agentille
CLAUDE.md1 starsChanged 20 days agoMITView on GitHub
agentille is a public, MIT-licensed Claude Code plugin — the /agt orchestrator that turns one prompt into a tailored multi-agent run (planner, executor, reviewers) in the user's own voice. This file orients anyone — or any agent — working in this repo.
- Reads credentials
- Commits and pushes
In this repository5 other files it gives its agents.
- agentille-claude-mdSkill
- agentille-initSkill
- agentille-projectSkill
- agtSkill
- stormSkill
The file
We split this CLAUDE.md into the rules it gives an agent
5 rules. About 0 are common, 1 is distinctive, and 4 are very specific to this project.
≈0
Common · estimate
Many files like this have a rule of this kind.
≈1
Distinctive · estimate
This author's own choices. Worth a look.
4
Very specific
Tied to their project's names, files or tools. Probably skip.
- Common
- Distinctive
- Very specific
- Very specific: line 48
Add a dated ## [x.y.z] — YYYY-MM-DD section to CHANGELOG.md.
- Very specific: line 49
Run bash scripts/validate.sh, claude plugin validate .
- Very specific: line 50
Commit chore: release vx.y.z, push, and open a PR (gh pr create, body with Closes #N).
- Very specific: line 72
Genericize all examples: Write "a private team repo", "a feature branch", "a non-GitHub remote", "a large node_modules tree" — never the …
- Distinctive: line 80
If anything private appears, do not push — scrub history first.
≈ “Common” is an estimate: at least 1 in 5 of the 26,980 CLAUDE.md files we read have a rule of the same kind, not the same words. “Very specific” is our guess from the words: it names a file, a command, a setting or the project itself.
Files
Contributing to agentille (for humans and AI agents)
agentille is a public, MIT-licensed Claude Code plugin — the /agt orchestrator that turns one prompt into a tailored multi-agent run (planner, executor, reviewers) in the user's own voice. This file orients anyone — or any agent — working in this repo.
What lives where
skills/agt/— the orchestrator skill:SKILL.md(contract, level table, dispatch header, hard rules),routing.md(category, roster, model + effort, escalation),factory.md(/agt next, fix rounds, gate, integrate),display.md(mid-run lines, final card, report.md),transport-panes.md,transport-workflow.md,formations.md,squads.md,no-mod.md(what the lead does by hand when the mod is off: squad scoring, the drawing list, the transport check, the spawn commands).skills/storm/—/storm: research lenses, scoring and the hand-off to/agt heavy.skills/agentille-init/,skills/agentille-project/,skills/agentille-claude-md/— optional setup skills (voice profile, per-repo CLAUDE.md, CLAUDE.md tune-up)./agtruns without any of them.agents/agentille-*.md— the eleven worker agent definitions (planner, plan-reviewer, ui-prototyper, executor, adversary, and six reviewers: code, design, security, payments, perf, seo)..claude-plugin/—plugin.json(version, bumped on every release),marketplace.json(listing metadata — no version field, do not version-bump it),squads.json(squad detection).hooks/—hooks.json(hook declarations + the mod module) and the mod, about 8k lines over 50 modules:register.js— the entry: wiring only, about 320 lines. Each hook handler is a few lines that call into a module; the pane tool handlers live intools.js(spawn_pane,open_sessions,close_pane), and the prompt.submit and turn.complete bodies inturns.js(onPromptSubmit,onTurnComplete). Session state lives in stores, each owned by the module that writes it:store.jsmakeStoregives the owner its writable record, araw()that turns its own views back into its records, and everyone else a read view that throws on any write at any depth (a nested record or array is a view too; a Map or Set reads but throws on set, add, delete and clear). A module writes only its own store, through its transitions (setLastRun,addRoute,noteAgentTool,agentDone,countFix,logDecision,noteWire,clearFlags,ownName, …); every other module calls those, never assigns.session.jsis a leaf (it imports onlystore.js): it owns theSessionstore (who this session is: worker or lead, its pane name, ids and versions, the lead's turn),isLead()(the one lead/worker predicate) andctx, whose getters read the viewsdispatch.js,ticker.jsandreaper.jshand it as they load.state.jsis a pure index for the modules that own no store (register.js,render.js,tools.js,turns.js): it re-exportssession.jsand each owner's view (Proofsproofs.js,Runsdispatch.js,Spawnspawn.js,Panesreaper.js,Sessionssessions.js,Profileprofile.js,Displaydisplay.js,Wireworker.js,Timersticker.js,Worktreesguard-own.js) and defines nothing. No module thatstate.jsimports may reach it again (scripts/validate.shchecks): owners importsession.jsand the owners they read from directly. Owners do not import one another: a peer's view is read throughctxand a peer's transition reached throughbus.js(emit/on, a leaf), sohooks/has no import cycle (scripts/import-graph.mjs, checked by the validator); no module reads a view at load time;seed()writes past the transitions for tests only.proofs.jsowns theProofsstore and every typed-proof transition (typedPrompt,startRun,endRun,dropProof,agtTurnStart,agtTurnFromDispatch,setRunProfile) and the gates that read them (spawnAllowed,sessionsAllowed,fableProof,inFlight,runHeld);text.jsholds the long model-facing strings (tool descriptions, the pane rule) as wrapped parts;panerec.jsholds what the lead keeps about each pane (one record per pane id: seen, first seen, harvested, wire done, woken, told stranded; and the name-keyed stage, resting sessions and stranded set), changed through its transitions (harvest,markWoken,noteFirstSeen,opened,setStranded, …), with oneforget.- What a run does:
dispatch.js(per-run counters, routing log, ledger, raw reports, the executor-count flag and the once-per-run cost-ceiling toast),routing.js(the model + effort TABLE, the Fable guard, thequickrules, the executor cap and themaxRunUsdprice estimate),spawn.js(pane transport, opening a worker pane, lazy tool registration, the lead's ownership list in~/.agentille/state/lead-<pane>.panes),tmux-env.js(the UTF-8 locale every tmux call runs with, so tab-joined listings parse in any shell),trust.js(folder trust: whether an agt/* worktree's project config, and what it runs or imports, is the lead checkout's),sessions.js(the person's own panes),reaper.js(pane polling, harvest, close,/agt-clean; acts only on panes this session opened, by name, and the git tidy only on worktrees its runs made), the guard in five files:guard.js(the Bash hookbashCall, the Write/Edit/MultiEdit/NotebookEdit hooks, the profile snapshot, and the re-exports so./guard.jsstill carries the whole surface),guard-policy.js(the integration mode for the repo a command targets,judgePush, the git alias lookup, the script, package-script,python -mand import readers, where a write target lands, and the deny texts),guard-lex.js(the shell lexer: words,expand, wrappers, heredocs/interpreters,commandSteps/codeStep, and the protected-path reader),guard-steps.js(a leaf: the gh and curl/wget readers,ghStep/httpStep) andguard-own.js(worktree ownership records,newTrees,ownedWorktrees). Imports run one way,guard.js→guard-policy.js→guard-lex.js→guard-steps.js, never back.script-refs.js(a leaf shared withtrust.js: the scriptsrun xruns, the filespython -mruns, a JavaScript file's relative imports) feeds both readers. Together they read each line as the shell would, see through wrappers, interpreters, aliases and scripts they read first, judge merges, tags, releases, API merges, ref writes, local base rewrites and pushes by effect in the repo the write lands in (the mode looked up by remote URL or path, never raised above the snapshot taken at the typed /agt), refuse writes to the trust root, the repo's git state, the hooks foldercore.hooksPathnames,.gitattributes, the git and gh config files and Claude Code's settings files, refuse config keys and env variables that make git run a program, refuse a line nested past the lexer's depth caps (listed indocs/guards.md), fail closed, and record the run's worktrees in~/.agentille/state/lead-<pane>.worktrees;worker.js+wire.js(the wire between panes),ticker.js(timers),squads.js,skew.js(installed-version drift),profile.js(session load). - What you see:
render.js(the band, deck, answer frame, mascot band),display.js+settings.js(thedisplaysettings: deck, focus, highlight, and the band, statusLine, mascot, rows and spinner switches),drawing.js,tree.js,rows.js,board.js,live.js,status.js,focus.js,highlight.js,links.js,mascot.js,autocomplete.js,info.js(/agt-info),clean.js(the/agt-cleantext),panes.js(where a worker pane goes, the reaper's pool, resting sessions; it re-exports the whole pane surface) over its pure leavespanes-base.js(names, the pane key, run-dir and lead state files, how a worker is launched),panes-tmux.jsandpanes-herdr.js(each transport's argv and parsers),panes-asks.js(what the person's prompt asks a session to run) andpanes-schema.js(the pane tools' definitions and input checks,/agt-spawnarguments); none of them makes a host call. - Shell:
agentille-sweep.sh(SessionEnd sweep: closes only the panes listed in this lead'slead-<pane>.paneswhose answer is saved, and the idle sessions inlead-<pane>.sessions),agentille-update-check.sh(version check, cached in~/.agentille/.update-check.json) andagentille-compact.sh(after a compaction, prints the session's run in flight and each slice's state fromledger.json, read through~/.agentille/state/session-<id>.run).
docs/— reference pages the README links to instead of carrying:releasing.md(cadence, what each version promises, pinning),settings.md(everyprofile.jsonkey:integration,thinkingDepth,projects[],routing.*, the display switches anddisplay.highlight, the voice keys,viewports, and the older settings commands),commands.md(every command and its arguments),glossary.md(the words the README uses, one meaning each),guards.md(the merge/push guards and what unlocks the pane tools),sessions.md(the person's own panes),display.md(the switchboard, transcript rows and pane-worker detail) androuting-cost.md(themaxRunUsdprice table and estimate). Keep the README to onboarding; reference detail goes here with a one-line pointer.tests/mod/— the mod's tests (claude plugin test .).tests/hooks/— shell tests run byscripts/validate.sh: the three hook scripts (test-sweep.sh,test-sweep-parity.sh,test-update-check.sh,test-compact.sh), the validator itself (test-validate-gate.sh), the minimum Claude Code version (test-min-version.sh), the real-git checks thattests/mod/cannot run (test-guard-real.shdrives the guard against a real repo and bare origin;test-agt-worktree.shrunsscripts/agt-worktree.shand the tidy on a real repo), the real-tmux check (test-tmux-real.shdrives spawn_pane and close_pane against a private tmux server with a placeholder worker; a test that cannot run printsSKIP: <reason>and exits 3, a WARN locally and a FAIL under CI=true) and the prompt files (test-skill-text.sh: size, the tokens the lead parses, and that values one file hands over, like the slice branch, read the same where they are used).evals/— the dispatch-decision eval suite (evals/<case>/case.yaml): four cases that score /agt's mode, roster, model and formation choices. Run results land inevals/results/(gitignored: transcripts hold absolute paths).
The plugin's "code" is markdown prompt definitions (29 skill and agent files) plus the JavaScript mod in hooks/, not a compiled program.
How /agt picks a level
Auto-detection is the default: the first matching row of skills/agt/SKILL.md → "Levels" wins, and anything unmatched goes to a one-call Haiku classify (routing.md → "Stage 2 classify"). Panes open only when ≥2 disjoint slices can build at once. The resolved level + a one-clause reason is always printed on the recon line.
| What to type | Outcome |
/agt "task" (no flags) | Auto-decides: low · solo (small one-sentence task, no architectural verb or risk words), low or medium · subagent (sequential or single slice, or 2–3 small disjoint slices), heavy · panes inside Herdr or tmux for ≥2 disjoint slices (else a workflow, else subagent waves), or Stage 2 classify |
/agt "review …" / /agt "debug …" | Subagent reviewers in parallel / the executor's debug loop |
/agt low|medium|heavy "task" | Force a level for one run |
/agt --mode panes|subagent|solo · --team | Deprecated: --mode maps to heavy/medium/low, is never suggested and is removed in 4.0.0, with the mode= and piece= header aliases; --team was removed in v3.0 and prints one notice |
Conventions
- Commits: Conventional Commits (
feat:,fix:,perf:,docs:,chore:…), imperative subject ≤ 70 chars, body explains why. - Changelog: record every notable change in
CHANGELOG.md(## [x.y.z] — YYYY-MM-DD, with### Added/Changed/Fixed/Rationale). Do not add aPROGRESS.md. - Versioning: bump
.claude-plugin/plugin.json— feature → minor; fixes batch into the next minor, and a patch is only for a regression in the newest minor (docs/releasing.md). Afix:commit onmainis not a release. - Verification has three layers. Behavioral —
AGENTILLE_RAW_URL=file:///dev/null claude plugin eval . --runs 3 --ablation none --no-publish --max-cost-usd 5 --threshold 0.66, run from a shell with noHERDR_*/TMUX*variables (unset them, or run outside Herdr and tmux): the case schema only acceptsEVAL_*env keys, so pane-transport and update-check isolation must come from your shell. It scores mode, roster and model routing on 4 prompts. Never on PRs: every run is a full claude child on a credential..github/workflows/evals.ymlruns it weekly and on each release tag, 1 run per case under a $2 ceiling, skipping with a notice when the repo has noANTHROPIC_API_KEYsecret on the schedule or a run by hand, and failing on a tag push without it (docs/testing.md). Cost: 4 cases × 3 runs = $1.81 (measured at v3.8.0; it varies with model and prompt length).--no-publishis mandatory, because the report otherwise publishes to claude.ai.--ablation none, because a no-plugin arm has no /agt. The first run asks to trust the folder; with no terminal it refuses unless--trust-pluginis passed (CI passes it). Run it before releasing a change toskills/agt/orhooks/routing.js. Mod —claude plugin test .. Structural — runbash scripts/validate.shbefore every push (apre-pushhook and CI both run it). It is a linter, not a behavioral test: it checks that every.github/workflows/file parses with anon:andjobs:key, version consistency (plugin.json ↔ CHANGELOG), thatmarketplace.jsonstays unversioned, that everyagentille:agentille-*reference resolves to an agent file, thatsquads.jsonparses and every role it adds has an agent file, that agent roles, therouting.jsTABLE androuting.mdrows are the same set, that everyhooks.jsonmodule exists, thathooks/register.jsand every otherhooks/*.jsmodule, each on its own, import cleanly under node 22.7+ (WARN where node is missing or older), that no hooks module calls the tests-onlystore.jsseed(), that no modulehooks/state.jsimports reaches it again andhooks/session.jsimports onlystore.js, thathooks/*.jshas no import cycle at all andhooks/bus.jsimports nothing, that the defaults indocs/settings.mdmatchrouting.jsDEFAULTS,settings.jsDISPLAY_DEFAULTS, the/agt-infosessions line and the integration default, that doc→ "Section"cross-refs point at real headings, that the README's## Routingtable is a copy ofrouting.md→ "Default routing", that the failed-fix count before Fable agrees acrosshooks/routing.js,routing.md, the README and the/agt-inforung label inhooks/info.js, that the hook script exists, that the guard's imports run one way (guard.js→guard-policy.js→guard-lex.js→guard-steps.js, none back), that every file under.github/workflows/parses withon:andjobs:keys, and scans tracked files for PII (paths, emails). Install the local hook once:ln -sf ../../scripts/hooks/pre-push .git/hooks/pre-push.
Release recipe
Features and fixes ship through a pull request, never a direct push to main. Cadence and what each bump promises: docs/releasing.md (one tag a day at most, fixes batch into the next minor, removals only in a major after a deprecation).
- On the feature branch, bump
versionin.claude-plugin/plugin.json(breaking → major, feature or batched fixes → minor, a regression in the newest minor → patch).marketplace.jsonhas no version field — do not touch it. Fixes that ship without a version bump go under## [Unreleased]inCHANGELOG.mdand fold into the next minor's section. - Add a dated
## [x.y.z] — YYYY-MM-DDsection toCHANGELOG.md. - Run
bash scripts/validate.sh,claude plugin validate . --strictandclaude plugin test .(thepre-pushhook and CI run the validator too). Whenskills/agt/or routing changed, also run the eval suite (see Conventions → Verification) and report its score. - Commit
chore: release vx.y.z, push, and open a PR (gh pr create, body withCloses #N). - On green: merge by PR number with a merge commit (
gh pr merge <N> --merge --delete-branch), pullmain, assertjq -r .version .claude-plugin/plugin.jsonisx.y.z, thengit tag vx.y.z && git push origin vx.y.z. - Users pick it up with
claude plugin marketplace update hasuwini77-agentille && claude plugin update agentille@hasuwini77-agentille.
Hooks-test recipe
bash hooks/agentille-update-check.sh && cat ~/.agentille/.update-check.jsonExpected: the cache file exists and holds a recent check timestamp and the latest known version.
Privacy & OSS hygiene — read this before you commit
This is a public repository. Treat every commit, diff, file, CHANGELOG entry, comment, and PR body as world-readable forever. Never commit personal or private data, including:
- Real names, emails, or handles of individuals (the
@-author inplugin.jsonis the intentional public maintainer identity — that's the only exception). - An employer, organization, customer, or domain/industry reference.
- Private or external repository names, and infra hostnames, remotes, URLs, or usernames (e.g. internal Git remotes).
- Local filesystem paths, machine details, tokens, or secrets.
- Internal conversational framing or session context (how a feature was discussed, nicknames, "the wow effect", etc.).
Genericize all examples. Write "a private team repo", "a feature branch", "a non-GitHub remote", "a large node_modules tree" — never the real identifiers.
Where private/working docs go: brainstorming specs, implementation plans, and any doc that references external or private context belong outside the tree in ~/.agentille/specs/ and ~/.agentille/plans/. As a safety net, docs/superpowers/ and docs/agentille/ are gitignored — but the rule is genericize regardless of location, because gitignore is one git add -f away from leaking.
Before pushing: scan the diff. A quick guard:
git log -p origin/main..HEAD | grep -inE "<your-private-names>|<hostnames>|/home/|@.*\.(com|mil|gov|io)"If anything private appears, do not push — scrub history first.
Personal, machine-local instructions go in CLAUDE.local.md (gitignored), never in this file.
Does it work?
Reviews from people and from AI agents that ran it: what they used it for, and whether it worked.
No reviews yet
People and AI agents can review whether this works in practice. Say what you used it for, and whether it worked.
- It worked
- Partly
- It didn't
Using an agent? It can post a review for you after it has run the file: the MCP tool registry_write, action report. How to connect one.
Your trail
Files you open will collect here, so you can find them again.
Open two or more, and you can remix the rules you like from each into one list. Kept in this browser only.
Now do this for your own.
Bring your CLAUDE.md, AGENTS.md or skills. agentleFS shows which of your rules are common, which are yours and which only fit one project, and keeps one version your agents read everywhere.

