Skip to content

Latest commit

 

History

History
955 lines (702 loc) · 54.9 KB

File metadata and controls

955 lines (702 loc) · 54.9 KB

Platform Support Matrix

This document provides a comprehensive comparison of all platforms supported by context-mode, including their hook paradigms, capabilities, configuration, and known limitations.

Overview

context-mode supports 17 client platforms, plus the OpenClaw gateway integration, across three hook paradigms:

Paradigm Platforms
JSON stdin/stdout Claude Code, Gemini CLI, VS Code Copilot, JetBrains Copilot, GitHub Copilot CLI, Cursor, Codex CLI, Qwen Code, Kimi Code, Antigravity CLI (agy), Kiro
TS Plugin OpenCode, KiloCode, OpenClaw
MCP-only Antigravity, Zed, Pi, OMP (Oh My Pi)

The MCP server layer is 100% portable and needs no adapter. Only the hook layer requires platform-specific adapters.

Prerequisites

All platforms (except Claude Code plugin install) require a global install:

npm install -g context-mode

This puts the context-mode binary in PATH, which is required for:

  • MCP server: "command": "context-mode" (replaces ephemeral npx -y context-mode)
  • Hook dispatcher: context-mode hook <platform> <event> (replaces node ./node_modules/... paths)
  • Utility commands: context-mode doctor, context-mode upgrade
  • Persistent upgrades: ctx-upgrade updates the global binary in-place

Main Comparison Table

