@kampus/fabrika-cli
v0.7.1
Published
@kampus/fabrika-cli — the deterministic verb package fabrika skills call; `fabrika <group> <verb> …` (epic #4650)
Downloads
4,295
Readme
@kampus/fabrika-cli
What it is
The deterministic verb package the fabrika skills call.
fabrika <group> <verb> … dispatches to a registered verb group. fabrika is a two-layer split:
deterministic work is pushed into CLI verbs, and each skill is a thin wrapper carrying only the
judgment that cannot be mechanized. This package is the deterministic layer.
It is internal tooling for the kamp.us agent pipeline, not a general-purpose CLI. It ships on the public npm registry so a consumer repo can pin a version of it. For what fabrika as a whole is, read the guide.
Why it exists
- Which copy of the binary answers an invocation, and why a copy from another repository is refused rather than delegated to: ADR 0287.
- The GitHub credential order, and why
ghis a convenience rather than a prerequisite: ADR 0315. - Why this package re-implements v1's work and never calls into it: ADR 0238. v1 is deleted, so that is history rather than a live constraint.
How to use it
pnpm add --global @kampus/fabrika-cli
fabrika --helpInside a phoenix checkout you can skip the install and run the working tree:
node packages/fabrika-cli/src/bin.ts --help.
Every verb that touches GitHub needs a credential in the environment — GITHUB_TOKEN, else
GH_TOKEN. With neither set and gh on PATH, the credential is resolved once from an existing
login before any request. A credential that resolves nowhere is a refusal naming both variables,
never an anonymous call. There is no gh prerequisite: the package reaches api.github.com over HTTP
(src/io/gh-api.ts), and guard no-gh check keeps it that way on every push.
This package installs into repositories that are not the one it is developed in, so neither its
source nor the plugin's skills may carry a reference that only resolves here. guard
portability-guard check holds that on every push: it walks claude-plugins/fabrika/ and
packages/fabrika-cli/src/ and reds a ticket number, a decision-record number in either spelling, a
.decisions/ path, a hosted issue or pull-request URL, and any name the repo declares under the
portability key of .fabrika.jsonc. A markdown heading, a hex colour and a ticket number that is
test data are not references. Neither is an @ruling <issue url> citation under
packages/fabrika-cli/: a docblock here cites the ruling issue that governs it rather than a
decision record, because a decision-record number means something else in the next repository
(ADR 0394). Only the tag's
own span is admitted, so prose sharing the line is scanned as usual, and the tag must name a URL.
The bounded allow-list in portability-guard.config.json has two
buckets, each entry carrying a mandatory why: exempt is a permanent per-file cap for text that
is not a portability defect, and unmigrated is the sweep floor — one row per sweep unit, and it
only shrinks, so a ceiling left above the count reds exactly as loudly as a new reference does.
Ordered recipes — installing, credentialing, finding a group and a verb, reading a refusal, running
from a consumer repo — are in
docs/running-fabrika-in-a-repo.md.
Reference
docs/usage-recording.mddescribes the shared host recording API, versioned usage envelopes, issue/run model and token summaries, native counter meanings and recovery. Claude and Codex totals report their coverage; Pi observation remains unavailable.docs/verb-reference.mdorients readers to command groups, retained contracts and thecapturelibrary. Group help lists verbs; each verb's--helpowns its inputs, answer and exit meanings. The help index comes fromsrc/registry.ts. The interface convention defines the shared calling rules and documentation owners.docs/packaging.md— which copy of the binary serves an invocation, the delegation-outcome table, the environment variables, the two Node floors and thepublishConfigrewrite..patterns/fabrika-verb-shape.md— how a verb module is put together and which services it takes.
Testing
pnpm --filter @kampus/fabrika-cli test # vitest
pnpm --filter @kampus/fabrika-cli typecheck # tsc
pnpm --filter @kampus/fabrika-cli build # tsc -> dist/, for the published tarball onlyThe development loop has no build step: bin points at ./src/bin.ts and Node ≥ 24 strips the types
natively, so an edit to src/ is live on the next invocation. build emits dist/ for the
published tarball and nothing else reads it — see
docs/packaging.md for the two floors and the publishConfig rewrite.
