@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.
Files changed (365) hide show
  1. package/.claude-plugin/marketplace.json +33 -0
  2. package/.claude-plugin/plugin.json +31 -0
  3. package/.codex-plugin/hooks.json +65 -0
  4. package/.codex-plugin/mcp.json +13 -0
  5. package/.codex-plugin/plugin.json +31 -0
  6. package/.openclaw-plugin/index.ts +12 -0
  7. package/.openclaw-plugin/openclaw.plugin.json +38 -0
  8. package/.openclaw-plugin/package.json +28 -0
  9. package/LICENSE +94 -0
  10. package/README.md +1619 -0
  11. package/bin/statusline.mjs +378 -0
  12. package/build/adapters/antigravity/index.d.ts +51 -0
  13. package/build/adapters/antigravity/index.js +169 -0
  14. package/build/adapters/antigravity-cli/index.d.ts +51 -0
  15. package/build/adapters/antigravity-cli/index.js +342 -0
  16. package/build/adapters/base.d.ts +92 -0
  17. package/build/adapters/base.js +135 -0
  18. package/build/adapters/claude-code/config.d.ts +8 -0
  19. package/build/adapters/claude-code/config.js +8 -0
  20. package/build/adapters/claude-code/hooks.d.ts +106 -0
  21. package/build/adapters/claude-code/hooks.js +183 -0
  22. package/build/adapters/claude-code/index.d.ts +80 -0
  23. package/build/adapters/claude-code/index.js +569 -0
  24. package/build/adapters/claude-code-base.d.ts +49 -0
  25. package/build/adapters/claude-code-base.js +113 -0
  26. package/build/adapters/client-map.d.ts +10 -0
  27. package/build/adapters/client-map.js +42 -0
  28. package/build/adapters/codex/config.d.ts +8 -0
  29. package/build/adapters/codex/config.js +8 -0
  30. package/build/adapters/codex/hooks.d.ts +55 -0
  31. package/build/adapters/codex/hooks.js +64 -0
  32. package/build/adapters/codex/index.d.ts +87 -0
  33. package/build/adapters/codex/index.js +995 -0
  34. package/build/adapters/codex/paths.d.ts +1 -0
  35. package/build/adapters/codex/paths.js +12 -0
  36. package/build/adapters/codex/usage.d.ts +107 -0
  37. package/build/adapters/codex/usage.js +227 -0
  38. package/build/adapters/copilot-base.d.ts +94 -0
  39. package/build/adapters/copilot-base.js +297 -0
  40. package/build/adapters/copilot-cli/hooks.d.ts +33 -0
  41. package/build/adapters/copilot-cli/hooks.js +64 -0
  42. package/build/adapters/copilot-cli/index.d.ts +48 -0
  43. package/build/adapters/copilot-cli/index.js +341 -0
  44. package/build/adapters/cursor/config.d.ts +4 -0
  45. package/build/adapters/cursor/config.js +4 -0
  46. package/build/adapters/cursor/hooks.d.ts +55 -0
  47. package/build/adapters/cursor/hooks.js +82 -0
  48. package/build/adapters/cursor/index.d.ts +64 -0
  49. package/build/adapters/cursor/index.js +517 -0
  50. package/build/adapters/detect.d.ts +136 -0
  51. package/build/adapters/detect.js +623 -0
  52. package/build/adapters/gemini-cli/config.d.ts +8 -0
  53. package/build/adapters/gemini-cli/config.js +8 -0
  54. package/build/adapters/gemini-cli/hooks.d.ts +83 -0
  55. package/build/adapters/gemini-cli/hooks.js +115 -0
  56. package/build/adapters/gemini-cli/index.d.ts +80 -0
  57. package/build/adapters/gemini-cli/index.js +483 -0
  58. package/build/adapters/jetbrains-copilot/config.d.ts +8 -0
  59. package/build/adapters/jetbrains-copilot/config.js +8 -0
  60. package/build/adapters/jetbrains-copilot/hooks.d.ts +59 -0
  61. package/build/adapters/jetbrains-copilot/hooks.js +87 -0
  62. package/build/adapters/jetbrains-copilot/index.d.ts +31 -0
  63. package/build/adapters/jetbrains-copilot/index.js +131 -0
  64. package/build/adapters/kimi/config.d.ts +8 -0
  65. package/build/adapters/kimi/config.js +8 -0
  66. package/build/adapters/kimi/hooks.d.ts +28 -0
  67. package/build/adapters/kimi/hooks.js +34 -0
  68. package/build/adapters/kimi/index.d.ts +66 -0
  69. package/build/adapters/kimi/index.js +537 -0
  70. package/build/adapters/kimi/paths.d.ts +21 -0
  71. package/build/adapters/kimi/paths.js +52 -0
  72. package/build/adapters/kimi/usage.d.ts +82 -0
  73. package/build/adapters/kimi/usage.js +217 -0
  74. package/build/adapters/kiro/hooks.d.ts +61 -0
  75. package/build/adapters/kiro/hooks.js +94 -0
  76. package/build/adapters/kiro/index.d.ts +61 -0
  77. package/build/adapters/kiro/index.js +301 -0
  78. package/build/adapters/omp/index.d.ts +65 -0
  79. package/build/adapters/omp/index.js +182 -0
  80. package/build/adapters/omp/plugin.d.ts +81 -0
  81. package/build/adapters/omp/plugin.js +331 -0
  82. package/build/adapters/omp/usage.d.ts +49 -0
  83. package/build/adapters/omp/usage.js +110 -0
  84. package/build/adapters/openclaw/config.d.ts +8 -0
  85. package/build/adapters/openclaw/config.js +8 -0
  86. package/build/adapters/openclaw/hooks.d.ts +50 -0
  87. package/build/adapters/openclaw/hooks.js +61 -0
  88. package/build/adapters/openclaw/index.d.ts +74 -0
  89. package/build/adapters/openclaw/index.js +439 -0
  90. package/build/adapters/openclaw/mcp-tools.d.ts +54 -0
  91. package/build/adapters/openclaw/mcp-tools.js +207 -0
  92. package/build/adapters/openclaw/plugin.d.ts +141 -0
  93. package/build/adapters/openclaw/plugin.js +818 -0
  94. package/build/adapters/openclaw/session-db.d.ts +55 -0
  95. package/build/adapters/openclaw/session-db.js +88 -0
  96. package/build/adapters/openclaw/usage.d.ts +34 -0
  97. package/build/adapters/openclaw/usage.js +52 -0
  98. package/build/adapters/openclaw/workspace-router.d.ts +29 -0
  99. package/build/adapters/openclaw/workspace-router.js +64 -0
  100. package/build/adapters/opencode/config.d.ts +8 -0
  101. package/build/adapters/opencode/config.js +8 -0
  102. package/build/adapters/opencode/hooks.d.ts +38 -0
  103. package/build/adapters/opencode/hooks.js +50 -0
  104. package/build/adapters/opencode/index.d.ts +144 -0
  105. package/build/adapters/opencode/index.js +638 -0
  106. package/build/adapters/opencode/plugin.d.ts +249 -0
  107. package/build/adapters/opencode/plugin.js +1536 -0
  108. package/build/adapters/opencode/v2.d.ts +117 -0
  109. package/build/adapters/opencode/v2.js +224 -0
  110. package/build/adapters/opencode/zod3tov4.d.ts +1 -0
  111. package/build/adapters/opencode/zod3tov4.js +132 -0
  112. package/build/adapters/pi/extension.d.ts +81 -0
  113. package/build/adapters/pi/extension.js +861 -0
  114. package/build/adapters/pi/index.d.ts +57 -0
  115. package/build/adapters/pi/index.js +173 -0
  116. package/build/adapters/pi/mcp-bridge.d.ts +268 -0
  117. package/build/adapters/pi/mcp-bridge.js +894 -0
  118. package/build/adapters/qwen-code/hooks.d.ts +26 -0
  119. package/build/adapters/qwen-code/hooks.js +29 -0
  120. package/build/adapters/qwen-code/index.d.ts +40 -0
  121. package/build/adapters/qwen-code/index.js +361 -0
  122. package/build/adapters/qwen-code/usage.d.ts +90 -0
  123. package/build/adapters/qwen-code/usage.js +222 -0
  124. package/build/adapters/types.d.ts +360 -0
  125. package/build/adapters/types.js +118 -0
  126. package/build/adapters/vscode-copilot/config.d.ts +8 -0
  127. package/build/adapters/vscode-copilot/config.js +8 -0
  128. package/build/adapters/vscode-copilot/hooks.d.ts +71 -0
  129. package/build/adapters/vscode-copilot/hooks.js +98 -0
  130. package/build/adapters/vscode-copilot/index.d.ts +32 -0
  131. package/build/adapters/vscode-copilot/index.js +222 -0
  132. package/build/adapters/zed/index.d.ts +40 -0
  133. package/build/adapters/zed/index.js +163 -0
  134. package/build/cli.d.ts +34 -0
  135. package/build/cli.js +1828 -0
  136. package/build/db-base.d.ts +250 -0
  137. package/build/db-base.js +756 -0
  138. package/build/executor.d.ts +72 -0
  139. package/build/executor.js +678 -0
  140. package/build/exit-classify.d.ts +19 -0
  141. package/build/exit-classify.js +12 -0
  142. package/build/fetch/blocks.d.ts +145 -0
  143. package/build/fetch/blocks.js +244 -0
  144. package/build/fetch/extract.d.ts +68 -0
  145. package/build/fetch/extract.js +123 -0
  146. package/build/fetch/page-store.d.ts +66 -0
  147. package/build/fetch/page-store.js +174 -0
  148. package/build/fetch-cache.d.ts +13 -0
  149. package/build/fetch-cache.js +15 -0
  150. package/build/lifecycle.d.ts +124 -0
  151. package/build/lifecycle.js +278 -0
  152. package/build/package-identity.d.ts +26 -0
  153. package/build/package-identity.js +28 -0
  154. package/build/runPool.d.ts +36 -0
  155. package/build/runPool.js +51 -0
  156. package/build/runtime.d.ts +71 -0
  157. package/build/runtime.js +659 -0
  158. package/build/search/auto-memory.d.ts +47 -0
  159. package/build/search/auto-memory.js +170 -0
  160. package/build/search/ctx-search-schema.d.ts +90 -0
  161. package/build/search/ctx-search-schema.js +135 -0
  162. package/build/search/flood-guard.d.ts +57 -0
  163. package/build/search/flood-guard.js +80 -0
  164. package/build/search/unified.d.ts +56 -0
  165. package/build/search/unified.js +104 -0
  166. package/build/security.d.ts +206 -0
  167. package/build/security.js +780 -0
  168. package/build/server.d.ts +240 -0
  169. package/build/server.js +5034 -0
  170. package/build/session/analytics.d.ts +773 -0
  171. package/build/session/analytics.js +2420 -0
  172. package/build/session/db.d.ts +468 -0
  173. package/build/session/db.js +1330 -0
  174. package/build/session/error-classifier.d.ts +87 -0
  175. package/build/session/error-classifier.js +303 -0
  176. package/build/session/event-emit.d.ts +48 -0
  177. package/build/session/event-emit.js +101 -0
  178. package/build/session/extract.d.ts +333 -0
  179. package/build/session/extract.js +2688 -0
  180. package/build/session/model-prices.json +429 -0
  181. package/build/session/persist-tool-calls.d.ts +54 -0
  182. package/build/session/persist-tool-calls.js +105 -0
  183. package/build/session/pricing.d.ts +64 -0
  184. package/build/session/pricing.js +151 -0
  185. package/build/session/project-attribution.d.ts +73 -0
  186. package/build/session/project-attribution.js +245 -0
  187. package/build/session/purge.d.ts +138 -0
  188. package/build/session/purge.js +240 -0
  189. package/build/session/retrieval-marker.d.ts +39 -0
  190. package/build/session/retrieval-marker.js +65 -0
  191. package/build/session/snapshot.d.ts +46 -0
  192. package/build/session/snapshot.js +532 -0
  193. package/build/store-directory.d.ts +56 -0
  194. package/build/store-directory.js +254 -0
  195. package/build/store.d.ts +147 -0
  196. package/build/store.js +1714 -0
  197. package/build/truncate.d.ts +57 -0
  198. package/build/truncate.js +142 -0
  199. package/build/types.d.ts +117 -0
  200. package/build/types.js +20 -0
  201. package/build/util/claude-config.d.ts +32 -0
  202. package/build/util/claude-config.js +84 -0
  203. package/build/util/hook-config.d.ts +27 -0
  204. package/build/util/hook-config.js +76 -0
  205. package/build/util/jsonc.d.ts +14 -0
  206. package/build/util/jsonc.js +104 -0
  207. package/build/util/plugin-cache-integrity.d.ts +51 -0
  208. package/build/util/plugin-cache-integrity.js +146 -0
  209. package/build/util/project-dir.d.ts +149 -0
  210. package/build/util/project-dir.js +340 -0
  211. package/build/util/sibling-mcp.d.ts +79 -0
  212. package/build/util/sibling-mcp.js +181 -0
  213. package/cli.bundle.mjs +1495 -0
  214. package/configs/antigravity/GEMINI.md +68 -0
  215. package/configs/antigravity/mcp_config.json +7 -0
  216. package/configs/antigravity-cli/hooks/hooks.json +37 -0
  217. package/configs/antigravity-cli/hooks.json +37 -0
  218. package/configs/antigravity-cli/mcp_config.json +10 -0
  219. package/configs/antigravity-cli/plugin.json +14 -0
  220. package/configs/antigravity-cli/rules/context-mode.md +77 -0
  221. package/configs/antigravity-cli/skills/context-mode/SKILL.md +77 -0
  222. package/configs/claude-code/CLAUDE.md +91 -0
  223. package/configs/codex/AGENTS.md +99 -0
  224. package/configs/codex/config.toml +8 -0
  225. package/configs/codex/hooks.json +47 -0
  226. package/configs/copilot-cli/.github/plugin/plugin.json +23 -0
  227. package/configs/copilot-cli/.mcp.json +12 -0
  228. package/configs/copilot-cli/README.md +47 -0
  229. package/configs/copilot-cli/hooks.json +41 -0
  230. package/configs/copilot-cli/skills/context-mode/SKILL.md +38 -0
  231. package/configs/cursor/context-mode.mdc +76 -0
  232. package/configs/cursor/hooks.json +21 -0
  233. package/configs/cursor/mcp.json +7 -0
  234. package/configs/gemini-cli/GEMINI.md +88 -0
  235. package/configs/gemini-cli/mcp.json +7 -0
  236. package/configs/gemini-cli/settings.json +60 -0
  237. package/configs/jetbrains-copilot/copilot-instructions.md +80 -0
  238. package/configs/jetbrains-copilot/hooks.json +16 -0
  239. package/configs/jetbrains-copilot/mcp.json +7 -0
  240. package/configs/kilo/AGENTS.md +84 -0
  241. package/configs/kilo/kilo.json +6 -0
  242. package/configs/kimi/hooks.json +54 -0
  243. package/configs/kiro/KIRO.md +84 -0
  244. package/configs/kiro/agent.json +18 -0
  245. package/configs/kiro/mcp.json +7 -0
  246. package/configs/omp/SYSTEM.md +85 -0
  247. package/configs/omp/mcp.json +7 -0
  248. package/configs/openclaw/AGENTS.md +87 -0
  249. package/configs/openclaw/openclaw.json +13 -0
  250. package/configs/opencode/AGENTS.md +84 -0
  251. package/configs/opencode/opencode.json +6 -0
  252. package/configs/pi/AGENTS.md +3 -0
  253. package/configs/qwen-code/QWEN.md +91 -0
  254. package/configs/vscode-copilot/copilot-instructions.md +80 -0
  255. package/configs/vscode-copilot/hooks.json +16 -0
  256. package/configs/vscode-copilot/mcp.json +7 -0
  257. package/configs/zed/AGENTS.md +68 -0
  258. package/hooks/antigravity-cli/payload.mjs +98 -0
  259. package/hooks/antigravity-cli/posttooluse.mjs +138 -0
  260. package/hooks/antigravity-cli/pretooluse.mjs +78 -0
  261. package/hooks/antigravity-cli/stop.mjs +58 -0
  262. package/hooks/auto-injection.mjs +102 -0
  263. package/hooks/cache-heal-utils.mjs +379 -0
  264. package/hooks/codex/platform.mjs +1 -0
  265. package/hooks/codex/posttooluse.mjs +66 -0
  266. package/hooks/codex/precompact.mjs +70 -0
  267. package/hooks/codex/pretooluse.mjs +42 -0
  268. package/hooks/codex/sessionstart.mjs +121 -0
  269. package/hooks/codex/stop.mjs +138 -0
  270. package/hooks/codex/userpromptsubmit.mjs +75 -0
  271. package/hooks/copilot-cli/posttooluse.mjs +79 -0
  272. package/hooks/copilot-cli/precompact.mjs +66 -0
  273. package/hooks/copilot-cli/pretooluse.mjs +41 -0
  274. package/hooks/copilot-cli/sessionstart.mjs +121 -0
  275. package/hooks/copilot-cli/stop.mjs +59 -0
  276. package/hooks/copilot-cli/userpromptsubmit.mjs +77 -0
  277. package/hooks/core/codex-caps.mjs +112 -0
  278. package/hooks/core/formatters.mjs +356 -0
  279. package/hooks/core/mcp-ready.mjs +109 -0
  280. package/hooks/core/platform-detect.mjs +49 -0
  281. package/hooks/core/routing.mjs +1050 -0
  282. package/hooks/core/stdin.mjs +90 -0
  283. package/hooks/core/tool-naming.mjs +57 -0
  284. package/hooks/cursor/afteragentresponse.mjs +74 -0
  285. package/hooks/cursor/hooks.json +31 -0
  286. package/hooks/cursor/posttooluse.mjs +72 -0
  287. package/hooks/cursor/pretooluse.mjs +26 -0
  288. package/hooks/cursor/sessionstart.mjs +97 -0
  289. package/hooks/cursor/stop.mjs +48 -0
  290. package/hooks/ensure-deps.mjs +254 -0
  291. package/hooks/formatters/claude-code.mjs +113 -0
  292. package/hooks/formatters/cursor.mjs +37 -0
  293. package/hooks/formatters/gemini-cli.mjs +55 -0
  294. package/hooks/formatters/vscode-copilot.mjs +55 -0
  295. package/hooks/gemini-cli/aftermodel.mjs +70 -0
  296. package/hooks/gemini-cli/aftertool.mjs +61 -0
  297. package/hooks/gemini-cli/beforeagent.mjs +99 -0
  298. package/hooks/gemini-cli/beforetool.mjs +27 -0
  299. package/hooks/gemini-cli/precompress.mjs +55 -0
  300. package/hooks/gemini-cli/sessionstart.mjs +137 -0
  301. package/hooks/heal-partial-install.mjs +712 -0
  302. package/hooks/hooks.json +143 -0
  303. package/hooks/jetbrains-copilot/posttooluse.mjs +61 -0
  304. package/hooks/jetbrains-copilot/precompact.mjs +55 -0
  305. package/hooks/jetbrains-copilot/pretooluse.mjs +27 -0
  306. package/hooks/jetbrains-copilot/sessionstart.mjs +124 -0
  307. package/hooks/kimi/platform.mjs +1 -0
  308. package/hooks/kimi/posttooluse.mjs +72 -0
  309. package/hooks/kimi/precompact.mjs +80 -0
  310. package/hooks/kimi/pretooluse.mjs +42 -0
  311. package/hooks/kimi/sessionend.mjs +61 -0
  312. package/hooks/kimi/sessionstart.mjs +113 -0
  313. package/hooks/kimi/stop.mjs +132 -0
  314. package/hooks/kimi/userpromptsubmit.mjs +90 -0
  315. package/hooks/kiro/agentspawn.mjs +97 -0
  316. package/hooks/kiro/posttooluse.mjs +51 -0
  317. package/hooks/kiro/pretooluse.mjs +64 -0
  318. package/hooks/kiro/userpromptsubmit.mjs +88 -0
  319. package/hooks/normalize-hooks.mjs +323 -0
  320. package/hooks/platform-bridge.mjs +340 -0
  321. package/hooks/posttooluse.mjs +225 -0
  322. package/hooks/precompact.mjs +100 -0
  323. package/hooks/pretooluse.mjs +227 -0
  324. package/hooks/qwen-code/platform.mjs +1 -0
  325. package/hooks/qwen-code/stop.mjs +168 -0
  326. package/hooks/routing-block.mjs +105 -0
  327. package/hooks/run-hook.mjs +95 -0
  328. package/hooks/security.bundle.mjs +2 -0
  329. package/hooks/session-attribution.bundle.mjs +1 -0
  330. package/hooks/session-db.bundle.mjs +145 -0
  331. package/hooks/session-directive.mjs +520 -0
  332. package/hooks/session-extract.bundle.mjs +3 -0
  333. package/hooks/session-helpers.mjs +428 -0
  334. package/hooks/session-loaders.mjs +448 -0
  335. package/hooks/session-snapshot.bundle.mjs +32 -0
  336. package/hooks/sessionstart.mjs +464 -0
  337. package/hooks/stop.mjs +82 -0
  338. package/hooks/suppress-stderr.mjs +25 -0
  339. package/hooks/userpromptsubmit.mjs +108 -0
  340. package/hooks/vscode-copilot/posttooluse.mjs +61 -0
  341. package/hooks/vscode-copilot/precompact.mjs +55 -0
  342. package/hooks/vscode-copilot/pretooluse.mjs +27 -0
  343. package/hooks/vscode-copilot/sessionstart.mjs +129 -0
  344. package/openclaw.plugin.json +38 -0
  345. package/package.json +132 -0
  346. package/scripts/heal-better-sqlite3.mjs +430 -0
  347. package/scripts/heal-installed-plugins.mjs +635 -0
  348. package/scripts/plugin-cache-integrity.mjs +248 -0
  349. package/scripts/postinstall.mjs +397 -0
  350. package/server.bundle.mjs +1421 -0
  351. package/server.js +5 -0
  352. package/skills/.ignore +7 -0
  353. package/skills/context-mode/SKILL.md +300 -0
  354. package/skills/context-mode/references/anti-patterns.md +283 -0
  355. package/skills/context-mode/references/patterns-javascript.md +298 -0
  356. package/skills/context-mode/references/patterns-python.md +304 -0
  357. package/skills/context-mode/references/patterns-shell.md +277 -0
  358. package/skills/ctx-doctor/SKILL.md +22 -0
  359. package/skills/ctx-index/SKILL.md +46 -0
  360. package/skills/ctx-insight/SKILL.md +24 -0
  361. package/skills/ctx-purge/SKILL.md +49 -0
  362. package/skills/ctx-search/SKILL.md +35 -0
  363. package/skills/ctx-stats/SKILL.md +26 -0
  364. package/skills/ctx-upgrade/SKILL.md +31 -0
  365. 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[];