@quickchatai/quickreview 1.1.0 → 1.3.1

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 (471) hide show
  1. package/README.md +137 -57
  2. package/bin/qcr.js +1 -1
  3. package/config.example.toml +60 -14
  4. package/deploy/ansible/README.md +20 -12
  5. package/deploy/ansible/inventory.example.ini +1 -1
  6. package/deploy/collect-secrets.sh +1 -1
  7. package/deploy/qcr-update.sh +1 -1
  8. package/dist/extensions/cli/home.js +14 -0
  9. package/dist/extensions/cli/home.js.map +1 -0
  10. package/dist/extensions/cli/login-route.js +5 -0
  11. package/dist/extensions/cli/login-route.js.map +1 -0
  12. package/dist/extensions/cli/selfimprove.js +18 -0
  13. package/dist/extensions/cli/selfimprove.js.map +1 -0
  14. package/dist/extensions/home.js +350 -0
  15. package/dist/extensions/home.js.map +1 -0
  16. package/dist/extensions/login-route.js +180 -0
  17. package/dist/extensions/login-route.js.map +1 -0
  18. package/dist/extensions/onboarding.js +35 -11
  19. package/dist/extensions/onboarding.js.map +1 -1
  20. package/dist/extensions/selfimprove.js +49 -0
  21. package/dist/extensions/selfimprove.js.map +1 -0
  22. package/dist/extensions/setup-scan.js +23 -592
  23. package/dist/extensions/setup-scan.js.map +1 -1
  24. package/dist/extensions/setup.js +2 -47
  25. package/dist/extensions/setup.js.map +1 -1
  26. package/dist/src/archive/restore.js +18 -15
  27. package/dist/src/archive/restore.js.map +1 -1
  28. package/dist/src/botworker.js +13 -2
  29. package/dist/src/botworker.js.map +1 -1
  30. package/dist/src/channelfs.js +3 -26
  31. package/dist/src/channelfs.js.map +1 -1
  32. package/dist/src/ciretry.js +2 -1
  33. package/dist/src/ciretry.js.map +1 -1
  34. package/dist/src/cli.js +54 -61
  35. package/dist/src/cli.js.map +1 -1
  36. package/dist/src/cliops.js +3 -2
  37. package/dist/src/cliops.js.map +1 -1
  38. package/dist/src/commands.js +25 -2
  39. package/dist/src/commands.js.map +1 -1
  40. package/dist/src/config.js +32 -2
  41. package/dist/src/config.js.map +1 -1
  42. package/dist/src/daemon.js +50 -8
  43. package/dist/src/daemon.js.map +1 -1
  44. package/dist/src/debuground.js +1 -0
  45. package/dist/src/debuground.js.map +1 -1
  46. package/dist/src/debugroundpi.js +6 -1
  47. package/dist/src/debugroundpi.js.map +1 -1
  48. package/dist/src/dispatch.js +5 -4
  49. package/dist/src/dispatch.js.map +1 -1
  50. package/dist/src/engine/caserunner-sdk.js +15 -251
  51. package/dist/src/engine/caserunner-sdk.js.map +1 -1
  52. package/dist/src/engine/debugpi.js +17 -5
  53. package/dist/src/engine/debugpi.js.map +1 -1
  54. package/dist/src/execboundary.js +10 -3
  55. package/dist/src/execboundary.js.map +1 -1
  56. package/dist/src/github.js +51 -16
  57. package/dist/src/github.js.map +1 -1
  58. package/dist/src/githubtoken.js +346 -0
  59. package/dist/src/githubtoken.js.map +1 -0
  60. package/dist/src/home/adapters.js +349 -0
  61. package/dist/src/home/adapters.js.map +1 -0
  62. package/dist/src/home/advanced.js +318 -0
  63. package/dist/src/home/advanced.js.map +1 -0
  64. package/dist/src/home/advancedtools.js +57 -0
  65. package/dist/src/home/advancedtools.js.map +1 -0
  66. package/dist/src/home/autoreview.js +325 -0
  67. package/dist/src/home/autoreview.js.map +1 -0
  68. package/dist/src/home/daemonstatus.js +32 -0
  69. package/dist/src/home/daemonstatus.js.map +1 -0
  70. package/dist/src/home/devicelogin.js +61 -0
  71. package/dist/src/home/devicelogin.js.map +1 -0
  72. package/dist/src/home/launch.js +202 -0
  73. package/dist/src/home/launch.js.map +1 -0
  74. package/dist/src/home/loginowner.js +205 -0
  75. package/dist/src/home/loginowner.js.map +1 -0
  76. package/dist/src/home/memory.js +122 -0
  77. package/dist/src/home/memory.js.map +1 -0
  78. package/dist/src/home/model.js +811 -0
  79. package/dist/src/home/model.js.map +1 -0
  80. package/dist/src/home/panel.js +520 -0
  81. package/dist/src/home/panel.js.map +1 -0
  82. package/dist/src/home/ports.js +19 -0
  83. package/dist/src/home/ports.js.map +1 -0
  84. package/dist/src/home/review.js +163 -0
  85. package/dist/src/home/review.js.map +1 -0
  86. package/dist/src/home/reviews.js +478 -0
  87. package/dist/src/home/reviews.js.map +1 -0
  88. package/dist/src/home/setup.js +507 -0
  89. package/dist/src/home/setup.js.map +1 -0
  90. package/dist/src/home/setupadapters.js +214 -0
  91. package/dist/src/home/setupadapters.js.map +1 -0
  92. package/dist/src/home/setupcard.js +199 -0
  93. package/dist/src/home/setupcard.js.map +1 -0
  94. package/dist/src/home/setuptools.js +45 -0
  95. package/dist/src/home/setuptools.js.map +1 -0
  96. package/dist/src/home/spend.js +160 -0
  97. package/dist/src/home/spend.js.map +1 -0
  98. package/dist/src/home/switches.js +209 -0
  99. package/dist/src/home/switches.js.map +1 -0
  100. package/dist/src/home/switchon.js +439 -0
  101. package/dist/src/home/switchon.js.map +1 -0
  102. package/dist/src/home/toolnames.js +41 -0
  103. package/dist/src/home/toolnames.js.map +1 -0
  104. package/dist/src/home/tune.js +341 -0
  105. package/dist/src/home/tune.js.map +1 -0
  106. package/dist/src/home/words.js +7 -0
  107. package/dist/src/home/words.js.map +1 -0
  108. package/dist/src/homes.js +14 -0
  109. package/dist/src/homes.js.map +1 -1
  110. package/dist/src/install.js +1 -1
  111. package/dist/src/install.js.map +1 -1
  112. package/dist/src/ipc/workerspec.js +8 -0
  113. package/dist/src/ipc/workerspec.js.map +1 -1
  114. package/dist/src/live/publish.js +1 -1
  115. package/dist/src/live/publish.js.map +1 -1
  116. package/dist/src/livecli.js +1 -1
  117. package/dist/src/livecli.js.map +1 -1
  118. package/dist/src/loginhint.js +8 -3
  119. package/dist/src/loginhint.js.map +1 -1
  120. package/dist/src/loginrefresh/handover.js +121 -0
  121. package/dist/src/loginrefresh/handover.js.map +1 -0
  122. package/dist/src/loginrefresh/lock.js +54 -3
  123. package/dist/src/loginrefresh/lock.js.map +1 -1
  124. package/dist/src/loginrefresh/pirefresh.js +3 -0
  125. package/dist/src/loginrefresh/pirefresh.js.map +1 -1
  126. package/dist/src/loginrefresh/refresher.js +33 -5
  127. package/dist/src/loginrefresh/refresher.js.map +1 -1
  128. package/dist/src/loginrefresh/supervisor.js +18 -1
  129. package/dist/src/loginrefresh/supervisor.js.map +1 -1
  130. package/dist/src/npmverbs.js +46 -14
  131. package/dist/src/npmverbs.js.map +1 -1
  132. package/dist/src/onboard/choices.js +35 -4
  133. package/dist/src/onboard/choices.js.map +1 -1
  134. package/dist/src/onboard/engine.js +32 -306
  135. package/dist/src/onboard/engine.js.map +1 -1
  136. package/dist/src/onboard/pipin.js +22 -0
  137. package/dist/src/onboard/pipin.js.map +1 -0
  138. package/dist/src/onboard/stepforward.js +41 -0
  139. package/dist/src/onboard/stepforward.js.map +1 -0
  140. package/dist/src/onboard/steps/appslug.js +4 -1
  141. package/dist/src/onboard/steps/appslug.js.map +1 -1
  142. package/dist/src/onboard/steps/bringup.js +3 -2
  143. package/dist/src/onboard/steps/bringup.js.map +1 -1
  144. package/dist/src/onboard/steps/compose.js +29 -0
  145. package/dist/src/onboard/steps/compose.js.map +1 -1
  146. package/dist/src/onboard/steps/configfill.js +120 -39
  147. package/dist/src/onboard/steps/configfill.js.map +1 -1
  148. package/dist/src/onboard/steps/githubaccount.js +595 -0
  149. package/dist/src/onboard/steps/githubaccount.js.map +1 -0
  150. package/dist/src/onboard/steps/githubapp.js +65 -7
  151. package/dist/src/onboard/steps/githubapp.js.map +1 -1
  152. package/dist/src/onboard/steps/golive.js +2 -0
  153. package/dist/src/onboard/steps/golive.js.map +1 -1
  154. package/dist/src/onboard/steps/index.js +11 -0
  155. package/dist/src/onboard/steps/index.js.map +1 -1
  156. package/dist/src/onboard/steps/ingress.js +80 -25
  157. package/dist/src/onboard/steps/ingress.js.map +1 -1
  158. package/dist/src/onboard/steps/llmauth.js +103 -30
  159. package/dist/src/onboard/steps/llmauth.js.map +1 -1
  160. package/dist/src/onboard/steps/loginshare.js +213 -0
  161. package/dist/src/onboard/steps/loginshare.js.map +1 -0
  162. package/dist/src/onboard/steps/memory.js +67 -3
  163. package/dist/src/onboard/steps/memory.js.map +1 -1
  164. package/dist/src/onboard/steps/proof.js +366 -56
  165. package/dist/src/onboard/steps/proof.js.map +1 -1
  166. package/dist/src/onboard/steps/repoconfig.js +72 -0
  167. package/dist/src/onboard/steps/repoconfig.js.map +1 -0
  168. package/dist/src/onboard/steps/topology.js +6 -6
  169. package/dist/src/onboard/steps/topology.js.map +1 -1
  170. package/dist/src/onboard/steps/transport.js +9 -1
  171. package/dist/src/onboard/steps/transport.js.map +1 -1
  172. package/dist/src/onboard/steps/tuiroute.js +102 -0
  173. package/dist/src/onboard/steps/tuiroute.js.map +1 -0
  174. package/dist/src/onboard/steps/verifyup.js +17 -1
  175. package/dist/src/onboard/steps/verifyup.js.map +1 -1
  176. package/dist/src/onboard/toolnames.js +30 -0
  177. package/dist/src/onboard/toolnames.js.map +1 -0
  178. package/dist/src/operatorwrite.js +23 -0
  179. package/dist/src/operatorwrite.js.map +1 -0
  180. package/dist/src/outcomes.js +4 -1
  181. package/dist/src/outcomes.js.map +1 -1
  182. package/dist/src/piagentdir.js +13 -0
  183. package/dist/src/piagentdir.js.map +1 -0
  184. package/dist/src/pilogin.js +31 -16
  185. package/dist/src/pilogin.js.map +1 -1
  186. package/dist/src/posting-journal.js +2 -1
  187. package/dist/src/posting-journal.js.map +1 -1
  188. package/dist/src/posting-outbox.js +6 -2
  189. package/dist/src/posting-outbox.js.map +1 -1
  190. package/dist/src/posting-receipt.js +14 -1
  191. package/dist/src/posting-receipt.js.map +1 -1
  192. package/dist/src/qcrbin.js +16 -11
  193. package/dist/src/qcrbin.js.map +1 -1
  194. package/dist/src/recheck.js +2 -1
  195. package/dist/src/recheck.js.map +1 -1
  196. package/dist/src/reconcile.js +22 -2
  197. package/dist/src/reconcile.js.map +1 -1
  198. package/dist/src/reviewargs.js +122 -0
  199. package/dist/src/reviewargs.js.map +1 -0
  200. package/dist/src/reviewcli.js +7 -161
  201. package/dist/src/reviewcli.js.map +1 -1
  202. package/dist/src/reviewdetach.js +76 -11
  203. package/dist/src/reviewdetach.js.map +1 -1
  204. package/dist/src/reviewhistory.js +32 -6
  205. package/dist/src/reviewhistory.js.map +1 -1
  206. package/dist/src/reviewnow.js +45 -0
  207. package/dist/src/reviewnow.js.map +1 -0
  208. package/dist/src/scancli.js +39 -691
  209. package/dist/src/scancli.js.map +1 -1
  210. package/dist/src/selfimprove.js +66 -0
  211. package/dist/src/selfimprove.js.map +1 -0
  212. package/dist/src/setup/adapters.js +5 -223
  213. package/dist/src/setup/adapters.js.map +1 -1
  214. package/dist/src/setup/caserunner.js +15 -249
  215. package/dist/src/setup/caserunner.js.map +1 -1
  216. package/dist/src/setup/engine.js +32 -341
  217. package/dist/src/setup/engine.js.map +1 -1
  218. package/dist/src/setup/facts.js +3 -592
  219. package/dist/src/setup/facts.js.map +1 -1
  220. package/dist/src/setup/findings.js +3 -947
  221. package/dist/src/setup/findings.js.map +1 -1
  222. package/dist/src/setup/presentation.js +3 -8
  223. package/dist/src/setup/presentation.js.map +1 -1
  224. package/dist/src/setup/scan.js +3 -724
  225. package/dist/src/setup/scan.js.map +1 -1
  226. package/dist/src/setup/scanbuild.js +9 -92
  227. package/dist/src/setup/scanbuild.js.map +1 -1
  228. package/dist/src/setup/scanlease.js +3 -250
  229. package/dist/src/setup/scanlease.js.map +1 -1
  230. package/dist/src/setup/scanreport.js +3 -288
  231. package/dist/src/setup/scanreport.js.map +1 -1
  232. package/dist/src/setup/scanrun.js +3 -1732
  233. package/dist/src/setup/scanrun.js.map +1 -1
  234. package/dist/src/setup/scantree.js +3 -256
  235. package/dist/src/setup/scantree.js.map +1 -1
  236. package/dist/src/setup/stage2request.js +3 -258
  237. package/dist/src/setup/stage2request.js.map +1 -1
  238. package/dist/src/setup/unitcut.js +3 -436
  239. package/dist/src/setup/unitcut.js.map +1 -1
  240. package/dist/src/state.js +2 -0
  241. package/dist/src/state.js.map +1 -1
  242. package/dist/src/statemachine.js +4 -1
  243. package/dist/src/statemachine.js.map +1 -1
  244. package/dist/src/takeover.js +1 -0
  245. package/dist/src/takeover.js.map +1 -1
  246. package/dist/src/takeoverpi.js +15 -1
  247. package/dist/src/takeoverpi.js.map +1 -1
  248. package/dist/src/tui/app.js +49 -0
  249. package/dist/src/tui/app.js.map +1 -1
  250. package/dist/src/tui/board.js +88 -12
  251. package/dist/src/tui/board.js.map +1 -1
  252. package/dist/src/tui/cmdbar.js +4 -1
  253. package/dist/src/tui/cmdbar.js.map +1 -1
  254. package/dist/src/tui/companion.js +76 -11
  255. package/dist/src/tui/companion.js.map +1 -1
  256. package/dist/src/tui/connect.js +7 -1
  257. package/dist/src/tui/connect.js.map +1 -1
  258. package/dist/src/tui/deploytab.js +2 -2
  259. package/dist/src/tui/deploytab.js.map +1 -1
  260. package/dist/src/tui/filters.js +5 -2
  261. package/dist/src/tui/filters.js.map +1 -1
  262. package/dist/src/tui/ghread.js +61 -5
  263. package/dist/src/tui/ghread.js.map +1 -1
  264. package/dist/src/tui/index.js +109 -20
  265. package/dist/src/tui/index.js.map +1 -1
  266. package/dist/src/tui/memforward.js +39 -2
  267. package/dist/src/tui/memforward.js.map +1 -1
  268. package/dist/src/tui/memory.js +3 -16
  269. package/dist/src/tui/memory.js.map +1 -1
  270. package/dist/src/tui/memoryurl.js +22 -0
  271. package/dist/src/tui/memoryurl.js.map +1 -0
  272. package/dist/src/tui/model.js +25 -0
  273. package/dist/src/tui/model.js.map +1 -1
  274. package/dist/src/tui/prpause.js +7 -0
  275. package/dist/src/tui/prpause.js.map +1 -1
  276. package/dist/src/tui/remote.js +7 -1
  277. package/dist/src/tui/remote.js.map +1 -1
  278. package/dist/src/tui/route.js +143 -0
  279. package/dist/src/tui/route.js.map +1 -0
  280. package/dist/src/tui/setupstate.js +32 -0
  281. package/dist/src/tui/setupstate.js.map +1 -0
  282. package/dist/src/tui/sshtriage.js +102 -5
  283. package/dist/src/tui/sshtriage.js.map +1 -1
  284. package/dist/src/tui/theme.js +2 -1
  285. package/dist/src/tui/theme.js.map +1 -1
  286. package/dist/src/tui/unwedge.js +2 -12
  287. package/dist/src/tui/unwedge.js.map +1 -1
  288. package/dist/src/verdicts.js +17 -5
  289. package/dist/src/verdicts.js.map +1 -1
  290. package/dist/src/version.js +1 -1
  291. package/dist/src/version.js.map +1 -1
  292. package/dist/src/webhook.js +12 -1
  293. package/dist/src/webhook.js.map +1 -1
  294. package/dist/src/wire.js +34 -8
  295. package/dist/src/wire.js.map +1 -1
  296. package/dist/src/workerworld.js +11 -1
  297. package/dist/src/workerworld.js.map +1 -1
  298. package/docker/README.md +1 -1
  299. package/docker/companion/entrypoint.sh +20 -1
  300. package/docker/entrypoint.sh +57 -6
  301. package/docker-compose.yml +16 -1
  302. package/extensions/cli/home.ts +14 -0
  303. package/extensions/cli/login-route.ts +10 -0
  304. package/extensions/cli/selfimprove.ts +18 -0
  305. package/extensions/home.ts +484 -0
  306. package/extensions/login-route.ts +220 -0
  307. package/extensions/onboarding.ts +41 -11
  308. package/extensions/selfimprove.ts +65 -0
  309. package/extensions/setup-scan.ts +79 -766
  310. package/extensions/setup.ts +14 -70
  311. package/package.json +6 -4
  312. package/prompts/onboarding.md +58 -18
  313. package/schemas/review-result.v1.json +60 -0
  314. package/scripts/deploy.sh +8 -6
  315. package/scripts/mint-token.sh +25 -4
  316. package/scripts/qcr-host.sh +28 -5
  317. package/scripts/vm-ghcr-login.sh +7 -4
  318. package/src/archive/restore.ts +18 -21
  319. package/src/botworker.ts +13 -2
  320. package/src/channelfs.ts +3 -26
  321. package/src/ciretry.ts +2 -1
  322. package/src/cli.ts +59 -67
  323. package/src/cliops.ts +3 -2
  324. package/src/commands.ts +28 -2
  325. package/src/config.ts +62 -4
  326. package/src/daemon.ts +58 -7
  327. package/src/debuground.ts +3 -0
  328. package/src/debugroundpi.ts +12 -1
  329. package/src/dispatch.ts +5 -4
  330. package/src/engine/caserunner-sdk.ts +29 -314
  331. package/src/engine/debugpi.ts +17 -5
  332. package/src/execboundary.ts +16 -4
  333. package/src/github.ts +57 -15
  334. package/src/githubtoken.ts +435 -0
  335. package/src/home/adapters.ts +418 -0
  336. package/src/home/advanced.ts +421 -0
  337. package/src/home/advancedtools.ts +96 -0
  338. package/src/home/autoreview.ts +385 -0
  339. package/src/home/daemonstatus.ts +55 -0
  340. package/src/home/devicelogin.ts +107 -0
  341. package/src/home/launch.ts +257 -0
  342. package/src/home/loginowner.ts +248 -0
  343. package/src/home/memory.ts +176 -0
  344. package/src/home/model.ts +965 -0
  345. package/src/home/panel.ts +666 -0
  346. package/src/home/ports.ts +338 -0
  347. package/src/home/review.ts +206 -0
  348. package/src/home/reviews.ts +565 -0
  349. package/src/home/setup.ts +689 -0
  350. package/src/home/setupadapters.ts +217 -0
  351. package/src/home/setupcard.ts +288 -0
  352. package/src/home/setuptools.ts +57 -0
  353. package/src/home/spend.ts +194 -0
  354. package/src/home/switches.ts +293 -0
  355. package/src/home/switchon.ts +554 -0
  356. package/src/home/toolnames.ts +46 -0
  357. package/src/home/tune.ts +405 -0
  358. package/src/home/words.ts +8 -0
  359. package/src/homes.ts +17 -0
  360. package/src/install.ts +1 -1
  361. package/src/ipc/workerspec.ts +15 -0
  362. package/src/live/publish.ts +4 -1
  363. package/src/livecli.ts +6 -1
  364. package/src/loginhint.ts +8 -3
  365. package/src/loginrefresh/handover.ts +138 -0
  366. package/src/loginrefresh/lock.ts +72 -3
  367. package/src/loginrefresh/pirefresh.ts +3 -0
  368. package/src/loginrefresh/refresher.ts +34 -5
  369. package/src/loginrefresh/supervisor.ts +25 -2
  370. package/src/npmverbs.ts +55 -13
  371. package/src/onboard/choices.ts +40 -4
  372. package/src/onboard/engine.ts +70 -421
  373. package/src/onboard/pipin.ts +31 -0
  374. package/src/onboard/stepforward.ts +61 -0
  375. package/src/onboard/steps/appslug.ts +4 -1
  376. package/src/onboard/steps/bringup.ts +3 -2
  377. package/src/onboard/steps/compose.ts +31 -0
  378. package/src/onboard/steps/configfill.ts +144 -40
  379. package/src/onboard/steps/githubaccount.ts +716 -0
  380. package/src/onboard/steps/githubapp.ts +92 -8
  381. package/src/onboard/steps/golive.ts +2 -0
  382. package/src/onboard/steps/index.ts +11 -0
  383. package/src/onboard/steps/ingress.ts +98 -31
  384. package/src/onboard/steps/llmauth.ts +114 -29
  385. package/src/onboard/steps/loginshare.ts +258 -0
  386. package/src/onboard/steps/memory.ts +76 -3
  387. package/src/onboard/steps/proof.ts +473 -55
  388. package/src/onboard/steps/repoconfig.ts +85 -0
  389. package/src/onboard/steps/topology.ts +7 -6
  390. package/src/onboard/steps/transport.ts +15 -0
  391. package/src/onboard/steps/tuiroute.ts +119 -0
  392. package/src/onboard/steps/verifyup.ts +20 -1
  393. package/src/onboard/toolnames.ts +34 -0
  394. package/src/operatorwrite.ts +25 -0
  395. package/src/outcomes.ts +8 -1
  396. package/src/piagentdir.ts +12 -0
  397. package/src/pilogin.ts +32 -16
  398. package/src/posting-journal.ts +6 -1
  399. package/src/posting-outbox.ts +10 -2
  400. package/src/posting-receipt.ts +17 -0
  401. package/src/qcrbin.ts +16 -11
  402. package/src/recheck.ts +2 -1
  403. package/src/reconcile.ts +29 -3
  404. package/src/reviewargs.ts +119 -0
  405. package/src/reviewcli.ts +6 -167
  406. package/src/reviewdetach.ts +107 -13
  407. package/src/reviewhistory.ts +20 -6
  408. package/src/reviewnow.ts +76 -0
  409. package/src/scancli.ts +75 -826
  410. package/src/selfimprove.ts +90 -0
  411. package/src/setup/adapters.ts +13 -221
  412. package/src/setup/caserunner.ts +34 -273
  413. package/src/setup/engine.ts +62 -496
  414. package/src/setup/facts.ts +3 -627
  415. package/src/setup/findings.ts +3 -1264
  416. package/src/setup/presentation.ts +3 -18
  417. package/src/setup/scan.ts +3 -1033
  418. package/src/setup/scanbuild.ts +20 -114
  419. package/src/setup/scanlease.ts +3 -297
  420. package/src/setup/scanreport.ts +3 -373
  421. package/src/setup/scanrun.ts +3 -2268
  422. package/src/setup/scantree.ts +3 -259
  423. package/src/setup/stage2request.ts +3 -347
  424. package/src/setup/unitcut.ts +3 -523
  425. package/src/state.ts +43 -0
  426. package/src/statemachine.ts +4 -1
  427. package/src/takeover.ts +5 -0
  428. package/src/takeoverpi.ts +16 -2
  429. package/src/tui/app.ts +47 -0
  430. package/src/tui/board.ts +111 -14
  431. package/src/tui/cmdbar.ts +4 -1
  432. package/src/tui/companion.ts +80 -11
  433. package/src/tui/connect.ts +7 -1
  434. package/src/tui/deploytab.ts +2 -2
  435. package/src/tui/filters.ts +7 -3
  436. package/src/tui/ghread.ts +74 -7
  437. package/src/tui/index.ts +117 -23
  438. package/src/tui/memforward.ts +52 -3
  439. package/src/tui/memory.ts +3 -15
  440. package/src/tui/memoryurl.ts +22 -0
  441. package/src/tui/model.ts +36 -2
  442. package/src/tui/prpause.ts +11 -2
  443. package/src/tui/remote.ts +9 -1
  444. package/src/tui/route.ts +173 -0
  445. package/src/tui/setupstate.ts +56 -0
  446. package/src/tui/sshtriage.ts +127 -6
  447. package/src/tui/theme.ts +2 -1
  448. package/src/tui/unwedge.ts +2 -14
  449. package/src/verdicts.ts +23 -5
  450. package/src/version.ts +1 -1
  451. package/src/webhook.ts +10 -1
  452. package/src/wire.ts +42 -9
  453. package/src/workerworld.ts +16 -2
  454. package/dist/src/live/projection.js +0 -450
  455. package/dist/src/live/projection.js.map +0 -1
  456. package/dist/src/live/read.js +0 -60
  457. package/dist/src/live/read.js.map +0 -1
  458. package/dist/src/onboard/launch.js +0 -83
  459. package/dist/src/onboard/launch.js.map +0 -1
  460. package/dist/src/setup/ledger.js +0 -207
  461. package/dist/src/setup/ledger.js.map +0 -1
  462. package/dist/src/setup/stage2.js +0 -617
  463. package/dist/src/setup/stage2.js.map +0 -1
  464. package/dist/src/setup/textsniff.js +0 -89
  465. package/dist/src/setup/textsniff.js.map +0 -1
  466. package/src/live/projection.ts +0 -491
  467. package/src/live/read.ts +0 -86
  468. package/src/onboard/launch.ts +0 -115
  469. package/src/setup/ledger.ts +0 -324
  470. package/src/setup/stage2.ts +0 -926
  471. package/src/setup/textsniff.ts +0 -95
