@songsid/agend 2.1.12 → 2.2.0-alpha.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 (358) hide show
  1. package/README.md +2 -2
  2. package/README.zh-TW.md +2 -2
  3. package/dist/auth/one-time-code.d.ts +19 -0
  4. package/dist/auth/one-time-code.js +49 -0
  5. package/dist/auth/one-time-code.js.map +1 -0
  6. package/dist/auth-api.d.ts +52 -0
  7. package/dist/auth-api.js +346 -0
  8. package/dist/auth-api.js.map +1 -0
  9. package/dist/backend/claude-code.d.ts +4 -0
  10. package/dist/backend/claude-code.js +97 -0
  11. package/dist/backend/claude-code.js.map +1 -1
  12. package/dist/backend/codex.js +59 -30
  13. package/dist/backend/codex.js.map +1 -1
  14. package/dist/backend/kiro-agent.d.ts +66 -0
  15. package/dist/backend/kiro-agent.js +302 -0
  16. package/dist/backend/kiro-agent.js.map +1 -0
  17. package/dist/backend/kiro-identity.d.ts +80 -0
  18. package/dist/backend/kiro-identity.js +537 -0
  19. package/dist/backend/kiro-identity.js.map +1 -0
  20. package/dist/backend/kiro-v2-store-worker.d.ts +1 -0
  21. package/dist/backend/kiro-v2-store-worker.js +87 -0
  22. package/dist/backend/kiro-v2-store-worker.js.map +1 -0
  23. package/dist/backend/kiro-v2-store.d.ts +54 -0
  24. package/dist/backend/kiro-v2-store.js +131 -0
  25. package/dist/backend/kiro-v2-store.js.map +1 -0
  26. package/dist/backend/kiro-v3-identity.d.ts +5 -0
  27. package/dist/backend/kiro-v3-identity.js +22 -0
  28. package/dist/backend/kiro-v3-identity.js.map +1 -1
  29. package/dist/backend/kiro.d.ts +83 -7
  30. package/dist/backend/kiro.js +418 -91
  31. package/dist/backend/kiro.js.map +1 -1
  32. package/dist/backend/types.d.ts +45 -3
  33. package/dist/backend/types.js.map +1 -1
  34. package/dist/channel/adapters/discord.d.ts +1 -0
  35. package/dist/channel/adapters/discord.js +29 -10
  36. package/dist/channel/adapters/discord.js.map +1 -1
  37. package/dist/channel/adapters/telegram.d.ts +1 -0
  38. package/dist/channel/adapters/telegram.js +13 -1
  39. package/dist/channel/adapters/telegram.js.map +1 -1
  40. package/dist/channel/types.d.ts +9 -1
  41. package/dist/classic-channel-manager.d.ts +18 -10
  42. package/dist/classic-channel-manager.js +45 -18
  43. package/dist/classic-channel-manager.js.map +1 -1
  44. package/dist/cli.js +225 -127
  45. package/dist/cli.js.map +1 -1
  46. package/dist/command-table.d.ts +5 -3
  47. package/dist/command-table.js +29 -27
  48. package/dist/command-table.js.map +1 -1
  49. package/dist/config-validator.js +46 -0
  50. package/dist/config-validator.js.map +1 -1
  51. package/dist/config.js +12 -0
  52. package/dist/config.js.map +1 -1
  53. package/dist/connection-secrets.d.ts +6 -0
  54. package/dist/connection-secrets.js +4 -0
  55. package/dist/connection-secrets.js.map +1 -1
  56. package/dist/daemon.d.ts +89 -4
  57. package/dist/daemon.js +661 -77
  58. package/dist/daemon.js.map +1 -1
  59. package/dist/darwin-memory.d.ts +6 -1
  60. package/dist/darwin-memory.js +17 -6
  61. package/dist/darwin-memory.js.map +1 -1
  62. package/dist/delivery-consumed-watch.d.ts +85 -0
  63. package/dist/delivery-consumed-watch.js +244 -0
  64. package/dist/delivery-consumed-watch.js.map +1 -0
  65. package/dist/delivery-outbox.d.ts +61 -0
  66. package/dist/delivery-outbox.js +120 -2
  67. package/dist/delivery-outbox.js.map +1 -1
  68. package/dist/delivery-reconciliation.d.ts +14 -5
  69. package/dist/delivery-reconciliation.js +27 -4
  70. package/dist/delivery-reconciliation.js.map +1 -1
  71. package/dist/delivery-reconciliation.test.js +35 -1
  72. package/dist/delivery-reconciliation.test.js.map +1 -1
  73. package/dist/event-loop-watch.d.ts +28 -0
  74. package/dist/event-loop-watch.js +75 -3
  75. package/dist/event-loop-watch.js.map +1 -1
  76. package/dist/fleet-context.d.ts +22 -2
  77. package/dist/fleet-level-config.d.ts +2 -2
  78. package/dist/fleet-level-config.js +6 -1
  79. package/dist/fleet-level-config.js.map +1 -1
  80. package/dist/fleet-manager.d.ts +293 -12
  81. package/dist/fleet-manager.js +2364 -449
  82. package/dist/fleet-manager.js.map +1 -1
  83. package/dist/host-memory.d.ts +4 -0
  84. package/dist/host-memory.js.map +1 -1
  85. package/dist/instance-config-impact.js +5 -0
  86. package/dist/instance-config-impact.js.map +1 -1
  87. package/dist/instance-lifecycle.d.ts +10 -5
  88. package/dist/instance-lifecycle.js +162 -53
  89. package/dist/instance-lifecycle.js.map +1 -1
  90. package/dist/locale.js +150 -16
  91. package/dist/locale.js.map +1 -1
  92. package/dist/login-controller.d.ts +2 -0
  93. package/dist/login-controller.js +17 -5
  94. package/dist/login-controller.js.map +1 -1
  95. package/dist/memory-pressure.d.ts +7 -8
  96. package/dist/memory-pressure.js +76 -15
  97. package/dist/memory-pressure.js.map +1 -1
  98. package/dist/monotonic-budget.d.ts +2 -0
  99. package/dist/monotonic-budget.js +28 -0
  100. package/dist/monotonic-budget.js.map +1 -0
  101. package/dist/needs-you-hub.d.ts +114 -0
  102. package/dist/needs-you-hub.js +370 -0
  103. package/dist/needs-you-hub.js.map +1 -0
  104. package/dist/needs-you-live.d.ts +116 -0
  105. package/dist/needs-you-live.js +228 -0
  106. package/dist/needs-you-live.js.map +1 -0
  107. package/dist/needs-you.d.ts +132 -0
  108. package/dist/needs-you.js +164 -0
  109. package/dist/needs-you.js.map +1 -0
  110. package/dist/node-version-guard.d.ts +30 -0
  111. package/dist/node-version-guard.js +50 -0
  112. package/dist/node-version-guard.js.map +1 -0
  113. package/dist/operator-control-paths.d.ts +4 -0
  114. package/dist/operator-control-paths.js +24 -0
  115. package/dist/operator-control-paths.js.map +1 -0
  116. package/dist/outbound-handlers.d.ts +2 -0
  117. package/dist/outbound-handlers.js +9 -2
  118. package/dist/outbound-handlers.js.map +1 -1
  119. package/dist/outbound-schemas.d.ts +5 -5
  120. package/dist/profile-control.js +4 -20
  121. package/dist/profile-control.js.map +1 -1
  122. package/dist/public-web-gateway.d.ts +18 -0
  123. package/dist/public-web-gateway.js +141 -0
  124. package/dist/public-web-gateway.js.map +1 -0
  125. package/dist/public-web-link.d.ts +53 -0
  126. package/dist/public-web-link.js +175 -0
  127. package/dist/public-web-link.js.map +1 -0
  128. package/dist/quickstart-api.d.ts +8 -1
  129. package/dist/quickstart-api.js +86 -48
  130. package/dist/quickstart-api.js.map +1 -1
  131. package/dist/quickstart.d.ts +1 -0
  132. package/dist/quickstart.js +6 -2
  133. package/dist/quickstart.js.map +1 -1
  134. package/dist/scheduler/db.d.ts +7 -1
  135. package/dist/scheduler/db.js +38 -0
  136. package/dist/scheduler/db.js.map +1 -1
  137. package/dist/scheduler/index.d.ts +1 -1
  138. package/dist/scheduler/retry-label.d.ts +11 -0
  139. package/dist/scheduler/retry-label.js +24 -0
  140. package/dist/scheduler/retry-label.js.map +1 -0
  141. package/dist/scheduler/scheduler.d.ts +55 -2
  142. package/dist/scheduler/scheduler.js +220 -8
  143. package/dist/scheduler/scheduler.js.map +1 -1
  144. package/dist/scheduler/types.d.ts +22 -0
  145. package/dist/scheduler/types.js.map +1 -1
  146. package/dist/secret-store.d.ts +5 -0
  147. package/dist/secret-store.js +20 -0
  148. package/dist/secret-store.js.map +1 -1
  149. package/dist/service-activation.d.ts +110 -0
  150. package/dist/service-activation.js +302 -0
  151. package/dist/service-activation.js.map +1 -0
  152. package/dist/service-installer.d.ts +7 -0
  153. package/dist/service-installer.js +7 -4
  154. package/dist/service-installer.js.map +1 -1
  155. package/dist/service-restart-selection.d.ts +6 -5
  156. package/dist/service-restart-selection.js +6 -5
  157. package/dist/service-restart-selection.js.map +1 -1
  158. package/dist/settings-api.d.ts +10 -2
  159. package/dist/settings-api.js +175 -72
  160. package/dist/settings-api.js.map +1 -1
  161. package/dist/settings-baseline.d.ts +20 -0
  162. package/dist/settings-baseline.js +104 -0
  163. package/dist/settings-baseline.js.map +1 -0
  164. package/dist/settings-change.d.ts +21 -0
  165. package/dist/settings-change.js +133 -0
  166. package/dist/settings-change.js.map +1 -0
  167. package/dist/settings-confirmation.d.ts +105 -0
  168. package/dist/settings-confirmation.js +232 -0
  169. package/dist/settings-confirmation.js.map +1 -0
  170. package/dist/settings-control.d.ts +41 -0
  171. package/dist/settings-control.js +294 -0
  172. package/dist/settings-control.js.map +1 -0
  173. package/dist/settings-effect.d.ts +24 -0
  174. package/dist/settings-effect.js +169 -0
  175. package/dist/settings-effect.js.map +1 -0
  176. package/dist/settings-http-confirmation.d.ts +29 -0
  177. package/dist/settings-http-confirmation.js +123 -0
  178. package/dist/settings-http-confirmation.js.map +1 -0
  179. package/dist/settings-instance-patch.d.ts +4 -0
  180. package/dist/settings-instance-patch.js +26 -0
  181. package/dist/settings-instance-patch.js.map +1 -0
  182. package/dist/settings-request-capability.d.ts +16 -0
  183. package/dist/settings-request-capability.js +32 -0
  184. package/dist/settings-request-capability.js.map +1 -0
  185. package/dist/settings-transaction.d.ts +65 -0
  186. package/dist/settings-transaction.js +223 -0
  187. package/dist/settings-transaction.js.map +1 -0
  188. package/dist/setup-auth.d.ts +10 -18
  189. package/dist/setup-auth.js +14 -38
  190. package/dist/setup-auth.js.map +1 -1
  191. package/dist/setup-form.d.ts +1 -1
  192. package/dist/setup-form.js +75 -18
  193. package/dist/setup-form.js.map +1 -1
  194. package/dist/setup-guide.d.ts +13 -0
  195. package/dist/setup-guide.js +25 -0
  196. package/dist/setup-guide.js.map +1 -0
  197. package/dist/setup-host.d.ts +16 -0
  198. package/dist/setup-host.js +197 -32
  199. package/dist/setup-host.js.map +1 -1
  200. package/dist/setup-wizard.js +3 -0
  201. package/dist/setup-wizard.js.map +1 -1
  202. package/dist/slash-authz.d.ts +17 -3
  203. package/dist/slash-authz.js +5 -0
  204. package/dist/slash-authz.js.map +1 -1
  205. package/dist/spawn-gate.js +3 -3
  206. package/dist/spawn-gate.js.map +1 -1
  207. package/dist/statusline-watcher.d.ts +5 -0
  208. package/dist/statusline-watcher.js +2 -0
  209. package/dist/statusline-watcher.js.map +1 -1
  210. package/dist/steer-capability.d.ts +6 -0
  211. package/dist/steer-capability.js +8 -0
  212. package/dist/steer-capability.js.map +1 -1
  213. package/dist/sync-work-attribution.d.ts +14 -0
  214. package/dist/sync-work-attribution.js +43 -8
  215. package/dist/sync-work-attribution.js.map +1 -1
  216. package/dist/tips.js +10 -5
  217. package/dist/tips.js.map +1 -1
  218. package/dist/tmux-control.d.ts +35 -5
  219. package/dist/tmux-control.js +291 -57
  220. package/dist/tmux-control.js.map +1 -1
  221. package/dist/tmux-manager.d.ts +20 -6
  222. package/dist/tmux-manager.js +90 -47
  223. package/dist/tmux-manager.js.map +1 -1
  224. package/dist/tmux-read.d.ts +59 -0
  225. package/dist/tmux-read.js +213 -0
  226. package/dist/tmux-read.js.map +1 -0
  227. package/dist/topic-commands.d.ts +21 -10
  228. package/dist/topic-commands.js +191 -58
  229. package/dist/topic-commands.js.map +1 -1
  230. package/dist/transcript-delta-reader.js +2 -1
  231. package/dist/transcript-delta-reader.js.map +1 -1
  232. package/dist/tunnel/cloudflared-install.d.ts +2 -0
  233. package/dist/tunnel/cloudflared-install.js +1 -1
  234. package/dist/tunnel/cloudflared-install.js.map +1 -1
  235. package/dist/tunnel/purpose-lane.d.ts +14 -0
  236. package/dist/tunnel/purpose-lane.js +43 -0
  237. package/dist/tunnel/purpose-lane.js.map +1 -0
  238. package/dist/turn-reply-guard.d.ts +2 -0
  239. package/dist/turn-reply-guard.js +10 -1
  240. package/dist/turn-reply-guard.js.map +1 -1
  241. package/dist/types.d.ts +33 -0
  242. package/dist/ui/app.html +18 -0
  243. package/dist/ui/chat-render.js +478 -0
  244. package/dist/ui/chat-store.js +289 -0
  245. package/dist/ui/chat-strings.js +69 -0
  246. package/dist/ui/chat-thread.js +209 -0
  247. package/dist/ui/chat-tour.js +116 -0
  248. package/dist/ui/fleet-org.js +142 -0
  249. package/dist/ui/panel-chat.js +418 -0
  250. package/dist/ui/panel-fleet.js +413 -0
  251. package/dist/ui/panel-needs.js +202 -0
  252. package/dist/ui/panel-settings.js +750 -0
  253. package/dist/ui/preview.js +266 -0
  254. package/dist/ui/settings-apply.js +239 -0
  255. package/dist/ui/settings-confirm.js +186 -0
  256. package/dist/ui/settings-dialogs.js +546 -0
  257. package/dist/ui/settings-model.js +277 -0
  258. package/dist/ui/settings-strings.js +652 -0
  259. package/dist/ui/settings-wizard.js +140 -0
  260. package/dist/ui/shared/agend-auth.js +93 -0
  261. package/dist/ui/shared/app-ctx.js +80 -0
  262. package/dist/ui/shared/app-html.js +9 -0
  263. package/dist/ui/shared/app-i18n.js +95 -0
  264. package/dist/ui/shared/app-nav.js +73 -0
  265. package/dist/ui/shared/app-needs.js +114 -0
  266. package/dist/ui/shared/app-route.js +73 -0
  267. package/dist/ui/shared/app-session.js +66 -0
  268. package/dist/ui/shared/app-shell.js +344 -0
  269. package/dist/ui/shared/app-store.js +51 -0
  270. package/dist/ui/shared/app-stream.js +201 -0
  271. package/dist/ui/shared/app.css +676 -0
  272. package/dist/ui/shared/app.js +88 -0
  273. package/dist/ui/shared/fonts/OFL.txt +92 -0
  274. package/dist/ui/shared/fonts/README.md +21 -0
  275. package/dist/ui/shared/fonts/inter.woff2 +0 -0
  276. package/dist/ui/shared/htm.module.js +1 -0
  277. package/dist/ui/shared/panel-view.js +655 -0
  278. package/dist/ui/shared/preact-hooks.module.js +2 -0
  279. package/dist/ui/shared/preact.module.js +2 -0
  280. package/dist/ui/shared/signin.js +130 -0
  281. package/dist/ui/shared/theme.js +29 -0
  282. package/dist/ui/shared/tokens.css +153 -0
  283. package/dist/ui/shared/ui-confirm.js +43 -0
  284. package/dist/ui/shared/ui-dialog.js +45 -0
  285. package/dist/ui/shared/ui-icons.js +61 -0
  286. package/dist/ui/shared/ui-menu.js +39 -0
  287. package/dist/ui/shared/ui-states.js +20 -0
  288. package/dist/ui/shared/ui-toast.js +18 -0
  289. package/dist/ui/shared/vendor/htm.LICENSE +202 -0
  290. package/dist/ui/shared/vendor/preact.LICENSE +21 -0
  291. package/dist/ui/shared/vendor/vendor.json +39 -0
  292. package/dist/ui/shared/view-strings.js +309 -0
  293. package/dist/ui/signin.html +51 -0
  294. package/dist/update-check.d.ts +6 -2
  295. package/dist/update-check.js +12 -3
  296. package/dist/update-check.js.map +1 -1
  297. package/dist/update-install.d.ts +71 -0
  298. package/dist/update-install.js +162 -0
  299. package/dist/update-install.js.map +1 -0
  300. package/dist/upgrade-notices.d.ts +17 -0
  301. package/dist/upgrade-notices.js +93 -0
  302. package/dist/upgrade-notices.js.map +1 -0
  303. package/dist/usage/statusline-usage.d.ts +2 -0
  304. package/dist/usage/statusline-usage.js +14 -10
  305. package/dist/usage/statusline-usage.js.map +1 -1
  306. package/dist/view-api.d.ts +6 -1
  307. package/dist/view-api.js +62 -51
  308. package/dist/view-api.js.map +1 -1
  309. package/dist/web-api.d.ts +71 -14
  310. package/dist/web-api.js +492 -77
  311. package/dist/web-api.js.map +1 -1
  312. package/dist/web-auth.d.ts +71 -27
  313. package/dist/web-auth.js +169 -69
  314. package/dist/web-auth.js.map +1 -1
  315. package/dist/web-body.d.ts +3 -0
  316. package/dist/web-body.js +55 -0
  317. package/dist/web-body.js.map +1 -0
  318. package/dist/web-channel-echo.d.ts +9 -0
  319. package/dist/web-channel-echo.js +55 -0
  320. package/dist/web-channel-echo.js.map +1 -0
  321. package/dist/web-chat-history.d.ts +125 -0
  322. package/dist/web-chat-history.js +184 -0
  323. package/dist/web-chat-history.js.map +1 -0
  324. package/dist/web-continuation.d.ts +7 -0
  325. package/dist/web-continuation.js +22 -0
  326. package/dist/web-continuation.js.map +1 -0
  327. package/dist/web-host-guard.d.ts +34 -0
  328. package/dist/web-host-guard.js +57 -1
  329. package/dist/web-host-guard.js.map +1 -1
  330. package/dist/web-login.d.ts +72 -0
  331. package/dist/web-login.js +132 -0
  332. package/dist/web-login.js.map +1 -0
  333. package/dist/web-org.d.ts +55 -0
  334. package/dist/web-org.js +67 -0
  335. package/dist/web-org.js.map +1 -0
  336. package/dist/web-preview.d.ts +77 -0
  337. package/dist/web-preview.js +240 -0
  338. package/dist/web-preview.js.map +1 -0
  339. package/dist/web-request-context.d.ts +10 -0
  340. package/dist/web-request-context.js +13 -0
  341. package/dist/web-request-context.js.map +1 -0
  342. package/dist/web-session.d.ts +167 -0
  343. package/dist/web-session.js +389 -0
  344. package/dist/web-session.js.map +1 -0
  345. package/dist/web-shell-routes.d.ts +59 -0
  346. package/dist/web-shell-routes.js +96 -0
  347. package/dist/web-shell-routes.js.map +1 -0
  348. package/dist/web-upload.d.ts +183 -0
  349. package/dist/web-upload.js +468 -0
  350. package/dist/web-upload.js.map +1 -0
  351. package/dist/website-tips-renderer.d.ts +2 -2
  352. package/dist/website-tips-renderer.js +3 -3
  353. package/dist/website-tips-renderer.js.map +1 -1
  354. package/package.json +8 -5
  355. package/scripts/preinstall-guard.cjs +36 -0
  356. package/dist/ui/dashboard.html +0 -774
  357. package/dist/ui/settings.html +0 -2165
  358. package/dist/ui/view.html +0 -1139
