@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
@@ -1,4 +1,5 @@
1
- import { CliError, ControllerClient, compactSessionListItem, compactText, conciseSessionSummary, deriveOrchestration, listWorkspaceHistoricalSessions, ok, parsePermissionMode, readConfig, readStoredTurnOutput, requirePositional, requireString, showSession, structuredSessionProjection, summarizeTurns, wantsJson, wantsVerbose } from "./lib/index.js";
1
+ import { normalizeSessionTags, sessionTagKeys } from "../../../../packages/shared/dist/index.js";
2
+ import { CliError, ControllerClient, compareSessionEventLogicalOrder, compactSessionListItem, compactText, conciseSessionSummary, deriveOrchestration, listWorkspaceHistoricalSessions, ok, parsePermissionMode, readConfig, readStoredTurnOutput, requirePositional, requireString, showSession, structuredSessionProjection, summarizeTurns, wantsJson, wantsVerbose } from "./lib/index.js";
2
3
  function formatTurnTimestamp(value) {
3
4
  return value === undefined ? "-" : new Date(value).toISOString();
4
5
  }
@@ -26,6 +27,14 @@ function parsePositiveIntFlag(flags, name) {
26
27
  }
27
28
  return parsed;
28
29
  }
30
+ function tagsFromFlagValue(value) {
31
+ if (typeof value !== "string")
32
+ return [];
33
+ return value.split(",").map((item) => item.trim()).filter(Boolean);
34
+ }
35
+ function tagsFromFlags(flags, names = ["tag", "tags"]) {
36
+ return normalizeSessionTags(names.flatMap((name) => tagsFromFlagValue(flags[name])));
37
+ }
29
38
  function selectWindow(items, flags, defaultLimit) {
30
39
  const limit = parsePositiveIntFlag(flags, "limit");
31
40
  const tail = parsePositiveIntFlag(flags, "tail");
@@ -53,8 +62,298 @@ function compactTurnRef(turn) {
53
62
  status: turn.status,
54
63
  ...(turn.prompt ? { promptPreview: compactText(turn.prompt, 180) } : {}),
55
64
  time: turn.completedAt ?? turn.updatedAt,
65
+ ...(turn.turnSeq !== undefined ? { turnSeq: turn.turnSeq } : {}),
66
+ };
67
+ }
68
+ function countBy(values) {
69
+ const counts = {};
70
+ for (const value of values)
71
+ counts[value] = (counts[value] ?? 0) + 1;
72
+ return counts;
73
+ }
74
+ function messagePrefix(messageId) {
75
+ if (!messageId)
76
+ return "none";
77
+ const index = messageId.indexOf("_");
78
+ return index > 0 ? messageId.slice(0, index) : "other";
79
+ }
80
+ function eventPayloadText(event) {
81
+ const payload = event.decoded;
82
+ if (!payload)
83
+ return event.decryptError ?? "";
84
+ if (payload.type === "user_prompt")
85
+ return payload.text;
86
+ if (payload.type === "text_delta")
87
+ return payload.text;
88
+ if (payload.type === "tool_call")
89
+ return `${payload.title ?? "tool"} ${payload.status ?? ""} ${payload.text ?? ""}`;
90
+ if (payload.type === "status" || payload.type === "control")
91
+ return payload.text;
92
+ if (payload.type === "done")
93
+ return payload.error ?? payload.stopReason ?? payload.status;
94
+ return "";
95
+ }
96
+ function isVisibleTranscriptPayloadEvent(event) {
97
+ const payload = event.decoded;
98
+ if (!payload)
99
+ return false;
100
+ return payload.type === "user_prompt" ||
101
+ (payload.type === "text_delta" && payload.stream !== "thought" && payload.text.trim().length > 0) ||
102
+ payload.type === "tool_call";
103
+ }
104
+ function compactEventDiagnostic(event) {
105
+ const text = compactText(eventPayloadText(event), 120);
106
+ return {
107
+ id: event.id,
108
+ ...(event.messageId ? { messageId: event.messageId } : {}),
109
+ payloadType: event.decoded?.type ?? (event.decryptError ? "decrypt_error" : "encrypted"),
110
+ seq: event.seq,
111
+ ...(text ? { textPreview: text } : {}),
112
+ turnId: event.turnId,
113
+ ...(event.turnSeq !== undefined ? { turnSeq: event.turnSeq } : {}),
114
+ };
115
+ }
116
+ function repairHeadInputForLatestCompletedEvent(events) {
117
+ const doneEvent = [...events]
118
+ .sort(compareSessionEventLogicalOrder)
119
+ .reverse()
120
+ .find((event) => event.decoded?.type === "done" && event.decoded.status === "completed");
121
+ const done = doneEvent?.decoded;
122
+ if (!doneEvent || done?.type !== "done") {
123
+ throw new CliError("No completed done event is available for head repair", "SESSION_HEAD_REPAIR_UNAVAILABLE");
124
+ }
125
+ if (!doneEvent.messageId) {
126
+ throw new CliError("Latest completed done event has no messageId basis", "SESSION_HEAD_REPAIR_UNAVAILABLE");
127
+ }
128
+ const turnSeq = doneEvent.turnSeq;
129
+ if (turnSeq === undefined) {
130
+ throw new CliError("Latest completed done event has no turnSeq basis", "SESSION_HEAD_REPAIR_UNAVAILABLE");
131
+ }
132
+ const currentHead = done.currentHead ?? done.lastTurnId ?? doneEvent.turnId;
133
+ const lastTurnId = done.lastTurnId ?? done.currentHead ?? doneEvent.turnId;
134
+ return {
135
+ currentHead,
136
+ lastTurnId,
137
+ status: "completed",
138
+ basis: {
139
+ turnId: doneEvent.turnId,
140
+ eventMessageId: doneEvent.messageId,
141
+ turnSeq,
142
+ ...(doneEvent.occurredAt === undefined ? {} : { occurredAt: doneEvent.occurredAt }),
143
+ },
144
+ };
145
+ }
146
+ function eventCollectionDiagnostics(events) {
147
+ return {
148
+ decryptErrors: events.filter((event) => event.decryptError).length,
149
+ first: events.slice(0, 5).map(compactEventDiagnostic),
150
+ last: events.slice(-5).map(compactEventDiagnostic),
151
+ messagePrefixes: countBy(events.map((event) => messagePrefix(event.messageId))),
152
+ payloadTypes: countBy(events.map((event) => event.decoded?.type ?? (event.decryptError ? "decrypt_error" : "encrypted"))),
153
+ total: events.length,
154
+ visiblePayloads: events.filter(isVisibleTranscriptPayloadEvent).length,
155
+ };
156
+ }
157
+ function headMatchesTurn(session, turn) {
158
+ if (!turn)
159
+ return false;
160
+ const turnHeads = new Set([
161
+ turn.checkpointId,
162
+ turn.runtimeTurnId,
163
+ turn.turnId,
164
+ ].filter((value) => typeof value === "string" && value.length > 0));
165
+ if (session.currentHead?.startsWith("event:")) {
166
+ const eventId = Number(/^event:(\d+)$/.exec(session.currentHead)?.[1]);
167
+ if (Number.isFinite(eventId) && eventId >= turn.firstEventId && eventId <= turn.lastEventId)
168
+ return true;
169
+ }
170
+ if (session.headBasis?.eventId !== undefined && session.headBasis.eventId >= turn.firstEventId && session.headBasis.eventId <= turn.lastEventId) {
171
+ return true;
172
+ }
173
+ return (session.currentHead !== undefined && turnHeads.has(session.currentHead)) ||
174
+ (session.lastTurnId !== undefined && turnHeads.has(session.lastTurnId));
175
+ }
176
+ function staleHeadSuspected(session, latestCompletedTurn) {
177
+ if (!latestCompletedTurn)
178
+ return false;
179
+ if (headMatchesTurn(session, latestCompletedTurn))
180
+ return false;
181
+ const basisTime = session.headBasis?.logicalTime;
182
+ const latestTime = latestCompletedTurn.completedAt ?? latestCompletedTurn.updatedAt;
183
+ if (basisTime !== undefined) {
184
+ if (latestTime !== basisTime)
185
+ return latestTime > basisTime;
186
+ if (session.headBasis?.turnSeq !== undefined && latestCompletedTurn.turnSeq !== undefined) {
187
+ return latestCompletedTurn.turnSeq > session.headBasis.turnSeq;
188
+ }
189
+ }
190
+ return Boolean(session.currentHead || session.lastTurnId);
191
+ }
192
+ function stringMetadata(metadata, key) {
193
+ const value = metadata[key];
194
+ return typeof value === "string" ? value : undefined;
195
+ }
196
+ function numberMetadata(metadata, key) {
197
+ const value = metadata[key];
198
+ return typeof value === "number" && Number.isFinite(value) ? value : undefined;
199
+ }
200
+ function isRecord(value) {
201
+ return typeof value === "object" && value !== null && !Array.isArray(value);
202
+ }
203
+ function diagnosticSessionMetadata(metadata) {
204
+ const runtime = isRecord(metadata.runtime) ? metadata.runtime : {};
205
+ return {
206
+ agent: stringMetadata(metadata, "agent"),
207
+ cwd: stringMetadata(metadata, "cwd"),
208
+ name: stringMetadata(metadata, "name"),
209
+ providerName: stringMetadata(metadata, "providerName"),
210
+ importedFromRuntimeSessionId: stringMetadata(metadata, "importedFromRuntimeSessionId"),
211
+ runtime: {
212
+ backend: stringMetadata(runtime, "backend"),
213
+ runtimeSessionName: stringMetadata(runtime, "runtimeSessionName"),
214
+ acpxRecordId: stringMetadata(runtime, "acpxRecordId"),
215
+ backendSessionId: stringMetadata(runtime, "backendSessionId"),
216
+ agentSessionId: stringMetadata(runtime, "agentSessionId"),
217
+ externalProviderId: stringMetadata(runtime, "externalProviderId"),
218
+ externalHandleSessionId: isRecord(runtime.externalHandle) ? stringMetadata(runtime.externalHandle, "sessionId") : undefined,
219
+ },
220
+ historicalBackfillStatus: stringMetadata(metadata, "historicalBackfillStatus") ?? stringMetadata(metadata, "historicalBackfill"),
221
+ historicalBackfillCursor: numberMetadata(metadata, "historicalBackfillCursor"),
222
+ historicalBackfillTotalEvents: numberMetadata(metadata, "historicalBackfillTotalEvents"),
223
+ availableHistoricalEvents: numberMetadata(metadata, "availableHistoricalEvents"),
224
+ backfilledEvents: numberMetadata(metadata, "backfilledEvents"),
225
+ historicalOlderBackfilledEvents: numberMetadata(metadata, "historicalOlderBackfilledEvents"),
226
+ historicalTailRepairedEvents: numberMetadata(metadata, "historicalTailRepairedEvents"),
227
+ truncatedHistoricalBackfill: metadata.truncatedHistoricalBackfill === true,
228
+ importRequestId: stringMetadata(metadata, "importRequestId"),
229
+ currentHead: stringMetadata(metadata, "currentHead"),
230
+ emptyRuntimeSession: metadata.emptyRuntimeSession === true,
231
+ };
232
+ }
233
+ function addRuntimeSessionId(ids, value) {
234
+ if (typeof value === "string" && value.trim())
235
+ ids.add(value.trim());
236
+ }
237
+ function metadataRuntimeSessionIds(metadata) {
238
+ const ids = new Set();
239
+ addRuntimeSessionId(ids, stringMetadata(metadata, "importedFromRuntimeSessionId"));
240
+ const runtime = isRecord(metadata.runtime) ? metadata.runtime : {};
241
+ addRuntimeSessionId(ids, runtime.backendSessionId);
242
+ addRuntimeSessionId(ids, runtime.agentSessionId);
243
+ addRuntimeSessionId(ids, runtime.acpxRecordId);
244
+ if (isRecord(runtime.externalHandle))
245
+ addRuntimeSessionId(ids, runtime.externalHandle.sessionId);
246
+ return ids;
247
+ }
248
+ function normalizedMatchValue(value) {
249
+ return typeof value === "string" && value.trim() ? value.trim().toLocaleLowerCase() : undefined;
250
+ }
251
+ function runtimeBindingCandidates(session, metadata, historicalSessions) {
252
+ const knownRuntimeIds = metadataRuntimeSessionIds(metadata);
253
+ const expectedAgent = stringMetadata(metadata, "agent") ?? session.agent;
254
+ const expectedCwd = stringMetadata(metadata, "cwd") ?? session.cwd;
255
+ const names = new Set([
256
+ normalizedMatchValue(stringMetadata(metadata, "name")),
257
+ normalizedMatchValue(stringMetadata(metadata, "providerName")),
258
+ normalizedMatchValue(session.name),
259
+ ].filter((value) => Boolean(value)));
260
+ const summaries = new Set([
261
+ normalizedMatchValue(stringMetadata(metadata, "importedSummary")),
262
+ normalizedMatchValue(session.name),
263
+ ].filter((value) => Boolean(value)));
264
+ return historicalSessions
265
+ .filter((historical) => historical.agent === expectedAgent &&
266
+ historical.cwd === expectedCwd &&
267
+ !knownRuntimeIds.has(historical.runtimeSessionId))
268
+ .map((historical) => {
269
+ const reasons = [];
270
+ let score = 0;
271
+ const historicalName = normalizedMatchValue(historical.name ?? historical.runtimeSessionName);
272
+ const historicalSummary = normalizedMatchValue(historical.summary);
273
+ if (historicalName && names.has(historicalName)) {
274
+ score += 100;
275
+ reasons.push("name");
276
+ }
277
+ if (historicalSummary && summaries.has(historicalSummary)) {
278
+ score += 30;
279
+ reasons.push("summary");
280
+ }
281
+ if (historical.loadedSessionId) {
282
+ score -= 20;
283
+ reasons.push("already-loaded");
284
+ }
285
+ if (score <= 0)
286
+ return undefined;
287
+ return {
288
+ runtimeSessionId: historical.runtimeSessionId,
289
+ agent: historical.agent,
290
+ cwd: historical.cwd,
291
+ name: historical.name ?? historical.runtimeSessionName,
292
+ summary: historical.summary,
293
+ updatedAt: historical.updatedAt,
294
+ score,
295
+ reasons,
296
+ ...(historical.runtimeState === "archived" ? { runtimeState: "archived" } : {}),
297
+ };
298
+ })
299
+ .filter((candidate) => Boolean(candidate))
300
+ .sort((left, right) => right.score - left.score || right.updatedAt - left.updatedAt || left.runtimeSessionId.localeCompare(right.runtimeSessionId));
301
+ }
302
+ function shouldSearchRuntimeBindingCandidates(latestEvents, metadata) {
303
+ const available = numberMetadata(metadata, "availableHistoricalEvents");
304
+ const emitted = numberMetadata(metadata, "backfilledEvents");
305
+ return latestEvents.length === 0 &&
306
+ (available === undefined || available === 0) &&
307
+ (emitted === undefined || emitted === 0);
308
+ }
309
+ function runtimeBindingSuspected(candidates) {
310
+ return candidates.some((candidate) => candidate.reasons.includes("name") && !candidate.reasons.includes("already-loaded"));
311
+ }
312
+ async function findRuntimeBindingCandidates(client, session, metadata, flags) {
313
+ const limit = parsePositiveIntFlag(flags, "runtime-limit") ?? 500;
314
+ const result = await listWorkspaceHistoricalSessions(client, {
315
+ machineId: session.machineId,
316
+ cwd: stringMetadata(metadata, "cwd") ?? session.cwd,
317
+ agent: stringMetadata(metadata, "agent") ?? session.agent,
318
+ includeArchived: true,
319
+ limit,
320
+ });
321
+ return {
322
+ candidates: runtimeBindingCandidates(session, metadata, result.sessions).slice(0, 8),
323
+ searched: true,
324
+ limit,
56
325
  };
57
326
  }
