@repo-os/repoos 0.5.45
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/LICENSE.md +110 -0
- package/README.md +272 -0
- package/dist/.build-info.json +4 -0
- package/dist/.build-stamp.json +3 -0
- package/dist/cli/colors.d.ts +13 -0
- package/dist/cli/colors.js +37 -0
- package/dist/cli/index.d.ts +2 -0
- package/dist/cli/index.js +221 -0
- package/dist/commands/check.d.ts +170 -0
- package/dist/commands/check.js +1227 -0
- package/dist/commands/docs.d.ts +2 -0
- package/dist/commands/docs.js +70 -0
- package/dist/commands/gc.d.ts +1 -0
- package/dist/commands/gc.js +57 -0
- package/dist/commands/init.d.ts +9 -0
- package/dist/commands/init.js +699 -0
- package/dist/commands/screenshots.d.ts +7 -0
- package/dist/commands/screenshots.js +77 -0
- package/dist/commands/serve.d.ts +55 -0
- package/dist/commands/serve.js +204 -0
- package/dist/commands/status.d.ts +140 -0
- package/dist/commands/status.js +569 -0
- package/dist/commands/stop.d.ts +1 -0
- package/dist/commands/stop.js +59 -0
- package/dist/commands/tasks.d.ts +47 -0
- package/dist/commands/tasks.js +334 -0
- package/dist/commands/tunnel.d.ts +1 -0
- package/dist/commands/tunnel.js +1271 -0
- package/dist/commands/ui-harness.d.ts +53 -0
- package/dist/commands/ui-harness.js +62 -0
- package/dist/commands/ui-smoke.d.ts +6 -0
- package/dist/commands/ui-smoke.js +220 -0
- package/dist/commands/upgrade.d.ts +15 -0
- package/dist/commands/upgrade.js +188 -0
- package/dist/core/auth-store.d.ts +81 -0
- package/dist/core/auth-store.js +530 -0
- package/dist/core/auth.d.ts +75 -0
- package/dist/core/auth.js +124 -0
- package/dist/core/bootstrap.d.ts +41 -0
- package/dist/core/bootstrap.js +236 -0
- package/dist/core/build.d.ts +92 -0
- package/dist/core/build.js +249 -0
- package/dist/core/canary.d.ts +10 -0
- package/dist/core/canary.js +14 -0
- package/dist/core/check-failure-summary.d.ts +10 -0
- package/dist/core/check-failure-summary.js +34 -0
- package/dist/core/config.d.ts +160 -0
- package/dist/core/config.js +1288 -0
- package/dist/core/context-pack.d.ts +74 -0
- package/dist/core/context-pack.js +778 -0
- package/dist/core/db.d.ts +236 -0
- package/dist/core/db.js +747 -0
- package/dist/core/detect.d.ts +69 -0
- package/dist/core/detect.js +251 -0
- package/dist/core/docs.d.ts +76 -0
- package/dist/core/docs.js +225 -0
- package/dist/core/frontmatter.d.ts +29 -0
- package/dist/core/frontmatter.js +215 -0
- package/dist/core/git.d.ts +505 -0
- package/dist/core/git.js +1453 -0
- package/dist/core/indexer.d.ts +33 -0
- package/dist/core/indexer.js +282 -0
- package/dist/core/input.d.ts +66 -0
- package/dist/core/input.js +222 -0
- package/dist/core/logger.d.ts +70 -0
- package/dist/core/logger.js +138 -0
- package/dist/core/models.d.ts +45 -0
- package/dist/core/models.js +291 -0
- package/dist/core/net-probe.d.ts +4 -0
- package/dist/core/net-probe.js +20 -0
- package/dist/core/providers/deepinfra.d.ts +23 -0
- package/dist/core/providers/deepinfra.js +44 -0
- package/dist/core/providers/index.d.ts +24 -0
- package/dist/core/providers/index.js +59 -0
- package/dist/core/providers/openrouter.d.ts +28 -0
- package/dist/core/providers/openrouter.js +82 -0
- package/dist/core/providers/spend.d.ts +86 -0
- package/dist/core/providers/spend.js +286 -0
- package/dist/core/providers/types.d.ts +56 -0
- package/dist/core/providers/types.js +39 -0
- package/dist/core/repoos.d.ts +59 -0
- package/dist/core/repoos.js +221 -0
- package/dist/core/runtime.d.ts +35 -0
- package/dist/core/runtime.js +167 -0
- package/dist/core/skills-registry.d.ts +39 -0
- package/dist/core/skills-registry.js +148 -0
- package/dist/core/skills-registry.test.d.ts +1 -0
- package/dist/core/skills-registry.test.js +52 -0
- package/dist/core/sysmem.d.ts +7 -0
- package/dist/core/sysmem.js +55 -0
- package/dist/core/tailscale.d.ts +2 -0
- package/dist/core/tailscale.js +19 -0
- package/dist/core/task.d.ts +53 -0
- package/dist/core/task.js +310 -0
- package/dist/core/toml-line.d.ts +20 -0
- package/dist/core/toml-line.js +52 -0
- package/dist/core/toml-validate.d.ts +44 -0
- package/dist/core/toml-validate.js +335 -0
- package/dist/core/tunnel-assistant.d.ts +30 -0
- package/dist/core/tunnel-assistant.js +65 -0
- package/dist/core/tunnel-registry.d.ts +96 -0
- package/dist/core/tunnel-registry.js +267 -0
- package/dist/core/tunnel-registry.test.d.ts +1 -0
- package/dist/core/tunnel-registry.test.js +309 -0
- package/dist/core/tunnel.d.ts +103 -0
- package/dist/core/tunnel.js +320 -0
- package/dist/core/types.d.ts +811 -0
- package/dist/core/types.js +27 -0
- package/dist/core/worktree-gc.d.ts +57 -0
- package/dist/core/worktree-gc.js +194 -0
- package/dist/server/__tests__/integration-job.test.d.ts +1 -0
- package/dist/server/__tests__/integration-job.test.js +129 -0
- package/dist/server/agents.d.ts +1020 -0
- package/dist/server/agents.js +4070 -0
- package/dist/server/attachments.d.ts +51 -0
- package/dist/server/attachments.js +130 -0
- package/dist/server/auto-engineering.d.ts +45 -0
- package/dist/server/auto-engineering.js +275 -0
- package/dist/server/branchless-release.d.ts +22 -0
- package/dist/server/branchless-release.js +67 -0
- package/dist/server/built-in-agents.d.ts +305 -0
- package/dist/server/built-in-agents.js +1838 -0
- package/dist/server/cto-monitor.d.ts +35 -0
- package/dist/server/cto-monitor.js +281 -0
- package/dist/server/cto.d.ts +125 -0
- package/dist/server/cto.js +590 -0
- package/dist/server/deployments.d.ts +119 -0
- package/dist/server/deployments.js +325 -0
- package/dist/server/diff-snapshot.d.ts +20 -0
- package/dist/server/diff-snapshot.js +73 -0
- package/dist/server/done.d.ts +160 -0
- package/dist/server/done.js +488 -0
- package/dist/server/freeform.d.ts +55 -0
- package/dist/server/freeform.js +179 -0
- package/dist/server/handoff.d.ts +99 -0
- package/dist/server/handoff.js +575 -0
- package/dist/server/hetzner.d.ts +45 -0
- package/dist/server/hetzner.js +117 -0
- package/dist/server/icons.d.ts +8 -0
- package/dist/server/icons.js +195 -0
- package/dist/server/integration-job.d.ts +75 -0
- package/dist/server/integration-job.js +144 -0
- package/dist/server/integration-orchestrator.d.ts +211 -0
- package/dist/server/integration-orchestrator.js +1299 -0
- package/dist/server/integration-status.d.ts +48 -0
- package/dist/server/integration-status.js +71 -0
- package/dist/server/live-index.d.ts +295 -0
- package/dist/server/live-index.js +452 -0
- package/dist/server/model-test.d.ts +20 -0
- package/dist/server/model-test.js +100 -0
- package/dist/server/ntfy.d.ts +57 -0
- package/dist/server/ntfy.js +112 -0
- package/dist/server/pm-attachments.d.ts +35 -0
- package/dist/server/pm-attachments.js +181 -0
- package/dist/server/pm-runs.d.ts +58 -0
- package/dist/server/pm-runs.js +80 -0
- package/dist/server/preview.d.ts +174 -0
- package/dist/server/preview.js +641 -0
- package/dist/server/release.d.ts +88 -0
- package/dist/server/release.js +449 -0
- package/dist/server/reload.d.ts +194 -0
- package/dist/server/reload.js +586 -0
- package/dist/server/remote-validation.d.ts +132 -0
- package/dist/server/remote-validation.js +478 -0
- package/dist/server/repo-lock.d.ts +36 -0
- package/dist/server/repo-lock.js +141 -0
- package/dist/server/review-guard.d.ts +14 -0
- package/dist/server/review-guard.js +159 -0
- package/dist/server/review.d.ts +243 -0
- package/dist/server/review.js +1211 -0
- package/dist/server/routes/agents.d.ts +6 -0
- package/dist/server/routes/agents.js +28 -0
- package/dist/server/routes/auth.d.ts +60 -0
- package/dist/server/routes/auth.js +755 -0
- package/dist/server/routes/config.d.ts +20 -0
- package/dist/server/routes/config.js +347 -0
- package/dist/server/routes/debugger.d.ts +33 -0
- package/dist/server/routes/debugger.js +360 -0
- package/dist/server/routes/deployments.d.ts +3 -0
- package/dist/server/routes/deployments.js +16 -0
- package/dist/server/routes/docs.d.ts +8 -0
- package/dist/server/routes/docs.js +135 -0
- package/dist/server/routes/helpers.d.ts +21 -0
- package/dist/server/routes/helpers.js +171 -0
- package/dist/server/routes/index.d.ts +19 -0
- package/dist/server/routes/index.js +18 -0
- package/dist/server/routes/info.d.ts +17 -0
- package/dist/server/routes/info.js +177 -0
- package/dist/server/routes/inputs.d.ts +7 -0
- package/dist/server/routes/inputs.js +125 -0
- package/dist/server/routes/model-providers.d.ts +27 -0
- package/dist/server/routes/model-providers.js +94 -0
- package/dist/server/routes/models.d.ts +3 -0
- package/dist/server/routes/models.js +36 -0
- package/dist/server/routes/notify.d.ts +2 -0
- package/dist/server/routes/notify.js +17 -0
- package/dist/server/routes/playground.d.ts +29 -0
- package/dist/server/routes/playground.js +81 -0
- package/dist/server/routes/release.d.ts +20 -0
- package/dist/server/routes/release.js +86 -0
- package/dist/server/routes/router.d.ts +12 -0
- package/dist/server/routes/router.js +32 -0
- package/dist/server/routes/skill-registry.d.ts +5 -0
- package/dist/server/routes/skill-registry.js +51 -0
- package/dist/server/routes/tasks.d.ts +58 -0
- package/dist/server/routes/tasks.js +1442 -0
- package/dist/server/routes/transcribe.d.ts +2 -0
- package/dist/server/routes/transcribe.js +124 -0
- package/dist/server/routes/types.d.ts +68 -0
- package/dist/server/routes/types.js +1 -0
- package/dist/server/routes/ui.d.ts +5 -0
- package/dist/server/routes/ui.js +81 -0
- package/dist/server/routes/utils.d.ts +3 -0
- package/dist/server/routes/utils.js +23 -0
- package/dist/server/serve-reaper.d.ts +135 -0
- package/dist/server/serve-reaper.js +491 -0
- package/dist/server/server.d.ts +49 -0
- package/dist/server/server.js +2171 -0
- package/dist/server/supervisor.d.ts +89 -0
- package/dist/server/supervisor.js +231 -0
- package/dist/server/system.d.ts +198 -0
- package/dist/server/system.js +480 -0
- package/dist/server/task-check.d.ts +45 -0
- package/dist/server/task-check.js +71 -0
- package/dist/server/task-transitions.d.ts +51 -0
- package/dist/server/task-transitions.js +78 -0
- package/dist/server/task-watchdog.d.ts +158 -0
- package/dist/server/task-watchdog.js +681 -0
- package/dist/server/test-run.d.ts +28 -0
- package/dist/server/test-run.js +81 -0
- package/dist/server/watcher.d.ts +21 -0
- package/dist/server/watcher.js +194 -0
- package/dist/server/write.d.ts +94 -0
- package/dist/server/write.js +345 -0
- package/dist/ui/assets/AgentsView-CF4wRvHh.css +1 -0
- package/dist/ui/assets/AgentsView-D-myL-kA.js +1 -0
- package/dist/ui/assets/ContextView-D3TC-RSp.css +1 -0
- package/dist/ui/assets/ContextView-DsOqAdyE.js +4 -0
- package/dist/ui/assets/DashboardView-BOhsIJqO.js +1 -0
- package/dist/ui/assets/DashboardView-Ck9o0RP2.css +1 -0
- package/dist/ui/assets/DeploymentsView--iIUVfEH.css +1 -0
- package/dist/ui/assets/DeploymentsView-DXu_FYR2.js +1 -0
- package/dist/ui/assets/InputsView-24HVbVPk.js +1 -0
- package/dist/ui/assets/InputsView-BLb7GHtx.css +1 -0
- package/dist/ui/assets/LoginView-6QlGg6cx.css +1 -0
- package/dist/ui/assets/LoginView-BqupI0Lt.js +1 -0
- package/dist/ui/assets/ReleasesView-BEG1A0YH.css +1 -0
- package/dist/ui/assets/ReleasesView-CAgMuxpe.js +3 -0
- package/dist/ui/assets/SettingsView-CA-NYSMK.css +1 -0
- package/dist/ui/assets/SettingsView-O3iZSnjg.js +3 -0
- package/dist/ui/assets/WorkView-D8Tl6qwy.js +1 -0
- package/dist/ui/assets/WorkView-DMYL2s3W.css +1 -0
- package/dist/ui/assets/abnfDiagram-VCTEODGH-J5lkSnEE.js +1 -0
- package/dist/ui/assets/arc-BHZnmhhM.js +1 -0
- package/dist/ui/assets/architecture-7GRP2DOG-pLdFt-xS.js +1 -0
- package/dist/ui/assets/architectureDiagram-5GKGNRK7-C3k89uKX.js +36 -0
- package/dist/ui/assets/array-BifhSqXX.js +1 -0
- package/dist/ui/assets/blockDiagram-I7D4REHJ-AWNoBzop.js +129 -0
- package/dist/ui/assets/button-lbikqSph.js +1 -0
- package/dist/ui/assets/c4Diagram-7LVT6UL2-DKG1D5gd.js +38 -0
- package/dist/ui/assets/channel-gA4qBv3A.js +1 -0
- package/dist/ui/assets/chunk-2Q5K7J3B-C1jixKkw.js +1 -0
- package/dist/ui/assets/chunk-4HAMMTFA-D1YR8lF_.js +62 -0
- package/dist/ui/assets/chunk-5VM5RSS4-ZNzvKenW.js +15 -0
- package/dist/ui/assets/chunk-75Z2AOVW-5GuBxfsL.js +2 -0
- package/dist/ui/assets/chunk-DU6HZSFF-DfdNNqwa.js +127 -0
- package/dist/ui/assets/chunk-F27PBJKO-BPZzinQ4.js +1 -0
- package/dist/ui/assets/chunk-FOHPRMQF-l2z4K2jD.js +161 -0
- package/dist/ui/assets/chunk-GMAD6QVW-DGWvSKj5.js +72 -0
- package/dist/ui/assets/chunk-GVQU2GXP-D6Aw75wJ.js +1 -0
- package/dist/ui/assets/chunk-IMKFNOWR-B8mMBKCW.js +231 -0
- package/dist/ui/assets/chunk-JWPE2WC7-DVXcaiue.js +1 -0
- package/dist/ui/assets/chunk-L3NEJ4N5-D5OJuXYE.js +1 -0
- package/dist/ui/assets/chunk-OSK3NFVY-B7r9w2UW.js +10 -0
- package/dist/ui/assets/chunk-P2QGCYS3-C74X4AQX.js +1 -0
- package/dist/ui/assets/chunk-POPQ4Y6H-C5_u1gUS.js +1 -0
- package/dist/ui/assets/chunk-PWAF6VOD-DfoTLtxn.js +1 -0
- package/dist/ui/assets/chunk-SHT3W25Y-D40m2eqz.js +168 -0
- package/dist/ui/assets/chunk-SVP7TREG-euxi0Kap.js +88 -0
- package/dist/ui/assets/chunk-TICWLB2K-fkdxngzN.js +206 -0
- package/dist/ui/assets/chunk-XXDRQBXY-DFBUG-OT.js +1 -0
- package/dist/ui/assets/chunk-Y2CYZVJY-DsF7k-Jl.js +1 -0
- package/dist/ui/assets/classDiagram-ZZMXUADV-BzW8bq2P.js +1 -0
- package/dist/ui/assets/classDiagram-v2-VYDZK3BY-BzW8bq2P.js +1 -0
- package/dist/ui/assets/cose-bilkent-JH36ORCC-BTcgMon1.js +1 -0
- package/dist/ui/assets/cynefin-OW5HDTMX-B5m_COsS.js +1 -0
- package/dist/ui/assets/cynefinDiagram-5FMLGOSQ-C-AG6CGe.js +62 -0
- package/dist/ui/assets/cytoscape.esm-FBntH-9t.js +321 -0
- package/dist/ui/assets/dagre-GXQ25YYZ-DDfDnp8L.js +4 -0
- package/dist/ui/assets/dagre-PrKaheQc.js +1 -0
- package/dist/ui/assets/defaultLocale-BFoDCU3G.js +1 -0
- package/dist/ui/assets/diagram-S7CK7UJ4-DjQZAlEY.js +30 -0
- package/dist/ui/assets/diagram-UQ7AKVKN-DAZ9yp1B.js +41 -0
- package/dist/ui/assets/diagram-VSXAHHWV-BWepUKJD.js +3 -0
- package/dist/ui/assets/diagram-VX7I27RA-EcV1J81b.js +24 -0
- package/dist/ui/assets/diagram-Z3DM3KII-Dbz7XU_K.js +24 -0
- package/dist/ui/assets/dist-DTg6UBE_.js +1 -0
- package/dist/ui/assets/ebnfDiagram-PWID7BFC-BUyQw8Mm.js +1 -0
- package/dist/ui/assets/erDiagram-RLTQ6QDP-WVf8ukKt.js +99 -0
- package/dist/ui/assets/eventmodeling-NTZA5JFV-DHqyLOAn.js +1 -0
- package/dist/ui/assets/flowDiagram-HODETNUW-CYk_ze5K.js +1 -0
- package/dist/ui/assets/ganttDiagram-EL5Y4UJY-rB4MZuB-.js +292 -0
- package/dist/ui/assets/gitGraph-4MIJSDKK-BOTWM8dY.js +1 -0
- package/dist/ui/assets/gitGraphDiagram-WWUBYQGX-eYscuhtP.js +106 -0
- package/dist/ui/assets/graphlib-DS17s2tU.js +1 -0
- package/dist/ui/assets/index-BACBfnga.css +1 -0
- package/dist/ui/assets/index-BOQ-ust6.js +26 -0
- package/dist/ui/assets/info-A6RAGUB7-_67wOORe.js +1 -0
- package/dist/ui/assets/infoDiagram-27XIBGKW-XVXbddTA.js +2 -0
- package/dist/ui/assets/init-C-OQMol4.js +1 -0
- package/dist/ui/assets/ishikawaDiagram-5VMMS53U-ClLNiEru.js +70 -0
- package/dist/ui/assets/journeyDiagram-3NMN7TZE-NRawjR6i.js +139 -0
- package/dist/ui/assets/kanban-definition-UXKFOSKX-BgSzBfIx.js +89 -0
- package/dist/ui/assets/katex-DolUETbr.js +257 -0
- package/dist/ui/assets/line-KAyfuul4.js +1 -0
- package/dist/ui/assets/linear-cCCPOpu7.js +1 -0
- package/dist/ui/assets/mermaid-parser.core-CgXZk1iN.js +7 -0
- package/dist/ui/assets/mermaid.core-BUUkChHW.js +44 -0
- package/dist/ui/assets/mindmap-definition-YA3MSWOX-Cpn7vW4r.js +96 -0
- package/dist/ui/assets/ordinal-BDEzSJ7C.js +1 -0
- package/dist/ui/assets/packet-AYTQ26CC-0lZwM-d6.js +1 -0
- package/dist/ui/assets/path-COt_16Va.js +1 -0
- package/dist/ui/assets/pegDiagram-XKGWAZYB-impy0inn.js +1 -0
- package/dist/ui/assets/pie-WAS4IAKB-CqfdGHYg.js +1 -0
- package/dist/ui/assets/pieDiagram-E7YTZNPT-CxjL4I1h.js +39 -0
- package/dist/ui/assets/quadrantDiagram-AXDQQJYC-Cjd1QMIe.js +7 -0
- package/dist/ui/assets/radar-RG4KPBEZ-CRkQIwiv.js +1 -0
- package/dist/ui/assets/railroad-74A4TZTK-i67XSWTB.js +1 -0
- package/dist/ui/assets/railroad-abnf-HS5TGJTU-Cv9m5aS3.js +1 -0
- package/dist/ui/assets/railroad-ebnf-LZEXJU2U-C5ZIn-Jh.js +1 -0
- package/dist/ui/assets/railroad-peg-WCYAUIDC-CGra9Oq-.js +1 -0
- package/dist/ui/assets/railroadDiagram-O6MQD6OU-_pK0qyaY.js +1 -0
- package/dist/ui/assets/releases-B0WNV-SY.js +1 -0
- package/dist/ui/assets/repoos-cto-square.webp +0 -0
- package/dist/ui/assets/repoos-helpful-pm-square.webp +0 -0
- package/dist/ui/assets/repoos-orchestrator-square.webp +0 -0
- package/dist/ui/assets/repoos-performance-agent-square.webp +0 -0
- package/dist/ui/assets/repoos-ross-from-friends-square.webp +0 -0
- package/dist/ui/assets/repoos-tech-debt-agent-square.webp +0 -0
- package/dist/ui/assets/requirementDiagram-BXWQKSXE-CRrFX-yw.js +84 -0
- package/dist/ui/assets/rough.esm-By172zw-.js +1 -0
- package/dist/ui/assets/sankeyDiagram-P5KCCOFB-X_xFRj9E.js +40 -0
- package/dist/ui/assets/sequenceDiagram-WJ2MYXX4-Byb49lKf.js +162 -0
- package/dist/ui/assets/sizeCapture-INFHLROL-B0uUizjq.js +1 -0
- package/dist/ui/assets/src-BH-TyZbA.js +1 -0
- package/dist/ui/assets/stateDiagram-D77RDMKH-CzaPrqYF.js +1 -0
- package/dist/ui/assets/stateDiagram-v2-MP3YSRHH-BCXckz7K.js +1 -0
- package/dist/ui/assets/swimlanes-42K2YHIH-Cx_1lnqr.js +1 -0
- package/dist/ui/assets/swimlanesDiagram-VR7AAH4N-54qsKi6A.js +8 -0
- package/dist/ui/assets/timeline-definition-24CTP7MA-B1IbZPQ-.js +120 -0
- package/dist/ui/assets/treeView-Q6P3EWNA-DFWhVE3d.js +1 -0
- package/dist/ui/assets/treemap-WGGIJYW6-BmbYPThn.js +1 -0
- package/dist/ui/assets/vendor-ui-DPm7zLxi.js +3 -0
- package/dist/ui/assets/vendor-vue-CobgyEJp.js +1 -0
- package/dist/ui/assets/vennDiagram-4TSXK5OY-Ae2AtRpt.js +34 -0
- package/dist/ui/assets/wardley-WFR3VGLG-BtD4X4tL.js +1 -0
- package/dist/ui/assets/wardleyDiagram-VM6X3IG4-B3YN2fTd.js +78 -0
- package/dist/ui/assets/xychartDiagram-S5SC5T6Z-CIzJfMKA.js +7 -0
- package/dist/ui/favicon.svg +11 -0
- package/dist/ui/index.html +49 -0
- package/dist/ui/sw.js +48 -0
- package/package.json +91 -0
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
export declare const SHOTS_DIR = "screenshots";
|
|
2
|
+
export declare const HASH_FILE: string;
|
|
3
|
+
export declare const SCREENSHOT_NAMES: readonly ["dashboard.png", "work-board.png", "task-drawer.png", "docs-context.png", "settings.png"];
|
|
4
|
+
/** Hash of everything that determines the committed screenshots. */
|
|
5
|
+
export declare function screenshotsHash(root: string): string | null;
|
|
6
|
+
/** True when committed screenshots do not match the current UI source. */
|
|
7
|
+
export declare function screenshotsStale(root: string): boolean;
|
|
@@ -0,0 +1,77 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Screenshot freshness guard — shared between `repoos check` and
|
|
3
|
+
* `scripts/capture-screenshots.mjs`.
|
|
4
|
+
*
|
|
5
|
+
* The committed PNGs under `screenshots/` are generated by the capture script
|
|
6
|
+
* against a controlled fixture repo. This module defines what "fresh" means:
|
|
7
|
+
* a sha256 over the UI source tree, the fixture repo, the capture script, AND
|
|
8
|
+
* the committed PNGs themselves, compared against the marker the generator
|
|
9
|
+
* writes to `screenshots/.ui-hash`. Any drift fails the `repoos check` gate so
|
|
10
|
+
* the screenshots cannot silently rot.
|
|
11
|
+
*/
|
|
12
|
+
import { createHash } from "node:crypto";
|
|
13
|
+
import { existsSync, readFileSync, readdirSync, statSync } from "node:fs";
|
|
14
|
+
import { join } from "node:path";
|
|
15
|
+
export const SHOTS_DIR = "screenshots";
|
|
16
|
+
export const HASH_FILE = join(SHOTS_DIR, ".ui-hash");
|
|
17
|
+
export const SCREENSHOT_NAMES = [
|
|
18
|
+
"dashboard.png",
|
|
19
|
+
"work-board.png",
|
|
20
|
+
"task-drawer.png",
|
|
21
|
+
"docs-context.png",
|
|
22
|
+
"settings.png",
|
|
23
|
+
];
|
|
24
|
+
/** Relative paths (sorted) that feed the freshness hash. */
|
|
25
|
+
function uiSources(root) {
|
|
26
|
+
const dirs = ["src/ui-app", "scripts/screenshot-fixtures"];
|
|
27
|
+
const extraFiles = [
|
|
28
|
+
"scripts/capture-screenshots.mjs",
|
|
29
|
+
...SCREENSHOT_NAMES.map((n) => join(SHOTS_DIR, n)),
|
|
30
|
+
];
|
|
31
|
+
const out = [];
|
|
32
|
+
const walk = (dir) => {
|
|
33
|
+
for (const e of readdirSync(dir, { withFileTypes: true })) {
|
|
34
|
+
const p = join(dir, e.name);
|
|
35
|
+
if (e.isDirectory()) {
|
|
36
|
+
if (e.name === "node_modules" || e.name === "dist")
|
|
37
|
+
continue;
|
|
38
|
+
walk(p);
|
|
39
|
+
}
|
|
40
|
+
else {
|
|
41
|
+
out.push(p);
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
};
|
|
45
|
+
for (const d of dirs) {
|
|
46
|
+
if (existsSync(join(root, d)))
|
|
47
|
+
walk(join(root, d));
|
|
48
|
+
}
|
|
49
|
+
for (const f of extraFiles) {
|
|
50
|
+
if (existsSync(join(root, f)))
|
|
51
|
+
out.push(join(root, f));
|
|
52
|
+
}
|
|
53
|
+
return out.sort();
|
|
54
|
+
}
|
|
55
|
+
/** Hash of everything that determines the committed screenshots. */
|
|
56
|
+
export function screenshotsHash(root) {
|
|
57
|
+
if (!existsSync(join(root, "src/ui-app")))
|
|
58
|
+
return null;
|
|
59
|
+
const hash = createHash("sha256");
|
|
60
|
+
for (const f of uiSources(root)) {
|
|
61
|
+
if (!statSync(f).isFile())
|
|
62
|
+
continue;
|
|
63
|
+
hash.update(f.slice(root.length + 1));
|
|
64
|
+
hash.update("\u0000");
|
|
65
|
+
hash.update(readFileSync(f));
|
|
66
|
+
}
|
|
67
|
+
return hash.digest("hex");
|
|
68
|
+
}
|
|
69
|
+
/** True when committed screenshots do not match the current UI source. */
|
|
70
|
+
export function screenshotsStale(root) {
|
|
71
|
+
const marker = join(root, HASH_FILE);
|
|
72
|
+
if (!existsSync(marker))
|
|
73
|
+
return true;
|
|
74
|
+
const recorded = readFileSync(marker, "utf8").trim();
|
|
75
|
+
const current = screenshotsHash(root);
|
|
76
|
+
return current === null || recorded !== current;
|
|
77
|
+
}
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The OS-visible process title for a `repoos serve` instance:
|
|
3
|
+
* `repoos-<project>`, where `<project>` is the managed root's directory name.
|
|
4
|
+
* This is the same display name the rest of RepoOS uses (`basename(root)` — the
|
|
5
|
+
* PWA manifest, login emails, the instance icon), so `ps`/Activity Monitor can
|
|
6
|
+
* tell which project an instance belongs to without `lsof`/`/api/config`.
|
|
7
|
+
*/
|
|
8
|
+
export declare function serveProcessTitle(root?: string): string;
|
|
9
|
+
type ExecveFn = (file: string, args: readonly string[], env: NodeJS.ProcessEnv) => never;
|
|
10
|
+
/**
|
|
11
|
+
* Set the OS-visible process title so `ps`/Activity Monitor name the project.
|
|
12
|
+
*
|
|
13
|
+
* Node's `process.title` writes through to the OS directly, but Bun's does NOT
|
|
14
|
+
* (verified on 1.3.x/macOS: the JS property sticks but the kernel argv is
|
|
15
|
+
* untouched, so `ps` still shows `bun … serve`). The mechanism that does work
|
|
16
|
+
* under Bun is `process.execve` — a true exec (same PID, same cwd, same stdio)
|
|
17
|
+
* with a custom argv[0] — so we re-exec once, guarded by {@link TITLE_GUARD}.
|
|
18
|
+
* On the relabeled second pass the marker is deleted immediately, before any
|
|
19
|
+
* child is spawned, so reload replacements and preview children start clean and
|
|
20
|
+
* relabel themselves instead of inheriting a stale "already titled" flag.
|
|
21
|
+
*
|
|
22
|
+
* `execve` is injectable purely so tests can observe the call without replacing
|
|
23
|
+
* the test runner's own process image.
|
|
24
|
+
*/
|
|
25
|
+
export declare function setServeProcessTitle(title: string, execve?: ExecveFn | undefined): void;
|
|
26
|
+
/**
|
|
27
|
+
* Picks the bind host: an explicit `--host` always wins; otherwise, if
|
|
28
|
+
* Tailscale is running on this machine, default to 0.0.0.0 (all interfaces)
|
|
29
|
+
* so the server is reachable both from other Tailscale devices AND from
|
|
30
|
+
* localhost — binding to the Tailscale IP alone would leave nothing
|
|
31
|
+
* listening on 127.0.0.1, silently breaking anything on this same machine
|
|
32
|
+
* that assumes localhost reachability (Cloudflare Tunnel's local origin,
|
|
33
|
+
* RepoOS's own tunnel readiness check, etc.). Falls back to localhost-only
|
|
34
|
+
* when Tailscale isn't detected. `tailscaleIP` is surfaced separately (even
|
|
35
|
+
* though the actual bind is 0.0.0.0) so callers can show the address other
|
|
36
|
+
* tailnet devices should actually use.
|
|
37
|
+
*/
|
|
38
|
+
export declare function resolveServeHost(explicitHost?: string): {
|
|
39
|
+
host: string;
|
|
40
|
+
tailscaleDetected: boolean;
|
|
41
|
+
tailscaleIP?: string;
|
|
42
|
+
};
|
|
43
|
+
/**
|
|
44
|
+
* True when this process is a managed agent (REPOOS_AGENT=1) attempting to
|
|
45
|
+
* launch `repoos serve` directly, as opposed to a preview child or a reload
|
|
46
|
+
* replacement spawned by the main server. The AgentRunner sets REPOOS_AGENT=1
|
|
47
|
+
* on every agent spawn; the preview/reload markers are exempt so RepoOS-owned
|
|
48
|
+
* processes keep working. Exported for the defense-in-depth tests (#0096).
|
|
49
|
+
*/
|
|
50
|
+
export declare function directServeBlockedByAgent(env?: NodeJS.ProcessEnv): boolean;
|
|
51
|
+
export declare function cmdServe(args: string[], opts?: {
|
|
52
|
+
onShutdown?: () => void;
|
|
53
|
+
onReady?: (url: string) => void;
|
|
54
|
+
}): Promise<void>;
|
|
55
|
+
export {};
|
|
@@ -0,0 +1,204 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* `repoos serve` — start the local RepoOS server: in-memory live index, file
|
|
3
|
+
* watcher, JSON API, and SSE event stream. Stays running until interrupted.
|
|
4
|
+
*/
|
|
5
|
+
import { basename } from "node:path";
|
|
6
|
+
import { startServer } from "../server/server.js";
|
|
7
|
+
import { PREVIEW_REQUEST_SIGNAL } from "../server/agents.js";
|
|
8
|
+
import { isBun } from "../core/runtime.js";
|
|
9
|
+
import { findRepoRoot } from "../core/config.js";
|
|
10
|
+
import { c, statusColor } from "../cli/colors.js";
|
|
11
|
+
import { detectTailscaleIPv4 } from "../core/tailscale.js";
|
|
12
|
+
/**
|
|
13
|
+
* The OS-visible process title for a `repoos serve` instance:
|
|
14
|
+
* `repoos-<project>`, where `<project>` is the managed root's directory name.
|
|
15
|
+
* This is the same display name the rest of RepoOS uses (`basename(root)` — the
|
|
16
|
+
* PWA manifest, login emails, the instance icon), so `ps`/Activity Monitor can
|
|
17
|
+
* tell which project an instance belongs to without `lsof`/`/api/config`.
|
|
18
|
+
*/
|
|
19
|
+
export function serveProcessTitle(root = findRepoRoot()) {
|
|
20
|
+
return `repoos-${basename(root) || "repoos"}`;
|
|
21
|
+
}
|
|
22
|
+
/** One-shot marker so the Bun re-exec below can never loop. */
|
|
23
|
+
const TITLE_GUARD = "REPOOS_PROCESS_TITLE";
|
|
24
|
+
/**
|
|
25
|
+
* Set the OS-visible process title so `ps`/Activity Monitor name the project.
|
|
26
|
+
*
|
|
27
|
+
* Node's `process.title` writes through to the OS directly, but Bun's does NOT
|
|
28
|
+
* (verified on 1.3.x/macOS: the JS property sticks but the kernel argv is
|
|
29
|
+
* untouched, so `ps` still shows `bun … serve`). The mechanism that does work
|
|
30
|
+
* under Bun is `process.execve` — a true exec (same PID, same cwd, same stdio)
|
|
31
|
+
* with a custom argv[0] — so we re-exec once, guarded by {@link TITLE_GUARD}.
|
|
32
|
+
* On the relabeled second pass the marker is deleted immediately, before any
|
|
33
|
+
* child is spawned, so reload replacements and preview children start clean and
|
|
34
|
+
* relabel themselves instead of inheriting a stale "already titled" flag.
|
|
35
|
+
*
|
|
36
|
+
* `execve` is injectable purely so tests can observe the call without replacing
|
|
37
|
+
* the test runner's own process image.
|
|
38
|
+
*/
|
|
39
|
+
export function setServeProcessTitle(title, execve = process.execve) {
|
|
40
|
+
process.title = title;
|
|
41
|
+
if (process.env[TITLE_GUARD] === "1") {
|
|
42
|
+
delete process.env[TITLE_GUARD];
|
|
43
|
+
return;
|
|
44
|
+
}
|
|
45
|
+
if (!isBun() || typeof execve !== "function")
|
|
46
|
+
return; // Node's process.title already reached the OS
|
|
47
|
+
const script = process.argv[1];
|
|
48
|
+
if (!script)
|
|
49
|
+
return; // no entry path to hand to the re-exec — stay put
|
|
50
|
+
try {
|
|
51
|
+
execve(process.execPath, [title, script, ...process.argv.slice(2)], {
|
|
52
|
+
...process.env,
|
|
53
|
+
[TITLE_GUARD]: "1",
|
|
54
|
+
});
|
|
55
|
+
}
|
|
56
|
+
catch {
|
|
57
|
+
// execve failed (platform/permission) — the process is intact and
|
|
58
|
+
// process.title above still stands. Never let a display-only nicety stop
|
|
59
|
+
// the server from starting.
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
/**
|
|
63
|
+
* Picks the bind host: an explicit `--host` always wins; otherwise, if
|
|
64
|
+
* Tailscale is running on this machine, default to 0.0.0.0 (all interfaces)
|
|
65
|
+
* so the server is reachable both from other Tailscale devices AND from
|
|
66
|
+
* localhost — binding to the Tailscale IP alone would leave nothing
|
|
67
|
+
* listening on 127.0.0.1, silently breaking anything on this same machine
|
|
68
|
+
* that assumes localhost reachability (Cloudflare Tunnel's local origin,
|
|
69
|
+
* RepoOS's own tunnel readiness check, etc.). Falls back to localhost-only
|
|
70
|
+
* when Tailscale isn't detected. `tailscaleIP` is surfaced separately (even
|
|
71
|
+
* though the actual bind is 0.0.0.0) so callers can show the address other
|
|
72
|
+
* tailnet devices should actually use.
|
|
73
|
+
*/
|
|
74
|
+
export function resolveServeHost(explicitHost) {
|
|
75
|
+
if (explicitHost)
|
|
76
|
+
return { host: explicitHost, tailscaleDetected: false };
|
|
77
|
+
const tailscaleIP = detectTailscaleIPv4();
|
|
78
|
+
if (tailscaleIP)
|
|
79
|
+
return { host: "0.0.0.0", tailscaleDetected: true, tailscaleIP };
|
|
80
|
+
return { host: "127.0.0.1", tailscaleDetected: false };
|
|
81
|
+
}
|
|
82
|
+
/**
|
|
83
|
+
* True when this process is a managed agent (REPOOS_AGENT=1) attempting to
|
|
84
|
+
* launch `repoos serve` directly, as opposed to a preview child or a reload
|
|
85
|
+
* replacement spawned by the main server. The AgentRunner sets REPOOS_AGENT=1
|
|
86
|
+
* on every agent spawn; the preview/reload markers are exempt so RepoOS-owned
|
|
87
|
+
* processes keep working. Exported for the defense-in-depth tests (#0096).
|
|
88
|
+
*/
|
|
89
|
+
export function directServeBlockedByAgent(env = process.env) {
|
|
90
|
+
return env.REPOOS_AGENT === "1" && env.REPOOS_PREVIEW_CHILD !== "1" && env.REPOOS_RELOAD !== "1";
|
|
91
|
+
}
|
|
92
|
+
export async function cmdServe(args, opts = {}) {
|
|
93
|
+
// Defense in depth (#0096): a managed agent process must never start its own
|
|
94
|
+
// `repoos serve`. An agent that ignores the mission and runs `repoos serve`
|
|
95
|
+
// directly is rejected here BEFORE binding, so it can never grab the main
|
|
96
|
+
// server port.
|
|
97
|
+
if (directServeBlockedByAgent()) {
|
|
98
|
+
console.error(c.red(" ✗ Managed agent processes may not launch `repoos serve`."));
|
|
99
|
+
console.error(c.dim(" RepoOS owns previews and the control-plane port. Request a managed preview instead:"));
|
|
100
|
+
console.error(c.dim(` include this exact line in your response: ${PREVIEW_REQUEST_SIGNAL}`));
|
|
101
|
+
console.error(c.dim(" RepoOS starts the preview from your worktree, probes it server-side, and records the URL + result in your transcript."));
|
|
102
|
+
process.exitCode = 1;
|
|
103
|
+
return;
|
|
104
|
+
}
|
|
105
|
+
// Undefined = "no --port flag"; startServer then resolves it from
|
|
106
|
+
// repoos.toml's `servePort` or a stable per-repo derived port. Explicit
|
|
107
|
+
// `--port` still wins.
|
|
108
|
+
let port;
|
|
109
|
+
let explicitHost;
|
|
110
|
+
let quiet = false;
|
|
111
|
+
for (let i = 0; i < args.length; i++) {
|
|
112
|
+
if (args[i] === "--port" || args[i] === "-p")
|
|
113
|
+
port = Number(args[++i]);
|
|
114
|
+
else if (args[i] === "--host")
|
|
115
|
+
explicitHost = args[++i];
|
|
116
|
+
else if (args[i] === "--quiet" || args[i] === "-q")
|
|
117
|
+
quiet = true;
|
|
118
|
+
}
|
|
119
|
+
const { host, tailscaleDetected, tailscaleIP } = resolveServeHost(explicitHost);
|
|
120
|
+
let handle;
|
|
121
|
+
try {
|
|
122
|
+
// REPOOS_RELOAD=1 marks a replacement spawned by the auto-reload manager:
|
|
123
|
+
// it retries EADDRINUSE until the old process hands the port over.
|
|
124
|
+
handle = await startServer({
|
|
125
|
+
port,
|
|
126
|
+
host,
|
|
127
|
+
reloadReplacement: process.env.REPOOS_RELOAD === "1",
|
|
128
|
+
});
|
|
129
|
+
}
|
|
130
|
+
catch (e) {
|
|
131
|
+
const msg = e.message;
|
|
132
|
+
if (msg.includes("EADDRINUSE") ||
|
|
133
|
+
msg.includes("already bound") ||
|
|
134
|
+
msg.includes("already in use")) {
|
|
135
|
+
// The message already names the port (node's EADDRINUSE string or
|
|
136
|
+
// detectConflict's own text).
|
|
137
|
+
console.error(c.red(" " + msg) + c.dim(" · pass --port N to use a different one"));
|
|
138
|
+
}
|
|
139
|
+
else {
|
|
140
|
+
console.error(c.red(" Failed to start server: " + msg));
|
|
141
|
+
}
|
|
142
|
+
process.exitCode = 1;
|
|
143
|
+
return;
|
|
144
|
+
}
|
|
145
|
+
const snap = handle.index.snapshot();
|
|
146
|
+
console.log(c.bold(c.cyan("\n RepoOS server")) + c.dim(" · ") + c.bold(handle.url));
|
|
147
|
+
console.log(c.dim(" open ") + c.cyan(handle.url) + c.dim(" in your browser for the UI"));
|
|
148
|
+
console.log(c.dim(" watching ") +
|
|
149
|
+
snap.taskCount +
|
|
150
|
+
c.dim(" tasks · SSE stream at ") +
|
|
151
|
+
c.cyan(handle.url + "/api/events"));
|
|
152
|
+
const rt = isBun()
|
|
153
|
+
? `Bun ${process.versions.bun ?? ""}`.trim()
|
|
154
|
+
: `Node ${process.versions.node}`;
|
|
155
|
+
console.log(c.dim(" runtime ") + rt);
|
|
156
|
+
console.log(c.dim(" api: ") + c.dim("/api/tasks /api/tasks/:id /api/counts /api/index /api/docs"));
|
|
157
|
+
if (tailscaleDetected) {
|
|
158
|
+
console.log(c.dim(" Tailscale detected — listening on all interfaces (") +
|
|
159
|
+
c.cyan("0.0.0.0") +
|
|
160
|
+
c.dim("), reachable from other Tailscale devices at ") +
|
|
161
|
+
c.cyan(`http://${tailscaleIP}:${handle.port}`) +
|
|
162
|
+
c.dim(". Use ") +
|
|
163
|
+
c.cyan("--host 127.0.0.1") +
|
|
164
|
+
c.dim(" to restrict to localhost only."));
|
|
165
|
+
}
|
|
166
|
+
console.log(c.dim(" press ^C to stop\n"));
|
|
167
|
+
// Fires only now that the server is actually listening (handle.url is a
|
|
168
|
+
// live, bound address) — a caller opening a browser tab any earlier races
|
|
169
|
+
// the server's own startup and shows connection errors until a manual
|
|
170
|
+
// reload.
|
|
171
|
+
opts.onReady?.(handle.url);
|
|
172
|
+
// Live activity log in the terminal, mirroring the SSE stream.
|
|
173
|
+
if (!quiet) {
|
|
174
|
+
handle.index.on((e) => {
|
|
175
|
+
const t = new Date().toTimeString().slice(0, 8);
|
|
176
|
+
const stamp = c.dim(t + " ");
|
|
177
|
+
if (e.type === "task.created")
|
|
178
|
+
console.log(stamp + c.green("created ") + c.dim("#" + e.task.id) + " " + e.task.title);
|
|
179
|
+
else if (e.type === "task.updated") {
|
|
180
|
+
const changed = Object.keys(e.prev).join(", ");
|
|
181
|
+
const statusBit = e.prev.status !== undefined ? " → " + statusColor(e.task.status)(e.task.status) : "";
|
|
182
|
+
console.log(stamp +
|
|
183
|
+
c.cyan("updated ") +
|
|
184
|
+
c.dim("#" + e.task.id) +
|
|
185
|
+
statusBit +
|
|
186
|
+
c.dim(" (" + changed + ")"));
|
|
187
|
+
}
|
|
188
|
+
else if (e.type === "task.deleted")
|
|
189
|
+
console.log(stamp + c.red("deleted ") + c.dim("#" + e.id));
|
|
190
|
+
});
|
|
191
|
+
}
|
|
192
|
+
let shuttingDown = false;
|
|
193
|
+
const shutdown = async (signal) => {
|
|
194
|
+
if (shuttingDown)
|
|
195
|
+
return;
|
|
196
|
+
shuttingDown = true;
|
|
197
|
+
console.log(c.dim(`\n shutting down after ${signal} (pid ${process.pid}, port ${handle.port})…`));
|
|
198
|
+
await handle.close(`received ${signal}`);
|
|
199
|
+
opts.onShutdown?.();
|
|
200
|
+
process.exit(0);
|
|
201
|
+
};
|
|
202
|
+
process.on("SIGINT", () => void shutdown("SIGINT"));
|
|
203
|
+
process.on("SIGTERM", () => void shutdown("SIGTERM"));
|
|
204
|
+
}
|
|
@@ -0,0 +1,140 @@
|
|
|
1
|
+
import { type RepoOSConfig, type Status } from "../core/types.js";
|
|
2
|
+
export interface StatusServer {
|
|
3
|
+
/**
|
|
4
|
+
* True when a serve process for THIS repo is actually reachable: the
|
|
5
|
+
* lockfile's PID is alive AND names a repoos serve process AND its port is
|
|
6
|
+
* answering (or /api/health answers with this repo's root). A lock whose
|
|
7
|
+
* PID was recycled by an unrelated process is NOT running — "running" is
|
|
8
|
+
* grounded in the port, not just in /proc existence.
|
|
9
|
+
*/
|
|
10
|
+
running: boolean;
|
|
11
|
+
/** Port of the primary serve lock (live first, else most recent), else the probed port. */
|
|
12
|
+
port: number | null;
|
|
13
|
+
/** PID recorded in the primary lock — may name a dead process when running is false. */
|
|
14
|
+
pid: number | null;
|
|
15
|
+
host: string | null;
|
|
16
|
+
/** ISO start time — from the lockfile, or /api/health when the lock is thin. */
|
|
17
|
+
startedAt: string | null;
|
|
18
|
+
startedAtSource: "lockfile" | "health" | null;
|
|
19
|
+
uptimeSeconds: number | null;
|
|
20
|
+
/**
|
|
21
|
+
* Result of probing /api/health on the port:
|
|
22
|
+
* "ok" — answered and its root matches this repo
|
|
23
|
+
* "foreign" — something answered, but it serves a different root
|
|
24
|
+
* "unreachable" — nothing answered
|
|
25
|
+
*/
|
|
26
|
+
health: "ok" | "foreign" | "unreachable";
|
|
27
|
+
/** The root the health probe reported (when it answered), for the mismatch note. */
|
|
28
|
+
healthRoot: string | null;
|
|
29
|
+
/** Number of serve lockfiles present (a repo may run more than one port). */
|
|
30
|
+
locks: number;
|
|
31
|
+
}
|
|
32
|
+
export interface StatusBuild {
|
|
33
|
+
/** Same codes as core/build.ts checkBuildForRoot. */
|
|
34
|
+
code: "fresh" | "stale" | "no-marker" | "no-build" | "corrupt" | "dev-mode" | "published";
|
|
35
|
+
stale: boolean;
|
|
36
|
+
/**
|
|
37
|
+
* Whether RepoOS's build-staleness contract applies to this checkout (see
|
|
38
|
+
* BuildCheckResult.applicable in core/build.ts). `stale` stays true for a
|
|
39
|
+
* non-RepoOS-build checkout so build-triggering callers still work — callers
|
|
40
|
+
* that want to know whether this is a real problem, not just a pipeline that
|
|
41
|
+
* doesn't use RepoOS's marker, should check `applicable` too rather than
|
|
42
|
+
* `stale` alone.
|
|
43
|
+
*/
|
|
44
|
+
applicable: boolean;
|
|
45
|
+
message: string | null;
|
|
46
|
+
version: string | null;
|
|
47
|
+
buildAt: string | null;
|
|
48
|
+
}
|
|
49
|
+
export interface StatusActiveTask {
|
|
50
|
+
id: string;
|
|
51
|
+
title: string;
|
|
52
|
+
branch: string;
|
|
53
|
+
worktreePath: string | null;
|
|
54
|
+
/** Branch exists but no usable worktree — the stuck-task signal. */
|
|
55
|
+
worktreeMissing: boolean;
|
|
56
|
+
updatedAt: string | null;
|
|
57
|
+
needsInput: boolean;
|
|
58
|
+
}
|
|
59
|
+
export interface StatusSnapshot {
|
|
60
|
+
generatedAt: string;
|
|
61
|
+
root: string;
|
|
62
|
+
server: StatusServer;
|
|
63
|
+
build: StatusBuild;
|
|
64
|
+
board: {
|
|
65
|
+
taskCount: number;
|
|
66
|
+
counts: Record<Status, number>;
|
|
67
|
+
active: StatusActiveTask[];
|
|
68
|
+
};
|
|
69
|
+
worktrees: {
|
|
70
|
+
/** Registered worktrees including the main checkout. */
|
|
71
|
+
count: number;
|
|
72
|
+
warnThreshold: number;
|
|
73
|
+
/** What `repoos gc --dry-run` would collect (same sweep, same inputs). */
|
|
74
|
+
leaked: Array<{
|
|
75
|
+
branch: string;
|
|
76
|
+
path: string;
|
|
77
|
+
}>;
|
|
78
|
+
/** What gc would keep, with the reason it is kept. */
|
|
79
|
+
kept: Array<{
|
|
80
|
+
branch: string;
|
|
81
|
+
path: string;
|
|
82
|
+
reason: string;
|
|
83
|
+
}>;
|
|
84
|
+
};
|
|
85
|
+
tunnel: {
|
|
86
|
+
configured: boolean;
|
|
87
|
+
tunnelName: string | null;
|
|
88
|
+
running: boolean;
|
|
89
|
+
hostnames: string[];
|
|
90
|
+
};
|
|
91
|
+
git: {
|
|
92
|
+
branch: string | null;
|
|
93
|
+
clean: boolean;
|
|
94
|
+
dirtyFiles: number;
|
|
95
|
+
/** True when the reported branch IS `main`. */
|
|
96
|
+
isMainBranch: boolean;
|
|
97
|
+
/** Commits ahead of / behind `main` (null when branch is main or main is missing). */
|
|
98
|
+
ahead: number | null;
|
|
99
|
+
behind: number | null;
|
|
100
|
+
};
|
|
101
|
+
}
|
|
102
|
+
export interface CollectStatusOptions {
|
|
103
|
+
/** Overrides "now" — for tests. */
|
|
104
|
+
now?: Date;
|
|
105
|
+
/** /api/health fetch timeout in ms (default 800 — a status command must never hang). */
|
|
106
|
+
probeTimeoutMs?: number;
|
|
107
|
+
/** Overrides the probed port (lockfile → default derivation) — for hermetic tests. */
|
|
108
|
+
probePort?: number;
|
|
109
|
+
}
|
|
110
|
+
interface ServeLockEntry {
|
|
111
|
+
file: string;
|
|
112
|
+
pid: number;
|
|
113
|
+
port: number | null;
|
|
114
|
+
host: string | null;
|
|
115
|
+
startedAt: string | null;
|
|
116
|
+
alive: boolean;
|
|
117
|
+
}
|
|
118
|
+
/**
|
|
119
|
+
* Read every `.repoos/serve[-<port>].lock`. Locks are scoped per port (see
|
|
120
|
+
* ServeReaper), so there can legitimately be more than one; they are ordered
|
|
121
|
+
* live-first, then newest-first by `startedAt`, so the primary is the one
|
|
122
|
+
* that matters. Exported for tests.
|
|
123
|
+
*/
|
|
124
|
+
export declare function readServeLocks(root: string, cacheDir: string): ServeLockEntry[];
|
|
125
|
+
/**
|
|
126
|
+
* Build the full snapshot. Everything is fail-soft: a missing lockfile, a dead
|
|
127
|
+
* server, an unreadable marker, or absent git degrade the matching section —
|
|
128
|
+
* never crash the command.
|
|
129
|
+
*/
|
|
130
|
+
export declare function collectStatus(config: RepoOSConfig, opts?: CollectStatusOptions): Promise<StatusSnapshot>;
|
|
131
|
+
/** "42s" | "5m 07s" | "3h 42m" | "2d 4h" */
|
|
132
|
+
export declare function formatUptime(ms: number): string;
|
|
133
|
+
/** Local "14:02" on the same day, else "Sep 2 14:02". */
|
|
134
|
+
export declare function formatSince(iso: string, now: Date): string;
|
|
135
|
+
/** "41s ago" | "5m ago" | "3h 02m ago" | "2d ago" — for last-activity stamps. */
|
|
136
|
+
export declare function formatRel(iso: string | null, now: Date): string;
|
|
137
|
+
export declare function renderStatus(s: StatusSnapshot, now?: Date): void;
|
|
138
|
+
/** `repoos status [--json]` */
|
|
139
|
+
export declare function cmdStatus(argv: string[]): Promise<void>;
|
|
140
|
+
export {};
|