package/src/qcrbin.ts CHANGED
@@ -3,11 +3,12 @@
3
3
  // verbs a person runs from an npm install are routed here first and load only
4
4
  // what they use, so they work where that native driver cannot load:
5
5
  //
6
- // qcr the admin TUI (`qcr tui`)
6
+ // qcr the home: the app's own pi (src/home/launch.ts)
7
+ // qcr tui the admin TUI (src/cli.ts)
7
8
  // qcr version the install's identity (src/version.ts)
8
9
  // qcr review … a daemonless review (src/reviewcli.ts)
9
10
  // qcr login [p] pi's own /login in the pinned pi (src/npmverbs.ts)
10
- // qcr pi [args] the pinned pi with the qcr plugin preloaded
11
+ // qcr pi [args] the pinned pi with the qcr plugin and /selfimprove
11
12
  // qcr update the installing package manager updates qcr
12
13
  //
13
14
  // Every other verb goes to src/cli.ts `main` unchanged. The image's
@@ -22,10 +23,11 @@ import { MissingConfigError } from "./missingconfig.js";
22
23
  export const BIN_HELP = [
23
24
  "qcr — QuickReview",
24
25
  "",
25
- " qcr open the admin TUI",
26
+ " qcr open the home: pi with the plugin and your pull requests",
27
+ " qcr tui open the admin TUI",
26
28
  " qcr review [target] review code here, with no daemon (`qcr review --help`)",
27
29
  " qcr login [provider] log in with pi's own /login, for the review sessions",
28
- " qcr pi [args] pi with the qcr plugin (/review, /scan, /selfimprove, /qcr-setup)",
30
+ " qcr pi [args] pi with the qcr plugin (/qcr-review, /qcr-scan, /qcr-setup) and /selfimprove",
29
31
  " qcr update update qcr with the package manager that installed it",
30
32
  " qcr version [--json] this install's version, schemas and pi pin",
31
33
  "",
@@ -33,19 +35,19 @@ export const BIN_HELP = [
33
35
  ].join("\n");
34
36
 
35
37
  /** The verbs that never print the update notice: the ones that hand the
36
- * terminal over (the TUI, pi) or are about versions themselves. */
37
- const QUIET_VERBS = new Set(["tui", "pi", "update", "version", "login"]);
38
+ * terminal over (the home, the TUI, pi) or are about versions themselves. */
39
+ const QUIET_VERBS = new Set(["home", "tui", "pi", "update", "version", "login"]);
38
40
 
39
41
  /** What `runBin` would do with `argv`, before doing it. */
40
42
  export type BinRoute =
41
- | { route: "tui" }
43
+ | { route: "home" }
42
44
  | { route: "help" }
43
45
  | { route: "pi"; args: string[] }
44
46
  | { route: "version" | "update" | "login" | "review"; args: string[]; json: boolean }
45
47
  | { route: "app"; argv: string[] };
46
48
 
47
49
  export function binRoute(argv: readonly string[]): BinRoute {
48
- if (argv.length === 0) return { route: "tui" };
50
+ if (argv.length === 0 || (argv.length === 1 && argv[0] === "home")) return { route: "home" };
49
51
  // pi's arguments are pi's, `--json` included
50
52
  if (argv[0] === "pi") return { route: "pi", args: argv.slice(1) };
51
53
  // `qcr message` carries free text: src/cli.ts reads its argv as it is
@@ -115,8 +117,11 @@ async function maybeNotice(json: boolean): Promise<void> {
115
117
 
116
118
  async function route(r: BinRoute): Promise<void> {
117
119
  switch (r.route) {
118
- case "tui":
119
- return appMain(["tui"]);
120
+ case "home": {
121
+ const { homeRunDeps, runHome } = await import("./home/launch.js");
122
+ process.exitCode = runHome(homeRunDeps(await packageRoot()));
123
+ return;
124
+ }
120
125
  case "help":
121
126
  console.log(BIN_HELP);
122
127
  try {
@@ -181,6 +186,6 @@ export async function runBin(argv: readonly string[]): Promise<void> {
181
186
  return;
182
187
  }
183
188
  const verb = r.route === "app" ? r.argv.find((a) => a !== "--json") : r.route;
184
- if (r.route !== "tui" && r.route !== "help" && !QUIET_VERBS.has(verb ?? ""))
189
+ if (r.route !== "help" && !QUIET_VERBS.has(verb ?? ""))
185
190
  await maybeNotice("json" in r ? r.json : r.route === "app" && r.argv.includes("--json"));
186
191
  }
package/src/recheck.ts CHANGED
@@ -38,6 +38,7 @@
38
38
  // 5. **No GitHub write lives here.** The module reads (compare, files) and
39
39
  // writes nothing; the session posts its review through the gated scripts.
40
40
  // The MutationGate keeps its monopoly by this module having no mutation.
41
+ import { botAccountLogin } from "@quickchatai/pi-quickreview/src/identity.js";
41
42
  import { existsSync, mkdirSync, readdirSync, renameSync, watch, type FSWatcher } from "node:fs";
42
43
  import { join } from "node:path";
43
44
  import type { Config } from "./config.js";
@@ -1647,7 +1648,7 @@ export class RecheckWatcher {
1647
1648
  { type: "verdict", verdict: "REQUEST_CHANGES" },
1648
1649
  {},
1649
1650
  {
1650
- botLogin: this.deps.cfg.github.bot_login,
1651
+ botLogin: botAccountLogin(this.deps.cfg.github),
1651
1652
  ...(this.deps.now ? { now: this.deps.now } : {}),
1652
1653
  reason: "recheck:request-changes",
1653
1654
  },
package/src/reconcile.ts CHANGED
@@ -29,7 +29,12 @@ import { DEFAULT_ROUND_STALL_GRACE_MIN, type Config } from "./config.js";
29
29
  import type { IssueCommentFull, PrRef, ReviewCommentFull, ReviewFull } from "./github.js";
30
30
  import type { OutcomeCapture, OutcomeSweepReport } from "./outcomes.js";
31
31
  import { applyEvent, isBotAuthor, mergedOverBlock } from "./statemachine.js";
32
- import type { RoundRow, StateStore } from "./state.js";
32
+ import {
33
+ botAccountLogin,
34
+ isOwnContent,
35
+ isPersonMode,
36
+ } from "@quickchatai/pi-quickreview/src/identity.js";
37
+ import type { OpenPrSummary, RoundRow, StateStore } from "./state.js";
33
38
  import type { OvSessionSweepReport, SessionHooks } from "@quickchatai/pi-quickreview/src/types.js";
34
39
  import { performance } from "node:perf_hooks";
35
40
  import { yieldToLoop } from "@quickchatai/pi-quickreview/src/yieldloop.js";
@@ -132,6 +137,9 @@ export const RECEIPT_SWEEP_BUDGET_MS = 20_000;
132
137
  export interface ReconcileReport {
133
138
  ran_at: string;
134
139
  open_prs: number;
140
+ /** The open PRs this pass listed, tracked or not; absent when the list
141
+ * step failed. The daemon publishes it in status.json for the board. */
142
+ open_list?: OpenPrSummary[];
135
143
  triggered: number[];
136
144
  closed: number[];
137
145
  backfilled_comments: number;
@@ -255,7 +263,11 @@ export function reconcileOrphanedRounds(
255
263
  export async function reconcileOnce(deps: ReconcileDeps): Promise<ReconcileReport> {
256
264
  const { store, cfg, adapter } = deps;
257
265
  const now = deps.now ?? (() => new Date());
258
- const botLogin = cfg.github.bot_login;
266
+ // The bot ACCOUNT: whose PRs are a bot's and whose captured comments are not
267
+ // a human's. "" in person mode (`[github] auth = "user"`), where the
268
+ // configured login is the person's: their PRs are reviewed, and their own
269
+ // comments are told from the reviewer's by its marker (identity.ts).
270
+ const botLogin = botAccountLogin(cfg.github);
259
271
  const report: ReconcileReport = {
260
272
  ran_at: now().toISOString(),
261
273
  open_prs: 0,
@@ -287,6 +299,13 @@ export async function reconcileOnce(deps: ReconcileDeps): Promise<ReconcileRepor
287
299
  for (const pr of await adapter.listOpenPrs()) open.set(pr.number, pr);
288
300
  openListed = true;
289
301
  report.open_prs = open.size;
302
+ report.open_list = [...open.values()].map((p) => ({
303
+ number: p.number,
304
+ title: p.title,
305
+ author: p.author,
306
+ draft: p.draft,
307
+ updated_at: p.updated_at,
308
+ }));
290
309
  for (const pr of open.values()) {
291
310
  if (isBotAuthor(pr.author, botLogin)) continue;
292
311
  const local = store.getPr(pr.number);
@@ -921,6 +940,8 @@ export async function reconcileOnce(deps: ReconcileDeps): Promise<ReconcileRepor
921
940
  }
922
941
  for (const c of rows) {
923
942
  if (!isHumanCapture(c, botLogin)) continue;
943
+ // Person mode: the reviewer's own words under the person's login.
944
+ if (isOwnContent(cfg.github, c.author, c.body)) continue;
924
945
  if (recordCapturedComment(store, c, "reconcile")) report.captured_comments++;
925
946
  }
926
947
  // ---- the exec boundary's OUTCOME layer ------------------------------
@@ -947,7 +968,12 @@ export async function reconcileOnce(deps: ReconcileDeps): Promise<ReconcileRepor
947
968
  reviewComments: commentsByReview(inlineFetched),
948
969
  gatedCommentIds: store.botCommentIds(n),
949
970
  },
950
- { botLogin, appSlug: cfg.github.app_slug },
971
+ {
972
+ botLogin: cfg.github.bot_login,
973
+ appSlug: cfg.github.app_slug,
974
+ // Person mode: only marker-bearing reviews are the reviewer's.
975
+ personMode: isPersonMode(cfg.github),
976
+ },
951
977
  );
952
978
  if (ungated.length > 0) {
953
979
  store.logEvent("ungated_review_detected", n, {
@@ -0,0 +1,119 @@
1
+ // `qcr review`'s arguments: the usage line and the parse of argv into a
2
+ // command, in a module of their own. The terminal verb (src/reviewcli.ts) and
3
+ // the detached registry (src/reviewdetach.ts) both read them, and the
4
+ // registry's callers (the app's home) never import the review's runtime.
5
+ import { parseDestinations, type Destination } from "@quickchatai/pi-quickreview/src/reviewdest.js";
6
+
7
+ export const REVIEW_USAGE =
8
+ "usage: qcr review start|status|stop (detached runs, see `qcr review start --help`) | qcr review [branch | --uncommitted | --diff FILE|- | <PR number|URL>] [--repo OWNER/NAME] [--base REF] [--preview] [--key K] [--limit USD] [--full] [--to DEST] [--out FILE] [--debug-pi] [--json] | --help";
9
+
10
+ export type ReviewCommand =
11
+ | { help: true }
12
+ | {
13
+ help: false;
14
+ uncommitted: boolean;
15
+ /** `--diff`: a file to read the diff from, or "-" for stdin. */
16
+ diff?: string;
17
+ pr?: string;
18
+ repo?: string;
19
+ base?: string;
20
+ preview: boolean;
21
+ key?: string;
22
+ limit?: number;
23
+ full: boolean;
24
+ to?: Destination[];
25
+ out?: string;
26
+ /** `--debug-pi`: the round runs inside interactive pi. */
27
+ debugPi: boolean;
28
+ };
29
+
30
+ const usage = (why?: string): Error => new Error(why ? `${REVIEW_USAGE}\n(${why})` : REVIEW_USAGE);
31
+
32
+ /** `qcr review`'s arguments (`--json` taken off before). An unknown token is
33
+ * refused, so a mistyped flag never runs something else. */
34
+ export function parseReviewArgs(rest: readonly string[]): ReviewCommand {
35
+ let help = false;
36
+ let uncommitted = false;
37
+ let diff: string | undefined;
38
+ let preview = false;
39
+ let full = false;
40
+ let base: string | undefined;
41
+ let pr: string | undefined;
42
+ let repo: string | undefined;
43
+ let key: string | undefined;
44
+ let limit: number | undefined;
45
+ let to: Destination[] | undefined;
46
+ let out: string | undefined;
47
+ let debugPi = false;
48
+ const value = (i: number, flag: string): string => {
49
+ const v = rest[i + 1];
50
+ if (v === undefined || v.startsWith("--")) throw usage(`${flag} needs a value`);
51
+ return v;
52
+ };
53
+ for (let i = 0; i < rest.length; i++) {
54
+ const a = rest[i]!;
55
+ if (a === "--help" || a === "-h") help = true;
56
+ else if (a === "--preview") preview = true;
57
+ else if (a === "--full") full = true;
58
+ else if (a === "--debug-pi") debugPi = true;
59
+ else if (a === "--base") base = value(i++, a);
60
+ else if (a === "--diff") {
61
+ // "-" is stdin; a file whose name begins with "-" is written ./-name
62
+ const v = rest[i + 1];
63
+ if (v === undefined || (v !== "-" && v.startsWith("-")))
64
+ throw usage("--diff needs a file, or - for stdin");
65
+ diff = v;
66
+ i++;
67
+ } else if (a === "--repo") repo = value(i++, a);
68
+ else if (a === "--key") key = value(i++, a);
69
+ else if (a === "--to") {
70
+ try {
71
+ to = parseDestinations(value(i++, a));
72
+ } catch (err) {
73
+ throw usage(err instanceof Error ? err.message : String(err));
74
+ }
75
+ } else if (a === "--out") out = value(i++, a);
76
+ else if (a === "--limit") {
77
+ const n = Number(value(i++, a));
78
+ if (!Number.isFinite(n) || n <= 0)
79
+ throw usage("--limit must be a positive number of dollars");
80
+ limit = n;
81
+ } else if (a === "branch") continue;
82
+ else if (a === "--uncommitted") uncommitted = true;
83
+ else if (/^#?\d+$/.test(a) || /^https?:\/\//.test(a)) {
84
+ if (pr !== undefined) throw usage("one PR at a time");
85
+ pr = a;
86
+ } else throw usage(`unknown argument ${a}`);
87
+ }
88
+ if (help) return { help: true };
89
+ if (uncommitted && base !== undefined)
90
+ throw usage("--uncommitted reviews against HEAD; --base does not apply");
91
+ if (uncommitted && rest.includes("branch"))
92
+ throw usage("choose one target: branch or --uncommitted");
93
+ if (uncommitted && pr !== undefined) throw usage("choose one target: --uncommitted or a PR");
94
+ if (diff !== undefined) {
95
+ if (uncommitted || pr !== undefined || rest.includes("branch"))
96
+ throw usage("choose one target: branch, --uncommitted, --diff or a PR");
97
+ if (base !== undefined) throw usage("--diff carries its own changes; --base does not apply");
98
+ if (repo !== undefined) throw usage("--repo goes with a PR number or URL");
99
+ }
100
+ if (debugPi && preview) throw usage("--debug-pi runs a round; a preview starts nothing");
101
+ if (debugPi && to?.includes("pr")) throw usage("a debug round posts nothing: drop --to pr");
102
+ if (pr !== undefined && base !== undefined) throw usage("--base applies to a branch, not a PR");
103
+ if (pr === undefined && repo !== undefined) throw usage("--repo goes with a PR number or URL");
104
+ return {
105
+ help: false,
106
+ uncommitted,
107
+ ...(diff !== undefined ? { diff } : {}),
108
+ ...(pr !== undefined ? { pr } : {}),
109
+ ...(repo !== undefined ? { repo } : {}),
110
+ preview,
111
+ full,
112
+ debugPi,
113
+ ...(base !== undefined ? { base } : {}),
114
+ ...(key !== undefined ? { key } : {}),
115
+ ...(limit !== undefined ? { limit } : {}),
116
+ ...(to !== undefined ? { to } : {}),
117
+ ...(out !== undefined ? { out } : {}),
118
+ };
119
+ }
package/src/reviewcli.ts CHANGED
@@ -24,8 +24,7 @@
24
24
  // stopped short (partial); 2 usage.
25
25
  import { existsSync, openSync, readFileSync, writeSync } from "node:fs";
26
26
  import { homedir } from "node:os";
27
- import { extname, join, resolve } from "node:path";
28
- import { fileURLToPath } from "node:url";
27
+ import { join, resolve } from "node:path";
29
28
  import type { CoreConfig } from "@quickchatai/pi-quickreview/src/reviewconfig.js";
30
29
  import type { Ecosystem } from "@quickchatai/pi-quickreview/src/ecosystem.js";
31
30
  import type { ReviewMemoryPort } from "@quickchatai/pi-quickreview/src/memoryport.js";
@@ -34,7 +33,6 @@ import type { PrCredentialDeps, PrFetchRequest } from "@quickchatai/pi-quickrevi
34
33
  import {
35
34
  FALLBACK_DESTINATIONS,
36
35
  loadDefaultDestinationsIn,
37
- parseDestinations,
38
36
  planDestinations,
39
37
  saveDefaultDestinationsIn,
40
38
  type Destination,
@@ -64,9 +62,9 @@ import {
64
62
  type ReviewTarget,
65
63
  } from "@quickchatai/pi-quickreview/src/reviewapi.js";
66
64
  import { reviewHome } from "./reviewhome.js";
65
+ import { parseReviewArgs, REVIEW_USAGE, type ReviewCommand } from "./reviewargs.js";
67
66
 
68
- export const REVIEW_USAGE =
69
- "usage: qcr review start|status|stop (detached runs, see `qcr review start --help`) | qcr review [branch | --uncommitted | --diff FILE|- | <PR number|URL>] [--repo OWNER/NAME] [--base REF] [--preview] [--key K] [--limit USD] [--full] [--to DEST] [--out FILE] [--debug-pi] [--json] | --help";
67
+ export { parseReviewArgs, REVIEW_USAGE, type ReviewCommand } from "./reviewargs.js";
70
68
 
71
69
  export function reviewHelp(): string {
72
70
  return [
@@ -130,117 +128,6 @@ export function reviewHelp(): string {
130
128
  ].join("\n");
131
129
  }
132
130
 
133
- export type ReviewCommand =
134
- | { help: true }
135
- | {
136
- help: false;
137
- uncommitted: boolean;
138
- /** `--diff`: a file to read the diff from, or "-" for stdin. */
139
- diff?: string;
140
- pr?: string;
141
- repo?: string;
142
- base?: string;
143
- preview: boolean;
144
- key?: string;
145
- limit?: number;
146
- full: boolean;
147
- to?: Destination[];
148
- out?: string;
149
- /** `--debug-pi`: the round runs inside interactive pi. */
150
- debugPi: boolean;
151
- };
152
-
153
- const usage = (why?: string): Error => new Error(why ? `${REVIEW_USAGE}\n(${why})` : REVIEW_USAGE);
154
-
155
- /** `qcr review`'s arguments (`--json` taken off before). An unknown token is
156
- * refused, so a mistyped flag never runs something else. */
157
- export function parseReviewArgs(rest: readonly string[]): ReviewCommand {
158
- let help = false;
159
- let uncommitted = false;
160
- let diff: string | undefined;
161
- let preview = false;
162
- let full = false;
163
- let base: string | undefined;
164
- let pr: string | undefined;
165
- let repo: string | undefined;
166
- let key: string | undefined;
167
- let limit: number | undefined;
168
- let to: Destination[] | undefined;
169
- let out: string | undefined;
170
- let debugPi = false;
171
- const value = (i: number, flag: string): string => {
172
- const v = rest[i + 1];
173
- if (v === undefined || v.startsWith("--")) throw usage(`${flag} needs a value`);
174
- return v;
175
- };
176
- for (let i = 0; i < rest.length; i++) {
177
- const a = rest[i]!;
178
- if (a === "--help" || a === "-h") help = true;
179
- else if (a === "--preview") preview = true;
180
- else if (a === "--full") full = true;
181
- else if (a === "--debug-pi") debugPi = true;
182
- else if (a === "--base") base = value(i++, a);
183
- else if (a === "--diff") {
184
- // "-" is stdin; a file whose name begins with "-" is written ./-name
185
- const v = rest[i + 1];
186
- if (v === undefined || (v !== "-" && v.startsWith("-")))
187
- throw usage("--diff needs a file, or - for stdin");
188
- diff = v;
189
- i++;
190
- } else if (a === "--repo") repo = value(i++, a);
191
- else if (a === "--key") key = value(i++, a);
192
- else if (a === "--to") {
193
- try {
194
- to = parseDestinations(value(i++, a));
195
- } catch (err) {
196
- throw usage(err instanceof Error ? err.message : String(err));
197
- }
198
- } else if (a === "--out") out = value(i++, a);
199
- else if (a === "--limit") {
200
- const n = Number(value(i++, a));
201
- if (!Number.isFinite(n) || n <= 0)
202
- throw usage("--limit must be a positive number of dollars");
203
- limit = n;
204
- } else if (a === "branch") continue;
205
- else if (a === "--uncommitted") uncommitted = true;
206
- else if (/^#?\d+$/.test(a) || /^https?:\/\//.test(a)) {
207
- if (pr !== undefined) throw usage("one PR at a time");
208
- pr = a;
209
- } else throw usage(`unknown argument ${a}`);
210
- }
211
- if (help) return { help: true };
212
- if (uncommitted && base !== undefined)
213
- throw usage("--uncommitted reviews against HEAD; --base does not apply");
214
- if (uncommitted && rest.includes("branch"))
215
- throw usage("choose one target: branch or --uncommitted");
216
- if (uncommitted && pr !== undefined) throw usage("choose one target: --uncommitted or a PR");
217
- if (diff !== undefined) {
218
- if (uncommitted || pr !== undefined || rest.includes("branch"))
219
- throw usage("choose one target: branch, --uncommitted, --diff or a PR");
220
- if (base !== undefined) throw usage("--diff carries its own changes; --base does not apply");
221
- if (repo !== undefined) throw usage("--repo goes with a PR number or URL");
222
- }
223
- if (debugPi && preview) throw usage("--debug-pi runs a round; a preview starts nothing");
224
- if (debugPi && to?.includes("pr")) throw usage("a debug round posts nothing: drop --to pr");
225
- if (pr !== undefined && base !== undefined) throw usage("--base applies to a branch, not a PR");
226
- if (pr === undefined && repo !== undefined) throw usage("--repo goes with a PR number or URL");
227
- return {
228
- help: false,
229
- uncommitted,
230
- ...(diff !== undefined ? { diff } : {}),
231
- ...(pr !== undefined ? { pr } : {}),
232
- ...(repo !== undefined ? { repo } : {}),
233
- preview,
234
- full,
235
- debugPi,
236
- ...(base !== undefined ? { base } : {}),
237
- ...(key !== undefined ? { key } : {}),
238
- ...(limit !== undefined ? { limit } : {}),
239
- ...(to !== undefined ? { to } : {}),
240
- ...(out !== undefined ? { out } : {}),
241
- };
242
- }
243
-
244
131
  export type { ReviewRoute };
245
132
 
246
133
  /** The route a process runs on: the Action sets QCR_ROUTE=action (or runs under
@@ -465,54 +352,6 @@ export function containerRunEnv(
465
352
  return { id, name };
466
353
  }
467
354
 
468
- /** The CLI entry the detached driver re-runs: `cli` beside this module. Read
469
- * from where this module is, not from `process.argv[1]`, which is whatever the
470
- * person launched (a bin symlink, a wrapper, a test runner). */
471
- export function detachedEntry(metaUrl: string = import.meta.url): string {
472
- return fileURLToPath(new URL(`./cli${extname(fileURLToPath(metaUrl))}`, metaUrl));
473
- }
474
-
475
- /** The process `qcr review start` detaches: this node, this entry, the run's
476
- * directory and key, the review's own arguments. */
477
- export function detachedCommand(
478
- l: { dir: string; key: string; argv: readonly string[] },
479
- o: { entry?: string; execPath?: string; execArgv?: readonly string[] } = {},
480
- ): { command: string; args: string[] } {
481
- return {
482
- command: o.execPath ?? process.execPath,
483
- args: [
484
- ...(o.execArgv ?? process.execArgv),
485
- o.entry ?? detachedEntry(),
486
- "review",
487
- "--detached-run",
488
- l.dir,
489
- l.key,
490
- ...l.argv,
491
- "--json",
492
- ],
493
- };
494
- }
495
-
496
- /** The watchdog `qcr review start` detaches beside the run: this node, this
497
- * entry, the run's directory, key and driver pid. */
498
- export function watchdogCommand(
499
- w: { dir: string; key: string; pid: number },
500
- o: { entry?: string; execPath?: string; execArgv?: readonly string[] } = {},
501
- ): { command: string; args: string[] } {
502
- return {
503
- command: o.execPath ?? process.execPath,
504
- args: [
505
- ...(o.execArgv ?? process.execArgv),
506
- o.entry ?? detachedEntry(),
507
- "review",
508
- "--watchdog",
509
- w.dir,
510
- w.key,
511
- String(w.pid),
512
- ],
513
- };
514
- }
515
-
516
355
  /** The runtime `[engine] runtime` selects for `qcr review`: the SDK runtime.
517
356
  * `[pi] lens_runtime = engine` is
518
357
  * the SDK runtime with our lens tools; with `[pi] engine_wave` the runtime
@@ -578,13 +417,13 @@ export async function cmdReview(
578
417
  container !== undefined
579
418
  ? { ok: true, pid: null, container: container.name }
580
419
  : det.launchDetached({
581
- ...detachedCommand(l),
420
+ ...det.detachedCommand(l),
582
421
  dir: l.dir,
583
422
  env: process.env,
584
423
  }),
585
424
  watch: (w) => {
586
425
  det.launchDetached({
587
- ...watchdogCommand(w),
426
+ ...det.watchdogCommand(w),
588
427
  dir: w.dir,
589
428
  env: process.env,
590
429
  log: "watchdog.log",
@@ -700,7 +539,7 @@ export async function cmdReview(
700
539
  // A person's run needs a credential for every provider the review's
701
540
  // models name; a key for another provider never stands in for one.
702
541
  const { reviewLoginRefusal } = await import("./loginhint.js");
703
- const { reviewProviders } = await import("@quickchatai/pi-quickreview/src/plugin/login.js");
542
+ const { reviewProviders } = await import("@quickchatai/pi-quickreview/src/modelroute.js");
704
543
  const problem = reviewLoginRefusal({
705
544
  providers: reviewProviders(cfg),
706
545
  agentDir,