@foundryprotocol/0gkit-kits
The kits engine: a neutral, dependency-light core that resolves, composes, and applies kits — drop-in, multi-framework feature overlays for 0G apps.
What it does
0gkit-kits is the engine behind npm create 0gkit-app -- --kits <kit> and
0g add <kit>. It reads each kit's kit.json manifest, validates it against
KitManifestSchema, resolves the right files for a given base (the target
template), follows composition (composes) and conflict (conflicts) rules,
and writes the overlay into a destination project — merging package.json and
.env.example idempotently.
The package depends only on zod (manifest validation) and giget (overlay
fetch) plus node:*. It never imports another @foundryprotocol/0gkit-*
package or any Foundry app package, so the CLI can load it without paying a
cold-start penalty and the neutrality boundary stays intact.
Concepts
- Kit — a versioned feature overlay stored as a git overlay under
templates/_kits/<name>/, described by akit.jsonmanifest. - Base — the template a kit is applied onto (e.g.
react-app,chat,storage-app,mcp-agent,tee-attested-api).detectBaseinfers it from a project'spackage.json. - 3-tier model — every kit ships a portable
libtier (always applied), optional per-frameworkadapters/<base>tiers, and an optional React-onlyuitier.resolveTierscomputes which files apply for a base. - Composition — a kit may
composesother kits (auto-applied deps-first, deduped, cycle-safe) and declareconflictsthat make a combination illegal.
When to use it
- Building the scaffolder / CLI surface that offers and installs kits.
- Programmatically applying a kit into a project (
applyKit). - Listing or inspecting the available kit registry (
listKits/getKit).
Install
npm install @foundryprotocol/0gkit-kits
Quick start
import { applyKit, listKits, detectBase, KitError } from "@foundryprotocol/0gkit-kits";
const base = detectBase(process.cwd()); // e.g. "react-app"
const available = listKits({ base }); // kits that contribute files to this base
try {
const result = await applyKit({
kit: "agent-memory",
dest: process.cwd(),
base,
});
console.log(result.applied, result.filesWritten, result.envAdded);
} catch (err) {
if (err instanceof KitError) {
// err.code ∈ KIT_NOT_FOUND | KIT_CONFLICT | KIT_MISSING_REQUIRES | KIT_INCOMPATIBLE
console.error(err.code, err.message);
}
}
API reference
Manifest
KitManifestSchema— the zod schema everykit.jsonis parsed through. Materialises defaults fortiers.lib,env,dependencies,devDependencies,requires,composes, andconflicts, so the engine always sees a fully-populated manifest.KitManifest— the inferred TypeScript type of a validated manifest.KIT_DOMAINS— the closed list of capability domains a kit may declare (verifiable-ai,agent-infra,markets,assets,defi).KitDomain— the union type derived fromKIT_DOMAINS.
Registry
KITS— the build-time registry: an array of every kit manifest, generated fromtemplates/_kits/*/kit.jsonbyscripts/gen-registry.mjs.loadRegistry()— returns the embeddedKITSarray.getKit(name, registry?)— looks up a single manifest by kebab-case name; returnsundefinedwhen not found.listKits({ base?, registry? })— lists kits, optionally filtered to those compatible withbaseand contributing at least one file for it.resolveTiers(manifest, base)— returns the ordered list of overlay files that apply forbase: thelibtier, then the matchingadapters[base]tier, then theuitier on a React base.
Bases
REACT_BASES— the set of bases that receive the Reactuitier (react-app,chat).isReactBase(base)— whether a base is inREACT_BASES.detectBase(dir)— infers the base of an existing project from itspackage.jsondependencies (falls back to"node").
Apply + compose
applyKit(options)— resolves the full composition closure (deps-first, deduped, cycle-safe), checksconflicts, then writes every tier's files, mergespackage.json, and appends env vars. Returns anApplyResult.ApplyKitOptions—{ kit, dest, base, pm?, dryRun?, deps? }.ApplyResult—{ applied, filesWritten, envAdded, notes, token }; thetokenis the stable success marker[0gkit:kit-applied].ApplyDeps— injectable seams (fetchOverlay,registry) for testingapplyKitwithout network or the real registry.KitError— thrown on an illegal apply; carries acodeof typeKitErrorCode(KIT_NOT_FOUND|KIT_CONFLICT|KIT_MISSING_REQUIRES|KIT_INCOMPATIBLE).
Overlay fetch
fetchKitOverlay(name, dir, deps?)— downloadstemplates/_kits/<name>from the canonical repo atOGKIT_TEMPLATE_REF(default"main") via giget.FetchKitOverlayDeps— injectabledownloadseam for unit tests.
Idempotent merges
mergePackageJson(base, incoming)— merges two partialpackage.jsonobjects; existing base keys win on conflict.PartialPackageJson— the shapemergePackageJsonoperates on.appendEnv(current, vars)— appendsEnvVarentries to an.env.examplestring, skipping any key already present (idempotent).EnvVar—{ key, example, note? }.
Exports
KITSKIT_DOMAINSKitErrorKitManifestSchemaREACT_BASESappendEnvapplyKitdetectBasefetchKitOverlaygetKitisReactBaselistKitsloadRegistrymergePackageJsonresolveTierstype ApplyDepstype ApplyKitOptionstype ApplyResulttype EnvVartype FetchKitOverlayDepstype KitDomaintype KitErrorCodetype KitManifesttype PartialPackageJson