@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/README.md
CHANGED
|
@@ -18,17 +18,27 @@ for one kind of problem and never see each other's output. It merges their
|
|
|
18
18
|
findings so one root cause gets one comment, and an **adversarial validator
|
|
19
19
|
re-derives every candidate from the code** before one review is posted.
|
|
20
20
|
|
|
21
|
+
<picture>
|
|
22
|
+
<source media="(prefers-color-scheme: dark)" srcset="docs/media/bench-hero-dark.png">
|
|
23
|
+
<img src="docs/media/bench-hero.png" alt="AACR-Bench, 185 real PRs, 520 verified defects, QuickReview on GPT-6.1 Sol against six other reviewers, share found at each severity. High (90 defects): QuickReview 97%, next best Codex CLI 90%. Medium (145): QuickReview 93%, next best pi-review panel 82%. Low (285): QuickReview 84%, next best pi-review panel 52%.">
|
|
24
|
+
</picture>
|
|
25
|
+
|
|
26
|
+
On 185 real PRs with 520 defects each verified in the code, QuickReview on
|
|
27
|
+
GPT-6.1 Sol finds **97% of the high-severity defects, 93% of the medium and
|
|
28
|
+
84% of the low**; at each severity the best of the six other reviewers we ran
|
|
29
|
+
finds 90%, 82% and 52%. On the same model it also finds more than the model
|
|
30
|
+
maker's own reviewer at every severity: against Claude Code's `/code-review`
|
|
31
|
+
on Claude Opus 5.5 and against Codex CLI on GPT-6.1 Sol. Its last changes were
|
|
32
|
+
mined from its misses on 145 of the 185 PRs; on the 20 kept out, it finds 83%
|
|
33
|
+
of all defects and the next best 72%. That recall costs more: about $2 and
|
|
34
|
+
17.5 minutes per PR, where the other tools take $0.07–0.53 and 0.7–2.3
|
|
35
|
+
minutes ([Benchmarks](#benchmarks)).
|
|
36
|
+
|
|
21
37
|
<p align="center">
|
|
22
38
|
<img src="docs/media/lenses.gif" width="800"
|
|
23
39
|
alt="Animation: nine lens passes sweep the same diff in parallel, each marking the lines where it finds a problem; findings that share a root cause merge, eight candidates into six causes; the validator re-derives each from the code, keeps four and strikes two with a reason (below the bar; refuted); the four survivors become one posted review, three blockers and one question, marked REQUEST_CHANGES.">
|
|
24
40
|
</p>
|
|
25
41
|
|
|
26
|
-
On 185 real PRs with 520 defects each verified in the code, it finds
|
|
27
|
-
**97% of the high-severity defects and 89% of all of them**; the strongest
|
|
28
|
-
third-party configuration we measured finds 67%. That recall costs more:
|
|
29
|
-
about $2 and 17 minutes per PR, where the other tools take $0.07–0.53 and
|
|
30
|
-
0.7–2.3 minutes ([Benchmarks](#benchmarks)).
|
|
31
|
-
|
|
32
42
|
Around the review sits a small, deterministic TypeScript daemon with no LLM
|
|
33
43
|
in its decision path. It takes GitHub App webhooks, runs an authoritative
|
|
34
44
|
reconcile poll, keeps one sticky [pi](https://github.com/earendil-works/pi)
|
|
@@ -70,22 +80,37 @@ The lens catalogue, with each lens's trigger and severity cap, is §3.3 of the
|
|
|
70
80
|
|
|
71
81
|
Recall is the headline: a review that misses the defect has failed, whatever
|
|
72
82
|
else it does. Precision, cost and time are shown beside it, because that is
|
|
73
|
-
where QuickReview pays.
|
|
74
|
-
`gpt-6.1-sol`, shipped
|
|
75
|
-
|
|
76
|
-
|
|
83
|
+
where QuickReview pays. Unless a chart or table names another build or model,
|
|
84
|
+
its results are the frozen build of 2026-10-04 on `gpt-6.1-sol`, shipped
|
|
85
|
+
defaults, one review per PR. The third-party tools we ran used the best
|
|
86
|
+
configuration we found for each (except Claude Code, which ran `/code-review`
|
|
87
|
+
at its default effort and was not varied), the OpenAI-based ones on the same
|
|
88
|
+
model, under the same judge on the same PRs.
|
|
89
|
+
|
|
90
|
+
**AACR-Bench, verified defects.** AACR-Bench's own reference comments are
|
|
91
|
+
mostly not real problems, so we built a key of 520 defects, each verified in
|
|
92
|
+
the code and graded by its consequence: **high** would block a merge (a
|
|
93
|
+
user-visible bug on a normal path, a crash, data loss, a security hole, a
|
|
94
|
+
broken build), **medium** should be fixed before merge, **low** is real but
|
|
95
|
+
fine as a follow-up. The chart at the top is this key. QuickReview misses 2.5
|
|
96
|
+
of the 90 high-severity defects, 10.5 of the 145 medium and 46 of the 285 low
|
|
97
|
+
(a partly found defect counts as half); the best other reviewer at each
|
|
98
|
+
severity misses 9, 26 and 136.5. Over the panel and Codex CLI the
|
|
99
|
+
high-severity lead holds under a paired bootstrap (+8.3 points [+1.9, +14.6]
|
|
100
|
+
over the panel). The price: 6.9 comments per PR, 42% of them true but minor.
|
|
77
101
|
|
|
78
102
|
<picture>
|
|
79
|
-
<source media="(prefers-color-scheme: dark)" srcset="docs/media/bench-
|
|
80
|
-
<img src="docs/media/bench-
|
|
103
|
+
<source media="(prefers-color-scheme: dark)" srcset="docs/media/bench-same-model-dark.png">
|
|
104
|
+
<img src="docs/media/bench-same-model.png" alt="AACR-Bench, the same base model in two reviewers, one judge, share found at high, medium and low severity. Claude Opus 5.5, 40 PRs: QuickReview 94%, 98%, 93%; Claude Code /code-review 75%, 71%, 45%. GPT-6.1 Sol, 185 PRs: QuickReview 97%, 93%, 84%; Codex CLI at high 90%, 70%, 37%. GPT-6 Sol, 185 PRs: QuickReview 96%, 86%, 80%; Codex CLI as shipped 78%, 61%, 31%.">
|
|
81
105
|
</picture>
|
|
82
106
|
|
|
83
|
-
**
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
107
|
+
**Same model, two reviewers.** With the model held fixed, QuickReview still
|
|
108
|
+
finds more than the model maker's own reviewer on each of the three models
|
|
109
|
+
where we ran both, at 11 to 20 times the cost ($3.24 against $0.16 per PR on
|
|
110
|
+
Opus). This contrasts two tools, not a measured design effect: they also
|
|
111
|
+
differ in budget and inputs, Claude Code ran `/code-review` at its default
|
|
112
|
+
effort, the Opus and GPT-6 Sol rows are September builds of QuickReview, and
|
|
113
|
+
the 40 Opus PRs are all PRs QuickReview was tuned on.
|
|
89
114
|
|
|
90
115
|
<picture>
|
|
91
116
|
<source media="(prefers-color-scheme: dark)" srcset="docs/media/bench-martian-dark.png">
|
|
@@ -97,7 +122,7 @@ per PR and counts every other comment as a false positive. It extracts about
|
|
|
97
122
|
12.8 issues per PR from QuickReview's reviews, so QuickReview has the highest
|
|
98
123
|
recall and the lowest precision. We
|
|
99
124
|
audited the goldens: of the 86 that describe a real defect the PR
|
|
100
|
-
introduces, it finds 75 (87%), the most of
|
|
125
|
+
introduces, it finds 75 (87%), the most of the seven reviewers judged alike.
|
|
101
126
|
|
|
102
127
|
<picture>
|
|
103
128
|
<source media="(prefers-color-scheme: dark)" srcset="docs/media/bench-qodo-dark.png">
|
|
@@ -109,20 +134,57 @@ and 271 violations of rules written in the repo. QuickReview finds the most
|
|
|
109
134
|
functional bugs of the thirteen tools (52.1%) and the second-most issues
|
|
110
135
|
overall, at the lowest precision; it is fourth on F1.
|
|
111
136
|
|
|
137
|
+
<picture>
|
|
138
|
+
<source media="(prefers-color-scheme: dark)" srcset="docs/media/bench-elo-dark.png">
|
|
139
|
+
<img src="docs/media/bench-elo.png" alt="Pairwise Elo on the 20 Martian PRs where QuickReview on GPT-6.1 Sol or DeepSeek did worst, two judges pooled, with 95% intervals. Claude Code max, Opus 5.5 directing Sonnet 5.5 agents, 1666, QuickReview on Opus 5.5 1628, QuickReview on GPT-6.1 Sol 1566, Claude Code high on Opus 5.5 1518, QuickReview on Sonnet 5.5 1489, QuickReview on DeepSeek V4.1 Flash 1406, Claude Code high on Sonnet 5.5 1398, QuickReview on GLM-5.3 Flash 1329.">
|
|
140
|
+
</picture>
|
|
141
|
+
|
|
142
|
+
**Judged side by side.** A pairwise judge reads two reviews of the same PR
|
|
143
|
+
blind and picks the better one. GPT-6.1 Sol and Claude Opus 5.5 both judged,
|
|
144
|
+
and a Bradley-Terry fit over their 596 verdicts gives Elo; alone, the two
|
|
145
|
+
judges pick the same winner only 56% of the time, which is why they are
|
|
146
|
+
pooled. On the 20 Martian PRs where QuickReview on GPT-6.1 Sol or DeepSeek did
|
|
147
|
+
worst, QuickReview on Opus 5.5 (six of its lenses on GPT-6 Luna) beat Claude
|
|
148
|
+
Code's `/code-review` at high effort on Opus 5.5 in 29 of 40 verdicts, at more
|
|
149
|
+
than ten times its cost (about $4 per PR). Only Claude Code's max mode (Opus
|
|
150
|
+
5.5 directing Sonnet 5.5 agents, about $20 per PR) ranks higher, by a margin
|
|
151
|
+
inside the intervals.
|
|
152
|
+
|
|
153
|
+
**Other models.** QuickReview's models are configurable. On AACR-Bench
|
|
154
|
+
it holds most of its recall on cheap open models, and it falls apart on a
|
|
155
|
+
weak one:
|
|
156
|
+
|
|
157
|
+
| QuickReview on | PRs | High (90) | Medium (145) | Low (285) | All (520) | $/PR | Judge |
|
|
158
|
+
|---|---|---|---|---|---|---|---|
|
|
159
|
+
| GPT-6.1 Sol (frozen build) | 185 | 87.5 (97%) | 134.5 (93%) | 239 (84%) | 461 (89%) | 2.06 | gpt-6-sol |
|
|
160
|
+
| DeepSeek V4.1 Flash (mostly low effort) | 185 | 83 (92%) | 131 (90%) | 237.5 (83%) | 451.5 (87%) | 0.74 | gpt-6.1-sol |
|
|
161
|
+
| GLM-5.3 Flash | 185 | 83 (92%) | 120.5 (83%) | 231.5 (81%) | 435 (84%) | 0.52 | gpt-6.1-sol |
|
|
162
|
+
| GPT-6 Luna | 185 | 39 (43%) | 44 (30%) | 64 (22%) | 147 (28%) | 0.04 | gpt-6-sol |
|
|
163
|
+
| Claude Opus 5.5 | 40 | 32/34 (94%) | 30.5/31 (98%) | 57/61 (93%) | 119.5/126 (95%) | 3.24 | gpt-6-sol |
|
|
164
|
+
|
|
165
|
+
The best third-party reviewer at each severity finds 81 of 90 high (Codex
|
|
166
|
+
CLI), 119 of 145 medium and 148.5 of 285 low (both the pi-review panel). The
|
|
167
|
+
open-model rows ran a later build (mid-October, with cost changes made after
|
|
168
|
+
the freeze) and a later judge; DeepSeek ran at low reasoning effort on 143 of
|
|
169
|
+
its PRs, and GLM's review was missing a lens pass on 7. The GPT-6 Luna and
|
|
170
|
+
Opus rows ran a September build; on the same 40 PRs as Opus, the frozen
|
|
171
|
+
GPT-6.1 Sol build finds 33 of 34 high, 28 of 31 medium and 44 of 61 low. Read
|
|
172
|
+
the table as directional.
|
|
173
|
+
|
|
112
174
|
<details>
|
|
113
175
|
<summary>The full tables</summary>
|
|
114
176
|
|
|
115
177
|
**AACR-Bench** (185 PRs, 10 languages, 520 verified defects; a partly found defect counts ½)
|
|
116
178
|
|
|
117
|
-
| Reviewer | High (90) |
|
|
118
|
-
|
|
119
|
-
| **QuickReview** | **87.5 (97%)** | **
|
|
120
|
-
| pi-review panel (high) | 80 (89%) |
|
|
121
|
-
| Claude Code (Opus 5.5) | 72.5 (81%) |
|
|
122
|
-
| open-code-review (high) | 63.5 (71%) |
|
|
123
|
-
| Codex CLI (high) | 81 (90%) |
|
|
124
|
-
| OpenCode (+ PR text) | 76 (84%) |
|
|
125
|
-
| PR-Agent | 55.5 (62%) |
|
|
179
|
+
| Reviewer | High (90) | Medium (145) | Low (285) | All (520) | Comments correct | $/PR | Median min/PR |
|
|
180
|
+
|---|---|---|---|---|---|---|---|
|
|
181
|
+
| **QuickReview** | **87.5 (97%)** | **134.5 (93%)** | **239 (84%)** | **461 (89%)** | 92% | 2.06 | 17.5 |
|
|
182
|
+
| pi-review panel (high) | 80 (89%) | 119 (82%) | 148.5 (52%) | 347.5 (67%) | 89% | 0.27 | 1.8 |
|
|
183
|
+
| Claude Code (Opus 5.5) | 72.5 (81%) | 105 (72%) | 147 (52%) | 324.5 (62%) | 81% | 0.20 | 0.7 |
|
|
184
|
+
| open-code-review (high) | 63.5 (71%) | 102 (70%) | 133 (47%) | 298.5 (57%) | 86% | 0.53 | 1.8 |
|
|
185
|
+
| Codex CLI (high) | 81 (90%) | 101.5 (70%) | 104.5 (37%) | 287 (55%) | 93% | 0.14 | 2.1 |
|
|
186
|
+
| OpenCode (+ PR text) | 76 (84%) | 99 (68%) | 88.5 (31%) | 263.5 (51%) | 93% | 0.17 | 2.3 |
|
|
187
|
+
| PR-Agent | 55.5 (62%) | 70 (48%) | 68.5 (24%) | 194 (37%) | 76% | 0.07 | 1.9 |
|
|
126
188
|
|
|
127
189
|
**Martian** (50 PRs, Core; one `gpt-6.1-sol` judge for every row, the vendor rows re-judged from their published comments)
|
|
128
190
|
|
|
@@ -154,8 +216,8 @@ overall, at the lowest precision; it is fourth on F1.
|
|
|
154
216
|
**Held-out PRs.** The last tuning round was mined from misses on part of
|
|
155
217
|
each benchmark. On the PRs kept out of it, the frozen build finds 83% of
|
|
156
218
|
AACR-Bench's defects (20 PRs), ties qodo-extended-v2 on Martian's real
|
|
157
|
-
goldens (43 of 52, 30 PRs), and reaches 60.3% recall and
|
|
158
|
-
|
|
219
|
+
goldens (43 of 52, 30 PRs), and on Qodo (31 PRs) reaches 60.3% recall and
|
|
220
|
+
F1 53.0, level with qodo-exhaustive's 51.3.
|
|
159
221
|
|
|
160
222
|
**Read more.** Two papers carry the method, every table and the threats to
|
|
161
223
|
validity: [*Measuring whether a code review finds the real
|
|
@@ -223,9 +285,19 @@ Slack concierge, a local companion session, opt-in escalation notes, and the
|
|
|
223
285
|
|
|
224
286
|
## Quickstart
|
|
225
287
|
|
|
226
|
-
You need **Docker** with Compose v2
|
|
227
|
-
|
|
228
|
-
Windows, run everything inside **WSL2**.
|
|
288
|
+
You need **Docker** with Compose v2, a model login, and either `gh` signed in
|
|
289
|
+
to your own GitHub account or **a GitHub account that can create an App** on
|
|
290
|
+
the repository to review. On Windows, run everything inside **WSL2**.
|
|
291
|
+
|
|
292
|
+
There is a second route that needs no App: `[github] auth = "user"` runs the
|
|
293
|
+
reviewer on **your own GitHub account**. Use it on one box where `gh` is
|
|
294
|
+
already signed in. It is polling-only, with no webhooks and no tunnel. Every
|
|
295
|
+
review it posts is a COMMENT that states its verdict, because an automated
|
|
296
|
+
verdict must never count as your approval and GitHub refuses either on your own
|
|
297
|
+
PR. Your token reaches the daemon only as the 0600 file
|
|
298
|
+
`<secrets dir>/github_token`, which `qcr github-token sync` refreshes from
|
|
299
|
+
`gh`. It never comes from the environment or a command line. On the App route
|
|
300
|
+
no personal access token is used.
|
|
229
301
|
|
|
230
302
|
```sh
|
|
231
303
|
# once: install `qcr`, the host wrapper the image writes (docs/host-wrapper.md);
|
|
@@ -233,32 +305,38 @@ Windows, run everything inside **WSL2**.
|
|
|
233
305
|
docker run --rm --user "$(id -u):$(id -g)" -v ~/.local/bin:/out \
|
|
234
306
|
ghcr.io/quickchatai/quickreview:<version> install
|
|
235
307
|
|
|
236
|
-
qcr
|
|
308
|
+
qcr # the home: sign in, connect GitHub, choose a repository
|
|
237
309
|
```
|
|
238
310
|
|
|
239
|
-
`qcr
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
OpenAI
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
311
|
+
A bare `qcr` opens the **home**: QuickReview's own pi, with the plugin loaded
|
|
312
|
+
and a panel of your repository's open pull requests. On a first run the panel
|
|
313
|
+
is a short setup checklist, and anything already set up is found and skipped:
|
|
314
|
+
sign in to OpenAI with pi's device code (device-code login must be on in
|
|
315
|
+
ChatGPT → Settings → Security), check that `gh` is signed in, and choose a
|
|
316
|
+
repository from your recently pushed ones or paste any `owner/name` or URL.
|
|
317
|
+
`alt+n` runs the next step. The home then lists the pull requests, "To review"
|
|
318
|
+
and "Reviewed". `qcr tui` opens the admin TUI, and only it starts the
|
|
319
|
+
companion. Through the Docker wrapper the home runs in a container of its own:
|
|
320
|
+
its login is kept in the `qcr-login` volume, its config and sessions in the
|
|
321
|
+
`qcr-state` volume, and its `gh` uses the token the wrapper finds on this
|
|
322
|
+
machine (`GITHUB_TOKEN`, `GH_TOKEN` or `gh auth token`). The always-on daemon, a GitHub App, webhooks and a server over ssh
|
|
323
|
+
are the setup wizard's steps: [docs/onboarding.md](docs/onboarding.md).
|
|
248
324
|
|
|
249
325
|
### Where the reviewer lives
|
|
250
326
|
|
|
251
|
-
- **
|
|
252
|
-
|
|
327
|
+
- **This computer**, in Docker ([docker/README.md](docker/README.md)): the
|
|
328
|
+
pick when the machine is itself an always-on server, such as a cloud VM;
|
|
329
|
+
on a laptop it reviews only while the machine is awake.
|
|
330
|
+
- **A server over ssh**, recommended when your own computer sleeps. Setup
|
|
331
|
+
rides the Ansible deploy
|
|
253
332
|
([deploy/ansible/README.md](deploy/ansible/README.md)); it needs
|
|
254
333
|
passwordless sudo there and `ansible-playbook` on your machine.
|
|
255
|
-
- **This computer**, in Docker, reviewing while the machine is awake
|
|
256
|
-
([docker/README.md](docker/README.md)).
|
|
257
334
|
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
335
|
+
Polling is the default: the daemon checks GitHub every few minutes and
|
|
336
|
+
exposes nothing, at the cost of trigger latency up to one poll interval and
|
|
337
|
+
quiet author-reply routing and `[feedback]` loop. Webhooks need an HTTPS URL:
|
|
338
|
+
a Cloudflare quick tunnel, ngrok or your own named Cloudflare tunnel, on the
|
|
339
|
+
App route only. The trade-offs are in
|
|
262
340
|
[docker/README.md](docker/README.md).
|
|
263
341
|
|
|
264
342
|
`dry_run = true` stays on until you flip it, through the wizard's go-live
|
|
@@ -279,9 +357,10 @@ npm i -g @quickchatai/quickreview
|
|
|
279
357
|
qcr login # pi's own /login, for the review's models
|
|
280
358
|
qcr review # review this branch against its base, with no daemon
|
|
281
359
|
qcr review 123 # review a pull request (or pass its URL)
|
|
282
|
-
qcr pi # pi with the
|
|
360
|
+
qcr pi # pi with the plugin (/qcr-review /qcr-scan /qcr-setup) and /selfimprove
|
|
283
361
|
qcr update # update qcr with the package manager that installed it
|
|
284
|
-
qcr # the
|
|
362
|
+
qcr # the home: pi on your own login, with your repo's pull requests
|
|
363
|
+
qcr tui # the admin TUI
|
|
285
364
|
```
|
|
286
365
|
|
|
287
366
|
`qcr review` asks where the result goes (shown, saved as markdown and JSON,
|
|
@@ -337,8 +416,9 @@ never the same system ([MANIFESTO.md](MANIFESTO.md)).
|
|
|
337
416
|
|
|
338
417
|
## Appendix — setting up by hand
|
|
339
418
|
|
|
340
|
-
|
|
341
|
-
|
|
419
|
+
The setup wizard's steps ([docs/onboarding.md](docs/onboarding.md)) compose
|
|
420
|
+
these tools rather than replacing them; re-running one afterwards re-checks it
|
|
421
|
+
without rewriting what already holds.
|
|
342
422
|
|
|
343
423
|
```sh
|
|
344
424
|
IMG=ghcr.io/quickchatai/quickreview:<version>
|
|
@@ -355,8 +435,8 @@ curl -s http://127.0.0.1:8787/health
|
|
|
355
435
|
|
|
356
436
|
Then point your HTTPS ingress at the webhook port, install the App, create
|
|
357
437
|
the trigger label and label a PR: `state/dryrun/` fills up. The memory keys
|
|
358
|
-
are minted by the running server
|
|
359
|
-
|
|
438
|
+
are minted by the running server (the wizard's memory-keys steps, 60 and 72,
|
|
439
|
+
in [docs/onboarding.md](docs/onboarding.md)); declining memory is supported.
|
|
360
440
|
|
|
361
441
|
## Star history
|
|
362
442
|
|
package/bin/qcr.js
CHANGED
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
// name `qcr`, so the CLI module cannot recognise itself by its file name: this
|
|
4
4
|
// file imports the bin's front door and calls it explicitly. The front door
|
|
5
5
|
// (src/qcrbin.ts) runs the verbs an npm install needs without the state
|
|
6
|
-
// database's native driver, opens the
|
|
6
|
+
// database's native driver, opens the home on a bare `qcr`, and hands
|
|
7
7
|
// every other verb to the app's `main` (src/cli.ts). The image's
|
|
8
8
|
// `node /opt/qcr/dist/src/cli.js` is the app's entry, run directly.
|
|
9
9
|
import { runBin } from "../dist/src/qcrbin.js";
|
package/config.example.toml
CHANGED
|
@@ -6,10 +6,11 @@
|
|
|
6
6
|
# supply are marked "← FILL (n)" — grep for FILL. Flip dry_run to false only
|
|
7
7
|
# as a deliberate cutover act, never as part of setup.
|
|
8
8
|
#
|
|
9
|
-
# YOU DO NOT HAVE TO FILL THIS BY HAND: `
|
|
10
|
-
#
|
|
11
|
-
#
|
|
12
|
-
#
|
|
9
|
+
# YOU DO NOT HAVE TO FILL THIS BY HAND: a bare `qcr` (the home) writes the
|
|
10
|
+
# repository you choose and its defaults, and the setup wizard's steps
|
|
11
|
+
# interview you for the rest, derive what they can, and patch this file in
|
|
12
|
+
# place — every comment survives, and a re-run edits only what changed.
|
|
13
|
+
# Neither writes dry_run in either direction; going live is its own explicit
|
|
13
14
|
# step. See docs/onboarding.md.
|
|
14
15
|
# ONE mutation class is exempt and executes for real even here: the App
|
|
15
16
|
# re-pointing its OWN webhook URL (see [ingress] below) — it can never touch
|
|
@@ -27,8 +28,22 @@ timezone = "UTC" # ← FILL: your IANA timezone, e.g
|
|
|
27
28
|
|
|
28
29
|
[github]
|
|
29
30
|
repo = "" # ← FILL (1): the repo to review, "owner/name"
|
|
30
|
-
|
|
31
|
-
|
|
31
|
+
# Whose GitHub credential the daemon runs on:
|
|
32
|
+
# "app" (the default; a missing key means "app") — a GitHub App: its
|
|
33
|
+
# installation token, webhooks, APPROVE / REQUEST_CHANGES reviews.
|
|
34
|
+
# "user" — your OWN GitHub account, no App. Polling only: [ingress] shape
|
|
35
|
+
# must be "polling" (config load refuses anything else), no webhooks,
|
|
36
|
+
# no webhook self-heal. Every review posts as a COMMENT whose body
|
|
37
|
+
# states the verdict (an automated verdict never counts as your
|
|
38
|
+
# approval, and GitHub refuses either on your own PR). The token is
|
|
39
|
+
# read from the FILE <secrets dir>/github_token (0600, the token
|
|
40
|
+
# alone), which `qcr github-token sync` writes from your `gh` login;
|
|
41
|
+
# never from the environment or a command line. app_slug may be "";
|
|
42
|
+
# bot_login is your own GitHub login. The App secrets (app_id,
|
|
43
|
+
# app.pem, webhook_secret) are not needed.
|
|
44
|
+
#auth = "app"
|
|
45
|
+
app_slug = "" # ← FILL (2): your GitHub App slug ("" under auth = "user")
|
|
46
|
+
bot_login = "" # ← FILL (3): the App bot login, "<app_slug>[bot]" (your login under auth = "user")
|
|
32
47
|
review_team = "" # ← FILL (4): "org/team" whose review request triggers
|
|
33
48
|
# There is no reviewer knob here. The reviewer never hands a PR back: it always
|
|
34
49
|
# decides on the merits and posts a verdict. If you want a named person told
|
|
@@ -39,7 +54,8 @@ in_progress_label = "AI review in progress"
|
|
|
39
54
|
reviewed_label = "Automatic Review"
|
|
40
55
|
improvement_label = "Bot improvement"
|
|
41
56
|
issue_label = "bot-filed"
|
|
42
|
-
# secrets dir: app_id, app.pem, webhook_secret, tunnel_token
|
|
57
|
+
# secrets dir: app_id, app.pem, webhook_secret, tunnel_token (auth = "user": github_token instead
|
|
58
|
+
# of the first three); optional openai_api_key (pi, API-key
|
|
43
59
|
# route) and openai_embeddings_api_key (only with embedding_provider = "openai" in the openviking table)
|
|
44
60
|
# "" (recommended) = the install's config home, $XDG_CONFIG_HOME/qcr/<install>/secrets (the old
|
|
45
61
|
# ~/.config/quickreview-bot is never read — `qcr install migrate` moves it). A path here wins.
|
|
@@ -81,8 +97,12 @@ port = 8787 # loopback only; your HTTPS ingress
|
|
|
81
97
|
# touches only the App's own configuration, never the reviewed repo. Off by
|
|
82
98
|
# default: with the section absent (or shape = "none") no watcher ever starts —
|
|
83
99
|
# a stable hostname (named tunnel, VM route) needs none of this.
|
|
100
|
+
# shape = "polling" takes no webhooks at all: the daemon's /webhook route
|
|
101
|
+
# refuses every delivery, no webhook_secret is read, and the reconcile poll
|
|
102
|
+
# (poll_interval_s, below) is the only trigger. [github] auth = "user"
|
|
103
|
+
# requires it.
|
|
84
104
|
#[ingress]
|
|
85
|
-
#shape = "tunnel-file" # "none" (default) | "tunnel-file"
|
|
105
|
+
#shape = "tunnel-file" # "none" (default) | "tunnel-file" | "polling"
|
|
86
106
|
#hostname_file = "" # "" ⇒ <root>/state/ingress/hostname
|
|
87
107
|
#debounce_ms = 3000 # settle time after a file change
|
|
88
108
|
#sweep_interval_s = 300 # polling backstop behind fs.watch
|
|
@@ -204,7 +224,9 @@ improvement_pr_deny_prefixes = ["migrations/", "infra/", "ansible/", ".github/wo
|
|
|
204
224
|
[models]
|
|
205
225
|
# default for every role; tiered pass models below
|
|
206
226
|
# Provider prefix is `openai-codex/` — the ChatGPT-OAuth route's provider key
|
|
207
|
-
# in pi's auth.json
|
|
227
|
+
# in pi's auth.json. Any OpenAI login serves it: when pi holds no
|
|
228
|
+
# `openai-codex` login but an `openai` one (pi 1.4's Sign in with ChatGPT, or
|
|
229
|
+
# an OpenAI API key), the same model runs on `openai` (docs/llm-setup.md).
|
|
208
230
|
default = "openai-codex/gpt-6.1-sol"
|
|
209
231
|
conversation = "openai-codex/gpt-6.1-sol"
|
|
210
232
|
# Passes always run at sol-high — single variant, not raisable (already top).
|
|
@@ -261,7 +283,11 @@ small_diff_lines = 150
|
|
|
261
283
|
# memory forward follows this knob too — it reaches the daemon
|
|
262
284
|
# container's loopback memory engine with a plain `docker exec`
|
|
263
285
|
# (the forward script's --local mode) instead of the ssh hop.
|
|
264
|
-
#
|
|
286
|
+
# Onboarding writes this from the recorded topology. Until it has (ssh with an
|
|
287
|
+
# EMPTY ssh_host), the TUI never runs `ssh ""`: on a compose project (the
|
|
288
|
+
# checklist recorded the local topology, or the project .env pins
|
|
289
|
+
# QCR_VERSION) it reads the local stack and says so once; otherwise every
|
|
290
|
+
# surface says "ssh_host is empty — set it to the VM's ssh alias".
|
|
265
291
|
target = "ssh"
|
|
266
292
|
ssh_host = "" # ← FILL (7): ssh alias of the VM running the container
|
|
267
293
|
# (leave "" when target = "local" — it is unused)
|
|
@@ -270,10 +296,14 @@ memory_container = "" # the container the memory forward relays into
|
|
|
270
296
|
# (OpenViking is the daemon container's child). On a VM running
|
|
271
297
|
# the memory sidecar (the openviking table's endpoint =
|
|
272
298
|
# "remote") set "quickreview-memory"; flip it back with the endpoint.
|
|
273
|
-
remote_state_dir = "/opt/quickreview/state" # host path on ssh; inside the daemon container on local
|
|
299
|
+
remote_state_dir = "/opt/quickreview/state" # host path on ssh; inside the daemon container on local,
|
|
300
|
+
# where this default reads as the release image's /opt/qcr/state
|
|
301
|
+
# (the compose state volume; onboarding writes it for local)
|
|
274
302
|
remote_sandbox_root = "" # "" = read the container's qcr.layout label (release: /opt/qcr, legacy: /opt/quickreview/sandbox);
|
|
275
303
|
# a value here wins and is never probed
|
|
276
|
-
sudo_docker = true # docker on the VM needs sudo (root-owned socket)
|
|
304
|
+
sudo_docker = true # docker on the VM needs sudo (root-owned socket). On local, onboarding
|
|
305
|
+
# writes false, and the TUI drops sudo by itself when this user can open
|
|
306
|
+
# the docker socket (a sudo prompt behind the TUI can only fail)
|
|
277
307
|
poll_interval_s = 3
|
|
278
308
|
stale_after_s = 90 # DATA STALE banner past this written_at age
|
|
279
309
|
# (the daemon rewrites status.json every ~30s)
|
|
@@ -338,6 +368,19 @@ session_dir = "state/pi-sessions"
|
|
|
338
368
|
# lens_cache_stagger_ms = 2500
|
|
339
369
|
# lens_pass_deadline_min = 8
|
|
340
370
|
|
|
371
|
+
[home]
|
|
372
|
+
# The home: a bare `qcr` opens the app's own pinned pi, on your own pi login
|
|
373
|
+
# ($PI_CODING_AGENT_DIR, default ~/.pi/agent), with a panel of the
|
|
374
|
+
# repository's pull requests. Every key is optional.
|
|
375
|
+
# model — the chat's model, "provider/id". The panel counts only this
|
|
376
|
+
# model's provider as signed in: a login under another provider
|
|
377
|
+
# cannot run the chat.
|
|
378
|
+
# tools — "reviewer": the model may call the plugin's tools, the home's
|
|
379
|
+
# own home_* tools and pi's read tools (read, grep, find, ls), and
|
|
380
|
+
# no MCP server starts. "full": every tool pi has.
|
|
381
|
+
model = "openai-codex/gpt-6.1-sol"
|
|
382
|
+
tools = "reviewer"
|
|
383
|
+
|
|
341
384
|
[memory]
|
|
342
385
|
# Round seeding — how much memory rides each round prompt and how
|
|
343
386
|
# long the daemon waits for it. Memory NEVER blocks or delays a round: past
|
|
@@ -594,7 +637,10 @@ local_embedder_threads = 1
|
|
|
594
637
|
# (COMPANION_DEFAULTS) are the shipped configuration; uncomment to override.
|
|
595
638
|
# enabled = true # `qcr tui` starts it unless --no-companion
|
|
596
639
|
# container_name = "qcr-companion"
|
|
597
|
-
# image = "qcr-companion:release" # the release image (docker/Dockerfile) in companion mode, built from the app root: qcr companion rebuild
|
|
640
|
+
# image = "qcr-companion:release" # the release image (docker/Dockerfile) in companion mode, built from the app root: qcr companion rebuild.
|
|
641
|
+
# # Left unset on a compose box (the project .env pins QCR_VERSION), a first start runs the
|
|
642
|
+
# # already-pulled ghcr.io/quickchatai/quickreview:<QCR_VERSION> instead of building, unless a
|
|
643
|
+
# # local build exists; a ghcr.io/quickchatai/quickreview tag set here is pulled, never built over
|
|
598
644
|
# pihome_volume = "companion-pihome" # its OWN pi auth — never the VM's auth.json
|
|
599
645
|
# session = "companion" # tmux session inside the container
|
|
600
646
|
# model = "openai-codex/gpt-6.1-sol:medium"
|
|
@@ -859,7 +905,7 @@ extra_vendored_segments = [] # extra third-party markers (case-insensitive)
|
|
|
859
905
|
# whatever — the system BEHAVES exactly as a build without the feature.
|
|
860
906
|
# (The placeholder that renders empty leaves a blank line in the prompt, like
|
|
861
907
|
# the sibling notes beside it.)
|
|
862
|
-
#
|
|
908
|
+
# The setup wizard's escalation step writes this section.
|
|
863
909
|
#
|
|
864
910
|
# The configuration cannot be half-done: `enabled = true` with no `targets`,
|
|
865
911
|
# or a rule pointing at a login that is not a target, or a rule that declares
|
package/deploy/ansible/README.md
CHANGED
|
@@ -12,7 +12,7 @@ once (`deploy.sh provision`, this playbook), which installs a thin updater,
|
|
|
12
12
|
`qcr-update`, and its run spec; every deploy after that is
|
|
13
13
|
`deploy.sh release <version>`, which runs `ssh vm sudo qcr-update ...`.
|
|
14
14
|
|
|
15
|
-
>
|
|
15
|
+
> **The setup wizard's steps drive this route.** The wizard's
|
|
16
16
|
> **topology** step offers it as one of two first-class answers — advertised as
|
|
17
17
|
> the always-on recommendation, because a reviewer that is asleep reviews
|
|
18
18
|
> nothing — then checks your ssh alias and agent *before* anything is built
|
|
@@ -40,7 +40,7 @@ having no built-in permission system.
|
|
|
40
40
|
|
|
41
41
|
## Prerequisites (once, manual)
|
|
42
42
|
|
|
43
|
-
Items 2–4 are what
|
|
43
|
+
Items 2–4 are what the setup wizard fills in for you on this route; item 1 is
|
|
44
44
|
yours either way — the wizard never creates a machine.
|
|
45
45
|
|
|
46
46
|
1. **A VM you can reach over ssh by an alias**, with passwordless sudo for your
|
|
@@ -198,14 +198,20 @@ when one names another root. `remote_state_dir` stays the host path.
|
|
|
198
198
|
|
|
199
199
|
### Pulling the release
|
|
200
200
|
|
|
201
|
-
The images are
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
201
|
+
The images are public on ghcr.io and are pulled BY the updater, on the VM, by
|
|
202
|
+
digest. A public pull needs no login, so a VM that pulls the release images
|
|
203
|
+
needs no registry credential at all; `deploy.sh verify` and `release` then say
|
|
204
|
+
`no ghcr login recorded` and nothing more.
|
|
205
|
+
|
|
206
|
+
**A private mirror.** Images that are not public (`QC_RELEASE_IMAGE` and
|
|
207
|
+
`QC_RELEASE_MEMORY_IMAGE` naming another package) need the VM logged in, with
|
|
208
|
+
ONE credential: your own CLASSIC personal access token, scoped `read:packages`
|
|
209
|
+
and nothing else, stored by `docker login` in root's docker config on the VM
|
|
210
|
+
host (never in a container, env, argv or the secrets directory: the daemon
|
|
211
|
+
holds only the App credential). Not the token `gh auth token` prints: that one
|
|
212
|
+
carries the full scopes of your gh login. The login must exist before the
|
|
213
|
+
first `release` from the mirror (the pull is the updater's first step, and a
|
|
214
|
+
lapsed login fails there with nothing changed).
|
|
209
215
|
|
|
210
216
|
Once per VM, and again when the token is renewed (it expires after one year):
|
|
211
217
|
|
|
@@ -227,7 +233,9 @@ idempotent, and the token is never an argument or an environment variable.
|
|
|
227
233
|
|
|
228
234
|
A lapsed login fails the updater's pull before anything on the VM changes
|
|
229
235
|
(`qcr-update` refuses at its `pull` step). `scripts/deploy.sh verify` and
|
|
230
|
-
`release` warn 14 days before the recorded expiry. `ssh <vm> sudo docker logout ghcr.io` removes the login
|
|
236
|
+
`release` warn 14 days before the recorded expiry. `ssh <vm> sudo docker logout ghcr.io` removes the login;
|
|
237
|
+
a VM back on the public images can drop it, and the recorded expiry with it
|
|
238
|
+
(`<state home>/ghcr-token-expiry`), so the warning stops.
|
|
231
239
|
|
|
232
240
|
### The cutover (legacy image to release image)
|
|
233
241
|
|
|
@@ -307,7 +315,7 @@ ssh <vm> docker exec quickreview-sandbox tmux ls
|
|
|
307
315
|
ssh <vm> curl -sS http://127.0.0.1:8787/health # loopback-only by design
|
|
308
316
|
```
|
|
309
317
|
|
|
310
|
-
That is the same layering
|
|
318
|
+
That is the same layering the setup wizard's verification step runs — containers,
|
|
311
319
|
then the health endpoint, then GitHub's own webhook delivery log — and the
|
|
312
320
|
order matters: a container that is not up cannot answer a health probe, and a
|
|
313
321
|
daemon that is not answering cannot accept a delivery. While the tunnel is up
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
# Copy to inventory.ini and fill in — inventory.ini is gitignored:
|
|
2
2
|
# it carries YOUR real hostnames and stays local to the controller machine.
|
|
3
3
|
#
|
|
4
|
-
#
|
|
4
|
+
# The setup wizard writes inventory.ini for you on the server route, from
|
|
5
5
|
# answers you have already given (the ssh alias, the login user your ssh config
|
|
6
6
|
# resolves, and whether the playbook should install cloudflared). This file
|
|
7
7
|
# documents what it writes, and what to fill if you do it by hand.
|
|
@@ -7,7 +7,7 @@
|
|
|
7
7
|
# Values are read with hidden input and NEVER printed back. Re-run any time —
|
|
8
8
|
# existing files are kept unless you choose to replace them.
|
|
9
9
|
#
|
|
10
|
-
#
|
|
10
|
+
# The setup wizard writes app_id / app.pem / webhook_secret itself, from
|
|
11
11
|
# the GitHub App manifest exchange, and mints the OpenViking keys — so on the
|
|
12
12
|
# guided path you only reach for this script for the values it points you at
|
|
13
13
|
# (the OpenAI key, a tunnel token, an ngrok authtoken, the hosted-embeddings
|
package/deploy/qcr-update.sh
CHANGED
|
@@ -535,7 +535,7 @@ fi
|
|
|
535
535
|
# ---- 4. pull both images by digest, check them ----------------------------------------------------------
|
|
536
536
|
|
|
537
537
|
step pull
|
|
538
|
-
d pull "$DAEMON_REF" >/dev/null || die "could not pull $DAEMON_REF (is the VM logged in
|
|
538
|
+
d pull "$DAEMON_REF" >/dev/null || die "could not pull $DAEMON_REF (the release images are public: check the VM reaches ghcr.io and the digest is published; a private mirror needs the VM logged in, scripts/vm-ghcr-login.sh)"
|
|
539
539
|
d pull "$MEMORY_REF" >/dev/null || die "could not pull $MEMORY_REF"
|
|
540
540
|
|
|
541
541
|
step check-images
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
// The env shim for the home's extension: the one place the process's env
|
|
2
|
+
// becomes its options (extensions/home.ts). A bare `qcr` loads it by path
|
|
3
|
+
// (src/home/launch.ts), with the model and tool set it launched on in the env.
|
|
4
|
+
import { VERSION } from "@earendil-works/pi-coding-agent";
|
|
5
|
+
import { homeOptionsFromEnv } from "../../src/home/adapters.js";
|
|
6
|
+
import { homeSetupFromEnv } from "../../src/home/setupadapters.js";
|
|
7
|
+
import { createHome } from "../home.js";
|
|
8
|
+
export default function activate(pi) {
|
|
9
|
+
void createHome({
|
|
10
|
+
...homeOptionsFromEnv(process.env),
|
|
11
|
+
setup: homeSetupFromEnv(process.env, VERSION),
|
|
12
|
+
})(pi);
|
|
13
|
+
}
|
|
14
|
+
//# sourceMappingURL=home.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"home.js","sourceRoot":"","sources":["../../../extensions/cli/home.ts"],"names":[],"mappings":"AAAA,yEAAyE;AACzE,0EAA0E;AAC1E,+EAA+E;AAC/E,OAAO,EAAE,OAAO,EAAqB,MAAM,iCAAiC,CAAC;AAC7E,OAAO,EAAE,kBAAkB,EAAE,MAAM,4BAA4B,CAAC;AAChE,OAAO,EAAE,gBAAgB,EAAE,MAAM,iCAAiC,CAAC;AACnE,OAAO,EAAE,UAAU,EAAE,MAAM,YAAY,CAAC;AAExC,MAAM,CAAC,OAAO,UAAU,QAAQ,CAAC,EAAgB;IAC/C,KAAK,UAAU,CAAC;QACd,GAAG,kBAAkB,CAAC,OAAO,CAAC,GAAG,CAAC;QAClC,KAAK,EAAE,gBAAgB,CAAC,OAAO,CAAC,GAAG,EAAE,OAAO,CAAC;KAC9C,CAAC,CAAC,EAAE,CAAC,CAAC;AACT,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"login-route.js","sourceRoot":"","sources":["../../../extensions/cli/login-route.ts"],"names":[],"mappings":"AAKA,OAAO,EAAE,gBAAgB,EAAE,uBAAuB,EAAE,MAAM,mBAAmB,CAAC;AAE9E,MAAM,CAAC,OAAO,UAAU,QAAQ,CAAC,EAAgB;IAC/C,KAAK,gBAAgB,CAAC,uBAAuB,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC;AAClE,CAAC"}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
// The env shim for the app's /selfimprove (extensions/selfimprove.ts): the
|
|
2
|
+
// one place the process's env, home and standard output become its config.
|
|
3
|
+
// `qcr pi` loads this file beside the plugin.
|
|
4
|
+
import { homedir } from "node:os";
|
|
5
|
+
import { VERSION } from "@earendil-works/pi-coding-agent";
|
|
6
|
+
import { nodeRunner } from "@quickchatai/pi-quickreview/src/plugin/runner.js";
|
|
7
|
+
import { createSelfImprove } from "../selfimprove.js";
|
|
8
|
+
export default function activate(pi) {
|
|
9
|
+
const env = process.env;
|
|
10
|
+
createSelfImprove({
|
|
11
|
+
env,
|
|
12
|
+
home: (env["HOME"] ?? "").trim() || homedir(),
|
|
13
|
+
runner: nodeRunner(env),
|
|
14
|
+
print: (text) => void process.stdout.write(text.endsWith("\n") ? text : `${text}\n`),
|
|
15
|
+
piVersion: VERSION,
|
|
16
|
+
})(pi);
|
|
17
|
+
}
|
|
18
|
+
//# sourceMappingURL=selfimprove.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"selfimprove.js","sourceRoot":"","sources":["../../../extensions/cli/selfimprove.ts"],"names":[],"mappings":"AAAA,2EAA2E;AAC3E,2EAA2E;AAC3E,8CAA8C;AAC9C,OAAO,EAAE,OAAO,EAAE,MAAM,SAAS,CAAC;AAClC,OAAO,EAAE,OAAO,EAAqB,MAAM,iCAAiC,CAAC;AAC7E,OAAO,EAAE,UAAU,EAAE,MAAM,kDAAkD,CAAC;AAC9E,OAAO,EAAE,iBAAiB,EAAE,MAAM,mBAAmB,CAAC;AAEtD,MAAM,CAAC,OAAO,UAAU,QAAQ,CAAC,EAAgB;IAC/C,MAAM,GAAG,GAAG,OAAO,CAAC,GAAG,CAAC;IACxB,iBAAiB,CAAC;QAChB,GAAG;QACH,IAAI,EAAE,CAAC,GAAG,CAAC,MAAM,CAAC,IAAI,EAAE,CAAC,CAAC,IAAI,EAAE,IAAI,OAAO,EAAE;QAC7C,MAAM,EAAE,UAAU,CAAC,GAAG,CAAC;QACvB,KAAK,EAAE,CAAC,IAAI,EAAE,EAAE,CAAC,KAAK,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,GAAG,IAAI,IAAI,CAAC;QACpF,SAAS,EAAE,OAAO;KACnB,CAAC,CAAC,EAAE,CAAC,CAAC;AACT,CAAC"}
|