diff --git a/CHANGELOG.md b/CHANGELOG.md index dc301c3..424bec0 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,17 @@ # Changelog +## Unreleased + +### Added + +- Support for Cursor, Codex CLI, Antigravity CLI and Gemini CLI alongside Claude Code. `init --agents claude,cursor,codex,antigravity,gemini` chooses which to wire; by default it wires Claude Code plus any agent whose config folder the project already has. See the Agents section of the README for each agent's config file and caveats. +- `status` and `doctor` report every wired agent, and `clean` removes canaryhook's hooks from all of them. +- The tamper check covers every agent's hook config, and `hooks = false` in `.codex/config.toml`. + +### Changed + +- `.canaryhook/canaries.json` records the agents `init` wired. A state file from 0.3.0 without that field still means Claude Code. + ## 0.3.0 Run `canaryhook init --force` on an existing install to add the `PostToolUse` hook. diff --git a/README.md b/README.md index 5bec22c..c566f2c 100644 --- a/README.md +++ b/README.md @@ -7,6 +7,8 @@ read, then blocks and records the moment an agent reads one or lets a canary string leave the machine. It is a smoke detector for AI coding sessions: no model, no signatures, and close to zero false positives by construction. +Works with Claude Code, Cursor, Codex CLI, Antigravity CLI and Gemini CLI. + Part of the [aiagentflow](https://aiagentflow.dev) suite. Website: **[aiagentflow.dev/canaryhook](https://aiagentflow.dev/canaryhook)** @@ -40,10 +42,42 @@ Or with Homebrew: brew install aiagentflow/tap/canaryhook ``` -`init` plants four decoys, registers `PreToolUse`, `PostToolUse` and -`SessionStart` hooks in `.claude/settings.json` (merging with hooks you already -have), and adds the decoys plus `.canaryhook/` to `.gitignore`. Upgrading from -0.2.0, run `canaryhook init --force` to add the `PostToolUse` hook. +`init` plants four decoys, registers canaryhook's hooks for each agent you use +(merging with hooks you already have), and adds the decoys plus `.canaryhook/` +to `.gitignore`. Upgrading from 0.2.0, run `canaryhook init --force` to add the +`PostToolUse` hook. + +## Agents + +By default `init` wires Claude Code plus any agent the project already uses, +judged by its config folder. Name them yourself with `--agents`: + +```bash +canaryhook init --agents claude,cursor,codex +``` + +| Agent | `--agents` | Config file | Before a call | After a call | Session start | +| --- | --- | --- | --- | --- | --- | +| Claude Code | `claude` | `.claude/settings.json` | `PreToolUse` | `PostToolUse` | `SessionStart` | +| Cursor | `cursor` | `.cursor/hooks.json` | `preToolUse` | `postToolUse` | `sessionStart` | +| Codex CLI | `codex` | `.codex/hooks.json` | `PreToolUse` | `PostToolUse` | `SessionStart` | +| Antigravity CLI | `antigravity` | `.agents/hooks.json` | `PreToolUse` | not supported | `SessionStart` | +| Gemini CLI | `gemini` | `.gemini/settings.json` | `BeforeTool` | `AfterTool` | `SessionStart` | + +Per agent: + +- **Codex CLI** runs project hooks only once you trust them. After `init`, run + `/hooks` in Codex and approve canaryhook's; until then nothing is watched. +- **Antigravity CLI** does not pass a tool's output to its hooks, so the output + path is not available there. A sweep like `grep -r AKIA .` is only caught + once a canary string shows up in a later call. +- **Gemini CLI** hides a result that holds a canary from the model, so on that + agent the output path also keeps the value out of the agent's context. +- **Cursor** blocks any call whose permission hook prints nothing, so the + Cursor hook always answers explicitly, allowing a clean call. + +`status` and `doctor` report every wired agent, and `clean` removes canaryhook's +hooks from all of them. ## Commands @@ -56,8 +90,9 @@ canaryhook verify # exit non-zero if anything tripped (for CI) canaryhook clean # remove decoys, unregister the hook ``` -Flags: `--json` on every command, `--commit` to track decoys in git instead of -ignoring them, `--force` to replant, `--keep-alerts` on clean. +Flags: `--json` on every command, `--agents` on init to choose the agents, +`--commit` to track decoys in git instead of ignoring them, `--force` to +replant, `--keep-alerts` on clean. ## Why @@ -104,7 +139,8 @@ Four checks then run on every tool call: blocked, but it is recorded and the agent is told the value is fake. - **Tamper path.** The hook trips when a call would blind canaryhook: deleting or rewriting `.canaryhook/`, running `canaryhook clean`, removing the hook - from `.claude/settings.json`, or setting `disableAllHooks`. Otherwise an + from an agent's config file, or switching hooks off there (`disableAllHooks` + in Claude Code, `hooks = false` in Codex). Otherwise an agent that tripped a decoy could erase the record and carry on. You can still do all of these yourself from a terminal, where no hook runs. diff --git a/backlog/tasks/task-7 - Document-multi-agent-support.md b/backlog/tasks/task-7 - Document-multi-agent-support.md index 529f790..6cf1dc9 100644 --- a/backlog/tasks/task-7 - Document-multi-agent-support.md +++ b/backlog/tasks/task-7 - Document-multi-agent-support.md @@ -1,9 +1,10 @@ --- id: TASK-7 title: Document multi-agent support -status: To Do +status: Done assignee: [] created_date: '2026-10-24 05:41' +updated_date: '2026-10-24 05:58' labels: - multi-agent dependencies: @@ -23,6 +24,6 @@ README: which agents are supported, the --agents flag, the per-agent config file ## Acceptance Criteria -- [ ] #1 README lists every supported agent and its config file -- [ ] #2 Caveats are stated per agent +- [x] #1 README lists every supported agent and its config file +- [x] #2 Caveats are stated per agent diff --git a/package.json b/package.json index 63ee6de..5e4c8d0 100644 --- a/package.json +++ b/package.json @@ -32,6 +32,10 @@ "ai-agents", "prompt-injection", "claude-code", + "cursor", + "codex", + "gemini-cli", + "antigravity", "mcp", "cli", "exfiltration"