specrails-desktop 2.36.0 → 2.42.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +94 -247
- package/client/dist/assets/ActivityFeedPage-DoEMumQS.js +1 -0
- package/client/dist/assets/AgentBrowserCapture-DIh4K0gh.js +1 -0
- package/client/dist/assets/AgentModeAnalyticsPane-mbq4WEoO.js +2 -0
- package/client/dist/assets/AgentModeCodePane-CKh7zuA4.js +2 -0
- package/client/dist/assets/AgentModeJobsPane-BDokPiLJ.js +1 -0
- package/client/dist/assets/AgentsPage-BFVAZbBj.js +87 -0
- package/client/dist/assets/AnalyticsPage-3Y9LuWwz.js +1 -0
- package/client/dist/assets/CodePage-C9KyuV_C.js +3 -0
- package/client/dist/assets/DesktopAnalyticsPage-Bhi54bXQ.js +1 -0
- package/client/dist/assets/{DocsDialog-C76VdBJC.js → DocsDialog-Dj6mt4ga.js} +2 -2
- package/client/dist/assets/{DocsPage-ziMlj6B6.js → DocsPage-24yWglNI.js} +1 -1
- package/client/dist/assets/ExportDropdown-ophapHrT.js +1 -0
- package/client/dist/assets/InteractiveJobComposer-C1ucmxQh.js +19 -0
- package/client/dist/assets/JobDetailModal-DNWmgVHD.js +1 -0
- package/client/dist/assets/JobDetailPage-BcajZyuu.js +1 -0
- package/client/dist/assets/JobsPage-B9nTZw6e.js +1 -0
- package/client/dist/assets/LoopBuilderPage-Oc48iOFW.js +7 -0
- package/client/dist/assets/LoopPreviewModal-ae0Fr6SU.js +1 -0
- package/client/dist/assets/LoopsPage-CUEqzUBI.js +1 -0
- package/client/dist/assets/MinimizedChatsContext-Deg39peL.js +1 -0
- package/client/dist/assets/PluginsPage-C1xtARIx.js +2 -0
- package/client/dist/assets/ProjectSettingsDialog-JZzrXFBN.js +1 -0
- package/client/dist/assets/RepositoryDeliveries-CSDsiVUz.js +5 -0
- package/client/dist/assets/RepositoryScopeSelector-D-RCaknl.js +1 -0
- package/client/dist/assets/ReviewPacketPage-x5EfGTiL.js +1 -0
- package/client/dist/assets/TemplatePreviewModal-BSyuZxGq.js +1 -0
- package/client/dist/assets/TicketDetailModalContext-DqyF0so-.js +14 -0
- package/client/dist/assets/Trans-SnMX4MhW.js +1 -0
- package/client/dist/assets/agent-BdT0SB1D.js +1 -0
- package/client/dist/assets/agent-Bh9K7iEt.js +1 -0
- package/client/dist/assets/agent-C4ibdFk9.js +1 -0
- package/client/dist/assets/agent-CSFY22Zo.js +1 -0
- package/client/dist/assets/agent-DAnqxUn8.js +1 -0
- package/client/dist/assets/agent-DTQiu0Mi.js +1 -0
- package/client/dist/assets/agent-T54WuR_Y.js +1 -0
- package/client/dist/assets/agent-i75WDZOA.js +1 -0
- package/client/dist/assets/browser-05vRDg_y.js +1 -0
- package/client/dist/assets/browser-Bulb-cB1.js +1 -0
- package/client/dist/assets/browser-C7f-Jsg1.js +1 -0
- package/client/dist/assets/browser-CG0PE1j_.js +1 -0
- package/client/dist/assets/browser-CMzaqAjo.js +1 -0
- package/client/dist/assets/browser-DMajYdNX.js +1 -0
- package/client/dist/assets/browser-DxcOHrdP.js +1 -0
- package/client/dist/assets/browser-ObE7xVo3.js +1 -0
- package/client/dist/assets/builder-765NeYTp.js +1 -0
- package/client/dist/assets/builder-8MG3V6ea.js +1 -0
- package/client/dist/assets/builder-B-1UBs5K.js +1 -0
- package/client/dist/assets/builder-BTiGnPT0.js +1 -0
- package/client/dist/assets/builder-Cx9Rz-7u.js +1 -0
- package/client/dist/assets/builder-DKFMELBl.js +1 -0
- package/client/dist/assets/builder-OcmKrC0h.js +1 -0
- package/client/dist/assets/builder-P9qVBXFZ.js +1 -0
- package/client/dist/assets/{button-CJqFnUOL.js → button-DCBqEaZl.js} +1 -1
- package/client/dist/assets/{code-CkUuW4m9.js → code-B37GRg9C.js} +1 -1
- package/client/dist/assets/{code-B0O8-p8k.js → code-BBOEZbf9.js} +1 -1
- package/client/dist/assets/{code-B1VLZDhS.js → code-BRm-jcyx.js} +1 -1
- package/client/dist/assets/{code-Bpj4Ddml.js → code-CF7w62CR.js} +1 -1
- package/client/dist/assets/{code-BykBZ5-e.js → code-CLuvJt2r.js} +1 -1
- package/client/dist/assets/{code-B86IMAfz.js → code-D0RCm59f.js} +1 -1
- package/client/dist/assets/code-DaZ-ZwCT.js +1 -0
- package/client/dist/assets/{code-cAqaqMTx.js → code-iIHkGaCL.js} +1 -1
- package/client/dist/assets/commands-0XjAftla.js +1 -0
- package/client/dist/assets/commands-BAWSYHjQ.js +1 -0
- package/client/dist/assets/commands-BBwowgiE.js +1 -0
- package/client/dist/assets/commands-BacjIZLN.js +1 -0
- package/client/dist/assets/commands-Bs62IAZ3.js +1 -0
- package/client/dist/assets/commands-CLPdh-Hh.js +1 -0
- package/client/dist/assets/commands-DlbFzgrp.js +1 -0
- package/client/dist/assets/commands-LjPSsi5F.js +1 -0
- package/client/dist/assets/common-B5AZNYMH.js +1 -0
- package/client/dist/assets/common-BFZ0c_vN.js +1 -0
- package/client/dist/assets/common-BrlwEnL7.js +1 -0
- package/client/dist/assets/common-BttQx3z4.js +1 -0
- package/client/dist/assets/common-CM65k_-e.js +1 -0
- package/client/dist/assets/common-D4mvFFlu.js +1 -0
- package/client/dist/assets/common-TZ9Ny96S.js +1 -0
- package/client/dist/assets/common-nFpSF4GC.js +1 -0
- package/client/dist/assets/dashboard-B14uYXkG.js +1 -0
- package/client/dist/assets/dashboard-BK_mez-z.js +1 -0
- package/client/dist/assets/dashboard-BfBir_6o.js +1 -0
- package/client/dist/assets/dashboard-Bt0cCzeG.js +1 -0
- package/client/dist/assets/dashboard-BwkjxI6H.js +1 -0
- package/client/dist/assets/{dashboard-C8WOEiPu.js → dashboard-C3bDKf7s.js} +1 -1
- package/client/dist/assets/dashboard-CdvjGfog.js +1 -0
- package/client/dist/assets/dashboard-fRrP0Kv0.js +1 -0
- package/client/dist/assets/dialog-SRw01_QU.js +45 -0
- package/client/dist/assets/dist-js-CJ_2XX1Y.js +1 -0
- package/client/dist/assets/formatDistanceToNow-DSj5DprF.js +1 -0
- package/client/dist/assets/getTimezoneOffsetInMilliseconds-YhD8rIEs.js +1 -0
- package/client/dist/assets/index-DwAmL7m5.css +2 -0
- package/client/dist/assets/index-EzrkUb8B.js +76 -0
- package/client/dist/assets/{jira-api-B1-MUehg.js → jira-api-CSCqGr-Q.js} +1 -1
- package/client/dist/assets/{jobs-CN_zv4Gr.js → jobs-B8rrzfyZ.js} +1 -1
- package/client/dist/assets/{jobs-DUlWSYq2.js → jobs-BS6RTurf.js} +1 -1
- package/client/dist/assets/{jobs-Bpks6doU.js → jobs-BTT0Bsks.js} +1 -1
- package/client/dist/assets/{jobs-Bgq-PZkC.js → jobs-CezU69AE.js} +1 -1
- package/client/dist/assets/{jobs-SwYS2M-B.js → jobs-ClFJae0s.js} +1 -1
- package/client/dist/assets/{jobs-BAls3bWq.js → jobs-DJSFIFVy.js} +1 -1
- package/client/dist/assets/{jobs-DhxKgWFq.js → jobs-DhgGr8vm.js} +1 -1
- package/client/dist/assets/{jobs-B_TeSQxb.js → jobs-DzMjUcaN.js} +1 -1
- package/client/dist/assets/mcp-6rMoZfEO.js +1 -0
- package/client/dist/assets/mcp-BD8sL5mP.js +1 -0
- package/client/dist/assets/mcp-BkcA3I5s.js +1 -0
- package/client/dist/assets/mcp-CCpSelOh.js +1 -0
- package/client/dist/assets/mcp-CUAN6ORK.js +1 -0
- package/client/dist/assets/mcp-CqbRxRTE.js +1 -0
- package/client/dist/assets/mcp-DP2YfVhO.js +1 -0
- package/client/dist/assets/mcp-DUVQamDz.js +1 -0
- package/client/dist/assets/narration-B-ynWTpn.js +1 -0
- package/client/dist/assets/narration-Bj_laZwg.js +1 -0
- package/client/dist/assets/narration-BxHpmMv_.js +1 -0
- package/client/dist/assets/narration-C1Px0-0j.js +1 -0
- package/client/dist/assets/narration-CAXhGbzM.js +1 -0
- package/client/dist/assets/narration-DQ1l_Kq6.js +1 -0
- package/client/dist/assets/narration-XISXwqZd.js +1 -0
- package/client/dist/assets/narration-kwzfglQo.js +1 -0
- package/client/dist/assets/nav-1-Hh2kOz.js +1 -0
- package/client/dist/assets/nav-B34QkESm.js +1 -0
- package/client/dist/assets/nav-Bap_UXAq.js +1 -0
- package/client/dist/assets/{nav-pYuXq7sf.js → nav-BwxXIB24.js} +1 -1
- package/client/dist/assets/nav-Ch-zHBG5.js +1 -0
- package/client/dist/assets/nav-CygC_WN-.js +1 -0
- package/client/dist/assets/{nav-iwjCg5FR.js → nav-KnnLQtOQ.js} +1 -1
- package/client/dist/assets/nav-m00uxYUG.js +1 -0
- package/client/dist/assets/packet-BQ2tXfJI.js +1 -0
- package/client/dist/assets/packet-BdpOJ1Cy.js +1 -0
- package/client/dist/assets/packet-C3Ievb9R.js +1 -0
- package/client/dist/assets/packet-C4zJIG0Y.js +1 -0
- package/client/dist/assets/packet-Cx-zRuWn.js +1 -0
- package/client/dist/assets/packet-DUTGX52M.js +1 -0
- package/client/dist/assets/packet-DhsKtUPB.js +1 -0
- package/client/dist/assets/packet-z3LJ8Zyy.js +1 -0
- package/client/dist/assets/project-repositories-DYhTvwQ1.js +1 -0
- package/client/dist/assets/provider-capabilities-B-wOHfLP.js +1 -0
- package/client/dist/assets/settings-BBt2xtDQ.js +1 -0
- package/client/dist/assets/settings-BJB9RKJj.js +1 -0
- package/client/dist/assets/settings-CHwQR2rB.js +1 -0
- package/client/dist/assets/settings-CrMi3kSi.js +1 -0
- package/client/dist/assets/settings-DKyhDGD1.js +1 -0
- package/client/dist/assets/settings-Deupji9c.js +1 -0
- package/client/dist/assets/settings-DqRMmwAM.js +1 -0
- package/client/dist/assets/settings-J4rj6vo-.js +1 -0
- package/client/dist/assets/setup-2xGgu4Sk.js +1 -0
- package/client/dist/assets/setup-Ba11l2JA.js +1 -0
- package/client/dist/assets/setup-BzW4kMok.js +1 -0
- package/client/dist/assets/setup-COzwYhkJ.js +1 -0
- package/client/dist/assets/setup-CRVULhtF.js +1 -0
- package/client/dist/assets/setup-DgvlxwpE.js +1 -0
- package/client/dist/assets/setup-Dw_wYeEY.js +1 -0
- package/client/dist/assets/setup-ZPtEeJPW.js +1 -0
- package/client/dist/assets/spending-BqbdPm_4.js +1 -0
- package/client/dist/assets/square-Ci-PFcFe.js +1 -0
- package/client/dist/assets/{terminal-BFRZnMPP.js → terminal-BAzpHtpY.js} +1 -1
- package/client/dist/assets/{terminal-IahE4LW9.js → terminal-C7dHeR3x.js} +1 -1
- package/client/dist/assets/{terminal-tITa81iz.js → terminal-CMla5Qsz.js} +1 -1
- package/client/dist/assets/{terminal-BZiIu3rf.js → terminal-CdNXH-n9.js} +1 -1
- package/client/dist/assets/{terminal-ScjyXNxQ.js → terminal-Cw5bZsmV.js} +1 -1
- package/client/dist/assets/{terminal-C2NAd7BW.js → terminal-DFUP4eNv.js} +1 -1
- package/client/dist/assets/{terminal-d7GadXbN.js → terminal-DGqljeK_.js} +1 -1
- package/client/dist/assets/{terminal-QpXZU2Bn.js → terminal-cU70NodO.js} +1 -1
- package/client/dist/assets/useDesktop-RSMTyy7V.js +1 -0
- package/client/dist/assets/useSharedWebSocket-BOdS5_Iz.js +2 -0
- package/client/dist/index.html +34 -35
- package/docs/README.md +3 -0
- package/docs/agent-live-steering.md +57 -0
- package/docs/ci-cd.md +57 -0
- package/docs/code-explorer.md +48 -0
- package/docs/codex.md +12 -1
- package/docs/features/detachable-mission-windows.md +59 -0
- package/docs/guide/de/integrations/5-mcp-server.md +13 -9
- package/docs/guide/de/integrations/6-agent-chat.md +1 -0
- package/docs/guide/en/integrations/5-mcp-server.md +13 -9
- package/docs/guide/en/integrations/6-agent-chat.md +1 -0
- package/docs/guide/es/integrations/5-mcp-server.md +13 -9
- package/docs/guide/es/integrations/6-agent-chat.md +1 -0
- package/docs/guide/fr/integrations/5-mcp-server.md +13 -9
- package/docs/guide/fr/integrations/6-agent-chat.md +1 -0
- package/docs/guide/it/integrations/5-mcp-server.md +13 -9
- package/docs/guide/it/integrations/6-agent-chat.md +1 -0
- package/docs/guide/ja/integrations/5-mcp-server.md +13 -9
- package/docs/guide/ja/integrations/6-agent-chat.md +1 -0
- package/docs/guide/pt/integrations/5-mcp-server.md +13 -9
- package/docs/guide/pt/integrations/6-agent-chat.md +1 -0
- package/docs/guide/zh/integrations/5-mcp-server.md +13 -9
- package/docs/guide/zh/integrations/6-agent-chat.md +1 -0
- package/docs/internals/README.md +1 -0
- package/docs/internals/browser-capture-performance.md +55 -3
- package/docs/internals/browser-login-popups.md +45 -0
- package/docs/internals/browser-native-retina-audit.md +39 -0
- package/docs/internals/ci-cd-audit.md +39 -0
- package/docs/internals/core-runtime-updates.md +68 -0
- package/docs/internals/embedded-browser-native-webview-evaluation.md +2 -0
- package/docs/internals/implementation-reliability-audit.md +93 -0
- package/docs/internals/interactive-jobs.md +110 -6
- package/docs/internals/mcp-mission-audit.md +76 -0
- package/docs/internals/project-builder.md +404 -42
- package/docs/internals/safe-pr-review-flow.md +52 -10
- package/docs/internals/startup-recovery-audit.md +58 -0
- package/docs/mcp.md +74 -41
- package/docs/mission-processes.md +59 -0
- package/docs/multi-repo-projects.md +51 -0
- package/docs/platforms/windows-parity.md +70 -0
- package/docs/platforms/windows.md +13 -11
- package/docs/running-pipelines.md +14 -0
- package/mcp-bridge/dist/specrails-mcp.js +7186 -0
- package/package.json +9 -4
- package/server/dist/agent-chat-manager.js +537 -68
- package/server/dist/agent-chat-router.js +87 -6
- package/server/dist/agent-context-resolver.js +129 -25
- package/server/dist/agent-defaults.js +19 -11
- package/server/dist/agent-input-store.js +206 -0
- package/server/dist/agent-mcp-config.js +54 -15
- package/server/dist/agent-operator-prompt.js +255 -65
- package/server/dist/agent-spec-framing.js +202 -0
- package/server/dist/agent-steering.js +218 -0
- package/server/dist/agent-store.js +153 -0
- package/server/dist/api-not-found.js +8 -0
- package/server/dist/background-process-control.js +164 -0
- package/server/dist/background-process-service.js +61 -0
- package/server/dist/background-process-store.js +242 -0
- package/server/dist/background-windows-bootstrap.js +238 -0
- package/server/dist/blueprint-chat-manager.js +476 -62
- package/server/dist/blueprint-commit.js +21 -1
- package/server/dist/blueprint-draft-parser.js +122 -17
- package/server/dist/blueprint-generation.js +238 -0
- package/server/dist/blueprint-operator-prompt.js +91 -63
- package/server/dist/blueprint-router.js +55 -3
- package/server/dist/blueprint-spec-fixtures.js +85 -0
- package/server/dist/blueprint-spec-quality.js +57 -16
- package/server/dist/blueprint-store.js +92 -1
- package/server/dist/browser-capture-manager.js +86 -30
- package/server/dist/browser-playwright.js +168 -45
- package/server/dist/browser-viewport.js +26 -0
- package/server/dist/chat-manager.js +23 -15
- package/server/dist/chromium-archive.cjs +83 -0
- package/server/dist/chromium-resolver.js +72 -64
- package/server/dist/code-activity.js +145 -0
- package/server/dist/code-explorer-router.js +714 -114
- package/server/dist/core-compat.js +28 -1
- package/server/dist/core-execution.js +111 -0
- package/server/dist/core-package.js +4 -16
- package/server/dist/core-runtime.js +202 -0
- package/server/dist/core-update-manager.js +161 -60
- package/server/dist/core-update-state.js +29 -0
- package/server/dist/db.js +66 -35
- package/server/dist/delivery-evidence.js +142 -39
- package/server/dist/desktop-db.js +239 -43
- package/server/dist/desktop-router.js +109 -9
- package/server/dist/dev-ports.js +8 -3
- package/server/dist/file-provenance.js +34 -22
- package/server/dist/file-story-manager.js +62 -64
- package/server/dist/file-story.js +118 -35
- package/server/dist/file-summary-generator.js +46 -5
- package/server/dist/file-summary-manager.js +355 -106
- package/server/dist/framework-manager.js +98 -110
- package/server/dist/framework-reseed.js +76 -10
- package/server/dist/git-diagnostics.js +2 -2
- package/server/dist/headroom-manager.js +38 -3
- package/server/dist/host-control.js +52 -0
- package/server/dist/index.js +43 -2
- package/server/dist/interactive-job-session.js +149 -16
- package/server/dist/internal-api.js +48 -0
- package/server/dist/jira/jira-materializer.js +1 -0
- package/server/dist/json-tolerant.js +174 -0
- package/server/dist/legacy-migration.js +4 -2
- package/server/dist/loop-command-catalog.js +83 -21
- package/server/dist/loop-constants.js +6 -1
- package/server/dist/loop-decider.js +11 -1
- package/server/dist/loop-executors.js +194 -45
- package/server/dist/loop-factory.js +11 -4
- package/server/dist/loop-graph.js +90 -4
- package/server/dist/loop-run-manager.js +301 -69
- package/server/dist/loop-shell-invocation.js +21 -0
- package/server/dist/loop-step-idle.js +55 -0
- package/server/dist/loop-templates.js +31 -7
- package/server/dist/mcp/agent-capability.js +37 -4
- package/server/dist/mcp/guide.js +149 -36
- package/server/dist/mcp/mcp-admin-router.js +20 -4
- package/server/dist/mcp/mcp-server.js +89 -43
- package/server/dist/mcp/mcp-tiers.js +6 -5
- package/server/dist/mcp/mcp-token.js +3 -1
- package/server/dist/mcp/resources.js +5 -4
- package/server/dist/mcp/tools/catalog.js +4 -0
- package/server/dist/mcp/tools/code.js +125 -14
- package/server/dist/mcp/tools/context.js +153 -0
- package/server/dist/mcp/tools/git.js +15 -5
- package/server/dist/mcp/tools/jobs.js +84 -71
- package/server/dist/mcp/tools/loops.js +17 -6
- package/server/dist/mcp/tools/meta.js +74 -27
- package/server/dist/mcp/tools/mission.js +29 -0
- package/server/dist/mcp/tools/projects.js +22 -6
- package/server/dist/mcp/tools/rails.js +48 -11
- package/server/dist/mcp/tools/specs.js +86 -14
- package/server/dist/mcp/tools/support.js +1 -1
- package/server/dist/mcp/tools/types.js +117 -43
- package/server/dist/mcp/tools/watch.js +144 -51
- package/server/dist/milestone-chain-store.js +164 -0
- package/server/dist/milestone-chain.js +487 -0
- package/server/dist/milestone-progress.js +348 -0
- package/server/dist/mobile/mobile-devices.js +10 -7
- package/server/dist/mobile/mobile-gateway.js +2 -0
- package/server/dist/mobile/mobile-missions.js +214 -0
- package/server/dist/mobile/mobile-redact.js +17 -3
- package/server/dist/mobile/mobile-router.js +46 -4
- package/server/dist/mobile/mobile-ws.js +49 -4
- package/server/dist/multi-repo-bases.js +56 -0
- package/server/dist/multi-repo-checkout.js +101 -0
- package/server/dist/multi-repo-delivery.js +100 -0
- package/server/dist/multi-repo-execution-store.js +65 -0
- package/server/dist/multi-repo-execution.js +453 -0
- package/server/dist/offline-assemble.js +10 -8
- package/server/dist/openspec-runtime-plugin-commands.json +18 -0
- package/server/dist/openspec-runtime-plugin.js +120 -0
- package/server/dist/plugins/codex-spawn.js +49 -0
- package/server/dist/plugins/serena/manifest.js +2 -2
- package/server/dist/plugins/serena/templates/instructions.md +16 -0
- package/server/dist/pr-publisher.js +1 -1
- package/server/dist/profiles-router.js +3 -18
- package/server/dist/project-code-discovery.js +142 -0
- package/server/dist/project-git.js +19 -21
- package/server/dist/project-registry.js +272 -20
- package/server/dist/project-repositories.js +157 -0
- package/server/dist/project-repository-provenance.js +31 -0
- package/server/dist/project-router-background-processes.js +105 -0
- package/server/dist/project-router-git.js +75 -16
- package/server/dist/project-router-jobs.js +2 -126
- package/server/dist/project-router-loop-runs.js +72 -2
- package/server/dist/project-router-tickets.js +53 -8
- package/server/dist/project-router.js +239 -38
- package/server/dist/provider-detection.js +18 -6
- package/server/dist/provider-limit.js +64 -0
- package/server/dist/providers/claude-adapter.js +26 -1
- package/server/dist/providers/claude-background-tasks.js +18 -0
- package/server/dist/providers/claude-live-session.js +383 -0
- package/server/dist/providers/codex-adapter.js +19 -0
- package/server/dist/providers/codex-live-session.js +545 -0
- package/server/dist/providers/gemini-adapter.js +1 -0
- package/server/dist/providers/live-session-types.js +12 -0
- package/server/dist/providers/live-session.js +13 -0
- package/server/dist/providers/terminal-result.js +24 -0
- package/server/dist/queue-manager.js +2 -0
- package/server/dist/rail-isolated-launch.js +141 -16
- package/server/dist/rail-pr-decision.js +364 -99
- package/server/dist/rail-pr-store.js +24 -10
- package/server/dist/rail-worktree-release.js +34 -2
- package/server/dist/rail-worktrees-store.js +4 -4
- package/server/dist/rails-router.js +249 -55
- package/server/dist/repo-lock.js +92 -17
- package/server/dist/review-packet.js +23 -13
- package/server/dist/schemas/file-summary.v1.json +59 -59
- package/server/dist/schemas/profile.v1.json +137 -137
- package/server/dist/setup-manager.js +52 -8
- package/server/dist/shell-integration/bash-shim.bash +45 -0
- package/server/dist/shell-integration/fish-shim.fish +36 -0
- package/server/dist/shell-integration/powershell-shim.ps1 +48 -0
- package/server/dist/shell-integration/zsh-shim.zsh +47 -0
- package/server/dist/smash-runner.js +1 -0
- package/server/dist/spawn-lifecycle.js +44 -27
- package/server/dist/spec-contract-prompt.js +143 -0
- package/server/dist/spec-draft-parser.js +6 -1
- package/server/dist/spec-models.js +1 -0
- package/server/dist/stuck-run-detector.js +1 -0
- package/server/dist/terminal-manager.js +21 -1
- package/server/dist/terminal-shell-integration.js +4 -1
- package/server/dist/transient-children.js +619 -230
- package/server/dist/util/cli-prompt.js +78 -5
- package/server/dist/util/sqlite-migrations.js +20 -0
- package/server/dist/util/win-spawn.js +18 -3
- package/server/dist/util/windows-provider-shell.js +29 -0
- package/server/dist/verification-sentinel.js +14 -0
- package/server/dist/vitest-setup.js +2 -0
- package/server/dist/windows-job-supervisor.js +133 -0
- package/server/dist/workspace-manager.js +9 -30
- package/server/dist/worktree-manager.js +17 -2
- package/server/dist/worktree-overlay.js +3 -1
- package/client/dist/assets/ActivityFeedPage-tAQcWs1R.js +0 -1
- package/client/dist/assets/AgentBrowserCapture-BX8BNae5.js +0 -1
- package/client/dist/assets/AgentModeAnalyticsPane-BVAqCL0K.js +0 -2
- package/client/dist/assets/AgentModeCodePane-9XfqQc9c.js +0 -2
- package/client/dist/assets/AgentModeJobsPane-BCjLsPhc.js +0 -1
- package/client/dist/assets/AgentsPage-C8J_42sm.js +0 -87
- package/client/dist/assets/AnalyticsPage-BtQuyfJm.js +0 -1
- package/client/dist/assets/CodePage-BZ2MwdCu.js +0 -2
- package/client/dist/assets/DesktopAnalyticsPage-Bh_29V4g.js +0 -1
- package/client/dist/assets/ExportDropdown-BrtfWzEG.js +0 -1
- package/client/dist/assets/InteractiveJobComposer-BCZiSfzc.js +0 -19
- package/client/dist/assets/JobDetailModal-NAJmuYIT.js +0 -1
- package/client/dist/assets/JobDetailPage-fE0ZycUX.js +0 -1
- package/client/dist/assets/JobsPage-z5M_HVJG.js +0 -1
- package/client/dist/assets/LoopBuilderPage-j1FQS47c.js +0 -7
- package/client/dist/assets/LoopPreviewModal-DhDJjdCe.js +0 -1
- package/client/dist/assets/LoopsPage-Ll7zORZb.js +0 -1
- package/client/dist/assets/MinimizedChatsContext-Bd3OqR_S.js +0 -1
- package/client/dist/assets/PluginsPage-DN4kGvJt.js +0 -2
- package/client/dist/assets/ProjectSettingsDialog-OgsgxjzF.js +0 -1
- package/client/dist/assets/ReviewPacketPage-DFog4sXn.js +0 -1
- package/client/dist/assets/TemplatePreviewModal-L2XxqiOD.js +0 -1
- package/client/dist/assets/TicketDetailModal-CsF-AWZX.js +0 -14
- package/client/dist/assets/Trans-Bsz9_gyq.js +0 -1
- package/client/dist/assets/agent-BQgKv_2F.js +0 -1
- package/client/dist/assets/agent-C1NRDJqL.js +0 -1
- package/client/dist/assets/agent-CLNleiy6.js +0 -1
- package/client/dist/assets/agent-CmceArkQ.js +0 -1
- package/client/dist/assets/agent-D3UxQ3SR.js +0 -1
- package/client/dist/assets/agent-DB1JeE64.js +0 -1
- package/client/dist/assets/agent-DXkHcQ-D.js +0 -1
- package/client/dist/assets/agent-DjJJJ2M8.js +0 -1
- package/client/dist/assets/auth-D_5bQv5W.js +0 -1
- package/client/dist/assets/ban-E4EaZe3a.js +0 -1
- package/client/dist/assets/bot-DzuuuC5R.js +0 -1
- package/client/dist/assets/browser-BgqHDMXP.js +0 -1
- package/client/dist/assets/browser-CsKJtrpv.js +0 -1
- package/client/dist/assets/browser-Cu58EpZU.js +0 -1
- package/client/dist/assets/browser-CvXOJm-j.js +0 -1
- package/client/dist/assets/browser-DOrFh1c7.js +0 -1
- package/client/dist/assets/browser-DQv_Jo7x.js +0 -1
- package/client/dist/assets/browser-LPgxvJu2.js +0 -1
- package/client/dist/assets/browser-eL-3MIEI.js +0 -1
- package/client/dist/assets/builder-0IWtosUm.js +0 -1
- package/client/dist/assets/builder-Bf2N6XWn.js +0 -1
- package/client/dist/assets/builder-BnqaaBkT.js +0 -1
- package/client/dist/assets/builder-BxxfGgAO.js +0 -1
- package/client/dist/assets/builder-C5IIgWsq.js +0 -1
- package/client/dist/assets/builder-CHuahItu.js +0 -1
- package/client/dist/assets/builder-CjWosXL_.js +0 -1
- package/client/dist/assets/builder-CpCIOoKj.js +0 -1
- package/client/dist/assets/code-CHPkOkDS.js +0 -1
- package/client/dist/assets/commands-6tYQih5m.js +0 -1
- package/client/dist/assets/commands-BK2QinXN.js +0 -1
- package/client/dist/assets/commands-C2Nca76h.js +0 -1
- package/client/dist/assets/commands-CKdLihNX.js +0 -1
- package/client/dist/assets/commands-CYIBTAlc.js +0 -1
- package/client/dist/assets/commands-CjUtYJIM.js +0 -1
- package/client/dist/assets/commands-Cq_u_8y9.js +0 -1
- package/client/dist/assets/commands-D_ZHYQug.js +0 -1
- package/client/dist/assets/common-6MLbD-jM.js +0 -1
- package/client/dist/assets/common-BKGEu4rm.js +0 -1
- package/client/dist/assets/common-BNbnv8cE.js +0 -1
- package/client/dist/assets/common-BqGWtDbt.js +0 -1
- package/client/dist/assets/common-DBtTzeYm.js +0 -1
- package/client/dist/assets/common-DEW3Nr8n.js +0 -1
- package/client/dist/assets/common-DHsv9N5d.js +0 -1
- package/client/dist/assets/common-mkrEcW-Y.js +0 -1
- package/client/dist/assets/dashboard-B9GhC5ku.js +0 -1
- package/client/dist/assets/dashboard-CBnv6zOI.js +0 -1
- package/client/dist/assets/dashboard-CaP0fU87.js +0 -1
- package/client/dist/assets/dashboard-D4ZZ4x84.js +0 -1
- package/client/dist/assets/dashboard-DmuTQBX8.js +0 -1
- package/client/dist/assets/dashboard-DynLYj3d.js +0 -1
- package/client/dist/assets/dashboard-zj4gGFJ1.js +0 -1
- package/client/dist/assets/dialog-CdWCb02j.js +0 -45
- package/client/dist/assets/dist-bVqfYmby.js +0 -1
- package/client/dist/assets/dist-js-CWeUdf5Z.js +0 -1
- package/client/dist/assets/formatDistanceToNow-DQCvMgUc.js +0 -1
- package/client/dist/assets/getTimezoneOffsetInMilliseconds-C16cxSe1.js +0 -1
- package/client/dist/assets/git-refresh-wTW0rO0Z.js +0 -1
- package/client/dist/assets/i18n-hnX2DPmo.js +0 -2
- package/client/dist/assets/index-DIhMEAVw.js +0 -66
- package/client/dist/assets/index-DwygcU7s.css +0 -2
- package/client/dist/assets/mcp-B8X8wBLu.js +0 -1
- package/client/dist/assets/mcp-C2AojZZN.js +0 -1
- package/client/dist/assets/mcp-D8BT78_L.js +0 -1
- package/client/dist/assets/mcp-Df5RWBNk.js +0 -1
- package/client/dist/assets/mcp-Dj7BgMQW.js +0 -1
- package/client/dist/assets/mcp-Q7iT7rcz.js +0 -1
- package/client/dist/assets/mcp-YlvNvJbW.js +0 -1
- package/client/dist/assets/mcp-mKFpTSRb.js +0 -1
- package/client/dist/assets/narration-4Z2VUhZw.js +0 -1
- package/client/dist/assets/narration-BGuiEDj3.js +0 -1
- package/client/dist/assets/narration-BuSoqRmv.js +0 -1
- package/client/dist/assets/narration-CB9t29fy.js +0 -1
- package/client/dist/assets/narration-CU3x8FHD.js +0 -1
- package/client/dist/assets/narration-CWeXhfP5.js +0 -1
- package/client/dist/assets/narration-DRaDnhT5.js +0 -1
- package/client/dist/assets/narration-DtEbQgCw.js +0 -1
- package/client/dist/assets/nav-ApJVg3xu.js +0 -1
- package/client/dist/assets/nav-BKNky1Bg.js +0 -1
- package/client/dist/assets/nav-C6vWWKYx.js +0 -1
- package/client/dist/assets/nav-CXJ6Aw89.js +0 -1
- package/client/dist/assets/nav-CsmFBIDf.js +0 -1
- package/client/dist/assets/nav-DjkmQJjd.js +0 -1
- package/client/dist/assets/packet-B1IxaL5f.js +0 -1
- package/client/dist/assets/packet-Bh5kkbiB.js +0 -1
- package/client/dist/assets/packet-By8fqYxW.js +0 -1
- package/client/dist/assets/packet-CZdvA44E.js +0 -1
- package/client/dist/assets/packet-CrjHRQCP.js +0 -1
- package/client/dist/assets/packet-Dwi2pTtx.js +0 -1
- package/client/dist/assets/packet-_-ZIa0IR.js +0 -1
- package/client/dist/assets/packet-n0W6E1Hn.js +0 -1
- package/client/dist/assets/play-DNlrawbS.js +0 -1
- package/client/dist/assets/provider-capabilities-Doej9lfa.js +0 -1
- package/client/dist/assets/settings-Bd0x4TBa.js +0 -1
- package/client/dist/assets/settings-C1-7cXzC.js +0 -1
- package/client/dist/assets/settings-CAFaT38b.js +0 -1
- package/client/dist/assets/settings-Ct3v1nW2.js +0 -1
- package/client/dist/assets/settings-DHh7_IF5.js +0 -1
- package/client/dist/assets/settings-DQXAmdcv.js +0 -1
- package/client/dist/assets/settings-guzlhpup.js +0 -1
- package/client/dist/assets/settings-sZfTPMEH.js +0 -1
- package/client/dist/assets/setup-3jWaoVUO.js +0 -1
- package/client/dist/assets/setup-BjgRneb2.js +0 -1
- package/client/dist/assets/setup-BzFIjv-f.js +0 -1
- package/client/dist/assets/setup-C4VfQsxE.js +0 -1
- package/client/dist/assets/setup-DfUkpDbN.js +0 -1
- package/client/dist/assets/setup-ECe90Pmu.js +0 -1
- package/client/dist/assets/setup-dlqC4Jmm.js +0 -1
- package/client/dist/assets/setup-jwfLMiM2.js +0 -1
- package/client/dist/assets/spending-EC9xqio-.js +0 -1
- package/client/dist/assets/useDesktop-BQVt8lFd.js +0 -1
|
@@ -74,6 +74,8 @@ const db_1 = require("./db");
|
|
|
74
74
|
const delivery_evidence_1 = require("./delivery-evidence");
|
|
75
75
|
const integration_branch_1 = require("./integration-branch");
|
|
76
76
|
const repo_lock_1 = require("./repo-lock");
|
|
77
|
+
const project_repositories_1 = require("./project-repositories");
|
|
78
|
+
const multi_repo_execution_store_1 = require("./multi-repo-execution-store");
|
|
77
79
|
const rail_isolation_1 = require("./rail-isolation");
|
|
78
80
|
const rail_pr_store_1 = require("./rail-pr-store");
|
|
79
81
|
const agent_chat_registry_1 = require("./agent-chat-registry");
|
|
@@ -92,6 +94,7 @@ const active_pr_continuation_1 = require("./active-pr-continuation");
|
|
|
92
94
|
const pr_lifecycle_1 = require("./pr-lifecycle");
|
|
93
95
|
const rail_worktree_release_1 = require("./rail-worktree-release");
|
|
94
96
|
const rail_pr_recovery_git_1 = require("./rail-pr-recovery-git");
|
|
97
|
+
const loop_graph_1 = require("./loop-graph");
|
|
95
98
|
/** A PR follow-up may only run on the verified PR branch in a dedicated
|
|
96
99
|
* worktree. Routers must surface this error instead of degrading to shared cwd. */
|
|
97
100
|
class PrContinuationIsolationError extends Error {
|
|
@@ -371,12 +374,31 @@ function branchRecords(results) {
|
|
|
371
374
|
/**
|
|
372
375
|
* Launch the rail's tickets in isolated worktrees + schedule the merge-back.
|
|
373
376
|
* Returns the loop run ids. Throws if worktree allocation fails, but only after
|
|
374
|
-
* tearing down owned partial allocation.
|
|
375
|
-
*
|
|
376
|
-
* must fail closed because shared cwd cannot prove which branch receives work.
|
|
377
|
+
* tearing down owned partial allocation. The router refuses shared-cwd
|
|
378
|
+
* fallback for these errors; execution stays bound to a verified worktree.
|
|
377
379
|
*/
|
|
378
380
|
async function launchIsolatedRail(input, io = {}) {
|
|
379
381
|
const { ctx, railIndex, ticketIds, loopId, loopName, loopGraph, provider, model, effort } = input;
|
|
382
|
+
let expectedRepositoryBaseSha = input.repositoryExecution?.expectedBaseSha;
|
|
383
|
+
let singleRepositoryId = input.repositoryExecution?.repositoryId;
|
|
384
|
+
if (!input.repositoryExecution) {
|
|
385
|
+
const members = (0, project_repositories_1.getProjectRepositories)(ctx.project);
|
|
386
|
+
const primary = members.find((repo) => repo.isPrimary) ?? members[0];
|
|
387
|
+
const selected = input.repositoryIds ?? (ticketIds.length === 0 && primary ? [primary.id] : [...new Set(ticketIds.flatMap((id) => {
|
|
388
|
+
const ids = ctx.getTicketSpec(id)?.repositoryIds;
|
|
389
|
+
return ids?.length ? ids : primary ? [primary.id] : [];
|
|
390
|
+
}))]);
|
|
391
|
+
(0, loop_graph_1.assertLoopShellRepositoryScope)(loopGraph, selected);
|
|
392
|
+
if (primary && selected.length === 1 && selected[0] === primary.id) {
|
|
393
|
+
input = { ...input, baseBranch: input.repositoryBaseBranches?.[primary.id] ?? input.baseBranch };
|
|
394
|
+
singleRepositoryId = primary.id;
|
|
395
|
+
expectedRepositoryBaseSha = input.repositoryBaseShas?.[primary.id];
|
|
396
|
+
}
|
|
397
|
+
if (selected.length !== 1 || selected[0] !== primary?.id) {
|
|
398
|
+
const { launchMultiRepositoryRail } = await Promise.resolve().then(() => __importStar(require('./multi-repo-execution')));
|
|
399
|
+
return launchMultiRepositoryRail({ ...input, repositoryIds: selected }, io);
|
|
400
|
+
}
|
|
401
|
+
}
|
|
380
402
|
const git = io.git ?? worktree_manager_1.defaultGitRunner;
|
|
381
403
|
const exec = io.exec ?? pr_publisher_1.defaultExec;
|
|
382
404
|
const create = io.create ?? worktree_manager_1.createWorktree;
|
|
@@ -385,7 +407,7 @@ async function launchIsolatedRail(input, io = {}) {
|
|
|
385
407
|
const resolveExecution = io.resolveExecution ?? workspace_resolution_1.resolveProjectExecution;
|
|
386
408
|
const baseRepo = ctx.project.path;
|
|
387
409
|
const slug = ctx.project.slug;
|
|
388
|
-
const worktreesRoot = path.join((0, artifact_registry_1.resolveHome)(), '.specrails', 'projects', slug, 'worktrees');
|
|
410
|
+
const worktreesRoot = path.join((0, artifact_registry_1.resolveHome)(), '.specrails', 'projects', slug, 'worktrees', ...(input.repositoryExecution ? [input.repositoryExecution.repositoryId] : []));
|
|
389
411
|
// A revision run is seeded with a full briefing (the instruction PLUS the
|
|
390
412
|
// frozen spec, the branch that carries the work and what the previous run
|
|
391
413
|
// actually reported) rather than the bare sentence — the run starts a FRESH
|
|
@@ -400,7 +422,7 @@ async function launchIsolatedRail(input, io = {}) {
|
|
|
400
422
|
: (0, loop_constants_1.loadConstantMap)(ctx.desktopDb);
|
|
401
423
|
// Capture the PR-delivery mode ONCE at launch entry so a mid-flight env flip
|
|
402
424
|
// can never split one launch across the two delivery paths.
|
|
403
|
-
const prMode = (0, rail_isolation_1.isRailPrDeliveryEnabled)();
|
|
425
|
+
const prMode = Boolean(input.repositoryExecution) || (0, rail_isolation_1.isRailPrDeliveryEnabled)();
|
|
404
426
|
// Ask-first PR delivery (safe-pr-review-flow): persist the authoritative
|
|
405
427
|
// decision row UP FRONT (decision='building') — so the origin link survives
|
|
406
428
|
// every await and late-joining clients hydrate mid-build via GET /rails —
|
|
@@ -472,7 +494,7 @@ async function launchIsolatedRail(input, io = {}) {
|
|
|
472
494
|
// run — the batch pipeline handles the tickets internally); `per-ticket` → one
|
|
473
495
|
// unit per ticket. The branch/ledger key is the unit's primary (first) ticket.
|
|
474
496
|
const scope = input.scope ?? 'per-ticket';
|
|
475
|
-
let units = scope === 'all'
|
|
497
|
+
let units = input.repositoryExecution && ticketIds.length === 0 ? [{ ticketId: 0, ticketIds: [] }] : scope === 'all'
|
|
476
498
|
? [{ ticketId: ticketIds[0], ticketIds: [...ticketIds] }]
|
|
477
499
|
: ticketIds.map((id) => ({ ticketId: id, ticketIds: [id] }));
|
|
478
500
|
// Effective artifact root for the per-worktree overlay: a RELOCATED project's
|
|
@@ -544,9 +566,12 @@ async function launchIsolatedRail(input, io = {}) {
|
|
|
544
566
|
// Resolve the project's designated integration branch ONCE, and branch every
|
|
545
567
|
// ticket's worktree off it (not the ambient HEAD). Empty setting → auto-resolve
|
|
546
568
|
// (repo default → HEAD fallback). See server/integration-branch.ts.
|
|
569
|
+
const executionRepository = (0, project_repositories_1.getProjectRepositories)(ctx.project).find((repo) => input.repositoryExecution
|
|
570
|
+
? repo.id === input.repositoryExecution.repositoryId : repo.isPrimary);
|
|
547
571
|
integration = await (0, integration_branch_1.resolveIntegrationBranch)(git, {
|
|
548
572
|
repoDir: baseRepo,
|
|
549
|
-
|
|
573
|
+
explicit: input.baseBranch ?? undefined,
|
|
574
|
+
projectSetting: executionRepository?.integrationBranch ?? (input.repositoryExecution && !input.repositoryExecution.primary ? undefined : (0, db_1.getProjectSettings)(ctx.db).integrationBranch),
|
|
550
575
|
});
|
|
551
576
|
// Prefer the freshly-fetched remote-tracking ref (origin/<branch>) over the
|
|
552
577
|
// bare local name for repo-default/project-setting sources — see
|
|
@@ -644,6 +669,9 @@ async function launchIsolatedRail(input, io = {}) {
|
|
|
644
669
|
}
|
|
645
670
|
if (prMode) {
|
|
646
671
|
const generation = (0, rail_pr_store_1.createPrDeliveryGeneration)(ctx.db, {
|
|
672
|
+
parentDeliveryId: input.repositoryExecution?.parentDeliveryId,
|
|
673
|
+
repositoryId: input.repositoryExecution?.repositoryId,
|
|
674
|
+
repositoryPath: input.repositoryExecution ? baseRepo : undefined,
|
|
647
675
|
railIndex,
|
|
648
676
|
loopId,
|
|
649
677
|
railKey: `${railIndex}-${loopId}`,
|
|
@@ -709,6 +737,9 @@ async function launchIsolatedRail(input, io = {}) {
|
|
|
709
737
|
const takenBranches = await (0, worktree_manager_1.listLocalBranches)(git, baseRepo);
|
|
710
738
|
const preexistingBranches = new Set(takenBranches);
|
|
711
739
|
const unitBranchName = (ticketId) => {
|
|
740
|
+
const revisionBranch = input.repositoryExecution?.revisionBranches?.get(ticketId);
|
|
741
|
+
if (revisionBranch)
|
|
742
|
+
return { branch: revisionBranch.branch, ownership: 'preexisting' };
|
|
712
743
|
const continuation = launchContinuation && continuationTargets.get(ticketId);
|
|
713
744
|
if (continuation) {
|
|
714
745
|
takenBranches.add(continuation.branch);
|
|
@@ -716,7 +747,10 @@ async function launchIsolatedRail(input, io = {}) {
|
|
|
716
747
|
}
|
|
717
748
|
const preferred = (0, pr_naming_1.ticketBranchName)(unitNamingInput(ctx, ticketId));
|
|
718
749
|
const branch = (0, pr_naming_1.resolveCollisionFreeName)(preferred, {
|
|
719
|
-
|
|
750
|
+
// A grouped run can reuse a branch only through the exact revision/PR
|
|
751
|
+
// evidence above. An accepted predecessor may now lag the integration
|
|
752
|
+
// branch, so ordinary grouped allocations must start a fresh branch.
|
|
753
|
+
taken: (name) => takenBranches.has(name) && (Boolean(input.repositoryExecution) || !(0, rail_worktrees_store_1.railWorktreeBranchExistsForTicket)(ctx.db, ticketId, name)),
|
|
720
754
|
reserved: [integration.branch],
|
|
721
755
|
}) ?? (0, worktree_manager_1.worktreeBranch)(slug, ticketId);
|
|
722
756
|
takenBranches.add(branch);
|
|
@@ -731,12 +765,19 @@ async function launchIsolatedRail(input, io = {}) {
|
|
|
731
765
|
let worktreeOwnership = 'created';
|
|
732
766
|
let initialSha = null;
|
|
733
767
|
try {
|
|
768
|
+
const revisionBranch = input.repositoryExecution?.revisionBranches?.get(unit.ticketId);
|
|
769
|
+
if (revisionBranch) {
|
|
770
|
+
const observed = await git.run(['rev-parse', '--verify', `refs/heads/${revisionBranch.branch}`], baseRepo);
|
|
771
|
+
if (observed.code !== 0 || observed.stdout.trim() !== revisionBranch.sha) {
|
|
772
|
+
throw new Error(`Revision branch ${revisionBranch.branch} no longer matches its recorded delivery commit`);
|
|
773
|
+
}
|
|
774
|
+
}
|
|
734
775
|
handle = await create(git, {
|
|
735
776
|
repoDir: baseRepo,
|
|
736
777
|
worktreesRoot,
|
|
737
778
|
slug,
|
|
738
779
|
ticketId: unit.ticketId,
|
|
739
|
-
baseRef: continuationTarget?.baseRef ?? worktreeBaseRef.baseRef,
|
|
780
|
+
baseRef: revisionBranch?.sha ?? continuationTarget?.baseRef ?? worktreeBaseRef.baseRef,
|
|
740
781
|
branch: branchPlan.branch,
|
|
741
782
|
refreshFromBaseRef: Boolean(continuationTarget?.baseRef),
|
|
742
783
|
});
|
|
@@ -749,6 +790,11 @@ async function launchIsolatedRail(input, io = {}) {
|
|
|
749
790
|
}
|
|
750
791
|
else {
|
|
751
792
|
initialSha = await readHeadSha(git, handle.worktreePath);
|
|
793
|
+
if (expectedRepositoryBaseSha && initialSha !== expectedRepositoryBaseSha)
|
|
794
|
+
throw new Error('The repository base changed before its worktree could be frozen');
|
|
795
|
+
if (revisionBranch && (handle.branch !== revisionBranch.branch || initialSha !== revisionBranch.sha)) {
|
|
796
|
+
throw new Error(`Revision checkout does not expose the exact recorded branch ${revisionBranch.branch}`);
|
|
797
|
+
}
|
|
752
798
|
}
|
|
753
799
|
// Per-run overlay: merge-link the framework surface the checkout didn't
|
|
754
800
|
// bring into the worktree (idempotent; resume-safe via its manifest).
|
|
@@ -806,10 +852,12 @@ async function launchIsolatedRail(input, io = {}) {
|
|
|
806
852
|
console.warn(`[rail-isolated] provenance snapshot failed: ${err.message}`);
|
|
807
853
|
}
|
|
808
854
|
}
|
|
809
|
-
const runId = (0, ids_1.newId)();
|
|
855
|
+
const runId = input.repositoryExecution?.runIds.get(unit.ticketId) ?? (0, ids_1.newId)();
|
|
810
856
|
const ledgerId = (0, ids_1.newId)();
|
|
811
857
|
(0, rail_worktrees_store_1.createRailWorktree)(ctx.db, {
|
|
812
858
|
id: ledgerId, railIndex, ticketId: unit.ticketId, runId,
|
|
859
|
+
repositoryId: input.repositoryExecution?.repositoryId,
|
|
860
|
+
repositoryPath: input.repositoryExecution ? baseRepo : undefined,
|
|
813
861
|
branch: handle.branch, worktreePath: handle.worktreePath,
|
|
814
862
|
});
|
|
815
863
|
allocated.push({
|
|
@@ -910,6 +958,7 @@ async function launchIsolatedRail(input, io = {}) {
|
|
|
910
958
|
runId: a.runId,
|
|
911
959
|
ticketId: a.ticketId,
|
|
912
960
|
repoDir: a.handle.worktreePath,
|
|
961
|
+
repositoryId: input.repositoryExecution?.repositoryId,
|
|
913
962
|
snapshot: a.provenanceSnapshot,
|
|
914
963
|
broadcast: (msg) => ctx.broadcast(msg),
|
|
915
964
|
});
|
|
@@ -934,19 +983,33 @@ async function launchIsolatedRail(input, io = {}) {
|
|
|
934
983
|
const settleAllocatedRun = async (a, enginePromise) => {
|
|
935
984
|
let actualOutcome = 'failed';
|
|
936
985
|
let engineFailure;
|
|
986
|
+
let stallReason;
|
|
937
987
|
try {
|
|
938
988
|
const result = await enginePromise;
|
|
939
989
|
actualOutcome = result.outcome;
|
|
990
|
+
stallReason = result.stallReason;
|
|
940
991
|
}
|
|
941
992
|
catch (err) {
|
|
942
993
|
engineFailure = errorDetail(err);
|
|
943
994
|
console.error(`[rail-isolated] loop run ${a.runId} rejected: ${engineFailure}`);
|
|
944
995
|
}
|
|
996
|
+
if (input.repositoryExecution?.isAborted?.()) {
|
|
997
|
+
// The coordinator never started. Do not commit incidental edits or
|
|
998
|
+
// release a mount borrowed from a previous delivery while rolling back.
|
|
999
|
+
const finalSha = await readHeadSha(git, a.handle.worktreePath);
|
|
1000
|
+
if (a.worktreeOwnership !== 'created')
|
|
1001
|
+
markWorktree(a, 'needs-review');
|
|
1002
|
+
return {
|
|
1003
|
+
run: a, implementationOutcome: 'failed', deliveryOutcome: 'not_started',
|
|
1004
|
+
initialSha: a.initialSha, finalSha, changed: Boolean(finalSha && a.initialSha !== finalSha),
|
|
1005
|
+
safeToRelease: a.worktreeOwnership === 'created' && finalSha !== null && finalSha === a.initialSha,
|
|
1006
|
+
};
|
|
1007
|
+
}
|
|
945
1008
|
const implementationOutcome = actualOutcome === 'success' ? 'succeeded' : 'failed';
|
|
946
1009
|
recordRunProvenance(a);
|
|
947
1010
|
let callbackFailure;
|
|
948
1011
|
try {
|
|
949
|
-
ctx.onLoopRunFinished(a.runId, actualOutcome, runFinishedOpts);
|
|
1012
|
+
ctx.onLoopRunFinished(a.runId, actualOutcome, { ...runFinishedOpts, ...(stallReason ? { stallReason } : {}) });
|
|
950
1013
|
}
|
|
951
1014
|
catch (err) {
|
|
952
1015
|
callbackFailure = errorDetail(err);
|
|
@@ -1112,12 +1175,23 @@ async function launchIsolatedRail(input, io = {}) {
|
|
|
1112
1175
|
const enginePromise = ctx.loopRunManager.run({
|
|
1113
1176
|
runId: a.runId, loopId, loopName, graph: loopGraph, projectId: ctx.project.id,
|
|
1114
1177
|
cwd: a.handle.worktreePath, repoDir: a.handle.worktreePath,
|
|
1178
|
+
repositoryId: singleRepositoryId,
|
|
1115
1179
|
isolation: { branch: a.handle.branch, worktreePath: a.handle.worktreePath },
|
|
1116
|
-
railIndex, ticketId: a.ticketId,
|
|
1117
|
-
spec:
|
|
1180
|
+
railIndex, ticketId: a.ticketIds.length ? a.ticketId : null,
|
|
1181
|
+
spec: {
|
|
1182
|
+
...spec,
|
|
1183
|
+
ticketIds: a.ticketIds,
|
|
1184
|
+
...(a.ticketIds.length > 1 ? {
|
|
1185
|
+
tickets: a.ticketIds.map((id) => {
|
|
1186
|
+
const ticket = ctx.getTicketSpec(id);
|
|
1187
|
+
return { id, title: ticket?.title, description: ticket?.description, repositoryIds: ticket?.repositoryIds };
|
|
1188
|
+
}),
|
|
1189
|
+
} : {}),
|
|
1190
|
+
},
|
|
1118
1191
|
ticketCompletionStatus: runFinishedOpts.ticketCompletionStatus,
|
|
1119
1192
|
deferTerminalOutcome: true,
|
|
1120
1193
|
constants, provider, model, effort,
|
|
1194
|
+
profileName: input.profileName,
|
|
1121
1195
|
});
|
|
1122
1196
|
runPromises.push(settleAllocatedRun(a, enginePromise));
|
|
1123
1197
|
try {
|
|
@@ -1454,6 +1528,7 @@ async function launchIsolatedRail(input, io = {}) {
|
|
|
1454
1528
|
ticketId: result.run.ticketId,
|
|
1455
1529
|
runId: result.run.runId,
|
|
1456
1530
|
worktreePath: result.run.handle.worktreePath,
|
|
1531
|
+
loopId,
|
|
1457
1532
|
})));
|
|
1458
1533
|
}
|
|
1459
1534
|
catch (e) {
|
|
@@ -1592,7 +1667,7 @@ async function launchIsolatedRail(input, io = {}) {
|
|
|
1592
1667
|
broadcastPrState();
|
|
1593
1668
|
syncOriginCard('update');
|
|
1594
1669
|
}
|
|
1595
|
-
});
|
|
1670
|
+
}).finally(() => { input.repositoryExecution?.onSettled(prDeliveryId); });
|
|
1596
1671
|
return allocated.map((a) => a.runId);
|
|
1597
1672
|
}
|
|
1598
1673
|
function recoveryOverlayExcludes(repoDir, worktreePath) {
|
|
@@ -1712,8 +1787,25 @@ async function reconcileRailWorktrees(db, repoDir, io = {}) {
|
|
|
1712
1787
|
const git = io.git ?? worktree_manager_1.defaultGitRunner;
|
|
1713
1788
|
const exec = io.exec ?? pr_publisher_1.defaultExec;
|
|
1714
1789
|
const remove = io.remove ?? worktree_manager_1.removeWorktree;
|
|
1790
|
+
if (!io.repositoryOnly) {
|
|
1791
|
+
const paths = db.prepare('SELECT DISTINCT repository_path FROM rail_worktrees WHERE repository_path IS NOT NULL UNION SELECT DISTINCT repository_path FROM rail_pr_deliveries WHERE repository_path IS NOT NULL').all();
|
|
1792
|
+
if (paths.length) {
|
|
1793
|
+
let count = 0;
|
|
1794
|
+
for (const target of [...new Set([repoDir, ...paths.map((row) => row.repository_path)])]) {
|
|
1795
|
+
count += await reconcileRailWorktrees(db, target, { ...io, repositoryOnly: true, primaryRepoDir: repoDir });
|
|
1796
|
+
}
|
|
1797
|
+
const { refreshRepositoryDeliveryGroup } = await Promise.resolve().then(() => __importStar(require('./multi-repo-execution')));
|
|
1798
|
+
const groups = db.prepare('SELECT id FROM rail_pr_deliveries WHERE parent_delivery_id IS NULL AND execution_manifest IS NOT NULL').all();
|
|
1799
|
+
for (const group of groups) {
|
|
1800
|
+
refreshRepositoryDeliveryGroup(db, group.id, { startup: true });
|
|
1801
|
+
io.onDeliveryRecovered?.(group.id);
|
|
1802
|
+
}
|
|
1803
|
+
return count;
|
|
1804
|
+
}
|
|
1805
|
+
}
|
|
1806
|
+
const belongsHere = (row) => (row.repository_path ?? io.primaryRepoDir ?? repoDir) === repoDir;
|
|
1715
1807
|
return (0, repo_lock_1.withRepoLock)(repoDir, async () => {
|
|
1716
|
-
const stuck = (0, rail_worktrees_store_1.listNonTerminalRailWorktrees)(db);
|
|
1808
|
+
const stuck = (0, rail_worktrees_store_1.listNonTerminalRailWorktrees)(db).filter(belongsHere);
|
|
1717
1809
|
const autoReleaseWorktreeIds = new Set();
|
|
1718
1810
|
const settledDeliveries = db.prepare(`
|
|
1719
1811
|
SELECT decision, delivery_outcome, worktree_ids FROM rail_pr_deliveries
|
|
@@ -1787,7 +1879,38 @@ async function reconcileRailWorktrees(db, repoDir, io = {}) {
|
|
|
1787
1879
|
// mismatch are all recoverable uncertainty. Never force-remove them.
|
|
1788
1880
|
(0, rail_worktrees_store_1.updateRailWorktreeState)(db, row.id, 'needs-review');
|
|
1789
1881
|
}
|
|
1790
|
-
const recovered = (0, rail_pr_store_1.reconcileFailedBuildingPrDeliveries)(db, { startup: true });
|
|
1882
|
+
const recovered = (0, rail_pr_store_1.reconcileFailedBuildingPrDeliveries)(db, { startup: true, repositoryPath: repoDir, legacyRepositoryPath: io.primaryRepoDir ?? repoDir });
|
|
1883
|
+
// Multi-repository recovery must not conflate the same run/branch names
|
|
1884
|
+
// across object stores. Promote only a clean unchanged base or an exact
|
|
1885
|
+
// app-marked settlement commit; retain uncertain work for explicit revision.
|
|
1886
|
+
for (const delivery of recovered) {
|
|
1887
|
+
const manifest = (0, multi_repo_execution_store_1.readExecutionManifest)(delivery.execution_manifest);
|
|
1888
|
+
if (!delivery.parent_delivery_id || !manifest || delivery.pr_url || delivery.implementation_outcome !== 'succeeded')
|
|
1889
|
+
continue;
|
|
1890
|
+
const units = (0, rail_pr_store_1.toPrDeliverySnapshot)(delivery).branches;
|
|
1891
|
+
const recoveredUnits = await Promise.all(units.map(async (unit) => {
|
|
1892
|
+
const ledger = stuck.find((row) => row.run_id === unit.runId && row.branch === unit.branch);
|
|
1893
|
+
const snapshot = manifest.repositories.find((repo) => repo.worktreeId === ledger?.id);
|
|
1894
|
+
const sha = unit.runId ? verifiedShaByRun.get(unit.runId) : undefined;
|
|
1895
|
+
const proven = Boolean(snapshot && sha && (sha === snapshot.baseSha || await (0, rail_pr_recovery_git_1.commitCarriesRunMarker)(git, repoDir, sha, unit.runId)));
|
|
1896
|
+
const noChanges = proven && sha === snapshot.baseSha;
|
|
1897
|
+
return {
|
|
1898
|
+
...unit, repositoryId: delivery.repository_id ?? undefined,
|
|
1899
|
+
succeeded: proven && !noChanges, initialSha: snapshot?.baseSha ?? null, finalSha: proven ? sha : null,
|
|
1900
|
+
changed: proven ? !noChanges : undefined, worktreePath: ledger?.worktree_path,
|
|
1901
|
+
branchOwnership: 'preexisting', deliveryOutcome: proven ? noChanges ? 'no_changes' : 'ready' : 'blocked',
|
|
1902
|
+
failureCode: proven ? null : 'settlement_interrupted',
|
|
1903
|
+
};
|
|
1904
|
+
}));
|
|
1905
|
+
const ready = recoveredUnits.filter((unit) => unit.deliveryOutcome === 'ready').length;
|
|
1906
|
+
const unchanged = recoveredUnits.length > 0 && recoveredUnits.every((unit) => unit.deliveryOutcome === 'no_changes');
|
|
1907
|
+
const blocked = recoveredUnits.some((unit) => unit.deliveryOutcome === 'blocked');
|
|
1908
|
+
const next = blocked ? 'pr_failed' : unchanged ? 'no_changes' : ready ? 'on_review' : 'pr_failed';
|
|
1909
|
+
(0, rail_pr_store_1.transitionDecision)(db, delivery.id, delivery.decision, next, {
|
|
1910
|
+
branches: recoveredUnits, deliveryOutcome: blocked ? 'blocked' : unchanged ? 'no_changes' : 'ready',
|
|
1911
|
+
statusCode: blocked ? 'settlement_interrupted' : unchanged ? 'no_changes' : 'ready_for_review',
|
|
1912
|
+
});
|
|
1913
|
+
}
|
|
1791
1914
|
// Migration 49 repairs legacy false implementation failures before Git is
|
|
1792
1915
|
// available. Revisit those already-pr_failed rows here: if their own
|
|
1793
1916
|
// durable run/worktree ledger proves one exact clean object, the card can
|
|
@@ -1848,6 +1971,8 @@ async function reconcileRailWorktrees(db, repoDir, io = {}) {
|
|
|
1848
1971
|
return recoveryProtectionScan;
|
|
1849
1972
|
};
|
|
1850
1973
|
for (const delivery of recoveryCandidates) {
|
|
1974
|
+
if (!belongsHere(delivery))
|
|
1975
|
+
continue;
|
|
1851
1976
|
if (!['succeeded', 'partially_succeeded'].includes(delivery.implementation_outcome))
|
|
1852
1977
|
continue;
|
|
1853
1978
|
// Exact-SHA promotion here is specifically an existing-PR retry. A fresh
|