context-mode 1.0.151 → 1.0.153

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (106) hide show
  1. package/.claude-plugin/marketplace.json +2 -2
  2. package/.claude-plugin/plugin.json +1 -1
  3. package/.codex-plugin/mcp.json +5 -1
  4. package/.codex-plugin/plugin.json +1 -1
  5. package/.openclaw-plugin/openclaw.plugin.json +16 -1
  6. package/.openclaw-plugin/package.json +1 -1
  7. package/README.md +89 -3
  8. package/build/adapters/claude-code/hooks.js +2 -2
  9. package/build/adapters/claude-code/index.js +14 -13
  10. package/build/adapters/client-map.js +3 -0
  11. package/build/adapters/detect.js +13 -1
  12. package/build/adapters/gemini-cli/hooks.d.ts +10 -0
  13. package/build/adapters/gemini-cli/hooks.js +12 -2
  14. package/build/adapters/gemini-cli/index.d.ts +21 -1
  15. package/build/adapters/gemini-cli/index.js +37 -1
  16. package/build/adapters/kimi/config.d.ts +8 -0
  17. package/build/adapters/kimi/config.js +8 -0
  18. package/build/adapters/kimi/hooks.d.ts +28 -0
  19. package/build/adapters/kimi/hooks.js +34 -0
  20. package/build/adapters/kimi/index.d.ts +66 -0
  21. package/build/adapters/kimi/index.js +537 -0
  22. package/build/adapters/kimi/paths.d.ts +1 -0
  23. package/build/adapters/kimi/paths.js +12 -0
  24. package/build/adapters/kiro/hooks.js +2 -2
  25. package/build/adapters/openclaw/plugin.d.ts +14 -13
  26. package/build/adapters/openclaw/plugin.js +140 -40
  27. package/build/adapters/opencode/plugin.js +4 -3
  28. package/build/adapters/opencode/zod3tov4.js +8 -8
  29. package/build/adapters/pi/extension.js +9 -24
  30. package/build/adapters/pi/mcp-bridge.js +37 -0
  31. package/build/adapters/qwen-code/index.js +7 -7
  32. package/build/adapters/types.d.ts +39 -2
  33. package/build/adapters/types.js +55 -2
  34. package/build/cli.js +433 -25
  35. package/build/executor.js +6 -3
  36. package/build/runtime.d.ts +81 -1
  37. package/build/runtime.js +195 -9
  38. package/build/search/ctx-search-schema.d.ts +90 -0
  39. package/build/search/ctx-search-schema.js +135 -0
  40. package/build/search/unified.d.ts +12 -0
  41. package/build/search/unified.js +17 -2
  42. package/build/server.d.ts +2 -1
  43. package/build/server.js +378 -97
  44. package/build/session/analytics.d.ts +36 -3
  45. package/build/session/analytics.js +88 -26
  46. package/build/session/db.d.ts +24 -0
  47. package/build/session/db.js +41 -0
  48. package/build/session/extract.js +30 -0
  49. package/build/session/snapshot.js +24 -0
  50. package/build/store.d.ts +12 -1
  51. package/build/store.js +72 -20
  52. package/build/types.d.ts +7 -0
  53. package/build/util/project-dir.d.ts +19 -16
  54. package/build/util/project-dir.js +80 -45
  55. package/cli.bundle.mjs +370 -319
  56. package/configs/kimi/hooks.json +54 -0
  57. package/configs/pi/AGENTS.md +3 -85
  58. package/hooks/cache-heal-utils.mjs +148 -0
  59. package/hooks/core/formatters.mjs +26 -0
  60. package/hooks/core/routing.mjs +9 -1
  61. package/hooks/core/stdin.mjs +74 -3
  62. package/hooks/core/tool-naming.mjs +1 -0
  63. package/hooks/heal-partial-install.mjs +712 -0
  64. package/hooks/kimi/platform.mjs +1 -0
  65. package/hooks/kimi/posttooluse.mjs +72 -0
  66. package/hooks/kimi/precompact.mjs +80 -0
  67. package/hooks/kimi/pretooluse.mjs +42 -0
  68. package/hooks/kimi/sessionend.mjs +61 -0
  69. package/hooks/kimi/sessionstart.mjs +113 -0
  70. package/hooks/kimi/stop.mjs +61 -0
  71. package/hooks/kimi/userpromptsubmit.mjs +90 -0
  72. package/hooks/normalize-hooks.mjs +66 -12
  73. package/hooks/routing-block.mjs +8 -2
  74. package/hooks/security.bundle.mjs +1 -1
  75. package/hooks/session-db.bundle.mjs +6 -4
  76. package/hooks/session-extract.bundle.mjs +2 -2
  77. package/hooks/session-helpers.mjs +93 -3
  78. package/hooks/session-snapshot.bundle.mjs +20 -19
  79. package/hooks/sessionstart.mjs +64 -0
  80. package/insight/server.mjs +15 -3
  81. package/openclaw.plugin.json +16 -1
  82. package/package.json +1 -1
  83. package/scripts/heal-installed-plugins.mjs +31 -10
  84. package/scripts/postinstall.mjs +10 -0
  85. package/server.bundle.mjs +206 -157
  86. package/skills/ctx-index/SKILL.md +46 -0
  87. package/skills/ctx-search/SKILL.md +35 -0
  88. package/start.mjs +84 -11
  89. package/build/cache-heal.d.ts +0 -48
  90. package/build/cache-heal.js +0 -150
  91. package/build/concurrency/runPool.d.ts +0 -36
  92. package/build/concurrency/runPool.js +0 -51
  93. package/build/openclaw/mcp-tools.d.ts +0 -54
  94. package/build/openclaw/mcp-tools.js +0 -198
  95. package/build/openclaw/workspace-router.d.ts +0 -29
  96. package/build/openclaw/workspace-router.js +0 -64
  97. package/build/openclaw-plugin.d.ts +0 -130
  98. package/build/openclaw-plugin.js +0 -626
  99. package/build/opencode-plugin.d.ts +0 -122
  100. package/build/opencode-plugin.js +0 -375
  101. package/build/pi-extension.d.ts +0 -14
  102. package/build/pi-extension.js +0 -451
  103. package/build/routing-block.d.ts +0 -8
  104. package/build/routing-block.js +0 -86
  105. package/build/tool-naming.d.ts +0 -4
  106. package/build/tool-naming.js +0 -24
