@quickchatai/quickreview 1.2.0 → 1.3.2
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 +116 -53
- package/bin/qcr.js +1 -1
- package/config.example.toml +25 -7
- 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/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 +1 -1
- package/dist/extensions/login-route.js.map +1 -1
- package/dist/extensions/onboarding.js +8 -7
- 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/extensions/vendor/openviking-pi/index.js +4 -0
- package/dist/extensions/vendor/openviking-pi/index.js.map +1 -1
- package/dist/extensions/vendor/openviking-pi/qcr-hooks.js +3 -1
- package/dist/extensions/vendor/openviking-pi/qcr-hooks.js.map +1 -1
- package/dist/extensions/vendor/openviking-pi/sync.js +81 -0
- package/dist/extensions/vendor/openviking-pi/sync.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/cli.js +14 -50
- package/dist/src/cli.js.map +1 -1
- package/dist/src/config.js +16 -0
- package/dist/src/config.js.map +1 -1
- package/dist/src/daemon.js +33 -4
- 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 +1 -0
- package/dist/src/debugroundpi.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/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/ledgercheck.js +39 -10
- package/dist/src/ledgercheck.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/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/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 +42 -12
- package/dist/src/npmverbs.js.map +1 -1
- package/dist/src/onboard/choices.js +6 -3
- package/dist/src/onboard/choices.js.map +1 -1
- package/dist/src/onboard/engine.js +33 -292
- package/dist/src/onboard/engine.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/configfill.js +18 -7
- package/dist/src/onboard/steps/configfill.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 +14 -2
- package/dist/src/onboard/steps/memory.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/toolnames.js +2 -2
- package/dist/src/onboard/toolnames.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/qcrbin.js +16 -11
- package/dist/src/qcrbin.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/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/session-command-supervisor.js +38 -9
- package/dist/src/session-command-supervisor.js.map +1 -1
- 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 +75 -9
- package/dist/src/state.js.map +1 -1
- package/dist/src/takeover.js +1 -0
- package/dist/src/takeover.js.map +1 -1
- package/dist/src/takeoverpi.js +2 -1
- package/dist/src/takeoverpi.js.map +1 -1
- package/dist/src/tui/alerts.js +4 -1
- package/dist/src/tui/alerts.js.map +1 -1
- package/dist/src/tui/board.js +2 -2
- package/dist/src/tui/board.js.map +1 -1
- package/dist/src/tui/companion.js +2 -1
- package/dist/src/tui/companion.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/index.js +9 -6
- package/dist/src/tui/index.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/remote.js +1 -1
- package/dist/src/tui/remote.js.map +1 -1
- package/dist/src/tui/route.js +2 -2
- package/dist/src/tui/route.js.map +1 -1
- package/dist/src/tui/setupstate.js +8 -5
- package/dist/src/tui/setupstate.js.map +1 -1
- package/dist/src/tui/sshtriage.js +1 -1
- package/dist/src/tui/sshtriage.js.map +1 -1
- package/dist/src/verdicts.js +12 -0
- package/dist/src/verdicts.js.map +1 -1
- package/dist/src/wire.js +9 -4
- package/dist/src/wire.js.map +1 -1
- package/dist/src/workerbreaker.js +32 -5
- package/dist/src/workerbreaker.js.map +1 -1
- package/dist/src/workerworld.js +4 -0
- package/dist/src/workerworld.js.map +1 -1
- package/docker/README.md +1 -1
- package/docker/entrypoint.sh +40 -6
- package/docker-compose.yml +16 -1
- package/extensions/cli/home.ts +14 -0
- package/extensions/cli/selfimprove.ts +18 -0
- package/extensions/home.ts +484 -0
- package/extensions/login-route.ts +1 -1
- package/extensions/onboarding.ts +8 -7
- package/extensions/selfimprove.ts +65 -0
- package/extensions/setup-scan.ts +79 -766
- package/extensions/setup.ts +14 -70
- package/extensions/vendor/openviking-pi/NOTICE +5 -0
- package/extensions/vendor/openviking-pi/README.md +39 -5
- package/extensions/vendor/openviking-pi/index.ts +4 -0
- package/extensions/vendor/openviking-pi/patches/0014-one-turn-sync-in-flight.patch +239 -0
- package/extensions/vendor/openviking-pi/qcr-hooks.ts +3 -1
- package/extensions/vendor/openviking-pi/sync.ts +80 -0
- package/extensions/vendor/openviking-pi/upstream.json +2 -1
- package/package.json +6 -4
- package/prompts/onboarding.md +8 -7
- package/schemas/review-result.v1.json +60 -0
- package/scripts/deploy.sh +8 -6
- 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/cli.ts +13 -54
- package/src/config.ts +38 -0
- package/src/daemon.ts +34 -4
- package/src/debuground.ts +3 -0
- package/src/debugroundpi.ts +1 -0
- package/src/engine/caserunner-sdk.ts +29 -314
- 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/ledgercheck.ts +45 -9
- package/src/live/publish.ts +4 -1
- package/src/livecli.ts +6 -1
- package/src/loginrefresh/handover.ts +138 -0
- package/src/loginrefresh/lock.ts +72 -3
- package/src/loginrefresh/refresher.ts +34 -5
- package/src/loginrefresh/supervisor.ts +25 -2
- package/src/npmverbs.ts +51 -11
- package/src/onboard/choices.ts +6 -3
- package/src/onboard/engine.ts +64 -434
- package/src/onboard/steps/bringup.ts +3 -2
- package/src/onboard/steps/configfill.ts +23 -7
- package/src/onboard/steps/loginshare.ts +258 -0
- package/src/onboard/steps/memory.ts +18 -2
- package/src/onboard/steps/repoconfig.ts +85 -0
- package/src/onboard/toolnames.ts +2 -2
- package/src/piagentdir.ts +12 -0
- package/src/pilogin.ts +32 -16
- package/src/qcrbin.ts +16 -11
- package/src/reviewargs.ts +119 -0
- package/src/reviewcli.ts +6 -167
- package/src/reviewdetach.ts +107 -13
- package/src/scancli.ts +75 -826
- package/src/selfimprove.ts +90 -0
- package/src/session-command-supervisor.ts +41 -8
- 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 +126 -11
- package/src/takeover.ts +5 -0
- package/src/takeoverpi.ts +3 -2
- package/src/tui/alerts.ts +9 -2
- package/src/tui/board.ts +2 -2
- package/src/tui/companion.ts +2 -1
- package/src/tui/deploytab.ts +2 -2
- package/src/tui/index.ts +9 -6
- package/src/tui/memory.ts +3 -15
- package/src/tui/memoryurl.ts +22 -0
- package/src/tui/remote.ts +1 -1
- package/src/tui/route.ts +2 -2
- package/src/tui/setupstate.ts +20 -16
- package/src/tui/sshtriage.ts +1 -1
- package/src/verdicts.ts +13 -0
- package/src/wire.ts +9 -4
- package/src/workerbreaker.ts +41 -5
- package/src/workerworld.ts +9 -1
- 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 -75
- 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 -103
- package/src/setup/ledger.ts +0 -324
- package/src/setup/stage2.ts +0 -926
- package/src/setup/textsniff.ts +0 -95
|
@@ -1,12 +1,6 @@
|
|
|
1
|
-
// The scan's leaf runner on the SDK
|
|
2
|
-
//
|
|
3
|
-
//
|
|
4
|
-
// runtime, with the same pieces the child process gets: the agent file's model,
|
|
5
|
-
// tools and body (appended to pi's own system prompt), bash-guard the one
|
|
6
|
-
// extension, no skill and no context file, a cwd that is first-party ground and
|
|
7
|
-
// never the reviewed checkout, and the allowlisted env. The outcome, the reads
|
|
8
|
-
// and the kept transcript are read off the same event stream by the same
|
|
9
|
-
// reader (`caseReadout`), so a case answers identically whichever host ran it.
|
|
1
|
+
// The scan driver's SDK leaves: the leaf runner on the SDK (scanleaves.ts
|
|
2
|
+
// `sdkCaseRunner`, the in-process twin of `piCaseRunner`) over a host this
|
|
3
|
+
// module builds per case, on the owner's borrowed login.
|
|
10
4
|
//
|
|
11
5
|
// WHERE IT RUNS. Only in scancli's detached driver, a disposable one-scan
|
|
12
6
|
// process (the scan sandbox or the host process `detachDriver` starts), whose
|
|
@@ -20,251 +14,20 @@
|
|
|
20
14
|
// login (engineCredentials): a token the companion refreshed mid-scan is
|
|
21
15
|
// picked up at the next case, a token the case would not outlive is refused
|
|
22
16
|
// before it starts, and nothing is ever refreshed or written here.
|
|
23
|
-
import {
|
|
24
|
-
import { homedir
|
|
25
|
-
import {
|
|
26
|
-
import {
|
|
27
|
-
import { CASE_STOP_GRACE_MS } from "@quickchatai/pi-quickreview/src/casebudget.js";
|
|
28
|
-
import { splitModelSpec } from "../config.js";
|
|
29
|
-
import { AuthError, AuthExpiring, SCAN_AUTH_SRC_ENV, SCAN_CASE_AUTH_BUDGET_MS, engineCredentials, scanAuthExpiring, scanAuthMissing, } from "@quickchatai/pi-quickreview/src/engine/auth.js";
|
|
30
|
-
import { TRANSCRIPT_RUNS_KEPT, caseReadout, leafEnv, parseAgentFile, pruneTranscripts, stderrExcerpt, transcriptFile, } from "../setup/caserunner.js";
|
|
31
|
-
import { LENS_SESSIONS_DIR } from "@quickchatai/pi-quickreview/src/engine/openable.js";
|
|
17
|
+
import { copyFileSync, existsSync, mkdirSync, rmSync } from "node:fs";
|
|
18
|
+
import { homedir } from "node:os";
|
|
19
|
+
import { isAbsolute, join } from "node:path";
|
|
20
|
+
import { AuthExpiring, SCAN_AUTH_SRC_ENV, SCAN_CASE_AUTH_BUDGET_MS, engineCredentials, scanAuthExpiring, scanAuthMissing, } from "@quickchatai/pi-quickreview/src/engine/auth.js";
|
|
32
21
|
import { PiHost } from "@quickchatai/pi-quickreview/src/engine/pisdk.js";
|
|
33
|
-
import { sdkRuntime
|
|
22
|
+
import { sdkRuntime } from "@quickchatai/pi-quickreview/src/engine/sdkruntime.js";
|
|
34
23
|
import { BUDGET_EXIT_CODE } from "@quickchatai/pi-quickreview/src/engine/budget.js";
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
*
|
|
39
|
-
|
|
40
|
-
/** What the model's bash may draw from the leaf env, beyond pi's defaults:
|
|
41
|
-
* certificates, proxies, XDG dirs and the temp dirs. Never a provider key. */
|
|
42
|
-
const LEAF_BASH_ENV_ALLOW = [
|
|
43
|
-
"TMP",
|
|
44
|
-
"TEMP",
|
|
45
|
-
"XDG_*",
|
|
46
|
-
"SSL_CERT_FILE",
|
|
47
|
-
"SSL_CERT_DIR",
|
|
48
|
-
"NODE_EXTRA_CA_CERTS",
|
|
49
|
-
"HTTP_PROXY",
|
|
50
|
-
"HTTPS_PROXY",
|
|
51
|
-
"NO_PROXY",
|
|
52
|
-
"ALL_PROXY",
|
|
53
|
-
"http_proxy",
|
|
54
|
-
"https_proxy",
|
|
55
|
-
"no_proxy",
|
|
56
|
-
"all_proxy",
|
|
57
|
-
];
|
|
58
|
-
/** A transcript's path under `dir`, relative and absolute, with its run
|
|
59
|
-
* directory made (and the old runs pruned when it is new); null when it cannot
|
|
60
|
-
* be made. A transcript is evidence, never a reason to fail a case. */
|
|
61
|
-
function openTranscript(dir, id) {
|
|
62
|
-
try {
|
|
63
|
-
const rel = transcriptFile(id);
|
|
64
|
-
const at = join(dir, rel);
|
|
65
|
-
const runDir = rel.includes("/") ? rel.slice(0, rel.indexOf("/")) : null;
|
|
66
|
-
const fresh = runDir !== null && !existsSync(join(dir, runDir));
|
|
67
|
-
mkdirSync(dirname(at), { recursive: true });
|
|
68
|
-
if (fresh)
|
|
69
|
-
pruneTranscripts(dir, TRANSCRIPT_RUNS_KEPT, runDir);
|
|
70
|
-
writeFileSync(at, "", { mode: 0o600 });
|
|
71
|
-
return { rel, at };
|
|
72
|
-
}
|
|
73
|
-
catch {
|
|
74
|
-
return null;
|
|
75
|
-
}
|
|
76
|
-
}
|
|
77
|
-
/** Where a case's session JSONL goes: `<run>/lens-sessions/<case>/` beside the
|
|
78
|
-
* transcript `rel` names (`<run>/<case>.jsonl`). */
|
|
79
|
-
export function caseSessionDir(transcriptDir, rel) {
|
|
80
|
-
return join(transcriptDir, dirname(rel), LENS_SESSIONS_DIR, basename(rel, ".jsonl"));
|
|
81
|
-
}
|
|
82
|
-
/**
|
|
83
|
-
* Runs a case as one SDK session, the way `piCaseRunner` runs it as one child:
|
|
84
|
-
* the agent's model (its `:thinking` suffix as the session's thinking level),
|
|
85
|
-
* its tools, its body appended to pi's system prompt, the task as the one
|
|
86
|
-
* message. The answer is the last assistant message's text; the cost is pi's
|
|
87
|
-
* own per-message accounting summed (null when it reported none); `reads` is the
|
|
88
|
-
* `read`/`grep` calls that finished without an error, resolved against `cwd`.
|
|
89
|
-
* With `transcriptDir` the session's whole event stream is kept at
|
|
90
|
-
* `transcriptFile(spec.id)` under it, the format `pi --mode json` prints, and
|
|
91
|
-
* its session JSONL beside it (`caseSessionDir`). An
|
|
92
|
-
* abort stops the session (abort, then dispose after the stop grace). Every
|
|
93
|
-
* outcome resolves — a runtime that cannot be built or a session that cannot
|
|
94
|
-
* start is a failed case, never a rejection.
|
|
95
|
-
*/
|
|
24
|
+
import { LEAF_TURN_TIMEOUT_MS, sdkCaseRunner as sdkCaseRunnerOver, } from "@quickchatai/pi-quickreview/src/scan/scanleaves.js";
|
|
25
|
+
export { LEAF_TURN_TIMEOUT_MS, caseSessionDir, } from "@quickchatai/pi-quickreview/src/scan/scanleaves.js";
|
|
26
|
+
/** `sdkCaseRunner` (scanleaves.ts) in this process: the leaf env filtered
|
|
27
|
+
* from this process's env and a read's `~` taken as this process's home,
|
|
28
|
+
* unless told otherwise. */
|
|
96
29
|
export function sdkCaseRunner(opts) {
|
|
97
|
-
return {
|
|
98
|
-
run: async (spec, signal, onCost) => {
|
|
99
|
-
if (!/^[a-z][a-z0-9-]*$/.test(spec.agent))
|
|
100
|
-
return {
|
|
101
|
-
ok: false,
|
|
102
|
-
reason: `not an agent name: ${JSON.stringify(spec.agent)}`,
|
|
103
|
-
cost_usd: 0,
|
|
104
|
-
};
|
|
105
|
-
let agent;
|
|
106
|
-
try {
|
|
107
|
-
agent = parseAgentFile(readFileSync(join(opts.agentsDir, `${spec.agent}.md`), "utf8"));
|
|
108
|
-
}
|
|
109
|
-
catch {
|
|
110
|
-
return { ok: false, reason: `no agent ${spec.agent} in ${opts.agentsDir}`, cost_usd: 0 };
|
|
111
|
-
}
|
|
112
|
-
if (agent === null || agent.name !== spec.agent)
|
|
113
|
-
return { ok: false, reason: `${spec.agent}.md is not an agent file`, cost_usd: 0 };
|
|
114
|
-
const modelSpec = agent.model ?? opts.defaultModel;
|
|
115
|
-
if (!modelSpec)
|
|
116
|
-
return { ok: false, reason: `${spec.agent} names no model and none is set`, cost_usd: 0 };
|
|
117
|
-
if (signal.aborted)
|
|
118
|
-
return { ok: false, reason: "stopped before it started", cost_usd: 0 };
|
|
119
|
-
let tmp;
|
|
120
|
-
try {
|
|
121
|
-
tmp = mkdtempSync(join(tmpdir(), "qcr-case-"));
|
|
122
|
-
}
|
|
123
|
-
catch (err) {
|
|
124
|
-
return { ok: false, reason: `no temp directory for the case: ${String(err)}`, cost_usd: 0 };
|
|
125
|
-
}
|
|
126
|
-
let session;
|
|
127
|
-
try {
|
|
128
|
-
const env = leafEnv(opts.env);
|
|
129
|
-
const { model, thinking } = splitModelSpec(modelSpec);
|
|
130
|
-
const guard = opts.guard ?? createBashGuard(bashGuardConfigFromEnv(env, opts.cwd));
|
|
131
|
-
const extras = () => ({
|
|
132
|
-
extensions: [guard],
|
|
133
|
-
appendSystemPrompt: [agent.systemPrompt],
|
|
134
|
-
bashEnv: { allow: LEAF_BASH_ENV_ALLOW },
|
|
135
|
-
...(thinking !== null
|
|
136
|
-
? { thinkingLevel: thinking }
|
|
137
|
-
: {}),
|
|
138
|
-
});
|
|
139
|
-
// The transcript: opened before the session, appended event by event,
|
|
140
|
-
// abandoned (and its name dropped from the outcome) at the first write
|
|
141
|
-
// that fails.
|
|
142
|
-
const opened = opts.transcriptDir !== undefined ? openTranscript(opts.transcriptDir, spec.id) : null;
|
|
143
|
-
const sessionSpec = {
|
|
144
|
-
cwd: opts.cwd,
|
|
145
|
-
env,
|
|
146
|
-
model,
|
|
147
|
-
...(agent.tools.length > 0 ? { tools: agent.tools } : {}),
|
|
148
|
-
name: spec.id,
|
|
149
|
-
// The case's session JSONL beside its transcript, so the case
|
|
150
|
-
// opens in pi: `qcr open <run dir> --lens <case>`.
|
|
151
|
-
...(opts.transcriptDir !== undefined && opened !== null
|
|
152
|
-
? { sessionDir: caseSessionDir(opts.transcriptDir, opened.rel) }
|
|
153
|
-
: {}),
|
|
154
|
-
eventsFile: join(tmp, "events.jsonl"),
|
|
155
|
-
stderrFile: join(tmp, "stderr.txt"),
|
|
156
|
-
limits: { timeoutMs: opts.timeoutMs ?? LEAF_TURN_TIMEOUT_MS },
|
|
157
|
-
};
|
|
158
|
-
let transcript = opened?.rel;
|
|
159
|
-
let transcriptAt = opened?.at ?? null;
|
|
160
|
-
const keep = (event) => {
|
|
161
|
-
if (transcriptAt === null)
|
|
162
|
-
return;
|
|
163
|
-
try {
|
|
164
|
-
appendFileSync(transcriptAt, JSON.stringify(event) + "\n");
|
|
165
|
-
}
|
|
166
|
-
catch {
|
|
167
|
-
transcriptAt = null;
|
|
168
|
-
transcript = undefined;
|
|
169
|
-
}
|
|
170
|
-
};
|
|
171
|
-
const readout = caseReadout(opts.cwd, onCost);
|
|
172
|
-
const finish = (o) => transcript === undefined ? o : { ...o, transcript };
|
|
173
|
-
try {
|
|
174
|
-
const runtime = await opts.runtime(extras);
|
|
175
|
-
session = await runtime.create(sessionSpec);
|
|
176
|
-
}
|
|
177
|
-
catch (err) {
|
|
178
|
-
const reason = err instanceof Error ? err.message : String(err);
|
|
179
|
-
// A refused login already says what to do; anything else is the host's.
|
|
180
|
-
return {
|
|
181
|
-
ok: false,
|
|
182
|
-
reason: err instanceof AuthError ? reason : `could not start the session: ${reason}`,
|
|
183
|
-
cost_usd: 0,
|
|
184
|
-
};
|
|
185
|
-
}
|
|
186
|
-
session.subscribe((event) => {
|
|
187
|
-
keep(event);
|
|
188
|
-
readout.feed(event);
|
|
189
|
-
});
|
|
190
|
-
let stopped = false;
|
|
191
|
-
let hardStop;
|
|
192
|
-
const gone = new Promise((resolve) => {
|
|
193
|
-
hardStop = resolve;
|
|
194
|
-
});
|
|
195
|
-
const onAbort = () => {
|
|
196
|
-
stopped = true;
|
|
197
|
-
const live = session;
|
|
198
|
-
void live?.abort().catch(() => { });
|
|
199
|
-
// The stop grace, then the session is released; a turn still not
|
|
200
|
-
// settled a grace later is given up on, so the case resolves.
|
|
201
|
-
setTimeout(() => void live?.dispose().catch(() => { }), CASE_STOP_GRACE_MS).unref();
|
|
202
|
-
setTimeout(() => hardStop?.({ ok: false, reason: "stopped", cost_usd: readout.spent() }), 2 * CASE_STOP_GRACE_MS).unref();
|
|
203
|
-
};
|
|
204
|
-
signal.addEventListener("abort", onAbort, { once: true });
|
|
205
|
-
if (signal.aborted) {
|
|
206
|
-
onAbort();
|
|
207
|
-
// Cancelled while the session was being created: no turn starts.
|
|
208
|
-
return finish({ ok: false, reason: "stopped", cost_usd: 0 });
|
|
209
|
-
}
|
|
210
|
-
const turn = (async () => {
|
|
211
|
-
let result;
|
|
212
|
-
try {
|
|
213
|
-
result = await session.prompt(`Task: ${spec.prompt}`);
|
|
214
|
-
}
|
|
215
|
-
catch (err) {
|
|
216
|
-
return {
|
|
217
|
-
ok: false,
|
|
218
|
-
reason: `the session failed: ${err instanceof Error ? err.message : String(err)}`,
|
|
219
|
-
cost_usd: readout.spent(),
|
|
220
|
-
};
|
|
221
|
-
}
|
|
222
|
-
// What a case that ended without an answer had spent: a failure costs
|
|
223
|
-
// money too, and a caller holding a budget must count it.
|
|
224
|
-
const cost_usd = readout.spent();
|
|
225
|
-
if (stopped)
|
|
226
|
-
return { ok: false, reason: "stopped", cost_usd };
|
|
227
|
-
if (result.timedOut)
|
|
228
|
-
return { ok: false, reason: "the case ran past its wall clock", cost_usd };
|
|
229
|
-
// The model's own reason leads: a provider error also ends the turn non-zero.
|
|
230
|
-
if (readout.failure !== null)
|
|
231
|
-
return { ok: false, reason: readout.failure, cost_usd };
|
|
232
|
-
if (result.code !== 0) {
|
|
233
|
-
let tail = "";
|
|
234
|
-
try {
|
|
235
|
-
tail = stderrExcerpt(readFileSync(sessionSpec.stderrFile, "utf8"));
|
|
236
|
-
}
|
|
237
|
-
catch {
|
|
238
|
-
// No stderr to quote.
|
|
239
|
-
}
|
|
240
|
-
return {
|
|
241
|
-
ok: false,
|
|
242
|
-
reason: `the session ended without a result${tail ? `: ${tail}` : ""}`,
|
|
243
|
-
cost_usd,
|
|
244
|
-
};
|
|
245
|
-
}
|
|
246
|
-
if (readout.final.trim() === "")
|
|
247
|
-
return { ok: false, reason: "the subagent gave no answer", cost_usd };
|
|
248
|
-
return { ok: true, output: readout.final, cost_usd, reads: readout.reads };
|
|
249
|
-
})();
|
|
250
|
-
try {
|
|
251
|
-
return finish(await Promise.race([turn, gone]));
|
|
252
|
-
}
|
|
253
|
-
finally {
|
|
254
|
-
signal.removeEventListener("abort", onAbort);
|
|
255
|
-
}
|
|
256
|
-
}
|
|
257
|
-
finally {
|
|
258
|
-
try {
|
|
259
|
-
await session?.dispose();
|
|
260
|
-
}
|
|
261
|
-
catch {
|
|
262
|
-
// Already released.
|
|
263
|
-
}
|
|
264
|
-
rmSync(tmp, { recursive: true, force: true });
|
|
265
|
-
}
|
|
266
|
-
},
|
|
267
|
-
};
|
|
30
|
+
return sdkCaseRunnerOver({ ...opts, env: opts.env ?? process.env, home: opts.home ?? homedir() });
|
|
268
31
|
}
|
|
269
32
|
/** Where the borrowed login is read from: the scan container's read-only mount
|
|
270
33
|
* of the companion's agent dir, else the process's own pi agent dir. */
|
|
@@ -284,6 +47,7 @@ export function scanSdkCases(o) {
|
|
|
284
47
|
throw new Error(`the SDK host's agentDir must be absolute: ${o.agentDir}`);
|
|
285
48
|
return sdkCaseRunner({
|
|
286
49
|
agentsDir: o.agentsDir,
|
|
50
|
+
home: homedir(),
|
|
287
51
|
cwd: o.cwd,
|
|
288
52
|
...(o.transcriptDir !== undefined ? { transcriptDir: o.transcriptDir } : {}),
|
|
289
53
|
env: o.env,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"caserunner-sdk.js","sourceRoot":"","sources":["../../../src/engine/caserunner-sdk.ts"],"names":[],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"caserunner-sdk.js","sourceRoot":"","sources":["../../../src/engine/caserunner-sdk.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,349 @@
|
|
|
1
|
+
// The home's real ports (src/home/ports.ts), and the one function that turns
|
|
2
|
+
// a process's environment into the home's options: the env shim
|
|
3
|
+
// (extensions/cli/home.ts) calls `homeOptionsFromEnv(process.env)`.
|
|
4
|
+
//
|
|
5
|
+
// pi login the auth file of the pi home the chat runs in: pi's own
|
|
6
|
+
// agent dir ($PI_CODING_AGENT_DIR, else ~/.pi/agent), read the
|
|
7
|
+
// way pi reads it, so the login line and the chat cannot
|
|
8
|
+
// disagree. Provider ids only, never a token.
|
|
9
|
+
// GitHub `gh`: the account, the repository's open PRs, the browser.
|
|
10
|
+
// repository `[github] repo` of the install's config.toml, read again on
|
|
11
|
+
// every refresh.
|
|
12
|
+
// clock Date.now.
|
|
13
|
+
// reviews the app's detached review runs, its review state and the
|
|
14
|
+
// daemon's status (src/home/reviews.ts), as the person: their
|
|
15
|
+
// environment, so the run uses their own pi login.
|
|
16
|
+
//
|
|
17
|
+
// auto-review, memory
|
|
18
|
+
// this machine's compose stack (src/home/autoreview.ts,
|
|
19
|
+
// src/home/memory.ts): the containers, the daemon's own
|
|
20
|
+
// status.json, and the switches over the wizard's steps.
|
|
21
|
+
// login owner
|
|
22
|
+
// the same pi agent dir: whether auto-review's refresher holds
|
|
23
|
+
// the login (its lock beside auth.json, shared into the stack)
|
|
24
|
+
// and whether its record says the login expired
|
|
25
|
+
// (src/home/loginowner.ts).
|
|
26
|
+
//
|
|
27
|
+
// spend the app's detached runs' costs and the daemon's recorded
|
|
28
|
+
// costs (src/home/spend.ts): unknown when either can't be read.
|
|
29
|
+
//
|
|
30
|
+
// The stack these drive is a compose project with the wizard's state under it
|
|
31
|
+
// (`homeStackRoot`): a checkout or the image is its own, an app installed by
|
|
32
|
+
// a package manager gets one in its state home, never inside the package.
|
|
33
|
+
import { execFile } from "node:child_process";
|
|
34
|
+
import { cpSync, existsSync, mkdirSync, readFileSync } from "node:fs";
|
|
35
|
+
import { join } from "node:path";
|
|
36
|
+
import { parse } from "smol-toml";
|
|
37
|
+
import { loginSummary } from "@quickchatai/pi-quickreview/src/engine/auth.js";
|
|
38
|
+
import { assetRoot } from "@quickchatai/pi-quickreview/src/assetroot.js";
|
|
39
|
+
import { postSavedReview } from "@quickchatai/pi-quickreview/src/savedpost.js";
|
|
40
|
+
import { HOME_DEFAULTS, sandboxRoot } from "../config.js";
|
|
41
|
+
import { loadOneShotConfig, locateConfig, stackRoot, stateHome } from "../homes.js";
|
|
42
|
+
import { openStepMemoryForward } from "../onboard/stepforward.js";
|
|
43
|
+
import { composeAutoReview, serviceState } from "./autoreview.js";
|
|
44
|
+
import { hostLoginOwner } from "./loginowner.js";
|
|
45
|
+
import { DAEMON_SERVICE } from "../onboard/steps/compose.js";
|
|
46
|
+
import { daemonSnapshot } from "./daemonstatus.js";
|
|
47
|
+
import { composeMemory } from "./memory.js";
|
|
48
|
+
import { realSpendPort } from "./spend.js";
|
|
49
|
+
import { composeAdvanced } from "./advanced.js";
|
|
50
|
+
import { checkoutTune } from "./tune.js";
|
|
51
|
+
import { stepRunner } from "./switchon.js";
|
|
52
|
+
import { piAgentDir } from "../piagentdir.js";
|
|
53
|
+
import { qcrChild, realDetachSeams, reviewsPort } from "./reviews.js";
|
|
54
|
+
import { known, unknown, } from "./ports.js";
|
|
55
|
+
/** The launch hands the child pi its model and tool set in these. */
|
|
56
|
+
export const HOME_MODEL_ENV = "QCR_HOME_MODEL";
|
|
57
|
+
export const HOME_TOOLS_ENV = "QCR_HOME_TOOLS";
|
|
58
|
+
export const execRunner = {
|
|
59
|
+
run: (cmd, args) => new Promise((resolve) => {
|
|
60
|
+
execFile(cmd, [...args], { timeout: 30_000, maxBuffer: 16 << 20 }, (err, stdout, stderr) => {
|
|
61
|
+
const e = err;
|
|
62
|
+
resolve({
|
|
63
|
+
code: e === null ? 0 : typeof e.code === "number" ? e.code : 1,
|
|
64
|
+
stdout: String(stdout),
|
|
65
|
+
stderr: e && !stderr ? String(e.message) : String(stderr),
|
|
66
|
+
...(e?.code === "ENOENT" ? { missing: true } : {}),
|
|
67
|
+
});
|
|
68
|
+
});
|
|
69
|
+
}),
|
|
70
|
+
};
|
|
71
|
+
const firstLine = (s) => s.trim().split("\n")[0]?.trim() || "no output";
|
|
72
|
+
const isMissingFile = (err) => err?.code === "ENOENT";
|
|
73
|
+
const message = (err) => (err instanceof Error ? err.message : String(err));
|
|
74
|
+
/** The providers pi holds a login for in `agentDir`. No auth file is no
|
|
75
|
+
* login; a file that cannot be read or parsed is unknown. */
|
|
76
|
+
export function piLoginPort(agentDir, read = (p) => readFileSync(p, "utf8")) {
|
|
77
|
+
return {
|
|
78
|
+
providers: async () => {
|
|
79
|
+
const path = join(agentDir, "auth.json");
|
|
80
|
+
let raw;
|
|
81
|
+
try {
|
|
82
|
+
raw = read(path);
|
|
83
|
+
}
|
|
84
|
+
catch (err) {
|
|
85
|
+
return isMissingFile(err) ? known([]) : unknown(`can't read ${path}: ${message(err)}`);
|
|
86
|
+
}
|
|
87
|
+
try {
|
|
88
|
+
return known(Object.keys(loginSummary(raw)));
|
|
89
|
+
}
|
|
90
|
+
catch (err) {
|
|
91
|
+
return unknown(`can't parse ${path}: ${message(err)}`);
|
|
92
|
+
}
|
|
93
|
+
},
|
|
94
|
+
};
|
|
95
|
+
}
|
|
96
|
+
/** gh's words for "you are not signed in". */
|
|
97
|
+
const SIGNED_OUT = /gh auth login|not logged in|authentication required|HTTP 401|bad credentials/i;
|
|
98
|
+
const PR_FIELDS = "number,title,author,updatedAt,isDraft,additions,deletions,changedFiles,headRefName,headRefOid";
|
|
99
|
+
export function githubPort(runner) {
|
|
100
|
+
const why = (r) => r.missing ? "gh is not installed" : `gh failed: ${firstLine(r.stderr)}`;
|
|
101
|
+
return {
|
|
102
|
+
user: async () => {
|
|
103
|
+
const r = await runner.run("gh", ["api", "user", "--jq", ".login"]);
|
|
104
|
+
if (r.code === 0 && r.stdout.trim() !== "")
|
|
105
|
+
return known(r.stdout.trim());
|
|
106
|
+
if (!r.missing && SIGNED_OUT.test(r.stderr))
|
|
107
|
+
return known(null);
|
|
108
|
+
return unknown(why(r));
|
|
109
|
+
},
|
|
110
|
+
openPulls: async (repo) => {
|
|
111
|
+
const r = await runner.run("gh", [
|
|
112
|
+
"pr",
|
|
113
|
+
"list",
|
|
114
|
+
"-R",
|
|
115
|
+
repo,
|
|
116
|
+
"--state",
|
|
117
|
+
"open",
|
|
118
|
+
"--limit",
|
|
119
|
+
"200",
|
|
120
|
+
"--json",
|
|
121
|
+
PR_FIELDS,
|
|
122
|
+
]);
|
|
123
|
+
if (r.code !== 0)
|
|
124
|
+
return unknown(why(r));
|
|
125
|
+
try {
|
|
126
|
+
return known(parsePulls(r.stdout));
|
|
127
|
+
}
|
|
128
|
+
catch (err) {
|
|
129
|
+
return unknown(`gh's answer is not a pull request list: ${message(err)}`);
|
|
130
|
+
}
|
|
131
|
+
},
|
|
132
|
+
openInBrowser: async (repo, pr) => {
|
|
133
|
+
const r = await runner.run("gh", ["pr", "view", String(pr), "-R", repo, "--web"]);
|
|
134
|
+
return r.code === 0 ? { ok: true } : { ok: false, why: why(r) };
|
|
135
|
+
},
|
|
136
|
+
};
|
|
137
|
+
}
|
|
138
|
+
/** `gh pr list --json` rows as OpenPulls; throws on a row of the wrong shape. */
|
|
139
|
+
export function parsePulls(json) {
|
|
140
|
+
const rows = JSON.parse(json);
|
|
141
|
+
if (!Array.isArray(rows))
|
|
142
|
+
throw new Error("not an array");
|
|
143
|
+
return rows.map((r) => {
|
|
144
|
+
if (typeof r["number"] !== "number" || typeof r["title"] !== "string")
|
|
145
|
+
throw new Error("a row without a number or title");
|
|
146
|
+
const author = r["author"];
|
|
147
|
+
const num = (k) => (typeof r[k] === "number" ? r[k] : 0);
|
|
148
|
+
return {
|
|
149
|
+
number: r["number"],
|
|
150
|
+
title: r["title"],
|
|
151
|
+
author: typeof author?.login === "string" ? author.login : "ghost",
|
|
152
|
+
updatedAt: typeof r["updatedAt"] === "string" ? r["updatedAt"] : "",
|
|
153
|
+
isDraft: r["isDraft"] === true,
|
|
154
|
+
additions: num("additions"),
|
|
155
|
+
deletions: num("deletions"),
|
|
156
|
+
changedFiles: num("changedFiles"),
|
|
157
|
+
headRefName: typeof r["headRefName"] === "string" ? r["headRefName"] : "",
|
|
158
|
+
headSha: typeof r["headRefOid"] === "string" ? r["headRefOid"] : "",
|
|
159
|
+
};
|
|
160
|
+
});
|
|
161
|
+
}
|
|
162
|
+
/** `[github] repo` of the config at `configPath()`, located again on every
|
|
163
|
+
* read. No config file, or an empty repo, is no repository. */
|
|
164
|
+
export function repoPort(configPath, read = (p) => readFileSync(p, "utf8")) {
|
|
165
|
+
return {
|
|
166
|
+
repo: async () => {
|
|
167
|
+
let path;
|
|
168
|
+
let raw;
|
|
169
|
+
try {
|
|
170
|
+
path = configPath();
|
|
171
|
+
raw = read(path);
|
|
172
|
+
}
|
|
173
|
+
catch (err) {
|
|
174
|
+
return isMissingFile(err) ? known(null) : unknown(message(err));
|
|
175
|
+
}
|
|
176
|
+
let repo;
|
|
177
|
+
try {
|
|
178
|
+
repo = parse(raw)["github"]?.["repo"];
|
|
179
|
+
}
|
|
180
|
+
catch (err) {
|
|
181
|
+
return unknown(`${path} is not valid TOML: ${message(err)}`);
|
|
182
|
+
}
|
|
183
|
+
if (repo === undefined || repo === "")
|
|
184
|
+
return known(null);
|
|
185
|
+
return typeof repo === "string" && /^[\w.-]+\/[\w.-]+$/.test(repo.trim())
|
|
186
|
+
? known(repo.trim())
|
|
187
|
+
: unknown(`${path}: [github] repo is not "owner/name" (${JSON.stringify(repo)})`);
|
|
188
|
+
},
|
|
189
|
+
};
|
|
190
|
+
}
|
|
191
|
+
const NOT_YET = "the home cannot read it yet";
|
|
192
|
+
const notYet = async () => unknown(NOT_YET);
|
|
193
|
+
/** The ports that have no adapter yet: each answers unknown. */
|
|
194
|
+
export const unbuiltPorts = {
|
|
195
|
+
autoReview: { status: notYet },
|
|
196
|
+
memory: { status: notYet },
|
|
197
|
+
spend: { totals: notYet },
|
|
198
|
+
};
|
|
199
|
+
/** The reviewer as the person: the app's own bin and registry, the install's
|
|
200
|
+
* state home and config, in the environment the home runs in; auto-review's
|
|
201
|
+
* rounds from the daemon of the compose stack at `stack.root`. */
|
|
202
|
+
export function realReviewsPort(env, stack) {
|
|
203
|
+
const state = stateHome(env);
|
|
204
|
+
const appRoot = sandboxRoot();
|
|
205
|
+
// the home's own working directory (src/home/launch.ts `homePaths`)
|
|
206
|
+
const cwd = join(state, "home");
|
|
207
|
+
const proc = { execPath: process.execPath, bin: join(appRoot, "bin", "qcr.js"), cwd, env };
|
|
208
|
+
const config = () => loadOneShotConfig({ root: assetRoot(), env }).cfg;
|
|
209
|
+
return reviewsPort({
|
|
210
|
+
registry: join(state, "review", "detached"),
|
|
211
|
+
reportsDir: join(cwd, "reviews"),
|
|
212
|
+
reviewHome: join(state, "review"),
|
|
213
|
+
snapshot: () => daemonSnapshot(stack.runner, stack.root),
|
|
214
|
+
qcr: qcrChild(proc),
|
|
215
|
+
detach: realDetachSeams(proc),
|
|
216
|
+
post: async (file) => {
|
|
217
|
+
const r = await postSavedReview(file, {
|
|
218
|
+
config: config(),
|
|
219
|
+
dryrunDir: join(state, "review", "dryrun"),
|
|
220
|
+
github: { env },
|
|
221
|
+
});
|
|
222
|
+
return { failed: r.failed, line: r.line };
|
|
223
|
+
},
|
|
224
|
+
dryRun: () => config().dry_run,
|
|
225
|
+
now: () => Date.now(),
|
|
226
|
+
});
|
|
227
|
+
}
|
|
228
|
+
/** The wizard's adapters for switch-on's steps, over the app root. */
|
|
229
|
+
export function stepAdapters(root, configPath) {
|
|
230
|
+
return (log) => ({
|
|
231
|
+
fetch: (input, init) => fetch(input, init),
|
|
232
|
+
runner: stepRunner,
|
|
233
|
+
clock: () => new Date(),
|
|
234
|
+
host: {
|
|
235
|
+
nodeVersion: process.version,
|
|
236
|
+
uid: typeof process.getuid === "function" ? process.getuid() : null,
|
|
237
|
+
inContainer: existsSync("/.dockerenv"),
|
|
238
|
+
},
|
|
239
|
+
paths: { stateDir: join(root, "state"), configPath: configPath() },
|
|
240
|
+
log,
|
|
241
|
+
memoryForward: (req) => openStepMemoryForward(req),
|
|
242
|
+
});
|
|
243
|
+
}
|
|
244
|
+
export function realHomeAdapters(o) {
|
|
245
|
+
const repo = repoPort(o.configPath);
|
|
246
|
+
const stack = o.root === undefined
|
|
247
|
+
? null
|
|
248
|
+
: {
|
|
249
|
+
root: o.root,
|
|
250
|
+
configPath: o.configPath,
|
|
251
|
+
runner: stepRunner,
|
|
252
|
+
stepAdapters: stepAdapters(o.root, o.configPath),
|
|
253
|
+
};
|
|
254
|
+
const daemonRuns = stack
|
|
255
|
+
? async () => {
|
|
256
|
+
const s = await serviceState(stack.runner, stack.root, DAEMON_SERVICE);
|
|
257
|
+
return s.kind === "known" ? s.value !== "stopped" : null;
|
|
258
|
+
}
|
|
259
|
+
: undefined;
|
|
260
|
+
return {
|
|
261
|
+
login: piLoginPort(o.agentDir),
|
|
262
|
+
loginOwner: hostLoginOwner({
|
|
263
|
+
loginDir: o.agentDir,
|
|
264
|
+
now: () => Date.now(),
|
|
265
|
+
...(daemonRuns ? { daemonRuns } : {}),
|
|
266
|
+
}),
|
|
267
|
+
github: githubPort(o.runner ?? execRunner),
|
|
268
|
+
repo,
|
|
269
|
+
clock: { now: () => Date.now() },
|
|
270
|
+
reviews: o.reviews,
|
|
271
|
+
...unbuiltPorts,
|
|
272
|
+
...(o.spend ? { spend: o.spend } : {}),
|
|
273
|
+
...(stack
|
|
274
|
+
? {
|
|
275
|
+
// switch-on shares the home's login with the stack (src/onboard/steps/loginshare.ts)
|
|
276
|
+
autoReview: composeAutoReview({ ...stack, loginDir: o.agentDir, now: () => Date.now() }),
|
|
277
|
+
memory: composeMemory({
|
|
278
|
+
...stack,
|
|
279
|
+
repo: async () => {
|
|
280
|
+
const r = await repo.repo();
|
|
281
|
+
return r.kind === "known" ? r.value : null;
|
|
282
|
+
},
|
|
283
|
+
}),
|
|
284
|
+
}
|
|
285
|
+
: {}),
|
|
286
|
+
};
|
|
287
|
+
}
|
|
288
|
+
/** What a compose project needs from the app: the stack, the tunnel
|
|
289
|
+
* wrappers' build context, and the config template the steps fill from. */
|
|
290
|
+
export const STACK_FILES = [
|
|
291
|
+
"docker-compose.yml",
|
|
292
|
+
join("docker", "tunnel"),
|
|
293
|
+
"config.example.toml",
|
|
294
|
+
];
|
|
295
|
+
/** The compose project the home's switches drive: src/homes.ts `stackRoot`,
|
|
296
|
+
* the one rule every surface that reads the stack uses. */
|
|
297
|
+
export function homeStackRoot(env, pkgRoot = sandboxRoot()) {
|
|
298
|
+
return stackRoot(env, pkgRoot);
|
|
299
|
+
}
|
|
300
|
+
/** Give a stack outside the package the package's own STACK_FILES, again on
|
|
301
|
+
* every launch, so an update brings the stack that matches the app. The
|
|
302
|
+
* person's state there (`.env`, `state/`) is never touched. A copy that
|
|
303
|
+
* fails is left to the compose-file check, which says what is missing. */
|
|
304
|
+
export function seedStack(root, pkgRoot) {
|
|
305
|
+
if (root === pkgRoot)
|
|
306
|
+
return;
|
|
307
|
+
for (const f of STACK_FILES) {
|
|
308
|
+
const from = join(pkgRoot, f);
|
|
309
|
+
if (!existsSync(from))
|
|
310
|
+
continue;
|
|
311
|
+
try {
|
|
312
|
+
mkdirSync(root, { recursive: true });
|
|
313
|
+
cpSync(from, join(root, f), { recursive: true, force: true });
|
|
314
|
+
}
|
|
315
|
+
catch {
|
|
316
|
+
// the compose-file check names it
|
|
317
|
+
}
|
|
318
|
+
}
|
|
319
|
+
}
|
|
320
|
+
/** The home's options from a process's environment: the env shim's one call. */
|
|
321
|
+
export function homeOptionsFromEnv(env) {
|
|
322
|
+
const model = (env[HOME_MODEL_ENV] ?? "").trim() || HOME_DEFAULTS.model;
|
|
323
|
+
const tools = env[HOME_TOOLS_ENV] === "full" ? "full" : "reviewer";
|
|
324
|
+
const root = homeStackRoot(env);
|
|
325
|
+
seedStack(root, sandboxRoot());
|
|
326
|
+
const configPath = () => locateConfig({ env }).path;
|
|
327
|
+
return {
|
|
328
|
+
adapters: realHomeAdapters({
|
|
329
|
+
agentDir: piAgentDir(env),
|
|
330
|
+
configPath,
|
|
331
|
+
reviews: realReviewsPort(env, { root, runner: stepRunner }),
|
|
332
|
+
root,
|
|
333
|
+
spend: realSpendPort({
|
|
334
|
+
registry: join(stateHome(env), "review", "detached"),
|
|
335
|
+
root,
|
|
336
|
+
runner: stepRunner,
|
|
337
|
+
}),
|
|
338
|
+
}),
|
|
339
|
+
model,
|
|
340
|
+
tools,
|
|
341
|
+
tune: checkoutTune({ env, root: assetRoot, configPath, runner: stepRunner }),
|
|
342
|
+
advanced: composeAdvanced({
|
|
343
|
+
root,
|
|
344
|
+
env,
|
|
345
|
+
stepAdapters: stepAdapters(root, configPath),
|
|
346
|
+
}),
|
|
347
|
+
};
|
|
348
|
+
}
|
|
349
|
+
//# sourceMappingURL=adapters.js.map
|