@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.
Files changed (1443) hide show
  1. package/LICENSE +23 -0
  2. package/README.md +385 -2
  3. package/THIRD-PARTY-NOTICES.md +134 -0
  4. package/agents/pass-abstraction.md +64 -0
  5. package/agents/pass-ask-human.md +134 -0
  6. package/agents/pass-backcompat.md +67 -0
  7. package/agents/pass-baseline.md +61 -0
  8. package/agents/pass-behaviour-delta.md +64 -0
  9. package/agents/pass-bounds.md +36 -0
  10. package/agents/pass-claims.md +31 -0
  11. package/agents/pass-concurrency.md +168 -0
  12. package/agents/pass-consistency.md +57 -0
  13. package/agents/pass-contracts.md +30 -0
  14. package/agents/pass-data-safety.md +54 -0
  15. package/agents/pass-deferred.md +35 -0
  16. package/agents/pass-delivery.md +37 -0
  17. package/agents/pass-duplication.md +60 -0
  18. package/agents/pass-intent.md +63 -0
  19. package/agents/pass-lint-conformance.md +46 -0
  20. package/agents/pass-maintainability.md +67 -0
  21. package/agents/pass-placement.md +68 -0
  22. package/agents/pass-prod-risk.md +24 -0
  23. package/agents/pass-rollout.md +32 -0
  24. package/agents/pass-roundtrip.md +46 -0
  25. package/agents/pass-security.md +31 -0
  26. package/agents/pass-simplicity.md +68 -0
  27. package/agents/pass-statelessness.md +27 -0
  28. package/agents/pass-style.md +37 -0
  29. package/agents/pass-sweep.md +57 -0
  30. package/agents/pass-tests.md +58 -0
  31. package/agents/pass-ui.md +23 -0
  32. package/agents/pass-validate.md +50 -0
  33. package/agents/pass-widened.md +46 -0
  34. package/agents/scan/pass-scan.md +86 -0
  35. package/bin/qcr.js +11 -0
  36. package/config.example.toml +1067 -0
  37. package/deploy/ansible/README.md +356 -0
  38. package/deploy/ansible/group_vars/all.yml +212 -0
  39. package/deploy/ansible/inventory.example.ini +25 -0
  40. package/deploy/ansible/playbook.yml +360 -0
  41. package/deploy/collect-secrets.sh +289 -0
  42. package/deploy/collect-slack-secrets.mjs +1190 -0
  43. package/deploy/github-app-manifest.json +31 -0
  44. package/deploy/manifest.schema.json +75 -0
  45. package/deploy/qcr-update.sh +803 -0
  46. package/deploy/reviewer/AGENTS.override.md +12 -0
  47. package/dist/extensions/cli/bash-guard-ambient.js +42 -0
  48. package/dist/extensions/cli/bash-guard-ambient.js.map +1 -0
  49. package/dist/extensions/cli/bash-guard.js +5 -0
  50. package/dist/extensions/cli/bash-guard.js.map +1 -0
  51. package/dist/extensions/cli/companion-guard.js +5 -0
  52. package/dist/extensions/cli/companion-guard.js.map +1 -0
  53. package/dist/extensions/cli/debug-round.js +8 -0
  54. package/dist/extensions/cli/debug-round.js.map +1 -0
  55. package/dist/extensions/cli/inject-bridge.js +5 -0
  56. package/dist/extensions/cli/inject-bridge.js.map +1 -0
  57. package/dist/extensions/cli/ledger-pin.js +5 -0
  58. package/dist/extensions/cli/ledger-pin.js.map +1 -0
  59. package/dist/extensions/cli/lens.js +13 -0
  60. package/dist/extensions/cli/lens.js.map +1 -0
  61. package/dist/extensions/cli/muted-theme.js +5 -0
  62. package/dist/extensions/cli/muted-theme.js.map +1 -0
  63. package/dist/extensions/cli/onboarding.js +5 -0
  64. package/dist/extensions/cli/onboarding.js.map +1 -0
  65. package/dist/extensions/cli/setup.js +5 -0
  66. package/dist/extensions/cli/setup.js.map +1 -0
  67. package/dist/extensions/cli/tui-view.js +5 -0
  68. package/dist/extensions/cli/tui-view.js.map +1 -0
  69. package/dist/extensions/companion-guard.js +361 -0
  70. package/dist/extensions/companion-guard.js.map +1 -0
  71. package/dist/extensions/debug-round.js +204 -0
  72. package/dist/extensions/debug-round.js.map +1 -0
  73. package/dist/extensions/inject-bridge.js +603 -0
  74. package/dist/extensions/inject-bridge.js.map +1 -0
  75. package/dist/extensions/muted-theme.js +12 -0
  76. package/dist/extensions/muted-theme.js.map +1 -0
  77. package/dist/extensions/onboarding.js +175 -0
  78. package/dist/extensions/onboarding.js.map +1 -0
  79. package/dist/extensions/setup-replay.js +269 -0
  80. package/dist/extensions/setup-replay.js.map +1 -0
  81. package/dist/extensions/setup-scan.js +998 -0
  82. package/dist/extensions/setup-scan.js.map +1 -0
  83. package/dist/extensions/setup-triage.js +175 -0
  84. package/dist/extensions/setup-triage.js.map +1 -0
  85. package/dist/extensions/setup.js +1160 -0
  86. package/dist/extensions/setup.js.map +1 -0
  87. package/dist/extensions/tui-view.js +389 -0
  88. package/dist/extensions/tui-view.js.map +1 -0
  89. package/dist/extensions/vendor/openviking-pi/client.js +376 -0
  90. package/dist/extensions/vendor/openviking-pi/client.js.map +1 -0
  91. package/dist/extensions/vendor/openviking-pi/config.js +189 -0
  92. package/dist/extensions/vendor/openviking-pi/config.js.map +1 -0
  93. package/dist/extensions/vendor/openviking-pi/index.js +421 -0
  94. package/dist/extensions/vendor/openviking-pi/index.js.map +1 -0
  95. package/dist/extensions/vendor/openviking-pi/lib/capture-adapter.mjs +86 -0
  96. package/dist/extensions/vendor/openviking-pi/lib/capture-adapter.mjs.map +1 -0
  97. package/dist/extensions/vendor/openviking-pi/lib/takeover-core.mjs +408 -0
  98. package/dist/extensions/vendor/openviking-pi/lib/takeover-core.mjs.map +1 -0
  99. package/dist/extensions/vendor/openviking-pi/lib/uri-guard-adapter.mjs +41 -0
  100. package/dist/extensions/vendor/openviking-pi/lib/uri-guard-adapter.mjs.map +1 -0
  101. package/dist/extensions/vendor/openviking-pi/qcr-hint.js +290 -0
  102. package/dist/extensions/vendor/openviking-pi/qcr-hint.js.map +1 -0
  103. package/dist/extensions/vendor/openviking-pi/qcr-honest.js +148 -0
  104. package/dist/extensions/vendor/openviking-pi/qcr-honest.js.map +1 -0
  105. package/dist/extensions/vendor/openviking-pi/qcr-hooks.js +68 -0
  106. package/dist/extensions/vendor/openviking-pi/qcr-hooks.js.map +1 -0
  107. package/dist/extensions/vendor/openviking-pi/qcr-leaf.js +77 -0
  108. package/dist/extensions/vendor/openviking-pi/qcr-leaf.js.map +1 -0
  109. package/dist/extensions/vendor/openviking-pi/qcr-lesson.js +216 -0
  110. package/dist/extensions/vendor/openviking-pi/qcr-lesson.js.map +1 -0
  111. package/dist/extensions/vendor/openviking-pi/qcr-namespaces.js +154 -0
  112. package/dist/extensions/vendor/openviking-pi/qcr-namespaces.js.map +1 -0
  113. package/dist/extensions/vendor/openviking-pi/qcr-recall.js +254 -0
  114. package/dist/extensions/vendor/openviking-pi/qcr-recall.js.map +1 -0
  115. package/dist/extensions/vendor/openviking-pi/qcr-shim.js +94 -0
  116. package/dist/extensions/vendor/openviking-pi/qcr-shim.js.map +1 -0
  117. package/dist/extensions/vendor/openviking-pi/qcr-write.js +333 -0
  118. package/dist/extensions/vendor/openviking-pi/qcr-write.js.map +1 -0
  119. package/dist/extensions/vendor/openviking-pi/recall.js +108 -0
  120. package/dist/extensions/vendor/openviking-pi/recall.js.map +1 -0
  121. package/dist/extensions/vendor/openviking-pi/shared/capture-utils.mjs +529 -0
  122. package/dist/extensions/vendor/openviking-pi/shared/capture-utils.mjs.map +1 -0
  123. package/dist/extensions/vendor/openviking-pi/shared/credentials.mjs +205 -0
  124. package/dist/extensions/vendor/openviking-pi/shared/credentials.mjs.map +1 -0
  125. package/dist/extensions/vendor/openviking-pi/shared/pending-queue.mjs +442 -0
  126. package/dist/extensions/vendor/openviking-pi/shared/pending-queue.mjs.map +1 -0
  127. package/dist/extensions/vendor/openviking-pi/shared/profile-inject.mjs +286 -0
  128. package/dist/extensions/vendor/openviking-pi/shared/profile-inject.mjs.map +1 -0
  129. package/dist/extensions/vendor/openviking-pi/shared/recall-compress-core.mjs +189 -0
  130. package/dist/extensions/vendor/openviking-pi/shared/recall-compress-core.mjs.map +1 -0
  131. package/dist/extensions/vendor/openviking-pi/shared/recall-core.mjs +580 -0
  132. package/dist/extensions/vendor/openviking-pi/shared/recall-core.mjs.map +1 -0
  133. package/dist/extensions/vendor/openviking-pi/shared/retryable.mjs +11 -0
  134. package/dist/extensions/vendor/openviking-pi/shared/retryable.mjs.map +1 -0
  135. package/dist/extensions/vendor/openviking-pi/shared/session-model.mjs +63 -0
  136. package/dist/extensions/vendor/openviking-pi/shared/session-model.mjs.map +1 -0
  137. package/dist/extensions/vendor/openviking-pi/shared/uri-guard.mjs +58 -0
  138. package/dist/extensions/vendor/openviking-pi/shared/uri-guard.mjs.map +1 -0
  139. package/dist/extensions/vendor/openviking-pi/shared/workspace-peer.mjs +16 -0
  140. package/dist/extensions/vendor/openviking-pi/shared/workspace-peer.mjs.map +1 -0
  141. package/dist/extensions/vendor/openviking-pi/sync.js +127 -0
  142. package/dist/extensions/vendor/openviking-pi/sync.js.map +1 -0
  143. package/dist/extensions/vendor/openviking-pi/takeover.js +25 -0
  144. package/dist/extensions/vendor/openviking-pi/takeover.js.map +1 -0
  145. package/dist/extensions/vendor/openviking-pi/tools.js +417 -0
  146. package/dist/extensions/vendor/openviking-pi/tools.js.map +1 -0
  147. package/dist/src/anomalies.js +483 -0
  148. package/dist/src/anomalies.js.map +1 -0
  149. package/dist/src/answerworker.js +180 -0
  150. package/dist/src/answerworker.js.map +1 -0
  151. package/dist/src/appstamp.js +68 -0
  152. package/dist/src/appstamp.js.map +1 -0
  153. package/dist/src/archive/admission.js +3 -0
  154. package/dist/src/archive/admission.js.map +1 -0
  155. package/dist/src/archive/archivedb.js +474 -0
  156. package/dist/src/archive/archivedb.js.map +1 -0
  157. package/dist/src/archive/archiver.js +1770 -0
  158. package/dist/src/archive/archiver.js.map +1 -0
  159. package/dist/src/archive/archivewrite.js +198 -0
  160. package/dist/src/archive/archivewrite.js.map +1 -0
  161. package/dist/src/archive/bundle.js +266 -0
  162. package/dist/src/archive/bundle.js.map +1 -0
  163. package/dist/src/archive/dbmove.js +638 -0
  164. package/dist/src/archive/dbmove.js.map +1 -0
  165. package/dist/src/archive/duplicatecounts.js +80 -0
  166. package/dist/src/archive/duplicatecounts.js.map +1 -0
  167. package/dist/src/archive/eligibility.js +113 -0
  168. package/dist/src/archive/eligibility.js.map +1 -0
  169. package/dist/src/archive/extract.js +288 -0
  170. package/dist/src/archive/extract.js.map +1 -0
  171. package/dist/src/archive/fsutil.js +330 -0
  172. package/dist/src/archive/fsutil.js.map +1 -0
  173. package/dist/src/archive/gzfile.js +277 -0
  174. package/dist/src/archive/gzfile.js.map +1 -0
  175. package/dist/src/archive/kinds.js +22 -0
  176. package/dist/src/archive/kinds.js.map +1 -0
  177. package/dist/src/archive/livecheckpoint.js +178 -0
  178. package/dist/src/archive/livecheckpoint.js.map +1 -0
  179. package/dist/src/archive/liveretention.js +145 -0
  180. package/dist/src/archive/liveretention.js.map +1 -0
  181. package/dist/src/archive/manifest.js +284 -0
  182. package/dist/src/archive/manifest.js.map +1 -0
  183. package/dist/src/archive/overseer.js +283 -0
  184. package/dist/src/archive/overseer.js.map +1 -0
  185. package/dist/src/archive/piglobal.js +129 -0
  186. package/dist/src/archive/piglobal.js.map +1 -0
  187. package/dist/src/archive/plan.js +398 -0
  188. package/dist/src/archive/plan.js.map +1 -0
  189. package/dist/src/archive/prarchive.js +831 -0
  190. package/dist/src/archive/prarchive.js.map +1 -0
  191. package/dist/src/archive/prfiles.js +303 -0
  192. package/dist/src/archive/prfiles.js.map +1 -0
  193. package/dist/src/archive/report.js +169 -0
  194. package/dist/src/archive/report.js.map +1 -0
  195. package/dist/src/archive/restore.js +276 -0
  196. package/dist/src/archive/restore.js.map +1 -0
  197. package/dist/src/archive/rows.js +106 -0
  198. package/dist/src/archive/rows.js.map +1 -0
  199. package/dist/src/archive/seal.js +480 -0
  200. package/dist/src/archive/seal.js.map +1 -0
  201. package/dist/src/archive/status.js +528 -0
  202. package/dist/src/archive/status.js.map +1 -0
  203. package/dist/src/archive/storepass.js +409 -0
  204. package/dist/src/archive/storepass.js.map +1 -0
  205. package/dist/src/backfill.js +217 -0
  206. package/dist/src/backfill.js.map +1 -0
  207. package/dist/src/bench/cost.js +87 -0
  208. package/dist/src/bench/exec.js +76 -0
  209. package/dist/src/bench/values.js +14 -0
  210. package/dist/src/botcontrol.js +127 -0
  211. package/dist/src/botcontrol.js.map +1 -0
  212. package/dist/src/botworker.js +805 -0
  213. package/dist/src/botworker.js.map +1 -0
  214. package/dist/src/capture.js +234 -0
  215. package/dist/src/capture.js.map +1 -0
  216. package/dist/src/cases.js +1491 -0
  217. package/dist/src/cases.js.map +1 -0
  218. package/dist/src/channelfs.js +27 -0
  219. package/dist/src/channelfs.js.map +1 -0
  220. package/dist/src/checklist.js +312 -0
  221. package/dist/src/checklist.js.map +1 -0
  222. package/dist/src/ciretry.js +91 -0
  223. package/dist/src/ciretry.js.map +1 -0
  224. package/dist/src/cli.js +1916 -0
  225. package/dist/src/cli.js.map +1 -0
  226. package/dist/src/cliops.js +333 -0
  227. package/dist/src/cliops.js.map +1 -0
  228. package/dist/src/clonedir.js +15 -0
  229. package/dist/src/clonedir.js.map +1 -0
  230. package/dist/src/commandeffects.js +43 -0
  231. package/dist/src/commandeffects.js.map +1 -0
  232. package/dist/src/commands.js +1312 -0
  233. package/dist/src/commands.js.map +1 -0
  234. package/dist/src/companioninbox.js +203 -0
  235. package/dist/src/companioninbox.js.map +1 -0
  236. package/dist/src/compare.js +673 -0
  237. package/dist/src/compare.js.map +1 -0
  238. package/dist/src/config.js +1027 -0
  239. package/dist/src/config.js.map +1 -0
  240. package/dist/src/configcheck.js +111 -0
  241. package/dist/src/configcheck.js.map +1 -0
  242. package/dist/src/coreext.js +43 -0
  243. package/dist/src/coreext.js.map +1 -0
  244. package/dist/src/daemon.js +929 -0
  245. package/dist/src/daemon.js.map +1 -0
  246. package/dist/src/debuground.js +731 -0
  247. package/dist/src/debuground.js.map +1 -0
  248. package/dist/src/debugroundpi.js +219 -0
  249. package/dist/src/debugroundpi.js.map +1 -0
  250. package/dist/src/diagnostics.js +14 -0
  251. package/dist/src/diagnostics.js.map +1 -0
  252. package/dist/src/digest.js +139 -0
  253. package/dist/src/digest.js.map +1 -0
  254. package/dist/src/dispatch.js +1726 -0
  255. package/dist/src/dispatch.js.map +1 -0
  256. package/dist/src/engine/answerguard.js +18 -0
  257. package/dist/src/engine/answerguard.js.map +1 -0
  258. package/dist/src/engine/botsdk.js +262 -0
  259. package/dist/src/engine/botsdk.js.map +1 -0
  260. package/dist/src/engine/caserunner-sdk.js +332 -0
  261. package/dist/src/engine/caserunner-sdk.js.map +1 -0
  262. package/dist/src/engine/debugpi.js +194 -0
  263. package/dist/src/engine/debugpi.js.map +1 -0
  264. package/dist/src/eod.js +473 -0
  265. package/dist/src/eod.js.map +1 -0
  266. package/dist/src/eodpinwatch.js +391 -0
  267. package/dist/src/eodpinwatch.js.map +1 -0
  268. package/dist/src/escalation.js +1009 -0
  269. package/dist/src/escalation.js.map +1 -0
  270. package/dist/src/eventloop.js +779 -0
  271. package/dist/src/eventloop.js.map +1 -0
  272. package/dist/src/execboundary.js +430 -0
  273. package/dist/src/execboundary.js.map +1 -0
  274. package/dist/src/feedback.js +915 -0
  275. package/dist/src/feedback.js.map +1 -0
  276. package/dist/src/findingscheck.js +200 -0
  277. package/dist/src/findingscheck.js.map +1 -0
  278. package/dist/src/fsdenied.js +26 -0
  279. package/dist/src/fsdenied.js.map +1 -0
  280. package/dist/src/ghread.js +181 -0
  281. package/dist/src/ghread.js.map +1 -0
  282. package/dist/src/github.js +1063 -0
  283. package/dist/src/github.js.map +1 -0
  284. package/dist/src/homes.js +103 -0
  285. package/dist/src/homes.js.map +1 -0
  286. package/dist/src/hostroute.js +24 -0
  287. package/dist/src/hostroute.js.map +1 -0
  288. package/dist/src/improvements.js +625 -0
  289. package/dist/src/improvements.js.map +1 -0
  290. package/dist/src/install.js +946 -0
  291. package/dist/src/install.js.map +1 -0
  292. package/dist/src/installkind.js +40 -0
  293. package/dist/src/installkind.js.map +1 -0
  294. package/dist/src/ipc/capability.js +286 -0
  295. package/dist/src/ipc/capability.js.map +1 -0
  296. package/dist/src/ipc/client.js +226 -0
  297. package/dist/src/ipc/client.js.map +1 -0
  298. package/dist/src/ipc/control.js +70 -0
  299. package/dist/src/ipc/control.js.map +1 -0
  300. package/dist/src/ipc/ghreadshim.js +77 -0
  301. package/dist/src/ipc/ghreadshim.js.map +1 -0
  302. package/dist/src/ipc/launcher.js +65 -0
  303. package/dist/src/ipc/launcher.js.map +1 -0
  304. package/dist/src/ipc/permits.js +293 -0
  305. package/dist/src/ipc/permits.js.map +1 -0
  306. package/dist/src/ipc/postshim.js +137 -0
  307. package/dist/src/ipc/postshim.js.map +1 -0
  308. package/dist/src/ipc/protocol.js +239 -0
  309. package/dist/src/ipc/protocol.js.map +1 -0
  310. package/dist/src/ipc/server.js +312 -0
  311. package/dist/src/ipc/server.js.map +1 -0
  312. package/dist/src/ipc/workerspec.js +148 -0
  313. package/dist/src/ipc/workerspec.js.map +1 -0
  314. package/dist/src/learner/learner.js +1272 -0
  315. package/dist/src/learner/learner.js.map +1 -0
  316. package/dist/src/learner/miner.js +948 -0
  317. package/dist/src/learner/miner.js.map +1 -0
  318. package/dist/src/learner/packet.js +216 -0
  319. package/dist/src/learner/packet.js.map +1 -0
  320. package/dist/src/learner/receipt.js +135 -0
  321. package/dist/src/learner/receipt.js.map +1 -0
  322. package/dist/src/learner/status.js +38 -0
  323. package/dist/src/learner/status.js.map +1 -0
  324. package/dist/src/ledgercheck.js +120 -0
  325. package/dist/src/ledgercheck.js.map +1 -0
  326. package/dist/src/lessonledger.js +451 -0
  327. package/dist/src/lessonledger.js.map +1 -0
  328. package/dist/src/lessonselect.js +639 -0
  329. package/dist/src/lessonselect.js.map +1 -0
  330. package/dist/src/lessonshadow.js +540 -0
  331. package/dist/src/lessonshadow.js.map +1 -0
  332. package/dist/src/levers.js +302 -0
  333. package/dist/src/levers.js.map +1 -0
  334. package/dist/src/live/projection.js +450 -0
  335. package/dist/src/live/projection.js.map +1 -0
  336. package/dist/src/live/publish.js +83 -0
  337. package/dist/src/live/publish.js.map +1 -0
  338. package/dist/src/live/read.js +60 -0
  339. package/dist/src/live/read.js.map +1 -0
  340. package/dist/src/livecli.js +288 -0
  341. package/dist/src/livecli.js.map +1 -0
  342. package/dist/src/loginhint.js +42 -0
  343. package/dist/src/loginhint.js.map +1 -0
  344. package/dist/src/loginrefresh/atomic.js +66 -0
  345. package/dist/src/loginrefresh/atomic.js.map +1 -0
  346. package/dist/src/loginrefresh/lock.js +93 -0
  347. package/dist/src/loginrefresh/lock.js.map +1 -0
  348. package/dist/src/loginrefresh/main.js +58 -0
  349. package/dist/src/loginrefresh/main.js.map +1 -0
  350. package/dist/src/loginrefresh/pirefresh.js +49 -0
  351. package/dist/src/loginrefresh/pirefresh.js.map +1 -0
  352. package/dist/src/loginrefresh/refresher.js +286 -0
  353. package/dist/src/loginrefresh/refresher.js.map +1 -0
  354. package/dist/src/loginrefresh/supervisor.js +253 -0
  355. package/dist/src/loginrefresh/supervisor.js.map +1 -0
  356. package/dist/src/loginrefresh/types.js +4 -0
  357. package/dist/src/loginrefresh/types.js.map +1 -0
  358. package/dist/src/memory/context.js +251 -0
  359. package/dist/src/memory/context.js.map +1 -0
  360. package/dist/src/memory/datafence.js +5 -0
  361. package/dist/src/memory/datafence.js.map +1 -0
  362. package/dist/src/memory/delivery.js +131 -0
  363. package/dist/src/memory/delivery.js.map +1 -0
  364. package/dist/src/memory/eventtags.js +81 -0
  365. package/dist/src/memory/eventtags.js.map +1 -0
  366. package/dist/src/memory/health.js +713 -0
  367. package/dist/src/memory/health.js.map +1 -0
  368. package/dist/src/memory/import.js +504 -0
  369. package/dist/src/memory/import.js.map +1 -0
  370. package/dist/src/memory/layout.js +252 -0
  371. package/dist/src/memory/layout.js.map +1 -0
  372. package/dist/src/memory/legacy-file.js +100 -0
  373. package/dist/src/memory/legacy-file.js.map +1 -0
  374. package/dist/src/memory/lessons.js +370 -0
  375. package/dist/src/memory/lessons.js.map +1 -0
  376. package/dist/src/memory/ovsession.js +449 -0
  377. package/dist/src/memory/ovsession.js.map +1 -0
  378. package/dist/src/memory/relayout.js +259 -0
  379. package/dist/src/memory/relayout.js.map +1 -0
  380. package/dist/src/memory/roundactivity.js +180 -0
  381. package/dist/src/memory/roundactivity.js.map +1 -0
  382. package/dist/src/memory/selection.js +690 -0
  383. package/dist/src/memory/selection.js.map +1 -0
  384. package/dist/src/memory/shadowstatus.js +69 -0
  385. package/dist/src/memory/shadowstatus.js.map +1 -0
  386. package/dist/src/memory/store.js +83 -0
  387. package/dist/src/memory/store.js.map +1 -0
  388. package/dist/src/memory/textidentity.js +8 -0
  389. package/dist/src/memory/textidentity.js.map +1 -0
  390. package/dist/src/metrics.js +773 -0
  391. package/dist/src/metrics.js.map +1 -0
  392. package/dist/src/missingconfig.js +8 -0
  393. package/dist/src/missingconfig.js.map +1 -0
  394. package/dist/src/npmverbs.js +226 -0
  395. package/dist/src/npmverbs.js.map +1 -0
  396. package/dist/src/onboard/choices.js +191 -0
  397. package/dist/src/onboard/choices.js.map +1 -0
  398. package/dist/src/onboard/engine.js +344 -0
  399. package/dist/src/onboard/engine.js.map +1 -0
  400. package/dist/src/onboard/launch.js +83 -0
  401. package/dist/src/onboard/launch.js.map +1 -0
  402. package/dist/src/onboard/steps/appslug.js +211 -0
  403. package/dist/src/onboard/steps/appslug.js.map +1 -0
  404. package/dist/src/onboard/steps/bringup.js +408 -0
  405. package/dist/src/onboard/steps/bringup.js.map +1 -0
  406. package/dist/src/onboard/steps/compose.js +343 -0
  407. package/dist/src/onboard/steps/compose.js.map +1 -0
  408. package/dist/src/onboard/steps/configdelivery.js +50 -0
  409. package/dist/src/onboard/steps/configdelivery.js.map +1 -0
  410. package/dist/src/onboard/steps/configfill.js +1148 -0
  411. package/dist/src/onboard/steps/configfill.js.map +1 -0
  412. package/dist/src/onboard/steps/deploysh.js +80 -0
  413. package/dist/src/onboard/steps/deploysh.js.map +1 -0
  414. package/dist/src/onboard/steps/embeddings.js +472 -0
  415. package/dist/src/onboard/steps/embeddings.js.map +1 -0
  416. package/dist/src/onboard/steps/escalation.js +571 -0
  417. package/dist/src/onboard/steps/escalation.js.map +1 -0
  418. package/dist/src/onboard/steps/githubapp.js +1092 -0
  419. package/dist/src/onboard/steps/githubapp.js.map +1 -0
  420. package/dist/src/onboard/steps/golive.js +506 -0
  421. package/dist/src/onboard/steps/golive.js.map +1 -0
  422. package/dist/src/onboard/steps/index.js +67 -0
  423. package/dist/src/onboard/steps/index.js.map +1 -0
  424. package/dist/src/onboard/steps/ingress.js +762 -0
  425. package/dist/src/onboard/steps/ingress.js.map +1 -0
  426. package/dist/src/onboard/steps/inventory.js +420 -0
  427. package/dist/src/onboard/steps/inventory.js.map +1 -0
  428. package/dist/src/onboard/steps/llmauth.js +893 -0
  429. package/dist/src/onboard/steps/llmauth.js.map +1 -0
  430. package/dist/src/onboard/steps/memory.js +1060 -0
  431. package/dist/src/onboard/steps/memory.js.map +1 -0
  432. package/dist/src/onboard/steps/memorykeys.js +43 -0
  433. package/dist/src/onboard/steps/memorykeys.js.map +1 -0
  434. package/dist/src/onboard/steps/preflight.js +172 -0
  435. package/dist/src/onboard/steps/preflight.js.map +1 -0
  436. package/dist/src/onboard/steps/proof.js +502 -0
  437. package/dist/src/onboard/steps/proof.js.map +1 -0
  438. package/dist/src/onboard/steps/ssh.js +300 -0
  439. package/dist/src/onboard/steps/ssh.js.map +1 -0
  440. package/dist/src/onboard/steps/topology.js +291 -0
  441. package/dist/src/onboard/steps/topology.js.map +1 -0
  442. package/dist/src/onboard/steps/transport.js +511 -0
  443. package/dist/src/onboard/steps/transport.js.map +1 -0
  444. package/dist/src/onboard/steps/verifyup.js +362 -0
  445. package/dist/src/onboard/steps/verifyup.js.map +1 -0
  446. package/dist/src/onboard/steps/vmdeploy.js +368 -0
  447. package/dist/src/onboard/steps/vmdeploy.js.map +1 -0
  448. package/dist/src/onboard/toml.js +53 -0
  449. package/dist/src/onboard/toml.js.map +1 -0
  450. package/dist/src/opencli.js +508 -0
  451. package/dist/src/opencli.js.map +1 -0
  452. package/dist/src/openpr.js +457 -0
  453. package/dist/src/openpr.js.map +1 -0
  454. package/dist/src/openviking/client.js +821 -0
  455. package/dist/src/openviking/client.js.map +1 -0
  456. package/dist/src/openviking/context.js +218 -0
  457. package/dist/src/openviking/context.js.map +1 -0
  458. package/dist/src/openviking/embedder.js +457 -0
  459. package/dist/src/openviking/embedder.js.map +1 -0
  460. package/dist/src/openviking/gapsink.js +38 -0
  461. package/dist/src/openviking/gapsink.js.map +1 -0
  462. package/dist/src/openviking/health.js +69 -0
  463. package/dist/src/openviking/health.js.map +1 -0
  464. package/dist/src/openviking/index.js +24 -0
  465. package/dist/src/openviking/index.js.map +1 -0
  466. package/dist/src/openviking/lessonfind.js +54 -0
  467. package/dist/src/openviking/lessonfind.js.map +1 -0
  468. package/dist/src/openviking/probe.js +89 -0
  469. package/dist/src/openviking/probe.js.map +1 -0
  470. package/dist/src/openviking/proc.js +95 -0
  471. package/dist/src/openviking/proc.js.map +1 -0
  472. package/dist/src/openviking/provisionreport.js +144 -0
  473. package/dist/src/openviking/provisionreport.js.map +1 -0
  474. package/dist/src/openviking/reembed.js +317 -0
  475. package/dist/src/openviking/reembed.js.map +1 -0
  476. package/dist/src/openviking/relayout.js +153 -0
  477. package/dist/src/openviking/relayout.js.map +1 -0
  478. package/dist/src/openviking/sidecar-main.js +39 -0
  479. package/dist/src/openviking/sidecar-main.js.map +1 -0
  480. package/dist/src/openviking/sidecar.js +79 -0
  481. package/dist/src/openviking/sidecar.js.map +1 -0
  482. package/dist/src/openviking/store.js +1758 -0
  483. package/dist/src/openviking/store.js.map +1 -0
  484. package/dist/src/openviking/supervisor.js +422 -0
  485. package/dist/src/openviking/supervisor.js.map +1 -0
  486. package/dist/src/openviking/types.js +5 -0
  487. package/dist/src/openviking/types.js.map +1 -0
  488. package/dist/src/operator-recovery.js +172 -0
  489. package/dist/src/operator-recovery.js.map +1 -0
  490. package/dist/src/operatormessage.js +44 -0
  491. package/dist/src/operatormessage.js.map +1 -0
  492. package/dist/src/outcomes.js +1361 -0
  493. package/dist/src/outcomes.js.map +1 -0
  494. package/dist/src/piauthcopy.js +5 -0
  495. package/dist/src/piauthcopy.js.map +1 -0
  496. package/dist/src/picli.js +45 -0
  497. package/dist/src/picli.js.map +1 -0
  498. package/dist/src/picwd.js +25 -0
  499. package/dist/src/picwd.js.map +1 -0
  500. package/dist/src/pilogin.js +35 -0
  501. package/dist/src/pilogin.js.map +1 -0
  502. package/dist/src/pingpong.js +1028 -0
  503. package/dist/src/pingpong.js.map +1 -0
  504. package/dist/src/posting-journal.js +441 -0
  505. package/dist/src/posting-journal.js.map +1 -0
  506. package/dist/src/posting-outbox.js +662 -0
  507. package/dist/src/posting-outbox.js.map +1 -0
  508. package/dist/src/posting-receipt.js +203 -0
  509. package/dist/src/posting-receipt.js.map +1 -0
  510. package/dist/src/posting.js +348 -0
  511. package/dist/src/posting.js.map +1 -0
  512. package/dist/src/postops.js +637 -0
  513. package/dist/src/postops.js.map +1 -0
  514. package/dist/src/pr-activity.js +11 -0
  515. package/dist/src/pr-activity.js.map +1 -0
  516. package/dist/src/pr-author.js +5 -0
  517. package/dist/src/pr-author.js.map +1 -0
  518. package/dist/src/pr-conversation.js +355 -0
  519. package/dist/src/pr-conversation.js.map +1 -0
  520. package/dist/src/pr-session-lifecycle.js +542 -0
  521. package/dist/src/pr-session-lifecycle.js.map +1 -0
  522. package/dist/src/preflight.js +341 -0
  523. package/dist/src/preflight.js.map +1 -0
  524. package/dist/src/priorresolve.js +275 -0
  525. package/dist/src/priorresolve.js.map +1 -0
  526. package/dist/src/qcrbin.js +180 -0
  527. package/dist/src/qcrbin.js.map +1 -0
  528. package/dist/src/recheck.js +1398 -0
  529. package/dist/src/recheck.js.map +1 -0
  530. package/dist/src/reconcile.js +820 -0
  531. package/dist/src/reconcile.js.map +1 -0
  532. package/dist/src/recordedfindings.js +15 -0
  533. package/dist/src/recordedfindings.js.map +1 -0
  534. package/dist/src/regression.js +546 -0
  535. package/dist/src/regression.js.map +1 -0
  536. package/dist/src/replay.js +598 -0
  537. package/dist/src/replay.js.map +1 -0
  538. package/dist/src/requiredpasses.js +113 -0
  539. package/dist/src/requiredpasses.js.map +1 -0
  540. package/dist/src/resumecheck.js +168 -0
  541. package/dist/src/resumecheck.js.map +1 -0
  542. package/dist/src/reviewcli.js +671 -0
  543. package/dist/src/reviewcli.js.map +1 -0
  544. package/dist/src/reviewcontext.js +22 -0
  545. package/dist/src/reviewcontext.js.map +1 -0
  546. package/dist/src/reviewdetach.js +574 -0
  547. package/dist/src/reviewdetach.js.map +1 -0
  548. package/dist/src/reviewhistory.js +284 -0
  549. package/dist/src/reviewhistory.js.map +1 -0
  550. package/dist/src/reviewhome.js +26 -0
  551. package/dist/src/reviewhome.js.map +1 -0
  552. package/dist/src/reviewmemory.js +110 -0
  553. package/dist/src/reviewmemory.js.map +1 -0
  554. package/dist/src/reviewrendercli.js +104 -0
  555. package/dist/src/reviewrendercli.js.map +1 -0
  556. package/dist/src/round-work.js +20 -0
  557. package/dist/src/round-work.js.map +1 -0
  558. package/dist/src/runhost.js +72 -0
  559. package/dist/src/runhost.js.map +1 -0
  560. package/dist/src/scanauth.js +25 -0
  561. package/dist/src/scanauth.js.map +1 -0
  562. package/dist/src/scanbox.js +846 -0
  563. package/dist/src/scanbox.js.map +1 -0
  564. package/dist/src/scancli.js +1074 -0
  565. package/dist/src/scancli.js.map +1 -0
  566. package/dist/src/scandriverlog.js +30 -0
  567. package/dist/src/scandriverlog.js.map +1 -0
  568. package/dist/src/session-bridge.js +75 -0
  569. package/dist/src/session-bridge.js.map +1 -0
  570. package/dist/src/session-command-payload.js +29 -0
  571. package/dist/src/session-command-payload.js.map +1 -0
  572. package/dist/src/session-command-supervisor.js +939 -0
  573. package/dist/src/session-command-supervisor.js.map +1 -0
  574. package/dist/src/sessionjsonl.js +85 -0
  575. package/dist/src/sessionjsonl.js.map +1 -0
  576. package/dist/src/sessions.js +541 -0
  577. package/dist/src/sessions.js.map +1 -0
  578. package/dist/src/setup/adapters.js +330 -0
  579. package/dist/src/setup/adapters.js.map +1 -0
  580. package/dist/src/setup/baselines.js +64 -0
  581. package/dist/src/setup/baselines.js.map +1 -0
  582. package/dist/src/setup/caserunner.js +554 -0
  583. package/dist/src/setup/caserunner.js.map +1 -0
  584. package/dist/src/setup/configcommit.js +358 -0
  585. package/dist/src/setup/configcommit.js.map +1 -0
  586. package/dist/src/setup/engine.js +672 -0
  587. package/dist/src/setup/engine.js.map +1 -0
  588. package/dist/src/setup/facts.js +593 -0
  589. package/dist/src/setup/facts.js.map +1 -0
  590. package/dist/src/setup/findings.js +948 -0
  591. package/dist/src/setup/findings.js.map +1 -0
  592. package/dist/src/setup/history.js +338 -0
  593. package/dist/src/setup/history.js.map +1 -0
  594. package/dist/src/setup/interview.js +185 -0
  595. package/dist/src/setup/interview.js.map +1 -0
  596. package/dist/src/setup/ledger.js +207 -0
  597. package/dist/src/setup/ledger.js.map +1 -0
  598. package/dist/src/setup/pins.js +43 -0
  599. package/dist/src/setup/pins.js.map +1 -0
  600. package/dist/src/setup/portrait.js +432 -0
  601. package/dist/src/setup/portrait.js.map +1 -0
  602. package/dist/src/setup/presentation.js +9 -0
  603. package/dist/src/setup/presentation.js.map +1 -0
  604. package/dist/src/setup/profile.js +417 -0
  605. package/dist/src/setup/profile.js.map +1 -0
  606. package/dist/src/setup/replay.js +240 -0
  607. package/dist/src/setup/replay.js.map +1 -0
  608. package/dist/src/setup/replaybuild.js +311 -0
  609. package/dist/src/setup/replaybuild.js.map +1 -0
  610. package/dist/src/setup/replayrun.js +806 -0
  611. package/dist/src/setup/replayrun.js.map +1 -0
  612. package/dist/src/setup/replaysource.js +169 -0
  613. package/dist/src/setup/replaysource.js.map +1 -0
  614. package/dist/src/setup/retune.js +333 -0
  615. package/dist/src/setup/retune.js.map +1 -0
  616. package/dist/src/setup/retunelog.js +51 -0
  617. package/dist/src/setup/retunelog.js.map +1 -0
  618. package/dist/src/setup/scan.js +725 -0
  619. package/dist/src/setup/scan.js.map +1 -0
  620. package/dist/src/setup/scanbuild.js +133 -0
  621. package/dist/src/setup/scanbuild.js.map +1 -0
  622. package/dist/src/setup/scanfacts.js +96 -0
  623. package/dist/src/setup/scanfacts.js.map +1 -0
  624. package/dist/src/setup/scanlease.js +251 -0
  625. package/dist/src/setup/scanlease.js.map +1 -0
  626. package/dist/src/setup/scanreport.js +289 -0
  627. package/dist/src/setup/scanreport.js.map +1 -0
  628. package/dist/src/setup/scanrun.js +1733 -0
  629. package/dist/src/setup/scanrun.js.map +1 -0
  630. package/dist/src/setup/scantree.js +257 -0
  631. package/dist/src/setup/scantree.js.map +1 -0
  632. package/dist/src/setup/stage2.js +617 -0
  633. package/dist/src/setup/stage2.js.map +1 -0
  634. package/dist/src/setup/stage2request.js +259 -0
  635. package/dist/src/setup/stage2request.js.map +1 -0
  636. package/dist/src/setup/survey.js +307 -0
  637. package/dist/src/setup/survey.js.map +1 -0
  638. package/dist/src/setup/surveyrun.js +549 -0
  639. package/dist/src/setup/surveyrun.js.map +1 -0
  640. package/dist/src/setup/textsniff.js +89 -0
  641. package/dist/src/setup/textsniff.js.map +1 -0
  642. package/dist/src/setup/trackersink.js +395 -0
  643. package/dist/src/setup/trackersink.js.map +1 -0
  644. package/dist/src/setup/triage.js +636 -0
  645. package/dist/src/setup/triage.js.map +1 -0
  646. package/dist/src/setup/tuning.js +585 -0
  647. package/dist/src/setup/tuning.js.map +1 -0
  648. package/dist/src/setup/unitcut.js +437 -0
  649. package/dist/src/setup/unitcut.js.map +1 -0
  650. package/dist/src/singleflight.js +72 -0
  651. package/dist/src/singleflight.js.map +1 -0
  652. package/dist/src/slack/announce.js +725 -0
  653. package/dist/src/slack/announce.js.map +1 -0
  654. package/dist/src/slack/api.js +227 -0
  655. package/dist/src/slack/api.js.map +1 -0
  656. package/dist/src/slack/messages.js +158 -0
  657. package/dist/src/slack/messages.js.map +1 -0
  658. package/dist/src/slack/origin.js +550 -0
  659. package/dist/src/slack/origin.js.map +1 -0
  660. package/dist/src/slack/policy.js +225 -0
  661. package/dist/src/slack/policy.js.map +1 -0
  662. package/dist/src/slack/reply.js +153 -0
  663. package/dist/src/slack/reply.js.map +1 -0
  664. package/dist/src/slack/router.js +189 -0
  665. package/dist/src/slack/router.js.map +1 -0
  666. package/dist/src/slack/socket.js +323 -0
  667. package/dist/src/slack/socket.js.map +1 -0
  668. package/dist/src/slack/types.js +11 -0
  669. package/dist/src/slack/types.js.map +1 -0
  670. package/dist/src/sqlitehint.js +30 -0
  671. package/dist/src/sqlitehint.js.map +1 -0
  672. package/dist/src/ssh-observation.js +25 -0
  673. package/dist/src/ssh-observation.js.map +1 -0
  674. package/dist/src/state.js +5869 -0
  675. package/dist/src/state.js.map +1 -0
  676. package/dist/src/statemachine.js +220 -0
  677. package/dist/src/statemachine.js.map +1 -0
  678. package/dist/src/stubs.js +52 -0
  679. package/dist/src/stubs.js.map +1 -0
  680. package/dist/src/takeover.js +506 -0
  681. package/dist/src/takeover.js.map +1 -0
  682. package/dist/src/takeoverpi.js +249 -0
  683. package/dist/src/takeoverpi.js.map +1 -0
  684. package/dist/src/terminal-failure.js +26 -0
  685. package/dist/src/terminal-failure.js.map +1 -0
  686. package/dist/src/thread-resolution-refusal.js +4 -0
  687. package/dist/src/thread-resolution-refusal.js.map +1 -0
  688. package/dist/src/tmux.js +126 -0
  689. package/dist/src/tmux.js.map +1 -0
  690. package/dist/src/trackerid.js +43 -0
  691. package/dist/src/trackerid.js.map +1 -0
  692. package/dist/src/transcriptindex.js +512 -0
  693. package/dist/src/transcriptindex.js.map +1 -0
  694. package/dist/src/tui/actions.js +404 -0
  695. package/dist/src/tui/actions.js.map +1 -0
  696. package/dist/src/tui/alerts.js +523 -0
  697. package/dist/src/tui/alerts.js.map +1 -0
  698. package/dist/src/tui/app.js +1835 -0
  699. package/dist/src/tui/app.js.map +1 -0
  700. package/dist/src/tui/archiveops.js +164 -0
  701. package/dist/src/tui/archiveops.js.map +1 -0
  702. package/dist/src/tui/autofile.js +191 -0
  703. package/dist/src/tui/autofile.js.map +1 -0
  704. package/dist/src/tui/board.js +1143 -0
  705. package/dist/src/tui/board.js.map +1 -0
  706. package/dist/src/tui/candidates.js +699 -0
  707. package/dist/src/tui/candidates.js.map +1 -0
  708. package/dist/src/tui/cellwidth.js +151 -0
  709. package/dist/src/tui/cellwidth.js.map +1 -0
  710. package/dist/src/tui/changelog-store.js +404 -0
  711. package/dist/src/tui/changelog-store.js.map +1 -0
  712. package/dist/src/tui/chord.js +26 -0
  713. package/dist/src/tui/chord.js.map +1 -0
  714. package/dist/src/tui/clipboard.js +81 -0
  715. package/dist/src/tui/clipboard.js.map +1 -0
  716. package/dist/src/tui/cmdbar.js +253 -0
  717. package/dist/src/tui/cmdbar.js.map +1 -0
  718. package/dist/src/tui/companion.js +1275 -0
  719. package/dist/src/tui/companion.js.map +1 -0
  720. package/dist/src/tui/companionplan.js +200 -0
  721. package/dist/src/tui/companionplan.js.map +1 -0
  722. package/dist/src/tui/companiontab.js +61 -0
  723. package/dist/src/tui/companiontab.js.map +1 -0
  724. package/dist/src/tui/confighome.js +105 -0
  725. package/dist/src/tui/confighome.js.map +1 -0
  726. package/dist/src/tui/connect.js +44 -0
  727. package/dist/src/tui/connect.js.map +1 -0
  728. package/dist/src/tui/deploy-ceremony.js +75 -0
  729. package/dist/src/tui/deploy-ceremony.js.map +1 -0
  730. package/dist/src/tui/deploy-drain.js +93 -0
  731. package/dist/src/tui/deploy-drain.js.map +1 -0
  732. package/dist/src/tui/deploy-process.js +234 -0
  733. package/dist/src/tui/deploy-process.js.map +1 -0
  734. package/dist/src/tui/deploytab.js +1263 -0
  735. package/dist/src/tui/deploytab.js.map +1 -0
  736. package/dist/src/tui/design.js +111 -0
  737. package/dist/src/tui/design.js.map +1 -0
  738. package/dist/src/tui/digesttab.js +148 -0
  739. package/dist/src/tui/digesttab.js.map +1 -0
  740. package/dist/src/tui/emptystate.js +32 -0
  741. package/dist/src/tui/emptystate.js.map +1 -0
  742. package/dist/src/tui/evidence.js +790 -0
  743. package/dist/src/tui/evidence.js.map +1 -0
  744. package/dist/src/tui/feed.js +415 -0
  745. package/dist/src/tui/feed.js.map +1 -0
  746. package/dist/src/tui/feedbacktab.js +907 -0
  747. package/dist/src/tui/feedbacktab.js.map +1 -0
  748. package/dist/src/tui/filters.js +72 -0
  749. package/dist/src/tui/filters.js.map +1 -0
  750. package/dist/src/tui/ghread.js +272 -0
  751. package/dist/src/tui/ghread.js.map +1 -0
  752. package/dist/src/tui/historypull.js +61 -0
  753. package/dist/src/tui/historypull.js.map +1 -0
  754. package/dist/src/tui/inboxpull.js +197 -0
  755. package/dist/src/tui/inboxpull.js.map +1 -0
  756. package/dist/src/tui/index.js +1425 -0
  757. package/dist/src/tui/index.js.map +1 -0
  758. package/dist/src/tui/issuesink.js +206 -0
  759. package/dist/src/tui/issuesink.js.map +1 -0
  760. package/dist/src/tui/jsonfile.js +32 -0
  761. package/dist/src/tui/jsonfile.js.map +1 -0
  762. package/dist/src/tui/keys.js +97 -0
  763. package/dist/src/tui/keys.js.map +1 -0
  764. package/dist/src/tui/layout.js +70 -0
  765. package/dist/src/tui/layout.js.map +1 -0
  766. package/dist/src/tui/learning.js +469 -0
  767. package/dist/src/tui/learning.js.map +1 -0
  768. package/dist/src/tui/lessonswitch.js +103 -0
  769. package/dist/src/tui/lessonswitch.js.map +1 -0
  770. package/dist/src/tui/livecontrol.js +167 -0
  771. package/dist/src/tui/livecontrol.js.map +1 -0
  772. package/dist/src/tui/memforward.js +310 -0
  773. package/dist/src/tui/memforward.js.map +1 -0
  774. package/dist/src/tui/memincident.js +287 -0
  775. package/dist/src/tui/memincident.js.map +1 -0
  776. package/dist/src/tui/memory.js +485 -0
  777. package/dist/src/tui/memory.js.map +1 -0
  778. package/dist/src/tui/memtab.js +513 -0
  779. package/dist/src/tui/memtab.js.map +1 -0
  780. package/dist/src/tui/metricstab.js +979 -0
  781. package/dist/src/tui/metricstab.js.map +1 -0
  782. package/dist/src/tui/model.js +104 -0
  783. package/dist/src/tui/model.js.map +1 -0
  784. package/dist/src/tui/mouse.js +83 -0
  785. package/dist/src/tui/mouse.js.map +1 -0
  786. package/dist/src/tui/msg.js +196 -0
  787. package/dist/src/tui/msg.js.map +1 -0
  788. package/dist/src/tui/nativecompanion.js +321 -0
  789. package/dist/src/tui/nativecompanion.js.map +1 -0
  790. package/dist/src/tui/openurl.js +17 -0
  791. package/dist/src/tui/openurl.js.map +1 -0
  792. package/dist/src/tui/paint.js +501 -0
  793. package/dist/src/tui/paint.js.map +1 -0
  794. package/dist/src/tui/panes.js +74 -0
  795. package/dist/src/tui/panes.js.map +1 -0
  796. package/dist/src/tui/pipane.js +166 -0
  797. package/dist/src/tui/pipane.js.map +1 -0
  798. package/dist/src/tui/poll-hooks.js +11 -0
  799. package/dist/src/tui/poll-hooks.js.map +1 -0
  800. package/dist/src/tui/poll.js +113 -0
  801. package/dist/src/tui/poll.js.map +1 -0
  802. package/dist/src/tui/proposals.js +715 -0
  803. package/dist/src/tui/proposals.js.map +1 -0
  804. package/dist/src/tui/prpause.js +132 -0
  805. package/dist/src/tui/prpause.js.map +1 -0
  806. package/dist/src/tui/reload.js +351 -0
  807. package/dist/src/tui/reload.js.map +1 -0
  808. package/dist/src/tui/remote.js +312 -0
  809. package/dist/src/tui/remote.js.map +1 -0
  810. package/dist/src/tui/rollover.js +767 -0
  811. package/dist/src/tui/rollover.js.map +1 -0
  812. package/dist/src/tui/scantab.js +1053 -0
  813. package/dist/src/tui/scantab.js.map +1 -0
  814. package/dist/src/tui/setupentry.js +81 -0
  815. package/dist/src/tui/setupentry.js.map +1 -0
  816. package/dist/src/tui/sidebar.js +602 -0
  817. package/dist/src/tui/sidebar.js.map +1 -0
  818. package/dist/src/tui/sshtriage.js +393 -0
  819. package/dist/src/tui/sshtriage.js.map +1 -0
  820. package/dist/src/tui/startup.js +172 -0
  821. package/dist/src/tui/startup.js.map +1 -0
  822. package/dist/src/tui/tabs.js +41 -0
  823. package/dist/src/tui/tabs.js.map +1 -0
  824. package/dist/src/tui/termmirror.js +217 -0
  825. package/dist/src/tui/termmirror.js.map +1 -0
  826. package/dist/src/tui/theme.js +95 -0
  827. package/dist/src/tui/theme.js.map +1 -0
  828. package/dist/src/tui/ticketstab.js +224 -0
  829. package/dist/src/tui/ticketstab.js.map +1 -0
  830. package/dist/src/tui/tmuxsocket.js +101 -0
  831. package/dist/src/tui/tmuxsocket.js.map +1 -0
  832. package/dist/src/tui/trackertickets.js +77 -0
  833. package/dist/src/tui/trackertickets.js.map +1 -0
  834. package/dist/src/tui/unwedge.js +245 -0
  835. package/dist/src/tui/unwedge.js.map +1 -0
  836. package/dist/src/tui/viewer.js +479 -0
  837. package/dist/src/tui/viewer.js.map +1 -0
  838. package/dist/src/tui/viewerinput.js +125 -0
  839. package/dist/src/tui/viewerinput.js.map +1 -0
  840. package/dist/src/updatenotice.js +143 -0
  841. package/dist/src/updatenotice.js.map +1 -0
  842. package/dist/src/usage.js +1007 -0
  843. package/dist/src/usage.js.map +1 -0
  844. package/dist/src/verdicts.js +3848 -0
  845. package/dist/src/verdicts.js.map +1 -0
  846. package/dist/src/version.js +58 -0
  847. package/dist/src/version.js.map +1 -0
  848. package/dist/src/wakes.js +411 -0
  849. package/dist/src/wakes.js.map +1 -0
  850. package/dist/src/webhook.js +725 -0
  851. package/dist/src/webhook.js.map +1 -0
  852. package/dist/src/webhookheal.js +238 -0
  853. package/dist/src/webhookheal.js.map +1 -0
  854. package/dist/src/wire.js +1801 -0
  855. package/dist/src/wire.js.map +1 -0
  856. package/dist/src/worker-session-host.js +531 -0
  857. package/dist/src/worker-session-host.js.map +1 -0
  858. package/dist/src/workerbreaker.js +112 -0
  859. package/dist/src/workerbreaker.js.map +1 -0
  860. package/dist/src/workercontrol.js +49 -0
  861. package/dist/src/workercontrol.js.map +1 -0
  862. package/dist/src/workerlease.js +351 -0
  863. package/dist/src/workerlease.js.map +1 -0
  864. package/dist/src/workerliveness.js +84 -0
  865. package/dist/src/workerliveness.js.map +1 -0
  866. package/dist/src/workerlog.js +65 -0
  867. package/dist/src/workerlog.js.map +1 -0
  868. package/dist/src/workerruntime.js +10 -0
  869. package/dist/src/workerruntime.js.map +1 -0
  870. package/dist/src/workersupervisor.js +1206 -0
  871. package/dist/src/workersupervisor.js.map +1 -0
  872. package/dist/src/workerusage.js +23 -0
  873. package/dist/src/workerusage.js.map +1 -0
  874. package/dist/src/workerworld.js +332 -0
  875. package/dist/src/workerworld.js.map +1 -0
  876. package/dist/src/worktrees.js +984 -0
  877. package/dist/src/worktrees.js.map +1 -0
  878. package/docker/Dockerfile +284 -0
  879. package/docker/Dockerfile.dockerignore +35 -0
  880. package/docker/README.md +221 -0
  881. package/docker/companion/Dockerfile +139 -0
  882. package/docker/companion/agents/evidence.md +34 -0
  883. package/docker/companion/agents/explore.md +26 -0
  884. package/docker/companion/agents/pass-survey.md +49 -0
  885. package/docker/companion/agents/study.md +26 -0
  886. package/docker/companion/entrypoint.sh +343 -0
  887. package/docker/companion/memory-health.mjs +269 -0
  888. package/docker/entrypoint.sh +782 -0
  889. package/docker/memory/Dockerfile +191 -0
  890. package/docker/memory/Dockerfile.dockerignore +20 -0
  891. package/docker/memory/README.md +60 -0
  892. package/docker/memory/entrypoint.sh +163 -0
  893. package/docker/setid/qcr-setid.c +109 -0
  894. package/docker/tunnel/Dockerfile.cloudflared +51 -0
  895. package/docker/tunnel/Dockerfile.ngrok +40 -0
  896. package/docker/tunnel/sidecar.mjs +411 -0
  897. package/docker/vm/tmux.conf +26 -0
  898. package/docker-compose.yml +348 -0
  899. package/extensions/cli/bash-guard-ambient.ts +71 -0
  900. package/extensions/cli/bash-guard.ts +12 -0
  901. package/extensions/cli/companion-guard.ts +8 -0
  902. package/extensions/cli/debug-round.ts +9 -0
  903. package/extensions/cli/inject-bridge.ts +8 -0
  904. package/extensions/cli/ledger-pin.ts +13 -0
  905. package/extensions/cli/lens.ts +22 -0
  906. package/extensions/cli/muted-theme.ts +9 -0
  907. package/extensions/cli/onboarding.ts +8 -0
  908. package/extensions/cli/setup.ts +8 -0
  909. package/extensions/cli/tui-view.ts +8 -0
  910. package/extensions/companion-guard.ts +411 -0
  911. package/extensions/debug-round.ts +281 -0
  912. package/extensions/inject-bridge.ts +630 -0
  913. package/extensions/inline-bash.ts +102 -0
  914. package/extensions/muted-theme.json +68 -0
  915. package/extensions/muted-theme.ts +23 -0
  916. package/extensions/onboarding.ts +233 -0
  917. package/extensions/setup-replay.ts +336 -0
  918. package/extensions/setup-scan.ts +1236 -0
  919. package/extensions/setup-triage.ts +190 -0
  920. package/extensions/setup.ts +1428 -0
  921. package/extensions/tui-view.ts +489 -0
  922. package/extensions/vendor/openviking-pi/LICENSE +201 -0
  923. package/extensions/vendor/openviking-pi/NOTICE +68 -0
  924. package/extensions/vendor/openviking-pi/README.md +550 -0
  925. package/extensions/vendor/openviking-pi/client.ts +588 -0
  926. package/extensions/vendor/openviking-pi/config.json +28 -0
  927. package/extensions/vendor/openviking-pi/config.ts +271 -0
  928. package/extensions/vendor/openviking-pi/index.ts +523 -0
  929. package/extensions/vendor/openviking-pi/lib/capture-adapter.d.mts +10 -0
  930. package/extensions/vendor/openviking-pi/lib/capture-adapter.mjs +88 -0
  931. package/extensions/vendor/openviking-pi/lib/takeover-core.d.mts +80 -0
  932. package/extensions/vendor/openviking-pi/lib/takeover-core.mjs +406 -0
  933. package/extensions/vendor/openviking-pi/lib/uri-guard-adapter.d.mts +1 -0
  934. package/extensions/vendor/openviking-pi/lib/uri-guard-adapter.mjs +42 -0
  935. package/extensions/vendor/openviking-pi/patches/0000-vendoring-and-build-conformance.patch +726 -0
  936. package/extensions/vendor/openviking-pi/patches/0001-remove-session-before-compact-handler.patch +101 -0
  937. package/extensions/vendor/openviking-pi/patches/0002-no-ambient-work-in-subagent-leaves.patch +202 -0
  938. package/extensions/vendor/openviking-pi/patches/0003-never-auto-create-openviking-sessions.patch +120 -0
  939. package/extensions/vendor/openviking-pi/patches/0004-viking-write-durable-batch-write.patch +521 -0
  940. package/extensions/vendor/openviking-pi/patches/0005-second-memory-namespace.patch +786 -0
  941. package/extensions/vendor/openviking-pi/patches/0006-writes-that-stick-and-honest-errors.patch +996 -0
  942. package/extensions/vendor/openviking-pi/patches/0007-bounded-recall-no-commit.patch +794 -0
  943. package/extensions/vendor/openviking-pi/patches/0008-pr-derived-recall.patch +379 -0
  944. package/extensions/vendor/openviking-pi/patches/0009-pr-session-tools-in-round-areas.patch +375 -0
  945. package/extensions/vendor/openviking-pi/patches/0010-typed-lessons.patch +448 -0
  946. package/extensions/vendor/openviking-pi/patches/0011-review-session-memory-boundary.patch +382 -0
  947. package/extensions/vendor/openviking-pi/patches/0012-typecheck-against-the-real-pi.patch +129 -0
  948. package/extensions/vendor/openviking-pi/patches/0013-createopenviking-factory.patch +1168 -0
  949. package/extensions/vendor/openviking-pi/qcr-hint.ts +313 -0
  950. package/extensions/vendor/openviking-pi/qcr-honest.ts +183 -0
  951. package/extensions/vendor/openviking-pi/qcr-hooks.ts +87 -0
  952. package/extensions/vendor/openviking-pi/qcr-leaf.ts +78 -0
  953. package/extensions/vendor/openviking-pi/qcr-lesson.ts +231 -0
  954. package/extensions/vendor/openviking-pi/qcr-namespaces.ts +198 -0
  955. package/extensions/vendor/openviking-pi/qcr-recall.ts +288 -0
  956. package/extensions/vendor/openviking-pi/qcr-shim.ts +142 -0
  957. package/extensions/vendor/openviking-pi/qcr-write.ts +427 -0
  958. package/extensions/vendor/openviking-pi/recall.ts +149 -0
  959. package/extensions/vendor/openviking-pi/shared/capture-utils.d.mts +9 -0
  960. package/extensions/vendor/openviking-pi/shared/capture-utils.mjs +515 -0
  961. package/extensions/vendor/openviking-pi/shared/credentials.d.mts +14 -0
  962. package/extensions/vendor/openviking-pi/shared/credentials.mjs +228 -0
  963. package/extensions/vendor/openviking-pi/shared/pending-queue.d.mts +19 -0
  964. package/extensions/vendor/openviking-pi/shared/pending-queue.mjs +458 -0
  965. package/extensions/vendor/openviking-pi/shared/profile-inject.d.mts +17 -0
  966. package/extensions/vendor/openviking-pi/shared/profile-inject.mjs +294 -0
  967. package/extensions/vendor/openviking-pi/shared/recall-compress-core.mjs +195 -0
  968. package/extensions/vendor/openviking-pi/shared/recall-core.d.mts +13 -0
  969. package/extensions/vendor/openviking-pi/shared/recall-core.mjs +609 -0
  970. package/extensions/vendor/openviking-pi/shared/retryable.mjs +9 -0
  971. package/extensions/vendor/openviking-pi/shared/session-model.d.mts +3 -0
  972. package/extensions/vendor/openviking-pi/shared/session-model.mjs +57 -0
  973. package/extensions/vendor/openviking-pi/shared/uri-guard.mjs +56 -0
  974. package/extensions/vendor/openviking-pi/shared/workspace-peer.d.mts +5 -0
  975. package/extensions/vendor/openviking-pi/shared/workspace-peer.mjs +16 -0
  976. package/extensions/vendor/openviking-pi/sync.ts +163 -0
  977. package/extensions/vendor/openviking-pi/takeover.ts +36 -0
  978. package/extensions/vendor/openviking-pi/tools.ts +479 -0
  979. package/extensions/vendor/openviking-pi/upstream.json +48 -0
  980. package/package.json +138 -4
  981. package/profiles/default/README.md +21 -0
  982. package/profiles/default/addenda/.gitkeep +0 -0
  983. package/profiles/default/profile.toml +17 -0
  984. package/profiles/example-django/README.md +21 -0
  985. package/profiles/example-django/addenda/10-migration-discipline.md +13 -0
  986. package/profiles/example-django/addenda/20-new-column-nullability.md +12 -0
  987. package/profiles/example-django/addenda/30-test-doctrine.md +12 -0
  988. package/profiles/example-django/addenda/40-orm-usage.md +19 -0
  989. package/profiles/example-django/addenda/50-declared-shape.md +10 -0
  990. package/profiles/example-django/addenda/60-config-placement.md +14 -0
  991. package/profiles/example-django/heuristics.toml +24 -0
  992. package/profiles/example-django/profile.toml +9 -0
  993. package/profiles/fast/README.md +24 -0
  994. package/profiles/fast/profile.toml +59 -0
  995. package/profiles/minimal/README.md +17 -0
  996. package/profiles/minimal/addenda/.gitkeep +0 -0
  997. package/profiles/minimal/profile.toml +8 -0
  998. package/profiles/snappy/README.md +24 -0
  999. package/profiles/snappy/addenda/10-race-as-question.md +6 -0
  1000. package/profiles/snappy/profile.toml +46 -0
  1001. package/prompts/companion-day-open.md +46 -0
  1002. package/prompts/companion-first-run.md +104 -0
  1003. package/prompts/companion.md +821 -0
  1004. package/prompts/conversation-system.md +117 -0
  1005. package/prompts/eod-sweep.md +120 -0
  1006. package/prompts/onboarding.md +74 -0
  1007. package/prompts/pass-common.md +52 -0
  1008. package/prompts/pass-quality-common.md +22 -0
  1009. package/prompts/round-first.md +874 -0
  1010. package/prompts/round-follow-up.md +991 -0
  1011. package/prompts/round-re-review.md +889 -0
  1012. package/prompts/round-recheck.md +196 -0
  1013. package/prompts/round-staleness.md +856 -0
  1014. package/schemas/review-result.v1.json +391 -0
  1015. package/schemas/scan-result.v1.json +421 -0
  1016. package/schemas/version.v1.json +57 -0
  1017. package/scripts/approve-pr.sh +16 -0
  1018. package/scripts/build-stamp.mjs +67 -0
  1019. package/scripts/commit-verdict.sh +155 -0
  1020. package/scripts/companion-e2e.sh +250 -0
  1021. package/scripts/companion-memory-forward.mjs +1966 -0
  1022. package/scripts/config-fingerprint.sh +28 -0
  1023. package/scripts/deploy-manifest.mjs +141 -0
  1024. package/scripts/deploy.sh +1435 -0
  1025. package/scripts/directory-lock.mjs +193 -0
  1026. package/scripts/heartbeat-fresh.mjs +54 -0
  1027. package/scripts/install-locator.sh +328 -0
  1028. package/scripts/install-wrapper.sh +76 -0
  1029. package/scripts/memory-search-check.mjs +98 -0
  1030. package/scripts/mint-token.sh +212 -0
  1031. package/scripts/openviking-embedder.py +392 -0
  1032. package/scripts/openviking-ov-conf.mjs +161 -0
  1033. package/scripts/openviking-provision.mjs +1122 -0
  1034. package/scripts/openviking-reembed.mjs +1154 -0
  1035. package/scripts/post-review.sh +16 -0
  1036. package/scripts/pr-checks.sh +256 -0
  1037. package/scripts/pr-context.py +174 -0
  1038. package/scripts/pr-context.sh +63 -0
  1039. package/scripts/pr-self.sh +144 -0
  1040. package/scripts/pr-threads.sh +145 -0
  1041. package/scripts/qcr +15 -0
  1042. package/scripts/qcr-host.sh +769 -0
  1043. package/scripts/render-review.sh +24 -0
  1044. package/scripts/reply-thread.sh +16 -0
  1045. package/scripts/required-passes.py +112 -0
  1046. package/scripts/smoke-companion.sh +211 -0
  1047. package/scripts/tui-deploy-runner.mjs +61 -0
  1048. package/scripts/verify-dist.mjs +201 -0
  1049. package/scripts/vm-ghcr-login.sh +188 -0
  1050. package/seeds/agents/pass-baseline.md +61 -0
  1051. package/seeds/agents/pass-contracts.md +30 -0
  1052. package/seeds/agents/pass-data-safety.md +54 -0
  1053. package/seeds/agents/pass-delivery.md +37 -0
  1054. package/seeds/agents/pass-prod-risk.md +24 -0
  1055. package/seeds/agents/pass-security.md +31 -0
  1056. package/seeds/agents/pass-statelessness.md +27 -0
  1057. package/seeds/agents/pass-ui.md +23 -0
  1058. package/seeds/agents/pass-validate.md +50 -0
  1059. package/seeds/prompts/conversation-system.md +117 -0
  1060. package/seeds/prompts/eod-sweep.md +120 -0
  1061. package/seeds/prompts/pass-common.md +52 -0
  1062. package/skills/companion/adjudicate/SKILL.md +247 -0
  1063. package/skills/companion/evidence/SKILL.md +150 -0
  1064. package/skills/companion/land/SKILL.md +200 -0
  1065. package/skills/companion/replay/SKILL.md +138 -0
  1066. package/skills/companion/setup/SKILL.md +167 -0
  1067. package/skills/companion/survey/SKILL.md +160 -0
  1068. package/skills/selfimprove/README.md +34 -0
  1069. package/skills/selfimprove/SKILL.md +127 -0
  1070. package/skills/selfimprove/agents/openai.yaml +2 -0
  1071. package/skills/selfimprove/commands/selfimprove.md +6 -0
  1072. package/skills/selfimprove/references/fix-loop.md +49 -0
  1073. package/skills/selfimprove/references/ledger.md +20 -0
  1074. package/skills/selfimprove/references/setup.md +40 -0
  1075. package/src/anomalies.ts +566 -0
  1076. package/src/answerworker.ts +251 -0
  1077. package/src/appstamp.ts +65 -0
  1078. package/src/archive/admission.ts +3 -0
  1079. package/src/archive/archivedb.ts +548 -0
  1080. package/src/archive/archiver.ts +1963 -0
  1081. package/src/archive/archivewrite.ts +279 -0
  1082. package/src/archive/bundle.ts +333 -0
  1083. package/src/archive/dbmove.ts +911 -0
  1084. package/src/archive/duplicatecounts.ts +98 -0
  1085. package/src/archive/eligibility.ts +181 -0
  1086. package/src/archive/extract.ts +342 -0
  1087. package/src/archive/fsutil.ts +415 -0
  1088. package/src/archive/gzfile.ts +370 -0
  1089. package/src/archive/kinds.ts +21 -0
  1090. package/src/archive/livecheckpoint.ts +217 -0
  1091. package/src/archive/liveretention.ts +180 -0
  1092. package/src/archive/manifest.ts +519 -0
  1093. package/src/archive/overseer.ts +336 -0
  1094. package/src/archive/piglobal.ts +174 -0
  1095. package/src/archive/plan.ts +612 -0
  1096. package/src/archive/prarchive.ts +984 -0
  1097. package/src/archive/prfiles.ts +406 -0
  1098. package/src/archive/report.ts +252 -0
  1099. package/src/archive/restore.ts +330 -0
  1100. package/src/archive/rows.ts +187 -0
  1101. package/src/archive/seal.ts +630 -0
  1102. package/src/archive/status.ts +719 -0
  1103. package/src/archive/storepass.ts +581 -0
  1104. package/src/backfill.ts +362 -0
  1105. package/src/bench/cost.ts +113 -0
  1106. package/src/bench/exec.ts +90 -0
  1107. package/src/bench/values.ts +13 -0
  1108. package/src/botcontrol.ts +176 -0
  1109. package/src/botworker.ts +953 -0
  1110. package/src/capture.ts +321 -0
  1111. package/src/cases.ts +1789 -0
  1112. package/src/channelfs.ts +26 -0
  1113. package/src/checklist.ts +506 -0
  1114. package/src/ciretry.ts +141 -0
  1115. package/src/cli.ts +2271 -0
  1116. package/src/cliops.ts +384 -0
  1117. package/src/clonedir.ts +15 -0
  1118. package/src/commandeffects.ts +57 -0
  1119. package/src/commands.ts +1678 -0
  1120. package/src/companioninbox.ts +239 -0
  1121. package/src/compare.ts +957 -0
  1122. package/src/config.ts +2050 -0
  1123. package/src/configcheck.ts +133 -0
  1124. package/src/coreext.ts +47 -0
  1125. package/src/daemon.ts +1302 -0
  1126. package/src/debuground.ts +927 -0
  1127. package/src/debugroundpi.ts +262 -0
  1128. package/src/diagnostics.ts +14 -0
  1129. package/src/digest.ts +183 -0
  1130. package/src/dispatch.ts +2250 -0
  1131. package/src/engine/answerguard.ts +27 -0
  1132. package/src/engine/botsdk.ts +336 -0
  1133. package/src/engine/caserunner-sdk.ts +423 -0
  1134. package/src/engine/debugpi.ts +235 -0
  1135. package/src/eod.ts +669 -0
  1136. package/src/eodpinwatch.ts +556 -0
  1137. package/src/escalation.ts +1253 -0
  1138. package/src/eventloop.ts +1045 -0
  1139. package/src/execboundary.ts +633 -0
  1140. package/src/feedback.ts +1162 -0
  1141. package/src/findingscheck.ts +298 -0
  1142. package/src/fsdenied.ts +24 -0
  1143. package/src/ghread.ts +242 -0
  1144. package/src/github.ts +1497 -0
  1145. package/src/homes.ts +175 -0
  1146. package/src/hostroute.ts +53 -0
  1147. package/src/improvements.ts +787 -0
  1148. package/src/install.ts +1103 -0
  1149. package/src/installkind.ts +50 -0
  1150. package/src/ipc/capability.ts +333 -0
  1151. package/src/ipc/client.ts +269 -0
  1152. package/src/ipc/control.ts +90 -0
  1153. package/src/ipc/ghreadshim.ts +94 -0
  1154. package/src/ipc/launcher.ts +65 -0
  1155. package/src/ipc/permits.ts +362 -0
  1156. package/src/ipc/postshim.ts +164 -0
  1157. package/src/ipc/protocol.ts +342 -0
  1158. package/src/ipc/server.ts +371 -0
  1159. package/src/ipc/workerspec.ts +218 -0
  1160. package/src/learner/learner.ts +1655 -0
  1161. package/src/learner/miner.ts +1290 -0
  1162. package/src/learner/packet.ts +340 -0
  1163. package/src/learner/receipt.ts +168 -0
  1164. package/src/learner/status.ts +107 -0
  1165. package/src/ledgercheck.ts +157 -0
  1166. package/src/lessonledger.ts +703 -0
  1167. package/src/lessonselect.ts +888 -0
  1168. package/src/lessonshadow.ts +810 -0
  1169. package/src/levers.ts +393 -0
  1170. package/src/live/projection.ts +491 -0
  1171. package/src/live/publish.ts +92 -0
  1172. package/src/live/read.ts +86 -0
  1173. package/src/livecli.ts +336 -0
  1174. package/src/loginhint.ts +56 -0
  1175. package/src/loginrefresh/atomic.ts +76 -0
  1176. package/src/loginrefresh/lock.ts +104 -0
  1177. package/src/loginrefresh/main.ts +59 -0
  1178. package/src/loginrefresh/pirefresh.ts +57 -0
  1179. package/src/loginrefresh/refresher.ts +326 -0
  1180. package/src/loginrefresh/supervisor.ts +273 -0
  1181. package/src/loginrefresh/types.ts +35 -0
  1182. package/src/memory/context.ts +385 -0
  1183. package/src/memory/datafence.ts +9 -0
  1184. package/src/memory/delivery.ts +171 -0
  1185. package/src/memory/eventtags.ts +80 -0
  1186. package/src/memory/health.ts +953 -0
  1187. package/src/memory/import.ts +664 -0
  1188. package/src/memory/layout.ts +261 -0
  1189. package/src/memory/legacy-file.ts +104 -0
  1190. package/src/memory/lessons.ts +447 -0
  1191. package/src/memory/ovsession.ts +601 -0
  1192. package/src/memory/relayout.ts +335 -0
  1193. package/src/memory/roundactivity.ts +209 -0
  1194. package/src/memory/selection.ts +989 -0
  1195. package/src/memory/shadowstatus.ts +125 -0
  1196. package/src/memory/store.ts +275 -0
  1197. package/src/memory/textidentity.ts +8 -0
  1198. package/src/metrics.ts +1056 -0
  1199. package/src/missingconfig.ts +7 -0
  1200. package/src/npmverbs.ts +264 -0
  1201. package/src/onboard/choices.ts +222 -0
  1202. package/src/onboard/engine.ts +518 -0
  1203. package/src/onboard/launch.ts +115 -0
  1204. package/src/onboard/steps/appslug.ts +265 -0
  1205. package/src/onboard/steps/bringup.ts +482 -0
  1206. package/src/onboard/steps/compose.ts +459 -0
  1207. package/src/onboard/steps/configdelivery.ts +58 -0
  1208. package/src/onboard/steps/configfill.ts +1352 -0
  1209. package/src/onboard/steps/deploysh.ts +105 -0
  1210. package/src/onboard/steps/embeddings.ts +550 -0
  1211. package/src/onboard/steps/escalation.ts +640 -0
  1212. package/src/onboard/steps/githubapp.ts +1414 -0
  1213. package/src/onboard/steps/golive.ts +577 -0
  1214. package/src/onboard/steps/index.ts +71 -0
  1215. package/src/onboard/steps/ingress.ts +907 -0
  1216. package/src/onboard/steps/inventory.ts +526 -0
  1217. package/src/onboard/steps/llmauth.ts +1095 -0
  1218. package/src/onboard/steps/memory.ts +1290 -0
  1219. package/src/onboard/steps/memorykeys.ts +85 -0
  1220. package/src/onboard/steps/preflight.ts +191 -0
  1221. package/src/onboard/steps/proof.ts +624 -0
  1222. package/src/onboard/steps/ssh.ts +377 -0
  1223. package/src/onboard/steps/topology.ts +337 -0
  1224. package/src/onboard/steps/transport.ts +665 -0
  1225. package/src/onboard/steps/verifyup.ts +448 -0
  1226. package/src/onboard/steps/vmdeploy.ts +442 -0
  1227. package/src/onboard/toml.ts +50 -0
  1228. package/src/opencli.ts +591 -0
  1229. package/src/openpr.ts +568 -0
  1230. package/src/openviking/client.ts +1131 -0
  1231. package/src/openviking/context.ts +263 -0
  1232. package/src/openviking/embedder.ts +516 -0
  1233. package/src/openviking/gapsink.ts +63 -0
  1234. package/src/openviking/health.ts +83 -0
  1235. package/src/openviking/index.ts +119 -0
  1236. package/src/openviking/lessonfind.ts +92 -0
  1237. package/src/openviking/probe.ts +129 -0
  1238. package/src/openviking/proc.ts +110 -0
  1239. package/src/openviking/provisionreport.ts +160 -0
  1240. package/src/openviking/reembed.ts +412 -0
  1241. package/src/openviking/relayout.ts +177 -0
  1242. package/src/openviking/sidecar-main.ts +38 -0
  1243. package/src/openviking/sidecar.ts +106 -0
  1244. package/src/openviking/store.ts +2025 -0
  1245. package/src/openviking/supervisor.ts +474 -0
  1246. package/src/openviking/types.ts +174 -0
  1247. package/src/operator-recovery.ts +237 -0
  1248. package/src/operatormessage.ts +52 -0
  1249. package/src/outcomes.ts +1670 -0
  1250. package/src/piauthcopy.ts +12 -0
  1251. package/src/picli.ts +49 -0
  1252. package/src/picwd.ts +25 -0
  1253. package/src/pilogin.ts +37 -0
  1254. package/src/pingpong.ts +1339 -0
  1255. package/src/posting-journal.ts +549 -0
  1256. package/src/posting-outbox.ts +802 -0
  1257. package/src/posting-receipt.ts +324 -0
  1258. package/src/posting.ts +603 -0
  1259. package/src/postops.ts +832 -0
  1260. package/src/pr-activity.ts +20 -0
  1261. package/src/pr-author.ts +6 -0
  1262. package/src/pr-conversation.ts +432 -0
  1263. package/src/pr-session-lifecycle.ts +631 -0
  1264. package/src/preflight.ts +391 -0
  1265. package/src/priorresolve.ts +343 -0
  1266. package/src/qcrbin.ts +186 -0
  1267. package/src/recheck.ts +1775 -0
  1268. package/src/reconcile.ts +1030 -0
  1269. package/src/recordedfindings.ts +27 -0
  1270. package/src/regression.ts +833 -0
  1271. package/src/replay.ts +816 -0
  1272. package/src/requiredpasses.ts +148 -0
  1273. package/src/resumecheck.ts +246 -0
  1274. package/src/reviewcli.ts +787 -0
  1275. package/src/reviewcontext.ts +35 -0
  1276. package/src/reviewdetach.ts +734 -0
  1277. package/src/reviewhistory.ts +427 -0
  1278. package/src/reviewhome.ts +36 -0
  1279. package/src/reviewmemory.ts +133 -0
  1280. package/src/reviewrendercli.ts +139 -0
  1281. package/src/round-work.ts +42 -0
  1282. package/src/runhost.ts +108 -0
  1283. package/src/scanauth.ts +36 -0
  1284. package/src/scanbox.ts +1081 -0
  1285. package/src/scancli.ts +1296 -0
  1286. package/src/scandriverlog.ts +32 -0
  1287. package/src/session-bridge.ts +139 -0
  1288. package/src/session-command-payload.ts +35 -0
  1289. package/src/session-command-supervisor.ts +1142 -0
  1290. package/src/sessionjsonl.ts +88 -0
  1291. package/src/sessions.ts +659 -0
  1292. package/src/setup/adapters.ts +335 -0
  1293. package/src/setup/baselines.ts +110 -0
  1294. package/src/setup/caserunner.ts +611 -0
  1295. package/src/setup/configcommit.ts +443 -0
  1296. package/src/setup/engine.ts +1001 -0
  1297. package/src/setup/facts.ts +627 -0
  1298. package/src/setup/findings.ts +1264 -0
  1299. package/src/setup/history.ts +443 -0
  1300. package/src/setup/interview.ts +243 -0
  1301. package/src/setup/ledger.ts +324 -0
  1302. package/src/setup/pins.ts +66 -0
  1303. package/src/setup/portrait.ts +635 -0
  1304. package/src/setup/presentation.ts +18 -0
  1305. package/src/setup/profile.ts +508 -0
  1306. package/src/setup/replay.ts +370 -0
  1307. package/src/setup/replaybuild.ts +392 -0
  1308. package/src/setup/replayrun.ts +1096 -0
  1309. package/src/setup/replaysource.ts +198 -0
  1310. package/src/setup/retune.ts +415 -0
  1311. package/src/setup/retunelog.ts +95 -0
  1312. package/src/setup/scan.ts +1033 -0
  1313. package/src/setup/scanbuild.ts +168 -0
  1314. package/src/setup/scanfacts.ts +107 -0
  1315. package/src/setup/scanlease.ts +297 -0
  1316. package/src/setup/scanreport.ts +373 -0
  1317. package/src/setup/scanrun.ts +2268 -0
  1318. package/src/setup/scantree.ts +259 -0
  1319. package/src/setup/stage2.ts +926 -0
  1320. package/src/setup/stage2request.ts +347 -0
  1321. package/src/setup/survey.ts +458 -0
  1322. package/src/setup/surveyrun.ts +758 -0
  1323. package/src/setup/textsniff.ts +95 -0
  1324. package/src/setup/trackersink.ts +433 -0
  1325. package/src/setup/triage.ts +768 -0
  1326. package/src/setup/tuning.ts +766 -0
  1327. package/src/setup/unitcut.ts +523 -0
  1328. package/src/singleflight.ts +86 -0
  1329. package/src/slack/announce.ts +911 -0
  1330. package/src/slack/api.ts +303 -0
  1331. package/src/slack/messages.ts +288 -0
  1332. package/src/slack/origin.ts +599 -0
  1333. package/src/slack/policy.ts +354 -0
  1334. package/src/slack/reply.ts +201 -0
  1335. package/src/slack/router.ts +285 -0
  1336. package/src/slack/socket.ts +384 -0
  1337. package/src/slack/types.ts +108 -0
  1338. package/src/sqlitehint.ts +32 -0
  1339. package/src/ssh-observation.ts +30 -0
  1340. package/src/state.ts +8243 -0
  1341. package/src/statemachine.ts +369 -0
  1342. package/src/stubs.ts +68 -0
  1343. package/src/takeover.ts +634 -0
  1344. package/src/takeoverpi.ts +293 -0
  1345. package/src/terminal-failure.ts +41 -0
  1346. package/src/thread-resolution-refusal.ts +2 -0
  1347. package/src/tmux.ts +153 -0
  1348. package/src/trackerid.ts +41 -0
  1349. package/src/transcriptindex.ts +665 -0
  1350. package/src/tui/actions.ts +484 -0
  1351. package/src/tui/alerts.ts +666 -0
  1352. package/src/tui/app.ts +1979 -0
  1353. package/src/tui/archiveops.ts +192 -0
  1354. package/src/tui/autofile.ts +233 -0
  1355. package/src/tui/board.ts +1432 -0
  1356. package/src/tui/candidates.ts +889 -0
  1357. package/src/tui/cellwidth.ts +148 -0
  1358. package/src/tui/changelog-store.ts +503 -0
  1359. package/src/tui/chord.ts +25 -0
  1360. package/src/tui/clipboard.ts +92 -0
  1361. package/src/tui/cmdbar.ts +296 -0
  1362. package/src/tui/companion.ts +1427 -0
  1363. package/src/tui/companionplan.ts +247 -0
  1364. package/src/tui/companiontab.ts +83 -0
  1365. package/src/tui/confighome.ts +155 -0
  1366. package/src/tui/connect.ts +68 -0
  1367. package/src/tui/deploy-ceremony.ts +104 -0
  1368. package/src/tui/deploy-drain.ts +129 -0
  1369. package/src/tui/deploy-process.ts +265 -0
  1370. package/src/tui/deploytab.ts +1523 -0
  1371. package/src/tui/design.ts +125 -0
  1372. package/src/tui/digesttab.ts +214 -0
  1373. package/src/tui/emptystate.ts +39 -0
  1374. package/src/tui/evidence.ts +999 -0
  1375. package/src/tui/feed.ts +604 -0
  1376. package/src/tui/feedbacktab.ts +1077 -0
  1377. package/src/tui/filters.ts +90 -0
  1378. package/src/tui/ghread.ts +321 -0
  1379. package/src/tui/historypull.ts +81 -0
  1380. package/src/tui/inboxpull.ts +236 -0
  1381. package/src/tui/index.ts +1565 -0
  1382. package/src/tui/issuesink.ts +238 -0
  1383. package/src/tui/jsonfile.ts +42 -0
  1384. package/src/tui/keys.ts +109 -0
  1385. package/src/tui/layout.ts +108 -0
  1386. package/src/tui/learning.ts +627 -0
  1387. package/src/tui/lessonswitch.ts +118 -0
  1388. package/src/tui/livecontrol.ts +228 -0
  1389. package/src/tui/memforward.ts +443 -0
  1390. package/src/tui/memincident.ts +363 -0
  1391. package/src/tui/memory.ts +620 -0
  1392. package/src/tui/memtab.ts +606 -0
  1393. package/src/tui/metricstab.ts +1177 -0
  1394. package/src/tui/model.ts +131 -0
  1395. package/src/tui/mouse.ts +98 -0
  1396. package/src/tui/msg.ts +268 -0
  1397. package/src/tui/nativecompanion.ts +417 -0
  1398. package/src/tui/openurl.ts +21 -0
  1399. package/src/tui/paint.ts +511 -0
  1400. package/src/tui/panes.ts +98 -0
  1401. package/src/tui/pipane.ts +219 -0
  1402. package/src/tui/poll-hooks.ts +12 -0
  1403. package/src/tui/poll.ts +147 -0
  1404. package/src/tui/proposals.ts +838 -0
  1405. package/src/tui/prpause.ts +150 -0
  1406. package/src/tui/reload.ts +436 -0
  1407. package/src/tui/remote.ts +413 -0
  1408. package/src/tui/rollover.ts +969 -0
  1409. package/src/tui/scantab.ts +1290 -0
  1410. package/src/tui/setupentry.ts +93 -0
  1411. package/src/tui/sidebar.ts +749 -0
  1412. package/src/tui/sshtriage.ts +510 -0
  1413. package/src/tui/startup.ts +231 -0
  1414. package/src/tui/tabs.ts +45 -0
  1415. package/src/tui/termmirror.ts +224 -0
  1416. package/src/tui/theme.ts +95 -0
  1417. package/src/tui/ticketstab.ts +310 -0
  1418. package/src/tui/tmuxsocket.ts +129 -0
  1419. package/src/tui/trackertickets.ts +84 -0
  1420. package/src/tui/unwedge.ts +286 -0
  1421. package/src/tui/viewer.ts +575 -0
  1422. package/src/tui/viewerinput.ts +173 -0
  1423. package/src/updatenotice.ts +178 -0
  1424. package/src/usage.ts +1154 -0
  1425. package/src/verdicts.ts +4689 -0
  1426. package/src/version.ts +80 -0
  1427. package/src/wakes.ts +476 -0
  1428. package/src/webhook.ts +942 -0
  1429. package/src/webhookheal.ts +276 -0
  1430. package/src/wire.ts +2153 -0
  1431. package/src/worker-session-host.ts +602 -0
  1432. package/src/workerbreaker.ts +156 -0
  1433. package/src/workercontrol.ts +104 -0
  1434. package/src/workerlease.ts +441 -0
  1435. package/src/workerliveness.ts +103 -0
  1436. package/src/workerlog.ts +79 -0
  1437. package/src/workerruntime.ts +30 -0
  1438. package/src/workersupervisor.ts +1538 -0
  1439. package/src/workerusage.ts +42 -0
  1440. package/src/workerworld.ts +427 -0
  1441. package/src/worktrees.ts +1138 -0
  1442. package/tests/fixtures/regression-cases.json +795 -0
  1443. package/tests/fixtures/seed-manifest.json +19 -0
