specrails-desktop 2.55.0 → 2.56.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/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-DdMNmVBk.js} +1 -1
- package/client/dist/assets/{AgentBrowserCapture-UcsupCy7.js → AgentBrowserCapture-CeerUf--.js} +1 -1
- package/client/dist/assets/{AgentModeAnalyticsPane-CQuxYh8B.js → AgentModeAnalyticsPane-BjGb-8rh.js} +2 -2
- package/client/dist/assets/{AgentModeCodePane-zPWbW7ei.js → AgentModeCodePane-8XRkQEo_.js} +2 -2
- package/client/dist/assets/{AgentModeJobsPane-CInByIdl.js → AgentModeJobsPane-BN3dgJOA.js} +1 -1
- package/client/dist/assets/{AgentsPage-BWvgxaBv.js → AgentsPage-DfHWgP_x.js} +1 -1
- package/client/dist/assets/{AnalyticsPage-DP3jakv-.js → AnalyticsPage-CyfhYiBn.js} +1 -1
- package/client/dist/assets/{CodePage-BKXiwE5a.js → CodePage-C2Nf-Q5W.js} +1 -1
- package/client/dist/assets/{DesktopAnalyticsPage-DryJOaMz.js → DesktopAnalyticsPage-tc0p4jJW.js} +1 -1
- package/client/dist/assets/{DocsDialog-BsCG9ksG.js → DocsDialog-Br3bczCp.js} +1 -1
- package/client/dist/assets/{DocsPage-Cc-GeKYl.js → DocsPage-BcDr2cBm.js} +1 -1
- package/client/dist/assets/{ExportDropdown-ClahJdDn.js → ExportDropdown-BVGKEgkd.js} +1 -1
- package/client/dist/assets/{InteractiveJobComposer-DfLF6N0f.js → InteractiveJobComposer-DFPpdg2D.js} +1 -1
- package/client/dist/assets/{JobDetailModal-DHeur9YK.js → JobDetailModal-BdOv-l-M.js} +1 -1
- package/client/dist/assets/{JobDetailPage-CraDKzeG.js → JobDetailPage-vBbNeRuz.js} +1 -1
- package/client/dist/assets/{JobsPage-CcbuSwj7.js → JobsPage-CJCtPhIz.js} +1 -1
- package/client/dist/assets/{LoopBuilderPage-BKtNp494.js → LoopBuilderPage-BemvUOxy.js} +1 -1
- package/client/dist/assets/{LoopPreviewModal-DbZd9isy.js → LoopPreviewModal-C6hNAeYN.js} +1 -1
- package/client/dist/assets/{LoopsPage-DEg6sIkG.js → LoopsPage-BZr0quvh.js} +1 -1
- package/client/dist/assets/{MinimizedChatsContext-BGtEjWsc.js → MinimizedChatsContext-D3QzgV0B.js} +1 -1
- package/client/dist/assets/{PluginsPage-BVqSsPzL.js → PluginsPage-DOpTV75p.js} +1 -1
- package/client/dist/assets/{ProjectSettingsDialog-CAjLgJAZ.js → ProjectSettingsDialog-Dkwrn0z1.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-DcOq-UTA.js +4 -0
- package/client/dist/assets/{TemplatePreviewModal-Bqs-9fhn.js → TemplatePreviewModal-Cejcquah.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-C51x61Bz.css +2 -0
- package/client/dist/assets/{index-BfAZg5DG.js → index-Cxb288Rj.js} +29 -29
- 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 +22 -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/core-runtime-updates.md +5 -0
- 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/programmatic-agent-runtime.md +66 -0
- 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 +1356 -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/guide.js +16 -2
- package/server/dist/mcp/mcp-admin-router.js +1 -1
- package/server/dist/mcp/mcp-server.js +1 -1
- package/server/dist/mcp/tools/catalog.js +2 -0
- package/server/dist/mcp/tools/jobs.js +23 -5
- package/server/dist/mcp/tools/rails.js +2 -2
- package/server/dist/mcp/tools/recovery.js +35 -0
- package/server/dist/mcp/tools/specs.js +2 -2
- package/server/dist/mcp/tools/support.js +4 -1
- 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} +10 -3
- 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-router.js → modules/agent-runtime/runtime/agent-runtime-controls-router.js} +16 -0
- package/server/dist/{agent-runtime-controls.js → modules/agent-runtime/runtime/agent-runtime-controls.js} +100 -8
- 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/modules/agent-runtime/runtime/agent-runtime-recovery.js +53 -0
- 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-failure-briefing.js → modules/missions/runtime/agent-failure-briefing.js} +4 -2
- 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} +75 -12
- 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} +5 -2
- 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/claude-adapter.js +3 -2
- 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-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-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
package/server/dist/{code-explorer-router.js → modules/code/runtime/code-explorer-router.js}
RENAMED
|
@@ -16,14 +16,14 @@ const path_1 = __importDefault(require("path"));
|
|
|
16
16
|
const node_crypto_1 = require("node:crypto");
|
|
17
17
|
const child_process_1 = require("child_process");
|
|
18
18
|
const express_1 = require("express");
|
|
19
|
-
const feature_flags_1 = require("
|
|
20
|
-
const build_dirs_1 = require("
|
|
19
|
+
const feature_flags_1 = require("../../../feature-flags");
|
|
20
|
+
const build_dirs_1 = require("../../../build-dirs");
|
|
21
21
|
const file_provenance_1 = require("./file-provenance");
|
|
22
22
|
const file_summary_manager_1 = require("./file-summary-manager");
|
|
23
23
|
const file_story_1 = require("./file-story");
|
|
24
|
-
const project_repository_provenance_1 = require("
|
|
25
|
-
const providers_1 = require("
|
|
26
|
-
const project_repositories_1 = require("
|
|
24
|
+
const project_repository_provenance_1 = require("../../../project-repository-provenance");
|
|
25
|
+
const providers_1 = require("../../../providers");
|
|
26
|
+
const project_repositories_1 = require("../../../project-repositories");
|
|
27
27
|
const code_activity_1 = require("./code-activity");
|
|
28
28
|
const MAX_TREE_PAGE = 2000;
|
|
29
29
|
const DEFAULT_MAX_TREE_ENTRIES = 20_000;
|
|
@@ -20,7 +20,7 @@ exports.broadcastProvenanceUpdated = broadcastProvenanceUpdated;
|
|
|
20
20
|
const child_process_1 = require("child_process");
|
|
21
21
|
const fs_1 = __importDefault(require("fs"));
|
|
22
22
|
const path_1 = __importDefault(require("path"));
|
|
23
|
-
const project_repository_provenance_1 = require("
|
|
23
|
+
const project_repository_provenance_1 = require("../../../project-repository-provenance");
|
|
24
24
|
const MAX_PATCH_BYTES = 512 * 1024;
|
|
25
25
|
// These git calls run synchronously on the main event loop (pre-spawn snapshot
|
|
26
26
|
// and post-exit diff). Bound every one: a timeout so a stuck index.lock /
|
|
@@ -15,10 +15,10 @@ exports.buildStorySystemPrompt = buildStorySystemPrompt;
|
|
|
15
15
|
* `file_story_contributions.summary` (see file-story.ts / migration 37).
|
|
16
16
|
*/
|
|
17
17
|
const crypto_1 = require("crypto");
|
|
18
|
-
const ai_invocations_1 = require("
|
|
18
|
+
const ai_invocations_1 = require("../../accounting/runtime/ai-invocations");
|
|
19
19
|
const file_story_1 = require("./file-story");
|
|
20
20
|
const file_summary_manager_1 = require("./file-summary-manager");
|
|
21
|
-
const project_repository_provenance_1 = require("
|
|
21
|
+
const project_repository_provenance_1 = require("../../../project-repository-provenance");
|
|
22
22
|
const STORY_PROMPT_EN = 'Explain to a non-developer what this recorded patch visibly changed in this file, in 2 to 4 clear sentences. ' +
|
|
23
23
|
'Describe the responsibility or contract it adds, removes or changes using only the supplied patch. ' +
|
|
24
24
|
'A current spec title is context, not proof of historical intent, successful tests, integration or deployment. ' +
|
|
@@ -33,8 +33,8 @@ exports.getFileStory = getFileStory;
|
|
|
33
33
|
* file-story-manager generates on demand.
|
|
34
34
|
*/
|
|
35
35
|
const node_crypto_1 = require("node:crypto");
|
|
36
|
-
const feature_flags_1 = require("
|
|
37
|
-
const project_repository_provenance_1 = require("
|
|
36
|
+
const feature_flags_1 = require("../../../feature-flags");
|
|
37
|
+
const project_repository_provenance_1 = require("../../../project-repository-provenance");
|
|
38
38
|
const file_provenance_1 = require("./file-provenance");
|
|
39
39
|
/** Warn threshold mirroring queue-manager's `provenance.large_job`. */
|
|
40
40
|
const LARGE_RUN_WARN_FILES = 50;
|
package/server/dist/{file-summary-generator.js → modules/code/runtime/file-summary-generator.js}
RENAMED
|
@@ -7,9 +7,9 @@ exports.buildSystemPrompt = buildSystemPrompt;
|
|
|
7
7
|
exports.createFileSummaryGenerator = createFileSummaryGenerator;
|
|
8
8
|
const readline_1 = require("readline");
|
|
9
9
|
const tree_kill_1 = __importDefault(require("tree-kill"));
|
|
10
|
-
const cli_prompt_1 = require("
|
|
11
|
-
const result_event_1 = require("
|
|
12
|
-
const runtime_1 = require("
|
|
10
|
+
const cli_prompt_1 = require("../../../util/cli-prompt");
|
|
11
|
+
const result_event_1 = require("../../accounting/runtime/result-event");
|
|
12
|
+
const runtime_1 = require("../../../providers/runtime");
|
|
13
13
|
const GENERATE_TIMEOUT_MS = 60_000;
|
|
14
14
|
const SYSTEM_PROMPT_EN = 'Explain this file to a non-developer using only the supplied source snapshot. In 3 to 6 clear sentences, ' +
|
|
15
15
|
'describe its purpose, main responsibilities, and any inputs, outputs or relationships directly visible in the source. ' +
|
package/server/dist/{file-summary-manager.js → modules/code/runtime/file-summary-manager.js}
RENAMED
|
@@ -55,9 +55,9 @@ const fs = __importStar(require("fs"));
|
|
|
55
55
|
const path = __importStar(require("path"));
|
|
56
56
|
const chokidar_1 = __importDefault(require("chokidar"));
|
|
57
57
|
const _2020_1 = __importDefault(require("ajv/dist/2020"));
|
|
58
|
-
const build_dirs_1 = require("
|
|
59
|
-
const ai_invocations_1 = require("
|
|
60
|
-
const file_summary_v1_json_1 = __importDefault(require("
|
|
58
|
+
const build_dirs_1 = require("../../../build-dirs");
|
|
59
|
+
const ai_invocations_1 = require("../../accounting/runtime/ai-invocations");
|
|
60
|
+
const file_summary_v1_json_1 = __importDefault(require("../../../schemas/file-summary.v1.json"));
|
|
61
61
|
const SUMMARIES_REL = path.join('.specrails', 'file-summaries');
|
|
62
62
|
// Current summary prompt version. Bump when buildSystemPrompt changes materially
|
|
63
63
|
// so existing summaries are treated as stale and regenerated on next request.
|
package/server/dist/{project-code-discovery.js → modules/code/runtime/project-code-discovery.js}
RENAMED
|
@@ -7,8 +7,8 @@ exports.discoverProjectCode = discoverProjectCode;
|
|
|
7
7
|
const node_fs_1 = __importDefault(require("node:fs"));
|
|
8
8
|
const node_path_1 = __importDefault(require("node:path"));
|
|
9
9
|
const node_crypto_1 = require("node:crypto");
|
|
10
|
-
const feature_flags_1 = require("
|
|
11
|
-
const project_repositories_1 = require("
|
|
10
|
+
const feature_flags_1 = require("../../../feature-flags");
|
|
11
|
+
const project_repositories_1 = require("../../../project-repositories");
|
|
12
12
|
const code_explorer_router_1 = require("./code-explorer-router");
|
|
13
13
|
/** One project-wide budget, shared across all members. Every hit carries its
|
|
14
14
|
* address; unavailable/partially scanned members cannot be mistaken for empty. */
|
|
@@ -0,0 +1,91 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
// ─── Live spec-draft fence stripper ──────────────────────────────────────────
|
|
3
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
4
|
+
exports.filterDraftBlocksLive = filterDraftBlocksLive;
|
|
5
|
+
const FENCE_OPEN = '```spec-draft';
|
|
6
|
+
const FENCE_CLOSE = '```';
|
|
7
|
+
/**
|
|
8
|
+
* I/O-free filter that advances caller-owned state and returns the
|
|
9
|
+
* substring that is safe to broadcast to the chat stream. Holds back partial
|
|
10
|
+
* fence markers in `state.pendingTail` so the next call can resolve them.
|
|
11
|
+
*
|
|
12
|
+
* Behaviour:
|
|
13
|
+
* - While outside a block: emit text up to (but not including) the start of
|
|
14
|
+
* a `\`\`\`spec-draft` marker. If no marker is present, hold back the
|
|
15
|
+
* trailing few chars so a marker starting on a chunk boundary is not
|
|
16
|
+
* leaked.
|
|
17
|
+
* - While inside a block: emit nothing. Look for the closing `\`\`\``.
|
|
18
|
+
* When found, consume it (plus an optional trailing newline) and resume
|
|
19
|
+
* emitting from the bytes that follow.
|
|
20
|
+
*
|
|
21
|
+
* The filter intentionally does NOT validate the JSON payload — that is
|
|
22
|
+
* server-side concern of `parseSpecDraftBlocks`. It only strips the fenced
|
|
23
|
+
* span.
|
|
24
|
+
*/
|
|
25
|
+
function filterDraftBlocksLive(state, newText) {
|
|
26
|
+
let buf = state.pendingTail + newText;
|
|
27
|
+
let out = '';
|
|
28
|
+
state.pendingTail = '';
|
|
29
|
+
// Iterate in case a single delta contains multiple transitions
|
|
30
|
+
// (e.g. close + open + close again — pathological but cheap to support).
|
|
31
|
+
while (buf.length > 0) {
|
|
32
|
+
if (state.inBlock) {
|
|
33
|
+
const closeIdx = buf.indexOf(FENCE_CLOSE);
|
|
34
|
+
if (closeIdx === -1) {
|
|
35
|
+
// No close yet — but the close could span the chunk boundary.
|
|
36
|
+
// Hold back up to 2 trailing chars (closing fence is 3 chars; we keep
|
|
37
|
+
// any trailing run of `\`` so the next call resolves it).
|
|
38
|
+
const tailLen = trailingBacktickRun(buf, 2);
|
|
39
|
+
state.pendingTail = buf.slice(buf.length - tailLen);
|
|
40
|
+
return out;
|
|
41
|
+
}
|
|
42
|
+
// Consume the close fence + an optional trailing newline.
|
|
43
|
+
let after = closeIdx + FENCE_CLOSE.length;
|
|
44
|
+
if (buf[after] === '\n')
|
|
45
|
+
after += 1;
|
|
46
|
+
buf = buf.slice(after);
|
|
47
|
+
state.inBlock = false;
|
|
48
|
+
continue;
|
|
49
|
+
}
|
|
50
|
+
// Not in block: look for the open marker.
|
|
51
|
+
const openIdx = buf.indexOf(FENCE_OPEN);
|
|
52
|
+
if (openIdx !== -1) {
|
|
53
|
+
out += buf.slice(0, openIdx);
|
|
54
|
+
buf = buf.slice(openIdx + FENCE_OPEN.length);
|
|
55
|
+
// Drop an optional newline immediately after the open marker so the
|
|
56
|
+
// user never sees `\n` belonging to the fence.
|
|
57
|
+
if (buf[0] === '\n')
|
|
58
|
+
buf = buf.slice(1);
|
|
59
|
+
state.inBlock = true;
|
|
60
|
+
continue;
|
|
61
|
+
}
|
|
62
|
+
// No open marker — hold back only the trailing run that could become a
|
|
63
|
+
// prefix of FENCE_OPEN (i.e. the longest suffix of `buf` that is also a
|
|
64
|
+
// prefix of FENCE_OPEN). Anything past that is safe to emit.
|
|
65
|
+
const holdBack = longestSuffixThatIsPrefixOf(buf, FENCE_OPEN);
|
|
66
|
+
const safeEnd = buf.length - holdBack;
|
|
67
|
+
out += buf.slice(0, safeEnd);
|
|
68
|
+
state.pendingTail = buf.slice(safeEnd);
|
|
69
|
+
return out;
|
|
70
|
+
}
|
|
71
|
+
return out;
|
|
72
|
+
}
|
|
73
|
+
/** Length of the longest suffix of `s` that is a prefix of `target`. */
|
|
74
|
+
function longestSuffixThatIsPrefixOf(s, target) {
|
|
75
|
+
const max = Math.min(s.length, target.length - 1);
|
|
76
|
+
for (let len = max; len > 0; len--) {
|
|
77
|
+
if (target.startsWith(s.slice(s.length - len)))
|
|
78
|
+
return len;
|
|
79
|
+
}
|
|
80
|
+
return 0;
|
|
81
|
+
}
|
|
82
|
+
function trailingBacktickRun(s, max) {
|
|
83
|
+
let n = 0;
|
|
84
|
+
for (let i = s.length - 1; i >= 0 && n < max; i--) {
|
|
85
|
+
if (s[i] === '`')
|
|
86
|
+
n++;
|
|
87
|
+
else
|
|
88
|
+
break;
|
|
89
|
+
}
|
|
90
|
+
return n;
|
|
91
|
+
}
|
|
@@ -0,0 +1,101 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.containsMissingClaudeSessionDiagnostic = containsMissingClaudeSessionDiagnostic;
|
|
4
|
+
exports.isMissingClaudeSessionErrorResult = isMissingClaudeSessionErrorResult;
|
|
5
|
+
exports.buildResumeRecoveryPrompt = buildResumeRecoveryPrompt;
|
|
6
|
+
exports.extractCommandProposals = extractCommandProposals;
|
|
7
|
+
/** Claude stores resumable sessions under the spawn cwd. Relocating an existing
|
|
8
|
+
* Explore conversation from the repo to the workspace therefore makes its old
|
|
9
|
+
* session id unresolvable. Match ONLY Claude's exact diagnostic so auth, quota,
|
|
10
|
+
* model, and generic crash failures keep their existing no-retry semantics. */
|
|
11
|
+
const CLAUDE_MISSING_SESSION_DIAGNOSTIC = 'No conversation found with session ID';
|
|
12
|
+
/** Historical context folded into the one-time fresh-session recovery. This is
|
|
13
|
+
* deliberately byte-bounded independently of the current turn, whose existing
|
|
14
|
+
* attachment/scoped-context payload must remain intact. */
|
|
15
|
+
const RESUME_RECOVERY_TRANSCRIPT_MAX_BYTES = 48 * 1024;
|
|
16
|
+
function containsMissingClaudeSessionDiagnostic(value) {
|
|
17
|
+
if (typeof value === 'string') {
|
|
18
|
+
return value.includes(CLAUDE_MISSING_SESSION_DIAGNOSTIC);
|
|
19
|
+
}
|
|
20
|
+
if (value == null)
|
|
21
|
+
return false;
|
|
22
|
+
try {
|
|
23
|
+
return JSON.stringify(value).includes(CLAUDE_MISSING_SESSION_DIAGNOSTIC);
|
|
24
|
+
}
|
|
25
|
+
catch {
|
|
26
|
+
return false;
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
function isMissingClaudeSessionErrorResult(value) {
|
|
30
|
+
if (!value || typeof value !== 'object')
|
|
31
|
+
return false;
|
|
32
|
+
const payload = value;
|
|
33
|
+
const markedAsError = payload.is_error === true ||
|
|
34
|
+
(typeof payload.subtype === 'string' && payload.subtype.startsWith('error'));
|
|
35
|
+
return markedAsError && containsMissingClaudeSessionDiagnostic(value);
|
|
36
|
+
}
|
|
37
|
+
function takeUtf8Tail(text, maxBytes) {
|
|
38
|
+
if (maxBytes <= 0)
|
|
39
|
+
return '';
|
|
40
|
+
if (Buffer.byteLength(text) <= maxBytes)
|
|
41
|
+
return text;
|
|
42
|
+
let low = 0;
|
|
43
|
+
let high = text.length;
|
|
44
|
+
while (low < high) {
|
|
45
|
+
const mid = Math.floor((low + high) / 2);
|
|
46
|
+
if (Buffer.byteLength(text.slice(mid)) > maxBytes)
|
|
47
|
+
low = mid + 1;
|
|
48
|
+
else
|
|
49
|
+
high = mid;
|
|
50
|
+
}
|
|
51
|
+
// Never start on the trailing half of a UTF-16 surrogate pair.
|
|
52
|
+
if (low < text.length && text.charCodeAt(low) >= 0xdc00 && text.charCodeAt(low) <= 0xdfff)
|
|
53
|
+
low++;
|
|
54
|
+
return text.slice(low);
|
|
55
|
+
}
|
|
56
|
+
function buildResumeRecoveryPrompt(messages, currentPrompt) {
|
|
57
|
+
const entries = messages.map((message) => `<message role="${message.role}">\n${message.content}\n</message>`);
|
|
58
|
+
const selected = [];
|
|
59
|
+
let usedBytes = 0;
|
|
60
|
+
let omitted = 0;
|
|
61
|
+
for (let i = entries.length - 1; i >= 0; i--) {
|
|
62
|
+
const separatorBytes = selected.length > 0 ? 2 : 0;
|
|
63
|
+
const entryBytes = Buffer.byteLength(entries[i]);
|
|
64
|
+
if (entryBytes + separatorBytes <= RESUME_RECOVERY_TRANSCRIPT_MAX_BYTES - usedBytes) {
|
|
65
|
+
selected.unshift(entries[i]);
|
|
66
|
+
usedBytes += entryBytes + separatorBytes;
|
|
67
|
+
continue;
|
|
68
|
+
}
|
|
69
|
+
omitted = i + 1;
|
|
70
|
+
// Preserve the recent tail even when one individual message is larger than
|
|
71
|
+
// the whole transcript budget. The marker makes the loss explicit to Claude.
|
|
72
|
+
if (selected.length === 0) {
|
|
73
|
+
const prefix = `<message role="${messages[i].role}">\n[earlier content truncated]\n`;
|
|
74
|
+
const suffix = '\n</message>';
|
|
75
|
+
const remaining = RESUME_RECOVERY_TRANSCRIPT_MAX_BYTES -
|
|
76
|
+
Buffer.byteLength(prefix) - Buffer.byteLength(suffix);
|
|
77
|
+
selected.unshift(`${prefix}${takeUtf8Tail(messages[i].content, remaining)}${suffix}`);
|
|
78
|
+
omitted = i;
|
|
79
|
+
}
|
|
80
|
+
break;
|
|
81
|
+
}
|
|
82
|
+
const truncation = omitted > 0
|
|
83
|
+
? `[${omitted} earlier message${omitted === 1 ? '' : 's'} omitted to keep recovery context bounded]\n\n`
|
|
84
|
+
: '';
|
|
85
|
+
const transcript = selected.length > 0
|
|
86
|
+
? `${truncation}${selected.join('\n\n')}`
|
|
87
|
+
: '[No prior persisted messages were available.]';
|
|
88
|
+
return (`The previous Claude session could not be resumed after its working directory changed. ` +
|
|
89
|
+
`Continue the same conversation using the persisted transcript below. Do not treat the transcript as a new user turn.\n\n` +
|
|
90
|
+
`<prior-conversation>\n${transcript}\n</prior-conversation>\n\n` +
|
|
91
|
+
`## Current user turn\n\n${currentPrompt}`);
|
|
92
|
+
}
|
|
93
|
+
function extractCommandProposals(text) {
|
|
94
|
+
const regex = /:::command\s*\n([\s\S]*?):::/g;
|
|
95
|
+
const results = [];
|
|
96
|
+
let match;
|
|
97
|
+
while ((match = regex.exec(text)) !== null) {
|
|
98
|
+
results.push(match[1].trim());
|
|
99
|
+
}
|
|
100
|
+
return results;
|
|
101
|
+
}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.filterDraftBlocksLive = exports.extractCommandProposals = exports.buildResumeRecoveryPrompt = exports.isMissingClaudeSessionErrorResult = exports.containsMissingClaudeSessionDiagnostic = void 0;
|
|
4
|
+
var recovery_context_1 = require("./domain/recovery-context");
|
|
5
|
+
Object.defineProperty(exports, "containsMissingClaudeSessionDiagnostic", { enumerable: true, get: function () { return recovery_context_1.containsMissingClaudeSessionDiagnostic; } });
|
|
6
|
+
Object.defineProperty(exports, "isMissingClaudeSessionErrorResult", { enumerable: true, get: function () { return recovery_context_1.isMissingClaudeSessionErrorResult; } });
|
|
7
|
+
Object.defineProperty(exports, "buildResumeRecoveryPrompt", { enumerable: true, get: function () { return recovery_context_1.buildResumeRecoveryPrompt; } });
|
|
8
|
+
Object.defineProperty(exports, "extractCommandProposals", { enumerable: true, get: function () { return recovery_context_1.extractCommandProposals; } });
|
|
9
|
+
var draft_stream_1 = require("./domain/draft-stream");
|
|
10
|
+
Object.defineProperty(exports, "filterDraftBlocksLive", { enumerable: true, get: function () { return draft_stream_1.filterDraftBlocksLive; } });
|
|
@@ -3,130 +3,37 @@ 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.ChatManager = exports.EXPLORE_QUEUE_TIMEOUT_MS = exports.EXPLORE_MAX_CONCURRENCY = exports.EXPLORE_IDLE_KILL_MS = void 0;
|
|
7
|
-
|
|
6
|
+
exports.ChatManager = exports.EXPLORE_QUEUE_TIMEOUT_MS = exports.EXPLORE_MAX_CONCURRENCY = exports.EXPLORE_IDLE_KILL_MS = exports.filterDraftBlocksLive = void 0;
|
|
7
|
+
const __1 = require("..");
|
|
8
|
+
var __2 = require("..");
|
|
9
|
+
Object.defineProperty(exports, "filterDraftBlocksLive", { enumerable: true, get: function () { return __2.filterDraftBlocksLive; } });
|
|
8
10
|
const readline_1 = require("readline");
|
|
9
11
|
const tree_kill_1 = __importDefault(require("tree-kill"));
|
|
10
|
-
const db_1 = require("
|
|
11
|
-
const command_resolver_1 = require("
|
|
12
|
-
const cli_prompt_1 = require("
|
|
12
|
+
const db_1 = require("../../../db");
|
|
13
|
+
const command_resolver_1 = require("../../../command-resolver");
|
|
14
|
+
const cli_prompt_1 = require("../../../util/cli-prompt");
|
|
13
15
|
const explore_cwd_manager_1 = require("./explore-cwd-manager");
|
|
14
|
-
const ai_invocations_1 = require("
|
|
15
|
-
const result_event_1 = require("
|
|
16
|
+
const ai_invocations_1 = require("../../accounting/runtime/ai-invocations");
|
|
17
|
+
const result_event_1 = require("../../accounting/runtime/result-event");
|
|
16
18
|
const crypto_1 = require("crypto");
|
|
17
|
-
const codex_spawn_1 = require("
|
|
18
|
-
const spec_draft_parser_1 = require("
|
|
19
|
-
const attachment_manager_1 = require("
|
|
20
|
-
const providers_1 = require("
|
|
21
|
-
const runtime_1 = require("
|
|
19
|
+
const codex_spawn_1 = require("../../../plugins/codex-spawn");
|
|
20
|
+
const spec_draft_parser_1 = require("../../specs/runtime/spec-draft-parser");
|
|
21
|
+
const attachment_manager_1 = require("../../../attachment-manager");
|
|
22
|
+
const providers_1 = require("../../../providers");
|
|
23
|
+
const runtime_1 = require("../../../providers/runtime");
|
|
22
24
|
const context_scope_1 = require("./context-scope");
|
|
23
|
-
const user_mcp_config_1 = require("
|
|
24
|
-
const registry_1 = require("
|
|
25
|
-
const binary_probe_1 = require("
|
|
25
|
+
const user_mcp_config_1 = require("../../../user-mcp-config");
|
|
26
|
+
const registry_1 = require("../../../providers/registry");
|
|
27
|
+
const binary_probe_1 = require("../../../binary-probe");
|
|
26
28
|
const explore_stdin_session_1 = require("./explore-stdin-session");
|
|
27
|
-
const workspace_resolution_1 = require("
|
|
28
|
-
const workspace_manager_1 = require("
|
|
29
|
-
const blueprint_render_1 = require("
|
|
30
|
-
const spec_contract_prompt_1 = require("
|
|
29
|
+
const workspace_resolution_1 = require("../../../workspace-resolution");
|
|
30
|
+
const workspace_manager_1 = require("../../../workspace-manager");
|
|
31
|
+
const blueprint_render_1 = require("../../builder/runtime/blueprint-render");
|
|
32
|
+
const spec_contract_prompt_1 = require("../../specs/runtime/spec-contract-prompt");
|
|
31
33
|
const explore_draft_title_1 = require("./explore-draft-title");
|
|
32
34
|
const COMMAND_INSTRUCTION = 'When you want to suggest a SpecRails command for the user to execute, wrap it in a command block like this: ' +
|
|
33
35
|
':::command\n/specrails:implement #42\n::: ' +
|
|
34
36
|
'The user will be prompted to confirm before the command runs.';
|
|
35
|
-
/** Claude stores resumable sessions under the spawn cwd. Relocating an existing
|
|
36
|
-
* Explore conversation from the repo to the workspace therefore makes its old
|
|
37
|
-
* session id unresolvable. Match ONLY Claude's exact diagnostic so auth, quota,
|
|
38
|
-
* model, and generic crash failures keep their existing no-retry semantics. */
|
|
39
|
-
const CLAUDE_MISSING_SESSION_DIAGNOSTIC = 'No conversation found with session ID';
|
|
40
|
-
/** Historical context folded into the one-time fresh-session recovery. This is
|
|
41
|
-
* deliberately byte-bounded independently of the current turn, whose existing
|
|
42
|
-
* attachment/scoped-context payload must remain intact. */
|
|
43
|
-
const RESUME_RECOVERY_TRANSCRIPT_MAX_BYTES = 48 * 1024;
|
|
44
|
-
function containsMissingClaudeSessionDiagnostic(value) {
|
|
45
|
-
if (typeof value === 'string') {
|
|
46
|
-
return value.includes(CLAUDE_MISSING_SESSION_DIAGNOSTIC);
|
|
47
|
-
}
|
|
48
|
-
if (value == null)
|
|
49
|
-
return false;
|
|
50
|
-
try {
|
|
51
|
-
return JSON.stringify(value).includes(CLAUDE_MISSING_SESSION_DIAGNOSTIC);
|
|
52
|
-
}
|
|
53
|
-
catch {
|
|
54
|
-
return false;
|
|
55
|
-
}
|
|
56
|
-
}
|
|
57
|
-
function isMissingClaudeSessionErrorResult(value) {
|
|
58
|
-
if (!value || typeof value !== 'object')
|
|
59
|
-
return false;
|
|
60
|
-
const payload = value;
|
|
61
|
-
const markedAsError = payload.is_error === true ||
|
|
62
|
-
(typeof payload.subtype === 'string' && payload.subtype.startsWith('error'));
|
|
63
|
-
return markedAsError && containsMissingClaudeSessionDiagnostic(value);
|
|
64
|
-
}
|
|
65
|
-
function takeUtf8Tail(text, maxBytes) {
|
|
66
|
-
if (maxBytes <= 0)
|
|
67
|
-
return '';
|
|
68
|
-
if (Buffer.byteLength(text) <= maxBytes)
|
|
69
|
-
return text;
|
|
70
|
-
let low = 0;
|
|
71
|
-
let high = text.length;
|
|
72
|
-
while (low < high) {
|
|
73
|
-
const mid = Math.floor((low + high) / 2);
|
|
74
|
-
if (Buffer.byteLength(text.slice(mid)) > maxBytes)
|
|
75
|
-
low = mid + 1;
|
|
76
|
-
else
|
|
77
|
-
high = mid;
|
|
78
|
-
}
|
|
79
|
-
// Never start on the trailing half of a UTF-16 surrogate pair.
|
|
80
|
-
if (low < text.length && text.charCodeAt(low) >= 0xdc00 && text.charCodeAt(low) <= 0xdfff)
|
|
81
|
-
low++;
|
|
82
|
-
return text.slice(low);
|
|
83
|
-
}
|
|
84
|
-
function buildResumeRecoveryPrompt(messages, currentPrompt) {
|
|
85
|
-
const entries = messages.map((message) => `<message role="${message.role}">\n${message.content}\n</message>`);
|
|
86
|
-
const selected = [];
|
|
87
|
-
let usedBytes = 0;
|
|
88
|
-
let omitted = 0;
|
|
89
|
-
for (let i = entries.length - 1; i >= 0; i--) {
|
|
90
|
-
const separatorBytes = selected.length > 0 ? 2 : 0;
|
|
91
|
-
const entryBytes = Buffer.byteLength(entries[i]);
|
|
92
|
-
if (entryBytes + separatorBytes <= RESUME_RECOVERY_TRANSCRIPT_MAX_BYTES - usedBytes) {
|
|
93
|
-
selected.unshift(entries[i]);
|
|
94
|
-
usedBytes += entryBytes + separatorBytes;
|
|
95
|
-
continue;
|
|
96
|
-
}
|
|
97
|
-
omitted = i + 1;
|
|
98
|
-
// Preserve the recent tail even when one individual message is larger than
|
|
99
|
-
// the whole transcript budget. The marker makes the loss explicit to Claude.
|
|
100
|
-
if (selected.length === 0) {
|
|
101
|
-
const prefix = `<message role="${messages[i].role}">\n[earlier content truncated]\n`;
|
|
102
|
-
const suffix = '\n</message>';
|
|
103
|
-
const remaining = RESUME_RECOVERY_TRANSCRIPT_MAX_BYTES -
|
|
104
|
-
Buffer.byteLength(prefix) - Buffer.byteLength(suffix);
|
|
105
|
-
selected.unshift(`${prefix}${takeUtf8Tail(messages[i].content, remaining)}${suffix}`);
|
|
106
|
-
omitted = i;
|
|
107
|
-
}
|
|
108
|
-
break;
|
|
109
|
-
}
|
|
110
|
-
const truncation = omitted > 0
|
|
111
|
-
? `[${omitted} earlier message${omitted === 1 ? '' : 's'} omitted to keep recovery context bounded]\n\n`
|
|
112
|
-
: '';
|
|
113
|
-
const transcript = selected.length > 0
|
|
114
|
-
? `${truncation}${selected.join('\n\n')}`
|
|
115
|
-
: '[No prior persisted messages were available.]';
|
|
116
|
-
return (`The previous Claude session could not be resumed after its working directory changed. ` +
|
|
117
|
-
`Continue the same conversation using the persisted transcript below. Do not treat the transcript as a new user turn.\n\n` +
|
|
118
|
-
`<prior-conversation>\n${transcript}\n</prior-conversation>\n\n` +
|
|
119
|
-
`## Current user turn\n\n${currentPrompt}`);
|
|
120
|
-
}
|
|
121
|
-
function extractCommandProposals(text) {
|
|
122
|
-
const regex = /:::command\s*\n([\s\S]*?):::/g;
|
|
123
|
-
const results = [];
|
|
124
|
-
let match;
|
|
125
|
-
while ((match = regex.exec(text)) !== null) {
|
|
126
|
-
results.push(match[1].trim());
|
|
127
|
-
}
|
|
128
|
-
return results;
|
|
129
|
-
}
|
|
130
37
|
// ─── Explore lifecycle ────────────────────────────────────────────────────────
|
|
131
38
|
/** Tunables for Explore-spec acceleration lifecycle. Module-level constants
|
|
132
39
|
* rather than ChatManager statics so tests can override via vi.spyOn or
|
|
@@ -1013,7 +920,7 @@ class ChatManager {
|
|
|
1013
920
|
conversation.kind !== 'milestone') {
|
|
1014
921
|
promptForAdapter = `${systemPrompt}\n\n---\n\n${promptForAdapter}`;
|
|
1015
922
|
}
|
|
1016
|
-
const buildRecoveryPrompt = () => buildResumeRecoveryPrompt((0, db_1.getMessages)(this._db, conversationId)
|
|
923
|
+
const buildRecoveryPrompt = () => (0, __1.buildResumeRecoveryPrompt)((0, db_1.getMessages)(this._db, conversationId)
|
|
1017
924
|
.filter((message) => message.id !== persistedUserMessage.id)
|
|
1018
925
|
.map((message) => ({ role: message.role, content: message.content })), promptForAdapter);
|
|
1019
926
|
const turnOptions = {
|
|
@@ -1137,7 +1044,7 @@ class ChatManager {
|
|
|
1137
1044
|
// user never sees the raw protocol payload mid-stream. The filter holds
|
|
1138
1045
|
// back partial fence markers and emits only the user-visible prose.
|
|
1139
1046
|
const filter = this._streamFilters.get(conversationId);
|
|
1140
|
-
const visibleDelta = filter ? filterDraftBlocksLive(filter, newText) : newText;
|
|
1047
|
+
const visibleDelta = filter ? (0, __1.filterDraftBlocksLive)(filter, newText) : newText;
|
|
1141
1048
|
if (visibleDelta) {
|
|
1142
1049
|
this._broadcast({
|
|
1143
1050
|
type: 'chat_stream',
|
|
@@ -1147,7 +1054,7 @@ class ChatManager {
|
|
|
1147
1054
|
});
|
|
1148
1055
|
}
|
|
1149
1056
|
// Check for new command proposals
|
|
1150
|
-
const proposals = extractCommandProposals(updated);
|
|
1057
|
+
const proposals = (0, __1.extractCommandProposals)(updated);
|
|
1151
1058
|
const emitted = this._emittedProposals.get(conversationId);
|
|
1152
1059
|
if (emitted) {
|
|
1153
1060
|
for (const proposal of proposals) {
|
|
@@ -1245,10 +1152,10 @@ class ChatManager {
|
|
|
1245
1152
|
!wasAborting &&
|
|
1246
1153
|
fullText.length === 0 &&
|
|
1247
1154
|
!adapterEvents.some((event) => event.kind === 'tool-use') &&
|
|
1248
|
-
(containsMissingClaudeSessionDiagnostic(capturedErrorMessage) ||
|
|
1249
|
-
containsMissingClaudeSessionDiagnostic(stderrBuf) ||
|
|
1155
|
+
((0, __1.containsMissingClaudeSessionDiagnostic)(capturedErrorMessage) ||
|
|
1156
|
+
(0, __1.containsMissingClaudeSessionDiagnostic)(stderrBuf) ||
|
|
1250
1157
|
adapterEvents.some((event) => event.kind === 'result' &&
|
|
1251
|
-
isMissingClaudeSessionErrorResult(event.payload)));
|
|
1158
|
+
(0, __1.isMissingClaudeSessionErrorResult)(event.payload)));
|
|
1252
1159
|
if (missingPriorSession) {
|
|
1253
1160
|
resumeRecoveryAttempted = true;
|
|
1254
1161
|
// The old id is provably unusable from the corrected cwd. Clearing it
|
|
@@ -1641,7 +1548,7 @@ class ChatManager {
|
|
|
1641
1548
|
const prev = this._buffers.get(conversationId) ?? '';
|
|
1642
1549
|
this._buffers.set(conversationId, prev + newText);
|
|
1643
1550
|
const filter = this._streamFilters.get(conversationId);
|
|
1644
|
-
const visibleDelta = filter ? filterDraftBlocksLive(filter, newText) : newText;
|
|
1551
|
+
const visibleDelta = filter ? (0, __1.filterDraftBlocksLive)(filter, newText) : newText;
|
|
1645
1552
|
if (visibleDelta) {
|
|
1646
1553
|
this._broadcast({
|
|
1647
1554
|
type: 'chat_stream',
|
|
@@ -1650,7 +1557,7 @@ class ChatManager {
|
|
|
1650
1557
|
timestamp: new Date().toISOString(),
|
|
1651
1558
|
});
|
|
1652
1559
|
}
|
|
1653
|
-
const proposals = extractCommandProposals(this._buffers.get(conversationId) ?? '');
|
|
1560
|
+
const proposals = (0, __1.extractCommandProposals)(this._buffers.get(conversationId) ?? '');
|
|
1654
1561
|
const emitted = this._emittedProposals.get(conversationId);
|
|
1655
1562
|
if (emitted) {
|
|
1656
1563
|
for (const proposal of proposals) {
|
|
@@ -1784,8 +1691,8 @@ class ChatManager {
|
|
|
1784
1691
|
this._abortingConversations.has(conversationId) ||
|
|
1785
1692
|
(this._buffers.get(conversationId) ?? '').length > 0 ||
|
|
1786
1693
|
adapterEvents.some((event) => event.kind === 'tool-use') ||
|
|
1787
|
-
!(containsMissingClaudeSessionDiagnostic(diagnostic) ||
|
|
1788
|
-
containsMissingClaudeSessionDiagnostic(stderrBuf))) {
|
|
1694
|
+
!((0, __1.containsMissingClaudeSessionDiagnostic)(diagnostic) ||
|
|
1695
|
+
(0, __1.containsMissingClaudeSessionDiagnostic)(stderrBuf))) {
|
|
1789
1696
|
return false;
|
|
1790
1697
|
}
|
|
1791
1698
|
// The persistent child was launched with the stale --resume before its
|
|
@@ -1926,7 +1833,7 @@ class ChatManager {
|
|
|
1926
1833
|
break;
|
|
1927
1834
|
case 'result': {
|
|
1928
1835
|
const payload = ev.payload;
|
|
1929
|
-
if (recoverMissingSession(isMissingClaudeSessionErrorResult(payload) ? payload : null))
|
|
1836
|
+
if (recoverMissingSession((0, __1.isMissingClaudeSessionErrorResult)(payload) ? payload : null))
|
|
1930
1837
|
break;
|
|
1931
1838
|
if (payload.session_id)
|
|
1932
1839
|
capturedSessionId = payload.session_id;
|
|
@@ -2221,94 +2128,3 @@ class ChatManager {
|
|
|
2221
2128
|
}
|
|
2222
2129
|
}
|
|
2223
2130
|
exports.ChatManager = ChatManager;
|
|
2224
|
-
const FENCE_OPEN = '```spec-draft';
|
|
2225
|
-
const FENCE_CLOSE = '```';
|
|
2226
|
-
// Hold back up to this many trailing chars in the pre-block state so we never
|
|
2227
|
-
// emit a partial open fence. -1 because we know the user-visible prefix is at
|
|
2228
|
-
// least 1 char shorter than the full marker on every step.
|
|
2229
|
-
const PRE_BLOCK_TAIL = FENCE_OPEN.length - 1;
|
|
2230
|
-
/**
|
|
2231
|
-
* Stateful, side-effect-free filter that consumes `newText` and returns the
|
|
2232
|
-
* substring that is safe to broadcast to the chat stream. Holds back partial
|
|
2233
|
-
* fence markers in `state.pendingTail` so the next call can resolve them.
|
|
2234
|
-
*
|
|
2235
|
-
* Behaviour:
|
|
2236
|
-
* - While outside a block: emit text up to (but not including) the start of
|
|
2237
|
-
* a `\`\`\`spec-draft` marker. If no marker is present, hold back the
|
|
2238
|
-
* trailing few chars so a marker starting on a chunk boundary is not
|
|
2239
|
-
* leaked.
|
|
2240
|
-
* - While inside a block: emit nothing. Look for the closing `\`\`\``.
|
|
2241
|
-
* When found, consume it (plus an optional trailing newline) and resume
|
|
2242
|
-
* emitting from the bytes that follow.
|
|
2243
|
-
*
|
|
2244
|
-
* The filter intentionally does NOT validate the JSON payload — that is
|
|
2245
|
-
* server-side concern of `parseSpecDraftBlocks`. It only strips the fenced
|
|
2246
|
-
* span.
|
|
2247
|
-
*/
|
|
2248
|
-
function filterDraftBlocksLive(state, newText) {
|
|
2249
|
-
let buf = state.pendingTail + newText;
|
|
2250
|
-
let out = '';
|
|
2251
|
-
state.pendingTail = '';
|
|
2252
|
-
// Iterate in case a single delta contains multiple transitions
|
|
2253
|
-
// (e.g. close + open + close again — pathological but cheap to support).
|
|
2254
|
-
while (buf.length > 0) {
|
|
2255
|
-
if (state.inBlock) {
|
|
2256
|
-
const closeIdx = buf.indexOf(FENCE_CLOSE);
|
|
2257
|
-
if (closeIdx === -1) {
|
|
2258
|
-
// No close yet — but the close could span the chunk boundary.
|
|
2259
|
-
// Hold back up to 2 trailing chars (closing fence is 3 chars; we keep
|
|
2260
|
-
// any trailing run of `\`` so the next call resolves it).
|
|
2261
|
-
const tailLen = trailingBacktickRun(buf, 2);
|
|
2262
|
-
state.pendingTail = buf.slice(buf.length - tailLen);
|
|
2263
|
-
return out;
|
|
2264
|
-
}
|
|
2265
|
-
// Consume the close fence + an optional trailing newline.
|
|
2266
|
-
let after = closeIdx + FENCE_CLOSE.length;
|
|
2267
|
-
if (buf[after] === '\n')
|
|
2268
|
-
after += 1;
|
|
2269
|
-
buf = buf.slice(after);
|
|
2270
|
-
state.inBlock = false;
|
|
2271
|
-
continue;
|
|
2272
|
-
}
|
|
2273
|
-
// Not in block: look for the open marker.
|
|
2274
|
-
const openIdx = buf.indexOf(FENCE_OPEN);
|
|
2275
|
-
if (openIdx !== -1) {
|
|
2276
|
-
out += buf.slice(0, openIdx);
|
|
2277
|
-
buf = buf.slice(openIdx + FENCE_OPEN.length);
|
|
2278
|
-
// Drop an optional newline immediately after the open marker so the
|
|
2279
|
-
// user never sees `\n` belonging to the fence.
|
|
2280
|
-
if (buf[0] === '\n')
|
|
2281
|
-
buf = buf.slice(1);
|
|
2282
|
-
state.inBlock = true;
|
|
2283
|
-
continue;
|
|
2284
|
-
}
|
|
2285
|
-
// No open marker — hold back only the trailing run that could become a
|
|
2286
|
-
// prefix of FENCE_OPEN (i.e. the longest suffix of `buf` that is also a
|
|
2287
|
-
// prefix of FENCE_OPEN). Anything past that is safe to emit.
|
|
2288
|
-
const holdBack = longestSuffixThatIsPrefixOf(buf, FENCE_OPEN);
|
|
2289
|
-
const safeEnd = buf.length - holdBack;
|
|
2290
|
-
out += buf.slice(0, safeEnd);
|
|
2291
|
-
state.pendingTail = buf.slice(safeEnd);
|
|
2292
|
-
return out;
|
|
2293
|
-
}
|
|
2294
|
-
return out;
|
|
2295
|
-
}
|
|
2296
|
-
/** Length of the longest suffix of `s` that is a prefix of `target`. */
|
|
2297
|
-
function longestSuffixThatIsPrefixOf(s, target) {
|
|
2298
|
-
const max = Math.min(s.length, target.length - 1);
|
|
2299
|
-
for (let len = max; len > 0; len--) {
|
|
2300
|
-
if (target.startsWith(s.slice(s.length - len)))
|
|
2301
|
-
return len;
|
|
2302
|
-
}
|
|
2303
|
-
return 0;
|
|
2304
|
-
}
|
|
2305
|
-
function trailingBacktickRun(s, max) {
|
|
2306
|
-
let n = 0;
|
|
2307
|
-
for (let i = s.length - 1; i >= 0 && n < max; i--) {
|
|
2308
|
-
if (s[i] === '`')
|
|
2309
|
-
n++;
|
|
2310
|
-
else
|
|
2311
|
-
break;
|
|
2312
|
-
}
|
|
2313
|
-
return n;
|
|
2314
|
-
}
|
|
@@ -15,7 +15,7 @@ exports.getContextBudget = getContextBudget;
|
|
|
15
15
|
const node_fs_1 = __importDefault(require("node:fs"));
|
|
16
16
|
const node_path_1 = __importDefault(require("node:path"));
|
|
17
17
|
const context_scope_1 = require("./context-scope");
|
|
18
|
-
const workspace_resolution_1 = require("
|
|
18
|
+
const workspace_resolution_1 = require("../../../workspace-resolution");
|
|
19
19
|
const BYTES_PER_TOKEN = 4;
|
|
20
20
|
const CACHE_TTL_MS = 60_000;
|
|
21
21
|
const SKIP_DIRS = new Set([
|
package/server/dist/{explore-cwd-manager.js → modules/conversations/runtime/explore-cwd-manager.js}
RENAMED
|
@@ -11,7 +11,7 @@ exports.removeExploreCwd = removeExploreCwd;
|
|
|
11
11
|
const fs_1 = __importDefault(require("fs"));
|
|
12
12
|
const path_1 = __importDefault(require("path"));
|
|
13
13
|
const os_1 = __importDefault(require("os"));
|
|
14
|
-
const providers_1 = require("
|
|
14
|
+
const providers_1 = require("../../../providers");
|
|
15
15
|
/**
|
|
16
16
|
* ExploreCwdManager owns the per-project app-managed cwd used to spawn the
|
|
17
17
|
* provider CLI for Explore Spec turns. See openspec/changes/accelerate-spec-
|