@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,1020 @@
|
|
|
1
|
+
import { type ChildProcess } from "node:child_process";
|
|
2
|
+
import type { Agent, AgentOutputEntry, AgentSessionStats, RepoOSConfig, SkillMeta, Task } from "../core/types.js";
|
|
3
|
+
import type { Logger } from "../core/logger.js";
|
|
4
|
+
import { type UsageRange } from "../core/db.js";
|
|
5
|
+
/** The SSE events the runner emits. Subset of RepoEvent. */
|
|
6
|
+
export type AgentEvent = {
|
|
7
|
+
type: "agent.running";
|
|
8
|
+
id: string;
|
|
9
|
+
at: string;
|
|
10
|
+
} | {
|
|
11
|
+
type: "agent.exited";
|
|
12
|
+
id: string;
|
|
13
|
+
at: string;
|
|
14
|
+
}
|
|
15
|
+
/** A start/send/chat was accepted but held for a free maxConcurrentAgents slot. */
|
|
16
|
+
| {
|
|
17
|
+
type: "agent.queued";
|
|
18
|
+
id: string;
|
|
19
|
+
at: string;
|
|
20
|
+
}
|
|
21
|
+
/** A queued id left the queue — about to spawn (an agent.running follows immediately). */
|
|
22
|
+
| {
|
|
23
|
+
type: "agent.dequeued";
|
|
24
|
+
id: string;
|
|
25
|
+
at: string;
|
|
26
|
+
} | {
|
|
27
|
+
type: "agent.output";
|
|
28
|
+
id: string;
|
|
29
|
+
entry: AgentOutputEntry;
|
|
30
|
+
stream: "out" | "err";
|
|
31
|
+
at: string;
|
|
32
|
+
} | {
|
|
33
|
+
type: "agent.stats";
|
|
34
|
+
id: string;
|
|
35
|
+
stats: AgentSessionStats;
|
|
36
|
+
at: string;
|
|
37
|
+
} | {
|
|
38
|
+
type: "task.corrected";
|
|
39
|
+
id: string;
|
|
40
|
+
path: string;
|
|
41
|
+
note: string;
|
|
42
|
+
at: string;
|
|
43
|
+
};
|
|
44
|
+
export declare const HANDOFF_READY_SIGNAL = "::repoos-handoff-ready::";
|
|
45
|
+
/**
|
|
46
|
+
* The exact line a sandboxed agent emits to request ITS managed preview
|
|
47
|
+
* (#0121). Like the handoff signal, it is an output-only intent: the agent
|
|
48
|
+
* never touches localhost or picks a port — the runner binds it to the live
|
|
49
|
+
* run and the server starts/probes the preview on the agent's behalf.
|
|
50
|
+
*/
|
|
51
|
+
export declare const PREVIEW_REQUEST_SIGNAL = "::repoos-preview-request::";
|
|
52
|
+
/**
|
|
53
|
+
* The transcript marker appended when a user interrupts an in-flight AI chat
|
|
54
|
+
* response. Shared so the runner and the CTO manager (and tests) never drift.
|
|
55
|
+
*/
|
|
56
|
+
export declare const INTERRUPTED_MARKER = "\u2014 response interrupted \u2014";
|
|
57
|
+
/** A capability minted by the runner for one completed agent turn. */
|
|
58
|
+
export interface AgentHandoffRequest {
|
|
59
|
+
taskId: string;
|
|
60
|
+
runId: string;
|
|
61
|
+
branch: string;
|
|
62
|
+
workdir: string;
|
|
63
|
+
sessionId?: string;
|
|
64
|
+
}
|
|
65
|
+
/** A capability minted when a clean turn requested its managed preview (#0121). */
|
|
66
|
+
export interface AgentPreviewRequest {
|
|
67
|
+
taskId: string;
|
|
68
|
+
runId: string;
|
|
69
|
+
branch: string;
|
|
70
|
+
workdir: string;
|
|
71
|
+
sessionId?: string;
|
|
72
|
+
}
|
|
73
|
+
export interface StartResult {
|
|
74
|
+
ok: boolean;
|
|
75
|
+
pid?: number;
|
|
76
|
+
/** True when the request was rejected because a turn is already running. */
|
|
77
|
+
busy?: boolean;
|
|
78
|
+
/** True when accepted but held for a free slot under maxConcurrentAgents — it will spawn once one frees. */
|
|
79
|
+
queued?: boolean;
|
|
80
|
+
reason?: string;
|
|
81
|
+
}
|
|
82
|
+
export interface StopResult {
|
|
83
|
+
stopped: boolean;
|
|
84
|
+
reason?: string;
|
|
85
|
+
}
|
|
86
|
+
export interface RunningAgentInfo {
|
|
87
|
+
id: string;
|
|
88
|
+
pid: number;
|
|
89
|
+
startedAt: string;
|
|
90
|
+
/** Working directory the agent runs in (worktree path, or repo root). */
|
|
91
|
+
workdir?: string;
|
|
92
|
+
}
|
|
93
|
+
/** Line-buffered transcript for one task, retained across turns and pause. */
|
|
94
|
+
interface Session {
|
|
95
|
+
lines: AgentOutputEntry[];
|
|
96
|
+
pending: string;
|
|
97
|
+
bytes: number;
|
|
98
|
+
workdir?: string;
|
|
99
|
+
sessionId?: string;
|
|
100
|
+
task?: Task;
|
|
101
|
+
branch?: string;
|
|
102
|
+
/** Agent name (e.g., "engineer", "reviewer", "Ross"). */
|
|
103
|
+
agent?: string;
|
|
104
|
+
/** Model name (e.g., "big pickle", "default"). */
|
|
105
|
+
model?: string;
|
|
106
|
+
/** Which session engine parses the CLI output into AgentOutputEntry cards. */
|
|
107
|
+
engine: "opencode" | "claude" | "copilot" | "qwen" | "codex" | "kiro" | "plain";
|
|
108
|
+
/** Cumulative ms across completed turns — excludes any turn in flight (0080). */
|
|
109
|
+
accumulatedMs: number;
|
|
110
|
+
/** ISO timestamp when the session was first created (never changes). */
|
|
111
|
+
createdAt?: string;
|
|
112
|
+
/** ISO timestamp the current turn started, or undefined when no turn is running. */
|
|
113
|
+
turnStartedAt?: string;
|
|
114
|
+
/** ISO timestamp of the most recent output line, or undefined until first output. */
|
|
115
|
+
lastOutputAt?: string;
|
|
116
|
+
/** Best-effort cumulative input token count reported by the CLI, or undefined if never reported. */
|
|
117
|
+
inputTokens?: number;
|
|
118
|
+
/** Best-effort cumulative output token count reported by the CLI, or undefined if never reported. */
|
|
119
|
+
outputTokens?: number;
|
|
120
|
+
/** Best-effort cumulative token count reported by the CLI, or undefined if never reported. */
|
|
121
|
+
tokens?: number;
|
|
122
|
+
/** Best-effort cumulative cost (USD) reported by the CLI, or undefined if never reported. */
|
|
123
|
+
costUsd?: number;
|
|
124
|
+
/** Cumulative prompt-cache read tokens, when the CLI reports them (Phase 0). */
|
|
125
|
+
cacheReadTokens?: number;
|
|
126
|
+
/** Cumulative prompt-cache creation tokens, when the CLI reports them. */
|
|
127
|
+
cacheCreationTokens?: number;
|
|
128
|
+
/** Cumulative model round-trips ("turns") across every invocation of this session. */
|
|
129
|
+
turns?: number;
|
|
130
|
+
/**
|
|
131
|
+
* Snapshot of inputTokens/outputTokens/tokens/costUsd/cache* taken each time
|
|
132
|
+
* a new CLI process is spawned for this session (`start()` or `send()`; see
|
|
133
|
+
* `captureUsageBaseline`). A claude `result` (or a running-total line)
|
|
134
|
+
* reports a total scoped to THAT process only — starting back at zero — so
|
|
135
|
+
* folding it straight into the session would replace/cap prior processes'
|
|
136
|
+
* totals instead of adding to them (a task resumed after review, or a
|
|
137
|
+
* follow-up turn, would see its cost drop back down). `applyUsage` adds
|
|
138
|
+
* this baseline onto authoritative/running-total values; delta-style events
|
|
139
|
+
* (already summed onto `cur`) don't need it.
|
|
140
|
+
*/
|
|
141
|
+
usageBaseline?: {
|
|
142
|
+
inputTokens: number;
|
|
143
|
+
outputTokens: number;
|
|
144
|
+
tokens: number;
|
|
145
|
+
costUsd: number;
|
|
146
|
+
cacheReadTokens: number;
|
|
147
|
+
cacheCreationTokens: number;
|
|
148
|
+
};
|
|
149
|
+
/**
|
|
150
|
+
* claude stream only (0109): a `tool_use` whose `tool_result` has not
|
|
151
|
+
* arrived yet. claude emits the call and its result as separate events, so
|
|
152
|
+
* the tool card is held back until the result line arrives and the entry
|
|
153
|
+
* can carry name + input + output together. Flushed without output if the
|
|
154
|
+
* turn ends before the result.
|
|
155
|
+
*/
|
|
156
|
+
pendingTool?: {
|
|
157
|
+
id: string;
|
|
158
|
+
name: string;
|
|
159
|
+
input?: string;
|
|
160
|
+
};
|
|
161
|
+
/**
|
|
162
|
+
* Edge-detection only, not part of the public stats shape: whether the last
|
|
163
|
+
* `agent.stats` snapshot we pushed already reported `stalled: true`, so the
|
|
164
|
+
* periodic check emits exactly once per stall (not every tick) and output
|
|
165
|
+
* arriving after a stall clears it exactly once too.
|
|
166
|
+
*/
|
|
167
|
+
stalledEmitted: boolean;
|
|
168
|
+
}
|
|
169
|
+
/**
|
|
170
|
+
* Default silence window before a still-running turn is flagged as possibly
|
|
171
|
+
* stalled (0080). Conservative on purpose: silence alone is never proof of a
|
|
172
|
+
* hang (the agent could just be thinking through a slow step), so this only
|
|
173
|
+
* fires a neutral "may be stalled" warning, never a definitive "it's dead."
|
|
174
|
+
* `AgentRunner`'s constructor accepts an override for tests.
|
|
175
|
+
*/
|
|
176
|
+
export declare const DEFAULT_STALL_TIMEOUT_MS = 90000;
|
|
177
|
+
/**
|
|
178
|
+
* Estimate cost from token count when the CLI doesn't report it explicitly.
|
|
179
|
+
* Uses rough pricing for common models: claude 3.5 sonnet $3/M input, $15/M output.
|
|
180
|
+
* This is a fallback when extractUsage yields no cost; never fabricates when
|
|
181
|
+
* the CLI provides no data at all.
|
|
182
|
+
*/
|
|
183
|
+
export declare function estimateCostUsd(tokens?: number): number | undefined;
|
|
184
|
+
/**
|
|
185
|
+
* Best-effort usage/cost extraction from one raw output line. Tries a JSON
|
|
186
|
+
* parse first (codex `--json` usage events, opencode payloads carrying usage)
|
|
187
|
+
* and falls back to plain-text patterns (the kind of human-readable summary
|
|
188
|
+
* claude/qwen print). Returns only the fields it actually found — this must
|
|
189
|
+
* never fabricate a number for a CLI that reports nothing.
|
|
190
|
+
*/
|
|
191
|
+
export interface ExtractedUsage {
|
|
192
|
+
inputTokens?: number;
|
|
193
|
+
outputTokens?: number;
|
|
194
|
+
totalTokens?: number;
|
|
195
|
+
costUsd?: number;
|
|
196
|
+
/** Input tokens served from the provider's prompt cache (~10% price). */
|
|
197
|
+
cacheReadTokens?: number;
|
|
198
|
+
/** Input tokens written to the prompt cache this turn (~125% price). */
|
|
199
|
+
cacheCreationTokens?: number;
|
|
200
|
+
/**
|
|
201
|
+
* True when parsed from a terminal turn-summary event (claude's
|
|
202
|
+
* `type:"result"`) — its numbers are authoritative for the whole turn and
|
|
203
|
+
* should OVERWRITE the running figures, not fold via Math.max. Without this
|
|
204
|
+
* a transient mid-stream `input_tokens` latches high and never comes down
|
|
205
|
+
* (e.g. #0310 showed "177k tokens" when the real non-cached input was 236).
|
|
206
|
+
*/
|
|
207
|
+
authoritative?: boolean;
|
|
208
|
+
/**
|
|
209
|
+
* True when parsed from a per-round-trip event (opencode's `step_finish`),
|
|
210
|
+
* whose token/cost figures are DELTAS for that one model call — NOT a running
|
|
211
|
+
* total and NOT authoritative. Folds by SUM, like `turns`. Without this,
|
|
212
|
+
* `Math.max` folding keeps only the single largest step and undercounts a
|
|
213
|
+
* multi-step opencode session ~5-15x on input and cache-read tokens (a
|
|
214
|
+
* 17-step reviewer run stored ~34k cache-read instead of the real ~500k).
|
|
215
|
+
*/
|
|
216
|
+
deltas?: boolean;
|
|
217
|
+
/**
|
|
218
|
+
* Model round-trips (agent "turns") this line accounts for — claude's
|
|
219
|
+
* `num_turns` from a `result` event, or 1 per opencode `step_finish`. Always
|
|
220
|
+
* a DELTA: folds by SUM (not max/overwrite), so multi-invocation sessions
|
|
221
|
+
* accumulate. `undefined` when the CLI reports nothing countable.
|
|
222
|
+
*/
|
|
223
|
+
turns?: number;
|
|
224
|
+
}
|
|
225
|
+
export declare function extractUsage(raw: string): ExtractedUsage;
|
|
226
|
+
/**
|
|
227
|
+
* Fold usage/cost found in a raw output line into a running total, clamped to
|
|
228
|
+
* never move backward (some CLIs report a running total, some reset per turn).
|
|
229
|
+
* Mirrors `AgentRunner.applyUsage` so one-shot roles aggregate the same way the
|
|
230
|
+
* streaming engineer runner does. Never fabricates a number — absent fields are
|
|
231
|
+
* simply left untouched.
|
|
232
|
+
*/
|
|
233
|
+
export declare function foldUsage(total: ExtractedUsage, raw: string): void;
|
|
234
|
+
/**
|
|
235
|
+
* Classify the cost source for a recorded session (0230). Authoritative
|
|
236
|
+
* CLI-reported cost wins; Kiro is flagged as its own unit (credits), never
|
|
237
|
+
* passed off as USD. Callers that compute a token-based estimate (the engineer
|
|
238
|
+
* runner) set `costSource` to "estimate" themselves — this only reports whether
|
|
239
|
+
* a real CLI figure was present.
|
|
240
|
+
*/
|
|
241
|
+
export declare function usageCostSource(agent: Agent, usage: {
|
|
242
|
+
costUsd?: number;
|
|
243
|
+
}): string;
|
|
244
|
+
/**
|
|
245
|
+
* Map a runner session key to the REAL task id it belongs to (0230). Engineer
|
|
246
|
+
* and review sessions are keyed by the task id directly. PM chats are keyed by
|
|
247
|
+
* a synthetic `pm-task-v2:<id>` id whose suffix is the actual task — attribute
|
|
248
|
+
* them under that real id so PM cost/tokens aggregate per-task. Non-task chats
|
|
249
|
+
* (guide) have no task and return null. Per-user PM sessions (0248) append
|
|
250
|
+
* `::<email>` after the task id; that suffix is stripped here too so cost
|
|
251
|
+
* attribution doesn't treat "<id>::<email>" as the task id.
|
|
252
|
+
*/
|
|
253
|
+
export declare function resolveSessionTaskId(taskKey: string | undefined): string | null;
|
|
254
|
+
/**
|
|
255
|
+
* Persistent session key for Ross's board-level chat. Must match the id the
|
|
256
|
+
* guide client subscribes to and persists under (RepoGuideChat.vue uses
|
|
257
|
+
* "repoos-guide"); a previous refactor drifted this to "__repoos-guide__",
|
|
258
|
+
* which hid the guide's running/stop state from the UI.
|
|
259
|
+
*/
|
|
260
|
+
export declare const REPO_GUIDE_SESSION_ID = "repoos-guide";
|
|
261
|
+
/** Persistent session id for the Debugger's bug-paste conversation. */
|
|
262
|
+
export declare const debuggerSessionId = "__repoos-debugger__";
|
|
263
|
+
/**
|
|
264
|
+
* Classify a runner session into the role label the board's "AI usage — all
|
|
265
|
+
* roles" panel groups by (0331). Exact matches on the built-in role names win
|
|
266
|
+
* first: the legacy "RepoOS Guide" name used to be swallowed into "engineer"
|
|
267
|
+
* because an earlier `includes("repoos")` probe ran before the guide check —
|
|
268
|
+
* classify on what the agent IS, not on a substring an earlier rule grabbed.
|
|
269
|
+
* Unknown names fall through ordered substring probes (guide before the rest
|
|
270
|
+
* so "ross guide"-style hybrids still land right), then to "task" when the
|
|
271
|
+
* session is keyed to a task at all, "chat" when it is not.
|
|
272
|
+
*/
|
|
273
|
+
export declare function classifySessionType(agentName: string | null | undefined, taskKey?: string): string;
|
|
274
|
+
export interface AgentRunnerOptions {
|
|
275
|
+
/** Test/embedding overrides; production defaults are the documented policy. */
|
|
276
|
+
writeDelayMs?: number;
|
|
277
|
+
retentionDays?: number;
|
|
278
|
+
retentionCount?: number;
|
|
279
|
+
now?: () => Date;
|
|
280
|
+
/** Resolve a task from the repo task index by ID. Used to populate task/branch on resume turns. */
|
|
281
|
+
getTask?: (taskId: string) => Task | null;
|
|
282
|
+
}
|
|
283
|
+
/**
|
|
284
|
+
* Parse one line of opencode's `--format json` stream into a structured
|
|
285
|
+
* transcript entry. Returns null for malformed lines and for event types we
|
|
286
|
+
* don't surface (session-id, title, reasoning, …) — callers fall back to the
|
|
287
|
+
* plain-line handling in those cases.
|
|
288
|
+
*/
|
|
289
|
+
export declare function parseJsonEvent(raw: string): {
|
|
290
|
+
entry: AgentOutputEntry;
|
|
291
|
+
sessionID?: string;
|
|
292
|
+
} | null;
|
|
293
|
+
/**
|
|
294
|
+
* Result of parsing one line of claude code's `--output-format stream-json`
|
|
295
|
+
* stream (0109). Fields are mutually exclusive:
|
|
296
|
+
*
|
|
297
|
+
* - `entry` — a ready-to-surface transcript entry (assistant text, a completed
|
|
298
|
+
* tool call, or a step boundary).
|
|
299
|
+
* - `pendingTool` — a `tool_use` whose `tool_result` hasn't arrived yet. The
|
|
300
|
+
* line has no entry yet; the runner buffers it and emits the tool card only
|
|
301
|
+
* when the matching `tool_result` line arrives (name + input + output
|
|
302
|
+
* together).
|
|
303
|
+
* - `toolResult` — a `tool_result` line to attach to the buffered tool.
|
|
304
|
+
* - `sessionID` — the `system/init` event's real `session_id` field (never
|
|
305
|
+
* regex-scraped).
|
|
306
|
+
*
|
|
307
|
+
* `null` means the line is not a claude stream event (a non-JSON warning line,
|
|
308
|
+
* unknown JSON schema, …) — callers fall back to the plain-line path.
|
|
309
|
+
*/
|
|
310
|
+
export interface ClaudeParseResult {
|
|
311
|
+
entry?: AgentOutputEntry;
|
|
312
|
+
sessionID?: string;
|
|
313
|
+
pendingTool?: {
|
|
314
|
+
id: string;
|
|
315
|
+
name: string;
|
|
316
|
+
input?: string;
|
|
317
|
+
};
|
|
318
|
+
toolResult?: {
|
|
319
|
+
id: string;
|
|
320
|
+
content?: string;
|
|
321
|
+
isError?: boolean;
|
|
322
|
+
};
|
|
323
|
+
}
|
|
324
|
+
/**
|
|
325
|
+
* Parse one line of claude code's `--output-format stream-json` stream into a
|
|
326
|
+
* structured transcript result. Mirrors `parseJsonEvent` for opencode but with
|
|
327
|
+
* claude's event shapes: content is nested under `message.content[]` (not
|
|
328
|
+
* `part`), the session id is a real `session_id` field on `system/init`, and
|
|
329
|
+
* tool results arrive as separate `user` events. Recognized-but-voiceless
|
|
330
|
+
* events (rate_limit, thinking-only assistant messages, the terminal `result`)
|
|
331
|
+
* are returned without an `entry` so the runner swallows them instead of
|
|
332
|
+
* dumping raw JSON into the transcript. `null` for anything else — callers
|
|
333
|
+
* fall back to the plain-line path.
|
|
334
|
+
*/
|
|
335
|
+
export declare function parseClaudeEvent(raw: string): ClaudeParseResult | null;
|
|
336
|
+
/**
|
|
337
|
+
* Parse Copilot CLI's `--output-format json` JSONL stream. The CLI emits
|
|
338
|
+
* lifecycle telemetry alongside assistant and tool events; lifecycle records
|
|
339
|
+
* are recognized and swallowed so the Agent tab remains a useful transcript.
|
|
340
|
+
*/
|
|
341
|
+
export declare function parseCopilotEvent(raw: string): {
|
|
342
|
+
entry?: AgentOutputEntry;
|
|
343
|
+
sessionID?: string;
|
|
344
|
+
} | null;
|
|
345
|
+
/**
|
|
346
|
+
* Qwen's stream-json is Claude-compatible for assistant/tool content, but
|
|
347
|
+
* versions in the wild also emit the shorter `{type, content}` form. Keep
|
|
348
|
+
* this adapter deliberately tolerant so a CLI upgrade cannot turn the chat
|
|
349
|
+
* into a wall of JSON.
|
|
350
|
+
*/
|
|
351
|
+
export declare function parseQwenEvent(raw: string): ClaudeParseResult | null;
|
|
352
|
+
interface CodexEventResult {
|
|
353
|
+
entry?: AgentOutputEntry;
|
|
354
|
+
sessionID?: string;
|
|
355
|
+
}
|
|
356
|
+
/** Parse Codex `exec --json` JSONL into the same chat cards as OpenCode. */
|
|
357
|
+
export declare function parseCodexEvent(raw: string): CodexEventResult | null;
|
|
358
|
+
/** Branch derived from a task title, mirroring the UI's `feat/<slug>` rule. */
|
|
359
|
+
export declare function deriveBranch(title: string): string;
|
|
360
|
+
/** Resolve the enabled `engineer` agent, or null when none is configured. */
|
|
361
|
+
export declare function resolveEngineer(config: RepoOSConfig): Agent | null;
|
|
362
|
+
/** Resolve the enabled `pm` agent, or null when none is configured. */
|
|
363
|
+
export declare function resolvePmAgent(config: RepoOSConfig): Agent | null;
|
|
364
|
+
/**
|
|
365
|
+
* Resolve the enabled `reviewer` agent, or null when it is disabled/absent.
|
|
366
|
+
*
|
|
367
|
+
* This is the single source of truth for whether a task landing in `review`
|
|
368
|
+
* gets an automatic agent review (0101): the Agents page writes the toggle
|
|
369
|
+
* into `repoos.toml`, and null here means "no agent review runs".
|
|
370
|
+
*/
|
|
371
|
+
export declare function resolveReviewer(config: RepoOSConfig): Agent | null;
|
|
372
|
+
/**
|
|
373
|
+
* Resolve the reviewer agent for a specific task, honoring per-task review
|
|
374
|
+
* overrides (set via the Review tab's selector, like Dev/PM overrides).
|
|
375
|
+
*
|
|
376
|
+
* When the task has no review override, this behaves exactly as the global
|
|
377
|
+
* `resolveReviewer` — the Agents-page reviewer. When a `reviewAgentOverride`
|
|
378
|
+
* is set, the enabled agent with that name is used (falling back to the global
|
|
379
|
+
* reviewer base when only CLI/model are overridden); `reviewCliOverride` /
|
|
380
|
+
* `reviewModelOverride` then replace the agent's CLI and model.
|
|
381
|
+
*/
|
|
382
|
+
export declare function resolveReviewerForTask(config: RepoOSConfig, task: Task): Agent | null;
|
|
383
|
+
export declare function resolveCto(config: RepoOSConfig): Agent | null;
|
|
384
|
+
/**
|
|
385
|
+
* Resolve the agent for a specific task, honoring per-task overrides.
|
|
386
|
+
*
|
|
387
|
+
* When the task has an `agentOverride`, the enabled agent with that name is
|
|
388
|
+
* used (falling back to the base agent when the override name matches). When
|
|
389
|
+
* only `cliOverride` or `modelOverride` are set (without a different agent
|
|
390
|
+
* name), the base agent's name and instructions are kept but cli/model are
|
|
391
|
+
* overridden.
|
|
392
|
+
*
|
|
393
|
+
* @param config Global config (provides the agents list and defaults).
|
|
394
|
+
* @param task The task being run (may carry overrides).
|
|
395
|
+
* @param role The role to resolve when no agent override is set (default: "engineer").
|
|
396
|
+
* @returns A merged Agent, or null when no matching enabled agent exists.
|
|
397
|
+
*/
|
|
398
|
+
/**
|
|
399
|
+
* True when a model-override field carries a real pin, not the "default"
|
|
400
|
+
* sentinel `AGENT_MODELS` offers for "use the base agent's own configured
|
|
401
|
+
* model, whatever that is" (config.ts). Every per-task model-override
|
|
402
|
+
* resolver (this file's `resolveAgentForTask`/`resolveReviewerForTask`, and
|
|
403
|
+
* routes/tasks.ts's inline PM-override logic) MUST run the override string
|
|
404
|
+
* through this before treating it as active — bare truthiness treats the
|
|
405
|
+
* literal string `"default"` as a real pin and force-overwrites the base
|
|
406
|
+
* agent's actual configured model with the string `"default"`, which then
|
|
407
|
+
* skips `--model` entirely (see `modelArgs` below) and falls back to the
|
|
408
|
+
* underlying CLI's own raw default — NOT the model configured on the
|
|
409
|
+
* Agents page. Confirmed live: tasks kept ending up running
|
|
410
|
+
* opencode+(no model flag) instead of the configured model every time a
|
|
411
|
+
* Dev/Review/PM override dropdown was left on (or reset to) "Default".
|
|
412
|
+
*/
|
|
413
|
+
export declare function isModelOverridePinned(model: string | null | undefined): boolean;
|
|
414
|
+
export declare function resolveAgentForTask(config: RepoOSConfig, task: Task, role?: string): Agent | null;
|
|
415
|
+
/** Resolve the enabled built-in repository assistant (by current "Ross" name or legacy "RepoOS Guide"). */
|
|
416
|
+
export declare function resolveRepoGuide(config: RepoOSConfig): Agent | null;
|
|
417
|
+
/** Build the read-only mission used by the persistent repository chat. */
|
|
418
|
+
export declare function repoGuidePrompt(question: string, repositoryContext: string, agent: Agent): string;
|
|
419
|
+
/** The Debugger agent's role name, used to route its chat prompt. */
|
|
420
|
+
export declare const DEBUGGER_NAME = "debugger";
|
|
421
|
+
/**
|
|
422
|
+
* The Debugger agent: a chat-first bug diagnostician (no background scan).
|
|
423
|
+
* Its CLI/model can be overridden from the persisted built-in agent state so
|
|
424
|
+
* the inline "coding agent + model" selector on the Agents page actually drives
|
|
425
|
+
* which model the Debugger runs on.
|
|
426
|
+
*/
|
|
427
|
+
export declare function debuggerAgent(override?: {
|
|
428
|
+
cli?: string;
|
|
429
|
+
model?: string;
|
|
430
|
+
}): Agent;
|
|
431
|
+
export declare function debuggerPrompt(question: string, repositoryContext: string, agent: Agent): string;
|
|
432
|
+
/** Build the writable task-management mission used only by the PM chat. */
|
|
433
|
+
export declare function taskPmPrompt(request: string, taskContext: string, agent: Agent): string;
|
|
434
|
+
/** Pick a small relevant subset; role defaults are preferences, never an unconditional prompt append. */
|
|
435
|
+
export declare function selectSkillsForRun(task: Task, agent: Agent, config: RepoOSConfig): SkillMeta[];
|
|
436
|
+
/** One-shot run outcome: resolved stdout, or a human-readable failure. */
|
|
437
|
+
export interface PromptResult {
|
|
438
|
+
ok: boolean;
|
|
439
|
+
output?: string;
|
|
440
|
+
error?: string;
|
|
441
|
+
/** Wall-clock elapsed ms for the run, or 0 if it never spawned. */
|
|
442
|
+
elapsedMs?: number;
|
|
443
|
+
/** Cumulative tokens/cost the CLI reported, when extractUsage found any. */
|
|
444
|
+
inputTokens?: number;
|
|
445
|
+
outputTokens?: number;
|
|
446
|
+
totalTokens?: number;
|
|
447
|
+
costUsd?: number;
|
|
448
|
+
cacheReadTokens?: number;
|
|
449
|
+
cacheCreationTokens?: number;
|
|
450
|
+
turns?: number;
|
|
451
|
+
}
|
|
452
|
+
/**
|
|
453
|
+
* Map an agent `cli` to a one-shot (print mode) invocation that writes its
|
|
454
|
+
* answer to stdout. opencode: `run`, claude: `-p`, qwen: `-p`, codex:
|
|
455
|
+
* `exec`. Explicit configured models are forwarded with the driver's model
|
|
456
|
+
* flag; `default` intentionally omits the flag and lets the CLI resolve it.
|
|
457
|
+
*/
|
|
458
|
+
export declare function promptCommand(agent: Agent, prompt: string): {
|
|
459
|
+
cmd: string;
|
|
460
|
+
args: string[];
|
|
461
|
+
};
|
|
462
|
+
/**
|
|
463
|
+
* Map an agent `cli` to a one-shot PM authoring invocation (0335). Same
|
|
464
|
+
* print-mode shape as `promptCommand`, with one difference that matters for
|
|
465
|
+
* the usage tab: structured output flags wherever the driver offers them, so
|
|
466
|
+
* `runPrompt`'s extractUsage/foldUsage sees real tokens/cost and the initial
|
|
467
|
+
* PM flesh-out lands in the ledger with figures instead of a blank row —
|
|
468
|
+
* exactly the treatment the reviewer got in 0273. Unlike `reviewCommand`,
|
|
469
|
+
* no permission-bypass flags: the PM only authors text (its output is applied
|
|
470
|
+
* via `patchTaskFile`), so it must not be able to write files or run tools.
|
|
471
|
+
*
|
|
472
|
+
* The JSONL/JSON stdout this produces is parsed back to the final answer with
|
|
473
|
+
* `extractOneShotReportText` and rendered live with `parseOneShotLine` — the
|
|
474
|
+
* same pairing the reviewer/CTO one-shots use.
|
|
475
|
+
*/
|
|
476
|
+
export declare function pmCommand(agent: Agent, prompt: string, cwd: string): {
|
|
477
|
+
cmd: string;
|
|
478
|
+
args: string[];
|
|
479
|
+
};
|
|
480
|
+
/**
|
|
481
|
+
* Map an agent `cli` to a one-shot REVIEW invocation: the agent inspects a
|
|
482
|
+
* worktree it must not modify and prints its report to stdout.
|
|
483
|
+
*
|
|
484
|
+
* Same print-mode shape as `promptCommand`, with one difference that matters:
|
|
485
|
+
* a reviewer has to READ the worktree (git diff, file reads, maybe the test
|
|
486
|
+
* suite), and stdin is ignored — so any engine that gates those calls behind a
|
|
487
|
+
* permission prompt would hang until the timeout instead of reporting. Only
|
|
488
|
+
* flags already verified for this repo's drivers are used:
|
|
489
|
+
* - claude code: `--dangerously-skip-permissions` (same reason as the runner's
|
|
490
|
+
* start turns — nobody can answer a prompt).
|
|
491
|
+
* - opencode: `--dir <cwd>` so a linked-worktree path is not auto-rejected,
|
|
492
|
+
* plus `--auto` so gated tool calls resolve instead of blocking.
|
|
493
|
+
* - codex: `exec` alone — its default sandbox is already read-only, which is
|
|
494
|
+
* exactly the blast radius a reviewer should have.
|
|
495
|
+
* - qwen code: plain `-p`, matching `promptCommand`.
|
|
496
|
+
* - opencode: `--format json`, matching the interactive runner (`cliCommand`
|
|
497
|
+
* below). Without it, `run`'s plain-text stdout interleaves the model's
|
|
498
|
+
* step-by-step narration ("Let me look at...") with its final answer, and
|
|
499
|
+
* nothing separates the two — the whole transcript ends up as the review
|
|
500
|
+
* report (0264 vs 0253). `extractOneShotReportText` below picks the final
|
|
501
|
+
* text event back out of the JSON stream.
|
|
502
|
+
*/
|
|
503
|
+
export declare function reviewCommand(agent: Agent, prompt: string, cwd: string): {
|
|
504
|
+
cmd: string;
|
|
505
|
+
args: string[];
|
|
506
|
+
};
|
|
507
|
+
/**
|
|
508
|
+
* Turn one line of a one-shot (review/CTO) agent's stdout into a transcript
|
|
509
|
+
* entry for live display. Structured event streams (opencode `--format json`,
|
|
510
|
+
* claude/qwen stream-json, codex `--json`, copilot json) get the same per-line
|
|
511
|
+
* parsing the interactive runner applies, so the review transcript reads
|
|
512
|
+
* cleanly instead of dumping raw JSON. A recognized-but-voiceless structured
|
|
513
|
+
* event (claude `result`, `system/init`, a thinking-only assistant message …)
|
|
514
|
+
* returns null so the caller can swallow it; a non-JSON line (warnings, plain
|
|
515
|
+
* text from kiro) passes through as a plain `{s, d}` entry.
|
|
516
|
+
*/
|
|
517
|
+
export declare function parseOneShotLine(cli: string, raw: string): AgentOutputEntry | null;
|
|
518
|
+
/**
|
|
519
|
+
* Isolate the final report/answer from a one-shot agent's full captured
|
|
520
|
+
* stdout. Structured JSONL engines (opencode `--format json`, claude/qwen
|
|
521
|
+
* stream-json, codex `--json`, copilot json) carry the model's whole narration
|
|
522
|
+
* as a sequence of `text` events interleaved with tool calls — the actual final
|
|
523
|
+
* answer is the LAST `text` event, so this discards the rest (0264 vs 0253).
|
|
524
|
+
* Non-JSON one-shot CLIs (kiro) print only the final answer, so their raw
|
|
525
|
+
* output IS the report. Falls back to the raw output if no text event parses,
|
|
526
|
+
* so a format change never yields an empty report.
|
|
527
|
+
*/
|
|
528
|
+
export declare function extractOneShotReportText(cli: string, rawOutput: string): string;
|
|
529
|
+
/**
|
|
530
|
+
* Run a coding agent once, non-interactively, and capture its full stdout.
|
|
531
|
+
* Unlike the streaming runner this is synchronous — callers wait for the whole
|
|
532
|
+
* answer (e.g. freeform task creation). Never throws: failures and timeouts
|
|
533
|
+
* resolve as `{ ok: false, error }` so an HTTP handler can respond cleanly.
|
|
534
|
+
*
|
|
535
|
+
* `onLine` streams each complete stdout line as it arrives (line-buffered, the
|
|
536
|
+
* same shape the runner uses) so a caller can forward live progress over SSE
|
|
537
|
+
* without waiting for the run to finish. It is called for real output only —
|
|
538
|
+
* never for a synthetic failure — and a trailing partial line is flushed on
|
|
539
|
+
* exit.
|
|
540
|
+
*
|
|
541
|
+
* `command` overrides the invocation (default: `promptCommand`) so a caller
|
|
542
|
+
* that needs different flags — the review agent's read-the-worktree mode —
|
|
543
|
+
* reuses this spawn/timeout/capture handling instead of duplicating it.
|
|
544
|
+
* `onSpawn` hands the live child to the caller so it can be killed early.
|
|
545
|
+
*
|
|
546
|
+
* The child inherits the server's env verbatim: unlike the streaming runner,
|
|
547
|
+
* NO `REPOOS_API_URL` / `REPOOS_TASK_ID` is injected, so a one-shot agent has
|
|
548
|
+
* no pointer at the control plane's task endpoints.
|
|
549
|
+
*/
|
|
550
|
+
export declare function runPrompt(agent: Agent, prompt: string, opts?: {
|
|
551
|
+
cwd?: string;
|
|
552
|
+
timeoutMs?: number;
|
|
553
|
+
onLine?: (line: string) => void;
|
|
554
|
+
command?: {
|
|
555
|
+
cmd: string;
|
|
556
|
+
args: string[];
|
|
557
|
+
};
|
|
558
|
+
onSpawn?: (proc: ChildProcess) => void;
|
|
559
|
+
}): Promise<PromptResult>;
|
|
560
|
+
/**
|
|
561
|
+
* Persist a one-shot `runPrompt` run to the sessions DB (0311). One-shot AI
|
|
562
|
+
* work — freeform task/doc authoring, the auto-engineering dispatch pass —
|
|
563
|
+
* bypasses the AgentRunner, so nothing books it unless the caller does. This
|
|
564
|
+
* is the shared path for those: it folds the `PromptResult` (elapsed, tokens,
|
|
565
|
+
* cost) into a session row, classifying `costSource` the same way
|
|
566
|
+
* `recordSessionToDb` does — a real CLI figure wins, a token-only run gets an
|
|
567
|
+
* estimate, Kiro credits are never presented as USD. Best-effort: a DB failure
|
|
568
|
+
* never propagates to the request.
|
|
569
|
+
*
|
|
570
|
+
* `taskId` is null for board-level work that belongs to no single task; those
|
|
571
|
+
* rows still roll into every board-level aggregation (getSessionTypeStats /
|
|
572
|
+
* getDailyTotals / board summary), just not a task drawer.
|
|
573
|
+
*/
|
|
574
|
+
export declare function recordOneShotSession(repoRoot: string, agent: Agent, result: PromptResult, opts: {
|
|
575
|
+
sessionType: string;
|
|
576
|
+
taskId?: string | null;
|
|
577
|
+
sessionId?: string;
|
|
578
|
+
}): void;
|
|
579
|
+
export declare class AgentRunner {
|
|
580
|
+
private entries;
|
|
581
|
+
private readonly sessions;
|
|
582
|
+
private readonly config;
|
|
583
|
+
/**
|
|
584
|
+
* Cap on simultaneously-spawned agent CLI processes — each one may
|
|
585
|
+
* itself run a build/test worker pool sized to the host's core count, so
|
|
586
|
+
* unlimited concurrent agents oversubscribe the machine. Configurable via
|
|
587
|
+
* `maxConcurrentAgents` in repoos.toml; "auto" (unset) sizes it to this
|
|
588
|
+
* machine's CPU count so the same repo behaves on a laptop and a desktop.
|
|
589
|
+
*/
|
|
590
|
+
private readonly maxConcurrentAgents;
|
|
591
|
+
/** Ids (taskId or chat sessionId) with a queued start/send waiting for a free slot, mapped to when they were queued. */
|
|
592
|
+
private readonly queuedIds;
|
|
593
|
+
/** FIFO of deferred spawns, drained as running agents exit (see cleanup()). */
|
|
594
|
+
private readonly startQueue;
|
|
595
|
+
private readonly emit;
|
|
596
|
+
private readonly logger?;
|
|
597
|
+
private readonly sessionsDir;
|
|
598
|
+
private readonly cacheDir;
|
|
599
|
+
private readonly logDir;
|
|
600
|
+
private readonly db;
|
|
601
|
+
private readonly writeDelayMs;
|
|
602
|
+
private readonly retentionDays;
|
|
603
|
+
private readonly retentionCount;
|
|
604
|
+
private readonly clock;
|
|
605
|
+
private readonly writeTimers;
|
|
606
|
+
private readonly pendingCompletion;
|
|
607
|
+
/**
|
|
608
|
+
* The main RepoOS server's own API URL, injected into every agent process so
|
|
609
|
+
* agents with host networking have an informational pointer at the ACTUAL
|
|
610
|
+
* control plane, never a hardcoded port. Managed previews are requested by
|
|
611
|
+
* signal (#0121), so this is not a requirement — it stays for diagnostics
|
|
612
|
+
* and future HTTP-capable drivers.
|
|
613
|
+
*/
|
|
614
|
+
apiUrl?: string;
|
|
615
|
+
private readonly stallTimeoutMs;
|
|
616
|
+
private readonly stallTimer;
|
|
617
|
+
private readonly authorizedHandoffs;
|
|
618
|
+
private readonly handoffsInFlight;
|
|
619
|
+
private readonly onHandoff?;
|
|
620
|
+
/**
|
|
621
|
+
* Fired on completion of a durable REVIEW turn (0288) — including for an
|
|
622
|
+
* entry re-attached after a reload, whose process finishes on the new
|
|
623
|
+
* server. The owning ReviewManager finalizes the report from this hook
|
|
624
|
+
* rather than a post-spawn continuation that would die with the old process.
|
|
625
|
+
* `reviewKind` (run vs chat) and `exitedCleanly` are threaded through so the
|
|
626
|
+
* ReviewManager can finalize an adopted turn in the right mode and decide
|
|
627
|
+
* whether it finished cleanly.
|
|
628
|
+
*/
|
|
629
|
+
private readonly onReviewDone?;
|
|
630
|
+
/**
|
|
631
|
+
* Tasks a human deliberately paused (via POST /api/tasks/:id/pause, 0070).
|
|
632
|
+
* The task stays `active` with no process, so without this the watchdog would
|
|
633
|
+
* treat a legitimately-paused task as stuck and disturb it (#0180). In-memory
|
|
634
|
+
* only: a paused task across a server restart loses the marker and reads as a
|
|
635
|
+
* stopped agent — the watchdog then surfaces it, which is the correct default
|
|
636
|
+
* (the paused process is, after all, gone).
|
|
637
|
+
*/
|
|
638
|
+
private readonly pausedTasks;
|
|
639
|
+
/**
|
|
640
|
+
* Preview capabilities minted per clean run (#0121). Superseded when a new
|
|
641
|
+
* run starts for the same task, so a stale request can never start a preview
|
|
642
|
+
* against a different worktree.
|
|
643
|
+
*/
|
|
644
|
+
private readonly authorizedPreviews;
|
|
645
|
+
private readonly onPreviewRequest?;
|
|
646
|
+
/** Resolve a task from the repo task index by ID. Used to populate task/branch on resume turns. */
|
|
647
|
+
private readonly getTask?;
|
|
648
|
+
/**
|
|
649
|
+
* `opts.stallTimeoutMs` overrides the 90s default (tests use a small value
|
|
650
|
+
* so stall detection doesn't need a real 90s wait); `opts.stallCheckIntervalMs`
|
|
651
|
+
* overrides the poll cadence, which otherwise scales with the timeout.
|
|
652
|
+
*/
|
|
653
|
+
constructor(config: RepoOSConfig, emit: (e: AgentEvent) => void, opts?: {
|
|
654
|
+
stallTimeoutMs?: number;
|
|
655
|
+
stallCheckIntervalMs?: number;
|
|
656
|
+
onHandoff?: (request: AgentHandoffRequest) => void | Promise<void>;
|
|
657
|
+
onPreviewRequest?: (request: AgentPreviewRequest) => void | Promise<void>;
|
|
658
|
+
onReviewDone?: (sessionKey: string, exitedCleanly: boolean, reviewKind?: "run" | "chat") => void;
|
|
659
|
+
logger?: Logger;
|
|
660
|
+
} & AgentRunnerOptions);
|
|
661
|
+
/** Stop the stall-check timer (server shutdown / test cleanup). Idempotent. */
|
|
662
|
+
dispose(): void;
|
|
663
|
+
/**
|
|
664
|
+
* Re-attach to agent children that survived a server restart (0214).
|
|
665
|
+
* Reads the durable registry, checks PID aliveness, and for each still-live
|
|
666
|
+
* child tail-catches the log file and restores the in-memory entry/session
|
|
667
|
+
* so `isRunning()` reports true and SSE streaming resumes from this point.
|
|
668
|
+
* Stale entries (PID dead) are dropped — this must not resurrect dead sessions.
|
|
669
|
+
*/
|
|
670
|
+
adoptRunningAgents(): void;
|
|
671
|
+
/** Replay a durable log into a transcript, optionally decoding the legacy tagged format. */
|
|
672
|
+
private replayLog;
|
|
673
|
+
/** True only while `replayLog` is rebuilding a transcript — see `applyUsage`. */
|
|
674
|
+
private replayingUsage;
|
|
675
|
+
/** Tail one durable stream file into the live transcript. */
|
|
676
|
+
private tailLog;
|
|
677
|
+
/** Persist a registry entry for one running task (0214). */
|
|
678
|
+
private writeRegistryEntry;
|
|
679
|
+
/** Remove a registry entry for a task (0214). */
|
|
680
|
+
private removeRegistryEntry;
|
|
681
|
+
/** Clear the entire durable registry (0214). */
|
|
682
|
+
private clearRegistry;
|
|
683
|
+
/** Persist a handoff request for recovery across process boundaries. */
|
|
684
|
+
private persistPendingHandoff;
|
|
685
|
+
/** Remove a persisted handoff request (by task id). */
|
|
686
|
+
private clearPendingHandoff;
|
|
687
|
+
/**
|
|
688
|
+
* Recover persisted handoff requests at server boot. Validates each request
|
|
689
|
+
* (task still exists, still active, branch matches, not already finalizing)
|
|
690
|
+
* and re-fires onHandoff for valid ones. Idempotent: a request already in
|
|
691
|
+
* handoffsInFlight is skipped.
|
|
692
|
+
*/
|
|
693
|
+
recoverPendingHandoffs(): void;
|
|
694
|
+
/** Append trusted server orchestration progress to the retained transcript. */
|
|
695
|
+
system(taskId: string, text: string): void;
|
|
696
|
+
/** Validate that a handoff capability was minted by a successful active turn. */
|
|
697
|
+
validateHandoff(request: AgentHandoffRequest): boolean;
|
|
698
|
+
/** Validate and expire one runner-issued handoff capability atomically. */
|
|
699
|
+
consumeHandoff(request: AgentHandoffRequest): boolean;
|
|
700
|
+
/**
|
|
701
|
+
* Validate that a preview capability was minted by a real, current runner
|
|
702
|
+
* turn (#0121). The capability carries the task id, the run id issued for
|
|
703
|
+
* that turn, the registered branch, and the registered worktree — a forged,
|
|
704
|
+
* expired (superseded by a newer run), cross-task, or path-substituted
|
|
705
|
+
* request never matches all four.
|
|
706
|
+
*/
|
|
707
|
+
validatePreview(request: AgentPreviewRequest): boolean;
|
|
708
|
+
isRunning(taskId: string): boolean;
|
|
709
|
+
/**
|
|
710
|
+
* The review turn kind ("run" | "chat") of a durable review session, if the
|
|
711
|
+
* entry is one (0288). Used by ReviewManager to finalize an ADOPTED turn in
|
|
712
|
+
* the right mode — the session's own `Run` record is not carried across a
|
|
713
|
+
* reload, but its review kind is (persisted in the registry).
|
|
714
|
+
*/
|
|
715
|
+
reviewKindOf(sessionKey: string): "run" | "chat" | undefined;
|
|
716
|
+
/**
|
|
717
|
+
* Record a deliberate human pause (0070): the task stays `active` but its
|
|
718
|
+
* agent is intentionally stopped, so the watchdog must not touch it (#0180).
|
|
719
|
+
* Cleared automatically the moment a new turn starts for the task.
|
|
720
|
+
*/
|
|
721
|
+
markPaused(taskId: string): void;
|
|
722
|
+
/** True when the task was explicitly paused and no new turn has started since. */
|
|
723
|
+
isPaused(taskId: string): boolean;
|
|
724
|
+
/**
|
|
725
|
+
* True while the server-side handoff for a task is still finalizing (check,
|
|
726
|
+
* commit, review). The process is already gone, so `isRunning` is false, but
|
|
727
|
+
* the task is not stuck — the close-out pipeline owns it for a few seconds.
|
|
728
|
+
*/
|
|
729
|
+
isHandoffInFlight(taskId: string): boolean;
|
|
730
|
+
/** Live run telemetry for a task's session — zeros/nulls when none exists yet. */
|
|
731
|
+
stats(taskId: string): AgentSessionStats;
|
|
732
|
+
running(): RunningAgentInfo[];
|
|
733
|
+
/** Query historical stats for a task from the database. */
|
|
734
|
+
taskStats(taskId: string): import("../core/db.js").TaskStats | null;
|
|
735
|
+
/** Query historical stats grouped by session type from the database. */
|
|
736
|
+
sessionTypeStats(): import("../core/db.js").SessionTypeStats[];
|
|
737
|
+
/** Per-day usage totals (server's local time). */
|
|
738
|
+
dailyTotals(): import("../core/db.js").DailyTotals[];
|
|
739
|
+
/** Query board-level summary stats from the database, optionally scoped to a usage range (0334). */
|
|
740
|
+
boardStats(range?: UsageRange): import("../core/db.js").BoardStats | null;
|
|
741
|
+
/**
|
|
742
|
+
* Spawn the coding agent on the task. Never blocks — the child runs
|
|
743
|
+
* detached from the HTTP response. Returns a StartResult describing the
|
|
744
|
+
* launch attempt; an async spawn failure is emitted as agent.exited.
|
|
745
|
+
*
|
|
746
|
+
* `opts.cwd` is the task's worktree directory when one was provisioned;
|
|
747
|
+
* defaults to the repo root so launch still works (best-effort) when
|
|
748
|
+
* worktree setup failed or the task's branch is the main checkout.
|
|
749
|
+
*/
|
|
750
|
+
start(task: Task, branch: string, agent: Agent, opts?: {
|
|
751
|
+
cwd?: string;
|
|
752
|
+
contextPack?: string;
|
|
753
|
+
resumePreamble?: string;
|
|
754
|
+
}): StartResult;
|
|
755
|
+
/** Start a persistent, non-task conversation with an explicit role mission. */
|
|
756
|
+
startChat(sessionId: string, text: string, agent: Agent, repositoryContext: string, promptBuilder?: (text: string, context: string, agent: Agent) => string): StartResult;
|
|
757
|
+
/**
|
|
758
|
+
* Spawn a durable REVIEW turn under a synthetic session key (0288), so the
|
|
759
|
+
* reviewer survives a server reload the same way engineer/PM turns do: the
|
|
760
|
+
* child's stdout/stderr stream to durable log files and its PID is registered
|
|
761
|
+
* so the next server's `adoptRunningAgents()` re-attaches and replays any
|
|
762
|
+
* output written during the handoff. On completion — even post-reload —
|
|
763
|
+
* `cleanup()` fires `onReviewDone` for the owning ReviewManager to finalize.
|
|
764
|
+
*
|
|
765
|
+
* Unlike `start`/`send`, the review agent is deliberately NOT given
|
|
766
|
+
* `REPOOS_TASK_ID` / `REPOOS_API_URL`, preserving the read-only boundary that
|
|
767
|
+
* keeps it from reaching the control plane's task endpoints (review.ts layer
|
|
768
|
+
* 2). `kind: "review"` is persisted in the durable registry so adoption knows
|
|
769
|
+
* to re-attach as a review.
|
|
770
|
+
*
|
|
771
|
+
* `reset: true` (a fresh run) clears any prior conversation; a chat turn
|
|
772
|
+
* (`reset: false`, with `humanEntry`) continues the existing one.
|
|
773
|
+
*/
|
|
774
|
+
startReview(sessionKey: string, agent: Agent, mission: string, cwd: string, opts?: {
|
|
775
|
+
humanEntry?: AgentOutputEntry;
|
|
776
|
+
reset?: boolean;
|
|
777
|
+
reviewKind?: "run" | "chat";
|
|
778
|
+
}): StartResult;
|
|
779
|
+
/** Release a durable review session from the in-memory map (its file stays). */
|
|
780
|
+
discardReviewSession(sessionKey: string): void;
|
|
781
|
+
/**
|
|
782
|
+
* Send a follow-up message to a task's session, resuming the same
|
|
783
|
+
* conversation as a new turn. Rejected when the task has no session yet
|
|
784
|
+
* (`ok: false`) or when a turn is already running (`ok: false, busy: true`).
|
|
785
|
+
*/
|
|
786
|
+
send(taskId: string, text: string, agent: Agent, opts?: {
|
|
787
|
+
resumePreamble?: string;
|
|
788
|
+
skipBoardDivergence?: boolean;
|
|
789
|
+
}): StartResult;
|
|
790
|
+
/** The retained transcript for a task, or null when no session exists. */
|
|
791
|
+
output(taskId: string): Session | null;
|
|
792
|
+
/** Whether a session exists for a key (in memory or persisted on disk). */
|
|
793
|
+
hasSession(sessionKey: string): boolean;
|
|
794
|
+
/** Drop a session both in memory and from disk (a fresh review run). */
|
|
795
|
+
clearSession(sessionKey: string): void;
|
|
796
|
+
/**
|
|
797
|
+
* Mark a task transcript complete and release its RAM. If its child is still
|
|
798
|
+
* draining after a stop request, cleanup performs the final flush/eviction.
|
|
799
|
+
*/
|
|
800
|
+
complete(taskId: string): void;
|
|
801
|
+
/** Flush all debounced transcript writes before shutdown/reload handover. */
|
|
802
|
+
flushAll(): void;
|
|
803
|
+
/**
|
|
804
|
+
* Gate for every spawnTurn call site: at capacity, defer the spawn
|
|
805
|
+
* instead of oversubscribing the machine. The caller still gets `ok: true`
|
|
806
|
+
* immediately — `queued: true` distinguishes "will run shortly" from
|
|
807
|
+
* "running now" without changing callers' happy-path handling. `id` is
|
|
808
|
+
* marked busy via queuedIds so a second start/send for the same task/chat
|
|
809
|
+
* while queued is rejected the same way an already-running one would be.
|
|
810
|
+
*/
|
|
811
|
+
private spawnOrQueue;
|
|
812
|
+
/** Tasks/chats currently waiting for a free maxConcurrentAgents slot. */
|
|
813
|
+
queued(): {
|
|
814
|
+
id: string;
|
|
815
|
+
queuedAt: string;
|
|
816
|
+
}[];
|
|
817
|
+
/** Start the next queued spawn once a slot is free (called from cleanup() on every exit). */
|
|
818
|
+
private drainQueue;
|
|
819
|
+
/**
|
|
820
|
+
* Spawn one turn and attach streaming. Everything after the spawn is async;
|
|
821
|
+
* failures surface as agent.exited via cleanup.
|
|
822
|
+
*/
|
|
823
|
+
private spawnTurn;
|
|
824
|
+
/** Line-buffer a chunk into the session transcript and stream it out. */
|
|
825
|
+
private onData;
|
|
826
|
+
/** Turn one buffered line into a transcript entry and stream it out. */
|
|
827
|
+
private appendLine;
|
|
828
|
+
/**
|
|
829
|
+
* Append a transcript entry, stream it out, and enforce the output cap.
|
|
830
|
+
* `sys` entries (self-heal notices) flow on the "out" stream, matching how
|
|
831
|
+
* parsed `error`/`file-update` events already surface as sys lines.
|
|
832
|
+
*/
|
|
833
|
+
private recordEntry;
|
|
834
|
+
/**
|
|
835
|
+
* Per-line bookkeeping shared by every append path: fold any usage/cost the
|
|
836
|
+
* line reported into the session and reset the stall clock. Any output is
|
|
837
|
+
* evidence the process isn't hung, so it resets the silence clock and clears
|
|
838
|
+
* a stall warning immediately — the periodic check only ever needs to raise
|
|
839
|
+
* the flag, never lower it.
|
|
840
|
+
*/
|
|
841
|
+
private lineTouched;
|
|
842
|
+
/**
|
|
843
|
+
* The claude stream-json branch of `appendLine` (0109). Recognized events
|
|
844
|
+
* map onto structured entries, or are swallowed when they have no transcript
|
|
845
|
+
* representation; anything else (a non-JSON `Warning: no stdin…` line, an
|
|
846
|
+
* unknown schema) falls back to the plain-line path so nothing the CLI said
|
|
847
|
+
* is lost.
|
|
848
|
+
*/
|
|
849
|
+
private appendClaudeLine;
|
|
850
|
+
/** Copilot's JSONL branch; unlike Claude, tool start/finish events stand alone. */
|
|
851
|
+
private appendCopilotLine;
|
|
852
|
+
/** Codex has one completed item per tool/message rather than Claude blocks. */
|
|
853
|
+
private appendCodexLine;
|
|
854
|
+
/** The transcript entry for a tool_use whose result never arrived. */
|
|
855
|
+
private pendingToolEntry;
|
|
856
|
+
/**
|
|
857
|
+
* Whether a raw line carries the exact capability-request `signal` in plain
|
|
858
|
+
* or structured output. Codex `--json` wraps the final assistant response in
|
|
859
|
+
* an `item.completed` event, so the signal is matched inside `item.text` too,
|
|
860
|
+
* not just as a standalone line.
|
|
861
|
+
*/
|
|
862
|
+
private signalPresent;
|
|
863
|
+
/** Recognize the exact handoff-request signal in plain or structured output. */
|
|
864
|
+
private isHandoffSignal;
|
|
865
|
+
/** Recognize the exact managed-preview request signal (#0121). */
|
|
866
|
+
private isPreviewRequestSignal;
|
|
867
|
+
/**
|
|
868
|
+
* Detect the runner's capability-request signals in one output line and act:
|
|
869
|
+
* the handoff signal is recorded for turn-end finalization, and the preview
|
|
870
|
+
* request is recorded for server-side start+probe at turn exit (#0121). The
|
|
871
|
+
* surfaced entry becomes a trusted system line so the raw signal text never
|
|
872
|
+
* clutters the transcript.
|
|
873
|
+
*
|
|
874
|
+
* When a handoff signal is recognized (#0235), the request is persisted to
|
|
875
|
+
* disk immediately so it survives an interrupted turn or server restart.
|
|
876
|
+
*/
|
|
877
|
+
private applySignals;
|
|
878
|
+
/**
|
|
879
|
+
* Fold any usage/cost found in a raw output line into the session. Returns
|
|
880
|
+
* true when a stored value actually changed (so callers only emit stats when
|
|
881
|
+
* there's something new to show). Also appends the raw event to
|
|
882
|
+
* `session_usage_events` — the lossless ground truth this rollup derives from.
|
|
883
|
+
*
|
|
884
|
+
* Three fold modes, matching `foldUsage`:
|
|
885
|
+
* - authoritative (claude `result`): the turn's real total FOR THIS PROCESS
|
|
886
|
+
* — added onto `usageBaseline` (prior processes' totals for this same
|
|
887
|
+
* session), not a bare overwrite, so a task resumed after review doesn't
|
|
888
|
+
* see its cumulative cost/tokens drop back down.
|
|
889
|
+
* - deltas (opencode `step_finish`): SUM — each event is one round-trip, and
|
|
890
|
+
* `Math.max` would keep only the largest step (0109 undercounted a
|
|
891
|
+
* 17-step reviewer run's cache-reads ~15x). Deltas accumulate directly on
|
|
892
|
+
* `cur`, so they're baseline-safe across process boundaries already.
|
|
893
|
+
* - otherwise (codex/claude running totals): Math.max against this
|
|
894
|
+
* process's own total plus baseline — count up, never flicker down on a
|
|
895
|
+
* transient mid-stream figure, and never dip below a prior process's
|
|
896
|
+
* total either.
|
|
897
|
+
*/
|
|
898
|
+
private applyUsage;
|
|
899
|
+
/**
|
|
900
|
+
* Append one raw usage-bearing line to `session_usage_events` before it is
|
|
901
|
+
* folded. Skips lines that carried no usage figure at all (the vast majority
|
|
902
|
+
* — text, tool calls, step_start). Best-effort; keyed by the CLI's own
|
|
903
|
+
* session id when known, else the runner key, plus the resolved task id and a
|
|
904
|
+
* timestamp so rows always correlate to a `sessions` row.
|
|
905
|
+
*/
|
|
906
|
+
private recordUsageEvent;
|
|
907
|
+
/** Emit the current live-stats snapshot for a task. */
|
|
908
|
+
private emitStats;
|
|
909
|
+
/** Compute a fresh stats snapshot — always safe to call, even with no session. */
|
|
910
|
+
private snapshotStats;
|
|
911
|
+
/**
|
|
912
|
+
* Periodic sweep (every `stallCheckIntervalMs`) over currently-running turns:
|
|
913
|
+
* raises the stall flag the moment silence crosses the threshold. Recovery
|
|
914
|
+
* (new output, or the turn exiting) is handled inline where it happens, so
|
|
915
|
+
* this only ever needs to turn the warning ON, never off.
|
|
916
|
+
* Also polls adopted entries (0214) for PID liveness: if the adopted PID
|
|
917
|
+
* died, clean up the entry so the task doesn't read as running forever.
|
|
918
|
+
*/
|
|
919
|
+
private checkStalls;
|
|
920
|
+
private tryExtractSessionId;
|
|
921
|
+
/**
|
|
922
|
+
* Signal a running agent to stop: graceful SIGTERM first, SIGKILL after a
|
|
923
|
+
* short grace period. Returns immediately; the registry clears on exit.
|
|
924
|
+
*/
|
|
925
|
+
stop(taskId: string): StopResult;
|
|
926
|
+
/**
|
|
927
|
+
* Interrupt a running AI chat response (PM, guide, debugger, …). Stops the
|
|
928
|
+
* in-flight agent process via {@link stop} and appends a persistent marker to
|
|
929
|
+
* the chat's transcript so the user sees the response was user-stopped rather
|
|
930
|
+
* than completed normally. Idempotent — safe to call when nothing is running.
|
|
931
|
+
*
|
|
932
|
+
* The marker is emitted server-side (so it survives a client hydrate, not just
|
|
933
|
+
* the live SSE stream) as a `sys` entry on the session. The agent's own exit
|
|
934
|
+
* also triggers the generic `agent.exited` "stopped" notice client-side.
|
|
935
|
+
*/
|
|
936
|
+
interrupt(taskId: string): StopResult;
|
|
937
|
+
/** Record a session to the database. Best-effort, never fails the server. */
|
|
938
|
+
private recordSessionToDb;
|
|
939
|
+
/** Drop the registry entry for a task (idempotent) and announce it. */
|
|
940
|
+
private cleanup;
|
|
941
|
+
/**
|
|
942
|
+
* Post-run session-id capture for Kiro CLI (#0148). Kiro does not print its
|
|
943
|
+
* session id during the run; after the process exits we query the CLI's local
|
|
944
|
+
* session list for the cwd and take the most-recently-updated entry — that is
|
|
945
|
+
* the turn that just finished. Best-effort and fail-soft: any failure leaves
|
|
946
|
+
* sessionId undefined so the next turn falls back to `-r` (most-recent resume).
|
|
947
|
+
*/
|
|
948
|
+
private captureKiroSessionId;
|
|
949
|
+
/**
|
|
950
|
+
* Snapshot a session's cumulative usage into `usageBaseline` right before a
|
|
951
|
+
* new CLI process is spawned for it (`start()` / `send()`), so an
|
|
952
|
+
* authoritative or running-total figure from THAT process — which starts
|
|
953
|
+
* counting at zero — is added onto prior processes' totals in `applyUsage`
|
|
954
|
+
* instead of replacing them.
|
|
955
|
+
*/
|
|
956
|
+
private captureUsageBaseline;
|
|
957
|
+
private emptySession;
|
|
958
|
+
private sessionFile;
|
|
959
|
+
/** Read and validate one versioned file. Corruption/version drift fails soft. */
|
|
960
|
+
private readPersisted;
|
|
961
|
+
private loadSession;
|
|
962
|
+
/** Boot only hot lifecycle states; completed transcripts remain cold. */
|
|
963
|
+
private loadHotSessions;
|
|
964
|
+
private schedulePersist;
|
|
965
|
+
/** Atomic temp-file + rename write; persistence remains best-effort. */
|
|
966
|
+
private persist;
|
|
967
|
+
private finishCompletion;
|
|
968
|
+
/** Remove completed files older than the age bound or beyond the count cap. */
|
|
969
|
+
private pruneSessions;
|
|
970
|
+
/**
|
|
971
|
+
* True when two absolute paths denote the same directory (realpath-normalized
|
|
972
|
+
* when possible, so macOS /var vs /private/var aliases compare equal).
|
|
973
|
+
*/
|
|
974
|
+
private samePath;
|
|
975
|
+
/**
|
|
976
|
+
* Persist a handoff failure reason to the task file's Activity log.
|
|
977
|
+
* Called when a handoff signal is expected but not detected, the process
|
|
978
|
+
* exits uncleanly before handoff can be finalized, or (from handoff.ts)
|
|
979
|
+
* server-side finalization itself fails. This persists the reason so it
|
|
980
|
+
* survives server reloads and lets the task watchdog classify the failure
|
|
981
|
+
* correctly instead of falling back to its generic guess (unlike
|
|
982
|
+
* in-memory transcript entries, which the watchdog cannot see).
|
|
983
|
+
*/
|
|
984
|
+
persistHandoffFailure(taskId: string, task: Task | undefined, reason: string): void;
|
|
985
|
+
/**
|
|
986
|
+
* Best-effort one-line summary of why a turn failed. Prefers the last
|
|
987
|
+
* non-empty stderr line (where CLI-level failures like an expired OAuth
|
|
988
|
+
* session land), falling back to the last `sys`/error line RepoOS itself
|
|
989
|
+
* parsed out of the CLI's own JSON stream, then a generic fallback.
|
|
990
|
+
*/
|
|
991
|
+
private lastFailureLine;
|
|
992
|
+
/**
|
|
993
|
+
* Flag a task for human attention the instant its agent turn ends non-
|
|
994
|
+
* cleanly (and isn't a deliberate pause or an in-flight handoff recovery —
|
|
995
|
+
* see the call site in cleanup()). Mirrors TaskWatchdog's own
|
|
996
|
+
* `needsInput` escalation, just fired immediately instead of waiting for
|
|
997
|
+
* the next staleness poll. Never overwrites an existing needsInput note.
|
|
998
|
+
*
|
|
999
|
+
* Also bumps `dev_error_count` — unlike the needsInput note, this always
|
|
1000
|
+
* increments, even on a repeat error before a human clears the flag,
|
|
1001
|
+
* because it counts real dev attempts, not distinct escalations (#0271
|
|
1002
|
+
* follow-up: confirmed live on #0291 — an engineer session that errors out
|
|
1003
|
+
* before ever reaching a review pass left `review_passes` at 0, so the
|
|
1004
|
+
* board's `D# · R#` badge showed nothing for a task that genuinely had one
|
|
1005
|
+
* failed dev round. TaskDrawer.vue's `taskRounds` folds this count into
|
|
1006
|
+
* `dev` so D can exceed R when a round errored without being reviewed.)
|
|
1007
|
+
*/
|
|
1008
|
+
private escalateFailedExit;
|
|
1009
|
+
/**
|
|
1010
|
+
* Self-heal the #0068 divergence. Narrowly scoped: ONLY the shape where the
|
|
1011
|
+
* main checkout's copy of the task is still `active` but the agent's
|
|
1012
|
+
* worktree copy shows `review` or `needs_input` backed by a real commit.
|
|
1013
|
+
* Any other state (task moved by a human, uncommitted worktree edit, no
|
|
1014
|
+
* separate worktree) is left untouched — this is not a general bidirectional
|
|
1015
|
+
* sync. The correction is surfaced (server log + a task.corrected event +
|
|
1016
|
+
* a transcript sys line) because it means the checklist itself failed.
|
|
1017
|
+
*/
|
|
1018
|
+
private healBoardDivergence;
|
|
1019
|
+
}
|
|
1020
|
+
export {};
|