@@ -0,0 +1,946 @@
1
+ // The install locator — the one module that decides where an
2
+ // install's own data lives. Every reader of the live config goes through it:
3
+ // the config loader, the onboarding wizard (via its adapters), the bench, the
4
+ // TUI, the daemon's session env, and — through `scripts/install-locator.sh`,
5
+ // its shell mirror, pinned by a differential test — the posting scripts,
6
+ // mint-token and deploy.sh's pin/drift preflight. Every reader of the secrets
7
+ // goes through it the same way.
8
+ //
9
+ // The resolution itself — the homes, the config, profile and secrets lookups —
10
+ // lives in src/homes.ts (the CLI's half, re-exported from here) and the pure
11
+ // profile search in packages/pi-plugin/src/profilelookup.ts; this module adds `qcr install
12
+ // migrate` and the operator-only homes.
13
+ //
14
+ // Two homes, split by kind:
15
+ // config home $XDG_CONFIG_HOME/qcr/<install>/ config.toml, profiles/, secrets/,
16
+ // portrait/ (the portrait narrative)
17
+ // state home $XDG_STATE_HOME/qcr/<install>/ scan ledger, findings, portrait facts
18
+ //
19
+ // `<install>` is `$QCR_INSTALL`, default `default` — one name per install, so
20
+ // one PC can hold more than one. `$QCR_CONFIG` overrides the config FILE
21
+ // outright (not the home). The checkout's own `config.toml` is not read: a
22
+ // checkout that still holds one is stranded — `strandedCheckoutConfig` names
23
+ // it so a not-found can point at `qcr install migrate`, which is the only
24
+ // thing that ever opens it.
25
+ //
26
+ // A session must never move any of this: `QCR_CONFIG=` and `QCR_INSTALL=` are
27
+ // both in the bash guard's POLICY_RELOCATING_ENV, and `HOME=` /
28
+ // `XDG_CONFIG_HOME=` are refused there too. The daemon hands each session
29
+ // the path it resolved as `QCR_CONFIG` (sessions.ts), so the posting scripts
30
+ // read exactly the daemon's config rather than re-deriving one.
31
+ //
32
+ // Repo profiles live in the config home too: `<home>/profiles/<name>/`
33
+ // first, then — when `$QCR_CONFIG` names a file — `profiles/` beside that file
34
+ // (what makes the compose route work: it mounts the located config's directory,
35
+ // profiles and all, and names the config inside the mount), then the checkout's
36
+ // `profiles/` — for the generic examples (`EXAMPLE_PROFILES`) only. Any other
37
+ // profile left there is stranded, never read, and `qcr install migrate`
38
+ // moves it.
39
+ //
40
+ // Pure where it can be: every locator takes the env as a parameter (and
41
+ // `strandedCheckoutConfig` / `locateProfile` an `exists` / `isDir` probe), so
42
+ // the tests drive it with temp XDG homes and never touch the operator's own.
43
+ import { randomUUID } from "node:crypto";
44
+ import { chmodSync, closeSync, fsyncSync, openSync, copyFileSync, cpSync, existsSync, lstatSync, mkdirSync, readdirSync, readFileSync, readlinkSync, realpathSync, renameSync, rmdirSync, rmSync, statSync, symlinkSync, unlinkSync, writeFileSync, } from "node:fs";
45
+ import { constants as fsConstants } from "node:fs";
46
+ import { dirname, isAbsolute, join, relative, resolve, sep } from "node:path";
47
+ import { CONFIG_FILE, configHome, EXAMPLE_PROFILES, installName, isLegacySecretsSpelling, legacySecretsDir, PROFILES_DIR, secretsHome, xdgBase, } from "./homes.js";
48
+ import { isDirectory, isPathSegment } from "@quickchatai/pi-quickreview/src/profilelookup.js";
49
+ // The homes themselves (config, state, profiles, secrets) are resolved in
50
+ // src/homes.ts; this module re-exports them, so its importers need not know.
51
+ export * from "./homes.js";
52
+ // ---- qcr install migrate ----------------------------------------------------
53
+ /** Whether two existing paths are the same file or directory (dev + inode, so
54
+ * a symlink or a config home that IS the checkout both count). A migrate whose
55
+ * source is its destination has nothing to move — and must never "deduplicate"
56
+ * the only copy by deleting it. */
57
+ function samePath(a, b) {
58
+ if (resolve(a) === resolve(b))
59
+ return true;
60
+ try {
61
+ const sa = statSync(a);
62
+ const sb = statSync(b);
63
+ return sa.dev === sb.dev && sa.ino === sb.ino;
64
+ }
65
+ catch {
66
+ return false;
67
+ }
68
+ }
69
+ /**
70
+ * Move `<root>/config.toml` into the install's config home. Idempotent: a
71
+ * second run finds the home populated and the checkout empty and says so. It
72
+ * never overwrites a config it did not move — a differing pair is a conflict
73
+ * the operator resolves by hand.
74
+ */
75
+ export function migrateConfig(opts) {
76
+ const env = opts.env ?? process.env;
77
+ const override = (env.QCR_CONFIG ?? "").trim();
78
+ if (override !== "")
79
+ return { kind: "override", path: resolve(override) };
80
+ const from = join(opts.root, CONFIG_FILE);
81
+ const to = join(configHome(env), CONFIG_FILE);
82
+ const inCheckout = existsSync(from);
83
+ const inHome = existsSync(to);
84
+ if (!inCheckout)
85
+ return inHome ? { kind: "already", to } : { kind: "nothing", to };
86
+ if (samePath(from, to))
87
+ return { kind: "already", to, inPlace: true };
88
+ if (inHome) {
89
+ if (!readFileSync(from).equals(readFileSync(to)))
90
+ return { kind: "conflict", from, to };
91
+ unlinkSync(from);
92
+ return { kind: "deduplicated", from, to };
93
+ }
94
+ mkdirSync(dirname(to), { recursive: true, mode: 0o700 });
95
+ // A symlinked config (often relative, `-> ./operator.toml`) would be renamed
96
+ // as a link and resolve against the config home, where its target is not:
97
+ // copy the bytes it points at instead, then drop the link.
98
+ if (lstatSync(from).isSymbolicLink()) {
99
+ copyFileSync(from, to);
100
+ unlinkSync(from);
101
+ }
102
+ else
103
+ moveFile(from, to);
104
+ return { kind: "moved", from, to };
105
+ }
106
+ /** What `qcr install migrate` prints, and its exit code. Only a conflict fails:
107
+ * every other outcome leaves the install in a state the locator reads. */
108
+ export function migrateReport(outcome) {
109
+ switch (outcome.kind) {
110
+ case "moved":
111
+ return {
112
+ code: 0,
113
+ lines: [
114
+ `moved ${outcome.from} → ${outcome.to}`,
115
+ "every reader now finds it there (restart a running daemon or TUI to pick it up).",
116
+ "If this checkout tracked config.toml in git, the move shows as a deletion — the snapshot manifests already exclude the path.",
117
+ "scripts/deploy.sh release ships the config home to the VM from there — and refuses a config left in the checkout.",
118
+ ],
119
+ };
120
+ case "already":
121
+ return {
122
+ code: 0,
123
+ lines: [
124
+ outcome.inPlace
125
+ ? `already migrated: the checkout's config.toml is ${outcome.to} itself — it stays, being the live config`
126
+ : `already migrated: the config is ${outcome.to}; nothing in the checkout`,
127
+ ],
128
+ };
129
+ case "deduplicated":
130
+ return {
131
+ code: 0,
132
+ lines: [
133
+ `${outcome.to} already held the same bytes — removed the checkout copy ${outcome.from}`,
134
+ ],
135
+ };
136
+ case "conflict":
137
+ return {
138
+ code: 1,
139
+ lines: [
140
+ `refused: ${outcome.from} and ${outcome.to} both exist and differ — nothing was touched.`,
141
+ `Keep the one you want at ${outcome.to}, delete the checkout copy, and re-run.`,
142
+ ],
143
+ };
144
+ case "nothing":
145
+ return {
146
+ code: 0,
147
+ lines: [
148
+ `no config.toml in the checkout or at ${outcome.to} — nothing to move (\`qcr onboard\` writes a new one there)`,
149
+ ],
150
+ };
151
+ case "override":
152
+ return {
153
+ code: 0,
154
+ lines: [
155
+ `QCR_CONFIG names ${outcome.path} — that file is the config; migrate moves nothing while it is set`,
156
+ ],
157
+ };
158
+ }
159
+ }
160
+ /** Relative path → bytes, for every file under `dir` (sorted). */
161
+ function treeFiles(dir) {
162
+ const out = new Map();
163
+ const walk = (rel) => {
164
+ for (const entry of readdirSync(join(dir, rel), { withFileTypes: true })) {
165
+ const path = rel === "" ? entry.name : join(rel, entry.name);
166
+ // A symlinked directory is walked like a real one (never read as a file).
167
+ if (entry.isDirectory() || isDirectory(join(dir, path)))
168
+ walk(path);
169
+ else
170
+ out.set(path, readFileSync(join(dir, path)));
171
+ }
172
+ };
173
+ walk("");
174
+ return out;
175
+ }
176
+ /** Whether `child` is `parent` or lies under it (both already resolved). */
177
+ function within(parent, child) {
178
+ const rel = relative(parent, child);
179
+ return rel === "" || (rel !== ".." && !rel.startsWith("../") && !isAbsolute(rel));
180
+ }
181
+ /** Whether anything under `dir` is a link resolving into `target` — a home
182
+ * profile whose files link into the checkout's depends on it, so removing the
183
+ * checkout copy as a "duplicate" would leave the home's links dangling. A
184
+ * linked directory is judged by where it points, not walked. */
185
+ function linksInto(dir, target) {
186
+ let realTarget;
187
+ try {
188
+ realTarget = realpathSync(target);
189
+ }
190
+ catch {
191
+ return false;
192
+ }
193
+ const walk = (abs) => {
194
+ for (const entry of readdirSync(abs, { withFileTypes: true })) {
195
+ const path = join(abs, entry.name);
196
+ if (entry.isSymbolicLink()) {
197
+ try {
198
+ if (within(realTarget, realpathSync(path)))
199
+ return true;
200
+ }
201
+ catch {
202
+ // a dangling link depends on nothing that exists
203
+ }
204
+ }
205
+ else if (entry.isDirectory() && walk(path))
206
+ return true;
207
+ }
208
+ return false;
209
+ };
210
+ return walk(dir);
211
+ }
212
+ function sameTree(a, b) {
213
+ const left = treeFiles(a);
214
+ const right = treeFiles(b);
215
+ if (left.size !== right.size)
216
+ return false;
217
+ for (const [path, bytes] of left) {
218
+ const other = right.get(path);
219
+ if (other === undefined || !bytes.equals(other))
220
+ return false;
221
+ }
222
+ return true;
223
+ }
224
+ function profileRepairPlan(path, from, to) {
225
+ if (!existsSync(path))
226
+ return { version: 1, from, to, links: [] };
227
+ if (!lstatSync(path).isFile() || statSync(path).size > 1_000_000)
228
+ throw new Error("invalid profile repair journal");
229
+ const plan = JSON.parse(readFileSync(path, "utf8"));
230
+ if (plan.version !== 1 ||
231
+ plan.from !== from ||
232
+ plan.to !== to ||
233
+ !Array.isArray(plan.links) ||
234
+ plan.links.some((link) => !link ||
235
+ !isPathSegment(link.profile) ||
236
+ EXAMPLE_PROFILES.includes(link.profile) ||
237
+ typeof link.target !== "string" ||
238
+ typeof link.path !== "string" ||
239
+ isAbsolute(link.path) ||
240
+ link.path.split(/[\\/]/).some((part) => part === "" || part === "." || part === "..")))
241
+ throw new Error("invalid profile repair journal");
242
+ return plan;
243
+ }
244
+ function saveProfileRepairPlan(path, plan) {
245
+ mkdirSync(dirname(path), { recursive: true, mode: 0o700 });
246
+ const tmp = `${path}.${randomUUID()}.tmp`;
247
+ try {
248
+ const fd = openSync(tmp, "wx", 0o600);
249
+ try {
250
+ writeFileSync(fd, JSON.stringify(plan));
251
+ fsyncSync(fd);
252
+ }
253
+ finally {
254
+ closeSync(fd);
255
+ }
256
+ renameSync(tmp, path);
257
+ const dir = openSync(dirname(path), "r");
258
+ try {
259
+ fsyncSync(dir);
260
+ }
261
+ finally {
262
+ closeSync(dir);
263
+ }
264
+ }
265
+ finally {
266
+ rmSync(tmp, { force: true });
267
+ }
268
+ }
269
+ function profileLinks(root, profile) {
270
+ if (lstatSync(root).isSymbolicLink())
271
+ return [];
272
+ const links = [];
273
+ const walk = (rel) => {
274
+ for (const entry of readdirSync(join(root, rel), { withFileTypes: true })) {
275
+ const path = rel === "" ? entry.name : join(rel, entry.name);
276
+ if (entry.isSymbolicLink())
277
+ links.push({ profile, path, target: readlinkSync(join(root, path)) });
278
+ else if (entry.isDirectory())
279
+ walk(path);
280
+ }
281
+ };
282
+ walk("");
283
+ return links;
284
+ }
285
+ function homeHoldsLink(path) {
286
+ try {
287
+ return lstatSync(path).isSymbolicLink();
288
+ }
289
+ catch {
290
+ return false;
291
+ }
292
+ }
293
+ /** Recover link publication even when rename succeeded before interruption. */
294
+ function repairProfileLinks(plan) {
295
+ const relocated = (profile) => !existsSync(join(plan.from, profile)) && isDirectory(join(plan.to, profile));
296
+ for (const link of plan.links) {
297
+ const oldAt = join(plan.from, link.profile, link.path);
298
+ const at = join(relocated(link.profile) ? plan.to : plan.from, link.profile, link.path);
299
+ // The snapshot walker never traversed symlinked directories. A changed
300
+ // parent must not redirect journal replay outside the captured profile.
301
+ let parent = join(relocated(link.profile) ? plan.to : plan.from, link.profile);
302
+ for (const part of ["", ...link.path.split(sep).slice(0, -1)]) {
303
+ parent = part === "" ? parent : join(parent, part);
304
+ const st = lstatSync(parent);
305
+ if (!st.isDirectory() || st.isSymbolicLink())
306
+ throw new Error(`profile directory changed during migration: ${link.profile}/${link.path}`);
307
+ }
308
+ const was = resolve(dirname(oldAt), link.target);
309
+ let target = was;
310
+ for (const base of [plan.from, realpathSync(plan.from)]) {
311
+ if (!within(base, was) || was === base)
312
+ continue;
313
+ const rel = relative(base, was);
314
+ if (relocated(rel.split(sep)[0]))
315
+ target = join(plan.to, rel);
316
+ }
317
+ // Relative links that already name the correct place retain their spelling.
318
+ if (resolve(dirname(at), link.target) === target)
319
+ continue;
320
+ try {
321
+ const st = lstatSync(at);
322
+ if (!st.isSymbolicLink())
323
+ throw new Error(`profile link changed during migration: ${link.profile}/${link.path}`);
324
+ const current = readlinkSync(at);
325
+ if (resolve(dirname(at), current) === target)
326
+ continue;
327
+ if (current !== link.target)
328
+ throw new Error(`profile link changed during migration: ${link.profile}/${link.path}`);
329
+ }
330
+ catch (err) {
331
+ if (err.code !== "ENOENT")
332
+ throw err;
333
+ }
334
+ const tmp = `${at}.${randomUUID()}.tmp`;
335
+ try {
336
+ symlinkSync(target, tmp);
337
+ renameSync(tmp, at);
338
+ }
339
+ finally {
340
+ rmSync(tmp, { force: true });
341
+ }
342
+ }
343
+ }
344
+ /**
345
+ * Move every install profile out of the checkout's `profiles/` into the
346
+ * config home's — every admissible profile directory except `EXAMPLE_PROFILES`.
347
+ * Same discipline as the config move: idempotent (a second run finds nothing
348
+ * left to move), an identical copy already in the home just drops the
349
+ * checkout's, and a differing one is a conflict that touches nothing.
350
+ *
351
+ * While `$QCR_CONFIG` is set nothing moves, exactly like the config half: the
352
+ * compose route mounts the directory holding that file (bring-up's
353
+ * `configMountOf`), not the config home, so a profile moved into the home
354
+ * would vanish from the container and fail the daemon's boot. The operator
355
+ * who named the config also decides where its profiles sit (beside it is on
356
+ * the lookup path).
357
+ */
358
+ export function migrateProfiles(opts) {
359
+ const env = opts.env ?? process.env;
360
+ const fromBase = join(opts.root, PROFILES_DIR);
361
+ const toBase = join(configHome(env), PROFILES_DIR);
362
+ if (!isDirectory(fromBase))
363
+ return [];
364
+ // A config home that IS the checkout: its profiles are already home.
365
+ if (samePath(fromBase, toBase))
366
+ return [];
367
+ const outcomes = [];
368
+ const realBase = realpathSync(fromBase);
369
+ // A link to a sibling that an earlier, interrupted run already moved into
370
+ // the home dangles in the checkout; it still names a profile, and that
371
+ // sibling's new place is where it now points.
372
+ const movedSibling = (link) => {
373
+ let target;
374
+ try {
375
+ target = readlinkSync(link);
376
+ }
377
+ catch {
378
+ return null;
379
+ }
380
+ const abs = resolve(fromBase, target);
381
+ for (const base of [fromBase, realBase]) {
382
+ if (!within(base, abs) || abs === base)
383
+ continue;
384
+ const moved = join(toBase, relative(base, abs));
385
+ if (isDirectory(moved))
386
+ return moved;
387
+ }
388
+ return null;
389
+ };
390
+ const names = readdirSync(fromBase, { withFileTypes: true })
391
+ // A symlinked profile dir counts: strandedCheckoutProfile (stat-based)
392
+ // names it, so migrate must have an outcome for it.
393
+ .filter((e) => (e.isDirectory() ||
394
+ (e.isSymbolicLink() &&
395
+ (isDirectory(join(fromBase, e.name)) ||
396
+ movedSibling(join(fromBase, e.name)) !== null))) &&
397
+ isPathSegment(e.name) &&
398
+ !EXAMPLE_PROFILES.includes(e.name))
399
+ .map((e) => e.name)
400
+ .sort();
401
+ const override = (env.QCR_CONFIG ?? "").trim();
402
+ if (override !== "") {
403
+ return names.map((name) => ({ kind: "override", name, path: resolve(override) }));
404
+ }
405
+ const repairPath = join(toBase, ".qcr-profile-repair.json");
406
+ const previousPlan = profileRepairPlan(repairPath, fromBase, toBase);
407
+ repairProfileLinks(previousPlan);
408
+ // Resolve all duplicate comparisons before sibling moves can dangle links.
409
+ const equalTrees = new Map();
410
+ const conflicts = new Set();
411
+ for (const name of names) {
412
+ const from = join(fromBase, name), to = join(toBase, name);
413
+ if (!isDirectory(from) ||
414
+ !existsSync(to) ||
415
+ samePath(from, to) ||
416
+ (isDirectory(to) && linksInto(to, from)))
417
+ continue;
418
+ const equal = isDirectory(to) && sameTree(from, to);
419
+ equalTrees.set(name, equal);
420
+ if (!equal)
421
+ conflicts.add(name);
422
+ }
423
+ const linkMap = new Map(previousPlan.links.map((link) => [`${link.profile}/${link.path}`, link]));
424
+ for (const name of names) {
425
+ if (!isDirectory(join(fromBase, name)))
426
+ continue;
427
+ // A conflicted profile stays in the checkout, so its links to a sibling
428
+ // that moves are repaired like a moved profile's.
429
+ const kept = equalTrees.get(name) === true;
430
+ for (const link of profileLinks(join(fromBase, name), name)) {
431
+ // A duplicate's checkout copy is deleted and the home's stays as it is:
432
+ // only a link the home copy holds as a link is the repair's to redirect.
433
+ if (kept && !homeHoldsLink(join(toBase, name, link.path)))
434
+ continue;
435
+ linkMap.set(`${name}/${link.path}`, link);
436
+ }
437
+ }
438
+ const repairPlan = {
439
+ version: 1,
440
+ from: fromBase,
441
+ to: toBase,
442
+ links: [...linkMap.values()],
443
+ };
444
+ if (repairPlan.links.length > 0)
445
+ saveProfileRepairPlan(repairPath, repairPlan);
446
+ // Linked profiles resolve before anything moves, and move last: a link to a
447
+ // sibling in the checkout (`house -> house-real`) must follow that sibling
448
+ // into the home, not point at the spot it was just moved out of.
449
+ const linkTargets = new Map();
450
+ for (const name of names) {
451
+ const from = join(fromBase, name);
452
+ if (!lstatSync(from).isSymbolicLink())
453
+ continue;
454
+ const target = isDirectory(from) ? realpathSync(from) : movedSibling(from);
455
+ if (target !== null)
456
+ linkTargets.set(name, target);
457
+ }
458
+ const ordered = [
459
+ ...names.filter((n) => !linkTargets.has(n)),
460
+ ...names.filter((n) => linkTargets.has(n)),
461
+ ];
462
+ const linkTargetNow = (real) => {
463
+ const rel = relative(realBase, real);
464
+ if (rel === "" || rel.startsWith("..") || isAbsolute(rel) || existsSync(real))
465
+ return real;
466
+ const moved = join(toBase, rel);
467
+ return existsSync(moved) ? moved : real;
468
+ };
469
+ for (const name of ordered) {
470
+ const from = join(fromBase, name);
471
+ const to = join(toBase, name);
472
+ if (existsSync(to)) {
473
+ // A dangling checkout link (its sibling already moved) has no tree to
474
+ // compare: it is a duplicate only when the home's entry IS where it now
475
+ // points — an earlier run re-pointed it and stopped before removing
476
+ // this one — and a conflict otherwise.
477
+ if (!isDirectory(from)) {
478
+ const moved = linkTargets.get(name);
479
+ if (moved !== undefined && samePath(to, moved)) {
480
+ unlinkSync(from);
481
+ outcomes.push({ kind: "deduplicated", name, from, to });
482
+ }
483
+ else {
484
+ outcomes.push({ kind: "conflict", name, from, to });
485
+ }
486
+ continue;
487
+ }
488
+ // Per-name identity: the base-dir check does not see a home profile
489
+ // linked to the checkout's, and "deduplicating" that deletes the only copy.
490
+ if (samePath(from, to) || (isDirectory(to) && linksInto(to, from))) {
491
+ outcomes.push({ kind: "aliased", name, from, to });
492
+ continue;
493
+ }
494
+ if (!isDirectory(to) || equalTrees.get(name) !== true) {
495
+ outcomes.push({ kind: "conflict", name, from, to });
496
+ continue;
497
+ }
498
+ rmSync(from, { recursive: true });
499
+ outcomes.push({ kind: "deduplicated", name, from, to });
500
+ continue;
501
+ }
502
+ mkdirSync(toBase, { recursive: true, mode: 0o700 });
503
+ if (lstatSync(from).isSymbolicLink()) {
504
+ // A linked pack stays linked: re-point from the home at its real target
505
+ // (a relative link renamed as-is would resolve against the home).
506
+ symlinkSync(linkTargetNow(linkTargets.get(name) ?? realpathSync(from)), to);
507
+ unlinkSync(from);
508
+ outcomes.push({ kind: "moved", name, from, to });
509
+ continue;
510
+ }
511
+ try {
512
+ renameSync(from, to);
513
+ }
514
+ catch (err) {
515
+ if (err.code !== "EXDEV")
516
+ throw err;
517
+ // verbatimSymlinks: a relative link inside the profile keeps pointing
518
+ // inside the copy, not back into the source tree removed next.
519
+ // The copy lands under a temporary name and is renamed into place, so an
520
+ // interrupted copy never leaves a partial profile at the destination.
521
+ const tmp = `${to}.${randomUUID()}.tmp`;
522
+ try {
523
+ cpSync(from, tmp, { recursive: true, verbatimSymlinks: true });
524
+ renameSync(tmp, to);
525
+ }
526
+ finally {
527
+ rmSync(tmp, { recursive: true, force: true });
528
+ }
529
+ rmSync(from, { recursive: true });
530
+ }
531
+ outcomes.push({ kind: "moved", name, from, to });
532
+ }
533
+ repairProfileLinks(repairPlan);
534
+ rmSync(repairPath, { force: true });
535
+ return outcomes.sort((a, b) => (a.name < b.name ? -1 : a.name > b.name ? 1 : 0));
536
+ }
537
+ /** What the profile half of `qcr install migrate` prints; a conflict fails. */
538
+ export function profileMigrateReport(outcomes) {
539
+ if (outcomes.length === 0) {
540
+ return { code: 0, lines: ["profiles: none in the checkout beyond the generic examples"] };
541
+ }
542
+ const lines = [];
543
+ let code = 0;
544
+ for (const o of outcomes) {
545
+ switch (o.kind) {
546
+ case "moved":
547
+ lines.push(`moved profile ${o.name}: ${o.from} → ${o.to}`);
548
+ break;
549
+ case "deduplicated":
550
+ lines.push(`profile ${o.name}: ${o.to} already held the same files — removed ${o.from}`);
551
+ break;
552
+ case "aliased":
553
+ lines.push(`profile ${o.name}: ${o.to} is a link to ${o.from} (or the reverse, or links into it) — one copy, already read from the home; nothing moved or removed`);
554
+ break;
555
+ case "override":
556
+ lines.push(`profile ${o.name}: QCR_CONFIG names ${o.path} — migrate moves no profile while it is set ` +
557
+ `(put it in profiles/ beside that file, or unset QCR_CONFIG and re-run)`);
558
+ break;
559
+ case "conflict":
560
+ code = 1;
561
+ lines.push(`refused profile ${o.name}: ${o.from} and ${o.to} both exist and differ — nothing was touched. ` +
562
+ `Keep the one you want at ${o.to}, delete the checkout copy, and re-run.`);
563
+ break;
564
+ }
565
+ }
566
+ if (outcomes.some((o) => o.kind === "moved" || o.kind === "deduplicated")) {
567
+ lines.push("A moved profile tracked in git shows as a deletion. scripts/deploy.sh release ships the config home's " +
568
+ "profiles/ to the VM with the config.");
569
+ }
570
+ return { code, lines };
571
+ }
572
+ // ---- secrets: what only migrate and the operator read ------------------------
573
+ //
574
+ // The companion's OpenViking key file is the one credential deliberately kept
575
+ // out of the config home: that home is mounted into the reviewer container on
576
+ // the compose route and shipped to the VM, and the file
577
+ // holds the companion key review sessions must never read (rule 8). It lives
578
+ // in a sibling tree, `$XDG_CONFIG_HOME/qcr-operator/<install>/`, that nothing
579
+ // mounts or ships.
580
+ export const KEYS_FILE = "openviking-keys.env";
581
+ /** The legacy secrets dir when it still holds anything — an install that has
582
+ * not run `qcr install migrate`. Never read; only named, so a missing
583
+ * credential can point at the way out. Null when it is gone or empty. */
584
+ export function strandedLegacySecrets(env = process.env) {
585
+ const dir = legacySecretsDir(env);
586
+ try {
587
+ return readdirSync(dir).length > 0 ? dir : null;
588
+ }
589
+ catch {
590
+ return null;
591
+ }
592
+ }
593
+ /** `$XDG_CONFIG_HOME/qcr-operator/<install>` — the operator-only credentials
594
+ * that must never reach a container (see the header of this section). */
595
+ export function operatorHome(env = process.env) {
596
+ return join(xdgBase(env.XDG_CONFIG_HOME, env, ".config"), "qcr-operator", installName(env));
597
+ }
598
+ /** `$XDG_STATE_HOME/qcr-operator/<install>` — operator-side runtime state
599
+ * that belongs in neither home: not the state home (the companion mounts it
600
+ * read-write) and not the config home (shipped to the VM). */
601
+ export function operatorStateHome(env = process.env) {
602
+ return join(xdgBase(env.XDG_STATE_HOME, env, join(".local", "state")), "qcr-operator", installName(env));
603
+ }
604
+ /** The companion's `commands/` directory under the state home it mounts rw
605
+ * (the companion boundary): the TUI forwards every file in it as a command of
606
+ * the companion's tier, so it is the companion's alone — every other container
607
+ * that mounts the state home (the scan sandbox) gets it covered. */
608
+ export const COMPANION_COMMANDS_DIR = "commands";
609
+ /** Where the host writes the companion's down-scoped, read-only GitHub token
610
+ * as an env file (`src/tui/ghread.ts`). Mounted read-only into the
611
+ * companion, and only this directory — never the secrets it was minted from. */
612
+ export function companionGithubDir(env = process.env) {
613
+ return join(operatorStateHome(env), "companion-github");
614
+ }
615
+ /** Where the host keeps the companion's read-only mirror of the live config
616
+ * (`CompanionLifecycle.syncConfigMirror`): a copy refreshed while the
617
+ * TUI runs, mounted as a directory so a rename-replaced config.toml is seen.
618
+ * config.toml holds no secret values (secrets are files under `secrets/`). */
619
+ export function companionConfigMirrorDir(env = process.env) {
620
+ return join(operatorStateHome(env), "companion-config");
621
+ }
622
+ /** Where `qcr scan start` copies the live config for a scan sandbox
623
+ * container (src/scanbox.ts), which mounts this directory read-only: the
624
+ * companion's mirror, kept apart so a scan never rewrites what a running
625
+ * companion reads. */
626
+ export function scanConfigMirrorDir(env = process.env) {
627
+ return join(operatorStateHome(env), "scan-config");
628
+ }
629
+ /**
630
+ * The companion's OpenViking key file (two user keys, handed to the companion
631
+ * container by `--env-file`, so no value ever reaches an argv):
632
+ * `$QCR_OPENVIKING_KEYS` as given, else the operator home's file — whether or
633
+ * not it exists yet. The legacy `~/.config/quickreview-bot/` copy is never read.
634
+ */
635
+ export function locateKeysFile(opts = {}) {
636
+ const env = opts.env ?? process.env;
637
+ const home = join(operatorHome(env), KEYS_FILE);
638
+ const override = (env.QCR_OPENVIKING_KEYS ?? "").trim();
639
+ if (override !== "")
640
+ return { path: override, source: "override", home };
641
+ return { path: home, source: "home", home };
642
+ }
643
+ function moveFile(from, to) {
644
+ try {
645
+ renameSync(from, to);
646
+ }
647
+ catch (err) {
648
+ // ~/.config and XDG_CONFIG_HOME on different filesystems: copy, keep the
649
+ // mode (copyFileSync does not promise it), then remove.
650
+ if (err.code !== "EXDEV")
651
+ throw err;
652
+ copyKeepingMode(from, to);
653
+ unlinkSync(from);
654
+ }
655
+ }
656
+ /** Copy `from` to a `to` that must not exist yet, with `from`'s mode bits. */
657
+ function copyKeepingMode(from, to) {
658
+ const mode = statSync(from).mode & 0o7777;
659
+ copyFileSync(from, to, fsConstants.COPYFILE_EXCL);
660
+ chmodSync(to, mode);
661
+ }
662
+ function ensurePrivateDir(dir) {
663
+ if (existsSync(dir))
664
+ return;
665
+ mkdirSync(dir, { recursive: true, mode: 0o700 });
666
+ chmodSync(dir, 0o700);
667
+ }
668
+ function listDir(dir) {
669
+ try {
670
+ return readdirSync(dir).sort();
671
+ }
672
+ catch {
673
+ return [];
674
+ }
675
+ }
676
+ function entryExists(p) {
677
+ try {
678
+ lstatSync(p);
679
+ return true;
680
+ }
681
+ catch {
682
+ return false;
683
+ }
684
+ }
685
+ function isRegularFile(p) {
686
+ try {
687
+ return statSync(p).isFile();
688
+ }
689
+ catch {
690
+ return false;
691
+ }
692
+ }
693
+ /**
694
+ * Move every file in `~/.config/quickreview-bot/` into `<config home>/secrets/`
695
+ * — except the companion key file, which goes to the operator home (it must
696
+ * never sit where a container can read it). A rename, so mode bits travel
697
+ * with the file; the destination dirs are created 0700. Idempotent, and it
698
+ * never overwrites a secret it did not move: a differing pair is a conflict.
699
+ *
700
+ * The legacy dir may be what a compose stack mounts (`repointComposeSecrets`
701
+ * re-points that mount only onto a home that can stand in for it), so it is
702
+ * emptied whole or not at all: when an entry has to stay there with no
703
+ * stand-in in the home, the other secrets are COPIED into the home and the
704
+ * legacy dir keeps the complete set. Once the operator settles that entry, a
705
+ * re-run moves the rest.
706
+ */
707
+ export function migrateSecrets(opts = {}) {
708
+ const env = opts.env ?? process.env;
709
+ const from = legacySecretsDir(env);
710
+ const to = secretsHome(env);
711
+ let st;
712
+ try {
713
+ st = lstatSync(from);
714
+ }
715
+ catch {
716
+ return { kind: "nothing", from, to };
717
+ }
718
+ if (st.isSymbolicLink())
719
+ return { kind: "symlink", from, to };
720
+ if (!st.isDirectory())
721
+ return { kind: "nothing", from, to };
722
+ const keysPinned = (env.QCR_OPENVIKING_KEYS ?? "").trim() !== "";
723
+ const keysHome = locateKeysFile({ env }).home;
724
+ const plan = readdirSync(from)
725
+ .sort()
726
+ .map((name) => {
727
+ const src = join(from, name);
728
+ const isKeys = name === KEYS_FILE;
729
+ const dest = isKeys ? keysHome : join(to, name);
730
+ const base = { name, src, dest, isKeys };
731
+ if (!lstatSync(src).isFile())
732
+ return { ...base, act: "skip", why: "not a regular file" };
733
+ if (isKeys && keysPinned)
734
+ return {
735
+ ...base,
736
+ act: "skip",
737
+ why: "QCR_OPENVIKING_KEYS is set — that variable names the key file",
738
+ };
739
+ if (!existsSync(dest))
740
+ return { ...base, act: "move" };
741
+ // A home dir linked to the legacy one reads the SAME file here: the byte
742
+ // compare would pass and the unlink below would delete the only copy.
743
+ if (samePath(src, dest))
744
+ return { ...base, act: "skip", why: `${dest} is the same file (a link) — nothing to move` };
745
+ return { ...base, act: readFileSync(src).equals(readFileSync(dest)) ? "same" : "conflict" };
746
+ });
747
+ // What stays behind and leaves the home unable to stand in for the legacy
748
+ // dir as a mount — the rule `repointComposeSecrets` holds a mount by. The
749
+ // key file never rides the mount.
750
+ const held = plan
751
+ .filter((f) => !f.isKeys && (f.act === "skip" || f.act === "conflict"))
752
+ .filter((f) => !standsIn(f.src, join(to, f.name)))
753
+ .map((f) => f.name);
754
+ const keepWhole = held.length > 0;
755
+ const kept = `kept in ${from} too: ${held.join(", ")} stays there, so it keeps a complete set`;
756
+ const files = [];
757
+ for (const f of plan) {
758
+ const { name, dest: fileTo } = f;
759
+ switch (f.act) {
760
+ case "skip":
761
+ files.push({ name, to: fileTo, outcome: "skipped", why: f.why });
762
+ break;
763
+ case "conflict":
764
+ files.push({ name, to: fileTo, outcome: "conflict" });
765
+ break;
766
+ case "same":
767
+ if (keepWhole && !f.isKeys) {
768
+ files.push({
769
+ name,
770
+ to: fileTo,
771
+ outcome: "skipped",
772
+ why: `${fileTo} holds the same bytes; ${kept}`,
773
+ });
774
+ break;
775
+ }
776
+ unlinkSync(f.src);
777
+ files.push({ name, to: fileTo, outcome: "deduplicated" });
778
+ break;
779
+ case "move":
780
+ ensurePrivateDir(dirname(fileTo));
781
+ if (keepWhole && !f.isKeys) {
782
+ // A dangling link where the copy would go: a rename replaces it,
783
+ // a copy never writes through it.
784
+ if (entryExists(fileTo)) {
785
+ files.push({
786
+ name,
787
+ to: fileTo,
788
+ outcome: "skipped",
789
+ why: `${fileTo} is a dangling link; ${kept}`,
790
+ });
791
+ break;
792
+ }
793
+ copyKeepingMode(f.src, fileTo);
794
+ files.push({ name, to: fileTo, outcome: "copied", why: kept });
795
+ break;
796
+ }
797
+ moveFile(f.src, fileTo);
798
+ files.push({ name, to: fileTo, outcome: "moved" });
799
+ break;
800
+ }
801
+ }
802
+ // A dir kept whole holds every secret the home does — what an earlier run
803
+ // moved out comes back as a copy, never over a file already there.
804
+ if (keepWhole)
805
+ for (const name of listDir(to)) {
806
+ const back = join(from, name);
807
+ if (name === KEYS_FILE || entryExists(back) || !isRegularFile(join(to, name)))
808
+ continue;
809
+ copyKeepingMode(join(to, name), back);
810
+ files.push({ name, to: back, outcome: "restored", why: `${from} is kept whole` });
811
+ }
812
+ const remaining = readdirSync(from).sort();
813
+ if (remaining.length === 0)
814
+ rmdirSync(from);
815
+ return { kind: "done", from, to, files, held, remaining };
816
+ }
817
+ /** What the secrets half of `qcr install migrate` prints, and its exit code.
818
+ * Names only — a secret's value never reaches a line. */
819
+ export function secretsMigrateReport(m) {
820
+ if (m.kind === "nothing")
821
+ return {
822
+ code: 0,
823
+ lines: [`secrets: no legacy dir ${m.from} — nothing to move (the home is ${m.to})`],
824
+ };
825
+ if (m.kind === "symlink")
826
+ return {
827
+ code: 0,
828
+ lines: [
829
+ `secrets: ${m.from} is a symlink — left alone (point it, or [github] secrets_dir, at ${m.to} yourself)`,
830
+ ],
831
+ };
832
+ const lines = [];
833
+ let code = 0;
834
+ for (const f of m.files) {
835
+ switch (f.outcome) {
836
+ case "moved":
837
+ lines.push(`secrets: moved ${f.name} → ${f.to}`);
838
+ break;
839
+ case "copied":
840
+ lines.push(`secrets: copied ${f.name} → ${f.to} (${f.why})`);
841
+ break;
842
+ case "restored":
843
+ lines.push(`secrets: copied ${f.name} back to ${f.to} from ${m.to} (${f.why}, so a compose stack that mounts it finds every secret)`);
844
+ break;
845
+ case "deduplicated":
846
+ lines.push(`secrets: ${f.to} already held the same bytes — removed the legacy ${f.name}`);
847
+ break;
848
+ case "conflict":
849
+ code = 1;
850
+ lines.push(`secrets: refused ${f.name}: ${join(m.from, f.name)} and ${f.to} both exist and differ — nothing was touched; keep one and re-run`);
851
+ break;
852
+ case "skipped":
853
+ lines.push(`secrets: left ${f.name} in ${m.from} (${f.why})`);
854
+ break;
855
+ }
856
+ }
857
+ if (m.files.length === 0)
858
+ lines.push(`secrets: ${m.from} is empty`);
859
+ lines.push(m.remaining.length === 0
860
+ ? `secrets: removed the now-empty ${m.from}; every reader finds them in ${m.to} (restart a running daemon, TUI or companion)`
861
+ : m.held.length > 0
862
+ ? `secrets: ${m.from} still holds ${m.remaining.join(", ")} — settle ${m.held.join(", ")} by hand and re-run; the locator's readers read ${m.to}, and a compose stack that mounts ${m.from} still finds every secret there`
863
+ : `secrets: ${m.from} still holds ${m.remaining.join(", ")} — resolve those by hand and re-run; the locator's readers read ${m.to}`);
864
+ return { code, lines };
865
+ }
866
+ export function repointComposeSecrets(opts) {
867
+ const env = opts.env ?? process.env;
868
+ const file = join(opts.root, ".env");
869
+ let text;
870
+ try {
871
+ text = readFileSync(file, "utf8");
872
+ }
873
+ catch {
874
+ return { kind: "none" };
875
+ }
876
+ const line = /^QCR_SECRETS_DIR=(.*)$/m.exec(text);
877
+ if (!line)
878
+ return { kind: "none" };
879
+ const value = (line[1] ?? "").trim().replace(/^(["'])(.*)\1$/, "$2");
880
+ if (value === "" || !isLegacySecretsSpelling(value, env))
881
+ return { kind: "none" };
882
+ const to = secretsHome(env);
883
+ if (!existsSync(to))
884
+ return { kind: "none" };
885
+ // Repoint only onto a home that holds everything the mounted dir still
886
+ // does, byte for byte — never swap a working mount for an empty, partial or
887
+ // different one (a conflict migrate refused leaves the running copy in the
888
+ // legacy dir and another in the home). The key file is exempt: it goes to
889
+ // the operator home, never into the mount.
890
+ const legacyDir = legacySecretsDir(env);
891
+ let legacyNames = [];
892
+ try {
893
+ legacyNames = readdirSync(legacyDir);
894
+ }
895
+ catch {
896
+ // Gone: migrate moved everything and removed it.
897
+ }
898
+ const mounted = legacyNames.filter((n) => n !== KEYS_FILE).sort();
899
+ const missing = mounted.filter((n) => !existsSync(join(to, n)));
900
+ const differ = mounted.filter((n) => existsSync(join(to, n)) && !standsIn(join(legacyDir, n), join(to, n)));
901
+ if (missing.length > 0 || differ.length > 0)
902
+ return { kind: "held", file, from: value, to, missing, differ };
903
+ const next = text.replace(/^QCR_SECRETS_DIR=.*$/m, `QCR_SECRETS_DIR=${to}`);
904
+ const mode = statSync(file).mode & 0o7777;
905
+ const tmp = join(opts.root, ".env.qcr-migrate.tmp");
906
+ writeFileSync(tmp, next, { mode });
907
+ chmodSync(tmp, mode);
908
+ renameSync(tmp, file);
909
+ return { kind: "repointed", file, from: value, to };
910
+ }
911
+ /** Whether the home's entry `b` can stand in for the mounted one `a`: two
912
+ * regular files must hold identical bytes; two non-files (migrate skips
913
+ * those) pass; a file against a non-file, a missing `b`, or anything
914
+ * unreadable, does not. The one rule both `migrateSecrets` (what keeps the
915
+ * legacy dir whole) and `repointComposeSecrets` (what holds the mount) use. */
916
+ function standsIn(a, b) {
917
+ try {
918
+ const aFile = statSync(a).isFile();
919
+ const bFile = statSync(b).isFile();
920
+ if (!aFile || !bFile)
921
+ return !aFile && !bFile;
922
+ return readFileSync(a).equals(readFileSync(b));
923
+ }
924
+ catch {
925
+ return false;
926
+ }
927
+ }
928
+ export function composeRepointReport(r) {
929
+ if (r.kind === "held") {
930
+ const why = [
931
+ ...(r.missing.length > 0 ? [`${r.to} lacks ${r.missing.join(", ")}`] : []),
932
+ ...(r.differ.length > 0 ? [`${r.to} holds a different ${r.differ.join(", ")}`] : []),
933
+ ].join("; ");
934
+ return [
935
+ `secrets: ${r.file} still mounts ${r.from} (QCR_SECRETS_DIR) — left as is: ${why}; ` +
936
+ "settle them there, then re-run migrate",
937
+ ];
938
+ }
939
+ return r.kind === "none"
940
+ ? []
941
+ : [
942
+ `secrets: ${r.file} mounted the legacy dir (QCR_SECRETS_DIR=${r.from}) — it now names ${r.to}; ` +
943
+ "recreate the compose stack (`docker compose up -d`) so the container mounts it",
944
+ ];
945
+ }
946
+ //# sourceMappingURL=install.js.map