@songsid/agend 2.2.0-beta.1 → 2.2.0-beta.10

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 (377) hide show
  1. package/README.md +1 -1
  2. package/README.zh-TW.md +1 -1
  3. package/dist/agent-cli-instructions.md +16 -9
  4. package/dist/agent-cli.js +15 -7
  5. package/dist/agent-cli.js.map +1 -1
  6. package/dist/agent-endpoint.js +21 -9
  7. package/dist/agent-endpoint.js.map +1 -1
  8. package/dist/agent-whats-new.d.ts +47 -0
  9. package/dist/agent-whats-new.js +147 -0
  10. package/dist/agent-whats-new.js.map +1 -0
  11. package/dist/auth-api.d.ts +2 -2
  12. package/dist/auth-api.js +4 -2
  13. package/dist/auth-api.js.map +1 -1
  14. package/dist/backend/antigravity.d.ts +3 -0
  15. package/dist/backend/antigravity.js +9 -0
  16. package/dist/backend/antigravity.js.map +1 -1
  17. package/dist/backend/claude-carry.d.ts +22 -0
  18. package/dist/backend/claude-carry.js +170 -0
  19. package/dist/backend/claude-carry.js.map +1 -0
  20. package/dist/backend/claude-code.d.ts +65 -2
  21. package/dist/backend/claude-code.js +226 -33
  22. package/dist/backend/claude-code.js.map +1 -1
  23. package/dist/backend/codex-metadata.d.ts +33 -0
  24. package/dist/backend/codex-metadata.js +122 -18
  25. package/dist/backend/codex-metadata.js.map +1 -1
  26. package/dist/backend/codex.d.ts +3 -0
  27. package/dist/backend/codex.js +17 -1
  28. package/dist/backend/codex.js.map +1 -1
  29. package/dist/backend/credential-profile.d.ts +40 -3
  30. package/dist/backend/credential-profile.js +113 -5
  31. package/dist/backend/credential-profile.js.map +1 -1
  32. package/dist/backend/effort-metadata.d.ts +1 -1
  33. package/dist/backend/effort-metadata.js +3 -2
  34. package/dist/backend/effort-metadata.js.map +1 -1
  35. package/dist/backend/grok.d.ts +4 -0
  36. package/dist/backend/grok.js +14 -0
  37. package/dist/backend/grok.js.map +1 -1
  38. package/dist/backend/kiro-engine-ledger.d.ts +5 -0
  39. package/dist/backend/kiro-engine-ledger.js +20 -0
  40. package/dist/backend/kiro-engine-ledger.js.map +1 -1
  41. package/dist/backend/kiro-identity.d.ts +6 -0
  42. package/dist/backend/kiro-identity.js +19 -5
  43. package/dist/backend/kiro-identity.js.map +1 -1
  44. package/dist/backend/kiro.d.ts +39 -3
  45. package/dist/backend/kiro.js +143 -19
  46. package/dist/backend/kiro.js.map +1 -1
  47. package/dist/backend/launch-effort.d.ts +33 -0
  48. package/dist/backend/launch-effort.js +123 -0
  49. package/dist/backend/launch-effort.js.map +1 -0
  50. package/dist/backend/muse.d.ts +84 -0
  51. package/dist/backend/muse.js +449 -53
  52. package/dist/backend/muse.js.map +1 -1
  53. package/dist/backend/types.d.ts +33 -4
  54. package/dist/backend/types.js +2 -1
  55. package/dist/backend/types.js.map +1 -1
  56. package/dist/backend-command.d.ts +91 -0
  57. package/dist/backend-command.js +122 -0
  58. package/dist/backend-command.js.map +1 -0
  59. package/dist/background-work-ended.d.ts +18 -0
  60. package/dist/background-work-ended.js +30 -0
  61. package/dist/background-work-ended.js.map +1 -0
  62. package/dist/cache-service.d.ts +2 -0
  63. package/dist/cache-service.js +2 -1
  64. package/dist/cache-service.js.map +1 -1
  65. package/dist/channel/adapters/discord.d.ts +24 -1
  66. package/dist/channel/adapters/discord.js +87 -2
  67. package/dist/channel/adapters/discord.js.map +1 -1
  68. package/dist/channel/adapters/telegram.d.ts +24 -2
  69. package/dist/channel/adapters/telegram.js +118 -20
  70. package/dist/channel/adapters/telegram.js.map +1 -1
  71. package/dist/channel/mcp-server.js +9 -1
  72. package/dist/channel/mcp-server.js.map +1 -1
  73. package/dist/channel/mcp-tools.d.ts +11 -0
  74. package/dist/channel/mcp-tools.js +24 -13
  75. package/dist/channel/mcp-tools.js.map +1 -1
  76. package/dist/channel/message-edit-errors.d.ts +5 -0
  77. package/dist/channel/message-edit-errors.js +24 -0
  78. package/dist/channel/message-edit-errors.js.map +1 -0
  79. package/dist/channel/telegram-markdown.d.ts +6 -0
  80. package/dist/channel/telegram-markdown.js +104 -0
  81. package/dist/channel/telegram-markdown.js.map +1 -0
  82. package/dist/channel/tool-router.js +9 -3
  83. package/dist/channel/tool-router.js.map +1 -1
  84. package/dist/channel/types.d.ts +39 -3
  85. package/dist/cli.js +133 -28
  86. package/dist/cli.js.map +1 -1
  87. package/dist/command-table.d.ts +2 -2
  88. package/dist/command-table.js +6 -3
  89. package/dist/command-table.js.map +1 -1
  90. package/dist/config-validator.js +59 -0
  91. package/dist/config-validator.js.map +1 -1
  92. package/dist/cross-instance-envelope.d.ts +15 -2
  93. package/dist/cross-instance-envelope.js +29 -5
  94. package/dist/cross-instance-envelope.js.map +1 -1
  95. package/dist/daemon.d.ts +156 -1
  96. package/dist/daemon.js +764 -89
  97. package/dist/daemon.js.map +1 -1
  98. package/dist/delivery-outbox.d.ts +62 -7
  99. package/dist/delivery-outbox.js +309 -22
  100. package/dist/delivery-outbox.js.map +1 -1
  101. package/dist/delivery-reconciliation.d.ts +18 -1
  102. package/dist/delivery-reconciliation.js +67 -2
  103. package/dist/delivery-reconciliation.js.map +1 -1
  104. package/dist/fleet-context.d.ts +10 -1
  105. package/dist/fleet-manager.d.ts +345 -10
  106. package/dist/fleet-manager.js +1868 -174
  107. package/dist/fleet-manager.js.map +1 -1
  108. package/dist/general-knowledge/skills/backend-providers/SKILL.md +1 -1
  109. package/dist/general-knowledge/skills/credential-profiles/SKILL.md +92 -21
  110. package/dist/general-knowledge/skills/cross-instance-messaging/SKILL.md +27 -3
  111. package/dist/general-knowledge/skills/delegation-playbook/SKILL.md +8 -8
  112. package/dist/general-knowledge/skills/fleet-config/SKILL.md +5 -5
  113. package/dist/general-knowledge/skills/fleet-health/SKILL.md +4 -4
  114. package/dist/general-knowledge/skills/fleet-restart/SKILL.md +13 -13
  115. package/dist/general-knowledge/skills/instance-lifecycle/SKILL.md +3 -2
  116. package/dist/general-knowledge/skills/kiro-engine-migration/SKILL.md +6 -0
  117. package/dist/general-knowledge/skills/model-discovery/SKILL.md +9 -9
  118. package/dist/general-knowledge/skills/multi-channel/SKILL.md +8 -2
  119. package/dist/general-knowledge/skills/scheduling/SKILL.md +5 -3
  120. package/dist/general-knowledge/skills/session-management/SKILL.md +6 -5
  121. package/dist/general-knowledge/skills/tui-effort/SKILL.md +2 -2
  122. package/dist/general-knowledge/skills/worker-collaboration/SKILL.md +8 -3
  123. package/dist/general-knowledge/steering/core-rules.md +8 -7
  124. package/dist/host-memory.d.ts +10 -0
  125. package/dist/host-memory.js +33 -1
  126. package/dist/host-memory.js.map +1 -1
  127. package/dist/human-delivery-receipts.d.ts +83 -0
  128. package/dist/human-delivery-receipts.js +194 -0
  129. package/dist/human-delivery-receipts.js.map +1 -0
  130. package/dist/instance-avatar.d.ts +36 -0
  131. package/dist/instance-avatar.js +57 -0
  132. package/dist/instance-avatar.js.map +1 -0
  133. package/dist/instance-config-impact.js +6 -0
  134. package/dist/instance-config-impact.js.map +1 -1
  135. package/dist/instance-lifecycle.d.ts +29 -6
  136. package/dist/instance-lifecycle.js +79 -28
  137. package/dist/instance-lifecycle.js.map +1 -1
  138. package/dist/instructions.d.ts +3 -1
  139. package/dist/instructions.js +11 -8
  140. package/dist/instructions.js.map +1 -1
  141. package/dist/kiro-log-gate.d.ts +42 -0
  142. package/dist/kiro-log-gate.js +39 -0
  143. package/dist/kiro-log-gate.js.map +1 -0
  144. package/dist/locale.js +200 -44
  145. package/dist/locale.js.map +1 -1
  146. package/dist/log-service.d.ts +99 -0
  147. package/dist/log-service.js +243 -0
  148. package/dist/log-service.js.map +1 -0
  149. package/dist/log-steps.d.ts +169 -0
  150. package/dist/log-steps.js +858 -0
  151. package/dist/log-steps.js.map +1 -0
  152. package/dist/login-controller.d.ts +20 -3
  153. package/dist/login-controller.js +71 -19
  154. package/dist/login-controller.js.map +1 -1
  155. package/dist/login-flows.d.ts +5 -2
  156. package/dist/login-flows.js +5 -4
  157. package/dist/login-flows.js.map +1 -1
  158. package/dist/memory-pressure.d.ts +13 -1
  159. package/dist/memory-pressure.js +50 -10
  160. package/dist/memory-pressure.js.map +1 -1
  161. package/dist/needs-you-hub.js +2 -0
  162. package/dist/needs-you-hub.js.map +1 -1
  163. package/dist/needs-you-live.d.ts +6 -0
  164. package/dist/needs-you-live.js +23 -3
  165. package/dist/needs-you-live.js.map +1 -1
  166. package/dist/next-steps.js +1 -1
  167. package/dist/next-steps.js.map +1 -1
  168. package/dist/outbound-handlers.d.ts +100 -0
  169. package/dist/outbound-handlers.js +263 -96
  170. package/dist/outbound-handlers.js.map +1 -1
  171. package/dist/outbound-schemas.d.ts +26 -15
  172. package/dist/outbound-schemas.js +24 -7
  173. package/dist/outbound-schemas.js.map +1 -1
  174. package/dist/public-link-progress.d.ts +1 -1
  175. package/dist/public-link-progress.js +8 -2
  176. package/dist/public-link-progress.js.map +1 -1
  177. package/dist/public-preview.d.ts +101 -0
  178. package/dist/public-preview.js +236 -0
  179. package/dist/public-preview.js.map +1 -0
  180. package/dist/public-web-gateway.js +11 -4
  181. package/dist/public-web-gateway.js.map +1 -1
  182. package/dist/public-web-link.d.ts +24 -1
  183. package/dist/public-web-link.js +63 -9
  184. package/dist/public-web-link.js.map +1 -1
  185. package/dist/reply-buttons-controller.d.ts +3 -0
  186. package/dist/reply-buttons-controller.js +3 -2
  187. package/dist/reply-buttons-controller.js.map +1 -1
  188. package/dist/restart-guard.d.ts +6 -3
  189. package/dist/restart-guard.js +6 -3
  190. package/dist/restart-guard.js.map +1 -1
  191. package/dist/restart-progress.d.ts +33 -0
  192. package/dist/restart-progress.js +30 -0
  193. package/dist/restart-progress.js.map +1 -1
  194. package/dist/service-activation.d.ts +15 -7
  195. package/dist/service-activation.js +46 -29
  196. package/dist/service-activation.js.map +1 -1
  197. package/dist/service-installer.d.ts +31 -0
  198. package/dist/service-installer.js +41 -2
  199. package/dist/service-installer.js.map +1 -1
  200. package/dist/settings-api.js +85 -25
  201. package/dist/settings-api.js.map +1 -1
  202. package/dist/settings-change.js +72 -1
  203. package/dist/settings-change.js.map +1 -1
  204. package/dist/settings-effect.js +28 -4
  205. package/dist/settings-effect.js.map +1 -1
  206. package/dist/settings-http-confirmation.js +7 -0
  207. package/dist/settings-http-confirmation.js.map +1 -1
  208. package/dist/setup-form.d.ts +1 -1
  209. package/dist/setup-form.js +1 -1
  210. package/dist/spawn-gate.js +5 -1
  211. package/dist/spawn-gate.js.map +1 -1
  212. package/dist/spawn-hold-reply.d.ts +12 -0
  213. package/dist/spawn-hold-reply.js +39 -0
  214. package/dist/spawn-hold-reply.js.map +1 -0
  215. package/dist/status-emojis.d.ts +10 -3
  216. package/dist/status-emojis.js +11 -2
  217. package/dist/status-emojis.js.map +1 -1
  218. package/dist/systemd-peer-bus.d.ts +95 -0
  219. package/dist/systemd-peer-bus.js +430 -0
  220. package/dist/systemd-peer-bus.js.map +1 -0
  221. package/dist/systemd-runtime.d.ts +27 -1
  222. package/dist/systemd-runtime.js +69 -7
  223. package/dist/systemd-runtime.js.map +1 -1
  224. package/dist/tips.js +4 -4
  225. package/dist/tips.js.map +1 -1
  226. package/dist/tool-progress.js +3 -2
  227. package/dist/tool-progress.js.map +1 -1
  228. package/dist/topic-commands.d.ts +42 -2
  229. package/dist/topic-commands.js +92 -7
  230. package/dist/topic-commands.js.map +1 -1
  231. package/dist/transcript-delta-reader.d.ts +3 -3
  232. package/dist/transcript-delta-reader.js +8 -8
  233. package/dist/transcript-delta-reader.js.map +1 -1
  234. package/dist/transcript-jsonl.d.ts +80 -3
  235. package/dist/transcript-jsonl.js +147 -10
  236. package/dist/transcript-jsonl.js.map +1 -1
  237. package/dist/transcript-monitor.d.ts +19 -0
  238. package/dist/transcript-monitor.js +87 -15
  239. package/dist/transcript-monitor.js.map +1 -1
  240. package/dist/transcript-sources.d.ts +78 -0
  241. package/dist/transcript-sources.js +375 -64
  242. package/dist/transcript-sources.js.map +1 -1
  243. package/dist/transcript-turns.d.ts +15 -2
  244. package/dist/transcript-turns.js +15 -2
  245. package/dist/transcript-turns.js.map +1 -1
  246. package/dist/tunnel/cloudflared.d.ts +7 -15
  247. package/dist/tunnel/cloudflared.js +36 -1
  248. package/dist/tunnel/cloudflared.js.map +1 -1
  249. package/dist/tunnel/purpose-lane.d.ts +5 -1
  250. package/dist/tunnel/purpose-lane.js +14 -7
  251. package/dist/tunnel/purpose-lane.js.map +1 -1
  252. package/dist/tunnel/types.d.ts +5 -1
  253. package/dist/tunnel/types.js.map +1 -1
  254. package/dist/turn-resume.d.ts +2 -0
  255. package/dist/turn-resume.js +1 -1
  256. package/dist/turn-resume.js.map +1 -1
  257. package/dist/types.d.ts +25 -0
  258. package/dist/ui/chat-commands.js +1 -0
  259. package/dist/ui/chat-emojis.js +33 -0
  260. package/dist/ui/chat-mentions.js +63 -0
  261. package/dist/ui/chat-render.js +42 -2
  262. package/dist/ui/chat-store.js +2 -2
  263. package/dist/ui/chat-strings.js +38 -20
  264. package/dist/ui/chat-thread.js +69 -12
  265. package/dist/ui/chat-time.js +80 -0
  266. package/dist/ui/panel-chat.js +39 -10
  267. package/dist/ui/panel-details.js +2 -0
  268. package/dist/ui/panel-fleet.js +199 -57
  269. package/dist/ui/panel-log.js +428 -0
  270. package/dist/ui/panel-needs.js +6 -2
  271. package/dist/ui/panel-settings.js +137 -32
  272. package/dist/ui/preview-panel.js +55 -15
  273. package/dist/ui/preview-status.js +28 -0
  274. package/dist/ui/preview.js +44 -3
  275. package/dist/ui/settings-dialogs.js +7 -2
  276. package/dist/ui/settings-model.js +2 -1
  277. package/dist/ui/settings-strings.js +46 -4
  278. package/dist/ui/settings-token.js +1 -1
  279. package/dist/ui/shared/app-i18n.js +43 -17
  280. package/dist/ui/shared/app-prefs.js +250 -0
  281. package/dist/ui/shared/app-route.js +7 -2
  282. package/dist/ui/shared/app-shell.js +165 -8
  283. package/dist/ui/shared/app-store.js +5 -1
  284. package/dist/ui/shared/app-stream.js +23 -5
  285. package/dist/ui/shared/app.css +155 -22
  286. package/dist/ui/shared/app.js +11 -1
  287. package/dist/ui/shared/fonts/README.md +1 -1
  288. package/dist/ui/shared/header-tools.js +55 -5
  289. package/dist/ui/shared/instance-nav.js +241 -45
  290. package/dist/ui/shared/instance-switch.js +4 -4
  291. package/dist/ui/shared/panel-view.js +6 -0
  292. package/dist/ui/shared/signin.js +7 -7
  293. package/dist/ui/shared/theme.js +39 -7
  294. package/dist/ui/shared/tokens.css +1 -1
  295. package/dist/ui/shared/ui-icons.js +1 -0
  296. package/dist/ui/shared/usage-dialog.js +23 -5
  297. package/dist/ui/shared/view-strings.js +32 -4
  298. package/dist/ui/signin.html +1 -1
  299. package/dist/unrecognised-prompt.d.ts +23 -0
  300. package/dist/unrecognised-prompt.js +74 -0
  301. package/dist/unrecognised-prompt.js.map +1 -0
  302. package/dist/update-install.d.ts +28 -2
  303. package/dist/update-install.js +22 -4
  304. package/dist/update-install.js.map +1 -1
  305. package/dist/update-marker.d.ts +51 -0
  306. package/dist/update-marker.js +61 -0
  307. package/dist/update-marker.js.map +1 -1
  308. package/dist/update-preflight.d.ts +100 -0
  309. package/dist/update-preflight.js +264 -0
  310. package/dist/update-preflight.js.map +1 -0
  311. package/dist/updater-caller.d.ts +31 -0
  312. package/dist/updater-caller.js +109 -0
  313. package/dist/updater-caller.js.map +1 -0
  314. package/dist/usage/i18n-keys.d.ts +1 -1
  315. package/dist/usage/i18n-keys.js +1 -1
  316. package/dist/usage/i18n-keys.js.map +1 -1
  317. package/dist/usage/providers.d.ts +34 -5
  318. package/dist/usage/providers.js +160 -27
  319. package/dist/usage/providers.js.map +1 -1
  320. package/dist/usage/statusline-usage.d.ts +6 -2
  321. package/dist/usage/statusline-usage.js +10 -4
  322. package/dist/usage/statusline-usage.js.map +1 -1
  323. package/dist/view-api.d.ts +1 -1
  324. package/dist/view-api.js +38 -8
  325. package/dist/view-api.js.map +1 -1
  326. package/dist/wake-coordinator.d.ts +11 -0
  327. package/dist/wake-coordinator.js +38 -4
  328. package/dist/wake-coordinator.js.map +1 -1
  329. package/dist/web-api.d.ts +49 -2
  330. package/dist/web-api.js +421 -31
  331. package/dist/web-api.js.map +1 -1
  332. package/dist/web-auth.d.ts +2 -2
  333. package/dist/web-auth.js +9 -4
  334. package/dist/web-auth.js.map +1 -1
  335. package/dist/web-commands.d.ts +27 -4
  336. package/dist/web-commands.js +19 -4
  337. package/dist/web-commands.js.map +1 -1
  338. package/dist/web-host-guard.d.ts +3 -11
  339. package/dist/web-host-guard.js +3 -12
  340. package/dist/web-host-guard.js.map +1 -1
  341. package/dist/web-images.d.ts +47 -0
  342. package/dist/web-images.js +169 -0
  343. package/dist/web-images.js.map +1 -0
  344. package/dist/web-mentions.d.ts +44 -0
  345. package/dist/web-mentions.js +75 -0
  346. package/dist/web-mentions.js.map +1 -0
  347. package/dist/web-prefs.d.ts +63 -0
  348. package/dist/web-prefs.js +265 -0
  349. package/dist/web-prefs.js.map +1 -0
  350. package/dist/web-preview.d.ts +14 -1
  351. package/dist/web-preview.js +35 -13
  352. package/dist/web-preview.js.map +1 -1
  353. package/dist/web-reply-files.d.ts +45 -0
  354. package/dist/web-reply-files.js +223 -0
  355. package/dist/web-reply-files.js.map +1 -0
  356. package/dist/web-schedules.d.ts +12 -0
  357. package/dist/web-schedules.js +34 -0
  358. package/dist/web-schedules.js.map +1 -0
  359. package/dist/web-server-drain.d.ts +10 -0
  360. package/dist/web-server-drain.js +50 -0
  361. package/dist/web-server-drain.js.map +1 -0
  362. package/dist/web-session.d.ts +36 -1
  363. package/dist/web-session.js +53 -6
  364. package/dist/web-session.js.map +1 -1
  365. package/dist/web-settings-patch.d.ts +23 -0
  366. package/dist/web-settings-patch.js +77 -0
  367. package/dist/web-settings-patch.js.map +1 -0
  368. package/dist/web-shell-routes.d.ts +5 -1
  369. package/dist/web-shell-routes.js +10 -1
  370. package/dist/web-shell-routes.js.map +1 -1
  371. package/dist/web-upload.d.ts +17 -4
  372. package/dist/web-upload.js +64 -13
  373. package/dist/web-upload.js.map +1 -1
  374. package/dist/workflow-templates/default.md +1 -1
  375. package/package.json +1 -1
  376. package/templates/launchd.plist.ejs +3 -1
  377. package/templates/systemd.service.ejs +2 -1
