@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,259 +1,4 @@
|
|
|
1
|
-
//
|
|
2
|
-
//
|
|
3
|
-
|
|
4
|
-
// setup engine — tests/single-shepherd.test.ts) can read the proposal and
|
|
5
|
-
// ask for its start. The click's whole TUI half lives here
|
|
6
|
-
// (`clickStartStage2`, `stage2ClickOutcome`); the [8] scan tab's plan pane
|
|
7
|
-
// (`P`, then ⏎) is its button.
|
|
8
|
-
//
|
|
9
|
-
// Stage 2 starts one of two ways, and neither keeps an approval record:
|
|
10
|
-
//
|
|
11
|
-
// * the operator's word — the companion calls `scan_stage2_start` with the
|
|
12
|
-
// proposal's key (and, for a narrowed "do it", the `rows` it may run —
|
|
13
|
-
// the same `keptRows` rule as the click's narrowing below);
|
|
14
|
-
// * a TUI click — the TUI writes `STAGE2_START_FILE` naming the key of the
|
|
15
|
-
// proposal it showed; the companion's scan belt picks it up within
|
|
16
|
-
// seconds and starts exactly that proposal, answering in
|
|
17
|
-
// `STAGE2_RESULT_FILE`.
|
|
18
|
-
//
|
|
19
|
-
// Either way the start quotes a key, and the engine re-plans before it runs:
|
|
20
|
-
// a proposal that moved since it was shown (a new proposal, a new commit, a
|
|
21
|
-
// price that changed) is refused, so nothing runs that the operator did not
|
|
22
|
-
// see priced. A request is answered once — the result names the request it
|
|
23
|
-
// answered — so a click is never replayed.
|
|
24
|
-
//
|
|
25
|
-
// The click may narrow the plan (space toggles a row off in the plan pane;
|
|
26
|
-
// the operator's word narrows the same way through `scan_stage2_start`'s
|
|
27
|
-
// `rows`): the request then names the runnable rows the operator kept, and
|
|
28
|
-
// the run is exactly those rows, stopped hard at their total — the sum
|
|
29
|
-
// the pane showed. It can only narrow: a row that was not runnable in the
|
|
30
|
-
// proposal (covered, over the budget) can never be named, so nothing runs
|
|
31
|
-
// that was not shown priced and runnable.
|
|
32
|
-
//
|
|
33
|
-
// Files, all in the state home: `scan/stage2.json` (the latest proposal, the
|
|
34
|
-
// engine's), `scan/stage2-start.json` (the TUI's request),
|
|
35
|
-
// `scan/stage2-start-result.json` (the engine's answer).
|
|
36
|
-
import { join } from "node:path";
|
|
37
|
-
import { readTextIfPresent, writeAtomic } from "../channelfs.js";
|
|
38
|
-
export const STAGE2_FILE = "scan/stage2.json";
|
|
39
|
-
export const STAGE2_START_FILE = "scan/stage2-start.json";
|
|
40
|
-
export const STAGE2_RESULT_FILE = "scan/stage2-start-result.json";
|
|
41
|
-
export const STAGE2_VERSION = 1;
|
|
42
|
-
/** The depth a stored proposal was made at. */
|
|
43
|
-
export const proposalDepth = (p) => p.depth === "deep" ? "deep" : "standard";
|
|
44
|
-
const clean = (err) => (err instanceof Error ? err.message : String(err));
|
|
45
|
-
/** Parse the proposal file; throws on anything this version does not read. */
|
|
46
|
-
export function parseStage2File(text) {
|
|
47
|
-
const raw = JSON.parse(text);
|
|
48
|
-
if (typeof raw !== "object" || raw === null || raw.version !== STAGE2_VERSION)
|
|
49
|
-
throw new Error("not a version-1 stage 2 file");
|
|
50
|
-
const p = raw.proposal ?? null;
|
|
51
|
-
if (p !== null &&
|
|
52
|
-
(typeof p !== "object" ||
|
|
53
|
-
typeof p.key !== "string" ||
|
|
54
|
-
typeof p.sha !== "string" ||
|
|
55
|
-
typeof p.cap_usd !== "number" ||
|
|
56
|
-
!Array.isArray(p.rows) ||
|
|
57
|
-
!Array.isArray(p.request))) {
|
|
58
|
-
throw new Error("`proposal` is not a stage 2 proposal");
|
|
59
|
-
}
|
|
60
|
-
return { version: STAGE2_VERSION, proposal: p };
|
|
61
|
-
}
|
|
62
|
-
/** Parse a start request, or null when it is not one. */
|
|
63
|
-
export function parseStartRequest(text) {
|
|
64
|
-
try {
|
|
65
|
-
const r = JSON.parse(text);
|
|
66
|
-
if (typeof r !== "object" ||
|
|
67
|
-
r === null ||
|
|
68
|
-
typeof r.id !== "string" ||
|
|
69
|
-
r.id === "" ||
|
|
70
|
-
typeof r.key !== "string")
|
|
71
|
-
return null;
|
|
72
|
-
if (r.rows !== undefined &&
|
|
73
|
-
(!Array.isArray(r.rows) || !r.rows.every((x) => typeof x === "string")))
|
|
74
|
-
return null;
|
|
75
|
-
return {
|
|
76
|
-
id: r.id,
|
|
77
|
-
key: r.key,
|
|
78
|
-
at: typeof r.at === "string" ? r.at : "",
|
|
79
|
-
by: "tui",
|
|
80
|
-
...(r.rows !== undefined ? { rows: [...r.rows] } : {}),
|
|
81
|
-
};
|
|
82
|
-
}
|
|
83
|
-
catch {
|
|
84
|
-
return null;
|
|
85
|
-
}
|
|
86
|
-
}
|
|
87
|
-
/** Parse a start result, or null when it is not one. */
|
|
88
|
-
export function parseStartResult(text) {
|
|
89
|
-
try {
|
|
90
|
-
const r = JSON.parse(text);
|
|
91
|
-
if (typeof r !== "object" ||
|
|
92
|
-
r === null ||
|
|
93
|
-
typeof r.request !== "string" ||
|
|
94
|
-
typeof r.ok !== "boolean")
|
|
95
|
-
return null;
|
|
96
|
-
return {
|
|
97
|
-
request: r.request,
|
|
98
|
-
key: typeof r.key === "string" ? r.key : "",
|
|
99
|
-
at: typeof r.at === "string" ? r.at : "",
|
|
100
|
-
ok: r.ok,
|
|
101
|
-
run: typeof r.run === "string" ? r.run : null,
|
|
102
|
-
errors: Array.isArray(r.errors)
|
|
103
|
-
? r.errors.filter((e) => typeof e === "string")
|
|
104
|
-
: [],
|
|
105
|
-
};
|
|
106
|
-
}
|
|
107
|
-
catch {
|
|
108
|
-
return null;
|
|
109
|
-
}
|
|
110
|
-
}
|
|
111
|
-
/** The latest stage-2 proposal in the state home at `home`, none, or why it
|
|
112
|
-
* cannot be read (then the TUI shows UNKNOWN — never "no proposal"). */
|
|
113
|
-
export function readStage2Proposal(home) {
|
|
114
|
-
try {
|
|
115
|
-
const text = readTextIfPresent(join(home, STAGE2_FILE));
|
|
116
|
-
return { ok: true, proposal: text === null ? null : parseStage2File(text).proposal };
|
|
117
|
-
}
|
|
118
|
-
catch (err) {
|
|
119
|
-
return { ok: false, error: `${STAGE2_FILE} cannot be read: ${clean(err)}` };
|
|
120
|
-
}
|
|
121
|
-
}
|
|
122
|
-
/**
|
|
123
|
-
* The runnable rows a start runs: all of them, or the subset `keep` names —
|
|
124
|
-
* refused when `keep` is empty or names a row that is not runnable in the
|
|
125
|
-
* proposal (the engine applies the same rule after it re-plans).
|
|
126
|
-
*/
|
|
127
|
-
export function keptRows(rows, keep) {
|
|
128
|
-
const runnable = rows.filter((r) => r.status === "run");
|
|
129
|
-
if (keep === undefined)
|
|
130
|
-
return { ok: true, rows: runnable, cap_usd: null };
|
|
131
|
-
if (keep.length === 0)
|
|
132
|
-
return { ok: false, errors: ["every row is toggled off — keep at least one"] };
|
|
133
|
-
const bad = keep.filter((id) => !runnable.some((r) => r.id === id));
|
|
134
|
-
if (bad.length > 0)
|
|
135
|
-
return { ok: false, errors: [`not a runnable row of the proposal: ${bad.join(", ")}`] };
|
|
136
|
-
const kept = runnable.filter((r) => keep.includes(r.id));
|
|
137
|
-
return { ok: true, rows: kept, cap_usd: kept.reduce((n, r) => n + r.estimate_usd, 0) };
|
|
138
|
-
}
|
|
139
|
-
/**
|
|
140
|
-
* The TUI's click: ask the companion to start the stored proposal whose key
|
|
141
|
-
* the TUI showed — all its runnable rows, or the ones in `keep`. Refused when
|
|
142
|
-
* there is no proposal, it is no longer the one shown (`key`), or `keep`
|
|
143
|
-
* names a row that is not runnable. Writes the request; the companion starts
|
|
144
|
-
* it (or says why not) in `STAGE2_RESULT_FILE`.
|
|
145
|
-
*/
|
|
146
|
-
export function requestStage2Start(home, key, now, keep) {
|
|
147
|
-
const read = readStage2Proposal(home);
|
|
148
|
-
if (!read.ok)
|
|
149
|
-
return { ok: false, errors: [read.error] };
|
|
150
|
-
const p = read.proposal;
|
|
151
|
-
if (p === null)
|
|
152
|
-
return { ok: false, errors: ["no stage 2 proposal — ask the companion to propose one"] };
|
|
153
|
-
if (p.key !== key) {
|
|
154
|
-
return {
|
|
155
|
-
ok: false,
|
|
156
|
-
errors: [
|
|
157
|
-
`the proposal changed since it was shown (showed ${key}, now ${p.key}) — look at the new one first`,
|
|
158
|
-
],
|
|
159
|
-
};
|
|
160
|
-
}
|
|
161
|
-
if (p.runnable === 0)
|
|
162
|
-
return { ok: false, errors: ["the proposal has no row to run"] };
|
|
163
|
-
const kept = keptRows(p.rows, keep);
|
|
164
|
-
if (!kept.ok)
|
|
165
|
-
return kept;
|
|
166
|
-
const request = {
|
|
167
|
-
id: `${now.toISOString()}-${Math.random().toString(36).slice(2, 8)}`,
|
|
168
|
-
key,
|
|
169
|
-
at: now.toISOString(),
|
|
170
|
-
by: "tui",
|
|
171
|
-
...(keep !== undefined ? { rows: [...keep] } : {}),
|
|
172
|
-
};
|
|
173
|
-
try {
|
|
174
|
-
writeAtomic(join(home, STAGE2_START_FILE), `${JSON.stringify(request)}\n`);
|
|
175
|
-
}
|
|
176
|
-
catch (err) {
|
|
177
|
-
return { ok: false, errors: [`the start request could not be written: ${clean(err)}`] };
|
|
178
|
-
}
|
|
179
|
-
return {
|
|
180
|
-
ok: true,
|
|
181
|
-
request,
|
|
182
|
-
proposal: p,
|
|
183
|
-
rows: kept.rows.length,
|
|
184
|
-
cap_usd: kept.cap_usd ?? p.cap_usd,
|
|
185
|
-
};
|
|
186
|
-
}
|
|
187
|
-
/** The companion's answer to the request `id`, or null while it has not
|
|
188
|
-
* answered (or answered another one); throws when the answer file exists
|
|
189
|
-
* but cannot be read. */
|
|
190
|
-
export function readStage2StartResult(home, id) {
|
|
191
|
-
const text = readTextIfPresent(join(home, STAGE2_RESULT_FILE));
|
|
192
|
-
const r = text === null ? null : parseStartResult(text);
|
|
193
|
-
return r !== null && r.request === id ? r : null;
|
|
194
|
-
}
|
|
195
|
-
// ---- the TUI's click -------------------------------------------------------------
|
|
196
|
-
const usd = (n) => `$${n.toFixed(2)}`;
|
|
197
|
-
/**
|
|
198
|
-
* The click: ask the companion to start the proposal whose key the TUI
|
|
199
|
-
* showed — its kept rows when the operator toggled some off. The notice line
|
|
200
|
-
* says what was asked, or why nothing was.
|
|
201
|
-
*/
|
|
202
|
-
export function clickStartStage2(home, key, now = new Date(), keep) {
|
|
203
|
-
const r = requestStage2Start(home, key, now, keep);
|
|
204
|
-
if (!r.ok)
|
|
205
|
-
return { ok: false, line: `stage 2 not started: ${r.errors.join("; ")}` };
|
|
206
|
-
return {
|
|
207
|
-
ok: true,
|
|
208
|
-
request: r.request.id,
|
|
209
|
-
line: `stage 2 asked to start — ${r.rows} row(s), hard stop ${usd(r.cap_usd)}; the companion starts it within seconds`,
|
|
210
|
-
};
|
|
211
|
-
}
|
|
212
|
-
/** What became of the click `request`: the companion's answer, or null while
|
|
213
|
-
* it has not answered (a companion that is down starts nothing) — or that
|
|
214
|
-
* the answer cannot be read. */
|
|
215
|
-
export function stage2ClickOutcome(home, request) {
|
|
216
|
-
let r;
|
|
217
|
-
try {
|
|
218
|
-
r = readStage2StartResult(home, request);
|
|
219
|
-
}
|
|
220
|
-
catch (err) {
|
|
221
|
-
// Not "no answer yet": the answer may be there, unreadable — said once,
|
|
222
|
-
// never polled for silently.
|
|
223
|
-
return `stage 2's answer cannot be read (${STAGE2_RESULT_FILE}: ${clean(err)}) — check scan_status`;
|
|
224
|
-
}
|
|
225
|
-
if (r === null)
|
|
226
|
-
return null;
|
|
227
|
-
return r.ok ? `stage 2 started: ${r.run}` : `stage 2 refused: ${r.errors.join("; ")}`;
|
|
228
|
-
}
|
|
229
|
-
// ---- a row's price, as the preview names it -------------------------------------
|
|
230
|
-
/** Whether a row's price is a measurement of the row's own lens at its own
|
|
231
|
-
* settings and depth — every other basis is an estimate. */
|
|
232
|
-
export function priceIsMeasured(p) {
|
|
233
|
-
return p.basis === "measured" && p.across_depth !== true;
|
|
234
|
-
}
|
|
235
|
-
/** What the preview says a row's price stands on: `measured`, or
|
|
236
|
-
* `estimate: …` and how it was made. */
|
|
237
|
-
export function priceLabel(p) {
|
|
238
|
-
const label = basisLabel(p);
|
|
239
|
-
return p.across_depth
|
|
240
|
-
? `${p.basis === "measured" ? "estimate: measured" : label} — from readings at the other depth`
|
|
241
|
-
: label;
|
|
242
|
-
}
|
|
243
|
-
function basisLabel(p) {
|
|
244
|
-
const onOff = (v) => (v ? "on" : "off");
|
|
245
|
-
switch (p.basis) {
|
|
246
|
-
case "measured":
|
|
247
|
-
return "measured";
|
|
248
|
-
case "borrowed":
|
|
249
|
-
return `estimate: borrowed from ${p.from}`;
|
|
250
|
-
case "learned":
|
|
251
|
-
return p.learned
|
|
252
|
-
? `estimate: learned from ${p.from} with the validator ${onOff(p.learned.validator)} (×${p.learned.factor.toFixed(2)} stage 1), ` +
|
|
253
|
-
`stage 1 validator ${onOff(!p.learned.validator)}/${onOff(p.learned.validator)} ×${p.learned.skeptic.toFixed(2)}`
|
|
254
|
-
: `estimate: learned from ${p.from}`;
|
|
255
|
-
default:
|
|
256
|
-
return `estimate: extrapolated from ${p.from}${p.factor !== undefined ? ` (×${p.factor})` : ""}`;
|
|
257
|
-
}
|
|
258
|
-
}
|
|
1
|
+
// Moved to the plugin (packages/pi-plugin/src/scan/stage2request.ts), the scan engine's
|
|
2
|
+
// home: this name stays for the app's importers.
|
|
3
|
+
export * from "@quickchatai/pi-quickreview/src/scan/stage2request.js";
|
|
259
4
|
//# sourceMappingURL=stage2request.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"stage2request.js","sourceRoot":"","sources":["../../../src/setup/stage2request.ts"],"names":[],"mappings":"AAAA,
|
|
1
|
+
{"version":3,"file":"stage2request.js","sourceRoot":"","sources":["../../../src/setup/stage2request.ts"],"names":[],"mappings":"AAAA,wFAAwF;AACxF,iDAAiD;AACjD,cAAc,uDAAuD,CAAC"}
|