context-mode 1.0.106 → 1.0.108
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.
- package/.claude-plugin/marketplace.json +2 -2
- package/.claude-plugin/plugin.json +1 -1
- package/.openclaw-plugin/openclaw.plugin.json +1 -1
- package/.openclaw-plugin/package.json +1 -1
- package/README.md +22 -18
- package/build/adapters/claude-code/index.js +26 -9
- package/build/adapters/copilot-base.d.ts +3 -3
- package/build/adapters/cursor/hooks.js +8 -0
- package/build/adapters/cursor/index.js +4 -1
- package/build/adapters/gemini-cli/hooks.d.ts +6 -1
- package/build/adapters/gemini-cli/hooks.js +7 -1
- package/build/adapters/gemini-cli/index.js +12 -0
- package/build/adapters/kiro/hooks.js +4 -0
- package/build/adapters/kiro/index.d.ts +9 -2
- package/build/adapters/kiro/index.js +49 -27
- package/build/adapters/opencode/index.js +11 -5
- package/build/adapters/qwen-code/index.js +18 -0
- package/build/adapters/vscode-copilot/hooks.d.ts +0 -4
- package/build/adapters/vscode-copilot/hooks.js +6 -6
- package/build/cli.js +93 -12
- package/build/openclaw/mcp-tools.d.ts +54 -0
- package/build/openclaw/mcp-tools.js +198 -0
- package/build/openclaw-plugin.d.ts +9 -0
- package/build/openclaw-plugin.js +132 -16
- package/build/opencode-plugin.d.ts +29 -4
- package/build/opencode-plugin.js +154 -7
- package/build/pi-extension.js +123 -29
- package/build/server.d.ts +1 -0
- package/build/server.js +26 -1
- package/build/session/analytics.js +36 -13
- package/build/session/extract.d.ts +1 -1
- package/build/session/extract.js +46 -1
- package/cli.bundle.mjs +133 -132
- package/hooks/core/platform-detect.mjs +49 -0
- package/hooks/core/routing.mjs +13 -1
- package/hooks/cursor/afteragentresponse.mjs +74 -0
- package/hooks/ensure-deps.mjs +28 -12
- package/hooks/gemini-cli/beforeagent.mjs +99 -0
- package/hooks/kiro/agentspawn.mjs +97 -0
- package/hooks/kiro/userpromptsubmit.mjs +88 -0
- package/hooks/posttooluse.mjs +90 -80
- package/hooks/precompact.mjs +56 -46
- package/hooks/pretooluse.mjs +161 -167
- package/hooks/routing-block.mjs +2 -2
- package/hooks/run-hook.mjs +82 -0
- package/hooks/session-extract.bundle.mjs +2 -2
- package/hooks/sessionstart.mjs +187 -153
- package/hooks/userpromptsubmit.mjs +69 -58
- package/hooks/vscode-copilot/sessionstart.mjs +13 -14
- package/openclaw.plugin.json +1 -1
- package/package.json +2 -1
- package/scripts/heal-better-sqlite3.mjs +108 -0
- package/scripts/postinstall.mjs +27 -0
- package/server.bundle.mjs +79 -79
- package/skills/UPSTREAM-CREDITS.md +51 -0
- package/skills/context-mode-ops/SKILL.md +147 -0
- package/skills/diagnose/SKILL.md +122 -0
- package/skills/diagnose/scripts/hitl-loop.template.sh +41 -0
- package/skills/grill-me/SKILL.md +15 -0
- package/skills/grill-with-docs/ADR-FORMAT.md +47 -0
- package/skills/grill-with-docs/CONTEXT-FORMAT.md +77 -0
- package/skills/grill-with-docs/SKILL.md +93 -0
- package/skills/improve-codebase-architecture/DEEPENING.md +37 -0
- package/skills/improve-codebase-architecture/INTERFACE-DESIGN.md +44 -0
- package/skills/improve-codebase-architecture/LANGUAGE.md +53 -0
- package/skills/improve-codebase-architecture/SKILL.md +76 -0
- package/skills/tdd/SKILL.md +114 -0
- package/skills/tdd/deep-modules.md +33 -0
- package/skills/tdd/interface-design.md +31 -0
- package/skills/tdd/mocking.md +59 -0
- package/skills/tdd/refactoring.md +10 -0
- package/skills/tdd/tests.md +61 -0
|
@@ -6,14 +6,14 @@
|
|
|
6
6
|
},
|
|
7
7
|
"metadata": {
|
|
8
8
|
"description": "Claude Code plugins by Mert Koseoğlu",
|
|
9
|
-
"version": "1.0.
|
|
9
|
+
"version": "1.0.108"
|
|
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.
|
|
16
|
+
"version": "1.0.108",
|
|
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.
|
|
3
|
+
"version": "1.0.108",
|
|
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,7 @@
|
|
|
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.
|
|
6
|
+
"version": "1.0.108",
|
|
7
7
|
"sandbox": {
|
|
8
8
|
"mode": "permissive",
|
|
9
9
|
"filesystem_access": "full",
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "context-mode",
|
|
3
|
-
"version": "1.0.
|
|
3
|
+
"version": "1.0.108",
|
|
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
|
@@ -404,7 +404,7 @@ Full configs: [`configs/cursor/hooks.json`](configs/cursor/hooks.json) | [`confi
|
|
|
404
404
|
|
|
405
405
|
The `mcp` entry registers all 11 MCP tools. The `plugin` entry enables hooks — OpenCode calls the plugin's TypeScript functions directly before and after each tool execution, blocking dangerous commands and enforcing sandbox routing.
|
|
406
406
|
|
|
407
|
-
3. *(Optional)* Copy the routing rules file.
|
|
407
|
+
3. *(Optional)* Copy the routing rules file. The model needs an `AGENTS.md` file for routing awareness:
|
|
408
408
|
|
|
409
409
|
```bash
|
|
410
410
|
cp node_modules/context-mode/configs/opencode/AGENTS.md AGENTS.md
|
|
@@ -416,9 +416,9 @@ Full configs: [`configs/cursor/hooks.json`](configs/cursor/hooks.json) | [`confi
|
|
|
416
416
|
|
|
417
417
|
**Verify:** In the OpenCode session, type `ctx stats`. Context-mode tools should appear and respond.
|
|
418
418
|
|
|
419
|
-
**Routing:** Hooks enforce routing programmatically via `tool.execute.before` and `tool.execute.after`. The optional [`AGENTS.md`](configs/opencode/AGENTS.md) file provides routing instructions for model awareness. The `experimental.session.compacting` hook builds resume snapshots when the conversation compacts.
|
|
419
|
+
**Routing:** Hooks enforce routing programmatically via `tool.execute.before` and `tool.execute.after`. The optional [`AGENTS.md`](configs/opencode/AGENTS.md) file provides routing instructions for model awareness. The `experimental.session.compacting` hook builds resume snapshots when the conversation compacts. The `experimental.chat.system.transform` hook injects the routing block and prior-session snapshots at session start, enabling session continuity across restarts. The `chat.message` hook captures user prompts and decisions (UserPromptSubmit equivalent).
|
|
420
420
|
|
|
421
|
-
> **Note:** OpenCode
|
|
421
|
+
> **Note:** OpenCode lacks a real SessionStart hook ([#14808](https://github.com/sst/opencode/issues/14808), [#5409](https://github.com/sst/opencode/issues/5409)). The plugin uses `experimental.chat.system.transform` as a surrogate — it injects both the routing block and resume snapshots into the system prompt. User-prompt capture uses `chat.message` instead of the missing UserPromptSubmit hook. AGENTS.md/CLAUDE.md/CONTEXT.md rules are captured automatically on first hook fire per project.
|
|
422
422
|
|
|
423
423
|
Full configs: [`configs/opencode/opencode.json`](configs/opencode/opencode.json) | [`configs/opencode/AGENTS.md`](configs/opencode/AGENTS.md)
|
|
424
424
|
|
|
@@ -454,7 +454,7 @@ Full configs: [`configs/opencode/opencode.json`](configs/opencode/opencode.json)
|
|
|
454
454
|
|
|
455
455
|
The `mcp` entry registers all 11 MCP tools. The `plugin` entry enables hooks — KiloCode calls the plugin's TypeScript functions directly before and after each tool execution, blocking dangerous commands and enforcing sandbox routing.
|
|
456
456
|
|
|
457
|
-
3. *(Optional)* Copy the routing rules file. KiloCode shares the OpenCode plugin architecture
|
|
457
|
+
3. *(Optional)* Copy the routing rules file. KiloCode shares the OpenCode plugin architecture, so the model needs an `AGENTS.md` file for routing awareness:
|
|
458
458
|
|
|
459
459
|
```bash
|
|
460
460
|
cp node_modules/context-mode/configs/opencode/AGENTS.md AGENTS.md
|
|
@@ -464,9 +464,9 @@ Full configs: [`configs/opencode/opencode.json`](configs/opencode/opencode.json)
|
|
|
464
464
|
|
|
465
465
|
**Verify:** In the KiloCode session, type `ctx stats`. Context-mode tools should appear and respond.
|
|
466
466
|
|
|
467
|
-
**Routing:** Hooks enforce routing programmatically via `tool.execute.before` and `tool.execute.after`. The optional [`AGENTS.md`](configs/opencode/AGENTS.md) file provides routing instructions for model awareness. The `experimental.session.compacting` hook builds resume snapshots when the conversation compacts.
|
|
467
|
+
**Routing:** Hooks enforce routing programmatically via `tool.execute.before` and `tool.execute.after`. The optional [`AGENTS.md`](configs/opencode/AGENTS.md) file provides routing instructions for model awareness. The `experimental.session.compacting` hook builds resume snapshots when the conversation compacts. The `experimental.chat.system.transform` hook injects the routing block and prior-session snapshots at session start, enabling session continuity across restarts. The `chat.message` hook captures user prompts and decisions (UserPromptSubmit equivalent).
|
|
468
468
|
|
|
469
|
-
> **Note:** KiloCode shares the same plugin architecture as OpenCode, using the OpenCodeAdapter with platform-specific configuration paths (`kilo.json` instead of `opencode.json`, `~/.config/kilo/` instead of `~/.config/opencode/`). SessionStart hook
|
|
469
|
+
> **Note:** KiloCode shares the same plugin architecture as OpenCode, using the OpenCodeAdapter with platform-specific configuration paths (`kilo.json` instead of `opencode.json`, `~/.config/kilo/` instead of `~/.config/opencode/`). Like OpenCode, it lacks a real SessionStart hook — the plugin uses `experimental.chat.system.transform` as a surrogate. User-prompt capture uses `chat.message` instead of the missing UserPromptSubmit hook. AGENTS.md/CLAUDE.md/CONTEXT.md rules are captured automatically on first hook fire per project.
|
|
470
470
|
|
|
471
471
|
</details>
|
|
472
472
|
|
|
@@ -817,6 +817,8 @@ Context Mode uses [better-sqlite3](https://github.com/WiseLibs/better-sqlite3) o
|
|
|
817
817
|
|
|
818
818
|
On older glibc systems (CentOS 7/8, RHEL 8, Debian 10), prebuilt binaries don't load and better-sqlite3 **automatically falls back to compiling from source** via `prebuild-install || node-gyp rebuild --release`. This requires a C++20 compiler (GCC 10+), Make, and Python with setuptools.
|
|
819
819
|
|
|
820
|
+
**Windows / missing binding self-heal:** if `better_sqlite3.node` ends up missing after install (e.g. `prebuild-install` not on cmd.exe PATH, no MSVC toolchain), the postinstall script and the runtime hook automatically re-fetch the prebuild and repair the binding — no manual `npm rebuild` needed (#408).
|
|
821
|
+
|
|
820
822
|
**CentOS 8 / RHEL 8** (glibc 2.28):
|
|
821
823
|
|
|
822
824
|
```bash
|
|
@@ -919,20 +921,22 @@ This means `--continue` sessions preserve indexed docs across restarts. No re-fe
|
|
|
919
921
|
|
|
920
922
|
When the context window fills up, the agent compacts the conversation — dropping older messages to make room. Without session tracking, the model forgets which files it was editing, what tasks are in progress, what errors were resolved, and what you last asked for.
|
|
921
923
|
|
|
922
|
-
Context Mode captures every meaningful event during your session and persists them in a per-project SQLite database. When the conversation compacts (or you resume with `--continue`), your working state is rebuilt automatically — the model continues from your last prompt without asking you to repeat anything.
|
|
924
|
+
Context Mode captures every meaningful event during your session and persists them in a per-project SQLite database. When the conversation compacts (or you resume with `--continue`, `--resume`, or `/resume`), your working state is rebuilt automatically — the model continues from your last prompt without asking you to repeat anything.
|
|
925
|
+
|
|
926
|
+
> Resuming a non-latest session via `/resume <picker>` works the same way: the SessionStart hook detects the empty live-event table for the freshly issued session id and falls back to the most recent unconsumed snapshot for the project (`session_resume` table). The picker selects the conversation; context-mode rehydrates the prior working state.
|
|
923
927
|
|
|
924
|
-
Session continuity requires
|
|
928
|
+
Session continuity requires 5 hooks working together:
|
|
925
929
|
|
|
926
930
|
| Hook | Role | Claude Code | Gemini CLI | VS Code Copilot | JetBrains Copilot | Cursor | OpenCode | KiloCode | OpenClaw | Codex CLI | Antigravity | Kiro | Zed | Pi |
|
|
927
931
|
|---|---|:---:|:---:|:---:|:---:|:---:|:---:|:---:|:---:|:---:|:---:|:---:|:---:|:---:|
|
|
928
932
|
| **PreToolUse** | Enforces sandbox routing before tool execution | Yes | -- | -- | -- | Yes | -- | -- | -- | Yes | -- | Yes | -- | ✓ (via tool_call event) |
|
|
929
933
|
| **PostToolUse** | Captures events after each tool call | Yes | Yes | Yes | Yes | Yes | Plugin | Plugin | Plugin | Yes | -- | Yes | -- | ✓ (via tool_result event) |
|
|
930
|
-
| **UserPromptSubmit** | Captures user decisions and corrections | Yes | -- | -- | -- | -- |
|
|
934
|
+
| **UserPromptSubmit** | Captures user decisions and corrections | Yes | -- | -- | -- | -- | Plugin (via chat.message) | Plugin (via chat.message) | -- | Yes | -- | -- | -- | -- |
|
|
931
935
|
| **PreCompact** | Builds snapshot before compaction | Yes | Yes | Yes | Yes | -- | Plugin | Plugin | Plugin | -- | -- | -- | -- | ✓ (via session_before_compact) |
|
|
932
|
-
| **SessionStart** | Restores state after compaction or resume | Yes | Yes | Yes | Yes | -- |
|
|
933
|
-
| | **Session completeness** | **Full** | **High** | **High** | **High** | **Partial** | **
|
|
936
|
+
| **SessionStart** | Restores state after compaction or resume | Yes | Yes | Yes | Yes | -- | ✓ (via experimental.chat.system.transform) | ✓ (via experimental.chat.system.transform) | Plugin | Yes | -- | -- | -- | ✓ (via session_start event) |
|
|
937
|
+
| | **Session completeness** | **Full** | **High** | **High** | **High** | **Partial** | **Full** | **Full** | **High** | **Partial** | **--** | **Partial** | **--** | **High** |
|
|
934
938
|
|
|
935
|
-
> **Note:** Full session continuity (capture + snapshot + restore) works on **Claude Code**, **Gemini CLI**, **VS Code Copilot**,
|
|
939
|
+
> **Note:** Full session continuity (capture + snapshot + restore) works on **Claude Code**, **Gemini CLI**, **VS Code Copilot**, **JetBrains Copilot**, **OpenCode**, and **KiloCode**. **OpenCode** and **KiloCode** use `experimental.chat.system.transform` as a SessionStart surrogate to inject the routing block and restore prior sessions, plus `chat.message` for user-prompt capture; full SessionStart hook support is not yet available ([#14808](https://github.com/sst/opencode/issues/14808), [#5409](https://github.com/sst/opencode/issues/5409)), but prior-session continuity and user-decision capture work fully. **Cursor** captures tool events via `preToolUse`/`postToolUse`, but `sessionStart` is currently rejected by Cursor's validator ([forum report](https://forum.cursor.com/t/unknown-hook-type-sessionstart/149566)), so session restore after compaction is not available yet. **OpenClaw** uses native gateway plugin hooks (`api.on()`) for full session continuity. **Pi Coding Agent** provides high session continuity via extension hooks (`tool_call`, `tool_result`, `session_start`, `session_before_compact`). **Codex CLI** provides partial hook-based session tracking through PreToolUse, PostToolUse, SessionStart, UserPromptSubmit, and Stop; MCP tools work. **Antigravity**, **Kiro**, and **Zed** have no hook support in the current release, so session tracking is not available.
|
|
936
940
|
|
|
937
941
|
<details>
|
|
938
942
|
<summary><strong>What gets captured</strong></summary>
|
|
@@ -1015,7 +1019,7 @@ Detailed event data is also indexed into FTS5 for on-demand retrieval via `ctx_s
|
|
|
1015
1019
|
<details>
|
|
1016
1020
|
<summary><strong>Per-platform details</strong></summary>
|
|
1017
1021
|
|
|
1018
|
-
**Claude Code** — Full session support. All 5 hook types fire, capturing tool events, user decisions, building compaction snapshots, and restoring state after compaction or
|
|
1022
|
+
**Claude Code** — Full session support. All 5 hook types fire, capturing tool events, user decisions, building compaction snapshots, and restoring state after compaction, `--continue`, `--resume`, or `/resume`.
|
|
1019
1023
|
|
|
1020
1024
|
**Gemini CLI** — High coverage. PostToolUse (AfterTool), PreCompact (PreCompress), and SessionStart all fire. Missing UserPromptSubmit, so user decisions and corrections aren't captured — but file edits, git ops, errors, and tasks are fully tracked.
|
|
1021
1025
|
|
|
@@ -1025,9 +1029,9 @@ Detailed event data is also indexed into FTS5 for on-demand retrieval via `ctx_s
|
|
|
1025
1029
|
|
|
1026
1030
|
**Cursor** — Partial coverage. Native `preToolUse` and `postToolUse` hooks capture tool events. `sessionStart` is documented by Cursor but currently rejected by their validator, so session restore is not available. Routing instructions are delivered via MCP server startup instead.
|
|
1027
1031
|
|
|
1028
|
-
**OpenCode** —
|
|
1032
|
+
**OpenCode** — Full session support. The TypeScript plugin captures PostToolUse events via `tool.execute.after`, user prompts and decisions via `chat.message`, builds compaction snapshots via `experimental.session.compacting`, and restores prior sessions via `experimental.chat.system.transform` (SessionStart surrogate). Routing block is injected on first `chat.system.transform` per session. AGENTS.md/CLAUDE.md/CONTEXT.md rules are captured automatically on first hook fire.
|
|
1029
1033
|
|
|
1030
|
-
**KiloCode** —
|
|
1034
|
+
**KiloCode** — Full session support. Shares the same plugin architecture as OpenCode via the OpenCodeAdapter. The TypeScript plugin captures PostToolUse events via `tool.execute.after`, user prompts and decisions via `chat.message`, builds compaction snapshots via `experimental.session.compacting`, and restores prior sessions via `experimental.chat.system.transform` (SessionStart surrogate).
|
|
1031
1035
|
|
|
1032
1036
|
**OpenClaw / Pi Agent** — High coverage. All tool lifecycle hooks (`after_tool_call`, `before_compaction`, `session_start`) fire via the native gateway plugin. User decisions aren't captured but file edits, git ops, errors, and tasks are fully tracked. Falls back to DB snapshot reconstruction if compaction hooks fail on older gateway versions. See [`docs/adapters/openclaw.md`](docs/adapters/openclaw.md).
|
|
1033
1037
|
|
|
@@ -1050,7 +1054,7 @@ Detailed event data is also indexed into FTS5 for on-demand retrieval via `ctx_s
|
|
|
1050
1054
|
| MCP Server | Yes | Yes | Yes | Yes | Yes | Yes | Yes | Yes | Yes | Yes | Yes | Yes | Yes | Yes |
|
|
1051
1055
|
| PreToolUse Hook | Yes | Yes | Yes | Yes | Yes | Yes | Plugin | Plugin | Plugin | Yes | -- | Yes | -- | Yes (extension) |
|
|
1052
1056
|
| PostToolUse Hook | Yes | Yes | Yes | Yes | Yes | Yes | Plugin | Plugin | Plugin | Yes | -- | Yes | -- | Yes (extension) |
|
|
1053
|
-
| SessionStart Hook | Yes | Yes | Yes | Yes | Yes | -- |
|
|
1057
|
+
| SessionStart Hook | Yes | Yes | Yes | Yes | Yes | -- | ✓ (via experimental.chat.system.transform) | ✓ (via experimental.chat.system.transform) | Plugin | Yes | -- | -- | -- | Yes (extension) |
|
|
1054
1058
|
| PreCompact Hook | Yes | Yes | Yes | Yes | Yes | -- | Plugin | Plugin | Plugin | -- | -- | -- | -- | Yes (extension) |
|
|
1055
1059
|
| Can Modify Args | Yes | Yes | Yes | Yes | Yes | Yes | Plugin | Plugin | Plugin | -- | -- | -- | -- | Yes (extension) |
|
|
1056
1060
|
| Can Block Tools | Yes | Yes | Yes | Yes | Yes | Yes | Plugin | Plugin | Plugin | Yes | -- | Yes | -- | Yes (extension) |
|
|
@@ -1058,9 +1062,9 @@ Detailed event data is also indexed into FTS5 for on-demand retrieval via `ctx_s
|
|
|
1058
1062
|
| Slash Commands | Yes | -- | -- | -- | -- | -- | -- | -- | -- | -- | -- | -- | -- | -- |
|
|
1059
1063
|
| Plugin Marketplace | Yes | -- | -- | -- | -- | -- | -- | -- | -- | -- | -- | -- | -- | -- |
|
|
1060
1064
|
|
|
1061
|
-
> **OpenCode** uses a TypeScript plugin paradigm — hooks run as in-process functions via `tool.execute.before`, `tool.execute.after`,
|
|
1065
|
+
> **OpenCode** uses a TypeScript plugin paradigm — hooks run as in-process functions via `tool.execute.before`, `tool.execute.after`, `experimental.session.compacting`, `experimental.chat.system.transform`, and `chat.message`, providing full routing enforcement, session continuity, and user-prompt capture. The `experimental.chat.system.transform` hook acts as a SessionStart surrogate to inject the routing block and restore prior sessions. The `chat.message` hook captures user prompts and decisions (UserPromptSubmit equivalent).
|
|
1062
1066
|
>
|
|
1063
|
-
> **KiloCode** shares the same TypeScript plugin architecture as OpenCode via the OpenCodeAdapter, with platform-specific configuration paths (`kilo.json` instead of `opencode.json`, `~/.config/kilo/` instead of `~/.config/opencode/`). Hook capabilities
|
|
1067
|
+
> **KiloCode** shares the same TypeScript plugin architecture as OpenCode via the OpenCodeAdapter, with platform-specific configuration paths (`kilo.json` instead of `opencode.json`, `~/.config/kilo/` instead of `~/.config/opencode/`). Hook capabilities match OpenCode, including SessionStart surrogate via `experimental.chat.system.transform` and user-prompt capture via `chat.message`.
|
|
1064
1068
|
>
|
|
1065
1069
|
> **OpenClaw** runs context-mode as a native gateway plugin targeting Pi Agent sessions. Hooks register via `api.on()` (tool/lifecycle) and `api.registerHook()` (commands). All tool interception and compaction hooks are supported. See [`docs/adapters/openclaw.md`](docs/adapters/openclaw.md).
|
|
1066
1070
|
>
|
|
@@ -308,19 +308,36 @@ export class ClaudeCodeAdapter extends ClaudeCodeBaseAdapter {
|
|
|
308
308
|
if (pluginHooks) {
|
|
309
309
|
const allCovered = REQUIRED_HOOKS.every((ht) => this.checkHookType(undefined, pluginHooks, ht));
|
|
310
310
|
if (allCovered) {
|
|
311
|
-
//
|
|
312
|
-
// is the source of truth
|
|
313
|
-
//
|
|
314
|
-
//
|
|
311
|
+
// Strip ONLY the inner context-mode hook commands from each matcher entry —
|
|
312
|
+
// hooks.json is the source of truth for ctx-mode. User hooks co-located in
|
|
313
|
+
// the same matcher entry MUST be preserved (#415: entry-level filter wiped
|
|
314
|
+
// every co-located user hook). After stripping, prune entries whose `hooks`
|
|
315
|
+
// array becomes empty.
|
|
316
|
+
const ctxScriptNames = Object.values(HOOK_SCRIPTS);
|
|
317
|
+
const isCtxModeCommand = (cmd) => cmd != null &&
|
|
318
|
+
(ctxScriptNames.some((s) => cmd.includes(s)) ||
|
|
319
|
+
cmd.includes("context-mode hook"));
|
|
315
320
|
for (const hookType of Object.keys(hooks)) {
|
|
316
321
|
const entries = hooks[hookType];
|
|
317
322
|
if (!Array.isArray(entries))
|
|
318
323
|
continue;
|
|
319
|
-
|
|
320
|
-
const
|
|
321
|
-
|
|
322
|
-
hooks[
|
|
323
|
-
|
|
324
|
+
let totalRemoved = 0;
|
|
325
|
+
for (const entry of entries) {
|
|
326
|
+
const typedEntry = entry;
|
|
327
|
+
const innerHooks = typedEntry.hooks ?? [];
|
|
328
|
+
const before = innerHooks.length;
|
|
329
|
+
typedEntry.hooks = innerHooks.filter((h) => !isCtxModeCommand(h.command));
|
|
330
|
+
totalRemoved += before - typedEntry.hooks.length;
|
|
331
|
+
}
|
|
332
|
+
const pruned = entries.filter((e) => {
|
|
333
|
+
const ih = e.hooks;
|
|
334
|
+
return Array.isArray(ih) && ih.length > 0;
|
|
335
|
+
});
|
|
336
|
+
if (totalRemoved > 0 || pruned.length !== entries.length) {
|
|
337
|
+
hooks[hookType] = pruned;
|
|
338
|
+
if (totalRemoved > 0) {
|
|
339
|
+
changes.push(`Removed ${totalRemoved} duplicate ${hookType} hook(s) — covered by plugin hooks.json`);
|
|
340
|
+
}
|
|
324
341
|
}
|
|
325
342
|
}
|
|
326
343
|
settings.hooks = hooks;
|
|
@@ -34,9 +34,9 @@ export interface CopilotHookModule {
|
|
|
34
34
|
readonly POST_TOOL_USE: string;
|
|
35
35
|
readonly PRE_COMPACT: string;
|
|
36
36
|
readonly SESSION_START: string;
|
|
37
|
-
readonly STOP
|
|
38
|
-
readonly SUBAGENT_START
|
|
39
|
-
readonly SUBAGENT_STOP
|
|
37
|
+
readonly STOP?: string;
|
|
38
|
+
readonly SUBAGENT_START?: string;
|
|
39
|
+
readonly SUBAGENT_STOP?: string;
|
|
40
40
|
};
|
|
41
41
|
HOOK_SCRIPTS: Record<string, string>;
|
|
42
42
|
buildHookCommand: (hookType: any, pluginRoot?: string) => string;
|
|
@@ -19,8 +19,16 @@ export const HOOK_SCRIPTS = {
|
|
|
19
19
|
[HOOK_TYPES.POST_TOOL_USE]: "posttooluse.mjs",
|
|
20
20
|
[HOOK_TYPES.SESSION_START]: "sessionstart.mjs",
|
|
21
21
|
[HOOK_TYPES.STOP]: "stop.mjs",
|
|
22
|
+
[HOOK_TYPES.AFTER_AGENT_RESPONSE]: "afteragentresponse.mjs",
|
|
22
23
|
};
|
|
23
24
|
/** Canonical Cursor-native matchers for tools context-mode routes proactively. */
|
|
25
|
+
// NOTE (Cursor-3, deferred): Cursor is closed-source and does not currently
|
|
26
|
+
// publish the exact tool name it uses for sub-agent dispatch (the analogue of
|
|
27
|
+
// Claude Code's "Task" tool). The "Task" matcher below is kept as a best-guess
|
|
28
|
+
// placeholder until probe data from a real Cursor session confirms the wire
|
|
29
|
+
// name. If/when that probe lands, replace or supplement this entry — do NOT
|
|
30
|
+
// add unverified matchers in the meantime. See Phase 7 audit
|
|
31
|
+
// `/tmp/v1.0.107-adapter-cursor.json` (Cursor-3) for the full deferral note.
|
|
24
32
|
export const PRE_TOOL_USE_MATCHERS = [
|
|
25
33
|
"Shell",
|
|
26
34
|
"Read",
|
|
@@ -21,7 +21,10 @@ export class CursorAdapter extends BaseAdapter {
|
|
|
21
21
|
preToolUse: true,
|
|
22
22
|
postToolUse: true,
|
|
23
23
|
preCompact: false,
|
|
24
|
-
sessionStart
|
|
24
|
+
// Cursor v1 ships native sessionStart and the matching hook script
|
|
25
|
+
// (hooks/cursor/sessionstart.mjs) is wired through the dispatcher
|
|
26
|
+
// (src/cli.ts HOOK_MAP). Capability flag must reflect script presence.
|
|
27
|
+
sessionStart: true,
|
|
25
28
|
canModifyArgs: true,
|
|
26
29
|
canModifyOutput: false,
|
|
27
30
|
canInjectSessionContext: true,
|
|
@@ -10,12 +10,17 @@
|
|
|
10
10
|
* Gemini CLI hook system reference:
|
|
11
11
|
* - Hooks are registered in ~/.gemini/settings.json under "hooks" key
|
|
12
12
|
* - Each hook type maps to an array of { matcher, hooks } entries
|
|
13
|
-
* - Hook names: BeforeTool, AfterTool, PreCompress, SessionStart
|
|
13
|
+
* - Hook names: BeforeAgent, BeforeTool, AfterTool, PreCompress, SessionStart
|
|
14
14
|
* - Input: JSON on stdin
|
|
15
15
|
* - Output: JSON on stdout (or empty for passthrough)
|
|
16
|
+
* - BeforeAgent fires when user submits a prompt — input.prompt carries
|
|
17
|
+
* the user message; hookSpecificOutput.additionalContext is appended
|
|
18
|
+
* to the prompt (hookRunner.ts:183-197). Equivalent to Claude Code's
|
|
19
|
+
* UserPromptSubmit for session-continuity capture.
|
|
16
20
|
*/
|
|
17
21
|
/** Gemini CLI hook types. */
|
|
18
22
|
export declare const HOOK_TYPES: {
|
|
23
|
+
readonly BEFORE_AGENT: "BeforeAgent";
|
|
19
24
|
readonly BEFORE_TOOL: "BeforeTool";
|
|
20
25
|
readonly AFTER_TOOL: "AfterTool";
|
|
21
26
|
readonly PRE_COMPRESS: "PreCompress";
|
|
@@ -11,15 +11,20 @@ import { buildNodeCommand } from "../types.js";
|
|
|
11
11
|
* Gemini CLI hook system reference:
|
|
12
12
|
* - Hooks are registered in ~/.gemini/settings.json under "hooks" key
|
|
13
13
|
* - Each hook type maps to an array of { matcher, hooks } entries
|
|
14
|
-
* - Hook names: BeforeTool, AfterTool, PreCompress, SessionStart
|
|
14
|
+
* - Hook names: BeforeAgent, BeforeTool, AfterTool, PreCompress, SessionStart
|
|
15
15
|
* - Input: JSON on stdin
|
|
16
16
|
* - Output: JSON on stdout (or empty for passthrough)
|
|
17
|
+
* - BeforeAgent fires when user submits a prompt — input.prompt carries
|
|
18
|
+
* the user message; hookSpecificOutput.additionalContext is appended
|
|
19
|
+
* to the prompt (hookRunner.ts:183-197). Equivalent to Claude Code's
|
|
20
|
+
* UserPromptSubmit for session-continuity capture.
|
|
17
21
|
*/
|
|
18
22
|
// ─────────────────────────────────────────────────────────
|
|
19
23
|
// Hook type constants
|
|
20
24
|
// ─────────────────────────────────────────────────────────
|
|
21
25
|
/** Gemini CLI hook types. */
|
|
22
26
|
export const HOOK_TYPES = {
|
|
27
|
+
BEFORE_AGENT: "BeforeAgent",
|
|
23
28
|
BEFORE_TOOL: "BeforeTool",
|
|
24
29
|
AFTER_TOOL: "AfterTool",
|
|
25
30
|
PRE_COMPRESS: "PreCompress",
|
|
@@ -30,6 +35,7 @@ export const HOOK_TYPES = {
|
|
|
30
35
|
// ─────────────────────────────────────────────────────────
|
|
31
36
|
/** Map of hook types to their script file names. */
|
|
32
37
|
export const HOOK_SCRIPTS = {
|
|
38
|
+
[HOOK_TYPES.BEFORE_AGENT]: "beforeagent.mjs",
|
|
33
39
|
[HOOK_TYPES.BEFORE_TOOL]: "beforetool.mjs",
|
|
34
40
|
[HOOK_TYPES.AFTER_TOOL]: "aftertool.mjs",
|
|
35
41
|
[HOOK_TYPES.PRE_COMPRESS]: "precompress.mjs",
|
|
@@ -165,6 +165,17 @@ export class GeminiCLIAdapter extends BaseAdapter {
|
|
|
165
165
|
}
|
|
166
166
|
generateHookConfig(pluginRoot) {
|
|
167
167
|
return {
|
|
168
|
+
[GEMINI_HOOK_NAMES.BEFORE_AGENT]: [
|
|
169
|
+
{
|
|
170
|
+
matcher: "",
|
|
171
|
+
hooks: [
|
|
172
|
+
{
|
|
173
|
+
type: "command",
|
|
174
|
+
command: buildGeminiHookCommand(GEMINI_HOOK_NAMES.BEFORE_AGENT, pluginRoot),
|
|
175
|
+
},
|
|
176
|
+
],
|
|
177
|
+
},
|
|
178
|
+
],
|
|
168
179
|
[GEMINI_HOOK_NAMES.BEFORE_TOOL]: [
|
|
169
180
|
{
|
|
170
181
|
matcher: "run_shell_command|read_file|read_many_files|grep_search|search_file_content|web_fetch|activate_skill|mcp__plugin_context-mode",
|
|
@@ -331,6 +342,7 @@ export class GeminiCLIAdapter extends BaseAdapter {
|
|
|
331
342
|
const hooks = (settings.hooks ?? {});
|
|
332
343
|
const changes = [];
|
|
333
344
|
const hookConfigs = [
|
|
345
|
+
{ name: GEMINI_HOOK_NAMES.BEFORE_AGENT },
|
|
334
346
|
{ name: GEMINI_HOOK_NAMES.BEFORE_TOOL },
|
|
335
347
|
{ name: GEMINI_HOOK_NAMES.SESSION_START },
|
|
336
348
|
];
|
|
@@ -20,6 +20,8 @@ export const HOOK_TYPES = {
|
|
|
20
20
|
export const HOOK_SCRIPTS = {
|
|
21
21
|
[HOOK_TYPES.PRE_TOOL_USE]: "pretooluse.mjs",
|
|
22
22
|
[HOOK_TYPES.POST_TOOL_USE]: "posttooluse.mjs",
|
|
23
|
+
[HOOK_TYPES.USER_PROMPT_SUBMIT]: "userpromptsubmit.mjs",
|
|
24
|
+
[HOOK_TYPES.AGENT_SPAWN]: "agentspawn.mjs",
|
|
23
25
|
};
|
|
24
26
|
// ─────────────────────────────────────────────────────────
|
|
25
27
|
// PreToolUse matchers
|
|
@@ -46,9 +48,11 @@ export const PRE_TOOL_USE_MATCHERS = [
|
|
|
46
48
|
export const PRE_TOOL_USE_MATCHER_PATTERN = PRE_TOOL_USE_MATCHERS.join("|");
|
|
47
49
|
export const REQUIRED_HOOKS = [
|
|
48
50
|
HOOK_TYPES.PRE_TOOL_USE,
|
|
51
|
+
HOOK_TYPES.AGENT_SPAWN,
|
|
49
52
|
];
|
|
50
53
|
export const OPTIONAL_HOOKS = [
|
|
51
54
|
HOOK_TYPES.POST_TOOL_USE,
|
|
55
|
+
HOOK_TYPES.USER_PROMPT_SUBMIT,
|
|
52
56
|
];
|
|
53
57
|
/**
|
|
54
58
|
* Check if a hook entry points to a context-mode hook script.
|
|
@@ -18,6 +18,13 @@
|
|
|
18
18
|
* - CLI hooks: https://kiro.dev/docs/cli/custom-agents/configuration-reference#hooks-field
|
|
19
19
|
*/
|
|
20
20
|
import { BaseAdapter } from "../base.js";
|
|
21
|
+
/**
|
|
22
|
+
* Steering integration: we ship a single context-mode-specific routing file
|
|
23
|
+
* at `configs/kiro/KIRO.md`. Users can copy it into `.kiro/steering/` to opt
|
|
24
|
+
* into deterministic injection. We do NOT deploy generic SDD scaffolds (e.g.
|
|
25
|
+
* cc-sdd's product/structure/tech + steering-custom/* templates) — those are
|
|
26
|
+
* project-template content, not adapter wiring.
|
|
27
|
+
*/
|
|
21
28
|
import type { HookAdapter, HookParadigm, PlatformCapabilities, DiagnosticResult, PreToolUseEvent, PostToolUseEvent, PreCompactEvent, SessionStartEvent, PreToolUseResponse, PostToolUseResponse, PreCompactResponse, SessionStartResponse, HookRegistration } from "../types.js";
|
|
22
29
|
export declare class KiroAdapter extends BaseAdapter implements HookAdapter {
|
|
23
30
|
constructor();
|
|
@@ -27,11 +34,11 @@ export declare class KiroAdapter extends BaseAdapter implements HookAdapter {
|
|
|
27
34
|
parsePreToolUseInput(raw: unknown): PreToolUseEvent;
|
|
28
35
|
parsePostToolUseInput(raw: unknown): PostToolUseEvent;
|
|
29
36
|
parsePreCompactInput(_raw: unknown): PreCompactEvent;
|
|
30
|
-
parseSessionStartInput(
|
|
37
|
+
parseSessionStartInput(raw: unknown): SessionStartEvent;
|
|
31
38
|
formatPreToolUseResponse(response: PreToolUseResponse): unknown;
|
|
32
39
|
formatPostToolUseResponse(_response: PostToolUseResponse): unknown;
|
|
33
40
|
formatPreCompactResponse(_response: PreCompactResponse): unknown;
|
|
34
|
-
formatSessionStartResponse(
|
|
41
|
+
formatSessionStartResponse(response: SessionStartResponse): unknown;
|
|
35
42
|
getSettingsPath(): string;
|
|
36
43
|
/**
|
|
37
44
|
* Kiro stores per-project context under .kiro/ (steering files, etc).
|
|
@@ -36,10 +36,10 @@ export class KiroAdapter extends BaseAdapter {
|
|
|
36
36
|
preToolUse: true,
|
|
37
37
|
postToolUse: true,
|
|
38
38
|
preCompact: false,
|
|
39
|
-
sessionStart:
|
|
39
|
+
sessionStart: true, // Kiro agentSpawn = SessionStart equivalent
|
|
40
40
|
canModifyArgs: false, // Kiro CLI uses exit codes, can't modify input
|
|
41
41
|
canModifyOutput: false,
|
|
42
|
-
canInjectSessionContext:
|
|
42
|
+
canInjectSessionContext: true, // agentSpawn returns additionalContext via JSON stdout
|
|
43
43
|
};
|
|
44
44
|
// ── Input parsing ──────────────────────────────────────
|
|
45
45
|
parsePreToolUseInput(raw) {
|
|
@@ -69,8 +69,16 @@ export class KiroAdapter extends BaseAdapter {
|
|
|
69
69
|
parsePreCompactInput(_raw) {
|
|
70
70
|
throw new Error("Kiro does not support PreCompact hooks");
|
|
71
71
|
}
|
|
72
|
-
parseSessionStartInput(
|
|
73
|
-
|
|
72
|
+
parseSessionStartInput(raw) {
|
|
73
|
+
// Kiro maps agentSpawn -> SessionStart. Stdin shape mirrors codex/CC.
|
|
74
|
+
const input = (raw ?? {});
|
|
75
|
+
const source = input.source ?? "startup";
|
|
76
|
+
return {
|
|
77
|
+
source,
|
|
78
|
+
sessionId: `pid-${process.ppid}`,
|
|
79
|
+
projectDir: input.cwd ?? process.cwd(),
|
|
80
|
+
raw,
|
|
81
|
+
};
|
|
74
82
|
}
|
|
75
83
|
// ── Response formatting ────────────────────────────────
|
|
76
84
|
formatPreToolUseResponse(response) {
|
|
@@ -91,8 +99,16 @@ export class KiroAdapter extends BaseAdapter {
|
|
|
91
99
|
formatPreCompactResponse(_response) {
|
|
92
100
|
return undefined;
|
|
93
101
|
}
|
|
94
|
-
formatSessionStartResponse(
|
|
95
|
-
|
|
102
|
+
formatSessionStartResponse(response) {
|
|
103
|
+
// Kiro agentSpawn returns the same hookSpecificOutput shape as CC SessionStart.
|
|
104
|
+
if (!response?.context)
|
|
105
|
+
return undefined;
|
|
106
|
+
return {
|
|
107
|
+
hookSpecificOutput: {
|
|
108
|
+
hookEventName: "agentSpawn",
|
|
109
|
+
additionalContext: response.context,
|
|
110
|
+
},
|
|
111
|
+
};
|
|
96
112
|
}
|
|
97
113
|
// ── Configuration ──────────────────────────────────────
|
|
98
114
|
getSettingsPath() {
|
|
@@ -111,8 +127,8 @@ export class KiroAdapter extends BaseAdapter {
|
|
|
111
127
|
return ["KIRO.md"];
|
|
112
128
|
}
|
|
113
129
|
generateHookConfig(pluginRoot) {
|
|
114
|
-
// Kiro CLI hook config format: {
|
|
115
|
-
// Note: This generates the entries for agent config files
|
|
130
|
+
// Kiro CLI hook config format: { <hookName>: [{ matcher, command }] }
|
|
131
|
+
// Note: This generates the entries for agent config files (~/.kiro/agents/*.json).
|
|
116
132
|
return {
|
|
117
133
|
[KIRO_HOOK_TYPES.PRE_TOOL_USE]: [{
|
|
118
134
|
matcher: KIRO_PRE_TOOL_USE_MATCHER_PATTERN,
|
|
@@ -122,6 +138,14 @@ export class KiroAdapter extends BaseAdapter {
|
|
|
122
138
|
matcher: "*",
|
|
123
139
|
hooks: [{ type: "command", command: buildKiroHookCommand(KIRO_HOOK_TYPES.POST_TOOL_USE, pluginRoot) }],
|
|
124
140
|
}],
|
|
141
|
+
[KIRO_HOOK_TYPES.AGENT_SPAWN]: [{
|
|
142
|
+
matcher: "*",
|
|
143
|
+
hooks: [{ type: "command", command: buildKiroHookCommand(KIRO_HOOK_TYPES.AGENT_SPAWN, pluginRoot) }],
|
|
144
|
+
}],
|
|
145
|
+
[KIRO_HOOK_TYPES.USER_PROMPT_SUBMIT]: [{
|
|
146
|
+
matcher: "*",
|
|
147
|
+
hooks: [{ type: "command", command: buildKiroHookCommand(KIRO_HOOK_TYPES.USER_PROMPT_SUBMIT, pluginRoot) }],
|
|
148
|
+
}],
|
|
125
149
|
};
|
|
126
150
|
}
|
|
127
151
|
readSettings() {
|
|
@@ -233,25 +257,23 @@ export class KiroAdapter extends BaseAdapter {
|
|
|
233
257
|
// No existing config — create new
|
|
234
258
|
}
|
|
235
259
|
const hooks = (config.hooks ?? {});
|
|
236
|
-
//
|
|
237
|
-
const
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
}
|
|
253
|
-
hooks[KIRO_HOOK_TYPES.POST_TOOL_USE] = postToolUseEntries;
|
|
254
|
-
changes.push(`Added ${KIRO_HOOK_TYPES.POST_TOOL_USE} hook to ${defaultAgent}`);
|
|
260
|
+
// Hooks to add: [hookType, matcher]
|
|
261
|
+
const hookSpecs = [
|
|
262
|
+
[KIRO_HOOK_TYPES.PRE_TOOL_USE, KIRO_PRE_TOOL_USE_MATCHER_PATTERN],
|
|
263
|
+
[KIRO_HOOK_TYPES.POST_TOOL_USE, "*"],
|
|
264
|
+
[KIRO_HOOK_TYPES.AGENT_SPAWN, "*"],
|
|
265
|
+
[KIRO_HOOK_TYPES.USER_PROMPT_SUBMIT, "*"],
|
|
266
|
+
];
|
|
267
|
+
for (const [hookType, matcher] of hookSpecs) {
|
|
268
|
+
const entries = (hooks[hookType] ?? []);
|
|
269
|
+
if (!entries.some(e => isKiroContextModeHook(e, hookType))) {
|
|
270
|
+
entries.push({
|
|
271
|
+
matcher,
|
|
272
|
+
command: buildKiroHookCommand(hookType, pluginRoot),
|
|
273
|
+
});
|
|
274
|
+
hooks[hookType] = entries;
|
|
275
|
+
changes.push(`Added ${hookType} hook to ${defaultAgent}`);
|
|
276
|
+
}
|
|
255
277
|
}
|
|
256
278
|
config.hooks = hooks;
|
|
257
279
|
writeFileSync(defaultAgent, JSON.stringify(config, null, 2), "utf-8");
|
|
@@ -40,10 +40,10 @@ export class OpenCodeAdapter extends BaseAdapter {
|
|
|
40
40
|
preToolUse: true,
|
|
41
41
|
postToolUse: true,
|
|
42
42
|
preCompact: true, // experimental
|
|
43
|
-
sessionStart:
|
|
43
|
+
sessionStart: true,
|
|
44
44
|
canModifyArgs: true,
|
|
45
45
|
canModifyOutput: true, // with TUI bug caveat for bash (#13575)
|
|
46
|
-
canInjectSessionContext:
|
|
46
|
+
canInjectSessionContext: true,
|
|
47
47
|
};
|
|
48
48
|
platform;
|
|
49
49
|
constructor(platform = "opencode") {
|
|
@@ -152,11 +152,17 @@ export class OpenCodeAdapter extends BaseAdapter {
|
|
|
152
152
|
}
|
|
153
153
|
paths() {
|
|
154
154
|
if (this.platform === "kilo") {
|
|
155
|
+
// Kilo runtime accepts `.kilo/`, `.kilocode/`, and `.opencode/` as
|
|
156
|
+
// project config dirs (refs/platforms/kilo/packages/opencode/src/
|
|
157
|
+
// kilocode/config/config.ts:50,408). Mirror that here so context-mode
|
|
158
|
+
// discovers config regardless of which suffix the user adopted.
|
|
155
159
|
return [
|
|
156
160
|
resolve("kilo.json"),
|
|
157
161
|
resolve("kilo.jsonc"),
|
|
158
162
|
resolve(".kilo", "kilo.json"),
|
|
159
163
|
resolve(".kilo", "kilo.jsonc"),
|
|
164
|
+
resolve(".kilocode", "kilo.json"),
|
|
165
|
+
resolve(".kilocode", "kilo.jsonc"),
|
|
160
166
|
join(homedir(), ".config", "kilo", "kilo.json"),
|
|
161
167
|
join(homedir(), ".config", "kilo", "kilo.jsonc"),
|
|
162
168
|
];
|
|
@@ -304,11 +310,11 @@ export class OpenCodeAdapter extends BaseAdapter {
|
|
|
304
310
|
fix: "context-mode upgrade",
|
|
305
311
|
});
|
|
306
312
|
}
|
|
307
|
-
//
|
|
313
|
+
// Note: SessionStart handled via experimental.chat.system.transform surrogate
|
|
308
314
|
results.push({
|
|
309
315
|
check: "SessionStart hook",
|
|
310
|
-
status: "
|
|
311
|
-
message: `SessionStart
|
|
316
|
+
status: "pass",
|
|
317
|
+
message: `SessionStart via experimental.chat.system.transform surrogate (native hook pending #14808, #5409)`,
|
|
312
318
|
});
|
|
313
319
|
return results;
|
|
314
320
|
}
|
|
@@ -230,6 +230,9 @@ export class QwenCodeAdapter extends ClaudeCodeBaseAdapter {
|
|
|
230
230
|
}
|
|
231
231
|
}
|
|
232
232
|
// ── Phase 2: Register fresh hooks ────────────────────
|
|
233
|
+
// All 5 hooks must be wired (z6 — capabilities declare 5 events but
|
|
234
|
+
// configureAllHooks previously only wrote 2). Qwen Code's hook stdin shape
|
|
235
|
+
// is wire-identical to Claude Code, so we reuse top-level hook scripts.
|
|
233
236
|
const hookTypes = [
|
|
234
237
|
{
|
|
235
238
|
name: "PreToolUse",
|
|
@@ -242,11 +245,26 @@ export class QwenCodeAdapter extends ClaudeCodeBaseAdapter {
|
|
|
242
245
|
"mcp__plugin_context-mode_context-mode__ctx_batch_execute",
|
|
243
246
|
].join("|"),
|
|
244
247
|
},
|
|
248
|
+
{
|
|
249
|
+
name: "PostToolUse",
|
|
250
|
+
script: "posttooluse.mjs",
|
|
251
|
+
matcher: "run_shell_command|read_file|write_file|edit|glob|grep_search|todo_write|agent|ask_user_question|mcp__",
|
|
252
|
+
},
|
|
245
253
|
{
|
|
246
254
|
name: "SessionStart",
|
|
247
255
|
script: "sessionstart.mjs",
|
|
248
256
|
matcher: "",
|
|
249
257
|
},
|
|
258
|
+
{
|
|
259
|
+
name: "PreCompact",
|
|
260
|
+
script: "precompact.mjs",
|
|
261
|
+
matcher: "",
|
|
262
|
+
},
|
|
263
|
+
{
|
|
264
|
+
name: "UserPromptSubmit",
|
|
265
|
+
script: "userpromptsubmit.mjs",
|
|
266
|
+
matcher: "",
|
|
267
|
+
},
|
|
250
268
|
];
|
|
251
269
|
for (const { name, script, matcher } of hookTypes) {
|
|
252
270
|
const entry = {
|