@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,484 @@
1
+ // home — the app's home: the panel at the top right of the app's own pi, and
2
+ // the `home_*` tools. Loaded by a bare `qcr` (src/home/launch.ts) through its
3
+ // env shim, extensions/cli/home.ts, beside the plugin; a factory over explicit
4
+ // options, so it reads no process state.
5
+ //
6
+ // Every action is one HomeModel method (src/home/model.ts), called by a key
7
+ // and by a tool alike:
8
+ //
9
+ // action key, while typing key, panel focused tool
10
+ // move the cursor alt+j / alt+k j / k, ↓ / ↑ home_move
11
+ // select a PR (hover, click) (hover, click) home_select
12
+ // open it on GitHub alt+o o home_open_pr
13
+ // read it all again alt+u u home_refresh
14
+ // review it alt+r ⏎, r home_review_pr
15
+ // show its review alt+r (reviewed) ⏎ (reviewed) home_show_review
16
+ // stop its review alt+s s home_stop_review
17
+ // what it shows — — home_status
18
+ // auto-review on/off alt+a a home_auto_review
19
+ // memory on/off alt+m m home_memory
20
+ // sign in again alt+l l home_relogin
21
+ //
22
+ // Signing in again is for a login that expired or was revoked: the login
23
+ // line says "login expired" (src/home/loginowner.ts reads the refresher's
24
+ // record, pi's own error in the chat and auto-review's pause). It is pi's
25
+ // device login, with auto-review's login refresher paused around it when it
26
+ // runs, so the box keeps one login that one process refreshes.
27
+ // tune to this repo alt+t t home_tune,
28
+ // home_tune_write
29
+ // advanced alt+x x home_advanced
30
+ //
31
+ // The two switches ask the person every question in the home (pi's select):
32
+ // a tool starts one but cannot answer it, so the confirm that turns
33
+ // auto-review on (in dry-run) and going live's own, after its proof round,
34
+ // are the person's (invariant 6).
35
+ //
36
+ // The review runs detached (the app's `qcr review start`, on the person's own
37
+ // pi login), writes its report to a file and never posts by itself; once it
38
+ // is done the person's posting rule (pi's settings, `quickreview.posting`)
39
+ // applies, asking with "No, keep it here" first; a rule pi's settings spell
40
+ // wrong is said, as the plugin says it. A review's findings go to the chat as
41
+ // the plugin's review message: shown, never a turn of its own, so a review
42
+ // that finishes while the agent works never steers it.
43
+ // next setup step alt+n ⏎ (on the card) home_setup_next
44
+ // each setup step — — home_sign_in,
45
+ // home_check_github,
46
+ // home_choose_repo
47
+ //
48
+ // On a machine that is not set up, the setup checklist (src/home/setup.ts)
49
+ // shows as a centred card (src/home/setupcard.ts) instead of the panel; when
50
+ // its last step is done the card gives way to the panel, and back again if a
51
+ // read shows a step missing once more.
52
+ //
53
+ // f2 or a click focuses the panel for its plain keys, and Esc gives the
54
+ // editor back: the panel never takes the keyboard by itself (nonCapturing).
55
+ // The first frame is drawn before any port is read; each read lands into it.
56
+ //
57
+ // The session's end (a quit, or /new replacing it) makes pi's context for it
58
+ // stale: the home lets go of it there, and a read still in flight lands into
59
+ // nothing.
60
+ import type {
61
+ ExtensionAPI,
62
+ ExtensionContext,
63
+ ExtensionFactory,
64
+ } from "@earendil-works/pi-coding-agent";
65
+ import type { KeyId, OverlayHandle, TUI } from "@earendil-works/pi-tui";
66
+ import {
67
+ registerQcrTool,
68
+ textResult,
69
+ type QcrTool,
70
+ } from "@quickchatai/pi-quickreview/extensions/pi-tool.js";
71
+ import { REVIEW_MESSAGE } from "@quickchatai/pi-quickreview/src/plugin/messages.js";
72
+ import { readQuickReviewSettings } from "@quickchatai/pi-quickreview/src/plugin/settings.js";
73
+ import type { HomeToolSet } from "../src/config.js";
74
+ import { piDeviceLogin } from "../src/home/devicelogin.js";
75
+ import { Relogin, RELOGIN_KEY, isLoginError } from "../src/home/loginowner.js";
76
+ import { HomeAdvanced, type AdvancedAsk, type AdvancedPort } from "../src/home/advanced.js";
77
+ import { advancedTools } from "../src/home/advancedtools.js";
78
+ import { HomeModel } from "../src/home/model.js";
79
+ import { HOME_OVERLAY, HomePanel } from "../src/home/panel.js";
80
+ import type { HomeAdapters } from "../src/home/ports.js";
81
+ import type { Ask } from "../src/home/switches.js";
82
+ import { HomeSetup, type HomeSetupPorts, type SetupUi } from "../src/home/setup.js";
83
+ import { SETUP_OVERLAY, SetupCard } from "../src/home/setupcard.js";
84
+ import { setupTools } from "../src/home/setuptools.js";
85
+ import { HOME_TOOL_NAMES } from "../src/home/toolnames.js";
86
+ import { HomeTune, type TunePort } from "../src/home/tune.js";
87
+
88
+ type HomeToolName = (typeof HOME_TOOL_NAMES)[number];
89
+
90
+ export interface HomeOptions {
91
+ adapters: HomeAdapters;
92
+ /** The model the home was launched on, `provider/id`. */
93
+ model: string;
94
+ /** The tool set it was launched with, shown on the login line. */
95
+ tools: HomeToolSet;
96
+ /** Run `fn` every `ms` until the returned stop is called. */
97
+ every?: (ms: number, fn: () => void) => () => void;
98
+ /** Run `fn` once after `ms`; the returned function cancels it. */
99
+ after?: (ms: number, fn: () => void) => () => void;
100
+ /** The setup checklist's ports beyond the home's own. */
101
+ setup?: HomeSetupPorts;
102
+ /** "Tune to this repo": Setup over a checkout (src/home/tune.ts). */
103
+ tune?: TunePort;
104
+ /** Advanced: the wizard's steps beyond switch-on (src/home/advanced.ts). */
105
+ advanced?: AdvancedPort;
106
+ }
107
+
108
+ /** How often the home reads its sources again by itself. */
109
+ export const REFRESH_MS = 60_000;
110
+ const SPIN_MS = 100;
111
+
112
+ const realEvery = (ms: number, fn: () => void): (() => void) => {
113
+ const t = setInterval(fn, ms);
114
+ t.unref?.();
115
+ return () => clearInterval(t);
116
+ };
117
+
118
+ const realAfter = (ms: number, fn: () => void): (() => void) => {
119
+ const t = setTimeout(fn, ms);
120
+ t.unref?.();
121
+ return () => clearTimeout(t);
122
+ };
123
+
124
+ const NO_PARAMS = { type: "object", properties: {}, additionalProperties: false } as const;
125
+ const PR_PARAM = {
126
+ type: "integer",
127
+ minimum: 1,
128
+ description: "The pull request's number.",
129
+ } as const;
130
+
131
+ export function createHome(o: HomeOptions): ExtensionFactory {
132
+ return (pi: ExtensionAPI) => {
133
+ const every = o.every ?? realEvery;
134
+ let tui: TUI | undefined;
135
+ let handle: OverlayHandle | undefined;
136
+ let close: (() => void) | undefined;
137
+ let mounted: "setup" | "home" | undefined;
138
+ let session: ExtensionContext | undefined;
139
+ let frame = 0;
140
+ /** The session's UI, for the switches' questions. */
141
+ let sessionUi: Ask | undefined;
142
+ const askOf = (ctx: ExtensionContext | undefined): Ask | undefined =>
143
+ ctx?.hasUI ? ctx.ui : sessionUi;
144
+ const stops: Array<() => void> = [];
145
+ const redraw = (): void => tui?.requestRender();
146
+ // the session's UI, for the post question; none outside the TUI
147
+ let ui: ExtensionContext["ui"] | undefined;
148
+ const message = (err: unknown): string => (err instanceof Error ? err.message : String(err));
149
+ // a read nobody awaits: what went wrong is said, while the session lasts
150
+ const refresh = (): void => {
151
+ model.refresh().catch((err: unknown) => {
152
+ if (session) model.say(`Couldn't read everything again: ${message(err)}`, "warn");
153
+ });
154
+ };
155
+ const model: HomeModel = new HomeModel({
156
+ adapters: o.adapters,
157
+ model: o.model,
158
+ tools: o.tools,
159
+ onChange: redraw,
160
+ after: o.after ?? realAfter,
161
+ ask: async (question, options) => ui?.select(question, options),
162
+ // shown, never a turn of its own: while the agent streams, the message
163
+ // waits for the turn to end instead of steering it
164
+ send: (m) =>
165
+ pi.sendMessage(
166
+ { customType: REVIEW_MESSAGE, content: m.content, display: true, details: m.details },
167
+ { triggerTurn: false },
168
+ ),
169
+ postingRule: () => {
170
+ let all: unknown;
171
+ try {
172
+ all = pi.getSettings();
173
+ } catch {
174
+ all = undefined;
175
+ }
176
+ const read = readQuickReviewSettings(all);
177
+ for (const w of read.warnings) warn(w);
178
+ return read.settings.posting;
179
+ },
180
+ gaps: (): string[] => setup.gaps(),
181
+ onRead: (): Promise<void> => setup.sync(),
182
+ });
183
+ // a word to the person: pi's notice, else the panel's line
184
+ const warn = (text: string): void => {
185
+ if (session?.hasUI) session.ui.notify(text, "warning");
186
+ else model.say(text, "warn");
187
+ };
188
+ const setup: HomeSetup = new HomeSetup({
189
+ model,
190
+ github: o.adapters.github,
191
+ ports: o.setup ?? {},
192
+ deviceLogin: () => deviceLogin(),
193
+ onChange: redraw,
194
+ onPhase: () => {
195
+ if (session?.mode === "tui") mount(session);
196
+ },
197
+ interactive: () => session?.mode === "tui",
198
+ });
199
+ const deviceLogin = () =>
200
+ o.setup?.deviceLogin ?? (session ? piDeviceLogin(session.modelRegistry) : undefined);
201
+ const relogin = new Relogin({
202
+ model,
203
+ owner: o.adapters.loginOwner,
204
+ deviceLogin,
205
+ onChange: redraw,
206
+ });
207
+ const tune = new HomeTune({
208
+ ...(o.tune ? { port: o.tune } : {}),
209
+ repo: () => model.repo(),
210
+ say: (text, kind) => model.say(text, kind),
211
+ after: o.after ?? realAfter,
212
+ onChange: redraw,
213
+ });
214
+ const advanced = new HomeAdvanced({
215
+ ...(o.advanced ? { port: o.advanced } : {}),
216
+ ...(o.adapters.autoReview.control ? { autoReview: o.adapters.autoReview.control } : {}),
217
+ say: (text, kind) => model.say(text, kind),
218
+ refresh: () => model.refresh(),
219
+ selected: () => model.selected,
220
+ });
221
+ // Setup's brief goes to the chat as the person's message, after the
222
+ // agent's turn when one is running
223
+ const tellAgent = (text: string): void => pi.sendUserMessage(text, { deliverAs: "followUp" });
224
+ const advancedAsk = (ctx: ExtensionContext | undefined): AdvancedAsk | undefined =>
225
+ ctx?.hasUI ? ctx.ui : session?.hasUI ? session.ui : undefined;
226
+ const dialogs = (ctx: ExtensionContext | undefined): SetupUi | undefined =>
227
+ ctx?.hasUI
228
+ ? {
229
+ select: (title, options) => ctx.ui.select(title, options),
230
+ input: (title, placeholder) => ctx.ui.input(title, placeholder),
231
+ }
232
+ : undefined;
233
+ const nextStep = (ctx: ExtensionContext | undefined): Promise<string> =>
234
+ setup.next(dialogs(ctx));
235
+
236
+ // The card while setup has a gap, the panel otherwise; a change of phase
237
+ // closes the one and opens the other.
238
+ const mount = (ctx: ExtensionContext): void => {
239
+ const want = setup.phase();
240
+ if (close && mounted === want) return;
241
+ close?.();
242
+ close = undefined;
243
+ handle = undefined;
244
+ mounted = want;
245
+ const focused = (): boolean => handle?.isFocused() ?? false;
246
+ void ctx.ui.custom<void>(
247
+ (t, theme, _keys, done) => {
248
+ tui = t;
249
+ close = () => done();
250
+ return want === "setup"
251
+ ? new SetupCard(theme, {
252
+ setup,
253
+ model,
254
+ focused,
255
+ rows: () => t.terminal.rows,
256
+ unfocus: () => handle?.unfocus(),
257
+ frame: () => frame,
258
+ next: () => void nextStep(session),
259
+ })
260
+ : new HomePanel(theme, {
261
+ model,
262
+ focused,
263
+ rows: () => t.terminal.rows,
264
+ unfocus: () => handle?.unfocus(),
265
+ frame: () => frame,
266
+ ask: () => sessionUi,
267
+ relogin: () => void relogin.start(),
268
+ signingAgain: () => relogin.running() !== null,
269
+ tune: () => void tune.tune(tellAgent),
270
+ advanced: () => void advanced.open(advancedAsk(session)),
271
+ });
272
+ },
273
+ {
274
+ overlay: true,
275
+ overlayOptions:
276
+ want === "setup"
277
+ ? { ...SETUP_OVERLAY }
278
+ : { ...HOME_OVERLAY, margin: { ...HOME_OVERLAY.margin } },
279
+ onHandle: (h) => (handle = h),
280
+ },
281
+ );
282
+ };
283
+
284
+ pi.on("session_start", (_e, ctx) => {
285
+ session = ctx;
286
+ model.setChatModel(ctx.model?.provider);
287
+ ui = ctx.mode === "tui" ? ctx.ui : undefined;
288
+ sessionUi = ctx.hasUI ? ctx.ui : undefined;
289
+ if (ctx.mode === "tui") {
290
+ mount(ctx);
291
+ // the spinner turns only while a read or a setup step is in flight
292
+ stops.push(
293
+ every(SPIN_MS, () => {
294
+ if (!model.busy() && !setup.busy() && relogin.running() === null) return;
295
+ frame++;
296
+ redraw();
297
+ }),
298
+ );
299
+ }
300
+ stops.push(every(REFRESH_MS, refresh));
301
+ refresh();
302
+ });
303
+ pi.on("model_select", (e) => model.setChatModel(e.model.provider));
304
+ // pi's own word on the login: a reply refused for it, or one that came back
305
+ pi.on("message_end", (e) => {
306
+ const m = e.message as { role?: unknown; stopReason?: unknown; errorMessage?: unknown };
307
+ if (m.role !== "assistant") return;
308
+ if (m.stopReason === "error") {
309
+ if (typeof m.errorMessage === "string" && isLoginError(m.errorMessage))
310
+ model.loginFailed(m.errorMessage);
311
+ } else if (m.stopReason !== "aborted") model.chatAnswered();
312
+ });
313
+ pi.on("session_shutdown", () => {
314
+ // the session's timers and its pricing stop; a running review goes on
315
+ model.dispose();
316
+ relogin.close();
317
+ tune.dispose();
318
+ ui = undefined;
319
+ for (const stop of stops.splice(0)) stop();
320
+ setup.close();
321
+ close?.();
322
+ close = undefined;
323
+ mounted = undefined;
324
+ // pi's context for this session is stale now: nothing may reach it
325
+ session = undefined;
326
+ sessionUi = undefined;
327
+ tui = undefined;
328
+ });
329
+
330
+ const key = (
331
+ id: string,
332
+ description: string,
333
+ run: (ctx: ExtensionContext | undefined) => unknown,
334
+ ): void =>
335
+ pi.registerShortcut(id as KeyId, {
336
+ description,
337
+ handler: (ctx) => {
338
+ void new Promise((resolve) => resolve(run(ctx))).catch((err: unknown) => {
339
+ if (session) model.say(message(err), "warn");
340
+ });
341
+ },
342
+ });
343
+ key("alt+j", "quickreview home: next pull request", () => model.move(1));
344
+ key("alt+k", "quickreview home: previous pull request", () => model.move(-1));
345
+ key("alt+o", "quickreview home: open the pull request on GitHub", () => model.openPr());
346
+ key("alt+u", "quickreview home: read everything again", () => refresh());
347
+ key("alt+r", "quickreview home: review the pull request, or show its review", () =>
348
+ model.enter(),
349
+ );
350
+ key("alt+s", "quickreview home: stop the pull request's review", () => model.stopReview());
351
+ key("f2", "quickreview home: focus the panel", () => handle?.focus());
352
+ key("alt+a", "quickreview home: switch auto-review on or off", (ctx) =>
353
+ model.switchAutoReview(askOf(ctx)),
354
+ );
355
+ key("alt+m", "quickreview home: switch memory on or off", (ctx) =>
356
+ model.switchMemory(askOf(ctx)),
357
+ );
358
+ key(RELOGIN_KEY, "quickreview home: sign in again (an expired login)", () => relogin.start());
359
+ key("alt+t", "quickreview home: tune the review to this repo (Setup)", () =>
360
+ tune.tune(tellAgent),
361
+ );
362
+ key(
363
+ "alt+x",
364
+ "quickreview home: advanced (a GitHub App, webhooks, a server, Slack, live)",
365
+ (ctx) => advanced.open(advancedAsk(ctx)),
366
+ );
367
+ pi.registerShortcut("alt+n", {
368
+ description: "quickreview home: run the next setup step",
369
+ handler: (ctx) => {
370
+ void nextStep(ctx);
371
+ },
372
+ });
373
+
374
+ // one definition per HOME_TOOL_NAMES entry: a name without one does not compile
375
+ const tools: { [N in HomeToolName]: QcrTool & { name: N } } = {
376
+ home_status: {
377
+ name: "home_status",
378
+ label: "Home status",
379
+ description:
380
+ "Read what the quickreview home shows: the repository, the logins, auto-review, memory, spend and the open pull requests (To review, Reviewed). A value that could not be read is null.",
381
+ parameters: NO_PARAMS,
382
+ execute: () => textResult(JSON.stringify(model.status(), null, 1)),
383
+ },
384
+ home_refresh: {
385
+ name: "home_refresh",
386
+ label: "Home refresh",
387
+ description:
388
+ "Read the home's sources again: the logins, the repository and its open pull requests.",
389
+ parameters: NO_PARAMS,
390
+ execute: async () => textResult(await model.refresh()),
391
+ },
392
+ home_move: {
393
+ name: "home_move",
394
+ label: "Home move",
395
+ description:
396
+ "Move the home's selection through its pull request lists: 1 is the next row, -1 the previous.",
397
+ parameters: {
398
+ type: "object",
399
+ properties: { by: { type: "integer", description: "Rows to move; negative moves up." } },
400
+ required: ["by"],
401
+ additionalProperties: false,
402
+ },
403
+ execute: (_id, p) => textResult(model.move(Number(p["by"]))),
404
+ },
405
+ home_select: {
406
+ name: "home_select",
407
+ label: "Home select",
408
+ description: "Select one open pull request in the home's lists, by number.",
409
+ parameters: {
410
+ type: "object",
411
+ properties: { pr: PR_PARAM },
412
+ required: ["pr"],
413
+ additionalProperties: false,
414
+ },
415
+ execute: (_id, p) => textResult(model.select(Number(p["pr"]))),
416
+ },
417
+ home_open_pr: {
418
+ name: "home_open_pr",
419
+ label: "Home open PR",
420
+ description:
421
+ "Open a pull request on GitHub in the person's browser: the one given, or the home's selected one.",
422
+ parameters: { type: "object", properties: { pr: PR_PARAM }, additionalProperties: false },
423
+ execute: async (_id, p) =>
424
+ textResult(await model.openPr(typeof p["pr"] === "number" ? p["pr"] : undefined)),
425
+ },
426
+ home_review_pr: {
427
+ name: "home_review_pr",
428
+ label: "Home review PR",
429
+ description:
430
+ "Review a pull request with QuickReview in the background: the one given, or the home's selected one. It previews the price, starts the review and returns at once; the home shows its progress and findings, and nothing is posted to GitHub unless the person's posting rule says so.",
431
+ parameters: { type: "object", properties: { pr: PR_PARAM }, additionalProperties: false },
432
+ execute: async (_id, p) =>
433
+ textResult(await model.review(typeof p["pr"] === "number" ? p["pr"] : undefined)),
434
+ },
435
+ home_show_review: {
436
+ name: "home_show_review",
437
+ label: "Home show review",
438
+ description:
439
+ "Put a reviewed pull request's findings in the chat: the one given, or the home's selected one.",
440
+ parameters: { type: "object", properties: { pr: PR_PARAM }, additionalProperties: false },
441
+ execute: (_id, p) =>
442
+ textResult(model.showReview(typeof p["pr"] === "number" ? p["pr"] : undefined)),
443
+ },
444
+ home_stop_review: {
445
+ name: "home_stop_review",
446
+ label: "Home stop review",
447
+ description:
448
+ "Stop the running QuickReview review of a pull request: the one given, or the home's selected one.",
449
+ parameters: { type: "object", properties: { pr: PR_PARAM }, additionalProperties: false },
450
+ execute: async (_id, p) =>
451
+ textResult(await model.stopReview(typeof p["pr"] === "number" ? p["pr"] : undefined)),
452
+ },
453
+ home_auto_review: {
454
+ name: "home_auto_review",
455
+ label: "Home auto-review",
456
+ description:
457
+ "Switch auto-review on or off. Switching on checks this machine, then asks the person where it runs, whether to turn memory on too, and for their one confirm, and it comes up in dry-run; switching off warns them which review is running, and from dry-run offers going live (a proof round on the selected pull request, then one more confirm). Every question is the person's to answer in the home: this tool cannot answer or confirm for them.",
458
+ parameters: NO_PARAMS,
459
+ execute: async (_id, _p, _signal, _onUpdate, ctx) =>
460
+ textResult(await model.switchAutoReview(askOf(ctx))),
461
+ },
462
+ home_memory: {
463
+ name: "home_memory",
464
+ label: "Home memory",
465
+ description:
466
+ "Switch reviewer memory on or off, on its own: auto-review is not touched. The person confirms in the home, after seeing its RAM cost.",
467
+ parameters: NO_PARAMS,
468
+ execute: async (_id, _p, _signal, _onUpdate, ctx) =>
469
+ textResult(await model.switchMemory(askOf(ctx))),
470
+ },
471
+ home_relogin: {
472
+ name: "home_relogin",
473
+ label: "Home sign in again",
474
+ description:
475
+ "Sign in again with pi's own device-code login, for the provider the chat runs on, when the login has expired or was revoked (the home's login line says \"login expired\"). When auto-review runs on this machine its login refresher is paused during the sign-in and resumes on the new login. Answers with the URL and the code to enter once pi has them; the sign-in finishes in the background when the person approves it.",
476
+ parameters: NO_PARAMS,
477
+ execute: async () => textResult(await relogin.start()),
478
+ },
479
+ ...setupTools(setup),
480
+ ...advancedTools({ tune, advanced, tellAgent, ask: (ctx) => advancedAsk(ctx) }),
481
+ };
482
+ for (const name of HOME_TOOL_NAMES) registerQcrTool(pi, tools[name]);
483
+ };
484
+ }