@repo-os/repoos 0.5.74 → 0.5.75
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/dist/.build-info.json +2 -2
- package/dist/.build-stamp.json +1 -1
- package/dist/cli/api-route-parity.js +7 -0
- package/dist/cli/help.js +4 -3
- package/dist/cli/repoos-api.d.ts +1 -0
- package/dist/cli/repoos-api.js +1 -0
- package/dist/commands/check.d.ts +2 -0
- package/dist/commands/check.js +50 -5
- package/dist/commands/checks.js +96 -18
- package/dist/commands/control-api.js +3 -3
- package/dist/commands/docs.js +2 -0
- package/dist/commands/gc.js +24 -26
- package/dist/commands/init.js +2 -2
- package/dist/commands/status.d.ts +32 -3
- package/dist/commands/status.js +59 -14
- package/dist/commands/tasks.d.ts +1 -1
- package/dist/commands/tasks.js +3 -3
- package/dist/commands/ui-smoke.js +8 -7
- package/dist/commands/upgrade.d.ts +1 -7
- package/dist/commands/upgrade.js +2 -19
- package/dist/core/active-task-card.d.ts +79 -0
- package/dist/core/active-task-card.js +172 -0
- package/dist/core/active-without-engineer-recovery.d.ts +34 -0
- package/dist/core/active-without-engineer-recovery.js +40 -0
- package/dist/core/agent-contract.js +2 -4
- package/dist/core/agent-run-tmpdir.d.ts +43 -0
- package/dist/core/agent-run-tmpdir.js +97 -0
- package/dist/core/attention.d.ts +2 -2
- package/dist/core/attention.js +1 -0
- package/dist/core/budget-runtime-state.d.ts +41 -0
- package/dist/core/budget-runtime-state.js +198 -0
- package/dist/core/check-results-store.d.ts +1 -0
- package/dist/core/check-results-store.js +1 -0
- package/dist/core/check-runner.d.ts +1 -0
- package/dist/core/check-runner.js +44 -37
- package/dist/core/check-store.d.ts +29 -1
- package/dist/core/check-store.js +167 -1
- package/dist/core/config.js +82 -34
- package/dist/core/done-task-cleanup.d.ts +6 -0
- package/dist/core/done-task-cleanup.js +53 -0
- package/dist/core/driver-brief.js +2 -0
- package/dist/core/engineer-crash-recovery.js +36 -2
- package/dist/core/engineer-slot.d.ts +15 -0
- package/dist/core/engineer-slot.js +21 -0
- package/dist/core/git.d.ts +42 -2
- package/dist/core/git.js +320 -49
- package/dist/core/landable.d.ts +13 -5
- package/dist/core/landable.js +38 -5
- package/dist/core/launcher-runtime.d.ts +14 -0
- package/dist/core/launcher-runtime.js +129 -0
- package/dist/core/needs-input.js +2 -0
- package/dist/core/process-group.d.ts +11 -0
- package/dist/core/process-group.js +39 -0
- package/dist/core/queued-message-recovery.d.ts +65 -0
- package/dist/core/queued-message-recovery.js +62 -0
- package/dist/core/repoos-toml-runtime-diff.d.ts +1 -0
- package/dist/core/repoos-toml-runtime-diff.js +70 -0
- package/dist/core/report-paths.d.ts +29 -0
- package/dist/core/report-paths.js +60 -0
- package/dist/core/review-findings.js +14 -2
- package/dist/core/review-passes.d.ts +24 -5
- package/dist/core/review-passes.js +74 -29
- package/dist/core/shot-fixtures.d.ts +1 -1
- package/dist/core/shot-fixtures.js +14 -0
- package/dist/core/task.d.ts +7 -0
- package/dist/core/task.js +18 -0
- package/dist/core/test-case-timings.d.ts +36 -0
- package/dist/core/test-case-timings.js +85 -0
- package/dist/core/types.d.ts +11 -0
- package/dist/core/watchdog-task-diff.d.ts +2 -0
- package/dist/core/watchdog-task-diff.js +113 -0
- package/dist/core/worktree-gc.d.ts +55 -13
- package/dist/core/worktree-gc.js +726 -94
- package/dist/server/__tests__/shot-capture-lock.test.d.ts +1 -0
- package/dist/server/__tests__/shot-capture-lock.test.js +18 -0
- package/dist/server/active-task-card.d.ts +24 -0
- package/dist/server/active-task-card.js +73 -0
- package/dist/server/active-without-engineer-recovery.d.ts +15 -0
- package/dist/server/active-without-engineer-recovery.js +148 -0
- package/dist/server/agents.d.ts +42 -1
- package/dist/server/agents.js +203 -27
- package/dist/server/attention-events.js +2 -1
- package/dist/server/attention-notify.d.ts +2 -0
- package/dist/server/attention-notify.js +15 -0
- package/dist/server/auto-engineering.d.ts +2 -1
- package/dist/server/auto-engineering.js +13 -8
- package/dist/server/branchless-release.d.ts +14 -0
- package/dist/server/branchless-release.js +96 -24
- package/dist/server/built-in-agent-runner.js +2 -0
- package/dist/server/cto-monitor.js +4 -0
- package/dist/server/cto.d.ts +4 -3
- package/dist/server/cto.js +4 -3
- package/dist/server/debug-tldr.js +5 -2
- package/dist/server/done-hold-migration.d.ts +8 -0
- package/dist/server/done-hold-migration.js +69 -0
- package/dist/server/done.d.ts +1 -0
- package/dist/server/done.js +24 -3
- package/dist/server/engineer-crash-recovery.js +2 -11
- package/dist/server/engineer-launch.js +22 -0
- package/dist/server/engineering-reports.d.ts +70 -0
- package/dist/server/engineering-reports.js +239 -0
- package/dist/server/freeform-runs.d.ts +2 -1
- package/dist/server/freeform-runs.js +16 -2
- package/dist/server/git-worker.d.ts +2 -0
- package/dist/server/git-worker.js +14 -2
- package/dist/server/handoff.d.ts +10 -0
- package/dist/server/handoff.js +196 -8
- package/dist/server/integration-orchestrator.d.ts +18 -0
- package/dist/server/integration-orchestrator.js +139 -43
- package/dist/server/model-test.d.ts +3 -0
- package/dist/server/model-test.js +16 -1
- package/dist/server/provider-usage-limit-probe.js +6 -8
- package/dist/server/remote-validation.d.ts +17 -4
- package/dist/server/remote-validation.js +119 -27
- package/dist/server/report-layout-migration.d.ts +31 -0
- package/dist/server/report-layout-migration.js +182 -0
- package/dist/server/request-close-out.js +6 -3
- package/dist/server/review-automation.d.ts +1 -0
- package/dist/server/review-automation.js +3 -0
- package/dist/server/review-guard.js +4 -2
- package/dist/server/review-report-store.d.ts +23 -0
- package/dist/server/review-report-store.js +56 -0
- package/dist/server/review-tree-identity.js +49 -2
- package/dist/server/review.d.ts +63 -1
- package/dist/server/review.js +345 -104
- package/dist/server/routes/check-runs.d.ts +2 -0
- package/dist/server/routes/check-runs.js +40 -0
- package/dist/server/routes/config.js +16 -5
- package/dist/server/routes/dev.js +2 -0
- package/dist/server/routes/docs.js +3 -0
- package/dist/server/routes/inputs.js +5 -1
- package/dist/server/routes/models.js +5 -1
- package/dist/server/routes/playground.js +5 -1
- package/dist/server/routes/release.js +3 -0
- package/dist/server/routes/stories.d.ts +3 -0
- package/dist/server/routes/stories.js +40 -1
- package/dist/server/routes/support.js +6 -1
- package/dist/server/routes/tasks.d.ts +4 -0
- package/dist/server/routes/tasks.js +98 -8
- package/dist/server/server.js +191 -22
- package/dist/server/shot-capture.d.ts +2 -0
- package/dist/server/shot-capture.js +34 -1
- package/dist/server/skill-suggestions.js +2 -1
- package/dist/server/story-pm.js +15 -2
- package/dist/server/system.d.ts +79 -0
- package/dist/server/system.js +243 -1
- package/dist/server/task-check.d.ts +9 -0
- package/dist/server/task-check.js +24 -1
- package/dist/server/task-watchdog.d.ts +14 -0
- package/dist/server/task-watchdog.js +64 -8
- package/dist/server/ui-handoff-gate.js +10 -5
- package/dist/server/worktree-handoff-guard.js +7 -2
- package/dist/server/write.js +3 -13
- package/dist/ui/assets/ActivityIndicator-DsxETMHH.js +1 -0
- package/dist/ui/assets/AgentModelControl-BLHKdXCK.js +1 -0
- package/dist/ui/assets/AgentModelModal-DEAULUdA.js +1 -0
- package/dist/ui/assets/AgentsView-BWKykKEA.js +2 -0
- package/dist/ui/assets/AgentsView-DEIyf0uD.css +1 -0
- package/dist/ui/assets/{ChatAgentModelChip-CwDV90K2.js → ChatAgentModelChip-C1B23ArJ.js} +1 -1
- package/dist/ui/assets/ChecksView-CfIhwy6Z.css +1 -0
- package/dist/ui/assets/ChecksView-DaRwduJB.js +0 -0
- package/dist/ui/assets/ContextView-DQ6RW6w0.js +4 -0
- package/dist/ui/assets/DashboardView-B-7-dQLU.js +1 -0
- package/dist/ui/assets/{DashboardView-DJdeWV8s.css → DashboardView-jENeCIEX.css} +1 -1
- package/dist/ui/assets/DeleteConfirmDialog-CHkMTvmt.js +1 -0
- package/dist/ui/assets/DeploymentsView-DiB0gR1F.js +1 -0
- package/dist/ui/assets/{DevView-CYfAT-0x.js → DevView-B-32GGYO.js} +2 -2
- package/dist/ui/assets/{DiffView-BTDGsIts.js → DiffView-DOftUGZx.js} +1 -1
- package/dist/ui/assets/FailedTestsList-C_9Floyr.js +1 -0
- package/dist/ui/assets/InputsView-D4WtnYSg.js +1 -0
- package/dist/ui/assets/LoginView-CcDGWaF3.js +1 -0
- package/dist/ui/assets/PageSkeleton-CsTdMpw3.css +1 -0
- package/dist/ui/assets/PageSkeleton-DRgDMfth.js +1 -0
- package/dist/ui/assets/{ReleasesView-BTN2vXUI.js → ReleasesView-Sxyylk3a.js} +1 -1
- package/dist/ui/assets/SecretsView-C99csAEO.js +1 -0
- package/dist/ui/assets/SettingsView-T6midXQa.js +4 -0
- package/dist/ui/assets/StoriesView-CpLqmKTx.js +1 -0
- package/dist/ui/assets/{VoiceDictate-CES0G8Vq.js → VoiceDictate-D97LIVNB.js} +1 -1
- package/dist/ui/assets/WorkView-C9Fd-nys.js +2 -0
- package/dist/ui/assets/WorkView-couHda3J.css +1 -0
- package/dist/ui/assets/{abnfDiagram-VCTEODGH-DqUj4qFG.js → abnfDiagram-VCTEODGH-B0BRuj2x.js} +1 -1
- package/dist/ui/assets/{architectureDiagram-5GKGNRK7-DAHlI7NO.js → architectureDiagram-5GKGNRK7-ZfY0-Gdw.js} +1 -1
- package/dist/ui/assets/{blockDiagram-I7D4REHJ-BZ71-q2F.js → blockDiagram-I7D4REHJ-C-J_DWun.js} +1 -1
- package/dist/ui/assets/{c4Diagram-7LVT6UL2-CXbbODvo.js → c4Diagram-7LVT6UL2-bQf4xDX5.js} +1 -1
- package/dist/ui/assets/channel-6uQ09cde.js +1 -0
- package/dist/ui/assets/check-progress-p3dLHxxW.js +2 -0
- package/dist/ui/assets/{chunk-2E4U76K2-RYa4g59L.js → chunk-2E4U76K2-DLFOie7L.js} +1 -1
- package/dist/ui/assets/{chunk-4HAMMTFA-CXuZpZ_d.js → chunk-4HAMMTFA-BPDy0z56.js} +1 -1
- package/dist/ui/assets/{chunk-75Z2AOVW-BP2GTRXO.js → chunk-75Z2AOVW-CGe3rSHt.js} +1 -1
- package/dist/ui/assets/{chunk-CLGD4ZFX-DLzOmHqh.js → chunk-CLGD4ZFX-Cc3Z-MGq.js} +1 -1
- package/dist/ui/assets/{chunk-DU6HZSFF-DdjsSi6z.js → chunk-DU6HZSFF-DoNdcPzn.js} +1 -1
- package/dist/ui/assets/{chunk-F27PBJKO-Dnn5wO3i.js → chunk-F27PBJKO-0W-eFq3z.js} +1 -1
- package/dist/ui/assets/{chunk-GMAD6QVW-DdG_nfFi.js → chunk-GMAD6QVW-DIa91igC.js} +1 -1
- package/dist/ui/assets/{chunk-GVQU2GXP-DMAbXLSv.js → chunk-GVQU2GXP-B9kO2TNG.js} +1 -1
- package/dist/ui/assets/{chunk-IMKFNOWR-DHz_-TDB.js → chunk-IMKFNOWR-BVh_kn6v.js} +1 -1
- package/dist/ui/assets/{chunk-L3NEJ4N5-BwhWYbi6.js → chunk-L3NEJ4N5-BIAmP_VV.js} +1 -1
- package/dist/ui/assets/{chunk-OSK3NFVY-CWlbubvG.js → chunk-OSK3NFVY-JwMwYbXa.js} +1 -1
- package/dist/ui/assets/{chunk-P2QGCYS3-D9Muf9td.js → chunk-P2QGCYS3-jcoeuQEp.js} +1 -1
- package/dist/ui/assets/{chunk-POPQ4Y6H-D3ODGb45.js → chunk-POPQ4Y6H-DIWunY1p.js} +1 -1
- package/dist/ui/assets/{chunk-PWAF6VOD-D6LRyAPN.js → chunk-PWAF6VOD-DK7-N58B.js} +1 -1
- package/dist/ui/assets/{chunk-SHT3W25Y-CXu4onhx.js → chunk-SHT3W25Y-CcbXenLZ.js} +1 -1
- package/dist/ui/assets/{chunk-SVP7TREG-7kV5LYQU.js → chunk-SVP7TREG-CU8QcmKz.js} +1 -1
- package/dist/ui/assets/{chunk-TICWLB2K-ygSlNLtb.js → chunk-TICWLB2K-C2dfqOZm.js} +1 -1
- package/dist/ui/assets/chunk-TLUHSLCS-D-41MDHJ.js +2 -0
- package/dist/ui/assets/classDiagram-ZZMXUADV-CG7r0YBU.js +1 -0
- package/dist/ui/assets/classDiagram-v2-VYDZK3BY-CG7r0YBU.js +1 -0
- package/dist/ui/assets/{cynefinDiagram-5FMLGOSQ-DDFWjNjK.js → cynefinDiagram-5FMLGOSQ-OgOMfJ2M.js} +1 -1
- package/dist/ui/assets/{dagre-GXQ25YYZ-CClbhBuT.js → dagre-GXQ25YYZ-DbmwwCwb.js} +1 -1
- package/dist/ui/assets/{diagram-S7CK7UJ4-BXdPXgUF.js → diagram-S7CK7UJ4-fSJUV0Sv.js} +1 -1
- package/dist/ui/assets/{diagram-UQ7AKVKN-Cx3iFpM0.js → diagram-UQ7AKVKN-CPLv2elu.js} +1 -1
- package/dist/ui/assets/{diagram-VSXAHHWV-szmYWA2M.js → diagram-VSXAHHWV-CsOV5L3Y.js} +1 -1
- package/dist/ui/assets/{diagram-VX7I27RA-CX2RE3DT.js → diagram-VX7I27RA-C6eTl1uM.js} +1 -1
- package/dist/ui/assets/{diagram-Z3DM3KII-CmMfHB9Q.js → diagram-Z3DM3KII-B4UZmomc.js} +1 -1
- package/dist/ui/assets/docs-ZCGAA3kV.js +1 -0
- package/dist/ui/assets/{ebnfDiagram-PWID7BFC-BO-2n4ZP.js → ebnfDiagram-PWID7BFC-CSTTfh_S.js} +1 -1
- package/dist/ui/assets/{erDiagram-RLTQ6QDP-dCEqdV8F.js → erDiagram-RLTQ6QDP-BYT61Y7Q.js} +1 -1
- package/dist/ui/assets/flowDiagram-HODETNUW-DzLUu-VJ.js +1 -0
- package/dist/ui/assets/{ganttDiagram-EL5Y4UJY-BJb9E6tm.js → ganttDiagram-EL5Y4UJY-DKTisdub.js} +1 -1
- package/dist/ui/assets/{gitGraphDiagram-WWUBYQGX-B1CtsArh.js → gitGraphDiagram-WWUBYQGX-ZkPvOAfk.js} +1 -1
- package/dist/ui/assets/index-BUmR8syJ.css +1 -0
- package/dist/ui/assets/index-hshjr8FP.js +68 -0
- package/dist/ui/assets/{infoDiagram-27XIBGKW-a6qt1YhM.js → infoDiagram-27XIBGKW-Ck98QGBN.js} +1 -1
- package/dist/ui/assets/{ishikawaDiagram-5VMMS53U-DU6MVFDK.js → ishikawaDiagram-5VMMS53U-CqwQ5qZ8.js} +1 -1
- package/dist/ui/assets/{journeyDiagram-3NMN7TZE-oc0zPgCF.js → journeyDiagram-3NMN7TZE-C1UQN2RN.js} +1 -1
- package/dist/ui/assets/{kanban-definition-UXKFOSKX-BFCluyXI.js → kanban-definition-UXKFOSKX-9zw0uM6N.js} +1 -1
- package/dist/ui/assets/{line-C0dnI-L4.js → line-CeMjuG_7.js} +1 -1
- package/dist/ui/assets/{mermaid-parser.core-CfrNQx8w.js → mermaid-parser.core-Bosog0P9.js} +1 -1
- package/dist/ui/assets/mermaid.core-CJqh-dHb.js +11 -0
- package/dist/ui/assets/{mindmap-definition-YA3MSWOX-DEEwX5b3.js → mindmap-definition-YA3MSWOX-Da8qCo0o.js} +1 -1
- package/dist/ui/assets/{pegDiagram-XKGWAZYB-P0QyFQvY.js → pegDiagram-XKGWAZYB-DELDftZr.js} +1 -1
- package/dist/ui/assets/{pieDiagram-E7YTZNPT-DUingoVK.js → pieDiagram-E7YTZNPT-Da3NN6-R.js} +1 -1
- package/dist/ui/assets/{quadrantDiagram-AXDQQJYC-5KZfHHFZ.js → quadrantDiagram-AXDQQJYC-B51kliky.js} +1 -1
- package/dist/ui/assets/{railroadDiagram-O6MQD6OU-D0sx6QJB.js → railroadDiagram-O6MQD6OU-BgsVU5EU.js} +1 -1
- package/dist/ui/assets/repo-PZFVwA66.js +54 -0
- package/dist/ui/assets/{requirementDiagram-BXWQKSXE-B4DIJgDV.js → requirementDiagram-BXWQKSXE-D1AT3iV0.js} +1 -1
- package/dist/ui/assets/{sankeyDiagram-P5KCCOFB-Ds9sRhEp.js → sankeyDiagram-P5KCCOFB-BDK2LYvj.js} +1 -1
- package/dist/ui/assets/{sequenceDiagram-WJ2MYXX4-BsebZj2V.js → sequenceDiagram-WJ2MYXX4-CNiCcLn-.js} +1 -1
- package/dist/ui/assets/{stateDiagram-D77RDMKH-D4ndCrsI.js → stateDiagram-D77RDMKH-Cf-064cv.js} +1 -1
- package/dist/ui/assets/stateDiagram-v2-MP3YSRHH-CrFLdWWs.js +1 -0
- package/dist/ui/assets/{swimlanes-42K2YHIH-DUuSZaDY.js → swimlanes-42K2YHIH-D-tbu4wq.js} +1 -1
- package/dist/ui/assets/swimlanesDiagram-VR7AAH4N-D6iLKbDv.js +8 -0
- package/dist/ui/assets/{timeline-definition-24CTP7MA-UcuOAqHi.js → timeline-definition-24CTP7MA-DRufowda.js} +1 -1
- package/dist/ui/assets/{vennDiagram-4TSXK5OY-Doc_z7zd.js → vennDiagram-4TSXK5OY-D1vf8POQ.js} +1 -1
- package/dist/ui/assets/{wardleyDiagram-VM6X3IG4-BbAt19tq.js → wardleyDiagram-VM6X3IG4-B4fB0w_8.js} +1 -1
- package/dist/ui/assets/{xychartDiagram-S5SC5T6Z-CFT0no8b.js → xychartDiagram-S5SC5T6Z-CpSh2ftP.js} +1 -1
- package/dist/ui/index.html +12 -14
- package/dist/ui/sw.js +2 -2
- package/package.json +1 -1
- package/dist/ui/assets/ActivityIndicator-4ufauHwi.js +0 -1
- package/dist/ui/assets/AgentModelControl-9-ZIzPrl.js +0 -1
- package/dist/ui/assets/AgentModelModal-Dgv9l_07.js +0 -1
- package/dist/ui/assets/AgentsView-Bl9Olksk.js +0 -2
- package/dist/ui/assets/AgentsView-SbjUmYp0.css +0 -1
- package/dist/ui/assets/ChecksView-DTrP7Uuz.js +0 -0
- package/dist/ui/assets/ChecksView-DVFC0J4t.css +0 -1
- package/dist/ui/assets/ContextView-CxfgyJ-y.js +0 -4
- package/dist/ui/assets/DashboardView-5rGQ9OEh.js +0 -1
- package/dist/ui/assets/DeleteConfirmDialog-Cy8bXm1R.js +0 -1
- package/dist/ui/assets/DependencyChip-CRG4bs5o.js +0 -1
- package/dist/ui/assets/DeploymentsView-BFOhkvLs.js +0 -1
- package/dist/ui/assets/FailedTestsList-xY10Qzc8.js +0 -1
- package/dist/ui/assets/InputsView-7HAgIHQh.js +0 -1
- package/dist/ui/assets/LoginView-BwP14kSS.js +0 -1
- package/dist/ui/assets/PageSkeleton-2lGeBsoi.css +0 -1
- package/dist/ui/assets/PageSkeleton-D7fVi3NJ.js +0 -1
- package/dist/ui/assets/SecretsView-CAFjCFQF.js +0 -1
- package/dist/ui/assets/SettingsView-B2WOxPud.js +0 -4
- package/dist/ui/assets/StoriesView-C-euuUSI.js +0 -1
- package/dist/ui/assets/WorkView-B1JytTp3.css +0 -1
- package/dist/ui/assets/WorkView-C9qAO66W.js +0 -2
- package/dist/ui/assets/channel-Cz_Tghq-.js +0 -1
- package/dist/ui/assets/check-setup-Bng0rbuw.js +0 -2
- package/dist/ui/assets/chunk-TLUHSLCS-Bj-PwaDc.js +0 -2
- package/dist/ui/assets/classDiagram-ZZMXUADV-DHAdi9dV.js +0 -1
- package/dist/ui/assets/classDiagram-v2-VYDZK3BY-DHAdi9dV.js +0 -1
- package/dist/ui/assets/docs-eoM8eVGk.js +0 -1
- package/dist/ui/assets/flowDiagram-HODETNUW-CX9qpoV4.js +0 -1
- package/dist/ui/assets/index-Pr4f9cgO.js +0 -68
- package/dist/ui/assets/index-m6du4z4N.css +0 -1
- package/dist/ui/assets/mermaid.core-CKD0p_aW.js +0 -11
- package/dist/ui/assets/repo-B9GZ5YkR.js +0 -40
- package/dist/ui/assets/stateDiagram-v2-MP3YSRHH-BHwEjBfW.js +0 -1
- package/dist/ui/assets/swimlanesDiagram-VR7AAH4N-BrUdO8ca.js +0 -8
- package/dist/ui/assets/ui-fJTOEtHH.js +0 -7
package/dist/.build-info.json
CHANGED
package/dist/.build-stamp.json
CHANGED
|
@@ -73,6 +73,11 @@ const FILE_CLI_MATCHERS = [
|
|
|
73
73
|
];
|
|
74
74
|
/** UI-only, SSE/hub, auth, or internal routes — no CLI required. */
|
|
75
75
|
const UI_ONLY_MATCHERS = [
|
|
76
|
+
// Task-card-only explicit cancellation of a stalled, registered local check.
|
|
77
|
+
re("POST", /^\/api\/tasks\/([^/]+)\/cancel-check$/.source),
|
|
78
|
+
// Read-only task engineering-report history used by the Dev tab.
|
|
79
|
+
re("GET", /^\/api\/tasks\/([^/]+)\/engineering-reports$/.source),
|
|
80
|
+
re("GET", /^\/api\/tasks\/([^/]+)\/engineering-reports\/([^/]+)$/.source),
|
|
76
81
|
under("/api/auth/"),
|
|
77
82
|
under("/api/hub/"),
|
|
78
83
|
under("/api/telegram/"),
|
|
@@ -111,6 +116,7 @@ const UI_ONLY_MATCHERS = [
|
|
|
111
116
|
exact("GET", "/api/attention"),
|
|
112
117
|
exact("GET", "/api/decisions"),
|
|
113
118
|
exact("GET", "/api/check-runs"),
|
|
119
|
+
exact("GET", "/api/check-run-test-cases"),
|
|
114
120
|
exact("GET", "/api/local-check-slots"),
|
|
115
121
|
re("POST", /^\/api\/local-check-slots\/(\d+)\/release\/(\d+)$/.source),
|
|
116
122
|
exact("GET", "/api/resource-queues"),
|
|
@@ -118,6 +124,7 @@ const UI_ONLY_MATCHERS = [
|
|
|
118
124
|
re("GET", /^\/api\/tasks\/([^/]+)\/integration-job$/.source),
|
|
119
125
|
re("POST", /^\/api\/tasks\/([^/]+)\/worktree-handoff\/discard$/.source),
|
|
120
126
|
re("GET", /^\/api\/tasks\/([^/]+)\/review$/.source),
|
|
127
|
+
re("GET", /^\/api\/tasks\/([^/]+)\/review\/passes\/([^/]+)$/.source),
|
|
121
128
|
re("POST", /^\/api\/tasks\/([^/]+)\/review\/message$/.source),
|
|
122
129
|
re("POST", /^\/api\/tasks\/([^/]+)\/pm\/message$/.source),
|
|
123
130
|
re("POST", /^\/api\/tasks\/([^/]+)\/pm\/interrupt$/.source),
|
package/dist/cli/help.js
CHANGED
|
@@ -157,7 +157,7 @@ const GROUPS = [
|
|
|
157
157
|
{
|
|
158
158
|
name: "landable",
|
|
159
159
|
usage: "landable <id> [--json] [--port N]",
|
|
160
|
-
desc: "Read-only
|
|
160
|
+
desc: "Read-only checks before merging (verdict, lock, worktree, merge, scope, main) — exits non-zero when the task is not ready to merge (GET /api/tasks/:id/landable)",
|
|
161
161
|
flags: "--json · --port",
|
|
162
162
|
},
|
|
163
163
|
{
|
|
@@ -304,8 +304,9 @@ const GROUPS = [
|
|
|
304
304
|
},
|
|
305
305
|
{
|
|
306
306
|
name: "checks timings",
|
|
307
|
-
usage: "checks timings",
|
|
308
|
-
desc: "
|
|
307
|
+
usage: "checks timings [--tests] [--run-id ID] [--recent-runs N] [--limit N] [--offset N] [--json]",
|
|
308
|
+
desc: "Recent check durations, slowest test files, and slow individual test cases",
|
|
309
|
+
flags: "--tests · --run-id ID · --recent-runs N · --limit N · --offset N · --json",
|
|
309
310
|
},
|
|
310
311
|
{
|
|
311
312
|
name: "checks slots",
|
package/dist/cli/repoos-api.d.ts
CHANGED
package/dist/cli/repoos-api.js
CHANGED
|
@@ -127,6 +127,7 @@ export class RepoOsApi {
|
|
|
127
127
|
method,
|
|
128
128
|
headers: this.buildHeaders(jsonBody),
|
|
129
129
|
body: jsonBody ? JSON.stringify(body) : undefined,
|
|
130
|
+
signal: opts.timeoutMs && opts.timeoutMs > 0 ? AbortSignal.timeout(opts.timeoutMs) : undefined,
|
|
130
131
|
});
|
|
131
132
|
}
|
|
132
133
|
catch (err) {
|
package/dist/commands/check.d.ts
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { type TestFileTiming } from "../core/test-file-timings.js";
|
|
2
|
+
import { type TestCaseTiming } from "../core/test-case-timings.js";
|
|
2
3
|
import type { CheckContrastPair, CheckThemeScope, RepoOSConfig } from "../core/types.js";
|
|
3
4
|
import { type CheckPlan, type CheckStep } from "../core/check-plan.js";
|
|
4
5
|
import { type StepRunResult, type StepStatus } from "../core/check-runner.js";
|
|
@@ -275,6 +276,7 @@ interface StepContext {
|
|
|
275
276
|
/** What a built-in `kind` handler returns. */
|
|
276
277
|
interface BuiltinOutcome {
|
|
277
278
|
testFileTimings?: TestFileTiming[];
|
|
279
|
+
testCaseTimings?: TestCaseTiming[];
|
|
278
280
|
status: StepStatus;
|
|
279
281
|
/** The command it resolved to (so the results block can name it). */
|
|
280
282
|
command?: string;
|
package/dist/commands/check.js
CHANGED
|
@@ -33,6 +33,7 @@ import { cpus, totalmem } from "node:os";
|
|
|
33
33
|
import { isAbsolute, join, relative, sep } from "node:path";
|
|
34
34
|
import { c } from "../cli/colors.js";
|
|
35
35
|
import { TestFileTimingCollector, testFileTimings, formatSlowestTestFiles, } from "../core/test-file-timings.js";
|
|
36
|
+
import { TestCaseTimingCollector, formatSlowestTestCases, mergeTestCaseTimings, pushTimingOutputChunk, } from "../core/test-case-timings.js";
|
|
36
37
|
import { checkBuildForRoot } from "../core/build.js";
|
|
37
38
|
import { findRepoRoot, loadConfig } from "../core/config.js";
|
|
38
39
|
import { availableMemBytes } from "../core/sysmem.js";
|
|
@@ -1403,6 +1404,10 @@ async function stepTests(ctx) {
|
|
|
1403
1404
|
: "skipped — test suite ran on the remote validation runner (REPOOS_SKIP_TESTS=1)");
|
|
1404
1405
|
}
|
|
1405
1406
|
const fileTimingCollector = new TestFileTimingCollector();
|
|
1407
|
+
const caseTimingCollector = new TestCaseTimingCollector();
|
|
1408
|
+
const onTimingChunk = (chunk) => {
|
|
1409
|
+
pushTimingOutputChunk(chunk, fileTimingCollector, caseTimingCollector);
|
|
1410
|
+
};
|
|
1406
1411
|
const hasTestScript = Boolean(ctx.scriptPkg.scripts?.test);
|
|
1407
1412
|
const hasTestFiles = ["test", "__tests__", "tests"].some((d) => existsSync(join(ctx.cwd, d)));
|
|
1408
1413
|
if (!hasTestScript && !hasTestFiles)
|
|
@@ -1441,7 +1446,7 @@ async function stepTests(ctx) {
|
|
|
1441
1446
|
console.log(c.dim(` · previously-failed test file(s) first · ${priorFiles.join(", ")}`));
|
|
1442
1447
|
const pre = await runCommand({
|
|
1443
1448
|
command: preflight,
|
|
1444
|
-
onChunk:
|
|
1449
|
+
onChunk: onTimingChunk,
|
|
1445
1450
|
cwd: ctx.cwd,
|
|
1446
1451
|
timeoutMs: 300_000,
|
|
1447
1452
|
env,
|
|
@@ -1455,6 +1460,7 @@ async function stepTests(ctx) {
|
|
|
1455
1460
|
status: pre.status === "timeout" ? "timeout" : "failed",
|
|
1456
1461
|
command: preflight,
|
|
1457
1462
|
testFileTimings: fileTimingCollector.values(),
|
|
1463
|
+
testCaseTimings: caseTimingCollector.values(),
|
|
1458
1464
|
detail: `previously-failed test file(s) still fail — ${why}`,
|
|
1459
1465
|
output: pre.output,
|
|
1460
1466
|
};
|
|
@@ -1478,13 +1484,14 @@ async function stepTests(ctx) {
|
|
|
1478
1484
|
timeoutMs,
|
|
1479
1485
|
env,
|
|
1480
1486
|
echo: ctx.echo,
|
|
1481
|
-
onChunk:
|
|
1487
|
+
onChunk: onTimingChunk,
|
|
1482
1488
|
});
|
|
1483
1489
|
if (res.status === "passed") {
|
|
1484
1490
|
return {
|
|
1485
1491
|
status: "passed",
|
|
1486
1492
|
command,
|
|
1487
1493
|
testFileTimings: fileTimingCollector.values(),
|
|
1494
|
+
testCaseTimings: caseTimingCollector.values(),
|
|
1488
1495
|
detail: changedRef ? `scoped to changed vs ${changedRef} plus always-run suites` : undefined,
|
|
1489
1496
|
output: res.output,
|
|
1490
1497
|
};
|
|
@@ -1493,6 +1500,7 @@ async function stepTests(ctx) {
|
|
|
1493
1500
|
return {
|
|
1494
1501
|
status: "timeout",
|
|
1495
1502
|
testFileTimings: fileTimingCollector.values(),
|
|
1503
|
+
testCaseTimings: caseTimingCollector.values(),
|
|
1496
1504
|
command,
|
|
1497
1505
|
detail: `timed out after ${timeoutLabel(timeoutMs)}`,
|
|
1498
1506
|
output: res.output,
|
|
@@ -1504,6 +1512,7 @@ async function stepTests(ctx) {
|
|
|
1504
1512
|
return {
|
|
1505
1513
|
status: "failed",
|
|
1506
1514
|
testFileTimings: fileTimingCollector.values(),
|
|
1515
|
+
testCaseTimings: caseTimingCollector.values(),
|
|
1507
1516
|
command,
|
|
1508
1517
|
detail: outputTail(res.output) ?? `Tests failed (exit ${res.exitCode})`,
|
|
1509
1518
|
output: res.output,
|
|
@@ -1822,6 +1831,7 @@ export async function runCheckPlan(plan, opts) {
|
|
|
1822
1831
|
required: step.required,
|
|
1823
1832
|
isolationNote: outcome.isolationNote,
|
|
1824
1833
|
testFileTimings: outcome.testFileTimings,
|
|
1834
|
+
testCaseTimings: outcome.testCaseTimings,
|
|
1825
1835
|
});
|
|
1826
1836
|
}
|
|
1827
1837
|
return results;
|
|
@@ -2142,12 +2152,27 @@ export async function cmdCheck(argv = []) {
|
|
|
2142
2152
|
console.log(c.red(`\n ✗ ${msg}\n`));
|
|
2143
2153
|
const holders = inspectCrossProcessSlots(localCheckLockRoot(repoRoot, cfg.cacheDir ?? ".repoos"));
|
|
2144
2154
|
for (const holder of holders) {
|
|
2145
|
-
console.log(c.dim(` slot ${holder.slot}: pid ${holder.pid ?? "unknown"}, ${Math.round(holder.ageMs / 1000)}s${holder.dead ? " (
|
|
2155
|
+
console.log(c.dim(` slot ${holder.slot}: pid ${holder.pid ?? "unknown"}, ${Math.round(holder.ageMs / 1000)}s${holder.dead ? " (process exited; reclaiming)" : holder.wedged ? ` (no recent heartbeat; last seen ${Math.round(holder.heartbeatAgeMs / 1000)}s ago)` : ""}`));
|
|
2146
2156
|
}
|
|
2147
2157
|
process.exit(1);
|
|
2148
2158
|
}
|
|
2149
2159
|
waitRecord = waits.finish();
|
|
2150
2160
|
const runStartedAt = new Date();
|
|
2161
|
+
// Persist a provisional row before running steps. If this process is killed,
|
|
2162
|
+
// the durable history still shows an interrupted run instead of no run.
|
|
2163
|
+
const historyRunId = recordRunHistoryRow({
|
|
2164
|
+
root: checkStoreRoot,
|
|
2165
|
+
cacheDir: cfg.cacheDir,
|
|
2166
|
+
attribution: runContext,
|
|
2167
|
+
scope: changedRef ? `changed:${changedRef}` : "full",
|
|
2168
|
+
worktree: repoRoot,
|
|
2169
|
+
startedAt: runStartedAt.toISOString(),
|
|
2170
|
+
durationMs: 0,
|
|
2171
|
+
outcome: "cancelled",
|
|
2172
|
+
failedStep: "check",
|
|
2173
|
+
skippedSteps: [],
|
|
2174
|
+
detail: "Check was interrupted before completion.",
|
|
2175
|
+
});
|
|
2151
2176
|
// Failed-first ordering (#0655): only interactive/CLI and pre-review runs
|
|
2152
2177
|
// reorder. Close-out and release run their selected suite from a clean
|
|
2153
2178
|
// slate, and the remote close-out gate never reaches this point. Attribution
|
|
@@ -2231,6 +2256,7 @@ export async function cmdCheck(argv = []) {
|
|
|
2231
2256
|
skippedSteps: [],
|
|
2232
2257
|
steps: completedSteps,
|
|
2233
2258
|
detail: `check crashed before completing: ${e.message}`,
|
|
2259
|
+
updateId: historyRunId,
|
|
2234
2260
|
});
|
|
2235
2261
|
throw e;
|
|
2236
2262
|
}
|
|
@@ -2290,9 +2316,17 @@ export async function cmdCheck(argv = []) {
|
|
|
2290
2316
|
}
|
|
2291
2317
|
}
|
|
2292
2318
|
const fileTimings = results.flatMap((r) => r.testFileTimings ?? testFileTimings(r.output ?? ""));
|
|
2319
|
+
// Individual case history comes only from Vitest's structured reporter
|
|
2320
|
+
// events. Step output is intentionally bounded and must never be its source.
|
|
2321
|
+
const caseTimings = mergeTestCaseTimings(results.flatMap((r) => r.testCaseTimings ?? []));
|
|
2293
2322
|
if (fileTimings.length) {
|
|
2294
2323
|
heading("Slowest test files");
|
|
2295
2324
|
console.log(formatSlowestTestFiles(fileTimings));
|
|
2325
|
+
console.log(c.dim(" File totals include hook time in that file; they are not the sum of individual cases below."));
|
|
2326
|
+
}
|
|
2327
|
+
if (caseTimings.length) {
|
|
2328
|
+
heading("Slowest test cases");
|
|
2329
|
+
console.log(formatSlowestTestCases(caseTimings));
|
|
2296
2330
|
}
|
|
2297
2331
|
// Persist the run for the Checks surface (#0447) before exiting. Fail-soft:
|
|
2298
2332
|
// visibility only, never a reason to fail an otherwise-green gate.
|
|
@@ -2352,6 +2386,7 @@ export async function cmdCheck(argv = []) {
|
|
|
2352
2386
|
durationMs: r.durationMs,
|
|
2353
2387
|
output: r.output,
|
|
2354
2388
|
testFileTimings: r.testFileTimings,
|
|
2389
|
+
testCaseTimings: r.testCaseTimings,
|
|
2355
2390
|
detail: r.detail,
|
|
2356
2391
|
required: r.required,
|
|
2357
2392
|
})),
|
|
@@ -2377,6 +2412,7 @@ export async function cmdCheck(argv = []) {
|
|
|
2377
2412
|
stepsDone: finalProgress?.stepsDone ?? null,
|
|
2378
2413
|
stepsTotal: finalProgress?.stepsTotal ?? null,
|
|
2379
2414
|
testFileTimings: fileTimings,
|
|
2415
|
+
testCaseTimings: caseTimings,
|
|
2380
2416
|
testsDone: testProgress?.testsDone ?? null,
|
|
2381
2417
|
testsTotal: testProgress?.testsTotal ?? null,
|
|
2382
2418
|
detail: (() => {
|
|
@@ -2403,6 +2439,7 @@ export async function cmdCheck(argv = []) {
|
|
|
2403
2439
|
failedTests: gatingFailures.flatMap((r) => extractFailedTests(r.output ?? "")),
|
|
2404
2440
|
// Informational isolation label (#0655) — never part of the outcome.
|
|
2405
2441
|
isolationNote: results.find((r) => r.isolationNote)?.isolationNote ?? null,
|
|
2442
|
+
updateId: historyRunId,
|
|
2406
2443
|
});
|
|
2407
2444
|
process.exit(gatingFailures.length > 0 ? 1 : 0);
|
|
2408
2445
|
}
|
|
@@ -2438,7 +2475,8 @@ export function previousFailedTestsForRun(opts) {
|
|
|
2438
2475
|
function recordRunHistoryRow(row) {
|
|
2439
2476
|
try {
|
|
2440
2477
|
const { taskId, phase } = row.attribution;
|
|
2441
|
-
getCheckStore(row.root, row.cacheDir)
|
|
2478
|
+
const store = getCheckStore(row.root, row.cacheDir);
|
|
2479
|
+
const input = {
|
|
2442
2480
|
taskId,
|
|
2443
2481
|
phase,
|
|
2444
2482
|
worktree: row.worktree,
|
|
@@ -2463,10 +2501,17 @@ function recordRunHistoryRow(row) {
|
|
|
2463
2501
|
testsTotal: row.testsTotal,
|
|
2464
2502
|
steps: row.steps,
|
|
2465
2503
|
testFileTimings: row.testFileTimings,
|
|
2466
|
-
|
|
2504
|
+
testCaseTimings: row.testCaseTimings,
|
|
2505
|
+
};
|
|
2506
|
+
if (row.updateId != null) {
|
|
2507
|
+
store.update(row.updateId, input);
|
|
2508
|
+
return row.updateId;
|
|
2509
|
+
}
|
|
2510
|
+
return store.record(input);
|
|
2467
2511
|
}
|
|
2468
2512
|
catch {
|
|
2469
2513
|
/* never fail the gate on a history write */
|
|
2514
|
+
return null;
|
|
2470
2515
|
}
|
|
2471
2516
|
}
|
|
2472
2517
|
/**
|
package/dist/commands/checks.js
CHANGED
|
@@ -1,32 +1,110 @@
|
|
|
1
|
-
import { getCheckStore } from "../core/check-store.js";
|
|
1
|
+
import { DEFAULT_TEST_CASE_LIST_LIMIT, getCheckStore, MAX_TEST_CASE_LIST_LIMIT, } from "../core/check-store.js";
|
|
2
2
|
import { formatSlowestTestFiles } from "../core/test-file-timings.js";
|
|
3
|
+
import { formatSlowestTestCases } from "../core/test-case-timings.js";
|
|
3
4
|
import { c } from "../cli/colors.js";
|
|
4
5
|
import { loadConfig } from "../core/config.js";
|
|
5
6
|
import { inspectCrossProcessSlots, listSlotWaiterPids, localCheckLockRoot, releaseLocalCheckSlot, } from "../core/cross-process-slots.js";
|
|
6
7
|
import { currentQueueMarkers, readQueueMarkers } from "../core/local-queue-marker.js";
|
|
7
8
|
import { mainCheckoutRoot } from "../core/git.js";
|
|
8
9
|
import { heavySlotLimit } from "../core/resource-limits.js";
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
10
|
+
function resolveChecksRoot() {
|
|
11
|
+
const config = loadConfig();
|
|
12
|
+
try {
|
|
13
|
+
return mainCheckoutRoot(config.root);
|
|
14
|
+
}
|
|
15
|
+
catch {
|
|
16
|
+
return config.root;
|
|
17
|
+
}
|
|
18
|
+
}
|
|
19
|
+
function parseTimingsFlags(args) {
|
|
20
|
+
let json = false;
|
|
21
|
+
let tests = false;
|
|
22
|
+
let runId;
|
|
23
|
+
let recentRuns = 10;
|
|
24
|
+
let limit = DEFAULT_TEST_CASE_LIST_LIMIT;
|
|
25
|
+
let offset = 0;
|
|
26
|
+
for (let i = 0; i < args.length; i++) {
|
|
27
|
+
const a = args[i];
|
|
28
|
+
if (a === "--json")
|
|
29
|
+
json = true;
|
|
30
|
+
else if (a === "--tests" || a === "tests")
|
|
31
|
+
tests = true;
|
|
32
|
+
else if (a === "--run-id" || a === "--run") {
|
|
33
|
+
const n = Number(args[++i]);
|
|
34
|
+
if (Number.isFinite(n) && n > 0)
|
|
35
|
+
runId = Math.floor(n);
|
|
36
|
+
}
|
|
37
|
+
else if (a === "--recent-runs" || a === "--recent") {
|
|
38
|
+
const n = Number(args[++i]);
|
|
39
|
+
if (Number.isFinite(n) && n > 0)
|
|
40
|
+
recentRuns = Math.min(100, Math.floor(n));
|
|
15
41
|
}
|
|
16
|
-
|
|
17
|
-
|
|
42
|
+
else if (a === "--limit") {
|
|
43
|
+
const n = Number(args[++i]);
|
|
44
|
+
if (Number.isFinite(n) && n > 0)
|
|
45
|
+
limit = Math.min(MAX_TEST_CASE_LIST_LIMIT, Math.floor(n));
|
|
18
46
|
}
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
if (
|
|
22
|
-
|
|
23
|
-
console.log(formatSlowestTestFiles(run.testFileTimings));
|
|
24
|
-
}
|
|
47
|
+
else if (a === "--offset") {
|
|
48
|
+
const n = Number(args[++i]);
|
|
49
|
+
if (Number.isFinite(n) && n >= 0)
|
|
50
|
+
offset = Math.floor(n);
|
|
25
51
|
}
|
|
52
|
+
}
|
|
53
|
+
return { json, tests, runId, recentRuns, limit, offset };
|
|
54
|
+
}
|
|
55
|
+
function cmdChecksTimings(args) {
|
|
56
|
+
const config = loadConfig();
|
|
57
|
+
const root = resolveChecksRoot();
|
|
58
|
+
const flags = parseTimingsFlags(args);
|
|
59
|
+
const store = getCheckStore(root, config.cacheDir);
|
|
60
|
+
if (flags.tests) {
|
|
61
|
+
const result = store.listSlowTestCases({
|
|
62
|
+
runId: flags.runId,
|
|
63
|
+
recentRuns: flags.recentRuns,
|
|
64
|
+
limit: flags.limit,
|
|
65
|
+
offset: flags.offset,
|
|
66
|
+
});
|
|
67
|
+
if (flags.json) {
|
|
68
|
+
console.log(JSON.stringify({ ok: true, ...result }, null, 0));
|
|
69
|
+
return;
|
|
70
|
+
}
|
|
71
|
+
const scope = flags.runId != null
|
|
72
|
+
? `run #${flags.runId}`
|
|
73
|
+
: `last ${result.recentRuns ?? flags.recentRuns} run(s)`;
|
|
74
|
+
console.log(`Slowest test cases (including beforeEach/afterEach hooks) · ${scope} · limit ${result.limit} offset ${result.offset}`);
|
|
75
|
+
if (!result.cases.length) {
|
|
76
|
+
console.log(" (no recorded cases — run repoos check after upgrading)");
|
|
77
|
+
return;
|
|
78
|
+
}
|
|
79
|
+
console.log(formatSlowestTestCases(result.cases.map(({ file, name, durationMs, result: outcome, retry, caseId }) => ({
|
|
80
|
+
file,
|
|
81
|
+
name,
|
|
82
|
+
caseId,
|
|
83
|
+
retry,
|
|
84
|
+
durationMs,
|
|
85
|
+
result: outcome,
|
|
86
|
+
})), result.limit));
|
|
87
|
+
if (result.hasMore) {
|
|
88
|
+
console.log(c.dim(` … more rows available (hasMore)`));
|
|
89
|
+
}
|
|
90
|
+
return;
|
|
91
|
+
}
|
|
92
|
+
for (const run of store.list({ limit: 10 })) {
|
|
93
|
+
console.log(`${run.startedAt} · ${run.phase} · ${run.machine ?? "local"} · ${run.scope} · ${((run.durationMs ?? 0) / 1000).toFixed(1)}s · run #${run.id}`);
|
|
94
|
+
if (run.testFileTimings?.length) {
|
|
95
|
+
console.log("Slowest test files (test + hook time in file):");
|
|
96
|
+
console.log(formatSlowestTestFiles(run.testFileTimings));
|
|
97
|
+
}
|
|
98
|
+
}
|
|
99
|
+
console.log(c.dim("\nIndividual cases: repoos checks timings --tests [--run-id ID] [--recent-runs N] [--limit N] [--offset N] [--json]"));
|
|
100
|
+
}
|
|
101
|
+
export function cmdChecks(args) {
|
|
102
|
+
if (args[0] === "timings") {
|
|
103
|
+
cmdChecksTimings(args.slice(1));
|
|
26
104
|
return;
|
|
27
105
|
}
|
|
28
106
|
if (args[0] !== "slots") {
|
|
29
|
-
console.error("Usage: repoos checks timings | slots [--release SLOT --confirm PID]");
|
|
107
|
+
console.error("Usage: repoos checks timings [--tests] [--run-id ID] [--recent-runs N] [--limit N] [--offset N] [--json] | slots [--release SLOT --confirm PID]");
|
|
30
108
|
process.exitCode = 2;
|
|
31
109
|
return;
|
|
32
110
|
}
|
|
@@ -54,7 +132,7 @@ export function cmdChecks(args) {
|
|
|
54
132
|
const holder = inspectCrossProcessSlots(root, heavySlotLimit(config), config.localChecks?.staleAfterMs).find((item) => item.slot === slot);
|
|
55
133
|
if (!holder?.pid)
|
|
56
134
|
throw new Error(`slot ${slot} is free`);
|
|
57
|
-
console.log(`Releasing slot ${slot}, held by task #${String(holder.meta?.taskId ?? "unknown")} check, PID ${holder.pid}${holder.dead ? ",
|
|
135
|
+
console.log(`Releasing slot ${slot}, held by task #${String(holder.meta?.taskId ?? "unknown")} check, PID ${holder.pid}${holder.dead ? ", process exited" : holder.wedged ? `, no recent heartbeat (last seen ${Math.round(holder.heartbeatAgeMs / 1000)}s ago)` : ", alive"}.`);
|
|
58
136
|
releaseLocalCheckSlot(root, slot, pid, config.localChecks?.staleAfterMs);
|
|
59
137
|
console.log(c.green(" ✔ Slot released."));
|
|
60
138
|
}
|
|
@@ -70,7 +148,7 @@ export function cmdChecks(args) {
|
|
|
70
148
|
? `#${String(holder.meta.taskId)} check`
|
|
71
149
|
: "unattributed check";
|
|
72
150
|
console.log(holder.pid
|
|
73
|
-
? `slot ${holder.slot}: ${task}, pid ${holder.pid}, ${holder.dead ? "
|
|
151
|
+
? `slot ${holder.slot}: ${task}, pid ${holder.pid}, ${holder.dead ? "process exited, reclaiming" : holder.wedged ? `no recent heartbeat (last seen ${Math.round(holder.heartbeatAgeMs / 1000)}s ago)` : "alive"}, held ${Math.round(holder.ageMs / 1000)}s, heartbeat ${Math.round(holder.heartbeatAgeMs / 1000)}s ago`
|
|
74
152
|
: `slot ${holder.slot}: free`);
|
|
75
153
|
}
|
|
76
154
|
const queue = currentQueueMarkers(readQueueMarkers(boardRoot, cacheDir).filter((entry) => entry.kind === "local-check"), listSlotWaiterPids(root));
|
|
@@ -738,7 +738,7 @@ export async function cmdDone(args) {
|
|
|
738
738
|
console.log(`${result.status >= 200 && result.status < 300 ? c.green(" ✓ ") : c.yellow(" · ")}${message} (HTTP ${result.status})`);
|
|
739
739
|
return (result.status >= 200 && result.status < 300) || result.status === 409 ? 0 : 1;
|
|
740
740
|
}
|
|
741
|
-
const started = await api.request("POST", `/api/tasks/${id}/done`, { commitDirty });
|
|
741
|
+
const started = await api.request("POST", `/api/tasks/${id}/done`, { commitDirty }, { timeoutMs: 0 });
|
|
742
742
|
if (started.status === 409 && started.body.needsCommit) {
|
|
743
743
|
throw new RepoOsApiError(started.body.error ?? "close-out blocked on dirty tree", 409, started.body);
|
|
744
744
|
}
|
|
@@ -1529,8 +1529,8 @@ export async function cmdLandable(args) {
|
|
|
1529
1529
|
printJson(result);
|
|
1530
1530
|
else {
|
|
1531
1531
|
const verdict = result.landable
|
|
1532
|
-
? c.green(`#${id} is
|
|
1533
|
-
: c.red(`#${id} is not
|
|
1532
|
+
? c.green(`#${id} is ready to merge`)
|
|
1533
|
+
: c.red(`#${id} is not ready to merge yet`);
|
|
1534
1534
|
console.log(` ${verdict}`);
|
|
1535
1535
|
for (const check of result.checks) {
|
|
1536
1536
|
console.log(` ${landableIcon(check.status)} ${c.bold(check.label)} — ${check.detail}`);
|
package/dist/commands/docs.js
CHANGED
|
@@ -5,6 +5,7 @@ import { readFileSync } from "node:fs";
|
|
|
5
5
|
import { createDocument, createFreeformDocument, docFreeformPrompt, parseGeneratedDocument, } from "../core/docs.js";
|
|
6
6
|
import { loadConfig } from "../core/config.js";
|
|
7
7
|
import { c } from "../cli/colors.js";
|
|
8
|
+
import { repoAgentRunTmpOpts } from "../core/agent-run-tmpdir.js";
|
|
8
9
|
import { resolvePmAgent, runPrompt, recordOneShotSession } from "../server/agents.js";
|
|
9
10
|
import { currentDocsDir, importDocsInto, scaffoldDocsInto } from "./docs-io.js";
|
|
10
11
|
/** `repoos new-doc "<description>"` or `repoos new-doc --path docs/foo.md --content-file x.md` */
|
|
@@ -34,6 +35,7 @@ export async function cmdNewDoc(args) {
|
|
|
34
35
|
const docResult = await createFreeformDocument(config, description, async (desc) => {
|
|
35
36
|
const result = await runPrompt(pm, docFreeformPrompt(desc), {
|
|
36
37
|
cwd: config.root,
|
|
38
|
+
...repoAgentRunTmpOpts(config),
|
|
37
39
|
});
|
|
38
40
|
// Freeform doc authoring is real PM spend that belongs to no task (0311).
|
|
39
41
|
recordOneShotSession(config.root, pm, result, { sessionType: "pm", taskId: null });
|
package/dist/commands/gc.js
CHANGED
|
@@ -3,29 +3,37 @@
|
|
|
3
3
|
*
|
|
4
4
|
* Runs against the MAIN checkout (via `boardRoot()`), never a linked worktree.
|
|
5
5
|
*
|
|
6
|
-
*
|
|
7
|
-
*
|
|
8
|
-
*
|
|
9
|
-
*
|
|
10
|
-
*
|
|
6
|
+
* Cleanup is automatic and safe by construction (#1004): the same sweep runs at
|
|
7
|
+
* boot and after every close-out. An operator can still inspect or force a run:
|
|
8
|
+
*
|
|
9
|
+
* repoos gc run the safe sweep now (candidates + resolved,
|
|
10
|
+
* provably-redundant feature worktrees)
|
|
11
|
+
* repoos gc --yes accepted for compatibility; identical to the above
|
|
12
|
+
* repoos gc --dry-run show candidates, retained reasons, and external
|
|
13
|
+
* worktrees, touching nothing
|
|
11
14
|
*/
|
|
12
15
|
import { createRepoOS } from "../core/repoos.js";
|
|
13
16
|
import { boardRoot } from "../core/config.js";
|
|
14
17
|
import { c } from "../cli/colors.js";
|
|
15
|
-
import { sweepStaleWorktrees } from "../core/worktree-gc.js";
|
|
18
|
+
import { formatGcEntryDetails, sweepStaleWorktrees } from "../core/worktree-gc.js";
|
|
16
19
|
function printReport(report, title) {
|
|
17
20
|
console.log(c.bold(` ${title}`));
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
console.log(c.dim(" nothing to collect"));
|
|
22
|
-
}
|
|
21
|
+
const counts = report.summary;
|
|
22
|
+
console.log(c.dim(` ${counts.candidates} safe candidate${counts.candidates === 1 ? "" : "s"} · ` +
|
|
23
|
+
`${counts.retained} retained · ${counts.external} outside RepoOS`));
|
|
23
24
|
for (const w of report.removedWorktrees) {
|
|
24
25
|
const verb = report.dryRun ? "would remove" : "removed";
|
|
25
|
-
console.log(` ${c.green(verb)} ${w.branch || c.dim("(detached)")} ${c.dim(w.path)}`
|
|
26
|
+
console.log(` ${c.green(verb)} ${w.branch || c.dim("(detached)")} ${c.dim(w.path)}` +
|
|
27
|
+
c.dim(` — ${w.reason}`));
|
|
26
28
|
}
|
|
27
|
-
for (const k of report.
|
|
29
|
+
for (const k of report.retained) {
|
|
28
30
|
console.log(` ${c.yellow("kept")} ${k.branch || c.dim("(detached)")} ${c.dim(`— ${k.reason}`)}`);
|
|
31
|
+
const detail = formatGcEntryDetails(k);
|
|
32
|
+
if (detail)
|
|
33
|
+
console.log(c.dim(` ${detail}`));
|
|
34
|
+
}
|
|
35
|
+
for (const e of report.external) {
|
|
36
|
+
console.log(` ${c.dim("external")} ${e.branch || c.dim("(detached)")} ${c.dim(e.path)}`);
|
|
29
37
|
}
|
|
30
38
|
for (const e of report.errors) {
|
|
31
39
|
console.log(` ${c.red("error")} ${e}`);
|
|
@@ -35,23 +43,13 @@ function printReport(report, title) {
|
|
|
35
43
|
}
|
|
36
44
|
export function cmdGc(argv) {
|
|
37
45
|
const dryRun = argv.includes("--dry-run") || argv.includes("-n");
|
|
38
|
-
|
|
46
|
+
// `--yes` is accepted as a no-op compatibility alias: the default sweep is
|
|
47
|
+
// already the same safe policy, with the same fail-closed guards.
|
|
39
48
|
const { root } = boardRoot();
|
|
40
49
|
const { config } = createRepoOS(root);
|
|
41
50
|
if (dryRun) {
|
|
42
51
|
printReport(sweepStaleWorktrees(config, { mode: "full", dryRun: true }), "gc — dry run");
|
|
43
52
|
return;
|
|
44
53
|
}
|
|
45
|
-
|
|
46
|
-
printReport(sweepStaleWorktrees(config, { mode: "full" }), "gc");
|
|
47
|
-
return;
|
|
48
|
-
}
|
|
49
|
-
// Default: do the safe part for real, preview the rest.
|
|
50
|
-
printReport(sweepStaleWorktrees(config, { mode: "integrate-only" }), "gc — candidates + stale metadata");
|
|
51
|
-
const preview = sweepStaleWorktrees(config, { mode: "full", dryRun: true });
|
|
52
|
-
const pendingFeature = preview.removedWorktrees.filter((w) => !w.branch.startsWith("repoos/integrate/"));
|
|
53
|
-
if (pendingFeature.length || preview.keptDirty.length) {
|
|
54
|
-
console.log();
|
|
55
|
-
printReport({ ...preview, removedWorktrees: pendingFeature }, "feature worktrees — run `repoos gc --yes` to apply");
|
|
56
|
-
}
|
|
54
|
+
printReport(sweepStaleWorktrees(config, { mode: "full" }), "gc");
|
|
57
55
|
}
|
package/dist/commands/init.js
CHANGED
|
@@ -1249,7 +1249,7 @@ async function offerAreaVocabulary(root) {
|
|
|
1249
1249
|
if (areas.length === 0)
|
|
1250
1250
|
return;
|
|
1251
1251
|
console.log(c.dim(" Preview targets route a task preview by its area — the picker and"));
|
|
1252
|
-
console.log(c.dim(" the PM prompt offer target areas automatically; see
|
|
1252
|
+
console.log(c.dim(" the PM prompt offer target areas automatically; see https://docs.repoos.org/configuration (Previews)."));
|
|
1253
1253
|
const previewStub = await confirm(" Scaffold commented preview-target stubs for these areas?", false);
|
|
1254
1254
|
// Do not clobber a config changed while the prompt was open.
|
|
1255
1255
|
if (readFileSync(tomlPath, "utf8") !== original) {
|
|
@@ -1706,7 +1706,7 @@ async function guidedNewRepo(opts) {
|
|
|
1706
1706
|
}
|
|
1707
1707
|
if (areas.length) {
|
|
1708
1708
|
console.log(c.dim(" Preview targets route a task preview by its area — the picker and"));
|
|
1709
|
-
console.log(c.dim(" the PM prompt offer target areas automatically; see
|
|
1709
|
+
console.log(c.dim(" the PM prompt offer target areas automatically; see https://docs.repoos.org/configuration (Previews)."));
|
|
1710
1710
|
}
|
|
1711
1711
|
// Preview targets reinforce areas ("define them together"): when an area
|
|
1712
1712
|
// vocabulary was given, offer to scaffold the commented `[[preview.targets]]`
|
|
@@ -99,20 +99,49 @@ export interface StatusSnapshot {
|
|
|
99
99
|
active: StatusActiveTask[];
|
|
100
100
|
};
|
|
101
101
|
worktrees: {
|
|
102
|
-
/** Registered worktrees including the main checkout. */
|
|
102
|
+
/** Registered worktrees including the main checkout and external ones. */
|
|
103
103
|
count: number;
|
|
104
|
+
/** Registered worktrees RepoOS manages (excludes external ones). */
|
|
105
|
+
managedCount: number;
|
|
104
106
|
warnThreshold: number;
|
|
105
107
|
/** What `repoos gc --dry-run` would collect (same sweep, same inputs). */
|
|
106
|
-
|
|
108
|
+
candidates: Array<{
|
|
107
109
|
branch: string;
|
|
108
110
|
path: string;
|
|
111
|
+
reason: string;
|
|
112
|
+
taskId?: string;
|
|
113
|
+
taskStatus?: string;
|
|
114
|
+
commitsAhead?: number;
|
|
115
|
+
dirtyPaths?: string[];
|
|
116
|
+
ignoredPaths?: string[];
|
|
117
|
+
changedSourcePaths?: string[];
|
|
109
118
|
}>;
|
|
110
119
|
/** What gc would keep, with the reason it is kept. */
|
|
111
|
-
|
|
120
|
+
retained: Array<{
|
|
121
|
+
branch: string;
|
|
122
|
+
path: string;
|
|
123
|
+
reason: string;
|
|
124
|
+
taskId?: string;
|
|
125
|
+
taskStatus?: string;
|
|
126
|
+
commitsAhead?: number;
|
|
127
|
+
dirtyPaths?: string[];
|
|
128
|
+
ignoredPaths?: string[];
|
|
129
|
+
changedSourcePaths?: string[];
|
|
130
|
+
}>;
|
|
131
|
+
/** Registered worktrees outside RepoOS's managed directory (never touched). */
|
|
132
|
+
external: Array<{
|
|
112
133
|
branch: string;
|
|
113
134
|
path: string;
|
|
114
135
|
reason: string;
|
|
115
136
|
}>;
|
|
137
|
+
/** Why a sweep could not proceed, e.g. unreadable lifecycle state. */
|
|
138
|
+
errors: string[];
|
|
139
|
+
/** Counts mirror `gc --dry-run`, so the two views agree by construction. */
|
|
140
|
+
counts: {
|
|
141
|
+
candidates: number;
|
|
142
|
+
retained: number;
|
|
143
|
+
external: number;
|
|
144
|
+
};
|
|
116
145
|
};
|
|
117
146
|
tunnel: {
|
|
118
147
|
configured: boolean;
|