@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
@@ -1,373 +1,3 @@
1
- // The scan report's read side and its stop channel: what the TUI's `[8] scan`
2
- // tab reads out of the state home, and the one file through which it asks
3
- // the companion to stop a running scan. A leaf like stage2request.ts:
4
- // it reaches its siblings by type only, so the TUI (which never imports the
5
- // setup engine — tests/single-shepherd.test.ts) can read the run record and
6
- // the findings store without carrying the case runner along.
7
- //
8
- // Two record files, both the engine's (this module owns their names and
9
- // their parsers, so the engine and the TUI can never read them differently):
10
- // `scan/run.json` (scanrun.ts — the current run and a short history) and
11
- // `scan/findings.json` (findings.ts — every finding with its state). Each is
12
- // read totally and is one of three facts: absent (no scan has written it),
13
- // read, or unreadable with the reason — never an empty list standing in for
14
- // a file that could not be read (the honest-unknown rule).
15
- //
16
- // The stop channel mirrors the stage-2 start channel: the TUI writes
17
- // `SCAN_STOP_FILE` naming the run it showed running; the companion's scan
18
- // belt picks it up within seconds, stops exactly that run (in-flight cases
19
- // aborted, the ledger resumes the rest) and answers in
20
- // `SCAN_STOP_RESULT_FILE`, naming the request it answered — so a stop is
21
- // answered once and never replayed onto a later run.
22
- import { join } from "node:path";
23
- import { readTextIfPresent, writeAtomic } from "../channelfs.js";
24
- import type { FindingsFile, MatchQuestion, ResemblesDismissed, ScanFinding } from "./findings.js";
25
- import type { RunFile, ScanRun, ScanRunSummary } from "./scanrun.js";
26
-
27
- export type { FindingState, ScanFinding } from "./findings.js";
28
- export type { ScanCaseState, ScanRun, ScanRunSummary } from "./scanrun.js";
29
- export type { ScanSeverity } from "./scan.js";
30
-
31
- export const FINDING_STATES = ["new", "promoted", "dismissed", "fixed"] as const;
32
-
33
- export const RUN_FILE = "scan/run.json";
34
- export const RUN_VERSION = 1;
35
- export const FINDINGS_FILE = "scan/findings.json";
36
- export const FINDINGS_VERSION = 1;
37
- export const SCAN_STOP_FILE = "scan/stop.json";
38
- export const SCAN_STOP_RESULT_FILE = "scan/stop-result.json";
39
-
40
- // ---- validity tiers (the scan validator is the skeptic) -----------------
41
-
42
- /** The skeptic's tier for a stored scan finding: `confirmed` (it traced a
43
- * concrete scenario), `likely` (a real mechanism, reachability not fully
44
- * traced), `doubtful` (refuted, class-matched, or anything it would have
45
- * killed — kept, never dropped). */
46
- export type Validity = "confirmed" | "likely" | "doubtful";
47
- export const VALIDITIES: readonly Validity[] = ["confirmed", "likely", "doubtful"];
48
- /** A tier, or `unknown`: no skeptic judged it (the validator was off or
49
- * failed) or it was stored before tiers existed — never guessed. */
50
- export type ValidityView = Validity | "unknown";
51
- /** Display order: confirmed first, unknown last. */
52
- export const VALIDITY_ORDER: readonly ValidityView[] = [...VALIDITIES, "unknown"];
53
-
54
- /** The longest dismissal reason triage takes. The TUI checks it before
55
- * asking, so an over-long reason is refused where it is typed. */
56
- export const DISMISS_REASON_MAX = 500;
57
-
58
- /** A dismissed finding a re-scan settled as no longer reported (findings.ts
59
- * `unreported`): out of play, as a fixed one is, until a scan reports it again. */
60
- export const goneDismissal = (f: Pick<ScanFinding, "state" | "unreported">): boolean =>
61
- f.state === "dismissed" && f.unreported != null;
62
-
63
- /** A finding's tier as stored — `unknown` when it carries none. */
64
- export function validityOf(f: { validity?: Validity | null }): ValidityView {
65
- return f.validity !== undefined &&
66
- f.validity !== null &&
67
- (VALIDITIES as readonly string[]).includes(f.validity)
68
- ? f.validity
69
- : "unknown";
70
- }
71
-
72
- const clean = (err: unknown): string => (err instanceof Error ? err.message : String(err));
73
-
74
- // ---- the two records ---------------------------------------------------------------
75
-
76
- /** Is a finding still standing — new, or promoted and not yet fixed? The
77
- * portrait's counts and the scan tab's weights read open the same way. */
78
- export const isOpenFinding = (f: Pick<ScanFinding, "state">): boolean =>
79
- f.state === "new" || f.state === "promoted";
80
-
81
- /** A finding's resemblance to a DISMISSED one (findings.ts sets it when it
82
- * stores the finding), as a reader shows it: only on a finding still
83
- * untriaged (`new`) — once the operator promotes or dismisses it, the
84
- * resemblance is answered. */
85
- export function dismissedLookalike(
86
- f: Pick<ScanFinding, "state" | "resembles_dismissed">,
87
- ): ResemblesDismissed | null {
88
- return f.state === "new" ? (f.resembles_dismissed ?? null) : null;
89
- }
90
-
91
- /** 1 for a finding flagged as resembling a dismissed one, else 0 — the sort
92
- * key that puts it below the unflagged findings of its tier. */
93
- export const lookalikeRank = (f: Pick<ScanFinding, "state" | "resembles_dismissed">): number =>
94
- dismissedLookalike(f) ? 1 : 0;
95
-
96
- /** Parse the run record; throws on anything this version does not read. */
97
- export function parseRunFile(text: string): RunFile {
98
- const raw = JSON.parse(text) as Partial<RunFile> | null;
99
- if (typeof raw !== "object" || raw === null || raw.version !== RUN_VERSION)
100
- throw new Error("unknown version");
101
- const current = raw.current ?? null;
102
- if (current !== null && (typeof current !== "object" || !Array.isArray(current.cases))) {
103
- throw new Error("`current` is not a scan run");
104
- }
105
- return { version: RUN_VERSION, current, history: Array.isArray(raw.history) ? raw.history : [] };
106
- }
107
-
108
- /** Parse the findings store; throws on anything this version does not read. */
109
- export function parseFindingsFile(text: string): FindingsFile {
110
- const raw = JSON.parse(text) as Partial<FindingsFile> | null;
111
- if (
112
- typeof raw !== "object" ||
113
- raw === null ||
114
- raw.version !== FINDINGS_VERSION ||
115
- !Array.isArray(raw.findings)
116
- ) {
117
- throw new Error("not a version-1 findings store");
118
- }
119
- for (const f of raw.findings) {
120
- if (
121
- typeof f?.fingerprint !== "string" ||
122
- typeof f.path !== "string" ||
123
- typeof f.state !== "string"
124
- ) {
125
- throw new Error("a finding has no fingerprint, path or state");
126
- }
127
- }
128
- const q = raw.question ?? null;
129
- if (
130
- q !== null &&
131
- (typeof q.key !== "string" || !Array.isArray(q.unreported) || !Array.isArray(q.fresh))
132
- ) {
133
- throw new Error("the pending match question is malformed");
134
- }
135
- return {
136
- version: FINDINGS_VERSION,
137
- findings: currentLookalikes(raw.findings.map(stickyDismissal)),
138
- question: q,
139
- };
140
- }
141
-
142
- /** A `resembles_dismissed` flag is written when a finding is stored; the
143
- * dismissal it names can change after that — re-dismissed with another
144
- * reason, promoted (the operator changed their mind), or folded into a fresh
145
- * finding by a match answer. Every reader goes through this parse, so the
146
- * flag is re-read against the store here: it names the finding that now
147
- * carries that fingerprint (itself, or the one it became an alias of) and
148
- * that finding's current reason while it is still dismissed, and it is
149
- * dropped otherwise — a stale "looks like a finding you dismissed" never
150
- * reaches the operator. */
151
- function currentLookalikes(findings: ScanFinding[]): ScanFinding[] {
152
- if (!findings.some((f) => f.resembles_dismissed)) return findings;
153
- const owner = new Map<string, ScanFinding>();
154
- for (const f of findings) for (const a of f.aliases ?? []) owner.set(a, f);
155
- for (const f of findings) owner.set(f.fingerprint, f);
156
- return findings.map((f) => {
157
- if (!f.resembles_dismissed) return f;
158
- const { resembles_dismissed: flag, ...rest } = f;
159
- const d = owner.get(flag.fingerprint);
160
- if (!d || d.state !== "dismissed" || d.fingerprint === f.fingerprint) return rest;
161
- return {
162
- ...rest,
163
- resembles_dismissed: {
164
- fingerprint: d.fingerprint,
165
- reason: d.dismissal?.reason ?? flag.reason,
166
- },
167
- };
168
- });
169
- }
170
-
171
- /** A legacy store may hold a dismissed finding recorded as `fixed` with
172
- * `fixed.from = "dismissed"`: it reads back as the dismissal it is, its fix
173
- * kept as the `unreported` audit stamp (findings.ts). Every other finding is
174
- * returned as it is. */
175
- function stickyDismissal(f: ScanFinding): ScanFinding {
176
- if (f.state !== "fixed" || f.fixed?.from !== "dismissed") return f;
177
- const { run, sha, at } = f.fixed;
178
- return { ...f, state: "dismissed", fixed: null, unreported: { run, sha, at } };
179
- }
180
-
181
- /** One record file: absent, read, or why it could not be. */
182
- export type RecordRead<T> =
183
- { kind: "absent" } | { kind: "read"; value: T } | { kind: "unreadable"; why: string };
184
-
185
- function readRecord<T>(home: string, rel: string, parse: (text: string) => T): RecordRead<T> {
186
- let text: string | null;
187
- try {
188
- text = readTextIfPresent(join(home, rel));
189
- } catch (err) {
190
- return { kind: "unreadable", why: `${rel} cannot be read: ${clean(err)}` };
191
- }
192
- if (text === null) return { kind: "absent" };
193
- try {
194
- return { kind: "read", value: parse(text) };
195
- } catch (err) {
196
- return { kind: "unreadable", why: `${rel} is not a record this version reads (${clean(err)})` };
197
- }
198
- }
199
-
200
- /** The scan run record in the state home at `home`. */
201
- export function readScanRuns(
202
- home: string,
203
- ): RecordRead<{ current: ScanRun | null; history: ScanRunSummary[] }> {
204
- return readRecord(home, RUN_FILE, (t) => {
205
- const f = parseRunFile(t);
206
- return { current: f.current, history: f.history };
207
- });
208
- }
209
-
210
- /** The findings store in the state home at `home`. */
211
- export function readScanFindings(
212
- home: string,
213
- ): RecordRead<{ findings: ScanFinding[]; question: MatchQuestion | null }> {
214
- return readRecord(home, FINDINGS_FILE, (t) => {
215
- const f = parseFindingsFile(t);
216
- return { findings: f.findings, question: f.question ?? null };
217
- });
218
- }
219
-
220
- // ---- the stop channel --------------------------------------------------------------
221
-
222
- export interface ScanStopRequest {
223
- /** Unique per click; the result names it. */
224
- id: string;
225
- /** The run the TUI showed running — only that run is stopped. */
226
- run: string;
227
- at: string;
228
- /** Who asked: the TUI's stop, `qcr scan stop`, or the companion's
229
- * scan_stop for a run another process drives. */
230
- by: "tui" | "cli" | "companion";
231
- }
232
-
233
- export interface ScanStopResult {
234
- request: string;
235
- run: string;
236
- at: string;
237
- ok: boolean;
238
- errors: string[];
239
- /** The run the answering companion was driving when it answered — `null`
240
- * when it drove none. Absent from an answer that does not say. A run the
241
- * record still calls running that the companion says it is not driving was
242
- * interrupted (a companion restart loses the run in flight). */
243
- in_flight?: string | null;
244
- }
245
-
246
- /** Parse a stop request, or null when it is not one. */
247
- export function parseStopRequest(text: string): ScanStopRequest | null {
248
- try {
249
- const r = JSON.parse(text) as Partial<ScanStopRequest> | null;
250
- if (
251
- typeof r !== "object" ||
252
- r === null ||
253
- typeof r.id !== "string" ||
254
- r.id === "" ||
255
- typeof r.run !== "string" ||
256
- r.run === ""
257
- )
258
- return null;
259
- return {
260
- id: r.id,
261
- run: r.run,
262
- at: typeof r.at === "string" ? r.at : "",
263
- by: r.by === "cli" || r.by === "companion" ? r.by : "tui",
264
- };
265
- } catch {
266
- return null;
267
- }
268
- }
269
-
270
- /** Parse a stop result, or null when it is not one. */
271
- export function parseStopResult(text: string): ScanStopResult | null {
272
- try {
273
- const r = JSON.parse(text) as Partial<ScanStopResult> | null;
274
- if (
275
- typeof r !== "object" ||
276
- r === null ||
277
- typeof r.request !== "string" ||
278
- typeof r.ok !== "boolean"
279
- )
280
- return null;
281
- return {
282
- request: r.request,
283
- run: typeof r.run === "string" ? r.run : "",
284
- at: typeof r.at === "string" ? r.at : "",
285
- ok: r.ok,
286
- errors: Array.isArray(r.errors)
287
- ? r.errors.filter((e): e is string => typeof e === "string")
288
- : [],
289
- ...(typeof r.in_flight === "string" || r.in_flight === null
290
- ? { in_flight: r.in_flight }
291
- : {}),
292
- };
293
- } catch {
294
- return null;
295
- }
296
- }
297
-
298
- /**
299
- * The TUI's stop: ask the companion to stop the run `run`, which the TUI
300
- * showed running. Refused when the record cannot be read or no longer shows
301
- * that run running — a stop is never aimed at a run the operator did not see.
302
- * The notice line says what was asked, or why nothing was.
303
- */
304
- export function clickStopScan(
305
- home: string,
306
- run: string,
307
- now: Date = new Date(),
308
- by: ScanStopRequest["by"] = "tui",
309
- ): { ok: true; request: string; line: string } | { ok: false; line: string } {
310
- const read = readScanRuns(home);
311
- if (read.kind === "unreadable") return { ok: false, line: `scan not stopped: ${read.why}` };
312
- const cur = read.kind === "read" ? read.value.current : null;
313
- if (cur === null || cur.id !== run || cur.state !== "running") {
314
- return {
315
- ok: false,
316
- line: `scan not stopped: ${run} is no longer running — look at the report again`,
317
- };
318
- }
319
- const request: ScanStopRequest = {
320
- id: `${now.toISOString()}-${Math.random().toString(36).slice(2, 8)}`,
321
- run,
322
- at: now.toISOString(),
323
- by,
324
- };
325
- try {
326
- writeAtomic(join(home, SCAN_STOP_FILE), `${JSON.stringify(request)}\n`);
327
- } catch (err) {
328
- return {
329
- ok: false,
330
- line: `scan not stopped: the stop request could not be written: ${clean(err)}`,
331
- };
332
- }
333
- return {
334
- ok: true,
335
- request: request.id,
336
- line: `stop asked for ${run} — the companion stops it within seconds; the ledger resumes the rest`,
337
- };
338
- }
339
-
340
- /** The companion's latest stop answer: none yet (`absent`, or a file this
341
- * version does not read as one), the answer, or `unreadable` with the reason
342
- * — never a throw, and an unreadable answer is never mistaken for none. */
343
- export type StopResultRead =
344
- | { kind: "absent" }
345
- | { kind: "read"; result: ScanStopResult }
346
- | { kind: "unreadable"; why: string };
347
-
348
- export function readStopResult(home: string): StopResultRead {
349
- let text: string | null;
350
- try {
351
- text = readTextIfPresent(join(home, SCAN_STOP_RESULT_FILE));
352
- } catch (err) {
353
- return { kind: "unreadable", why: `${SCAN_STOP_RESULT_FILE}: ${clean(err)}` };
354
- }
355
- const r = text === null ? null : parseStopResult(text);
356
- return r === null ? { kind: "absent" } : { kind: "read", result: r };
357
- }
358
-
359
- /** What became of the stop `request`: the companion's answer, or null while
360
- * it has not answered (a companion that is down stops nothing — and runs
361
- * nothing either). */
362
- export function scanStopOutcome(home: string, request: string): string | null {
363
- const read = readStopResult(home);
364
- // Not "no answer yet": the answer may be there, unreadable — said once,
365
- // never polled for silently.
366
- if (read.kind === "unreadable")
367
- return `the scan stop's answer cannot be read (${read.why}) — check scan_status`;
368
- if (read.kind === "absent" || read.result.request !== request) return null;
369
- const r = read.result;
370
- return r.ok
371
- ? `scan ${r.run} stopped — what finished is in the ledger`
372
- : `scan stop refused: ${r.errors.join("; ")}`;
373
- }
1
+ // Moved to the plugin (packages/pi-plugin/src/scan/scanreport.ts), the scan engine's
2
+ // home: this name stays for the app's importers.
3
+ export * from "@quickchatai/pi-quickreview/src/scan/scanreport.js";