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.
Files changed (72) hide show
  1. package/.claude-plugin/marketplace.json +2 -2
  2. package/.claude-plugin/plugin.json +1 -1
  3. package/.openclaw-plugin/openclaw.plugin.json +1 -1
  4. package/.openclaw-plugin/package.json +1 -1
  5. package/README.md +22 -18
  6. package/build/adapters/claude-code/index.js +26 -9
  7. package/build/adapters/copilot-base.d.ts +3 -3
  8. package/build/adapters/cursor/hooks.js +8 -0
  9. package/build/adapters/cursor/index.js +4 -1
  10. package/build/adapters/gemini-cli/hooks.d.ts +6 -1
  11. package/build/adapters/gemini-cli/hooks.js +7 -1
  12. package/build/adapters/gemini-cli/index.js +12 -0
  13. package/build/adapters/kiro/hooks.js +4 -0
  14. package/build/adapters/kiro/index.d.ts +9 -2
  15. package/build/adapters/kiro/index.js +49 -27
  16. package/build/adapters/opencode/index.js +11 -5
  17. package/build/adapters/qwen-code/index.js +18 -0
  18. package/build/adapters/vscode-copilot/hooks.d.ts +0 -4
  19. package/build/adapters/vscode-copilot/hooks.js +6 -6
  20. package/build/cli.js +93 -12
  21. package/build/openclaw/mcp-tools.d.ts +54 -0
  22. package/build/openclaw/mcp-tools.js +198 -0
  23. package/build/openclaw-plugin.d.ts +9 -0
  24. package/build/openclaw-plugin.js +132 -16
  25. package/build/opencode-plugin.d.ts +29 -4
  26. package/build/opencode-plugin.js +154 -7
  27. package/build/pi-extension.js +123 -29
  28. package/build/server.d.ts +1 -0
  29. package/build/server.js +26 -1
  30. package/build/session/analytics.js +36 -13
  31. package/build/session/extract.d.ts +1 -1
  32. package/build/session/extract.js +46 -1
  33. package/cli.bundle.mjs +133 -132
  34. package/hooks/core/platform-detect.mjs +49 -0
  35. package/hooks/core/routing.mjs +13 -1
  36. package/hooks/cursor/afteragentresponse.mjs +74 -0
  37. package/hooks/ensure-deps.mjs +28 -12
  38. package/hooks/gemini-cli/beforeagent.mjs +99 -0
  39. package/hooks/kiro/agentspawn.mjs +97 -0
  40. package/hooks/kiro/userpromptsubmit.mjs +88 -0
  41. package/hooks/posttooluse.mjs +90 -80
  42. package/hooks/precompact.mjs +56 -46
  43. package/hooks/pretooluse.mjs +161 -167
  44. package/hooks/routing-block.mjs +2 -2
  45. package/hooks/run-hook.mjs +82 -0
  46. package/hooks/session-extract.bundle.mjs +2 -2
  47. package/hooks/sessionstart.mjs +187 -153
  48. package/hooks/userpromptsubmit.mjs +69 -58
  49. package/hooks/vscode-copilot/sessionstart.mjs +13 -14
  50. package/openclaw.plugin.json +1 -1
  51. package/package.json +2 -1
  52. package/scripts/heal-better-sqlite3.mjs +108 -0
  53. package/scripts/postinstall.mjs +27 -0
  54. package/server.bundle.mjs +79 -79
  55. package/skills/UPSTREAM-CREDITS.md +51 -0
  56. package/skills/context-mode-ops/SKILL.md +147 -0
  57. package/skills/diagnose/SKILL.md +122 -0
  58. package/skills/diagnose/scripts/hitl-loop.template.sh +41 -0
  59. package/skills/grill-me/SKILL.md +15 -0
  60. package/skills/grill-with-docs/ADR-FORMAT.md +47 -0
  61. package/skills/grill-with-docs/CONTEXT-FORMAT.md +77 -0
  62. package/skills/grill-with-docs/SKILL.md +93 -0
  63. package/skills/improve-codebase-architecture/DEEPENING.md +37 -0
  64. package/skills/improve-codebase-architecture/INTERFACE-DESIGN.md +44 -0
  65. package/skills/improve-codebase-architecture/LANGUAGE.md +53 -0
  66. package/skills/improve-codebase-architecture/SKILL.md +76 -0
  67. package/skills/tdd/SKILL.md +114 -0
  68. package/skills/tdd/deep-modules.md +33 -0
  69. package/skills/tdd/interface-design.md +31 -0
  70. package/skills/tdd/mocking.md +59 -0
  71. package/skills/tdd/refactoring.md +10 -0
  72. 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.106"
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.106",
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.106",
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.106",
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.106",
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. OpenCode lacks a SessionStart hook, so the model needs an `AGENTS.md` file for routing awareness:
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's SessionStart hook is not yet available ([#14808](https://github.com/sst/opencode/issues/14808)), so startup/resume session restore is not supported. Compaction recovery works fully via the plugin.
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 and lacks SessionStart, so the model needs an `AGENTS.md` file for routing awareness:
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 availability depends on KiloCode's implementation.
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 4 hooks working together:
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 | -- | -- | -- | -- | -- | -- | -- | 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 | -- | -- | -- | Plugin | Yes | -- | -- | -- | ✓ (via session_start event) |
933
- | | **Session completeness** | **Full** | **High** | **High** | **High** | **Partial** | **High** | **High** | **High** | **Partial** | **--** | **Partial** | **--** | **High** |
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**, and **JetBrains Copilot**. **OpenCode** provides **high** session continuity: it captures tool events and injects compaction snapshots via the plugin, but SessionStart is not yet available ([#14808](https://github.com/sst/opencode/issues/14808)), so startup/resume restore is not supported. **KiloCode** shares the same plugin architecture as OpenCode via the OpenCodeAdapter, so its continuity level depends on KiloCode's SessionStart support. **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.
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 `--continue`.
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** — Partial. The TypeScript plugin captures PostToolUse events via `tool.execute.after`, but SessionStart is not yet available ([#14808](https://github.com/sst/opencode/issues/14808)). Events are stored but not automatically restored after compaction.
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** — Partial. Shares the same plugin architecture as OpenCode via the OpenCodeAdapter. The TypeScript plugin captures PostToolUse events via `tool.execute.after`, but SessionStart availability depends on KiloCode's implementation. Events are stored but may not be automatically restored after compaction.
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 | -- | -- | -- | Plugin | Yes | -- | -- | -- | Yes (extension) |
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`, and `experimental.session.compacting`, providing the same routing enforcement and session continuity as shell-based hooks. SessionStart is not yet available ([#14808](https://github.com/sst/opencode/issues/14808)), but compaction recovery works via the plugin's compacting hook.
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 depend on KiloCode's implementation of the plugin interface.
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
- // Remove ALL existing context-mode hooks from settings.json hooks.json
312
- // is the source of truth. Keeping them causes duplicate concurrent hook
313
- // processes (one from settings.json, one from hooks.json), which triggers
314
- // "non-blocking hook error" warnings on every tool call.
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
- const filtered = entries.filter((entry) => !isAnyContextModeHook(entry));
320
- const removed = entries.length - filtered.length;
321
- if (removed > 0) {
322
- hooks[hookType] = filtered;
323
- changes.push(`Removed ${removed} duplicate ${hookType} hook(s) — covered by plugin hooks.json`);
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: string;
38
- readonly SUBAGENT_START: string;
39
- readonly SUBAGENT_STOP: string;
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: false,
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(_raw: unknown): SessionStartEvent;
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(_response: SessionStartResponse): unknown;
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: false,
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: false,
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(_raw) {
73
- throw new Error("Kiro does not support SessionStart hooks (yet)");
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(_response) {
95
- return undefined;
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: { preToolUse: [{ matcher, command }] }
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
- // Add preToolUse hook if not present
237
- const preToolUseEntries = (hooks[KIRO_HOOK_TYPES.PRE_TOOL_USE] ?? []);
238
- if (!preToolUseEntries.some(e => isKiroContextModeHook(e, KIRO_HOOK_TYPES.PRE_TOOL_USE))) {
239
- preToolUseEntries.push({
240
- matcher: KIRO_PRE_TOOL_USE_MATCHER_PATTERN,
241
- command: buildKiroHookCommand(KIRO_HOOK_TYPES.PRE_TOOL_USE, pluginRoot),
242
- });
243
- hooks[KIRO_HOOK_TYPES.PRE_TOOL_USE] = preToolUseEntries;
244
- changes.push(`Added ${KIRO_HOOK_TYPES.PRE_TOOL_USE} hook to ${defaultAgent}`);
245
- }
246
- // Add postToolUse hook if not present
247
- const postToolUseEntries = (hooks[KIRO_HOOK_TYPES.POST_TOOL_USE] ?? []);
248
- if (!postToolUseEntries.some(e => isKiroContextModeHook(e, KIRO_HOOK_TYPES.POST_TOOL_USE))) {
249
- postToolUseEntries.push({
250
- matcher: "*",
251
- command: buildKiroHookCommand(KIRO_HOOK_TYPES.POST_TOOL_USE, pluginRoot),
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: false,
43
+ sessionStart: true,
44
44
  canModifyArgs: true,
45
45
  canModifyOutput: true, // with TUI bug caveat for bash (#13575)
46
- canInjectSessionContext: false,
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
- // Warn about SessionStart limitation
313
+ // Note: SessionStart handled via experimental.chat.system.transform surrogate
308
314
  results.push({
309
315
  check: "SessionStart hook",
310
- status: "warn",
311
- message: `SessionStart not supported in ${this.name} (see issues #14808, #5409)`,
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 = {