@songsid/agend 2.3.5-alpha.4 → 2.3.5-alpha.5

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 (838) hide show
  1. package/THIRD_PARTY_NOTICES.md +52 -0
  2. package/dist/accounts-view.d.ts +97 -0
  3. package/dist/accounts-view.js +116 -0
  4. package/dist/accounts-view.js.map +1 -0
  5. package/dist/agent-cli-instructions.md +1 -1
  6. package/dist/agent-credentials.d.ts +24 -0
  7. package/dist/agent-credentials.js +66 -0
  8. package/dist/agent-credentials.js.map +1 -0
  9. package/dist/agent-endpoint.d.ts +3 -1
  10. package/dist/agent-endpoint.js +13 -0
  11. package/dist/agent-endpoint.js.map +1 -1
  12. package/dist/agent-file-read.js +1 -1
  13. package/dist/agent-file-read.js.map +1 -1
  14. package/dist/agent-runtime-change.d.ts +3 -1
  15. package/dist/agent-runtime-change.js +15 -3
  16. package/dist/agent-runtime-change.js.map +1 -1
  17. package/dist/agent-workspace.d.ts +93 -0
  18. package/dist/agent-workspace.js +353 -0
  19. package/dist/agent-workspace.js.map +1 -0
  20. package/dist/auth-api.d.ts +27 -0
  21. package/dist/auth-api.js +164 -3
  22. package/dist/auth-api.js.map +1 -1
  23. package/dist/authority/session-authorizations.d.ts +28 -4
  24. package/dist/authority/session-authorizations.js +63 -17
  25. package/dist/authority/session-authorizations.js.map +1 -1
  26. package/dist/backend/antigravity.js +3 -1
  27. package/dist/backend/antigravity.js.map +1 -1
  28. package/dist/backend/codex-footer-hints.d.ts +3 -0
  29. package/dist/backend/codex-footer-hints.js +14 -0
  30. package/dist/backend/codex-footer-hints.js.map +1 -1
  31. package/dist/backend/codex-metadata.d.ts +14 -0
  32. package/dist/backend/codex-metadata.js +45 -0
  33. package/dist/backend/codex-metadata.js.map +1 -1
  34. package/dist/backend/codex-quota-history.d.ts +7 -0
  35. package/dist/backend/codex-quota-history.js +57 -0
  36. package/dist/backend/codex-quota-history.js.map +1 -0
  37. package/dist/backend/codex-session-lookup.d.ts +6 -0
  38. package/dist/backend/codex-session-lookup.js +1 -1
  39. package/dist/backend/codex-session-lookup.js.map +1 -1
  40. package/dist/backend/codex-speed.d.ts +14 -0
  41. package/dist/backend/codex-speed.js +35 -0
  42. package/dist/backend/codex-speed.js.map +1 -0
  43. package/dist/backend/codex.d.ts +7 -0
  44. package/dist/backend/codex.js +78 -15
  45. package/dist/backend/codex.js.map +1 -1
  46. package/dist/backend/grok-weekly-reset.d.ts +24 -0
  47. package/dist/backend/grok-weekly-reset.js +95 -0
  48. package/dist/backend/grok-weekly-reset.js.map +1 -0
  49. package/dist/backend/grok.d.ts +30 -1
  50. package/dist/backend/grok.js +301 -54
  51. package/dist/backend/grok.js.map +1 -1
  52. package/dist/backend/kiro.d.ts +3 -0
  53. package/dist/backend/kiro.js +50 -2
  54. package/dist/backend/kiro.js.map +1 -1
  55. package/dist/backend/muse.js +5 -3
  56. package/dist/backend/muse.js.map +1 -1
  57. package/dist/backend/native-pane.d.ts +3 -1
  58. package/dist/backend/native-pane.js +2 -2
  59. package/dist/backend/native-pane.js.map +1 -1
  60. package/dist/backend/types.d.ts +13 -1
  61. package/dist/backend/types.js +3 -0
  62. package/dist/backend/types.js.map +1 -1
  63. package/dist/build-provenance-cli.d.ts +3 -0
  64. package/dist/build-provenance-cli.js +11 -0
  65. package/dist/build-provenance-cli.js.map +1 -0
  66. package/dist/build-provenance.d.ts +20 -0
  67. package/dist/build-provenance.js +67 -0
  68. package/dist/build-provenance.js.map +1 -0
  69. package/dist/build-provenance.json +1 -0
  70. package/dist/cache-ledger.d.ts +95 -0
  71. package/dist/cache-ledger.js +276 -4
  72. package/dist/cache-ledger.js.map +1 -1
  73. package/dist/cache-service.d.ts +5 -0
  74. package/dist/cache-service.js +16 -4
  75. package/dist/cache-service.js.map +1 -1
  76. package/dist/channel/adapters/discord.js +11 -3
  77. package/dist/channel/adapters/discord.js.map +1 -1
  78. package/dist/channel/adapters/telegram.d.ts +51 -0
  79. package/dist/channel/adapters/telegram.js +235 -17
  80. package/dist/channel/adapters/telegram.js.map +1 -1
  81. package/dist/channel/mcp-tools.js +3 -3
  82. package/dist/channel/mcp-tools.js.map +1 -1
  83. package/dist/channel/types.d.ts +2 -0
  84. package/dist/claude-auth-status.d.ts +48 -0
  85. package/dist/claude-auth-status.js +149 -0
  86. package/dist/claude-auth-status.js.map +1 -0
  87. package/dist/cli.js +138 -37
  88. package/dist/cli.js.map +1 -1
  89. package/dist/config-validator.js +21 -1
  90. package/dist/config-validator.js.map +1 -1
  91. package/dist/cross-instance-notice.d.ts +10 -0
  92. package/dist/cross-instance-notice.js +67 -5
  93. package/dist/cross-instance-notice.js.map +1 -1
  94. package/dist/daemon.d.ts +70 -1
  95. package/dist/daemon.js +547 -25
  96. package/dist/daemon.js.map +1 -1
  97. package/dist/dashboard-permissions.d.ts +8 -0
  98. package/dist/dashboard-permissions.js +16 -0
  99. package/dist/dashboard-permissions.js.map +1 -1
  100. package/dist/delivery-consumed-watch.d.ts +23 -1
  101. package/dist/delivery-consumed-watch.js +30 -3
  102. package/dist/delivery-consumed-watch.js.map +1 -1
  103. package/dist/delivery-reconciliation.d.ts +1 -1
  104. package/dist/delivery-reconciliation.js +1 -1
  105. package/dist/delivery-reconciliation.js.map +1 -1
  106. package/dist/doctor.js +20 -9
  107. package/dist/doctor.js.map +1 -1
  108. package/dist/export-import.d.ts +7 -0
  109. package/dist/export-import.js +44 -10
  110. package/dist/export-import.js.map +1 -1
  111. package/dist/fleet-context.d.ts +2 -0
  112. package/dist/fleet-manager.d.ts +359 -7
  113. package/dist/fleet-manager.js +1365 -90
  114. package/dist/fleet-manager.js.map +1 -1
  115. package/dist/fleet-windows-runtime.d.ts +2 -1
  116. package/dist/fleet-windows-runtime.js +25 -7
  117. package/dist/fleet-windows-runtime.js.map +1 -1
  118. package/dist/general-knowledge/skills/concepts/SKILL.md +425 -0
  119. package/dist/general-knowledge/skills/credential-profiles/SKILL.md +5 -2
  120. package/dist/general-knowledge/skills/cross-instance-messaging/SKILL.md +1 -0
  121. package/dist/general-knowledge/skills/fleet-health/SKILL.md +2 -2
  122. package/dist/general-knowledge/skills/instance-lifecycle/SKILL.md +3 -1
  123. package/dist/general-knowledge/skills/kiro-engine-migration/SKILL.md +41 -4
  124. package/dist/general-knowledge/skills/session-management/SKILL.md +1 -1
  125. package/dist/general-knowledge/skills/tui-effort/SKILL.md +10 -10
  126. package/dist/general-knowledge/skills/web-dashboard/SKILL.md +31 -15
  127. package/dist/general-knowledge/skills/worker-collaboration/SKILL.md +1 -1
  128. package/dist/general-role.d.ts +1 -1
  129. package/dist/general-role.js +1 -0
  130. package/dist/general-role.js.map +1 -1
  131. package/dist/hub/admission.d.ts +28 -0
  132. package/dist/hub/admission.js +62 -0
  133. package/dist/hub/admission.js.map +1 -0
  134. package/dist/hub/attachments/limits.d.ts +20 -0
  135. package/dist/hub/attachments/limits.js +48 -0
  136. package/dist/hub/attachments/limits.js.map +1 -0
  137. package/dist/hub/attachments/store.d.ts +116 -0
  138. package/dist/hub/attachments/store.js +246 -0
  139. package/dist/hub/attachments/store.js.map +1 -0
  140. package/dist/hub/audit/index.d.ts +62 -0
  141. package/dist/hub/audit/index.js +344 -0
  142. package/dist/hub/audit/index.js.map +1 -0
  143. package/dist/hub/browser-certificate.d.ts +38 -0
  144. package/dist/hub/browser-certificate.js +247 -0
  145. package/dist/hub/browser-certificate.js.map +1 -0
  146. package/dist/hub/buttons-model.d.ts +9 -0
  147. package/dist/hub/buttons-model.js +42 -0
  148. package/dist/hub/buttons-model.js.map +1 -0
  149. package/dist/hub/buttons.d.ts +54 -0
  150. package/dist/hub/buttons.js +346 -0
  151. package/dist/hub/buttons.js.map +1 -0
  152. package/dist/hub/catalog.d.ts +74 -0
  153. package/dist/hub/catalog.js +195 -0
  154. package/dist/hub/catalog.js.map +1 -0
  155. package/dist/hub/client.d.ts +69 -0
  156. package/dist/hub/client.js +300 -0
  157. package/dist/hub/client.js.map +1 -0
  158. package/dist/hub/compose/member.d.ts +139 -0
  159. package/dist/hub/compose/member.js +450 -0
  160. package/dist/hub/compose/member.js.map +1 -0
  161. package/dist/hub/compose/server.d.ts +77 -0
  162. package/dist/hub/compose/server.js +349 -0
  163. package/dist/hub/compose/server.js.map +1 -0
  164. package/dist/hub/compose/views.d.ts +12 -0
  165. package/dist/hub/compose/views.js +4 -0
  166. package/dist/hub/compose/views.js.map +1 -0
  167. package/dist/hub/db.d.ts +56 -0
  168. package/dist/hub/db.js +188 -0
  169. package/dist/hub/db.js.map +1 -0
  170. package/dist/hub/directory/config.d.ts +39 -0
  171. package/dist/hub/directory/config.js +108 -0
  172. package/dist/hub/directory/config.js.map +1 -0
  173. package/dist/hub/directory/directory.d.ts +18 -0
  174. package/dist/hub/directory/directory.js +320 -0
  175. package/dist/hub/directory/directory.js.map +1 -0
  176. package/dist/hub/directory/index.d.ts +7 -0
  177. package/dist/hub/directory/index.js +4 -0
  178. package/dist/hub/directory/index.js.map +1 -0
  179. package/dist/hub/directory/profiles.d.ts +41 -0
  180. package/dist/hub/directory/profiles.js +90 -0
  181. package/dist/hub/directory/profiles.js.map +1 -0
  182. package/dist/hub/directory/types.d.ts +71 -0
  183. package/dist/hub/directory/types.js +14 -0
  184. package/dist/hub/directory/types.js.map +1 -0
  185. package/dist/hub/execution/cli-provider.d.ts +23 -0
  186. package/dist/hub/execution/cli-provider.js +341 -0
  187. package/dist/hub/execution/cli-provider.js.map +1 -0
  188. package/dist/hub/execution/index.d.ts +13 -0
  189. package/dist/hub/execution/index.js +8 -0
  190. package/dist/hub/execution/index.js.map +1 -0
  191. package/dist/hub/execution/model-broker.d.ts +24 -0
  192. package/dist/hub/execution/model-broker.js +208 -0
  193. package/dist/hub/execution/model-broker.js.map +1 -0
  194. package/dist/hub/execution/provider-setup.d.ts +11 -0
  195. package/dist/hub/execution/provider-setup.js +21 -0
  196. package/dist/hub/execution/provider-setup.js.map +1 -0
  197. package/dist/hub/execution/sandbox-runner.d.ts +1 -0
  198. package/dist/hub/execution/sandbox-runner.js +221 -0
  199. package/dist/hub/execution/sandbox-runner.js.map +1 -0
  200. package/dist/hub/execution/service.d.ts +136 -0
  201. package/dist/hub/execution/service.js +459 -0
  202. package/dist/hub/execution/service.js.map +1 -0
  203. package/dist/hub/execution/store.d.ts +61 -0
  204. package/dist/hub/execution/store.js +182 -0
  205. package/dist/hub/execution/store.js.map +1 -0
  206. package/dist/hub/execution/views.d.ts +20 -0
  207. package/dist/hub/execution/views.js +48 -0
  208. package/dist/hub/execution/views.js.map +1 -0
  209. package/dist/hub/http/compose.d.ts +20 -0
  210. package/dist/hub/http/compose.js +518 -0
  211. package/dist/hub/http/compose.js.map +1 -0
  212. package/dist/hub/http/core.d.ts +49 -0
  213. package/dist/hub/http/core.js +124 -0
  214. package/dist/hub/http/core.js.map +1 -0
  215. package/dist/hub/http/deps.d.ts +61 -0
  216. package/dist/hub/http/deps.js +2 -0
  217. package/dist/hub/http/deps.js.map +1 -0
  218. package/dist/hub/http/schema.d.ts +14 -0
  219. package/dist/hub/http/schema.js +80 -0
  220. package/dist/hub/http/schema.js.map +1 -0
  221. package/dist/hub/identity.d.ts +32 -0
  222. package/dist/hub/identity.js +80 -0
  223. package/dist/hub/identity.js.map +1 -0
  224. package/dist/hub/init/browser-certificate.d.ts +9 -0
  225. package/dist/hub/init/browser-certificate.js +78 -0
  226. package/dist/hub/init/browser-certificate.js.map +1 -0
  227. package/dist/hub/init/browser-tls.d.ts +18 -0
  228. package/dist/hub/init/browser-tls.js +62 -0
  229. package/dist/hub/init/browser-tls.js.map +1 -0
  230. package/dist/hub/init/cli.d.ts +3 -0
  231. package/dist/hub/init/cli.js +83 -0
  232. package/dist/hub/init/cli.js.map +1 -0
  233. package/dist/hub/init/directory-certificate.d.ts +24 -0
  234. package/dist/hub/init/directory-certificate.js +222 -0
  235. package/dist/hub/init/directory-certificate.js.map +1 -0
  236. package/dist/hub/init/existing-fleet.d.ts +6 -0
  237. package/dist/hub/init/existing-fleet.js +58 -0
  238. package/dist/hub/init/existing-fleet.js.map +1 -0
  239. package/dist/hub/init/handoff.d.ts +8 -0
  240. package/dist/hub/init/handoff.js +36 -0
  241. package/dist/hub/init/handoff.js.map +1 -0
  242. package/dist/hub/init/identity.d.ts +5 -0
  243. package/dist/hub/init/identity.js +24 -0
  244. package/dist/hub/init/identity.js.map +1 -0
  245. package/dist/hub/init/initializer.d.ts +24 -0
  246. package/dist/hub/init/initializer.js +385 -0
  247. package/dist/hub/init/initializer.js.map +1 -0
  248. package/dist/hub/init/inventory.d.ts +17 -0
  249. package/dist/hub/init/inventory.js +33 -0
  250. package/dist/hub/init/inventory.js.map +1 -0
  251. package/dist/hub/init/layout.d.ts +32 -0
  252. package/dist/hub/init/layout.js +53 -0
  253. package/dist/hub/init/layout.js.map +1 -0
  254. package/dist/hub/init/network.d.ts +18 -0
  255. package/dist/hub/init/network.js +104 -0
  256. package/dist/hub/init/network.js.map +1 -0
  257. package/dist/hub/init/plan-digest.d.ts +5 -0
  258. package/dist/hub/init/plan-digest.js +47 -0
  259. package/dist/hub/init/plan-digest.js.map +1 -0
  260. package/dist/hub/init/prompt.d.ts +26 -0
  261. package/dist/hub/init/prompt.js +110 -0
  262. package/dist/hub/init/prompt.js.map +1 -0
  263. package/dist/hub/init/secret-file.d.ts +1 -0
  264. package/dist/hub/init/secret-file.js +59 -0
  265. package/dist/hub/init/secret-file.js.map +1 -0
  266. package/dist/hub/init/text.d.ts +127 -0
  267. package/dist/hub/init/text.js +247 -0
  268. package/dist/hub/init/text.js.map +1 -0
  269. package/dist/hub/init/types.d.ts +114 -0
  270. package/dist/hub/init/types.js +9 -0
  271. package/dist/hub/init/types.js.map +1 -0
  272. package/dist/hub/init/wizard.d.ts +34 -0
  273. package/dist/hub/init/wizard.js +554 -0
  274. package/dist/hub/init/wizard.js.map +1 -0
  275. package/dist/hub/initialization.d.ts +23 -0
  276. package/dist/hub/initialization.js +28 -0
  277. package/dist/hub/initialization.js.map +1 -0
  278. package/dist/hub/member/agent-mode.d.ts +6 -0
  279. package/dist/hub/member/agent-mode.js +23 -0
  280. package/dist/hub/member/agent-mode.js.map +1 -0
  281. package/dist/hub/member/attachments.d.ts +29 -0
  282. package/dist/hub/member/attachments.js +107 -0
  283. package/dist/hub/member/attachments.js.map +1 -0
  284. package/dist/hub/member/exposure-api.d.ts +87 -0
  285. package/dist/hub/member/exposure-api.js +64 -0
  286. package/dist/hub/member/exposure-api.js.map +1 -0
  287. package/dist/hub/member/exposures.d.ts +123 -0
  288. package/dist/hub/member/exposures.js +282 -0
  289. package/dist/hub/member/exposures.js.map +1 -0
  290. package/dist/hub/member/pairing-api.d.ts +85 -0
  291. package/dist/hub/member/pairing-api.js +385 -0
  292. package/dist/hub/member/pairing-api.js.map +1 -0
  293. package/dist/hub/member/quota.d.ts +20 -0
  294. package/dist/hub/member/quota.js +98 -0
  295. package/dist/hub/member/quota.js.map +1 -0
  296. package/dist/hub/member-journal.d.ts +104 -0
  297. package/dist/hub/member-journal.js +336 -0
  298. package/dist/hub/member-journal.js.map +1 -0
  299. package/dist/hub/member-reconciliation.d.ts +14 -0
  300. package/dist/hub/member-reconciliation.js +97 -0
  301. package/dist/hub/member-reconciliation.js.map +1 -0
  302. package/dist/hub/mount.d.ts +39 -0
  303. package/dist/hub/mount.js +123 -0
  304. package/dist/hub/mount.js.map +1 -0
  305. package/dist/hub/pairing-client.d.ts +17 -0
  306. package/dist/hub/pairing-client.js +108 -0
  307. package/dist/hub/pairing-client.js.map +1 -0
  308. package/dist/hub/pairing.d.ts +65 -0
  309. package/dist/hub/pairing.js +211 -0
  310. package/dist/hub/pairing.js.map +1 -0
  311. package/dist/hub/policy.d.ts +63 -0
  312. package/dist/hub/policy.js +147 -0
  313. package/dist/hub/policy.js.map +1 -0
  314. package/dist/hub/preview.d.ts +32 -0
  315. package/dist/hub/preview.js +64 -0
  316. package/dist/hub/preview.js.map +1 -0
  317. package/dist/hub/private-files.d.ts +5 -0
  318. package/dist/hub/private-files.js +44 -0
  319. package/dist/hub/private-files.js.map +1 -0
  320. package/dist/hub/profile.d.ts +59 -0
  321. package/dist/hub/profile.js +73 -0
  322. package/dist/hub/profile.js.map +1 -0
  323. package/dist/hub/protocol.d.ts +779 -0
  324. package/dist/hub/protocol.js +93 -0
  325. package/dist/hub/protocol.js.map +1 -0
  326. package/dist/hub/quota.d.ts +24 -0
  327. package/dist/hub/quota.js +112 -0
  328. package/dist/hub/quota.js.map +1 -0
  329. package/dist/hub/representative.d.ts +141 -0
  330. package/dist/hub/representative.js +528 -0
  331. package/dist/hub/representative.js.map +1 -0
  332. package/dist/hub/retention.d.ts +17 -0
  333. package/dist/hub/retention.js +45 -0
  334. package/dist/hub/retention.js.map +1 -0
  335. package/dist/hub/rooms.d.ts +120 -0
  336. package/dist/hub/rooms.js +535 -0
  337. package/dist/hub/rooms.js.map +1 -0
  338. package/dist/hub/runtime.d.ts +106 -0
  339. package/dist/hub/runtime.js +298 -0
  340. package/dist/hub/runtime.js.map +1 -0
  341. package/dist/hub/server.d.ts +56 -0
  342. package/dist/hub/server.js +202 -0
  343. package/dist/hub/server.js.map +1 -0
  344. package/dist/hub/service-start.d.ts +17 -0
  345. package/dist/hub/service-start.js +109 -0
  346. package/dist/hub/service-start.js.map +1 -0
  347. package/dist/hub/sessions.d.ts +53 -0
  348. package/dist/hub/sessions.js +196 -0
  349. package/dist/hub/sessions.js.map +1 -0
  350. package/dist/hub/socket.d.ts +24 -0
  351. package/dist/hub/socket.js +79 -0
  352. package/dist/hub/socket.js.map +1 -0
  353. package/dist/hub/store.d.ts +77 -0
  354. package/dist/hub/store.js +88 -0
  355. package/dist/hub/store.js.map +1 -0
  356. package/dist/hub/tls.d.ts +31 -0
  357. package/dist/hub/tls.js +135 -0
  358. package/dist/hub/tls.js.map +1 -0
  359. package/dist/hub/types.d.ts +401 -0
  360. package/dist/hub/types.js +2 -0
  361. package/dist/hub/types.js.map +1 -0
  362. package/dist/hub/validation.d.ts +33 -0
  363. package/dist/hub/validation.js +136 -0
  364. package/dist/hub/validation.js.map +1 -0
  365. package/dist/hub/version-floor.d.ts +10 -0
  366. package/dist/hub/version-floor.js +45 -0
  367. package/dist/hub/version-floor.js.map +1 -0
  368. package/dist/hub-browser-certificate-policy.d.ts +31 -0
  369. package/dist/hub-browser-certificate-policy.js +25 -0
  370. package/dist/hub-browser-certificate-policy.js.map +1 -0
  371. package/dist/hub-membership-settings.d.ts +6 -0
  372. package/dist/hub-membership-settings.js +21 -0
  373. package/dist/hub-membership-settings.js.map +1 -0
  374. package/dist/hub-mode.d.ts +15 -0
  375. package/dist/hub-mode.js +17 -0
  376. package/dist/hub-mode.js.map +1 -0
  377. package/dist/hub-pairing-summary.d.ts +48 -0
  378. package/dist/hub-pairing-summary.js +36 -0
  379. package/dist/hub-pairing-summary.js.map +1 -0
  380. package/dist/hub-report-target.d.ts +32 -0
  381. package/dist/hub-report-target.js +33 -0
  382. package/dist/hub-report-target.js.map +1 -0
  383. package/dist/hub-retention-policy.d.ts +14 -0
  384. package/dist/hub-retention-policy.js +15 -0
  385. package/dist/hub-retention-policy.js.map +1 -0
  386. package/dist/instance-config-impact.js +3 -0
  387. package/dist/instance-config-impact.js.map +1 -1
  388. package/dist/instance-lifecycle.d.ts +17 -2
  389. package/dist/instance-lifecycle.js +58 -8
  390. package/dist/instance-lifecycle.js.map +1 -1
  391. package/dist/instance-topic-delete.d.ts +77 -0
  392. package/dist/instance-topic-delete.js +123 -0
  393. package/dist/instance-topic-delete.js.map +1 -0
  394. package/dist/instructions.d.ts +1 -1
  395. package/dist/instructions.js +1 -1
  396. package/dist/instructions.js.map +1 -1
  397. package/dist/kiro-engine-status.d.ts +11 -0
  398. package/dist/kiro-engine-status.js +6 -0
  399. package/dist/kiro-engine-status.js.map +1 -1
  400. package/dist/launchd-service-domain.d.ts +5 -0
  401. package/dist/launchd-service-domain.js +21 -0
  402. package/dist/launchd-service-domain.js.map +1 -0
  403. package/dist/locale.js +125 -3
  404. package/dist/locale.js.map +1 -1
  405. package/dist/log-service.d.ts +28 -0
  406. package/dist/log-service.js +29 -0
  407. package/dist/log-service.js.map +1 -1
  408. package/dist/log-steps.d.ts +4 -3
  409. package/dist/log-steps.js +32 -7
  410. package/dist/log-steps.js.map +1 -1
  411. package/dist/logger.d.ts +16 -2
  412. package/dist/logger.js +346 -66
  413. package/dist/logger.js.map +1 -1
  414. package/dist/login-flows.d.ts +15 -7
  415. package/dist/login-flows.js +29 -3
  416. package/dist/login-flows.js.map +1 -1
  417. package/dist/login-manager.js +25 -4
  418. package/dist/login-manager.js.map +1 -1
  419. package/dist/ls-rows.js +3 -4
  420. package/dist/ls-rows.js.map +1 -1
  421. package/dist/missed-offline.d.ts +25 -0
  422. package/dist/missed-offline.js +79 -0
  423. package/dist/missed-offline.js.map +1 -0
  424. package/dist/native-instance-api.d.ts +0 -1
  425. package/dist/native-instance-api.js +15 -3
  426. package/dist/native-instance-api.js.map +1 -1
  427. package/dist/native-instance-input.d.ts +3 -0
  428. package/dist/native-instance-input.js +6 -1
  429. package/dist/native-instance-input.js.map +1 -1
  430. package/dist/native-instance-registry.d.ts +6 -0
  431. package/dist/native-instance-registry.js +24 -0
  432. package/dist/native-instance-registry.js.map +1 -1
  433. package/dist/native-mcp.d.ts +3 -0
  434. package/dist/native-mcp.js +15 -2
  435. package/dist/native-mcp.js.map +1 -1
  436. package/dist/native-pane-lifecycle.d.ts +8 -0
  437. package/dist/native-pane-lifecycle.js +13 -4
  438. package/dist/native-pane-lifecycle.js.map +1 -1
  439. package/dist/native-pane-manager.js +17 -9
  440. package/dist/native-pane-manager.js.map +1 -1
  441. package/dist/needs-you-hub.d.ts +9 -1
  442. package/dist/needs-you-hub.js +46 -8
  443. package/dist/needs-you-hub.js.map +1 -1
  444. package/dist/needs-you.d.ts +47 -2
  445. package/dist/needs-you.js +31 -3
  446. package/dist/needs-you.js.map +1 -1
  447. package/dist/office-share-page.js +2 -2
  448. package/dist/office-share-page.js.map +1 -1
  449. package/dist/office-share.d.ts +11 -0
  450. package/dist/office-share.js +14 -0
  451. package/dist/office-share.js.map +1 -1
  452. package/dist/office-talk.d.ts +26 -0
  453. package/dist/office-talk.js +50 -0
  454. package/dist/office-talk.js.map +1 -0
  455. package/dist/outbound-handlers.d.ts +14 -0
  456. package/dist/outbound-handlers.js +49 -6
  457. package/dist/outbound-handlers.js.map +1 -1
  458. package/dist/outbound-schemas.d.ts +33 -1
  459. package/dist/outbound-schemas.js +29 -16
  460. package/dist/outbound-schemas.js.map +1 -1
  461. package/dist/pane-quota-history.d.ts +9 -0
  462. package/dist/pane-quota-history.js +67 -0
  463. package/dist/pane-quota-history.js.map +1 -0
  464. package/dist/pause-marker.d.ts +1 -1
  465. package/dist/pause-marker.js +1 -1
  466. package/dist/pause-marker.js.map +1 -1
  467. package/dist/platform-general.d.ts +46 -0
  468. package/dist/platform-general.js +91 -0
  469. package/dist/platform-general.js.map +1 -0
  470. package/dist/public-web-gateway.js +7 -0
  471. package/dist/public-web-gateway.js.map +1 -1
  472. package/dist/queued-handoffs.d.ts +33 -0
  473. package/dist/queued-handoffs.js +75 -0
  474. package/dist/queued-handoffs.js.map +1 -0
  475. package/dist/quickstart.d.ts +13 -0
  476. package/dist/quickstart.js +81 -5
  477. package/dist/quickstart.js.map +1 -1
  478. package/dist/quota-notice.d.ts +7 -0
  479. package/dist/quota-notice.js +40 -0
  480. package/dist/quota-notice.js.map +1 -1
  481. package/dist/reply-buttons-controller.js +10 -6
  482. package/dist/reply-buttons-controller.js.map +1 -1
  483. package/dist/reply-polls.d.ts +2 -2
  484. package/dist/reply-polls.js +3 -3
  485. package/dist/reply-polls.js.map +1 -1
  486. package/dist/runtime-api.d.ts +2 -0
  487. package/dist/runtime-api.js +25 -7
  488. package/dist/runtime-api.js.map +1 -1
  489. package/dist/runtime-build-info.js +5 -3
  490. package/dist/runtime-build-info.js.map +1 -1
  491. package/dist/runtime-bundle.d.ts +3 -0
  492. package/dist/runtime-bundle.js +3 -1
  493. package/dist/runtime-bundle.js.map +1 -1
  494. package/dist/runtime-cli.d.ts +8 -1
  495. package/dist/runtime-cli.js +127 -8
  496. package/dist/runtime-cli.js.map +1 -1
  497. package/dist/runtime-client-store.d.ts +7 -0
  498. package/dist/runtime-client-store.js +30 -2
  499. package/dist/runtime-client-store.js.map +1 -1
  500. package/dist/runtime-client.d.ts +63 -1
  501. package/dist/runtime-client.js +295 -21
  502. package/dist/runtime-client.js.map +1 -1
  503. package/dist/runtime-coordinator.d.ts +7 -0
  504. package/dist/runtime-coordinator.js +213 -35
  505. package/dist/runtime-coordinator.js.map +1 -1
  506. package/dist/runtime-credential-profiles.d.ts +78 -0
  507. package/dist/runtime-credential-profiles.js +280 -0
  508. package/dist/runtime-credential-profiles.js.map +1 -0
  509. package/dist/runtime-install.d.ts +50 -0
  510. package/dist/runtime-install.js +186 -0
  511. package/dist/runtime-install.js.map +1 -0
  512. package/dist/runtime-pane-assets.d.ts +1 -1
  513. package/dist/runtime-pane-assets.js +1 -1
  514. package/dist/runtime-pane-assets.js.map +1 -1
  515. package/dist/runtime-pane-codex-index.d.ts +10 -1
  516. package/dist/runtime-pane-codex-index.js +131 -27
  517. package/dist/runtime-pane-codex-index.js.map +1 -1
  518. package/dist/runtime-pane-host.d.ts +19 -0
  519. package/dist/runtime-pane-host.js +50 -7
  520. package/dist/runtime-pane-host.js.map +1 -1
  521. package/dist/runtime-pane-link.d.ts +7 -0
  522. package/dist/runtime-pane-link.js +93 -2
  523. package/dist/runtime-pane-link.js.map +1 -1
  524. package/dist/runtime-pane-mcp-relay.d.ts +1 -0
  525. package/dist/runtime-pane-mcp-relay.js +10 -0
  526. package/dist/runtime-pane-mcp-relay.js.map +1 -1
  527. package/dist/runtime-pane-mcp.d.ts +4 -0
  528. package/dist/runtime-pane-mcp.js +6 -3
  529. package/dist/runtime-pane-mcp.js.map +1 -1
  530. package/dist/runtime-pane-native.d.ts +32 -2
  531. package/dist/runtime-pane-native.js +55 -6
  532. package/dist/runtime-pane-native.js.map +1 -1
  533. package/dist/runtime-pane-port.d.ts +5 -0
  534. package/dist/runtime-pane-port.js +17 -1
  535. package/dist/runtime-pane-port.js.map +1 -1
  536. package/dist/runtime-pane-process.d.ts +1 -1
  537. package/dist/runtime-pane-process.js +11 -2
  538. package/dist/runtime-pane-process.js.map +1 -1
  539. package/dist/runtime-pane-protocol.d.ts +11 -1
  540. package/dist/runtime-pane-protocol.js +27 -5
  541. package/dist/runtime-pane-protocol.js.map +1 -1
  542. package/dist/runtime-pane-quota-history.d.ts +6 -0
  543. package/dist/runtime-pane-quota-history.js +44 -0
  544. package/dist/runtime-pane-quota-history.js.map +1 -0
  545. package/dist/runtime-pane-service.d.ts +5 -0
  546. package/dist/runtime-pane-service.js +47 -12
  547. package/dist/runtime-pane-service.js.map +1 -1
  548. package/dist/runtime-pane-transcript.d.ts +5 -0
  549. package/dist/runtime-pane-transcript.js +66 -5
  550. package/dist/runtime-pane-transcript.js.map +1 -1
  551. package/dist/runtime-pane-worker.js +19 -6
  552. package/dist/runtime-pane-worker.js.map +1 -1
  553. package/dist/runtime-protocol.d.ts +17 -2
  554. package/dist/runtime-protocol.js +12 -0
  555. package/dist/runtime-protocol.js.map +1 -1
  556. package/dist/runtime-update-activity.d.ts +21 -0
  557. package/dist/runtime-update-activity.js +51 -0
  558. package/dist/runtime-update-activity.js.map +1 -0
  559. package/dist/runtime-update-artifact.d.ts +31 -0
  560. package/dist/runtime-update-artifact.js +252 -0
  561. package/dist/runtime-update-artifact.js.map +1 -0
  562. package/dist/runtime-update-install.d.ts +31 -0
  563. package/dist/runtime-update-install.js +205 -0
  564. package/dist/runtime-update-install.js.map +1 -0
  565. package/dist/runtime-update-journal.d.ts +44 -0
  566. package/dist/runtime-update-journal.js +121 -0
  567. package/dist/runtime-update-journal.js.map +1 -0
  568. package/dist/runtime-update-lock.d.ts +48 -0
  569. package/dist/runtime-update-lock.js +217 -0
  570. package/dist/runtime-update-lock.js.map +1 -0
  571. package/dist/runtime-update-owners.d.ts +29 -0
  572. package/dist/runtime-update-owners.js +240 -0
  573. package/dist/runtime-update-owners.js.map +1 -0
  574. package/dist/runtime-update-protocol.d.ts +15 -0
  575. package/dist/runtime-update-protocol.js +13 -0
  576. package/dist/runtime-update-protocol.js.map +1 -0
  577. package/dist/runtime-windows-bridge.d.ts +2 -1
  578. package/dist/runtime-windows-bridge.js +11 -1
  579. package/dist/runtime-windows-bridge.js.map +1 -1
  580. package/dist/scheduler/db.d.ts +2 -1
  581. package/dist/scheduler/db.js +23 -9
  582. package/dist/scheduler/db.js.map +1 -1
  583. package/dist/scheduler/task-board-text.js +1 -1
  584. package/dist/scheduler/task-board-text.js.map +1 -1
  585. package/dist/scheduler/task-board.d.ts +13 -0
  586. package/dist/scheduler/task-board.js +28 -3
  587. package/dist/scheduler/task-board.js.map +1 -1
  588. package/dist/service-drain.d.ts +19 -0
  589. package/dist/service-drain.js +64 -0
  590. package/dist/service-drain.js.map +1 -0
  591. package/dist/service-installer.d.ts +7 -2
  592. package/dist/service-installer.js +13 -10
  593. package/dist/service-installer.js.map +1 -1
  594. package/dist/settings-api.d.ts +20 -0
  595. package/dist/settings-api.js +414 -4
  596. package/dist/settings-api.js.map +1 -1
  597. package/dist/settings-baseline.d.ts +6 -0
  598. package/dist/settings-baseline.js +3 -1
  599. package/dist/settings-baseline.js.map +1 -1
  600. package/dist/settings-change.js +29 -6
  601. package/dist/settings-change.js.map +1 -1
  602. package/dist/settings-effect.d.ts +13 -0
  603. package/dist/settings-effect.js +97 -0
  604. package/dist/settings-effect.js.map +1 -1
  605. package/dist/settings-http-confirmation.js +13 -1
  606. package/dist/settings-http-confirmation.js.map +1 -1
  607. package/dist/settings-instance-patch.js +27 -0
  608. package/dist/settings-instance-patch.js.map +1 -1
  609. package/dist/setup-wizard.js +6 -2
  610. package/dist/setup-wizard.js.map +1 -1
  611. package/dist/task-board-tool.d.ts +13 -1
  612. package/dist/task-board-tool.js +104 -4
  613. package/dist/task-board-tool.js.map +1 -1
  614. package/dist/task-board-waker.d.ts +6 -0
  615. package/dist/task-board-waker.js +4 -0
  616. package/dist/task-board-waker.js.map +1 -1
  617. package/dist/tmux-binary.d.ts +59 -0
  618. package/dist/tmux-binary.js +200 -0
  619. package/dist/tmux-binary.js.map +1 -0
  620. package/dist/tmux-control.js +4 -4
  621. package/dist/tmux-control.js.map +1 -1
  622. package/dist/tmux-exec-helper.js +32 -1
  623. package/dist/tmux-exec-helper.js.map +1 -1
  624. package/dist/tmux-manager.d.ts +1 -1
  625. package/dist/tmux-manager.js +45 -36
  626. package/dist/tmux-manager.js.map +1 -1
  627. package/dist/tmux-read.js +4 -3
  628. package/dist/tmux-read.js.map +1 -1
  629. package/dist/tool-permissions.d.ts +5 -2
  630. package/dist/tool-permissions.js +6 -5
  631. package/dist/tool-permissions.js.map +1 -1
  632. package/dist/tool-progress.d.ts +2 -0
  633. package/dist/tool-progress.js +19 -3
  634. package/dist/tool-progress.js.map +1 -1
  635. package/dist/topic-commands.js +10 -5
  636. package/dist/topic-commands.js.map +1 -1
  637. package/dist/transcript-monitor.d.ts +20 -0
  638. package/dist/transcript-monitor.js +47 -3
  639. package/dist/transcript-monitor.js.map +1 -1
  640. package/dist/transcript-needles.d.ts +7 -0
  641. package/dist/transcript-needles.js +9 -1
  642. package/dist/transcript-needles.js.map +1 -1
  643. package/dist/transcript-records.d.ts +1 -1
  644. package/dist/transcript-records.js +2 -1
  645. package/dist/transcript-records.js.map +1 -1
  646. package/dist/types.d.ts +6 -0
  647. package/dist/ui/account-identity.js +27 -0
  648. package/dist/ui/accounts-view.js +214 -0
  649. package/dist/ui/agent-runtime-settings.js +9 -8
  650. package/dist/ui/backend-signin.js +4 -1
  651. package/dist/ui/chat-ambient.js +1 -1
  652. package/dist/ui/chat-md-strings.js +3 -0
  653. package/dist/ui/chat-render.js +3 -670
  654. package/dist/ui/chat-store.js +1 -1
  655. package/dist/ui/chat-strings.js +3 -333
  656. package/dist/ui/chat-thread.js +3 -919
  657. package/dist/ui/chat-time.js +3 -80
  658. package/dist/ui/chat-tour.js +1 -1
  659. package/dist/ui/credential-profile-select.js +54 -0
  660. package/dist/ui/fleet-office-dialogue.d.ts +30 -0
  661. package/dist/ui/fleet-office-dialogue.js +382 -0
  662. package/dist/ui/fleet-office-pack.d.ts +9 -0
  663. package/dist/ui/fleet-office-pack.js +76 -4
  664. package/dist/ui/fleet-office-skin.js +23 -5
  665. package/dist/ui/fleet-office-store.js +5 -0
  666. package/dist/ui/fleet-office.js +173 -6
  667. package/dist/ui/fleet-task-card.js +10 -6
  668. package/dist/ui/fleet-task-common.js +12 -2
  669. package/dist/ui/fleet-task-menu.js +188 -0
  670. package/dist/ui/fleet-task-stats.js +124 -0
  671. package/dist/ui/fleet-task-view.js +340 -0
  672. package/dist/ui/fleet-tasks.js +131 -43
  673. package/dist/ui/fleet-usage.js +90 -27
  674. package/dist/ui/html-attachment.js +3 -40
  675. package/dist/ui/hub-agent-copy.js +23 -0
  676. package/dist/ui/hub-button-actions.js +65 -0
  677. package/dist/ui/hub-chat-store.js +158 -0
  678. package/dist/ui/hub-chat-strings.js +77 -0
  679. package/dist/ui/hub-client.js +329 -0
  680. package/dist/ui/hub-owner-strings.js +51 -0
  681. package/dist/ui/hub-provider-guidance.js +31 -0
  682. package/dist/ui/hub-quota.js +85 -0
  683. package/dist/ui/hub-strings.js +162 -0
  684. package/dist/ui/hub-switcher.js +27 -0
  685. package/dist/ui/native-pane-recovery.js +1 -1
  686. package/dist/ui/office-share-page.js +4 -2
  687. package/dist/ui/panel-chat.js +34 -48
  688. package/dist/ui/panel-details.js +1 -1
  689. package/dist/ui/panel-fleet.js +78 -10
  690. package/dist/ui/panel-hub.js +619 -0
  691. package/dist/ui/panel-log.js +2 -2
  692. package/dist/ui/panel-needs.js +24 -8
  693. package/dist/ui/panel-runtimes.js +114 -23
  694. package/dist/ui/panel-settings.js +69 -80
  695. package/dist/ui/panel-windows-cli.js +12 -2
  696. package/dist/ui/preview-pages.js +1 -1
  697. package/dist/ui/preview-panel.js +92 -6
  698. package/dist/ui/preview-versions.js +1 -1
  699. package/dist/ui/preview.js +3 -476
  700. package/dist/ui/runtime-commands.d.ts +4 -0
  701. package/dist/ui/runtime-commands.js +59 -0
  702. package/dist/ui/search-dialog.js +2 -0
  703. package/dist/ui/settings-access-strings.js +42 -0
  704. package/dist/ui/settings-build-version.js +35 -0
  705. package/dist/ui/settings-codex-copy.js +19 -0
  706. package/dist/ui/settings-devices.js +253 -0
  707. package/dist/ui/settings-dialogs.js +28 -7
  708. package/dist/ui/settings-hub-browser-certificate.js +74 -0
  709. package/dist/ui/settings-hub-membership.js +72 -0
  710. package/dist/ui/settings-hub-retention.js +52 -0
  711. package/dist/ui/settings-hub.js +196 -0
  712. package/dist/ui/settings-layout.js +8 -11
  713. package/dist/ui/settings-model.js +16 -2
  714. package/dist/ui/settings-outside.js +104 -38
  715. package/dist/ui/settings-registry.js +4 -1
  716. package/dist/ui/settings-shared-strings.js +143 -0
  717. package/dist/ui/settings-shared.js +345 -0
  718. package/dist/ui/settings-strings.js +10 -46
  719. package/dist/ui/settings-web-authority.js +5 -2
  720. package/dist/ui/shared/accounts.css +15 -0
  721. package/dist/ui/shared/app-i18n.js +2 -2
  722. package/dist/ui/shared/app-needs.js +1 -1
  723. package/dist/ui/shared/app-route.js +6 -1
  724. package/dist/ui/shared/app-session.js +6 -2
  725. package/dist/ui/shared/app-shell.js +64 -8
  726. package/dist/ui/shared/app.css +121 -30
  727. package/dist/ui/shared/app.js +12 -3
  728. package/dist/ui/shared/chat-composer.js +68 -0
  729. package/dist/ui/shared/chat-md-strings.js +9 -0
  730. package/dist/ui/shared/chat-render.js +682 -0
  731. package/dist/ui/shared/chat-strings.js +333 -0
  732. package/dist/ui/shared/chat-thread.js +969 -0
  733. package/dist/ui/shared/chat-time.js +80 -0
  734. package/dist/ui/shared/header-tools.js +3 -5
  735. package/dist/ui/shared/html-attachment.js +42 -0
  736. package/dist/ui/shared/hub-chat.css +85 -0
  737. package/dist/ui/shared/hub-owner.css +33 -0
  738. package/dist/ui/shared/hub-quota.css +8 -0
  739. package/dist/ui/shared/hub.css +71 -0
  740. package/dist/ui/shared/page-head.js +8 -0
  741. package/dist/ui/shared/panel-view.js +77 -4
  742. package/dist/ui/shared/preview.js +476 -0
  743. package/dist/ui/shared/runtime-install.css +26 -0
  744. package/dist/ui/shared/side-rail.js +15 -0
  745. package/dist/ui/shared/signin.js +172 -0
  746. package/dist/ui/shared/task-board.css +95 -0
  747. package/dist/ui/shared/usage-dialog.js +18 -1
  748. package/dist/ui/shared/view-history.css +17 -0
  749. package/dist/ui/shared/view-history.js +438 -0
  750. package/dist/ui/shared/view-strings.js +16 -0
  751. package/dist/ui/shared/workspace.css +20 -0
  752. package/dist/ui/signin.html +21 -0
  753. package/dist/ui/workspace-panel.js +189 -0
  754. package/dist/ui/workspace-strings.js +35 -0
  755. package/dist/unattended-install.d.ts +11 -2
  756. package/dist/unattended-install.js +41 -6
  757. package/dist/unattended-install.js.map +1 -1
  758. package/dist/usage/capacity.d.ts +69 -0
  759. package/dist/usage/capacity.js +119 -0
  760. package/dist/usage/capacity.js.map +1 -0
  761. package/dist/usage/i18n-keys.d.ts +1 -1
  762. package/dist/usage/i18n-keys.js +3 -0
  763. package/dist/usage/i18n-keys.js.map +1 -1
  764. package/dist/usage/profile-timeline.d.ts +16 -0
  765. package/dist/usage/profile-timeline.js +58 -0
  766. package/dist/usage/profile-timeline.js.map +1 -0
  767. package/dist/usage/providers.js +2 -1
  768. package/dist/usage/providers.js.map +1 -1
  769. package/dist/usage/quota-history.d.ts +43 -0
  770. package/dist/usage/quota-history.js +168 -0
  771. package/dist/usage/quota-history.js.map +1 -0
  772. package/dist/usage/usage-api.d.ts +31 -0
  773. package/dist/usage/usage-api.js +80 -1
  774. package/dist/usage/usage-api.js.map +1 -1
  775. package/dist/usage-report.d.ts +25 -1
  776. package/dist/usage-report.js +55 -4
  777. package/dist/usage-report.js.map +1 -1
  778. package/dist/usage-rollup.d.ts +6 -1
  779. package/dist/usage-rollup.js +16 -4
  780. package/dist/usage-rollup.js.map +1 -1
  781. package/dist/view-api.d.ts +16 -0
  782. package/dist/view-api.js +105 -23
  783. package/dist/view-api.js.map +1 -1
  784. package/dist/view-history.d.ts +84 -0
  785. package/dist/view-history.js +116 -0
  786. package/dist/view-history.js.map +1 -0
  787. package/dist/web-api.d.ts +48 -2
  788. package/dist/web-api.js +276 -8
  789. package/dist/web-api.js.map +1 -1
  790. package/dist/web-backend-login.d.ts +23 -1
  791. package/dist/web-backend-login.js +11 -17
  792. package/dist/web-backend-login.js.map +1 -1
  793. package/dist/web-device-login.d.ts +153 -0
  794. package/dist/web-device-login.js +278 -0
  795. package/dist/web-device-login.js.map +1 -0
  796. package/dist/web-office-skins.d.ts +9 -0
  797. package/dist/web-office-skins.js +16 -1
  798. package/dist/web-office-skins.js.map +1 -1
  799. package/dist/web-session-authorization.d.ts +13 -2
  800. package/dist/web-session-authorization.js +10 -3
  801. package/dist/web-session-authorization.js.map +1 -1
  802. package/dist/web-session.d.ts +35 -0
  803. package/dist/web-session.js +7 -0
  804. package/dist/web-session.js.map +1 -1
  805. package/dist/web-settings-patch.d.ts +3 -1
  806. package/dist/web-settings-patch.js +4 -1
  807. package/dist/web-settings-patch.js.map +1 -1
  808. package/dist/web-shell-routes.d.ts +6 -0
  809. package/dist/web-shell-routes.js +7 -0
  810. package/dist/web-shell-routes.js.map +1 -1
  811. package/dist/web-terminal.d.ts +4 -30
  812. package/dist/web-terminal.js +9 -6
  813. package/dist/web-terminal.js.map +1 -1
  814. package/dist/windows-agents.d.ts +1 -0
  815. package/dist/windows-agents.js +1 -0
  816. package/dist/windows-agents.js.map +1 -1
  817. package/dist/windows-cli-api.d.ts +12 -1
  818. package/dist/windows-cli-api.js +27 -1
  819. package/dist/windows-cli-api.js.map +1 -1
  820. package/dist/windows-cli-providers.d.ts +0 -9
  821. package/dist/windows-cli-providers.js +4 -9
  822. package/dist/windows-cli-providers.js.map +1 -1
  823. package/dist/windows-cli-worker.d.ts +24 -0
  824. package/dist/windows-cli-worker.js +96 -5
  825. package/dist/windows-cli-worker.js.map +1 -1
  826. package/dist/windows-cli.d.ts +10 -0
  827. package/dist/windows-cli.js +10 -1
  828. package/dist/windows-cli.js.map +1 -1
  829. package/dist/yaml-shared-nodes.js +8 -3
  830. package/dist/yaml-shared-nodes.js.map +1 -1
  831. package/launcher/agend-install.cjs +8 -1
  832. package/launcher/launchd-session-type.cjs +14 -0
  833. package/launcher/postinstall.cjs +27 -2
  834. package/launcher/private-home.cjs +1 -1
  835. package/launcher/tmux-bundle.cjs +247 -0
  836. package/package.json +3 -2
  837. package/templates/launchd.plist.ejs +3 -1
  838. package/templates/runtime-install/install.ps1 +270 -0
