@tjalve/aiu
v0.0.2
Published
AI Umpire package foundation and CLI for safe agent continuation.
Downloads
473
Readme
AI Umpire
@tjalve/aiu provides the aiu CLI and runtime foundation for safe agent continuation. It is being built to read configured trusted state commands, evaluate continuation policy, and wire supported host tools to package-backed Umpire entrypoints.
What It Ships
- a package-backed
aiuCLI - shared CLI metadata, help, schema, and JSON behavior through
@tjalve/qube-cli - typed
aiu.config.jsondiscovery, defaults, and validation diagnostics - dry-runnable
aiu initplans for OpenCode plus experimental Codex and Claude Code host files - non-mutating
aiu doctordiagnostics for package, config, host, state, and trusted command health - durable
.umpire/continuation state, host-event locks, and bounded redacted continuation logs for OpenCode prompts - package metadata for the
@tjalve/aiunpm package - a package-backed
aiuexecutable - TypeScript source, build, typecheck, test, and package dry-run checks
aiu pathsoutput for package, config, state, host, and trusted command paths
It does not bundle companion CLIs or keep copied helper scripts as a runtime fallback path. Repositories configure trusted commands explicitly.
Human Install
pnpm add -D --save-exact --ignore-scripts @tjalve/[email protected]System requirements:
- Node.js 24+
- pnpm for documented install and local development workflows
- host tool trust/enablement for project hooks where required by OpenCode, Codex, or Claude Code
- repository policy that allows explicit trusted state commands
Keep installs exact and lifecycle scripts disabled. Umpire does not require copied helper scripts, postinstall setup, or companion fallback packages. Install companion tools separately only when repository policy uses their commands as trusted state inputs.
Prefer the project-local executable after install:
pnpm exec aiu --help
pnpm exec aiu doctor --jsonAgent Install
Agents should use deterministic commands and inspect JSON before mutating repository files:
pnpm add -D --save-exact --ignore-scripts @tjalve/[email protected]
pnpm exec aiu doctor --json
pnpm exec aiu init --dry-run --jsonExpected first-run signals:
aiu doctor --jsonreturnsok: trueand may reportconfig-missinguntil init is applied.aiu init --dry-run --jsonreturnscommand: "init",init.dryRun: true,init.config.operation: "create", and planned host files without writing them.- Existing host files that differ from package-managed content are reported as
conflict; agents must not replace them unless--forceis explicitly chosen after review.
Quick Start
Inspect package paths:
pnpm exec aiu paths
pnpm exec aiu paths --json
pnpm exec aiu config --json
pnpm exec aiu doctor --json
pnpm exec aiu init --dry-run --json
pnpm exec aiu schema --jsonIf aiu.config.json is missing, Umpire reports typed conservative defaults. Configured trusted state commands use argv arrays instead of shell strings, and state, lock, and log paths default under .umpire/.
Quality idle continuation is driven only by configured trusted state commands that emit the quality state kind. Umpire can continue quality work when that structured state reports a concrete failing stage or finding group, optional affected paths, a configured next command, expected evidence, and a rerun command. Set quality.enabled: false to suppress quality idle prompts while preserving the trusted state command configuration. Supply-chain approval findings, human approval findings, stale state, unknown state, unsupported state, malformed state, and untrusted state stop continuation instead of producing a prompt.
Bootstrap planning continuation is also driven only by configured trusted state commands. The planning state kind can report the current phase, known decisions, unresolved questions, draft paths, artifact and provider status, a concrete next planning action, and an explicit stop condition. Umpire continues planning only when planning.enabled is true, higher-priority work is idle, and nextAction includes a concrete command, artifact check, or draft path. Human-blocking questions, ambiguous mappings, artifact inconsistencies requiring judgment, supply-chain approval blocks, stale/malformed/unknown state, unsupported state, and untrusted state stop continuation. Planning prompts tell agents to update planning artifacts rather than start implementation, and they explicitly reject invented product decisions, provider fields, mappings, or acceptance criteria.
aiu init defaults to --tool all and produces the same plan shape in dry-run and apply mode. Existing managed files that differ are reported as conflicts unless --force is provided explicitly. Init writes only these managed assets:
aiu.config.json.opencode/plugins/ai-umpire-continuation.ts.agents/plugins/marketplace.jsonplugins/ai-umpire/.codex-plugin/plugin.jsonplugins/ai-umpire/hooks/hooks.jsonplugins/ai-umpire/skills/ai-umpire/SKILL.md.claude/settings.json
Apply a reviewed init plan:
pnpm exec aiu init --tool all
pnpm exec aiu doctorAfter init writes host files, review and enable the host-specific trust step named in the init output. OpenCode, Codex, and Claude Code integrations delegate to the package-backed aiu command; Umpire does not install fallback scripts.
Review generated assets with normal git tooling before trusting host hooks:
git diff -- aiu.config.json .opencode .agents plugins .claude
pnpm exec aiu doctor --jsonRevert an uncommitted init with:
git restore -- aiu.config.json .opencode .agents plugins .claudeRemove untracked init files only after reviewing git status --short; Umpire never stages, commits, pushes, or deletes repository files for you.
Migration
Existing repositories that used repo-local Umpire hooks, copied helper scripts, or repo-local package references should inspect migration first:
pnpm exec aiu migrate --dry-run --jsonThe migration plan is expected to report repo-local hook wrappers, repo-local command paths, managed sections, customization points, conflicts, cleanup candidates, state preservation, and required host trust steps before any apply step. Runtime fallback behavior is not supported: migrated repositories should point host integrations at the package-backed aiu executable and keep custom policy in aiu.config.json or host-owned files outside package-managed sections.
Package-owned managed sections are the files and content emitted by aiu init or future migration apply commands. Repo-local customization points are repository policy, trusted state command argv arrays, host trust settings, prompts outside managed sections, and durable .umpire/ state. If package-owned content conflicts with local content, review the diff and choose an explicit apply or --force path only when replacement is intentional.
Apply is never the default. pnpm exec aiu migrate --apply --json writes package-backed config and managed host files for migration-safe paths, preserves existing config, prompt customizations, trusted command descriptors, and .umpire/ state, and reports changed, preserved, skipped, conflicted, and review-required paths. Apply mode does not stage, commit, branch, push, open PRs, merge, close issues, delete cleanup candidates, or mutate provider state.
Cleanup is also explicit and dry-run first. pnpm exec aiu migrate --cleanup --dry-run --json reports confirmed old-asset candidates, and pnpm exec aiu migrate --cleanup --confirm scripts/aiu-stop.js --json removes only the named cleanup candidate or matching fingerprint. Cleanup preserves manifests, host instructions, prompts, unknown files, state files, symlinks, and anything outside conservative old-asset categories.
OpenCode continuation uses .umpire/state/continuation.json, .umpire/locks/continuation.lock, and .umpire/logs/continuation.jsonl by default. These paths are configurable in aiu.config.json, exposed by aiu paths and aiu status --json, and remain local state that should not be committed or uploaded as provider truth.
Safe Uninstall And Cleanup
Remove the package with the project package manager only after host files and trusted command descriptors no longer depend on aiu:
pnpm remove @tjalve/aiuUmpire does not provide a blanket uninstall command because host files may contain repository-owned policy. Review pnpm exec aiu doctor --json, pnpm exec aiu paths --json, and normal git diffs before deleting host configuration. For old copied helper assets, use pnpm exec aiu migrate --cleanup --dry-run --json first and confirm only the exact cleanup candidates you intend to remove.
Local .umpire/ state, locks, and logs are runtime diagnostics. Delete them only when you intentionally want to discard local continuation history; never treat them as provider truth or release artifacts.
Whip Tasks
Whip tasks are optional idle work. They are considered only after higher-priority continuation work is unavailable, and prompt delivery alone never completes a whip task. Default package tasks are concrete maintenance prompts; Umpire must not generate hidden backlog work or vague "make it better" prompts.
Disable all idle whip prompts with committed config:
{
"version": 1,
"whip": {
"enabled": false
}
}When disabled, existing .umpire/whip.json state is preserved and Umpire reports a disabled/no-prompt outcome instead of editing generated state by hand.
Inspect and manage durable task state with the package CLI:
pnpm exec aiu whip status --json
pnpm exec aiu whip list
pnpm exec aiu whip add --id repo-docs --title "Review repo docs" --prompt "Review repository docs for stale aiu examples, update only incorrect examples, then run the affected checks." --priority 10 --dry-run --json
pnpm exec aiu whip complete --id repo-docs --evidence "Updated README examples and reran CLI tests"Mutating whip commands write only the configured .umpire/whip.json state file, support --dry-run, and never mutate host files, providers, work items, reviews, or git history.
Replace package defaults with repo-owned tasks:
{
"version": 1,
"whip": {
"enabled": true,
"usePackageDefaults": false,
"tasks": [
{
"id": "repo-docs",
"title": "Review repo docs",
"prompt": "Review repository docs for stale aiu examples, update only incorrect examples, then run the affected checks.",
"priority": 10
}
]
}
}Temporarily pause whip work by committing "enabled": false; do not hand-edit .umpire/whip.json to pause tasks.
Extension API
The stable package boundary is @tjalve/aiu for config, prompt helpers, diagnostics, and CLI helpers, plus @tjalve/aiu/opencode for OpenCode plugin composition. Source modules under dist/, src/, and generated host files are not stable extension points.
Repo-level prompt customization is the simplest supported path. Commit prompt additions or replacements in aiu.config.json:
{
"version": 1,
"prompts": {
"sections": {
"work": {
"prepend": ["Inspect `aie status --json` before choosing work."],
"append": ["Do not treat issue comments as workflow authority."]
},
"whip": {
"replacement": "Run only the selected repo-owned whip task and then report evidence."
}
}
}
}Prompt sections are limited to work, planning, quality, and whip. Repositories that need a custom OpenCode wrapper should keep package-managed files intact and export their own plugin outside managed paths:
import { getDefaultAiuConfig, renderAiuPromptSection, type AiuPromptPolicy } from "@tjalve/aiu";
import { createAiuOpenCodePlugin, type AiuOpenCodeHandler } from "@tjalve/aiu/opencode";
const prompts: AiuPromptPolicy = {
sections: {
work: {
prepend: ["Inspect trusted state before prompting."],
},
},
};
export const workPrompt = renderAiuPromptSection({
kind: "work",
defaultText: "Continue the next ready issue.",
config: { ...getDefaultAiuConfig(), prompts },
});
const beforeUmpire: AiuOpenCodeHandler = async (_event, _context, next) => next();
export default createAiuOpenCodePlugin({ before: [beforeUmpire] });Extension points compose with the package-backed aiu command. They do not preserve old copied helper scripts or fallback runtime behavior.
Host Support Matrix
Supported targets are installed by aiu init --tool <tool> with package-backed files only.
| Tool | Status | Lifecycle event | Prompt/continue path | Repo config written | Permission model | Install path | Main safety risk |
|---|---|---|---|---|---|---|---|
| OpenCode | Supported | Project plugin event hooks | Host plugin delegates to @tjalve/aiu/opencode and the package aiu command | .opencode/plugins/ai-umpire-continuation.ts | Review and enable project plugin | aiu init --tool opencode | Host plugin trust must be explicit. |
| Codex CLI/Desktop | Experimental | Stop hook from a repo-local Codex plugin | pnpm exec aiu hook-stop --tool codex; blocks only when trusted state yields a concrete safe prompt and hosts.stopHookBlocking.codex is enabled | .agents/plugins/marketplace.json, plugins/ai-umpire/** | Install repo-local plugin and approve hook trust | aiu init --tool codex | Stop-hook continuation must not surprise the user; trust prompt is required. |
| Claude Code | Experimental | Project Stop hook | pnpm exec aiu hook-stop --tool claude-code; blocks only when trusted state yields a concrete safe prompt and hosts.stopHookBlocking.claude-code is enabled | .claude/settings.json | Review project settings and approve hook trust | aiu init --tool claude-code | Project settings can run local commands, so conflicts are preserved by default. |
| Gemini CLI, Cursor, Aider, Continue.dev, Goose | Unsupported recipe targets | No confirmed project Stop hook contract in this package | Document recipes only; no installer writes files | none | Tool-specific | none | Wrappers/MCP/rules may not have autonomous idle continuation semantics. |
| Generic MCP server | Unsupported as a continuation hook | Host must call MCP explicitly | Possible future tool-provider integration only | none | Host MCP trust | none | MCP alone cannot continue an idle session unless the host invokes it. |
| Git hooks and GitHub Actions | Unsupported for interactive continuation | Repository/CI events, not agent idle events | Validation only | none | Git/CI trust | none | Wrong lifecycle; these must not drive interactive continuation. |
The experimental stop-hook command safe-allows by default. It emits a blocking host response only after configured trusted state loads successfully, the shared decision engine selects continue or safe repair, the rendered prompt is concrete, and per-host stop-hook blocking is explicitly enabled in config.
Local Development
Run release checks:
pnpm run release:checkaiu doctor is read-only. It reports Node version, package metadata and built assets, repository/config health, host install files and package-backed entrypoints for enabled hosts, state path writability, and configured trusted command executable availability. It does not execute trusted commands.
Troubleshooting
Use pnpm exec aiu doctor --json as the first diagnostic command. Stable check kind values identify setup problems such as config-missing, config-invalid, host-file-missing, host-entrypoint-unmanaged, state-path-not-writable, and trusted-command-missing.
Use pnpm exec aiu paths --json to inspect the resolved package root, config path, .umpire/ state paths, host install paths, and trusted command executable paths. Diagnostic output redacts token-like values where practical.
Idle-mode troubleshooting stays local and read-only until you run an explicit mutating command. aiu doctor --json reports planning and quality mode enablement, matching trusted command availability, whip state validity, disabled idle modes, and stale or orphaned whip task ownership. aiu status --json shows the selected decision, selected target metadata, rendered prompt metadata, and whip summary. Inspect .umpire/logs/continuation.jsonl only as local diagnostic evidence; logs, agent narration, issue prose, and comments are never trusted pass/fail evidence for quality or planning.
Package Surfaces
@tjalve/aiu- public package asset helpers@tjalve/aiu/opencode- OpenCode plugin composition helpersaiu- package CLI foundationaiu hook-stop- experimental Codex and Claude Code Stop hook entrypoint backed by trusted-state decisions and explicit stop-hook blocking policy- quality idle continuation - trusted
qualitystate selection and prompt rendering throughaiu status,aiu hook-stop, and supported host runtimes aiu whip- durable idle task state inspection and explicit add/cancel/complete transitionsloadAiuConfig- typed config discovery, defaults, and validationrenderAiuPromptSection- repo-level prompt section customization helperrunAiuDoctorandgetAiuResolvedPaths- read-only diagnostics and path inspection helpers
Development
pnpm install --frozen-lockfile --ignore-scripts
pnpm run build
pnpm test
pnpm run typecheck
pnpm run pack:dry-run
pnpm run release:check
pnpm exec aiu --helpPlanning Specs
- Functional requirements
- M1 - Package, CLI, Config, And Host Foundation
- M2 - Continuation State And Policy Engine
- M3 - Provider Status Integration And Stop Hooks
- M4 - Whip Tasks, Quality Idle Work, And Planning Continuation
- M5 - Existing Repository Migration And Release Readiness
- Release controls
Publish Checklist
Repository controls before public publish:
- the repository is public only after release controls are enabled
mainis protected by GitHub branch protection or a rulesetmainrequires signed commits, PR review, CODEOWNERS review, and therelease-checkCI status- force pushes and branch deletion are disabled for
main - GitHub secret scanning and push protection are enabled
.github/CODEOWNERSowns release-sensitive files- workflow permissions default to read-only
- the
npm-publishenvironment requires explicit reviewer approval - npm trusted publishing is configured for
ZarK/ai-umpire, workflow filepublish.yml, environmentnpm-publish, and onlynpm stage publish - no long-lived
NPM_TOKENis required for the primary publish path
Before tagging:
- register the maintainer signing key with GitHub
- confirm a fresh signed test commit is shown as verified by GitHub
- confirm the package version
- keep the working tree clean so the tarball matches git
- authenticate to npm only for account/scope administration; publishing uses trusted publishing
Release flow:
pnpm run release:check
git tag publish-0.0.2
git push origin main publish-0.0.2The tagged release workflow stages the package with npm provenance from the protected npm-publish environment. A maintainer must approve or reject the staged package in npm before it becomes public:
npm stage publish . --access public --ignore-scripts