@cydm/happy-elves 0.1.0-beta.31 → 0.1.0-beta.310

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/apps/cli/dist/commands/app.js +10 -0
  2. package/apps/cli/dist/commands/daemon.js +92 -4
  3. package/apps/cli/dist/commands/gateway.d.ts +2 -0
  4. package/apps/cli/dist/commands/gateway.js +429 -0
  5. package/apps/cli/dist/commands/lib/args.js +49 -0
  6. package/apps/cli/dist/commands/lib/bootstrap-daemon.d.ts +2 -2
  7. package/apps/cli/dist/commands/lib/bootstrap-daemon.js +2 -2
  8. package/apps/cli/dist/commands/lib/doctor.d.ts +11 -0
  9. package/apps/cli/dist/commands/lib/doctor.js +276 -11
  10. package/apps/cli/dist/commands/lib/gateway-store.d.ts +38 -0
  11. package/apps/cli/dist/commands/lib/gateway-store.js +33 -0
  12. package/apps/cli/dist/commands/lib/index.d.ts +4 -2
  13. package/apps/cli/dist/commands/lib/index.js +2 -0
  14. package/apps/cli/dist/commands/lib/json.d.ts +2 -2
  15. package/apps/cli/dist/commands/lib/json.js +5 -2
  16. package/apps/cli/dist/commands/lib/local-daemon.d.ts +1 -0
  17. package/apps/cli/dist/commands/lib/local-daemon.js +14 -0
  18. package/apps/cli/dist/commands/lib/paths.d.ts +2 -0
  19. package/apps/cli/dist/commands/lib/paths.js +2 -0
  20. package/apps/cli/dist/commands/lib/relay-db-audit.d.ts +37 -0
  21. package/apps/cli/dist/commands/lib/relay-db-audit.js +300 -0
  22. package/apps/cli/dist/commands/lib/relay-http.d.ts +1 -1
  23. package/apps/cli/dist/commands/lib/scope.d.ts +1 -1
  24. package/apps/cli/dist/commands/lib/session-output.d.ts +15 -1
  25. package/apps/cli/dist/commands/lib/session-output.js +214 -6
  26. package/apps/cli/dist/commands/lib/session-view.d.ts +2 -2
  27. package/apps/cli/dist/commands/lib/status.js +5 -1
  28. package/apps/cli/dist/commands/lib/types.d.ts +4 -2
  29. package/apps/cli/dist/commands/lib/usage.js +123 -10
  30. package/apps/cli/dist/commands/lib/workspace.d.ts +2 -2
  31. package/apps/cli/dist/commands/lib/workspace.js +63 -10
  32. package/apps/cli/dist/commands/machine.js +50 -9
  33. package/apps/cli/dist/commands/memory.d.ts +2 -0
  34. package/apps/cli/dist/commands/memory.js +179 -0
  35. package/apps/cli/dist/commands/relay.js +29 -2
  36. package/apps/cli/dist/commands/release.d.ts +2 -0
  37. package/apps/cli/dist/commands/release.js +197 -0
  38. package/apps/cli/dist/commands/remote.js +10 -2
  39. package/apps/cli/dist/commands/schedule.d.ts +2 -0
  40. package/apps/cli/dist/commands/schedule.js +273 -0
  41. package/apps/cli/dist/commands/session.js +517 -5
  42. package/apps/cli/dist/commands/turn.js +225 -9
  43. package/apps/cli/dist/commands/workspace.d.ts +2 -0
  44. package/apps/cli/dist/commands/workspace.js +68 -0
  45. package/apps/cli/package.json +6 -0
  46. package/apps/daemon/dist/gateway/adapters.d.ts +38 -0
  47. package/apps/daemon/dist/gateway/adapters.js +2 -0
  48. package/apps/daemon/dist/gateway/feishu.d.ts +65 -0
  49. package/apps/daemon/dist/gateway/feishu.js +493 -0
  50. package/apps/daemon/dist/gateway/format.d.ts +2 -0
  51. package/apps/daemon/dist/gateway/format.js +19 -0
  52. package/apps/daemon/dist/gateway/handler.d.ts +7 -0
  53. package/apps/daemon/dist/gateway/handler.js +151 -0
  54. package/apps/daemon/dist/gateway/runtime.d.ts +33 -0
  55. package/apps/daemon/dist/gateway/runtime.js +850 -0
  56. package/apps/daemon/dist/gateway/store.d.ts +92 -0
  57. package/apps/daemon/dist/gateway/store.js +268 -0
  58. package/apps/daemon/dist/memory/handler.d.ts +7 -0
  59. package/apps/daemon/dist/memory/handler.js +105 -0
  60. package/apps/daemon/dist/memory/manager.d.ts +44 -0
  61. package/apps/daemon/dist/memory/manager.js +359 -0
  62. package/apps/daemon/dist/paths.d.ts +3 -0
  63. package/apps/daemon/dist/paths.js +3 -0
  64. package/apps/daemon/dist/relay/admission.d.ts +30 -0
  65. package/apps/daemon/dist/relay/admission.js +31 -0
  66. package/apps/daemon/dist/relay/connection.js +37 -1
  67. package/apps/daemon/dist/relay/devtools.d.ts +1 -1
  68. package/apps/daemon/dist/relay/register.js +2 -0
  69. package/apps/daemon/dist/relay/send.d.ts +2 -2
  70. package/apps/daemon/dist/relay/send.js +2 -0
  71. package/apps/daemon/dist/relay-http.d.ts +1 -1
  72. package/apps/daemon/dist/runtime/external-provider.d.ts +1 -1
  73. package/apps/daemon/dist/runtime/external-provider.js +187 -17
  74. package/apps/daemon/dist/runtime.d.ts +1 -2
  75. package/apps/daemon/dist/runtime.js +0 -3
  76. package/apps/daemon/dist/schedule/handler.d.ts +9 -0
  77. package/apps/daemon/dist/schedule/handler.js +148 -0
  78. package/apps/daemon/dist/schedule/runner.d.ts +21 -0
  79. package/apps/daemon/dist/schedule/runner.js +547 -0
  80. package/apps/daemon/dist/schedule/store.d.ts +9 -0
  81. package/apps/daemon/dist/schedule/store.js +143 -0
  82. package/apps/daemon/dist/session/create-session.d.ts +1 -1
  83. package/apps/daemon/dist/session/directory.d.ts +1 -1
  84. package/apps/daemon/dist/session/events.d.ts +15 -2
  85. package/apps/daemon/dist/session/events.js +76 -24
  86. package/apps/daemon/dist/session/file-preview.d.ts +1 -1
  87. package/apps/daemon/dist/session/lifecycle.d.ts +26 -3
  88. package/apps/daemon/dist/session/lifecycle.js +161 -22
  89. package/apps/daemon/dist/session/metadata.d.ts +2 -2
  90. package/apps/daemon/dist/session/metadata.js +42 -1
  91. package/apps/daemon/dist/session/primitives.d.ts +1 -1
  92. package/apps/daemon/dist/session/primitives.js +37 -6
  93. package/apps/daemon/dist/session/prompt.d.ts +28 -1
  94. package/apps/daemon/dist/session/prompt.js +340 -5
  95. package/apps/daemon/dist/session/reconcile.d.ts +3 -0
  96. package/apps/daemon/dist/session/reconcile.js +235 -0
  97. package/apps/daemon/dist/session/runtime-handle.d.ts +1 -1
  98. package/apps/daemon/dist/start.js +5 -1
  99. package/apps/daemon/dist/state.d.ts +2 -2
  100. package/apps/daemon/dist/turn-coordinator.d.ts +1 -0
  101. package/apps/daemon/dist/turn-coordinator.js +4 -0
  102. package/apps/daemon/dist/types.d.ts +16 -1
  103. package/apps/daemon/package.json +3 -25
  104. package/apps/relay/dist/connections.d.ts +2 -0
  105. package/apps/relay/dist/controller-handlers.d.ts +42 -2
  106. package/apps/relay/dist/controller-handlers.js +349 -37
  107. package/apps/relay/dist/db.js +296 -2
  108. package/apps/relay/dist/errors.d.ts +2 -1
  109. package/apps/relay/dist/errors.js +3 -1
  110. package/apps/relay/dist/http-routes.js +659 -33
  111. package/apps/relay/dist/http-schemas.d.ts +156 -0
  112. package/apps/relay/dist/http-schemas.js +85 -0
  113. package/apps/relay/dist/index.js +31 -1
  114. package/apps/relay/dist/machine-handlers.d.ts +15 -7
  115. package/apps/relay/dist/machine-handlers.js +567 -27
  116. package/apps/relay/dist/projections.d.ts +1 -1
  117. package/apps/relay/dist/projections.js +13 -0
  118. package/apps/relay/dist/relay-context.d.ts +41 -3
  119. package/apps/relay/dist/relay-context.js +244 -19
  120. package/apps/relay/dist/repositories.d.ts +2 -2
  121. package/apps/relay/dist/repositories.js +28 -1
  122. package/apps/relay/dist/runtime-bindings.d.ts +25 -0
  123. package/apps/relay/dist/runtime-bindings.js +49 -0
  124. package/apps/relay/dist/scope.d.ts +1 -1
  125. package/apps/relay/dist/types.d.ts +71 -1
  126. package/apps/relay/dist/websocket.js +2 -0
  127. package/package.json +5 -11
  128. package/packages/agent-sdk/dist/index.d.ts +80 -0
  129. package/packages/agent-sdk/dist/index.js +16 -0
  130. package/packages/client/dist/account.d.ts +35 -2
  131. package/packages/client/dist/account.js +98 -1
  132. package/packages/client/dist/client.d.ts +59 -6
  133. package/packages/client/dist/client.js +312 -58
  134. package/packages/client/dist/index.d.ts +1 -1
  135. package/packages/client/dist/parsers.d.ts +28 -2
  136. package/packages/client/dist/parsers.js +167 -0
  137. package/packages/client/dist/transport.d.ts +21 -1
  138. package/packages/client/dist/transport.js +69 -6
  139. package/packages/client/dist/types.d.ts +177 -1
  140. package/packages/client/dist/validation.d.ts +1 -1
  141. package/packages/runtime/dist/index.d.ts +66 -0
  142. package/packages/runtime-acpx/dist/index.d.ts +1 -1
  143. package/packages/runtime-acpx/dist/index.js +8 -0
  144. package/packages/runtime-cli/dist/claude-history.d.ts +1 -2
  145. package/packages/runtime-cli/dist/claude-history.js +0 -3
  146. package/packages/runtime-cli/dist/claude-session-store.d.ts +0 -1
  147. package/packages/runtime-cli/dist/claude-session-store.js +1 -1
  148. package/packages/runtime-cli/dist/claude-turn.d.ts +2 -1
  149. package/packages/runtime-cli/dist/claude-turn.js +29 -9
  150. package/packages/runtime-cli/dist/codex-app-server.d.ts +8 -3
  151. package/packages/runtime-cli/dist/codex-app-server.js +122 -25
  152. package/packages/runtime-cli/dist/codex-history.d.ts +1 -2
  153. package/packages/runtime-cli/dist/codex-history.js +11 -5
  154. package/packages/runtime-cli/dist/codex-protocol.d.ts +2 -2
  155. package/packages/runtime-cli/dist/codex-protocol.js +4 -4
  156. package/packages/runtime-cli/dist/history-merge.d.ts +1 -1
  157. package/packages/runtime-cli/dist/index.d.ts +1 -1
  158. package/packages/runtime-cli/dist/index.js +108 -2
  159. package/packages/runtime-cli/dist/permissions.d.ts +1 -1
  160. package/packages/runtime-cli/dist/session-store.d.ts +2 -1
  161. package/packages/runtime-cli/dist/session-store.js +9 -8
  162. package/packages/shared/dist/index.d.ts +2 -0
  163. package/packages/shared/dist/index.js +2 -0
  164. package/packages/shared/dist/protocol-schemas.d.ts +1077 -0
  165. package/packages/shared/dist/protocol-schemas.js +273 -0
  166. package/packages/shared/dist/protocol-types.d.ts +371 -3
  167. package/packages/shared/dist/protocol.d.ts +181 -2
  168. package/packages/shared/dist/protocol.js +197 -1
  169. package/packages/shared/dist/session-tags.d.ts +12 -0
  170. package/packages/shared/dist/session-tags.js +50 -0
  171. package/apps/cli/dist/commands/account.js.map +0 -1
  172. package/apps/cli/dist/commands/app.js.map +0 -1
  173. package/apps/cli/dist/commands/collect.js.map +0 -1
  174. package/apps/cli/dist/commands/command.js.map +0 -1
  175. package/apps/cli/dist/commands/config.js.map +0 -1
  176. package/apps/cli/dist/commands/daemon.js.map +0 -1
  177. package/apps/cli/dist/commands/lib/args.js.map +0 -1
  178. package/apps/cli/dist/commands/lib/audit.js.map +0 -1
  179. package/apps/cli/dist/commands/lib/bootstrap-config.js.map +0 -1
  180. package/apps/cli/dist/commands/lib/bootstrap-daemon.js.map +0 -1
  181. package/apps/cli/dist/commands/lib/bootstrap-output.js.map +0 -1
  182. package/apps/cli/dist/commands/lib/bootstrap.js.map +0 -1
  183. package/apps/cli/dist/commands/lib/config.js.map +0 -1
  184. package/apps/cli/dist/commands/lib/doctor.js.map +0 -1
  185. package/apps/cli/dist/commands/lib/exit.js.map +0 -1
  186. package/apps/cli/dist/commands/lib/index.js.map +0 -1
  187. package/apps/cli/dist/commands/lib/json.js.map +0 -1
  188. package/apps/cli/dist/commands/lib/local-daemon.js.map +0 -1
  189. package/apps/cli/dist/commands/lib/loop-store.js.map +0 -1
  190. package/apps/cli/dist/commands/lib/paths.js.map +0 -1
  191. package/apps/cli/dist/commands/lib/relay-http.js.map +0 -1
  192. package/apps/cli/dist/commands/lib/scope.js.map +0 -1
  193. package/apps/cli/dist/commands/lib/session-output.js.map +0 -1
  194. package/apps/cli/dist/commands/lib/session-view.js.map +0 -1
  195. package/apps/cli/dist/commands/lib/status.js.map +0 -1
  196. package/apps/cli/dist/commands/lib/types.js.map +0 -1
  197. package/apps/cli/dist/commands/lib/usage.js.map +0 -1
  198. package/apps/cli/dist/commands/lib/workspace.js.map +0 -1
  199. package/apps/cli/dist/commands/loop.js.map +0 -1
  200. package/apps/cli/dist/commands/machine.js.map +0 -1
  201. package/apps/cli/dist/commands/relay.js.map +0 -1
  202. package/apps/cli/dist/commands/remote.js.map +0 -1
  203. package/apps/cli/dist/commands/session.js.map +0 -1
  204. package/apps/cli/dist/commands/token.js.map +0 -1
  205. package/apps/cli/dist/commands/turn.js.map +0 -1
  206. package/apps/cli/dist/errors.js.map +0 -1
  207. package/apps/cli/dist/index.js.map +0 -1
  208. package/apps/daemon/dist/app.js.map +0 -1
  209. package/apps/daemon/dist/args.js.map +0 -1
  210. package/apps/daemon/dist/audit.js.map +0 -1
  211. package/apps/daemon/dist/cli.js.map +0 -1
  212. package/apps/daemon/dist/config.js.map +0 -1
  213. package/apps/daemon/dist/errors.js.map +0 -1
  214. package/apps/daemon/dist/loop/runner.js.map +0 -1
  215. package/apps/daemon/dist/loop/store.js.map +0 -1
  216. package/apps/daemon/dist/pair.js.map +0 -1
  217. package/apps/daemon/dist/paths.js.map +0 -1
  218. package/apps/daemon/dist/process.js.map +0 -1
  219. package/apps/daemon/dist/relay/connection.js.map +0 -1
  220. package/apps/daemon/dist/relay/devtools.js.map +0 -1
  221. package/apps/daemon/dist/relay/register.js.map +0 -1
  222. package/apps/daemon/dist/relay/send.js.map +0 -1
  223. package/apps/daemon/dist/relay-http.js.map +0 -1
  224. package/apps/daemon/dist/runtime/external-provider.js.map +0 -1
  225. package/apps/daemon/dist/runtime.js.map +0 -1
  226. package/apps/daemon/dist/session/create-session.js.map +0 -1
  227. package/apps/daemon/dist/session/directory.js.map +0 -1
  228. package/apps/daemon/dist/session/events.js.map +0 -1
  229. package/apps/daemon/dist/session/file-preview.js.map +0 -1
  230. package/apps/daemon/dist/session/lifecycle.js.map +0 -1
  231. package/apps/daemon/dist/session/metadata.js.map +0 -1
  232. package/apps/daemon/dist/session/primitives.js.map +0 -1
  233. package/apps/daemon/dist/session/prompt.js.map +0 -1
  234. package/apps/daemon/dist/session/runtime-handle.js.map +0 -1
  235. package/apps/daemon/dist/start.js.map +0 -1
  236. package/apps/daemon/dist/state.js.map +0 -1
  237. package/apps/daemon/dist/turn-coordinator.js.map +0 -1
  238. package/apps/daemon/dist/types.js.map +0 -1
  239. package/apps/daemon/dist/utils.js.map +0 -1
  240. package/apps/relay/dist/auth.js.map +0 -1
  241. package/apps/relay/dist/connections.js.map +0 -1
  242. package/apps/relay/dist/controller-handlers.js.map +0 -1
  243. package/apps/relay/dist/db.js.map +0 -1
  244. package/apps/relay/dist/errors.js.map +0 -1
  245. package/apps/relay/dist/http-routes.js.map +0 -1
  246. package/apps/relay/dist/http-schemas.js.map +0 -1
  247. package/apps/relay/dist/index.js.map +0 -1
  248. package/apps/relay/dist/machine-handlers.js.map +0 -1
  249. package/apps/relay/dist/projections.js.map +0 -1
  250. package/apps/relay/dist/relay-context.js.map +0 -1
  251. package/apps/relay/dist/repositories.js.map +0 -1
  252. package/apps/relay/dist/retention.js.map +0 -1
  253. package/apps/relay/dist/scope.js.map +0 -1
  254. package/apps/relay/dist/security.js.map +0 -1
  255. package/apps/relay/dist/types.js.map +0 -1
  256. package/apps/relay/dist/websocket.js.map +0 -1
  257. package/apps/relay/package.json +0 -29
  258. package/packages/agent-sdk/dist/index.d.ts.map +0 -1
  259. package/packages/agent-sdk/dist/index.js.map +0 -1
  260. package/packages/agent-sdk/package.json +0 -20
  261. package/packages/client/dist/account.d.ts.map +0 -1
  262. package/packages/client/dist/account.js.map +0 -1
  263. package/packages/client/dist/client.d.ts.map +0 -1
  264. package/packages/client/dist/client.js.map +0 -1
  265. package/packages/client/dist/errors.d.ts.map +0 -1
  266. package/packages/client/dist/errors.js.map +0 -1
  267. package/packages/client/dist/http.d.ts.map +0 -1
  268. package/packages/client/dist/http.js.map +0 -1
  269. package/packages/client/dist/index.d.ts.map +0 -1
  270. package/packages/client/dist/index.js.map +0 -1
  271. package/packages/client/dist/parsers.d.ts.map +0 -1
  272. package/packages/client/dist/parsers.js.map +0 -1
  273. package/packages/client/dist/transport.d.ts.map +0 -1
  274. package/packages/client/dist/transport.js.map +0 -1
  275. package/packages/client/dist/types.d.ts.map +0 -1
  276. package/packages/client/dist/types.js.map +0 -1
  277. package/packages/client/dist/validation.d.ts.map +0 -1
  278. package/packages/client/dist/validation.js.map +0 -1
  279. package/packages/client/package.json +0 -22
  280. package/packages/pie-provider/dist/index.d.ts.map +0 -1
  281. package/packages/pie-provider/dist/index.js.map +0 -1
  282. package/packages/pie-provider/package.json +0 -26
  283. package/packages/runtime/dist/index.d.ts.map +0 -1
  284. package/packages/runtime/dist/index.js.map +0 -1
  285. package/packages/runtime/package.json +0 -19
  286. package/packages/runtime-acpx/dist/index.d.ts.map +0 -1
  287. package/packages/runtime-acpx/dist/index.js.map +0 -1
  288. package/packages/runtime-acpx/package.json +0 -23
  289. package/packages/runtime-cli/dist/async-queue.d.ts.map +0 -1
  290. package/packages/runtime-cli/dist/async-queue.js.map +0 -1
  291. package/packages/runtime-cli/dist/claude-history.d.ts.map +0 -1
  292. package/packages/runtime-cli/dist/claude-history.js.map +0 -1
  293. package/packages/runtime-cli/dist/claude-json.d.ts.map +0 -1
  294. package/packages/runtime-cli/dist/claude-json.js.map +0 -1
  295. package/packages/runtime-cli/dist/claude-rename.d.ts.map +0 -1
  296. package/packages/runtime-cli/dist/claude-rename.js.map +0 -1
  297. package/packages/runtime-cli/dist/claude-session-store.d.ts.map +0 -1
  298. package/packages/runtime-cli/dist/claude-session-store.js.map +0 -1
  299. package/packages/runtime-cli/dist/claude-turn.d.ts.map +0 -1
  300. package/packages/runtime-cli/dist/claude-turn.js.map +0 -1
  301. package/packages/runtime-cli/dist/codex-app-server.d.ts.map +0 -1
  302. package/packages/runtime-cli/dist/codex-app-server.js.map +0 -1
  303. package/packages/runtime-cli/dist/codex-approvals.d.ts.map +0 -1
  304. package/packages/runtime-cli/dist/codex-approvals.js.map +0 -1
  305. package/packages/runtime-cli/dist/codex-history.d.ts.map +0 -1
  306. package/packages/runtime-cli/dist/codex-history.js.map +0 -1
  307. package/packages/runtime-cli/dist/codex-json-rpc.d.ts.map +0 -1
  308. package/packages/runtime-cli/dist/codex-json-rpc.js.map +0 -1
  309. package/packages/runtime-cli/dist/codex-lifecycle.d.ts.map +0 -1
  310. package/packages/runtime-cli/dist/codex-lifecycle.js.map +0 -1
  311. package/packages/runtime-cli/dist/codex-protocol.d.ts.map +0 -1
  312. package/packages/runtime-cli/dist/codex-protocol.js.map +0 -1
  313. package/packages/runtime-cli/dist/command-resolver.d.ts.map +0 -1
  314. package/packages/runtime-cli/dist/command-resolver.js.map +0 -1
  315. package/packages/runtime-cli/dist/history-merge.d.ts.map +0 -1
  316. package/packages/runtime-cli/dist/history-merge.js.map +0 -1
  317. package/packages/runtime-cli/dist/index.d.ts.map +0 -1
  318. package/packages/runtime-cli/dist/index.js.map +0 -1
  319. package/packages/runtime-cli/dist/permissions.d.ts.map +0 -1
  320. package/packages/runtime-cli/dist/permissions.js.map +0 -1
  321. package/packages/runtime-cli/dist/session-store.d.ts.map +0 -1
  322. package/packages/runtime-cli/dist/session-store.js.map +0 -1
  323. package/packages/runtime-cli/package.json +0 -22
  324. package/packages/shared/dist/args.d.ts.map +0 -1
  325. package/packages/shared/dist/args.js.map +0 -1
  326. package/packages/shared/dist/crypto.d.ts.map +0 -1
  327. package/packages/shared/dist/crypto.js.map +0 -1
  328. package/packages/shared/dist/ids.d.ts.map +0 -1
  329. package/packages/shared/dist/ids.js.map +0 -1
  330. package/packages/shared/dist/index.d.ts.map +0 -1
  331. package/packages/shared/dist/index.js.map +0 -1
  332. package/packages/shared/dist/protocol-schemas.d.ts.map +0 -1
  333. package/packages/shared/dist/protocol-schemas.js.map +0 -1
  334. package/packages/shared/dist/protocol-types.d.ts.map +0 -1
  335. package/packages/shared/dist/protocol-types.js.map +0 -1
  336. package/packages/shared/dist/protocol.d.ts.map +0 -1
  337. package/packages/shared/dist/protocol.js.map +0 -1
  338. package/packages/shared/dist/session-name.d.ts.map +0 -1
  339. package/packages/shared/dist/session-name.js.map +0 -1
  340. package/packages/shared/dist/session-state.d.ts.map +0 -1
  341. package/packages/shared/dist/session-state.js.map +0 -1
  342. package/packages/shared/package.json +0 -24
