Hooks Reference
Complete reference for all 10 ctx-tree hooks. All hooks are installed automatically by the marketplace installer.
Hook input format
All Claude Code hooks receive a JSON object on stdin. Common fields:
{
session_id: string;
cwd: string;
tool_name?: string; // PreToolUse / PostToolUse
tool_input?: object; // PreToolUse / PostToolUse
tool_response?: object; // PostToolUse
prompt?: string; // UserPromptSubmit
}
Hook output format
Hooks write JSON to stdout. Relevant fields:
{
// Block a tool call (PreToolUse only):
decision?: 'block';
reason?: string;
// Inject context into Claude's window:
hookSpecificOutput?: {
additionalContext: string;
};
// Continue with modifications (PostToolUse):
continue?: boolean;
}
SessionStart hooks
session-start.mjs
Trigger: Session startup and resume
Writes a compact tool guide to hookSpecificOutput.additionalContext reminding Claude to use ctx-tree tools instead of native ones. Includes the full redirect map and example calls.
No DB writes. Fires on every session start.
UserPromptSubmit hooks
userpromptsubmit-capture.mjs
Trigger: Every non-empty user prompt submission
- Reads
input.prompt - Deduplicates by
sha256(content)— no duplicate nodes for the same prompt - Inserts a
promptnode with:source_uri: prompt://<hash-prefix>metadata: { session_id, title, cwd, turn_index }
- Wires a
followsedge:prompt → previous_response(if one exists this session) - Returns
nodeIdinadditionalContextfor subagent context building
Stop hooks
stop-response-capture.mjs
Trigger: Every assistant response completion
Reads CLAUDE_TRANSCRIPT_PATH for the session transcript. For the latest assistant turn:
- Extracts thinking content →
thinkingnode - Extracts response content →
responsenode - Wires edges:
response → prompt(follows)response → nodes_referenced_this_turn(derived_from)thinking → response(derived_from)
PreToolUse hooks
pretooluse-redirect.mjs
Trigger: Read | Grep | Bash | WebFetch | PowerShell | Monitor
For each matched tool:
| Native tool | Condition | Redirects to |
|---|---|---|
Read | any | ctx_tree_read({ path, lines }) |
Grep | any | ctx_tree_grep({ pattern, path, ... }) |
Bash | command contains grep/rg/cat | ctx_tree_grep or ctx_tree_read |
WebFetch | any | ctx_tree_browse({ url }) |
Monitor | any | ctx_tree_monitor({ command }) |
PowerShell | command contains grep/cat | ctx_tree_grep or ctx_tree_read |
Returns { decision: "block" } + hookSpecificOutput.additionalContext with the redirect instruction.
pretooluse-agent-enrich.mjs
Trigger: Agent
- Extracts keywords from the agent prompt
- Queries
ctx_tree_searchfor relevant stored nodes - Appends to the agent's prompt:
- Top 5 matching node IDs with excerpts
- A compact tool map of available ctx-tree tools
Passes through (does not block the Agent call).
pretooluse-skill-recall.mjs
Trigger: Skill
Checks for a stored skill://name node matching the skill being invoked. On cache hit, blocks the native Skill call and returns the stored content directly. On miss, passes through.
pretooluse-proxy.mjs
Trigger: Read | Grep | Bash | WebFetch (only when ~/.ctx-tree/proxy-mode file exists)
Soft advisory mode. Does not block the native tool. Injects a suggestion to use the ctx-tree equivalent. Remove ~/.ctx-tree/proxy-mode to disable.
PostToolUse hooks
posttooluse-agent-capture.mjs
Trigger: Agent (after completion)
Reads the agent's output and tool use list. Creates a summary node. Wires summarizes edges to every node the subagent touched.
posttooluse-skill-capture.mjs
Trigger: Skill (after completion)
Stores the Skill output content as a skill://name node for instant recall on the next invocation.
posttooluse-websearch-capture.mjs
Trigger: WebSearch (after completion)
Queues all result URLs for background browsing via ctx_tree_browse. URLs are processed asynchronously — the hook returns immediately without waiting. Results are available for recall in subsequent turns or future sessions.
Project hash algorithm
All hooks and the MCP server must agree on the same ~/.ctx-tree/<project-hash>/ path. The hash is computed as:
const gitRoot = execSync('git rev-parse --show-toplevel', { cwd }).toString().trim();
const firstCommit = execSync('git rev-list --max-parents=0 HEAD', { cwd }).toString().trim();
const hash = sha256(`${gitRoot}:${firstCommit}`).slice(0, 16);
// Fallback: sha256(cwd).slice(0, 16) if not a git repo
Hooks import this from hooks/lib/project-hash.mjs. The MCP server implements the same algorithm in mcp/src/project-hash.ts.