@cleocode/adapters 2026.3.76 → 2026.4.2

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 (221) hide show
  1. package/dist/index.d.ts +9 -1
  2. package/dist/index.d.ts.map +1 -1
  3. package/dist/index.js +732 -630
  4. package/dist/index.js.map +4 -4
  5. package/dist/providers/claude-code/adapter.d.ts +21 -1
  6. package/dist/providers/claude-code/adapter.d.ts.map +1 -1
  7. package/dist/providers/claude-code/context-monitor.d.ts +11 -0
  8. package/dist/providers/claude-code/context-monitor.d.ts.map +1 -1
  9. package/dist/providers/claude-code/hooks.d.ts +7 -0
  10. package/dist/providers/claude-code/hooks.d.ts.map +1 -1
  11. package/dist/providers/claude-code/index.d.ts +16 -1
  12. package/dist/providers/claude-code/index.d.ts.map +1 -1
  13. package/dist/providers/claude-code/install.d.ts +10 -18
  14. package/dist/providers/claude-code/install.d.ts.map +1 -1
  15. package/dist/providers/claude-code/paths.d.ts +8 -0
  16. package/dist/providers/claude-code/paths.d.ts.map +1 -1
  17. package/dist/providers/claude-code/spawn.d.ts +7 -0
  18. package/dist/providers/claude-code/spawn.d.ts.map +1 -1
  19. package/dist/providers/claude-code/statusline.d.ts +44 -0
  20. package/dist/providers/claude-code/statusline.d.ts.map +1 -1
  21. package/dist/providers/claude-code/task-sync.d.ts +8 -0
  22. package/dist/providers/claude-code/task-sync.d.ts.map +1 -1
  23. package/dist/providers/claude-code/transport.d.ts +11 -0
  24. package/dist/providers/claude-code/transport.d.ts.map +1 -1
  25. package/dist/providers/codex/adapter.d.ts +14 -1
  26. package/dist/providers/codex/adapter.d.ts.map +1 -1
  27. package/dist/providers/codex/hooks.d.ts +6 -0
  28. package/dist/providers/codex/hooks.d.ts.map +1 -1
  29. package/dist/providers/codex/index.d.ts +16 -1
  30. package/dist/providers/codex/index.d.ts.map +1 -1
  31. package/dist/providers/codex/install.d.ts +8 -17
  32. package/dist/providers/codex/install.d.ts.map +1 -1
  33. package/dist/providers/cursor/adapter.d.ts +15 -1
  34. package/dist/providers/cursor/adapter.d.ts.map +1 -1
  35. package/dist/providers/cursor/hooks.d.ts +7 -0
  36. package/dist/providers/cursor/hooks.d.ts.map +1 -1
  37. package/dist/providers/cursor/index.d.ts +16 -1
  38. package/dist/providers/cursor/index.d.ts.map +1 -1
  39. package/dist/providers/cursor/install.d.ts +10 -17
  40. package/dist/providers/cursor/install.d.ts.map +1 -1
  41. package/dist/providers/gemini-cli/adapter.d.ts +15 -1
  42. package/dist/providers/gemini-cli/adapter.d.ts.map +1 -1
  43. package/dist/providers/gemini-cli/hooks.d.ts +7 -0
  44. package/dist/providers/gemini-cli/hooks.d.ts.map +1 -1
  45. package/dist/providers/gemini-cli/index.d.ts +16 -1
  46. package/dist/providers/gemini-cli/index.d.ts.map +1 -1
  47. package/dist/providers/gemini-cli/install.d.ts +8 -17
  48. package/dist/providers/gemini-cli/install.d.ts.map +1 -1
  49. package/dist/providers/kimi/adapter.d.ts +15 -2
  50. package/dist/providers/kimi/adapter.d.ts.map +1 -1
  51. package/dist/providers/kimi/hooks.d.ts +6 -0
  52. package/dist/providers/kimi/hooks.d.ts.map +1 -1
  53. package/dist/providers/kimi/index.d.ts +16 -1
  54. package/dist/providers/kimi/index.d.ts.map +1 -1
  55. package/dist/providers/kimi/install.d.ts +7 -22
  56. package/dist/providers/kimi/install.d.ts.map +1 -1
  57. package/dist/providers/opencode/adapter.d.ts +17 -1
  58. package/dist/providers/opencode/adapter.d.ts.map +1 -1
  59. package/dist/providers/opencode/hooks.d.ts +9 -0
  60. package/dist/providers/opencode/hooks.d.ts.map +1 -1
  61. package/dist/providers/opencode/index.d.ts +16 -1
  62. package/dist/providers/opencode/index.d.ts.map +1 -1
  63. package/dist/providers/opencode/install.d.ts +8 -17
  64. package/dist/providers/opencode/install.d.ts.map +1 -1
  65. package/dist/providers/opencode/spawn.d.ts +23 -1
  66. package/dist/providers/opencode/spawn.d.ts.map +1 -1
  67. package/dist/providers/shared/transcript-reader.d.ts +15 -0
  68. package/dist/providers/shared/transcript-reader.d.ts.map +1 -1
  69. package/dist/registry.d.ts +54 -2
  70. package/dist/registry.d.ts.map +1 -1
  71. package/package.json +3 -3
  72. package/src/__tests__/claude-code-adapter.test.js +21 -30
  73. package/src/__tests__/claude-code-adapter.test.js.map +1 -1
  74. package/src/__tests__/claude-code-adapter.test.ts +21 -32
  75. package/src/__tests__/cursor-adapter.test.js +25 -29
  76. package/src/__tests__/cursor-adapter.test.js.map +1 -1
  77. package/src/__tests__/cursor-adapter.test.ts +26 -33
  78. package/src/__tests__/opencode-adapter.test.js +47 -46
  79. package/src/__tests__/opencode-adapter.test.js.map +1 -1
  80. package/src/__tests__/opencode-adapter.test.ts +51 -49
  81. package/src/index.ts +9 -1
  82. package/src/providers/claude-code/__tests__/adapter.test.js +50 -23
  83. package/src/providers/claude-code/__tests__/adapter.test.js.map +1 -1
  84. package/src/providers/claude-code/__tests__/adapter.test.ts +52 -23
  85. package/src/providers/claude-code/adapter.ts +22 -2
  86. package/src/providers/claude-code/context-monitor.ts +11 -0
  87. package/src/providers/claude-code/hooks.ts +7 -0
  88. package/src/providers/claude-code/index.ts +16 -1
  89. package/src/providers/claude-code/install.ts +15 -96
  90. package/src/providers/claude-code/manifest.json +1 -1
  91. package/src/providers/claude-code/paths.ts +8 -0
  92. package/src/providers/claude-code/spawn.ts +7 -0
  93. package/src/providers/claude-code/statusline.ts +44 -0
  94. package/src/providers/claude-code/task-sync.ts +8 -0
  95. package/src/providers/claude-code/transport.ts +11 -0
  96. package/src/providers/codex/adapter.ts +15 -2
  97. package/src/providers/codex/hooks.ts +6 -0
  98. package/src/providers/codex/index.ts +16 -1
  99. package/src/providers/codex/install.ts +17 -81
  100. package/src/providers/codex/manifest.json +1 -1
  101. package/src/providers/cursor/__tests__/adapter.test.js +37 -12
  102. package/src/providers/cursor/__tests__/adapter.test.js.map +1 -1
  103. package/src/providers/cursor/__tests__/adapter.test.ts +43 -12
  104. package/src/providers/cursor/adapter.ts +16 -2
  105. package/src/providers/cursor/hooks.ts +7 -0
  106. package/src/providers/cursor/index.ts +16 -1
  107. package/src/providers/cursor/install.ts +23 -88
  108. package/src/providers/cursor/manifest.json +1 -1
  109. package/src/providers/gemini-cli/adapter.ts +16 -2
  110. package/src/providers/gemini-cli/hooks.ts +7 -0
  111. package/src/providers/gemini-cli/index.ts +16 -1
  112. package/src/providers/gemini-cli/install.ts +17 -81
  113. package/src/providers/gemini-cli/manifest.json +1 -1
  114. package/src/providers/kimi/adapter.ts +16 -3
  115. package/src/providers/kimi/hooks.ts +6 -0
  116. package/src/providers/kimi/index.ts +16 -1
  117. package/src/providers/kimi/install.ts +16 -86
  118. package/src/providers/kimi/manifest.json +1 -1
  119. package/src/providers/opencode/__tests__/adapter.test.js +48 -35
  120. package/src/providers/opencode/__tests__/adapter.test.js.map +1 -1
  121. package/src/providers/opencode/__tests__/adapter.test.ts +49 -34
  122. package/src/providers/opencode/adapter.ts +18 -2
  123. package/src/providers/opencode/hooks.ts +9 -0
  124. package/src/providers/opencode/index.ts +16 -1
  125. package/src/providers/opencode/install.ts +17 -90
  126. package/src/providers/opencode/manifest.json +1 -1
  127. package/src/providers/opencode/spawn.ts +23 -1
  128. package/src/providers/shared/transcript-reader.ts +15 -0
  129. package/src/registry.ts +54 -2
  130. package/src/__tests__/claude-code-adapter.test.d.ts +0 -10
  131. package/src/__tests__/cursor-adapter.test.d.ts +0 -10
  132. package/src/__tests__/opencode-adapter.test.d.ts +0 -10
  133. package/src/index.d.ts +0 -35
  134. package/src/index.d.ts.map +0 -1
  135. package/src/index.js +0 -13
  136. package/src/index.js.map +0 -1
  137. package/src/providers/claude-code/__tests__/adapter.test.d.ts +0 -7
  138. package/src/providers/claude-code/adapter.d.ts +0 -79
  139. package/src/providers/claude-code/adapter.d.ts.map +0 -1
  140. package/src/providers/claude-code/adapter.js +0 -154
  141. package/src/providers/claude-code/adapter.js.map +0 -1
  142. package/src/providers/claude-code/context-monitor.d.ts +0 -24
  143. package/src/providers/claude-code/context-monitor.d.ts.map +0 -1
  144. package/src/providers/claude-code/context-monitor.js +0 -148
  145. package/src/providers/claude-code/context-monitor.js.map +0 -1
  146. package/src/providers/claude-code/hooks.d.ts +0 -59
  147. package/src/providers/claude-code/hooks.d.ts.map +0 -1
  148. package/src/providers/claude-code/hooks.js +0 -77
  149. package/src/providers/claude-code/hooks.js.map +0 -1
  150. package/src/providers/claude-code/index.d.ts +0 -28
  151. package/src/providers/claude-code/index.d.ts.map +0 -1
  152. package/src/providers/claude-code/index.js +0 -26
  153. package/src/providers/claude-code/index.js.map +0 -1
  154. package/src/providers/claude-code/install.d.ts +0 -75
  155. package/src/providers/claude-code/install.d.ts.map +0 -1
  156. package/src/providers/claude-code/install.js +0 -234
  157. package/src/providers/claude-code/install.js.map +0 -1
  158. package/src/providers/claude-code/paths.d.ts +0 -24
  159. package/src/providers/claude-code/paths.d.ts.map +0 -1
  160. package/src/providers/claude-code/paths.js +0 -33
  161. package/src/providers/claude-code/paths.js.map +0 -1
  162. package/src/providers/claude-code/spawn.d.ts +0 -60
  163. package/src/providers/claude-code/spawn.d.ts.map +0 -1
  164. package/src/providers/claude-code/spawn.js +0 -164
  165. package/src/providers/claude-code/spawn.js.map +0 -1
  166. package/src/providers/claude-code/statusline.d.ts +0 -23
  167. package/src/providers/claude-code/statusline.d.ts.map +0 -1
  168. package/src/providers/claude-code/statusline.js +0 -86
  169. package/src/providers/claude-code/statusline.js.map +0 -1
  170. package/src/providers/claude-code/task-sync.js +0 -122
  171. package/src/providers/claude-code/task-sync.js.map +0 -1
  172. package/src/providers/claude-code/transport.d.ts +0 -14
  173. package/src/providers/claude-code/transport.d.ts.map +0 -1
  174. package/src/providers/claude-code/transport.js +0 -18
  175. package/src/providers/claude-code/transport.js.map +0 -1
  176. package/src/providers/cursor/__tests__/adapter.test.d.ts +0 -7
  177. package/src/providers/cursor/adapter.d.ts +0 -66
  178. package/src/providers/cursor/adapter.d.ts.map +0 -1
  179. package/src/providers/cursor/adapter.js +0 -124
  180. package/src/providers/cursor/adapter.js.map +0 -1
  181. package/src/providers/cursor/hooks.d.ts +0 -48
  182. package/src/providers/cursor/hooks.d.ts.map +0 -1
  183. package/src/providers/cursor/hooks.js +0 -55
  184. package/src/providers/cursor/hooks.js.map +0 -1
  185. package/src/providers/cursor/index.d.ts +0 -19
  186. package/src/providers/cursor/index.d.ts.map +0 -1
  187. package/src/providers/cursor/index.js +0 -21
  188. package/src/providers/cursor/index.js.map +0 -1
  189. package/src/providers/cursor/install.d.ts +0 -94
  190. package/src/providers/cursor/install.d.ts.map +0 -1
  191. package/src/providers/cursor/install.js +0 -238
  192. package/src/providers/cursor/install.js.map +0 -1
  193. package/src/providers/cursor/spawn.d.ts +0 -50
  194. package/src/providers/cursor/spawn.d.ts.map +0 -1
  195. package/src/providers/cursor/spawn.js +0 -59
  196. package/src/providers/cursor/spawn.js.map +0 -1
  197. package/src/providers/opencode/__tests__/adapter.test.d.ts +0 -7
  198. package/src/providers/opencode/adapter.d.ts +0 -71
  199. package/src/providers/opencode/adapter.d.ts.map +0 -1
  200. package/src/providers/opencode/adapter.js +0 -144
  201. package/src/providers/opencode/adapter.js.map +0 -1
  202. package/src/providers/opencode/hooks.d.ts +0 -66
  203. package/src/providers/opencode/hooks.d.ts.map +0 -1
  204. package/src/providers/opencode/hooks.js +0 -89
  205. package/src/providers/opencode/hooks.js.map +0 -1
  206. package/src/providers/opencode/index.d.ts +0 -20
  207. package/src/providers/opencode/index.d.ts.map +0 -1
  208. package/src/providers/opencode/index.js +0 -22
  209. package/src/providers/opencode/index.js.map +0 -1
  210. package/src/providers/opencode/install.d.ts +0 -65
  211. package/src/providers/opencode/install.d.ts.map +0 -1
  212. package/src/providers/opencode/install.js +0 -180
  213. package/src/providers/opencode/install.js.map +0 -1
  214. package/src/providers/opencode/spawn.d.ts +0 -75
  215. package/src/providers/opencode/spawn.d.ts.map +0 -1
  216. package/src/providers/opencode/spawn.js +0 -219
  217. package/src/providers/opencode/spawn.js.map +0 -1
  218. package/src/registry.d.ts +0 -36
  219. package/src/registry.d.ts.map +0 -1
  220. package/src/registry.js +0 -55
  221. package/src/registry.js.map +0 -1
package/dist/index.js CHANGED
@@ -8,23 +8,27 @@ var __export = (target, all) => {
8
8
  __defProp(target, name, { get: all[name], enumerable: true });
9
9
  };
10
10
 
11
- // packages/adapters/src/providers/claude-code/paths.js
11
+ // packages/adapters/src/providers/claude-code/paths.ts
12
12
  import { homedir } from "node:os";
13
13
  import { join } from "node:path";
14
14
  var ClaudeCodePathProvider;