package/dist/cli.js CHANGED
@@ -20,7 +20,7 @@ import { existsSync, readFileSync, writeFileSync, appendFileSync, unlinkSync, mk
20
20
  import { homedir, totalmem, freemem, userInfo } from "node:os";
21
21
  import { fileURLToPath } from "node:url";
22
22
  import { spawn, spawnSync, execSync, execFileSync } from "node:child_process";
23
- import { getAgendHome, getTmuxSocketName } from "./paths.js";
23
+ import { getAgendHome, getTmuxSocketName, isDefaultAgendHome } from "./paths.js";
24
24
  import { hasPausedMarker } from "./pause-marker.js";
25
25
  import { COMPLETION_SHELLS, completionScript } from "./completion.js";
26
26
  import { getUpdateSelector, isExactVersion, isUnrequestedDowngrade, lookupTargetVersion, reportUpdateRestart, shouldSkipUpdate, runningFleetPredatesInstall, processStartMs, } from "./update-check.js";
@@ -1495,7 +1495,7 @@ program
1495
1495
  const { newAgendInvocation, retireSystemCopy, activationSettled } = await import("./update-install.js");
1496
1496
  // What the restart came to — carried, never inferred from the exit code (pending ≠ restarted).
1497
1497
  let restartResult = null;
1498
- const { activateService } = await import("./service-activation.js");
1498
+ const { activateService, systemdPeerBus } = await import("./service-activation.js");
1499
1499
  const { getServicePath, getSystemServicePath, detectPlatform } = await import("./service-installer.js");
1500
1500
  const { accessSync, constants } = await import("node:fs");
1501
1501
  const newAgend = newAgendInvocation({ viaNvm, nvmSh }, verified.agendPath);
@@ -1518,6 +1518,18 @@ program
1518
1518
  const result = spawnSync(command, args, { encoding: "utf-8", timeout: 15_000, stdio: ["ignore", "pipe", "pipe"] });
1519
1519
  return { status: result.status, signal: result.signal, stdout: result.stdout ?? "", stderr: result.stderr ?? "" };
1520
1520
  };
