@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
@@ -0,0 +1,418 @@
1
+ // The home's real ports (src/home/ports.ts), and the one function that turns
2
+ // a process's environment into the home's options: the env shim
3
+ // (extensions/cli/home.ts) calls `homeOptionsFromEnv(process.env)`.
4
+ //
5
+ // pi login the auth file of the pi home the chat runs in: pi's own
6
+ // agent dir ($PI_CODING_AGENT_DIR, else ~/.pi/agent), read the
7
+ // way pi reads it, so the login line and the chat cannot
8
+ // disagree. Provider ids only, never a token.
9
+ // GitHub `gh`: the account, the repository's open PRs, the browser.
10
+ // repository `[github] repo` of the install's config.toml, read again on
11
+ // every refresh.
12
+ // clock Date.now.
13
+ // reviews the app's detached review runs, its review state and the
14
+ // daemon's status (src/home/reviews.ts), as the person: their
15
+ // environment, so the run uses their own pi login.
16
+ //
17
+ // auto-review, memory
18
+ // this machine's compose stack (src/home/autoreview.ts,
19
+ // src/home/memory.ts): the containers, the daemon's own
20
+ // status.json, and the switches over the wizard's steps.
21
+ // login owner
22
+ // the same pi agent dir: whether auto-review's refresher holds
23
+ // the login (its lock beside auth.json, shared into the stack)
24
+ // and whether its record says the login expired
25
+ // (src/home/loginowner.ts).
26
+ //
27
+ // spend the app's detached runs' costs and the daemon's recorded
28
+ // costs (src/home/spend.ts): unknown when either can't be read.
29
+ //
30
+ // The stack these drive is a compose project with the wizard's state under it
31
+ // (`homeStackRoot`): a checkout or the image is its own, an app installed by
32
+ // a package manager gets one in its state home, never inside the package.
33
+ import { execFile } from "node:child_process";
34
+ import { cpSync, existsSync, mkdirSync, readFileSync } from "node:fs";
35
+ import { join } from "node:path";
36
+ import { parse } from "smol-toml";
37
+ import { loginSummary } from "@quickchatai/pi-quickreview/src/engine/auth.js";
38
+ import { assetRoot } from "@quickchatai/pi-quickreview/src/assetroot.js";
39
+ import { postSavedReview } from "@quickchatai/pi-quickreview/src/savedpost.js";
40
+ import { HOME_DEFAULTS, sandboxRoot, type HomeToolSet } from "../config.js";
41
+ import { loadOneShotConfig, locateConfig, stackRoot, stateHome } from "../homes.js";
42
+ import type { OnboardAdapters, ProcessRunner } from "../onboard/engine.js";
43
+ import { openStepMemoryForward } from "../onboard/stepforward.js";
44
+ import { composeAutoReview, serviceState } from "./autoreview.js";
45
+ import { hostLoginOwner } from "./loginowner.js";
46
+ import { DAEMON_SERVICE } from "../onboard/steps/compose.js";
47
+ import { daemonSnapshot } from "./daemonstatus.js";
48
+ import { composeMemory } from "./memory.js";
49
+ import { realSpendPort } from "./spend.js";
50
+ import { composeAdvanced, type AdvancedPort } from "./advanced.js";
51
+ import { checkoutTune, type TunePort } from "./tune.js";
52
+ import { stepRunner } from "./switchon.js";
53
+ import { piAgentDir } from "../piagentdir.js";
54
+ import { qcrChild, realDetachSeams, reviewsPort } from "./reviews.js";
55
+ import {
56
+ known,
57
+ unknown,
58
+ type AutoReviewPort,
59
+ type GithubPort,
60
+ type HomeAdapters,
61
+ type Known,
62
+ type MemoryPort,
63
+ type OpenPull,
64
+ type PiLoginPort,
65
+ type RepoPort,
66
+ type ReviewsPort,
67
+ type SpendPort,
68
+ } from "./ports.js";
69
+
70
+ /** The launch hands the child pi its model and tool set in these. */
71
+ export const HOME_MODEL_ENV = "QCR_HOME_MODEL";
72
+ export const HOME_TOOLS_ENV = "QCR_HOME_TOOLS";
73
+
74
+ export interface RunResult {
75
+ code: number;
76
+ stdout: string;
77
+ stderr: string;
78
+ /** The command is not installed. */
79
+ missing?: boolean;
80
+ }
81
+
82
+ export interface Runner {
83
+ run(cmd: string, args: readonly string[]): Promise<RunResult>;
84
+ }
85
+
86
+ export const execRunner: Runner = {
87
+ run: (cmd, args) =>
88
+ new Promise((resolve) => {
89
+ execFile(cmd, [...args], { timeout: 30_000, maxBuffer: 16 << 20 }, (err, stdout, stderr) => {
90
+ const e = err as (NodeJS.ErrnoException & { code?: unknown }) | null;
91
+ resolve({
92
+ code: e === null ? 0 : typeof e.code === "number" ? e.code : 1,
93
+ stdout: String(stdout),
94
+ stderr: e && !stderr ? String(e.message) : String(stderr),
95
+ ...(e?.code === "ENOENT" ? { missing: true } : {}),
96
+ });
97
+ });
98
+ }),
99
+ };
100
+
101
+ const firstLine = (s: string): string => s.trim().split("\n")[0]?.trim() || "no output";
102
+ const isMissingFile = (err: unknown): boolean =>
103
+ (err as NodeJS.ErrnoException | null)?.code === "ENOENT";
104
+ const message = (err: unknown): string => (err instanceof Error ? err.message : String(err));
105
+
106
+ /** The providers pi holds a login for in `agentDir`. No auth file is no
107
+ * login; a file that cannot be read or parsed is unknown. */
108
+ export function piLoginPort(
109
+ agentDir: string,
110
+ read: (p: string) => string = (p) => readFileSync(p, "utf8"),
111
+ ): PiLoginPort {
112
+ return {
113
+ providers: async () => {
114
+ const path = join(agentDir, "auth.json");
115
+ let raw: string;
116
+ try {
117
+ raw = read(path);
118
+ } catch (err) {
119
+ return isMissingFile(err) ? known([]) : unknown(`can't read ${path}: ${message(err)}`);
120
+ }
121
+ try {
122
+ return known(Object.keys(loginSummary(raw)));
123
+ } catch (err) {
124
+ return unknown(`can't parse ${path}: ${message(err)}`);
125
+ }
126
+ },
127
+ };
128
+ }
129
+
130
+ /** gh's words for "you are not signed in". */
131
+ const SIGNED_OUT = /gh auth login|not logged in|authentication required|HTTP 401|bad credentials/i;
132
+
133
+ const PR_FIELDS =
134
+ "number,title,author,updatedAt,isDraft,additions,deletions,changedFiles,headRefName,headRefOid";
135
+
136
+ export function githubPort(runner: Runner): GithubPort {
137
+ const why = (r: RunResult): string =>
138
+ r.missing ? "gh is not installed" : `gh failed: ${firstLine(r.stderr)}`;
139
+ return {
140
+ user: async () => {
141
+ const r = await runner.run("gh", ["api", "user", "--jq", ".login"]);
142
+ if (r.code === 0 && r.stdout.trim() !== "") return known(r.stdout.trim());
143
+ if (!r.missing && SIGNED_OUT.test(r.stderr)) return known(null);
144
+ return unknown(why(r));
145
+ },
146
+ openPulls: async (repo) => {
147
+ const r = await runner.run("gh", [
148
+ "pr",
149
+ "list",
150
+ "-R",
151
+ repo,
152
+ "--state",
153
+ "open",
154
+ "--limit",
155
+ "200",
156
+ "--json",
157
+ PR_FIELDS,
158
+ ]);
159
+ if (r.code !== 0) return unknown(why(r));
160
+ try {
161
+ return known(parsePulls(r.stdout));
162
+ } catch (err) {
163
+ return unknown(`gh's answer is not a pull request list: ${message(err)}`);
164
+ }
165
+ },
166
+ openInBrowser: async (repo, pr) => {
167
+ const r = await runner.run("gh", ["pr", "view", String(pr), "-R", repo, "--web"]);
168
+ return r.code === 0 ? { ok: true } : { ok: false, why: why(r) };
169
+ },
170
+ };
171
+ }
172
+
173
+ /** `gh pr list --json` rows as OpenPulls; throws on a row of the wrong shape. */
174
+ export function parsePulls(json: string): OpenPull[] {
175
+ const rows = JSON.parse(json) as unknown;
176
+ if (!Array.isArray(rows)) throw new Error("not an array");
177
+ return rows.map((r: Record<string, unknown>) => {
178
+ if (typeof r["number"] !== "number" || typeof r["title"] !== "string")
179
+ throw new Error("a row without a number or title");
180
+ const author = r["author"] as { login?: unknown } | null | undefined;
181
+ const num = (k: string): number => (typeof r[k] === "number" ? r[k] : 0);
182
+ return {
183
+ number: r["number"],
184
+ title: r["title"],
185
+ author: typeof author?.login === "string" ? author.login : "ghost",
186
+ updatedAt: typeof r["updatedAt"] === "string" ? r["updatedAt"] : "",
187
+ isDraft: r["isDraft"] === true,
188
+ additions: num("additions"),
189
+ deletions: num("deletions"),
190
+ changedFiles: num("changedFiles"),
191
+ headRefName: typeof r["headRefName"] === "string" ? r["headRefName"] : "",
192
+ headSha: typeof r["headRefOid"] === "string" ? r["headRefOid"] : "",
193
+ };
194
+ });
195
+ }
196
+
197
+ /** `[github] repo` of the config at `configPath()`, located again on every
198
+ * read. No config file, or an empty repo, is no repository. */
199
+ export function repoPort(
200
+ configPath: () => string,
201
+ read: (p: string) => string = (p) => readFileSync(p, "utf8"),
202
+ ): RepoPort {
203
+ return {
204
+ repo: async () => {
205
+ let path: string;
206
+ let raw: string;
207
+ try {
208
+ path = configPath();
209
+ raw = read(path);
210
+ } catch (err) {
211
+ return isMissingFile(err) ? known(null) : unknown(message(err));
212
+ }
213
+ let repo: unknown;
214
+ try {
215
+ repo = (
216
+ (parse(raw) as Record<string, unknown>)["github"] as Record<string, unknown> | undefined
217
+ )?.["repo"];
218
+ } catch (err) {
219
+ return unknown(`${path} is not valid TOML: ${message(err)}`);
220
+ }
221
+ if (repo === undefined || repo === "") return known(null);
222
+ return typeof repo === "string" && /^[\w.-]+\/[\w.-]+$/.test(repo.trim())
223
+ ? known(repo.trim())
224
+ : unknown(`${path}: [github] repo is not "owner/name" (${JSON.stringify(repo)})`);
225
+ },
226
+ };
227
+ }
228
+
229
+ const NOT_YET = "the home cannot read it yet";
230
+ const notYet = async (): Promise<Known<never>> => unknown(NOT_YET);
231
+
232
+ /** The ports that have no adapter yet: each answers unknown. */
233
+ export const unbuiltPorts: {
234
+ autoReview: AutoReviewPort;
235
+ memory: MemoryPort;
236
+ spend: SpendPort;
237
+ } = {
238
+ autoReview: { status: notYet },
239
+ memory: { status: notYet },
240
+ spend: { totals: notYet },
241
+ };
242
+
243
+ /** The reviewer as the person: the app's own bin and registry, the install's
244
+ * state home and config, in the environment the home runs in; auto-review's
245
+ * rounds from the daemon of the compose stack at `stack.root`. */
246
+ export function realReviewsPort(
247
+ env: Readonly<Record<string, string | undefined>>,
248
+ stack: { root: string; runner: ProcessRunner },
249
+ ): ReviewsPort {
250
+ const state = stateHome(env);
251
+ const appRoot = sandboxRoot();
252
+ // the home's own working directory (src/home/launch.ts `homePaths`)
253
+ const cwd = join(state, "home");
254
+ const proc = { execPath: process.execPath, bin: join(appRoot, "bin", "qcr.js"), cwd, env };
255
+ const config = () => loadOneShotConfig({ root: assetRoot(), env }).cfg;
256
+ return reviewsPort({
257
+ registry: join(state, "review", "detached"),
258
+ reportsDir: join(cwd, "reviews"),
259
+ reviewHome: join(state, "review"),
260
+ snapshot: () => daemonSnapshot(stack.runner, stack.root),
261
+ qcr: qcrChild(proc),
262
+ detach: realDetachSeams(proc),
263
+ post: async (file) => {
264
+ const r = await postSavedReview(file, {
265
+ config: config(),
266
+ dryrunDir: join(state, "review", "dryrun"),
267
+ github: { env },
268
+ });
269
+ return { failed: r.failed, line: r.line };
270
+ },
271
+ dryRun: () => config().dry_run,
272
+ now: () => Date.now(),
273
+ });
274
+ }
275
+
276
+ /** The wizard's adapters for switch-on's steps, over the app root. */
277
+ export function stepAdapters(root: string, configPath: () => string) {
278
+ return (log: (line: string) => void): OnboardAdapters => ({
279
+ fetch: (input, init) => fetch(input, init),
280
+ runner: stepRunner,
281
+ clock: () => new Date(),
282
+ host: {
283
+ nodeVersion: process.version,
284
+ uid: typeof process.getuid === "function" ? process.getuid() : null,
285
+ inContainer: existsSync("/.dockerenv"),
286
+ },
287
+ paths: { stateDir: join(root, "state"), configPath: configPath() },
288
+ log,
289
+ memoryForward: (req) => openStepMemoryForward(req),
290
+ });
291
+ }
292
+
293
+ export function realHomeAdapters(o: {
294
+ agentDir: string;
295
+ configPath: () => string;
296
+ reviews: ReviewsPort;
297
+ runner?: Runner;
298
+ /** The app root, the compose project of this machine's stack: given, the
299
+ * auto-review and memory ports read and switch it. */
300
+ root?: string;
301
+ /** The spend line's port (src/home/spend.ts); absent, its stub. */
302
+ spend?: SpendPort;
303
+ }): HomeAdapters {
304
+ const repo = repoPort(o.configPath);
305
+ const stack =
306
+ o.root === undefined
307
+ ? null
308
+ : {
309
+ root: o.root,
310
+ configPath: o.configPath,
311
+ runner: stepRunner,
312
+ stepAdapters: stepAdapters(o.root, o.configPath),
313
+ };
314
+ const daemonRuns = stack
315
+ ? async (): Promise<boolean | null> => {
316
+ const s = await serviceState(stack.runner, stack.root, DAEMON_SERVICE);
317
+ return s.kind === "known" ? s.value !== "stopped" : null;
318
+ }
319
+ : undefined;
320
+ return {
321
+ login: piLoginPort(o.agentDir),
322
+ loginOwner: hostLoginOwner({
323
+ loginDir: o.agentDir,
324
+ now: () => Date.now(),
325
+ ...(daemonRuns ? { daemonRuns } : {}),
326
+ }),
327
+ github: githubPort(o.runner ?? execRunner),
328
+ repo,
329
+ clock: { now: () => Date.now() },
330
+ reviews: o.reviews,
331
+ ...unbuiltPorts,
332
+ ...(o.spend ? { spend: o.spend } : {}),
333
+ ...(stack
334
+ ? {
335
+ // switch-on shares the home's login with the stack (src/onboard/steps/loginshare.ts)
336
+ autoReview: composeAutoReview({ ...stack, loginDir: o.agentDir, now: () => Date.now() }),
337
+ memory: composeMemory({
338
+ ...stack,
339
+ repo: async () => {
340
+ const r = await repo.repo();
341
+ return r.kind === "known" ? r.value : null;
342
+ },
343
+ }),
344
+ }
345
+ : {}),
346
+ };
347
+ }
348
+
349
+ /** What a compose project needs from the app: the stack, the tunnel
350
+ * wrappers' build context, and the config template the steps fill from. */
351
+ export const STACK_FILES: readonly string[] = [
352
+ "docker-compose.yml",
353
+ join("docker", "tunnel"),
354
+ "config.example.toml",
355
+ ];
356
+
357
+ /** The compose project the home's switches drive: src/homes.ts `stackRoot`,
358
+ * the one rule every surface that reads the stack uses. */
359
+ export function homeStackRoot(
360
+ env: Readonly<Record<string, string | undefined>>,
361
+ pkgRoot: string = sandboxRoot(),
362
+ ): string {
363
+ return stackRoot(env, pkgRoot);
364
+ }
365
+
366
+ /** Give a stack outside the package the package's own STACK_FILES, again on
367
+ * every launch, so an update brings the stack that matches the app. The
368
+ * person's state there (`.env`, `state/`) is never touched. A copy that
369
+ * fails is left to the compose-file check, which says what is missing. */
370
+ export function seedStack(root: string, pkgRoot: string): void {
371
+ if (root === pkgRoot) return;
372
+ for (const f of STACK_FILES) {
373
+ const from = join(pkgRoot, f);
374
+ if (!existsSync(from)) continue;
375
+ try {
376
+ mkdirSync(root, { recursive: true });
377
+ cpSync(from, join(root, f), { recursive: true, force: true });
378
+ } catch {
379
+ // the compose-file check names it
380
+ }
381
+ }
382
+ }
383
+
384
+ /** The home's options from a process's environment: the env shim's one call. */
385
+ export function homeOptionsFromEnv(env: Readonly<Record<string, string | undefined>>): {
386
+ adapters: HomeAdapters;
387
+ model: string;
388
+ tools: HomeToolSet;
389
+ tune: TunePort;
390
+ advanced: AdvancedPort;
391
+ } {
392
+ const model = (env[HOME_MODEL_ENV] ?? "").trim() || HOME_DEFAULTS.model;
393
+ const tools: HomeToolSet = env[HOME_TOOLS_ENV] === "full" ? "full" : "reviewer";
394
+ const root = homeStackRoot(env);
395
+ seedStack(root, sandboxRoot());
396
+ const configPath = (): string => locateConfig({ env }).path;
397
+ return {
398
+ adapters: realHomeAdapters({
399
+ agentDir: piAgentDir(env),
400
+ configPath,
401
+ reviews: realReviewsPort(env, { root, runner: stepRunner }),
402
+ root,
403
+ spend: realSpendPort({
404
+ registry: join(stateHome(env), "review", "detached"),
405
+ root,
406
+ runner: stepRunner,
407
+ }),
408
+ }),
409
+ model,
410
+ tools,
411
+ tune: checkoutTune({ env, root: assetRoot, configPath, runner: stepRunner }),
412
+ advanced: composeAdvanced({
413
+ root,
414
+ env,
415
+ stepAdapters: stepAdapters(root, configPath),
416
+ }),
417
+ };
418
+ }