package/dist/daemon.js CHANGED
@@ -1,5 +1,6 @@
1
1
  import { nativePaneToolRefusal } from "./native-pane-tools.js";
2
2
  import { generalByName } from "./general-instance.js";
3
+ import { quotaHistoryCount, quotaAfterInput } from "./pane-quota-history.js";
3
4
  import { dialogScreenText } from "./dialog-screen-text.js";
4
5
  import { readActiveKiroModel } from "./backend/kiro.js";
5
6
  import { dashboardAccessOf } from "./dashboard-permissions.js";
@@ -35,14 +36,14 @@ import { scopedFleetConfigEnvironment } from "./web-experimental.js";
35
36
  import { readAgentFile } from "./agent-file-read.js";
36
37
  import { ASSET_UPLOAD_MAX_BYTES, receivePreview, sendAssetInParts, writePreview } from "./web-asset-parts.js";
37
38
  import { LOGIN_FLOWS } from "./login-flows.js";
38
- import { ProgressAccumulator, summarizeProgress } from "./tool-progress.js";
39
+ import { ProgressAccumulator, isSearchProgram, summarizeProgress } from "./tool-progress.js";
39
40
  import { assembleSystemPrompt, resolveWorkflowText } from "./prompt-file-ref.js";
40
41
  import { isCrossInstanceVisibility } from "./cross-instance-notice.js";
