@xingular/harness 0.1.7 → 1.1.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 (819) hide show
  1. package/CHANGELOG.md +125 -1
  2. package/LICENSE +202 -0
  3. package/NOTICE.md +22 -0
  4. package/README.md +239 -86
  5. package/THIRD_PARTY_LICENSES.md +942 -0
  6. package/dist/cli.js +17853 -13114
  7. package/dist/sdk/accounts/accounts.d.ts +165 -0
  8. package/dist/sdk/accounts/accounts.js +730 -0
  9. package/dist/sdk/accounts/choices.d.ts +23 -0
  10. package/dist/sdk/accounts/choices.js +62 -0
  11. package/dist/sdk/accounts/env.d.ts +78 -0
  12. package/dist/sdk/accounts/env.js +294 -0
  13. package/dist/sdk/accounts/secrets.d.ts +16 -0
  14. package/dist/sdk/accounts/secrets.js +40 -0
  15. package/dist/sdk/accounts/store.d.ts +114 -0
  16. package/dist/sdk/accounts/store.js +255 -0
  17. package/dist/sdk/agents/builtin.d.ts +2 -0
  18. package/dist/sdk/agents/builtin.js +34 -0
  19. package/dist/sdk/agents/narrow.d.ts +13 -0
  20. package/dist/sdk/agents/narrow.js +29 -0
  21. package/dist/sdk/agents/profiles.d.ts +80 -0
  22. package/dist/sdk/agents/profiles.js +221 -0
  23. package/dist/sdk/annotations/bridge.d.ts +42 -0
  24. package/dist/sdk/annotations/bridge.js +264 -0
  25. package/dist/sdk/annotations/capture.d.ts +116 -0
  26. package/dist/sdk/annotations/capture.js +308 -0
  27. package/dist/sdk/annotations/delivery.d.ts +72 -0
  28. package/dist/sdk/annotations/delivery.js +130 -0
  29. package/dist/sdk/annotations/inspect.d.ts +10 -0
  30. package/dist/sdk/annotations/inspect.js +33 -0
  31. package/dist/sdk/annotations/isolated.d.ts +6 -0
  32. package/dist/sdk/annotations/isolated.js +51 -0
  33. package/dist/sdk/annotations/pageScript.d.ts +28 -0
  34. package/dist/sdk/annotations/pageScript.js +570 -0
  35. package/dist/sdk/annotations/part.d.ts +10 -0
  36. package/dist/sdk/annotations/part.js +144 -0
  37. package/dist/sdk/annotations/queue.d.ts +4 -0
  38. package/dist/sdk/annotations/queue.js +40 -0
  39. package/dist/sdk/annotations/serverMethods.d.ts +3 -0
  40. package/dist/sdk/annotations/serverMethods.js +62 -0
  41. package/dist/sdk/annotations/store.d.ts +160 -0
  42. package/dist/sdk/annotations/store.js +386 -0
  43. package/dist/sdk/browser/config.d.ts +16 -0
  44. package/dist/sdk/browser/config.js +22 -0
  45. package/dist/sdk/browser/diagnostics.d.ts +4 -0
  46. package/dist/sdk/browser/diagnostics.js +38 -0
  47. package/dist/sdk/browser/index.d.ts +28 -0
  48. package/dist/sdk/browser/index.js +72 -0
  49. package/dist/sdk/browser/network.d.ts +10 -0
  50. package/dist/sdk/browser/network.js +59 -0
  51. package/dist/sdk/browser/serverMethods.d.ts +3 -0
  52. package/dist/sdk/browser/serverMethods.js +7 -0
  53. package/dist/sdk/browser/session.d.ts +85 -0
  54. package/dist/sdk/browser/session.js +228 -0
  55. package/dist/sdk/browser/tools.d.ts +8 -0
  56. package/dist/sdk/browser/tools.js +329 -0
  57. package/dist/sdk/capabilities/api.d.ts +22 -0
  58. package/dist/sdk/capabilities/api.js +54 -0
  59. package/dist/sdk/capabilities/runSnapshot.d.ts +18 -0
  60. package/dist/sdk/capabilities/runSnapshot.js +47 -0
  61. package/dist/sdk/capabilities/types.d.ts +29 -0
  62. package/dist/sdk/capabilities/types.js +1 -0
  63. package/dist/sdk/cli.d.ts +2 -0
  64. package/dist/sdk/cli.js +150 -0
  65. package/dist/sdk/core/bus.d.ts +23 -0
  66. package/dist/sdk/core/bus.js +76 -0
  67. package/dist/sdk/core/caller.d.ts +22 -0
  68. package/dist/sdk/core/caller.js +16 -0
  69. package/dist/sdk/core/changes.d.ts +15 -0
  70. package/dist/sdk/core/changes.js +15 -0
  71. package/dist/sdk/core/effort.d.ts +2 -0
  72. package/dist/sdk/core/effort.js +1 -0
  73. package/dist/sdk/core/env.d.ts +18 -0
  74. package/dist/sdk/core/env.js +8 -0
  75. package/dist/sdk/core/errors.d.ts +15 -0
  76. package/dist/sdk/core/errors.js +24 -0
  77. package/dist/sdk/core/frontmatter.d.ts +12 -0
  78. package/dist/sdk/core/frontmatter.js +50 -0
  79. package/dist/sdk/core/fs.d.ts +18 -0
  80. package/dist/sdk/core/fs.js +106 -0
  81. package/dist/sdk/core/index.d.ts +24 -0
  82. package/dist/sdk/core/index.js +187 -0
  83. package/dist/sdk/core/path.d.ts +7 -0
  84. package/dist/sdk/core/path.js +79 -0
  85. package/dist/sdk/core/projects.d.ts +18 -0
  86. package/dist/sdk/core/projects.js +67 -0
  87. package/dist/sdk/core/secrets.d.ts +2 -0
  88. package/dist/sdk/core/secrets.js +5 -0
  89. package/dist/sdk/core/text.d.ts +7 -0
  90. package/dist/sdk/core/text.js +40 -0
  91. package/dist/sdk/doctor/checks.d.ts +5 -0
  92. package/dist/sdk/doctor/checks.js +208 -0
  93. package/dist/sdk/doctor/probe.d.ts +4 -0
  94. package/dist/sdk/doctor/probe.js +92 -0
  95. package/dist/sdk/doctor/serverMethods.d.ts +3 -0
  96. package/dist/sdk/doctor/serverMethods.js +8 -0
  97. package/dist/sdk/doctor/service.d.ts +23 -0
  98. package/dist/sdk/doctor/service.js +144 -0
  99. package/dist/sdk/doctor/types.d.ts +141 -0
  100. package/dist/sdk/doctor/types.js +29 -0
  101. package/dist/sdk/harness.d.ts +148 -0
  102. package/dist/sdk/harness.js +338 -0
  103. package/dist/sdk/history/lessonPrompt.d.ts +2 -0
  104. package/dist/sdk/history/lessonPrompt.js +15 -0
  105. package/dist/sdk/history/lessons.d.ts +52 -0
  106. package/dist/sdk/history/lessons.js +173 -0
  107. package/dist/sdk/history/recall.d.ts +68 -0
  108. package/dist/sdk/history/recall.js +199 -0
  109. package/dist/sdk/history/serverMethods.d.ts +3 -0
  110. package/dist/sdk/history/serverMethods.js +8 -0
  111. package/dist/sdk/history/trajectory.d.ts +7 -0
  112. package/dist/sdk/history/trajectory.js +216 -0
  113. package/dist/sdk/hub/catalog.json +123 -0
  114. package/dist/sdk/hub/cli.d.ts +7 -0
  115. package/dist/sdk/hub/cli.js +81 -0
  116. package/dist/sdk/hub/hub.d.ts +74 -0
  117. package/dist/sdk/hub/hub.js +474 -0
  118. package/dist/sdk/hub/schema.d.ts +280 -0
  119. package/dist/sdk/hub/schema.js +78 -0
  120. package/dist/sdk/hub/serverMethods.d.ts +3 -0
  121. package/dist/sdk/hub/serverMethods.js +11 -0
  122. package/dist/sdk/index.d.ts +73 -0
  123. package/dist/sdk/index.js +55 -0
  124. package/dist/sdk/mcp/connections.d.ts +83 -0
  125. package/dist/sdk/mcp/connections.js +676 -0
  126. package/dist/sdk/mcp/manager.d.ts +26 -0
  127. package/dist/sdk/mcp/manager.js +124 -0
  128. package/dist/sdk/mcp/oauth.d.ts +35 -0
  129. package/dist/sdk/mcp/oauth.js +171 -0
  130. package/dist/sdk/mcp/scopeMigration.d.ts +19 -0
  131. package/dist/sdk/mcp/scopeMigration.js +198 -0
  132. package/dist/sdk/mcp/serverMethods.d.ts +3 -0
  133. package/dist/sdk/mcp/serverMethods.js +22 -0
  134. package/dist/sdk/mcp/service.d.ts +160 -0
  135. package/dist/sdk/mcp/service.js +510 -0
  136. package/dist/sdk/mcp/types.d.ts +131 -0
  137. package/dist/sdk/mcp/types.js +49 -0
  138. package/dist/sdk/pi/runtime.d.ts +13 -0
  139. package/dist/sdk/pi/runtime.js +31 -0
  140. package/dist/sdk/plugins/api.d.ts +66 -0
  141. package/dist/sdk/plugins/api.js +155 -0
  142. package/dist/sdk/plugins/attachments.d.ts +46 -0
  143. package/dist/sdk/plugins/attachments.js +111 -0
  144. package/dist/sdk/plugins/builtin.d.ts +7 -0
  145. package/dist/sdk/plugins/builtin.js +163 -0
  146. package/dist/sdk/plugins/builtinRegistry.d.ts +53 -0
  147. package/dist/sdk/plugins/builtinRegistry.js +49 -0
  148. package/dist/sdk/plugins/catalogue.d.ts +29 -0
  149. package/dist/sdk/plugins/catalogue.js +196 -0
  150. package/dist/sdk/plugins/cli.d.ts +13 -0
  151. package/dist/sdk/plugins/cli.js +188 -0
  152. package/dist/sdk/plugins/discover.d.ts +42 -0
  153. package/dist/sdk/plugins/discover.js +115 -0
  154. package/dist/sdk/plugins/firstParty.d.ts +50 -0
  155. package/dist/sdk/plugins/firstParty.js +113 -0
  156. package/dist/sdk/plugins/hooks.d.ts +94 -0
  157. package/dist/sdk/plugins/hooks.js +162 -0
  158. package/dist/sdk/plugins/identity.d.ts +19 -0
  159. package/dist/sdk/plugins/identity.js +48 -0
  160. package/dist/sdk/plugins/install.d.ts +20 -0
  161. package/dist/sdk/plugins/install.js +110 -0
  162. package/dist/sdk/plugins/inventory.d.ts +22 -0
  163. package/dist/sdk/plugins/inventory.js +110 -0
  164. package/dist/sdk/plugins/manifest.d.ts +13 -0
  165. package/dist/sdk/plugins/manifest.js +56 -0
  166. package/dist/sdk/plugins/plugins.d.ts +104 -0
  167. package/dist/sdk/plugins/plugins.js +164 -0
  168. package/dist/sdk/plugins/runtime.d.ts +9 -0
  169. package/dist/sdk/plugins/runtime.js +95 -0
  170. package/dist/sdk/plugins/trust.d.ts +44 -0
  171. package/dist/sdk/plugins/trust.js +120 -0
  172. package/dist/sdk/plugins/types.d.ts +159 -0
  173. package/dist/sdk/plugins/types.js +7 -0
  174. package/dist/sdk/prompt/compile.d.ts +177 -0
  175. package/dist/sdk/prompt/compile.js +413 -0
  176. package/dist/sdk/refine/cli.d.ts +4 -0
  177. package/dist/sdk/refine/cli.js +186 -0
  178. package/dist/sdk/refine/demo.d.ts +21 -0
  179. package/dist/sdk/refine/demo.js +114 -0
  180. package/dist/sdk/refine/evidence.d.ts +55 -0
  181. package/dist/sdk/refine/evidence.js +330 -0
  182. package/dist/sdk/refine/host.d.ts +51 -0
  183. package/dist/sdk/refine/host.js +76 -0
  184. package/dist/sdk/refine/ledger.d.ts +48 -0
  185. package/dist/sdk/refine/ledger.js +76 -0
  186. package/dist/sdk/refine/library.d.ts +55 -0
  187. package/dist/sdk/refine/library.js +177 -0
  188. package/dist/sdk/refine/pi.d.ts +72 -0
  189. package/dist/sdk/refine/pi.js +248 -0
  190. package/dist/sdk/refine/prompts.d.ts +45 -0
  191. package/dist/sdk/refine/prompts.js +390 -0
  192. package/dist/sdk/refine/recursion.d.ts +113 -0
  193. package/dist/sdk/refine/recursion.js +258 -0
  194. package/dist/sdk/refine/runner.d.ts +81 -0
  195. package/dist/sdk/refine/runner.js +150 -0
  196. package/dist/sdk/refine/selection.d.ts +57 -0
  197. package/dist/sdk/refine/selection.js +251 -0
  198. package/dist/sdk/refine/serverMethods.d.ts +3 -0
  199. package/dist/sdk/refine/serverMethods.js +20 -0
  200. package/dist/sdk/refine/service.d.ts +84 -0
  201. package/dist/sdk/refine/service.js +165 -0
  202. package/dist/sdk/refine/suite.d.ts +67 -0
  203. package/dist/sdk/refine/suite.js +174 -0
  204. package/dist/sdk/refine/trajectory.d.ts +9 -0
  205. package/dist/sdk/refine/trajectory.js +68 -0
  206. package/dist/sdk/refine/types.d.ts +77 -0
  207. package/dist/sdk/refine/types.js +10 -0
  208. package/dist/sdk/server/methods.d.ts +3 -0
  209. package/dist/sdk/server/methods.js +293 -0
  210. package/dist/sdk/server/params.d.ts +4 -0
  211. package/dist/sdk/server/params.js +11 -0
  212. package/dist/sdk/server/remote.d.ts +19 -0
  213. package/dist/sdk/server/remote.js +84 -0
  214. package/dist/sdk/server/rpc.d.ts +20 -0
  215. package/dist/sdk/server/rpc.js +102 -0
  216. package/dist/sdk/server/serve.d.ts +10 -0
  217. package/dist/sdk/server/serve.js +18 -0
  218. package/dist/sdk/sessions/approvals.d.ts +47 -0
  219. package/dist/sdk/sessions/approvals.js +119 -0
  220. package/dist/sdk/sessions/continuation.d.ts +48 -0
  221. package/dist/sdk/sessions/continuation.js +85 -0
  222. package/dist/sdk/sessions/contracts.d.ts +551 -0
  223. package/dist/sdk/sessions/contracts.js +338 -0
  224. package/dist/sdk/sessions/extensionUi.d.ts +19 -0
  225. package/dist/sdk/sessions/extensionUi.js +64 -0
  226. package/dist/sdk/sessions/history.d.ts +16 -0
  227. package/dist/sdk/sessions/history.js +68 -0
  228. package/dist/sdk/sessions/lineageJoin.d.ts +2 -0
  229. package/dist/sdk/sessions/lineageJoin.js +61 -0
  230. package/dist/sdk/sessions/planMode.d.ts +39 -0
  231. package/dist/sdk/sessions/planMode.js +93 -0
  232. package/dist/sdk/sessions/policy.d.ts +43 -0
  233. package/dist/sdk/sessions/policy.js +1 -0
  234. package/dist/sdk/sessions/pricing.d.ts +34 -0
  235. package/dist/sdk/sessions/pricing.js +40 -0
  236. package/dist/sdk/sessions/reasoningSummaries.d.ts +11 -0
  237. package/dist/sdk/sessions/reasoningSummaries.js +61 -0
  238. package/dist/sdk/sessions/registry.d.ts +103 -0
  239. package/dist/sdk/sessions/registry.js +386 -0
  240. package/dist/sdk/sessions/runIndex.d.ts +21 -0
  241. package/dist/sdk/sessions/runIndex.js +65 -0
  242. package/dist/sdk/sessions/runStore.d.ts +66 -0
  243. package/dist/sdk/sessions/runStore.js +337 -0
  244. package/dist/sdk/sessions/runner.d.ts +213 -0
  245. package/dist/sdk/sessions/runner.js +589 -0
  246. package/dist/sdk/sessions/sessions.d.ts +152 -0
  247. package/dist/sdk/sessions/sessions.js +461 -0
  248. package/dist/sdk/sessions/sideQuestionServerMethods.d.ts +3 -0
  249. package/dist/sdk/sessions/sideQuestionServerMethods.js +19 -0
  250. package/dist/sdk/sessions/sideQuestions.d.ts +66 -0
  251. package/dist/sdk/sessions/sideQuestions.js +290 -0
  252. package/dist/sdk/sessions/subagentServerMethods.d.ts +3 -0
  253. package/dist/sdk/sessions/subagentServerMethods.js +41 -0
  254. package/dist/sdk/sessions/subagentService.d.ts +52 -0
  255. package/dist/sdk/sessions/subagentService.js +265 -0
  256. package/dist/sdk/sessions/subagents.d.ts +58 -0
  257. package/dist/sdk/sessions/subagents.js +87 -0
  258. package/dist/sdk/terminal/accountsMenu.d.ts +46 -0
  259. package/dist/sdk/terminal/accountsMenu.js +392 -0
  260. package/dist/sdk/terminal/browser.d.ts +62 -0
  261. package/dist/sdk/terminal/browser.js +41 -0
  262. package/dist/sdk/terminal/browserControl.d.ts +29 -0
  263. package/dist/sdk/terminal/browserControl.js +186 -0
  264. package/dist/sdk/terminal/cli.d.ts +20 -0
  265. package/dist/sdk/terminal/cli.js +121 -0
  266. package/dist/sdk/terminal/client.d.ts +15 -0
  267. package/dist/sdk/terminal/client.js +126 -0
  268. package/dist/sdk/terminal/commandHelp.d.ts +17 -0
  269. package/dist/sdk/terminal/commandHelp.js +20 -0
  270. package/dist/sdk/terminal/control.d.ts +4 -0
  271. package/dist/sdk/terminal/control.js +25 -0
  272. package/dist/sdk/terminal/controller.d.ts +78 -0
  273. package/dist/sdk/terminal/controller.js +383 -0
  274. package/dist/sdk/terminal/hubMenu.d.ts +10 -0
  275. package/dist/sdk/terminal/hubMenu.js +34 -0
  276. package/dist/sdk/terminal/launch.d.ts +5 -0
  277. package/dist/sdk/terminal/launch.js +27 -0
  278. package/dist/sdk/terminal/logs.d.ts +14 -0
  279. package/dist/sdk/terminal/logs.js +59 -0
  280. package/dist/sdk/terminal/opentui/subagentsWidget.d.ts +28 -0
  281. package/dist/sdk/terminal/opentui/subagentsWidget.js +52 -0
  282. package/dist/sdk/terminal/piExtension.d.ts +6 -0
  283. package/dist/sdk/terminal/piExtension.js +377 -0
  284. package/dist/sdk/terminal/pluginMenu.d.ts +34 -0
  285. package/dist/sdk/terminal/pluginMenu.js +101 -0
  286. package/dist/sdk/terminal/socket.d.ts +73 -0
  287. package/dist/sdk/terminal/socket.js +287 -0
  288. package/dist/sdk/terminal/standalone.d.ts +20 -0
  289. package/dist/sdk/terminal/standalone.js +186 -0
  290. package/dist/sdk/terminal/subagentMonitor.d.ts +38 -0
  291. package/dist/sdk/terminal/subagentMonitor.js +121 -0
  292. package/dist/sdk/terminal/terminals.d.ts +212 -0
  293. package/dist/sdk/terminal/terminals.js +1108 -0
  294. package/dist/sdk/terminal/trajectory.d.ts +10 -0
  295. package/dist/sdk/terminal/trajectory.js +30 -0
  296. package/dist/sdk/terminal/tui/annotateCommand.d.ts +3 -0
  297. package/dist/sdk/terminal/tui/annotateCommand.js +22 -0
  298. package/dist/sdk/terminal/tui/chrome.d.ts +64 -0
  299. package/dist/sdk/terminal/tui/chrome.js +169 -0
  300. package/dist/sdk/terminal/tui/clipboardFiles.d.ts +11 -0
  301. package/dist/sdk/terminal/tui/clipboardFiles.js +74 -0
  302. package/dist/sdk/terminal/tui/commandPages.d.ts +11 -0
  303. package/dist/sdk/terminal/tui/commandPages.js +111 -0
  304. package/dist/sdk/terminal/tui/commands.d.ts +46 -0
  305. package/dist/sdk/terminal/tui/commands.js +399 -0
  306. package/dist/sdk/terminal/tui/dialogGeometry.d.ts +27 -0
  307. package/dist/sdk/terminal/tui/dialogGeometry.js +52 -0
  308. package/dist/sdk/terminal/tui/dialogs.d.ts +80 -0
  309. package/dist/sdk/terminal/tui/dialogs.js +370 -0
  310. package/dist/sdk/terminal/tui/keybindings.d.ts +11 -0
  311. package/dist/sdk/terminal/tui/keybindings.js +49 -0
  312. package/dist/sdk/terminal/tui/list.d.ts +73 -0
  313. package/dist/sdk/terminal/tui/list.js +196 -0
  314. package/dist/sdk/terminal/tui/modeChoices.d.ts +42 -0
  315. package/dist/sdk/terminal/tui/modeChoices.js +70 -0
  316. package/dist/sdk/terminal/tui/modelPicker.d.ts +55 -0
  317. package/dist/sdk/terminal/tui/modelPicker.js +150 -0
  318. package/dist/sdk/terminal/tui/mouse.d.ts +3 -0
  319. package/dist/sdk/terminal/tui/mouse.js +3 -0
  320. package/dist/sdk/terminal/tui/page.d.ts +17 -0
  321. package/dist/sdk/terminal/tui/page.js +1 -0
  322. package/dist/sdk/terminal/tui/pageOverlay.d.ts +27 -0
  323. package/dist/sdk/terminal/tui/pageOverlay.js +156 -0
  324. package/dist/sdk/terminal/tui/pages/accountsPage.d.ts +76 -0
  325. package/dist/sdk/terminal/tui/pages/accountsPage.js +409 -0
  326. package/dist/sdk/terminal/tui/pages/agentsPage.d.ts +74 -0
  327. package/dist/sdk/terminal/tui/pages/agentsPage.js +190 -0
  328. package/dist/sdk/terminal/tui/pages/annotatePage.d.ts +94 -0
  329. package/dist/sdk/terminal/tui/pages/annotatePage.js +341 -0
  330. package/dist/sdk/terminal/tui/pages/browserPage.d.ts +87 -0
  331. package/dist/sdk/terminal/tui/pages/browserPage.js +738 -0
  332. package/dist/sdk/terminal/tui/pages/componentsPage.d.ts +47 -0
  333. package/dist/sdk/terminal/tui/pages/componentsPage.js +119 -0
  334. package/dist/sdk/terminal/tui/pages/doctorPage.d.ts +39 -0
  335. package/dist/sdk/terminal/tui/pages/doctorPage.js +233 -0
  336. package/dist/sdk/terminal/tui/pages/hubPage.d.ts +39 -0
  337. package/dist/sdk/terminal/tui/pages/hubPage.js +128 -0
  338. package/dist/sdk/terminal/tui/pages/logPage.d.ts +38 -0
  339. package/dist/sdk/terminal/tui/pages/logPage.js +189 -0
  340. package/dist/sdk/terminal/tui/pages/notesPage.d.ts +75 -0
  341. package/dist/sdk/terminal/tui/pages/notesPage.js +201 -0
  342. package/dist/sdk/terminal/tui/pages/permissionsPage.d.ts +44 -0
  343. package/dist/sdk/terminal/tui/pages/permissionsPage.js +124 -0
  344. package/dist/sdk/terminal/tui/pages/pluginsPage.d.ts +57 -0
  345. package/dist/sdk/terminal/tui/pages/pluginsPage.js +243 -0
  346. package/dist/sdk/terminal/tui/pages/settingsPage.d.ts +63 -0
  347. package/dist/sdk/terminal/tui/pages/settingsPage.js +103 -0
  348. package/dist/sdk/terminal/tui/pages/subagentsPage.d.ts +23 -0
  349. package/dist/sdk/terminal/tui/pages/subagentsPage.js +70 -0
  350. package/dist/sdk/terminal/tui/pages/trajectoryPage.d.ts +65 -0
  351. package/dist/sdk/terminal/tui/pages/trajectoryPage.js +450 -0
  352. package/dist/sdk/terminal/tui/pages/worktreesPage.d.ts +72 -0
  353. package/dist/sdk/terminal/tui/pages/worktreesPage.js +203 -0
  354. package/dist/sdk/terminal/tui/piAdapter.d.ts +18 -0
  355. package/dist/sdk/terminal/tui/piAdapter.js +48 -0
  356. package/dist/sdk/terminal/tui/planMode.d.ts +2 -0
  357. package/dist/sdk/terminal/tui/planMode.js +2 -0
  358. package/dist/sdk/terminal/tui/pluginCommands.d.ts +14 -0
  359. package/dist/sdk/terminal/tui/pluginCommands.js +27 -0
  360. package/dist/sdk/terminal/tui/questionPicker.d.ts +20 -0
  361. package/dist/sdk/terminal/tui/questionPicker.js +150 -0
  362. package/dist/sdk/terminal/tui/questions.d.ts +21 -0
  363. package/dist/sdk/terminal/tui/questions.js +42 -0
  364. package/dist/sdk/terminal/tui/runtime.d.ts +114 -0
  365. package/dist/sdk/terminal/tui/runtime.js +443 -0
  366. package/dist/sdk/terminal/tui/search.d.ts +22 -0
  367. package/dist/sdk/terminal/tui/search.js +60 -0
  368. package/dist/sdk/terminal/tui/selection.d.ts +16 -0
  369. package/dist/sdk/terminal/tui/selection.js +16 -0
  370. package/dist/sdk/terminal/tui/sessionUi.d.ts +3 -0
  371. package/dist/sdk/terminal/tui/sessionUi.js +30 -0
  372. package/dist/sdk/terminal/tui/settingsModel.d.ts +14 -0
  373. package/dist/sdk/terminal/tui/settingsModel.js +114 -0
  374. package/dist/sdk/terminal/tui/sideQuestion.d.ts +53 -0
  375. package/dist/sdk/terminal/tui/sideQuestion.js +230 -0
  376. package/dist/sdk/terminal/tui/skillInvocation.d.ts +9 -0
  377. package/dist/sdk/terminal/tui/skillInvocation.js +43 -0
  378. package/dist/sdk/terminal/tui/status.d.ts +18 -0
  379. package/dist/sdk/terminal/tui/status.js +67 -0
  380. package/dist/sdk/terminal/tui/theme.d.ts +45 -0
  381. package/dist/sdk/terminal/tui/theme.js +176 -0
  382. package/dist/sdk/terminal/tui/treeModel.d.ts +79 -0
  383. package/dist/sdk/terminal/tui/treeModel.js +483 -0
  384. package/dist/sdk/terminal/tui/treePicker.d.ts +49 -0
  385. package/dist/sdk/terminal/tui/treePicker.js +251 -0
  386. package/dist/sdk/terminal/tui/ui.d.ts +49 -0
  387. package/dist/sdk/terminal/tui/ui.js +149 -0
  388. package/dist/sdk/terminal/tui/workingStatus.d.ts +9 -0
  389. package/dist/sdk/terminal/tui/workingStatus.js +229 -0
  390. package/dist/sdk/tools/askUser.d.ts +6 -0
  391. package/dist/sdk/tools/askUser.js +92 -0
  392. package/dist/sdk/tools/checklist.d.ts +9 -0
  393. package/dist/sdk/tools/checklist.js +54 -0
  394. package/dist/sdk/tools/definitions.d.ts +30 -0
  395. package/dist/sdk/tools/definitions.js +117 -0
  396. package/dist/sdk/tools/dispatch.d.ts +16 -0
  397. package/dist/sdk/tools/dispatch.js +67 -0
  398. package/dist/sdk/tools/harnessTools.d.ts +8 -0
  399. package/dist/sdk/tools/harnessTools.js +20 -0
  400. package/dist/sdk/tools/sessionName.d.ts +7 -0
  401. package/dist/sdk/tools/sessionName.js +31 -0
  402. package/dist/sdk/tools/spawnSubagent.d.ts +4 -0
  403. package/dist/sdk/tools/spawnSubagent.js +58 -0
  404. package/dist/sdk/tools/types.d.ts +48 -0
  405. package/dist/sdk/tools/types.js +1 -0
  406. package/dist/sdk/variant/components.d.ts +34 -0
  407. package/dist/sdk/variant/components.js +230 -0
  408. package/dist/sdk/variant/materialise.d.ts +66 -0
  409. package/dist/sdk/variant/materialise.js +81 -0
  410. package/dist/sdk/variant/migrate.d.ts +4 -0
  411. package/dist/sdk/variant/migrate.js +41 -0
  412. package/dist/sdk/variant/seed.d.ts +20 -0
  413. package/dist/sdk/variant/seed.js +116 -0
  414. package/dist/sdk/variant/store.d.ts +82 -0
  415. package/dist/sdk/variant/store.js +151 -0
  416. package/dist/sdk/variant/surface.d.ts +56 -0
  417. package/dist/sdk/variant/surface.js +81 -0
  418. package/dist/sdk/variant/trust.d.ts +27 -0
  419. package/dist/sdk/variant/trust.js +64 -0
  420. package/dist/sdk/variant/variant.d.ts +71 -0
  421. package/dist/sdk/variant/variant.js +331 -0
  422. package/dist/sdk/web/markdown.d.ts +10 -0
  423. package/dist/sdk/web/markdown.js +66 -0
  424. package/dist/sdk/web/part.d.ts +10 -0
  425. package/dist/sdk/web/part.js +6 -0
  426. package/dist/sdk/web/safeRequest.d.ts +34 -0
  427. package/dist/sdk/web/safeRequest.js +175 -0
  428. package/dist/sdk/web/search.d.ts +53 -0
  429. package/dist/sdk/web/search.js +168 -0
  430. package/dist/sdk/web/serverMethods.d.ts +3 -0
  431. package/dist/sdk/web/serverMethods.js +7 -0
  432. package/dist/sdk/web/text.d.ts +2 -0
  433. package/dist/sdk/web/text.js +7 -0
  434. package/dist/sdk/web/tools.d.ts +22 -0
  435. package/dist/sdk/web/tools.js +195 -0
  436. package/dist/sdk/web/turndown-plugin-gfm.d.ts +4 -0
  437. package/dist/sdk/wiki/notes.d.ts +68 -0
  438. package/dist/sdk/wiki/notes.js +297 -0
  439. package/dist/sdk/wiki/serverMethods.d.ts +3 -0
  440. package/dist/sdk/wiki/serverMethods.js +26 -0
  441. package/dist/sdk/worktrees/cli.d.ts +11 -0
  442. package/dist/sdk/worktrees/cli.js +146 -0
  443. package/dist/sdk/worktrees/copy.d.ts +9 -0
  444. package/dist/sdk/worktrees/copy.js +111 -0
  445. package/dist/sdk/worktrees/git.d.ts +16 -0
  446. package/dist/sdk/worktrees/git.js +81 -0
  447. package/dist/sdk/worktrees/serverMethods.d.ts +3 -0
  448. package/dist/sdk/worktrees/serverMethods.js +30 -0
  449. package/dist/sdk/worktrees/service.d.ts +73 -0
  450. package/dist/sdk/worktrees/service.js +483 -0
  451. package/dist/sdk/worktrees/setup.d.ts +23 -0
  452. package/dist/sdk/worktrees/setup.js +65 -0
  453. package/dist/sdk/worktrees/types.d.ts +91 -0
  454. package/dist/sdk/worktrees/types.js +1 -0
  455. package/dist/sdk/world/actions.d.ts +23 -0
  456. package/dist/sdk/world/actions.js +31 -0
  457. package/dist/sdk/world/cli.d.ts +12 -0
  458. package/dist/sdk/world/cli.js +166 -0
  459. package/dist/sdk/world/images.d.ts +20 -0
  460. package/dist/sdk/world/images.js +48 -0
  461. package/dist/sdk/world/untrusted.d.ts +12 -0
  462. package/dist/sdk/world/untrusted.js +20 -0
  463. package/dist/sdk/world/world.d.ts +67 -0
  464. package/dist/sdk/world/world.js +79 -0
  465. package/dist/terminal-opentui.js +20778 -0
  466. package/dist/terminal-pi.js +794 -518
  467. package/docs/README.md +42 -0
  468. package/docs/architecture/00-overview.md +171 -0
  469. package/docs/architecture/01-extension-points.md +78 -0
  470. package/docs/architecture/02-sessions-and-runs.md +203 -0
  471. package/docs/architecture/03-variants.md +103 -0
  472. package/docs/architecture/04-prompt.md +122 -0
  473. package/docs/architecture/05-refinement.md +107 -0
  474. package/docs/architecture/06-plugins-and-capabilities.md +129 -0
  475. package/docs/architecture/07-tools-and-gate.md +103 -0
  476. package/docs/architecture/08-memory-and-history.md +94 -0
  477. package/docs/architecture/09-accounts-and-connectors.md +98 -0
  478. package/docs/architecture/10-server-protocol.md +193 -0
  479. package/docs/architecture/11-terminal.md +261 -0
  480. package/docs/architecture/12-storage.md +75 -0
  481. package/docs/architecture/13-world-tools.md +45 -0
  482. package/docs/architecture/14-surfaces-and-parity.md +89 -0
  483. package/docs/architecture/README.md +125 -0
  484. package/docs/architecture/proposals/PROP-0001-reporting-section.md +106 -0
  485. package/docs/architecture/proposals/PROP-0002-retain-rollout-workspaces.md +104 -0
  486. package/docs/architecture/proposals/PROP-0003-executor-settings.md +81 -0
  487. package/docs/architecture/proposals/PROP-0004-flexible-reporting-guidance.md +71 -0
  488. package/docs/architecture/proposals/PROP-0005-xharness-cli-name.md +78 -0
  489. package/docs/architecture/proposals/PROP-0006-run-checklist.md +70 -0
  490. package/docs/architecture/proposals/PROP-0007-run-continuation.md +80 -0
  491. package/docs/architecture/proposals/PROP-0008-lessons-from-runs.md +80 -0
  492. package/docs/architecture/proposals/PROP-0009-foundation-and-variants.md +78 -0
  493. package/docs/architecture/proposals/PROP-0010-session-names.md +73 -0
  494. package/docs/architecture/proposals/PROP-0011-doctor.md +63 -0
  495. package/docs/architecture/proposals/PROP-0012-release-baseline.md +56 -0
  496. package/docs/architecture/proposals/PROP-0013-resource-browser.md +58 -0
  497. package/docs/architecture/proposals/PROP-0014-fullscreen-browser-tabs.md +58 -0
  498. package/docs/architecture/proposals/PROP-0015-one-capability-surface.md +88 -0
  499. package/docs/architecture/proposals/PROP-0016-managed-worktrees.md +156 -0
  500. package/docs/architecture/proposals/PROP-0017-page-annotations.md +127 -0
  501. package/docs/architecture/proposals/PROP-0018-annotation-queue-and-app-targets.md +179 -0
  502. package/docs/architecture/proposals/PROP-0019-contextual-side-questions.md +122 -0
  503. package/docs/architecture/proposals/PROP-0020-builtin-feature-plugins.md +105 -0
  504. package/docs/architecture/proposals/PROP-0021-command-namespaces-and-duplicates.md +99 -0
  505. package/docs/architecture/proposals/PROP-0022-plan-only-questions.md +102 -0
  506. package/docs/architecture/proposals/PROP-0023-xagent-cli-name.md +61 -0
  507. package/docs/architecture/proposals/PROP-0024-question-sketch-previews.md +130 -0
  508. package/docs/architecture/proposals/PROP-0025-contextual-question-wireframes.md +49 -0
  509. package/docs/architecture/proposals/PROP-0026-connected-sketch-display.md +94 -0
  510. package/docs/architecture/proposals/PROP-0027-xingular-agent-product-identity.md +60 -0
  511. package/docs/architecture/proposals/PROP-0028-normalize-question-wireframes.md +55 -0
  512. package/docs/architecture/proposals/PROP-0029-agent-profiles.md +124 -0
  513. package/docs/architecture/proposals/PROP-0030-subagent-title.md +86 -0
  514. package/docs/architecture/proposals/README.md +101 -0
  515. package/docs/decisions/ADR-0002-native-subagent-lifecycle.md +49 -0
  516. package/docs/decisions/ADR-0003-shared-asynchronous-subagents.md +70 -0
  517. package/docs/decisions/ADR-0004-fullscreen-terminal-layout.md +50 -0
  518. package/docs/decisions/ADR-0005-app-provided-oauth-clients.md +54 -0
  519. package/docs/decisions/ADR-0006-opentui-only-terminal.md +47 -0
  520. package/docs/decisions/ADR-0007-reporting-section.md +33 -0
  521. package/docs/decisions/ADR-0008-flexible-reporting-guidance.md +38 -0
  522. package/docs/decisions/ADR-0009-xharness-command.md +39 -0
  523. package/docs/decisions/ADR-0010-lessons-in-the-wiki.md +31 -0
  524. package/docs/decisions/ADR-0011-foundation-and-variants.md +28 -0
  525. package/docs/decisions/ADR-0012-native-session-names.md +34 -0
  526. package/docs/decisions/ADR-0013-doctor.md +27 -0
  527. package/docs/decisions/ADR-0014-public-release-baseline.md +22 -0
  528. package/docs/decisions/ADR-0015-resource-browser.md +28 -0
  529. package/docs/decisions/ADR-0016-fullscreen-browser-tabs.md +31 -0
  530. package/docs/decisions/ADR-0017-one-capability-surface.md +34 -0
  531. package/docs/decisions/ADR-0018-builtin-feature-plugins.md +35 -0
  532. package/docs/decisions/ADR-0019-managed-git-worktrees.md +31 -0
  533. package/docs/decisions/ADR-0020-page-annotations.md +37 -0
  534. package/docs/decisions/ADR-0021-required-command-namespaces.md +40 -0
  535. package/docs/decisions/ADR-0022-plan-only-question-tools.md +34 -0
  536. package/docs/decisions/ADR-0023-contextual-side-question-runs.md +35 -0
  537. package/docs/decisions/ADR-0024-xagent-command.md +40 -0
  538. package/docs/decisions/ADR-0025-question-choice-sketches.md +49 -0
  539. package/docs/decisions/ADR-0026-contextual-question-wireframes.md +58 -0
  540. package/docs/decisions/ADR-0027-connected-sketch-display.md +60 -0
  541. package/docs/decisions/ADR-0028-xingular-agent-product-identity.md +56 -0
  542. package/docs/decisions/ADR-0029-normalized-question-wireframe-borders.md +33 -0
  543. package/docs/decisions/ADR-0030-agent-profiles.md +43 -0
  544. package/docs/doctor.md +80 -0
  545. package/docs/experiments/EXP-0001-terminal-input-latency/plan.md +81 -0
  546. package/docs/experiments/EXP-0001-terminal-input-latency/results.md +46 -0
  547. package/docs/experiments/EXP-0002-opentui-typing-latency/plan.md +70 -0
  548. package/docs/experiments/EXP-0002-opentui-typing-latency/results.md +92 -0
  549. package/docs/features/README.md +46 -0
  550. package/docs/features/automations/README.md +41 -0
  551. package/docs/features/cores/README.md +39 -0
  552. package/docs/features/google-harness2/README.md +52 -0
  553. package/docs/features/integrations/README.md +40 -0
  554. package/docs/features/interfaces/README.md +29 -0
  555. package/docs/features/memory/README.md +28 -0
  556. package/docs/future-work.md +48 -0
  557. package/docs/parity.md +78 -0
  558. package/docs/releases/1.0.0.md +40 -0
  559. package/docs/releases/4.0.0.md +46 -0
  560. package/docs/releases/README.md +41 -0
  561. package/docs/study/00-index.md +83 -0
  562. package/docs/study/arms/00-matrix.md +20 -0
  563. package/docs/study/arms/01-system-prompt.md +211 -0
  564. package/docs/study/arms/02-tools.md +79 -0
  565. package/docs/study/arms/03-subagents.md +90 -0
  566. package/docs/study/arms/04-skills.md +75 -0
  567. package/docs/study/arms/05-context-management.md +90 -0
  568. package/docs/study/arms/06-memory.md +90 -0
  569. package/docs/study/arms/07-governance.md +71 -0
  570. package/docs/study/arms/08-execution.md +69 -0
  571. package/docs/study/arms/09-observability.md +60 -0
  572. package/docs/study/arms/10-refinement.md +110 -0
  573. package/docs/study/autonomous-engineering-sources.md +277 -0
  574. package/docs/study/autonomy-sources.md +147 -0
  575. package/docs/study/btw-comparison.md +37 -0
  576. package/docs/study/feature-gap-review.md +42 -0
  577. package/docs/study/insights.md +123 -0
  578. package/docs/study/proactive-autonomy.md +408 -0
  579. package/docs/study/roadmap.md +72 -0
  580. package/docs/study/sources/claude-code.md +44 -0
  581. package/docs/study/sources/deepseek-harness.md +102 -0
  582. package/docs/study/sources/harness2.md +50 -0
  583. package/docs/study/sources/kimi-cli.md +42 -0
  584. package/docs/study/sources/omp.md +93 -0
  585. package/docs/study/sources/opencode.md +43 -0
  586. package/docs/study/sources/openhands.md +46 -0
  587. package/docs/study/sources/smolagents.md +40 -0
  588. package/docs/study/sources/swe-agent.md +34 -0
  589. package/docs/study/tui-resource-browser.md +78 -0
  590. package/docs/system-prompt-design.md +196 -0
  591. package/docs/terminal-tui.md +707 -58
  592. package/package.json +43 -13
  593. package/docs/evidence/terminal-2026-10-17/120x40-completed-transcript.ansi.gz +0 -0
  594. package/docs/evidence/terminal-2026-10-17/40x20-settings-interaction.ansi.gz +0 -0
  595. package/docs/evidence/terminal-2026-10-17/40x20-settings-keyboard.ansi.gz +0 -0
  596. package/docs/evidence/terminal-2026-10-17/40x20-welcome.ansi.gz +0 -0
  597. package/docs/evidence/terminal-2026-10-17/80x24-approval-0.ansi.gz +0 -0
  598. package/docs/evidence/terminal-2026-10-17/80x24-question.ansi.gz +0 -0
  599. package/docs/evidence/terminal-2026-10-17/verification.json +0 -130
  600. package/docs/evidence/terminal-2026-10-17-followup/120x40-completed-transcript.ansi.gz +0 -0
  601. package/docs/evidence/terminal-2026-10-17-followup/40x20-settings-interaction.ansi.gz +0 -0
  602. package/docs/evidence/terminal-2026-10-17-followup/40x20-settings-keyboard.ansi.gz +0 -0
  603. package/docs/evidence/terminal-2026-10-17-followup/40x20-welcome.ansi.gz +0 -0
  604. package/docs/evidence/terminal-2026-10-17-followup/80x24-approval-0.ansi.gz +0 -0
  605. package/docs/evidence/terminal-2026-10-17-followup/80x24-plugin-light.ansi.gz +0 -0
  606. package/docs/evidence/terminal-2026-10-17-followup/80x24-question-batch.ansi.gz +0 -0
  607. package/docs/evidence/terminal-2026-10-17-followup/80x24-question.ansi.gz +0 -0
  608. package/docs/evidence/terminal-2026-10-17-followup/app-bundle/80x24-approval-0.ansi.gz +0 -0
  609. package/docs/evidence/terminal-2026-10-17-followup/app-bundle/80x24-plugin-light.ansi.gz +0 -0
  610. package/docs/evidence/terminal-2026-10-17-followup/app-bundle/80x24-question-batch.ansi.gz +0 -0
  611. package/docs/evidence/terminal-2026-10-17-followup/app-bundle/80x24-question.ansi.gz +0 -0
  612. package/docs/evidence/terminal-2026-10-17-followup/app-bundle/verification.json +0 -95
  613. package/docs/evidence/terminal-2026-10-17-followup/global-install/80x24-approval-0.ansi.gz +0 -0
  614. package/docs/evidence/terminal-2026-10-17-followup/global-install/80x24-plugin-light.ansi.gz +0 -0
  615. package/docs/evidence/terminal-2026-10-17-followup/global-install/80x24-question-batch.ansi.gz +0 -0
  616. package/docs/evidence/terminal-2026-10-17-followup/global-install/80x24-question.ansi.gz +0 -0
  617. package/docs/evidence/terminal-2026-10-17-followup/global-install/README.md +0 -27
  618. package/docs/evidence/terminal-2026-10-17-followup/global-install/shell-command-80x24.ansi.gz +0 -0
  619. package/docs/evidence/terminal-2026-10-17-followup/global-install/shell-command.json +0 -18
  620. package/docs/evidence/terminal-2026-10-17-followup/global-install/verification.json +0 -95
  621. package/docs/evidence/terminal-2026-10-17-followup/harness-reference-80x24.json.gz +0 -0
  622. package/docs/evidence/terminal-2026-10-17-followup/harness-reference-final-80x24.json.gz +0 -0
  623. package/docs/evidence/terminal-2026-10-17-followup/harness-reference-scenario.json +0 -60
  624. package/docs/evidence/terminal-2026-10-17-followup/live-codex/README.md +0 -24
  625. package/docs/evidence/terminal-2026-10-17-followup/live-codex/complete-80x24.ansi.gz +0 -0
  626. package/docs/evidence/terminal-2026-10-17-followup/live-codex/verification.json +0 -57
  627. package/docs/evidence/terminal-2026-10-17-followup/omp-reference-80x24-early.json.gz +0 -0
  628. package/docs/evidence/terminal-2026-10-17-followup/omp-reference-80x24.json.gz +0 -0
  629. package/docs/evidence/terminal-2026-10-17-followup/omp-reference-scenario.json +0 -58
  630. package/docs/evidence/terminal-2026-10-17-followup/omp-supplemental-static.json.gz +0 -0
  631. package/docs/evidence/terminal-2026-10-17-followup/rea-artifacts.json +0 -320
  632. package/docs/evidence/terminal-2026-10-17-followup/reference-comparison.json +0 -30
  633. package/docs/evidence/terminal-2026-10-17-followup/reference-comparison.md +0 -133
  634. package/docs/evidence/terminal-2026-10-17-followup/reference-source-observations.json +0 -20
  635. package/docs/evidence/terminal-2026-10-17-followup/verification.json +0 -207
  636. package/src/accounts/accounts.test.ts +0 -333
  637. package/src/accounts/accounts.ts +0 -658
  638. package/src/accounts/env.test.ts +0 -95
  639. package/src/accounts/env.ts +0 -338
  640. package/src/accounts/secrets.ts +0 -50
  641. package/src/accounts/store.ts +0 -338
  642. package/src/capabilities/api.ts +0 -75
  643. package/src/capabilities/runSnapshot.ts +0 -59
  644. package/src/capabilities/types.ts +0 -34
  645. package/src/cli.ts +0 -118
  646. package/src/core/bus.ts +0 -34
  647. package/src/core/changes.ts +0 -33
  648. package/src/core/env.ts +0 -27
  649. package/src/core/errors.ts +0 -32
  650. package/src/core/frontmatter.ts +0 -47
  651. package/src/core/fs.test.ts +0 -38
  652. package/src/core/fs.ts +0 -92
  653. package/src/core/index.ts +0 -193
  654. package/src/core/path.test.ts +0 -14
  655. package/src/core/path.ts +0 -79
  656. package/src/core/projects.ts +0 -90
  657. package/src/core/text.ts +0 -39
  658. package/src/harness.ts +0 -312
  659. package/src/hub/catalog.json +0 -123
  660. package/src/hub/cli.ts +0 -59
  661. package/src/hub/hub.test.ts +0 -205
  662. package/src/hub/hub.ts +0 -256
  663. package/src/hub/schema.ts +0 -81
  664. package/src/index.ts +0 -75
  665. package/src/mcp/connections.ts +0 -614
  666. package/src/mcp/manager.ts +0 -130
  667. package/src/mcp/oauth.ts +0 -195
  668. package/src/mcp/scopeMigration.test.ts +0 -79
  669. package/src/mcp/scopeMigration.ts +0 -204
  670. package/src/mcp/service.test.ts +0 -376
  671. package/src/mcp/service.ts +0 -549
  672. package/src/mcp/types.ts +0 -108
  673. package/src/memory/api.test.ts +0 -82
  674. package/src/memory/api.ts +0 -303
  675. package/src/memory/blocks.test.ts +0 -78
  676. package/src/memory/blocks.ts +0 -408
  677. package/src/memory/caller.ts +0 -69
  678. package/src/memory/curation.test.ts +0 -163
  679. package/src/memory/curation.ts +0 -64
  680. package/src/memory/dispatch.ts +0 -59
  681. package/src/memory/facts.test.ts +0 -41
  682. package/src/memory/facts.ts +0 -248
  683. package/src/memory/graph.ts +0 -103
  684. package/src/memory/health.test.ts +0 -130
  685. package/src/memory/health.ts +0 -74
  686. package/src/memory/maintainer.ts +0 -272
  687. package/src/memory/maintenance.test.ts +0 -176
  688. package/src/memory/maintenance.ts +0 -518
  689. package/src/memory/migrate.ts +0 -79
  690. package/src/memory/operations.ts +0 -150
  691. package/src/memory/proposals.test.ts +0 -168
  692. package/src/memory/proposals.ts +0 -584
  693. package/src/memory/recall.test.ts +0 -115
  694. package/src/memory/recall.ts +0 -278
  695. package/src/memory/references.ts +0 -77
  696. package/src/memory/runContext.ts +0 -93
  697. package/src/memory/secrets.ts +0 -6
  698. package/src/memory/store.test.ts +0 -66
  699. package/src/memory/store.ts +0 -385
  700. package/src/memory/wiki.test.ts +0 -47
  701. package/src/memory/wiki.ts +0 -422
  702. package/src/memory/wikiIndex.test.ts +0 -88
  703. package/src/memory/wikiIndex.ts +0 -116
  704. package/src/plugins/api.ts +0 -181
  705. package/src/plugins/attachments.test.ts +0 -84
  706. package/src/plugins/attachments.ts +0 -141
  707. package/src/plugins/builtin.ts +0 -82
  708. package/src/plugins/catalogue.test.ts +0 -254
  709. package/src/plugins/catalogue.ts +0 -251
  710. package/src/plugins/cli.ts +0 -184
  711. package/src/plugins/discover.ts +0 -151
  712. package/src/plugins/firstParty.test.ts +0 -143
  713. package/src/plugins/firstParty.ts +0 -129
  714. package/src/plugins/hooks.test.ts +0 -250
  715. package/src/plugins/hooks.ts +0 -239
  716. package/src/plugins/identity.ts +0 -37
  717. package/src/plugins/install.test.ts +0 -107
  718. package/src/plugins/install.ts +0 -106
  719. package/src/plugins/inventory.ts +0 -123
  720. package/src/plugins/manifest.ts +0 -76
  721. package/src/plugins/plugins.test.ts +0 -205
  722. package/src/plugins/plugins.ts +0 -189
  723. package/src/plugins/proposal.ts +0 -121
  724. package/src/plugins/runtime.test.ts +0 -40
  725. package/src/plugins/runtime.ts +0 -82
  726. package/src/plugins/trust.ts +0 -142
  727. package/src/plugins/types.ts +0 -149
  728. package/src/prompt/compile.test.ts +0 -261
  729. package/src/prompt/compile.ts +0 -732
  730. package/src/server/methods.ts +0 -349
  731. package/src/server/remote.ts +0 -77
  732. package/src/server/rpc.ts +0 -116
  733. package/src/server/serve.ts +0 -28
  734. package/src/server/server.test.ts +0 -174
  735. package/src/sessions/approvals.ts +0 -118
  736. package/src/sessions/contracts.ts +0 -336
  737. package/src/sessions/conversation.test.ts +0 -177
  738. package/src/sessions/extensionSession.test.ts +0 -74
  739. package/src/sessions/extensionUi.test.ts +0 -65
  740. package/src/sessions/extensionUi.ts +0 -102
  741. package/src/sessions/history.ts +0 -51
  742. package/src/sessions/lineageJoin.ts +0 -75
  743. package/src/sessions/policy.ts +0 -36
  744. package/src/sessions/pricing.ts +0 -60
  745. package/src/sessions/questionBatches.test.ts +0 -110
  746. package/src/sessions/reasoningSummaries.ts +0 -59
  747. package/src/sessions/registry.ts +0 -381
  748. package/src/sessions/runIndex.ts +0 -99
  749. package/src/sessions/runStore.test.ts +0 -152
  750. package/src/sessions/runStore.ts +0 -332
  751. package/src/sessions/runner.ts +0 -604
  752. package/src/sessions/runtimeResources.test.ts +0 -61
  753. package/src/sessions/sessions.test.ts +0 -549
  754. package/src/sessions/sessions.ts +0 -339
  755. package/src/skills/registry.test.ts +0 -104
  756. package/src/skills/registry.ts +0 -413
  757. package/src/terminal/accountsMenu.test.ts +0 -225
  758. package/src/terminal/accountsMenu.ts +0 -382
  759. package/src/terminal/cli.ts +0 -149
  760. package/src/terminal/client.ts +0 -74
  761. package/src/terminal/control.test.ts +0 -23
  762. package/src/terminal/control.ts +0 -23
  763. package/src/terminal/controller.ts +0 -291
  764. package/src/terminal/hubMenu.ts +0 -24
  765. package/src/terminal/launch.test.ts +0 -25
  766. package/src/terminal/launch.ts +0 -48
  767. package/src/terminal/piExtension.lifecycle.test.ts +0 -55
  768. package/src/terminal/piExtension.ts +0 -259
  769. package/src/terminal/pluginControl.test.ts +0 -146
  770. package/src/terminal/pluginMenu.ts +0 -112
  771. package/src/terminal/socket.test.ts +0 -71
  772. package/src/terminal/socket.ts +0 -232
  773. package/src/terminal/standalone.test.ts +0 -167
  774. package/src/terminal/standalone.ts +0 -153
  775. package/src/terminal/terminal.test.ts +0 -399
  776. package/src/terminal/terminals.ts +0 -553
  777. package/src/terminal/tui/application.test.ts +0 -114
  778. package/src/terminal/tui/application.ts +0 -491
  779. package/src/terminal/tui/commands.test.ts +0 -218
  780. package/src/terminal/tui/commands.ts +0 -361
  781. package/src/terminal/tui/dialogs.ts +0 -301
  782. package/src/terminal/tui/editor.test.ts +0 -84
  783. package/src/terminal/tui/editor.ts +0 -79
  784. package/src/terminal/tui/keybindings.test.ts +0 -22
  785. package/src/terminal/tui/keybindings.ts +0 -50
  786. package/src/terminal/tui/piAdapter.ts +0 -62
  787. package/src/terminal/tui/presentation.test.ts +0 -79
  788. package/src/terminal/tui/questions.test.ts +0 -41
  789. package/src/terminal/tui/questions.ts +0 -47
  790. package/src/terminal/tui/runtime.socket.test.ts +0 -104
  791. package/src/terminal/tui/runtime.test.ts +0 -215
  792. package/src/terminal/tui/runtime.ts +0 -388
  793. package/src/terminal/tui/sessionUi.ts +0 -24
  794. package/src/terminal/tui/settings.test.ts +0 -150
  795. package/src/terminal/tui/settings.ts +0 -188
  796. package/src/terminal/tui/status.test.ts +0 -70
  797. package/src/terminal/tui/status.ts +0 -109
  798. package/src/terminal/tui/theme.ts +0 -174
  799. package/src/terminal/tui/tools.test.ts +0 -145
  800. package/src/terminal/tui/tools.ts +0 -142
  801. package/src/terminal/tui/transcript.test.ts +0 -25
  802. package/src/terminal/tui/transcript.ts +0 -124
  803. package/src/terminal/tui/ui.test.ts +0 -313
  804. package/src/terminal/tui/ui.ts +0 -166
  805. package/src/terminal/tui/welcome.ts +0 -102
  806. package/src/tools/askUser.test.ts +0 -69
  807. package/src/tools/askUser.ts +0 -59
  808. package/src/tools/definitions.ts +0 -187
  809. package/src/tools/maintenance.ts +0 -24
  810. package/src/tools/memoryTools.ts +0 -22
  811. package/src/tools/pluginPropose.ts +0 -41
  812. package/src/tools/registryWrite.test.ts +0 -101
  813. package/src/tools/registryWrite.ts +0 -182
  814. package/src/tools/spawnSubagent.ts +0 -92
  815. package/src/tools/types.ts +0 -39
  816. package/src/web/safeRequest.ts +0 -171
  817. package/src/web/text.ts +0 -53
  818. package/src/web/tools.ts +0 -134
  819. package/src/web/web.test.ts +0 -141
