@alan-ai-hq/agent-manager 0.1.78 → 0.1.80

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 (342) hide show
  1. package/dist/__tests__/binding-switch-git.test.d.ts +2 -0
  2. package/dist/__tests__/binding-switch-git.test.d.ts.map +1 -0
  3. package/dist/__tests__/binding-switch-git.test.js +610 -0
  4. package/dist/__tests__/binding-switch-git.test.js.map +1 -0
  5. package/dist/__tests__/cli-ensure-install.test.d.ts +2 -0
  6. package/dist/__tests__/cli-ensure-install.test.d.ts.map +1 -0
  7. package/dist/__tests__/cli-ensure-install.test.js +109 -0
  8. package/dist/__tests__/cli-ensure-install.test.js.map +1 -0
  9. package/dist/__tests__/cli-executable.test.d.ts +2 -0
  10. package/dist/__tests__/cli-executable.test.d.ts.map +1 -0
  11. package/dist/__tests__/cli-executable.test.js +129 -0
  12. package/dist/__tests__/cli-executable.test.js.map +1 -0
  13. package/dist/__tests__/cli-help.test.d.ts +2 -0
  14. package/dist/__tests__/cli-help.test.d.ts.map +1 -0
  15. package/dist/__tests__/cli-help.test.js +34 -0
  16. package/dist/__tests__/cli-help.test.js.map +1 -0
  17. package/dist/__tests__/computer-readiness.test.d.ts +2 -0
  18. package/dist/__tests__/computer-readiness.test.d.ts.map +1 -0
  19. package/dist/__tests__/computer-readiness.test.js +63 -0
  20. package/dist/__tests__/computer-readiness.test.js.map +1 -0
  21. package/dist/__tests__/core-agent-workflow-context.test.d.ts +2 -0
  22. package/dist/__tests__/core-agent-workflow-context.test.d.ts.map +1 -0
  23. package/dist/__tests__/core-agent-workflow-context.test.js +139 -0
  24. package/dist/__tests__/core-agent-workflow-context.test.js.map +1 -0
  25. package/dist/__tests__/daemon-reconcile-ask.test.d.ts +2 -0
  26. package/dist/__tests__/daemon-reconcile-ask.test.d.ts.map +1 -0
  27. package/dist/__tests__/daemon-reconcile-ask.test.js +86 -0
  28. package/dist/__tests__/daemon-reconcile-ask.test.js.map +1 -0
  29. package/dist/__tests__/daemon-socket.integration.test.d.ts +2 -0
  30. package/dist/__tests__/daemon-socket.integration.test.d.ts.map +1 -0
  31. package/dist/__tests__/daemon-socket.integration.test.js +450 -0
  32. package/dist/__tests__/daemon-socket.integration.test.js.map +1 -0
  33. package/dist/__tests__/daemon.test.d.ts +2 -0
  34. package/dist/__tests__/daemon.test.d.ts.map +1 -0
  35. package/dist/__tests__/daemon.test.js +3975 -0
  36. package/dist/__tests__/daemon.test.js.map +1 -0
  37. package/dist/__tests__/ensure-shared-checkout-branch.test.d.ts +2 -0
  38. package/dist/__tests__/ensure-shared-checkout-branch.test.d.ts.map +1 -0
  39. package/dist/__tests__/ensure-shared-checkout-branch.test.js +129 -0
  40. package/dist/__tests__/ensure-shared-checkout-branch.test.js.map +1 -0
  41. package/dist/__tests__/event-outbox-persist-failure.test.d.ts +2 -0
  42. package/dist/__tests__/event-outbox-persist-failure.test.d.ts.map +1 -0
  43. package/dist/__tests__/event-outbox-persist-failure.test.js +84 -0
  44. package/dist/__tests__/event-outbox-persist-failure.test.js.map +1 -0
  45. package/dist/__tests__/event-outbox.test.d.ts +2 -0
  46. package/dist/__tests__/event-outbox.test.d.ts.map +1 -0
  47. package/dist/__tests__/event-outbox.test.js +256 -0
  48. package/dist/__tests__/event-outbox.test.js.map +1 -0
  49. package/dist/__tests__/fake-provider-cli.test.d.ts +2 -0
  50. package/dist/__tests__/fake-provider-cli.test.d.ts.map +1 -0
  51. package/dist/__tests__/fake-provider-cli.test.js +46 -0
  52. package/dist/__tests__/fake-provider-cli.test.js.map +1 -0
  53. package/dist/__tests__/generated-images.test.d.ts +2 -0
  54. package/dist/__tests__/generated-images.test.d.ts.map +1 -0
  55. package/dist/__tests__/generated-images.test.js +132 -0
  56. package/dist/__tests__/generated-images.test.js.map +1 -0
  57. package/dist/__tests__/lifecycle-logger.test.d.ts +2 -0
  58. package/dist/__tests__/lifecycle-logger.test.d.ts.map +1 -0
  59. package/dist/__tests__/lifecycle-logger.test.js +49 -0
  60. package/dist/__tests__/lifecycle-logger.test.js.map +1 -0
  61. package/dist/__tests__/local-skill-scan.test.d.ts +2 -0
  62. package/dist/__tests__/local-skill-scan.test.d.ts.map +1 -0
  63. package/dist/__tests__/local-skill-scan.test.js +91 -0
  64. package/dist/__tests__/local-skill-scan.test.js.map +1 -0
  65. package/dist/__tests__/local-workspace-migration.test.d.ts +2 -0
  66. package/dist/__tests__/local-workspace-migration.test.d.ts.map +1 -0
  67. package/dist/__tests__/local-workspace-migration.test.js +195 -0
  68. package/dist/__tests__/local-workspace-migration.test.js.map +1 -0
  69. package/dist/__tests__/mcp-inspect-timeout.test.d.ts +2 -0
  70. package/dist/__tests__/mcp-inspect-timeout.test.d.ts.map +1 -0
  71. package/dist/__tests__/mcp-inspect-timeout.test.js +97 -0
  72. package/dist/__tests__/mcp-inspect-timeout.test.js.map +1 -0
  73. package/dist/__tests__/mcp-readiness.test.d.ts +2 -0
  74. package/dist/__tests__/mcp-readiness.test.d.ts.map +1 -0
  75. package/dist/__tests__/mcp-readiness.test.js +267 -0
  76. package/dist/__tests__/mcp-readiness.test.js.map +1 -0
  77. package/dist/__tests__/mcp-registration-cli.test.d.ts +2 -0
  78. package/dist/__tests__/mcp-registration-cli.test.d.ts.map +1 -0
  79. package/dist/__tests__/mcp-registration-cli.test.js +71 -0
  80. package/dist/__tests__/mcp-registration-cli.test.js.map +1 -0
  81. package/dist/__tests__/mcp-registration.test.d.ts +2 -0
  82. package/dist/__tests__/mcp-registration.test.d.ts.map +1 -0
  83. package/dist/__tests__/mcp-registration.test.js +426 -0
  84. package/dist/__tests__/mcp-registration.test.js.map +1 -0
  85. package/dist/__tests__/model-scan-runner.test.d.ts +2 -0
  86. package/dist/__tests__/model-scan-runner.test.d.ts.map +1 -0
  87. package/dist/__tests__/model-scan-runner.test.js +67 -0
  88. package/dist/__tests__/model-scan-runner.test.js.map +1 -0
  89. package/dist/__tests__/network-diagnostics.test.d.ts +2 -0
  90. package/dist/__tests__/network-diagnostics.test.d.ts.map +1 -0
  91. package/dist/__tests__/network-diagnostics.test.js +26 -0
  92. package/dist/__tests__/network-diagnostics.test.js.map +1 -0
  93. package/dist/__tests__/observable-map.test.d.ts +2 -0
  94. package/dist/__tests__/observable-map.test.d.ts.map +1 -0
  95. package/dist/__tests__/observable-map.test.js +54 -0
  96. package/dist/__tests__/observable-map.test.js.map +1 -0
  97. package/dist/__tests__/provider-auth-preflight.test.d.ts +2 -0
  98. package/dist/__tests__/provider-auth-preflight.test.d.ts.map +1 -0
  99. package/dist/__tests__/provider-auth-preflight.test.js +123 -0
  100. package/dist/__tests__/provider-auth-preflight.test.js.map +1 -0
  101. package/dist/__tests__/provider-model-discovery.test.d.ts +2 -0
  102. package/dist/__tests__/provider-model-discovery.test.d.ts.map +1 -0
  103. package/dist/__tests__/provider-model-discovery.test.js +472 -0
  104. package/dist/__tests__/provider-model-discovery.test.js.map +1 -0
  105. package/dist/__tests__/remove-worktrees-if-clean.test.d.ts +2 -0
  106. package/dist/__tests__/remove-worktrees-if-clean.test.d.ts.map +1 -0
  107. package/dist/__tests__/remove-worktrees-if-clean.test.js +221 -0
  108. package/dist/__tests__/remove-worktrees-if-clean.test.js.map +1 -0
  109. package/dist/__tests__/resume-fallback-env.test.d.ts +2 -0
  110. package/dist/__tests__/resume-fallback-env.test.d.ts.map +1 -0
  111. package/dist/__tests__/resume-fallback-env.test.js +28 -0
  112. package/dist/__tests__/resume-fallback-env.test.js.map +1 -0
  113. package/dist/__tests__/run-journal.test.d.ts +2 -0
  114. package/dist/__tests__/run-journal.test.d.ts.map +1 -0
  115. package/dist/__tests__/run-journal.test.js +121 -0
  116. package/dist/__tests__/run-journal.test.js.map +1 -0
  117. package/dist/__tests__/run-start-gate.test.d.ts +2 -0
  118. package/dist/__tests__/run-start-gate.test.d.ts.map +1 -0
  119. package/dist/__tests__/run-start-gate.test.js +29 -0
  120. package/dist/__tests__/run-start-gate.test.js.map +1 -0
  121. package/dist/__tests__/runtime-capabilities-sync.test.d.ts +2 -0
  122. package/dist/__tests__/runtime-capabilities-sync.test.d.ts.map +1 -0
  123. package/dist/__tests__/runtime-capabilities-sync.test.js +66 -0
  124. package/dist/__tests__/runtime-capabilities-sync.test.js.map +1 -0
  125. package/dist/__tests__/runtime-config.test.d.ts +2 -0
  126. package/dist/__tests__/runtime-config.test.d.ts.map +1 -0
  127. package/dist/__tests__/runtime-config.test.js +102 -0
  128. package/dist/__tests__/runtime-config.test.js.map +1 -0
  129. package/dist/__tests__/runtime-presenter-heartbeat.test.d.ts +2 -0
  130. package/dist/__tests__/runtime-presenter-heartbeat.test.d.ts.map +1 -0
  131. package/dist/__tests__/runtime-presenter-heartbeat.test.js +159 -0
  132. package/dist/__tests__/runtime-presenter-heartbeat.test.js.map +1 -0
  133. package/dist/__tests__/sandbox-outbox.test.d.ts +2 -0
  134. package/dist/__tests__/sandbox-outbox.test.d.ts.map +1 -0
  135. package/dist/__tests__/sandbox-outbox.test.js +214 -0
  136. package/dist/__tests__/sandbox-outbox.test.js.map +1 -0
  137. package/dist/__tests__/sandbox-workflow-context.test.d.ts +2 -0
  138. package/dist/__tests__/sandbox-workflow-context.test.d.ts.map +1 -0
  139. package/dist/__tests__/sandbox-workflow-context.test.js +396 -0
  140. package/dist/__tests__/sandbox-workflow-context.test.js.map +1 -0
  141. package/dist/__tests__/service-manager.test.d.ts +2 -0
  142. package/dist/__tests__/service-manager.test.d.ts.map +1 -0
  143. package/dist/__tests__/service-manager.test.js +50 -0
  144. package/dist/__tests__/service-manager.test.js.map +1 -0
  145. package/dist/__tests__/sleep-inhibitor.test.d.ts +2 -0
  146. package/dist/__tests__/sleep-inhibitor.test.d.ts.map +1 -0
  147. package/dist/__tests__/sleep-inhibitor.test.js +236 -0
  148. package/dist/__tests__/sleep-inhibitor.test.js.map +1 -0
  149. package/dist/__tests__/status-local-workspace.test.d.ts +2 -0
  150. package/dist/__tests__/status-local-workspace.test.d.ts.map +1 -0
  151. package/dist/__tests__/status-local-workspace.test.js +121 -0
  152. package/dist/__tests__/status-local-workspace.test.js.map +1 -0
  153. package/dist/__tests__/suspension-detector.test.d.ts +2 -0
  154. package/dist/__tests__/suspension-detector.test.d.ts.map +1 -0
  155. package/dist/__tests__/suspension-detector.test.js +112 -0
  156. package/dist/__tests__/suspension-detector.test.js.map +1 -0
  157. package/dist/__tests__/web-presenter-parent-events.test.d.ts +2 -0
  158. package/dist/__tests__/web-presenter-parent-events.test.d.ts.map +1 -0
  159. package/dist/__tests__/web-presenter-parent-events.test.js +130 -0
  160. package/dist/__tests__/web-presenter-parent-events.test.js.map +1 -0
  161. package/dist/__tests__/workspace-relocation.test.d.ts +2 -0
  162. package/dist/__tests__/workspace-relocation.test.d.ts.map +1 -0
  163. package/dist/__tests__/workspace-relocation.test.js +66 -0
  164. package/dist/__tests__/workspace-relocation.test.js.map +1 -0
  165. package/dist/__tests__/workspace-run-lease.test.d.ts +2 -0
  166. package/dist/__tests__/workspace-run-lease.test.d.ts.map +1 -0
  167. package/dist/__tests__/workspace-run-lease.test.js +230 -0
  168. package/dist/__tests__/workspace-run-lease.test.js.map +1 -0
  169. package/dist/__tests__/ws-client-heartbeat-volatile.test.d.ts +2 -0
  170. package/dist/__tests__/ws-client-heartbeat-volatile.test.d.ts.map +1 -0
  171. package/dist/__tests__/ws-client-heartbeat-volatile.test.js +61 -0
  172. package/dist/__tests__/ws-client-heartbeat-volatile.test.js.map +1 -0
  173. package/dist/__tests__/ws-client-heartbeat.integration.test.d.ts +2 -0
  174. package/dist/__tests__/ws-client-heartbeat.integration.test.d.ts.map +1 -0
  175. package/dist/__tests__/ws-client-heartbeat.integration.test.js +109 -0
  176. package/dist/__tests__/ws-client-heartbeat.integration.test.js.map +1 -0
  177. package/dist/__tests__/ws-client-user-message-ack.integration.test.d.ts +2 -0
  178. package/dist/__tests__/ws-client-user-message-ack.integration.test.d.ts.map +1 -0
  179. package/dist/__tests__/ws-client-user-message-ack.integration.test.js +167 -0
  180. package/dist/__tests__/ws-client-user-message-ack.integration.test.js.map +1 -0
  181. package/dist/aiden-system-prompt.d.ts +6 -0
  182. package/dist/aiden-system-prompt.d.ts.map +1 -0
  183. package/dist/aiden-system-prompt.js +6 -0
  184. package/dist/aiden-system-prompt.js.map +1 -0
  185. package/dist/binding-switch-git.d.ts +26 -0
  186. package/dist/binding-switch-git.d.ts.map +1 -0
  187. package/dist/binding-switch-git.js +973 -0
  188. package/dist/binding-switch-git.js.map +1 -0
  189. package/dist/cli-ensure-install.d.ts +39 -0
  190. package/dist/cli-ensure-install.d.ts.map +1 -0
  191. package/dist/cli-ensure-install.js +133 -0
  192. package/dist/cli-ensure-install.js.map +1 -0
  193. package/dist/cli-executable.d.ts +97 -0
  194. package/dist/cli-executable.d.ts.map +1 -0
  195. package/dist/cli-executable.js +432 -0
  196. package/dist/cli-executable.js.map +1 -0
  197. package/dist/cli-help.d.ts +7 -0
  198. package/dist/cli-help.d.ts.map +1 -0
  199. package/dist/cli-help.js +49 -0
  200. package/dist/cli-help.js.map +1 -0
  201. package/dist/computer-readiness.d.ts +42 -0
  202. package/dist/computer-readiness.d.ts.map +1 -0
  203. package/dist/computer-readiness.js +191 -0
  204. package/dist/computer-readiness.js.map +1 -0
  205. package/dist/core-agent.d.ts +47 -0
  206. package/dist/core-agent.d.ts.map +1 -0
  207. package/dist/core-agent.js +364 -0
  208. package/dist/core-agent.js.map +1 -0
  209. package/dist/daemon.d.ts +392 -0
  210. package/dist/daemon.d.ts.map +1 -0
  211. package/dist/daemon.js +4711 -0
  212. package/dist/daemon.js.map +1 -0
  213. package/dist/event-outbox.d.ts +83 -0
  214. package/dist/event-outbox.d.ts.map +1 -0
  215. package/dist/event-outbox.js +440 -0
  216. package/dist/event-outbox.js.map +1 -0
  217. package/dist/fake-provider-cli.d.ts +13 -0
  218. package/dist/fake-provider-cli.d.ts.map +1 -0
  219. package/dist/fake-provider-cli.js +53 -0
  220. package/dist/fake-provider-cli.js.map +1 -0
  221. package/dist/generated-images.d.ts +2 -0
  222. package/dist/generated-images.d.ts.map +1 -0
  223. package/dist/generated-images.js +2 -0
  224. package/dist/generated-images.js.map +1 -0
  225. package/dist/index.cjs +1037 -188
  226. package/dist/index.d.ts +6 -0
  227. package/dist/index.d.ts.map +1 -0
  228. package/dist/index.js +209 -0
  229. package/dist/index.js.map +1 -0
  230. package/dist/lifecycle-logger.d.ts +25 -0
  231. package/dist/lifecycle-logger.d.ts.map +1 -0
  232. package/dist/lifecycle-logger.js +73 -0
  233. package/dist/lifecycle-logger.js.map +1 -0
  234. package/dist/local-skill-scan.d.ts +21 -0
  235. package/dist/local-skill-scan.d.ts.map +1 -0
  236. package/dist/local-skill-scan.js +109 -0
  237. package/dist/local-skill-scan.js.map +1 -0
  238. package/dist/local-workspace-migration.d.ts +68 -0
  239. package/dist/local-workspace-migration.d.ts.map +1 -0
  240. package/dist/local-workspace-migration.js +157 -0
  241. package/dist/local-workspace-migration.js.map +1 -0
  242. package/dist/mcp-readiness.d.ts +59 -0
  243. package/dist/mcp-readiness.d.ts.map +1 -0
  244. package/dist/mcp-readiness.js +202 -0
  245. package/dist/mcp-readiness.js.map +1 -0
  246. package/dist/mcp-registration.d.ts +75 -0
  247. package/dist/mcp-registration.d.ts.map +1 -0
  248. package/dist/mcp-registration.js +563 -0
  249. package/dist/mcp-registration.js.map +1 -0
  250. package/dist/model-scan-runner.d.ts +15 -0
  251. package/dist/model-scan-runner.d.ts.map +1 -0
  252. package/dist/model-scan-runner.js +51 -0
  253. package/dist/model-scan-runner.js.map +1 -0
  254. package/dist/network-diagnostics.d.ts +8 -0
  255. package/dist/network-diagnostics.d.ts.map +1 -0
  256. package/dist/network-diagnostics.js +56 -0
  257. package/dist/network-diagnostics.js.map +1 -0
  258. package/dist/observable-map.d.ts +25 -0
  259. package/dist/observable-map.d.ts.map +1 -0
  260. package/dist/observable-map.js +42 -0
  261. package/dist/observable-map.js.map +1 -0
  262. package/dist/provider-auth-preflight.d.ts +22 -0
  263. package/dist/provider-auth-preflight.d.ts.map +1 -0
  264. package/dist/provider-auth-preflight.js +110 -0
  265. package/dist/provider-auth-preflight.js.map +1 -0
  266. package/dist/provider-model-discovery.d.ts +38 -0
  267. package/dist/provider-model-discovery.d.ts.map +1 -0
  268. package/dist/provider-model-discovery.js +519 -0
  269. package/dist/provider-model-discovery.js.map +1 -0
  270. package/dist/resume-fallback-env.d.ts +20 -0
  271. package/dist/resume-fallback-env.d.ts.map +1 -0
  272. package/dist/resume-fallback-env.js +30 -0
  273. package/dist/resume-fallback-env.js.map +1 -0
  274. package/dist/run-journal.d.ts +53 -0
  275. package/dist/run-journal.d.ts.map +1 -0
  276. package/dist/run-journal.js +193 -0
  277. package/dist/run-journal.js.map +1 -0
  278. package/dist/run-start-gate.d.ts +9 -0
  279. package/dist/run-start-gate.d.ts.map +1 -0
  280. package/dist/run-start-gate.js +24 -0
  281. package/dist/run-start-gate.js.map +1 -0
  282. package/dist/runtime-backends.d.ts +2 -0
  283. package/dist/runtime-backends.d.ts.map +1 -0
  284. package/dist/runtime-backends.js +2 -0
  285. package/dist/runtime-backends.js.map +1 -0
  286. package/dist/runtime-capabilities-sync.d.ts +33 -0
  287. package/dist/runtime-capabilities-sync.d.ts.map +1 -0
  288. package/dist/runtime-capabilities-sync.js +56 -0
  289. package/dist/runtime-capabilities-sync.js.map +1 -0
  290. package/dist/runtime-config.d.ts +24 -0
  291. package/dist/runtime-config.d.ts.map +1 -0
  292. package/dist/runtime-config.js +124 -0
  293. package/dist/runtime-config.js.map +1 -0
  294. package/dist/sandbox-outbox.d.ts +122 -0
  295. package/dist/sandbox-outbox.d.ts.map +1 -0
  296. package/dist/sandbox-outbox.js +180 -0
  297. package/dist/sandbox-outbox.js.map +1 -0
  298. package/dist/sandbox.d.ts +44 -0
  299. package/dist/sandbox.d.ts.map +1 -0
  300. package/dist/sandbox.js +438 -0
  301. package/dist/sandbox.js.map +1 -0
  302. package/dist/service-manager.d.ts +28 -0
  303. package/dist/service-manager.d.ts.map +1 -0
  304. package/dist/service-manager.js +259 -0
  305. package/dist/service-manager.js.map +1 -0
  306. package/dist/sleep-inhibitor.d.ts +111 -0
  307. package/dist/sleep-inhibitor.d.ts.map +1 -0
  308. package/dist/sleep-inhibitor.js +412 -0
  309. package/dist/sleep-inhibitor.js.map +1 -0
  310. package/dist/suspension-detector.d.ts +48 -0
  311. package/dist/suspension-detector.d.ts.map +1 -0
  312. package/dist/suspension-detector.js +89 -0
  313. package/dist/suspension-detector.js.map +1 -0
  314. package/dist/types.d.ts +6 -0
  315. package/dist/types.d.ts.map +1 -0
  316. package/dist/types.js +6 -0
  317. package/dist/types.js.map +1 -0
  318. package/dist/updater.d.ts +15 -0
  319. package/dist/updater.d.ts.map +1 -0
  320. package/dist/updater.js +50 -0
  321. package/dist/updater.js.map +1 -0
  322. package/dist/version.d.ts +2 -0
  323. package/dist/version.d.ts.map +1 -0
  324. package/dist/version.js +2 -0
  325. package/dist/version.js.map +1 -0
  326. package/dist/web-presenter.d.ts +55 -0
  327. package/dist/web-presenter.d.ts.map +1 -0
  328. package/dist/web-presenter.js +265 -0
  329. package/dist/web-presenter.js.map +1 -0
  330. package/dist/workspace-relocation.d.ts +22 -0
  331. package/dist/workspace-relocation.d.ts.map +1 -0
  332. package/dist/workspace-relocation.js +90 -0
  333. package/dist/workspace-relocation.js.map +1 -0
  334. package/dist/workspace-run-lease.d.ts +97 -0
  335. package/dist/workspace-run-lease.d.ts.map +1 -0
  336. package/dist/workspace-run-lease.js +241 -0
  337. package/dist/workspace-run-lease.js.map +1 -0
  338. package/dist/ws-client.d.ts +194 -0
  339. package/dist/ws-client.d.ts.map +1 -0
  340. package/dist/ws-client.js +282 -0
  341. package/dist/ws-client.js.map +1 -0
  342. package/package.json +1 -1
