@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,979 @@
|
|
|
1
|
+
import { barHeight, paintCmdBar } from "./cmdbar.js";
|
|
2
|
+
import { HEAD_ARGV, logArgv } from "./deploytab.js";
|
|
3
|
+
import { keyChar } from "./keys.js";
|
|
4
|
+
import { hitTest } from "./mouse.js";
|
|
5
|
+
// `MUTED` is used (it paints the TIME IN STATE card's retired-state rows),
|
|
6
|
+
// though it is easy to mistake for an unused import.
|
|
7
|
+
import { ACCENT, ACCENT_BG, BAD, HEADING, MUTED, OK, RESET as DRESET, SEP, STRONG, WARN, modeBadge, sectionTitle, } from "./design.js";
|
|
8
|
+
import { Frame, displayWidth, fit, rule, sanitizeText, truncate } from "./paint.js";
|
|
9
|
+
import { RETIRED_STATES, RETIRED_STATE_MARK, historicalStateLabel } from "./model.js";
|
|
10
|
+
import { metricsArgv, metricsPrArgv } from "./remote.js";
|
|
11
|
+
import { FG, RESET, fmtAge, stateColor, verdictColor } from "./theme.js";
|
|
12
|
+
// ---- chart primitives -------------------------------------------------------
|
|
13
|
+
const SPARK = ["▁", "▂", "▃", "▄", "▅", "▆", "▇", "█"];
|
|
14
|
+
/** Card accents — every card mark rides the one accent; red/green/state
|
|
15
|
+
* colors remain only where they carry truth (verdicts, states, failures).
|
|
16
|
+
* The hue keys are kept so card definitions stay diff-stable. */
|
|
17
|
+
export const ACCENTS = {
|
|
18
|
+
cyan: ACCENT,
|
|
19
|
+
blue: ACCENT,
|
|
20
|
+
green: ACCENT,
|
|
21
|
+
magenta: ACCENT,
|
|
22
|
+
yellow: ACCENT,
|
|
23
|
+
};
|
|
24
|
+
function dim(s) {
|
|
25
|
+
return `${FG.dim}${s}${RESET}`;
|
|
26
|
+
}
|
|
27
|
+
/** The first series index of bucket `b` when `len` values are averaged into
|
|
28
|
+
* `n` buckets — the ONE partition `bucketize` averages over and `bucketOf`
|
|
29
|
+
* inverts, so an axis tick always sits under the bar its day was averaged
|
|
30
|
+
* into. */
|
|
31
|
+
function bucketStart(b, len, n) {
|
|
32
|
+
return Math.floor(b * (len / n));
|
|
33
|
+
}
|
|
34
|
+
/** Average `values` down to exactly `n` buckets (oldest first is the contract). */
|
|
35
|
+
function bucketize(values, n) {
|
|
36
|
+
if (n <= 0 || values.length === 0)
|
|
37
|
+
return [];
|
|
38
|
+
if (values.length <= n)
|
|
39
|
+
return [...values];
|
|
40
|
+
const len = values.length;
|
|
41
|
+
const out = [];
|
|
42
|
+
for (let i = 0; i < n; i++) {
|
|
43
|
+
const start = bucketStart(i, len, n);
|
|
44
|
+
const slice = values.slice(start, Math.max(bucketStart(i + 1, len, n), start + 1));
|
|
45
|
+
out.push(slice.reduce((a, b) => a + b, 0) / slice.length);
|
|
46
|
+
}
|
|
47
|
+
return out;
|
|
48
|
+
}
|
|
49
|
+
/**
|
|
50
|
+
* One-line trend. Longer series than `width` are bucket-averaged (oldest
|
|
51
|
+
* first is the caller's contract); an all-zero series renders as the floor
|
|
52
|
+
* glyph rather than pretending to a shape.
|
|
53
|
+
*/
|
|
54
|
+
export function sparkline(values, width) {
|
|
55
|
+
const w = Math.max(0, Math.floor(width));
|
|
56
|
+
if (w === 0 || values.length === 0)
|
|
57
|
+
return "";
|
|
58
|
+
const buckets = bucketize(values, Math.min(values.length, w));
|
|
59
|
+
const max = Math.max(...buckets);
|
|
60
|
+
if (max <= 0)
|
|
61
|
+
return SPARK[0].repeat(buckets.length);
|
|
62
|
+
return buckets
|
|
63
|
+
.map((v) => SPARK[Math.min(SPARK.length - 1, Math.max(0, Math.floor((v / max) * (SPARK.length - 1))))])
|
|
64
|
+
.join("");
|
|
65
|
+
}
|
|
66
|
+
/** Label column width for a bar row — under a third of the card, clamped. */
|
|
67
|
+
function labelWidth(width) {
|
|
68
|
+
return Math.min(16, Math.max(6, Math.floor(width * 0.3)));
|
|
69
|
+
}
|
|
70
|
+
/**
|
|
71
|
+
* `label ███████ value` in exactly `width` cells. The bar scales across the
|
|
72
|
+
* room the label and value leave, and the value sits at its end, outside the
|
|
73
|
+
* bar, in normal ink. A zero value (or `max <= 0`) renders a dim `·`: a zero
|
|
74
|
+
* row is still a row.
|
|
75
|
+
*/
|
|
76
|
+
export function hbar(label, value, max, width, valueText, color) {
|
|
77
|
+
const w = Math.max(8, Math.floor(width));
|
|
78
|
+
const lw = labelWidth(w);
|
|
79
|
+
const vt = valueText ?? String(value);
|
|
80
|
+
const vw = Math.min(displayWidth(vt), Math.max(0, w - lw - 4));
|
|
81
|
+
const avail = w - lw - 3 - vw; // gutters + one cell of right margin
|
|
82
|
+
if (avail < 3)
|
|
83
|
+
return fit(`${label} ${vt}`, w);
|
|
84
|
+
// The bar scales across the whole row and the value rides at its end —
|
|
85
|
+
// no cap, no track run-out to the far margin.
|
|
86
|
+
const filled = max > 0 ? Math.min(avail, Math.max(value > 0 ? 1 : 0, Math.round((value / max) * avail))) : 0;
|
|
87
|
+
const bar = filled > 0 ? `${color ?? ""}${"█".repeat(filled)}${color ? RESET : ""}` : dim("·");
|
|
88
|
+
return `${fit(label, lw)} ${bar} ${truncate(vt, vw)}`;
|
|
89
|
+
}
|
|
90
|
+
/** `median 5m · p90 16m · n=56` — the distribution's stats, for a card title. */
|
|
91
|
+
export function distStats(dist, fmt = String) {
|
|
92
|
+
if (dist.n === 0)
|
|
93
|
+
return "no data yet";
|
|
94
|
+
return `median ${fmt(dist.median ?? 0)} · p90 ${fmt(dist.p90 ?? 0)} · n=${dist.n}`;
|
|
95
|
+
}
|
|
96
|
+
/**
|
|
97
|
+
* A whole distribution as a small column chart: four rows of per-bucket block
|
|
98
|
+
* columns scaled to the max count, in the card's accent, on a dim baseline,
|
|
99
|
+
* then a dim row of per-bucket counts (`·` for an empty bucket) and a dim row
|
|
100
|
+
* of bucket labels. Stats live in the card title — see `distStats`.
|
|
101
|
+
*/
|
|
102
|
+
export function histogramLines(dist, width, color = FG.accent) {
|
|
103
|
+
if (dist.n === 0 || dist.histogram.length === 0)
|
|
104
|
+
return []; // the title already reads "no data yet"
|
|
105
|
+
const w = Math.max(4, Math.floor(width));
|
|
106
|
+
const buckets = dist.histogram;
|
|
107
|
+
// Slots widen with the terminal (up to 18 cells) and the bars get real
|
|
108
|
+
// height — a small column chart, not a row of nubs.
|
|
109
|
+
// Buckets spread across the full width with a 2-space gap and sit on a dim
|
|
110
|
+
// baseline, so the shape reads as one chart instead of floating strips.
|
|
111
|
+
const slot = Math.max(3, Math.min(18, Math.floor((w + 2) / buckets.length)));
|
|
112
|
+
const cell = Math.max(1, slot - 2);
|
|
113
|
+
const height = 4;
|
|
114
|
+
const max = buckets.reduce((m, b) => Math.max(m, b.count), 0);
|
|
115
|
+
const levels = buckets.map((b) => b.count <= 0 || max <= 0 ? 0 : Math.max(1, Math.ceil((b.count / max) * height * 8)));
|
|
116
|
+
const chartW = buckets.length * slot - 2;
|
|
117
|
+
const rows = [];
|
|
118
|
+
for (let r = height - 1; r >= 0; r--) {
|
|
119
|
+
const row = buckets
|
|
120
|
+
.map((_b, i) => {
|
|
121
|
+
const rem = levels[i] - r * 8;
|
|
122
|
+
if (rem >= 8)
|
|
123
|
+
return `${color}${"█".repeat(cell)}${RESET}`;
|
|
124
|
+
if (rem > 0)
|
|
125
|
+
return `${color}${SPARK[rem - 1].repeat(cell)}${RESET}`;
|
|
126
|
+
return " ".repeat(cell);
|
|
127
|
+
})
|
|
128
|
+
.join(" ");
|
|
129
|
+
rows.push(truncate(row, w));
|
|
130
|
+
}
|
|
131
|
+
rows.push(truncate(dim("▔".repeat(Math.min(chartW, w))), w));
|
|
132
|
+
const counts = buckets
|
|
133
|
+
.map((b) => fit(b.count > 0 ? String(b.count) : "·", slot))
|
|
134
|
+
.join("")
|
|
135
|
+
.trimEnd();
|
|
136
|
+
const axis = buckets
|
|
137
|
+
.map((b) => fit(b.label.replace(/^</, ""), slot))
|
|
138
|
+
.join("")
|
|
139
|
+
.trimEnd();
|
|
140
|
+
rows.push(truncate(dim(counts), w));
|
|
141
|
+
rows.push(truncate(dim(axis), w));
|
|
142
|
+
return rows;
|
|
143
|
+
}
|
|
144
|
+
/**
|
|
145
|
+
* The column chart's geometry, shared with its day axis so the two can never
|
|
146
|
+
* disagree: `slot` cells per column (bar + one-space gap; widens with the
|
|
147
|
+
* terminal, up to 5 cells of bar, so a wide pane fills instead of showing thin
|
|
148
|
+
* threads) and `n` columns — fewer than `len` when the series is
|
|
149
|
+
* bucket-averaged to fit. A gapless slot-1 column needs no trailing gap.
|
|
150
|
+
*/
|
|
151
|
+
function columnGeometry(len, width) {
|
|
152
|
+
const w = Math.max(1, Math.floor(width));
|
|
153
|
+
const slot = Math.max(1, Math.min(6, Math.floor((w + 1) / len)));
|
|
154
|
+
const n = Math.min(len, Math.max(1, Math.floor((w + (slot > 1 ? 1 : 0)) / slot)));
|
|
155
|
+
return { slot, n };
|
|
156
|
+
}
|
|
157
|
+
/** The bucket `bucketize(len → n)` averages series index `i` into. */
|
|
158
|
+
function bucketOf(i, len, n) {
|
|
159
|
+
if (len <= n)
|
|
160
|
+
return i;
|
|
161
|
+
let b = Math.min(n - 1, Math.floor(i / (len / n)));
|
|
162
|
+
while (b + 1 < n && bucketStart(b + 1, len, n) <= i)
|
|
163
|
+
b++;
|
|
164
|
+
while (b > 0 && bucketStart(b, len, n) > i)
|
|
165
|
+
b--;
|
|
166
|
+
return b;
|
|
167
|
+
}
|
|
168
|
+
/**
|
|
169
|
+
* Multi-row column chart (tall terminals): block glyphs stacked per column,
|
|
170
|
+
* full `█` rows plus a fractional top glyph, single hue, dim `·` baseline for
|
|
171
|
+
* a zero day. Series longer than the width are bucket-averaged.
|
|
172
|
+
*/
|
|
173
|
+
export function columnChart(values, width, height, color) {
|
|
174
|
+
const w = Math.max(1, Math.floor(width));
|
|
175
|
+
const h = Math.max(1, Math.floor(height));
|
|
176
|
+
if (values.length === 0)
|
|
177
|
+
return [];
|
|
178
|
+
const { slot, n } = columnGeometry(values.length, w);
|
|
179
|
+
const cell = Math.max(1, slot - 1);
|
|
180
|
+
const vals = bucketize(values, n);
|
|
181
|
+
const max = Math.max(...vals, 0);
|
|
182
|
+
const gap = slot > 1 ? " " : "";
|
|
183
|
+
const rows = [];
|
|
184
|
+
for (let r = 0; r < h; r++) {
|
|
185
|
+
const cells = vals.map((v) => {
|
|
186
|
+
const eighths = max > 0 ? Math.round((v / max) * h * 8) : 0;
|
|
187
|
+
const cellE = eighths - (h - 1 - r) * 8;
|
|
188
|
+
if (cellE >= 8)
|
|
189
|
+
return `${color}${"█".repeat(cell)}${RESET}${gap}`;
|
|
190
|
+
if (cellE > 0)
|
|
191
|
+
return `${color}${SPARK[cellE - 1].repeat(cell)}${RESET}${gap}`;
|
|
192
|
+
return (r === h - 1 ? `${dim("·")}${" ".repeat(cell - 1)}` : " ".repeat(cell)) + gap;
|
|
193
|
+
});
|
|
194
|
+
rows.push(truncate(cells.join(""), w));
|
|
195
|
+
}
|
|
196
|
+
return rows;
|
|
197
|
+
}
|
|
198
|
+
/**
|
|
199
|
+
* Sparse day axis under a `columnChart` of the same series and width: first,
|
|
200
|
+
* last, and weekly ticks, each at the column its day was bucketed into.
|
|
201
|
+
*/
|
|
202
|
+
export function dayAxis(days, width) {
|
|
203
|
+
const w = Math.max(0, Math.floor(width));
|
|
204
|
+
const buf = new Array(w).fill(" ");
|
|
205
|
+
const { slot, n } = columnGeometry(Math.max(1, days.length), w);
|
|
206
|
+
const put = (idx, text) => {
|
|
207
|
+
const col = bucketOf(idx, days.length, n) * slot;
|
|
208
|
+
const start = Math.min(Math.max(0, col), w - text.length);
|
|
209
|
+
if (start < 0)
|
|
210
|
+
return;
|
|
211
|
+
for (let i = start - 1; i <= start + text.length; i++)
|
|
212
|
+
if (i >= 0 && i < w && buf[i] !== " ")
|
|
213
|
+
return;
|
|
214
|
+
for (let i = 0; i < text.length; i++)
|
|
215
|
+
buf[start + i] = text[i];
|
|
216
|
+
};
|
|
217
|
+
const short = (d) => (d.length >= 10 ? d.slice(5) : d);
|
|
218
|
+
if (days.length === 0)
|
|
219
|
+
return "";
|
|
220
|
+
put(0, short(days[0]));
|
|
221
|
+
if (days.length > 1)
|
|
222
|
+
put(days.length - 1, short(days[days.length - 1]));
|
|
223
|
+
for (let i = 7; i < days.length - 1; i += 7)
|
|
224
|
+
put(i, short(days[i]));
|
|
225
|
+
return dim(buf.join("").trimEnd());
|
|
226
|
+
}
|
|
227
|
+
/** 45s / 12m / 3h / 2d from a second count — fmtAge's vocabulary, no clock. */
|
|
228
|
+
export function fmtDur(seconds) {
|
|
229
|
+
if (seconds === null || seconds === undefined)
|
|
230
|
+
return "—";
|
|
231
|
+
const s = Math.max(0, Math.round(seconds));
|
|
232
|
+
if (s < 60)
|
|
233
|
+
return `${s}s`;
|
|
234
|
+
if (s < 3600)
|
|
235
|
+
return `${Math.round(s / 60)}m`;
|
|
236
|
+
if (s < 86_400)
|
|
237
|
+
return `${(s / 3600).toFixed(1)}h`;
|
|
238
|
+
return `${(s / 86_400).toFixed(1)}d`;
|
|
239
|
+
}
|
|
240
|
+
function usd(v) {
|
|
241
|
+
return v === null || v === undefined ? "—" : `$${v.toFixed(2)}`;
|
|
242
|
+
}
|
|
243
|
+
function pct(v) {
|
|
244
|
+
return v === null || v === undefined ? "—" : `${Math.round(v * 100)}%`;
|
|
245
|
+
}
|
|
246
|
+
/** The real probe: deploytab's own read-only argvs through its LocalRunner —
|
|
247
|
+
* one implementation of "what is local HEAD / how far ahead is it". */
|
|
248
|
+
export function localHeadProbe(local) {
|
|
249
|
+
return {
|
|
250
|
+
async read(deployedSha) {
|
|
251
|
+
const head = await local(HEAD_ARGV);
|
|
252
|
+
const out = {};
|
|
253
|
+
if (head.ok && head.stdout.trim())
|
|
254
|
+
out.head = head.stdout.trim();
|
|
255
|
+
if (deployedSha) {
|
|
256
|
+
const log = await local(logArgv(deployedSha, "HEAD"));
|
|
257
|
+
if (log.ok)
|
|
258
|
+
out.ahead = log.stdout.split("\n").filter((l) => l.trim() !== "").length;
|
|
259
|
+
}
|
|
260
|
+
return out;
|
|
261
|
+
},
|
|
262
|
+
};
|
|
263
|
+
}
|
|
264
|
+
/**
|
|
265
|
+
* The window switcher. Hotkeys are letters — week / month / all — because the
|
|
266
|
+
* digits `1`…`8` open the eight surfaces on every tab: a digit that did
|
|
267
|
+
* something else on exactly one tab would be a hidden mode.
|
|
268
|
+
*/
|
|
269
|
+
export const WINDOW_LABELS = [
|
|
270
|
+
{ key: "d7", label: "7d", hotkey: "w" },
|
|
271
|
+
{ key: "d30", label: "30d", hotkey: "m" },
|
|
272
|
+
{ key: "all", label: "all", hotkey: "a" },
|
|
273
|
+
];
|
|
274
|
+
// ---- cards ------------------------------------------------------------------
|
|
275
|
+
/** Card title: the one section language; the accent param is unused (one
|
|
276
|
+
* accent) but kept for signature stability. */
|
|
277
|
+
function section(title, subtitle, _accent = ACCENT) {
|
|
278
|
+
return sectionTitle(title, subtitle);
|
|
279
|
+
}
|
|
280
|
+
/** Single-hue bar list: identity is the row label, not the color. Capped. */
|
|
281
|
+
function barList(rows, width, accent, cap = 6) {
|
|
282
|
+
if (rows.length === 0)
|
|
283
|
+
return [dim("no data yet")];
|
|
284
|
+
const max = rows.reduce((m, r) => Math.max(m, r.value), 0);
|
|
285
|
+
const shown = rows.slice(0, cap);
|
|
286
|
+
const lines = shown.map((r) => hbar(r.label, r.value, max, width, r.text, r.color ?? accent));
|
|
287
|
+
if (rows.length > cap)
|
|
288
|
+
lines.push(dim(`…+${rows.length - cap} more`));
|
|
289
|
+
return lines;
|
|
290
|
+
}
|
|
291
|
+
function barsFromRecord(rec, width, accent, fmt) {
|
|
292
|
+
const rows = Object.entries(rec)
|
|
293
|
+
.sort((a, b) => b[1] - a[1])
|
|
294
|
+
.map(([k, v]) => ({ label: k, value: v, text: fmt(v) }));
|
|
295
|
+
return barList(rows, width, accent);
|
|
296
|
+
}
|
|
297
|
+
/** Heartbeats older than this read as a stalled daemon, not a slow tick. */
|
|
298
|
+
export const HEARTBEAT_STALE_S = 300;
|
|
299
|
+
/** The daemon's mode as the ops card states it: unknown without a snapshot
|
|
300
|
+
* or a mode in it — "live" is the one label that must never be guessed. The
|
|
301
|
+
* subtitle and the body both read it here, so they cannot disagree. */
|
|
302
|
+
export function opsMode(ops) {
|
|
303
|
+
if (ops.heartbeat === null || ops.dry_run === null)
|
|
304
|
+
return "unknown";
|
|
305
|
+
return ops.dry_run ? "dry-run" : "live";
|
|
306
|
+
}
|
|
307
|
+
/**
|
|
308
|
+
* The operations card body: how the daemon is running (mode, heartbeat,
|
|
309
|
+
* concurrency), which commit it is running (BUILD_SHA marker) with an accented
|
|
310
|
+
* "deploy needed" when the operator's checkout has moved past it, and the
|
|
311
|
+
* window's aggregate event traffic as a thin bar list.
|
|
312
|
+
*
|
|
313
|
+
* `ops` absent (an older daemon's payload) or `local` absent (no git here —
|
|
314
|
+
* tests, or a laptop without the repo) both degrade to fewer lines, never to a
|
|
315
|
+
* throw or a fake answer.
|
|
316
|
+
*/
|
|
317
|
+
export function opsLines(ops, local, win, width, now) {
|
|
318
|
+
const lines = [];
|
|
319
|
+
if (!ops) {
|
|
320
|
+
lines.push(dim("no ops data in this payload (older daemon?)"));
|
|
321
|
+
}
|
|
322
|
+
else {
|
|
323
|
+
const known = opsMode(ops);
|
|
324
|
+
const mode = known === "unknown" ? dim("mode unknown") : modeBadge(known === "dry-run");
|
|
325
|
+
const beatS = ops.heartbeat
|
|
326
|
+
? Math.max(0, Math.floor((now.getTime() - new Date(ops.heartbeat).getTime()) / 1000))
|
|
327
|
+
: null;
|
|
328
|
+
const beat = ops.heartbeat === null
|
|
329
|
+
? `${FG.anomaly}no heartbeat${RESET}`
|
|
330
|
+
: `${beatS !== null && beatS > HEARTBEAT_STALE_S ? BAD : OK}♥${DRESET} ${fmtAge(ops.heartbeat, now)} ago`;
|
|
331
|
+
const rounds = `${STRONG}${ops.running_rounds}${DRESET}/${ops.max_concurrent_rounds ?? "?"} rounds running`;
|
|
332
|
+
lines.push(`${mode} ${beat} ${SEP} ${rounds}`);
|
|
333
|
+
const b = ops.build;
|
|
334
|
+
lines.push(b
|
|
335
|
+
? `running ${STRONG}${b.sha}${DRESET}${b.at ? ` ${FG.dim}· deployed ${fmtAge(b.at, now)} ago${RESET}` : ""}${b.mode ? ` ${FG.dim}· ${b.mode}${RESET}` : ""}`
|
|
336
|
+
: dim("running an unknown commit — no BUILD_SHA on the VM yet"));
|
|
337
|
+
if (b && local?.head) {
|
|
338
|
+
lines.push(local.head === b.sha
|
|
339
|
+
? `${OK}✓${DRESET} ${FG.dim}your checkout (${local.head}) is what the VM runs${RESET}`
|
|
340
|
+
: `${WARN}${STRONG}deploy needed${DRESET}${SEP}` +
|
|
341
|
+
`${local.ahead === undefined ? `local ${local.head} differs` : `${local.ahead} commit${local.ahead === 1 ? "" : "s"} ahead (${local.head})`}`);
|
|
342
|
+
}
|
|
343
|
+
}
|
|
344
|
+
lines.push("");
|
|
345
|
+
lines.push(sectionTitle("EVENTS"));
|
|
346
|
+
const kinds = win.events_by_kind ?? [];
|
|
347
|
+
if (win.events_by_kind === undefined) {
|
|
348
|
+
lines.push(dim("events are not reported by the daemon build on the VM"));
|
|
349
|
+
}
|
|
350
|
+
else if (kinds.length === 0) {
|
|
351
|
+
lines.push(dim("no events in this window"));
|
|
352
|
+
}
|
|
353
|
+
else {
|
|
354
|
+
const max = kinds.reduce((m, k) => Math.max(m, k.count), 0);
|
|
355
|
+
for (const k of kinds.slice(0, 8))
|
|
356
|
+
lines.push(hbar(k.kind, k.count, max, width, String(k.count), ACCENTS.magenta));
|
|
357
|
+
if (kinds.length > 8)
|
|
358
|
+
lines.push(dim(`…+${kinds.length - 8} more kinds`));
|
|
359
|
+
// The all-time window counts rows the archiver moved out
|
|
360
|
+
// of the live table too — say so, so the tally is never read as live.
|
|
361
|
+
if (win.events_archived)
|
|
362
|
+
lines.push(dim(`(incl. ${win.events_archived} archived row(s) — moved to archive/db)`));
|
|
363
|
+
}
|
|
364
|
+
return lines;
|
|
365
|
+
}
|
|
366
|
+
/**
|
|
367
|
+
* The cancelled rounds card.
|
|
368
|
+
*
|
|
369
|
+
* It makes cancelled rounds visible, grouped by cause because an ungrouped
|
|
370
|
+
* total would mislead: most cancellation is the boot orphan sweep after a
|
|
371
|
+
* redeploy (a container restart orphans every in-flight round by
|
|
372
|
+
* construction), and that bar stays in normal ink no matter how tall it gets.
|
|
373
|
+
* Only a round that stopped dead is marked.
|
|
374
|
+
*/
|
|
375
|
+
export function cancellationLines(win, width) {
|
|
376
|
+
const c = win.cancellations;
|
|
377
|
+
// Not reported ≠ none: an older daemon build simply omits it.
|
|
378
|
+
if (!c)
|
|
379
|
+
return [dim("cancellations are not reported by the daemon build on the VM")];
|
|
380
|
+
if (c.total === 0)
|
|
381
|
+
return [dim("no cancelled rounds in this window")];
|
|
382
|
+
const max = c.by_cause.reduce((m, b) => Math.max(m, b.count), 0);
|
|
383
|
+
const lines = c.by_cause.map((b) => hbar(b.label, b.count, max, width, String(b.count), b.loud ? BAD : ACCENTS.yellow));
|
|
384
|
+
lines.push("");
|
|
385
|
+
lines.push(c.loud > 0
|
|
386
|
+
? `${BAD}${c.loud} stopped dead${DRESET} ${FG.dim}— no verdict inside the deadline; the rest is the system working${RESET}`
|
|
387
|
+
: dim("none stopped dead — every cancellation here is a redeploy artefact or a superseded round"));
|
|
388
|
+
return lines;
|
|
389
|
+
}
|
|
390
|
+
function cancelSubtitle(win) {
|
|
391
|
+
const c = win.cancellations;
|
|
392
|
+
if (!c || c.total === 0)
|
|
393
|
+
return "by cause";
|
|
394
|
+
return `${c.total} by cause · ${c.loud} stopped dead`;
|
|
395
|
+
}
|
|
396
|
+
/** Tall terminals earn a real column chart in the ACTIVITY card. */
|
|
397
|
+
export function activityChartHeight(rows) {
|
|
398
|
+
if (rows < 34)
|
|
399
|
+
return 0; // short: the 1-row sparkline degradation
|
|
400
|
+
return Math.max(6, Math.min(10, Math.floor((rows - 18) / 4)));
|
|
401
|
+
}
|
|
402
|
+
export function metricsCards(win, daily, rows = 24, extra = {}) {
|
|
403
|
+
const chartH = activityChartHeight(rows);
|
|
404
|
+
const now = extra.now ?? new Date();
|
|
405
|
+
const opsSubtitle = extra.ops
|
|
406
|
+
? `${opsMode(extra.ops) === "unknown" ? "mode unknown" : opsMode(extra.ops)} · ${extra.ops.build ? extra.ops.build.sha : "build unknown"}`
|
|
407
|
+
: "daemon health · version · event traffic";
|
|
408
|
+
return [
|
|
409
|
+
{
|
|
410
|
+
title: "ACTIVITY",
|
|
411
|
+
subtitle: daily.length > 0 ? `${daily[0].day} → ${daily[daily.length - 1].day}` : "per ops day",
|
|
412
|
+
accent: ACCENTS.cyan,
|
|
413
|
+
body: (w) => {
|
|
414
|
+
if (daily.length === 0)
|
|
415
|
+
return [dim("no data yet")];
|
|
416
|
+
const rounds = daily.map((d) => d.rounds);
|
|
417
|
+
const prs = daily.map((d) => d.prs);
|
|
418
|
+
const spend = daily.map((d) => d.spend_usd);
|
|
419
|
+
const days = daily.map((d) => d.day);
|
|
420
|
+
if (chartH > 0) {
|
|
421
|
+
return [
|
|
422
|
+
dim(`rounds/day · max ${Math.max(...rounds)}`),
|
|
423
|
+
...columnChart(rounds, w, chartH, ACCENTS.blue),
|
|
424
|
+
dayAxis(days, w),
|
|
425
|
+
"",
|
|
426
|
+
dim(`spend/day · max ${usd(Math.max(...spend))}`),
|
|
427
|
+
...columnChart(spend, w, chartH, ACCENTS.yellow),
|
|
428
|
+
dayAxis(days, w),
|
|
429
|
+
];
|
|
430
|
+
}
|
|
431
|
+
const sparkW = Math.max(8, w - 14);
|
|
432
|
+
return [
|
|
433
|
+
`${fit("rounds", 7)}${ACCENTS.blue}${sparkline(rounds, sparkW)}${RESET} ${Math.max(...rounds)}`,
|
|
434
|
+
`${fit("prs", 7)}${ACCENTS.cyan}${sparkline(prs, sparkW)}${RESET} ${Math.max(...prs)}`,
|
|
435
|
+
`${fit("spend", 7)}${ACCENTS.yellow}${sparkline(spend, sparkW)}${RESET} ${usd(Math.max(...spend))}`,
|
|
436
|
+
];
|
|
437
|
+
},
|
|
438
|
+
},
|
|
439
|
+
{
|
|
440
|
+
title: "OPERATIONS",
|
|
441
|
+
subtitle: opsSubtitle,
|
|
442
|
+
accent: ACCENTS.magenta,
|
|
443
|
+
body: (w) => opsLines(extra.ops, extra.local, win, w, now),
|
|
444
|
+
},
|
|
445
|
+
{
|
|
446
|
+
title: "TIME TO FIRST VERDICT",
|
|
447
|
+
subtitle: `all live rounds: queue ${fmtDur(win.ttfv.queue_median_s)} · review ${fmtDur(win.ttfv.review_median_s)} · ${distStats(win.ttfv, fmtDur)}`,
|
|
448
|
+
accent: ACCENTS.blue,
|
|
449
|
+
body: (w) => histogramLines(win.ttfv, w, ACCENTS.blue),
|
|
450
|
+
},
|
|
451
|
+
{
|
|
452
|
+
title: "VERDICT MIX",
|
|
453
|
+
subtitle: "rounds by verdict",
|
|
454
|
+
accent: ACCENTS.green,
|
|
455
|
+
body: (w) => barList(win.verdict_mix.map((r) => ({
|
|
456
|
+
label: r.verdict,
|
|
457
|
+
value: r.count,
|
|
458
|
+
text: String(r.count),
|
|
459
|
+
color: verdictColor(r.verdict),
|
|
460
|
+
})), w, ACCENTS.green),
|
|
461
|
+
},
|
|
462
|
+
{
|
|
463
|
+
// History, not current state: these buckets come from the
|
|
464
|
+
// `pr_transition` event log, so they can name a state the daemon has
|
|
465
|
+
// since retired. Such a row is marked `†`, carries its retirement date
|
|
466
|
+
// in the value column, and is painted MUTED on purpose, so it never
|
|
467
|
+
// reads like a current state.
|
|
468
|
+
title: "TIME IN STATE",
|
|
469
|
+
subtitle: `median dwell per state · ${RETIRED_STATE_MARK} = retired state, history only`,
|
|
470
|
+
accent: ACCENTS.magenta,
|
|
471
|
+
body: (w) => barList(win.time_in_state
|
|
472
|
+
.filter((r) => r.total_s > 0 || r.median_s !== null)
|
|
473
|
+
.map((r) => {
|
|
474
|
+
const retired = RETIRED_STATES[r.state];
|
|
475
|
+
return {
|
|
476
|
+
label: historicalStateLabel(r.state),
|
|
477
|
+
value: r.median_s ?? 0,
|
|
478
|
+
text: retired === undefined ? fmtDur(r.median_s) : `${fmtDur(r.median_s)} · ${retired}`,
|
|
479
|
+
color: retired === undefined ? stateColor(r.state) : MUTED,
|
|
480
|
+
};
|
|
481
|
+
}), w, ACCENTS.magenta),
|
|
482
|
+
},
|
|
483
|
+
{
|
|
484
|
+
title: "ROUND DURATION",
|
|
485
|
+
subtitle: `overrun ${pct(win.duration.overrun_rate)} · ${distStats(win.duration, fmtDur)}`,
|
|
486
|
+
accent: ACCENTS.yellow,
|
|
487
|
+
body: (w) => histogramLines(win.duration, w, ACCENTS.yellow),
|
|
488
|
+
},
|
|
489
|
+
{
|
|
490
|
+
title: "ROUNDS UNTIL RESOLUTION",
|
|
491
|
+
subtitle: distStats(win.rounds_until_resolution),
|
|
492
|
+
accent: ACCENTS.green,
|
|
493
|
+
body: (w) => histogramLines(win.rounds_until_resolution, w, ACCENTS.green),
|
|
494
|
+
},
|
|
495
|
+
{
|
|
496
|
+
title: "SPEND",
|
|
497
|
+
subtitle: `per-PR median ${usd(win.spend.per_pr_median)} · p90 ${usd(win.spend.per_pr_p90)}`,
|
|
498
|
+
accent: ACCENTS.cyan,
|
|
499
|
+
body: (w) => barsFromRecord(win.spend.by_round_type, w, ACCENTS.cyan, usd),
|
|
500
|
+
},
|
|
501
|
+
{
|
|
502
|
+
title: "SPEND BY LENS",
|
|
503
|
+
subtitle: "usd per lens",
|
|
504
|
+
accent: ACCENTS.blue,
|
|
505
|
+
body: (w) => barsFromRecord(win.spend.by_lens, w, ACCENTS.blue, usd),
|
|
506
|
+
},
|
|
507
|
+
{
|
|
508
|
+
title: "AUTHOR RESPONSE",
|
|
509
|
+
subtitle: distStats(win.author_response, fmtDur),
|
|
510
|
+
accent: ACCENTS.yellow,
|
|
511
|
+
body: (w) => histogramLines(win.author_response, w, ACCENTS.yellow),
|
|
512
|
+
},
|
|
513
|
+
{
|
|
514
|
+
title: "REVIEW DEPTH",
|
|
515
|
+
subtitle: `bot comments per round · ${distStats(win.review_depth)}`,
|
|
516
|
+
accent: ACCENTS.magenta,
|
|
517
|
+
body: (w) => histogramLines(win.review_depth, w, ACCENTS.magenta),
|
|
518
|
+
},
|
|
519
|
+
{
|
|
520
|
+
title: "PR SIZE",
|
|
521
|
+
subtitle: "prs · median ttfv per size bucket",
|
|
522
|
+
accent: ACCENTS.green,
|
|
523
|
+
body: (w) => barList(win.size
|
|
524
|
+
.filter((r) => r.prs > 0)
|
|
525
|
+
.map((r) => ({
|
|
526
|
+
label: r.bucket,
|
|
527
|
+
value: r.prs,
|
|
528
|
+
text: `${r.prs} · ${fmtDur(r.median_ttfv_s)}`,
|
|
529
|
+
})), w, ACCENTS.green),
|
|
530
|
+
},
|
|
531
|
+
{
|
|
532
|
+
title: "CANCELLED ROUNDS",
|
|
533
|
+
subtitle: cancelSubtitle(win),
|
|
534
|
+
accent: ACCENTS.yellow,
|
|
535
|
+
body: (w) => cancellationLines(win, w),
|
|
536
|
+
},
|
|
537
|
+
{
|
|
538
|
+
title: "PING-PONG",
|
|
539
|
+
subtitle: `cap hits ${win.pingpong.cap_hits} · ${distStats(win.pingpong)}`,
|
|
540
|
+
accent: ACCENTS.cyan,
|
|
541
|
+
body: (w) => histogramLines(win.pingpong, w, ACCENTS.cyan),
|
|
542
|
+
},
|
|
543
|
+
];
|
|
544
|
+
}
|
|
545
|
+
/** Always a single column — one card under the other. */
|
|
546
|
+
export function columnWidths(cols) {
|
|
547
|
+
return [cols - 2];
|
|
548
|
+
}
|
|
549
|
+
/**
|
|
550
|
+
* Balance the cards across columns by their actual rendered height
|
|
551
|
+
* (longest-first bin packing, then original order restored inside each
|
|
552
|
+
* column) so no column strands a screenful of dead rows.
|
|
553
|
+
*/
|
|
554
|
+
export function packColumns(cards, widths) {
|
|
555
|
+
const n = widths.length;
|
|
556
|
+
const measureW = Math.max(8, Math.min(...widths) - 1);
|
|
557
|
+
const heights = new Array(n).fill(0);
|
|
558
|
+
const assign = new Array(cards.length).fill(0);
|
|
559
|
+
const sized = cards.map((card, i) => ({ i, h: card.body(measureW).length + 1 }));
|
|
560
|
+
// The first card is the headline — it stays top-left; the rest are packed
|
|
561
|
+
// longest-first so every column ends within a card of the others.
|
|
562
|
+
const order = sized.slice(1).sort((a, b) => b.h - a.h || a.i - b.i);
|
|
563
|
+
if (sized.length > 0)
|
|
564
|
+
heights[0] = sized[0].h + 1;
|
|
565
|
+
for (const it of order) {
|
|
566
|
+
let target = 0;
|
|
567
|
+
for (let k = 1; k < n; k++)
|
|
568
|
+
if (heights[k] < heights[target])
|
|
569
|
+
target = k;
|
|
570
|
+
assign[it.i] = target;
|
|
571
|
+
heights[target] += it.h + 1; // + the blank separator row
|
|
572
|
+
}
|
|
573
|
+
const blocks = widths.map(() => []);
|
|
574
|
+
cards.forEach((card, i) => {
|
|
575
|
+
const target = assign[i];
|
|
576
|
+
const w = Math.max(8, widths[target] - 1);
|
|
577
|
+
const block = [truncate(section(card.title, card.subtitle, card.accent), w)];
|
|
578
|
+
// Bodies sit indented under their title — the extra margin keeps
|
|
579
|
+
// neighbouring charts from reading as one figure.
|
|
580
|
+
for (const line of card.body(w - 2))
|
|
581
|
+
block.push(` ${truncate(line, w - 2)}`);
|
|
582
|
+
blocks[target].push(block);
|
|
583
|
+
});
|
|
584
|
+
// Two blank rows between cards — proper breathing room between figures.
|
|
585
|
+
return blocks.map((column) => {
|
|
586
|
+
const out = [];
|
|
587
|
+
column.forEach((block, i) => {
|
|
588
|
+
if (i > 0)
|
|
589
|
+
out.push("", "");
|
|
590
|
+
out.push(...block);
|
|
591
|
+
});
|
|
592
|
+
return out;
|
|
593
|
+
});
|
|
594
|
+
}
|
|
595
|
+
// ---- header -----------------------------------------------------------------
|
|
596
|
+
export function statStrip(win, width) {
|
|
597
|
+
const h = win.header;
|
|
598
|
+
const bits = [
|
|
599
|
+
`${FG.dim}triggered${RESET} ${STRONG}${h.prs_triggered}${DRESET}`,
|
|
600
|
+
`${FG.dim}reviewed${RESET} ${STRONG}${h.prs_reviewed}${DRESET}`,
|
|
601
|
+
`${FG.approve}✓${h.approvals}${RESET} ${FG.request_changes}✗${h.request_changes}${RESET}`,
|
|
602
|
+
`${FG.dim}rounds${RESET} ${STRONG}${h.rounds}${DRESET}`,
|
|
603
|
+
`${FG.accent}$${h.spend_usd.toFixed(2)}${RESET}`,
|
|
604
|
+
`${h.overruns > 0 ? WARN : FG.dim}overruns ${h.overruns}${RESET}`,
|
|
605
|
+
// The loud cancellations only — a round that stopped dead. The benign
|
|
606
|
+
// redeploy orphan sweep is in the card below, never in the strip: a tile
|
|
607
|
+
// that lights up after every deploy is a tile nobody reads.
|
|
608
|
+
// `undefined` means an older daemon does not report the field at all —
|
|
609
|
+
// "?" not "0": a zero here reads as "nothing stopped dead".
|
|
610
|
+
win.cancellations === undefined
|
|
611
|
+
? `${FG.dim}stopped ?${RESET}`
|
|
612
|
+
: `${win.cancellations.loud > 0 ? WARN : FG.dim}stopped ${win.cancellations.loud}${RESET}`,
|
|
613
|
+
];
|
|
614
|
+
return truncate(bits.join(SEP), width);
|
|
615
|
+
}
|
|
616
|
+
/** Window switcher, with the 1-based x-ranges of each button for zoning. */
|
|
617
|
+
export function windowSwitcher(selected, startX) {
|
|
618
|
+
let x = startX;
|
|
619
|
+
const parts = [];
|
|
620
|
+
const zones = [];
|
|
621
|
+
for (const w of WINDOW_LABELS) {
|
|
622
|
+
const plain = `[ ${w.label} ]`;
|
|
623
|
+
zones.push({ x1: x, x2: x + plain.length - 1, window: w.key });
|
|
624
|
+
parts.push(w.key === selected
|
|
625
|
+
? `${ACCENT_BG}${plain}${DRESET}`
|
|
626
|
+
: `${FG.dim}[${RESET} ${w.label} ${FG.dim}]${RESET}`);
|
|
627
|
+
x += plain.length + 1;
|
|
628
|
+
}
|
|
629
|
+
return { text: parts.join(" "), zones };
|
|
630
|
+
}
|
|
631
|
+
// ---- timeline drill-down ----------------------------------------------------
|
|
632
|
+
const KIND_GLYPHS = [
|
|
633
|
+
[/trigger/i, "▸", FG.accent],
|
|
634
|
+
[/round_start|round-start|started/i, "▶", FG.reviewing],
|
|
635
|
+
[/verdict|round_finish|round-finish|finished/i, "■", FG.approve],
|
|
636
|
+
[/push|synchron/i, "↑", FG.awaiting_author],
|
|
637
|
+
[/merge/i, "⇢", FG.approve],
|
|
638
|
+
[/close/i, "✖", FG.closed],
|
|
639
|
+
[/state|transition/i, "→", FG.needs_human],
|
|
640
|
+
];
|
|
641
|
+
export function kindGlyph(kind) {
|
|
642
|
+
for (const [re, glyph] of KIND_GLYPHS)
|
|
643
|
+
if (re.test(kind))
|
|
644
|
+
return glyph;
|
|
645
|
+
return "·";
|
|
646
|
+
}
|
|
647
|
+
/** Only the glyph carries color in the timeline — the text stays in ink. */
|
|
648
|
+
export function kindColor(kind) {
|
|
649
|
+
for (const [re, , color] of KIND_GLYPHS)
|
|
650
|
+
if (re.test(kind))
|
|
651
|
+
return color;
|
|
652
|
+
return FG.dim;
|
|
653
|
+
}
|
|
654
|
+
export function timelineLines(tl, width, now) {
|
|
655
|
+
const lines = [];
|
|
656
|
+
const title = tl.title ? sanitizeText(tl.title) : "(unknown PR)";
|
|
657
|
+
lines.push(truncate(`${HEADING}#${tl.pr}${DRESET} ${STRONG}${title}${DRESET}${tl.author ? ` ${FG.author}${tl.author}${RESET}` : ""}`, width));
|
|
658
|
+
if (!tl.known) {
|
|
659
|
+
lines.push(`${FG.dim}the daemon has no record of this PR${RESET}`);
|
|
660
|
+
return lines;
|
|
661
|
+
}
|
|
662
|
+
lines.push(truncate(section("TIMELINE", `${tl.items.length} events, oldest first`), width));
|
|
663
|
+
for (const item of tl.items) {
|
|
664
|
+
lines.push(truncate(`${FG.dim}${fit(fmtAge(item.ts, now), 5)}${RESET} ${kindColor(item.kind)}${kindGlyph(item.kind)}${RESET} ${item.label}`, width));
|
|
665
|
+
if (item.detail)
|
|
666
|
+
lines.push(truncate(` ${FG.dim}${sanitizeText(item.detail)}${RESET}`, width));
|
|
667
|
+
}
|
|
668
|
+
if (tl.backfilled_rounds.length > 0) {
|
|
669
|
+
lines.push("");
|
|
670
|
+
lines.push(truncate(section("BACKFILLED ROUNDS", "reconstructed from GitHub"), width));
|
|
671
|
+
for (const r of tl.backfilled_rounds) {
|
|
672
|
+
lines.push(truncate(` r${r.round_no} ${verdictColor(r.verdict)}${r.verdict ?? "—"}${RESET} ${FG.dim}${r.submitted_at}${RESET}`, width));
|
|
673
|
+
}
|
|
674
|
+
}
|
|
675
|
+
return lines;
|
|
676
|
+
}
|
|
677
|
+
// ---- render -----------------------------------------------------------------
|
|
678
|
+
/**
|
|
679
|
+
* What the metrics tab answers to on this frame: the `# <pr>` box owns the
|
|
680
|
+
* digits while it is open (`1`…`8` decode as tab switches, and `keyChar`
|
|
681
|
+
* folds them back — without registering them here `#5265` would lose its 5
|
|
682
|
+
* to the companion column); a drill-down answers to Esc; the dashboard to
|
|
683
|
+
* the window hotkeys and `#`. ⏎ is offered only inside the box: a key that
|
|
684
|
+
* acts must be painted, and the dashboard paints no ⏎.
|
|
685
|
+
*/
|
|
686
|
+
export function metricsKeys(view) {
|
|
687
|
+
if (view.prEntry !== undefined) {
|
|
688
|
+
return {
|
|
689
|
+
bar: [
|
|
690
|
+
{ key: "\r", label: "⏎ open" },
|
|
691
|
+
{ key: "\x1b", label: "Esc cancel" },
|
|
692
|
+
],
|
|
693
|
+
inline: [..."0123456789"],
|
|
694
|
+
};
|
|
695
|
+
}
|
|
696
|
+
if (view.drill)
|
|
697
|
+
return { bar: [{ key: "\x1b", label: "Esc back" }], inline: [] };
|
|
698
|
+
const bar = WINDOW_LABELS.map((w) => ({
|
|
699
|
+
key: w.hotkey,
|
|
700
|
+
label: `${w.hotkey} ${w.label}`,
|
|
701
|
+
}));
|
|
702
|
+
bar.push({ key: "#", label: "# pr" });
|
|
703
|
+
return { bar, inline: [] };
|
|
704
|
+
}
|
|
705
|
+
export function renderMetrics(view, cols, rows) {
|
|
706
|
+
const frame = new Frame(cols, rows);
|
|
707
|
+
const now = view.now ?? new Date();
|
|
708
|
+
const drill = view.drill;
|
|
709
|
+
const live = metricsKeys(view);
|
|
710
|
+
const barRows = barHeight("metrics", cols, live.bar);
|
|
711
|
+
frame.set(0, rule(cols, "┌", "┐", [
|
|
712
|
+
`${HEADING}quickreview${DRESET}`,
|
|
713
|
+
modeBadge(view.dryRun),
|
|
714
|
+
drill ? `metrics · #${drill.pr}` : "metrics",
|
|
715
|
+
drill ? `${FG.dim}Esc back to the dashboard · j/k scroll${RESET}` : "",
|
|
716
|
+
]));
|
|
717
|
+
if (drill) {
|
|
718
|
+
// A cached timeline stays on screen through a failed refresh, and the
|
|
719
|
+
// failure is said above it rather than hidden behind the old data.
|
|
720
|
+
const lines = drill.payload
|
|
721
|
+
? [
|
|
722
|
+
...(drill.error ? [`${WARN}refresh failed: ${drill.error}${RESET}`] : []),
|
|
723
|
+
...timelineLines(drill.payload, cols - 4, now),
|
|
724
|
+
]
|
|
725
|
+
: [
|
|
726
|
+
drill.error
|
|
727
|
+
? `${FG.dim}metrics unavailable: ${drill.error}${RESET}`
|
|
728
|
+
: `${FG.dim}loading timeline for #${drill.pr}…${RESET}`,
|
|
729
|
+
];
|
|
730
|
+
view.scroll = Math.max(0, Math.min(view.scroll, lines.length - (rows - 2 - barRows)));
|
|
731
|
+
for (let r = 0; r < rows - 2 - barRows; r++)
|
|
732
|
+
frame.boxRow(1 + r, [{ text: ` ${lines[view.scroll + r] ?? ""}`, width: cols - 2 }]);
|
|
733
|
+
paintCmdBar(frame, "metrics", cols, rows, live.bar);
|
|
734
|
+
frame.set(rows - 1, rule(cols, "└", "┘", []));
|
|
735
|
+
return frame;
|
|
736
|
+
}
|
|
737
|
+
// Window switcher (row 1) + its click zones.
|
|
738
|
+
const sw = windowSwitcher(view.window, 3);
|
|
739
|
+
const entry = view.prEntry !== undefined
|
|
740
|
+
? ` ${FG.accent}#${view.prEntry}▁${RESET} ${FG.dim}⏎ open timeline · Esc cancel${RESET}`
|
|
741
|
+
: "";
|
|
742
|
+
// Cached metrics stay on screen through a failed refresh; the failure is
|
|
743
|
+
// said beside their age rather than hidden behind the old data.
|
|
744
|
+
const generated = view.payload
|
|
745
|
+
? `${FG.dim}generated ${fmtAge(view.payload.generated_at, now)} ago${RESET}` +
|
|
746
|
+
(view.error ? ` ${WARN}refresh failed: ${view.error}${RESET}` : "")
|
|
747
|
+
: "";
|
|
748
|
+
frame.boxRow(1, [{ text: ` ${sw.text}${entry} ${generated}`, width: cols - 2 }]);
|
|
749
|
+
for (const z of sw.zones) {
|
|
750
|
+
frame.zones.push({
|
|
751
|
+
x1: z.x1,
|
|
752
|
+
y1: 2,
|
|
753
|
+
x2: z.x2,
|
|
754
|
+
y2: 2,
|
|
755
|
+
action: { t: "window", window: z.window },
|
|
756
|
+
});
|
|
757
|
+
}
|
|
758
|
+
const bodyRows = rows - 4 - barRows; // top bar + switcher + stat strip + command bar + bottom
|
|
759
|
+
if (!view.payload) {
|
|
760
|
+
const msg = view.error
|
|
761
|
+
? `${FG.dim}metrics unavailable: ${view.error}${RESET}`
|
|
762
|
+
: `${FG.dim}loading metrics…${RESET}`;
|
|
763
|
+
for (let r = 2; r <= rows - 2 - barRows; r++)
|
|
764
|
+
frame.boxRow(r, [{ text: r === 2 ? ` ${msg}` : "", width: cols - 2 }]);
|
|
765
|
+
paintCmdBar(frame, "metrics", cols, rows, live.bar);
|
|
766
|
+
frame.set(rows - 1, rule(cols, "└", "┘", []));
|
|
767
|
+
return frame;
|
|
768
|
+
}
|
|
769
|
+
const win = view.payload.windows[view.window];
|
|
770
|
+
const bf = view.payload.backfill;
|
|
771
|
+
const bfNote = `${FG.dim}backfill ${bf.rounds} rounds / ${bf.prs} PRs${bf.oldest ? ` since ${bf.oldest}` : ""}${RESET}`;
|
|
772
|
+
frame.boxRow(2, [{ text: ` ${statStrip(win, cols - 3)} ${bfNote}`, width: cols - 2 }]);
|
|
773
|
+
const widths = columnWidths(cols);
|
|
774
|
+
const cards = metricsCards(win, view.payload.daily, bodyRows, {
|
|
775
|
+
...(view.payload.ops ? { ops: view.payload.ops } : {}),
|
|
776
|
+
...(view.local ? { local: view.local } : {}),
|
|
777
|
+
now,
|
|
778
|
+
});
|
|
779
|
+
const columns = packColumns(cards, widths);
|
|
780
|
+
view.scroll = Math.max(0, Math.min(view.scroll, Math.max(0, ...columns.map((c) => c.length)) - bodyRows));
|
|
781
|
+
for (let r = 0; r < bodyRows; r++) {
|
|
782
|
+
frame.boxRow(3 + r, widths.map((w, i) => ({ text: ` ${columns[i]?.[view.scroll + r] ?? ""}`, width: w })));
|
|
783
|
+
}
|
|
784
|
+
paintCmdBar(frame, "metrics", cols, rows, live.bar);
|
|
785
|
+
frame.set(rows - 1, rule(cols, "└", "┘", []));
|
|
786
|
+
return frame;
|
|
787
|
+
}
|
|
788
|
+
/** Both reads are `qcr … --json` in the container — nothing writes. */
|
|
789
|
+
export class SshMetricsFetcher {
|
|
790
|
+
cfg;
|
|
791
|
+
ssh;
|
|
792
|
+
constructor(cfg, ssh) {
|
|
793
|
+
this.cfg = cfg;
|
|
794
|
+
this.ssh = ssh;
|
|
795
|
+
}
|
|
796
|
+
async read(argv) {
|
|
797
|
+
const res = await this.ssh(this.cfg.ssh_host, argv);
|
|
798
|
+
if (!res.ok)
|
|
799
|
+
return { error: res.stderr.trim().split("\n")[0] || `qcr exited ${res.code ?? "?"}` };
|
|
800
|
+
try {
|
|
801
|
+
return { payload: JSON.parse(res.stdout) };
|
|
802
|
+
}
|
|
803
|
+
catch {
|
|
804
|
+
return { error: "unparseable JSON from qcr metrics" };
|
|
805
|
+
}
|
|
806
|
+
}
|
|
807
|
+
overall() {
|
|
808
|
+
return this.read(metricsArgv(this.cfg));
|
|
809
|
+
}
|
|
810
|
+
timeline(pr) {
|
|
811
|
+
return this.read(metricsPrArgv(this.cfg, pr));
|
|
812
|
+
}
|
|
813
|
+
}
|
|
814
|
+
// ---- hooks ------------------------------------------------------------------
|
|
815
|
+
export const METRICS_TTL_MS = 60_000;
|
|
816
|
+
export function installMetricsHooks(app, fetcher, probe) {
|
|
817
|
+
const f = fetcher ?? new SshMetricsFetcher(app.cfg, app.ssh);
|
|
818
|
+
const view = { window: "d7", loading: false, scroll: 0, dryRun: app.view.dryRun };
|
|
819
|
+
let fetchedAt = 0;
|
|
820
|
+
let lastFrame;
|
|
821
|
+
const timelineCache = new Map();
|
|
822
|
+
const load = async (force = false) => {
|
|
823
|
+
if (view.loading)
|
|
824
|
+
return;
|
|
825
|
+
// Gate on fetch time alone: a failed fetch must also wait out the TTL, or
|
|
826
|
+
// error -> repaint -> load would spin forever and the app could never quit.
|
|
827
|
+
if (!force && fetchedAt && Date.now() - fetchedAt < METRICS_TTL_MS)
|
|
828
|
+
return;
|
|
829
|
+
view.loading = true;
|
|
830
|
+
try {
|
|
831
|
+
const res = await f.overall();
|
|
832
|
+
if (res.payload) {
|
|
833
|
+
view.payload = res.payload;
|
|
834
|
+
view.error = undefined;
|
|
835
|
+
fetchedAt = Date.now();
|
|
836
|
+
// Local git answers "is a deploy needed?" against the sha the VM
|
|
837
|
+
// reports. No probe (or a repo-less machine) simply omits the line.
|
|
838
|
+
if (probe) {
|
|
839
|
+
try {
|
|
840
|
+
view.local = await probe.read(res.payload.ops?.build?.sha ?? null);
|
|
841
|
+
}
|
|
842
|
+
catch {
|
|
843
|
+
view.local = undefined;
|
|
844
|
+
}
|
|
845
|
+
}
|
|
846
|
+
}
|
|
847
|
+
else {
|
|
848
|
+
view.error = res.error ?? "unknown error";
|
|
849
|
+
fetchedAt = Date.now();
|
|
850
|
+
}
|
|
851
|
+
}
|
|
852
|
+
finally {
|
|
853
|
+
view.loading = false;
|
|
854
|
+
}
|
|
855
|
+
app.repaint();
|
|
856
|
+
};
|
|
857
|
+
/** Bumped per drill: only the newest request's answer may land — a refresh
|
|
858
|
+
* pressed while a read is out must not be overwritten by the older read. */
|
|
859
|
+
let drillSeq = 0;
|
|
860
|
+
const drillTo = (pr, force = false) => {
|
|
861
|
+
const seq = ++drillSeq;
|
|
862
|
+
const cached = timelineCache.get(pr);
|
|
863
|
+
view.drill = { pr, payload: cached?.payload, loading: true };
|
|
864
|
+
view.scroll = 0;
|
|
865
|
+
if (!force && cached && Date.now() - cached.fetched_at < METRICS_TTL_MS) {
|
|
866
|
+
view.drill.loading = false;
|
|
867
|
+
app.repaint();
|
|
868
|
+
return;
|
|
869
|
+
}
|
|
870
|
+
void (async () => {
|
|
871
|
+
const res = await f.timeline(pr);
|
|
872
|
+
if (seq !== drillSeq || view.drill?.pr !== pr)
|
|
873
|
+
return;
|
|
874
|
+
if (res.payload) {
|
|
875
|
+
timelineCache.set(pr, { payload: res.payload, fetched_at: Date.now() });
|
|
876
|
+
view.drill = { pr, payload: res.payload, loading: false };
|
|
877
|
+
}
|
|
878
|
+
else {
|
|
879
|
+
view.drill = { pr, payload: cached?.payload, error: res.error, loading: false };
|
|
880
|
+
}
|
|
881
|
+
app.repaint();
|
|
882
|
+
})();
|
|
883
|
+
app.repaint();
|
|
884
|
+
};
|
|
885
|
+
const screen = (theApp, cols, rows) => {
|
|
886
|
+
view.dryRun = theApp.view.dryRun;
|
|
887
|
+
// TTL-gated: a repaint inside the window costs nothing. Started after this
|
|
888
|
+
// frame is written, never inside the paint: a TUI resumed on this tab
|
|
889
|
+
// paints it first, and nothing external may precede the first frame.
|
|
890
|
+
queueMicrotask(() => void load());
|
|
891
|
+
const frame = renderMetrics(view, cols, rows);
|
|
892
|
+
lastFrame = frame;
|
|
893
|
+
return frame;
|
|
894
|
+
};
|
|
895
|
+
const click = (theApp, x, y) => {
|
|
896
|
+
if (!lastFrame)
|
|
897
|
+
return false;
|
|
898
|
+
const action = hitTest(lastFrame.zones, x, y);
|
|
899
|
+
if (action?.t !== "window")
|
|
900
|
+
return false;
|
|
901
|
+
view.window = action.window;
|
|
902
|
+
view.scroll = 0;
|
|
903
|
+
theApp.repaint();
|
|
904
|
+
return true;
|
|
905
|
+
};
|
|
906
|
+
const onKey = (theApp, key) => {
|
|
907
|
+
// PR-entry mode owns every printable key until enter or Esc.
|
|
908
|
+
if (view.prEntry !== undefined) {
|
|
909
|
+
const ch = keyChar(key);
|
|
910
|
+
if (key.kind === "escape")
|
|
911
|
+
view.prEntry = undefined;
|
|
912
|
+
else if (key.kind === "backspace")
|
|
913
|
+
view.prEntry = view.prEntry.slice(0, -1);
|
|
914
|
+
else if (key.kind === "enter") {
|
|
915
|
+
const pr = Number(view.prEntry);
|
|
916
|
+
view.prEntry = undefined;
|
|
917
|
+
if (Number.isFinite(pr) && pr > 0)
|
|
918
|
+
drillTo(pr);
|
|
919
|
+
}
|
|
920
|
+
else if (ch !== undefined && /^\d+$/.test(ch))
|
|
921
|
+
view.prEntry += ch; // a pasted run arrives whole
|
|
922
|
+
else if (key.kind === "quit")
|
|
923
|
+
return false;
|
|
924
|
+
theApp.repaint();
|
|
925
|
+
return true;
|
|
926
|
+
}
|
|
927
|
+
switch (key.kind) {
|
|
928
|
+
case "escape":
|
|
929
|
+
if (view.drill) {
|
|
930
|
+
view.drill = undefined;
|
|
931
|
+
view.scroll = 0;
|
|
932
|
+
theApp.repaint();
|
|
933
|
+
return true;
|
|
934
|
+
}
|
|
935
|
+
return false;
|
|
936
|
+
case "down":
|
|
937
|
+
case "up":
|
|
938
|
+
view.scroll = key.kind === "down" ? view.scroll + 1 : Math.max(0, view.scroll - 1);
|
|
939
|
+
theApp.repaint();
|
|
940
|
+
return true;
|
|
941
|
+
case "refresh":
|
|
942
|
+
if (view.drill)
|
|
943
|
+
drillTo(view.drill.pr, true);
|
|
944
|
+
else
|
|
945
|
+
void load(true);
|
|
946
|
+
theApp.repaint();
|
|
947
|
+
return true;
|
|
948
|
+
case "attach":
|
|
949
|
+
case "message":
|
|
950
|
+
case "char": {
|
|
951
|
+
// `a` and `m` decode as the board's verbs; `keyChar` folds them back
|
|
952
|
+
// to the letters this tab's switcher reads. A drill-down answers to
|
|
953
|
+
// Esc only; the dashboard's hotkeys are not its, so they reach the
|
|
954
|
+
// companion column from here.
|
|
955
|
+
if (view.drill)
|
|
956
|
+
return false;
|
|
957
|
+
const ch = keyChar(key);
|
|
958
|
+
const w = WINDOW_LABELS.find((x) => x.hotkey === ch);
|
|
959
|
+
if (w) {
|
|
960
|
+
view.window = w.key;
|
|
961
|
+
view.scroll = 0;
|
|
962
|
+
theApp.repaint();
|
|
963
|
+
return true;
|
|
964
|
+
}
|
|
965
|
+
if (ch === "#") {
|
|
966
|
+
view.prEntry = "";
|
|
967
|
+
theApp.repaint();
|
|
968
|
+
return true;
|
|
969
|
+
}
|
|
970
|
+
return false;
|
|
971
|
+
}
|
|
972
|
+
default:
|
|
973
|
+
return false; // tabs/quit/help fall through to the app
|
|
974
|
+
}
|
|
975
|
+
};
|
|
976
|
+
app.hooks.tabs.metrics = { screen, click, key: onKey, keys: () => metricsKeys(view) };
|
|
977
|
+
return view;
|
|
978
|
+
}
|
|
979
|
+
//# sourceMappingURL=metricstab.js.map
|