agent-log-viewer 1.1.0 → 1.2.0
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/bin/cli.mjs +4 -0
- package/bin/server-runtime.test.ts +63 -12
- package/dist/mcp-server.mjs +31365 -26173
- package/dist/runtime-host.mjs +15618 -7081
- package/dist/standalone/.next/BUILD_ID +1 -1
- package/dist/standalone/.next/app-path-routes-manifest.json +21 -16
- package/dist/standalone/.next/build-manifest.json +3 -3
- package/dist/standalone/.next/prerender-manifest.json +4 -4
- package/dist/standalone/.next/react-loadable-manifest.json +1 -1
- package/dist/standalone/.next/required-server-files.json +1 -1
- package/dist/standalone/.next/routes-manifest.json +30 -0
- package/dist/standalone/.next/server/account-migration-controller-worker.js +1 -1
- package/dist/standalone/.next/server/app/_global-error/page.js +2 -2
- package/dist/standalone/.next/server/app/_global-error/page.js.nft.json +1 -1
- package/dist/standalone/.next/server/app/_global-error/page_client-reference-manifest.js +1 -1
- package/dist/standalone/.next/server/app/_global-error.html +1 -1
- package/dist/standalone/.next/server/app/_global-error.rsc +1 -1
- package/dist/standalone/.next/server/app/_global-error.segments/_full.segment.rsc +1 -1
- package/dist/standalone/.next/server/app/_global-error.segments/_global-error/__PAGE__.segment.rsc +1 -1
- package/dist/standalone/.next/server/app/_global-error.segments/_tree.segment.rsc +1 -1
- package/dist/standalone/.next/server/app/_not-found/page.js +1 -1
- package/dist/standalone/.next/server/app/_not-found/page.js.nft.json +1 -1
- package/dist/standalone/.next/server/app/_not-found/page_client-reference-manifest.js +1 -1
- package/dist/standalone/.next/server/app/_not-found.html +1 -1
- package/dist/standalone/.next/server/app/_not-found.rsc +2 -2
- package/dist/standalone/.next/server/app/_not-found.segments/_full.segment.rsc +2 -2
- package/dist/standalone/.next/server/app/_not-found.segments/_not-found/__PAGE__.segment.rsc +2 -2
- package/dist/standalone/.next/server/app/_not-found.segments/_tree.segment.rsc +2 -2
- package/dist/standalone/.next/server/app/api/access/route.js +1 -1
- package/dist/standalone/.next/server/app/api/access/route.js.nft.json +1 -1
- package/dist/standalone/.next/server/app/api/account-migrations/[intentId]/route.js +1 -1
- package/dist/standalone/.next/server/app/api/account-migrations/[intentId]/route.js.nft.json +1 -1
- package/dist/standalone/.next/server/app/api/account-project-bindings/route.js +1 -1
- package/dist/standalone/.next/server/app/api/account-project-bindings/route.js.nft.json +1 -1
- package/dist/standalone/.next/server/app/api/accounts/claude/[id]/status/route.js +1 -1
- package/dist/standalone/.next/server/app/api/accounts/claude/[id]/status/route.js.nft.json +1 -1
- package/dist/standalone/.next/server/app/api/accounts/claude/active/route.js +1 -1
- package/dist/standalone/.next/server/app/api/accounts/claude/active/route.js.nft.json +1 -1
- package/dist/standalone/.next/server/app/api/accounts/claude/limits/route.js +1 -1
- package/dist/standalone/.next/server/app/api/accounts/claude/limits/route.js.nft.json +1 -1
- package/dist/standalone/.next/server/app/api/accounts/claude/login/[operationId]/input/route.js +1 -1
- package/dist/standalone/.next/server/app/api/accounts/claude/login/[operationId]/input/route.js.nft.json +1 -1
- package/dist/standalone/.next/server/app/api/accounts/claude/login/[operationId]/route.js +1 -1
- package/dist/standalone/.next/server/app/api/accounts/claude/login/[operationId]/route.js.nft.json +1 -1
- package/dist/standalone/.next/server/app/api/accounts/claude/policy/route.js +1 -1
- package/dist/standalone/.next/server/app/api/accounts/claude/policy/route.js.nft.json +1 -1
- package/dist/standalone/.next/server/app/api/accounts/claude/route.js +1 -1
- package/dist/standalone/.next/server/app/api/accounts/claude/route.js.nft.json +1 -1
- package/dist/standalone/.next/server/app/api/accounts/claude/terminal/route.js +1 -1
- package/dist/standalone/.next/server/app/api/accounts/claude/terminal/route.js.nft.json +1 -1
- package/dist/standalone/.next/server/app/api/accounts/codex/active/route.js +1 -1
- package/dist/standalone/.next/server/app/api/accounts/codex/active/route.js.nft.json +1 -1
- package/dist/standalone/.next/server/app/api/accounts/codex/limits/route.js +1 -1
- package/dist/standalone/.next/server/app/api/accounts/codex/limits/route.js.nft.json +1 -1
- package/dist/standalone/.next/server/app/api/accounts/codex/policy/route.js +1 -1
- package/dist/standalone/.next/server/app/api/accounts/codex/policy/route.js.nft.json +1 -1
- package/dist/standalone/.next/server/app/api/accounts/codex/reset-credits/route.js +2 -2
- package/dist/standalone/.next/server/app/api/accounts/codex/reset-credits/route.js.nft.json +1 -1
- package/dist/standalone/.next/server/app/api/accounts/codex/route.js +1 -1
- package/dist/standalone/.next/server/app/api/accounts/codex/route.js.nft.json +1 -1
- package/dist/standalone/.next/server/app/api/accounts/codex/terminal/route.js +1 -1
- package/dist/standalone/.next/server/app/api/accounts/codex/terminal/route.js.nft.json +1 -1
- package/dist/standalone/.next/server/app/api/accounts/route.js +1 -1
- package/dist/standalone/.next/server/app/api/accounts/route.js.nft.json +1 -1
- package/dist/standalone/.next/server/app/api/agent/route.js +1 -1
- package/dist/standalone/.next/server/app/api/agent/route.js.nft.json +1 -1
- package/dist/standalone/.next/server/app/api/agent/snapshot/route.js +1 -1
- package/dist/standalone/.next/server/app/api/agent/snapshot/route.js.nft.json +1 -1
- package/dist/standalone/.next/server/app/api/answer/route.js +1 -2
- package/dist/standalone/.next/server/app/api/answer/route.js.nft.json +1 -1
- package/dist/standalone/.next/server/app/api/artifact/route.js +1 -1
- package/dist/standalone/.next/server/app/api/artifact/route.js.nft.json +1 -1
- package/dist/standalone/.next/server/app/api/attach-command/route.js +1 -1
- package/dist/standalone/.next/server/app/api/attach-command/route.js.nft.json +1 -1
- package/dist/standalone/.next/server/app/api/attention/[id]/route.js +1 -1
- package/dist/standalone/.next/server/app/api/attention/[id]/route.js.nft.json +1 -1
- package/dist/standalone/.next/server/app/api/attention/route.js +1 -1
- package/dist/standalone/.next/server/app/api/attention/route.js.nft.json +1 -1
- package/dist/standalone/.next/server/app/api/board/route.js +1 -1
- package/dist/standalone/.next/server/app/api/board/route.js.nft.json +1 -1
- package/dist/standalone/.next/server/app/api/bridge/route.js +1 -2
- package/dist/standalone/.next/server/app/api/bridge/route.js.nft.json +1 -1
- package/dist/standalone/.next/server/app/api/conversation-host/route.js +1 -1
- package/dist/standalone/.next/server/app/api/conversation-host/route.js.nft.json +1 -1
- package/dist/standalone/.next/server/app/api/conversation-host/targets/route.js +1 -1
- package/dist/standalone/.next/server/app/api/conversation-host/targets/route.js.nft.json +1 -1
- package/dist/standalone/.next/server/app/api/conversations/[conversationId]/migration/route.js +1 -1
- package/dist/standalone/.next/server/app/api/conversations/[conversationId]/migration/route.js.nft.json +1 -1
- package/dist/standalone/.next/server/app/api/conversations/route.js +1 -1
- package/dist/standalone/.next/server/app/api/conversations/route.js.nft.json +1 -1
- package/dist/standalone/.next/server/app/api/files/route.js +3 -2
- package/dist/standalone/.next/server/app/api/files/route.js.nft.json +1 -1
- package/dist/standalone/.next/server/app/api/flows/[id]/route.js +1 -1
- package/dist/standalone/.next/server/app/api/flows/[id]/route.js.nft.json +1 -1
- package/dist/standalone/.next/server/app/api/flows/route.js +1 -1
- package/dist/standalone/.next/server/app/api/flows/route.js.nft.json +1 -1
- package/dist/standalone/.next/server/app/api/image/route.js +1 -1
- package/dist/standalone/.next/server/app/api/image/route.js.nft.json +1 -1
- package/dist/standalone/.next/server/app/api/inbox/route.js +2 -2
- package/dist/standalone/.next/server/app/api/inbox/route.js.nft.json +1 -1
- package/dist/standalone/.next/server/app/api/lifecycle/reaper/route.js +1 -1
- package/dist/standalone/.next/server/app/api/lifecycle/reaper/route.js.nft.json +1 -1
- package/dist/standalone/.next/server/app/api/limits/history/route.js +1 -1
- package/dist/standalone/.next/server/app/api/limits/history/route.js.nft.json +1 -1
- package/dist/standalone/.next/server/app/api/limits/route.js +1 -1
- package/dist/standalone/.next/server/app/api/limits/route.js.nft.json +1 -1
- package/dist/standalone/.next/server/app/api/log/preflight/route.js +1 -1
- package/dist/standalone/.next/server/app/api/log/preflight/route.js.nft.json +1 -1
- package/dist/standalone/.next/server/app/api/log/project-delete/route.js +1 -1
- package/dist/standalone/.next/server/app/api/log/project-delete/route.js.nft.json +1 -1
- package/dist/standalone/.next/server/app/api/log/provenance/route.js +107 -1
- package/dist/standalone/.next/server/app/api/log/provenance/route.js.nft.json +1 -1
- package/dist/standalone/.next/server/app/api/log/route.js +1 -1
- package/dist/standalone/.next/server/app/api/log/route.js.nft.json +1 -1
- package/dist/standalone/.next/server/app/api/log/suggestions/route.js +2 -4
- package/dist/standalone/.next/server/app/api/log/suggestions/route.js.nft.json +1 -1
- package/dist/standalone/.next/server/app/api/logs/route.js +1 -1
- package/dist/standalone/.next/server/app/api/logs/route.js.nft.json +1 -1
- package/dist/standalone/.next/server/app/api/logs/stream/route.js +2 -2
- package/dist/standalone/.next/server/app/api/logs/stream/route.js.nft.json +1 -1
- package/dist/standalone/.next/server/app/api/monitor/runs/route.js +3 -3
- package/dist/standalone/.next/server/app/api/monitor/runs/route.js.nft.json +1 -1
- package/dist/standalone/.next/server/app/api/monitor/seat-tick/route.js +25 -0
- package/dist/standalone/.next/server/app/api/monitor/seat-tick/route.js.nft.json +1 -0
- package/dist/standalone/.next/server/app/api/monitor/seat-tick/route_client-reference-manifest.js +1 -0
- package/dist/standalone/.next/server/app/api/monitor/seat-tick/settings/route.js +2 -0
- package/dist/standalone/.next/server/app/api/monitor/seat-tick/settings/route.js.nft.json +1 -0
- package/dist/standalone/.next/server/app/api/monitor/seat-tick/settings/route_client-reference-manifest.js +1 -0
- package/dist/standalone/.next/server/app/api/orchestrator/rotate/route.js +1 -1
- package/dist/standalone/.next/server/app/api/orchestrator/rotate/route.js.nft.json +1 -1
- package/dist/standalone/.next/server/app/api/orchestrator/seat/route.js +1 -1
- package/dist/standalone/.next/server/app/api/orchestrator/seat/route.js.nft.json +1 -1
- package/dist/standalone/.next/server/app/api/orchestrator/seat/status/route.js +2 -2
- package/dist/standalone/.next/server/app/api/orchestrator/seat/status/route.js.nft.json +1 -1
- package/dist/standalone/.next/server/app/api/pipelines/[id]/route.js +1 -1
- package/dist/standalone/.next/server/app/api/pipelines/[id]/route.js.nft.json +1 -1
- package/dist/standalone/.next/server/app/api/pipelines/preflight/route.js +1 -1
- package/dist/standalone/.next/server/app/api/pipelines/preflight/route.js.nft.json +1 -1
- package/dist/standalone/.next/server/app/api/pipelines/route.js +1 -2
- package/dist/standalone/.next/server/app/api/pipelines/route.js.nft.json +1 -1
- package/dist/standalone/.next/server/app/api/pipelines/tick/route.js +2 -2
- package/dist/standalone/.next/server/app/api/pipelines/tick/route.js.nft.json +1 -1
- package/dist/standalone/.next/server/app/api/proc/route.js +1 -1
- package/dist/standalone/.next/server/app/api/proc/route.js.nft.json +1 -1
- package/dist/standalone/.next/server/app/api/projects/create/route.js +2 -2
- package/dist/standalone/.next/server/app/api/projects/create/route.js.nft.json +1 -1
- package/dist/standalone/.next/server/app/api/projects/crown/route.js +1 -1
- package/dist/standalone/.next/server/app/api/projects/crown/route.js.nft.json +1 -1
- package/dist/standalone/.next/server/app/api/projects/directories/route.js +1 -1
- package/dist/standalone/.next/server/app/api/projects/directories/route.js.nft.json +1 -1
- package/dist/standalone/.next/server/app/api/push/route.js +2 -2
- package/dist/standalone/.next/server/app/api/push/route.js.nft.json +1 -1
- package/dist/standalone/.next/server/app/api/resources/route.js +1 -1
- package/dist/standalone/.next/server/app/api/resources/route.js.nft.json +1 -1
- package/dist/standalone/.next/server/app/api/roles/route.js +2 -2
- package/dist/standalone/.next/server/app/api/roles/route.js.nft.json +1 -1
- package/dist/standalone/.next/server/app/api/runtime/answer/route.js +1 -1
- package/dist/standalone/.next/server/app/api/runtime/answer/route.js.nft.json +1 -1
- package/dist/standalone/.next/server/app/api/runtime/deployments/[deploymentId]/route.js +1 -1
- package/dist/standalone/.next/server/app/api/runtime/deployments/[deploymentId]/route.js.nft.json +1 -1
- package/dist/standalone/.next/server/app/api/runtime/deployments/capabilities/v1/route.js +1 -1
- package/dist/standalone/.next/server/app/api/runtime/deployments/capabilities/v1/route.js.nft.json +1 -1
- package/dist/standalone/.next/server/app/api/runtime/deployments/route.js +1 -1
- package/dist/standalone/.next/server/app/api/runtime/deployments/route.js.nft.json +1 -1
- package/dist/standalone/.next/server/app/api/runtime/hosts/route.js +1 -1
- package/dist/standalone/.next/server/app/api/runtime/hosts/route.js.nft.json +1 -1
- package/dist/standalone/.next/server/app/api/runtime/inject/route.js +1 -0
- package/dist/standalone/.next/server/app/api/runtime/inject/route.js.nft.json +1 -0
- package/dist/standalone/.next/server/app/api/runtime/inject/route_client-reference-manifest.js +1 -0
- package/dist/standalone/.next/server/app/api/runtime/interrupt/route.js +1 -1
- package/dist/standalone/.next/server/app/api/runtime/interrupt/route.js.nft.json +1 -1
- package/dist/standalone/.next/server/app/api/runtime/operations/[operationId]/route.js +1 -1
- package/dist/standalone/.next/server/app/api/runtime/operations/[operationId]/route.js.nft.json +1 -1
- package/dist/standalone/.next/server/app/api/runtime/operations/route.js +1 -1
- package/dist/standalone/.next/server/app/api/runtime/operations/route.js.nft.json +1 -1
- package/dist/standalone/.next/server/app/api/runtime/queue/route.js +1 -0
- package/dist/standalone/.next/server/app/api/runtime/queue/route.js.nft.json +1 -0
- package/dist/standalone/.next/server/app/api/runtime/queue/route_client-reference-manifest.js +1 -0
- package/dist/standalone/.next/server/app/api/runtime/realtime/route.js +1 -2
- package/dist/standalone/.next/server/app/api/runtime/realtime/route.js.nft.json +1 -1
- package/dist/standalone/.next/server/app/api/runtime/send/route.js +1 -1
- package/dist/standalone/.next/server/app/api/runtime/send/route.js.nft.json +1 -1
- package/dist/standalone/.next/server/app/api/runtime/snapshot/route.js +1 -1
- package/dist/standalone/.next/server/app/api/runtime/snapshot/route.js.nft.json +1 -1
- package/dist/standalone/.next/server/app/api/runtime/spawn/route.js +1 -1
- package/dist/standalone/.next/server/app/api/runtime/spawn/route.js.nft.json +1 -1
- package/dist/standalone/.next/server/app/api/runtime/steer/route.js +1 -1
- package/dist/standalone/.next/server/app/api/runtime/steer/route.js.nft.json +1 -1
- package/dist/standalone/.next/server/app/api/runtime/stream/route.js +2 -2
- package/dist/standalone/.next/server/app/api/runtime/stream/route.js.nft.json +1 -1
- package/dist/standalone/.next/server/app/api/search/transcripts/route.js +2 -2
- package/dist/standalone/.next/server/app/api/search/transcripts/route.js.nft.json +1 -1
- package/dist/standalone/.next/server/app/api/session/route.js +1 -1
- package/dist/standalone/.next/server/app/api/session/route.js.nft.json +1 -1
- package/dist/standalone/.next/server/app/api/session/supersedence/route.js +1 -1
- package/dist/standalone/.next/server/app/api/session/supersedence/route.js.nft.json +1 -1
- package/dist/standalone/.next/server/app/api/session/title/route.js +1 -1
- package/dist/standalone/.next/server/app/api/session/title/route.js.nft.json +1 -1
- package/dist/standalone/.next/server/app/api/spawn/policy/route.js +3 -3
- package/dist/standalone/.next/server/app/api/spawn/policy/route.js.nft.json +1 -1
- package/dist/standalone/.next/server/app/api/spawn/route.js +1 -2
- package/dist/standalone/.next/server/app/api/spawn/route.js.nft.json +1 -1
- package/dist/standalone/.next/server/app/api/spawn/validate/route.js +1 -0
- package/dist/standalone/.next/server/app/api/spawn/validate/route.js.nft.json +1 -0
- package/dist/standalone/.next/server/app/api/spawn/validate/route_client-reference-manifest.js +1 -0
- package/dist/standalone/.next/server/app/api/staging/route.js +2 -2
- package/dist/standalone/.next/server/app/api/staging/route.js.nft.json +1 -1
- package/dist/standalone/.next/server/app/api/task-attachments/route.js +2 -2
- package/dist/standalone/.next/server/app/api/task-attachments/route.js.nft.json +1 -1
- package/dist/standalone/.next/server/app/api/tasks/[id]/assignment/route.js +1 -1
- package/dist/standalone/.next/server/app/api/tasks/[id]/assignment/route.js.nft.json +1 -1
- package/dist/standalone/.next/server/app/api/tasks/[id]/route.js +1 -1
- package/dist/standalone/.next/server/app/api/tasks/[id]/route.js.nft.json +1 -1
- package/dist/standalone/.next/server/app/api/tasks/[id]/send/route.js +1 -2
- package/dist/standalone/.next/server/app/api/tasks/[id]/send/route.js.nft.json +1 -1
- package/dist/standalone/.next/server/app/api/tasks/[id]/spawn/route.js +1 -2
- package/dist/standalone/.next/server/app/api/tasks/[id]/spawn/route.js.nft.json +1 -1
- package/dist/standalone/.next/server/app/api/tasks/curator/route.js +1 -1
- package/dist/standalone/.next/server/app/api/tasks/curator/route.js.nft.json +1 -1
- package/dist/standalone/.next/server/app/api/tasks/route.js +1 -1
- package/dist/standalone/.next/server/app/api/tasks/route.js.nft.json +1 -1
- package/dist/standalone/.next/server/app/api/telegram/reports/route.js +1 -1
- package/dist/standalone/.next/server/app/api/telegram/reports/route.js.nft.json +1 -1
- package/dist/standalone/.next/server/app/api/telegram/route.js +1 -1
- package/dist/standalone/.next/server/app/api/telegram/route.js.nft.json +1 -1
- package/dist/standalone/.next/server/app/api/timeline/route.js +1 -1
- package/dist/standalone/.next/server/app/api/timeline/route.js.nft.json +1 -1
- package/dist/standalone/.next/server/app/api/tmux/route.js +1 -1
- package/dist/standalone/.next/server/app/api/tmux/route.js.nft.json +1 -1
- package/dist/standalone/.next/server/app/api/tmux/targets/route.js +1 -1
- package/dist/standalone/.next/server/app/api/tmux/targets/route.js.nft.json +1 -1
- package/dist/standalone/.next/server/app/api/transcribe/backend/route.js +2 -2
- package/dist/standalone/.next/server/app/api/transcribe/backend/route.js.nft.json +1 -1
- package/dist/standalone/.next/server/app/api/transcribe/route.js +2 -2
- package/dist/standalone/.next/server/app/api/transcribe/route.js.nft.json +1 -1
- package/dist/standalone/.next/server/app/api/transcribe/token/route.js +2 -2
- package/dist/standalone/.next/server/app/api/transcribe/token/route.js.nft.json +1 -1
- package/dist/standalone/.next/server/app/api/tts/backend/route.js +1 -1
- package/dist/standalone/.next/server/app/api/tts/backend/route.js.nft.json +1 -1
- package/dist/standalone/.next/server/app/api/tts/route.js +3 -3
- package/dist/standalone/.next/server/app/api/tts/route.js.nft.json +1 -1
- package/dist/standalone/.next/server/app/api/view/presence/route.js +1 -1
- package/dist/standalone/.next/server/app/api/view/presence/route.js.nft.json +1 -1
- package/dist/standalone/.next/server/app/api/workflows/[id]/route.js +1 -1
- package/dist/standalone/.next/server/app/api/workflows/[id]/route.js.nft.json +1 -1
- package/dist/standalone/.next/server/app/api/workflows/route.js +1 -1
- package/dist/standalone/.next/server/app/api/workflows/route.js.nft.json +1 -1
- package/dist/standalone/.next/server/app/favicon.ico/route.js +1 -1
- package/dist/standalone/.next/server/app/favicon.ico/route.js.nft.json +1 -1
- package/dist/standalone/.next/server/app/index.html +1 -1
- package/dist/standalone/.next/server/app/index.rsc +3 -3
- package/dist/standalone/.next/server/app/index.segments/__PAGE__.segment.rsc +3 -3
- package/dist/standalone/.next/server/app/index.segments/_full.segment.rsc +3 -3
- package/dist/standalone/.next/server/app/index.segments/_tree.segment.rsc +2 -2
- package/dist/standalone/.next/server/app/page.js +59 -30
- package/dist/standalone/.next/server/app/page.js.nft.json +1 -1
- package/dist/standalone/.next/server/app/page_client-reference-manifest.js +1 -1
- package/dist/standalone/.next/server/app-paths-manifest.json +21 -16
- package/dist/standalone/.next/server/chunks/107.js +1 -1
- package/dist/standalone/.next/server/chunks/1100.js +29 -10
- package/dist/standalone/.next/server/chunks/1406.js +399 -0
- package/dist/standalone/.next/server/chunks/1585.js +108 -0
- package/dist/standalone/.next/server/chunks/160.js +4 -4
- package/dist/standalone/.next/server/chunks/1617.js +2 -2
- package/dist/standalone/.next/server/chunks/1849.js +1 -0
- package/dist/standalone/.next/server/chunks/1888.js +1 -1
- package/dist/standalone/.next/server/chunks/193.js +1 -0
- package/dist/standalone/.next/server/chunks/1952.js +1 -0
- package/dist/standalone/.next/server/chunks/2549.js +1 -1
- package/dist/standalone/.next/server/chunks/2555.js +1 -0
- package/dist/standalone/.next/server/chunks/2647.js +1 -1
- package/dist/standalone/.next/server/chunks/2857.js +1 -0
- package/dist/standalone/.next/server/chunks/2914.js +24 -0
- package/dist/standalone/.next/server/chunks/3034.js +1 -0
- package/dist/standalone/.next/server/chunks/3086.js +1 -1
- package/dist/standalone/.next/server/chunks/3131.js +1 -0
- package/dist/standalone/.next/server/chunks/3214.js +1 -1
- package/dist/standalone/.next/server/chunks/3302.js +1 -2
- package/dist/standalone/.next/server/chunks/3407.js +1 -0
- package/dist/standalone/.next/server/chunks/3422.js +1 -0
- package/dist/standalone/.next/server/chunks/3558.js +1 -0
- package/dist/standalone/.next/server/chunks/3570.js +81 -0
- package/dist/standalone/.next/server/chunks/3587.js +1 -1
- package/dist/standalone/.next/server/chunks/3743.js +74 -24
- package/dist/standalone/.next/server/chunks/3830.js +1 -1
- package/dist/standalone/.next/server/chunks/3896.js +1 -0
- package/dist/standalone/.next/server/chunks/4127.js +1 -1
- package/dist/standalone/.next/server/chunks/4509.js +1 -1
- package/dist/standalone/.next/server/chunks/4637.js +62 -0
- package/dist/standalone/.next/server/chunks/4651.js +1 -1
- package/dist/standalone/.next/server/chunks/4783.js +1 -0
- package/dist/standalone/.next/server/chunks/480.js +126 -0
- package/dist/standalone/.next/server/chunks/4972.js +3 -3
- package/dist/standalone/.next/server/chunks/{4756.js → 4995.js} +3 -5
- package/dist/standalone/.next/server/chunks/5480.js +1 -1
- package/dist/standalone/.next/server/chunks/5545.js +1 -1
- package/dist/standalone/.next/server/chunks/568.js +1 -2
- package/dist/standalone/.next/server/chunks/5682.js +1 -0
- package/dist/standalone/.next/server/chunks/5771.js +1 -0
- package/dist/standalone/.next/server/chunks/5847.js +1 -0
- package/dist/standalone/.next/server/chunks/6023.js +1 -0
- package/dist/standalone/.next/server/chunks/6277.js +81 -0
- package/dist/standalone/.next/server/chunks/6289.js +2 -0
- package/dist/standalone/.next/server/chunks/644.js +81 -0
- package/dist/standalone/.next/server/chunks/6453.js +1 -0
- package/dist/standalone/.next/server/chunks/6522.js +1 -0
- package/dist/standalone/.next/server/chunks/6665.js +1 -1
- package/dist/standalone/.next/server/chunks/6809.js +3 -0
- package/dist/standalone/.next/server/chunks/6826.js +1 -1
- package/dist/standalone/.next/server/chunks/6926.js +1 -1
- package/dist/standalone/.next/server/chunks/{1920.js → 6942.js} +1 -1
- package/dist/standalone/.next/server/chunks/6978.js +1 -0
- package/dist/standalone/.next/server/chunks/7008.js +114 -9
- package/dist/standalone/.next/server/chunks/7192.js +1 -0
- package/dist/standalone/.next/server/chunks/7238.js +2 -0
- package/dist/standalone/.next/server/chunks/7361.js +22 -0
- package/dist/standalone/.next/server/chunks/7644.js +3 -3
- package/dist/standalone/.next/server/chunks/7722.js +1 -1
- package/dist/standalone/.next/server/chunks/781.js +55 -0
- package/dist/standalone/.next/server/chunks/7826.js +62 -0
- package/dist/standalone/.next/server/chunks/8027.js +11 -1
- package/dist/standalone/.next/server/chunks/8444.js +1 -1
- package/dist/standalone/.next/server/chunks/8512.js +1 -0
- package/dist/standalone/.next/server/chunks/8513.js +2 -0
- package/dist/standalone/.next/server/chunks/8617.js +1 -1
- package/dist/standalone/.next/server/chunks/8817.js +1 -1
- package/dist/standalone/.next/server/chunks/8991.js +1 -1
- package/dist/standalone/.next/server/chunks/8996.js +1 -1
- package/dist/standalone/.next/server/chunks/9296.js +104 -0
- package/dist/standalone/.next/server/chunks/{7139.js → 9298.js} +2 -2
- package/dist/standalone/.next/server/chunks/9307.js +1 -1
- package/dist/standalone/.next/server/chunks/9360.js +197 -0
- package/dist/standalone/.next/server/chunks/9403.js +1 -1
- package/dist/standalone/.next/server/chunks/9517.js +1 -1
- package/dist/standalone/.next/server/chunks/9554.js +47 -0
- package/dist/standalone/.next/server/chunks/9676.js +1 -62
- package/dist/standalone/.next/server/chunks/9822.js +11 -1
- package/dist/standalone/.next/server/chunks/9901.js +1 -62
- package/dist/standalone/.next/server/chunks/9940.js +3 -3
- package/dist/standalone/.next/server/chunks/9998.js +1 -1
- package/dist/standalone/.next/server/file-scanner-worker.js +3 -3
- package/dist/standalone/.next/server/files-response-worker.js +6 -6
- package/dist/standalone/.next/server/functions-config-manifest.json +5 -0
- package/dist/standalone/.next/server/instrumentation.js +1 -1
- package/dist/standalone/.next/server/middleware-build-manifest.js +1 -1
- package/dist/standalone/.next/server/middleware-react-loadable-manifest.js +1 -1
- package/dist/standalone/.next/server/middleware.js +4 -4
- package/dist/standalone/.next/server/pages/404.html +1 -1
- package/dist/standalone/.next/server/pages/500.html +1 -1
- package/dist/standalone/.next/server/resource-collector-worker.js +1 -1
- package/dist/standalone/.next/server/server-reference-manifest.json +1 -1
- package/dist/standalone/.next/server/wakatime-sync-worker.js +2 -2
- package/dist/standalone/.next/static/chunks/{3794-d1854fdd0e41dc44.js → 3794-0ef35fddac53cd9a.js} +1 -1
- package/dist/standalone/.next/static/chunks/6976-016b6947195a6ed2.js +1 -0
- package/dist/standalone/.next/static/chunks/app/_global-error/page-60a25d1c4cbf0128.js +1 -0
- package/dist/standalone/.next/static/chunks/app/api/access/route-60a25d1c4cbf0128.js +1 -0
- package/dist/standalone/.next/static/chunks/app/api/account-migrations/[intentId]/route-60a25d1c4cbf0128.js +1 -0
- package/dist/standalone/.next/static/chunks/app/api/account-project-bindings/route-60a25d1c4cbf0128.js +1 -0
- package/dist/standalone/.next/static/chunks/app/api/accounts/claude/[id]/status/route-60a25d1c4cbf0128.js +1 -0
- package/dist/standalone/.next/static/chunks/app/api/accounts/claude/active/route-60a25d1c4cbf0128.js +1 -0
- package/dist/standalone/.next/static/chunks/app/api/accounts/claude/limits/route-60a25d1c4cbf0128.js +1 -0
- package/dist/standalone/.next/static/chunks/app/api/accounts/claude/login/[operationId]/input/route-60a25d1c4cbf0128.js +1 -0
- package/dist/standalone/.next/static/chunks/app/api/accounts/claude/login/[operationId]/route-60a25d1c4cbf0128.js +1 -0
- package/dist/standalone/.next/static/chunks/app/api/accounts/claude/policy/route-60a25d1c4cbf0128.js +1 -0
- package/dist/standalone/.next/static/chunks/app/api/accounts/claude/route-60a25d1c4cbf0128.js +1 -0
- package/dist/standalone/.next/static/chunks/app/api/accounts/claude/terminal/route-60a25d1c4cbf0128.js +1 -0
- package/dist/standalone/.next/static/chunks/app/api/accounts/codex/active/route-60a25d1c4cbf0128.js +1 -0
- package/dist/standalone/.next/static/chunks/app/api/accounts/codex/limits/route-60a25d1c4cbf0128.js +1 -0
- package/dist/standalone/.next/static/chunks/app/api/accounts/codex/policy/route-60a25d1c4cbf0128.js +1 -0
- package/dist/standalone/.next/static/chunks/app/api/accounts/codex/reset-credits/route-60a25d1c4cbf0128.js +1 -0
- package/dist/standalone/.next/static/chunks/app/api/accounts/codex/route-60a25d1c4cbf0128.js +1 -0
- package/dist/standalone/.next/static/chunks/app/api/accounts/codex/terminal/route-60a25d1c4cbf0128.js +1 -0
- package/dist/standalone/.next/static/chunks/app/api/accounts/route-60a25d1c4cbf0128.js +1 -0
- package/dist/standalone/.next/static/chunks/app/api/agent/route-60a25d1c4cbf0128.js +1 -0
- package/dist/standalone/.next/static/chunks/app/api/agent/snapshot/route-60a25d1c4cbf0128.js +1 -0
- package/dist/standalone/.next/static/chunks/app/api/answer/route-60a25d1c4cbf0128.js +1 -0
- package/dist/standalone/.next/static/chunks/app/api/artifact/route-60a25d1c4cbf0128.js +1 -0
- package/dist/standalone/.next/static/chunks/app/api/attach-command/route-60a25d1c4cbf0128.js +1 -0
- package/dist/standalone/.next/static/chunks/app/api/attention/[id]/route-60a25d1c4cbf0128.js +1 -0
- package/dist/standalone/.next/static/chunks/app/api/attention/route-60a25d1c4cbf0128.js +1 -0
- package/dist/standalone/.next/static/chunks/app/api/board/route-60a25d1c4cbf0128.js +1 -0
- package/dist/standalone/.next/static/chunks/app/api/bridge/route-60a25d1c4cbf0128.js +1 -0
- package/dist/standalone/.next/static/chunks/app/api/conversation-host/route-60a25d1c4cbf0128.js +1 -0
- package/dist/standalone/.next/static/chunks/app/api/conversation-host/targets/route-60a25d1c4cbf0128.js +1 -0
- package/dist/standalone/.next/static/chunks/app/api/conversations/[conversationId]/migration/route-60a25d1c4cbf0128.js +1 -0
- package/dist/standalone/.next/static/chunks/app/api/conversations/route-60a25d1c4cbf0128.js +1 -0
- package/dist/standalone/.next/static/chunks/app/api/files/route-60a25d1c4cbf0128.js +1 -0
- package/dist/standalone/.next/static/chunks/app/api/flows/[id]/route-60a25d1c4cbf0128.js +1 -0
- package/dist/standalone/.next/static/chunks/app/api/flows/route-60a25d1c4cbf0128.js +1 -0
- package/dist/standalone/.next/static/chunks/app/api/image/route-60a25d1c4cbf0128.js +1 -0
- package/dist/standalone/.next/static/chunks/app/api/inbox/route-60a25d1c4cbf0128.js +1 -0
- package/dist/standalone/.next/static/chunks/app/api/lifecycle/reaper/route-60a25d1c4cbf0128.js +1 -0
- package/dist/standalone/.next/static/chunks/app/api/limits/history/route-60a25d1c4cbf0128.js +1 -0
- package/dist/standalone/.next/static/chunks/app/api/limits/route-60a25d1c4cbf0128.js +1 -0
- package/dist/standalone/.next/static/chunks/app/api/log/preflight/route-60a25d1c4cbf0128.js +1 -0
- package/dist/standalone/.next/static/chunks/app/api/log/project-delete/route-60a25d1c4cbf0128.js +1 -0
- package/dist/standalone/.next/static/chunks/app/api/log/provenance/route-60a25d1c4cbf0128.js +1 -0
- package/dist/standalone/.next/static/chunks/app/api/log/route-60a25d1c4cbf0128.js +1 -0
- package/dist/standalone/.next/static/chunks/app/api/log/suggestions/route-60a25d1c4cbf0128.js +1 -0
- package/dist/standalone/.next/static/chunks/app/api/logs/route-60a25d1c4cbf0128.js +1 -0
- package/dist/standalone/.next/static/chunks/app/api/logs/stream/route-60a25d1c4cbf0128.js +1 -0
- package/dist/standalone/.next/static/chunks/app/api/monitor/runs/route-60a25d1c4cbf0128.js +1 -0
- package/dist/standalone/.next/static/chunks/app/api/monitor/seat-tick/route-60a25d1c4cbf0128.js +1 -0
- package/dist/standalone/.next/static/chunks/app/api/monitor/seat-tick/settings/route-60a25d1c4cbf0128.js +1 -0
- package/dist/standalone/.next/static/chunks/app/api/orchestrator/rotate/route-60a25d1c4cbf0128.js +1 -0
- package/dist/standalone/.next/static/chunks/app/api/orchestrator/seat/route-60a25d1c4cbf0128.js +1 -0
- package/dist/standalone/.next/static/chunks/app/api/orchestrator/seat/status/route-60a25d1c4cbf0128.js +1 -0
- package/dist/standalone/.next/static/chunks/app/api/pipelines/[id]/route-60a25d1c4cbf0128.js +1 -0
- package/dist/standalone/.next/static/chunks/app/api/pipelines/preflight/route-60a25d1c4cbf0128.js +1 -0
- package/dist/standalone/.next/static/chunks/app/api/pipelines/route-60a25d1c4cbf0128.js +1 -0
- package/dist/standalone/.next/static/chunks/app/api/pipelines/tick/route-60a25d1c4cbf0128.js +1 -0
- package/dist/standalone/.next/static/chunks/app/api/proc/route-60a25d1c4cbf0128.js +1 -0
- package/dist/standalone/.next/static/chunks/app/api/projects/create/route-60a25d1c4cbf0128.js +1 -0
- package/dist/standalone/.next/static/chunks/app/api/projects/crown/route-60a25d1c4cbf0128.js +1 -0
- package/dist/standalone/.next/static/chunks/app/api/projects/directories/route-60a25d1c4cbf0128.js +1 -0
- package/dist/standalone/.next/static/chunks/app/api/push/route-60a25d1c4cbf0128.js +1 -0
- package/dist/standalone/.next/static/chunks/app/api/resources/route-60a25d1c4cbf0128.js +1 -0
- package/dist/standalone/.next/static/chunks/app/api/roles/route-60a25d1c4cbf0128.js +1 -0
- package/dist/standalone/.next/static/chunks/app/api/runtime/answer/route-60a25d1c4cbf0128.js +1 -0
- package/dist/standalone/.next/static/chunks/app/api/runtime/deployments/[deploymentId]/route-60a25d1c4cbf0128.js +1 -0
- package/dist/standalone/.next/static/chunks/app/api/runtime/deployments/capabilities/v1/route-60a25d1c4cbf0128.js +1 -0
- package/dist/standalone/.next/static/chunks/app/api/runtime/deployments/route-60a25d1c4cbf0128.js +1 -0
- package/dist/standalone/.next/static/chunks/app/api/runtime/hosts/route-60a25d1c4cbf0128.js +1 -0
- package/dist/standalone/.next/static/chunks/app/api/runtime/inject/route-60a25d1c4cbf0128.js +1 -0
- package/dist/standalone/.next/static/chunks/app/api/runtime/interrupt/route-60a25d1c4cbf0128.js +1 -0
- package/dist/standalone/.next/static/chunks/app/api/runtime/operations/[operationId]/route-60a25d1c4cbf0128.js +1 -0
- package/dist/standalone/.next/static/chunks/app/api/runtime/operations/route-60a25d1c4cbf0128.js +1 -0
- package/dist/standalone/.next/static/chunks/app/api/runtime/queue/route-60a25d1c4cbf0128.js +1 -0
- package/dist/standalone/.next/static/chunks/app/api/runtime/realtime/route-60a25d1c4cbf0128.js +1 -0
- package/dist/standalone/.next/static/chunks/app/api/runtime/send/route-60a25d1c4cbf0128.js +1 -0
- package/dist/standalone/.next/static/chunks/app/api/runtime/snapshot/route-60a25d1c4cbf0128.js +1 -0
- package/dist/standalone/.next/static/chunks/app/api/runtime/spawn/route-60a25d1c4cbf0128.js +1 -0
- package/dist/standalone/.next/static/chunks/app/api/runtime/steer/route-60a25d1c4cbf0128.js +1 -0
- package/dist/standalone/.next/static/chunks/app/api/runtime/stream/route-60a25d1c4cbf0128.js +1 -0
- package/dist/standalone/.next/static/chunks/app/api/search/transcripts/route-60a25d1c4cbf0128.js +1 -0
- package/dist/standalone/.next/static/chunks/app/api/session/route-60a25d1c4cbf0128.js +1 -0
- package/dist/standalone/.next/static/chunks/app/api/session/supersedence/route-60a25d1c4cbf0128.js +1 -0
- package/dist/standalone/.next/static/chunks/app/api/session/title/route-60a25d1c4cbf0128.js +1 -0
- package/dist/standalone/.next/static/chunks/app/api/spawn/policy/route-60a25d1c4cbf0128.js +1 -0
- package/dist/standalone/.next/static/chunks/app/api/spawn/route-60a25d1c4cbf0128.js +1 -0
- package/dist/standalone/.next/static/chunks/app/api/spawn/validate/route-60a25d1c4cbf0128.js +1 -0
- package/dist/standalone/.next/static/chunks/app/api/staging/route-60a25d1c4cbf0128.js +1 -0
- package/dist/standalone/.next/static/chunks/app/api/task-attachments/route-60a25d1c4cbf0128.js +1 -0
- package/dist/standalone/.next/static/chunks/app/api/tasks/[id]/assignment/route-60a25d1c4cbf0128.js +1 -0
- package/dist/standalone/.next/static/chunks/app/api/tasks/[id]/route-60a25d1c4cbf0128.js +1 -0
- package/dist/standalone/.next/static/chunks/app/api/tasks/[id]/send/route-60a25d1c4cbf0128.js +1 -0
- package/dist/standalone/.next/static/chunks/app/api/tasks/[id]/spawn/route-60a25d1c4cbf0128.js +1 -0
- package/dist/standalone/.next/static/chunks/app/api/tasks/curator/route-60a25d1c4cbf0128.js +1 -0
- package/dist/standalone/.next/static/chunks/app/api/tasks/route-60a25d1c4cbf0128.js +1 -0
- package/dist/standalone/.next/static/chunks/app/api/telegram/reports/route-60a25d1c4cbf0128.js +1 -0
- package/dist/standalone/.next/static/chunks/app/api/telegram/route-60a25d1c4cbf0128.js +1 -0
- package/dist/standalone/.next/static/chunks/app/api/timeline/route-60a25d1c4cbf0128.js +1 -0
- package/dist/standalone/.next/static/chunks/app/api/tmux/route-60a25d1c4cbf0128.js +1 -0
- package/dist/standalone/.next/static/chunks/app/api/tmux/targets/route-60a25d1c4cbf0128.js +1 -0
- package/dist/standalone/.next/static/chunks/app/api/transcribe/backend/route-60a25d1c4cbf0128.js +1 -0
- package/dist/standalone/.next/static/chunks/app/api/transcribe/route-60a25d1c4cbf0128.js +1 -0
- package/dist/standalone/.next/static/chunks/app/api/transcribe/token/route-60a25d1c4cbf0128.js +1 -0
- package/dist/standalone/.next/static/chunks/app/api/tts/backend/route-60a25d1c4cbf0128.js +1 -0
- package/dist/standalone/.next/static/chunks/app/api/tts/route-60a25d1c4cbf0128.js +1 -0
- package/dist/standalone/.next/static/chunks/app/api/view/presence/route-60a25d1c4cbf0128.js +1 -0
- package/dist/standalone/.next/static/chunks/app/api/workflows/[id]/route-60a25d1c4cbf0128.js +1 -0
- package/dist/standalone/.next/static/chunks/app/api/workflows/route-60a25d1c4cbf0128.js +1 -0
- package/dist/standalone/.next/static/chunks/app/page-16384e540b4c0a90.js +125 -0
- package/dist/standalone/.next/static/chunks/{main-8691b7dc3557ef3f.js → main-7e65147ff5ce0866.js} +1 -1
- package/dist/standalone/.next/static/chunks/next/dist/client/components/builtin/app-error-60a25d1c4cbf0128.js +1 -0
- package/dist/standalone/.next/static/chunks/next/dist/client/components/builtin/forbidden-60a25d1c4cbf0128.js +1 -0
- package/dist/standalone/.next/static/chunks/next/dist/client/components/builtin/not-found-60a25d1c4cbf0128.js +1 -0
- package/dist/standalone/.next/static/chunks/next/dist/client/components/builtin/unauthorized-60a25d1c4cbf0128.js +1 -0
- package/dist/standalone/.next/static/css/496211a19557b7ee.css +1 -0
- package/dist/standalone/.next/static/e4qE_aCE0s0KQnnU6IWRw/_buildManifest.js +1 -0
- package/dist/standalone/AGENTS.md +20 -0
- package/dist/standalone/node_modules/@next/env/package.json +1 -1
- package/dist/standalone/node_modules/next/dist/build/swc/index.js +1 -1
- package/dist/standalone/node_modules/next/dist/build/webpack-config.js +3 -3
- package/dist/standalone/node_modules/next/dist/compiled/next-server/app-page-experimental.runtime.prod.js +1 -1
- package/dist/standalone/node_modules/next/dist/compiled/next-server/app-page-turbo-experimental.runtime.prod.js +1 -1
- package/dist/standalone/node_modules/next/dist/compiled/next-server/app-page-turbo.runtime.prod.js +1 -1
- package/dist/standalone/node_modules/next/dist/compiled/next-server/app-page.runtime.prod.js +1 -1
- package/dist/standalone/node_modules/next/dist/compiled/next-server/app-route.runtime.prod.js +1 -1
- package/dist/standalone/node_modules/next/dist/compiled/next-server/pages-turbo.runtime.prod.js +5 -5
- package/dist/standalone/node_modules/next/dist/compiled/next-server/pages.runtime.prod.js +5 -5
- package/dist/standalone/node_modules/next/dist/lib/patch-incorrect-lockfile.js +3 -3
- package/dist/standalone/node_modules/next/dist/server/config.js +1 -1
- package/dist/standalone/node_modules/next/dist/server/dev/hot-reloader-turbopack.js +2 -2
- package/dist/standalone/node_modules/next/dist/server/dev/hot-reloader-webpack.js +1 -1
- package/dist/standalone/node_modules/next/dist/server/image-optimizer.js +2 -2
- package/dist/standalone/node_modules/next/dist/server/lib/app-info-log.js +1 -1
- package/dist/standalone/node_modules/next/dist/server/lib/incremental-cache/file-system-cache.js +17 -4
- package/dist/standalone/node_modules/next/dist/server/lib/start-server.js +1 -1
- package/dist/standalone/node_modules/next/dist/shared/lib/router/utils/escape-path-delimiters.js +1 -1
- package/dist/standalone/node_modules/next/dist/telemetry/anonymous-meta.js +1 -1
- package/dist/standalone/node_modules/next/dist/telemetry/events/swc-load-failure.js +1 -1
- package/dist/standalone/node_modules/next/dist/telemetry/events/version.js +2 -2
- package/dist/standalone/node_modules/next/package.json +10 -10
- package/dist/standalone/package.json +5 -5
- package/dist/standalone/server.bun.js +1 -1
- package/dist/standalone/src/lib/viewerInstrumentation.ts +809 -0
- package/package.json +5 -5
- package/dist/standalone/.next/server/chunks/112.js +0 -1
- package/dist/standalone/.next/server/chunks/2190.js +0 -1
- package/dist/standalone/.next/server/chunks/2318.js +0 -2
- package/dist/standalone/.next/server/chunks/2371.js +0 -1
- package/dist/standalone/.next/server/chunks/2500.js +0 -55
- package/dist/standalone/.next/server/chunks/2799.js +0 -1
- package/dist/standalone/.next/server/chunks/2870.js +0 -104
- package/dist/standalone/.next/server/chunks/3598.js +0 -81
- package/dist/standalone/.next/server/chunks/3740.js +0 -126
- package/dist/standalone/.next/server/chunks/3953.js +0 -1
- package/dist/standalone/.next/server/chunks/411.js +0 -1
- package/dist/standalone/.next/server/chunks/4191.js +0 -1
- package/dist/standalone/.next/server/chunks/461.js +0 -1
- package/dist/standalone/.next/server/chunks/4968.js +0 -2
- package/dist/standalone/.next/server/chunks/5408.js +0 -1
- package/dist/standalone/.next/server/chunks/6333.js +0 -47
- package/dist/standalone/.next/server/chunks/6839.js +0 -81
- package/dist/standalone/.next/server/chunks/7045.js +0 -319
- package/dist/standalone/.next/server/chunks/7159.js +0 -1
- package/dist/standalone/.next/server/chunks/8176.js +0 -1
- package/dist/standalone/.next/server/chunks/8263.js +0 -81
- package/dist/standalone/.next/server/chunks/8392.js +0 -126
- package/dist/standalone/.next/server/chunks/9120.js +0 -78
- package/dist/standalone/.next/server/chunks/9507.js +0 -1
- package/dist/standalone/.next/static/6jhPk8sOUI3wRf_j1l5vY/_buildManifest.js +0 -1
- package/dist/standalone/.next/static/chunks/3021-9ced2d55bf2cbf77.js +0 -1
- package/dist/standalone/.next/static/chunks/app/_global-error/page-3e358516d279299e.js +0 -1
- package/dist/standalone/.next/static/chunks/app/api/access/route-3e358516d279299e.js +0 -1
- package/dist/standalone/.next/static/chunks/app/api/account-migrations/[intentId]/route-3e358516d279299e.js +0 -1
- package/dist/standalone/.next/static/chunks/app/api/account-project-bindings/route-3e358516d279299e.js +0 -1
- package/dist/standalone/.next/static/chunks/app/api/accounts/claude/[id]/status/route-3e358516d279299e.js +0 -1
- package/dist/standalone/.next/static/chunks/app/api/accounts/claude/active/route-3e358516d279299e.js +0 -1
- package/dist/standalone/.next/static/chunks/app/api/accounts/claude/limits/route-3e358516d279299e.js +0 -1
- package/dist/standalone/.next/static/chunks/app/api/accounts/claude/login/[operationId]/input/route-3e358516d279299e.js +0 -1
- package/dist/standalone/.next/static/chunks/app/api/accounts/claude/login/[operationId]/route-3e358516d279299e.js +0 -1
- package/dist/standalone/.next/static/chunks/app/api/accounts/claude/policy/route-3e358516d279299e.js +0 -1
- package/dist/standalone/.next/static/chunks/app/api/accounts/claude/route-3e358516d279299e.js +0 -1
- package/dist/standalone/.next/static/chunks/app/api/accounts/claude/terminal/route-3e358516d279299e.js +0 -1
- package/dist/standalone/.next/static/chunks/app/api/accounts/codex/active/route-3e358516d279299e.js +0 -1
- package/dist/standalone/.next/static/chunks/app/api/accounts/codex/limits/route-3e358516d279299e.js +0 -1
- package/dist/standalone/.next/static/chunks/app/api/accounts/codex/policy/route-3e358516d279299e.js +0 -1
- package/dist/standalone/.next/static/chunks/app/api/accounts/codex/reset-credits/route-3e358516d279299e.js +0 -1
- package/dist/standalone/.next/static/chunks/app/api/accounts/codex/route-3e358516d279299e.js +0 -1
- package/dist/standalone/.next/static/chunks/app/api/accounts/codex/terminal/route-3e358516d279299e.js +0 -1
- package/dist/standalone/.next/static/chunks/app/api/accounts/route-3e358516d279299e.js +0 -1
- package/dist/standalone/.next/static/chunks/app/api/agent/route-3e358516d279299e.js +0 -1
- package/dist/standalone/.next/static/chunks/app/api/agent/snapshot/route-3e358516d279299e.js +0 -1
- package/dist/standalone/.next/static/chunks/app/api/answer/route-3e358516d279299e.js +0 -1
- package/dist/standalone/.next/static/chunks/app/api/artifact/route-3e358516d279299e.js +0 -1
- package/dist/standalone/.next/static/chunks/app/api/attach-command/route-3e358516d279299e.js +0 -1
- package/dist/standalone/.next/static/chunks/app/api/attention/[id]/route-3e358516d279299e.js +0 -1
- package/dist/standalone/.next/static/chunks/app/api/attention/route-3e358516d279299e.js +0 -1
- package/dist/standalone/.next/static/chunks/app/api/board/route-3e358516d279299e.js +0 -1
- package/dist/standalone/.next/static/chunks/app/api/bridge/route-3e358516d279299e.js +0 -1
- package/dist/standalone/.next/static/chunks/app/api/conversation-host/route-3e358516d279299e.js +0 -1
- package/dist/standalone/.next/static/chunks/app/api/conversation-host/targets/route-3e358516d279299e.js +0 -1
- package/dist/standalone/.next/static/chunks/app/api/conversations/[conversationId]/migration/route-3e358516d279299e.js +0 -1
- package/dist/standalone/.next/static/chunks/app/api/conversations/route-3e358516d279299e.js +0 -1
- package/dist/standalone/.next/static/chunks/app/api/files/route-3e358516d279299e.js +0 -1
- package/dist/standalone/.next/static/chunks/app/api/flows/[id]/route-3e358516d279299e.js +0 -1
- package/dist/standalone/.next/static/chunks/app/api/flows/route-3e358516d279299e.js +0 -1
- package/dist/standalone/.next/static/chunks/app/api/image/route-3e358516d279299e.js +0 -1
- package/dist/standalone/.next/static/chunks/app/api/inbox/route-3e358516d279299e.js +0 -1
- package/dist/standalone/.next/static/chunks/app/api/lifecycle/reaper/route-3e358516d279299e.js +0 -1
- package/dist/standalone/.next/static/chunks/app/api/limits/history/route-3e358516d279299e.js +0 -1
- package/dist/standalone/.next/static/chunks/app/api/limits/route-3e358516d279299e.js +0 -1
- package/dist/standalone/.next/static/chunks/app/api/log/preflight/route-3e358516d279299e.js +0 -1
- package/dist/standalone/.next/static/chunks/app/api/log/project-delete/route-3e358516d279299e.js +0 -1
- package/dist/standalone/.next/static/chunks/app/api/log/provenance/route-3e358516d279299e.js +0 -1
- package/dist/standalone/.next/static/chunks/app/api/log/route-3e358516d279299e.js +0 -1
- package/dist/standalone/.next/static/chunks/app/api/log/suggestions/route-3e358516d279299e.js +0 -1
- package/dist/standalone/.next/static/chunks/app/api/logs/route-3e358516d279299e.js +0 -1
- package/dist/standalone/.next/static/chunks/app/api/logs/stream/route-3e358516d279299e.js +0 -1
- package/dist/standalone/.next/static/chunks/app/api/monitor/runs/route-3e358516d279299e.js +0 -1
- package/dist/standalone/.next/static/chunks/app/api/orchestrator/rotate/route-3e358516d279299e.js +0 -1
- package/dist/standalone/.next/static/chunks/app/api/orchestrator/seat/route-3e358516d279299e.js +0 -1
- package/dist/standalone/.next/static/chunks/app/api/orchestrator/seat/status/route-3e358516d279299e.js +0 -1
- package/dist/standalone/.next/static/chunks/app/api/pipelines/[id]/route-3e358516d279299e.js +0 -1
- package/dist/standalone/.next/static/chunks/app/api/pipelines/preflight/route-3e358516d279299e.js +0 -1
- package/dist/standalone/.next/static/chunks/app/api/pipelines/route-3e358516d279299e.js +0 -1
- package/dist/standalone/.next/static/chunks/app/api/pipelines/tick/route-3e358516d279299e.js +0 -1
- package/dist/standalone/.next/static/chunks/app/api/proc/route-3e358516d279299e.js +0 -1
- package/dist/standalone/.next/static/chunks/app/api/projects/create/route-3e358516d279299e.js +0 -1
- package/dist/standalone/.next/static/chunks/app/api/projects/crown/route-3e358516d279299e.js +0 -1
- package/dist/standalone/.next/static/chunks/app/api/projects/directories/route-3e358516d279299e.js +0 -1
- package/dist/standalone/.next/static/chunks/app/api/push/route-3e358516d279299e.js +0 -1
- package/dist/standalone/.next/static/chunks/app/api/resources/route-3e358516d279299e.js +0 -1
- package/dist/standalone/.next/static/chunks/app/api/roles/route-3e358516d279299e.js +0 -1
- package/dist/standalone/.next/static/chunks/app/api/runtime/answer/route-3e358516d279299e.js +0 -1
- package/dist/standalone/.next/static/chunks/app/api/runtime/deployments/[deploymentId]/route-3e358516d279299e.js +0 -1
- package/dist/standalone/.next/static/chunks/app/api/runtime/deployments/capabilities/v1/route-3e358516d279299e.js +0 -1
- package/dist/standalone/.next/static/chunks/app/api/runtime/deployments/route-3e358516d279299e.js +0 -1
- package/dist/standalone/.next/static/chunks/app/api/runtime/hosts/route-3e358516d279299e.js +0 -1
- package/dist/standalone/.next/static/chunks/app/api/runtime/interrupt/route-3e358516d279299e.js +0 -1
- package/dist/standalone/.next/static/chunks/app/api/runtime/operations/[operationId]/route-3e358516d279299e.js +0 -1
- package/dist/standalone/.next/static/chunks/app/api/runtime/operations/route-3e358516d279299e.js +0 -1
- package/dist/standalone/.next/static/chunks/app/api/runtime/realtime/route-3e358516d279299e.js +0 -1
- package/dist/standalone/.next/static/chunks/app/api/runtime/send/route-3e358516d279299e.js +0 -1
- package/dist/standalone/.next/static/chunks/app/api/runtime/snapshot/route-3e358516d279299e.js +0 -1
- package/dist/standalone/.next/static/chunks/app/api/runtime/spawn/route-3e358516d279299e.js +0 -1
- package/dist/standalone/.next/static/chunks/app/api/runtime/steer/route-3e358516d279299e.js +0 -1
- package/dist/standalone/.next/static/chunks/app/api/runtime/stream/route-3e358516d279299e.js +0 -1
- package/dist/standalone/.next/static/chunks/app/api/search/transcripts/route-3e358516d279299e.js +0 -1
- package/dist/standalone/.next/static/chunks/app/api/session/route-3e358516d279299e.js +0 -1
- package/dist/standalone/.next/static/chunks/app/api/session/supersedence/route-3e358516d279299e.js +0 -1
- package/dist/standalone/.next/static/chunks/app/api/session/title/route-3e358516d279299e.js +0 -1
- package/dist/standalone/.next/static/chunks/app/api/spawn/policy/route-3e358516d279299e.js +0 -1
- package/dist/standalone/.next/static/chunks/app/api/spawn/route-3e358516d279299e.js +0 -1
- package/dist/standalone/.next/static/chunks/app/api/staging/route-3e358516d279299e.js +0 -1
- package/dist/standalone/.next/static/chunks/app/api/task-attachments/route-3e358516d279299e.js +0 -1
- package/dist/standalone/.next/static/chunks/app/api/tasks/[id]/assignment/route-3e358516d279299e.js +0 -1
- package/dist/standalone/.next/static/chunks/app/api/tasks/[id]/route-3e358516d279299e.js +0 -1
- package/dist/standalone/.next/static/chunks/app/api/tasks/[id]/send/route-3e358516d279299e.js +0 -1
- package/dist/standalone/.next/static/chunks/app/api/tasks/[id]/spawn/route-3e358516d279299e.js +0 -1
- package/dist/standalone/.next/static/chunks/app/api/tasks/curator/route-3e358516d279299e.js +0 -1
- package/dist/standalone/.next/static/chunks/app/api/tasks/route-3e358516d279299e.js +0 -1
- package/dist/standalone/.next/static/chunks/app/api/telegram/reports/route-3e358516d279299e.js +0 -1
- package/dist/standalone/.next/static/chunks/app/api/telegram/route-3e358516d279299e.js +0 -1
- package/dist/standalone/.next/static/chunks/app/api/timeline/route-3e358516d279299e.js +0 -1
- package/dist/standalone/.next/static/chunks/app/api/tmux/route-3e358516d279299e.js +0 -1
- package/dist/standalone/.next/static/chunks/app/api/tmux/targets/route-3e358516d279299e.js +0 -1
- package/dist/standalone/.next/static/chunks/app/api/transcribe/backend/route-3e358516d279299e.js +0 -1
- package/dist/standalone/.next/static/chunks/app/api/transcribe/route-3e358516d279299e.js +0 -1
- package/dist/standalone/.next/static/chunks/app/api/transcribe/token/route-3e358516d279299e.js +0 -1
- package/dist/standalone/.next/static/chunks/app/api/tts/backend/route-3e358516d279299e.js +0 -1
- package/dist/standalone/.next/static/chunks/app/api/tts/route-3e358516d279299e.js +0 -1
- package/dist/standalone/.next/static/chunks/app/api/view/presence/route-3e358516d279299e.js +0 -1
- package/dist/standalone/.next/static/chunks/app/api/workflows/[id]/route-3e358516d279299e.js +0 -1
- package/dist/standalone/.next/static/chunks/app/api/workflows/route-3e358516d279299e.js +0 -1
- package/dist/standalone/.next/static/chunks/app/page-dbe7cb010b4941d6.js +0 -96
- package/dist/standalone/.next/static/chunks/next/dist/client/components/builtin/app-error-3e358516d279299e.js +0 -1
- package/dist/standalone/.next/static/chunks/next/dist/client/components/builtin/forbidden-3e358516d279299e.js +0 -1
- package/dist/standalone/.next/static/chunks/next/dist/client/components/builtin/not-found-3e358516d279299e.js +0 -1
- package/dist/standalone/.next/static/chunks/next/dist/client/components/builtin/unauthorized-3e358516d279299e.js +0 -1
- package/dist/standalone/.next/static/css/282596e2aaee1aa4.css +0 -1
- package/dist/standalone/src/lib/inboxFiles.ts +0 -203
- /package/dist/standalone/.next/static/{6jhPk8sOUI3wRf_j1l5vY → e4qE_aCE0s0KQnnU6IWRw}/_ssgManifest.js +0 -0
|
@@ -0,0 +1,809 @@
|
|
|
1
|
+
import fs from "node:fs";
|
|
2
|
+
import path from "node:path";
|
|
3
|
+
import type { ChildProcess } from "node:child_process";
|
|
4
|
+
|
|
5
|
+
import { statePath } from "@/lib/configDir";
|
|
6
|
+
import { RuntimeHostUnavailableError } from "@/lib/runtime/client";
|
|
7
|
+
import { structuredHostsEnabled } from "@/lib/runtime/flags";
|
|
8
|
+
import {
|
|
9
|
+
acknowledgeHotStateFence,
|
|
10
|
+
completeHotStatePreparation,
|
|
11
|
+
hotStateWriterRevision,
|
|
12
|
+
markHotStateActivationReady,
|
|
13
|
+
markViewerReleaseReady,
|
|
14
|
+
publishHotStateAuthority,
|
|
15
|
+
readHotStateAuthority,
|
|
16
|
+
type HotStateAuthority,
|
|
17
|
+
type HotStateCheckpoint,
|
|
18
|
+
} from "@/lib/state/hotStateAuthority";
|
|
19
|
+
import { initializeStateCollections, markStateSqliteCutoverReady } from "@/lib/state/sqliteStateStore";
|
|
20
|
+
import { markStructuredHostStartupFailed, markStructuredHostStartupReady } from "@/lib/runtime/startupStatus";
|
|
21
|
+
import { StructuredRuntimeRequirementError } from "@/lib/proc/darwinIdentity";
|
|
22
|
+
import {
|
|
23
|
+
discardWakatimeEnvironmentCredential,
|
|
24
|
+
withoutWakatimeCredential,
|
|
25
|
+
} from "@/lib/wakatime/credential";
|
|
26
|
+
import { wakatimeIntegrationEnabled } from "@/lib/wakatime/activation";
|
|
27
|
+
|
|
28
|
+
/*
|
|
29
|
+
* The Viewer's node-side startup runtime. This module (and everything it pulls
|
|
30
|
+
* in — node: builtins included) must stay OUT of `src/instrumentation.ts`:
|
|
31
|
+
* Next's dev fallback compiler builds that entry without node:-scheme support,
|
|
32
|
+
* so any node: import reachable from it fails the compile and 500s every
|
|
33
|
+
* request (the local QA `/api/files` regression). `register()` reaches this
|
|
34
|
+
* module only through a dynamic import inside a statically-pruned
|
|
35
|
+
* `NEXT_RUNTIME === "nodejs"` branch.
|
|
36
|
+
*/
|
|
37
|
+
|
|
38
|
+
const RELEASE_ACTIVATION_POLL_MS = 250;
|
|
39
|
+
const HOT_STATE_CUTOVER_STABLE_POLLS = 3;
|
|
40
|
+
const HOT_STATE_CUTOVER_MAX_POLLS = 12;
|
|
41
|
+
const WAKATIME_WORKER_RESTART_MS = 1_000;
|
|
42
|
+
const wakatimeWorkerStore = globalThis as typeof globalThis & {
|
|
43
|
+
__llvWakatimeWorker?: ChildProcess;
|
|
44
|
+
__llvWakatimeWorkerRestart?: ReturnType<typeof setTimeout>;
|
|
45
|
+
};
|
|
46
|
+
|
|
47
|
+
interface ActivationTimer {
|
|
48
|
+
unref?(): unknown;
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
interface StructuredHostStartupOptions {
|
|
52
|
+
signal?: AbortSignal;
|
|
53
|
+
schedule?: (callback: () => void, delayMs: number) => ActivationTimer;
|
|
54
|
+
initialRetryMs?: number;
|
|
55
|
+
maxRetryMs?: number;
|
|
56
|
+
jitterRatio?: number;
|
|
57
|
+
random?: () => number;
|
|
58
|
+
waitUntilReady?: boolean;
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
interface ViewerReleaseActivationOptions {
|
|
62
|
+
pollMs?: number;
|
|
63
|
+
schedule?: (callback: () => void, delayMs: number) => ActivationTimer;
|
|
64
|
+
log?: (...args: unknown[]) => void;
|
|
65
|
+
fenceRequest?: () => HotStateAuthority | null;
|
|
66
|
+
onFenceRequested?: (request: HotStateAuthority) => void | Promise<void>;
|
|
67
|
+
onDemoted?: (context: { fenced: boolean }) => void | Promise<void>;
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
interface HotStateCutoverOptions {
|
|
71
|
+
pollMs?: number;
|
|
72
|
+
stablePolls?: number;
|
|
73
|
+
maxPolls?: number;
|
|
74
|
+
schedule?: (callback: () => void, delayMs: number) => ActivationTimer;
|
|
75
|
+
legacySignature?: () => string;
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
export interface HotStateCutoverBoundary {
|
|
79
|
+
authority: HotStateAuthority | null;
|
|
80
|
+
reimportLegacy: boolean;
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
interface CurrentReleaseControllerLoaders {
|
|
84
|
+
loadFlowPipelineController: () => Promise<{ startFlowPipelineController: () => void }>;
|
|
85
|
+
loadAccountMigrationController: () => Promise<{ startAccountMigrationController: () => Promise<void> }>;
|
|
86
|
+
/** Optional so a test can supply the two controllers it exercises and get
|
|
87
|
+
nothing else. Production always passes it. */
|
|
88
|
+
loadTelegramReportScheduler?: () => Promise<{ ensureTelegramReportScheduler: () => void }>;
|
|
89
|
+
/** Optional for the same reason. */
|
|
90
|
+
loadTelegramConnectorBoot?: () => Promise<{ provisionTelegramConnectorAtStartup: () => Promise<unknown> }>;
|
|
91
|
+
/** Optional for the same reason. */
|
|
92
|
+
loadStructuredHostRetirement?: () => Promise<{ startStructuredHostRetirement: () => void }>;
|
|
93
|
+
/** Optional for the same reason. */
|
|
94
|
+
loadSeatTick?: () => Promise<{ startSeatTick: () => boolean }>;
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
interface ViewerRuntimeActivationSteps {
|
|
98
|
+
initializeOperatorCapability: () => Promise<void>;
|
|
99
|
+
runIdentityMigration?: () => Promise<void> | void;
|
|
100
|
+
startWakatime: () => Promise<void>;
|
|
101
|
+
startStructuredHosts: (() => void) | null;
|
|
102
|
+
startControllers: () => Promise<void>;
|
|
103
|
+
publishHotStateActivation: () => void;
|
|
104
|
+
publishViewerReleaseReady: () => void;
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
/** Candidate containers share production state while their health gate runs.
|
|
108
|
+
* The durable proxy target grants authority to the endpoint currently serving
|
|
109
|
+
* traffic. A missing target keeps local development and first boot active. */
|
|
110
|
+
export function viewerReleaseOwnsTraffic(
|
|
111
|
+
env: Readonly<Record<string, string | undefined>> = process.env,
|
|
112
|
+
readTarget: () => string = () => fs.readFileSync(statePath("viewer-release.json"), "utf8"),
|
|
113
|
+
): boolean {
|
|
114
|
+
const port = env.PORT?.trim();
|
|
115
|
+
if (!port) return true;
|
|
116
|
+
let raw: string;
|
|
117
|
+
try {
|
|
118
|
+
raw = readTarget();
|
|
119
|
+
} catch (error) {
|
|
120
|
+
return (error as NodeJS.ErrnoException).code === "ENOENT";
|
|
121
|
+
}
|
|
122
|
+
try {
|
|
123
|
+
const target = JSON.parse(raw) as { endpoint?: unknown };
|
|
124
|
+
if (typeof target.endpoint !== "string") return false;
|
|
125
|
+
return new URL(target.endpoint).port === port;
|
|
126
|
+
} catch {
|
|
127
|
+
return false;
|
|
128
|
+
}
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
function legacyHotStateSignature(): string {
|
|
132
|
+
return ["flows.json", "pipelines.json", "pipelines-archive.json", "workflows.json"].map((name) => {
|
|
133
|
+
const filename = statePath(name);
|
|
134
|
+
try {
|
|
135
|
+
const stat = fs.statSync(filename, { bigint: true });
|
|
136
|
+
return `${name}:${stat.mtimeNs}:${stat.size}`;
|
|
137
|
+
} catch {
|
|
138
|
+
return `${name}:missing`;
|
|
139
|
+
}
|
|
140
|
+
}).join("|");
|
|
141
|
+
}
|
|
142
|
+
|
|
143
|
+
/** A promoted first-SQLite release waits through the predecessor's demotion
|
|
144
|
+
* poll and imports only after every legacy hot-state file is stable. */
|
|
145
|
+
export async function establishHotStateCutoverBoundary(
|
|
146
|
+
isCurrent: () => boolean,
|
|
147
|
+
options: HotStateCutoverOptions = {},
|
|
148
|
+
): Promise<HotStateCutoverBoundary> {
|
|
149
|
+
const directory = path.dirname(statePath("state.sqlite"));
|
|
150
|
+
const releaseRevision = hotStateWriterRevision(directory);
|
|
151
|
+
const targetExists = releaseRevision !== null || fs.existsSync(statePath("viewer-release.json"));
|
|
152
|
+
if (targetExists && releaseRevision === null) throw new Error("viewer release cannot publish hot-state authority");
|
|
153
|
+
if (releaseRevision === null) {
|
|
154
|
+
markStateSqliteCutoverReady(statePath("state.sqlite"));
|
|
155
|
+
return { authority: null, reimportLegacy: false };
|
|
156
|
+
}
|
|
157
|
+
let authority = readHotStateAuthority(directory);
|
|
158
|
+
if (authority?.mode === "sqlite" && authority.releaseRevision !== releaseRevision) {
|
|
159
|
+
authority = publishHotStateAuthority(directory, "sqlite", releaseRevision);
|
|
160
|
+
markStateSqliteCutoverReady(statePath("state.sqlite"));
|
|
161
|
+
return { authority, reimportLegacy: false };
|
|
162
|
+
}
|
|
163
|
+
if (authority?.mode === "sqlite" && authority.releaseRevision === releaseRevision) {
|
|
164
|
+
markStateSqliteCutoverReady(statePath("state.sqlite"));
|
|
165
|
+
return { authority, reimportLegacy: false };
|
|
166
|
+
}
|
|
167
|
+
if (authority?.mode === "fencing") throw new Error("hot-state cutover cannot replace an active rollback fence");
|
|
168
|
+
if (authority?.mode !== "preparing" || authority.releaseRevision !== releaseRevision) {
|
|
169
|
+
authority = publishHotStateAuthority(directory, "preparing", releaseRevision);
|
|
170
|
+
}
|
|
171
|
+
const { hotStateMigrationApplied, hotStateMigrationDryRun } = await import("@/lib/state/hotStateMigration");
|
|
172
|
+
if (hotStateMigrationApplied()) {
|
|
173
|
+
markStateSqliteCutoverReady(statePath("state.sqlite"));
|
|
174
|
+
return { authority, reimportLegacy: false };
|
|
175
|
+
}
|
|
176
|
+
const pollMs = options.pollMs ?? RELEASE_ACTIVATION_POLL_MS;
|
|
177
|
+
const stablePolls = options.stablePolls ?? HOT_STATE_CUTOVER_STABLE_POLLS;
|
|
178
|
+
const maxPolls = options.maxPolls ?? HOT_STATE_CUTOVER_MAX_POLLS;
|
|
179
|
+
const schedule = options.schedule ?? ((callback, delayMs) => setTimeout(callback, delayMs));
|
|
180
|
+
const signature = options.legacySignature ?? legacyHotStateSignature;
|
|
181
|
+
let previous = signature();
|
|
182
|
+
let stable = 0;
|
|
183
|
+
for (let poll = 0; poll < maxPolls; poll += 1) {
|
|
184
|
+
await new Promise<void>((resolve) => schedule(resolve, pollMs).unref?.());
|
|
185
|
+
if (!isCurrent()) throw new Error("viewer release lost traffic during hot-state cutover");
|
|
186
|
+
const current = signature();
|
|
187
|
+
stable = current === previous ? stable + 1 : 0;
|
|
188
|
+
previous = current;
|
|
189
|
+
if (stable >= stablePolls) {
|
|
190
|
+
hotStateMigrationDryRun();
|
|
191
|
+
markStateSqliteCutoverReady(statePath("state.sqlite"));
|
|
192
|
+
return { authority, reimportLegacy: true };
|
|
193
|
+
}
|
|
194
|
+
}
|
|
195
|
+
throw new Error("legacy hot-state files did not quiesce during release cutover");
|
|
196
|
+
}
|
|
197
|
+
|
|
198
|
+
/** Run stateful startup immediately for the current release. A deployment
|
|
199
|
+
* candidate polls the durable target and activates once promotion appoints it. */
|
|
200
|
+
export async function activateViewerRuntimeWhenCurrent(
|
|
201
|
+
activate: () => Promise<void>,
|
|
202
|
+
isCurrent: () => boolean,
|
|
203
|
+
options: ViewerReleaseActivationOptions = {},
|
|
204
|
+
): Promise<void> {
|
|
205
|
+
const pollMs = options.pollMs ?? RELEASE_ACTIVATION_POLL_MS;
|
|
206
|
+
const schedule = options.schedule ?? ((callback, delayMs) => setTimeout(callback, delayMs));
|
|
207
|
+
const log = options.log ?? console.error;
|
|
208
|
+
let started = false;
|
|
209
|
+
let demoted = false;
|
|
210
|
+
let fenceInProgress = false;
|
|
211
|
+
let fencedEpoch: number | null = null;
|
|
212
|
+
const monitor = () => {
|
|
213
|
+
if (demoted) return;
|
|
214
|
+
if (started && !isCurrent()) {
|
|
215
|
+
demoted = true;
|
|
216
|
+
void Promise.resolve(options.onDemoted?.({ fenced: fencedEpoch !== null })).catch((error) => {
|
|
217
|
+
log("[viewer release] demotion checkpoint failed", error);
|
|
218
|
+
});
|
|
219
|
+
return;
|
|
220
|
+
}
|
|
221
|
+
const fence = started ? options.fenceRequest?.() ?? null : null;
|
|
222
|
+
if (!fence || fence.mode !== "fencing") {
|
|
223
|
+
if (!fenceInProgress) fencedEpoch = null;
|
|
224
|
+
} else if (fencedEpoch !== fence.epoch && !fenceInProgress) {
|
|
225
|
+
fenceInProgress = true;
|
|
226
|
+
void Promise.resolve(options.onFenceRequested?.(fence)).then(() => {
|
|
227
|
+
fencedEpoch = fence.epoch;
|
|
228
|
+
}).catch((error) => {
|
|
229
|
+
log("[viewer release] hot-state fence checkpoint failed", error);
|
|
230
|
+
}).finally(() => {
|
|
231
|
+
fenceInProgress = false;
|
|
232
|
+
});
|
|
233
|
+
}
|
|
234
|
+
schedule(monitor, pollMs).unref?.();
|
|
235
|
+
};
|
|
236
|
+
const start = async () => {
|
|
237
|
+
if (started) return;
|
|
238
|
+
started = true;
|
|
239
|
+
schedule(monitor, pollMs).unref?.();
|
|
240
|
+
await activate();
|
|
241
|
+
};
|
|
242
|
+
if (isCurrent()) {
|
|
243
|
+
await start();
|
|
244
|
+
return;
|
|
245
|
+
}
|
|
246
|
+
const poll = () => {
|
|
247
|
+
if (started) return;
|
|
248
|
+
if (!isCurrent()) {
|
|
249
|
+
schedule(poll, pollMs).unref?.();
|
|
250
|
+
return;
|
|
251
|
+
}
|
|
252
|
+
void start().catch((error) => log("[viewer release] deferred runtime activation failed", error));
|
|
253
|
+
};
|
|
254
|
+
schedule(poll, pollMs).unref?.();
|
|
255
|
+
}
|
|
256
|
+
|
|
257
|
+
export function accountControllerDelayMs(env: Readonly<Record<string, string | undefined>> = process.env): number {
|
|
258
|
+
const configured = Number(env.LLV_ACCOUNT_CONTROLLER_DELAY_MS ?? 0);
|
|
259
|
+
return Number.isFinite(configured) ? Math.max(0, configured) : 0;
|
|
260
|
+
}
|
|
261
|
+
|
|
262
|
+
export function scheduleAccountMigrationController(start: () => Promise<void>, delayMs: number): void {
|
|
263
|
+
const run = () => {
|
|
264
|
+
start().catch((error) => { console.error("[account migration controller] initial durable reconciliation failed", error); });
|
|
265
|
+
};
|
|
266
|
+
const timer = setTimeout(() => {
|
|
267
|
+
if (delayMs > 0) run();
|
|
268
|
+
// A second zero-delay timer gives already queued readiness probes a turn.
|
|
269
|
+
else setTimeout(run, 0).unref?.();
|
|
270
|
+
}, delayMs);
|
|
271
|
+
timer.unref?.();
|
|
272
|
+
}
|
|
273
|
+
|
|
274
|
+
export async function completeViewerReleaseDemotion(
|
|
275
|
+
checkpoint: () => void | Promise<void>,
|
|
276
|
+
exit: (code: number) => unknown = (code) => process.exit(code),
|
|
277
|
+
log: (...args: unknown[]) => void = console.error,
|
|
278
|
+
releaseStructuredHosts: () => Promise<unknown> = async () => {
|
|
279
|
+
const { releaseStructuredDeliveryHostsForDemotion } = await import("@/lib/runtime/structuredDeliveryController");
|
|
280
|
+
await releaseStructuredDeliveryHostsForDemotion();
|
|
281
|
+
},
|
|
282
|
+
): Promise<void> {
|
|
283
|
+
let failure: unknown = null;
|
|
284
|
+
try {
|
|
285
|
+
await releaseStructuredHosts();
|
|
286
|
+
} catch (error) {
|
|
287
|
+
failure = error;
|
|
288
|
+
}
|
|
289
|
+
try {
|
|
290
|
+
await checkpoint();
|
|
291
|
+
} catch (error) {
|
|
292
|
+
failure ??= error;
|
|
293
|
+
}
|
|
294
|
+
if (failure) {
|
|
295
|
+
log("[viewer release] demotion cleanup failed", failure);
|
|
296
|
+
exit(1);
|
|
297
|
+
return;
|
|
298
|
+
}
|
|
299
|
+
exit(0);
|
|
300
|
+
}
|
|
301
|
+
|
|
302
|
+
export async function checkpointHotStateRollbackMirrorsForDemotion(): Promise<HotStateCheckpoint["revisions"]> {
|
|
303
|
+
const [flows, pipelines, workflows] = await Promise.all([
|
|
304
|
+
import("@/lib/flows/store"),
|
|
305
|
+
import("@/lib/pipelines/store"),
|
|
306
|
+
import("@/lib/workflows/store"),
|
|
307
|
+
]);
|
|
308
|
+
const flowRevision = await flows.checkpointFlowRollbackMirrorForDemotionAsync();
|
|
309
|
+
const pipelineRevisions = await pipelines.checkpointPipelineRollbackMirrorsForDemotionAsync();
|
|
310
|
+
const workflowRevision = await workflows.checkpointWorkflowRollbackMirrorForDemotionAsync();
|
|
311
|
+
return {
|
|
312
|
+
flows: flowRevision,
|
|
313
|
+
pipelines: pipelineRevisions.pipelines,
|
|
314
|
+
pipelinesArchive: pipelineRevisions.pipelinesArchive,
|
|
315
|
+
workflows: workflowRevision,
|
|
316
|
+
};
|
|
317
|
+
}
|
|
318
|
+
|
|
319
|
+
export async function initializeHotStateStoresAtStartup(
|
|
320
|
+
boundary: HotStateCutoverBoundary = { authority: null, reimportLegacy: false },
|
|
321
|
+
options: { afterCollectionImport?: (collection: string) => void } = {},
|
|
322
|
+
): Promise<HotStateAuthority | null> {
|
|
323
|
+
const [flows, pipelines, workflows] = await Promise.all([
|
|
324
|
+
import("@/lib/flows/store"),
|
|
325
|
+
import("@/lib/pipelines/store"),
|
|
326
|
+
import("@/lib/workflows/store"),
|
|
327
|
+
]);
|
|
328
|
+
initializeStateCollections(statePath("state.sqlite"), [
|
|
329
|
+
flows.flowStateCollectionSeed(),
|
|
330
|
+
...pipelines.pipelineStateCollectionSeeds(),
|
|
331
|
+
workflows.workflowStateCollectionSeed(),
|
|
332
|
+
], {
|
|
333
|
+
reimportExisting: boundary.reimportLegacy,
|
|
334
|
+
...(options.afterCollectionImport ? { afterCollectionImport: options.afterCollectionImport } : {}),
|
|
335
|
+
});
|
|
336
|
+
flows.loadFlows();
|
|
337
|
+
pipelines.loadPipelines();
|
|
338
|
+
pipelines.loadArchivedPipelines();
|
|
339
|
+
workflows.loadWorkflows();
|
|
340
|
+
if (boundary.authority?.mode === "preparing") {
|
|
341
|
+
return completeHotStatePreparation(path.dirname(statePath("state.sqlite")), boundary.authority);
|
|
342
|
+
}
|
|
343
|
+
return boundary.authority;
|
|
344
|
+
}
|
|
345
|
+
|
|
346
|
+
export async function startCurrentReleaseControllers(
|
|
347
|
+
env: Readonly<Record<string, string | undefined>> = process.env,
|
|
348
|
+
loaders: CurrentReleaseControllerLoaders = {
|
|
349
|
+
loadFlowPipelineController: () => import("@/lib/pipelines/controller"),
|
|
350
|
+
loadAccountMigrationController: () => import("@/lib/accounts/migration/controller"),
|
|
351
|
+
loadTelegramReportScheduler: () => import("@/lib/telegram/reportRunner"),
|
|
352
|
+
loadTelegramConnectorBoot: () => import("@/lib/telegram/connectorBoot"),
|
|
353
|
+
loadStructuredHostRetirement: () => import("@/lib/runtime/structuredHostRetirement"),
|
|
354
|
+
loadSeatTick: () => import("@/lib/monitor/seatTickController"),
|
|
355
|
+
},
|
|
356
|
+
): Promise<void> {
|
|
357
|
+
const { startFlowPipelineController } = await loaders.loadFlowPipelineController();
|
|
358
|
+
startFlowPipelineController();
|
|
359
|
+
/* The shared Telegram connector dies with the viewer container it is a child
|
|
360
|
+
of (#1133), and the supervisor only ever started one when a consumer asked
|
|
361
|
+
— so the Daily Report run after a restart was the thing that discovered it
|
|
362
|
+
was gone, and failed. The release that owns traffic brings it back for an
|
|
363
|
+
account that already has one. NOT awaited: verifying a connector takes
|
|
364
|
+
tens of seconds and the release-ready marker must not sit behind it. */
|
|
365
|
+
try {
|
|
366
|
+
const connector = await loaders.loadTelegramConnectorBoot?.();
|
|
367
|
+
if (connector) {
|
|
368
|
+
void connector.provisionTelegramConnectorAtStartup()
|
|
369
|
+
.catch((error) => console.error("[telegram connector] boot provisioning failed", error instanceof Error ? error.name : "unknown"));
|
|
370
|
+
}
|
|
371
|
+
} catch (error) {
|
|
372
|
+
console.error("[telegram connector] boot provisioning unavailable", error instanceof Error ? error.name : "unknown");
|
|
373
|
+
}
|
|
374
|
+
/* The Daily Report timer (#1086) belongs to the release that owns traffic,
|
|
375
|
+
like every other controller here. Starting it from the Telegram route
|
|
376
|
+
alone would mean a standalone Viewer nobody has opened in a browser runs
|
|
377
|
+
no report and catches up no missed slot. It is idempotent per process, and
|
|
378
|
+
a failure to start it must not take the other controllers down with it. */
|
|
379
|
+
try {
|
|
380
|
+
const telegram = await loaders.loadTelegramReportScheduler?.();
|
|
381
|
+
telegram?.ensureTelegramReportScheduler();
|
|
382
|
+
} catch (error) {
|
|
383
|
+
console.error("[telegram report] scheduler start failed", error instanceof Error ? error.name : "unknown");
|
|
384
|
+
}
|
|
385
|
+
/* Automatic structured host retirement (#747). It belongs to the release
|
|
386
|
+
that owns traffic for a stronger reason than the others: ownership of a
|
|
387
|
+
host and its live transports are process-scoped state of the process that
|
|
388
|
+
bound the delivery queue, so this is the only process that can answer the
|
|
389
|
+
predicate's questions or ask a host to shut down through its own
|
|
390
|
+
lifecycle. Started before the account-controller switch below, because
|
|
391
|
+
turning account migration off must not silently stop reclaiming hosts —
|
|
392
|
+
retirement has its own off switch (`LLV_HOST_RETIREMENT_IDLE_HOURS=0`). */
|
|
393
|
+
try {
|
|
394
|
+
const retirement = await loaders.loadStructuredHostRetirement?.();
|
|
395
|
+
retirement?.startStructuredHostRetirement();
|
|
396
|
+
} catch (error) {
|
|
397
|
+
console.error("[host retirement] sweep start failed", error instanceof Error ? error.name : "unknown");
|
|
398
|
+
}
|
|
399
|
+
/* The seat tick (#1245). It belongs here for the reason every controller
|
|
400
|
+
above does — one clock, in the release that owns traffic. Starting here
|
|
401
|
+
makes this the only process that starts a ticker, but not the only one that
|
|
402
|
+
is running one: this activation is reached once, and a promoted successor
|
|
403
|
+
leaves the predecessor alive with its timer armed. So the tick re-asks
|
|
404
|
+
`viewerReleaseOwnsTraffic` at the top of every sweep and stops its own clock
|
|
405
|
+
when the answer has turned, which is what makes a cross-process lock
|
|
406
|
+
unnecessary rather than merely omitted. A rotation hands the tick over with
|
|
407
|
+
nobody configuring anything, and a Viewer restart resumes it from the
|
|
408
|
+
durable stamps rather than from a timer that happened to survive. */
|
|
409
|
+
try {
|
|
410
|
+
const seatTick = await loaders.loadSeatTick?.();
|
|
411
|
+
seatTick?.startSeatTick();
|
|
412
|
+
} catch (error) {
|
|
413
|
+
console.error("[seat tick] start failed", error instanceof Error ? error.name : "unknown");
|
|
414
|
+
}
|
|
415
|
+
if (env.LLV_ACCOUNT_CONTROLLER_DISABLED === "1") return;
|
|
416
|
+
const { startAccountMigrationController } = await loaders.loadAccountMigrationController();
|
|
417
|
+
scheduleAccountMigrationController(startAccountMigrationController, accountControllerDelayMs(env));
|
|
418
|
+
}
|
|
419
|
+
|
|
420
|
+
export async function initializeOperatorSpawnCapabilityAtStartup(
|
|
421
|
+
env: Readonly<Record<string, string | undefined>> = process.env,
|
|
422
|
+
log: (line: string) => void = (line) => console.error(line),
|
|
423
|
+
): Promise<void> {
|
|
424
|
+
const { ensureOperatorSpawnCapability, rotateOperatorSpawnCapability } = await import("@/lib/agent/operatorCapability");
|
|
425
|
+
if (env.LLV_ROTATE_OPERATOR_SPAWN_CAPABILITY === "1") rotateOperatorSpawnCapability();
|
|
426
|
+
else ensureOperatorSpawnCapability();
|
|
427
|
+
|
|
428
|
+
/* NO KEY IS EMITTED, because none exists to emit. Rounds 9–10 printed an operator
|
|
429
|
+
session secret here — to `/dev/tty` or an inherited descriptor, never to captured
|
|
430
|
+
output — and the operator pasted it into the tab to unlock designation and voice.
|
|
431
|
+
That ceremony was rejected after use: it broke one-click manager and one-click
|
|
432
|
+
voice, and a reload put the tab back behind it. Same-origin is now the operator
|
|
433
|
+
(see `operatorAuthority`), so startup has nothing secret to hand anyone.
|
|
434
|
+
|
|
435
|
+
What remains is the AGENT capability on disk, ensured above: it identifies
|
|
436
|
+
workers, and identifying a worker is the one distinction still made. */
|
|
437
|
+
const port = env.PORT?.trim() || "8898";
|
|
438
|
+
log(`[viewer] Open http://127.0.0.1:${port}.`);
|
|
439
|
+
}
|
|
440
|
+
|
|
441
|
+
export async function startWakatimeIntegrationIfEnabled(
|
|
442
|
+
env: Readonly<Record<string, string | undefined>> = process.env,
|
|
443
|
+
start: () => Promise<void> = startWakatimeWorker,
|
|
444
|
+
log: (event: string, fields: Readonly<Record<string, never>>) => void = (event, fields) => console.error(event, fields),
|
|
445
|
+
): Promise<void> {
|
|
446
|
+
if (!wakatimeIntegrationEnabled(env)) return;
|
|
447
|
+
try {
|
|
448
|
+
await start();
|
|
449
|
+
} catch {
|
|
450
|
+
log("[wakatime] startup_failed", {});
|
|
451
|
+
}
|
|
452
|
+
}
|
|
453
|
+
|
|
454
|
+
export function runIdentityWaveMigrationWithoutBlockingStartup(
|
|
455
|
+
run: () => unknown,
|
|
456
|
+
log: (...args: unknown[]) => void = console.error,
|
|
457
|
+
options: {
|
|
458
|
+
maxAttempts?: number;
|
|
459
|
+
initialRetryMs?: number;
|
|
460
|
+
schedule?: (callback: () => void, delayMs: number) => ActivationTimer;
|
|
461
|
+
} = {},
|
|
462
|
+
): void {
|
|
463
|
+
const maxAttempts = Math.max(1, Math.floor(options.maxAttempts ?? 3));
|
|
464
|
+
const initialRetryMs = Math.max(0, options.initialRetryMs ?? 5_000);
|
|
465
|
+
const schedule = options.schedule ?? ((callback, delayMs) => setTimeout(callback, delayMs));
|
|
466
|
+
let attempts = 0;
|
|
467
|
+
const attempt = () => {
|
|
468
|
+
attempts += 1;
|
|
469
|
+
try {
|
|
470
|
+
run();
|
|
471
|
+
} catch (error) {
|
|
472
|
+
if (attempts >= maxAttempts) {
|
|
473
|
+
log("[identity-wave] registry migration failed; retry limit reached", { attempt: attempts, error });
|
|
474
|
+
return;
|
|
475
|
+
}
|
|
476
|
+
const retryInMs = initialRetryMs * (2 ** (attempts - 1));
|
|
477
|
+
log("[identity-wave] registry migration failed; retry scheduled", { attempt: attempts, retryInMs, error });
|
|
478
|
+
schedule(attempt, retryInMs).unref?.();
|
|
479
|
+
}
|
|
480
|
+
};
|
|
481
|
+
attempt();
|
|
482
|
+
}
|
|
483
|
+
|
|
484
|
+
async function startWakatimeWorker(): Promise<void> {
|
|
485
|
+
if (wakatimeWorkerStore.__llvWakatimeWorker) return;
|
|
486
|
+
const cwd = process.cwd();
|
|
487
|
+
const source = path.join(cwd, "src/lib/wakatimeSync.worker.ts");
|
|
488
|
+
const bundled = path.join(cwd, ".next/server/wakatime-sync-worker.js");
|
|
489
|
+
const bunContainer = "/usr/local/bin/bun-container";
|
|
490
|
+
const launch = fs.existsSync(source) && fs.existsSync(bunContainer)
|
|
491
|
+
? { executable: bunContainer, workerPath: source }
|
|
492
|
+
: fs.existsSync(bundled)
|
|
493
|
+
? {
|
|
494
|
+
executable: process.versions.bun ? process.execPath : (process.env.LLV_BUN_EXECUTABLE || "bun"),
|
|
495
|
+
workerPath: bundled,
|
|
496
|
+
}
|
|
497
|
+
: { executable: process.execPath, workerPath: source };
|
|
498
|
+
const { spawn } = await import("node:child_process");
|
|
499
|
+
const useNice = fs.existsSync("/usr/bin/nice");
|
|
500
|
+
const child = spawn(useNice ? "/usr/bin/nice" : launch.executable, [
|
|
501
|
+
...(useNice ? ["-n", "10", launch.executable] : []),
|
|
502
|
+
launch.workerPath,
|
|
503
|
+
], {
|
|
504
|
+
cwd,
|
|
505
|
+
stdio: ["ignore", "inherit", "inherit"],
|
|
506
|
+
env: {
|
|
507
|
+
...withoutWakatimeCredential(process.env),
|
|
508
|
+
LLV_WAKATIME_SYNC_WORKER: "1",
|
|
509
|
+
},
|
|
510
|
+
});
|
|
511
|
+
wakatimeWorkerStore.__llvWakatimeWorker = child;
|
|
512
|
+
child.once("error", (error) => {
|
|
513
|
+
console.error("[wakatime] worker_start_failed", { message: error.message });
|
|
514
|
+
});
|
|
515
|
+
child.once("exit", (code, signal) => {
|
|
516
|
+
if (wakatimeWorkerStore.__llvWakatimeWorker === child) {
|
|
517
|
+
wakatimeWorkerStore.__llvWakatimeWorker = undefined;
|
|
518
|
+
}
|
|
519
|
+
if (wakatimeWorkerStore.__llvWakatimeWorkerRestart) return;
|
|
520
|
+
console.error("[wakatime] worker_exited", { code, signal });
|
|
521
|
+
const timer = setTimeout(() => {
|
|
522
|
+
wakatimeWorkerStore.__llvWakatimeWorkerRestart = undefined;
|
|
523
|
+
void startWakatimeWorker();
|
|
524
|
+
}, WAKATIME_WORKER_RESTART_MS);
|
|
525
|
+
timer.unref?.();
|
|
526
|
+
wakatimeWorkerStore.__llvWakatimeWorkerRestart = timer;
|
|
527
|
+
});
|
|
528
|
+
}
|
|
529
|
+
|
|
530
|
+
export type StructuredHostStartupErrorCategory =
|
|
531
|
+
| "runtime-host-unavailable"
|
|
532
|
+
| "timeout"
|
|
533
|
+
| "registry-contention"
|
|
534
|
+
| "transient-io"
|
|
535
|
+
| "instrumentation-order"
|
|
536
|
+
| "configuration"
|
|
537
|
+
| "data-corruption"
|
|
538
|
+
| "unknown-recoverable";
|
|
539
|
+
|
|
540
|
+
export interface StructuredHostStartupErrorClassification {
|
|
541
|
+
disposition: "recoverable" | "terminal";
|
|
542
|
+
category: StructuredHostStartupErrorCategory;
|
|
543
|
+
action: string;
|
|
544
|
+
}
|
|
545
|
+
|
|
546
|
+
const TRANSIENT_IO_CODES = new Set([
|
|
547
|
+
"EAGAIN",
|
|
548
|
+
"EBUSY",
|
|
549
|
+
"ECONNREFUSED",
|
|
550
|
+
"ECONNRESET",
|
|
551
|
+
"EINTR",
|
|
552
|
+
"EIO",
|
|
553
|
+
"EMFILE",
|
|
554
|
+
"ENFILE",
|
|
555
|
+
"ENOENT",
|
|
556
|
+
]);
|
|
557
|
+
const DATA_CORRUPTION_CODES = new Set(["SQLITE_CORRUPT", "SQLITE_NOTADB"]);
|
|
558
|
+
|
|
559
|
+
function startupErrorField(error: unknown, field: "code" | "name" | "message"): string {
|
|
560
|
+
if (typeof error !== "object" || error === null || !(field in error)) return "";
|
|
561
|
+
const value = error[field as keyof typeof error];
|
|
562
|
+
return typeof value === "string" ? value : "";
|
|
563
|
+
}
|
|
564
|
+
|
|
565
|
+
/** Known configuration and durable-data failures stop with repair guidance.
|
|
566
|
+
The fallback class stays recoverable so an unexpected dependency blip
|
|
567
|
+
cannot permanently remove delivery from a live Viewer process. */
|
|
568
|
+
export function classifyStructuredHostStartupError(
|
|
569
|
+
error: unknown,
|
|
570
|
+
): StructuredHostStartupErrorClassification {
|
|
571
|
+
const name = startupErrorField(error, "name");
|
|
572
|
+
const code = startupErrorField(error, "code");
|
|
573
|
+
const message = startupErrorField(error, "message");
|
|
574
|
+
if (error instanceof StructuredRuntimeRequirementError || name === "StructuredRuntimeRequirementError") {
|
|
575
|
+
return {
|
|
576
|
+
disposition: "terminal",
|
|
577
|
+
category: "configuration",
|
|
578
|
+
action: "Correct the structured-host configuration and restart the Viewer.",
|
|
579
|
+
};
|
|
580
|
+
}
|
|
581
|
+
if (name === "RegistryParityError"
|
|
582
|
+
|| name === "RegistryBackendIdentityError"
|
|
583
|
+
|| DATA_CORRUPTION_CODES.has(code)
|
|
584
|
+
|| /corrupt .* SQLite row|SQLite row is malformed|schema is unsupported/i.test(message)) {
|
|
585
|
+
return {
|
|
586
|
+
disposition: "terminal",
|
|
587
|
+
category: "data-corruption",
|
|
588
|
+
action: "Repair or restore the reported state data, then restart the Viewer.",
|
|
589
|
+
};
|
|
590
|
+
}
|
|
591
|
+
if (code === "structured-delivery-controller-unavailable") {
|
|
592
|
+
return {
|
|
593
|
+
disposition: "recoverable",
|
|
594
|
+
category: "instrumentation-order",
|
|
595
|
+
action: "Retry after the process controller publication becomes visible.",
|
|
596
|
+
};
|
|
597
|
+
}
|
|
598
|
+
if (code === "ETIMEDOUT" || /\btimed out\b/i.test(message)) {
|
|
599
|
+
return {
|
|
600
|
+
disposition: "recoverable",
|
|
601
|
+
category: "timeout",
|
|
602
|
+
action: "Retry after the dependency response window.",
|
|
603
|
+
};
|
|
604
|
+
}
|
|
605
|
+
if (name === "FileTransactionBusyError") {
|
|
606
|
+
return {
|
|
607
|
+
disposition: "recoverable",
|
|
608
|
+
category: "registry-contention",
|
|
609
|
+
action: "Retry after the active registry transaction releases its lock.",
|
|
610
|
+
};
|
|
611
|
+
}
|
|
612
|
+
if (TRANSIENT_IO_CODES.has(code)) {
|
|
613
|
+
return {
|
|
614
|
+
disposition: "recoverable",
|
|
615
|
+
category: "transient-io",
|
|
616
|
+
action: "Retry after the local I/O dependency recovers.",
|
|
617
|
+
};
|
|
618
|
+
}
|
|
619
|
+
if (error instanceof RuntimeHostUnavailableError
|
|
620
|
+
|| /^runtime host (?:is unavailable|request cancelled|response exceeds limit|returned invalid JSON|response id mismatch)$/i.test(message)) {
|
|
621
|
+
return {
|
|
622
|
+
disposition: "recoverable",
|
|
623
|
+
category: "runtime-host-unavailable",
|
|
624
|
+
action: "Retry after the runtime host becomes available.",
|
|
625
|
+
};
|
|
626
|
+
}
|
|
627
|
+
return {
|
|
628
|
+
disposition: "recoverable",
|
|
629
|
+
category: "unknown-recoverable",
|
|
630
|
+
action: "Retry with bounded backoff while the Viewer remains unavailable for structured delivery.",
|
|
631
|
+
};
|
|
632
|
+
}
|
|
633
|
+
|
|
634
|
+
export async function runStructuredHostStartup(
|
|
635
|
+
adopt: () => Promise<unknown>,
|
|
636
|
+
log: (...args: unknown[]) => void = console.error,
|
|
637
|
+
options: StructuredHostStartupOptions = {},
|
|
638
|
+
): Promise<void> {
|
|
639
|
+
const schedule = options.schedule ?? ((callback, delayMs) => setTimeout(callback, delayMs));
|
|
640
|
+
const maxRetryMs = options.maxRetryMs ?? 1_000;
|
|
641
|
+
const jitterRatio = Math.min(Math.max(options.jitterRatio ?? 0.2, 0), 1);
|
|
642
|
+
const random = options.random ?? Math.random;
|
|
643
|
+
let retryMs = options.initialRetryMs ?? 100;
|
|
644
|
+
let retryPending = false;
|
|
645
|
+
let attempts = 0;
|
|
646
|
+
let resolveReady: (() => void) | null = null;
|
|
647
|
+
let rejectReady: ((error: unknown) => void) | null = null;
|
|
648
|
+
const ready = options.waitUntilReady
|
|
649
|
+
? new Promise<void>((resolve, reject) => { resolveReady = resolve; rejectReady = reject; })
|
|
650
|
+
: null;
|
|
651
|
+
|
|
652
|
+
const attempt = async (): Promise<void> => {
|
|
653
|
+
attempts += 1;
|
|
654
|
+
try {
|
|
655
|
+
options.signal?.throwIfAborted();
|
|
656
|
+
await adopt();
|
|
657
|
+
options.signal?.throwIfAborted();
|
|
658
|
+
markStructuredHostStartupReady();
|
|
659
|
+
resolveReady?.();
|
|
660
|
+
if (attempts > 1) log("[structured hosts] startup adoption recovered", { attempts });
|
|
661
|
+
} catch (error) {
|
|
662
|
+
markStructuredHostStartupFailed();
|
|
663
|
+
if (options.signal?.aborted) {
|
|
664
|
+
rejectReady?.(error);
|
|
665
|
+
throw error;
|
|
666
|
+
}
|
|
667
|
+
const classification = classifyStructuredHostStartupError(error);
|
|
668
|
+
if (classification.disposition === "terminal") {
|
|
669
|
+
log("[structured hosts] startup adoption failed", error, {
|
|
670
|
+
category: classification.category,
|
|
671
|
+
action: classification.action,
|
|
672
|
+
});
|
|
673
|
+
rejectReady?.(error);
|
|
674
|
+
throw error;
|
|
675
|
+
}
|
|
676
|
+
if (retryPending) return;
|
|
677
|
+
const jitter = 1 + ((Math.min(Math.max(random(), 0), 1) * 2) - 1) * jitterRatio;
|
|
678
|
+
const delayMs = Math.min(maxRetryMs, Math.max(0, Math.round(retryMs * jitter)));
|
|
679
|
+
retryMs = Math.min(retryMs * 2, maxRetryMs);
|
|
680
|
+
retryPending = true;
|
|
681
|
+
if (attempts === 1) log("[structured hosts] startup adoption failed; retry scheduled", error);
|
|
682
|
+
schedule(() => {
|
|
683
|
+
retryPending = false;
|
|
684
|
+
void attempt().catch((retryError) => {
|
|
685
|
+
log("[structured hosts] startup adoption retry aborted", retryError);
|
|
686
|
+
});
|
|
687
|
+
}, delayMs).unref?.();
|
|
688
|
+
}
|
|
689
|
+
};
|
|
690
|
+
|
|
691
|
+
const aborted = () => {
|
|
692
|
+
markStructuredHostStartupFailed();
|
|
693
|
+
// An executing attempt must settle before retirement can checkpoint.
|
|
694
|
+
if (retryPending) rejectReady?.(options.signal?.reason);
|
|
695
|
+
};
|
|
696
|
+
options.signal?.addEventListener("abort", aborted, { once: true });
|
|
697
|
+
|
|
698
|
+
if (ready) {
|
|
699
|
+
try { await Promise.all([attempt(), ready]); }
|
|
700
|
+
finally { options.signal?.removeEventListener("abort", aborted); }
|
|
701
|
+
return;
|
|
702
|
+
}
|
|
703
|
+
await attempt();
|
|
704
|
+
}
|
|
705
|
+
|
|
706
|
+
export async function completeViewerRuntimeActivation(
|
|
707
|
+
steps: ViewerRuntimeActivationSteps,
|
|
708
|
+
): Promise<void> {
|
|
709
|
+
await steps.initializeOperatorCapability();
|
|
710
|
+
await steps.runIdentityMigration?.();
|
|
711
|
+
await steps.startWakatime();
|
|
712
|
+
steps.publishHotStateActivation();
|
|
713
|
+
steps.startStructuredHosts?.();
|
|
714
|
+
await steps.startControllers();
|
|
715
|
+
steps.publishViewerReleaseReady();
|
|
716
|
+
}
|
|
717
|
+
|
|
718
|
+
/** The full node-runtime startup sequence `src/instrumentation.ts` defers to. */
|
|
719
|
+
export async function registerViewerRuntime(): Promise<void> {
|
|
720
|
+
discardWakatimeEnvironmentCredential();
|
|
721
|
+
const isCurrent = () => viewerReleaseOwnsTraffic();
|
|
722
|
+
const hotStateDirectory = path.dirname(statePath("state.sqlite"));
|
|
723
|
+
const releaseRevision = () => hotStateWriterRevision(hotStateDirectory);
|
|
724
|
+
let activatedReleaseRevision: string | null = null;
|
|
725
|
+
const startupAbort = new AbortController();
|
|
726
|
+
let startup: Promise<void> | null = null;
|
|
727
|
+
const quiesceStartup = async () => {
|
|
728
|
+
startupAbort.abort(new Error("structured startup retired by release handover"));
|
|
729
|
+
await startup?.catch(() => {});
|
|
730
|
+
};
|
|
731
|
+
const assertStartupActive = () => {
|
|
732
|
+
// Observe durable retirement at every phase/batch boundary, including
|
|
733
|
+
// before the monitor's next poll and after an awaited transcript refresh.
|
|
734
|
+
if (!isCurrent() || readHotStateAuthority(hotStateDirectory)?.mode === "fencing") {
|
|
735
|
+
startupAbort.abort(new Error("structured startup lost release authority"));
|
|
736
|
+
}
|
|
737
|
+
startupAbort.signal.throwIfAborted();
|
|
738
|
+
};
|
|
739
|
+
const releaseHosts = async () => {
|
|
740
|
+
const { releaseUnpublishedStartupHostsForDemotion } = await import("@/lib/runtime/startup");
|
|
741
|
+
await releaseUnpublishedStartupHostsForDemotion();
|
|
742
|
+
const { releaseStructuredDeliveryHostsForDemotion } = await import("@/lib/runtime/structuredDeliveryController");
|
|
743
|
+
await releaseStructuredDeliveryHostsForDemotion();
|
|
744
|
+
};
|
|
745
|
+
await activateViewerRuntimeWhenCurrent(async () => {
|
|
746
|
+
const boundary = await establishHotStateCutoverBoundary(isCurrent);
|
|
747
|
+
activatedReleaseRevision = boundary.authority?.releaseRevision ?? null;
|
|
748
|
+
const authority = await initializeHotStateStoresAtStartup(boundary);
|
|
749
|
+
let activatedAuthority: HotStateAuthority | null = null;
|
|
750
|
+
await completeViewerRuntimeActivation({
|
|
751
|
+
initializeOperatorCapability: initializeOperatorSpawnCapabilityAtStartup,
|
|
752
|
+
runIdentityMigration: async () => {
|
|
753
|
+
const { runIdentityWaveMigrationAtStartup } = await import("@/lib/agent/identityWaveStartup");
|
|
754
|
+
runIdentityWaveMigrationWithoutBlockingStartup(runIdentityWaveMigrationAtStartup);
|
|
755
|
+
},
|
|
756
|
+
startWakatime: startWakatimeIntegrationIfEnabled,
|
|
757
|
+
startStructuredHosts: structuredHostsEnabled()
|
|
758
|
+
? () => {
|
|
759
|
+
startup = (async () => {
|
|
760
|
+
const { adoptStructuredHostsAtStartup } = await import("@/lib/runtime/startup");
|
|
761
|
+
await runStructuredHostStartup(
|
|
762
|
+
() => adoptStructuredHostsAtStartup({ assertActive: assertStartupActive }),
|
|
763
|
+
console.error, { waitUntilReady: true, signal: startupAbort.signal },
|
|
764
|
+
);
|
|
765
|
+
})();
|
|
766
|
+
void startup.catch((error) => console.error("[structured hosts] background startup aborted", error));
|
|
767
|
+
}
|
|
768
|
+
: null,
|
|
769
|
+
startControllers: startCurrentReleaseControllers,
|
|
770
|
+
publishHotStateActivation: () => {
|
|
771
|
+
if (authority) activatedAuthority = markHotStateActivationReady(hotStateDirectory, authority);
|
|
772
|
+
},
|
|
773
|
+
publishViewerReleaseReady: () => {
|
|
774
|
+
if (activatedAuthority) markViewerReleaseReady(hotStateDirectory, activatedAuthority);
|
|
775
|
+
},
|
|
776
|
+
});
|
|
777
|
+
}, isCurrent, {
|
|
778
|
+
fenceRequest: () => {
|
|
779
|
+
const revision = releaseRevision();
|
|
780
|
+
const authority = readHotStateAuthority(hotStateDirectory);
|
|
781
|
+
return revision !== null
|
|
782
|
+
&& authority?.mode === "fencing"
|
|
783
|
+
&& authority.releaseRevision === revision
|
|
784
|
+
? authority
|
|
785
|
+
: null;
|
|
786
|
+
},
|
|
787
|
+
onFenceRequested: async (request) => {
|
|
788
|
+
await quiesceStartup();
|
|
789
|
+
await releaseHosts();
|
|
790
|
+
const revisions = await checkpointHotStateRollbackMirrorsForDemotion();
|
|
791
|
+
const { agentRegistry } = await import("@/lib/agent/registry");
|
|
792
|
+
agentRegistry().checkpointRollbackMirrorForDemotion();
|
|
793
|
+
acknowledgeHotStateFence(hotStateDirectory, request, revisions);
|
|
794
|
+
},
|
|
795
|
+
onDemoted: async ({ fenced }) => {
|
|
796
|
+
await quiesceStartup();
|
|
797
|
+
await completeViewerReleaseDemotion(async () => {
|
|
798
|
+
if (fenced) return;
|
|
799
|
+
const authority = readHotStateAuthority(hotStateDirectory);
|
|
800
|
+
if (!activatedReleaseRevision
|
|
801
|
+
|| authority?.releaseRevision !== activatedReleaseRevision
|
|
802
|
+
|| (authority.mode !== "sqlite" && authority.mode !== "fencing")) return;
|
|
803
|
+
const { agentRegistry } = await import("@/lib/agent/registry");
|
|
804
|
+
await checkpointHotStateRollbackMirrorsForDemotion();
|
|
805
|
+
agentRegistry().checkpointRollbackMirrorForDemotion();
|
|
806
|
+
}, undefined, undefined, releaseHosts);
|
|
807
|
+
},
|
|
808
|
+
});
|
|
809
|
+
}
|