@@ -2,7 +2,7 @@ import { CliError } from "../../errors.js";
2
2
  import { showMachine } from "./session-view.js";
3
3
  export async function listWorkspaceHistoricalSessions(client, input) {
4
4
  const snapshot = await client.snapshot();
5
- const providerLimit = Math.min(200, Math.max(input.limit, 50));
5
+ const providerPageSize = Math.min(200, Math.max(Math.min(input.limit, 200), 50));
6
6
  const selectedMachines = snapshot.machines.filter((machine) => {
7
7
  if (input.machineId)
8
8
  return machine.id === input.machineId;
@@ -17,13 +17,26 @@ export async function listWorkspaceHistoricalSessions(client, input) {
17
17
  const rows = await Promise.all(machines.map(async ({ machine, projected }) => {
18
18
  const machineName = projected.metadata.name ?? projected.metadata.hostname ?? machine.name;
19
19
  try {
20
- const sessions = await client.listHistoricalSessions({
21
- machineId: machine.id,
22
- cwd: input.cwd,
23
- agent: input.agent,
24
- includeArchived: input.includeArchived,
25
- limit: providerLimit,
26
- });
20
+ const sessions = [];
21
+ let cursor;
22
+ const seenCursors = new Set();
23
+ while (sessions.length < input.limit) {
24
+ const page = await client.listHistoricalSessionsPage({
25
+ machineId: machine.id,
26
+ cwd: input.cwd,
27
+ agent: input.agent,
28
+ includeArchived: input.includeArchived,
29
+ limit: providerPageSize,
30
+ cursor,
31
+ });
32
+ sessions.push(...page.sessions);
33
+ if (!page.hasMore || !page.nextCursor)
34
+ break;
35
+ if (seenCursors.has(page.nextCursor))
36
+ break;
37
+ seenCursors.add(page.nextCursor);
38
+ cursor = page.nextCursor;
39
+ }
27
40
  return {
28
41
  sessions: sessions
29
42
  .filter((session) => input.includeArchived === true || session.runtimeState !== "archived")
@@ -47,12 +60,52 @@ export async function listWorkspaceHistoricalSessions(client, input) {
47
60
  }
48
61
  }));
49
62
  return {
50
- sessions: rows
63
+ sessions: await enrichHistoricalLoadedSessionIds(client, rows
51
64
  .flatMap((row) => row.sessions)
52
65
  .sort((left, right) => right.updatedAt - left.updatedAt || left.runtimeSessionId.localeCompare(right.runtimeSessionId))
53
- .slice(0, input.limit),
66
+ .slice(0, input.limit)),
54
67
  errors: rows.flatMap((row) => row.error ? [row.error] : []),
55
68
  machines: rows.map((row) => row.machine),
56
69
  };
57
70
  }
71
+ async function enrichHistoricalLoadedSessionIds(client, sessions) {
72
+ const snapshot = await client.snapshot();
73
+ const runtimeIdToSession = new Map();
74
+ for (const session of snapshot.sessions) {
75
+ if (session.status === "closed")
76
+ continue;
77
+ const metadata = await client.decodeSessionMetadata(session);
78
+ for (const runtimeSessionId of metadataRuntimeSessionIds(metadata)) {
79
+ const key = `${session.machineId}:${session.agent}:${runtimeSessionId}`;
80
+ const existing = runtimeIdToSession.get(key);
81
+ if (!existing || session.createdAt < existing.createdAt || (session.createdAt === existing.createdAt && session.id < existing.id)) {
82
+ runtimeIdToSession.set(key, session);
83
+ }
84
+ }
85
+ }
86
+ return sessions.map((historical) => {
87
+ const loaded = runtimeIdToSession.get(`${historical.machineId}:${historical.agent}:${historical.runtimeSessionId}`);
88
+ return loaded ? { ...historical, loadedSessionId: loaded.id } : historical;
89
+ });
90
+ }
91
+ function metadataRuntimeSessionIds(metadata) {
92
+ const ids = new Set();
93
+ addRuntimeSessionId(ids, metadata.importedFromRuntimeSessionId);
94
+ const runtime = metadata.runtime;
95
+ if (runtime && typeof runtime === "object" && !Array.isArray(runtime)) {
96
+ const record = runtime;
97
+ addRuntimeSessionId(ids, record.backendSessionId);
98
+ addRuntimeSessionId(ids, record.agentSessionId);
99
+ addRuntimeSessionId(ids, record.acpxRecordId);
100
+ const externalHandle = record.externalHandle;
101
+ if (externalHandle && typeof externalHandle === "object" && !Array.isArray(externalHandle)) {
102
+ addRuntimeSessionId(ids, externalHandle.sessionId);
103
+ }
104
+ }
105
+ return ids;
106
+ }
107
+ function addRuntimeSessionId(ids, value) {
108
+ if (typeof value === "string" && value.trim())
109
+ ids.add(value.trim());
110
+ }
58
111
  //# sourceMappingURL=workspace.js.map
@@ -1,14 +1,50 @@
1
1
  import fs from "node:fs";
2
2
  import { CliError, ControllerClient, compactText, machineSessionOverview, ok, readConfig, requirePositional, showMachine, wantsJson, wantsVerbose } from "./lib/index.js";
3
+ function machineDisplayName(machine) {
4
+ return machine.metadata.name ?? machine.name;
5
+ }
6
+ function duplicateNameKey(value) {
7
+ return value.trim().toLocaleLowerCase();
8
+ }
9
+ function annotateStaleDuplicateMachines(machines) {
10
+ const byName = new Map();
11
+ for (const machine of machines) {
12
+ const displayName = machineDisplayName(machine);
13
+ const key = duplicateNameKey(displayName);
14
+ if (!key)
15
+ continue;
16
+ const group = byName.get(key) ?? { displayName, machines: [] };
17
+ group.machines.push(machine);
18
+ byName.set(key, group);
19
+ }
20
+ return machines.map((machine) => {
21
+ if (machine.online)
22
+ return machine;
23
+ const displayName = machineDisplayName(machine);
24
+ const group = byName.get(duplicateNameKey(displayName));
25
+ const onlinePeerIds = group?.machines.filter((peer) => peer.online && peer.id !== machine.id).map((peer) => peer.id) ?? [];
26
+ if (onlinePeerIds.length === 0)
27
+ return machine;
28
+ return {
29
+ ...machine,
30
+ staleDuplicate: {
31
+ reason: "offline-same-name",
32
+ displayName,
33
+ onlinePeerIds,
34
+ },
35
+ };
36
+ });
37
+ }
3
38
  function structuredMachineSummary(machine) {
4
39
  const summary = machine.summary;
5
40
  return {
6
41
  machineId: machine.id,
7
- name: machine.metadata.name ?? machine.name,
42
+ name: machineDisplayName(machine),
8
43
  online: machine.online,
9
44
  sessionCount: summary.sessionCount,
10
45
  runningCount: summary.runningSessionCount,
11
46
  blockedCount: summary.blockedSessionCount,
47
+ ...(machine.staleDuplicate ? { staleDuplicate: machine.staleDuplicate } : {}),
12
48
  };
13
49
  }
14
50
  function structuredMachineVerbose(machine) {
@@ -16,26 +52,30 @@ function structuredMachineVerbose(machine) {
16
52
  machineId: machine.id,
17
53
  online: machine.online,
18
54
  lastSeen: machine.lastSeen,
19
- name: machine.metadata.name ?? machine.name,
55
+ name: machineDisplayName(machine),
20
56
  defaultCwd: machine.defaultCwd,
21
57
  capabilities: machine.capabilities,
22
58
  metadata: machine.metadata,
23
59
  summary: machine.summary,
24
60
  sessions: machine.sessions,
25
61
  encryptedMetadata: machine.encryptedMetadata,
62
+ ...(machine.staleDuplicate ? { staleDuplicate: machine.staleDuplicate } : {}),
26
63
  };
27
64
  }
28
65
  function printMachineLine(machine) {
29
- const name = machine.metadata.name ?? machine.name;
66
+ const name = machineDisplayName(machine);
30
67
  const summary = machine.summary;
31
- console.log(`${machine.id} ${machine.online ? "online" : "offline"} ${compactText(name, 32)} sessions:${summary.sessionCount} running:${summary.runningSessionCount} blocked:${summary.blockedSessionCount}`);
68
+ const duplicate = machine.staleDuplicate ? ` stale-duplicate-of:${machine.staleDuplicate.onlinePeerIds.join(",")}` : "";
69
+ console.log(`${machine.id} ${machine.online ? "online" : "offline"} ${compactText(name, 32)} sessions:${summary.sessionCount} running:${summary.runningSessionCount} blocked:${summary.blockedSessionCount}${duplicate}`);
32
70
  }
33
71
  function printMachineDetails(machine) {
34
- const name = machine.metadata.name ?? machine.name;
72
+ const name = machineDisplayName(machine);
35
73
  const agents = machine.capabilities.agents.map((agent) => agent.id).join(", ") || "-";
36
74
  const summary = machine.summary;
37
75
  console.log(`${name} (${machine.id})`);
38
76
  console.log(` status: ${machine.online ? "online" : "offline"} agents: ${agents}`);
77
+ if (machine.staleDuplicate)
78
+ console.log(` stale duplicate: offline machine with online peer ${machine.staleDuplicate.onlinePeerIds.join(", ")}`);
39
79
  console.log(` cwd: ${machine.defaultCwd ?? "-"}`);
40
80
  console.log(` sessions: ${summary.sessionCount} total, ${summary.runningSessionCount} running, ${summary.readySessionCount} ready, ${summary.needsUserSessionCount} needs user`);
41
81
  console.log(` sessions: happy-elves session list --machine ${machine.id} --limit 20`);
@@ -176,19 +216,20 @@ export async function handleMachine({ domain, action, positional, flags }) {
176
216
  ...(await showMachine(client, machine)),
177
217
  ...(await machineSessionOverview(client, snapshot.sessions, machine.id)),
178
218
  })));
219
+ const annotatedMachines = annotateStaleDuplicateMachines(machines);
179
220
  if (!wantsJson(flags)) {
180
- if (machines.length === 0) {
221
+ if (annotatedMachines.length === 0) {
181
222
  console.log("No machines.");
182
223
  return true;
183
224
  }
184
- for (const machine of machines) {
225
+ for (const machine of annotatedMachines) {
185
226
  printMachineLine(machine);
186
227
  }
187
228
  return true;
188
229
  }
189
230
  ok("machine.list", {
190
- machines: machines.map((machine) => (wantsVerbose(flags) ? structuredMachineVerbose(machine) : structuredMachineSummary(machine))),
191
- page: { returned: machines.length },
231
+ machines: annotatedMachines.map((machine) => (wantsVerbose(flags) ? structuredMachineVerbose(machine) : structuredMachineSummary(machine))),
232
+ page: { returned: annotatedMachines.length },
192
233
  });
193
234
  return true;
194
235
  }
@@ -0,0 +1,2 @@
1
+ import type { CommandInput } from "./command.js";
2
+ export declare function handleMemory({ domain, action, positional, flags }: CommandInput): Promise<boolean>;
@@ -0,0 +1,179 @@
1
+ import { CliError, ControllerClient, ok, readConfig, readPromptTextFile, requirePositional, requireString, wantsJson, wantsVerbose } from "./lib/index.js";
2
+ export async function handleMemory({ domain, action, positional, flags }) {
3
+ if (domain !== "memory")
4
+ return false;
5
+ const config = await readConfig(flags);
6
+ const client = new ControllerClient(config);
7
+ if (action === "overview" || action === "status" || action === "list") {
8
+ const machineId = await resolveMemoryMachineId(client, flags);
9
+ const projectKey = await resolveMemoryProjectKey(client, flags, machineId);
10
+ const result = await client.memory({ machineId, action: "overview", projectKey, mode: parseMemoryMode(flags.mode) ?? "readonly" });
11
+ if (!wantsJson(flags)) {
12
+ const files = result.overview?.files ?? [];
13
+ if (files.length === 0)
14
+ console.log("No memory files.");
15
+ else
16
+ for (const file of files)
17
+ console.log(`${file.layer} ${file.path} ${file.lineCount} lines ${file.updatedAt}`);
18
+ return true;
19
+ }
20
+ ok(`memory.${action}`, result);
21
+ return true;
22
+ }
23
+ if (action === "save" || action === "write") {
24
+ const machineId = await resolveMemoryMachineId(client, flags);
25
+ const projectKey = await resolveMemoryProjectKey(client, flags, machineId);
26
+ const text = typeof flags.text === "string"
27
+ ? flags.text
28
+ : typeof flags["text-file"] === "string"
29
+ ? await readPromptTextFile(flags["text-file"])
30
+ : "";
31
+ if (!text.trim())
32
+ throw new CliError("Missing --text or --text-file", "MISSING_ARGUMENT");
33
+ const layer = parseMemoryLayer(flags.layer) ?? "curated";
34
+ const result = await client.memory({
35
+ machineId,
36
+ action: "write",
37
+ projectKey,
38
+ write: {
39
+ projectKey,
40
+ layer,
41
+ text,
42
+ ...(typeof flags.title === "string" ? { title: flags.title } : {}),
43
+ ...(typeof flags.date === "string" ? { date: flags.date } : {}),
44
+ },
45
+ });
46
+ ok("memory.save", result);
47
+ return true;
48
+ }
49
+ if (action === "read") {
50
+ const machineId = await resolveMemoryMachineId(client, flags);
51
+ const projectKey = await resolveMemoryProjectKey(client, flags, machineId);
52
+ const path = typeof flags.path === "string" ? flags.path : requirePositional(positional[0], "path");
53
+ const result = await client.memory({ machineId, action: "read", projectKey, path });
54
+ if (!wantsJson(flags)) {
55
+ console.log(result.content ?? "");
56
+ return true;
57
+ }
58
+ ok("memory.read", result);
59
+ return true;
60
+ }
61
+ if (action === "search") {
62
+ const machineId = await resolveMemoryMachineId(client, flags);
63
+ const projectKey = await resolveMemoryProjectKey(client, flags, machineId);
64
+ const query = requireString(flags, "query");
65
+ const limit = typeof flags.limit === "string" ? Number(flags.limit) : 5;
66
+ if (!Number.isInteger(limit) || limit <= 0)
67
+ throw new CliError("Invalid --limit", "INVALID_ARGUMENT");
68
+ const result = await client.memory({ machineId, action: "search", projectKey, query, limit });
69
+ if (!wantsJson(flags)) {
70
+ const results = result.results ?? [];
71
+ if (results.length === 0)
72
+ console.log("No matching memory.");
73
+ else
74
+ for (const item of results) {
75
+ const hash = item.citation.contentHash ? ` hash=${item.citation.contentHash.slice(0, 10)}` : "";
76
+ const stale = item.citation.stale ? " stale" : "";
77
+ console.log(`${item.path}:${item.citation.startLine}-${item.citation.endLine}${hash}${stale} ${item.snippet}`);
78
+ if (wantsVerbose(flags))
79
+ console.log(` score=${item.score}`);
80
+ }
81
+ return true;
82
+ }
83
+ ok("memory.search", result);
84
+ return true;
85
+ }
86
+ if (action === "promote") {
87
+ const machineId = await resolveMemoryMachineId(client, flags);
88
+ const projectKey = await resolveMemoryProjectKey(client, flags, machineId);
89
+ const source = typeof flags.source === "string" ? parseMemoryCitation(flags.source) : undefined;
90
+ if (!source)
91
+ throw new CliError("Missing --source <path:start-end>", "MISSING_ARGUMENT");
92
+ const targetLayer = parsePromotionLayer(flags.layer) ?? "curated";
93
+ const result = await client.memory({
94
+ machineId,
95
+ action: "promote",
96
+ projectKey,
97
+ promote: {
98
+ projectKey,
99
+ source,
100
+ targetLayer,
101
+ ...(typeof flags.title === "string" ? { title: flags.title } : {}),
102
+ },
103
+ });
104
+ ok("memory.promote", result);
105
+ return true;
106
+ }
107
+ if (action === "reindex" || action === "sync") {
108
+ const machineId = await resolveMemoryMachineId(client, flags);
109
+ const projectKey = await resolveMemoryProjectKey(client, flags, machineId);
110
+ ok(`memory.${action}`, await client.memory({ machineId, action, projectKey, mode: parseMemoryMode(flags.mode) ?? "readonly" }));
111
+ return true;
112
+ }
113
+ return false;
114
+ }
115
+ async function resolveMemoryMachineId(client, flags) {
116
+ if (typeof flags.machine === "string" && flags.machine.length > 0)
117
+ return flags.machine;
118
+ if (typeof flags.session === "string" && flags.session.length > 0) {
119
+ const session = await client.getSession(flags.session);
120
+ if (session)
121
+ return session.machineId;
122
+ }
123
+ const snapshot = await client.snapshot();
124
+ const machine = snapshot.machines.find((item) => item.online) ?? snapshot.machines[0];
125
+ if (!machine)
126
+ throw new CliError("No daemon machine is available; pass --machine <machineId>", "MACHINE_NOT_FOUND");
127
+ return machine.id;
128
+ }
129
+ async function resolveMemoryProjectKey(client, flags, machineId) {
130
+ if (typeof flags.project === "string" && flags.project.trim())
131
+ return flags.project.trim();
132
+ if (typeof flags.session === "string" && flags.session.trim()) {
133
+ const session = await client.getSession(flags.session.trim());
134
+ if (session)
135
+ return `${session.machineId}:${session.cwd}`;
136
+ }
137
+ const cwd = typeof flags.cwd === "string" && flags.cwd.trim() ? flags.cwd.trim() : process.cwd();
138
+ return `${machineId}:${cwd}`;
139
+ }
140
+ function parseMemoryLayer(value) {
141
+ if (typeof value !== "string" || !value.trim())
142
+ return undefined;
143
+ if (value === "user" || value === "curated" || value === "daily")
144
+ return value;
145
+ throw new CliError("Invalid --layer; expected user|curated|daily", "INVALID_ARGUMENT");
146
+ }
147
+ function parseMemoryMode(value) {
148
+ if (typeof value !== "string" || !value.trim())
149
+ return undefined;
150
+ const normalized = value.trim().toLowerCase().replace(/-/g, "");
151
+ if (normalized === "off" || normalized === "readonly" || normalized === "readwrite")
152
+ return normalized;
153
+ throw new CliError("Invalid --mode; expected off|readonly|readwrite|read-only|read-write", "INVALID_ARGUMENT");
154
+ }
155
+ function parsePromotionLayer(value) {
156
+ const layer = parseMemoryLayer(value);
157
+ if (!layer)
158
+ return undefined;
159
+ if (layer === "user" || layer === "curated")
160
+ return layer;
161
+ throw new CliError("Invalid --layer for promotion; expected user|curated", "INVALID_ARGUMENT");
162
+ }
163
+ function parseMemoryCitation(value) {
164
+ const match = value.match(/^(.+):(\d+)-(\d+)(?:@([A-Za-z0-9._-]+))?$/);
165
+ if (!match)
166
+ throw new CliError("Invalid --source; expected path:start-end or path:start-end@contentHash", "INVALID_ARGUMENT");
167
+ const startLine = Number(match[2]);
168
+ const endLine = Number(match[3]);
169
+ if (!Number.isInteger(startLine) || !Number.isInteger(endLine) || startLine < 1 || endLine < startLine) {
170
+ throw new CliError("Invalid --source line range", "INVALID_ARGUMENT");
171
+ }
172
+ return {
173
+ path: match[1],
174
+ startLine,
175
+ endLine,
176
+ ...(match[4] ? { contentHash: match[4] } : {}),
177
+ };
178
+ }
179
+ //# sourceMappingURL=memory.js.map
@@ -1,5 +1,28 @@
1
- import { CliError, ok, relayHealth, requireRelayUrl, wantsJson } from "./lib/index.js";
1
+ import { CliError, auditRelayDb, ok, relayHealth, requireRelayUrl, wantsJson } from "./lib/index.js";
2
2
  export async function handleRelay({ domain, action, flags }) {
3
+ if (domain === "relay" && action === "audit-db") {
4
+ const dbPath = typeof flags.path === "string" ? flags.path : process.env.HAPPY_ELVES_DB;
5
+ if (!dbPath)
6
+ throw new CliError("relay audit-db requires --path <relay.db> or HAPPY_ELVES_DB.", "MISSING_ARGUMENT");
7
+ const result = await auditRelayDb({
8
+ dbPath,
9
+ outputDir: typeof flags.output === "string" ? flags.output : undefined,
10
+ });
11
+ if (wantsJson(flags)) {
12
+ ok("relay.audit-db", result);
13
+ }
14
+ else {
15
+ console.log(`Relay DB audit: ${result.ok ? "ok" : "failed"}`);
16
+ console.log(`source: ${result.sourceDbPath}`);
17
+ console.log(`backup: ${result.backupPath}`);
18
+ console.log(`manifest: ${result.manifestPath}`);
19
+ if (result.unknownTables.length > 0)
20
+ console.log(`unknown tables preserved: ${result.unknownTables.join(", ")}`);
21
+ for (const mismatch of result.backupVerification.mismatches)
22
+ console.log(`mismatch: ${mismatch}`);
23
+ }
24
+ return true;
25
+ }
3
26
  if (domain === "relay" && action === "serve") {
4
27
  const host = typeof flags.host === "string" ? flags.host : "0.0.0.0";
5
28
  const relayPort = typeof flags.port === "string" ? Number(flags.port) : 8787;
@@ -45,7 +68,9 @@ export async function handleRelay({ domain, action, flags }) {
45
68
  }
46
69
  const allOk = checks.every((check) => check.ok);
47
70
  if (wantsJson(flags)) {
48
- ok("relay.doctor", { ok: allOk, relayUrl, checks });
71
+ if (!allOk)
72
+ process.exitCode = 1;
73
+ ok("relay.doctor", { ok: allOk, relayUrl, checks }, {}, allOk);
49
74
  }
50
75
  else {
51
76
  console.log(`Relay doctor: ${allOk ? "ok" : "issues found"}`);
@@ -53,6 +78,8 @@ export async function handleRelay({ domain, action, flags }) {
53
78
  for (const check of checks) {
54
79
  console.log(`${check.ok ? "ok" : "fail"} ${check.name}: ${check.message}`);
55
80
  }
81
+ if (!allOk)
82
+ process.exitCode = 1;
56
83
  }
57
84
  return true;
58
85
  }
@@ -0,0 +1,2 @@
1
+ import type { CommandInput } from "./command.js";
2
+ export declare function handleRelease({ domain, action, positional, flags }: CommandInput): Promise<boolean>;
@@ -0,0 +1,197 @@
1
+ import fs from "node:fs/promises";
2
+ import path from "node:path";
3
+ import { normalizeSessionTags, sessionTagsMatch } from "../../../../packages/shared/dist/index.js";
4
+ import { CliError, ControllerClient, DEFAULT_COMMAND_TIMEOUT_MS, compactText, ok, parseDurationMs, readConfig, releaseProfilesPath, wantsJson, } from "./lib/index.js";
5
+ const defaultReleaseProfile = {
6
+ name: "happy-elves",
7
+ releaseSessionTags: ["Happy Elves", "Release Session"],
8
+ reviewerSessionTags: ["Happy Elves", "Reviewer"],
9
+ dogfoodSessionTags: ["Happy Elves", "Dogfood"],
10
+ };
11
+ export async function handleRelease({ domain, action, positional, flags }) {
12
+ if (domain !== "release")
13
+ return false;
14
+ if (action === "profile") {
15
+ const subaction = positional[0];
16
+ if (subaction === "list") {
17
+ const store = await readReleaseProfileStore();
18
+ printReleaseOutput("release.profile.list", { profiles: store.profiles, defaultProfile: defaultReleaseProfile.name }, flags);
19
+ return true;
20
+ }
21
+ if (subaction === "show") {
22
+ const { profile } = await loadProfile(profileNameFromFlags(flags));
23
+ printReleaseOutput("release.profile.show", { profile }, flags);
24
+ return true;
25
+ }
26
+ if (subaction === "set") {
27
+ const name = positional[1] || profileNameFromFlags(flags);
28
+ const profile = profileFromFlags(name, flags);
29
+ const store = await readReleaseProfileStore();
30
+ const profiles = store.profiles.filter((item) => item.name !== profile.name);
31
+ profiles.push(profile);
32
+ await writeReleaseProfileStore({ version: 1, profiles: profiles.sort((left, right) => left.name.localeCompare(right.name)) });
33
+ printReleaseOutput("release.profile.set", { profile }, flags);
34
+ return true;
35
+ }
36
+ throw new CliError(`Unsupported release profile action: ${subaction ?? ""}`, "USAGE");
37
+ }
38
+ if (action === "resolve") {
39
+ const config = await readConfig(flags);
40
+ const client = new ControllerClient(config);
41
+ const { profile } = await loadProfile(profileNameFromFlags(flags));
42
+ const resolved = await resolveReleaseTargets(client, profile);
43
+ printReleaseOutput("release.resolve", resolved, flags, resolved.errors.length === 0);
44
+ if (resolved.errors.length > 0)
45
+ process.exit(1);
46
+ return true;
47
+ }
48
+ if (action === "notify") {
49
+ const config = await readConfig(flags);
50
+ const client = new ControllerClient(config);
51
+ const { profile } = await loadProfile(profileNameFromFlags(flags));
52
+ const releaseTarget = await resolveRequiredReleaseTarget(client, profile);
53
+ const text = releaseNotifyText(flags);
54
+ const wait = flags.detach !== true && flags["no-wait"] !== true;
55
+ const result = await client.run(releaseTarget.sessionId, text, {
56
+ wait,
57
+ permissionMode: "approve-all",
58
+ memoryMode: "off",
59
+ memoryProjectKey: `${releaseTarget.machineId}:${releaseTarget.cwd}`,
60
+ waitTimeoutMs: parseDurationMs(flags.timeout, DEFAULT_COMMAND_TIMEOUT_MS),
61
+ ackTimeoutMs: parseDurationMs(flags["ack-timeout"], 15_000),
62
+ inactivityTimeoutMs: parseDurationMs(flags["inactivity-timeout"] ?? flags["runtime-timeout"], DEFAULT_COMMAND_TIMEOUT_MS),
63
+ });
64
+ printReleaseOutput("release.notify", {
65
+ profile: profile.name,
66
+ releaseTarget,
67
+ prompt: text,
68
+ promptPreview: compactText(text, 80),
69
+ permissionMode: "approve-all",
70
+ memoryMode: "off",
71
+ wait,
72
+ ...result,
73
+ }, flags);
74
+ return true;
75
+ }
76
+ return false;
77
+ }
78
+ function profileNameFromFlags(flags) {
79
+ return typeof flags.profile === "string" && flags.profile.trim() ? flags.profile.trim() : defaultReleaseProfile.name;
80
+ }
81
+ function releaseNotifyText(flags) {
82
+ const value = typeof flags.text === "string" ? flags.text.trim() : "";
83
+ return value || "发布";
84
+ }
85
+ function tagsFromFlagValue(value) {
86
+ if (typeof value !== "string")
87
+ return [];
88
+ return value.split(",").map((item) => item.trim()).filter(Boolean);
89
+ }
90
+ function profileFromFlags(name, flags) {
91
+ const releaseSessionTags = normalizeSessionTags(tagsFromFlagValue(flags["release-tag"]));
92
+ if (releaseSessionTags.length === 0)
93
+ throw new CliError("Missing --release-tag", "MISSING_ARGUMENT");
94
+ const reviewerSessionTags = normalizeSessionTags(tagsFromFlagValue(flags["reviewer-tag"]));
95
+ const dogfoodSessionTags = normalizeSessionTags(tagsFromFlagValue(flags["dogfood-tag"]));
96
+ return {
97
+ name,
98
+ releaseSessionTags,
99
+ ...(reviewerSessionTags.length > 0 ? { reviewerSessionTags } : {}),
100
+ ...(dogfoodSessionTags.length > 0 ? { dogfoodSessionTags } : {}),
101
+ };
102
+ }
103
+ async function loadProfile(name) {
104
+ const store = await readReleaseProfileStore();
105
+ return { profile: store.profiles.find((profile) => profile.name === name) ?? defaultReleaseProfile, store };
106
+ }
107
+ async function readReleaseProfileStore() {
108
+ try {
109
+ const parsed = JSON.parse(await fs.readFile(releaseProfilesPath, "utf8"));
110
+ const profiles = Array.isArray(parsed.profiles) ? parsed.profiles.filter(isReleaseProfile) : [];
111
+ const hasDefault = profiles.some((profile) => profile.name === defaultReleaseProfile.name);
112
+ return { version: 1, profiles: hasDefault ? profiles : [defaultReleaseProfile, ...profiles] };
113
+ }
114
+ catch (error) {
115
+ if (error.code !== "ENOENT")
116
+ throw error;
117
+ return { version: 1, profiles: [defaultReleaseProfile] };
118
+ }
119
+ }
120
+ function isReleaseProfile(value) {
121
+ if (!value || typeof value !== "object")
122
+ return false;
123
+ const candidate = value;
124
+ return typeof candidate.name === "string" && Array.isArray(candidate.releaseSessionTags);
125
+ }
126
+ async function writeReleaseProfileStore(store) {
127
+ await fs.mkdir(path.dirname(releaseProfilesPath), { recursive: true });
128
+ const tempPath = `${releaseProfilesPath}.${process.pid}.${Date.now()}.tmp`;
129
+ await fs.writeFile(tempPath, `${JSON.stringify(store, null, 2)}\n`, { mode: 0o600 });
130
+ await fs.rename(tempPath, releaseProfilesPath);
131
+ }
132
+ async function resolveReleaseTargets(client, profile) {
133
+ const warnings = [];
134
+ const errors = [];
135
+ const release = await resolveTaggedSession(client, profile.releaseSessionTags);
136
+ if (release.kind === "missing")
137
+ errors.push({ code: "TAG_TARGET_NOT_FOUND", message: `No release session matches tags: ${profile.releaseSessionTags.join(", ")}` });
138
+ if (release.kind === "ambiguous")
139
+ errors.push({ code: "TAG_TARGET_AMBIGUOUS", message: `Multiple release sessions match tags: ${profile.releaseSessionTags.join(", ")}`, candidates: release.candidates });
140
+ const reviewer = profile.reviewerSessionTags?.length ? await resolveTaggedSession(client, profile.reviewerSessionTags) : { kind: "skipped" };
141
+ if (reviewer.kind === "ambiguous")
142
+ errors.push({ code: "TAG_TARGET_AMBIGUOUS", message: `Multiple reviewer sessions match tags: ${profile.reviewerSessionTags?.join(", ")}`, candidates: reviewer.candidates });
143
+ if (reviewer.kind === "missing")
144
+ warnings.push({ code: "TAG_TARGET_NOT_FOUND", message: `No reviewer session matches tags: ${profile.reviewerSessionTags?.join(", ")}` });
145
+ const dogfood = profile.dogfoodSessionTags?.length ? await resolveTaggedSession(client, profile.dogfoodSessionTags) : { kind: "skipped" };
146
+ if (dogfood.kind === "ambiguous")
147
+ errors.push({ code: "TAG_TARGET_AMBIGUOUS", message: `Multiple dogfood sessions match tags: ${profile.dogfoodSessionTags?.join(", ")}`, candidates: dogfood.candidates });
148
+ if (dogfood.kind === "missing")
149
+ warnings.push({ code: "TAG_TARGET_NOT_FOUND", message: `No dogfood session matches tags: ${profile.dogfoodSessionTags?.join(", ")}` });
150
+ return {
151
+ profile,
152
+ ...(release.kind === "found" ? { releaseTarget: release.session } : {}),
153
+ ...(reviewer.kind === "found" ? { reviewerTarget: reviewer.session } : {}),
154
+ ...(dogfood.kind === "found" ? { dogfoodTarget: dogfood.session } : {}),
155
+ warnings,
156
+ errors,
157
+ };
158
+ }
159
+ async function resolveRequiredReleaseTarget(client, profile) {
160
+ const resolved = await resolveReleaseTargets(client, profile);
161
+ if (resolved.errors.length > 0 || !resolved.releaseTarget) {
162
+ const error = resolved.errors[0];
163
+ throw new CliError(error?.message ?? "Release target not found", error?.code ?? "TAG_TARGET_NOT_FOUND");
164
+ }
165
+ return resolved.releaseTarget;
166
+ }
167
+ async function resolveTaggedSession(client, tags) {
168
+ const sessions = await client.listSessions({ tags });
169
+ const candidates = [];
170
+ for (const session of sessions.filter((session) => session.status !== "closed")) {
171
+ const metadata = await client.decodeSessionMetadata(session);
172
+ const sessionTags = normalizeSessionTags(metadata.tags);
173
+ if (!sessionTagsMatch(sessionTags, tags))
174
+ continue;
175
+ candidates.push({
176
+ sessionId: session.id,
177
+ machineId: session.machineId,
178
+ agent: metadata.agent ?? session.agent,
179
+ cwd: metadata.cwd ?? session.cwd,
180
+ name: metadata.name ?? session.name,
181
+ tags: sessionTags,
182
+ });
183
+ }
184
+ if (candidates.length === 0)
185
+ return { kind: "missing" };
186
+ if (candidates.length > 1)
187
+ return { kind: "ambiguous", candidates };
188
+ return { kind: "found", session: candidates[0] };
189
+ }
190
+ function printReleaseOutput(type, data, flags, success = true) {
191
+ if (wantsJson(flags)) {
192
+ ok(type, data, {}, success);
193
+ return;
194
+ }
195
+ console.log(JSON.stringify(data, null, 2));
196
+ }
197
+ //# sourceMappingURL=release.js.map