The harness gives every agent the same loop in the form it natively understands: run shipmoor scan against the agent’s edits and route the findings back where the agent will read them. Four adapters ship today. Each installs with shipmoor harness install <agent>, manages its own clearly-marked block, and removes cleanly with shipmoor harness uninstall <agent>. This page is the routing overview: the matrix below, then the per-agent shape, with dedicated pages for the two deepest integrations.
The adapter matrix
| Agent | Install command | Files managed | How the decision is delivered |
|---|---|---|---|
| Claude Code | shipmoor harness install claude | .claude/settings.json (PostToolUse and Stop hooks) | hookSpecificOutput.additionalContext (feedback) · stderr and exit 2 (block) |
| Cursor | shipmoor harness install cursor | .cursor/hooks.json (afterFileEdit and stop); --soft → .cursor/rules/shipmoor-harness.md | followup_message (feedback / block) |
| Codex | shipmoor harness install codex | guidance block in AGENTS.md | the wrapper re-prompts Codex via shipmoor harness codex -- <args> |
| Aider | shipmoor harness install aider | a lint-cmd in .aider.conf.yml | Aider’s own repair loop, triggered by a non-zero lint exit |
All four adapters are CLI clients: they need the shipmoor binary on your PATH, they re-implement no detection of their own, and if the CLI is missing they degrade to a no-op rather than breaking the agent. See Install & modes for the gate, the install surface, and observe / feedback / block.
Claude Code: lifecycle hooks
The deepest integration. install claude mirrors a PostToolUse hook (matching Edit|MultiEdit|Write|NotebookEdit) and a Stop hook into the top-level hooks key of .claude/settings.json, beside any hooks you already have, and records provenance under a "// shipmoor:harness" sibling key so uninstall restores your exact pre-install file. The adapter probes your local claude version first and refuses builds below the hook-schema minimum, naming both versions.
After every edit, the PostToolUse hook scans the changed set and the Stop hook runs a final pass. In feedback mode a finding comes back as hookSpecificOutput.additionalContext; in block mode a threshold breach exits 2 with the findings on stderr, which Claude feeds back to the model. The harness never edits CLAUDE.md; that file belongs to Agent Skills.
Full setup and a worked block → fix → clear cycle are on Use with Claude Code.
Cursor: native hooks (with a soft fallback)
Cursor ships a real lifecycle-hook surface, so this is a hard adapter at parity with Claude. install cursor mirrors an afterFileEdit hook and a stop hook into .cursor/hooks.json (with the same "// shipmoor:harness" provenance key), beside any user hooks.
afterFileEdit is the recorder: Cursor gives it no channel back to the agent, so it scans and writes the findings report. stop is the gate: on routable findings it returns a followup_message that Cursor auto-submits as the next turn, bounded by max_feedback_cycles. Pass --soft to decline hooks and instead write a fully harness-owned .cursor/rules/shipmoor-harness.md that points the agent at the watcher’s report; the module owns both surfaces and migrates between them.
The Cursor harness never touches .cursor/rules/shipmoor.md (the Agent Skills file). Details and the soft-vs-hard tradeoff are on Use with Cursor.
Codex: the wrapped runtime
Codex has no reliable native hook, so it runs through a wrapper instead of a hook. install codex writes a managed guidance block into AGENTS.md; you then drive the loop with:
shipmoor harness codex -- <your codex args>
The wrapper forwards your args, environment, and working directory to Codex, snapshots the working tree, scans what changed, and re-prompts Codex with any findings, bounded by max_feedback_cycles so it never spins. Its exit codes are distinct from the CLI’s:
| Exit code | Meaning |
|---|---|
0 | Clean |
1 | Findings remain (in block mode) |
2 | Scan failed |
3 | Codex itself failed |
Aider: the lint-cmd
Aider already has a repair loop: it re-prompts on a failing lint command. The adapter plugs Shipmoor into it by managing a lint-cmd block in .aider.conf.yml that runs:
shipmoor scan --changed --no-color --fail-on high
That is the CLI’s default human report (already agent-readable: rule, file:line, why, and the fix) with colour stripped, and --fail-on high so the scan exits 1 only on a high or critical finding. Exit 1 is what drives Aider’s own fix-and-retry behaviour; no wrapper needed. If you already have a lint-cmd outside any Shipmoor block, the install reports a conflict instead of clobbering it; pass --replace-existing to take it over (recorded as a lint_cmd_replaced warning in status).
Coexistence with Agent Skills
The harness and Agent Skills can both wire into the same project, and they stay out of each other’s way: each writes its own marker-wrapped managed block and never touches the other’s. Concretely, the Claude harness never edits CLAUDE.md, and the Cursor harness never touches .cursor/rules/shipmoor.md; both of those belong to skills. Where the two share a file (AGENTS.md for Codex, .aider.conf.yml for Aider), they live in distinct blocks, so installing or removing one leaves the other byte-for-byte intact.
Every adapter is a thin client of the CLI. It needs
shipmooron yourPATH, it adds no detection logic of its own, and a missing or erroring CLI degrades to a no-op so a tooling problem never blocks your agent.
Next
- Use with Claude Code: the lifecycle-hook setup and a full worked cycle.
- Use with Cursor: native hooks, the soft fallback, and the watcher pairing.
- Using skills with your agent: the behavior layer that pairs with this runtime.