@xingular/harness 0.1.7 → 1.0.0

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 (683) hide show
  1. package/CHANGELOG.md +97 -1
  2. package/LICENSE +202 -0
  3. package/NOTICE.md +22 -0
  4. package/README.md +187 -85
  5. package/THIRD_PARTY_LICENSES.md +942 -0
  6. package/dist/cli.js +13701 -13498
  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/browser/config.d.ts +16 -0
  18. package/dist/sdk/browser/config.js +22 -0
  19. package/dist/sdk/browser/diagnostics.d.ts +4 -0
  20. package/dist/sdk/browser/diagnostics.js +38 -0
  21. package/dist/sdk/browser/index.d.ts +17 -0
  22. package/dist/sdk/browser/index.js +65 -0
  23. package/dist/sdk/browser/network.d.ts +10 -0
  24. package/dist/sdk/browser/network.js +59 -0
  25. package/dist/sdk/browser/session.d.ts +84 -0
  26. package/dist/sdk/browser/session.js +192 -0
  27. package/dist/sdk/browser/tools.d.ts +8 -0
  28. package/dist/sdk/browser/tools.js +329 -0
  29. package/dist/sdk/capabilities/api.d.ts +22 -0
  30. package/dist/sdk/capabilities/api.js +54 -0
  31. package/dist/sdk/capabilities/runSnapshot.d.ts +18 -0
  32. package/dist/sdk/capabilities/runSnapshot.js +47 -0
  33. package/dist/sdk/capabilities/types.d.ts +29 -0
  34. package/dist/sdk/capabilities/types.js +1 -0
  35. package/dist/sdk/cli.d.ts +2 -0
  36. package/dist/sdk/cli.js +142 -0
  37. package/dist/sdk/core/bus.d.ts +23 -0
  38. package/dist/sdk/core/bus.js +76 -0
  39. package/dist/sdk/core/caller.d.ts +22 -0
  40. package/dist/sdk/core/caller.js +16 -0
  41. package/dist/sdk/core/changes.d.ts +15 -0
  42. package/dist/sdk/core/changes.js +15 -0
  43. package/dist/sdk/core/effort.d.ts +2 -0
  44. package/dist/sdk/core/effort.js +1 -0
  45. package/dist/sdk/core/env.d.ts +18 -0
  46. package/dist/sdk/core/env.js +8 -0
  47. package/dist/sdk/core/errors.d.ts +15 -0
  48. package/dist/sdk/core/errors.js +24 -0
  49. package/dist/sdk/core/frontmatter.d.ts +12 -0
  50. package/dist/sdk/core/frontmatter.js +50 -0
  51. package/dist/sdk/core/fs.d.ts +18 -0
  52. package/dist/sdk/core/fs.js +106 -0
  53. package/dist/sdk/core/index.d.ts +24 -0
  54. package/dist/sdk/core/index.js +187 -0
  55. package/dist/sdk/core/path.d.ts +7 -0
  56. package/dist/sdk/core/path.js +79 -0
  57. package/dist/sdk/core/projects.d.ts +18 -0
  58. package/dist/sdk/core/projects.js +67 -0
  59. package/dist/sdk/core/secrets.d.ts +2 -0
  60. package/dist/sdk/core/secrets.js +5 -0
  61. package/dist/sdk/core/text.d.ts +7 -0
  62. package/dist/sdk/core/text.js +40 -0
  63. package/dist/sdk/doctor/checks.d.ts +5 -0
  64. package/dist/sdk/doctor/checks.js +208 -0
  65. package/dist/sdk/doctor/probe.d.ts +4 -0
  66. package/dist/sdk/doctor/probe.js +92 -0
  67. package/dist/sdk/doctor/service.d.ts +23 -0
  68. package/dist/sdk/doctor/service.js +144 -0
  69. package/dist/sdk/doctor/types.d.ts +141 -0
  70. package/dist/sdk/doctor/types.js +29 -0
  71. package/dist/sdk/harness.d.ts +133 -0
  72. package/dist/sdk/harness.js +299 -0
  73. package/dist/sdk/history/lessonPrompt.d.ts +2 -0
  74. package/dist/sdk/history/lessonPrompt.js +15 -0
  75. package/dist/sdk/history/lessons.d.ts +52 -0
  76. package/dist/sdk/history/lessons.js +173 -0
  77. package/dist/sdk/history/recall.d.ts +68 -0
  78. package/dist/sdk/history/recall.js +199 -0
  79. package/dist/sdk/history/trajectory.d.ts +7 -0
  80. package/dist/sdk/history/trajectory.js +216 -0
  81. package/dist/sdk/hub/catalog.json +123 -0
  82. package/dist/sdk/hub/cli.d.ts +7 -0
  83. package/dist/sdk/hub/cli.js +81 -0
  84. package/dist/sdk/hub/hub.d.ts +74 -0
  85. package/dist/sdk/hub/hub.js +474 -0
  86. package/dist/sdk/hub/schema.d.ts +280 -0
  87. package/dist/sdk/hub/schema.js +78 -0
  88. package/dist/sdk/index.d.ts +63 -0
  89. package/dist/sdk/index.js +48 -0
  90. package/dist/sdk/mcp/connections.d.ts +83 -0
  91. package/dist/sdk/mcp/connections.js +669 -0
  92. package/dist/sdk/mcp/manager.d.ts +26 -0
  93. package/dist/sdk/mcp/manager.js +124 -0
  94. package/dist/sdk/mcp/oauth.d.ts +35 -0
  95. package/dist/sdk/mcp/oauth.js +171 -0
  96. package/dist/sdk/mcp/scopeMigration.d.ts +19 -0
  97. package/dist/sdk/mcp/scopeMigration.js +198 -0
  98. package/dist/sdk/mcp/service.d.ts +160 -0
  99. package/dist/sdk/mcp/service.js +510 -0
  100. package/dist/sdk/mcp/types.d.ts +131 -0
  101. package/dist/sdk/mcp/types.js +49 -0
  102. package/dist/sdk/pi/runtime.d.ts +13 -0
  103. package/dist/sdk/pi/runtime.js +31 -0
  104. package/dist/sdk/plugins/api.d.ts +66 -0
  105. package/dist/sdk/plugins/api.js +155 -0
  106. package/dist/sdk/plugins/attachments.d.ts +46 -0
  107. package/dist/sdk/plugins/attachments.js +111 -0
  108. package/dist/sdk/plugins/builtin.d.ts +6 -0
  109. package/dist/sdk/plugins/builtin.js +68 -0
  110. package/dist/sdk/plugins/catalogue.d.ts +29 -0
  111. package/dist/sdk/plugins/catalogue.js +196 -0
  112. package/dist/sdk/plugins/cli.d.ts +13 -0
  113. package/dist/sdk/plugins/cli.js +187 -0
  114. package/dist/sdk/plugins/discover.d.ts +42 -0
  115. package/dist/sdk/plugins/discover.js +115 -0
  116. package/dist/sdk/plugins/firstParty.d.ts +50 -0
  117. package/dist/sdk/plugins/firstParty.js +113 -0
  118. package/dist/sdk/plugins/hooks.d.ts +94 -0
  119. package/dist/sdk/plugins/hooks.js +162 -0
  120. package/dist/sdk/plugins/identity.d.ts +19 -0
  121. package/dist/sdk/plugins/identity.js +48 -0
  122. package/dist/sdk/plugins/install.d.ts +20 -0
  123. package/dist/sdk/plugins/install.js +110 -0
  124. package/dist/sdk/plugins/inventory.d.ts +22 -0
  125. package/dist/sdk/plugins/inventory.js +110 -0
  126. package/dist/sdk/plugins/manifest.d.ts +13 -0
  127. package/dist/sdk/plugins/manifest.js +56 -0
  128. package/dist/sdk/plugins/plugins.d.ts +104 -0
  129. package/dist/sdk/plugins/plugins.js +164 -0
  130. package/dist/sdk/plugins/runtime.d.ts +9 -0
  131. package/dist/sdk/plugins/runtime.js +95 -0
  132. package/dist/sdk/plugins/trust.d.ts +44 -0
  133. package/dist/sdk/plugins/trust.js +120 -0
  134. package/dist/sdk/plugins/types.d.ts +159 -0
  135. package/dist/sdk/plugins/types.js +7 -0
  136. package/dist/sdk/prompt/compile.d.ts +174 -0
  137. package/dist/sdk/prompt/compile.js +396 -0
  138. package/dist/sdk/refine/cli.d.ts +4 -0
  139. package/dist/sdk/refine/cli.js +186 -0
  140. package/dist/sdk/refine/demo.d.ts +21 -0
  141. package/dist/sdk/refine/demo.js +114 -0
  142. package/dist/sdk/refine/evidence.d.ts +55 -0
  143. package/dist/sdk/refine/evidence.js +330 -0
  144. package/dist/sdk/refine/host.d.ts +51 -0
  145. package/dist/sdk/refine/host.js +76 -0
  146. package/dist/sdk/refine/ledger.d.ts +48 -0
  147. package/dist/sdk/refine/ledger.js +76 -0
  148. package/dist/sdk/refine/library.d.ts +55 -0
  149. package/dist/sdk/refine/library.js +177 -0
  150. package/dist/sdk/refine/pi.d.ts +72 -0
  151. package/dist/sdk/refine/pi.js +248 -0
  152. package/dist/sdk/refine/prompts.d.ts +45 -0
  153. package/dist/sdk/refine/prompts.js +390 -0
  154. package/dist/sdk/refine/recursion.d.ts +113 -0
  155. package/dist/sdk/refine/recursion.js +258 -0
  156. package/dist/sdk/refine/runner.d.ts +81 -0
  157. package/dist/sdk/refine/runner.js +150 -0
  158. package/dist/sdk/refine/selection.d.ts +57 -0
  159. package/dist/sdk/refine/selection.js +251 -0
  160. package/dist/sdk/refine/service.d.ts +84 -0
  161. package/dist/sdk/refine/service.js +165 -0
  162. package/dist/sdk/refine/suite.d.ts +67 -0
  163. package/dist/sdk/refine/suite.js +174 -0
  164. package/dist/sdk/refine/trajectory.d.ts +9 -0
  165. package/dist/sdk/refine/trajectory.js +68 -0
  166. package/dist/sdk/refine/types.d.ts +77 -0
  167. package/dist/sdk/refine/types.js +10 -0
  168. package/dist/sdk/server/methods.d.ts +3 -0
  169. package/dist/sdk/server/methods.js +370 -0
  170. package/dist/sdk/server/remote.d.ts +19 -0
  171. package/dist/sdk/server/remote.js +84 -0
  172. package/dist/sdk/server/rpc.d.ts +20 -0
  173. package/dist/sdk/server/rpc.js +102 -0
  174. package/dist/sdk/server/serve.d.ts +10 -0
  175. package/dist/sdk/server/serve.js +18 -0
  176. package/dist/sdk/sessions/approvals.d.ts +47 -0
  177. package/dist/sdk/sessions/approvals.js +119 -0
  178. package/dist/sdk/sessions/continuation.d.ts +48 -0
  179. package/dist/sdk/sessions/continuation.js +85 -0
  180. package/dist/sdk/sessions/contracts.d.ts +534 -0
  181. package/dist/sdk/sessions/contracts.js +299 -0
  182. package/dist/sdk/sessions/extensionUi.d.ts +19 -0
  183. package/dist/sdk/sessions/extensionUi.js +64 -0
  184. package/dist/sdk/sessions/history.d.ts +16 -0
  185. package/dist/sdk/sessions/history.js +68 -0
  186. package/dist/sdk/sessions/lineageJoin.d.ts +2 -0
  187. package/dist/sdk/sessions/lineageJoin.js +61 -0
  188. package/dist/sdk/sessions/planMode.d.ts +36 -0
  189. package/dist/sdk/sessions/planMode.js +84 -0
  190. package/dist/sdk/sessions/policy.d.ts +43 -0
  191. package/dist/sdk/sessions/policy.js +1 -0
  192. package/dist/sdk/sessions/pricing.d.ts +34 -0
  193. package/dist/sdk/sessions/pricing.js +40 -0
  194. package/dist/sdk/sessions/reasoningSummaries.d.ts +11 -0
  195. package/dist/sdk/sessions/reasoningSummaries.js +61 -0
  196. package/dist/sdk/sessions/registry.d.ts +102 -0
  197. package/dist/sdk/sessions/registry.js +383 -0
  198. package/dist/sdk/sessions/runIndex.d.ts +21 -0
  199. package/dist/sdk/sessions/runIndex.js +65 -0
  200. package/dist/sdk/sessions/runStore.d.ts +66 -0
  201. package/dist/sdk/sessions/runStore.js +335 -0
  202. package/dist/sdk/sessions/runner.d.ts +213 -0
  203. package/dist/sdk/sessions/runner.js +589 -0
  204. package/dist/sdk/sessions/sessions.d.ts +140 -0
  205. package/dist/sdk/sessions/sessions.js +394 -0
  206. package/dist/sdk/sessions/subagentService.d.ts +41 -0
  207. package/dist/sdk/sessions/subagentService.js +247 -0
  208. package/dist/sdk/sessions/subagents.d.ts +50 -0
  209. package/dist/sdk/sessions/subagents.js +68 -0
  210. package/dist/sdk/terminal/accountsMenu.d.ts +46 -0
  211. package/dist/sdk/terminal/accountsMenu.js +392 -0
  212. package/dist/sdk/terminal/cli.d.ts +20 -0
  213. package/dist/sdk/terminal/cli.js +121 -0
  214. package/dist/sdk/terminal/client.d.ts +15 -0
  215. package/dist/sdk/terminal/client.js +126 -0
  216. package/dist/sdk/terminal/control.d.ts +4 -0
  217. package/dist/sdk/terminal/control.js +25 -0
  218. package/dist/sdk/terminal/controller.d.ts +72 -0
  219. package/dist/sdk/terminal/controller.js +351 -0
  220. package/dist/sdk/terminal/hubMenu.d.ts +10 -0
  221. package/dist/sdk/terminal/hubMenu.js +34 -0
  222. package/dist/sdk/terminal/launch.d.ts +5 -0
  223. package/dist/sdk/terminal/launch.js +27 -0
  224. package/dist/sdk/terminal/logs.d.ts +14 -0
  225. package/dist/sdk/terminal/logs.js +59 -0
  226. package/dist/sdk/terminal/piExtension.d.ts +6 -0
  227. package/dist/sdk/terminal/piExtension.js +392 -0
  228. package/dist/sdk/terminal/pluginMenu.d.ts +34 -0
  229. package/dist/sdk/terminal/pluginMenu.js +101 -0
  230. package/dist/sdk/terminal/socket.d.ts +70 -0
  231. package/dist/sdk/terminal/socket.js +256 -0
  232. package/dist/sdk/terminal/standalone.d.ts +18 -0
  233. package/dist/sdk/terminal/standalone.js +146 -0
  234. package/dist/sdk/terminal/terminals.d.ts +176 -0
  235. package/dist/sdk/terminal/terminals.js +767 -0
  236. package/dist/sdk/terminal/trajectory.d.ts +10 -0
  237. package/dist/sdk/terminal/trajectory.js +30 -0
  238. package/dist/sdk/terminal/tui/chrome.d.ts +64 -0
  239. package/dist/sdk/terminal/tui/chrome.js +169 -0
  240. package/dist/sdk/terminal/tui/clipboardFiles.d.ts +11 -0
  241. package/dist/sdk/terminal/tui/clipboardFiles.js +74 -0
  242. package/dist/sdk/terminal/tui/commandPages.d.ts +7 -0
  243. package/dist/sdk/terminal/tui/commandPages.js +63 -0
  244. package/dist/sdk/terminal/tui/commands.d.ts +42 -0
  245. package/dist/sdk/terminal/tui/commands.js +276 -0
  246. package/dist/sdk/terminal/tui/dialogGeometry.d.ts +27 -0
  247. package/dist/sdk/terminal/tui/dialogGeometry.js +50 -0
  248. package/dist/sdk/terminal/tui/dialogs.d.ts +75 -0
  249. package/dist/sdk/terminal/tui/dialogs.js +363 -0
  250. package/dist/sdk/terminal/tui/keybindings.d.ts +11 -0
  251. package/dist/sdk/terminal/tui/keybindings.js +49 -0
  252. package/dist/sdk/terminal/tui/list.d.ts +73 -0
  253. package/dist/sdk/terminal/tui/list.js +196 -0
  254. package/dist/sdk/terminal/tui/modeChoices.d.ts +42 -0
  255. package/dist/sdk/terminal/tui/modeChoices.js +70 -0
  256. package/dist/sdk/terminal/tui/modelPicker.d.ts +55 -0
  257. package/dist/sdk/terminal/tui/modelPicker.js +155 -0
  258. package/dist/sdk/terminal/tui/mouse.d.ts +3 -0
  259. package/dist/sdk/terminal/tui/mouse.js +3 -0
  260. package/dist/sdk/terminal/tui/page.d.ts +14 -0
  261. package/dist/sdk/terminal/tui/page.js +1 -0
  262. package/dist/sdk/terminal/tui/pageOverlay.d.ts +27 -0
  263. package/dist/sdk/terminal/tui/pageOverlay.js +145 -0
  264. package/dist/sdk/terminal/tui/pages/accountsPage.d.ts +54 -0
  265. package/dist/sdk/terminal/tui/pages/accountsPage.js +181 -0
  266. package/dist/sdk/terminal/tui/pages/componentsPage.d.ts +47 -0
  267. package/dist/sdk/terminal/tui/pages/componentsPage.js +119 -0
  268. package/dist/sdk/terminal/tui/pages/doctorPage.d.ts +37 -0
  269. package/dist/sdk/terminal/tui/pages/doctorPage.js +145 -0
  270. package/dist/sdk/terminal/tui/pages/hubPage.d.ts +39 -0
  271. package/dist/sdk/terminal/tui/pages/hubPage.js +128 -0
  272. package/dist/sdk/terminal/tui/pages/logPage.d.ts +38 -0
  273. package/dist/sdk/terminal/tui/pages/logPage.js +189 -0
  274. package/dist/sdk/terminal/tui/pages/permissionsPage.d.ts +44 -0
  275. package/dist/sdk/terminal/tui/pages/permissionsPage.js +124 -0
  276. package/dist/sdk/terminal/tui/pages/pluginsPage.d.ts +57 -0
  277. package/dist/sdk/terminal/tui/pages/pluginsPage.js +243 -0
  278. package/dist/sdk/terminal/tui/pages/settingsPage.d.ts +55 -0
  279. package/dist/sdk/terminal/tui/pages/settingsPage.js +88 -0
  280. package/dist/sdk/terminal/tui/pages/trajectoryPage.d.ts +58 -0
  281. package/dist/sdk/terminal/tui/pages/trajectoryPage.js +377 -0
  282. package/dist/sdk/terminal/tui/piAdapter.d.ts +18 -0
  283. package/dist/sdk/terminal/tui/piAdapter.js +48 -0
  284. package/dist/sdk/terminal/tui/planMode.d.ts +2 -0
  285. package/dist/sdk/terminal/tui/planMode.js +2 -0
  286. package/dist/sdk/terminal/tui/questionPicker.d.ts +20 -0
  287. package/dist/sdk/terminal/tui/questionPicker.js +150 -0
  288. package/dist/sdk/terminal/tui/questions.d.ts +19 -0
  289. package/dist/sdk/terminal/tui/questions.js +42 -0
  290. package/dist/sdk/terminal/tui/runtime.d.ts +114 -0
  291. package/dist/sdk/terminal/tui/runtime.js +441 -0
  292. package/dist/sdk/terminal/tui/search.d.ts +22 -0
  293. package/dist/sdk/terminal/tui/search.js +60 -0
  294. package/dist/sdk/terminal/tui/selection.d.ts +16 -0
  295. package/dist/sdk/terminal/tui/selection.js +16 -0
  296. package/dist/sdk/terminal/tui/sessionUi.d.ts +3 -0
  297. package/dist/sdk/terminal/tui/sessionUi.js +30 -0
  298. package/dist/sdk/terminal/tui/settingsModel.d.ts +12 -0
  299. package/dist/sdk/terminal/tui/settingsModel.js +84 -0
  300. package/dist/sdk/terminal/tui/sideQuestion.d.ts +53 -0
  301. package/dist/sdk/terminal/tui/sideQuestion.js +197 -0
  302. package/dist/sdk/terminal/tui/skillInvocation.d.ts +9 -0
  303. package/dist/sdk/terminal/tui/skillInvocation.js +43 -0
  304. package/dist/sdk/terminal/tui/status.d.ts +18 -0
  305. package/dist/sdk/terminal/tui/status.js +67 -0
  306. package/dist/sdk/terminal/tui/theme.d.ts +45 -0
  307. package/dist/sdk/terminal/tui/theme.js +176 -0
  308. package/dist/sdk/terminal/tui/treeModel.d.ts +79 -0
  309. package/dist/sdk/terminal/tui/treeModel.js +483 -0
  310. package/dist/sdk/terminal/tui/treePicker.d.ts +49 -0
  311. package/dist/sdk/terminal/tui/treePicker.js +251 -0
  312. package/dist/sdk/terminal/tui/ui.d.ts +47 -0
  313. package/dist/sdk/terminal/tui/ui.js +148 -0
  314. package/dist/sdk/terminal/tui/workingStatus.d.ts +9 -0
  315. package/dist/sdk/terminal/tui/workingStatus.js +229 -0
  316. package/dist/sdk/tools/askUser.d.ts +6 -0
  317. package/dist/sdk/tools/askUser.js +74 -0
  318. package/dist/sdk/tools/checklist.d.ts +9 -0
  319. package/dist/sdk/tools/checklist.js +54 -0
  320. package/dist/sdk/tools/definitions.d.ts +30 -0
  321. package/dist/sdk/tools/definitions.js +117 -0
  322. package/dist/sdk/tools/dispatch.d.ts +16 -0
  323. package/dist/sdk/tools/dispatch.js +67 -0
  324. package/dist/sdk/tools/harnessTools.d.ts +6 -0
  325. package/dist/sdk/tools/harnessTools.js +20 -0
  326. package/dist/sdk/tools/sessionName.d.ts +7 -0
  327. package/dist/sdk/tools/sessionName.js +31 -0
  328. package/dist/sdk/tools/spawnSubagent.d.ts +4 -0
  329. package/dist/sdk/tools/spawnSubagent.js +49 -0
  330. package/dist/sdk/tools/types.d.ts +48 -0
  331. package/dist/sdk/tools/types.js +1 -0
  332. package/dist/sdk/variant/components.d.ts +34 -0
  333. package/dist/sdk/variant/components.js +230 -0
  334. package/dist/sdk/variant/materialise.d.ts +66 -0
  335. package/dist/sdk/variant/materialise.js +81 -0
  336. package/dist/sdk/variant/migrate.d.ts +4 -0
  337. package/dist/sdk/variant/migrate.js +41 -0
  338. package/dist/sdk/variant/seed.d.ts +20 -0
  339. package/dist/sdk/variant/seed.js +116 -0
  340. package/dist/sdk/variant/store.d.ts +82 -0
  341. package/dist/sdk/variant/store.js +151 -0
  342. package/dist/sdk/variant/surface.d.ts +56 -0
  343. package/dist/sdk/variant/surface.js +81 -0
  344. package/dist/sdk/variant/trust.d.ts +27 -0
  345. package/dist/sdk/variant/trust.js +64 -0
  346. package/dist/sdk/variant/variant.d.ts +71 -0
  347. package/dist/sdk/variant/variant.js +331 -0
  348. package/dist/sdk/web/markdown.d.ts +10 -0
  349. package/dist/sdk/web/markdown.js +66 -0
  350. package/dist/sdk/web/safeRequest.d.ts +34 -0
  351. package/dist/sdk/web/safeRequest.js +175 -0
  352. package/dist/sdk/web/search.d.ts +53 -0
  353. package/dist/sdk/web/search.js +168 -0
  354. package/dist/sdk/web/text.d.ts +2 -0
  355. package/dist/sdk/web/text.js +7 -0
  356. package/dist/sdk/web/tools.d.ts +22 -0
  357. package/dist/sdk/web/tools.js +195 -0
  358. package/dist/sdk/web/turndown-plugin-gfm.d.ts +4 -0
  359. package/dist/sdk/wiki/notes.d.ts +68 -0
  360. package/dist/sdk/wiki/notes.js +297 -0
  361. package/dist/sdk/world/actions.d.ts +23 -0
  362. package/dist/sdk/world/actions.js +31 -0
  363. package/dist/sdk/world/cli.d.ts +12 -0
  364. package/dist/sdk/world/cli.js +166 -0
  365. package/dist/sdk/world/images.d.ts +20 -0
  366. package/dist/sdk/world/images.js +48 -0
  367. package/dist/sdk/world/untrusted.d.ts +12 -0
  368. package/dist/sdk/world/untrusted.js +20 -0
  369. package/dist/sdk/world/world.d.ts +65 -0
  370. package/dist/sdk/world/world.js +80 -0
  371. package/dist/terminal-opentui.js +13612 -0
  372. package/dist/terminal-pi.js +808 -151
  373. package/docs/README.md +22 -0
  374. package/docs/architecture/00-overview.md +159 -0
  375. package/docs/architecture/01-extension-points.md +78 -0
  376. package/docs/architecture/02-sessions-and-runs.md +146 -0
  377. package/docs/architecture/03-variants.md +95 -0
  378. package/docs/architecture/04-prompt.md +102 -0
  379. package/docs/architecture/05-refinement.md +107 -0
  380. package/docs/architecture/06-plugins-and-capabilities.md +93 -0
  381. package/docs/architecture/07-tools-and-gate.md +88 -0
  382. package/docs/architecture/08-memory-and-history.md +94 -0
  383. package/docs/architecture/09-accounts-and-connectors.md +90 -0
  384. package/docs/architecture/10-server-protocol.md +84 -0
  385. package/docs/architecture/11-terminal.md +81 -0
  386. package/docs/architecture/12-storage.md +61 -0
  387. package/docs/architecture/13-world-tools.md +23 -0
  388. package/docs/architecture/README.md +114 -0
  389. package/docs/architecture/proposals/PROP-0001-reporting-section.md +106 -0
  390. package/docs/architecture/proposals/PROP-0002-retain-rollout-workspaces.md +104 -0
  391. package/docs/architecture/proposals/PROP-0003-executor-settings.md +81 -0
  392. package/docs/architecture/proposals/PROP-0004-flexible-reporting-guidance.md +71 -0
  393. package/docs/architecture/proposals/PROP-0005-xharness-cli-name.md +78 -0
  394. package/docs/architecture/proposals/PROP-0006-run-checklist.md +68 -0
  395. package/docs/architecture/proposals/PROP-0007-run-continuation.md +80 -0
  396. package/docs/architecture/proposals/PROP-0008-lessons-from-runs.md +80 -0
  397. package/docs/architecture/proposals/PROP-0009-foundation-and-variants.md +78 -0
  398. package/docs/architecture/proposals/PROP-0010-session-names.md +73 -0
  399. package/docs/architecture/proposals/PROP-0011-doctor.md +63 -0
  400. package/docs/architecture/proposals/PROP-0012-release-baseline.md +56 -0
  401. package/docs/architecture/proposals/README.md +76 -0
  402. package/docs/decisions/ADR-0002-native-subagent-lifecycle.md +49 -0
  403. package/docs/decisions/ADR-0003-shared-asynchronous-subagents.md +70 -0
  404. package/docs/decisions/ADR-0004-fullscreen-terminal-layout.md +50 -0
  405. package/docs/decisions/ADR-0005-app-provided-oauth-clients.md +54 -0
  406. package/docs/decisions/ADR-0006-opentui-only-terminal.md +47 -0
  407. package/docs/decisions/ADR-0007-reporting-section.md +33 -0
  408. package/docs/decisions/ADR-0008-flexible-reporting-guidance.md +38 -0
  409. package/docs/decisions/ADR-0009-xharness-command.md +38 -0
  410. package/docs/decisions/ADR-0010-lessons-in-the-wiki.md +31 -0
  411. package/docs/decisions/ADR-0011-foundation-and-variants.md +28 -0
  412. package/docs/decisions/ADR-0012-native-session-names.md +34 -0
  413. package/docs/decisions/ADR-0013-doctor.md +27 -0
  414. package/docs/decisions/ADR-0014-public-release-baseline.md +21 -0
  415. package/docs/doctor.md +74 -0
  416. package/docs/experiments/EXP-0001-terminal-input-latency/plan.md +81 -0
  417. package/docs/experiments/EXP-0001-terminal-input-latency/results.md +46 -0
  418. package/docs/experiments/EXP-0002-opentui-typing-latency/plan.md +70 -0
  419. package/docs/experiments/EXP-0002-opentui-typing-latency/results.md +92 -0
  420. package/docs/features/README.md +20 -0
  421. package/docs/features/automations/README.md +41 -0
  422. package/docs/features/cores/README.md +39 -0
  423. package/docs/features/google-harness2/README.md +52 -0
  424. package/docs/features/integrations/README.md +40 -0
  425. package/docs/features/interfaces/README.md +29 -0
  426. package/docs/features/memory/README.md +28 -0
  427. package/docs/releases/1.0.0.md +40 -0
  428. package/docs/releases/README.md +36 -0
  429. package/docs/study/00-index.md +78 -0
  430. package/docs/study/arms/00-matrix.md +20 -0
  431. package/docs/study/arms/01-system-prompt.md +211 -0
  432. package/docs/study/arms/02-tools.md +79 -0
  433. package/docs/study/arms/03-subagents.md +90 -0
  434. package/docs/study/arms/04-skills.md +75 -0
  435. package/docs/study/arms/05-context-management.md +90 -0
  436. package/docs/study/arms/06-memory.md +90 -0
  437. package/docs/study/arms/07-governance.md +71 -0
  438. package/docs/study/arms/08-execution.md +69 -0
  439. package/docs/study/arms/09-observability.md +60 -0
  440. package/docs/study/arms/10-refinement.md +110 -0
  441. package/docs/study/btw-comparison.md +37 -0
  442. package/docs/study/feature-gap-review.md +42 -0
  443. package/docs/study/insights.md +123 -0
  444. package/docs/study/roadmap.md +72 -0
  445. package/docs/study/sources/claude-code.md +44 -0
  446. package/docs/study/sources/deepseek-harness.md +102 -0
  447. package/docs/study/sources/harness2.md +50 -0
  448. package/docs/study/sources/kimi-cli.md +42 -0
  449. package/docs/study/sources/omp.md +93 -0
  450. package/docs/study/sources/opencode.md +43 -0
  451. package/docs/study/sources/openhands.md +46 -0
  452. package/docs/study/sources/smolagents.md +40 -0
  453. package/docs/study/sources/swe-agent.md +34 -0
  454. package/docs/system-prompt-design.md +196 -0
  455. package/docs/terminal-tui.md +473 -56
  456. package/package.json +43 -13
  457. package/docs/evidence/terminal-2026-10-17/120x40-completed-transcript.ansi.gz +0 -0
  458. package/docs/evidence/terminal-2026-10-17/40x20-settings-interaction.ansi.gz +0 -0
  459. package/docs/evidence/terminal-2026-10-17/40x20-settings-keyboard.ansi.gz +0 -0
  460. package/docs/evidence/terminal-2026-10-17/40x20-welcome.ansi.gz +0 -0
  461. package/docs/evidence/terminal-2026-10-17/80x24-approval-0.ansi.gz +0 -0
  462. package/docs/evidence/terminal-2026-10-17/80x24-question.ansi.gz +0 -0
  463. package/docs/evidence/terminal-2026-10-17/verification.json +0 -130
  464. package/docs/evidence/terminal-2026-10-17-followup/120x40-completed-transcript.ansi.gz +0 -0
  465. package/docs/evidence/terminal-2026-10-17-followup/40x20-settings-interaction.ansi.gz +0 -0
  466. package/docs/evidence/terminal-2026-10-17-followup/40x20-settings-keyboard.ansi.gz +0 -0
  467. package/docs/evidence/terminal-2026-10-17-followup/40x20-welcome.ansi.gz +0 -0
  468. package/docs/evidence/terminal-2026-10-17-followup/80x24-approval-0.ansi.gz +0 -0
  469. package/docs/evidence/terminal-2026-10-17-followup/80x24-plugin-light.ansi.gz +0 -0
  470. package/docs/evidence/terminal-2026-10-17-followup/80x24-question-batch.ansi.gz +0 -0
  471. package/docs/evidence/terminal-2026-10-17-followup/80x24-question.ansi.gz +0 -0
  472. package/docs/evidence/terminal-2026-10-17-followup/app-bundle/80x24-approval-0.ansi.gz +0 -0
  473. package/docs/evidence/terminal-2026-10-17-followup/app-bundle/80x24-plugin-light.ansi.gz +0 -0
  474. package/docs/evidence/terminal-2026-10-17-followup/app-bundle/80x24-question-batch.ansi.gz +0 -0
  475. package/docs/evidence/terminal-2026-10-17-followup/app-bundle/80x24-question.ansi.gz +0 -0
  476. package/docs/evidence/terminal-2026-10-17-followup/app-bundle/verification.json +0 -95
  477. package/docs/evidence/terminal-2026-10-17-followup/global-install/80x24-approval-0.ansi.gz +0 -0
  478. package/docs/evidence/terminal-2026-10-17-followup/global-install/80x24-plugin-light.ansi.gz +0 -0
  479. package/docs/evidence/terminal-2026-10-17-followup/global-install/80x24-question-batch.ansi.gz +0 -0
  480. package/docs/evidence/terminal-2026-10-17-followup/global-install/80x24-question.ansi.gz +0 -0
  481. package/docs/evidence/terminal-2026-10-17-followup/global-install/README.md +0 -27
  482. package/docs/evidence/terminal-2026-10-17-followup/global-install/shell-command-80x24.ansi.gz +0 -0
  483. package/docs/evidence/terminal-2026-10-17-followup/global-install/shell-command.json +0 -18
  484. package/docs/evidence/terminal-2026-10-17-followup/global-install/verification.json +0 -95
  485. package/docs/evidence/terminal-2026-10-17-followup/harness-reference-80x24.json.gz +0 -0
  486. package/docs/evidence/terminal-2026-10-17-followup/harness-reference-final-80x24.json.gz +0 -0
  487. package/docs/evidence/terminal-2026-10-17-followup/harness-reference-scenario.json +0 -60
  488. package/docs/evidence/terminal-2026-10-17-followup/live-codex/README.md +0 -24
  489. package/docs/evidence/terminal-2026-10-17-followup/live-codex/complete-80x24.ansi.gz +0 -0
  490. package/docs/evidence/terminal-2026-10-17-followup/live-codex/verification.json +0 -57
  491. package/docs/evidence/terminal-2026-10-17-followup/omp-reference-80x24-early.json.gz +0 -0
  492. package/docs/evidence/terminal-2026-10-17-followup/omp-reference-80x24.json.gz +0 -0
  493. package/docs/evidence/terminal-2026-10-17-followup/omp-reference-scenario.json +0 -58
  494. package/docs/evidence/terminal-2026-10-17-followup/omp-supplemental-static.json.gz +0 -0
  495. package/docs/evidence/terminal-2026-10-17-followup/rea-artifacts.json +0 -320
  496. package/docs/evidence/terminal-2026-10-17-followup/reference-comparison.json +0 -30
  497. package/docs/evidence/terminal-2026-10-17-followup/reference-comparison.md +0 -133
  498. package/docs/evidence/terminal-2026-10-17-followup/reference-source-observations.json +0 -20
  499. package/docs/evidence/terminal-2026-10-17-followup/verification.json +0 -207
  500. package/src/accounts/accounts.test.ts +0 -333
  501. package/src/accounts/accounts.ts +0 -658
  502. package/src/accounts/env.test.ts +0 -95
  503. package/src/accounts/env.ts +0 -338
  504. package/src/accounts/secrets.ts +0 -50
  505. package/src/accounts/store.ts +0 -338
  506. package/src/capabilities/api.ts +0 -75
  507. package/src/capabilities/runSnapshot.ts +0 -59
  508. package/src/capabilities/types.ts +0 -34
  509. package/src/cli.ts +0 -118
  510. package/src/core/bus.ts +0 -34
  511. package/src/core/changes.ts +0 -33
  512. package/src/core/env.ts +0 -27
  513. package/src/core/errors.ts +0 -32
  514. package/src/core/frontmatter.ts +0 -47
  515. package/src/core/fs.test.ts +0 -38
  516. package/src/core/fs.ts +0 -92
  517. package/src/core/index.ts +0 -193
  518. package/src/core/path.test.ts +0 -14
  519. package/src/core/path.ts +0 -79
  520. package/src/core/projects.ts +0 -90
  521. package/src/core/text.ts +0 -39
  522. package/src/harness.ts +0 -312
  523. package/src/hub/catalog.json +0 -123
  524. package/src/hub/cli.ts +0 -59
  525. package/src/hub/hub.test.ts +0 -205
  526. package/src/hub/hub.ts +0 -256
  527. package/src/hub/schema.ts +0 -81
  528. package/src/index.ts +0 -75
  529. package/src/mcp/connections.ts +0 -614
  530. package/src/mcp/manager.ts +0 -130
  531. package/src/mcp/oauth.ts +0 -195
  532. package/src/mcp/scopeMigration.test.ts +0 -79
  533. package/src/mcp/scopeMigration.ts +0 -204
  534. package/src/mcp/service.test.ts +0 -376
  535. package/src/mcp/service.ts +0 -549
  536. package/src/mcp/types.ts +0 -108
  537. package/src/memory/api.test.ts +0 -82
  538. package/src/memory/api.ts +0 -303
  539. package/src/memory/blocks.test.ts +0 -78
  540. package/src/memory/blocks.ts +0 -408
  541. package/src/memory/caller.ts +0 -69
  542. package/src/memory/curation.test.ts +0 -163
  543. package/src/memory/curation.ts +0 -64
  544. package/src/memory/dispatch.ts +0 -59
  545. package/src/memory/facts.test.ts +0 -41
  546. package/src/memory/facts.ts +0 -248
  547. package/src/memory/graph.ts +0 -103
  548. package/src/memory/health.test.ts +0 -130
  549. package/src/memory/health.ts +0 -74
  550. package/src/memory/maintainer.ts +0 -272
  551. package/src/memory/maintenance.test.ts +0 -176
  552. package/src/memory/maintenance.ts +0 -518
  553. package/src/memory/migrate.ts +0 -79
  554. package/src/memory/operations.ts +0 -150
  555. package/src/memory/proposals.test.ts +0 -168
  556. package/src/memory/proposals.ts +0 -584
  557. package/src/memory/recall.test.ts +0 -115
  558. package/src/memory/recall.ts +0 -278
  559. package/src/memory/references.ts +0 -77
  560. package/src/memory/runContext.ts +0 -93
  561. package/src/memory/secrets.ts +0 -6
  562. package/src/memory/store.test.ts +0 -66
  563. package/src/memory/store.ts +0 -385
  564. package/src/memory/wiki.test.ts +0 -47
  565. package/src/memory/wiki.ts +0 -422
  566. package/src/memory/wikiIndex.test.ts +0 -88
  567. package/src/memory/wikiIndex.ts +0 -116
  568. package/src/plugins/api.ts +0 -181
  569. package/src/plugins/attachments.test.ts +0 -84
  570. package/src/plugins/attachments.ts +0 -141
  571. package/src/plugins/builtin.ts +0 -82
  572. package/src/plugins/catalogue.test.ts +0 -254
  573. package/src/plugins/catalogue.ts +0 -251
  574. package/src/plugins/cli.ts +0 -184
  575. package/src/plugins/discover.ts +0 -151
  576. package/src/plugins/firstParty.test.ts +0 -143
  577. package/src/plugins/firstParty.ts +0 -129
  578. package/src/plugins/hooks.test.ts +0 -250
  579. package/src/plugins/hooks.ts +0 -239
  580. package/src/plugins/identity.ts +0 -37
  581. package/src/plugins/install.test.ts +0 -107
  582. package/src/plugins/install.ts +0 -106
  583. package/src/plugins/inventory.ts +0 -123
  584. package/src/plugins/manifest.ts +0 -76
  585. package/src/plugins/plugins.test.ts +0 -205
  586. package/src/plugins/plugins.ts +0 -189
  587. package/src/plugins/proposal.ts +0 -121
  588. package/src/plugins/runtime.test.ts +0 -40
  589. package/src/plugins/runtime.ts +0 -82
  590. package/src/plugins/trust.ts +0 -142
  591. package/src/plugins/types.ts +0 -149
  592. package/src/prompt/compile.test.ts +0 -261
  593. package/src/prompt/compile.ts +0 -732
  594. package/src/server/methods.ts +0 -349
  595. package/src/server/remote.ts +0 -77
  596. package/src/server/rpc.ts +0 -116
  597. package/src/server/serve.ts +0 -28
  598. package/src/server/server.test.ts +0 -174
  599. package/src/sessions/approvals.ts +0 -118
  600. package/src/sessions/contracts.ts +0 -336
  601. package/src/sessions/conversation.test.ts +0 -177
  602. package/src/sessions/extensionSession.test.ts +0 -74
  603. package/src/sessions/extensionUi.test.ts +0 -65
  604. package/src/sessions/extensionUi.ts +0 -102
  605. package/src/sessions/history.ts +0 -51
  606. package/src/sessions/lineageJoin.ts +0 -75
  607. package/src/sessions/policy.ts +0 -36
  608. package/src/sessions/pricing.ts +0 -60
  609. package/src/sessions/questionBatches.test.ts +0 -110
  610. package/src/sessions/reasoningSummaries.ts +0 -59
  611. package/src/sessions/registry.ts +0 -381
  612. package/src/sessions/runIndex.ts +0 -99
  613. package/src/sessions/runStore.test.ts +0 -152
  614. package/src/sessions/runStore.ts +0 -332
  615. package/src/sessions/runner.ts +0 -604
  616. package/src/sessions/runtimeResources.test.ts +0 -61
  617. package/src/sessions/sessions.test.ts +0 -549
  618. package/src/sessions/sessions.ts +0 -339
  619. package/src/skills/registry.test.ts +0 -104
  620. package/src/skills/registry.ts +0 -413
  621. package/src/terminal/accountsMenu.test.ts +0 -225
  622. package/src/terminal/accountsMenu.ts +0 -382
  623. package/src/terminal/cli.ts +0 -149
  624. package/src/terminal/client.ts +0 -74
  625. package/src/terminal/control.test.ts +0 -23
  626. package/src/terminal/control.ts +0 -23
  627. package/src/terminal/controller.ts +0 -291
  628. package/src/terminal/hubMenu.ts +0 -24
  629. package/src/terminal/launch.test.ts +0 -25
  630. package/src/terminal/launch.ts +0 -48
  631. package/src/terminal/piExtension.lifecycle.test.ts +0 -55
  632. package/src/terminal/piExtension.ts +0 -259
  633. package/src/terminal/pluginControl.test.ts +0 -146
  634. package/src/terminal/pluginMenu.ts +0 -112
  635. package/src/terminal/socket.test.ts +0 -71
  636. package/src/terminal/socket.ts +0 -232
  637. package/src/terminal/standalone.test.ts +0 -167
  638. package/src/terminal/standalone.ts +0 -153
  639. package/src/terminal/terminal.test.ts +0 -399
  640. package/src/terminal/terminals.ts +0 -553
  641. package/src/terminal/tui/application.test.ts +0 -114
  642. package/src/terminal/tui/application.ts +0 -491
  643. package/src/terminal/tui/commands.test.ts +0 -218
  644. package/src/terminal/tui/commands.ts +0 -361
  645. package/src/terminal/tui/dialogs.ts +0 -301
  646. package/src/terminal/tui/editor.test.ts +0 -84
  647. package/src/terminal/tui/editor.ts +0 -79
  648. package/src/terminal/tui/keybindings.test.ts +0 -22
  649. package/src/terminal/tui/keybindings.ts +0 -50
  650. package/src/terminal/tui/piAdapter.ts +0 -62
  651. package/src/terminal/tui/presentation.test.ts +0 -79
  652. package/src/terminal/tui/questions.test.ts +0 -41
  653. package/src/terminal/tui/questions.ts +0 -47
  654. package/src/terminal/tui/runtime.socket.test.ts +0 -104
  655. package/src/terminal/tui/runtime.test.ts +0 -215
  656. package/src/terminal/tui/runtime.ts +0 -388
  657. package/src/terminal/tui/sessionUi.ts +0 -24
  658. package/src/terminal/tui/settings.test.ts +0 -150
  659. package/src/terminal/tui/settings.ts +0 -188
  660. package/src/terminal/tui/status.test.ts +0 -70
  661. package/src/terminal/tui/status.ts +0 -109
  662. package/src/terminal/tui/theme.ts +0 -174
  663. package/src/terminal/tui/tools.test.ts +0 -145
  664. package/src/terminal/tui/tools.ts +0 -142
  665. package/src/terminal/tui/transcript.test.ts +0 -25
  666. package/src/terminal/tui/transcript.ts +0 -124
  667. package/src/terminal/tui/ui.test.ts +0 -313
  668. package/src/terminal/tui/ui.ts +0 -166
  669. package/src/terminal/tui/welcome.ts +0 -102
  670. package/src/tools/askUser.test.ts +0 -69
  671. package/src/tools/askUser.ts +0 -59
  672. package/src/tools/definitions.ts +0 -187
  673. package/src/tools/maintenance.ts +0 -24
  674. package/src/tools/memoryTools.ts +0 -22
  675. package/src/tools/pluginPropose.ts +0 -41
  676. package/src/tools/registryWrite.test.ts +0 -101
  677. package/src/tools/registryWrite.ts +0 -182
  678. package/src/tools/spawnSubagent.ts +0 -92
  679. package/src/tools/types.ts +0 -39
  680. package/src/web/safeRequest.ts +0 -171
  681. package/src/web/text.ts +0 -53
  682. package/src/web/tools.ts +0 -134
  683. package/src/web/web.test.ts +0 -141
