@songsid/agend 2.2.0-alpha.2 → 2.2.0-alpha.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (239) hide show
  1. package/README.md +4 -4
  2. package/README.zh-TW.md +4 -4
  3. package/dist/agent-endpoint.d.ts +4 -1
  4. package/dist/agent-endpoint.js +14 -2
  5. package/dist/agent-endpoint.js.map +1 -1
  6. package/dist/atomic-write.d.ts +21 -0
  7. package/dist/atomic-write.js +65 -0
  8. package/dist/atomic-write.js.map +1 -0
  9. package/dist/auth-api.js +2 -0
  10. package/dist/auth-api.js.map +1 -1
  11. package/dist/backend/codex.d.ts +7 -0
  12. package/dist/backend/codex.js +7 -0
  13. package/dist/backend/codex.js.map +1 -1
  14. package/dist/backend/muse.d.ts +7 -0
  15. package/dist/backend/muse.js +7 -0
  16. package/dist/backend/muse.js.map +1 -1
  17. package/dist/backend/types.d.ts +6 -0
  18. package/dist/backend/types.js.map +1 -1
  19. package/dist/binary-probe.d.ts +80 -0
  20. package/dist/binary-probe.js +182 -0
  21. package/dist/binary-probe.js.map +1 -0
  22. package/dist/cache-service.d.ts +17 -1
  23. package/dist/cache-service.js +39 -4
  24. package/dist/cache-service.js.map +1 -1
  25. package/dist/channel/adapters/discord.d.ts +5 -1
  26. package/dist/channel/adapters/discord.js +56 -11
  27. package/dist/channel/adapters/discord.js.map +1 -1
  28. package/dist/channel/adapters/telegram.d.ts +38 -1
  29. package/dist/channel/adapters/telegram.js +82 -0
  30. package/dist/channel/adapters/telegram.js.map +1 -1
  31. package/dist/channel/mcp-tools.js +1 -1
  32. package/dist/channel/mcp-tools.js.map +1 -1
  33. package/dist/channel/tool-router.d.ts +8 -1
  34. package/dist/channel/tool-router.js +4 -2
  35. package/dist/channel/tool-router.js.map +1 -1
  36. package/dist/channel/types.d.ts +21 -0
  37. package/dist/cli.js +133 -38
  38. package/dist/cli.js.map +1 -1
  39. package/dist/connection-secrets.d.ts +5 -0
  40. package/dist/connection-secrets.js.map +1 -1
  41. package/dist/cpu-profile.js +50 -0
  42. package/dist/cpu-profile.js.map +1 -1
  43. package/dist/daemon.d.ts +12 -0
  44. package/dist/daemon.js +166 -26
  45. package/dist/daemon.js.map +1 -1
  46. package/dist/delivery-outbox.d.ts +1 -0
  47. package/dist/delivery-outbox.js +12 -0
  48. package/dist/delivery-outbox.js.map +1 -1
  49. package/dist/discord-permissions.d.ts +33 -0
  50. package/dist/discord-permissions.js +42 -0
  51. package/dist/discord-permissions.js.map +1 -0
  52. package/dist/env-file.d.ts +11 -0
  53. package/dist/env-file.js +27 -0
  54. package/dist/env-file.js.map +1 -0
  55. package/dist/fleet-context.d.ts +5 -0
  56. package/dist/fleet-context.js.map +1 -1
  57. package/dist/fleet-level-config.d.ts +8 -1
  58. package/dist/fleet-level-config.js +31 -0
  59. package/dist/fleet-level-config.js.map +1 -1
  60. package/dist/fleet-manager.d.ts +76 -7
  61. package/dist/fleet-manager.js +599 -127
  62. package/dist/fleet-manager.js.map +1 -1
  63. package/dist/fleet-stop-budget.d.ts +22 -0
  64. package/dist/fleet-stop-budget.js +95 -0
  65. package/dist/fleet-stop-budget.js.map +1 -0
  66. package/dist/kiro-transcript-lane.d.ts +8 -4
  67. package/dist/kiro-transcript-lane.js +66 -44
  68. package/dist/kiro-transcript-lane.js.map +1 -1
  69. package/dist/locale.js +82 -0
  70. package/dist/locale.js.map +1 -1
  71. package/dist/next-steps.d.ts +5 -0
  72. package/dist/next-steps.js +26 -0
  73. package/dist/next-steps.js.map +1 -0
  74. package/dist/outbound-handlers.js +8 -0
  75. package/dist/outbound-handlers.js.map +1 -1
  76. package/dist/outbound-schemas.d.ts +4 -0
  77. package/dist/outbound-schemas.js +6 -1
  78. package/dist/outbound-schemas.js.map +1 -1
  79. package/dist/outbox-open-error.d.ts +7 -0
  80. package/dist/outbox-open-error.js +15 -0
  81. package/dist/outbox-open-error.js.map +1 -0
  82. package/dist/pane-context-cache.d.ts +25 -0
  83. package/dist/pane-context-cache.js +73 -0
  84. package/dist/pane-context-cache.js.map +1 -0
  85. package/dist/paths.d.ts +0 -7
  86. package/dist/paths.js +8 -2
  87. package/dist/paths.js.map +1 -1
  88. package/dist/provider-probe.d.ts +15 -0
  89. package/dist/provider-probe.js +20 -0
  90. package/dist/provider-probe.js.map +1 -1
  91. package/dist/public-link-progress.d.ts +73 -0
  92. package/dist/public-link-progress.js +190 -0
  93. package/dist/public-link-progress.js.map +1 -0
  94. package/dist/public-web-gateway.js +1 -1
  95. package/dist/public-web-gateway.js.map +1 -1
  96. package/dist/public-web-link.d.ts +6 -1
  97. package/dist/public-web-link.js +87 -15
  98. package/dist/public-web-link.js.map +1 -1
  99. package/dist/quickstart-api.d.ts +93 -20
  100. package/dist/quickstart-api.js +194 -62
  101. package/dist/quickstart-api.js.map +1 -1
  102. package/dist/quickstart.d.ts +15 -0
  103. package/dist/quickstart.js +100 -29
  104. package/dist/quickstart.js.map +1 -1
  105. package/dist/reply-buttons-controller.d.ts +98 -0
  106. package/dist/reply-buttons-controller.js +174 -0
  107. package/dist/reply-buttons-controller.js.map +1 -0
  108. package/dist/reply-buttons.d.ts +113 -0
  109. package/dist/reply-buttons.js +208 -0
  110. package/dist/reply-buttons.js.map +1 -0
  111. package/dist/reply-dedup.js +3 -1
  112. package/dist/reply-dedup.js.map +1 -1
  113. package/dist/restart-guard.d.ts +1 -0
  114. package/dist/restart-guard.js +8 -3
  115. package/dist/restart-guard.js.map +1 -1
  116. package/dist/service-activation.d.ts +15 -2
  117. package/dist/service-activation.js +81 -4
  118. package/dist/service-activation.js.map +1 -1
  119. package/dist/service-installer.js +19 -1
  120. package/dist/service-installer.js.map +1 -1
  121. package/dist/settings-api.js +53 -12
  122. package/dist/settings-api.js.map +1 -1
  123. package/dist/settings-authority.d.ts +11 -0
  124. package/dist/settings-authority.js +128 -0
  125. package/dist/settings-authority.js.map +1 -0
  126. package/dist/settings-change.d.ts +5 -0
  127. package/dist/settings-change.js +4 -3
  128. package/dist/settings-change.js.map +1 -1
  129. package/dist/settings-confirmation.d.ts +3 -0
  130. package/dist/settings-confirmation.js +7 -1
  131. package/dist/settings-confirmation.js.map +1 -1
  132. package/dist/settings-effect.js +19 -7
  133. package/dist/settings-effect.js.map +1 -1
  134. package/dist/settings-http-confirmation.js +1 -1
  135. package/dist/settings-http-confirmation.js.map +1 -1
  136. package/dist/settings-redaction.d.ts +18 -0
  137. package/dist/settings-redaction.js +58 -0
  138. package/dist/settings-redaction.js.map +1 -0
  139. package/dist/setup-form.d.ts +9 -1
  140. package/dist/setup-form.js +25 -1
  141. package/dist/setup-form.js.map +1 -1
  142. package/dist/setup-host.js +13 -3
  143. package/dist/setup-host.js.map +1 -1
  144. package/dist/setup-wizard.js +26 -19
  145. package/dist/setup-wizard.js.map +1 -1
  146. package/dist/systemd-runtime.d.ts +15 -0
  147. package/dist/systemd-runtime.js +41 -0
  148. package/dist/systemd-runtime.js.map +1 -0
  149. package/dist/tmux-control.d.ts +22 -0
  150. package/dist/tmux-control.js +82 -17
  151. package/dist/tmux-control.js.map +1 -1
  152. package/dist/token-env-name.d.ts +37 -0
  153. package/dist/token-env-name.js +93 -0
  154. package/dist/token-env-name.js.map +1 -0
  155. package/dist/tool-permissions.js +5 -3
  156. package/dist/tool-permissions.js.map +1 -1
  157. package/dist/topic-commands.d.ts +7 -16
  158. package/dist/topic-commands.js +45 -83
  159. package/dist/topic-commands.js.map +1 -1
  160. package/dist/transcript-monitor.js +3 -0
  161. package/dist/transcript-monitor.js.map +1 -1
  162. package/dist/transcript-sources.d.ts +68 -0
  163. package/dist/transcript-sources.js +336 -29
  164. package/dist/transcript-sources.js.map +1 -1
  165. package/dist/transcript-turns.d.ts +39 -0
  166. package/dist/transcript-turns.js +58 -0
  167. package/dist/transcript-turns.js.map +1 -0
  168. package/dist/tunnel/cloudflared-install.d.ts +18 -0
  169. package/dist/tunnel/cloudflared-install.js +15 -1
  170. package/dist/tunnel/cloudflared-install.js.map +1 -1
  171. package/dist/turn-reply-guard.d.ts +3 -0
  172. package/dist/turn-reply-guard.js.map +1 -1
  173. package/dist/ui/chat-render.js +32 -6
  174. package/dist/ui/chat-store.js +21 -1
  175. package/dist/ui/chat-strings.js +8 -0
  176. package/dist/ui/chat-thread.js +109 -52
  177. package/dist/ui/first-run.js +64 -0
  178. package/dist/ui/html-attachment.js +26 -0
  179. package/dist/ui/panel-chat.js +13 -5
  180. package/dist/ui/panel-fleet.js +5 -5
  181. package/dist/ui/panel-settings.js +18 -8
  182. package/dist/ui/preview-panel.js +38 -3
  183. package/dist/ui/settings-apply.js +3 -1
  184. package/dist/ui/settings-dialogs.js +95 -25
  185. package/dist/ui/settings-discord.js +130 -0
  186. package/dist/ui/settings-model.js +21 -0
  187. package/dist/ui/settings-strings.js +46 -6
  188. package/dist/ui/settings-token.js +54 -0
  189. package/dist/ui/settings-wizard.js +63 -29
  190. package/dist/ui/shared/app-shell.js +19 -33
  191. package/dist/ui/shared/app-store.js +5 -3
  192. package/dist/ui/shared/app-stream.js +2 -1
  193. package/dist/ui/shared/app.css +34 -2
  194. package/dist/ui/shared/app.js +2 -1
  195. package/dist/ui/shared/instance-nav.js +310 -0
  196. package/dist/ui/shared/panel-view.js +12 -190
  197. package/dist/ui/shared/view-roster-store.js +5 -0
  198. package/dist/ui/shared/view-strings.js +12 -0
  199. package/dist/update-dispatch.d.ts +1 -1
  200. package/dist/update-dispatch.js +1 -1
  201. package/dist/update-install.d.ts +15 -3
  202. package/dist/update-install.js +41 -13
  203. package/dist/update-install.js.map +1 -1
  204. package/dist/update-launch.d.ts +22 -0
  205. package/dist/update-launch.js +106 -0
  206. package/dist/update-launch.js.map +1 -0
  207. package/dist/update-marker.js +3 -8
  208. package/dist/update-marker.js.map +1 -1
  209. package/dist/usage/format-rich.js +7 -1
  210. package/dist/usage/format-rich.js.map +1 -1
  211. package/dist/usage/i18n-keys.d.ts +1 -1
  212. package/dist/usage/i18n-keys.js +1 -1
  213. package/dist/usage/i18n-keys.js.map +1 -1
  214. package/dist/usage/providers.d.ts +4 -0
  215. package/dist/usage/providers.js +2 -1
  216. package/dist/usage/providers.js.map +1 -1
  217. package/dist/usage/usage-api.js +48 -2
  218. package/dist/usage/usage-api.js.map +1 -1
  219. package/dist/view-api.d.ts +40 -0
  220. package/dist/view-api.js +28 -10
  221. package/dist/view-api.js.map +1 -1
  222. package/dist/web-api.d.ts +8 -0
  223. package/dist/web-api.js +50 -16
  224. package/dist/web-api.js.map +1 -1
  225. package/dist/web-auth.d.ts +8 -0
  226. package/dist/web-auth.js +34 -8
  227. package/dist/web-auth.js.map +1 -1
  228. package/dist/web-chat-history.d.ts +21 -0
  229. package/dist/web-chat-history.js +44 -0
  230. package/dist/web-chat-history.js.map +1 -1
  231. package/dist/web-host-guard.d.ts +18 -2
  232. package/dist/web-host-guard.js +30 -5
  233. package/dist/web-host-guard.js.map +1 -1
  234. package/dist/web-session.d.ts +7 -1
  235. package/dist/web-session.js +23 -2
  236. package/dist/web-session.js.map +1 -1
  237. package/launcher/postinstall.cjs +8 -4
  238. package/package.json +1 -1
  239. package/templates/systemd.service.ejs +3 -3
