Keep your own Claude Code hooks
Status: ShippedYour repo may already commit a .claude/settings.json with hooks, such as
a formatter after every edit or a guard before shell commands. This guide
shows how to keep them working in CodeSense worktrees, alongside CodeSense’s
own hook and any hooks your team adds.
CodeSense’s own hook never touches your settings
To drive the status dot on a terminal tab (in Beta), CodeSense adds a hook that runs
.claude/hooks/codesense-notify.sh. It writes that hook into
.claude/settings.local.json in the worktree, never into
.claude/settings.json:
- Claude Code runs hooks from both files, so yours and CodeSense’s both fire.
- Existing keys and hooks in
settings.local.jsonare kept, and the file is excluded from git. - If your
settings.local.jsonis tracked by git, is a symlink, or isn’t valid JSON, CodeSense leaves it alone. - If your committed
settings.jsonalready runscodesense-notifyfor an event, CodeSense doesn’t add it again.
If your team context has no .claude/settings.json, that’s all there is to
it: your repo’s settings are untouched.
When your team ships a settings.json too
Say Ledgerline’s billing team wants every agent to run a check when it
stops, so it adds billing/content/.claude/settings.json:
{ "hooks": { "Stop": [ { "hooks": [{ "type": "command", "command": "npm run lint --silent" }] } ] }}Meanwhile ledgerline/api commits its own .claude/settings.json:
{ "permissions": { "allow": ["Bash(npm test:*)"] }, "hooks": { "PostToolUse": [ { "matcher": "Edit|Write", "hooks": [{ "type": "command", "command": "npx prettier --write ." }] } ] }}By default, a team file replaces the repo’s file of the same name in each worktree. To combine them instead, mark the team’s file as a merge file:
- In the file tree for the
billingteam, right-click.claude/settings.json. - Choose Mark as merge file. The file gets a badge: “Merges with the source file instead of overwriting it”.
- Open the file and switch the viewer from Authored to Merged
preview, then pick
apito see exactly what the worktree will get.
For the example above, the merged file keeps the repo’s permissions and
PostToolUse hook and adds the team’s Stop hook.
How the merge decides
- Objects merge key by key, all the way down.
- A key only the team file has is added.
- Where both files set the same key, the repo’s value is kept.
- Lists aren’t combined. If both files have hooks for the same event
(both define
PostToolUse, say), the repo’s list for that event is kept and the team’s is dropped.
So the safe pattern is: put team hooks under events your repos don’t use, and let each repo’s own settings win where they overlap. Check the Merged preview for each repo when in doubt.
Related
- Teams and inheritance: merge marks and the other rules for how team files combine.
- Launch your first agent: the status dot this hook drives.
How we know this is accurate 11 sources
Checked against the app at 1b3d5a69d73473db077dfb44f4390b42cded6bd4.
Feature inventory
-
WW-3 -
A-14 -
D-11
Code
-
src-tauri/src/commands/content_engine.rs -
src-tauri/src/install/merge_marks.rs -
src-tauri/src/install/story_linker.rs -
src-tauri/src/shared/json_io.rs -
src-tauri/src/shared/config_format.rs -
src/features/dashboard/lib/use-merge-marks.ts -
src/features/dashboard/components/status-nav/nav-context-menu.tsx -
src/features/viewer/components/merge-marked-viewer.tsx