@wringer/gunshi
v0.2.0
Published
The gunshi adapter for wringer: turns a wringer registry into a CLI
Readme
Turns a wringer registry into the repo's verify CLI, with gunshi parsing the command line.
Install
bun add @wringer/core @wringer/gunshiThe package runs on Bun 1.3 or newer.
Usage
Call runVerify from the repo's verify script with the registry that @wringer/core builds:
import { runVerify } from '@wringer/gunshi';
import { registry } from './registry.ts';
await runVerify(registry, { skill: '.claude/skills/verify' });Run it as bun verify.ts <command>, for example bun verify.ts up or
bun verify.ts action seed --count 3. The CLI lists the built-in commands, such as up, doctor
and lint, beside the commands that the registry declares and that its drivers add. A registry
can't declare a command named lint: runVerify throws Two commands share the name, as build()
does on any duplicate name.
skill is the path, from the repo root, of the folder that holds the repo's verify skill: the
Markdown that tells the repo's agents how to use each feature. lint reads that folder. The path
defaults to .claude/skills/verify.
Agent skill
The package ships an agent skill in skills/wringer/. It walks an agent through adding a verify
CLI, a feature map and a verify skill to a repo, and through the checks that prove them. Its
template/ folder holds the example files for the repo's own verify skill, which the agent writes.
The install command deletes the folder it installs to, so move any edits out of the repo's copy first. After you install or upgrade the package, run the install command from the repo root:
bunx @wringer/gunshi skill installIt copies the skill from the installed package to .claude/skills/wringer, or to --dir <path>. It
refuses a folder that is not a copy of this agent skill, and exits with code 2.
lint
bun verify.ts lint checks the feature map and the verify skill without starting the app, so CI can
run it on a fresh checkout. It exits with code 1, with check-failed in its envelope's
error.code, when it finds any of these:
- a feature's
pathsglob that matches no tracked file, and no untracked file outside git's ignore rules; - a line in a fenced code block of the verify skill's Markdown files that calls the CLI and fails to parse, whose arguments fail the command's schema, or that names a feature or a target the registry lacks;
- a skill folder with no
SKILL.md; - a verify skill whose frontmatter lacks
metadata.wringer-templateormetadata.wringer-command, or whosemetadata.wringer-templatediffers from the template version that this package ships. The agent skill's upgrade steps bring the verify skill to the shipped version.
metadata.wringer-command holds the words that call the CLI, such as bun verify. lint checks
only the code block lines that start with those words, after an optional $ prompt and environment
assignments.
Behaviour
- Each command prints one JSON envelope. A streaming command, such as
doctor, prints its NDJSON events first. - The CLI prints text in place of JSON when stdout is a terminal and no coding agent runs it.
--humanand--jsonchoose the format. - An unknown flag, a flag of the wrong type or arguments that fail the command's schema end in a
usageenvelope and exit code 2. So does a flag with no value after it; write--label ''to pass an empty one. - Write a negative value with
=, as in--degrees=-15. The parser reads--degrees -15as two short options, and the usage envelope's hint gives the joined form. Put a negative positional after--, as inlean -- -15. - A flag of an object or a list of objects takes JSON text, such as
--address '{"town":"Hollin"}'. - When a command's arguments are a union of objects, each branch's fields are flags, and the command's schema picks the branch.
- Every command takes
--target,--featureand--timeout-ms, unless it declares an argument of the same name.use --targetsets the target for later commands, wherestatus --targetreads one target once. --helpmarks each command[read]or[write], so a reader sees which commands a read-only target refuses. A command whose arguments decide, such asdb query, shows[read or write].- The script starts itself again, detached, as the run's supervisor, so
upandattachneed no separate daemon.