@@ -1,232 +0,0 @@
1
- // The session socket: how a process the harness did not start in-process (the `pi` command in
2
- // a terminal, with its extension and the `xagent-wiki` / `xagent-mcp` commands) reaches the
3
- // session it belongs to. Owner-only Unix socket (a named pipe on Windows), newline-delimited JSON,
4
- // one request per connection. Each terminal session holds a random token bound to its caller, its
5
- // connected-apps grant, and its controller; the token stops working when the terminal ends.
6
- import { createHash, randomBytes } from 'node:crypto'
7
- import { chmodSync, mkdirSync, rmSync, statSync } from 'node:fs'
8
- import { createServer, type Server, type Socket } from 'node:net'
9
- import { tmpdir } from 'node:os'
10
- import { dirname, join } from 'node:path'
11
-
12
- import { log } from '../core/bus'
13
- import { HarnessError, toErrorShape } from '../core/errors'
14
- import { newId } from '../core/fs'
15
- import type { BrokerSession } from '../mcp/service'
16
- import type { CallerContext } from '../memory/caller'
17
-
18
- /** What a token stands for. */
19
- export interface SocketGrant {
20
- sessionId: string
21
- /** Who memory, Wiki, and recall calls are made as. The run is filled in while a turn is live. */
22
- caller: () => CallerContext
23
- /** The session's connected-apps grant, when it has one. */
24
- broker: BrokerSession | null
25
- /** Telemetry from the native process, and what to do when it hangs up mid-request. */
26
- terminal?: { accept(event: string, data: Record<string, unknown>): Promise<unknown>; disconnected(): void; control?(call: string, data: Record<string, unknown>): unknown }
27
- }
28
-
29
- export interface SocketHandlers {
30
- /** `wiki.*`, `memory.*`, `recall.*`. */
31
- memory(caller: CallerContext, call: string, params: Record<string, unknown>): string
32
- /** `mcp.list`, `mcp.call`, `mcp.revision`, `tools.list`, `tools.call`. */
33
- apps(session: BrokerSession, call: string, params: Record<string, unknown>): Promise<unknown>
34
- /**
35
- * `plugins.*`. `control` is true only for the session's own extension, which holds a key the
36
- * session's shell never sees; anything that changes what loads needs it.
37
- */
38
- plugins?(grant: SocketGrant, call: string, params: Record<string, unknown>, control: boolean): Promise<unknown>
39
- /** `accounts.*`. Every call needs `control`: adding, signing in, or removing an account is a person's choice. */
40
- accounts?(grant: SocketGrant, call: string, params: Record<string, unknown>, control: boolean): Promise<unknown>
41
- }
42
-
43
- const MAX_REQUEST_BYTES = 1024 * 1024
44
- /** macOS refuses a socket path longer than 103 bytes. */
45
- const MAX_SOCKET_PATH = 100
46
-
47
- /**
48
- * Windows has no socket files for Node's `net`: it listens on a named pipe, which lives in a
49
- * machine-wide namespace. A random name keeps another local process from guessing it and standing
50
- * in front of the session; the token still decides what a caller may do.
51
- */
52
- export function socketPath(stateDir: string): string {
53
- if (process.platform === 'win32') return `\\\\.\\pipe\\xingular-harness-${randomBytes(12).toString('hex')}`
54
- const path = join(stateDir, 'run', 'harness.sock')
55
- if (Buffer.byteLength(path) <= MAX_SOCKET_PATH) return path
56
- return join(tmpdir(), `xh-${createHash('sha256').update(path).digest('hex').slice(0, 16)}.sock`)
57
- }
58
-
59
- /** A named pipe has no folder, file mode, or owner to check or clean up. */
60
- const isPipePath = (path: string): boolean => path.startsWith('\\\\.\\pipe\\')
61
-
62
- /** Names the folder and the user when the operating system refuses the socket, so the cause shows. */
63
- function refusedBind(path: string, error: unknown): unknown {
64
- const code = (error as { code?: unknown } | null)?.code
65
- if (code !== 'EACCES' && code !== 'EPERM') return error
66
- if (isPipePath(path)) {
67
- return new HarnessError(
68
- 'session_socket_denied',
69
- `The session pipe ${path} could not be created (${code}).`,
70
- 'Start the harness again from your own user session. If it keeps failing, report this code and the Windows version.'
71
- )
72
- }
73
- let folder: string
74
- try {
75
- const stat = statSync(dirname(path))
76
- folder = `${dirname(path)} is owned by uid ${stat.uid} with mode ${(stat.mode & 0o777).toString(8)}`
77
- } catch {
78
- folder = `${dirname(path)} could not be read`
79
- }
80
- const uid = process.getuid?.() ?? 'unknown'
81
- return new HarnessError(
82
- 'session_socket_denied',
83
- `The session socket ${path} could not be created (${code}). ${folder}; this process runs as uid ${uid}.`,
84
- 'Run the harness from your own terminal, as the user that owns its state folder, or choose a state folder you own with --state.'
85
- )
86
- }
87
-
88
- export class SessionSocket {
89
- private server: Server | null = null
90
- private listening: Promise<void> | null = null
91
- private readonly grants = new Map<string, SocketGrant>()
92
- /**
93
- * A second key per token, handed out once. The token is in the session's environment, where a
94
- * command the model runs can read it; this key is claimed by the session's extension as it
95
- * loads, before any model turn, and kept in its memory only.
96
- */
97
- private readonly controls = new Map<string, string>()
98
- private readonly clients = new Set<Socket>()
99
-
100
- constructor(
101
- readonly path: string,
102
- private readonly handlers: SocketHandlers
103
- ) {}
104
-
105
- issue(grant: SocketGrant): string {
106
- const token = `${newId()}${newId()}`.replaceAll('-', '')
107
- this.grants.set(token, grant)
108
- return token
109
- }
110
-
111
- revoke(token: string): void {
112
- this.grants.delete(token)
113
- this.controls.delete(token)
114
- }
115
-
116
- revokeSession(sessionId: string): void {
117
- for (const [token, grant] of this.grants) if (grant.sessionId === sessionId) this.revoke(token)
118
- }
119
-
120
- /** Runs one request line and returns the reply line's object. */
121
- async handle(line: string, connection?: { waiting: (grant: SocketGrant | null) => void }): Promise<{ result: unknown } | { error: unknown }> {
122
- try {
123
- let request: Record<string, unknown>
124
- try {
125
- request = JSON.parse(line) as Record<string, unknown>
126
- } catch {
127
- throw new HarnessError('invalid_request', 'The request is not JSON.')
128
- }
129
- const token = typeof request.token === 'string' ? request.token : ''
130
- const grant = this.grants.get(token)
131
- if (!grant) throw new HarnessError('unauthorized', 'This session token is not valid. It ends when its terminal session ends.')
132
- if (typeof request.event === 'string') {
133
- if (!grant.terminal) throw new HarnessError('unknown_method', 'This session has no terminal controller.')
134
- connection?.waiting(grant)
135
- try {
136
- return { result: (await grant.terminal.accept(request.event, (request.data ?? {}) as Record<string, unknown>)) ?? {} }
137
- } finally {
138
- connection?.waiting(null)
139
- }
140
- }
141
- const call = typeof request.call === 'string' ? request.call : ''
142
- const params = (request.params && typeof request.params === 'object' ? request.params : {}) as Record<string, unknown>
143
- if (['wiki.', 'memory.', 'recall.'].some((prefix) => call.startsWith(prefix))) return { result: this.handlers.memory(grant.caller(), call, params) }
144
- if (['mcp.', 'tools.'].some((prefix) => call.startsWith(prefix))) {
145
- if (!grant.broker) throw new HarnessError('mcp_unauthorized', 'Connected apps are not available to this session.')
146
- return { result: await this.handlers.apps(grant.broker, call, params) }
147
- }
148
- if (call === 'control.claim') {
149
- if (this.controls.has(token)) throw new HarnessError('unauthorized', "This session's control key was already claimed.")
150
- const key = `${newId()}${newId()}`.replaceAll('-', '')
151
- this.controls.set(token, key)
152
- return { result: { key } }
153
- }
154
- if (call.startsWith('terminal.') && grant.terminal?.control) {
155
- const key = this.controls.get(token)
156
- if (!key || request.control !== key) throw new HarnessError('unauthorized', 'Only a person at this terminal can answer decisions or change its draft state.')
157
- return { result: await grant.terminal.control(call, params) }
158
- }
159
- if ((call.startsWith('plugins.') || call.startsWith('hub.')) && this.handlers.plugins) {
160
- const key = this.controls.get(token)
161
- return { result: await this.handlers.plugins(grant, call, params, key !== undefined && request.control === key) }
162
- }
163
- if (call.startsWith('accounts.') && this.handlers.accounts) {
164
- const key = this.controls.get(token)
165
- return { result: await this.handlers.accounts(grant, call, params, key !== undefined && request.control === key) }
166
- }
167
- throw new HarnessError('unknown_method', `Unknown call ${call}.`)
168
- } catch (error) {
169
- return { error: toErrorShape(error) }
170
- }
171
- }
172
-
173
- private serve(client: Socket): void {
174
- let buffer = ''
175
- let waiting: SocketGrant | null = null
176
- this.clients.add(client)
177
- client.on('error', () => {})
178
- client.once('close', () => {
179
- this.clients.delete(client)
180
- // A decision the native process was waiting on can no longer reach it.
181
- waiting?.terminal?.disconnected()
182
- })
183
- client.on('data', (chunk) => {
184
- buffer += chunk.toString('utf8')
185
- if (Buffer.byteLength(buffer) > MAX_REQUEST_BYTES) {
186
- client.destroy()
187
- return
188
- }
189
- const newline = buffer.indexOf('\n')
190
- if (newline < 0) return
191
- client.pause()
192
- void this.handle(buffer.slice(0, newline), { waiting: (grant) => void (waiting = grant) }).then((reply) => client.end(`${JSON.stringify(reply)}\n`))
193
- })
194
- }
195
-
196
- /** Binds the socket once; later calls wait for the same bind. */
197
- listen(): Promise<void> {
198
- this.listening ??= new Promise<void>((resolve, reject) => {
199
- if (!isPipePath(this.path)) {
200
- mkdirSync(dirname(this.path), { recursive: true, mode: 0o700 })
201
- rmSync(this.path, { force: true })
202
- }
203
- const server = createServer((client) => this.serve(client))
204
- server.once('error', (error) => {
205
- this.listening = null
206
- reject(refusedBind(this.path, error))
207
- })
208
- server.listen(this.path, () => {
209
- if (!isPipePath(this.path)) {
210
- try {
211
- chmodSync(this.path, 0o600)
212
- } catch (error) {
213
- log('session socket permissions', error instanceof Error ? error.message : String(error))
214
- }
215
- }
216
- this.server = server
217
- resolve()
218
- })
219
- })
220
- return this.listening
221
- }
222
-
223
- async close(): Promise<void> {
224
- this.grants.clear()
225
- const server = this.server
226
- this.server = null
227
- this.listening = null
228
- for (const client of this.clients) client.destroy()
229
- if (server) await new Promise<void>((resolve) => server.close(() => resolve()))
230
- if (!isPipePath(this.path)) rmSync(this.path, { force: true })
231
- }
232
- }
@@ -1,167 +0,0 @@
1
- import { EventEmitter } from 'node:events'
2
- import { createHash } from 'node:crypto'
3
- import { existsSync, mkdtempSync, rmSync } from 'node:fs'
4
- import { tmpdir } from 'node:os'
5
- import { join, resolve } from 'node:path'
6
- import type { ChildProcess, spawn as nodeSpawn } from 'node:child_process'
7
- import { afterEach, describe, expect, it, vi } from 'vitest'
8
-
9
- import { memorySecretStore } from '../accounts/secrets'
10
- import { createHarness, type Harness, type HarnessOptions } from '../harness'
11
- import { defaultAssets } from './terminals'
12
- import { parseStandaloneOptions, runStandaloneTerminal, standaloneArguments } from './standalone'
13
- import { socketPath } from './socket'
14
- import { SOCKET_ENV, TOKEN_ENV, socketCall } from './client'
15
-
16
- const scratch: string[] = []
17
- const harnesses: Harness[] = []
18
-
19
- afterEach(async () => {
20
- for (const harness of harnesses.splice(0)) await harness.close()
21
- for (const path of scratch.splice(0)) rmSync(path, { recursive: true, force: true })
22
- vi.restoreAllMocks()
23
- })
24
-
25
- function temporaryDirectory(prefix: string): string {
26
- const path = mkdtempSync(join(tmpdir(), prefix))
27
- scratch.push(path)
28
- return path
29
- }
30
-
31
- function fakeSpawn(onSpawn: (program: string, args: string[], options: { cwd?: string; env?: NodeJS.ProcessEnv; stdio?: string }) => void, outcome: { code?: number; error?: Error } = {}): typeof nodeSpawn {
32
- return ((program: string, args: string[], options: { cwd?: string; env?: NodeJS.ProcessEnv; stdio?: string }) => {
33
- onSpawn(program, args, options)
34
- const child = new EventEmitter() as ChildProcess
35
- child.kill = vi.fn(() => true)
36
- queueMicrotask(() => {
37
- if (outcome.error) child.emit('error', outcome.error)
38
- else child.emit('exit', outcome.code ?? 0, null)
39
- })
40
- return child
41
- }) as unknown as typeof nodeSpawn
42
- }
43
-
44
- function harnessFactory(options: HarnessOptions): Harness {
45
- const harness = createHarness({ ...options, secrets: memorySecretStore(), piProgram: () => '/opt/pi/bin/pi' })
46
- harnesses.push(harness)
47
- return harness
48
- }
49
-
50
- describe('standalone terminal startup', () => {
51
- it('routes the no-command and terminal invocations to Pi, leaving host commands explicit', () => {
52
- expect(standaloneArguments([])).toEqual([])
53
- expect(standaloneArguments(['--data', '/tmp/data'])).toEqual(['--data', '/tmp/data'])
54
- expect(standaloneArguments(['terminal', '--state', '/tmp/state'])).toEqual(['--state', '/tmp/state'])
55
- expect(standaloneArguments(['serve', '--state', '/tmp/state'])).toBeNull()
56
- })
57
-
58
- it('uses a dedicated default data and state root and accepts path overrides', () => {
59
- expect(parseStandaloneOptions([], '/home/test', '/work/project')).toEqual({
60
- dataRoot: '/home/test/.xingular-harness/data',
61
- stateDir: '/home/test/.xingular-harness/state'
62
- })
63
- expect(parseStandaloneOptions(['--data', './knowledge', '--state', './device'], '/home/test', '/work/project')).toEqual({
64
- dataRoot: '/work/project/knowledge',
65
- stateDir: '/work/project/device'
66
- })
67
- expect(() => parseStandaloneOptions(['--data'])).toThrow('--data needs a directory path.')
68
- expect(() => parseStandaloneOptions(['--model', 'unknown'])).toThrow('Unknown standalone option: --model')
69
- })
70
-
71
- it('refuses default folders under a home that is not a folder path, and accepts explicit absolute folders', () => {
72
- expect(() => parseStandaloneOptions([], 'HOME', '/work/project')).toThrow('is not an absolute path')
73
- expect(parseStandaloneOptions(['--data', '/data', '--state', '/state'], 'HOME', '/work/project')).toEqual({ dataRoot: '/data', stateDir: '/state' })
74
- })
75
-
76
- it('starts Pi in the current directory, creates the first isolated account, and cleans up on exit', async () => {
77
- const home = temporaryDirectory('harness-standalone-')
78
- const cwd = temporaryDirectory('harness-cwd-')
79
- const paths = parseStandaloneOptions([], home)
80
- let invocation: { program: string; args: string[]; options: { cwd?: string; env?: NodeJS.ProcessEnv; stdio?: string } } | undefined
81
- const spawn = fakeSpawn((program, args, options) => {
82
- invocation = { program, args, options }
83
- })
84
-
85
- expect(await runStandaloneTerminal([], { home, cwd, stdinIsTTY: true, stdoutIsTTY: true, createSessionId: () => 'standalone', createHarness: harnessFactory, spawn })).toBe(0)
86
-
87
- const harness = harnesses.shift()!
88
- expect(harness.accounts.overview().accounts).toMatchObject([{ label: 'Default', isDefault: true }])
89
- expect(invocation?.program).toBe('/opt/pi/bin/pi')
90
- expect(invocation?.options).toMatchObject({ cwd, stdio: 'inherit' })
91
- expect(invocation?.args).toContain('--extension')
92
- expect(invocation?.args).toContain(defaultAssets().piExtension)
93
- expect(invocation?.args).toContain(join(paths.dataRoot, 'sessions', 'terminal', createHash('sha256').update(resolve(cwd)).digest('hex'), 'pi'))
94
- expect(invocation?.options.env?.PI_CODING_AGENT_DIR).toContain(join(paths.stateDir, 'accounts'))
95
- expect(invocation?.options.env?.XINGULAR_HARNESS_SOCKET).toBeTruthy()
96
- expect(invocation?.options.env?.XINGULAR_HARNESS_TOKEN).toBeTruthy()
97
- expect(existsSync(join(paths.stateDir, 'accounts', harness.accounts.overview().accounts[0].id, 'home', 'pi', 'auth.json'))).toBe(false)
98
- expect(existsSync(socketPath(paths.stateDir))).toBe(false)
99
- expect(harness.terminals.has('standalone')).toBe(false)
100
- })
101
-
102
- it('requires an interactive TTY before creating Harness data', async () => {
103
- const create = vi.fn(harnessFactory)
104
- await expect(runStandaloneTerminal([], { stdinIsTTY: false, stdoutIsTTY: true, createHarness: create })).rejects.toThrow('needs a TTY')
105
- expect(create).not.toHaveBeenCalled()
106
- })
107
-
108
- it('cleans up the prepared terminal when Pi cannot be spawned', async () => {
109
- const home = temporaryDirectory('harness-standalone-fail-')
110
- const cwd = temporaryDirectory('harness-cwd-fail-')
111
- const spawn = fakeSpawn(() => undefined, { error: new Error('spawn failed') })
112
-
113
- await expect(runStandaloneTerminal([], { home, cwd, stdinIsTTY: true, stdoutIsTTY: true, createSessionId: () => 'failed', createHarness: harnessFactory, spawn })).rejects.toThrow('spawn failed')
114
-
115
- const harness = harnesses.shift()!
116
- const account = harness.accounts.overview().accounts[0]
117
- expect(existsSync(join(harness.accounts.dir, account.id, 'home', 'pi', 'auth.json'))).toBe(false)
118
- expect(existsSync(socketPath(harness.stateDir))).toBe(false)
119
- expect(harness.terminals.has('failed')).toBe(false)
120
- })
121
-
122
- it('explains a missing Pi executable in terms of the terminal launch', async () => {
123
- const home = temporaryDirectory('harness-standalone-enoent-')
124
- const cwd = temporaryDirectory('harness-cwd-enoent-')
125
- const error = Object.assign(new Error('spawn /opt/pi/bin/pi ENOENT'), { code: 'ENOENT' })
126
- const spawn = fakeSpawn(() => undefined, { error })
127
-
128
- await expect(runStandaloneTerminal([], { home, cwd, stdinIsTTY: true, stdoutIsTTY: true, createSessionId: () => 'missing-pi', createHarness: harnessFactory, spawn }))
129
- .rejects.toThrow(/Could not start Pi terminal.*Pi executable.*\/opt\/pi\/bin\/pi/)
130
- })
131
- })
132
-
133
- describe('switching the account of a running terminal', () => {
134
- it('ends Pi when the person asks for another account, and starts it again on that account', async () => {
135
- const home = temporaryDirectory('harness-switch-')
136
- const cwd = temporaryDirectory('harness-switch-cwd-')
137
- const paths = parseStandaloneOptions([], home)
138
- const spawned: { args: string[]; env: NodeJS.ProcessEnv }[] = []
139
- let spareId = ''
140
- const spawn = ((_program: string, args: string[], options: { cwd?: string; env?: NodeJS.ProcessEnv; stdio?: string }) => {
141
- spawned.push({ args, env: options.env ?? {} })
142
- const child = new EventEmitter() as ChildProcess
143
- child.kill = vi.fn(() => true)
144
- void (async () => {
145
- // Deferred, as a real process is: the launcher attaches its listeners after spawn returns.
146
- await Promise.resolve()
147
- if (spawned.length === 1) {
148
- // The first Pi asks for the other account through its own extension, then ends.
149
- spareId = harnesses[0].accounts.create('Spare', 'apiKey').accounts.find((account) => account.label === 'Spare')!.id
150
- const connection = { socket: options.env![SOCKET_ENV]!, token: options.env![TOKEN_ENV]! }
151
- const { key } = await socketCall<{ key: string }>(connection, 'control.claim')
152
- await socketCall(connection, 'accounts.relaunch', { accountId: spareId }, 5_000, key)
153
- }
154
- child.emit('exit', 0, null)
155
- })()
156
- return child
157
- }) as unknown as typeof nodeSpawn
158
-
159
- expect(await runStandaloneTerminal([], { home, cwd, stdinIsTTY: true, stdoutIsTTY: true, createHarness: harnessFactory, spawn })).toBe(0)
160
-
161
- expect(spawned).toHaveLength(2)
162
- expect(spawned[1].env.PI_CODING_AGENT_DIR).toContain(join(paths.stateDir, 'accounts', spareId))
163
- expect(spawned[1].env[TOKEN_ENV]).not.toBe(spawned[0].env[TOKEN_ENV])
164
- // The session it ended is closed; nothing is left running in the harness.
165
- expect(harnesses[0].terminals.has('standalone')).toBe(false)
166
- })
167
- })
@@ -1,153 +0,0 @@
1
- // The standalone host prepares an isolated Harness terminal and supervises its frontend.
2
- import { spawn as nodeSpawn } from 'node:child_process'
3
- import { createHash, randomUUID } from 'node:crypto'
4
- import { homedir } from 'node:os'
5
- import { isAbsolute, join, resolve } from 'node:path'
6
-
7
- import { createHarness, type Harness, type HarnessOptions } from '../harness'
8
- import type { TerminalLaunch } from './terminals'
9
-
10
- export interface StandalonePaths {
11
- dataRoot: string
12
- stateDir: string
13
- }
14
-
15
- export interface StandaloneDependencies {
16
- home?: string
17
- cwd?: string
18
- stdinIsTTY?: boolean
19
- stdoutIsTTY?: boolean
20
- createSessionId?: () => string
21
- createHarness?: (options: HarnessOptions) => Harness
22
- spawn?: typeof nodeSpawn
23
- }
24
-
25
- export function standaloneArguments(argv: string[]): string[] | null {
26
- const command = argv[0]
27
- if (!command || command.startsWith('--') || command === '-h') return argv
28
- return command === 'terminal' ? argv.slice(1) : null
29
- }
30
-
31
- export function parseStandaloneOptions(argv: string[], home = homedir(), cwd = process.cwd()): StandalonePaths {
32
- const root = join(home, '.xingular-harness')
33
- const paths: StandalonePaths = {
34
- dataRoot: join(root, 'data'),
35
- stateDir: join(root, 'state')
36
- }
37
-
38
- const given = new Set<string>()
39
- for (let index = 0; index < argv.length; index += 1) {
40
- const argument = argv[index]
41
- if (argument !== '--data' && argument !== '--state') throw new Error(`Unknown standalone option: ${argument}`)
42
- const value = argv[index + 1]
43
- if (!value || value.startsWith('--')) throw new Error(`${argument} needs a directory path.`)
44
- paths[argument === '--data' ? 'dataRoot' : 'stateDir'] = resolve(cwd, value)
45
- given.add(argument)
46
- index += 1
47
- }
48
-
49
- // A home that is not a folder path (for example HOME set to the word "HOME") would put the
50
- // defaults, and the session socket, in whatever folder the command was started from.
51
- if (!isAbsolute(home) && !(given.has('--data') && given.has('--state'))) {
52
- throw new Error(`The home folder "${home}" is not an absolute path, so the default data and state folders cannot be placed. Set HOME to your home folder, or pass --data and --state with absolute folders.`)
53
- }
54
-
55
- return paths
56
- }
57
-
58
- function processEnvironment(overrides: Record<string, string | null>): NodeJS.ProcessEnv {
59
- const environment = { ...process.env }
60
- for (const [name, value] of Object.entries(overrides)) {
61
- if (value === null) delete environment[name]
62
- else environment[name] = value
63
- }
64
- return environment
65
- }
66
-
67
- function exitCode(code: number | null, signal: NodeJS.Signals | null): number {
68
- if (code !== null) return code
69
- if (signal === 'SIGINT') return 130
70
- if (signal === 'SIGTERM') return 143
71
- if (signal === 'SIGHUP') return 129
72
- return 1
73
- }
74
-
75
- function spawnError(error: Error, launch: TerminalLaunch): Error {
76
- const code = (error as NodeJS.ErrnoException).code
77
- if (code !== 'ENOENT' && code !== 'EACCES' && code !== 'EPERM') return error
78
- if (launch.program === process.execPath || launch.env.XINGULAR_HARNESS_NODE === launch.program) {
79
- return new Error(`Could not start the Harness terminal because Node could not run "${launch.args[0] ?? 'the bundled Harness CLI'}" (${code}). Verify Node and the Harness package are installed.`, { cause: error })
80
- }
81
- const problem = code === 'ENOENT' ? 'was not found' : `could not start (${code})`
82
- return new Error(`Could not start Pi terminal. Pi executable "${launch.program}" ${problem}; verify it is installed and executable or check the configured terminal executable.`, { cause: error })
83
- }
84
-
85
- function spawnPi(launch: TerminalLaunch, cwd: string, spawn = nodeSpawn): Promise<number> {
86
- return new Promise((resolveExit, reject) => {
87
- const child = spawn(launch.program, launch.args, {
88
- cwd,
89
- env: processEnvironment(launch.env),
90
- stdio: 'inherit'
91
- })
92
- let settled = false
93
- const cleanup = (): void => {
94
- process.off('SIGINT', onInterrupt)
95
- process.off('SIGTERM', onTerminate)
96
- process.off('SIGHUP', onHangup)
97
- }
98
- const finish = (action: () => void): void => {
99
- if (settled) return
100
- settled = true
101
- cleanup()
102
- action()
103
- }
104
- // Ctrl+C is delivered to both processes in the foreground process group. Keep this host
105
- // alive while Pi handles it so the account credentials and harness socket are cleaned up.
106
- const onInterrupt = (): void => undefined
107
- const onTerminate = (): void => {
108
- child.kill('SIGTERM')
109
- }
110
- const onHangup = (): void => undefined
111
-
112
- process.on('SIGINT', onInterrupt)
113
- process.on('SIGTERM', onTerminate)
114
- process.on('SIGHUP', onHangup)
115
- child.once('error', (error) => finish(() => reject(spawnError(error, launch))))
116
- child.once('exit', (code, signal) => finish(() => resolveExit(exitCode(code, signal))))
117
- })
118
- }
119
-
120
- export async function runStandaloneTerminal(argv: string[], dependencies: StandaloneDependencies = {}): Promise<number> {
121
- if (!(dependencies.stdinIsTTY ?? process.stdin.isTTY) || !(dependencies.stdoutIsTTY ?? process.stdout.isTTY)) {
122
- throw new Error('The interactive Harness terminal needs a TTY. Run it from a terminal, or use `xingular-harness serve` for a host process.')
123
- }
124
-
125
- const cwd = resolve(dependencies.cwd ?? process.cwd())
126
- const paths = parseStandaloneOptions(argv, dependencies.home, cwd)
127
- const makeHarness = dependencies.createHarness ?? createHarness
128
- const harness = makeHarness({ dataRoot: paths.dataRoot, stateDir: paths.stateDir, productName: 'Xingular Harness' })
129
- const newSessionId = dependencies.createSessionId ?? randomUUID
130
- let current = { sessionId: newSessionId(), accountId: null as string | null, nativeSessionId: null as string | null }
131
-
132
- try {
133
- await harness.ready
134
- if (harness.accounts.overview().accounts.length === 0) harness.accounts.create('Default', 'subscription')
135
-
136
- const cwdHash = createHash('sha256').update(cwd).digest('hex')
137
- const sessionFolder = join(paths.dataRoot, 'sessions', 'terminal', cwdHash)
138
- for (;;) {
139
- const launch = await harness.terminals.prepare({ ...current, cwd, sessionFolder })
140
- const code = await spawnPi(launch, cwd, dependencies.spawn)
141
- // `/accounts` asks for a switch and ends Pi. The conversation resumes on the chosen account.
142
- const next = harness.terminals.takeRelaunch(current.sessionId)
143
- if (!next) return code
144
- const label = harness.accounts.find(next.accountId).label
145
- process.stdout.write(`Switching this session to account ${label}.\n`)
146
- await harness.terminals.dispose(current.sessionId)
147
- current = { sessionId: newSessionId(), accountId: next.accountId, nativeSessionId: next.nativeSessionId }
148
- }
149
- } finally {
150
- await harness.terminals.dispose(current.sessionId)
151
- await harness.close()
152
- }
153
- }