@quickchatai/quickreview 0.0.0-stage → 1.1.0
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/LICENSE +23 -0
- package/README.md +385 -2
- package/THIRD-PARTY-NOTICES.md +134 -0
- package/agents/pass-abstraction.md +64 -0
- package/agents/pass-ask-human.md +134 -0
- package/agents/pass-backcompat.md +67 -0
- package/agents/pass-baseline.md +61 -0
- package/agents/pass-behaviour-delta.md +64 -0
- package/agents/pass-bounds.md +36 -0
- package/agents/pass-claims.md +31 -0
- package/agents/pass-concurrency.md +168 -0
- package/agents/pass-consistency.md +57 -0
- package/agents/pass-contracts.md +30 -0
- package/agents/pass-data-safety.md +54 -0
- package/agents/pass-deferred.md +35 -0
- package/agents/pass-delivery.md +37 -0
- package/agents/pass-duplication.md +60 -0
- package/agents/pass-intent.md +63 -0
- package/agents/pass-lint-conformance.md +46 -0
- package/agents/pass-maintainability.md +67 -0
- package/agents/pass-placement.md +68 -0
- package/agents/pass-prod-risk.md +24 -0
- package/agents/pass-rollout.md +32 -0
- package/agents/pass-roundtrip.md +46 -0
- package/agents/pass-security.md +31 -0
- package/agents/pass-simplicity.md +68 -0
- package/agents/pass-statelessness.md +27 -0
- package/agents/pass-style.md +37 -0
- package/agents/pass-sweep.md +57 -0
- package/agents/pass-tests.md +58 -0
- package/agents/pass-ui.md +23 -0
- package/agents/pass-validate.md +50 -0
- package/agents/pass-widened.md +46 -0
- package/agents/scan/pass-scan.md +86 -0
- package/bin/qcr.js +11 -0
- package/config.example.toml +1067 -0
- package/deploy/ansible/README.md +356 -0
- package/deploy/ansible/group_vars/all.yml +212 -0
- package/deploy/ansible/inventory.example.ini +25 -0
- package/deploy/ansible/playbook.yml +360 -0
- package/deploy/collect-secrets.sh +289 -0
- package/deploy/collect-slack-secrets.mjs +1190 -0
- package/deploy/github-app-manifest.json +31 -0
- package/deploy/manifest.schema.json +75 -0
- package/deploy/qcr-update.sh +803 -0
- package/deploy/reviewer/AGENTS.override.md +12 -0
- package/dist/extensions/cli/bash-guard-ambient.js +42 -0
- package/dist/extensions/cli/bash-guard-ambient.js.map +1 -0
- package/dist/extensions/cli/bash-guard.js +5 -0
- package/dist/extensions/cli/bash-guard.js.map +1 -0
- package/dist/extensions/cli/companion-guard.js +5 -0
- package/dist/extensions/cli/companion-guard.js.map +1 -0
- package/dist/extensions/cli/debug-round.js +8 -0
- package/dist/extensions/cli/debug-round.js.map +1 -0
- package/dist/extensions/cli/inject-bridge.js +5 -0
- package/dist/extensions/cli/inject-bridge.js.map +1 -0
- package/dist/extensions/cli/ledger-pin.js +5 -0
- package/dist/extensions/cli/ledger-pin.js.map +1 -0
- package/dist/extensions/cli/lens.js +13 -0
- package/dist/extensions/cli/lens.js.map +1 -0
- package/dist/extensions/cli/muted-theme.js +5 -0
- package/dist/extensions/cli/muted-theme.js.map +1 -0
- package/dist/extensions/cli/onboarding.js +5 -0
- package/dist/extensions/cli/onboarding.js.map +1 -0
- package/dist/extensions/cli/setup.js +5 -0
- package/dist/extensions/cli/setup.js.map +1 -0
- package/dist/extensions/cli/tui-view.js +5 -0
- package/dist/extensions/cli/tui-view.js.map +1 -0
- package/dist/extensions/companion-guard.js +361 -0
- package/dist/extensions/companion-guard.js.map +1 -0
- package/dist/extensions/debug-round.js +204 -0
- package/dist/extensions/debug-round.js.map +1 -0
- package/dist/extensions/inject-bridge.js +603 -0
- package/dist/extensions/inject-bridge.js.map +1 -0
- package/dist/extensions/muted-theme.js +12 -0
- package/dist/extensions/muted-theme.js.map +1 -0
- package/dist/extensions/onboarding.js +175 -0
- package/dist/extensions/onboarding.js.map +1 -0
- package/dist/extensions/setup-replay.js +269 -0
- package/dist/extensions/setup-replay.js.map +1 -0
- package/dist/extensions/setup-scan.js +998 -0
- package/dist/extensions/setup-scan.js.map +1 -0
- package/dist/extensions/setup-triage.js +175 -0
- package/dist/extensions/setup-triage.js.map +1 -0
- package/dist/extensions/setup.js +1160 -0
- package/dist/extensions/setup.js.map +1 -0
- package/dist/extensions/tui-view.js +389 -0
- package/dist/extensions/tui-view.js.map +1 -0
- package/dist/extensions/vendor/openviking-pi/client.js +376 -0
- package/dist/extensions/vendor/openviking-pi/client.js.map +1 -0
- package/dist/extensions/vendor/openviking-pi/config.js +189 -0
- package/dist/extensions/vendor/openviking-pi/config.js.map +1 -0
- package/dist/extensions/vendor/openviking-pi/index.js +421 -0
- package/dist/extensions/vendor/openviking-pi/index.js.map +1 -0
- package/dist/extensions/vendor/openviking-pi/lib/capture-adapter.mjs +86 -0
- package/dist/extensions/vendor/openviking-pi/lib/capture-adapter.mjs.map +1 -0
- package/dist/extensions/vendor/openviking-pi/lib/takeover-core.mjs +408 -0
- package/dist/extensions/vendor/openviking-pi/lib/takeover-core.mjs.map +1 -0
- package/dist/extensions/vendor/openviking-pi/lib/uri-guard-adapter.mjs +41 -0
- package/dist/extensions/vendor/openviking-pi/lib/uri-guard-adapter.mjs.map +1 -0
- package/dist/extensions/vendor/openviking-pi/qcr-hint.js +290 -0
- package/dist/extensions/vendor/openviking-pi/qcr-hint.js.map +1 -0
- package/dist/extensions/vendor/openviking-pi/qcr-honest.js +148 -0
- package/dist/extensions/vendor/openviking-pi/qcr-honest.js.map +1 -0
- package/dist/extensions/vendor/openviking-pi/qcr-hooks.js +68 -0
- package/dist/extensions/vendor/openviking-pi/qcr-hooks.js.map +1 -0
- package/dist/extensions/vendor/openviking-pi/qcr-leaf.js +77 -0
- package/dist/extensions/vendor/openviking-pi/qcr-leaf.js.map +1 -0
- package/dist/extensions/vendor/openviking-pi/qcr-lesson.js +216 -0
- package/dist/extensions/vendor/openviking-pi/qcr-lesson.js.map +1 -0
- package/dist/extensions/vendor/openviking-pi/qcr-namespaces.js +154 -0
- package/dist/extensions/vendor/openviking-pi/qcr-namespaces.js.map +1 -0
- package/dist/extensions/vendor/openviking-pi/qcr-recall.js +254 -0
- package/dist/extensions/vendor/openviking-pi/qcr-recall.js.map +1 -0
- package/dist/extensions/vendor/openviking-pi/qcr-shim.js +94 -0
- package/dist/extensions/vendor/openviking-pi/qcr-shim.js.map +1 -0
- package/dist/extensions/vendor/openviking-pi/qcr-write.js +333 -0
- package/dist/extensions/vendor/openviking-pi/qcr-write.js.map +1 -0
- package/dist/extensions/vendor/openviking-pi/recall.js +108 -0
- package/dist/extensions/vendor/openviking-pi/recall.js.map +1 -0
- package/dist/extensions/vendor/openviking-pi/shared/capture-utils.mjs +529 -0
- package/dist/extensions/vendor/openviking-pi/shared/capture-utils.mjs.map +1 -0
- package/dist/extensions/vendor/openviking-pi/shared/credentials.mjs +205 -0
- package/dist/extensions/vendor/openviking-pi/shared/credentials.mjs.map +1 -0
- package/dist/extensions/vendor/openviking-pi/shared/pending-queue.mjs +442 -0
- package/dist/extensions/vendor/openviking-pi/shared/pending-queue.mjs.map +1 -0
- package/dist/extensions/vendor/openviking-pi/shared/profile-inject.mjs +286 -0
- package/dist/extensions/vendor/openviking-pi/shared/profile-inject.mjs.map +1 -0
- package/dist/extensions/vendor/openviking-pi/shared/recall-compress-core.mjs +189 -0
- package/dist/extensions/vendor/openviking-pi/shared/recall-compress-core.mjs.map +1 -0
- package/dist/extensions/vendor/openviking-pi/shared/recall-core.mjs +580 -0
- package/dist/extensions/vendor/openviking-pi/shared/recall-core.mjs.map +1 -0
- package/dist/extensions/vendor/openviking-pi/shared/retryable.mjs +11 -0
- package/dist/extensions/vendor/openviking-pi/shared/retryable.mjs.map +1 -0
- package/dist/extensions/vendor/openviking-pi/shared/session-model.mjs +63 -0
- package/dist/extensions/vendor/openviking-pi/shared/session-model.mjs.map +1 -0
- package/dist/extensions/vendor/openviking-pi/shared/uri-guard.mjs +58 -0
- package/dist/extensions/vendor/openviking-pi/shared/uri-guard.mjs.map +1 -0
- package/dist/extensions/vendor/openviking-pi/shared/workspace-peer.mjs +16 -0
- package/dist/extensions/vendor/openviking-pi/shared/workspace-peer.mjs.map +1 -0
- package/dist/extensions/vendor/openviking-pi/sync.js +127 -0
- package/dist/extensions/vendor/openviking-pi/sync.js.map +1 -0
- package/dist/extensions/vendor/openviking-pi/takeover.js +25 -0
- package/dist/extensions/vendor/openviking-pi/takeover.js.map +1 -0
- package/dist/extensions/vendor/openviking-pi/tools.js +417 -0
- package/dist/extensions/vendor/openviking-pi/tools.js.map +1 -0
- package/dist/src/anomalies.js +483 -0
- package/dist/src/anomalies.js.map +1 -0
- package/dist/src/answerworker.js +180 -0
- package/dist/src/answerworker.js.map +1 -0
- package/dist/src/appstamp.js +68 -0
- package/dist/src/appstamp.js.map +1 -0
- package/dist/src/archive/admission.js +3 -0
- package/dist/src/archive/admission.js.map +1 -0
- package/dist/src/archive/archivedb.js +474 -0
- package/dist/src/archive/archivedb.js.map +1 -0
- package/dist/src/archive/archiver.js +1770 -0
- package/dist/src/archive/archiver.js.map +1 -0
- package/dist/src/archive/archivewrite.js +198 -0
- package/dist/src/archive/archivewrite.js.map +1 -0
- package/dist/src/archive/bundle.js +266 -0
- package/dist/src/archive/bundle.js.map +1 -0
- package/dist/src/archive/dbmove.js +638 -0
- package/dist/src/archive/dbmove.js.map +1 -0
- package/dist/src/archive/duplicatecounts.js +80 -0
- package/dist/src/archive/duplicatecounts.js.map +1 -0
- package/dist/src/archive/eligibility.js +113 -0
- package/dist/src/archive/eligibility.js.map +1 -0
- package/dist/src/archive/extract.js +288 -0
- package/dist/src/archive/extract.js.map +1 -0
- package/dist/src/archive/fsutil.js +330 -0
- package/dist/src/archive/fsutil.js.map +1 -0
- package/dist/src/archive/gzfile.js +277 -0
- package/dist/src/archive/gzfile.js.map +1 -0
- package/dist/src/archive/kinds.js +22 -0
- package/dist/src/archive/kinds.js.map +1 -0
- package/dist/src/archive/livecheckpoint.js +178 -0
- package/dist/src/archive/livecheckpoint.js.map +1 -0
- package/dist/src/archive/liveretention.js +145 -0
- package/dist/src/archive/liveretention.js.map +1 -0
- package/dist/src/archive/manifest.js +284 -0
- package/dist/src/archive/manifest.js.map +1 -0
- package/dist/src/archive/overseer.js +283 -0
- package/dist/src/archive/overseer.js.map +1 -0
- package/dist/src/archive/piglobal.js +129 -0
- package/dist/src/archive/piglobal.js.map +1 -0
- package/dist/src/archive/plan.js +398 -0
- package/dist/src/archive/plan.js.map +1 -0
- package/dist/src/archive/prarchive.js +831 -0
- package/dist/src/archive/prarchive.js.map +1 -0
- package/dist/src/archive/prfiles.js +303 -0
- package/dist/src/archive/prfiles.js.map +1 -0
- package/dist/src/archive/report.js +169 -0
- package/dist/src/archive/report.js.map +1 -0
- package/dist/src/archive/restore.js +276 -0
- package/dist/src/archive/restore.js.map +1 -0
- package/dist/src/archive/rows.js +106 -0
- package/dist/src/archive/rows.js.map +1 -0
- package/dist/src/archive/seal.js +480 -0
- package/dist/src/archive/seal.js.map +1 -0
- package/dist/src/archive/status.js +528 -0
- package/dist/src/archive/status.js.map +1 -0
- package/dist/src/archive/storepass.js +409 -0
- package/dist/src/archive/storepass.js.map +1 -0
- package/dist/src/backfill.js +217 -0
- package/dist/src/backfill.js.map +1 -0
- package/dist/src/bench/cost.js +87 -0
- package/dist/src/bench/exec.js +76 -0
- package/dist/src/bench/values.js +14 -0
- package/dist/src/botcontrol.js +127 -0
- package/dist/src/botcontrol.js.map +1 -0
- package/dist/src/botworker.js +805 -0
- package/dist/src/botworker.js.map +1 -0
- package/dist/src/capture.js +234 -0
- package/dist/src/capture.js.map +1 -0
- package/dist/src/cases.js +1491 -0
- package/dist/src/cases.js.map +1 -0
- package/dist/src/channelfs.js +27 -0
- package/dist/src/channelfs.js.map +1 -0
- package/dist/src/checklist.js +312 -0
- package/dist/src/checklist.js.map +1 -0
- package/dist/src/ciretry.js +91 -0
- package/dist/src/ciretry.js.map +1 -0
- package/dist/src/cli.js +1916 -0
- package/dist/src/cli.js.map +1 -0
- package/dist/src/cliops.js +333 -0
- package/dist/src/cliops.js.map +1 -0
- package/dist/src/clonedir.js +15 -0
- package/dist/src/clonedir.js.map +1 -0
- package/dist/src/commandeffects.js +43 -0
- package/dist/src/commandeffects.js.map +1 -0
- package/dist/src/commands.js +1312 -0
- package/dist/src/commands.js.map +1 -0
- package/dist/src/companioninbox.js +203 -0
- package/dist/src/companioninbox.js.map +1 -0
- package/dist/src/compare.js +673 -0
- package/dist/src/compare.js.map +1 -0
- package/dist/src/config.js +1027 -0
- package/dist/src/config.js.map +1 -0
- package/dist/src/configcheck.js +111 -0
- package/dist/src/configcheck.js.map +1 -0
- package/dist/src/coreext.js +43 -0
- package/dist/src/coreext.js.map +1 -0
- package/dist/src/daemon.js +929 -0
- package/dist/src/daemon.js.map +1 -0
- package/dist/src/debuground.js +731 -0
- package/dist/src/debuground.js.map +1 -0
- package/dist/src/debugroundpi.js +219 -0
- package/dist/src/debugroundpi.js.map +1 -0
- package/dist/src/diagnostics.js +14 -0
- package/dist/src/diagnostics.js.map +1 -0
- package/dist/src/digest.js +139 -0
- package/dist/src/digest.js.map +1 -0
- package/dist/src/dispatch.js +1726 -0
- package/dist/src/dispatch.js.map +1 -0
- package/dist/src/engine/answerguard.js +18 -0
- package/dist/src/engine/answerguard.js.map +1 -0
- package/dist/src/engine/botsdk.js +262 -0
- package/dist/src/engine/botsdk.js.map +1 -0
- package/dist/src/engine/caserunner-sdk.js +332 -0
- package/dist/src/engine/caserunner-sdk.js.map +1 -0
- package/dist/src/engine/debugpi.js +194 -0
- package/dist/src/engine/debugpi.js.map +1 -0
- package/dist/src/eod.js +473 -0
- package/dist/src/eod.js.map +1 -0
- package/dist/src/eodpinwatch.js +391 -0
- package/dist/src/eodpinwatch.js.map +1 -0
- package/dist/src/escalation.js +1009 -0
- package/dist/src/escalation.js.map +1 -0
- package/dist/src/eventloop.js +779 -0
- package/dist/src/eventloop.js.map +1 -0
- package/dist/src/execboundary.js +430 -0
- package/dist/src/execboundary.js.map +1 -0
- package/dist/src/feedback.js +915 -0
- package/dist/src/feedback.js.map +1 -0
- package/dist/src/findingscheck.js +200 -0
- package/dist/src/findingscheck.js.map +1 -0
- package/dist/src/fsdenied.js +26 -0
- package/dist/src/fsdenied.js.map +1 -0
- package/dist/src/ghread.js +181 -0
- package/dist/src/ghread.js.map +1 -0
- package/dist/src/github.js +1063 -0
- package/dist/src/github.js.map +1 -0
- package/dist/src/homes.js +103 -0
- package/dist/src/homes.js.map +1 -0
- package/dist/src/hostroute.js +24 -0
- package/dist/src/hostroute.js.map +1 -0
- package/dist/src/improvements.js +625 -0
- package/dist/src/improvements.js.map +1 -0
- package/dist/src/install.js +946 -0
- package/dist/src/install.js.map +1 -0
- package/dist/src/installkind.js +40 -0
- package/dist/src/installkind.js.map +1 -0
- package/dist/src/ipc/capability.js +286 -0
- package/dist/src/ipc/capability.js.map +1 -0
- package/dist/src/ipc/client.js +226 -0
- package/dist/src/ipc/client.js.map +1 -0
- package/dist/src/ipc/control.js +70 -0
- package/dist/src/ipc/control.js.map +1 -0
- package/dist/src/ipc/ghreadshim.js +77 -0
- package/dist/src/ipc/ghreadshim.js.map +1 -0
- package/dist/src/ipc/launcher.js +65 -0
- package/dist/src/ipc/launcher.js.map +1 -0
- package/dist/src/ipc/permits.js +293 -0
- package/dist/src/ipc/permits.js.map +1 -0
- package/dist/src/ipc/postshim.js +137 -0
- package/dist/src/ipc/postshim.js.map +1 -0
- package/dist/src/ipc/protocol.js +239 -0
- package/dist/src/ipc/protocol.js.map +1 -0
- package/dist/src/ipc/server.js +312 -0
- package/dist/src/ipc/server.js.map +1 -0
- package/dist/src/ipc/workerspec.js +148 -0
- package/dist/src/ipc/workerspec.js.map +1 -0
- package/dist/src/learner/learner.js +1272 -0
- package/dist/src/learner/learner.js.map +1 -0
- package/dist/src/learner/miner.js +948 -0
- package/dist/src/learner/miner.js.map +1 -0
- package/dist/src/learner/packet.js +216 -0
- package/dist/src/learner/packet.js.map +1 -0
- package/dist/src/learner/receipt.js +135 -0
- package/dist/src/learner/receipt.js.map +1 -0
- package/dist/src/learner/status.js +38 -0
- package/dist/src/learner/status.js.map +1 -0
- package/dist/src/ledgercheck.js +120 -0
- package/dist/src/ledgercheck.js.map +1 -0
- package/dist/src/lessonledger.js +451 -0
- package/dist/src/lessonledger.js.map +1 -0
- package/dist/src/lessonselect.js +639 -0
- package/dist/src/lessonselect.js.map +1 -0
- package/dist/src/lessonshadow.js +540 -0
- package/dist/src/lessonshadow.js.map +1 -0
- package/dist/src/levers.js +302 -0
- package/dist/src/levers.js.map +1 -0
- package/dist/src/live/projection.js +450 -0
- package/dist/src/live/projection.js.map +1 -0
- package/dist/src/live/publish.js +83 -0
- package/dist/src/live/publish.js.map +1 -0
- package/dist/src/live/read.js +60 -0
- package/dist/src/live/read.js.map +1 -0
- package/dist/src/livecli.js +288 -0
- package/dist/src/livecli.js.map +1 -0
- package/dist/src/loginhint.js +42 -0
- package/dist/src/loginhint.js.map +1 -0
- package/dist/src/loginrefresh/atomic.js +66 -0
- package/dist/src/loginrefresh/atomic.js.map +1 -0
- package/dist/src/loginrefresh/lock.js +93 -0
- package/dist/src/loginrefresh/lock.js.map +1 -0
- package/dist/src/loginrefresh/main.js +58 -0
- package/dist/src/loginrefresh/main.js.map +1 -0
- package/dist/src/loginrefresh/pirefresh.js +49 -0
- package/dist/src/loginrefresh/pirefresh.js.map +1 -0
- package/dist/src/loginrefresh/refresher.js +286 -0
- package/dist/src/loginrefresh/refresher.js.map +1 -0
- package/dist/src/loginrefresh/supervisor.js +253 -0
- package/dist/src/loginrefresh/supervisor.js.map +1 -0
- package/dist/src/loginrefresh/types.js +4 -0
- package/dist/src/loginrefresh/types.js.map +1 -0
- package/dist/src/memory/context.js +251 -0
- package/dist/src/memory/context.js.map +1 -0
- package/dist/src/memory/datafence.js +5 -0
- package/dist/src/memory/datafence.js.map +1 -0
- package/dist/src/memory/delivery.js +131 -0
- package/dist/src/memory/delivery.js.map +1 -0
- package/dist/src/memory/eventtags.js +81 -0
- package/dist/src/memory/eventtags.js.map +1 -0
- package/dist/src/memory/health.js +713 -0
- package/dist/src/memory/health.js.map +1 -0
- package/dist/src/memory/import.js +504 -0
- package/dist/src/memory/import.js.map +1 -0
- package/dist/src/memory/layout.js +252 -0
- package/dist/src/memory/layout.js.map +1 -0
- package/dist/src/memory/legacy-file.js +100 -0
- package/dist/src/memory/legacy-file.js.map +1 -0
- package/dist/src/memory/lessons.js +370 -0
- package/dist/src/memory/lessons.js.map +1 -0
- package/dist/src/memory/ovsession.js +449 -0
- package/dist/src/memory/ovsession.js.map +1 -0
- package/dist/src/memory/relayout.js +259 -0
- package/dist/src/memory/relayout.js.map +1 -0
- package/dist/src/memory/roundactivity.js +180 -0
- package/dist/src/memory/roundactivity.js.map +1 -0
- package/dist/src/memory/selection.js +690 -0
- package/dist/src/memory/selection.js.map +1 -0
- package/dist/src/memory/shadowstatus.js +69 -0
- package/dist/src/memory/shadowstatus.js.map +1 -0
- package/dist/src/memory/store.js +83 -0
- package/dist/src/memory/store.js.map +1 -0
- package/dist/src/memory/textidentity.js +8 -0
- package/dist/src/memory/textidentity.js.map +1 -0
- package/dist/src/metrics.js +773 -0
- package/dist/src/metrics.js.map +1 -0
- package/dist/src/missingconfig.js +8 -0
- package/dist/src/missingconfig.js.map +1 -0
- package/dist/src/npmverbs.js +226 -0
- package/dist/src/npmverbs.js.map +1 -0
- package/dist/src/onboard/choices.js +191 -0
- package/dist/src/onboard/choices.js.map +1 -0
- package/dist/src/onboard/engine.js +344 -0
- package/dist/src/onboard/engine.js.map +1 -0
- package/dist/src/onboard/launch.js +83 -0
- package/dist/src/onboard/launch.js.map +1 -0
- package/dist/src/onboard/steps/appslug.js +211 -0
- package/dist/src/onboard/steps/appslug.js.map +1 -0
- package/dist/src/onboard/steps/bringup.js +408 -0
- package/dist/src/onboard/steps/bringup.js.map +1 -0
- package/dist/src/onboard/steps/compose.js +343 -0
- package/dist/src/onboard/steps/compose.js.map +1 -0
- package/dist/src/onboard/steps/configdelivery.js +50 -0
- package/dist/src/onboard/steps/configdelivery.js.map +1 -0
- package/dist/src/onboard/steps/configfill.js +1148 -0
- package/dist/src/onboard/steps/configfill.js.map +1 -0
- package/dist/src/onboard/steps/deploysh.js +80 -0
- package/dist/src/onboard/steps/deploysh.js.map +1 -0
- package/dist/src/onboard/steps/embeddings.js +472 -0
- package/dist/src/onboard/steps/embeddings.js.map +1 -0
- package/dist/src/onboard/steps/escalation.js +571 -0
- package/dist/src/onboard/steps/escalation.js.map +1 -0
- package/dist/src/onboard/steps/githubapp.js +1092 -0
- package/dist/src/onboard/steps/githubapp.js.map +1 -0
- package/dist/src/onboard/steps/golive.js +506 -0
- package/dist/src/onboard/steps/golive.js.map +1 -0
- package/dist/src/onboard/steps/index.js +67 -0
- package/dist/src/onboard/steps/index.js.map +1 -0
- package/dist/src/onboard/steps/ingress.js +762 -0
- package/dist/src/onboard/steps/ingress.js.map +1 -0
- package/dist/src/onboard/steps/inventory.js +420 -0
- package/dist/src/onboard/steps/inventory.js.map +1 -0
- package/dist/src/onboard/steps/llmauth.js +893 -0
- package/dist/src/onboard/steps/llmauth.js.map +1 -0
- package/dist/src/onboard/steps/memory.js +1060 -0
- package/dist/src/onboard/steps/memory.js.map +1 -0
- package/dist/src/onboard/steps/memorykeys.js +43 -0
- package/dist/src/onboard/steps/memorykeys.js.map +1 -0
- package/dist/src/onboard/steps/preflight.js +172 -0
- package/dist/src/onboard/steps/preflight.js.map +1 -0
- package/dist/src/onboard/steps/proof.js +502 -0
- package/dist/src/onboard/steps/proof.js.map +1 -0
- package/dist/src/onboard/steps/ssh.js +300 -0
- package/dist/src/onboard/steps/ssh.js.map +1 -0
- package/dist/src/onboard/steps/topology.js +291 -0
- package/dist/src/onboard/steps/topology.js.map +1 -0
- package/dist/src/onboard/steps/transport.js +511 -0
- package/dist/src/onboard/steps/transport.js.map +1 -0
- package/dist/src/onboard/steps/verifyup.js +362 -0
- package/dist/src/onboard/steps/verifyup.js.map +1 -0
- package/dist/src/onboard/steps/vmdeploy.js +368 -0
- package/dist/src/onboard/steps/vmdeploy.js.map +1 -0
- package/dist/src/onboard/toml.js +53 -0
- package/dist/src/onboard/toml.js.map +1 -0
- package/dist/src/opencli.js +508 -0
- package/dist/src/opencli.js.map +1 -0
- package/dist/src/openpr.js +457 -0
- package/dist/src/openpr.js.map +1 -0
- package/dist/src/openviking/client.js +821 -0
- package/dist/src/openviking/client.js.map +1 -0
- package/dist/src/openviking/context.js +218 -0
- package/dist/src/openviking/context.js.map +1 -0
- package/dist/src/openviking/embedder.js +457 -0
- package/dist/src/openviking/embedder.js.map +1 -0
- package/dist/src/openviking/gapsink.js +38 -0
- package/dist/src/openviking/gapsink.js.map +1 -0
- package/dist/src/openviking/health.js +69 -0
- package/dist/src/openviking/health.js.map +1 -0
- package/dist/src/openviking/index.js +24 -0
- package/dist/src/openviking/index.js.map +1 -0
- package/dist/src/openviking/lessonfind.js +54 -0
- package/dist/src/openviking/lessonfind.js.map +1 -0
- package/dist/src/openviking/probe.js +89 -0
- package/dist/src/openviking/probe.js.map +1 -0
- package/dist/src/openviking/proc.js +95 -0
- package/dist/src/openviking/proc.js.map +1 -0
- package/dist/src/openviking/provisionreport.js +144 -0
- package/dist/src/openviking/provisionreport.js.map +1 -0
- package/dist/src/openviking/reembed.js +317 -0
- package/dist/src/openviking/reembed.js.map +1 -0
- package/dist/src/openviking/relayout.js +153 -0
- package/dist/src/openviking/relayout.js.map +1 -0
- package/dist/src/openviking/sidecar-main.js +39 -0
- package/dist/src/openviking/sidecar-main.js.map +1 -0
- package/dist/src/openviking/sidecar.js +79 -0
- package/dist/src/openviking/sidecar.js.map +1 -0
- package/dist/src/openviking/store.js +1758 -0
- package/dist/src/openviking/store.js.map +1 -0
- package/dist/src/openviking/supervisor.js +422 -0
- package/dist/src/openviking/supervisor.js.map +1 -0
- package/dist/src/openviking/types.js +5 -0
- package/dist/src/openviking/types.js.map +1 -0
- package/dist/src/operator-recovery.js +172 -0
- package/dist/src/operator-recovery.js.map +1 -0
- package/dist/src/operatormessage.js +44 -0
- package/dist/src/operatormessage.js.map +1 -0
- package/dist/src/outcomes.js +1361 -0
- package/dist/src/outcomes.js.map +1 -0
- package/dist/src/piauthcopy.js +5 -0
- package/dist/src/piauthcopy.js.map +1 -0
- package/dist/src/picli.js +45 -0
- package/dist/src/picli.js.map +1 -0
- package/dist/src/picwd.js +25 -0
- package/dist/src/picwd.js.map +1 -0
- package/dist/src/pilogin.js +35 -0
- package/dist/src/pilogin.js.map +1 -0
- package/dist/src/pingpong.js +1028 -0
- package/dist/src/pingpong.js.map +1 -0
- package/dist/src/posting-journal.js +441 -0
- package/dist/src/posting-journal.js.map +1 -0
- package/dist/src/posting-outbox.js +662 -0
- package/dist/src/posting-outbox.js.map +1 -0
- package/dist/src/posting-receipt.js +203 -0
- package/dist/src/posting-receipt.js.map +1 -0
- package/dist/src/posting.js +348 -0
- package/dist/src/posting.js.map +1 -0
- package/dist/src/postops.js +637 -0
- package/dist/src/postops.js.map +1 -0
- package/dist/src/pr-activity.js +11 -0
- package/dist/src/pr-activity.js.map +1 -0
- package/dist/src/pr-author.js +5 -0
- package/dist/src/pr-author.js.map +1 -0
- package/dist/src/pr-conversation.js +355 -0
- package/dist/src/pr-conversation.js.map +1 -0
- package/dist/src/pr-session-lifecycle.js +542 -0
- package/dist/src/pr-session-lifecycle.js.map +1 -0
- package/dist/src/preflight.js +341 -0
- package/dist/src/preflight.js.map +1 -0
- package/dist/src/priorresolve.js +275 -0
- package/dist/src/priorresolve.js.map +1 -0
- package/dist/src/qcrbin.js +180 -0
- package/dist/src/qcrbin.js.map +1 -0
- package/dist/src/recheck.js +1398 -0
- package/dist/src/recheck.js.map +1 -0
- package/dist/src/reconcile.js +820 -0
- package/dist/src/reconcile.js.map +1 -0
- package/dist/src/recordedfindings.js +15 -0
- package/dist/src/recordedfindings.js.map +1 -0
- package/dist/src/regression.js +546 -0
- package/dist/src/regression.js.map +1 -0
- package/dist/src/replay.js +598 -0
- package/dist/src/replay.js.map +1 -0
- package/dist/src/requiredpasses.js +113 -0
- package/dist/src/requiredpasses.js.map +1 -0
- package/dist/src/resumecheck.js +168 -0
- package/dist/src/resumecheck.js.map +1 -0
- package/dist/src/reviewcli.js +671 -0
- package/dist/src/reviewcli.js.map +1 -0
- package/dist/src/reviewcontext.js +22 -0
- package/dist/src/reviewcontext.js.map +1 -0
- package/dist/src/reviewdetach.js +574 -0
- package/dist/src/reviewdetach.js.map +1 -0
- package/dist/src/reviewhistory.js +284 -0
- package/dist/src/reviewhistory.js.map +1 -0
- package/dist/src/reviewhome.js +26 -0
- package/dist/src/reviewhome.js.map +1 -0
- package/dist/src/reviewmemory.js +110 -0
- package/dist/src/reviewmemory.js.map +1 -0
- package/dist/src/reviewrendercli.js +104 -0
- package/dist/src/reviewrendercli.js.map +1 -0
- package/dist/src/round-work.js +20 -0
- package/dist/src/round-work.js.map +1 -0
- package/dist/src/runhost.js +72 -0
- package/dist/src/runhost.js.map +1 -0
- package/dist/src/scanauth.js +25 -0
- package/dist/src/scanauth.js.map +1 -0
- package/dist/src/scanbox.js +846 -0
- package/dist/src/scanbox.js.map +1 -0
- package/dist/src/scancli.js +1074 -0
- package/dist/src/scancli.js.map +1 -0
- package/dist/src/scandriverlog.js +30 -0
- package/dist/src/scandriverlog.js.map +1 -0
- package/dist/src/session-bridge.js +75 -0
- package/dist/src/session-bridge.js.map +1 -0
- package/dist/src/session-command-payload.js +29 -0
- package/dist/src/session-command-payload.js.map +1 -0
- package/dist/src/session-command-supervisor.js +939 -0
- package/dist/src/session-command-supervisor.js.map +1 -0
- package/dist/src/sessionjsonl.js +85 -0
- package/dist/src/sessionjsonl.js.map +1 -0
- package/dist/src/sessions.js +541 -0
- package/dist/src/sessions.js.map +1 -0
- package/dist/src/setup/adapters.js +330 -0
- package/dist/src/setup/adapters.js.map +1 -0
- package/dist/src/setup/baselines.js +64 -0
- package/dist/src/setup/baselines.js.map +1 -0
- package/dist/src/setup/caserunner.js +554 -0
- package/dist/src/setup/caserunner.js.map +1 -0
- package/dist/src/setup/configcommit.js +358 -0
- package/dist/src/setup/configcommit.js.map +1 -0
- package/dist/src/setup/engine.js +672 -0
- package/dist/src/setup/engine.js.map +1 -0
- package/dist/src/setup/facts.js +593 -0
- package/dist/src/setup/facts.js.map +1 -0
- package/dist/src/setup/findings.js +948 -0
- package/dist/src/setup/findings.js.map +1 -0
- package/dist/src/setup/history.js +338 -0
- package/dist/src/setup/history.js.map +1 -0
- package/dist/src/setup/interview.js +185 -0
- package/dist/src/setup/interview.js.map +1 -0
- package/dist/src/setup/ledger.js +207 -0
- package/dist/src/setup/ledger.js.map +1 -0
- package/dist/src/setup/pins.js +43 -0
- package/dist/src/setup/pins.js.map +1 -0
- package/dist/src/setup/portrait.js +432 -0
- package/dist/src/setup/portrait.js.map +1 -0
- package/dist/src/setup/presentation.js +9 -0
- package/dist/src/setup/presentation.js.map +1 -0
- package/dist/src/setup/profile.js +417 -0
- package/dist/src/setup/profile.js.map +1 -0
- package/dist/src/setup/replay.js +240 -0
- package/dist/src/setup/replay.js.map +1 -0
- package/dist/src/setup/replaybuild.js +311 -0
- package/dist/src/setup/replaybuild.js.map +1 -0
- package/dist/src/setup/replayrun.js +806 -0
- package/dist/src/setup/replayrun.js.map +1 -0
- package/dist/src/setup/replaysource.js +169 -0
- package/dist/src/setup/replaysource.js.map +1 -0
- package/dist/src/setup/retune.js +333 -0
- package/dist/src/setup/retune.js.map +1 -0
- package/dist/src/setup/retunelog.js +51 -0
- package/dist/src/setup/retunelog.js.map +1 -0
- package/dist/src/setup/scan.js +725 -0
- package/dist/src/setup/scan.js.map +1 -0
- package/dist/src/setup/scanbuild.js +133 -0
- package/dist/src/setup/scanbuild.js.map +1 -0
- package/dist/src/setup/scanfacts.js +96 -0
- package/dist/src/setup/scanfacts.js.map +1 -0
- package/dist/src/setup/scanlease.js +251 -0
- package/dist/src/setup/scanlease.js.map +1 -0
- package/dist/src/setup/scanreport.js +289 -0
- package/dist/src/setup/scanreport.js.map +1 -0
- package/dist/src/setup/scanrun.js +1733 -0
- package/dist/src/setup/scanrun.js.map +1 -0
- package/dist/src/setup/scantree.js +257 -0
- package/dist/src/setup/scantree.js.map +1 -0
- package/dist/src/setup/stage2.js +617 -0
- package/dist/src/setup/stage2.js.map +1 -0
- package/dist/src/setup/stage2request.js +259 -0
- package/dist/src/setup/stage2request.js.map +1 -0
- package/dist/src/setup/survey.js +307 -0
- package/dist/src/setup/survey.js.map +1 -0
- package/dist/src/setup/surveyrun.js +549 -0
- package/dist/src/setup/surveyrun.js.map +1 -0
- package/dist/src/setup/textsniff.js +89 -0
- package/dist/src/setup/textsniff.js.map +1 -0
- package/dist/src/setup/trackersink.js +395 -0
- package/dist/src/setup/trackersink.js.map +1 -0
- package/dist/src/setup/triage.js +636 -0
- package/dist/src/setup/triage.js.map +1 -0
- package/dist/src/setup/tuning.js +585 -0
- package/dist/src/setup/tuning.js.map +1 -0
- package/dist/src/setup/unitcut.js +437 -0
- package/dist/src/setup/unitcut.js.map +1 -0
- package/dist/src/singleflight.js +72 -0
- package/dist/src/singleflight.js.map +1 -0
- package/dist/src/slack/announce.js +725 -0
- package/dist/src/slack/announce.js.map +1 -0
- package/dist/src/slack/api.js +227 -0
- package/dist/src/slack/api.js.map +1 -0
- package/dist/src/slack/messages.js +158 -0
- package/dist/src/slack/messages.js.map +1 -0
- package/dist/src/slack/origin.js +550 -0
- package/dist/src/slack/origin.js.map +1 -0
- package/dist/src/slack/policy.js +225 -0
- package/dist/src/slack/policy.js.map +1 -0
- package/dist/src/slack/reply.js +153 -0
- package/dist/src/slack/reply.js.map +1 -0
- package/dist/src/slack/router.js +189 -0
- package/dist/src/slack/router.js.map +1 -0
- package/dist/src/slack/socket.js +323 -0
- package/dist/src/slack/socket.js.map +1 -0
- package/dist/src/slack/types.js +11 -0
- package/dist/src/slack/types.js.map +1 -0
- package/dist/src/sqlitehint.js +30 -0
- package/dist/src/sqlitehint.js.map +1 -0
- package/dist/src/ssh-observation.js +25 -0
- package/dist/src/ssh-observation.js.map +1 -0
- package/dist/src/state.js +5869 -0
- package/dist/src/state.js.map +1 -0
- package/dist/src/statemachine.js +220 -0
- package/dist/src/statemachine.js.map +1 -0
- package/dist/src/stubs.js +52 -0
- package/dist/src/stubs.js.map +1 -0
- package/dist/src/takeover.js +506 -0
- package/dist/src/takeover.js.map +1 -0
- package/dist/src/takeoverpi.js +249 -0
- package/dist/src/takeoverpi.js.map +1 -0
- package/dist/src/terminal-failure.js +26 -0
- package/dist/src/terminal-failure.js.map +1 -0
- package/dist/src/thread-resolution-refusal.js +4 -0
- package/dist/src/thread-resolution-refusal.js.map +1 -0
- package/dist/src/tmux.js +126 -0
- package/dist/src/tmux.js.map +1 -0
- package/dist/src/trackerid.js +43 -0
- package/dist/src/trackerid.js.map +1 -0
- package/dist/src/transcriptindex.js +512 -0
- package/dist/src/transcriptindex.js.map +1 -0
- package/dist/src/tui/actions.js +404 -0
- package/dist/src/tui/actions.js.map +1 -0
- package/dist/src/tui/alerts.js +523 -0
- package/dist/src/tui/alerts.js.map +1 -0
- package/dist/src/tui/app.js +1835 -0
- package/dist/src/tui/app.js.map +1 -0
- package/dist/src/tui/archiveops.js +164 -0
- package/dist/src/tui/archiveops.js.map +1 -0
- package/dist/src/tui/autofile.js +191 -0
- package/dist/src/tui/autofile.js.map +1 -0
- package/dist/src/tui/board.js +1143 -0
- package/dist/src/tui/board.js.map +1 -0
- package/dist/src/tui/candidates.js +699 -0
- package/dist/src/tui/candidates.js.map +1 -0
- package/dist/src/tui/cellwidth.js +151 -0
- package/dist/src/tui/cellwidth.js.map +1 -0
- package/dist/src/tui/changelog-store.js +404 -0
- package/dist/src/tui/changelog-store.js.map +1 -0
- package/dist/src/tui/chord.js +26 -0
- package/dist/src/tui/chord.js.map +1 -0
- package/dist/src/tui/clipboard.js +81 -0
- package/dist/src/tui/clipboard.js.map +1 -0
- package/dist/src/tui/cmdbar.js +253 -0
- package/dist/src/tui/cmdbar.js.map +1 -0
- package/dist/src/tui/companion.js +1275 -0
- package/dist/src/tui/companion.js.map +1 -0
- package/dist/src/tui/companionplan.js +200 -0
- package/dist/src/tui/companionplan.js.map +1 -0
- package/dist/src/tui/companiontab.js +61 -0
- package/dist/src/tui/companiontab.js.map +1 -0
- package/dist/src/tui/confighome.js +105 -0
- package/dist/src/tui/confighome.js.map +1 -0
- package/dist/src/tui/connect.js +44 -0
- package/dist/src/tui/connect.js.map +1 -0
- package/dist/src/tui/deploy-ceremony.js +75 -0
- package/dist/src/tui/deploy-ceremony.js.map +1 -0
- package/dist/src/tui/deploy-drain.js +93 -0
- package/dist/src/tui/deploy-drain.js.map +1 -0
- package/dist/src/tui/deploy-process.js +234 -0
- package/dist/src/tui/deploy-process.js.map +1 -0
- package/dist/src/tui/deploytab.js +1263 -0
- package/dist/src/tui/deploytab.js.map +1 -0
- package/dist/src/tui/design.js +111 -0
- package/dist/src/tui/design.js.map +1 -0
- package/dist/src/tui/digesttab.js +148 -0
- package/dist/src/tui/digesttab.js.map +1 -0
- package/dist/src/tui/emptystate.js +32 -0
- package/dist/src/tui/emptystate.js.map +1 -0
- package/dist/src/tui/evidence.js +790 -0
- package/dist/src/tui/evidence.js.map +1 -0
- package/dist/src/tui/feed.js +415 -0
- package/dist/src/tui/feed.js.map +1 -0
- package/dist/src/tui/feedbacktab.js +907 -0
- package/dist/src/tui/feedbacktab.js.map +1 -0
- package/dist/src/tui/filters.js +72 -0
- package/dist/src/tui/filters.js.map +1 -0
- package/dist/src/tui/ghread.js +272 -0
- package/dist/src/tui/ghread.js.map +1 -0
- package/dist/src/tui/historypull.js +61 -0
- package/dist/src/tui/historypull.js.map +1 -0
- package/dist/src/tui/inboxpull.js +197 -0
- package/dist/src/tui/inboxpull.js.map +1 -0
- package/dist/src/tui/index.js +1425 -0
- package/dist/src/tui/index.js.map +1 -0
- package/dist/src/tui/issuesink.js +206 -0
- package/dist/src/tui/issuesink.js.map +1 -0
- package/dist/src/tui/jsonfile.js +32 -0
- package/dist/src/tui/jsonfile.js.map +1 -0
- package/dist/src/tui/keys.js +97 -0
- package/dist/src/tui/keys.js.map +1 -0
- package/dist/src/tui/layout.js +70 -0
- package/dist/src/tui/layout.js.map +1 -0
- package/dist/src/tui/learning.js +469 -0
- package/dist/src/tui/learning.js.map +1 -0
- package/dist/src/tui/lessonswitch.js +103 -0
- package/dist/src/tui/lessonswitch.js.map +1 -0
- package/dist/src/tui/livecontrol.js +167 -0
- package/dist/src/tui/livecontrol.js.map +1 -0
- package/dist/src/tui/memforward.js +310 -0
- package/dist/src/tui/memforward.js.map +1 -0
- package/dist/src/tui/memincident.js +287 -0
- package/dist/src/tui/memincident.js.map +1 -0
- package/dist/src/tui/memory.js +485 -0
- package/dist/src/tui/memory.js.map +1 -0
- package/dist/src/tui/memtab.js +513 -0
- package/dist/src/tui/memtab.js.map +1 -0
- package/dist/src/tui/metricstab.js +979 -0
- package/dist/src/tui/metricstab.js.map +1 -0
- package/dist/src/tui/model.js +104 -0
- package/dist/src/tui/model.js.map +1 -0
- package/dist/src/tui/mouse.js +83 -0
- package/dist/src/tui/mouse.js.map +1 -0
- package/dist/src/tui/msg.js +196 -0
- package/dist/src/tui/msg.js.map +1 -0
- package/dist/src/tui/nativecompanion.js +321 -0
- package/dist/src/tui/nativecompanion.js.map +1 -0
- package/dist/src/tui/openurl.js +17 -0
- package/dist/src/tui/openurl.js.map +1 -0
- package/dist/src/tui/paint.js +501 -0
- package/dist/src/tui/paint.js.map +1 -0
- package/dist/src/tui/panes.js +74 -0
- package/dist/src/tui/panes.js.map +1 -0
- package/dist/src/tui/pipane.js +166 -0
- package/dist/src/tui/pipane.js.map +1 -0
- package/dist/src/tui/poll-hooks.js +11 -0
- package/dist/src/tui/poll-hooks.js.map +1 -0
- package/dist/src/tui/poll.js +113 -0
- package/dist/src/tui/poll.js.map +1 -0
- package/dist/src/tui/proposals.js +715 -0
- package/dist/src/tui/proposals.js.map +1 -0
- package/dist/src/tui/prpause.js +132 -0
- package/dist/src/tui/prpause.js.map +1 -0
- package/dist/src/tui/reload.js +351 -0
- package/dist/src/tui/reload.js.map +1 -0
- package/dist/src/tui/remote.js +312 -0
- package/dist/src/tui/remote.js.map +1 -0
- package/dist/src/tui/rollover.js +767 -0
- package/dist/src/tui/rollover.js.map +1 -0
- package/dist/src/tui/scantab.js +1053 -0
- package/dist/src/tui/scantab.js.map +1 -0
- package/dist/src/tui/setupentry.js +81 -0
- package/dist/src/tui/setupentry.js.map +1 -0
- package/dist/src/tui/sidebar.js +602 -0
- package/dist/src/tui/sidebar.js.map +1 -0
- package/dist/src/tui/sshtriage.js +393 -0
- package/dist/src/tui/sshtriage.js.map +1 -0
- package/dist/src/tui/startup.js +172 -0
- package/dist/src/tui/startup.js.map +1 -0
- package/dist/src/tui/tabs.js +41 -0
- package/dist/src/tui/tabs.js.map +1 -0
- package/dist/src/tui/termmirror.js +217 -0
- package/dist/src/tui/termmirror.js.map +1 -0
- package/dist/src/tui/theme.js +95 -0
- package/dist/src/tui/theme.js.map +1 -0
- package/dist/src/tui/ticketstab.js +224 -0
- package/dist/src/tui/ticketstab.js.map +1 -0
- package/dist/src/tui/tmuxsocket.js +101 -0
- package/dist/src/tui/tmuxsocket.js.map +1 -0
- package/dist/src/tui/trackertickets.js +77 -0
- package/dist/src/tui/trackertickets.js.map +1 -0
- package/dist/src/tui/unwedge.js +245 -0
- package/dist/src/tui/unwedge.js.map +1 -0
- package/dist/src/tui/viewer.js +479 -0
- package/dist/src/tui/viewer.js.map +1 -0
- package/dist/src/tui/viewerinput.js +125 -0
- package/dist/src/tui/viewerinput.js.map +1 -0
- package/dist/src/updatenotice.js +143 -0
- package/dist/src/updatenotice.js.map +1 -0
- package/dist/src/usage.js +1007 -0
- package/dist/src/usage.js.map +1 -0
- package/dist/src/verdicts.js +3848 -0
- package/dist/src/verdicts.js.map +1 -0
- package/dist/src/version.js +58 -0
- package/dist/src/version.js.map +1 -0
- package/dist/src/wakes.js +411 -0
- package/dist/src/wakes.js.map +1 -0
- package/dist/src/webhook.js +725 -0
- package/dist/src/webhook.js.map +1 -0
- package/dist/src/webhookheal.js +238 -0
- package/dist/src/webhookheal.js.map +1 -0
- package/dist/src/wire.js +1801 -0
- package/dist/src/wire.js.map +1 -0
- package/dist/src/worker-session-host.js +531 -0
- package/dist/src/worker-session-host.js.map +1 -0
- package/dist/src/workerbreaker.js +112 -0
- package/dist/src/workerbreaker.js.map +1 -0
- package/dist/src/workercontrol.js +49 -0
- package/dist/src/workercontrol.js.map +1 -0
- package/dist/src/workerlease.js +351 -0
- package/dist/src/workerlease.js.map +1 -0
- package/dist/src/workerliveness.js +84 -0
- package/dist/src/workerliveness.js.map +1 -0
- package/dist/src/workerlog.js +65 -0
- package/dist/src/workerlog.js.map +1 -0
- package/dist/src/workerruntime.js +10 -0
- package/dist/src/workerruntime.js.map +1 -0
- package/dist/src/workersupervisor.js +1206 -0
- package/dist/src/workersupervisor.js.map +1 -0
- package/dist/src/workerusage.js +23 -0
- package/dist/src/workerusage.js.map +1 -0
- package/dist/src/workerworld.js +332 -0
- package/dist/src/workerworld.js.map +1 -0
- package/dist/src/worktrees.js +984 -0
- package/dist/src/worktrees.js.map +1 -0
- package/docker/Dockerfile +284 -0
- package/docker/Dockerfile.dockerignore +35 -0
- package/docker/README.md +221 -0
- package/docker/companion/Dockerfile +139 -0
- package/docker/companion/agents/evidence.md +34 -0
- package/docker/companion/agents/explore.md +26 -0
- package/docker/companion/agents/pass-survey.md +49 -0
- package/docker/companion/agents/study.md +26 -0
- package/docker/companion/entrypoint.sh +343 -0
- package/docker/companion/memory-health.mjs +269 -0
- package/docker/entrypoint.sh +782 -0
- package/docker/memory/Dockerfile +191 -0
- package/docker/memory/Dockerfile.dockerignore +20 -0
- package/docker/memory/README.md +60 -0
- package/docker/memory/entrypoint.sh +163 -0
- package/docker/setid/qcr-setid.c +109 -0
- package/docker/tunnel/Dockerfile.cloudflared +51 -0
- package/docker/tunnel/Dockerfile.ngrok +40 -0
- package/docker/tunnel/sidecar.mjs +411 -0
- package/docker/vm/tmux.conf +26 -0
- package/docker-compose.yml +348 -0
- package/extensions/cli/bash-guard-ambient.ts +71 -0
- package/extensions/cli/bash-guard.ts +12 -0
- package/extensions/cli/companion-guard.ts +8 -0
- package/extensions/cli/debug-round.ts +9 -0
- package/extensions/cli/inject-bridge.ts +8 -0
- package/extensions/cli/ledger-pin.ts +13 -0
- package/extensions/cli/lens.ts +22 -0
- package/extensions/cli/muted-theme.ts +9 -0
- package/extensions/cli/onboarding.ts +8 -0
- package/extensions/cli/setup.ts +8 -0
- package/extensions/cli/tui-view.ts +8 -0
- package/extensions/companion-guard.ts +411 -0
- package/extensions/debug-round.ts +281 -0
- package/extensions/inject-bridge.ts +630 -0
- package/extensions/inline-bash.ts +102 -0
- package/extensions/muted-theme.json +68 -0
- package/extensions/muted-theme.ts +23 -0
- package/extensions/onboarding.ts +233 -0
- package/extensions/setup-replay.ts +336 -0
- package/extensions/setup-scan.ts +1236 -0
- package/extensions/setup-triage.ts +190 -0
- package/extensions/setup.ts +1428 -0
- package/extensions/tui-view.ts +489 -0
- package/extensions/vendor/openviking-pi/LICENSE +201 -0
- package/extensions/vendor/openviking-pi/NOTICE +68 -0
- package/extensions/vendor/openviking-pi/README.md +550 -0
- package/extensions/vendor/openviking-pi/client.ts +588 -0
- package/extensions/vendor/openviking-pi/config.json +28 -0
- package/extensions/vendor/openviking-pi/config.ts +271 -0
- package/extensions/vendor/openviking-pi/index.ts +523 -0
- package/extensions/vendor/openviking-pi/lib/capture-adapter.d.mts +10 -0
- package/extensions/vendor/openviking-pi/lib/capture-adapter.mjs +88 -0
- package/extensions/vendor/openviking-pi/lib/takeover-core.d.mts +80 -0
- package/extensions/vendor/openviking-pi/lib/takeover-core.mjs +406 -0
- package/extensions/vendor/openviking-pi/lib/uri-guard-adapter.d.mts +1 -0
- package/extensions/vendor/openviking-pi/lib/uri-guard-adapter.mjs +42 -0
- package/extensions/vendor/openviking-pi/patches/0000-vendoring-and-build-conformance.patch +726 -0
- package/extensions/vendor/openviking-pi/patches/0001-remove-session-before-compact-handler.patch +101 -0
- package/extensions/vendor/openviking-pi/patches/0002-no-ambient-work-in-subagent-leaves.patch +202 -0
- package/extensions/vendor/openviking-pi/patches/0003-never-auto-create-openviking-sessions.patch +120 -0
- package/extensions/vendor/openviking-pi/patches/0004-viking-write-durable-batch-write.patch +521 -0
- package/extensions/vendor/openviking-pi/patches/0005-second-memory-namespace.patch +786 -0
- package/extensions/vendor/openviking-pi/patches/0006-writes-that-stick-and-honest-errors.patch +996 -0
- package/extensions/vendor/openviking-pi/patches/0007-bounded-recall-no-commit.patch +794 -0
- package/extensions/vendor/openviking-pi/patches/0008-pr-derived-recall.patch +379 -0
- package/extensions/vendor/openviking-pi/patches/0009-pr-session-tools-in-round-areas.patch +375 -0
- package/extensions/vendor/openviking-pi/patches/0010-typed-lessons.patch +448 -0
- package/extensions/vendor/openviking-pi/patches/0011-review-session-memory-boundary.patch +382 -0
- package/extensions/vendor/openviking-pi/patches/0012-typecheck-against-the-real-pi.patch +129 -0
- package/extensions/vendor/openviking-pi/patches/0013-createopenviking-factory.patch +1168 -0
- package/extensions/vendor/openviking-pi/qcr-hint.ts +313 -0
- package/extensions/vendor/openviking-pi/qcr-honest.ts +183 -0
- package/extensions/vendor/openviking-pi/qcr-hooks.ts +87 -0
- package/extensions/vendor/openviking-pi/qcr-leaf.ts +78 -0
- package/extensions/vendor/openviking-pi/qcr-lesson.ts +231 -0
- package/extensions/vendor/openviking-pi/qcr-namespaces.ts +198 -0
- package/extensions/vendor/openviking-pi/qcr-recall.ts +288 -0
- package/extensions/vendor/openviking-pi/qcr-shim.ts +142 -0
- package/extensions/vendor/openviking-pi/qcr-write.ts +427 -0
- package/extensions/vendor/openviking-pi/recall.ts +149 -0
- package/extensions/vendor/openviking-pi/shared/capture-utils.d.mts +9 -0
- package/extensions/vendor/openviking-pi/shared/capture-utils.mjs +515 -0
- package/extensions/vendor/openviking-pi/shared/credentials.d.mts +14 -0
- package/extensions/vendor/openviking-pi/shared/credentials.mjs +228 -0
- package/extensions/vendor/openviking-pi/shared/pending-queue.d.mts +19 -0
- package/extensions/vendor/openviking-pi/shared/pending-queue.mjs +458 -0
- package/extensions/vendor/openviking-pi/shared/profile-inject.d.mts +17 -0
- package/extensions/vendor/openviking-pi/shared/profile-inject.mjs +294 -0
- package/extensions/vendor/openviking-pi/shared/recall-compress-core.mjs +195 -0
- package/extensions/vendor/openviking-pi/shared/recall-core.d.mts +13 -0
- package/extensions/vendor/openviking-pi/shared/recall-core.mjs +609 -0
- package/extensions/vendor/openviking-pi/shared/retryable.mjs +9 -0
- package/extensions/vendor/openviking-pi/shared/session-model.d.mts +3 -0
- package/extensions/vendor/openviking-pi/shared/session-model.mjs +57 -0
- package/extensions/vendor/openviking-pi/shared/uri-guard.mjs +56 -0
- package/extensions/vendor/openviking-pi/shared/workspace-peer.d.mts +5 -0
- package/extensions/vendor/openviking-pi/shared/workspace-peer.mjs +16 -0
- package/extensions/vendor/openviking-pi/sync.ts +163 -0
- package/extensions/vendor/openviking-pi/takeover.ts +36 -0
- package/extensions/vendor/openviking-pi/tools.ts +479 -0
- package/extensions/vendor/openviking-pi/upstream.json +48 -0
- package/package.json +138 -4
- package/profiles/default/README.md +21 -0
- package/profiles/default/addenda/.gitkeep +0 -0
- package/profiles/default/profile.toml +17 -0
- package/profiles/example-django/README.md +21 -0
- package/profiles/example-django/addenda/10-migration-discipline.md +13 -0
- package/profiles/example-django/addenda/20-new-column-nullability.md +12 -0
- package/profiles/example-django/addenda/30-test-doctrine.md +12 -0
- package/profiles/example-django/addenda/40-orm-usage.md +19 -0
- package/profiles/example-django/addenda/50-declared-shape.md +10 -0
- package/profiles/example-django/addenda/60-config-placement.md +14 -0
- package/profiles/example-django/heuristics.toml +24 -0
- package/profiles/example-django/profile.toml +9 -0
- package/profiles/fast/README.md +24 -0
- package/profiles/fast/profile.toml +59 -0
- package/profiles/minimal/README.md +17 -0
- package/profiles/minimal/addenda/.gitkeep +0 -0
- package/profiles/minimal/profile.toml +8 -0
- package/profiles/snappy/README.md +24 -0
- package/profiles/snappy/addenda/10-race-as-question.md +6 -0
- package/profiles/snappy/profile.toml +46 -0
- package/prompts/companion-day-open.md +46 -0
- package/prompts/companion-first-run.md +104 -0
- package/prompts/companion.md +821 -0
- package/prompts/conversation-system.md +117 -0
- package/prompts/eod-sweep.md +120 -0
- package/prompts/onboarding.md +74 -0
- package/prompts/pass-common.md +52 -0
- package/prompts/pass-quality-common.md +22 -0
- package/prompts/round-first.md +874 -0
- package/prompts/round-follow-up.md +991 -0
- package/prompts/round-re-review.md +889 -0
- package/prompts/round-recheck.md +196 -0
- package/prompts/round-staleness.md +856 -0
- package/schemas/review-result.v1.json +391 -0
- package/schemas/scan-result.v1.json +421 -0
- package/schemas/version.v1.json +57 -0
- package/scripts/approve-pr.sh +16 -0
- package/scripts/build-stamp.mjs +67 -0
- package/scripts/commit-verdict.sh +155 -0
- package/scripts/companion-e2e.sh +250 -0
- package/scripts/companion-memory-forward.mjs +1966 -0
- package/scripts/config-fingerprint.sh +28 -0
- package/scripts/deploy-manifest.mjs +141 -0
- package/scripts/deploy.sh +1435 -0
- package/scripts/directory-lock.mjs +193 -0
- package/scripts/heartbeat-fresh.mjs +54 -0
- package/scripts/install-locator.sh +328 -0
- package/scripts/install-wrapper.sh +76 -0
- package/scripts/memory-search-check.mjs +98 -0
- package/scripts/mint-token.sh +212 -0
- package/scripts/openviking-embedder.py +392 -0
- package/scripts/openviking-ov-conf.mjs +161 -0
- package/scripts/openviking-provision.mjs +1122 -0
- package/scripts/openviking-reembed.mjs +1154 -0
- package/scripts/post-review.sh +16 -0
- package/scripts/pr-checks.sh +256 -0
- package/scripts/pr-context.py +174 -0
- package/scripts/pr-context.sh +63 -0
- package/scripts/pr-self.sh +144 -0
- package/scripts/pr-threads.sh +145 -0
- package/scripts/qcr +15 -0
- package/scripts/qcr-host.sh +769 -0
- package/scripts/render-review.sh +24 -0
- package/scripts/reply-thread.sh +16 -0
- package/scripts/required-passes.py +112 -0
- package/scripts/smoke-companion.sh +211 -0
- package/scripts/tui-deploy-runner.mjs +61 -0
- package/scripts/verify-dist.mjs +201 -0
- package/scripts/vm-ghcr-login.sh +188 -0
- package/seeds/agents/pass-baseline.md +61 -0
- package/seeds/agents/pass-contracts.md +30 -0
- package/seeds/agents/pass-data-safety.md +54 -0
- package/seeds/agents/pass-delivery.md +37 -0
- package/seeds/agents/pass-prod-risk.md +24 -0
- package/seeds/agents/pass-security.md +31 -0
- package/seeds/agents/pass-statelessness.md +27 -0
- package/seeds/agents/pass-ui.md +23 -0
- package/seeds/agents/pass-validate.md +50 -0
- package/seeds/prompts/conversation-system.md +117 -0
- package/seeds/prompts/eod-sweep.md +120 -0
- package/seeds/prompts/pass-common.md +52 -0
- package/skills/companion/adjudicate/SKILL.md +247 -0
- package/skills/companion/evidence/SKILL.md +150 -0
- package/skills/companion/land/SKILL.md +200 -0
- package/skills/companion/replay/SKILL.md +138 -0
- package/skills/companion/setup/SKILL.md +167 -0
- package/skills/companion/survey/SKILL.md +160 -0
- package/skills/selfimprove/README.md +34 -0
- package/skills/selfimprove/SKILL.md +127 -0
- package/skills/selfimprove/agents/openai.yaml +2 -0
- package/skills/selfimprove/commands/selfimprove.md +6 -0
- package/skills/selfimprove/references/fix-loop.md +49 -0
- package/skills/selfimprove/references/ledger.md +20 -0
- package/skills/selfimprove/references/setup.md +40 -0
- package/src/anomalies.ts +566 -0
- package/src/answerworker.ts +251 -0
- package/src/appstamp.ts +65 -0
- package/src/archive/admission.ts +3 -0
- package/src/archive/archivedb.ts +548 -0
- package/src/archive/archiver.ts +1963 -0
- package/src/archive/archivewrite.ts +279 -0
- package/src/archive/bundle.ts +333 -0
- package/src/archive/dbmove.ts +911 -0
- package/src/archive/duplicatecounts.ts +98 -0
- package/src/archive/eligibility.ts +181 -0
- package/src/archive/extract.ts +342 -0
- package/src/archive/fsutil.ts +415 -0
- package/src/archive/gzfile.ts +370 -0
- package/src/archive/kinds.ts +21 -0
- package/src/archive/livecheckpoint.ts +217 -0
- package/src/archive/liveretention.ts +180 -0
- package/src/archive/manifest.ts +519 -0
- package/src/archive/overseer.ts +336 -0
- package/src/archive/piglobal.ts +174 -0
- package/src/archive/plan.ts +612 -0
- package/src/archive/prarchive.ts +984 -0
- package/src/archive/prfiles.ts +406 -0
- package/src/archive/report.ts +252 -0
- package/src/archive/restore.ts +330 -0
- package/src/archive/rows.ts +187 -0
- package/src/archive/seal.ts +630 -0
- package/src/archive/status.ts +719 -0
- package/src/archive/storepass.ts +581 -0
- package/src/backfill.ts +362 -0
- package/src/bench/cost.ts +113 -0
- package/src/bench/exec.ts +90 -0
- package/src/bench/values.ts +13 -0
- package/src/botcontrol.ts +176 -0
- package/src/botworker.ts +953 -0
- package/src/capture.ts +321 -0
- package/src/cases.ts +1789 -0
- package/src/channelfs.ts +26 -0
- package/src/checklist.ts +506 -0
- package/src/ciretry.ts +141 -0
- package/src/cli.ts +2271 -0
- package/src/cliops.ts +384 -0
- package/src/clonedir.ts +15 -0
- package/src/commandeffects.ts +57 -0
- package/src/commands.ts +1678 -0
- package/src/companioninbox.ts +239 -0
- package/src/compare.ts +957 -0
- package/src/config.ts +2050 -0
- package/src/configcheck.ts +133 -0
- package/src/coreext.ts +47 -0
- package/src/daemon.ts +1302 -0
- package/src/debuground.ts +927 -0
- package/src/debugroundpi.ts +262 -0
- package/src/diagnostics.ts +14 -0
- package/src/digest.ts +183 -0
- package/src/dispatch.ts +2250 -0
- package/src/engine/answerguard.ts +27 -0
- package/src/engine/botsdk.ts +336 -0
- package/src/engine/caserunner-sdk.ts +423 -0
- package/src/engine/debugpi.ts +235 -0
- package/src/eod.ts +669 -0
- package/src/eodpinwatch.ts +556 -0
- package/src/escalation.ts +1253 -0
- package/src/eventloop.ts +1045 -0
- package/src/execboundary.ts +633 -0
- package/src/feedback.ts +1162 -0
- package/src/findingscheck.ts +298 -0
- package/src/fsdenied.ts +24 -0
- package/src/ghread.ts +242 -0
- package/src/github.ts +1497 -0
- package/src/homes.ts +175 -0
- package/src/hostroute.ts +53 -0
- package/src/improvements.ts +787 -0
- package/src/install.ts +1103 -0
- package/src/installkind.ts +50 -0
- package/src/ipc/capability.ts +333 -0
- package/src/ipc/client.ts +269 -0
- package/src/ipc/control.ts +90 -0
- package/src/ipc/ghreadshim.ts +94 -0
- package/src/ipc/launcher.ts +65 -0
- package/src/ipc/permits.ts +362 -0
- package/src/ipc/postshim.ts +164 -0
- package/src/ipc/protocol.ts +342 -0
- package/src/ipc/server.ts +371 -0
- package/src/ipc/workerspec.ts +218 -0
- package/src/learner/learner.ts +1655 -0
- package/src/learner/miner.ts +1290 -0
- package/src/learner/packet.ts +340 -0
- package/src/learner/receipt.ts +168 -0
- package/src/learner/status.ts +107 -0
- package/src/ledgercheck.ts +157 -0
- package/src/lessonledger.ts +703 -0
- package/src/lessonselect.ts +888 -0
- package/src/lessonshadow.ts +810 -0
- package/src/levers.ts +393 -0
- package/src/live/projection.ts +491 -0
- package/src/live/publish.ts +92 -0
- package/src/live/read.ts +86 -0
- package/src/livecli.ts +336 -0
- package/src/loginhint.ts +56 -0
- package/src/loginrefresh/atomic.ts +76 -0
- package/src/loginrefresh/lock.ts +104 -0
- package/src/loginrefresh/main.ts +59 -0
- package/src/loginrefresh/pirefresh.ts +57 -0
- package/src/loginrefresh/refresher.ts +326 -0
- package/src/loginrefresh/supervisor.ts +273 -0
- package/src/loginrefresh/types.ts +35 -0
- package/src/memory/context.ts +385 -0
- package/src/memory/datafence.ts +9 -0
- package/src/memory/delivery.ts +171 -0
- package/src/memory/eventtags.ts +80 -0
- package/src/memory/health.ts +953 -0
- package/src/memory/import.ts +664 -0
- package/src/memory/layout.ts +261 -0
- package/src/memory/legacy-file.ts +104 -0
- package/src/memory/lessons.ts +447 -0
- package/src/memory/ovsession.ts +601 -0
- package/src/memory/relayout.ts +335 -0
- package/src/memory/roundactivity.ts +209 -0
- package/src/memory/selection.ts +989 -0
- package/src/memory/shadowstatus.ts +125 -0
- package/src/memory/store.ts +275 -0
- package/src/memory/textidentity.ts +8 -0
- package/src/metrics.ts +1056 -0
- package/src/missingconfig.ts +7 -0
- package/src/npmverbs.ts +264 -0
- package/src/onboard/choices.ts +222 -0
- package/src/onboard/engine.ts +518 -0
- package/src/onboard/launch.ts +115 -0
- package/src/onboard/steps/appslug.ts +265 -0
- package/src/onboard/steps/bringup.ts +482 -0
- package/src/onboard/steps/compose.ts +459 -0
- package/src/onboard/steps/configdelivery.ts +58 -0
- package/src/onboard/steps/configfill.ts +1352 -0
- package/src/onboard/steps/deploysh.ts +105 -0
- package/src/onboard/steps/embeddings.ts +550 -0
- package/src/onboard/steps/escalation.ts +640 -0
- package/src/onboard/steps/githubapp.ts +1414 -0
- package/src/onboard/steps/golive.ts +577 -0
- package/src/onboard/steps/index.ts +71 -0
- package/src/onboard/steps/ingress.ts +907 -0
- package/src/onboard/steps/inventory.ts +526 -0
- package/src/onboard/steps/llmauth.ts +1095 -0
- package/src/onboard/steps/memory.ts +1290 -0
- package/src/onboard/steps/memorykeys.ts +85 -0
- package/src/onboard/steps/preflight.ts +191 -0
- package/src/onboard/steps/proof.ts +624 -0
- package/src/onboard/steps/ssh.ts +377 -0
- package/src/onboard/steps/topology.ts +337 -0
- package/src/onboard/steps/transport.ts +665 -0
- package/src/onboard/steps/verifyup.ts +448 -0
- package/src/onboard/steps/vmdeploy.ts +442 -0
- package/src/onboard/toml.ts +50 -0
- package/src/opencli.ts +591 -0
- package/src/openpr.ts +568 -0
- package/src/openviking/client.ts +1131 -0
- package/src/openviking/context.ts +263 -0
- package/src/openviking/embedder.ts +516 -0
- package/src/openviking/gapsink.ts +63 -0
- package/src/openviking/health.ts +83 -0
- package/src/openviking/index.ts +119 -0
- package/src/openviking/lessonfind.ts +92 -0
- package/src/openviking/probe.ts +129 -0
- package/src/openviking/proc.ts +110 -0
- package/src/openviking/provisionreport.ts +160 -0
- package/src/openviking/reembed.ts +412 -0
- package/src/openviking/relayout.ts +177 -0
- package/src/openviking/sidecar-main.ts +38 -0
- package/src/openviking/sidecar.ts +106 -0
- package/src/openviking/store.ts +2025 -0
- package/src/openviking/supervisor.ts +474 -0
- package/src/openviking/types.ts +174 -0
- package/src/operator-recovery.ts +237 -0
- package/src/operatormessage.ts +52 -0
- package/src/outcomes.ts +1670 -0
- package/src/piauthcopy.ts +12 -0
- package/src/picli.ts +49 -0
- package/src/picwd.ts +25 -0
- package/src/pilogin.ts +37 -0
- package/src/pingpong.ts +1339 -0
- package/src/posting-journal.ts +549 -0
- package/src/posting-outbox.ts +802 -0
- package/src/posting-receipt.ts +324 -0
- package/src/posting.ts +603 -0
- package/src/postops.ts +832 -0
- package/src/pr-activity.ts +20 -0
- package/src/pr-author.ts +6 -0
- package/src/pr-conversation.ts +432 -0
- package/src/pr-session-lifecycle.ts +631 -0
- package/src/preflight.ts +391 -0
- package/src/priorresolve.ts +343 -0
- package/src/qcrbin.ts +186 -0
- package/src/recheck.ts +1775 -0
- package/src/reconcile.ts +1030 -0
- package/src/recordedfindings.ts +27 -0
- package/src/regression.ts +833 -0
- package/src/replay.ts +816 -0
- package/src/requiredpasses.ts +148 -0
- package/src/resumecheck.ts +246 -0
- package/src/reviewcli.ts +787 -0
- package/src/reviewcontext.ts +35 -0
- package/src/reviewdetach.ts +734 -0
- package/src/reviewhistory.ts +427 -0
- package/src/reviewhome.ts +36 -0
- package/src/reviewmemory.ts +133 -0
- package/src/reviewrendercli.ts +139 -0
- package/src/round-work.ts +42 -0
- package/src/runhost.ts +108 -0
- package/src/scanauth.ts +36 -0
- package/src/scanbox.ts +1081 -0
- package/src/scancli.ts +1296 -0
- package/src/scandriverlog.ts +32 -0
- package/src/session-bridge.ts +139 -0
- package/src/session-command-payload.ts +35 -0
- package/src/session-command-supervisor.ts +1142 -0
- package/src/sessionjsonl.ts +88 -0
- package/src/sessions.ts +659 -0
- package/src/setup/adapters.ts +335 -0
- package/src/setup/baselines.ts +110 -0
- package/src/setup/caserunner.ts +611 -0
- package/src/setup/configcommit.ts +443 -0
- package/src/setup/engine.ts +1001 -0
- package/src/setup/facts.ts +627 -0
- package/src/setup/findings.ts +1264 -0
- package/src/setup/history.ts +443 -0
- package/src/setup/interview.ts +243 -0
- package/src/setup/ledger.ts +324 -0
- package/src/setup/pins.ts +66 -0
- package/src/setup/portrait.ts +635 -0
- package/src/setup/presentation.ts +18 -0
- package/src/setup/profile.ts +508 -0
- package/src/setup/replay.ts +370 -0
- package/src/setup/replaybuild.ts +392 -0
- package/src/setup/replayrun.ts +1096 -0
- package/src/setup/replaysource.ts +198 -0
- package/src/setup/retune.ts +415 -0
- package/src/setup/retunelog.ts +95 -0
- package/src/setup/scan.ts +1033 -0
- package/src/setup/scanbuild.ts +168 -0
- package/src/setup/scanfacts.ts +107 -0
- package/src/setup/scanlease.ts +297 -0
- package/src/setup/scanreport.ts +373 -0
- package/src/setup/scanrun.ts +2268 -0
- package/src/setup/scantree.ts +259 -0
- package/src/setup/stage2.ts +926 -0
- package/src/setup/stage2request.ts +347 -0
- package/src/setup/survey.ts +458 -0
- package/src/setup/surveyrun.ts +758 -0
- package/src/setup/textsniff.ts +95 -0
- package/src/setup/trackersink.ts +433 -0
- package/src/setup/triage.ts +768 -0
- package/src/setup/tuning.ts +766 -0
- package/src/setup/unitcut.ts +523 -0
- package/src/singleflight.ts +86 -0
- package/src/slack/announce.ts +911 -0
- package/src/slack/api.ts +303 -0
- package/src/slack/messages.ts +288 -0
- package/src/slack/origin.ts +599 -0
- package/src/slack/policy.ts +354 -0
- package/src/slack/reply.ts +201 -0
- package/src/slack/router.ts +285 -0
- package/src/slack/socket.ts +384 -0
- package/src/slack/types.ts +108 -0
- package/src/sqlitehint.ts +32 -0
- package/src/ssh-observation.ts +30 -0
- package/src/state.ts +8243 -0
- package/src/statemachine.ts +369 -0
- package/src/stubs.ts +68 -0
- package/src/takeover.ts +634 -0
- package/src/takeoverpi.ts +293 -0
- package/src/terminal-failure.ts +41 -0
- package/src/thread-resolution-refusal.ts +2 -0
- package/src/tmux.ts +153 -0
- package/src/trackerid.ts +41 -0
- package/src/transcriptindex.ts +665 -0
- package/src/tui/actions.ts +484 -0
- package/src/tui/alerts.ts +666 -0
- package/src/tui/app.ts +1979 -0
- package/src/tui/archiveops.ts +192 -0
- package/src/tui/autofile.ts +233 -0
- package/src/tui/board.ts +1432 -0
- package/src/tui/candidates.ts +889 -0
- package/src/tui/cellwidth.ts +148 -0
- package/src/tui/changelog-store.ts +503 -0
- package/src/tui/chord.ts +25 -0
- package/src/tui/clipboard.ts +92 -0
- package/src/tui/cmdbar.ts +296 -0
- package/src/tui/companion.ts +1427 -0
- package/src/tui/companionplan.ts +247 -0
- package/src/tui/companiontab.ts +83 -0
- package/src/tui/confighome.ts +155 -0
- package/src/tui/connect.ts +68 -0
- package/src/tui/deploy-ceremony.ts +104 -0
- package/src/tui/deploy-drain.ts +129 -0
- package/src/tui/deploy-process.ts +265 -0
- package/src/tui/deploytab.ts +1523 -0
- package/src/tui/design.ts +125 -0
- package/src/tui/digesttab.ts +214 -0
- package/src/tui/emptystate.ts +39 -0
- package/src/tui/evidence.ts +999 -0
- package/src/tui/feed.ts +604 -0
- package/src/tui/feedbacktab.ts +1077 -0
- package/src/tui/filters.ts +90 -0
- package/src/tui/ghread.ts +321 -0
- package/src/tui/historypull.ts +81 -0
- package/src/tui/inboxpull.ts +236 -0
- package/src/tui/index.ts +1565 -0
- package/src/tui/issuesink.ts +238 -0
- package/src/tui/jsonfile.ts +42 -0
- package/src/tui/keys.ts +109 -0
- package/src/tui/layout.ts +108 -0
- package/src/tui/learning.ts +627 -0
- package/src/tui/lessonswitch.ts +118 -0
- package/src/tui/livecontrol.ts +228 -0
- package/src/tui/memforward.ts +443 -0
- package/src/tui/memincident.ts +363 -0
- package/src/tui/memory.ts +620 -0
- package/src/tui/memtab.ts +606 -0
- package/src/tui/metricstab.ts +1177 -0
- package/src/tui/model.ts +131 -0
- package/src/tui/mouse.ts +98 -0
- package/src/tui/msg.ts +268 -0
- package/src/tui/nativecompanion.ts +417 -0
- package/src/tui/openurl.ts +21 -0
- package/src/tui/paint.ts +511 -0
- package/src/tui/panes.ts +98 -0
- package/src/tui/pipane.ts +219 -0
- package/src/tui/poll-hooks.ts +12 -0
- package/src/tui/poll.ts +147 -0
- package/src/tui/proposals.ts +838 -0
- package/src/tui/prpause.ts +150 -0
- package/src/tui/reload.ts +436 -0
- package/src/tui/remote.ts +413 -0
- package/src/tui/rollover.ts +969 -0
- package/src/tui/scantab.ts +1290 -0
- package/src/tui/setupentry.ts +93 -0
- package/src/tui/sidebar.ts +749 -0
- package/src/tui/sshtriage.ts +510 -0
- package/src/tui/startup.ts +231 -0
- package/src/tui/tabs.ts +45 -0
- package/src/tui/termmirror.ts +224 -0
- package/src/tui/theme.ts +95 -0
- package/src/tui/ticketstab.ts +310 -0
- package/src/tui/tmuxsocket.ts +129 -0
- package/src/tui/trackertickets.ts +84 -0
- package/src/tui/unwedge.ts +286 -0
- package/src/tui/viewer.ts +575 -0
- package/src/tui/viewerinput.ts +173 -0
- package/src/updatenotice.ts +178 -0
- package/src/usage.ts +1154 -0
- package/src/verdicts.ts +4689 -0
- package/src/version.ts +80 -0
- package/src/wakes.ts +476 -0
- package/src/webhook.ts +942 -0
- package/src/webhookheal.ts +276 -0
- package/src/wire.ts +2153 -0
- package/src/worker-session-host.ts +602 -0
- package/src/workerbreaker.ts +156 -0
- package/src/workercontrol.ts +104 -0
- package/src/workerlease.ts +441 -0
- package/src/workerliveness.ts +103 -0
- package/src/workerlog.ts +79 -0
- package/src/workerruntime.ts +30 -0
- package/src/workersupervisor.ts +1538 -0
- package/src/workerusage.ts +42 -0
- package/src/workerworld.ts +427 -0
- package/src/worktrees.ts +1138 -0
- package/tests/fixtures/regression-cases.json +795 -0
- package/tests/fixtures/seed-manifest.json +19 -0
|
@@ -0,0 +1,782 @@
|
|
|
1
|
+
#!/usr/bin/env bash
|
|
2
|
+
# The release image's one entrypoint (docker/Dockerfile): mode dispatch.
|
|
3
|
+
#
|
|
4
|
+
# docker run <img> [MODE] [ARGS...]
|
|
5
|
+
#
|
|
6
|
+
# cli (default) qcr, daemonless: review, scan, version, ... ARGS go to
|
|
7
|
+
# dist/src/cli.js. A first argument that is not a mode name is a
|
|
8
|
+
# cli argument, so `docker run <img> version --json` works.
|
|
9
|
+
# daemon the always-on bot: dist/src/wire.js under a tmux server.
|
|
10
|
+
# companion the pi companion container: a tmux server, kept alive.
|
|
11
|
+
# tui the operator TUI (dist/src/cli.js tui).
|
|
12
|
+
# login pi's own /login, typed for the user (scanbox loginInPi).
|
|
13
|
+
# mint a GitHub App installation token on stdout (scripts/mint-token.sh).
|
|
14
|
+
# install the host wrapper, pinned to this image (scripts/install-wrapper.sh):
|
|
15
|
+
# `-v ~/.local/bin:/out` writes /out/qcr, otherwise `| sh` installs it.
|
|
16
|
+
# worker the per-round bot worker.
|
|
17
|
+
#
|
|
18
|
+
# `install where|migrate` and `companion up|down|status|rebuild` are qcr verbs
|
|
19
|
+
# that share a mode's name: with arguments they go to the cli.
|
|
20
|
+
#
|
|
21
|
+
# What every mode does before it hands over:
|
|
22
|
+
# - asserts config.toml [pi] version == the installed pi package's version,
|
|
23
|
+
# and refuses to start otherwise (the pin lives in four places; this is the
|
|
24
|
+
# one that sees the running image);
|
|
25
|
+
# - makes <root>/state writable-or-fatal (the MutationGate's state/dryrun
|
|
26
|
+
# and every other state file live there).
|
|
27
|
+
# No npm build, no state symlink: the image is built, /opt/qcr is read-only to
|
|
28
|
+
# every runtime uid, and <root>/state is a world-writable mount point.
|
|
29
|
+
#
|
|
30
|
+
# bash-guard (extensions/cli/bash-guard.ts) is no longer registered in pi's global
|
|
31
|
+
# settings: every lens and worker session gets it from the factory, and
|
|
32
|
+
# the takeover and debug pi load it by path. The per-call cli mode runs in a
|
|
33
|
+
# throwaway container that is the sandbox, and puts the model's
|
|
34
|
+
# tools under another uid, so the kernel keeps them off the
|
|
35
|
+
# token-holding Node process (/proc/<pid>/mem and environ):
|
|
36
|
+
# - started as root (--user 0:0 --cap-drop ALL --cap-add SETUID --cap-add
|
|
37
|
+
# SETGID), the cli mode re-executes this script as QCR_RUN_UID:QCR_RUN_GID
|
|
38
|
+
# (default 1000:1000) with CAP_SETUID/CAP_SETGID as ambient capabilities,
|
|
39
|
+
# and exports QCR_TOOL_UID/QCR_TOOL_GID (QCR_TOOLS_AS, default 65534, and the run gid);
|
|
40
|
+
# - the engine then runs everything that executes the model's commands
|
|
41
|
+
# through setpriv (packages/pi-plugin/src/engine/tooluid.ts): the SDK session's bash tool
|
|
42
|
+
# (packages/pi-plugin/src/engine/pisdk.ts), a pi child (toolIsolation), a debug round's
|
|
43
|
+
# interactive pi (src/engine/debugpi.ts). They get the tool uid, no
|
|
44
|
+
# capabilities and no_new_privs. The SDK session's file tools (read, grep,
|
|
45
|
+
# find, ls, edit, write) run in the engine's own uid, so they are fenced off
|
|
46
|
+
# /proc, /run/qcr-in and the agent dir (packages/pi-plugin/src/engine/toolfence.ts). The tool
|
|
47
|
+
# uid shares the run gid, which is how it reaches the group-writable state;
|
|
48
|
+
# it is a different uid, so /proc/<node pid>/mem and environ are closed to it;
|
|
49
|
+
# - started as any other uid, no separation is possible: the cli mode says
|
|
50
|
+
# so, exports QCR_TOOL_UID_REQUIRED=1, and the engine then refuses to
|
|
51
|
+
# run the model's tools unless QCR_ALLOW_SHARED_TOOL_UID=1 (version, doctor
|
|
52
|
+
# and every other verb that runs none are unaffected).
|
|
53
|
+
# The daemon mode (the always-on bot) makes the same split from a
|
|
54
|
+
# NON-root start, so `docker exec` into the bot keeps landing as its uid: the
|
|
55
|
+
# image's setid helper (/usr/local/libexec/qcr/qcr-setid, file capabilities, gate
|
|
56
|
+
# group QCR_SETID_GID) is probed, and the daemon exports QCR_TOOL_UID (QCR_TOOLS_AS,
|
|
57
|
+
# default 65534), QCR_TOOL_GID (the image's compiled tool gid, QCR_IMAGE_TOOL_GID; the
|
|
58
|
+
# daemon must already be a member of it) and QCR_SETPRIV_BIN; its workers run
|
|
59
|
+
# every model command through the helper (packages/pi-plugin/src/engine/tooluid.ts setidHelperOf).
|
|
60
|
+
# A probe that fails refuses the start (QCR_ALLOW_SHARED_TOOL_UID=1 accepts the
|
|
61
|
+
# shared uid). Started as root instead, the daemon drops to QCR_RUN_UID the way
|
|
62
|
+
# the cli mode does. Either way the daemon opens the directories the model's
|
|
63
|
+
# scripts write to its group (share_tool_dirs) and nothing else: the secrets
|
|
64
|
+
# mount and pi's login stay unreadable to the tool uid.
|
|
65
|
+
# The login and tui modes run no engine and hold no GitHub token: they are
|
|
66
|
+
# not separated. pi holds its own OAuth token as the tools' uid, which no
|
|
67
|
+
# split hides from the tools it runs; the split protects the GitHub token.
|
|
68
|
+
#
|
|
69
|
+
# The login volume outlives every uid. `login` runs as the caller and
|
|
70
|
+
# leaves every entry of pi's agent dir in the fixed login group (QCR_LOGIN_GID,
|
|
71
|
+
# default 4747) at 0660/2770 when pi exits; the wrapper gives every call that
|
|
72
|
+
# mounts the volume that group (--group-add), and the cli mode keeps it across
|
|
73
|
+
# its uid drop (setpriv --groups). A review under another uid reads the login
|
|
74
|
+
# through the group; the model's tools, which clear their groups, do not; and
|
|
75
|
+
# a later login under yet another uid can still rewrite it.
|
|
76
|
+
#
|
|
77
|
+
# The daemon is the live bot and keeps the guard, the pinned-CLI check and the
|
|
78
|
+
# reviewer context stub it has always had (the VM's retired
|
|
79
|
+
# deploy/ansible/templates/entrypoint.sh.j2).
|
|
80
|
+
# The VM runs this image since the cutover: deploy/ansible/playbook.yml.
|
|
81
|
+
#
|
|
82
|
+
# Every mode that reaches pi needs a writable <root>/state and a writable HOME
|
|
83
|
+
# (pi settings are merged under ~/.pi on every cli start, `version` included):
|
|
84
|
+
# a read-only rootfs without a state mount and a writable HOME is refused here.
|
|
85
|
+
#
|
|
86
|
+
# Every line this script prints goes to stderr: a cli mode's stdout is the
|
|
87
|
+
# command's (--json), never ours.
|
|
88
|
+
set -euo pipefail
|
|
89
|
+
|
|
90
|
+
APP="${QCR_APP_ROOT:-$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)}"
|
|
91
|
+
STATE="$APP/state"
|
|
92
|
+
|
|
93
|
+
say() { echo "qcr-entrypoint: $*" >&2; }
|
|
94
|
+
die() {
|
|
95
|
+
echo "qcr-entrypoint: FATAL: $*" >&2
|
|
96
|
+
exit 1
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
# ---- mode ---------------------------------------------------------------------
|
|
100
|
+
|
|
101
|
+
# The group that owns the login volume's files (see the header).
|
|
102
|
+
LOGIN_GID="${QCR_LOGIN_GID:-4747}"
|
|
103
|
+
[[ "$LOGIN_GID" =~ ^[1-9][0-9]*$ ]] || die "QCR_LOGIN_GID must be a non-zero numeric group id ($LOGIN_GID)"
|
|
104
|
+
|
|
105
|
+
mode=cli
|
|
106
|
+
if [ "$#" -gt 0 ]; then
|
|
107
|
+
case "$1" in
|
|
108
|
+
install | mint | cli | daemon | worker | tui | companion | login)
|
|
109
|
+
mode="$1"
|
|
110
|
+
shift
|
|
111
|
+
;;
|
|
112
|
+
esac
|
|
113
|
+
fi
|
|
114
|
+
case "$mode" in
|
|
115
|
+
install | companion)
|
|
116
|
+
if [ "$#" -gt 0 ]; then
|
|
117
|
+
set -- "$mode" "$@"
|
|
118
|
+
mode=cli
|
|
119
|
+
fi
|
|
120
|
+
;;
|
|
121
|
+
esac
|
|
122
|
+
|
|
123
|
+
# ---- the model's tools run as another uid ---------------------------------
|
|
124
|
+
|
|
125
|
+
# The cli mode and the daemon mode run the engine (`daemon --preflight` reads
|
|
126
|
+
# mounts and runs none). See the header for the contract; the host wrapper
|
|
127
|
+
# owns the docker flags that make the cli's root start possible, and the
|
|
128
|
+
# VM's updater (deploy/qcr-update.sh) the daemon's.
|
|
129
|
+
isolate_tools() {
|
|
130
|
+
case "$mode" in
|
|
131
|
+
cli) ;;
|
|
132
|
+
daemon) [ "${1:-}" != --preflight ] || return 0 ;;
|
|
133
|
+
*) return 0 ;;
|
|
134
|
+
esac
|
|
135
|
+
if [ -n "${QCR_TOOLS_ISOLATED:-}" ]; then
|
|
136
|
+
# Second pass, already the run uid. Group-writable files are how the tool
|
|
137
|
+
# uid (same gid, different uid) shares state and pi's home with this one.
|
|
138
|
+
# The daemon keeps its umask: its workers set the group-writable one for
|
|
139
|
+
# what the model's tools share (src/botworker.ts), and what the daemon
|
|
140
|
+
# writes for a session to read stays its own.
|
|
141
|
+
[ "$mode" != cli ] || umask 002
|
|
142
|
+
return 0
|
|
143
|
+
fi
|
|
144
|
+
# Whatever the caller exported, only a split made here counts.
|
|
145
|
+
unset QCR_TOOL_UID QCR_TOOL_GID QCR_SETPRIV_BIN
|
|
146
|
+
if [ "$(id -u)" != 0 ]; then
|
|
147
|
+
if [ "$mode" = daemon ]; then
|
|
148
|
+
daemon_setid_helper
|
|
149
|
+
return 0
|
|
150
|
+
fi
|
|
151
|
+
export QCR_TOOL_UID_REQUIRED=1
|
|
152
|
+
return 0
|
|
153
|
+
fi
|
|
154
|
+
local run_uid="${QCR_RUN_UID:-1000}" run_gid="${QCR_RUN_GID:-1000}" tool_uid="${QCR_TOOLS_AS:-65534}"
|
|
155
|
+
[[ "$run_uid$run_gid$tool_uid" =~ ^[0-9]+$ && "$run_uid" != 0 && "$run_gid" != 0 && "$tool_uid" != 0 ]] ||
|
|
156
|
+
die "QCR_RUN_UID/QCR_RUN_GID/QCR_TOOLS_AS must be non-zero numeric ids"
|
|
157
|
+
[ "$run_uid" != "$tool_uid" ] || die "the tool uid must differ from the run uid ($run_uid)"
|
|
158
|
+
command -v setpriv >/dev/null || die "setpriv (util-linux) is needed for the tool uid split"
|
|
159
|
+
export QCR_TOOLS_ISOLATED=1 QCR_TOOL_UID="$tool_uid" QCR_TOOL_GID="$run_gid"
|
|
160
|
+
# The cli keeps the login group (the login volume); the daemon runs as a
|
|
161
|
+
# plain uid, as it does when docker starts it as one.
|
|
162
|
+
local groups="--groups=$LOGIN_GID"
|
|
163
|
+
[ "$mode" = cli ] || groups="--clear-groups"
|
|
164
|
+
exec setpriv --reuid="$run_uid" --regid="$run_gid" "$groups" \
|
|
165
|
+
--inh-caps=+setuid,+setgid --ambient-caps=+setuid,+setgid \
|
|
166
|
+
-- "${BASH_SOURCE[0]}" "$mode" "$@"
|
|
167
|
+
}
|
|
168
|
+
|
|
169
|
+
# The always-on bot. It runs as its own uid, not root, so every
|
|
170
|
+
# `docker exec` into it (the TUI's reads and messages, `tmux` for a takeover's
|
|
171
|
+
# pane, `qcr` in the container) keeps landing as that uid, and docker cannot
|
|
172
|
+
# give a non-root uid ambient capabilities. Its way to the tool uid is the
|
|
173
|
+
# image's setid helper (docker/Dockerfile): a copy of setpriv carrying
|
|
174
|
+
# CAP_SETUID/CAP_SETGID as file capabilities, runnable only by the gate group
|
|
175
|
+
# (QCR_SETID_GID, 4748), which the run spec gives the bot with --group-add. The
|
|
176
|
+
# model's tools run with no_new_privs and without that group, so the helper is
|
|
177
|
+
# nothing to them. The probe below proves the helper works here (it switches to
|
|
178
|
+
# the tool uid and runs `true`); where it does not, the bot refuses to start
|
|
179
|
+
# rather than run the model's tools in the uid that reads secrets/, unless
|
|
180
|
+
# QCR_ALLOW_SHARED_TOOL_UID=1 accepts that.
|
|
181
|
+
SETID_HELPER="${QCR_SETID_HELPER:-/usr/local/libexec/qcr/qcr-setid}"
|
|
182
|
+
daemon_setid_helper() {
|
|
183
|
+
local tool_uid="${QCR_TOOLS_AS:-${QCR_IMAGE_TOOL_UID:-65534}}" tool_gid="${QCR_IMAGE_TOOL_GID:-}" uid
|
|
184
|
+
uid="$(id -u)"
|
|
185
|
+
[[ "$tool_uid" =~ ^[1-9][0-9]*$ ]] || die "QCR_TOOLS_AS must be a non-zero numeric id ($tool_uid)"
|
|
186
|
+
[ "$tool_uid" != "$uid" ] || die "the tool uid must differ from the daemon's uid ($uid)"
|
|
187
|
+
if [[ "$tool_gid" =~ ^[1-9][0-9]*$ ]] && [ -x "$SETID_HELPER" ] &&
|
|
188
|
+
"$SETID_HELPER" --reuid="$tool_uid" --regid="$tool_gid" --clear-groups \
|
|
189
|
+
--inh-caps=-all --ambient-caps=-all --no-new-privs -- true 2>/dev/null; then
|
|
190
|
+
# The daemon shares the directories the model's scripts write through the
|
|
191
|
+
# tool's own group, so it must be a member of it (the run spec's second
|
|
192
|
+
# --group-add); a daemon outside it could not read what the tools write.
|
|
193
|
+
id -G | tr ' ' '\n' | grep -qx "$tool_gid" ||
|
|
194
|
+
die "the daemon (uid $uid) is not in the tool gid $tool_gid: start it with --group-add $tool_gid (re-run provision)"
|
|
195
|
+
export QCR_TOOL_UID="$tool_uid" QCR_TOOL_GID="$tool_gid" QCR_SETPRIV_BIN="$SETID_HELPER"
|
|
196
|
+
say "the model's tools run as uid $tool_uid gid $tool_gid through $SETID_HELPER; the daemon keeps uid $uid"
|
|
197
|
+
return 0
|
|
198
|
+
fi
|
|
199
|
+
if [ "${QCR_ALLOW_SHARED_TOOL_UID-}" = 1 ]; then
|
|
200
|
+
say "WARNING: the model's tools run as the daemon's own uid $uid, which reads the secrets mount (QCR_ALLOW_SHARED_TOOL_UID is 1)"
|
|
201
|
+
return 0
|
|
202
|
+
fi
|
|
203
|
+
die "the model's tools cannot run as another uid: $SETID_HELPER is not runnable by uid $uid or cannot switch to $tool_uid:${tool_gid:-?} here (it switches to the image's tool identity only). Start the bot with --group-add ${QCR_SETID_GID:-4748} (the helper's gate group) and without no-new-privileges, or as root (--user 0:0 --cap-drop ALL --cap-add SETUID --cap-add SETGID -e QCR_RUN_UID -e QCR_RUN_GID); setting QCR_ALLOW_SHARED_TOOL_UID to 1 accepts the shared uid"
|
|
204
|
+
}
|
|
205
|
+
|
|
206
|
+
# What the model's tools write through the sanctioned scripts, as the tool uid:
|
|
207
|
+
# the round's rendered review (render-review.sh, state/), a findings record, the
|
|
208
|
+
# verdicts (commit-verdict.sh), the ledgers a debug round's pi pins, the
|
|
209
|
+
# session commands. Those directories, and only those, are handed to the tool's
|
|
210
|
+
# own gid, setgid so every entry made in them stays in that group (the daemon
|
|
211
|
+
# reads what the tools write, the tools what the daemon leaves there for them).
|
|
212
|
+
# state/ and commands/ are also sticky: the tool uid may add entries but never
|
|
213
|
+
# rename or remove one it does not own (state.db, the IPC run dir, the built
|
|
214
|
+
# agents, status.json, the root-owned commands/operator seal). verdict/ is not:
|
|
215
|
+
# commit-verdict.sh, run as the tool uid, publishes by renaming the file the
|
|
216
|
+
# session's own write tool staged as the daemon's uid. The rest of the tree,
|
|
217
|
+
# secrets/ and pi's login stay out of the tool's group.
|
|
218
|
+
share_tool_dirs() {
|
|
219
|
+
[ -n "${QCR_TOOL_UID:-}" ] || return 0
|
|
220
|
+
local d gid="${QCR_TOOL_GID}"
|
|
221
|
+
for d in "$STATE" "$STATE/findings" "$STATE/ledgers" "$APP/verdict" "$APP/commands"; do
|
|
222
|
+
{ mkdir -p "$d" && chgrp "$gid" "$d" && chmod g+rwxs "$d"; } 2>/dev/null ||
|
|
223
|
+
say "WARNING: $d could not be opened to the tool gid $gid: the model's scripts cannot write there"
|
|
224
|
+
done
|
|
225
|
+
for d in "$STATE" "$APP/commands"; do
|
|
226
|
+
chmod +t "$d" 2>/dev/null || say "WARNING: $d could not be made sticky: the tool uid could rename the daemon's entries in it"
|
|
227
|
+
done
|
|
228
|
+
}
|
|
229
|
+
|
|
230
|
+
isolate_tools "$@"
|
|
231
|
+
|
|
232
|
+
# ---- the token handoff ------------------------------------------------------
|
|
233
|
+
|
|
234
|
+
# A GitHub token is never env or argv in this image. The caller bind-mounts a
|
|
235
|
+
# 0700 dir at /run/qcr-in holding a 0600 file and names it in QCR_GH_TOKEN_FILE;
|
|
236
|
+
# packages/pi-plugin/src/ghcred.ts reads and unlinks it as the first thing cli.js does, before any
|
|
237
|
+
# pi or bash child exists, and drops the variable. This script never reads it.
|
|
238
|
+
# What keeps the model's bash off the Node process that then holds the token:
|
|
239
|
+
# - the tools' uid (above) where the split is possible;
|
|
240
|
+
# - Yama kernel.yama.ptrace_scope >= 1, under which a child cannot ptrace-attach
|
|
241
|
+
# to its ancestor (host-wide: 1 on the owner's PC, unknown on Docker Desktop
|
|
242
|
+
# VMs and GitHub runners);
|
|
243
|
+
# - bash-guard's /proc environ/mem/cmdline deny and its program allowlist,
|
|
244
|
+
# where the guard runs.
|
|
245
|
+
# --cap-drop ALL and no-new-privileges are hardening, not that block: same-uid
|
|
246
|
+
# access to /proc/<ppid>/mem needs no CAP_SYS_PTRACE. So the value is recorded
|
|
247
|
+
# at start (QCR_DEBUG=1), for the CI smoke and the macOS checklist to compare.
|
|
248
|
+
debug_ptrace_scope() {
|
|
249
|
+
[ "${QCR_DEBUG:-}" = 1 ] || return 0
|
|
250
|
+
say "debug: kernel.yama.ptrace_scope=$(cat /proc/sys/kernel/yama/ptrace_scope 2>/dev/null || echo absent)"
|
|
251
|
+
}
|
|
252
|
+
|
|
253
|
+
# ---- the pi pin ----------------------------------------------------------------
|
|
254
|
+
|
|
255
|
+
# shellcheck source=../scripts/install-locator.sh
|
|
256
|
+
. "$APP/scripts/install-locator.sh"
|
|
257
|
+
|
|
258
|
+
# A key of the [pi] table of a config file, unquoted; nothing when absent.
|
|
259
|
+
toml_pi() { # toml_pi <file> <key>
|
|
260
|
+
awk -v key="$2" '
|
|
261
|
+
/^\[/ { in_pi = ($0 ~ /^\[pi\][[:space:]]*(#.*)?$/); next }
|
|
262
|
+
in_pi && $0 ~ "^[[:space:]]*" key "[[:space:]]*=" {
|
|
263
|
+
sub(/^[^=]*=[[:space:]]*/, ""); sub(/[[:space:]]*#.*$/, ""); gsub(/"/, ""); print; exit
|
|
264
|
+
}
|
|
265
|
+
' "$1"
|
|
266
|
+
}
|
|
267
|
+
|
|
268
|
+
# The version of a pi package directory, or nothing.
|
|
269
|
+
pkg_version() { # pkg_version <package dir>
|
|
270
|
+
[ -f "$1/package.json" ] || return 0
|
|
271
|
+
node -p 'require(process.argv[1]).version' "$1/package.json" 2>/dev/null || true
|
|
272
|
+
}
|
|
273
|
+
|
|
274
|
+
# The config the pin is read from: the install locator's (the daemon's own
|
|
275
|
+
# config, and the one every session is handed), else the example the image
|
|
276
|
+
# bakes, whose pin the build checked. A daemon never falls back: a missing
|
|
277
|
+
# config is a mount that was not made, and the boot names it.
|
|
278
|
+
PI_VERSION_PINNED=""
|
|
279
|
+
PI_PACKAGE_PINNED=""
|
|
280
|
+
assert_pi_pin() {
|
|
281
|
+
local cfg ver pkg have example="$APP/config.example.toml"
|
|
282
|
+
cfg="$(qcr_locate_config "$APP")" || exit 1
|
|
283
|
+
if [ ! -f "$cfg" ]; then
|
|
284
|
+
[ "$mode" != daemon ] || die "config not found: $cfg (is the install's config home mounted?)"
|
|
285
|
+
cfg="$example"
|
|
286
|
+
fi
|
|
287
|
+
[ -f "$cfg" ] || die "config not found: $cfg"
|
|
288
|
+
ver="$(toml_pi "$cfg" version)"
|
|
289
|
+
pkg="$(toml_pi "$cfg" package)"
|
|
290
|
+
[ -n "$ver" ] || ver="$(toml_pi "$example" version 2>/dev/null || true)"
|
|
291
|
+
[ -n "$pkg" ] || pkg="$(toml_pi "$example" package 2>/dev/null || true)"
|
|
292
|
+
[ -n "$ver" ] && [ -n "$pkg" ] || die "$cfg has no [pi] package/version and neither has $example"
|
|
293
|
+
[[ "$pkg" =~ ^@?[A-Za-z0-9._-]+(/[A-Za-z0-9._-]+)?$ && "$pkg" != *..* ]] ||
|
|
294
|
+
die "$cfg [pi] package \"$pkg\" is not an npm package name"
|
|
295
|
+
have="$(pkg_version "$APP/node_modules/$pkg")"
|
|
296
|
+
[ -n "$have" ] || die "pi is not installed: no $APP/node_modules/$pkg/package.json"
|
|
297
|
+
[ "$have" = "$ver" ] ||
|
|
298
|
+
die "pi version mismatch: $cfg [pi] version is $ver but $pkg $have is installed — refusing to start (bump config.toml, package.json and the image together)"
|
|
299
|
+
PI_VERSION_PINNED="$ver"
|
|
300
|
+
PI_PACKAGE_PINNED="$pkg"
|
|
301
|
+
}
|
|
302
|
+
|
|
303
|
+
# ---- state ---------------------------------------------------------------------
|
|
304
|
+
|
|
305
|
+
assert_state_writable() {
|
|
306
|
+
{ mkdir -p "$STATE" 2>/dev/null && [ -d "$STATE" ] && [ -w "$STATE" ]; } ||
|
|
307
|
+
die "$STATE is not writable by uid $(id -u) — mount a volume there (the image ships it world-writable)"
|
|
308
|
+
}
|
|
309
|
+
|
|
310
|
+
# ---- pi settings ----------------------------------------------------------------
|
|
311
|
+
|
|
312
|
+
# Registers pi's global settings under $HOME/.pi/agent. Idempotent MERGE, safe
|
|
313
|
+
# on every boot: the file carries keys pi itself and the user wrote. Env knobs:
|
|
314
|
+
# QCR_PI_TRUST_DIR a directory pre-seeded into pi's trust store.
|
|
315
|
+
# QCR_PI_AGENTS_TARGET where $HOME/.pi/agent/agents links (the lens tool's
|
|
316
|
+
# agent discovery, <agent dir>/agents).
|
|
317
|
+
# No extension is registered globally: bash-guard rides every lens and
|
|
318
|
+
# worker session as a factory, and the takeover and debug pi load it by path.
|
|
319
|
+
# A global entry would arm every lens leaf with ambient extension work.
|
|
320
|
+
provision_pi_settings() {
|
|
321
|
+
node <<'PI_EXT_MERGE'
|
|
322
|
+
const fs = require("fs");
|
|
323
|
+
const path = require("path");
|
|
324
|
+
|
|
325
|
+
const file = path.join(process.env.HOME, ".pi", "agent", "settings.json");
|
|
326
|
+
fs.mkdirSync(path.dirname(file), { recursive: true });
|
|
327
|
+
let settings = {};
|
|
328
|
+
if (fs.existsSync(file)) settings = JSON.parse(fs.readFileSync(file, "utf8"));
|
|
329
|
+
if (!Array.isArray(settings.extensions)) settings.extensions = [];
|
|
330
|
+
|
|
331
|
+
// bash-guard is no longer a global registration. The pihome volume still
|
|
332
|
+
// carries the entry an older image merged, and a global entry would load the
|
|
333
|
+
// guard a second time beside the factory's, so it is dropped here.
|
|
334
|
+
const retiredGuard = (p) => /(^|[\\/])extensions[\\/](cli[\\/])?bash-guard\.ts$/.test(p);
|
|
335
|
+
const retired = settings.extensions.filter(retiredGuard);
|
|
336
|
+
if (retired.length) {
|
|
337
|
+
settings.extensions = settings.extensions.filter((p) => !retiredGuard(p));
|
|
338
|
+
console.log("pi extensions pruned (bash-guard is no longer global): " + retired.join(", "));
|
|
339
|
+
}
|
|
340
|
+
// settings.json lives on a PERSISTENT pihome volume on the bot, so entries
|
|
341
|
+
// written by an older image survive a rebuild. Prune anything that is not on
|
|
342
|
+
// disk. A `builtin:` override (below) names no file, so it is never "stale".
|
|
343
|
+
const isBuiltinEntry = (p) => /^[-+!]?builtin:/.test(p);
|
|
344
|
+
const stale = settings.extensions.filter((p) => !isBuiltinEntry(p) && !fs.existsSync(p));
|
|
345
|
+
if (stale.length) {
|
|
346
|
+
settings.extensions = settings.extensions.filter((p) => isBuiltinEntry(p) || fs.existsSync(p));
|
|
347
|
+
console.log("pi extensions pruned (not on disk): " + stale.join(", "));
|
|
348
|
+
}
|
|
349
|
+
// Never block on pi's interactive "Trust project folder?" modal. Belt: trust
|
|
350
|
+
// every project by default. Braces: pre-seed the trust store for the app root.
|
|
351
|
+
// Third layer: sessions.ts passes --approve on every spawn.
|
|
352
|
+
settings.defaultProjectTrust = "always";
|
|
353
|
+
// pi 1.0 made the interactive TUI fullscreen by default. Sessions run under
|
|
354
|
+
// tmux and the operator TUI mirrors and scrolls their panes, so keep the
|
|
355
|
+
// terminal's normal scrollback (pi 0.99's default) — packages/pi-plugin/src/pibuiltins.ts PI_TUI_MODE.
|
|
356
|
+
settings.tuiMode = "regular";
|
|
357
|
+
// pi 0.99's built-in extensions (mcp, codemode, tool-search, llama.cpp) are
|
|
358
|
+
// switched OFF, reasons per built-in in packages/pi-plugin/src/pibuiltins.ts, the list this
|
|
359
|
+
// mirrors. Any other global `builtin:` entry is dropped first, so this list is
|
|
360
|
+
// the only word the user settings say about built-ins.
|
|
361
|
+
const DISABLED_BUILTINS = ["-builtin:mcp", "-builtin:codemode", "-builtin:tool-search", "-builtin:llama.cpp"];
|
|
362
|
+
settings.extensions = settings.extensions.filter((p) => !isBuiltinEntry(p)).concat(DISABLED_BUILTINS);
|
|
363
|
+
|
|
364
|
+
function atomicJsonWrite(target, value) {
|
|
365
|
+
const tmp = `${target}.tmp-${process.pid}-${require("node:crypto").randomUUID()}`;
|
|
366
|
+
try {
|
|
367
|
+
const mode = fs.existsSync(target) ? fs.statSync(target).mode & 0o777 : 0o600;
|
|
368
|
+
fs.writeFileSync(tmp, JSON.stringify(value, null, 2) + "\n", { mode });
|
|
369
|
+
fs.renameSync(tmp, target);
|
|
370
|
+
} finally { fs.rmSync(tmp, { force: true }); }
|
|
371
|
+
}
|
|
372
|
+
atomicJsonWrite(file, settings);
|
|
373
|
+
console.log("pi extensions registered: " + (settings.extensions.join(", ")));
|
|
374
|
+
|
|
375
|
+
const trustDir = process.env.QCR_PI_TRUST_DIR || "";
|
|
376
|
+
if (trustDir) {
|
|
377
|
+
const trustFile = path.join(process.env.HOME, ".pi", "agent", "trust.json");
|
|
378
|
+
let trust = {};
|
|
379
|
+
if (fs.existsSync(trustFile)) trust = JSON.parse(fs.readFileSync(trustFile, "utf8"));
|
|
380
|
+
if (trust[trustDir] !== true) {
|
|
381
|
+
trust[trustDir] = true;
|
|
382
|
+
atomicJsonWrite(trustFile, trust);
|
|
383
|
+
}
|
|
384
|
+
console.log("pi project trust: defaultProjectTrust=always, " + trustDir + " pre-trusted");
|
|
385
|
+
}
|
|
386
|
+
|
|
387
|
+
// Agent discovery for the lens tool: its agent dir's `agents` is
|
|
388
|
+
// $HOME/.pi/agent/agents. Symlink-or-absent only: a REAL directory here
|
|
389
|
+
// is someone's own agents and is never clobbered — loud log instead.
|
|
390
|
+
const agentsTarget = process.env.QCR_PI_AGENTS_TARGET || "";
|
|
391
|
+
if (agentsTarget) {
|
|
392
|
+
const agentsLink = path.join(process.env.HOME, ".pi", "agent", "agents");
|
|
393
|
+
try {
|
|
394
|
+
const st = fs.lstatSync(agentsLink, { throwIfNoEntry: false });
|
|
395
|
+
if (st && !st.isSymbolicLink()) {
|
|
396
|
+
console.error("WARNING: " + agentsLink + " exists and is not a symlink — NOT touching it; lens agents will not resolve");
|
|
397
|
+
} else {
|
|
398
|
+
if (st) fs.unlinkSync(agentsLink);
|
|
399
|
+
fs.symlinkSync(agentsTarget, agentsLink);
|
|
400
|
+
console.log("pi user agents dir -> " + agentsTarget);
|
|
401
|
+
}
|
|
402
|
+
} catch (e) {
|
|
403
|
+
console.error("WARNING: could not link " + agentsLink + ": " + e.message);
|
|
404
|
+
}
|
|
405
|
+
}
|
|
406
|
+
PI_EXT_MERGE
|
|
407
|
+
}
|
|
408
|
+
|
|
409
|
+
# ---- modes -------------------------------------------------------------------
|
|
410
|
+
|
|
411
|
+
mode_daemon() {
|
|
412
|
+
# `daemon --preflight`: the updater's check on a scratch copy, run with
|
|
413
|
+
# --network none. It starts nothing (no tmux, no git config, no pi settings):
|
|
414
|
+
# it reads the mounts and prints one JSON report.
|
|
415
|
+
if [ "${1:-}" = "--preflight" ]; then
|
|
416
|
+
exec node "$APP/dist/src/preflight.js"
|
|
417
|
+
fi
|
|
418
|
+
# The key a pi OAuth /login does not provide: exported so the tmux server and
|
|
419
|
+
# every pi process inherit it.
|
|
420
|
+
local secrets="${QCR_SECRETS_MOUNT:-/opt/quickreview/secrets}"
|
|
421
|
+
export QCR_SECRETS_MOUNT="$secrets"
|
|
422
|
+
# The code resolves secrets through the install locator: an empty (or
|
|
423
|
+
# old-default) config.toml [github].secrets_dir means <config home>/secrets -
|
|
424
|
+
# point that at the secrets mount. A SET [github] secrets_dir names a host
|
|
425
|
+
# path this container cannot see: QCR_SECRETS_MOUNT answers that instead, for
|
|
426
|
+
# the daemon, every session it spawns and mint-token.sh alike.
|
|
427
|
+
local xdg="${XDG_CONFIG_HOME:-}" secrets_home
|
|
428
|
+
[[ "$xdg" == /* ]] || xdg="$HOME/.config"
|
|
429
|
+
secrets_home="$xdg/qcr/${QCR_INSTALL:-default}/secrets"
|
|
430
|
+
mkdir -p "$(dirname "$secrets_home")"
|
|
431
|
+
[[ -L "$secrets_home" ]] || ln -sfn "$secrets" "$secrets_home"
|
|
432
|
+
if [[ -r "$secrets/openai_api_key" ]]; then
|
|
433
|
+
OPENAI_API_KEY="$(<"$secrets/openai_api_key")"
|
|
434
|
+
export OPENAI_API_KEY
|
|
435
|
+
fi
|
|
436
|
+
|
|
437
|
+
share_tool_dirs
|
|
438
|
+
|
|
439
|
+
# No global extension registration (see provision_pi_settings).
|
|
440
|
+
QCR_PI_TRUST_DIR="$APP" \
|
|
441
|
+
QCR_PI_AGENTS_TARGET="$STATE/agents" \
|
|
442
|
+
provision_pi_settings >&2
|
|
443
|
+
|
|
444
|
+
# Private-repo git auth (reviewed-repo clone + per-PR fetches): the app
|
|
445
|
+
# installation token over HTTPS - never a personal credential (rule 3).
|
|
446
|
+
git config --global credential.helper \
|
|
447
|
+
"!f() { echo username=x-access-token; echo \"password=\$(\"$APP/scripts/mint-token.sh\")\"; }; f"
|
|
448
|
+
|
|
449
|
+
# Reviewer context: pi loads the FIRST of AGENTS.override.md / AGENTS.md /
|
|
450
|
+
# CLAUDE.md from the cwd into every session and every lens pass, and they all
|
|
451
|
+
# run here - so without the stub the contributor guide would ride every turn.
|
|
452
|
+
# The image bakes it 0444 in $APP (read-only to this uid); a tree that was
|
|
453
|
+
# synced instead gets it installed. Never into a repo checkout: $APP is the
|
|
454
|
+
# image's own tree.
|
|
455
|
+
local stub_src="$APP/deploy/reviewer/AGENTS.override.md" stub="$APP/AGENTS.override.md"
|
|
456
|
+
[ -f "$stub_src" ] || stub_src="$stub"
|
|
457
|
+
if [ -f "$stub_src" ] && ! { cmp -s "$stub_src" "$stub" && [ "$(stat -c %a "$stub")" = 444 ]; }; then
|
|
458
|
+
install -m 0444 "$stub_src" "$stub" ||
|
|
459
|
+
say "WARNING: reviewer context stub not installed - sessions will load the full AGENTS.md"
|
|
460
|
+
elif [ ! -f "$stub_src" ]; then
|
|
461
|
+
say "WARNING: reviewer context stub not found - sessions will load the full AGENTS.md"
|
|
462
|
+
fi
|
|
463
|
+
|
|
464
|
+
# tmux server = the jump-in surface. The csi-u lines must exist before the
|
|
465
|
+
# server starts or modified keys (Shift-Enter etc.) collapse before reaching pi.
|
|
466
|
+
[ -f "$APP/docker/vm/tmux.conf" ] || die "$APP/docker/vm/tmux.conf missing"
|
|
467
|
+
cp "$APP/docker/vm/tmux.conf" "$HOME/.tmux.conf"
|
|
468
|
+
tmux start-server
|
|
469
|
+
tmux has-session -t main 2>/dev/null || tmux new-session -d -s main
|
|
470
|
+
|
|
471
|
+
exec node "$APP/dist/src/wire.js" "$@"
|
|
472
|
+
}
|
|
473
|
+
|
|
474
|
+
# The companion's pi settings on top of the common merge: its skills, its
|
|
475
|
+
# default model, its agent set, the /workspace trust. The agent set is the
|
|
476
|
+
# image's (QCR_COMPANION_AGENTS, default $APP/docker/companion/agents): the
|
|
477
|
+
# companion runs the image's code, not the checkout's.
|
|
478
|
+
provision_companion_settings() {
|
|
479
|
+
QCR_COMPANION_AGENTS="${QCR_COMPANION_AGENTS:-$APP/docker/companion/agents}" node <<'PI_COMPANION_MERGE'
|
|
480
|
+
const fs = require("fs");
|
|
481
|
+
const path = require("path");
|
|
482
|
+
const home = process.env.HOME;
|
|
483
|
+
const file = path.join(home, ".pi", "agent", "settings.json");
|
|
484
|
+
let cfg = {};
|
|
485
|
+
try { cfg = JSON.parse(fs.readFileSync(file, "utf8")); } catch {}
|
|
486
|
+
// Skills: the vendored set and our own, each registered only when really
|
|
487
|
+
// there. An unmounted /workspace leaves the companion under-equipped, never
|
|
488
|
+
// unable to start.
|
|
489
|
+
if (!Array.isArray(cfg.skills)) cfg.skills = [];
|
|
490
|
+
const skillDirs = ["/workspace/.claude/skills", "/workspace/skills/companion"];
|
|
491
|
+
for (const d of skillDirs) {
|
|
492
|
+
if (fs.existsSync(d)) {
|
|
493
|
+
if (!cfg.skills.includes(d)) cfg.skills.push(d);
|
|
494
|
+
} else {
|
|
495
|
+
console.log("!! " + d + " is missing - its skills are not registered.");
|
|
496
|
+
}
|
|
497
|
+
}
|
|
498
|
+
// `/skill:<name>` from pi's own input line.
|
|
499
|
+
cfg.enableSkillCommands = true;
|
|
500
|
+
// The configured model ("provider/model[:thinking]") is pi's default on every start.
|
|
501
|
+
const defMatch = /^([^/:\s]+)\/([^:\s]+)(?::([a-z]+))?$/.exec(process.env.QCR_PI_DEFAULT_MODEL || "");
|
|
502
|
+
if (defMatch) {
|
|
503
|
+
cfg.defaultProvider = defMatch[1];
|
|
504
|
+
cfg.defaultModel = defMatch[2];
|
|
505
|
+
if (defMatch[3]) cfg.defaultThinkingLevel = defMatch[3];
|
|
506
|
+
}
|
|
507
|
+
fs.writeFileSync(file, JSON.stringify(cfg, null, 2) + "\n");
|
|
508
|
+
console.log("pi skills registered: " + (cfg.skills.join(", ") || "none"));
|
|
509
|
+
|
|
510
|
+
const trustFile = path.join(home, ".pi", "agent", "trust.json");
|
|
511
|
+
let trust = {};
|
|
512
|
+
try { trust = JSON.parse(fs.readFileSync(trustFile, "utf8")); } catch {}
|
|
513
|
+
if (trust["/workspace"] !== true) {
|
|
514
|
+
trust["/workspace"] = true;
|
|
515
|
+
fs.writeFileSync(trustFile, JSON.stringify(trust, null, 2) + "\n");
|
|
516
|
+
}
|
|
517
|
+
console.log("pi project trust: /workspace pre-trusted");
|
|
518
|
+
|
|
519
|
+
// Agent discovery for the lens tool (packages/pi-plugin/extensions/lens.ts reads the agents dir
|
|
520
|
+
// under pi's agent dir): link it at the companion agent set in the image.
|
|
521
|
+
// Symlink-or-absent only: a REAL directory here is someone's own agents and is
|
|
522
|
+
// never clobbered.
|
|
523
|
+
const agentsLink = path.join(home, ".pi", "agent", "agents");
|
|
524
|
+
const companionAgents = process.env.QCR_COMPANION_AGENTS;
|
|
525
|
+
try {
|
|
526
|
+
const st = fs.lstatSync(agentsLink, { throwIfNoEntry: false });
|
|
527
|
+
if (st && !st.isSymbolicLink()) {
|
|
528
|
+
console.log("!! " + agentsLink + " exists and is not a symlink - NOT touching it; the companion agent set is not discoverable");
|
|
529
|
+
} else {
|
|
530
|
+
if (st) fs.unlinkSync(agentsLink);
|
|
531
|
+
fs.symlinkSync(companionAgents, agentsLink);
|
|
532
|
+
console.log("pi user agents dir -> " + companionAgents);
|
|
533
|
+
}
|
|
534
|
+
} catch (e) {
|
|
535
|
+
console.log("!! could not link " + agentsLink + ": " + e.message);
|
|
536
|
+
}
|
|
537
|
+
PI_COMPANION_MERGE
|
|
538
|
+
}
|
|
539
|
+
|
|
540
|
+
mode_companion() {
|
|
541
|
+
local pi_home="$HOME/.pi"
|
|
542
|
+
mkdir -p "$pi_home/agent" /workspace /tracker /feed /alerts 2>/dev/null || true
|
|
543
|
+
# Full ssh to the VM (rule 8): the agent socket and the ssh config are
|
|
544
|
+
# mounted read-only; ssh needs a passwd entry for this uid to use them.
|
|
545
|
+
if [ -n "${SSH_AUTH_SOCK:-}" ]; then
|
|
546
|
+
tui_identity
|
|
547
|
+
say "ssh agent mounted at $SSH_AUTH_SOCK (the companion may reach the VM; no key is in this container)"
|
|
548
|
+
fi
|
|
549
|
+
|
|
550
|
+
# Durability guard: pi writes its OAuth token, settings and trust store under
|
|
551
|
+
# $HOME/.pi. If that is NOT the mounted volume, every one of them dies with
|
|
552
|
+
# the next recreate. Loud, never fatal. /proc/mounts, not `mountpoint`.
|
|
553
|
+
if ! awk -v d="$pi_home" '$2 == d { found = 1 } END { exit !found }' /proc/mounts 2>/dev/null; then
|
|
554
|
+
say "!! $pi_home is NOT a mount point - pi's OAuth token and settings will NOT survive a container recreate (HOME=$HOME)"
|
|
555
|
+
else
|
|
556
|
+
say "pi home on the volume: $pi_home (OAuth + conversation are durable)"
|
|
557
|
+
fi
|
|
558
|
+
|
|
559
|
+
if [ -d /reviewed-repo ] && [ -n "$(ls -A /reviewed-repo 2>/dev/null)" ]; then
|
|
560
|
+
say "reviewed repo mounted READ-ONLY at /reviewed-repo"
|
|
561
|
+
else
|
|
562
|
+
say "!! /reviewed-repo is not mounted - no reviewed-repo source to read."
|
|
563
|
+
fi
|
|
564
|
+
if [ -d /evidence ]; then
|
|
565
|
+
say "round evidence mounted READ-ONLY at /evidence ($(ls -1 /evidence 2>/dev/null | wc -l) PR dirs)"
|
|
566
|
+
else
|
|
567
|
+
say "!! /evidence is not mounted - no finished-round transcripts to read."
|
|
568
|
+
fi
|
|
569
|
+
if [ -s /github-read/github-read.env ]; then
|
|
570
|
+
say "read-only GitHub token file at /github-read/github-read.env"
|
|
571
|
+
else
|
|
572
|
+
say "!! no read-only GitHub token yet - GitHub reads unavailable until the TUI mints one."
|
|
573
|
+
fi
|
|
574
|
+
|
|
575
|
+
# The companion registers no global extension (companion-guard and the lens
|
|
576
|
+
# tool ride per-spawn argv); the common merge and the companion's own keys.
|
|
577
|
+
[ -f "$APP/docker/vm/tmux.conf" ] || die "$APP/docker/vm/tmux.conf missing"
|
|
578
|
+
cp "$APP/docker/vm/tmux.conf" "$HOME/.tmux.conf"
|
|
579
|
+
provision_pi_settings >&2
|
|
580
|
+
provision_companion_settings >&2
|
|
581
|
+
|
|
582
|
+
# The companion commits its own work to the mounted repo; git refuses without
|
|
583
|
+
# an identity. `|| true`: an unusable git identity degrades committing, it
|
|
584
|
+
# must never stop the companion from starting.
|
|
585
|
+
git config --global user.name "QCR Companion" || true
|
|
586
|
+
git config --global user.email "companion@quickchat.ai" || true
|
|
587
|
+
git config --global --add safe.directory /workspace || true
|
|
588
|
+
|
|
589
|
+
# Memory health watcher: backgrounded and non-fatal by construction.
|
|
590
|
+
local watcher="$APP/docker/companion/memory-health.mjs"
|
|
591
|
+
[ -f "$watcher" ] || watcher=/usr/local/lib/qcr/memory-health.mjs
|
|
592
|
+
if [ -n "${QCR_MEMORY_ENDPOINT:-}${OPENVIKING_URL:-}${OPENVIKING_BASE_URL:-}" ] && [ -f "$watcher" ]; then
|
|
593
|
+
node "$watcher" &
|
|
594
|
+
else
|
|
595
|
+
say "memory watcher idle: no OpenViking endpoint configured for this container"
|
|
596
|
+
fi
|
|
597
|
+
|
|
598
|
+
# Stay alive, and DIE PROMPTLY when asked: PID 1 has no default signal
|
|
599
|
+
# dispositions, so without a trap `docker stop` waits its full timeout. The
|
|
600
|
+
# trap goes in before anything is started, and `child` is set up front: a
|
|
601
|
+
# TERM landing before `sleep` is forked would otherwise hit an unbound
|
|
602
|
+
# variable under `set -u` and exit 1.
|
|
603
|
+
# `sleep &` + `wait`, because a foreground child would block the trap.
|
|
604
|
+
local child=""
|
|
605
|
+
term() {
|
|
606
|
+
[ -z "$child" ] || kill "$child" 2>/dev/null || true
|
|
607
|
+
exit 0
|
|
608
|
+
}
|
|
609
|
+
trap term TERM INT
|
|
610
|
+
|
|
611
|
+
if [ -n "${QCR_TMUX_SOCKET:-}" ]; then
|
|
612
|
+
# The server listens on a socket in the volume the containerised TUI
|
|
613
|
+
# shares (`tmux -S`), and stays up with no session so the TUI can find it
|
|
614
|
+
# before pi is spawned. A socket left by an earlier run is stale.
|
|
615
|
+
mkdir -p "$(dirname "$QCR_TMUX_SOCKET")" 2>/dev/null || true
|
|
616
|
+
rm -f "$QCR_TMUX_SOCKET"
|
|
617
|
+
tmux -S "$QCR_TMUX_SOCKET" start-server \; set -s exit-empty off
|
|
618
|
+
else
|
|
619
|
+
tmux start-server
|
|
620
|
+
fi
|
|
621
|
+
|
|
622
|
+
sleep infinity &
|
|
623
|
+
child=$!
|
|
624
|
+
# `|| true`: a signal makes `wait` return 128+N, which under `set -e` would
|
|
625
|
+
# end the script before the trap's own `exit 0`.
|
|
626
|
+
wait "$child" || true
|
|
627
|
+
exit 0
|
|
628
|
+
}
|
|
629
|
+
|
|
630
|
+
mode_login() {
|
|
631
|
+
# pi itself with `/login` typed and sent for the user: the one script
|
|
632
|
+
# scanbox.ts `loginInPi` builds (it validates the provider name too), run on
|
|
633
|
+
# the image's one pi, node_modules/.bin/pi (there is no pi on the PATH).
|
|
634
|
+
local script
|
|
635
|
+
script="$(node --input-type=module -e '
|
|
636
|
+
const { loginInPi } = await import(process.argv[1] + "/dist/src/scanbox.js");
|
|
637
|
+
process.stdout.write(loginInPi(process.argv[2] || undefined, process.argv[1] + "/node_modules/.bin/pi")[2]);
|
|
638
|
+
' "$APP" "${1:-}")" || die "login: could not build the pi login command"
|
|
639
|
+
# The bot's login has ONE refresher (src/loginrefresh/); when this
|
|
640
|
+
# container runs it, it stands down for the login and takes over again after.
|
|
641
|
+
login_handover_begin
|
|
642
|
+
# Not exec: the login is shared with the login group once pi has written it,
|
|
643
|
+
# however the session ended, and the refresher is released after that.
|
|
644
|
+
local rc=0
|
|
645
|
+
sh -c "$script" || rc=$?
|
|
646
|
+
share_login
|
|
647
|
+
login_handover_end
|
|
648
|
+
exit "$rc"
|
|
649
|
+
}
|
|
650
|
+
|
|
651
|
+
# The handover between pi's /login and the bot container's login refresher
|
|
652
|
+
#. The refresher holds an exclusive flock on <agent>/auth.json.lock for
|
|
653
|
+
# its whole life: when that lock is held, a refresher is running, and a login
|
|
654
|
+
# rewriting auth.json beside it would race its refresh. So the login asks it to
|
|
655
|
+
# pause - writes <agent>/auth.json.pause - and waits for `"paused": true` in
|
|
656
|
+
# its status file. A paused refresher neither refreshes nor writes, but KEEPS
|
|
657
|
+
# the lock, so no second refresher can start during the login. login_handover_end
|
|
658
|
+
# removes the pause file and the refresher re-reads the new login and resumes (a
|
|
659
|
+
# pause file left behind is lifted by the refresher after 15 minutes). Where
|
|
660
|
+
# nobody holds the lock (a laptop, the companion) nothing is done.
|
|
661
|
+
LOGIN_PAUSE_FILE=""
|
|
662
|
+
login_agent_dir() { printf '%s\n' "${PI_CODING_AGENT_DIR:-$HOME/.pi/agent}"; }
|
|
663
|
+
|
|
664
|
+
login_handover_begin() {
|
|
665
|
+
local dir lock status rc=0 waited=0 max
|
|
666
|
+
dir="$(login_agent_dir)"
|
|
667
|
+
lock="$dir/auth.json.lock"
|
|
668
|
+
status="$dir/loginrefresh.status.json"
|
|
669
|
+
[ -e "$lock" ] || return 0
|
|
670
|
+
if ! command -v flock >/dev/null 2>&1; then
|
|
671
|
+
say "WARNING: flock is not installed - cannot tell whether a login refresher holds $lock"
|
|
672
|
+
return 0
|
|
673
|
+
fi
|
|
674
|
+
flock -n -E 75 "$lock" true 2>/dev/null || rc=$?
|
|
675
|
+
[ "$rc" -eq 75 ] || return 0
|
|
676
|
+
LOGIN_PAUSE_FILE="$dir/auth.json.pause"
|
|
677
|
+
trap 'rm -f "$LOGIN_PAUSE_FILE"' EXIT
|
|
678
|
+
say "login: the bot's login refresher holds $lock - asking it to pause while you log in"
|
|
679
|
+
(umask 007 && : >"$LOGIN_PAUSE_FILE") || die "login: cannot write $LOGIN_PAUSE_FILE"
|
|
680
|
+
chgrp "$LOGIN_GID" "$LOGIN_PAUSE_FILE" 2>/dev/null || true
|
|
681
|
+
max="${QCR_LOGIN_PAUSE_WAIT_S:-60}"
|
|
682
|
+
# Half-second polls: the refresher looks at the pause file every 2 s.
|
|
683
|
+
while ! grep -q '"paused": true' "$status" 2>/dev/null; do
|
|
684
|
+
if [ "$waited" -ge $((max * 2)) ]; then
|
|
685
|
+
die "login: the refresher did not pause within ${max}s ($status) - is the daemon running?"
|
|
686
|
+
fi
|
|
687
|
+
sleep 0.5
|
|
688
|
+
waited=$((waited + 1))
|
|
689
|
+
done
|
|
690
|
+
say "login: the refresher is paused (it keeps the lock) - /login is yours"
|
|
691
|
+
}
|
|
692
|
+
|
|
693
|
+
login_handover_end() {
|
|
694
|
+
[ -n "$LOGIN_PAUSE_FILE" ] || return 0
|
|
695
|
+
rm -f "$LOGIN_PAUSE_FILE"
|
|
696
|
+
LOGIN_PAUSE_FILE=""
|
|
697
|
+
say "login: released - the refresher re-reads the login and resumes"
|
|
698
|
+
}
|
|
699
|
+
|
|
700
|
+
# Leave pi's agent dir (the login volume) readable by a later run under any
|
|
701
|
+
# uid, and writable by a later login under any uid: the login group, files
|
|
702
|
+
# 0660, directories 2770. Best effort per entry - what another uid wrote in an
|
|
703
|
+
# earlier login was shared by that login already, and this uid may not own it.
|
|
704
|
+
share_login() {
|
|
705
|
+
local dir="$HOME/.pi/agent"
|
|
706
|
+
[ -d "$dir" ] || return 0
|
|
707
|
+
find "$dir" -mindepth 1 ! -group "$LOGIN_GID" -exec chgrp -h "$LOGIN_GID" {} + 2>/dev/null || true
|
|
708
|
+
find "$dir" -mindepth 1 -type d -exec chmod 2770 {} + 2>/dev/null || true
|
|
709
|
+
find "$dir" -mindepth 1 -type f -exec chmod 0660 {} + 2>/dev/null || true
|
|
710
|
+
}
|
|
711
|
+
|
|
712
|
+
# ssh will not run for a uid the image has no passwd entry for, and the tui and
|
|
713
|
+
# companion modes run as the caller's own uid. When the entry is missing,
|
|
714
|
+
# nss_wrapper answers the lookup with one (its HOME is this HOME, where
|
|
715
|
+
# ~/.ssh/config and known_hosts are mounted). Needed by the TUI's ssh runner
|
|
716
|
+
# (src/tui/remote.ts) and by the companion's ssh to the VM (rule 8); a missing
|
|
717
|
+
# library is said, never fatal.
|
|
718
|
+
tui_identity() {
|
|
719
|
+
local entry lib dir="$HOME/.qcr-nss"
|
|
720
|
+
# ssh reads ~/.ssh from the passwd entry's home, never from $HOME. An entry
|
|
721
|
+
# whose home IS this HOME needs nothing; a missing one, or the base image's
|
|
722
|
+
# own user at this uid (uid 1000 is node, home /home/node), is answered with
|
|
723
|
+
# one whose home is this HOME.
|
|
724
|
+
entry="$(getent passwd "$(id -u)" 2>/dev/null || true)"
|
|
725
|
+
[ -n "$entry" ] && [ "$(printf '%s' "$entry" | cut -d: -f6)" = "$HOME" ] && return 0
|
|
726
|
+
lib="${QCR_NSS_WRAPPER_LIB:-$(find /usr/lib /lib -name 'libnss_wrapper.so*' 2>/dev/null | head -n 1)}"
|
|
727
|
+
if [ ! -f "$lib" ] || ! mkdir -p "$dir" 2>/dev/null; then
|
|
728
|
+
say "WARNING: uid $(id -u) has no passwd entry at $HOME and nss_wrapper is not usable - ssh will not read the mounted ssh config"
|
|
729
|
+
return 0
|
|
730
|
+
fi
|
|
731
|
+
{ awk -F: -v u="$(id -u)" '$3 != u' /etc/passwd; printf 'qcr:x:%s:%s:qcr:%s:/bin/sh\n' "$(id -u)" "$(id -g)" "$HOME"; } >"$dir/passwd"
|
|
732
|
+
{ cat /etc/group; printf 'qcr:x:%s:\n' "$(id -g)"; } >"$dir/group"
|
|
733
|
+
export LD_PRELOAD="$lib" NSS_WRAPPER_PASSWD="$dir/passwd" NSS_WRAPPER_GROUP="$dir/group"
|
|
734
|
+
}
|
|
735
|
+
|
|
736
|
+
# ---- dispatch -----------------------------------------------------------------
|
|
737
|
+
|
|
738
|
+
assert_pi_pin
|
|
739
|
+
|
|
740
|
+
case "$mode" in
|
|
741
|
+
install)
|
|
742
|
+
# Stdout is the wrapper's (or the installer `| sh` runs) and nothing else.
|
|
743
|
+
exec "$APP/scripts/install-wrapper.sh"
|
|
744
|
+
;;
|
|
745
|
+
worker)
|
|
746
|
+
say "worker: the per-round bot worker is not shipped in this image yet"
|
|
747
|
+
exit 64
|
|
748
|
+
;;
|
|
749
|
+
esac
|
|
750
|
+
|
|
751
|
+
case "$mode" in
|
|
752
|
+
mint)
|
|
753
|
+
# An installation token on stdout and nothing else; touches no state.
|
|
754
|
+
exec "$APP/scripts/mint-token.sh" "$@"
|
|
755
|
+
;;
|
|
756
|
+
esac
|
|
757
|
+
|
|
758
|
+
assert_state_writable
|
|
759
|
+
debug_ptrace_scope
|
|
760
|
+
|
|
761
|
+
case "$mode" in
|
|
762
|
+
cli)
|
|
763
|
+
QCR_PI_TRUST_DIR="$APP" provision_pi_settings >&2
|
|
764
|
+
# pi's home is read by the tool uid (settings, trust, auth), written by pi.
|
|
765
|
+
[ -z "${QCR_TOOLS_ISOLATED:-}" ] || chmod -R g+rwX "$HOME/.pi" 2>/dev/null || true
|
|
766
|
+
exec node "$APP/dist/src/cli.js" "$@"
|
|
767
|
+
;;
|
|
768
|
+
tui)
|
|
769
|
+
tui_identity
|
|
770
|
+
exec node "$APP/dist/src/cli.js" tui "$@"
|
|
771
|
+
;;
|
|
772
|
+
login)
|
|
773
|
+
QCR_PI_TRUST_DIR="$APP" provision_pi_settings >&2
|
|
774
|
+
mode_login "$@"
|
|
775
|
+
;;
|
|
776
|
+
daemon)
|
|
777
|
+
mode_daemon "$@"
|
|
778
|
+
;;
|
|
779
|
+
companion)
|
|
780
|
+
mode_companion
|
|
781
|
+
;;
|
|
782
|
+
esac
|