@mxalbert/context-mode 2.0.0
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 +33 -0
- package/.claude-plugin/plugin.json +31 -0
- package/.codex-plugin/hooks.json +65 -0
- package/.codex-plugin/mcp.json +13 -0
- package/.codex-plugin/plugin.json +31 -0
- package/.openclaw-plugin/index.ts +12 -0
- package/.openclaw-plugin/openclaw.plugin.json +38 -0
- package/.openclaw-plugin/package.json +28 -0
- package/LICENSE +94 -0
- package/README.md +1619 -0
- package/bin/statusline.mjs +378 -0
- package/build/adapters/antigravity/index.d.ts +51 -0
- package/build/adapters/antigravity/index.js +169 -0
- package/build/adapters/antigravity-cli/index.d.ts +51 -0
- package/build/adapters/antigravity-cli/index.js +342 -0
- package/build/adapters/base.d.ts +92 -0
- package/build/adapters/base.js +135 -0
- package/build/adapters/claude-code/config.d.ts +8 -0
- package/build/adapters/claude-code/config.js +8 -0
- package/build/adapters/claude-code/hooks.d.ts +106 -0
- package/build/adapters/claude-code/hooks.js +183 -0
- package/build/adapters/claude-code/index.d.ts +80 -0
- package/build/adapters/claude-code/index.js +569 -0
- package/build/adapters/claude-code-base.d.ts +49 -0
- package/build/adapters/claude-code-base.js +113 -0
- package/build/adapters/client-map.d.ts +10 -0
- package/build/adapters/client-map.js +42 -0
- package/build/adapters/codex/config.d.ts +8 -0
- package/build/adapters/codex/config.js +8 -0
- package/build/adapters/codex/hooks.d.ts +55 -0
- package/build/adapters/codex/hooks.js +64 -0
- package/build/adapters/codex/index.d.ts +87 -0
- package/build/adapters/codex/index.js +995 -0
- package/build/adapters/codex/paths.d.ts +1 -0
- package/build/adapters/codex/paths.js +12 -0
- package/build/adapters/codex/usage.d.ts +107 -0
- package/build/adapters/codex/usage.js +227 -0
- package/build/adapters/copilot-base.d.ts +94 -0
- package/build/adapters/copilot-base.js +297 -0
- package/build/adapters/copilot-cli/hooks.d.ts +33 -0
- package/build/adapters/copilot-cli/hooks.js +64 -0
- package/build/adapters/copilot-cli/index.d.ts +48 -0
- package/build/adapters/copilot-cli/index.js +341 -0
- package/build/adapters/cursor/config.d.ts +4 -0
- package/build/adapters/cursor/config.js +4 -0
- package/build/adapters/cursor/hooks.d.ts +55 -0
- package/build/adapters/cursor/hooks.js +82 -0
- package/build/adapters/cursor/index.d.ts +64 -0
- package/build/adapters/cursor/index.js +517 -0
- package/build/adapters/detect.d.ts +136 -0
- package/build/adapters/detect.js +623 -0
- package/build/adapters/gemini-cli/config.d.ts +8 -0
- package/build/adapters/gemini-cli/config.js +8 -0
- package/build/adapters/gemini-cli/hooks.d.ts +83 -0
- package/build/adapters/gemini-cli/hooks.js +115 -0
- package/build/adapters/gemini-cli/index.d.ts +80 -0
- package/build/adapters/gemini-cli/index.js +483 -0
- package/build/adapters/jetbrains-copilot/config.d.ts +8 -0
- package/build/adapters/jetbrains-copilot/config.js +8 -0
- package/build/adapters/jetbrains-copilot/hooks.d.ts +59 -0
- package/build/adapters/jetbrains-copilot/hooks.js +87 -0
- package/build/adapters/jetbrains-copilot/index.d.ts +31 -0
- package/build/adapters/jetbrains-copilot/index.js +131 -0
- package/build/adapters/kimi/config.d.ts +8 -0
- package/build/adapters/kimi/config.js +8 -0
- package/build/adapters/kimi/hooks.d.ts +28 -0
- package/build/adapters/kimi/hooks.js +34 -0
- package/build/adapters/kimi/index.d.ts +66 -0
- package/build/adapters/kimi/index.js +537 -0
- package/build/adapters/kimi/paths.d.ts +21 -0
- package/build/adapters/kimi/paths.js +52 -0
- package/build/adapters/kimi/usage.d.ts +82 -0
- package/build/adapters/kimi/usage.js +217 -0
- package/build/adapters/kiro/hooks.d.ts +61 -0
- package/build/adapters/kiro/hooks.js +94 -0
- package/build/adapters/kiro/index.d.ts +61 -0
- package/build/adapters/kiro/index.js +301 -0
- package/build/adapters/omp/index.d.ts +65 -0
- package/build/adapters/omp/index.js +182 -0
- package/build/adapters/omp/plugin.d.ts +81 -0
- package/build/adapters/omp/plugin.js +331 -0
- package/build/adapters/omp/usage.d.ts +49 -0
- package/build/adapters/omp/usage.js +110 -0
- package/build/adapters/openclaw/config.d.ts +8 -0
- package/build/adapters/openclaw/config.js +8 -0
- package/build/adapters/openclaw/hooks.d.ts +50 -0
- package/build/adapters/openclaw/hooks.js +61 -0
- package/build/adapters/openclaw/index.d.ts +74 -0
- package/build/adapters/openclaw/index.js +439 -0
- package/build/adapters/openclaw/mcp-tools.d.ts +54 -0
- package/build/adapters/openclaw/mcp-tools.js +207 -0
- package/build/adapters/openclaw/plugin.d.ts +141 -0
- package/build/adapters/openclaw/plugin.js +818 -0
- package/build/adapters/openclaw/session-db.d.ts +55 -0
- package/build/adapters/openclaw/session-db.js +88 -0
- package/build/adapters/openclaw/usage.d.ts +34 -0
- package/build/adapters/openclaw/usage.js +52 -0
- package/build/adapters/openclaw/workspace-router.d.ts +29 -0
- package/build/adapters/openclaw/workspace-router.js +64 -0
- package/build/adapters/opencode/config.d.ts +8 -0
- package/build/adapters/opencode/config.js +8 -0
- package/build/adapters/opencode/hooks.d.ts +38 -0
- package/build/adapters/opencode/hooks.js +50 -0
- package/build/adapters/opencode/index.d.ts +144 -0
- package/build/adapters/opencode/index.js +638 -0
- package/build/adapters/opencode/plugin.d.ts +249 -0
- package/build/adapters/opencode/plugin.js +1536 -0
- package/build/adapters/opencode/v2.d.ts +117 -0
- package/build/adapters/opencode/v2.js +224 -0
- package/build/adapters/opencode/zod3tov4.d.ts +1 -0
- package/build/adapters/opencode/zod3tov4.js +132 -0
- package/build/adapters/pi/extension.d.ts +81 -0
- package/build/adapters/pi/extension.js +861 -0
- package/build/adapters/pi/index.d.ts +57 -0
- package/build/adapters/pi/index.js +173 -0
- package/build/adapters/pi/mcp-bridge.d.ts +268 -0
- package/build/adapters/pi/mcp-bridge.js +894 -0
- package/build/adapters/qwen-code/hooks.d.ts +26 -0
- package/build/adapters/qwen-code/hooks.js +29 -0
- package/build/adapters/qwen-code/index.d.ts +40 -0
- package/build/adapters/qwen-code/index.js +361 -0
- package/build/adapters/qwen-code/usage.d.ts +90 -0
- package/build/adapters/qwen-code/usage.js +222 -0
- package/build/adapters/types.d.ts +360 -0
- package/build/adapters/types.js +118 -0
- package/build/adapters/vscode-copilot/config.d.ts +8 -0
- package/build/adapters/vscode-copilot/config.js +8 -0
- package/build/adapters/vscode-copilot/hooks.d.ts +71 -0
- package/build/adapters/vscode-copilot/hooks.js +98 -0
- package/build/adapters/vscode-copilot/index.d.ts +32 -0
- package/build/adapters/vscode-copilot/index.js +222 -0
- package/build/adapters/zed/index.d.ts +40 -0
- package/build/adapters/zed/index.js +163 -0
- package/build/cli.d.ts +34 -0
- package/build/cli.js +1828 -0
- package/build/db-base.d.ts +250 -0
- package/build/db-base.js +756 -0
- package/build/executor.d.ts +72 -0
- package/build/executor.js +678 -0
- package/build/exit-classify.d.ts +19 -0
- package/build/exit-classify.js +12 -0
- package/build/fetch/blocks.d.ts +145 -0
- package/build/fetch/blocks.js +244 -0
- package/build/fetch/extract.d.ts +68 -0
- package/build/fetch/extract.js +123 -0
- package/build/fetch/page-store.d.ts +66 -0
- package/build/fetch/page-store.js +174 -0
- package/build/fetch-cache.d.ts +13 -0
- package/build/fetch-cache.js +15 -0
- package/build/lifecycle.d.ts +124 -0
- package/build/lifecycle.js +278 -0
- package/build/package-identity.d.ts +26 -0
- package/build/package-identity.js +28 -0
- package/build/runPool.d.ts +36 -0
- package/build/runPool.js +51 -0
- package/build/runtime.d.ts +71 -0
- package/build/runtime.js +659 -0
- package/build/search/auto-memory.d.ts +47 -0
- package/build/search/auto-memory.js +170 -0
- package/build/search/ctx-search-schema.d.ts +90 -0
- package/build/search/ctx-search-schema.js +135 -0
- package/build/search/flood-guard.d.ts +57 -0
- package/build/search/flood-guard.js +80 -0
- package/build/search/unified.d.ts +56 -0
- package/build/search/unified.js +104 -0
- package/build/security.d.ts +206 -0
- package/build/security.js +780 -0
- package/build/server.d.ts +240 -0
- package/build/server.js +5034 -0
- package/build/session/analytics.d.ts +773 -0
- package/build/session/analytics.js +2420 -0
- package/build/session/db.d.ts +468 -0
- package/build/session/db.js +1330 -0
- package/build/session/error-classifier.d.ts +87 -0
- package/build/session/error-classifier.js +303 -0
- package/build/session/event-emit.d.ts +48 -0
- package/build/session/event-emit.js +101 -0
- package/build/session/extract.d.ts +333 -0
- package/build/session/extract.js +2688 -0
- package/build/session/model-prices.json +429 -0
- package/build/session/persist-tool-calls.d.ts +54 -0
- package/build/session/persist-tool-calls.js +105 -0
- package/build/session/pricing.d.ts +64 -0
- package/build/session/pricing.js +151 -0
- package/build/session/project-attribution.d.ts +73 -0
- package/build/session/project-attribution.js +245 -0
- package/build/session/purge.d.ts +138 -0
- package/build/session/purge.js +240 -0
- package/build/session/retrieval-marker.d.ts +39 -0
- package/build/session/retrieval-marker.js +65 -0
- package/build/session/snapshot.d.ts +46 -0
- package/build/session/snapshot.js +532 -0
- package/build/store-directory.d.ts +56 -0
- package/build/store-directory.js +254 -0
- package/build/store.d.ts +147 -0
- package/build/store.js +1714 -0
- package/build/truncate.d.ts +57 -0
- package/build/truncate.js +142 -0
- package/build/types.d.ts +117 -0
- package/build/types.js +20 -0
- package/build/util/claude-config.d.ts +32 -0
- package/build/util/claude-config.js +84 -0
- package/build/util/hook-config.d.ts +27 -0
- package/build/util/hook-config.js +76 -0
- package/build/util/jsonc.d.ts +14 -0
- package/build/util/jsonc.js +104 -0
- package/build/util/plugin-cache-integrity.d.ts +51 -0
- package/build/util/plugin-cache-integrity.js +146 -0
- package/build/util/project-dir.d.ts +149 -0
- package/build/util/project-dir.js +340 -0
- package/build/util/sibling-mcp.d.ts +79 -0
- package/build/util/sibling-mcp.js +181 -0
- package/cli.bundle.mjs +1495 -0
- package/configs/antigravity/GEMINI.md +68 -0
- package/configs/antigravity/mcp_config.json +7 -0
- package/configs/antigravity-cli/hooks/hooks.json +37 -0
- package/configs/antigravity-cli/hooks.json +37 -0
- package/configs/antigravity-cli/mcp_config.json +10 -0
- package/configs/antigravity-cli/plugin.json +14 -0
- package/configs/antigravity-cli/rules/context-mode.md +77 -0
- package/configs/antigravity-cli/skills/context-mode/SKILL.md +77 -0
- package/configs/claude-code/CLAUDE.md +91 -0
- package/configs/codex/AGENTS.md +99 -0
- package/configs/codex/config.toml +8 -0
- package/configs/codex/hooks.json +47 -0
- package/configs/copilot-cli/.github/plugin/plugin.json +23 -0
- package/configs/copilot-cli/.mcp.json +12 -0
- package/configs/copilot-cli/README.md +47 -0
- package/configs/copilot-cli/hooks.json +41 -0
- package/configs/copilot-cli/skills/context-mode/SKILL.md +38 -0
- package/configs/cursor/context-mode.mdc +76 -0
- package/configs/cursor/hooks.json +21 -0
- package/configs/cursor/mcp.json +7 -0
- package/configs/gemini-cli/GEMINI.md +88 -0
- package/configs/gemini-cli/mcp.json +7 -0
- package/configs/gemini-cli/settings.json +60 -0
- package/configs/jetbrains-copilot/copilot-instructions.md +80 -0
- package/configs/jetbrains-copilot/hooks.json +16 -0
- package/configs/jetbrains-copilot/mcp.json +7 -0
- package/configs/kilo/AGENTS.md +84 -0
- package/configs/kilo/kilo.json +6 -0
- package/configs/kimi/hooks.json +54 -0
- package/configs/kiro/KIRO.md +84 -0
- package/configs/kiro/agent.json +18 -0
- package/configs/kiro/mcp.json +7 -0
- package/configs/omp/SYSTEM.md +85 -0
- package/configs/omp/mcp.json +7 -0
- package/configs/openclaw/AGENTS.md +87 -0
- package/configs/openclaw/openclaw.json +13 -0
- package/configs/opencode/AGENTS.md +84 -0
- package/configs/opencode/opencode.json +6 -0
- package/configs/pi/AGENTS.md +3 -0
- package/configs/qwen-code/QWEN.md +91 -0
- package/configs/vscode-copilot/copilot-instructions.md +80 -0
- package/configs/vscode-copilot/hooks.json +16 -0
- package/configs/vscode-copilot/mcp.json +7 -0
- package/configs/zed/AGENTS.md +68 -0
- package/hooks/antigravity-cli/payload.mjs +98 -0
- package/hooks/antigravity-cli/posttooluse.mjs +138 -0
- package/hooks/antigravity-cli/pretooluse.mjs +78 -0
- package/hooks/antigravity-cli/stop.mjs +58 -0
- package/hooks/auto-injection.mjs +102 -0
- package/hooks/cache-heal-utils.mjs +379 -0
- package/hooks/codex/platform.mjs +1 -0
- package/hooks/codex/posttooluse.mjs +66 -0
- package/hooks/codex/precompact.mjs +70 -0
- package/hooks/codex/pretooluse.mjs +42 -0
- package/hooks/codex/sessionstart.mjs +121 -0
- package/hooks/codex/stop.mjs +138 -0
- package/hooks/codex/userpromptsubmit.mjs +75 -0
- package/hooks/copilot-cli/posttooluse.mjs +79 -0
- package/hooks/copilot-cli/precompact.mjs +66 -0
- package/hooks/copilot-cli/pretooluse.mjs +41 -0
- package/hooks/copilot-cli/sessionstart.mjs +121 -0
- package/hooks/copilot-cli/stop.mjs +59 -0
- package/hooks/copilot-cli/userpromptsubmit.mjs +77 -0
- package/hooks/core/codex-caps.mjs +112 -0
- package/hooks/core/formatters.mjs +356 -0
- package/hooks/core/mcp-ready.mjs +109 -0
- package/hooks/core/platform-detect.mjs +49 -0
- package/hooks/core/routing.mjs +1050 -0
- package/hooks/core/stdin.mjs +90 -0
- package/hooks/core/tool-naming.mjs +57 -0
- package/hooks/cursor/afteragentresponse.mjs +74 -0
- package/hooks/cursor/hooks.json +31 -0
- package/hooks/cursor/posttooluse.mjs +72 -0
- package/hooks/cursor/pretooluse.mjs +26 -0
- package/hooks/cursor/sessionstart.mjs +97 -0
- package/hooks/cursor/stop.mjs +48 -0
- package/hooks/ensure-deps.mjs +254 -0
- package/hooks/formatters/claude-code.mjs +113 -0
- package/hooks/formatters/cursor.mjs +37 -0
- package/hooks/formatters/gemini-cli.mjs +55 -0
- package/hooks/formatters/vscode-copilot.mjs +55 -0
- package/hooks/gemini-cli/aftermodel.mjs +70 -0
- package/hooks/gemini-cli/aftertool.mjs +61 -0
- package/hooks/gemini-cli/beforeagent.mjs +99 -0
- package/hooks/gemini-cli/beforetool.mjs +27 -0
- package/hooks/gemini-cli/precompress.mjs +55 -0
- package/hooks/gemini-cli/sessionstart.mjs +137 -0
- package/hooks/heal-partial-install.mjs +712 -0
- package/hooks/hooks.json +143 -0
- package/hooks/jetbrains-copilot/posttooluse.mjs +61 -0
- package/hooks/jetbrains-copilot/precompact.mjs +55 -0
- package/hooks/jetbrains-copilot/pretooluse.mjs +27 -0
- package/hooks/jetbrains-copilot/sessionstart.mjs +124 -0
- package/hooks/kimi/platform.mjs +1 -0
- package/hooks/kimi/posttooluse.mjs +72 -0
- package/hooks/kimi/precompact.mjs +80 -0
- package/hooks/kimi/pretooluse.mjs +42 -0
- package/hooks/kimi/sessionend.mjs +61 -0
- package/hooks/kimi/sessionstart.mjs +113 -0
- package/hooks/kimi/stop.mjs +132 -0
- package/hooks/kimi/userpromptsubmit.mjs +90 -0
- package/hooks/kiro/agentspawn.mjs +97 -0
- package/hooks/kiro/posttooluse.mjs +51 -0
- package/hooks/kiro/pretooluse.mjs +64 -0
- package/hooks/kiro/userpromptsubmit.mjs +88 -0
- package/hooks/normalize-hooks.mjs +323 -0
- package/hooks/platform-bridge.mjs +340 -0
- package/hooks/posttooluse.mjs +225 -0
- package/hooks/precompact.mjs +100 -0
- package/hooks/pretooluse.mjs +227 -0
- package/hooks/qwen-code/platform.mjs +1 -0
- package/hooks/qwen-code/stop.mjs +168 -0
- package/hooks/routing-block.mjs +105 -0
- package/hooks/run-hook.mjs +95 -0
- package/hooks/security.bundle.mjs +2 -0
- package/hooks/session-attribution.bundle.mjs +1 -0
- package/hooks/session-db.bundle.mjs +145 -0
- package/hooks/session-directive.mjs +520 -0
- package/hooks/session-extract.bundle.mjs +3 -0
- package/hooks/session-helpers.mjs +428 -0
- package/hooks/session-loaders.mjs +448 -0
- package/hooks/session-snapshot.bundle.mjs +32 -0
- package/hooks/sessionstart.mjs +464 -0
- package/hooks/stop.mjs +82 -0
- package/hooks/suppress-stderr.mjs +25 -0
- package/hooks/userpromptsubmit.mjs +108 -0
- package/hooks/vscode-copilot/posttooluse.mjs +61 -0
- package/hooks/vscode-copilot/precompact.mjs +55 -0
- package/hooks/vscode-copilot/pretooluse.mjs +27 -0
- package/hooks/vscode-copilot/sessionstart.mjs +129 -0
- package/openclaw.plugin.json +38 -0
- package/package.json +132 -0
- package/scripts/heal-better-sqlite3.mjs +430 -0
- package/scripts/heal-installed-plugins.mjs +635 -0
- package/scripts/plugin-cache-integrity.mjs +248 -0
- package/scripts/postinstall.mjs +397 -0
- package/server.bundle.mjs +1421 -0
- package/server.js +5 -0
- package/skills/.ignore +7 -0
- package/skills/context-mode/SKILL.md +300 -0
- package/skills/context-mode/references/anti-patterns.md +283 -0
- package/skills/context-mode/references/patterns-javascript.md +298 -0
- package/skills/context-mode/references/patterns-python.md +304 -0
- package/skills/context-mode/references/patterns-shell.md +277 -0
- package/skills/ctx-doctor/SKILL.md +22 -0
- package/skills/ctx-index/SKILL.md +46 -0
- package/skills/ctx-insight/SKILL.md +24 -0
- package/skills/ctx-purge/SKILL.md +49 -0
- package/skills/ctx-search/SKILL.md +35 -0
- package/skills/ctx-stats/SKILL.md +26 -0
- package/skills/ctx-upgrade/SKILL.md +31 -0
- package/start.mjs +616 -0
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* adapters/openclaw — OpenClaw platform adapter.
|
|
3
|
+
*
|
|
4
|
+
* Implements HookAdapter for OpenClaw's TypeScript plugin paradigm.
|
|
5
|
+
*
|
|
6
|
+
* OpenClaw hook specifics:
|
|
7
|
+
* - I/O: TS plugin functions via api.registerHook() and api.on()
|
|
8
|
+
* - Hook events: tool_call:before, tool_call:after, command:new
|
|
9
|
+
* - Lifecycle: before_prompt_build (routing instruction injection)
|
|
10
|
+
* - Context engine: api.registerContextEngine() with ownsCompaction
|
|
11
|
+
* - Arg modification: mutate event.params in tool_call:before
|
|
12
|
+
* - Blocking: return { block: true, blockReason } from tool_call:before
|
|
13
|
+
* - Session ID: event context (no specific env var)
|
|
14
|
+
* - Project dir: process.cwd()
|
|
15
|
+
* - Config: openclaw.json plugins.entries, ~/.openclaw/extensions/
|
|
16
|
+
* - Session dir: ~/.openclaw/context-mode/sessions/
|
|
17
|
+
*/
|
|
18
|
+
import { BaseAdapter } from "../base.js";
|
|
19
|
+
import type { HookAdapter, HookParadigm, PlatformCapabilities, DiagnosticResult, PreToolUseEvent, PostToolUseEvent, PreCompactEvent, SessionStartEvent, PreToolUseResponse, PostToolUseResponse, PreCompactResponse, SessionStartResponse, HookRegistration } from "../types.js";
|
|
20
|
+
export declare class OpenClawAdapter extends BaseAdapter implements HookAdapter {
|
|
21
|
+
constructor();
|
|
22
|
+
readonly name = "OpenClaw";
|
|
23
|
+
readonly paradigm: HookParadigm;
|
|
24
|
+
readonly capabilities: PlatformCapabilities;
|
|
25
|
+
parsePreToolUseInput(raw: unknown): PreToolUseEvent;
|
|
26
|
+
parsePostToolUseInput(raw: unknown): PostToolUseEvent;
|
|
27
|
+
parsePreCompactInput(raw: unknown): PreCompactEvent;
|
|
28
|
+
parseSessionStartInput(raw: unknown): SessionStartEvent;
|
|
29
|
+
formatPreToolUseResponse(response: PreToolUseResponse): unknown;
|
|
30
|
+
formatPostToolUseResponse(response: PostToolUseResponse): unknown;
|
|
31
|
+
formatPreCompactResponse(response: PreCompactResponse): unknown;
|
|
32
|
+
formatSessionStartResponse(response: SessionStartResponse): unknown;
|
|
33
|
+
getSettingsPath(): string;
|
|
34
|
+
/**
|
|
35
|
+
* OpenClaw stores everything in the project root — no separate config
|
|
36
|
+
* dir. Returned as the absolute project directory itself per the
|
|
37
|
+
* HookAdapter.getConfigDir contract (always-absolute).
|
|
38
|
+
*/
|
|
39
|
+
getConfigDir(projectDir?: string): string;
|
|
40
|
+
getInstructionFiles(): string[];
|
|
41
|
+
/**
|
|
42
|
+
* Absolute <projectRoot>/memory directory.
|
|
43
|
+
*
|
|
44
|
+
* OpenClaw's `getConfigDir(projectDir)` already returns the project root,
|
|
45
|
+
* so the memory dir is naturally project-scoped per the OpenClaw
|
|
46
|
+
* convention. The `projectDir` parameter is honored for explicit
|
|
47
|
+
* resolution; without it, falls back to the implicit `process.cwd()`
|
|
48
|
+
* inside `getConfigDir`. Either way, two projects never share a path
|
|
49
|
+
* — no hash suffix needed (issue #663).
|
|
50
|
+
*/
|
|
51
|
+
getMemoryDir(projectDir?: string): string;
|
|
52
|
+
generateHookConfig(_pluginRoot: string): HookRegistration;
|
|
53
|
+
readSettings(): Record<string, unknown> | null;
|
|
54
|
+
writeSettings(settings: Record<string, unknown>): void;
|
|
55
|
+
validateHooks(_pluginRoot: string): DiagnosticResult[];
|
|
56
|
+
checkPluginRegistration(): DiagnosticResult;
|
|
57
|
+
getInstalledVersion(): string;
|
|
58
|
+
configureAllHooks(_pluginRoot: string): string[];
|
|
59
|
+
backupSettings(): string | null;
|
|
60
|
+
setHookPermissions(_pluginRoot: string): string[];
|
|
61
|
+
updatePluginRegistry(_pluginRoot: string, _version: string): void;
|
|
62
|
+
/**
|
|
63
|
+
* Resolve the project directory for an OpenClaw hook input.
|
|
64
|
+
* Priority: input.cwd > OPENCLAW_PROJECT_DIR env > process.cwd().
|
|
65
|
+
* Mirrors the cursor / opencode pattern so downstream hooks always
|
|
66
|
+
* receive a defined projectDir even under worktrees or when the
|
|
67
|
+
* platform omits cwd from the wire payload.
|
|
68
|
+
*/
|
|
69
|
+
private getProjectDir;
|
|
70
|
+
/**
|
|
71
|
+
* Extract session ID from OpenClaw hook input.
|
|
72
|
+
*/
|
|
73
|
+
private extractSessionId;
|
|
74
|
+
}
|
|
@@ -0,0 +1,439 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* adapters/openclaw — OpenClaw platform adapter.
|
|
3
|
+
*
|
|
4
|
+
* Implements HookAdapter for OpenClaw's TypeScript plugin paradigm.
|
|
5
|
+
*
|
|
6
|
+
* OpenClaw hook specifics:
|
|
7
|
+
* - I/O: TS plugin functions via api.registerHook() and api.on()
|
|
8
|
+
* - Hook events: tool_call:before, tool_call:after, command:new
|
|
9
|
+
* - Lifecycle: before_prompt_build (routing instruction injection)
|
|
10
|
+
* - Context engine: api.registerContextEngine() with ownsCompaction
|
|
11
|
+
* - Arg modification: mutate event.params in tool_call:before
|
|
12
|
+
* - Blocking: return { block: true, blockReason } from tool_call:before
|
|
13
|
+
* - Session ID: event context (no specific env var)
|
|
14
|
+
* - Project dir: process.cwd()
|
|
15
|
+
* - Config: openclaw.json plugins.entries, ~/.openclaw/extensions/
|
|
16
|
+
* - Session dir: ~/.openclaw/context-mode/sessions/
|
|
17
|
+
*/
|
|
18
|
+
import { readFileSync, writeFileSync, copyFileSync, accessSync, constants, } from "node:fs";
|
|
19
|
+
import { resolve, join } from "node:path";
|
|
20
|
+
import { homedir } from "node:os";
|
|
21
|
+
import { BaseAdapter } from "../base.js";
|
|
22
|
+
// ─────────────────────────────────────────────────────────
|
|
23
|
+
// Hook constants (re-exported from hooks.ts)
|
|
24
|
+
// ─────────────────────────────────────────────────────────
|
|
25
|
+
import { HOOK_EVENTS as OPENCLAW_HOOK_EVENTS } from "./hooks.js";
|
|
26
|
+
// ─────────────────────────────────────────────────────────
|
|
27
|
+
// Adapter implementation
|
|
28
|
+
// ─────────────────────────────────────────────────────────
|
|
29
|
+
export class OpenClawAdapter extends BaseAdapter {
|
|
30
|
+
constructor() {
|
|
31
|
+
super([".openclaw"]);
|
|
32
|
+
}
|
|
33
|
+
name = "OpenClaw";
|
|
34
|
+
paradigm = "ts-plugin";
|
|
35
|
+
capabilities = {
|
|
36
|
+
preToolUse: true,
|
|
37
|
+
postToolUse: true,
|
|
38
|
+
preCompact: true, // via registerContextEngine with ownsCompaction
|
|
39
|
+
sessionStart: true, // via command:new hook
|
|
40
|
+
canModifyArgs: true,
|
|
41
|
+
canModifyOutput: false,
|
|
42
|
+
canInjectSessionContext: true, // via before_prompt_build lifecycle hook
|
|
43
|
+
};
|
|
44
|
+
// ── Input parsing ──────────────────────────────────────
|
|
45
|
+
parsePreToolUseInput(raw) {
|
|
46
|
+
const input = raw;
|
|
47
|
+
return {
|
|
48
|
+
toolName: input.toolName ?? input.tool_name ?? "",
|
|
49
|
+
toolInput: input.params ?? input.tool_input ?? {},
|
|
50
|
+
sessionId: this.extractSessionId(input),
|
|
51
|
+
projectDir: this.getProjectDir(input),
|
|
52
|
+
raw,
|
|
53
|
+
};
|
|
54
|
+
}
|
|
55
|
+
parsePostToolUseInput(raw) {
|
|
56
|
+
const input = raw;
|
|
57
|
+
return {
|
|
58
|
+
toolName: input.toolName ?? input.tool_name ?? "",
|
|
59
|
+
toolInput: input.params ?? input.tool_input ?? {},
|
|
60
|
+
toolOutput: input.output ?? input.tool_output,
|
|
61
|
+
isError: input.isError ?? input.is_error,
|
|
62
|
+
sessionId: this.extractSessionId(input),
|
|
63
|
+
projectDir: this.getProjectDir(input),
|
|
64
|
+
raw,
|
|
65
|
+
};
|
|
66
|
+
}
|
|
67
|
+
parsePreCompactInput(raw) {
|
|
68
|
+
const input = raw;
|
|
69
|
+
return {
|
|
70
|
+
sessionId: this.extractSessionId(input),
|
|
71
|
+
projectDir: this.getProjectDir(input),
|
|
72
|
+
raw,
|
|
73
|
+
};
|
|
74
|
+
}
|
|
75
|
+
parseSessionStartInput(raw) {
|
|
76
|
+
const input = raw;
|
|
77
|
+
const rawSource = input.source ?? "startup";
|
|
78
|
+
let source;
|
|
79
|
+
switch (rawSource) {
|
|
80
|
+
case "compact":
|
|
81
|
+
source = "compact";
|
|
82
|
+
break;
|
|
83
|
+
case "resume":
|
|
84
|
+
source = "resume";
|
|
85
|
+
break;
|
|
86
|
+
case "clear":
|
|
87
|
+
source = "clear";
|
|
88
|
+
break;
|
|
89
|
+
default:
|
|
90
|
+
source = "startup";
|
|
91
|
+
}
|
|
92
|
+
return {
|
|
93
|
+
sessionId: this.extractSessionId(input),
|
|
94
|
+
source,
|
|
95
|
+
projectDir: this.getProjectDir(input),
|
|
96
|
+
raw,
|
|
97
|
+
};
|
|
98
|
+
}
|
|
99
|
+
// ── Response formatting ────────────────────────────────
|
|
100
|
+
formatPreToolUseResponse(response) {
|
|
101
|
+
if (response.decision === "deny") {
|
|
102
|
+
// OpenClaw plugin paradigm: return { block, blockReason } to block
|
|
103
|
+
return {
|
|
104
|
+
block: true,
|
|
105
|
+
blockReason: response.reason ?? "Blocked by context-mode hook",
|
|
106
|
+
};
|
|
107
|
+
}
|
|
108
|
+
if (response.decision === "modify" && response.updatedInput) {
|
|
109
|
+
// OpenClaw: mutate params in the event object
|
|
110
|
+
return { params: response.updatedInput };
|
|
111
|
+
}
|
|
112
|
+
if (response.decision === "ask") {
|
|
113
|
+
// OpenClaw: block for safety when user confirmation needed
|
|
114
|
+
return {
|
|
115
|
+
block: true,
|
|
116
|
+
blockReason: response.reason ?? "Action requires user confirmation (security policy)",
|
|
117
|
+
};
|
|
118
|
+
}
|
|
119
|
+
if (response.decision === "context" && response.additionalContext) {
|
|
120
|
+
// OpenClaw supports context injection via before_prompt_build,
|
|
121
|
+
// but not inline in tool_call:before. Passthrough.
|
|
122
|
+
return undefined;
|
|
123
|
+
}
|
|
124
|
+
// "allow" — passthrough
|
|
125
|
+
return undefined;
|
|
126
|
+
}
|
|
127
|
+
formatPostToolUseResponse(response) {
|
|
128
|
+
const result = {};
|
|
129
|
+
if (response.additionalContext) {
|
|
130
|
+
result.additionalContext = response.additionalContext;
|
|
131
|
+
}
|
|
132
|
+
return Object.keys(result).length > 0 ? result : undefined;
|
|
133
|
+
}
|
|
134
|
+
formatPreCompactResponse(response) {
|
|
135
|
+
// Context engine compact() returns { ok, compacted } — context is managed internally
|
|
136
|
+
return response.context ?? "";
|
|
137
|
+
}
|
|
138
|
+
formatSessionStartResponse(response) {
|
|
139
|
+
return response.context ?? "";
|
|
140
|
+
}
|
|
141
|
+
// ── Configuration ──────────────────────────────────────
|
|
142
|
+
getSettingsPath() {
|
|
143
|
+
// OpenClaw uses openclaw.json in the project root or ~/.openclaw/openclaw.json
|
|
144
|
+
return resolve("openclaw.json");
|
|
145
|
+
}
|
|
146
|
+
/**
|
|
147
|
+
* OpenClaw stores everything in the project root — no separate config
|
|
148
|
+
* dir. Returned as the absolute project directory itself per the
|
|
149
|
+
* HookAdapter.getConfigDir contract (always-absolute).
|
|
150
|
+
*/
|
|
151
|
+
getConfigDir(projectDir) {
|
|
152
|
+
return resolve(projectDir ?? process.cwd());
|
|
153
|
+
}
|
|
154
|
+
getInstructionFiles() {
|
|
155
|
+
return ["AGENTS.md"];
|
|
156
|
+
}
|
|
157
|
+
/**
|
|
158
|
+
* Absolute <projectRoot>/memory directory.
|
|
159
|
+
*
|
|
160
|
+
* OpenClaw's `getConfigDir(projectDir)` already returns the project root,
|
|
161
|
+
* so the memory dir is naturally project-scoped per the OpenClaw
|
|
162
|
+
* convention. The `projectDir` parameter is honored for explicit
|
|
163
|
+
* resolution; without it, falls back to the implicit `process.cwd()`
|
|
164
|
+
* inside `getConfigDir`. Either way, two projects never share a path
|
|
165
|
+
* — no hash suffix needed (issue #663).
|
|
166
|
+
*/
|
|
167
|
+
getMemoryDir(projectDir) {
|
|
168
|
+
return join(this.getConfigDir(projectDir), "memory");
|
|
169
|
+
}
|
|
170
|
+
generateHookConfig(_pluginRoot) {
|
|
171
|
+
// OpenClaw uses TS plugin paradigm — hooks are registered via
|
|
172
|
+
// api.registerHook() in the plugin entry point, not via config files.
|
|
173
|
+
// Return the hook name mapping for documentation purposes.
|
|
174
|
+
return {
|
|
175
|
+
[OPENCLAW_HOOK_EVENTS.TOOL_CALL_BEFORE]: [
|
|
176
|
+
{
|
|
177
|
+
matcher: "",
|
|
178
|
+
hooks: [
|
|
179
|
+
{
|
|
180
|
+
type: "plugin",
|
|
181
|
+
command: "context-mode",
|
|
182
|
+
},
|
|
183
|
+
],
|
|
184
|
+
},
|
|
185
|
+
],
|
|
186
|
+
[OPENCLAW_HOOK_EVENTS.TOOL_CALL_AFTER]: [
|
|
187
|
+
{
|
|
188
|
+
matcher: "",
|
|
189
|
+
hooks: [
|
|
190
|
+
{
|
|
191
|
+
type: "plugin",
|
|
192
|
+
command: "context-mode",
|
|
193
|
+
},
|
|
194
|
+
],
|
|
195
|
+
},
|
|
196
|
+
],
|
|
197
|
+
[OPENCLAW_HOOK_EVENTS.COMMAND_NEW]: [
|
|
198
|
+
{
|
|
199
|
+
matcher: "",
|
|
200
|
+
hooks: [
|
|
201
|
+
{
|
|
202
|
+
type: "plugin",
|
|
203
|
+
command: "context-mode",
|
|
204
|
+
},
|
|
205
|
+
],
|
|
206
|
+
},
|
|
207
|
+
],
|
|
208
|
+
};
|
|
209
|
+
}
|
|
210
|
+
readSettings() {
|
|
211
|
+
// Try project-local paths first, then global config
|
|
212
|
+
const paths = [
|
|
213
|
+
resolve("openclaw.json"),
|
|
214
|
+
resolve(".openclaw", "openclaw.json"),
|
|
215
|
+
join(homedir(), ".openclaw", "openclaw.json"),
|
|
216
|
+
];
|
|
217
|
+
for (const configPath of paths) {
|
|
218
|
+
try {
|
|
219
|
+
const raw = readFileSync(configPath, "utf-8");
|
|
220
|
+
return JSON.parse(raw);
|
|
221
|
+
}
|
|
222
|
+
catch {
|
|
223
|
+
continue;
|
|
224
|
+
}
|
|
225
|
+
}
|
|
226
|
+
return null;
|
|
227
|
+
}
|
|
228
|
+
writeSettings(settings) {
|
|
229
|
+
// Write to openclaw.json in current directory
|
|
230
|
+
const configPath = resolve("openclaw.json");
|
|
231
|
+
writeFileSync(configPath, JSON.stringify(settings, null, 2) + "\n", "utf-8");
|
|
232
|
+
}
|
|
233
|
+
// ── Diagnostics (doctor) ─────────────────────────────────
|
|
234
|
+
validateHooks(_pluginRoot) {
|
|
235
|
+
const results = [];
|
|
236
|
+
const settings = this.readSettings();
|
|
237
|
+
if (!settings) {
|
|
238
|
+
results.push({
|
|
239
|
+
check: "Plugin configuration",
|
|
240
|
+
status: "fail",
|
|
241
|
+
message: "Could not read openclaw.json",
|
|
242
|
+
fix: "context-mode upgrade",
|
|
243
|
+
});
|
|
244
|
+
return results;
|
|
245
|
+
}
|
|
246
|
+
// Check for context-mode in plugins.entries
|
|
247
|
+
const plugins = settings.plugins;
|
|
248
|
+
const entries = plugins?.entries;
|
|
249
|
+
if (entries) {
|
|
250
|
+
const hasPlugin = Object.keys(entries).some((k) => k.includes("context-mode"));
|
|
251
|
+
results.push({
|
|
252
|
+
check: "Plugin registration",
|
|
253
|
+
status: hasPlugin ? "pass" : "fail",
|
|
254
|
+
message: hasPlugin
|
|
255
|
+
? "context-mode found in plugins.entries"
|
|
256
|
+
: "context-mode not found in plugins.entries",
|
|
257
|
+
fix: hasPlugin
|
|
258
|
+
? undefined
|
|
259
|
+
: "context-mode upgrade",
|
|
260
|
+
});
|
|
261
|
+
// Check if enabled
|
|
262
|
+
if (hasPlugin) {
|
|
263
|
+
const entry = entries["context-mode"];
|
|
264
|
+
const isEnabled = entry?.enabled !== false;
|
|
265
|
+
results.push({
|
|
266
|
+
check: "Plugin enabled",
|
|
267
|
+
status: isEnabled ? "pass" : "warn",
|
|
268
|
+
message: isEnabled
|
|
269
|
+
? "context-mode plugin is enabled"
|
|
270
|
+
: "context-mode plugin is disabled",
|
|
271
|
+
});
|
|
272
|
+
}
|
|
273
|
+
}
|
|
274
|
+
else {
|
|
275
|
+
results.push({
|
|
276
|
+
check: "Plugin registration",
|
|
277
|
+
status: "fail",
|
|
278
|
+
message: "No plugins.entries found in openclaw.json",
|
|
279
|
+
fix: "context-mode upgrade",
|
|
280
|
+
});
|
|
281
|
+
}
|
|
282
|
+
// Check context engine slot
|
|
283
|
+
const slots = plugins?.slots;
|
|
284
|
+
if (slots?.contextEngine === "context-mode") {
|
|
285
|
+
results.push({
|
|
286
|
+
check: "Context engine",
|
|
287
|
+
status: "pass",
|
|
288
|
+
message: "context-mode registered as context engine (owns compaction)",
|
|
289
|
+
});
|
|
290
|
+
}
|
|
291
|
+
else {
|
|
292
|
+
results.push({
|
|
293
|
+
check: "Context engine",
|
|
294
|
+
status: "warn",
|
|
295
|
+
message: "context-mode not set as context engine — compaction will use default engine",
|
|
296
|
+
});
|
|
297
|
+
}
|
|
298
|
+
return results;
|
|
299
|
+
}
|
|
300
|
+
checkPluginRegistration() {
|
|
301
|
+
const settings = this.readSettings();
|
|
302
|
+
if (!settings) {
|
|
303
|
+
return {
|
|
304
|
+
check: "Plugin registration",
|
|
305
|
+
status: "warn",
|
|
306
|
+
message: "Could not read openclaw.json",
|
|
307
|
+
};
|
|
308
|
+
}
|
|
309
|
+
const plugins = settings.plugins;
|
|
310
|
+
const entries = plugins?.entries;
|
|
311
|
+
if (entries) {
|
|
312
|
+
const hasPlugin = Object.keys(entries).some((k) => k.includes("context-mode"));
|
|
313
|
+
if (hasPlugin) {
|
|
314
|
+
return {
|
|
315
|
+
check: "Plugin registration",
|
|
316
|
+
status: "pass",
|
|
317
|
+
message: "context-mode found in plugins.entries",
|
|
318
|
+
};
|
|
319
|
+
}
|
|
320
|
+
}
|
|
321
|
+
return {
|
|
322
|
+
check: "Plugin registration",
|
|
323
|
+
status: "fail",
|
|
324
|
+
message: "context-mode not found in openclaw.json plugins.entries",
|
|
325
|
+
fix: "context-mode upgrade",
|
|
326
|
+
};
|
|
327
|
+
}
|
|
328
|
+
getInstalledVersion() {
|
|
329
|
+
// Check ~/.openclaw/extensions/context-mode/ for the plugin
|
|
330
|
+
try {
|
|
331
|
+
const pkgPath = resolve(homedir(), ".openclaw", "extensions", "context-mode", "package.json");
|
|
332
|
+
const pkg = JSON.parse(readFileSync(pkgPath, "utf-8"));
|
|
333
|
+
if (typeof pkg.version === "string")
|
|
334
|
+
return pkg.version;
|
|
335
|
+
}
|
|
336
|
+
catch {
|
|
337
|
+
/* not found */
|
|
338
|
+
}
|
|
339
|
+
// Also check node_modules
|
|
340
|
+
try {
|
|
341
|
+
const pkgPath = resolve("node_modules", "context-mode", "package.json");
|
|
342
|
+
const pkg = JSON.parse(readFileSync(pkgPath, "utf-8"));
|
|
343
|
+
if (typeof pkg.version === "string")
|
|
344
|
+
return pkg.version;
|
|
345
|
+
}
|
|
346
|
+
catch {
|
|
347
|
+
/* not found */
|
|
348
|
+
}
|
|
349
|
+
return "not installed";
|
|
350
|
+
}
|
|
351
|
+
// ── Upgrade ────────────────────────────────────────────
|
|
352
|
+
configureAllHooks(_pluginRoot) {
|
|
353
|
+
const settings = this.readSettings() ?? {};
|
|
354
|
+
const changes = [];
|
|
355
|
+
// Ensure plugins.entries exists
|
|
356
|
+
if (!settings.plugins) {
|
|
357
|
+
settings.plugins = {};
|
|
358
|
+
}
|
|
359
|
+
const plugins = settings.plugins;
|
|
360
|
+
if (!plugins.entries) {
|
|
361
|
+
plugins.entries = {};
|
|
362
|
+
}
|
|
363
|
+
const entries = plugins.entries;
|
|
364
|
+
// Add context-mode to plugins.entries
|
|
365
|
+
if (!entries["context-mode"]) {
|
|
366
|
+
entries["context-mode"] = { enabled: true };
|
|
367
|
+
changes.push("Added context-mode to plugins.entries");
|
|
368
|
+
}
|
|
369
|
+
else {
|
|
370
|
+
const entry = entries["context-mode"];
|
|
371
|
+
if (entry.enabled === false) {
|
|
372
|
+
entry.enabled = true;
|
|
373
|
+
changes.push("Enabled context-mode plugin");
|
|
374
|
+
}
|
|
375
|
+
else {
|
|
376
|
+
changes.push("context-mode already configured in plugins.entries");
|
|
377
|
+
}
|
|
378
|
+
}
|
|
379
|
+
// Optionally set context engine slot
|
|
380
|
+
if (!plugins.slots) {
|
|
381
|
+
plugins.slots = {};
|
|
382
|
+
}
|
|
383
|
+
const slots = plugins.slots;
|
|
384
|
+
if (!slots.contextEngine) {
|
|
385
|
+
slots.contextEngine = "context-mode";
|
|
386
|
+
changes.push("Set context-mode as context engine (owns compaction)");
|
|
387
|
+
}
|
|
388
|
+
else if (slots.contextEngine !== "context-mode") {
|
|
389
|
+
changes.push(`Context engine already set to "${slots.contextEngine}" — not overwriting`);
|
|
390
|
+
}
|
|
391
|
+
this.writeSettings(settings);
|
|
392
|
+
return changes;
|
|
393
|
+
}
|
|
394
|
+
backupSettings() {
|
|
395
|
+
const paths = [
|
|
396
|
+
resolve("openclaw.json"),
|
|
397
|
+
resolve(".openclaw", "openclaw.json"),
|
|
398
|
+
join(homedir(), ".openclaw", "openclaw.json"),
|
|
399
|
+
];
|
|
400
|
+
for (const configPath of paths) {
|
|
401
|
+
try {
|
|
402
|
+
accessSync(configPath, constants.R_OK);
|
|
403
|
+
const backupPath = configPath + ".bak";
|
|
404
|
+
copyFileSync(configPath, backupPath);
|
|
405
|
+
return backupPath;
|
|
406
|
+
}
|
|
407
|
+
catch {
|
|
408
|
+
continue;
|
|
409
|
+
}
|
|
410
|
+
}
|
|
411
|
+
return null;
|
|
412
|
+
}
|
|
413
|
+
setHookPermissions(_pluginRoot) {
|
|
414
|
+
// OpenClaw uses TS plugin paradigm — no shell scripts to chmod
|
|
415
|
+
return [];
|
|
416
|
+
}
|
|
417
|
+
updatePluginRegistry(_pluginRoot, _version) {
|
|
418
|
+
// OpenClaw manages plugins through npm/openclaw.json — no separate registry
|
|
419
|
+
}
|
|
420
|
+
// ── Internal helpers ───────────────────────────────────
|
|
421
|
+
/**
|
|
422
|
+
* Resolve the project directory for an OpenClaw hook input.
|
|
423
|
+
* Priority: input.cwd > OPENCLAW_PROJECT_DIR env > process.cwd().
|
|
424
|
+
* Mirrors the cursor / opencode pattern so downstream hooks always
|
|
425
|
+
* receive a defined projectDir even under worktrees or when the
|
|
426
|
+
* platform omits cwd from the wire payload.
|
|
427
|
+
*/
|
|
428
|
+
getProjectDir(input) {
|
|
429
|
+
return input.cwd ?? process.env.OPENCLAW_PROJECT_DIR ?? process.cwd();
|
|
430
|
+
}
|
|
431
|
+
/**
|
|
432
|
+
* Extract session ID from OpenClaw hook input.
|
|
433
|
+
*/
|
|
434
|
+
extractSessionId(input) {
|
|
435
|
+
if (input.sessionId)
|
|
436
|
+
return input.sessionId;
|
|
437
|
+
return `pid-${process.ppid}`;
|
|
438
|
+
}
|
|
439
|
+
}
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* OpenClaw MCP tool registry.
|
|
3
|
+
*
|
|
4
|
+
* Catalogs the 11 ctx_* tools that OpenClaw plugin must register via
|
|
5
|
+
* api.registerTool(...) so the routing block (which nudges agents toward
|
|
6
|
+
* ctx_execute, ctx_search, etc.) actually has tools to call. Without this,
|
|
7
|
+
* Phase 7 audit (v1.0.107-adapter-openclaw.json) flagged severity=CRITICAL —
|
|
8
|
+
* routing-block premise is broken when the named tools don't exist.
|
|
9
|
+
*
|
|
10
|
+
* Pattern mirrors the swarmvault MCP plugin
|
|
11
|
+
* (refs/plugin-examples/openclaw/swarmvault/packages/engine/src/mcp.ts:46-51):
|
|
12
|
+
* server.registerTool(name, { description, inputSchema }, handler)
|
|
13
|
+
*
|
|
14
|
+
* OpenClaw signature is slightly different — see building-plugins.md:116
|
|
15
|
+
* api.registerTool({ name, description, parameters: TypeBox, execute(id, params) })
|
|
16
|
+
*
|
|
17
|
+
* Tool handlers are intentionally thin shims that delegate to the bundled CLI
|
|
18
|
+
* (cli.bundle.mjs) — same fall-through pattern already used by ctx-doctor and
|
|
19
|
+
* ctx-upgrade slash commands. This keeps the plugin's blast radius minimal:
|
|
20
|
+
* we don't re-export the entire MCP server stack inside OpenClaw's process.
|
|
21
|
+
*
|
|
22
|
+
* The 11 tools mirror src/server.ts registerTool calls (lines 897, 1226, 1371,
|
|
23
|
+
* 1497, 2034, 2256, 2440, 2501, 2592, 2712, 2808).
|
|
24
|
+
*/
|
|
25
|
+
/** Minimal JSON-schema-like parameter spec accepted by OpenClaw registerTool. */
|
|
26
|
+
export interface OpenClawToolParameters {
|
|
27
|
+
type: "object";
|
|
28
|
+
properties: Record<string, {
|
|
29
|
+
type: string;
|
|
30
|
+
description?: string;
|
|
31
|
+
}>;
|
|
32
|
+
required?: string[];
|
|
33
|
+
additionalProperties?: boolean;
|
|
34
|
+
}
|
|
35
|
+
/** Tool definition shape returned to OpenClaw via api.registerTool. */
|
|
36
|
+
export interface OpenClawToolDef {
|
|
37
|
+
name: string;
|
|
38
|
+
description: string;
|
|
39
|
+
parameters: OpenClawToolParameters;
|
|
40
|
+
execute: (id: string, params: Record<string, unknown>) => Promise<{
|
|
41
|
+
content: Array<{
|
|
42
|
+
type: "text";
|
|
43
|
+
text: string;
|
|
44
|
+
}>;
|
|
45
|
+
}>;
|
|
46
|
+
}
|
|
47
|
+
/**
|
|
48
|
+
* The 11 ctx_* tool definitions registered into OpenClaw via api.registerTool.
|
|
49
|
+
* Names + descriptions mirror src/server.ts registerTool blocks 1:1 so prompts
|
|
50
|
+
* referencing them (routing block, AGENTS.md) resolve to real callable tools.
|
|
51
|
+
*/
|
|
52
|
+
export declare const OPENCLAW_TOOL_DEFS: readonly OpenClawToolDef[];
|
|
53
|
+
/** Stable list of tool names — used by tests and manifest validation. */
|
|
54
|
+
export declare const OPENCLAW_TOOL_NAMES: readonly string[];
|