Type to search the docs and updates.

Browse documentation

Maintain and set up

Memory

Project

Project readiness

Upgrade

Automatic upgrade offers

Upgrade options

Migrate

This page covers handoffs, generated-file recovery, packs, hook helpers, git hooks, completion, and the language server. Other maintenance commands have their own pages: project CLI and readiness, upgrade and migrate, and memory.

handoff list

List saved task handoffs across the repository's worktrees:

agnostic-ai handoff list

Each branch gets one row: live worktree (or removed), saved HEAD and date, working changes (clean, dirty, or unknown), task status, PR (- when missing), and handoff file. The newest manual note wins over automatic snapshots. It reads only note headers, from the stores the handoff skill uses.

It suggests removal only when local Git ancestry proves the branch merged into the main checkout's branch and no working changes are pending, so squash merges need your review. It never fetches or deletes files.

revert

Undo a sync --backup: for every generated file and tool instruction file (CLAUDE.md, AGENTS.md, GEMINI.md, CONVENTIONS.md, .agnostic-ai/AGNOSTIC_AI.md), restore <path>.bak with its permissions, never wider than the file's, and remove it. It also restores a nested CLAUDE.md that sync deleted. An unfiltered revert restores intact recorded backups of removed outputs, including those from dropped targets. Paths under sync.unmanaged are never touched. A file that is both a generated file and an instruction file, such as a shared AGENTS.md, is handled once. revert takes the project lock, so it stops while another command writes; --dry-run does not.

FlagDescription
-t, --only, --exceptSelect targets, as in sync.
--dry-runShow what it would do and change nothing.
--forceAlso delete generated files that have no .bak, including generated tool instruction files and your own files at the same paths.
--jsonSame format as sync --json. Actions: "restore", "remove", "preserve" (no .bak, no --force), "skip" (already gone).

cleanup

Remove the <path>.bak backups that sync --backup wrote, and no other .bak files.

agnostic-ai cleanup
agnostic-ai cleanup --dry-run   # preview deletions

packs

Add, update, and remove collections of shared specs. See the packs guide.

agnostic-ai packs add github.com/obra/superpowers@v6.4.2
agnostic-ai packs add ./path/to/pack
agnostic-ai packs list
agnostic-ai packs update [name]            # at the commit in agnostic.packs.lock
agnostic-ai packs update --latest [name]   # move to the newest commit of the ref
agnostic-ai packs remove superpowers

hook paths

Run inside an edit hook to print the files the edit leaves on disk, one per line. Edited paths explains the input, tool detection, and exit codes.

files=$(agnostic-ai hook paths) || exit 1
printf '%s\n' "$files" | grep '\.go$' | while IFS= read -r f; do gofmt -w "$f"; done

Capture the output before the loop, as shown above. Piping it directly into the loop hides failures and lets the hook exit 0.

FlagDescription
-t, --target <name>Tool that sent the event. Defaults to AGNOSTIC_AI_TARGET.
--actionPrint each change as <action><TAB><path> (add, update, delete, move), including deleted files and move sources.
--jsonPrint each change as a JSON array of {action, path, from}. Not with --action.

hook worktree-remove

Remove one clean Git worktree from a Claude Code WorktreeRemove event on stdin. Pair it with your WorktreeCreate hook; it does not change cleanup for worktrees the host creates without one.

agnostic-ai hook worktree-remove --repo "/path/to/repository" --allowed-root "/path/to/disposable worktrees"
FlagDescription
--repo <path>Required. A surviving checkout of the repository, outside the disposable worktrees.
--allowed-root <path>Required. Only descendants of this directory may be removed.

After checking Git's worktree registration and repository metadata, it runs git worktree remove without force, keeping the branch. It refuses the main checkout, the allowed root itself, other repositories, unregistered directories, traversal, symlinks below the allowed root, locked worktrees, and worktrees with changed, untracked, or ignored files (ignored dependencies included; remove them first). It also refuses indexes with assume-unchanged or skip-worktree entries, sparse checkouts included, because those can hide changed contents.

ResultOutputExit
Removedremoved: <path>0
Already gone below the allowed root (also on a repeat call); nothing deleted or prunedalready absent: <path>0
Unsafe input, event data over 1 MiB, or a failed Git operationerror1

Claude Code runs this event instead of its own cleanup, while the directory still exists. A non-zero exit keeps the directory, with no Git fallback.

hook guard

Run inside an after-edit or stop hook, as the spec guard hooks do. It exits 2 with a short report for the agent on a problem, else 0 with no output.

command -v agnostic-ai >/dev/null 2>&1 || exit 0; agnostic-ai hook guard after-edit
command -v agnostic-ai >/dev/null 2>&1 || exit 0; agnostic-ai hook guard stop
  • after-edit reads the event data on stdin, like hook paths, and reports lint errors in the specs the edit touched.
  • stop reports specs changed without a sync. It passes when the agent already continued from a stop hook, so the notice cannot loop.
  • It uses the nearest agnostic-ai.yaml at or above the current directory, and exits 0 when it cannot read the event data or config.
FlagDescription
-t, --target <name>Tool that sent an after-edit event. Defaults to AGNOSTIC_AI_TARGET.

hook memory

Print the MEMORY.md fact lists, personal first, for a session-start hook to add to the model's context. The memory built-in sets this up, and also runs it on Claude Code when a subagent starts.