@@ -39,6 +39,11 @@ export interface ConnectionMetadata {
39
39
  group_id: string | number | null;
40
40
  general_channel_id?: string | null;
41
41
  status: string;
42
+ /**
43
+ * A known cause the connection is down: "missing_intent" — Message Content is off in the developer portal (#1519 P3);
44
+ * "rejected" — the platform refused the token (P6).
45
+ */
46
+ problem?: "missing_intent" | "rejected";
42
47
  identity?: {
43
48
  id: string | null;
44
49
  username: string | null;
@@ -1 +1 @@
1
- {"version":3,"file":"connection-secrets.js","sourceRoot":"","sources":["../src/connection-secrets.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,sBAAsB,EAAE,MAAM,kCAAkC,CAAC;AAC1E,OAAO,EAAE,UAAU,EAAE,WAAW,EAAE,MAAM,aAAa,CAAC;AAEtD,OAAO,EAAE,mBAAmB,EAAE,MAAM,qBAAqB,CAAC;AAE1D,MAAM,CAAC,MAAM,uBAAuB,GAAG,CAAC,GAAG,MAAM,CAAC;AAClD,MAAM,CAAC,MAAM,mBAAmB,GAAG;IACjC,UAAU,EAAE,UAAU,EAAE,SAAS,EAAE,kBAAkB,EAAE,UAAU,EAAE,kBAAkB,EAAE,aAAa,EAAE,iBAAiB;CAC/G,CAAC;AAuGX,MAAM,UAAU,qBAAqB,CAAC,GAAoB;IACxD,MAAM,QAAQ,GAAG,sBAAsB,CAAC,GAAG,CAAC,CAAC;IAAC,IAAI,QAAQ;QAAE,OAAO,QAAQ,CAAC;IAC5E,6EAA6E;IAC7E,qEAAqE;IACrE,MAAM,MAAM,GAAG,OAAO,GAAG,CAAC,OAAO,CAAC,MAAM,KAAK,QAAQ,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC;IAChF,MAAM,MAAM,GAAG,OAAO,GAAG,CAAC,OAAO,CAAC,eAAe,CAAC,KAAK,QAAQ,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,eAAe,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC;IACpG,OAAO,UAAU,CAAC,QAAQ,CAAC,CAAC,MAAM,CAAC,wBAAwB,MAAM,KAAK,MAAM,EAAE,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;AAChG,CAAC;AAED,MAAM,UAAU,QAAQ,CAAC,MAAc;IACrC,OAAO,GAAG,MAAM,IAAI,WAAW,CAAC,EAAE,CAAC,CAAC,QAAQ,CAAC,WAAW,CAAC,EAAE,CAAC;AAC9D,CAAC;AAED,MAAM,UAAU,eAAe,CAAC,KAAc,EAAE,MAAe,EAAE,oBAAuC,EAAE;IACxG,IAAI,OAAO,GAAG,mBAAmB,CAAC,KAAK,EAAE,MAAM,CAAC,CAAC;IACjD,KAAK,MAAM,KAAK,IAAI,iBAAiB,EAAE,CAAC;QACtC,IAAI,KAAK;YAAE,OAAO,GAAG,mBAAmB,CAAC,OAAO,EAAE,KAAK,CAAC,CAAC;IAC3D,CAAC;IACD,OAAO,OAAO,CAAC,OAAO,CAAC,SAAS,EAAE,GAAG,CAAC,CAAC,KAAK,CAAC,CAAC,EAAE,GAAG,CAAC,CAAC;AACvD,CAAC"}
1
+ {"version":3,"file":"connection-secrets.js","sourceRoot":"","sources":["../src/connection-secrets.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,sBAAsB,EAAE,MAAM,kCAAkC,CAAC;AAC1E,OAAO,EAAE,UAAU,EAAE,WAAW,EAAE,MAAM,aAAa,CAAC;AAEtD,OAAO,EAAE,mBAAmB,EAAE,MAAM,qBAAqB,CAAC;AAE1D,MAAM,CAAC,MAAM,uBAAuB,GAAG,CAAC,GAAG,MAAM,CAAC;AAClD,MAAM,CAAC,MAAM,mBAAmB,GAAG;IACjC,UAAU,EAAE,UAAU,EAAE,SAAS,EAAE,kBAAkB,EAAE,UAAU,EAAE,kBAAkB,EAAE,aAAa,EAAE,iBAAiB;CAC/G,CAAC;AA4GX,MAAM,UAAU,qBAAqB,CAAC,GAAoB;IACxD,MAAM,QAAQ,GAAG,sBAAsB,CAAC,GAAG,CAAC,CAAC;IAAC,IAAI,QAAQ;QAAE,OAAO,QAAQ,CAAC;IAC5E,6EAA6E;IAC7E,qEAAqE;IACrE,MAAM,MAAM,GAAG,OAAO,GAAG,CAAC,OAAO,CAAC,MAAM,KAAK,QAAQ,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC;IAChF,MAAM,MAAM,GAAG,OAAO,GAAG,CAAC,OAAO,CAAC,eAAe,CAAC,KAAK,QAAQ,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,eAAe,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC;IACpG,OAAO,UAAU,CAAC,QAAQ,CAAC,CAAC,MAAM,CAAC,wBAAwB,MAAM,KAAK,MAAM,EAAE,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;AAChG,CAAC;AAED,MAAM,UAAU,QAAQ,CAAC,MAAc;IACrC,OAAO,GAAG,MAAM,IAAI,WAAW,CAAC,EAAE,CAAC,CAAC,QAAQ,CAAC,WAAW,CAAC,EAAE,CAAC;AAC9D,CAAC;AAED,MAAM,UAAU,eAAe,CAAC,KAAc,EAAE,MAAe,EAAE,oBAAuC,EAAE;IACxG,IAAI,OAAO,GAAG,mBAAmB,CAAC,KAAK,EAAE,MAAM,CAAC,CAAC;IACjD,KAAK,MAAM,KAAK,IAAI,iBAAiB,EAAE,CAAC;QACtC,IAAI,KAAK;YAAE,OAAO,GAAG,mBAAmB,CAAC,OAAO,EAAE,KAAK,CAAC,CAAC;IAC3D,CAAC;IACD,OAAO,OAAO,CAAC,OAAO,CAAC,SAAS,EAAE,GAAG,CAAC,CAAC,KAAK,CAAC,CAAC,EAAE,GAAG,CAAC,CAAC;AACvD,CAAC"}
@@ -28,6 +28,56 @@ export function cpuProfileSeconds(env) {
28
28
  /** Bounded artifacts, not a bound on V8's native recording memory or JSON allocation. */
29
29
  export async function saveCpuProfile(dataDir, profile, signal) {
30
30
  signal?.throwIfAborted();
31
+ // Guard the event loop: a V8 CPU profile with many nodes/samples can exceed
32
+ // 20 MiB when serialised. We estimate from the structural data before
33
+ // allocating the full string, so an oversize profile is rejected without
34
+ // blocking the event loop for O(n) stringify time.
35
+ //
36
+ // Estimate accounts for variable-length fields:
37
+ // - callFrame.url (the dominant contributor — can be 300+ chars each)
38
+ // - callFrame.functionName (typically short, budget 50 bytes)
39
+ // - fixed overhead per node: id, hitCount, children array refs (~100 bytes)
40
+ // - timeDeltas: one number per sample (~8 bytes)
41
+ // A node without a long URL is estimated at ~200 bytes fixed; URL bytes are
42
+ // counted separately per-node so a profile with many long URLs is caught early.
43
+ const p = profile;
44
+ const nodes = Array.isArray(p?.nodes) ? p.nodes : [];
45
+ const samples = Array.isArray(p?.samples) ? p.samples : [];
46
+ const timeDeltas = Array.isArray(p?.timeDeltas) ? p.timeDeltas : [];
47
+ const NODE_FIXED = 100; // id, hitCount, children, JSON punctuation
48
+ const FRAME_FIXED = 50; // functionName (short), scriptId, lineNumber, columnNumber
49
+ let estimatedBytes = timeDeltas.length * 8; // timeDeltas
50
+ estimatedBytes += samples.length * 8; // samples array
51
+ for (const node of nodes) {
52
+ const frame = (node.callFrame ?? {});
53
+ // JSON.stringify the individual string fields for exact escaped+UTF-8 byte
54
+ // count. BMP CJK chars: 1 UTF-16 unit but 3 UTF-8 bytes (JSON keeps them
55
+ // unescaped). Backslash paths: each \\ → 2 JSON bytes.
56
+ const urlBytes = typeof frame.url === "string"
57
+ ? Buffer.byteLength(JSON.stringify(frame.url), "utf8") - 2 : 0;
58
+ const fnBytes = typeof frame.functionName === "string"
59
+ ? Buffer.byteLength(JSON.stringify(frame.functionName), "utf8") - 2 : 0;
60
+ // Variable arrays per node: positionTicks and children.
61
+ // Do NOT call JSON.stringify on these arrays — that would allocate the very
62
+ // large string the guard is meant to prevent. Instead use a conservative
63
+ // per-record byte estimate:
64
+ // positionTicks: each {line,ticks} entry ≤ 35 JSON bytes in the worst case
65
+ // (e.g. '{"line":999999,"ticks":9999}' = 29 bytes; 35 gives headroom).
66
+ // children: each node-id integer ≤ 8 JSON bytes.
67
+ const MAX_BYTES_PER_TICK = 35;
68
+ const posTicksBytes = Array.isArray(node.positionTicks)
69
+ ? node.positionTicks.length * MAX_BYTES_PER_TICK : 0;
70
+ const childrenBytes = Array.isArray(node.children)
71
+ ? node.children.length * 8 : 0;
72
+ estimatedBytes += NODE_FIXED + FRAME_FIXED + urlBytes + fnBytes + posTicksBytes + childrenBytes;
73
+ // Early exit: avoid accumulating through every node if already over cap.
74
+ if (estimatedBytes > CPU_PROFILE_MAX_BYTES) {
75
+ throw new Error(`CPU profile is too large to save (estimated ≥${Math.round(estimatedBytes / 1_048_576)} MiB, cap is 20 MiB); discarded`);
76
+ }
77
+ }
78
+ if (estimatedBytes > CPU_PROFILE_MAX_BYTES) {
79
+ throw new Error(`CPU profile is too large to save (estimated ≥${Math.round(estimatedBytes / 1_048_576)} MiB, cap is 20 MiB); discarded`);
80
+ }
31
81
  const json = JSON.stringify(profile);
32
82
  if (json === undefined || Buffer.byteLength(json) > CPU_PROFILE_MAX_BYTES)
33
83
  throw new Error("CPU profile exceeds the 20 MiB artifact cap; discarded");
@@ -1 +1 @@
1
- {"version":3,"file":"cpu-profile.js","sourceRoot":"","sources":["../src/cpu-profile.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"cpu-profile.js","sourceRoot":"","sources":["../src/cpu-profile.ts"],"names":[],"mappings":"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"}
package/dist/daemon.d.ts CHANGED
@@ -1,3 +1,4 @@
1
+ import type { PaneContextSource } from "./pane-context-cache.js";
1
2
  import { EventEmitter } from "node:events";
2
3
  import type { InstanceConfig, RotationSnapshot } from "./types.js";
3
4
  import { type Logger } from "./logger.js";
@@ -589,6 +590,10 @@ export declare class Daemon extends EventEmitter {
589
590
  private sessionCheckpointWarningEmitted;
590
591
  private statePollInFlight;
591
592
  private turnReplyGuard;
593
+ /** #1510: turn boundaries from the CLI's transcript, for a backend whose guard reads its turn end there. */
594
+ private transcriptTurns;
595
+ /** #1510: since when (monotonic) this generation has been held as running in the transcript. */
596
+ private transcriptRunningSince;
592
597
  /** Prevent a visible stale XML fragment from being recovered on later turns. */
593
598
  private lastMalformedToolCallSignature;
594
599
  private proxyReplySeq;
@@ -1199,6 +1204,8 @@ export declare class Daemon extends EventEmitter {
1199
1204
  */
1200
1205
  private cancelQuitConfirmation;
1201
1206
  stop(): Promise<void>;
1207
+ /** Context refresh uses the already-bound manager; no name-based child or backend probe. */
1208
+ getPaneContextSource(): PaneContextSource | null;
1202
1209
  getHangDetector(): HangDetector | null;
1203
1210
  getInstanceState(): InstanceState | "paused";
1204
1211
  getInstanceStateSnapshot(): InstanceStateSnapshot;
@@ -1285,6 +1292,11 @@ export declare class Daemon extends EventEmitter {
1285
1292
  private maybeConfirmReplyGuardIdle;
1286
1293
  private maybeProxyReplyOnTurnEnd;
1287
1294
  private isClaudeCodeBackend;
1295
+ /**
1296
+ * This launch's transcript monitor. #1510: its turn boundaries feed the reply guard's ledger, which starts empty
1297
+ * with it — a new monitor re-baselines at the transcript's end, so nothing the old one read can be attributed.
1298
+ */
1299
+ private buildTranscriptMonitor;
1288
1300
  private replyCompletionGuardEnabled;
1289
1301
  private startReplyRecovery;
1290
1302
  private reportReplyDropWithoutRetry;
package/dist/daemon.js CHANGED
@@ -11,6 +11,7 @@ import { clearPausedMarker, writePausedMarker } from "./pause-marker.js";
11
11
  import { TmuxManager, resolveTmuxLogicalSize } from "./tmux-manager.js";
12
12
  import { TranscriptMonitor } from "./transcript-monitor.js";
13
13
  import { createTranscriptSource } from "./transcript-sources.js";
14
+ import { TranscriptTurnLedger } from "./transcript-turns.js";
14
15
  import { credentialProfileStoreHome, resolveCredentialProfile } from "./backend/credential-profile.js";
15
16
  import { resolveToolSet } from "./tool-permissions.js";
16
17
  import { getAgendHome } from "./paths.js";
@@ -25,6 +26,7 @@ import { MessageBus } from "./channel/message-bus.js";
25
26
  import { shellQuote, UnsupportedCliError } from "./backend/types.js";
26
27
  import { getTmuxSession } from "./config.js";
27
28
  import { routeToolCall } from "./channel/tool-router.js";
29
+ import { parseReplyButtons, replyButtonsFallbackText } from "./reply-buttons.js";
28
30
  import { HangDetector } from "./hang-detector.js";
29
31
  import { writeSecretFile } from "./secret-file.js";
30
32
  import { PaneWriteLock } from "./pane-write-lock.js";
@@ -69,6 +71,12 @@ const REPLY_DROP_WARNING_COOLDOWN_MS = 5 * 60_000;
69
71
  * backstop is delayed by at most this window, never disabled.
70
72
  */
71
73
  const REPLY_GUARD_IDLE_CONFIRM_MS = 60_000;
74
+ /**
75
+ * #1510: how long an idle pane may be held because the transcript still shows the turn running. A turn whose end is
76
+ * never written (the CLI killed, the rollout replaced) would otherwise be re-checked for ever; past this it stands
77
+ * down like a turn the transcript cannot place — never a recovery.
78
+ */
79
+ const TRANSCRIPT_RUNNING_HOLD_MAX_MS = 30 * 60_000;
72
80
  const REPLY_RECOVERY_PROMPT = "[system:reply-required] The previous human-facing turn ended without a successfully delivered reply. Do not redo the work. React with an emoji or use the reply tool exactly once now to send the user a concise conclusion. If no substantive answer is needed, a brief react is sufficient. If you already replied to this message, do nothing. Do not reply to this system instruction except through the react or reply tool.";
73
81
  /** Point a resumed CLI at its one backend-native instruction source. */
74
82
  /** The outbox evidence for a delivery the CLI's transcript shows taken (#758; #1201 absorbed). */
@@ -644,6 +652,8 @@ const CONFIRM_BUSY_POLL_MS = 200;
644
652
  * hold the pane write lock along with it.
645
653
  */
646
654
  const CONFIRM_BUSY_MAX_WAIT_MS = 10_000;
655
+ /** How much longer a confirmation waits while the control client is blind (a drained read; its limit is 10 s). */
656
+ const CONFIRM_BUSY_BLIND_EXTRA_MS = 12_000;
647
657
  /**
648
658
  * How long a delivery waits for an in-flight spawn. Comfortably past the default
649
659
  * 25s startup timeout plus dialog dismissal; past it we fall back to the old
@@ -1225,6 +1235,10 @@ export class Daemon extends EventEmitter {
1225
1235
  // It also supplies the older dead-MCP/malformed-call recovery paths, so those
1226
1236
  // paths cannot disagree about whether the turn already spoke to the channel.
1227
1237
  turnReplyGuard = new TurnReplyGuard();
1238
+ /** #1510: turn boundaries from the CLI's transcript, for a backend whose guard reads its turn end there. */
1239
+ transcriptTurns = new TranscriptTurnLedger();
1240
+ /** #1510: since when (monotonic) this generation has been held as running in the transcript. */
1241
+ transcriptRunningSince = null;
1228
1242
  /** Prevent a visible stale XML fragment from being recovered on later turns. */
1229
1243
  lastMalformedToolCallSignature;
1230
1244
  proxyReplySeq = 0;
@@ -2178,7 +2192,7 @@ export class Daemon extends EventEmitter {
2178
2192
  // (statusline transcript); codex/kiro/opencode read their CLI's own
2179
2193
  // conversation store via a pluggable source. Backends with no known
2180
2194
  // source stay inert exactly as before.
2181
- this.transcriptMonitor = new TranscriptMonitor(this.instanceDir, this.logger, createTranscriptSource(this.config.backend ?? "claude-code", this.config.working_directory, this.credentialProfileStore()));
2195
+ this.transcriptMonitor = this.buildTranscriptMonitor(createTranscriptSource(this.config.backend ?? "claude-code", this.config.working_directory, this.credentialProfileStore()));
2182
2196
  const transcriptMonitor = this.transcriptMonitor;
2183
2197
  const transcriptFence = this.launchFenceEpoch;
2184
2198
  // Baseline in the isolate before this daemon accepts new work. A
@@ -4113,6 +4127,23 @@ export class Daemon extends EventEmitter {
4113
4127
  this.logger.debug({ err: e }, "Failed to remove PID file");
4114
4128
  }
4115
4129
  }
4130
+ /** Context refresh uses the already-bound manager; no name-based child or backend probe. */
4131
+ getPaneContextSource() {
4132
+ const tmux = this.tmux;
4133
+ const control = this.controlClient;
4134
+ if (!tmux || !control || this.deliveryWritesStopping)
4135
+ return null;
4136
+ const owner = this.interactionOwner();
4137
+ const epoch = this.deliveryEpoch;
4138
+ const isCurrent = () => {
4139
+ const now = this.interactionOwner();
4140
+ return !this.deliveryWritesStopping && this.controlClient === control && this.tmux === tmux && this.deliveryEpoch === epoch
4141
+ && now.bootId === owner.bootId && now.spawnGeneration === owner.spawnGeneration
4142
+ && now.launchAttempt === owner.launchAttempt && now.launchFenceEpoch === owner.launchFenceEpoch;
4143
+ };
4144
+ return { owner: tmux, generation: JSON.stringify([owner.bootId, owner.spawnGeneration, owner.launchAttempt, owner.launchFenceEpoch, epoch]),
4145
+ isCurrent, capture: () => isCurrent() ? tmux.capturePaneWithHistory(60, 2_000) : Promise.reject(new Error("Pane context owner retired")) };
4146
+ }
4116
4147
  getHangDetector() {
4117
4148
  return this.hangDetector;
4118
4149
  }
@@ -4651,11 +4682,14 @@ export class Daemon extends EventEmitter {
4651
4682
  // chat_id) does not update lastChatId, so its proxy reply would land in
4652
4683
  // whatever USER topic spoke to this instance last — the wrong audience for
4653
4684
  // a task result, and a stale one (sol's review of #515).
4654
- if (meta.from_instance || !meta.chat_id)
4685
+ // A web message on a fleet with no chat platform has no chat_id (its reply goes to the web chat through the fleet's
4686
+ // web-only sink), but it is a person waiting for an answer all the same: the guard arms for it (alpha.2).
4687
+ if (meta.from_instance || (!meta.chat_id && meta.source !== "web"))
4655
4688
  return;
4656
4689
  // The last non-empty line of what we pasted: everything on screen after it
4657
4690
  // is the agent's own output.
4658
4691
  const inboundMarker = deliveredText.split(/\r?\n/).map(l => l.trim()).filter(Boolean).pop();
4692
+ const deliveredAt = Date.now();
4659
4693
  // #1241 P2-1: carry pre-arm work evidence over the arm, bounded by this
4660
4694
  // delivery's ingress — output the paste produced before it confirmed.
4661
4695
  this.turnReplyGuard.arm({
@@ -4665,6 +4699,8 @@ export class Daemon extends EventEmitter {
4665
4699
  messageId: meta.message_id || undefined,
4666
4700
  correlationId: meta.correlation_id || undefined,
4667
4701
  inboundMarker,
4702
+ deliveredText,
4703
+ deliveredAt,
4668
4704
  }, this.pendingWork.lastInboundTimestamp());
4669
4705
  // #1209: persist the in-flight turn with a seam checkpoint. A marker
4670
4706
  // that survives a restart is an interrupted turn by construction —
@@ -4953,6 +4989,34 @@ export class Daemon extends EventEmitter {
4953
4989
  this.clearReplyGuardConfirm();
4954
4990
  return;
4955
4991
  }
4992
+ // #1510: a backend whose turn end is read from its own transcript (codex) must show it there too: the turn that
4993
+ // took this delivery ended and nothing started since. Anything less never starts a recovery.
4994
+ if (this.backend?.turnEndFromTranscript === true) {
4995
+ let verdict = this.transcriptTurns.verdict(turn.target.deliveredText, turn.target.deliveredAt ?? 0);
4996
+ if (verdict === "running") {
4997
+ if (this.transcriptRunningSince?.generation !== turn.generation) {
4998
+ this.transcriptRunningSince = { generation: turn.generation, at: performance.now() };
4999
+ }
5000
+ if (performance.now() - this.transcriptRunningSince.at >= TRANSCRIPT_RUNNING_HOLD_MAX_MS)
5001
+ verdict = "unknown";
5002
+ }
5003
+ if (verdict !== "running")
5004
+ this.transcriptRunningSince = null;
5005
+ if (verdict === "running") {
5006
+ // Idle on screen, still working in the transcript: look again after another window.
5007
+ this.armReplyGuardConfirm(turn.generation);
5008
+ this.logger.info({ correlationId: turn.target.correlationId, generation: turn.generation, reason: "transcript_turn_running" }, "Reply guard holding — the transcript shows the turn still running");
5009
+ return;
5010
+ }
5011
+ if (verdict !== "ended") {
5012
+ this.clearReplyGuardConfirm();
5013
+ this.turnReplyGuard.complete(turn.generation);
5014
+ this.logger.info({ correlationId: turn.target.correlationId, generation: turn.generation, reason: `transcript_${verdict}` }, verdict === "unknown" ? "Reply guard stood down — this delivery's turn is not in the transcript followed (fail-safe)"
5015
+ : verdict === "aborted" ? "Reply guard stood down — the turn was interrupted"
5016
+ : "Reply guard stood down — the turn ended on a provider error (its own notice covers it)");
5017
+ return;
5018
+ }
5019
+ }
4956
5020
  this.clearReplyGuardConfirm();
4957
5021
  if (turn.replyAttempted) {
4958
5022
  // A reply was attempted but its deliver result is unknown (in-flight
@@ -4970,6 +5034,16 @@ export class Daemon extends EventEmitter {
4970
5034
  || this.config.backend === "claude-code"
4971
5035
  || this.backend?.binaryName === "claude";
4972
5036
  }
5037
+ /**
5038
+ * This launch's transcript monitor. #1510: its turn boundaries feed the reply guard's ledger, which starts empty
5039
+ * with it — a new monitor re-baselines at the transcript's end, so nothing the old one read can be attributed.
5040
+ */
5041
+ buildTranscriptMonitor(source) {
5042
+ const monitor = new TranscriptMonitor(this.instanceDir, this.logger, source);
5043
+ this.transcriptTurns.reset();
5044
+ monitor.on("turns", (turns) => this.transcriptTurns.observe(turns));
5045
+ return monitor;
5046
+ }
4973
5047
  replyCompletionGuardEnabled() {
4974
5048
  return this.config.reply_completion_guard !== false
4975
5049
  && this.backend?.replyCompletionGuard === true;
@@ -8275,6 +8349,10 @@ export class Daemon extends EventEmitter {
8275
8349
  // is disqualifying and no amount of output may override it. Where it
8276
8350
  // cannot (a backend with no prompt pattern), the output signal remains
8277
8351
  // exactly as before — this must not regress backends we cannot read.
8352
+ // The attempt's owner (#1514 review): a confirmation fenced because the window was replaced must not be revived
8353
+ // by the late proof below on the replacement's pane.
8354
+ const ownerTmux = this.tmux, ownerGeneration = this.spawnGeneration;
8355
+ const owned = () => this.tmux === ownerTmux && this.spawnGeneration === ownerGeneration;
8278
8356
  const becameBusy = await this.confirmAfterEnter(windowId, enterAt, signature, pasteBaseline, "idle-to-busy-retry", !rawPaste);
8279
8357
  if (becameBusy) {
8280
8358
  if (status)
@@ -8286,15 +8364,29 @@ export class Daemon extends EventEmitter {
8286
8364
  if (!rawPaste && !steer && !this.canProveSubmission())
8287
8365
  verdict.proof = "output-edge";
8288
8366
  }
8367
+ else if (!owned()) {
8368
+ // The window this delivery was pasted into was replaced while it was being confirmed: whether its CLI took
8369
+ // the message is unknown, and the new window's pane says nothing about it. Uncertain, never ✅ or ❌.
8370
+ this.logger.warn({ phase: "post-submit-proof" }, "Window replaced during submission proof — delivery outcome uncertain");
8371
+ verdict.phase = "post-submit-proof";
8372
+ verdict.proof = "window-replaced";
8373
+ return false;
8374
+ }
8289
8375
  else {
8290
8376
  const proof = this.structuredInputEvidence()
8291
- ? await this.lateCodexSubmissionProof(signature, pasteBaseline)
8292
- : await this.confirmSubmitted(signature, pasteBaseline);
8293
- if (proof === "submitted") {
8377
+ ? await this.lateCodexSubmissionProof(signature, pasteBaseline, false, owned)
8378
+ : await this.confirmSubmitted(signature, pasteBaseline, owned);
8379
+ if (proof === "submitted" && owned()) {
8294
8380
  if (status)
8295
8381
  this.emit("message_confirmed", status);
8296
8382
  return true;
8297
8383
  }
8384
+ if (!owned()) {
8385
+ this.logger.warn({ phase: "post-submit-proof" }, "Window replaced during submission proof — delivery outcome uncertain");
8386
+ verdict.phase = "post-submit-proof";
8387
+ verdict.proof = "window-replaced";
8388
+ return false;
8389
+ }
8298
8390
  if (this.structuredInputEvidence() && proof !== "stranded") {
8299
8391
  // This is the observed #910 race: the CLI processed the message
8300
8392
  // although its echo had not appeared within the proof window. A
@@ -8397,16 +8489,25 @@ export class Daemon extends EventEmitter {
8397
8489
  * still confirmed on output alone).
8398
8490
  */
8399
8491
  async confirmAfterEnter(windowId, enterAt, signature, baseline, retryPhase, allowRecoveryEnter = true) {
8492
+ // The window this confirmation is about (#1490). The waits below can span a recoverWindow, which replaces
8493
+ // this.tmux with a new TmuxManager, so its identity (with the spawn generation) is the fence. A recovery Enter or
8494
+ // a proof taken after that would be about another window: the fence goes down to the write
8495
+ // (sendDeliveryEnterAfterAvailability asks it last, right before the key) and into every proof, which asks it
8496
+ // before its capture and again before judging what it read (#1514 review) — so a replacement during a capture
8497
+ // can neither confirm this delivery nor run a proof's side effects.
8498
+ const generation = this.spawnGeneration, tmux = this.tmux;
8499
+ const current = () => this.spawnGeneration === generation && this.tmux === tmux;
8500
+ const proofNow = () => this.confirmSubmitted(signature, baseline, current);
8400
8501
  if (!this.canProveSubmission()) {
8401
- let busy = await this.confirmBusyAfterEnter(windowId, enterAt);
8502
+ let busy = (await this.confirmBusyAfterEnter(windowId, enterAt)) && current();
8402
8503
  if (!busy) {
8403
- if (!allowRecoveryEnter)
8504
+ if (!allowRecoveryEnter || !current())
8404
8505
  return false;
8405
8506
  this.logger.warn("No idle→busy transition after Enter — re-sending Enter once");
8406
8507
  const retryAt = Date.now();
8407
- if (!(await this.sendDeliveryEnter(retryPhase)))
8508
+ if (!(await this.sendDeliveryEnter(retryPhase, current)))
8408
8509
  return false;
8409
- busy = await this.confirmBusyAfterEnter(windowId, retryAt);
8510
+ busy = (await this.confirmBusyAfterEnter(windowId, retryAt)) && current();
8410
8511
  }
8411
8512
  return busy;
8412
8513
  }
@@ -8422,7 +8523,9 @@ export class Daemon extends EventEmitter {
8422
8523
  // proves a swallowed Enter only once it outlasts the window; an early one is polled through. Codex keeps its rule.
8423
8524
  const strandMustPersist = !!this.backend?.readInputRow;
8424
8525
  for (;;) {
8425
- proof = await this.confirmSubmitted(signature, baseline);
8526
+ proof = await proofNow();
8527
+ if (!current())
8528
+ return false;
8426
8529
  if (proof === "submitted")
8427
8530
  return true;
8428
8531
  if ((proof === "stranded" && !strandMustPersist) || Date.now() >= firstDeadline)
@@ -8431,18 +8534,22 @@ export class Daemon extends EventEmitter {
8431
8534
  }
8432
8535
  if (proof !== "stranded" || !allowRecoveryEnter)
8433
8536
  return false;
8434
- if (!(await this.waitForPaneReadyForDelivery(windowId, STRANDED_RETRY_READY_WAIT_MS)))
8537
+ if (!(await this.waitForPaneReadyForDelivery(windowId, STRANDED_RETRY_READY_WAIT_MS)) || !current())
8538
+ return false;
8539
+ proof = await proofNow();
8540
+ if (!current())
8435
8541
  return false;
8436
- proof = await this.confirmSubmitted(signature, baseline);
8437
8542
  if (proof === "submitted")
8438
8543
  return true;
8439
8544
  if (proof !== "stranded")
8440
8545
  return false;
8441
- if (!(await this.sendDeliveryEnter(retryPhase)))
8546
+ if (!(await this.sendDeliveryEnter(retryPhase, current)))
8442
8547
  return false;
8443
8548
  const retryDeadline = Date.now() + POST_ENTER_PROOF_WINDOW_MS;
8444
8549
  for (;;) {
8445
- proof = await this.confirmSubmitted(signature, baseline);
8550
+ proof = await proofNow();
8551
+ if (!current())
8552
+ return false;
8446
8553
  if (proof === "submitted")
8447
8554
  return true;
8448
8555
  if (Date.now() >= retryDeadline)
@@ -8450,8 +8557,10 @@ export class Daemon extends EventEmitter {
8450
8557
  await new Promise(r => setTimeout(r, POST_ENTER_PROOF_POLL_MS));
8451
8558
  }
8452
8559
  }
8453
- if (await this.confirmSubmitted(signature, baseline) === "submitted")
8560
+ if (await proofNow() === "submitted" && current())
8454
8561
  return true;
8562
+ if (!current())
8563
+ return false;
8455
8564
  // Retry once the prompt is back — an Enter sent into a mid-redraw TUI is
8456
8565
  // how we got here. Then poll briefly rather than judging on one capture:
8457
8566
  // the key takes a moment to be digested, and a single early look would
@@ -8461,25 +8570,32 @@ export class Daemon extends EventEmitter {
8461
8570
  this.logger.warn("Enter did not submit — waiting for the prompt, then re-sending once");
8462
8571
  if (!(await this.waitForPaneReadyForDelivery(windowId, STRANDED_RETRY_READY_WAIT_MS)))
8463
8572
  return false;
8464
- if (!(await this.sendDeliveryEnter(retryPhase)))
8573
+ if (!(await this.sendDeliveryEnter(retryPhase, current)))
8465
8574
  return false;
8466
8575
  const deadline = Date.now() + POST_ENTER_PROOF_WINDOW_MS;
8467
8576
  for (;;) {
8468
- if (await this.confirmSubmitted(signature, baseline) === "submitted")
8577
+ const proof = await proofNow();
8578
+ if (!current())
8579
+ return false;
8580
+ if (proof === "submitted")
8469
8581
  return true;
8470
8582
  if (Date.now() >= deadline)
8471
8583
  return false;
8472
8584
  await new Promise(r => setTimeout(r, POST_ENTER_PROOF_POLL_MS));
8473
8585
  }
8474
8586
  }
8475
- async confirmSubmitted(signature, baseline) {
8476
- if (!this.tmux)
8587
+ async confirmSubmitted(signature, baseline, owned) {
8588
+ // `owned`: the attempt's window fence (#1514 review), asked before the capture and again before judging it —
8589
+ // judging can retire the spawn's input guard, so a capture of a replaced window must not even be judged.
8590
+ if (!this.tmux || (owned && !owned()))
8477
8591
  return "unproven";
8478
8592
  let pane = null;
8479
8593
  try {
8480
8594
  pane = await this.tmux.capturePane();
8481
8595
  }
8482
8596
  catch { /* the transcript may still say */ }
8597
+ if (owned && !owned())
8598
+ return "unproven";
8483
8599
  const onPane = pane === null ? "unproven" : this.judgeSubmission(pane, signature, baseline);
8484
8600
  if (onPane === "submitted")
8485
8601
  return onPane;
@@ -8487,7 +8603,7 @@ export class Daemon extends EventEmitter {
8487
8603
  const found = await this.transcriptLook(signature);
8488
8604
  // One synchronous stretch from here: the fence is asked after the last await, and only then is the hit kept and the
8489
8605
  // spawn's guard retired — a stop or respawn that lands between the look and this line leaves both untouched.
8490
- if (!found || !t?.current())
8606
+ if (!found || !t?.current() || (owned && !owned()))
8491
8607
  return onPane;
8492
8608
  if (!t.provenBy) {
8493
8609
  t.provenBy = found;
@@ -8622,11 +8738,13 @@ export class Daemon extends EventEmitter {
8622
8738
  return "unverifiable";
8623
8739
  }
8624
8740
  /** Only positive echo/queue evidence may turn an ambiguous Codex write into ✅. */
8625
- async lateCodexSubmissionProof(signature, baseline, waitThroughStranded = false) {
8741
+ async lateCodexSubmissionProof(signature, baseline, waitThroughStranded = false, owned) {
8626
8742
  const deadline = Date.now() + CODEX_LATE_PROOF_MS;
8627
8743
  let proof = "unproven";
8628
8744
  for (;;) {
8629
- proof = await this.confirmSubmitted(signature, baseline);
8745
+ if (owned && !owned())
8746
+ return "unproven";
8747
+ proof = await this.confirmSubmitted(signature, baseline, owned);
8630
8748
  // Ordinary idle-path proof may return a strand immediately. After a
8631
8749
  // native-queue recovery Enter, though, it can be the previous frame
8632
8750
  // still on screen; only a strand that survives the bounded repaint
@@ -8638,6 +8756,8 @@ export class Daemon extends EventEmitter {
8638
8756
  // Scrollback can hold the echo the viewport lost — but it is judged exactly like the viewport: a box that
8639
8757
  // cannot be read, or that still holds our text, is never upgraded by an echo further up.
8640
8758
  const history = await this.tmux.capturePaneWithHistory(300);
8759
+ if (owned && !owned())
8760
+ return "unproven";
8641
8761
  if (this.judgeSubmission(history, signature, baseline) === "submitted")
8642
8762
  return this.submittedProof();
8643
8763
  }
@@ -8924,12 +9044,18 @@ export class Daemon extends EventEmitter {
8924
9044
  async confirmBusyAfterEnter(windowId, since) {
8925
9045
  const client = this.controlClient;
8926
9046
  const hardDeadline = Date.now() + CONFIRM_BUSY_MAX_WAIT_MS;
9047
+ // A drained control read hides notifications (#1517 review): while the client is blind a quiet pane is not
9048
+ // evidence of a swallowed Enter, so blind polls do not count toward "no reaction". Bounded: past the drain limit
9049
+ // the client retires and resets, which restarts this check from when it could see again.
9050
+ const blindDeadline = hardDeadline + CONFIRM_BUSY_BLIND_EXTRA_MS;
8927
9051
  let observedFrom = since;
8928
9052
  let polls = 0;
8929
9053
  while (polls < CONFIRM_BUSY_POLLS) {
8930
9054
  await new Promise(r => setTimeout(r, CONFIRM_BUSY_POLL_MS));
8931
9055
  if (client.hasOutputSince(windowId, observedFrom))
8932
9056
  return true;
9057
+ if (client.isObservationBlind?.() && Date.now() < blindDeadline)
9058
+ continue;
8933
9059
  const resetAt = client.getObservationResetAt();
8934
9060
  if (resetAt > observedFrom && Date.now() < hardDeadline) {
8935
9061
  this.logger.debug({ windowId, resetAt }, "Control mode reconnected mid-confirmation — restarting the Enter check from when we could see again");
@@ -9247,7 +9373,20 @@ export class Daemon extends EventEmitter {
9247
9373
  respond(null, "No channel world bound to this chat context — awaiting an inbound message to establish it");
9248
9374
  return;
9249
9375
  }
9250
- if (!routeToolCall(adapter, tool, args, this.lastThreadId, respond)) {
9376
+ // #1266: without the fleet there is no button store: buttons are checked, then offered as text.
9377
+ let routed = args;
9378
+ if (tool === "reply") {
9379
+ const buttons = parseReplyButtons(args.buttons, args);
9380
+ if (buttons && "error" in buttons) {
9381
+ respond(null, `reply: ${buttons.error}`);
9382
+ return;
9383
+ }
9384
+ if (buttons) {
9385
+ routed = { ...args, text: `${String(args.text)}\n\n${replyButtonsFallbackText(buttons.buttons)}` };
9386
+ delete routed.buttons;
9387
+ }
9388
+ }
9389
+ if (!routeToolCall(adapter, tool, routed, this.lastThreadId, respond)) {
9251
9390
  respond(null, `Unknown tool: ${tool}`);
9252
9391
  }
9253
9392
  }
@@ -10344,15 +10483,16 @@ export class Daemon extends EventEmitter {
10344
10483
  // this file from <instanceDir>/agent.token (mode 0o600) and sends its
10345
10484
  // value in the X-Agend-Instance-Token header; the daemon-side /agent
10346
10485
  // endpoint verifies it matches the on-disk value for the claimed
10347
- // instance. This prevents other local processes (even those holding
10348
- // the global web token) from impersonating instances.
10486
+ // instance. A global web token cannot substitute for this credential, but
10487
+ // same-uid shell processes can read sibling tokens. Mode 0600 separates
10488
+ // OS users; it does not isolate mutually untrusted agents on this account.
10349
10489
  const agentTokenPath = join(this.instanceDir, "agent.token");
10350
10490
  const agentToken = randomBytes(32).toString("hex");
10351
10491
  const tokenWrite = writeSecretFile(agentTokenPath, agentToken);
10352
10492
  if (!tokenWrite.ok) {
10353
10493
  // Do not fail the spawn over it — an instance that cannot start is worse
10354
10494
  // than one whose token is readable. But say so, loudly: the whole point of
10355
- // this token is that other local processes cannot use it.
10495
+ // this permission check separates other OS users, not same-uid processes.
10356
10496
  this.logger.error({ path: agentTokenPath, mode: tokenWrite.mode?.toString(8), reason: tokenWrite.reason }, "Agent token file is not owner-only — other local users can impersonate this instance");
10357
10497
  }
10358
10498
  // AGEND_HOME points the child's agent-cli at the same data dir the daemon