Shipmoor plugs into Claude Code on three levels, and the integration is strongest when you use all of them. The CLI is the scan engine, the source of truth for findings. The Skills are always-on instructions in CLAUDE.md that make the agent want to scan and triage its own work. The Harness is a set of lifecycle hooks in .claude/settings.json that make the scan actually happen after each edit and gate the result before Claude declares the task done. Skills shape behavior; hooks enforce it. This page wires up both.
Prerequisites
- CLI:
shipmoor --versionreports0.10.0. - Authorization: authorize the device to an account. Agent Skills and Agent Harness are unlimited on Free and Pro; check the device with
shipmoor auth status. - PATH:
shipmooris on yourPATH, because the hooks Claude runs invoke the bareshipmoorcommand. Confirm withcommand -v shipmoor.
shipmoor --version # shipmoor 0.10.0
shipmoor auth status # authorized account and device
command -v shipmoor # ~/.shipmoor/bin/shipmoor
If the installation is not authorized, complete device authorization. Skills and Harness are unlimited on Free and Pro.
Step 1: Install the Skills
Skills teach Claude the Shipmoor behaviors. Installing them writes a single marker-wrapped managed block into your project’s CLAUDE.md:
shipmoor skills install claude # write the managed block into CLAUDE.md
shipmoor skills status # what's installed where
shipmoor skills uninstall claude # remove only the managed block
The write is idempotent; re-run it any time to update the block in place. uninstall removes only the managed block, leaving the rest of your CLAUDE.md untouched. The five skills it installs:
| Skill | What it does |
|---|---|
shipmoor-review | Run the scan, triage findings, explain blockers, and report a review-readiness verdict. |
shipmoor-agent-guard | Inject compact pre-edit guardrails that prevent common defects before review. |
shipmoor-intent-contract | Compare the change against its declared intent and surface what didn’t earn its claim. |
shipmoor-fix | Repair findings introduced by the current change and re-scan until the gate passes. |
shipmoor-pr-preflight | Run the final PR-readiness path: diff scan, structural gate, and a copyable PR note. |
See The five skills for the behavior each one drives. In Claude Code, shipmoor-review also responds to slash triggers; type any of these to invoke it on demand:
| Trigger | Effect |
|---|---|
/shipmoor | Scan the current change and report the verdict. |
/shipmoor-changed | Scan the working-tree change-set (scan --changed). |
/shipmoor-gate | Run the structural gate and report whether the change is ready. |
/shipmoor-explain | Expand a finding into the why and the fix. |
Step 2: Install the Harness hooks
Skills make Claude willing to scan, but they don’t guarantee a scan runs. The harness does: shipmoor harness install claude writes managed lifecycle hooks into .claude/settings.json. Claude reads hooks from the top-level hooks key, so the harness mirrors its entries there and records provenance in a sibling "// shipmoor:harness" key. The managed shape looks like this:
{
"hooks": {
"PostToolUse": [
{
"matcher": "Edit|MultiEdit|Write|NotebookEdit",
"hooks": [
{ "type": "command", "command": "shipmoor harness hook claude-code post-tool-use" }
]
}
],
"Stop": [
{
"hooks": [
{ "type": "command", "command": "shipmoor harness hook claude-code stop" }
]
}
]
},
"// shipmoor:harness": {
"note": "Managed by shipmoor-harness (Claude Code adapter). Uninstall removes exactly these entries."
}
}
The install is idempotent, so re-running it is byte-identical. uninstall restores the file byte-for-byte. And because pre-bundle installs wrote the standalone shipmoor-harness … command form, a reinstall recognizes and migrates those legacy hook entries to the bundled shipmoor harness … form.
shipmoor harness install claude # write hooks into .claude/settings.json
shipmoor harness status # mode + adapter for this project
shipmoor harness uninstall claude # restore settings.json byte-for-byte
Skills vs hooks. Skills make the agent want to scan: that’s behavior. Hooks make the scan happen and gate the result: that’s enforcement. Use both. They live in separate files (
CLAUDE.mdvs.claude/settings.json) and never conflict: the skills installer ownsCLAUDE.mdand never touchessettings.json, and the harness owns its hook entries and never editsCLAUDE.md.
How the loop behaves
Once the hooks are installed, the integrity loop runs on Claude’s own lifecycle:
- After each edit, the
PostToolUsehook fires on anyEdit,MultiEdit,Write, orNotebookEditand scans the working-tree change-set.- In feedback mode, a finding is returned as
hookSpecificOutput.additionalContextso Claude reads it as context and keeps working. - In block mode, a finding is written as
[shipmoor-harness] …to stderr and the hook exits 2, so Claude surfaces it to the model as a hard block.
- In feedback mode, a finding is returned as
- Before Claude finishes, the
Stophook runs the gate one more time, so a session can’t end on an unaddressed blocker. - A clean scan, observe mode, or a missing CLI is a no-op (exit 0): the harness never interrupts the agent over tooling problems or when there’s nothing to say.
- The whole loop is bounded by
max_feedback_cycles, so it can never trap a session in an endless fix-rescan cycle.
Choose a mode
shipmoor harness mode feedback # day-to-day: findings flow back as context
shipmoor harness mode block # firmest local mode
shipmoor harness status # verify the active mode + adapter
Use feedback for everyday work: Claude sees each finding inline and self-corrects without being hard-stopped. Use block when you want the local Harness loop to enforce the gate. Self-managed CI supports Scan only. See Install & modes.
A real example: a block in flight
With the project in block mode, an edit that introduces a phantom import triggers the Stop/PostToolUse block path. The harness writes the finding to stderr and exits 2, and Claude feeds it straight back to the model:
[shipmoor-harness] Shipmoor found 1 issue (1 high).
[high] pay.py:6 python.phantom_import
Local module 'receipt_engine' is referenced but no file matches under PYTHONPATH.
→ 'receipt_engine' looks local but does not resolve from project module paths. Add the file, fix PYTHONPATH, or remove the import.
Shipmoor caught a change that referenced a module it can’t find; it doesn’t claim the change is correct, only that this import doesn’t resolve. Claude reads the block, fixes the import, and the next scan clears.
Troubleshooting
| Symptom | Likely cause | Fix |
|---|---|---|
| Claude finishes despite open findings | The project is in observe mode (report-only, never affects the verdict). | shipmoor harness mode feedback (or block), then confirm with shipmoor harness status. |
| Hooks never seem to fire | The hooks weren’t written to .claude/settings.json, or shipmoor isn’t on PATH for the command Claude runs. | Re-run shipmoor harness install claude; verify command -v shipmoor resolves in the same environment Claude launches in. |
Old shipmoor-harness … hook entries linger | Pre-bundle installs wrote the standalone command form. | Re-run shipmoor harness install claude; a reinstall recognizes and migrates legacy entries to the bundled shipmoor harness … form. |
The standalone
shipmoor-harnessscript is a recognized legacy alias only. Since 0.5.0 the harness is theshipmoor harness …subcommand of the main binary. Don’t add new hooks that call the old script.
Next
- Cursor integration: the same three-level wiring for Cursor.
- The self-correction loop: how feedback and block mode drive the fix-rescan cycle.
- The five skills: what each Skill does and the loop it drives.
- Install & modes: the harness command surface and mode contract.