@@ -1,658 +0,0 @@
1
- // The accounts service: everything that needs the secret store, the Pi runtime, or a notice.
2
- // Credentials go to the embedding application's secret store; nothing here writes one to the
3
- // harness's own files, except a terminal session's `auth.json` while that terminal runs.
4
- import { chmodSync, rmSync } from 'node:fs'
5
- import { randomUUID } from 'node:crypto'
6
- import { join } from 'node:path'
7
-
8
- import type { ModelRuntime } from '@earendil-works/pi-coding-agent'
9
-
10
- import { log, type Bus } from '../core/bus'
11
- import { HarnessError, invalid } from '../core/errors'
12
- import { atomicWrite, now, readJson, safeId } from '../core/fs'
13
- import type { RunEvent, RunRecord } from '../sessions/contracts'
14
- import * as env from './env'
15
- import { secretKey, type SecretStore } from './secrets'
16
- import * as store from './store'
17
- import type { Account, AccountsOverview, Issue, Limit } from './store'
18
-
19
- export type IssueCategory = 'auth_expired' | 'rate_limited' | 'quota' | 'network' | 'unknown'
20
-
21
- /** Best-effort classification of a provider error message. */
22
- export function classifyMessage(message: string): IssueCategory | null {
23
- const text = message.toLowerCase()
24
- if (/\b401\b|unauthori[sz]ed|invalid (api )?key|invalid x-api-key|authentication|not logged in|log ?in again|expired token|token (has )?expired|refresh token|oauth/.test(text)) return 'auth_expired'
25
- if (/usage limit|quota|insufficient_quota|billing|credit balance|out of credits/.test(text)) return 'quota'
26
- if (/\b429\b|rate.?limit|too many requests/.test(text)) return 'rate_limited'
27
- if (/econnrefused|enotfound|etimedout|network|socket hang up|fetch failed/.test(text)) return 'network'
28
- return null
29
- }
30
-
31
- export interface ModelOption {
32
- id: string
33
- name: string
34
- provider: string
35
- supportsImages: boolean
36
- reasoning: boolean
37
- }
38
-
39
- type Credential = Record<string, unknown> & { type: 'api_key' | 'oauth' }
40
-
41
- function validProvider(provider: string): string {
42
- if (provider && provider.length <= 64 && /^[A-Za-z0-9._-]+$/.test(provider)) return provider
43
- throw invalid('Invalid provider name.')
44
- }
45
-
46
- interface PendingLogin {
47
- accountId: string
48
- provider: string
49
- method: 'oauth' | 'api_key'
50
- cancel: () => void
51
- prompts: Map<string, { resolve: (value: string) => void; reject: (error: Error) => void }>
52
- revision: number
53
- events: Record<string, unknown>[]
54
- prompt: Record<string, unknown> | null
55
- }
56
-
57
- export interface AccountLoginSnapshot {
58
- accountId: string
59
- loginId: string
60
- provider: string
61
- method: string
62
- revision: number
63
- status: 'running' | 'completed' | 'failed' | 'cancelled'
64
- events: Record<string, unknown>[]
65
- prompt: Record<string, unknown> | null
66
- success: boolean | null
67
- error: string | null
68
- }
69
-
70
- interface Probe {
71
- signedIn: boolean | null
72
- authMethod: string | null
73
- plan: string | null
74
- identity: string | null
75
- limits?: Limit[]
76
- capabilities: string[]
77
- }
78
-
79
- export interface AccountsOptions {
80
- /** `<state dir>/accounts`. */
81
- dir: string
82
- secrets: SecretStore
83
- bus: Bus
84
- }
85
-
86
- export class Accounts {
87
- readonly dir: string
88
- private readonly secrets: SecretStore
89
- private readonly bus: Bus
90
- private readonly runtimes = new Map<string, Promise<ModelRuntime>>()
91
- private readonly logins = new Map<string, PendingLogin>()
92
- private readonly latestLogins = new Map<string, AccountLoginSnapshot>()
93
- private readonly terminals = new Map<string, number>()
94
- private installationDeviceIdPromise: Promise<string> | null = null
95
-
96
- constructor(options: AccountsOptions) {
97
- this.dir = options.dir
98
- this.secrets = options.secrets
99
- this.bus = options.bus
100
- }
101
-
102
- private changed(payload: Record<string, unknown> = {}): void {
103
- this.bus.emit({ type: 'accounts.changed', ...payload })
104
- }
105
-
106
- overview(): AccountsOverview {
107
- return store.overview(this.dir)
108
- }
109
-
110
- find(accountId: string): Account {
111
- return store.find(this.dir, accountId)
112
- }
113
-
114
- /** The account a new session uses; a session that already has one passes it and keeps it. */
115
- resolve(accountId?: string | null, poolId?: string | null): Account {
116
- return store.resolve(this.dir, accountId, poolId)
117
- }
118
-
119
- context(account: Account): env.AccountContext {
120
- return env.accountContext(this.dir, account)
121
- }
122
-
123
- // ---- Stored credentials -----------------------------------------------------------------
124
-
125
- async readCredential(accountId: string, provider: string): Promise<Credential | null> {
126
- this.find(accountId)
127
- const text = await this.secrets.get(secretKey(accountId, `pi-auth/${validProvider(provider)}`))
128
- if (!text) return null
129
- try {
130
- return JSON.parse(text) as Credential
131
- } catch {
132
- return null
133
- }
134
- }
135
-
136
- /** Stores a provider's credential, or removes it when `credential` is `null`. */
137
- async writeCredential(accountId: string, provider: string, credential: Credential | null): Promise<void> {
138
- this.find(accountId)
139
- const name = validProvider(provider)
140
- if (credential === null) await this.secrets.delete(secretKey(accountId, `pi-auth/${name}`))
141
- else await this.secrets.set(secretKey(accountId, `pi-auth/${name}`), JSON.stringify(credential))
142
- store.updateState(this.dir, accountId, (state) => {
143
- state.piProviders = state.piProviders.filter((existing) => existing !== name)
144
- if (credential !== null) state.piProviders = [...state.piProviders, name].sort()
145
- })
146
- }
147
-
148
- async listCredentials(accountId: string): Promise<{ providerId: string; type: 'api_key' | 'oauth' }[]> {
149
- this.find(accountId)
150
- const listed: { providerId: string; type: 'api_key' | 'oauth' }[] = []
151
- for (const provider of store.loadState(this.dir, accountId).piProviders) {
152
- const credential = await this.readCredential(accountId, provider).catch(() => null)
153
- if (credential && typeof credential.type === 'string') listed.push({ providerId: provider, type: credential.type })
154
- }
155
- return listed
156
- }
157
-
158
- /** Pi's `CredentialStore` for one account. Writes are serialized, so a refresh never races another. */
159
- private credentialStore(accountId: string) {
160
- let chain: Promise<unknown> = Promise.resolve()
161
- const serialize = <T>(work: () => Promise<T>): Promise<T> => {
162
- const next = chain.then(work)
163
- chain = next.catch(() => undefined)
164
- return next
165
- }
166
- return {
167
- read: async (providerId: string) => (await this.readCredential(accountId, providerId)) ?? undefined,
168
- list: () => this.listCredentials(accountId),
169
- modify: (providerId: string, change: (current: Credential | undefined) => Promise<Credential | undefined>) =>
170
- serialize(async () => {
171
- const current = (await this.readCredential(accountId, providerId)) ?? undefined
172
- const updated = await change(current)
173
- if (updated !== undefined) await this.writeCredential(accountId, providerId, updated)
174
- return updated ?? current
175
- }),
176
- delete: (providerId: string) => serialize(() => this.writeCredential(accountId, providerId, null))
177
- }
178
- }
179
-
180
- /** Pi's OAuth device ID belongs to this Harness installation, not to one isolated account. */
181
- installationDeviceId(): Promise<string> {
182
- if (!this.installationDeviceIdPromise) {
183
- this.installationDeviceIdPromise = this.loadInstallationDeviceId().catch((error: unknown) => {
184
- this.installationDeviceIdPromise = null
185
- throw error
186
- })
187
- }
188
- return this.installationDeviceIdPromise
189
- }
190
-
191
- private async loadInstallationDeviceId(): Promise<string> {
192
- const { SettingsManager } = await import('@earendil-works/pi-coding-agent')
193
- const settings = SettingsManager.create(process.cwd(), env.ensureSharedDir(this.dir))
194
- const deviceId = settings.getOrCreateDeviceId()
195
- await settings.flush()
196
- return deviceId
197
- }
198
-
199
- // ---- The Pi runtime ---------------------------------------------------------------------
200
-
201
- /** The lazily loaded Pi runtime of one account: its models and its credentials. Pi's own `~/.pi` is never used. */
202
- runtime(account: env.AccountContext | Account): Promise<ModelRuntime> {
203
- const id = account.id
204
- let runtime = this.runtimes.get(id)
205
- if (!runtime) {
206
- const configDir = 'configDir' in account ? account.configDir : env.ensureHome(this.dir, account)
207
- runtime = import('@earendil-works/pi-coding-agent')
208
- .then(({ ModelRuntime }) => ModelRuntime.create({ credentials: this.credentialStore(id) as never, modelsPath: join(configDir, 'models.json') }))
209
- .catch((error: unknown) => {
210
- this.runtimes.delete(id)
211
- throw error
212
- })
213
- this.runtimes.set(id, runtime)
214
- }
215
- return runtime
216
- }
217
-
218
- /** Drops a cached runtime after its credentials changed outside it (sign-in, key edits, terminal sessions). */
219
- invalidate(accountId: string): void {
220
- this.runtimes.delete(accountId)
221
- }
222
-
223
- async models(accountId?: string | null): Promise<ModelOption[]> {
224
- const account = accountId ? this.find(accountId) : store.defaultAccount(this.dir)
225
- if (!account) return []
226
- const available = await (await this.runtime(account)).getAvailable()
227
- return available.map((model) => ({ id: `${model.provider}/${model.id}`, name: model.name || model.id, provider: String(model.provider), supportsImages: model.input.includes('image'), reasoning: model.reasoning }))
228
- }
229
-
230
- /** Whether sessions can run, and why not. */
231
- async status(accountId?: string | null): Promise<{ available: boolean; reason: string | null; models: number }> {
232
- const account = accountId ? this.find(accountId) : store.defaultAccount(this.dir)
233
- if (!account) return { available: false, reason: 'Add a Pi account in Accounts to use Chat.', models: 0 }
234
- try {
235
- const models = await this.models(account.id)
236
- return models.length ? { available: true, reason: null, models: models.length } : { available: false, reason: `The Pi account "${account.label}" has no signed-in provider. Sign in or add a key in Accounts.`, models: 0 }
237
- } catch (error) {
238
- log('Pi runtime failed to load', error instanceof Error ? error.message : String(error))
239
- return { available: false, reason: 'The Pi SDK could not be loaded.', models: 0 }
240
- }
241
- }
242
-
243
- /** Providers Pi can sign in to (OAuth) or take a key for, independent of any account. */
244
- async providers(): Promise<{ id: string; name: string; oauth: boolean; oauthLabel: string | null; subscription: boolean; apiKey: boolean }[]> {
245
- const { ModelRuntime } = await import('@earendil-works/pi-coding-agent')
246
- const none = { read: async () => undefined, list: async () => [], modify: async () => undefined, delete: async () => undefined }
247
- const runtime = await ModelRuntime.create({ credentials: none, modelsPath: null, refreshOnCreate: false })
248
- return runtime
249
- .getProviders()
250
- .map((provider) => ({ id: provider.id, name: provider.name, oauth: Boolean(provider.auth.oauth), oauthLabel: provider.auth.oauth?.loginLabel ?? provider.auth.oauth?.name ?? null, subscription: Boolean(provider.auth.oauth?.isSubscription), apiKey: Boolean(provider.auth.apiKey?.login) }))
251
- .filter((provider) => provider.oauth || provider.apiKey)
252
- .sort((left, right) => left.name.localeCompare(right.name))
253
- }
254
-
255
- // ---- Status checks ----------------------------------------------------------------------
256
-
257
- private async probe(account: Account): Promise<Probe> {
258
- const runtime = await this.runtime(account)
259
- const credentials = await runtime.listCredentials()
260
- const available = await runtime.getAvailable()
261
- const subscription = credentials.filter((credential) => runtime.isUsingSubscription(credential.providerId)).map((credential) => credential.providerId)
262
- return {
263
- signedIn: credentials.length > 0 && available.length > 0,
264
- authMethod: [...new Set(credentials.map((credential) => credential.type))].join(', ') || null,
265
- plan: subscription.length ? `Subscription: ${subscription.join(', ')}` : null,
266
- identity: credentials.map((credential) => credential.providerId).join(', ') || null,
267
- capabilities: [`models:${available.length}`, ...credentials.map((credential) => `provider:${credential.providerId}`)]
268
- }
269
- }
270
-
271
- /** Checks one account and records what Pi reports. */
272
- async refreshOne(account: Account): Promise<void> {
273
- let probe: Probe | null = null
274
- let failure: string | null = null
275
- try {
276
- probe = await this.probe(account)
277
- } catch (error) {
278
- failure = error instanceof Error ? error.message : String(error)
279
- }
280
- const { previous, state } = store.updateState(this.dir, account.id, (current) => {
281
- current.lastCheckedAt = now()
282
- if (probe) {
283
- current.signedIn = probe.signedIn
284
- current.authMethod = probe.authMethod
285
- current.plan = probe.plan ?? current.plan
286
- current.identity = probe.identity
287
- if (probe.limits) current.limits = probe.limits
288
- current.capabilities = probe.capabilities
289
- const keepLimitError = current.lastError !== null && store.isLimitCategory(current.lastError.category) && store.limitErrorActive(current.lastError)
290
- if (probe.signedIn === true && !keepLimitError) current.lastError = null
291
- } else {
292
- current.lastError = { category: classifyMessage(failure ?? '') ?? 'unknown', message: store.scrub(failure ?? ''), at: now(), resetsAt: null }
293
- }
294
- })
295
- if (previous !== state.health) store.audit(this.dir, account.id, 'health.changed', `${previous} → ${state.health} (status check)`)
296
- this.changed({ accountId: account.id })
297
- }
298
-
299
- async refresh(accountId?: string | null): Promise<AccountsOverview> {
300
- const accounts = accountId ? [this.find(accountId)] : store.loadRegistry(this.dir).accounts.filter((account) => account.provider === store.PROVIDER)
301
- for (const account of accounts) await this.refreshOne(account)
302
- return this.overview()
303
- }
304
-
305
- // ---- Create, rename, remove -------------------------------------------------------------
306
-
307
- create(label: string, authKind: string): AccountsOverview {
308
- const account = store.addAccount(this.dir, label, authKind)
309
- env.ensureHome(this.dir, account)
310
- store.audit(this.dir, account.id, 'account.created', `Pi account "${account.label}" (${account.authKind})`)
311
- this.changed({ accountId: account.id })
312
- return this.overview()
313
- }
314
-
315
- rename(accountId: string, label: string): AccountsOverview {
316
- store.renameAccount(this.dir, accountId, label)
317
- store.audit(this.dir, accountId, 'account.renamed', store.cleanLabel(label))
318
- this.changed({ accountId })
319
- return this.overview()
320
- }
321
-
322
- setDefault(accountId: string): AccountsOverview {
323
- store.setDefault(this.dir, accountId)
324
- store.audit(this.dir, accountId, 'default.changed', 'Default Pi account for new sessions.')
325
- this.changed({ accountId })
326
- return this.overview()
327
- }
328
-
329
- private async forgetCredentials(account: Account): Promise<void> {
330
- for (const provider of store.loadState(this.dir, account.id).piProviders) await this.writeCredential(account.id, provider, null)
331
- this.invalidate(account.id)
332
- }
333
-
334
- /** Deletes the account: removes its stored credentials and its runtime folder. Sessions pinned to it ask for another account next time they start. */
335
- async remove(accountId: string): Promise<AccountsOverview> {
336
- const account = this.find(accountId)
337
- for (const login of this.logins.values()) if (login.accountId === accountId) login.cancel()
338
- this.latestLogins.delete(accountId)
339
- await this.forgetCredentials(account).catch(() => undefined)
340
- await this.secrets.delete(secretKey(account.id, 'apiKey')).catch(() => undefined)
341
- store.forgetAccount(this.dir, account)
342
- rmSync(join(this.dir, safeId(account.id)), { recursive: true, force: true })
343
- store.audit(this.dir, account.id, 'account.deleted', `"${account.label}" and its stored sign-in were removed.`)
344
- this.changed({ accountId: account.id })
345
- return this.overview()
346
- }
347
-
348
- savePool(pool: { id?: string; label: string; accountIds: string[] }): AccountsOverview {
349
- const saved = store.savePool(this.dir, pool)
350
- store.audit(this.dir, null, 'pool.saved', `${saved.label}: ${saved.accountIds.length} account(s)`)
351
- this.changed()
352
- return this.overview()
353
- }
354
-
355
- removePool(poolId: string): AccountsOverview {
356
- store.removePool(this.dir, poolId)
357
- store.audit(this.dir, null, 'pool.removed', poolId)
358
- this.changed()
359
- return this.overview()
360
- }
361
-
362
- // ---- Keys and sign-in -------------------------------------------------------------------
363
-
364
- async setApiKey(accountId: string, rawKey: string, provider: string): Promise<AccountsOverview> {
365
- const account = this.find(accountId)
366
- const key = rawKey.trim()
367
- if (!key || key.length > 4096 || /\s/.test(key)) throw invalid('Paste the key without spaces.')
368
- if (!provider) throw invalid('Choose which Pi provider the key is for.')
369
- await this.writeCredential(account.id, provider, { type: 'api_key', key })
370
- this.invalidate(account.id)
371
- store.audit(this.dir, account.id, 'key.set', 'Provider key stored in the Keychain.')
372
- await this.refreshOne(account)
373
- return this.overview()
374
- }
375
-
376
- async removeProvider(accountId: string, provider: string): Promise<AccountsOverview> {
377
- const account = this.find(accountId)
378
- await this.writeCredential(account.id, provider, null)
379
- this.invalidate(account.id)
380
- store.audit(this.dir, account.id, 'key.removed', provider)
381
- await this.refreshOne(account)
382
- return this.overview()
383
- }
384
-
385
- async signOut(accountId: string): Promise<AccountsOverview> {
386
- const account = this.find(accountId)
387
- await this.forgetCredentials(account)
388
- store.audit(this.dir, account.id, 'logout', 'Signed out; stored credentials removed.')
389
- store.updateState(this.dir, account.id, (current) => {
390
- current.signedIn = false
391
- current.identity = null
392
- current.lastError = null
393
- })
394
- this.changed({ accountId: account.id })
395
- return this.overview()
396
- }
397
-
398
- private finishLogin(loginId: string, success: boolean, error: string | null, cancelled = false): void {
399
- const login = this.logins.get(loginId)
400
- if (!login) return
401
- this.logins.delete(loginId)
402
- for (const prompt of login.prompts.values()) prompt.reject(new Error('Sign-in ended.'))
403
- if (success) this.invalidate(login.accountId)
404
- store.audit(this.dir, login.accountId, success ? 'login.completed' : 'login.failed', error ?? '')
405
- // A fresh sign-in starts clean; a limit that still applies is reported again by the next run.
406
- if (success) store.updateState(this.dir, login.accountId, (current) => void (current.lastError = null))
407
- login.revision += 1
408
- const status: AccountLoginSnapshot['status'] = success ? 'completed' : cancelled ? 'cancelled' : 'failed'
409
- if (this.latestLogins.get(login.accountId)?.loginId === loginId) {
410
- this.latestLogins.set(login.accountId, {
411
- accountId: login.accountId,
412
- loginId,
413
- provider: login.provider,
414
- method: login.method,
415
- revision: login.revision,
416
- status,
417
- // A terminal result is enough to reconcile the client. In particular, do not retain a
418
- // device code after the attempt ends.
419
- events: [],
420
- prompt: null,
421
- success,
422
- error
423
- })
424
- }
425
- this.bus.emit({ type: 'accounts.login', accountId: login.accountId, loginId, revision: login.revision, success, error })
426
- try {
427
- void this.refreshOne(this.find(login.accountId)).catch(() => undefined)
428
- } catch {
429
- // The account was removed while its sign-in was running.
430
- }
431
- }
432
-
433
- /**
434
- * Starts a provider's own sign-in for this account. Progress, links to open, and prompts
435
- * arrive as `accounts.loginEvent` notices; the outcome as `accounts.login`.
436
- */
437
- async loginStart(accountId: string, provider: string, method?: string | null): Promise<{ loginId: string }> {
438
- const account = this.find(accountId)
439
- if (!provider) throw invalid('Choose which Pi provider to sign in to.')
440
- store.audit(this.dir, account.id, 'login.started', `${method ?? 'oauth'} · ${provider}`)
441
- const loginId = randomUUID()
442
- const controller = new AbortController()
443
- const login: PendingLogin = {
444
- accountId: account.id,
445
- provider,
446
- method: method === 'api_key' ? 'api_key' : 'oauth',
447
- prompts: new Map(),
448
- cancel: () => controller.abort(),
449
- revision: 0,
450
- events: [],
451
- prompt: null
452
- }
453
- this.logins.set(loginId, login)
454
- this.latestLogins.set(account.id, {
455
- accountId: account.id,
456
- loginId,
457
- provider: login.provider,
458
- method: login.method,
459
- revision: 0,
460
- status: 'running',
461
- events: [],
462
- prompt: null,
463
- success: null,
464
- error: null
465
- })
466
- const event = (payload: Record<string, unknown>): void => {
467
- login.revision += 1
468
- if (payload.type === 'prompt') login.prompt = payload
469
- else if (payload.type === 'promptClosed' && login.prompt?.promptId === payload.promptId) login.prompt = null
470
- else {
471
- login.events.push(payload)
472
- if (login.events.length > 50) login.events.shift()
473
- }
474
- if (this.latestLogins.get(account.id)?.loginId === loginId) {
475
- this.latestLogins.set(account.id, {
476
- accountId: account.id,
477
- loginId,
478
- provider: login.provider,
479
- method: login.method,
480
- revision: login.revision,
481
- status: 'running',
482
- events: login.events.map((step) => ({ ...step })),
483
- prompt: login.prompt ? { ...login.prompt } : null,
484
- success: null,
485
- error: null
486
- })
487
- }
488
- this.bus.emit({ type: 'accounts.loginEvent', accountId: account.id, loginId, revision: login.revision, event: payload })
489
- }
490
- const interaction = {
491
- signal: controller.signal,
492
- notify: (notification: Record<string, unknown>) => event(notification),
493
- prompt: (prompt: { type: string; message: string; placeholder?: string; options?: unknown; signal?: AbortSignal }) =>
494
- new Promise<string>((resolve, reject) => {
495
- const promptId = randomUUID()
496
- login.prompts.set(promptId, { resolve, reject })
497
- prompt.signal?.addEventListener('abort', () => {
498
- login.prompts.delete(promptId)
499
- event({ type: 'promptClosed', promptId })
500
- reject(new Error('Prompt closed.'))
501
- })
502
- event({ type: 'prompt', promptId, prompt: { type: prompt.type, message: prompt.message, placeholder: prompt.placeholder ?? null, options: prompt.options ?? null } })
503
- })
504
- }
505
- void this.runtime(account)
506
- .then(async (runtime) => {
507
- if (login.method !== 'oauth') return runtime.login(provider, login.method, interaction as never)
508
- const deviceId = await this.installationDeviceId()
509
- return runtime.login(provider, login.method, interaction as never, { getDeviceId: () => deviceId })
510
- })
511
- .then(() => this.finishLogin(loginId, true, null))
512
- .catch((error: unknown) => this.finishLogin(
513
- loginId,
514
- false,
515
- controller.signal.aborted ? 'Sign-in was cancelled.' : error instanceof Error ? error.message : String(error),
516
- controller.signal.aborted
517
- ))
518
- return { loginId }
519
- }
520
-
521
- /** Current in-memory sign-in progress for one account; codes and prompts are never written to disk. */
522
- loginStatus(accountId: string): AccountLoginSnapshot | null {
523
- this.find(accountId)
524
- const snapshot = this.latestLogins.get(accountId)
525
- return snapshot ? structuredClone(snapshot) : null
526
- }
527
-
528
- loginRespond(loginId: string, promptId: string, value: string | null): void {
529
- const login = this.logins.get(loginId)
530
- const prompt = login?.prompts.get(promptId)
531
- if (!login || !prompt) throw new HarnessError('not_found', 'That sign-in step is no longer waiting.')
532
- login.prompts.delete(promptId)
533
- // The renderer's recoverable snapshot must stop presenting a prompt as soon as it is answered.
534
- const current = this.latestLogins.get(login.accountId)
535
- if (current?.loginId === loginId && current.prompt?.promptId === promptId) {
536
- login.prompt = null
537
- current.revision += 1
538
- login.revision = current.revision
539
- current.prompt = null
540
- this.latestLogins.set(login.accountId, current)
541
- this.bus.emit({ type: 'accounts.loginEvent', accountId: login.accountId, loginId, revision: current.revision, event: { type: 'promptClosed', promptId } })
542
- }
543
- if (value === null) prompt.reject(new Error('Cancelled.'))
544
- else prompt.resolve(value)
545
- }
546
-
547
- loginCancel(accountId: string, loginId?: string | null): void {
548
- if (loginId) {
549
- const login = this.logins.get(loginId)
550
- if (login?.accountId === accountId) login.cancel()
551
- } else for (const login of this.logins.values()) if (login.accountId === accountId) login.cancel()
552
- store.audit(this.dir, accountId, 'login.cancelled', '')
553
- }
554
-
555
- // ---- Terminal sessions --------------------------------------------------------------------
556
-
557
- /**
558
- * The `pi` command reads `auth.json` from its agent folder. For a terminal session the
559
- * account's stored credentials are written there (mode 0600) while the terminal runs, then
560
- * read back and removed.
561
- */
562
- /** How many terminal sessions are running on this account right now. */
563
- terminalCount(accountId: string): number {
564
- return this.terminals.get(accountId) ?? 0
565
- }
566
-
567
- async terminalBegin(account: Account): Promise<void> {
568
- const count = (this.terminals.get(account.id) ?? 0) + 1
569
- this.terminals.set(account.id, count)
570
- if (count > 1) return
571
- const path = join(env.configDir(this.dir, account), 'auth.json')
572
- try {
573
- const data: Record<string, unknown> = {}
574
- for (const provider of store.loadState(this.dir, account.id).piProviders) {
575
- const credential = await this.readCredential(account.id, provider).catch(() => null)
576
- if (credential) data[provider] = credential
577
- }
578
- atomicWrite(path, JSON.stringify(data, null, 2))
579
- chmodSync(path, 0o600)
580
- } catch (error) {
581
- this.terminals.delete(account.id)
582
- rmSync(path, { force: true })
583
- throw error
584
- }
585
- }
586
-
587
- async terminalEnd(account: Account): Promise<void> {
588
- const remaining = Math.max(0, (this.terminals.get(account.id) ?? 1) - 1)
589
- if (remaining > 0) {
590
- this.terminals.set(account.id, remaining)
591
- return
592
- }
593
- this.terminals.delete(account.id)
594
- const path = join(env.configDir(this.dir, account), 'auth.json')
595
- let data: Record<string, Credential> | null = null
596
- try {
597
- const parsed = readJson<Record<string, Credential>>(path)
598
- data = parsed && typeof parsed === 'object' && !Array.isArray(parsed) ? parsed : null
599
- } catch {
600
- data = null
601
- }
602
- if (data) {
603
- for (const provider of store.loadState(this.dir, account.id).piProviders) if (!(provider in data)) await this.writeCredential(account.id, provider, null).catch(() => undefined)
604
- for (const [provider, credential] of Object.entries(data)) await this.writeCredential(account.id, provider, credential).catch(() => undefined)
605
- this.invalidate(account.id)
606
- store.audit(this.dir, account.id, 'credentials.synced', 'Pi terminal sign-in saved to the Keychain.')
607
- }
608
- rmSync(path, { force: true })
609
- }
610
-
611
- // ---- Health from runs ---------------------------------------------------------------------
612
-
613
- /** Tracks account health and limits from run events. `run` is the event's run record, when it is known. */
614
- onRunEvent(event: RunEvent, run: RunRecord | null): void {
615
- if (event.type === 'account.status') this.applyStatus(event)
616
- else if (event.type === 'completed' && run?.accountId) {
617
- const accountId = run.accountId
618
- const { previous, state } = store.updateState(this.dir, accountId, (current) => {
619
- // A finished run proves the sign-in works; limit windows and limit errors stay until they reset.
620
- if (current.lastError && (!store.isLimitCategory(current.lastError.category) || !store.limitErrorActive(current.lastError))) current.lastError = null
621
- current.signedIn = true
622
- })
623
- if (previous !== state.health) this.changed({ accountId, health: state.health, previous })
624
- }
625
- }
626
-
627
- private applyStatus(event: RunEvent): void {
628
- const payload = event.payload as { accountId?: unknown; category?: unknown; message?: unknown; limits?: unknown; plan?: unknown; resetsAt?: unknown }
629
- if (typeof payload.accountId !== 'string') return
630
- const accountId = payload.accountId
631
- const text = (value: unknown): string | null => (typeof value === 'string' ? value : null)
632
- const category = text(payload.category)
633
- const message = text(payload.message) === null ? null : store.scrub(payload.message as string)
634
- const limits = Array.isArray(payload.limits) ? (payload.limits as Limit[]) : null
635
- let result: ReturnType<typeof store.updateState>
636
- try {
637
- result = store.updateState(this.dir, accountId, (state) => {
638
- if (limits) {
639
- for (const limit of limits) state.limits = [...state.limits.filter((existing) => existing.id !== limit.id), limit]
640
- state.limits.sort((left, right) => (left.id < right.id ? -1 : left.id > right.id ? 1 : 0))
641
- }
642
- if (text(payload.plan) !== null) state.plan = text(payload.plan)
643
- if (category) {
644
- state.lastError = { category, message: message ?? '', at: now(), resetsAt: text(payload.resetsAt) } satisfies Issue
645
- if (category === 'auth_expired') state.signedIn = false
646
- }
647
- })
648
- } catch {
649
- return
650
- }
651
- if (result.previous !== result.state.health) {
652
- store.audit(this.dir, accountId, 'health.changed', `${result.previous} → ${result.state.health}${message ? `: ${message}` : ''}`)
653
- this.changed({ accountId, health: result.state.health, previous: result.previous, message, resetsAt: text(payload.resetsAt) })
654
- } else {
655
- this.changed({ accountId })
656
- }
657
- }
658
- }