@@ -4,6 +4,10 @@ export interface HostMemory {
4
4
  availableKind: "available" | "free" | "unknown";
5
5
  swapTotalBytes: number | null;
6
6
  swapFreeBytes: number | null;
7
+ /** Darwin kernel alarm, independent of the diagnostic RAM/swap estimates. */
8
+ darwinPressureLevel?: 1 | 2 | 4 | null;
9
+ /** Bounded diagnostic output; null when unavailable or not requested. */
10
+ darwinPressureRaw?: string | null;
7
11
  }
8
12
  interface HostMemoryDeps {
9
13
  platform: NodeJS.Platform;
@@ -1 +1 @@
1
- {"version":3,"file":"host-memory.js","sourceRoot":"","sources":["../src/host-memory.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,iBAAiB,EAAE,MAAM,oBAAoB,CAAC;AACvD,OAAO,EAAE,YAAY,EAAE,MAAM,SAAS,CAAC;AACvC,OAAO,EAAE,OAAO,EAAE,QAAQ,EAAE,QAAQ,EAAE,MAAM,SAAS,CAAC;AAiBtD,0FAA0F;AAC1F,MAAM,UAAU,cAAc,CAAC,YAAqC,EAAE;IACpE,MAAM,IAAI,GAAG,EAAE,QAAQ,EAAE,QAAQ,EAAE,EAAE,OAAO,EAAE,GAAG,EAAE,CAAC,YAAY,CAAC,eAAe,EAAE,MAAM,CAAC,EAAE,QAAQ,EAAE,OAAO,EAAE,GAAG,SAAS,EAAE,CAAC;IAC7H,4EAA4E;IAC5E,0EAA0E;IAC1E,IAAI,IAAI,CAAC,QAAQ,KAAK,QAAQ,EAAE,CAAC;QAC/B,OAAO,EAAE,UAAU,EAAE,IAAI,CAAC,QAAQ,EAAE,EAAE,cAAc,EAAE,IAAI,EAAE,aAAa,EAAE,SAAS,EAAE,cAAc,EAAE,IAAI,EAAE,aAAa,EAAE,IAAI,EAAE,CAAC;IACpI,CAAC;IACD,IAAI,IAAI,CAAC,QAAQ,KAAK,OAAO,EAAE,CAAC;QAC9B,IAAI,CAAC;YACH,MAAM,MAAM,GAAG,IAAI,GAAG,EAAkB,CAAC;YACzC,KAAK,MAAM,KAAK,IAAI,IAAI,CAAC,OAAO,EAAE,CAAC,QAAQ,CAAC,4BAA4B,CAAC,EAAE,CAAC;gBAC1E,MAAM,KAAK,GAAG,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,GAAG,IAAI,CAAC;gBACtC,IAAI,MAAM,CAAC,aAAa,CAAC,KAAK,CAAC;oBAAE,MAAM,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE,KAAK,CAAC,CAAC;YAC/D,CAAC;YACD,MAAM,KAAK,GAAG,MAAM,CAAC,GAAG,CAAC,UAAU,CAAC,CAAC;YACrC,MAAM,SAAS,GAAG,MAAM,CAAC,GAAG,CAAC,cAAc,CAAC,IAAI,MAAM,CAAC,GAAG,CAAC,SAAS,CAAC,CAAC;YACtE,IAAI,KAAK,IAAI,SAAS,KAAK,SAAS,IAAI,SAAS,IAAI,KAAK,EAAE,CAAC;gBAC3D,MAAM,SAAS,GAAG,MAAM,CAAC,GAAG,CAAC,WAAW,CAAC,CAAC;gBAC1C,MAAM,QAAQ,GAAG,MAAM,CAAC,GAAG,CAAC,UAAU,CAAC,CAAC;gBACxC,MAAM,OAAO,GAAG,SAAS,KAAK,SAAS,IAAI,QAAQ,KAAK,SAAS,IAAI,QAAQ,IAAI,SAAS,CAAC;gBAC3F,OAAO;oBACL,UAAU,EAAE,KAAK,EAAE,cAAc,EAAE,SAAS;oBAC5C,aAAa,EAAE,MAAM,CAAC,GAAG,CAAC,cAAc,CAAC,CAAC,CAAC,CAAC,WAAW,CAAC,CAAC,CAAC,MAAM;oBAChE,cAAc,EAAE,OAAO,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,IAAI;oBAC1C,aAAa,EAAE,OAAO,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,IAAI;iBACzC,CAAC;YACJ,CAAC;QACH,CAAC;QAAC,MAAM,CAAC,CAAC,oEAAoE,CAAC,CAAC;IAClF,CAAC;IACD,OAAO,EAAE,UAAU,EAAE,IAAI,CAAC,QAAQ,EAAE,EAAE,cAAc,EAAE,IAAI,CAAC,OAAO,EAAE,EAAE,aAAa,EAAE,MAAM,EAAE,cAAc,EAAE,IAAI,EAAE,aAAa,EAAE,IAAI,EAAE,CAAC;AAC3I,CAAC;AAED,oFAAoF;AACpF,IAAI,qBAAqB,GAA6B,IAAI,CAAC;AAC3D,MAAM,UAAU,mBAAmB;IACjC,IAAI,QAAQ,EAAE,KAAK,QAAQ;QAAE,OAAO,OAAO,CAAC,OAAO,CAAC,cAAc,EAAE,CAAC,CAAC;IACtE,qBAAqB,KAAK,IAAI,iBAAiB,EAAE,CAAC;IAClD,OAAO,qBAAqB,CAAC,IAAI,EAAE,CAAC;AACtC,CAAC"}
1
+ {"version":3,"file":"host-memory.js","sourceRoot":"","sources":["../src/host-memory.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,iBAAiB,EAAE,MAAM,oBAAoB,CAAC;AACvD,OAAO,EAAE,YAAY,EAAE,MAAM,SAAS,CAAC;AACvC,OAAO,EAAE,OAAO,EAAE,QAAQ,EAAE,QAAQ,EAAE,MAAM,SAAS,CAAC;AAqBtD,0FAA0F;AAC1F,MAAM,UAAU,cAAc,CAAC,YAAqC,EAAE;IACpE,MAAM,IAAI,GAAG,EAAE,QAAQ,EAAE,QAAQ,EAAE,EAAE,OAAO,EAAE,GAAG,EAAE,CAAC,YAAY,CAAC,eAAe,EAAE,MAAM,CAAC,EAAE,QAAQ,EAAE,OAAO,EAAE,GAAG,SAAS,EAAE,CAAC;IAC7H,4EAA4E;IAC5E,0EAA0E;IAC1E,IAAI,IAAI,CAAC,QAAQ,KAAK,QAAQ,EAAE,CAAC;QAC/B,OAAO,EAAE,UAAU,EAAE,IAAI,CAAC,QAAQ,EAAE,EAAE,cAAc,EAAE,IAAI,EAAE,aAAa,EAAE,SAAS,EAAE,cAAc,EAAE,IAAI,EAAE,aAAa,EAAE,IAAI,EAAE,CAAC;IACpI,CAAC;IACD,IAAI,IAAI,CAAC,QAAQ,KAAK,OAAO,EAAE,CAAC;QAC9B,IAAI,CAAC;YACH,MAAM,MAAM,GAAG,IAAI,GAAG,EAAkB,CAAC;YACzC,KAAK,MAAM,KAAK,IAAI,IAAI,CAAC,OAAO,EAAE,CAAC,QAAQ,CAAC,4BAA4B,CAAC,EAAE,CAAC;gBAC1E,MAAM,KAAK,GAAG,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,GAAG,IAAI,CAAC;gBACtC,IAAI,MAAM,CAAC,aAAa,CAAC,KAAK,CAAC;oBAAE,MAAM,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE,KAAK,CAAC,CAAC;YAC/D,CAAC;YACD,MAAM,KAAK,GAAG,MAAM,CAAC,GAAG,CAAC,UAAU,CAAC,CAAC;YACrC,MAAM,SAAS,GAAG,MAAM,CAAC,GAAG,CAAC,cAAc,CAAC,IAAI,MAAM,CAAC,GAAG,CAAC,SAAS,CAAC,CAAC;YACtE,IAAI,KAAK,IAAI,SAAS,KAAK,SAAS,IAAI,SAAS,IAAI,KAAK,EAAE,CAAC;gBAC3D,MAAM,SAAS,GAAG,MAAM,CAAC,GAAG,CAAC,WAAW,CAAC,CAAC;gBAC1C,MAAM,QAAQ,GAAG,MAAM,CAAC,GAAG,CAAC,UAAU,CAAC,CAAC;gBACxC,MAAM,OAAO,GAAG,SAAS,KAAK,SAAS,IAAI,QAAQ,KAAK,SAAS,IAAI,QAAQ,IAAI,SAAS,CAAC;gBAC3F,OAAO;oBACL,UAAU,EAAE,KAAK,EAAE,cAAc,EAAE,SAAS;oBAC5C,aAAa,EAAE,MAAM,CAAC,GAAG,CAAC,cAAc,CAAC,CAAC,CAAC,CAAC,WAAW,CAAC,CAAC,CAAC,MAAM;oBAChE,cAAc,EAAE,OAAO,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,IAAI;oBAC1C,aAAa,EAAE,OAAO,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,IAAI;iBACzC,CAAC;YACJ,CAAC;QACH,CAAC;QAAC,MAAM,CAAC,CAAC,oEAAoE,CAAC,CAAC;IAClF,CAAC;IACD,OAAO,EAAE,UAAU,EAAE,IAAI,CAAC,QAAQ,EAAE,EAAE,cAAc,EAAE,IAAI,CAAC,OAAO,EAAE,EAAE,aAAa,EAAE,MAAM,EAAE,cAAc,EAAE,IAAI,EAAE,aAAa,EAAE,IAAI,EAAE,CAAC;AAC3I,CAAC;AAED,oFAAoF;AACpF,IAAI,qBAAqB,GAA6B,IAAI,CAAC;AAC3D,MAAM,UAAU,mBAAmB;IACjC,IAAI,QAAQ,EAAE,KAAK,QAAQ;QAAE,OAAO,OAAO,CAAC,OAAO,CAAC,cAAc,EAAE,CAAC,CAAC;IACtE,qBAAqB,KAAK,IAAI,iBAAiB,EAAE,CAAC;IAClD,OAAO,qBAAqB,CAAC,IAAI,EAAE,CAAC;AACtC,CAAC"}
@@ -71,12 +71,17 @@ const INSTANCE_FIELDS = [
71
71
  const CLASSIC_FIELDS = [
72
72
  "backend", "model", "auto_pause_after", "tool_progress",
73
73
  "reply_completion_guard", "collab", "context_lines", "pre_task_command",
74
+ "web_echo",
74
75
  ];
75
76
  /**
76
77
  * Fleet-level fields, which no per-key rule can derive: they belong to the
77
78
  * fleet process or the channel binding rather than to an instance's config.
78
79
  */
79
80
  const FLEET_FIELD_IMPACTS = {
81
+ "web.echo_to_channel": "now",
82
+ "web.public_link.allow_public": "now",
83
+ "web.public_link.ttl_minutes": "now",
84
+ "web.public_link.protocol": "now",
80
85
  "defaults.locale": "now",
81
86
  "fleet.channels": "fleet",
82
87
  "fleet.channel.access.mode": "fleet",
@@ -1 +1 @@
1
- {"version":3,"file":"instance-config-impact.js","sourceRoot":"","sources":["../src/instance-config-impact.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"instance-config-impact.js","sourceRoot":"","sources":["../src/instance-config-impact.ts"],"names":[],"mappings":"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"}
@@ -1,3 +1,4 @@
1
+ import { SettingsExecution } from "./settings-transaction.js";
1
2
  import type { InstanceConfig, FleetConfig } from "./types.js";
2
3
  import { RoutingEngine } from "./routing-engine.js";
3
4
  import type { Logger } from "./logger.js";
@@ -45,6 +46,7 @@ export interface LifecycleContext {
45
46
  readonly fleetConfig: FleetConfig | null;
46
47
  readonly logger: Logger;
47
48
  readonly dataDir: string;
49
+ getSettingsConfigPath?(): string;
48
50
  readonly routing: RoutingEngine;
49
51
  readonly instanceIpcClients: Map<string, IpcClient>;
50
52
  readonly ipcStoppingInstances: Set<string>;
@@ -97,6 +99,8 @@ export interface LifecycleContext {
97
99
  notifyInstanceTopic(name: string, text: string): boolean | void;
98
100
  /** Notify the blocked instance and offer an interactive assist action in General. */
99
101
  notifyInteractivePrompt(name: string, kind: string): Promise<void>;
102
+ /** #1386: an instance's interaction observation, pause or wake changed ("Needs you" recomputes at once, not at its tick). */
103
+ onAttentionChanged?(name: string): void;
100
104
  /**
101
105
  * Offer a one-tap re-login beside an auth alert. Optional: contexts without
102
106
  * it (tests, lightweight fleets) still get the alert's written remedy.
@@ -159,6 +163,7 @@ export declare class SupersededStartError extends Error {
159
163
  * cross-instance idle gate (60s) plus a 60s grace.
160
164
  */
161
165
  export declare const PRECLAIM_LEASE_MS = 120000;
166
+ type Daemon = InstanceType<typeof import("./daemon.js").Daemon>;
162
167
  /**
163
168
  * Working directories of the fleet's other instances on `backendName` (#984):
164
169
  * Codex consults them only to decide whether `resume --last` could take a
@@ -433,7 +438,7 @@ export declare class InstanceLifecycle {
433
438
  * never an auth-deferred or operator pause.
434
439
  */
435
440
  hasWorkLease(name: string, now?: number): boolean;
436
- start(name: string, config: InstanceConfig, topicMode: boolean, runtimeIdentity?: FleetInstructionsParams["runtimeIdentity"], transition?: TransitionHandle): Promise<void>;
441
+ start(name: string, config: InstanceConfig, topicMode: boolean, runtimeIdentity?: FleetInstructionsParams["runtimeIdentity"], transition?: TransitionHandle, execution?: SettingsExecution, published?: (daemon: Daemon) => void): Promise<void>;
437
442
  private startInTransition;
438
443
  isPaused(name: string): boolean;
439
444
  getLastPausedAt(name: string): number | null;
@@ -452,16 +457,16 @@ export declare class InstanceLifecycle {
452
457
  * surface.
453
458
  */
454
459
  static startOrDispose(daemon: {
455
- start(): Promise<void>;
460
+ start(admission?: () => void): Promise<void>;
456
461
  abortStartup(): Promise<void>;
457
- }, name: string, logger: Logger): Promise<void>;
462
+ }, name: string, logger: Logger, admission?: () => void): Promise<void>;
458
463
  /** Stop the registered daemon only if it is still `daemon` (a concurrent restart may have replaced it). */
459
464
  stopIfCurrent(name: string, daemon: unknown): Promise<boolean>;
460
465
  stop(name: string, transition?: TransitionHandle): Promise<void>;
461
466
  private stopInTransition;
462
- remove(name: string, authorization: ExplicitInstanceRemoval): Promise<void>;
467
+ remove(name: string, authorization: ExplicitInstanceRemoval, execution?: SettingsExecution, transition?: TransitionHandle): Promise<void>;
463
468
  /** Handle create_instance tool call from a daemon. */
464
- handleCreate(args: LifecycleCreateArgs, respond: (result: unknown, error?: string) => void, adapterId?: string): Promise<void>;
469
+ handleCreate(args: LifecycleCreateArgs, respond: (result: unknown, error?: string) => void, adapterId?: string, execution?: SettingsExecution): Promise<void>;
465
470
  /** Handle delete_instance tool call from a daemon. */
466
471
  handleDelete(args: LifecycleDeleteArgs, respond: (result: unknown, error?: string) => void): Promise<void>;
467
472
  has(name: string): boolean;
@@ -1,6 +1,7 @@
1
+ import { settingsUndo, undoSettingsPaths } from "./settings-transaction.js";
1
2
  import { measureSyncWork } from "./sync-work-attribution.js";
2
3
  import { REMOVED_BACKENDS, isRemovedBackend, removedBackendMessage } from "./backend/removed.js";
3
- import { existsSync, readFileSync, mkdirSync, realpathSync, writeFileSync } from "node:fs";
4
+ import { existsSync, readFileSync, mkdirSync, realpathSync, writeFileSync, statSync } from "node:fs";
4
5
  import { ensureInstanceDir } from "./private-dir.js";
5
6
  import { execFileSync } from "node:child_process";
6
7
  import { join, basename, dirname, resolve, sep as pathSep } from "node:path";
@@ -822,6 +823,7 @@ export class InstanceLifecycle {
822
823
  this.notifyIncident(name, "dialog_answer_ignored", text);
823
824
  this.ctx.notifyFleetError?.(t("fleet.dialog_answer_ignored", name, data.description, String(data.attempts)));
824
825
  }, this.ctx.logger, `daemon.dialog_answer_ignored[${name}]`));
826
+ daemon.on("instance_interaction", () => this.ctx.onAttentionChanged?.(name));
825
827
  daemon.on("interactive_prompt", safeHandler(async (data) => {
826
828
  this.ctx.eventLog?.insert(name, "interactive_prompt", { kind: data.kind });
827
829
  this.ctx.logger.warn({ name, kind: data.kind, prompt: data.prompt }, "Instance is waiting for interactive terminal input");
@@ -1159,11 +1161,14 @@ export class InstanceLifecycle {
1159
1161
  return false;
1160
1162
  return outbox.countForTarget(name, ["queued", "retry_wait"]) > 0;
1161
1163
  }
1162
- async start(name, config, topicMode, runtimeIdentity, transition) {
1163
- return this.runTransition(name, () => this.startInTransition(name, config, topicMode, runtimeIdentity), transition);
1164
+ async start(name, config, topicMode, runtimeIdentity, transition, execution, published) {
1165
+ return this.runTransition(name, () => this.startInTransition(name, config, topicMode, runtimeIdentity, execution, published), transition);
1164
1166
  }
1165
- async startInTransition(name, config, topicMode, runtimeIdentity) {
1167
+ async startInTransition(name, config, topicMode, runtimeIdentity, execution, published) {
1166
1168
  const epoch = this.epochOf(name);
1169
+ const check = () => { execution?.assert(); if (this.epochOf(name) !== epoch)
1170
+ throw new SupersededStartError(name); };
1171
+ check();
1167
1172
  const seedNow = this.activitySeedNow.delete(name);
1168
1173
  if (this.daemons.has(name)) {
1169
1174
  this.ctx.logger.info({ name }, "Instance already running, skipping");
@@ -1179,6 +1184,7 @@ export class InstanceLifecycle {
1179
1184
  // that fails before reaching the daemon must leave that intent intact.
1180
1185
  const { Daemon } = await import("./daemon.js");
1181
1186
  const { createBackend } = await import("./backend/factory.js");
1187
+ check();
1182
1188
  const backendName = config.backend ?? this.ctx.fleetConfig?.defaults?.backend ?? "claude-code";
1183
1189
  // A removed backend (#1280): this instance refuses to start, says why and what to use instead, and the rest of
1184
1190
  // the fleet is unaffected. Never a fallback to another backend.
@@ -1258,7 +1264,7 @@ export class InstanceLifecycle {
1258
1264
  throw new Error(message);
1259
1265
  }
1260
1266
  }
1261
- if (this.epochOf(name) !== epoch) {
1267
+ if (this.epochOf(name) !== epoch || execution && !execution.current()) {
1262
1268
  // A stop/restart arrived while this start was reconciling: do not spawn.
1263
1269
  await daemon.abortStartup().catch(() => { });
1264
1270
  throw new SupersededStartError(name);
@@ -1267,16 +1273,17 @@ export class InstanceLifecycle {
1267
1273
  // before the handlers below exist and before this daemon is registered;
1268
1274
  // hold it and deliver it once both are true.
1269
1275
  daemon.holdStartupIncidents?.();
1270
- await InstanceLifecycle.startOrDispose(daemon, name, this.ctx.logger);
1276
+ await InstanceLifecycle.startOrDispose(daemon, name, this.ctx.logger, execution ? check : undefined);
1271
1277
  // Publication fence (Phase 2a): the spawn cannot be cancelled, so a stop or
1272
1278
  // restart requested meanwhile has been waiting behind this transition. A
1273
1279
  // superseded start must not register, signal ready, or keep its window.
1274
- if (this.epochOf(name) !== epoch) {
1280
+ if (this.epochOf(name) !== epoch || execution && !execution.current()) {
1275
1281
  await daemon.abortStartup().catch(err => this.ctx.logger.warn({ err, name }, "Failed to dispose a superseded start"));
1276
1282
  throw new SupersededStartError(name);
1277
1283
  }
1278
1284
  this.capacityBackoffBaselines.delete(name);
1279
1285
  this.daemons.set(name, daemon);
1286
+ published?.(daemon); // Exact publication, synchronously after the ownership fence.
1280
1287
  if (seedNow)
1281
1288
  this.noteWokeForWork(name);
1282
1289
  this.ctx.onDaemonReady?.(name, daemon.bootId);
@@ -1287,8 +1294,10 @@ export class InstanceLifecycle {
1287
1294
  this.ctx.eventLog?.insert(name, "instance_paused", { reason: "idle", paused_at: data.pausedAt });
1288
1295
  this.ctx.logger.info({ name, pausedAt: data.pausedAt }, "Instance auto-paused after idle timeout");
1289
1296
  this.ctx.setTopicIcon(name, "remove");
1297
+ this.ctx.onAttentionChanged?.(name);
1290
1298
  });
1291
1299
  daemon.on("auto_woke", () => {
1300
+ this.ctx.onAttentionChanged?.(name);
1292
1301
  this.ctx.eventLog?.insert(name, "instance_resumed", { reason: "message" });
1293
1302
  this.ctx.logger.info({ name }, "Instance auto-woke for delivery");
1294
1303
  this.ctx.setTopicIcon(name, "green");
@@ -1349,6 +1358,7 @@ export class InstanceLifecycle {
1349
1358
  // its fleet-level statusline watcher in the frozen state.
1350
1359
  if (!daemon.isPaused)
1351
1360
  this.ctx.startStatuslineWatcher(name);
1361
+ this.ctx.onAttentionChanged?.(name);
1352
1362
  }
1353
1363
  }
1354
1364
  /** When `name` was last woken or (re)started for work, if recorded. */
@@ -1356,7 +1366,7 @@ export class InstanceLifecycle {
1356
1366
  return this.wokeAt.get(name);
1357
1367
  }
1358
1368
  async wake(name, timeoutMs = 30_000, transition, opts = {}) {
1359
- const woke = await this.wakeInner(name, timeoutMs, transition);
1369
+ const woke = await this.wakeInner(name, timeoutMs, transition).finally(() => this.ctx.onAttentionChanged?.(name));
1360
1370
  // Only a successful operator/user wake lifts the coordinator's park.
1361
1371
  if (opts.source !== "coordinator")
1362
1372
  this.ctx.onExternalWake?.(name);
@@ -1418,9 +1428,12 @@ export class InstanceLifecycle {
1418
1428
  * rethrowing. The abort is best-effort — the start error is the one to
1419
1429
  * surface.
1420
1430
  */
1421
- static async startOrDispose(daemon, name, logger) {
1431
+ static async startOrDispose(daemon, name, logger, admission) {
1422
1432
  try {
1423
- await daemon.start();
1433
+ if (admission)
1434
+ await daemon.start(admission);
1435
+ else
1436
+ await daemon.start();
1424
1437
  }
1425
1438
  catch (err) {
1426
1439
  await daemon.abortStartup().catch(abortErr => logger.warn({ err: abortErr, name }, "Failed to dispose a daemon whose start() rejected"));
@@ -1551,12 +1564,15 @@ export class InstanceLifecycle {
1551
1564
  this.ctx.sessionRegistry.delete(session);
1552
1565
  }
1553
1566
  }
1554
- async remove(name, authorization) {
1567
+ async remove(name, authorization, execution, transition) {
1555
1568
  // Automatic topology reconciliation must never reach the destructive path.
1556
1569
  assertExplicitInstanceRemoval(authorization);
1557
1570
  const config = this.ctx.fleetConfig?.instances[name];
1558
1571
  if (!config)
1559
1572
  return;
1573
+ const check = () => { execution?.assert(); if (this.ctx.fleetConfig?.instances[name] !== config)
1574
+ throw new Error("instance removal superseded"); };
1575
+ check();
1560
1576
  // Never remove the General instance
1561
1577
  if (config.general_topic) {
1562
1578
  this.ctx.logger.warn({ name }, "Refusing to remove General instance");
@@ -1566,16 +1582,21 @@ export class InstanceLifecycle {
1566
1582
  // Access scheduler through fleetConfig — scheduler is managed by FleetManager
1567
1583
  // We just clean up instance-related data here
1568
1584
  // Stop daemon and clean up tmux window (handles both in-memory and orphaned cases)
1569
- await this.stop(name);
1585
+ await this.stop(name, transition);
1586
+ check();
1570
1587
  // Clean up backend config files (MCP config, instructions, etc.)
1571
1588
  // This is needed even when daemon is not in memory — stop() only calls
1572
1589
  // backend.cleanup() when daemon object exists. Without this, stale MCP
1573
1590
  // entries remain in the working directory and crash new instances.
1574
- if (config.working_directory && config.backend) {
1591
+ // By the effective backend: an instance on the fleet default backend (no per-instance `backend`) has the same
1592
+ // files to clean up (#906 review: an inherited kiro left its agent, steering and shared entry behind).
1593
+ const effectiveBackend = config.backend ?? this.ctx.fleetConfig?.defaults?.backend;
1594
+ if (config.working_directory && effectiveBackend) {
1575
1595
  try {
1576
1596
  const { createBackend } = await import("./backend/factory.js");
1597
+ check();
1577
1598
  const instanceDir = this.ctx.getInstanceDir(name);
1578
- const backend = createBackend(config.backend, instanceDir);
1599
+ const backend = createBackend(effectiveBackend, instanceDir);
1579
1600
  if (backend?.cleanup) {
1580
1601
  const backendConfig = {
1581
1602
  workingDirectory: config.working_directory,
@@ -1593,6 +1614,15 @@ export class InstanceLifecycle {
1593
1614
  this.ctx.logger.debug({ err, name }, "Backend cleanup failed (best effort)");
1594
1615
  }
1595
1616
  }
1617
+ // State a backend keeps outside the instance directory (kiro: which conversations it owns, #906) — by the
1618
+ // effective backend, so an instance on the fleet default is forgotten too.
1619
+ try {
1620
+ const { createBackend } = await import("./backend/factory.js");
1621
+ check();
1622
+ const effective = config.backend ?? this.ctx.fleetConfig?.defaults?.backend ?? "claude-code";
1623
+ createBackend(effective, this.ctx.getInstanceDir(name))?.forget?.(name);
1624
+ }
1625
+ catch { /* best effort */ }
1596
1626
  // Clean up git worktree if applicable
1597
1627
  if (config.worktree_source && config.working_directory) {
1598
1628
  if (!existsSync(config.working_directory)) {
@@ -1602,20 +1632,24 @@ export class InstanceLifecycle {
1602
1632
  try {
1603
1633
  const { execFile: execFileCb } = await import("node:child_process");
1604
1634
  const { promisify } = await import("node:util");
1635
+ check();
1605
1636
  const execFileAsync = promisify(execFileCb);
1606
1637
  await execFileAsync("git", ["worktree", "remove", "--force", config.working_directory], {
1607
1638
  cwd: config.worktree_source,
1608
1639
  });
1640
+ check();
1609
1641
  this.ctx.logger.info({ worktree: config.working_directory }, "Removed git worktree");
1610
1642
  }
1611
1643
  catch {
1612
- // worktree remove failed — directory exists but isn't a valid worktree.
1644
+ check(); // worktree remove failed — directory exists but isn't a valid worktree.
1613
1645
  // Only rm if directory is in the expected location (sibling of source repo or under ~/.agend/).
1614
1646
  const expectedParent = dirname(config.working_directory);
1615
1647
  const sourceParent = dirname(config.worktree_source);
1616
1648
  if (expectedParent === sourceParent || config.working_directory.startsWith(getAgendHome())) {
1617
1649
  const { rm } = await import("node:fs/promises");
1650
+ check();
1618
1651
  await rm(config.working_directory, { recursive: true, force: true });
1652
+ check();
1619
1653
  this.ctx.logger.info({ worktree: config.working_directory }, "Removed orphaned worktree directory");
1620
1654
  }
1621
1655
  else {
@@ -1627,16 +1661,22 @@ export class InstanceLifecycle {
1627
1661
  try {
1628
1662
  const { execFile: execFileCb } = await import("node:child_process");
1629
1663
  const { promisify } = await import("node:util");
1664
+ check();
1630
1665
  const execFileAsync = promisify(execFileCb);
1631
1666
  await execFileAsync("git", ["worktree", "prune"], { cwd: config.worktree_source });
1632
1667
  }
1633
- catch { /* best effort */ }
1668
+ catch {
1669
+ check(); /* best effort */
1670
+ }
1634
1671
  }
1672
+ check();
1635
1673
  // Clean up IPC
1636
1674
  const ipc = this.ctx.instanceIpcClients.get(name);
1637
1675
  if (ipc) {
1638
1676
  await ipc.close();
1639
- this.ctx.instanceIpcClients.delete(name);
1677
+ check();
1678
+ if (this.ctx.instanceIpcClients.get(name) === ipc)
1679
+ this.ctx.instanceIpcClients.delete(name);
1640
1680
  }
1641
1681
  // Remove from routing table (this instance only: #1085, another Telegram
1642
1682
  // world may own the same topic number)
@@ -1644,13 +1684,20 @@ export class InstanceLifecycle {
1644
1684
  this.ctx.routing.unregister(config.topic_id, name);
1645
1685
  }
1646
1686
  // Remove from fleet config and save
1647
- delete this.ctx.fleetConfig.instances[name];
1648
- this.ctx.saveFleetConfig();
1687
+ const persist = () => { delete this.ctx.fleetConfig.instances[name]; this.ctx.saveFleetConfig(); };
1688
+ if (execution)
1689
+ execution.mutate(persist);
1690
+ else {
1691
+ check();
1692
+ persist();
1693
+ }
1649
1694
  clearPausedMarker(this.ctx.getInstanceDir(name));
1650
1695
  this.ctx.logger.info({ name }, "Instance removed");
1651
1696
  }
1652
1697
  /** Handle create_instance tool call from a daemon. */
1653
- async handleCreate(args, respond, adapterId) {
1698
+ async handleCreate(args, respond, adapterId, execution) {
1699
+ const check = () => execution?.assert();
1700
+ check();
1654
1701
  const rawDirectory = args.directory;
1655
1702
  const directory = rawDirectory ? rawDirectory.replace(/^~/, process.env.HOME || "~") : undefined;
1656
1703
  const topicName = args.topic_name || (directory ? basename(directory) : undefined);
@@ -1666,6 +1713,7 @@ export class InstanceLifecycle {
1666
1713
  if (directory) {
1667
1714
  try {
1668
1715
  await access(directory);
1716
+ check();
1669
1717
  }
1670
1718
  catch {
1671
1719
  respond(null, `Directory does not exist: ${directory}`);
@@ -1723,6 +1771,36 @@ export class InstanceLifecycle {
1723
1771
  // If branch specified, create git worktree (requires directory)
1724
1772
  let workDir = directory ?? "";
1725
1773
  let worktreePath;
1774
+ let acquiredWorktree = false;
1775
+ let acquiredDirectory;
1776
+ const directoryReferenced = () => Object.values(this.ctx.fleetConfig?.instances ?? {}).some(config => config.working_directory === workDir);
1777
+ const cleanupDirectory = async () => {
1778
+ if (!acquiredDirectory || !workDir || directoryReferenced())
1779
+ return;
1780
+ const ownsPath = () => {
1781
+ if (directoryReferenced())
1782
+ return false;
1783
+ try {
1784
+ const current = statSync(workDir);
1785
+ return current.dev === acquiredDirectory.dev && current.ino === acquiredDirectory.ino;
1786
+ }
1787
+ catch {
1788
+ return false;
1789
+ }
1790
+ };
1791
+ if (acquiredWorktree) {
1792
+ const { execFile } = await import("node:child_process");
1793
+ const { promisify } = await import("node:util");
1794
+ if (!ownsPath())
1795
+ return;
1796
+ await promisify(execFile)("git", ["worktree", "remove", "--force", workDir], { cwd: directory });
1797
+ }
1798
+ else {
1799
+ const { rm } = await import("node:fs/promises");
1800
+ if (ownsPath())
1801
+ await rm(workDir, { recursive: true, force: true });
1802
+ }
1803
+ };
1726
1804
  if (branch && !directory) {
1727
1805
  respond(null, "directory is required when branch is specified");
1728
1806
  return;
@@ -1731,7 +1809,14 @@ export class InstanceLifecycle {
1731
1809
  try {
1732
1810
  const { execFile: execFileCb } = await import("node:child_process");
1733
1811
  const { promisify } = await import("node:util");
1734
- const execFileAsync = promisify(execFileCb);
1812
+ const nativeExec = promisify(execFileCb);
1813
+ const execFileAsync = async (file, args, options, acquired) => {
1814
+ check();
1815
+ const result = await nativeExec(file, args, options);
1816
+ acquired?.();
1817
+ check();
1818
+ return result;
1819
+ };
1735
1820
  await execFileAsync("git", ["rev-parse", "--git-dir"], { cwd: directory });
1736
1821
  const customPath = args.worktree_path;
1737
1822
  if (customPath) {
@@ -1767,23 +1852,25 @@ export class InstanceLifecycle {
1767
1852
  respond(null, EMBEDDED_CREDENTIAL_REMOTE_REPAIR_FAILED);
1768
1853
  return;
1769
1854
  }
1855
+ const acquired = () => { acquiredWorktree = true; workDir = worktreePath; acquiredDirectory = statSync(workDir); };
1770
1856
  if (detach) {
1771
- await execFileAsync("git", ["worktree", "add", "--detach", worktreePath, branch], { cwd: directory });
1857
+ await execFileAsync("git", ["worktree", "add", "--detach", worktreePath, branch], { cwd: directory }, acquired);
1772
1858
  }
1773
1859
  else if (branchExists) {
1774
- await execFileAsync("git", ["worktree", "add", worktreePath, branch], { cwd: directory });
1860
+ await execFileAsync("git", ["worktree", "add", worktreePath, branch], { cwd: directory }, acquired);
1775
1861
  }
1776
1862
  else {
1777
1863
  const startPoint = args.start_point;
1778
1864
  const worktreeArgs = ["worktree", "add", worktreePath, "-b", branch];
1779
1865
  if (startPoint)
1780
1866
  worktreeArgs.push(startPoint);
1781
- await execFileAsync("git", worktreeArgs, { cwd: directory });
1867
+ await execFileAsync("git", worktreeArgs, { cwd: directory }, acquired);
1782
1868
  }
1783
1869
  this.ctx.logger.info({ worktreePath, branch, repo: directory }, "Created git worktree for instance");
1784
1870
  workDir = worktreePath;
1785
1871
  }
1786
1872
  catch (err) {
1873
+ await cleanupDirectory().catch(e => this.ctx.logger.warn({ err: e }, "Owned worktree cleanup failed"));
1787
1874
  respond(null, `Failed to create worktree: ${err.message}`);
1788
1875
  return;
1789
1876
  }
@@ -1808,13 +1895,18 @@ export class InstanceLifecycle {
1808
1895
  // Sequential steps with rollback
1809
1896
  let createdTopicId;
1810
1897
  let newInstanceName;
1898
+ let createdConfig;
1899
+ let createdDaemon;
1900
+ let createUndo = [];
1811
1901
  // Capture the creating world's delete capability BEFORE the create await:
1812
1902
  // rollback must use exactly this adapter even if the world is removed or
1813
1903
  // replaced while creating. Never re-resolve (that would substitute the
1814
1904
  // primary or a new world). Null means fail closed at rollback.
1815
1905
  const topicDeleter = this.ctx.getForumTopicDeleter?.(adapterId) ?? null;
1816
1906
  try {
1907
+ check();
1817
1908
  createdTopicId = await this.ctx.createForumTopic(topicName, adapterId);
1909
+ check();
1818
1910
  // Use explicit topic_name as name base when provided; fall back to directory basename
1819
1911
  const explicitTopicName = args.topic_name;
1820
1912
  const nameBase = explicitTopicName ?? (worktreePath ? topicName : (directory ? basename(workDir) : topicName));
@@ -1842,7 +1934,10 @@ export class InstanceLifecycle {
1842
1934
  // If no directory was provided, auto-create default workspace
1843
1935
  if (!directory) {
1844
1936
  workDir = join(getAgendHome(), "workspaces", newInstanceName);
1937
+ const existed = existsSync(workDir);
1845
1938
  mkdirSync(workDir, { recursive: true });
1939
+ if (!existed)
1940
+ acquiredDirectory = statSync(workDir);
1846
1941
  ensureWorkspaceGit(workDir);
1847
1942
  }
1848
1943
  const instanceConfig = {
@@ -1872,11 +1967,31 @@ export class InstanceLifecycle {
1872
1967
  && !isModelCompatible(instanceConfig.backend, instanceConfig.model)) {
1873
1968
  delete instanceConfig.model;
1874
1969
  }
1875
- this.ctx.fleetConfig.instances[newInstanceName] = instanceConfig;
1876
- this.ctx.routing.register(createdTopicId, { kind: "instance", name: newInstanceName });
1877
- this.ctx.saveFleetConfig();
1878
- await this.start(newInstanceName, instanceConfig, true);
1970
+ createdConfig = instanceConfig;
1971
+ const beforeCreate = structuredClone(this.ctx.fleetConfig);
1972
+ const persist = () => {
1973
+ this.ctx.fleetConfig.instances[newInstanceName] = instanceConfig;
1974
+ this.ctx.routing.register(createdTopicId, { kind: "instance", name: newInstanceName });
1975
+ try {
1976
+ this.ctx.saveFleetConfig();
1977
+ }
1978
+ finally {
1979
+ createUndo = settingsUndo((this.ctx.getSettingsConfigPath?.() ?? join(this.ctx.dataDir, "fleet.yaml")), beforeCreate, this.ctx.fleetConfig, [["instances", newInstanceName]]);
1980
+ }
1981
+ };
1982
+ if (execution)
1983
+ execution.mutate(persist);
1984
+ else
1985
+ persist();
1986
+ if (execution)
1987
+ await this.start(newInstanceName, instanceConfig, true, undefined, undefined, execution);
1988
+ else
1989
+ await this.start(newInstanceName, instanceConfig, true);
1990
+ createdDaemon = this.daemons.get(newInstanceName);
1991
+ check();
1879
1992
  await this.ctx.connectIpcToInstance(newInstanceName);
1993
+ check();
1994
+ execution?.complete();
1880
1995
  respond({
1881
1996
  success: true,
1882
1997
  name: newInstanceName,
@@ -1886,16 +2001,20 @@ export class InstanceLifecycle {
1886
2001
  }
1887
2002
  catch (err) {
1888
2003
  // Rollback in reverse order
1889
- if (newInstanceName && this.daemons.has(newInstanceName)) {
2004
+ if (newInstanceName && createdDaemon && this.daemons.get(newInstanceName) === createdDaemon) {
1890
2005
  await this.stop(newInstanceName).catch(e => this.ctx.logger.error({ err: e, name: newInstanceName }, "Failed to stop instance during rollback"));
1891
2006
  }
1892
- if (newInstanceName && this.ctx.fleetConfig?.instances[newInstanceName]) {
1893
- delete this.ctx.fleetConfig.instances[newInstanceName];
1894
- if (createdTopicId)
1895
- this.ctx.routing.unregister(createdTopicId, newInstanceName);
1896
- this.ctx.saveFleetConfig();
2007
+ if (newInstanceName && createdConfig && this.ctx.fleetConfig?.instances[newInstanceName] === createdConfig && createUndo.length) {
2008
+ const retained = undoSettingsPaths((this.ctx.getSettingsConfigPath?.() ?? join(this.ctx.dataDir, "fleet.yaml")), this.ctx.fleetConfig, createUndo);
2009
+ if (!retained.conflicts) {
2010
+ this.ctx.fleetConfig.instances = retained.value.instances;
2011
+ if (createdTopicId && !this.ctx.fleetConfig.instances[newInstanceName])
2012
+ this.ctx.routing.unregister(createdTopicId, newInstanceName);
2013
+ this.ctx.saveFleetConfig();
2014
+ }
1897
2015
  }
1898
- if (createdTopicId) {
2016
+ const topicReferenced = createdTopicId != null && Object.values(this.ctx.fleetConfig?.instances ?? {}).some(config => String(config.topic_id) === String(createdTopicId) && (adapterId == null || config.channel_id == null || config.channel_id === adapterId));
2017
+ if (createdTopicId && !topicReferenced) {
1899
2018
  // Delete through the captured creating adapter only (#1305 P2-4/r4).
1900
2019
  // If the world went away, fail closed: log and leave the topic for
1901
2020
  // manual cleanup rather than deleting through a substituted adapter.
@@ -1911,24 +2030,7 @@ export class InstanceLifecycle {
1911
2030
  this.ctx.logger.warn({ topicId: createdTopicId }, "Creating world has no delete capability; leaving topic for manual cleanup");
1912
2031
  }
1913
2032
  }
1914
- if (worktreePath) {
1915
- try {
1916
- const { execFile: execFileCb } = await import("node:child_process");
1917
- const { promisify } = await import("node:util");
1918
- const execFileAsync = promisify(execFileCb);
1919
- await execFileAsync("git", ["worktree", "remove", "--force", worktreePath], { cwd: directory });
1920
- await execFileAsync("git", ["worktree", "prune"], { cwd: directory });
1921
- }
1922
- catch { /* best-effort worktree cleanup */ }
1923
- }
1924
- else if (!directory && workDir) {
1925
- // Remove auto-created workspace directory
1926
- try {
1927
- const { rm } = await import("node:fs/promises");
1928
- await rm(workDir, { recursive: true, force: true });
1929
- }
1930
- catch { /* best-effort cleanup */ }
1931
- }
2033
+ await cleanupDirectory().catch(e => this.ctx.logger.warn({ err: e }, "Owned instance directory cleanup failed"));
1932
2034
  respond(null, `Failed to create instance: ${err.message}`);
1933
2035
  }
1934
2036
  }
@@ -1992,6 +2094,13 @@ export class InstanceLifecycle {
1992
2094
  this.ctx.saveFleetConfig();
1993
2095
  // 5. Clean instanceDir to avoid stale rotation-state.json / crash-history
1994
2096
  const instanceDir = this.ctx.getInstanceDir(instanceName);
2097
+ // The replacement starts a fresh context: forget the conversations the old one owned (kiro, #906).
2098
+ try {
2099
+ const { createBackend } = await import("./backend/factory.js");
2100
+ const effective = savedConfig.backend ?? this.ctx.fleetConfig?.defaults?.backend ?? "claude-code";
2101
+ createBackend(effective, instanceDir)?.forget?.(instanceName);
2102
+ }
2103
+ catch { /* best effort */ }
1995
2104
  try {
1996
2105
  const { rm } = await import("node:fs/promises");
1997
2106
  await rm(instanceDir, { recursive: true, force: true });