agent-log-viewer 1.0.2 → 1.0.3

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 (551) hide show
  1. package/README.md +18 -0
  2. package/dist/mcp-server.mjs +2458 -392
  3. package/dist/runtime-host.mjs +1613 -244
  4. package/dist/standalone/.next/BUILD_ID +1 -1
  5. package/dist/standalone/.next/app-path-routes-manifest.json +28 -25
  6. package/dist/standalone/.next/build-manifest.json +2 -2
  7. package/dist/standalone/.next/prerender-manifest.json +3 -3
  8. package/dist/standalone/.next/routes-manifest.json +18 -0
  9. package/dist/standalone/.next/server/account-migration-controller-worker.js +1 -1
  10. package/dist/standalone/.next/server/app/_global-error/page.js +3 -3
  11. package/dist/standalone/.next/server/app/_global-error/page.js.nft.json +1 -1
  12. package/dist/standalone/.next/server/app/_global-error/page_client-reference-manifest.js +1 -1
  13. package/dist/standalone/.next/server/app/_global-error.html +1 -1
  14. package/dist/standalone/.next/server/app/_global-error.rsc +1 -1
  15. package/dist/standalone/.next/server/app/_global-error.segments/_full.segment.rsc +1 -1
  16. package/dist/standalone/.next/server/app/_global-error.segments/_global-error/__PAGE__.segment.rsc +1 -1
  17. package/dist/standalone/.next/server/app/_global-error.segments/_global-error.segment.rsc +1 -1
  18. package/dist/standalone/.next/server/app/_global-error.segments/_head.segment.rsc +1 -1
  19. package/dist/standalone/.next/server/app/_global-error.segments/_index.segment.rsc +1 -1
  20. package/dist/standalone/.next/server/app/_global-error.segments/_tree.segment.rsc +1 -1
  21. package/dist/standalone/.next/server/app/_not-found/page.js +2 -2
  22. package/dist/standalone/.next/server/app/_not-found/page.js.nft.json +1 -1
  23. package/dist/standalone/.next/server/app/_not-found/page_client-reference-manifest.js +1 -1
  24. package/dist/standalone/.next/server/app/_not-found.html +1 -1
  25. package/dist/standalone/.next/server/app/_not-found.rsc +2 -2
  26. package/dist/standalone/.next/server/app/_not-found.segments/_full.segment.rsc +2 -2
  27. package/dist/standalone/.next/server/app/_not-found.segments/_head.segment.rsc +1 -1
  28. package/dist/standalone/.next/server/app/_not-found.segments/_index.segment.rsc +2 -2
  29. package/dist/standalone/.next/server/app/_not-found.segments/_not-found/__PAGE__.segment.rsc +1 -1
  30. package/dist/standalone/.next/server/app/_not-found.segments/_not-found.segment.rsc +1 -1
  31. package/dist/standalone/.next/server/app/_not-found.segments/_tree.segment.rsc +2 -2
  32. package/dist/standalone/.next/server/app/api/access/route.js +1 -1
  33. package/dist/standalone/.next/server/app/api/access/route.js.nft.json +1 -1
  34. package/dist/standalone/.next/server/app/api/account-migrations/[intentId]/route.js +1 -1
  35. package/dist/standalone/.next/server/app/api/account-migrations/[intentId]/route.js.nft.json +1 -1
  36. package/dist/standalone/.next/server/app/api/accounts/claude/[id]/status/route.js +1 -1
  37. package/dist/standalone/.next/server/app/api/accounts/claude/[id]/status/route.js.nft.json +1 -1
  38. package/dist/standalone/.next/server/app/api/accounts/claude/active/route.js +1 -1
  39. package/dist/standalone/.next/server/app/api/accounts/claude/active/route.js.nft.json +1 -1
  40. package/dist/standalone/.next/server/app/api/accounts/claude/login/[operationId]/input/route.js +1 -1
  41. package/dist/standalone/.next/server/app/api/accounts/claude/login/[operationId]/input/route.js.nft.json +1 -1
  42. package/dist/standalone/.next/server/app/api/accounts/claude/login/[operationId]/route.js +1 -1
  43. package/dist/standalone/.next/server/app/api/accounts/claude/login/[operationId]/route.js.nft.json +1 -1
  44. package/dist/standalone/.next/server/app/api/accounts/claude/policy/route.js +1 -1
  45. package/dist/standalone/.next/server/app/api/accounts/claude/policy/route.js.nft.json +1 -1
  46. package/dist/standalone/.next/server/app/api/accounts/claude/route.js +1 -1
  47. package/dist/standalone/.next/server/app/api/accounts/claude/route.js.nft.json +1 -1
  48. package/dist/standalone/.next/server/app/api/accounts/claude/terminal/route.js +1 -1
  49. package/dist/standalone/.next/server/app/api/accounts/claude/terminal/route.js.nft.json +1 -1
  50. package/dist/standalone/.next/server/app/api/accounts/codex/active/route.js +1 -1
  51. package/dist/standalone/.next/server/app/api/accounts/codex/active/route.js.nft.json +1 -1
  52. package/dist/standalone/.next/server/app/api/accounts/codex/policy/route.js +1 -1
  53. package/dist/standalone/.next/server/app/api/accounts/codex/policy/route.js.nft.json +1 -1
  54. package/dist/standalone/.next/server/app/api/accounts/codex/route.js +1 -1
  55. package/dist/standalone/.next/server/app/api/accounts/codex/route.js.nft.json +1 -1
  56. package/dist/standalone/.next/server/app/api/accounts/codex/terminal/route.js +1 -1
  57. package/dist/standalone/.next/server/app/api/accounts/codex/terminal/route.js.nft.json +1 -1
  58. package/dist/standalone/.next/server/app/api/accounts/route.js +1 -1
  59. package/dist/standalone/.next/server/app/api/accounts/route.js.nft.json +1 -1
  60. package/dist/standalone/.next/server/app/api/agent/route.js +1 -1
  61. package/dist/standalone/.next/server/app/api/agent/route.js.nft.json +1 -1
  62. package/dist/standalone/.next/server/app/api/agent/snapshot/route.js +1 -1
  63. package/dist/standalone/.next/server/app/api/agent/snapshot/route.js.nft.json +1 -1
  64. package/dist/standalone/.next/server/app/api/answer/route.js +2 -1
  65. package/dist/standalone/.next/server/app/api/answer/route.js.nft.json +1 -1
  66. package/dist/standalone/.next/server/app/api/artifact/route.js +1 -1
  67. package/dist/standalone/.next/server/app/api/artifact/route.js.nft.json +1 -1
  68. package/dist/standalone/.next/server/app/api/attach-command/route.js +1 -1
  69. package/dist/standalone/.next/server/app/api/attach-command/route.js.nft.json +1 -1
  70. package/dist/standalone/.next/server/app/api/attention/[id]/route.js +1 -1
  71. package/dist/standalone/.next/server/app/api/attention/[id]/route.js.nft.json +1 -1
  72. package/dist/standalone/.next/server/app/api/attention/route.js +1 -1
  73. package/dist/standalone/.next/server/app/api/attention/route.js.nft.json +1 -1
  74. package/dist/standalone/.next/server/app/api/board/route.js +1 -1
  75. package/dist/standalone/.next/server/app/api/board/route.js.nft.json +1 -1
  76. package/dist/standalone/.next/server/app/api/bridge/route.js +2 -2
  77. package/dist/standalone/.next/server/app/api/bridge/route.js.nft.json +1 -1
  78. package/dist/standalone/.next/server/app/api/conversations/[conversationId]/migration/route.js +1 -1
  79. package/dist/standalone/.next/server/app/api/conversations/[conversationId]/migration/route.js.nft.json +1 -1
  80. package/dist/standalone/.next/server/app/api/conversations/route.js +1 -1
  81. package/dist/standalone/.next/server/app/api/conversations/route.js.nft.json +1 -1
  82. package/dist/standalone/.next/server/app/api/files/route.js +2 -2
  83. package/dist/standalone/.next/server/app/api/files/route.js.nft.json +1 -1
  84. package/dist/standalone/.next/server/app/api/flows/[id]/route.js +1 -1
  85. package/dist/standalone/.next/server/app/api/flows/[id]/route.js.nft.json +1 -1
  86. package/dist/standalone/.next/server/app/api/flows/route.js +1 -1
  87. package/dist/standalone/.next/server/app/api/flows/route.js.nft.json +1 -1
  88. package/dist/standalone/.next/server/app/api/image/route.js +1 -1
  89. package/dist/standalone/.next/server/app/api/image/route.js.nft.json +1 -1
  90. package/dist/standalone/.next/server/app/api/inbox/route.js +2 -2
  91. package/dist/standalone/.next/server/app/api/inbox/route.js.nft.json +1 -1
  92. package/dist/standalone/.next/server/app/api/lifecycle/reaper/route.js +1 -1
  93. package/dist/standalone/.next/server/app/api/lifecycle/reaper/route.js.nft.json +1 -1
  94. package/dist/standalone/.next/server/app/api/limits/history/route.js +1 -1
  95. package/dist/standalone/.next/server/app/api/limits/history/route.js.nft.json +1 -1
  96. package/dist/standalone/.next/server/app/api/limits/route.js +1 -1
  97. package/dist/standalone/.next/server/app/api/limits/route.js.nft.json +1 -1
  98. package/dist/standalone/.next/server/app/api/log/preflight/route.js +1 -1
  99. package/dist/standalone/.next/server/app/api/log/preflight/route.js.nft.json +1 -1
  100. package/dist/standalone/.next/server/app/api/log/project-delete/route.js +1 -1
  101. package/dist/standalone/.next/server/app/api/log/project-delete/route.js.nft.json +1 -1
  102. package/dist/standalone/.next/server/app/api/log/provenance/route.js +67 -1
  103. package/dist/standalone/.next/server/app/api/log/provenance/route.js.nft.json +1 -1
  104. package/dist/standalone/.next/server/app/api/log/route.js +1 -1
  105. package/dist/standalone/.next/server/app/api/log/route.js.nft.json +1 -1
  106. package/dist/standalone/.next/server/app/api/log/suggestions/route.js +3 -0
  107. package/dist/standalone/.next/server/app/api/log/suggestions/route.js.nft.json +1 -0
  108. package/dist/standalone/.next/server/app/api/log/suggestions/route_client-reference-manifest.js +1 -0
  109. package/dist/standalone/.next/server/app/api/logs/route.js +1 -1
  110. package/dist/standalone/.next/server/app/api/logs/route.js.nft.json +1 -1
  111. package/dist/standalone/.next/server/app/api/logs/stream/route.js +2 -2
  112. package/dist/standalone/.next/server/app/api/logs/stream/route.js.nft.json +1 -1
  113. package/dist/standalone/.next/server/app/api/monitor/lock/route.js +1 -3
  114. package/dist/standalone/.next/server/app/api/monitor/lock/route.js.nft.json +1 -1
  115. package/dist/standalone/.next/server/app/api/monitor/runs/route.js +1 -3
  116. package/dist/standalone/.next/server/app/api/monitor/runs/route.js.nft.json +1 -1
  117. package/dist/standalone/.next/server/app/api/orchestrator/rotate/route.js +1 -1
  118. package/dist/standalone/.next/server/app/api/orchestrator/rotate/route.js.nft.json +1 -1
  119. package/dist/standalone/.next/server/app/api/orchestrator/seat/route.js +1 -1
  120. package/dist/standalone/.next/server/app/api/orchestrator/seat/route.js.nft.json +1 -1
  121. package/dist/standalone/.next/server/app/api/orchestrator/seat/status/route.js +2 -2
  122. package/dist/standalone/.next/server/app/api/orchestrator/seat/status/route.js.nft.json +1 -1
  123. package/dist/standalone/.next/server/app/api/pipelines/[id]/route.js +1 -1
  124. package/dist/standalone/.next/server/app/api/pipelines/[id]/route.js.nft.json +1 -1
  125. package/dist/standalone/.next/server/app/api/pipelines/preflight/route.js +1 -1
  126. package/dist/standalone/.next/server/app/api/pipelines/preflight/route.js.nft.json +1 -1
  127. package/dist/standalone/.next/server/app/api/pipelines/route.js +2 -2
  128. package/dist/standalone/.next/server/app/api/pipelines/route.js.nft.json +1 -1
  129. package/dist/standalone/.next/server/app/api/pipelines/tick/route.js +2 -2
  130. package/dist/standalone/.next/server/app/api/pipelines/tick/route.js.nft.json +1 -1
  131. package/dist/standalone/.next/server/app/api/proc/route.js +1 -1
  132. package/dist/standalone/.next/server/app/api/proc/route.js.nft.json +1 -1
  133. package/dist/standalone/.next/server/app/api/projects/create/route.js +2 -2
  134. package/dist/standalone/.next/server/app/api/projects/create/route.js.nft.json +1 -1
  135. package/dist/standalone/.next/server/app/api/projects/crown/route.js +1 -1
  136. package/dist/standalone/.next/server/app/api/projects/crown/route.js.nft.json +1 -1
  137. package/dist/standalone/.next/server/app/api/projects/directories/route.js +1 -0
  138. package/dist/standalone/.next/server/app/api/projects/directories/route.js.nft.json +1 -0
  139. package/dist/standalone/.next/server/app/api/projects/directories/route_client-reference-manifest.js +1 -0
  140. package/dist/standalone/.next/server/app/api/push/route.js +2 -2
  141. package/dist/standalone/.next/server/app/api/push/route.js.nft.json +1 -1
  142. package/dist/standalone/.next/server/app/api/resources/route.js +1 -1
  143. package/dist/standalone/.next/server/app/api/resources/route.js.nft.json +1 -1
  144. package/dist/standalone/.next/server/app/api/roles/route.js +2 -2
  145. package/dist/standalone/.next/server/app/api/roles/route.js.nft.json +1 -1
  146. package/dist/standalone/.next/server/app/api/runtime/answer/route.js +2 -1
  147. package/dist/standalone/.next/server/app/api/runtime/answer/route.js.nft.json +1 -1
  148. package/dist/standalone/.next/server/app/api/runtime/deployments/[deploymentId]/route.js +1 -1
  149. package/dist/standalone/.next/server/app/api/runtime/deployments/[deploymentId]/route.js.nft.json +1 -1
  150. package/dist/standalone/.next/server/app/api/runtime/deployments/capabilities/v1/route.js +1 -1
  151. package/dist/standalone/.next/server/app/api/runtime/deployments/capabilities/v1/route.js.nft.json +1 -1
  152. package/dist/standalone/.next/server/app/api/runtime/deployments/route.js +1 -1
  153. package/dist/standalone/.next/server/app/api/runtime/deployments/route.js.nft.json +1 -1
  154. package/dist/standalone/.next/server/app/api/runtime/hosts/route.js +1 -0
  155. package/dist/standalone/.next/server/app/api/runtime/hosts/route.js.nft.json +1 -0
  156. package/dist/standalone/.next/server/app/api/runtime/hosts/route_client-reference-manifest.js +1 -0
  157. package/dist/standalone/.next/server/app/api/runtime/interrupt/route.js +2 -1
  158. package/dist/standalone/.next/server/app/api/runtime/interrupt/route.js.nft.json +1 -1
  159. package/dist/standalone/.next/server/app/api/runtime/operations/[operationId]/route.js +2 -1
  160. package/dist/standalone/.next/server/app/api/runtime/operations/[operationId]/route.js.nft.json +1 -1
  161. package/dist/standalone/.next/server/app/api/runtime/operations/route.js +1 -1
  162. package/dist/standalone/.next/server/app/api/runtime/operations/route.js.nft.json +1 -1
  163. package/dist/standalone/.next/server/app/api/runtime/realtime/route.js +2 -1
  164. package/dist/standalone/.next/server/app/api/runtime/realtime/route.js.nft.json +1 -1
  165. package/dist/standalone/.next/server/app/api/runtime/send/route.js +2 -1
  166. package/dist/standalone/.next/server/app/api/runtime/send/route.js.nft.json +1 -1
  167. package/dist/standalone/.next/server/app/api/runtime/snapshot/route.js +1 -1
  168. package/dist/standalone/.next/server/app/api/runtime/snapshot/route.js.nft.json +1 -1
  169. package/dist/standalone/.next/server/app/api/runtime/spawn/route.js +2 -1
  170. package/dist/standalone/.next/server/app/api/runtime/spawn/route.js.nft.json +1 -1
  171. package/dist/standalone/.next/server/app/api/runtime/steer/route.js +2 -1
  172. package/dist/standalone/.next/server/app/api/runtime/steer/route.js.nft.json +1 -1
  173. package/dist/standalone/.next/server/app/api/runtime/stream/route.js +2 -2
  174. package/dist/standalone/.next/server/app/api/runtime/stream/route.js.nft.json +1 -1
  175. package/dist/standalone/.next/server/app/api/search/transcripts/route.js +2 -2
  176. package/dist/standalone/.next/server/app/api/search/transcripts/route.js.nft.json +1 -1
  177. package/dist/standalone/.next/server/app/api/session/route.js +1 -1
  178. package/dist/standalone/.next/server/app/api/session/route.js.nft.json +1 -1
  179. package/dist/standalone/.next/server/app/api/session/supersedence/route.js +1 -1
  180. package/dist/standalone/.next/server/app/api/session/supersedence/route.js.nft.json +1 -1
  181. package/dist/standalone/.next/server/app/api/session/title/route.js +1 -1
  182. package/dist/standalone/.next/server/app/api/session/title/route.js.nft.json +1 -1
  183. package/dist/standalone/.next/server/app/api/spawn/policy/route.js +3 -3
  184. package/dist/standalone/.next/server/app/api/spawn/policy/route.js.nft.json +1 -1
  185. package/dist/standalone/.next/server/app/api/spawn/route.js +2 -2
  186. package/dist/standalone/.next/server/app/api/spawn/route.js.nft.json +1 -1
  187. package/dist/standalone/.next/server/app/api/staging/route.js +2 -2
  188. package/dist/standalone/.next/server/app/api/staging/route.js.nft.json +1 -1
  189. package/dist/standalone/.next/server/app/api/task-attachments/route.js +2 -2
  190. package/dist/standalone/.next/server/app/api/task-attachments/route.js.nft.json +1 -1
  191. package/dist/standalone/.next/server/app/api/tasks/[id]/assignment/route.js +1 -1
  192. package/dist/standalone/.next/server/app/api/tasks/[id]/assignment/route.js.nft.json +1 -1
  193. package/dist/standalone/.next/server/app/api/tasks/[id]/route.js +1 -1
  194. package/dist/standalone/.next/server/app/api/tasks/[id]/route.js.nft.json +1 -1
  195. package/dist/standalone/.next/server/app/api/tasks/[id]/send/route.js +2 -1
  196. package/dist/standalone/.next/server/app/api/tasks/[id]/send/route.js.nft.json +1 -1
  197. package/dist/standalone/.next/server/app/api/tasks/[id]/spawn/route.js +2 -1
  198. package/dist/standalone/.next/server/app/api/tasks/[id]/spawn/route.js.nft.json +1 -1
  199. package/dist/standalone/.next/server/app/api/tasks/curator/route.js +1 -1
  200. package/dist/standalone/.next/server/app/api/tasks/curator/route.js.nft.json +1 -1
  201. package/dist/standalone/.next/server/app/api/tasks/route.js +2 -2
  202. package/dist/standalone/.next/server/app/api/tasks/route.js.nft.json +1 -1
  203. package/dist/standalone/.next/server/app/api/telegram/reports/route.js +1 -1
  204. package/dist/standalone/.next/server/app/api/telegram/reports/route.js.nft.json +1 -1
  205. package/dist/standalone/.next/server/app/api/telegram/route.js +1 -1
  206. package/dist/standalone/.next/server/app/api/telegram/route.js.nft.json +1 -1
  207. package/dist/standalone/.next/server/app/api/timeline/route.js +1 -1
  208. package/dist/standalone/.next/server/app/api/timeline/route.js.nft.json +1 -1
  209. package/dist/standalone/.next/server/app/api/tmux/route.js +2 -1
  210. package/dist/standalone/.next/server/app/api/tmux/route.js.nft.json +1 -1
  211. package/dist/standalone/.next/server/app/api/tmux/targets/route.js +1 -1
  212. package/dist/standalone/.next/server/app/api/tmux/targets/route.js.nft.json +1 -1
  213. package/dist/standalone/.next/server/app/api/transcribe/backend/route.js +2 -2
  214. package/dist/standalone/.next/server/app/api/transcribe/backend/route.js.nft.json +1 -1
  215. package/dist/standalone/.next/server/app/api/transcribe/route.js +2 -2
  216. package/dist/standalone/.next/server/app/api/transcribe/route.js.nft.json +1 -1
  217. package/dist/standalone/.next/server/app/api/transcribe/token/route.js +2 -2
  218. package/dist/standalone/.next/server/app/api/transcribe/token/route.js.nft.json +1 -1
  219. package/dist/standalone/.next/server/app/api/tts/backend/route.js +1 -1
  220. package/dist/standalone/.next/server/app/api/tts/backend/route.js.nft.json +1 -1
  221. package/dist/standalone/.next/server/app/api/tts/route.js +1 -1
  222. package/dist/standalone/.next/server/app/api/tts/route.js.nft.json +1 -1
  223. package/dist/standalone/.next/server/app/api/view/presence/route.js +1 -1
  224. package/dist/standalone/.next/server/app/api/view/presence/route.js.nft.json +1 -1
  225. package/dist/standalone/.next/server/app/api/workflows/[id]/route.js +1 -1
  226. package/dist/standalone/.next/server/app/api/workflows/[id]/route.js.nft.json +1 -1
  227. package/dist/standalone/.next/server/app/api/workflows/route.js +1 -1
  228. package/dist/standalone/.next/server/app/api/workflows/route.js.nft.json +1 -1
  229. package/dist/standalone/.next/server/app/favicon.ico/route.js +1 -1
  230. package/dist/standalone/.next/server/app/favicon.ico/route.js.nft.json +1 -1
  231. package/dist/standalone/.next/server/app/index.html +1 -1
  232. package/dist/standalone/.next/server/app/index.rsc +3 -3
  233. package/dist/standalone/.next/server/app/index.segments/__PAGE__.segment.rsc +2 -2
  234. package/dist/standalone/.next/server/app/index.segments/_full.segment.rsc +3 -3
  235. package/dist/standalone/.next/server/app/index.segments/_head.segment.rsc +1 -1
  236. package/dist/standalone/.next/server/app/index.segments/_index.segment.rsc +2 -2
  237. package/dist/standalone/.next/server/app/index.segments/_tree.segment.rsc +2 -2
  238. package/dist/standalone/.next/server/app/page.js +17 -13
  239. package/dist/standalone/.next/server/app/page.js.nft.json +1 -1
  240. package/dist/standalone/.next/server/app/page_client-reference-manifest.js +1 -1
  241. package/dist/standalone/.next/server/app-paths-manifest.json +28 -25
  242. package/dist/standalone/.next/server/chunks/107.js +1 -0
  243. package/dist/standalone/.next/server/chunks/{1858.js → 1100.js} +2 -2
  244. package/dist/standalone/.next/server/chunks/1872.js +42 -0
  245. package/dist/standalone/.next/server/chunks/1952.js +3 -0
  246. package/dist/standalone/.next/server/chunks/2243.js +1 -0
  247. package/dist/standalone/.next/server/chunks/2260.js +104 -0
  248. package/dist/standalone/.next/server/chunks/2318.js +2 -2
  249. package/dist/standalone/.next/server/chunks/2324.js +1 -1
  250. package/dist/standalone/.next/server/chunks/2549.js +81 -0
  251. package/dist/standalone/.next/server/chunks/2682.js +85 -0
  252. package/dist/standalone/.next/server/chunks/3086.js +1 -1
  253. package/dist/standalone/.next/server/chunks/3214.js +1 -1
  254. package/dist/standalone/.next/server/chunks/3302.js +2 -0
  255. package/dist/standalone/.next/server/chunks/3336.js +1 -1
  256. package/dist/standalone/.next/server/chunks/3386.js +2 -0
  257. package/dist/standalone/.next/server/chunks/3558.js +1 -1
  258. package/dist/standalone/.next/server/chunks/3587.js +1 -1
  259. package/dist/standalone/.next/server/chunks/3740.js +20 -20
  260. package/dist/standalone/.next/server/chunks/3830.js +1 -0
  261. package/dist/standalone/.next/server/chunks/4191.js +1 -1
  262. package/dist/standalone/.next/server/chunks/4310.js +1 -0
  263. package/dist/standalone/.next/server/chunks/4509.js +1 -1
  264. package/dist/standalone/.next/server/chunks/4565.js +1 -0
  265. package/dist/standalone/.next/server/chunks/4651.js +2 -0
  266. package/dist/standalone/.next/server/chunks/4756.js +13 -0
  267. package/dist/standalone/.next/server/chunks/4972.js +1 -1
  268. package/dist/standalone/.next/server/chunks/5103.js +10 -0
  269. package/dist/standalone/.next/server/chunks/5408.js +1 -0
  270. package/dist/standalone/.next/server/chunks/5545.js +1 -0
  271. package/dist/standalone/.next/server/chunks/5689.js +1 -1
  272. package/dist/standalone/.next/server/chunks/6333.js +3 -3
  273. package/dist/standalone/.next/server/chunks/6487.js +10 -0
  274. package/dist/standalone/.next/server/chunks/6796.js +1 -1
  275. package/dist/standalone/.next/server/chunks/6820.js +99 -0
  276. package/dist/standalone/.next/server/chunks/6826.js +1 -1
  277. package/dist/standalone/.next/server/chunks/6839.js +81 -0
  278. package/dist/standalone/.next/server/chunks/6850.js +1 -1
  279. package/dist/standalone/.next/server/chunks/6909.js +1 -1
  280. package/dist/standalone/.next/server/chunks/6942.js +27 -0
  281. package/dist/standalone/.next/server/chunks/7139.js +82 -0
  282. package/dist/standalone/.next/server/chunks/7471.js +13 -13
  283. package/dist/standalone/.next/server/chunks/7644.js +2 -2
  284. package/dist/standalone/.next/server/chunks/7722.js +1 -1
  285. package/dist/standalone/.next/server/chunks/773.js +47 -0
  286. package/dist/standalone/.next/server/chunks/8263.js +81 -0
  287. package/dist/standalone/.next/server/chunks/8326.js +1 -0
  288. package/dist/standalone/.next/server/chunks/8444.js +1 -1
  289. package/dist/standalone/.next/server/chunks/8617.js +1 -1
  290. package/dist/standalone/.next/server/chunks/8817.js +1 -1
  291. package/dist/standalone/.next/server/chunks/8996.js +1 -1
  292. package/dist/standalone/.next/server/chunks/9307.js +1 -0
  293. package/dist/standalone/.next/server/chunks/9364.js +58 -58
  294. package/dist/standalone/.next/server/chunks/9381.js +42 -0
  295. package/dist/standalone/.next/server/chunks/9403.js +1 -0
  296. package/dist/standalone/.next/server/chunks/9434.js +3 -3
  297. package/dist/standalone/.next/server/chunks/9488.js +1 -0
  298. package/dist/standalone/.next/server/chunks/9750.js +1 -0
  299. package/dist/standalone/.next/server/chunks/9777.js +1 -0
  300. package/dist/standalone/.next/server/chunks/9937.js +1 -1
  301. package/dist/standalone/.next/server/chunks/9940.js +1 -1
  302. package/dist/standalone/.next/server/chunks/9998.js +1 -1
  303. package/dist/standalone/.next/server/files-response-worker.js +3 -3
  304. package/dist/standalone/.next/server/functions-config-manifest.json +3 -0
  305. package/dist/standalone/.next/server/instrumentation.js +1 -1
  306. package/dist/standalone/.next/server/middleware-build-manifest.js +1 -1
  307. package/dist/standalone/.next/server/pages/404.html +1 -1
  308. package/dist/standalone/.next/server/pages/500.html +1 -1
  309. package/dist/standalone/.next/server/resource-collector-worker.js +1 -1
  310. package/dist/standalone/.next/server/server-reference-manifest.json +1 -1
  311. package/dist/standalone/.next/server/wakatime-sync-worker.js +2 -2
  312. package/dist/standalone/.next/static/94yAMfjyhUPRgarycP9y4/_buildManifest.js +1 -0
  313. package/dist/standalone/.next/static/chunks/app/_global-error/page-ae02882983617748.js +1 -0
  314. package/dist/standalone/.next/static/chunks/app/api/access/route-ae02882983617748.js +1 -0
  315. package/dist/standalone/.next/static/chunks/app/api/account-migrations/[intentId]/route-ae02882983617748.js +1 -0
  316. package/dist/standalone/.next/static/chunks/app/api/accounts/claude/[id]/status/route-ae02882983617748.js +1 -0
  317. package/dist/standalone/.next/static/chunks/app/api/accounts/claude/active/route-ae02882983617748.js +1 -0
  318. package/dist/standalone/.next/static/chunks/app/api/accounts/claude/login/[operationId]/input/route-ae02882983617748.js +1 -0
  319. package/dist/standalone/.next/static/chunks/app/api/accounts/claude/login/[operationId]/route-ae02882983617748.js +1 -0
  320. package/dist/standalone/.next/static/chunks/app/api/accounts/claude/policy/route-ae02882983617748.js +1 -0
  321. package/dist/standalone/.next/static/chunks/app/api/accounts/claude/route-ae02882983617748.js +1 -0
  322. package/dist/standalone/.next/static/chunks/app/api/accounts/claude/terminal/route-ae02882983617748.js +1 -0
  323. package/dist/standalone/.next/static/chunks/app/api/accounts/codex/active/route-ae02882983617748.js +1 -0
  324. package/dist/standalone/.next/static/chunks/app/api/accounts/codex/policy/route-ae02882983617748.js +1 -0
  325. package/dist/standalone/.next/static/chunks/app/api/accounts/codex/route-ae02882983617748.js +1 -0
  326. package/dist/standalone/.next/static/chunks/app/api/accounts/codex/terminal/route-ae02882983617748.js +1 -0
  327. package/dist/standalone/.next/static/chunks/app/api/accounts/route-ae02882983617748.js +1 -0
  328. package/dist/standalone/.next/static/chunks/app/api/agent/route-ae02882983617748.js +1 -0
  329. package/dist/standalone/.next/static/chunks/app/api/agent/snapshot/route-ae02882983617748.js +1 -0
  330. package/dist/standalone/.next/static/chunks/app/api/answer/route-ae02882983617748.js +1 -0
  331. package/dist/standalone/.next/static/chunks/app/api/artifact/route-ae02882983617748.js +1 -0
  332. package/dist/standalone/.next/static/chunks/app/api/attach-command/route-ae02882983617748.js +1 -0
  333. package/dist/standalone/.next/static/chunks/app/api/attention/[id]/route-ae02882983617748.js +1 -0
  334. package/dist/standalone/.next/static/chunks/app/api/attention/route-ae02882983617748.js +1 -0
  335. package/dist/standalone/.next/static/chunks/app/api/board/route-ae02882983617748.js +1 -0
  336. package/dist/standalone/.next/static/chunks/app/api/bridge/route-ae02882983617748.js +1 -0
  337. package/dist/standalone/.next/static/chunks/app/api/conversations/[conversationId]/migration/route-ae02882983617748.js +1 -0
  338. package/dist/standalone/.next/static/chunks/app/api/conversations/route-ae02882983617748.js +1 -0
  339. package/dist/standalone/.next/static/chunks/app/api/files/route-ae02882983617748.js +1 -0
  340. package/dist/standalone/.next/static/chunks/app/api/flows/[id]/route-ae02882983617748.js +1 -0
  341. package/dist/standalone/.next/static/chunks/app/api/flows/route-ae02882983617748.js +1 -0
  342. package/dist/standalone/.next/static/chunks/app/api/image/route-ae02882983617748.js +1 -0
  343. package/dist/standalone/.next/static/chunks/app/api/inbox/route-ae02882983617748.js +1 -0
  344. package/dist/standalone/.next/static/chunks/app/api/lifecycle/reaper/route-ae02882983617748.js +1 -0
  345. package/dist/standalone/.next/static/chunks/app/api/limits/history/route-ae02882983617748.js +1 -0
  346. package/dist/standalone/.next/static/chunks/app/api/limits/route-ae02882983617748.js +1 -0
  347. package/dist/standalone/.next/static/chunks/app/api/log/preflight/route-ae02882983617748.js +1 -0
  348. package/dist/standalone/.next/static/chunks/app/api/log/project-delete/route-ae02882983617748.js +1 -0
  349. package/dist/standalone/.next/static/chunks/app/api/log/provenance/route-ae02882983617748.js +1 -0
  350. package/dist/standalone/.next/static/chunks/app/api/log/route-ae02882983617748.js +1 -0
  351. package/dist/standalone/.next/static/chunks/app/api/log/suggestions/route-ae02882983617748.js +1 -0
  352. package/dist/standalone/.next/static/chunks/app/api/logs/route-ae02882983617748.js +1 -0
  353. package/dist/standalone/.next/static/chunks/app/api/logs/stream/route-ae02882983617748.js +1 -0
  354. package/dist/standalone/.next/static/chunks/app/api/monitor/lock/route-ae02882983617748.js +1 -0
  355. package/dist/standalone/.next/static/chunks/app/api/monitor/runs/route-ae02882983617748.js +1 -0
  356. package/dist/standalone/.next/static/chunks/app/api/orchestrator/rotate/route-ae02882983617748.js +1 -0
  357. package/dist/standalone/.next/static/chunks/app/api/orchestrator/seat/route-ae02882983617748.js +1 -0
  358. package/dist/standalone/.next/static/chunks/app/api/orchestrator/seat/status/route-ae02882983617748.js +1 -0
  359. package/dist/standalone/.next/static/chunks/app/api/pipelines/[id]/route-ae02882983617748.js +1 -0
  360. package/dist/standalone/.next/static/chunks/app/api/pipelines/preflight/route-ae02882983617748.js +1 -0
  361. package/dist/standalone/.next/static/chunks/app/api/pipelines/route-ae02882983617748.js +1 -0
  362. package/dist/standalone/.next/static/chunks/app/api/pipelines/tick/route-ae02882983617748.js +1 -0
  363. package/dist/standalone/.next/static/chunks/app/api/proc/route-ae02882983617748.js +1 -0
  364. package/dist/standalone/.next/static/chunks/app/api/projects/create/route-ae02882983617748.js +1 -0
  365. package/dist/standalone/.next/static/chunks/app/api/projects/crown/route-ae02882983617748.js +1 -0
  366. package/dist/standalone/.next/static/chunks/app/api/projects/directories/route-ae02882983617748.js +1 -0
  367. package/dist/standalone/.next/static/chunks/app/api/push/route-ae02882983617748.js +1 -0
  368. package/dist/standalone/.next/static/chunks/app/api/resources/route-ae02882983617748.js +1 -0
  369. package/dist/standalone/.next/static/chunks/app/api/roles/route-ae02882983617748.js +1 -0
  370. package/dist/standalone/.next/static/chunks/app/api/runtime/answer/route-ae02882983617748.js +1 -0
  371. package/dist/standalone/.next/static/chunks/app/api/runtime/deployments/[deploymentId]/route-ae02882983617748.js +1 -0
  372. package/dist/standalone/.next/static/chunks/app/api/runtime/deployments/capabilities/v1/route-ae02882983617748.js +1 -0
  373. package/dist/standalone/.next/static/chunks/app/api/runtime/deployments/route-ae02882983617748.js +1 -0
  374. package/dist/standalone/.next/static/chunks/app/api/runtime/hosts/route-ae02882983617748.js +1 -0
  375. package/dist/standalone/.next/static/chunks/app/api/runtime/interrupt/route-ae02882983617748.js +1 -0
  376. package/dist/standalone/.next/static/chunks/app/api/runtime/operations/[operationId]/route-ae02882983617748.js +1 -0
  377. package/dist/standalone/.next/static/chunks/app/api/runtime/operations/route-ae02882983617748.js +1 -0
  378. package/dist/standalone/.next/static/chunks/app/api/runtime/realtime/route-ae02882983617748.js +1 -0
  379. package/dist/standalone/.next/static/chunks/app/api/runtime/send/route-ae02882983617748.js +1 -0
  380. package/dist/standalone/.next/static/chunks/app/api/runtime/snapshot/route-ae02882983617748.js +1 -0
  381. package/dist/standalone/.next/static/chunks/app/api/runtime/spawn/route-ae02882983617748.js +1 -0
  382. package/dist/standalone/.next/static/chunks/app/api/runtime/steer/route-ae02882983617748.js +1 -0
  383. package/dist/standalone/.next/static/chunks/app/api/runtime/stream/route-ae02882983617748.js +1 -0
  384. package/dist/standalone/.next/static/chunks/app/api/search/transcripts/route-ae02882983617748.js +1 -0
  385. package/dist/standalone/.next/static/chunks/app/api/session/route-ae02882983617748.js +1 -0
  386. package/dist/standalone/.next/static/chunks/app/api/session/supersedence/route-ae02882983617748.js +1 -0
  387. package/dist/standalone/.next/static/chunks/app/api/session/title/route-ae02882983617748.js +1 -0
  388. package/dist/standalone/.next/static/chunks/app/api/spawn/policy/route-ae02882983617748.js +1 -0
  389. package/dist/standalone/.next/static/chunks/app/api/spawn/route-ae02882983617748.js +1 -0
  390. package/dist/standalone/.next/static/chunks/app/api/staging/route-ae02882983617748.js +1 -0
  391. package/dist/standalone/.next/static/chunks/app/api/task-attachments/route-ae02882983617748.js +1 -0
  392. package/dist/standalone/.next/static/chunks/app/api/tasks/[id]/assignment/route-ae02882983617748.js +1 -0
  393. package/dist/standalone/.next/static/chunks/app/api/tasks/[id]/route-ae02882983617748.js +1 -0
  394. package/dist/standalone/.next/static/chunks/app/api/tasks/[id]/send/route-ae02882983617748.js +1 -0
  395. package/dist/standalone/.next/static/chunks/app/api/tasks/[id]/spawn/route-ae02882983617748.js +1 -0
  396. package/dist/standalone/.next/static/chunks/app/api/tasks/curator/route-ae02882983617748.js +1 -0
  397. package/dist/standalone/.next/static/chunks/app/api/tasks/route-ae02882983617748.js +1 -0
  398. package/dist/standalone/.next/static/chunks/app/api/telegram/reports/route-ae02882983617748.js +1 -0
  399. package/dist/standalone/.next/static/chunks/app/api/telegram/route-ae02882983617748.js +1 -0
  400. package/dist/standalone/.next/static/chunks/app/api/timeline/route-ae02882983617748.js +1 -0
  401. package/dist/standalone/.next/static/chunks/app/api/tmux/route-ae02882983617748.js +1 -0
  402. package/dist/standalone/.next/static/chunks/app/api/tmux/targets/route-ae02882983617748.js +1 -0
  403. package/dist/standalone/.next/static/chunks/app/api/transcribe/backend/route-ae02882983617748.js +1 -0
  404. package/dist/standalone/.next/static/chunks/app/api/transcribe/route-ae02882983617748.js +1 -0
  405. package/dist/standalone/.next/static/chunks/app/api/transcribe/token/route-ae02882983617748.js +1 -0
  406. package/dist/standalone/.next/static/chunks/app/api/tts/backend/route-ae02882983617748.js +1 -0
  407. package/dist/standalone/.next/static/chunks/app/api/tts/route-ae02882983617748.js +1 -0
  408. package/dist/standalone/.next/static/chunks/app/api/view/presence/route-ae02882983617748.js +1 -0
  409. package/dist/standalone/.next/static/chunks/app/api/workflows/[id]/route-ae02882983617748.js +1 -0
  410. package/dist/standalone/.next/static/chunks/app/api/workflows/route-ae02882983617748.js +1 -0
  411. package/dist/standalone/.next/static/chunks/app/page-1a141ae4aa9d31a9.js +85 -0
  412. package/dist/standalone/.next/static/chunks/{framework-d1de002210ddaaef.js → framework-04bc8c1a646a0097.js} +1 -1
  413. package/dist/standalone/.next/static/chunks/next/dist/client/components/builtin/app-error-ae02882983617748.js +1 -0
  414. package/dist/standalone/.next/static/chunks/next/dist/client/components/builtin/forbidden-ae02882983617748.js +1 -0
  415. package/dist/standalone/.next/static/chunks/next/dist/client/components/builtin/not-found-ae02882983617748.js +1 -0
  416. package/dist/standalone/.next/static/chunks/next/dist/client/components/builtin/unauthorized-ae02882983617748.js +1 -0
  417. package/dist/standalone/.next/static/css/dc96fb2edbd8742e.css +1 -0
  418. package/dist/standalone/node_modules/{nanoid → next/node_modules/postcss/node_modules/nanoid}/non-secure/index.cjs +2 -2
  419. package/dist/standalone/node_modules/{nanoid → next/node_modules/postcss/node_modules/nanoid}/package.json +1 -1
  420. package/dist/standalone/node_modules/react/cjs/react.development.js +1 -1
  421. package/dist/standalone/node_modules/react/cjs/react.production.js +1 -1
  422. package/dist/standalone/node_modules/react/package.json +3 -3
  423. package/dist/standalone/node_modules/react-dom/cjs/react-dom-server-legacy.browser.production.js +1 -1
  424. package/dist/standalone/node_modules/react-dom/cjs/react-dom-server-legacy.node.production.js +1 -1
  425. package/dist/standalone/node_modules/react-dom/cjs/react-dom-server.browser.production.js +3 -3
  426. package/dist/standalone/node_modules/react-dom/cjs/react-dom-server.edge.production.js +3 -3
  427. package/dist/standalone/node_modules/react-dom/cjs/react-dom-server.node.production.js +3 -3
  428. package/dist/standalone/node_modules/react-dom/cjs/react-dom.production.js +1 -1
  429. package/dist/standalone/node_modules/react-dom/package.json +4 -4
  430. package/dist/standalone/package.json +9 -8
  431. package/dist/standalone/src/lib/inboxFiles.ts +203 -0
  432. package/package.json +9 -8
  433. package/dist/standalone/.next/server/chunks/156.js +0 -2
  434. package/dist/standalone/.next/server/chunks/1920.js +0 -27
  435. package/dist/standalone/.next/server/chunks/2338.js +0 -12
  436. package/dist/standalone/.next/server/chunks/2904.js +0 -42
  437. package/dist/standalone/.next/server/chunks/2977.js +0 -1
  438. package/dist/standalone/.next/server/chunks/3139.js +0 -10
  439. package/dist/standalone/.next/server/chunks/3598.js +0 -81
  440. package/dist/standalone/.next/server/chunks/4968.js +0 -1
  441. package/dist/standalone/.next/server/chunks/6977.js +0 -1
  442. package/dist/standalone/.next/server/chunks/7295.js +0 -10
  443. package/dist/standalone/.next/server/chunks/7868.js +0 -1
  444. package/dist/standalone/.next/server/chunks/8026.js +0 -1
  445. package/dist/standalone/.next/server/chunks/8600.js +0 -12
  446. package/dist/standalone/.next/server/chunks/9246.js +0 -47
  447. package/dist/standalone/.next/server/chunks/9733.js +0 -42
  448. package/dist/standalone/.next/static/2ybXlxpylgBaGz43zp2fM/_buildManifest.js +0 -1
  449. package/dist/standalone/.next/static/chunks/app/_global-error/page-c132c5ba005ff29e.js +0 -1
  450. package/dist/standalone/.next/static/chunks/app/api/access/route-c132c5ba005ff29e.js +0 -1
  451. package/dist/standalone/.next/static/chunks/app/api/account-migrations/[intentId]/route-c132c5ba005ff29e.js +0 -1
  452. package/dist/standalone/.next/static/chunks/app/api/accounts/claude/[id]/status/route-c132c5ba005ff29e.js +0 -1
  453. package/dist/standalone/.next/static/chunks/app/api/accounts/claude/active/route-c132c5ba005ff29e.js +0 -1
  454. package/dist/standalone/.next/static/chunks/app/api/accounts/claude/login/[operationId]/input/route-c132c5ba005ff29e.js +0 -1
  455. package/dist/standalone/.next/static/chunks/app/api/accounts/claude/login/[operationId]/route-c132c5ba005ff29e.js +0 -1
  456. package/dist/standalone/.next/static/chunks/app/api/accounts/claude/policy/route-c132c5ba005ff29e.js +0 -1
  457. package/dist/standalone/.next/static/chunks/app/api/accounts/claude/route-c132c5ba005ff29e.js +0 -1
  458. package/dist/standalone/.next/static/chunks/app/api/accounts/claude/terminal/route-c132c5ba005ff29e.js +0 -1
  459. package/dist/standalone/.next/static/chunks/app/api/accounts/codex/active/route-c132c5ba005ff29e.js +0 -1
  460. package/dist/standalone/.next/static/chunks/app/api/accounts/codex/policy/route-c132c5ba005ff29e.js +0 -1
  461. package/dist/standalone/.next/static/chunks/app/api/accounts/codex/route-c132c5ba005ff29e.js +0 -1
  462. package/dist/standalone/.next/static/chunks/app/api/accounts/codex/terminal/route-c132c5ba005ff29e.js +0 -1
  463. package/dist/standalone/.next/static/chunks/app/api/accounts/route-c132c5ba005ff29e.js +0 -1
  464. package/dist/standalone/.next/static/chunks/app/api/agent/route-c132c5ba005ff29e.js +0 -1
  465. package/dist/standalone/.next/static/chunks/app/api/agent/snapshot/route-c132c5ba005ff29e.js +0 -1
  466. package/dist/standalone/.next/static/chunks/app/api/answer/route-c132c5ba005ff29e.js +0 -1
  467. package/dist/standalone/.next/static/chunks/app/api/artifact/route-c132c5ba005ff29e.js +0 -1
  468. package/dist/standalone/.next/static/chunks/app/api/attach-command/route-c132c5ba005ff29e.js +0 -1
  469. package/dist/standalone/.next/static/chunks/app/api/attention/[id]/route-c132c5ba005ff29e.js +0 -1
  470. package/dist/standalone/.next/static/chunks/app/api/attention/route-c132c5ba005ff29e.js +0 -1
  471. package/dist/standalone/.next/static/chunks/app/api/board/route-c132c5ba005ff29e.js +0 -1
  472. package/dist/standalone/.next/static/chunks/app/api/bridge/route-c132c5ba005ff29e.js +0 -1
  473. package/dist/standalone/.next/static/chunks/app/api/conversations/[conversationId]/migration/route-c132c5ba005ff29e.js +0 -1
  474. package/dist/standalone/.next/static/chunks/app/api/conversations/route-c132c5ba005ff29e.js +0 -1
  475. package/dist/standalone/.next/static/chunks/app/api/files/route-c132c5ba005ff29e.js +0 -1
  476. package/dist/standalone/.next/static/chunks/app/api/flows/[id]/route-c132c5ba005ff29e.js +0 -1
  477. package/dist/standalone/.next/static/chunks/app/api/flows/route-c132c5ba005ff29e.js +0 -1
  478. package/dist/standalone/.next/static/chunks/app/api/image/route-c132c5ba005ff29e.js +0 -1
  479. package/dist/standalone/.next/static/chunks/app/api/inbox/route-c132c5ba005ff29e.js +0 -1
  480. package/dist/standalone/.next/static/chunks/app/api/lifecycle/reaper/route-c132c5ba005ff29e.js +0 -1
  481. package/dist/standalone/.next/static/chunks/app/api/limits/history/route-c132c5ba005ff29e.js +0 -1
  482. package/dist/standalone/.next/static/chunks/app/api/limits/route-c132c5ba005ff29e.js +0 -1
  483. package/dist/standalone/.next/static/chunks/app/api/log/preflight/route-c132c5ba005ff29e.js +0 -1
  484. package/dist/standalone/.next/static/chunks/app/api/log/project-delete/route-c132c5ba005ff29e.js +0 -1
  485. package/dist/standalone/.next/static/chunks/app/api/log/provenance/route-c132c5ba005ff29e.js +0 -1
  486. package/dist/standalone/.next/static/chunks/app/api/log/route-c132c5ba005ff29e.js +0 -1
  487. package/dist/standalone/.next/static/chunks/app/api/logs/route-c132c5ba005ff29e.js +0 -1
  488. package/dist/standalone/.next/static/chunks/app/api/logs/stream/route-c132c5ba005ff29e.js +0 -1
  489. package/dist/standalone/.next/static/chunks/app/api/monitor/lock/route-c132c5ba005ff29e.js +0 -1
  490. package/dist/standalone/.next/static/chunks/app/api/monitor/runs/route-c132c5ba005ff29e.js +0 -1
  491. package/dist/standalone/.next/static/chunks/app/api/orchestrator/rotate/route-c132c5ba005ff29e.js +0 -1
  492. package/dist/standalone/.next/static/chunks/app/api/orchestrator/seat/route-c132c5ba005ff29e.js +0 -1
  493. package/dist/standalone/.next/static/chunks/app/api/orchestrator/seat/status/route-c132c5ba005ff29e.js +0 -1
  494. package/dist/standalone/.next/static/chunks/app/api/pipelines/[id]/route-c132c5ba005ff29e.js +0 -1
  495. package/dist/standalone/.next/static/chunks/app/api/pipelines/preflight/route-c132c5ba005ff29e.js +0 -1
  496. package/dist/standalone/.next/static/chunks/app/api/pipelines/route-c132c5ba005ff29e.js +0 -1
  497. package/dist/standalone/.next/static/chunks/app/api/pipelines/tick/route-c132c5ba005ff29e.js +0 -1
  498. package/dist/standalone/.next/static/chunks/app/api/proc/route-c132c5ba005ff29e.js +0 -1
  499. package/dist/standalone/.next/static/chunks/app/api/projects/create/route-c132c5ba005ff29e.js +0 -1
  500. package/dist/standalone/.next/static/chunks/app/api/projects/crown/route-c132c5ba005ff29e.js +0 -1
  501. package/dist/standalone/.next/static/chunks/app/api/push/route-c132c5ba005ff29e.js +0 -1
  502. package/dist/standalone/.next/static/chunks/app/api/resources/route-c132c5ba005ff29e.js +0 -1
  503. package/dist/standalone/.next/static/chunks/app/api/roles/route-c132c5ba005ff29e.js +0 -1
  504. package/dist/standalone/.next/static/chunks/app/api/runtime/answer/route-c132c5ba005ff29e.js +0 -1
  505. package/dist/standalone/.next/static/chunks/app/api/runtime/deployments/[deploymentId]/route-c132c5ba005ff29e.js +0 -1
  506. package/dist/standalone/.next/static/chunks/app/api/runtime/deployments/capabilities/v1/route-c132c5ba005ff29e.js +0 -1
  507. package/dist/standalone/.next/static/chunks/app/api/runtime/deployments/route-c132c5ba005ff29e.js +0 -1
  508. package/dist/standalone/.next/static/chunks/app/api/runtime/interrupt/route-c132c5ba005ff29e.js +0 -1
  509. package/dist/standalone/.next/static/chunks/app/api/runtime/operations/[operationId]/route-c132c5ba005ff29e.js +0 -1
  510. package/dist/standalone/.next/static/chunks/app/api/runtime/operations/route-c132c5ba005ff29e.js +0 -1
  511. package/dist/standalone/.next/static/chunks/app/api/runtime/realtime/route-c132c5ba005ff29e.js +0 -1
  512. package/dist/standalone/.next/static/chunks/app/api/runtime/send/route-c132c5ba005ff29e.js +0 -1
  513. package/dist/standalone/.next/static/chunks/app/api/runtime/snapshot/route-c132c5ba005ff29e.js +0 -1
  514. package/dist/standalone/.next/static/chunks/app/api/runtime/spawn/route-c132c5ba005ff29e.js +0 -1
  515. package/dist/standalone/.next/static/chunks/app/api/runtime/steer/route-c132c5ba005ff29e.js +0 -1
  516. package/dist/standalone/.next/static/chunks/app/api/runtime/stream/route-c132c5ba005ff29e.js +0 -1
  517. package/dist/standalone/.next/static/chunks/app/api/search/transcripts/route-c132c5ba005ff29e.js +0 -1
  518. package/dist/standalone/.next/static/chunks/app/api/session/route-c132c5ba005ff29e.js +0 -1
  519. package/dist/standalone/.next/static/chunks/app/api/session/supersedence/route-c132c5ba005ff29e.js +0 -1
  520. package/dist/standalone/.next/static/chunks/app/api/session/title/route-c132c5ba005ff29e.js +0 -1
  521. package/dist/standalone/.next/static/chunks/app/api/spawn/policy/route-c132c5ba005ff29e.js +0 -1
  522. package/dist/standalone/.next/static/chunks/app/api/spawn/route-c132c5ba005ff29e.js +0 -1
  523. package/dist/standalone/.next/static/chunks/app/api/staging/route-c132c5ba005ff29e.js +0 -1
  524. package/dist/standalone/.next/static/chunks/app/api/task-attachments/route-c132c5ba005ff29e.js +0 -1
  525. package/dist/standalone/.next/static/chunks/app/api/tasks/[id]/assignment/route-c132c5ba005ff29e.js +0 -1
  526. package/dist/standalone/.next/static/chunks/app/api/tasks/[id]/route-c132c5ba005ff29e.js +0 -1
  527. package/dist/standalone/.next/static/chunks/app/api/tasks/[id]/send/route-c132c5ba005ff29e.js +0 -1
  528. package/dist/standalone/.next/static/chunks/app/api/tasks/[id]/spawn/route-c132c5ba005ff29e.js +0 -1
  529. package/dist/standalone/.next/static/chunks/app/api/tasks/curator/route-c132c5ba005ff29e.js +0 -1
  530. package/dist/standalone/.next/static/chunks/app/api/tasks/route-c132c5ba005ff29e.js +0 -1
  531. package/dist/standalone/.next/static/chunks/app/api/telegram/reports/route-c132c5ba005ff29e.js +0 -1
  532. package/dist/standalone/.next/static/chunks/app/api/telegram/route-c132c5ba005ff29e.js +0 -1
  533. package/dist/standalone/.next/static/chunks/app/api/timeline/route-c132c5ba005ff29e.js +0 -1
  534. package/dist/standalone/.next/static/chunks/app/api/tmux/route-c132c5ba005ff29e.js +0 -1
  535. package/dist/standalone/.next/static/chunks/app/api/tmux/targets/route-c132c5ba005ff29e.js +0 -1
  536. package/dist/standalone/.next/static/chunks/app/api/transcribe/backend/route-c132c5ba005ff29e.js +0 -1
  537. package/dist/standalone/.next/static/chunks/app/api/transcribe/route-c132c5ba005ff29e.js +0 -1
  538. package/dist/standalone/.next/static/chunks/app/api/transcribe/token/route-c132c5ba005ff29e.js +0 -1
  539. package/dist/standalone/.next/static/chunks/app/api/tts/backend/route-c132c5ba005ff29e.js +0 -1
  540. package/dist/standalone/.next/static/chunks/app/api/tts/route-c132c5ba005ff29e.js +0 -1
  541. package/dist/standalone/.next/static/chunks/app/api/view/presence/route-c132c5ba005ff29e.js +0 -1
  542. package/dist/standalone/.next/static/chunks/app/api/workflows/[id]/route-c132c5ba005ff29e.js +0 -1
  543. package/dist/standalone/.next/static/chunks/app/api/workflows/route-c132c5ba005ff29e.js +0 -1
  544. package/dist/standalone/.next/static/chunks/app/page-7ba2538fa87e3d62.js +0 -80
  545. package/dist/standalone/.next/static/chunks/next/dist/client/components/builtin/app-error-c132c5ba005ff29e.js +0 -1
  546. package/dist/standalone/.next/static/chunks/next/dist/client/components/builtin/forbidden-c132c5ba005ff29e.js +0 -1
  547. package/dist/standalone/.next/static/chunks/next/dist/client/components/builtin/not-found-c132c5ba005ff29e.js +0 -1
  548. package/dist/standalone/.next/static/chunks/next/dist/client/components/builtin/unauthorized-c132c5ba005ff29e.js +0 -1
  549. package/dist/standalone/.next/static/css/498f12ddef7ecb0e.css +0 -1
  550. /package/dist/standalone/.next/static/{2ybXlxpylgBaGz43zp2fM → 94yAMfjyhUPRgarycP9y4}/_ssgManifest.js +0 -0
  551. /package/dist/standalone/node_modules/{nanoid → next/node_modules/postcss/node_modules/nanoid}/non-secure/package.json +0 -0
