context-mode 1.0.54 → 1.0.56

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 (50) 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 +20 -6
  6. package/build/adapters/antigravity/index.d.ts +1 -3
  7. package/build/adapters/antigravity/index.js +0 -30
  8. package/build/adapters/claude-code/index.d.ts +1 -3
  9. package/build/adapters/claude-code/index.js +15 -34
  10. package/build/adapters/codex/index.d.ts +1 -3
  11. package/build/adapters/codex/index.js +1 -31
  12. package/build/adapters/cursor/index.d.ts +1 -3
  13. package/build/adapters/cursor/index.js +0 -11
  14. package/build/adapters/gemini-cli/index.d.ts +1 -3
  15. package/build/adapters/gemini-cli/index.js +0 -30
  16. package/build/adapters/kiro/index.d.ts +1 -3
  17. package/build/adapters/kiro/index.js +0 -30
  18. package/build/adapters/openclaw/index.d.ts +1 -3
  19. package/build/adapters/openclaw/index.js +0 -38
  20. package/build/adapters/opencode/index.d.ts +1 -3
  21. package/build/adapters/opencode/index.js +15 -34
  22. package/build/adapters/types.d.ts +0 -13
  23. package/build/adapters/vscode-copilot/index.d.ts +1 -3
  24. package/build/adapters/vscode-copilot/index.js +0 -32
  25. package/build/adapters/zed/index.d.ts +1 -3
  26. package/build/adapters/zed/index.js +0 -30
  27. package/build/executor.d.ts +0 -1
  28. package/build/executor.js +26 -14
  29. package/build/openclaw-plugin.js +0 -30
  30. package/build/opencode-plugin.d.ts +1 -0
  31. package/build/opencode-plugin.js +1 -8
  32. package/build/server.js +34 -17
  33. package/build/truncate.d.ts +4 -17
  34. package/build/truncate.js +4 -52
  35. package/cli.bundle.mjs +109 -136
  36. package/hooks/ensure-deps.mjs +80 -2
  37. package/hooks/routing-block.mjs +10 -1
  38. package/hooks/session-snapshot.bundle.mjs +13 -13
  39. package/openclaw.plugin.json +1 -1
  40. package/package.json +1 -1
  41. package/server.bundle.mjs +82 -106
  42. package/skills/context-mode-ops/SKILL.md +111 -0
  43. package/skills/context-mode-ops/agent-teams.md +198 -0
  44. package/skills/context-mode-ops/communication.md +224 -0
  45. package/skills/context-mode-ops/release.md +199 -0
  46. package/skills/context-mode-ops/review-pr.md +269 -0
  47. package/skills/context-mode-ops/tdd.md +329 -0
  48. package/skills/context-mode-ops/triage-issue.md +218 -0
  49. package/skills/context-mode-ops/validation.md +238 -0
  50. package/start.mjs +5 -52
@@ -6,14 +6,14 @@
6
6
  },
