agent-primitives
v0.14.0
Published
Agent-first CLI primitives (bounded JSON envelopes, a mutation-probe runner, a verify runner, a PATH doctor, an identifier-drift guard, a commit-hygiene guard, an exact-text patcher, checkout snapshot/delta, and a skill installer) for narrow subagents
Maintainers
Readme
agent-primitives
Agent-first CLI primitives for narrow subagents: a mutation-probe runner, a verify runner, a PATH doctor, an identifier-drift guard, a commit-hygiene guard, an all-or-nothing exact-text patcher, checkout snapshot/delta, and linked-worktree creation, removal and reporting, each returning one bounded JSON result instead of raw tool output.
Overview
agent-primitives is an agent-first CLI: JSON on stdout by default, one
bounded result object per invocation, and stable exit codes (0 ok, 1
finding, 2 cannot conclude, including a usage error). It exists to remove a
few recurring failure classes in agent-driven review and implementation work:
hand-edited mutation probes that forget to restore a file, verify output that
blows past a harness's output cap, and "which binary is even on PATH"
guesswork. Unlike its sibling packages, it defaults to JSON output (-f,
--format text opts into a human-readable rendering instead), because its
primary caller is another agent, not a terminal. Part of
agent-dx, playbooks and tooling
for teams shipping with AI agents.
Key features
doctor: checks a list of required and optional binaries onPATHand reports a few environment signals (git worktree,node_modules, whether a rebuild is likely needed).verify: runs named checks (build,typecheck,lint,testby default) and reports a compact, bounded summary instead of raw output.probe: runs one mutation probe (or a--planof several), confirms the baseline passes first, and reports whether the target test caught the mutant, restoring the file afterward either way.init: installs the package's own skill document into a harness's skill directory.drift: finds prose and comments that still cite an identifier a change deleted or renamed.hygiene: refuses staged or committed backup files (*.bak,*.orig,*~, and the BSDsed -ileftovers*-e,*-E,*-n,*-r,*-s) and flags rewrites of extend-only files and dropped test cases.patch: replaces exact text in one or more files from a JSON edit plan (or one--file/--old/--newedit), resolving every edit first and writing nothing when one is missing, ambiguous or overlapping; reports the matching tier per edit, keeps line endings, BOM and file mode, and has a--dry-rundiff preview.snapshot/delta: save checkout/index/content fingerprints to a full external artifact and compare the same checkout later.worktree create: makes a linked worktree on a new branch with no upstream, from a chosen base, without touching the main checkout; optionally writes the.ai/runpointer, symlinks shared dependency directories, runs a setup command and a smoke check, and reports the base sha as a readyrun-base[<repo>] = <sha>line.worktree remove: removes one linked worktree, refusing a dirty, unpushed or (with--require-merged, optionally against--base <rev>) unmerged one unless--force, unlinking the dependency links it finds without ever following them, keeping the branch unless--delete-branchsays otherwise, and never removing or switching the main checkout.worktree list: reports every worktree of a repository, or every work tree below--root, with its branch,.ai/runpointer, dirty state, commits ahead of and behind the default base (or a remote-tracking--base <rev>), merge verdict and dependency links.- Non-Node repositories are supported: PHP (PHPUnit, PHPStan,
PHP_CodeSniffer) output is recognized by
verifyandprobealongside vitest, tsc, and eslint. - Every command accepts the same global flags (
-f/--format,-C/--cwd,-m/--max-chars,-l/--log-dir, and--jsonas an alias for-f json); see Output shape for the JSON envelope and the-mreduction algorithm.
Install / quick start
npx agent-primitives doctorFor a binary that stays on PATH, so a subagent started as an ordinary
child process finds it too:
npm install -g agent-primitives
agent-primitives doctorRequires Node >= 20 and git (2.35 or newer for probe's default
worktree isolation; doctor reports its git-version check ok from
2.36).
Usage
agent-primitives probe --file src/foo.js -n 12 -r 'return false;' \
-t 'npm test'Mutates line 12 of src/foo.js to return false;, confirms npm test
passes first (the baseline), reruns it against the mutant, restores the
file, and reports whether the test caught it (killed) or missed it
(survived).
Documentation
doctor: PATH and environment checks.verify: run named checks with a bounded summary.probe: the mutation-probe runner,--plan, and the result shape.init: install the package's skill into a harness.drift: the identifier-drift guard for docs and comments.hygiene: the commit-hygiene guard for backup files, extend-only rewrites and dropped test cases.patch: all-or-nothing exact-text edits, the matching tiers, refusals and the result shape.snapshot: read-only checkout fingerprints.delta: compare the same checkout with a saved snapshot.worktree: create, list and remove linked worktrees for a task branch, with their flags and refusals.- Non-JS test runners: PHP and other
non-Node test runner support, including the "Python bytecode cache"
section a
probewarning points to. - Output shape: the JSON envelope, global flags,
and the
-m/--max-charsreduction algorithm.
Architecture
src/cli.ts registers every command and sends each result through
buildEnvelope in src/envelope.ts, which applies the -m bound and
maps the status to the exit code. Each command lives in its own module:
| Command | Module |
| --- | --- |
| doctor | src/doctor/index.ts |
| verify | src/verify/index.ts, output detectors in src/verify/detectors/ |
| probe | src/probe/ (index.ts, setup.ts, step.ts, session.ts, isolation.ts and helpers) |
| init | src/init/index.ts, digest ledger in src/init/ledger.ts; installs assets/skill/SKILL.md |
| drift | src/drift/ |
| hygiene | src/hygiene/index.ts, using src/drift/git.ts |
| patch | src/patch/ (index.ts plan and write phase, engine.ts matching, hint.ts, diff.ts) |
| snapshot, delta | src/snapshot/ |
| worktree | src/worktree/ (create.ts, remove.ts, list.ts; shared git helpers in git.ts, the smoke verdict in readiness.ts) |
verify spawns its checks through execCommand in src/exec.ts.
probe is split into a setup phase (src/probe/setup.ts: containment,
lock, stale-marker recovery, worktree preparation, baseline) and a
per-mutant step (src/probe/step.ts: in-flight marker, apply, test,
restore, classify), which --plan runs once per mutant;
docs/probe.md shows the order of its gates. Both phases
go through src/probe/session.ts: its runPreThenTest starts the
baseline's and each mutant's --pre and test command through
execCommand (the final --pre rebuild under -i inplace goes
through runFinalRebuild in the same module, which probe/index.ts
calls through finalRebuildOrWarn), and its
prepareWorktreeSession creates the -i worktree copy through
src/probe/isolation.ts. doctor reuses src/lock.ts and
src/probe/isolation.ts to read the markers and scratch worktrees
probe leaves behind. The diagram shows the main imports between the
verify, probe and doctor modules and the shared ones; output
helpers that setup.ts and step.ts also import from exec.ts are
left out.
flowchart TD
VER["verify/index.ts"] -->|execCommand| EXEC["exec.ts"]
PRB["probe/index.ts"] --> SET["probe/setup.ts"]
PRB --> STP["probe/step.ts"]
SET --> SES["probe/session.ts"]
STP --> SES
PRB -->|finalRebuildOrWarn| SES
SET -->|acquireLock| LCK["lock.ts"]
STP -->|writeMarker| LCK
SES -->|execCommand| EXEC
SES -->|beginWorktree| ISO["probe/isolation.ts"]
ISO --> CON["probe/containment.ts"]
ISO --> LP["probe/link-policy.ts"]
LP --> CON
DOC["doctor/index.ts"] --> LCK
DOC --> ISODevelopment
To work on the package itself, build it from source:
git clone https://github.com/LanNguyenSi/agent-dx.git
cd agent-dx/packages/agent-primitives
npm install
npm run build
node dist/cli.js doctornpm test runs the build first (pretest), then the test suite
(vitest). Before pushing, run npm run typecheck, npm run
typecheck:test, npm run format:check and npm test; CI runs all of
them for this package (see the repository's
CONTRIBUTING.md).
License
MIT