@@ -6,14 +6,14 @@
6
6
  },
7
7
  "metadata": {
8
8
  "description": "Claude Code plugins by Mert Koseoğlu",
9
- "version": "1.0.151"
9
+ "version": "1.0.153"
10
10
  },
11
11
  "plugins": [
12
12
  {
13
13
  "name": "context-mode",
14
14
  "source": "./",
15
15
  "description": "Claude Code MCP plugin that saves 98% of your context window. Sandboxed code execution in 11 languages, FTS5 knowledge base with BM25 ranking, and intent-driven search.",
16
- "version": "1.0.151",
16
+ "version": "1.0.153",
17
17
  "author": {
18
18
  "name": "Mert Koseoğlu"
19
19
  },
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "context-mode",
3
- "version": "1.0.151",
3
+ "version": "1.0.153",
4
4
  "description": "MCP server that saves 98% of your context window with session continuity. Sandboxed code execution in 11 languages, FTS5 knowledge base with BM25 ranking, and automatic state restore across compactions.",
5
5
  "author": {
6
6
  "name": "Mert Koseoğlu",
@@ -3,7 +3,11 @@
3
3
  "context-mode": {
4
4
  "command": "node",
5
5
  "args": ["./start.mjs"],
6
- "cwd": "."
6
+ "cwd": ".",
7
+ "env": {
8
+ "CONTEXT_MODE_PLATFORM": "codex"
9
+ },
10
+ "default_tools_approval_mode": "approve"
7
11
  }
8
12
  }
9
13
  }
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "context-mode",
3
- "version": "1.0.151",
3
+ "version": "1.0.153",
4
4
  "description": "MCP server that saves 98% of your context window with session continuity. Sandboxed code execution in 11 languages, FTS5 knowledge base with BM25 ranking, and automatic state restore across compactions.",
5
5
  "author": {
6
6
  "name": "Mert Koseoğlu",
@@ -3,12 +3,27 @@
3
3
  "name": "Context Mode",
4
4
  "kind": "tool",
5
5
  "description": "OpenClaw plugin that saves 98% of your context window. Sandboxed code execution in 11 languages, FTS5 knowledge base with BM25 ranking, and intent-driven search.",
6
- "version": "1.0.151",
6
+ "version": "1.0.153",
7
7
  "sandbox": {
8
8
  "mode": "permissive",
9
9
  "filesystem_access": "full",
10
10
  "system_access": "full"
11
11
  },
12
+ "contracts": {
13
+ "tools": [
14
+ "ctx_execute",
15
+ "ctx_execute_file",
16
+ "ctx_index",
17
+ "ctx_search",
18
+ "ctx_fetch_and_index",
19
+ "ctx_batch_execute",
20
+ "ctx_stats",
21
+ "ctx_doctor",
22
+ "ctx_upgrade",
23
+ "ctx_purge",
24
+ "ctx_insight"
25
+ ]
26
+ },
12
27
  "configSchema": {
13
28
  "type": "object",
14
29
  "properties": {
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "context-mode",
3
- "version": "1.0.151",
3
+ "version": "1.0.153",
4
4
  "description": "OpenClaw plugin that saves 98% of your context window. Sandboxed code execution in 11 languages, FTS5 knowledge base with BM25 ranking, and intent-driven search.",
5
5
  "author": {
6
6
  "name": "Mert Koseoğlu",
package/README.md CHANGED
@@ -39,7 +39,7 @@ Context Mode is an MCP server that solves all four sides of this problem:
39
39
 
40
40
  1. **Context Saving** — Sandbox tools keep raw data out of the context window. 315 KB becomes 5.4 KB. 98% reduction.
41
41
  2. **Session Continuity** — Every file edit, git operation, task, error, and user decision is tracked in SQLite. When the conversation compacts, context-mode doesn't dump this data back into context — it indexes events into FTS5 and retrieves only what's relevant via BM25 search. The model picks up exactly where you left off. If you don't `--continue`, previous session data is deleted immediately — a fresh session means a clean slate.
42
- 3. **Think in Code** — The LLM should program the analysis, not compute it. Instead of reading 50 files into context to count functions, the agent writes a script that does the counting and `console.log()`s only the result. One script replaces ten tool calls and saves 100x context. This is a mandatory paradigm across all 15 platforms: stop treating the LLM as a data processor, treat it as a code generator.
42
+ 3. **Think in Code** — The LLM should program the analysis, not compute it. Instead of reading 50 files into context to count functions, the agent writes a script that does the counting and `console.log()`s only the result. One script replaces ten tool calls and saves 100x context. This is a mandatory paradigm across all 16 platforms: stop treating the LLM as a data processor, treat it as a code generator.
43
43
 
44
44
  ```js
45
45
  // Before: 47 × Read() = 700 KB. After: 1 × ctx_execute() = 3.6 KB.
@@ -89,11 +89,13 @@ All checks should show `[x]`. The doctor validates runtimes, hooks, FTS5, and pl
89
89
  |---|---|
90
90
  | `/context-mode:ctx-stats` | Context savings — per-tool breakdown, tokens consumed, savings ratio. |
91
91
  | `/context-mode:ctx-doctor` | Diagnostics — runtimes, hooks, FTS5, plugin registration, versions. |
92
+ | `/context-mode:ctx-index` | Index a local file or directory into the persistent FTS5 knowledge base. |
93
+ | `/context-mode:ctx-search` | Search previously indexed content. |
92
94
  | `/context-mode:ctx-upgrade` | Pull latest, rebuild, migrate cache, fix hooks. |
93
95
  | `/context-mode:ctx-purge` | Permanently delete all indexed content from the knowledge base. |
94
96
  | `/context-mode:ctx-insight` | Personal analytics dashboard — 90 metrics, 37 insight patterns, 4 composite scores (productivity, quality, delegation, context health) across 23 event categories. Opens a local web UI. |
95
97
 
96
- > **Note:** Slash commands are a Claude Code plugin feature. On other platforms, type `ctx stats`, `ctx doctor`, `ctx upgrade`, or `ctx insight` in the chat — the model calls the MCP tool automatically. See [Utility Commands](#utility-commands).
98
+ > **Note:** Slash commands are a Claude Code plugin feature. On other platforms, type `ctx stats`, `ctx doctor`, `ctx index`, `ctx search`, `ctx upgrade`, or `ctx insight` in the chat — the model calls the MCP tool automatically. See [Utility Commands](#utility-commands).
97
99
 
98
100
  **Status line (optional):** Claude Code's plugin manifest cannot declare a status line, so this is a one-time manual edit to `~/.claude/settings.json`:
99
101
 
@@ -586,6 +588,9 @@ The Codex plugin manifest provides MCP via `.codex-plugin/mcp.json`, skills via
586
588
 
587
589
  [mcp_servers.context-mode]
588
590
  command = "context-mode"
591
+
592
+ [mcp_servers.context-mode.env]
593
+ CONTEXT_MODE_PLATFORM = "codex"
589
594
  ```
590
595
 
591
596
  3. Create `$CODEX_HOME/hooks.json` (or `~/.codex/hooks.json` when `CODEX_HOME` is unset):
@@ -626,6 +631,83 @@ The Codex plugin manifest provides MCP via `.codex-plugin/mcp.json`, skills via
626
631
 
627
632
  </details>
628
633
 
634
+ <details>
635
+ <summary><strong>Kimi Code</strong> — MCP + hooks (TOML config, same JSON wire protocol as Codex)</summary>
636
+
637
+ **Prerequisites:** Node.js >= 22.5 (or Bun), Kimi Code CLI installed.
638
+
639
+ 1. Install context-mode:
640
+
641
+ ```bash
642
+ npm install -g context-mode
643
+ ```
644
+
645
+ 2. Add context-mode as an MCP server. Add to `~/.kimi-code/mcp.json`:
646
+
647
+ ```json
648
+ {
649
+ "mcpServers": {
650
+ "context-mode": {
651
+ "command": "context-mode",
652
+ "args": []
653
+ }
654
+ }
655
+ }
656
+ ```
657
+
658
+ 3. Add hooks to `~/.kimi-code/config.toml`:
659
+
660
+ ```toml
661
+ [[hooks]]
662
+ event = "PreToolUse"
663
+ matcher = "Bash|Shell|Read|Edit|Write|WebFetch|Agent|ctx_execute|ctx_execute_file|ctx_batch_execute|ctx_fetch_and_index|ctx_search|ctx_index|mcp__"
664
+ command = "context-mode hook kimi pretooluse"
665
+ timeout = 30
666
+
667
+ [[hooks]]
668
+ event = "PostToolUse"
669
+ command = "context-mode hook kimi posttooluse"
670
+ timeout = 30
671
+
672
+ [[hooks]]
673
+ event = "SessionStart"
674
+ command = "context-mode hook kimi sessionstart"
675
+ timeout = 30
676
+
677
+ [[hooks]]
678
+ event = "PreCompact"
679
+ command = "context-mode hook kimi precompact"
680
+ timeout = 30
681
+
682
+ [[hooks]]
683
+ event = "UserPromptSubmit"
684
+ command = "context-mode hook kimi userpromptsubmit"
685
+ timeout = 30
686
+
687
+ [[hooks]]
688
+ event = "Stop"
689
+ command = "context-mode hook kimi stop"
690
+ timeout = 30
691
+ ```
692
+
693
+ 4. Restart Kimi Code CLI and verify MCP with `ctx stats`.
694
+
695
+ > **Note:** Kimi Code uses the same JSON stdin/stdout wire protocol as Codex, but accepts `additionalContext`, `updatedInput`, and `permissionDecision: "ask"` in PreToolUse responses (Codex rejects these). The kimi hook normalizes `ContentPart[]` prompt arrays to strings for downstream extractors.
696
+
697
+ 5. (Optional) Copy the routing instructions file for your project:
698
+
699
+ ```bash
700
+ cp "$(npm root -g)/context-mode/configs/codex/AGENTS.md" ./AGENTS.md
701
+ ```
702
+
703
+ Or for global use:
704
+
705
+ ```bash
706
+ CM_ROOT="$(npm root -g)/context-mode"; cp "$CM_ROOT/configs/codex/AGENTS.md" ~/.kimi-code/AGENTS.md
707
+ ```
708
+
709
+ </details>
710
+
629
711
  <details>
630
712
  <summary><strong>Qwen Code</strong> — MCP + hooks (identical wire protocol to Claude Code)</summary>
631
713
 
@@ -1249,6 +1331,8 @@ See [`docs/platform-support.md`](docs/platform-support.md) for the full capabili
1249
1331
  ```
1250
1332
  ctx stats → context savings, call counts, session report
1251
1333
  ctx doctor → diagnose runtimes, hooks, FTS5, versions
1334
+ ctx index → index a local file or directory for later search
1335
+ ctx search → search previously indexed content
1252
1336
  ctx upgrade → update from GitHub, rebuild, reconfigure hooks
1253
1337
  ctx purge → permanently delete all indexed content from the knowledge base
1254
1338
  ctx insight → personal analytics dashboard (opens local web UI)
@@ -1258,6 +1342,8 @@ ctx insight → personal analytics dashboard (opens local web UI)
1258
1342
 
1259
1343
  ```bash
1260
1344
  context-mode doctor
1345
+ context-mode index . --source project:my-app
1346
+ context-mode search "authentication middleware" --source project:my-app
1261
1347
  context-mode upgrade
1262
1348
  context-mode insight # opens analytics dashboard in browser
1263
1349
  bash scripts/ctx-debug.sh # full diagnostic report for bug reports
@@ -1265,7 +1351,7 @@ bash scripts/ctx-debug.sh # full diagnostic report for bug reports
1265
1351
 
1266
1352
  The debug script collects OS info, runtime versions, better-sqlite3 status, adapter detection, config files (redacted), hook validation, FTS5/SQLite test, executor test, process check, session databases, and environment variables into a single pasteable markdown report.
1267
1353
 
1268
- Works on **all platforms**. On Claude Code, slash commands (`/ctx-stats`, `/ctx-doctor`, `/ctx-upgrade`, `/ctx-purge`, `/ctx-insight`) are also available.
1354
+ Works on **all platforms**. On Claude Code, slash commands (`/ctx-stats`, `/ctx-doctor`, `/ctx-index`, `/ctx-search`, `/ctx-upgrade`, `/ctx-purge`, `/ctx-insight`) are also available.
1269
1355
 
1270
1356
  ## Benchmarks
1271
1357
 
@@ -1,4 +1,4 @@
1
- import { buildNodeCommand, parseNodeCommand } from "../types.js";
1
+ import { buildHookRuntimeCommand, parseNodeCommand } from "../types.js";
2
2
  /**
3
3
  * adapters/claude-code/hooks — Claude Code hook definitions and matchers.
4
4
  *
@@ -136,7 +136,7 @@ export function isContextModeHook(entry, hookType) {
136
136
  export function buildHookCommand(hookType, pluginRoot) {
137
137
  if (pluginRoot) {
138
138
  const scriptName = HOOK_SCRIPTS[hookType];
139
- return buildNodeCommand(`${pluginRoot}/hooks/${scriptName}`);
139
+ return buildHookRuntimeCommand(`${pluginRoot}/hooks/${scriptName}`);
140
140
  }
141
141
  return `context-mode hook claude-code ${hookType.toLowerCase()}`;
142
142
  }
@@ -18,7 +18,7 @@ import { ClaudeCodeBaseAdapter } from "../claude-code-base.js";
18
18
  import { resolveContextModeDataRoot } from "../base.js";
19
19
  import { resolveClaudeConfigDir } from "../../util/claude-config.js";
20
20
  import { checkPluginCacheIntegritySync } from "../../util/plugin-cache-integrity.js";
21
- import { buildNodeCommand, } from "../types.js";
21
+ import { buildHookRuntimeCommand, } from "../types.js";
22
22
  import { HOOK_TYPES, HOOK_SCRIPTS, REQUIRED_HOOKS, PRE_TOOL_USE_MATCHERS, PRE_TOOL_USE_MATCHER_PATTERN, isContextModeHook, isAnyContextModeHook, extractHookScriptPath, buildHookCommand, } from "./hooks.js";
23
23
  // ─────────────────────────────────────────────────────────
24
24
  // Adapter implementation
@@ -77,20 +77,21 @@ export class ClaudeCodeAdapter extends ClaudeCodeBaseAdapter {
77
77
  return join(this.getConfigDir(), "settings.json");
78
78
  }
79
79
  generateHookConfig(pluginRoot) {
80
- // Algo-D3: every command flows through `buildNodeCommand` (defined in
81
- // src/adapters/types.ts), which:
82
- // - quotes both nodePath and scriptPath (#548 — Windows pluginRoots
83
- // with spaces no longer fall through extractHookScriptPath's
84
- // ambiguous-tail fallback),
80
+ // Algo-D3: every command flows through `buildHookRuntimeCommand`
81
+ // (defined in src/adapters/types.ts), which:
82
+ // - quotes both runtime path and scriptPath (#548 — Windows
83
+ // pluginRoots with spaces no longer fall through
84
+ // extractHookScriptPath's ambiguous-tail fallback),
85
85
  // - swaps backslashes for forward slashes (#372 MSYS path mangling),
86
- // - uses `process.execPath` instead of bare `node` (#369 PATH
87
- // resolution on Git Bash).
86
+ // - resolves the JS runtime via `resolveHookRuntime`: Bun ≥1.0 when
87
+ // available, else `process.execPath` (#369 PATH resolution on Git
88
+ // Bash, #738 bun cold-start win).
88
89
  // Pre-D3 we hand-rolled `node "${pluginRoot}/hooks/X.mjs"` for all
89
90
  // five events; bare `node` made claude-code the lone outlier and
90
91
  // dropping the execPath swap re-opened the Windows class. Algo-D3.5
91
92
  // (CI invariant in tests/adapters/claude-code.test.ts) locks this in
92
93
  // for adapter #16.
93
- const preToolUseCommand = buildNodeCommand(`${pluginRoot}/hooks/pretooluse.mjs`);
94
+ const preToolUseCommand = buildHookRuntimeCommand(`${pluginRoot}/hooks/pretooluse.mjs`);
94
95
  const preToolUseMatchers = [...PRE_TOOL_USE_MATCHERS];
95
96
  return {
96
97
  PreToolUse: preToolUseMatchers.map((matcher) => ({
@@ -103,7 +104,7 @@ export class ClaudeCodeAdapter extends ClaudeCodeBaseAdapter {
103
104
  hooks: [
104
105
  {
105
106
  type: "command",
106
- command: buildNodeCommand(`${pluginRoot}/hooks/posttooluse.mjs`),
107
+ command: buildHookRuntimeCommand(`${pluginRoot}/hooks/posttooluse.mjs`),
107
108
  },
108
109
  ],
109
110
  },
@@ -114,7 +115,7 @@ export class ClaudeCodeAdapter extends ClaudeCodeBaseAdapter {
114
115
  hooks: [
115
116
  {
116
117
  type: "command",
117
- command: buildNodeCommand(`${pluginRoot}/hooks/precompact.mjs`),
118
+ command: buildHookRuntimeCommand(`${pluginRoot}/hooks/precompact.mjs`),
118
119
  },
119
120
  ],
120
121
  },
@@ -125,7 +126,7 @@ export class ClaudeCodeAdapter extends ClaudeCodeBaseAdapter {
125
126
  hooks: [
126
127
  {
127
128
  type: "command",
128
- command: buildNodeCommand(`${pluginRoot}/hooks/userpromptsubmit.mjs`),
129
+ command: buildHookRuntimeCommand(`${pluginRoot}/hooks/userpromptsubmit.mjs`),
129
130
  },
130
131
  ],
131
132
  },
@@ -136,7 +137,7 @@ export class ClaudeCodeAdapter extends ClaudeCodeBaseAdapter {
136
137
  hooks: [
137
138
  {
138
139
  type: "command",
139
- command: buildNodeCommand(`${pluginRoot}/hooks/sessionstart.mjs`),
140
+ command: buildHookRuntimeCommand(`${pluginRoot}/hooks/sessionstart.mjs`),
140
141
  },
141
142
  ],
142
143
  },
@@ -31,4 +31,7 @@ export const CLIENT_NAME_TO_PLATFORM = {
31
31
  "zed": "zed",
32
32
  "qwen-code": "qwen-code",
33
33
  "qwen-cli-mcp-client": "qwen-code",
34
+ "kimi-code": "kimi",
35
+ "kimi": "kimi",
36
+ "Kimi Code": "kimi",
34
37
  };
@@ -281,6 +281,7 @@ export function getSessionDirSegments(platform) {
281
281
  case "pi": return [".pi"];
282
282
  case "omp": return [".omp"];
283
283
  case "qwen-code": return [".qwen"];
284
+ case "kimi": return [".kimi-code"];
284
285
  case "kilo": return [".config", "kilo"];
285
286
  case "opencode": return [".config", "opencode"];
286
287
  case "zed": return [".config", "zed"];
@@ -319,7 +320,7 @@ export function detectPlatform(clientInfo) {
319
320
  if (platformOverride) {
320
321
  const validPlatforms = [
321
322
  "claude-code", "gemini-cli", "kilo", "opencode", "codex",
322
- "vscode-copilot", "jetbrains-copilot", "cursor", "antigravity", "kiro", "pi", "omp", "zed", "qwen-code",
323
+ "vscode-copilot", "jetbrains-copilot", "cursor", "antigravity", "kiro", "pi", "omp", "zed", "qwen-code", "kimi",
323
324
  ];
324
325
  if (validPlatforms.includes(platformOverride)) {
325
326
  return {
@@ -416,6 +417,13 @@ export function detectPlatform(clientInfo) {
416
417
  reason: "~/.qwen/ directory exists",
417
418
  };
418
419
  }
420
+ if (existsSync(resolve(home, ".kimi-code"))) {
421
+ return {
422
+ platform: "kimi",
423
+ confidence: "medium",
424
+ reason: "~/.kimi-code/ directory exists",
425
+ };
426
+ }
419
427
  if (existsSync(resolve(home, ".openclaw"))) {
420
428
  return {
421
429
  platform: "openclaw",
@@ -533,6 +541,10 @@ export async function getAdapter(platform) {
533
541
  const { PiAdapter } = await import("./pi/index.js");
534
542
  return new PiAdapter();
535
543
  }
544
+ case "kimi": {
545
+ const { KimiAdapter } = await import("./kimi/index.js");
546
+ return new KimiAdapter();
547
+ }
536
548
  default: {
537
549
  // Unsupported platform — fall back to Claude Code adapter
538
550
  // (MCP server works everywhere, hooks may not)
@@ -63,5 +63,15 @@ export declare function isContextModeHook(entry: {
63
63
  * Build the hook command string for a given hook type.
64
64
  * Uses absolute node path to avoid PATH issues (homebrew, nvm, volta, etc.).
65
65
  * Falls back to CLI dispatcher if pluginRoot is not provided.
66
+ *
67
+ * Issue #712: gemini-cli hook scripts live under `hooks/gemini-cli/<script>`
68
+ * on disk (verified via the published `files` field in package.json and
69
+ * HOOK_MAP in src/cli.ts which uses the same subdir for the CLI
70
+ * dispatcher form). The introducing commit (f5c9d02) carried claude-code's
71
+ * flat `hooks/<script>` shape over without accounting for the platform
72
+ * subdir, causing `ctx doctor` to FAIL every hook on every install
73
+ * (paths pointed at `<pluginRoot>/hooks/<script>` which never exist for
74
+ * gemini-cli). `setHookPermissions` in index.ts already uses the correct
75
+ * subdir, so this restores three-callsite parity.
66
76
  */
67
77
  export declare function buildHookCommand(hookType: HookType, pluginRoot?: string): string;
@@ -1,4 +1,4 @@
1
- import { buildNodeCommand } from "../types.js";
1
+ import { buildHookRuntimeCommand } from "../types.js";
2
2
  /**
3
3
  * adapters/gemini-cli/hooks — Gemini CLI hook definitions and matchers.
4
4
  *
@@ -87,11 +87,21 @@ export function isContextModeHook(entry, hookType) {
87
87
  * Build the hook command string for a given hook type.
88
88
  * Uses absolute node path to avoid PATH issues (homebrew, nvm, volta, etc.).
89
89
  * Falls back to CLI dispatcher if pluginRoot is not provided.
90
+ *
91
+ * Issue #712: gemini-cli hook scripts live under `hooks/gemini-cli/<script>`
92
+ * on disk (verified via the published `files` field in package.json and
93
+ * HOOK_MAP in src/cli.ts which uses the same subdir for the CLI
94
+ * dispatcher form). The introducing commit (f5c9d02) carried claude-code's
95
+ * flat `hooks/<script>` shape over without accounting for the platform
96
+ * subdir, causing `ctx doctor` to FAIL every hook on every install
97
+ * (paths pointed at `<pluginRoot>/hooks/<script>` which never exist for
98
+ * gemini-cli). `setHookPermissions` in index.ts already uses the correct
99
+ * subdir, so this restores three-callsite parity.
90
100
  */
91
101
  export function buildHookCommand(hookType, pluginRoot) {
92
102
  const scriptName = HOOK_SCRIPTS[hookType];
93
103
  if (pluginRoot && scriptName) {
94
- return buildNodeCommand(`${pluginRoot}/hooks/${scriptName}`);
104
+ return buildHookRuntimeCommand(`${pluginRoot}/hooks/gemini-cli/${scriptName}`);
95
105
  }
96
106
  return `context-mode hook gemini-cli ${hookType.toLowerCase()}`;
97
107
  }
@@ -19,7 +19,7 @@
19
19
  * - Session dir: ~/.gemini/context-mode/sessions/
20
20
  */
21
21
  import { BaseAdapter } from "../base.js";
22
- import type { HookAdapter, HookParadigm, PlatformCapabilities, DiagnosticResult, PreToolUseEvent, PostToolUseEvent, PreCompactEvent, SessionStartEvent, PreToolUseResponse, PostToolUseResponse, PreCompactResponse, SessionStartResponse, HookRegistration } from "../types.js";
22
+ import type { HookAdapter, HookParadigm, PlatformCapabilities, DiagnosticResult, HealthCheck, PreToolUseEvent, PostToolUseEvent, PreCompactEvent, SessionStartEvent, PreToolUseResponse, PostToolUseResponse, PreCompactResponse, SessionStartResponse, HookRegistration } from "../types.js";
23
23
  export declare class GeminiCLIAdapter extends BaseAdapter implements HookAdapter {
24
24
  constructor();
25
25
  readonly name = "Gemini CLI";
@@ -39,6 +39,26 @@ export declare class GeminiCLIAdapter extends BaseAdapter implements HookAdapter
39
39
  readSettings(): Record<string, unknown> | null;
40
40
  writeSettings(settings: Record<string, unknown>): void;
41
41
  validateHooks(pluginRoot: string): DiagnosticResult[];
42
+ /**
43
+ * Adapter-defined health checks (Algo-D1) — mirrors claude-code's override
44
+ * at src/adapters/claude-code/index.ts:275.
45
+ *
46
+ * Issue #712 motivation: gemini-cli's hook scripts ship under
47
+ * `<pluginRoot>/hooks/gemini-cli/<scriptName>` (see HOOK_MAP in
48
+ * src/cli.ts and `setHookPermissions` in this file). The legacy doctor
49
+ * path (`getHookScriptPaths` -> `extractHookScriptPath`) round-trips
50
+ * through `buildHookCommand` -> command-string parsing, so a missing
51
+ * platform subdir in the emit was invisible to the doctor until a user
52
+ * installed globally and observed FAIL lines. This override drops the
53
+ * round-trip: HOOK_SCRIPTS is the single source of truth and we probe
54
+ * `existsSync(join(pluginRoot, "hooks", "gemini-cli", scriptName))`
55
+ * directly, so a future regression in the command emit cannot make the
56
+ * doctor lie about hook health.
57
+ *
58
+ * Adding a new hook event in HOOK_SCRIPTS auto-extends doctor coverage
59
+ * here — no parallel hardcoded list to maintain.
60
+ */
61
+ getHealthChecks(pluginRoot: string): readonly HealthCheck[];
42
62
  checkPluginRegistration(): DiagnosticResult;
43
63
  getInstalledVersion(): string;
44
64
  configureAllHooks(pluginRoot: string): string[];
@@ -18,7 +18,7 @@
18
18
  * - Project dir env: GEMINI_PROJECT_DIR (also CLAUDE_PROJECT_DIR alias)
19
19
  * - Session dir: ~/.gemini/context-mode/sessions/
20
20
  */
21
- import { readFileSync, writeFileSync, mkdirSync, accessSync, chmodSync, constants, } from "node:fs";
21
+ import { readFileSync, writeFileSync, mkdirSync, accessSync, chmodSync, existsSync, constants, } from "node:fs";
22
22
  import { resolve, join } from "node:path";
23
23
  import { homedir } from "node:os";
24
24
  import { BaseAdapter } from "../base.js";
@@ -296,6 +296,42 @@ export class GeminiCLIAdapter extends BaseAdapter {
296
296
  }
297
297
  return results;
298
298
  }
299
+ /**
300
+ * Adapter-defined health checks (Algo-D1) — mirrors claude-code's override
301
+ * at src/adapters/claude-code/index.ts:275.
302
+ *
303
+ * Issue #712 motivation: gemini-cli's hook scripts ship under
304
+ * `<pluginRoot>/hooks/gemini-cli/<scriptName>` (see HOOK_MAP in
305
+ * src/cli.ts and `setHookPermissions` in this file). The legacy doctor
306
+ * path (`getHookScriptPaths` -> `extractHookScriptPath`) round-trips
307
+ * through `buildHookCommand` -> command-string parsing, so a missing
308
+ * platform subdir in the emit was invisible to the doctor until a user
309
+ * installed globally and observed FAIL lines. This override drops the
310
+ * round-trip: HOOK_SCRIPTS is the single source of truth and we probe
311
+ * `existsSync(join(pluginRoot, "hooks", "gemini-cli", scriptName))`
312
+ * directly, so a future regression in the command emit cannot make the
313
+ * doctor lie about hook health.
314
+ *
315
+ * Adding a new hook event in HOOK_SCRIPTS auto-extends doctor coverage
316
+ * here — no parallel hardcoded list to maintain.
317
+ */
318
+ getHealthChecks(pluginRoot) {
319
+ return Object.entries(GEMINI_HOOK_SCRIPTS).map(([hookType, scriptName]) => {
320
+ const absolutePath = join(pluginRoot, "hooks", "gemini-cli", scriptName);
321
+ return {
322
+ name: `Hook script: ${hookType} (${scriptName})`,
323
+ check: () => {
324
+ if (existsSync(absolutePath)) {
325
+ return { status: "OK", detail: absolutePath };
326
+ }
327
+ return {
328
+ status: "FAIL",
329
+ detail: `not found at ${absolutePath}`,
330
+ };
331
+ },
332
+ };
333
+ });
334
+ }
299
335
  checkPluginRegistration() {
300
336
  const settings = this.readSettings();
301
337
  if (!settings) {
@@ -0,0 +1,8 @@
1
+ /**
2
+ * adapters/kimi/config — Thin re-exports from KimiAdapter.
3
+ *
4
+ * This module exists for backward compatibility. All logic lives in the
5
+ * adapter class (index.ts). New code should use getAdapter() from detect.ts.
6
+ */
7
+ export { KimiAdapter } from "./index.js";
8
+ export { HOOK_TYPES, ROUTING_INSTRUCTIONS_PATH } from "./hooks.js";
@@ -0,0 +1,8 @@
1
+ /**
2
+ * adapters/kimi/config — Thin re-exports from KimiAdapter.
3
+ *
4
+ * This module exists for backward compatibility. All logic lives in the
5
+ * adapter class (index.ts). New code should use getAdapter() from detect.ts.
6
+ */
7
+ export { KimiAdapter } from "./index.js";
8
+ export { HOOK_TYPES, ROUTING_INSTRUCTIONS_PATH } from "./hooks.js";
@@ -0,0 +1,28 @@
1
+ /**
2
+ * adapters/kimi/hooks — Kimi Code CLI hook definitions.
3
+ *
4
+ * Kimi Code CLI hooks run behind the `[[hooks]]` array-table surface in
5
+ * `~/.kimi-code/config.toml`. 7 hook events: PreToolUse, PostToolUse,
6
+ * PreCompact, SessionStart, SessionEnd, UserPromptSubmit, Stop.
7
+ * Same JSON stdin/stdout wire protocol as Codex CLI.
8
+ *
9
+ * Known limitations (verified against upstream source):
10
+ * - PreToolUse: deny works; updatedInput / additionalContext / ask are
11
+ * silently stripped by the host runner (refs/platforms/kimi-code/...
12
+ * /session/hooks/runner.ts:36-39,162-178 and types.ts:28-37).
13
+ * - PostToolUse: updatedMCPToolOutput is parsed but not acted upon.
14
+ */
15
+ /** Kimi Code CLI hook types — mirrors Codex CLI's events + SessionEnd. */
16
+ export declare const HOOK_TYPES: {
17
+ readonly PRE_TOOL_USE: "PreToolUse";
18
+ readonly POST_TOOL_USE: "PostToolUse";
19
+ readonly PRE_COMPACT: "PreCompact";
20
+ readonly SESSION_START: "SessionStart";
21
+ readonly SESSION_END: "SessionEnd";
22
+ readonly USER_PROMPT_SUBMIT: "UserPromptSubmit";
23
+ readonly STOP: "Stop";
24
+ };
25
+ /**
26
+ * Path to the routing instructions file for Kimi Code CLI.
27
+ */
28
+ export declare const ROUTING_INSTRUCTIONS_PATH = "configs/kimi/AGENTS.md";
@@ -0,0 +1,34 @@
1
+ /**
2
+ * adapters/kimi/hooks — Kimi Code CLI hook definitions.
3
+ *
4
+ * Kimi Code CLI hooks run behind the `[[hooks]]` array-table surface in
5
+ * `~/.kimi-code/config.toml`. 7 hook events: PreToolUse, PostToolUse,
6
+ * PreCompact, SessionStart, SessionEnd, UserPromptSubmit, Stop.
7
+ * Same JSON stdin/stdout wire protocol as Codex CLI.
8
+ *
9
+ * Known limitations (verified against upstream source):
10
+ * - PreToolUse: deny works; updatedInput / additionalContext / ask are
11
+ * silently stripped by the host runner (refs/platforms/kimi-code/...
12
+ * /session/hooks/runner.ts:36-39,162-178 and types.ts:28-37).
13
+ * - PostToolUse: updatedMCPToolOutput is parsed but not acted upon.
14
+ */
15
+ // ─────────────────────────────────────────────────────────
16
+ // Hook type constants
17
+ // ─────────────────────────────────────────────────────────
18
+ /** Kimi Code CLI hook types — mirrors Codex CLI's events + SessionEnd. */
19
+ export const HOOK_TYPES = {
20
+ PRE_TOOL_USE: "PreToolUse",
21
+ POST_TOOL_USE: "PostToolUse",
22
+ PRE_COMPACT: "PreCompact",
23
+ SESSION_START: "SessionStart",
24
+ SESSION_END: "SessionEnd",
25
+ USER_PROMPT_SUBMIT: "UserPromptSubmit",
26
+ STOP: "Stop",
27
+ };
28
+ // ─────────────────────────────────────────────────────────
29
+ // Routing instructions
30
+ // ─────────────────────────────────────────────────────────
31
+ /**
32
+ * Path to the routing instructions file for Kimi Code CLI.
33
+ */
34
+ export const ROUTING_INSTRUCTIONS_PATH = "configs/kimi/AGENTS.md";