7
7
  "metadata": {
8
8
  "description": "Claude Code plugins by Mert Koseoğlu",
9
- "version": "1.0.54"
9
+ "version": "1.0.56"
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.54",
16
+ "version": "1.0.56",
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.54",
3
+ "version": "1.0.56",
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.54",
6
+ "version": "1.0.56",
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.54",
3
+ "version": "1.0.56",
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
@@ -282,15 +282,23 @@ Full configs: [`configs/cursor/hooks.json`](configs/cursor/hooks.json) | [`confi
282
282
 
283
283
  The `mcp` entry registers the 6 sandbox 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.
284
284
 
285
- 3. Restart OpenCode.
285
+ 3. *(Optional)* Copy the routing rules file. OpenCode lacks a SessionStart hook, so the model needs an `AGENTS.md` file for routing awareness:
286
+
287
+ ```bash
288
+ cp node_modules/context-mode/configs/opencode/AGENTS.md AGENTS.md
289
+ ```
290
+
291
+ This tells the model which tools to use and which commands are blocked. Without it, hooks still enforce routing — but the model won't know *why* a command was denied.
292
+
293
+ 4. Restart OpenCode.
286
294
 
287
295
  **Verify:** In the OpenCode session, type `ctx stats`. Context-mode tools should appear and respond.
288
296
 
289
- **Routing:** Automatic. The plugin intercepts tool calls at runtime via `tool.execute.before` and `tool.execute.after`. No routing file is written to your project. The `experimental.session.compacting` hook builds resume snapshots when the conversation compacts.
297
+ **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.
290
298
 
291
299
  > **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.
292
300
 
293
- Full config: [`configs/opencode/opencode.json`](configs/opencode/opencode.json)
301
+ Full configs: [`configs/opencode/opencode.json`](configs/opencode/opencode.json) | [`configs/opencode/AGENTS.md`](configs/opencode/AGENTS.md)
294
302
 
295
303
  </details>
296
304
 
@@ -324,11 +332,17 @@ Full config: [`configs/opencode/opencode.json`](configs/opencode/opencode.json)
324
332
 
325
333
  The `mcp` entry registers the 6 sandbox 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.
326
334
 
327
- 3. Restart KiloCode.
335
+ 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:
336
+
337
+ ```bash
338
+ cp node_modules/context-mode/configs/opencode/AGENTS.md AGENTS.md
339
+ ```
340
+
341
+ 4. Restart KiloCode.
328
342
 
329
343
  **Verify:** In the KiloCode session, type `ctx stats`. Context-mode tools should appear and respond.
330
344
 
331
- **Routing:** Automatic. The plugin intercepts tool calls at runtime via `tool.execute.before` and `tool.execute.after`. No routing file is written to your project. The `experimental.session.compacting` hook builds resume snapshots when the conversation compacts.
345
+ **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.
332
346
 
333
347
  > **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.
334
348
 
@@ -710,7 +724,7 @@ Session continuity requires 4 hooks working together:
710
724
  | **SessionStart** | Restores state after compaction or resume | Yes | Yes | Yes | -- | -- | -- | Plugin | -- | -- | -- | -- | ✓ (via session_start event) |
711
725
  | | **Session completeness** | **Full** | **High** | **High** | **Partial** | **High** | **High** | **High** | **--** | **--** | **Partial** | **--** | **High** |
712
726
 
713
- > **Note:** Full session continuity (capture + snapshot + restore) works on **Claude Code**, **Gemini CLI**, **VS Code Copilot**, and **OpenCode**. **KiloCode** shares the same plugin architecture as OpenCode via the OpenCodeAdapter. **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. **OpenCode** uses the `experimental.session.compacting` plugin hook for compaction recovery, but SessionStart is not yet available ([#14808](https://github.com/sst/opencode/issues/14808)), so startup/resume is not supported. **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**, **Antigravity**, **Kiro**, and **Zed** have no hook support in the current release, so session tracking is not available.
727
+ > **Note:** Full session continuity (capture + snapshot + restore) works on **Claude Code**, **Gemini CLI**, and **VS Code 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**, **Antigravity**, **Kiro**, and **Zed** have no hook support in the current release, so session tracking is not available.
714
728
 
715
729
  <details>
716
730
  <summary><strong>What gets captured</strong></summary>
@@ -16,7 +16,7 @@
16
16
  * - MCP support: https://antigravity.google/docs/mcp
17
17
  * - Tool list: System prompt leak (21 verified tools)
18
18
  */
19
- import type { HookAdapter, HookParadigm, PlatformCapabilities, DiagnosticResult, PreToolUseEvent, PostToolUseEvent, PreCompactEvent, SessionStartEvent, PreToolUseResponse, PostToolUseResponse, PreCompactResponse, SessionStartResponse, HookRegistration, RoutingInstructionsConfig } from "../types.js";
19
+ import type { HookAdapter, HookParadigm, PlatformCapabilities, DiagnosticResult, PreToolUseEvent, PostToolUseEvent, PreCompactEvent, SessionStartEvent, PreToolUseResponse, PostToolUseResponse, PreCompactResponse, SessionStartResponse, HookRegistration } from "../types.js";
20
20
  export declare class AntigravityAdapter implements HookAdapter {
21
21
  readonly name = "Antigravity";
22
22
  readonly paradigm: HookParadigm;
@@ -43,7 +43,5 @@ export declare class AntigravityAdapter implements HookAdapter {
43
43
  backupSettings(): string | null;
44
44
  setHookPermissions(_pluginRoot: string): string[];
45
45
  updatePluginRegistry(_pluginRoot: string, _version: string): void;
46
- getRoutingInstructionsConfig(): RoutingInstructionsConfig;
47
- writeRoutingInstructions(projectDir: string, pluginRoot: string): string | null;
48
46
  getRoutingInstructions(): string;
49
47
  }
@@ -175,36 +175,6 @@ export class AntigravityAdapter {
175
175
  updatePluginRegistry(_pluginRoot, _version) {
176
176
  // Antigravity plugin registry is managed via mcp_config.json
177
177
  }
178
- // ── Routing Instructions (soft enforcement) ────────────
179
- getRoutingInstructionsConfig() {
180
- return {
181
- fileName: "GEMINI.md",
182
- globalPath: resolve(homedir(), ".gemini", "GEMINI.md"),
183
- projectRelativePath: "GEMINI.md",
184
- };
185
- }
186
- writeRoutingInstructions(projectDir, pluginRoot) {
187
- const config = this.getRoutingInstructionsConfig();
188
- const targetPath = resolve(projectDir, config.projectRelativePath);
189
- const sourcePath = resolve(pluginRoot, "configs", "antigravity", config.fileName);
190
- try {
191
- const content = readFileSync(sourcePath, "utf-8");
192
- try {
193
- const existing = readFileSync(targetPath, "utf-8");
194
- if (existing.includes("context-mode"))
195
- return null;
196
- writeFileSync(targetPath, existing.trimEnd() + "\n\n" + content, "utf-8");
197
- return targetPath;
198
- }
199
- catch {
200
- writeFileSync(targetPath, content, "utf-8");
201
- return targetPath;
202
- }
203
- }
204
- catch {
205
- return null;
206
- }
207
- }
208
178
  getRoutingInstructions() {
209
179
  const instructionsPath = resolve(dirname(fileURLToPath(import.meta.url)), "..", "..", "..", "configs", "antigravity", "GEMINI.md");
210
180
  try {
@@ -13,7 +13,7 @@
13
13
  * - Config: ~/.claude/settings.json
14
14
  * - Session dir: ~/.claude/context-mode/sessions/
15
15
  */
16
- import type { HookAdapter, HookParadigm, PlatformCapabilities, DiagnosticResult, PreToolUseEvent, PostToolUseEvent, PreCompactEvent, SessionStartEvent, PreToolUseResponse, PostToolUseResponse, PreCompactResponse, SessionStartResponse, HookRegistration, RoutingInstructionsConfig } from "../types.js";
16
+ import type { HookAdapter, HookParadigm, PlatformCapabilities, DiagnosticResult, PreToolUseEvent, PostToolUseEvent, PreCompactEvent, SessionStartEvent, PreToolUseResponse, PostToolUseResponse, PreCompactResponse, SessionStartResponse, HookRegistration } from "../types.js";
17
17
  export declare class ClaudeCodeAdapter implements HookAdapter {
18
18
  readonly name = "Claude Code";
19
19
  readonly paradigm: HookParadigm;
@@ -44,8 +44,6 @@ export declare class ClaudeCodeAdapter implements HookAdapter {
44
44
  backupSettings(): string | null;
45
45
  setHookPermissions(pluginRoot: string): string[];
46
46
  updatePluginRegistry(pluginRoot: string, version: string): void;
47
- getRoutingInstructionsConfig(): RoutingInstructionsConfig;
48
- writeRoutingInstructions(projectDir: string, pluginRoot: string): string | null;
49
47
  /**
50
48
  * Extract session ID from Claude Code hook input.
51
49
  * Priority: transcript_path UUID > session_id field > CLAUDE_SESSION_ID env > ppid fallback.
@@ -17,7 +17,7 @@ import { createHash } from "node:crypto";
17
17
  import { readFileSync, writeFileSync, mkdirSync, copyFileSync, accessSync, existsSync, readdirSync, chmodSync, constants, } from "node:fs";
18
18
  import { resolve, join } from "node:path";
19
19
  import { homedir } from "node:os";
20
- import { HOOK_TYPES, HOOK_SCRIPTS, PRE_TOOL_USE_MATCHER_PATTERN, isContextModeHook, isAnyContextModeHook, extractHookScriptPath, buildHookCommand, } from "./hooks.js";
20
+ import { HOOK_TYPES, HOOK_SCRIPTS, REQUIRED_HOOKS, PRE_TOOL_USE_MATCHER_PATTERN, isContextModeHook, isAnyContextModeHook, extractHookScriptPath, buildHookCommand, } from "./hooks.js";
21
21
  // ─────────────────────────────────────────────────────────
22
22
  // Adapter implementation
23
23
  // ─────────────────────────────────────────────────────────
@@ -414,6 +414,20 @@ export class ClaudeCodeAdapter {
414
414
  changes.push(`Removed ${removed} stale ${hookType} hook(s)`);
415
415
  }
416
416
  }
417
+ // If plugin hooks.json already covers all required hooks, skip settings.json
418
+ // registration entirely (Issue #198). Plugin installs don't need settings.json
419
+ // entries — hooks.json with ${CLAUDE_PLUGIN_ROOT} is the source of truth.
420
+ const pluginHooks = this.readPluginHooks(pluginRoot);
421
+ if (pluginHooks) {
422
+ const allCovered = REQUIRED_HOOKS.every((ht) => this.checkHookType(undefined, pluginHooks, ht));
423
+ if (allCovered) {
424
+ // Still write cleaned settings (stale removal) but don't add new entries
425
+ settings.hooks = hooks;
426
+ this.writeSettings(settings);
427
+ changes.push("Skipped settings.json registration — plugin hooks.json is sufficient");
428
+ return changes;
429
+ }
430
+ }
417
431
  // Register fresh hooks for required hook types
418
432
  const hookTypes = [
419
433
  HOOK_TYPES.PRE_TOOL_USE,
@@ -518,39 +532,6 @@ export class ClaudeCodeAdapter {
518
532
  /* best effort */
519
533
  }
520
534
  }
521
- // ── Routing Instructions (soft enforcement) ────────────
522
- getRoutingInstructionsConfig() {
523
- return {
524
- fileName: "CLAUDE.md",
525
- globalPath: resolve(homedir(), ".claude", "CLAUDE.md"),
526
- projectRelativePath: "CLAUDE.md",
527
- };
528
- }
529
- writeRoutingInstructions(projectDir, pluginRoot) {
530
- const config = this.getRoutingInstructionsConfig();
531
- const targetPath = resolve(projectDir, config.projectRelativePath);
532
- const sourcePath = resolve(pluginRoot, "configs", "claude-code", config.fileName);
533
- try {
534
- const content = readFileSync(sourcePath, "utf-8");
535
- // Check if file exists and already has context-mode instructions
536
- try {
537
- const existing = readFileSync(targetPath, "utf-8");
538
- if (existing.includes("context-mode"))
539
- return null;
540
- // Append to existing file
541
- writeFileSync(targetPath, existing.trimEnd() + "\n\n" + content, "utf-8");
542
- return targetPath;
543
- }
544
- catch {
545
- // File doesn't exist — create it
546
- writeFileSync(targetPath, content, "utf-8");
547
- return targetPath;
548
- }
549
- }
550
- catch {
551
- return null;
552
- }
553
- }
554
535
  // ── Internal helpers ───────────────────────────────────
555
536
  /**
556
537
  * Extract session ID from Claude Code hook input.
@@ -11,7 +11,7 @@
11
11
  * - All capabilities are false — MCP is the only integration path
12
12
  * - Session dir: ~/.codex/context-mode/sessions/
13
13
  */
14
- import type { HookAdapter, HookParadigm, PlatformCapabilities, DiagnosticResult, PreToolUseEvent, PostToolUseEvent, PreCompactEvent, SessionStartEvent, PreToolUseResponse, PostToolUseResponse, PreCompactResponse, SessionStartResponse, HookRegistration, RoutingInstructionsConfig } from "../types.js";
14
+ import type { HookAdapter, HookParadigm, PlatformCapabilities, DiagnosticResult, PreToolUseEvent, PostToolUseEvent, PreCompactEvent, SessionStartEvent, PreToolUseResponse, PostToolUseResponse, PreCompactResponse, SessionStartResponse, HookRegistration } from "../types.js";
15
15
  export declare class CodexAdapter implements HookAdapter {
16
16
  readonly name = "Codex CLI";
17
17
  readonly paradigm: HookParadigm;
@@ -38,7 +38,5 @@ export declare class CodexAdapter implements HookAdapter {
38
38
  backupSettings(): string | null;
39
39
  setHookPermissions(_pluginRoot: string): string[];
40
40
  updatePluginRegistry(_pluginRoot: string, _version: string): void;
41
- getRoutingInstructionsConfig(): RoutingInstructionsConfig;
42
- writeRoutingInstructions(projectDir: string, pluginRoot: string): string | null;
43
41
  getRoutingInstructions(): string;
44
42
  }
@@ -12,7 +12,7 @@
12
12
  * - Session dir: ~/.codex/context-mode/sessions/
13
13
  */
14
14
  import { createHash } from "node:crypto";
15
- import { readFileSync, writeFileSync, mkdirSync, copyFileSync, accessSync, constants, } from "node:fs";
15
+ import { readFileSync, mkdirSync, copyFileSync, accessSync, constants, } from "node:fs";
16
16
  import { resolve, join, dirname } from "node:path";
17
17
  import { fileURLToPath } from "node:url";
18
18
  import { homedir } from "node:os";
@@ -180,36 +180,6 @@ export class CodexAdapter {
180
180
  updatePluginRegistry(_pluginRoot, _version) {
181
181
  // Codex CLI has no plugin registry
182
182
  }
183
- // ── Routing Instructions (soft enforcement) ────────────
184
- getRoutingInstructionsConfig() {
185
- return {
186
- fileName: "AGENTS.md",
187
- globalPath: resolve(homedir(), ".codex", "AGENTS.md"),
188
- projectRelativePath: "AGENTS.md",
189
- };
190
- }
191
- writeRoutingInstructions(projectDir, pluginRoot) {
192
- const config = this.getRoutingInstructionsConfig();
193
- const targetPath = resolve(projectDir, config.projectRelativePath);
194
- const sourcePath = resolve(pluginRoot, "configs", "codex", config.fileName);
195
- try {
196
- const content = readFileSync(sourcePath, "utf-8");
197
- try {
198
- const existing = readFileSync(targetPath, "utf-8");
199
- if (existing.includes("context-mode"))
200
- return null;
201
- writeFileSync(targetPath, existing.trimEnd() + "\n\n" + content, "utf-8");
202
- return targetPath;
203
- }
204
- catch {
205
- writeFileSync(targetPath, content, "utf-8");
206
- return targetPath;
207
- }
208
- }
209
- catch {
210
- return null;
211
- }
212
- }
213
183
  getRoutingInstructions() {
214
184
  const instructionsPath = resolve(dirname(fileURLToPath(import.meta.url)), "..", "..", "..", "configs", "codex", "AGENTS.md");
215
185
  try {
@@ -4,7 +4,7 @@
4
4
  * Native Cursor hooks use lower-camel hook names and flat command entries in
5
5
  * `.cursor/hooks.json` / `~/.cursor/hooks.json`.
6
6
  */
7
- import type { HookAdapter, HookParadigm, PlatformCapabilities, DiagnosticResult, PreToolUseEvent, PostToolUseEvent, SessionStartEvent, PreToolUseResponse, PostToolUseResponse, SessionStartResponse, HookRegistration, RoutingInstructionsConfig } from "../types.js";
7
+ import type { HookAdapter, HookParadigm, PlatformCapabilities, DiagnosticResult, PreToolUseEvent, PostToolUseEvent, SessionStartEvent, PreToolUseResponse, PostToolUseResponse, SessionStartResponse, HookRegistration } from "../types.js";
8
8
  export declare class CursorAdapter implements HookAdapter {
9
9
  readonly name = "Cursor";
10
10
  readonly paradigm: HookParadigm;
@@ -29,8 +29,6 @@ export declare class CursorAdapter implements HookAdapter {
29
29
  backupSettings(): string | null;
30
30
  setHookPermissions(pluginRoot: string): string[];
31
31
  updatePluginRegistry(_pluginRoot: string, _version: string): void;
32
- getRoutingInstructionsConfig(): RoutingInstructionsConfig;
33
- writeRoutingInstructions(_projectDir: string, _pluginRoot: string): string | null;
34
32
  private getCandidateHookConfigPaths;
35
33
  private getProjectDir;
36
34
  private extractSessionId;
@@ -338,17 +338,6 @@ export class CursorAdapter {
338
338
  updatePluginRegistry(_pluginRoot, _version) {
339
339
  // Cursor manages extensions and native hooks internally.
340
340
  }
341
- getRoutingInstructionsConfig() {
342
- return {
343
- fileName: "AGENTS.md",
344
- globalPath: "",
345
- projectRelativePath: "AGENTS.md",
346
- };
347
- }
348
- writeRoutingInstructions(_projectDir, _pluginRoot) {
349
- // Native Cursor hook support ships independently from any instruction-file story.
350
- return null;
351
- }
352
341
  getCandidateHookConfigPaths() {
353
342
  const paths = [this.getSettingsPath(), join(homedir(), ".cursor", "hooks.json")];
354
343
  if (process.platform === "darwin") {
@@ -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 type { HookAdapter, HookParadigm, PlatformCapabilities, DiagnosticResult, PreToolUseEvent, PostToolUseEvent, PreCompactEvent, SessionStartEvent, PreToolUseResponse, PostToolUseResponse, PreCompactResponse, SessionStartResponse, HookRegistration, RoutingInstructionsConfig } from "../types.js";
21
+ import type { HookAdapter, HookParadigm, PlatformCapabilities, DiagnosticResult, PreToolUseEvent, PostToolUseEvent, PreCompactEvent, SessionStartEvent, PreToolUseResponse, PostToolUseResponse, PreCompactResponse, SessionStartResponse, HookRegistration } from "../types.js";
22
22
  export declare class GeminiCLIAdapter implements HookAdapter {
23
23
  readonly name = "Gemini CLI";
24
24
  readonly paradigm: HookParadigm;
@@ -45,8 +45,6 @@ export declare class GeminiCLIAdapter implements HookAdapter {
45
45
  backupSettings(): string | null;
46
46
  setHookPermissions(pluginRoot: string): string[];
47
47
  updatePluginRegistry(pluginRoot: string, version: string): void;
48
- getRoutingInstructionsConfig(): RoutingInstructionsConfig;
49
- writeRoutingInstructions(projectDir: string, pluginRoot: string): string | null;
50
48
  /** Get the project directory from environment variables. */
51
49
  private getProjectDir;
52
50
  /**
@@ -421,36 +421,6 @@ export class GeminiCLIAdapter {
421
421
  /* best effort */
422
422
  }
423
423
  }
424
- // ── Routing Instructions (soft enforcement) ────────────
425
- getRoutingInstructionsConfig() {
426
- return {
427
- fileName: "GEMINI.md",
428
- globalPath: resolve(homedir(), ".gemini", "GEMINI.md"),
429
- projectRelativePath: "GEMINI.md",
430
- };
431
- }
432
- writeRoutingInstructions(projectDir, pluginRoot) {
433
- const config = this.getRoutingInstructionsConfig();
434
- const targetPath = resolve(projectDir, config.projectRelativePath);
435
- const sourcePath = resolve(pluginRoot, "configs", "gemini-cli", config.fileName);
436
- try {
437
- const content = readFileSync(sourcePath, "utf-8");
438
- try {
439
- const existing = readFileSync(targetPath, "utf-8");
440
- if (existing.includes("context-mode"))
441
- return null;
442
- writeFileSync(targetPath, existing.trimEnd() + "\n\n" + content, "utf-8");
443
- return targetPath;
444
- }
445
- catch {
446
- writeFileSync(targetPath, content, "utf-8");
447
- return targetPath;
448
- }
449
- }
450
- catch {
451
- return null;
452
- }
453
- }
454
424
  // ── Internal helpers ───────────────────────────────────
455
425
  /** Get the project directory from environment variables. */
456
426
  getProjectDir() {
@@ -17,7 +17,7 @@
17
17
  * - clientInfo.name: https://github.com/kirodotdev/Kiro/issues/5205 ("Kiro CLI")
18
18
  * - CLI hooks: https://kiro.dev/docs/cli/custom-agents/configuration-reference#hooks-field
19
19
  */
20
- import type { HookAdapter, HookParadigm, PlatformCapabilities, DiagnosticResult, PreToolUseEvent, PostToolUseEvent, PreCompactEvent, SessionStartEvent, PreToolUseResponse, PostToolUseResponse, PreCompactResponse, SessionStartResponse, HookRegistration, RoutingInstructionsConfig } from "../types.js";
20
+ import type { HookAdapter, HookParadigm, PlatformCapabilities, DiagnosticResult, PreToolUseEvent, PostToolUseEvent, PreCompactEvent, SessionStartEvent, PreToolUseResponse, PostToolUseResponse, PreCompactResponse, SessionStartResponse, HookRegistration } from "../types.js";
21
21
  export declare class KiroAdapter implements HookAdapter {
22
22
  readonly name = "Kiro";
23
23
  readonly paradigm: HookParadigm;
@@ -44,7 +44,5 @@ export declare class KiroAdapter implements HookAdapter {
44
44
  backupSettings(): string | null;
45
45
  setHookPermissions(_pluginRoot: string): string[];
46
46
  updatePluginRegistry(_pluginRoot: string, _version: string): void;
47
- getRoutingInstructionsConfig(): RoutingInstructionsConfig;
48
- writeRoutingInstructions(projectDir: string, pluginRoot: string): string | null;
49
47
  getRoutingInstructions(): string;
50
48
  }
@@ -283,36 +283,6 @@ export class KiroAdapter {
283
283
  updatePluginRegistry(_pluginRoot, _version) {
284
284
  // Kiro plugin registry is managed via mcp.json
285
285
  }
286
- // ── Routing Instructions (soft enforcement) ────────────
287
- getRoutingInstructionsConfig() {
288
- return {
289
- fileName: "KIRO.md",
290
- globalPath: resolve(homedir(), ".kiro", "KIRO.md"),
291
- projectRelativePath: "KIRO.md",
292
- };
293
- }
294
- writeRoutingInstructions(projectDir, pluginRoot) {
295
- const config = this.getRoutingInstructionsConfig();
296
- const targetPath = resolve(projectDir, config.projectRelativePath);
297
- const sourcePath = resolve(pluginRoot, "configs", "kiro", config.fileName);
298
- try {
299
- const content = readFileSync(sourcePath, "utf-8");
300
- try {
301
- const existing = readFileSync(targetPath, "utf-8");
302
- if (existing.includes("context-mode"))
303
- return null;
304
- writeFileSync(targetPath, existing.trimEnd() + "\n\n" + content, "utf-8");
305
- return targetPath;
306
- }
307
- catch {
308
- writeFileSync(targetPath, content, "utf-8");
309
- return targetPath;
310
- }
311
- }
312
- catch {
313
- return null;
314
- }
315
- }
316
286
  getRoutingInstructions() {
317
287
  const instructionsPath = resolve(dirname(fileURLToPath(import.meta.url)), "..", "..", "..", "configs", "kiro", "KIRO.md");
318
288
  try {
@@ -15,7 +15,7 @@
15
15
  * - Config: openclaw.json plugins.entries, ~/.openclaw/extensions/
16
16
  * - Session dir: ~/.openclaw/context-mode/sessions/
17
17
  */
18
- import type { HookAdapter, HookParadigm, PlatformCapabilities, DiagnosticResult, PreToolUseEvent, PostToolUseEvent, PreCompactEvent, SessionStartEvent, PreToolUseResponse, PostToolUseResponse, PreCompactResponse, SessionStartResponse, HookRegistration, RoutingInstructionsConfig } from "../types.js";
18
+ import type { HookAdapter, HookParadigm, PlatformCapabilities, DiagnosticResult, PreToolUseEvent, PostToolUseEvent, PreCompactEvent, SessionStartEvent, PreToolUseResponse, PostToolUseResponse, PreCompactResponse, SessionStartResponse, HookRegistration } from "../types.js";
19
19
  export declare class OpenClawAdapter implements HookAdapter {
20
20
  readonly name = "OpenClaw";
21
21
  readonly paradigm: HookParadigm;
@@ -42,8 +42,6 @@ export declare class OpenClawAdapter implements HookAdapter {
42
42
  backupSettings(): string | null;
43
43
  setHookPermissions(_pluginRoot: string): string[];
44
44
  updatePluginRegistry(_pluginRoot: string, _version: string): void;
45
- getRoutingInstructionsConfig(): RoutingInstructionsConfig;
46
- writeRoutingInstructions(projectDir: string, pluginRoot: string): string | null;
47
45
  /**
48
46
  * Extract session ID from OpenClaw hook input.
49
47
  */
@@ -409,44 +409,6 @@ export class OpenClawAdapter {
409
409
  updatePluginRegistry(_pluginRoot, _version) {
410
410
  // OpenClaw manages plugins through npm/openclaw.json — no separate registry
411
411
  }
412
- // ── Routing Instructions (soft enforcement) ────────────
413
- getRoutingInstructionsConfig() {
414
- return {
415
- fileName: "AGENTS.md",
416
- globalPath: resolve(homedir(), ".openclaw", "AGENTS.md"),
417
- projectRelativePath: "AGENTS.md",
418
- };
419
- }
420
- writeRoutingInstructions(projectDir, pluginRoot) {
421
- const config = this.getRoutingInstructionsConfig();
422
- const targetPath = resolve(projectDir, config.projectRelativePath);
423
- const sourcePath = resolve(pluginRoot, "configs", "openclaw", config.fileName);
424
- try {
425
- let content;
426
- try {
427
- content = readFileSync(sourcePath, "utf-8");
428
- }
429
- catch {
430
- // Fall back to opencode config if openclaw-specific doesn't exist yet
431
- const fallbackPath = resolve(pluginRoot, "configs", "opencode", config.fileName);
432
- content = readFileSync(fallbackPath, "utf-8");
433
- }
434
- try {
435
- const existing = readFileSync(targetPath, "utf-8");
436
- if (existing.includes("context-mode"))
437
- return null;
438
- writeFileSync(targetPath, existing.trimEnd() + "\n\n" + content, "utf-8");
439
- return targetPath;
440
- }
441
- catch {
442
- writeFileSync(targetPath, content, "utf-8");
443
- return targetPath;
444
- }
445
- }
446
- catch {
447
- return null;
448
- }
449
- }
450
412
  // ── Internal helpers ───────────────────────────────────
451
413
  /**
452
414
  * Extract session ID from OpenClaw hook input.
@@ -15,7 +15,7 @@
15
15
  * - Config: opencode.json plugin array, .opencode/plugins/*.ts
16
16
  * - Session dir: ~/.config/opencode/context-mode/sessions/
17
17
  */
18
- import type { HookAdapter, HookParadigm, PlatformCapabilities, DiagnosticResult, PreToolUseEvent, PostToolUseEvent, PreCompactEvent, SessionStartEvent, PreToolUseResponse, PostToolUseResponse, PreCompactResponse, SessionStartResponse, HookRegistration, RoutingInstructionsConfig, PlatformId } from "../types.js";
18
+ import type { HookAdapter, HookParadigm, PlatformCapabilities, DiagnosticResult, PreToolUseEvent, PostToolUseEvent, PreCompactEvent, SessionStartEvent, PreToolUseResponse, PostToolUseResponse, PreCompactResponse, SessionStartResponse, HookRegistration, PlatformId } from "../types.js";
19
19
  export type AdapterPlatformType = Extract<PlatformId, "opencode" | "kilo">;
20
20
  export declare class OpenCodeAdapter implements HookAdapter {
21
21
  get name(): string;
@@ -47,8 +47,6 @@ export declare class OpenCodeAdapter implements HookAdapter {
47
47
  backupSettings(): string | null;
48
48
  setHookPermissions(_pluginRoot: string): string[];
49
49
  updatePluginRegistry(_pluginRoot: string, _version: string): void;
50
- getRoutingInstructionsConfig(): RoutingInstructionsConfig;
51
- writeRoutingInstructions(projectDir: string, pluginRoot: string): string | null;
52
50
  /**
53
51
  * Extract session ID from OpenCode hook input.
54
52
  * OpenCode uses camelCase sessionID.