327
+ async function resolveRuntimeBindingRepairTarget(client, session, metadata, flags) {
328
+ const runtimeSessionId = typeof flags["runtime-session"] === "string" ? flags["runtime-session"].trim() : undefined;
329
+ const limit = parsePositiveIntFlag(flags, "runtime-limit") ?? 500;
330
+ const result = await listWorkspaceHistoricalSessions(client, {
331
+ machineId: session.machineId,
332
+ cwd: stringMetadata(metadata, "cwd") ?? session.cwd,
333
+ agent: stringMetadata(metadata, "agent") ?? session.agent,
334
+ includeArchived: true,
335
+ limit,
336
+ });
337
+ const candidateDiagnostics = runtimeBindingCandidates(session, metadata, result.sessions);
338
+ if (runtimeSessionId) {
339
+ const explicit = result.sessions.find((item) => item.runtimeSessionId === runtimeSessionId);
340
+ if (!explicit)
341
+ throw new CliError(`Runtime session not found in the first ${limit} historical rows: ${runtimeSessionId}`, "RUNTIME_SESSION_NOT_FOUND");
342
+ return { candidate: explicit, candidates: candidateDiagnostics.slice(0, 8) };
343
+ }
344
+ const usableCandidates = candidateDiagnostics.filter((candidate) => !candidate.reasons.includes("already-loaded"));
345
+ if (usableCandidates.length === 0) {
346
+ throw new CliError("No unambiguous runtime binding repair candidate found. Re-run with --runtime-session <id>.", "SESSION_BINDING_REPAIR_UNAVAILABLE");
347
+ }
348
+ const [first, second] = usableCandidates;
349
+ if (second && second.score === first.score) {
350
+ throw new CliError("Multiple runtime binding repair candidates found. Re-run with --runtime-session <id>.", "SESSION_BINDING_REPAIR_AMBIGUOUS");
351
+ }
352
+ const selected = result.sessions.find((item) => item.runtimeSessionId === first.runtimeSessionId);
353
+ if (!selected)
354
+ throw new CliError("Selected repair candidate disappeared from runtime history", "SESSION_BINDING_REPAIR_UNAVAILABLE");
355
+ return { candidate: selected, candidates: candidateDiagnostics.slice(0, 8) };
356
+ }
58
357
  export async function handleSession({ domain, action, positional, flags }) {
59
358
  if (domain !== "session")
60
359
  return false;
@@ -66,8 +365,21 @@ export async function handleSession({ domain, action, positional, flags }) {
66
365
  const requestedRuntimeName = typeof flags.name === "string" ? flags.name : undefined;
67
366
  const name = "main";
68
367
  const permissionMode = parsePermissionMode(flags["permission-mode"] ?? flags.permission);
368
+ const model = typeof flags.model === "string" && flags.model.trim() ? flags.model.trim() : undefined;
369
+ const tags = tagsFromFlags(flags);
69
370
  const client = await makeClient();
70
- const result = await client.createSession({ machineId, agent, cwd, name, runtimeName: requestedRuntimeName, permissionMode });
371
+ const result = await client.createSession({
372
+ machineId,
373
+ agent,
374
+ cwd,
375
+ name,
376
+ runtimeName: requestedRuntimeName,
377
+ permissionMode,
378
+ model,
379
+ ...(tags.length > 0 ? { tags } : {}),
380
+ ...(flags.hidden === true ? { hiddenFromWorkspace: true } : {}),
381
+ ...(typeof flags.source === "string" ? { source: flags.source } : {}),
382
+ });
71
383
  const session = result.sessionId ? await client.getSession(result.sessionId) : undefined;
72
384
  const projectedSession = session
73
385
  ? wantsVerbose(flags)
@@ -89,8 +401,13 @@ export async function handleSession({ domain, action, positional, flags }) {
89
401
  agent: typeof flags.agent === "string" ? flags.agent : undefined,
90
402
  cwd: cwdFilter,
91
403
  name: typeof flags.name === "string" ? flags.name : undefined,
404
+ tags: tagsFromFlags(flags),
92
405
  });
93
- const visibleSessions = flags.all === true ? allSessions : allSessions.filter((session) => session.status !== "closed");
406
+ const visibleSessions = flags.all === true
407
+ ? allSessions
408
+ : (await Promise.all(allSessions.map(async (session) => ({ session, metadata: await client.decodeSessionMetadata(session) }))))
409
+ .filter(({ session, metadata }) => session.status !== "closed" && metadata.hiddenFromWorkspace !== true)
410
+ .map(({ session }) => session);
94
411
  const { items: sessions, page } = selectWindow(visibleSessions, flags, 20);
95
412
  if (wantsJson(flags) || wantsVerbose(flags)) {
96
413
  const machinesById = new Map();
@@ -126,6 +443,37 @@ export async function handleSession({ domain, action, positional, flags }) {
126
443
  }
127
444
  return true;
128
445
  }
446
+ if (action === "tag") {
447
+ const subaction = requirePositional(positional[0], "tag action");
448
+ const sessionId = requirePositional(positional[1], "sessionId");
449
+ const client = await makeClient();
450
+ const session = await client.getSession(sessionId);
451
+ if (!session)
452
+ throw new CliError("Session not found", "SESSION_NOT_FOUND");
453
+ const metadata = await client.decodeSessionMetadata(session);
454
+ const currentTags = normalizeSessionTags(metadata.tags);
455
+ if (subaction === "list") {
456
+ ok("session.tag.list", { sessionId, tags: currentTags, tagKeys: sessionTagKeys(currentTags) }, { sessionId });
457
+ return true;
458
+ }
459
+ const requested = tagsFromFlags(flags);
460
+ if (requested.length === 0)
461
+ throw new CliError("Missing --tag", "MISSING_ARGUMENT");
462
+ if (subaction === "add") {
463
+ const tags = normalizeSessionTags([...currentTags, ...requested]);
464
+ const result = await client.setSessionTags(sessionId, tags);
465
+ ok("session.tag.add", { sessionId, tags: result.tags, tagKeys: sessionTagKeys(result.tags) }, { sessionId });
466
+ return true;
467
+ }
468
+ if (subaction === "remove") {
469
+ const removeKeys = new Set(sessionTagKeys(requested));
470
+ const tags = currentTags.filter((tag) => !removeKeys.has(sessionTagKeys([tag])[0]));
471
+ const result = await client.setSessionTags(sessionId, tags);
472
+ ok("session.tag.remove", { sessionId, tags: result.tags, tagKeys: sessionTagKeys(result.tags) }, { sessionId });
473
+ return true;
474
+ }
475
+ throw new CliError(`Unsupported session tag action: ${subaction}`, "USAGE");
476
+ }
129
477
  if (action === "status") {
130
478
  const sessionId = requirePositional(positional[0], "sessionId");
131
479
  const client = await makeClient();
@@ -140,7 +488,7 @@ export async function handleSession({ domain, action, positional, flags }) {
140
488
  const latestCompletedTurn = turns.find((turn) => turn.status === "completed");
141
489
  const latestTerminalTurn = turns.find((turn) => turn.status !== "running");
142
490
  const orchestration = deriveOrchestration(session, recentEvents);
143
- const latestOutput = await readStoredTurnOutput(session.id).catch(() => undefined);
491
+ const latestOutput = await readStoredTurnOutput(session.id, latestCompletedTurn?.turnId).catch(async () => await readStoredTurnOutput(session.id).catch(() => undefined));
144
492
  const terminalOutput = latestCompletedTurn?.output || latestCompletedTurn?.terminalText || latestTerminalTurn?.output || latestTerminalTurn?.terminalText || undefined;
145
493
  const data = {
146
494
  state: orchestration.state,
@@ -192,6 +540,170 @@ export async function handleSession({ domain, action, positional, flags }) {
192
540
  }
193
541
  return true;
194
542
  }
543
+ if (action === "diagnose") {
544
+ const sessionId = requirePositional(positional[0], "sessionId");
545
+ const limit = parsePositiveIntFlag(flags, "limit") ?? 200;
546
+ const client = await makeClient();
547
+ const snapshot = await client.snapshot();
548
+ const initialSession = snapshot.sessions.find((item) => item.id === sessionId);
549
+ if (!initialSession)
550
+ throw new CliError("Session not found", "SESSION_NOT_FOUND");
551
+ let session = initialSession;
552
+ const machine = snapshot.machines.find((item) => item.id === session.machineId);
553
+ const metadata = await client.decodeSessionMetadata(session);
554
+ const latestPage = await client.collectPage(session.id, { limit });
555
+ const turns = summarizeTurns(latestPage.events);
556
+ const latestCompletedTurn = turns.find((turn) => turn.status === "completed");
557
+ const latestTerminalTurn = turns.find((turn) => turn.status !== "running");
558
+ const runtimeBinding = shouldSearchRuntimeBindingCandidates(latestPage.events, metadata)
559
+ ? await findRuntimeBindingCandidates(client, session, metadata, flags)
560
+ : { candidates: [], searched: false, limit: parsePositiveIntFlag(flags, "runtime-limit") ?? 500 };
561
+ const repair = flags["repair-head"] === true
562
+ ? await client.repairSessionHead(session.id, repairHeadInputForLatestCompletedEvent(latestPage.events))
563
+ : undefined;
564
+ if (repair)
565
+ session = repair.session;
566
+ const data = {
567
+ generatedAt: new Date().toISOString(),
568
+ session: {
569
+ id: session.id,
570
+ machineId: session.machineId,
571
+ agent: session.agent,
572
+ status: session.status,
573
+ name: session.name,
574
+ cwd: session.cwd,
575
+ historyModel: session.historyModel ?? "append-only",
576
+ currentHead: session.currentHead,
577
+ lastTurnId: session.lastTurnId,
578
+ headBasis: session.headBasis,
579
+ sourceSessionId: session.sourceSessionId,
580
+ sourceCheckpointId: session.sourceCheckpointId,
581
+ updatedAt: session.updatedAt,
582
+ capabilities: session.capabilities,
583
+ },
584
+ machine: machine ? {
585
+ id: machine.id,
586
+ name: machine.name,
587
+ online: machine.online,
588
+ agents: machine.capabilities.agents.map((agent) => ({
589
+ id: agent.id,
590
+ historyModel: agent.historyModel,
591
+ sessionPrimitives: agent.sessionPrimitives,
592
+ })),
593
+ } : undefined,
594
+ metadata: diagnosticSessionMetadata(metadata),
595
+ latestPage: {
596
+ limit,
597
+ hasMoreBefore: latestPage.hasMoreBefore,
598
+ newestCursor: latestPage.newestCursor,
599
+ newestEventId: latestPage.newestEventId,
600
+ oldestCursor: latestPage.oldestCursor,
601
+ oldestEventId: latestPage.oldestEventId,
602
+ events: eventCollectionDiagnostics(latestPage.events),
603
+ },
604
+ turns: {
605
+ count: turns.length,
606
+ latestCompletedTurn: compactTurnRef(latestCompletedTurn),
607
+ latestTerminalTurn: compactTurnRef(latestTerminalTurn),
608
+ first: turns.slice(0, 4).map(compactTurnRef),
609
+ last: turns.slice(-4).map(compactTurnRef),
610
+ },
611
+ diagnosis: {
612
+ importedRuntimeSessionId: stringMetadata(metadata, "importedFromRuntimeSessionId"),
613
+ latestPageEmpty: latestPage.events.length === 0,
614
+ latestPageHasVisibleTranscript: latestPage.events.some(isVisibleTranscriptPayloadEvent),
615
+ metadataReportsEmptyRuntimeSession: metadata.emptyRuntimeSession === true,
616
+ backfillAvailableEvents: numberMetadata(metadata, "availableHistoricalEvents"),
617
+ backfillEmittedEvents: numberMetadata(metadata, "backfilledEvents"),
618
+ backfillStatus: stringMetadata(metadata, "historicalBackfillStatus") ?? stringMetadata(metadata, "historicalBackfill"),
619
+ wrongRuntimeBindingSuspected: runtimeBindingSuspected(runtimeBinding.candidates),
620
+ runtimeBindingCandidateCount: runtimeBinding.candidates.length,
621
+ staleHeadSuspected: staleHeadSuspected(session, latestCompletedTurn),
622
+ headMatchesLatestCompletedTurn: headMatchesTurn(session, latestCompletedTurn),
623
+ },
624
+ runtimeBinding: {
625
+ searched: runtimeBinding.searched,
626
+ searchLimit: runtimeBinding.limit,
627
+ suspected: runtimeBindingSuspected(runtimeBinding.candidates),
628
+ candidates: runtimeBinding.candidates,
629
+ repairCommand: runtimeBinding.candidates[0]
630
+ ? `happy-elves session repair-binding ${session.id} --runtime-session ${runtimeBinding.candidates[0].runtimeSessionId} --json`
631
+ : undefined,
632
+ },
633
+ repair: repair ? {
634
+ advanced: repair.advanced,
635
+ settled: repair.settled,
636
+ basis: repair.basis,
637
+ status: repair.session.status,
638
+ currentHead: repair.session.currentHead,
639
+ lastTurnId: repair.session.lastTurnId,
640
+ reason: repair.reason,
641
+ } : undefined,
642
+ };
643
+ if (wantsJson(flags) || wantsVerbose(flags)) {
644
+ ok("session.diagnose", data, { machineId: session.machineId, sessionId: session.id });
645
+ }
646
+ else {
647
+ console.log(`Session: ${session.id} ${session.status} ${session.agent}`);
648
+ console.log(`Machine: ${session.machineId}${machine ? ` ${machine.online ? "online" : "offline"}` : ""}`);
649
+ const runtime = isRecord(metadata.runtime) ? metadata.runtime : {};
650
+ console.log(`Runtime: ${stringMetadata(metadata, "importedFromRuntimeSessionId") ?? stringMetadata(runtime, "backendSessionId") ?? stringMetadata(runtime, "agentSessionId") ?? "-"}`);
651
+ console.log(`Backfill: ${data.diagnosis.backfillStatus ?? "-"} available=${data.diagnosis.backfillAvailableEvents ?? "-"} emitted=${data.diagnosis.backfillEmittedEvents ?? "-"}`);
652
+ console.log(`Head: ${session.currentHead ?? "-"} lastTurn=${session.lastTurnId ?? "-"} stale=${data.diagnosis.staleHeadSuspected ? "yes" : "no"}`);
653
+ console.log(`Latest page: ${latestPage.events.length} events, visible=${latestPage.events.filter(isVisibleTranscriptPayloadEvent).length}, hasMore=${latestPage.hasMoreBefore}`);
654
+ if (data.runtimeBinding.suspected && data.runtimeBinding.candidates[0]) {
655
+ console.log(`Runtime binding: suspected wrong binding; candidate=${data.runtimeBinding.candidates[0].runtimeSessionId}`);
656
+ console.log(`Repair: ${data.runtimeBinding.repairCommand}`);
657
+ }
658
+ }
659
+ return true;
660
+ }
661
+ if (action === "repair-binding") {
662
+ const sessionId = requirePositional(positional[0], "sessionId");
663
+ const client = await makeClient();
664
+ const session = await client.getSession(sessionId);
665
+ if (!session)
666
+ throw new CliError("Session not found", "SESSION_NOT_FOUND");
667
+ if (session.status === "running")
668
+ throw new CliError("Cannot repair binding for a running session", "SESSION_BINDING_REPAIR_RUNNING");
669
+ const metadata = await client.decodeSessionMetadata(session);
670
+ const { candidate, candidates } = await resolveRuntimeBindingRepairTarget(client, session, metadata, flags);
671
+ const name = typeof flags.name === "string" && flags.name.trim()
672
+ ? flags.name.trim()
673
+ : stringMetadata(metadata, "name") ?? session.name ?? candidate.name ?? candidate.summary ?? candidate.runtimeSessionId;
674
+ const imported = await client.importHistoricalSession({
675
+ machineId: session.machineId,
676
+ agent: candidate.agent,
677
+ cwd: candidate.cwd,
678
+ runtimeSessionId: candidate.runtimeSessionId,
679
+ name,
680
+ summary: candidate.summary,
681
+ runtimeState: candidate.runtimeState,
682
+ ...(candidate.name ? { providerName: candidate.name } : {}),
683
+ });
684
+ const closeSource = flags["keep-source"] !== true;
685
+ let sourceClosed = false;
686
+ if (closeSource) {
687
+ await client.close(session.id, `replaced by runtime session ${candidate.runtimeSessionId}`);
688
+ sourceClosed = true;
689
+ }
690
+ ok("session.repair-binding", {
691
+ sourceSessionId: session.id,
692
+ sessionId: imported.sessionId,
693
+ runtimeSessionId: candidate.runtimeSessionId,
694
+ mode: imported.mode === "existing" ? "existing" : "created",
695
+ sourceClosed,
696
+ candidate: {
697
+ runtimeSessionId: candidate.runtimeSessionId,
698
+ name: candidate.name ?? candidate.runtimeSessionName,
699
+ summary: candidate.summary,
700
+ updatedAt: candidate.updatedAt,
701
+ ...(candidate.runtimeState === "archived" ? { runtimeState: "archived" } : {}),
702
+ },
703
+ candidates,
704
+ }, { requestId: imported.requestId, machineId: session.machineId, sessionId: imported.sessionId });
705
+ return true;
706
+ }
195
707
  if (action === "history") {
196
708
  const machineId = requireString(flags, "machine");
197
709
  const limit = parsePositiveIntFlag(flags, "limit") ?? 20;
@@ -280,7 +792,7 @@ export async function handleSession({ domain, action, positional, flags }) {
280
792
  ok("session.continue", {
281
793
  sessionId: continued.sessionId,
282
794
  runtimeSessionId,
283
- mode: "created",
795
+ mode: continued.mode === "existing" ? "existing" : "created",
284
796
  ...(historical.runtimeState === "archived" ? { runtimeState: "archived" } : {}),
285
797
  }, { requestId: continued.requestId, machineId, sessionId: continued.sessionId });
286
798
  return true;