package/dist/index.cjs CHANGED
@@ -15240,7 +15240,7 @@ function describeError(error61) {
15240
15240
  }
15241
15241
 
15242
15242
  // src/version.ts
15243
- var AGENT_VERSION = "0.1.78";
15243
+ var AGENT_VERSION = "0.1.80";
15244
15244
 
15245
15245
  // src/daemon-worktree.ts
15246
15246
  var import_node_child_process3 = require("child_process");
@@ -15576,8 +15576,8 @@ var RESOURCE_CLASS_GC_TIME_MS = {
15576
15576
  var import_node_fs2 = require("fs");
15577
15577
  var import_node_os2 = require("os");
15578
15578
  var import_node_path2 = require("path");
15579
- function resolveAlanDefaultWorkspacePath(homeDirectory = (0, import_node_os2.homedir)()) {
15580
- return (0, import_node_path2.join)(homeDirectory, ".alan", "workspace");
15579
+ function resolveAlanDefaultWorkspacePath(homeDirectory2 = (0, import_node_os2.homedir)()) {
15580
+ return (0, import_node_path2.join)(homeDirectory2, ".alan", "workspace");
15581
15581
  }
15582
15582
 
15583
15583
  // src/local-workspace-migration.ts
@@ -35665,6 +35665,22 @@ var import_node_os4 = require("os");
35665
35665
  var import_node_path5 = require("path");
35666
35666
  var DEFAULT_AGENT_DIR = (0, import_node_path5.join)((0, import_node_os4.homedir)(), ".alan", "agent");
35667
35667
  var LEGACY_AGENT_DIR = (0, import_node_path5.join)((0, import_node_os4.homedir)(), ".aiden", "agent");
35668
+ function configuredConfigPathFromEnvironment() {
35669
+ const explicit = process.env.ALAN_AGENT_CONFIG_PATH?.trim() || process.env.ALAN_AGENT_CONFIG?.trim();
35670
+ return explicit || void 0;
35671
+ }
35672
+ function resolveIsolatedAgentBaseDir(profile) {
35673
+ switch (profile) {
35674
+ case "local":
35675
+ return (0, import_node_path5.join)((0, import_node_os4.homedir)(), ".alan-dev", "agent");
35676
+ case "staging":
35677
+ return (0, import_node_path5.join)((0, import_node_os4.homedir)(), ".alan-staging", "agent");
35678
+ case "custom":
35679
+ return (0, import_node_path5.join)((0, import_node_os4.homedir)(), ".alan-prod", "agent");
35680
+ default:
35681
+ return null;
35682
+ }
35683
+ }
35668
35684
  var AGENT_CONFIG_KEYS = /* @__PURE__ */ new Map([
35669
35685
  ["apiUrl", "string"],
35670
35686
  ["wsUrl", "string"],
@@ -35742,9 +35758,13 @@ function resolveAgentConfigPath(input2) {
35742
35758
  const profile = normalizeAgentEndpointProfile(
35743
35759
  typeof input2?.profile === "string" ? input2.profile : input2?.profile ?? null
35744
35760
  ) ?? "production";
35745
- const baseDir = input2?.baseDir ?? DEFAULT_AGENT_DIR;
35746
- if (input2?.baseDir === void 0) migrateLegacyAgentConfig({ profile });
35747
- return (0, import_node_path5.join)(baseDir, resolveAgentConfigFileName(profile));
35761
+ if (input2?.baseDir !== void 0) {
35762
+ return (0, import_node_path5.join)(input2.baseDir, resolveAgentConfigFileName(profile));
35763
+ }
35764
+ const isolatedBaseDir = profile === "production" ? null : resolveIsolatedAgentBaseDir(profile);
35765
+ if (isolatedBaseDir) return (0, import_node_path5.join)(isolatedBaseDir, "config.json");
35766
+ migrateLegacyAgentConfig({ profile });
35767
+ return (0, import_node_path5.join)(DEFAULT_AGENT_DIR, resolveAgentConfigFileName(profile));
35748
35768
  }
35749
35769
  function configExistsAtPath(configPath) {
35750
35770
  return (0, import_node_fs5.existsSync)(configPath);
@@ -35760,13 +35780,22 @@ function explicitConfigPathFromArgs(args) {
35760
35780
  const prefix = "--config-path=";
35761
35781
  return args.find((arg) => arg.startsWith(prefix))?.slice(prefix.length).trim() || void 0;
35762
35782
  }
35783
+ function hasExplicitProfileArg(args) {
35784
+ return args.some((arg) => arg === "--profile" || arg.startsWith("--profile="));
35785
+ }
35763
35786
  function bindAgentConfigPathFromArgs(args) {
35764
35787
  const argumentPath = explicitConfigPathFromArgs(args);
35765
35788
  if (argumentPath) {
35766
35789
  process.env.ALAN_AGENT_CONFIG_PATH = argumentPath;
35767
35790
  return argumentPath;
35768
35791
  }
35769
- const explicit = process.env.ALAN_AGENT_CONFIG_PATH?.trim();
35792
+ if (hasExplicitProfileArg(args)) {
35793
+ const profile2 = resolveEndpointProfileFromArgs(args);
35794
+ const configPath2 = resolveAgentConfigPath({ profile: profile2 });
35795
+ process.env.ALAN_AGENT_CONFIG_PATH = configPath2;
35796
+ return configPath2;
35797
+ }
35798
+ const explicit = configuredConfigPathFromEnvironment();
35770
35799
  if (explicit) return explicit;
35771
35800
  const profile = resolveEndpointProfileFromArgs(args);
35772
35801
  const configPath = resolveAgentConfigPath({ profile });
@@ -60269,9 +60298,9 @@ function buildMcpParamHeaders(declarations, args) {
60269
60298
  for (const decl of declarations) {
60270
60299
  const raw = valueAtPath(args, decl.path);
60271
60300
  if (raw === void 0 || raw === null) continue;
60272
- const stringValue = mcpParamPrimitiveToString(raw);
60273
- if (stringValue === void 0) continue;
60274
- out[`${MCP_PARAM_HEADER_PREFIX}${decl.headerName}`] = encodeMcpParamValue(stringValue);
60301
+ const stringValue2 = mcpParamPrimitiveToString(raw);
60302
+ if (stringValue2 === void 0) continue;
60303
+ out[`${MCP_PARAM_HEADER_PREFIX}${decl.headerName}`] = encodeMcpParamValue(stringValue2);
60275
60304
  }
60276
60305
  return out;
60277
60306
  }
@@ -72840,9 +72869,29 @@ function failureFromError(error61, paths) {
72840
72869
  stage: "protocol",
72841
72870
  message: "Alan's tool service returned an invalid MCP response.",
72842
72871
  retryable: false,
72843
- paths
72872
+ paths,
72873
+ diagnostic: describeReadinessError(error61)
72844
72874
  };
72845
72875
  }
72876
+ function describeReadinessError(error61) {
72877
+ if (!(error61 instanceof Error)) return String(error61);
72878
+ const parts2 = [];
72879
+ let current = error61;
72880
+ for (let depth = 0; current instanceof Error && depth < 4; depth += 1) {
72881
+ const { name, message } = current;
72882
+ const { code, status } = current;
72883
+ parts2.push(
72884
+ [
72885
+ name,
72886
+ message,
72887
+ code === void 0 ? "" : `code=${String(code)}`,
72888
+ status === void 0 ? "" : `status=${String(status)}`
72889
+ ].filter(Boolean).join(" ")
72890
+ );
72891
+ current = current.cause;
72892
+ }
72893
+ return parts2.join(" <- ");
72894
+ }
72846
72895
  async function waitBeforeRetry() {
72847
72896
  await new Promise((resolve15) => setTimeout(resolve15, RETRY_DELAY_MS2));
72848
72897
  }
@@ -73283,7 +73332,8 @@ async function handleAgentExecute(ctx, payload) {
73283
73332
  console.warn("[alan-agent] Alan MCP readiness observed failure", {
73284
73333
  ...correlation,
73285
73334
  code: failure.code,
73286
- stage: failure.stage
73335
+ stage: failure.stage,
73336
+ ...failure.diagnostic ? { diagnostic: failure.diagnostic } : {}
73287
73337
  });
73288
73338
  }
73289
73339
  });
@@ -74207,7 +74257,7 @@ var NativeTranscriptStreamer = class {
74207
74257
  continue;
74208
74258
  }
74209
74259
  const parsed = parseJsonObject3(raw);
74210
- const events = parsed ? claudeRecordToAgentEvents(parsed) : [];
74260
+ const events = parsed ? providerRecordToAgentEvents(hook.provider, parsed) : [];
74211
74261
  for (let index = 0; index < events.length; index += 1) {
74212
74262
  const deliveredEvent = events[index];
74213
74263
  const sourceCursor = `${start.generation}:${recordEndOffset}:${index}`;
@@ -74267,12 +74317,62 @@ function parseJsonObject3(value2) {
74267
74317
  return null;
74268
74318
  }
74269
74319
  }
74270
- function claudeRecordToAgentEvents(record2) {
74320
+ function providerRecordToAgentEvents(provider, record2) {
74321
+ if (provider === "codex") return codexRecordToAgentEvents(record2);
74322
+ if (provider === "copilot") return copilotRecordToAgentEvents(record2);
74323
+ return claudeCompatibleRecordToAgentEvents(record2);
74324
+ }
74325
+ function copilotRecordToAgentEvents(record2) {
74326
+ if (typeof record2.type !== "string" || !isRecord2(record2.data)) return [];
74327
+ const timestamp = timestampOf(record2) ? Date.parse(timestampOf(record2)) : Date.now();
74328
+ const ts = Number.isFinite(timestamp) ? timestamp : Date.now();
74329
+ const data = record2.data;
74330
+ if (record2.type === "assistant.message") {
74331
+ const events = [];
74332
+ if (typeof data.reasoningText === "string" && data.reasoningText.length > 0) {
74333
+ events.push({ type: "thinking", text: data.reasoningText, ts });
74334
+ }
74335
+ if (typeof data.content === "string" && data.content.length > 0) {
74336
+ events.push({ type: "text", text: data.content, ts });
74337
+ }
74338
+ if (Array.isArray(data.toolRequests)) {
74339
+ for (const request of data.toolRequests) {
74340
+ if (!isRecord2(request)) continue;
74341
+ const id = stringValue(request.id, request.toolCallId, request.tool_call_id);
74342
+ const name = stringValue(request.name, request.toolName, request.tool_name);
74343
+ if (id && name) {
74344
+ events.push({
74345
+ type: "tool_use",
74346
+ id,
74347
+ name,
74348
+ input: request.arguments ?? request.input,
74349
+ ts
74350
+ });
74351
+ }
74352
+ }
74353
+ }
74354
+ return events;
74355
+ }
74356
+ if (record2.type === "tool.execution_complete" || record2.type === "tool.execution_end") {
74357
+ const id = stringValue(data.toolCallId, data.tool_call_id, data.id);
74358
+ if (!id) return [];
74359
+ return [
74360
+ {
74361
+ type: "tool_result",
74362
+ id,
74363
+ content: extractText2(data.result ?? data.output ?? data.content),
74364
+ ts
74365
+ }
74366
+ ];
74367
+ }
74368
+ return [];
74369
+ }
74370
+ function claudeCompatibleRecordToAgentEvents(record2) {
74271
74371
  const timestamp = timestampOf(record2) ? Date.parse(timestampOf(record2)) : Date.now();
74272
74372
  const ts = Number.isFinite(timestamp) ? timestamp : Date.now();
74273
74373
  const message = isRecord2(record2.message) ? record2.message : record2;
74274
74374
  const content = message.content;
74275
- const role = typeof message.role === "string" ? message.role : typeof record2.type === "string" ? record2.type : null;
74375
+ const role = typeof message.role === "string" ? message.role : typeof record2.role === "string" ? record2.role : typeof record2.type === "string" ? record2.type : null;
74276
74376
  if (role === "user") {
74277
74377
  if (!Array.isArray(content)) return [];
74278
74378
  return content.flatMap((block) => {
@@ -74310,6 +74410,47 @@ function claudeRecordToAgentEvents(record2) {
74310
74410
  return [{ type: "text", text: content, ts }];
74311
74411
  return [];
74312
74412
  }
74413
+ function codexRecordToAgentEvents(record2) {
74414
+ if (record2.type !== "response_item" || !isRecord2(record2.payload)) return [];
74415
+ const payload = record2.payload;
74416
+ const timestamp = timestampOf(record2) ? Date.parse(timestampOf(record2)) : Date.now();
74417
+ const ts = Number.isFinite(timestamp) ? timestamp : Date.now();
74418
+ if (payload.type === "message" && payload.role === "assistant") {
74419
+ if (!Array.isArray(payload.content)) return [];
74420
+ return payload.content.flatMap((block) => {
74421
+ if (!isRecord2(block) || block.type !== "output_text" || typeof block.text !== "string") {
74422
+ return [];
74423
+ }
74424
+ return block.text ? [{ type: "text", text: block.text, ts }] : [];
74425
+ });
74426
+ }
74427
+ if (payload.type === "reasoning") {
74428
+ const text = extractText2(payload.summary);
74429
+ return text ? [{ type: "thinking", text, ts }] : [];
74430
+ }
74431
+ if (payload.type === "custom_tool_call") {
74432
+ const id = stringValue(payload.call_id, payload.id);
74433
+ const name = stringValue(payload.name);
74434
+ if (!id || !name) return [];
74435
+ return [{ type: "tool_use", id, name, input: parseEmbeddedJson(payload.input), ts }];
74436
+ }
74437
+ if (payload.type === "custom_tool_call_output") {
74438
+ const id = stringValue(payload.call_id, payload.id);
74439
+ return id ? [{ type: "tool_result", id, content: extractText2(payload.output), ts }] : [];
74440
+ }
74441
+ return [];
74442
+ }
74443
+ function stringValue(...values) {
74444
+ return values.find((value2) => typeof value2 === "string" && value2.length > 0) ?? null;
74445
+ }
74446
+ function parseEmbeddedJson(value2) {
74447
+ if (typeof value2 !== "string") return value2;
74448
+ try {
74449
+ return JSON.parse(value2);
74450
+ } catch {
74451
+ return value2;
74452
+ }
74453
+ }
74313
74454
  function extractText2(value2) {
74314
74455
  if (typeof value2 === "string") return value2;
74315
74456
  if (Array.isArray(value2)) return value2.map(extractText2).filter(Boolean).join("\n");
@@ -75132,10 +75273,10 @@ function createIgnoreMatcher(path2) {
75132
75273
  const expression = globToRegExp(pattern);
75133
75274
  return (candidate) => expression.test(candidate) || expression.test(`${candidate}/`);
75134
75275
  }
75135
- function isIgnored(normalizedPath, basename6, isDirectory2, configured) {
75136
- if (isDirectory2 && ALWAYS_IGNORED_DIRECTORIES.has(basename6))
75276
+ function isIgnored(normalizedPath, basename7, isDirectory2, configured) {
75277
+ if (isDirectory2 && ALWAYS_IGNORED_DIRECTORIES.has(basename7))
75137
75278
  return true;
75138
- if (!isDirectory2 && ALWAYS_IGNORED_FILES.has(basename6))
75279
+ if (!isDirectory2 && ALWAYS_IGNORED_FILES.has(basename7))
75139
75280
  return true;
75140
75281
  return configured.some((matches) => matches(normalizedPath));
75141
75282
  }
@@ -75742,8 +75883,8 @@ function isWithinDirectory(parent, candidate) {
75742
75883
  const path2 = (0, import_node_path18.relative)(parent, candidate);
75743
75884
  return path2 !== ".." && !path2.startsWith(`..${import_node_path18.sep}`) && !(0, import_node_path18.isAbsolute)(path2);
75744
75885
  }
75745
- async function loadSkillSourceConfig(homeDirectory) {
75746
- const configDirectory = (0, import_node_path18.join)(homeDirectory, ".alan");
75886
+ async function loadSkillSourceConfig(homeDirectory2) {
75887
+ const configDirectory = (0, import_node_path18.join)(homeDirectory2, ".alan");
75747
75888
  const configPath = (0, import_node_path18.join)(configDirectory, "config.toml");
75748
75889
  await (0, import_promises2.mkdir)(configDirectory, { recursive: true, mode: 448 });
75749
75890
  let created = false;
@@ -75759,18 +75900,18 @@ async function loadSkillSourceConfig(homeDirectory) {
75759
75900
  }
75760
75901
  const content = await (0, import_promises2.readFile)(configPath, "utf8");
75761
75902
  try {
75762
- return { state: "ready", config: parseSkillSourceConfig(content, homeDirectory), created };
75903
+ return { state: "ready", config: parseSkillSourceConfig(content, homeDirectory2), created };
75763
75904
  } catch (error61) {
75764
75905
  return {
75765
75906
  state: "invalid",
75766
- config: parseSkillSourceConfig(DEFAULT_SKILL_CONFIG, homeDirectory),
75907
+ config: parseSkillSourceConfig(DEFAULT_SKILL_CONFIG, homeDirectory2),
75767
75908
  created: false,
75768
75909
  diagnostic: error61 instanceof Error ? error61.message : String(error61)
75769
75910
  };
75770
75911
  }
75771
75912
  }
75772
- async function resolveSkillScanInput(homeDirectory, declared) {
75773
- const loaded = await loadSkillSourceConfig(homeDirectory);
75913
+ async function resolveSkillScanInput(homeDirectory2, declared) {
75914
+ const loaded = await loadSkillSourceConfig(homeDirectory2);
75774
75915
  if (loaded.state === "invalid") {
75775
75916
  throw Object.assign(new Error(`Invalid Skill source configuration: ${loaded.diagnostic}`), {
75776
75917
  code: "SKILL_SOURCE_CONFIG_INVALID"
@@ -75778,7 +75919,7 @@ async function resolveSkillScanInput(homeDirectory, declared) {
75778
75919
  }
75779
75920
  const { config: config2 } = loaded;
75780
75921
  if (!config2.enabled) return { ...declared, roots: [], ignoredPaths: config2.ignoredPaths };
75781
- const draftsPath = (0, import_node_path18.resolve)((0, import_node_path18.join)(homeDirectory, ".alan", "skill-sources"));
75922
+ const draftsPath = (0, import_node_path18.resolve)((0, import_node_path18.join)(homeDirectory2, ".alan", "skill-sources"));
75782
75923
  const enabledProviders = new Set(declared.enabledProviderKinds ?? []);
75783
75924
  const configured = [];
75784
75925
  for (const source of config2.sources) {
@@ -75802,7 +75943,7 @@ async function resolveSkillScanInput(homeDirectory, declared) {
75802
75943
  ignoredPaths: [.../* @__PURE__ */ new Set([...config2.ignoredPaths, ...declared.ignoredPaths ?? []])]
75803
75944
  };
75804
75945
  }
75805
- function parseSkillSourceConfig(content, homeDirectory) {
75946
+ function parseSkillSourceConfig(content, homeDirectory2) {
75806
75947
  const parsed = parse5(content);
75807
75948
  if (!isRecord4(parsed) || parsed.version !== 1 || !isRecord4(parsed.skills)) {
75808
75949
  throw new Error("~/.alan/config.toml must contain version = 1 and a [skills] table");
@@ -75825,7 +75966,7 @@ function parseSkillSourceConfig(content, homeDirectory) {
75825
75966
  `skills.sources entry ${index + 1} must contain string path and label values`
75826
75967
  );
75827
75968
  }
75828
- const sourcePath = resolveSkillSourcePath(value2.path, homeDirectory);
75969
+ const sourcePath = resolveSkillSourcePath(value2.path, homeDirectory2);
75829
75970
  const label = value2.label.trim();
75830
75971
  if (!label) throw new Error(`skills.sources entry ${index + 1} has an empty label`);
75831
75972
  const declarationId = value2.id === void 0 ? stableSourceDeclarationId(sourcePath) : requiredSourceId(value2.id, `skills.sources[${index}].id`);
@@ -75833,7 +75974,7 @@ function parseSkillSourceConfig(content, homeDirectory) {
75833
75974
  value2.providers,
75834
75975
  `skills.sources[${index}].providers`
75835
75976
  );
75836
- const relativeDirectory = import_node_path18.default.relative(homeDirectory, sourcePath);
75977
+ const relativeDirectory = import_node_path18.default.relative(homeDirectory2, sourcePath);
75837
75978
  const inferredProviders = providerKindsForUserDirectory(relativeDirectory);
75838
75979
  const declaredProviders = value2.providers === void 0 ? inferredProviders : [...new Set(explicitProviders.map((provider) => provider.trim()).filter(Boolean))];
75839
75980
  const stale = staleCodexDeclaration(relativeDirectory, label, declaredProviders);
@@ -75863,14 +76004,14 @@ function requiredSourceId(value2, field) {
75863
76004
  }
75864
76005
  return value2;
75865
76006
  }
75866
- function resolveSkillSourcePath(sourcePath, homeDirectory, pathApi = import_node_path18.default) {
76007
+ function resolveSkillSourcePath(sourcePath, homeDirectory2, pathApi = import_node_path18.default) {
75867
76008
  const trimmed = sourcePath.trim();
75868
- if (trimmed === "~") return pathApi.resolve(homeDirectory);
76009
+ if (trimmed === "~") return pathApi.resolve(homeDirectory2);
75869
76010
  if (trimmed.startsWith("~/") || trimmed.startsWith("~\\")) {
75870
76011
  const components = trimmed.slice(2).split(/[\\/]+/).filter(Boolean);
75871
- return pathApi.resolve(pathApi.join(homeDirectory, ...components));
76012
+ return pathApi.resolve(pathApi.join(homeDirectory2, ...components));
75872
76013
  }
75873
- return pathApi.isAbsolute(trimmed) ? pathApi.resolve(trimmed) : pathApi.resolve(homeDirectory, trimmed);
76014
+ return pathApi.isAbsolute(trimmed) ? pathApi.resolve(trimmed) : pathApi.resolve(homeDirectory2, trimmed);
75874
76015
  }
75875
76016
  function optionalBoolean(value2, fallback, field) {
75876
76017
  if (value2 === void 0) return fallback;
@@ -78777,17 +78918,10 @@ var log = {
78777
78918
  debug: () => {
78778
78919
  }
78779
78920
  };
78780
- var HOME = (0, import_node_os12.homedir)();
78781
- var PATHS = {
78782
- claude: (0, import_node_path23.join)(HOME, ".claude.json"),
78783
- codex: (0, import_node_path23.join)(HOME, ".codex", "config.toml"),
78784
- cursor: (0, import_node_path23.join)(HOME, ".cursor", "mcp.json"),
78785
- antigravity: (0, import_node_path23.join)(HOME, ".gemini", "config", "mcp_config.json"),
78786
- kimi: (0, import_node_path23.join)(HOME, ".kimi", "mcp.json"),
78787
- opencode: (0, import_node_path23.join)(HOME, ".config", "opencode", "opencode.json"),
78788
- factory: (0, import_node_path23.join)(HOME, ".factory", "mcp.json"),
78789
- amp: (0, import_node_path23.join)(HOME, ".config", "amp", "settings.json")
78790
- };
78921
+ var homeDirectoryOverride;
78922
+ function homeDirectory() {
78923
+ return homeDirectoryOverride ?? (0, import_node_os12.homedir)();
78924
+ }
78791
78925
  var MalformedToolConfigError = class extends Error {
78792
78926
  };
78793
78927
  function parseJsonSafe2(content) {
@@ -78848,9 +78982,12 @@ function saveMalformedBackup2(path2, content) {
78848
78982
  }
78849
78983
  var claudeAdapter = {
78850
78984
  cli: "Claude Code",
78851
- configPath: PATHS.claude,
78852
- guardDir: HOME,
78853
- // ~/.claude.json lives in home — always exists
78985
+ get configPath() {
78986
+ return (0, import_node_path23.join)(homeDirectory(), ".claude.json");
78987
+ },
78988
+ get guardDir() {
78989
+ return homeDirectory();
78990
+ },
78854
78991
  merge(existing, servers) {
78855
78992
  const config2 = parseJsonSafe2(existing);
78856
78993
  const mcpServers = config2.mcpServers ?? {};
@@ -78878,8 +79015,12 @@ var claudeAdapter = {
78878
79015
  };
78879
79016
  var codexAdapter = {
78880
79017
  cli: "Codex",
78881
- configPath: PATHS.codex,
78882
- guardDir: (0, import_node_path23.join)(HOME, ".codex"),
79018
+ get configPath() {
79019
+ return (0, import_node_path23.join)(homeDirectory(), ".codex", "config.toml");
79020
+ },
79021
+ get guardDir() {
79022
+ return (0, import_node_path23.join)(homeDirectory(), ".codex");
79023
+ },
78883
79024
  merge(existing, servers) {
78884
79025
  let config2 = {};
78885
79026
  if (existing) {
@@ -78920,8 +79061,12 @@ var codexAdapter = {
78920
79061
  };
78921
79062
  var cursorAdapter = {
78922
79063
  cli: "Cursor",
78923
- configPath: PATHS.cursor,
78924
- guardDir: (0, import_node_path23.join)(HOME, ".cursor"),
79064
+ get configPath() {
79065
+ return (0, import_node_path23.join)(homeDirectory(), ".cursor", "mcp.json");
79066
+ },
79067
+ get guardDir() {
79068
+ return (0, import_node_path23.join)(homeDirectory(), ".cursor");
79069
+ },
78925
79070
  merge(existing, servers) {
78926
79071
  const config2 = parseJsonSafe2(existing);
78927
79072
  const mcpServers = config2.mcpServers ?? {};
@@ -78950,8 +79095,12 @@ var cursorAdapter = {
78950
79095
  function createAntigravityAdapter() {
78951
79096
  return {
78952
79097
  cli: "Antigravity CLI",
78953
- configPath: PATHS.antigravity,
78954
- guardDir: (0, import_node_path23.join)(HOME, ".gemini", "config"),
79098
+ get configPath() {
79099
+ return (0, import_node_path23.join)(homeDirectory(), ".gemini", "config", "mcp_config.json");
79100
+ },
79101
+ get guardDir() {
79102
+ return (0, import_node_path23.join)(homeDirectory(), ".gemini", "config");
79103
+ },
78955
79104
  merge(existing, servers) {
78956
79105
  const config2 = parseJsonSafe2(existing);
78957
79106
  const mcpServers = config2.mcpServers ?? {};
@@ -78981,8 +79130,12 @@ function createAntigravityAdapter() {
78981
79130
  var antigravityAdapter = createAntigravityAdapter();
78982
79131
  var kimiAdapter = {
78983
79132
  cli: "Kimi CLI",
78984
- configPath: PATHS.kimi,
78985
- guardDir: (0, import_node_path23.join)(HOME, ".kimi"),
79133
+ get configPath() {
79134
+ return (0, import_node_path23.join)(homeDirectory(), ".kimi", "mcp.json");
79135
+ },
79136
+ get guardDir() {
79137
+ return (0, import_node_path23.join)(homeDirectory(), ".kimi");
79138
+ },
78986
79139
  merge(existing, servers) {
78987
79140
  const config2 = parseJsonSafe2(existing);
78988
79141
  const mcpServers = config2.mcpServers ?? {};
@@ -79010,8 +79163,12 @@ var kimiAdapter = {
79010
79163
  };
79011
79164
  var opencodeAdapter = {
79012
79165
  cli: "OpenCode",
79013
- configPath: PATHS.opencode,
79014
- guardDir: (0, import_node_path23.join)(HOME, ".config", "opencode"),
79166
+ get configPath() {
79167
+ return (0, import_node_path23.join)(homeDirectory(), ".config", "opencode", "opencode.json");
79168
+ },
79169
+ get guardDir() {
79170
+ return (0, import_node_path23.join)(homeDirectory(), ".config", "opencode");
79171
+ },
79015
79172
  merge(existing, servers) {
79016
79173
  const config2 = parseJsonSafe2(existing);
79017
79174
  const mcp = config2.mcp ?? {};
@@ -79039,8 +79196,12 @@ var opencodeAdapter = {
79039
79196
  };
79040
79197
  var factoryAdapter = {
79041
79198
  cli: "Factory Droid",
79042
- configPath: PATHS.factory,
79043
- guardDir: (0, import_node_path23.join)(HOME, ".factory"),
79199
+ get configPath() {
79200
+ return (0, import_node_path23.join)(homeDirectory(), ".factory", "mcp.json");
79201
+ },
79202
+ get guardDir() {
79203
+ return (0, import_node_path23.join)(homeDirectory(), ".factory");
79204
+ },
79044
79205
  merge(existing, servers) {
79045
79206
  const config2 = parseJsonSafe2(existing);
79046
79207
  const mcpServers = config2.mcpServers ?? {};
@@ -79075,8 +79236,12 @@ var factoryAdapter = {
79075
79236
  };
79076
79237
  var ampAdapter = {
79077
79238
  cli: "Amp",
79078
- configPath: PATHS.amp,
79079
- guardDir: (0, import_node_path23.join)(HOME, ".config", "amp"),
79239
+ get configPath() {
79240
+ return (0, import_node_path23.join)(homeDirectory(), ".config", "amp", "settings.json");
79241
+ },
79242
+ get guardDir() {
79243
+ return (0, import_node_path23.join)(homeDirectory(), ".config", "amp");
79244
+ },
79080
79245
  merge(existing, servers) {
79081
79246
  const config2 = parseJsonSafe2(existing);
79082
79247
  const mcpServers = config2["amp.mcpServers"] ?? {};
@@ -79182,6 +79347,77 @@ function normalizeAlanRuntimeEntry(actual, expected) {
79182
79347
  function matchesAlanManagedEntry(actual, expected) {
79183
79348
  return entriesMatch(actual, expected) || entriesMatch(normalizeAlanRuntimeEntry(actual, expected), expected);
79184
79349
  }
79350
+ var LOCAL_ALAN_MCP_HOSTS = /* @__PURE__ */ new Set(["localhost", "127.0.0.1", "0.0.0.0"]);
79351
+ var LEGACY_LOCAL_ALAN_MCP_PORTS = /* @__PURE__ */ new Set(["8400"]);
79352
+ var ALAN_MCP_HOST_SUFFIXES = [".tryalan.ai"];
79353
+ function normalizeMcpPathname(pathname) {
79354
+ const trimmed = pathname.replace(/\/+$/, "");
79355
+ return trimmed.length > 0 ? trimmed : "/";
79356
+ }
79357
+ function urlsShareAlanMcpEndpoint(left, right) {
79358
+ try {
79359
+ const a = new URL(left);
79360
+ const b = new URL(right);
79361
+ return a.origin === b.origin && normalizeMcpPathname(a.pathname) === normalizeMcpPathname(b.pathname);
79362
+ } catch {
79363
+ return left === right;
79364
+ }
79365
+ }
79366
+ function configuredAlanMcpUrlsFromEnv() {
79367
+ const urls = [];
79368
+ for (const raw of [
79369
+ process.env.ALAN_MCP_DESKTOP_URL,
79370
+ process.env.ALAN_MCP_PUBLIC_URL,
79371
+ process.env.ALAN_LOCAL_API_URL
79372
+ ]) {
79373
+ const value2 = raw?.trim();
79374
+ if (!value2) continue;
79375
+ try {
79376
+ const parsed = new URL(value2);
79377
+ if (normalizeMcpPathname(parsed.pathname) === "/mcp") {
79378
+ urls.push(parsed.toString());
79379
+ continue;
79380
+ }
79381
+ parsed.pathname = "/mcp";
79382
+ urls.push(parsed.toString());
79383
+ } catch {
79384
+ urls.push(value2.endsWith("/mcp") ? value2 : `${value2.replace(/\/$/, "")}/mcp`);
79385
+ }
79386
+ }
79387
+ return urls;
79388
+ }
79389
+ function extractHttpUrlFromEntry(entry) {
79390
+ if (!entry || typeof entry !== "object") return void 0;
79391
+ const record2 = entry;
79392
+ for (const key of ["url", "serverUrl"]) {
79393
+ const value2 = record2[key];
79394
+ if (typeof value2 === "string" && value2.length > 0) return value2;
79395
+ }
79396
+ for (const value2 of Object.values(record2)) {
79397
+ if (!value2 || typeof value2 !== "object") continue;
79398
+ const nested = extractHttpUrlFromEntry(value2);
79399
+ if (nested) return nested;
79400
+ }
79401
+ return void 0;
79402
+ }
79403
+ function isAlanSelfRegistrationEntry(entry) {
79404
+ const url3 = extractHttpUrlFromEntry(entry);
79405
+ if (!url3) return false;
79406
+ try {
79407
+ const parsed = new URL(url3);
79408
+ if (normalizeMcpPathname(parsed.pathname) !== "/mcp") return false;
79409
+ const host = parsed.hostname.toLowerCase();
79410
+ if (LOCAL_ALAN_MCP_HOSTS.has(host) && LEGACY_LOCAL_ALAN_MCP_PORTS.has(parsed.port)) {
79411
+ return true;
79412
+ }
79413
+ if (ALAN_MCP_HOST_SUFFIXES.some((suffix) => host.endsWith(suffix))) return true;
79414
+ return configuredAlanMcpUrlsFromEnv().some(
79415
+ (configured) => urlsShareAlanMcpEndpoint(configured, url3)
79416
+ );
79417
+ } catch {
79418
+ return false;
79419
+ }
79420
+ }
79185
79421
  function hasAlanManagedSignature(entry) {
79186
79422
  if (!entry || typeof entry !== "object") return false;
79187
79423
  for (const [key, value2] of Object.entries(entry)) {
@@ -79202,6 +79438,9 @@ function expectedServerEntry(adapter, server) {
79202
79438
  function isManagedServerList(entries) {
79203
79439
  return entries.length === 0 || typeof entries[0] !== "string";
79204
79440
  }
79441
+ function isAlanOwnedMcpEntry(entry, desiredEntry, previousEntry) {
79442
+ return hasAlanManagedSignature(entry) || isAlanSelfRegistrationEntry(entry) || matchesAlanManagedEntry(entry, desiredEntry) || previousEntry !== void 0 && matchesAlanManagedEntry(entry, previousEntry);
79443
+ }
79205
79444
  function syncMcpToAllClis(servers, oldManagedServers = []) {
79206
79445
  const written = [];
79207
79446
  const failures = [];
@@ -79216,6 +79455,7 @@ function syncMcpToAllClis(servers, oldManagedServers = []) {
79216
79455
  try {
79217
79456
  const existing = readFileOr(adapter.configPath);
79218
79457
  const previousServers = isManagedServerList(oldManagedServers) ? oldManagedServers : [];
79458
+ const previousNames = isManagedServerList(oldManagedServers) ? oldManagedServers.map((server) => server.name) : oldManagedServers;
79219
79459
  const previousByName = new Map(previousServers.map((server) => [server.name, server]));
79220
79460
  if (existing) {
79221
79461
  for (const server of servers) {
@@ -79224,21 +79464,20 @@ function syncMcpToAllClis(servers, oldManagedServers = []) {
79224
79464
  const desiredEntry = expectedServerEntry(adapter, server);
79225
79465
  const previous = previousByName.get(server.name);
79226
79466
  const previousEntry = previous ? expectedServerEntry(adapter, previous) : void 0;
79227
- if (!hasAlanManagedSignature(currentEntry) && !matchesAlanManagedEntry(currentEntry, desiredEntry) && (!previousEntry || !matchesAlanManagedEntry(currentEntry, previousEntry))) {
79467
+ if (!isAlanOwnedMcpEntry(currentEntry, desiredEntry, previousEntry)) {
79228
79468
  throw new Error(`an unowned entry already uses the name ${server.name}`);
79229
79469
  }
79230
79470
  }
79231
79471
  }
79232
79472
  const currentNames = new Set(servers.map((s) => s.name));
79233
- const toRemove = previousServers.filter((server) => !currentNames.has(server.name));
79473
+ const toRemove = previousNames.filter((name) => !currentNames.has(name));
79234
79474
  let content;
79235
79475
  if (toRemove.length > 0) {
79236
- const ownedNames = existing ? toRemove.filter(
79237
- (server) => matchesAlanManagedEntry(
79238
- serverEntry(adapter, existing, server.name),
79239
- expectedServerEntry(adapter, server)
79240
- )
79241
- ).map((server) => server.name) : [];
79476
+ const ownedNames = existing ? toRemove.filter((name) => {
79477
+ const entry = serverEntry(adapter, existing, name);
79478
+ const previous = previousByName.get(name);
79479
+ return hasAlanManagedSignature(entry) || isAlanSelfRegistrationEntry(entry) || previous !== void 0 && matchesAlanManagedEntry(entry, expectedServerEntry(adapter, previous));
79480
+ }) : [];
79242
79481
  const cleaned = adapter.remove(existing, ownedNames);
79243
79482
  content = adapter.merge(cleaned, servers);
79244
79483
  } else {
@@ -79323,7 +79562,9 @@ function inspectAlanMcpPresence(expectedServers = [], candidateNames = DEFAULT_A
79323
79562
  if (entry === void 0) continue;
79324
79563
  const expected = expectedByName.get(name);
79325
79564
  const matchesExpected = expected ? matchesAlanManagedEntry(entry, expectedServerEntry(adapter, expected)) : false;
79326
- if (!hasAlanManagedSignature(entry) && !matchesExpected) continue;
79565
+ if (!hasAlanManagedSignature(entry) && !matchesExpected && !isAlanSelfRegistrationEntry(entry)) {
79566
+ continue;
79567
+ }
79327
79568
  foundOnCli = true;
79328
79569
  serverNamesFound.add(name);
79329
79570
  }
@@ -79371,7 +79612,8 @@ var McpSyncService = class {
79371
79612
  managedServerNames;
79372
79613
  legacyServerNames;
79373
79614
  getStatus() {
79374
- const presence = inspectAlanMcpPresence([], this.managedServerNames);
79615
+ const candidateNames = [.../* @__PURE__ */ new Set([...this.managedServerNames, ...this.legacyServerNames])];
79616
+ const presence = inspectAlanMcpPresence([], candidateNames);
79375
79617
  return {
79376
79618
  configured: presence.configured,
79377
79619
  lastSyncAt: null,
@@ -79425,6 +79667,10 @@ var McpSyncService = class {
79425
79667
  var import_node_fs22 = require("fs");
79426
79668
  var import_node_os13 = require("os");
79427
79669
  var import_node_path24 = require("path");
79670
+ var ALAN_HOOK_MARKER = "# alan-native-session-hook";
79671
+ var ALAN_KIMI_HOOKS_START = "# alan-native-session-hooks:start";
79672
+ var ALAN_KIMI_HOOKS_END = "# alan-native-session-hooks:end";
79673
+ var ALAN_OPENCODE_PLUGIN_MARKER = "// alan-native-session-plugin";
79428
79674
  var CLAUDE_HOOK_EVENTS = [
79429
79675
  "SessionStart",
79430
79676
  "UserPromptSubmit",
@@ -79434,15 +79680,59 @@ var CLAUDE_HOOK_EVENTS = [
79434
79680
  "SubagentStop",
79435
79681
  "SessionEnd"
79436
79682
  ];
79437
- var ALAN_HOOK_MARKER = "# alan-native-session-hook";
79683
+ var CODEX_HOOK_EVENTS = [
79684
+ "SessionStart",
79685
+ "UserPromptSubmit",
79686
+ "PostToolUse",
79687
+ "Stop",
79688
+ "SubagentStart",
79689
+ "SubagentStop",
79690
+ "SessionEnd"
79691
+ ];
79692
+ var COPILOT_HOOK_EVENTS = [
79693
+ "SessionStart",
79694
+ "UserPromptSubmit",
79695
+ "PostToolUse",
79696
+ "Stop",
79697
+ "SubagentStop",
79698
+ "SessionEnd"
79699
+ ];
79700
+ var CURSOR_HOOK_EVENTS = [
79701
+ "sessionStart",
79702
+ "beforeSubmitPrompt",
79703
+ "afterAgentResponse",
79704
+ "stop",
79705
+ "sessionEnd"
79706
+ ];
79707
+ var KIMI_HOOK_EVENTS = [
79708
+ "SessionStart",
79709
+ "UserPromptSubmit",
79710
+ "PostToolUse",
79711
+ "Stop",
79712
+ "Interrupt",
79713
+ "SubagentStart",
79714
+ "SubagentStop",
79715
+ "SessionEnd"
79716
+ ];
79717
+ var GROK_HOOK_EVENTS = [
79718
+ "SessionStart",
79719
+ "UserPromptSubmit",
79720
+ "PostToolUse",
79721
+ "Stop",
79722
+ "StopFailure",
79723
+ "StopCancelled",
79724
+ "SubagentStart",
79725
+ "SubagentStop",
79726
+ "SessionEnd"
79727
+ ];
79438
79728
  function shellQuote(value2) {
79439
79729
  return `'${value2.replaceAll("'", `'\\''`)}'`;
79440
79730
  }
79441
79731
  function powershellQuote(value2) {
79442
79732
  return `'${value2.replaceAll("'", "''")}'`;
79443
79733
  }
79444
- function nativeHookCommand(input2) {
79445
- const args = [
79734
+ function hookArgs(input2) {
79735
+ return [
79446
79736
  input2.cliEntry,
79447
79737
  "hook",
79448
79738
  "--config-path",
@@ -79453,19 +79743,21 @@ function nativeHookCommand(input2) {
79453
79743
  input2.event,
79454
79744
  ALAN_HOOK_MARKER
79455
79745
  ];
79456
- const environment = Object.entries(input2.environment ?? {});
79457
- for (const [key] of environment) {
79746
+ }
79747
+ function checkedEnvironment(environment) {
79748
+ const entries = Object.entries(environment ?? {});
79749
+ for (const [key] of entries) {
79458
79750
  if (!/^[A-Za-z_][A-Za-z0-9_]*$/.test(key)) {
79459
79751
  throw new Error(`Invalid native hook environment variable: ${key}`);
79460
79752
  }
79461
79753
  }
79754
+ return entries;
79755
+ }
79756
+ function nativeHookCommand(input2) {
79757
+ const args = hookArgs(input2);
79758
+ const environment = checkedEnvironment(input2.environment);
79462
79759
  if (environment.length === 0) {
79463
- return {
79464
- type: "command",
79465
- command: input2.nodeExecutable,
79466
- args,
79467
- timeout: 5
79468
- };
79760
+ return { type: "command", command: input2.nodeExecutable, args, timeout: 5 };
79469
79761
  }
79470
79762
  if ((input2.platform ?? (0, import_node_os13.platform)()) === "win32") {
79471
79763
  const environmentPrefix2 = environment.map(([key, value2]) => `$env:${key}=${powershellQuote(value2)}`).join("; ");
@@ -79486,7 +79778,40 @@ function nativeHookCommand(input2) {
79486
79778
  timeout: 5
79487
79779
  };
79488
79780
  }
79489
- function readSettings(path2) {
79781
+ function nativeShellCommand(runtime, provider, event, platform6 = runtime.platform) {
79782
+ const args = hookArgs({
79783
+ configPath: runtime.configPath,
79784
+ cliEntry: runtime.cliEntry,
79785
+ provider,
79786
+ event
79787
+ });
79788
+ const environment = checkedEnvironment(runtime.environment);
79789
+ if (platform6 === "win32") {
79790
+ const prefix2 = environment.map(([key, value2]) => `$env:${key}=${powershellQuote(value2)}`).join("; ");
79791
+ const command2 = `& ${[runtime.nodeExecutable, ...args].map(powershellQuote).join(" ")}`;
79792
+ return prefix2 ? `${prefix2}; ${command2}` : command2;
79793
+ }
79794
+ const prefix = environment.map(([key, value2]) => `${key}=${shellQuote(value2)}`).join(" ");
79795
+ const command = [runtime.nodeExecutable, ...args].map(shellQuote).join(" ");
79796
+ return prefix ? `${prefix} ${command}` : command;
79797
+ }
79798
+ function resolveRuntime(input2 = {}) {
79799
+ const cliEntry = input2.cliEntry ?? process.argv[1];
79800
+ const configPath = input2.configPath ?? process.env.ALAN_AGENT_CONFIG_PATH;
79801
+ if (!cliEntry) throw new Error("Cannot resolve the alan-agent CLI entrypoint");
79802
+ if (!configPath?.trim()) {
79803
+ throw new Error("Cannot install native hooks without an exact Alan agent config path");
79804
+ }
79805
+ return {
79806
+ configPath,
79807
+ homeDir: input2.homeDir ?? (0, import_node_os13.homedir)(),
79808
+ nodeExecutable: input2.nodeExecutable ?? process.execPath,
79809
+ cliEntry,
79810
+ environment: input2.environment,
79811
+ platform: input2.platform ?? (0, import_node_os13.platform)()
79812
+ };
79813
+ }
79814
+ function readSettings(path2, providerLabel) {
79490
79815
  if (!(0, import_node_fs22.existsSync)(path2)) return {};
79491
79816
  try {
79492
79817
  const value2 = JSON.parse((0, import_node_fs22.readFileSync)(path2, "utf8"));
@@ -79498,78 +79823,363 @@ function readSettings(path2) {
79498
79823
  const backup = `${path2}.malformed-${Date.now()}.bak`;
79499
79824
  (0, import_node_fs22.copyFileSync)(path2, backup);
79500
79825
  throw new Error(
79501
- `Claude settings were malformed and moved to ${backup}: ${error61 instanceof Error ? error61.message : String(error61)}`
79826
+ `${providerLabel} settings were malformed and copied to ${backup}: ${error61 instanceof Error ? error61.message : String(error61)}`
79502
79827
  );
79503
79828
  }
79504
79829
  }
79505
- function withoutAlanHookGroups(value2) {
79830
+ function withoutAlanEntries(value2) {
79506
79831
  if (!Array.isArray(value2)) return [];
79507
- return value2.filter((group) => !JSON.stringify(group).includes(ALAN_HOOK_MARKER));
79832
+ return value2.filter((entry) => !JSON.stringify(entry).includes(ALAN_HOOK_MARKER));
79508
79833
  }
79509
79834
  function writeSettings(path2, settings) {
79835
+ const serialized = `${JSON.stringify(settings, null, 2)}
79836
+ `;
79837
+ if ((0, import_node_fs22.existsSync)(path2) && (0, import_node_fs22.readFileSync)(path2, "utf8") === serialized) return false;
79510
79838
  (0, import_node_fs22.mkdirSync)((0, import_node_path24.dirname)(path2), { recursive: true, mode: 448 });
79511
79839
  const temporary = `${path2}.${process.pid}.tmp`;
79512
- (0, import_node_fs22.writeFileSync)(temporary, `${JSON.stringify(settings, null, 2)}
79513
- `, { mode: 384 });
79840
+ (0, import_node_fs22.writeFileSync)(temporary, serialized, { mode: 384 });
79514
79841
  (0, import_node_fs22.renameSync)(temporary, path2);
79842
+ return true;
79515
79843
  }
79516
- function reconcileClaudeNativeHooks(input2) {
79517
- const homeDir = input2?.homeDir ?? (0, import_node_os13.homedir)();
79518
- const settingsPath = (0, import_node_path24.join)(homeDir, ".claude", "settings.json");
79519
- const nodeExecutable = input2?.nodeExecutable ?? process.execPath;
79520
- const cliEntry = input2?.cliEntry ?? process.argv[1];
79521
- const configPath = input2?.configPath ?? process.env.ALAN_AGENT_CONFIG_PATH;
79522
- if (!cliEntry) throw new Error("Cannot resolve the alan-agent CLI entrypoint");
79523
- if (!configPath?.trim()) {
79524
- throw new Error("Cannot install Claude hooks without an exact Alan agent config path");
79844
+ function writeTextFile(path2, content) {
79845
+ if ((0, import_node_fs22.existsSync)(path2) && (0, import_node_fs22.readFileSync)(path2, "utf8") === content) return false;
79846
+ (0, import_node_fs22.mkdirSync)((0, import_node_path24.dirname)(path2), { recursive: true, mode: 448 });
79847
+ const temporary = `${path2}.${process.pid}.tmp`;
79848
+ (0, import_node_fs22.writeFileSync)(temporary, content, { mode: 384 });
79849
+ (0, import_node_fs22.renameSync)(temporary, path2);
79850
+ return true;
79851
+ }
79852
+ function withoutMarkedSection(content, start, end) {
79853
+ const startIndex = content.indexOf(start);
79854
+ const endIndex = content.indexOf(end);
79855
+ if (startIndex < 0 && endIndex < 0) return content;
79856
+ if (startIndex < 0 || endIndex < startIndex) {
79857
+ throw new Error(`Malformed Alan-owned configuration section: ${start}`);
79858
+ }
79859
+ const afterEnd = endIndex + end.length;
79860
+ return `${content.slice(0, startIndex).trimEnd()}
79861
+ ${content.slice(afterEnd).trimStart()}`.trim();
79862
+ }
79863
+ function reconcileNestedCommandHooks(input2) {
79864
+ const settings = readSettings(input2.path, input2.providerLabel);
79865
+ const currentHooks = settings.hooks && typeof settings.hooks === "object" && !Array.isArray(settings.hooks) ? settings.hooks : {};
79866
+ const hooks = { ...currentHooks };
79867
+ for (const event of input2.events) {
79868
+ hooks[event] = [...withoutAlanEntries(currentHooks[event]), { hooks: [input2.command(event)] }];
79869
+ }
79870
+ return writeSettings(input2.path, { ...settings, hooks });
79871
+ }
79872
+ function removeNestedCommandHooks(path2, providerLabel) {
79873
+ if (!(0, import_node_fs22.existsSync)(path2)) return false;
79874
+ const settings = readSettings(path2, providerLabel);
79875
+ if (!settings.hooks || typeof settings.hooks !== "object" || Array.isArray(settings.hooks)) {
79876
+ return false;
79877
+ }
79878
+ const hooks = {};
79879
+ let removed = false;
79880
+ for (const [event, groups] of Object.entries(settings.hooks)) {
79881
+ const retained = withoutAlanEntries(groups);
79882
+ if (Array.isArray(groups) && retained.length !== groups.length) removed = true;
79883
+ if (retained.length > 0) hooks[event] = retained;
79884
+ }
79885
+ return removed ? writeSettings(path2, { ...settings, hooks }) : false;
79886
+ }
79887
+ function reconcileClaudeNativeHooks(input2 = {}) {
79888
+ const runtime = resolveRuntime(input2);
79889
+ return reconcileNestedCommandHooks({
79890
+ path: (0, import_node_path24.join)(runtime.homeDir, ".claude", "settings.json"),
79891
+ providerLabel: "Claude",
79892
+ events: CLAUDE_HOOK_EVENTS,
79893
+ command: (event) => ({
79894
+ ...nativeHookCommand({
79895
+ ...runtime,
79896
+ provider: "claude_cli",
79897
+ event
79898
+ })
79899
+ })
79900
+ });
79901
+ }
79902
+ function removeClaudeNativeHooks(homeDir = (0, import_node_os13.homedir)()) {
79903
+ return removeNestedCommandHooks((0, import_node_path24.join)(homeDir, ".claude", "settings.json"), "Claude");
79904
+ }
79905
+ function reconcileCodexNativeHooks(input2 = {}) {
79906
+ const runtime = resolveRuntime(input2);
79907
+ return reconcileNestedCommandHooks({
79908
+ path: (0, import_node_path24.join)(runtime.homeDir, ".codex", "hooks.json"),
79909
+ providerLabel: "Codex",
79910
+ events: CODEX_HOOK_EVENTS,
79911
+ command: (event) => ({
79912
+ type: "command",
79913
+ command: nativeShellCommand(runtime, "codex_app_server", event, "darwin"),
79914
+ commandWindows: nativeShellCommand(runtime, "codex_app_server", event, "win32"),
79915
+ timeout: event === "SessionEnd" ? 3 : 5
79916
+ })
79917
+ });
79918
+ }
79919
+ function removeCodexNativeHooks(homeDir = (0, import_node_os13.homedir)()) {
79920
+ return removeNestedCommandHooks((0, import_node_path24.join)(homeDir, ".codex", "hooks.json"), "Codex");
79921
+ }
79922
+ function reconcileCopilotNativeHooks(input2 = {}) {
79923
+ const runtime = resolveRuntime(input2);
79924
+ const path2 = (0, import_node_path24.join)(runtime.homeDir, ".copilot", "hooks", "alan-native-session.json");
79925
+ if ((0, import_node_fs22.existsSync)(path2) && !(0, import_node_fs22.readFileSync)(path2, "utf8").includes(ALAN_HOOK_MARKER)) {
79926
+ throw new Error(`Refusing to overwrite non-Alan Copilot hook configuration at ${path2}`);
79525
79927
  }
79526
- const settings = readSettings(settingsPath);
79928
+ const hooks = Object.fromEntries(
79929
+ COPILOT_HOOK_EVENTS.map((event) => [
79930
+ event,
79931
+ [
79932
+ {
79933
+ type: "command",
79934
+ bash: nativeShellCommand(runtime, "copilot_cli", event, "darwin"),
79935
+ powershell: nativeShellCommand(runtime, "copilot_cli", event, "win32"),
79936
+ timeoutSec: event === "SessionEnd" ? 3 : 5
79937
+ }
79938
+ ]
79939
+ ])
79940
+ );
79941
+ return writeSettings(path2, { version: 1, hooks });
79942
+ }
79943
+ function removeCopilotNativeHooks(homeDir = (0, import_node_os13.homedir)()) {
79944
+ const path2 = (0, import_node_path24.join)(homeDir, ".copilot", "hooks", "alan-native-session.json");
79945
+ if (!(0, import_node_fs22.existsSync)(path2)) return false;
79946
+ if (!(0, import_node_fs22.readFileSync)(path2, "utf8").includes(ALAN_HOOK_MARKER)) return false;
79947
+ (0, import_node_fs22.rmSync)(path2);
79948
+ return true;
79949
+ }
79950
+ function reconcileCursorNativeHooks(input2 = {}) {
79951
+ const runtime = resolveRuntime(input2);
79952
+ const path2 = (0, import_node_path24.join)(runtime.homeDir, ".cursor", "hooks.json");
79953
+ const settings = readSettings(path2, "Cursor");
79527
79954
  const currentHooks = settings.hooks && typeof settings.hooks === "object" && !Array.isArray(settings.hooks) ? settings.hooks : {};
79528
79955
  const hooks = { ...currentHooks };
79529
- for (const event of CLAUDE_HOOK_EVENTS) {
79956
+ for (const event of CURSOR_HOOK_EVENTS) {
79530
79957
  hooks[event] = [
79531
- ...withoutAlanHookGroups(currentHooks[event]),
79958
+ ...withoutAlanEntries(currentHooks[event]),
79532
79959
  {
79533
- hooks: [
79534
- nativeHookCommand({
79535
- configPath,
79536
- nodeExecutable,
79537
- cliEntry,
79538
- environment: input2?.environment,
79539
- platform: input2?.platform,
79540
- provider: "claude_cli",
79541
- event
79542
- })
79543
- ]
79960
+ type: "command",
79961
+ command: nativeShellCommand(runtime, "cursor_agent_cli", event),
79962
+ timeout: 5
79544
79963
  }
79545
79964
  ];
79546
79965
  }
79547
- const next = { ...settings, hooks };
79548
- const previous = (0, import_node_fs22.existsSync)(settingsPath) ? (0, import_node_fs22.readFileSync)(settingsPath, "utf8") : null;
79549
- const serialized = `${JSON.stringify(next, null, 2)}
79550
- `;
79551
- if (previous === serialized) return false;
79552
- writeSettings(settingsPath, next);
79553
- return true;
79966
+ return writeSettings(path2, { ...settings, version: settings.version ?? 1, hooks });
79554
79967
  }
79555
- function removeClaudeNativeHooks(homeDir = (0, import_node_os13.homedir)()) {
79556
- const settingsPath = (0, import_node_path24.join)(homeDir, ".claude", "settings.json");
79557
- if (!(0, import_node_fs22.existsSync)(settingsPath)) return false;
79558
- const settings = readSettings(settingsPath);
79968
+ function removeCursorNativeHooks(homeDir = (0, import_node_os13.homedir)()) {
79969
+ const path2 = (0, import_node_path24.join)(homeDir, ".cursor", "hooks.json");
79970
+ if (!(0, import_node_fs22.existsSync)(path2)) return false;
79971
+ const settings = readSettings(path2, "Cursor");
79559
79972
  if (!settings.hooks || typeof settings.hooks !== "object" || Array.isArray(settings.hooks)) {
79560
79973
  return false;
79561
79974
  }
79562
79975
  const hooks = {};
79563
79976
  let removed = false;
79564
- for (const [event, groups] of Object.entries(settings.hooks)) {
79565
- const retained = withoutAlanHookGroups(groups);
79566
- if (Array.isArray(groups) && retained.length !== groups.length) removed = true;
79977
+ for (const [event, entries] of Object.entries(settings.hooks)) {
79978
+ const retained = withoutAlanEntries(entries);
79979
+ if (Array.isArray(entries) && retained.length !== entries.length) removed = true;
79567
79980
  if (retained.length > 0) hooks[event] = retained;
79568
79981
  }
79569
- if (!removed) return false;
79570
- writeSettings(settingsPath, { ...settings, hooks });
79982
+ return removed ? writeSettings(path2, { ...settings, hooks }) : false;
79983
+ }
79984
+ function kimiHookSection(runtime) {
79985
+ const hooks = KIMI_HOOK_EVENTS.map(
79986
+ (event) => [
79987
+ "[[hooks]]",
79988
+ `event = ${JSON.stringify(event)}`,
79989
+ `command = ${JSON.stringify(nativeShellCommand(runtime, "kimi_cli", event))}`,
79990
+ `timeout = ${event === "SessionEnd" ? 3 : 5}`
79991
+ ].join("\n")
79992
+ ).join("\n\n");
79993
+ return `${ALAN_KIMI_HOOKS_START}
79994
+ ${hooks}
79995
+ ${ALAN_KIMI_HOOKS_END}`;
79996
+ }
79997
+ function reconcileKimiNativeHooks(input2 = {}) {
79998
+ const runtime = resolveRuntime(input2);
79999
+ const path2 = (0, import_node_path24.join)(runtime.homeDir, ".kimi-code", "config.toml");
80000
+ const current = (0, import_node_fs22.existsSync)(path2) ? (0, import_node_fs22.readFileSync)(path2, "utf8") : "";
80001
+ const userContent = withoutMarkedSection(current, ALAN_KIMI_HOOKS_START, ALAN_KIMI_HOOKS_END);
80002
+ const content = `${userContent.trimEnd()}${userContent.trim() ? "\n\n" : ""}${kimiHookSection(runtime)}
80003
+ `;
80004
+ return writeTextFile(path2, content);
80005
+ }
80006
+ function removeKimiNativeHooks(homeDir = (0, import_node_os13.homedir)()) {
80007
+ const path2 = (0, import_node_path24.join)(homeDir, ".kimi-code", "config.toml");
80008
+ if (!(0, import_node_fs22.existsSync)(path2)) return false;
80009
+ const current = (0, import_node_fs22.readFileSync)(path2, "utf8");
80010
+ const content = withoutMarkedSection(current, ALAN_KIMI_HOOKS_START, ALAN_KIMI_HOOKS_END);
80011
+ if (content === current) return false;
80012
+ return writeTextFile(path2, content ? `${content.trimEnd()}
80013
+ ` : "");
80014
+ }
80015
+ function reconcileGrokNativeHooks(input2 = {}) {
80016
+ const runtime = resolveRuntime(input2);
80017
+ const path2 = (0, import_node_path24.join)(runtime.homeDir, ".grok", "hooks", "alan-native-session.json");
80018
+ if ((0, import_node_fs22.existsSync)(path2) && !(0, import_node_fs22.readFileSync)(path2, "utf8").includes(ALAN_HOOK_MARKER)) {
80019
+ throw new Error(`Refusing to overwrite non-Alan Grok hook configuration at ${path2}`);
80020
+ }
80021
+ return reconcileNestedCommandHooks({
80022
+ path: path2,
80023
+ providerLabel: "Grok",
80024
+ events: GROK_HOOK_EVENTS,
80025
+ command: (event) => ({
80026
+ type: "command",
80027
+ command: nativeShellCommand(runtime, "grok_cli", event),
80028
+ timeout: event === "SessionEnd" ? 3 : 5
80029
+ })
80030
+ });
80031
+ }
80032
+ function removeGrokNativeHooks(homeDir = (0, import_node_os13.homedir)()) {
80033
+ const path2 = (0, import_node_path24.join)(homeDir, ".grok", "hooks", "alan-native-session.json");
80034
+ if (!(0, import_node_fs22.existsSync)(path2)) return false;
80035
+ if (!(0, import_node_fs22.readFileSync)(path2, "utf8").includes(ALAN_HOOK_MARKER)) return false;
80036
+ (0, import_node_fs22.rmSync)(path2);
79571
80037
  return true;
79572
80038
  }
80039
+ function opencodePluginSource(runtime) {
80040
+ const command = [
80041
+ runtime.nodeExecutable,
80042
+ runtime.cliEntry,
80043
+ "hook",
80044
+ "--config-path",
80045
+ runtime.configPath,
80046
+ "--provider",
80047
+ "opencode_cli"
80048
+ ];
80049
+ const environment = runtime.environment ?? {};
80050
+ return `${ALAN_OPENCODE_PLUGIN_MARKER}
80051
+ const command = ${JSON.stringify(command)}
80052
+ const environment = ${JSON.stringify(environment)}
80053
+
80054
+ export const AlanNativeSessionPlugin = async ({ directory }) => {
80055
+ const textByPart = new Map()
80056
+ const userPartIdsBySession = new Map()
80057
+ const send = async (event, payload) => {
80058
+ const proc = Bun.spawn({
80059
+ cmd: [...command, "--event", event, ${JSON.stringify(ALAN_HOOK_MARKER)}],
80060
+ env: { ...process.env, ...environment },
80061
+ stdin: "pipe",
80062
+ stdout: "ignore",
80063
+ stderr: "ignore",
80064
+ })
80065
+ proc.stdin.write(JSON.stringify({ ...payload, cwd: payload.cwd ?? directory }))
80066
+ proc.stdin.end()
80067
+ await proc.exited
80068
+ }
80069
+
80070
+ return {
80071
+ "chat.message": async (input, output) => {
80072
+ userPartIdsBySession.set(
80073
+ input.sessionID,
80074
+ new Set(output.parts.map((part) => part.id).filter(Boolean)),
80075
+ )
80076
+ const prompt = output.parts
80077
+ .filter((part) => part.type === "text")
80078
+ .map((part) => part.text)
80079
+ .join("\\n")
80080
+ await send("user_prompt", { session_id: input.sessionID, prompt })
80081
+ },
80082
+ event: async ({ event }) => {
80083
+ if (event.type === "session.created") {
80084
+ await send("session_start", { session_id: event.properties.info.id })
80085
+ return
80086
+ }
80087
+ if (event.type === "session.idle") {
80088
+ await send("stop", { session_id: event.properties.sessionID })
80089
+ return
80090
+ }
80091
+ if (event.type === "session.deleted") {
80092
+ userPartIdsBySession.delete(event.properties.info.id)
80093
+ await send("session_end", { session_id: event.properties.info.id })
80094
+ return
80095
+ }
80096
+ if (event.type === "session.error" && event.properties.sessionID) {
80097
+ await send("stop", {
80098
+ session_id: event.properties.sessionID,
80099
+ error: event.properties.error,
80100
+ })
80101
+ return
80102
+ }
80103
+ if (event.type !== "message.part.updated") return
80104
+ const part = event.properties.part
80105
+ if (part.type !== "text" && part.type !== "reasoning") return
80106
+ if (userPartIdsBySession.get(part.sessionID)?.has(part.id)) return
80107
+ const previous = textByPart.get(part.id) ?? ""
80108
+ const complete = typeof part.text === "string" ? part.text : ""
80109
+ const text = event.properties.delta ?? (complete.startsWith(previous) ? complete.slice(previous.length) : complete)
80110
+ textByPart.set(part.id, complete)
80111
+ if (!text) return
80112
+ await send("transcript_update", {
80113
+ session_id: part.sessionID,
80114
+ source_cursor: part.id + ":" + complete.length,
80115
+ ...(part.type === "reasoning" ? { thinking: text } : { transcript_delta: text }),
80116
+ })
80117
+ },
80118
+ }
80119
+ }
80120
+ `;
80121
+ }
80122
+ function reconcileOpencodeNativePlugin(input2 = {}) {
80123
+ const runtime = resolveRuntime(input2);
80124
+ const path2 = (0, import_node_path24.join)(runtime.homeDir, ".config", "opencode", "plugins", "alan-native-session.js");
80125
+ if ((0, import_node_fs22.existsSync)(path2) && !(0, import_node_fs22.readFileSync)(path2, "utf8").includes(ALAN_OPENCODE_PLUGIN_MARKER)) {
80126
+ throw new Error(`Refusing to overwrite non-Alan OpenCode plugin at ${path2}`);
80127
+ }
80128
+ const source = opencodePluginSource(runtime);
80129
+ if ((0, import_node_fs22.existsSync)(path2) && (0, import_node_fs22.readFileSync)(path2, "utf8") === source) return false;
80130
+ (0, import_node_fs22.mkdirSync)((0, import_node_path24.dirname)(path2), { recursive: true, mode: 448 });
80131
+ const temporary = `${path2}.${process.pid}.tmp`;
80132
+ (0, import_node_fs22.writeFileSync)(temporary, source, { mode: 384 });
80133
+ (0, import_node_fs22.renameSync)(temporary, path2);
80134
+ return true;
80135
+ }
80136
+ function removeOpencodeNativePlugin(homeDir = (0, import_node_os13.homedir)()) {
80137
+ const path2 = (0, import_node_path24.join)(homeDir, ".config", "opencode", "plugins", "alan-native-session.js");
80138
+ if (!(0, import_node_fs22.existsSync)(path2)) return false;
80139
+ if (!(0, import_node_fs22.readFileSync)(path2, "utf8").includes(ALAN_OPENCODE_PLUGIN_MARKER)) return false;
80140
+ (0, import_node_fs22.rmSync)(path2);
80141
+ return true;
80142
+ }
80143
+ function configFileContainsMarker(path2, marker) {
80144
+ if (!(0, import_node_fs22.existsSync)(path2)) return false;
80145
+ try {
80146
+ return (0, import_node_fs22.readFileSync)(path2, "utf8").includes(marker);
80147
+ } catch {
80148
+ return false;
80149
+ }
80150
+ }
80151
+ function inspectNativeHooksConfigured(providerKind, homeDir = (0, import_node_os13.homedir)()) {
80152
+ switch (providerKind) {
80153
+ case "claude_cli":
80154
+ return configFileContainsMarker((0, import_node_path24.join)(homeDir, ".claude", "settings.json"), ALAN_HOOK_MARKER);
80155
+ case "codex_app_server":
80156
+ return configFileContainsMarker((0, import_node_path24.join)(homeDir, ".codex", "hooks.json"), ALAN_HOOK_MARKER);
80157
+ case "copilot_cli":
80158
+ return configFileContainsMarker(
80159
+ (0, import_node_path24.join)(homeDir, ".copilot", "hooks", "alan-native-session.json"),
80160
+ ALAN_HOOK_MARKER
80161
+ );
80162
+ case "cursor_agent_cli":
80163
+ return configFileContainsMarker((0, import_node_path24.join)(homeDir, ".cursor", "hooks.json"), ALAN_HOOK_MARKER);
80164
+ case "kimi_cli":
80165
+ return configFileContainsMarker(
80166
+ (0, import_node_path24.join)(homeDir, ".kimi-code", "config.toml"),
80167
+ ALAN_KIMI_HOOKS_START
80168
+ );
80169
+ case "grok_cli":
80170
+ return configFileContainsMarker(
80171
+ (0, import_node_path24.join)(homeDir, ".grok", "hooks", "alan-native-session.json"),
80172
+ ALAN_HOOK_MARKER
80173
+ );
80174
+ case "opencode_cli":
80175
+ return configFileContainsMarker(
80176
+ (0, import_node_path24.join)(homeDir, ".config", "opencode", "plugins", "alan-native-session.js"),
80177
+ ALAN_OPENCODE_PLUGIN_MARKER
80178
+ );
80179
+ default:
80180
+ return false;
80181
+ }
80182
+ }
79573
80183
 
79574
80184
  // src/integration-cli.ts
79575
80185
  function alanMcpServers(apiUrl) {
@@ -79580,12 +80190,41 @@ function alanMcpServers(apiUrl) {
79580
80190
  }
79581
80191
  };
79582
80192
  }
80193
+ function reconcileInstalledNativeHooks(options) {
80194
+ const environment = getDaemonCliEnvironment();
80195
+ const nativeRuntime = {
80196
+ configPath: options.configPath ?? getConfigPath(),
80197
+ nodeExecutable: options.nativeHookRuntime?.executable,
80198
+ cliEntry: options.nativeHookRuntime?.cliEntry,
80199
+ environment: options.nativeHookRuntime?.environment
80200
+ };
80201
+ return [
80202
+ resolveCliExecutable("claude", environment) ? reconcileClaudeNativeHooks(nativeRuntime) : false,
80203
+ resolveCliExecutable("codex", environment) ? reconcileCodexNativeHooks(nativeRuntime) : false,
80204
+ resolveCliExecutable("copilot", environment) ? reconcileCopilotNativeHooks(nativeRuntime) : false,
80205
+ resolveCliExecutable("cursor-agent", environment) ? reconcileCursorNativeHooks(nativeRuntime) : false,
80206
+ resolveCliExecutable("kimi-cli", environment) ? reconcileKimiNativeHooks(nativeRuntime) : false,
80207
+ resolveCliExecutable("grok", environment) ? reconcileGrokNativeHooks(nativeRuntime) : false,
80208
+ resolveCliExecutable("opencode", environment) ? reconcileOpencodeNativePlugin(nativeRuntime) : false
80209
+ ].some(Boolean);
80210
+ }
80211
+ function removeNativeHooksOnly() {
80212
+ removeClaudeNativeHooks();
80213
+ removeCodexNativeHooks();
80214
+ removeCopilotNativeHooks();
80215
+ removeCursorNativeHooks();
80216
+ removeKimiNativeHooks();
80217
+ removeGrokNativeHooks();
80218
+ removeOpencodeNativePlugin();
80219
+ }
79583
80220
  function runMcpIntegrationCommand(args, options = {}) {
79584
80221
  bindConfigPath(args);
79585
80222
  const action = args[0] ?? "status";
79586
80223
  const config2 = readConfig();
79587
80224
  const endpoints = resolveEndpoints(args.slice(1), config2);
79588
80225
  const service = new McpSyncService({ enabled: true });
80226
+ const reconcileMcp = options.reconcileMcp ?? true;
80227
+ const reconcileHooks = options.reconcileHooks ?? true;
79589
80228
  if (action === "status") {
79590
80229
  process.stdout.write(`${JSON.stringify(service.getStatus(), null, 2)}
79591
80230
  `);
@@ -79597,23 +80236,26 @@ function runMcpIntegrationCommand(args, options = {}) {
79597
80236
  "Alan is not configured. Run `alan-agent login` or `alan-agent setup` first."
79598
80237
  );
79599
80238
  }
79600
- const result = service.syncServers(alanMcpServers(endpoints.apiUrl), endpoints.apiUrl);
79601
- if (result.errors.length > 0) throw new Error(result.errors.join("; "));
79602
- const hooksUpdated = resolveCliExecutable("claude", getDaemonCliEnvironment()) ? reconcileClaudeNativeHooks({
79603
- configPath: getConfigPath(),
79604
- nodeExecutable: options.nativeHookRuntime?.executable,
79605
- cliEntry: options.nativeHookRuntime?.cliEntry,
79606
- environment: options.nativeHookRuntime?.environment
79607
- }) : false;
80239
+ let mcpServersUpdated = false;
80240
+ if (reconcileMcp) {
80241
+ const result = service.syncServers(alanMcpServers(endpoints.apiUrl), endpoints.apiUrl);
80242
+ if (result.errors.length > 0) throw new Error(result.errors.join("; "));
80243
+ mcpServersUpdated = result.mcpServersUpdated;
80244
+ }
80245
+ const hooksUpdated = reconcileHooks ? reconcileInstalledNativeHooks(options) : false;
79608
80246
  process.stdout.write(
79609
- `${result.mcpServersUpdated || hooksUpdated ? "Alan CLI integrations updated" : "Alan CLI integrations already current"}.
80247
+ `${mcpServersUpdated || hooksUpdated ? "Alan CLI integrations updated" : "Alan CLI integrations already current"}.
79610
80248
  `
79611
80249
  );
79612
80250
  return;
79613
80251
  }
79614
80252
  if (action === "uninstall") {
79615
- service.cleanup(toManagedMcpServers(alanMcpServers(endpoints.apiUrl)));
79616
- removeClaudeNativeHooks();
80253
+ if (reconcileMcp) {
80254
+ service.cleanup(toManagedMcpServers(alanMcpServers(endpoints.apiUrl)));
80255
+ }
80256
+ if (reconcileHooks) {
80257
+ removeNativeHooksOnly();
80258
+ }
79617
80259
  process.stdout.write("Removed Alan-owned MCP configuration.\n");
79618
80260
  return;
79619
80261
  }
@@ -79695,6 +80337,7 @@ function omitUndefined(record2) {
79695
80337
  // src/native-hook-command.ts
79696
80338
  var import_node_crypto19 = require("crypto");
79697
80339
  var import_node_fs23 = require("fs");
80340
+ var import_node_os14 = require("os");
79698
80341
  var import_node_path25 = require("path");
79699
80342
 
79700
80343
  // src/native-session.ts
@@ -79727,28 +80370,64 @@ var NATIVE_SESSION_PROVIDER_CAPABILITIES = [
79727
80370
  command: "codex",
79728
80371
  capabilities: {
79729
80372
  mcp: true,
79730
- lifecycleHooks: false,
79731
- transcriptDelta: false,
79732
- subagents: false,
79733
- sessionEnd: false,
79734
- state: "degraded",
79735
- reason: "Codex exposes a turn-complete notification, not full lifecycle hooks."
80373
+ lifecycleHooks: true,
80374
+ transcriptDelta: true,
80375
+ subagents: true,
80376
+ sessionEnd: true,
80377
+ state: "supported"
79736
80378
  },
79737
- supportedHookEvents: ["agent-turn-complete"]
80379
+ supportedHookEvents: [
80380
+ "SessionStart",
80381
+ "UserPromptSubmit",
80382
+ "PostToolUse",
80383
+ "Stop",
80384
+ "SubagentStart",
80385
+ "SubagentStop",
80386
+ "SessionEnd"
80387
+ ]
79738
80388
  },
79739
80389
  {
79740
80390
  providerKind: "copilot_cli",
79741
80391
  provider: "copilot",
79742
80392
  command: "copilot",
79743
- capabilities: unsupportedMcpOnlyCapability(),
79744
- supportedHookEvents: []
80393
+ capabilities: {
80394
+ mcp: true,
80395
+ lifecycleHooks: true,
80396
+ transcriptDelta: true,
80397
+ subagents: false,
80398
+ sessionEnd: true,
80399
+ state: "supported",
80400
+ reason: "Copilot exposes stable subagent identity only on SubagentStop, so paired subagent lifecycle is not projected."
80401
+ },
80402
+ supportedHookEvents: [
80403
+ "SessionStart",
80404
+ "UserPromptSubmit",
80405
+ "PostToolUse",
80406
+ "Stop",
80407
+ "SubagentStop",
80408
+ "SessionEnd"
80409
+ ]
79745
80410
  },
79746
80411
  {
79747
80412
  providerKind: "cursor_agent_cli",
79748
80413
  provider: "cursor",
79749
80414
  command: "cursor-agent",
79750
- capabilities: unsupportedMcpOnlyCapability(),
79751
- supportedHookEvents: []
80415
+ capabilities: {
80416
+ mcp: true,
80417
+ lifecycleHooks: true,
80418
+ transcriptDelta: true,
80419
+ subagents: false,
80420
+ sessionEnd: true,
80421
+ state: "supported",
80422
+ reason: "Cursor's subagent stop hook does not expose the stable subagent id from subagent start."
80423
+ },
80424
+ supportedHookEvents: [
80425
+ "sessionStart",
80426
+ "beforeSubmitPrompt",
80427
+ "afterAgentResponse",
80428
+ "stop",
80429
+ "sessionEnd"
80430
+ ]
79752
80431
  },
79753
80432
  {
79754
80433
  providerKind: "antigravity_cli",
@@ -79761,22 +80440,70 @@ var NATIVE_SESSION_PROVIDER_CAPABILITIES = [
79761
80440
  providerKind: "kimi_cli",
79762
80441
  provider: "kimi",
79763
80442
  command: "kimi-cli",
79764
- capabilities: unsupportedMcpOnlyCapability(),
79765
- supportedHookEvents: []
80443
+ capabilities: {
80444
+ mcp: true,
80445
+ lifecycleHooks: true,
80446
+ transcriptDelta: true,
80447
+ subagents: false,
80448
+ sessionEnd: true,
80449
+ state: "supported",
80450
+ reason: "Kimi hooks identify subagents by name but do not expose a stable child session id."
80451
+ },
80452
+ supportedHookEvents: [
80453
+ "SessionStart",
80454
+ "UserPromptSubmit",
80455
+ "PostToolUse",
80456
+ "Stop",
80457
+ "Interrupt",
80458
+ "SubagentStart",
80459
+ "SubagentStop",
80460
+ "SessionEnd"
80461
+ ]
79766
80462
  },
79767
80463
  {
79768
80464
  providerKind: "grok_cli",
79769
80465
  provider: "grok",
79770
80466
  command: "grok",
79771
- capabilities: unsupportedMcpOnlyCapability(),
79772
- supportedHookEvents: []
80467
+ capabilities: {
80468
+ mcp: true,
80469
+ lifecycleHooks: true,
80470
+ transcriptDelta: false,
80471
+ subagents: false,
80472
+ sessionEnd: true,
80473
+ state: "supported",
80474
+ reason: "Grok supplies the final assistant message on terminal hooks, but not incremental transcript deltas or stable child session ids."
80475
+ },
80476
+ supportedHookEvents: [
80477
+ "SessionStart",
80478
+ "UserPromptSubmit",
80479
+ "PostToolUse",
80480
+ "Stop",
80481
+ "StopFailure",
80482
+ "StopCancelled",
80483
+ "SubagentStart",
80484
+ "SubagentStop",
80485
+ "SessionEnd"
80486
+ ]
79773
80487
  },
79774
80488
  {
79775
80489
  providerKind: "opencode_cli",
79776
80490
  provider: "opencode",
79777
80491
  command: "opencode",
79778
- capabilities: unsupportedMcpOnlyCapability(),
79779
- supportedHookEvents: []
80492
+ capabilities: {
80493
+ mcp: true,
80494
+ lifecycleHooks: true,
80495
+ transcriptDelta: true,
80496
+ subagents: false,
80497
+ sessionEnd: true,
80498
+ state: "supported",
80499
+ reason: "OpenCode exposes root session and message events; subagent lifecycle is not distinct."
80500
+ },
80501
+ supportedHookEvents: [
80502
+ "session.created",
80503
+ "message.part.updated",
80504
+ "session.idle",
80505
+ "session.deleted"
80506
+ ]
79780
80507
  },
79781
80508
  {
79782
80509
  providerKind: "droid_cli",
@@ -79826,6 +80553,17 @@ function stringField4(payload, ...names) {
79826
80553
  }
79827
80554
  return void 0;
79828
80555
  }
80556
+ function firstStringArrayField(payload, ...names) {
80557
+ for (const name of names) {
80558
+ const value2 = payload[name];
80559
+ if (!Array.isArray(value2)) continue;
80560
+ const first = value2.find(
80561
+ (entry) => typeof entry === "string" && entry.trim().length > 0
80562
+ );
80563
+ if (first) return first.trim();
80564
+ }
80565
+ return void 0;
80566
+ }
79829
80567
  function nonNegativeIntegerField(payload, ...names) {
79830
80568
  for (const name of names) {
79831
80569
  const value2 = payload[name];
@@ -79833,19 +80571,77 @@ function nonNegativeIntegerField(payload, ...names) {
79833
80571
  }
79834
80572
  return void 0;
79835
80573
  }
80574
+ function resolveCodexSessionIdFromTranscriptPath(transcriptPath) {
80575
+ const fileName = (0, import_node_path25.basename)(transcriptPath);
80576
+ const match = /^rollout-.*-([0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12})\.jsonl$/i.exec(
80577
+ fileName
80578
+ );
80579
+ return match?.[1];
80580
+ }
80581
+ function resolveKimiTranscriptPath(externalSessionId, kimiHomeDir = process.env.KIMI_CODE_HOME?.trim() || (0, import_node_path25.join)((0, import_node_os14.homedir)(), ".kimi-code")) {
80582
+ if ((0, import_node_path25.basename)(externalSessionId) !== externalSessionId) return void 0;
80583
+ const sessionsDir = (0, import_node_path25.join)(kimiHomeDir, "sessions");
80584
+ if (!(0, import_node_fs23.existsSync)(sessionsDir)) return void 0;
80585
+ for (const workspace of (0, import_node_fs23.readdirSync)(sessionsDir, { withFileTypes: true })) {
80586
+ if (!workspace.isDirectory()) continue;
80587
+ const transcriptPath = (0, import_node_path25.join)(
80588
+ sessionsDir,
80589
+ workspace.name,
80590
+ externalSessionId,
80591
+ "agents",
80592
+ "main",
80593
+ "wire.jsonl"
80594
+ );
80595
+ if ((0, import_node_fs23.existsSync)(transcriptPath)) return transcriptPath;
80596
+ }
80597
+ return void 0;
80598
+ }
80599
+ function enrichProviderPayload(provider, payload) {
80600
+ if (provider === "codex_app_server") {
80601
+ const externalSessionId2 = stringField4(
80602
+ payload,
80603
+ "session_id",
80604
+ "sessionId",
80605
+ "thread_id",
80606
+ "threadId"
80607
+ );
80608
+ if (externalSessionId2) return payload;
80609
+ const transcriptPath2 = stringField4(payload, "transcript_path", "transcriptPath");
80610
+ if (!transcriptPath2) return payload;
80611
+ const derivedSessionId = resolveCodexSessionIdFromTranscriptPath(transcriptPath2);
80612
+ return derivedSessionId ? { ...payload, session_id: derivedSessionId } : payload;
80613
+ }
80614
+ if (provider !== "kimi_cli") return payload;
80615
+ const externalSessionId = stringField4(payload, "session_id", "sessionId");
80616
+ if (!externalSessionId || stringField4(payload, "transcript_path", "transcriptPath")) {
80617
+ return payload;
80618
+ }
80619
+ const transcriptPath = resolveKimiTranscriptPath(externalSessionId);
80620
+ return transcriptPath ? { ...payload, transcript_path: transcriptPath } : payload;
80621
+ }
79836
80622
  function parseNativeHookEnvelope(input2) {
79837
80623
  if (!isNativeSessionProviderKind(input2.provider)) {
79838
80624
  throw new Error(`unsupported native session provider: ${input2.provider}`);
79839
80625
  }
79840
- const rawHookEvent = input2.hookEvent ?? stringField4(input2.payload, "hook_event_name", "hookEvent", "type") ?? "notification";
79841
- const cwd = stringField4(input2.payload, "cwd", "working_directory", "workingDirectory");
79842
- const transcriptPath = stringField4(input2.payload, "transcript_path", "transcriptPath");
80626
+ const payload = enrichProviderPayload(input2.provider, input2.payload);
80627
+ const rawHookEvent = input2.hookEvent ?? stringField4(payload, "hook_event_name", "hookEvent", "hookEventName", "type") ?? "notification";
80628
+ const eventType = normalizeHookEvent(rawHookEvent);
80629
+ const cwd = stringField4(payload, "cwd", "working_directory", "workingDirectory") ?? firstStringArrayField(payload, "workspace_roots", "workspaceRoots");
80630
+ const transcriptPath = eventType === "subagent_start" || eventType === "subagent_end" ? stringField4(
80631
+ payload,
80632
+ "agent_transcript_path",
80633
+ "agentTranscriptPath",
80634
+ "transcript_path",
80635
+ "transcriptPath"
80636
+ ) : stringField4(payload, "transcript_path", "transcriptPath");
79843
80637
  const capability = NATIVE_SESSION_PROVIDER_CAPABILITIES.find(
79844
80638
  (candidate) => candidate.providerKind === input2.provider
79845
80639
  );
79846
80640
  if (!capability) throw new Error(`unsupported native session provider: ${input2.provider}`);
79847
- const externalSessionId = stringField4(
79848
- input2.payload,
80641
+ const parentSessionId = stringField4(
80642
+ payload,
80643
+ "parent_session_id",
80644
+ "parentSessionId",
79849
80645
  "session_id",
79850
80646
  "sessionId",
79851
80647
  "conversation_id",
@@ -79853,20 +80649,30 @@ function parseNativeHookEnvelope(input2) {
79853
80649
  "thread_id",
79854
80650
  "threadId"
79855
80651
  );
80652
+ const externalSessionId = eventType === "subagent_start" || eventType === "subagent_end" ? stringField4(
80653
+ payload,
80654
+ "agent_id",
80655
+ "agentId",
80656
+ "subagent_id",
80657
+ "subagentId",
80658
+ "task_id",
80659
+ "taskId"
80660
+ ) ?? parentSessionId : parentSessionId;
79856
80661
  if (!externalSessionId) throw new Error("hook payload is missing a provider session id");
79857
- const cursor = stringField4(input2.payload, "source_cursor", "sourceCursor") ?? nonNegativeIntegerField(input2.payload, "byte_offset", "byteOffset")?.toString() ?? nonNegativeIntegerField(input2.payload, "sequence", "seq")?.toString();
80662
+ const cursor = stringField4(payload, "source_cursor", "sourceCursor") ?? nonNegativeIntegerField(payload, "byte_offset", "byteOffset")?.toString() ?? nonNegativeIntegerField(payload, "sequence", "seq")?.toString();
80663
+ const providerPayload = capability.providerKind === "cursor_agent_cli" && eventType === "transcript_update" && !transcriptPath && typeof payload.text === "string" ? { ...payload, assistant_response: payload.text } : payload;
79858
80664
  return {
79859
80665
  schemaVersion: 1,
79860
80666
  eventId: (0, import_node_crypto19.randomUUID)(),
79861
80667
  provider: capability.provider,
79862
- eventType: normalizeHookEvent(rawHookEvent),
80668
+ eventType,
79863
80669
  observedAt: (input2.now ?? /* @__PURE__ */ new Date()).toISOString(),
79864
80670
  externalSessionId,
79865
- parentExternalSessionId: stringField4(input2.payload, "parent_session_id", "parentSessionId"),
80671
+ ...(eventType === "subagent_start" || eventType === "subagent_end") && parentSessionId ? { parentExternalSessionId: parentSessionId } : {},
79866
80672
  ...cwd ? { cwd: (0, import_node_path25.resolve)(cwd) } : {},
79867
80673
  ...transcriptPath ? { transcriptPath: (0, import_node_path25.resolve)(transcriptPath) } : {},
79868
80674
  ...cursor ? { sourceCursor: cursor } : {},
79869
- providerPayload: input2.payload
80675
+ providerPayload
79870
80676
  };
79871
80677
  }
79872
80678
  function normalizeHookEvent(raw) {
@@ -79875,6 +80681,8 @@ function normalizeHookEvent(raw) {
79875
80681
  case "session_start":
79876
80682
  return "session_start";
79877
80683
  case "userpromptsubmit":
80684
+ case "userpromptsubmitted":
80685
+ case "beforesubmitprompt":
79878
80686
  case "user_prompt":
79879
80687
  return "user_prompt";
79880
80688
  case "subagentstart":
@@ -79887,8 +80695,19 @@ function normalizeHookEvent(raw) {
79887
80695
  case "session_end":
79888
80696
  return "session_end";
79889
80697
  case "stop":
80698
+ case "agentstop":
80699
+ case "agent_stop":
79890
80700
  case "agent_turn_complete":
80701
+ case "stopfailure":
80702
+ case "stop_failure":
80703
+ case "stopcancelled":
80704
+ case "stop_cancelled":
80705
+ case "interrupt":
79891
80706
  return "stop";
80707
+ case "afteragentresponse":
80708
+ case "message.part.updated":
80709
+ case "transcript_update":
80710
+ return "transcript_update";
79892
80711
  default:
79893
80712
  return "transcript_update";
79894
80713
  }
@@ -79933,21 +80752,34 @@ function runNativeHookCommand(args) {
79933
80752
  try {
79934
80753
  const payload = readBoundedHookPayload();
79935
80754
  const enqueued = enqueueNativeHookFromConfig({ args, payload });
79936
- const hookEvent = argumentValue(args, "--event")?.toLowerCase();
79937
- if (enqueued && (hookEvent === "userpromptsubmit" || hookEvent === "user_prompt")) {
80755
+ const hookEvent = argumentValue(args, "--event");
80756
+ const normalizedEvent = normalizeHookEvent(hookEvent ?? "notification");
80757
+ if (enqueued && (normalizedEvent === "user_prompt" || normalizedEvent === "session_start")) {
79938
80758
  const providerKind = argumentValue(args, "--provider");
79939
- const externalSessionId = stringField4(payload, "session_id", "sessionId");
80759
+ const externalSessionId = stringField4(
80760
+ payload,
80761
+ "session_id",
80762
+ "sessionId",
80763
+ "conversation_id",
80764
+ "conversationId",
80765
+ "thread_id",
80766
+ "threadId"
80767
+ );
79940
80768
  const capability = providerKind ? NATIVE_SESSION_PROVIDER_CAPABILITIES.find(
79941
80769
  (candidate) => candidate.providerKind === providerKind
79942
80770
  ) : void 0;
79943
- if (capability && externalSessionId) {
80771
+ const shouldInjectLinkingContext = capability && externalSessionId && (capability.providerKind === "claude_cli" || capability.providerKind === "codex_app_server" || capability.providerKind === "kimi_cli" ? normalizedEvent === "user_prompt" : capability.providerKind === "cursor_agent_cli" && normalizedEvent === "session_start");
80772
+ if (shouldInjectLinkingContext && capability && externalSessionId) {
80773
+ const additionalContext = `First call get_native_session_link_status with provider=${capability.provider} and externalSessionId=${externalSessionId}. If status is linked, continue without asking or linking again. If status is syncing, wait briefly and retry the status check. Only when status is pending, ask the user one question: work on an Alan task or continue as a direct session. Resolve a named task with find_records, then call link_native_session. Do not guess a task and do not change task status.`;
79944
80774
  process.stdout.write(
79945
- `${JSON.stringify({
79946
- hookSpecificOutput: {
79947
- hookEventName: "UserPromptSubmit",
79948
- additionalContext: `First call get_native_session_link_status with provider=${capability.provider} and externalSessionId=${externalSessionId}. If status is linked, continue without asking or linking again. If status is syncing, wait briefly and retry the status check. Only when status is pending, ask the user one question: work on an Alan task or continue as a direct session. Resolve a named task with find_records, then call link_native_session. Do not guess a task and do not change task status.`
80775
+ `${JSON.stringify(
80776
+ capability.providerKind === "cursor_agent_cli" ? { additional_context: additionalContext } : {
80777
+ hookSpecificOutput: {
80778
+ hookEventName: "UserPromptSubmit",
80779
+ additionalContext
80780
+ }
79949
80781
  }
79950
- })}
80782
+ )}
79951
80783
  `
79952
80784
  );
79953
80785
  }
@@ -79965,10 +80797,12 @@ function collectNativeIntegrationStatus(args = []) {
79965
80797
  bindConfigPath(args);
79966
80798
  const config2 = readConfig();
79967
80799
  const env = getDaemonCliEnvironment();
80800
+ const homeDir = (0, import_node_os14.homedir)();
79968
80801
  return NATIVE_SESSION_PROVIDER_CAPABILITIES.map((capability) => ({
79969
80802
  provider: capability.providerKind,
79970
80803
  command: capability.command,
79971
80804
  installed: resolveCliExecutable(capability.command, env) !== null,
80805
+ hooksConfigured: inspectNativeHooksConfigured(capability.providerKind, homeDir),
79972
80806
  hookCoverage: capability.capabilities.lifecycleHooks ? "lifecycle" : capability.capabilities.state === "degraded" ? "notification" : "none",
79973
80807
  transcriptStreaming: capability.capabilities.transcriptDelta,
79974
80808
  inboxReady: Boolean(config2.eventSpoolKey)
@@ -79992,7 +80826,7 @@ function decodeResumeFallbackContext(encoded) {
79992
80826
  }
79993
80827
 
79994
80828
  // src/sandbox.ts
79995
- var import_node_os14 = require("os");
80829
+ var import_node_os15 = require("os");
79996
80830
 
79997
80831
  // src/execution-activity-tracker.ts
79998
80832
  var ExecutionActivityTracker = class {
@@ -80510,6 +81344,9 @@ var WebPresenter = class {
80510
81344
  id: (0, import_node_crypto20.randomUUID)(),
80511
81345
  title: APPLICATION_PROBLEM_TITLES[input2.code],
80512
81346
  detail: input2.message,
81347
+ // The schema's slot for the technical cause, so the problem carries it
81348
+ // without putting an SDK error message in front of the person.
81349
+ ...input2.diagnostic ? { diagnosticsRef: input2.diagnostic } : {},
80513
81350
  occurredAt: (/* @__PURE__ */ new Date()).toISOString(),
80514
81351
  severity: "terminal",
80515
81352
  scope: {
@@ -81095,9 +81932,10 @@ var WSClient = class {
81095
81932
 
81096
81933
  // src/sandbox.ts
81097
81934
  var RequiredToolsUnavailableError = class extends Error {
81098
- constructor(code, message) {
81935
+ constructor(code, message, diagnostic) {
81099
81936
  super(message);
81100
81937
  this.code = code;
81938
+ this.diagnostic = diagnostic;
81101
81939
  this.name = "RequiredToolsUnavailableError";
81102
81940
  }
81103
81941
  };
@@ -81285,7 +82123,7 @@ async function runSandbox(config2) {
81285
82123
  }
81286
82124
  const presenter = new WebPresenter(wsClient, config2.sessionId, config2.projectPath);
81287
82125
  presenter.setSuppressSessionLifecycle(true);
81288
- const runtimeSkillManager = await RuntimeSkillManager.open({ homeDirectory: (0, import_node_os14.homedir)() });
82126
+ const runtimeSkillManager = await RuntimeSkillManager.open({ homeDirectory: (0, import_node_os15.homedir)() });
81289
82127
  let lastProviderSessionId = config2.providerSessionId;
81290
82128
  let resumeFallbackContext = config2.resumeFallbackContext;
81291
82129
  let activeBackendKind = config2.backendKind || "claude_cli";
@@ -81370,10 +82208,17 @@ async function runSandbox(config2) {
81370
82208
  lifecycle.warn("sandbox_agent_mcp_readiness_failed", {
81371
82209
  backendKind: activeBackendKind,
81372
82210
  code: readiness.code,
82211
+ // The protocol branch cannot describe itself; without this the
82212
+ // event names a category and nothing else.
82213
+ ...readiness.diagnostic ? { diagnostic: readiness.diagnostic } : {},
81373
82214
  stage: readiness.stage,
81374
82215
  retryable: readiness.retryable
81375
82216
  });
81376
- throw new RequiredToolsUnavailableError(readiness.code, readiness.message);
82217
+ throw new RequiredToolsUnavailableError(
82218
+ readiness.code,
82219
+ readiness.message,
82220
+ readiness.diagnostic
82221
+ );
81377
82222
  }
81378
82223
  } else if (currentRunId ?? config2.runId) {
81379
82224
  lifecycle.warn("sandbox_agent_mcp_contract_missing", {
@@ -81464,7 +82309,11 @@ async function runSandbox(config2) {
81464
82309
  error: errorMessage
81465
82310
  };
81466
82311
  if (error61 instanceof RequiredToolsUnavailableError) {
81467
- presenter.onApplicationError({ code: error61.code, message: error61.message });
82312
+ presenter.onApplicationError({
82313
+ code: error61.code,
82314
+ message: error61.message,
82315
+ ...error61.diagnostic ? { diagnostic: error61.diagnostic } : {}
82316
+ });
81468
82317
  } else {
81469
82318
  presenter.onError(errorMessage, false);
81470
82319
  }
@@ -81574,7 +82423,7 @@ async function runSandbox(config2) {
81574
82423
  // src/service-manager.ts
81575
82424
  var import_node_child_process9 = require("child_process");
81576
82425
  var import_node_fs25 = require("fs");
81577
- var import_node_os15 = require("os");
82426
+ var import_node_os16 = require("os");
81578
82427
  var import_node_path26 = require("path");
81579
82428
  var SERVICE_LABEL = "ai.tryalan.agent";
81580
82429
  var SYSTEMD_UNIT = "alan-agent.service";
@@ -81767,7 +82616,7 @@ WantedBy=default.target
81767
82616
  };
81768
82617
  }
81769
82618
  function currentServicePlan(args, runtime) {
81770
- const currentPlatform = (0, import_node_os15.platform)();
82619
+ const currentPlatform = (0, import_node_os16.platform)();
81771
82620
  if (currentPlatform !== "darwin" && currentPlatform !== "linux" && currentPlatform !== "win32") {
81772
82621
  throw new Error(`Daemon service installation is not supported on ${currentPlatform}`);
81773
82622
  }
@@ -81776,7 +82625,7 @@ function currentServicePlan(args, runtime) {
81776
82625
  if (!cliEntry) throw new Error("Cannot determine the alan-agent executable path");
81777
82626
  return buildDaemonServicePlan({
81778
82627
  platform: currentPlatform,
81779
- homeDir: (0, import_node_os15.homedir)(),
82628
+ homeDir: (0, import_node_os16.homedir)(),
81780
82629
  nodeExecutable: runtime?.executable ?? process.execPath,
81781
82630
  cliEntry: (0, import_node_path26.resolve)(cliEntry),
81782
82631
  profile,
@@ -81813,8 +82662,8 @@ function installDaemonService(args = [], runtime) {
81813
82662
  }
81814
82663
  const plan = currentServicePlan(args, runtime);
81815
82664
  if (plan.manifestPath && plan.manifest) {
81816
- if ((0, import_node_os15.platform)() === "darwin") {
81817
- (0, import_node_fs25.mkdirSync)((0, import_node_path26.join)((0, import_node_os15.homedir)(), ".alan", "agent", "logs"), { recursive: true, mode: 448 });
82665
+ if ((0, import_node_os16.platform)() === "darwin") {
82666
+ (0, import_node_fs25.mkdirSync)((0, import_node_path26.join)((0, import_node_os16.homedir)(), ".alan", "agent", "logs"), { recursive: true, mode: 448 });
81818
82667
  }
81819
82668
  writeManifest(plan.manifestPath, plan.manifest);
81820
82669
  }
@@ -81836,16 +82685,16 @@ function printDaemonServiceStatus(args = []) {
81836
82685
 
81837
82686
  // src/skills/skill-cli.ts
81838
82687
  var import_promises6 = require("fs/promises");
81839
- var import_node_os16 = require("os");
82688
+ var import_node_os17 = require("os");
81840
82689
  var import_node_path27 = require("path");
81841
82690
  async function runSkillsCommand(args) {
81842
82691
  const [subcommand, ...options] = args;
81843
- const homeDirectory = option(options, "--home") ?? (0, import_node_os16.homedir)();
81844
- const manager = await RuntimeSkillManager.open({ homeDirectory });
82692
+ const homeDirectory2 = option(options, "--home") ?? (0, import_node_os17.homedir)();
82693
+ const manager = await RuntimeSkillManager.open({ homeDirectory: homeDirectory2 });
81845
82694
  if (subcommand === "scan") {
81846
82695
  const inputPath = option(options, "--input");
81847
82696
  const declaredInput = inputPath ? scanSkillsInputSchema.parse(await readProtectedJson(inputPath)) : null;
81848
- const input2 = declaredInput ? options.includes("--include-configured") ? await resolveSkillScanInput(homeDirectory, declaredInput) : declaredInput : await defaultScanInput(homeDirectory);
82697
+ const input2 = declaredInput ? options.includes("--include-configured") ? await resolveSkillScanInput(homeDirectory2, declaredInput) : declaredInput : await defaultScanInput(homeDirectory2);
81849
82698
  const outcome = await manager.scan(input2);
81850
82699
  process.stdout.write(`${JSON.stringify(outcome)}
81851
82700
  `);
@@ -81872,8 +82721,8 @@ async function runSkillsCommand(args) {
81872
82721
  "Usage: alan-agent skills scan [--input <0600-json>] [--include-configured] [--home <path>] | skills reconcile --manifest <0600-json> [--home <path>] | skills publish --input <0600-json> [--home <path>]"
81873
82722
  );
81874
82723
  }
81875
- async function defaultScanInput(homeDirectory) {
81876
- return resolveSkillScanInput(homeDirectory, {
82724
+ async function defaultScanInput(homeDirectory2) {
82725
+ return resolveSkillScanInput(homeDirectory2, {
81877
82726
  mode: "audit",
81878
82727
  reason: "refresh",
81879
82728
  enabledProviderKinds: [],