@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,118 @@
1
+ /**
2
+ * adapters/types — Platform adapter interface for multi-platform hook support.
3
+ *
4
+ * Defines the contract that each platform adapter must implement.
5
+ * Three paradigms exist across supported platforms:
6
+ * A) JSON stdin/stdout — Claude Code, Gemini/Qwen family CLIs, Copilot/Codex/Kimi,
7
+ * Cursor, Kiro, Antigravity CLI (`agy`)
8
+ * B) TS Plugin Functions — OpenCode, KiloCode, OpenClaw
9
+ * C) MCP-only (no hooks) — Antigravity IDE, Zed, Pi/OMP MCP-only paths
10
+ *
11
+ * The MCP server layer is 100% portable and needs no adapter.
12
+ * Only the hook layer requires platform-specific adapters.
13
+ */
14
+ // ─────────────────────────────────────────────────────────
15
+ // Hook paradigm
16
+ // ─────────────────────────────────────────────────────────
17
+ import { resolveHookRuntime } from "../runtime.js";
18
+ // ─────────────────────────────────────────────────────────
19
+ // Platform detection
20
+ // ─────────────────────────────────────────────────────────
21
+ // ─────────────────────────────────────────────────────────
22
+ // Cross-platform command helpers (#369, #372)
23
+ // ─────────────────────────────────────────────────────────
24
+ /**
25
+ * Build a cross-platform `node <script>` command string.
26
+ *
27
+ * Fixes two Windows bugs:
28
+ * #369 — Bare `node` fails on Windows Git Bash (MSYS) because PATH
29
+ * resolution is unreliable. Uses `process.execPath` instead.
30
+ * #372 — MSYS rewrites absolute paths on non-C: drives (e.g.
31
+ * `C:\Users\...` → `D:\c\Users\...`). Forward slashes +
32
+ * double-quoting prevents the translation.
33
+ *
34
+ * Safe on macOS/Linux — quoting and forward slashes are no-ops there.
35
+ */
36
+ export function buildNodeCommand(scriptPath, opts) {
37
+ let nodePath = process.execPath.replace(/\\/g, "/");
38
+ if (isInProcessPluginPlatform(opts?.platform)) {
39
+ const base = nodePath.split("/").pop().replace(/\.exe$/i, "");
40
+ if (!JS_RUNTIMES.has(base)) {
41
+ nodePath = opts?.jsRuntime?.replace(/\\/g, "/") ?? "node";
42
+ }
43
+ }
44
+ const safePath = scriptPath.replace(/\\/g, "/");
45
+ return `"${nodePath}" "${safePath}"`;
46
+ }
47
+ /**
48
+ * Build a cross-platform hook spawn command using the resolved JS runtime
49
+ * (issue #738). Identical wire-format to {@link buildNodeCommand} — two
50
+ * double-quoted, forward-slashed tokens separated by whitespace — so it
51
+ * round-trips through {@link parseNodeCommand} unchanged.
52
+ *
53
+ * The only difference is the runtime path: when a Bun ≥1.0 install is
54
+ * detected at process start, that path is used in place of `process.execPath`.
55
+ * Hooks run end-to-end in pure JS (no native modules) so swapping the
56
+ * runtime is a no-op for output but cuts ~40-60ms of Node cold-start per
57
+ * tool call.
58
+ *
59
+ * Why a SEPARATE helper instead of repurposing {@link buildNodeCommand}:
60
+ * `buildNodeCommand` is also called by openclaw plugin (doctor / upgrade
61
+ * command suggestions in `src/adapters/openclaw/plugin.ts`). Those CLI
62
+ * targets MUST stay on Node because they load better-sqlite3, which has
63
+ * no Bun-compatible prebuild yet (#543). Keeping the two helpers separate
64
+ * makes the audit trivial: anything emitting a hook spawn command uses
65
+ * `buildHookRuntimeCommand`; anything emitting a user-visible CLI command
66
+ * stays on `buildNodeCommand`.
67
+ *
68
+ * `opts.platform` is forwarded to {@link isInProcessPluginPlatform} so the
69
+ * existing opencode/kilo in-process JS-runtime substitution still works
70
+ * (those platforms inject their own runtime via `opts.jsRuntime`).
71
+ */
72
+ export function buildHookRuntimeCommand(scriptPath, opts) {
73
+ // In-process plugin platforms (opencode/kilo) inject their own runtime —
74
+ // delegate to buildNodeCommand which already handles that special case.
75
+ if (isInProcessPluginPlatform(opts?.platform)) {
76
+ return buildNodeCommand(scriptPath, opts);
77
+ }
78
+ const runtime = resolveHookRuntime();
79
+ const runtimePath = runtime.path.replace(/\\/g, "/");
80
+ const safePath = scriptPath.replace(/\\/g, "/");
81
+ return `"${runtimePath}" "${safePath}"`;
82
+ }
83
+ /**
84
+ * Strict inverse of `buildNodeCommand`.
85
+ *
86
+ * Returns `{ nodePath, scriptPath }` ONLY when `cmd` could have been
87
+ * produced by `buildNodeCommand` — i.e. exactly two double-quoted args
88
+ * separated by whitespace. Anything else (bare `node …`, single quotes,
89
+ * unquoted ambiguous input, CLI dispatcher entries) returns `null`.
90
+ *
91
+ * Why strict: the legacy `\S+\.mjs` fallback in
92
+ * `src/util/hook-config.ts:24` and the two-step regex in
93
+ * `src/adapters/claude-code/hooks.ts:178` silently grabbed the path tail
94
+ * after the last whitespace whenever the host wire-format dropped quotes,
95
+ * producing the #548 doubled-path FAIL when `pluginRoot` contained
96
+ * spaces (e.g. `C:\Users\High Ground Services\…`). A canonical inverse
97
+ * lets every emit (`buildNodeCommand`) round-trip through every parse
98
+ * (`parseNodeCommand`) without inventing fallbacks. Adapter #16 inherits
99
+ * the contract by importing one module.
100
+ */
101
+ export function parseNodeCommand(cmd) {
102
+ if (typeof cmd !== "string" || cmd.length === 0)
103
+ return null;
104
+ // Match `"<nodePath>" "<scriptPath>"` with arbitrary whitespace
105
+ // separator. Both segments must be non-empty and contain no embedded
106
+ // double quotes — buildNodeCommand never emits embedded quotes.
107
+ const m = cmd.match(/^"([^"]+)"\s+"([^"]+)"\s*$/);
108
+ if (!m)
109
+ return null;
110
+ return { nodePath: m[1], scriptPath: m[2] };
111
+ }
112
+ /** Known JS runtime binary names (base filename without extension). */
113
+ export const JS_RUNTIMES = new Set(["node", "bun", "deno"]);
114
+ /** Platforms where context-mode runs as an in-process TS plugin (not MCP stdio). */
115
+ export const IN_PROCESS_PLUGIN_PLATFORMS = new Set(["opencode", "kilo"]);
116
+ export function isInProcessPluginPlatform(p) {
117
+ return !!p && IN_PROCESS_PLUGIN_PLATFORMS.has(p);
118
+ }
@@ -0,0 +1,8 @@
1
+ /**
2
+ * adapters/vscode-copilot/config — Thin re-exports from VSCodeCopilotAdapter.
3
+ *
4
+ * This module exists for backward compatibility. All logic lives in the
5
+ * adapter class (index.ts). New code should use getAdapter() from detect.ts.
6
+ */
7
+ export { VSCodeCopilotAdapter } from "./index.js";
8
+ export { HOOK_TYPES, HOOK_SCRIPTS, REQUIRED_HOOKS, OPTIONAL_HOOKS } from "./hooks.js";
@@ -0,0 +1,8 @@
1
+ /**
2
+ * adapters/vscode-copilot/config — Thin re-exports from VSCodeCopilotAdapter.
3
+ *
4
+ * This module exists for backward compatibility. All logic lives in the
5
+ * adapter class (index.ts). New code should use getAdapter() from detect.ts.
6
+ */
7
+ export { VSCodeCopilotAdapter } from "./index.js";
8
+ export { HOOK_TYPES, HOOK_SCRIPTS, REQUIRED_HOOKS, OPTIONAL_HOOKS } from "./hooks.js";
@@ -0,0 +1,71 @@
1
+ /**
2
+ * adapters/vscode-copilot/hooks — VS Code Copilot hook definitions and matchers.
3
+ *
4
+ * Defines the hook types, matchers, and registration format specific to
5
+ * VS Code Copilot's hook system. This module is used by:
6
+ * - CLI setup/upgrade commands (to configure hooks)
7
+ * - Doctor command (to validate hook configuration)
8
+ * - Hook config generation
9
+ *
10
+ * VS Code Copilot hook system reference:
11
+ * - Hooks are registered in .github/hooks/*.json
12
+ * - Hook names: PreToolUse, PostToolUse, PreCompact, SessionStart (PascalCase)
13
+ * - CRITICAL: matchers are parsed but IGNORED (all hooks fire on all tools)
14
+ * - Input: JSON on stdin
15
+ * - Output: JSON on stdout (or empty for passthrough)
16
+ * - Preview status — API may change
17
+ */
18
+ /** VS Code Copilot hook types. */
19
+ export declare const HOOK_TYPES: {
20
+ readonly PRE_TOOL_USE: "PreToolUse";
21
+ readonly POST_TOOL_USE: "PostToolUse";
22
+ readonly PRE_COMPACT: "PreCompact";
23
+ readonly SESSION_START: "SessionStart";
24
+ };
25
+ export type HookType = (typeof HOOK_TYPES)[keyof typeof HOOK_TYPES];
26
+ /** Map of hook types to their script file names. */
27
+ export declare const HOOK_SCRIPTS: Record<string, string>;
28
+ /** Required hooks that must be configured for context-mode to function. */
29
+ export declare const REQUIRED_HOOKS: HookType[];
30
+ /** Optional hooks that enhance functionality but aren't critical. */
31
+ export declare const OPTIONAL_HOOKS: HookType[];
32
+ /**
33
+ * Check if a hook entry points to a context-mode hook script.
34
+ * Matches both legacy format (node .../pretooluse.mjs) and
35
+ * CLI dispatcher format (context-mode hook vscode-copilot pretooluse).
36
+ */
37
+ export declare function isContextModeHook(entry: {
38
+ hooks?: Array<{
39
+ command?: string;
40
+ }>;
41
+ }, hookType: HookType): boolean;
42
+ /**
43
+ * Build the hook command string for a given hook type.
44
+ *
45
+ * Always emits the CLI dispatcher form
46
+ * (`context-mode hook vscode-copilot <event>`) — the `pluginRoot` argument
47
+ * is accepted for API compatibility but intentionally ignored.
48
+ *
49
+ * Why the dispatcher form is mandatory here (Issue #613 — Tier C contract):
50
+ * `.github/hooks/context-mode.json` is a **workspace-committed** file
51
+ * (upstream: refs/platforms/vscode-copilot/assets/prompts/skills/
52
+ * agent-customization/references/hooks.md line 7 — "Workspace
53
+ * (team-shared)"). It lands in every teammate's `git status`. Embedding
54
+ * `process.execPath` or any absolute pluginRoot path here:
55
+ * - Leaks PII (username, `C:/Users/<user>/...` paths).
56
+ * - Breaks cross-machine portability (fnm/nvm/volta/brew shims are
57
+ * per-shell-session ephemeral; the path goes stale immediately on
58
+ * Windows + fnm).
59
+ *
60
+ * Commit `f5c9d02` (2026-03-06) added an absolute-path branch when a
61
+ * pluginRoot was passed. It solved a real PATH-availability bug on
62
+ * Brew/nvm setups by going too far — the CLI then always passes
63
+ * pluginRoot, so the portable form became unreachable in production
64
+ * and every `/ctx-upgrade` baked a non-portable command into the
65
+ * committed config. This reverts to the pre-`f5c9d02` shape.
66
+ *
67
+ * For users without a global install, the recovery path is the same as
68
+ * every other CLI-dispatcher adapter (cursor, codex):
69
+ * `npm install -g @mxalbert/context-mode`
70
+ */
71
+ export declare function buildHookCommand(hookType: HookType, _pluginRoot?: string): string;
@@ -0,0 +1,98 @@
1
+ /**
2
+ * adapters/vscode-copilot/hooks — VS Code Copilot hook definitions and matchers.
3
+ *
4
+ * Defines the hook types, matchers, and registration format specific to
5
+ * VS Code Copilot's hook system. This module is used by:
6
+ * - CLI setup/upgrade commands (to configure hooks)
7
+ * - Doctor command (to validate hook configuration)
8
+ * - Hook config generation
9
+ *
10
+ * VS Code Copilot hook system reference:
11
+ * - Hooks are registered in .github/hooks/*.json
12
+ * - Hook names: PreToolUse, PostToolUse, PreCompact, SessionStart (PascalCase)
13
+ * - CRITICAL: matchers are parsed but IGNORED (all hooks fire on all tools)
14
+ * - Input: JSON on stdin
15
+ * - Output: JSON on stdout (or empty for passthrough)
16
+ * - Preview status — API may change
17
+ */
18
+ // ─────────────────────────────────────────────────────────
19
+ // Hook type constants
20
+ // ─────────────────────────────────────────────────────────
21
+ /** VS Code Copilot hook types. */
22
+ export const HOOK_TYPES = {
23
+ PRE_TOOL_USE: "PreToolUse",
24
+ POST_TOOL_USE: "PostToolUse",
25
+ PRE_COMPACT: "PreCompact",
26
+ SESSION_START: "SessionStart",
27
+ };
28
+ // ─────────────────────────────────────────────────────────
29
+ // Hook script file names
30
+ // ─────────────────────────────────────────────────────────
31
+ /** Map of hook types to their script file names. */
32
+ export const HOOK_SCRIPTS = {
33
+ [HOOK_TYPES.PRE_TOOL_USE]: "pretooluse.mjs",
34
+ [HOOK_TYPES.POST_TOOL_USE]: "posttooluse.mjs",
35
+ [HOOK_TYPES.PRE_COMPACT]: "precompact.mjs",
36
+ [HOOK_TYPES.SESSION_START]: "sessionstart.mjs",
37
+ };
38
+ // ─────────────────────────────────────────────────────────
39
+ // Hook validation
40
+ // ─────────────────────────────────────────────────────────
41
+ /** Required hooks that must be configured for context-mode to function. */
42
+ export const REQUIRED_HOOKS = [
43
+ HOOK_TYPES.PRE_TOOL_USE,
44
+ HOOK_TYPES.SESSION_START,
45
+ ];
46
+ /** Optional hooks that enhance functionality but aren't critical. */
47
+ export const OPTIONAL_HOOKS = [
48
+ HOOK_TYPES.POST_TOOL_USE,
49
+ HOOK_TYPES.PRE_COMPACT,
50
+ ];
51
+ /**
52
+ * Check if a hook entry points to a context-mode hook script.
53
+ * Matches both legacy format (node .../pretooluse.mjs) and
54
+ * CLI dispatcher format (context-mode hook vscode-copilot pretooluse).
55
+ */
56
+ export function isContextModeHook(entry, hookType) {
57
+ const scriptName = HOOK_SCRIPTS[hookType];
58
+ if (!scriptName)
59
+ return false;
60
+ const cliCommand = buildHookCommand(hookType);
61
+ return (entry.hooks?.some((h) => h.command?.includes(scriptName) || h.command?.includes(cliCommand)) ?? false);
62
+ }
63
+ /**
64
+ * Build the hook command string for a given hook type.
65
+ *
66
+ * Always emits the CLI dispatcher form
67
+ * (`context-mode hook vscode-copilot <event>`) — the `pluginRoot` argument
68
+ * is accepted for API compatibility but intentionally ignored.
69
+ *
70
+ * Why the dispatcher form is mandatory here (Issue #613 — Tier C contract):
71
+ * `.github/hooks/context-mode.json` is a **workspace-committed** file
72
+ * (upstream: refs/platforms/vscode-copilot/assets/prompts/skills/
73
+ * agent-customization/references/hooks.md line 7 — "Workspace
74
+ * (team-shared)"). It lands in every teammate's `git status`. Embedding
75
+ * `process.execPath` or any absolute pluginRoot path here:
76
+ * - Leaks PII (username, `C:/Users/<user>/...` paths).
77
+ * - Breaks cross-machine portability (fnm/nvm/volta/brew shims are
78
+ * per-shell-session ephemeral; the path goes stale immediately on
79
+ * Windows + fnm).
80
+ *
81
+ * Commit `f5c9d02` (2026-03-06) added an absolute-path branch when a
82
+ * pluginRoot was passed. It solved a real PATH-availability bug on
83
+ * Brew/nvm setups by going too far — the CLI then always passes
84
+ * pluginRoot, so the portable form became unreachable in production
85
+ * and every `/ctx-upgrade` baked a non-portable command into the
86
+ * committed config. This reverts to the pre-`f5c9d02` shape.
87
+ *
88
+ * For users without a global install, the recovery path is the same as
89
+ * every other CLI-dispatcher adapter (cursor, codex):
90
+ * `npm install -g @mxalbert/context-mode`
91
+ */
92
+ export function buildHookCommand(hookType, _pluginRoot) {
93
+ const scriptName = HOOK_SCRIPTS[hookType];
94
+ if (!scriptName) {
95
+ throw new Error(`No script defined for hook type: ${hookType}`);
96
+ }
97
+ return `context-mode hook vscode-copilot ${hookType.toLowerCase()}`;
98
+ }
@@ -0,0 +1,32 @@
1
+ /**
2
+ * adapters/vscode-copilot — VS Code Copilot platform adapter.
3
+ *
4
+ * Extends CopilotBaseAdapter with VS Code-specific logic:
5
+ * - extractSessionId: VSCODE_PID fallback
6
+ * - getProjectDir: CLAUDE_PROJECT_DIR
7
+ * - getSessionDir: .github/ detection with ~/.vscode/ fallback
8
+ * - checkPluginRegistration: reads .vscode/mcp.json
9
+ * - getInstalledVersion: scans VS Code extensions dir
10
+ * - validateHooks: preview status + matcher warnings
11
+ */
12
+ import { CopilotBaseAdapter } from "../copilot-base.js";
13
+ import type { CopilotHookInput, CopilotHookModule } from "../copilot-base.js";
14
+ import type { DiagnosticResult } from "../types.js";
15
+ export declare class VSCodeCopilotAdapter extends CopilotBaseAdapter {
16
+ constructor();
17
+ readonly name = "VS Code Copilot";
18
+ protected readonly hookModule: CopilotHookModule;
19
+ protected readonly hookSubdir = "vscode-copilot";
20
+ protected extractSessionId(input: CopilotHookInput): string;
21
+ protected getProjectDir(): string;
22
+ getSessionDir(): string;
23
+ /**
24
+ * VS Code Copilot honors .github/copilot-instructions.md per project.
25
+ * Always returned absolute, resolved against `projectDir` (or `cwd`).
26
+ */
27
+ getConfigDir(projectDir?: string): string;
28
+ getInstructionFiles(): string[];
29
+ validateHooks(pluginRoot: string): DiagnosticResult[];
30
+ checkPluginRegistration(): DiagnosticResult;
31
+ getInstalledVersion(): string;
32
+ }
@@ -0,0 +1,222 @@
1
+ /**
2
+ * adapters/vscode-copilot — VS Code Copilot platform adapter.
3
+ *
4
+ * Extends CopilotBaseAdapter with VS Code-specific logic:
5
+ * - extractSessionId: VSCODE_PID fallback
6
+ * - getProjectDir: CLAUDE_PROJECT_DIR
7
+ * - getSessionDir: .github/ detection with ~/.vscode/ fallback
8
+ * - checkPluginRegistration: reads .vscode/mcp.json
9
+ * - getInstalledVersion: scans VS Code extensions dir
10
+ * - validateHooks: preview status + matcher warnings
11
+ */
12
+ import { readFileSync, mkdirSync, accessSync, existsSync, constants, } from "node:fs";
13
+ import { resolve, join } from "node:path";
14
+ import { homedir } from "node:os";
15
+ import { CopilotBaseAdapter } from "../copilot-base.js";
16
+ import { resolveContextModeDataRoot } from "../base.js";
17
+ // ─────────────────────────────────────────────────────────
18
+ // Hook constants (re-exported from hooks.ts)
19
+ // ─────────────────────────────────────────────────────────
20
+ import { HOOK_TYPES as VSCODE_HOOK_NAMES, HOOK_SCRIPTS as VSCODE_HOOK_SCRIPTS, buildHookCommand as buildVSCodeHookCommand, } from "./hooks.js";
21
+ // ─────────────────────────────────────────────────────────
22
+ // Adapter implementation
23
+ // ─────────────────────────────────────────────────────────
24
+ export class VSCodeCopilotAdapter extends CopilotBaseAdapter {
25
+ constructor() {
26
+ // sessionDirSegments unused — vscode-copilot overrides getSessionDir()
27
+ // with .github directory detection fallback logic
28
+ super([".vscode"]);
29
+ }
30
+ name = "VS Code Copilot";
31
+ hookModule = {
32
+ HOOK_TYPES: VSCODE_HOOK_NAMES,
33
+ HOOK_SCRIPTS: VSCODE_HOOK_SCRIPTS,
34
+ buildHookCommand: buildVSCodeHookCommand,
35
+ };
36
+ hookSubdir = "vscode-copilot";
37
+ // ── Platform-specific overrides ────────────────────────
38
+ extractSessionId(input) {
39
+ if (input.sessionId)
40
+ return input.sessionId;
41
+ if (process.env.VSCODE_PID)
42
+ return `vscode-${process.env.VSCODE_PID}`;
43
+ return `pid-${process.ppid}`;
44
+ }
45
+ getProjectDir() {
46
+ // Cascade order (locked by tests/adapters/vscode-copilot.test.ts):
47
+ // 1. CLAUDE_PROJECT_DIR — top priority for users running VS Code under
48
+ // Claude Code CLI.
49
+ // 2. VSCODE_CWD — exported by VS Code's bootstrap into every child it
50
+ // spawns (refs/platforms/vscode-copilot/src/util/vs/base/common/
51
+ // process.ts:31). The MCP child inherits it. Was previously missing
52
+ // from this cascade — every direct VS Code Copilot session silently
53
+ // lost its workspace folder. PR #689 5-agent EM audit (Phase A
54
+ // claim verification) confirmed the gap; this is the minimal fix.
55
+ // 3. process.cwd() — last resort.
56
+ return (process.env.CLAUDE_PROJECT_DIR
57
+ || process.env.VSCODE_CWD
58
+ || process.cwd());
59
+ }
60
+ getSessionDir() {
61
+ // Issue #649: CONTEXT_MODE_DATA_DIR wins over both the .github project
62
+ // dir and the ~/.vscode fallback so dev-container/CI users can pin
63
+ // storage to a writable volume regardless of whether a .github tree
64
+ // happens to exist in cwd.
65
+ const override = resolveContextModeDataRoot();
66
+ if (override) {
67
+ const overrideDir = join(override, "context-mode", "sessions");
68
+ mkdirSync(overrideDir, { recursive: true });
69
+ return overrideDir;
70
+ }
71
+ // Prefer .github/context-mode/sessions/ if .github exists,
72
+ // otherwise fall back to ~/.vscode/context-mode/sessions/
73
+ const githubDir = resolve(".github", "context-mode", "sessions");
74
+ const fallbackDir = join(homedir(), ".vscode", "context-mode", "sessions");
75
+ const dir = existsSync(resolve(".github")) ? githubDir : fallbackDir;
76
+ mkdirSync(dir, { recursive: true });
77
+ return dir;
78
+ }
79
+ /**
80
+ * VS Code Copilot honors .github/copilot-instructions.md per project.
81
+ * Always returned absolute, resolved against `projectDir` (or `cwd`).
82
+ */
83
+ getConfigDir(projectDir) {
84
+ return resolve(projectDir ?? process.cwd(), ".github");
85
+ }
86
+ getInstructionFiles() {
87
+ return ["copilot-instructions.md"];
88
+ }
89
+ // ── Diagnostics (doctor) ─────────────────────────────────
90
+ validateHooks(pluginRoot) {
91
+ const results = [];
92
+ // Check .github/hooks/ directory for hook JSON files
93
+ const hooksDir = resolve(".github", "hooks");
94
+ try {
95
+ accessSync(hooksDir, constants.R_OK);
96
+ }
97
+ catch {
98
+ results.push({
99
+ check: "Hooks directory",
100
+ status: "fail",
101
+ message: ".github/hooks/ directory not found",
102
+ fix: "context-mode upgrade",
103
+ });
104
+ return results;
105
+ }
106
+ // Check for context-mode hook config
107
+ const hookConfigPath = resolve(hooksDir, "context-mode.json");
108
+ try {
109
+ const raw = readFileSync(hookConfigPath, "utf-8");
110
+ const config = JSON.parse(raw);
111
+ const hooks = config.hooks;
112
+ // Check PreToolUse
113
+ if (hooks?.[VSCODE_HOOK_NAMES.PRE_TOOL_USE]) {
114
+ results.push({
115
+ check: "PreToolUse hook",
116
+ status: "pass",
117
+ message: "PreToolUse hook configured in context-mode.json",
118
+ });
119
+ }
120
+ else {
121
+ results.push({
122
+ check: "PreToolUse hook",
123
+ status: "fail",
124
+ message: "PreToolUse not found in context-mode.json",
125
+ fix: "context-mode upgrade",
126
+ });
127
+ }
128
+ // Check SessionStart
129
+ if (hooks?.[VSCODE_HOOK_NAMES.SESSION_START]) {
130
+ results.push({
131
+ check: "SessionStart hook",
132
+ status: "pass",
133
+ message: "SessionStart hook configured in context-mode.json",
134
+ });
135
+ }
136
+ else {
137
+ results.push({
138
+ check: "SessionStart hook",
139
+ status: "fail",
140
+ message: "SessionStart not found in context-mode.json",
141
+ fix: "context-mode upgrade",
142
+ });
143
+ }
144
+ }
145
+ catch {
146
+ results.push({
147
+ check: "Hook configuration",
148
+ status: "fail",
149
+ message: "Could not read .github/hooks/context-mode.json",
150
+ fix: "context-mode upgrade",
151
+ });
152
+ }
153
+ // Warn about preview status
154
+ results.push({
155
+ check: "API stability",
156
+ status: "warn",
157
+ message: "VS Code Copilot hooks are in preview — API may change without notice",
158
+ });
159
+ // Warn about matcher behavior
160
+ results.push({
161
+ check: "Matcher support",
162
+ status: "warn",
163
+ message: "Matchers are parsed but IGNORED — all hooks fire on all tools",
164
+ });
165
+ return results;
166
+ }
167
+ checkPluginRegistration() {
168
+ // Check MCP config in .vscode/mcp.json
169
+ try {
170
+ const mcpConfigPath = resolve(".vscode", "mcp.json");
171
+ const raw = readFileSync(mcpConfigPath, "utf-8");
172
+ const config = JSON.parse(raw);
173
+ const servers = config.servers;
174
+ if (servers) {
175
+ const hasPlugin = Object.keys(servers).some((k) => k.includes("context-mode"));
176
+ if (hasPlugin) {
177
+ return {
178
+ check: "MCP registration",
179
+ status: "pass",
180
+ message: "context-mode found in .vscode/mcp.json",
181
+ };
182
+ }
183
+ }
184
+ return {
185
+ check: "MCP registration",
186
+ status: "fail",
187
+ message: "context-mode not found in .vscode/mcp.json",
188
+ fix: "Add context-mode server to .vscode/mcp.json",
189
+ };
190
+ }
191
+ catch {
192
+ return {
193
+ check: "MCP registration",
194
+ status: "warn",
195
+ message: "Could not read .vscode/mcp.json",
196
+ };
197
+ }
198
+ }
199
+ getInstalledVersion() {
200
+ // Check VS Code extensions for context-mode
201
+ const extensionDirs = [
202
+ join(homedir(), ".vscode", "extensions"),
203
+ join(homedir(), ".vscode-insiders", "extensions"),
204
+ ];
205
+ for (const extDir of extensionDirs) {
206
+ try {
207
+ const entries = readFileSync(join(extDir, "extensions.json"), "utf-8");
208
+ const exts = JSON.parse(entries);
209
+ const contextMode = exts.find((e) => typeof e.identifier === "object" &&
210
+ e.identifier !== null &&
211
+ e.identifier.id?.toString().includes("context-mode"));
212
+ if (contextMode && typeof contextMode.version === "string") {
213
+ return contextMode.version;
214
+ }
215
+ }
216
+ catch {
217
+ continue;
218
+ }
219
+ }
220
+ return "not installed";
221
+ }
222
+ }
@@ -0,0 +1,40 @@
1
+ /**
2
+ * adapters/zed — Zed editor platform adapter.
3
+ *
4
+ * Implements HookAdapter for Zed's MCP-only paradigm.
5
+ *
6
+ * Zed hook specifics:
7
+ * - NO hook support — Zed is an editor, not a CLI with hook pipelines
8
+ * - Config: ~/.config/zed/settings.json (JSON format)
9
+ * - MCP: full support via context_servers section in settings.json
10
+ * - All capabilities are false — MCP is the only integration path
11
+ * - Session dir: ~/.config/zed/context-mode/sessions/
12
+ */
13
+ import { BaseAdapter } from "../base.js";
14
+ import type { HookAdapter, HookParadigm, PlatformCapabilities, DiagnosticResult, PreToolUseEvent, PostToolUseEvent, PreCompactEvent, SessionStartEvent, PreToolUseResponse, PostToolUseResponse, PreCompactResponse, SessionStartResponse, HookRegistration } from "../types.js";
15
+ export declare class ZedAdapter extends BaseAdapter implements HookAdapter {
16
+ constructor();
17
+ readonly name = "Zed";
18
+ readonly paradigm: HookParadigm;
19
+ readonly capabilities: PlatformCapabilities;
20
+ parsePreToolUseInput(_raw: unknown): PreToolUseEvent;
21
+ parsePostToolUseInput(_raw: unknown): PostToolUseEvent;
22
+ parsePreCompactInput(_raw: unknown): PreCompactEvent;
23
+ parseSessionStartInput(_raw: unknown): SessionStartEvent;
24
+ formatPreToolUseResponse(_response: PreToolUseResponse): unknown;
25
+ formatPostToolUseResponse(_response: PostToolUseResponse): unknown;
26
+ formatPreCompactResponse(_response: PreCompactResponse): unknown;
27
+ formatSessionStartResponse(_response: SessionStartResponse): unknown;
28
+ getSettingsPath(): string;
29
+ getInstructionFiles(): string[];
30
+ generateHookConfig(_pluginRoot: string): HookRegistration;
31
+ readSettings(): Record<string, unknown> | null;
32
+ writeSettings(settings: Record<string, unknown>): void;
33
+ validateHooks(_pluginRoot: string): DiagnosticResult[];
34
+ checkPluginRegistration(): DiagnosticResult;
35
+ getInstalledVersion(): string;
36
+ configureAllHooks(_pluginRoot: string): string[];
37
+ setHookPermissions(_pluginRoot: string): string[];
38
+ updatePluginRegistry(_pluginRoot: string, _version: string): void;
39
+ getRoutingInstructions(): string;
40
+ }