15
15
  var init_paths = __esm({
16
- "packages/adapters/src/providers/claude-code/paths.js"() {
16
+ "packages/adapters/src/providers/claude-code/paths.ts"() {
17
17
  "use strict";
18
18
  ClaudeCodePathProvider = class {
19
+ /** Get the provider's root configuration directory. */
19
20
  getProviderDir() {
20
21
  return process.env["CLAUDE_HOME"] ?? join(homedir(), ".claude");
21
22
  }
23
+ /** Get the path to the provider's settings file, or null if unavailable. */
22
24
  getSettingsPath() {
23
25
  return process.env["CLAUDE_SETTINGS"] ?? join(this.getProviderDir(), "settings.json");
24
26
  }
27
+ /** Get the directory where agents are installed, or null if unsupported. */
25
28
  getAgentInstallDir() {
26
29
  return join(this.getProviderDir(), "agents");
27
30
  }
31
+ /** Get the path to the provider's memory database, or null if unsupported. */
28
32
  getMemoryDbPath() {
29
33
  return process.env["CLAUDE_MEM_DB"] ?? join(homedir(), ".claude-mem", "claude-mem.db");
30
34
  }
@@ -32,25 +36,21 @@ var init_paths = __esm({
32
36
  }
33
37
  });
34
38
 
35
- // packages/adapters/src/providers/claude-code/context-monitor.js
39
+ // packages/adapters/src/providers/claude-code/context-monitor.ts
36
40
  import { existsSync, readFileSync, writeFileSync } from "node:fs";
37
41
  import { mkdir } from "node:fs/promises";
38
42
  import { homedir as homedir2 } from "node:os";
39
43
  import { dirname, join as join2 } from "node:path";
40
44
  function getContextStatusFromPercentage(percentage) {
41
- if (percentage >= THRESHOLDS.EMERGENCY)
42
- return "emergency";
43
- if (percentage >= THRESHOLDS.CRITICAL)
44
- return "critical";
45
- if (percentage >= THRESHOLDS.CAUTION)
46
- return "caution";
47
- if (percentage >= THRESHOLDS.WARNING)
48
- return "warning";
45
+ if (percentage >= THRESHOLDS.EMERGENCY) return "emergency";
46
+ if (percentage >= THRESHOLDS.CRITICAL) return "critical";
47
+ if (percentage >= THRESHOLDS.CAUTION) return "caution";
48
+ if (percentage >= THRESHOLDS.WARNING) return "warning";
49
49
  return "ok";
50
50
  }
51
51
  var THRESHOLDS, ClaudeCodeContextMonitorProvider;
52
52
  var init_context_monitor = __esm({
53
- "packages/adapters/src/providers/claude-code/context-monitor.js"() {
53
+ "packages/adapters/src/providers/claude-code/context-monitor.ts"() {
54
54
  "use strict";
55
55
  init_paths();
56
56
  THRESHOLDS = {
@@ -60,13 +60,14 @@ var init_context_monitor = __esm({
60
60
  EMERGENCY: 95
61
61
  };
62
62
  ClaudeCodeContextMonitorProvider = class {
63
+ /** Path provider for resolving Claude Code directory locations. */
63
64
  pathProvider = new ClaudeCodePathProvider();
65
+ /** Process raw context window JSON and return a formatted summary string. */
64
66
  async processContextInput(input, cwd) {
65
67
  const typed = input;
66
68
  const contextSize = typed.context_window?.context_window_size ?? 2e5;
67
69
  const usage = typed.context_window?.current_usage;
68
- if (!usage)
69
- return "-- no data";
70
+ if (!usage) return "-- no data";
70
71
  const inputTokens = usage.input_tokens ?? 0;
71
72
  const outputTokens = usage.output_tokens ?? 0;
72
73
  const cacheCreate = usage.cache_creation_input_tokens ?? 0;
@@ -110,17 +111,15 @@ var init_context_monitor = __esm({
110
111
  }
111
112
  return `${percentage}% | ${totalTokens}/${contextSize}`;
112
113
  }
114
+ /** Check the current statusline integration status in Claude Code settings. */
113
115
  checkStatuslineIntegration() {
114
116
  const settingsPath = this.pathProvider.getSettingsPath();
115
- if (!settingsPath || !existsSync(settingsPath))
116
- return "no_settings";
117
+ if (!settingsPath || !existsSync(settingsPath)) return "no_settings";
117
118
  try {
118
119
  const settings = JSON.parse(readFileSync(settingsPath, "utf-8"));
119
120
  const statusLine = settings.statusLine;
120
- if (!statusLine?.type)
121
- return "not_configured";
122
- if (statusLine.type !== "command")
123
- return "custom_no_cleo";
121
+ if (!statusLine?.type) return "not_configured";
122
+ if (statusLine.type !== "command") return "custom_no_cleo";
124
123
  const cmd = statusLine.command ?? "";
125
124
  if (cmd.includes("context-monitor.sh") || cmd.includes("cleo-statusline") || cmd.includes(".context-state.json") || cmd.includes("context-states")) {
126
125
  return "configured";
@@ -129,8 +128,7 @@ var init_context_monitor = __esm({
129
128
  if (existsSync(scriptPath)) {
130
129
  try {
131
130
  const content = readFileSync(scriptPath, "utf-8");
132
- if (content.includes("context-state.json"))
133
- return "configured";
131
+ if (content.includes("context-state.json")) return "configured";
134
132
  } catch {
135
133
  }
136
134
  }
@@ -139,6 +137,7 @@ var init_context_monitor = __esm({
139
137
  return "no_settings";
140
138
  }
141
139
  }
140
+ /** Get the recommended statusline configuration object for Claude Code settings. */
142
141
  getStatuslineConfig() {
143
142
  return {
144
143
  statusLine: {
@@ -147,6 +146,7 @@ var init_context_monitor = __esm({
147
146
  }
148
147
  };
149
148
  }
149
+ /** Get human-readable setup instructions for enabling context monitoring. */
150
150
  getSetupInstructions() {
151
151
  const settingsPath = this.pathProvider.getSettingsPath() ?? "~/.claude/settings.json";
152
152
  return [
@@ -162,24 +162,58 @@ var init_context_monitor = __esm({
162
162
  }
163
163
  });
164
164
 
165
- // packages/adapters/src/providers/claude-code/hooks.js
166
- var CLAUDE_CODE_EVENT_MAP, ClaudeCodeHookProvider;
165
+ // packages/adapters/src/providers/claude-code/hooks.ts
166
+ import { readdir, readFile } from "node:fs/promises";
167
+ import { join as join3 } from "node:path";
168
+ var PROVIDER_ID, CLAUDE_CODE_EVENT_MAP, ClaudeCodeHookProvider;
167
169
  var init_hooks = __esm({
168
- "packages/adapters/src/providers/claude-code/hooks.js"() {
170
+ "packages/adapters/src/providers/claude-code/hooks.ts"() {
169
171
  "use strict";
172
+ PROVIDER_ID = "claude-code";
170
173
  CLAUDE_CODE_EVENT_MAP = {
171
- SessionStart: "onSessionStart",
172
- PostToolUse: "onToolComplete",
173
- UserPromptSubmit: "onPromptSubmit",
174
- Stop: "onSessionEnd"
174
+ // CAAMP: toNative('SessionStart', 'claude-code') = 'SessionStart'
175
+ SessionStart: "SessionStart",
176
+ // CAAMP: toNative('SessionEnd', 'claude-code') = 'SessionEnd'
177
+ SessionEnd: "SessionEnd",
178
+ // CAAMP: toNative('PromptSubmit', 'claude-code') = 'UserPromptSubmit'
179
+ UserPromptSubmit: "PromptSubmit",
180
+ // CAAMP: toNative('ResponseComplete', 'claude-code') = 'Stop'
181
+ Stop: "ResponseComplete",
182
+ // CAAMP: toNative('PreToolUse', 'claude-code') = 'PreToolUse'
183
+ PreToolUse: "PreToolUse",
184
+ // CAAMP: toNative('PostToolUse', 'claude-code') = 'PostToolUse'
185
+ PostToolUse: "PostToolUse",
186
+ // CAAMP: toNative('PostToolUseFailure','claude-code') = 'PostToolUseFailure'
187
+ PostToolUseFailure: "PostToolUseFailure",
188
+ // CAAMP: toNative('PermissionRequest', 'claude-code') = 'PermissionRequest'
189
+ PermissionRequest: "PermissionRequest",
190
+ // CAAMP: toNative('SubagentStart', 'claude-code') = 'SubagentStart'
191
+ SubagentStart: "SubagentStart",
192
+ // CAAMP: toNative('SubagentStop', 'claude-code') = 'SubagentStop'
193
+ SubagentStop: "SubagentStop",
194
+ // CAAMP: toNative('PreCompact', 'claude-code') = 'PreCompact'
195
+ PreCompact: "PreCompact",
196
+ // CAAMP: toNative('PostCompact', 'claude-code') = 'PostCompact'
197
+ PostCompact: "PostCompact",
198
+ // CAAMP: toNative('Notification', 'claude-code') = 'Notification'
199
+ Notification: "Notification",
200
+ // CAAMP: toNative('ConfigChange', 'claude-code') = 'ConfigChange'
201
+ ConfigChange: "ConfigChange"
175
202
  };
176
203
  ClaudeCodeHookProvider = class {
204
+ /** Whether hooks have been registered for the current session. */
177
205
  registered = false;
178
206
  /**
179
- * Map a Claude Code native event name to a CAAMP hook event name.
207
+ * Map a Claude Code native event name to a CAAMP canonical hook event name.
208
+ *
209
+ * Looks up the native event name in the map derived from
210
+ * `getProviderHookProfile('claude-code').mappings` (CAAMP 1.9.1).
211
+ * Returns null for unrecognised events (e.g. PreModel, PostModel which
212
+ * Claude Code does not support).
180
213
  *
181
- * @param providerEvent - Claude Code event name (e.g. "SessionStart", "PostToolUse")
182
- * @returns CAAMP event name or null if unmapped
214
+ * @param providerEvent - Claude Code native event (e.g. "UserPromptSubmit", "Stop")
215
+ * @returns CAAMP canonical event name, or null if unmapped
216
+ * @task T164
183
217
  */
184
218
  mapProviderEvent(providerEvent) {
185
219
  return CLAUDE_CODE_EVENT_MAP[providerEvent] ?? null;
@@ -187,12 +221,15 @@ var init_hooks = __esm({
187
221
  /**
188
222
  * Register native hooks for a project.
189
223
  *
190
- * For Claude Code, hooks are registered via the plugin system
191
- * (hooks.json descriptor), which is handled by the
192
- * install provider. This method is a no-op since registration
193
- * is managed through the plugin install lifecycle.
224
+ * For Claude Code, hooks are registered via the config system
225
+ * (`~/.claude/settings.json`), managed by the install provider.
226
+ * This method marks hooks as registered without performing filesystem operations.
194
227
  *
195
- * @param _projectDir - Project directory (unused; hooks are global)
228
+ * Iterating supported events is handled at install time using
229
+ * `getSupportedCanonicalEvents()` to enumerate all 14 supported hooks.
230
+ *
231
+ * @param _projectDir - Project directory (unused; Claude Code uses global config)
232
+ * @task T164
196
233
  */
197
234
  async registerNativeHooks(_projectDir) {
198
235
  this.registered = true;
@@ -200,111 +237,206 @@ var init_hooks = __esm({
200
237
  /**
201
238
  * Unregister native hooks.
202
239
  *
203
- * For Claude Code, this is a no-op since hooks are managed through
204
- * the plugin system. Unregistration happens via the install provider's
205
- * uninstall method.
240
+ * For Claude Code, this is a no-op since hooks are managed through the config
241
+ * system. Unregistration happens via the install provider's uninstall method.
242
+ *
243
+ * @task T164
206
244
  */
207
245
  async unregisterNativeHooks() {
208
246
  this.registered = false;
209
247
  }
210
248
  /**
211
- * Check whether hooks have been registered via registerNativeHooks.
249
+ * Check whether hooks have been registered via `registerNativeHooks`.
212
250
  */
213
251
  isRegistered() {
214
252
  return this.registered;
215
253
  }
216
254
  /**
217
- * Get the full event mapping for introspection/debugging.
255
+ * Get the native→canonical event mapping for introspection and debugging.
256
+ *
257
+ * Returns the map derived from `getProviderHookProfile('claude-code').mappings`
258
+ * (CAAMP 1.9.1). Use `getSupportedCanonicalEvents()` to enumerate canonical
259
+ * names via live CAAMP APIs.
260
+ *
261
+ * @returns Immutable record of native event name → canonical event name
218
262
  */
219
263
  getEventMap() {
220
264
  return { ...CLAUDE_CODE_EVENT_MAP };
221
265
  }
266
+ /**
267
+ * Enumerate supported canonical events via CAAMP's `getSupportedEvents()`.
268
+ *
269
+ * Calls `getSupportedEvents('claude-code')` from the CAAMP normalizer to
270
+ * get the authoritative list. Claude Code supports 14 of 16 canonical events
271
+ * (PreModel and PostModel are not supported). Falls back to the values of
272
+ * the static event map when CAAMP is unavailable at runtime.
273
+ *
274
+ * @returns Array of CAAMP canonical event names supported by Claude Code
275
+ * @task T164
276
+ */
277
+ async getSupportedCanonicalEvents() {
278
+ try {
279
+ const { getSupportedEvents } = await import("@cleocode/caamp");
280
+ return getSupportedEvents(PROVIDER_ID);
281
+ } catch {
282
+ return [...new Set(Object.values(CLAUDE_CODE_EVENT_MAP))];
283
+ }
284
+ }
285
+ /**
286
+ * Retrieve the full provider hook profile from CAAMP.
287
+ *
288
+ * Calls `getProviderHookProfile('claude-code')` from the CAAMP normalizer to
289
+ * get the complete profile: hook system type (`config`), config path
290
+ * (`~/.claude/settings.json`), handler types, and all event mappings.
291
+ * Returns null when CAAMP is unavailable at runtime.
292
+ *
293
+ * @returns Provider hook profile or null if CAAMP is unavailable
294
+ * @task T164
295
+ */
296
+ async getProviderProfile() {
297
+ try {
298
+ const { getProviderHookProfile } = await import("@cleocode/caamp");
299
+ return getProviderHookProfile(PROVIDER_ID) ?? null;
300
+ } catch {
301
+ return null;
302
+ }
303
+ }
304
+ /**
305
+ * Translate a CAAMP canonical event to its Claude Code native name via CAAMP.
306
+ *
307
+ * Calls `toNative(canonical, 'claude-code')` from the CAAMP normalizer.
308
+ * Returns null for unsupported events (PreModel, PostModel) or when
309
+ * CAAMP is unavailable.
310
+ *
311
+ * @param canonical - CAAMP canonical event name (e.g. "PromptSubmit")
312
+ * @returns Claude Code native event name or null
313
+ * @task T164
314
+ */
315
+ async toNativeEvent(canonical) {
316
+ try {
317
+ const { toNative } = await import("@cleocode/caamp");
318
+ return toNative(canonical, PROVIDER_ID);
319
+ } catch {
320
+ const entry = Object.entries(CLAUDE_CODE_EVENT_MAP).find(([, v]) => v === canonical);
321
+ return entry?.[0] ?? null;
322
+ }
323
+ }
324
+ /**
325
+ * Extract a plain-text transcript from Claude Code session JSONL files.
326
+ *
327
+ * Reads the most recent .jsonl file under `~/.claude/projects/` and
328
+ * extracts user/assistant turn text into a flat string for brain
329
+ * observation extraction.
330
+ *
331
+ * Returns null when no session data is found or on any read error.
332
+ *
333
+ * @param _sessionId - CLEO session ID (unused; reads the most recent file)
334
+ * @param _projectDir - Project directory (unused; Claude Code uses global paths)
335
+ * @task T144 @epic T134
336
+ */
337
+ async getTranscript(_sessionId, _projectDir) {
338
+ try {
339
+ const homeDir = process.env.HOME ?? process.env.USERPROFILE ?? "/root";
340
+ const projectsDir = join3(homeDir, ".claude", "projects");
341
+ let allFiles = [];
342
+ try {
343
+ const projectDirs = await readdir(projectsDir, { withFileTypes: true });
344
+ for (const entry of projectDirs) {
345
+ if (!entry.isDirectory()) continue;
346
+ const subDir = join3(projectsDir, entry.name);
347
+ try {
348
+ const files = await readdir(subDir);
349
+ for (const file of files) {
350
+ if (!file.endsWith(".jsonl")) continue;
351
+ const filePath = join3(subDir, file);
352
+ allFiles.push({ path: filePath, mtime: 0 });
353
+ }
354
+ } catch {
355
+ }
356
+ }
357
+ } catch {
358
+ return null;
359
+ }
360
+ if (allFiles.length === 0) return null;
361
+ allFiles = allFiles.sort((a, b) => b.path.localeCompare(a.path));
362
+ const mostRecent = allFiles[0];
363
+ if (!mostRecent) return null;
364
+ const raw = await readFile(mostRecent.path, "utf-8");
365
+ const lines = raw.split("\n").filter((l) => l.trim());
366
+ const turns = [];
367
+ for (const line of lines) {
368
+ try {
369
+ const entry = JSON.parse(line);
370
+ const role = entry.role;
371
+ const content = entry.content;
372
+ if (role === "assistant" && typeof content === "string") {
373
+ turns.push(`assistant: ${content}`);
374
+ } else if (role === "user" && typeof content === "string") {
375
+ turns.push(`user: ${content}`);
376
+ }
377
+ } catch {
378
+ }
379
+ }
380
+ return turns.length > 0 ? turns.join("\n") : null;
381
+ } catch {
382
+ return null;
383
+ }
384
+ }
222
385
  };
223
386
  }
224
387
  });
225
388
 
226
- // packages/adapters/src/providers/claude-code/install.js
389
+ // packages/adapters/src/providers/claude-code/install.ts
227
390
  import { existsSync as existsSync2, mkdirSync, readFileSync as readFileSync2, writeFileSync as writeFileSync2 } from "node:fs";
228
391
  import { homedir as homedir3 } from "node:os";
229
- import { join as join3 } from "node:path";
230
- var INSTRUCTION_REFERENCES, MCP_SERVER_KEY, ClaudeCodeInstallProvider;
392
+ import { join as join4 } from "node:path";
393
+ var INSTRUCTION_REFERENCES, ClaudeCodeInstallProvider;
231
394
  var init_install = __esm({
232
- "packages/adapters/src/providers/claude-code/install.js"() {
395
+ "packages/adapters/src/providers/claude-code/install.ts"() {
233
396
  "use strict";
234
397
  INSTRUCTION_REFERENCES = ["@~/.cleo/templates/CLEO-INJECTION.md", "@.cleo/memory-bridge.md"];
235
- MCP_SERVER_KEY = "cleo";
236
398
  ClaudeCodeInstallProvider = class {
237
- installedProjectDir = null;
238
399
  /**
239
400
  * Install CLEO into a Claude Code project.
240
401
  *
241
- * @param options - Installation options including project directory and MCP server path
402
+ * @param options - Installation options including project directory
242
403
  * @returns Result describing what was installed
243
404
  */
244
405
  async install(options) {
245
- const { projectDir, mcpServerPath } = options;
406
+ const { projectDir } = options;
246
407
  const installedAt = (/* @__PURE__ */ new Date()).toISOString();
247
408
  let instructionFileUpdated = false;
248
- let mcpRegistered = false;
249
409
  const details = {};
250
- if (mcpServerPath) {
251
- mcpRegistered = this.registerMcpServer(projectDir, mcpServerPath);
252
- if (mcpRegistered) {
253
- details.mcpConfigPath = join3(projectDir, ".mcp.json");
254
- }
255
- }
256
410
  instructionFileUpdated = this.updateInstructionFile(projectDir);
257
411
  if (instructionFileUpdated) {
258
- details.instructionFile = join3(projectDir, "CLAUDE.md");
412
+ details.instructionFile = join4(projectDir, "CLAUDE.md");
259
413
  }
260
414
  const pluginResult = this.registerPlugin();
261
415
  if (pluginResult) {
262
416
  details.plugin = pluginResult;
263
417
  }
264
- this.installedProjectDir = projectDir;
265
418
  return {
266
419
  success: true,
267
420
  installedAt,
268
421
  instructionFileUpdated,
269
- mcpRegistered,
422
+ mcpRegistered: false,
270
423
  details
271
424
  };
272
425
  }
273
426
  /**
274
427
  * Uninstall CLEO from the current Claude Code project.
275
428
  *
276
- * Removes the MCP server registration from .mcp.json.
277
429
  * Does not remove CLAUDE.md references (they are harmless if CLEO is not present).
278
430
  */
279
431
  async uninstall() {
280
- if (!this.installedProjectDir)
281
- return;
282
- const mcpPath = join3(this.installedProjectDir, ".mcp.json");
283
- if (existsSync2(mcpPath)) {
284
- try {
285
- const raw = readFileSync2(mcpPath, "utf-8");
286
- const config = JSON.parse(raw);
287
- const mcpServers = config.mcpServers;
288
- if (mcpServers && MCP_SERVER_KEY in mcpServers) {
289
- delete mcpServers[MCP_SERVER_KEY];
290
- writeFileSync2(mcpPath, JSON.stringify(config, null, 2) + "\n", "utf-8");
291
- }
292
- } catch {
293
- }
294
- }
295
- this.installedProjectDir = null;
296
432
  }
297
433
  /**
298
434
  * Check whether CLEO is installed in the current environment.
299
435
  *
300
- * Checks for:
301
- * 1. MCP server registered in .mcp.json
302
- * 2. Plugin enabled in ~/.claude/settings.json
303
- *
304
- * Returns true if either condition is met (partial install counts).
436
+ * Checks for plugin enabled in ~/.claude/settings.json.
305
437
  */
306
438
  async isInstalled() {
307
- const settingsPath = join3(homedir3(), ".claude", "settings.json");
439
+ const settingsPath = join4(homedir3(), ".claude", "settings.json");
308
440
  if (existsSync2(settingsPath)) {
309
441
  try {
310
442
  const settings = JSON.parse(readFileSync2(settingsPath, "utf-8"));
@@ -315,17 +447,6 @@ var init_install = __esm({
315
447
  } catch {
316
448
  }
317
449
  }
318
- const mcpPath = join3(process.cwd(), ".mcp.json");
319
- if (existsSync2(mcpPath)) {
320
- try {
321
- const config = JSON.parse(readFileSync2(mcpPath, "utf-8"));
322
- const mcpServers = config.mcpServers;
323
- if (mcpServers && MCP_SERVER_KEY in mcpServers) {
324
- return true;
325
- }
326
- } catch {
327
- }
328
- }
329
450
  return false;
330
451
  }
331
452
  /**
@@ -338,38 +459,13 @@ var init_install = __esm({
338
459
  async ensureInstructionReferences(projectDir) {
339
460
  this.updateInstructionFile(projectDir);
340
461
  }
341
- /**
342
- * Register the CLEO MCP server in .mcp.json.
343
- *
344
- * @returns true if registration was performed or updated
345
- */
346
- registerMcpServer(projectDir, mcpServerPath) {
347
- const mcpPath = join3(projectDir, ".mcp.json");
348
- let config = {};
349
- if (existsSync2(mcpPath)) {
350
- try {
351
- config = JSON.parse(readFileSync2(mcpPath, "utf-8"));
352
- } catch {
353
- }
354
- }
355
- if (!config.mcpServers || typeof config.mcpServers !== "object") {
356
- config.mcpServers = {};
357
- }
358
- const mcpServers = config.mcpServers;
359
- mcpServers[MCP_SERVER_KEY] = {
360
- command: "node",
361
- args: [mcpServerPath]
362
- };
363
- writeFileSync2(mcpPath, JSON.stringify(config, null, 2) + "\n", "utf-8");
364
- return true;
365
- }
366
462
  /**
367
463
  * Update CLAUDE.md with CLEO @-references.
368
464
  *
369
465
  * @returns true if the file was created or modified
370
466
  */
371
467
  updateInstructionFile(projectDir) {
372
- const claudeMdPath = join3(projectDir, "CLAUDE.md");
468
+ const claudeMdPath = join4(projectDir, "CLAUDE.md");
373
469
  let content = "";
374
470
  let existed = false;
375
471
  if (existsSync2(claudeMdPath)) {
@@ -397,7 +493,7 @@ var init_install = __esm({
397
493
  */
398
494
  registerPlugin() {
399
495
  const home = homedir3();
400
- const settingsPath = join3(home, ".claude", "settings.json");
496
+ const settingsPath = join4(home, ".claude", "settings.json");
401
497
  let settings = {};
402
498
  if (existsSync2(settingsPath)) {
403
499
  try {
@@ -415,7 +511,7 @@ var init_install = __esm({
415
511
  }
416
512
  enabledPlugins[pluginKey] = true;
417
513
  settings.enabledPlugins = enabledPlugins;
418
- mkdirSync(join3(home, ".claude"), { recursive: true });
514
+ mkdirSync(join4(home, ".claude"), { recursive: true });
419
515
  writeFileSync2(settingsPath, JSON.stringify(settings, null, 2) + "\n", "utf-8");
420
516
  return `Enabled ${pluginKey} in ~/.claude/settings.json`;
421
517
  }
@@ -550,6 +646,13 @@ var init_operations = __esm({
550
646
  }
551
647
  });
552
648
 
649
+ // packages/contracts/src/orchestration-hierarchy.ts
650
+ var init_orchestration_hierarchy = __esm({
651
+ "packages/contracts/src/orchestration-hierarchy.ts"() {
652
+ "use strict";
653
+ }
654
+ });
655
+
553
656
  // packages/contracts/src/session.ts
554
657
  var init_session2 = __esm({
555
658
  "packages/contracts/src/session.ts"() {
@@ -579,19 +682,20 @@ var init_src = __esm({
579
682
  init_facade();
580
683
  init_lafs();
581
684
  init_operations();
685
+ init_orchestration_hierarchy();
582
686
  init_session2();
583
687
  init_status_registry();
584
688
  init_wasm();
585
689
  }
586
690
  });
587
691
 
588
- // packages/adapters/src/providers/claude-code/spawn.js
692
+ // packages/adapters/src/providers/claude-code/spawn.ts
589
693
  import { exec, spawn as nodeSpawn } from "node:child_process";
590
694
  import { unlink, writeFile } from "node:fs/promises";
591
695
  import { promisify } from "node:util";
592
696
  var execAsync, ClaudeCodeSpawnProvider;
593
697
  var init_spawn = __esm({
594
- "packages/adapters/src/providers/claude-code/spawn.js"() {
698
+ "packages/adapters/src/providers/claude-code/spawn.ts"() {
595
699
  "use strict";
596
700
  init_src();
597
701
  execAsync = promisify(exec);
@@ -714,8 +818,7 @@ var init_spawn = __esm({
714
818
  */
715
819
  async terminate(instanceId) {
716
820
  const tracked = this.processMap.get(instanceId);
717
- if (!tracked)
718
- return;
821
+ if (!tracked) return;
719
822
  try {
720
823
  process.kill(tracked.pid, "SIGTERM");
721
824
  } catch {
@@ -726,9 +829,9 @@ var init_spawn = __esm({
726
829
  }
727
830
  });
728
831
 
729
- // packages/adapters/src/providers/claude-code/task-sync.js
730
- import { readFile, rm, stat } from "node:fs/promises";
731
- import { join as join4 } from "node:path";
832
+ // packages/adapters/src/providers/claude-code/task-sync.ts
833
+ import { readFile as readFile2, stat } from "node:fs/promises";
834
+ import { join as join5 } from "node:path";
732
835
  function parseTaskId(content) {
733
836
  const match = content.match(/^\[T(\d+)\]/);
734
837
  return match ? `T${match[1]}` : null;
@@ -749,17 +852,19 @@ function mapStatus(twStatus) {
749
852
  }
750
853
  }
751
854
  function getTodoWriteFilePath(projectDir) {
752
- return join4(projectDir, ".cleo", "sync", "todowrite-state.json");
855
+ return join5(projectDir, ".cleo", "sync", "todowrite-state.json");
753
856
  }
754
857
  var ClaudeCodeTaskSyncProvider;
755
858
  var init_task_sync = __esm({
756
- "packages/adapters/src/providers/claude-code/task-sync.js"() {
859
+ "packages/adapters/src/providers/claude-code/task-sync.ts"() {
757
860
  "use strict";
758
861
  ClaudeCodeTaskSyncProvider = class {
862
+ /** Optional override path for the TodoWrite state file (used in tests). */
759
863
  customFilePath;
760
864
  constructor(options) {
761
865
  this.customFilePath = options?.filePath;
762
866
  }
867
+ /** Retrieve external tasks from Claude's TodoWrite state file. */
763
868
  async getExternalTasks(projectDir) {
764
869
  const filePath = this.customFilePath ?? getTodoWriteFilePath(projectDir);
765
870
  try {
@@ -767,7 +872,7 @@ var init_task_sync = __esm({
767
872
  } catch {
768
873
  return [];
769
874
  }
770
- const raw = await readFile(filePath, "utf-8");
875
+ const raw = await readFile2(filePath, "utf-8");
771
876
  let state;
772
877
  try {
773
878
  state = JSON.parse(raw);
@@ -782,15 +887,14 @@ var init_task_sync = __esm({
782
887
  for (const item of state.todos) {
783
888
  const cleoTaskId = parseTaskId(item.content);
784
889
  const title = cleoTaskId ? stripPrefixes(item.content).trim() : item.content.trim();
785
- if (!title)
786
- continue;
890
+ if (!title) continue;
787
891
  tasks.push({
788
892
  externalId: cleoTaskId ?? `tw-new-${syntheticIndex++}`,
789
- cleoTaskId,
790
893
  title,
791
894
  status: mapStatus(item.status),
792
895
  providerMeta: {
793
896
  source: "todowrite",
897
+ cleoTaskId,
794
898
  activeForm: item.activeForm,
795
899
  rawContent: item.content
796
900
  }
@@ -798,24 +902,19 @@ var init_task_sync = __esm({
798
902
  }
799
903
  return tasks;
800
904
  }
801
- async cleanup(projectDir) {
802
- const filePath = this.customFilePath ?? getTodoWriteFilePath(projectDir);
803
- try {
804
- await rm(filePath);
805
- } catch {
806
- }
807
- }
808
905
  };
809
906
  }
810
907
  });
811
908
 
812
- // packages/adapters/src/providers/claude-code/transport.js
909
+ // packages/adapters/src/providers/claude-code/transport.ts
813
910
  var ClaudeCodeTransportProvider;
814
911
  var init_transport = __esm({
815
- "packages/adapters/src/providers/claude-code/transport.js"() {
912
+ "packages/adapters/src/providers/claude-code/transport.ts"() {
816
913
  "use strict";
817
914
  ClaudeCodeTransportProvider = class {
915
+ /** Provider-specific transport name used for capability negotiation. */
818
916
  transportName = "claude-code";
917
+ /** Create a transport instance for inter-agent messaging. */
819
918
  createTransport() {
820
919
  return null;
821
920
  }
@@ -823,15 +922,15 @@ var init_transport = __esm({
823
922
  }
824
923
  });
825
924
 
826
- // packages/adapters/src/providers/claude-code/adapter.js
925
+ // packages/adapters/src/providers/claude-code/adapter.ts
827
926
  import { exec as exec2 } from "node:child_process";
828
927
  import { existsSync as existsSync3 } from "node:fs";
829
928
  import { homedir as homedir4 } from "node:os";
830
- import { join as join5 } from "node:path";
929
+ import { join as join6 } from "node:path";
831
930
  import { promisify as promisify2 } from "node:util";
832
931
  var execAsync2, ClaudeCodeAdapter;
833
932
  var init_adapter = __esm({
834
- "packages/adapters/src/providers/claude-code/adapter.js"() {
933
+ "packages/adapters/src/providers/claude-code/adapter.ts"() {
835
934
  "use strict";
836
935
  init_context_monitor();
837
936
  init_hooks();
@@ -842,21 +941,36 @@ var init_adapter = __esm({
842
941
  init_transport();
843
942
  execAsync2 = promisify2(exec2);
844
943
  ClaudeCodeAdapter = class {
944
+ /** Unique provider identifier. */
845
945
  id = "claude-code";
946
+ /** Human-readable provider name. */
846
947
  name = "Claude Code";
948
+ /** Adapter version string. */
847
949
  version = "1.0.0";
950
+ /** Declared capabilities for this provider. */
848
951
  capabilities = {
849
952
  supportsHooks: true,
953
+ // 14/16 canonical events — derived from getProviderHookProfile('claude-code') in CAAMP 1.9.1.
954
+ // PreModel and PostModel are not supported by Claude Code.
850
955
  supportedHookEvents: [
851
- "onSessionStart",
852
- "onSessionEnd",
853
- "onToolStart",
854
- "onToolComplete",
855
- "onError"
956
+ "SessionStart",
957
+ "SessionEnd",
958
+ "PromptSubmit",
959
+ "ResponseComplete",
960
+ "PreToolUse",
961
+ "PostToolUse",
962
+ "PostToolUseFailure",
963
+ "PermissionRequest",
964
+ "SubagentStart",
965
+ "SubagentStop",
966
+ "PreCompact",
967
+ "PostCompact",
968
+ "Notification",
969
+ "ConfigChange"
856
970
  ],
857
971
  supportsSpawn: true,
858
972
  supportsInstall: true,
859
- supportsMcp: true,
973
+ supportsMcp: false,
860
974
  supportsInstructionFiles: true,
861
975
  instructionFilePattern: "CLAUDE.md",
862
976
  supportsContextMonitor: true,
@@ -865,14 +979,23 @@ var init_adapter = __esm({
865
979
  supportsTransport: true,
866
980
  supportsTaskSync: true
867
981
  };
982
+ /** Hook provider for CAAMP event mapping and registration. */
868
983
  hooks;
984
+ /** Spawn provider for launching subagent processes via `claude` CLI. */
869
985
  spawn;
986
+ /** Install provider for managing instruction files and plugin registration. */
870
987
  install;
988
+ /** Path provider for resolving Claude Code directory locations. */
871
989
  paths;
990
+ /** Context monitor for tracking context window usage and statusline output. */
872
991
  contextMonitor;
992
+ /** Transport provider for inter-agent communication. */
873
993
  transport;
994
+ /** Task sync provider bridging Claude's TodoWrite format to CLEO tasks. */
874
995
  taskSync;
996
+ /** Project directory this adapter was initialized with, or null. */
875
997
  projectDir = null;
998
+ /** Whether {@link initialize} has been called. */
876
999
  initialized = false;
877
1000
  constructor() {
878
1001
  this.hooks = new ClaudeCodeHookProvider();
@@ -934,7 +1057,7 @@ var init_adapter = __esm({
934
1057
  } catch {
935
1058
  details.cliAvailable = false;
936
1059
  }
937
- const claudeConfigDir = join5(homedir4(), ".claude");
1060
+ const claudeConfigDir = join6(homedir4(), ".claude");
938
1061
  const configExists = existsSync3(claudeConfigDir);
939
1062
  details.configDirExists = configExists;
940
1063
  const entrypointSet = process.env.CLAUDE_CODE_ENTRYPOINT !== void 0;
@@ -963,24 +1086,21 @@ var init_adapter = __esm({
963
1086
  }
964
1087
  });
965
1088
 
966
- // packages/adapters/src/providers/claude-code/statusline.js
1089
+ // packages/adapters/src/providers/claude-code/statusline.ts
967
1090
  import { existsSync as existsSync4, readFileSync as readFileSync3 } from "node:fs";
968
1091
  import { homedir as homedir5 } from "node:os";
969
- import { join as join6 } from "node:path";
1092
+ import { join as join7 } from "node:path";
970
1093
  function getClaudeSettingsPath() {
971
- return process.env["CLAUDE_SETTINGS"] ?? join6(process.env["CLAUDE_HOME"] ?? join6(homedir5(), ".claude"), "settings.json");
1094
+ return process.env["CLAUDE_SETTINGS"] ?? join7(process.env["CLAUDE_HOME"] ?? join7(homedir5(), ".claude"), "settings.json");
972
1095
  }
973
1096
  function checkStatuslineIntegration() {
974
1097
  const settingsPath = getClaudeSettingsPath();
975
- if (!existsSync4(settingsPath))
976
- return "no_settings";
1098
+ if (!existsSync4(settingsPath)) return "no_settings";
977
1099
  try {
978
1100
  const settings = JSON.parse(readFileSync3(settingsPath, "utf-8"));
979
1101
  const statusLine = settings.statusLine;
980
- if (!statusLine?.type)
981
- return "not_configured";
982
- if (statusLine.type !== "command")
983
- return "custom_no_cleo";
1102
+ if (!statusLine?.type) return "not_configured";
1103
+ if (statusLine.type !== "command") return "custom_no_cleo";
984
1104
  const cmd = statusLine.command ?? "";
985
1105
  if (cmd.includes("context-monitor.sh") || cmd.includes("cleo-statusline") || cmd.includes(".context-state.json") || cmd.includes("context-states")) {
986
1106
  return "configured";
@@ -989,8 +1109,7 @@ function checkStatuslineIntegration() {
989
1109
  if (existsSync4(scriptPath)) {
990
1110
  try {
991
1111
  const content = readFileSync3(scriptPath, "utf-8");
992
- if (content.includes("context-state.json"))
993
- return "configured";
1112
+ if (content.includes("context-state.json")) return "configured";
994
1113
  } catch {
995
1114
  }
996
1115
  }
@@ -1003,7 +1122,7 @@ function getStatuslineConfig(cleoHome) {
1003
1122
  return {
1004
1123
  statusLine: {
1005
1124
  type: "command",
1006
- command: join6(cleoHome, "lib", "session", "context-monitor.sh")
1125
+ command: join7(cleoHome, "lib", "session", "context-monitor.sh")
1007
1126
  }
1008
1127
  };
1009
1128
  }
@@ -1019,12 +1138,12 @@ function getSetupInstructions(cleoHome) {
1019
1138
  ].join("\n");
1020
1139
  }
1021
1140
  var init_statusline = __esm({
1022
- "packages/adapters/src/providers/claude-code/statusline.js"() {
1141
+ "packages/adapters/src/providers/claude-code/statusline.ts"() {
1023
1142
  "use strict";
1024
1143
  }
1025
1144
  });
1026
1145
 
1027
- // packages/adapters/src/providers/claude-code/index.js
1146
+ // packages/adapters/src/providers/claude-code/index.ts
1028
1147
  var claude_code_exports = {};
1029
1148
  __export(claude_code_exports, {
1030
1149
  ClaudeCodeAdapter: () => ClaudeCodeAdapter,
@@ -1045,7 +1164,7 @@ function createAdapter() {
1045
1164
  }
1046
1165
  var claude_code_default;
1047
1166
  var init_claude_code = __esm({
1048
- "packages/adapters/src/providers/claude-code/index.js"() {
1167
+ "packages/adapters/src/providers/claude-code/index.ts"() {
1049
1168
  "use strict";
1050
1169
  init_adapter();
1051
1170
  init_adapter();
@@ -1060,30 +1179,66 @@ var init_claude_code = __esm({
1060
1179
  }
1061
1180
  });
1062
1181
 
1063
- // packages/adapters/src/providers/cursor/hooks.js
1064
- var CursorHookProvider;
1182
+ // packages/adapters/src/providers/cursor/hooks.ts
1183
+ var PROVIDER_ID2, CURSOR_EVENT_MAP, CursorHookProvider;
1065
1184
  var init_hooks2 = __esm({
1066
- "packages/adapters/src/providers/cursor/hooks.js"() {
1185
+ "packages/adapters/src/providers/cursor/hooks.ts"() {
1067
1186
  "use strict";
1187
+ PROVIDER_ID2 = "cursor";
1188
+ CURSOR_EVENT_MAP = {
1189
+ // CAAMP: toNative('SessionStart', 'cursor') = 'sessionStart'
1190
+ sessionStart: "SessionStart",
1191
+ // CAAMP: toNative('SessionEnd', 'cursor') = 'sessionEnd'
1192
+ sessionEnd: "SessionEnd",
1193
+ // CAAMP: toNative('PromptSubmit', 'cursor') = 'beforeSubmitPrompt'
1194
+ beforeSubmitPrompt: "PromptSubmit",
1195
+ // CAAMP: toNative('ResponseComplete', 'cursor') = 'stop'
1196
+ stop: "ResponseComplete",
1197
+ // CAAMP: toNative('PreToolUse', 'cursor') = 'preToolUse'
1198
+ preToolUse: "PreToolUse",
1199
+ // CAAMP: toNative('PostToolUse', 'cursor') = 'postToolUse'
1200
+ postToolUse: "PostToolUse",
1201
+ // CAAMP: toNative('PostToolUseFailure', 'cursor') = 'postToolUseFailure'
1202
+ postToolUseFailure: "PostToolUseFailure",
1203
+ // CAAMP: toNative('SubagentStart', 'cursor') = 'subagentStart'
1204
+ subagentStart: "SubagentStart",
1205
+ // CAAMP: toNative('SubagentStop', 'cursor') = 'subagentStop'
1206
+ subagentStop: "SubagentStop",
1207
+ // CAAMP: toNative('PreCompact', 'cursor') = 'preCompact'
1208
+ preCompact: "PreCompact"
1209
+ };
1068
1210
  CursorHookProvider = class {
1211
+ /** Whether hooks have been registered for the current session. */
1069
1212
  registered = false;
1070
1213
  /**
1071
- * Map a provider event name to a CAAMP hook event name.
1214
+ * Map a Cursor native event name to a CAAMP canonical hook event name.
1072
1215
  *
1073
- * Always returns null since Cursor does not emit hook events.
1216
+ * Looks up the native event name in the map derived from
1217
+ * `getProviderHookProfile('cursor').mappings` (CAAMP 1.9.1). Cursor uses
1218
+ * camelCase names (e.g. "preToolUse", "sessionStart").
1074
1219
  *
1075
- * @param _providerEvent - Ignored; Cursor has no hook events
1076
- * @returns null (no mapping available)
1220
+ * Returns null for unsupported events (PermissionRequest, PreModel,
1221
+ * PostModel, PostCompact, Notification, ConfigChange).
1222
+ *
1223
+ * @param providerEvent - Cursor native event name (e.g. "preToolUse", "sessionStart")
1224
+ * @returns CAAMP canonical event name, or null if unmapped
1225
+ * @task T165
1077
1226
  */
1078
- mapProviderEvent(_providerEvent) {
1079
- return null;
1227
+ mapProviderEvent(providerEvent) {
1228
+ return CURSOR_EVENT_MAP[providerEvent] ?? null;
1080
1229
  }
1081
1230
  /**
1082
1231
  * Register native hooks for a project.
1083
1232
  *
1084
- * No-op for Cursor since it has no hook system.
1233
+ * For Cursor, hooks are registered via the config system
1234
+ * (`.cursor/hooks.json`), managed by the install provider.
1235
+ * This method marks hooks as registered without performing filesystem operations.
1085
1236
  *
1086
- * @param _projectDir - Ignored
1237
+ * Iterating supported events is handled at install time using
1238
+ * `getSupportedCanonicalEvents()` to enumerate all 10 supported hooks.
1239
+ *
1240
+ * @param _projectDir - Project directory (unused; Cursor config manages registration)
1241
+ * @task T165
1087
1242
  */
1088
1243
  async registerNativeHooks(_projectDir) {
1089
1244
  this.registered = true;
@@ -1091,99 +1246,146 @@ var init_hooks2 = __esm({
1091
1246
  /**
1092
1247
  * Unregister native hooks.
1093
1248
  *
1094
- * No-op for Cursor since it has no hook system.
1249
+ * For Cursor, this is a no-op since hooks are managed through the config
1250
+ * system. Unregistration happens via the install provider's uninstall method.
1251
+ *
1252
+ * @task T165
1095
1253
  */
1096
1254
  async unregisterNativeHooks() {
1097
1255
  this.registered = false;
1098
1256
  }
1099
1257
  /**
1100
- * Check whether hooks have been registered.
1258
+ * Check whether hooks have been registered via `registerNativeHooks`.
1101
1259
  */
1102
1260
  isRegistered() {
1103
1261
  return this.registered;
1104
1262
  }
1263
+ /**
1264
+ * Get the native→canonical event mapping for introspection and debugging.
1265
+ *
1266
+ * Returns the map derived from `getProviderHookProfile('cursor').mappings`
1267
+ * (CAAMP 1.9.1). Use `getSupportedCanonicalEvents()` to enumerate canonical
1268
+ * names via live CAAMP APIs.
1269
+ *
1270
+ * @returns Immutable record of native event name → canonical event name
1271
+ */
1272
+ getEventMap() {
1273
+ return { ...CURSOR_EVENT_MAP };
1274
+ }
1275
+ /**
1276
+ * Enumerate supported canonical events via CAAMP's `getSupportedEvents()`.
1277
+ *
1278
+ * Calls `getSupportedEvents('cursor')` from the CAAMP normalizer to get the
1279
+ * authoritative list. Cursor supports 10 of 16 canonical events. Falls back
1280
+ * to the values of the static event map when CAAMP is unavailable at runtime.
1281
+ *
1282
+ * @returns Array of CAAMP canonical event names supported by Cursor
1283
+ * @task T165
1284
+ */
1285
+ async getSupportedCanonicalEvents() {
1286
+ try {
1287
+ const { getSupportedEvents } = await import("@cleocode/caamp");
1288
+ return getSupportedEvents(PROVIDER_ID2);
1289
+ } catch {
1290
+ return [...new Set(Object.values(CURSOR_EVENT_MAP))];
1291
+ }
1292
+ }
1293
+ /**
1294
+ * Retrieve the full provider hook profile from CAAMP.
1295
+ *
1296
+ * Calls `getProviderHookProfile('cursor')` from the CAAMP normalizer to
1297
+ * get the complete profile: hook system type (`config`), config path
1298
+ * (`.cursor/hooks.json`), handler types (command, prompt), and all event
1299
+ * mappings. Returns null when CAAMP is unavailable at runtime.
1300
+ *
1301
+ * @returns Provider hook profile or null if CAAMP is unavailable
1302
+ * @task T165
1303
+ */
1304
+ async getProviderProfile() {
1305
+ try {
1306
+ const { getProviderHookProfile } = await import("@cleocode/caamp");
1307
+ return getProviderHookProfile(PROVIDER_ID2) ?? null;
1308
+ } catch {
1309
+ return null;
1310
+ }
1311
+ }
1312
+ /**
1313
+ * Translate a CAAMP canonical event to its Cursor native name via CAAMP.
1314
+ *
1315
+ * Calls `toNative(canonical, 'cursor')` from the CAAMP normalizer.
1316
+ * Returns null for unsupported events or when CAAMP is unavailable.
1317
+ *
1318
+ * @param canonical - CAAMP canonical event name (e.g. "PreToolUse")
1319
+ * @returns Cursor native event name (e.g. "preToolUse") or null
1320
+ * @task T165
1321
+ */
1322
+ async toNativeEvent(canonical) {
1323
+ try {
1324
+ const { toNative } = await import("@cleocode/caamp");
1325
+ return toNative(canonical, PROVIDER_ID2);
1326
+ } catch {
1327
+ const entry = Object.entries(CURSOR_EVENT_MAP).find(([, v]) => v === canonical);
1328
+ return entry?.[0] ?? null;
1329
+ }
1330
+ }
1105
1331
  };
1106
1332
  }
1107
1333
  });
1108
1334
 
1109
- // packages/adapters/src/providers/cursor/install.js
1110
- import { existsSync as existsSync7, mkdirSync as mkdirSync3, readFileSync as readFileSync5, writeFileSync as writeFileSync4 } from "node:fs";
1111
- import { join as join11 } from "node:path";
1112
- var INSTRUCTION_REFERENCES3, MCP_SERVER_KEY3, CursorInstallProvider;
1335
+ // packages/adapters/src/providers/cursor/install.ts
1336
+ import { existsSync as existsSync7, mkdirSync as mkdirSync2, readFileSync as readFileSync5, writeFileSync as writeFileSync4 } from "node:fs";
1337
+ import { join as join12 } from "node:path";
1338
+ var INSTRUCTION_REFERENCES3, CursorInstallProvider;
1113
1339
  var init_install2 = __esm({
1114
- "packages/adapters/src/providers/cursor/install.js"() {
1340
+ "packages/adapters/src/providers/cursor/install.ts"() {
1115
1341
  "use strict";
1116
1342
  INSTRUCTION_REFERENCES3 = ["@~/.cleo/templates/CLEO-INJECTION.md", "@.cleo/memory-bridge.md"];
1117
- MCP_SERVER_KEY3 = "cleo";
1118
1343
  CursorInstallProvider = class {
1119
- installedProjectDir = null;
1120
1344
  /**
1121
1345
  * Install CLEO into a Cursor project.
1122
1346
  *
1123
- * @param options - Installation options including project directory and MCP server path
1347
+ * @param options - Installation options including project directory
1124
1348
  * @returns Result describing what was installed
1125
1349
  */
1126
1350
  async install(options) {
1127
- const { projectDir, mcpServerPath } = options;
1351
+ const { projectDir } = options;
1128
1352
  const installedAt = (/* @__PURE__ */ new Date()).toISOString();
1129
1353
  let instructionFileUpdated = false;
1130
- let mcpRegistered = false;
1131
1354
  const details = {};
1132
- if (mcpServerPath) {
1133
- mcpRegistered = this.registerMcpServer(projectDir, mcpServerPath);
1134
- if (mcpRegistered) {
1135
- details.mcpConfigPath = join11(projectDir, ".cursor", "mcp.json");
1136
- }
1137
- }
1138
1355
  instructionFileUpdated = this.updateInstructionFiles(projectDir);
1139
1356
  if (instructionFileUpdated) {
1140
1357
  details.instructionFiles = this.getUpdatedFileList(projectDir);
1141
1358
  }
1142
- this.installedProjectDir = projectDir;
1143
1359
  return {
1144
1360
  success: true,
1145
1361
  installedAt,
1146
1362
  instructionFileUpdated,
1147
- mcpRegistered,
1363
+ mcpRegistered: false,
1148
1364
  details
1149
1365
  };
1150
1366
  }
1151
1367
  /**
1152
1368
  * Uninstall CLEO from the current Cursor project.
1153
1369
  *
1154
- * Removes the MCP server registration from .cursor/mcp.json.
1155
1370
  * Does not remove instruction file references (they are harmless if CLEO is not present).
1156
1371
  */
1157
1372
  async uninstall() {
1158
- if (!this.installedProjectDir)
1159
- return;
1160
- const mcpPath = join11(this.installedProjectDir, ".cursor", "mcp.json");
1161
- if (existsSync7(mcpPath)) {
1162
- try {
1163
- const raw = readFileSync5(mcpPath, "utf-8");
1164
- const config = JSON.parse(raw);
1165
- const mcpServers = config.mcpServers;
1166
- if (mcpServers && MCP_SERVER_KEY3 in mcpServers) {
1167
- delete mcpServers[MCP_SERVER_KEY3];
1168
- writeFileSync4(mcpPath, JSON.stringify(config, null, 2) + "\n", "utf-8");
1169
- }
1170
- } catch {
1171
- }
1172
- }
1173
- this.installedProjectDir = null;
1174
1373
  }
1175
1374
  /**
1176
1375
  * Check whether CLEO is installed in the current environment.
1177
1376
  *
1178
- * Checks for MCP server registered in .cursor/mcp.json.
1377
+ * Checks for .cursor/rules/cleo.mdc or .cursorrules with CLEO references.
1179
1378
  */
1180
1379
  async isInstalled() {
1181
- const mcpPath = join11(process.cwd(), ".cursor", "mcp.json");
1182
- if (existsSync7(mcpPath)) {
1380
+ const mdcPath = join12(process.cwd(), ".cursor", "rules", "cleo.mdc");
1381
+ if (existsSync7(mdcPath)) {
1382
+ return true;
1383
+ }
1384
+ const rulesPath = join12(process.cwd(), ".cursorrules");
1385
+ if (existsSync7(rulesPath)) {
1183
1386
  try {
1184
- const config = JSON.parse(readFileSync5(mcpPath, "utf-8"));
1185
- const mcpServers = config.mcpServers;
1186
- if (mcpServers && MCP_SERVER_KEY3 in mcpServers) {
1387
+ const content = readFileSync5(rulesPath, "utf-8");
1388
+ if (INSTRUCTION_REFERENCES3.some((ref) => content.includes(ref))) {
1187
1389
  return true;
1188
1390
  }
1189
1391
  } catch {
@@ -1201,36 +1403,6 @@ var init_install2 = __esm({
1201
1403
  async ensureInstructionReferences(projectDir) {
1202
1404
  this.updateInstructionFiles(projectDir);
1203
1405
  }
1204
- /**
1205
- * Register the CLEO MCP server in .cursor/mcp.json.
1206
- *
1207
- * Cursor stores MCP server configuration in .cursor/mcp.json
1208
- * under the mcpServers key.
1209
- *
1210
- * @returns true if registration was performed or updated
1211
- */
1212
- registerMcpServer(projectDir, mcpServerPath) {
1213
- const cursorDir = join11(projectDir, ".cursor");
1214
- const mcpPath = join11(cursorDir, "mcp.json");
1215
- let config = {};
1216
- mkdirSync3(cursorDir, { recursive: true });
1217
- if (existsSync7(mcpPath)) {
1218
- try {
1219
- config = JSON.parse(readFileSync5(mcpPath, "utf-8"));
1220
- } catch {
1221
- }
1222
- }
1223
- if (!config.mcpServers || typeof config.mcpServers !== "object") {
1224
- config.mcpServers = {};
1225
- }
1226
- const mcpServers = config.mcpServers;
1227
- mcpServers[MCP_SERVER_KEY3] = {
1228
- command: "node",
1229
- args: [mcpServerPath]
1230
- };
1231
- writeFileSync4(mcpPath, JSON.stringify(config, null, 2) + "\n", "utf-8");
1232
- return true;
1233
- }
1234
1406
  /**
1235
1407
  * Update instruction files with CLEO @-references.
1236
1408
  *
@@ -1255,7 +1427,7 @@ var init_install2 = __esm({
1255
1427
  * @returns true if the file was modified
1256
1428
  */
1257
1429
  updateLegacyRules(projectDir) {
1258
- const rulesPath = join11(projectDir, ".cursorrules");
1430
+ const rulesPath = join12(projectDir, ".cursorrules");
1259
1431
  if (!existsSync7(rulesPath)) {
1260
1432
  return false;
1261
1433
  }
@@ -1278,8 +1450,8 @@ var init_install2 = __esm({
1278
1450
  * @returns true if the file was created or modified
1279
1451
  */
1280
1452
  updateModernRules(projectDir) {
1281
- const rulesDir = join11(projectDir, ".cursor", "rules");
1282
- const mdcPath = join11(rulesDir, "cleo.mdc");
1453
+ const rulesDir = join12(projectDir, ".cursor", "rules");
1454
+ const mdcPath = join12(rulesDir, "cleo.mdc");
1283
1455
  const expectedContent = [
1284
1456
  "---",
1285
1457
  "description: CLEO task management protocol references",
@@ -1296,7 +1468,7 @@ var init_install2 = __esm({
1296
1468
  return false;
1297
1469
  }
1298
1470
  }
1299
- mkdirSync3(rulesDir, { recursive: true });
1471
+ mkdirSync2(rulesDir, { recursive: true });
1300
1472
  writeFileSync4(mdcPath, expectedContent, "utf-8");
1301
1473
  return true;
1302
1474
  }
@@ -1305,35 +1477,53 @@ var init_install2 = __esm({
1305
1477
  */
1306
1478
  getUpdatedFileList(projectDir) {
1307
1479
  const files = [];
1308
- if (existsSync7(join11(projectDir, ".cursorrules"))) {
1309
- files.push(join11(projectDir, ".cursorrules"));
1480
+ if (existsSync7(join12(projectDir, ".cursorrules"))) {
1481
+ files.push(join12(projectDir, ".cursorrules"));
1310
1482
  }
1311
- files.push(join11(projectDir, ".cursor", "rules", "cleo.mdc"));
1483
+ files.push(join12(projectDir, ".cursor", "rules", "cleo.mdc"));
1312
1484
  return files;
1313
1485
  }
1314
1486
  };
1315
1487
  }
1316
1488
  });
1317
1489
 
1318
- // packages/adapters/src/providers/cursor/adapter.js
1490
+ // packages/adapters/src/providers/cursor/adapter.ts
1319
1491
  import { existsSync as existsSync8 } from "node:fs";
1320
- import { join as join12 } from "node:path";
1492
+ import { join as join13 } from "node:path";
1321
1493
  var CursorAdapter;
1322
1494
  var init_adapter2 = __esm({
1323
- "packages/adapters/src/providers/cursor/adapter.js"() {
1495
+ "packages/adapters/src/providers/cursor/adapter.ts"() {
1324
1496
  "use strict";
1325
1497
  init_hooks2();
1326
1498
  init_install2();
1327
1499
  CursorAdapter = class {
1500
+ /** Unique provider identifier. */
1328
1501
  id = "cursor";
1502
+ /** Human-readable provider name. */
1329
1503
  name = "Cursor";
1504
+ /** Adapter version string. */
1330
1505
  version = "1.0.0";
1506
+ /** Declared capabilities for this provider. */
1331
1507
  capabilities = {
1332
- supportsHooks: false,
1333
- supportedHookEvents: [],
1508
+ supportsHooks: true,
1509
+ // 10/16 canonical events — derived from getProviderHookProfile('cursor') in CAAMP 1.9.1.
1510
+ // PermissionRequest, PreModel, PostModel, PostCompact, Notification, ConfigChange are
1511
+ // not supported by Cursor's hook system.
1512
+ supportedHookEvents: [
1513
+ "SessionStart",
1514
+ "SessionEnd",
1515
+ "PromptSubmit",
1516
+ "ResponseComplete",
1517
+ "PreToolUse",
1518
+ "PostToolUse",
1519
+ "PostToolUseFailure",
1520
+ "SubagentStart",
1521
+ "SubagentStop",
1522
+ "PreCompact"
1523
+ ],
1334
1524
  supportsSpawn: false,
1335
1525
  supportsInstall: true,
1336
- supportsMcp: true,
1526
+ supportsMcp: false,
1337
1527
  supportsInstructionFiles: true,
1338
1528
  instructionFilePattern: ".cursor/rules/*.mdc",
1339
1529
  supportsContextMonitor: false,
@@ -1342,9 +1532,13 @@ var init_adapter2 = __esm({
1342
1532
  supportsTransport: false,
1343
1533
  supportsTaskSync: false
1344
1534
  };
1535
+ /** Hook provider for CAAMP event mapping. */
1345
1536
  hooks;
1537
+ /** Install provider for managing rule files. */
1346
1538
  install;
1539
+ /** Project directory this adapter was initialized with, or null. */
1347
1540
  projectDir = null;
1541
+ /** Whether {@link initialize} has been called. */
1348
1542
  initialized = false;
1349
1543
  constructor() {
1350
1544
  this.hooks = new CursorHookProvider();
@@ -1390,14 +1584,14 @@ var init_adapter2 = __esm({
1390
1584
  }
1391
1585
  let configExists = false;
1392
1586
  if (this.projectDir) {
1393
- const cursorConfigDir = join12(this.projectDir, ".cursor");
1587
+ const cursorConfigDir = join13(this.projectDir, ".cursor");
1394
1588
  configExists = existsSync8(cursorConfigDir);
1395
1589
  details.configDirExists = configExists;
1396
1590
  }
1397
1591
  const editorEnvSet = process.env.CURSOR_EDITOR !== void 0;
1398
1592
  details.editorEnvSet = editorEnvSet;
1399
1593
  if (this.projectDir) {
1400
- const legacyRulesExist = existsSync8(join12(this.projectDir, ".cursorrules"));
1594
+ const legacyRulesExist = existsSync8(join13(this.projectDir, ".cursorrules"));
1401
1595
  details.legacyRulesExist = legacyRulesExist;
1402
1596
  }
1403
1597
  const healthy = configExists || editorEnvSet;
@@ -1424,7 +1618,7 @@ var init_adapter2 = __esm({
1424
1618
  }
1425
1619
  });
1426
1620
 
1427
- // packages/adapters/src/providers/cursor/index.js
1621
+ // packages/adapters/src/providers/cursor/index.ts
1428
1622
  var cursor_exports = {};
1429
1623
  __export(cursor_exports, {
1430
1624
  CursorAdapter: () => CursorAdapter,
@@ -1438,7 +1632,7 @@ function createAdapter3() {
1438
1632
  }
1439
1633
  var cursor_default;
1440
1634
  var init_cursor = __esm({
1441
- "packages/adapters/src/providers/cursor/index.js"() {
1635
+ "packages/adapters/src/providers/cursor/index.ts"() {
1442
1636
  "use strict";
1443
1637
  init_adapter2();
1444
1638
  init_adapter2();
@@ -1448,26 +1642,48 @@ var init_cursor = __esm({
1448
1642
  }
1449
1643
  });
1450
1644
 
1451
- // packages/adapters/src/providers/opencode/hooks.js
1452
- var OPENCODE_EVENT_MAP, OpenCodeHookProvider;
1645
+ // packages/adapters/src/providers/opencode/hooks.ts
1646
+ var PROVIDER_ID3, OPENCODE_EVENT_MAP, OpenCodeHookProvider;
1453
1647
  var init_hooks3 = __esm({
1454
- "packages/adapters/src/providers/opencode/hooks.js"() {
1648
+ "packages/adapters/src/providers/opencode/hooks.ts"() {
1455
1649
  "use strict";
1650
+ PROVIDER_ID3 = "opencode";
1456
1651
  OPENCODE_EVENT_MAP = {
1457
- "session.start": "onSessionStart",
1458
- "session.end": "onSessionEnd",
1459
- "tool.start": "onToolStart",
1460
- "tool.complete": "onToolComplete",
1461
- error: "onError",
1462
- "prompt.submit": "onPromptSubmit"
1652
+ // CAAMP: toNative('SessionStart', 'opencode') = 'event:session.created'
1653
+ "event:session.created": "SessionStart",
1654
+ // CAAMP: toNative('SessionEnd', 'opencode') = 'event:session.deleted'
1655
+ "event:session.deleted": "SessionEnd",
1656
+ // CAAMP: toNative('PromptSubmit', 'opencode') = 'chat.message'
1657
+ "chat.message": "PromptSubmit",
1658
+ // CAAMP: toNative('ResponseComplete', 'opencode') = 'event:session.idle'
1659
+ "event:session.idle": "ResponseComplete",
1660
+ // CAAMP: toNative('PreToolUse', 'opencode') = 'tool.execute.before'
1661
+ "tool.execute.before": "PreToolUse",
1662
+ // CAAMP: toNative('PostToolUse', 'opencode') = 'tool.execute.after'
1663
+ "tool.execute.after": "PostToolUse",
1664
+ // CAAMP: toNative('PermissionRequest', 'opencode') = 'permission.ask'
1665
+ "permission.ask": "PermissionRequest",
1666
+ // CAAMP: toNative('PreModel', 'opencode') = 'chat.params'
1667
+ "chat.params": "PreModel",
1668
+ // CAAMP: toNative('PreCompact', 'opencode') = 'experimental.session.compacting'
1669
+ "experimental.session.compacting": "PreCompact",
1670
+ // CAAMP: toNative('PostCompact', 'opencode') = 'event:session.compacted'
1671
+ "event:session.compacted": "PostCompact"
1463
1672
  };
1464
1673
  OpenCodeHookProvider = class {
1674
+ /** Whether hooks have been registered for the current session. */
1465
1675
  registered = false;
1466
1676
  /**
1467
- * Map an OpenCode native event name to a CAAMP hook event name.
1677
+ * Map an OpenCode native event name to a CAAMP canonical hook event name.
1468
1678
  *
1469
- * @param providerEvent - OpenCode event name (e.g. "session.start", "tool.complete")
1470
- * @returns CAAMP event name or null if unmapped
1679
+ * Looks up the native event name in the map derived from
1680
+ * `getProviderHookProfile('opencode').mappings` (CAAMP 1.9.1).
1681
+ * Returns null for unsupported events (PostToolUseFailure, SubagentStart,
1682
+ * SubagentStop, Notification, ConfigChange).
1683
+ *
1684
+ * @param providerEvent - OpenCode native event (e.g. "event:session.created", "tool.execute.before")
1685
+ * @returns CAAMP canonical event name, or null if unmapped
1686
+ * @task T164
1471
1687
  */
1472
1688
  mapProviderEvent(providerEvent) {
1473
1689
  return OPENCODE_EVENT_MAP[providerEvent] ?? null;
@@ -1475,12 +1691,15 @@ var init_hooks3 = __esm({
1475
1691
  /**
1476
1692
  * Register native hooks for a project.
1477
1693
  *
1478
- * For OpenCode, hooks are registered via the config system
1479
- * (.opencode/config.json), which is handled by the install provider.
1480
- * This method marks hooks as registered without performing
1481
- * filesystem operations.
1694
+ * For OpenCode, hooks are registered via the plugin system
1695
+ * (`.opencode/plugins/`), managed by the install provider.
1696
+ * This method marks hooks as registered without performing filesystem operations.
1697
+ *
1698
+ * Iterating supported events is handled at install time using
1699
+ * `getSupportedCanonicalEvents()` to enumerate all 10 supported hooks.
1482
1700
  *
1483
1701
  * @param _projectDir - Project directory (unused; config manages registration)
1702
+ * @task T164
1484
1703
  */
1485
1704
  async registerNativeHooks(_projectDir) {
1486
1705
  this.registered = true;
@@ -1488,108 +1707,143 @@ var init_hooks3 = __esm({
1488
1707
  /**
1489
1708
  * Unregister native hooks.
1490
1709
  *
1491
- * For OpenCode, this is a no-op since hooks are managed through
1492
- * the config system. Unregistration happens via the install
1493
- * provider's uninstall method.
1710
+ * For OpenCode, this is a no-op since hooks are managed through the plugin
1711
+ * system. Unregistration happens via the install provider's uninstall method.
1712
+ *
1713
+ * @task T164
1494
1714
  */
1495
1715
  async unregisterNativeHooks() {
1496
1716
  this.registered = false;
1497
1717
  }
1498
1718
  /**
1499
- * Check whether hooks have been registered via registerNativeHooks.
1719
+ * Check whether hooks have been registered via `registerNativeHooks`.
1500
1720
  */
1501
1721
  isRegistered() {
1502
1722
  return this.registered;
1503
1723
  }
1504
1724
  /**
1505
- * Get the full event mapping for introspection/debugging.
1725
+ * Get the native→canonical event mapping for introspection and debugging.
1726
+ *
1727
+ * Returns the map derived from `getProviderHookProfile('opencode').mappings`
1728
+ * (CAAMP 1.9.1). Use `getSupportedCanonicalEvents()` to enumerate canonical
1729
+ * names via live CAAMP APIs.
1730
+ *
1731
+ * @returns Immutable record of native event name → canonical event name
1506
1732
  */
1507
1733
  getEventMap() {
1508
1734
  return { ...OPENCODE_EVENT_MAP };
1509
1735
  }
1736
+ /**
1737
+ * Enumerate supported canonical events via CAAMP's `getSupportedEvents()`.
1738
+ *
1739
+ * Calls `getSupportedEvents('opencode')` from the CAAMP normalizer to get the
1740
+ * authoritative list. OpenCode supports 10 of 16 canonical events via its
1741
+ * plugin system. Falls back to the values of the static event map when
1742
+ * CAAMP is unavailable at runtime.
1743
+ *
1744
+ * @returns Array of CAAMP canonical event names supported by OpenCode
1745
+ * @task T164
1746
+ */
1747
+ async getSupportedCanonicalEvents() {
1748
+ try {
1749
+ const { getSupportedEvents } = await import("@cleocode/caamp");
1750
+ return getSupportedEvents(PROVIDER_ID3);
1751
+ } catch {
1752
+ return [...new Set(Object.values(OPENCODE_EVENT_MAP))];
1753
+ }
1754
+ }
1755
+ /**
1756
+ * Retrieve the full provider hook profile from CAAMP.
1757
+ *
1758
+ * Calls `getProviderHookProfile('opencode')` from the CAAMP normalizer to
1759
+ * get the complete profile: hook system type (`plugin`), config path
1760
+ * (`.opencode/plugins/`), handler types, and all event mappings.
1761
+ * Returns null when CAAMP is unavailable at runtime.
1762
+ *
1763
+ * @returns Provider hook profile or null if CAAMP is unavailable
1764
+ * @task T164
1765
+ */
1766
+ async getProviderProfile() {
1767
+ try {
1768
+ const { getProviderHookProfile } = await import("@cleocode/caamp");
1769
+ return getProviderHookProfile(PROVIDER_ID3) ?? null;
1770
+ } catch {
1771
+ return null;
1772
+ }
1773
+ }
1774
+ /**
1775
+ * Translate a CAAMP canonical event to its OpenCode native name via CAAMP.
1776
+ *
1777
+ * Calls `toNative(canonical, 'opencode')` from the CAAMP normalizer.
1778
+ * Returns null for unsupported events or when CAAMP is unavailable.
1779
+ *
1780
+ * @param canonical - CAAMP canonical event name (e.g. "PreToolUse")
1781
+ * @returns OpenCode native event name or null
1782
+ * @task T164
1783
+ */
1784
+ async toNativeEvent(canonical) {
1785
+ try {
1786
+ const { toNative } = await import("@cleocode/caamp");
1787
+ return toNative(canonical, PROVIDER_ID3);
1788
+ } catch {
1789
+ const entry = Object.entries(OPENCODE_EVENT_MAP).find(([, v]) => v === canonical);
1790
+ return entry?.[0] ?? null;
1791
+ }
1792
+ }
1510
1793
  };
1511
1794
  }
1512
1795
  });
1513
1796
 
1514
- // packages/adapters/src/providers/opencode/install.js
1515
- import { existsSync as existsSync13, mkdirSync as mkdirSync6, readFileSync as readFileSync8, writeFileSync as writeFileSync7 } from "node:fs";
1516
- import { join as join18 } from "node:path";
1517
- var INSTRUCTION_REFERENCES6, MCP_SERVER_KEY6, OpenCodeInstallProvider;
1797
+ // packages/adapters/src/providers/opencode/install.ts
1798
+ import { existsSync as existsSync13, readFileSync as readFileSync8, writeFileSync as writeFileSync7 } from "node:fs";
1799
+ import { join as join19 } from "node:path";
1800
+ var INSTRUCTION_REFERENCES6, OpenCodeInstallProvider;
1518
1801
  var init_install3 = __esm({
1519
- "packages/adapters/src/providers/opencode/install.js"() {
1802
+ "packages/adapters/src/providers/opencode/install.ts"() {
1520
1803
  "use strict";
1521
1804
  INSTRUCTION_REFERENCES6 = ["@~/.cleo/templates/CLEO-INJECTION.md", "@.cleo/memory-bridge.md"];
1522
- MCP_SERVER_KEY6 = "cleo";
1523
1805
  OpenCodeInstallProvider = class {
1524
- installedProjectDir = null;
1525
1806
  /**
1526
1807
  * Install CLEO into an OpenCode project.
1527
1808
  *
1528
- * @param options - Installation options including project directory and MCP server path
1809
+ * @param options - Installation options including project directory
1529
1810
  * @returns Result describing what was installed
1530
1811
  */
1531
1812
  async install(options) {
1532
- const { projectDir, mcpServerPath } = options;
1813
+ const { projectDir } = options;
1533
1814
  const installedAt = (/* @__PURE__ */ new Date()).toISOString();
1534
1815
  let instructionFileUpdated = false;
1535
- let mcpRegistered = false;
1536
1816
  const details = {};
1537
- if (mcpServerPath) {
1538
- mcpRegistered = this.registerMcpServer(projectDir, mcpServerPath);
1539
- if (mcpRegistered) {
1540
- details.mcpConfigPath = join18(projectDir, ".opencode", "config.json");
1541
- }
1542
- }
1543
1817
  instructionFileUpdated = this.updateInstructionFile(projectDir);
1544
1818
  if (instructionFileUpdated) {
1545
- details.instructionFile = join18(projectDir, "AGENTS.md");
1819
+ details.instructionFile = join19(projectDir, "AGENTS.md");
1546
1820
  }
1547
- this.installedProjectDir = projectDir;
1548
1821
  return {
1549
1822
  success: true,
1550
1823
  installedAt,
1551
1824
  instructionFileUpdated,
1552
- mcpRegistered,
1825
+ mcpRegistered: false,
1553
1826
  details
1554
1827
  };
1555
1828
  }
1556
1829
  /**
1557
1830
  * Uninstall CLEO from the current OpenCode project.
1558
1831
  *
1559
- * Removes the MCP server registration from .opencode/config.json.
1560
1832
  * Does not remove AGENTS.md references (they are harmless if CLEO is not present).
1561
1833
  */
1562
1834
  async uninstall() {
1563
- if (!this.installedProjectDir)
1564
- return;
1565
- const configPath = join18(this.installedProjectDir, ".opencode", "config.json");
1566
- if (existsSync13(configPath)) {
1567
- try {
1568
- const raw = readFileSync8(configPath, "utf-8");
1569
- const config = JSON.parse(raw);
1570
- const mcpServers = config.mcpServers;
1571
- if (mcpServers && MCP_SERVER_KEY6 in mcpServers) {
1572
- delete mcpServers[MCP_SERVER_KEY6];
1573
- writeFileSync7(configPath, JSON.stringify(config, null, 2) + "\n", "utf-8");
1574
- }
1575
- } catch {
1576
- }
1577
- }
1578
- this.installedProjectDir = null;
1579
1835
  }
1580
1836
  /**
1581
1837
  * Check whether CLEO is installed in the current environment.
1582
1838
  *
1583
- * Checks for MCP server registered in .opencode/config.json.
1584
- * Returns true if the CLEO MCP server entry is found.
1839
+ * Checks for CLEO references in AGENTS.md.
1585
1840
  */
1586
1841
  async isInstalled() {
1587
- const configPath = join18(process.cwd(), ".opencode", "config.json");
1588
- if (existsSync13(configPath)) {
1842
+ const agentsMdPath = join19(process.cwd(), "AGENTS.md");
1843
+ if (existsSync13(agentsMdPath)) {
1589
1844
  try {
1590
- const config = JSON.parse(readFileSync8(configPath, "utf-8"));
1591
- const mcpServers = config.mcpServers;
1592
- if (mcpServers && MCP_SERVER_KEY6 in mcpServers) {
1845
+ const content = readFileSync8(agentsMdPath, "utf-8");
1846
+ if (INSTRUCTION_REFERENCES6.some((ref) => content.includes(ref))) {
1593
1847
  return true;
1594
1848
  }
1595
1849
  } catch {
@@ -1607,43 +1861,13 @@ var init_install3 = __esm({
1607
1861
  async ensureInstructionReferences(projectDir) {
1608
1862
  this.updateInstructionFile(projectDir);
1609
1863
  }
1610
- /**
1611
- * Register the CLEO MCP server in .opencode/config.json.
1612
- *
1613
- * OpenCode stores its MCP server configuration in .opencode/config.json
1614
- * under the mcpServers key.
1615
- *
1616
- * @returns true if registration was performed or updated
1617
- */
1618
- registerMcpServer(projectDir, mcpServerPath) {
1619
- const openCodeDir = join18(projectDir, ".opencode");
1620
- const configPath = join18(openCodeDir, "config.json");
1621
- let config = {};
1622
- mkdirSync6(openCodeDir, { recursive: true });
1623
- if (existsSync13(configPath)) {
1624
- try {
1625
- config = JSON.parse(readFileSync8(configPath, "utf-8"));
1626
- } catch {
1627
- }
1628
- }
1629
- if (!config.mcpServers || typeof config.mcpServers !== "object") {
1630
- config.mcpServers = {};
1631
- }
1632
- const mcpServers = config.mcpServers;
1633
- mcpServers[MCP_SERVER_KEY6] = {
1634
- command: "node",
1635
- args: [mcpServerPath]
1636
- };
1637
- writeFileSync7(configPath, JSON.stringify(config, null, 2) + "\n", "utf-8");
1638
- return true;
1639
- }
1640
1864
  /**
1641
1865
  * Update AGENTS.md with CLEO @-references.
1642
1866
  *
1643
1867
  * @returns true if the file was created or modified
1644
1868
  */
1645
1869
  updateInstructionFile(projectDir) {
1646
- const agentsMdPath = join18(projectDir, "AGENTS.md");
1870
+ const agentsMdPath = join19(projectDir, "AGENTS.md");
1647
1871
  let content = "";
1648
1872
  let existed = false;
1649
1873
  if (existsSync13(agentsMdPath)) {
@@ -1668,10 +1892,10 @@ var init_install3 = __esm({
1668
1892
  }
1669
1893
  });
1670
1894
 
1671
- // packages/adapters/src/providers/opencode/spawn.js
1895
+ // packages/adapters/src/providers/opencode/spawn.ts
1672
1896
  import { exec as exec6, spawn as nodeSpawn2 } from "node:child_process";
1673
- import { mkdir as mkdir2, readFile as readFile3, writeFile as writeFile2 } from "node:fs/promises";
1674
- import { join as join19 } from "node:path";
1897
+ import { mkdir as mkdir2, readFile as readFile4, writeFile as writeFile2 } from "node:fs/promises";
1898
+ import { join as join20 } from "node:path";
1675
1899
  import { promisify as promisify6 } from "node:util";
1676
1900
  function buildOpenCodeAgentMarkdown(description, instructions) {
1677
1901
  const normalizedDesc = description.replace(/\s+/g, " ").trim();
@@ -1687,8 +1911,8 @@ function buildOpenCodeAgentMarkdown(description, instructions) {
1687
1911
  ].join("\n");
1688
1912
  }
1689
1913
  async function ensureSubagentDefinition(workingDirectory) {
1690
- const agentDir = join19(workingDirectory, ".opencode", "agent");
1691
- const agentPath = join19(agentDir, `${OPENCODE_SUBAGENT_NAME}.md`);
1914
+ const agentDir = join20(workingDirectory, ".opencode", "agent");
1915
+ const agentPath = join20(agentDir, `${OPENCODE_SUBAGENT_NAME}.md`);
1692
1916
  const description = "CLEO task executor with protocol compliance.";
1693
1917
  const instructions = [
1694
1918
  "# CLEO Subagent",
@@ -1702,7 +1926,7 @@ async function ensureSubagentDefinition(workingDirectory) {
1702
1926
  await mkdir2(agentDir, { recursive: true });
1703
1927
  let existing = null;
1704
1928
  try {
1705
- existing = await readFile3(agentPath, "utf-8");
1929
+ existing = await readFile4(agentPath, "utf-8");
1706
1930
  } catch {
1707
1931
  existing = null;
1708
1932
  }
@@ -1713,7 +1937,7 @@ async function ensureSubagentDefinition(workingDirectory) {
1713
1937
  }
1714
1938
  var execAsync6, OPENCODE_SUBAGENT_NAME, OPENCODE_FALLBACK_AGENT, OpenCodeSpawnProvider;
1715
1939
  var init_spawn2 = __esm({
1716
- "packages/adapters/src/providers/opencode/spawn.js"() {
1940
+ "packages/adapters/src/providers/opencode/spawn.ts"() {
1717
1941
  "use strict";
1718
1942
  execAsync6 = promisify6(exec6);
1719
1943
  OPENCODE_SUBAGENT_NAME = "cleo-subagent";
@@ -1755,20 +1979,24 @@ var init_spawn2 = __esm({
1755
1979
  } catch {
1756
1980
  agentName = OPENCODE_FALLBACK_AGENT;
1757
1981
  }
1758
- const child = nodeSpawn2("opencode", [
1759
- "run",
1760
- "--format",
1761
- "json",
1762
- "--agent",
1763
- agentName,
1764
- "--title",
1765
- `CLEO ${context.taskId}`,
1766
- context.prompt
1767
- ], {
1768
- cwd: workingDirectory,
1769
- detached: true,
1770
- stdio: "ignore"
1771
- });
1982
+ const child = nodeSpawn2(
1983
+ "opencode",
1984
+ [
1985
+ "run",
1986
+ "--format",
1987
+ "json",
1988
+ "--agent",
1989
+ agentName,
1990
+ "--title",
1991
+ `CLEO ${context.taskId}`,
1992
+ context.prompt
1993
+ ],
1994
+ {
1995
+ cwd: workingDirectory,
1996
+ detached: true,
1997
+ stdio: "ignore"
1998
+ }
1999
+ );
1772
2000
  child.unref();
1773
2001
  if (child.pid) {
1774
2002
  this.processMap.set(instanceId, {
@@ -1834,8 +2062,7 @@ var init_spawn2 = __esm({
1834
2062
  */
1835
2063
  async terminate(instanceId) {
1836
2064
  const tracked = this.processMap.get(instanceId);
1837
- if (!tracked)
1838
- return;
2065
+ if (!tracked) return;
1839
2066
  try {
1840
2067
  process.kill(tracked.pid, "SIGTERM");
1841
2068
  } catch {
@@ -1846,36 +2073,47 @@ var init_spawn2 = __esm({
1846
2073
  }
1847
2074
  });
1848
2075
 
1849
- // packages/adapters/src/providers/opencode/adapter.js
2076
+ // packages/adapters/src/providers/opencode/adapter.ts
1850
2077
  import { exec as exec7 } from "node:child_process";
1851
2078
  import { existsSync as existsSync14 } from "node:fs";
1852
- import { join as join20 } from "node:path";
2079
+ import { join as join21 } from "node:path";
1853
2080
  import { promisify as promisify7 } from "node:util";
1854
2081
  var execAsync7, OpenCodeAdapter;
1855
2082
  var init_adapter3 = __esm({
1856
- "packages/adapters/src/providers/opencode/adapter.js"() {
2083
+ "packages/adapters/src/providers/opencode/adapter.ts"() {
1857
2084
  "use strict";
1858
2085
  init_hooks3();
1859
2086
  init_install3();
1860
2087
  init_spawn2();
1861
2088
  execAsync7 = promisify7(exec7);
1862
2089
  OpenCodeAdapter = class {
2090
+ /** Unique provider identifier. */
1863
2091
  id = "opencode";
2092
+ /** Human-readable provider name. */
1864
2093
  name = "OpenCode";
2094
+ /** Adapter version string. */
1865
2095
  version = "1.0.0";
2096
+ /** Declared capabilities for this provider. */
1866
2097
  capabilities = {
1867
2098
  supportsHooks: true,
2099
+ // 10/16 canonical events — derived from getProviderHookProfile('opencode') in CAAMP 1.9.1.
2100
+ // PostToolUseFailure, SubagentStart, SubagentStop, Notification, ConfigChange are
2101
+ // not supported by OpenCode's plugin system.
1868
2102
  supportedHookEvents: [
1869
- "onSessionStart",
1870
- "onSessionEnd",
1871
- "onToolStart",
1872
- "onToolComplete",
1873
- "onError",
1874
- "onPromptSubmit"
2103
+ "SessionStart",
2104
+ "SessionEnd",
2105
+ "PromptSubmit",
2106
+ "ResponseComplete",
2107
+ "PreToolUse",
2108
+ "PostToolUse",
2109
+ "PermissionRequest",
2110
+ "PreModel",
2111
+ "PreCompact",
2112
+ "PostCompact"
1875
2113
  ],
1876
2114
  supportsSpawn: true,
1877
2115
  supportsInstall: true,
1878
- supportsMcp: true,
2116
+ supportsMcp: false,
1879
2117
  supportsInstructionFiles: true,
1880
2118
  instructionFilePattern: "AGENTS.md",
1881
2119
  supportsContextMonitor: false,
@@ -1884,10 +2122,15 @@ var init_adapter3 = __esm({
1884
2122
  supportsTransport: false,
1885
2123
  supportsTaskSync: false
1886
2124
  };
2125
+ /** Hook provider for CAAMP event mapping via OpenCode's plugin system. */
1887
2126
  hooks;
2127
+ /** Spawn provider for launching subagent processes via `opencode run`. */
1888
2128
  spawn;
2129
+ /** Install provider for managing AGENTS.md instruction files. */
1889
2130
  install;
2131
+ /** Project directory this adapter was initialized with, or null. */
1890
2132
  projectDir = null;
2133
+ /** Whether {@link initialize} has been called. */
1891
2134
  initialized = false;
1892
2135
  constructor() {
1893
2136
  this.hooks = new OpenCodeHookProvider();
@@ -1946,7 +2189,7 @@ var init_adapter3 = __esm({
1946
2189
  details.cliAvailable = false;
1947
2190
  }
1948
2191
  if (this.projectDir) {
1949
- const openCodeConfigDir = join20(this.projectDir, ".opencode");
2192
+ const openCodeConfigDir = join21(this.projectDir, ".opencode");
1950
2193
  const configExists = existsSync14(openCodeConfigDir);
1951
2194
  details.configDirExists = configExists;
1952
2195
  }
@@ -1976,7 +2219,7 @@ var init_adapter3 = __esm({
1976
2219
  }
1977
2220
  });
1978
2221
 
1979
- // packages/adapters/src/providers/opencode/index.js
2222
+ // packages/adapters/src/providers/opencode/index.ts
1980
2223
  var opencode_exports = {};
1981
2224
  __export(opencode_exports, {
1982
2225
  OpenCodeAdapter: () => OpenCodeAdapter,
@@ -1991,7 +2234,7 @@ function createAdapter6() {
1991
2234
  }
1992
2235
  var opencode_default;
1993
2236
  var init_opencode = __esm({
1994
- "packages/adapters/src/providers/opencode/index.js"() {
2237
+ "packages/adapters/src/providers/opencode/index.ts"() {
1995
2238
  "use strict";
1996
2239
  init_adapter3();
1997
2240
  init_adapter3();
@@ -2008,17 +2251,17 @@ init_claude_code();
2008
2251
  // packages/adapters/src/providers/codex/adapter.ts
2009
2252
  import { exec as exec3 } from "node:child_process";
2010
2253
  import { existsSync as existsSync6 } from "node:fs";
2011
- import { homedir as homedir8 } from "node:os";
2012
- import { join as join10 } from "node:path";
2254
+ import { homedir as homedir7 } from "node:os";
2255
+ import { join as join11 } from "node:path";
2013
2256
  import { promisify as promisify3 } from "node:util";
2014
2257
 
2015
2258
  // packages/adapters/src/providers/codex/hooks.ts
2016
2259
  import { homedir as homedir6 } from "node:os";
2017
- import { join as join8 } from "node:path";
2260
+ import { join as join9 } from "node:path";
2018
2261
 
2019
2262
  // packages/adapters/src/providers/shared/transcript-reader.ts
2020
- import { readdir, readFile as readFile2 } from "node:fs/promises";
2021
- import { join as join7 } from "node:path";
2263
+ import { readdir as readdir2, readFile as readFile3 } from "node:fs/promises";
2264
+ import { join as join8 } from "node:path";
2022
2265
  function parseTranscriptLines(raw) {
2023
2266
  const turns = [];
2024
2267
  const lines = raw.split("\n").filter((l) => l.trim());
@@ -2038,12 +2281,12 @@ function parseTranscriptLines(raw) {
2038
2281
  async function readLatestTranscript(providerDir) {
2039
2282
  let allFiles = [];
2040
2283
  try {
2041
- const entries = await readdir(providerDir, { withFileTypes: true });
2284
+ const entries = await readdir2(providerDir, { withFileTypes: true });
2042
2285
  for (const entry of entries) {
2043
2286
  if (!entry.isFile()) continue;
2044
2287
  const name = entry.name;
2045
2288
  if (name.endsWith(".json") || name.endsWith(".jsonl")) {
2046
- allFiles.push(join7(providerDir, name));
2289
+ allFiles.push(join8(providerDir, name));
2047
2290
  }
2048
2291
  }
2049
2292
  } catch {
@@ -2054,7 +2297,7 @@ async function readLatestTranscript(providerDir) {
2054
2297
  const mostRecent = allFiles[0];
2055
2298
  if (!mostRecent) return null;
2056
2299
  try {
2057
- const raw = await readFile2(mostRecent, "utf-8");
2300
+ const raw = await readFile3(mostRecent, "utf-8");
2058
2301
  const turns = parseTranscriptLines(raw);
2059
2302
  return turns.length > 0 ? turns.map((t) => `${t.role}: ${t.content}`).join("\n") : null;
2060
2303
  } catch {
@@ -2069,6 +2312,7 @@ var CODEX_EVENT_MAP = {
2069
2312
  ResponseComplete: "Stop"
2070
2313
  };
2071
2314
  var CodexHookProvider = class {
2315
+ /** Whether hooks have been registered for the current session. */
2072
2316
  registered = false;
2073
2317
  /**
2074
2318
  * Map a Codex CLI native event name to a CAAMP hook event name.
@@ -2132,84 +2376,59 @@ var CodexHookProvider = class {
2132
2376
  * @task T162 @epic T134
2133
2377
  */
2134
2378
  async getTranscript(_sessionId, _projectDir) {
2135
- return readLatestTranscript(join8(homedir6(), ".codex"));
2379
+ return readLatestTranscript(join9(homedir6(), ".codex"));
2136
2380
  }
2137
2381
  };
2138
2382
 
2139
2383
  // packages/adapters/src/providers/codex/install.ts
2140
- import { existsSync as existsSync5, mkdirSync as mkdirSync2, readFileSync as readFileSync4, writeFileSync as writeFileSync3 } from "node:fs";
2141
- import { homedir as homedir7 } from "node:os";
2142
- import { join as join9 } from "node:path";
2384
+ import { existsSync as existsSync5, readFileSync as readFileSync4, writeFileSync as writeFileSync3 } from "node:fs";
2385
+ import { join as join10 } from "node:path";
2143
2386
  var INSTRUCTION_REFERENCES2 = ["@~/.cleo/templates/CLEO-INJECTION.md", "@.cleo/memory-bridge.md"];
2144
- var MCP_SERVER_KEY2 = "cleo";
2145
2387
  var CodexInstallProvider = class {
2146
2388
  /**
2147
2389
  * Install CLEO into a Codex CLI environment.
2148
2390
  *
2149
- * @param options - Installation options including project directory and MCP server path
2391
+ * @param options - Installation options including project directory
2150
2392
  * @returns Result describing what was installed
2151
2393
  * @task T162
2152
2394
  */
2153
2395
  async install(options) {
2154
- const { projectDir, mcpServerPath } = options;
2396
+ const { projectDir } = options;
2155
2397
  const installedAt = (/* @__PURE__ */ new Date()).toISOString();
2156
2398
  let instructionFileUpdated = false;
2157
- let mcpRegistered = false;
2158
2399
  const details = {};
2159
- if (mcpServerPath) {
2160
- mcpRegistered = this.registerMcpServer(mcpServerPath);
2161
- if (mcpRegistered) {
2162
- details.mcpConfigPath = join9(homedir7(), ".codex", "config.json");
2163
- }
2164
- }
2165
2400
  instructionFileUpdated = this.updateInstructionFile(projectDir);
2166
2401
  if (instructionFileUpdated) {
2167
- details.instructionFile = join9(projectDir, "AGENTS.md");
2402
+ details.instructionFile = join10(projectDir, "AGENTS.md");
2168
2403
  }
2169
2404
  return {
2170
2405
  success: true,
2171
2406
  installedAt,
2172
2407
  instructionFileUpdated,
2173
- mcpRegistered,
2408
+ mcpRegistered: false,
2174
2409
  details
2175
2410
  };
2176
2411
  }
2177
2412
  /**
2178
2413
  * Uninstall CLEO from the Codex CLI environment.
2179
2414
  *
2180
- * Removes the MCP server registration from ~/.codex/config.json.
2181
2415
  * Does not remove AGENTS.md references (they are harmless if CLEO is not present).
2182
2416
  * @task T162
2183
2417
  */
2184
2418
  async uninstall() {
2185
- const configPath = join9(homedir7(), ".codex", "config.json");
2186
- if (existsSync5(configPath)) {
2187
- try {
2188
- const raw = readFileSync4(configPath, "utf-8");
2189
- const config = JSON.parse(raw);
2190
- const mcpServers = config.mcpServers;
2191
- if (mcpServers && MCP_SERVER_KEY2 in mcpServers) {
2192
- delete mcpServers[MCP_SERVER_KEY2];
2193
- writeFileSync3(configPath, JSON.stringify(config, null, 2) + "\n", "utf-8");
2194
- }
2195
- } catch {
2196
- }
2197
- }
2198
2419
  }
2199
2420
  /**
2200
2421
  * Check whether CLEO is installed in the Codex CLI environment.
2201
2422
  *
2202
- * Checks for MCP server registered in ~/.codex/config.json.
2203
- * Returns true if the CLEO MCP server entry is found.
2423
+ * Checks for CLEO references in AGENTS.md.
2204
2424
  * @task T162
2205
2425
  */
2206
2426
  async isInstalled() {
2207
- const configPath = join9(homedir7(), ".codex", "config.json");
2208
- if (existsSync5(configPath)) {
2427
+ const agentsMdPath = join10(process.cwd(), "AGENTS.md");
2428
+ if (existsSync5(agentsMdPath)) {
2209
2429
  try {
2210
- const config = JSON.parse(readFileSync4(configPath, "utf-8"));
2211
- const mcpServers = config.mcpServers;
2212
- if (mcpServers && MCP_SERVER_KEY2 in mcpServers) {
2430
+ const content = readFileSync4(agentsMdPath, "utf-8");
2431
+ if (INSTRUCTION_REFERENCES2.some((ref) => content.includes(ref))) {
2213
2432
  return true;
2214
2433
  }
2215
2434
  } catch {
@@ -2228,37 +2447,6 @@ var CodexInstallProvider = class {
2228
2447
  async ensureInstructionReferences(projectDir) {
2229
2448
  this.updateInstructionFile(projectDir);
2230
2449
  }
2231
- /**
2232
- * Register the CLEO MCP server in ~/.codex/config.json.
2233
- *
2234
- * Codex CLI stores its MCP server configuration in ~/.codex/config.json
2235
- * under the mcpServers key.
2236
- *
2237
- * @param mcpServerPath - Absolute path to the MCP server entry point
2238
- * @returns true if registration was performed or updated
2239
- */
2240
- registerMcpServer(mcpServerPath) {
2241
- const codexDir = join9(homedir7(), ".codex");
2242
- const configPath = join9(codexDir, "config.json");
2243
- let config = {};
2244
- mkdirSync2(codexDir, { recursive: true });
2245
- if (existsSync5(configPath)) {
2246
- try {
2247
- config = JSON.parse(readFileSync4(configPath, "utf-8"));
2248
- } catch {
2249
- }
2250
- }
2251
- if (!config.mcpServers || typeof config.mcpServers !== "object") {
2252
- config.mcpServers = {};
2253
- }
2254
- const mcpServers = config.mcpServers;
2255
- mcpServers[MCP_SERVER_KEY2] = {
2256
- command: "node",
2257
- args: [mcpServerPath]
2258
- };
2259
- writeFileSync3(configPath, JSON.stringify(config, null, 2) + "\n", "utf-8");
2260
- return true;
2261
- }
2262
2450
  /**
2263
2451
  * Update AGENTS.md with CLEO @-references.
2264
2452
  *
@@ -2266,7 +2454,7 @@ var CodexInstallProvider = class {
2266
2454
  * @returns true if the file was created or modified
2267
2455
  */
2268
2456
  updateInstructionFile(projectDir) {
2269
- const agentsMdPath = join9(projectDir, "AGENTS.md");
2457
+ const agentsMdPath = join10(projectDir, "AGENTS.md");
2270
2458
  let content = "";
2271
2459
  let existed = false;
2272
2460
  if (existsSync5(agentsMdPath)) {
@@ -2292,15 +2480,19 @@ var CodexInstallProvider = class {
2292
2480
  // packages/adapters/src/providers/codex/adapter.ts
2293
2481
  var execAsync3 = promisify3(exec3);
2294
2482
  var CodexAdapter = class {
2483
+ /** Unique provider identifier. */
2295
2484
  id = "codex";
2485
+ /** Human-readable provider name. */
2296
2486
  name = "Codex";
2487
+ /** Adapter version string. */
2297
2488
  version = "1.0.0";
2489
+ /** Declared capabilities for this provider. */
2298
2490
  capabilities = {
2299
2491
  supportsHooks: true,
2300
2492
  supportedHookEvents: ["SessionStart", "UserPromptSubmit", "Stop"],
2301
2493
  supportsSpawn: false,
2302
2494
  supportsInstall: true,
2303
- supportsMcp: true,
2495
+ supportsMcp: false,
2304
2496
  supportsInstructionFiles: false,
2305
2497
  supportsContextMonitor: false,
2306
2498
  supportsStatusline: false,
@@ -2308,9 +2500,13 @@ var CodexAdapter = class {
2308
2500
  supportsTransport: false,
2309
2501
  supportsTaskSync: false
2310
2502
  };
2503
+ /** Hook provider for CAAMP event mapping. */
2311
2504
  hooks;
2505
+ /** Install provider for managing instruction files. */
2312
2506
  install;
2507
+ /** Project directory this adapter was initialized with, or null. */
2313
2508
  projectDir = null;
2509
+ /** Whether {@link initialize} has been called. */
2314
2510
  initialized = false;
2315
2511
  constructor() {
2316
2512
  this.hooks = new CodexHookProvider();
@@ -2367,7 +2563,7 @@ var CodexAdapter = class {
2367
2563
  } catch {
2368
2564
  details.cliAvailable = false;
2369
2565
  }
2370
- const codexConfigDir = join10(homedir8(), ".codex");
2566
+ const codexConfigDir = join11(homedir7(), ".codex");
2371
2567
  const configExists = existsSync6(codexConfigDir);
2372
2568
  details.configDirExists = configExists;
2373
2569
  const healthy = cliAvailable;
@@ -2405,13 +2601,13 @@ init_cursor();
2405
2601
  // packages/adapters/src/providers/gemini-cli/adapter.ts
2406
2602
  import { exec as exec4 } from "node:child_process";
2407
2603
  import { existsSync as existsSync10 } from "node:fs";
2408
- import { homedir as homedir11 } from "node:os";
2409
- import { join as join15 } from "node:path";
2604
+ import { homedir as homedir9 } from "node:os";
2605
+ import { join as join16 } from "node:path";
2410
2606
  import { promisify as promisify4 } from "node:util";
2411
2607
 
2412
2608
  // packages/adapters/src/providers/gemini-cli/hooks.ts
2413
- import { homedir as homedir9 } from "node:os";
2414
- import { join as join13 } from "node:path";
2609
+ import { homedir as homedir8 } from "node:os";
2610
+ import { join as join14 } from "node:path";
2415
2611
  var GEMINI_CLI_EVENT_MAP = {
2416
2612
  SessionStart: "SessionStart",
2417
2613
  SessionEnd: "SessionEnd",
@@ -2425,6 +2621,7 @@ var GEMINI_CLI_EVENT_MAP = {
2425
2621
  Notification: "Notification"
2426
2622
  };
2427
2623
  var GeminiCliHookProvider = class {
2624
+ /** Whether hooks have been registered for the current session. */
2428
2625
  registered = false;
2429
2626
  /**
2430
2627
  * Map a Gemini CLI native event name to a CAAMP hook event name.
@@ -2488,84 +2685,59 @@ var GeminiCliHookProvider = class {
2488
2685
  * @task T161 @epic T134
2489
2686
  */
2490
2687
  async getTranscript(_sessionId, _projectDir) {
2491
- return readLatestTranscript(join13(homedir9(), ".gemini"));
2688
+ return readLatestTranscript(join14(homedir8(), ".gemini"));
2492
2689
  }
2493
2690
  };
2494
2691
 
2495
2692
  // packages/adapters/src/providers/gemini-cli/install.ts
2496
- import { existsSync as existsSync9, mkdirSync as mkdirSync4, readFileSync as readFileSync6, writeFileSync as writeFileSync5 } from "node:fs";
2497
- import { homedir as homedir10 } from "node:os";
2498
- import { join as join14 } from "node:path";
2693
+ import { existsSync as existsSync9, readFileSync as readFileSync6, writeFileSync as writeFileSync5 } from "node:fs";
2694
+ import { join as join15 } from "node:path";
2499
2695
  var INSTRUCTION_REFERENCES4 = ["@~/.cleo/templates/CLEO-INJECTION.md", "@.cleo/memory-bridge.md"];
2500
- var MCP_SERVER_KEY4 = "cleo";
2501
2696
  var GeminiCliInstallProvider = class {
2502
2697
  /**
2503
2698
  * Install CLEO into a Gemini CLI environment.
2504
2699
  *
2505
- * @param options - Installation options including project directory and MCP server path
2700
+ * @param options - Installation options including project directory
2506
2701
  * @returns Result describing what was installed
2507
2702
  * @task T161
2508
2703
  */
2509
2704
  async install(options) {
2510
- const { projectDir, mcpServerPath } = options;
2705
+ const { projectDir } = options;
2511
2706
  const installedAt = (/* @__PURE__ */ new Date()).toISOString();
2512
2707
  let instructionFileUpdated = false;
2513
- let mcpRegistered = false;
2514
2708
  const details = {};
2515
- if (mcpServerPath) {
2516
- mcpRegistered = this.registerMcpServer(mcpServerPath);
2517
- if (mcpRegistered) {
2518
- details.mcpConfigPath = join14(homedir10(), ".gemini", "settings.json");
2519
- }
2520
- }
2521
2709
  instructionFileUpdated = this.updateInstructionFile(projectDir);
2522
2710
  if (instructionFileUpdated) {
2523
- details.instructionFile = join14(projectDir, "AGENTS.md");
2711
+ details.instructionFile = join15(projectDir, "AGENTS.md");
2524
2712
  }
2525
2713
  return {
2526
2714
  success: true,
2527
2715
  installedAt,
2528
2716
  instructionFileUpdated,
2529
- mcpRegistered,
2717
+ mcpRegistered: false,
2530
2718
  details
2531
2719
  };
2532
2720
  }
2533
2721
  /**
2534
2722
  * Uninstall CLEO from the Gemini CLI environment.
2535
2723
  *
2536
- * Removes the MCP server registration from ~/.gemini/settings.json.
2537
2724
  * Does not remove AGENTS.md references (they are harmless if CLEO is not present).
2538
2725
  * @task T161
2539
2726
  */
2540
2727
  async uninstall() {
2541
- const settingsPath = join14(homedir10(), ".gemini", "settings.json");
2542
- if (existsSync9(settingsPath)) {
2543
- try {
2544
- const raw = readFileSync6(settingsPath, "utf-8");
2545
- const config = JSON.parse(raw);
2546
- const mcpServers = config.mcpServers;
2547
- if (mcpServers && MCP_SERVER_KEY4 in mcpServers) {
2548
- delete mcpServers[MCP_SERVER_KEY4];
2549
- writeFileSync5(settingsPath, JSON.stringify(config, null, 2) + "\n", "utf-8");
2550
- }
2551
- } catch {
2552
- }
2553
- }
2554
2728
  }
2555
2729
  /**
2556
2730
  * Check whether CLEO is installed in the Gemini CLI environment.
2557
2731
  *
2558
- * Checks for MCP server registered in ~/.gemini/settings.json.
2559
- * Returns true if the CLEO MCP server entry is found.
2732
+ * Checks for CLEO references in AGENTS.md.
2560
2733
  * @task T161
2561
2734
  */
2562
2735
  async isInstalled() {
2563
- const settingsPath = join14(homedir10(), ".gemini", "settings.json");
2564
- if (existsSync9(settingsPath)) {
2736
+ const agentsMdPath = join15(process.cwd(), "AGENTS.md");
2737
+ if (existsSync9(agentsMdPath)) {
2565
2738
  try {
2566
- const config = JSON.parse(readFileSync6(settingsPath, "utf-8"));
2567
- const mcpServers = config.mcpServers;
2568
- if (mcpServers && MCP_SERVER_KEY4 in mcpServers) {
2739
+ const content = readFileSync6(agentsMdPath, "utf-8");
2740
+ if (INSTRUCTION_REFERENCES4.some((ref) => content.includes(ref))) {
2569
2741
  return true;
2570
2742
  }
2571
2743
  } catch {
@@ -2584,37 +2756,6 @@ var GeminiCliInstallProvider = class {
2584
2756
  async ensureInstructionReferences(projectDir) {
2585
2757
  this.updateInstructionFile(projectDir);
2586
2758
  }
2587
- /**
2588
- * Register the CLEO MCP server in ~/.gemini/settings.json.
2589
- *
2590
- * Gemini CLI stores its MCP server configuration in ~/.gemini/settings.json
2591
- * under the mcpServers key.
2592
- *
2593
- * @param mcpServerPath - Absolute path to the MCP server entry point
2594
- * @returns true if registration was performed or updated
2595
- */
2596
- registerMcpServer(mcpServerPath) {
2597
- const geminiDir = join14(homedir10(), ".gemini");
2598
- const settingsPath = join14(geminiDir, "settings.json");
2599
- let config = {};
2600
- mkdirSync4(geminiDir, { recursive: true });
2601
- if (existsSync9(settingsPath)) {
2602
- try {
2603
- config = JSON.parse(readFileSync6(settingsPath, "utf-8"));
2604
- } catch {
2605
- }
2606
- }
2607
- if (!config.mcpServers || typeof config.mcpServers !== "object") {
2608
- config.mcpServers = {};
2609
- }
2610
- const mcpServers = config.mcpServers;
2611
- mcpServers[MCP_SERVER_KEY4] = {
2612
- command: "node",
2613
- args: [mcpServerPath]
2614
- };
2615
- writeFileSync5(settingsPath, JSON.stringify(config, null, 2) + "\n", "utf-8");
2616
- return true;
2617
- }
2618
2759
  /**
2619
2760
  * Update AGENTS.md with CLEO @-references.
2620
2761
  *
@@ -2622,7 +2763,7 @@ var GeminiCliInstallProvider = class {
2622
2763
  * @returns true if the file was created or modified
2623
2764
  */
2624
2765
  updateInstructionFile(projectDir) {
2625
- const agentsMdPath = join14(projectDir, "AGENTS.md");
2766
+ const agentsMdPath = join15(projectDir, "AGENTS.md");
2626
2767
  let content = "";
2627
2768
  let existed = false;
2628
2769
  if (existsSync9(agentsMdPath)) {
@@ -2648,9 +2789,13 @@ var GeminiCliInstallProvider = class {
2648
2789
  // packages/adapters/src/providers/gemini-cli/adapter.ts
2649
2790
  var execAsync4 = promisify4(exec4);
2650
2791
  var GeminiCliAdapter = class {
2792
+ /** Unique provider identifier. */
2651
2793
  id = "gemini-cli";
2794
+ /** Human-readable provider name. */
2652
2795
  name = "Gemini CLI";
2796
+ /** Adapter version string. */
2653
2797
  version = "1.0.0";
2798
+ /** Declared capabilities for this provider. */
2654
2799
  capabilities = {
2655
2800
  supportsHooks: true,
2656
2801
  supportedHookEvents: [
@@ -2667,7 +2812,7 @@ var GeminiCliAdapter = class {
2667
2812
  ],
2668
2813
  supportsSpawn: false,
2669
2814
  supportsInstall: true,
2670
- supportsMcp: true,
2815
+ supportsMcp: false,
2671
2816
  supportsInstructionFiles: false,
2672
2817
  supportsContextMonitor: false,
2673
2818
  supportsStatusline: false,
@@ -2675,9 +2820,13 @@ var GeminiCliAdapter = class {
2675
2820
  supportsTransport: false,
2676
2821
  supportsTaskSync: false
2677
2822
  };
2823
+ /** Hook provider for CAAMP event mapping. */
2678
2824
  hooks;
2825
+ /** Install provider for managing instruction files. */
2679
2826
  install;
2827
+ /** Project directory this adapter was initialized with, or null. */
2680
2828
  projectDir = null;
2829
+ /** Whether {@link initialize} has been called. */
2681
2830
  initialized = false;
2682
2831
  constructor() {
2683
2832
  this.hooks = new GeminiCliHookProvider();
@@ -2734,7 +2883,7 @@ var GeminiCliAdapter = class {
2734
2883
  } catch {
2735
2884
  details.cliAvailable = false;
2736
2885
  }
2737
- const geminiConfigDir = join15(homedir11(), ".gemini");
2886
+ const geminiConfigDir = join16(homedir9(), ".gemini");
2738
2887
  const configExists = existsSync10(geminiConfigDir);
2739
2888
  details.configDirExists = configExists;
2740
2889
  const healthy = cliAvailable;
@@ -2769,12 +2918,13 @@ function createAdapter4() {
2769
2918
  // packages/adapters/src/providers/kimi/adapter.ts
2770
2919
  import { exec as exec5 } from "node:child_process";
2771
2920
  import { existsSync as existsSync12 } from "node:fs";
2772
- import { homedir as homedir13 } from "node:os";
2773
- import { join as join17 } from "node:path";
2921
+ import { homedir as homedir10 } from "node:os";
2922
+ import { join as join18 } from "node:path";
2774
2923
  import { promisify as promisify5 } from "node:util";
2775
2924
 
2776
2925
  // packages/adapters/src/providers/kimi/hooks.ts
2777
2926
  var KimiHookProvider = class {
2927
+ /** Whether hooks have been registered (always a no-op for Kimi). */
2778
2928
  registered = false;
2779
2929
  /**
2780
2930
  * Map a Kimi native event name to a CAAMP hook event name.
@@ -2828,79 +2978,54 @@ var KimiHookProvider = class {
2828
2978
  };
2829
2979
 
2830
2980
  // packages/adapters/src/providers/kimi/install.ts
2831
- import { existsSync as existsSync11, mkdirSync as mkdirSync5, readFileSync as readFileSync7, writeFileSync as writeFileSync6 } from "node:fs";
2832
- import { homedir as homedir12 } from "node:os";
2833
- import { join as join16 } from "node:path";
2981
+ import { existsSync as existsSync11, readFileSync as readFileSync7, writeFileSync as writeFileSync6 } from "node:fs";
2982
+ import { join as join17 } from "node:path";
2834
2983
  var INSTRUCTION_REFERENCES5 = ["@~/.cleo/templates/CLEO-INJECTION.md", "@.cleo/memory-bridge.md"];
2835
- var MCP_SERVER_KEY5 = "cleo";
2836
2984
  var KimiInstallProvider = class {
2837
2985
  /**
2838
2986
  * Install CLEO into a Kimi environment.
2839
2987
  *
2840
- * @param options - Installation options including project directory and MCP server path
2988
+ * @param options - Installation options including project directory
2841
2989
  * @returns Result describing what was installed
2842
2990
  * @task T163
2843
2991
  */
2844
2992
  async install(options) {
2845
- const { projectDir, mcpServerPath } = options;
2993
+ const { projectDir } = options;
2846
2994
  const installedAt = (/* @__PURE__ */ new Date()).toISOString();
2847
2995
  let instructionFileUpdated = false;
2848
- let mcpRegistered = false;
2849
2996
  const details = {};
2850
- if (mcpServerPath) {
2851
- mcpRegistered = this.registerMcpServer(mcpServerPath);
2852
- if (mcpRegistered) {
2853
- details.mcpConfigPath = join16(homedir12(), ".kimi", "mcp.json");
2854
- }
2855
- }
2856
2997
  instructionFileUpdated = this.updateInstructionFile(projectDir);
2857
2998
  if (instructionFileUpdated) {
2858
- details.instructionFile = join16(projectDir, "AGENTS.md");
2999
+ details.instructionFile = join17(projectDir, "AGENTS.md");
2859
3000
  }
2860
3001
  return {
2861
3002
  success: true,
2862
3003
  installedAt,
2863
3004
  instructionFileUpdated,
2864
- mcpRegistered,
3005
+ mcpRegistered: false,
2865
3006
  details
2866
3007
  };
2867
3008
  }
2868
3009
  /**
2869
3010
  * Uninstall CLEO from the Kimi environment.
2870
3011
  *
2871
- * Removes the MCP server registration from ~/.kimi/mcp.json.
2872
3012
  * Does not remove AGENTS.md references (they are harmless if CLEO is not present).
2873
3013
  * @task T163
2874
3014
  */
2875
3015
  async uninstall() {
2876
- const mcpPath = join16(homedir12(), ".kimi", "mcp.json");
2877
- if (existsSync11(mcpPath)) {
2878
- try {
2879
- const raw = readFileSync7(mcpPath, "utf-8");
2880
- const config = JSON.parse(raw);
2881
- const mcpServers = config.mcpServers;
2882
- if (mcpServers && MCP_SERVER_KEY5 in mcpServers) {
2883
- delete mcpServers[MCP_SERVER_KEY5];
2884
- writeFileSync6(mcpPath, JSON.stringify(config, null, 2) + "\n", "utf-8");
2885
- }
2886
- } catch {
2887
- }
2888
- }
2889
3016
  }
2890
3017
  /**
2891
3018
  * Check whether CLEO is installed in the Kimi environment.
2892
3019
  *
2893
- * Checks for MCP server registered in ~/.kimi/mcp.json.
2894
- * Returns true if the CLEO MCP server entry is found.
3020
+ * Checks for CLEO references in AGENTS.md.
2895
3021
  * @task T163
2896
3022
  */
2897
3023
  async isInstalled() {
2898
- const mcpPath = join16(homedir12(), ".kimi", "mcp.json");
2899
- if (existsSync11(mcpPath)) {
3024
+ const agentsMdPath = join17(process.cwd(), "AGENTS.md");
3025
+ if (existsSync11(agentsMdPath)) {
2900
3026
  try {
2901
- const config = JSON.parse(readFileSync7(mcpPath, "utf-8"));
2902
- const mcpServers = config.mcpServers;
2903
- if (mcpServers && MCP_SERVER_KEY5 in mcpServers) {
3027
+ const content = readFileSync7(agentsMdPath, "utf-8");
3028
+ if (INSTRUCTION_REFERENCES5.some((ref) => content.includes(ref))) {
2904
3029
  return true;
2905
3030
  }
2906
3031
  } catch {
@@ -2919,37 +3044,6 @@ var KimiInstallProvider = class {
2919
3044
  async ensureInstructionReferences(projectDir) {
2920
3045
  this.updateInstructionFile(projectDir);
2921
3046
  }
2922
- /**
2923
- * Register the CLEO MCP server in ~/.kimi/mcp.json.
2924
- *
2925
- * Kimi stores its MCP server configuration in ~/.kimi/mcp.json
2926
- * under the mcpServers key.
2927
- *
2928
- * @param mcpServerPath - Absolute path to the MCP server entry point
2929
- * @returns true if registration was performed or updated
2930
- */
2931
- registerMcpServer(mcpServerPath) {
2932
- const kimiDir = join16(homedir12(), ".kimi");
2933
- const mcpPath = join16(kimiDir, "mcp.json");
2934
- let config = {};
2935
- mkdirSync5(kimiDir, { recursive: true });
2936
- if (existsSync11(mcpPath)) {
2937
- try {
2938
- config = JSON.parse(readFileSync7(mcpPath, "utf-8"));
2939
- } catch {
2940
- }
2941
- }
2942
- if (!config.mcpServers || typeof config.mcpServers !== "object") {
2943
- config.mcpServers = {};
2944
- }
2945
- const mcpServers = config.mcpServers;
2946
- mcpServers[MCP_SERVER_KEY5] = {
2947
- command: "node",
2948
- args: [mcpServerPath]
2949
- };
2950
- writeFileSync6(mcpPath, JSON.stringify(config, null, 2) + "\n", "utf-8");
2951
- return true;
2952
- }
2953
3047
  /**
2954
3048
  * Update AGENTS.md with CLEO @-references.
2955
3049
  *
@@ -2957,7 +3051,7 @@ var KimiInstallProvider = class {
2957
3051
  * @returns true if the file was created or modified
2958
3052
  */
2959
3053
  updateInstructionFile(projectDir) {
2960
- const agentsMdPath = join16(projectDir, "AGENTS.md");
3054
+ const agentsMdPath = join17(projectDir, "AGENTS.md");
2961
3055
  let content = "";
2962
3056
  let existed = false;
2963
3057
  if (existsSync11(agentsMdPath)) {
@@ -2983,15 +3077,19 @@ var KimiInstallProvider = class {
2983
3077
  // packages/adapters/src/providers/kimi/adapter.ts
2984
3078
  var execAsync5 = promisify5(exec5);
2985
3079
  var KimiAdapter = class {
3080
+ /** Unique provider identifier. */
2986
3081
  id = "kimi";
3082
+ /** Human-readable provider name. */
2987
3083
  name = "Kimi";
3084
+ /** Adapter version string. */
2988
3085
  version = "1.0.0";
3086
+ /** Declared capabilities for this provider. */
2989
3087
  capabilities = {
2990
3088
  supportsHooks: false,
2991
3089
  supportedHookEvents: [],
2992
3090
  supportsSpawn: false,
2993
3091
  supportsInstall: true,
2994
- supportsMcp: true,
3092
+ supportsMcp: false,
2995
3093
  supportsInstructionFiles: false,
2996
3094
  supportsContextMonitor: false,
2997
3095
  supportsStatusline: false,
@@ -2999,9 +3097,13 @@ var KimiAdapter = class {
2999
3097
  supportsTransport: false,
3000
3098
  supportsTaskSync: false
3001
3099
  };
3100
+ /** Hook provider (no-op since Kimi has no event system). */
3002
3101
  hooks;
3102
+ /** Install provider for managing instruction files. */
3003
3103
  install;
3104
+ /** Project directory this adapter was initialized with, or null. */
3004
3105
  projectDir = null;
3106
+ /** Whether {@link initialize} has been called. */
3005
3107
  initialized = false;
3006
3108
  constructor() {
3007
3109
  this.hooks = new KimiHookProvider();
@@ -3056,7 +3158,7 @@ var KimiAdapter = class {
3056
3158
  } catch {
3057
3159
  details.cliAvailable = false;
3058
3160
  }
3059
- const kimiConfigDir = join17(homedir13(), ".kimi");
3161
+ const kimiConfigDir = join18(homedir10(), ".kimi");
3060
3162
  const configExists = existsSync12(kimiConfigDir);
3061
3163
  details.configDirExists = configExists;
3062
3164
  const healthy = cliAvailable;
@@ -3091,9 +3193,9 @@ function createAdapter5() {
3091
3193
  // packages/adapters/src/index.ts
3092
3194
  init_opencode();
3093
3195
 
3094
- // packages/adapters/src/registry.js
3196
+ // packages/adapters/src/registry.ts
3095
3197
  import { readFileSync as readFileSync9 } from "node:fs";
3096
- import { dirname as dirname2, join as join21, resolve } from "node:path";
3198
+ import { dirname as dirname2, join as join22, resolve } from "node:path";
3097
3199
  import { fileURLToPath } from "node:url";
3098
3200
  var PROVIDER_IDS = ["claude-code", "opencode", "cursor"];
3099
3201
  function getProviderManifests() {
@@ -3101,7 +3203,7 @@ function getProviderManifests() {
3101
3203
  const baseDir = resolve(dirname2(fileURLToPath(import.meta.url)), "providers");
3102
3204
  for (const providerId of PROVIDER_IDS) {
3103
3205
  try {
3104
- const manifestPath = join21(baseDir, providerId, "manifest.json");
3206
+ const manifestPath = join22(baseDir, providerId, "manifest.json");
3105
3207
  const raw = readFileSync9(manifestPath, "utf-8");
3106
3208
  manifests.push(JSON.parse(raw));
3107
3209
  } catch {