@quickchatai/quickreview 1.1.0 → 1.3.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +137 -57
- package/bin/qcr.js +1 -1
- package/config.example.toml +60 -14
- package/deploy/ansible/README.md +20 -12
- package/deploy/ansible/inventory.example.ini +1 -1
- package/deploy/collect-secrets.sh +1 -1
- package/deploy/qcr-update.sh +1 -1
- package/dist/extensions/cli/home.js +14 -0
- package/dist/extensions/cli/home.js.map +1 -0
- package/dist/extensions/cli/login-route.js +5 -0
- package/dist/extensions/cli/login-route.js.map +1 -0
- package/dist/extensions/cli/selfimprove.js +18 -0
- package/dist/extensions/cli/selfimprove.js.map +1 -0
- package/dist/extensions/home.js +350 -0
- package/dist/extensions/home.js.map +1 -0
- package/dist/extensions/login-route.js +180 -0
- package/dist/extensions/login-route.js.map +1 -0
- package/dist/extensions/onboarding.js +35 -11
- package/dist/extensions/onboarding.js.map +1 -1
- package/dist/extensions/selfimprove.js +49 -0
- package/dist/extensions/selfimprove.js.map +1 -0
- package/dist/extensions/setup-scan.js +23 -592
- package/dist/extensions/setup-scan.js.map +1 -1
- package/dist/extensions/setup.js +2 -47
- package/dist/extensions/setup.js.map +1 -1
- package/dist/src/archive/restore.js +18 -15
- package/dist/src/archive/restore.js.map +1 -1
- package/dist/src/botworker.js +13 -2
- package/dist/src/botworker.js.map +1 -1
- package/dist/src/channelfs.js +3 -26
- package/dist/src/channelfs.js.map +1 -1
- package/dist/src/ciretry.js +2 -1
- package/dist/src/ciretry.js.map +1 -1
- package/dist/src/cli.js +54 -61
- package/dist/src/cli.js.map +1 -1
- package/dist/src/cliops.js +3 -2
- package/dist/src/cliops.js.map +1 -1
- package/dist/src/commands.js +25 -2
- package/dist/src/commands.js.map +1 -1
- package/dist/src/config.js +32 -2
- package/dist/src/config.js.map +1 -1
- package/dist/src/daemon.js +50 -8
- package/dist/src/daemon.js.map +1 -1
- package/dist/src/debuground.js +1 -0
- package/dist/src/debuground.js.map +1 -1
- package/dist/src/debugroundpi.js +6 -1
- package/dist/src/debugroundpi.js.map +1 -1
- package/dist/src/dispatch.js +5 -4
- package/dist/src/dispatch.js.map +1 -1
- package/dist/src/engine/caserunner-sdk.js +15 -251
- package/dist/src/engine/caserunner-sdk.js.map +1 -1
- package/dist/src/engine/debugpi.js +17 -5
- package/dist/src/engine/debugpi.js.map +1 -1
- package/dist/src/execboundary.js +10 -3
- package/dist/src/execboundary.js.map +1 -1
- package/dist/src/github.js +51 -16
- package/dist/src/github.js.map +1 -1
- package/dist/src/githubtoken.js +346 -0
- package/dist/src/githubtoken.js.map +1 -0
- package/dist/src/home/adapters.js +349 -0
- package/dist/src/home/adapters.js.map +1 -0
- package/dist/src/home/advanced.js +318 -0
- package/dist/src/home/advanced.js.map +1 -0
- package/dist/src/home/advancedtools.js +57 -0
- package/dist/src/home/advancedtools.js.map +1 -0
- package/dist/src/home/autoreview.js +325 -0
- package/dist/src/home/autoreview.js.map +1 -0
- package/dist/src/home/daemonstatus.js +32 -0
- package/dist/src/home/daemonstatus.js.map +1 -0
- package/dist/src/home/devicelogin.js +61 -0
- package/dist/src/home/devicelogin.js.map +1 -0
- package/dist/src/home/launch.js +202 -0
- package/dist/src/home/launch.js.map +1 -0
- package/dist/src/home/loginowner.js +205 -0
- package/dist/src/home/loginowner.js.map +1 -0
- package/dist/src/home/memory.js +122 -0
- package/dist/src/home/memory.js.map +1 -0
- package/dist/src/home/model.js +811 -0
- package/dist/src/home/model.js.map +1 -0
- package/dist/src/home/panel.js +520 -0
- package/dist/src/home/panel.js.map +1 -0
- package/dist/src/home/ports.js +19 -0
- package/dist/src/home/ports.js.map +1 -0
- package/dist/src/home/review.js +163 -0
- package/dist/src/home/review.js.map +1 -0
- package/dist/src/home/reviews.js +478 -0
- package/dist/src/home/reviews.js.map +1 -0
- package/dist/src/home/setup.js +507 -0
- package/dist/src/home/setup.js.map +1 -0
- package/dist/src/home/setupadapters.js +214 -0
- package/dist/src/home/setupadapters.js.map +1 -0
- package/dist/src/home/setupcard.js +199 -0
- package/dist/src/home/setupcard.js.map +1 -0
- package/dist/src/home/setuptools.js +45 -0
- package/dist/src/home/setuptools.js.map +1 -0
- package/dist/src/home/spend.js +160 -0
- package/dist/src/home/spend.js.map +1 -0
- package/dist/src/home/switches.js +209 -0
- package/dist/src/home/switches.js.map +1 -0
- package/dist/src/home/switchon.js +439 -0
- package/dist/src/home/switchon.js.map +1 -0
- package/dist/src/home/toolnames.js +41 -0
- package/dist/src/home/toolnames.js.map +1 -0
- package/dist/src/home/tune.js +341 -0
- package/dist/src/home/tune.js.map +1 -0
- package/dist/src/home/words.js +7 -0
- package/dist/src/home/words.js.map +1 -0
- package/dist/src/homes.js +14 -0
- package/dist/src/homes.js.map +1 -1
- package/dist/src/install.js +1 -1
- package/dist/src/install.js.map +1 -1
- package/dist/src/ipc/workerspec.js +8 -0
- package/dist/src/ipc/workerspec.js.map +1 -1
- package/dist/src/live/publish.js +1 -1
- package/dist/src/live/publish.js.map +1 -1
- package/dist/src/livecli.js +1 -1
- package/dist/src/livecli.js.map +1 -1
- package/dist/src/loginhint.js +8 -3
- package/dist/src/loginhint.js.map +1 -1
- package/dist/src/loginrefresh/handover.js +121 -0
- package/dist/src/loginrefresh/handover.js.map +1 -0
- package/dist/src/loginrefresh/lock.js +54 -3
- package/dist/src/loginrefresh/lock.js.map +1 -1
- package/dist/src/loginrefresh/pirefresh.js +3 -0
- package/dist/src/loginrefresh/pirefresh.js.map +1 -1
- package/dist/src/loginrefresh/refresher.js +33 -5
- package/dist/src/loginrefresh/refresher.js.map +1 -1
- package/dist/src/loginrefresh/supervisor.js +18 -1
- package/dist/src/loginrefresh/supervisor.js.map +1 -1
- package/dist/src/npmverbs.js +46 -14
- package/dist/src/npmverbs.js.map +1 -1
- package/dist/src/onboard/choices.js +35 -4
- package/dist/src/onboard/choices.js.map +1 -1
- package/dist/src/onboard/engine.js +32 -306
- package/dist/src/onboard/engine.js.map +1 -1
- package/dist/src/onboard/pipin.js +22 -0
- package/dist/src/onboard/pipin.js.map +1 -0
- package/dist/src/onboard/stepforward.js +41 -0
- package/dist/src/onboard/stepforward.js.map +1 -0
- package/dist/src/onboard/steps/appslug.js +4 -1
- package/dist/src/onboard/steps/appslug.js.map +1 -1
- package/dist/src/onboard/steps/bringup.js +3 -2
- package/dist/src/onboard/steps/bringup.js.map +1 -1
- package/dist/src/onboard/steps/compose.js +29 -0
- package/dist/src/onboard/steps/compose.js.map +1 -1
- package/dist/src/onboard/steps/configfill.js +120 -39
- package/dist/src/onboard/steps/configfill.js.map +1 -1
- package/dist/src/onboard/steps/githubaccount.js +595 -0
- package/dist/src/onboard/steps/githubaccount.js.map +1 -0
- package/dist/src/onboard/steps/githubapp.js +65 -7
- package/dist/src/onboard/steps/githubapp.js.map +1 -1
- package/dist/src/onboard/steps/golive.js +2 -0
- package/dist/src/onboard/steps/golive.js.map +1 -1
- package/dist/src/onboard/steps/index.js +11 -0
- package/dist/src/onboard/steps/index.js.map +1 -1
- package/dist/src/onboard/steps/ingress.js +80 -25
- package/dist/src/onboard/steps/ingress.js.map +1 -1
- package/dist/src/onboard/steps/llmauth.js +103 -30
- package/dist/src/onboard/steps/llmauth.js.map +1 -1
- package/dist/src/onboard/steps/loginshare.js +213 -0
- package/dist/src/onboard/steps/loginshare.js.map +1 -0
- package/dist/src/onboard/steps/memory.js +67 -3
- package/dist/src/onboard/steps/memory.js.map +1 -1
- package/dist/src/onboard/steps/proof.js +366 -56
- package/dist/src/onboard/steps/proof.js.map +1 -1
- package/dist/src/onboard/steps/repoconfig.js +72 -0
- package/dist/src/onboard/steps/repoconfig.js.map +1 -0
- package/dist/src/onboard/steps/topology.js +6 -6
- package/dist/src/onboard/steps/topology.js.map +1 -1
- package/dist/src/onboard/steps/transport.js +9 -1
- package/dist/src/onboard/steps/transport.js.map +1 -1
- package/dist/src/onboard/steps/tuiroute.js +102 -0
- package/dist/src/onboard/steps/tuiroute.js.map +1 -0
- package/dist/src/onboard/steps/verifyup.js +17 -1
- package/dist/src/onboard/steps/verifyup.js.map +1 -1
- package/dist/src/onboard/toolnames.js +30 -0
- package/dist/src/onboard/toolnames.js.map +1 -0
- package/dist/src/operatorwrite.js +23 -0
- package/dist/src/operatorwrite.js.map +1 -0
- package/dist/src/outcomes.js +4 -1
- package/dist/src/outcomes.js.map +1 -1
- package/dist/src/piagentdir.js +13 -0
- package/dist/src/piagentdir.js.map +1 -0
- package/dist/src/pilogin.js +31 -16
- package/dist/src/pilogin.js.map +1 -1
- package/dist/src/posting-journal.js +2 -1
- package/dist/src/posting-journal.js.map +1 -1
- package/dist/src/posting-outbox.js +6 -2
- package/dist/src/posting-outbox.js.map +1 -1
- package/dist/src/posting-receipt.js +14 -1
- package/dist/src/posting-receipt.js.map +1 -1
- package/dist/src/qcrbin.js +16 -11
- package/dist/src/qcrbin.js.map +1 -1
- package/dist/src/recheck.js +2 -1
- package/dist/src/recheck.js.map +1 -1
- package/dist/src/reconcile.js +22 -2
- package/dist/src/reconcile.js.map +1 -1
- package/dist/src/reviewargs.js +122 -0
- package/dist/src/reviewargs.js.map +1 -0
- package/dist/src/reviewcli.js +7 -161
- package/dist/src/reviewcli.js.map +1 -1
- package/dist/src/reviewdetach.js +76 -11
- package/dist/src/reviewdetach.js.map +1 -1
- package/dist/src/reviewhistory.js +32 -6
- package/dist/src/reviewhistory.js.map +1 -1
- package/dist/src/reviewnow.js +45 -0
- package/dist/src/reviewnow.js.map +1 -0
- package/dist/src/scancli.js +39 -691
- package/dist/src/scancli.js.map +1 -1
- package/dist/src/selfimprove.js +66 -0
- package/dist/src/selfimprove.js.map +1 -0
- package/dist/src/setup/adapters.js +5 -223
- package/dist/src/setup/adapters.js.map +1 -1
- package/dist/src/setup/caserunner.js +15 -249
- package/dist/src/setup/caserunner.js.map +1 -1
- package/dist/src/setup/engine.js +32 -341
- package/dist/src/setup/engine.js.map +1 -1
- package/dist/src/setup/facts.js +3 -592
- package/dist/src/setup/facts.js.map +1 -1
- package/dist/src/setup/findings.js +3 -947
- package/dist/src/setup/findings.js.map +1 -1
- package/dist/src/setup/presentation.js +3 -8
- package/dist/src/setup/presentation.js.map +1 -1
- package/dist/src/setup/scan.js +3 -724
- package/dist/src/setup/scan.js.map +1 -1
- package/dist/src/setup/scanbuild.js +9 -92
- package/dist/src/setup/scanbuild.js.map +1 -1
- package/dist/src/setup/scanlease.js +3 -250
- package/dist/src/setup/scanlease.js.map +1 -1
- package/dist/src/setup/scanreport.js +3 -288
- package/dist/src/setup/scanreport.js.map +1 -1
- package/dist/src/setup/scanrun.js +3 -1732
- package/dist/src/setup/scanrun.js.map +1 -1
- package/dist/src/setup/scantree.js +3 -256
- package/dist/src/setup/scantree.js.map +1 -1
- package/dist/src/setup/stage2request.js +3 -258
- package/dist/src/setup/stage2request.js.map +1 -1
- package/dist/src/setup/unitcut.js +3 -436
- package/dist/src/setup/unitcut.js.map +1 -1
- package/dist/src/state.js +2 -0
- package/dist/src/state.js.map +1 -1
- package/dist/src/statemachine.js +4 -1
- package/dist/src/statemachine.js.map +1 -1
- package/dist/src/takeover.js +1 -0
- package/dist/src/takeover.js.map +1 -1
- package/dist/src/takeoverpi.js +15 -1
- package/dist/src/takeoverpi.js.map +1 -1
- package/dist/src/tui/app.js +49 -0
- package/dist/src/tui/app.js.map +1 -1
- package/dist/src/tui/board.js +88 -12
- package/dist/src/tui/board.js.map +1 -1
- package/dist/src/tui/cmdbar.js +4 -1
- package/dist/src/tui/cmdbar.js.map +1 -1
- package/dist/src/tui/companion.js +76 -11
- package/dist/src/tui/companion.js.map +1 -1
- package/dist/src/tui/connect.js +7 -1
- package/dist/src/tui/connect.js.map +1 -1
- package/dist/src/tui/deploytab.js +2 -2
- package/dist/src/tui/deploytab.js.map +1 -1
- package/dist/src/tui/filters.js +5 -2
- package/dist/src/tui/filters.js.map +1 -1
- package/dist/src/tui/ghread.js +61 -5
- package/dist/src/tui/ghread.js.map +1 -1
- package/dist/src/tui/index.js +109 -20
- package/dist/src/tui/index.js.map +1 -1
- package/dist/src/tui/memforward.js +39 -2
- package/dist/src/tui/memforward.js.map +1 -1
- package/dist/src/tui/memory.js +3 -16
- package/dist/src/tui/memory.js.map +1 -1
- package/dist/src/tui/memoryurl.js +22 -0
- package/dist/src/tui/memoryurl.js.map +1 -0
- package/dist/src/tui/model.js +25 -0
- package/dist/src/tui/model.js.map +1 -1
- package/dist/src/tui/prpause.js +7 -0
- package/dist/src/tui/prpause.js.map +1 -1
- package/dist/src/tui/remote.js +7 -1
- package/dist/src/tui/remote.js.map +1 -1
- package/dist/src/tui/route.js +143 -0
- package/dist/src/tui/route.js.map +1 -0
- package/dist/src/tui/setupstate.js +32 -0
- package/dist/src/tui/setupstate.js.map +1 -0
- package/dist/src/tui/sshtriage.js +102 -5
- package/dist/src/tui/sshtriage.js.map +1 -1
- package/dist/src/tui/theme.js +2 -1
- package/dist/src/tui/theme.js.map +1 -1
- package/dist/src/tui/unwedge.js +2 -12
- package/dist/src/tui/unwedge.js.map +1 -1
- package/dist/src/verdicts.js +17 -5
- package/dist/src/verdicts.js.map +1 -1
- package/dist/src/version.js +1 -1
- package/dist/src/version.js.map +1 -1
- package/dist/src/webhook.js +12 -1
- package/dist/src/webhook.js.map +1 -1
- package/dist/src/wire.js +34 -8
- package/dist/src/wire.js.map +1 -1
- package/dist/src/workerworld.js +11 -1
- package/dist/src/workerworld.js.map +1 -1
- package/docker/README.md +1 -1
- package/docker/companion/entrypoint.sh +20 -1
- package/docker/entrypoint.sh +57 -6
- package/docker-compose.yml +16 -1
- package/extensions/cli/home.ts +14 -0
- package/extensions/cli/login-route.ts +10 -0
- package/extensions/cli/selfimprove.ts +18 -0
- package/extensions/home.ts +484 -0
- package/extensions/login-route.ts +220 -0
- package/extensions/onboarding.ts +41 -11
- package/extensions/selfimprove.ts +65 -0
- package/extensions/setup-scan.ts +79 -766
- package/extensions/setup.ts +14 -70
- package/package.json +6 -4
- package/prompts/onboarding.md +58 -18
- package/schemas/review-result.v1.json +60 -0
- package/scripts/deploy.sh +8 -6
- package/scripts/mint-token.sh +25 -4
- package/scripts/qcr-host.sh +28 -5
- package/scripts/vm-ghcr-login.sh +7 -4
- package/src/archive/restore.ts +18 -21
- package/src/botworker.ts +13 -2
- package/src/channelfs.ts +3 -26
- package/src/ciretry.ts +2 -1
- package/src/cli.ts +59 -67
- package/src/cliops.ts +3 -2
- package/src/commands.ts +28 -2
- package/src/config.ts +62 -4
- package/src/daemon.ts +58 -7
- package/src/debuground.ts +3 -0
- package/src/debugroundpi.ts +12 -1
- package/src/dispatch.ts +5 -4
- package/src/engine/caserunner-sdk.ts +29 -314
- package/src/engine/debugpi.ts +17 -5
- package/src/execboundary.ts +16 -4
- package/src/github.ts +57 -15
- package/src/githubtoken.ts +435 -0
- package/src/home/adapters.ts +418 -0
- package/src/home/advanced.ts +421 -0
- package/src/home/advancedtools.ts +96 -0
- package/src/home/autoreview.ts +385 -0
- package/src/home/daemonstatus.ts +55 -0
- package/src/home/devicelogin.ts +107 -0
- package/src/home/launch.ts +257 -0
- package/src/home/loginowner.ts +248 -0
- package/src/home/memory.ts +176 -0
- package/src/home/model.ts +965 -0
- package/src/home/panel.ts +666 -0
- package/src/home/ports.ts +338 -0
- package/src/home/review.ts +206 -0
- package/src/home/reviews.ts +565 -0
- package/src/home/setup.ts +689 -0
- package/src/home/setupadapters.ts +217 -0
- package/src/home/setupcard.ts +288 -0
- package/src/home/setuptools.ts +57 -0
- package/src/home/spend.ts +194 -0
- package/src/home/switches.ts +293 -0
- package/src/home/switchon.ts +554 -0
- package/src/home/toolnames.ts +46 -0
- package/src/home/tune.ts +405 -0
- package/src/home/words.ts +8 -0
- package/src/homes.ts +17 -0
- package/src/install.ts +1 -1
- package/src/ipc/workerspec.ts +15 -0
- package/src/live/publish.ts +4 -1
- package/src/livecli.ts +6 -1
- package/src/loginhint.ts +8 -3
- package/src/loginrefresh/handover.ts +138 -0
- package/src/loginrefresh/lock.ts +72 -3
- package/src/loginrefresh/pirefresh.ts +3 -0
- package/src/loginrefresh/refresher.ts +34 -5
- package/src/loginrefresh/supervisor.ts +25 -2
- package/src/npmverbs.ts +55 -13
- package/src/onboard/choices.ts +40 -4
- package/src/onboard/engine.ts +70 -421
- package/src/onboard/pipin.ts +31 -0
- package/src/onboard/stepforward.ts +61 -0
- package/src/onboard/steps/appslug.ts +4 -1
- package/src/onboard/steps/bringup.ts +3 -2
- package/src/onboard/steps/compose.ts +31 -0
- package/src/onboard/steps/configfill.ts +144 -40
- package/src/onboard/steps/githubaccount.ts +716 -0
- package/src/onboard/steps/githubapp.ts +92 -8
- package/src/onboard/steps/golive.ts +2 -0
- package/src/onboard/steps/index.ts +11 -0
- package/src/onboard/steps/ingress.ts +98 -31
- package/src/onboard/steps/llmauth.ts +114 -29
- package/src/onboard/steps/loginshare.ts +258 -0
- package/src/onboard/steps/memory.ts +76 -3
- package/src/onboard/steps/proof.ts +473 -55
- package/src/onboard/steps/repoconfig.ts +85 -0
- package/src/onboard/steps/topology.ts +7 -6
- package/src/onboard/steps/transport.ts +15 -0
- package/src/onboard/steps/tuiroute.ts +119 -0
- package/src/onboard/steps/verifyup.ts +20 -1
- package/src/onboard/toolnames.ts +34 -0
- package/src/operatorwrite.ts +25 -0
- package/src/outcomes.ts +8 -1
- package/src/piagentdir.ts +12 -0
- package/src/pilogin.ts +32 -16
- package/src/posting-journal.ts +6 -1
- package/src/posting-outbox.ts +10 -2
- package/src/posting-receipt.ts +17 -0
- package/src/qcrbin.ts +16 -11
- package/src/recheck.ts +2 -1
- package/src/reconcile.ts +29 -3
- package/src/reviewargs.ts +119 -0
- package/src/reviewcli.ts +6 -167
- package/src/reviewdetach.ts +107 -13
- package/src/reviewhistory.ts +20 -6
- package/src/reviewnow.ts +76 -0
- package/src/scancli.ts +75 -826
- package/src/selfimprove.ts +90 -0
- package/src/setup/adapters.ts +13 -221
- package/src/setup/caserunner.ts +34 -273
- package/src/setup/engine.ts +62 -496
- package/src/setup/facts.ts +3 -627
- package/src/setup/findings.ts +3 -1264
- package/src/setup/presentation.ts +3 -18
- package/src/setup/scan.ts +3 -1033
- package/src/setup/scanbuild.ts +20 -114
- package/src/setup/scanlease.ts +3 -297
- package/src/setup/scanreport.ts +3 -373
- package/src/setup/scanrun.ts +3 -2268
- package/src/setup/scantree.ts +3 -259
- package/src/setup/stage2request.ts +3 -347
- package/src/setup/unitcut.ts +3 -523
- package/src/state.ts +43 -0
- package/src/statemachine.ts +4 -1
- package/src/takeover.ts +5 -0
- package/src/takeoverpi.ts +16 -2
- package/src/tui/app.ts +47 -0
- package/src/tui/board.ts +111 -14
- package/src/tui/cmdbar.ts +4 -1
- package/src/tui/companion.ts +80 -11
- package/src/tui/connect.ts +7 -1
- package/src/tui/deploytab.ts +2 -2
- package/src/tui/filters.ts +7 -3
- package/src/tui/ghread.ts +74 -7
- package/src/tui/index.ts +117 -23
- package/src/tui/memforward.ts +52 -3
- package/src/tui/memory.ts +3 -15
- package/src/tui/memoryurl.ts +22 -0
- package/src/tui/model.ts +36 -2
- package/src/tui/prpause.ts +11 -2
- package/src/tui/remote.ts +9 -1
- package/src/tui/route.ts +173 -0
- package/src/tui/setupstate.ts +56 -0
- package/src/tui/sshtriage.ts +127 -6
- package/src/tui/theme.ts +2 -1
- package/src/tui/unwedge.ts +2 -14
- package/src/verdicts.ts +23 -5
- package/src/version.ts +1 -1
- package/src/webhook.ts +10 -1
- package/src/wire.ts +42 -9
- package/src/workerworld.ts +16 -2
- package/dist/src/live/projection.js +0 -450
- package/dist/src/live/projection.js.map +0 -1
- package/dist/src/live/read.js +0 -60
- package/dist/src/live/read.js.map +0 -1
- package/dist/src/onboard/launch.js +0 -83
- package/dist/src/onboard/launch.js.map +0 -1
- package/dist/src/setup/ledger.js +0 -207
- package/dist/src/setup/ledger.js.map +0 -1
- package/dist/src/setup/stage2.js +0 -617
- package/dist/src/setup/stage2.js.map +0 -1
- package/dist/src/setup/textsniff.js +0 -89
- package/dist/src/setup/textsniff.js.map +0 -1
- package/src/live/projection.ts +0 -491
- package/src/live/read.ts +0 -86
- package/src/onboard/launch.ts +0 -115
- package/src/setup/ledger.ts +0 -324
- package/src/setup/stage2.ts +0 -926
- package/src/setup/textsniff.ts +0 -95
package/src/wire.ts
CHANGED
|
@@ -30,7 +30,7 @@ import { Archiver } from "./archive/archiver.js";
|
|
|
30
30
|
import { piGlobalSessionsDir } from "./archive/piglobal.js";
|
|
31
31
|
import { runDirOf, toolUidSplit } from "./ipc/capability.js";
|
|
32
32
|
import { PermitBroker } from "./ipc/permits.js";
|
|
33
|
-
import { LoginRefreshSupervisor } from "./loginrefresh/supervisor.js";
|
|
33
|
+
import { LoginRefreshSupervisor, loginDirOf } from "./loginrefresh/supervisor.js";
|
|
34
34
|
import { pendingArchiveStatus } from "./archive/status.js";
|
|
35
35
|
import { Learner, learnerKnobsOf } from "./learner/learner.js";
|
|
36
36
|
import { renderNoPacketSection } from "./learner/packet.js";
|
|
@@ -54,7 +54,11 @@ import { priorSidecarPath } from "@quickchatai/pi-quickreview/src/priorfindings.
|
|
|
54
54
|
import { completeRecordedFindings } from "./recordedfindings.js";
|
|
55
55
|
import { makePostingGuard } from "@quickchatai/pi-quickreview/src/guards.js";
|
|
56
56
|
import { classifyCi, ciBlocksApproval } from "@quickchatai/pi-quickreview/src/cigate.js";
|
|
57
|
-
import {
|
|
57
|
+
import {
|
|
58
|
+
githubCredential,
|
|
59
|
+
type GitHubCredential,
|
|
60
|
+
} from "@quickchatai/pi-quickreview/src/githubAuth.js";
|
|
61
|
+
import { botAccountLogin, isPersonMode } from "@quickchatai/pi-quickreview/src/identity.js";
|
|
58
62
|
import {
|
|
59
63
|
FeedbackEngine,
|
|
60
64
|
FeedbackMemoryPump,
|
|
@@ -125,6 +129,7 @@ import {
|
|
|
125
129
|
} from "./openviking/provisionreport.js";
|
|
126
130
|
import { countedGapSink } from "./openviking/gapsink.js";
|
|
127
131
|
import { recoverPrForOperator } from "./operator-recovery.js";
|
|
132
|
+
import { reviewNow } from "./reviewnow.js";
|
|
128
133
|
import { createWorkerLiveness, inFlightPrs } from "./workerliveness.js";
|
|
129
134
|
import { resolveTerminalFailure } from "./terminal-failure.js";
|
|
130
135
|
import type { MemoryStore } from "./memory/store.js";
|
|
@@ -158,7 +163,8 @@ import { buildWorkerWorld } from "./workerworld.js";
|
|
|
158
163
|
export interface ProductionParts {
|
|
159
164
|
cfg: Config;
|
|
160
165
|
root: string;
|
|
161
|
-
|
|
166
|
+
/** The `[github] auth` credential: the App minter, or the person's token file. */
|
|
167
|
+
minter: GitHubCredential;
|
|
162
168
|
gate: MutationGate;
|
|
163
169
|
adapter: GitHubAdapter;
|
|
164
170
|
/** The tmux manager: it serves what has not moved to workers yet (the overseer) and
|
|
@@ -225,7 +231,7 @@ export function buildParts(
|
|
|
225
231
|
process.env.QCR_OPENVIKING_BOOT_DISABLED === "1" && overlaid.openviking.enabled
|
|
226
232
|
? "OpenViking state migration is incomplete; memory is unavailable for this boot — original files were retained; retry after correcting storage and restarting"
|
|
227
233
|
: undefined;
|
|
228
|
-
const minter =
|
|
234
|
+
const minter = githubCredential(cfg.github);
|
|
229
235
|
const gate: MutationGate = new MutationGate(
|
|
230
236
|
cfg.dry_run,
|
|
231
237
|
join(root, "state", "dryrun"),
|
|
@@ -764,6 +770,9 @@ export function createProductionDaemon(parts: ProductionParts = buildParts()): D
|
|
|
764
770
|
// src/workerworld.ts. No config key picks the tmux route, and nothing births a
|
|
765
771
|
// `pr-<n>` tmux session any more; `sessions` serves paths, worktrees and the replay harness.
|
|
766
772
|
const agentDir = process.env["PI_CODING_AGENT_DIR"]?.trim() || join(homedir(), ".pi", "agent");
|
|
773
|
+
// The login itself: the agent dir, or the host's shared login on a single
|
|
774
|
+
// box (one login per box): the refresher owns it and every worker borrows it.
|
|
775
|
+
const loginDir = loginDirOf(process.env, agentDir);
|
|
767
776
|
const workerWorld = buildWorkerWorld({
|
|
768
777
|
cfg,
|
|
769
778
|
root,
|
|
@@ -777,6 +786,7 @@ export function createProductionDaemon(parts: ProductionParts = buildParts()): D
|
|
|
777
786
|
...(parts.ovSessions ? { ovSessions: parts.ovSessions } : {}),
|
|
778
787
|
permits: lensPermits,
|
|
779
788
|
agentDir,
|
|
789
|
+
loginDir,
|
|
780
790
|
pump: () => daemon.pump(),
|
|
781
791
|
loginGate: {
|
|
782
792
|
paused: () => loginRefresh?.paused() ?? false,
|
|
@@ -1052,7 +1062,9 @@ export function createProductionDaemon(parts: ProductionParts = buildParts()): D
|
|
|
1052
1062
|
// the base clone; the daemon's own bot identity never qualifies.
|
|
1053
1063
|
directiveAuthor: (sha, paths) =>
|
|
1054
1064
|
sessions.worktrees.lastHumanAuthor(sha, paths, {
|
|
1055
|
-
|
|
1065
|
+
// Person mode has no bot account: the person's own commits are a
|
|
1066
|
+
// human's, and they may well be the one to mention.
|
|
1067
|
+
botLogins: isPersonMode(cfg.github) ? [] : [cfg.github.bot_login, cfg.github.app_slug],
|
|
1056
1068
|
}),
|
|
1057
1069
|
log,
|
|
1058
1070
|
// Lazy on purpose: the Slack subsystem is built in onStart, after the
|
|
@@ -1552,7 +1564,9 @@ export function createProductionDaemon(parts: ProductionParts = buildParts()): D
|
|
|
1552
1564
|
outcomes: d.outcomes,
|
|
1553
1565
|
memory,
|
|
1554
1566
|
repo: cfg.github.repo,
|
|
1555
|
-
|
|
1567
|
+
// The bot ACCOUNT, against captured human comments: none in person
|
|
1568
|
+
// mode, where the person's replies are a human's.
|
|
1569
|
+
botLogin: botAccountLogin(cfg.github),
|
|
1556
1570
|
healthy: () => health.currentState() === "healthy",
|
|
1557
1571
|
// No case batch starts while a review round reads memory (its seed,
|
|
1558
1572
|
// its lesson selection); every batch sent reports its embedding
|
|
@@ -1580,7 +1594,7 @@ export function createProductionDaemon(parts: ProductionParts = buildParts()): D
|
|
|
1580
1594
|
root,
|
|
1581
1595
|
eodTime: cfg.eod.time,
|
|
1582
1596
|
timeZone: cfg.eod.timezone,
|
|
1583
|
-
botLogin: cfg.github
|
|
1597
|
+
botLogin: botAccountLogin(cfg.github),
|
|
1584
1598
|
baseBranch: cfg.github.base_branch,
|
|
1585
1599
|
config: learnerKnobsOf(cfg.memory),
|
|
1586
1600
|
git: sessions.worktrees,
|
|
@@ -1617,7 +1631,7 @@ export function createProductionDaemon(parts: ProductionParts = buildParts()): D
|
|
|
1617
1631
|
if (cfg.login_refresh.enabled) {
|
|
1618
1632
|
loginRefresh = new LoginRefreshSupervisor({
|
|
1619
1633
|
repoRoot: root,
|
|
1620
|
-
agentDir,
|
|
1634
|
+
agentDir: loginDir,
|
|
1621
1635
|
marginMin: cfg.login_refresh.margin_min,
|
|
1622
1636
|
log,
|
|
1623
1637
|
// One anomaly per failure episode, through the one durable funnel.
|
|
@@ -1696,6 +1710,21 @@ export function createProductionDaemon(parts: ProductionParts = buildParts()): D
|
|
|
1696
1710
|
"restart-session",
|
|
1697
1711
|
);
|
|
1698
1712
|
},
|
|
1713
|
+
// The operator's "review this PR now" (the onboarding proof round):
|
|
1714
|
+
// the label path's state-machine trigger, with no GitHub write to ask.
|
|
1715
|
+
reviewNow(pr) {
|
|
1716
|
+
return reviewNow(
|
|
1717
|
+
{
|
|
1718
|
+
store: d.store,
|
|
1719
|
+
getPr: (n) => adapter.getPr(n),
|
|
1720
|
+
pump: () => d.pump(),
|
|
1721
|
+
// On the own-account route the bot login is the person, whose
|
|
1722
|
+
// own PRs are the point; only an App's bot is never reviewed.
|
|
1723
|
+
...(isPersonMode(cfg.github) ? {} : { botLogin: cfg.github.bot_login }),
|
|
1724
|
+
},
|
|
1725
|
+
pr,
|
|
1726
|
+
);
|
|
1727
|
+
},
|
|
1699
1728
|
resolveTerminalFailure(payload) {
|
|
1700
1729
|
return resolveTerminalFailure(
|
|
1701
1730
|
{
|
|
@@ -1861,7 +1890,9 @@ export function createProductionDaemon(parts: ProductionParts = buildParts()): D
|
|
|
1861
1890
|
// Webhook-URL self-heal: only under the tunnel-file ingress shape. The
|
|
1862
1891
|
// gated PATCH rides the app-self-config class, so it executes even in
|
|
1863
1892
|
// dry-run (AGENTS.md invariant 6) — loudly.
|
|
1864
|
-
|
|
1893
|
+
// Never under the person's credential: there is no App whose webhook
|
|
1894
|
+
// URL could be re-pointed (config load already refuses the shape).
|
|
1895
|
+
if (cfg.ingress.shape === "tunnel-file" && !isPersonMode(cfg.github)) {
|
|
1865
1896
|
webhookHeal = new WebhookHealer({
|
|
1866
1897
|
hostnameFile: ingressHostnameFile(cfg, root),
|
|
1867
1898
|
readConfig: () => adapter.getAppWebhookConfig(),
|
|
@@ -2112,6 +2143,8 @@ export function createProductionDaemon(parts: ProductionParts = buildParts()): D
|
|
|
2112
2143
|
adapter,
|
|
2113
2144
|
botLogin: cfg.github.bot_login,
|
|
2114
2145
|
guards: cfg.guards,
|
|
2146
|
+
// Person mode: every review event posts as COMMENT (guards.ts).
|
|
2147
|
+
personMode: isPersonMode(cfg.github),
|
|
2115
2148
|
log,
|
|
2116
2149
|
}),
|
|
2117
2150
|
);
|
package/src/workerworld.ts
CHANGED
|
@@ -18,6 +18,7 @@
|
|
|
18
18
|
// PiSessionManager that still exists serves what has not moved yet (the overseer, for now)
|
|
19
19
|
// and lends its path helpers and environment, which is what keeps a worker's session the same
|
|
20
20
|
// session a tmux round saw.
|
|
21
|
+
import { isPersonMode } from "@quickchatai/pi-quickreview/src/identity.js";
|
|
21
22
|
import { mkdirSync, readFileSync } from "node:fs";
|
|
22
23
|
import { join } from "node:path";
|
|
23
24
|
import { AnswerHost, answerCapsOf } from "./answerworker.js";
|
|
@@ -26,6 +27,7 @@ import type { Config } from "./config.js";
|
|
|
26
27
|
import { DebugRoundManager } from "./debuground.js";
|
|
27
28
|
import type { FileOutcome } from "./improvements.js";
|
|
28
29
|
import { identityVars } from "@quickchatai/pi-quickreview/src/include.js";
|
|
30
|
+
import { reviewProviders } from "@quickchatai/pi-quickreview/src/modelroute.js";
|
|
29
31
|
import {
|
|
30
32
|
CapabilityStore,
|
|
31
33
|
LaunchFiles,
|
|
@@ -88,8 +90,12 @@ export interface WorkerWorldOptions {
|
|
|
88
90
|
sessions: PiSessionManager;
|
|
89
91
|
ovSessions?: OvSessionLifecycle;
|
|
90
92
|
permits: PermitBroker;
|
|
91
|
-
/** pi's agent dir:
|
|
93
|
+
/** pi's agent dir: models.json, settings and the built lens agents. */
|
|
92
94
|
agentDir: string;
|
|
95
|
+
/** Where the login lives (the refresher keeps it): the agent dir, unless
|
|
96
|
+
* the single box's shared login is mounted elsewhere (supervisor.ts
|
|
97
|
+
* `loginDirOf`). */
|
|
98
|
+
loginDir?: string;
|
|
93
99
|
/** Run the daemon's pump (a lease freed, a worker gone). Late-bound: the daemon is built
|
|
94
100
|
* after this. */
|
|
95
101
|
pump: () => Promise<void>;
|
|
@@ -205,6 +211,8 @@ export function buildWorkerWorld(o: WorkerWorldOptions): WorkerWorld {
|
|
|
205
211
|
root,
|
|
206
212
|
cwd: root,
|
|
207
213
|
agent_dir: o.agentDir,
|
|
214
|
+
...(o.loginDir !== undefined && o.loginDir !== o.agentDir ? { login_dir: o.loginDir } : {}),
|
|
215
|
+
providers: reviewProviders(cfg),
|
|
208
216
|
session_dir: sessions.sessionDir(row.session),
|
|
209
217
|
system_prompt_file: sessions.writeSystemPrompt(row.session, prompt),
|
|
210
218
|
model: cfg.models.conversation,
|
|
@@ -223,6 +231,7 @@ export function buildWorkerWorld(o: WorkerWorldOptions): WorkerWorld {
|
|
|
223
231
|
const journal = new PostingJournal({
|
|
224
232
|
dir: join(stateDir, "posting-receipts"),
|
|
225
233
|
repo: cfg.github.repo,
|
|
234
|
+
personMode: isPersonMode(cfg.github),
|
|
226
235
|
});
|
|
227
236
|
|
|
228
237
|
// The takeover and debug managers are built before the supervisor (it takes their gates)
|
|
@@ -253,6 +262,7 @@ export function buildWorkerWorld(o: WorkerWorldOptions): WorkerWorld {
|
|
|
253
262
|
takeoverPlanFor({
|
|
254
263
|
root,
|
|
255
264
|
agentDir: o.agentDir,
|
|
265
|
+
...(o.loginDir !== undefined ? { loginDir: o.loginDir } : {}),
|
|
256
266
|
sessionsRoot: sessions.sessionsRoot(),
|
|
257
267
|
model: cfg.models.conversation,
|
|
258
268
|
pr,
|
|
@@ -311,7 +321,11 @@ export function buildWorkerWorld(o: WorkerWorldOptions): WorkerWorld {
|
|
|
311
321
|
store,
|
|
312
322
|
journal,
|
|
313
323
|
cfg,
|
|
314
|
-
|
|
324
|
+
// Marker-matched (posting-outbox.ts markedReviewsOf), so the person's
|
|
325
|
+
// login alone is safe in person mode: there is no App slug to add.
|
|
326
|
+
botLogins: isPersonMode(cfg.github)
|
|
327
|
+
? [cfg.github.bot_login]
|
|
328
|
+
: [cfg.github.bot_login, cfg.github.app_slug],
|
|
315
329
|
roundOf: commandRoundOf(store, headOf),
|
|
316
330
|
log,
|
|
317
331
|
},
|
|
@@ -1,450 +0,0 @@
|
|
|
1
|
-
// The round-progress v2 projection of a LiveEvent log.
|
|
2
|
-
//
|
|
3
|
-
// extensions/round-progress.ts publishes `state/round-progress/pr-<n>.json`
|
|
4
|
-
// (and the append-only transition log beside it) from inside the tmux pi, by
|
|
5
|
-
// listening to pi's events. This module reproduces both from the LiveEvent log
|
|
6
|
-
// alone, so the engine routes - which have no such extension - and a viewer
|
|
7
|
-
// reading a finished or running round all get the same snapshot, with the
|
|
8
|
-
// contract in packages/pi-plugin/src/round-progress.ts unchanged: board.ts, requiredpasses.ts and
|
|
9
|
-
// the supervisor read it as they always have.
|
|
10
|
-
//
|
|
11
|
-
// The extension is the REFERENCE. Every rule here mirrors the handler it
|
|
12
|
-
// stands for, line by line, because the golden test
|
|
13
|
-
// (tests/live-projection-golden.test.ts) holds the two byte-equal on the same
|
|
14
|
-
// events. The one place the log is coarser than pi's stream is time: a held
|
|
15
|
-
// update is stamped at its window's flush (~250 ms), so a heartbeat or a
|
|
16
|
-
// `started_at` taken from an update can differ from the extension's by that
|
|
17
|
-
// much. Nothing the supervisor decides on (the milestones' order, statuses,
|
|
18
|
-
// command identity) depends on it.
|
|
19
|
-
import { parseSessionCommandMarker } from "@quickchatai/pi-quickreview/src/session-command.js";
|
|
20
|
-
import { isLiveAgentStatus, } from "@quickchatai/pi-quickreview/src/round-progress.js";
|
|
21
|
-
function text(value) {
|
|
22
|
-
return typeof value === "string" && value.trim().length > 0 ? value.trim() : undefined;
|
|
23
|
-
}
|
|
24
|
-
function number(value) {
|
|
25
|
-
return typeof value === "number" && Number.isFinite(value) ? Math.max(0, value) : 0;
|
|
26
|
-
}
|
|
27
|
-
function status(value, exitCode) {
|
|
28
|
-
if (isLiveAgentStatus(value))
|
|
29
|
-
return value;
|
|
30
|
-
return exitCode === 0 ? "completed" : exitCode === undefined ? "running" : "failed";
|
|
31
|
-
}
|
|
32
|
-
/** The round number rides the order's posting calls (`QCR_ROUND_NO=<k>`, with
|
|
33
|
-
* or without `export`); the head rides the Worktree line. */
|
|
34
|
-
function reviewIdentity(body) {
|
|
35
|
-
const round = /(?:^|\s)(?:export )?QCR_ROUND_NO=(\d+)(?=\s|$)/.exec(body);
|
|
36
|
-
const head = /\*\*Worktree\*\*:[^\n]* @ `([^`]+)`/.exec(body);
|
|
37
|
-
if (!round || !head)
|
|
38
|
-
return undefined;
|
|
39
|
-
const roundNo = Number(round[1]);
|
|
40
|
-
return Number.isInteger(roundNo) && roundNo > 0
|
|
41
|
-
? { round_no: roundNo, head_sha: head[1] }
|
|
42
|
-
: undefined;
|
|
43
|
-
}
|
|
44
|
-
function currentTool(progress) {
|
|
45
|
-
if (!Array.isArray(progress?.recent_tools))
|
|
46
|
-
return undefined;
|
|
47
|
-
const tools = progress.recent_tools;
|
|
48
|
-
const picked = [...tools].reverse().find((x) => x.status === "running") ?? tools.at(-1);
|
|
49
|
-
if (!picked)
|
|
50
|
-
return undefined;
|
|
51
|
-
const name = text(picked.tool) ?? "tool";
|
|
52
|
-
const args = text(picked.args);
|
|
53
|
-
return args ? `${name}: ${args.slice(0, 120)}` : name;
|
|
54
|
-
}
|
|
55
|
-
function asAgent(result, fallbackAgent, live = false) {
|
|
56
|
-
const agent = text(result.agent) ?? fallbackAgent;
|
|
57
|
-
if (!agent)
|
|
58
|
-
return undefined;
|
|
59
|
-
const progress = result.progress;
|
|
60
|
-
const native = result.native ?? { tool_count: 0 };
|
|
61
|
-
const error = text(progress?.error) ?? text(result.error_message);
|
|
62
|
-
const exit = result.exit_code;
|
|
63
|
-
const nativeFailed = (typeof exit === "number" && exit > 0) ||
|
|
64
|
-
result.stop_reason === "error" ||
|
|
65
|
-
result.stop_reason === "aborted";
|
|
66
|
-
const st = isLiveAgentStatus(progress?.status)
|
|
67
|
-
? progress.status
|
|
68
|
-
: nativeFailed
|
|
69
|
-
? "failed"
|
|
70
|
-
: live || exit === -1 || exit === undefined
|
|
71
|
-
? "running"
|
|
72
|
-
: status(undefined, exit);
|
|
73
|
-
const tool = currentTool(progress) ?? (live ? native.last_tool : undefined);
|
|
74
|
-
const last = text(progress?.last_message) ?? native.last_text;
|
|
75
|
-
return {
|
|
76
|
-
agent,
|
|
77
|
-
status: st,
|
|
78
|
-
duration_ms: number(progress?.duration_ms),
|
|
79
|
-
tool_count: number(progress?.tool_count) || native.tool_count,
|
|
80
|
-
...(tool ? { current_tool: tool } : {}),
|
|
81
|
-
...(last ? { last_message: last } : {}),
|
|
82
|
-
...(error ? { error } : {}),
|
|
83
|
-
};
|
|
84
|
-
}
|
|
85
|
-
export class RoundProgressProjection {
|
|
86
|
-
who;
|
|
87
|
-
snapshotState;
|
|
88
|
-
written;
|
|
89
|
-
log = [];
|
|
90
|
-
lastHeartbeat = 0;
|
|
91
|
-
clock = "";
|
|
92
|
-
agents = new Map();
|
|
93
|
-
callAgents = new Map();
|
|
94
|
-
runKeys = new Map();
|
|
95
|
-
endLogged = new Set();
|
|
96
|
-
/** The children of each open lens call, rebuilt from the changed slots. */
|
|
97
|
-
calls = new Map();
|
|
98
|
-
constructor(who) {
|
|
99
|
-
this.who = who;
|
|
100
|
-
}
|
|
101
|
-
/** The snapshot as its file would hold it now (the last write). */
|
|
102
|
-
get snapshot() {
|
|
103
|
-
return this.written === undefined
|
|
104
|
-
? undefined
|
|
105
|
-
: JSON.parse(this.written);
|
|
106
|
-
}
|
|
107
|
-
/** The bytes of `pr-<n>.json`. */
|
|
108
|
-
get snapshotJson() {
|
|
109
|
-
return this.written;
|
|
110
|
-
}
|
|
111
|
-
/** The transition lines, in order. */
|
|
112
|
-
get transitions() {
|
|
113
|
-
return this.log;
|
|
114
|
-
}
|
|
115
|
-
/** The bytes of `pr-<n>.jsonl` (before its size-cap rotation). */
|
|
116
|
-
get transitionsJsonl() {
|
|
117
|
-
return this.log.map((l) => `${JSON.stringify(l)}\n`).join("");
|
|
118
|
-
}
|
|
119
|
-
apply(event) {
|
|
120
|
-
this.clock = event.at;
|
|
121
|
-
switch (event.type) {
|
|
122
|
-
case "agent_start":
|
|
123
|
-
return this.agentStart();
|
|
124
|
-
case "message_start":
|
|
125
|
-
return this.messageStart(event.role, event.text);
|
|
126
|
-
case "turn_start":
|
|
127
|
-
case "message_delta":
|
|
128
|
-
return this.heartbeat();
|
|
129
|
-
case "tool_start":
|
|
130
|
-
return this.toolStart(event);
|
|
131
|
-
case "tool_update":
|
|
132
|
-
return this.toolUpdate(event);
|
|
133
|
-
case "tool_end":
|
|
134
|
-
return this.toolEnd(event);
|
|
135
|
-
case "agent_settled":
|
|
136
|
-
return this.settled();
|
|
137
|
-
default:
|
|
138
|
-
return;
|
|
139
|
-
}
|
|
140
|
-
}
|
|
141
|
-
// ---- the extension's helpers --------------------------------------------------
|
|
142
|
-
nowIso() {
|
|
143
|
-
return this.clock;
|
|
144
|
-
}
|
|
145
|
-
bindRun(run, key) {
|
|
146
|
-
if (run === null)
|
|
147
|
-
return key;
|
|
148
|
-
const held = this.runKeys.get(run);
|
|
149
|
-
if (held !== undefined)
|
|
150
|
-
return held;
|
|
151
|
-
this.runKeys.set(run, key);
|
|
152
|
-
return key;
|
|
153
|
-
}
|
|
154
|
-
executionKeys(callId, names) {
|
|
155
|
-
const seen = new Map();
|
|
156
|
-
return names.map((agent) => {
|
|
157
|
-
const n = (seen.get(agent) ?? 0) + 1;
|
|
158
|
-
seen.set(agent, n);
|
|
159
|
-
return n === 1 ? `${callId}:${agent}` : `${callId}:${agent}#${n}`;
|
|
160
|
-
});
|
|
161
|
-
}
|
|
162
|
-
write() {
|
|
163
|
-
const snapshot = this.snapshotState;
|
|
164
|
-
if (!snapshot)
|
|
165
|
-
return;
|
|
166
|
-
snapshot.updated_at = this.nowIso();
|
|
167
|
-
snapshot.agents = [...this.agents.values()];
|
|
168
|
-
this.written = `${JSON.stringify(snapshot)}\n`;
|
|
169
|
-
}
|
|
170
|
-
transition(entry) {
|
|
171
|
-
const snapshot = this.snapshotState;
|
|
172
|
-
if (!snapshot)
|
|
173
|
-
return;
|
|
174
|
-
this.log.push({
|
|
175
|
-
at: this.nowIso(),
|
|
176
|
-
pr: this.who.pr,
|
|
177
|
-
session: this.who.session,
|
|
178
|
-
run_started_at: snapshot.run_started_at,
|
|
179
|
-
...(snapshot.command_id ? { command_id: snapshot.command_id } : {}),
|
|
180
|
-
...entry,
|
|
181
|
-
});
|
|
182
|
-
}
|
|
183
|
-
passEnded(agent) {
|
|
184
|
-
const key = agent.execution_id;
|
|
185
|
-
if (!key || agent.status === "running" || this.endLogged.has(key))
|
|
186
|
-
return;
|
|
187
|
-
this.endLogged.add(key);
|
|
188
|
-
this.transition({
|
|
189
|
-
event: "pass_end",
|
|
190
|
-
execution_id: key,
|
|
191
|
-
agent: agent.agent,
|
|
192
|
-
status: agent.status,
|
|
193
|
-
});
|
|
194
|
-
}
|
|
195
|
-
fanoutSeen() {
|
|
196
|
-
const snapshot = this.snapshotState;
|
|
197
|
-
if (!snapshot || this.agents.size === 0)
|
|
198
|
-
return;
|
|
199
|
-
snapshot.first_lens_started_at ??= this.nowIso();
|
|
200
|
-
snapshot.fanout_started_at ??= snapshot.first_lens_started_at;
|
|
201
|
-
}
|
|
202
|
-
activity(description) {
|
|
203
|
-
const snapshot = this.snapshotState;
|
|
204
|
-
if (!snapshot)
|
|
205
|
-
return;
|
|
206
|
-
snapshot.last_activity = description;
|
|
207
|
-
snapshot.last_activity_at = this.nowIso();
|
|
208
|
-
this.write();
|
|
209
|
-
}
|
|
210
|
-
heartbeat() {
|
|
211
|
-
if (!this.snapshotState)
|
|
212
|
-
return;
|
|
213
|
-
const now = Date.parse(this.clock);
|
|
214
|
-
if (now - this.lastHeartbeat < 1_000)
|
|
215
|
-
return;
|
|
216
|
-
this.lastHeartbeat = now;
|
|
217
|
-
this.write();
|
|
218
|
-
}
|
|
219
|
-
freshSnapshot(lastActivity) {
|
|
220
|
-
const at = this.nowIso();
|
|
221
|
-
this.agents.clear();
|
|
222
|
-
this.callAgents.clear();
|
|
223
|
-
this.runKeys.clear();
|
|
224
|
-
this.endLogged.clear();
|
|
225
|
-
return {
|
|
226
|
-
version: 2,
|
|
227
|
-
pr: this.who.pr,
|
|
228
|
-
session: this.who.session,
|
|
229
|
-
run_started_at: at,
|
|
230
|
-
updated_at: at,
|
|
231
|
-
parent_status: "active",
|
|
232
|
-
last_activity_at: at,
|
|
233
|
-
last_activity: lastActivity,
|
|
234
|
-
agents: [],
|
|
235
|
-
};
|
|
236
|
-
}
|
|
237
|
-
/** The children of a call after this line: the slots it carries laid over
|
|
238
|
-
* what the call's earlier lines left. */
|
|
239
|
-
merge(id, n, changed) {
|
|
240
|
-
const held = this.calls.get(id) ?? [];
|
|
241
|
-
for (const r of changed)
|
|
242
|
-
held[r.slot] = r;
|
|
243
|
-
const full = Array.from({ length: n }, (_, slot) => held[slot] ?? { slot });
|
|
244
|
-
this.calls.set(id, full);
|
|
245
|
-
return full;
|
|
246
|
-
}
|
|
247
|
-
// ---- the handlers ---------------------------------------------------------------
|
|
248
|
-
agentStart() {
|
|
249
|
-
// pi's automatic retry or queued continuation emits another agent_start
|
|
250
|
-
// inside the SAME outer run: an inner start keeps the run's command,
|
|
251
|
-
// milestones and passes.
|
|
252
|
-
if (this.snapshotState && this.snapshotState.parent_status === "active") {
|
|
253
|
-
this.activity("parent run continued");
|
|
254
|
-
return;
|
|
255
|
-
}
|
|
256
|
-
this.snapshotState = this.freshSnapshot("parent run started");
|
|
257
|
-
this.write();
|
|
258
|
-
this.transition({ event: "parent_start" });
|
|
259
|
-
}
|
|
260
|
-
messageStart(role, body) {
|
|
261
|
-
const snapshot = this.snapshotState;
|
|
262
|
-
if (!snapshot || role !== "user" || !body)
|
|
263
|
-
return;
|
|
264
|
-
const marker = parseSessionCommandMarker(body);
|
|
265
|
-
if (!marker)
|
|
266
|
-
return;
|
|
267
|
-
// A different command in a run that has one already is a new execution.
|
|
268
|
-
let current = snapshot;
|
|
269
|
-
if (current.command_id !== undefined && current.command_id !== marker.id) {
|
|
270
|
-
current = this.freshSnapshot("parent run started");
|
|
271
|
-
this.snapshotState = current;
|
|
272
|
-
}
|
|
273
|
-
current.command_id = marker.id;
|
|
274
|
-
current.command_sha256 = marker.payloadSha256;
|
|
275
|
-
const identity = reviewIdentity(body);
|
|
276
|
-
if (identity) {
|
|
277
|
-
current.round_no = identity.round_no;
|
|
278
|
-
current.head_sha = identity.head_sha;
|
|
279
|
-
}
|
|
280
|
-
const firstAcceptance = current.command_accepted_at === undefined;
|
|
281
|
-
current.command_accepted_at ??= this.nowIso();
|
|
282
|
-
current.preparing_at ??= current.command_accepted_at;
|
|
283
|
-
if (firstAcceptance)
|
|
284
|
-
this.transition({
|
|
285
|
-
event: "command_accepted",
|
|
286
|
-
...(current.round_no !== undefined ? { round_no: current.round_no } : {}),
|
|
287
|
-
...(current.head_sha !== undefined ? { head_sha: current.head_sha } : {}),
|
|
288
|
-
});
|
|
289
|
-
this.activity(`command ${marker.id} accepted; parent preparing compact fanout context`);
|
|
290
|
-
}
|
|
291
|
-
toolStart(ev) {
|
|
292
|
-
const snapshot = this.snapshotState;
|
|
293
|
-
if (!snapshot)
|
|
294
|
-
return;
|
|
295
|
-
const executions = ev.executions ?? [];
|
|
296
|
-
if (executions.length > 0) {
|
|
297
|
-
const names = executions.map(({ agent }) => agent);
|
|
298
|
-
const at = this.nowIso();
|
|
299
|
-
this.callAgents.set(ev.id, names);
|
|
300
|
-
const keys = this.executionKeys(ev.id, names);
|
|
301
|
-
for (const [index, agent] of names.entries()) {
|
|
302
|
-
const key = keys[index];
|
|
303
|
-
const phase = executions[index]?.phase;
|
|
304
|
-
this.agents.set(key, {
|
|
305
|
-
execution_id: key,
|
|
306
|
-
agent,
|
|
307
|
-
...(phase ? { phase } : {}),
|
|
308
|
-
status: "running",
|
|
309
|
-
duration_ms: 0,
|
|
310
|
-
tool_count: 0,
|
|
311
|
-
started_at: at,
|
|
312
|
-
});
|
|
313
|
-
this.transition({ event: "pass_start", execution_id: key, agent });
|
|
314
|
-
}
|
|
315
|
-
snapshot.first_lens_started_at ??= at;
|
|
316
|
-
snapshot.fanout_started_at ??= snapshot.first_lens_started_at;
|
|
317
|
-
snapshot.active_tool = `subagent: ${names.join(", ")}`;
|
|
318
|
-
this.activity(`${names.join(", ")} started`);
|
|
319
|
-
return;
|
|
320
|
-
}
|
|
321
|
-
snapshot.active_tool = ev.preview ? `${ev.tool}: ${ev.preview}` : ev.tool;
|
|
322
|
-
this.activity(snapshot.active_tool);
|
|
323
|
-
}
|
|
324
|
-
toolUpdate(ev) {
|
|
325
|
-
const snapshot = this.snapshotState;
|
|
326
|
-
if (!snapshot)
|
|
327
|
-
return;
|
|
328
|
-
const fallbacks = this.callAgents.get(ev.id) ?? [];
|
|
329
|
-
const reported = this.merge(ev.id, ev.n, ev.results);
|
|
330
|
-
// Native parallel mode marks a still-running slot with exitCode -1 and a
|
|
331
|
-
// finished one with its real exit code.
|
|
332
|
-
let changed = false;
|
|
333
|
-
const updated = reported.flatMap((result, index) => {
|
|
334
|
-
const agent = asAgent(result, fallbacks[index] ?? (fallbacks.length === 1 ? fallbacks[0] : undefined), ev.mode === "parallel" ? result.exit_code === -1 : true);
|
|
335
|
-
return agent ? [{ agent, run: result.id ?? null }] : [];
|
|
336
|
-
});
|
|
337
|
-
const updateKeys = this.executionKeys(ev.id, updated.map(({ agent }) => agent.agent));
|
|
338
|
-
for (const [index, { agent, run }] of updated.entries()) {
|
|
339
|
-
const key = this.bindRun(run, updateKeys[index]);
|
|
340
|
-
const previous = this.agents.get(key);
|
|
341
|
-
// A parallel slot can finish while its siblings still run: a terminal
|
|
342
|
-
// record carries its completion milestone from the first update that
|
|
343
|
-
// reports it, and a running one never carries one.
|
|
344
|
-
const { finished_at: previousFinished, ...kept } = previous ?? {};
|
|
345
|
-
const next = {
|
|
346
|
-
...kept,
|
|
347
|
-
...agent,
|
|
348
|
-
execution_id: key,
|
|
349
|
-
started_at: previous?.started_at ?? this.nowIso(),
|
|
350
|
-
...(agent.status === "running" ? {} : { finished_at: previousFinished ?? this.nowIso() }),
|
|
351
|
-
};
|
|
352
|
-
this.agents.set(key, next);
|
|
353
|
-
this.passEnded(next);
|
|
354
|
-
snapshot.active_tool = `subagent: ${agent.agent}`;
|
|
355
|
-
changed = true;
|
|
356
|
-
}
|
|
357
|
-
this.fanoutSeen();
|
|
358
|
-
if (changed)
|
|
359
|
-
this.write();
|
|
360
|
-
else
|
|
361
|
-
this.heartbeat();
|
|
362
|
-
}
|
|
363
|
-
toolEnd(ev) {
|
|
364
|
-
const snapshot = this.snapshotState;
|
|
365
|
-
if (!snapshot)
|
|
366
|
-
return;
|
|
367
|
-
const id = ev.id;
|
|
368
|
-
const fallbacks = this.callAgents.get(id) ?? [];
|
|
369
|
-
const reported = this.merge(id, ev.n, ev.results);
|
|
370
|
-
this.calls.delete(id);
|
|
371
|
-
const finalAgents = [];
|
|
372
|
-
const ended = reported.flatMap((result, index) => {
|
|
373
|
-
const agent = asAgent(result, fallbacks[index] ?? (fallbacks.length === 1 ? fallbacks[0] : undefined));
|
|
374
|
-
return agent ? [{ agent, run: result.id ?? null }] : [];
|
|
375
|
-
});
|
|
376
|
-
const endKeys = this.executionKeys(id, ended.map(({ agent }) => agent.agent));
|
|
377
|
-
for (const [index, { agent, run }] of ended.entries()) {
|
|
378
|
-
const key = this.bindRun(run, endKeys[index]);
|
|
379
|
-
const previous = this.agents.get(key);
|
|
380
|
-
// A child the call returns still running (a placeholder) carries no
|
|
381
|
-
// finish time, as in toolUpdate: the parser refuses the pair.
|
|
382
|
-
const { finished_at: previousFinished, ...kept } = previous ?? {};
|
|
383
|
-
const finalAgent = {
|
|
384
|
-
...kept,
|
|
385
|
-
...agent,
|
|
386
|
-
execution_id: key,
|
|
387
|
-
started_at: previous?.started_at ?? this.nowIso(),
|
|
388
|
-
...(agent.status === "running" ? {} : { finished_at: previousFinished ?? this.nowIso() }),
|
|
389
|
-
};
|
|
390
|
-
this.agents.set(key, finalAgent);
|
|
391
|
-
finalAgents.push(finalAgent);
|
|
392
|
-
this.passEnded(finalAgent);
|
|
393
|
-
}
|
|
394
|
-
if (finalAgents.length === 0 && fallbacks.length > 0) {
|
|
395
|
-
const failed = ev.is_error;
|
|
396
|
-
const fallbackKeys = this.executionKeys(id, fallbacks);
|
|
397
|
-
for (const [index, fallback] of fallbacks.entries()) {
|
|
398
|
-
const key = fallbackKeys[index];
|
|
399
|
-
const previous = this.agents.get(key);
|
|
400
|
-
if (previous && previous.status !== "running") {
|
|
401
|
-
finalAgents.push(previous);
|
|
402
|
-
continue;
|
|
403
|
-
}
|
|
404
|
-
const finalAgent = {
|
|
405
|
-
...(previous ?? {
|
|
406
|
-
execution_id: key,
|
|
407
|
-
agent: fallback,
|
|
408
|
-
duration_ms: 0,
|
|
409
|
-
tool_count: 0,
|
|
410
|
-
started_at: this.nowIso(),
|
|
411
|
-
}),
|
|
412
|
-
status: failed ? "failed" : "completed",
|
|
413
|
-
finished_at: previous?.finished_at ?? this.nowIso(),
|
|
414
|
-
};
|
|
415
|
-
this.agents.set(key, finalAgent);
|
|
416
|
-
finalAgents.push(finalAgent);
|
|
417
|
-
this.passEnded(finalAgent);
|
|
418
|
-
}
|
|
419
|
-
}
|
|
420
|
-
this.fanoutSeen();
|
|
421
|
-
this.callAgents.delete(id);
|
|
422
|
-
snapshot.active_tool = undefined;
|
|
423
|
-
this.activity(finalAgents.length > 0
|
|
424
|
-
? `${finalAgents.map((agent) => `${agent.agent} ${agent.status}`).join(", ")}`
|
|
425
|
-
: `${ev.tool} ${ev.is_error ? "failed" : "completed"}`);
|
|
426
|
-
}
|
|
427
|
-
settled() {
|
|
428
|
-
const snapshot = this.snapshotState;
|
|
429
|
-
if (!snapshot)
|
|
430
|
-
return;
|
|
431
|
-
snapshot.parent_status = "settled";
|
|
432
|
-
snapshot.active_tool = undefined;
|
|
433
|
-
this.activity("parent session settled");
|
|
434
|
-
this.transition({ event: "parent_settle" });
|
|
435
|
-
}
|
|
436
|
-
}
|
|
437
|
-
/** Project a main log. The identity (PR, session) comes from its
|
|
438
|
-
* `session_start` line; a log with none, or for a round that has no PR number,
|
|
439
|
-
* projects to nothing - as the extension does nothing outside a numbered PR
|
|
440
|
-
* session. */
|
|
441
|
-
export function projectRoundProgress(events) {
|
|
442
|
-
const start = events.find((e) => e.type === "session_start");
|
|
443
|
-
if (start?.type !== "session_start" || start.stream !== "main" || start.pr === null)
|
|
444
|
-
return undefined;
|
|
445
|
-
const projection = new RoundProgressProjection({ pr: start.pr, session: start.session });
|
|
446
|
-
for (const e of events)
|
|
447
|
-
projection.apply(e);
|
|
448
|
-
return projection;
|
|
449
|
-
}
|
|
450
|
-
//# sourceMappingURL=projection.js.map
|