@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
|
@@ -0,0 +1,214 @@
|
|
|
1
|
+
// The setup checklist's real ports (src/home/setup.ts), and the one function
|
|
2
|
+
// that turns a process's environment into them: the env shim
|
|
3
|
+
// (extensions/cli/home.ts) calls `homeSetupFromEnv(process.env, VERSION)`.
|
|
4
|
+
//
|
|
5
|
+
// first-run checks the plugin's pi-version and git steps, over a
|
|
6
|
+
// PluginHost of this process (its PATH, the running pi)
|
|
7
|
+
// repository pick `gh`: the person's recently pushed repositories, the
|
|
8
|
+
// chosen one's canonical name and default branch, and the
|
|
9
|
+
// account's login and name
|
|
10
|
+
// the write the app config the home's repo port reads
|
|
11
|
+
// (locateConfig: $QCR_CONFIG, else the install home's
|
|
12
|
+
// config.toml), patched the way the onboarding config
|
|
13
|
+
// fill patches it (src/onboard/steps/configfill.ts):
|
|
14
|
+
// comment-preserving, only the keys that change, never
|
|
15
|
+
// dry_run. A fresh config starts from the shipped
|
|
16
|
+
// template, whose dry_run = true it keeps (invariant 6).
|
|
17
|
+
// timezone the machine's IANA zone, as Intl resolves it
|
|
18
|
+
//
|
|
19
|
+
// The silent defaults ride on the repository write: the base branch is the
|
|
20
|
+
// chosen repository's (always: it belongs to that repository), and the
|
|
21
|
+
// timezone and the owner's name and login fill a value only while it is
|
|
22
|
+
// empty (or the config is new), so an owner's own choice is never overwritten.
|
|
23
|
+
import { readFileSync } from "node:fs";
|
|
24
|
+
import { homedir } from "node:os";
|
|
25
|
+
import { join } from "node:path";
|
|
26
|
+
import { assetRoot } from "@quickchatai/pi-quickreview/src/assetroot.js";
|
|
27
|
+
import { nodeRunner } from "@quickchatai/pi-quickreview/src/plugin/runner.js";
|
|
28
|
+
import { declaredPiRange } from "@quickchatai/pi-quickreview/src/plugin/versiongate.js";
|
|
29
|
+
import { writeAtomic } from "@quickchatai/pi-quickreview/src/setupchecklist.js";
|
|
30
|
+
import { locateConfig, stateHome } from "../homes.js";
|
|
31
|
+
import { piAgentDir } from "../piagentdir.js";
|
|
32
|
+
import { execRunner } from "./adapters.js";
|
|
33
|
+
import { known, unknown } from "./ports.js";
|
|
34
|
+
const firstLine = (s) => s.trim().split("\n")[0]?.trim() || "no output";
|
|
35
|
+
const message = (err) => (err instanceof Error ? err.message : String(err));
|
|
36
|
+
/** gh's words for "you are not signed in". */
|
|
37
|
+
const SIGNED_OUT = /gh auth login|not logged in|authentication required|HTTP 401|bad credentials/i;
|
|
38
|
+
function ghWhy(r) {
|
|
39
|
+
if (r.missing)
|
|
40
|
+
return "gh is not installed";
|
|
41
|
+
if (SIGNED_OUT.test(r.stderr))
|
|
42
|
+
return "gh is signed out: run `gh auth login`";
|
|
43
|
+
return firstLine(r.stderr);
|
|
44
|
+
}
|
|
45
|
+
/** The machine's IANA timezone, or null when Intl cannot say. */
|
|
46
|
+
export function systemTimezone() {
|
|
47
|
+
try {
|
|
48
|
+
const tz = Intl.DateTimeFormat().resolvedOptions().timeZone;
|
|
49
|
+
return typeof tz === "string" && tz !== "" ? tz : null;
|
|
50
|
+
}
|
|
51
|
+
catch {
|
|
52
|
+
return null;
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
/** A file's text; null only when it does not exist. Any other failure
|
|
56
|
+
* throws: a config that exists and cannot be read is never "no config", or
|
|
57
|
+
* the template would be written over it. */
|
|
58
|
+
function readIfThere(path) {
|
|
59
|
+
try {
|
|
60
|
+
return readFileSync(path, "utf8");
|
|
61
|
+
}
|
|
62
|
+
catch (err) {
|
|
63
|
+
if (err?.code === "ENOENT")
|
|
64
|
+
return null;
|
|
65
|
+
throw err;
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
export function repoPickPort(o) {
|
|
69
|
+
const read = o.read ?? readIfThere;
|
|
70
|
+
const write = o.write ?? writeAtomic;
|
|
71
|
+
return {
|
|
72
|
+
recent: async () => {
|
|
73
|
+
const r = await o.runner.run("gh", [
|
|
74
|
+
"repo",
|
|
75
|
+
"list",
|
|
76
|
+
"--limit",
|
|
77
|
+
"8",
|
|
78
|
+
"--json",
|
|
79
|
+
"nameWithOwner",
|
|
80
|
+
]);
|
|
81
|
+
if (r.code !== 0)
|
|
82
|
+
return unknown(ghWhy(r));
|
|
83
|
+
try {
|
|
84
|
+
const rows = JSON.parse(r.stdout);
|
|
85
|
+
if (!Array.isArray(rows))
|
|
86
|
+
return unknown("gh's answer is not a list");
|
|
87
|
+
return known(rows.flatMap((x) => typeof x?.nameWithOwner === "string" ? [x.nameWithOwner] : []));
|
|
88
|
+
}
|
|
89
|
+
catch (err) {
|
|
90
|
+
return unknown(`gh's answer is not JSON: ${message(err)}`);
|
|
91
|
+
}
|
|
92
|
+
},
|
|
93
|
+
describe: async (repo) => {
|
|
94
|
+
const r = await o.runner.run("gh", [
|
|
95
|
+
"repo",
|
|
96
|
+
"view",
|
|
97
|
+
repo,
|
|
98
|
+
"--json",
|
|
99
|
+
"nameWithOwner,defaultBranchRef",
|
|
100
|
+
]);
|
|
101
|
+
if (r.code !== 0)
|
|
102
|
+
return { ok: false, why: ghWhy(r) };
|
|
103
|
+
try {
|
|
104
|
+
const v = JSON.parse(r.stdout);
|
|
105
|
+
const branch = v.defaultBranchRef?.name;
|
|
106
|
+
return {
|
|
107
|
+
ok: true,
|
|
108
|
+
repo: typeof v.nameWithOwner === "string" ? v.nameWithOwner : repo,
|
|
109
|
+
defaultBranch: typeof branch === "string" && branch !== "" ? branch : null,
|
|
110
|
+
};
|
|
111
|
+
}
|
|
112
|
+
catch (err) {
|
|
113
|
+
return { ok: false, why: `gh's answer is not JSON: ${message(err)}` };
|
|
114
|
+
}
|
|
115
|
+
},
|
|
116
|
+
profile: async () => {
|
|
117
|
+
const r = await o.runner.run("gh", ["api", "user"]);
|
|
118
|
+
if (r.code !== 0)
|
|
119
|
+
return unknown(ghWhy(r));
|
|
120
|
+
try {
|
|
121
|
+
const v = JSON.parse(r.stdout);
|
|
122
|
+
if (typeof v.login !== "string")
|
|
123
|
+
return unknown("gh's account has no login");
|
|
124
|
+
return known({
|
|
125
|
+
login: v.login,
|
|
126
|
+
name: typeof v.name === "string" && v.name.trim() !== "" ? v.name.trim() : null,
|
|
127
|
+
});
|
|
128
|
+
}
|
|
129
|
+
catch (err) {
|
|
130
|
+
return unknown(`gh's answer is not JSON: ${message(err)}`);
|
|
131
|
+
}
|
|
132
|
+
},
|
|
133
|
+
write: async (choice) => {
|
|
134
|
+
let path;
|
|
135
|
+
try {
|
|
136
|
+
path = o.configPath();
|
|
137
|
+
}
|
|
138
|
+
catch (err) {
|
|
139
|
+
return { ok: false, why: message(err) };
|
|
140
|
+
}
|
|
141
|
+
let existing;
|
|
142
|
+
let template = "";
|
|
143
|
+
try {
|
|
144
|
+
existing = read(path);
|
|
145
|
+
}
|
|
146
|
+
catch (err) {
|
|
147
|
+
return { ok: false, why: `can't read ${path} (${message(err)}); nothing was written` };
|
|
148
|
+
}
|
|
149
|
+
try {
|
|
150
|
+
if (existing === null)
|
|
151
|
+
template = read(o.templatePath());
|
|
152
|
+
}
|
|
153
|
+
catch {
|
|
154
|
+
template = null;
|
|
155
|
+
}
|
|
156
|
+
if (template === null)
|
|
157
|
+
return { ok: false, why: `there is no ${path} and the shipped template is not readable` };
|
|
158
|
+
// the config fill's writer, loaded only when a repository is written
|
|
159
|
+
const { renderRepoConfig } = await import("../onboard/steps/repoconfig.js");
|
|
160
|
+
const r = renderRepoConfig(existing, template, choice);
|
|
161
|
+
if (!r.ok)
|
|
162
|
+
return r;
|
|
163
|
+
try {
|
|
164
|
+
if (r.text !== existing)
|
|
165
|
+
write(path, r.text);
|
|
166
|
+
}
|
|
167
|
+
catch (err) {
|
|
168
|
+
return { ok: false, why: `can't write ${path}: ${message(err)}` };
|
|
169
|
+
}
|
|
170
|
+
return { ok: true, path, wrote: r.wrote };
|
|
171
|
+
},
|
|
172
|
+
};
|
|
173
|
+
}
|
|
174
|
+
/** The PluginHost the first-run checks read: this process's PATH and the
|
|
175
|
+
* running pi (its version, which the env shim reads off pi). Only the
|
|
176
|
+
* plugin's pi-version and git steps run over it, so its auth answers
|
|
177
|
+
* nothing. */
|
|
178
|
+
export function firstRunHost(env, piVersion) {
|
|
179
|
+
return {
|
|
180
|
+
cwd: join(stateHome(env), "home"),
|
|
181
|
+
env,
|
|
182
|
+
home: (env["HOME"] ?? "").trim() || homedir(),
|
|
183
|
+
piVersion,
|
|
184
|
+
agentDir: piAgentDir(env),
|
|
185
|
+
auth: {
|
|
186
|
+
logins: () => ({}),
|
|
187
|
+
configured: () => false,
|
|
188
|
+
refresh: () => Promise.reject(new Error("the home's first-run checks hold no login")),
|
|
189
|
+
},
|
|
190
|
+
runner: nodeRunner(env),
|
|
191
|
+
shutdown: new AbortController().signal,
|
|
192
|
+
};
|
|
193
|
+
}
|
|
194
|
+
/** The setup's options from a process's environment and the running pi's
|
|
195
|
+
* version: the env shim's one call. */
|
|
196
|
+
export function homeSetupFromEnv(env, piVersion) {
|
|
197
|
+
let range = null;
|
|
198
|
+
try {
|
|
199
|
+
range = declaredPiRange();
|
|
200
|
+
}
|
|
201
|
+
catch {
|
|
202
|
+
range = null;
|
|
203
|
+
}
|
|
204
|
+
return {
|
|
205
|
+
...(range !== null ? { firstRun: { host: firstRunHost(env, piVersion), range } } : {}),
|
|
206
|
+
repos: repoPickPort({
|
|
207
|
+
runner: execRunner,
|
|
208
|
+
configPath: () => locateConfig({ env }).path,
|
|
209
|
+
templatePath: () => join(assetRoot(), "config.example.toml"),
|
|
210
|
+
}),
|
|
211
|
+
timezone: systemTimezone,
|
|
212
|
+
};
|
|
213
|
+
}
|
|
214
|
+
//# sourceMappingURL=setupadapters.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"setupadapters.js","sourceRoot":"","sources":["../../../src/home/setupadapters.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,199 @@
|
|
|
1
|
+
import { matchesKey, truncateToWidth, visibleWidth, wrapTextWithAnsi, } from "@earendil-works/pi-tui";
|
|
2
|
+
import { loginFailureText } from "./setup.js";
|
|
3
|
+
/** Where the card sits: centred, half the width. */
|
|
4
|
+
export const SETUP_OVERLAY = {
|
|
5
|
+
anchor: "center",
|
|
6
|
+
width: "50%",
|
|
7
|
+
minWidth: 80,
|
|
8
|
+
nonCapturing: true,
|
|
9
|
+
};
|
|
10
|
+
/** The share of the terminal's height the card fills. */
|
|
11
|
+
export const CARD_HEIGHT = 0.5;
|
|
12
|
+
/** Sub-rows (instructions, the device code) are indented under the label. */
|
|
13
|
+
const INDENT = " ";
|
|
14
|
+
const NOTICE_ROWS = 3;
|
|
15
|
+
const SPIN = ["⠋", "⠙", "⠹", "⠸", "⠼", "⠴", "⠦", "⠧", "⠇", "⠏"];
|
|
16
|
+
/** What each step's key does, in the hint beside it. */
|
|
17
|
+
const VERB = {
|
|
18
|
+
login: "sign in",
|
|
19
|
+
github: "check",
|
|
20
|
+
repo: "choose",
|
|
21
|
+
};
|
|
22
|
+
export class SetupCard {
|
|
23
|
+
th;
|
|
24
|
+
host;
|
|
25
|
+
constructor(th, host) {
|
|
26
|
+
this.th = th;
|
|
27
|
+
this.host = host;
|
|
28
|
+
}
|
|
29
|
+
c(color, s) {
|
|
30
|
+
return this.th.fg(color, s);
|
|
31
|
+
}
|
|
32
|
+
spin() {
|
|
33
|
+
return SPIN[this.host.frame() % SPIN.length];
|
|
34
|
+
}
|
|
35
|
+
edge(s) {
|
|
36
|
+
return this.c(this.host.focused() ? "borderAccent" : "borderMuted", s);
|
|
37
|
+
}
|
|
38
|
+
/** The key that runs the next step now. */
|
|
39
|
+
key() {
|
|
40
|
+
return this.host.focused() ? "⏎" : "alt+n";
|
|
41
|
+
}
|
|
42
|
+
row(w, left, right = "", selected = false) {
|
|
43
|
+
const inner = w - 4;
|
|
44
|
+
const r = right ? ` ${right}` : "";
|
|
45
|
+
const l = truncateToWidth(left, Math.max(1, inner - visibleWidth(r)), "…");
|
|
46
|
+
const gap = Math.max(0, inner - visibleWidth(l) - visibleWidth(r));
|
|
47
|
+
let text = ` ${l}${" ".repeat(gap)}${r} `;
|
|
48
|
+
if (selected)
|
|
49
|
+
text = this.th.bg("selectedBg", text);
|
|
50
|
+
return `${this.edge("│")}${text}${this.edge("│")}`;
|
|
51
|
+
}
|
|
52
|
+
/** Text under a step, wrapped inside the frame. */
|
|
53
|
+
sub(w, text, color = "muted") {
|
|
54
|
+
const room = Math.max(10, w - 4 - INDENT.length);
|
|
55
|
+
return wrapTextWithAnsi(text, room).map((l) => this.row(w, `${INDENT}${this.c(color, l)}`));
|
|
56
|
+
}
|
|
57
|
+
top(w) {
|
|
58
|
+
const left = `${this.edge("╭─ ")}${this.th.bold(this.c("accent", "quickreview"))} `;
|
|
59
|
+
const right = ` ${this.c("muted", "setup")}${this.edge(" ─╮")}`;
|
|
60
|
+
const fill = Math.max(0, w - visibleWidth(left) - visibleWidth(right));
|
|
61
|
+
return `${left}${this.edge("─".repeat(fill))}${right}`;
|
|
62
|
+
}
|
|
63
|
+
rule(w) {
|
|
64
|
+
return this.edge(`├${"─".repeat(Math.max(0, w - 2))}┤`);
|
|
65
|
+
}
|
|
66
|
+
bottom(w) {
|
|
67
|
+
return this.edge(`╰${"─".repeat(Math.max(0, w - 2))}╯`);
|
|
68
|
+
}
|
|
69
|
+
stepRows(w, s) {
|
|
70
|
+
const v = this.host.setup.view();
|
|
71
|
+
const out = [];
|
|
72
|
+
const k = this.key();
|
|
73
|
+
let mark;
|
|
74
|
+
let label;
|
|
75
|
+
let right = "";
|
|
76
|
+
if (s.state === "done") {
|
|
77
|
+
mark = this.c("success", "✓");
|
|
78
|
+
label = this.c("muted", s.title);
|
|
79
|
+
right = this.c("muted", s.found ?? "done");
|
|
80
|
+
}
|
|
81
|
+
else if (s.state === "running") {
|
|
82
|
+
mark = this.c("accent", this.spin());
|
|
83
|
+
label = this.th.bold(this.c("text", s.title));
|
|
84
|
+
right = this.c("dim", v.login.code ? "waiting for you…" : "starting…");
|
|
85
|
+
}
|
|
86
|
+
else if (s.unknown !== undefined) {
|
|
87
|
+
mark = this.c("dim", "?");
|
|
88
|
+
label = s.next ? this.th.bold(this.c("text", s.title)) : this.c("text", s.title);
|
|
89
|
+
right = s.next
|
|
90
|
+
? `${this.c("accent", k)} ${this.c("muted", VERB[s.id])}`
|
|
91
|
+
: this.c("dim", "unknown");
|
|
92
|
+
}
|
|
93
|
+
else if (s.next) {
|
|
94
|
+
mark = this.c("accent", "▸");
|
|
95
|
+
label = this.th.bold(this.c("text", s.title));
|
|
96
|
+
right = `${this.c("accent", k)} ${this.c("muted", VERB[s.id])}`;
|
|
97
|
+
}
|
|
98
|
+
else {
|
|
99
|
+
mark = this.c("dim", "○");
|
|
100
|
+
label = this.c("dim", s.title);
|
|
101
|
+
}
|
|
102
|
+
out.push(this.row(w, ` ${mark} ${label}`, right, s.next));
|
|
103
|
+
if (s.state === "done")
|
|
104
|
+
return out;
|
|
105
|
+
if (s.id === "login")
|
|
106
|
+
out.push(...this.loginRows(w, s));
|
|
107
|
+
else if (s.unknown !== undefined)
|
|
108
|
+
out.push(...this.sub(w, `Unknown — ${s.unknown}.`, "warning"));
|
|
109
|
+
else if (s.next && s.id === "github" && s.missing)
|
|
110
|
+
out.push(...this.sub(w, `${capital(s.missing)}, then ${k} checks again.`, "warning"));
|
|
111
|
+
else if (s.next && s.id === "repo")
|
|
112
|
+
out.push(...this.sub(w, "One of your recently pushed repositories, or paste any owner/name or GitHub URL."));
|
|
113
|
+
return out;
|
|
114
|
+
}
|
|
115
|
+
loginRows(w, s) {
|
|
116
|
+
const v = this.host.setup.view();
|
|
117
|
+
const k = this.key();
|
|
118
|
+
const out = [];
|
|
119
|
+
const chatgpt = v.provider === "OpenAI";
|
|
120
|
+
const setting = "Device-code login must be on first: ChatGPT → Settings → Security.";
|
|
121
|
+
if (s.state === "running") {
|
|
122
|
+
const code = v.login.code;
|
|
123
|
+
if (!code) {
|
|
124
|
+
if (chatgpt)
|
|
125
|
+
out.push(...this.sub(w, setting));
|
|
126
|
+
out.push(this.row(w, `${INDENT}${this.c("accent", this.spin())} ${this.c("dim", "asking for a code…")}`));
|
|
127
|
+
return out;
|
|
128
|
+
}
|
|
129
|
+
out.push(this.row(w, ""));
|
|
130
|
+
out.push(this.row(w, `${INDENT}${this.c("muted", "1 Open ")} ${this.c("accent", code.verificationUri)}`));
|
|
131
|
+
out.push(this.row(w, `${INDENT}${this.c("muted", "2 Enter")} ${this.th.bold(this.c("text", code.userCode))}`));
|
|
132
|
+
out.push(this.row(w, ""));
|
|
133
|
+
if (chatgpt)
|
|
134
|
+
out.push(...this.sub(w, setting, "dim"));
|
|
135
|
+
out.push(this.row(w, `${INDENT}${this.c("accent", this.spin())} ${this.c("dim", "waiting for you to approve…")}`));
|
|
136
|
+
return out;
|
|
137
|
+
}
|
|
138
|
+
if (v.login.failure)
|
|
139
|
+
out.push(...this.sub(w, loginFailureText(v.login.failure, k), "warning"));
|
|
140
|
+
if (s.unknown !== undefined)
|
|
141
|
+
out.push(...this.sub(w, `Unknown — ${s.unknown}.`, "warning"));
|
|
142
|
+
if (s.next && chatgpt && v.login.failure?.kind !== "not_enabled")
|
|
143
|
+
out.push(...this.sub(w, setting));
|
|
144
|
+
return out;
|
|
145
|
+
}
|
|
146
|
+
hints(w) {
|
|
147
|
+
const k = (key, label) => `${this.c("accent", key)} ${this.c("muted", label)}`;
|
|
148
|
+
return this.row(w, this.host.focused()
|
|
149
|
+
? `${k("⏎", "next step")} ${k("esc", "back to the chat")}`
|
|
150
|
+
: `${k("alt+n", "next step")} ${k("f2", "focus the card")} ${this.c("dim", "· or just type to ask pi")}`);
|
|
151
|
+
}
|
|
152
|
+
render(width) {
|
|
153
|
+
const w = Math.max(40, width);
|
|
154
|
+
const v = this.host.setup.view();
|
|
155
|
+
const body = [
|
|
156
|
+
this.row(w, ""),
|
|
157
|
+
this.row(w, ` ${this.th.bold(this.c("text", "Welcome to quickreview"))}`, this.c("muted", `${v.done} of ${v.total} done `)),
|
|
158
|
+
this.row(w, ` ${this.c("muted", "Sign in once, choose a repository, and review your first pull request.")}`),
|
|
159
|
+
this.row(w, ""),
|
|
160
|
+
];
|
|
161
|
+
for (const c of v.checks) {
|
|
162
|
+
body.push(this.row(w, ` ${this.c("warning", "✗")} ${this.th.bold(this.c("text", c.title))}`, c.next ? `${this.c("accent", this.key())} ${this.c("muted", "check")}` : "", c.next));
|
|
163
|
+
body.push(...this.sub(w, `${capital(c.why)}${c.next ? `, then ${this.key()} checks again.` : "."}`, "warning"));
|
|
164
|
+
}
|
|
165
|
+
for (const s of v.steps)
|
|
166
|
+
body.push(...this.stepRows(w, s));
|
|
167
|
+
body.push(this.row(w, ""));
|
|
168
|
+
const foot = [this.rule(w)];
|
|
169
|
+
const n = this.host.model.notice;
|
|
170
|
+
if (n) {
|
|
171
|
+
const color = n.kind === "ok" ? "success" : n.kind === "warn" ? "warning" : "text";
|
|
172
|
+
for (const l of wrapTextWithAnsi(n.text, w - 4).slice(0, NOTICE_ROWS))
|
|
173
|
+
foot.push(this.row(w, this.c(color, l)));
|
|
174
|
+
}
|
|
175
|
+
foot.push(this.hints(w), this.bottom(w));
|
|
176
|
+
const target = Math.round(this.host.rows() * CARD_HEIGHT);
|
|
177
|
+
const spare = Math.max(0, target - 1 - body.length - foot.length);
|
|
178
|
+
const blank = (k) => Array.from({ length: k }, () => this.row(w, ""));
|
|
179
|
+
return [
|
|
180
|
+
this.top(w),
|
|
181
|
+
...blank(Math.floor(spare / 2)),
|
|
182
|
+
...body,
|
|
183
|
+
...blank(Math.ceil(spare / 2)),
|
|
184
|
+
...foot,
|
|
185
|
+
].map((l) => truncateToWidth(l, w));
|
|
186
|
+
}
|
|
187
|
+
handleInput(data) {
|
|
188
|
+
if (matchesKey(data, "escape"))
|
|
189
|
+
this.host.unfocus();
|
|
190
|
+
else if (matchesKey(data, "enter"))
|
|
191
|
+
this.host.next();
|
|
192
|
+
}
|
|
193
|
+
handleMouse(e) {
|
|
194
|
+
return e.type === "click" ? { focus: true } : undefined;
|
|
195
|
+
}
|
|
196
|
+
invalidate() { }
|
|
197
|
+
}
|
|
198
|
+
const capital = (s) => (s ? `${s[0].toUpperCase()}${s.slice(1)}` : s);
|
|
199
|
+
//# sourceMappingURL=setupcard.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"setupcard.js","sourceRoot":"","sources":["../../../src/home/setupcard.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
// The setup checklist's `home_*` tools: each step's action, as the model in
|
|
2
|
+
// the chat calls it. The keys call the same HomeSetup methods
|
|
3
|
+
// (extensions/home.ts), so a key and a tool never do two different things.
|
|
4
|
+
import { textResult } from "@quickchatai/pi-quickreview/extensions/pi-tool.js";
|
|
5
|
+
const NO_PARAMS = { type: "object", properties: {}, additionalProperties: false };
|
|
6
|
+
/** One definition per HOME_SETUP_TOOL_NAMES entry. */
|
|
7
|
+
export function setupTools(setup) {
|
|
8
|
+
return {
|
|
9
|
+
home_setup_next: {
|
|
10
|
+
name: "home_setup_next",
|
|
11
|
+
label: "Home: next setup step",
|
|
12
|
+
description: "Run the next step of the quickreview home's setup checklist (sign in, connect GitHub, choose a repository), as alt+n does. Answers what happened, or that setup is done.",
|
|
13
|
+
parameters: NO_PARAMS,
|
|
14
|
+
execute: async () => textResult(await setup.next()),
|
|
15
|
+
},
|
|
16
|
+
home_sign_in: {
|
|
17
|
+
name: "home_sign_in",
|
|
18
|
+
label: "Home: sign in",
|
|
19
|
+
description: "Start pi's own device-code login for the provider the chat runs on. Answers with the URL and the code to enter once pi has them; the sign-in finishes in the background when the person approves it. Device-code login must be on in ChatGPT → Settings → Security.",
|
|
20
|
+
parameters: NO_PARAMS,
|
|
21
|
+
execute: async () => textResult(await setup.signIn()),
|
|
22
|
+
},
|
|
23
|
+
home_check_github: {
|
|
24
|
+
name: "home_check_github",
|
|
25
|
+
label: "Home: check GitHub",
|
|
26
|
+
description: "Check again whether gh is installed and signed in. When it is not, the answer says what to run.",
|
|
27
|
+
parameters: NO_PARAMS,
|
|
28
|
+
execute: async () => textResult(await setup.checkGithub()),
|
|
29
|
+
},
|
|
30
|
+
home_choose_repo: {
|
|
31
|
+
name: "home_choose_repo",
|
|
32
|
+
label: "Home: choose a repository",
|
|
33
|
+
description: "Set the repository the home reviews: owner/name or any GitHub URL of it. It is written to the qcr config's [github] repo. Without `repo`, answers the person's recently pushed repositories to choose from.",
|
|
34
|
+
parameters: {
|
|
35
|
+
type: "object",
|
|
36
|
+
properties: {
|
|
37
|
+
repo: { type: "string", description: "owner/name, or a GitHub URL of the repository." },
|
|
38
|
+
},
|
|
39
|
+
additionalProperties: false,
|
|
40
|
+
},
|
|
41
|
+
execute: async (_id, p) => textResult(await setup.chooseRepo(typeof p["repo"] === "string" ? p["repo"] : undefined)),
|
|
42
|
+
},
|
|
43
|
+
};
|
|
44
|
+
}
|
|
45
|
+
//# sourceMappingURL=setuptools.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"setuptools.js","sourceRoot":"","sources":["../../../src/home/setuptools.ts"],"names":[],"mappings":"AAAA,4EAA4E;AAC5E,8DAA8D;AAC9D,2EAA2E;AAC3E,OAAO,EAAE,UAAU,EAAgB,MAAM,mDAAmD,CAAC;AAM7F,MAAM,SAAS,GAAG,EAAE,IAAI,EAAE,QAAQ,EAAE,UAAU,EAAE,EAAE,EAAE,oBAAoB,EAAE,KAAK,EAAW,CAAC;AAE3F,sDAAsD;AACtD,MAAM,UAAU,UAAU,CAAC,KAAgB;IAGzC,OAAO;QACL,eAAe,EAAE;YACf,IAAI,EAAE,iBAAiB;YACvB,KAAK,EAAE,uBAAuB;YAC9B,WAAW,EACT,0KAA0K;YAC5K,UAAU,EAAE,SAAS;YACrB,OAAO,EAAE,KAAK,IAAI,EAAE,CAAC,UAAU,CAAC,MAAM,KAAK,CAAC,IAAI,EAAE,CAAC;SACpD;QACD,YAAY,EAAE;YACZ,IAAI,EAAE,cAAc;YACpB,KAAK,EAAE,eAAe;YACtB,WAAW,EACT,qQAAqQ;YACvQ,UAAU,EAAE,SAAS;YACrB,OAAO,EAAE,KAAK,IAAI,EAAE,CAAC,UAAU,CAAC,MAAM,KAAK,CAAC,MAAM,EAAE,CAAC;SACtD;QACD,iBAAiB,EAAE;YACjB,IAAI,EAAE,mBAAmB;YACzB,KAAK,EAAE,oBAAoB;YAC3B,WAAW,EACT,iGAAiG;YACnG,UAAU,EAAE,SAAS;YACrB,OAAO,EAAE,KAAK,IAAI,EAAE,CAAC,UAAU,CAAC,MAAM,KAAK,CAAC,WAAW,EAAE,CAAC;SAC3D;QACD,gBAAgB,EAAE;YAChB,IAAI,EAAE,kBAAkB;YACxB,KAAK,EAAE,2BAA2B;YAClC,WAAW,EACT,6MAA6M;YAC/M,UAAU,EAAE;gBACV,IAAI,EAAE,QAAQ;gBACd,UAAU,EAAE;oBACV,IAAI,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE,WAAW,EAAE,gDAAgD,EAAE;iBACxF;gBACD,oBAAoB,EAAE,KAAK;aAC5B;YACD,OAAO,EAAE,KAAK,EAAE,GAAG,EAAE,CAAC,EAAE,EAAE,CACxB,UAAU,CAAC,MAAM,KAAK,CAAC,UAAU,CAAC,OAAO,CAAC,CAAC,MAAM,CAAC,KAAK,QAAQ,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC;SAC5F;KACF,CAAC;AACJ,CAAC"}
|
|
@@ -0,0 +1,160 @@
|
|
|
1
|
+
// The home's spend line: today's and this month's review cost, summed from
|
|
2
|
+
// two sources (src/home/ports.ts `SpendPort`):
|
|
3
|
+
//
|
|
4
|
+
// the home the app's detached review runs (`<state home>/review/
|
|
5
|
+
// detached`, the registry the review button starts in): each
|
|
6
|
+
// run that has ended and whose result says what it cost, in
|
|
7
|
+
// the day and month it ended
|
|
8
|
+
// auto-review the daemon's recorded costs: its status snapshot's
|
|
9
|
+
// `today_spend_usd` and `month_spend_usd`, read from the
|
|
10
|
+
// daemon's own state on this machine's compose stack
|
|
11
|
+
//
|
|
12
|
+
// Today and this month are UTC days and months, the daemon's own (its
|
|
13
|
+
// snapshot, `qcr spend`): the two halves are summed over one calendar.
|
|
14
|
+
//
|
|
15
|
+
// When either source cannot be read, the total is unknown, with why (invariant
|
|
16
|
+
// 9): never a zero, and never the half that could be read passed off as the
|
|
17
|
+
// whole. A source that cannot hold a cost is a known zero, as a missing auth
|
|
18
|
+
// file is no login: a registry with no runs yet, a machine with no Docker, or
|
|
19
|
+
// a stack that was never brought up (no state volume) recorded nothing.
|
|
20
|
+
//
|
|
21
|
+
// A run still going is not counted until its result says what it cost; a run
|
|
22
|
+
// whose result names no cost has nothing to add.
|
|
23
|
+
import { listRunViews } from "../reviewdetach.js";
|
|
24
|
+
import { daemonSnapshot } from "./daemonstatus.js";
|
|
25
|
+
import { known, unknown } from "./ports.js";
|
|
26
|
+
import { parseRunStatus } from "./reviews.js";
|
|
27
|
+
const message = (err) => (err instanceof Error ? err.message : String(err));
|
|
28
|
+
/** The UTC day (`YYYY-MM-DD`) and month (`YYYY-MM`) of `ms`. */
|
|
29
|
+
export function utcPeriod(ms) {
|
|
30
|
+
const iso = new Date(ms).toISOString();
|
|
31
|
+
return { day: iso.slice(0, 10), month: iso.slice(0, 7) };
|
|
32
|
+
}
|
|
33
|
+
async function safe(read) {
|
|
34
|
+
try {
|
|
35
|
+
return await read();
|
|
36
|
+
}
|
|
37
|
+
catch (err) {
|
|
38
|
+
return unknown(message(err));
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
/** The spend port over its two sources: both read, or unknown. */
|
|
42
|
+
export function spendPort(src, now) {
|
|
43
|
+
return {
|
|
44
|
+
totals: async () => {
|
|
45
|
+
const at = now();
|
|
46
|
+
const [home, auto] = await Promise.all([safe(() => src.home()), safe(() => src.auto(at))]);
|
|
47
|
+
if (home.kind === "unknown")
|
|
48
|
+
return unknown(`the home's reviews: ${home.why}`);
|
|
49
|
+
if (auto.kind === "unknown")
|
|
50
|
+
return unknown(`auto-review's: ${auto.why}`);
|
|
51
|
+
const { day, month } = utcPeriod(at);
|
|
52
|
+
let today = auto.value.today;
|
|
53
|
+
let thisMonth = auto.value.month;
|
|
54
|
+
for (const c of home.value) {
|
|
55
|
+
if (!Number.isFinite(c.at) || !Number.isFinite(c.usd))
|
|
56
|
+
continue;
|
|
57
|
+
const p = utcPeriod(c.at);
|
|
58
|
+
if (p.month !== month)
|
|
59
|
+
continue;
|
|
60
|
+
thisMonth += c.usd;
|
|
61
|
+
if (p.day === day)
|
|
62
|
+
today += c.usd;
|
|
63
|
+
}
|
|
64
|
+
return known({ today, month: thisMonth });
|
|
65
|
+
},
|
|
66
|
+
};
|
|
67
|
+
}
|
|
68
|
+
// ---- the home's half: the detached registry -------------------------------
|
|
69
|
+
/** Is the process with this pid alive? */
|
|
70
|
+
const alive = (pid) => {
|
|
71
|
+
try {
|
|
72
|
+
process.kill(pid, 0);
|
|
73
|
+
return true;
|
|
74
|
+
}
|
|
75
|
+
catch {
|
|
76
|
+
return false;
|
|
77
|
+
}
|
|
78
|
+
};
|
|
79
|
+
/** The costs of every run in the registry at `registry` that has ended with
|
|
80
|
+
* a cost, at the time it ended. */
|
|
81
|
+
export function registryCosts(registry, o = { now: Date.now }) {
|
|
82
|
+
return async () => {
|
|
83
|
+
let views;
|
|
84
|
+
try {
|
|
85
|
+
views = listRunViews(registry, { alive: o.alive ?? alive, now: o.now });
|
|
86
|
+
}
|
|
87
|
+
catch (err) {
|
|
88
|
+
return unknown(`can't read the review runs in ${registry}: ${message(err)}`);
|
|
89
|
+
}
|
|
90
|
+
const out = [];
|
|
91
|
+
for (const v of views) {
|
|
92
|
+
const s = parseRunStatus(v.view, v.argv);
|
|
93
|
+
const usd = s?.result?.costUsd;
|
|
94
|
+
if (s === null || s.state === "running" || usd === null || usd === undefined)
|
|
95
|
+
continue;
|
|
96
|
+
out.push({ at: s.endedAt ?? s.startedAt, usd });
|
|
97
|
+
}
|
|
98
|
+
return known(out);
|
|
99
|
+
};
|
|
100
|
+
}
|
|
101
|
+
const isObj = (v) => typeof v === "object" && v !== null && !Array.isArray(v);
|
|
102
|
+
const usd = (v) => (typeof v === "number" && Number.isFinite(v) ? v : null);
|
|
103
|
+
/** What a status snapshot's text says auto-review spent, for the UTC day and
|
|
104
|
+
* month of `now`. Pure. A snapshot written on an earlier day is the daemon's
|
|
105
|
+
* last word: it has recorded nothing since (it writes one every heartbeat
|
|
106
|
+
* while it runs), so the days after it add nothing. */
|
|
107
|
+
export function snapshotSpend(text, now) {
|
|
108
|
+
let s;
|
|
109
|
+
try {
|
|
110
|
+
s = JSON.parse(text);
|
|
111
|
+
}
|
|
112
|
+
catch {
|
|
113
|
+
return unknown("its status.json is not readable JSON");
|
|
114
|
+
}
|
|
115
|
+
if (!isObj(s))
|
|
116
|
+
return unknown("its status.json is not an object");
|
|
117
|
+
const written = typeof s["written_at"] === "string" ? Date.parse(s["written_at"]) : NaN;
|
|
118
|
+
if (!Number.isFinite(written))
|
|
119
|
+
return unknown("its status has no time it was written");
|
|
120
|
+
const today = usd(s["today_spend_usd"]);
|
|
121
|
+
const month = usd(s["month_spend_usd"]);
|
|
122
|
+
if (month === null)
|
|
123
|
+
return unknown("its status has no month's spend (an older daemon)");
|
|
124
|
+
if (today === null)
|
|
125
|
+
return unknown("its status has no day's spend");
|
|
126
|
+
const at = utcPeriod(written);
|
|
127
|
+
const want = utcPeriod(now);
|
|
128
|
+
if (at.month !== want.month)
|
|
129
|
+
return known({ today: 0, month: 0 });
|
|
130
|
+
return known({ today: at.day === want.day ? today : 0, month });
|
|
131
|
+
}
|
|
132
|
+
/** Auto-review's recorded costs on this machine's compose stack: read from
|
|
133
|
+
* the daemon's own status.json while it runs (src/home/daemonstatus.ts). A
|
|
134
|
+
* daemon that is off keeps its costs in its state volume, where the home
|
|
135
|
+
* cannot read them: unknown. */
|
|
136
|
+
export function composeAutoSpend(o) {
|
|
137
|
+
return async (now) => {
|
|
138
|
+
const s = await daemonSnapshot(o.runner, o.root);
|
|
139
|
+
if (s.kind === "text")
|
|
140
|
+
return snapshotSpend(s.text, now);
|
|
141
|
+
if (s.kind === "none")
|
|
142
|
+
return known({ today: 0, month: 0 });
|
|
143
|
+
if (s.kind === "off")
|
|
144
|
+
return unknown("auto-review is off, and its costs are read from it while it runs");
|
|
145
|
+
return unknown(s.why);
|
|
146
|
+
};
|
|
147
|
+
}
|
|
148
|
+
/** The spend port as the home's env shim builds it: the install's registry
|
|
149
|
+
* in the state home, and the compose stack at `root` (null: no stack, so
|
|
150
|
+
* auto-review recorded nothing here). */
|
|
151
|
+
export function realSpendPort(o) {
|
|
152
|
+
const now = o.now ?? Date.now;
|
|
153
|
+
return spendPort({
|
|
154
|
+
home: registryCosts(o.registry, { now }),
|
|
155
|
+
auto: o.root === null
|
|
156
|
+
? async () => known({ today: 0, month: 0 })
|
|
157
|
+
: composeAutoSpend({ root: o.root, runner: o.runner }),
|
|
158
|
+
}, now);
|
|
159
|
+
}
|
|
160
|
+
//# sourceMappingURL=spend.js.map
|