@@ -3344,7 +3344,7 @@ function freshSpecFor(engine, cwd, options = {}) {
3344
3344
  allowSubagents: options.allowSubagents ?? false,
3345
3345
  mcpServers,
3346
3346
  plugins: [],
3347
- title: null,
3347
+ title: options.title?.trim() || null,
3348
3348
  project: null,
3349
3349
  parentConversationId: null,
3350
3350
  role: "worker",
@@ -3385,7 +3385,7 @@ function freshSpecFor(engine, cwd, options = {}) {
3385
3385
  allowSubagents: options.allowSubagents ?? false,
3386
3386
  mcpServers,
3387
3387
  plugins: [],
3388
- title: null,
3388
+ title: options.title?.trim() || null,
3389
3389
  project: null,
3390
3390
  parentConversationId: null,
3391
3391
  role: "worker",
@@ -3584,6 +3584,97 @@ var init_cli = __esm(() => {
3584
3584
  CLAUDE_SHADOWED_ENV = ["ANTHROPIC_API_KEY", "ANTHROPIC_AUTH_TOKEN", "CLAUDE_CODE_OAUTH_TOKEN", "ANTHROPIC_BASE_URL", "AWS_ACCESS_KEY_ID", "AWS_SECRET_ACCESS_KEY", "AWS_SESSION_TOKEN", "GOOGLE_APPLICATION_CREDENTIALS", "VERTEXAI_PROJECT", "CLAUDE_CODE_USE_BEDROCK", "CLAUDE_CODE_USE_VERTEX", "LLV_TOKEN"];
3585
3585
  });
3586
3586
 
3587
+ // src/lib/proc/darwinArgv.ts
3588
+ import { createRequire as createRequire2 } from "module";
3589
+ function parseDarwinProcArgs2(buffer, bytesRead) {
3590
+ if (bytesRead < ARGC_SIZE || bytesRead > buffer.byteLength)
3591
+ return null;
3592
+ const argc = buffer.readInt32LE(0);
3593
+ if (argc <= 0 || argc > MAX_ARGC)
3594
+ return null;
3595
+ let cursor = buffer.indexOf(0, ARGC_SIZE);
3596
+ if (cursor < 0 || cursor >= bytesRead)
3597
+ return null;
3598
+ while (cursor < bytesRead && buffer[cursor] === 0)
3599
+ cursor += 1;
3600
+ const argv = [];
3601
+ while (argv.length < argc) {
3602
+ const end = buffer.indexOf(0, cursor);
3603
+ if (end < 0 || end >= bytesRead)
3604
+ return null;
3605
+ argv.push(buffer.toString("utf8", cursor, end));
3606
+ cursor = end + 1;
3607
+ }
3608
+ return argv;
3609
+ }
3610
+ function loadReader2() {
3611
+ if (cachedReader2 !== undefined)
3612
+ return cachedReader2;
3613
+ if (process.platform !== "darwin") {
3614
+ cachedReader2 = null;
3615
+ return cachedReader2;
3616
+ }
3617
+ try {
3618
+ const runtimeRequire = createRequire2(import.meta.url);
3619
+ const ffi = runtimeRequire(`bun:${"ffi"}`);
3620
+ const library = ffi.dlopen("/usr/lib/libSystem.B.dylib", {
3621
+ sysctl: {
3622
+ args: [ffi.FFIType.ptr, ffi.FFIType.u32, ffi.FFIType.ptr, ffi.FFIType.ptr, ffi.FFIType.ptr, ffi.FFIType.u64],
3623
+ returns: ffi.FFIType.i32
3624
+ }
3625
+ });
3626
+ const unusedNew = Buffer.alloc(8);
3627
+ const call = (mib, out, outLength) => Number(library.symbols.sysctl(ffi.ptr(mib), mib.byteLength / 4, ffi.ptr(out), ffi.ptr(outLength), ffi.ptr(unusedNew), BigInt(0)));
3628
+ cachedReader2 = (pid, buffer) => {
3629
+ const mib = Buffer.alloc(12);
3630
+ mib.writeInt32LE(CTL_KERN, 0);
3631
+ mib.writeInt32LE(KERN_PROCARGS2, 4);
3632
+ mib.writeInt32LE(pid, 8);
3633
+ const length = Buffer.alloc(8);
3634
+ length.writeBigUInt64LE(BigInt(buffer.byteLength));
3635
+ if (call(mib, buffer, length) !== 0)
3636
+ return -1;
3637
+ const written = Number(length.readBigUInt64LE());
3638
+ return Number.isSafeInteger(written) ? written : -1;
3639
+ };
3640
+ cachedBuffer = Buffer.alloc(readArgMax(call));
3641
+ } catch {
3642
+ cachedReader2 = null;
3643
+ }
3644
+ return cachedReader2;
3645
+ }
3646
+ function readArgMax(call) {
3647
+ const mib = Buffer.alloc(8);
3648
+ mib.writeInt32LE(CTL_KERN, 0);
3649
+ mib.writeInt32LE(KERN_ARGMAX, 4);
3650
+ const value = Buffer.alloc(4);
3651
+ const length = Buffer.alloc(8);
3652
+ length.writeBigUInt64LE(BigInt(value.byteLength));
3653
+ if (call(mib, value, length) !== 0)
3654
+ return DEFAULT_ARG_MAX;
3655
+ const argMax = value.readInt32LE(0);
3656
+ return argMax >= MIN_ARG_MAX && argMax <= MAX_ARG_MAX ? argMax : DEFAULT_ARG_MAX;
3657
+ }
3658
+ function darwinProcessArgv(pid) {
3659
+ if (!Number.isInteger(pid) || pid <= 0)
3660
+ return null;
3661
+ const reader = loadReader2();
3662
+ const buffer = cachedBuffer;
3663
+ if (!reader || !buffer)
3664
+ return null;
3665
+ try {
3666
+ return parseDarwinProcArgs2(buffer, reader(pid, buffer));
3667
+ } catch {
3668
+ return null;
3669
+ }
3670
+ }
3671
+ var CTL_KERN = 1, KERN_ARGMAX = 8, KERN_PROCARGS2 = 49, ARGC_SIZE = 4, DEFAULT_ARG_MAX, MIN_ARG_MAX, MAX_ARG_MAX, MAX_ARGC = 4096, cachedReader2, cachedBuffer = null;
3672
+ var init_darwinArgv = __esm(() => {
3673
+ DEFAULT_ARG_MAX = 1024 * 1024;
3674
+ MIN_ARG_MAX = 4 * 1024;
3675
+ MAX_ARG_MAX = 32 * 1024 * 1024;
3676
+ });
3677
+
3587
3678
  // src/lib/accounts/claudeLogin.ts
3588
3679
  import { spawn } from "child_process";
3589
3680
  import crypto7 from "crypto";
@@ -3596,13 +3687,18 @@ function procStartToken(pid) {
3596
3687
  return null;
3597
3688
  }
3598
3689
  }
3599
- async function waitForProcessExit(pid, startToken) {
3600
- while (procStartToken(pid) === startToken) {
3601
- await new Promise((resolve) => setTimeout(resolve, 25));
3602
- }
3690
+ function exitPoller(startTokenOf) {
3691
+ return async function waitForProcessExit(pid, startToken) {
3692
+ while (startTokenOf(pid) === startToken) {
3693
+ await new Promise((resolve) => setTimeout(resolve, 25));
3694
+ }
3695
+ };
3603
3696
  }
3604
3697
  function isExpectedClaudeLoginCommand(commandLine) {
3605
- const args = commandLine.split("\x00").filter(Boolean);
3698
+ return isExpectedClaudeLoginArgv(commandLine.split("\x00"));
3699
+ }
3700
+ function isExpectedClaudeLoginArgv(argv) {
3701
+ const args = argv.filter(Boolean);
3606
3702
  const direct = /(?:^|\/)claude$/.test(args[0] ?? "") && args.length === 4;
3607
3703
  const wrapped = /(?:^|\/)(?:node|bun)$/.test(args[0] ?? "") && /claude/i.test(args[1] ?? "") && args.length === 5;
3608
3704
  const shimmed = /(?:^|\/)(?:sh|dash|bash)$/.test(args[0] ?? "") && /(?:^|\/)claude$/.test(args[1] ?? "") && args.length === 5;
@@ -3616,6 +3712,46 @@ function expectedClaude(pid) {
3616
3712
  return false;
3617
3713
  }
3618
3714
  }
3715
+ function sleepThrough(ms) {
3716
+ try {
3717
+ Atomics.wait(execWindowLatch, 0, 0, ms);
3718
+ } catch {
3719
+ const until = Date.now() + ms;
3720
+ while (Date.now() < until) {}
3721
+ }
3722
+ }
3723
+ function sameArguments(left, right) {
3724
+ return right !== null && left.length === right.length && left.every((entry, index) => entry === right[index]);
3725
+ }
3726
+ function executedArgv(pid, readers) {
3727
+ if (pid === process.pid)
3728
+ return readers.argv(pid);
3729
+ const forking = readers.argv(process.pid);
3730
+ const deadline = Date.now() + EXEC_WINDOW_MS;
3731
+ for (;; ) {
3732
+ const argv = readers.argv(pid);
3733
+ if (argv !== null && !sameArguments(argv, forking))
3734
+ return argv;
3735
+ if (argv === null && readers.startToken(pid) === null)
3736
+ return null;
3737
+ if (Date.now() >= deadline)
3738
+ return argv;
3739
+ sleepThrough(EXEC_POLL_MS);
3740
+ }
3741
+ }
3742
+ function identityPortsFrom(readers) {
3743
+ return {
3744
+ pidStartToken: readers.startToken,
3745
+ isExpectedClaude: (pid) => {
3746
+ const argv = executedArgv(pid, readers);
3747
+ return argv !== null && isExpectedClaudeLoginArgv(argv);
3748
+ },
3749
+ waitForExit: exitPoller(readers.startToken)
3750
+ };
3751
+ }
3752
+ function processIdentityPorts(platform = process.platform, darwin = darwinIdentityReaders) {
3753
+ return platform === "darwin" ? identityPortsFrom(darwin) : { pidStartToken: procStartToken, isExpectedClaude: expectedClaude, waitForExit: exitPoller(procStartToken) };
3754
+ }
3619
3755
  function isSupervisedClaudeHome(home) {
3620
3756
  return isManagedClaudeHome(home) || home === legacyClaudeHome();
3621
3757
  }
@@ -4137,10 +4273,12 @@ class ClaudeLoginSupervisor {
4137
4273
  function osHome() {
4138
4274
  return process.env.HOME || "/";
4139
4275
  }
4140
- var OUTPUT_LIMIT, CODE_LIMIT, LOGIN_TIMEOUT_MS, TERM_GRACE_MS = 2000, URL_HOSTS, ANSI, URL_PATTERN, realClaudeLoginPorts, fileClaudeLoginStore, LIVE_CLAUDE_LOGIN_PHASES, defaultClaudeLoginSupervisor, claudeLoginSupervisor;
4276
+ var OUTPUT_LIMIT, CODE_LIMIT, LOGIN_TIMEOUT_MS, TERM_GRACE_MS = 2000, URL_HOSTS, ANSI, URL_PATTERN, darwinIdentityReaders, EXEC_WINDOW_MS = 1000, EXEC_POLL_MS = 2, execWindowLatch, realClaudeLoginPorts, fileClaudeLoginStore, LIVE_CLAUDE_LOGIN_PHASES, defaultClaudeLoginSupervisor, claudeLoginSupervisor;
4141
4277
  var init_claudeLogin = __esm(() => {
4142
4278
  init_cli();
4143
4279
  init_configDir();
4280
+ init_darwinArgv();
4281
+ init_darwinIdentity();
4144
4282
  init_accountMutation();
4145
4283
  init_claude();
4146
4284
  OUTPUT_LIMIT = 64 * 1024;
@@ -4149,6 +4287,11 @@ var init_claudeLogin = __esm(() => {
4149
4287
  URL_HOSTS = new Set(["claude.ai", "claude.com", "platform.claude.com", "console.anthropic.com"]);
4150
4288
  ANSI = /\x1B(?:\[[0-?]*[ -/]*[@-~]|\][^\x07\x1B]*(?:\x07|\x1B\\))/g;
4151
4289
  URL_PATTERN = /https:\/\/[^\s"'<>]+/g;
4290
+ darwinIdentityReaders = {
4291
+ startToken: darwinProcessIdentity,
4292
+ argv: darwinProcessArgv
4293
+ };
4294
+ execWindowLatch = new Int32Array(new SharedArrayBuffer(4));
4152
4295
  realClaudeLoginPorts = {
4153
4296
  spawn: (command, args, options) => spawn(command, args, options),
4154
4297
  kill: (pid, signal) => {
@@ -4160,9 +4303,7 @@ var init_claudeLogin = __esm(() => {
4160
4303
  } catch {}
4161
4304
  }
4162
4305
  },
4163
- pidStartToken: procStartToken,
4164
- isExpectedClaude: expectedClaude,
4165
- waitForExit: waitForProcessExit,
4306
+ ...processIdentityPorts(),
4166
4307
  status: structuredStatus,
4167
4308
  now: Date.now,
4168
4309
  setTimeout,
@@ -5120,6 +5261,58 @@ function unavailableLimits() {
5120
5261
  return { state: "unavailable", session: null, weekly: null, checkedAt: null };
5121
5262
  }
5122
5263
 
5264
+ // src/lib/title.ts
5265
+ function compactPath(value) {
5266
+ return value.replace(/(?:\/[^\s)]+){3,}/g, (match) => {
5267
+ if (match.length <= 40)
5268
+ return match;
5269
+ const parts = match.split("/").filter(Boolean);
5270
+ return parts.length >= 2 ? ".../" + parts.slice(-2).join("/") : match;
5271
+ });
5272
+ }
5273
+ function cleanTitle(value, maxLength = 160) {
5274
+ const stripped = value.replace(/\[([^\]]+)\]\(([^)]+)\)/g, "$1").replace(/`([^`]+)`/g, "$1").replace(/[*_~#>]+/g, "").replace(/\s+/g, " ").trim();
5275
+ const compacted = compactPath(stripped).replace(/\s+/g, " ").trim();
5276
+ return compacted.length > maxLength ? compacted.slice(0, maxLength - 1).trimEnd() + "\u2026" : compacted;
5277
+ }
5278
+ function genericSessionTitleKey(value) {
5279
+ return value.toLocaleLowerCase().replace(/[\p{P}\p{S}\s]+/gu, " ").trim();
5280
+ }
5281
+ function isGenericSessionTitle(value) {
5282
+ return typeof value === "string" && GENERIC_SESSION_TITLES.has(genericSessionTitleKey(value));
5283
+ }
5284
+ function durableSemanticTitle(value, maxLength = 160) {
5285
+ if (typeof value !== "string")
5286
+ return null;
5287
+ const trimmed = value.trim();
5288
+ const cleaned = cleanTitle(trimmed, maxLength);
5289
+ if (!trimmed || !/[\p{L}\p{N}]/u.test(cleaned) || isGenericSessionTitle(trimmed))
5290
+ return null;
5291
+ return trimmed.length > maxLength ? trimmed.slice(0, maxLength - 1).trimEnd() + "\u2026" : trimmed;
5292
+ }
5293
+ function semanticTitle(value, maxLength = 160) {
5294
+ const durable = durableSemanticTitle(value, maxLength);
5295
+ return durable ? cleanTitle(durable, maxLength) : null;
5296
+ }
5297
+ function firstPromptLine(value, maxLength = 60) {
5298
+ const firstLine = value?.split(/\r?\n/, 1)[0] ?? "";
5299
+ return semanticTitle(firstLine, maxLength);
5300
+ }
5301
+ function derivedSpawnTitle(role, prompt, fallback = "New task") {
5302
+ const semanticRole = typeof role === "string" ? cleanTitle(role, 40) || "agent" : "agent";
5303
+ const semanticPrompt = firstPromptLine(prompt, 60) ?? semanticTitle(fallback, 60) ?? "New task";
5304
+ return cleanTitle(`${semanticRole} \xB7 ${semanticPrompt}`, 120);
5305
+ }
5306
+ var GENERIC_SESSION_TITLES, SPAWN_TITLE_REQUIRED_ERROR = "title is required for every new spawn";
5307
+ var init_title = __esm(() => {
5308
+ GENERIC_SESSION_TITLES = new Set([
5309
+ "codex session",
5310
+ "claude session",
5311
+ "codex",
5312
+ "claude"
5313
+ ]);
5314
+ });
5315
+
5123
5316
  // src/lib/accounts/migration/contracts.ts
5124
5317
  function validExplicitProject(value) {
5125
5318
  if (typeof value !== "string")
@@ -5163,6 +5356,12 @@ function emptyLaunchProfile(overrides = {}, policy) {
5163
5356
  plugins: grantedPlugins(overrides.plugins)
5164
5357
  };
5165
5358
  }
5359
+ function migrationSuccessorLaunchProfile(profile) {
5360
+ return emptyLaunchProfile({
5361
+ ...profile,
5362
+ title: durableSemanticTitle(profile.title, 120) ?? derivedSpawnTitle("migration successor", profile.goal?.objective ?? profile.cwd, "Conversation migration")
5363
+ });
5364
+ }
5166
5365
  function sameProcessIdentity(left, right) {
5167
5366
  return left.pid === right.pid && left.startIdentity === right.startIdentity;
5168
5367
  }
@@ -5182,6 +5381,7 @@ var PROJECT_KEY_PATTERN;
5182
5381
  var init_contracts2 = __esm(() => {
5183
5382
  init_mcpAllowlist();
5184
5383
  init_pluginAllowlist();
5384
+ init_title();
5185
5385
  PROJECT_KEY_PATTERN = /^-?[A-Za-z0-9][A-Za-z0-9._-]{0,126}$/;
5186
5386
  });
5187
5387
 
@@ -5225,6 +5425,403 @@ var init_intentLiveness = __esm(() => {
5225
5425
  COMMITTED_MIGRATION_DELIVERY_REASON = `${MIGRATION_DELIVERY_CANCELLATION_PREFIX} its owning account migration committed; send again to authorize a fresh delivery action`;
5226
5426
  });
5227
5427
 
5428
+ // src/lib/agent/identityWaveMigration.ts
5429
+ function canonicalConversationId(file, conversationId) {
5430
+ if (!conversationId.startsWith("conversation_"))
5431
+ return null;
5432
+ let current = conversationId;
5433
+ const seen = new Set;
5434
+ while (file.conversationAliases[current] && !seen.has(current)) {
5435
+ seen.add(current);
5436
+ current = file.conversationAliases[current];
5437
+ }
5438
+ return seen.has(current) ? null : current;
5439
+ }
5440
+ function semanticEvidence(value) {
5441
+ if (typeof value !== "string")
5442
+ return null;
5443
+ const firstNonEmptyLine = value.split(/\r?\n/).find((line) => line.trim());
5444
+ return semanticTitle(firstNonEmptyLine, 120);
5445
+ }
5446
+ function receiptTitles(file) {
5447
+ const titles = new Map;
5448
+ const byLaunchFirst = Object.values(file.receipts).sort((left, right) => left.createdAt.localeCompare(right.createdAt)).sort((left, right) => Number(right.purpose === "launch") - Number(left.purpose === "launch"));
5449
+ for (const receipt of byLaunchFirst) {
5450
+ const conversationId = canonicalConversationId(file, receipt.conversationId);
5451
+ const title = semanticEvidence(receipt.launchDisplay?.prompt);
5452
+ if (conversationId && title && !titles.has(conversationId))
5453
+ titles.set(conversationId, title);
5454
+ }
5455
+ return titles;
5456
+ }
5457
+ function placeholderTitle(value) {
5458
+ return typeof value === "string" && semanticTitle(value) === null;
5459
+ }
5460
+ function newestSemanticConversationTitle(conversation) {
5461
+ for (let index = conversation.generations.length - 1;index >= 0; index -= 1) {
5462
+ const title = durableSemanticTitle(conversation.generations[index].launchProfile.title);
5463
+ if (title)
5464
+ return title;
5465
+ }
5466
+ return null;
5467
+ }
5468
+ function conversationNeedsTitleCleanup(file, conversation) {
5469
+ if (conversation.generations.some((generation) => placeholderTitle(generation.launchProfile.title)))
5470
+ return true;
5471
+ const ownedPaths = new Set(conversation.generations.map((generation) => generation.path));
5472
+ if (Object.values(file.entries).some((entry) => ownedPaths.has(entry.artifactPath) && placeholderTitle(entry.launchProfile?.title)))
5473
+ return true;
5474
+ return Object.values(file.receipts).some((receipt) => canonicalConversationId(file, receipt.conversationId) === conversation.id && placeholderTitle(receipt.launchProfile.title));
5475
+ }
5476
+ function safeSharedPath(input, pathname) {
5477
+ try {
5478
+ const candidate = input.sharedPathForLegacy(pathname);
5479
+ if (!candidate)
5480
+ return { kind: "absent" };
5481
+ if (candidate.sharedPath === pathname)
5482
+ return { kind: "absent" };
5483
+ return { kind: "found", value: candidate };
5484
+ } catch (error) {
5485
+ return { kind: "failed", error };
5486
+ }
5487
+ }
5488
+ function safeTranscriptTitle(input, pathname, engine) {
5489
+ try {
5490
+ const title = semanticEvidence(input.transcriptTitle(pathname, engine));
5491
+ return title ? { kind: "found", value: title } : { kind: "absent" };
5492
+ } catch (error) {
5493
+ return { kind: "failed", error };
5494
+ }
5495
+ }
5496
+ function evidenceValue(resolution) {
5497
+ if (resolution.kind === "failed")
5498
+ throw resolution.error;
5499
+ return resolution.kind === "found" ? resolution.value : null;
5500
+ }
5501
+ function resolveConversationEvidence(file, input) {
5502
+ const evidence = new Map;
5503
+ for (const conversation of Object.values(file.conversations)) {
5504
+ const generation = conversation.generations.at(-1);
5505
+ if (!generation)
5506
+ continue;
5507
+ const conversationTitle = newestSemanticConversationTitle(conversation);
5508
+ const needsTitleCleanup = conversationNeedsTitleCleanup(file, conversation);
5509
+ const pathRekeys = conversation.generations.flatMap((ownedGeneration) => {
5510
+ const candidate = evidenceValue(safeSharedPath(input, ownedGeneration.path));
5511
+ return candidate ? [{ legacyPath: ownedGeneration.path, ...candidate }] : [];
5512
+ });
5513
+ evidence.set(conversation.id, { conversationTitle, needsTitleCleanup, pathRekeys, transcriptTitle: null });
5514
+ }
5515
+ return evidence;
5516
+ }
5517
+ function resolveRekeyOwnership(file, evidence) {
5518
+ const owners = new Map;
5519
+ const generationPaths = new Map;
5520
+ const generationOwners = new Map;
5521
+ const rememberOwner = (map, pathname, conversationId) => {
5522
+ const pathOwners = map.get(pathname) ?? new Set;
5523
+ pathOwners.add(conversationId);
5524
+ map.set(pathname, pathOwners);
5525
+ };
5526
+ for (const conversation of Object.values(file.conversations)) {
5527
+ for (const generation of conversation.generations) {
5528
+ rememberOwner(owners, generation.path, conversation.id);
5529
+ rememberOwner(generationPaths, generation.path, conversation.id);
5530
+ rememberOwner(generationOwners, `${conversation.engine}:${generation.id}`, conversation.id);
5531
+ }
5532
+ for (const pathname of conversation.continuityPaths)
5533
+ rememberOwner(owners, pathname, conversation.id);
5534
+ }
5535
+ for (const receipt of Object.values(file.receipts)) {
5536
+ if (!receipt.artifactPath)
5537
+ continue;
5538
+ rememberOwner(owners, receipt.artifactPath, canonicalConversationId(file, receipt.conversationId) ?? `receipt:${receipt.launchId}`);
5539
+ }
5540
+ for (const entry of Object.values(file.entries)) {
5541
+ const entryOwners = generationOwners.get(`${entry.key.engine}:${entry.key.sessionId}`);
5542
+ if (entryOwners?.size) {
5543
+ for (const conversationId of entryOwners)
5544
+ rememberOwner(owners, entry.artifactPath, conversationId);
5545
+ } else {
5546
+ rememberOwner(owners, entry.artifactPath, `entry:${entry.key.engine}:${entry.key.sessionId}`);
5547
+ }
5548
+ }
5549
+ const targetSources = new Map;
5550
+ const rekeys = [];
5551
+ let quarantined = 0;
5552
+ for (const [conversationId, conversationEvidence] of evidence) {
5553
+ const owned = [];
5554
+ for (const rekey of conversationEvidence.pathRekeys) {
5555
+ if (!rekey.identityEquivalent) {
5556
+ quarantined += 1;
5557
+ continue;
5558
+ }
5559
+ const pathOwners = owners.get(rekey.sharedPath);
5560
+ const sourceOwners = owners.get(rekey.legacyPath);
5561
+ const generationOwners2 = generationPaths.get(rekey.sharedPath);
5562
+ const priorSource = targetSources.get(rekey.sharedPath);
5563
+ if (!sourceOwners || sourceOwners.size !== 1 || !sourceOwners.has(conversationId) || pathOwners && [...pathOwners].some((owner) => owner !== conversationId) || generationOwners2 && rekey.sharedPath !== rekey.legacyPath || priorSource && priorSource !== rekey.legacyPath) {
5564
+ quarantined += 1;
5565
+ continue;
5566
+ }
5567
+ targetSources.set(rekey.sharedPath, rekey.legacyPath);
5568
+ owned.push(rekey);
5569
+ rekeys.push({ legacyPath: rekey.legacyPath, sharedPath: rekey.sharedPath });
5570
+ }
5571
+ conversationEvidence.pathRekeys = owned;
5572
+ }
5573
+ return { rekeys, quarantined };
5574
+ }
5575
+ function resolveTranscriptEvidence(file, input, titlesByReceipt, evidence) {
5576
+ for (const conversation of Object.values(file.conversations)) {
5577
+ const generation = conversation.generations.at(-1);
5578
+ const conversationEvidence = evidence.get(conversation.id);
5579
+ if (!generation || !conversationEvidence?.needsTitleCleanup || conversationEvidence.conversationTitle !== null || titlesByReceipt.has(conversation.id))
5580
+ continue;
5581
+ const transcriptPath = conversationEvidence.pathRekeys.find((rekey) => rekey.legacyPath === generation.path)?.sharedPath ?? generation.path;
5582
+ conversationEvidence.transcriptTitle = evidenceValue(safeTranscriptTitle(input, transcriptPath, conversation.engine));
5583
+ }
5584
+ }
5585
+ function rekeyProviderReceipt(receipt, legacyPath, sharedPath) {
5586
+ if (receipt.path === legacyPath)
5587
+ receipt.path = sharedPath;
5588
+ receipt.continuityPaths = [...new Set(receipt.continuityPaths.map((pathname) => pathname === legacyPath ? sharedPath : pathname))];
5589
+ }
5590
+ function rekeyArtifactReferences(file, legacyPath, sharedPath) {
5591
+ for (const entry of Object.values(file.entries)) {
5592
+ if (entry.artifactPath === legacyPath)
5593
+ entry.artifactPath = sharedPath;
5594
+ }
5595
+ for (const receipt of Object.values(file.receipts)) {
5596
+ if (receipt.artifactPath === legacyPath)
5597
+ receipt.artifactPath = sharedPath;
5598
+ if (receipt.resumeSourcePath === legacyPath)
5599
+ receipt.resumeSourcePath = sharedPath;
5600
+ }
5601
+ for (const edge of Object.values(file.lineageEdges)) {
5602
+ if (edge.childArtifactPath === legacyPath)
5603
+ edge.childArtifactPath = sharedPath;
5604
+ if (edge.parentArtifactPath === legacyPath)
5605
+ edge.parentArtifactPath = sharedPath;
5606
+ }
5607
+ for (const delivery of Object.values(file.heldDeliveries)) {
5608
+ delivery.artifactPaths = [...new Set(delivery.artifactPaths.map((pathname) => pathname === legacyPath ? sharedPath : pathname))];
5609
+ }
5610
+ for (const conversation of Object.values(file.conversations)) {
5611
+ const migration = conversation.migration;
5612
+ if (!migration)
5613
+ continue;
5614
+ if (migration.providerReceipt)
5615
+ rekeyProviderReceipt(migration.providerReceipt, legacyPath, sharedPath);
5616
+ migration.pendingContinuityPaths = [...new Set(migration.pendingContinuityPaths.map((pathname) => pathname === legacyPath ? sharedPath : pathname))];
5617
+ }
5618
+ for (const pending of Object.values(file.pendingSuccessorCleanups)) {
5619
+ rekeyProviderReceipt(pending.receipt, legacyPath, sharedPath);
5620
+ }
5621
+ const resumePane = file.legacyResumePanes.panes[legacyPath];
5622
+ if (resumePane) {
5623
+ file.legacyResumePanes.panes[sharedPath] ??= resumePane;
5624
+ delete file.legacyResumePanes.panes[legacyPath];
5625
+ }
5626
+ }
5627
+ function stampOrchestratorLineage(file, seat, createdAt) {
5628
+ const conversationId = seat.conversationId ? canonicalConversationId(file, seat.conversationId) : null;
5629
+ const conversation = conversationId ? file.conversations[conversationId] : null;
5630
+ if (!conversationId || !conversation)
5631
+ return { changed: false, engine: null };
5632
+ const predecessorId = seat.predecessorConversationId ? canonicalConversationId(file, seat.predecessorConversationId) : null;
5633
+ const predecessor = predecessorId && predecessorId !== conversationId ? file.conversations[predecessorId] : null;
5634
+ const lineageWouldCycle = predecessorId && predecessor ? wouldCreateLineageCycle(file, conversationId, predecessorId) : false;
5635
+ const lineagePredecessorId = lineageWouldCycle ? null : predecessorId;
5636
+ const lineagePredecessor = lineageWouldCycle ? null : predecessor;
5637
+ const rows = file.memberships[conversationId] ??= [];
5638
+ let changed = false;
5639
+ if (!rows.some((row) => row.kind === "orchestrator" && row.containerId === seat.project && row.slot === `seat:${seat.seatEpoch}`)) {
5640
+ rows.push({
5641
+ conversationId,
5642
+ kind: "orchestrator",
5643
+ containerId: seat.project,
5644
+ role: "orchestrator",
5645
+ slot: `seat:${seat.seatEpoch}`,
5646
+ stageId: null,
5647
+ stageOrder: null,
5648
+ round: null,
5649
+ parentConversationId: lineagePredecessor ? lineagePredecessorId : null,
5650
+ runtime: null,
5651
+ createdAt
5652
+ });
5653
+ changed = true;
5654
+ }
5655
+ if (conversation.agentRole !== "orchestrator") {
5656
+ conversation.agentRole = "orchestrator";
5657
+ changed = true;
5658
+ }
5659
+ if (conversation.delegationDepth !== 0) {
5660
+ conversation.delegationDepth = 0;
5661
+ changed = true;
5662
+ }
5663
+ if (lineagePredecessor && !file.lineageEdges[conversationId]) {
5664
+ const generation = conversation.generations.at(-1);
5665
+ const parentGeneration = lineagePredecessor.generations.at(-1);
5666
+ const edge = {
5667
+ childConversationId: conversationId,
5668
+ parentConversationId: lineagePredecessorId,
5669
+ childSessionKey: generation ? sessionKeyFromTranscript(conversation.engine, generation.path) : null,
5670
+ parentSessionKey: parentGeneration ? sessionKeyFromTranscript(lineagePredecessor.engine, parentGeneration.path) : null,
5671
+ childArtifactPath: generation?.path ?? null,
5672
+ parentArtifactPath: parentGeneration?.path ?? null,
5673
+ kind: "spawn",
5674
+ role: "orchestrator",
5675
+ reviewsConversationId: null,
5676
+ source: "viewer-spawn",
5677
+ evidence: { launchId: null, clientAttemptId: null, parentSource: null },
5678
+ createdAt
5679
+ };
5680
+ file.lineageEdges[conversationId] = edge;
5681
+ changed = true;
5682
+ }
5683
+ if (changed)
5684
+ conversation.updatedAt = createdAt;
5685
+ return { changed, engine: conversation.engine };
5686
+ }
5687
+ function stampPendingOrchestratorLineage(file, seat) {
5688
+ const conversationId = seat.conversationId ? canonicalConversationId(file, seat.conversationId) : null;
5689
+ if (!conversationId || file.conversations[conversationId])
5690
+ return { changed: false, engine: null };
5691
+ const receipt = Object.values(file.receipts).find((candidate) => canonicalConversationId(file, candidate.conversationId) === conversationId);
5692
+ if (!receipt)
5693
+ return { changed: false, engine: null };
5694
+ const pending = {
5695
+ project: seat.project,
5696
+ seatEpoch: seat.seatEpoch,
5697
+ conversationId,
5698
+ predecessorConversationId: seat.predecessorConversationId ? canonicalConversationId(file, seat.predecessorConversationId) : null,
5699
+ designatedAt: seat.designatedAt,
5700
+ activatedAt: seat.activatedAt,
5701
+ path: seat.path ?? null
5702
+ };
5703
+ if (JSON.stringify(receipt.pendingOrchestratorSeatIdentity) === JSON.stringify(pending)) {
5704
+ return { changed: false, engine: receipt.engine };
5705
+ }
5706
+ receipt.pendingOrchestratorSeatIdentity = pending;
5707
+ return { changed: true, engine: receipt.engine };
5708
+ }
5709
+ function wouldCreateLineageCycle(file, childConversationId, parentConversationId) {
5710
+ const visited = new Set;
5711
+ let cursor = parentConversationId;
5712
+ while (cursor) {
5713
+ if (cursor === childConversationId || visited.has(cursor))
5714
+ return true;
5715
+ visited.add(cursor);
5716
+ const parent = file.lineageEdges[cursor]?.parentConversationId;
5717
+ cursor = parent ? canonicalConversationId(file, parent) : null;
5718
+ }
5719
+ return false;
5720
+ }
5721
+ function applyIdentityWaveMigration(source, input) {
5722
+ const dryRun = input.dryRun === true;
5723
+ const file = dryRun ? structuredClone(source) : source;
5724
+ if (file.identityMigrations[IDENTITY_WAVE_MIGRATION]) {
5725
+ return { dryRun, alreadyCompleted: true, retitled: 0, rekeyed: 0, quarantinedRekeys: 0, edgesStamped: 0 };
5726
+ }
5727
+ const titlesByReceipt = receiptTitles(file);
5728
+ const evidenceByConversation = resolveConversationEvidence(file, input);
5729
+ const ownership = resolveRekeyOwnership(file, evidenceByConversation);
5730
+ resolveTranscriptEvidence(file, input, titlesByReceipt, evidenceByConversation);
5731
+ if (!dryRun && ownership.rekeys.length > 0) {
5732
+ input.commitExternalPathRekeys?.(ownership.rekeys);
5733
+ }
5734
+ const changedEngines = new Set;
5735
+ let retitled = 0;
5736
+ let rekeyed = 0;
5737
+ let edgesStamped = 0;
5738
+ for (const conversation of Object.values(file.conversations)) {
5739
+ const generation = conversation.generations.at(-1);
5740
+ if (!generation)
5741
+ continue;
5742
+ let conversationChanged = false;
5743
+ const evidence = evidenceByConversation.get(conversation.id);
5744
+ const pathRekeys = evidence?.pathRekeys ?? [];
5745
+ if (pathRekeys.length > 0) {
5746
+ for (const { legacyPath, sharedPath } of pathRekeys) {
5747
+ if (!conversation.continuityPaths.includes(legacyPath))
5748
+ conversation.continuityPaths.push(legacyPath);
5749
+ conversation.continuityPaths = conversation.continuityPaths.filter((pathname) => pathname !== sharedPath);
5750
+ for (const ownedGeneration of conversation.generations) {
5751
+ if (ownedGeneration.path === legacyPath)
5752
+ ownedGeneration.path = sharedPath;
5753
+ }
5754
+ rekeyArtifactReferences(file, legacyPath, sharedPath);
5755
+ }
5756
+ rekeyed += 1;
5757
+ conversationChanged = true;
5758
+ }
5759
+ if (evidence?.needsTitleCleanup) {
5760
+ const replacement = evidence.conversationTitle ?? titlesByReceipt.get(conversation.id) ?? evidence?.transcriptTitle ?? null;
5761
+ for (const ownedGeneration of conversation.generations) {
5762
+ if (placeholderTitle(ownedGeneration.launchProfile.title)) {
5763
+ ownedGeneration.launchProfile.title = replacement;
5764
+ }
5765
+ }
5766
+ const ownedPaths = new Set(conversation.generations.map((ownedGeneration) => ownedGeneration.path));
5767
+ for (const entry of Object.values(file.entries)) {
5768
+ if (ownedPaths.has(entry.artifactPath) && entry.launchProfile && placeholderTitle(entry.launchProfile.title)) {
5769
+ entry.launchProfile.title = replacement;
5770
+ }
5771
+ }
5772
+ for (const receipt of Object.values(file.receipts)) {
5773
+ if (canonicalConversationId(file, receipt.conversationId) === conversation.id && placeholderTitle(receipt.launchProfile.title)) {
5774
+ receipt.launchProfile.title = replacement;
5775
+ if (replacement)
5776
+ receipt.identityWaveTitleBackfill = true;
5777
+ }
5778
+ }
5779
+ if (replacement)
5780
+ retitled += 1;
5781
+ conversationChanged = true;
5782
+ }
5783
+ if (conversationChanged) {
5784
+ conversation.updatedAt = input.now;
5785
+ changedEngines.add(conversation.engine);
5786
+ }
5787
+ }
5788
+ for (const seat of input.orchestratorSeats) {
5789
+ const stamped = stampOrchestratorLineage(file, seat, seat.activatedAt ?? seat.designatedAt ?? input.now);
5790
+ const pending = stamped.engine ? { changed: false, engine: null } : stampPendingOrchestratorLineage(file, seat);
5791
+ const changed = stamped.changed || pending.changed;
5792
+ const engine = stamped.engine ?? pending.engine;
5793
+ if (!changed || !engine)
5794
+ continue;
5795
+ edgesStamped += 1;
5796
+ changedEngines.add(engine);
5797
+ }
5798
+ for (const engine of changedEngines) {
5799
+ file.conversationRevision[engine] += 1;
5800
+ }
5801
+ if (!dryRun) {
5802
+ file.identityMigrations[IDENTITY_WAVE_MIGRATION] = {
5803
+ completedAt: input.now,
5804
+ retitled,
5805
+ rekeyed,
5806
+ quarantinedRekeys: ownership.quarantined,
5807
+ edgesStamped
5808
+ };
5809
+ }
5810
+ return {
5811
+ dryRun,
5812
+ alreadyCompleted: false,
5813
+ retitled,
5814
+ rekeyed,
5815
+ quarantinedRekeys: ownership.quarantined,
5816
+ edgesStamped
5817
+ };
5818
+ }
5819
+ var IDENTITY_WAVE_MIGRATION = "identity-wave-a-d-913";
5820
+ var init_identityWaveMigration = __esm(() => {
5821
+ init_sessionKey();
5822
+ init_title();
5823
+ });
5824
+
5228
5825
  // src/lib/agent/accountLiveness.ts
5229
5826
  function futureRetryAt(value, now) {
5230
5827
  if (!value)
@@ -6455,6 +7052,7 @@ var init_sqliteRegistryStore = __esm(() => {
6455
7052
  META_FIELDS = [
6456
7053
  "importedResumePanes",
6457
7054
  "legacyResumePanes",
7055
+ "identityMigrations",
6458
7056
  "conversationRevision",
6459
7057
  "engineRouting",
6460
7058
  "autoBalance",
@@ -6693,7 +7291,7 @@ function mergeResumeLaunchProfile(current, requested) {
6693
7291
  allowSubagents: current.allowSubagents || requested.allowSubagents,
6694
7292
  mcpServers: current.mcpServers,
6695
7293
  plugins: current.plugins ?? [],
6696
- title: requested.title ?? current.title,
7294
+ title: durableSemanticTitle(current.title) ?? durableSemanticTitle(requested.title),
6697
7295
  project: requested.project ?? current.project,
6698
7296
  parentConversationId: requested.parentConversationId ?? current.parentConversationId,
6699
7297
  role: current.role === "root" || requested.role === "root" ? "root" : "worker",
@@ -6757,6 +7355,7 @@ function conversationMigrationForIntent(conversation, source, intent, phase, cha
6757
7355
  errorCode: null,
6758
7356
  operationId: crypto9.randomUUID(),
6759
7357
  sourceGenerationId: source.id,
7358
+ successorLaunchProfile: null,
6760
7359
  providerReceipt: null,
6761
7360
  pendingContinuityPaths,
6762
7361
  boardProject,
@@ -6999,7 +7598,7 @@ function normalizeMemberships(value) {
6999
7598
  if (!candidate || typeof candidate !== "object" || Array.isArray(candidate))
7000
7599
  return [];
7001
7600
  const row = candidate;
7002
- if (row.kind !== "flow" && row.kind !== "pipeline" || typeof row.containerId !== "string" || !row.containerId || typeof row.role !== "string" || !row.role || typeof row.slot !== "string" || !row.slot)
7601
+ if (row.kind !== "flow" && row.kind !== "pipeline" && row.kind !== "orchestrator" || typeof row.containerId !== "string" || !row.containerId || typeof row.role !== "string" || !row.role || typeof row.slot !== "string" || !row.slot)
7003
7602
  return [];
7004
7603
  const runtime2 = row.runtime && typeof row.runtime === "object" && (row.runtime.engine === "claude" || row.runtime.engine === "codex") ? {
7005
7604
  engine: row.runtime.engine,
@@ -7025,6 +7624,25 @@ function normalizeMemberships(value) {
7025
7624
  }
7026
7625
  return normalized;
7027
7626
  }
7627
+ function normalizeIdentityMigrations(value) {
7628
+ if (!value || typeof value !== "object" || Array.isArray(value))
7629
+ return {};
7630
+ return Object.fromEntries(Object.entries(value).flatMap(([key2, candidate]) => {
7631
+ if (!candidate || typeof candidate !== "object" || Array.isArray(candidate))
7632
+ return [];
7633
+ const marker = candidate;
7634
+ const quarantinedRekeys = marker.quarantinedRekeys ?? 0;
7635
+ if (typeof marker.completedAt !== "string" || !Number.isSafeInteger(marker.retitled) || marker.retitled < 0 || !Number.isSafeInteger(marker.rekeyed) || marker.rekeyed < 0 || !Number.isSafeInteger(quarantinedRekeys) || quarantinedRekeys < 0 || !Number.isSafeInteger(marker.edgesStamped) || marker.edgesStamped < 0)
7636
+ return [];
7637
+ return [[key2, {
7638
+ completedAt: marker.completedAt,
7639
+ retitled: marker.retitled,
7640
+ rekeyed: marker.rekeyed,
7641
+ quarantinedRekeys,
7642
+ edgesStamped: marker.edgesStamped
7643
+ }]];
7644
+ }));
7645
+ }
7028
7646
  function normalizeProviderReceipt(value) {
7029
7647
  if (!value || typeof value !== "object")
7030
7648
  return null;
@@ -7064,12 +7682,14 @@ function normalizeConversation(value, policy) {
7064
7682
  const current = generations.at(-1);
7065
7683
  const legacyContinuity = value.migration?.continuityPaths;
7066
7684
  const providerReceipt = normalizeProviderReceipt(value.migration?.providerReceipt);
7685
+ const successorLaunchProfile = value.migration?.successorLaunchProfile && typeof value.migration.successorLaunchProfile === "object" && !Array.isArray(value.migration.successorLaunchProfile) ? emptyLaunchProfile(value.migration.successorLaunchProfile, policy) : null;
7067
7686
  const pendingContinuityPaths = Array.isArray(value.migration?.pendingContinuityPaths) ? value.migration.pendingContinuityPaths.filter((pathname) => typeof pathname === "string") : value.migration?.phase !== "committed" && providerReceipt ? [...new Set([...providerReceipt.continuityPaths, providerReceipt.path])] : [];
7068
7687
  const migration = value.migration && typeof value.migration === "object" ? {
7069
7688
  ...value.migration,
7070
7689
  errorCode: value.migration.errorCode ?? null,
7071
7690
  operationId: value.migration.operationId ?? `${value.migration.intentId}:${value.id}:${value.migration.revision}`,
7072
7691
  sourceGenerationId: value.migration.sourceGenerationId ?? current?.id ?? "",
7692
+ successorLaunchProfile,
7073
7693
  providerReceipt,
7074
7694
  pendingContinuityPaths,
7075
7695
  boardProject: typeof value.migration.boardProject === "string" ? value.migration.boardProject : null,
@@ -7671,13 +8291,13 @@ function commitPendingSupersedenceInFile(file) {
7671
8291
  }
7672
8292
  }
7673
8293
  function recordMembership(file, conversationId, input, createdAt) {
7674
- if (input.kind !== "flow" && input.kind !== "pipeline" || !input.containerId.trim() || !input.role.trim() || !input.slot.trim()) {
8294
+ if (input.kind !== "flow" && input.kind !== "pipeline" && input.kind !== "orchestrator" || !input.containerId.trim() || !input.role.trim() || !input.slot.trim()) {
7675
8295
  throw new Error("durable membership is invalid");
7676
8296
  }
7677
- const canonicalConversationId = resolveConversationAlias(file, conversationId);
8297
+ const canonicalConversationId2 = resolveConversationAlias(file, conversationId);
7678
8298
  const parentConversationId = input.parentConversationId ? resolveConversationAlias(file, input.parentConversationId) : null;
7679
8299
  const membership = {
7680
- conversationId: canonicalConversationId,
8300
+ conversationId: canonicalConversationId2,
7681
8301
  kind: input.kind,
7682
8302
  containerId: input.containerId,
7683
8303
  role: input.role,
@@ -7689,7 +8309,7 @@ function recordMembership(file, conversationId, input, createdAt) {
7689
8309
  runtime: input.runtime ? { ...input.runtime } : null,
7690
8310
  createdAt
7691
8311
  };
7692
- const rows = file.memberships[canonicalConversationId] ?? [];
8312
+ const rows = file.memberships[canonicalConversationId2] ?? [];
7693
8313
  const existing = rows.find((row) => row.kind === membership.kind && row.containerId === membership.containerId && row.slot === membership.slot);
7694
8314
  if (existing) {
7695
8315
  const immutableShape = ({ createdAt: createdAt2, ...row }) => {
@@ -7701,9 +8321,38 @@ function recordMembership(file, conversationId, input, createdAt) {
7701
8321
  return existing;
7702
8322
  }
7703
8323
  rows.push(membership);
7704
- file.memberships[canonicalConversationId] = rows;
8324
+ file.memberships[canonicalConversationId2] = rows;
7705
8325
  return membership;
7706
8326
  }
8327
+ function readOnlyConversationLookupFromSnapshot(snapshot2) {
8328
+ return snapshotConversationLookup(snapshot2, (conversation) => conversation);
8329
+ }
8330
+ function snapshotConversationLookup(snapshot2, materialize) {
8331
+ const byPath = new Map;
8332
+ for (const conversation of Object.values(snapshot2.conversations)) {
8333
+ for (const generation of conversation.generations) {
8334
+ if (!byPath.has(generation.path))
8335
+ byPath.set(generation.path, conversation);
8336
+ }
8337
+ for (const pathname of conversation.continuityPaths) {
8338
+ if (!byPath.has(pathname))
8339
+ byPath.set(pathname, conversation);
8340
+ }
8341
+ }
8342
+ return {
8343
+ conversationForPath(artifactPath) {
8344
+ const conversation = byPath.get(artifactPath);
8345
+ return conversation ? materialize(conversation) : null;
8346
+ },
8347
+ canonicalConversationId(id) {
8348
+ return resolveConversationAlias(snapshot2, id);
8349
+ },
8350
+ conversation(id) {
8351
+ const conversation = snapshot2.conversations[resolveConversationAlias(snapshot2, id)];
8352
+ return conversation ? materialize(conversation) : null;
8353
+ }
8354
+ };
8355
+ }
7707
8356
  function adoptProvisionalOwner(file, owner, target, pathname) {
7708
8357
  if (!scannerAllocatedProvisionalOwner(owner, pathname))
7709
8358
  return false;
@@ -7895,6 +8544,22 @@ function normalizeQueuedPinnedSpawn(value, policy) {
7895
8544
  pipelineSourceConversationId: typeof candidate.pipelineSourceConversationId === "string" && candidate.pipelineSourceConversationId.startsWith("conversation_") ? candidate.pipelineSourceConversationId : null
7896
8545
  };
7897
8546
  }
8547
+ function normalizePendingOrchestratorSeatIdentity(value) {
8548
+ if (!value || typeof value !== "object" || Array.isArray(value))
8549
+ return null;
8550
+ const seat = value;
8551
+ if (typeof seat.project !== "string" || !seat.project || !Number.isInteger(seat.seatEpoch) || (seat.seatEpoch ?? 0) < 1 || typeof seat.conversationId !== "string" || !seat.conversationId.startsWith("conversation_") || seat.predecessorConversationId !== null && typeof seat.predecessorConversationId !== "string" || typeof seat.designatedAt !== "string" || seat.activatedAt !== null && typeof seat.activatedAt !== "string")
8552
+ return null;
8553
+ return {
8554
+ project: seat.project,
8555
+ seatEpoch: seat.seatEpoch,
8556
+ conversationId: seat.conversationId,
8557
+ predecessorConversationId: seat.predecessorConversationId ?? null,
8558
+ designatedAt: seat.designatedAt,
8559
+ activatedAt: seat.activatedAt ?? null,
8560
+ path: typeof seat.path === "string" ? seat.path : null
8561
+ };
8562
+ }
7898
8563
  function normalizeReceipt(value, policy) {
7899
8564
  const state = value.state === "completed" || value.state === "failed" || value.state === "pane-bound" || value.state === "host-verified" || value.state === "prompt-delivered" || value.state === "path-pending" || value.state === "conflicted" ? value.state : "starting";
7900
8565
  const pane = value.pane && typeof value.pane === "object" && typeof value.pane.paneId === "string" && typeof value.pane.target === "string" ? { ...value.pane, display: typeof value.pane.display === "string" ? value.pane.display : value.pane.target, target: value.pane.paneId } : null;
@@ -7902,6 +8567,8 @@ function normalizeReceipt(value, policy) {
7902
8567
  ...value,
7903
8568
  clientAttemptId: typeof value.clientAttemptId === "string" ? value.clientAttemptId : null,
7904
8569
  requestDigest: typeof value.requestDigest === "string" ? value.requestDigest : null,
8570
+ ...value.identityWaveTitleBackfill === true ? { identityWaveTitleBackfill: true } : {},
8571
+ pendingOrchestratorSeatIdentity: normalizePendingOrchestratorSeatIdentity(value.pendingOrchestratorSeatIdentity),
7905
8572
  transport: value.transport === "tmux" || value.transport === "structured" ? value.transport : null,
7906
8573
  admissionOwner: value.admissionOwner && Number.isInteger(value.admissionOwner.pid) && value.admissionOwner.pid > 0 ? {
7907
8574
  pid: value.admissionOwner.pid,
@@ -8040,6 +8707,7 @@ function normalizeRegistry2(value, policy) {
8040
8707
  receipts: Object.fromEntries(Object.entries(parsed.receipts).map(([id, receipt]) => [id, normalizeReceipt(receipt, policy)])),
8041
8708
  lineageEdges: parsed.lineageEdges && typeof parsed.lineageEdges === "object" ? Object.fromEntries(Object.entries(parsed.lineageEdges).map(([id, edge]) => [id, normalizeLineageEdge(edge)])) : {},
8042
8709
  memberships: normalizeMemberships(parsed.memberships),
8710
+ identityMigrations: normalizeIdentityMigrations(parsed.identityMigrations),
8043
8711
  importedResumePanes: parsed.importedResumePanes === true,
8044
8712
  legacyResumePanes: legacy && typeof legacy === "object" && "panes" in legacy ? { serverPid: typeof legacy.serverPid === "number" ? legacy.serverPid : null, panes: legacy.panes ?? {} } : { serverPid: null, panes: {} },
8045
8713
  conversations: parsed.conversations && typeof parsed.conversations === "object" ? Object.fromEntries(Object.entries(parsed.conversations).map(([id, conversation]) => [id, normalizeConversation(conversation, policy)])) : {},
@@ -8779,8 +9447,22 @@ class AgentRegistry {
8779
9447
  if (sqlite && !changed)
8780
9448
  this.assertSqliteParity();
8781
9449
  if (sqlite && changed) {
8782
- this.beforeDualWriteMutationReplace?.();
8783
- const replacement = this.sqliteStore.replace(file, sqlite.revision);
9450
+ let replacement;
9451
+ try {
9452
+ this.beforeDualWriteMutationReplace?.();
9453
+ replacement = this.sqliteStore.replace(file, sqlite.revision);
9454
+ } catch (error) {
9455
+ const durableSqlite = this.sqliteStore.snapshot();
9456
+ if (durableSqlite.revision === sqlite.revision) {
9457
+ if (original.payload === null)
9458
+ writeAtomic(this.filename, original.file, sqlite.revision);
9459
+ else
9460
+ writeAtomicPayload(this.filename, original.payload);
9461
+ } else {
9462
+ this.mirrorSqliteSnapshot(durableSqlite);
9463
+ }
9464
+ throw error;
9465
+ }
8784
9466
  if (!replacement.replaced) {
8785
9467
  this.mirrorSqliteSnapshot(replacement);
8786
9468
  throw new RegistryParityError(`agent registry SQLite revision changed during dual-write mutation: expected ${sqlite.revision}, current ${replacement.revision}`);
@@ -8895,9 +9577,11 @@ class AgentRegistry {
8895
9577
  throw new Error("a conversation cannot supersede itself");
8896
9578
  }
8897
9579
  const existingConversation = conversationId ? file.conversations[conversationId] : null;
9580
+ const requestedTitle = input.launchProfile?.title;
8898
9581
  const requestedProfile = emptyLaunchProfile({
8899
9582
  cwd: input.cwd,
8900
9583
  ...input.launchProfile ?? {},
9584
+ title: durableSemanticTitle(requestedTitle),
8901
9585
  ...explicitProject ? { project: explicitProject } : {},
8902
9586
  parentConversationId
8903
9587
  });
@@ -8916,10 +9600,39 @@ class AgentRegistry {
8916
9600
  if (input.clientAttemptId) {
8917
9601
  const existing = Object.values(file.receipts).find((receipt2) => receipt2.clientAttemptId === input.clientAttemptId);
8918
9602
  if (existing) {
8919
- const compatible = existing.requestDigest === (input.requestDigest ?? null) && existing.engine === input.engine && existing.cwd === input.cwd && existing.transport === (input.transport ?? null) && existing.accountPin === (input.accountPin === true) && existing.explicitProject === explicitProject && (existing.supersedes?.conversationId ?? null) === supersedes && existing.launchProfile.permissionMode === profile.permissionMode;
9603
+ const existingTitle = durableSemanticTitle(existing.launchProfile.title);
9604
+ const requestedTitle2 = durableSemanticTitle(profile.title);
9605
+ const titleCompatible = !existingTitle || !requestedTitle2 || existingTitle === requestedTitle2;
9606
+ const compatible = existing.requestDigest === (input.requestDigest ?? null) && existing.engine === input.engine && existing.cwd === input.cwd && existing.transport === (input.transport ?? null) && existing.accountPin === (input.accountPin === true) && existing.explicitProject === explicitProject && (existing.supersedes?.conversationId ?? null) === supersedes && existing.launchProfile.permissionMode === profile.permissionMode && titleCompatible;
9607
+ if (compatible && !existingTitle && requestedTitle2) {
9608
+ existing.launchProfile.title = requestedTitle2;
9609
+ const existingConversationId = resolveConversationAlias(file, existing.conversationId);
9610
+ const titledConversation = file.conversations[existingConversationId];
9611
+ if (titledConversation) {
9612
+ const ownedPaths = new Set(titledConversation.generations.map((generation) => generation.path));
9613
+ for (const generation of titledConversation.generations) {
9614
+ if (!durableSemanticTitle(generation.launchProfile.title))
9615
+ generation.launchProfile.title = requestedTitle2;
9616
+ }
9617
+ for (const entry of Object.values(file.entries)) {
9618
+ if (ownedPaths.has(entry.artifactPath) && entry.launchProfile && !durableSemanticTitle(entry.launchProfile.title)) {
9619
+ entry.launchProfile.title = requestedTitle2;
9620
+ }
9621
+ }
9622
+ for (const receipt2 of Object.values(file.receipts)) {
9623
+ if (resolveConversationAlias(file, receipt2.conversationId) === existingConversationId && !durableSemanticTitle(receipt2.launchProfile.title)) {
9624
+ receipt2.launchProfile.title = requestedTitle2;
9625
+ }
9626
+ }
9627
+ titledConversation.updatedAt = now();
9628
+ file.conversationRevision[titledConversation.engine] += 1;
9629
+ }
9630
+ }
8920
9631
  return { kind: compatible ? "replay" : "conflict", receipt: clone(existing) };
8921
9632
  }
8922
9633
  }
9634
+ if (!durableSemanticTitle(profile.title))
9635
+ throw new Error(SPAWN_TITLE_REQUIRED_ERROR);
8923
9636
  const purpose = input.purpose ?? "launch";
8924
9637
  const successorIdentity = purpose !== "launch" || input.origin?.kind === "successor";
8925
9638
  const resolvedOrigin = !successorIdentity && input.origin ? resolveSpawnOrigin(file, input.origin) : null;
@@ -8979,6 +9692,7 @@ class AgentRegistry {
8979
9692
  launchId: crypto9.randomUUID(),
8980
9693
  clientAttemptId: input.clientAttemptId ?? null,
8981
9694
  requestDigest: input.requestDigest ?? null,
9695
+ pendingOrchestratorSeatIdentity: null,
8982
9696
  transport: input.transport ?? null,
8983
9697
  admissionOwner: input.transport === "structured" || input.ownStartingActuation === true ? { pid: process.pid, startIdentity: procBackend.processIdentity(process.pid) } : null,
8984
9698
  spawnCapabilityDigest: typeof input.spawnCapabilityDigest === "string" && /^[0-9a-f]{64}$/.test(input.spawnCapabilityDigest) ? input.spawnCapabilityDigest : null,
@@ -9147,6 +9861,29 @@ class AgentRegistry {
9147
9861
  rememberMembership(conversationId, membership) {
9148
9862
  return this.mutate((file) => clone(recordMembership(file, conversationId, membership, now())));
9149
9863
  }
9864
+ runIdentityWaveMigration(input) {
9865
+ if (input.dryRun) {
9866
+ return applyIdentityWaveMigration(clone(this.readOnlySnapshot()), { ...input, dryRun: true });
9867
+ }
9868
+ return withAccountMutationLock(() => this.mutate((file) => applyIdentityWaveMigration(file, input)));
9869
+ }
9870
+ stampOrchestratorSeatIdentity(seat) {
9871
+ return this.mutate((file) => {
9872
+ const stamped = stampOrchestratorLineage(file, seat, seat.activatedAt ?? seat.designatedAt);
9873
+ if (stamped.changed && stamped.engine)
9874
+ file.conversationRevision[stamped.engine] += 1;
9875
+ if (stamped.engine)
9876
+ return stamped.changed;
9877
+ const receipt = Object.values(file.receipts).find((candidate) => candidate.conversationId === seat.conversationId);
9878
+ if (!receipt)
9879
+ return false;
9880
+ const pending = normalizePendingOrchestratorSeatIdentity(seat);
9881
+ if (!pending || isDeepStrictEqual2(receipt.pendingOrchestratorSeatIdentity, pending))
9882
+ return false;
9883
+ receipt.pendingOrchestratorSeatIdentity = pending;
9884
+ return true;
9885
+ });
9886
+ }
9150
9887
  beginSpawn(engine, cwd, launchProfile = {}) {
9151
9888
  const result2 = this.beginSpawnRequest({ engine, cwd, launchProfile });
9152
9889
  if (result2.kind !== "created")
@@ -9405,6 +10142,13 @@ class AgentRegistry {
9405
10142
  file.conversationRevision[conversation.engine] += 1;
9406
10143
  file.engineRouting[conversation.engine].revision += 1;
9407
10144
  }
10145
+ const settledGeneration = conversation.generations.find((generation) => generation.path === entry.artifactPath);
10146
+ const receiptTitle = durableSemanticTitle(receipt.launchProfile.title, 120);
10147
+ if (settledGeneration && receiptTitle && !durableSemanticTitle(settledGeneration.launchProfile.title, 120)) {
10148
+ settledGeneration.launchProfile.title = receiptTitle;
10149
+ file.conversationRevision[conversation.engine] += 1;
10150
+ file.engineRouting[conversation.engine].revision += 1;
10151
+ }
9408
10152
  const activeIntent = Object.values(file.migrationIntents).find((intent) => intent.engine === conversation.engine && engineScopedIntent(intent) && migrationIntentCanEnroll(file, intent, Date.parse(createdAt)));
9409
10153
  const source = conversation.generations.at(-1);
9410
10154
  if (activeIntent && !conversation.pinnedAccountId && source && source.accountId !== activeIntent.targetId && !conversation.migration) {
@@ -9417,6 +10161,7 @@ class AgentRegistry {
9417
10161
  errorCode: null,
9418
10162
  operationId: crypto9.randomUUID(),
9419
10163
  sourceGenerationId: source.id,
10164
+ successorLaunchProfile: null,
9420
10165
  providerReceipt: null,
9421
10166
  pendingContinuityPaths: [],
9422
10167
  boardProject: null,
@@ -9436,6 +10181,13 @@ class AgentRegistry {
9436
10181
  file.entries[sessionKeyId(entry.key)] = full;
9437
10182
  receipt.key = entry.key;
9438
10183
  receipt.artifactPath = entry.artifactPath;
10184
+ if (receipt.pendingOrchestratorSeatIdentity) {
10185
+ const pendingSeat = receipt.pendingOrchestratorSeatIdentity;
10186
+ const stamped = stampOrchestratorLineage(file, pendingSeat, pendingSeat.activatedAt ?? pendingSeat.designatedAt);
10187
+ receipt.pendingOrchestratorSeatIdentity = null;
10188
+ if (stamped.changed && stamped.engine)
10189
+ file.conversationRevision[stamped.engine] += 1;
10190
+ }
9439
10191
  const lineage = file.lineageEdges[receipt.conversationId];
9440
10192
  if (lineage) {
9441
10193
  lineage.childSessionKey = entry.key;
@@ -9727,12 +10479,15 @@ class AgentRegistry {
9727
10479
  return clone(entry);
9728
10480
  });
9729
10481
  }
9730
- terminateStructuredHost(key2) {
10482
+ terminateStructuredHost(key2, expected) {
9731
10483
  return this.mutate((file) => {
9732
10484
  const keyId = sessionKeyId(key2);
9733
10485
  const entry = file.entries[keyId];
9734
10486
  if (!entry)
9735
10487
  return false;
10488
+ const current = entry.structuredHost?.process ?? null;
10489
+ if (expected && current && (current.pid !== expected.pid || current.startIdentity !== expected.startIdentity))
10490
+ return false;
9736
10491
  const replacement = {
9737
10492
  ...entry,
9738
10493
  host: null,
@@ -10107,7 +10862,10 @@ class AgentRegistry {
10107
10862
  id: nativeGenerationId(observation.path),
10108
10863
  path: observation.path,
10109
10864
  accountId: observation.accountId,
10110
- launchProfile: emptyLaunchProfile(observation.launchProfile),
10865
+ launchProfile: emptyLaunchProfile({
10866
+ ...observation.launchProfile,
10867
+ title: durableSemanticTitle(observation.launchProfile.title)
10868
+ }),
10111
10869
  historyHash: null,
10112
10870
  host: null,
10113
10871
  createdAt,
@@ -10152,7 +10910,7 @@ class AgentRegistry {
10152
10910
  permissionMode: generation.launchProfile.permissionMode ?? observation.launchProfile.permissionMode,
10153
10911
  readOnly: generation.launchProfile.readOnly ?? observation.launchProfile.readOnly,
10154
10912
  mcpServers: generation.launchProfile.mcpServers,
10155
- title: generation.launchProfile.title ?? observation.launchProfile.title,
10913
+ title: durableSemanticTitle(generation.launchProfile.title) ?? durableSemanticTitle(observation.launchProfile.title),
10156
10914
  project: observation.launchProfile.project ?? generation.launchProfile.project,
10157
10915
  parentConversationId: lineage?.source === "viewer-spawn" ? lineage.parentConversationId : observedParentConversationId ?? generation.launchProfile.parentConversationId,
10158
10916
  role: generation.launchProfile.role === "root" || observation.launchProfile.role === "root" ? "root" : "worker",
@@ -10668,6 +11426,7 @@ class AgentRegistry {
10668
11426
  errorCode: migration.errorCode ?? null,
10669
11427
  operationId: migration.operationId ?? `${migration.intentId}:${canonicalId3}:${migration.revision}`,
10670
11428
  sourceGenerationId: migration.sourceGenerationId ?? source?.id ?? "",
11429
+ successorLaunchProfile: migration.successorLaunchProfile ?? null,
10671
11430
  providerReceipt: migration.providerReceipt ?? null,
10672
11431
  pendingContinuityPaths: migration.pendingContinuityPaths ?? [],
10673
11432
  boardProject: migration.boardProject ?? null,
@@ -10809,6 +11568,7 @@ class AgentRegistry {
10809
11568
  revision: intent.revision,
10810
11569
  operationId: current.errorCode === "codex-fork-outcome-unknown" || current.revision === intent.revision ? current.operationId : crypto9.randomUUID(),
10811
11570
  sourceGenerationId: source.id,
11571
+ successorLaunchProfile: current.revision === intent.revision ? current.successorLaunchProfile ?? null : null,
10812
11572
  providerReceipt: null,
10813
11573
  pendingContinuityPaths: current.phase === "committed" ? [] : current.pendingContinuityPaths,
10814
11574
  boardProject: current.boardProject,
@@ -11347,9 +12107,11 @@ var STRUCTURED_CLAIM_PREFIX = "structured-host:", SpawnChildLimitError, Supersed
11347
12107
  var init_registry = __esm(() => {
11348
12108
  init_configDir();
11349
12109
  init_proc();
12110
+ init_title();
11350
12111
  init_accountMutation();
11351
12112
  init_contracts2();
11352
12113
  init_intentLiveness();
12114
+ init_identityWaveMigration();
11353
12115
  init_mcpAllowlist();
11354
12116
  init_accountLiveness();
11355
12117
  init_nestingPolicy();
@@ -11405,6 +12167,7 @@ var init_registry = __esm(() => {
11405
12167
  receipts: {},
11406
12168
  lineageEdges: {},
11407
12169
  memberships: {},
12170
+ identityMigrations: {},
11408
12171
  importedResumePanes: false,
11409
12172
  legacyResumePanes: { serverPid: null, panes: {} },
11410
12173
  conversations: {},
@@ -13403,8 +14166,10 @@ function projectIdentityFromDirectory(cwd) {
13403
14166
  if (!base || resolved === path24.sep)
13404
14167
  return null;
13405
14168
  const displayName = resolved === os7.homedir() ? `home-${base}` : base;
13406
- const digest = crypto12.createHash("sha256").update(`dir:${resolved}`).digest("hex").slice(0, 32);
13407
- return { project: `dir-${digest}`, displayName };
14169
+ return { project: directoryProjectId(resolved), displayName };
14170
+ }
14171
+ function directoryProjectId(resolvedPath) {
14172
+ return `dir-${crypto12.createHash("sha256").update(`dir:${resolvedPath}`).digest("hex").slice(0, 32)}`;
13408
14173
  }
13409
14174
  function displayNameFromProjectIdentity(project) {
13410
14175
  if (project === UNRESOLVED_PROJECT)
@@ -14448,11 +15213,26 @@ function claudeTasksRoot() {
14448
15213
  return legacyCandidate;
14449
15214
  return tmpdirCandidate;
14450
15215
  }
15216
+ function openclawStateDir() {
15217
+ const configured = process.env.OPENCLAW_STATE_DIR?.trim();
15218
+ return configured ? path27.resolve(configured) : path27.join(os8.homedir(), ".openclaw");
15219
+ }
15220
+ function openclawSessionRoots() {
15221
+ const agents = path27.join(openclawStateDir(), "agents");
15222
+ let entries;
15223
+ try {
15224
+ entries = fs28.readdirSync(agents, { withFileTypes: true });
15225
+ } catch {
15226
+ return [];
15227
+ }
15228
+ return entries.filter((entry) => (entry.isDirectory() || entry.isSymbolicLink()) && !entry.name.startsWith(".")).map((entry) => path27.join(agents, entry.name, "sessions")).sort();
15229
+ }
14451
15230
  function scanRootEntries() {
14452
15231
  const entries = [
14453
15232
  ...codexSessionRoots().map((root) => ["codex-sessions", root]),
14454
15233
  ...claudeProjectRoots().map((root) => ["claude-projects", root]),
14455
- ["claude-tasks", ROOTS["claude-tasks"]]
15234
+ ["claude-tasks", ROOTS["claude-tasks"]],
15235
+ ...openclawSessionRoots().map((root) => ["openclaw-sessions", root])
14456
15236
  ];
14457
15237
  const seen = new Set;
14458
15238
  return entries.filter(([, root]) => {
@@ -14498,7 +15278,8 @@ var init_roots = __esm(() => {
14498
15278
  ROOTS = {
14499
15279
  "codex-sessions": path27.join(HOME, ".codex/sessions"),
14500
15280
  "claude-projects": path27.join(HOME, ".claude/projects"),
14501
- "claude-tasks": claudeTasksRoot()
15281
+ "claude-tasks": claudeTasksRoot(),
15282
+ "openclaw-sessions": path27.join(HOME, ".openclaw/agents")
14502
15283
  };
14503
15284
  EXTS = [".log", ".jsonl", ".output", ".txt"];
14504
15285
  MAX_CHUNK = 768 * 1024;
@@ -14512,6 +15293,12 @@ var init_spawnParent = __esm(() => {
14512
15293
  init_roots();
14513
15294
  });
14514
15295
 
15296
+ // src/lib/board/types.ts
15297
+ var DEFAULT_BOARD_IDLE_COLLAPSE_MINUTES = 120, MAX_BOARD_IDLE_COLLAPSE_MINUTES;
15298
+ var init_types2 = __esm(() => {
15299
+ MAX_BOARD_IDLE_COLLAPSE_MINUTES = 30 * 24 * 60;
15300
+ });
15301
+
14515
15302
  // src/lib/board/keys.ts
14516
15303
  function resolveThrough(pathname, aliases) {
14517
15304
  const seen = new Set;
@@ -14570,11 +15357,15 @@ function boardKeysChanged(before, after) {
14570
15357
  keys.add(VIEW_MODE_KEY);
14571
15358
  if (before.prefs.taskPanelOpen !== after.prefs.taskPanelOpen)
14572
15359
  keys.add(TASK_PANEL_KEY);
15360
+ const beforeIdle = before.prefs.idleCollapseMinutes === undefined ? DEFAULT_BOARD_IDLE_COLLAPSE_MINUTES : before.prefs.idleCollapseMinutes;
15361
+ const afterIdle = after.prefs.idleCollapseMinutes === undefined ? DEFAULT_BOARD_IDLE_COLLAPSE_MINUTES : after.prefs.idleCollapseMinutes;
15362
+ if (beforeIdle !== afterIdle)
15363
+ keys.add(IDLE_COLLAPSE_KEY);
14573
15364
  return keys;
14574
15365
  }
14575
15366
  function liveBoardKeys(board) {
14576
15367
  const aliases = board.pathAliases ?? {};
14577
- const keys = new Set([VIEW_MODE_KEY, TASK_PANEL_KEY]);
15368
+ const keys = new Set([VIEW_MODE_KEY, TASK_PANEL_KEY, IDLE_COLLAPSE_KEY]);
14578
15369
  for (const canonical of canonicalPlacements(board, aliases).keys())
14579
15370
  keys.add(pathKey(canonical));
14580
15371
  for (const id of board.prefs.favorites ?? [])
@@ -14625,12 +15416,17 @@ function stampKeyRevisions(before, after, revision, inherited = []) {
14625
15416
  }
14626
15417
  return { keyRevisions, keyRevisionFloor };
14627
15418
  }
14628
- var VIEW_MODE_KEY = "viewMode", TASK_PANEL_KEY = "taskPanelOpen", PATH_PREFIX = "path:", pathKey = (pathname) => `${PATH_PREFIX}${pathname}`, favoriteKey = (id) => `favorite:${id}`, foldKey = (id) => `fold:${id}`, trayKey = (parentId) => `tray:${parentId}`, ROLE_RANK, MAX_RETIRED_KEY_REVISIONS = 512;
15419
+ var VIEW_MODE_KEY = "viewMode", TASK_PANEL_KEY = "taskPanelOpen", IDLE_COLLAPSE_KEY = "idleCollapseMinutes", PATH_PREFIX = "path:", pathKey = (pathname) => `${PATH_PREFIX}${pathname}`, favoriteKey = (id) => `favorite:${id}`, foldKey = (id) => `fold:${id}`, trayKey = (parentId) => `tray:${parentId}`, ROLE_RANK, MAX_RETIRED_KEY_REVISIONS = 512;
14629
15420
  var init_keys = __esm(() => {
15421
+ init_types2();
14630
15422
  ROLE_RANK = { absent: 0, manual: 1, pinned: 2, expanded: 3, hidden: 4 };
14631
15423
  });
14632
15424
 
14633
15425
  // src/lib/board/mutations.ts
15426
+ function boundedSeenAt(stamps) {
15427
+ const entries = Object.entries(stamps).sort((left, right) => right[1] - left[1]);
15428
+ return Object.fromEntries(entries.slice(0, MAX_SEEN_STAMPS));
15429
+ }
14634
15430
  function unique(paths) {
14635
15431
  return [...new Set(paths)];
14636
15432
  }
@@ -14675,7 +15471,9 @@ function normalize2(board, aliases = aliasesOf(board)) {
14675
15471
  expanded: visible(board.prefs.expanded),
14676
15472
  favorites: unique(board.prefs.favorites ?? []),
14677
15473
  foldedEngineChildIds: unique(board.prefs.foldedEngineChildIds ?? []),
14678
- expandedEngineTrayParentIds: unique(board.prefs.expandedEngineTrayParentIds ?? [])
15474
+ expandedEngineTrayParentIds: unique(board.prefs.expandedEngineTrayParentIds ?? []),
15475
+ seenAt: boundedSeenAt(board.prefs.seenAt ?? {}),
15476
+ idleCollapseMinutes: board.prefs.idleCollapseMinutes === undefined ? DEFAULT_BOARD_IDLE_COLLAPSE_MINUTES : board.prefs.idleCollapseMinutes
14679
15477
  }
14680
15478
  };
14681
15479
  }
@@ -14765,6 +15563,12 @@ function applyBoardMutations(board, mutations) {
14765
15563
  next = normalize2({ ...next, prefs: { ...next.prefs, favorites } });
14766
15564
  continue;
14767
15565
  }
15566
+ if (mutation.kind === "mark-seen") {
15567
+ const current = next.prefs.seenAt ?? {};
15568
+ const at = Math.max(current[mutation.id] ?? 0, Math.floor(mutation.at));
15569
+ next = normalize2({ ...next, prefs: { ...next.prefs, seenAt: { ...current, [mutation.id]: at } } });
15570
+ continue;
15571
+ }
14768
15572
  if (mutation.kind === "set-engine-child-fold") {
14769
15573
  const currentFolded = next.prefs.foldedEngineChildIds ?? [];
14770
15574
  const foldedEngineChildIds = mutation.folded ? unique([...currentFolded, mutation.id]) : currentFolded.filter((item) => item !== mutation.id);
@@ -14793,7 +15597,8 @@ function applyBoardMutations(board, mutations) {
14793
15597
  prefs: {
14794
15598
  ...next.prefs,
14795
15599
  ...mutation.viewMode === undefined ? {} : { viewMode: mutation.viewMode },
14796
- ...mutation.taskPanelOpen === undefined ? {} : { taskPanelOpen: mutation.taskPanelOpen }
15600
+ ...mutation.taskPanelOpen === undefined ? {} : { taskPanelOpen: mutation.taskPanelOpen },
15601
+ ...mutation.idleCollapseMinutes === undefined ? {} : { idleCollapseMinutes: mutation.idleCollapseMinutes }
14797
15602
  }
14798
15603
  });
14799
15604
  continue;
@@ -14812,6 +15617,10 @@ function applyBoardMutations(board, mutations) {
14812
15617
  }
14813
15618
  return preserveDurableHiddenSpellings(board, next);
14814
15619
  }
15620
+ var MAX_SEEN_STAMPS = 512;
15621
+ var init_mutations = __esm(() => {
15622
+ init_types2();
15623
+ });
14815
15624
 
14816
15625
  // src/lib/board/store.ts
14817
15626
  import crypto15 from "crypto";
@@ -14825,6 +15634,11 @@ function aliases(value) {
14825
15634
  return false;
14826
15635
  return Object.values(value).every((item) => typeof item === "string");
14827
15636
  }
15637
+ function seenStamps(value) {
15638
+ if (!value || typeof value !== "object" || Array.isArray(value))
15639
+ return false;
15640
+ return Object.values(value).every((item) => typeof item === "number" && Number.isFinite(item) && item >= 0);
15641
+ }
14828
15642
  function keyRevisions(value) {
14829
15643
  if (!value || typeof value !== "object" || Array.isArray(value))
14830
15644
  return false;
@@ -14835,7 +15649,15 @@ function projectState(value) {
14835
15649
  return false;
14836
15650
  const state = value;
14837
15651
  const prefs = state.prefs;
14838
- return state.schemaVersion === 1 && Number.isInteger(state.revision) && state.revision >= 0 && typeof state.updatedAt === "string" && Boolean(prefs) && stringArray2(prefs.manual) && stringArray2(prefs.hidden) && stringArray2(prefs.expanded) && (prefs.favorites === undefined || stringArray2(prefs.favorites)) && (prefs.foldedEngineChildIds === undefined || stringArray2(prefs.foldedEngineChildIds)) && (prefs.expandedEngineTrayParentIds === undefined || stringArray2(prefs.expandedEngineTrayParentIds)) && (state.explicitManual === undefined || stringArray2(state.explicitManual)) && (state.pathAliases === undefined || aliases(state.pathAliases)) && (state.keyRevisions === undefined || keyRevisions(state.keyRevisions)) && (state.keyRevisionFloor === undefined || Number.isInteger(state.keyRevisionFloor) && state.keyRevisionFloor >= 0) && (prefs.viewMode === null || prefs.viewMode === "scheme" || prefs.viewMode === "list") && typeof prefs.taskPanelOpen === "boolean";
15652
+ return state.schemaVersion === 1 && Number.isInteger(state.revision) && state.revision >= 0 && typeof state.updatedAt === "string" && Boolean(prefs) && stringArray2(prefs.manual) && stringArray2(prefs.hidden) && stringArray2(prefs.expanded) && (prefs.favorites === undefined || stringArray2(prefs.favorites)) && (prefs.foldedEngineChildIds === undefined || stringArray2(prefs.foldedEngineChildIds)) && (prefs.expandedEngineTrayParentIds === undefined || stringArray2(prefs.expandedEngineTrayParentIds)) && (prefs.seenAt === undefined || seenStamps(prefs.seenAt)) && (prefs.idleCollapseMinutes === undefined || prefs.idleCollapseMinutes === null || Number.isInteger(prefs.idleCollapseMinutes) && prefs.idleCollapseMinutes > 0 && prefs.idleCollapseMinutes <= MAX_BOARD_IDLE_COLLAPSE_MINUTES) && (state.explicitManual === undefined || stringArray2(state.explicitManual)) && (state.pathAliases === undefined || aliases(state.pathAliases)) && (state.keyRevisions === undefined || keyRevisions(state.keyRevisions)) && (state.keyRevisionFloor === undefined || Number.isInteger(state.keyRevisionFloor) && state.keyRevisionFloor >= 0) && (prefs.viewMode === null || prefs.viewMode === "scheme" || prefs.viewMode === "list") && typeof prefs.taskPanelOpen === "boolean";
15653
+ }
15654
+ function mergeSeenAt(maps) {
15655
+ const merged = {};
15656
+ for (const map of maps) {
15657
+ for (const [id, at] of Object.entries(map ?? {}))
15658
+ merged[id] = Math.max(merged[id] ?? 0, at);
15659
+ }
15660
+ return merged;
14839
15661
  }
14840
15662
  function emptyBoard() {
14841
15663
  return { schemaVersion: 1, revision: 0, updatedAt: new Date(0).toISOString(), pathAliases: {}, explicitManual: [], keyRevisions: {}, keyRevisionFloor: 0, prefs: { ...EMPTY_PREFS, manual: [], hidden: [], expanded: [] } };
@@ -14870,7 +15692,9 @@ function read(filePath) {
14870
15692
  ...state.prefs,
14871
15693
  favorites: state.prefs.favorites ?? [],
14872
15694
  foldedEngineChildIds: state.prefs.foldedEngineChildIds ?? [],
14873
- expandedEngineTrayParentIds: state.prefs.expandedEngineTrayParentIds ?? []
15695
+ expandedEngineTrayParentIds: state.prefs.expandedEngineTrayParentIds ?? [],
15696
+ seenAt: state.prefs.seenAt ?? {},
15697
+ idleCollapseMinutes: state.prefs.idleCollapseMinutes === undefined ? DEFAULT_BOARD_IDLE_COLLAPSE_MINUTES : state.prefs.idleCollapseMinutes
14874
15698
  }
14875
15699
  }])) };
14876
15700
  } catch (error) {
@@ -15111,6 +15935,7 @@ function mergedBoards(states) {
15111
15935
  favorites: [...new Set(ordered.flatMap((state) => state.prefs.favorites ?? []))],
15112
15936
  foldedEngineChildIds: [...new Set(ordered.flatMap((state) => state.prefs.foldedEngineChildIds ?? []))],
15113
15937
  expandedEngineTrayParentIds: [...new Set(ordered.flatMap((state) => state.prefs.expandedEngineTrayParentIds ?? []))],
15938
+ seenAt: mergeSeenAt(ordered.map((state) => state.prefs.seenAt)),
15114
15939
  viewMode,
15115
15940
  taskPanelOpen
15116
15941
  };
@@ -15169,8 +15994,10 @@ var init_store3 = __esm(() => {
15169
15994
  init_proc();
15170
15995
  init_aliases();
15171
15996
  init_keys();
15997
+ init_mutations();
15998
+ init_types2();
15172
15999
  BOARD_FILE = statePath("board.json");
15173
- EMPTY_PREFS = { manual: [], hidden: [], expanded: [], favorites: [], foldedEngineChildIds: [], expandedEngineTrayParentIds: [], viewMode: null, taskPanelOpen: false };
16000
+ EMPTY_PREFS = { manual: [], hidden: [], expanded: [], favorites: [], foldedEngineChildIds: [], expandedEngineTrayParentIds: [], seenAt: {}, idleCollapseMinutes: DEFAULT_BOARD_IDLE_COLLAPSE_MINUTES, viewMode: null, taskPanelOpen: false };
15174
16001
  BoardStoreError = class BoardStoreError extends Error {
15175
16002
  constructor(message = "board state unavailable") {
15176
16003
  super(message);
@@ -15246,6 +16073,9 @@ function argvEngine(argv) {
15246
16073
  }
15247
16074
  return null;
15248
16075
  }
16076
+ function structuredHostStamp() {
16077
+ return statePath();
16078
+ }
15249
16079
  function isHelperArgv(argv) {
15250
16080
  return argv.some((token) => HELPER_ARGS.has(token));
15251
16081
  }
@@ -15268,8 +16098,9 @@ function agentProcesses(fresh = false) {
15268
16098
  agentMemo = { at: now2, list };
15269
16099
  return list;
15270
16100
  }
15271
- var HOLDERS_TTL_MS = 12000, MAX_PATH_HOLDER_CANDIDATES = 256, outputMemo = null, pathMemo = null, agentMemo = null, HELPER_ARGS;
16101
+ var HOLDERS_TTL_MS = 12000, MAX_PATH_HOLDER_CANDIDATES = 256, outputMemo = null, pathMemo = null, agentMemo = null, STRUCTURED_HOST_STAMP_ENV = "LLV_STRUCTURED_HOST", HELPER_ARGS;
15272
16102
  var init_process = __esm(() => {
16103
+ init_configDir();
15273
16104
  init_proc();
15274
16105
  init_roots();
15275
16106
  HELPER_ARGS = new Set(["daemon", "--bg-pty-host", "--bg-spare"]);
@@ -15321,6 +16152,27 @@ var init_json = __esm(() => {
15321
16152
  jsonCache = globalCache("json-v3");
15322
16153
  });
15323
16154
 
16155
+ // src/lib/scanner/openclawNative.ts
16156
+ function isOpenclawTranscript(basename) {
16157
+ if (!basename.endsWith(".jsonl"))
16158
+ return false;
16159
+ return !NON_TRANSCRIPT_SEGMENTS.some((segment) => basename.includes(segment));
16160
+ }
16161
+ function openclawMessage(record3) {
16162
+ return record3.type === "message" ? recordValue(record3.message) : null;
16163
+ }
16164
+ function openclawProviderAssistant(record3) {
16165
+ const message = openclawMessage(record3);
16166
+ if (!message || message.role !== "assistant")
16167
+ return null;
16168
+ return stringValue(message.provider) === OPENCLAW_SYNTHETIC_PROVIDER ? null : message;
16169
+ }
16170
+ var OPENCLAW_SYNTHETIC_PROVIDER = "openclaw", NON_TRANSCRIPT_SEGMENTS;
16171
+ var init_openclawNative = __esm(() => {
16172
+ init_json();
16173
+ NON_TRANSCRIPT_SEGMENTS = [".trajectory.", ".checkpoint.", ".acp-stream.", ".deleted.", ".bak"];
16174
+ });
16175
+
15324
16176
  // src/lib/accounts/migration/turnState.ts
15325
16177
  function timestamp2(record3) {
15326
16178
  const value = record3.timestamp;
@@ -15370,8 +16222,30 @@ function claudeRecoveryTailRelease(records) {
15370
16222
  }
15371
16223
  return null;
15372
16224
  }
15373
- function turnStateFromRecords(records, codex, authoritative = false) {
15374
- if (codex) {
16225
+ function openclawTurnState(records) {
16226
+ for (let index = records.length - 1;index >= 0; index -= 1) {
16227
+ const record3 = records[index];
16228
+ const message = openclawMessage(record3);
16229
+ if (!message)
16230
+ continue;
16231
+ if (message.role === "assistant") {
16232
+ if (!openclawProviderAssistant(record3))
16233
+ continue;
16234
+ const stop = stringValue(message.stopReason);
16235
+ if (stop === "stop" || stop === "error" || stop === "aborted") {
16236
+ return { state: "terminal", source: "lifecycle", terminalAt: timestamp2(record3) };
16237
+ }
16238
+ return { state: "busy", source: "assistant", terminalAt: null };
16239
+ }
16240
+ if (message.role === "user")
16241
+ return { state: "busy", source: "lifecycle", terminalAt: null };
16242
+ }
16243
+ return { state: "unknown", source: "empty", terminalAt: null };
16244
+ }
16245
+ function turnStateFromRecords(records, engine, authoritative = false) {
16246
+ if (engine === "openclaw")
16247
+ return openclawTurnState(records);
16248
+ if (engine === "codex") {
15375
16249
  let turnOpen = false;
15376
16250
  let terminalAt = null;
15377
16251
  let terminalSeen = false;
@@ -15461,6 +16335,7 @@ function turnStateFromRecords(records, codex, authoritative = false) {
15461
16335
  }
15462
16336
  var TERMINAL_API_ERRORS, SYNTHETIC_NO_OP_TEXT, INTERRUPT_SENTINEL_TEXT;
15463
16337
  var init_turnState = __esm(() => {
16338
+ init_openclawNative();
15464
16339
  init_json();
15465
16340
  TERMINAL_API_ERRORS = new Set(["authentication_failed", "rate_limit"]);
15466
16341
  SYNTHETIC_NO_OP_TEXT = /^no response requested\.?$/i;
@@ -15519,15 +16394,22 @@ function storeTurnEvidence(pathname, evidence) {
15519
16394
  }
15520
16395
  turnEvidenceCache.set(key2, evidence);
15521
16396
  }
15522
- function recoveryRelease(turn, records, codex, authoritative) {
15523
- if (codex || !authoritative || turn.state !== "terminal")
16397
+ function recoveryRelease(turn, records, engine, authoritative) {
16398
+ if (engine !== "claude" || !authoritative || turn.state !== "terminal")
15524
16399
  return false;
15525
16400
  return claudeRecoveryTailRelease(records) !== null;
15526
16401
  }
15527
- function transcriptTurnResult(pathname, size, mtimeMs, codex, authoritative = true) {
16402
+ function transcriptEngineForRoot(root) {
16403
+ if (root === "codex-sessions")
16404
+ return "codex";
16405
+ if (root === "openclaw-sessions")
16406
+ return "openclaw";
16407
+ return "claude";
16408
+ }
16409
+ function transcriptTurnResult(pathname, size, mtimeMs, engine, authoritative = true) {
15528
16410
  const key2 = `${authoritative ? "authoritative" : "activity"}:${pathname}`;
15529
16411
  const cached3 = turnEvidenceCache.get(key2);
15530
- if (cached3 && cached3.size === size && cached3.mtimeMs === mtimeMs && cached3.codex === codex) {
16412
+ if (cached3 && cached3.size === size && cached3.mtimeMs === mtimeMs && cached3.engine === engine) {
15531
16413
  storeTurnEvidence(pathname, cached3);
15532
16414
  return {
15533
16415
  turn: { ...cached3.turn },
@@ -15537,31 +16419,31 @@ function transcriptTurnResult(pathname, size, mtimeMs, codex, authoritative = tr
15537
16419
  };
15538
16420
  }
15539
16421
  const tail = tailRecordsResult(pathname, size, mtimeMs);
15540
- const turn = turnStateFromRecords(tail.records, codex, authoritative);
15541
- const recoveryReleased = tail.complete && recoveryRelease(turn, tail.records, codex, authoritative);
16422
+ const turn = turnStateFromRecords(tail.records, engine, authoritative);
16423
+ const recoveryReleased = tail.complete && recoveryRelease(turn, tail.records, engine, authoritative);
15542
16424
  if (tail.complete) {
15543
- storeTurnEvidence(pathname, { size, mtimeMs, codex, authoritative, turn, composerReleased: false, recoveryReleased });
16425
+ storeTurnEvidence(pathname, { size, mtimeMs, engine, authoritative, turn, composerReleased: false, recoveryReleased });
15544
16426
  const companionAuthoritative = !authoritative;
15545
16427
  const companionKey = `${companionAuthoritative ? "authoritative" : "activity"}:${pathname}`;
15546
16428
  const cachedCompanion = turnEvidenceCache.get(companionKey);
15547
- const companionComposerReleased = cachedCompanion?.size === size && cachedCompanion.mtimeMs === mtimeMs && cachedCompanion.codex === codex && cachedCompanion.composerReleased;
15548
- const companionTurn = turnStateFromRecords(tail.records, codex, companionAuthoritative);
16429
+ const companionComposerReleased = cachedCompanion?.size === size && cachedCompanion.mtimeMs === mtimeMs && cachedCompanion.engine === engine && cachedCompanion.composerReleased;
16430
+ const companionTurn = turnStateFromRecords(tail.records, engine, companionAuthoritative);
15549
16431
  storeTurnEvidence(pathname, {
15550
16432
  size,
15551
16433
  mtimeMs,
15552
- codex,
16434
+ engine,
15553
16435
  authoritative: companionAuthoritative,
15554
16436
  turn: companionTurn,
15555
16437
  composerReleased: companionComposerReleased,
15556
- recoveryReleased: recoveryRelease(companionTurn, tail.records, codex, companionAuthoritative)
16438
+ recoveryReleased: recoveryRelease(companionTurn, tail.records, engine, companionAuthoritative)
15557
16439
  });
15558
16440
  }
15559
16441
  return { turn, complete: tail.complete, composerReleased: false, recoveryReleased };
15560
16442
  }
15561
- function cachedTranscriptTurn(pathname, size, mtimeMs, codex) {
16443
+ function cachedTranscriptTurn(pathname, size, mtimeMs, engine) {
15562
16444
  for (const key2 of [`activity:${pathname}`, `authoritative:${pathname}`]) {
15563
16445
  const cached3 = turnEvidenceCache.get(key2);
15564
- if (cached3 && cached3.size === size && cached3.mtimeMs === mtimeMs && cached3.codex === codex) {
16446
+ if (cached3 && cached3.size === size && cached3.mtimeMs === mtimeMs && cached3.engine === engine) {
15565
16447
  return { ...cached3.turn };
15566
16448
  }
15567
16449
  }
@@ -15637,7 +16519,7 @@ function activityVerdict(root, pathname, mtime, size) {
15637
16519
  let complete = true;
15638
16520
  if (pathname.endsWith(".jsonl")) {
15639
16521
  const mtimeMs = mtime * 1000;
15640
- const turn = transcriptTurnResult(pathname, size, mtimeMs, root.startsWith("codex"), false);
16522
+ const turn = transcriptTurnResult(pathname, size, mtimeMs, transcriptEngineForRoot(root), false);
15641
16523
  const state = turn.turn.state === "terminal" ? "done" : turn.turn.state === "busy" ? "busy" : null;
15642
16524
  complete = turn.complete;
15643
16525
  if (state === "busy") {
@@ -15661,7 +16543,8 @@ var init_activity = __esm(() => {
15661
16543
  init_turnState();
15662
16544
  globalCache("turn").clear();
15663
16545
  globalCache("turn-evidence-v1").clear();
15664
- turnEvidenceCache = globalCache("turn-evidence-v2");
16546
+ globalCache("turn-evidence-v2").clear();
16547
+ turnEvidenceCache = globalCache("turn-evidence-v3");
15665
16548
  tailCache = globalCache("tail-v3");
15666
16549
  headCache2 = globalCache("head-records-v2");
15667
16550
  HEAD_CACHE_BYTE_CAP2 = 16 * 1024 * 1024;
@@ -15974,12 +16857,7 @@ function runtimeSettingsCapability(engine) {
15974
16857
  return { perTurnEffort: engine === "codex", perTurnModel: false };
15975
16858
  }
15976
16859
  function runtimeCompactCapability(engine) {
15977
- return engine === "codex" ? { control: "compact", engine, supported: true } : {
15978
- control: "compact",
15979
- engine,
15980
- supported: false,
15981
- reason: "The Claude stream-json protocol has no client-originated compact control; only interrupt is exposed."
15982
- };
16860
+ return engine === "codex" ? { control: "compact", engine, supported: true, confirmation: "observed" } : { control: "compact", engine, supported: true, confirmation: "best-effort" };
15983
16861
  }
15984
16862
  function canonicalRuntimeKind(kind) {
15985
16863
  return KIND_ALIASES[kind] ?? kind;
@@ -16418,7 +17296,6 @@ var init_compactText = __esm(() => {
16418
17296
  init_review();
16419
17297
  SCAN_BYTES = 1024 * 1024;
16420
17298
  });
16421
-
16422
17299
  // src/lib/runtime/voiceDelivery.ts
16423
17300
  function record3(value) {
16424
17301
  return value && typeof value === "object" && !Array.isArray(value) ? value : null;
@@ -16875,11 +17752,22 @@ class FileRuntimeEventStore {
16875
17752
  return path31.join(this.directory, `${encodeURIComponent(threadId)}.jsonl`);
16876
17753
  }
16877
17754
  }
16878
- var MAX_CACHED_LEDGER_BYTES, MAX_CACHED_LEDGERS = 64, eventStoreGlobals, MAX_DIAGNOSTIC_SESSION_ID_LENGTH = 160;
17755
+ var MAX_CACHED_LEDGER_BYTES, MAX_CACHED_LEDGERS = 64, eventStoreGlobals, MAX_DIAGNOSTIC_SESSION_ID_LENGTH = 160, EVENT_TAIL_STEP_BYTES, EVENT_TAIL_MAX_RECORD_BYTES;
16879
17756
  var init_eventStore = __esm(() => {
16880
17757
  init_configDir();
16881
17758
  MAX_CACHED_LEDGER_BYTES = 64 * 1024 * 1024;
16882
17759
  eventStoreGlobals = globalThis;
17760
+ EVENT_TAIL_STEP_BYTES = 64 * 1024;
17761
+ EVENT_TAIL_MAX_RECORD_BYTES = 32 * 1024 * 1024;
17762
+ });
17763
+
17764
+ // src/lib/runtime/hostActivityFlags.ts
17765
+ var NATIVE_MULTI_AGENT_DENY_FLAG, CAPABILITY_FLAGS;
17766
+ var init_hostActivityFlags = __esm(() => {
17767
+ init_spawnPolicy();
17768
+ init_structuredContent();
17769
+ NATIVE_MULTI_AGENT_DENY_FLAG = `native-multi-agent-deny:${NATIVE_MULTI_AGENT_TOOLS.join(",")}`;
17770
+ CAPABILITY_FLAGS = new Set([STRUCTURED_IMAGE_CAPABILITY]);
16883
17771
  });
16884
17772
 
16885
17773
  // src/lib/runtime/runtimeImageStore.ts
@@ -17909,6 +18797,7 @@ function subscriptionEnv(source, claudeConfigDir, forwardGitHubConfig = false) {
17909
18797
  env.GH_CONFIG_DIR = source.GH_CONFIG_DIR;
17910
18798
  if (claudeConfigDir)
17911
18799
  env.CLAUDE_CONFIG_DIR = claudeConfigDir;
18800
+ env[STRUCTURED_HOST_STAMP_ENV] = structuredHostStamp();
17912
18801
  return env;
17913
18802
  }
17914
18803
  function claudeCliProbe(binary, args, cwd, env) {
@@ -18069,10 +18958,13 @@ class ClaudeStreamBrokerHost {
18069
18958
  eventStore;
18070
18959
  deliveryLedger;
18071
18960
  readImage;
18961
+ compactEvidenceTimeoutMs;
18072
18962
  requestTimeoutMs;
18073
18963
  shutdownGraceMs;
18074
18964
  onEventCursorRecovery;
18075
18965
  signalProcess;
18966
+ processIdentity;
18967
+ childStartIdentity;
18076
18968
  subscribers = new Set;
18077
18969
  events = [];
18078
18970
  deliveries = [];
@@ -18080,6 +18972,7 @@ class ClaudeStreamBrokerHost {
18080
18972
  attentions = new Map;
18081
18973
  pendingControls = new Map;
18082
18974
  pendingAnswers = new Map;
18975
+ compactions = new Map;
18083
18976
  interruptedTurns = new Set;
18084
18977
  partialTurns = new Set;
18085
18978
  pendingDeliveries = new Map;
@@ -18102,6 +18995,7 @@ class ClaudeStreamBrokerHost {
18102
18995
  releaseCleanup;
18103
18996
  terminationTimer = null;
18104
18997
  terminationStarted = false;
18998
+ releaseFence = null;
18105
18999
  reapedPromise;
18106
19000
  resolveReaped;
18107
19001
  launchFlags;
@@ -18111,10 +19005,13 @@ class ClaudeStreamBrokerHost {
18111
19005
  this.eventStore = options.eventStore ?? new FileRuntimeEventStore;
18112
19006
  this.deliveryLedger = options.deliveryLedger ?? new FileClaudeDeliveryLedger;
18113
19007
  this.readImage = options.readImage ?? ((ref) => runtimeImageStore().read(ref));
19008
+ this.compactEvidenceTimeoutMs = options.compactEvidenceTimeoutMs ?? DEFAULT_COMPACT_EVIDENCE_TIMEOUT_MS;
18114
19009
  this.requestTimeoutMs = options.requestTimeoutMs ?? DEFAULT_TIMEOUT_MS2;
18115
19010
  this.shutdownGraceMs = options.shutdownGraceMs ?? DEFAULT_SHUTDOWN_GRACE_MS2;
18116
19011
  this.onEventCursorRecovery = options.onEventCursorRecovery;
18117
19012
  this.signalProcess = options.signalProcess ?? process.kill;
19013
+ this.processIdentity = options.processIdentity ?? ((pid) => procBackend.processIdentity(pid));
19014
+ this.childStartIdentity = child.pid ? this.processIdentity(child.pid) : null;
18118
19015
  this.releaseCleanup = options.releaseCleanup ?? null;
18119
19016
  this.cursor = options.initialEventCursor ?? 0;
18120
19017
  this.protocolVersion = auth.version ?? null;
@@ -18375,6 +19272,66 @@ class ClaudeStreamBrokerHost {
18375
19272
  this.write({ type: "control_request", request_id: requestId, request: { subtype: "interrupt" } });
18376
19273
  });
18377
19274
  }
19275
+ async compact(request) {
19276
+ const existing = this.compactions.get(request.operationId);
19277
+ if (existing)
19278
+ return existing.promise;
19279
+ if (this.unavailable())
19280
+ throw new StructuredCompactError("Claude stream host is unavailable", "refused");
19281
+ if (request.threadId && request.threadId !== this.identity.sessionId) {
19282
+ throw new StructuredCompactError("compact target session is not the session this host owns", "refused");
19283
+ }
19284
+ if (this.activeTurnId) {
19285
+ throw new StructuredCompactError("a turn is active; compaction would race it", "refused");
19286
+ }
19287
+ if ([...this.compactions.values()].some((compaction2) => !compaction2.settled)) {
19288
+ throw new StructuredCompactError("a compaction is already running on this conversation", "refused");
19289
+ }
19290
+ let resolveOutcome;
19291
+ let rejectOutcome;
19292
+ const promise = new Promise((resolve, reject) => {
19293
+ resolveOutcome = resolve;
19294
+ rejectOutcome = reject;
19295
+ });
19296
+ const compaction = {
19297
+ promise,
19298
+ resolve: (outcome) => resolveOutcome(outcome),
19299
+ reject: (error) => rejectOutcome(error),
19300
+ settled: false,
19301
+ timer: null
19302
+ };
19303
+ this.compactions.set(request.operationId, compaction);
19304
+ promise.catch(() => {
19305
+ return;
19306
+ });
19307
+ this.write({
19308
+ type: "user",
19309
+ session_id: this.identity.sessionId,
19310
+ message: { role: "user", content: [{ type: "text", text: CLAUDE_COMPACT_COMMAND }] }
19311
+ });
19312
+ compaction.timer = setTimeout(() => {
19313
+ this.settleCompaction(compaction, new StructuredCompactError(CLAUDE_COMPACT_UNOBSERVED_REASON, "unverified"));
19314
+ }, this.compactEvidenceTimeoutMs);
19315
+ return promise;
19316
+ }
19317
+ settleCompaction(compaction, outcome) {
19318
+ if (compaction.settled)
19319
+ return;
19320
+ compaction.settled = true;
19321
+ if (compaction.timer)
19322
+ clearTimeout(compaction.timer);
19323
+ compaction.timer = null;
19324
+ if (outcome instanceof StructuredCompactError)
19325
+ compaction.reject(outcome);
19326
+ else
19327
+ compaction.resolve(outcome);
19328
+ }
19329
+ settlePendingCompactions(outcome) {
19330
+ for (const compaction of this.compactions.values()) {
19331
+ if (!compaction.settled)
19332
+ this.settleCompaction(compaction, outcome);
19333
+ }
19334
+ }
18378
19335
  async answer(attentionRef, value) {
18379
19336
  if (this.unavailable())
18380
19337
  throw new Error("Claude stream host is unavailable");
@@ -18426,6 +19383,19 @@ class ClaudeStreamBrokerHost {
18426
19383
  }
18427
19384
  return this.releasePromise;
18428
19385
  }
19386
+ async releaseIfOwned(expected) {
19387
+ const pid = this.child.pid;
19388
+ if (this.released || this.releasing || this.releasePromise !== null || !pid || expected.startIdentity === null || pid !== expected.pid || this.childStartIdentity !== expected.startIdentity || this.processIdentity(pid) !== expected.startIdentity)
19389
+ return false;
19390
+ this.releaseFence = expected;
19391
+ try {
19392
+ await this.release();
19393
+ return true;
19394
+ } finally {
19395
+ if (this.releaseFence === expected)
19396
+ this.releaseFence = null;
19397
+ }
19398
+ }
18429
19399
  unavailable() {
18430
19400
  if (this.dead || this.releasing || this.released)
18431
19401
  return true;
@@ -18443,7 +19413,7 @@ class ClaudeStreamBrokerHost {
18443
19413
  sessionKey: this.identity.sessionId,
18444
19414
  endpoint: pid ? `stdio:${pid}` : "stdio:released",
18445
19415
  pid,
18446
- processStartIdentity: pid ? procBackend.processIdentity(pid) : null,
19416
+ processStartIdentity: pid ? this.processIdentity(pid) : null,
18447
19417
  eventCursor: this.cursor,
18448
19418
  protocolVersion: this.protocolVersion,
18449
19419
  activeTurnRef: this.activeTurnId,
@@ -18572,6 +19542,10 @@ class ClaudeStreamBrokerHost {
18572
19542
  return this.fail(new Error("Claude stream process did not use subscription OAuth"));
18573
19543
  return;
18574
19544
  }
19545
+ if (type === "system" && message.subtype === "compact_boundary") {
19546
+ this.settlePendingCompactions({ compactionId: stringField(message, "uuid") });
19547
+ return;
19548
+ }
18575
19549
  if (type === "user") {
18576
19550
  const content = messageContent(message);
18577
19551
  const directUserEcho = stringField(message.message, "role") === "user" && content !== null;
@@ -18680,8 +19654,10 @@ class ClaudeStreamBrokerHost {
18680
19654
  }
18681
19655
  acceptResult(message) {
18682
19656
  const turnId = this.turnQueue.shift() ?? this.activeTurnId;
18683
- if (!turnId)
19657
+ if (!turnId) {
19658
+ this.settlePendingCompactions(new StructuredCompactError(CLAUDE_COMPACT_DECLINED_REASON, "refused"));
18684
19659
  return;
19660
+ }
18685
19661
  this.partialTurns.delete(turnId);
18686
19662
  const interrupted = this.interruptedTurns.delete(turnId);
18687
19663
  const status = interrupted || message.subtype === "interrupted" ? "interrupted" : message.subtype === "success" ? "completed" : "error";
@@ -18715,9 +19691,15 @@ class ClaudeStreamBrokerHost {
18715
19691
  async releaseAndReap() {
18716
19692
  this.releasing = true;
18717
19693
  this.rejectPending(new Error("Claude stream host released"));
18718
- this.startTermination();
19694
+ if (!this.startTermination() && this.releaseFence) {
19695
+ this.releasing = false;
19696
+ throw new Error("Claude child identity changed before signalling");
19697
+ }
18719
19698
  if (!await this.waitForReap(this.shutdownGraceMs * 2)) {
18720
- signalDetachedProcessGroup(this.child, "SIGKILL", this.signalProcess);
19699
+ if (!this.signalReleaseGroup("SIGKILL") && this.releaseFence) {
19700
+ this.releasing = false;
19701
+ throw new Error("Claude child identity changed before signalling");
19702
+ }
18721
19703
  if (!await this.waitForReap(this.shutdownGraceMs)) {
18722
19704
  const leaderExited = this.child.pid === undefined || (this.child.exitCode ?? null) !== null || (this.child.signalCode ?? null) !== null;
18723
19705
  if (!leaderExited)
@@ -18798,20 +19780,31 @@ class ClaudeStreamBrokerHost {
18798
19780
  this.closeSubscribers();
18799
19781
  this.startTermination();
18800
19782
  }
19783
+ signalReleaseGroup(signal2) {
19784
+ const expected = this.releaseFence;
19785
+ if (expected) {
19786
+ const pid = this.child.pid;
19787
+ if (!pid || expected.startIdentity === null || pid !== expected.pid || this.childStartIdentity !== expected.startIdentity || this.processIdentity(pid) !== expected.startIdentity)
19788
+ return false;
19789
+ }
19790
+ return signalDetachedProcessGroup(this.child, signal2, this.signalProcess);
19791
+ }
18801
19792
  startTermination() {
18802
19793
  if (this.terminationStarted || this.reaped)
18803
- return;
18804
- this.terminationStarted = true;
19794
+ return true;
18805
19795
  try {
18806
19796
  this.child.stdin.end();
18807
19797
  } catch {}
18808
- signalDetachedProcessGroup(this.child, "SIGTERM", this.signalProcess);
19798
+ if (!this.signalReleaseGroup("SIGTERM"))
19799
+ return false;
19800
+ this.terminationStarted = true;
18809
19801
  this.terminationTimer = setTimeout(() => {
18810
19802
  this.terminationTimer = null;
18811
19803
  if (this.reaped)
18812
19804
  return;
18813
- signalDetachedProcessGroup(this.child, "SIGKILL", this.signalProcess);
19805
+ this.signalReleaseGroup("SIGKILL");
18814
19806
  }, this.shutdownGraceMs);
19807
+ return true;
18815
19808
  }
18816
19809
  rejectPending(error) {
18817
19810
  for (const pending of this.pendingDeliveries.values()) {
@@ -18829,6 +19822,7 @@ class ClaudeStreamBrokerHost {
18829
19822
  pending.reject(new Error(safeError(error)));
18830
19823
  }
18831
19824
  this.pendingAnswers.clear();
19825
+ this.settlePendingCompactions(new StructuredCompactError(CLAUDE_COMPACT_UNOBSERVED_REASON, "unverified"));
18832
19826
  }
18833
19827
  closeSubscribers() {
18834
19828
  for (const subscriber of this.subscribers) {
@@ -18842,16 +19836,18 @@ class ClaudeStreamBrokerHost {
18842
19836
  listener(state);
18843
19837
  }
18844
19838
  }
18845
- var CHILD_ENV_ALLOWLIST, DEFAULT_TIMEOUT_MS2 = 30000, DEFAULT_SHUTDOWN_GRACE_MS2 = 1000, NATIVE_MULTI_AGENT_DENY_FLAG, MAX_REPLAY_ENVELOPE_BYTES, MAX_LINE_BYTES, TERMINAL_EXIT_MATCH_BYTES = 512, TERMINAL_CLI_EXIT_SIGNATURES, safeError, MAX_AUTH_PROBE_STDOUT_BYTES;
19839
+ var CHILD_ENV_ALLOWLIST, DEFAULT_TIMEOUT_MS2 = 30000, DEFAULT_SHUTDOWN_GRACE_MS2 = 1000, CLAUDE_COMPACT_COMMAND = "/compact", CLAUDE_COMPACT_UNOBSERVED_REASON = "compact-sent-unobserved", CLAUDE_COMPACT_DECLINED_REASON = "compact-declined", DEFAULT_COMPACT_EVIDENCE_TIMEOUT_MS, MAX_REPLAY_ENVELOPE_BYTES, MAX_LINE_BYTES, TERMINAL_EXIT_MATCH_BYTES = 512, TERMINAL_CLI_EXIT_SIGNATURES, safeError, MAX_AUTH_PROBE_STDOUT_BYTES;
18846
19840
  var init_claudeStreamBrokerHost = __esm(() => {
18847
19841
  init_configDir();
18848
19842
  init_cli();
18849
19843
  init_spawnPolicy();
18850
19844
  init_transcript();
18851
19845
  init_proc();
19846
+ init_process();
18852
19847
  init_compactText();
18853
19848
  init_engineHost();
18854
19849
  init_eventStore();
19850
+ init_hostActivityFlags();
18855
19851
  init_runtimeImageStore();
18856
19852
  init_telegramConnectorEnv();
18857
19853
  init_structuredContent();
@@ -18880,7 +19876,7 @@ var init_claudeStreamBrokerHost = __esm(() => {
18880
19876
  "SSL_CERT_DIR",
18881
19877
  "LLV_SPAWN_CAPABILITY"
18882
19878
  ];
18883
- NATIVE_MULTI_AGENT_DENY_FLAG = `native-multi-agent-deny:${NATIVE_MULTI_AGENT_TOOLS.join(",")}`;
19879
+ DEFAULT_COMPACT_EVIDENCE_TIMEOUT_MS = 5 * 60000;
18884
19880
  MAX_REPLAY_ENVELOPE_BYTES = 256 * 1024;
18885
19881
  MAX_LINE_BYTES = MAX_STRUCTURED_IMAGE_ENCODED_BYTES + MAX_REPLAY_ENVELOPE_BYTES;
18886
19882
  TERMINAL_CLI_EXIT_SIGNATURES = [
@@ -18929,7 +19925,13 @@ function decodeCodexStructuredUserText(value) {
18929
19925
  senderRole = messageOriginRole(attribute);
18930
19926
  }
18931
19927
  const origin = originKind ? { kind: originKind, ...originKind === "agent" && senderRole ? { role: senderRole } : {} } : null;
18932
- return { text: value.slice(marker[0].length), structured: true, contentDigest, selectedContext, origin };
19928
+ return {
19929
+ text: value.slice(marker[0].length),
19930
+ structured: true,
19931
+ contentDigest,
19932
+ selectedContext,
19933
+ origin
19934
+ };
18933
19935
  }
18934
19936
  if (!value.startsWith(STRUCTURED_USER_MARKER)) {
18935
19937
  return { text: value, structured: false, contentDigest: null, selectedContext: null, origin: null };
@@ -19445,6 +20447,7 @@ function subscriptionEnv2(source, codexHome, desktopSession = false, forwardGitH
19445
20447
  env.GH_CONFIG_DIR = source.GH_CONFIG_DIR;
19446
20448
  if (codexHome)
19447
20449
  env.CODEX_HOME = codexHome;
20450
+ env[STRUCTURED_HOST_STAMP_ENV] = structuredHostStamp();
19448
20451
  return env;
19449
20452
  }
19450
20453
  function threadFromResult(value, method) {
@@ -19714,7 +20717,7 @@ class CodexAppServerHost {
19714
20717
  this.realtimePersonaTimeoutMs = options.realtimePersonaTimeoutMs ?? REALTIME_PERSONA_TIMEOUT_MS;
19715
20718
  this.realtimeStartTimeoutMs = options.realtimeStartTimeoutMs ?? REALTIME_START_TIMEOUT_MS;
19716
20719
  this.deliveryConfirmationTimeoutMs = options.deliveryConfirmationTimeoutMs ?? DEFAULT_DELIVERY_CONFIRMATION_TIMEOUT_MS;
19717
- this.compactEvidenceTimeoutMs = options.compactEvidenceTimeoutMs ?? DEFAULT_COMPACT_EVIDENCE_TIMEOUT_MS;
20720
+ this.compactEvidenceTimeoutMs = options.compactEvidenceTimeoutMs ?? DEFAULT_COMPACT_EVIDENCE_TIMEOUT_MS2;
19718
20721
  this.shutdownGraceMs = options.shutdownGraceMs ?? DEFAULT_SHUTDOWN_GRACE_MS3;
19719
20722
  this.eventStore = options.eventStore ?? new FileRuntimeEventStore;
19720
20723
  this.effort = options.effort;
@@ -20583,6 +21586,13 @@ class CodexAppServerHost {
20583
21586
  }
20584
21587
  return this.releasePromise;
20585
21588
  }
21589
+ async releaseIfOwned(expected) {
21590
+ const pid = this.child.pid;
21591
+ if (this.released || this.releasing || this.releasePromise !== null || !pid || expected.startIdentity === null || pid !== expected.pid || this.childStartIdentity !== expected.startIdentity || this.childProcessOwnership() !== "owned")
21592
+ return false;
21593
+ await this.release();
21594
+ return true;
21595
+ }
20586
21596
  async releaseAndReap() {
20587
21597
  this.realtimeDeliveryEpoch += 1;
20588
21598
  if (this.realtimeSessionId) {
@@ -21669,10 +22679,11 @@ class CodexAppServerHost {
21669
22679
  pending.reject(new Error(safeError2(error)));
21670
22680
  }
21671
22681
  }
21672
- var CHILD_ENV_ALLOWLIST2, DESKTOP_ENV_ALLOWLIST, DEFAULT_TIMEOUT_MS3 = 30000, DEFAULT_DELIVERY_CONFIRMATION_TIMEOUT_MS, DEFAULT_COMPACT_EVIDENCE_TIMEOUT_MS, ACTIVE_THREAD_READ_TIMEOUT_MULTIPLIER = 3, LATE_THREAD_READ_RESPONSE_TTL_MULTIPLIER = 3, MIN_LATE_THREAD_READ_RESPONSE_TTL_MS = 1000, MAX_LATE_THREAD_READ_RESPONSES = 32, DEFAULT_SHUTDOWN_GRACE_MS3 = 1000, REALTIME_START_TIMEOUT_MS = 90000, REALTIME_PERSONA_TIMEOUT_MS = 3000, REALTIME_HANGUP_TIMEOUT_MS = 2000, REALTIME_LIVE_MODEL = "gpt-live-1-codex", MAX_REALTIME_SDP_BYTES, MAX_REALTIME_SPEECH_BYTES, MAX_REALTIME_CONTEXT_ITEMS = 12, MAX_REALTIME_CONTEXT_ITEM_BYTES, MAX_REALTIME_CONTEXT_BYTES, MAX_REPLAY_ENVELOPE_BYTES2, MAX_LINE_BYTES2, REPLAY_ENVELOPE_METHODS, REPLAY_REDUCTION_THRESHOLD_BYTES, REPLAY_STRING_UNITS, MAX_REPLAY_RAW_UNITS, REPLAY_STREAM_OUTPUT_UNITS, MAX_TRACKED_REPLAY_ENVELOPE_REQUESTS = 64, REPLAY_RESPONSE_PREFIX, REPLAY_FRAME_BUDGETS, MAX_STDERR_TAIL_BYTES, MAX_PRE_RESTORE_FRAMES = 256, MAX_PRE_RESTORE_BYTES, MUTATING_RPC_METHODS, safeError2;
22682
+ var CHILD_ENV_ALLOWLIST2, DESKTOP_ENV_ALLOWLIST, DEFAULT_TIMEOUT_MS3 = 30000, DEFAULT_DELIVERY_CONFIRMATION_TIMEOUT_MS, DEFAULT_COMPACT_EVIDENCE_TIMEOUT_MS2, ACTIVE_THREAD_READ_TIMEOUT_MULTIPLIER = 3, LATE_THREAD_READ_RESPONSE_TTL_MULTIPLIER = 3, MIN_LATE_THREAD_READ_RESPONSE_TTL_MS = 1000, MAX_LATE_THREAD_READ_RESPONSES = 32, DEFAULT_SHUTDOWN_GRACE_MS3 = 1000, REALTIME_START_TIMEOUT_MS = 90000, REALTIME_PERSONA_TIMEOUT_MS = 3000, REALTIME_HANGUP_TIMEOUT_MS = 2000, REALTIME_LIVE_MODEL = "gpt-live-1-codex", MAX_REALTIME_SDP_BYTES, MAX_REALTIME_SPEECH_BYTES, MAX_REALTIME_CONTEXT_ITEMS = 12, MAX_REALTIME_CONTEXT_ITEM_BYTES, MAX_REALTIME_CONTEXT_BYTES, MAX_REPLAY_ENVELOPE_BYTES2, MAX_LINE_BYTES2, REPLAY_ENVELOPE_METHODS, REPLAY_REDUCTION_THRESHOLD_BYTES, REPLAY_STRING_UNITS, MAX_REPLAY_RAW_UNITS, REPLAY_STREAM_OUTPUT_UNITS, MAX_TRACKED_REPLAY_ENVELOPE_REQUESTS = 64, REPLAY_RESPONSE_PREFIX, REPLAY_FRAME_BUDGETS, MAX_STDERR_TAIL_BYTES, MAX_PRE_RESTORE_FRAMES = 256, MAX_PRE_RESTORE_BYTES, MUTATING_RPC_METHODS, safeError2;
21673
22683
  var init_codexAppServerHost = __esm(() => {
21674
22684
  init_efforts();
21675
22685
  init_proc();
22686
+ init_process();
21676
22687
  init_codexHeadlessConfig();
21677
22688
  init_pluginAllowlist();
21678
22689
  init_compactText();
@@ -21719,7 +22730,7 @@ var init_codexAppServerHost = __esm(() => {
21719
22730
  "DESKTOP_SESSION"
21720
22731
  ];
21721
22732
  DEFAULT_DELIVERY_CONFIRMATION_TIMEOUT_MS = 5 * 60000;
21722
- DEFAULT_COMPACT_EVIDENCE_TIMEOUT_MS = 5 * 60000;
22733
+ DEFAULT_COMPACT_EVIDENCE_TIMEOUT_MS2 = 5 * 60000;
21723
22734
  MAX_REALTIME_SDP_BYTES = 512 * 1024;
21724
22735
  MAX_REALTIME_SPEECH_BYTES = 8 * 1024;
21725
22736
  MAX_REALTIME_CONTEXT_ITEM_BYTES = 8 * 1024;
@@ -25913,7 +26924,7 @@ function candidateFor(registry, request, durableProfileWins = false) {
25913
26924
  return null;
25914
26925
  const terminal2 = entry?.status === "dead" || entry?.status === "unhosted";
25915
26926
  const publishReady = Boolean(structuredHostProcessAlive(entry?.structuredHost?.process ?? null) && entry?.claimOwner && entry.pendingAction === null && !terminal2);
25916
- const profile = emptyLaunchProfile(durableProfileWins ? {
26927
+ const inheritedProfile = emptyLaunchProfile(durableProfileWins ? {
25917
26928
  ...entry?.launchProfile ?? {},
25918
26929
  ...generation.launchProfile,
25919
26930
  cwd: generation.launchProfile.cwd || entry?.launchProfile?.cwd || entry?.cwd
@@ -25922,6 +26933,11 @@ function candidateFor(registry, request, durableProfileWins = false) {
25922
26933
  ...entry?.launchProfile ?? {},
25923
26934
  cwd: entry?.launchProfile?.cwd || generation.launchProfile.cwd || entry?.cwd
25924
26935
  });
26936
+ const inheritedTitle = durableSemanticTitle(generation.launchProfile.title, 120) ?? durableSemanticTitle(entry?.launchProfile?.title, 120);
26937
+ const profile = emptyLaunchProfile({
26938
+ ...inheritedProfile,
26939
+ title: inheritedTitle ?? derivedSpawnTitle("recovery", inheritedProfile.goal?.objective ?? inheritedProfile.cwd, "Conversation recovery")
26940
+ });
25925
26941
  const recordedParent = snapshot2.lineageEdges[conversation.id]?.parentConversationId ?? profile.parentConversationId;
25926
26942
  const parentConversationId = recordedParent && recordedParent !== conversation.id ? registry.canonicalConversationId(recordedParent) : null;
25927
26943
  return {
@@ -26070,6 +27086,7 @@ var init_structuredRecovery = __esm(() => {
26070
27086
  init_registry();
26071
27087
  init_sessionKey();
26072
27088
  init_proc();
27089
+ init_title();
26073
27090
  init_client();
26074
27091
  init_registry3();
26075
27092
  init_structuredSpawn();
@@ -26687,11 +27704,13 @@ var init_structuredDeliveryController = __esm(() => {
26687
27704
  activeRegistry: null,
26688
27705
  activeHosts: null,
26689
27706
  registerActiveHost: null,
27707
+ activeRegistrations: null,
26690
27708
  republishActiveHost: null,
26691
27709
  releaseActiveHost: null,
26692
27710
  terminateActiveHost: null,
26693
27711
  completeActive: null,
26694
- stopActive: () => {}
27712
+ stopActive: () => {},
27713
+ everPublished: false
26695
27714
  };
26696
27715
  StructuredDeliveryControllerUnavailableError = class StructuredDeliveryControllerUnavailableError extends Error {
26697
27716
  code = CONTROLLER_UNAVAILABLE_CODE;
@@ -26771,7 +27790,7 @@ function completeProviderTurnObservation(conversation, source, virtualSource, re
26771
27790
  } catch (error) {
26772
27791
  return virtualSource && error.code === "ENOENT";
26773
27792
  }
26774
- const observed = transcriptTurnResult(source.path, before.size, before.mtimeMs, conversation.engine === "codex");
27793
+ const observed = transcriptTurnResult(source.path, before.size, before.mtimeMs, conversation.engine);
26775
27794
  if (!observed.complete)
26776
27795
  return false;
26777
27796
  let after;
@@ -26957,13 +27976,21 @@ async function advanceConversationMigration(conversationId, registry = agentRegi
26957
27976
  throw new Error("conversation has no source generation");
26958
27977
  if (!completeProviderTurnObservation(conversation, source2, successorProvider.virtualSource === true, registry))
26959
27978
  return restoreCreationFence(conversation);
27979
+ if (!migration.successorLaunchProfile) {
27980
+ conversation = registry.transitionConversationMigration(conversation.id, migration.revision, ["successor-starting"], { successorLaunchProfile: migrationSuccessorLaunchProfile(source2.launchProfile) });
27981
+ migration = conversation.migration;
27982
+ }
26960
27983
  const conversationId2 = conversation.id;
26961
27984
  const creationOwner = { operationId: migration.operationId, revision: migration.revision };
27985
+ const successorSource = {
27986
+ ...source2,
27987
+ launchProfile: migration.successorLaunchProfile
27988
+ };
26962
27989
  receipt = await successorProvider.create({
26963
27990
  engine: conversation.engine,
26964
27991
  operationId: creationOwner.operationId,
26965
27992
  conversationId: conversationId2,
26966
- source: source2,
27993
+ source: successorSource,
26967
27994
  targetAccountId: migration.targetId,
26968
27995
  recordContinuityPath(pathname) {
26969
27996
  registry.recordMigrationContinuityPath(conversationId2, pathname, creationOwner);
@@ -26978,9 +28005,10 @@ async function advanceConversationMigration(conversationId, registry = agentRegi
26978
28005
  const source = conversation.generations.find((generation) => generation.id === migration.sourceGenerationId) ?? conversation.generations.at(-1);
26979
28006
  if (!source)
26980
28007
  throw new Error("conversation has no source generation");
28008
+ const successorProfile = migration.successorLaunchProfile ?? migrationSuccessorLaunchProfile(source.launchProfile);
26981
28009
  if (!receipt || receipt.operationId !== migration.operationId)
26982
28010
  throw new Error("persisted successor receipt operation does not match");
26983
- await successorProvider.verify(receipt, { engine: conversation.engine, targetAccountId: migration.targetId, launchProfile: source.launchProfile });
28011
+ await successorProvider.verify(receipt, { engine: conversation.engine, targetAccountId: migration.targetId, launchProfile: successorProfile });
26984
28012
  const publicationConversationId = conversation.id;
26985
28013
  const publicationReceipt = receipt;
26986
28014
  const publicationRevision = migration.revision;
@@ -27007,7 +28035,7 @@ async function advanceConversationMigration(conversationId, registry = agentRegi
27007
28035
  engine: conversation.engine,
27008
28036
  conversationId: publicationConversationId,
27009
28037
  targetAccountId: migration.targetId,
27010
- launchProfile: source.launchProfile,
28038
+ launchProfile: successorProfile,
27011
28039
  ownsOperation: ownsPublication
27012
28040
  });
27013
28041
  publishOwner = registry.conversation(publicationConversationId);
@@ -27025,7 +28053,7 @@ async function advanceConversationMigration(conversationId, registry = agentRegi
27025
28053
  id: publicationReceipt.nativeId,
27026
28054
  path: publicationReceipt.path,
27027
28055
  accountId: migration.targetId,
27028
- launchProfile: source.launchProfile,
28056
+ launchProfile: successorProfile,
27029
28057
  historyHash: publicationReceipt.historyHash,
27030
28058
  host: publicationReceipt.host
27031
28059
  }, publicationRevision, publicationOperationId, publicationReceipt);
@@ -27087,6 +28115,7 @@ var init_coordinator = __esm(() => {
27087
28115
  init_activity();
27088
28116
  init_codexNative();
27089
28117
  init_process();
28118
+ init_title();
27090
28119
  init_structuredDeliveryController();
27091
28120
  init_contracts2();
27092
28121
  init_provider();
@@ -27297,21 +28326,6 @@ var init_pauseResumeActor = __esm(() => {
27297
28326
  OPERATOR_PAUSE_RESUME_ACTOR = { kind: "operator" };
27298
28327
  });
27299
28328
 
27300
- // src/lib/title.ts
27301
- function compactPath(value) {
27302
- return value.replace(/(?:\/[^\s)]+){3,}/g, (match) => {
27303
- if (match.length <= 40)
27304
- return match;
27305
- const parts = match.split("/").filter(Boolean);
27306
- return parts.length >= 2 ? ".../" + parts.slice(-2).join("/") : match;
27307
- });
27308
- }
27309
- function cleanTitle(value, maxLength = 160) {
27310
- const stripped = value.replace(/\[([^\]]+)\]\(([^)]+)\)/g, "$1").replace(/`([^`]+)`/g, "$1").replace(/[*_~#>]+/g, "").replace(/\s+/g, " ").trim();
27311
- const compacted = compactPath(stripped).replace(/\s+/g, " ").trim();
27312
- return compacted.length > maxLength ? compacted.slice(0, maxLength - 1).trimEnd() + "\u2026" : compacted;
27313
- }
27314
-
27315
28329
  // src/lib/scanner/projectState.ts
27316
28330
  import crypto23 from "crypto";
27317
28331
  import fs46 from "fs";
@@ -27442,6 +28456,7 @@ var init_projectState = __esm(() => {
27442
28456
 
27443
28457
  // src/lib/scanner/describe.ts
27444
28458
  import fs47 from "fs";
28459
+ import os10 from "os";
27445
28460
  import path43 from "path";
27446
28461
  function subagentSidecarPath(rootName, pathname) {
27447
28462
  if (rootName !== "claude-projects" || !path43.basename(pathname).startsWith("agent-") || !pathname.endsWith(".jsonl")) {
@@ -27737,6 +28752,17 @@ function persistedProjects(stateKey = projectResolutionStateKey()) {
27737
28752
  persistedProjectCache.set("state", [Date.now() + PERSISTED_PROJECT_TTL_MS, dir, stateKey, maps]);
27738
28753
  return maps;
27739
28754
  }
28755
+ function projectInfoFromOpenclawWorkspace(cwd) {
28756
+ const resolved = path43.resolve(cwd);
28757
+ if (path43.basename(resolved) !== "workspace")
28758
+ return null;
28759
+ const state2 = path43.dirname(resolved);
28760
+ const configured = process.env.OPENCLAW_STATE_DIR?.trim();
28761
+ const recognized = configured !== undefined && configured !== "" && path43.resolve(configured) === state2 || path43.dirname(state2) === os10.homedir() && OPENCLAW_STATE_DIRECTORY.test(path43.basename(state2));
28762
+ if (!recognized)
28763
+ return null;
28764
+ return { project: directoryProjectId(resolved), displayName: "OpenClaw" };
28765
+ }
27740
28766
  function projectInfoFromCwd(cwd, requestedState) {
27741
28767
  if (!cwd.trim())
27742
28768
  return null;
@@ -27749,6 +28775,11 @@ function projectInfoFromCwd(cwd, requestedState) {
27749
28775
  projectInfoCwdCache.set(cwd, [Date.now() + PROJECT_INFO_CWD_TTL_MS, resolutionState, scratchpad]);
27750
28776
  return scratchpad;
27751
28777
  }
28778
+ const openclawWorkspace = projectInfoFromOpenclawWorkspace(cwd);
28779
+ if (openclawWorkspace) {
28780
+ projectInfoCwdCache.set(cwd, [Date.now() + PROJECT_INFO_CWD_TTL_MS, resolutionState, openclawWorkspace]);
28781
+ return openclawWorkspace;
28782
+ }
27752
28783
  const codexWorktree = worktreeFromCodexPath(cwd);
27753
28784
  let worktree = worktreeFromPath(cwd) ?? worktreeFromNested(cwd) ?? (codexWorktree ? worktreeFromGitFile(cwd) ?? codexWorktree : worktreeFromGitFile(cwd));
27754
28785
  if (!worktree && !hasGitMarker(cwd)) {
@@ -27784,6 +28815,8 @@ function projectRootForCwd(cwd) {
27784
28815
  const scratchpad = projectInfoFromClaudeTaskCwd(cwd);
27785
28816
  if (scratchpad)
27786
28817
  return scratchpad.repo;
28818
+ if (projectInfoFromOpenclawWorkspace(cwd))
28819
+ return;
27787
28820
  const worktree = worktreeFromPath(cwd) ?? worktreeFromNested(cwd) ?? (worktreeFromCodexPath(cwd) ? worktreeFromGitFile(cwd) ?? worktreeFromCodexPath(cwd) : null) ?? worktreeFromGitFile(cwd) ?? worktreeFromMemory(cwd);
27788
28821
  return worktree?.repo || repositoryRootForPath(cwd) || undefined;
27789
28822
  }
@@ -27866,8 +28899,18 @@ function goodTitle(text2) {
27866
28899
  const val = typeof text2 === "string" ? text2.trim() : "";
27867
28900
  return val && !skipTitlePrefixes.some((prefix) => val.startsWith(prefix)) ? val : null;
27868
28901
  }
27869
- function userPromptFromRecord(obj, wantCodex) {
27870
- if (wantCodex) {
28902
+ function userPromptFromRecord(obj, engine) {
28903
+ if (engine === "openclaw") {
28904
+ const message = openclawMessage(obj);
28905
+ if (!message || message.role !== "user")
28906
+ return null;
28907
+ const content = message.content;
28908
+ if (typeof content === "string")
28909
+ return content.trim() || null;
28910
+ const text2 = recordsValue(content).filter((part) => part.type === "text").map((part) => stringValue(part.text) ?? "").join(" ").trim();
28911
+ return text2 || null;
28912
+ }
28913
+ if (engine === "codex") {
27871
28914
  const payload = recordValue(obj.payload) ?? {};
27872
28915
  if (payload.type === "user_message") {
27873
28916
  const prompt = typeof payload.message === "string" ? payload.message.trim() : "";
@@ -27886,7 +28929,7 @@ function userPromptFromRecord(obj, wantCodex) {
27886
28929
  }
27887
28930
  return null;
27888
28931
  }
27889
- function titleFromLines(lines, wantCodex) {
28932
+ function titleFromLines(lines, engine) {
27890
28933
  for (const line of lines) {
27891
28934
  let obj;
27892
28935
  try {
@@ -27907,7 +28950,7 @@ function titleFromLines(lines, wantCodex) {
27907
28950
  if (title2)
27908
28951
  return title2;
27909
28952
  }
27910
- const title = goodTitle(userPromptFromRecord(obj, wantCodex));
28953
+ const title = goodTitle(userPromptFromRecord(obj, engine));
27911
28954
  if (title)
27912
28955
  return title;
27913
28956
  }
@@ -27998,7 +29041,7 @@ function projectInfoFromSlug(slug, stateKey) {
27998
29041
  const persisted = persistedProjects(stateKey).bySlug.get(slug);
27999
29042
  return persisted ? aliasedProjectInfo(persisted.project, persisted.worktree, persisted.repo) : null;
28000
29043
  }
28001
- function scanJsonlTitle(pathname, st, wantCodex) {
29044
+ function scanJsonlTitle(pathname, st, engine) {
28002
29045
  const cached3 = titleCache.get(pathname);
28003
29046
  if (cached3?.size === st.size && cached3.mtimeMs === st.mtimeMs) {
28004
29047
  return { value: cached3.value, complete: true, headPreserved: true };
@@ -28014,7 +29057,7 @@ function scanJsonlTitle(pathname, st, wantCodex) {
28014
29057
  }
28015
29058
  }
28016
29059
  const title = titleFromLines(head.value.text.split(`
28017
- `).slice(0, 151), wantCodex);
29060
+ `).slice(0, 151), engine);
28018
29061
  titleCache.set(pathname, cacheHeadMetadata(st, head.value, title));
28019
29062
  return { value: title, complete: true, headPreserved: false };
28020
29063
  }
@@ -28050,7 +29093,7 @@ function deriveTranscriptMetadata(rootName, pathname, st, identity) {
28050
29093
  kind = "session";
28051
29094
  fmt = "codex";
28052
29095
  if (complete) {
28053
- const titleRead = scanJsonlTitle(pathname, st, true);
29096
+ const titleRead = scanJsonlTitle(pathname, st, "codex");
28054
29097
  complete &&= titleRead.complete;
28055
29098
  title = titleRead.value;
28056
29099
  }
@@ -28073,7 +29116,7 @@ function deriveTranscriptMetadata(rootName, pathname, st, identity) {
28073
29116
  const meta = sidecar.value ?? {};
28074
29117
  title = stringValue(meta.description) ?? stringValue(meta.name) ?? null;
28075
29118
  if (!title && complete) {
28076
- const titleRead = scanJsonlTitle(pathname, st, false);
29119
+ const titleRead = scanJsonlTitle(pathname, st, "claude");
28077
29120
  complete &&= titleRead.complete;
28078
29121
  title = titleRead.value;
28079
29122
  }
@@ -28081,12 +29124,31 @@ function deriveTranscriptMetadata(rootName, pathname, st, identity) {
28081
29124
  } else {
28082
29125
  kind = "session";
28083
29126
  if (complete) {
28084
- const titleRead = scanJsonlTitle(pathname, st, false);
29127
+ const titleRead = scanJsonlTitle(pathname, st, "claude");
28085
29128
  complete &&= titleRead.complete;
28086
29129
  title = titleRead.value;
28087
29130
  }
28088
29131
  title ??= "Claude session";
28089
29132
  }
29133
+ } else if (rootName === "openclaw-sessions") {
29134
+ const cwdRead = complete ? transcriptCwd(pathname, st) : { value: null, complete: false, headPreserved: false };
29135
+ complete &&= cwdRead.complete;
29136
+ cwdComplete = cwdRead.complete;
29137
+ cwd = cwdRead.value ?? undefined;
29138
+ if (complete) {
29139
+ const startedAtRead = transcriptStartedAt(pathname, st);
29140
+ complete &&= startedAtRead.complete;
29141
+ sessionStartedAt = startedAtRead.value;
29142
+ }
29143
+ engine = "openclaw";
29144
+ kind = "session";
29145
+ fmt = "openclaw";
29146
+ if (complete) {
29147
+ const titleRead = scanJsonlTitle(pathname, st, "openclaw");
29148
+ complete &&= titleRead.complete;
29149
+ title = titleRead.value;
29150
+ }
29151
+ title ??= "OpenClaw session";
28090
29152
  } else if (rootName === "claude-tasks") {
28091
29153
  engine = "shell";
28092
29154
  kind = "background";
@@ -28126,6 +29188,8 @@ function resolveProjectOverlay(rootName, root, pathname, cwd, cwdAuthoritative,
28126
29188
  const slug = rel.split(path43.sep)[0] ?? "";
28127
29189
  const worktreeInfo = worktreeFromSlug(slug);
28128
29190
  info = (cwd ? projectInfoFromCwd(cwd, stateKey) : null) ?? projectInfoFromTranscript(pathname, stateKey) ?? (worktreeInfo ? aliasedProjectInfo(worktreeInfo.project, worktreeInfo.worktree, worktreeInfo.repo) : aliasedProjectInfo(projectFromSlug(slug)));
29191
+ } else if (rootName === "openclaw-sessions") {
29192
+ info = (cwd ? projectInfoFromCwd(cwd, stateKey) : null) ?? projectInfoFromTranscript(pathname, stateKey);
28129
29193
  } else if (rootName === "claude-tasks") {
28130
29194
  const rel = path43.relative(root, pathname);
28131
29195
  const slug = rel.split(path43.sep)[0] ?? "";
@@ -28192,16 +29256,18 @@ function describeFile(rootName, root, pathname, st, stateKey = projectResolution
28192
29256
  function describe(rootName, root, pathname, st, stateKey = projectResolutionStateKey(), identity = fileDescriptionIdentity(rootName, pathname, st)) {
28193
29257
  return describeFile(rootName, root, pathname, st, stateKey, identity).description;
28194
29258
  }
28195
- var transcriptMetaCache, projectOverlayCache, titleCache, repoSlugCache, cwdCache, sessionStartedAtCache, HEAD_BYTES2, skipTitlePrefixes, worktreeGitCache, WORKTREE_TTL_MS = 60000, projectInfoCwdCache, PROJECT_INFO_CWD_TTL_MS = 1e4, persistedProjectCache, PERSISTED_PROJECT_TTL_MS = 1e4, WORKTREE_MAP_FILE = "worktree-map.json", worktreeMemory = null, worktreeMemoryDirty = false;
29259
+ var transcriptMetaCache, projectOverlayCache, titleCache, repoSlugCache, cwdCache, sessionStartedAtCache, HEAD_BYTES2, skipTitlePrefixes, worktreeGitCache, WORKTREE_TTL_MS = 60000, projectInfoCwdCache, PROJECT_INFO_CWD_TTL_MS = 1e4, persistedProjectCache, PERSISTED_PROJECT_TTL_MS = 1e4, WORKTREE_MAP_FILE = "worktree-map.json", worktreeMemory = null, worktreeMemoryDirty = false, OPENCLAW_STATE_DIRECTORY;
28196
29260
  var init_describe = __esm(() => {
28197
29261
  init_configDir();
28198
29262
  init_aliases();
28199
29263
  init_sqliteStateStore();
28200
29264
  init_identity();
29265
+ init_title();
28201
29266
  init_caches();
28202
29267
  init_codexNative();
28203
29268
  init_head();
28204
29269
  init_json();
29270
+ init_openclawNative();
28205
29271
  init_projectState();
28206
29272
  globalCache("meta-v4").clear();
28207
29273
  globalCache("title-v2").clear();
@@ -28220,6 +29286,7 @@ var init_describe = __esm(() => {
28220
29286
  worktreeGitCache = globalCache("worktree-git");
28221
29287
  projectInfoCwdCache = globalCache("project-info-cwd-v2");
28222
29288
  persistedProjectCache = globalCache("persisted-project-v2");
29289
+ OPENCLAW_STATE_DIRECTORY = /^\.openclaw(?:-[A-Za-z0-9._-]+)?$/;
28223
29290
  });
28224
29291
 
28225
29292
  // src/lib/pipelines/controllerSignal.ts
@@ -28418,7 +29485,7 @@ function scanEventStream(stdout) {
28418
29485
  }
28419
29486
  return { sessionId, lastAgentMessage };
28420
29487
  }
28421
- function reviewerCommand(role, reviewRequest, outputPath, cwd, codexAccount, claudeAccount, spawnCapability) {
29488
+ function reviewerCommand(role, reviewRequest, outputPath, cwd, codexAccount, claudeAccount, spawnCapability, options = {}) {
28422
29489
  if (role.engine === "claude") {
28423
29490
  const sessionId = crypto24.randomUUID();
28424
29491
  const args2 = [
@@ -28441,7 +29508,17 @@ function reviewerCommand(role, reviewRequest, outputPath, cwd, codexAccount, cla
28441
29508
  const baseEnv = claudeAccount?.managed ? claudeManagedEnvironment(claudeAccount.home) : process.env;
28442
29509
  return { command: resolveBinary("claude"), args: args2, env: reviewerEnvironment(baseEnv, spawnCapability), stdin: null, outputPath: null, sessionId, reviewerPath: claudeTranscriptPath(cwd, sessionId, claudeAccount?.projectsDir) };
28443
29510
  }
28444
- const args = ["--disable", "multi_agent", "exec", "--ignore-user-config", "-", "--json", "--output-last-message", outputPath, "--dangerously-bypass-approvals-and-sandbox"];
29511
+ const args = [
29512
+ "--disable",
29513
+ "multi_agent",
29514
+ "exec",
29515
+ "--ignore-user-config",
29516
+ "-",
29517
+ "--json",
29518
+ "--output-last-message",
29519
+ outputPath,
29520
+ ...options.sandbox === "read-only" ? ["-s", "read-only", "--skip-git-repo-check"] : ["--dangerously-bypass-approvals-and-sandbox"]
29521
+ ];
28445
29522
  if (codexAccount?.managed)
28446
29523
  args.unshift("-c", "cli_auth_credentials_store=file");
28447
29524
  if (role.model)
@@ -28458,34 +29535,29 @@ function reviewerCommand(role, reviewRequest, outputPath, cwd, codexAccount, cla
28458
29535
  reviewerPath: null
28459
29536
  };
28460
29537
  }
28461
- function startHeadlessReview(flowId, round, role, cwd, reviewRequest, timeoutMs = DEFAULT_TIMEOUT_MS4, codexAccount, claudeAccount, runtime2, spawnCapability) {
28462
- const key2 = runKey(flowId, round);
28463
- if (runs.has(key2))
28464
- return { pid: null, identity: null, sessionId: null, reviewerPath: null };
28465
- const outputPath = outputPathFor(flowId, round);
28466
- fs48.mkdirSync(path44.dirname(outputPath), { recursive: true });
28467
- clearHeadlessReviewArtifacts(flowId, round);
28468
- const built = reviewerCommand(role, reviewRequest, outputPath, cwd, codexAccount, claudeAccount, spawnCapability);
28469
- const stdoutFd = fs48.openSync(stdoutPathFor(flowId, round), "w");
28470
- const stderrFd = fs48.openSync(stderrPathFor(flowId, round), "w");
29538
+ function launchDetached(input) {
29539
+ if (runs.has(input.key))
29540
+ return null;
29541
+ const stdoutFd = fs48.openSync(input.stdoutPath, "w");
29542
+ const stderrFd = fs48.openSync(input.stderrPath, "w");
28471
29543
  let child;
28472
29544
  try {
28473
- child = spawn6(runtime2?.command ?? built.command, built.args, {
28474
- cwd,
28475
- env: built.env,
29545
+ child = spawn6(input.runtime?.command ?? input.built.command, input.built.args, {
29546
+ cwd: input.cwd,
29547
+ env: input.built.env,
28476
29548
  detached: true,
28477
- stdio: [built.stdin === null ? "ignore" : "pipe", stdoutFd, stderrFd]
29549
+ stdio: [input.built.stdin === null ? "ignore" : "pipe", stdoutFd, stderrFd]
28478
29550
  });
28479
- if (built.stdin !== null && child.stdin) {
29551
+ if (input.built.stdin !== null && child.stdin) {
28480
29552
  child.stdin.on("error", () => {});
28481
- child.stdin.end(built.stdin, "utf8");
29553
+ child.stdin.end(input.built.stdin, "utf8");
28482
29554
  }
28483
29555
  } finally {
28484
29556
  fs48.closeSync(stdoutFd);
28485
29557
  fs48.closeSync(stderrFd);
28486
29558
  }
28487
29559
  child.unref();
28488
- const identityOf = runtime2?.processIdentity ?? procBackend.processIdentity;
29560
+ const identityOf = input.runtime?.processIdentity ?? procBackend.processIdentity;
28489
29561
  const identity = child.pid ? identityOf(child.pid) : null;
28490
29562
  const run = {
28491
29563
  child,
@@ -28495,31 +29567,55 @@ function startHeadlessReview(flowId, round, role, cwd, reviewRequest, timeoutMs
28495
29567
  exit: null,
28496
29568
  terminationStarted: false,
28497
29569
  timer: setTimeout(() => {
29570
+ input.onTimeout?.();
28498
29571
  killOwnedRun(run);
28499
- }, timeoutMs)
29572
+ }, input.timeoutMs)
28500
29573
  };
28501
29574
  run.timer.unref();
28502
- runs.set(key2, run);
28503
- let completionSignaled = false;
28504
- const signalCompletion = () => {
28505
- if (completionSignaled)
28506
- return;
28507
- completionSignaled = true;
28508
- requestPipelineTick();
28509
- };
29575
+ runs.set(input.key, run);
28510
29576
  child.on("error", () => {
28511
29577
  clearTimeout(run.timer);
28512
29578
  run.exit = { code: null, signal: null };
28513
29579
  killOwnedRun(run);
28514
- signalCompletion();
29580
+ input.onExit(run);
28515
29581
  });
28516
29582
  child.on("close", (code, signal3) => {
28517
29583
  clearTimeout(run.timer);
28518
29584
  run.exit = { code, signal: signal3 };
28519
29585
  killOwnedRun(run);
28520
- signalCompletion();
29586
+ input.onExit(run);
28521
29587
  });
28522
- return { pid: child.pid ?? null, identity, sessionId: built.sessionId, reviewerPath: built.reviewerPath };
29588
+ return { pid: child.pid ?? null, identity };
29589
+ }
29590
+ function startHeadlessReview(flowId, round, role, cwd, reviewRequest, timeoutMs = DEFAULT_TIMEOUT_MS4, codexAccount, claudeAccount, runtime2, spawnCapability) {
29591
+ const key2 = runKey(flowId, round);
29592
+ const idle = { pid: null, identity: null, sessionId: null, reviewerPath: null };
29593
+ if (runs.has(key2))
29594
+ return idle;
29595
+ const outputPath = outputPathFor(flowId, round);
29596
+ fs48.mkdirSync(path44.dirname(outputPath), { recursive: true });
29597
+ clearHeadlessReviewArtifacts(flowId, round);
29598
+ const built = reviewerCommand(role, reviewRequest, outputPath, cwd, codexAccount, claudeAccount, spawnCapability);
29599
+ let completionSignaled = false;
29600
+ const signalCompletion = () => {
29601
+ if (completionSignaled)
29602
+ return;
29603
+ completionSignaled = true;
29604
+ requestPipelineTick();
29605
+ };
29606
+ const launched = launchDetached({
29607
+ key: key2,
29608
+ built,
29609
+ cwd,
29610
+ stdoutPath: stdoutPathFor(flowId, round),
29611
+ stderrPath: stderrPathFor(flowId, round),
29612
+ timeoutMs,
29613
+ runtime: runtime2,
29614
+ onExit: signalCompletion
29615
+ });
29616
+ if (!launched)
29617
+ return idle;
29618
+ return { pid: launched.pid, identity: launched.identity, sessionId: built.sessionId, reviewerPath: built.reviewerPath };
28523
29619
  }
28524
29620
  function clearHeadlessReviewArtifacts(flowId, round) {
28525
29621
  for (const artifact of [outputPathFor(flowId, round), stdoutPathFor(flowId, round), stderrPathFor(flowId, round)]) {
@@ -29924,10 +31020,14 @@ var init_provision = __esm(() => {
29924
31020
  });
29925
31021
 
29926
31022
  // src/lib/pipelines/durableEvidence.ts
31023
+ var CODEX_TURN_END_TYPES, CODEX_TURN_START_TYPES;
29927
31024
  var init_durableEvidence = __esm(() => {
29928
31025
  init_turnState();
29929
31026
  init_findings();
29930
31027
  init_activity();
31028
+ init_json();
31029
+ CODEX_TURN_END_TYPES = new Set(["task_complete", "turn_complete", "turn_completed", "turn_aborted"]);
31030
+ CODEX_TURN_START_TYPES = new Set(["task_started", "turn_started", "user_message"]);
29931
31031
  });
29932
31032
  // src/lib/pipelines/limits.ts
29933
31033
  var MAX_STAGE_PROMPT_LENGTH = 8000, MAX_FAIL_EDGE_ROUNDS = 9;
@@ -29935,7 +31035,7 @@ var MAX_STAGE_PROMPT_LENGTH = 8000, MAX_FAIL_EDGE_ROUNDS = 9;
29935
31035
  // src/lib/pipelines/preflight.ts
29936
31036
  import { spawnSync as spawnSync5 } from "child_process";
29937
31037
  import fs53 from "fs";
29938
- import os10 from "os";
31038
+ import os11 from "os";
29939
31039
  var GIT_PROBE_TIMEOUT_MS = 4000, boundedGitExec = (command, args, cwd) => {
29940
31040
  if (command !== "git")
29941
31041
  return realExec(command, args, cwd);
@@ -29949,7 +31049,7 @@ var GIT_PROBE_TIMEOUT_MS = 4000, boundedGitExec = (command, args, cwd) => {
29949
31049
  var init_preflight = __esm(() => {
29950
31050
  init_provision();
29951
31051
  DEFAULT_PORTS = {
29952
- homeDir: os10.homedir,
31052
+ homeDir: os11.homedir,
29953
31053
  stat: fs53.statSync,
29954
31054
  access: fs53.accessSync,
29955
31055
  exec: boundedGitExec
@@ -29957,7 +31057,7 @@ var init_preflight = __esm(() => {
29957
31057
  preflightCache = new Map;
29958
31058
  });
29959
31059
  // src/lib/pipelines/types.ts
29960
- var init_types2 = () => {};
31060
+ var init_types3 = () => {};
29961
31061
 
29962
31062
  // src/lib/pipelines/roles.ts
29963
31063
  var PIPELINE_ROLE_IDS;
@@ -29966,7 +31066,7 @@ var init_roles = __esm(() => {
29966
31066
  init_store();
29967
31067
  init_efforts();
29968
31068
  init_models();
29969
- init_types2();
31069
+ init_types3();
29970
31070
  PIPELINE_ROLE_IDS = [
29971
31071
  "orchestrator",
29972
31072
  "reviewer",
@@ -30022,9 +31122,9 @@ var init_engine = __esm(() => {
30022
31122
  init_commands();
30023
31123
  init_findings();
30024
31124
  init_store2();
30025
- init_handoffLineage();
30026
31125
  init_pauseResumeActor();
30027
31126
  init_client();
31127
+ init_structuredDeliveryController();
30028
31128
  init_redact();
30029
31129
  init_review();
30030
31130
  init_structuredSpawn();
@@ -30032,6 +31132,7 @@ var init_engine = __esm(() => {
30032
31132
  init_store4();
30033
31133
  init_roots();
30034
31134
  init_status();
31135
+ init_title();
30035
31136
  init_tmux();
30036
31137
  init_provision();
30037
31138
  init_controllerSignal2();
@@ -30072,6 +31173,12 @@ var init_engine = __esm(() => {
30072
31173
  STAGE_ON_FAIL_SHAPE = `null, or {to: <existing stage id>, maxRounds?: 1\u2013${MAX_FAIL_EDGE_ROUNDS}} \u2014 run stages only`;
30073
31174
  });
30074
31175
 
31176
+ // src/lib/bridge/types.ts
31177
+ var BRIDGE_ASK_TTL_SECONDS;
31178
+ var init_types4 = __esm(() => {
31179
+ BRIDGE_ASK_TTL_SECONDS = 2 * 3600;
31180
+ });
31181
+
30075
31182
  // src/lib/displayNames.ts
30076
31183
  var KNOWN_ROLE_WORDS;
30077
31184
  var init_displayNames = __esm(() => {
@@ -30098,6 +31205,7 @@ var init_projectModel = __esm(() => {
30098
31205
  // src/components/attention.ts
30099
31206
  var STALLED_ATTENTION_TTL;
30100
31207
  var init_attention = __esm(() => {
31208
+ init_types4();
30101
31209
  init_projectModel();
30102
31210
  STALLED_ATTENTION_TTL = 2 * 3600;
30103
31211
  });
@@ -30144,6 +31252,7 @@ var init_projectResolution = __esm(() => {
30144
31252
  var init_titleStore = __esm(() => {
30145
31253
  init_sessionKey();
30146
31254
  init_configDir();
31255
+ init_title();
30147
31256
  });
30148
31257
 
30149
31258
  // src/lib/session/renameEligibility.ts
@@ -30153,7 +31262,7 @@ var init_renameEligibility = __esm(() => {
30153
31262
  });
30154
31263
 
30155
31264
  // src/lib/session/titleProjection.ts
30156
- function canonicalConversationId(snapshot2, alias) {
31265
+ function canonicalConversationId2(snapshot2, alias) {
30157
31266
  let current = alias;
30158
31267
  const seen = new Set;
30159
31268
  while (!seen.has(current)) {
@@ -30203,7 +31312,7 @@ function projectRegistrySnapshot(snapshot2, signature, includeProjects = true) {
30203
31312
  }
30204
31313
  }
30205
31314
  for (const alias of Object.keys(snapshot2.conversationAliases)) {
30206
- const canonical = canonicalConversationId(snapshot2, alias);
31315
+ const canonical = canonicalConversationId2(snapshot2, alias);
30207
31316
  if (canonical === alias)
30208
31317
  continue;
30209
31318
  const list = aliasesByCanonical.get(canonical);
@@ -30869,9 +31978,9 @@ function defaultPorts() {
30869
31978
  exec: realExec,
30870
31979
  startSetup,
30871
31980
  setupStatus,
30872
- spawnAgent: async (role, cwd, prompt, accountId) => {
31981
+ spawnAgent: async (role, cwd, prompt, accountId, title) => {
30873
31982
  const account2 = accountManager.resolveSpawn(role.engine, accountId);
30874
- const spec = freshSpecFor(role.engine, cwd, { model: role.model, effort: role.effort, codexHome: account2.engine === "codex" ? account2.home : null, claudeConfigDir: account2.engine === "claude" ? account2.home : null, claudeProjectsDir: account2.engine === "claude" ? account2.transcriptRoot : null });
31983
+ const spec = freshSpecFor(role.engine, cwd, { title, model: role.model, effort: role.effort, codexHome: account2.engine === "codex" ? account2.home : null, claudeConfigDir: account2.engine === "claude" ? account2.home : null, claudeProjectsDir: account2.engine === "claude" ? account2.transcriptRoot : null });
30875
31984
  const startedAtMs = Date.now();
30876
31985
  const pane = await spawnAgentWithPrompt(spec, prompt);
30877
31986
  const transcript = await resolveSpawnedTranscriptPath({
@@ -30906,6 +32015,12 @@ function defaultPorts() {
30906
32015
  function spawnKey(wf, run) {
30907
32016
  return `${wf.id}:${run.index}`;
30908
32017
  }
32018
+ function stageSpawnTitle(wf, run) {
32019
+ const stage = wf.template.stages[run.index];
32020
+ const stageLabel = stage?.kind === "review-loop" ? "review fixer" : `stage ${run.index + 1}`;
32021
+ const suffix = ` \xB7 ${stageLabel}`;
32022
+ return `${cleanTitle(wf.task, 120 - suffix.length)}${suffix}`;
32023
+ }
30909
32024
  function park(wf, detail) {
30910
32025
  wf.pausedState = wf.state;
30911
32026
  wf.state = "needs_decision";
@@ -30993,7 +32108,7 @@ async function ensureStageAgent(wf, run, role, stagePrompt, entries, ports, pers
30993
32108
  spawnsThisProcess2.add(spawnKey(wf, run));
30994
32109
  persistCheckpoint();
30995
32110
  try {
30996
- const spawned = await ports.spawnAgent(role, wf.worktreeDir, stagePrompt, run.accountId);
32111
+ const spawned = await ports.spawnAgent(role, wf.worktreeDir, stagePrompt, run.accountId, stageSpawnTitle(wf, run));
30997
32112
  run.paneId = spawned.paneId;
30998
32113
  if (spawned.transcript) {
30999
32114
  run.agentPath = spawned.transcript;
@@ -31218,6 +32333,7 @@ var init_engine2 = __esm(() => {
31218
32333
  init_describe();
31219
32334
  init_status();
31220
32335
  init_tmux();
32336
+ init_title();
31221
32337
  init_provision();
31222
32338
  init_store5();
31223
32339
  TERMINAL_STATES2 = new Set(["approved", "closed"]);
@@ -31390,15 +32506,6 @@ function isCommandCaveatText(text2) {
31390
32506
  function isTaskNotificationText(text2) {
31391
32507
  return /^<task-notification\b[^>]*>[\s\S]*<\/task-notification>$/.test(text2);
31392
32508
  }
31393
- function isClaudeProtocolUser(record9) {
31394
- if (originKindOf(record9) === "human" || str2(record9.promptSource) === "typed")
31395
- return false;
31396
- if (record9.isMeta === true || record9.isCompactSummary === true || "interruptedMessageId" in record9 || "promptSource" in record9 || "origin" in record9) {
31397
- return true;
31398
- }
31399
- const text2 = claudeUserText(rec2(record9.message).content).trim();
31400
- return isClaudeInterruptSentinelText(text2) || isCommandCaveatText(text2) || isTaskNotificationText(text2) || /^This came from another Claude session\b[\s\S]*not typed by your user[\s\S]*$/.test(text2);
31401
- }
31402
32509
  function isClaudeTurnWindowMeta(record9) {
31403
32510
  const originKind = originKindOf(record9);
31404
32511
  if (originKind === "human" || originKind === "peer" || originKind === "coordinator")
@@ -31536,8 +32643,6 @@ function recentTurnWindowsFromRecords(records, codex) {
31536
32643
  return windows;
31537
32644
  }
31538
32645
  function recentTurnActivityFromRecords(records, codex) {
31539
- const operatorActions = new Set;
31540
- const unprovenancedUserActions = new Set;
31541
32646
  const assistantMessages = new Set;
31542
32647
  for (const record9 of records) {
31543
32648
  const atMs = parseMillis(record9.timestamp);
@@ -31545,32 +32650,9 @@ function recentTurnActivityFromRecords(records, codex) {
31545
32650
  continue;
31546
32651
  if (visibleAssistantMessage(record9, codex))
31547
32652
  assistantMessages.add(atMs);
31548
- if (codex) {
31549
- const payload = recordValue(record9.payload) ?? {};
31550
- let text2 = "";
31551
- if (stringValue(payload.type) === "user_message") {
31552
- text2 = stringValue(payload.message) ?? "";
31553
- } else if (stringValue(payload.type) === "message" && payload.role === "user") {
31554
- text2 = recordsValue(payload.content).map((part) => stringValue(part.text) ?? stringValue(part.input_text) ?? "").join(`
31555
- `);
31556
- }
31557
- if (text2 && decodeCodexStructuredUserText(text2).structured)
31558
- operatorActions.add(atMs);
31559
- continue;
31560
- }
31561
- if (!isTurnStart(record9, false))
31562
- continue;
31563
- const originKind = typeof record9.origin === "string" ? record9.origin : stringValue(recordValue(record9.origin)?.kind);
31564
- if (originKind === "human" || record9.promptSource === "typed") {
31565
- operatorActions.add(atMs);
31566
- } else if (!isClaudeProtocolUser(record9)) {
31567
- unprovenancedUserActions.add(atMs);
31568
- }
31569
32653
  }
31570
32654
  return {
31571
32655
  windows: recentTurnWindowsFromRecords(records, codex),
31572
- operatorActionsAtMs: [...operatorActions].sort((left, right) => left - right),
31573
- unprovenancedUserActionsAtMs: [...unprovenancedUserActions].sort((left, right) => left - right),
31574
32656
  assistantMessagesAtMs: [...assistantMessages].sort((left, right) => left - right)
31575
32657
  };
31576
32658
  }
@@ -31620,7 +32702,6 @@ function lastAssistantMessageAtFor(entry) {
31620
32702
  }
31621
32703
  var turnBoundaryCache, recentTurnWindowsCache;
31622
32704
  var init_turnDuration = __esm(() => {
31623
- init_codexStructuredUserText();
31624
32705
  init_activity();
31625
32706
  init_caches();
31626
32707
  init_json();
@@ -32051,11 +33132,11 @@ function readState() {
32051
33132
  if (!value || typeof value !== "object" || Array.isArray(value))
32052
33133
  continue;
32053
33134
  const file = value;
32054
- if (file.rootName !== "codex-sessions" && file.rootName !== "claude-projects" && file.rootName !== "claude-tasks" || typeof file.size !== "number" || typeof file.mtimeMs !== "number" || typeof file.stateKey !== "string" || typeof file.project !== "string" || file.projectName !== undefined && typeof file.projectName !== "string" || file.projectUnresolved !== undefined && file.projectUnresolved !== true || file.projectRoot !== undefined && file.projectRoot !== null && typeof file.projectRoot !== "string" || typeof file.kind !== "string") {
33135
+ if (file.rootName !== "codex-sessions" && file.rootName !== "claude-projects" && file.rootName !== "claude-tasks" && file.rootName !== "openclaw-sessions" || typeof file.size !== "number" || typeof file.mtimeMs !== "number" || typeof file.stateKey !== "string" || typeof file.project !== "string" || file.projectName !== undefined && typeof file.projectName !== "string" || file.projectUnresolved !== undefined && file.projectUnresolved !== true || file.projectRoot !== undefined && file.projectRoot !== null && typeof file.projectRoot !== "string" || typeof file.kind !== "string") {
32055
33136
  continue;
32056
33137
  }
32057
- const engine = file.engine === "codex" || file.engine === "claude" || file.engine === "shell" ? file.engine : undefined;
32058
- const fmt = file.fmt === "codex" || file.fmt === "claude" || file.fmt === "plain" ? file.fmt : undefined;
33138
+ const engine = file.engine === "codex" || file.engine === "claude" || file.engine === "shell" || file.engine === "openclaw" ? file.engine : undefined;
33139
+ const fmt = file.fmt === "codex" || file.fmt === "claude" || file.fmt === "plain" || file.fmt === "openclaw" ? file.fmt : undefined;
32059
33140
  const cwd = typeof file.cwd === "string" ? file.cwd : file.cwd === null ? null : undefined;
32060
33141
  const sessionStartedAt = typeof file.sessionStartedAt === "string" ? file.sessionStartedAt : file.sessionStartedAt === null ? null : undefined;
32061
33142
  const nativeParentThreadId = typeof file.nativeParentThreadId === "string" ? file.nativeParentThreadId : file.nativeParentThreadId === null ? null : undefined;
@@ -32128,13 +33209,15 @@ function writeState(state3) {
32128
33209
  }
32129
33210
  }
32130
33211
  function isConversation(rootName, kind) {
32131
- return rootName === "codex-sessions" || rootName === "claude-projects" && (kind === "session" || kind === "subagent");
33212
+ return rootName === "codex-sessions" || rootName === "openclaw-sessions" || rootName === "claude-projects" && (kind === "session" || kind === "subagent");
32132
33213
  }
32133
33214
  function engineForRoot(rootName) {
32134
33215
  if (rootName === "codex-sessions")
32135
33216
  return "codex";
32136
33217
  if (rootName === "claude-projects")
32137
33218
  return "claude";
33219
+ if (rootName === "openclaw-sessions")
33220
+ return "openclaw";
32138
33221
  return "shell";
32139
33222
  }
32140
33223
  function fmtForRoot(rootName) {
@@ -32142,6 +33225,8 @@ function fmtForRoot(rootName) {
32142
33225
  return "codex";
32143
33226
  if (rootName === "claude-projects")
32144
33227
  return "claude";
33228
+ if (rootName === "openclaw-sessions")
33229
+ return "openclaw";
32145
33230
  return "plain";
32146
33231
  }
32147
33232
  function fallbackTitle(raw, kind) {
@@ -32152,6 +33237,8 @@ function fallbackTitle(raw, kind) {
32152
33237
  return "Codex session";
32153
33238
  if (raw.rootName === "claude-projects")
32154
33239
  return "Claude session";
33240
+ if (raw.rootName === "openclaw-sessions")
33241
+ return "OpenClaw session";
32155
33242
  return "Background task " + filename.split(".")[0];
32156
33243
  }
32157
33244
  function storeCachedFile(state3, file) {
@@ -32439,7 +33526,7 @@ async function projectCatalogSnapshotFromRaw(raw, options = {}) {
32439
33526
  kind: file.kind,
32440
33527
  fmt: file.fmt
32441
33528
  });
32442
- if (!file.session || file.engine !== "codex" && file.engine !== "claude")
33529
+ if (!file.session || file.engine !== "codex" && file.engine !== "claude" && file.engine !== "openclaw")
32443
33530
  return;
32444
33531
  conversationCatalog.push({
32445
33532
  path: file.path,
@@ -32655,6 +33742,8 @@ async function walkPaths(rootName, root, dir, limit) {
32655
33742
  }
32656
33743
  if (!entry.isFile() || !EXTS.some((ext) => entry.name.endsWith(ext)))
32657
33744
  return { paths: [], complete: true };
33745
+ if (rootName === "openclaw-sessions" && !isOpenclawTranscript(entry.name))
33746
+ return { paths: [], complete: true };
32658
33747
  return { paths: [{ rootName, root, path: path55.join(dir, entry.name) }], complete: true };
32659
33748
  }));
32660
33749
  return {
@@ -32724,13 +33813,13 @@ function canonicalizerFor(roots) {
32724
33813
  function transcriptIndexFeed(catalog, complete, projectByPath) {
32725
33814
  return {
32726
33815
  complete,
32727
- sources: catalog.map((entry) => ({
33816
+ sources: catalog.flatMap((entry) => entry.engine === "openclaw" ? [] : [{
32728
33817
  path: entry.path,
32729
33818
  project: projectByPath?.get(entry.path) ?? entry.project,
32730
33819
  engine: entry.engine,
32731
33820
  size: entry.size,
32732
33821
  mtimeMs: entry.mtime * 1000
32733
- }))
33822
+ }])
32734
33823
  };
32735
33824
  }
32736
33825
  function publishTranscriptIndexFeed(catalog, complete, scanToken, projectByPath, scheduler) {
@@ -32776,7 +33865,7 @@ function isLiveEntry(entry, hosted) {
32776
33865
  return true;
32777
33866
  if (!entry.path.endsWith(".jsonl"))
32778
33867
  return false;
32779
- const turn = cachedTranscriptTurn(entry.path, entry.st.size, entry.st.mtimeMs, entry.rootName === "codex-sessions");
33868
+ const turn = cachedTranscriptTurn(entry.path, entry.st.size, entry.st.mtimeMs, transcriptEngineForRoot(entry.rootName));
32780
33869
  return turn?.state === "busy";
32781
33870
  }
32782
33871
  async function primeElidedOpenTurns(ranked, selected) {
@@ -32787,13 +33876,13 @@ async function primeElidedOpenTurns(ranked, selected) {
32787
33876
  break;
32788
33877
  if (selected.has(entry.path) || !entry.path.endsWith(".jsonl") || entry.st.mtimeMs <= horizon)
32789
33878
  continue;
32790
- const codex = entry.rootName === "codex-sessions";
32791
- if (!cachedTranscriptTurn(entry.path, entry.st.size, entry.st.mtimeMs, codex))
33879
+ const engine = transcriptEngineForRoot(entry.rootName);
33880
+ if (!cachedTranscriptTurn(entry.path, entry.st.size, entry.st.mtimeMs, engine))
32792
33881
  candidates.push(entry);
32793
33882
  }
32794
33883
  let open = false;
32795
33884
  await forEachCooperatively(candidates, (entry) => {
32796
- const turn = transcriptTurnResult(entry.path, entry.st.size, entry.st.mtimeMs, entry.rootName === "codex-sessions", false);
33885
+ const turn = transcriptTurnResult(entry.path, entry.st.size, entry.st.mtimeMs, transcriptEngineForRoot(entry.rootName), false);
32797
33886
  open ||= turn.turn.state === "busy";
32798
33887
  });
32799
33888
  return open;
@@ -32822,7 +33911,7 @@ function resourceScopeFromPaths(raw, baseline) {
32822
33911
  const conversations = raw.filter((entry) => entry.rootName !== "claude-tasks" && entry.path.endsWith(".jsonl"));
32823
33912
  const files = conversations.map((entry) => {
32824
33913
  const previous = previousByPath.get(entry.path);
32825
- const engine = entry.rootName === "codex-sessions" ? "codex" : "claude";
33914
+ const engine = entry.rootName === "codex-sessions" ? "codex" : entry.rootName === "openclaw-sessions" ? "openclaw" : "claude";
32826
33915
  const mtime = previous?.mtime ?? Date.now() / 1000;
32827
33916
  const size = previous?.size ?? 1;
32828
33917
  const activity = resourceActivity(previous, mtime, size);
@@ -32840,7 +33929,7 @@ function resourceScopeFromPaths(raw, baseline) {
32840
33929
  nativeForkSourceThreadId: previous?.nativeForkSourceThreadId,
32841
33930
  projectRoot: previous?.projectRoot,
32842
33931
  worktree: previous?.worktree,
32843
- title: previous?.title ?? (filename.startsWith("agent-") ? `Subagent ${filename.slice(6).split(".")[0]}` : `${engine === "codex" ? "Codex" : "Claude"} session`),
33932
+ title: previous?.title ?? (filename.startsWith("agent-") ? `Subagent ${filename.slice(6).split(".")[0]}` : `${ENGINE_LABEL[engine]} session`),
32844
33933
  engine,
32845
33934
  kind: previous?.kind ?? (filename.startsWith("agent-") ? "subagent" : "session"),
32846
33935
  fmt: engine,
@@ -33020,13 +34109,14 @@ async function discoverFiles(roots = scanRootEntries(), demote, pin, hosted) {
33020
34109
  publishTranscriptIndexFeed(snapshot2.conversationCatalog, snapshot2.complete, scanToken, projectByPath);
33021
34110
  return entries.files;
33022
34111
  }
33023
- var DISCOVERY_DIAGNOSTIC_MS = 60000, lastDiscoveryDiagnosticAt, OPEN_TURN_PROBE_WINDOW_MS = 180000, OPEN_TURN_PROBE_LIMIT = 32;
34112
+ var DISCOVERY_DIAGNOSTIC_MS = 60000, lastDiscoveryDiagnosticAt, OPEN_TURN_PROBE_WINDOW_MS = 180000, OPEN_TURN_PROBE_LIMIT = 32, ENGINE_LABEL;
33024
34113
  var init_discover = __esm(() => {
33025
34114
  init_cooperative();
33026
34115
  init_titleProjection();
33027
34116
  init_transcriptFeed();
33028
34117
  init_claudeNative();
33029
34118
  init_codexNative();
34119
+ init_openclawNative();
33030
34120
  init_describe();
33031
34121
  init_projectCatalog();
33032
34122
  init_projectState();
@@ -33034,6 +34124,7 @@ var init_discover = __esm(() => {
33034
34124
  init_activity();
33035
34125
  init_transcriptIdentity();
33036
34126
  lastDiscoveryDiagnosticAt = Number.NEGATIVE_INFINITY;
34127
+ ENGINE_LABEL = { codex: "Codex", claude: "Claude", openclaw: "OpenClaw" };
33037
34128
  });
33038
34129
 
33039
34130
  // src/lib/scanner/effort.ts
@@ -33050,6 +34141,9 @@ function pickEffort(entry, obj) {
33050
34141
  const settings = recordValue(recordValue(payload?.collaboration_mode)?.settings);
33051
34142
  return stringValue(settings?.reasoning_effort);
33052
34143
  }
34144
+ if (entry.root === "openclaw-sessions" && obj.type === "thinking_level_change") {
34145
+ return stringValue(obj.thinkingLevel);
34146
+ }
33053
34147
  if (entry.root === "claude-projects" && obj.type === "assistant") {
33054
34148
  const message = recordValue(obj.message);
33055
34149
  const content = recordsValue(message?.content);
@@ -33077,7 +34171,7 @@ function entryEffort(entry) {
33077
34171
  return entryEffortResult(entry).value;
33078
34172
  }
33079
34173
  function entryEffortResult(entry) {
33080
- if (entry.root !== "claude-projects" && entry.root !== "codex-sessions" || !entry.path.endsWith(".jsonl")) {
34174
+ if (entry.root !== "claude-projects" && entry.root !== "codex-sessions" && entry.root !== "openclaw-sessions" || !entry.path.endsWith(".jsonl")) {
33081
34175
  return { value: null, complete: true };
33082
34176
  }
33083
34177
  const argv = normalizeEffort(argvEffort(entry));
@@ -33128,7 +34222,32 @@ var init_effort = __esm(() => {
33128
34222
  init_json();
33129
34223
  init_process();
33130
34224
  effortCache = globalCache("effort");
33131
- TIERS = new Set(["minimal", "low", "medium", "high", "xhigh", "max", "ultra"]);
34225
+ TIERS = new Set(["off", "minimal", "low", "medium", "high", "xhigh", "max", "ultra", "adaptive"]);
34226
+ });
34227
+
34228
+ // src/lib/agent/spawnProjection.ts
34229
+ function durableHandoffProvenanceForConversation(snapshot2, conversationId, lookup = readOnlyConversationLookupFromSnapshot(snapshot2)) {
34230
+ const canonicalConversationId3 = lookup.canonicalConversationId(conversationId);
34231
+ const edge = snapshot2.lineageEdges[canonicalConversationId3];
34232
+ if (!edge || edge.source !== "viewer-spawn")
34233
+ return null;
34234
+ const receipt = edge.evidence.launchId ? snapshot2.receipts[edge.evidence.launchId] : null;
34235
+ const parentConversationId = lookup.canonicalConversationId(edge.parentConversationId);
34236
+ const bornAt = receipt?.createdAt ?? edge.createdAt;
34237
+ const bornIntoContainer = (snapshot2.memberships[canonicalConversationId3] ?? []).some((membership) => membership.createdAt === bornAt && membership.parentConversationId !== null && lookup.canonicalConversationId(membership.parentConversationId) === parentConversationId);
34238
+ const parentSource = edge.evidence.parentSource ?? receipt?.parentSource ?? null;
34239
+ const delegatedAtBirth = receipt?.delegationDepth !== null && receipt?.delegationDepth !== undefined && receipt.delegationDepth > 0;
34240
+ if (bornIntoContainer || parentSource === "inferred-caller" || delegatedAtBirth)
34241
+ return "container-spawn";
34242
+ return "operator-handoff";
34243
+ }
34244
+ var TERMINAL_SPAWN_RECENT_MS, PLACEHOLDER_RETIREMENT_MS;
34245
+ var init_spawnProjection = __esm(() => {
34246
+ init_registry();
34247
+ init_describe();
34248
+ init_projectResolution();
34249
+ TERMINAL_SPAWN_RECENT_MS = 15 * 60 * 1000;
34250
+ PLACEHOLDER_RETIREMENT_MS = 24 * 60 * 60 * 1000;
33132
34251
  });
33133
34252
 
33134
34253
  // src/lib/scanner/needle.ts
@@ -33800,6 +34919,26 @@ function bgCommand(tid, transcripts, fallbackTranscripts, budget) {
33800
34919
  }
33801
34920
  return weak;
33802
34921
  }
34922
+ function durableHandoffLineageFromSnapshot(snapshot2) {
34923
+ const lookup = readOnlyConversationLookupFromSnapshot(snapshot2);
34924
+ return {
34925
+ provenanceForChild(pathname) {
34926
+ const conversation = lookup.conversationForPath(pathname);
34927
+ if (!conversation)
34928
+ return null;
34929
+ return durableHandoffProvenanceForConversation(snapshot2, conversation.id, lookup);
34930
+ }
34931
+ };
34932
+ }
34933
+ function currentDurableHandoffLineage() {
34934
+ try {
34935
+ return durableHandoffLineageFromSnapshot(agentRegistry().readOnlySnapshot());
34936
+ } catch (error) {
34937
+ if (error instanceof RegistryReadError)
34938
+ return { provenanceForChild: () => null };
34939
+ throw error;
34940
+ }
34941
+ }
33803
34942
  function loadLineage() {
33804
34943
  if (lineageLoaded)
33805
34944
  return;
@@ -33897,9 +35036,12 @@ async function attachLiveCodexParents(entries, persist) {
33897
35036
  if (persist)
33898
35037
  persistLineage();
33899
35038
  }
33900
- async function attachHandoffParents(entries, persist) {
35039
+ async function attachHandoffParents(entries, persist, durableLineage) {
33901
35040
  const byPath = new Map(entries.map((entry) => [entry.path, entry]));
33902
35041
  await forEachCooperatively(entries, (entry) => {
35042
+ const durableProvenance = durableLineage.provenanceForChild(entry.path);
35043
+ if (durableProvenance === "container-spawn")
35044
+ delete entry.handoff;
33903
35045
  if (entry.parent)
33904
35046
  return;
33905
35047
  if (entry.root !== "claude-projects" && entry.root !== "codex-sessions")
@@ -33922,7 +35064,8 @@ async function attachHandoffParents(entries, persist) {
33922
35064
  }
33923
35065
  if (parent && parent !== entry.path && byPath.has(parent)) {
33924
35066
  entry.parent = parent;
33925
- entry.handoff = true;
35067
+ if (durableProvenance !== "container-spawn")
35068
+ entry.handoff = true;
33926
35069
  }
33927
35070
  });
33928
35071
  if (persist)
@@ -33930,6 +35073,7 @@ async function attachHandoffParents(entries, persist) {
33930
35073
  }
33931
35074
  async function linkEntries(entries, options = {}) {
33932
35075
  const persist = options.persist !== false;
35076
+ const durableHandoffLineage = options.durableHandoffLineage ?? currentDurableHandoffLineage();
33933
35077
  loadBackgroundCommands();
33934
35078
  loadCompactChains();
33935
35079
  const limit = createLimiter2(48);
@@ -33988,7 +35132,7 @@ async function linkEntries(entries, options = {}) {
33988
35132
  });
33989
35133
  await attachNativeCodexSubagentParents(entries, persist);
33990
35134
  await attachLiveCodexParents(entries, persist);
33991
- await attachHandoffParents(entries, persist);
35135
+ await attachHandoffParents(entries, persist, durableHandoffLineage);
33992
35136
  await chainCompactedSessions(entries);
33993
35137
  const rootProject = (entry) => {
33994
35138
  const seen = new Set;
@@ -34018,6 +35162,8 @@ var sidSlugCache, bgcmdCache, backgroundIndexCache, chainCache, compactLinkCache
34018
35162
  var init_links = __esm(() => {
34019
35163
  init_configDir();
34020
35164
  init_handoffLineage();
35165
+ init_registry();
35166
+ init_spawnProjection();
34021
35167
  init_cooperative();
34022
35168
  init_caches();
34023
35169
  init_claudeNative();
@@ -34055,6 +35201,8 @@ function pickModel(entry, obj) {
34055
35201
  if (obj.type === "turn_context" || obj.type === "session_meta") {
34056
35202
  return stringValue(recordValue(obj.payload)?.model);
34057
35203
  }
35204
+ } else if (entry.root === "openclaw-sessions") {
35205
+ return stringValue(openclawProviderAssistant(obj)?.model);
34058
35206
  } else if (obj.type === "assistant") {
34059
35207
  const model = stringValue(recordValue(obj.message)?.model);
34060
35208
  if (model && model !== "<synthetic>")
@@ -34069,7 +35217,7 @@ function entryModelsResult(entry) {
34069
35217
  if (model2)
34070
35218
  return { value: { display: shortModel(model2), launch: model2 }, complete: true };
34071
35219
  }
34072
- if (entry.root !== "claude-projects" && entry.root !== "codex-sessions" || !entry.path.endsWith(".jsonl")) {
35220
+ if (entry.root !== "claude-projects" && entry.root !== "codex-sessions" && entry.root !== "openclaw-sessions" || !entry.path.endsWith(".jsonl")) {
34073
35221
  return { value: { display: null, launch: null }, complete: true };
34074
35222
  }
34075
35223
  const mtimeMs = entry.mtime * 1000;
@@ -34103,6 +35251,7 @@ var init_model = __esm(() => {
34103
35251
  init_activity();
34104
35252
  init_caches();
34105
35253
  init_json();
35254
+ init_openclawNative();
34106
35255
  modelCache = globalCache("model");
34107
35256
  });
34108
35257
 
@@ -34768,8 +35917,8 @@ async function listFilesInternal(includeProjectCatalog, selectedProject, options
34768
35917
  entry.activity = verdict.state;
34769
35918
  entry.activityReason = verdict.reason;
34770
35919
  entry.derivationComplete = verdict.complete;
34771
- if (entry.path.endsWith(".jsonl") && (entry.engine === "claude" || entry.engine === "codex")) {
34772
- const authoritative = transcriptTurnResult(entry.path, entry.size, entry.mtime * 1000, entry.engine === "codex");
35920
+ if (entry.path.endsWith(".jsonl") && (entry.engine === "claude" || entry.engine === "codex" || entry.engine === "openclaw")) {
35921
+ const authoritative = transcriptTurnResult(entry.path, entry.size, entry.mtime * 1000, entry.engine);
34773
35922
  entry.derivationComplete &&= authoritative.complete;
34774
35923
  if (authoritative.complete)
34775
35924
  entry.authoritativeTurn = authoritative.turn;
@@ -35359,6 +36508,12 @@ function beginRegistryResume(entry, spec, registry = agentRegistry()) {
35359
36508
  return null;
35360
36509
  const conversation = registry.conversationForPath(entry.path) ?? registry.ensureConversation(entry.engine, entry.path, null);
35361
36510
  const current = conversation.generations.at(-1);
36511
+ const launchProfile = emptyLaunchProfile({
36512
+ ...current?.launchProfile ?? {},
36513
+ ...spec.launchProfile ?? {},
36514
+ cwd: spec.launchProfile?.cwd || current?.launchProfile.cwd || spec.cwd,
36515
+ title: durableSemanticTitle(current?.launchProfile.title, 120) ?? durableSemanticTitle(spec.launchProfile?.title, 120) ?? derivedSpawnTitle("resume", current?.launchProfile.goal?.objective ?? spec.cwd, "Conversation resume")
36516
+ });
35362
36517
  const begun = registry.beginSpawnRequest({
35363
36518
  engine: entry.engine,
35364
36519
  cwd: spec.cwd,
@@ -35366,9 +36521,9 @@ function beginRegistryResume(entry, spec, registry = agentRegistry()) {
35366
36521
  conversationId: conversation.id,
35367
36522
  purpose: "resume-successor",
35368
36523
  origin: { kind: "successor" },
35369
- launchProfile: spec.launchProfile ?? current?.launchProfile
36524
+ launchProfile
35370
36525
  });
35371
- return { receipt: begun.receipt, spec };
36526
+ return { receipt: begun.receipt, spec: { ...spec, launchProfile } };
35372
36527
  }
35373
36528
  async function serializeRegistryDelivery(entry, task) {
35374
36529
  if (entry.engine !== "claude" && entry.engine !== "codex")
@@ -35385,6 +36540,7 @@ async function serializeRegistryDelivery(entry, task) {
35385
36540
  }
35386
36541
  var UUID_RE4, MAX_ANCESTRY_HOPS2 = 64, CLAIM_RANK, globalStore, TranscriptHostConflictError, runtimeResolver, readTranscriptHosts, deliverToTranscriptHost;
35387
36542
  var init_transcriptHost = __esm(() => {
36543
+ init_contracts2();
35388
36544
  init_registry();
35389
36545
  init_sessionKey();
35390
36546
  init_proc();
@@ -35393,6 +36549,7 @@ var init_transcriptHost = __esm(() => {
35393
36549
  init_process();
35394
36550
  init_claudeNative();
35395
36551
  init_tmux();
36552
+ init_title();
35396
36553
  UUID_RE4 = /[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}/i;
35397
36554
  CLAIM_RANK = {
35398
36555
  scanner: 3,
@@ -35570,6 +36727,10 @@ function reserveReviewerSpawn(flow, round, role, accountId, registry = agentRegi
35570
36727
  const reviewerBindingId = round.reviewerBindingId ?? crypto32.randomUUID();
35571
36728
  round.reviewerBindingId = reviewerBindingId;
35572
36729
  const correlation = crypto32.createHash("sha256").update(`${flow.id}:${round.n}:${reviewerBindingId}`).digest("hex").slice(0, 24);
36730
+ const clientAttemptId = `flow_${flow.id}_${correlation}`;
36731
+ const reservedTitle = durableSemanticTitle(registry.spawnReceiptForClientAttempt(clientAttemptId)?.launchProfile.title, 120);
36732
+ const flowTitle = firstPromptLine(flow.spec ?? "", 80) ?? durableSemanticTitle(owner.generations.at(-1)?.launchProfile.title, 80) ?? semanticTitle(flow.project, 80) ?? "Review flow";
36733
+ const reviewerTitle = reservedTitle ?? cleanTitle(`${flowTitle} \xB7 review round ${round.n}`, 120);
35573
36734
  const begun = registry.beginSpawnRequest({
35574
36735
  engine: role.engine,
35575
36736
  cwd: flow.cwd,
@@ -35581,6 +36742,11 @@ function reserveReviewerSpawn(flow, round, role, accountId, registry = agentRegi
35581
36742
  role: "reviewer",
35582
36743
  reviewsConversationId: owner.id,
35583
36744
  origin: { kind: "container", container: "flow", containerId: flow.id, creatorConversationId: null },
36745
+ launchProfile: emptyLaunchProfile({
36746
+ cwd: flow.cwd,
36747
+ parentConversationId: owner.id,
36748
+ title: reviewerTitle
36749
+ }),
35584
36750
  memberships: [{
35585
36751
  kind: "flow",
35586
36752
  containerId: flow.id,
@@ -35591,7 +36757,7 @@ function reserveReviewerSpawn(flow, round, role, accountId, registry = agentRegi
35591
36757
  round: round.n,
35592
36758
  parentConversationId: owner.id
35593
36759
  }],
35594
- clientAttemptId: `flow_${flow.id}_${correlation}`,
36760
+ clientAttemptId,
35595
36761
  requestDigest: crypto32.createHash("sha256").update(JSON.stringify({
35596
36762
  flowId: flow.id,
35597
36763
  round: round.n,
@@ -36442,6 +37608,7 @@ var TERMINAL_STATES3, READY_RE, UUID_RE5, store3, relayStartedThisProcess, relay
36442
37608
  var init_engine3 = __esm(() => {
36443
37609
  init_cli();
36444
37610
  init_manager();
37611
+ init_contracts2();
36445
37612
  init_transcriptHost();
36446
37613
  init_registry();
36447
37614
  init_sessionKey();
@@ -36451,6 +37618,7 @@ var init_engine3 = __esm(() => {
36451
37618
  init_structuredMessageDelivery();
36452
37619
  init_structuredRecovery();
36453
37620
  init_status();
37621
+ init_title();
36454
37622
  init_tmux();
36455
37623
  init_exec();
36456
37624
  init_git();
@@ -36623,11 +37791,11 @@ class PreserializedJson {
36623
37791
  // src/runtime-host/runtimeHostFence.ts
36624
37792
  import crypto33 from "crypto";
36625
37793
  import fs63 from "fs";
36626
- import { createRequire as createRequire2 } from "module";
37794
+ import { createRequire as createRequire3 } from "module";
36627
37795
  import path59 from "path";
36628
37796
  function flock(fd, operation) {
36629
37797
  if (!cachedFlock) {
36630
- const runtimeRequire = createRequire2(import.meta.url);
37798
+ const runtimeRequire = createRequire3(import.meta.url);
36631
37799
  const ffi = runtimeRequire(`bun:${"ffi"}`);
36632
37800
  const library = ffi.dlopen(process.platform === "darwin" ? "/usr/lib/libSystem.B.dylib" : "libc.so.6", {
36633
37801
  flock: {
@@ -38175,7 +39343,7 @@ class RuntimeJournal {
38175
39343
  if (!session || session.host !== "hosted") {
38176
39344
  status = "rejected";
38177
39345
  reason = session?.host === "dead" || session?.host === "unhosted" ? "dead-host" : "no-claim";
38178
- } else if (!capability.supported || session.hostKind !== "codex-app-server") {
39346
+ } else if (!capability.supported || session.hostKind !== "codex-app-server" && session.hostKind !== "claude-broker") {
38179
39347
  status = "rejected";
38180
39348
  reason = "unsupported-capability";
38181
39349
  } else if (session.sessionKey.engine !== command.sessionKey.engine || session.sessionKey.sessionId !== command.sessionKey.sessionId) {
@@ -38210,6 +39378,7 @@ class RuntimeJournal {
38210
39378
  status = "queued";
38211
39379
  }
38212
39380
  const revision = Number(this.db.query("SELECT revision FROM scope_revisions WHERE scope = ?").get(`operation:${operationId}`)?.revision ?? 0) + 1;
39381
+ const admittedAt = new Date(this.now()).toISOString();
38213
39382
  return {
38214
39383
  operationId,
38215
39384
  ...retryOfOperationId ? { retryOfOperationId } : {},
@@ -38227,7 +39396,8 @@ class RuntimeJournal {
38227
39396
  text: command.kind === "send" || command.kind === "steer" ? command.text.slice(0, 240) : null,
38228
39397
  ...command.kind === "send" || command.kind === "steer" ? { imageCount: command.images?.length ?? 0 } : {},
38229
39398
  ...(command.kind === "send" || command.kind === "steer") && command.runtime ? { runtime: command.runtime } : {},
38230
- at: new Date(this.now()).toISOString(),
39399
+ at: admittedAt,
39400
+ admittedAt,
38231
39401
  revision
38232
39402
  };
38233
39403
  }
@@ -39162,6 +40332,7 @@ class ViewerDeploymentCoordinator {
39162
40332
  ownerAlive;
39163
40333
  hostGeneration;
39164
40334
  onHostHandoff;
40335
+ log;
39165
40336
  constructor(journal, adapter, owner, options = {}) {
39166
40337
  this.journal = journal;
39167
40338
  this.adapter = adapter;
@@ -39170,6 +40341,7 @@ class ViewerDeploymentCoordinator {
39170
40341
  this.ownerAlive = options.ownerAlive ?? ((candidate) => procBackend.pidAlive(candidate.pid) && (candidate.startIdentity === null || procBackend.processIdentity(candidate.pid) === candidate.startIdentity));
39171
40342
  this.hostGeneration = options.hostGeneration;
39172
40343
  this.onHostHandoff = options.onHostHandoff;
40344
+ this.log = options.log ?? ((line) => console.error(line));
39173
40345
  }
39174
40346
  async requestViewerDeployment(request) {
39175
40347
  return this.runAdmissionExclusive(() => this.admit(request));
@@ -39262,12 +40434,19 @@ class ViewerDeploymentCoordinator {
39262
40434
  return this.journal.viewerDeployment(deploymentId);
39263
40435
  }
39264
40436
  async stageDriftedHostSuccessor(status) {
39265
- if (!this.hostGeneration || !status.candidate)
40437
+ const trace = (line) => this.log(`[viewer deployment] ${status.deploymentId} host-handoff ${line}`);
40438
+ if (!this.hostGeneration || !status.candidate) {
40439
+ trace("skipped: this runtime host does not track its own generation, so no successor can be staged");
39266
40440
  return null;
40441
+ }
39267
40442
  const running = this.hostGeneration();
39268
- if (running.revision === status.revision && running.image === status.candidate.image)
40443
+ if (running.revision === status.revision && running.image === status.candidate.image) {
40444
+ trace(`not required: the runtime host already runs ${status.revision}`);
39269
40445
  return null;
40446
+ }
40447
+ trace(`staging a successor for ${status.revision}; the running generation is ${running.revision ?? "untracked"}`);
39270
40448
  await this.adapter.stageRuntimeHostSuccessor(status.candidate);
40449
+ trace(`staged; the successor waits for the singleton fence while this generation hands off ${status.revision}`);
39271
40450
  return {
39272
40451
  deploymentId: status.deploymentId,
39273
40452
  revision: status.revision,
@@ -39278,7 +40457,7 @@ class ViewerDeploymentCoordinator {
39278
40457
  start(status) {
39279
40458
  if (this.tasks.has(status.deploymentId) || status.terminal)
39280
40459
  return;
39281
- const task = this.run(status).catch((error) => console.error(`[viewer deployment] ${safeError3(error)}`)).finally(() => this.tasks.delete(status.deploymentId));
40460
+ const task = this.run(status).catch((error) => this.log(`[viewer deployment] ${safeError3(error)}`)).finally(() => this.tasks.delete(status.deploymentId));
39282
40461
  this.tasks.set(status.deploymentId, task);
39283
40462
  }
39284
40463
  async run(initial) {
@@ -39339,6 +40518,9 @@ class ViewerDeploymentCoordinator {
39339
40518
  if (!status.candidate)
39340
40519
  throw new Error("candidate identity is missing");
39341
40520
  const publication = await this.adapter.promote(status.candidate);
40521
+ if (publication.hotStateHandOver) {
40522
+ this.log(`[viewer deployment] ${status.deploymentId} promote hot-state hand-over: ${publication.hotStateHandOver}`);
40523
+ }
39342
40524
  const runtime2 = mcpRuntimeStatus(status);
39343
40525
  status = this.journal.updateViewerDeployment(status.deploymentId, {
39344
40526
  phase: "post-promotion-health",
@@ -39405,6 +40587,7 @@ class ViewerDeploymentCoordinator {
39405
40587
  const message = safeError3(error);
39406
40588
  const latest = this.journal.viewerDeployment(status.deploymentId) ?? status;
39407
40589
  if (latest.phase === "host-handoff") {
40590
+ this.log(`[viewer deployment] ${latest.deploymentId} host-handoff failed and stays retryable: ${message}`);
39408
40591
  this.journal.updateViewerDeployment(latest.deploymentId, {
39409
40592
  error: message,
39410
40593
  phase: "host-handoff",
@@ -39458,15 +40641,24 @@ var init_deployment = __esm(() => {
39458
40641
  init_contracts3();
39459
40642
  });
39460
40643
 
40644
+ // src/runtime-host/deploymentHotState.ts
40645
+ var HOT_STATE_ACTIVATION_TIMEOUT_MS = 180000, INCUMBENT_RELEASE_TIMEOUT_MS = 15000, CONTAINER_INSPECTION_TIMEOUT_MS = 5000, PROMOTE_PUBLICATION_BUDGET_MS = 60000, HAND_OVER_BUDGET_MS, PROMOTE_ACTION_TIMEOUT_MS, INSPECTION_EXPIRED;
40646
+ var init_deploymentHotState = __esm(() => {
40647
+ init_hotStateAuthority();
40648
+ HAND_OVER_BUDGET_MS = INCUMBENT_RELEASE_TIMEOUT_MS + HOT_STATE_ACTIVATION_TIMEOUT_MS;
40649
+ PROMOTE_ACTION_TIMEOUT_MS = HAND_OVER_BUDGET_MS + PROMOTE_PUBLICATION_BUDGET_MS + 2 * CONTAINER_INSPECTION_TIMEOUT_MS;
40650
+ INSPECTION_EXPIRED = Symbol("container inspection expired");
40651
+ });
40652
+
39461
40653
  // src/runtime-host/mcpHealthProbeAdmissionChannel.ts
39462
40654
  import fs66 from "fs";
39463
40655
  import net3 from "net";
39464
- import { createRequire as createRequire3 } from "module";
39465
- import os11 from "os";
40656
+ import { createRequire as createRequire4 } from "module";
40657
+ import os12 from "os";
39466
40658
  import path61 from "path";
39467
40659
  function duplicateDescriptor(fd) {
39468
40660
  if (!cachedDup) {
39469
- const runtimeRequire = createRequire3(import.meta.url);
40661
+ const runtimeRequire = createRequire4(import.meta.url);
39470
40662
  const ffi = runtimeRequire(`bun:${"ffi"}`);
39471
40663
  const library = ffi.dlopen(process.platform === "darwin" ? "/usr/lib/libSystem.B.dylib" : "libc.so.6", {
39472
40664
  dup: {
@@ -39479,7 +40671,7 @@ function duplicateDescriptor(fd) {
39479
40671
  return cachedDup(fd);
39480
40672
  }
39481
40673
  async function createMcpHealthProbeAdmissionChannel() {
39482
- const directory = fs66.mkdtempSync(path61.join(os11.tmpdir(), "llv-mcp-health-channel-"));
40674
+ const directory = fs66.mkdtempSync(path61.join(os12.tmpdir(), "llv-mcp-health-channel-"));
39483
40675
  const socketPath = path61.join(directory, "channel.sock");
39484
40676
  const server = net3.createServer({ pauseOnConnect: true });
39485
40677
  let accepted = null;
@@ -39734,12 +40926,50 @@ function publication(value) {
39734
40926
  if (item.action !== "activate" && item.action !== "restore" || typeof item.publishedAt !== "string" || item.durable !== true) {
39735
40927
  throw new Error("deployment adapter returned invalid MCP runtime publication evidence");
39736
40928
  }
39737
- return { ...runtime2, action: item.action, publishedAt: item.publishedAt, durable: true };
40929
+ const hotStateHandOver = typeof item.hotStateHandOver === "string" ? item.hotStateHandOver.slice(0, 200) : null;
40930
+ return {
40931
+ ...runtime2,
40932
+ action: item.action,
40933
+ publishedAt: item.publishedAt,
40934
+ durable: true,
40935
+ ...hotStateHandOver ? { hotStateHandOver } : {}
40936
+ };
40937
+ }
40938
+ function probeObservations(value) {
40939
+ if (!Array.isArray(value))
40940
+ throw new Error("deployment adapter returned invalid health evidence");
40941
+ return value.map((entry) => {
40942
+ const item = object(entry);
40943
+ if (!PROBE_NAMES.includes(item.name) || typeof item.url !== "string" || typeof item.status !== "number" || typeof item.elapsedMs !== "number" || typeof item.expected !== "string" || typeof item.ok !== "boolean")
40944
+ throw new Error("deployment adapter returned invalid health evidence");
40945
+ return {
40946
+ name: item.name,
40947
+ url: item.url,
40948
+ status: item.status,
40949
+ elapsedMs: item.elapsedMs,
40950
+ expected: item.expected,
40951
+ ok: item.ok,
40952
+ ...typeof item.error === "string" ? { error: item.error } : {},
40953
+ ...typeof item.body === "string" ? { body: item.body } : {}
40954
+ };
40955
+ });
40956
+ }
40957
+ function readinessRecord(value) {
40958
+ const item = object(value);
40959
+ if (typeof item.attempts !== "number" || typeof item.maxAttempts !== "number" || typeof item.delayMs !== "number" || typeof item.elapsedMs !== "number")
40960
+ throw new Error("deployment adapter returned invalid health evidence");
40961
+ return {
40962
+ attempts: item.attempts,
40963
+ maxAttempts: item.maxAttempts,
40964
+ delayMs: item.delayMs,
40965
+ elapsedMs: item.elapsedMs,
40966
+ ...typeof item.firstDetail === "string" ? { firstDetail: item.firstDetail } : {}
40967
+ };
39738
40968
  }
39739
40969
  function evidence(value) {
39740
40970
  const item = object(value);
39741
40971
  const assets = Array.isArray(item.assets) ? item.assets.map((asset) => object(asset)) : [];
39742
- if (typeof item.checkedAt !== "string" || typeof item.endpoint !== "string" || typeof item.processReady !== "boolean" || typeof item.rootStatus !== "number" || item.authenticatedStatus !== null && typeof item.authenticatedStatus !== "number" || item.unauthorizedStatus !== null && typeof item.unauthorizedStatus !== "number" || typeof item.ok !== "boolean" || assets.some((asset) => typeof asset.path !== "string" || typeof asset.status !== "number"))
40972
+ if (typeof item.checkedAt !== "string" || typeof item.endpoint !== "string" || typeof item.processReady !== "boolean" || typeof item.rootStatus !== "number" || item.authenticatedStatus !== null && typeof item.authenticatedStatus !== "number" || item.unauthorizedStatus !== null && typeof item.unauthorizedStatus !== "number" || typeof item.ok !== "boolean" || assets.some((asset) => typeof asset.path !== "string" || typeof asset.status !== "number") || item.containerLog !== undefined && (!Array.isArray(item.containerLog) || item.containerLog.some((line) => typeof line !== "string")))
39743
40973
  throw new Error("deployment adapter returned invalid health evidence");
39744
40974
  return {
39745
40975
  checkedAt: item.checkedAt,
@@ -39749,6 +40979,9 @@ function evidence(value) {
39749
40979
  authenticatedStatus: item.authenticatedStatus,
39750
40980
  unauthorizedStatus: item.unauthorizedStatus,
39751
40981
  assets: assets.map((asset) => ({ path: asset.path, status: asset.status })),
40982
+ ...item.observations === undefined ? {} : { observations: probeObservations(item.observations) },
40983
+ ...item.readiness === undefined ? {} : { readiness: readinessRecord(item.readiness) },
40984
+ ...item.containerLog === undefined ? {} : { containerLog: item.containerLog },
39752
40985
  ...item.mcpRuntime === undefined ? {} : { mcpRuntime: mcpHealthEvidence(item.mcpRuntime) },
39753
40986
  ok: item.ok,
39754
40987
  ...typeof item.detail === "string" ? { detail: item.detail } : {}
@@ -39760,6 +40993,7 @@ function mcpHealthEvidence(value) {
39760
40993
  if (typeof item.checkedAt !== "string" || typeof item.revision !== "string" || !/^[0-9a-f]{40}$/.test(item.revision) || typeof item.artifactDigest !== "string" || !/^[0-9a-f]{64}$/.test(item.artifactDigest) || typeof item.processReady !== "boolean" || !Array.isArray(item.tools) || item.tools.some((tool) => typeof tool !== "string") || typeof calls.deploymentStatus !== "boolean" || typeof calls.boardSnapshot !== "boolean" || typeof item.ok !== "boolean") {
39761
40994
  throw new Error("deployment adapter returned invalid MCP runtime health evidence");
39762
40995
  }
40996
+ const callFailures = mcpCallFailures(item.callFailures);
39763
40997
  return {
39764
40998
  checkedAt: item.checkedAt,
39765
40999
  revision: item.revision,
@@ -39770,10 +41004,28 @@ function mcpHealthEvidence(value) {
39770
41004
  deploymentStatus: calls.deploymentStatus,
39771
41005
  boardSnapshot: calls.boardSnapshot
39772
41006
  },
41007
+ ...callFailures.length ? { callFailures } : {},
39773
41008
  ok: item.ok,
39774
41009
  ...typeof item.detail === "string" ? { detail: item.detail } : {}
39775
41010
  };
39776
41011
  }
41012
+ function mcpCallFailures(value) {
41013
+ if (value === undefined)
41014
+ return [];
41015
+ if (!Array.isArray(value))
41016
+ throw new Error("deployment adapter returned invalid MCP runtime call failures");
41017
+ return value.map((entry) => {
41018
+ const failure4 = object(entry);
41019
+ if (typeof failure4.tool !== "string" || typeof failure4.error !== "string" || failure4.code !== undefined && typeof failure4.code !== "string") {
41020
+ throw new Error("deployment adapter returned invalid MCP runtime call failures");
41021
+ }
41022
+ return {
41023
+ tool: failure4.tool,
41024
+ ...failure4.code === undefined ? {} : { code: failure4.code },
41025
+ error: failure4.error
41026
+ };
41027
+ });
41028
+ }
39777
41029
  function reconciliation(value) {
39778
41030
  if (value === null)
39779
41031
  return null;
@@ -39797,6 +41049,8 @@ class HostCommandViewerDeploymentAdapter {
39797
41049
  const stateFile = options.stateFile ?? statePath("viewer-deployment-adapter-process.json");
39798
41050
  const phaseFile = `${stateFile}.phase`;
39799
41051
  const proc = options.proc ?? procBackend;
41052
+ const log = options.log ?? console.error;
41053
+ const phaseLogIntervalMs = Math.max(1, options.phaseLogIntervalMs ?? PHASE_LOG_INTERVAL_MS);
39800
41054
  const timeouts = { ...ACTION_TIMEOUTS, ...options.timeouts };
39801
41055
  const reconcile = async () => {
39802
41056
  const previous = readProcessRecord(stateFile);
@@ -39810,6 +41064,7 @@ class HostCommandViewerDeploymentAdapter {
39810
41064
  fs67.rmSync(phaseFile, { force: true });
39811
41065
  };
39812
41066
  const runAction = async (action, input, healthAdmissions) => {
41067
+ const timeoutMs = Math.max(1, timeouts[action]);
39813
41068
  const admissionChannel = healthAdmissions ? await createMcpHealthProbeAdmissionChannel() : null;
39814
41069
  const stdio = admissionChannel ? ["pipe", "pipe", "pipe", admissionChannel.childFd] : ["pipe", "pipe", "pipe"];
39815
41070
  let child;
@@ -39820,7 +41075,8 @@ class HostCommandViewerDeploymentAdapter {
39820
41075
  env: {
39821
41076
  ...withoutWakatimeCredential(process.env),
39822
41077
  LLV_DEPLOYMENT_ADAPTER_PROTOCOL: "1",
39823
- LLV_DEPLOYMENT_ADAPTER_PHASE_FILE: phaseFile
41078
+ LLV_DEPLOYMENT_ADAPTER_PHASE_FILE: phaseFile,
41079
+ LLV_DEPLOYMENT_ADAPTER_ACTION_DEADLINE_MS: String(timeoutMs)
39824
41080
  },
39825
41081
  detached: true
39826
41082
  });
@@ -39868,8 +41124,16 @@ class HostCommandViewerDeploymentAdapter {
39868
41124
  const stdoutPromise = readStream(child.stdout);
39869
41125
  const stderrPromise = readStream(child.stderr);
39870
41126
  let timer = null;
41127
+ let reportedPhase = null;
41128
+ const phaseLog = setInterval(() => {
41129
+ const phase = readAdapterPhase(phaseFile, action);
41130
+ if (phase === null || phase === reportedPhase)
41131
+ return;
41132
+ reportedPhase = phase;
41133
+ log(`[viewer deployment] ${action} ${phase}`);
41134
+ }, phaseLogIntervalMs);
41135
+ phaseLog.unref?.();
39871
41136
  try {
39872
- const timeoutMs = Math.max(1, timeouts[action]);
39873
41137
  const outcome = await Promise.race([
39874
41138
  exitPromise.then((exitCode) => ({ type: "exit", exitCode })),
39875
41139
  new Promise((resolve) => {
@@ -39894,6 +41158,7 @@ class HostCommandViewerDeploymentAdapter {
39894
41158
  } finally {
39895
41159
  if (timer)
39896
41160
  clearTimeout(timer);
41161
+ clearInterval(phaseLog);
39897
41162
  closeHealthAdmission?.();
39898
41163
  clearProcessRecord(stateFile, record11);
39899
41164
  fs67.rmSync(phaseFile, { force: true });
@@ -39968,10 +41233,11 @@ class HostCommandViewerDeploymentAdapter {
39968
41233
  await this.run("complete-host-handoff", { generation });
39969
41234
  }
39970
41235
  }
39971
- var ACTION_TIMEOUTS, MCP_HEALTH_PROBE_ACTIONS;
41236
+ var ACTION_TIMEOUTS, MCP_HEALTH_PROBE_ACTIONS, PHASE_LOG_INTERVAL_MS = 5000, PROBE_NAMES;
39972
41237
  var init_deploymentAdapter = __esm(() => {
39973
41238
  init_configDir();
39974
41239
  init_proc();
41240
+ init_deploymentHotState();
39975
41241
  init_mcpHealthProbeAdmissionChannel();
39976
41242
  ACTION_TIMEOUTS = {
39977
41243
  "resolve-revision": 110000,
@@ -39981,7 +41247,7 @@ var init_deploymentAdapter = __esm(() => {
39981
41247
  "current-mcp-runtime": 90000,
39982
41248
  "reconcile-mcp-runtime": 10 * 60000,
39983
41249
  "verify-candidate": 90000,
39984
- promote: 30000,
41250
+ promote: PROMOTE_ACTION_TIMEOUT_MS,
39985
41251
  "verify-promoted": 120000,
39986
41252
  rollback: 90000,
39987
41253
  retire: 60000,
@@ -39994,6 +41260,7 @@ var init_deploymentAdapter = __esm(() => {
39994
41260
  "verify-candidate",
39995
41261
  "verify-promoted"
39996
41262
  ]);
41263
+ PROBE_NAMES = ["root", "authenticated", "unauthorized", "capability"];
39997
41264
  });
39998
41265
 
39999
41266
  // src/runtime-host/deploymentProxy.ts
@@ -40051,6 +41318,55 @@ Content-Length: 0\r
40051
41318
  }
40052
41319
  var init_deploymentProxy = () => {};
40053
41320
 
41321
+ // src/runtime-host/receiptSweep.ts
41322
+ var exports_receiptSweep = {};
41323
+ __export(exports_receiptSweep, {
41324
+ RECEIPT_SWEEP_SUMMARY_INTERVAL_MS: () => RECEIPT_SWEEP_SUMMARY_INTERVAL_MS,
41325
+ ReceiptSweepReporter: () => ReceiptSweepReporter,
41326
+ receiptSweepDebugEnabled: () => receiptSweepDebugEnabled
41327
+ });
41328
+ function receiptSweepDebugEnabled(env = process.env) {
41329
+ return env.LLV_RUNTIME_JOURNAL_DEBUG === "1";
41330
+ }
41331
+
41332
+ class ReceiptSweepReporter {
41333
+ deleted = 0;
41334
+ cycles = 0;
41335
+ windowStartedAt = null;
41336
+ debug;
41337
+ summaryIntervalMs;
41338
+ constructor(options = {}) {
41339
+ this.debug = options.debug ?? false;
41340
+ this.summaryIntervalMs = Math.max(0, options.summaryIntervalMs ?? RECEIPT_SWEEP_SUMMARY_INTERVAL_MS);
41341
+ }
41342
+ record(pass, nowMs) {
41343
+ if (this.debug) {
41344
+ return pass.deleted > 0 ? `[runtime journal] receipt sweep cycle removed ${pass.deleted} stale producer receipts` : null;
41345
+ }
41346
+ this.windowStartedAt ??= nowMs;
41347
+ if (pass.deleted > 0) {
41348
+ this.deleted += pass.deleted;
41349
+ this.cycles += 1;
41350
+ }
41351
+ if (this.deleted === 0) {
41352
+ this.windowStartedAt = nowMs;
41353
+ return null;
41354
+ }
41355
+ if (nowMs - this.windowStartedAt < this.summaryIntervalMs)
41356
+ return null;
41357
+ const minutes = Math.max(1, Math.round((nowMs - this.windowStartedAt) / 60000));
41358
+ const line = `[runtime journal] receipt sweep removed ${this.deleted} stale producer receipts across ${this.cycles} cycles in the last ${minutes}m`;
41359
+ this.deleted = 0;
41360
+ this.cycles = 0;
41361
+ this.windowStartedAt = nowMs;
41362
+ return line;
41363
+ }
41364
+ }
41365
+ var RECEIPT_SWEEP_SUMMARY_INTERVAL_MS;
41366
+ var init_receiptSweep = __esm(() => {
41367
+ RECEIPT_SWEEP_SUMMARY_INTERVAL_MS = 15 * 60000;
41368
+ });
41369
+
40054
41370
  // src/runtime-host/hostRelease.ts
40055
41371
  var exports_hostRelease = {};
40056
41372
  __export(exports_hostRelease, {
@@ -40162,6 +41478,66 @@ var init_hostRelease = __esm(() => {
40162
41478
  init_configDir();
40163
41479
  });
40164
41480
 
41481
+ // src/runtime-host/fenceWait.ts
41482
+ var exports_fenceWait = {};
41483
+ __export(exports_fenceWait, {
41484
+ RUNTIME_HOST_FENCE_PARK_ENV: () => RUNTIME_HOST_FENCE_PARK_ENV,
41485
+ RUNTIME_HOST_FENCE_WAIT_ENV: () => RUNTIME_HOST_FENCE_WAIT_ENV,
41486
+ acquireRuntimeHostFence: () => acquireRuntimeHostFence,
41487
+ runtimeHostFenceTimeoutLine: () => runtimeHostFenceTimeoutLine,
41488
+ runtimeHostFenceWaitLine: () => runtimeHostFenceWaitLine,
41489
+ runtimeHostFenceWaitPlan: () => runtimeHostFenceWaitPlan
41490
+ });
41491
+ function runtimeHostFenceWaitPlan(environment) {
41492
+ if (environment[RUNTIME_HOST_FENCE_PARK_ENV] === "1")
41493
+ return { parked: true, budgetMs: 0 };
41494
+ const budgetMs = Number(environment[RUNTIME_HOST_FENCE_WAIT_ENV] || 0);
41495
+ return { parked: false, budgetMs: Number.isFinite(budgetMs) && budgetMs > 0 ? budgetMs : 0 };
41496
+ }
41497
+ function seconds(milliseconds) {
41498
+ return Math.max(0, Math.round(milliseconds / 1000));
41499
+ }
41500
+ function generation(container) {
41501
+ return container ? `runtime-host successor ${container}` : "this runtime-host generation";
41502
+ }
41503
+ function runtimeHostFenceWaitLine(plan, container, elapsedMs) {
41504
+ if (plan.parked) {
41505
+ return `[runtime host] ${generation(container)} is parked on the singleton fence with no deadline` + `; waited ${seconds(elapsedMs)}s` + "; the predecessor still serves and has not been asked to exit" + "; run scripts/bootstrap-runtime-host.ts --hand-over to release it";
41506
+ }
41507
+ return `[runtime host] ${generation(container)} is waiting for the singleton fence` + `; waited ${seconds(elapsedMs)}s of ${seconds(plan.budgetMs)}s` + "; the predecessor has not released it yet";
41508
+ }
41509
+ function runtimeHostFenceTimeoutLine(plan, container, elapsedMs) {
41510
+ return `${generation(container)} never acquired the singleton fence` + `; waited ${seconds(elapsedMs)}s of ${seconds(plan.budgetMs)}s` + "; the predecessor generation still holds it";
41511
+ }
41512
+ async function acquireRuntimeHostFence(options) {
41513
+ const now2 = options.now ?? Date.now;
41514
+ const sleep6 = options.sleep ?? ((milliseconds) => new Promise((resolve) => setTimeout(resolve, milliseconds)));
41515
+ const pollMs = Math.max(1, options.pollMs ?? FENCE_ACQUIRE_POLL_MS);
41516
+ const reportEveryMs = Math.max(1, options.reportEveryMs ?? FENCE_REPORT_EVERY_MS);
41517
+ const started = now2();
41518
+ const deadline = started + options.plan.budgetMs;
41519
+ let reportedAt = null;
41520
+ for (;; ) {
41521
+ try {
41522
+ options.acquire();
41523
+ return { waitedMs: now2() - started };
41524
+ } catch (error) {
41525
+ const elapsedMs = now2() - started;
41526
+ if (!options.plan.parked && now2() >= deadline) {
41527
+ if (options.plan.budgetMs <= 0)
41528
+ throw error;
41529
+ throw new Error(runtimeHostFenceTimeoutLine(options.plan, options.container, elapsedMs), { cause: error });
41530
+ }
41531
+ if (reportedAt === null || elapsedMs - reportedAt >= reportEveryMs) {
41532
+ reportedAt = elapsedMs;
41533
+ options.report?.(runtimeHostFenceWaitLine(options.plan, options.container, elapsedMs));
41534
+ }
41535
+ await sleep6(pollMs);
41536
+ }
41537
+ }
41538
+ }
41539
+ var RUNTIME_HOST_FENCE_WAIT_ENV = "LLV_RUNTIME_HOST_FENCE_WAIT_MS", RUNTIME_HOST_FENCE_PARK_ENV = "LLV_RUNTIME_HOST_FENCE_PARK", FENCE_ACQUIRE_POLL_MS = 500, FENCE_REPORT_EVERY_MS = 60000;
41540
+
40165
41541
  // src/runtime-host/main.ts
40166
41542
  discardWakatimeEnvironmentCredential();
40167
41543
  var { statePath: statePath2 } = await Promise.resolve().then(() => (init_configDir(), exports_configDir));
@@ -40176,10 +41552,12 @@ var { serveRuntimeHost: serveRuntimeHost2 } = await Promise.resolve().then(() =>
40176
41552
  var { ViewerDeploymentCoordinator: ViewerDeploymentCoordinator2 } = await Promise.resolve().then(() => (init_deployment(), exports_deployment));
40177
41553
  var { HostCommandViewerDeploymentAdapter: HostCommandViewerDeploymentAdapter2 } = await Promise.resolve().then(() => (init_deploymentAdapter(), exports_deploymentAdapter));
40178
41554
  var { serveViewerDeploymentProxy: serveViewerDeploymentProxy2 } = await Promise.resolve().then(() => (init_deploymentProxy(), exports_deploymentProxy));
41555
+ var { ReceiptSweepReporter: ReceiptSweepReporter2, receiptSweepDebugEnabled: receiptSweepDebugEnabled2 } = await Promise.resolve().then(() => (init_receiptSweep(), exports_receiptSweep));
40179
41556
  var {
40180
41557
  currentRuntimeHostGeneration: currentRuntimeHostGeneration2,
40181
41558
  RUNTIME_HOST_CONTAINER_ENV: RUNTIME_HOST_CONTAINER_ENV2
40182
41559
  } = await Promise.resolve().then(() => (init_hostRelease(), exports_hostRelease));
41560
+ var { acquireRuntimeHostFence: acquireRuntimeHostFence2, runtimeHostFenceWaitPlan: runtimeHostFenceWaitPlan2 } = await Promise.resolve().then(() => exports_fenceWait);
40183
41561
  var { runtimeHostActivationRefusal: runtimeHostActivationRefusal2 } = await Promise.resolve().then(() => exports_flags);
40184
41562
  var socketPath = process.env.LLV_RUNTIME_HOST_SOCKET || statePath2("runtime-host.sock");
40185
41563
  var activationRefusal = runtimeHostActivationRefusal2();
@@ -40189,18 +41567,12 @@ if (process.env.LLV_RUNTIME_LEGACY_SCHEDULER === "1" && process.env.LLV_ACCOUNT_
40189
41567
  throw new Error("runtime legacy scheduler requires LLV_ACCOUNT_CONTROLLER_DISABLED=1 to preserve single-writer reconciliation");
40190
41568
  }
40191
41569
  var fence = new RuntimeHostFence2(`${socketPath}.lock`);
40192
- var fenceWaitMs = Number(process.env.LLV_RUNTIME_HOST_FENCE_WAIT_MS || 0);
40193
- var fenceDeadline = Date.now() + (Number.isFinite(fenceWaitMs) && fenceWaitMs > 0 ? fenceWaitMs : 0);
40194
- for (;; ) {
40195
- try {
40196
- fence.acquire();
40197
- break;
40198
- } catch (error) {
40199
- if (Date.now() >= fenceDeadline)
40200
- throw error;
40201
- await new Promise((resolve) => setTimeout(resolve, 500));
40202
- }
40203
- }
41570
+ await acquireRuntimeHostFence2({
41571
+ acquire: () => fence.acquire(),
41572
+ plan: runtimeHostFenceWaitPlan2(process.env),
41573
+ container: process.env[RUNTIME_HOST_CONTAINER_ENV2],
41574
+ report: (line) => console.error(line)
41575
+ });
40204
41576
  var journal = new RuntimeJournal2(process.env.LLV_RUNTIME_JOURNAL || statePath2("runtime-events.sqlite"));
40205
41577
  if (journal.isWritable())
40206
41578
  journal.claimHostEpoch();
@@ -40235,17 +41607,14 @@ var legacyScheduler = process.env.LLV_RUNTIME_LEGACY_SCHEDULER === "1" ? createL
40235
41607
  var legacyTimer = legacyScheduler ? setInterval(() => {
40236
41608
  legacyScheduler.runDue().catch(() => console.error("[runtime scheduler] tick failed; next tick will retry"));
40237
41609
  }, 1000) : null;
40238
- var receiptSweepDeleted = 0;
41610
+ var receiptSweepReporter = new ReceiptSweepReporter2({ debug: receiptSweepDebugEnabled2() });
40239
41611
  var receiptSweepTimer = journal.isWritable() ? setInterval(() => {
40240
41612
  if (!journal.isWritable())
40241
41613
  return;
40242
41614
  try {
40243
- const pass = journal.maintainProducerReceipts();
40244
- receiptSweepDeleted += pass.deleted;
40245
- if (pass.cycled && receiptSweepDeleted > 0) {
40246
- console.error(`[runtime journal] receipt sweep cycle removed ${receiptSweepDeleted} stale producer receipts`);
40247
- receiptSweepDeleted = 0;
40248
- }
41615
+ const line = receiptSweepReporter.record(journal.maintainProducerReceipts(), Date.now());
41616
+ if (line)
41617
+ console.error(line);
40249
41618
  } catch (error) {
40250
41619
  console.error(`[runtime journal] receipt sweep failed; next tick will retry: ${error instanceof Error ? error.message : String(error)}`);
40251
41620
  }