specrails-desktop 2.55.0 → 2.55.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/cli/dist/args.js +80 -0
- package/cli/dist/desktop-client.js +125 -0
- package/cli/dist/desktop-control.js +339 -0
- package/cli/dist/format.js +45 -0
- package/cli/dist/help.js +68 -0
- package/cli/dist/output.js +47 -0
- package/cli/dist/run-command.js +340 -0
- package/cli/dist/specrails-desktop.js +41 -1107
- package/cli/dist/status.js +111 -0
- package/client/dist/assets/{ActivityFeedPage-ILXMZXcb.js → ActivityFeedPage-DmJcQpNe.js} +1 -1
- package/client/dist/assets/{AgentBrowserCapture-UcsupCy7.js → AgentBrowserCapture-NxBHrU-V.js} +1 -1
- package/client/dist/assets/{AgentModeAnalyticsPane-CQuxYh8B.js → AgentModeAnalyticsPane-CGAKTJfU.js} +2 -2
- package/client/dist/assets/{AgentModeCodePane-zPWbW7ei.js → AgentModeCodePane-DNSs5_oe.js} +2 -2
- package/client/dist/assets/{AgentModeJobsPane-CInByIdl.js → AgentModeJobsPane-DLoVYDnG.js} +1 -1
- package/client/dist/assets/{AgentsPage-BWvgxaBv.js → AgentsPage-CAzMn9Gg.js} +1 -1
- package/client/dist/assets/{AnalyticsPage-DP3jakv-.js → AnalyticsPage-C06KT4Y0.js} +1 -1
- package/client/dist/assets/{CodePage-BKXiwE5a.js → CodePage-aX1mxGyT.js} +1 -1
- package/client/dist/assets/{DesktopAnalyticsPage-DryJOaMz.js → DesktopAnalyticsPage-BtscfiQD.js} +1 -1
- package/client/dist/assets/{DocsDialog-BsCG9ksG.js → DocsDialog-CNOcXhp-.js} +1 -1
- package/client/dist/assets/{DocsPage-Cc-GeKYl.js → DocsPage-C2BugxaI.js} +1 -1
- package/client/dist/assets/{ExportDropdown-ClahJdDn.js → ExportDropdown-BVGKEgkd.js} +1 -1
- package/client/dist/assets/{InteractiveJobComposer-DfLF6N0f.js → InteractiveJobComposer-CCncBqNu.js} +1 -1
- package/client/dist/assets/{JobDetailModal-DHeur9YK.js → JobDetailModal-Cn_k3-RM.js} +1 -1
- package/client/dist/assets/{JobDetailPage-CraDKzeG.js → JobDetailPage-BogJFBsk.js} +1 -1
- package/client/dist/assets/{JobsPage-CcbuSwj7.js → JobsPage-DL4E8ZyU.js} +1 -1
- package/client/dist/assets/{LoopBuilderPage-BKtNp494.js → LoopBuilderPage-9L6URQLY.js} +1 -1
- package/client/dist/assets/{LoopPreviewModal-DbZd9isy.js → LoopPreviewModal-CAPqTIgL.js} +1 -1
- package/client/dist/assets/{LoopsPage-DEg6sIkG.js → LoopsPage-aU8dYw7L.js} +1 -1
- package/client/dist/assets/{MinimizedChatsContext-BGtEjWsc.js → MinimizedChatsContext-D3QzgV0B.js} +1 -1
- package/client/dist/assets/{PluginsPage-BVqSsPzL.js → PluginsPage-D_tsW9B5.js} +1 -1
- package/client/dist/assets/{ProjectSettingsDialog-CAjLgJAZ.js → ProjectSettingsDialog-_ZbNuspP.js} +1 -1
- package/client/dist/assets/{RepositoryDeliveries-DrcrxLe0.js → RepositoryDeliveries-Du2UCf1a.js} +1 -1
- package/client/dist/assets/{RepositoryScopeSelector-CAGY3xW6.js → RepositoryScopeSelector-hPGZNRBm.js} +1 -1
- package/client/dist/assets/ReviewPacketPage-CG-Dv0El.js +4 -0
- package/client/dist/assets/{TemplatePreviewModal-Bqs-9fhn.js → TemplatePreviewModal-C19H2b2o.js} +1 -1
- package/client/dist/assets/{TicketDetailModalContext-C0jQ5yOk.js → TicketDetailModalContext-DAK-NoK6.js} +1 -1
- package/client/dist/assets/{Trans-DtWlCJN9.js → Trans-DEbgkuAY.js} +1 -1
- package/client/dist/assets/{dashboard-CTfEtkqX.js → dashboard-B9uWNGO2.js} +1 -1
- package/client/dist/assets/{dashboard-DMklepmz.js → dashboard-BIwmO9wc.js} +1 -1
- package/client/dist/assets/{dashboard-DBAP2_SQ.js → dashboard-BV4vOZkR.js} +1 -1
- package/client/dist/assets/{dashboard-D40HP2ks.js → dashboard-Bf6MPVsM.js} +1 -1
- package/client/dist/assets/{dashboard-Csf1yGSN.js → dashboard-C8klWVvZ.js} +1 -1
- package/client/dist/assets/{dashboard-C29Qwa-L.js → dashboard-D1ORhPF0.js} +1 -1
- package/client/dist/assets/{dashboard-Cr4D8oMn.js → dashboard-DSubvs9x.js} +1 -1
- package/client/dist/assets/{dashboard-CSJzf5OT.js → dashboard-px_vlRx_.js} +1 -1
- package/client/dist/assets/{formatDistanceToNow-DYmvOA3R.js → formatDistanceToNow-Cc2u5FwQ.js} +1 -1
- package/client/dist/assets/{getTimezoneOffsetInMilliseconds-BAhW5E6V.js → getTimezoneOffsetInMilliseconds-BHm2U-w1.js} +1 -1
- package/client/dist/assets/{index-BfAZg5DG.js → index-BcligJ3-.js} +29 -29
- package/client/dist/assets/index-C51x61Bz.css +2 -0
- package/client/dist/assets/{jira-api-B27Za5FP.js → jira-api-DrGxiD9p.js} +1 -1
- package/client/dist/assets/packet-8nn9RsU7.js +1 -0
- package/client/dist/assets/packet-B0H15elv.js +1 -0
- package/client/dist/assets/packet-BQvBgrwh.js +1 -0
- package/client/dist/assets/packet-BR7mO0-a.js +1 -0
- package/client/dist/assets/packet-BgcQ6q_K.js +1 -0
- package/client/dist/assets/packet-D2s92Jnn.js +1 -0
- package/client/dist/assets/packet-YbtcD1HS.js +1 -0
- package/client/dist/assets/packet-c0Qj_9eX.js +1 -0
- package/client/dist/assets/{project-repositories-DixIZHTA.js → project-repositories-9Wzs0coQ.js} +1 -1
- package/client/dist/assets/{spending-BGmZBX5B.js → spending-T5GM7wpn.js} +1 -1
- package/client/dist/assets/{useDesktop-CPB4cnwI.js → useDesktop-QogiN0zR.js} +1 -1
- package/client/dist/assets/{useRuntimeRuns-DEQ9HdAM.js → useRuntimeRuns-Dqmz9fS9.js} +1 -1
- package/client/dist/assets/{useSharedWebSocket-DcPRKR8R.js → useSharedWebSocket-Dz-HI6De.js} +2 -2
- package/client/dist/index.html +17 -17
- package/docs/codex.md +5 -5
- package/docs/customizing.md +1 -1
- package/docs/gemini-cli-provider-study.md +14 -14
- package/docs/gemini-core-support-evaluation.md +1 -1
- package/docs/gemini.md +5 -5
- package/docs/internals/README.md +6 -2
- package/docs/internals/adding-a-provider.md +15 -15
- package/docs/internals/agent-runtime-framework-evaluation.md +8 -8
- package/docs/internals/api-reference.md +2 -2
- package/docs/internals/architecture.md +9 -9
- package/docs/internals/browser-capture-performance.md +3 -3
- package/docs/internals/code-explorer-story.md +2 -2
- package/docs/internals/companion-rails-as-loops-contract.md +2 -2
- package/docs/internals/embedded-browser-native-webview-evaluation.md +5 -5
- package/docs/internals/gemini-mcp-registration.md +2 -2
- package/docs/internals/global-artifacts-alignment-contract.md +1 -1
- package/docs/internals/global-artifacts-relocation-evaluation.md +1 -1
- package/docs/internals/interactive-jobs.md +8 -8
- package/docs/internals/legacy-implementation-notes.md +722 -0
- package/docs/internals/loop-step-log-explorer.md +8 -8
- package/docs/internals/mission-rail-cards.md +14 -14
- package/docs/internals/modular-architecture.md +107 -0
- package/docs/internals/profiles.md +1 -1
- package/docs/internals/project-builder.md +18 -18
- package/docs/internals/review-packet.md +8 -8
- package/docs/internals/safe-pr-review-flow.md +11 -11
- package/docs/internals/source-architecture.md +131 -0
- package/docs/internals/source-map.md +1354 -0
- package/docs/internals/spec-addenda.md +65 -9
- package/docs/internals/switch-to-agent-mode-design.md +11 -11
- package/docs/tracking-cost.md +1 -1
- package/package.json +5 -2
- package/server/dist/agent-mcp-config.js +1 -1
- package/server/dist/attachment-manager.js +1 -1
- package/server/dist/build-dirs.js +2 -2
- package/server/dist/config.js +0 -3
- package/server/dist/core-completion.js +1 -1
- package/server/dist/core-execution.js +1 -1
- package/server/dist/db/activity.js +39 -0
- package/server/dist/db/connection.js +41 -0
- package/server/dist/db/conversations.js +48 -0
- package/server/dist/db/jobs.js +251 -0
- package/server/dist/db/migrations.js +1521 -0
- package/server/dist/db/proposals.js +50 -0
- package/server/dist/db/settings.js +15 -0
- package/server/dist/db/stats.js +61 -0
- package/server/dist/db/telemetry.js +56 -0
- package/server/dist/db/templates.js +37 -0
- package/server/dist/db/types.js +2 -0
- package/server/dist/db.js +66 -2224
- package/server/dist/desktop-db.js +3 -3
- package/server/dist/desktop-router.js +8 -8
- package/server/dist/git-diagnostics.js +1 -1
- package/server/dist/index.js +11 -11
- package/server/dist/integration-branch.js +3 -14
- package/server/dist/jira/jira-issue-fields.js +0 -1
- package/server/dist/jira/jira-materializer.js +1 -1
- package/server/dist/jira/jira-sync-manager.js +1 -1
- package/server/dist/mcp/mcp-admin-router.js +1 -1
- package/server/dist/mcp/mcp-server.js +1 -1
- package/server/dist/mcp/tools/jobs.js +1 -1
- package/server/dist/mcp/tools/rails.js +2 -2
- package/server/dist/mcp/tools/specs.js +2 -2
- package/server/dist/mcp/tools/types.js +3 -3
- package/server/dist/mobile/mobile-gateway.js +1 -1
- package/server/dist/mobile/mobile-missions.js +1 -1
- package/server/dist/{desktop-analytics.js → modules/accounting/runtime/desktop-analytics.js} +2 -2
- package/server/dist/{pricing.js → modules/accounting/runtime/pricing.js} +1 -1
- package/server/dist/{result-event.js → modules/accounting/runtime/result-event.js} +3 -3
- package/server/dist/{spending.js → modules/accounting/runtime/spending.js} +0 -3
- package/server/dist/{telemetry-compactor.js → modules/accounting/runtime/telemetry-compactor.js} +1 -1
- package/server/dist/{telemetry-receiver.js → modules/accounting/runtime/telemetry-receiver.js} +2 -2
- package/server/dist/{agent-runtime-bridge.js → modules/agent-runtime/runtime/agent-runtime-bridge.js} +2 -2
- package/server/dist/{agent-runtime-controls.js → modules/agent-runtime/runtime/agent-runtime-controls.js} +7 -7
- package/server/dist/{agent-runtime-effective-config.js → modules/agent-runtime/runtime/agent-runtime-effective-config.js} +1 -1
- package/server/dist/{agent-runtime-loader.js → modules/agent-runtime/runtime/agent-runtime-loader.js} +3 -3
- package/server/dist/{agent-runtime-paths.js → modules/agent-runtime/runtime/agent-runtime-paths.js} +1 -1
- package/server/dist/{agent-runtime-settings-router.js → modules/agent-runtime/runtime/agent-runtime-settings-router.js} +2 -2
- package/server/dist/{agent-runtime-settings.js → modules/agent-runtime/runtime/agent-runtime-settings.js} +3 -3
- package/server/dist/{agent-runtime-settlement.js → modules/agent-runtime/runtime/agent-runtime-settlement.js} +6 -6
- package/server/dist/{agent-defaults.js → modules/agents/runtime/agent-defaults.js} +3 -3
- package/server/dist/{agent-generator.js → modules/agents/runtime/agent-generator.js} +7 -7
- package/server/dist/{agent-refine-manager.js → modules/agents/runtime/agent-refine-manager.js} +5 -5
- package/server/dist/{agent-store.js → modules/agents/runtime/agent-store.js} +1 -1
- package/server/dist/{profile-manager.js → modules/agents/runtime/profile-manager.js} +2 -2
- package/server/dist/{profiles-router.js → modules/agents/runtime/profiles-router.js} +5 -5
- package/server/dist/{browser-capture-manager.js → modules/browser/runtime/browser-capture-manager.js} +2 -4
- package/server/dist/{browser-playwright.js → modules/browser/runtime/browser-playwright.js} +1 -1
- package/server/dist/{blueprint-chat-manager.js → modules/builder/runtime/blueprint-chat-manager.js} +7 -7
- package/server/dist/{blueprint-commit.js → modules/builder/runtime/blueprint-commit.js} +8 -8
- package/server/dist/{blueprint-draft-parser.js → modules/builder/runtime/blueprint-draft-parser.js} +1 -1
- package/server/dist/{blueprint-generation.js → modules/builder/runtime/blueprint-generation.js} +1 -1
- package/server/dist/{blueprint-operator-prompt.js → modules/builder/runtime/blueprint-operator-prompt.js} +1 -1
- package/server/dist/{blueprint-router.js → modules/builder/runtime/blueprint-router.js} +3 -3
- package/server/dist/{blueprint-spec-quality.js → modules/builder/runtime/blueprint-spec-quality.js} +1 -1
- package/server/dist/{milestone-chain.js → modules/builder/runtime/milestone-chain.js} +1 -1
- package/server/dist/{milestone-progress.js → modules/builder/runtime/milestone-progress.js} +6 -6
- package/server/dist/{code-activity.js → modules/code/runtime/code-activity.js} +1 -1
- package/server/dist/{code-explorer-router.js → modules/code/runtime/code-explorer-router.js} +5 -5
- package/server/dist/{file-provenance.js → modules/code/runtime/file-provenance.js} +1 -1
- package/server/dist/{file-story-manager.js → modules/code/runtime/file-story-manager.js} +2 -2
- package/server/dist/{file-story.js → modules/code/runtime/file-story.js} +2 -2
- package/server/dist/{file-summary-generator.js → modules/code/runtime/file-summary-generator.js} +3 -3
- package/server/dist/{file-summary-manager.js → modules/code/runtime/file-summary-manager.js} +3 -3
- package/server/dist/{project-code-discovery.js → modules/code/runtime/project-code-discovery.js} +2 -2
- package/server/dist/modules/conversations/domain/draft-stream.js +91 -0
- package/server/dist/modules/conversations/domain/recovery-context.js +101 -0
- package/server/dist/modules/conversations/index.js +10 -0
- package/server/dist/{chat-manager.js → modules/conversations/runtime/chat-manager.js} +32 -216
- package/server/dist/{context-budget.js → modules/conversations/runtime/context-budget.js} +1 -1
- package/server/dist/{explore-cwd-manager.js → modules/conversations/runtime/explore-cwd-manager.js} +1 -1
- package/server/dist/{explore-smash.js → modules/conversations/runtime/explore-smash.js} +1 -1
- package/server/dist/{explore-stdin-session.js → modules/conversations/runtime/explore-stdin-session.js} +1 -1
- package/server/dist/modules/delivery/adapters/decisions/chains.js +138 -0
- package/server/dist/modules/delivery/adapters/decisions/contracts.js +2 -0
- package/server/dist/modules/delivery/adapters/decisions/create.js +234 -0
- package/server/dist/modules/delivery/adapters/decisions/discard.js +251 -0
- package/server/dist/modules/delivery/adapters/decisions/dispatch.js +107 -0
- package/server/dist/modules/delivery/adapters/decisions/evidence.js +205 -0
- package/server/dist/modules/delivery/adapters/decisions/merge-local.js +338 -0
- package/server/dist/modules/delivery/adapters/decisions/metadata.js +109 -0
- package/server/dist/modules/delivery/adapters/decisions/observations.js +260 -0
- package/server/dist/modules/delivery/adapters/decisions/ownership.js +83 -0
- package/server/dist/modules/delivery/adapters/decisions/publish.js +242 -0
- package/server/dist/modules/delivery/adapters/decisions/recovery.js +425 -0
- package/server/dist/modules/delivery/adapters/decisions/retry.js +112 -0
- package/server/dist/modules/delivery/adapters/decisions/transitions.js +94 -0
- package/server/dist/modules/delivery/domain/decision-policy.js +50 -0
- package/server/dist/modules/delivery/domain/state.js +2 -0
- package/server/dist/modules/delivery/index.js +7 -0
- package/server/dist/{active-pr-continuation.js → modules/delivery/runtime/active-pr-continuation.js} +2 -2
- package/server/dist/{delivery-evidence.js → modules/delivery/runtime/delivery-evidence.js} +3 -3
- package/server/dist/{multi-repo-bases.js → modules/delivery/runtime/multi-repo-bases.js} +1 -1
- package/server/dist/{multi-repo-checkout.js → modules/delivery/runtime/multi-repo-checkout.js} +4 -4
- package/server/dist/{multi-repo-delivery.js → modules/delivery/runtime/multi-repo-delivery.js} +4 -4
- package/server/dist/{multi-repo-execution.js → modules/delivery/runtime/multi-repo-execution.js} +8 -8
- package/server/dist/{pr-body.js → modules/delivery/runtime/pr-body.js} +1 -1
- package/server/dist/{pr-follow-up-scope.js → modules/delivery/runtime/pr-follow-up-scope.js} +2 -2
- package/server/dist/{pr-follow-up.js → modules/delivery/runtime/pr-follow-up.js} +1 -1
- package/server/dist/{pr-naming.js → modules/delivery/runtime/pr-naming.js} +1 -1
- package/server/dist/{pr-publisher.js → modules/delivery/runtime/pr-publisher.js} +2 -2
- package/server/dist/{rail-isolated-launch.js → modules/delivery/runtime/rail-isolated-launch.js} +29 -27
- package/server/dist/{rail-launch-parser.js → modules/delivery/runtime/rail-launch-parser.js} +2 -2
- package/server/dist/{rail-merge-orchestrator.js → modules/delivery/runtime/rail-merge-orchestrator.js} +5 -5
- package/server/dist/modules/delivery/runtime/rail-pr-decision.js +12 -0
- package/server/dist/{rail-pr-delivery.js → modules/delivery/runtime/rail-pr-delivery.js} +1 -1
- package/server/dist/{rail-pr-store.js → modules/delivery/runtime/rail-pr-store.js} +2 -2
- package/server/dist/{rail-pr-ticket-effects.js → modules/delivery/runtime/rail-pr-ticket-effects.js} +3 -3
- package/server/dist/{rail-worktree-release.js → modules/delivery/runtime/rail-worktree-release.js} +4 -4
- package/server/dist/{rails-router.js → modules/delivery/runtime/rails-router.js} +66 -67
- package/server/dist/{review-packet.js → modules/delivery/runtime/review-packet.js} +3 -3
- package/server/dist/modules/execution/adapters/budget-storage.js +21 -0
- package/server/dist/modules/execution/adapters/usage-reader.js +38 -0
- package/server/dist/modules/execution/application/enforce-budget.js +14 -0
- package/server/dist/modules/execution/application/record-job-invocations.js +64 -0
- package/server/dist/modules/execution/application/recover-job-usage.js +200 -0
- package/server/dist/modules/execution/domain/job-accounting.js +2 -0
- package/server/dist/modules/execution/domain/scheduling.js +24 -0
- package/server/dist/modules/execution/domain/usage.js +21 -0
- package/server/dist/modules/execution/index.js +14 -0
- package/server/dist/modules/execution/ports.js +2 -0
- package/server/dist/{accept-ladder.js → modules/execution/runtime/accept-ladder.js} +1 -1
- package/server/dist/{interactive-job-session.js → modules/execution/runtime/interactive-job-session.js} +11 -11
- package/server/dist/{job-phase-breakdown.js → modules/execution/runtime/job-phase-breakdown.js} +1 -1
- package/server/dist/{queue-manager.js → modules/execution/runtime/queue-manager.js} +74 -491
- package/server/dist/{revision-seed.js → modules/execution/runtime/revision-seed.js} +1 -1
- package/server/dist/{spawn-lifecycle.js → modules/execution/runtime/spawn-lifecycle.js} +3 -3
- package/server/dist/{stuck-run-detector.js → modules/execution/runtime/stuck-run-detector.js} +1 -1
- package/server/dist/{loop-command-catalog.js → modules/loops/runtime/loop-command-catalog.js} +1 -1
- package/server/dist/{loop-executors.js → modules/loops/runtime/loop-executors.js} +17 -17
- package/server/dist/{loop-factory.js → modules/loops/runtime/loop-factory.js} +2 -21
- package/server/dist/{loop-graph.js → modules/loops/runtime/loop-graph.js} +25 -0
- package/server/dist/{loop-role-engines.js → modules/loops/runtime/loop-role-engines.js} +4 -4
- package/server/dist/{loop-run-manager.js → modules/loops/runtime/loop-run-manager.js} +101 -26
- package/server/dist/{loop-runs-store.js → modules/loops/runtime/loop-runs-store.js} +1 -1
- package/server/dist/{loop-shell-invocation.js → modules/loops/runtime/loop-shell-invocation.js} +2 -2
- package/server/dist/{loop-step-idle.js → modules/loops/runtime/loop-step-idle.js} +1 -1
- package/server/dist/{loop-templates.js → modules/loops/runtime/loop-templates.js} +24 -29
- package/server/dist/{loops-router.js → modules/loops/runtime/loops-router.js} +2 -2
- package/server/dist/{agent-chat-manager.js → modules/missions/runtime/agent-chat-manager.js} +19 -19
- package/server/dist/{agent-chat-router.js → modules/missions/runtime/agent-chat-router.js} +6 -6
- package/server/dist/{agent-context-resolver.js → modules/missions/runtime/agent-context-resolver.js} +8 -8
- package/server/dist/{agent-fence-promotion.js → modules/missions/runtime/agent-fence-promotion.js} +1 -1
- package/server/dist/{agent-input-store.js → modules/missions/runtime/agent-input-store.js} +1 -1
- package/server/dist/{agent-operator-prompt.js → modules/missions/runtime/agent-operator-prompt.js} +17 -7
- package/server/dist/{agent-spec-framing.js → modules/missions/runtime/agent-spec-framing.js} +4 -4
- package/server/dist/{agent-steering.js → modules/missions/runtime/agent-steering.js} +1 -1
- package/server/dist/{mission-run-notify.js → modules/missions/runtime/mission-run-notify.js} +1 -1
- package/server/dist/modules/project-settings/adapters/http.js +24 -0
- package/server/dist/modules/project-settings/adapters/sqlite.js +120 -0
- package/server/dist/modules/project-settings/application.js +11 -0
- package/server/dist/modules/project-settings/domain.js +95 -0
- package/server/dist/modules/project-settings/index.js +11 -0
- package/server/dist/modules/project-settings/ports.js +2 -0
- package/server/dist/{contract-refine-runner.js → modules/specs/runtime/contract-refine-runner.js} +12 -12
- package/server/dist/{proposal-manager.js → modules/specs/runtime/proposal-manager.js} +8 -8
- package/server/dist/{smash-runner.js → modules/specs/runtime/smash-runner.js} +26 -58
- package/server/dist/{spec-addenda-core.js → modules/specs/runtime/spec-addenda-core.js} +2 -2
- package/server/dist/{spec-addenda.js → modules/specs/runtime/spec-addenda.js} +3 -3
- package/server/dist/{spec-launcher-manager.js → modules/specs/runtime/spec-launcher-manager.js} +8 -8
- package/server/dist/{spec-models.js → modules/specs/runtime/spec-models.js} +1 -1
- package/server/dist/{ticket-watcher.js → modules/specs/runtime/ticket-watcher.js} +1 -1
- package/server/dist/{background-process-control.js → modules/terminals/runtime/background-process-control.js} +1 -1
- package/server/dist/{background-process-service.js → modules/terminals/runtime/background-process-service.js} +3 -3
- package/server/dist/{background-process-store.js → modules/terminals/runtime/background-process-store.js} +1 -1
- package/server/dist/{background-windows-bootstrap.js → modules/terminals/runtime/background-windows-bootstrap.js} +3 -3
- package/server/dist/{terminal-manager.js → modules/terminals/runtime/terminal-manager.js} +3 -3
- package/server/dist/project-git.js +1 -1
- package/server/dist/project-profile-support.js +32 -0
- package/server/dist/project-registry.js +34 -40
- package/server/dist/project-router-background-processes.js +1 -1
- package/server/dist/project-router-chat.js +6 -6
- package/server/dist/project-router-git.js +1 -1
- package/server/dist/project-router-helpers.js +2 -2
- package/server/dist/project-router-jobs.js +14 -12
- package/server/dist/project-router-loop-runs.js +12 -12
- package/server/dist/project-router-settings.js +15 -75
- package/server/dist/project-router-setup.js +2 -2
- package/server/dist/project-router-spending.js +4 -4
- package/server/dist/project-router-terminals.js +4 -4
- package/server/dist/project-router-tickets.js +14 -14
- package/server/dist/project-router.js +13 -13
- package/server/dist/providers/codex-adapter.js +3 -3
- package/server/dist/providers/gemini-adapter.js +1 -1
- package/server/dist/providers/telemetry-env.js +55 -0
- package/server/dist/runtime-role-prompts-router.js +2 -2
- package/server/dist/setup-manager.js +2 -48
- package/server/dist/shared/git-branch-name.js +16 -0
- package/server/dist/transient-children.js +3 -3
- package/server/dist/util/distribute-int.js +33 -0
- package/client/dist/assets/ReviewPacketPage-D-UjTef3.js +0 -4
- package/client/dist/assets/index-BAtqmAZR.css +0 -2
- package/client/dist/assets/packet-CjS_478C.js +0 -1
- package/client/dist/assets/packet-D69dKsHN.js +0 -1
- package/client/dist/assets/packet-D9rU6Oxo.js +0 -1
- package/client/dist/assets/packet-DMDFoamg.js +0 -1
- package/client/dist/assets/packet-Dd2RMs1h.js +0 -1
- package/client/dist/assets/packet-DjC9OibC.js +0 -1
- package/client/dist/assets/packet-DwPtJoDz.js +0 -1
- package/client/dist/assets/packet-ceahDg8_.js +0 -1
- package/server/dist/rail-pr-decision.js +0 -2377
- package/server/dist/ticket-broadcast.js +0 -47
- /package/server/dist/{ai-invocations.js → modules/accounting/runtime/ai-invocations.js} +0 -0
- /package/server/dist/{codex-otel-bridge.js → modules/accounting/runtime/codex-otel-bridge.js} +0 -0
- /package/server/dist/{metrics.js → modules/accounting/runtime/metrics.js} +0 -0
- /package/server/dist/{telemetry-export.js → modules/accounting/runtime/telemetry-export.js} +0 -0
- /package/server/dist/{agent-runtime-accounting.js → modules/agent-runtime/runtime/agent-runtime-accounting.js} +0 -0
- /package/server/dist/{agent-runtime-controls-router.js → modules/agent-runtime/runtime/agent-runtime-controls-router.js} +0 -0
- /package/server/dist/{agent-runtime-events.js → modules/agent-runtime/runtime/agent-runtime-events.js} +0 -0
- /package/server/dist/{agent-runtime-history.js → modules/agent-runtime/runtime/agent-runtime-history.js} +0 -0
- /package/server/dist/{agent-runtime-metrics.js → modules/agent-runtime/runtime/agent-runtime-metrics.js} +0 -0
- /package/server/dist/{agent-runtime-package.js → modules/agent-runtime/runtime/agent-runtime-package.js} +0 -0
- /package/server/dist/{agent-runtime-repositories.js → modules/agent-runtime/runtime/agent-runtime-repositories.js} +0 -0
- /package/server/dist/{agent-runtime-verification-suggestions.js → modules/agent-runtime/runtime/agent-runtime-verification-suggestions.js} +0 -0
- /package/server/dist/{agent-refine-db.js → modules/agents/runtime/agent-refine-db.js} +0 -0
- /package/server/dist/{browser-capture-types.js → modules/browser/runtime/browser-capture-types.js} +0 -0
- /package/server/dist/{browser-context-pool.js → modules/browser/runtime/browser-context-pool.js} +0 -0
- /package/server/dist/{browser-network.js → modules/browser/runtime/browser-network.js} +0 -0
- /package/server/dist/{browser-viewport.js → modules/browser/runtime/browser-viewport.js} +0 -0
- /package/server/dist/{blueprint-render.js → modules/builder/runtime/blueprint-render.js} +0 -0
- /package/server/dist/{blueprint-spec-fixtures.js → modules/builder/runtime/blueprint-spec-fixtures.js} +0 -0
- /package/server/dist/{blueprint-store.js → modules/builder/runtime/blueprint-store.js} +0 -0
- /package/server/dist/{blueprint-types.js → modules/builder/runtime/blueprint-types.js} +0 -0
- /package/server/dist/{builder-cwd-manager.js → modules/builder/runtime/builder-cwd-manager.js} +0 -0
- /package/server/dist/{milestone-chain-store.js → modules/builder/runtime/milestone-chain-store.js} +0 -0
- /package/server/dist/{changes-reader.js → modules/code/runtime/changes-reader.js} +0 -0
- /package/server/dist/{context-scope.js → modules/conversations/runtime/context-scope.js} +0 -0
- /package/server/dist/{explore-contract-refine.js → modules/conversations/runtime/explore-contract-refine.js} +0 -0
- /package/server/dist/{explore-draft-title.js → modules/conversations/runtime/explore-draft-title.js} +0 -0
- /package/server/dist/{merge-manager.js → modules/delivery/runtime/merge-manager.js} +0 -0
- /package/server/dist/{multi-repo-execution-store.js → modules/delivery/runtime/multi-repo-execution-store.js} +0 -0
- /package/server/dist/{pr-lifecycle.js → modules/delivery/runtime/pr-lifecycle.js} +0 -0
- /package/server/dist/{rail-isolation.js → modules/delivery/runtime/rail-isolation.js} +0 -0
- /package/server/dist/{rail-pr-recovery-git.js → modules/delivery/runtime/rail-pr-recovery-git.js} +0 -0
- /package/server/dist/{rail-worktrees-store.js → modules/delivery/runtime/rail-worktrees-store.js} +0 -0
- /package/server/dist/{rails-store.js → modules/delivery/runtime/rails-store.js} +0 -0
- /package/server/dist/{job-listing.js → modules/execution/runtime/job-listing.js} +0 -0
- /package/server/dist/{job-spawn-idempotency.js → modules/execution/runtime/job-spawn-idempotency.js} +0 -0
- /package/server/dist/{run-duration-stats.js → modules/execution/runtime/run-duration-stats.js} +0 -0
- /package/server/dist/{verification-sentinel.js → modules/execution/runtime/verification-sentinel.js} +0 -0
- /package/server/dist/{loop-constants.js → modules/loops/runtime/loop-constants.js} +0 -0
- /package/server/dist/{loop-decider.js → modules/loops/runtime/loop-decider.js} +0 -0
- /package/server/dist/{loop-effect.js → modules/loops/runtime/loop-effect.js} +0 -0
- /package/server/dist/{loop-preview.js → modules/loops/runtime/loop-preview.js} +0 -0
- /package/server/dist/{loop-templates-ported.js → modules/loops/runtime/loop-templates-ported.js} +0 -0
- /package/server/dist/{loops-store.js → modules/loops/runtime/loops-store.js} +0 -0
- /package/server/dist/{agent-chat-registry.js → modules/missions/runtime/agent-chat-registry.js} +0 -0
- /package/server/dist/{agent-cwd-manager.js → modules/missions/runtime/agent-cwd-manager.js} +0 -0
- /package/server/dist/{agent-failure-briefing.js → modules/missions/runtime/agent-failure-briefing.js} +0 -0
- /package/server/dist/{agent-tier.js → modules/missions/runtime/agent-tier.js} +0 -0
- /package/server/dist/{spec-contract-prompt.js → modules/specs/runtime/spec-contract-prompt.js} +0 -0
- /package/server/dist/{spec-draft-parser.js → modules/specs/runtime/spec-draft-parser.js} +0 -0
- /package/server/dist/{ticket-store.js → modules/specs/runtime/ticket-store.js} +0 -0
- /package/server/dist/{terminal-marks-store.js → modules/terminals/runtime/terminal-marks-store.js} +0 -0
- /package/server/dist/{terminal-osc-parser.js → modules/terminals/runtime/terminal-osc-parser.js} +0 -0
- /package/server/dist/{terminal-settings.js → modules/terminals/runtime/terminal-settings.js} +0 -0
|
@@ -3,151 +3,51 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
|
3
3
|
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
4
|
};
|
|
5
5
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
-
exports.QueueManager = exports.FREESTYLE_COMMAND_RE = exports.InvalidJobDependencyError = exports.JobAlreadyTerminalError = exports.JobNotFoundError = exports.CodexNotFoundError = exports.ClaudeNotFoundError = exports.DEFAULT_ZOMBIE_TIMEOUT_MS = void 0;
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
6
|
+
exports.QueueManager = exports.FREESTYLE_COMMAND_RE = exports.InvalidJobDependencyError = exports.JobAlreadyTerminalError = exports.JobNotFoundError = exports.CodexNotFoundError = exports.ClaudeNotFoundError = exports.DEFAULT_ZOMBIE_TIMEOUT_MS = exports.distributeIntEvenly = exports.projectSupportsProfiles = exports.buildTelemetryEnv = void 0;
|
|
7
|
+
const budget_storage_1 = require("../adapters/budget-storage");
|
|
8
|
+
const __1 = require("..");
|
|
9
|
+
const usage_reader_1 = require("../adapters/usage-reader");
|
|
10
|
+
const __2 = require("..");
|
|
10
11
|
const fs_1 = __importDefault(require("fs"));
|
|
11
12
|
const path_1 = __importDefault(require("path"));
|
|
12
13
|
const readline_1 = require("readline");
|
|
13
|
-
const ids_1 = require("
|
|
14
|
-
const win_spawn_1 = require("
|
|
15
|
-
const types_1 = require("
|
|
16
|
-
const
|
|
17
|
-
const
|
|
18
|
-
const
|
|
19
|
-
const
|
|
20
|
-
const
|
|
21
|
-
const
|
|
22
|
-
const
|
|
23
|
-
const
|
|
24
|
-
const
|
|
25
|
-
const result_event_1 = require("./result-event");
|
|
14
|
+
const ids_1 = require("../../../ids");
|
|
15
|
+
const win_spawn_1 = require("../../../util/win-spawn");
|
|
16
|
+
const types_1 = require("../../../types");
|
|
17
|
+
const rail_isolation_1 = require("../../delivery/runtime/rail-isolation");
|
|
18
|
+
const repo_map_1 = require("../../../repo-map");
|
|
19
|
+
const cli_prompt_1 = require("../../../util/cli-prompt");
|
|
20
|
+
const stream_display_1 = require("../../../util/stream-display");
|
|
21
|
+
const hooks_1 = require("../../../hooks");
|
|
22
|
+
const ai_invocations_1 = require("../../accounting/runtime/ai-invocations");
|
|
23
|
+
const feature_flags_1 = require("../../../feature-flags");
|
|
24
|
+
const file_provenance_1 = require("../../code/runtime/file-provenance");
|
|
25
|
+
const result_event_1 = require("../../accounting/runtime/result-event");
|
|
26
26
|
const crypto_1 = require("crypto");
|
|
27
|
-
const codex_spawn_1 = require("
|
|
28
|
-
const providers_1 = require("
|
|
29
|
-
const runtime_1 = require("
|
|
30
|
-
const agent_defaults_1 = require("
|
|
31
|
-
const codex_otel_bridge_1 = require("
|
|
32
|
-
const db_1 = require("
|
|
27
|
+
const codex_spawn_1 = require("../../../plugins/codex-spawn");
|
|
28
|
+
const providers_1 = require("../../../providers");
|
|
29
|
+
const runtime_1 = require("../../../providers/runtime");
|
|
30
|
+
const agent_defaults_1 = require("../../agents/runtime/agent-defaults");
|
|
31
|
+
const codex_otel_bridge_1 = require("../../accounting/runtime/codex-otel-bridge");
|
|
32
|
+
const db_1 = require("../../../db");
|
|
33
33
|
const interactive_job_session_1 = require("./interactive-job-session");
|
|
34
|
-
const attachment_manager_1 = require("
|
|
35
|
-
const ticket_store_1 = require("
|
|
36
|
-
const spec_addenda_1 = require("
|
|
37
|
-
const binary_probe_1 = require("
|
|
38
|
-
const workspace_manager_1 = require("
|
|
39
|
-
const claude_trust_1 = require("
|
|
40
|
-
const workspace_resolution_1 = require("
|
|
41
|
-
const project_env_1 = require("
|
|
42
|
-
const framework_manager_1 = require("
|
|
43
|
-
const openspec_shim_1 = require("
|
|
44
|
-
const artifact_registry_1 = require("
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
* convention (plus claude's `CLAUDE_CODE_ENABLE_TELEMETRY=1` master switch),
|
|
52
|
-
* but the Gemini CLI does NOT — it reads its own `GEMINI_TELEMETRY_*` prefixed
|
|
53
|
-
* vars (verified against google-gemini/gemini-cli docs/cli/telemetry.md) and
|
|
54
|
-
* defaults to gRPC, so gemini rails need `GEMINI_TELEMETRY_OTLP_PROTOCOL=http`
|
|
55
|
-
* and the OTLP endpoint pointed at our loopback receiver. Resource attributes
|
|
56
|
-
* still flow via the standard `OTEL_RESOURCE_ATTRIBUTES` (read by the OTel JS
|
|
57
|
-
* SDK that the Gemini CLI uses), so the receiver can route by job/project id.
|
|
58
|
-
*
|
|
59
|
-
* The `providerId` argument defaults to `'claude'` so existing claude/codex
|
|
60
|
-
* call paths stay byte-identical. */
|
|
61
|
-
function buildTelemetryEnv(jobId, projectId, desktopPort, extraResourceAttributes = {}, providerId = 'claude') {
|
|
62
|
-
const baseAttrs = [
|
|
63
|
-
['specrails.job_id', jobId],
|
|
64
|
-
['specrails.project_id', projectId],
|
|
65
|
-
];
|
|
66
|
-
for (const [k, v] of Object.entries(extraResourceAttributes)) {
|
|
67
|
-
baseAttrs.push([k, String(v)]);
|
|
68
|
-
}
|
|
69
|
-
const resourceAttributes = baseAttrs.map(([k, v]) => `${k}=${v}`).join(',');
|
|
70
|
-
const endpoint = `http://127.0.0.1:${desktopPort}/otlp`;
|
|
71
|
-
if (providerId === 'gemini') {
|
|
72
|
-
// Gemini CLI uses its own env contract (not OTEL_*). Defaults to gRPC, so we
|
|
73
|
-
// must force the http transport to reach our OTLP/HTTP JSON receiver, and
|
|
74
|
-
// target the `local` backend (not gcp). OTEL_RESOURCE_ATTRIBUTES is still
|
|
75
|
-
// honoured by the underlying OTel SDK for job/project routing.
|
|
76
|
-
return {
|
|
77
|
-
GEMINI_TELEMETRY_ENABLED: 'true',
|
|
78
|
-
GEMINI_TELEMETRY_TARGET: 'local',
|
|
79
|
-
GEMINI_TELEMETRY_OTLP_ENDPOINT: endpoint,
|
|
80
|
-
GEMINI_TELEMETRY_OTLP_PROTOCOL: 'http',
|
|
81
|
-
GEMINI_TELEMETRY_TRACES_ENABLED: 'true',
|
|
82
|
-
OTEL_RESOURCE_ATTRIBUTES: resourceAttributes,
|
|
83
|
-
};
|
|
84
|
-
}
|
|
85
|
-
// claude (master switch + OTEL_*) and codex (OTEL_* only) — byte-identical to
|
|
86
|
-
// the pre-fix block for both.
|
|
87
|
-
return {
|
|
88
|
-
CLAUDE_CODE_ENABLE_TELEMETRY: '1',
|
|
89
|
-
OTEL_EXPORTER_OTLP_ENDPOINT: endpoint,
|
|
90
|
-
OTEL_EXPORTER_OTLP_PROTOCOL: 'http/json',
|
|
91
|
-
OTEL_METRICS_EXPORTER: 'otlp',
|
|
92
|
-
OTEL_LOGS_EXPORTER: 'otlp',
|
|
93
|
-
OTEL_TRACES_EXPORTER: 'otlp',
|
|
94
|
-
OTEL_RESOURCE_ATTRIBUTES: resourceAttributes,
|
|
95
|
-
};
|
|
96
|
-
}
|
|
97
|
-
/** Detect whether a project's installed specrails-core version supports the
|
|
98
|
-
* profile-aware pipeline (shipped in 4.1.0). Returns false when the version
|
|
99
|
-
* file is missing or unparseable so we default to legacy (safer). */
|
|
100
|
-
function projectSupportsProfiles(projectPath) {
|
|
101
|
-
const candidates = [
|
|
102
|
-
path_1.default.join(projectPath, '.specrails', 'specrails-version'),
|
|
103
|
-
path_1.default.join(projectPath, '.specrails-version'),
|
|
104
|
-
];
|
|
105
|
-
for (const p of candidates) {
|
|
106
|
-
if (!fs_1.default.existsSync(p))
|
|
107
|
-
continue;
|
|
108
|
-
try {
|
|
109
|
-
const raw = fs_1.default.readFileSync(p, 'utf8').trim();
|
|
110
|
-
const [ma, mi, pa] = raw.split('.').map((n) => parseInt(n, 10));
|
|
111
|
-
if (isNaN(ma) || isNaN(mi) || isNaN(pa))
|
|
112
|
-
return false;
|
|
113
|
-
return ma > 4 || (ma === 4 && mi > 1) || (ma === 4 && mi === 1 && pa >= 0);
|
|
114
|
-
}
|
|
115
|
-
catch {
|
|
116
|
-
return false;
|
|
117
|
-
}
|
|
118
|
-
}
|
|
119
|
-
return false;
|
|
120
|
-
}
|
|
121
|
-
/**
|
|
122
|
-
* Distribute an integer `total` across `n` buckets via the largest-remainder
|
|
123
|
-
* method so the per-bucket values sum EXACTLY back to `total` (no floor loss).
|
|
124
|
-
* Mirrors smash-runner's `distributeInt` — used to split a multi-ticket job's
|
|
125
|
-
* token / turn totals across one ai_invocations row per ticket
|
|
126
|
-
* (COST-ACCOUNTING-AUDIT MED-7). Returns `undefined` per bucket when the input
|
|
127
|
-
* is absent so the row carries NULL rather than a spurious 0.
|
|
128
|
-
*/
|
|
129
|
-
function distributeIntEvenly(total, n) {
|
|
130
|
-
if (total === null || total === undefined)
|
|
131
|
-
return new Array(n).fill(undefined);
|
|
132
|
-
const t = Math.trunc(total);
|
|
133
|
-
const base = Math.floor(t / n);
|
|
134
|
-
let remainder = t - base * n;
|
|
135
|
-
const out = new Array(n);
|
|
136
|
-
for (let i = 0; i < n; i++) {
|
|
137
|
-
// Hand the leftover to the leading buckets; sign-safe for negative totals.
|
|
138
|
-
if (remainder > 0) {
|
|
139
|
-
out[i] = base + 1;
|
|
140
|
-
remainder -= 1;
|
|
141
|
-
}
|
|
142
|
-
else if (remainder < 0) {
|
|
143
|
-
out[i] = base - 1;
|
|
144
|
-
remainder += 1;
|
|
145
|
-
}
|
|
146
|
-
else
|
|
147
|
-
out[i] = base;
|
|
148
|
-
}
|
|
149
|
-
return out;
|
|
150
|
-
}
|
|
34
|
+
const attachment_manager_1 = require("../../../attachment-manager");
|
|
35
|
+
const ticket_store_1 = require("../../specs/runtime/ticket-store");
|
|
36
|
+
const spec_addenda_1 = require("../../specs/runtime/spec-addenda");
|
|
37
|
+
const binary_probe_1 = require("../../../binary-probe");
|
|
38
|
+
const workspace_manager_1 = require("../../../workspace-manager");
|
|
39
|
+
const claude_trust_1 = require("../../../claude-trust");
|
|
40
|
+
const workspace_resolution_1 = require("../../../workspace-resolution");
|
|
41
|
+
const project_env_1 = require("../../../project-env");
|
|
42
|
+
const framework_manager_1 = require("../../../framework-manager");
|
|
43
|
+
const openspec_shim_1 = require("../../../openspec-shim");
|
|
44
|
+
const artifact_registry_1 = require("../../../artifact-registry");
|
|
45
|
+
const telemetry_env_1 = require("../../../providers/telemetry-env");
|
|
46
|
+
Object.defineProperty(exports, "buildTelemetryEnv", { enumerable: true, get: function () { return telemetry_env_1.buildTelemetryEnv; } });
|
|
47
|
+
const project_profile_support_1 = require("../../../project-profile-support");
|
|
48
|
+
Object.defineProperty(exports, "projectSupportsProfiles", { enumerable: true, get: function () { return project_profile_support_1.projectSupportsProfiles; } });
|
|
49
|
+
const distribute_int_1 = require("../../../util/distribute-int");
|
|
50
|
+
Object.defineProperty(exports, "distributeIntEvenly", { enumerable: true, get: function () { return distribute_int_1.distributeIntEvenly; } });
|
|
151
51
|
function maxNullable(left, right) {
|
|
152
52
|
const safeLeft = typeof left === 'number' && Number.isFinite(left) && left >= 0 ? left : null;
|
|
153
53
|
const safeRight = typeof right === 'number' && Number.isFinite(right) && right >= 0 ? right : null;
|
|
@@ -157,24 +57,6 @@ function maxNullable(left, right) {
|
|
|
157
57
|
return safeLeft;
|
|
158
58
|
return Math.max(safeLeft, safeRight);
|
|
159
59
|
}
|
|
160
|
-
function sanitizeRecoveredResult(result) {
|
|
161
|
-
const safe = { ...result };
|
|
162
|
-
const numeric = [
|
|
163
|
-
'tokens_in', 'tokens_out', 'tokens_cache_read', 'tokens_cache_create',
|
|
164
|
-
'total_cost_usd', 'num_turns', 'duration_ms', 'duration_api_ms',
|
|
165
|
-
];
|
|
166
|
-
for (const key of numeric) {
|
|
167
|
-
const value = safe[key];
|
|
168
|
-
if (value !== undefined && (typeof value !== 'number' || !Number.isFinite(value) || value < 0)) {
|
|
169
|
-
delete safe[key];
|
|
170
|
-
}
|
|
171
|
-
}
|
|
172
|
-
if (safe.model !== undefined && typeof safe.model !== 'string')
|
|
173
|
-
delete safe.model;
|
|
174
|
-
if (safe.session_id !== undefined && typeof safe.session_id !== 'string')
|
|
175
|
-
delete safe.session_id;
|
|
176
|
-
return safe;
|
|
177
|
-
}
|
|
178
60
|
const LOG_BUFFER_MAX = 5000;
|
|
179
61
|
const LOG_BUFFER_DROP = 1000;
|
|
180
62
|
exports.DEFAULT_ZOMBIE_TIMEOUT_MS = 1_800_000; // 30 minutes
|
|
@@ -1284,13 +1166,6 @@ class QueueManager {
|
|
|
1284
1166
|
phasesForCommand(command) {
|
|
1285
1167
|
return this._phasesForCommand(command);
|
|
1286
1168
|
}
|
|
1287
|
-
/**
|
|
1288
|
-
* Resolve a slash command into a full prompt with $ARGUMENTS substituted.
|
|
1289
|
-
* Delegates to the shared resolveCommand utility in command-resolver.ts.
|
|
1290
|
-
*/
|
|
1291
|
-
_resolveCommand(command) {
|
|
1292
|
-
return (0, command_resolver_1.resolveCommand)(command, this._cwd ?? process.cwd());
|
|
1293
|
-
}
|
|
1294
1169
|
_phasesForCommand(command) {
|
|
1295
1170
|
// Extract slug from command strings like "/specrails:implement #5" or "implement"
|
|
1296
1171
|
const firstToken = command.trim().split(/\s+/)[0];
|
|
@@ -1319,67 +1194,14 @@ class QueueManager {
|
|
|
1319
1194
|
* locate/replace the rows later.
|
|
1320
1195
|
*/
|
|
1321
1196
|
_recordJobInvocations(params) {
|
|
1322
|
-
const { jobId, provider, status, startedAt, finishedAt, ticketIds, estimated, result } = params;
|
|
1323
1197
|
const db = this._db;
|
|
1324
1198
|
const projectId = this._projectId;
|
|
1325
1199
|
if (!db || !projectId)
|
|
1326
1200
|
return [];
|
|
1327
|
-
|
|
1328
|
-
|
|
1329
|
-
(0, ai_invocations_1.recordInvocation)(db,
|
|
1330
|
-
id: (0, crypto_1.randomUUID)(),
|
|
1331
|
-
project_id: projectId,
|
|
1332
|
-
provider,
|
|
1333
|
-
surface: 'job',
|
|
1334
|
-
surface_ref_id: jobId,
|
|
1335
|
-
ticket_id: ticketIds[0] ?? null,
|
|
1336
|
-
conversation_id: params.conversationId ?? null,
|
|
1337
|
-
status,
|
|
1338
|
-
started_at: startedAt,
|
|
1339
|
-
finished_at: finishedAt,
|
|
1340
|
-
total_cost_usd_estimated: estimated,
|
|
1341
|
-
...result,
|
|
1342
|
-
});
|
|
1343
|
-
return [jobId];
|
|
1344
|
-
}
|
|
1345
|
-
// Multi-ticket: split across one row per ticket. Cost & duration split evenly
|
|
1346
|
-
// as floats; token & turn totals via largest-remainder (sum exactly to total).
|
|
1347
|
-
const n = ticketIds.length;
|
|
1348
|
-
const evenSplit = (v) => v === undefined ? undefined : v / n;
|
|
1349
|
-
const tokensIn = distributeIntEvenly(result.tokens_in, n);
|
|
1350
|
-
const tokensOut = distributeIntEvenly(result.tokens_out, n);
|
|
1351
|
-
const cacheRead = distributeIntEvenly(result.tokens_cache_read, n);
|
|
1352
|
-
const cacheCreate = distributeIntEvenly(result.tokens_cache_create, n);
|
|
1353
|
-
const numTurns = distributeIntEvenly(result.num_turns, n);
|
|
1354
|
-
const refIds = [];
|
|
1355
|
-
ticketIds.forEach((ticketId, i) => {
|
|
1356
|
-
const refId = `${jobId}#t${ticketId}`;
|
|
1357
|
-
refIds.push(refId);
|
|
1358
|
-
(0, ai_invocations_1.recordInvocation)(db, {
|
|
1359
|
-
id: (0, crypto_1.randomUUID)(),
|
|
1360
|
-
project_id: projectId,
|
|
1361
|
-
provider,
|
|
1362
|
-
surface: 'job',
|
|
1363
|
-
surface_ref_id: refId,
|
|
1364
|
-
ticket_id: ticketId,
|
|
1365
|
-
conversation_id: params.conversationId ?? null,
|
|
1366
|
-
status,
|
|
1367
|
-
started_at: startedAt,
|
|
1368
|
-
finished_at: finishedAt,
|
|
1369
|
-
total_cost_usd_estimated: estimated,
|
|
1370
|
-
tokens_in: tokensIn[i],
|
|
1371
|
-
tokens_out: tokensOut[i],
|
|
1372
|
-
tokens_cache_read: cacheRead[i],
|
|
1373
|
-
tokens_cache_create: cacheCreate[i],
|
|
1374
|
-
total_cost_usd: evenSplit(result.total_cost_usd),
|
|
1375
|
-
num_turns: numTurns[i],
|
|
1376
|
-
model: result.model,
|
|
1377
|
-
session_id: result.session_id,
|
|
1378
|
-
duration_ms: evenSplit(result.duration_ms),
|
|
1379
|
-
duration_api_ms: evenSplit(result.duration_api_ms),
|
|
1380
|
-
});
|
|
1201
|
+
return (0, __2.recordJobInvocations)(projectId, params, {
|
|
1202
|
+
newId: crypto_1.randomUUID,
|
|
1203
|
+
write: invocation => (0, ai_invocations_1.recordInvocation)(db, invocation),
|
|
1381
1204
|
});
|
|
1382
|
-
return refIds;
|
|
1383
1205
|
}
|
|
1384
1206
|
/**
|
|
1385
1207
|
* Local calendar-day start, expressed as a UTC-ISO instant so it compares
|
|
@@ -1402,46 +1224,31 @@ class QueueManager {
|
|
|
1402
1224
|
if (!db)
|
|
1403
1225
|
return;
|
|
1404
1226
|
try {
|
|
1405
|
-
|
|
1406
|
-
|
|
1407
|
-
|
|
1408
|
-
|
|
1409
|
-
|
|
1410
|
-
|
|
1411
|
-
|
|
1412
|
-
|
|
1413
|
-
|
|
1414
|
-
|
|
1415
|
-
|
|
1416
|
-
const wasPaused = this._paused;
|
|
1417
|
-
this._paused = true;
|
|
1418
|
-
if (!wasPaused) {
|
|
1419
|
-
db.prepare(`INSERT OR REPLACE INTO queue_state (key, value) VALUES ('paused', 'true')`).run();
|
|
1420
|
-
}
|
|
1421
|
-
this._broadcast({ type: 'daily_budget_exceeded', projectId: '', dailySpend, budget: dailyBudget, queuePaused: true });
|
|
1227
|
+
const storage = (0, budget_storage_1.createQueueBudgetStorage)(db);
|
|
1228
|
+
(0, __1.enforceDailyBudgets)({
|
|
1229
|
+
project: () => storage.project(this._projectId, () => this._localDayStartIso()),
|
|
1230
|
+
desktop: this._getDesktopDailyBudget ? () => this._getDesktopDailyBudget() : undefined,
|
|
1231
|
+
exceeded: (scope, { budget, totalSpend }) => {
|
|
1232
|
+
const wasPaused = this._paused;
|
|
1233
|
+
this._paused = true;
|
|
1234
|
+
if (!wasPaused)
|
|
1235
|
+
storage.pause();
|
|
1236
|
+
if (scope === 'project') {
|
|
1237
|
+
this._broadcast({ type: 'daily_budget_exceeded', projectId: '', dailySpend: totalSpend, budget, queuePaused: true });
|
|
1422
1238
|
try {
|
|
1423
|
-
this._onBudgetExceeded?.('daily_budget_exceeded', { dailySpend, budget
|
|
1239
|
+
this._onBudgetExceeded?.('daily_budget_exceeded', { dailySpend: totalSpend, budget, queuePaused: true });
|
|
1424
1240
|
}
|
|
1425
1241
|
catch { /* webhook delivery is best-effort */ }
|
|
1426
1242
|
}
|
|
1427
|
-
|
|
1428
|
-
|
|
1429
|
-
|
|
1430
|
-
|
|
1431
|
-
|
|
1432
|
-
|
|
1433
|
-
const wasPaused = this._paused;
|
|
1434
|
-
this._paused = true;
|
|
1435
|
-
if (!wasPaused) {
|
|
1436
|
-
db.prepare(`INSERT OR REPLACE INTO queue_state (key, value) VALUES ('paused', 'true')`).run();
|
|
1437
|
-
}
|
|
1438
|
-
this._broadcast({ type: 'desktop_daily_budget_exceeded', projectId: '', desktopDailySpend: desktopTotalSpend, desktopBudget, queuePaused: true });
|
|
1439
|
-
try {
|
|
1440
|
-
this._onBudgetExceeded?.('desktop_daily_budget_exceeded', { desktopDailySpend: desktopTotalSpend, desktopBudget, queuePaused: true });
|
|
1243
|
+
else {
|
|
1244
|
+
this._broadcast({ type: 'desktop_daily_budget_exceeded', projectId: '', desktopDailySpend: totalSpend, desktopBudget: budget, queuePaused: true });
|
|
1245
|
+
try {
|
|
1246
|
+
this._onBudgetExceeded?.('desktop_daily_budget_exceeded', { desktopDailySpend: totalSpend, desktopBudget: budget, queuePaused: true });
|
|
1247
|
+
}
|
|
1248
|
+
catch { /* webhook delivery is best-effort */ }
|
|
1441
1249
|
}
|
|
1442
|
-
|
|
1443
|
-
|
|
1444
|
-
}
|
|
1250
|
+
},
|
|
1251
|
+
});
|
|
1445
1252
|
}
|
|
1446
1253
|
catch (err) {
|
|
1447
1254
|
console.error('[queue-manager] daily-budget enforcement failed (db unavailable?):', err);
|
|
@@ -1549,19 +1356,7 @@ class QueueManager {
|
|
|
1549
1356
|
// an invalid caller: only unique, presently-queued jobs may reach start.
|
|
1550
1357
|
// In particular, a duplicated id must not relaunch after its first run
|
|
1551
1358
|
// becomes terminal.
|
|
1552
|
-
const
|
|
1553
|
-
const normalizedQueue = [];
|
|
1554
|
-
const removedJobIds = [];
|
|
1555
|
-
for (const id of this._queue) {
|
|
1556
|
-
if (seen.has(id))
|
|
1557
|
-
continue;
|
|
1558
|
-
seen.add(id);
|
|
1559
|
-
const candidate = this._jobs.get(id);
|
|
1560
|
-
if (candidate?.status === 'queued')
|
|
1561
|
-
normalizedQueue.push(id);
|
|
1562
|
-
else
|
|
1563
|
-
removedJobIds.push(id);
|
|
1564
|
-
}
|
|
1359
|
+
const { normalizedQueue, removedJobIds } = (0, __2.normalizePendingQueue)(this._queue, this._jobs);
|
|
1565
1360
|
if (normalizedQueue.length !== this._queue.length) {
|
|
1566
1361
|
this._queue = normalizedQueue;
|
|
1567
1362
|
this._recomputePositions();
|
|
@@ -2348,10 +2143,10 @@ class QueueManager {
|
|
|
2348
2143
|
const selection = this._jobProfileSelection.get(jobId); // undefined|null|string
|
|
2349
2144
|
// When relocated, core + `.specrails/profiles` live in the workspace
|
|
2350
2145
|
// (execution.cwd); legacy reads from the repo (execution.cwd === repo).
|
|
2351
|
-
const coreSupports = projectSupportsProfiles(execution.cwd);
|
|
2146
|
+
const coreSupports = (0, project_profile_support_1.projectSupportsProfiles)(execution.cwd);
|
|
2352
2147
|
if (selection !== null && coreSupports) {
|
|
2353
2148
|
// selection is string (explicit) or undefined (default resolution)
|
|
2354
|
-
const { resolveProfile, snapshotForJob, persistJobProfile, } = require('
|
|
2149
|
+
const { resolveProfile, snapshotForJob, persistJobProfile, } = require('../../agents/runtime/profile-manager');
|
|
2355
2150
|
let resolved = resolveProfile(execution.cwd, selection ?? undefined, adapter.id);
|
|
2356
2151
|
// Global agent defaults: fill per-agent model gaps in the resolved
|
|
2357
2152
|
// profile, or synthesize a baseline profile when the project has
|
|
@@ -2438,7 +2233,7 @@ class QueueManager {
|
|
|
2438
2233
|
extra['specrails.framework_version'] = frameworkVersion;
|
|
2439
2234
|
spawnEnv = {
|
|
2440
2235
|
...spawnEnv,
|
|
2441
|
-
...buildTelemetryEnv(jobId, this._projectId, this._desktopPort, extra, adapter.id),
|
|
2236
|
+
...(0, telemetry_env_1.buildTelemetryEnv)(jobId, this._projectId, this._desktopPort, extra, adapter.id),
|
|
2442
2237
|
};
|
|
2443
2238
|
}
|
|
2444
2239
|
// Inject the profile path whenever the adapter honours it (was: claude-
|
|
@@ -2465,7 +2260,7 @@ class QueueManager {
|
|
|
2465
2260
|
let resolver = this._resolvePluginsForSpawn;
|
|
2466
2261
|
let snapshotter = null;
|
|
2467
2262
|
if (!resolver) {
|
|
2468
|
-
const pluginIntegration = require('
|
|
2263
|
+
const pluginIntegration = require('../../../plugins/rail-integration');
|
|
2469
2264
|
resolver = pluginIntegration.resolvePluginsForSpawn;
|
|
2470
2265
|
snapshotter = pluginIntegration.snapshotPluginsForJob;
|
|
2471
2266
|
}
|
|
@@ -2481,7 +2276,7 @@ class QueueManager {
|
|
|
2481
2276
|
if (pluginActive.length > 0 || pluginDegraded.length > 0) {
|
|
2482
2277
|
// The injected resolver normally returns an empty test fixture. Load
|
|
2483
2278
|
// the snapshotter lazily only if its result actually needs one.
|
|
2484
|
-
snapshotter ??= require('
|
|
2279
|
+
snapshotter ??= require('../../../plugins/rail-integration').snapshotPluginsForJob;
|
|
2485
2280
|
pluginSnapshotPath = snapshotter(this._projectSlug, jobId, this._projectId, pluginActive, pluginDegraded);
|
|
2486
2281
|
}
|
|
2487
2282
|
for (const d of pluginDegraded) {
|
|
@@ -2534,7 +2329,7 @@ class QueueManager {
|
|
|
2534
2329
|
}
|
|
2535
2330
|
spawnEnv = {
|
|
2536
2331
|
...spawnEnv,
|
|
2537
|
-
...buildTelemetryEnv(jobId, this._projectId, this._desktopPort, extra),
|
|
2332
|
+
...(0, telemetry_env_1.buildTelemetryEnv)(jobId, this._projectId, this._desktopPort, extra),
|
|
2538
2333
|
};
|
|
2539
2334
|
}
|
|
2540
2335
|
}
|
|
@@ -3388,7 +3183,7 @@ class QueueManager {
|
|
|
3388
3183
|
});
|
|
3389
3184
|
try {
|
|
3390
3185
|
const finalised = (0, result_event_1.finaliseInvocationResult)(adapter, adapterEvents, { fallbackModel: spawnedModel });
|
|
3391
|
-
const normalised = sanitizeRecoveredResult(finalised.result);
|
|
3186
|
+
const normalised = (0, __2.sanitizeRecoveredResult)(finalised.result);
|
|
3392
3187
|
const estimated = finalised.estimated;
|
|
3393
3188
|
const hasRealSpend = (normalised.total_cost_usd ?? 0) > 0 ||
|
|
3394
3189
|
(normalised.tokens_in ?? 0) > 0 ||
|
|
@@ -3706,7 +3501,7 @@ class QueueManager {
|
|
|
3706
3501
|
if (!job.dependsOnJobId)
|
|
3707
3502
|
return true;
|
|
3708
3503
|
const parentStatus = this._getDependencyStatus(job.dependsOnJobId);
|
|
3709
|
-
return
|
|
3504
|
+
return (0, __2.isDependencySatisfied)(parentStatus);
|
|
3710
3505
|
}
|
|
3711
3506
|
_skipDependents(parentJobId, reason) {
|
|
3712
3507
|
const toSkip = [];
|
|
@@ -3857,8 +3652,7 @@ class QueueManager {
|
|
|
3857
3652
|
* cumulative cost/turn snapshot, so segments must be folded exactly like the
|
|
3858
3653
|
* live session; assistant-only tail frames are one estimated in-flight turn. */
|
|
3859
3654
|
_recoverPersistedJobUsage(jobId, providerId, fallbackModel, interactive) {
|
|
3860
|
-
|
|
3861
|
-
if (!db)
|
|
3655
|
+
if (!this._db)
|
|
3862
3656
|
return { result: {}, estimated: false, authoritative: false };
|
|
3863
3657
|
let adapter;
|
|
3864
3658
|
try {
|
|
@@ -3867,218 +3661,7 @@ class QueueManager {
|
|
|
3867
3661
|
catch {
|
|
3868
3662
|
adapter = this._adapter;
|
|
3869
3663
|
}
|
|
3870
|
-
|
|
3871
|
-
try {
|
|
3872
|
-
return (0, runtime_1.parseStreamEvents)(adapter, row.payload);
|
|
3873
|
-
}
|
|
3874
|
-
catch (err) {
|
|
3875
|
-
console.warn(`[queue-manager] ignored malformed durable event for ${jobId}:`, err);
|
|
3876
|
-
return [];
|
|
3877
|
-
}
|
|
3878
|
-
};
|
|
3879
|
-
const makeUsageAccumulator = () => {
|
|
3880
|
-
const totals = {
|
|
3881
|
-
tokens_in: 0,
|
|
3882
|
-
tokens_out: 0,
|
|
3883
|
-
tokens_cache_read: 0,
|
|
3884
|
-
tokens_cache_create: 0,
|
|
3885
|
-
total_cost_usd: 0,
|
|
3886
|
-
num_turns: 0,
|
|
3887
|
-
duration_ms: 0,
|
|
3888
|
-
duration_api_ms: 0,
|
|
3889
|
-
};
|
|
3890
|
-
let model = fallbackModel ?? undefined;
|
|
3891
|
-
let sessionId;
|
|
3892
|
-
let estimated = false;
|
|
3893
|
-
const snapshots = new Map();
|
|
3894
|
-
const MAX_SNAPSHOT_KEYS = 4_096;
|
|
3895
|
-
const add = (event, seq) => {
|
|
3896
|
-
const finalised = (0, result_event_1.finaliseInvocationResult)(adapter, [event], { fallbackModel: model });
|
|
3897
|
-
const result = sanitizeRecoveredResult(finalised.result);
|
|
3898
|
-
const raw = event.kind === 'other' ? event.raw : null;
|
|
3899
|
-
const message = raw && typeof raw.message === 'object' && raw.message
|
|
3900
|
-
? raw.message
|
|
3901
|
-
: null;
|
|
3902
|
-
const directMessageId = event.messageId;
|
|
3903
|
-
const messageId = directMessageId ?? (message && typeof message.id === 'string' ? message.id : undefined);
|
|
3904
|
-
const stableId = messageId ? `message:${messageId}` : `${event.kind}:${seq}`;
|
|
3905
|
-
const previous = snapshots.get(stableId) ?? {};
|
|
3906
|
-
const addDelta = (key) => {
|
|
3907
|
-
const current = result[key];
|
|
3908
|
-
if (typeof current !== 'number')
|
|
3909
|
-
return;
|
|
3910
|
-
const prior = previous[key];
|
|
3911
|
-
totals[key] += Math.max(0, current - (typeof prior === 'number' ? prior : 0));
|
|
3912
|
-
};
|
|
3913
|
-
addDelta('tokens_in');
|
|
3914
|
-
addDelta('tokens_out');
|
|
3915
|
-
addDelta('tokens_cache_read');
|
|
3916
|
-
addDelta('tokens_cache_create');
|
|
3917
|
-
addDelta('total_cost_usd');
|
|
3918
|
-
addDelta('num_turns');
|
|
3919
|
-
addDelta('duration_ms');
|
|
3920
|
-
addDelta('duration_api_ms');
|
|
3921
|
-
model = result.model ?? model;
|
|
3922
|
-
sessionId = result.session_id ?? sessionId;
|
|
3923
|
-
estimated = estimated || finalised.estimated;
|
|
3924
|
-
if (!snapshots.has(stableId) && snapshots.size >= MAX_SNAPSHOT_KEYS) {
|
|
3925
|
-
snapshots.delete(snapshots.keys().next().value);
|
|
3926
|
-
}
|
|
3927
|
-
// Frames for one provider message are contiguous; retain a bounded LRU
|
|
3928
|
-
// of recent snapshots for retransmission/delta dedupe without letting a
|
|
3929
|
-
// malicious transcript allocate one map entry per event forever.
|
|
3930
|
-
snapshots.delete(stableId);
|
|
3931
|
-
snapshots.set(stableId, { ...previous, ...result });
|
|
3932
|
-
};
|
|
3933
|
-
const result = () => {
|
|
3934
|
-
const hasUsage = Object.values(totals).some((value) => value > 0);
|
|
3935
|
-
return {
|
|
3936
|
-
result: hasUsage ? { ...totals, model, session_id: sessionId } : {},
|
|
3937
|
-
estimated,
|
|
3938
|
-
};
|
|
3939
|
-
};
|
|
3940
|
-
return { add, result };
|
|
3941
|
-
};
|
|
3942
|
-
if (!interactive) {
|
|
3943
|
-
const accumulator = makeUsageAccumulator();
|
|
3944
|
-
let lastValidResult = null;
|
|
3945
|
-
const events = db.prepare(`
|
|
3946
|
-
SELECT seq, event_type, payload FROM events
|
|
3947
|
-
WHERE job_id = ? AND source = 'stdout' AND event_type != 'log'
|
|
3948
|
-
ORDER BY seq, id
|
|
3949
|
-
`).iterate(jobId);
|
|
3950
|
-
for (const row of events) {
|
|
3951
|
-
for (const event of parse(row)) {
|
|
3952
|
-
if (event.kind === 'result') {
|
|
3953
|
-
const finalised = (0, result_event_1.finaliseInvocationResult)(adapter, [event], {
|
|
3954
|
-
fallbackModel: fallbackModel ?? undefined,
|
|
3955
|
-
});
|
|
3956
|
-
lastValidResult = {
|
|
3957
|
-
...finalised,
|
|
3958
|
-
result: sanitizeRecoveredResult(finalised.result),
|
|
3959
|
-
};
|
|
3960
|
-
}
|
|
3961
|
-
else {
|
|
3962
|
-
accumulator.add(event, row.seq);
|
|
3963
|
-
}
|
|
3964
|
-
}
|
|
3965
|
-
}
|
|
3966
|
-
const fallback = accumulator.result();
|
|
3967
|
-
if (lastValidResult) {
|
|
3968
|
-
const result = { ...fallback.result };
|
|
3969
|
-
for (const [key, value] of Object.entries(lastValidResult.result)) {
|
|
3970
|
-
// Provider normalisers intentionally retain optional keys with an
|
|
3971
|
-
// undefined value. Only concrete terminal fields are authoritative;
|
|
3972
|
-
// an omitted field must not erase recoverable assistant evidence.
|
|
3973
|
-
if (value !== undefined) {
|
|
3974
|
-
result[key] = value;
|
|
3975
|
-
}
|
|
3976
|
-
}
|
|
3977
|
-
return {
|
|
3978
|
-
result,
|
|
3979
|
-
// A native terminal cost is authoritative. When the terminal frame
|
|
3980
|
-
// omits cost, preserve whether the assistant-frame backfill was an
|
|
3981
|
-
// estimate instead of silently relabelling it as exact.
|
|
3982
|
-
estimated: result.total_cost_usd === lastValidResult.result.total_cost_usd &&
|
|
3983
|
-
lastValidResult.result.total_cost_usd !== undefined
|
|
3984
|
-
? lastValidResult.estimated
|
|
3985
|
-
: (lastValidResult.estimated || fallback.estimated),
|
|
3986
|
-
authoritative: true,
|
|
3987
|
-
};
|
|
3988
|
-
}
|
|
3989
|
-
return { ...fallback, authoritative: false };
|
|
3990
|
-
}
|
|
3991
|
-
const totals = {
|
|
3992
|
-
tokens_in: 0,
|
|
3993
|
-
tokens_out: 0,
|
|
3994
|
-
tokens_cache_read: 0,
|
|
3995
|
-
tokens_cache_create: 0,
|
|
3996
|
-
total_cost_usd: 0,
|
|
3997
|
-
num_turns: 0,
|
|
3998
|
-
duration_ms: 0,
|
|
3999
|
-
duration_api_ms: 0,
|
|
4000
|
-
};
|
|
4001
|
-
let model = fallbackModel ?? undefined;
|
|
4002
|
-
let sessionId;
|
|
4003
|
-
let baselineCost = 0;
|
|
4004
|
-
let baselineTurns = 0;
|
|
4005
|
-
let estimated = false;
|
|
4006
|
-
let lastResultSeq = -1;
|
|
4007
|
-
const resultRows = db.prepare(`
|
|
4008
|
-
SELECT seq, event_type, payload FROM events
|
|
4009
|
-
WHERE job_id = ? AND source = 'stdout' AND event_type = 'result'
|
|
4010
|
-
ORDER BY seq, id
|
|
4011
|
-
`).iterate(jobId);
|
|
4012
|
-
for (const row of resultRows) {
|
|
4013
|
-
for (const event of parse(row)) {
|
|
4014
|
-
if (event.kind !== 'result')
|
|
4015
|
-
continue;
|
|
4016
|
-
const finalised = (0, result_event_1.finaliseInvocationResult)(adapter, [event], { fallbackModel: model });
|
|
4017
|
-
const result = sanitizeRecoveredResult(finalised.result);
|
|
4018
|
-
totals.tokens_in += result.tokens_in ?? 0;
|
|
4019
|
-
totals.tokens_out += result.tokens_out ?? 0;
|
|
4020
|
-
totals.tokens_cache_read += result.tokens_cache_read ?? 0;
|
|
4021
|
-
totals.tokens_cache_create += result.tokens_cache_create ?? 0;
|
|
4022
|
-
const cumulativeCost = result.total_cost_usd ?? baselineCost;
|
|
4023
|
-
totals.total_cost_usd += Math.max(0, cumulativeCost - baselineCost);
|
|
4024
|
-
baselineCost = cumulativeCost;
|
|
4025
|
-
const cumulativeTurns = result.num_turns ?? (baselineTurns + 1);
|
|
4026
|
-
totals.num_turns += Math.max(0, cumulativeTurns - baselineTurns);
|
|
4027
|
-
baselineTurns = cumulativeTurns;
|
|
4028
|
-
totals.duration_ms += result.duration_ms ?? 0;
|
|
4029
|
-
totals.duration_api_ms += result.duration_api_ms ?? 0;
|
|
4030
|
-
model = result.model ?? model;
|
|
4031
|
-
sessionId = result.session_id ?? sessionId;
|
|
4032
|
-
estimated = estimated || finalised.estimated;
|
|
4033
|
-
lastResultSeq = row.seq;
|
|
4034
|
-
}
|
|
4035
|
-
}
|
|
4036
|
-
const tail = makeUsageAccumulator();
|
|
4037
|
-
const tailRows = db.prepare(`
|
|
4038
|
-
SELECT seq, event_type, payload FROM events
|
|
4039
|
-
WHERE job_id = ? AND source = 'stdout' AND event_type != 'log' AND seq > ?
|
|
4040
|
-
ORDER BY seq, id
|
|
4041
|
-
`).iterate(jobId, lastResultSeq);
|
|
4042
|
-
for (const row of tailRows) {
|
|
4043
|
-
for (const event of parse(row)) {
|
|
4044
|
-
if (event.kind !== 'result')
|
|
4045
|
-
tail.add(event, row.seq);
|
|
4046
|
-
}
|
|
4047
|
-
}
|
|
4048
|
-
const tailUsage = tail.result();
|
|
4049
|
-
const tailResult = tailUsage.result;
|
|
4050
|
-
const hasTailUsage = [
|
|
4051
|
-
tailResult.tokens_in,
|
|
4052
|
-
tailResult.tokens_out,
|
|
4053
|
-
tailResult.tokens_cache_read,
|
|
4054
|
-
tailResult.tokens_cache_create,
|
|
4055
|
-
tailResult.total_cost_usd,
|
|
4056
|
-
].some((value) => typeof value === 'number' && value > 0);
|
|
4057
|
-
if (hasTailUsage) {
|
|
4058
|
-
totals.tokens_in += tailResult.tokens_in ?? 0;
|
|
4059
|
-
totals.tokens_out += tailResult.tokens_out ?? 0;
|
|
4060
|
-
totals.tokens_cache_read += tailResult.tokens_cache_read ?? 0;
|
|
4061
|
-
totals.tokens_cache_create += tailResult.tokens_cache_create ?? 0;
|
|
4062
|
-
totals.total_cost_usd += tailResult.total_cost_usd ?? 0;
|
|
4063
|
-
totals.num_turns += tailResult.num_turns ?? 1;
|
|
4064
|
-
totals.duration_ms += tailResult.duration_ms ?? 0;
|
|
4065
|
-
totals.duration_api_ms += tailResult.duration_api_ms ?? 0;
|
|
4066
|
-
model = tailResult.model ?? model;
|
|
4067
|
-
sessionId = tailResult.session_id ?? sessionId;
|
|
4068
|
-
estimated = estimated || tailUsage.estimated;
|
|
4069
|
-
}
|
|
4070
|
-
const hasRecoveredUsage = Object.values(totals).some((value) => value > 0);
|
|
4071
|
-
return {
|
|
4072
|
-
result: hasRecoveredUsage
|
|
4073
|
-
? {
|
|
4074
|
-
...totals,
|
|
4075
|
-
model,
|
|
4076
|
-
session_id: sessionId,
|
|
4077
|
-
}
|
|
4078
|
-
: {},
|
|
4079
|
-
estimated,
|
|
4080
|
-
authoritative: false,
|
|
4081
|
-
};
|
|
3664
|
+
return (0, __2.recoverJobUsage)((0, usage_reader_1.createDurableUsageReader)(this._db, jobId, adapter), fallbackModel, interactive);
|
|
4082
3665
|
}
|
|
4083
3666
|
_decodeRecoveryPayload(jobId, encoded) {
|
|
4084
3667
|
const payload = JSON.parse(encoded);
|