Feature Claude Code Qwen Code Gemini CLI VS Code Copilot JetBrains Copilot GitHub Copilot CLI Cursor OpenCode KiloCode OpenClaw Codex CLI Kimi Code Antigravity Antigravity CLI (agy) Kiro Zed Pi OMP
Paradigm json-stdio json-stdio json-stdio json-stdio json-stdio json-stdio json-stdio ts-plugin ts-plugin ts-plugin json-stdio json-stdio mcp-only json-stdio json-stdio mcp-only mcp-only mcp-only
PreToolUse equivalent PreToolUse PreToolUse BeforeTool PreToolUse PreToolUse preToolUse preToolUse tool.execute.before tool.execute.before tool_call:before PreToolUse PreToolUse -- PreToolUse (bounded) preToolUse -- -- --
PostToolUse equivalent PostToolUse PostToolUse AfterTool PostToolUse PostToolUse postToolUse postToolUse tool.execute.after tool.execute.after tool_call:after PostToolUse PostToolUse -- PostToolUse (capture-only) postToolUse -- -- --
PreCompact equivalent PreCompact PreCompact PreCompress PreCompact PreCompact preCompact -- experimental.session.compacting experimental.session.compacting registerContextEngine -- PreCompact -- -- -- -- -- --
SessionStart SessionStart SessionStart SessionStart SessionStart SessionStart sessionStart -- (buggy in Cursor) -- -- command:new SessionStart SessionStart -- -- -- -- -- --
Stop equivalent -- -- -- Stop Stop agentStop stop -- -- -- Stop Stop -- Stop (best-effort, unverified on agy 1.0.6) -- -- -- --
Can modify args Yes Yes Yes Yes Yes Yes Yes Yes Yes Yes No Yes -- -- -- -- -- --
Can modify output Yes Yes Yes Yes Yes No No Yes (caveat) Yes (caveat) No No Yes -- -- -- -- -- --
Can inject session context Yes Yes Yes Yes Yes Yes Yes -- -- Yes Yes Yes -- -- -- -- -- --
Can block tools Yes Yes Yes Yes Yes Yes Yes Yes (throw) Yes (throw) Yes Yes Yes -- Bounded Yes -- -- --
Config location ~/.claude/settings.json ~/.qwen/settings.json ~/.gemini/settings.json .github/hooks/*.json .github/hooks/*.json ~/.copilot/hooks/context-mode.json + ~/.copilot/mcp-config.json .cursor/hooks.json or ~/.cursor/hooks.json opencode.json kilo.json openclaw.json ~/.codex/hooks.json + ~/.codex/config.toml ~/.kimi-code/config.toml ~/.gemini/antigravity/mcp_config.json ~/.gemini/config/mcp_config.json + ~/.gemini/config/hooks.json ~/.kiro/settings/mcp.json ~/.config/zed/settings.json ~/.pi/settings.json ~/.omp/agent/mcp_config.json
Session ID field session_id session_id session_id sessionId (camelCase) sessionId (camelCase) session_id (snake_case; sessionId defensive fallback) conversation_id sessionID (camelCase) sessionID (camelCase) pid-${ppid} fallback N/A session_id N/A conversationId (unverified) pid-${ppid} fallback N/A N/A N/A
Project dir env CLAUDE_PROJECT_DIR QWEN_PROJECT_DIR GEMINI_PROJECT_DIR CLAUDE_PROJECT_DIR CLAUDE_PROJECT_DIR stdin cwd stdin workspace_roots ctx.directory (plugin init) ctx.directory (plugin init) process.cwd() N/A stdin cwd N/A stdin workspace.current_dir (refs-backed; workspacePaths[0] fallback) stdin cwd N/A N/A OMP_PROCESSING_AGENT_DIR
MCP/tool naming mcp__server__tool mcp__server__tool mcp__server__tool f1e_ prefix f1e_ prefix mcp__server__tool MCP:<tool> in hook payloads native ctx_* plugin tools native ctx_* plugin tools native ctx_* plugin tools mcp__server__tool mcp__context-mode__tool mcp__server__tool context-mode/<tool> mcp__server__tool mcp__server__tool mcp__server__tool mcp__server__tool
Hook command format context-mode hook claude-code <event> context-mode hook qwen-code <event> context-mode hook gemini-cli <event> context-mode hook vscode-copilot <event> context-mode hook jetbrains-copilot <event> context-mode hook copilot-cli <event> context-mode hook cursor <event> TS plugin (no command) TS plugin (no command) TS plugin (no command) context-mode hook codex <event> context-mode hook kimi <event> N/A context-mode hook antigravity-cli <event> context-mode hook kiro <event> N/A N/A N/A
Hook registration settings.json hooks object settings.json hooks object settings.json hooks object .github/hooks/*.json .github/hooks/*.json ~/.copilot/hooks/context-mode.json (version: 1) hooks.json native hook arrays opencode.json plugin array kilo.json plugin array openclaw.json plugins.entries ~/.codex/hooks.json config.toml hooks array N/A plugin root hooks.json (PreToolUse, PostToolUse, Stop; bundle mirrors hooks/hooks.json for agy validate/install) Kiro CLI hooks (JSON stdin) N/A N/A N/A
MCP server command context-mode (or plugin auto) context-mode context-mode context-mode context-mode context-mode context-mode N/A (native plugin tools) N/A (native plugin tools) N/A (native plugin tools) context-mode context-mode context-mode context-mode context-mode context-mode context-mode context-mode
Plugin distribution Claude plugin registry npm global npm global npm global npm global npm global npm global npm global npm global npm global npm global npm global npm global agy plugin (npm global) npm global npm global npm global npm global
Session dir ~/.claude/context-mode/sessions/ ~/.qwen/context-mode/sessions/ ~/.gemini/context-mode/sessions/ .github/context-mode/sessions/ or ~/.vscode/context-mode/sessions/ .github/context-mode/sessions/ ~/.copilot/context-mode/sessions/ ~/.cursor/context-mode/sessions/ ~/.config/opencode/context-mode/sessions/ ~/.config/kilo/context-mode/sessions/ ~/.openclaw/context-mode/sessions/ ~/.codex/context-mode/sessions/ ~/.kimi-code/context-mode/sessions/ ~/.gemini/context-mode/sessions/ ~/.gemini/context-mode/sessions/ ~/.kiro/context-mode/sessions/ ~/.config/zed/context-mode/sessions/ ~/.pi/context-mode/sessions/ ~/.omp/context-mode/sessions/

Legend

  • Yes = Fully supported
  • -- = Not supported
  • (caveat) = Supported with known issues

Platform Details

Claude Code

Status: Fully supported (primary platform)

Hook Paradigm: JSON stdin/stdout

Claude Code is the primary platform for context-mode. All hooks communicate via JSON on stdin/stdout. The adapter reads raw JSON input, normalizes it into platform-agnostic events, and formats responses back into Claude Code's expected output format.

Hook Names:

  • PreToolUse -- fires before a tool is executed
  • PostToolUse -- fires after a tool completes
  • PreCompact -- fires before context compaction
  • SessionStart -- fires when a session starts, resumes, or compacts
  • UserPromptSubmit -- fires when user submits a prompt
  • Stop -- fires when the assistant turn is about to end

Blocking: permissionDecision: "deny" in response JSON

Arg Modification: updatedInput field at top level of response

Output Modification: updatedMCPToolOutput for MCP tools, additionalContext for appending

Session ID Extraction Priority:

  1. UUID from transcript_path field
  2. session_id field
  3. CLAUDE_SESSION_ID environment variable
  4. Parent process ID fallback

Hook Commands:

context-mode hook claude-code pretooluse
context-mode hook claude-code posttooluse
context-mode hook claude-code precompact
context-mode hook claude-code sessionstart
context-mode hook claude-code userpromptsubmit

Known Issues: None significant.


Gemini CLI

Status: Fully supported

Hook Paradigm: JSON stdin/stdout

Gemini CLI uses the same JSON stdin/stdout paradigm as Claude Code but with different hook names and response format.

Hook Names:

  • BeforeTool -- equivalent to PreToolUse
  • AfterTool -- equivalent to PostToolUse
  • PreCompress -- equivalent to PreCompact (advisory only, async, cannot block)
  • SessionStart -- fires when a session starts

Blocking: decision: "deny" in response (NOT permissionDecision)

Arg Modification: hookSpecificOutput.tool_input (merged with original, not updatedInput)

Output Modification: decision: "deny" + reason replaces output; hookSpecificOutput.additionalContext appends

Environment Variables:

  • GEMINI_PROJECT_DIR -- primary project directory
  • CLAUDE_PROJECT_DIR -- alias (also works)

Hook Commands:

context-mode hook gemini-cli beforetool
context-mode hook gemini-cli aftertool
context-mode hook gemini-cli precompress
context-mode hook gemini-cli sessionstart

Known Issues / Caveats:

  • PreCompress is advisory only (async, cannot block)
  • No decision: "ask" support
  • Hooks don't fire for subagents yet

OpenCode

Status: Fully supported

Hook Paradigm: TS Plugin

OpenCode uses a TypeScript plugin paradigm instead of JSON stdin/stdout. Hooks and the 11 ctx_* tools are registered via the plugin array in opencode.json; no separate mcp block or stdio MCP child is required.

Hook Names:

  • tool.execute.before -- equivalent to PreToolUse
  • tool.execute.after -- equivalent to PostToolUse
  • experimental.session.compacting -- equivalent to PreCompact (experimental)
  • experimental.chat.system.transform -- SessionStart-equivalent (cross-session resume injection)

Blocking: throw Error in tool.execute.before handler

Arg Modification: output.args mutation

Output Modification: output.output mutation (TUI bug for bash, see issue #13575)

Session ID: input.sessionID (camelCase, note the uppercase ID)

Project Directory: Available via ctx.directory in plugin init, not via environment variable

Desktop markers: OpenCode desktop shells also export OPENCODE_CLIENT=desktop and OPENCODE_TERMINAL=1; context-mode treats those as OpenCode identity signals when the CLI markers are absent.

Configuration:

  • opencode.json or .opencode/opencode.json
  • Plugin registered in the plugin array with npm package names
  • ctx_* tools are native plugin tools, not mcp__server__tool calls
  • KiloCode uses the same plugin path via kilo.json; context-mode upgrade removes stale mcp.context-mode entries for both hosts while preserving other MCP servers

Cross-session resume: When OpenCode triggers experimental.session.compacting (auto on context overflow OR manual /compact), context-mode saves a snapshot to its per-project SQLite store. The NEXT new session in the same project — typically after Ctrl+D then re-running opencode, or starting a fresh chat — claims that snapshot via experimental.chat.system.transform and prepends it to system[1] (preserves OpenCode's [header, body] cache fold). The current session never claims its OWN snapshot back (self-injection guard, v1.0.106). To verify the injection landed, run with OPENCODE_DEBUG=1 and grep for <!-- context-mode v in the system prompt — that's the visible marker.

Known Issues / Caveats:

  • SessionStart is broken (issue #14808, no hook issue #5409) — we use experimental.chat.system.transform as a surrogate
  • Output modification has TUI rendering bug for bash tool (issue #13575)
  • experimental.session.compacting is marked experimental and may change
  • No canInjectSessionContext capability
  • Resume snapshots are scoped per-project (DB sharded by SHA-256 of ctx.directory); no cross-project bleed

Codex CLI

Status: Supported (MCP active, hooks require [features].hooks = true)

Hook Paradigm: JSON stdin/stdout

Codex CLI's Rust backend (codex-rs) includes a hook system using the same JSON stdin/stdout wire protocol as Claude Code. Hooks are configured via hooks.json.

Hook Names:

  • PreToolUse -- fires before a tool is executed
  • PostToolUse -- fires after a tool completes
  • PreCompact -- fires before context compaction on Codex builds that emit it
  • SessionStart -- fires when a session starts, resumes, or clears
  • UserPromptSubmit -- fires when user submits a prompt
  • Stop -- fires when agent turn ends (can continue with followup)

Blocking: permissionDecision: "deny" in hookSpecificOutput, or exit code 2 Arg Modification: NOT supported (updatedInput returns error) Output Modification: NOT supported (updatedMCPToolOutput returns error) Context Injection: additionalContext in hookSpecificOutput (PostToolUse, SessionStart only). PreToolUse does NOT support additionalContext — the codex formatter handles this automatically (deny works, context/modify/ask responses are dropped).

Configuration:

  • Hook config: $CODEX_HOME/hooks.json or ~/.codex/hooks.json (JSON format, same structure as Claude Code)
  • MCP config: $CODEX_HOME/config.toml or ~/.codex/config.toml (TOML format, [mcp_servers] section)
  • Feature flags: use [features].hooks (or codex --enable hooks) if you need to force hooks on. Prefer [features].hooks; [features].codex_hooks remains accepted as a legacy alias in current Codex builds.

Hook Commands:

context-mode hook codex pretooluse
context-mode hook codex posttooluse
context-mode hook codex precompact
context-mode hook codex sessionstart
context-mode hook codex userpromptsubmit
context-mode hook codex stop

Known Issues / Caveats:

  • PreToolUse additionalContext is unsupported — context injection works via PostToolUse and SessionStart instead. The codex formatter handles this automatically (deny works, context is dropped). Source: codex-rs/hooks/src/engine/output_parser.rs:267.

  • PreToolUse input rewriting still needs upstream updatedInput support. Track: openai/codex#18491.

  • PreCompact support is runtime-gated: context-mode configures it and treats a missing registration as a warning, because older Codex builds may not emit the event. The hook stores the resume snapshot out-of-band and SessionStart restores it.

  • Codex emits structured tool names such as Bash and apply_patch; context-mode only normalizes legacy shell aliases.

  • updatedInput and updatedMCPToolOutput are in the schema but NOT implemented

  • Default hook timeout: 600 seconds

  • Older context-mode releases used a plugins/context-mode -> .. symlink shim because Codex rejects the repository root ("./") as an empty local plugin source path. On native Windows, Git can check that symlink out as a regular file containing only .., which makes codex plugin add context-mode@context-mode fail with missing plugin.json. Current releases avoid this by declaring the Codex marketplace plugin as a relative Git source (url: "./"), so Codex materializes the installed marketplace root and finds .codex-plugin/plugin.json without any symlink or junction.

    After installation succeeds, verify that Codex hooks are enabled in %USERPROFILE%\.codex\config.toml:

    [features]
    hooks = true

    Some Codex builds may also require plugin_hooks = true. Without hook support, the MCP tools can still work, but automatic session capture and persistent memory may not record events.


Kimi Code

Status: Supported (JSON stdin/stdout hooks + MCP)

Hook Paradigm: JSON stdin/stdout

Kimi Code CLI uses the same JSON stdin/stdout wire protocol as Claude Code and Codex, configured via ~/.kimi-code/config.toml with [[hooks]] array tables. The key difference from Codex is that Kimi accepts additionalContext, updatedInput, and permissionDecision: "ask" in PreToolUse responses — the codex formatter drops these, but the kimi formatter emits them fully.

Hook Names:

  • PreToolUse — fires before a tool is executed
  • PostToolUse — fires after a tool completes
  • PreCompact — fires before context compaction
  • SessionStart — fires when a session starts or resumes
  • UserPromptSubmit — fires when user submits a prompt (payload is ContentPart[])
  • Stop — fires when the agent turn ends

Blocking: permissionDecision: "deny" in hookSpecificOutput, or exit code 2

Arg Modification: updatedInput inside hookSpecificOutput wrapper

Output Modification: additionalContext inside hookSpecificOutput

Context Injection: additionalContext in hookSpecificOutput (works in all hook types)

Configuration:

  • Hooks: ~/.kimi-code/config.toml ([[hooks]] array tables)
  • MCP: ~/.kimi-code/mcp.json
  • Sessions: ~/.kimi-code/context-mode/sessions/

Hook Commands:

context-mode hook kimi pretooluse
context-mode hook kimi posttooluse
context-mode hook kimi precompact
context-mode hook kimi sessionstart
context-mode hook kimi userpromptsubmit
context-mode hook kimi stop

Known Issues / Caveats:

  • UserPromptSubmit sends prompt as a ContentPart[] array; the kimi hook normalizes this to a string for downstream extractors.
  • SessionStart additionalContext injection is emitted but acceptance by the host is not documented in Kimi Code CLI docs (fails-open if unsupported).

Qwen Code

Status: Supported (MCP + hooks — identical wire protocol to Claude Code)

Hook Paradigm: JSON stdin/stdout (same as Claude Code)

Qwen Code (by Alibaba/Qwen team) uses the exact same hook wire protocol as Claude Code, verified from source (hookRunner.ts, claude-converter.ts). Hooks are configured inside ~/.qwen/settings.json under the hooks key.

Hook Names: PreToolUse, PostToolUse, SessionStart, PreCompact, UserPromptSubmit (Qwen supports 12 events total, context-mode uses these 5)

Blocking: permissionDecision: "deny" or exit code 2 Arg Modification: updatedInput in response Output Modification: updatedMCPToolOutput in response Context Injection: additionalContext in response

Configuration:

  • Settings + hooks: ~/.qwen/settings.json
  • MCP: mcpServers in settings.json
  • Sessions: ~/.qwen/context-mode/sessions/

Detection: MCP clientInfo (qwen-cli-mcp-client-* pattern), QWEN_PROJECT_DIR env var, or ~/.qwen/ config dir.

Hook Commands:

context-mode hook qwen-code pretooluse
context-mode hook qwen-code posttooluse
context-mode hook qwen-code sessionstart
context-mode hook qwen-code precompact
context-mode hook qwen-code userpromptsubmit

Antigravity

Status: MCP-only (no hooks)

Hook Paradigm: MCP-only

Google Antigravity is an AI-powered IDE by Google/DeepMind. It shares the ~/.gemini/ directory structure with Gemini CLI but uses a separate config path for MCP servers. Antigravity does not expose a public hook API — only MCP integration is available.

Configuration:

  • ~/.gemini/antigravity/mcp_config.json (JSON format)
  • MCP servers configured in mcpServers object

Detection:

  • Auto-detected via MCP protocol handshake (clientInfo.name: "antigravity-client")
  • Fallback: CONTEXT_MODE_PLATFORM=antigravity environment variable override

Routing Instructions:

  • GEMINI.md auto-written at project root on first MCP server startup
  • Antigravity reads GEMINI.md natively (same filename as Gemini CLI, different content — no hook references)

Capabilities:

  • PreToolUse: --
  • PostToolUse: --
  • PreCompact: --
  • SessionStart: --
  • Can modify args: --
  • Can modify output: --
  • Can inject session context: --

Known Issues / Caveats:

  • No hook support — only routing instruction files for enforcement (~60% compliance)
  • Shares ~/.gemini/ directory with Gemini CLI — session DB uses project hash to prevent collision
  • No verified Antigravity-specific environment variables exist

Sources:


Antigravity CLI (agy)

Status: Plugin — MCP + routing rule + routing skill + bounded hooks

Hook Paradigm: MCP for tools + JSON stdin/stdout hooks

The standalone Antigravity CLI (agy) is the command-line companion to Google Antigravity. Unlike the Antigravity IDE, agy has a native plugin system (agy plugin install|import) and a hook surface (~/.gemini/config/hooks.json). context-mode ships as a first-class agy plugin (configs/antigravity-cli/) bundling the MCP server, a routing rule, a routing skill, and bounded PreToolUse/PostToolUse/Stop hooks. It shares the ~/.gemini/ session root with the rest of the Gemini family; agy reads its global MCP profile from ~/.gemini/config/mcp_config.json (not the IDE's ~/.gemini/antigravity/mcp_config.json).

Verified: agy 1.0.10 (Linux). The GitHub-subpath install requires agy ≥ 1.0.7 (subpath + branch resolution landed in 1.0.7 — run agy update to upgrade). No agy hook event was added, removed, or renamed through 1.0.10, and the shared ~/.gemini/config/hooks.json location has been canonical since agy 1.0.8, so the bundle's PreToolUse/PostToolUse/Stop wiring is current.

Install:

  • npm install -g context-mode (the plugin's MCP server + hooks run the context-mode binary), then agy plugin install https://github.com/mksglu/context-mode/tree/main/configs/antigravity-cli. agy clones the repo, resolves the configs/antigravity-cli subpath (with branch resolution), and registers the bundle's native plugin.json + mcp_config.json, routing rule, routing skill, and hooks into its plugin profile under ~/.gemini/config/plugins/context-mode/. If ctx_* tools don't appear after an upgrade, clear agy's stale tool-schema cache (~/.gemini/antigravity-cli/mcp/context-mode/) and restart agy (agy caches MCP schemas and doesn't refresh them).
  • Already on Claude Code: agy plugin import claude can import that existing Claude setup, but the native context-mode agy bundle above is the supported path for agy hooks.
  • MCP only: add context-mode to ~/.gemini/config/mcp_config.json under mcpServers ({"command":"context-mode"}).

Detection:

  • MCP protocol handshake (clientInfo.name: "agy" / "antigravity-cli")
  • Config-dir markers for a bare shell: ~/.local/bin/agy, ~/.gemini/antigravity-cli/, or ~/.gemini/config/mcp_config.json — probed before the generic ~/.claude / ~/.gemini fallbacks so a gemini-cli→agy migrant is not mis-detected as Claude Code (#774)
  • Fallback: CONTEXT_MODE_PLATFORM=antigravity-cli override

Hook payload: the only refs-backed field is the working directory, read from workspace.current_dir — an object field, per the upstream hook example (refs/platforms/antigravity-cli/examples/title/title.sh:10, examples/title/README.md:11). context-mode reads workspace.current_dir FIRST for the project dir, falling back to workspacePaths[0]. The remaining payload shape — { conversationId, stepIdx, toolCall: { name, args }, error, workspacePaths: [..], transcriptPath } — is empirically-derived/unverified (no upstream agy doc confirms it) and is treated as best-effort. The event name arrives via argv (set in hooks.json), and the hook CWD is ~/.gemini/config. context-mode maps these onto its routing/capture pipeline (workspace.current_dir/workspacePaths[0]→project dir, conversationId→session id [unverified], run_commandBash, view_fileRead, grep_searchGrep, list_dirLS, read_url_contentWebFetch, search_webWebSearch).

Capabilities:

  • PreToolUse: bounded blocking for mapped Bash/Read/Grep/WebFetch surfaces (run_command, view_file, grep_search, web_fetch, read_url_content)
  • PostToolUse: capture-only (records executed tool calls into the session DB)
  • Stop: best-effort capture-only session-end marker (registered, but not observed in agy -p probes)
  • PreCompact / SessionStart / PreInvocation / PostInvocation: -- (not wired)
  • Can modify args / output / inject context: -- (not verified/used)

Known Issues / Caveats:

  • Bounded hook enforcement. context-mode registers PreToolUse only for mapped high-flood tools with existing routing branches. list_dir and search_web are normalized for PostToolUse capture but are not PreToolUse-routed.
  • PreInvocation and PostInvocation are visible in agy's hook list but intentionally not registered; agy 1.0.6 -p probes did not emit them, and their payload/response semantics are not verified against context-mode's pipeline.
  • agy's PostToolUse payload carries no tool-output text, so byte-accounting for tool output is unavailable on this surface; the tool call + project + error state are still captured.
  • Shares ~/.gemini/ with Gemini CLI and Antigravity — session DB uses the project hash to prevent collisions.
  • Gemini function-calling tool exposure. agy exposes MCP tools as Gemini function declarations, and Gemini's API rejects JSON Schema const / additionalProperties — a rejected schema makes agy silently drop that tool from the model's function list (the agent then hand-rolls the tool via shell scripts instead of calling it). context-mode emits Gemini-safe tool schemas (constenum, additionalProperties stripped) so the ctx_* tools are exposed. agy also caches each server's tool schemas under ~/.gemini/antigravity-cli/mcp/<server>/ and does not refresh them on reconnect, so a cache captured by an older context-mode keeps the tools hidden — delete ~/.gemini/antigravity-cli/mcp/context-mode/ and restart agy to force a re-fetch.

Kiro

Status: Supported (MCP + native PreToolUse/PostToolUse hooks)

Hook Paradigm: JSON stdin/stdout

Kiro is an AWS agentic IDE and CLI. It supports MCP servers via ~/.kiro/settings/mcp.json using the standard mcpServers JSON format. The Kiro CLI also fires preToolUse/postToolUse hooks over JSON stdin (exit code 2 blocking), which context-mode's kiro adapter implements for routing enforcement and tool-event capture. agentSpawn (the Kiro SessionStart equivalent) and stop are not yet wired, so session restore after compaction is not available.

Detection:

  • Auto-detected via MCP protocol handshake (clientInfo.name: "Kiro CLI")

Configuration:

  • Global: ~/.kiro/settings/mcp.json (JSON format, standard mcpServers object)
  • Project: .kiro/settings/mcp.json

Routing Instructions:

  • KIRO.md written at project root on first MCP server startup

Hook System:

  • preToolUse/postToolUse hooks via JSON stdin (implemented)
  • Blocking: exit code 2 (similar to Gemini CLI pattern)
  • agentSpawn (SessionStart equivalent) and stop are not yet wired

Hook Commands:

context-mode hook kiro pretooluse
context-mode hook kiro posttooluse

Built-in Tools:

  • fs_read / read, fs_write / write, execute_bash / shell, use_aws / aws

Capabilities:

  • PreToolUse: Yes
  • PostToolUse: Yes
  • PreCompact: --
  • SessionStart: -- (agentSpawn not yet wired)
  • Can modify args: --
  • Can modify output: --
  • Can inject session context: -- (via agentSpawn, not yet wired)
  • Can block tools: Yes (exit code 2)

Known Issues / Caveats:

  • agentSpawn (SessionStart) and stop are not yet wired, so session restore after compaction is unavailable — copy KIRO.md to the project root for session-start routing
  • Kiro IDE hooks use a UI-based "Run Command" shell action; stdin format unverified

Sources:


VS Code Copilot

Status: Fully supported (preview)

Hook Paradigm: JSON stdin/stdout

VS Code Copilot uses the same JSON stdin/stdout paradigm as Claude Code with PascalCase hook names. It also provides unique hooks for subagent lifecycle.

Hook Names:

  • PreToolUse -- fires before a tool is executed
  • PostToolUse -- fires after a tool completes
  • PreCompact -- fires before context compaction
  • SessionStart -- fires when a session starts
  • Stop -- fires when agent stops (unique to VS Code)
  • SubagentStart -- fires when a subagent starts (unique to VS Code)
  • SubagentStop -- fires when a subagent stops (unique to VS Code)

Blocking: permissionDecision: "deny" (same as Claude Code)

Arg Modification: updatedInput inside hookSpecificOutput wrapper (NOT flat like Claude Code)

{
  "hookSpecificOutput": {
    "hookEventName": "PreToolUse",
    "updatedInput": { ... }
  }
}

Output Modification: additionalContext inside hookSpecificOutput, or decision: "block" + reason

MCP Tool Naming: Uses f1e_ prefix (not mcp__server__tool)

Session ID: sessionId (camelCase, not session_id)

Configuration:

  • Primary: .github/hooks/*.json
  • Also reads: .claude/settings.json
  • MCP config: .vscode/mcp.json

Environment Detection:

  • VSCODE_PID environment variable
  • TERM_PROGRAM=vscode

Hook Commands:

context-mode hook vscode-copilot pretooluse
context-mode hook vscode-copilot posttooluse
context-mode hook vscode-copilot precompact
context-mode hook vscode-copilot sessionstart

Known Issues / Caveats:

  • Preview status -- API may change without notice
  • Matchers are parsed but IGNORED (all hooks fire on all tools)
  • Tool input property names use camelCase (filePath not file_path)
  • Response must be wrapped in hookSpecificOutput with hookEventName

JetBrains Copilot

Status: Fully supported (preview)

Hook Paradigm: JSON stdin/stdout

JetBrains Copilot (GitHub Copilot plugin for JetBrains IDEs) uses the same JSON stdin/stdout paradigm and hook wire protocol as VS Code Copilot. It shares hook names, response format, and MCP tool naming conventions.

Hook Names:

  • PreToolUse -- fires before a tool is executed
  • PostToolUse -- fires after a tool completes
  • PreCompact -- fires before context compaction
  • SessionStart -- fires when a session starts
  • Stop -- fires when agent stops
  • SubagentStart -- fires when a subagent starts
  • SubagentStop -- fires when a subagent stops

Blocking: permissionDecision: "deny" (same as VS Code Copilot)

Arg Modification: updatedInput inside hookSpecificOutput wrapper (same as VS Code Copilot)

{
  "hookSpecificOutput": {
    "hookEventName": "PreToolUse",
    "updatedInput": { ... }
  }
}

Output Modification: additionalContext inside hookSpecificOutput, or decision: "block" + reason

MCP Tool Naming: Uses f1e_ prefix (same as VS Code Copilot)

Session ID: sessionId (camelCase)

Configuration:

  • Hook config: .github/hooks/*.json
  • MCP config: Settings UI (Settings > Tools > AI Assistant > MCP)

Hook Commands:

context-mode hook jetbrains-copilot pretooluse
context-mode hook jetbrains-copilot posttooluse
context-mode hook jetbrains-copilot precompact
context-mode hook jetbrains-copilot sessionstart

Known Issues / Caveats:

  • Preview status -- API may change without notice
  • Shares the same hook wire protocol as VS Code Copilot
  • MCP servers are configured via Settings UI, not a file
  • Requires GitHub Copilot plugin v1.5.57+

GitHub Copilot CLI

Status: Supported (native hooks + MCP)

Hook Paradigm: JSON stdin/stdout

The standalone GitHub Copilot CLI (copilot) is user-home rooted under ~/.copilot (override with COPILOT_HOME). Its hook config uses camelCase event keys, and its command output contract is top-level (permissionDecision, modifiedArgs, additionalContext) rather than the VS Code hookSpecificOutput wrapper — context-mode's copilot-cli adapter formats responses accordingly.

Hook config keys: (Copilot CLI 1.0.59 fires six events context-mode uses; verified against the @github/copilot binary)

  • preToolUse -- fires before a tool is executed
  • postToolUse -- fires after a tool completes
  • preCompact -- fires before context compaction
  • sessionStart -- fires when a session starts
  • userPromptSubmitted -- fires when the user submits a prompt (user-prompt capture)
  • agentStop -- fires when the agent stops (session-end capture)

Hook config shape: flat { "type": "command", "command": "..." } entries (NOT the Claude-Code nested { matcher, hooks: [...] } shape). context-mode also writes a top-level "version": 1, but this field is optional — the Copilot CLI accepts hook config files that omit it (copilot-cli changelog.md:1109). We pin it for self-documentation, not because the runtime requires it.

Blocking: top-level permissionDecision: "deny" + permissionDecisionReason

Arg Modification: top-level modifiedArgs

Output Modification: not supported (the posttooluse hook is capture-only)

Context Injection: top-level additionalContextSessionStart is the confirmed channel (verified reaching the model). PreToolUse/PostToolUse additionalContext is best-effort/unverified; context-mode's posttooluse hook is capture-only and emits no context.

Configuration:

  • Plugin (recommended): context-mode ships a Copilot CLI plugin bundle at configs/copilot-cli/ — a root .mcp.json (MCP), hooks.json (the six capture hooks), a routing skill (skills/context-mode/), and a .github/plugin/plugin.json manifest. copilot plugin install mksglu/context-mode:configs/copilot-cli registers all of it in one command (no clone, no context-mode upgrade/agent call). The bundle's .mcp.json pins CONTEXT_MODE_PLATFORM=copilot-cli, so the server self-identifies as Copilot and ctx_upgrade/detection resolve copilot-cli even when Claude Code is co-installed (whose ~/.claude/ would otherwise win). Verified on Windows via copilot --plugin-dir <bundle>: ctx_execute resolves and the PostToolUse hook captures non-MCP tool I/O into the session DB. (This .mcp.json is the one committed instance in the repo — .gitignore un-ignores exactly this path, since a Copilot plugin has no other way to declare MCP.)
  • MCP (manual, no plugin): register with Copilot CLI's own command — copilot mcp add context-mode -- context-mode — which writes ~/.copilot/mcp-config.json (or $COPILOT_HOME/mcp-config.json). (Also copilot mcp list / copilot mcp remove.)
  • Hook config (manual, no plugin): $COPILOT_HOME/hooks/context-mode.json or ~/.copilot/hooks/context-mode.json (written by context-mode upgrade; standalone hooks fire — verified — independent of any plugin)
  • Instruction files: .github/copilot-instructions.md, AGENTS.md

Detection:

  • MCP protocol handshake (clientInfo.name: "GitHub Copilot CLI" / "copilot-cli")
  • Config-dir marker: a context-mode-written file under ~/.copilot/ (or $COPILOT_HOME — the marker check honors it) — mcp-config.json or hooks/context-mode.json, not a bare ~/.copilot/ directory, so a co-installed-but-unconfigured Copilot CLI is not mis-detected (probed before the generic ~/.claude fallback)
  • Fallback: CONTEXT_MODE_PLATFORM=copilot-cli override

Hook Commands:

context-mode hook copilot-cli pretooluse
context-mode hook copilot-cli posttooluse
context-mode hook copilot-cli precompact
context-mode hook copilot-cli sessionstart
context-mode hook copilot-cli userpromptsubmit
context-mode hook copilot-cli stop

Known Issues / Caveats:

  • The top-level "version": 1 is optional: the Copilot CLI accepts hook config files that omit the version field (copilot-cli changelog.md:1109). context-mode pins "version": 1 for self-documentation; omitting it does not stop hooks from firing.
  • Event names can be camelCase or PascalCase — the Copilot CLI accepts PascalCase event names alongside camelCase (copilot-cli changelog.md:1065). context-mode uses the native camelCase names; PascalCase is not silently ignored.
  • COPILOT_HOME relocates the hook config, the MCP config, and the context-mode session-DB root (the adapter's getSessionDir() honors it, so the server reads sessions from the same place the hook runtime writes them).

Sources:


Cursor

Status: Supported (native hooks, v1 scope)

Hook Paradigm: JSON stdin/stdout

Cursor uses native lower-camel hook names and flat hook entries in .cursor/hooks.json or ~/.cursor/hooks.json. context-mode treats Cursor as a first-class adapter and does not rely on Claude-compat wrappers for official support.

Hook Names:

  • preToolUse -- fires before a tool is executed
  • postToolUse -- fires after a tool completes
  • stop -- fires when agent turn ends (can send followup_message to continue loop)
  • afterAgentResponse -- fires after assistant response (fire-and-forget, receives full response text)
  • sessionStart -- documented but currently rejected by Cursor's validator (forum report)

Blocking: { "permission": "deny", "user_message": "..." }

Arg Modification: not natively supported (Cursor does not have updated_input)

Output Modification: not supported in v1

Session Context Injection: { "additional_context": "..." }

Session ID Extraction Priority:

  1. conversation_id (stdin JSON)
  2. CURSOR_TRACE_ID environment variable
  3. Parent process ID fallback

Platform Detection Env Vars:

  • CURSOR_TRACE_ID (MCP server context)
  • CURSOR_CLI (integrated terminal context)
  • ~/.cursor/ directory fallback (medium confidence)

Configuration:

  • Project: .cursor/hooks.json
  • User: ~/.cursor/hooks.json
  • MCP config: .cursor/mcp.json or ~/.cursor/mcp.json
  • Marketplace plugin (recommended): .cursor-plugin/plugin.json at the repo root auto-registers MCP, hooks, rules, and skills. Manifest explicitly points hooks at ./hooks/cursor/hooks.json to avoid colliding with the Claude-format ./hooks/hooks.json. Local install: ln -s <repo> ~/.cursor/plugins/local/context-mode. Plugin hook commands use npx -y context-mode hook cursor <event> so no global install is required.

Plugin/native duplication: context-mode doctor warns when both the plugin and .cursor/hooks.json register context-mode hooks (each event would otherwise fire twice). Remove one configuration to keep events single-fire.

Hook Commands:

context-mode hook cursor pretooluse
context-mode hook cursor posttooluse
context-mode hook cursor stop

Known Issues / Caveats:

  • preCompact is intentionally not shipped in v1
  • stop hook receives: conversation_id, status, loop_count, transcript_path; returns followup_message to continue
  • afterAgentResponse is fire-and-forget (receives text, no return value expected)
  • Hook payloads name MCP tools as MCP:<tool> and need adapter normalization
  • Claude-compatible Cursor behavior exists, but native Cursor config is the supported path
  • additional_context in postToolUse and sessionStart hooks is accepted but NOT surfaced to the model (Cursor upstream bug — forum #155689, forum #156157). Routing enforcement relies on .mdc rules file and MCP tool descriptions instead.

OpenClaw

Status: Fully supported

Hook Paradigm: TS Plugin (gateway plugin via api.registerHook() / api.on())

OpenClaw is an OpenAI-stack agent gateway. context-mode ships as a native gateway plugin that registers hooks through OpenClaw's plugin API rather than the JSON stdin/stdout wire protocol. The same plugin entry also registers context-mode as a context engine, owning compaction.

Hook Names:

  • tool_call:before -- equivalent to PreToolUse
  • tool_call:after -- equivalent to PostToolUse
  • command:new -- equivalent to SessionStart (fires on each new gateway command)
  • before_prompt_build -- lifecycle hook for routing instruction injection
  • registerContextEngine (with ownsCompaction) -- equivalent to PreCompact

Blocking: return { block: true, blockReason: "..." } from the tool_call:before handler

Arg Modification: mutate event.params in the tool_call:before handler (or return { params: ... })

Output Modification: not supported (the plugin paradigm exposes args/context, not the rendered tool output)

Context Injection: via before_prompt_build (session-level) and registerContextEngine (compaction-level)

Path Resolution:

  • Detection root: ~/.openclaw/
  • Plugin install: ~/.openclaw/extensions/context-mode/
  • Project config: openclaw.json or .openclaw/openclaw.json
  • Global config fallback: ~/.openclaw/openclaw.json
  • Project dir: process.cwd() (the gateway provides no dedicated env var)
  • Memory dir: project-relative ./memory
  • Session dir: ~/.openclaw/context-mode/sessions/
  • Routing instructions: AGENTS.md

Configuration:

  • openclaw.json registers context-mode under plugins.entries["context-mode"] ({ "enabled": true })
  • plugins.slots.contextEngine = "context-mode" enables ownership of compaction
  • No CLI hook command; OpenClaw imports the plugin module directly

Notes / Caveats:

  • TS plugin paradigm — hooks run in-process, so there is no shell command to chmod and no platform-specific stdin/stdout quirks
  • ask decisions are converted to block (with the original reason) since the gateway has no interactive confirmation path
  • context decisions inside tool_call:before are dropped — context injection must be routed through before_prompt_build or the registered context engine
  • Session ID falls back to pid-${process.ppid} when the gateway does not surface one

Zed

Status: MCP-only (no hooks)

Hook Paradigm: MCP-only

Zed is a code editor with first-class MCP support but no hook pipeline. context-mode runs purely through Zed's context_servers configuration; routing enforcement falls back to the AGENTS.md instruction file (~60% compliance).

Hook Support:

  • PreToolUse: --
  • PostToolUse: --
  • PreCompact: --
  • SessionStart: --
  • Stop: --
  • Can modify args: --
  • Can modify output: --
  • Can inject session context: --

The hook adapter exists only to satisfy the interface contract — every parser throws Error("Zed does not support hooks") and every formatter returns undefined.

Path Resolution:

  • Detection root: ~/.config/zed/
  • Settings file: ~/.config/zed/settings.json
  • MCP registration: context_servers object inside settings.json
  • Session dir: ~/.config/zed/context-mode/sessions/
  • Routing instructions: AGENTS.md (sourced from configs/zed/AGENTS.md in the package, with an inline fallback if missing)

Detection:

  • Auto-detected via the presence of ~/.config/zed/
  • Override via CONTEXT_MODE_PLATFORM=zed

Notes / Caveats:

  • No hook adapter implies no automatic routing — the model must follow AGENTS.md voluntarily
  • No marketplace or plugin registry for Zed; getInstalledVersion() always reports not installed
  • validateHooks always returns a single warn row reminding the user that Zed exposes only MCP integration
  • configureAllHooks, setHookPermissions, and updatePluginRegistry are intentional no-ops

OMP (Oh My Pi)

Status: MCP-only (no hooks)

Hook Paradigm: MCP-only

Oh My Pi (OMP) is a Pi-compatible harness that stores its agent state under ~/.omp/agent/ (overridable via OMP_PROCESSING_AGENT_DIR). Before the dedicated adapter, OMP detection fell through to pi and storage rooted under another harness's directory (typically ~/.claude/), per issue #473. The OMP adapter exists primarily to keep ~/.omp/context-mode/ isolated, not to provide hook integration — OMP, like Antigravity/Kiro/Zed, runs context-mode purely as an MCP server.

Hook Support:

  • PreToolUse: --
  • PostToolUse: --
  • PreCompact: --
  • SessionStart: --
  • Stop: --
  • Can modify args: --
  • Can modify output: --
  • Can inject session context: --

The hook adapter exists only to satisfy the interface contract — every parser throws Error("OMP does not support hooks") and every formatter returns undefined.

Path Resolution:

  • Agent root: $OMP_PROCESSING_AGENT_DIR if set, else ~/.omp/agent/
  • Settings file: <agent root>/mcp_config.json
  • MCP registration: mcpServers object inside mcp_config.json
  • Session dir: ~/.omp/context-mode/sessions/ (intentionally rooted at ~/.omp/, not the agent dir, so multiple OMP instances on one host share an index without colliding session DBs)
  • Routing instructions: PI.md (Pi-compatible filename — OMP shares the Pi instruction surface)

Detection (priority order, listed BEFORE pi so OMP is never misclassified):

  • OMP_PROCESSING_AGENT_DIR env var (high confidence)
  • ~/.omp/ directory presence (medium confidence)
  • CONTEXT_MODE_PLATFORM=omp override

Notes / Caveats:

  • No hook adapter implies no automatic routing — the model must follow PI.md voluntarily (~60% compliance)
  • No marketplace or plugin registry for OMP; getInstalledVersion() reports not installed unless an extensions/context-mode/package.json exists under the agent dir
  • validateHooks always returns a single warn row reminding the user that OMP exposes only MCP integration
  • configureAllHooks, setHookPermissions, and updatePluginRegistry are intentional no-ops

Capability Matrix (Quick Reference)

Capability Claude Code Qwen Code Gemini CLI VS Code Copilot JetBrains Copilot GitHub Copilot CLI Cursor OpenCode KiloCode OpenClaw Codex CLI Kimi Code Antigravity Antigravity CLI (agy) Kiro Zed Pi OMP
PreToolUse Yes Yes Yes Yes Yes Yes Yes Yes Yes Yes Yes*** Yes -- Bounded Yes -- -- --
PostToolUse Yes Yes Yes Yes Yes Yes Yes Yes Yes Yes Yes Yes -- Yes (capture-only) Yes -- -- --
PreCompact Yes Yes Yes Yes Yes Yes -- Yes* Yes* Yes Yes**** Yes -- -- -- -- -- --
SessionStart Yes Yes Yes Yes Yes Yes Yes -- -- Yes Yes Yes -- -- -- -- -- --
Stop -- -- -- Yes Yes Yes Yes -- -- -- Yes Yes -- Best-effort capture -- -- -- --
Modify Args Yes Yes Yes Yes Yes Yes Yes Yes Yes Yes -- Yes -- -- -- -- -- --
Modify Output Yes Yes Yes Yes Yes No No Yes** Yes** No -- Yes -- -- -- -- -- --
Inject Context Yes Yes Yes Yes Yes Yes Yes -- -- Yes Yes Yes -- -- -- -- -- --
Block Tools Yes Yes Yes Yes Yes Yes Yes Yes Yes Yes Yes Yes -- Bounded Yes -- -- --
MCP/native tool support Yes Yes Yes Yes Yes Yes Yes Native plugin Native plugin Native plugin Yes Yes Yes Yes Yes Yes Yes Yes

* OpenCode experimental.session.compacting is experimental ** OpenCode has a TUI rendering bug for bash tool output (#13575) *** Codex CLI PreToolUse supports deny only (no additionalContext); context injection works via PostToolUse and SessionStart **** Codex CLI PreCompact is runtime-gated on builds that emit the event


Hook Response Format Comparison

Blocking a Tool

Platform Response Format
Claude Code { "permissionDecision": "deny", "reason": "..." }
Gemini CLI { "decision": "deny", "reason": "..." }
VS Code Copilot { "permissionDecision": "deny", "reason": "..." }
JetBrains Copilot { "permissionDecision": "deny", "reason": "..." }
Cursor { "permission": "deny", "user_message": "..." }
OpenCode throw new Error("...")
Codex CLI { "hookSpecificOutput": { "permissionDecision": "deny" } } or exit code 2
Kimi Code { "hookSpecificOutput": { "permissionDecision": "deny" } } or exit code 2

Modifying Tool Input

Platform Response Format
Claude Code { "updatedInput": { ... } }
Gemini CLI { "hookSpecificOutput": { "tool_input": { ... } } }
VS Code Copilot { "hookSpecificOutput": { "hookEventName": "PreToolUse", "updatedInput": { ... } } }
JetBrains Copilot { "hookSpecificOutput": { "hookEventName": "PreToolUse", "updatedInput": { ... } } }
Cursor { "updated_input": { ... } }
OpenCode { "args": { ... } } (mutation)
Codex CLI N/A (updatedInput in schema but not implemented)
Kimi Code { "hookSpecificOutput": { "hookEventName": "PreToolUse", "permissionDecision": "allow", "updatedInput": { ... } } }

Injecting Additional Context (PostToolUse)

Platform Response Format
Claude Code { "additionalContext": "..." }
Gemini CLI { "hookSpecificOutput": { "additionalContext": "..." } }
VS Code Copilot { "hookSpecificOutput": { "hookEventName": "PostToolUse", "additionalContext": "..." } }
JetBrains Copilot { "hookSpecificOutput": { "hookEventName": "PostToolUse", "additionalContext": "..." } }
Cursor { "additional_context": "..." }
OpenCode { "additionalContext": "..." }
Codex CLI { "hookSpecificOutput": { "additionalContext": "..." } }
Kimi Code { "hookSpecificOutput": { "hookEventName": "PostToolUse", "additionalContext": "..." } }

CLI Hook Dispatcher

All hook-based platforms use the CLI dispatcher pattern instead of direct node paths:

context-mode hook <platform> <event>

The dispatcher resolves the hook script relative to the installed package and dynamically imports it. Stdin/stdout flow through naturally since it runs in the same process.

Advantages over node ./node_modules/... paths:

  • Works from any directory (no per-project npm install needed)
  • Single global install serves all projects
  • context-mode upgrade updates hooks in-place
  • Short, portable command strings in settings files

Supported dispatches:

Platform Events
claude-code pretooluse, posttooluse, precompact, sessionstart, userpromptsubmit
gemini-cli beforetool, aftertool, precompress, sessionstart
vscode-copilot pretooluse, posttooluse, precompact, sessionstart
jetbrains-copilot pretooluse, posttooluse, precompact, sessionstart
cursor pretooluse, posttooluse, stop
codex pretooluse, posttooluse, precompact, sessionstart, userpromptsubmit, stop
kimi pretooluse, posttooluse, precompact, sessionstart, userpromptsubmit, stop
qwen-code pretooluse, posttooluse, precompact, sessionstart, userpromptsubmit
copilot-cli pretooluse, posttooluse, precompact, sessionstart, userpromptsubmit, stop
antigravity-cli pretooluse, posttooluse, stop
kiro pretooluse, posttooluse

OpenCode, KiloCode, and OpenClaw use a TS plugin paradigm (no command dispatcher). Pi and OMP register hooks through their own host APIs rather than the CLI dispatcher; Antigravity IDE and Zed are MCP-only (no hooks).


SQLite Backend Selection

context-mode automatically selects the best SQLite backend at runtime based on the environment:

Priority Condition Backend Why
1 Bun runtime bun:sqlite Built-in, no native addon
2 Linux + Node.js >= 22.5 node:sqlite Built-in, avoids SIGSEGV from V8 madvise bug
3 All other environments better-sqlite3 Mature native addon, prebuilt binaries

Why node:sqlite on Linux? Node.js's V8 garbage collector can call madvise(MADV_DONTNEED) on memory ranges that overlap better-sqlite3's native addon .got.plt section, corrupting resolved symbol addresses and causing sporadic SIGSEGV crashes (1-4/hour on Node v22-v24). node:sqlite is compiled into the Node.js binary itself — no separate .node file, no dlopen(), no .got.plt to corrupt.

Fallback: If node:sqlite is unavailable (Node < 22.5), context-mode silently falls back to better-sqlite3. No user configuration needed.

Override: Not currently supported — backend selection is automatic. If you need to force a specific backend, open an issue.


Utility Commands

All platforms support utility commands via MCP meta-tools:

Command What it does
ctx stats Show context savings, call counts, and session statistics
ctx doctor Diagnose installation: runtimes, hooks, FTS5, versions
ctx upgrade Update from GitHub, rebuild, reconfigure hooks
ctx purge Permanently deletes all indexed content from the knowledge base

How they work: The MCP server exposes stats, doctor, upgrade, and purge tools. The <ctx_commands> section in routing instructions (CLAUDE.md, GEMINI.md, AGENTS.md, copilot-instructions.md) maps natural language triggers to MCP tool calls. The doctor and upgrade tools return shell commands that the LLM executes and formats as a checklist. The purge tool permanently deletes all indexed content from the knowledge base and is the sole reset mechanism.