agnostic-ai hook memory --target codex
ToolOutput
Codex, FactoryPlain text
Cursor{"additional_context": ...}
Gemini CLI, Qoder{"hookSpecificOutput": {"hookEventName": "SessionStart", "additionalContext": ...}}
CopilotThat object for VS Code, plus a top-level additionalContext for Copilot CLI
Claude Code{"hookSpecificOutput": {"hookEventName": "SubagentStart", "additionalContext": ...}} with personal memory only, since CLAUDE.md gives subagents the project list. Nothing when CLAUDE.md imports the personal list too.
  • Output stays under 6,000 bytes, cut at a line end with a note naming the full index. Hidden characters are dropped first (see session start), except a zero-width joiner or non-joiner between two non-ASCII characters, as in an emoji or a Persian word.
  • With no project, it prints nothing. With memory.personal: repo, it names the personal folder even before an index exists; in checkout mode, no index means no output. It finds the project as the shared-memory skill does.
FlagDescription
-t, --target <name>Tool that runs the hook. Defaults to AGNOSTIC_AI_TARGET.

hook worktree-refresh

Rerun Claude Code's configured environment setup in one registered linked worktree:

agnostic-ai hook worktree-refresh --repo /path/to/main --worktree "/path/to/linked worktree"

--repo is a checkout of the owning repository and --worktree the linked checkout. The helper checks that the worktree is registered to that repository and refuses the main checkout. Run agnostic-ai sync in that worktree first when setup changes: it resets the completion marker only when the generated setup script matches current source, including output-path overrides such as outputs.claude.dir. See refresh an existing worktree for how markers work.

  • Setup runs from the worktree with a 600-second limit; output and failures pass through. Cancellation stops the setup processes it owns; a successful setup can leave background services running. Other worktrees keep their markers.
  • On Windows it needs Git Bash, from CLAUDE_CODE_GIT_BASH_PATH or the Git for Windows install, never a bash launcher from PATH.
  • It installs dependencies only if your setup command does. It does not check application health or change other tools' setup, and normal Claude setup hooks still run once per worktree.

hook run

Test a synced hook spec without starting a session. See test a hook for the sample events, results, and exit codes.

agnostic-ai hook run protect-files --edit .github/workflows/tests.yml --expect block
FlagDescription
-t, --target <names>Test only these tools. Defaults to every configured tool the hook applies to.
--edit <path>Send a PreToolUse or PostToolUse event that edits this file.
--bash <command>Send a PreToolUse or PostToolUse event that runs this shell command.
--prompt <text>Prompt text for UserPromptSubmit.
--runtime vscodeWith --target cline, model Cline VS Code TaskStart on Unix instead of the SDK. Windows launcher selection is not modeled.
--payload <file>Send this JSON file to every tool, for events the flags above do not cover.
--expect allow|blockFail unless every tool gives this result.
--include-assumedCount assumed results toward --expect and the comparison between tools.
--format text|jsonjson prints one report with a targets array; see the JSON fields. Defaults to text.

install-hook

Install git hooks; see the git hooks guide. By default it installs a pre-commit hook that runs project --check --against index, so a commit fails if regenerated files are not staged. Project hooks prefer the installed local binary over PATH.

agnostic-ai install-hook            # writes .git/hooks/pre-commit (local)
agnostic-ai install-hook --shared   # writes .githooks/ and sets core.hooksPath
agnostic-ai install-hook --global   # checks global specs before committing

agnostic-ai install-hook --post-checkout            # writes .git/hooks/post-checkout and post-merge
agnostic-ai install-hook --post-checkout --shared   # writes both hooks in .githooks/

An existing hook keeps its content, and the checks go at its end. A hook that would stop before them (its first line does not select sh or bash, or it has an exec or an unindented exit) is left alone, and the command prints the lines to add by hand.

  • --shared writes .githooks/<hook> at the root of the main working tree, even from a linked worktree. It stops if core.hooksPath already points elsewhere.
  • --global is for the global specs folder, which must be the root of its own git repository. The hook runs lint --global --strict, validate --global, and sync --global --check (skipped in a linked worktree). Not with --shared or --post-checkout; it stops when core.hooksPath points elsewhere or the hook already runs the project sync --check.
  • --post-checkout installs post-checkout and post-merge, which run agnostic-ai project from the worktree root after a branch or worktree checkout (not a single file) or a merge, pull included. See regenerate on checkout.

completion

Generate a shell completion script.

agnostic-ai completion bash > ~/.local/share/bash-completion/completions/agnostic-ai  # or /etc/bash_completion.d/
agnostic-ai completion zsh > "${fpath[1]}/_agnostic-ai"
agnostic-ai completion fish > ~/.config/fish/completions/agnostic-ai.fish
agnostic-ai completion powershell | Out-String | Invoke-Expression

Restart your shell or source the file. Completing --target reads agnostic-ai.yaml in the current directory, or offers every target if there is none.

lsp

Start the language server on stdin and stdout. The VS Code extension starts it for a configured workspace, using agnostic-ai.binaryPath; other editors can launch agnostic-ai lsp for Markdown and YAML files.

  • It lints the project's configured sources, custom and absolute directories included, when you open or save a file. Unsaved edits are not linted.
  • Config and spec load failures appear on the source file, with the parser location when known, or as a workspace error.
  • A successful check clears resolved diagnostics from every affected file, deleted sources included. After a failed load, earlier diagnostics stay until you fix the problem and save a project file.