@songsid/agend 2.3.5-alpha.5 → 2.3.5-beta.1

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 (976) hide show
  1. package/README.md +0 -2
  2. package/README.zh-TW.md +0 -2
  3. package/THIRD_PARTY_NOTICES.md +0 -68
  4. package/dist/agent-endpoint.d.ts +1 -5
  5. package/dist/agent-endpoint.js +2 -12
  6. package/dist/agent-endpoint.js.map +1 -1
  7. package/dist/agent-file-read.js +1 -1
  8. package/dist/agent-file-read.js.map +1 -1
  9. package/dist/auth-api.d.ts +0 -48
  10. package/dist/auth-api.js +4 -250
  11. package/dist/auth-api.js.map +1 -1
  12. package/dist/authority/session-authorizations.d.ts +2 -0
  13. package/dist/authority/session-authorizations.js +7 -1
  14. package/dist/authority/session-authorizations.js.map +1 -1
  15. package/dist/authority/web-authority.d.ts +2 -12
  16. package/dist/authority/web-authority.js +4 -25
  17. package/dist/authority/web-authority.js.map +1 -1
  18. package/dist/backend/claude-code.d.ts +12 -15
  19. package/dist/backend/claude-code.js +133 -152
  20. package/dist/backend/claude-code.js.map +1 -1
  21. package/dist/backend/codex-footer-hints.d.ts +0 -3
  22. package/dist/backend/codex-footer-hints.js +0 -14
  23. package/dist/backend/codex-footer-hints.js.map +1 -1
  24. package/dist/backend/codex-package.d.ts +2 -5
  25. package/dist/backend/codex-package.js +5 -1
  26. package/dist/backend/codex-package.js.map +1 -1
  27. package/dist/backend/codex-quota-history.js +19 -4
  28. package/dist/backend/codex-quota-history.js.map +1 -1
  29. package/dist/backend/codex.d.ts +115 -142
  30. package/dist/backend/codex.js +1094 -1187
  31. package/dist/backend/codex.js.map +1 -1
  32. package/dist/backend/grok.d.ts +0 -2
  33. package/dist/backend/grok.js +0 -22
  34. package/dist/backend/grok.js.map +1 -1
  35. package/dist/backend/types.d.ts +2 -7
  36. package/dist/backend/types.js.map +1 -1
  37. package/dist/bundled-tmux-guard.d.ts +21 -0
  38. package/dist/bundled-tmux-guard.js +96 -0
  39. package/dist/bundled-tmux-guard.js.map +1 -0
  40. package/dist/channel/ipc-bridge.d.ts +0 -2
  41. package/dist/channel/mcp-tools.js +2 -2
  42. package/dist/channel/mcp-tools.js.map +1 -1
  43. package/dist/classic-channel-manager.d.ts +2 -0
  44. package/dist/classic-channel-manager.js +5 -1
  45. package/dist/classic-channel-manager.js.map +1 -1
  46. package/dist/cli.js +30 -127
  47. package/dist/cli.js.map +1 -1
  48. package/dist/config-validator.js +13 -74
  49. package/dist/config-validator.js.map +1 -1
  50. package/dist/config.js +3 -17
  51. package/dist/config.js.map +1 -1
  52. package/dist/daemon.d.ts +5 -72
  53. package/dist/daemon.js +275 -869
  54. package/dist/daemon.js.map +1 -1
  55. package/dist/delivery-consumed-watch.d.ts +3 -15
  56. package/dist/delivery-consumed-watch.js +1 -23
  57. package/dist/delivery-consumed-watch.js.map +1 -1
  58. package/dist/delivery-outbox.d.ts +0 -5
  59. package/dist/delivery-outbox.js +4 -32
  60. package/dist/delivery-outbox.js.map +1 -1
  61. package/dist/delivery-reconciliation.d.ts +42 -2
  62. package/dist/delivery-reconciliation.js +164 -2
  63. package/dist/delivery-reconciliation.js.map +1 -1
  64. package/dist/doctor.js +9 -20
  65. package/dist/doctor.js.map +1 -1
  66. package/dist/fleet-context.d.ts +2 -2
  67. package/dist/fleet-level-config.d.ts +1 -1
  68. package/dist/fleet-level-config.js +0 -2
  69. package/dist/fleet-level-config.js.map +1 -1
  70. package/dist/fleet-manager.d.ts +9 -498
  71. package/dist/fleet-manager.js +202 -2849
  72. package/dist/fleet-manager.js.map +1 -1
  73. package/dist/general-instance.d.ts +0 -7
  74. package/dist/general-instance.js +3 -20
  75. package/dist/general-instance.js.map +1 -1
  76. package/dist/general-knowledge/skills/concepts/SKILL.md +18 -50
  77. package/dist/general-knowledge/skills/credential-profiles/SKILL.md +2 -5
  78. package/dist/general-knowledge/skills/fleet-health/SKILL.md +2 -2
  79. package/dist/general-knowledge/skills/session-management/SKILL.md +1 -1
  80. package/dist/general-knowledge/skills/tui-effort/SKILL.md +10 -10
  81. package/dist/general-knowledge/skills/web-dashboard/SKILL.md +13 -23
  82. package/dist/instance-config-impact.js +4 -8
  83. package/dist/instance-config-impact.js.map +1 -1
  84. package/dist/instance-lifecycle.d.ts +3 -22
  85. package/dist/instance-lifecycle.js +176 -393
  86. package/dist/instance-lifecycle.js.map +1 -1
  87. package/dist/instructions.d.ts +0 -2
  88. package/dist/instructions.js +0 -6
  89. package/dist/instructions.js.map +1 -1
  90. package/dist/locale.js +2 -147
  91. package/dist/locale.js.map +1 -1
  92. package/dist/login-flows.d.ts +7 -8
  93. package/dist/login-flows.js +1 -24
  94. package/dist/login-flows.js.map +1 -1
  95. package/dist/ls-rows.js +4 -3
  96. package/dist/ls-rows.js.map +1 -1
  97. package/dist/muse-usage-relay.d.ts +2 -0
  98. package/dist/muse-usage-relay.js +5 -3
  99. package/dist/muse-usage-relay.js.map +1 -1
  100. package/dist/needs-you-hub.d.ts +0 -5
  101. package/dist/needs-you-hub.js +2 -18
  102. package/dist/needs-you-hub.js.map +1 -1
  103. package/dist/needs-you.d.ts +2 -45
  104. package/dist/needs-you.js +2 -26
  105. package/dist/needs-you.js.map +1 -1
  106. package/dist/office-share-page.js +3 -3
  107. package/dist/office-share-page.js.map +1 -1
  108. package/dist/office-share.d.ts +0 -11
  109. package/dist/office-share.js +0 -14
  110. package/dist/office-share.js.map +1 -1
  111. package/dist/outbound-handlers.d.ts +2 -30
  112. package/dist/outbound-handlers.js +4 -109
  113. package/dist/outbound-handlers.js.map +1 -1
  114. package/dist/outbound-schemas.d.ts +1 -71
  115. package/dist/outbound-schemas.js +14 -36
  116. package/dist/outbound-schemas.js.map +1 -1
  117. package/dist/pane-quota-history.d.ts +0 -2
  118. package/dist/pane-quota-history.js +0 -20
  119. package/dist/pane-quota-history.js.map +1 -1
  120. package/dist/pause-marker.d.ts +1 -1
  121. package/dist/pause-marker.js +1 -1
  122. package/dist/pause-marker.js.map +1 -1
  123. package/dist/public-web-gateway.js +0 -16
  124. package/dist/public-web-gateway.js.map +1 -1
  125. package/dist/public-web-link.d.ts +0 -11
  126. package/dist/public-web-link.js +0 -13
  127. package/dist/public-web-link.js.map +1 -1
  128. package/dist/quickstart-api.js +5 -9
  129. package/dist/quickstart-api.js.map +1 -1
  130. package/dist/quickstart.d.ts +0 -6
  131. package/dist/quickstart.js +6 -44
  132. package/dist/quickstart.js.map +1 -1
  133. package/dist/quota-notice-config.d.ts +22 -0
  134. package/dist/quota-notice-config.js +41 -0
  135. package/dist/quota-notice-config.js.map +1 -0
  136. package/dist/scheduler/task-board-text.js +1 -1
  137. package/dist/scheduler/task-board-text.js.map +1 -1
  138. package/dist/scheduler/task-board.d.ts +0 -4
  139. package/dist/scheduler/task-board.js +3 -9
  140. package/dist/scheduler/task-board.js.map +1 -1
  141. package/dist/service-installer.d.ts +2 -7
  142. package/dist/service-installer.js +10 -13
  143. package/dist/service-installer.js.map +1 -1
  144. package/dist/settings-api.d.ts +0 -12
  145. package/dist/settings-api.js +7 -487
  146. package/dist/settings-api.js.map +1 -1
  147. package/dist/settings-baseline.d.ts +0 -7
  148. package/dist/settings-baseline.js +1 -3
  149. package/dist/settings-baseline.js.map +1 -1
  150. package/dist/settings-change.js +7 -35
  151. package/dist/settings-change.js.map +1 -1
  152. package/dist/settings-confirmation.d.ts +1 -16
  153. package/dist/settings-confirmation.js +9 -47
  154. package/dist/settings-confirmation.js.map +1 -1
  155. package/dist/settings-effect.d.ts +0 -17
  156. package/dist/settings-effect.js +1 -155
  157. package/dist/settings-effect.js.map +1 -1
  158. package/dist/settings-http-confirmation.d.ts +0 -4
  159. package/dist/settings-http-confirmation.js +3 -43
  160. package/dist/settings-http-confirmation.js.map +1 -1
  161. package/dist/settings-instance-patch.js +1 -1
  162. package/dist/settings-instance-patch.js.map +1 -1
  163. package/dist/settings-request-capability.d.ts +0 -2
  164. package/dist/settings-request-capability.js +0 -4
  165. package/dist/settings-request-capability.js.map +1 -1
  166. package/dist/settings-transaction.d.ts +0 -4
  167. package/dist/settings-transaction.js +0 -9
  168. package/dist/settings-transaction.js.map +1 -1
  169. package/dist/setup-form.js +3 -6
  170. package/dist/setup-form.js.map +1 -1
  171. package/dist/setup-i18n.js +0 -3
  172. package/dist/setup-i18n.js.map +1 -1
  173. package/dist/setup-wizard.js +2 -6
  174. package/dist/setup-wizard.js.map +1 -1
  175. package/dist/task-board-tool.d.ts +1 -2
  176. package/dist/task-board-tool.js +6 -62
  177. package/dist/task-board-tool.js.map +1 -1
  178. package/dist/tmux-control.d.ts +1 -2
  179. package/dist/tmux-control.js +4 -4
  180. package/dist/tmux-control.js.map +1 -1
  181. package/dist/tmux-exec-helper.js +1 -32
  182. package/dist/tmux-exec-helper.js.map +1 -1
  183. package/dist/tmux-manager.d.ts +2 -3
  184. package/dist/tmux-manager.js +36 -45
  185. package/dist/tmux-manager.js.map +1 -1
  186. package/dist/tmux-read.js +3 -4
  187. package/dist/tmux-read.js.map +1 -1
  188. package/dist/tool-permissions.js +1 -2
  189. package/dist/tool-permissions.js.map +1 -1
  190. package/dist/topic-commands.js +5 -9
  191. package/dist/topic-commands.js.map +1 -1
  192. package/dist/transcript-delta-reader.d.ts +1 -1
  193. package/dist/transcript-delta-reader.js +1 -1
  194. package/dist/transcript-delta-reader.js.map +1 -1
  195. package/dist/transcript-monitor.d.ts +0 -3
  196. package/dist/transcript-monitor.js +51 -27
  197. package/dist/transcript-monitor.js.map +1 -1
  198. package/dist/transcript-sources.d.ts +0 -5
  199. package/dist/transcript-sources.js +79 -8
  200. package/dist/transcript-sources.js.map +1 -1
  201. package/dist/types.d.ts +3 -29
  202. package/dist/ui/app.html +8 -1
  203. package/dist/ui/backend-signin.js +21 -39
  204. package/dist/ui/chat-ambient.js +1 -1
  205. package/dist/ui/chat-md-strings.js +9 -3
  206. package/dist/ui/chat-render.js +670 -3
  207. package/dist/ui/chat-store.js +3 -14
  208. package/dist/ui/chat-strings.js +285 -3
  209. package/dist/ui/chat-thread.js +969 -3
  210. package/dist/ui/chat-time.js +80 -3
  211. package/dist/ui/chat-tour.js +1 -1
  212. package/dist/ui/fleet-office-pack.d.ts +0 -9
  213. package/dist/ui/fleet-office-pack.js +4 -76
  214. package/dist/ui/fleet-office-skin.js +5 -23
  215. package/dist/ui/fleet-office-store.js +0 -5
  216. package/dist/ui/fleet-office.js +6 -173
  217. package/dist/ui/fleet-task-card.js +4 -8
  218. package/dist/ui/fleet-task-common.js +2 -2
  219. package/dist/ui/fleet-tasks.js +39 -125
  220. package/dist/ui/html-attachment.js +40 -3
  221. package/dist/ui/office-share-page.js +2 -4
  222. package/dist/ui/panel-chat.js +75 -90
  223. package/dist/ui/panel-details.js +2 -3
  224. package/dist/ui/panel-fleet.js +18 -105
  225. package/dist/ui/panel-log.js +2 -2
  226. package/dist/ui/panel-needs.js +4 -162
  227. package/dist/ui/panel-notices.js +4 -3
  228. package/dist/ui/panel-settings.js +202 -281
  229. package/dist/ui/preview-pages.js +1 -1
  230. package/dist/ui/preview-panel.js +13 -21
  231. package/dist/ui/preview-versions.js +1 -1
  232. package/dist/ui/preview.js +476 -3
  233. package/dist/ui/search-dialog.js +3 -4
  234. package/dist/ui/settings-appearance.js +23 -122
  235. package/dist/ui/settings-catalog.js +10 -37
  236. package/dist/ui/settings-confirm.js +1 -3
  237. package/dist/ui/settings-dialogs.js +20 -48
  238. package/dist/ui/settings-guests.js +14 -27
  239. package/dist/ui/settings-model.js +1 -10
  240. package/dist/ui/settings-quota-notice.js +100 -0
  241. package/dist/ui/settings-registry.js +5 -15
  242. package/dist/ui/settings-strings.js +32 -105
  243. package/dist/ui/settings-web-authority.js +13 -18
  244. package/dist/ui/shared/app-i18n.js +2 -2
  245. package/dist/ui/shared/app-route.js +3 -12
  246. package/dist/ui/shared/app-session.js +2 -6
  247. package/dist/ui/shared/app-shell.js +26 -87
  248. package/dist/ui/shared/app-store.js +2 -3
  249. package/dist/ui/shared/app-stream.js +1 -3
  250. package/dist/ui/shared/app.css +5 -1368
  251. package/dist/ui/shared/app.js +5 -17
  252. package/dist/ui/shared/header-tools.js +9 -9
  253. package/dist/ui/shared/instance-nav.js +7 -34
  254. package/dist/ui/shared/instance-switch.js +3 -4
  255. package/dist/ui/shared/loading.css +37 -0
  256. package/dist/ui/shared/signin.js +6 -211
  257. package/dist/ui/shared/tokens.css +0 -1
  258. package/dist/ui/shared/ui-dialog.js +2 -2
  259. package/dist/ui/shared/ui-menu.js +10 -30
  260. package/dist/ui/shared/ui-states.js +14 -3
  261. package/dist/ui/shared/vendor/vendor.json +2 -19
  262. package/dist/ui/shared/view-strings.js +0 -8
  263. package/dist/ui/signin.html +5 -23
  264. package/dist/unattended-install.js +1 -2
  265. package/dist/unattended-install.js.map +1 -1
  266. package/dist/usage/providers.d.ts +5 -0
  267. package/dist/usage/providers.js +6 -2
  268. package/dist/usage/providers.js.map +1 -1
  269. package/dist/usage/quota-notices.d.ts +38 -0
  270. package/dist/usage/quota-notices.js +160 -0
  271. package/dist/usage/quota-notices.js.map +1 -0
  272. package/dist/usage/usage-api.d.ts +1 -0
  273. package/dist/usage/usage-api.js +16 -0
  274. package/dist/usage/usage-api.js.map +1 -1
  275. package/dist/view-api.js +7 -5
  276. package/dist/view-api.js.map +1 -1
  277. package/dist/web-api.d.ts +2 -80
  278. package/dist/web-api.js +10 -513
  279. package/dist/web-api.js.map +1 -1
  280. package/dist/web-backend-login.d.ts +1 -23
  281. package/dist/web-backend-login.js +17 -11
  282. package/dist/web-backend-login.js.map +1 -1
  283. package/dist/web-chat-history.d.ts +2 -19
  284. package/dist/web-chat-history.js +3 -72
  285. package/dist/web-chat-history.js.map +1 -1
  286. package/dist/web-office-skins.d.ts +0 -9
  287. package/dist/web-office-skins.js +1 -16
  288. package/dist/web-office-skins.js.map +1 -1
  289. package/dist/web-only-fleet.d.ts +0 -20
  290. package/dist/web-only-fleet.js +0 -21
  291. package/dist/web-only-fleet.js.map +1 -1
  292. package/dist/web-session.d.ts +0 -42
  293. package/dist/web-session.js +0 -9
  294. package/dist/web-session.js.map +1 -1
  295. package/dist/web-settings-patch.d.ts +1 -3
  296. package/dist/web-settings-patch.js +1 -4
  297. package/dist/web-settings-patch.js.map +1 -1
  298. package/dist/web-shell-routes.d.ts +1 -10
  299. package/dist/web-shell-routes.js +2 -14
  300. package/dist/web-shell-routes.js.map +1 -1
  301. package/dist/web-terminal.d.ts +30 -4
  302. package/dist/web-terminal.js +6 -9
  303. package/dist/web-terminal.js.map +1 -1
  304. package/dist/yaml-shared-nodes.js +3 -8
  305. package/dist/yaml-shared-nodes.js.map +1 -1
  306. package/launcher/agend-install.cjs +1 -8
  307. package/launcher/postinstall.cjs +2 -27
  308. package/package.json +3 -10
  309. package/templates/launchd.plist.ejs +1 -3
  310. package/dist/accounts-view.d.ts +0 -97
  311. package/dist/accounts-view.js +0 -116
  312. package/dist/accounts-view.js.map +0 -1
  313. package/dist/agent-runtime-api.d.ts +0 -4
  314. package/dist/agent-runtime-api.js +0 -59
  315. package/dist/agent-runtime-api.js.map +0 -1
  316. package/dist/agent-runtime-change.d.ts +0 -76
  317. package/dist/agent-runtime-change.js +0 -114
  318. package/dist/agent-runtime-change.js.map +0 -1
  319. package/dist/agent-workspace.d.ts +0 -93
  320. package/dist/agent-workspace.js +0 -353
  321. package/dist/agent-workspace.js.map +0 -1
  322. package/dist/backend/grok-model-cache.d.ts +0 -7
  323. package/dist/backend/grok-model-cache.js +0 -65
  324. package/dist/backend/grok-model-cache.js.map +0 -1
  325. package/dist/backend/native-pane.d.ts +0 -11
  326. package/dist/backend/native-pane.js +0 -59
  327. package/dist/backend/native-pane.js.map +0 -1
  328. package/dist/build-provenance-cli.d.ts +0 -3
  329. package/dist/build-provenance-cli.js +0 -11
  330. package/dist/build-provenance-cli.js.map +0 -1
  331. package/dist/build-provenance.d.ts +0 -20
  332. package/dist/build-provenance.js +0 -67
  333. package/dist/build-provenance.js.map +0 -1
  334. package/dist/build-provenance.json +0 -1
  335. package/dist/claude-auth-status.d.ts +0 -48
  336. package/dist/claude-auth-status.js +0 -149
  337. package/dist/claude-auth-status.js.map +0 -1
  338. package/dist/fleet-windows-runtime.d.ts +0 -98
  339. package/dist/fleet-windows-runtime.js +0 -467
  340. package/dist/fleet-windows-runtime.js.map +0 -1
  341. package/dist/general-binding.d.ts +0 -85
  342. package/dist/general-binding.js +0 -298
  343. package/dist/general-binding.js.map +0 -1
  344. package/dist/general-host-owner.d.ts +0 -8
  345. package/dist/general-host-owner.js +0 -26
  346. package/dist/general-host-owner.js.map +0 -1
  347. package/dist/general-role.d.ts +0 -5
  348. package/dist/general-role.js +0 -27
  349. package/dist/general-role.js.map +0 -1
  350. package/dist/hub/admission.d.ts +0 -28
  351. package/dist/hub/admission.js +0 -62
  352. package/dist/hub/admission.js.map +0 -1
  353. package/dist/hub/attachments/limits.d.ts +0 -20
  354. package/dist/hub/attachments/limits.js +0 -48
  355. package/dist/hub/attachments/limits.js.map +0 -1
  356. package/dist/hub/attachments/store.d.ts +0 -116
  357. package/dist/hub/attachments/store.js +0 -246
  358. package/dist/hub/attachments/store.js.map +0 -1
  359. package/dist/hub/audit/index.d.ts +0 -62
  360. package/dist/hub/audit/index.js +0 -344
  361. package/dist/hub/audit/index.js.map +0 -1
  362. package/dist/hub/browser-certificate.d.ts +0 -38
  363. package/dist/hub/browser-certificate.js +0 -247
  364. package/dist/hub/browser-certificate.js.map +0 -1
  365. package/dist/hub/buttons-model.d.ts +0 -9
  366. package/dist/hub/buttons-model.js +0 -42
  367. package/dist/hub/buttons-model.js.map +0 -1
  368. package/dist/hub/buttons.d.ts +0 -54
  369. package/dist/hub/buttons.js +0 -346
  370. package/dist/hub/buttons.js.map +0 -1
  371. package/dist/hub/catalog.d.ts +0 -74
  372. package/dist/hub/catalog.js +0 -195
  373. package/dist/hub/catalog.js.map +0 -1
  374. package/dist/hub/client.d.ts +0 -69
  375. package/dist/hub/client.js +0 -300
  376. package/dist/hub/client.js.map +0 -1
  377. package/dist/hub/compose/member.d.ts +0 -139
  378. package/dist/hub/compose/member.js +0 -450
  379. package/dist/hub/compose/member.js.map +0 -1
  380. package/dist/hub/compose/server.d.ts +0 -77
  381. package/dist/hub/compose/server.js +0 -349
  382. package/dist/hub/compose/server.js.map +0 -1
  383. package/dist/hub/compose/views.d.ts +0 -12
  384. package/dist/hub/compose/views.js +0 -4
  385. package/dist/hub/compose/views.js.map +0 -1
  386. package/dist/hub/db.d.ts +0 -56
  387. package/dist/hub/db.js +0 -188
  388. package/dist/hub/db.js.map +0 -1
  389. package/dist/hub/directory/config.d.ts +0 -39
  390. package/dist/hub/directory/config.js +0 -108
  391. package/dist/hub/directory/config.js.map +0 -1
  392. package/dist/hub/directory/directory.d.ts +0 -18
  393. package/dist/hub/directory/directory.js +0 -320
  394. package/dist/hub/directory/directory.js.map +0 -1
  395. package/dist/hub/directory/index.d.ts +0 -7
  396. package/dist/hub/directory/index.js +0 -4
  397. package/dist/hub/directory/index.js.map +0 -1
  398. package/dist/hub/directory/profiles.d.ts +0 -41
  399. package/dist/hub/directory/profiles.js +0 -90
  400. package/dist/hub/directory/profiles.js.map +0 -1
  401. package/dist/hub/directory/types.d.ts +0 -71
  402. package/dist/hub/directory/types.js +0 -14
  403. package/dist/hub/directory/types.js.map +0 -1
  404. package/dist/hub/execution/cli-provider.d.ts +0 -23
  405. package/dist/hub/execution/cli-provider.js +0 -341
  406. package/dist/hub/execution/cli-provider.js.map +0 -1
  407. package/dist/hub/execution/index.d.ts +0 -13
  408. package/dist/hub/execution/index.js +0 -8
  409. package/dist/hub/execution/index.js.map +0 -1
  410. package/dist/hub/execution/model-broker.d.ts +0 -24
  411. package/dist/hub/execution/model-broker.js +0 -208
  412. package/dist/hub/execution/model-broker.js.map +0 -1
  413. package/dist/hub/execution/provider-setup.d.ts +0 -11
  414. package/dist/hub/execution/provider-setup.js +0 -21
  415. package/dist/hub/execution/provider-setup.js.map +0 -1
  416. package/dist/hub/execution/sandbox-runner.d.ts +0 -1
  417. package/dist/hub/execution/sandbox-runner.js +0 -221
  418. package/dist/hub/execution/sandbox-runner.js.map +0 -1
  419. package/dist/hub/execution/service.d.ts +0 -136
  420. package/dist/hub/execution/service.js +0 -459
  421. package/dist/hub/execution/service.js.map +0 -1
  422. package/dist/hub/execution/store.d.ts +0 -61
  423. package/dist/hub/execution/store.js +0 -182
  424. package/dist/hub/execution/store.js.map +0 -1
  425. package/dist/hub/execution/views.d.ts +0 -20
  426. package/dist/hub/execution/views.js +0 -48
  427. package/dist/hub/execution/views.js.map +0 -1
  428. package/dist/hub/http/compose.d.ts +0 -20
  429. package/dist/hub/http/compose.js +0 -518
  430. package/dist/hub/http/compose.js.map +0 -1
  431. package/dist/hub/http/core.d.ts +0 -49
  432. package/dist/hub/http/core.js +0 -124
  433. package/dist/hub/http/core.js.map +0 -1
  434. package/dist/hub/http/deps.d.ts +0 -61
  435. package/dist/hub/http/deps.js +0 -2
  436. package/dist/hub/http/deps.js.map +0 -1
  437. package/dist/hub/http/schema.d.ts +0 -14
  438. package/dist/hub/http/schema.js +0 -80
  439. package/dist/hub/http/schema.js.map +0 -1
  440. package/dist/hub/identity.d.ts +0 -32
  441. package/dist/hub/identity.js +0 -80
  442. package/dist/hub/identity.js.map +0 -1
  443. package/dist/hub/init/browser-certificate.d.ts +0 -9
  444. package/dist/hub/init/browser-certificate.js +0 -78
  445. package/dist/hub/init/browser-certificate.js.map +0 -1
  446. package/dist/hub/init/browser-tls.d.ts +0 -18
  447. package/dist/hub/init/browser-tls.js +0 -62
  448. package/dist/hub/init/browser-tls.js.map +0 -1
  449. package/dist/hub/init/cli.d.ts +0 -3
  450. package/dist/hub/init/cli.js +0 -83
  451. package/dist/hub/init/cli.js.map +0 -1
  452. package/dist/hub/init/directory-certificate.d.ts +0 -24
  453. package/dist/hub/init/directory-certificate.js +0 -222
  454. package/dist/hub/init/directory-certificate.js.map +0 -1
  455. package/dist/hub/init/existing-fleet.d.ts +0 -6
  456. package/dist/hub/init/existing-fleet.js +0 -58
  457. package/dist/hub/init/existing-fleet.js.map +0 -1
  458. package/dist/hub/init/handoff.d.ts +0 -8
  459. package/dist/hub/init/handoff.js +0 -36
  460. package/dist/hub/init/handoff.js.map +0 -1
  461. package/dist/hub/init/identity.d.ts +0 -5
  462. package/dist/hub/init/identity.js +0 -24
  463. package/dist/hub/init/identity.js.map +0 -1
  464. package/dist/hub/init/initializer.d.ts +0 -24
  465. package/dist/hub/init/initializer.js +0 -385
  466. package/dist/hub/init/initializer.js.map +0 -1
  467. package/dist/hub/init/inventory.d.ts +0 -17
  468. package/dist/hub/init/inventory.js +0 -33
  469. package/dist/hub/init/inventory.js.map +0 -1
  470. package/dist/hub/init/layout.d.ts +0 -32
  471. package/dist/hub/init/layout.js +0 -53
  472. package/dist/hub/init/layout.js.map +0 -1
  473. package/dist/hub/init/network.d.ts +0 -18
  474. package/dist/hub/init/network.js +0 -104
  475. package/dist/hub/init/network.js.map +0 -1
  476. package/dist/hub/init/plan-digest.d.ts +0 -5
  477. package/dist/hub/init/plan-digest.js +0 -47
  478. package/dist/hub/init/plan-digest.js.map +0 -1
  479. package/dist/hub/init/prompt.d.ts +0 -26
  480. package/dist/hub/init/prompt.js +0 -110
  481. package/dist/hub/init/prompt.js.map +0 -1
  482. package/dist/hub/init/secret-file.d.ts +0 -1
  483. package/dist/hub/init/secret-file.js +0 -59
  484. package/dist/hub/init/secret-file.js.map +0 -1
  485. package/dist/hub/init/text.d.ts +0 -127
  486. package/dist/hub/init/text.js +0 -247
  487. package/dist/hub/init/text.js.map +0 -1
  488. package/dist/hub/init/types.d.ts +0 -114
  489. package/dist/hub/init/types.js +0 -9
  490. package/dist/hub/init/types.js.map +0 -1
  491. package/dist/hub/init/wizard.d.ts +0 -34
  492. package/dist/hub/init/wizard.js +0 -554
  493. package/dist/hub/init/wizard.js.map +0 -1
  494. package/dist/hub/initialization.d.ts +0 -23
  495. package/dist/hub/initialization.js +0 -28
  496. package/dist/hub/initialization.js.map +0 -1
  497. package/dist/hub/member/agent-mode.d.ts +0 -6
  498. package/dist/hub/member/agent-mode.js +0 -23
  499. package/dist/hub/member/agent-mode.js.map +0 -1
  500. package/dist/hub/member/attachments.d.ts +0 -29
  501. package/dist/hub/member/attachments.js +0 -107
  502. package/dist/hub/member/attachments.js.map +0 -1
  503. package/dist/hub/member/exposure-api.d.ts +0 -87
  504. package/dist/hub/member/exposure-api.js +0 -64
  505. package/dist/hub/member/exposure-api.js.map +0 -1
  506. package/dist/hub/member/exposures.d.ts +0 -123
  507. package/dist/hub/member/exposures.js +0 -282
  508. package/dist/hub/member/exposures.js.map +0 -1
  509. package/dist/hub/member/pairing-api.d.ts +0 -85
  510. package/dist/hub/member/pairing-api.js +0 -385
  511. package/dist/hub/member/pairing-api.js.map +0 -1
  512. package/dist/hub/member/quota.d.ts +0 -20
  513. package/dist/hub/member/quota.js +0 -98
  514. package/dist/hub/member/quota.js.map +0 -1
  515. package/dist/hub/member-journal.d.ts +0 -104
  516. package/dist/hub/member-journal.js +0 -336
  517. package/dist/hub/member-journal.js.map +0 -1
  518. package/dist/hub/member-reconciliation.d.ts +0 -14
  519. package/dist/hub/member-reconciliation.js +0 -97
  520. package/dist/hub/member-reconciliation.js.map +0 -1
  521. package/dist/hub/mount.d.ts +0 -39
  522. package/dist/hub/mount.js +0 -123
  523. package/dist/hub/mount.js.map +0 -1
  524. package/dist/hub/pairing-client.d.ts +0 -17
  525. package/dist/hub/pairing-client.js +0 -108
  526. package/dist/hub/pairing-client.js.map +0 -1
  527. package/dist/hub/pairing.d.ts +0 -65
  528. package/dist/hub/pairing.js +0 -211
  529. package/dist/hub/pairing.js.map +0 -1
  530. package/dist/hub/policy.d.ts +0 -63
  531. package/dist/hub/policy.js +0 -147
  532. package/dist/hub/policy.js.map +0 -1
  533. package/dist/hub/preview.d.ts +0 -32
  534. package/dist/hub/preview.js +0 -64
  535. package/dist/hub/preview.js.map +0 -1
  536. package/dist/hub/private-files.d.ts +0 -5
  537. package/dist/hub/private-files.js +0 -44
  538. package/dist/hub/private-files.js.map +0 -1
  539. package/dist/hub/profile.d.ts +0 -59
  540. package/dist/hub/profile.js +0 -73
  541. package/dist/hub/profile.js.map +0 -1
  542. package/dist/hub/protocol.d.ts +0 -779
  543. package/dist/hub/protocol.js +0 -93
  544. package/dist/hub/protocol.js.map +0 -1
  545. package/dist/hub/quota.d.ts +0 -24
  546. package/dist/hub/quota.js +0 -112
  547. package/dist/hub/quota.js.map +0 -1
  548. package/dist/hub/representative.d.ts +0 -141
  549. package/dist/hub/representative.js +0 -528
  550. package/dist/hub/representative.js.map +0 -1
  551. package/dist/hub/retention.d.ts +0 -17
  552. package/dist/hub/retention.js +0 -45
  553. package/dist/hub/retention.js.map +0 -1
  554. package/dist/hub/rooms.d.ts +0 -120
  555. package/dist/hub/rooms.js +0 -535
  556. package/dist/hub/rooms.js.map +0 -1
  557. package/dist/hub/runtime.d.ts +0 -106
  558. package/dist/hub/runtime.js +0 -298
  559. package/dist/hub/runtime.js.map +0 -1
  560. package/dist/hub/server.d.ts +0 -56
  561. package/dist/hub/server.js +0 -202
  562. package/dist/hub/server.js.map +0 -1
  563. package/dist/hub/service-start.d.ts +0 -17
  564. package/dist/hub/service-start.js +0 -109
  565. package/dist/hub/service-start.js.map +0 -1
  566. package/dist/hub/sessions.d.ts +0 -53
  567. package/dist/hub/sessions.js +0 -196
  568. package/dist/hub/sessions.js.map +0 -1
  569. package/dist/hub/socket.d.ts +0 -24
  570. package/dist/hub/socket.js +0 -79
  571. package/dist/hub/socket.js.map +0 -1
  572. package/dist/hub/store.d.ts +0 -77
  573. package/dist/hub/store.js +0 -88
  574. package/dist/hub/store.js.map +0 -1
  575. package/dist/hub/tls.d.ts +0 -31
  576. package/dist/hub/tls.js +0 -135
  577. package/dist/hub/tls.js.map +0 -1
  578. package/dist/hub/types.d.ts +0 -401
  579. package/dist/hub/types.js +0 -2
  580. package/dist/hub/types.js.map +0 -1
  581. package/dist/hub/validation.d.ts +0 -33
  582. package/dist/hub/validation.js +0 -136
  583. package/dist/hub/validation.js.map +0 -1
  584. package/dist/hub/version-floor.d.ts +0 -10
  585. package/dist/hub/version-floor.js +0 -45
  586. package/dist/hub/version-floor.js.map +0 -1
  587. package/dist/hub-browser-certificate-policy.d.ts +0 -31
  588. package/dist/hub-browser-certificate-policy.js +0 -25
  589. package/dist/hub-browser-certificate-policy.js.map +0 -1
  590. package/dist/hub-membership-settings.d.ts +0 -6
  591. package/dist/hub-membership-settings.js +0 -21
  592. package/dist/hub-membership-settings.js.map +0 -1
  593. package/dist/hub-mode.d.ts +0 -15
  594. package/dist/hub-mode.js +0 -17
  595. package/dist/hub-mode.js.map +0 -1
  596. package/dist/hub-pairing-summary.d.ts +0 -48
  597. package/dist/hub-pairing-summary.js +0 -36
  598. package/dist/hub-pairing-summary.js.map +0 -1
  599. package/dist/hub-report-target.d.ts +0 -32
  600. package/dist/hub-report-target.js +0 -33
  601. package/dist/hub-report-target.js.map +0 -1
  602. package/dist/hub-retention-policy.d.ts +0 -14
  603. package/dist/hub-retention-policy.js +0 -15
  604. package/dist/hub-retention-policy.js.map +0 -1
  605. package/dist/launchd-service-domain.d.ts +0 -5
  606. package/dist/launchd-service-domain.js +0 -21
  607. package/dist/launchd-service-domain.js.map +0 -1
  608. package/dist/local-pane-endpoint.d.ts +0 -46
  609. package/dist/local-pane-endpoint.js +0 -189
  610. package/dist/local-pane-endpoint.js.map +0 -1
  611. package/dist/local-pane-launcher.d.ts +0 -2
  612. package/dist/local-pane-launcher.js +0 -38
  613. package/dist/local-pane-launcher.js.map +0 -1
  614. package/dist/local-pane-stage.ps1 +0 -101
  615. package/dist/model-catalog-defaults.d.ts +0 -14
  616. package/dist/model-catalog-defaults.js +0 -20
  617. package/dist/model-catalog-defaults.js.map +0 -1
  618. package/dist/native-agent-admission.d.ts +0 -7
  619. package/dist/native-agent-admission.js +0 -26
  620. package/dist/native-agent-admission.js.map +0 -1
  621. package/dist/native-daemon-client.d.ts +0 -13
  622. package/dist/native-daemon-client.js +0 -28
  623. package/dist/native-daemon-client.js.map +0 -1
  624. package/dist/native-instance-api.d.ts +0 -13
  625. package/dist/native-instance-api.js +0 -217
  626. package/dist/native-instance-api.js.map +0 -1
  627. package/dist/native-instance-input.d.ts +0 -87
  628. package/dist/native-instance-input.js +0 -59
  629. package/dist/native-instance-input.js.map +0 -1
  630. package/dist/native-instance-registry.d.ts +0 -38
  631. package/dist/native-instance-registry.js +0 -129
  632. package/dist/native-instance-registry.js.map +0 -1
  633. package/dist/native-mcp.d.ts +0 -43
  634. package/dist/native-mcp.js +0 -291
  635. package/dist/native-mcp.js.map +0 -1
  636. package/dist/native-model-catalog.d.ts +0 -5
  637. package/dist/native-model-catalog.js +0 -76
  638. package/dist/native-model-catalog.js.map +0 -1
  639. package/dist/native-pane-crash-budget.d.ts +0 -20
  640. package/dist/native-pane-crash-budget.js +0 -60
  641. package/dist/native-pane-crash-budget.js.map +0 -1
  642. package/dist/native-pane-create.d.ts +0 -26
  643. package/dist/native-pane-create.js +0 -53
  644. package/dist/native-pane-create.js.map +0 -1
  645. package/dist/native-pane-lifecycle.d.ts +0 -73
  646. package/dist/native-pane-lifecycle.js +0 -239
  647. package/dist/native-pane-lifecycle.js.map +0 -1
  648. package/dist/native-pane-manager.d.ts +0 -59
  649. package/dist/native-pane-manager.js +0 -592
  650. package/dist/native-pane-manager.js.map +0 -1
  651. package/dist/native-pane-output-log.d.ts +0 -15
  652. package/dist/native-pane-output-log.js +0 -108
  653. package/dist/native-pane-output-log.js.map +0 -1
  654. package/dist/native-pane-reconciliation.d.ts +0 -4
  655. package/dist/native-pane-reconciliation.js +0 -40
  656. package/dist/native-pane-reconciliation.js.map +0 -1
  657. package/dist/native-pane-recovery.d.ts +0 -12
  658. package/dist/native-pane-recovery.js +0 -10
  659. package/dist/native-pane-recovery.js.map +0 -1
  660. package/dist/native-pane-tools.d.ts +0 -2
  661. package/dist/native-pane-tools.js +0 -14
  662. package/dist/native-pane-tools.js.map +0 -1
  663. package/dist/office-talk.d.ts +0 -26
  664. package/dist/office-talk.js +0 -50
  665. package/dist/office-talk.js.map +0 -1
  666. package/dist/pane-port.d.ts +0 -118
  667. package/dist/pane-port.js +0 -2
  668. package/dist/pane-port.js.map +0 -1
  669. package/dist/runtime-api.d.ts +0 -10
  670. package/dist/runtime-api.js +0 -189
  671. package/dist/runtime-api.js.map +0 -1
  672. package/dist/runtime-assets/@xterm/addon-serialize/LICENSE +0 -21
  673. package/dist/runtime-assets/@xterm/addon-serialize/lib/addon-serialize.js +0 -2
  674. package/dist/runtime-assets/@xterm/addon-serialize/lib/addon-serialize.mjs +0 -19
  675. package/dist/runtime-assets/@xterm/addon-serialize/package.json +0 -29
  676. package/dist/runtime-assets/@xterm/headless/LICENSE +0 -21
  677. package/dist/runtime-assets/@xterm/headless/lib-headless/xterm-headless.js +0 -2
  678. package/dist/runtime-assets/@xterm/headless/lib-headless/xterm-headless.mjs +0 -46
  679. package/dist/runtime-assets/@xterm/headless/package.json +0 -29
  680. package/dist/runtime-assets/node-pty/CONPTY-LICENSE +0 -21
  681. package/dist/runtime-assets/node-pty/CONPTY-NOTICE.md +0 -503
  682. package/dist/runtime-assets/node-pty/LICENSE +0 -69
  683. package/dist/runtime-assets/node-pty/lib/conpty_console_list_agent.js +0 -16
  684. package/dist/runtime-assets/node-pty/lib/eventEmitter2.js +0 -47
  685. package/dist/runtime-assets/node-pty/lib/index.js +0 -52
  686. package/dist/runtime-assets/node-pty/lib/interfaces.js +0 -7
  687. package/dist/runtime-assets/node-pty/lib/shared/conout.js +0 -11
  688. package/dist/runtime-assets/node-pty/lib/terminal.js +0 -190
  689. package/dist/runtime-assets/node-pty/lib/types.js +0 -7
  690. package/dist/runtime-assets/node-pty/lib/unixTerminal.js +0 -346
  691. package/dist/runtime-assets/node-pty/lib/utils.js +0 -39
  692. package/dist/runtime-assets/node-pty/lib/windowsConoutConnection.js +0 -125
  693. package/dist/runtime-assets/node-pty/lib/windowsPtyAgent.js +0 -320
  694. package/dist/runtime-assets/node-pty/lib/windowsTerminal.js +0 -199
  695. package/dist/runtime-assets/node-pty/lib/worker/conoutSocketWorker.js +0 -22
  696. package/dist/runtime-assets/node-pty/package.json +0 -64
  697. package/dist/runtime-assets/node-pty/prebuilds/win32-arm64/conpty/OpenConsole.exe +0 -0
  698. package/dist/runtime-assets/node-pty/prebuilds/win32-arm64/conpty/conpty.dll +0 -0
  699. package/dist/runtime-assets/node-pty/prebuilds/win32-arm64/conpty.node +0 -0
  700. package/dist/runtime-assets/node-pty/prebuilds/win32-arm64/conpty_console_list.node +0 -0
  701. package/dist/runtime-assets/node-pty/prebuilds/win32-x64/conpty/OpenConsole.exe +0 -0
  702. package/dist/runtime-assets/node-pty/prebuilds/win32-x64/conpty/conpty.dll +0 -0
  703. package/dist/runtime-assets/node-pty/prebuilds/win32-x64/conpty.node +0 -0
  704. package/dist/runtime-assets/node-pty/prebuilds/win32-x64/conpty_console_list.node +0 -0
  705. package/dist/runtime-build-info.d.ts +0 -9
  706. package/dist/runtime-build-info.js +0 -59
  707. package/dist/runtime-build-info.js.map +0 -1
  708. package/dist/runtime-bundle.d.ts +0 -22
  709. package/dist/runtime-bundle.js +0 -158
  710. package/dist/runtime-bundle.js.map +0 -1
  711. package/dist/runtime-cli.d.ts +0 -14
  712. package/dist/runtime-cli.js +0 -271
  713. package/dist/runtime-cli.js.map +0 -1
  714. package/dist/runtime-client-store.d.ts +0 -75
  715. package/dist/runtime-client-store.js +0 -372
  716. package/dist/runtime-client-store.js.map +0 -1
  717. package/dist/runtime-client.d.ts +0 -174
  718. package/dist/runtime-client.js +0 -1010
  719. package/dist/runtime-client.js.map +0 -1
  720. package/dist/runtime-connection.d.ts +0 -22
  721. package/dist/runtime-connection.js +0 -93
  722. package/dist/runtime-connection.js.map +0 -1
  723. package/dist/runtime-coordinator.d.ts +0 -98
  724. package/dist/runtime-coordinator.js +0 -1089
  725. package/dist/runtime-coordinator.js.map +0 -1
  726. package/dist/runtime-credential-profiles.d.ts +0 -78
  727. package/dist/runtime-credential-profiles.js +0 -280
  728. package/dist/runtime-credential-profiles.js.map +0 -1
  729. package/dist/runtime-general-protocol.d.ts +0 -22
  730. package/dist/runtime-general-protocol.js +0 -57
  731. package/dist/runtime-general-protocol.js.map +0 -1
  732. package/dist/runtime-general-workspace.d.ts +0 -17
  733. package/dist/runtime-general-workspace.js +0 -213
  734. package/dist/runtime-general-workspace.js.map +0 -1
  735. package/dist/runtime-install.d.ts +0 -50
  736. package/dist/runtime-install.js +0 -186
  737. package/dist/runtime-install.js.map +0 -1
  738. package/dist/runtime-pane-assets.d.ts +0 -17
  739. package/dist/runtime-pane-assets.js +0 -23
  740. package/dist/runtime-pane-assets.js.map +0 -1
  741. package/dist/runtime-pane-boot.d.ts +0 -9
  742. package/dist/runtime-pane-boot.js +0 -47
  743. package/dist/runtime-pane-boot.js.map +0 -1
  744. package/dist/runtime-pane-codex-index.d.ts +0 -10
  745. package/dist/runtime-pane-codex-index.js +0 -151
  746. package/dist/runtime-pane-codex-index.js.map +0 -1
  747. package/dist/runtime-pane-config.d.ts +0 -16
  748. package/dist/runtime-pane-config.js +0 -54
  749. package/dist/runtime-pane-config.js.map +0 -1
  750. package/dist/runtime-pane-host.d.ts +0 -63
  751. package/dist/runtime-pane-host.js +0 -467
  752. package/dist/runtime-pane-host.js.map +0 -1
  753. package/dist/runtime-pane-job-owner.d.ts +0 -1
  754. package/dist/runtime-pane-job-owner.js +0 -29
  755. package/dist/runtime-pane-job-owner.js.map +0 -1
  756. package/dist/runtime-pane-job.ps1 +0 -116
  757. package/dist/runtime-pane-link.d.ts +0 -47
  758. package/dist/runtime-pane-link.js +0 -337
  759. package/dist/runtime-pane-link.js.map +0 -1
  760. package/dist/runtime-pane-mcp-protocol.d.ts +0 -32
  761. package/dist/runtime-pane-mcp-protocol.js +0 -39
  762. package/dist/runtime-pane-mcp-protocol.js.map +0 -1
  763. package/dist/runtime-pane-mcp-relay.d.ts +0 -18
  764. package/dist/runtime-pane-mcp-relay.js +0 -80
  765. package/dist/runtime-pane-mcp-relay.js.map +0 -1
  766. package/dist/runtime-pane-mcp.d.ts +0 -55
  767. package/dist/runtime-pane-mcp.js +0 -153
  768. package/dist/runtime-pane-mcp.js.map +0 -1
  769. package/dist/runtime-pane-native.d.ts +0 -75
  770. package/dist/runtime-pane-native.js +0 -114
  771. package/dist/runtime-pane-native.js.map +0 -1
  772. package/dist/runtime-pane-output.d.ts +0 -19
  773. package/dist/runtime-pane-output.js +0 -53
  774. package/dist/runtime-pane-output.js.map +0 -1
  775. package/dist/runtime-pane-port.d.ts +0 -144
  776. package/dist/runtime-pane-port.js +0 -574
  777. package/dist/runtime-pane-port.js.map +0 -1
  778. package/dist/runtime-pane-private.d.ts +0 -14
  779. package/dist/runtime-pane-private.js +0 -51
  780. package/dist/runtime-pane-private.js.map +0 -1
  781. package/dist/runtime-pane-private.ps1 +0 -14
  782. package/dist/runtime-pane-process.d.ts +0 -4
  783. package/dist/runtime-pane-process.js +0 -117
  784. package/dist/runtime-pane-process.js.map +0 -1
  785. package/dist/runtime-pane-protocol.d.ts +0 -182
  786. package/dist/runtime-pane-protocol.js +0 -217
  787. package/dist/runtime-pane-protocol.js.map +0 -1
  788. package/dist/runtime-pane-quota-history.d.ts +0 -6
  789. package/dist/runtime-pane-quota-history.js +0 -44
  790. package/dist/runtime-pane-quota-history.js.map +0 -1
  791. package/dist/runtime-pane-screen.d.ts +0 -19
  792. package/dist/runtime-pane-screen.js +0 -76
  793. package/dist/runtime-pane-screen.js.map +0 -1
  794. package/dist/runtime-pane-service.d.ts +0 -16
  795. package/dist/runtime-pane-service.js +0 -256
  796. package/dist/runtime-pane-service.js.map +0 -1
  797. package/dist/runtime-pane-stdio-protocol.d.ts +0 -54
  798. package/dist/runtime-pane-stdio-protocol.js +0 -94
  799. package/dist/runtime-pane-stdio-protocol.js.map +0 -1
  800. package/dist/runtime-pane-stdio.d.ts +0 -3
  801. package/dist/runtime-pane-stdio.js +0 -123
  802. package/dist/runtime-pane-stdio.js.map +0 -1
  803. package/dist/runtime-pane-store.d.ts +0 -33
  804. package/dist/runtime-pane-store.js +0 -164
  805. package/dist/runtime-pane-store.js.map +0 -1
  806. package/dist/runtime-pane-transcript-protocol.d.ts +0 -43
  807. package/dist/runtime-pane-transcript-protocol.js +0 -58
  808. package/dist/runtime-pane-transcript-protocol.js.map +0 -1
  809. package/dist/runtime-pane-transcript.d.ts +0 -50
  810. package/dist/runtime-pane-transcript.js +0 -666
  811. package/dist/runtime-pane-transcript.js.map +0 -1
  812. package/dist/runtime-pane-worker.d.ts +0 -1
  813. package/dist/runtime-pane-worker.js +0 -167
  814. package/dist/runtime-pane-worker.js.map +0 -1
  815. package/dist/runtime-protocol.d.ts +0 -177
  816. package/dist/runtime-protocol.js +0 -49
  817. package/dist/runtime-protocol.js.map +0 -1
  818. package/dist/runtime-switches.d.ts +0 -79
  819. package/dist/runtime-switches.js +0 -90
  820. package/dist/runtime-switches.js.map +0 -1
  821. package/dist/runtime-transcript-delta-reader.d.ts +0 -23
  822. package/dist/runtime-transcript-delta-reader.js +0 -74
  823. package/dist/runtime-transcript-delta-reader.js.map +0 -1
  824. package/dist/runtime-transcript-source.d.ts +0 -36
  825. package/dist/runtime-transcript-source.js +0 -189
  826. package/dist/runtime-transcript-source.js.map +0 -1
  827. package/dist/runtime-update-activity.d.ts +0 -21
  828. package/dist/runtime-update-activity.js +0 -51
  829. package/dist/runtime-update-activity.js.map +0 -1
  830. package/dist/runtime-update-artifact.d.ts +0 -31
  831. package/dist/runtime-update-artifact.js +0 -252
  832. package/dist/runtime-update-artifact.js.map +0 -1
  833. package/dist/runtime-update-install.d.ts +0 -31
  834. package/dist/runtime-update-install.js +0 -205
  835. package/dist/runtime-update-install.js.map +0 -1
  836. package/dist/runtime-update-journal.d.ts +0 -44
  837. package/dist/runtime-update-journal.js +0 -121
  838. package/dist/runtime-update-journal.js.map +0 -1
  839. package/dist/runtime-update-lock.d.ts +0 -48
  840. package/dist/runtime-update-lock.js +0 -217
  841. package/dist/runtime-update-lock.js.map +0 -1
  842. package/dist/runtime-update-owners.d.ts +0 -29
  843. package/dist/runtime-update-owners.js +0 -240
  844. package/dist/runtime-update-owners.js.map +0 -1
  845. package/dist/runtime-update-protocol.d.ts +0 -15
  846. package/dist/runtime-update-protocol.js +0 -13
  847. package/dist/runtime-update-protocol.js.map +0 -1
  848. package/dist/runtime-windows-bridge.d.ts +0 -42
  849. package/dist/runtime-windows-bridge.js +0 -167
  850. package/dist/runtime-windows-bridge.js.map +0 -1
  851. package/dist/service-drain.d.ts +0 -19
  852. package/dist/service-drain.js +0 -64
  853. package/dist/service-drain.js.map +0 -1
  854. package/dist/settings-route-lifetime.d.ts +0 -14
  855. package/dist/settings-route-lifetime.js +0 -48
  856. package/dist/settings-route-lifetime.js.map +0 -1
  857. package/dist/tmux-binary.d.ts +0 -59
  858. package/dist/tmux-binary.js +0 -200
  859. package/dist/tmux-binary.js.map +0 -1
  860. package/dist/tmux-pane-host.d.ts +0 -26
  861. package/dist/tmux-pane-host.js +0 -25
  862. package/dist/tmux-pane-host.js.map +0 -1
  863. package/dist/transcript-needles.d.ts +0 -42
  864. package/dist/transcript-needles.js +0 -166
  865. package/dist/transcript-needles.js.map +0 -1
  866. package/dist/transcript-records.d.ts +0 -21
  867. package/dist/transcript-records.js +0 -141
  868. package/dist/transcript-records.js.map +0 -1
  869. package/dist/ui/account-identity.js +0 -27
  870. package/dist/ui/accounts-view.js +0 -214
  871. package/dist/ui/agent-proposals.js +0 -90
  872. package/dist/ui/agent-runtime-settings.js +0 -68
  873. package/dist/ui/agent-runtime.js +0 -124
  874. package/dist/ui/cli-picker.js +0 -42
  875. package/dist/ui/credential-profile-select.js +0 -54
  876. package/dist/ui/fleet-office-dialogue.d.ts +0 -30
  877. package/dist/ui/fleet-office-dialogue.js +0 -382
  878. package/dist/ui/fleet-task-menu.js +0 -188
  879. package/dist/ui/fleet-task-stats.js +0 -124
  880. package/dist/ui/fleet-task-view.js +0 -340
  881. package/dist/ui/general-location.js +0 -71
  882. package/dist/ui/hub-agent-copy.js +0 -23
  883. package/dist/ui/hub-button-actions.js +0 -65
  884. package/dist/ui/hub-chat-store.js +0 -158
  885. package/dist/ui/hub-chat-strings.js +0 -77
  886. package/dist/ui/hub-client.js +0 -329
  887. package/dist/ui/hub-owner-strings.js +0 -51
  888. package/dist/ui/hub-provider-guidance.js +0 -31
  889. package/dist/ui/hub-quota.js +0 -85
  890. package/dist/ui/hub-strings.js +0 -162
  891. package/dist/ui/hub-switcher.js +0 -27
  892. package/dist/ui/native-instance-settings.js +0 -44
  893. package/dist/ui/native-pane-recovery.js +0 -45
  894. package/dist/ui/panel-hub.js +0 -619
  895. package/dist/ui/panel-runtimes.js +0 -425
  896. package/dist/ui/panel-windows-agent.js +0 -86
  897. package/dist/ui/panel-windows-cli.js +0 -189
  898. package/dist/ui/provider-marks.js +0 -83
  899. package/dist/ui/runtime-catalog.js +0 -55
  900. package/dist/ui/runtime-commands.d.ts +0 -4
  901. package/dist/ui/runtime-commands.js +0 -59
  902. package/dist/ui/settings-access-strings.js +0 -42
  903. package/dist/ui/settings-agent-filters.js +0 -94
  904. package/dist/ui/settings-build-version.js +0 -35
  905. package/dist/ui/settings-devices.js +0 -253
  906. package/dist/ui/settings-hub-browser-certificate.js +0 -74
  907. package/dist/ui/settings-hub-membership.js +0 -72
  908. package/dist/ui/settings-hub-retention.js +0 -52
  909. package/dist/ui/settings-hub.js +0 -196
  910. package/dist/ui/settings-layout.js +0 -242
  911. package/dist/ui/settings-outside.js +0 -242
  912. package/dist/ui/settings-shared-strings.js +0 -143
  913. package/dist/ui/settings-shared.js +0 -345
  914. package/dist/ui/settings-shortcuts.js +0 -65
  915. package/dist/ui/shared/accounts.css +0 -15
  916. package/dist/ui/shared/chat-composer.js +0 -68
  917. package/dist/ui/shared/chat-md-strings.js +0 -9
  918. package/dist/ui/shared/chat-render.js +0 -682
  919. package/dist/ui/shared/chat-strings.js +0 -333
  920. package/dist/ui/shared/chat-thread.js +0 -969
  921. package/dist/ui/shared/chat-time.js +0 -80
  922. package/dist/ui/shared/html-attachment.js +0 -42
  923. package/dist/ui/shared/hub-chat.css +0 -85
  924. package/dist/ui/shared/hub-owner.css +0 -33
  925. package/dist/ui/shared/hub-quota.css +0 -8
  926. package/dist/ui/shared/hub.css +0 -71
  927. package/dist/ui/shared/machine-name.js +0 -13
  928. package/dist/ui/shared/page-head.js +0 -8
  929. package/dist/ui/shared/preview.js +0 -476
  930. package/dist/ui/shared/qrcode.module.js +0 -2237
  931. package/dist/ui/shared/runtime-install.css +0 -26
  932. package/dist/ui/shared/settings-width.js +0 -31
  933. package/dist/ui/shared/side-rail.js +0 -15
  934. package/dist/ui/shared/task-board.css +0 -95
  935. package/dist/ui/shared/vendor/qrcode-generator.LICENSE +0 -27
  936. package/dist/ui/shared/workspace.css +0 -20
  937. package/dist/ui/windows-agents-nav.js +0 -2
  938. package/dist/ui/windows-cli-catalog.js +0 -108
  939. package/dist/ui/workspace-panel.js +0 -189
  940. package/dist/ui/workspace-strings.js +0 -35
  941. package/dist/web-device-login.d.ts +0 -153
  942. package/dist/web-device-login.js +0 -278
  943. package/dist/web-device-login.js.map +0 -1
  944. package/dist/web-remote-access.d.ts +0 -152
  945. package/dist/web-remote-access.js +0 -368
  946. package/dist/web-remote-access.js.map +0 -1
  947. package/dist/windows-agents.d.ts +0 -127
  948. package/dist/windows-agents.js +0 -491
  949. package/dist/windows-agents.js.map +0 -1
  950. package/dist/windows-cli-api.d.ts +0 -34
  951. package/dist/windows-cli-api.js +0 -185
  952. package/dist/windows-cli-api.js.map +0 -1
  953. package/dist/windows-cli-providers.d.ts +0 -106
  954. package/dist/windows-cli-providers.js +0 -424
  955. package/dist/windows-cli-providers.js.map +0 -1
  956. package/dist/windows-cli-worker.d.ts +0 -83
  957. package/dist/windows-cli-worker.js +0 -570
  958. package/dist/windows-cli-worker.js.map +0 -1
  959. package/dist/windows-cli.d.ts +0 -126
  960. package/dist/windows-cli.js +0 -416
  961. package/dist/windows-cli.js.map +0 -1
  962. package/dist/windows-native-mcp.d.ts +0 -19
  963. package/dist/windows-native-mcp.js +0 -143
  964. package/dist/windows-native-mcp.js.map +0 -1
  965. package/dist/windows-pane-mcp.d.ts +0 -26
  966. package/dist/windows-pane-mcp.js +0 -187
  967. package/dist/windows-pane-mcp.js.map +0 -1
  968. package/launcher/launchd-session-type.cjs +0 -14
  969. package/launcher/tmux-bundle.cjs +0 -247
  970. package/templates/runtime-assets/conpty-LICENSE +0 -21
  971. package/templates/runtime-assets/conpty-NOTICE.md +0 -503
  972. package/templates/runtime-assets/local-pane-stage.ps1 +0 -101
  973. package/templates/runtime-assets/runtime-pane-job.ps1 +0 -116
  974. package/templates/runtime-assets/runtime-pane-private.ps1 +0 -14
  975. package/templates/runtime-assets/xterm-LICENSE +0 -21
  976. package/templates/runtime-install/install.ps1 +0 -270