1521
+ // #1660: the retire outcome lands after this process's restart returns —
1522
+ // after the new fleet may have consumed this receipt. Capture it now so
1523
+ // the cleanup write later can prove it still owns the marker (checklist
1524
+ // 3/5). A missed capture only skips the marker write; retire still runs.
1525
+ let cleanupReceipt = null;
1526
+ if (verified.retireSystemCopy) {
1527
+ try {
1528
+ const { markCleanupPending } = await import("./update-marker.js");
1529
+ cleanupReceipt = markCleanupPending(DATA_DIR);
1530
+ }
1531
+ catch { /* no receipt: retire still runs, the marker write is skipped */ }
1532
+ }
1521
1533
  const outcome = activateService(manager, verified, {
1522
1534
  run: capture,
1523
1535
  readFile: path => { try {
@@ -1546,7 +1558,8 @@ program
1546
1558
  catch {
1547
1559
  return false;
1548
1560
  } },
1549
- // `agend install` activates by default; the update owns stop/start, so only the file is refreshed here.
1561
+ // `agend install` activates by default; the update owns stop/start, so only the file is refreshed here. Only
1562
+ // an existing service is refreshed: a detached fleet's update never calls this (#1631).
1550
1563
  refresh: () => {
1551
1564
  const result = capture(newAgend.command, [...newAgend.args, "install", "--no-activate"]);
1552
1565
  if (result.status === 0)
@@ -1566,6 +1579,7 @@ program
1566
1579
  log: message => console.log(message),
1567
1580
  restorePackage,
1568
1581
  systemdRecovery: restoreChecked ? { restorePackage: restoreChecked } : undefined,
1582
+ peerBus: systemdPeerBus,
1569
1583
  });
1570
1584
  // Settled: after a success only this transition's preimage is kept (for a repair); a failure consumed it.
1571
1585
  if (activationSettled(outcome, restartResult) && rollback)
@@ -1574,10 +1588,41 @@ program
1574
1588
  // new install (activationSettled) is it removed; pending, failed or refused, it stays, so the old unit still starts.
1575
1589
  if (verified.retireSystemCopy) {
1576
1590
  if (activationSettled(outcome, restartResult)) {
1577
- const retireResult = retireSystemCopy({ run: (command, args) => capture(command, args), log: message => console.log(message) }, verified.npmPath);
1591
+ // #1735: the old copy is the package this updater runs from (the nvm route is taken because its prefix is not
1592
+ // writable); the warning names it.
1593
+ const oldCopyDir = (() => { try {
1594
+ return realpathSync(dirname(__dirname));
1595
+ }
1596
+ catch {
1597
+ return undefined;
1598
+ } })();
1599
+ const retireResult = retireSystemCopy({ run: (command, args) => capture(command, args), log: message => console.log(message) }, verified.npmPath, oldCopyDir);
1600
+ // The marker write proves the pre-restart receipt still owns the
1601
+ // marker: refused when it is gone or belongs to another operation.
1602
+ const recordCleanup = async (result) => {
1603
+ if (!cleanupReceipt)
1604
+ return;
1605
+ try {
1606
+ const { writeCleanupOutcome } = await import("./update-marker.js");
1607
+ writeCleanupOutcome(DATA_DIR, cleanupReceipt, result);
1608
+ }
1609
+ catch { /* receipt unverifiable: retire already ran; stdout stands */ }
1610
+ };
1578
1611
  if (!retireResult.ok) {
1579
1612
  console.error(` ✗ Old system install was not removed: ${retireResult.reason}`);
1580
1613
  process.exitCode = 1;
1614
+ // Resolve the pending flag so no watch waits out the max age.
1615
+ await recordCleanup(null);
1616
+ }
1617
+ else if (retireResult.warning) {
1618
+ // #1660: cleanup only — the new version runs. Exit 0; the single
1619
+ // print lives here (retireSystemCopy stays silent, P3-1).
1620
+ console.log(` ⚠️ ${retireResult.warning}`
1621
+ + (retireResult.cleanupCommand ? `\n $ ${retireResult.cleanupCommand}` : ""));
1622
+ await recordCleanup({ warning: retireResult.warning, cleanupCommand: retireResult.cleanupCommand });
1623
+ }
1624
+ else {
1625
+ await recordCleanup(null);
1581
1626
  }
1582
1627
  }
1583
1628
  else {
@@ -1663,6 +1708,42 @@ program
1663
1708
  process.exitCode = 1;
1664
1709
  return;
1665
1710
  }
1711
+ // ── Check if npm global needs sudo (read-only; decides the nvm path the preflight judges) ──
1712
+ let needsSudo = false;
1713
+ try {
1714
+ const prefix = execSync("npm config get prefix", { encoding: "utf-8" }).trim();
1715
+ const { accessSync, constants } = await import("node:fs");
1716
+ try {
1717
+ accessSync(prefix, constants.W_OK);
1718
+ }
1719
+ catch {
1720
+ needsSudo = true;
1721
+ }
1722
+ }
1723
+ catch { /* assume no sudo needed */ }
1724
+ // ── #1441 B: can the target run here, on the Node it will actually run on? ──
1725
+ // Read where the install runs (#1623 review): a direct install runs `npm` and the release's `node` from this
1726
+ // environment, so it is decided now, before anything is touched. An nvm install runs nvm's npm and Node 22, which
1727
+ // exist only once nvm has selected them: runUpdateInstall decides it there, before the lock and npm.
1728
+ const preflight = targetVersion ? await import("./update-preflight.js") : null;
1729
+ if (preflight && targetVersion && !needsSudo) {
1730
+ const verdict = preflight.preflightUpdate({
1731
+ run: (argv, timeoutMs) => {
1732
+ const r = spawnSync(argv[0], argv.slice(1), { encoding: "utf-8", timeout: timeoutMs, stdio: ["ignore", "pipe", "ignore"] });
1733
+ return { status: r.status, stdout: r.stdout ?? "" };
1734
+ },
1735
+ npm: "npm",
1736
+ }, pkg, targetVersion, "the `node` on PATH");
1737
+ if (verdict.kind === "refuse") {
1738
+ console.error(`\n${verdict.message}\n`);
1739
+ // A chat-started /update (Discord, Telegram, an agent) is waiting on this: the reason is its outcome.
1740
+ setUpdateProgressStage(DATA_DIR, "failed", { error: `Not updated: ${verdict.summary}. Nothing was changed.` });
1741
+ process.exitCode = 1;
1742
+ return;
1743
+ }
1744
+ if (verdict.kind === "unknown")
1745
+ console.log(verdict.note);
1746
+ }
1666
1747
  if (targetVersion) {
1667
1748
  console.log(`\n Updating AgEnD v${pkgVersion} → v${targetVersion}...\n`);
1668
1749
  }
@@ -1684,19 +1765,6 @@ program
1684
1765
  process.exit(1);
1685
1766
  };
1686
1767
  setUpdateProgressStage(DATA_DIR, "downloading");
1687
- // ── Check if npm global needs sudo ──
1688
- let needsSudo = false;
1689
- try {
1690
- const prefix = execSync("npm config get prefix", { encoding: "utf-8" }).trim();
1691
- const { accessSync, constants } = await import("node:fs");
1692
- try {
1693
- accessSync(prefix, constants.W_OK);
1694
- }
1695
- catch {
1696
- needsSudo = true;
1697
- }
1698
- }
1699
- catch { /* assume no sudo needed */ }
1700
1768
  if (needsSudo) {
1701
1769
  // ── nvm path: install without sudo ──
1702
1770
  if (!existsSync(nvmSh)) {
@@ -1728,6 +1796,9 @@ program
1728
1796
  process.once("exit", () => releaseLock());
1729
1797
  const installed = runUpdateInstall({
1730
1798
  pkg, targetVersion, viaNvm: needsSudo, nvmSh, rollback: true,
1799
+ ...(preflight && targetVersion && needsSudo
1800
+ ? { preflight: preflight.installPreflight(pkg, targetVersion, "the Node 22 nvm selected", { log: m => console.log(m), error: m => console.error(m) }) }
1801
+ : {}),
1731
1802
  lock: prefix => {
1732
1803
  const lock = acquireInstallLock(prefix, { spec: pkg, agendHome: DATA_DIR }, {
1733
1804
  pid: process.pid, processStart: admission.processStart, newToken: () => randomBytes(16).toString("hex"),
@@ -1786,15 +1857,34 @@ program
1786
1857
  .option("--activate", "Deprecated; service activation is now the default")
1787
1858
  .option("--no-activate", "Write the service file without activating it")
1788
1859
  .action(async (opts) => {
1789
- const { installService, activateService, detectPlatform, renderLaunchdPlist, launchdPlistPath } = await import("./service-installer.js");
1860
+ const { installService, activateService, detectPlatform, renderLaunchdPlist, launchdPlistPath, getServicePath, getSystemServicePath, serviceHomeFor } = await import("./service-installer.js");
1861
+ // #1631 B: an older updater (2.2.0-beta.1 and before) refreshes a hand-started fleet's service too, through this
1862
+ // command — which would CREATE a unit or plist, and every later update would then take a manager it may not reach
1863
+ // as the authority. When no service exists and it is certain this is that updater's refresh, write nothing. A
1864
+ // manual `agend install` (with or without --no-activate) creates the service as always.
1865
+ if (opts.activate === false && getServicePath() === null && getSystemServicePath() === null) {
1866
+ const { startedByUpdater, systemUpdaterCallerProbe } = await import("./updater-caller.js");
1867
+ const caller = startedByUpdater(systemUpdaterCallerProbe(DATA_DIR, pkgVersion));
1868
+ if (caller.updater) {
1869
+ console.log(" No service to refresh: this update runs a hand-started fleet, so none was created (`agend install` creates one).");
1870
+ return;
1871
+ }
1872
+ }
1790
1873
  const execPath = canonicalCliEntry();
1791
- const serviceVars = {
1792
- label: "com.agend.fleet",
1793
- execPath,
1794
- path: process.env.PATH,
1795
- workingDirectory: DATA_DIR,
1796
- logPath: join(DATA_DIR, "fleet.log"),
1797
- };
1874
+ // A fleet on a custom AGEND_HOME must come back on it after a service restart or an update: the definition names
1875
+ // it (the default home adds nothing). A refresh from the default home keeps an existing definition's home.
1876
+ const existingPath = getServicePath();
1877
+ const service = serviceHomeFor(DATA_DIR, {
1878
+ refresh: opts.activate === false,
1879
+ existingDefinition: existingPath ? (() => { try {
1880
+ return readFileSync(existingPath, "utf-8");
1881
+ }
1882
+ catch {
1883
+ return null;
1884
+ } })() : null,
1885
+ isDefault: isDefaultAgendHome,
1886
+ });
1887
+ const serviceVars = { label: "com.agend.fleet", execPath, path: process.env.PATH, ...service };
1798
1888
  // #1450 C6: on launchd, writing a new plist without activating is a PLANNED activation — proven, recorded, and
1799
1889
  // left for `agend restart` (a reload there would itself start the job). See service-plan.ts.
1800
1890
  if (opts.activate === false && detectPlatform() === "macos") {
@@ -2194,7 +2284,8 @@ program
2194
2284
  }
2195
2285
  if (filterCustom)
2196
2286
  console.log(` ⚠ ${unitPath} sets its own CoredumpFilter; left as is. CoredumpFilter=0 keeps crash dumps to a few KB (#1113).`);
2197
- if (expectation.ok && refuses(guard.guardSystemd(captureRun, systemdTarget.user, systemdTarget.unit, expectation.expected, guardDeps)))
2287
+ const { systemdPeerBus } = await import("./service-activation.js");
2288
+ if (expectation.ok && refuses(guard.guardSystemd(captureRun, systemdTarget.user, systemdTarget.unit, expectation.expected, guardDeps, systemdPeerBus)))
2198
2289
  return;
2199
2290
  // Clears the failed state AND the start-limit counter (#1113:
2200
2291
  // StartLimitBurst=4 in 30min) for whichever unit this restart targets,
@@ -2578,7 +2669,7 @@ program
2578
2669
  console.log("Web token rotated.");
2579
2670
  console.log("Every previously issued dashboard link and browser session is now rejected.");
2580
2671
  console.log("A running fleet picks this up immediately — no restart needed.");
2581
- console.log("Sign in again with `agend web` (prints a one-time code), or /dashboard in your chat channel.");
2672
+ console.log("Sign in again with `agend web` (prints a one-time code), or /web in your chat channel.");
2582
2673
  });
2583
2674
  program
2584
2675
  .command("view")
@@ -2901,7 +2992,21 @@ async function fuzzyMatch(query, names) {
2901
2992
  return null;
2902
2993
  }
2903
2994
  async function resolveInstance(query, config) {
2904
- const names = await listInstanceNames(config);
2995
+ const namesRaw = await listInstanceNames(config);
2996
+ const names = [...new Set(namesRaw)]; // P3-3: deduplicate (a classicBot instanceName can equal a fleet name)
2997
+ const { resolveName } = await import("./topic-commands.js");
2998
+ const entries = names.map((name) => ({
2999
+ name,
3000
+ displayName: config.instances[name]?.display_name,
3001
+ }));
3002
+ const result = resolveName(query, entries);
3003
+ if (result.kind === "name")
3004
+ return result.realName;
3005
+ if (result.kind === "ambiguous") {
3006
+ console.error(`"${query}" matches multiple instances: ${result.realNames.join(", ")}. Use the real name.`);
3007
+ process.exit(1);
3008
+ }
3009
+ // Fall through to the original fuzzy match on real names.
2905
3010
  const match = await fuzzyMatch(query, names);
2906
3011
  if (!match) {
2907
3012
  console.error(`No instance matching "${query}". Available: ${names.join(", ")}`);