@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,782 @@
1
+ #!/usr/bin/env bash
2
+ # The release image's one entrypoint (docker/Dockerfile): mode dispatch.
3
+ #
4
+ # docker run <img> [MODE] [ARGS...]
5
+ #
6
+ # cli (default) qcr, daemonless: review, scan, version, ... ARGS go to
7
+ # dist/src/cli.js. A first argument that is not a mode name is a
8
+ # cli argument, so `docker run <img> version --json` works.
9
+ # daemon the always-on bot: dist/src/wire.js under a tmux server.
10
+ # companion the pi companion container: a tmux server, kept alive.
11
+ # tui the operator TUI (dist/src/cli.js tui).
12
+ # login pi's own /login, typed for the user (scanbox loginInPi).
13
+ # mint a GitHub App installation token on stdout (scripts/mint-token.sh).
14
+ # install the host wrapper, pinned to this image (scripts/install-wrapper.sh):
15
+ # `-v ~/.local/bin:/out` writes /out/qcr, otherwise `| sh` installs it.
16
+ # worker the per-round bot worker.
17
+ #
18
+ # `install where|migrate` and `companion up|down|status|rebuild` are qcr verbs
19
+ # that share a mode's name: with arguments they go to the cli.
20
+ #
21
+ # What every mode does before it hands over:
22
+ # - asserts config.toml [pi] version == the installed pi package's version,
23
+ # and refuses to start otherwise (the pin lives in four places; this is the
24
+ # one that sees the running image);
25
+ # - makes <root>/state writable-or-fatal (the MutationGate's state/dryrun
26
+ # and every other state file live there).
27
+ # No npm build, no state symlink: the image is built, /opt/qcr is read-only to
28
+ # every runtime uid, and <root>/state is a world-writable mount point.
29
+ #
30
+ # bash-guard (extensions/cli/bash-guard.ts) is no longer registered in pi's global
31
+ # settings: every lens and worker session gets it from the factory, and
32
+ # the takeover and debug pi load it by path. The per-call cli mode runs in a
33
+ # throwaway container that is the sandbox, and puts the model's
34
+ # tools under another uid, so the kernel keeps them off the
35
+ # token-holding Node process (/proc/<pid>/mem and environ):
36
+ # - started as root (--user 0:0 --cap-drop ALL --cap-add SETUID --cap-add
37
+ # SETGID), the cli mode re-executes this script as QCR_RUN_UID:QCR_RUN_GID
38
+ # (default 1000:1000) with CAP_SETUID/CAP_SETGID as ambient capabilities,
39
+ # and exports QCR_TOOL_UID/QCR_TOOL_GID (QCR_TOOLS_AS, default 65534, and the run gid);
40
+ # - the engine then runs everything that executes the model's commands
41
+ # through setpriv (packages/pi-plugin/src/engine/tooluid.ts): the SDK session's bash tool
42
+ # (packages/pi-plugin/src/engine/pisdk.ts), a pi child (toolIsolation), a debug round's
43
+ # interactive pi (src/engine/debugpi.ts). They get the tool uid, no
44
+ # capabilities and no_new_privs. The SDK session's file tools (read, grep,
45
+ # find, ls, edit, write) run in the engine's own uid, so they are fenced off
46
+ # /proc, /run/qcr-in and the agent dir (packages/pi-plugin/src/engine/toolfence.ts). The tool
47
+ # uid shares the run gid, which is how it reaches the group-writable state;
48
+ # it is a different uid, so /proc/<node pid>/mem and environ are closed to it;
49
+ # - started as any other uid, no separation is possible: the cli mode says
50
+ # so, exports QCR_TOOL_UID_REQUIRED=1, and the engine then refuses to
51
+ # run the model's tools unless QCR_ALLOW_SHARED_TOOL_UID=1 (version, doctor
52
+ # and every other verb that runs none are unaffected).
53
+ # The daemon mode (the always-on bot) makes the same split from a
54
+ # NON-root start, so `docker exec` into the bot keeps landing as its uid: the
55
+ # image's setid helper (/usr/local/libexec/qcr/qcr-setid, file capabilities, gate
56
+ # group QCR_SETID_GID) is probed, and the daemon exports QCR_TOOL_UID (QCR_TOOLS_AS,
57
+ # default 65534), QCR_TOOL_GID (the image's compiled tool gid, QCR_IMAGE_TOOL_GID; the
58
+ # daemon must already be a member of it) and QCR_SETPRIV_BIN; its workers run
59
+ # every model command through the helper (packages/pi-plugin/src/engine/tooluid.ts setidHelperOf).
60
+ # A probe that fails refuses the start (QCR_ALLOW_SHARED_TOOL_UID=1 accepts the
61
+ # shared uid). Started as root instead, the daemon drops to QCR_RUN_UID the way
62
+ # the cli mode does. Either way the daemon opens the directories the model's
63
+ # scripts write to its group (share_tool_dirs) and nothing else: the secrets
64
+ # mount and pi's login stay unreadable to the tool uid.
65
+ # The login and tui modes run no engine and hold no GitHub token: they are
66
+ # not separated. pi holds its own OAuth token as the tools' uid, which no
67
+ # split hides from the tools it runs; the split protects the GitHub token.
68
+ #
69
+ # The login volume outlives every uid. `login` runs as the caller and
70
+ # leaves every entry of pi's agent dir in the fixed login group (QCR_LOGIN_GID,
71
+ # default 4747) at 0660/2770 when pi exits; the wrapper gives every call that
72
+ # mounts the volume that group (--group-add), and the cli mode keeps it across
73
+ # its uid drop (setpriv --groups). A review under another uid reads the login
74
+ # through the group; the model's tools, which clear their groups, do not; and
75
+ # a later login under yet another uid can still rewrite it.
76
+ #
77
+ # The daemon is the live bot and keeps the guard, the pinned-CLI check and the
78
+ # reviewer context stub it has always had (the VM's retired
79
+ # deploy/ansible/templates/entrypoint.sh.j2).
80
+ # The VM runs this image since the cutover: deploy/ansible/playbook.yml.
81
+ #
82
+ # Every mode that reaches pi needs a writable <root>/state and a writable HOME
83
+ # (pi settings are merged under ~/.pi on every cli start, `version` included):
84
+ # a read-only rootfs without a state mount and a writable HOME is refused here.
85
+ #
86
+ # Every line this script prints goes to stderr: a cli mode's stdout is the
87
+ # command's (--json), never ours.
88
+ set -euo pipefail
89
+
90
+ APP="${QCR_APP_ROOT:-$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)}"
91
+ STATE="$APP/state"
92
+
93
+ say() { echo "qcr-entrypoint: $*" >&2; }
94
+ die() {
95
+ echo "qcr-entrypoint: FATAL: $*" >&2
96
+ exit 1
97
+ }
98
+
99
+ # ---- mode ---------------------------------------------------------------------
100
+
101
+ # The group that owns the login volume's files (see the header).
102
+ LOGIN_GID="${QCR_LOGIN_GID:-4747}"
103
+ [[ "$LOGIN_GID" =~ ^[1-9][0-9]*$ ]] || die "QCR_LOGIN_GID must be a non-zero numeric group id ($LOGIN_GID)"
104
+
105
+ mode=cli
106
+ if [ "$#" -gt 0 ]; then
107
+ case "$1" in
108
+ install | mint | cli | daemon | worker | tui | companion | login)
109
+ mode="$1"
110
+ shift
111
+ ;;
112
+ esac
113
+ fi
114
+ case "$mode" in
115
+ install | companion)
116
+ if [ "$#" -gt 0 ]; then
117
+ set -- "$mode" "$@"
118
+ mode=cli
119
+ fi
120
+ ;;
121
+ esac
122
+
123
+ # ---- the model's tools run as another uid ---------------------------------
124
+
125
+ # The cli mode and the daemon mode run the engine (`daemon --preflight` reads
126
+ # mounts and runs none). See the header for the contract; the host wrapper
127
+ # owns the docker flags that make the cli's root start possible, and the
128
+ # VM's updater (deploy/qcr-update.sh) the daemon's.
129
+ isolate_tools() {
130
+ case "$mode" in
131
+ cli) ;;
132
+ daemon) [ "${1:-}" != --preflight ] || return 0 ;;
133
+ *) return 0 ;;
134
+ esac
135
+ if [ -n "${QCR_TOOLS_ISOLATED:-}" ]; then
136
+ # Second pass, already the run uid. Group-writable files are how the tool
137
+ # uid (same gid, different uid) shares state and pi's home with this one.
138
+ # The daemon keeps its umask: its workers set the group-writable one for
139
+ # what the model's tools share (src/botworker.ts), and what the daemon
140
+ # writes for a session to read stays its own.
141
+ [ "$mode" != cli ] || umask 002
142
+ return 0
143
+ fi
144
+ # Whatever the caller exported, only a split made here counts.
145
+ unset QCR_TOOL_UID QCR_TOOL_GID QCR_SETPRIV_BIN
146
+ if [ "$(id -u)" != 0 ]; then
147
+ if [ "$mode" = daemon ]; then
148
+ daemon_setid_helper
149
+ return 0
150
+ fi
151
+ export QCR_TOOL_UID_REQUIRED=1
152
+ return 0
153
+ fi
154
+ local run_uid="${QCR_RUN_UID:-1000}" run_gid="${QCR_RUN_GID:-1000}" tool_uid="${QCR_TOOLS_AS:-65534}"
155
+ [[ "$run_uid$run_gid$tool_uid" =~ ^[0-9]+$ && "$run_uid" != 0 && "$run_gid" != 0 && "$tool_uid" != 0 ]] ||
156
+ die "QCR_RUN_UID/QCR_RUN_GID/QCR_TOOLS_AS must be non-zero numeric ids"
157
+ [ "$run_uid" != "$tool_uid" ] || die "the tool uid must differ from the run uid ($run_uid)"
158
+ command -v setpriv >/dev/null || die "setpriv (util-linux) is needed for the tool uid split"
159
+ export QCR_TOOLS_ISOLATED=1 QCR_TOOL_UID="$tool_uid" QCR_TOOL_GID="$run_gid"
160
+ # The cli keeps the login group (the login volume); the daemon runs as a
161
+ # plain uid, as it does when docker starts it as one.
162
+ local groups="--groups=$LOGIN_GID"
163
+ [ "$mode" = cli ] || groups="--clear-groups"
164
+ exec setpriv --reuid="$run_uid" --regid="$run_gid" "$groups" \
165
+ --inh-caps=+setuid,+setgid --ambient-caps=+setuid,+setgid \
166
+ -- "${BASH_SOURCE[0]}" "$mode" "$@"
167
+ }
168
+
169
+ # The always-on bot. It runs as its own uid, not root, so every
170
+ # `docker exec` into it (the TUI's reads and messages, `tmux` for a takeover's
171
+ # pane, `qcr` in the container) keeps landing as that uid, and docker cannot
172
+ # give a non-root uid ambient capabilities. Its way to the tool uid is the
173
+ # image's setid helper (docker/Dockerfile): a copy of setpriv carrying
174
+ # CAP_SETUID/CAP_SETGID as file capabilities, runnable only by the gate group
175
+ # (QCR_SETID_GID, 4748), which the run spec gives the bot with --group-add. The
176
+ # model's tools run with no_new_privs and without that group, so the helper is
177
+ # nothing to them. The probe below proves the helper works here (it switches to
178
+ # the tool uid and runs `true`); where it does not, the bot refuses to start
179
+ # rather than run the model's tools in the uid that reads secrets/, unless
180
+ # QCR_ALLOW_SHARED_TOOL_UID=1 accepts that.
181
+ SETID_HELPER="${QCR_SETID_HELPER:-/usr/local/libexec/qcr/qcr-setid}"
182
+ daemon_setid_helper() {
183
+ local tool_uid="${QCR_TOOLS_AS:-${QCR_IMAGE_TOOL_UID:-65534}}" tool_gid="${QCR_IMAGE_TOOL_GID:-}" uid
184
+ uid="$(id -u)"
185
+ [[ "$tool_uid" =~ ^[1-9][0-9]*$ ]] || die "QCR_TOOLS_AS must be a non-zero numeric id ($tool_uid)"
186
+ [ "$tool_uid" != "$uid" ] || die "the tool uid must differ from the daemon's uid ($uid)"
187
+ if [[ "$tool_gid" =~ ^[1-9][0-9]*$ ]] && [ -x "$SETID_HELPER" ] &&
188
+ "$SETID_HELPER" --reuid="$tool_uid" --regid="$tool_gid" --clear-groups \
189
+ --inh-caps=-all --ambient-caps=-all --no-new-privs -- true 2>/dev/null; then
190
+ # The daemon shares the directories the model's scripts write through the
191
+ # tool's own group, so it must be a member of it (the run spec's second
192
+ # --group-add); a daemon outside it could not read what the tools write.
193
+ id -G | tr ' ' '\n' | grep -qx "$tool_gid" ||
194
+ die "the daemon (uid $uid) is not in the tool gid $tool_gid: start it with --group-add $tool_gid (re-run provision)"
195
+ export QCR_TOOL_UID="$tool_uid" QCR_TOOL_GID="$tool_gid" QCR_SETPRIV_BIN="$SETID_HELPER"
196
+ say "the model's tools run as uid $tool_uid gid $tool_gid through $SETID_HELPER; the daemon keeps uid $uid"
197
+ return 0
198
+ fi
199
+ if [ "${QCR_ALLOW_SHARED_TOOL_UID-}" = 1 ]; then
200
+ say "WARNING: the model's tools run as the daemon's own uid $uid, which reads the secrets mount (QCR_ALLOW_SHARED_TOOL_UID is 1)"
201
+ return 0
202
+ fi
203
+ die "the model's tools cannot run as another uid: $SETID_HELPER is not runnable by uid $uid or cannot switch to $tool_uid:${tool_gid:-?} here (it switches to the image's tool identity only). Start the bot with --group-add ${QCR_SETID_GID:-4748} (the helper's gate group) and without no-new-privileges, or as root (--user 0:0 --cap-drop ALL --cap-add SETUID --cap-add SETGID -e QCR_RUN_UID -e QCR_RUN_GID); setting QCR_ALLOW_SHARED_TOOL_UID to 1 accepts the shared uid"
204
+ }
205
+
206
+ # What the model's tools write through the sanctioned scripts, as the tool uid:
207
+ # the round's rendered review (render-review.sh, state/), a findings record, the
208
+ # verdicts (commit-verdict.sh), the ledgers a debug round's pi pins, the
209
+ # session commands. Those directories, and only those, are handed to the tool's
210
+ # own gid, setgid so every entry made in them stays in that group (the daemon
211
+ # reads what the tools write, the tools what the daemon leaves there for them).
212
+ # state/ and commands/ are also sticky: the tool uid may add entries but never
213
+ # rename or remove one it does not own (state.db, the IPC run dir, the built
214
+ # agents, status.json, the root-owned commands/operator seal). verdict/ is not:
215
+ # commit-verdict.sh, run as the tool uid, publishes by renaming the file the
216
+ # session's own write tool staged as the daemon's uid. The rest of the tree,
217
+ # secrets/ and pi's login stay out of the tool's group.
218
+ share_tool_dirs() {
219
+ [ -n "${QCR_TOOL_UID:-}" ] || return 0
220
+ local d gid="${QCR_TOOL_GID}"
221
+ for d in "$STATE" "$STATE/findings" "$STATE/ledgers" "$APP/verdict" "$APP/commands"; do
222
+ { mkdir -p "$d" && chgrp "$gid" "$d" && chmod g+rwxs "$d"; } 2>/dev/null ||
223
+ say "WARNING: $d could not be opened to the tool gid $gid: the model's scripts cannot write there"
224
+ done
225
+ for d in "$STATE" "$APP/commands"; do
226
+ chmod +t "$d" 2>/dev/null || say "WARNING: $d could not be made sticky: the tool uid could rename the daemon's entries in it"
227
+ done
228
+ }
229
+
230
+ isolate_tools "$@"
231
+
232
+ # ---- the token handoff ------------------------------------------------------
233
+
234
+ # A GitHub token is never env or argv in this image. The caller bind-mounts a
235
+ # 0700 dir at /run/qcr-in holding a 0600 file and names it in QCR_GH_TOKEN_FILE;
236
+ # packages/pi-plugin/src/ghcred.ts reads and unlinks it as the first thing cli.js does, before any
237
+ # pi or bash child exists, and drops the variable. This script never reads it.
238
+ # What keeps the model's bash off the Node process that then holds the token:
239
+ # - the tools' uid (above) where the split is possible;
240
+ # - Yama kernel.yama.ptrace_scope >= 1, under which a child cannot ptrace-attach
241
+ # to its ancestor (host-wide: 1 on the owner's PC, unknown on Docker Desktop
242
+ # VMs and GitHub runners);
243
+ # - bash-guard's /proc environ/mem/cmdline deny and its program allowlist,
244
+ # where the guard runs.
245
+ # --cap-drop ALL and no-new-privileges are hardening, not that block: same-uid
246
+ # access to /proc/<ppid>/mem needs no CAP_SYS_PTRACE. So the value is recorded
247
+ # at start (QCR_DEBUG=1), for the CI smoke and the macOS checklist to compare.
248
+ debug_ptrace_scope() {
249
+ [ "${QCR_DEBUG:-}" = 1 ] || return 0
250
+ say "debug: kernel.yama.ptrace_scope=$(cat /proc/sys/kernel/yama/ptrace_scope 2>/dev/null || echo absent)"
251
+ }
252
+
253
+ # ---- the pi pin ----------------------------------------------------------------
254
+
255
+ # shellcheck source=../scripts/install-locator.sh
256
+ . "$APP/scripts/install-locator.sh"
257
+
258
+ # A key of the [pi] table of a config file, unquoted; nothing when absent.
259
+ toml_pi() { # toml_pi <file> <key>
260
+ awk -v key="$2" '
261
+ /^\[/ { in_pi = ($0 ~ /^\[pi\][[:space:]]*(#.*)?$/); next }
262
+ in_pi && $0 ~ "^[[:space:]]*" key "[[:space:]]*=" {
263
+ sub(/^[^=]*=[[:space:]]*/, ""); sub(/[[:space:]]*#.*$/, ""); gsub(/"/, ""); print; exit
264
+ }
265
+ ' "$1"
266
+ }
267
+
268
+ # The version of a pi package directory, or nothing.
269
+ pkg_version() { # pkg_version <package dir>
270
+ [ -f "$1/package.json" ] || return 0
271
+ node -p 'require(process.argv[1]).version' "$1/package.json" 2>/dev/null || true
272
+ }
273
+
274
+ # The config the pin is read from: the install locator's (the daemon's own
275
+ # config, and the one every session is handed), else the example the image
276
+ # bakes, whose pin the build checked. A daemon never falls back: a missing
277
+ # config is a mount that was not made, and the boot names it.
278
+ PI_VERSION_PINNED=""
279
+ PI_PACKAGE_PINNED=""
280
+ assert_pi_pin() {
281
+ local cfg ver pkg have example="$APP/config.example.toml"
282
+ cfg="$(qcr_locate_config "$APP")" || exit 1
283
+ if [ ! -f "$cfg" ]; then
284
+ [ "$mode" != daemon ] || die "config not found: $cfg (is the install's config home mounted?)"
285
+ cfg="$example"
286
+ fi
287
+ [ -f "$cfg" ] || die "config not found: $cfg"
288
+ ver="$(toml_pi "$cfg" version)"
289
+ pkg="$(toml_pi "$cfg" package)"
290
+ [ -n "$ver" ] || ver="$(toml_pi "$example" version 2>/dev/null || true)"
291
+ [ -n "$pkg" ] || pkg="$(toml_pi "$example" package 2>/dev/null || true)"
292
+ [ -n "$ver" ] && [ -n "$pkg" ] || die "$cfg has no [pi] package/version and neither has $example"
293
+ [[ "$pkg" =~ ^@?[A-Za-z0-9._-]+(/[A-Za-z0-9._-]+)?$ && "$pkg" != *..* ]] ||
294
+ die "$cfg [pi] package \"$pkg\" is not an npm package name"
295
+ have="$(pkg_version "$APP/node_modules/$pkg")"
296
+ [ -n "$have" ] || die "pi is not installed: no $APP/node_modules/$pkg/package.json"
297
+ [ "$have" = "$ver" ] ||
298
+ die "pi version mismatch: $cfg [pi] version is $ver but $pkg $have is installed — refusing to start (bump config.toml, package.json and the image together)"
299
+ PI_VERSION_PINNED="$ver"
300
+ PI_PACKAGE_PINNED="$pkg"
301
+ }
302
+
303
+ # ---- state ---------------------------------------------------------------------
304
+
305
+ assert_state_writable() {
306
+ { mkdir -p "$STATE" 2>/dev/null && [ -d "$STATE" ] && [ -w "$STATE" ]; } ||
307
+ die "$STATE is not writable by uid $(id -u) — mount a volume there (the image ships it world-writable)"
308
+ }
309
+
310
+ # ---- pi settings ----------------------------------------------------------------
311
+
312
+ # Registers pi's global settings under $HOME/.pi/agent. Idempotent MERGE, safe
313
+ # on every boot: the file carries keys pi itself and the user wrote. Env knobs:
314
+ # QCR_PI_TRUST_DIR a directory pre-seeded into pi's trust store.
315
+ # QCR_PI_AGENTS_TARGET where $HOME/.pi/agent/agents links (the lens tool's
316
+ # agent discovery, <agent dir>/agents).
317
+ # No extension is registered globally: bash-guard rides every lens and
318
+ # worker session as a factory, and the takeover and debug pi load it by path.
319
+ # A global entry would arm every lens leaf with ambient extension work.
320
+ provision_pi_settings() {
321
+ node <<'PI_EXT_MERGE'
322
+ const fs = require("fs");
323
+ const path = require("path");
324
+
325
+ const file = path.join(process.env.HOME, ".pi", "agent", "settings.json");
326
+ fs.mkdirSync(path.dirname(file), { recursive: true });
327
+ let settings = {};
328
+ if (fs.existsSync(file)) settings = JSON.parse(fs.readFileSync(file, "utf8"));
329
+ if (!Array.isArray(settings.extensions)) settings.extensions = [];
330
+
331
+ // bash-guard is no longer a global registration. The pihome volume still
332
+ // carries the entry an older image merged, and a global entry would load the
333
+ // guard a second time beside the factory's, so it is dropped here.
334
+ const retiredGuard = (p) => /(^|[\\/])extensions[\\/](cli[\\/])?bash-guard\.ts$/.test(p);
335
+ const retired = settings.extensions.filter(retiredGuard);
336
+ if (retired.length) {
337
+ settings.extensions = settings.extensions.filter((p) => !retiredGuard(p));
338
+ console.log("pi extensions pruned (bash-guard is no longer global): " + retired.join(", "));
339
+ }
340
+ // settings.json lives on a PERSISTENT pihome volume on the bot, so entries
341
+ // written by an older image survive a rebuild. Prune anything that is not on
342
+ // disk. A `builtin:` override (below) names no file, so it is never "stale".
343
+ const isBuiltinEntry = (p) => /^[-+!]?builtin:/.test(p);
344
+ const stale = settings.extensions.filter((p) => !isBuiltinEntry(p) && !fs.existsSync(p));
345
+ if (stale.length) {
346
+ settings.extensions = settings.extensions.filter((p) => isBuiltinEntry(p) || fs.existsSync(p));
347
+ console.log("pi extensions pruned (not on disk): " + stale.join(", "));
348
+ }
349
+ // Never block on pi's interactive "Trust project folder?" modal. Belt: trust
350
+ // every project by default. Braces: pre-seed the trust store for the app root.
351
+ // Third layer: sessions.ts passes --approve on every spawn.
352
+ settings.defaultProjectTrust = "always";
353
+ // pi 1.0 made the interactive TUI fullscreen by default. Sessions run under
354
+ // tmux and the operator TUI mirrors and scrolls their panes, so keep the
355
+ // terminal's normal scrollback (pi 0.99's default) — packages/pi-plugin/src/pibuiltins.ts PI_TUI_MODE.
356
+ settings.tuiMode = "regular";
357
+ // pi 0.99's built-in extensions (mcp, codemode, tool-search, llama.cpp) are
358
+ // switched OFF, reasons per built-in in packages/pi-plugin/src/pibuiltins.ts, the list this
359
+ // mirrors. Any other global `builtin:` entry is dropped first, so this list is
360
+ // the only word the user settings say about built-ins.
361
+ const DISABLED_BUILTINS = ["-builtin:mcp", "-builtin:codemode", "-builtin:tool-search", "-builtin:llama.cpp"];
362
+ settings.extensions = settings.extensions.filter((p) => !isBuiltinEntry(p)).concat(DISABLED_BUILTINS);
363
+
364
+ function atomicJsonWrite(target, value) {
365
+ const tmp = `${target}.tmp-${process.pid}-${require("node:crypto").randomUUID()}`;
366
+ try {
367
+ const mode = fs.existsSync(target) ? fs.statSync(target).mode & 0o777 : 0o600;
368
+ fs.writeFileSync(tmp, JSON.stringify(value, null, 2) + "\n", { mode });
369
+ fs.renameSync(tmp, target);
370
+ } finally { fs.rmSync(tmp, { force: true }); }
371
+ }
372
+ atomicJsonWrite(file, settings);
373
+ console.log("pi extensions registered: " + (settings.extensions.join(", ")));
374
+
375
+ const trustDir = process.env.QCR_PI_TRUST_DIR || "";
376
+ if (trustDir) {
377
+ const trustFile = path.join(process.env.HOME, ".pi", "agent", "trust.json");
378
+ let trust = {};
379
+ if (fs.existsSync(trustFile)) trust = JSON.parse(fs.readFileSync(trustFile, "utf8"));
380
+ if (trust[trustDir] !== true) {
381
+ trust[trustDir] = true;
382
+ atomicJsonWrite(trustFile, trust);
383
+ }
384
+ console.log("pi project trust: defaultProjectTrust=always, " + trustDir + " pre-trusted");
385
+ }
386
+
387
+ // Agent discovery for the lens tool: its agent dir's `agents` is
388
+ // $HOME/.pi/agent/agents. Symlink-or-absent only: a REAL directory here
389
+ // is someone's own agents and is never clobbered — loud log instead.
390
+ const agentsTarget = process.env.QCR_PI_AGENTS_TARGET || "";
391
+ if (agentsTarget) {
392
+ const agentsLink = path.join(process.env.HOME, ".pi", "agent", "agents");
393
+ try {
394
+ const st = fs.lstatSync(agentsLink, { throwIfNoEntry: false });
395
+ if (st && !st.isSymbolicLink()) {
396
+ console.error("WARNING: " + agentsLink + " exists and is not a symlink — NOT touching it; lens agents will not resolve");
397
+ } else {
398
+ if (st) fs.unlinkSync(agentsLink);
399
+ fs.symlinkSync(agentsTarget, agentsLink);
400
+ console.log("pi user agents dir -> " + agentsTarget);
401
+ }
402
+ } catch (e) {
403
+ console.error("WARNING: could not link " + agentsLink + ": " + e.message);
404
+ }
405
+ }
406
+ PI_EXT_MERGE
407
+ }
408
+
409
+ # ---- modes -------------------------------------------------------------------
410
+
411
+ mode_daemon() {
412
+ # `daemon --preflight`: the updater's check on a scratch copy, run with
413
+ # --network none. It starts nothing (no tmux, no git config, no pi settings):
414
+ # it reads the mounts and prints one JSON report.
415
+ if [ "${1:-}" = "--preflight" ]; then
416
+ exec node "$APP/dist/src/preflight.js"
417
+ fi
418
+ # The key a pi OAuth /login does not provide: exported so the tmux server and
419
+ # every pi process inherit it.
420
+ local secrets="${QCR_SECRETS_MOUNT:-/opt/quickreview/secrets}"
421
+ export QCR_SECRETS_MOUNT="$secrets"
422
+ # The code resolves secrets through the install locator: an empty (or
423
+ # old-default) config.toml [github].secrets_dir means <config home>/secrets -
424
+ # point that at the secrets mount. A SET [github] secrets_dir names a host
425
+ # path this container cannot see: QCR_SECRETS_MOUNT answers that instead, for
426
+ # the daemon, every session it spawns and mint-token.sh alike.
427
+ local xdg="${XDG_CONFIG_HOME:-}" secrets_home
428
+ [[ "$xdg" == /* ]] || xdg="$HOME/.config"
429
+ secrets_home="$xdg/qcr/${QCR_INSTALL:-default}/secrets"
430
+ mkdir -p "$(dirname "$secrets_home")"
431
+ [[ -L "$secrets_home" ]] || ln -sfn "$secrets" "$secrets_home"
432
+ if [[ -r "$secrets/openai_api_key" ]]; then
433
+ OPENAI_API_KEY="$(<"$secrets/openai_api_key")"
434
+ export OPENAI_API_KEY
435
+ fi
436
+
437
+ share_tool_dirs
438
+
439
+ # No global extension registration (see provision_pi_settings).
440
+ QCR_PI_TRUST_DIR="$APP" \
441
+ QCR_PI_AGENTS_TARGET="$STATE/agents" \
442
+ provision_pi_settings >&2
443
+
444
+ # Private-repo git auth (reviewed-repo clone + per-PR fetches): the app
445
+ # installation token over HTTPS - never a personal credential (rule 3).
446
+ git config --global credential.helper \
447
+ "!f() { echo username=x-access-token; echo \"password=\$(\"$APP/scripts/mint-token.sh\")\"; }; f"
448
+
449
+ # Reviewer context: pi loads the FIRST of AGENTS.override.md / AGENTS.md /
450
+ # CLAUDE.md from the cwd into every session and every lens pass, and they all
451
+ # run here - so without the stub the contributor guide would ride every turn.
452
+ # The image bakes it 0444 in $APP (read-only to this uid); a tree that was
453
+ # synced instead gets it installed. Never into a repo checkout: $APP is the
454
+ # image's own tree.
455
+ local stub_src="$APP/deploy/reviewer/AGENTS.override.md" stub="$APP/AGENTS.override.md"
456
+ [ -f "$stub_src" ] || stub_src="$stub"
457
+ if [ -f "$stub_src" ] && ! { cmp -s "$stub_src" "$stub" && [ "$(stat -c %a "$stub")" = 444 ]; }; then
458
+ install -m 0444 "$stub_src" "$stub" ||
459
+ say "WARNING: reviewer context stub not installed - sessions will load the full AGENTS.md"
460
+ elif [ ! -f "$stub_src" ]; then
461
+ say "WARNING: reviewer context stub not found - sessions will load the full AGENTS.md"
462
+ fi
463
+
464
+ # tmux server = the jump-in surface. The csi-u lines must exist before the
465
+ # server starts or modified keys (Shift-Enter etc.) collapse before reaching pi.
466
+ [ -f "$APP/docker/vm/tmux.conf" ] || die "$APP/docker/vm/tmux.conf missing"
467
+ cp "$APP/docker/vm/tmux.conf" "$HOME/.tmux.conf"
468
+ tmux start-server
469
+ tmux has-session -t main 2>/dev/null || tmux new-session -d -s main
470
+
471
+ exec node "$APP/dist/src/wire.js" "$@"
472
+ }
473
+
474
+ # The companion's pi settings on top of the common merge: its skills, its
475
+ # default model, its agent set, the /workspace trust. The agent set is the
476
+ # image's (QCR_COMPANION_AGENTS, default $APP/docker/companion/agents): the
477
+ # companion runs the image's code, not the checkout's.
478
+ provision_companion_settings() {
479
+ QCR_COMPANION_AGENTS="${QCR_COMPANION_AGENTS:-$APP/docker/companion/agents}" node <<'PI_COMPANION_MERGE'
480
+ const fs = require("fs");
481
+ const path = require("path");
482
+ const home = process.env.HOME;
483
+ const file = path.join(home, ".pi", "agent", "settings.json");
484
+ let cfg = {};
485
+ try { cfg = JSON.parse(fs.readFileSync(file, "utf8")); } catch {}
486
+ // Skills: the vendored set and our own, each registered only when really
487
+ // there. An unmounted /workspace leaves the companion under-equipped, never
488
+ // unable to start.
489
+ if (!Array.isArray(cfg.skills)) cfg.skills = [];
490
+ const skillDirs = ["/workspace/.claude/skills", "/workspace/skills/companion"];
491
+ for (const d of skillDirs) {
492
+ if (fs.existsSync(d)) {
493
+ if (!cfg.skills.includes(d)) cfg.skills.push(d);
494
+ } else {
495
+ console.log("!! " + d + " is missing - its skills are not registered.");
496
+ }
497
+ }
498
+ // `/skill:<name>` from pi's own input line.
499
+ cfg.enableSkillCommands = true;
500
+ // The configured model ("provider/model[:thinking]") is pi's default on every start.
501
+ const defMatch = /^([^/:\s]+)\/([^:\s]+)(?::([a-z]+))?$/.exec(process.env.QCR_PI_DEFAULT_MODEL || "");
502
+ if (defMatch) {
503
+ cfg.defaultProvider = defMatch[1];
504
+ cfg.defaultModel = defMatch[2];
505
+ if (defMatch[3]) cfg.defaultThinkingLevel = defMatch[3];
506
+ }
507
+ fs.writeFileSync(file, JSON.stringify(cfg, null, 2) + "\n");
508
+ console.log("pi skills registered: " + (cfg.skills.join(", ") || "none"));
509
+
510
+ const trustFile = path.join(home, ".pi", "agent", "trust.json");
511
+ let trust = {};
512
+ try { trust = JSON.parse(fs.readFileSync(trustFile, "utf8")); } catch {}
513
+ if (trust["/workspace"] !== true) {
514
+ trust["/workspace"] = true;
515
+ fs.writeFileSync(trustFile, JSON.stringify(trust, null, 2) + "\n");
516
+ }
517
+ console.log("pi project trust: /workspace pre-trusted");
518
+
519
+ // Agent discovery for the lens tool (packages/pi-plugin/extensions/lens.ts reads the agents dir
520
+ // under pi's agent dir): link it at the companion agent set in the image.
521
+ // Symlink-or-absent only: a REAL directory here is someone's own agents and is
522
+ // never clobbered.
523
+ const agentsLink = path.join(home, ".pi", "agent", "agents");
524
+ const companionAgents = process.env.QCR_COMPANION_AGENTS;
525
+ try {
526
+ const st = fs.lstatSync(agentsLink, { throwIfNoEntry: false });
527
+ if (st && !st.isSymbolicLink()) {
528
+ console.log("!! " + agentsLink + " exists and is not a symlink - NOT touching it; the companion agent set is not discoverable");
529
+ } else {
530
+ if (st) fs.unlinkSync(agentsLink);
531
+ fs.symlinkSync(companionAgents, agentsLink);
532
+ console.log("pi user agents dir -> " + companionAgents);
533
+ }
534
+ } catch (e) {
535
+ console.log("!! could not link " + agentsLink + ": " + e.message);
536
+ }
537
+ PI_COMPANION_MERGE
538
+ }
539
+
540
+ mode_companion() {
541
+ local pi_home="$HOME/.pi"
542
+ mkdir -p "$pi_home/agent" /workspace /tracker /feed /alerts 2>/dev/null || true
543
+ # Full ssh to the VM (rule 8): the agent socket and the ssh config are
544
+ # mounted read-only; ssh needs a passwd entry for this uid to use them.
545
+ if [ -n "${SSH_AUTH_SOCK:-}" ]; then
546
+ tui_identity
547
+ say "ssh agent mounted at $SSH_AUTH_SOCK (the companion may reach the VM; no key is in this container)"
548
+ fi
549
+
550
+ # Durability guard: pi writes its OAuth token, settings and trust store under
551
+ # $HOME/.pi. If that is NOT the mounted volume, every one of them dies with
552
+ # the next recreate. Loud, never fatal. /proc/mounts, not `mountpoint`.
553
+ if ! awk -v d="$pi_home" '$2 == d { found = 1 } END { exit !found }' /proc/mounts 2>/dev/null; then
554
+ say "!! $pi_home is NOT a mount point - pi's OAuth token and settings will NOT survive a container recreate (HOME=$HOME)"
555
+ else
556
+ say "pi home on the volume: $pi_home (OAuth + conversation are durable)"
557
+ fi
558
+
559
+ if [ -d /reviewed-repo ] && [ -n "$(ls -A /reviewed-repo 2>/dev/null)" ]; then
560
+ say "reviewed repo mounted READ-ONLY at /reviewed-repo"
561
+ else
562
+ say "!! /reviewed-repo is not mounted - no reviewed-repo source to read."
563
+ fi
564
+ if [ -d /evidence ]; then
565
+ say "round evidence mounted READ-ONLY at /evidence ($(ls -1 /evidence 2>/dev/null | wc -l) PR dirs)"
566
+ else
567
+ say "!! /evidence is not mounted - no finished-round transcripts to read."
568
+ fi
569
+ if [ -s /github-read/github-read.env ]; then
570
+ say "read-only GitHub token file at /github-read/github-read.env"
571
+ else
572
+ say "!! no read-only GitHub token yet - GitHub reads unavailable until the TUI mints one."
573
+ fi
574
+
575
+ # The companion registers no global extension (companion-guard and the lens
576
+ # tool ride per-spawn argv); the common merge and the companion's own keys.
577
+ [ -f "$APP/docker/vm/tmux.conf" ] || die "$APP/docker/vm/tmux.conf missing"
578
+ cp "$APP/docker/vm/tmux.conf" "$HOME/.tmux.conf"
579
+ provision_pi_settings >&2
580
+ provision_companion_settings >&2
581
+
582
+ # The companion commits its own work to the mounted repo; git refuses without
583
+ # an identity. `|| true`: an unusable git identity degrades committing, it
584
+ # must never stop the companion from starting.
585
+ git config --global user.name "QCR Companion" || true
586
+ git config --global user.email "companion@quickchat.ai" || true
587
+ git config --global --add safe.directory /workspace || true
588
+
589
+ # Memory health watcher: backgrounded and non-fatal by construction.
590
+ local watcher="$APP/docker/companion/memory-health.mjs"
591
+ [ -f "$watcher" ] || watcher=/usr/local/lib/qcr/memory-health.mjs
592
+ if [ -n "${QCR_MEMORY_ENDPOINT:-}${OPENVIKING_URL:-}${OPENVIKING_BASE_URL:-}" ] && [ -f "$watcher" ]; then
593
+ node "$watcher" &
594
+ else
595
+ say "memory watcher idle: no OpenViking endpoint configured for this container"
596
+ fi
597
+
598
+ # Stay alive, and DIE PROMPTLY when asked: PID 1 has no default signal
599
+ # dispositions, so without a trap `docker stop` waits its full timeout. The
600
+ # trap goes in before anything is started, and `child` is set up front: a
601
+ # TERM landing before `sleep` is forked would otherwise hit an unbound
602
+ # variable under `set -u` and exit 1.
603
+ # `sleep &` + `wait`, because a foreground child would block the trap.
604
+ local child=""
605
+ term() {
606
+ [ -z "$child" ] || kill "$child" 2>/dev/null || true
607
+ exit 0
608
+ }
609
+ trap term TERM INT
610
+
611
+ if [ -n "${QCR_TMUX_SOCKET:-}" ]; then
612
+ # The server listens on a socket in the volume the containerised TUI
613
+ # shares (`tmux -S`), and stays up with no session so the TUI can find it
614
+ # before pi is spawned. A socket left by an earlier run is stale.
615
+ mkdir -p "$(dirname "$QCR_TMUX_SOCKET")" 2>/dev/null || true
616
+ rm -f "$QCR_TMUX_SOCKET"
617
+ tmux -S "$QCR_TMUX_SOCKET" start-server \; set -s exit-empty off
618
+ else
619
+ tmux start-server
620
+ fi
621
+
622
+ sleep infinity &
623
+ child=$!
624
+ # `|| true`: a signal makes `wait` return 128+N, which under `set -e` would
625
+ # end the script before the trap's own `exit 0`.
626
+ wait "$child" || true
627
+ exit 0
628
+ }
629
+
630
+ mode_login() {
631
+ # pi itself with `/login` typed and sent for the user: the one script
632
+ # scanbox.ts `loginInPi` builds (it validates the provider name too), run on
633
+ # the image's one pi, node_modules/.bin/pi (there is no pi on the PATH).
634
+ local script
635
+ script="$(node --input-type=module -e '
636
+ const { loginInPi } = await import(process.argv[1] + "/dist/src/scanbox.js");
637
+ process.stdout.write(loginInPi(process.argv[2] || undefined, process.argv[1] + "/node_modules/.bin/pi")[2]);
638
+ ' "$APP" "${1:-}")" || die "login: could not build the pi login command"
639
+ # The bot's login has ONE refresher (src/loginrefresh/); when this
640
+ # container runs it, it stands down for the login and takes over again after.
641
+ login_handover_begin
642
+ # Not exec: the login is shared with the login group once pi has written it,
643
+ # however the session ended, and the refresher is released after that.
644
+ local rc=0
645
+ sh -c "$script" || rc=$?
646
+ share_login
647
+ login_handover_end
648
+ exit "$rc"
649
+ }
650
+
651
+ # The handover between pi's /login and the bot container's login refresher
652
+ #. The refresher holds an exclusive flock on <agent>/auth.json.lock for
653
+ # its whole life: when that lock is held, a refresher is running, and a login
654
+ # rewriting auth.json beside it would race its refresh. So the login asks it to
655
+ # pause - writes <agent>/auth.json.pause - and waits for `"paused": true` in
656
+ # its status file. A paused refresher neither refreshes nor writes, but KEEPS
657
+ # the lock, so no second refresher can start during the login. login_handover_end
658
+ # removes the pause file and the refresher re-reads the new login and resumes (a
659
+ # pause file left behind is lifted by the refresher after 15 minutes). Where
660
+ # nobody holds the lock (a laptop, the companion) nothing is done.
661
+ LOGIN_PAUSE_FILE=""
662
+ login_agent_dir() { printf '%s\n' "${PI_CODING_AGENT_DIR:-$HOME/.pi/agent}"; }
663
+
664
+ login_handover_begin() {
665
+ local dir lock status rc=0 waited=0 max
666
+ dir="$(login_agent_dir)"
667
+ lock="$dir/auth.json.lock"
668
+ status="$dir/loginrefresh.status.json"
669
+ [ -e "$lock" ] || return 0
670
+ if ! command -v flock >/dev/null 2>&1; then
671
+ say "WARNING: flock is not installed - cannot tell whether a login refresher holds $lock"
672
+ return 0
673
+ fi
674
+ flock -n -E 75 "$lock" true 2>/dev/null || rc=$?
675
+ [ "$rc" -eq 75 ] || return 0
676
+ LOGIN_PAUSE_FILE="$dir/auth.json.pause"
677
+ trap 'rm -f "$LOGIN_PAUSE_FILE"' EXIT
678
+ say "login: the bot's login refresher holds $lock - asking it to pause while you log in"
679
+ (umask 007 && : >"$LOGIN_PAUSE_FILE") || die "login: cannot write $LOGIN_PAUSE_FILE"
680
+ chgrp "$LOGIN_GID" "$LOGIN_PAUSE_FILE" 2>/dev/null || true
681
+ max="${QCR_LOGIN_PAUSE_WAIT_S:-60}"
682
+ # Half-second polls: the refresher looks at the pause file every 2 s.
683
+ while ! grep -q '"paused": true' "$status" 2>/dev/null; do
684
+ if [ "$waited" -ge $((max * 2)) ]; then
685
+ die "login: the refresher did not pause within ${max}s ($status) - is the daemon running?"
686
+ fi
687
+ sleep 0.5
688
+ waited=$((waited + 1))
689
+ done
690
+ say "login: the refresher is paused (it keeps the lock) - /login is yours"
691
+ }
692
+
693
+ login_handover_end() {
694
+ [ -n "$LOGIN_PAUSE_FILE" ] || return 0
695
+ rm -f "$LOGIN_PAUSE_FILE"
696
+ LOGIN_PAUSE_FILE=""
697
+ say "login: released - the refresher re-reads the login and resumes"
698
+ }
699
+
700
+ # Leave pi's agent dir (the login volume) readable by a later run under any
701
+ # uid, and writable by a later login under any uid: the login group, files
702
+ # 0660, directories 2770. Best effort per entry - what another uid wrote in an
703
+ # earlier login was shared by that login already, and this uid may not own it.
704
+ share_login() {
705
+ local dir="$HOME/.pi/agent"
706
+ [ -d "$dir" ] || return 0
707
+ find "$dir" -mindepth 1 ! -group "$LOGIN_GID" -exec chgrp -h "$LOGIN_GID" {} + 2>/dev/null || true
708
+ find "$dir" -mindepth 1 -type d -exec chmod 2770 {} + 2>/dev/null || true
709
+ find "$dir" -mindepth 1 -type f -exec chmod 0660 {} + 2>/dev/null || true
710
+ }
711
+
712
+ # ssh will not run for a uid the image has no passwd entry for, and the tui and
713
+ # companion modes run as the caller's own uid. When the entry is missing,
714
+ # nss_wrapper answers the lookup with one (its HOME is this HOME, where
715
+ # ~/.ssh/config and known_hosts are mounted). Needed by the TUI's ssh runner
716
+ # (src/tui/remote.ts) and by the companion's ssh to the VM (rule 8); a missing
717
+ # library is said, never fatal.
718
+ tui_identity() {
719
+ local entry lib dir="$HOME/.qcr-nss"
720
+ # ssh reads ~/.ssh from the passwd entry's home, never from $HOME. An entry
721
+ # whose home IS this HOME needs nothing; a missing one, or the base image's
722
+ # own user at this uid (uid 1000 is node, home /home/node), is answered with
723
+ # one whose home is this HOME.
724
+ entry="$(getent passwd "$(id -u)" 2>/dev/null || true)"
725
+ [ -n "$entry" ] && [ "$(printf '%s' "$entry" | cut -d: -f6)" = "$HOME" ] && return 0
726
+ lib="${QCR_NSS_WRAPPER_LIB:-$(find /usr/lib /lib -name 'libnss_wrapper.so*' 2>/dev/null | head -n 1)}"
727
+ if [ ! -f "$lib" ] || ! mkdir -p "$dir" 2>/dev/null; then
728
+ say "WARNING: uid $(id -u) has no passwd entry at $HOME and nss_wrapper is not usable - ssh will not read the mounted ssh config"
729
+ return 0
730
+ fi
731
+ { awk -F: -v u="$(id -u)" '$3 != u' /etc/passwd; printf 'qcr:x:%s:%s:qcr:%s:/bin/sh\n' "$(id -u)" "$(id -g)" "$HOME"; } >"$dir/passwd"
732
+ { cat /etc/group; printf 'qcr:x:%s:\n' "$(id -g)"; } >"$dir/group"
733
+ export LD_PRELOAD="$lib" NSS_WRAPPER_PASSWD="$dir/passwd" NSS_WRAPPER_GROUP="$dir/group"
734
+ }
735
+
736
+ # ---- dispatch -----------------------------------------------------------------
737
+
738
+ assert_pi_pin
739
+
740
+ case "$mode" in
741
+ install)
742
+ # Stdout is the wrapper's (or the installer `| sh` runs) and nothing else.
743
+ exec "$APP/scripts/install-wrapper.sh"
744
+ ;;
745
+ worker)
746
+ say "worker: the per-round bot worker is not shipped in this image yet"
747
+ exit 64
748
+ ;;
749
+ esac
750
+
751
+ case "$mode" in
752
+ mint)
753
+ # An installation token on stdout and nothing else; touches no state.
754
+ exec "$APP/scripts/mint-token.sh" "$@"
755
+ ;;
756
+ esac
757
+
758
+ assert_state_writable
759
+ debug_ptrace_scope
760
+
761
+ case "$mode" in
762
+ cli)
763
+ QCR_PI_TRUST_DIR="$APP" provision_pi_settings >&2
764
+ # pi's home is read by the tool uid (settings, trust, auth), written by pi.
765
+ [ -z "${QCR_TOOLS_ISOLATED:-}" ] || chmod -R g+rwX "$HOME/.pi" 2>/dev/null || true
766
+ exec node "$APP/dist/src/cli.js" "$@"
767
+ ;;
768
+ tui)
769
+ tui_identity
770
+ exec node "$APP/dist/src/cli.js" tui "$@"
771
+ ;;
772
+ login)
773
+ QCR_PI_TRUST_DIR="$APP" provision_pi_settings >&2
774
+ mode_login "$@"
775
+ ;;
776
+ daemon)
777
+ mode_daemon "$@"
778
+ ;;
779
+ companion)
780
+ mode_companion
781
+ ;;
782
+ esac