package/dist/daemon.js CHANGED
@@ -1,5 +1,4 @@
1
- import { nativePaneToolRefusal } from "./native-pane-tools.js";
2
- import { generalByName } from "./general-instance.js";
1
+ import { quotaNoticeProblem } from "./quota-notice-config.js";
3
2
  import { quotaHistoryCount, quotaAfterInput } from "./pane-quota-history.js";
4
3
  import { dialogScreenText } from "./dialog-screen-text.js";
5
4
  import { readActiveKiroModel } from "./backend/kiro.js";
@@ -23,7 +22,7 @@ import { assertNoSessionOomStop, readSessionOomStop, writeSessionOomStop, Sessio
23
22
  import { mcpServerState } from "./mcp-liveness.js";
24
23
  import { clearPausedMarker, writePausedMarker } from "./pause-marker.js";
25
24
  import { writeBackgroundWorkEndedMarker } from "./background-work-ended.js";
26
- import { resolveTmuxLogicalSize } from "./tmux-manager.js";
25
+ import { TmuxManager, resolveTmuxLogicalSize } from "./tmux-manager.js";
27
26
  import { TranscriptMonitor } from "./transcript-monitor.js";
28
27
  import { createTranscriptSource } from "./transcript-sources.js";
29
28
  import { TranscriptTurnLedger } from "./transcript-turns.js";
@@ -51,7 +50,6 @@ import { HangDetector } from "./hang-detector.js";
51
50
  import { writeSecretFile } from "./secret-file.js";
52
51
  import { PaneWriteLock } from "./pane-write-lock.js";
53
52
  import { answerRemoteCard } from "./remote-card-answer.js";
54
- import { tmuxPaneHost } from "./tmux-pane-host.js";
55
53
  import { buildFleetInstructions } from "./instructions.js";
56
54
  import { formatHumanInboundMessage, prepareDeliveryWire, steerInboundEnvelope, BTW_INBOUND_PREFIX, humanBodyHash, humanOwnerObjectId } from "./human-delivery-receipts.js";
57
55
  import { formatCrossInstanceInboundMessage, renderCrossInstanceHandoffMetadata, } from "./cross-instance-envelope.js";
@@ -61,7 +59,6 @@ import { CLAUDE_CREDIT_BALANCE_LOW, CLAUDE_MODEL_USAGE_LIMIT, CLAUDE_USAGE_LIMIT
61
59
  import { t } from "./locale.js";
62
60
  import { claudeResetInstant, claudeResetTime, quotaPausedLine } from "./quota-notice.js";
63
61
  import { MuseUsageRelay, clearMuseUsageSnapshot } from "./muse-usage-relay.js";
64
- import { reconcileNativePaneTarget } from "./native-pane-reconciliation.js";
65
62
  import { deliveryContentDigest } from "./delivery-outbox.js";
66
63
  import { consumedWatches } from "./delivery-consumed-watch.js";
67
64
  import { queueResumePolicyForAttempt } from "./delivery-queue-evidence.js";
@@ -1121,7 +1118,6 @@ export class Daemon extends EventEmitter {
1121
1118
  spawnGate;
1122
1119
  stormWindow;
1123
1120
  backendOutage;
1124
- paneTransport;
1125
1121
  /** #1314: fleet-directory fallbacks already reported to the topic (once per daemon, per field and path). */
1126
1122
  promptFileFallbackNoticed = new Set();
1127
1123
  /** Identity of this live Daemon object; changes on object stop/restart. */
@@ -1800,7 +1796,6 @@ export class Daemon extends EventEmitter {
1800
1796
  // still booting. Its new tmux window starts empty before resume restores the
1801
1797
  // old transcript, so pre-ready scans must not lower this seeded baseline.
1802
1798
  seededErrorCountBaselines = new Map();
1803
- nativeQuotaReplayTaken = false;
1804
1799
  quotaReplay = null;
1805
1800
  paneQuotaPatterns() {
1806
1801
  if (!["codex", "grok"].includes(this.backend?.binaryName ?? ""))
@@ -1836,11 +1831,7 @@ export class Daemon extends EventEmitter {
1836
1831
  }
1837
1832
  /** Before admission, this launch may absorb ONLY rows positively known before its resume. */
1838
1833
  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);
1834
+ const history = this.quotaReplay;
1844
1835
  if (!history)
1845
1836
  return;
1846
1837
  this.quotaReplay = null;
@@ -1906,15 +1897,6 @@ export class Daemon extends EventEmitter {
1906
1897
  static USAGE_PAUSE_NOTICE_WINDOW_MS = 30 * 60_000;
1907
1898
  /** The usage-pause notice told last: when (monotonic), Claude's words for the reset, and that reset (wall clock). */
1908
1899
  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
1900
  /**
1919
1901
  * #2834 (#816): Claude paused itself until its usage window opens — the same notice the screen pattern gave. `at`: when
1920
1902
  * Claude wrote it (its record's timestamp). One notice per pause: a reset time already past is not this pause (an old
@@ -2081,94 +2063,9 @@ export class Daemon extends EventEmitter {
2081
2063
  this.errorRecoveryDeadlineAt = 0;
2082
2064
  this.activeErrorPatternKey = null;
2083
2065
  }
2084
- /** Lazy default also preserves bare-prototype diagnostic/test construction. */
2085
- get paneHost() { return this.paneTransport ?? tmuxPaneHost; }
2086
- nativePaneLifecycle;
2087
- nativeFleetBridge;
2088
- nativeTranscriptSource;
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
- } }
2097
- logNativeInputRefusal(details) {
2098
- this.logger.warn({ component: "runtime-pane-host", reason: "expected_seq_changed", ...details }, "Native pane input refused before write");
2099
- }
2100
- logNativeToolFailure(details) {
2101
- const turn = this.turnReplyGuard.snapshot();
2102
- this.logger.warn({ ...details, currentMessageId: turn?.target.messageId ?? null,
2103
- guardGeneration: turn?.generation ?? null, guardPhase: turn?.phase ?? null }, "Native pane tool operation failed");
2104
- }
2105
- nativePaneCurrent() { return this.nativePaneLifecycle?.current() ?? false; }
2106
- nativeEnterHold = null;
2107
- /** Per-launch attention for a native delivery whose bounded input attempts were refused or uncertain, including non-outbox input. */
2108
- nativeDeliveryHold() {
2109
- const hold = this.nativeEnterHold;
2110
- return hold && this.nativePaneLifecycle && !this.deliveryWritesStopping && hold.spawn === this.spawnGeneration && hold.fence === this.launchFenceEpoch
2111
- ? { key: hold.key, since: hold.since } : null;
2112
- }
2113
- nativePaneHasExited() {
2114
- const snapshot = this.nativePaneLifecycle?.snapshot?.();
2115
- return snapshot?.state === "exited" && snapshot.instance === this.name && this.tmux?.getWindowId() === snapshot.paneId;
2116
- }
2117
- /** Positive native exit evidence only, fenced to this exact launch and Daemon owner. */
2118
- nativePaneExitCurrent(snapshot, owner) {
2119
- const actual = this.nativePaneLifecycle?.snapshot?.();
2120
- return !!actual && actual.state === "exited" && snapshot.state === "exited"
2121
- && sameInteractionOwner(owner, this.interactionOwner()) && !this.runtimeMonitorsFrozen && !this.startupAborted
2122
- && ["hostBootId", "paneId", "launchId", "agentId", "instance", "sessionId", "commandSequence", "exitCode"].every(key => actual[key] === snapshot[key])
2123
- && this.tmux?.getWindowId() === snapshot.paneId;
2124
- }
2125
- async reconcileNativeDeliveries(outbox, current) {
2126
- if (!this.nativePaneLifecycle)
2127
- return false;
2128
- return reconcileNativePaneTarget(outbox, this.name, this.nativePaneLifecycle, current);
2129
- }
2130
- /** Same-process transport for the owned native daemon; never exposed as a runner RPC. */
2131
- setNativeFleetBridge(bridge) {
2132
- if (!this.nativePaneLifecycle || this.nativeFleetBridge?.current())
2133
- throw Error("Native Fleet bridge requires one bound pane owner");
2134
- this.nativeFleetBridge = bridge;
2135
- }
2136
- /** Fleet admission and generation checks happen before this synchronous handoff. */
2137
- acceptNativeFleetMessage(message) {
2138
- if (!this.nativePaneLifecycle || !this.nativeFleetBridge?.current() || this.deliveryWritesStopping || this.runtimeMonitorsFrozen)
2139
- return false;
2140
- if (typeof message.type === "string" && FLEET_RESPONSE_TYPES.has(message.type)) {
2141
- this.routeFleetResponse(message);
2142
- return true;
2143
- }
2144
- const bridge = this.nativeFleetBridge;
2145
- const current = () => this.nativeFleetBridge === bridge && bridge.current() && !this.deliveryWritesStopping && !this.runtimeMonitorsFrozen;
2146
- return this.handleFleetMessage(message, reply => { if (current())
2147
- this.broadcastFleetMessage(reply); }, current);
2148
- }
2149
- broadcastFleetMessage(message) {
2150
- if (this.nativePaneLifecycle) {
2151
- if (this.nativeFleetBridge?.current() && !this.runtimeMonitorsFrozen && !this.deliveryWritesStopping)
2152
- this.nativeFleetBridge.send(message);
2153
- }
2154
- else
2155
- this.ipcServer?.broadcast(message);
2156
- }
2157
- fleetTransportAvailable() {
2158
- return this.nativePaneLifecycle ? !!this.nativeFleetBridge?.current() && !this.runtimeMonitorsFrozen : !!this.ipcServer;
2159
- }
2160
- /** Internal lifecycle injection, before start. Native paths and provider files stay on their runner. */
2161
- setNativePaneLifecycle(native) {
2162
- if (this.tmux || this.ipcServer || this.nativePaneLifecycle)
2163
- throw Error("Native pane adapter must be bound before daemon startup");
2164
- this.nativePaneLifecycle = native;
2165
- this.backend = native.backend;
2166
- this.paneTransport = native.host;
2167
- this.controlClient = native.observation;
2168
- }
2169
2066
  constructor(name, config, instanceDir, topicMode = false, backend, controlClient, rootLogger, runtimeIdentity, spawnGate, stormWindow,
2170
2067
  /** Fleet-level "is this CLI's backend down?" memory — see backend-outage.ts. */
2171
- backendOutage, paneTransport) {
2068
+ backendOutage) {
2172
2069
  super();
2173
2070
  this.name = name;
2174
2071
  this.config = config;
@@ -2180,7 +2077,6 @@ export class Daemon extends EventEmitter {
2180
2077
  this.spawnGate = spawnGate;
2181
2078
  this.stormWindow = stormWindow;
2182
2079
  this.backendOutage = backendOutage;
2183
- this.paneTransport = paneTransport;
2184
2080
  // The live process owns its adopted configuration. Fleet defaults may be re-resolved in place after a save;
2185
2081
  // sharing that object would activate cold changes before the normal restart/apply boundary.
2186
2082
  this.config = structuredClone(config);
@@ -2203,8 +2099,7 @@ export class Daemon extends EventEmitter {
2203
2099
  this.messageBus.setLogger(this.logger);
2204
2100
  // General is the dispatcher — it must stay warm to route messages, so it is
2205
2101
  // never auto-paused regardless of auto_pause_after.
2206
- // #3035 review: the one rule (an agent named general unticked — general_topic: false — is a worker).
2207
- const isGeneral = config.general_topic === true || generalByName(name, config);
2102
+ const isGeneral = config.general_topic === true || name === "general";
2208
2103
  const autoPauseMinutes = isGeneral ? 0 : (typeof config.auto_pause_after === "number" ? config.auto_pause_after : 0); // default: disabled
2209
2104
  this.autoPauseController = new AutoPauseController(Math.max(0, autoPauseMinutes) * 60_000, readLastInboundAt(instanceDir) ?? Date.now());
2210
2105
  // #1209: every real completion clears the in-flight marker, so a
@@ -2266,19 +2161,12 @@ export class Daemon extends EventEmitter {
2266
2161
  return outcome === "begun";
2267
2162
  }
2268
2163
  async durableAttemptEvidence(windowId, handingOffToNativeQueue, steer, rawPaste = false) {
2269
- let checkpoint = null, runtimeTranscript = null;
2270
- if (this.nativePaneLifecycle) {
2271
- runtimeTranscript = await this.transcriptMonitor?.reconciliationRuntimeCheckpoint() ?? null;
2272
- if (!runtimeTranscript || !this.nativePaneLifecycle.current(runtimeTranscript))
2273
- throw Error("Native transcript checkpoint is not current; no delivery was written");
2164
+ let checkpoint = null;
2165
+ try {
2166
+ checkpoint = await this.transcriptMonitor?.reconciliationCheckpoint() ?? null;
2274
2167
  }
2275
- else {
2276
- try {
2277
- checkpoint = await this.transcriptMonitor?.reconciliationCheckpoint() ?? null;
2278
- }
2279
- catch (err) {
2280
- this.logger.debug({ err }, "Could not checkpoint transcript before durable delivery");
2281
- }
2168
+ catch (err) {
2169
+ this.logger.debug({ err }, "Could not checkpoint transcript before durable delivery");
2282
2170
  }
2283
2171
  const submissionMode = rawPaste ? "raw_paste" : steer
2284
2172
  ? "steer"
@@ -2294,9 +2182,8 @@ export class Daemon extends EventEmitter {
2294
2182
  backendVersion,
2295
2183
  windowId: windowId ?? this.tmux?.getWindowId() ?? null,
2296
2184
  transcriptPath: checkpoint?.path ?? null,
2297
- transcriptOffset: runtimeTranscript?.cursor.offset ?? checkpoint?.offset ?? null,
2298
- transcriptSessionId: runtimeTranscript?.cursor.sessionId ?? checkpoint?.sessionId ?? null,
2299
- ...(runtimeTranscript ? { runtimeTranscript } : {}),
2185
+ transcriptOffset: checkpoint?.offset ?? null,
2186
+ transcriptSessionId: checkpoint?.sessionId ?? null,
2300
2187
  submissionMode,
2301
2188
  queueResumePolicy: queueResumePolicyForAttempt(backend, backendVersion, submissionMode),
2302
2189
  };
@@ -2339,25 +2226,17 @@ export class Daemon extends EventEmitter {
2339
2226
  const outbox = this.deliveryOutbox;
2340
2227
  if (!checkpoint || !outbox?.markConsumed)
2341
2228
  return;
2342
- if (this.nativePaneLifecycle && !checkpoint.runtime)
2343
- return;
2344
2229
  if (verdict.submissionMode !== "steer" && verdict.submissionMode !== "native_queue_handoff")
2345
2230
  return;
2346
2231
  if (!["claude-code", "codex"].includes(checkpoint.backend))
2347
2232
  return;
2348
2233
  const spawn = this.spawnGeneration, fence = this.launchFenceEpoch, boot = this.bootId;
2349
- let location;
2350
- try {
2351
- location = checkpoint.runtime ? { reader: this.nativeTranscriptReader(checkpoint.runtime, delivery.deliveryId) } : { path: checkpoint.path, offset: checkpoint.offset };
2352
- }
2353
- catch {
2354
- return;
2355
- } // The owner changed; an unavailable consumed watch proves nothing.
2356
2234
  consumedWatches.start({
2357
2235
  deliveryId: delivery.deliveryId,
2358
2236
  attemptNo: delivery.attemptNo,
2359
2237
  backend: checkpoint.backend,
2360
- ...location,
2238
+ path: checkpoint.path,
2239
+ offset: checkpoint.offset,
2361
2240
  current: () => !this.deliveryWritesStopping && spawn === this.spawnGeneration && fence === this.launchFenceEpoch,
2362
2241
  consumed: (via, evidence) => {
2363
2242
  try {
@@ -2399,18 +2278,15 @@ export class Daemon extends EventEmitter {
2399
2278
  : humanVerificationId ? `[agend-human-id:${humanVerificationId}]` : null;
2400
2279
  if (!marker || !formatted.startsWith(marker))
2401
2280
  return;
2402
- let found = verdict.transcriptCheckpoint ?? null;
2403
- if (!found) {
2281
+ let checkpoint = verdict.transcriptCheckpoint ?? null;
2282
+ if (!checkpoint) {
2404
2283
  try {
2405
- found = await this.transcriptMonitor?.reconciliationCheckpoint() ?? null;
2284
+ checkpoint = await this.transcriptMonitor?.reconciliationCheckpoint() ?? null;
2406
2285
  }
2407
2286
  catch (err) {
2408
2287
  this.logger.debug({ err }, "Could not checkpoint the transcript before a queued hand-off");
2409
2288
  }
2410
2289
  }
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
2290
  if (!checkpoint)
2415
2291
  return; // nothing could judge it later: it runs as before (✅ at the hand-off)
2416
2292
  const entry = {
@@ -2678,34 +2554,24 @@ export class Daemon extends EventEmitter {
2678
2554
  const spawn = this.spawnGeneration;
2679
2555
  const fence = this.launchFenceEpoch;
2680
2556
  let last = "unavailable";
2681
- const native = !!checkpoint.runtime || !!this.nativePaneLifecycle;
2682
- let outcome = native ? "uncertain" : "delivered";
2683
- let evidence = native ? "runtime-transcript-unconfirmed" : OUTPUT_EDGE_ONLY_EVIDENCE;
2557
+ let outcome = "delivered";
2558
+ let evidence = OUTPUT_EDGE_ONLY_EVIDENCE;
2684
2559
  // #1647: a raw paste has no marker; its text is the needle, and its pane proof already failed — so without the turn
2685
2560
  // in the transcript it stays uncertain (with the pane's reason), never the output-edge outcome.
2686
2561
  const needle = rawPaste ? { rawText: rawPaste.text } : delivery.deliveryId;
2687
2562
  let found = false;
2688
2563
  try {
2689
- if (this.nativePaneLifecycle && !checkpoint.runtime)
2690
- throw Error("Native proof cannot read a coordinator-local transcript path");
2691
- const nativeReader = checkpoint.runtime ? this.nativeTranscriptReader(checkpoint.runtime, needle) : null;
2692
2564
  for (let polls = 0; polls <= TRANSCRIPT_PROOF_WINDOW_MS / TRANSCRIPT_PROOF_POLL_MS; polls++) {
2693
2565
  if (this.deliveryWritesStopping)
2694
2566
  return; // reconciliation owns the row now
2695
- const look = nativeReader ? await nativeReader.look() : await scanTranscriptForDeliveryMarker(checkpoint.path, checkpoint.offset, checkpoint.backend, needle);
2696
- if (this.deliveryWritesStopping)
2697
- return;
2698
- if (spawn !== this.spawnGeneration || fence !== this.launchFenceEpoch) {
2699
- last = "unavailable";
2700
- break;
2701
- }
2567
+ const look = await scanTranscriptForDeliveryMarker(checkpoint.path, checkpoint.offset, checkpoint.backend, needle);
2702
2568
  if (look === "user" || look === "absorbed" || look === "queued") {
2703
2569
  found = true;
2704
2570
  outcome = "delivered";
2705
2571
  evidence = transcriptMarkerEvidence(look, !!rawPaste);
2706
2572
  break;
2707
2573
  }
2708
- last = look === "pending" ? "unavailable" : look;
2574
+ last = look;
2709
2575
  if (spawn !== this.spawnGeneration || fence !== this.launchFenceEpoch) {
2710
2576
  last = "unavailable";
2711
2577
  break;
@@ -2717,13 +2583,13 @@ export class Daemon extends EventEmitter {
2717
2583
  // `uncertain`: re-check the same fixed epochs after the last await, before settling (#1207 P2).
2718
2584
  if (spawn !== this.spawnGeneration || fence !== this.launchFenceEpoch)
2719
2585
  last = "unavailable";
2720
- if (last === "no-match" && !found) {
2586
+ if (last === "no-match" && evidence === OUTPUT_EDGE_ONLY_EVIDENCE) {
2721
2587
  outcome = "uncertain";
2722
2588
  evidence = "unverifiable-no-transcript-marker";
2723
2589
  }
2724
2590
  }
2725
2591
  catch (err) {
2726
- this.logger.debug({ err }, "Transcript proof unavailable — preserving the conservative outcome");
2592
+ this.logger.debug({ err }, "Transcript proof of a delivery failed — keeping the output-edge outcome");
2727
2593
  }
2728
2594
  if (rawPaste && !found) {
2729
2595
  outcome = "uncertain";
@@ -2910,143 +2776,128 @@ export class Daemon extends EventEmitter {
2910
2776
  }
2911
2777
  }
2912
2778
  catch { /* corrupt/missing — ignore */ }
2913
- if (!this.nativePaneLifecycle) {
2914
- // 1. IPC server — bridge between MCP server (Claude's child) and daemon
2915
- const sockPath = join(this.instanceDir, "channel.sock");
2916
- this.ipcServer = new IpcServer(sockPath, this.logger);
2917
- // Forward IPC server errors as daemon events (prevents unhandled 'error' crash).
2918
- // Guard: only forward post-listen errors — startup errors are handled by listen() rejection.
2919
- let ipcListening = false;
2920
- this.ipcServer.on("error", (err) => {
2921
- if (!ipcListening)
2922
- return; // startup errors handled by listen() rejection
2923
- this.logger.error({ err, name: this.name }, "IPC server error");
2924
- this.emit("error", err);
2925
- });
2926
- await this.ipcServer.listen();
2927
- this.startupAdmission?.();
2928
- ipcListening = true;
2929
- // Permanent IPC dispatcher: routes responses to pending requests by type+id key
2930
- this.ipcServer.on("message", (msg) => this.routeFleetResponse(msg));
2931
- // IPC message relay: when daemon wants to push a channel message to Claude,
2932
- // it broadcasts to all IPC clients (the MCP server is one of them).
2933
- // When MCP server sends a tool_call, daemon handles it via the messageBus.
2934
- this.ipcServer.on("message", (msg, socket) => {
2935
- if (msg.type === "tool_call") {
2936
- // MCP server forwarding a Claude tool call (reply, react, edit, download)
2937
- this.handleToolCall(msg, socket);
2938
- }
2939
- else if (msg.type === "mcp_ready") {
2940
- this.handleMcpReady(msg, socket);
2941
- }
2942
- else if (msg.type === "pong") {
2943
- this.handleMcpPong(msg, socket);
2944
- }
2945
- else if (msg.type === "query_sessions") {
2946
- // Fleet manager asks for all registered session names (catches sessions
2947
- // that sent mcp_ready before fleet manager connected).
2948
- const sessions = [];
2949
- for (const [s, sessionName] of this.socketSessionNames) {
2950
- if (!s.destroyed && sessionName !== this.name) {
2951
- // Individual mcp_ready for initial registration path
2952
- this.ipcServer?.send(socket, { type: "mcp_ready", sessionName });
2953
- sessions.push(sessionName);
2954
- }
2779
+ // 1. IPC server — bridge between MCP server (Claude's child) and daemon
2780
+ const sockPath = join(this.instanceDir, "channel.sock");
2781
+ this.ipcServer = new IpcServer(sockPath, this.logger);
2782
+ // Forward IPC server errors as daemon events (prevents unhandled 'error' crash).
2783
+ // Guard: only forward post-listen errors — startup errors are handled by listen() rejection.
2784
+ let ipcListening = false;
2785
+ this.ipcServer.on("error", (err) => {
2786
+ if (!ipcListening)
2787
+ return; // startup errors handled by listen() rejection
2788
+ this.logger.error({ err, name: this.name }, "IPC server error");
2789
+ this.emit("error", err);
2790
+ });
2791
+ await this.ipcServer.listen();
2792
+ this.startupAdmission?.();
2793
+ ipcListening = true;
2794
+ // Permanent IPC dispatcher: routes responses to pending requests by type+id key
2795
+ this.ipcServer.on("message", (msg) => this.routeFleetResponse(msg));
2796
+ // IPC message relay: when daemon wants to push a channel message to Claude,
2797
+ // it broadcasts to all IPC clients (the MCP server is one of them).
2798
+ // When MCP server sends a tool_call, daemon handles it via the messageBus.
2799
+ this.ipcServer.on("message", (msg, socket) => {
2800
+ if (msg.type === "tool_call") {
2801
+ // MCP server forwarding a Claude tool call (reply, react, edit, download)
2802
+ this.handleToolCall(msg, socket);
2803
+ }
2804
+ else if (msg.type === "mcp_ready") {
2805
+ this.handleMcpReady(msg, socket);
2806
+ }
2807
+ else if (msg.type === "pong") {
2808
+ this.handleMcpPong(msg, socket);
2809
+ }
2810
+ else if (msg.type === "query_sessions") {
2811
+ // Fleet manager asks for all registered session names (catches sessions
2812
+ // that sent mcp_ready before fleet manager connected).
2813
+ const sessions = [];
2814
+ for (const [s, sessionName] of this.socketSessionNames) {
2815
+ if (!s.destroyed && sessionName !== this.name) {
2816
+ // Individual mcp_ready for initial registration path
2817
+ this.ipcServer?.send(socket, { type: "mcp_ready", sessionName });
2818
+ sessions.push(sessionName);
2955
2819
  }
2956
- // Batch response for prune path
2957
- this.ipcServer?.send(socket, { type: "query_sessions_response", sessions });
2958
2820
  }
2959
- else
2960
- this.handleFleetMessage(msg, reply => { this.ipcServer?.send(socket, reply); });
2961
- });
2962
- }
2963
- let nativeDisposition;
2964
- if (this.nativePaneLifecycle) {
2965
- this.beginSpawn();
2966
- try {
2967
- const acquired = await this.nativePaneLifecycle.acquire(() => {
2968
- this.startupAdmission?.();
2969
- if (this.startupAborted)
2970
- throw Error("Native launch was superseded");
2821
+ // Batch response for prune path
2822
+ this.ipcServer?.send(socket, { type: "query_sessions_response", sessions });
2823
+ }
2824
+ else if (msg.type === "fleet_inbound") {
2825
+ // Fleet manager routed a message to us (topic mode)
2826
+ const meta = msg.meta;
2827
+ const targetSession = msg.targetSession;
2828
+ const deliveryEpoch = this.captureDeliveryEpoch(msg.delivery_epoch);
2829
+ void this.wake().then(() => {
2830
+ this.pushChannelMessage(msg.content, meta, targetSession, deliveryEpoch);
2831
+ }).catch(err => {
2832
+ this.deferDurableDelivery(meta, `target wake failed before pane submission: ${err.message}`);
2833
+ this.logger.error({ err: err.message }, "Wake failed for inbound delivery");
2971
2834
  });
2972
- this.tmux = acquired.pane;
2973
- this.nativeTranscriptSource = acquired.source;
2974
- nativeDisposition = acquired.disposition;
2975
- this.lastSpawnAt = Date.now();
2976
- this.setProcessStatus("running");
2977
- this.bindInstanceStateOutputListener(this.tmux.getWindowId());
2978
- this.saveSessionId();
2979
- // New/resumed native processes can still be painting their first frame. Keep deliveries behind the same
2980
- // bounded dialog/readiness scan as local startup. An already-running reattachment may be busy: do not
2981
- // wait for that work to finish or inject a startup key into it.
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 {
2996
- if (!await this.finishStartupScan(120_000))
2997
- throw Error("Native CLI exited during startup; retained session was not replaced");
2998
- this.startupAdmission?.();
2999
- if (this.startupAborted || this.deliveryWritesStopping || !this.nativePaneLifecycle.current())
3000
- throw Error("Native launch was superseded");
3001
- }
3002
2835
  }
3003
- finally {
3004
- this.endSpawn();
2836
+ else if (msg.type === "raw_paste") {
2837
+ this.handleRawPasteIpcMessage(msg);
3005
2838
  }
3006
- }
3007
- else {
3008
- // 2. Tmux — ensure session, create window if not alive
3009
- await this.paneHost.ensureSession(this.tmuxSessionName);
3010
- this.startupAdmission?.();
3011
- this.tmux = this.paneHost.bind(this.tmuxSessionName, "", resolveTmuxLogicalSize(this.config.terminal), this.controlClient);
3012
- // Strategy A: always start fresh Claude window (MCP server has no reconnection)
3013
- // Kill any existing window from previous run
3014
- const windowIdFile = join(this.instanceDir, "window-id");
3015
- if (existsSync(windowIdFile)) {
3016
- const savedId = readFileSync(windowIdFile, "utf-8").trim();
3017
- if (savedId) {
3018
- const oldTmux = this.paneHost.bind(this.tmuxSessionName, savedId);
3019
- if (await oldTmux.isWindowAlive()) {
3020
- this.startupAdmission?.();
3021
- await this.checkpointSessionId();
3022
- this.startupAdmission?.();
3023
- await oldTmux.killWindow();
3024
- this.startupAdmission?.();
3025
- this.logger.info({ savedId }, "Killed old tmux window for fresh start");
3026
- }
3027
- }
2839
+ else if (msg.type === "config_update") {
2840
+ this.applyConfigUpdate(msg.config);
3028
2841
  }
3029
- const resumed = await this.spawnClaudeWindow();
3030
- this.startupAdmission?.();
3031
- this.isNewSession = !resumed;
3032
- if (!resumed) {
3033
- await this.injectSnapshotMessage(this.startupAdmission);
3034
- this.startupAdmission?.();
2842
+ else if (msg.type === "steer") {
2843
+ const meta = (msg.meta ?? {});
2844
+ this.steerMessage(msg.content, meta, this.captureDeliveryEpoch(msg.delivery_epoch));
3035
2845
  }
3036
- else {
3037
- // Clean up stale snapshot file — resume restored full context, snapshot not needed
3038
- try {
3039
- unlinkSync(join(this.instanceDir, "rotation-state.json"));
2846
+ else if (msg.type === "btw") {
2847
+ const meta = (msg.meta ?? {});
2848
+ this.btwMessage(msg.content, meta, this.captureDeliveryEpoch(msg.delivery_epoch));
2849
+ }
2850
+ else if (msg.type === "fleet_schedule_trigger") {
2851
+ const payload = msg.payload;
2852
+ const meta = msg.meta;
2853
+ const deliveryEpoch = this.captureDeliveryEpoch(msg.delivery_epoch);
2854
+ void this.wake().then(() => this.pushChannelMessage(payload.message, meta, undefined, deliveryEpoch)).catch(err => {
2855
+ this.logger.error({ err: err.message }, "Wake failed for scheduled delivery");
2856
+ });
2857
+ }
2858
+ else if (msg.type === "query_instance_state") {
2859
+ void this.respondToInstanceStateQuery(msg, socket);
2860
+ }
2861
+ });
2862
+ // 2. Tmux — ensure session, create window if not alive
2863
+ await TmuxManager.ensureSession(this.tmuxSessionName);
2864
+ this.startupAdmission?.();
2865
+ this.tmux = new TmuxManager(this.tmuxSessionName, "", resolveTmuxLogicalSize(this.config.terminal), this.controlClient);
2866
+ // Strategy A: always start fresh Claude window (MCP server has no reconnection)
2867
+ // Kill any existing window from previous run
2868
+ const windowIdFile = join(this.instanceDir, "window-id");
2869
+ if (existsSync(windowIdFile)) {
2870
+ const savedId = readFileSync(windowIdFile, "utf-8").trim();
2871
+ if (savedId) {
2872
+ const oldTmux = new TmuxManager(this.tmuxSessionName, savedId);
2873
+ if (await oldTmux.isWindowAlive()) {
2874
+ this.startupAdmission?.();
2875
+ await this.checkpointSessionId();
2876
+ this.startupAdmission?.();
2877
+ await oldTmux.killWindow();
2878
+ this.startupAdmission?.();
2879
+ this.logger.info({ savedId }, "Killed old tmux window for fresh start");
3040
2880
  }
3041
- catch { /* may not exist */ }
3042
2881
  }
3043
2882
  }
3044
- if (nativeDisposition)
3045
- this.isNewSession = nativeDisposition === "fresh";
2883
+ const resumed = await this.spawnClaudeWindow();
2884
+ this.startupAdmission?.();
2885
+ this.isNewSession = !resumed;
2886
+ if (!resumed) {
2887
+ await this.injectSnapshotMessage(this.startupAdmission);
2888
+ this.startupAdmission?.();
2889
+ }
2890
+ else {
2891
+ // Clean up stale snapshot file — resume restored full context, snapshot not needed
2892
+ try {
2893
+ unlinkSync(join(this.instanceDir, "rotation-state.json"));
2894
+ }
2895
+ catch { /* may not exist */ }
2896
+ }
3046
2897
  // #1209: conditional continuation for the turn interrupted by the last
3047
2898
  // restart, if the gates allow. Detached; the gate
3048
2899
  // consumes its one-shot marker first and never throws into boot.
3049
- const legacyResume = this.nativePaneLifecycle ? Promise.resolve("unknown") : this.maybeResumeInterruptedTurn().catch(() => "unknown");
2900
+ const legacyResume = this.maybeResumeInterruptedTurn().catch(() => "unknown");
3050
2901
  const recoveryOwner = JSON.stringify(this.interactionOwner());
3051
2902
  void Promise.allSettled([legacyResume]).then(() => {
3052
2903
  if (JSON.stringify(this.interactionOwner()) === recoveryOwner) {
@@ -3065,7 +2916,7 @@ export class Daemon extends EventEmitter {
3065
2916
  // (statusline transcript); codex/kiro/opencode read their CLI's own
3066
2917
  // conversation store via a pluggable source. Backends with no known
3067
2918
  // source stay inert exactly as before.
3068
- this.transcriptMonitor = this.buildTranscriptMonitor(this.nativeTranscriptSource ?? createTranscriptSource(this.config.backend ?? "claude-code", this.config.working_directory, this.credentialProfileStore(), () => this.backend?.transcriptLaunch?.() ?? null));
2919
+ this.transcriptMonitor = this.buildTranscriptMonitor(createTranscriptSource(this.config.backend ?? "claude-code", this.config.working_directory, this.credentialProfileStore(), () => this.backend?.transcriptLaunch?.() ?? null));
3069
2920
  const transcriptMonitor = this.transcriptMonitor;
3070
2921
  const transcriptFence = this.launchFenceEpoch;
3071
2922
  // Baseline in the isolate before this daemon accepts new work. A
@@ -3121,15 +2972,13 @@ export class Daemon extends EventEmitter {
3121
2972
  if (hangConfig?.enabled !== false) {
3122
2973
  this.hangDetector = new HangDetector();
3123
2974
  }
3124
- if (!this.nativePaneLifecycle) {
3125
- // 8. Context guardian
3126
- const statusFile = join(this.instanceDir, "statusline.json");
3127
- this.guardian = new ContextGuardian(this.config.context_guardian ?? {}, this.logger, statusFile);
3128
- this.guardian.startWatching();
3129
- this.guardian.on("status_update", () => {
3130
- this.saveSessionId();
3131
- });
3132
- }
2975
+ // 8. Context guardian
2976
+ const statusFile = join(this.instanceDir, "statusline.json");
2977
+ this.guardian = new ContextGuardian(this.config.context_guardian ?? {}, this.logger, statusFile);
2978
+ this.guardian.startWatching();
2979
+ this.guardian.on("status_update", () => {
2980
+ this.saveSessionId();
2981
+ });
3133
2982
  // Context rotation removed: all CLI backends have built-in auto-compact.
3134
2983
  // Crash recovery (health check + respawn with snapshot) is retained below.
3135
2984
  }
@@ -3182,7 +3031,7 @@ export class Daemon extends EventEmitter {
3182
3031
  this.socketPids.delete(socket);
3183
3032
  // Notify fleet manager so it can clean up sessionRegistry
3184
3033
  if (sessionName !== this.name) {
3185
- this.broadcastFleetMessage({ type: "session_disconnected", sessionName });
3034
+ this.ipcServer?.broadcast({ type: "session_disconnected", sessionName });
3186
3035
  }
3187
3036
  });
3188
3037
  }
@@ -3198,16 +3047,11 @@ export class Daemon extends EventEmitter {
3198
3047
  // sub-agent's server may have left a dead pid in the slot).
3199
3048
  this.noteMcpProofOfLife("mcp_ready", typeof msg.pid === "number" ? msg.pid : undefined);
3200
3049
  }
3201
- this.broadcastFleetMessage({ type: "mcp_ready", sessionName });
3050
+ this.ipcServer?.broadcast({ type: "mcp_ready", sessionName });
3202
3051
  }
3203
3052
  checkMcpServerAlive() {
3204
3053
  if (this.isPaused)
3205
3054
  return;
3206
- if (this.nativePaneLifecycle) {
3207
- if (this.nativePaneLifecycle.mcpProof() === "alive")
3208
- this.noteMcpProofOfLife("connection");
3209
- return; // No native PID/socket guessing or restart from an unknown helper observation.
3210
- }
3211
3055
  const status = mcpServerState(this.instanceDir);
3212
3056
  if (status.state === "alive") {
3213
3057
  this.mcpServedGeneration = this.spawnGeneration;
@@ -3291,8 +3135,6 @@ export class Daemon extends EventEmitter {
3291
3135
  * server from a third-party one, and failed the whole launch for either.
3292
3136
  */
3293
3137
  checkFleetMcpNeverConnected() {
3294
- if (this.nativePaneLifecycle)
3295
- return; // Native helper presence owns this observation.
3296
3138
  if (this.config.agent_mode === "cli")
3297
3139
  return; // no MCP server by design
3298
3140
  if (this.lastSpawnAt === 0 || this.mcpServedGeneration === this.spawnGeneration)
@@ -3503,8 +3345,6 @@ export class Daemon extends EventEmitter {
3503
3345
  * proof that tools are being served, whatever channel.mcp.pid says.
3504
3346
  */
3505
3347
  mcpServerAlive() {
3506
- if (this.nativePaneLifecycle)
3507
- return this.nativePaneLifecycle.mcpProof() === "alive" ? { alive: true, source: "connection" } : { alive: false, source: "none" };
3508
3348
  const status = mcpServerState(this.instanceDir);
3509
3349
  if (status.state === "alive")
3510
3350
  return { alive: true, source: "pid", pid: status.pid };
@@ -3569,7 +3409,7 @@ export class Daemon extends EventEmitter {
3569
3409
  this.mcpDeathNotifiedForPid = null;
3570
3410
  this.mcpDeathDeferredForPid = null;
3571
3411
  this.clearMcpRestartRequest();
3572
- if (!this.nativePaneLifecycle && pid && mcpServerState(this.instanceDir).state !== "alive")
3412
+ if (pid && mcpServerState(this.instanceDir).state !== "alive")
3573
3413
  this.repairMcpPidSlot(pid, source);
3574
3414
  }
3575
3415
  emitMcpRecovered(source, pid) {
@@ -3616,26 +3456,6 @@ export class Daemon extends EventEmitter {
3616
3456
  // ended this instance's health loop because scheduleNext() sat after the
3617
3457
  // throwing code. Catch, log, and keep checking.
3618
3458
  try {
3619
- if (this.nativePaneLifecycle) {
3620
- if (this.healthCheckPaused) {
3621
- scheduleNext();
3622
- return;
3623
- }
3624
- const native = this.nativePaneLifecycle, pane = this.tmux;
3625
- const status = await pane?.getPaneStatus();
3626
- if (this.runtimeMonitorsFrozen || native !== this.nativePaneLifecycle || pane !== this.tmux)
3627
- return;
3628
- const snapshot = native.snapshot?.();
3629
- if (status?.alive === false && snapshot?.state === "exited") {
3630
- this.healthCheckPaused = true;
3631
- this.setProcessStatus(snapshot.exitCode === 0 ? "stopped" : "crashed");
3632
- this.emit("native_pane_exited", { name: this.name, snapshot, owner: this.interactionOwner() });
3633
- }
3634
- else if (status?.alive)
3635
- this.checkMcpServerAlive();
3636
- scheduleNext();
3637
- return;
3638
- }
3639
3459
  // Instance directory removed externally (e.g. `rm -rf ~/.agend/instances/<name>`).
3640
3460
  // Stop the loop permanently — otherwise every tick triggers a respawn, whose
3641
3461
  // writeRotationSnapshot fails with ENOENT and gets caught as "Failed to respawn",
@@ -3771,13 +3591,13 @@ export class Daemon extends EventEmitter {
3771
3591
  let inWindowLossBurst = false;
3772
3592
  let nullReason;
3773
3593
  if (!paneStatus) {
3774
- const serverAlive = await this.paneHost.sessionExists(this.tmuxSessionName);
3594
+ const serverAlive = await TmuxManager.sessionExists(this.tmuxSessionName);
3775
3595
  if (discardStaleHealth())
3776
3596
  return;
3777
3597
  // A server may have already restarted before this daemon's health
3778
3598
  // tick. The new PID is the durable generation boundary: treat it as
3779
3599
  // a fleet storm even though `has-session` is true again.
3780
- const serverPid = serverAlive ? await this.paneHost.getServerPid(this.tmuxSessionName) : null;
3600
+ const serverPid = serverAlive ? await TmuxManager.getServerPid(this.tmuxSessionName) : null;
3781
3601
  if (discardStaleHealth())
3782
3602
  return;
3783
3603
  const generationChanged = serverAlive && this.stormWindow?.observeServerAlive(serverPid) === true;
@@ -3806,7 +3626,7 @@ export class Daemon extends EventEmitter {
3806
3626
  // the window truly no longer exists vs a transient query glitch.
3807
3627
  nullReason = "no_window";
3808
3628
  try {
3809
- const windows = await this.paneHost.listWindowsStrict(this.tmuxSessionName, this.controlClient);
3629
+ const windows = await TmuxManager.listWindowsStrict(this.tmuxSessionName, this.controlClient);
3810
3630
  if (discardStaleHealth())
3811
3631
  return;
3812
3632
  this.windowQueryFailureTicks = 0;
@@ -4053,10 +3873,10 @@ export class Daemon extends EventEmitter {
4053
3873
  // Wrapped in try-catch: if tmux server is dead, listWindows throws —
4054
3874
  // must not block spawnClaudeWindow (which calls ensureSession).
4055
3875
  try {
4056
- const windows = await this.paneHost.listWindows(this.tmuxSessionName);
3876
+ const windows = await TmuxManager.listWindows(this.tmuxSessionName);
4057
3877
  for (const w of windows) {
4058
3878
  if (w.name === this.name) {
4059
- const tm = this.paneHost.bind(this.tmuxSessionName, w.id);
3879
+ const tm = new TmuxManager(this.tmuxSessionName, w.id);
4060
3880
  await tm.killWindow();
4061
3881
  }
4062
3882
  }
@@ -4201,7 +4021,7 @@ export class Daemon extends EventEmitter {
4201
4021
  // Force the next ready capture to emit a fresh transition after respawn.
4202
4022
  this.instanceState = "working";
4203
4023
  }
4204
- this.broadcastFleetMessage({
4024
+ this.ipcServer?.broadcast({
4205
4025
  type: "instance_process_state",
4206
4026
  instanceName: this.name,
4207
4027
  status,
@@ -4397,15 +4217,12 @@ export class Daemon extends EventEmitter {
4397
4217
  for (const key of dialog.keys) {
4398
4218
  if (stale())
4399
4219
  return;
4400
- const keyScreen = this.nativePaneLifecycle ? await pollTmux.capturePane() : currentPane;
4401
- if (stale() || !Daemon.dialogMatches(dialog, keyScreen))
4402
- return;
4403
4220
  let sent = false;
4404
4221
  if (SPECIAL_KEYS.has(key)) {
4405
- sent = await (this.nativePaneLifecycle ? pollTmux.sendSpecialKey(key, undefined, { kind: "dialog", screen: keyScreen }) : pollTmux.sendSpecialKey(key));
4222
+ sent = await pollTmux.sendSpecialKey(key);
4406
4223
  }
4407
4224
  else if (dialog.literalKeys) {
4408
- sent = await (this.nativePaneLifecycle ? pollTmux.sendKeys(key, { kind: "dialog", screen: keyScreen }) : pollTmux.sendKeys(key)); // typed, no Enter (#2872)
4225
+ sent = await pollTmux.sendKeys(key); // typed, no Enter (#2872)
4409
4226
  }
4410
4227
  else {
4411
4228
  sent = await pollTmux.pasteText(key, this.systemPasteOptions());
@@ -4776,20 +4593,7 @@ export class Daemon extends EventEmitter {
4776
4593
  */
4777
4594
  async sendEscape() {
4778
4595
  const cancelKey = this.backend?.getCancelKey() ?? "Escape";
4779
- const tmux = this.tmux;
4780
- if (!tmux)
4781
- return;
4782
- if (this.nativePaneLifecycle) {
4783
- // A native pane's composer proof cannot see a permission dialog, so an unproved key is withheld there. The cancel
4784
- // is the person's own interrupt, keyed on the screen read just before (as the dialog answer path is): what Esc
4785
- // does on Linux's tmux pane, on the same screen, with the same key.
4786
- const screen = await tmux.capturePane().catch(() => null);
4787
- if (screen === null)
4788
- return;
4789
- await tmux.sendSpecialKey(cancelKey, undefined, { kind: "dialog", screen });
4790
- return;
4791
- }
4792
- await tmux.sendSpecialKey(cancelKey);
4596
+ await this.tmux?.sendSpecialKey(cancelKey);
4793
4597
  }
4794
4598
  /**
4795
4599
  * Drop every not-yet-started pane delivery which predates a user cancel.
@@ -4855,7 +4659,7 @@ export class Daemon extends EventEmitter {
4855
4659
  return;
4856
4660
  const outcome = follower.look(pane);
4857
4661
  if (outcome) {
4858
- this.broadcastFleetMessage({ type: "compact_pane_result", id, owner, outcome });
4662
+ this.ipcServer?.broadcast({ type: "compact_pane_result", id, owner, outcome });
4859
4663
  return;
4860
4664
  }
4861
4665
  }
@@ -4875,7 +4679,7 @@ export class Daemon extends EventEmitter {
4875
4679
  const reportSwitch = (result) => {
4876
4680
  if (!ownSwitch)
4877
4681
  return;
4878
- this.broadcastFleetMessage({ type: "runtime_switch_result", id: ownSwitch.id, ...result });
4682
+ this.ipcServer?.broadcast({ type: "runtime_switch_result", id: ownSwitch.id, ...result });
4879
4683
  };
4880
4684
  // Board 003648ac: the fleet follows a web /compact from just before its paste is written: the transcript's end then
4881
4685
  // (taken here, under this launch, before the write) and the launch it was written under ride with the notice — once.
@@ -4890,7 +4694,7 @@ export class Daemon extends EventEmitter {
4890
4694
  if (!notifyWritten || told)
4891
4695
  return;
4892
4696
  told = true;
4893
- this.broadcastFleetMessage({ type: "raw_paste_written", id: notifyWritten, outcome: written ? "written" : "not_written",
4697
+ this.ipcServer?.broadcast({ type: "raw_paste_written", id: notifyWritten, outcome: written ? "written" : "not_written",
4894
4698
  ...(written ? { owner, checkpoint, ...(paneFollower ? { pane: true } : {}) } : {}) });
4895
4699
  if (written && paneFollower)
4896
4700
  void this.followCompactPane(notifyWritten, owner, paneFollower);
@@ -5052,11 +4856,10 @@ export class Daemon extends EventEmitter {
5052
4856
  const press = (target, cursor, key) => this.paneWriteLock.run(async () => {
5053
4857
  if (this.tmux !== tmux)
5054
4858
  return false;
5055
- const screen = await read();
5056
- const now = claudeSwitchDialog(screen);
4859
+ const now = claudeSwitchDialog(await read());
5057
4860
  if (!now || now.kind !== "model" || now.target !== target || (cursor !== null && now.cursor !== cursor))
5058
4861
  return false;
5059
- return this.nativePaneLifecycle ? tmux.sendSpecialKey(key, undefined, { kind: "dialog", screen }) : tmux.sendSpecialKey(key);
4862
+ return tmux.sendSpecialKey(key);
5060
4863
  });
5061
4864
  const gone = async () => {
5062
4865
  const until = performance.now() + OWN_SWITCH_SETTLE_MS;
@@ -5145,12 +4948,9 @@ export class Daemon extends EventEmitter {
5145
4948
  return false;
5146
4949
  const specialKeys = new Set(["Up", "Down", "Enter", "Escape", "Right", "Left"]);
5147
4950
  for (const key of dialog.keys) {
5148
- const keyScreen = this.nativePaneLifecycle ? await this.tmux.capturePane() : currentPane;
5149
- if (!matches(keyScreen))
5150
- return false;
5151
4951
  const ok = specialKeys.has(key)
5152
- ? await (this.nativePaneLifecycle ? this.tmux.sendSpecialKey(key, undefined, { kind: "dialog", screen: keyScreen }) : this.tmux.sendSpecialKey(key))
5153
- : await (this.nativePaneLifecycle ? this.tmux.sendKeys(key, { kind: "dialog", screen: keyScreen }) : this.tmux.sendKeys(key));
4952
+ ? await this.tmux.sendSpecialKey(key)
4953
+ : await this.tmux.sendKeys(key);
5154
4954
  if (!ok)
5155
4955
  return false;
5156
4956
  await new Promise(resolve => setTimeout(resolve, 100));
@@ -5393,7 +5193,7 @@ export class Daemon extends EventEmitter {
5393
5193
  await this.tmux.sendSpecialKey("Escape").catch(() => false);
5394
5194
  return true;
5395
5195
  }
5396
- async stop(options = {}) {
5196
+ async stop() {
5397
5197
  this.publishWorkingState("before_stop");
5398
5198
  this.logger.info("Stopping daemon instance");
5399
5199
  this.clearQuitRelaunchWatch();
@@ -5415,18 +5215,8 @@ export class Daemon extends EventEmitter {
5415
5215
  }
5416
5216
  if (this.adapter)
5417
5217
  await this.adapter.stop();
5418
- if (this.nativePaneLifecycle) {
5419
- this.healthCheckPaused = true;
5420
- this.saveSessionId();
5421
- await this.nativePaneLifecycle.release(options.nativePane ?? "detach");
5422
- try {
5423
- unlinkSync(join(this.instanceDir, "daemon.pid"));
5424
- }
5425
- catch { /* metadata only */ }
5426
- return;
5427
- }
5428
5218
  // Notify MCP servers of graceful shutdown (prevents reconnect attempts)
5429
- this.broadcastFleetMessage({ type: "shutdown" });
5219
+ this.ipcServer?.broadcast({ type: "shutdown" });
5430
5220
  // Quit CLI FIRST — this kills MCP server child processes cleanly.
5431
5221
  // IPC must stay open during quit so MCP servers receive the shutdown message.
5432
5222
  if (this.tmux) {
@@ -5572,24 +5362,6 @@ export class Daemon extends EventEmitter {
5572
5362
  freshChoice: this.recoveryFreshChoice || this.isNewSession && !this.bootSkippedResume, crashLoopFresh: this.recoveryCrashLoopFresh,
5573
5363
  cancelled: this.recoveryCancelled, background: this.workingBackgroundObservation };
5574
5364
  }
5575
- /** Observe this host General before its approved switch. No keys, process signals or provider writes. */
5576
- async generalHostOwner() {
5577
- const pane = this.tmux, owner = JSON.stringify(this.interactionOwner());
5578
- if (!this.config.general_topic || this.nativePaneLifecycle || !pane || !/^@\d+$/.test(pane.getWindowId()))
5579
- throw Error("General host owner is unavailable");
5580
- const status = await pane.getPaneStatus();
5581
- if (!status?.alive || !status.pid || status.pid <= 1)
5582
- throw Error("General host process cannot be proven");
5583
- const checkpoint = await this.transcriptMonitor?.reconciliationCheckpoint();
5584
- if (this.tmux !== pane || owner !== JSON.stringify(this.interactionOwner()))
5585
- throw Error("General host owner changed during observation");
5586
- const backend = this.config.backend ?? "claude-code";
5587
- let sessionId = this.backend?.getSessionId() ?? undefined;
5588
- if (backend === "codex" && checkpoint)
5589
- sessionId = /([0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12})\.jsonl$/i.exec(checkpoint.path)?.[1];
5590
- return { kind: "tmux", windowId: pane.getWindowId(), pid: status.pid,
5591
- ...(typeof sessionId === "string" && sessionId.length > 0 && sessionId.length <= 256 && !/[\p{Cc}\p{Cf}]/u.test(sessionId) ? { pin: { backend, sessionId } } : {}) };
5592
- }
5593
5365
  /** Local system work: no user turn, channel reply target, wake or replay of an original request. */
5594
5366
  async deliverWorkingRecovery(content, delivery, admitted) {
5595
5367
  const tmux = this.tmux, owner = JSON.stringify(this.interactionOwner()), epoch = this.deliveryEpoch;
@@ -5610,11 +5382,7 @@ export class Daemon extends EventEmitter {
5610
5382
  || !this.paneAuthoritativelyIdle(pane) || this.inputTransientInPane(pane)
5611
5383
  || this.backend?.backgroundWorkRunning?.(pane) === true)
5612
5384
  return;
5613
- if (this.nativePaneLifecycle ? !this.nativePaneLifecycle.current() || this.nativePaneLifecycle.mcpProof() !== "alive"
5614
- || !!this.backend?.isDeliveryInputReadyPane && !this.backend.isDeliveryInputReadyPane(pane)
5615
- : await tmux.getPaneInputMode?.() !== "raw")
5616
- return;
5617
- if (!current())
5385
+ if (await tmux.getPaneInputMode?.() !== "raw" || !current())
5618
5386
  return;
5619
5387
  const evidence = await this.durableAttemptEvidence(tmux.getWindowId(), false, false);
5620
5388
  if (!current())
@@ -5705,7 +5473,7 @@ export class Daemon extends EventEmitter {
5705
5473
  this.logger.debug({ err }, "Interaction listener failed");
5706
5474
  }
5707
5475
  try {
5708
- this.broadcastFleetMessage({ type: "instance_interaction", instanceName: this.name, interaction });
5476
+ this.ipcServer?.broadcast({ type: "instance_interaction", instanceName: this.name, interaction });
5709
5477
  }
5710
5478
  catch (err) {
5711
5479
  this.logger.debug({ err }, "Interaction broadcast failed");
@@ -5793,56 +5561,6 @@ export class Daemon extends EventEmitter {
5793
5561
  }
5794
5562
  return true;
5795
5563
  }
5796
- /** Shared Fleet inputs: socket and native transports retain the same wake, epoch and raw-paste semantics. */
5797
- handleFleetMessage(msg, send, current = () => true) {
5798
- if (msg.type === "query_sessions") {
5799
- send({ type: "query_sessions_response", sessions: [] });
5800
- }
5801
- else if (msg.type === "fleet_inbound") {
5802
- const meta = msg.meta;
5803
- const targetSession = msg.targetSession;
5804
- const deliveryEpoch = this.captureDeliveryEpoch(msg.delivery_epoch);
5805
- void this.wake().then(() => {
5806
- if (!current()) {
5807
- this.deferDurableDelivery(meta, "native channel owner changed before pane submission");
5808
- return;
5809
- }
5810
- this.pushChannelMessage(msg.content, meta, targetSession, deliveryEpoch);
5811
- }).catch(err => {
5812
- this.deferDurableDelivery(meta, `target wake failed before pane submission: ${err.message}`);
5813
- this.logger.error({ err: err.message }, "Wake failed for inbound delivery");
5814
- });
5815
- }
5816
- else if (msg.type === "raw_paste") {
5817
- this.handleRawPasteIpcMessage(msg);
5818
- }
5819
- else if (msg.type === "config_update") {
5820
- this.applyConfigUpdate(msg.config);
5821
- }
5822
- else if (msg.type === "steer") {
5823
- const meta = (msg.meta ?? {});
5824
- this.steerMessage(msg.content, meta, this.captureDeliveryEpoch(msg.delivery_epoch));
5825
- }
5826
- else if (msg.type === "btw") {
5827
- const meta = (msg.meta ?? {});
5828
- this.btwMessage(msg.content, meta, this.captureDeliveryEpoch(msg.delivery_epoch));
5829
- }
5830
- else if (msg.type === "fleet_schedule_trigger") {
5831
- const payload = msg.payload;
5832
- const meta = msg.meta;
5833
- const deliveryEpoch = this.captureDeliveryEpoch(msg.delivery_epoch);
5834
- void this.wake().then(() => { if (current())
5835
- this.pushChannelMessage(payload.message, meta, undefined, deliveryEpoch); }).catch(err => {
5836
- this.logger.error({ err: err.message }, "Wake failed for scheduled delivery");
5837
- });
5838
- }
5839
- else if (msg.type === "query_instance_state") {
5840
- void this.respondToInstanceStateQuery(msg, undefined, send);
5841
- }
5842
- else
5843
- return false;
5844
- return true;
5845
- }
5846
5564
  /**
5847
5565
  * Answer a FleetManager state query. Most callers only need the cached state,
5848
5566
  * but lifecycle decisions such as post-reply Cancel retirement need an
@@ -5850,7 +5568,7 @@ export class Daemon extends EventEmitter {
5850
5568
  * the last transition can stay "working" even though the CLI has since
5851
5569
  * settled without emitting another control-mode output record.
5852
5570
  */
5853
- async respondToInstanceStateQuery(msg, socket, send) {
5571
+ async respondToInstanceStateQuery(msg, socket) {
5854
5572
  try {
5855
5573
  if (msg.deliveryIdle === true) {
5856
5574
  await this.captureAndEvaluateInstanceState("delivery_idle_gate");
@@ -5859,7 +5577,7 @@ export class Daemon extends EventEmitter {
5859
5577
  await this.captureAndEvaluateInstanceState("state_query");
5860
5578
  }
5861
5579
  const snapshot = this.getInstanceStateSnapshot();
5862
- const reply = {
5580
+ this.ipcServer?.send(socket, {
5863
5581
  type: "instance_state_response",
5864
5582
  requestId: msg.requestId,
5865
5583
  instanceName: this.name,
@@ -5867,11 +5585,7 @@ export class Daemon extends EventEmitter {
5867
5585
  state: this.isPaused ? "paused" : snapshot.state,
5868
5586
  processStatus: this.processStatus,
5869
5587
  pausedAt: this.lastPausedAt,
5870
- };
5871
- if (send)
5872
- send(reply);
5873
- else if (socket)
5874
- this.ipcServer?.send(socket, reply);
5588
+ });
5875
5589
  }
5876
5590
  catch (err) {
5877
5591
  this.logger.debug({ err: err.message }, "Instance state query failed");
@@ -5911,49 +5625,7 @@ export class Daemon extends EventEmitter {
5911
5625
  static AUTH_RECONFIRM_ROWS = 15;
5912
5626
  /** Why the deferred pause was requested; what its marker records (Phase 2a). */
5913
5627
  pendingPauseReason = "auth";
5914
- nativePauseProof = null;
5915
- /** Consume the exact idle proof synchronously after the lifecycle's await, before fencing and closing. */
5916
- nativePauseStillReady() {
5917
- const proof = this.nativePauseProof;
5918
- this.nativePauseProof = null;
5919
- if (proof?.())
5920
- return true;
5921
- this.pauseRequested = false;
5922
- return false;
5923
- }
5924
- /** Native lifecycle pause uses the ordinary idle/background/admission proof before closing its owned Job. */
5925
- async nativePauseReady(admission) {
5926
- this.nativePauseProof = null;
5927
- const native = this.nativePaneLifecycle, pane = this.tmux, owner = this.interactionOwner();
5928
- const allowStuck = this.pauseAllowStuck;
5929
- this.pauseAllowStuck = false;
5930
- const ready = () => !!native && native === this.nativePaneLifecycle && native.current() && this.tmux === pane
5931
- && sameInteractionOwner(owner, this.interactionOwner()) && !this.runtimeMonitorsFrozen && !this.spawning
5932
- && this.processStatus === "running" && this.pasteQueueDepth === 0
5933
- && (this.instanceState === "idle" || allowStuck && this.instanceState === "stuck") && (!admission || admission.current());
5934
- if (!pane || !ready()) {
5935
- this.pauseRequested = false;
5936
- return false;
5937
- }
5938
- let text;
5939
- try {
5940
- text = await pane.capturePane();
5941
- }
5942
- catch {
5943
- this.pauseRequested = false;
5944
- return false;
5945
- }
5946
- if (!ready() || admission && !admission.accepts(text) || this.backend?.backgroundWorkRunning?.(text)
5947
- || !allowStuck && !this.paneAuthoritativelyIdle(text)) {
5948
- this.pauseRequested = false;
5949
- return false;
5950
- }
5951
- this.nativePauseProof = ready;
5952
- return true;
5953
- }
5954
5628
  async pause(reason = "operator", admission) {
5955
- if (this.nativePaneLifecycle)
5956
- throw Error("Native pause is owned by its Fleet lifecycle transition");
5957
5629
  if (admission && !admission.current())
5958
5630
  return;
5959
5631
  if (this.pauseWakeState === "paused")
@@ -6049,7 +5721,7 @@ export class Daemon extends EventEmitter {
6049
5721
  writePausedMarker(this.instanceDir, this.lastPausedAt ?? Date.now(), reason);
6050
5722
  this.publishWorkingState("execution");
6051
5723
  this.logger.info({ pausedAt: this.lastPausedAt }, "Instance auto-paused");
6052
- this.broadcastFleetMessage({
5724
+ this.ipcServer?.broadcast({
6053
5725
  type: "instance_state", instanceName: this.name, state: "paused", pausedAt: this.lastPausedAt,
6054
5726
  });
6055
5727
  this.emit("auto_paused", { name: this.name, pausedAt: this.lastPausedAt });
@@ -6144,7 +5816,7 @@ export class Daemon extends EventEmitter {
6144
5816
  this.resumeRuntimeMonitors();
6145
5817
  this.publishWorkingState("execution");
6146
5818
  this.logger.info("Instance auto-woke");
6147
- this.broadcastFleetMessage({
5819
+ this.ipcServer?.broadcast({
6148
5820
  type: "instance_state", instanceName: this.name, state: this.instanceState, pausedAt: null,
6149
5821
  });
6150
5822
  this.emit("auto_woke", { name: this.name });
@@ -6308,7 +5980,7 @@ export class Daemon extends EventEmitter {
6308
5980
  this.logStateEdge(previous, snapshot);
6309
5981
  this.publishWorkingState("execution");
6310
5982
  this.emit("instance_state", { name: this.name, ...snapshot });
6311
- this.broadcastFleetMessage({ type: "instance_state", instanceName: this.name, ...snapshot });
5983
+ this.ipcServer?.broadcast({ type: "instance_state", instanceName: this.name, ...snapshot });
6312
5984
  if (snapshot.state === "stuck" && pane && this.instanceStateReadyPattern) {
6313
5985
  this.handleStuckTransition(pane, snapshot, this.instanceStateReadyPattern);
6314
5986
  }
@@ -6410,7 +6082,7 @@ export class Daemon extends EventEmitter {
6410
6082
  // writing a marker would re-inject a continuation for a finished turn.
6411
6083
  // #3030: a message only queued in the busy CLI has not started a turn: the interrupted turn is still the running one,
6412
6084
  // 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) {
6085
+ if (!meta.resumedContinuationOf && !armed.completionDelivered && !queuedHandoff) {
6414
6086
  const resumeBackend = this.config.backend ?? this.backend?.binaryName ?? this.runtimeIdentity?.backend;
6415
6087
  const resumeCwd = this.config.working_directory ?? "";
6416
6088
  writeInFlightTurnMarker(this.instanceDir, {
@@ -6642,7 +6314,7 @@ export class Daemon extends EventEmitter {
6642
6314
  // outbound action suppresses a duplicate proxy; only a delivered
6643
6315
  // human-facing channel action satisfies the completion guard below.
6644
6316
  if (!turn.outboundDelivered && this.config.mcp_proxy_reply === true
6645
- && (this.nativePaneLifecycle ? this.nativePaneLifecycle.mcpProof() === "dead" : mcpServerState(this.instanceDir).state === "dead")) {
6317
+ && mcpServerState(this.instanceDir).state === "dead") {
6646
6318
  this.turnReplyGuard.complete(turn.generation);
6647
6319
  void this.sendProxyReply(pane, turn.target);
6648
6320
  return;
@@ -7019,7 +6691,7 @@ export class Daemon extends EventEmitter {
7019
6691
  }
7020
6692
  });
7021
6693
  }
7022
- if (!this.fleetTransportAvailable()) {
6694
+ if (!this.ipcServer) {
7023
6695
  this.logger.error(`${logLabel} failed — no adapter or fleet IPC route`);
7024
6696
  return Promise.resolve(false);
7025
6697
  }
@@ -7043,7 +6715,7 @@ export class Daemon extends EventEmitter {
7043
6715
  resolve(delivered);
7044
6716
  });
7045
6717
  try {
7046
- this.broadcastFleetMessage({
6718
+ this.ipcServer.broadcast({
7047
6719
  type: "fleet_outbound",
7048
6720
  tool: "reply",
7049
6721
  args,
@@ -7614,7 +7286,7 @@ export class Daemon extends EventEmitter {
7614
7286
  if (next === this.currentActivity)
7615
7287
  return;
7616
7288
  this.currentActivity = next;
7617
- this.broadcastFleetMessage({
7289
+ this.ipcServer?.broadcast({
7618
7290
  type: "instance_activity",
7619
7291
  instanceName: this.name,
7620
7292
  activity: next,
@@ -7667,6 +7339,10 @@ export class Daemon extends EventEmitter {
7667
7339
  else if (update.reply_completion_guard === null) {
7668
7340
  delete this.config.reply_completion_guard;
7669
7341
  }
7342
+ if (update.quota_notice === null)
7343
+ delete this.config.quota_notice;
7344
+ else if (update.quota_notice !== undefined && !quotaNoticeProblem(update.quota_notice))
7345
+ this.config.quota_notice = structuredClone(update.quota_notice);
7670
7346
  if (typeof update.mcp_proxy_reply === "boolean")
7671
7347
  this.config.mcp_proxy_reply = update.mcp_proxy_reply;
7672
7348
  else if (update.mcp_proxy_reply === null)
@@ -7691,7 +7367,7 @@ export class Daemon extends EventEmitter {
7691
7367
  else
7692
7368
  this.config.auto_pause_after = nextAutoPause;
7693
7369
  if (nextAutoPause !== previousAutoPause) {
7694
- const isGeneral = this.config.general_topic === true || generalByName(this.name, this.config);
7370
+ const isGeneral = this.config.general_topic === true || this.name === "general";
7695
7371
  this.autoPauseController.reconfigure((isGeneral ? 0 : nextAutoPause) * 60_000);
7696
7372
  }
7697
7373
  }
@@ -7771,7 +7447,7 @@ export class Daemon extends EventEmitter {
7771
7447
  return;
7772
7448
  this.lastProgressBroadcast = rendered;
7773
7449
  this.lastProgressBroadcastAt = Date.now();
7774
- this.broadcastFleetMessage({
7450
+ this.ipcServer?.broadcast({
7775
7451
  type: "instance_progress",
7776
7452
  instanceName: this.name,
7777
7453
  progress: rendered,
@@ -7787,7 +7463,7 @@ export class Daemon extends EventEmitter {
7787
7463
  if (this.lastProgressBroadcast !== "") {
7788
7464
  this.lastProgressBroadcast = "";
7789
7465
  this.lastProgressBroadcastAt = Date.now();
7790
- this.broadcastFleetMessage({ type: "instance_progress", instanceName: this.name, progress: "" });
7466
+ this.ipcServer?.broadcast({ type: "instance_progress", instanceName: this.name, progress: "" });
7791
7467
  }
7792
7468
  }
7793
7469
  /**
@@ -7954,7 +7630,7 @@ export class Daemon extends EventEmitter {
7954
7630
  reportCrossInstanceDeliveryFailure(meta, verdict, error) {
7955
7631
  if (!meta.from_instance)
7956
7632
  return;
7957
- this.broadcastFleetMessage({
7633
+ this.ipcServer?.broadcast({
7958
7634
  type: "cross_instance_delivery_failed",
7959
7635
  senderSession: meta.from_instance,
7960
7636
  targetInstance: this.name,
@@ -9335,14 +9011,13 @@ export class Daemon extends EventEmitter {
9335
9011
  if (this.remoteCardAnswering)
9336
9012
  return { outcome: "refused", reason: "another answer to this card is being keyed in" };
9337
9013
  this.remoteCardAnswering = true;
9338
- let answerScreen = null;
9339
9014
  try {
9340
9015
  const outcome = await answerRemoteCard({
9341
9016
  locked: fn => this.paneWriteLock.run(fn),
9342
9017
  // An unreadable screen (a failed capture, another spawn's pane) is unknown — never "the card closed".
9343
- read: async () => answerScreen = this.tmux === tmux ? await tmux.capturePane().catch(() => null) : null,
9344
- key: key => this.tmux !== tmux || answerScreen === null ? Promise.resolve(false) : key === "Space" ? (this.nativePaneLifecycle ? tmux.sendKeys(" ", { kind: "dialog", screen: answerScreen }) : tmux.sendKeys(" ")) : (this.nativePaneLifecycle ? tmux.sendSpecialKey(key, undefined, { kind: "dialog", screen: answerScreen }) : tmux.sendSpecialKey(key)),
9345
- paste: text => this.tmux !== tmux || answerScreen === null ? Promise.resolve(false) : this.nativePaneLifecycle ? tmux.pasteBuffer(text, { proof: { kind: "dialog", screen: answerScreen } }) : tmux.pasteBuffer(text),
9018
+ read: () => this.tmux === tmux ? tmux.capturePane().catch(() => null) : Promise.resolve(null),
9019
+ key: key => this.tmux !== tmux ? Promise.resolve(false) : key === "Space" ? tmux.sendKeys(" ") : tmux.sendSpecialKey(key),
9020
+ paste: text => this.tmux !== tmux ? Promise.resolve(false) : tmux.pasteBuffer(text),
9346
9021
  sleep: ms => new Promise(resolve => setTimeout(resolve, ms)),
9347
9022
  now: () => performance.now(),
9348
9023
  }, pane => {
@@ -9613,19 +9288,12 @@ export class Daemon extends EventEmitter {
9613
9288
  if (!check || !this.tmux)
9614
9289
  return !check;
9615
9290
  try {
9616
- const inputActive = this.nativePaneLifecycle
9617
- ? this.nativePaneLifecycle.current() && this.nativePaneLifecycle.mcpProof() === "alive"
9618
- : await this.tmux.getPaneInputMode?.() === "raw";
9619
- // ConPTY has no POSIX termios mode. Its closed launch plus current helper handshake is the input barrier;
9620
- // the same strict composer detector below is still required. Never grant native unknown-layout fallback.
9621
- if (!inputActive) {
9291
+ const mode = await this.tmux.getPaneInputMode?.();
9292
+ if (mode !== "raw") {
9622
9293
  this.resetFooterFallback();
9623
9294
  return false;
9624
9295
  }
9625
- const pane = await this.tmux.capturePane();
9626
- if (this.nativePaneLifecycle && (!this.nativePaneLifecycle.current() || this.nativePaneLifecycle.mcpProof() !== "alive"))
9627
- return false;
9628
- return this.deliveryInputReadyPane(pane);
9296
+ return this.deliveryInputReadyPane(await this.tmux.capturePane());
9629
9297
  }
9630
9298
  catch {
9631
9299
  this.resetFooterFallback();
@@ -10399,86 +10067,34 @@ export class Daemon extends EventEmitter {
10399
10067
  // tmux object and window — so the spawn generation and launch fence are part of the fence too: an Enter meant for
10400
10068
  // the CLI this paste went to is never sent to its successor.
10401
10069
  const tmux = this.tmux;
10402
- const backend = this.backend;
10403
- const native = !!this.nativePaneLifecycle;
10404
10070
  const generation = this.spawnGeneration;
10405
10071
  const fence = this.launchFenceEpoch;
10406
- const windowId = native ? tmux?.getWindowId() : undefined;
10407
- // M-2290 (#2985 review, Fable): the mode wait can last up to 10 minutes, and a respawn or relaunch reuses the same
10408
- // tmux object and window — so the spawn generation and launch fence are part of every pane's fence: an Enter meant
10409
- // for the CLI this paste went to is never sent to its successor. A native Windows pane keeps #2958's full fence too
10410
- // (its launch can be replaced under the same handle).
10411
10072
  const current = () => this.tmux === tmux && this.spawnGeneration === generation && this.launchFenceEpoch === fence
10412
- && !this.deliveryWritesStopping && (!stillCurrent || stillCurrent())
10413
- && (!native || (!!windowId && !!backend && this.backend === backend && tmux.getWindowId() === windowId));
10073
+ && !this.deliveryWritesStopping && (!stillCurrent || stillCurrent());
10414
10074
  if (!current())
10415
10075
  return false;
10416
10076
  // The pasted text may still be in the box: the caller keeps it uncertain (no false failure, no second paste).
10417
- // S-35: say which check withheld Enter.
10418
- const hold = (reason) => {
10419
- onInputHeld?.(reason);
10420
- if (reason === "output_changed" && current() && !this.nativeDeliveryHold())
10421
- this.nativeEnterHold = {
10422
- key: `${this.bootId}:${generation}:${fence}`, since: Date.now(), spawn: generation, fence,
10423
- };
10424
- if (reason === "pane-in-mode")
10425
- this.logger.warn({ phase, reason }, "The pane stayed in a tmux mode; Enter withheld");
10426
- else
10427
- this.logger.warn({ ...tmux?.getLastInputDiagnostic?.(), phase, reason, retryCount: positiveRefusals }, "Native delivery Enter withheld by its safety check");
10077
+ const hold = () => {
10078
+ onInputHeld?.("pane-in-mode");
10079
+ this.logger.warn({ phase }, "The pane stayed in a tmux mode; Enter withheld");
10428
10080
  return false;
10429
10081
  };
10430
10082
  // M-2267 (#2971): a pane in a tmux mode (a person left it in copy-mode) would take this Enter. Wait for the mode to
10431
10083
  // end, then look once more within the same deadline — a pane flickering back into a mode is waited out again, never
10432
- // past the bound.
10433
- // Native delivery follows main #2990: only this backend's recognised runtime dialog vetoes Enter.
10434
- // The fresh capture still binds the native host output sequence; ownership and positive-ACK-only retries remain.
10084
+ // past the bound. (beta.5: #2958's composer proof that used to sit between the two looks is reverted, decision
10085
+ // f57474aa: it rejected Codex's footer after a resume and while busy. #2957 is open again.)
10435
10086
  const modeDeadline = performance.now() + PANE_MODE_ENTER_WAIT_MS;
10436
- let pane;
10437
- let positiveRefusals = 0, enterMarked = false, positiveRetryDeadline = Infinity, linuxDialogRead = false;
10438
10087
  for (;;) {
10439
- const mode = await this.waitWhilePaneInMode(phase, current, Math.min(modeDeadline, positiveRetryDeadline));
10088
+ const mode = await this.waitWhilePaneInMode(phase, current, modeDeadline);
10440
10089
  if (mode === "stale")
10441
10090
  return false;
10442
10091
  if (mode === "held")
10443
- return hold("pane-in-mode");
10444
- if (native) {
10445
- // S-35: a native pane's capture refuses while output is still arriving ("Pane changed during capture; observe it
10446
- // again"). Right after a turn the CLI repaints for a moment; one refused read left the message unsent for ever.
10447
- // Read again a few times — reading types nothing — and still hold if it never settles.
10448
- let captured;
10449
- for (let attempt = 0; captured === undefined; attempt++) {
10450
- try {
10451
- captured = await tmux.capturePane();
10452
- }
10453
- catch {
10454
- if (!current())
10455
- return false;
10456
- if (attempt >= 4)
10457
- return hold("capture_failed");
10458
- await new Promise(done => setTimeout(done, 150 * (attempt + 1)));
10459
- if (!current())
10460
- return false;
10461
- }
10462
- }
10463
- const screen = captured;
10464
- pane = screen;
10465
- if (!current())
10466
- return false;
10467
- try {
10468
- if (backend?.getRuntimeDialogs?.().some(dialog => Daemon.dialogMatches(dialog, screen)))
10469
- return hold("dialog");
10470
- }
10471
- catch {
10472
- return hold("check_failed");
10473
- }
10474
- if (!current())
10475
- return false;
10476
- }
10092
+ return hold();
10477
10093
  if (await this.paneInTmuxMode(phase)) {
10478
10094
  if (!current())
10479
10095
  return false;
10480
10096
  if (performance.now() >= modeDeadline)
10481
- return hold("pane-in-mode");
10097
+ return hold();
10482
10098
  await new Promise(r => setTimeout(r, PANE_MODE_POLL_MS));
10483
10099
  if (!current())
10484
10100
  return false;
@@ -10486,143 +10102,54 @@ export class Daemon extends EventEmitter {
10486
10102
  }
10487
10103
  if (!current())
10488
10104
  return false;
10489
- // M-2290 (the simple half of the #2957 redesign, leader xmsg-1793712561468; main): on a Linux pane, a dialog the
10490
- // backend RECOGNISES (runtimeDialogs: a permission card, the dangerous-command card, …) that painted between the
10491
- // paste and this Enter would take the key as its answer. Read the pane once more: such a dialog withholds the
10492
- // Enter (the caller keeps the delivery uncertain → Needs-you; the dialog scanner parks it for a person). Nothing
10493
- // else is judged — an unknown or unreadable screen sends: #2958's composer proof (decision f57474aa) is NOT back.
10494
- // Only a caller that can hold asks (onInputHeld); a native pane read its own screen above, every round.
10495
- if (!native && onInputHeld && !linuxDialogRead) {
10496
- linuxDialogRead = true;
10497
- let finalPane = null;
10498
- try {
10499
- finalPane = await tmux.capturePane();
10500
- }
10501
- catch {
10502
- finalPane = null;
10503
- }
10504
- if (!current())
10505
- return false;
10506
- let dialog;
10507
- try {
10508
- dialog = finalPane === null ? undefined : (this.backend?.getRuntimeDialogs?.() ?? []).find(d => Daemon.dialogMatches(d, finalPane))?.description;
10509
- }
10510
- catch {
10511
- dialog = undefined;
10512
- }
10513
- if (dialog !== undefined) {
10514
- onInputHeld("dialog");
10515
- this.logger.warn({ phase, dialog }, "A dialog is on the pane; the delivery's Enter is withheld (it would answer it)");
10516
- return false;
10517
- }
10518
- }
10519
- if (positiveRefusals && performance.now() >= positiveRetryDeadline)
10520
- return hold("output_changed");
10521
- // W1: persist the "Enter may have happened" boundary before tmux receives
10522
- // the key. A crash after this commit is never auto-replayed without a
10523
- // positive transcript marker, even if the stale pane still shows composer.
10524
- if (!enterMarked && durableAttempt && !this.deliveryOutbox?.markEnterStarted(durableAttempt.deliveryId, this.bootId, durableAttempt.attemptNo)) {
10525
- this.logger.error({ phase, deliveryId: durableAttempt.deliveryId }, "Could not commit durable Enter write-ahead fence");
10526
- return false;
10527
- }
10528
- enterMarked = true;
10529
- const sent = await (native && pane !== undefined ? tmux.sendSpecialKey("Enter", undefined, { kind: "delivery", screen: pane, retryCount: positiveRefusals }) : tmux.sendSpecialKey("Enter"));
10530
- // A busy renderer can change seq after our capture. Only a positive zero-input ACK admits a NEW proof/key;
10531
- // An Enter retry never re-pastes, retries an uncertain write, reuses stale proof or re-commits the durable boundary.
10532
- if (!sent && native && tmux.lastInputWasNotSent?.() === true
10533
- && tmux.getLastSendSpecialKeyError() === "Pane changed after observation; input was not sent"
10534
- && current()) {
10535
- if (!positiveRefusals)
10536
- positiveRetryDeadline = Math.min(modeDeadline, performance.now() + 2000);
10537
- if (positiveRefusals >= 4 || performance.now() >= positiveRetryDeadline)
10538
- return hold("output_changed");
10539
- positiveRefusals++;
10540
- await new Promise(done => setTimeout(done, 100));
10541
- if (!current())
10542
- return false;
10543
- if (performance.now() >= positiveRetryDeadline)
10544
- return hold("output_changed");
10545
- continue;
10546
- }
10547
- if (!sent) {
10548
- const details = { phase, tmuxError: this.tmux.getLastSendSpecialKeyError() ?? "unknown tmux send-keys failure" };
10549
- if (native)
10550
- this.logger.warn({ ...tmux?.getLastInputDiagnostic?.(), ...details, retryCount: positiveRefusals }, "Native delivery Enter gave up");
10551
- else
10552
- this.logger.error(details, "tmux send-keys Enter failed during message delivery");
10553
- }
10554
- if (sent && native && current())
10555
- this.nativeEnterHold = null;
10556
- return sent;
10557
- }
10558
- }
10559
- /** A pre-existing native busy-paste race: retry bytes only after an exact, owned zero-input acknowledgement. */
10560
- async sendDeliveryPaste(text, stillCurrent) {
10561
- const pane = this.tmux, native = this.nativePaneLifecycle;
10562
- if (!native)
10563
- return pane.pasteBuffer(text);
10564
- const backend = this.backend, generation = this.spawnGeneration, fence = this.launchFenceEpoch, windowId = pane.getWindowId();
10565
- const current = () => !!windowId && this.tmux === pane && this.nativePaneLifecycle === native && this.backend === backend
10566
- && this.spawnGeneration === generation && this.launchFenceEpoch === fence && pane.getWindowId() === windowId
10567
- && !this.deliveryWritesStopping && (!stillCurrent || stillCurrent());
10568
- let retryCount = 0;
10569
- const hold = (reason) => {
10570
- if (current() && !this.nativeDeliveryHold())
10571
- this.nativeEnterHold = { key: `${this.bootId}:${generation}:${fence}`, since: Date.now(), spawn: generation, fence };
10572
- this.logger.warn({ ...pane.getLastInputDiagnostic?.(), reason, retryCount }, "Native delivery paste held by its safety check");
10573
- return false;
10574
- };
10575
- const deadline = performance.now() + 2000;
10576
- for (let attempt = 0; attempt < 5; attempt++) {
10577
- retryCount = attempt;
10578
- if (!current())
10579
- return false;
10580
- if (performance.now() >= deadline)
10581
- return hold("output_changed");
10582
- let screen;
10583
- for (let read = 0; read < 5 && screen === undefined; read++) {
10584
- try {
10585
- screen = await pane.capturePane();
10586
- }
10587
- catch { /* Reads do not construct an input operation. */ }
10588
- if (!current())
10589
- return false;
10590
- if (performance.now() >= deadline)
10591
- return hold("capture_failed");
10592
- if (screen === undefined && read < 4)
10593
- await new Promise(done => setTimeout(done, 100));
10594
- }
10595
- if (screen === undefined)
10596
- return hold("capture_failed");
10105
+ break;
10106
+ }
10107
+ // M-2290 (the simple half of the #2957 redesign, leader xmsg-1793712561468): a dialog the backend RECOGNISES
10108
+ // (runtimeDialogs: a permission card, the dangerous-command card, …) that painted between the paste and this Enter
10109
+ // would take the key as its answer. Read the pane once more: such a dialog withholds the Enter, the caller keeps the
10110
+ // delivery uncertain (Needs-you), and the dialog scanner parks the dialog for a person. Nothing else is judged here
10111
+ // — an unknown or unreadable screen sends, exactly as before: #2958's composer proof (decision f57474aa) is NOT back.
10112
+ // Only a caller that can hold (onInputHeld: the delivery's initial submit, settled uncertain → Needs-you) asks: one
10113
+ // that cannot would read `false` as a failure and paste again. Only the backend's OWN dialogs count — not AgEnD's
10114
+ // unrecognised-prompt guess — so an unknown screen still sends.
10115
+ if (onInputHeld) {
10116
+ let finalPane = null;
10597
10117
  try {
10598
- if (backend?.getRuntimeDialogs?.().some(dialog => Daemon.dialogMatches(dialog, screen)))
10599
- return hold("dialog");
10118
+ finalPane = await tmux.capturePane();
10600
10119
  }
10601
10120
  catch {
10602
- return hold("check_failed");
10121
+ finalPane = null;
10603
10122
  }
10604
10123
  if (!current())
10605
10124
  return false;
10606
- if (performance.now() >= deadline)
10607
- return hold("output_changed");
10608
- let sent;
10125
+ let dialog;
10609
10126
  try {
10610
- sent = await pane.pasteBuffer(text, { guard: current, proof: { kind: "composer", screen, retryCount: attempt } });
10127
+ dialog = finalPane === null ? undefined : (this.backend?.getRuntimeDialogs?.() ?? []).find(d => Daemon.dialogMatches(d, finalPane))?.description;
10611
10128
  }
10612
10129
  catch {
10613
- return hold("unconfirmed");
10130
+ dialog = undefined;
10614
10131
  }
10615
- if (sent)
10616
- return true; // Exactly one successful paste ends the loop, before any Enter.
10617
- if (!current())
10132
+ if (dialog !== undefined) {
10133
+ onInputHeld?.("dialog");
10134
+ this.logger.warn({ phase, dialog }, "A dialog is on the pane; the delivery's Enter is withheld (it would answer it)");
10618
10135
  return false;
10619
- if (pane.lastInputWasNotSent?.() !== true || pane.getLastPasteError?.() !== "Pane changed after observation; input was not sent")
10620
- return hold("unconfirmed");
10621
- if (attempt >= 4 || performance.now() >= deadline)
10622
- return hold("output_changed");
10623
- await new Promise(done => setTimeout(done, 100));
10136
+ }
10137
+ }
10138
+ // W1: persist the "Enter may have happened" boundary before tmux receives
10139
+ // the key. A crash after this commit is never auto-replayed without a
10140
+ // positive transcript marker, even if the stale pane still shows composer.
10141
+ if (durableAttempt && !this.deliveryOutbox?.markEnterStarted(durableAttempt.deliveryId, this.bootId, durableAttempt.attemptNo)) {
10142
+ this.logger.error({ phase, deliveryId: durableAttempt.deliveryId }, "Could not commit durable Enter write-ahead fence");
10143
+ return false;
10144
+ }
10145
+ const sent = await tmux.sendSpecialKey("Enter");
10146
+ if (!sent) {
10147
+ this.logger.error({
10148
+ phase,
10149
+ tmuxError: this.tmux.getLastSendSpecialKeyError() ?? "unknown tmux send-keys failure",
10150
+ }, "tmux send-keys Enter failed during message delivery");
10624
10151
  }
10625
- return hold("output_changed");
10152
+ return sent;
10626
10153
  }
10627
10154
  async writeMessageToPane(formatted, initialWindowId, handingOffToNativeQueue, status, submissionId,
10628
10155
  // Last and defaulted so the positional callers that ignore the outcome stay
@@ -10660,9 +10187,6 @@ export class Daemon extends EventEmitter {
10660
10187
  const tmuxAtWrite = this.tmux;
10661
10188
  const steerCurrent = () => (!stillCurrent || stillCurrent()) && !this.deliveryWritesStopping
10662
10189
  && this.tmux === tmuxAtWrite && this.spawnGeneration === spawnAtWrite;
10663
- // Alpha (S-36, Prism #2989 P2): a NATIVE pane keeps #2958's pre-paste owner fence through the initial Enter and every
10664
- // retry Enter (a pane replaced while the paste awaits never takes this delivery's Enter); a tmux pane follows main.
10665
- const nativeOwner = this.nativePaneLifecycle ? steerCurrent : undefined;
10666
10190
  // Bug A: paste with backoff. Transient failures are usually a stale window id
10667
10191
  // after a crash/respawn — recover by name and retry (max 3 attempts, 2s apart).
10668
10192
  const maxAttempts = 3;
@@ -10730,8 +10254,8 @@ export class Daemon extends EventEmitter {
10730
10254
  }
10731
10255
  verdict.durableBeginCommitted = true;
10732
10256
  verdict.submissionMode = attemptEvidence.submissionMode;
10733
- if (attemptEvidence.runtimeTranscript || attemptEvidence.transcriptPath && attemptEvidence.transcriptOffset !== null) {
10734
- verdict.transcriptCheckpoint = attemptEvidence.runtimeTranscript ? { backend: attemptEvidence.backend, runtime: attemptEvidence.runtimeTranscript } : {
10257
+ if (attemptEvidence.transcriptPath && attemptEvidence.transcriptOffset !== null) {
10258
+ verdict.transcriptCheckpoint = {
10735
10259
  backend: attemptEvidence.backend,
10736
10260
  path: attemptEvidence.transcriptPath,
10737
10261
  offset: attemptEvidence.transcriptOffset,
@@ -10807,15 +10331,7 @@ export class Daemon extends EventEmitter {
10807
10331
  }
10808
10332
  const pasteGeneration = this.spawnGeneration;
10809
10333
  beforePaste?.();
10810
- const pasted = await this.sendDeliveryPaste(formatted, nativeOwner);
10811
- if (!pasted && this.nativePaneLifecycle) {
10812
- // The native write attempt is retained as uncertain, including exhausted positive refusals. Never route an
10813
- // unknown/partial write through legacy window recovery or abort it back to an automatically replayable row.
10814
- verdict.paneWriteStarted = true;
10815
- verdict.phase = "paste";
10816
- verdict.proof = "native-paste-held";
10817
- return false;
10818
- }
10334
+ const pasted = await this.tmux.pasteBuffer(formatted);
10819
10335
  if (pasted)
10820
10336
  this.rememberPaste(formatted, pasteGeneration);
10821
10337
  if (!pasted) {
@@ -10902,18 +10418,15 @@ export class Daemon extends EventEmitter {
10902
10418
  const enterMono = performance.now();
10903
10419
  const steerEnterCurrent = () => steerCurrent() && performance.now() <= steerEnterDeadline;
10904
10420
  let inputHeld = null;
10905
- if (!(await this.sendDeliveryEnter("initial-submit", steerComposerProof || nativeOwner ? steerEnterCurrent : undefined, durableAttempt, (why) => { inputHeld = why; }))) {
10421
+ if (!(await this.sendDeliveryEnter("initial-submit", steerComposerProof ? steerEnterCurrent : undefined, durableAttempt, (why) => { inputHeld = why; }))) {
10906
10422
  if (inputHeld) {
10907
10423
  // #2971: held in a tmux mode past the bound; M-2290: a recognised dialog on the pane. The paste may still be in
10908
10424
  // the CLI: keep it uncertain (Needs-you), never re-paste, never answer the dialog.
10909
10425
  verdict.phase = "submit-enter";
10910
- // The merge of #2957/M-2290 (main) and the alpha's native holds: a tmux mode, a recognised dialog on a Linux pane,
10911
- // and each native safety check say which.
10912
- verdict.proof = inputHeld === "pane-in-mode" ? "pane-in-mode-held" : nativeOwner ? `native-input-${inputHeld}`
10913
- : inputHeld === "dialog" ? "dialog-on-pane" : `input-held-${inputHeld}`;
10426
+ verdict.proof = inputHeld === "dialog" ? "dialog-on-pane" : "pane-in-mode-held";
10914
10427
  return false;
10915
10428
  }
10916
- if ((steerComposerProof || nativeOwner) && !steerCurrent()) {
10429
+ if (steerComposerProof && !steerCurrent()) {
10917
10430
  verdict.phase = "submit-enter";
10918
10431
  verdict.proof = "fenced-before-enter";
10919
10432
  return false;
@@ -10943,7 +10456,7 @@ export class Daemon extends EventEmitter {
10943
10456
  if (!rawPaste && !steerComposerProof && this.backend?.requiresDeliveryEnterRetry?.() === true) {
10944
10457
  await new Promise(r => setTimeout(r, 1_000));
10945
10458
  const retryAt = Date.now();
10946
- if (await this.sendDeliveryEnter("queue-less-defensive-retry", nativeOwner)) {
10459
+ if (await this.sendDeliveryEnter("queue-less-defensive-retry")) {
10947
10460
  enterAt = retryAt;
10948
10461
  enterRetry = true;
10949
10462
  this.logger.debug("Sent defensive Enter retry (queue-less TUI can swallow the first)");
@@ -11081,7 +10594,7 @@ export class Daemon extends EventEmitter {
11081
10594
  // again. The prompt is back now, so an Enter can land.
11082
10595
  this.logger.warn("Message still in the input row after idle — submitting the existing text instead of pasting it again");
11083
10596
  const strandedAt = Date.now();
11084
- if (!(await this.sendDeliveryEnter("native-queue-stranded-submit", nativeOwner))) {
10597
+ if (!(await this.sendDeliveryEnter("native-queue-stranded-submit"))) {
11085
10598
  return this.failDelivery(verdict, status, "native-queue-submit", "tmux-send-keys-failed");
11086
10599
  }
11087
10600
  // The recovery Enter can be accepted before Codex paints its new
@@ -11134,7 +10647,7 @@ export class Daemon extends EventEmitter {
11134
10647
  }
11135
10648
  await new Promise(r => setTimeout(r, NORMAL_ENTER_SETTLE_MS));
11136
10649
  const retryAt = Date.now();
11137
- if (!(await this.sendDeliveryEnter("native-queue-idle-redelivery", nativeOwner))) {
10650
+ if (!(await this.sendDeliveryEnter("native-queue-idle-redelivery"))) {
11138
10651
  return this.failDelivery(verdict, status, "native-queue-redelivery", "tmux-send-keys-failed");
11139
10652
  }
11140
10653
  if (windowId && this.controlClient) {
@@ -11186,7 +10699,7 @@ export class Daemon extends EventEmitter {
11186
10699
  this.logger.warn("Message not submitted after Enter — waiting for the prompt, then re-sending Enter once");
11187
10700
  const promptBack = await this.waitForPaneReadyForDelivery(windowId, STRANDED_RETRY_READY_WAIT_MS);
11188
10701
  const retryAt = Date.now();
11189
- if (promptBack && !(await this.sendDeliveryEnter("stranded-text-retry", nativeOwner))) {
10702
+ if (promptBack && !(await this.sendDeliveryEnter("stranded-text-retry"))) {
11190
10703
  return this.failDelivery(verdict, status, "stranded-text-retry", "tmux-send-keys-failed");
11191
10704
  }
11192
10705
  submitted = promptBack && await this.confirmSubmittedAfterEnter(windowId, retryAt, formatted);
@@ -11274,7 +10787,7 @@ export class Daemon extends EventEmitter {
11274
10787
  }
11275
10788
  // No control client to observe output: fall back to the legacy double-Enter.
11276
10789
  await new Promise(r => setTimeout(r, 1000));
11277
- await this.sendDeliveryEnter("unobserved-defensive-retry", nativeOwner);
10790
+ await this.sendDeliveryEnter("unobserved-defensive-retry");
11278
10791
  if (status)
11279
10792
  this.emit("message_confirmed", status); // ✅ (best-effort)
11280
10793
  }
@@ -11494,22 +11007,14 @@ export class Daemon extends EventEmitter {
11494
11007
  * and the caller's own fence — so a look that lands after any of them is never used (#1380 review).
11495
11008
  */
11496
11009
  transcriptProofFor(checkpoint, needle, spawnAtWrite, stillCurrent, onProof) {
11497
- if (this.nativePaneLifecycle && !checkpoint.runtime)
11498
- throw Error("Native proof cannot read a coordinator-local transcript path");
11499
11010
  const launchAtWrite = this.launchFenceEpoch;
11500
11011
  return {
11501
- reader: checkpoint.runtime ? this.nativeTranscriptReader(checkpoint.runtime, needle) : new TranscriptDeltaReader(checkpoint.path, checkpoint.offset, checkpoint.backend, needle),
11012
+ reader: new TranscriptDeltaReader(checkpoint.path, checkpoint.offset, checkpoint.backend, needle),
11502
11013
  current: () => !this.deliveryWritesStopping && this.spawnGeneration === spawnAtWrite
11503
- && this.launchFenceEpoch === launchAtWrite && (stillCurrent?.() ?? true)
11504
- && (!checkpoint.runtime || this.nativePaneLifecycle?.current(checkpoint.runtime) === true),
11014
+ && this.launchFenceEpoch === launchAtWrite && (stillCurrent?.() ?? true),
11505
11015
  onProof,
11506
11016
  };
11507
11017
  }
11508
- nativeTranscriptReader(reference, needle) {
11509
- if (!this.nativePaneLifecycle || !this.nativePaneLifecycle.current(reference))
11510
- throw Error("Native delivery transcript owner is unavailable");
11511
- return this.nativePaneLifecycle.proofReader(reference, needle);
11512
- }
11513
11018
  /** The CLI this daemon drives, for log lines shared by every backend ("claude-code", "codex", …). */
11514
11019
  cliLabel() {
11515
11020
  return this.config.backend ?? this.backend?.binaryName ?? "CLI";
@@ -11759,14 +11264,7 @@ export class Daemon extends EventEmitter {
11759
11264
  * (the retries included). Without a guard it is exactly the old unconditional path.
11760
11265
  */
11761
11266
  async submitSystemPaste(text, label, guard, admission) {
11762
- // Alpha (S-36, Prism #2989 P2): a NATIVE pane's system paste keeps the pane owner from before its first await
11763
- // (#2958's fence, reverted on main for tmux panes) — a pane replaced while the paste awaits never takes its Enter.
11764
- const native = !!this.nativePaneLifecycle;
11765
- const ownerTmux = this.tmux, ownerGeneration = this.spawnGeneration, ownerFence = this.launchFenceEpoch;
11766
- const ownerWindow = native ? ownerTmux?.getWindowId() : undefined;
11767
- const owner = () => !native || (!!ownerTmux && !!ownerWindow && this.tmux === ownerTmux && ownerTmux.getWindowId() === ownerWindow
11768
- && this.spawnGeneration === ownerGeneration && this.launchFenceEpoch === ownerFence && !this.deliveryWritesStopping);
11769
- const current = guard || admission || native ? () => { admission?.(); return owner() && (guard?.current() ?? true); } : undefined;
11267
+ const current = guard || admission ? () => { admission?.(); return guard?.current() ?? true; } : undefined;
11770
11268
  if (current && !current())
11771
11269
  return false;
11772
11270
  if (!this.tmux)
@@ -11784,10 +11282,6 @@ export class Daemon extends EventEmitter {
11784
11282
  if (!current() || !guard.accept(pane))
11785
11283
  return false;
11786
11284
  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
- }
11791
11285
  }
11792
11286
  else {
11793
11287
  baseline = await this.capturePaneEvidence(signature);
@@ -11891,13 +11385,13 @@ export class Daemon extends EventEmitter {
11891
11385
  && sameInteractionOwner(recoveryOwner, this.interactionOwner());
11892
11386
  const previousWindowId = this.tmux?.getWindowId();
11893
11387
  try {
11894
- const windows = await this.paneHost.listWindows(this.tmuxSessionName, this.controlClient);
11388
+ const windows = await TmuxManager.listWindows(this.tmuxSessionName, this.controlClient);
11895
11389
  if (!recoveryCurrent() || this.tmux !== previousTmux)
11896
11390
  return undefined;
11897
11391
  const match = windows.find(w => w.name === this.name);
11898
11392
  if (!match)
11899
11393
  return undefined;
11900
- this.tmux = this.paneHost.bind(this.tmuxSessionName, match.id, resolveTmuxLogicalSize(this.config.terminal), this.controlClient);
11394
+ this.tmux = new TmuxManager(this.tmuxSessionName, match.id, resolveTmuxLogicalSize(this.config.terminal), this.controlClient);
11901
11395
  const recoveredTmux = this.tmux;
11902
11396
  writeFileSync(join(this.instanceDir, "window-id"), match.id);
11903
11397
  // The window we were talking to is gone; leaving it registered means the
@@ -11960,8 +11454,6 @@ export class Daemon extends EventEmitter {
11960
11454
  return false;
11961
11455
  }
11962
11456
  getWindowId() {
11963
- if (this.nativePaneLifecycle)
11964
- return this.nativePaneLifecycle.current() ? this.tmux?.getWindowId() : undefined;
11965
11457
  try {
11966
11458
  return readFileSync(join(this.instanceDir, "window-id"), "utf-8").trim() || undefined;
11967
11459
  }
@@ -11993,55 +11485,7 @@ export class Daemon extends EventEmitter {
11993
11485
  * Handle a tool call from the MCP server (forwarded by Claude).
11994
11486
  * Routes to the channel adapter via MessageBus.
11995
11487
  */
11996
- /** Internal native-MCP admission. The pane/machine/launch owner supplies a current, dynamically checked tool lease. */
11997
- handlePaneToolCall(input, lease) {
11998
- const refusal = nativePaneToolRefusal(input.tool, input.args);
11999
- if (refusal)
12000
- return Promise.resolve({ result: null, error: refusal });
12001
- if (!lease.current() || !lease.allowed(input.tool, input.args) || this.deliveryWritesStopping)
12002
- return Promise.resolve({ result: null, error: "Pane tool permission is no longer current" });
12003
- const fence = this.launchFenceEpoch;
12004
- const current = () => lease.current() && lease.allowed(input.tool, input.args) && !this.deliveryWritesStopping && fence === this.launchFenceEpoch;
12005
- return new Promise(resolve => {
12006
- let settled = false;
12007
- const finish = (value) => { if (settled)
12008
- return; settled = true; clearTimeout(timer); resolve(value); };
12009
- const timer = setTimeout(() => finish({ result: null, error: "Pane tool result is unconfirmed; inspect its operation before retrying" }), daemonBudgetMs(input.tool) + 1000);
12010
- timer.unref?.();
12011
- try {
12012
- this.handleToolCall({ ...input, requestId: ++this.fleetRequestSeq }, undefined, {
12013
- current,
12014
- dispatch: (tool, args, respond) => {
12015
- if (!current()) {
12016
- respond(null, "Pane tool permission was revoked before dispatch");
12017
- return true;
12018
- }
12019
- const dispatched = lease.dispatch?.(tool, args);
12020
- if (!dispatched)
12021
- return false;
12022
- void dispatched.then(result => respond(result), () => respond(null, "Pane tool operation was refused"));
12023
- return true;
12024
- },
12025
- // Resolving the relay is not proof that its HTTP response reached the provider. No response-written receipt yet.
12026
- send: value => {
12027
- finish({ result: value.result, ...(typeof value.error === "string" ? { error: value.error } : {}),
12028
- ...(typeof value.errorCode === "string" || typeof value.errorCode === "number" ? { errorCode: value.errorCode } : {}) });
12029
- return false;
12030
- },
12031
- });
12032
- }
12033
- catch {
12034
- finish({ result: null, error: "Pane tool operation failed" });
12035
- }
12036
- });
12037
- }
12038
- /** Only the authority lease with a verified helper stdout ACK calls this internal barrier. */
12039
- paneToolResponseWritten(operationId, current) {
12040
- if (!current() || this.deliveryWritesStopping || !/^[a-f0-9-]{36}$/i.test(operationId))
12041
- return;
12042
- this.emit("mcp_tool_response_written", { operationId, daemonBootId: this.bootId });
12043
- }
12044
- handleToolCall(msg, socket, peer) {
11488
+ handleToolCall(msg, socket) {
12045
11489
  const tool = msg.tool;
12046
11490
  const args = (msg.args ?? {});
12047
11491
  const requestId = msg.requestId;
@@ -12049,20 +11493,20 @@ export class Daemon extends EventEmitter {
12049
11493
  this.logger.debug({ tool, requestId }, "Tool call from MCP server");
12050
11494
  // A tool call can only come from a live MCP server of ours — proof of life
12051
11495
  // that outranks whatever the pid slot says.
12052
- if (peer?.current() || socket && this.socketSessionNames.get(socket) === this.name) {
12053
- this.noteMcpProofOfLife("tool_call", socket ? this.socketPids.get(socket) : undefined);
11496
+ if (this.socketSessionNames.get(socket) === this.name) {
11497
+ this.noteMcpProofOfLife("tool_call", this.socketPids.get(socket));
12054
11498
  }
12055
11499
  // A tool invocation is not delivery evidence. Capture which obligation it
12056
11500
  // belongs to now, then settle it only after the adapter/fleet responds.
12057
11501
  // Explicitly mapped sibling sessions must not satisfy this instance's turn;
12058
11502
  // an unmapped socket is retained for legacy/tests where mcp_ready was not
12059
11503
  // observed before the first tool call.
12060
- const sourceSession = peer ? this.name : socket ? this.socketSessionNames.get(socket) : undefined;
11504
+ const sourceSession = this.socketSessionNames.get(socket);
12061
11505
  const replyAttempt = TURN_OUTBOUND_TOOLS.has(tool) && (!sourceSession || sourceSession === this.name)
12062
11506
  ? this.turnReplyGuard.beginToolAttempt(tool === "reply", TURN_COMPLETION_TOOLS.has(tool))
12063
11507
  : null;
12064
11508
  // For now, log and respond. Full adapter routing will be wired in fleet manager.
12065
- const respond = (result, error, errorCode) => {
11509
+ const respond = (result, error) => {
12066
11510
  // A message that verifiably went out stands down the dead-MCP proxy reply
12067
11511
  // for this turn: the agent proved it can still speak for itself.
12068
11512
  if (!error && result != null && TURN_OUTBOUND_TOOLS.has(tool)) {
@@ -12103,21 +11547,14 @@ export class Daemon extends EventEmitter {
12103
11547
  // failed" and report unknown immediately rather than starting recovery.
12104
11548
  this.turnReplyGuard.settleToolAttempt(replyAttempt, false);
12105
11549
  }
12106
- const packet = { requestId, result, error, operationId, ...(errorCode !== undefined ? { errorCode } : {}) };
12107
- const sent = peer ? peer.current() && peer.send(packet) : socket ? this.ipcServer?.send(socket, packet) ?? false : false;
11550
+ const sent = this.ipcServer?.send(socket, { requestId, result, error, operationId }) ?? false;
12108
11551
  if (!sent) {
12109
- if (peer)
12110
- this.logger.debug({ tool, requestId }, "Native MCP result awaits transport-written confirmation");
12111
- else
12112
- this.logger.warn({ tool, requestId }, "Tool result could not be returned — originating MCP socket is closed");
11552
+ this.logger.warn({ tool, requestId }, "Tool result could not be returned — originating MCP socket is closed");
12113
11553
  }
12114
11554
  else if (operationId) {
12115
11555
  this.emit("mcp_tool_response_written", { operationId, daemonBootId: this.bootId });
12116
11556
  }
12117
11557
  };
12118
- // Native Fleet/task operations carry their lease to the existing dispatcher mutation admission points.
12119
- if (peer?.dispatch?.(tool, args, respond))
12120
- return;
12121
11558
  // Repo checkout — handled locally in daemon (no fleet-manager)
12122
11559
  if (tool === "checkout_repo") {
12123
11560
  this.handleCheckoutRepo(args, respond);
@@ -12146,7 +11583,7 @@ export class Daemon extends EventEmitter {
12146
11583
  clearTimeout(timeout);
12147
11584
  respond(respMsg.result, respMsg.error);
12148
11585
  });
12149
- this.broadcastFleetMessage({
11586
+ this.ipcServer?.broadcast({
12150
11587
  type,
12151
11588
  payload: args,
12152
11589
  meta: { instance_name: this.name },
@@ -12172,7 +11609,7 @@ export class Daemon extends EventEmitter {
12172
11609
  clearTimeout(timeout);
12173
11610
  resolve({ result: respMsg.result, error: respMsg.error });
12174
11611
  });
12175
- this.broadcastFleetMessage({ type: WEB_THEME_IPC[tool], payload, meta: { instance_name: this.name }, fleetRequestId: fleetReqId });
11612
+ this.ipcServer?.broadcast({ type: WEB_THEME_IPC[tool], payload, meta: { instance_name: this.name }, fleetRequestId: fleetReqId });
12176
11613
  });
12177
11614
  void (async () => {
12178
11615
  if (tool === "preview_web_appearance") {
@@ -12249,7 +11686,7 @@ export class Daemon extends EventEmitter {
12249
11686
  clearTimeout(timeout);
12250
11687
  respond(respMsg.result, respMsg.error);
12251
11688
  });
12252
- this.broadcastFleetMessage({
11689
+ this.ipcServer?.broadcast({
12253
11690
  type: "fleet_task",
12254
11691
  payload: args,
12255
11692
  meta: { instance_name: this.name },
@@ -12272,7 +11709,7 @@ export class Daemon extends EventEmitter {
12272
11709
  clearTimeout(timeout);
12273
11710
  respond(respMsg.result, respMsg.error);
12274
11711
  });
12275
- this.broadcastFleetMessage({
11712
+ this.ipcServer?.broadcast({
12276
11713
  type: typeMap[tool],
12277
11714
  payload: args,
12278
11715
  meta: { instance_name: this.name, working_directory: this.config.working_directory },
@@ -12299,7 +11736,7 @@ export class Daemon extends EventEmitter {
12299
11736
  clearTimeout(timeout);
12300
11737
  respond(respMsg.result, respMsg.error);
12301
11738
  });
12302
- this.broadcastFleetMessage({
11739
+ this.ipcServer?.broadcast({
12303
11740
  type: typeMap[tool],
12304
11741
  payload: args,
12305
11742
  meta: {
@@ -12314,11 +11751,11 @@ export class Daemon extends EventEmitter {
12314
11751
  }
12315
11752
  if (CROSS_INSTANCE_TOOLS.has(tool)) {
12316
11753
  // Route to fleet manager via IPC (topic mode only)
12317
- if (this.topicMode && this.fleetTransportAvailable()) {
11754
+ if (this.topicMode && this.ipcServer) {
12318
11755
  // Use fleetRequestId (not requestId) to avoid MCP server resolving the
12319
11756
  // pending tool call prematurely when it receives the broadcast.
12320
11757
  const fleetReqId = `xmsg_${++this.fleetRequestSeq}_${requestId}`;
12321
- const senderSessionName = sourceSession;
11758
+ const senderSessionName = this.socketSessionNames.get(socket);
12322
11759
  // Shared table, so delete_instance and the deployment tools get the same
12323
11760
  // budget here as the MCP client expects (the ad-hoc list omitted them).
12324
11761
  const crossTimeoutMs = daemonBudgetMs(tool);
@@ -12330,7 +11767,7 @@ export class Daemon extends EventEmitter {
12330
11767
  clearTimeout(timeout);
12331
11768
  respond(respMsg.result, respMsg.error);
12332
11769
  });
12333
- this.broadcastFleetMessage({
11770
+ this.ipcServer.broadcast({
12334
11771
  type: "fleet_outbound",
12335
11772
  tool,
12336
11773
  args,
@@ -12384,12 +11821,12 @@ export class Daemon extends EventEmitter {
12384
11821
  }, daemonBudgetMs(tool));
12385
11822
  this.pendingIpcRequests.set(outboundKey, (respMsg) => {
12386
11823
  clearTimeout(timeout);
12387
- respond(respMsg.result, respMsg.error, respMsg.errorCode);
11824
+ respond(respMsg.result, respMsg.error);
12388
11825
  });
12389
11826
  // Register the waiter before broadcasting. A fast/mock adapter can settle
12390
11827
  // immediately; broadcasting first left a response-before-registration
12391
11828
  // window that degraded into a timeout despite a completed POST.
12392
- this.broadcastFleetMessage({
11829
+ this.ipcServer?.broadcast({
12393
11830
  type: "fleet_outbound",
12394
11831
  tool,
12395
11832
  args,
@@ -12520,7 +11957,7 @@ export class Daemon extends EventEmitter {
12520
11957
  // The daemon used to read `general_topic` alone while `isGeneralInstance`
12521
11958
  // also accepted the name, so an instance called `general` without the flag
12522
11959
  // was a worker here and a general everywhere else.
12523
- const isGeneral = this.config.general_topic === true || generalByName(this.name, this.config);
11960
+ const isGeneral = this.config.general_topic === true || this.name === "general";
12524
11961
  // No third argument for an ordinary instance: the default is `worker` now,
12525
11962
  // and naming it here would be a second place to change it.
12526
11963
  const toolSet = isGeneral
@@ -12683,7 +12120,6 @@ export class Daemon extends EventEmitter {
12683
12120
  this.cancelCapacityNudge("the instance was stopped, paused or respawned");
12684
12121
  this.lastErrorEpisode = null;
12685
12122
  this.quotaReplay = null;
12686
- this.nativeQuotaReplayTaken = false;
12687
12123
  this.quotaInput = null;
12688
12124
  this.nudgeBaselines = null;
12689
12125
  // A relaunch settles any outstanding quit watch: the CLI came back.
@@ -12899,8 +12335,6 @@ export class Daemon extends EventEmitter {
12899
12335
  catch { /* best effort */ }
12900
12336
  }
12901
12337
  async spawnClaudeWindow() {
12902
- if (this.nativePaneLifecycle)
12903
- throw Error("Native panes never enter local resume/fresh fallback");
12904
12338
  this.assertSessionOomAdmission();
12905
12339
  this.beginSpawn();
12906
12340
  let resumedSuccessfully = false;
@@ -13487,14 +12921,6 @@ export class Daemon extends EventEmitter {
13487
12921
  await this.museUsageRelay.stop().catch(() => { });
13488
12922
  this.museUsageRelay = null;
13489
12923
  }
13490
- if (this.nativePaneLifecycle) {
13491
- await this.nativePaneLifecycle.release("detach");
13492
- try {
13493
- unlinkSync(join(this.instanceDir, "daemon.pid"));
13494
- }
13495
- catch { /* metadata only */ }
13496
- return;
13497
- }
13498
12924
  try {
13499
12925
  await this.killProcessTree("SIGTERM", "startup aborted");
13500
12926
  }
@@ -13524,15 +12950,13 @@ export class Daemon extends EventEmitter {
13524
12950
  }
13525
12951
  /** Kill the entire process tree of the current tmux pane (CLI + MCP server). */
13526
12952
  async killProcessTree(signal = "SIGTERM", reason = "unspecified") {
13527
- if (this.nativePaneLifecycle)
13528
- throw Error("Native processes can only be closed through their owned runtime pane");
13529
12953
  const windowId = this.tmux?.getWindowId();
13530
12954
  // Before createWindow succeeds there is no pane owned by this daemon.
13531
12955
  // tmux interprets an empty selector as the session's active window.
13532
12956
  if (!windowId?.trim())
13533
12957
  return;
13534
12958
  try {
13535
- const pid = await this.paneHost.getPanePid(this.tmuxSessionName, windowId);
12959
+ const pid = await TmuxManager.getPanePid(this.tmuxSessionName, windowId);
13536
12960
  if (pid) {
13537
12961
  this.noteStopRequest(signal, reason);
13538
12962
  process.kill(-pid, signal);
@@ -13751,7 +13175,7 @@ export class Daemon extends EventEmitter {
13751
13175
  whatsNewRoles() {
13752
13176
  if (this.runtimeIdentity?.kind === "classic")
13753
13177
  return ["classic"];
13754
- if (this.config.general_topic === true || generalByName(this.name, this.config))
13178
+ if (this.config.general_topic === true || this.name === "general")
13755
13179
  return ["general"];
13756
13180
  const set = resolveToolSet(this.config, this.name);
13757
13181
  return set === "coordinator" || set === "full" ? ["worker", "coordinator"] : ["worker"];
@@ -13778,8 +13202,6 @@ export class Daemon extends EventEmitter {
13778
13202
  }
13779
13203
  }
13780
13204
  async trySpawnInsideGate(reuseWindow = false, startupTimeoutMs) {
13781
- if (this.nativePaneLifecycle)
13782
- throw Error("Native relaunch requires its owned exit and a new lifecycle reservation");
13783
13205
  this.assertSessionOomAdmission();
13784
13206
  this.startupAdmission?.();
13785
13207
  const launchFence = this.launchFenceEpoch;
@@ -13892,8 +13314,8 @@ export class Daemon extends EventEmitter {
13892
13314
  this.emit("backend_launch_warning", { name: this.name, message: note, quiet: true });
13893
13315
  }
13894
13316
  // Ensure tmux session exists (may have been destroyed if all windows died)
13895
- await this.paneHost.ensureSession(this.tmuxSessionName);
13896
- if (this.stormWindow?.observeServerAlive(await this.paneHost.getServerPid(this.tmuxSessionName))) {
13317
+ await TmuxManager.ensureSession(this.tmuxSessionName);
13318
+ if (this.stormWindow?.observeServerAlive(await TmuxManager.getServerPid(this.tmuxSessionName))) {
13897
13319
  this.emit("tmux_server_crash", this.name);
13898
13320
  }
13899
13321
  this.startupAdmission?.();
@@ -14170,15 +13592,12 @@ export class Daemon extends EventEmitter {
14170
13592
  // each have seen a respawn, pause or stop.
14171
13593
  if (!owned())
14172
13594
  return false;
14173
- const keyScreen = this.nativePaneLifecycle ? await this.tmux.capturePane() : answeredPane;
14174
- if (!owned() || !Daemon.dialogMatches(dialog, keyScreen))
14175
- return false;
14176
13595
  if (key === "Up" || key === "Down" || key === "Enter" || key === "Escape") {
14177
- if (!await (this.nativePaneLifecycle ? this.tmux.sendSpecialKey(key, undefined, { kind: "dialog", screen: keyScreen }) : this.tmux.sendSpecialKey(key)))
13596
+ if (!await this.tmux.sendSpecialKey(key))
14178
13597
  return false;
14179
13598
  }
14180
13599
  else {
14181
- if (!await (this.nativePaneLifecycle ? this.tmux.sendKeys(key, { kind: "dialog", screen: keyScreen }) : this.tmux.sendKeys(key)))
13600
+ if (!await this.tmux.sendKeys(key))
14182
13601
  return false;
14183
13602
  }
14184
13603
  await new Promise(r => setTimeout(r, 200));
@@ -14192,8 +13611,7 @@ export class Daemon extends EventEmitter {
14192
13611
  // Wait for next screen to render — bounded by what is left of the budget.
14193
13612
  const renderWait = Math.max(0, Math.min(10_000, remaining()));
14194
13613
  if (this.controlClient) {
14195
- const wid = this.nativePaneLifecycle ? ownerTmux.getWindowId()
14196
- : readFileSync(join(this.instanceDir, "window-id"), "utf-8").trim();
13614
+ const wid = readFileSync(join(this.instanceDir, "window-id"), "utf-8").trim();
14197
13615
  await this.controlClient.waitForIdle(wid, renderWait);
14198
13616
  }
14199
13617
  else {
@@ -14229,9 +13647,7 @@ export class Daemon extends EventEmitter {
14229
13647
  // scan parked on the old limit text.
14230
13648
  const codexReady = this.backend.binaryName !== "codex"
14231
13649
  || this.isCodexLivePaneSnapshot(pane);
14232
- const nativeComposerReady = !this.nativePaneLifecycle || (this.backend?.readInputRow
14233
- ? this.backend.readInputRow(pane) !== null : this.backend?.isDeliveryInputReadyPane?.(pane) === true);
14234
- if (readyPatternMatches && codexReady && nativeComposerReady) {
13650
+ if (readyPatternMatches && codexReady) {
14235
13651
  cleanReadyPolls++;
14236
13652
  if (cleanReadyPolls >= 2 || remaining() <= 0) {
14237
13653
  // A real ready prompt (with no fatal dialog on screen — those are
@@ -14360,16 +13776,6 @@ export class Daemon extends EventEmitter {
14360
13776
  void refresh.call(this.backend).then(() => this.saveSessionId(), () => { });
14361
13777
  }
14362
13778
  saveSessionId() {
14363
- if (this.nativePaneLifecycle) {
14364
- try {
14365
- this.nativePaneLifecycle.checkpointSession();
14366
- this.ownedWorkingSession = this.backend?.getSessionId() ?? null;
14367
- }
14368
- catch (err) {
14369
- this.logger.warn({ err }, "Native conversation checkpoint is unconfirmed");
14370
- }
14371
- return;
14372
- }
14373
13779
  // When a resume failure has forced a fresh start, don't persist the stale id
14374
13780
  // back from statusline.json — that would re-arm --continue and re-loop.
14375
13781
  if (this.skipResume)