@songsid/agend 2.3.0-beta.9 → 2.3.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.
- package/README.md +16 -8
- package/README.zh-TW.md +16 -8
- package/dist/adapter-world.js.map +1 -1
- package/dist/agend-home.d.ts +5 -0
- package/dist/agend-home.js +7 -0
- package/dist/agend-home.js.map +1 -0
- package/dist/agent-cli-instructions.md +7 -1
- package/dist/agent-cli.js +41 -0
- package/dist/agent-cli.js.map +1 -1
- package/dist/agent-endpoint.d.ts +9 -0
- package/dist/agent-endpoint.js +23 -0
- package/dist/agent-endpoint.js.map +1 -1
- package/dist/agent-file-read.js +1 -1
- package/dist/agent-file-read.js.map +1 -1
- package/dist/agent-whats-new.d.ts +16 -0
- package/dist/agent-whats-new.js +53 -12
- package/dist/agent-whats-new.js.map +1 -1
- package/dist/apply-job.js.map +1 -1
- package/dist/atomic-write.js.map +1 -1
- package/dist/auth-api.d.ts +12 -0
- package/dist/auth-api.js +77 -22
- package/dist/auth-api.js.map +1 -1
- package/dist/authority/authority-state.d.ts +4 -0
- package/dist/authority/authority-state.js +17 -8
- package/dist/authority/authority-state.js.map +1 -1
- package/dist/authority/session-authorizations.js.map +1 -1
- package/dist/authority/web-authority.d.ts +16 -8
- package/dist/authority/web-authority.js +19 -5
- package/dist/authority/web-authority.js.map +1 -1
- package/dist/backend/antigravity.d.ts +2 -2
- package/dist/backend/antigravity.js +2 -1
- package/dist/backend/antigravity.js.map +1 -1
- package/dist/backend/claude-code.js +13 -4
- package/dist/backend/claude-code.js.map +1 -1
- package/dist/backend/codex-metadata.d.ts +8 -0
- package/dist/backend/codex-metadata.js +74 -17
- package/dist/backend/codex-metadata.js.map +1 -1
- package/dist/backend/codex-package.d.ts +30 -0
- package/dist/backend/codex-package.js +133 -0
- package/dist/backend/codex-package.js.map +1 -0
- package/dist/backend/codex-session-lookup.js.map +1 -1
- package/dist/backend/codex.d.ts +2 -0
- package/dist/backend/codex.js +25 -5
- package/dist/backend/codex.js.map +1 -1
- package/dist/backend/credential-profile.d.ts +2 -0
- package/dist/backend/credential-profile.js +2 -0
- package/dist/backend/credential-profile.js.map +1 -1
- package/dist/backend/effort-metadata.js.map +1 -1
- package/dist/backend/grok.js +58 -3
- package/dist/backend/grok.js.map +1 -1
- package/dist/backend/kiro-engine-ledger.js.map +1 -1
- package/dist/backend/kiro-kas-store.js.map +1 -1
- package/dist/backend/kiro-v2-store.js.map +1 -1
- package/dist/backend/kiro-v3-identity.js.map +1 -1
- package/dist/backend/kiro.d.ts +9 -1
- package/dist/backend/kiro.js +102 -1
- package/dist/backend/kiro.js.map +1 -1
- package/dist/backend/launch-effort.js.map +1 -1
- package/dist/backend/mock.js.map +1 -1
- package/dist/backend/muse.d.ts +20 -2
- package/dist/backend/muse.js +154 -16
- package/dist/backend/muse.js.map +1 -1
- package/dist/backend/opencode-permission.js +1 -1
- package/dist/backend/opencode-permission.js.map +1 -1
- package/dist/backend/opencode.js +2 -1
- package/dist/backend/opencode.js.map +1 -1
- package/dist/backend/session-signals.js.map +1 -1
- package/dist/backend-availability.js.map +1 -1
- package/dist/backend-command.d.ts +2 -0
- package/dist/backend-command.js +3 -1
- package/dist/backend-command.js.map +1 -1
- package/dist/backend-outage.js.map +1 -1
- package/dist/binary-probe.js +1 -1
- package/dist/binary-probe.js.map +1 -1
- package/dist/bug-report-cli.d.ts +30 -0
- package/dist/bug-report-cli.js +139 -0
- package/dist/bug-report-cli.js.map +1 -0
- package/dist/bug-report.d.ts +47 -0
- package/dist/bug-report.js +137 -0
- package/dist/bug-report.js.map +1 -0
- package/dist/bundled-skills.d.ts +18 -0
- package/dist/bundled-skills.js +38 -0
- package/dist/bundled-skills.js.map +1 -0
- package/dist/cache-service.js +1 -1
- package/dist/cache-service.js.map +1 -1
- package/dist/channel/adapters/discord-client-retirement.d.ts +5 -0
- package/dist/channel/adapters/discord-client-retirement.js +57 -0
- package/dist/channel/adapters/discord-client-retirement.js.map +1 -0
- package/dist/channel/adapters/discord.d.ts +4 -0
- package/dist/channel/adapters/discord.js +57 -12
- package/dist/channel/adapters/discord.js.map +1 -1
- package/dist/channel/adapters/telegram.d.ts +7 -1
- package/dist/channel/adapters/telegram.js +57 -49
- package/dist/channel/adapters/telegram.js.map +1 -1
- package/dist/channel/mcp-server.js +21 -4
- package/dist/channel/mcp-server.js.map +1 -1
- package/dist/channel/mcp-tools.d.ts +3 -1
- package/dist/channel/mcp-tools.js +41 -4
- package/dist/channel/mcp-tools.js.map +1 -1
- package/dist/channel/message-queue.js.map +1 -1
- package/dist/channel/sticker-download.js.map +1 -1
- package/dist/channel/tool-router.js.map +1 -1
- package/dist/child-process.d.ts +21 -0
- package/dist/child-process.js +54 -0
- package/dist/child-process.js.map +1 -0
- package/dist/classic-channel-manager.js +3 -2
- package/dist/classic-channel-manager.js.map +1 -1
- package/dist/cli-entry.js.map +1 -1
- package/dist/cli-flags.js.map +1 -1
- package/dist/cli.d.ts +1 -0
- package/dist/cli.js +448 -313
- package/dist/cli.js.map +1 -1
- package/dist/command-table.d.ts +1 -1
- package/dist/command-table.js +1 -1
- package/dist/command-table.js.map +1 -1
- package/dist/compact-watch.js.map +1 -1
- package/dist/completion-install.js.map +1 -1
- package/dist/completion.js.map +1 -1
- package/dist/config-validator.d.ts +6 -0
- package/dist/config-validator.js +81 -8
- package/dist/config-validator.js.map +1 -1
- package/dist/config.d.ts +15 -3
- package/dist/config.js +41 -10
- package/dist/config.js.map +1 -1
- package/dist/connection-secrets.js.map +1 -1
- package/dist/context-guardian.js.map +1 -1
- package/dist/coredump-filter.js.map +1 -1
- package/dist/cpu-profile.js.map +1 -1
- package/dist/cross-instance-envelope.js.map +1 -1
- package/dist/cross-instance-notice.d.ts +7 -0
- package/dist/cross-instance-notice.js +10 -0
- package/dist/cross-instance-notice.js.map +1 -1
- package/dist/daemon.d.ts +52 -1
- package/dist/daemon.js +385 -27
- package/dist/daemon.js.map +1 -1
- package/dist/daily-summary.js.map +1 -1
- package/dist/darwin-memory.js +1 -1
- package/dist/darwin-memory.js.map +1 -1
- package/dist/dashboard-live.d.ts +8 -0
- package/dist/dashboard-live.js +35 -0
- package/dist/dashboard-live.js.map +1 -0
- package/dist/dashboard-permissions.d.ts +69 -0
- package/dist/dashboard-permissions.js +138 -0
- package/dist/dashboard-permissions.js.map +1 -0
- package/dist/decision-list.js.map +1 -1
- package/dist/delivery-consumed-watch.js.map +1 -1
- package/dist/delivery-outbox.d.ts +11 -0
- package/dist/delivery-outbox.js +52 -2
- package/dist/delivery-outbox.js.map +1 -1
- package/dist/delivery-outbox.test.js.map +1 -1
- package/dist/delivery-reconciliation.test.js.map +1 -1
- package/dist/diagnostic-redaction.d.ts +10 -0
- package/dist/diagnostic-redaction.js +167 -0
- package/dist/diagnostic-redaction.js.map +1 -0
- package/dist/doctor.d.ts +8 -0
- package/dist/doctor.js +52 -0
- package/dist/doctor.js.map +1 -1
- package/dist/e2e-isolation.js.map +1 -1
- package/dist/event-log.js.map +1 -1
- package/dist/export-import.js +7 -5
- package/dist/export-import.js.map +1 -1
- package/dist/fleet-context.d.ts +1 -1
- package/dist/fleet-control-audit.js.map +1 -1
- package/dist/fleet-label.js.map +1 -1
- package/dist/fleet-level-config.d.ts +1 -1
- package/dist/fleet-level-config.js +2 -0
- package/dist/fleet-level-config.js.map +1 -1
- package/dist/fleet-lock.d.ts +6 -0
- package/dist/fleet-lock.js +22 -2
- package/dist/fleet-lock.js.map +1 -1
- package/dist/fleet-manager.d.ts +283 -15
- package/dist/fleet-manager.js +1825 -331
- package/dist/fleet-manager.js.map +1 -1
- package/dist/fleet-process-handlers.d.ts +18 -0
- package/dist/fleet-process-handlers.js +70 -0
- package/dist/fleet-process-handlers.js.map +1 -0
- package/dist/fleet-startup.d.ts +14 -0
- package/dist/fleet-startup.js +30 -0
- package/dist/fleet-startup.js.map +1 -0
- package/dist/fleet-traffic.js.map +1 -1
- package/dist/forged-envelope-scan.d.ts +0 -20
- package/dist/forged-envelope-scan.js +3 -2
- package/dist/forged-envelope-scan.js.map +1 -1
- package/dist/full-restart.d.ts +5 -5
- package/dist/full-restart.js +5 -5
- package/dist/full-restart.js.map +1 -1
- package/dist/general-knowledge/skills/bug-report/SKILL.md +31 -0
- package/dist/general-knowledge/skills/credential-profiles/SKILL.md +52 -11
- package/dist/general-knowledge/skills/cross-instance-messaging/SKILL.md +5 -1
- package/dist/general-knowledge/skills/fleet-config/SKILL.md +3 -1
- package/dist/general-knowledge/skills/fleet-restart/SKILL.md +8 -9
- package/dist/general-knowledge/skills/instance-lifecycle/SKILL.md +11 -0
- package/dist/general-knowledge/skills/multi-channel/SKILL.md +1 -1
- package/dist/general-knowledge/skills/persona-emoji/SKILL.md +1 -1
- package/dist/general-knowledge/skills/scheduling/SKILL.md +4 -0
- package/dist/general-knowledge/skills/web-appearance/SKILL.canvas-worker-off.md +321 -0
- package/dist/general-knowledge/skills/web-appearance/SKILL.md +24 -4
- package/dist/general-knowledge/skills/web-dashboard/SKILL.canvas-worker-off.md +554 -0
- package/dist/general-knowledge/skills/web-dashboard/SKILL.md +156 -32
- package/dist/general-knowledge/skills/worker-collaboration/SKILL.md +1 -1
- package/dist/general-knowledge/steering/core-rules.md +1 -1
- package/dist/host-memory.js.map +1 -1
- package/dist/idle-gate-log.d.ts +19 -0
- package/dist/idle-gate-log.js +15 -0
- package/dist/idle-gate-log.js.map +1 -0
- package/dist/instance-config-impact.js +25 -4
- package/dist/instance-config-impact.js.map +1 -1
- package/dist/instance-lifecycle.d.ts +11 -1
- package/dist/instance-lifecycle.js +97 -25
- package/dist/instance-lifecycle.js.map +1 -1
- package/dist/instructions.d.ts +12 -6
- package/dist/instructions.js +19 -10
- package/dist/instructions.js.map +1 -1
- package/dist/kiro-compact-pane.js.map +1 -1
- package/dist/kiro-db-reader.js.map +1 -1
- package/dist/kiro-engine-status.js.map +1 -1
- package/dist/kiro-log-gate.js.map +1 -1
- package/dist/kiro-transcript-lane.js.map +1 -1
- package/dist/locale.js +450 -20
- package/dist/locale.js.map +1 -1
- package/dist/log-service.js +1 -0
- package/dist/log-service.js.map +1 -1
- package/dist/log-steps.d.ts +1 -0
- package/dist/log-steps.js +15 -0
- package/dist/log-steps.js.map +1 -1
- package/dist/logger.js +3 -2
- package/dist/logger.js.map +1 -1
- package/dist/login-controller.d.ts +45 -0
- package/dist/login-controller.js +101 -5
- package/dist/login-controller.js.map +1 -1
- package/dist/login-flows.js +1 -1
- package/dist/login-manager.js.map +1 -1
- package/dist/login-shell.js +3 -1
- package/dist/login-shell.js.map +1 -1
- package/dist/ls-attach-resolve.d.ts +96 -0
- package/dist/ls-attach-resolve.js +180 -0
- package/dist/ls-attach-resolve.js.map +1 -0
- package/dist/ls-rows.d.ts +12 -0
- package/dist/ls-rows.js +83 -4
- package/dist/ls-rows.js.map +1 -1
- package/dist/memory-pressure.js.map +1 -1
- package/dist/muse-usage-relay.js.map +1 -1
- package/dist/needs-you-hub.d.ts +98 -1
- package/dist/needs-you-hub.js +313 -44
- package/dist/needs-you-hub.js.map +1 -1
- package/dist/needs-you-live.d.ts +5 -2
- package/dist/needs-you-live.js +6 -3
- package/dist/needs-you-live.js.map +1 -1
- package/dist/needs-you.d.ts +68 -3
- package/dist/needs-you.js +39 -4
- package/dist/needs-you.js.map +1 -1
- package/dist/network-family.js.map +1 -1
- package/dist/operator-control-paths.js +3 -4
- package/dist/operator-control-paths.js.map +1 -1
- package/dist/outbound-handlers.d.ts +5 -2
- package/dist/outbound-handlers.js +81 -24
- package/dist/outbound-handlers.js.map +1 -1
- package/dist/outbound-schemas.d.ts +106 -60
- package/dist/outbound-schemas.js +33 -10
- package/dist/outbound-schemas.js.map +1 -1
- package/dist/outbox-open-error.js.map +1 -1
- package/dist/pane-context-cache.js.map +1 -1
- package/dist/paths.js.map +1 -1
- package/dist/private-dir.js.map +1 -1
- package/dist/probe-worker-pool.js.map +1 -1
- package/dist/profile-control.js.map +1 -1
- package/dist/prompt-file-ref.js.map +1 -1
- package/dist/provider-probe.js.map +1 -1
- package/dist/provider-secret-registry.d.ts +5 -3
- package/dist/provider-secret-registry.js +8 -2
- package/dist/provider-secret-registry.js.map +1 -1
- package/dist/public-link-auto-open.d.ts +32 -0
- package/dist/public-link-auto-open.js +86 -0
- package/dist/public-link-auto-open.js.map +1 -0
- package/dist/public-link-owner.d.ts +10 -0
- package/dist/public-link-owner.js +36 -0
- package/dist/public-link-owner.js.map +1 -0
- package/dist/public-link-progress.d.ts +12 -1
- package/dist/public-link-progress.js +5 -10
- package/dist/public-link-progress.js.map +1 -1
- package/dist/public-preview.js.map +1 -1
- package/dist/public-tunnel-config.d.ts +11 -0
- package/dist/public-tunnel-config.js +68 -0
- package/dist/public-tunnel-config.js.map +1 -0
- package/dist/public-web-gateway.d.ts +2 -0
- package/dist/public-web-gateway.js +19 -6
- package/dist/public-web-gateway.js.map +1 -1
- package/dist/public-web-link.d.ts +48 -3
- package/dist/public-web-link.js +177 -51
- package/dist/public-web-link.js.map +1 -1
- package/dist/quickstart-api.d.ts +9 -0
- package/dist/quickstart-api.js +82 -0
- package/dist/quickstart-api.js.map +1 -1
- package/dist/quickstart.d.ts +5 -0
- package/dist/quickstart.js +40 -25
- package/dist/quickstart.js.map +1 -1
- package/dist/reply-buttons-controller.js.map +1 -1
- package/dist/reply-dedup.js.map +1 -1
- package/dist/resource-report.js +1 -1
- package/dist/resource-report.js.map +1 -1
- package/dist/restart-guard.js.map +1 -1
- package/dist/restart-progress.d.ts +80 -1
- package/dist/restart-progress.js +306 -21
- package/dist/restart-progress.js.map +1 -1
- package/dist/rollout-index.js.map +1 -1
- package/dist/runtime-cpu-profile.js.map +1 -1
- package/dist/scheduler/db.d.ts +40 -13
- package/dist/scheduler/db.js +123 -89
- package/dist/scheduler/db.js.map +1 -1
- package/dist/scheduler/scheduler.js.map +1 -1
- package/dist/scheduler/task-board-text.d.ts +26 -0
- package/dist/scheduler/task-board-text.js +140 -0
- package/dist/scheduler/task-board-text.js.map +1 -0
- package/dist/scheduler/task-board.d.ts +730 -0
- package/dist/scheduler/task-board.js +2179 -0
- package/dist/scheduler/task-board.js.map +1 -0
- package/dist/scheduler/types.d.ts +6 -1
- package/dist/sd-notify.js +2 -1
- package/dist/sd-notify.js.map +1 -1
- package/dist/search/search-docs.d.ts +58 -0
- package/dist/search/search-docs.js +63 -0
- package/dist/search/search-docs.js.map +1 -0
- package/dist/search/search-index.d.ts +149 -0
- package/dist/search/search-index.js +453 -0
- package/dist/search/search-index.js.map +1 -0
- package/dist/search/search-store.d.ts +122 -0
- package/dist/search/search-store.js +236 -0
- package/dist/search/search-store.js.map +1 -0
- package/dist/search/search-worker.d.ts +1 -0
- package/dist/search/search-worker.js +163 -0
- package/dist/search/search-worker.js.map +1 -0
- package/dist/secret-file.js.map +1 -1
- package/dist/secret-store.d.ts +2 -0
- package/dist/secret-store.js +21 -0
- package/dist/secret-store.js.map +1 -1
- package/dist/service-installer.d.ts +98 -1
- package/dist/service-installer.js +246 -11
- package/dist/service-installer.js.map +1 -1
- package/dist/service-owner.d.ts +44 -0
- package/dist/service-owner.js +48 -0
- package/dist/service-owner.js.map +1 -0
- package/dist/service-plan.d.ts +39 -2
- package/dist/service-plan.js +188 -6
- package/dist/service-plan.js.map +1 -1
- package/dist/session-oom-stop.d.ts +45 -0
- package/dist/session-oom-stop.js +259 -0
- package/dist/session-oom-stop.js.map +1 -0
- package/dist/session-oom.d.ts +34 -0
- package/dist/session-oom.js +251 -0
- package/dist/session-oom.js.map +1 -0
- package/dist/settings-api.d.ts +14 -1
- package/dist/settings-api.js +74 -13
- package/dist/settings-api.js.map +1 -1
- package/dist/settings-baseline.js.map +1 -1
- package/dist/settings-change.d.ts +5 -0
- package/dist/settings-change.js +167 -6
- package/dist/settings-change.js.map +1 -1
- package/dist/settings-confirmation.d.ts +9 -1
- package/dist/settings-confirmation.js +18 -8
- package/dist/settings-confirmation.js.map +1 -1
- package/dist/settings-control.js +2 -1
- package/dist/settings-control.js.map +1 -1
- package/dist/settings-effect.js +29 -4
- package/dist/settings-effect.js.map +1 -1
- package/dist/settings-http-confirmation.d.ts +13 -0
- package/dist/settings-http-confirmation.js +15 -3
- package/dist/settings-http-confirmation.js.map +1 -1
- package/dist/settings-instance-patch.js +13 -1
- package/dist/settings-instance-patch.js.map +1 -1
- package/dist/settings-request-capability.d.ts +4 -1
- package/dist/settings-request-capability.js +11 -3
- package/dist/settings-request-capability.js.map +1 -1
- package/dist/settings-transaction.js.map +1 -1
- package/dist/setup-auth.d.ts +1 -0
- package/dist/setup-auth.js +2 -1
- package/dist/setup-auth.js.map +1 -1
- package/dist/setup-form.d.ts +1 -1
- package/dist/setup-form.js +23 -7
- package/dist/setup-form.js.map +1 -1
- package/dist/setup-host.d.ts +6 -1
- package/dist/setup-host.js +15 -4
- package/dist/setup-host.js.map +1 -1
- package/dist/setup-wizard.js +6 -3
- package/dist/setup-wizard.js.map +1 -1
- package/dist/spawn-gate.d.ts +7 -0
- package/dist/spawn-gate.js +45 -12
- package/dist/spawn-gate.js.map +1 -1
- package/dist/start-attempt.d.ts +11 -0
- package/dist/start-attempt.js +29 -0
- package/dist/start-attempt.js.map +1 -0
- package/dist/start-failure-chat.d.ts +37 -0
- package/dist/start-failure-chat.js +142 -0
- package/dist/start-failure-chat.js.map +1 -0
- package/dist/start-failure-notice.d.ts +4 -0
- package/dist/start-failure-notice.js +20 -0
- package/dist/start-failure-notice.js.map +1 -0
- package/dist/start-failure.d.ts +171 -0
- package/dist/start-failure.js +348 -0
- package/dist/start-failure.js.map +1 -0
- package/dist/startup-memory-deadline.d.ts +23 -0
- package/dist/startup-memory-deadline.js +55 -0
- package/dist/startup-memory-deadline.js.map +1 -0
- package/dist/statusline-watcher.js.map +1 -1
- package/dist/storm-window.js.map +1 -1
- package/dist/systemd-peer-bus.js.map +1 -1
- package/dist/target-queue-worker.js.map +1 -1
- package/dist/task-board-summary.d.ts +101 -0
- package/dist/task-board-summary.js +177 -0
- package/dist/task-board-summary.js.map +1 -0
- package/dist/task-board-tool.d.ts +25 -0
- package/dist/task-board-tool.js +155 -0
- package/dist/task-board-tool.js.map +1 -0
- package/dist/task-board-waker.d.ts +51 -0
- package/dist/task-board-waker.js +141 -0
- package/dist/task-board-waker.js.map +1 -0
- package/dist/telegram-api-root.d.ts +1 -0
- package/dist/telegram-api-root.js +40 -0
- package/dist/telegram-api-root.js.map +1 -0
- package/dist/tips.js.map +1 -1
- package/dist/tmux-control.js +1 -1
- package/dist/tmux-control.js.map +1 -1
- package/dist/tmux-exec-helper.d.ts +104 -0
- package/dist/tmux-exec-helper.js +412 -0
- package/dist/tmux-exec-helper.js.map +1 -0
- package/dist/tmux-manager.d.ts +1 -0
- package/dist/tmux-manager.js +29 -13
- package/dist/tmux-manager.js.map +1 -1
- package/dist/tmux-read.js +2 -2
- package/dist/tmux-read.js.map +1 -1
- package/dist/tool-permissions.js.map +1 -1
- package/dist/tool-progress.js.map +1 -1
- package/dist/topic-archiver.js.map +1 -1
- package/dist/topic-commands.d.ts +13 -0
- package/dist/topic-commands.js +56 -33
- package/dist/topic-commands.js.map +1 -1
- package/dist/topic-link.js.map +1 -1
- package/dist/transcript-delta-reader.js.map +1 -1
- package/dist/transcript-jsonl.js.map +1 -1
- package/dist/transcript-monitor.js +5 -0
- package/dist/transcript-monitor.js.map +1 -1
- package/dist/transcript-sources.d.ts +2 -0
- package/dist/transcript-sources.js +4 -0
- package/dist/transcript-sources.js.map +1 -1
- package/dist/tunnel/cloudflared-install.js +3 -1
- package/dist/tunnel/cloudflared-install.js.map +1 -1
- package/dist/tunnel/cloudflared.d.ts +7 -16
- package/dist/tunnel/cloudflared.js +100 -13
- package/dist/tunnel/cloudflared.js.map +1 -1
- package/dist/tunnel/lease.js +3 -2
- package/dist/tunnel/lease.js.map +1 -1
- package/dist/tunnel/manager.js.map +1 -1
- package/dist/tunnel/named-diagnostics.d.ts +13 -0
- package/dist/tunnel/named-diagnostics.js +52 -0
- package/dist/tunnel/named-diagnostics.js.map +1 -0
- package/dist/tunnel/public-fetch.js.map +1 -1
- package/dist/tunnel/purpose-lane.js.map +1 -1
- package/dist/tunnel/types.d.ts +4 -1
- package/dist/tunnel/types.js.map +1 -1
- package/dist/types.d.ts +56 -2
- package/dist/ui/app-effects.js +23 -5
- package/dist/ui/app.html +2 -0
- package/dist/ui/backend-signin.js +297 -0
- package/dist/ui/chat-effects.js +10 -3
- package/dist/ui/chat-msg-actions.js +176 -0
- package/dist/ui/chat-render.js +62 -18
- package/dist/ui/chat-store.js +218 -48
- package/dist/ui/chat-strings.js +40 -8
- package/dist/ui/chat-thread.js +119 -10
- package/dist/ui/effect-trial-offer.js +2 -31
- package/dist/ui/effects-waker.js +2 -0
- package/dist/ui/fleet-canvas-layout.js +13 -4
- package/dist/ui/fleet-canvas.js +69 -28
- package/dist/ui/fleet-office-editor.js +149 -0
- package/dist/ui/fleet-office-model.js +358 -0
- package/dist/ui/fleet-office-pack.js +199 -0
- package/dist/ui/fleet-office-skin.js +474 -0
- package/dist/ui/fleet-office-store.js +49 -0
- package/dist/ui/fleet-office-zones.js +177 -0
- package/dist/ui/fleet-office.js +434 -0
- package/dist/ui/fleet-org.js +18 -5
- package/dist/ui/fleet-route-scene.js +272 -0
- package/dist/ui/fleet-route-worker.js +21 -0
- package/dist/ui/fleet-route.js +88 -0
- package/dist/ui/fleet-task-card.js +436 -0
- package/dist/ui/fleet-task-common.js +482 -0
- package/dist/ui/fleet-task-work.js +107 -0
- package/dist/ui/fleet-tasks.js +569 -0
- package/dist/ui/fleet-traffic.js +81 -18
- package/dist/ui/fleet-usage.js +36 -2
- package/dist/ui/guest-refused.html +41 -0
- package/dist/ui/icons/icon-192.png +0 -0
- package/dist/ui/icons/icon-512.png +0 -0
- package/dist/ui/image-lightbox.js +45 -1
- package/dist/ui/image-zoom.js +242 -0
- package/dist/ui/panel-chat.js +214 -57
- package/dist/ui/panel-details.js +2 -0
- package/dist/ui/panel-fleet.js +32 -71
- package/dist/ui/panel-log.js +3 -3
- package/dist/ui/panel-needs.js +23 -6
- package/dist/ui/panel-settings.js +166 -33
- package/dist/ui/preview-panel.js +2 -1
- package/dist/ui/search-dialog.js +350 -0
- package/dist/ui/settings-appearance.js +170 -10
- package/dist/ui/settings-apply.js +3 -3
- package/dist/ui/settings-confirm.js +7 -2
- package/dist/ui/settings-dialogs.js +46 -21
- package/dist/ui/settings-discord.js +6 -2
- package/dist/ui/settings-guests.js +2 -1
- package/dist/ui/settings-learn.js +1 -0
- package/dist/ui/settings-model.js +51 -18
- package/dist/ui/settings-mods.js +8 -3
- package/dist/ui/settings-owner-effects.js +6 -4
- package/dist/ui/settings-strings.js +186 -6
- package/dist/ui/settings-token.js +3 -1
- package/dist/ui/settings-web-authority.js +13 -5
- package/dist/ui/settings-wizard.js +13 -7
- package/dist/ui/shared/agend-auth.js +2 -0
- package/dist/ui/shared/app-i18n.js +12 -5
- package/dist/ui/shared/app-needs.js +2 -2
- package/dist/ui/shared/app-prefs.js +15 -0
- package/dist/ui/shared/app-route.js +18 -0
- package/dist/ui/shared/app-shell.js +189 -28
- package/dist/ui/shared/app-store.js +3 -2
- package/dist/ui/shared/app-stream.js +5 -1
- package/dist/ui/shared/app-themes.js +116 -1
- package/dist/ui/shared/app.css +668 -48
- package/dist/ui/shared/app.js +9 -1
- package/dist/ui/shared/card-strings.js +4 -0
- package/dist/ui/shared/effect-app-runtime.js +7 -5
- package/dist/ui/shared/effect-chat-runtime.js +2 -7
- package/dist/ui/shared/effect-cursor.js +3 -2
- package/dist/ui/shared/effect-display-metadata.js +39 -0
- package/dist/ui/shared/effect-owner-source.js +8 -1
- package/dist/ui/shared/effect-registry.js +14 -4
- package/dist/ui/shared/effect-runtime-loader.js +3 -1
- package/dist/ui/shared/effect-stock-trust.js +5 -5
- package/dist/ui/shared/feature-flags.js +127 -0
- package/dist/ui/shared/guest-refused.js +35 -0
- package/dist/ui/shared/header-tools.js +2 -2
- package/dist/ui/shared/identity-card.js +26 -8
- package/dist/ui/shared/identity-color.js +17 -10
- package/dist/ui/shared/instance-nav.js +183 -28
- package/dist/ui/shared/owner-css.js +30 -1
- package/dist/ui/shared/panel-view.js +14 -29
- package/dist/ui/shared/text-undo.js +210 -0
- package/dist/ui/shared/tokens.css +4 -0
- package/dist/ui/shared/ui-dialog.js +5 -4
- package/dist/ui/shared/ui-icons.js +4 -0
- package/dist/ui/shared/ui-menu.js +20 -7
- package/dist/ui/shared/ui-toast.js +16 -3
- package/dist/ui/shared/usage-dialog.js +216 -16
- package/dist/ui/shared/view-strings.js +70 -4
- package/dist/ui/shared/web-authorize.js +50 -1
- package/dist/ui/signin.html +2 -0
- package/dist/ui/web-terminal/terminal.html +10 -10
- package/dist/ui/web-terminal/terminal.js +58 -12
- package/dist/update-check.js.map +1 -1
- package/dist/update-dispatch.js +1 -1
- package/dist/update-dispatch.js.map +1 -1
- package/dist/update-install.js.map +1 -1
- package/dist/update-launch.d.ts +10 -1
- package/dist/update-launch.js +39 -14
- package/dist/update-launch.js.map +1 -1
- package/dist/update-marker.js.map +1 -1
- package/dist/update-preflight.js +1 -1
- package/dist/update-preflight.js.map +1 -1
- package/dist/update-progress.d.ts +3 -1
- package/dist/update-progress.js +3 -1
- package/dist/update-progress.js.map +1 -1
- package/dist/usage/format-rich.js +6 -3
- package/dist/usage/format-rich.js.map +1 -1
- package/dist/usage/i18n-keys.d.ts +1 -1
- package/dist/usage/i18n-keys.js +2 -1
- package/dist/usage/i18n-keys.js.map +1 -1
- package/dist/usage/i18n.d.ts +13 -1
- package/dist/usage/i18n.js +29 -0
- package/dist/usage/i18n.js.map +1 -1
- package/dist/usage/providers.d.ts +89 -2
- package/dist/usage/providers.js +247 -41
- package/dist/usage/providers.js.map +1 -1
- package/dist/usage/statusline-usage.js.map +1 -1
- package/dist/usage/usage-api.d.ts +5 -1
- package/dist/usage/usage-api.js +185 -58
- package/dist/usage/usage-api.js.map +1 -1
- package/dist/usage-report.js.map +1 -1
- package/dist/usage-rollup.js +1 -1
- package/dist/usage-rollup.js.map +1 -1
- package/dist/user-systemd.d.ts +24 -0
- package/dist/user-systemd.js +75 -0
- package/dist/user-systemd.js.map +1 -0
- package/dist/view-api.d.ts +7 -0
- package/dist/view-api.js +16 -4
- package/dist/view-api.js.map +1 -1
- package/dist/wake-coordinator.js.map +1 -1
- package/dist/web-ambient.js.map +1 -1
- package/dist/web-api.d.ts +58 -11
- package/dist/web-api.js +1104 -71
- package/dist/web-api.js.map +1 -1
- package/dist/web-app-icon-worker.d.ts +1 -0
- package/dist/web-app-icon-worker.js +16 -0
- package/dist/web-app-icon-worker.js.map +1 -0
- package/dist/web-app-icon.d.ts +109 -0
- package/dist/web-app-icon.js +257 -0
- package/dist/web-app-icon.js.map +1 -0
- package/dist/web-appearance-policy.js.map +1 -1
- package/dist/web-appearance-tools.d.ts +1 -0
- package/dist/web-appearance-tools.js +7 -3
- package/dist/web-appearance-tools.js.map +1 -1
- package/dist/web-appearance-view.js.map +1 -1
- package/dist/web-appearance.d.ts +4 -10
- package/dist/web-appearance.js +7 -4
- package/dist/web-appearance.js.map +1 -1
- package/dist/web-auth.d.ts +8 -4
- package/dist/web-auth.js +33 -21
- package/dist/web-auth.js.map +1 -1
- package/dist/web-backend-login.d.ts +130 -0
- package/dist/web-backend-login.js +225 -0
- package/dist/web-backend-login.js.map +1 -0
- package/dist/web-card.js.map +1 -1
- package/dist/web-channel-echo.js.map +1 -1
- package/dist/web-chat-history.d.ts +118 -8
- package/dist/web-chat-history.js +220 -25
- package/dist/web-chat-history.js.map +1 -1
- package/dist/web-commands.d.ts +5 -1
- package/dist/web-commands.js +1 -1
- package/dist/web-commands.js.map +1 -1
- package/dist/web-cookie-names.d.ts +5 -0
- package/dist/web-cookie-names.js +12 -0
- package/dist/web-cookie-names.js.map +1 -0
- package/dist/web-effect-bundle.d.ts +2 -2
- package/dist/web-effect-library.js.map +1 -1
- package/dist/web-effect-playback.js.map +1 -1
- package/dist/web-effect-profiles.d.ts +16 -16
- package/dist/web-effect-profiles.js +3 -2
- package/dist/web-effect-profiles.js.map +1 -1
- package/dist/web-effect-service.js.map +1 -1
- package/dist/web-effect-tools.js.map +1 -1
- package/dist/web-effect-trials.js.map +1 -1
- package/dist/web-effect-upload.js.map +1 -1
- package/dist/web-effect.d.ts +6 -6
- package/dist/web-effect.js.map +1 -1
- package/dist/web-experimental-http.d.ts +2 -0
- package/dist/web-experimental-http.js +12 -0
- package/dist/web-experimental-http.js.map +1 -0
- package/dist/web-experimental.d.ts +11 -0
- package/dist/web-experimental.js +49 -0
- package/dist/web-experimental.js.map +1 -0
- package/dist/web-guest-access.d.ts +4 -2
- package/dist/web-guest-access.js +22 -10
- package/dist/web-guest-access.js.map +1 -1
- package/dist/web-guest-rooms.js.map +1 -1
- package/dist/web-host-guard.d.ts +11 -0
- package/dist/web-host-guard.js +11 -0
- package/dist/web-host-guard.js.map +1 -1
- package/dist/web-icons.d.ts +33 -1
- package/dist/web-icons.js +83 -11
- package/dist/web-icons.js.map +1 -1
- package/dist/web-identity-color.js.map +1 -1
- package/dist/web-image-meta.d.ts +13 -0
- package/dist/web-image-meta.js +62 -0
- package/dist/web-image-meta.js.map +1 -1
- package/dist/web-images.js.map +1 -1
- package/dist/web-libavoid.d.ts +14 -0
- package/dist/web-libavoid.js +46 -0
- package/dist/web-libavoid.js.map +1 -0
- package/dist/web-login.js.map +1 -1
- package/dist/web-mentions.js.map +1 -1
- package/dist/web-mod-agent.js.map +1 -1
- package/dist/web-mod-store.d.ts +2 -0
- package/dist/web-mod-store.js +10 -0
- package/dist/web-mod-store.js.map +1 -1
- package/dist/web-office-store.d.ts +104 -0
- package/dist/web-office-store.js +236 -0
- package/dist/web-office-store.js.map +1 -0
- package/dist/web-owner-css-store.d.ts +44 -1
- package/dist/web-owner-css-store.js +70 -9
- package/dist/web-owner-css-store.js.map +1 -1
- package/dist/web-owner-css.js.map +1 -1
- package/dist/web-png.d.ts +33 -0
- package/dist/web-png.js +329 -0
- package/dist/web-png.js.map +1 -0
- package/dist/web-prefs.d.ts +6 -0
- package/dist/web-prefs.js +29 -3
- package/dist/web-prefs.js.map +1 -1
- package/dist/web-preview.d.ts +2 -0
- package/dist/web-preview.js +2 -0
- package/dist/web-preview.js.map +1 -1
- package/dist/web-profile.js.map +1 -1
- package/dist/web-reactions.d.ts +35 -0
- package/dist/web-reactions.js +47 -0
- package/dist/web-reactions.js.map +1 -0
- package/dist/web-request-context.d.ts +5 -0
- package/dist/web-request-context.js.map +1 -1
- package/dist/web-returning-device.d.ts +4 -2
- package/dist/web-returning-device.js +13 -6
- package/dist/web-returning-device.js.map +1 -1
- package/dist/web-schedules.js.map +1 -1
- package/dist/web-send-dedupe.d.ts +36 -0
- package/dist/web-send-dedupe.js +69 -0
- package/dist/web-send-dedupe.js.map +1 -0
- package/dist/web-session-authorization.js.map +1 -1
- package/dist/web-session.js +1 -1
- package/dist/web-session.js.map +1 -1
- package/dist/web-settings-patch.d.ts +3 -1
- package/dist/web-settings-patch.js +11 -5
- package/dist/web-settings-patch.js.map +1 -1
- package/dist/web-settings-tools.d.ts +6 -0
- package/dist/web-settings-tools.js +52 -17
- package/dist/web-settings-tools.js.map +1 -1
- package/dist/web-terminal-http.js +15 -2
- package/dist/web-terminal-http.js.map +1 -1
- package/dist/web-terminal.js +1 -1
- package/dist/web-terminal.js.map +1 -1
- package/dist/web-theme-store.d.ts +2 -2
- package/dist/web-theme-store.js +6 -3
- package/dist/web-theme-store.js.map +1 -1
- package/dist/web-theme.d.ts +29 -0
- package/dist/web-theme.js +89 -1
- package/dist/web-theme.js.map +1 -1
- package/dist/web-upload.d.ts +18 -1
- package/dist/web-upload.js +45 -7
- package/dist/web-upload.js.map +1 -1
- package/dist/web-widget.js.map +1 -1
- package/dist/webhook-emitter.js.map +1 -1
- package/dist/windows-shortcuts.d.ts +78 -0
- package/dist/windows-shortcuts.js +203 -0
- package/dist/windows-shortcuts.js.map +1 -0
- package/dist/workflow-templates/default.md +3 -0
- package/dist/working-state-journal.d.ts +68 -0
- package/dist/working-state-journal.js +93 -0
- package/dist/working-state-journal.js.map +1 -0
- package/dist/ws-server.js.map +1 -1
- package/dist/yaml-shared-nodes.d.ts +25 -0
- package/dist/yaml-shared-nodes.js +185 -0
- package/dist/yaml-shared-nodes.js.map +1 -0
- package/launcher/agend-install.cjs +828 -0
- package/launcher/install-admission.cjs +4 -39
- package/launcher/postinstall.cjs +14 -12
- package/launcher/private-home.cjs +43 -0
- package/package.json +16 -13
- package/scripts/preinstall-guard.cjs +2 -5
- package/templates/windows-shortcuts.ps1 +181 -0
- package/launcher/old-updater-note.cjs +0 -48
package/dist/daemon.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { agentWhatsNew, agendVersion, planWhatsNew, readWhatsNewRecord, recordWhatsNew, whatsNewNotice } from "./agent-whats-new.js";
|
|
2
2
|
import { join, dirname, resolve } from "node:path";
|
|
3
3
|
import { checkoutTarget, readCheckouts, releaseCandidate, reposRoot, verifyWorktree, writeCheckouts } from "./repo-worktree-guard.js";
|
|
4
4
|
import { mkdirSync, writeFileSync, readFileSync, readdirSync, existsSync, unlinkSync, rmSync, appendFileSync, statSync, renameSync } from "node:fs";
|
|
@@ -10,6 +10,8 @@ import { createHash, randomBytes, randomUUID } from "node:crypto";
|
|
|
10
10
|
import { EventEmitter } from "node:events";
|
|
11
11
|
import { rotateLogIfNeededAsync } from "./logger.js";
|
|
12
12
|
import { coredumpFilterLaunchPrefix } from "./coredump-filter.js";
|
|
13
|
+
import { observeCliOomIdentity, confirmedCliOom, consecutiveSessionOoms, describeSelfOom } from "./session-oom.js";
|
|
14
|
+
import { assertNoSessionOomStop, readSessionOomStop, writeSessionOomStop, SessionOomStoppedError, sessionOomStopHint } from "./session-oom-stop.js";
|
|
13
15
|
import { mcpServerState } from "./mcp-liveness.js";
|
|
14
16
|
import { clearPausedMarker, writePausedMarker } from "./pause-marker.js";
|
|
15
17
|
import { writeBackgroundWorkEndedMarker } from "./background-work-ended.js";
|
|
@@ -19,7 +21,9 @@ import { createTranscriptSource } from "./transcript-sources.js";
|
|
|
19
21
|
import { TranscriptTurnLedger } from "./transcript-turns.js";
|
|
20
22
|
import { credentialProfileStoreHome, resolveCredentialProfile } from "./backend/credential-profile.js";
|
|
21
23
|
import { resolveToolSet } from "./tool-permissions.js";
|
|
24
|
+
import { dashboardAccessProblem, dashboardFeaturesOff } from "./dashboard-permissions.js";
|
|
22
25
|
import { getAgendHome } from "./paths.js";
|
|
26
|
+
import { readCanvasWorkerEnabled, scopedFleetConfigEnvironment } from "./web-experimental.js";
|
|
23
27
|
import { readAgentEffect, sendEffectInParts } from "./web-effect-upload.js";
|
|
24
28
|
import { readAgentFile } from "./agent-file-read.js";
|
|
25
29
|
import { ASSET_UPLOAD_MAX_BYTES, MOD_FILE, MOD_MAX_PARTS, MOD_UPLOAD_MAX_BYTES, receiveFiles, receivePreview, sendAssetInParts, writeModFile, writePreview } from "./web-asset-parts.js";
|
|
@@ -53,7 +57,9 @@ import { measureSyncWork, noteSyncWork } from "./sync-work-attribution.js";
|
|
|
53
57
|
import { TranscriptDeltaReader } from "./transcript-delta-reader.js";
|
|
54
58
|
import { buildResumeContinuation, clearInFlightTurnMarker, consumeInFlightTurnMarker, decideTurnResume, normalizeResumeBackend, readResumeFingerprint, RESUME_BLOCKING_DELIVERY_STATES, writeInFlightTurnMarker, } from "./turn-resume.js";
|
|
55
59
|
import { codexLiveRowMatches } from "./backend/codex.js";
|
|
60
|
+
import { codexPackageProblemMessage } from "./backend/codex-package.js";
|
|
56
61
|
import { claudeConfigDirFor, claudeProfileConfigDir, claudeSwitchDialog, claudeSwitchTargetMatches } from "./backend/claude-code.js";
|
|
62
|
+
import { MuseBackend } from "./backend/muse.js";
|
|
57
63
|
import { InteractionObservation, INTERACTION_CONFIRM_MS, sameInteractionOwner } from "./interaction-observation.js";
|
|
58
64
|
import { unrecognisedPromptShape } from "./unrecognised-prompt.js";
|
|
59
65
|
/** #2140: deliveries that may carry an unwritten what's-new notice before it is recorded anyway. */
|
|
@@ -1157,6 +1163,37 @@ export class Daemon extends EventEmitter {
|
|
|
1157
1163
|
// injected by FleetManager below.
|
|
1158
1164
|
healthCheckTimer = null;
|
|
1159
1165
|
crashCount = 0;
|
|
1166
|
+
cliOomObservation = null;
|
|
1167
|
+
consecutiveOoms = null;
|
|
1168
|
+
collateralOomRecovery = false;
|
|
1169
|
+
unclearOomStopped = false;
|
|
1170
|
+
sessionOomStopUnpersisted = false;
|
|
1171
|
+
assertSessionOomAdmission() {
|
|
1172
|
+
if (this.sessionOomStopUnpersisted)
|
|
1173
|
+
throw new SessionOomStoppedError(false, { blocked: true, record: null, revision: null, confirmedOom: true });
|
|
1174
|
+
assertNoSessionOomStop(this.instanceDir);
|
|
1175
|
+
}
|
|
1176
|
+
isSessionOomStopped() {
|
|
1177
|
+
return this.sessionOomStopUnpersisted || readSessionOomStop(this.instanceDir).blocked;
|
|
1178
|
+
}
|
|
1179
|
+
isUnclearOomStopped() {
|
|
1180
|
+
return this.unclearOomStopped && this.healthCheckPaused && this.processStatus === "crashed";
|
|
1181
|
+
}
|
|
1182
|
+
stopUnclearOom(exitCode) {
|
|
1183
|
+
this.unclearOomStopped = true;
|
|
1184
|
+
this.healthCheckPaused = true;
|
|
1185
|
+
this.emitSupervisionEnded(t("inst.oom_unclear_stopped"), t("inst.session_oom_remedy"), exitCode, "oom_unclear");
|
|
1186
|
+
}
|
|
1187
|
+
oomSessionKey() {
|
|
1188
|
+
// Claude's per-instance statusline owns its ID. Other current getters
|
|
1189
|
+
// either return null or select by cwd (Muse/Grok): those are not proof
|
|
1190
|
+
// of this pane's session and must not trigger this destructive decision.
|
|
1191
|
+
if ((this.config.backend ?? "claude-code") !== "claude-code")
|
|
1192
|
+
return null;
|
|
1193
|
+
const session = this.backend?.getSessionId?.();
|
|
1194
|
+
return typeof session === "string" && session.trim() && session.length <= 512
|
|
1195
|
+
? JSON.stringify([this.config.backend ?? "claude-code", session.trim()]) : null;
|
|
1196
|
+
}
|
|
1160
1197
|
lastCrashAt = 0;
|
|
1161
1198
|
lastSpawnAt = 0;
|
|
1162
1199
|
crashTimestamps = [];
|
|
@@ -1565,6 +1602,7 @@ export class Daemon extends EventEmitter {
|
|
|
1565
1602
|
windowQueryFailureTicks = 0;
|
|
1566
1603
|
mcpRestartPending = false;
|
|
1567
1604
|
mcpRestartStaleTimer = null;
|
|
1605
|
+
mcpRestartCooldownTimer = null;
|
|
1568
1606
|
/** In-flight replacement grace; also the guard against three triggers stacking. */
|
|
1569
1607
|
mcpRestartGraceTimer = null;
|
|
1570
1608
|
/**
|
|
@@ -1601,6 +1639,20 @@ export class Daemon extends EventEmitter {
|
|
|
1601
1639
|
get isErrorState() {
|
|
1602
1640
|
return this.errorWaitingForRecovery || (this.healthCheckPaused && !this.isPaused) || this.stormWindow?.isActive() === true;
|
|
1603
1641
|
}
|
|
1642
|
+
/**
|
|
1643
|
+
* #2327: which of isErrorState's conditions holds, so a warning names the one actually observed. A CLI no longer
|
|
1644
|
+
* supervised outranks a tmux recovery, which outranks a detected error pattern — one match is enough for that last
|
|
1645
|
+
* one, so it proves neither a pause nor a repetition.
|
|
1646
|
+
*/
|
|
1647
|
+
get errorStateCause() {
|
|
1648
|
+
if (this.healthCheckPaused && !this.isPaused)
|
|
1649
|
+
return "unsupervised";
|
|
1650
|
+
if (this.stormWindow?.isActive() === true)
|
|
1651
|
+
return "tmux_recovering";
|
|
1652
|
+
if (this.errorWaitingForRecovery)
|
|
1653
|
+
return "error_detected";
|
|
1654
|
+
return null;
|
|
1655
|
+
}
|
|
1604
1656
|
get isPaused() { return this.pauseWakeState !== "active"; }
|
|
1605
1657
|
/** Current CLI process state for status surfaces and recovery commands. */
|
|
1606
1658
|
getProcessStatus() {
|
|
@@ -1779,6 +1831,12 @@ export class Daemon extends EventEmitter {
|
|
|
1779
1831
|
model: config.model ?? "default",
|
|
1780
1832
|
};
|
|
1781
1833
|
this.logger = rootLogger.child({ instance: name }, { level: config.log_level });
|
|
1834
|
+
if (backend instanceof MuseBackend) {
|
|
1835
|
+
const log = this.logger;
|
|
1836
|
+
backend.setPlaceholderDebug((rec) => {
|
|
1837
|
+
log.debug(rec, "muse empty-composer placeholder classified as empty");
|
|
1838
|
+
});
|
|
1839
|
+
}
|
|
1782
1840
|
this.tmuxSessionName = getTmuxSession();
|
|
1783
1841
|
this.messageBus = new MessageBus();
|
|
1784
1842
|
this.messageBus.setLogger(this.logger);
|
|
@@ -1791,7 +1849,10 @@ export class Daemon extends EventEmitter {
|
|
|
1791
1849
|
// finished turn can never resume after a later restart. reset() is
|
|
1792
1850
|
// deliberately NOT hooked: stop/spawn abandon the in-memory turn while
|
|
1793
1851
|
// the on-disk interruption must survive for the resume gate.
|
|
1794
|
-
this.turnReplyGuard.onComplete = () =>
|
|
1852
|
+
this.turnReplyGuard.onComplete = () => {
|
|
1853
|
+
clearInFlightTurnMarker(this.instanceDir);
|
|
1854
|
+
this.publishWorkingState("turn_closed");
|
|
1855
|
+
};
|
|
1795
1856
|
}
|
|
1796
1857
|
/** FleetManager and this daemon share a process, so durable begin/ACK is a direct synchronous store call. */
|
|
1797
1858
|
setDeliveryOutboxPort(port) {
|
|
@@ -2086,6 +2147,11 @@ export class Daemon extends EventEmitter {
|
|
|
2086
2147
|
* daemon's own state only; it never inspects the pane itself.
|
|
2087
2148
|
*/
|
|
2088
2149
|
notAcceptingReason() {
|
|
2150
|
+
if (this.sessionOomStopUnpersisted)
|
|
2151
|
+
return t("inst.session_oom_hold");
|
|
2152
|
+
const oomStop = readSessionOomStop(this.instanceDir);
|
|
2153
|
+
if (oomStop.blocked)
|
|
2154
|
+
return sessionOomStopHint(oomStop);
|
|
2089
2155
|
if (this.pauseWakeState !== "active")
|
|
2090
2156
|
return t("delivery.hold_state", this.pauseWakeState);
|
|
2091
2157
|
if (this.inputBlockedDialogKey !== null)
|
|
@@ -2136,6 +2202,7 @@ export class Daemon extends EventEmitter {
|
|
|
2136
2202
|
}
|
|
2137
2203
|
}
|
|
2138
2204
|
async startAdmitted() {
|
|
2205
|
+
this.assertSessionOomAdmission();
|
|
2139
2206
|
ensureInstanceDir(this.instanceDir);
|
|
2140
2207
|
writeFileSync(join(this.instanceDir, "daemon.pid"), String(process.pid));
|
|
2141
2208
|
this.logger.info(`Starting ${this.name}`);
|
|
@@ -2356,6 +2423,7 @@ export class Daemon extends EventEmitter {
|
|
|
2356
2423
|
ackIfPending();
|
|
2357
2424
|
this.recordRecentEvent({ type: "assistant_text", preview: text.slice(0, 100) });
|
|
2358
2425
|
});
|
|
2426
|
+
this.transcriptMonitor.on("codex_package_missing_host", (root) => this.noteCodexPackageMissingHost(root));
|
|
2359
2427
|
this.transcriptMonitor.startPolling();
|
|
2360
2428
|
// HangDetector is the notification bridge to the fleet manager; pane state
|
|
2361
2429
|
// transitions below are the sole source of hang events (see hang-detector.ts).
|
|
@@ -2583,6 +2651,24 @@ export class Daemon extends EventEmitter {
|
|
|
2583
2651
|
this.fireMcpRestartRequest("already_idle");
|
|
2584
2652
|
}
|
|
2585
2653
|
}
|
|
2654
|
+
/** Keep a cooldown-suppressed revival alive without bypassing the idle gate. */
|
|
2655
|
+
deferMcpRestart(delayMs) {
|
|
2656
|
+
this.clearMcpRestartRequest();
|
|
2657
|
+
if (this.config.mcp_auto_restart === false || this.authFailureUnresolved
|
|
2658
|
+
|| this.mcpRestartCancelledByRecovery("cooldown"))
|
|
2659
|
+
return;
|
|
2660
|
+
this.mcpRestartPending = true;
|
|
2661
|
+
this.mcpRestartCooldownTimer = setTimeout(() => {
|
|
2662
|
+
this.mcpRestartCooldownTimer = null;
|
|
2663
|
+
if (this.mcpRestartCancelledByRecovery("cooldown_expired"))
|
|
2664
|
+
return;
|
|
2665
|
+
this.clearMcpRestartRequest();
|
|
2666
|
+
if (this.config.mcp_auto_restart === false || this.authFailureUnresolved || this.mcpServerAlive().alive)
|
|
2667
|
+
return;
|
|
2668
|
+
this.armMcpRestartWhenIdle();
|
|
2669
|
+
}, Math.max(0, delayMs));
|
|
2670
|
+
this.mcpRestartCooldownTimer.unref?.();
|
|
2671
|
+
}
|
|
2586
2672
|
/**
|
|
2587
2673
|
* Single chokepoint for all three revival triggers (already_idle, idle_edge,
|
|
2588
2674
|
* stale_timeout) — and therefore the one place worth re-checking reality.
|
|
@@ -2600,6 +2686,8 @@ export class Daemon extends EventEmitter {
|
|
|
2600
2686
|
fireMcpRestartRequest(trigger) {
|
|
2601
2687
|
if (this.mcpRestartCancelledByRecovery(trigger))
|
|
2602
2688
|
return;
|
|
2689
|
+
if (this.mcpRestartCooldownTimer)
|
|
2690
|
+
return;
|
|
2603
2691
|
// Authoritative re-read — the CLI may have replaced the server since the
|
|
2604
2692
|
// health tick that armed this.
|
|
2605
2693
|
if (this.mcpServerAlive().alive) {
|
|
@@ -2794,6 +2882,10 @@ export class Daemon extends EventEmitter {
|
|
|
2794
2882
|
}
|
|
2795
2883
|
clearMcpRestartRequest() {
|
|
2796
2884
|
this.mcpRestartPending = false;
|
|
2885
|
+
if (this.mcpRestartCooldownTimer) {
|
|
2886
|
+
clearTimeout(this.mcpRestartCooldownTimer);
|
|
2887
|
+
this.mcpRestartCooldownTimer = null;
|
|
2888
|
+
}
|
|
2797
2889
|
if (this.mcpRestartStaleTimer) {
|
|
2798
2890
|
clearTimeout(this.mcpRestartStaleTimer);
|
|
2799
2891
|
this.mcpRestartStaleTimer = null;
|
|
@@ -2862,6 +2954,19 @@ export class Daemon extends EventEmitter {
|
|
|
2862
2954
|
if (discardStaleHealth())
|
|
2863
2955
|
return;
|
|
2864
2956
|
if (paneStatus?.alive) {
|
|
2957
|
+
// Capture only a known primary while it lives. No extra tmux call: PID comes
|
|
2958
|
+
// from this same status read. Fast/unobserved deaths remain ordinary crashes.
|
|
2959
|
+
const key = this.oomSessionKey();
|
|
2960
|
+
if (this.cliOomObservation?.key !== key)
|
|
2961
|
+
this.cliOomObservation = null;
|
|
2962
|
+
if (paneStatus.pid && key && !this.cliOomObservation) {
|
|
2963
|
+
const identity = await observeCliOomIdentity(paneStatus.pid, cliLabel);
|
|
2964
|
+
if (discardStaleHealth())
|
|
2965
|
+
return;
|
|
2966
|
+
if (identity && this.oomSessionKey() === key) {
|
|
2967
|
+
this.cliOomObservation = { identity, key, owner: healthOwner, tmux: healthTmux };
|
|
2968
|
+
}
|
|
2969
|
+
}
|
|
2865
2970
|
this.windowQueryFailureTicks = 0;
|
|
2866
2971
|
this.stormWindow?.noteWindowAlive(this.name);
|
|
2867
2972
|
// Instance output.log is fed by tmux pipe-pane and was previously never
|
|
@@ -3016,6 +3121,47 @@ export class Daemon extends EventEmitter {
|
|
|
3016
3121
|
return;
|
|
3017
3122
|
this.setProcessStatus("crashed");
|
|
3018
3123
|
this.logPaneDeath(cliLabel, exitCode, lastOutput);
|
|
3124
|
+
const observed = this.cliOomObservation;
|
|
3125
|
+
const key = this.oomSessionKey();
|
|
3126
|
+
const oom = paneStatus && exitCode === 137 && observed && observed.key === key
|
|
3127
|
+
&& observed.tmux === healthTmux && sameInteractionOwner(observed.owner, healthOwner)
|
|
3128
|
+
? await confirmedCliOom(observed.identity, Date.now()) : null;
|
|
3129
|
+
if (discardStaleHealth())
|
|
3130
|
+
return;
|
|
3131
|
+
this.cliOomObservation = null;
|
|
3132
|
+
const decisionKey = this.oomSessionKey();
|
|
3133
|
+
this.consecutiveOoms = consecutiveSessionOoms(this.consecutiveOoms, decisionKey, decisionKey === key && oom?.attribution === "self");
|
|
3134
|
+
const collateralOom = oom?.attribution === "collateral";
|
|
3135
|
+
if (collateralOom)
|
|
3136
|
+
this.logger.warn({ attribution: oom.attribution, pid: oom.pid }, "OOM victim without self-caused proof — preserving session; waiting for memory recovery");
|
|
3137
|
+
if (this.consecutiveOoms && this.consecutiveOoms.count >= 2) {
|
|
3138
|
+
// Stop supervision, not an idle pause: queued work must not auto-wake
|
|
3139
|
+
// the same session. An explicit restart is the person's retry choice.
|
|
3140
|
+
// No await after the final captured health owner/session check. The
|
|
3141
|
+
// stop is authoritative before observers can see supervision end.
|
|
3142
|
+
try {
|
|
3143
|
+
writeSessionOomStop(this.instanceDir, { owner: healthOwner, sessionKey: decisionKey,
|
|
3144
|
+
configuration: this.getWorkingStateObservation().configuration, stoppedAt: Date.now(),
|
|
3145
|
+
count: this.consecutiveOoms.count, victim: { pid: oom.pid, at: oom.at }, evidence: oom.evidence });
|
|
3146
|
+
}
|
|
3147
|
+
catch {
|
|
3148
|
+
// Storage failure cannot revive this CLI in the current process.
|
|
3149
|
+
// Say explicitly that a fleet restart cannot yet rely on durability.
|
|
3150
|
+
this.sessionOomStopUnpersisted = true;
|
|
3151
|
+
this.logger.error("Could not persist session OOM stop; fix storage before restarting the fleet");
|
|
3152
|
+
}
|
|
3153
|
+
this.healthCheckPaused = true;
|
|
3154
|
+
try {
|
|
3155
|
+
this.appendCrashHistory({ exitCode, lastOutput, crashType, reason: "session_oom", oomEvidence: oom.evidence });
|
|
3156
|
+
}
|
|
3157
|
+
catch (error) {
|
|
3158
|
+
this.logger.warn({ error }, "Could not append session OOM history");
|
|
3159
|
+
}
|
|
3160
|
+
this.logger.error({ pid: oom.pid, count: this.consecutiveOoms.count }, "Repeated confirmed CLI OOM — automatic resume stopped; session preserved");
|
|
3161
|
+
this.emitSupervisionEnded(`${t("inst.session_oom_stopped")} (${describeSelfOom(oom.evidence)})`, t("inst.session_oom_remedy")
|
|
3162
|
+
+ (this.sessionOomStopUnpersisted ? ` ${t("inst.session_oom_save_failed")}` : ""), exitCode, "session_oom");
|
|
3163
|
+
return;
|
|
3164
|
+
}
|
|
3019
3165
|
// Kill the dead window (remain-on-exit keeps it around) before respawn
|
|
3020
3166
|
if (paneStatus) {
|
|
3021
3167
|
await healthTmux.killWindow();
|
|
@@ -3023,7 +3169,7 @@ export class Daemon extends EventEmitter {
|
|
|
3023
3169
|
return;
|
|
3024
3170
|
}
|
|
3025
3171
|
// Detect claude-code background session conflict — recover without counting as crash
|
|
3026
|
-
if (lastOutput && (lastOutput.includes("background agent") || lastOutput.includes("Session is currently running"))) {
|
|
3172
|
+
if (!oom && lastOutput && (lastOutput.includes("background agent") || lastOutput.includes("Session is currently running"))) {
|
|
3027
3173
|
if (!this.backgroundSessionRecoveryAttempted) {
|
|
3028
3174
|
this.backgroundSessionRecoveryAttempted = true;
|
|
3029
3175
|
this.logger.warn("Detected lingering background agent session — starting fresh (no resume)");
|
|
@@ -3063,7 +3209,7 @@ export class Daemon extends EventEmitter {
|
|
|
3063
3209
|
// --continue again and crash in the same way → loop. Clear the session id
|
|
3064
3210
|
// and skip resume so the next spawn starts fresh. (skipResume also stops
|
|
3065
3211
|
// saveSessionId below from resurrecting the id from statusline.json.)
|
|
3066
|
-
if (this.paneSaysNoConversation(lastOutput)) {
|
|
3212
|
+
if (!oom && this.paneSaysNoConversation(lastOutput)) {
|
|
3067
3213
|
this.setSessionAside("cli_reported_no_conversation");
|
|
3068
3214
|
this.skipResume = true;
|
|
3069
3215
|
}
|
|
@@ -3084,12 +3230,21 @@ export class Daemon extends EventEmitter {
|
|
|
3084
3230
|
return;
|
|
3085
3231
|
}
|
|
3086
3232
|
// Detect rapid crash: sliding window — 3+ crashes in 5 minutes
|
|
3087
|
-
|
|
3233
|
+
if (!collateralOom)
|
|
3234
|
+
this.crashTimestamps.push(Date.now());
|
|
3235
|
+
else
|
|
3236
|
+
this.crashTimestamps = [];
|
|
3088
3237
|
const crashWindowMs = 5 * 60_000;
|
|
3089
3238
|
this.crashTimestamps = this.crashTimestamps.filter(t => t > Date.now() - crashWindowMs);
|
|
3090
3239
|
if (this.crashTimestamps.length >= 3) {
|
|
3091
3240
|
this.healthCheckPaused = true;
|
|
3092
3241
|
this.logger.error({ crashesInWindow: this.crashTimestamps.length, lastExitCode: exitCode ?? null, lastOutput: paneTail(lastOutput) ?? null }, "3+ crashes in 5 minutes — pausing respawn");
|
|
3242
|
+
// Unknown cause is bounded like an ordinary crash, never a
|
|
3243
|
+
// self-OOM verdict. Preserve the session for the person's choice.
|
|
3244
|
+
if (oom?.attribution === "unknown") {
|
|
3245
|
+
this.stopUnclearOom(exitCode);
|
|
3246
|
+
return;
|
|
3247
|
+
}
|
|
3093
3248
|
// P1: Persist crash state so next process restart skips resume
|
|
3094
3249
|
try {
|
|
3095
3250
|
writeFileSync(join(this.instanceDir, "crash-state.json"), JSON.stringify({
|
|
@@ -3106,18 +3261,23 @@ export class Daemon extends EventEmitter {
|
|
|
3106
3261
|
if (reset_after > 0 && Date.now() - this.lastCrashAt > reset_after) {
|
|
3107
3262
|
this.crashCount = 0;
|
|
3108
3263
|
}
|
|
3109
|
-
|
|
3264
|
+
if (!collateralOom)
|
|
3265
|
+
this.crashCount++;
|
|
3110
3266
|
this.lastCrashAt = Date.now();
|
|
3111
|
-
if (this.crashCount > max_retries) {
|
|
3267
|
+
if (!collateralOom && this.crashCount > max_retries) {
|
|
3112
3268
|
this.logger.error({ crashCount: this.crashCount, maxRetries: max_retries, lastExitCode: exitCode ?? null, lastOutput: paneTail(lastOutput) ?? null }, "Max crash retries exceeded — not respawning");
|
|
3113
3269
|
this.healthCheckPaused = true;
|
|
3270
|
+
if (oom?.attribution === "unknown") {
|
|
3271
|
+
this.stopUnclearOom(exitCode);
|
|
3272
|
+
return;
|
|
3273
|
+
}
|
|
3114
3274
|
this.emitSupervisionEnded(`it crashed ${this.crashCount} times, exceeding restart_policy.max_retries (${max_retries})`, "Check the logs for the cause, then restart it.");
|
|
3115
3275
|
return; // don't schedule next — given up
|
|
3116
3276
|
}
|
|
3117
3277
|
// Calculate backoff delay
|
|
3118
3278
|
const delay = backoff === "exponential"
|
|
3119
|
-
? Math.min(1000 * Math.pow(2, this.crashCount - 1), 60_000)
|
|
3120
|
-
: 1000 * this.crashCount;
|
|
3279
|
+
? Math.min(1000 * Math.pow(2, Math.max(1, this.crashCount) - 1), 60_000)
|
|
3280
|
+
: 1000 * Math.max(1, this.crashCount);
|
|
3121
3281
|
this.logger.warn({ crashCount: this.crashCount, delay }, `${cliLabel} window died — respawning after backoff`);
|
|
3122
3282
|
await new Promise(r => setTimeout(r, delay));
|
|
3123
3283
|
try {
|
|
@@ -3126,14 +3286,14 @@ export class Daemon extends EventEmitter {
|
|
|
3126
3286
|
// (bounded) session lookup. They only stop LATER ticks; this continuation is already
|
|
3127
3287
|
// past that check and must not clear the process/window or respawn an instance that
|
|
3128
3288
|
// was just stopped or paused (#1160 review).
|
|
3129
|
-
if (
|
|
3289
|
+
if (discardStaleHealth())
|
|
3130
3290
|
return;
|
|
3131
3291
|
// Reset is synchronous for file sources, but Kiro's baseline is
|
|
3132
3292
|
// read off-thread. Finish it before starting the replacement CLI,
|
|
3133
3293
|
// otherwise its first work could become part of that baseline.
|
|
3134
3294
|
if (!await this.resetTranscriptBeforeAdmission())
|
|
3135
3295
|
return;
|
|
3136
|
-
if (
|
|
3296
|
+
if (discardStaleHealth())
|
|
3137
3297
|
return;
|
|
3138
3298
|
// Kill orphan MCP server from the crashed CLI session.
|
|
3139
3299
|
// MCP server writes its PID to channel.mcp.pid on startup.
|
|
@@ -3157,10 +3317,19 @@ export class Daemon extends EventEmitter {
|
|
|
3157
3317
|
}
|
|
3158
3318
|
}
|
|
3159
3319
|
catch { /* tmux server may be dead — ensureSession in trySpawn will recover */ }
|
|
3320
|
+
if (discardStaleHealth())
|
|
3321
|
+
return;
|
|
3160
3322
|
// Write snapshot before spawn — consumed only if resume fails
|
|
3161
3323
|
this.writeRotationSnapshot("crash");
|
|
3162
3324
|
// Try --resume first; spawnClaudeWindow falls back to fresh session if resume fails
|
|
3163
|
-
|
|
3325
|
+
this.collateralOomRecovery = collateralOom;
|
|
3326
|
+
let resumed;
|
|
3327
|
+
try {
|
|
3328
|
+
resumed = await this.spawnClaudeWindow();
|
|
3329
|
+
}
|
|
3330
|
+
finally {
|
|
3331
|
+
this.collateralOomRecovery = false;
|
|
3332
|
+
}
|
|
3164
3333
|
if (!resumed) {
|
|
3165
3334
|
// Resume failed → fresh session → inject snapshot for context
|
|
3166
3335
|
await this.injectSnapshotMessage();
|
|
@@ -3254,6 +3423,7 @@ export class Daemon extends EventEmitter {
|
|
|
3254
3423
|
* four, carrying a human-readable cause and the operator's next step.
|
|
3255
3424
|
*/
|
|
3256
3425
|
emitSupervisionEnded(reason, remedy, exitCode, cause) {
|
|
3426
|
+
this.publishWorkingState("supervision_ended");
|
|
3257
3427
|
this.emit("supervision_ended", {
|
|
3258
3428
|
name: this.name,
|
|
3259
3429
|
reason,
|
|
@@ -3266,6 +3436,7 @@ export class Daemon extends EventEmitter {
|
|
|
3266
3436
|
if (this.processStatus === status)
|
|
3267
3437
|
return;
|
|
3268
3438
|
this.processStatus = status;
|
|
3439
|
+
this.publishWorkingState("process");
|
|
3269
3440
|
if (status === "running") {
|
|
3270
3441
|
// A successful crash respawn is a new pane generation. It is ready by
|
|
3271
3442
|
// this point, so an error gate inherited from the dead pane must not keep
|
|
@@ -3651,6 +3822,17 @@ export class Daemon extends EventEmitter {
|
|
|
3651
3822
|
const key = Daemon.errorPatternKey(ep);
|
|
3652
3823
|
const count = countMatches(ep.pattern);
|
|
3653
3824
|
const seen = this.lastErrorCount.get(key) ?? 0;
|
|
3825
|
+
// #2282: a resumed exhausted429 row is history, not even a new
|
|
3826
|
+
// notification/failover incident. Wait for the first live composer to
|
|
3827
|
+
// establish its baseline; later appended occurrences remain eligible.
|
|
3828
|
+
if (ep.type === "rate_limit" && ep.action === "nudge_continue") {
|
|
3829
|
+
const baseline = this.nudgeBaselines?.get(key);
|
|
3830
|
+
if (baseline === undefined || count <= baseline) {
|
|
3831
|
+
if (baseline !== undefined)
|
|
3832
|
+
this.lastErrorCount.set(key, count);
|
|
3833
|
+
continue;
|
|
3834
|
+
}
|
|
3835
|
+
}
|
|
3654
3836
|
// The generic Codex usage-limit line remains in scrollback after the
|
|
3655
3837
|
// user selects Luna Reserve. What proves that is NOT a live composer —
|
|
3656
3838
|
// codex paints one after a plain hit too, and the old live-composer guard
|
|
@@ -3803,6 +3985,7 @@ export class Daemon extends EventEmitter {
|
|
|
3803
3985
|
this.deliveryEpoch = fleetEpoch === undefined
|
|
3804
3986
|
? this.deliveryEpoch + 1
|
|
3805
3987
|
: Math.max(this.deliveryEpoch, fleetEpoch);
|
|
3988
|
+
this.publishWorkingState("cancelled");
|
|
3806
3989
|
this.logger.info({ deliveryEpoch: this.deliveryEpoch }, "Pending delivery queue cleared by user cancel");
|
|
3807
3990
|
}
|
|
3808
3991
|
/** Board 907c7899: the layout a web /compact's end can be read from on this pane (kiro classic or TUI V2), or null. */
|
|
@@ -4371,6 +4554,7 @@ export class Daemon extends EventEmitter {
|
|
|
4371
4554
|
return true;
|
|
4372
4555
|
}
|
|
4373
4556
|
async stop() {
|
|
4557
|
+
this.publishWorkingState("before_stop");
|
|
4374
4558
|
this.logger.info("Stopping daemon instance");
|
|
4375
4559
|
this.clearQuitRelaunchWatch();
|
|
4376
4560
|
this.fenceDeliveryWritesForStop();
|
|
@@ -4519,6 +4703,31 @@ export class Daemon extends EventEmitter {
|
|
|
4519
4703
|
getInteractionSnapshot() {
|
|
4520
4704
|
return this.interactionObservation.snapshot(this.interactionOwner());
|
|
4521
4705
|
}
|
|
4706
|
+
workingTurnDelivery = null;
|
|
4707
|
+
workingBackgroundObservation = null;
|
|
4708
|
+
/** Pure metadata read: never discovers sessions, captures a pane or reads backend files. */
|
|
4709
|
+
getWorkingStateObservation() {
|
|
4710
|
+
const turn = this.turnReplyGuard.snapshot();
|
|
4711
|
+
const backend = this.config.backend ?? this.backend?.binaryName ?? "unknown";
|
|
4712
|
+
const profile = resolveCredentialProfile(this.config.backend_options?.[backend]);
|
|
4713
|
+
return {
|
|
4714
|
+
owner: this.interactionOwner(), backend,
|
|
4715
|
+
configuration: createHash("sha256").update(JSON.stringify([backend, this.config.working_directory, profile])).digest("hex"),
|
|
4716
|
+
executionState: this.processStatus === "running" ? this.isPaused ? "paused" : this.instanceState : null,
|
|
4717
|
+
processStatus: this.getProcessStatus(), sessionId: null, backendTurnId: null,
|
|
4718
|
+
backgroundWork: this.workingBackgroundObservation,
|
|
4719
|
+
turn: turn ? { generation: turn.generation,
|
|
4720
|
+
deliveryId: this.workingTurnDelivery?.generation === turn.generation ? this.workingTurnDelivery.deliveryId : null,
|
|
4721
|
+
correlationId: turn.target.correlationId ?? null, messageId: turn.target.messageId ?? null,
|
|
4722
|
+
cancelled: turn.cancelledByUser, completionDelivered: turn.completionDelivered } : null,
|
|
4723
|
+
};
|
|
4724
|
+
}
|
|
4725
|
+
publishWorkingState(reason) {
|
|
4726
|
+
try {
|
|
4727
|
+
this.emit("working_state", { reason, observation: this.getWorkingStateObservation() });
|
|
4728
|
+
}
|
|
4729
|
+
catch { /* Journal observers cannot change daemon behavior. */ }
|
|
4730
|
+
}
|
|
4522
4731
|
/** Key of the last interaction snapshot actually emitted + broadcast (#1219). */
|
|
4523
4732
|
lastPublishedInteractionKey = null;
|
|
4524
4733
|
publishInteraction() {
|
|
@@ -4677,7 +4886,9 @@ export class Daemon extends EventEmitter {
|
|
|
4677
4886
|
static AUTH_RECONFIRM_ROWS = 15;
|
|
4678
4887
|
/** Why the deferred pause was requested; what its marker records (Phase 2a). */
|
|
4679
4888
|
pendingPauseReason = "auth";
|
|
4680
|
-
async pause(reason = "operator") {
|
|
4889
|
+
async pause(reason = "operator", admission) {
|
|
4890
|
+
if (admission && !admission.current())
|
|
4891
|
+
return;
|
|
4681
4892
|
if (this.pauseWakeState === "paused")
|
|
4682
4893
|
return;
|
|
4683
4894
|
if (this.pauseWakeState === "pausing" || this.pauseWakeState === "waking") {
|
|
@@ -4685,6 +4896,8 @@ export class Daemon extends EventEmitter {
|
|
|
4685
4896
|
if (this.getPauseWakeState() !== "active")
|
|
4686
4897
|
return;
|
|
4687
4898
|
}
|
|
4899
|
+
if (admission && !admission.current())
|
|
4900
|
+
return;
|
|
4688
4901
|
// `pauseAllowStuck` is consumed here, not merely read: it authorises exactly
|
|
4689
4902
|
// one pause from a stuck pane (the auth-deferred one) and must never leak
|
|
4690
4903
|
// into an ordinary idle-timeout pause of a busy instance.
|
|
@@ -4704,7 +4917,7 @@ export class Daemon extends EventEmitter {
|
|
|
4704
4917
|
// this cycle while the backend reports background work; the next idle
|
|
4705
4918
|
// tick retries once the task ends. A pane-capture failure proceeds (the
|
|
4706
4919
|
// quit-menu handler below stays the backstop), never wedges unpaused.
|
|
4707
|
-
if (this.backend?.backgroundWorkRunning && this.tmux) {
|
|
4920
|
+
if ((admission || this.backend?.backgroundWorkRunning) && this.tmux) {
|
|
4708
4921
|
const tmux = this.tmux;
|
|
4709
4922
|
const windowId = tmux.getWindowId?.();
|
|
4710
4923
|
const generation = this.spawnGeneration;
|
|
@@ -4716,7 +4929,8 @@ export class Daemon extends EventEmitter {
|
|
|
4716
4929
|
// #1730 P2-2: the await yields — the pane read is only valid for the
|
|
4717
4930
|
// world it was taken from. Revalidate owner, phase, state and queue
|
|
4718
4931
|
// before acting on it; anything that moved defers this cycle.
|
|
4719
|
-
if (
|
|
4932
|
+
if ((admission && (!admission.current() || pane === null || !admission.accepts(pane)))
|
|
4933
|
+
|| this.tmux !== tmux
|
|
4720
4934
|
|| this.tmux?.getWindowId?.() !== windowId
|
|
4721
4935
|
|| this.spawnGeneration !== generation
|
|
4722
4936
|
|| this.getPauseWakeState() !== "active"
|
|
@@ -4766,6 +4980,7 @@ export class Daemon extends EventEmitter {
|
|
|
4766
4980
|
this.pauseWakeState = "paused";
|
|
4767
4981
|
this.autoPauseController.markPaused();
|
|
4768
4982
|
writePausedMarker(this.instanceDir, this.lastPausedAt ?? Date.now(), reason);
|
|
4983
|
+
this.publishWorkingState("execution");
|
|
4769
4984
|
this.logger.info({ pausedAt: this.lastPausedAt }, "Instance auto-paused");
|
|
4770
4985
|
this.ipcServer?.broadcast({
|
|
4771
4986
|
type: "instance_state", instanceName: this.name, state: "paused", pausedAt: this.lastPausedAt,
|
|
@@ -4791,6 +5006,7 @@ export class Daemon extends EventEmitter {
|
|
|
4791
5006
|
}
|
|
4792
5007
|
/** Respawn the CLI in the preserved window and block until its prompt is ready. */
|
|
4793
5008
|
async wake(timeoutMs = 30_000) {
|
|
5009
|
+
this.assertSessionOomAdmission();
|
|
4794
5010
|
// An explicit wake (e.g. after the user re-logs in) cancels a deferred
|
|
4795
5011
|
// auth pause — otherwise the instance would pause again the moment it idles.
|
|
4796
5012
|
this.pausePending = false;
|
|
@@ -4858,6 +5074,7 @@ export class Daemon extends EventEmitter {
|
|
|
4858
5074
|
this.clearErrorRecoveryGate();
|
|
4859
5075
|
clearPausedMarker(this.instanceDir);
|
|
4860
5076
|
this.resumeRuntimeMonitors();
|
|
5077
|
+
this.publishWorkingState("execution");
|
|
4861
5078
|
this.logger.info("Instance auto-woke");
|
|
4862
5079
|
this.ipcServer?.broadcast({
|
|
4863
5080
|
type: "instance_state", instanceName: this.name, state: this.instanceState, pausedAt: null,
|
|
@@ -4913,7 +5130,9 @@ export class Daemon extends EventEmitter {
|
|
|
4913
5130
|
this.logger.info({ notLogged: this.stateEdgesNotLogged }, "Instance execution state edges were not logged while it was flapping");
|
|
4914
5131
|
this.stateEdgesNotLogged = 0;
|
|
4915
5132
|
}
|
|
4916
|
-
|
|
5133
|
+
// #2482: idle ↔ working is every turn (40% of daemon.log): debug. Anything involving stuck stays INFO.
|
|
5134
|
+
const routine = previous !== "stuck" && snapshot.state !== "stuck";
|
|
5135
|
+
this.logger[routine ? "debug" : "info"](fields, "Instance execution state changed");
|
|
4917
5136
|
return;
|
|
4918
5137
|
}
|
|
4919
5138
|
if (this.stateEdgesNotLogged === 0) {
|
|
@@ -4957,6 +5176,17 @@ export class Daemon extends EventEmitter {
|
|
|
4957
5176
|
}
|
|
4958
5177
|
this.instanceState = snapshot.state;
|
|
4959
5178
|
this.acceptedInstanceSnapshot = { ...snapshot };
|
|
5179
|
+
// Reuse an already-captured pane and the backend's pure parser, never capture for the journal.
|
|
5180
|
+
if (typeof pane === "string" && this.backend?.backgroundWorkRunning) {
|
|
5181
|
+
try {
|
|
5182
|
+
const background = this.backend.backgroundWorkRunning(pane);
|
|
5183
|
+
if (background !== this.workingBackgroundObservation) {
|
|
5184
|
+
this.workingBackgroundObservation = background;
|
|
5185
|
+
this.publishWorkingState("background");
|
|
5186
|
+
}
|
|
5187
|
+
}
|
|
5188
|
+
catch { /* Observational parsing cannot change accepted execution state. */ }
|
|
5189
|
+
}
|
|
4960
5190
|
// OpenCode creates its session lazily on the first submitted message.
|
|
4961
5191
|
// Waiting until stop/pause to persist that id loses resume state when the
|
|
4962
5192
|
// fleet is SIGKILLed or the host reboots.
|
|
@@ -5001,6 +5231,7 @@ export class Daemon extends EventEmitter {
|
|
|
5001
5231
|
}
|
|
5002
5232
|
if (snapshot.state !== previous) {
|
|
5003
5233
|
this.logStateEdge(previous, snapshot);
|
|
5234
|
+
this.publishWorkingState("execution");
|
|
5004
5235
|
this.emit("instance_state", { name: this.name, ...snapshot });
|
|
5005
5236
|
this.ipcServer?.broadcast({ type: "instance_state", instanceName: this.name, ...snapshot });
|
|
5006
5237
|
if (snapshot.state === "stuck" && pane && this.instanceStateReadyPattern) {
|
|
@@ -5083,6 +5314,8 @@ export class Daemon extends EventEmitter {
|
|
|
5083
5314
|
deliveredText,
|
|
5084
5315
|
deliveredAt,
|
|
5085
5316
|
}, this.pendingWork.lastInboundTimestamp());
|
|
5317
|
+
this.workingTurnDelivery = { generation: this.turnReplyGuard.snapshot().generation, deliveryId: meta.delivery_id || null };
|
|
5318
|
+
this.publishWorkingState("turn_started");
|
|
5086
5319
|
// #1209: persist the in-flight turn with a seam checkpoint. A marker
|
|
5087
5320
|
// that survives a restart is an interrupted turn by construction —
|
|
5088
5321
|
// completion (via the guard's onComplete) and cancel paths delete it.
|
|
@@ -6353,6 +6586,15 @@ export class Daemon extends EventEmitter {
|
|
|
6353
6586
|
this.config.cross_instance_visibility = update.cross_instance_visibility;
|
|
6354
6587
|
else if (update.cross_instance_visibility === null)
|
|
6355
6588
|
delete this.config.cross_instance_visibility;
|
|
6589
|
+
if (Number.isInteger(update.board_cards_at_once) && update.board_cards_at_once >= 1)
|
|
6590
|
+
this.config.board_cards_at_once = update.board_cards_at_once;
|
|
6591
|
+
else if (update.board_cards_at_once === null)
|
|
6592
|
+
delete this.config.board_cards_at_once;
|
|
6593
|
+
// The fleet reads it at each tool call; kept current here for the next spawn's tool menu.
|
|
6594
|
+
if (update.dashboard && typeof update.dashboard === "object" && !dashboardAccessProblem(update.dashboard))
|
|
6595
|
+
this.config.dashboard = update.dashboard;
|
|
6596
|
+
else if (update.dashboard === null)
|
|
6597
|
+
delete this.config.dashboard;
|
|
6356
6598
|
if (["trace", "debug", "info", "warn", "error"].includes(String(update.log_level))) {
|
|
6357
6599
|
const level = update.log_level;
|
|
6358
6600
|
if (this.config.log_level !== level) {
|
|
@@ -7612,6 +7854,46 @@ export class Daemon extends EventEmitter {
|
|
|
7612
7854
|
this.logger.info({ delayMs }, "Model-capacity nudge armed");
|
|
7613
7855
|
return true;
|
|
7614
7856
|
}
|
|
7857
|
+
/**
|
|
7858
|
+
* Consume an exhausted nudge only if its failed turn still owns an empty,
|
|
7859
|
+
* idle pane. Unlike arming, this verifies all input/work gates before pause.
|
|
7860
|
+
* The returned owner survives pause's own monitor freeze (which advances the
|
|
7861
|
+
* launch fence), but never another spawn/launch, cancel, delivery or episode.
|
|
7862
|
+
*/
|
|
7863
|
+
async prepareCapacityNudgePause() {
|
|
7864
|
+
const nudge = this.capacityNudge, episode = this.lastErrorEpisode;
|
|
7865
|
+
const tmux = this.tmux, attempt = this.launchAttempt, boot = this.bootId;
|
|
7866
|
+
this.cancelCapacityNudge("retries exhausted");
|
|
7867
|
+
if (!nudge || !episode || !tmux)
|
|
7868
|
+
return null;
|
|
7869
|
+
const window = tmux.getWindowId?.();
|
|
7870
|
+
const current = () => this.tmux === tmux && tmux.getWindowId?.() === window
|
|
7871
|
+
&& boot === this.bootId && nudge.spawn === this.spawnGeneration && attempt === this.launchAttempt
|
|
7872
|
+
&& episode === this.lastErrorEpisode && this.isDeliveryEpochCurrent(nudge.epoch)
|
|
7873
|
+
&& !this.startupAborted && !this.spawning && !this.isPaused
|
|
7874
|
+
&& this.getProcessStatus() === "running" && this.instanceState === "idle" && this.pasteQueueDepth === 0;
|
|
7875
|
+
const accepts = (pane) => pane === nudge.pane && this.paneAuthoritativelyIdle(pane)
|
|
7876
|
+
&& this.backend?.isPeriodicRedrawIdlePane?.(pane) === true
|
|
7877
|
+
&& codexLiveRowMatches(pane, nudge.pattern) && !this.backend?.backgroundWorkRunning?.(pane);
|
|
7878
|
+
const revalidate = () => this.paneWriteLock.run(async () => {
|
|
7879
|
+
if (!current())
|
|
7880
|
+
return false;
|
|
7881
|
+
try {
|
|
7882
|
+
const pane = await tmux.capturePane();
|
|
7883
|
+
return current() && accepts(pane);
|
|
7884
|
+
}
|
|
7885
|
+
catch {
|
|
7886
|
+
return false;
|
|
7887
|
+
}
|
|
7888
|
+
});
|
|
7889
|
+
// Initial admission must also respect the captured monitor fence. Later
|
|
7890
|
+
// revalidation deliberately tolerates only pause's own fence advancement.
|
|
7891
|
+
if (nudge.fence !== this.launchFenceEpoch || this.healthCheckPaused || this.runtimeMonitorsFrozen)
|
|
7892
|
+
return null;
|
|
7893
|
+
if (!await revalidate() || nudge.fence !== this.launchFenceEpoch || this.healthCheckPaused || this.runtimeMonitorsFrozen)
|
|
7894
|
+
return null;
|
|
7895
|
+
return { current, accepts, revalidate };
|
|
7896
|
+
}
|
|
7615
7897
|
/** Drop an armed nudge (the user stopped / paused the instance, or the lifecycle gave up on it). */
|
|
7616
7898
|
cancelCapacityNudge(reason) {
|
|
7617
7899
|
if (!this.capacityNudge)
|
|
@@ -7954,6 +8236,21 @@ export class Daemon extends EventEmitter {
|
|
|
7954
8236
|
this.footerFallbackEpoch = null;
|
|
7955
8237
|
}
|
|
7956
8238
|
footerFallbackWarnedGeneration = null;
|
|
8239
|
+
/** #2357: the launch (spawn generation and attempt) the missing code-mode host was last reported for. */
|
|
8240
|
+
codexPackageNoticeEpoch = null;
|
|
8241
|
+
/**
|
|
8242
|
+
* #2357: codex recorded that a tool call could not start its code-mode host. Every tool call of a code-mode-only
|
|
8243
|
+
* account fails this way (AgEnD's reply too) while the pane shows only `⚠ N warnings · f2 to view`. Told once per
|
|
8244
|
+
* launch however often the model retries; the launch check (CodexBackend.buildCommand) may already have said so.
|
|
8245
|
+
*/
|
|
8246
|
+
noteCodexPackageMissingHost(root) {
|
|
8247
|
+
const epoch = `${this.spawnGeneration}:${this.launchAttempt}`;
|
|
8248
|
+
if (this.codexPackageNoticeEpoch === epoch)
|
|
8249
|
+
return;
|
|
8250
|
+
this.codexPackageNoticeEpoch = epoch;
|
|
8251
|
+
this.logger.warn({ root }, "Codex tool call failed: code-mode host missing");
|
|
8252
|
+
this.emit("backend_launch_warning", { name: this.name, message: codexPackageProblemMessage(root, { file: "bin/codex-code-mode-host", reason: "missing" }) });
|
|
8253
|
+
}
|
|
7957
8254
|
/**
|
|
7958
8255
|
* The input-row proof used before a paste (#931/#947), with one fallback
|
|
7959
8256
|
* (#1031). Codex sometimes paints an idle composer without its Context
|
|
@@ -9918,8 +10215,10 @@ export class Daemon extends EventEmitter {
|
|
|
9918
10215
|
// purposes even before the idle edge completes the guard. Without
|
|
9919
10216
|
// this, a restart in the reply-to-idle window would re-inject a
|
|
9920
10217
|
// continuation for an already-answered turn.
|
|
9921
|
-
if (replyAttempt?.completionAction)
|
|
10218
|
+
if (replyAttempt?.completionAction) {
|
|
9922
10219
|
clearInFlightTurnMarker(this.instanceDir);
|
|
10220
|
+
this.publishWorkingState("completion_delivered");
|
|
10221
|
+
}
|
|
9923
10222
|
// #1377: a confirmed completion action (reply/react/edit_message) ends
|
|
9924
10223
|
// the human-facing obligation immediately — the idle edge does not need
|
|
9925
10224
|
// to confirm it. Clear any pending confirmation window so a later
|
|
@@ -10414,7 +10713,11 @@ export class Daemon extends EventEmitter {
|
|
|
10414
10713
|
}
|
|
10415
10714
|
}
|
|
10416
10715
|
// ── MCP server env (dual-track: still passes env vars for MCP instructions fallback) ──
|
|
10716
|
+
const configEnvironment = scopedFleetConfigEnvironment(join(this.instanceDir, "..", ".."));
|
|
10417
10717
|
const mcpEnv = {
|
|
10718
|
+
// Empty values clear an unrelated reference inherited by the CLI or tmux server.
|
|
10719
|
+
AGEND_FLEET_DATA_DIR: configEnvironment.AGEND_FLEET_DATA_DIR ?? "",
|
|
10720
|
+
AGEND_FLEET_CONFIG_PATH: configEnvironment.AGEND_FLEET_CONFIG_PATH ?? "",
|
|
10418
10721
|
AGEND_SOCKET_PATH: sockPath,
|
|
10419
10722
|
AGEND_INSTANCE_NAME: this.name,
|
|
10420
10723
|
AGEND_WORKING_DIR: this.config.working_directory,
|
|
@@ -10437,6 +10740,11 @@ export class Daemon extends EventEmitter {
|
|
|
10437
10740
|
? resolveToolSet(this.config, this.name, "general")
|
|
10438
10741
|
: resolveToolSet(this.config, this.name);
|
|
10439
10742
|
mcpEnv.AGEND_TOOL_SET = toolSet;
|
|
10743
|
+
// The dashboard features the person switched off: out of the tool menu from this start (the fleet refuses them
|
|
10744
|
+
// at once, whatever the menu still shows).
|
|
10745
|
+
const dashboardOff = dashboardFeaturesOff(this.config.dashboard);
|
|
10746
|
+
if (dashboardOff.length)
|
|
10747
|
+
mcpEnv.AGEND_DASHBOARD_OFF = dashboardOff.join(",");
|
|
10440
10748
|
if (this.config.display_name)
|
|
10441
10749
|
mcpEnv.AGEND_DISPLAY_NAME = this.config.display_name;
|
|
10442
10750
|
if (this.config.description)
|
|
@@ -10469,6 +10777,7 @@ export class Daemon extends EventEmitter {
|
|
|
10469
10777
|
catch { /* fallback to empty */ }
|
|
10470
10778
|
instructions = buildFleetInstructions({
|
|
10471
10779
|
instanceName: this.name,
|
|
10780
|
+
taskBoard: !dashboardOff.includes("task_board"),
|
|
10472
10781
|
workingDirectory: this.config.working_directory,
|
|
10473
10782
|
runtimeIdentity: this.runtimeIdentity,
|
|
10474
10783
|
displayName: this.config.display_name,
|
|
@@ -10483,6 +10792,7 @@ export class Daemon extends EventEmitter {
|
|
|
10483
10792
|
else {
|
|
10484
10793
|
instructions = buildFleetInstructions({
|
|
10485
10794
|
instanceName: this.name,
|
|
10795
|
+
taskBoard: !dashboardOff.includes("task_board"),
|
|
10486
10796
|
workingDirectory: this.config.working_directory,
|
|
10487
10797
|
runtimeIdentity: this.runtimeIdentity,
|
|
10488
10798
|
displayName: this.config.display_name,
|
|
@@ -10571,6 +10881,9 @@ export class Daemon extends EventEmitter {
|
|
|
10571
10881
|
* into exactly the window this exists to close.
|
|
10572
10882
|
*/
|
|
10573
10883
|
beginSpawn() {
|
|
10884
|
+
this.unclearOomStopped = false;
|
|
10885
|
+
this.publishWorkingState("before_spawn");
|
|
10886
|
+
this.workingBackgroundObservation = null;
|
|
10574
10887
|
this.dialogAnswers = null;
|
|
10575
10888
|
this.capacityNudge = null;
|
|
10576
10889
|
this.lastErrorEpisode = null;
|
|
@@ -10585,6 +10898,7 @@ export class Daemon extends EventEmitter {
|
|
|
10585
10898
|
this.clearReplyGuardConfirm();
|
|
10586
10899
|
this.sawBlockedInput = false;
|
|
10587
10900
|
if (this.spawnDepth === 0) {
|
|
10901
|
+
this.cliOomObservation = null;
|
|
10588
10902
|
this.spawnGeneration++;
|
|
10589
10903
|
this.interactionObservation.reset(this.interactionOwner());
|
|
10590
10904
|
this.clearInteractionConfirmation();
|
|
@@ -10785,6 +11099,7 @@ export class Daemon extends EventEmitter {
|
|
|
10785
11099
|
catch { /* best effort */ }
|
|
10786
11100
|
}
|
|
10787
11101
|
async spawnClaudeWindow() {
|
|
11102
|
+
this.assertSessionOomAdmission();
|
|
10788
11103
|
this.beginSpawn();
|
|
10789
11104
|
let resumedSuccessfully = false;
|
|
10790
11105
|
try {
|
|
@@ -10888,6 +11203,10 @@ export class Daemon extends EventEmitter {
|
|
|
10888
11203
|
// is reachable again (a fresh prompt is local and proves nothing).
|
|
10889
11204
|
this.backendOutage?.clear(this.backendKey());
|
|
10890
11205
|
}
|
|
11206
|
+
// A pre-existing fresh fallback is not another resume of the old session.
|
|
11207
|
+
// Providers may not have rewritten their session reading yet.
|
|
11208
|
+
if (!resumedSuccessfully)
|
|
11209
|
+
this.consecutiveOoms = null;
|
|
10891
11210
|
this.lastSpawnAt = Date.now();
|
|
10892
11211
|
// #1217: whatever session this CLI writes from here on is this backend's.
|
|
10893
11212
|
this.recordSessionOwner();
|
|
@@ -11171,11 +11490,20 @@ export class Daemon extends EventEmitter {
|
|
|
11171
11490
|
* Returns true if CLI is ready, false if it failed or got stuck.
|
|
11172
11491
|
*/
|
|
11173
11492
|
async trySpawn(reuseWindow = false, startupTimeoutMs) {
|
|
11174
|
-
const
|
|
11493
|
+
const recoveryOwner = this.collateralOomRecovery ? this.interactionOwner() : null;
|
|
11494
|
+
const enter = () => {
|
|
11495
|
+
if (recoveryOwner && (!sameInteractionOwner(recoveryOwner, this.interactionOwner())
|
|
11496
|
+
|| this.startupAborted || this.deliveryWritesStopping || this.runtimeMonitorsFrozen || this.healthCheckPaused)) {
|
|
11497
|
+
throw new Error("OOM recovery cancelled: the instance was stopped, paused or replaced while memory was unavailable");
|
|
11498
|
+
}
|
|
11499
|
+
return this.trySpawnInsideGate(reuseWindow, startupTimeoutMs);
|
|
11500
|
+
};
|
|
11501
|
+
const ready = !this.spawnGate ? await enter() : await this.spawnGate.run({
|
|
11175
11502
|
instanceName: this.name,
|
|
11176
11503
|
workingDirectory: this.config.working_directory,
|
|
11177
11504
|
reason: reuseWindow ? "wake" : this.lastSpawnAt > 0 ? "recovery" : "startup",
|
|
11178
|
-
|
|
11505
|
+
requireNormalMemory: this.collateralOomRecovery,
|
|
11506
|
+
}, enter);
|
|
11179
11507
|
// #906: a resumed kiro conversation comes back as the agent it was saved under. Every launch path that reaches a
|
|
11180
11508
|
// ready CLI (start, recovery, wake) switches it to this instance's own agent here, while the spawn still holds
|
|
11181
11509
|
// deliveries — and outside the spawn gate, which it does not need.
|
|
@@ -11404,16 +11732,41 @@ export class Daemon extends EventEmitter {
|
|
|
11404
11732
|
this.pendingWhatsNew = null;
|
|
11405
11733
|
return null;
|
|
11406
11734
|
}
|
|
11407
|
-
|
|
11408
|
-
|
|
11409
|
-
|
|
11735
|
+
// Rebuild even when ids are unchanged: an experimental switch may have changed
|
|
11736
|
+
// while this delivery waited. Never paste the old enabled capability text.
|
|
11737
|
+
// #2163: rebuilt as planned — only the entries this instance's roles are told; the rest are recorded with them.
|
|
11738
|
+
const roles = this.whatsNewRoles();
|
|
11739
|
+
const shown = agentWhatsNew(readCanvasWorkerEnabled(join(this.instanceDir, "..", ".."))).filter(e => ids.includes(e.id) && (!e.audience || e.audience.some(r => roles.includes(r))));
|
|
11740
|
+
if (!shown.length) {
|
|
11741
|
+
this.pendingWhatsNew = null;
|
|
11742
|
+
try {
|
|
11743
|
+
recordWhatsNew(this.instanceDir, ids, pending.version);
|
|
11744
|
+
}
|
|
11745
|
+
catch (err) {
|
|
11746
|
+
this.logger.warn({ err }, "what's-new record not written — the notice may repeat once");
|
|
11747
|
+
}
|
|
11748
|
+
return null;
|
|
11749
|
+
}
|
|
11750
|
+
const narrowed = { notice: whatsNewNotice(pending.version, shown), ids, version: pending.version };
|
|
11410
11751
|
this.pendingWhatsNew = narrowed;
|
|
11411
11752
|
return narrowed;
|
|
11412
11753
|
}
|
|
11754
|
+
/**
|
|
11755
|
+
* #2163: who this instance is to the what's-new notices — a ClassicBot room's agent, General, or a fleet worker (with
|
|
11756
|
+
* `coordinator` too when its tool set is coordinator or full, the ones that carry get_/set_web_settings).
|
|
11757
|
+
*/
|
|
11758
|
+
whatsNewRoles() {
|
|
11759
|
+
if (this.runtimeIdentity?.kind === "classic")
|
|
11760
|
+
return ["classic"];
|
|
11761
|
+
if (this.config.general_topic === true || this.name === "general")
|
|
11762
|
+
return ["general"];
|
|
11763
|
+
const set = resolveToolSet(this.config, this.name);
|
|
11764
|
+
return set === "coordinator" || set === "full" ? ["worker", "coordinator"] : ["worker"];
|
|
11765
|
+
}
|
|
11413
11766
|
/** #1633: what this instance has not been told about its AgEnD version yet (see agent-whats-new.ts). */
|
|
11414
11767
|
prepareWhatsNew(fresh, version = agendVersion()) {
|
|
11415
11768
|
try {
|
|
11416
|
-
const plan = planWhatsNew({ record: readWhatsNewRecord(this.instanceDir), fresh, version });
|
|
11769
|
+
const plan = planWhatsNew({ record: readWhatsNewRecord(this.instanceDir), fresh, version, roles: this.whatsNewRoles(), canvasWorker: readCanvasWorkerEnabled(join(this.instanceDir, "..", "..")) });
|
|
11417
11770
|
if (!plan) {
|
|
11418
11771
|
this.pendingWhatsNew = null;
|
|
11419
11772
|
return;
|
|
@@ -11432,6 +11785,7 @@ export class Daemon extends EventEmitter {
|
|
|
11432
11785
|
}
|
|
11433
11786
|
}
|
|
11434
11787
|
async trySpawnInsideGate(reuseWindow = false, startupTimeoutMs) {
|
|
11788
|
+
this.assertSessionOomAdmission();
|
|
11435
11789
|
this.startupAdmission?.();
|
|
11436
11790
|
const launchFence = this.launchFenceEpoch;
|
|
11437
11791
|
const backendConfig = this.buildBackendConfig();
|
|
@@ -11480,6 +11834,7 @@ export class Daemon extends EventEmitter {
|
|
|
11480
11834
|
// Thrown, not `false`: a false verdict reads as "the CLI failed to start" and sends the startup path
|
|
11481
11835
|
// into its resume-retry / set-the-session-aside handling, for an instance somebody just stopped.
|
|
11482
11836
|
this.startupAdmission?.();
|
|
11837
|
+
this.assertSessionOomAdmission();
|
|
11483
11838
|
if (launchFence !== this.launchFenceEpoch)
|
|
11484
11839
|
throw new Error("Launch cancelled: the instance was stopped or paused while the launch was being prepared");
|
|
11485
11840
|
this.backend.writeConfig(backendConfig);
|
|
@@ -11505,7 +11860,8 @@ export class Daemon extends EventEmitter {
|
|
|
11505
11860
|
// AGEND_HOME points the child's agent-cli at the same data dir the daemon
|
|
11506
11861
|
// is using, so it can locate <instanceDir>/agent.token.
|
|
11507
11862
|
const agendHome = join(this.instanceDir, "..", "..");
|
|
11508
|
-
|
|
11863
|
+
const configEnvironment = scopedFleetConfigEnvironment(agendHome);
|
|
11864
|
+
let envPrefix = `TERM=xterm-256color AGEND_INSTANCE_NAME=${shellQuote(this.name)} AGEND_HOME=${shellQuote(agendHome)} AGEND_FLEET_DATA_DIR=${shellQuote(configEnvironment.AGEND_FLEET_DATA_DIR ?? "")} AGEND_FLEET_CONFIG_PATH=${shellQuote(configEnvironment.AGEND_FLEET_CONFIG_PATH ?? "")}`;
|
|
11509
11865
|
if (backendConfig.agentMode === "cli" && backendConfig.agentPort) {
|
|
11510
11866
|
envPrefix += ` AGEND_PORT=${backendConfig.agentPort}`;
|
|
11511
11867
|
}
|
|
@@ -11565,6 +11921,7 @@ export class Daemon extends EventEmitter {
|
|
|
11565
11921
|
}
|
|
11566
11922
|
this.startupAdmission?.();
|
|
11567
11923
|
let windowId;
|
|
11924
|
+
this.assertSessionOomAdmission();
|
|
11568
11925
|
if (reuseWindow) {
|
|
11569
11926
|
this.controlClient?.unregisterWindow(this.tmux.getWindowId());
|
|
11570
11927
|
await this.tmux.respawnWindow(cmd, resolvedCwd);
|
|
@@ -12199,6 +12556,7 @@ export class Daemon extends EventEmitter {
|
|
|
12199
12556
|
crashType: data.crashType,
|
|
12200
12557
|
exitCode: data.exitCode,
|
|
12201
12558
|
reason: data.reason,
|
|
12559
|
+
...(data.oomEvidence ? { oomEvidence: data.oomEvidence } : {}),
|
|
12202
12560
|
lastOutput: data.lastOutput,
|
|
12203
12561
|
crashCount: this.crashCount + 1,
|
|
12204
12562
|
crashesInWindow: this.crashTimestamps.length,
|
|
@@ -12228,7 +12586,7 @@ export class Daemon extends EventEmitter {
|
|
|
12228
12586
|
}
|
|
12229
12587
|
// ── Repo Checkout ─────────────────────────────────────────
|
|
12230
12588
|
async handleCheckoutRepo(args, respond) {
|
|
12231
|
-
const { execFile: execFileCb } = await import("
|
|
12589
|
+
const { execFile: execFileCb } = await import("./child-process.js");
|
|
12232
12590
|
const { promisify } = await import("node:util");
|
|
12233
12591
|
const execFileAsync = promisify(execFileCb);
|
|
12234
12592
|
const rawSource = args.source;
|
|
@@ -12264,7 +12622,7 @@ export class Daemon extends EventEmitter {
|
|
|
12264
12622
|
respond(null, `Not a git repository: ${source}`);
|
|
12265
12623
|
return;
|
|
12266
12624
|
}
|
|
12267
|
-
mkdirSync(join(this.instanceDir, "repos"), { recursive: true });
|
|
12625
|
+
mkdirSync(join(this.instanceDir, "repos"), { recursive: true, mode: 0o700 });
|
|
12268
12626
|
// Only a fresh direct child of a real repos/ directory (never through a symlinked repos/, never an existing path).
|
|
12269
12627
|
const target = checkoutTarget(this.instanceDir, source, branch);
|
|
12270
12628
|
if (!target.ok) {
|
|
@@ -12306,7 +12664,7 @@ export class Daemon extends EventEmitter {
|
|
|
12306
12664
|
respond(null, `Cannot release: ${root.reason}`);
|
|
12307
12665
|
return;
|
|
12308
12666
|
}
|
|
12309
|
-
const { execFile: execFileCb } = await import("
|
|
12667
|
+
const { execFile: execFileCb } = await import("./child-process.js");
|
|
12310
12668
|
const { promisify } = await import("node:util");
|
|
12311
12669
|
const execFileAsync = promisify(execFileCb);
|
|
12312
12670
|
const git = async (gitArgs, cwd) => (await execFileAsync("git", gitArgs, { cwd })).stdout;
|