41
42
  import { ContextGuardian } from "./context-guardian.js";
42
43
  import { IpcServer } from "./channel/ipc-bridge.js";
43
44
  import { daemonBudgetMs } from "./channel/ipc-timeouts.js";
44
45
  import { MessageBus } from "./channel/message-bus.js";
45
- import { shellQuote, UnsupportedCliError, ResumeBlockedError } from "./backend/types.js";
46
+ import { shellQuote, KiroCompatibilityError, UnsupportedCliError, ResumeBlockedError } from "./backend/types.js";
46
47
  import { getTmuxSession } from "./config.js";
47
48
  import { routeToolCall } from "./channel/tool-router.js";
48
49
  import { parseReplyButtons, replyButtonsFallbackText } from "./reply-buttons.js";
@@ -58,13 +59,14 @@ import { agendMessageInInput, bottomRowIsReady, inputAreaText, inputShowsPastedT
58
59
  import { TurnReplyGuard, formatReplyDropDetection, turnExpectsPersonReply } from "./turn-reply-guard.js";
59
60
  import { CLAUDE_CREDIT_BALANCE_LOW, CLAUDE_MODEL_USAGE_LIMIT, CLAUDE_USAGE_LIMIT_PAUSE } from "./backend/claude-transcript-errors.js";
60
61
  import { t } from "./locale.js";
61
- import { claudeResetTime, quotaPausedLine } from "./quota-notice.js";
62
+ import { claudeResetInstant, claudeResetTime, quotaPausedLine } from "./quota-notice.js";
62
63
  import { MuseUsageRelay, clearMuseUsageSnapshot } from "./muse-usage-relay.js";
63
64
  import { reconcileNativePaneTarget } from "./native-pane-reconciliation.js";
64
65
  import { deliveryContentDigest } from "./delivery-outbox.js";
65
66
  import { consumedWatches } from "./delivery-consumed-watch.js";
66
67
  import { queueResumePolicyForAttempt } from "./delivery-queue-evidence.js";
67
- import { scanTranscriptForDeliveryMarker } from "./delivery-reconciliation.js";
68
+ import { markerConsumed, scanTranscriptForDeliveryMarker } from "./delivery-reconciliation.js";
69
+ import { QUEUED_HANDOFF_MAX_REDELIVERIES, QueuedHandoffStore } from "./queued-handoffs.js";
68
70
  import { measureSyncWork, noteSyncWork } from "./sync-work-attribution.js";
69
71
  import { TranscriptDeltaReader } from "./transcript-delta-reader.js";
70
72
  import { buildResumeContinuation, clearInFlightTurnMarker, consumeInFlightTurnMarker, decideTurnResume, normalizeResumeBackend, readResumeFingerprint, RESUME_BLOCKING_DELIVERY_STATES, writeInFlightTurnMarker, } from "./turn-resume.js";
@@ -155,6 +157,8 @@ export const HANDOFF_RECHECK_MS = 1_000;
155
157
  export const WAIT_STOP_POLL_MS = 250;
156
158
  /** #2770: human messages a cancel dropped are told in one notice, this long after the last of them. */
157
159
  export const CANCELLED_HUMANS_NOTICE_MS = 1_000;
160
+ /** #3030: a queued hand-off's watch outlives a long turn (the record outlives the watch in any case). */
161
+ export const QUEUED_HANDOFF_WATCH_LIFETIME_MS = 12 * 60 * 60_000;
158
162
  /**
159
163
  * An instance publishing more than this many execution-state edges inside the
160
164
  * window is flapping; its edges stop being logged one by one (#1116). One
@@ -347,7 +351,8 @@ export function shellCommandLabel(command) {
347
351
  if (!program)
348
352
  return "";
349
353
  const isBareWord = (t) => !!t && /^[A-Za-z][A-Za-z0-9_-]*$/.test(t);
350
- const label = isBareWord(tokens[1]) ? `${program} ${tokens[1]}` : program;
354
+ // A search program's next word is what it searches for, not a subcommand: `grep <token>` keeps only `grep`.
355
+ const label = isBareWord(tokens[1]) && !isSearchProgram(program) ? `${program} ${tokens[1]}` : program;
351
356
  return label.length > 40 ? `${label.slice(0, 39)}…` : label;
352
357
  }
353
358
  export class PaneStateMachine {
@@ -1585,6 +1590,12 @@ export class Daemon extends EventEmitter {
1585
1590
  pendingWhatsNew = null;
1586
1591
  pasteQueueDepth = 0;
1587
1592
  /** #2770: a person's messages a cancel dropped before they reached the CLI, told together (noteCancelledHuman). */
1593
+ /** #3030: people's messages a CLI never took (or that a restart left unverifiable), told once per batch. */
1594
+ unsettledHandoffs = { "not-taken": [], unverifiable: [] };
1595
+ unsettledHandoffsTimer = null;
1596
+ /** #3030: since when (monotonic) the CLI has been idle without a break; null while it is not. */
1597
+ instanceIdleSinceMono = null;
1598
+ queuedHandoffStore = null;
1588
1599
  cancelledHumans = [];
1589
1600
  cancelledHumansTimer = null;
1590
1601
  firstDeliveryDelay = new FirstDeliveryDelay();
@@ -1789,6 +1800,85 @@ export class Daemon extends EventEmitter {
1789
1800
  // still booting. Its new tmux window starts empty before resume restores the
1790
1801
  // old transcript, so pre-ready scans must not lower this seeded baseline.
1791
1802
  seededErrorCountBaselines = new Map();
1803
+ nativeQuotaReplayTaken = false;
1804
+ quotaReplay = null;
1805
+ paneQuotaPatterns() {
1806
+ if (!["codex", "grok"].includes(this.backend?.binaryName ?? ""))
1807
+ return [];
1808
+ const patterns = this.backend?.getErrorPatterns?.() ?? [];
1809
+ return this.backend?.binaryName === "codex" ? patterns.filter(ep => Daemon.isCodexUsageLimitPause(ep)) : patterns.filter(ep => ep.type === "quota");
1810
+ }
1811
+ async prepareQuotaReplayHistory(reuseWindow) {
1812
+ this.quotaReplay = null;
1813
+ const backend = this.backend, owner = this.tmux, window = owner?.getWindowId?.();
1814
+ const spawn = this.spawnGeneration, fence = this.launchFenceEpoch, attempt = this.launchAttempt;
1815
+ const current = () => backend === this.backend && owner === this.tmux && window === owner?.getWindowId?.()
1816
+ && spawn === this.spawnGeneration && fence === this.launchFenceEpoch && attempt === this.launchAttempt;
1817
+ const replay = backend?.quotaReplayHistory?.();
1818
+ if (replay)
1819
+ this.quotaReplay = { ...replay, spawn, fence, attempt };
1820
+ // A Grok wake keeps its exited pane. The replacement's first ready pane is not history proof.
1821
+ if (reuseWindow && backend?.resumesPreservedQuotaHistory?.()) {
1822
+ let oldPane;
1823
+ try {
1824
+ oldPane = await owner.capturePane();
1825
+ }
1826
+ catch {
1827
+ return;
1828
+ }
1829
+ this.startupAdmission?.();
1830
+ if (!current())
1831
+ return;
1832
+ const patterns = this.paneQuotaPatterns();
1833
+ const messages = oldPane.split(/\r?\n/).filter(row => patterns.some(ep => ep.pattern.test(row)));
1834
+ this.quotaReplay = { messages, current: () => true, spawn, fence, attempt };
1835
+ }
1836
+ }
1837
+ /** Before admission, this launch may absorb ONLY rows positively known before its resume. */
1838
+ takeQuotaReplayBaseline(pane) {
1839
+ // Native captures carry only a runner-frozen pre-launch proof, revalidated with this capture's owner and seq.
1840
+ const native = !this.nativeQuotaReplayTaken ? this.nativePaneLifecycle?.quotaReplayHistory?.() : null;
1841
+ if (this.nativePaneLifecycle)
1842
+ this.nativeQuotaReplayTaken = true;
1843
+ const history = this.quotaReplay ?? (native ? { ...native, spawn: this.spawnGeneration, fence: this.launchFenceEpoch, attempt: this.launchAttempt } : null);
1844
+ if (!history)
1845
+ return;
1846
+ this.quotaReplay = null;
1847
+ if (history.spawn !== this.spawnGeneration || history.fence !== this.launchFenceEpoch || history.attempt !== this.launchAttempt || !history.current())
1848
+ return;
1849
+ for (const ep of this.paneQuotaPatterns()) {
1850
+ const count = Math.min(Daemon.countOccurrences(ep.pattern, pane), quotaHistoryCount(pane, ep.pattern, history.messages));
1851
+ if (!count)
1852
+ continue;
1853
+ const key = Daemon.errorPatternKey(ep);
1854
+ this.lastErrorCount.set(key, Math.max(this.lastErrorCount.get(key) ?? 0, count));
1855
+ this.logger.debug({ backend: this.backend?.binaryName, count, evidence: "before-resume" }, "Quota rows restored from history — not a new incident");
1856
+ }
1857
+ }
1858
+ // Submission makes captured rows history even when no monitor reported them yet. Keep this acknowledged input's
1859
+ // marker as well: a new error can replace an old row in the viewport without increasing the total match count.
1860
+ quotaInput = null;
1861
+ commitPreInputQuotaHistory(evidence) {
1862
+ const history = evidence?.quotaHistory;
1863
+ if (!history || history.spawn !== this.spawnGeneration || history.fence !== this.launchFenceEpoch || history.attempt !== this.launchAttempt
1864
+ || history.tmux !== this.tmux || history.window !== this.tmux?.getWindowId?.() || this.deliveryWritesStopping)
1865
+ return;
1866
+ for (const row of history.counts)
1867
+ this.lastErrorCount.set(row.key, row.count);
1868
+ this.quotaInput = history.marker && history.occurrences === 0 ? { history, reported: new Map() } : null;
1869
+ }
1870
+ quotaOccurrencesAfterInput(pane, ep) {
1871
+ if (!(this.backend?.binaryName === "codex" && Daemon.isCodexUsageLimitPause(ep)
1872
+ || this.backend?.binaryName === "grok" && ep.type === "quota"))
1873
+ return null;
1874
+ const input = this.quotaInput, history = input?.history;
1875
+ if (!input || !history || history.spawn !== this.spawnGeneration || history.fence !== this.launchFenceEpoch
1876
+ || history.attempt !== this.launchAttempt || history.tmux !== this.tmux || history.window !== this.tmux?.getWindowId?.()
1877
+ || this.deliveryWritesStopping)
1878
+ return null;
1879
+ const suffix = quotaAfterInput(pane, history.marker);
1880
+ return suffix === null ? null : { input, count: Daemon.countOccurrences(ep.pattern, suffix) };
1881
+ }
1792
1882
  lastDetectedErrorType = null;
1793
1883
  /**
1794
1884
  * #2822: Claude's per-model usage limit (`You've reached your <model> limit.`), known only from Claude's own record of
@@ -1810,12 +1900,55 @@ export class Daemon extends EventEmitter {
1810
1900
  static CREDIT_BALANCE_LOW = CLAUDE_CREDIT_BALANCE_LOW;
1811
1901
  /** #2834 (#816): Claude's usage-limit auto-continue note, as it records it (`system` / `informational`). */
1812
1902
  static USAGE_LIMIT_PAUSE = CLAUDE_USAGE_LIMIT_PAUSE;
1813
- /** #2834 (#816): Claude paused itself until its usage window opens — the same notice the screen pattern gave. */
1814
- noteClaudeInformational(text) {
1815
- const match = Daemon.USAGE_LIMIT_PAUSE.exec(text.trim());
1903
+ /** Claude's note that its usage window opened again ("Usage limit reset · continuing automatically"). */
1904
+ static USAGE_LIMIT_RESET = /^Usage limit reset\b/i;
1905
+ /** Repeats of one usage pause ("reached again" every few minutes) collapse into the first notice for this long. */
1906
+ static USAGE_PAUSE_NOTICE_WINDOW_MS = 30 * 60_000;
1907
+ /** The usage-pause notice told last: when (monotonic), Claude's words for the reset, and that reset (wall clock). */
1908
+ usagePauseNotice = null;
1909
+ /** Coarse status for the representative quota hint; never exports model names or transcript text. */
1910
+ quotaPaused() {
1911
+ if (this.usageLimitHold)
1912
+ return true;
1913
+ const pause = this.usagePauseNotice;
1914
+ return !!pause && (pause.resetAt === null
1915
+ ? performance.now() - pause.at < Daemon.USAGE_PAUSE_NOTICE_WINDOW_MS
1916
+ : Date.now() < pause.resetAt);
1917
+ }
1918
+ /**
1919
+ * #2834 (#816): Claude paused itself until its usage window opens — the same notice the screen pattern gave. `at`: when
1920
+ * Claude wrote it (its record's timestamp). One notice per pause: a reset time already past is not this pause (an old
1921
+ * note), and its repeats ("reached again") within the window — or naming the same reset, until it comes — say nothing
1922
+ * more. Claude's own "Usage limit reset" ends it.
1923
+ */
1924
+ /** #3186 review: the lifecycle's second opinion dropped the notice (usage has capacity): nothing was told. */
1925
+ clearUsagePauseNotice() { this.usagePauseNotice = null; }
1926
+ noteClaudeInformational(text, at = null) {
1927
+ const line = text.trim();
1928
+ if (Daemon.USAGE_LIMIT_RESET.test(line)) {
1929
+ this.usagePauseNotice = null;
1930
+ return;
1931
+ }
1932
+ const match = Daemon.USAGE_LIMIT_PAUSE.exec(line);
1816
1933
  if (!match)
1817
1934
  return;
1818
1935
  const when = match[1].trim();
1936
+ const wallNow = Date.now(), now = performance.now();
1937
+ const resetAt = claudeResetInstant(when, at ?? wallNow);
1938
+ if (resetAt !== null && resetAt <= wallNow) {
1939
+ this.logger.debug({ when, writtenAt: at }, "Claude usage-limit note names a reset already past — an old note, not told");
1940
+ return;
1941
+ }
1942
+ // A pause told earlier is this one while its own reset has not come (unknown: within the window): its repeats —
1943
+ // "reached again", or a relative time drifting ("in 3h", "in 2h 55m") — within the window, or naming the same reset.
1944
+ // Once its reset has passed, a later note is a new pause even without Claude's "Usage limit reset" (#3186 review).
1945
+ const told = this.usagePauseNotice;
1946
+ const toldOpen = !!told && (told.resetAt === null || wallNow < told.resetAt);
1947
+ if (told && toldOpen && (now - told.at < Daemon.USAGE_PAUSE_NOTICE_WINDOW_MS || (told.when === when && told.resetAt !== null))) {
1948
+ this.logger.debug({ when }, "Claude usage-limit note repeats a pause already told — collapsed");
1949
+ return;
1950
+ }
1951
+ this.usagePauseNotice = { at: now, when, resetAt };
1819
1952
  this.emit("pty_error", { name: this.name, type: "quota", action: "notify", verifyQuota: true, skipCooldown: true, skipRecoveryWait: true,
1820
1953
  message: `Claude Code usage limit reached — paused; continuing automatically ${when}`,
1821
1954
  notice: quotaPausedLine("Claude", "usage", claudeResetTime(when)) });
@@ -1954,6 +2087,13 @@ export class Daemon extends EventEmitter {
1954
2087
  nativeFleetBridge;
1955
2088
  nativeTranscriptSource;
1956
2089
  usesNativePane() { return !!this.nativePaneLifecycle; }
2090
+ /** cc3ce4fe: the CLI version this pane's launch actually ran, as its helper recorded it (undefined: not known). */
2091
+ nativePaneCliVersion() { try {
2092
+ return this.nativePaneLifecycle?.snapshot?.()?.cliVersion;
2093
+ }
2094
+ catch {
2095
+ return undefined;
2096
+ } }
1957
2097
  logNativeInputRefusal(details) {
1958
2098
  this.logger.warn({ component: "runtime-pane-host", reason: "expected_seq_changed", ...details }, "Native pane input refused before write");
1959
2099
  }
@@ -2076,6 +2216,9 @@ export class Daemon extends EventEmitter {
2076
2216
  this.publishWorkingState("turn_closed");
2077
2217
  };
2078
2218
  }
2219
+ /** Register each issued HTTP credential with the same-process lifecycle owner. */
2220
+ agentCredentialIssuer;
2221
+ setAgentCredentialIssuer(issue) { this.agentCredentialIssuer = issue; }
2079
2222
  /** FleetManager and this daemon share a process, so durable begin/ACK is a direct synchronous store call. */
2080
2223
  setDeliveryOutboxPort(port) {
2081
2224
  this.deliveryOutbox = port;
@@ -2228,6 +2371,246 @@ export class Daemon extends EventEmitter {
2228
2371
  logger: this.logger,
2229
2372
  });
2230
2373
  }
2374
+ handoffStore() {
2375
+ return this.queuedHandoffStore ??= new QueuedHandoffStore(this.instanceDir);
2376
+ }
2377
+ /** #3030: the CLI that holds a queued hand-off; a record is settled only by a later one. */
2378
+ handoffHolder() { return `${this.bootId}:${this.spawnGeneration}`; }
2379
+ /**
2380
+ * #3030: before the paste. A hand-off into a busy Claude Code / Codex queue gets its record — the transcript
2381
+ * checkpoint before the paste, the unique leading marker and what a redelivery needs — or, for a redelivery written
2382
+ * as an ordinary idle submission, its record moves its checkpoint here, so a crash right after this paste is still
2383
+ * judged from the transcript that will show it. A write that did not keep a record runs as before.
2384
+ */
2385
+ async recordQueuedHandoff(formatted, handingOff, verdict, durableAttempt, humanVerificationId) {
2386
+ const track = verdict.trackHandoff;
2387
+ if (!track)
2388
+ return;
2389
+ if (!handingOff && !track.id) {
2390
+ // An earlier attempt of this delivery was a hand-off; this one is an idle submission.
2391
+ if (verdict.handoff)
2392
+ this.dropQueuedHandoff(verdict);
2393
+ return;
2394
+ }
2395
+ const backend = this.config.backend ?? this.backend?.binaryName ?? "";
2396
+ if (!["claude-code", "codex"].includes(backend))
2397
+ return;
2398
+ const marker = durableAttempt ? `[agend-delivery-id:${durableAttempt.deliveryId}]`
2399
+ : humanVerificationId ? `[agend-human-id:${humanVerificationId}]` : null;
2400
+ if (!marker || !formatted.startsWith(marker))
2401
+ return;
2402
+ let found = verdict.transcriptCheckpoint ?? null;
2403
+ if (!found) {
2404
+ try {
2405
+ found = await this.transcriptMonitor?.reconciliationCheckpoint() ?? null;
2406
+ }
2407
+ catch (err) {
2408
+ this.logger.debug({ err }, "Could not checkpoint the transcript before a queued hand-off");
2409
+ }
2410
+ }
2411
+ // main→alpha sync: a hand-off record is judged against a local transcript file. A native or remote runtime's
2412
+ // transcript (no local path) has none: it runs as before (✅ at the hand-off), as with no checkpoint at all.
2413
+ const checkpoint = found && typeof found.path === "string" && typeof found.offset === "number" ? { path: found.path, offset: found.offset } : null;
2414
+ if (!checkpoint)
2415
+ return; // nothing could judge it later: it runs as before (✅ at the hand-off)
2416
+ const entry = {
2417
+ id: track.id ?? randomUUID(), marker, backend, path: checkpoint.path, offset: checkpoint.offset,
2418
+ content: track.content, meta: track.meta, holder: this.handoffHolder(), createdAt: Date.now(),
2419
+ redeliveries: track.redeliveries ?? 0,
2420
+ };
2421
+ try {
2422
+ const dropped = this.handoffStore().put(entry);
2423
+ if (handingOff)
2424
+ verdict.handoff = entry;
2425
+ for (const old of dropped)
2426
+ this.logger.warn({ handoff: old.id, createdAt: old.createdAt }, "Queued hand-off record dropped: too many on record");
2427
+ }
2428
+ catch (err) {
2429
+ this.logger.warn({ err }, "Could not record a queued hand-off; it runs as before (✅ at the hand-off)");
2430
+ }
2431
+ }
2432
+ /**
2433
+ * #3030: after pushChannelMessage's write. A hand-off on record whose paste went out is watched (✅ when a turn
2434
+ * takes it); one that was never written goes. A redelivery that ended as an ordinary submission is done; one that a
2435
+ * cancel dropped goes too (a cancel is the person's); one stopped before its write stays for the next CLI.
2436
+ */
2437
+ afterTrackedWrite(meta, verdict, sent, deliveryEpoch) {
2438
+ try {
2439
+ // A stale epoch with writes still allowed is a cancel (the person's); a stop fences writes too, and keeps records.
2440
+ const cancelled = !this.isDeliveryEpochCurrent(deliveryEpoch) && !this.deliveryWritesStopping;
2441
+ if (verdict.handoff) {
2442
+ if (sent || verdict.paneWriteStarted)
2443
+ this.watchQueuedHandoff(verdict.handoff);
2444
+ else if (!verdict.trackHandoff?.id || cancelled)
2445
+ this.dropQueuedHandoff(verdict);
2446
+ return;
2447
+ }
2448
+ const id = meta.handoff_redelivery;
2449
+ if (!id)
2450
+ return;
2451
+ if (sent || verdict.paneWriteStarted || cancelled) {
2452
+ this.handoffStore().remove(id);
2453
+ this.logger.info({ handoff: id, sent, proof: verdict.proof ?? null }, "Queued hand-off redelivered as an ordinary submission");
2454
+ }
2455
+ }
2456
+ catch (err) {
2457
+ this.logger.warn({ err }, "Could not update the queued hand-off record after its write");
2458
+ }
2459
+ }
2460
+ redeliveryStillOurs(meta) {
2461
+ const holder = this.handoffHolder();
2462
+ if (meta.handoff_holder !== holder)
2463
+ return false;
2464
+ try {
2465
+ return this.handoffStore().get(meta.handoff_redelivery)?.holder === holder;
2466
+ }
2467
+ catch {
2468
+ return false;
2469
+ }
2470
+ }
2471
+ dropQueuedHandoff(verdict) {
2472
+ const entry = verdict.handoff;
2473
+ verdict.handoff = undefined;
2474
+ if (!entry)
2475
+ return;
2476
+ try {
2477
+ this.handoffStore().remove(entry.id);
2478
+ }
2479
+ catch (err) {
2480
+ this.logger.warn({ err, handoff: entry.id }, "Could not remove a queued hand-off record");
2481
+ }
2482
+ }
2483
+ /**
2484
+ * #3030: the hand-off's CLI is the current one: watch its transcript for the turn that takes it (✅ then), and for an
2485
+ * idle CLI that never did (reported). A stop ends the watch; the record stays for the next CLI to settle.
2486
+ */
2487
+ watchQueuedHandoff(entry) {
2488
+ const spawn = this.spawnGeneration, fence = this.launchFenceEpoch, epoch = this.deliveryEpoch;
2489
+ const started = consumedWatches.start({
2490
+ deliveryId: `handoff:${entry.id}`,
2491
+ attemptNo: entry.redeliveries,
2492
+ backend: entry.backend,
2493
+ path: entry.path,
2494
+ offset: entry.offset,
2495
+ marker: entry.marker,
2496
+ // A cancel or stop moves the epoch: the watch ends quietly (a cancel cleared the record, a stop leaves it).
2497
+ current: () => !this.deliveryWritesStopping && spawn === this.spawnGeneration && fence === this.launchFenceEpoch
2498
+ && epoch === this.deliveryEpoch,
2499
+ consumed: (via) => this.settleQueuedHandoff(entry, "taken", `transcript:${via}`),
2500
+ idleForMs: () => this.instanceIdleSinceMono === null ? null : performance.now() - this.instanceIdleSinceMono,
2501
+ notTaken: () => this.settleQueuedHandoff(entry, "not-taken", "transcript:absent-while-idle"),
2502
+ // A queued message waits for the running turn, however long that is.
2503
+ lifetimeMs: QUEUED_HANDOFF_WATCH_LIFETIME_MS,
2504
+ logger: this.logger,
2505
+ });
2506
+ if (!started) {
2507
+ // No watch (the fleet's cap): ✅ as before; the record still lets a restart judge it.
2508
+ const status = channelStatus(entry.meta);
2509
+ if (status)
2510
+ this.emit("message_confirmed", status);
2511
+ }
2512
+ }
2513
+ /** #3030: a record's end — taken (✅), or never taken / not judgeable (❌, told once per batch). */
2514
+ settleQueuedHandoff(entry, outcome, proof) {
2515
+ try {
2516
+ this.handoffStore().remove(entry.id);
2517
+ }
2518
+ catch (err) {
2519
+ this.logger.warn({ err, handoff: entry.id }, "Could not remove a settled queued hand-off record");
2520
+ }
2521
+ const meta = entry.meta;
2522
+ const status = channelStatus(meta);
2523
+ if (outcome === "taken") {
2524
+ this.logger.info({ handoff: entry.id, proof, redeliveries: entry.redeliveries }, "Queued hand-off taken by the CLI");
2525
+ if (status)
2526
+ this.emit("message_confirmed", status);
2527
+ return;
2528
+ }
2529
+ this.logger.warn({ handoff: entry.id, outcome, proof, redeliveries: entry.redeliveries }, "Queued hand-off was not taken by the CLI");
2530
+ if (meta.from_instance) {
2531
+ this.reportCrossInstanceDeliveryFailure(meta, { reached: true, phase: "handoff-not-consumed", proof: outcome === "not-taken" ? "not-taken" : "unverifiable" });
2532
+ return;
2533
+ }
2534
+ if (!status)
2535
+ return;
2536
+ this.unsettledHandoffs[outcome].push({ chatId: status.chatId, messageId: status.messageId, ...(status.threadId ? { threadId: status.threadId } : {}) });
2537
+ if (this.unsettledHandoffsTimer)
2538
+ clearTimeout(this.unsettledHandoffsTimer);
2539
+ this.unsettledHandoffsTimer = setTimeout(() => {
2540
+ this.unsettledHandoffsTimer = null;
2541
+ for (const reason of ["not-taken", "unverifiable"]) {
2542
+ const messages = this.unsettledHandoffs[reason].splice(0);
2543
+ if (messages.length)
2544
+ this.emit("human_handoffs_unsettled", { reason, messages });
2545
+ }
2546
+ }, CANCELLED_HUMANS_NOTICE_MS);
2547
+ this.unsettledHandoffsTimer.unref?.();
2548
+ }
2549
+ /**
2550
+ * #3030: right after a CLI came up — the records left by CLIs that are gone. Their queue went with them, so each is
2551
+ * judged by its own transcript from its checkpoint: taken there (✅, nothing pasted); proven not taken (the whole
2552
+ * delta read, the marker absent or only enqueued) → redelivered once, with the same marker, through the ordinary
2553
+ * queue; anything that cannot be judged → never pasted, reported. Ownership is evidence: never pasted twice.
2554
+ */
2555
+ async reconcileQueuedHandoffs() {
2556
+ let entries;
2557
+ try {
2558
+ entries = this.handoffStore().list().filter(e => e.holder !== this.handoffHolder());
2559
+ }
2560
+ catch (err) {
2561
+ this.logger.warn({ err }, "Could not read the queued hand-off records");
2562
+ return;
2563
+ }
2564
+ if (!entries.length)
2565
+ return;
2566
+ // Captured before any await: a reconciliation that outlives its CLI can never claim the next CLI's holder.
2567
+ const holder = this.handoffHolder();
2568
+ const spawn = this.spawnGeneration, fence = this.launchFenceEpoch, epoch = this.deliveryEpoch;
2569
+ const fresh = () => spawn === this.spawnGeneration && fence === this.launchFenceEpoch && epoch === this.deliveryEpoch
2570
+ && !this.deliveryWritesStopping;
2571
+ let redelivered = 0, taken = 0, unverifiable = 0;
2572
+ for (const entry of entries) {
2573
+ const kind = await scanTranscriptForDeliveryMarker(entry.path, entry.offset, entry.backend, { marker: entry.marker });
2574
+ // This CLI is gone already, or a cancel came: the next CLI settles them (a cancel cleared them).
2575
+ if (!fresh())
2576
+ return;
2577
+ // …and the record is still the one that was read (another reconciliation or a cancel did not change it meanwhile).
2578
+ let current;
2579
+ try {
2580
+ current = this.handoffStore().get(entry.id);
2581
+ }
2582
+ catch {
2583
+ current = undefined;
2584
+ }
2585
+ if (!current || current.holder !== entry.holder || current.redeliveries !== entry.redeliveries)
2586
+ continue;
2587
+ if (markerConsumed(kind)) {
2588
+ taken++;
2589
+ this.settleQueuedHandoff(entry, "taken", `restart-transcript:${kind}`);
2590
+ continue;
2591
+ }
2592
+ if (kind === "unavailable" || entry.redeliveries >= QUEUED_HANDOFF_MAX_REDELIVERIES) {
2593
+ unverifiable++;
2594
+ this.settleQueuedHandoff(entry, "unverifiable", kind === "unavailable" ? "restart-transcript:unavailable" : "redelivery-limit");
2595
+ continue;
2596
+ }
2597
+ // Proven not taken: the CLI that queued it is gone and its transcript, read to the end, never took it.
2598
+ const next = { ...entry, holder, redeliveries: entry.redeliveries + 1 };
2599
+ try {
2600
+ this.handoffStore().put(next);
2601
+ }
2602
+ catch (err) {
2603
+ this.logger.warn({ err, handoff: entry.id }, "Could not update a queued hand-off record; not redelivered now");
2604
+ continue;
2605
+ }
2606
+ redelivered++;
2607
+ // The person's receipt was settled by the first write: the redelivery carries its marker, not its receipt binding.
2608
+ const { human_receipt_id: _r, human_owner_key: _o, human_daemon_owner: _d, human_wire_sha256: _w, ...meta } = entry.meta;
2609
+ this.pushChannelMessage(entry.content, { ...meta, handoff_redelivery: entry.id,
2610
+ handoff_redeliveries: String(next.redeliveries), handoff_holder: next.holder }, undefined, epoch);
2611
+ }
2612
+ this.logger.info({ instance: this.name, redelivered, taken, unverifiable, proof: "transcript" }, "Queued hand-offs left by the previous CLI settled");
2613
+ }
2231
2614
  finishDurableSubmission(delivery, verdict) {
2232
2615
  // Legacy backends may accept a pane write without enough pane evidence to
2233
2616
  // claim submission. Keep that row inspectable instead of recording a false
@@ -2596,7 +2979,20 @@ export class Daemon extends EventEmitter {
2596
2979
  // New/resumed native processes can still be painting their first frame. Keep deliveries behind the same
2597
2980
  // bounded dialog/readiness scan as local startup. An already-running reattachment may be busy: do not
2598
2981
  // wait for that work to finish or inject a startup key into it.
2599
- if (acquired.disposition !== "reattached") {
2982
+ if (acquired.disposition === "reattached") {
2983
+ if (this.backend?.binaryName === "codex") {
2984
+ const native = this.nativePaneLifecycle, spawn = this.spawnGeneration, fence = this.launchFenceEpoch, attempt = this.launchAttempt;
2985
+ try {
2986
+ const pane = await acquired.pane.capturePane();
2987
+ this.startupAdmission?.();
2988
+ if (!this.startupAborted && !this.deliveryWritesStopping && this.nativePaneLifecycle === native && this.tmux === acquired.pane
2989
+ && spawn === this.spawnGeneration && fence === this.launchFenceEpoch && attempt === this.launchAttempt && native.current())
2990
+ this.takeQuotaReplayBaseline(pane);
2991
+ }
2992
+ catch { /* An old runner or unavailable proof keeps the existing fail-closed scanner. */ }
2993
+ }
2994
+ }
2995
+ else {
2600
2996
  if (!await this.finishStartupScan(120_000))
2601
2997
  throw Error("Native CLI exited during startup; retained session was not replaced");
2602
2998
  this.startupAdmission?.();
@@ -2705,7 +3101,7 @@ export class Daemon extends EventEmitter {
2705
3101
  this.publishActivity(null);
2706
3102
  });
2707
3103
  this.transcriptMonitor.on("api_error", (text, status, _at, errorKind) => this.noteClaudeApiError(text, status, errorKind));
2708
- this.transcriptMonitor.on("system_informational", (text) => this.noteClaudeInformational(text));
3104
+ this.transcriptMonitor.on("system_informational", (text, at) => this.noteClaudeInformational(text, at));
2709
3105
  this.transcriptMonitor.on("user_prompt", () => this.noteClaudePrompt());
2710
3106
  this.transcriptMonitor.on("assistant_text", (text) => {
2711
3107
  this.noteClaudeOutput();
@@ -2750,6 +3146,8 @@ export class Daemon extends EventEmitter {
2750
3146
  this.startErrorMonitor();
2751
3147
  }
2752
3148
  this.startInstanceStateMonitor();
3149
+ // #3030: messages a gone CLI still had queued — judged by its transcript, redelivered once or reported.
3150
+ void this.reconcileQueuedHandoffs().catch(err => this.logger.warn({ err }, "Queued hand-off reconciliation failed"));
2753
3151
  this.logger.info(`${this.name} ready`);
2754
3152
  }
2755
3153
  /**
@@ -3253,8 +3651,6 @@ export class Daemon extends EventEmitter {
3253
3651
  scheduleNext();
3254
3652
  return;
3255
3653
  }
3256
- // The CLI owns the MCP server process, so the daemon can only observe it.
3257
- measureSyncWork("daemon.healthCheck", () => this.checkMcpServerAlive());
3258
3654
  // Human-readable backend label for logs (e.g. "claude", "kiro-cli")
3259
3655
  const cliLabel = this.backend?.binaryName ?? "CLI";
3260
3656
  const healthTmux = this.tmux;
@@ -3275,6 +3671,9 @@ export class Daemon extends EventEmitter {
3275
3671
  if (discardStaleHealth())
3276
3672
  return;
3277
3673
  if (paneStatus?.alive) {
3674
+ // A CLI shutdown also closes its MCP children. Revive tools only for
3675
+ // a positively live pane, never while its exit is being classified.
3676
+ measureSyncWork("daemon.healthCheck", () => this.checkMcpServerAlive());
3278
3677
  // Capture only a known primary while it lives. No extra tmux call: PID comes
3279
3678
  // from this same status read. Fast/unobserved deaths remain ordinary crashes.
3280
3679
  const key = this.oomSessionKey();
@@ -3321,6 +3720,29 @@ export class Daemon extends EventEmitter {
3321
3720
  return;
3322
3721
  }
3323
3722
  }
3723
+ // tmux marks the PTY dead when its fd closes, before SIGCHLD can fill
3724
+ // pane_dead_status. Claude /exit (and any other CLI) can hit this gap.
3725
+ // Give the status four bounded re-probes; missing is never exit zero.
3726
+ if (paneStatus && !paneStatus.alive && paneStatus.exitCode === undefined) {
3727
+ for (let attempt = 0; attempt < 4; attempt++) {
3728
+ await new Promise(resolve => setTimeout(resolve, 250));
3729
+ if (discardStaleHealth())
3730
+ return;
3731
+ const observed = await healthTmux.getPaneStatus();
3732
+ if (discardStaleHealth())
3733
+ return;
3734
+ if (observed)
3735
+ paneStatus = observed;
3736
+ if (paneStatus.alive || paneStatus.exitCode !== undefined)
3737
+ break;
3738
+ }
3739
+ if (paneStatus.alive) {
3740
+ this.windowQueryFailureTicks = 0;
3741
+ this.stormWindow?.noteWindowAlive(this.name);
3742
+ scheduleNext();
3743
+ return;
3744
+ }
3745
+ }
3324
3746
  // paneStatus === null → window gone entirely (e.g. tmux server crash)
3325
3747
  // paneStatus.alive === false → pane dead, exit code available
3326
3748
  const exitCode = paneStatus?.exitCode;
@@ -3504,6 +3926,8 @@ export class Daemon extends EventEmitter {
3504
3926
  try {
3505
3927
  await this.spawnClaudeWindow();
3506
3928
  this.setProcessStatus("running");
3929
+ // #3030: messages a gone CLI still had queued — judged by its transcript, redelivered once or reported.
3930
+ void this.reconcileQueuedHandoffs().catch(err => this.logger.warn({ err }, "Queued hand-off reconciliation failed"));
3507
3931
  this.logger.info("Recovered from background session conflict");
3508
3932
  this.emit("crash_respawn", this.name);
3509
3933
  }
@@ -3663,6 +4087,8 @@ export class Daemon extends EventEmitter {
3663
4087
  catch { /* may not exist */ }
3664
4088
  }
3665
4089
  this.setProcessStatus("running");
4090
+ // #3030: messages a gone CLI still had queued — judged by its transcript, redelivered once or reported.
4091
+ void this.reconcileQueuedHandoffs().catch(err => this.logger.warn({ err }, "Queued hand-off reconciliation failed"));
3666
4092
  this.logger.info({ resumed }, `Respawned ${cliLabel} window after crash`);
3667
4093
  this.emit("crash_respawn", this.name);
3668
4094
  // Emit the per-instance audit event while the storm is still active
@@ -4179,7 +4605,13 @@ export class Daemon extends EventEmitter {
4179
4605
  for (const ep of patterns) {
4180
4606
  const key = Daemon.errorPatternKey(ep);
4181
4607
  const count = countMatches(ep.pattern);
4182
- const seen = this.lastErrorCount.get(key) ?? 0;
4608
+ let seen = this.lastErrorCount.get(key) ?? 0;
4609
+ const afterInput = this.quotaOccurrencesAfterInput(pane, ep);
4610
+ // Only a new echo of our acknowledged input can re-arm a same-count replacement. Old rows before that echo,
4611
+ // an ambiguous/missing marker or a superseded input owner retain the ordinary count-based decision.
4612
+ const newQuotaAfterInput = !!afterInput && afterInput.count > (afterInput.input.reported.get(key) ?? 0);
4613
+ if (newQuotaAfterInput)
4614
+ seen = Math.min(seen, count - 1);
4183
4615
  // #2282: a resumed exhausted429 row is history, not even a new
4184
4616
  // notification/failover incident; so is a resumed codex workspace-limit row
4185
4617
  // (#2844: a wake must not pause again on it). Wait for the first live
@@ -4201,7 +4633,7 @@ export class Daemon extends EventEmitter {
4201
4633
  // the lifecycle, whose usage probe decides (available / reserve / exhausted).
4202
4634
  if (Daemon.isCodexUsageLimitPause(ep)) {
4203
4635
  const ack = this.codexReserveAck;
4204
- if (ack && ack.generation === this.spawnGeneration && count <= ack.count) {
4636
+ if (ack && ack.generation === this.spawnGeneration && count <= ack.count && !newQuotaAfterInput) {
4205
4637
  // The handled incident's lines can scroll out of the capture buffer as
4206
4638
  // the reserve session talks on. Lower the proof (and the occurrence
4207
4639
  // baseline) with them: otherwise `count <= ack.count` would keep
@@ -4242,6 +4674,8 @@ export class Daemon extends EventEmitter {
4242
4674
  continue;
4243
4675
  }
4244
4676
  this.lastErrorCount.set(key, count);
4677
+ if (afterInput)
4678
+ afterInput.input.reported.set(key, Math.max(afterInput.input.reported.get(key) ?? 0, afterInput.count));
4245
4679
  // Kiro's `auto` model picks a concrete model per turn and reroutes around
4246
4680
  // a temporarily unavailable one on its own — telling the user to run
4247
4681
  // /model would ask them to fix something the CLI is already handling.
@@ -4375,6 +4809,14 @@ export class Daemon extends EventEmitter {
4375
4809
  // (Completion paths clear via the guard's onComplete; a cancel with no
4376
4810
  // later idle edge would otherwise leave the marker behind.)
4377
4811
  clearInFlightTurnMarker(this.instanceDir);
4812
+ // #3030: what the person cancelled is not kept for a redelivery (nor reported as not taken).
4813
+ try {
4814
+ for (const entry of this.handoffStore().list())
4815
+ this.handoffStore().remove(entry.id);
4816
+ }
4817
+ catch (err) {
4818
+ this.logger.warn({ err }, "Could not clear queued hand-off records on cancel");
4819
+ }
4378
4820
  this.deliveryEpoch = fleetEpoch === undefined
4379
4821
  ? this.deliveryEpoch + 1
4380
4822
  : Math.max(this.deliveryEpoch, fleetEpoch);
@@ -5803,6 +6245,10 @@ export class Daemon extends EventEmitter {
5803
6245
  if (snapshot.state === "working" && this.recoveryBootSettled
5804
6246
  && this.workingRecoveryInputOwner !== JSON.stringify(this.interactionOwner()))
5805
6247
  this.recoveryNativeWork = true;
6248
+ if (snapshot.state !== "idle")
6249
+ this.instanceIdleSinceMono = null;
6250
+ else if (this.instanceState !== "idle" || this.instanceIdleSinceMono === null)
6251
+ this.instanceIdleSinceMono = performance.now();
5806
6252
  this.instanceState = snapshot.state;
5807
6253
  this.acceptedInstanceSnapshot = { ...snapshot };
5808
6254
  // Reuse an already-captured pane and the backend's pure parser, never capture for the journal.
@@ -5914,7 +6360,7 @@ export class Daemon extends EventEmitter {
5914
6360
  * message can arrive mid-turn and sit queued, and marking at arrival would let
5915
6361
  * the PREVIOUS turn's idle edge consume (and reset) the new turn's state.
5916
6362
  */
5917
- markTurnStarted(meta, deliveredText, deliveryEpoch = this.deliveryEpoch) {
6363
+ markTurnStarted(meta, deliveredText, deliveryEpoch = this.deliveryEpoch, queuedHandoff = false) {
5918
6364
  // Cancel may have interrupted an in-flight paste before its promise settled.
5919
6365
  // Its late success must not re-arm the turn that the user just cancelled.
5920
6366
  if (!this.isDeliveryEpochCurrent(deliveryEpoch))
@@ -5962,7 +6408,9 @@ export class Daemon extends EventEmitter {
5962
6408
  // during the continuation boots clean instead of chaining resumes.
5963
6409
  // #2544: a reply that settled before this arm already answered the person —
5964
6410
  // writing a marker would re-inject a continuation for a finished turn.
5965
- if (!this.nativePaneLifecycle && !meta.resumedContinuationOf && !armed.completionDelivered) {
6411
+ // #3030: a message only queued in the busy CLI has not started a turn: the interrupted turn is still the running one,
6412
+ // and a queued message lost to a restart is the hand-off record's to redeliver, not a continuation's.
6413
+ if (!this.nativePaneLifecycle && !meta.resumedContinuationOf && !armed.completionDelivered && !queuedHandoff) {
5966
6414
  const resumeBackend = this.config.backend ?? this.backend?.binaryName ?? this.runtimeIdentity?.backend;
5967
6415
  const resumeCwd = this.config.working_directory ?? "";
5968
6416
  writeInFlightTurnMarker(this.instanceDir, {
@@ -7367,10 +7815,12 @@ export class Daemon extends EventEmitter {
7367
7815
  // Command name only — never the arguments. See shellCommandLabel.
7368
7816
  if (name === "Bash")
7369
7817
  return `$ ${shellCommandLabel(String(inp.command ?? ""))}`;
7818
+ // The tool name only — never the search pattern: it can be a literal secret someone is looking for, and this label
7819
+ // reaches the channel's progress line.
7370
7820
  if (name === "Glob")
7371
- return `Glob ${inp.pattern ?? ""}`;
7821
+ return "Glob";
7372
7822
  if (name === "Grep")
7373
- return `Grep ${inp.pattern ?? ""}`;
7823
+ return "Grep";
7374
7824
  if (name === "Agent")
7375
7825
  return "Agent (subagent)";
7376
7826
  if (name.startsWith("mcp__agend__"))
@@ -7741,6 +8191,13 @@ export class Daemon extends EventEmitter {
7741
8191
  if (!this.isDeliveryEpochCurrent(deliveryEpoch)) {
7742
8192
  this.logger.info("Pending channel delivery dropped by user cancel");
7743
8193
  this.deferDurableDelivery(meta, "delivery epoch changed while queued");
8194
+ // #3030: a cancel is the person's — a queued redelivery it dropped is not redelivered later.
8195
+ if (meta.handoff_redelivery && !this.deliveryWritesStopping) {
8196
+ try {
8197
+ this.handoffStore().remove(meta.handoff_redelivery);
8198
+ }
8199
+ catch { /* the next CLI judges it */ }
8200
+ }
7744
8201
  return;
7745
8202
  }
7746
8203
  if (this.config.pre_task_command) {
@@ -7751,13 +8208,26 @@ export class Daemon extends EventEmitter {
7751
8208
  // #2800: with this real message, in the same paste — never a paste or turn of its own: after its delivery marker
7752
8209
  // (transcript proof anchors on it), before the message. A person's message with a verified receipt is pasted
7753
8210
  // byte for byte (its proof is the wire's hash), so the notice waits for the next delivery without one.
7754
- const whatsNew = this.pendingWhatsNew && !meta.human_receipt_id ? this.currentWhatsNew(this.pendingWhatsNew) : null;
8211
+ const whatsNew = this.pendingWhatsNew && !meta.human_receipt_id && !meta.handoff_redelivery
8212
+ ? this.currentWhatsNew(this.pendingWhatsNew) : null;
7755
8213
  const pasted = whatsNew ? withWhatsNew(formatted, whatsNew.notice) : formatted;
7756
8214
  const status = channelStatus(meta);
7757
8215
  // A fresh delivery begins a fresh turn — its bubble must not inherit
7758
8216
  // the previous turn's tool list.
7759
8217
  this.resetToolProgress();
7760
8218
  verdict = { reached: false, humanReceipt: this.humanReceiptAttempt(meta, formatted) };
8219
+ // #3030: a hand-off into the CLI's own queue stays on record until a turn takes it (redeliveries included).
8220
+ if (!content.startsWith("/raw ") || meta.from_instance) {
8221
+ const { handoff_redelivery: redeliveryOf, handoff_redeliveries: redeliveries, handoff_holder: _holder, ...kept } = meta;
8222
+ verdict.trackHandoff = { content, meta: kept,
8223
+ ...(redeliveryOf ? { id: redeliveryOf, redeliveries: Number(redeliveries) || 0 } : {}) };
8224
+ }
8225
+ // #3030: a redelivery is written only by the CLI it was issued for, and only while its record still says so —
8226
+ // one queued for a CLI that was replaced meanwhile is that next CLI's reconciliation's to judge again.
8227
+ if (meta.handoff_redelivery && !this.redeliveryStillOurs(meta)) {
8228
+ this.logger.info({ handoff: meta.handoff_redelivery }, "Queued hand-off redelivery dropped: its CLI was replaced before the write");
8229
+ return;
8230
+ }
7761
8231
  const durableAttempt = this.durableDeliveryAttempt(meta, content);
7762
8232
  if (durableAttempt === false) {
7763
8233
  this.deferDurableDelivery(meta, "invalid durable delivery attempt metadata");
@@ -7780,10 +8250,11 @@ export class Daemon extends EventEmitter {
7780
8250
  if (whatsNew && (sent || verdict.paneWriteStarted))
7781
8251
  this.recordWhatsNewSent(whatsNew);
7782
8252
  }
8253
+ this.afterTrackedWrite(meta, verdict, !!sent, deliveryEpoch);
7783
8254
  if (sent) {
7784
8255
  delivered = true;
7785
8256
  this.finishDurableSubmission(durable, verdict);
7786
- this.markTurnStarted(meta, formatted, deliveryEpoch);
8257
+ this.markTurnStarted(meta, formatted, deliveryEpoch, !!verdict.handoff);
7787
8258
  }
7788
8259
  else if (durableAttempt && verdict.paneWriteStarted) {
7789
8260
  this.finishDurableDelivery(durable, "uncertain", `${verdict.phase ?? "post-submit"}:${verdict.proof ?? "unproven"}`, verdict);
@@ -10274,6 +10745,17 @@ export class Daemon extends EventEmitter {
10274
10745
  }
10275
10746
  }
10276
10747
  }
10748
+ // #3030: a hand-off into a busy CLI's own queue is on record before its paste (write-ahead): that queue lives only
10749
+ // in the CLI process, and a stop before a turn takes it would lose it without a trace.
10750
+ if (verdict.trackHandoff && !rawPaste) {
10751
+ await this.recordQueuedHandoff(formatted, handingOffToNativeQueue, verdict, durableAttempt, humanVerificationId);
10752
+ if (stillCurrent && !stillCurrent()) {
10753
+ if (!verdict.trackHandoff.id)
10754
+ this.dropQueuedHandoff(verdict);
10755
+ verdict.fenced = !verdict.durableBeginCommitted;
10756
+ return false;
10757
+ }
10758
+ }
10277
10759
  if (lookBeforePaste) {
10278
10760
  await lookBeforePaste();
10279
10761
  // The look awaited: this attempt is still this write's — the same fence, tmux and launch — or nothing is written.
@@ -10440,6 +10922,7 @@ export class Daemon extends EventEmitter {
10440
10922
  return this.failDelivery(verdict, status, "submit-enter", "pre-enter-deadline");
10441
10923
  return this.failDelivery(verdict, status, "submit-enter", "tmux-send-keys-failed");
10442
10924
  }
10925
+ this.commitPreInputQuotaHistory(pasteBaseline);
10443
10926
  // The proof's whole budget, from the Enter: every capture and dialog probe inside it, a late answer dropped.
10444
10927
  const steerProofDeadline = performance.now() + NATIVE_QUEUE_PASTE_VERIFY_MS + POST_ENTER_PROOF_WINDOW_MS;
10445
10928
  // Kiro's legacy TUI can swallow Enter while it is still processing a large
@@ -10521,8 +11004,9 @@ export class Daemon extends EventEmitter {
10521
11004
  }
10522
11005
  const proof = await this.confirmSubmitted(signature, pasteBaseline);
10523
11006
  if (proof === "submitted") {
10524
- if (status)
10525
- this.emit("message_confirmed", status); // ✅ native queue accepted
11007
+ // ✅ native queue accepted — unless it is on record (#3030): then ✅ waits for the turn that takes it.
11008
+ if (status && !verdict.handoff)
11009
+ this.emit("message_confirmed", status);
10526
11010
  return true;
10527
11011
  }
10528
11012
  if (proof === "unverifiable") {
@@ -10554,8 +11038,8 @@ export class Daemon extends EventEmitter {
10554
11038
  this.logger.warn("Paste reached the pane but could not be verified as submitted — accepting without proof");
10555
11039
  verdict.phase = "best-effort-submission";
10556
11040
  verdict.proof = "unverified";
10557
- if (status)
10558
- this.emit("message_confirmed", status); // ✅ (best-effort)
11041
+ if (status && !verdict.handoff)
11042
+ this.emit("message_confirmed", status); // ✅ (best-effort; on record: when taken, #3030)
10559
11043
  return true;
10560
11044
  }
10561
11045
  // raw_paste has no unique marker and is not allowed to re-paste or
@@ -10570,6 +11054,10 @@ export class Daemon extends EventEmitter {
10570
11054
  // confirmation ladder. "stranded" is the case that used to be a silent
10571
11055
  // ✅ — the text was visible, so the old check called it delivered.
10572
11056
  this.logger.warn({ proof }, "Native-queue paste not confirmed as submitted — retrying via idle-gated delivery");
11057
+ // #3030: what follows is an idle submission (or a failure the caller reports): no longer a queued hand-off.
11058
+ if (verdict.handoff && !verdict.trackHandoff?.id)
11059
+ this.dropQueuedHandoff(verdict);
11060
+ verdict.handoff = undefined;
10573
11061
  if (windowId && this.controlClient && !(await this.controlClient.waitUntilIdle(windowId))) {
10574
11062
  verdict.phase = "native-queue-idle-wait";
10575
11063
  verdict.proof = "idle-wait-failed";
@@ -11161,12 +11649,18 @@ export class Daemon extends EventEmitter {
11161
11649
  async capturePaneEvidence(signature) {
11162
11650
  if (!this.tmux)
11163
11651
  return null;
11652
+ const owner = this.tmux, window = owner.getWindowId?.(), spawn = this.spawnGeneration, fence = this.launchFenceEpoch, launch = this.launchAttempt;
11164
11653
  // Bounded re-probe: a capture that fails here costs the delivery its only
11165
11654
  // "before" picture, and a momentary failure should not decide anything.
11166
11655
  for (let attempt = 1; attempt <= BASELINE_CAPTURE_ATTEMPTS; attempt++) {
11167
11656
  try {
11168
11657
  const pane = await this.tmux.capturePane();
11169
11658
  const evidence = this.paneEvidence(pane, signature);
11659
+ if (owner === this.tmux && window === owner.getWindowId?.() && spawn === this.spawnGeneration && fence === this.launchFenceEpoch && launch === this.launchAttempt) {
11660
+ const counts = this.paneQuotaPatterns().map(ep => ({ key: Daemon.errorPatternKey(ep), count: Daemon.countOccurrences(ep.pattern, pane) }));
11661
+ if (counts.length)
11662
+ evidence.quotaHistory = { spawn, fence, attempt: launch, tmux: owner, window, counts, marker: signature.value, occurrences: evidence.payload };
11663
+ }
11170
11664
  const input = this.inputRegion(pane);
11171
11665
  if (input && agendMessageInInput(input.text)) {
11172
11666
  // Whatever we paste now lands after it, and one Enter submits both as
@@ -11290,6 +11784,10 @@ export class Daemon extends EventEmitter {
11290
11784
  if (!current() || !guard.accept(pane))
11291
11785
  return false;
11292
11786
  baseline = this.paneEvidence(pane, signature);
11787
+ if (native && this.backend?.binaryName === "codex") {
11788
+ const counts = this.paneQuotaPatterns().map(ep => ({ key: Daemon.errorPatternKey(ep), count: Daemon.countOccurrences(ep.pattern, pane) }));
11789
+ baseline.quotaHistory = { spawn: ownerGeneration, fence: ownerFence, attempt: this.launchAttempt, tmux: ownerTmux, window: ownerWindow, counts, marker: signature.value, occurrences: baseline.payload };
11790
+ }
11293
11791
  }
11294
11792
  else {
11295
11793
  baseline = await this.capturePaneEvidence(signature);
@@ -11308,6 +11806,7 @@ export class Daemon extends EventEmitter {
11308
11806
  await new Promise(r => setTimeout(r, NORMAL_ENTER_SETTLE_MS));
11309
11807
  if (!(await this.sendDeliveryEnter(label, current)))
11310
11808
  return false;
11809
+ this.commitPreInputQuotaHistory(baseline);
11311
11810
  let proof = await this.confirmSubmitted(signature, baseline);
11312
11811
  if (current && !current())
11313
11812
  return false;
@@ -12183,6 +12682,9 @@ export class Daemon extends EventEmitter {
12183
12682
  }
12184
12683
  this.cancelCapacityNudge("the instance was stopped, paused or respawned");
12185
12684
  this.lastErrorEpisode = null;
12685
+ this.quotaReplay = null;
12686
+ this.nativeQuotaReplayTaken = false;
12687
+ this.quotaInput = null;
12186
12688
  this.nudgeBaselines = null;
12187
12689
  // A relaunch settles any outstanding quit watch: the CLI came back.
12188
12690
  this.clearQuitRelaunchWatch();
@@ -13052,7 +13554,12 @@ export class Daemon extends EventEmitter {
13052
13554
  || this.startupAborted || this.deliveryWritesStopping || this.runtimeMonitorsFrozen || this.healthCheckPaused)) {
13053
13555
  throw new Error("OOM recovery cancelled: the instance was stopped, paused or replaced while memory was unavailable");
13054
13556
  }
13055
- return this.trySpawnInsideGate(reuseWindow, startupTimeoutMs);
13557
+ return this.trySpawnInsideGate(reuseWindow, startupTimeoutMs).catch(err => {
13558
+ // Includes an in-place binary replacement during asynchronous launch preparation.
13559
+ if (err instanceof KiroCompatibilityError)
13560
+ this.emit("kiro_compatibility_hold", err.message);
13561
+ throw err;
13562
+ });
13056
13563
  };
13057
13564
  const ready = !this.spawnGate ? await enter() : await this.spawnGate.run({
13058
13565
  instanceName: this.name,
@@ -13277,6 +13784,11 @@ export class Daemon extends EventEmitter {
13277
13784
  this.startupAdmission?.();
13278
13785
  const launchFence = this.launchFenceEpoch;
13279
13786
  const backendConfig = this.buildBackendConfig();
13787
+ // A compatibility refusal is not a failed resume: no configuration, pin, history or pane may change.
13788
+ if (this.backend?.assertLaunchSupported) {
13789
+ this.backend.assertLaunchSupported(backendConfig);
13790
+ this.emit("kiro_compatibility_hold", null);
13791
+ }
13280
13792
  // #1633: decided before prev-instructions is first written — its absence is what says "never launched before".
13281
13793
  this.prepareWhatsNew(!existsSync(join(this.instanceDir, "prev-instructions")));
13282
13794
  // Record what this launch writes. #2787: a change is never announced in the pane; the CLI takes the new
@@ -13313,6 +13825,7 @@ export class Daemon extends EventEmitter {
13313
13825
  const agentTokenPath = join(this.instanceDir, "agent.token");
13314
13826
  const agentToken = randomBytes(32).toString("hex");
13315
13827
  const tokenWrite = writeSecretFile(agentTokenPath, agentToken);
13828
+ this.agentCredentialIssuer?.(agentToken);
13316
13829
  if (!tokenWrite.ok) {
13317
13830
  // Do not fail the spawn over it — an instance that cannot start is worse
13318
13831
  // than one whose token is readable. But say so, loudly: the whole point of
@@ -13358,6 +13871,8 @@ export class Daemon extends EventEmitter {
13358
13871
  // Every launched command re-arms the passive-transient check, including a
13359
13872
  // retry inside the same spawn: its load is a new one.
13360
13873
  this.launchAttempt++;
13874
+ await this.prepareQuotaReplayHistory(reuseWindow);
13875
+ this.startupAdmission?.();
13361
13876
  this.interactionObservation.reset(this.interactionOwner());
13362
13877
  this.clearInteractionConfirmation();
13363
13878
  // A launch that cannot paint a passive transient (Codex: a fresh start
@@ -13514,6 +14029,7 @@ export class Daemon extends EventEmitter {
13514
14029
  let lastDialog = null;
13515
14030
  let lastTransient = null;
13516
14031
  let captureFailures = 0;
14032
+ let lastPane = null;
13517
14033
  let attempts = 0;
13518
14034
  // A safety-critical startup choice is one-shot. If the CLI has not
13519
14035
  // repainted after Enter, let the following hold-only entry report it
@@ -13537,11 +14053,13 @@ export class Daemon extends EventEmitter {
13537
14053
  try {
13538
14054
  pane = await this.tmux.capturePane();
13539
14055
  this.startupAdmission?.();
14056
+ lastPane = pane;
13540
14057
  }
13541
14058
  catch (err) {
13542
14059
  this.startupAdmission?.();
13543
14060
  // Transient tmux trouble is not evidence about the CLI. Returning false
13544
14061
  // here would clear the session; retry within the budget instead.
14062
+ lastPane = null;
13545
14063
  captureFailures++;
13546
14064
  this.logger.debug({ err, captureFailures }, "capture-pane failed during the startup dialog scan — retrying");
13547
14065
  // Only a POSITIVE dead pane ends the scan; an unanswerable liveness
@@ -13720,6 +14238,8 @@ export class Daemon extends EventEmitter {
13720
14238
  // matched above, before this check) means the fatal screen is gone,
13721
14239
  // e.g. the user fixed the config and the instance respawned.
13722
14240
  this.fatalStartupBlocked = false;
14241
+ if (owned())
14242
+ this.takeQuotaReplayBaseline(pane);
13723
14243
  return true;
13724
14244
  }
13725
14245
  await sleep();
@@ -13758,6 +14278,8 @@ export class Daemon extends EventEmitter {
13758
14278
  this.logger.warn({ attempts, budgetMs, captureFailures }, "Startup scan exhausted without a ready prompt or a known dialog — assuming ready (unknown CLI screen)");
13759
14279
  }
13760
14280
  this.startupAdmission?.();
14281
+ if (owned() && lastPane !== null && !lastDialog && !lastTransient)
14282
+ this.takeQuotaReplayBaseline(lastPane);
13761
14283
  return true;
13762
14284
  }
13763
14285
  /**