@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,95 +0,0 @@
1
- import { existsSync, lstatSync, linkSync, mkdirSync, mkdtempSync, readdirSync, readFileSync, readlinkSync, symlinkSync, writeFileSync } from 'node:fs'
2
- import { tmpdir } from 'node:os'
3
- import { join } from 'node:path'
4
- import { expect, test } from 'vitest'
5
-
6
- import { configDir, ensureSharedDir, linkSharedEntries, sharedDir, type EntryLinker } from './env'
7
-
8
- const temp = () => mkdtempSync(join(tmpdir(), 'harness-env-'))
9
- const refused = (code = 'EPERM') => Object.assign(new Error(`${code}: operation not permitted, symlink`), { code })
10
- const backups = (folder: string) => readdirSync(folder).filter((name) => name.includes('xagent-backup') || name.includes('agentx-backup'))
11
-
12
- // A Windows account without the symlink privilege: file symlinks are refused, junctions and hard links work.
13
- const windowsLike: EntryLinker = {
14
- symlink: (target, path, isDir) => {
15
- if (!isDir) throw refused()
16
- symlinkSync(target, path)
17
- },
18
- hardLink: (target, path) => linkSync(target, path)
19
- }
20
-
21
- const refusesAll: EntryLinker = {
22
- symlink: () => {
23
- throw refused()
24
- },
25
- hardLink: () => {
26
- throw refused()
27
- }
28
- }
29
-
30
- test('without the symlink privilege, files are hard-linked and folders are junctioned', () => {
31
- const dir = temp()
32
- const home = configDir(dir, { id: 'acc1' })
33
- mkdirSync(home, { recursive: true })
34
- writeFileSync(join(home, 'settings.json'), '{"theme":"dark"}')
35
-
36
- const first = linkSharedEntries(dir, { id: 'acc1' }, windowsLike)
37
- const shared = join(sharedDir(dir), 'settings.json')
38
- expect(first.entries.find((entry) => entry.name === 'settings.json')).toEqual({ name: 'settings.json', state: 'linked' })
39
- expect(lstatSync(join(home, 'settings.json')).ino).toBe(lstatSync(shared).ino)
40
- expect(lstatSync(join(home, 'settings.json')).isSymbolicLink()).toBe(false)
41
- expect(lstatSync(join(home, 'skills')).isSymbolicLink()).toBe(true)
42
-
43
- // Entries with no shared copy yet cannot be hard-linked, so they stay the account's own.
44
- expect(first.entries.find((entry) => entry.name === 'AGENTS.md')).toMatchObject({ state: 'unshared' })
45
-
46
- // A second launch finds the links in place and moves nothing aside.
47
- const second = linkSharedEntries(dir, { id: 'acc1' }, windowsLike)
48
- expect(second.entries.find((entry) => entry.name === 'settings.json')?.state).toBe('linked')
49
- expect(second.entries.find((entry) => entry.name === 'skills')?.state).toBe('linked')
50
- expect(backups(home)).toEqual([])
51
- expect(backups(sharedDir(dir))).toEqual([])
52
- expect(readFileSync(join(home, 'settings.json'), 'utf8')).toBe('{"theme":"dark"}')
53
- })
54
-
55
- test('when links are refused, the account keeps its own settings', () => {
56
- const dir = temp()
57
- const home = configDir(dir, { id: 'acc1' })
58
- mkdirSync(home, { recursive: true })
59
- writeFileSync(join(home, 'settings.json'), '{"mine":true}')
60
-
61
- const { entries } = linkSharedEntries(dir, { id: 'acc1' }, refusesAll)
62
- expect(entries.find((entry) => entry.name === 'settings.json')).toEqual({ name: 'settings.json', state: 'unshared', reason: 'EPERM' })
63
- expect(readFileSync(join(home, 'settings.json'), 'utf8')).toBe('{"mine":true}')
64
- expect(existsSync(join(sharedDir(dir), 'settings.json'))).toBe(false)
65
- expect(backups(home)).toEqual([])
66
- })
67
-
68
- test('when links are refused, a shared file the account lacks is copied in and stays put', () => {
69
- const dir = temp()
70
- writeFileSync(join(ensureSharedDir(dir), 'settings.json'), '{"shared":true}')
71
- const home = configDir(dir, { id: 'acc2' })
72
-
73
- const first = linkSharedEntries(dir, { id: 'acc2' }, refusesAll)
74
- expect(readFileSync(join(home, 'settings.json'), 'utf8')).toBe('{"shared":true}')
75
- expect(first.entries.find((entry) => entry.name === 'settings.json')?.state).toBe('unshared')
76
-
77
- const second = linkSharedEntries(dir, { id: 'acc2' }, refusesAll)
78
- expect(second.entries.find((entry) => entry.name === 'settings.json')?.state).toBe('unshared')
79
- expect(readFileSync(join(home, 'settings.json'), 'utf8')).toBe('{"shared":true}')
80
- expect(backups(home)).toEqual([])
81
- expect(backups(sharedDir(dir))).toEqual([])
82
- })
83
-
84
- test('a refused link leaves the account\'s existing link as it was', () => {
85
- const dir = temp()
86
- const home = configDir(dir, { id: 'acc3' })
87
- mkdirSync(home, { recursive: true })
88
- const elsewhere = join(temp(), 'skills')
89
- mkdirSync(elsewhere)
90
- symlinkSync(elsewhere, join(home, 'skills'))
91
-
92
- const { entries } = linkSharedEntries(dir, { id: 'acc3' }, refusesAll)
93
- expect(entries.find((entry) => entry.name === 'skills')?.state).toBe('unshared')
94
- expect(readlinkSync(join(home, 'skills'))).toBe(elsewhere)
95
- })
@@ -1,338 +0,0 @@
1
- // Isolated launch environments. Every Pi session the harness starts gets its account's own
2
- // agent folder (`PI_CODING_AGENT_DIR`) under the state directory, and inherited credential
3
- // variables are removed. A launch that would fall back to `~/.pi` is refused.
4
- //
5
- // Settings, skills, prompts, and instructions are shared by every account: the account's agent
6
- // folder links those entries to `_shared/pi/`. Where the system refuses a link (Windows without
7
- // the symlink privilege), the entry stays the account's own, and a shared file is copied in so
8
- // its settings still load. Credentials, sessions, and history stay in the account's own folder.
9
- import { chmodSync, copyFileSync, linkSync, lstatSync, mkdirSync, readlinkSync, renameSync, rmdirSync, statSync, symlinkSync, unlinkSync, utimesSync } from 'node:fs'
10
- import { homedir } from 'node:os'
11
- import { basename, dirname, join, resolve, sep } from 'node:path'
12
-
13
- import { HarnessError } from '../core/errors'
14
- import type { Account } from './store'
15
-
16
- // Config-directory variables the harness always sets itself, including those of other tools so
17
- // a session can never inherit them.
18
- const DIR_VARS = ['CODEX_HOME', 'CLAUDE_CONFIG_DIR', 'PI_CODING_AGENT_DIR']
19
-
20
- /** Inherited variables that carry credentials; they would bypass the account's own sign-in. */
21
- export function isCredentialVar(name: string): boolean {
22
- const upper = name.toUpperCase()
23
- return DIR_VARS.includes(upper) || ['_API_KEY', '_AUTH_TOKEN', '_OAUTH_TOKEN', '_ACCESS_TOKEN'].some((suffix) => upper.endsWith(suffix))
24
- }
25
-
26
- /** Names of inherited variables to remove from a session's process. */
27
- export function inheritedCredentialVars(env: NodeJS.ProcessEnv = process.env): string[] {
28
- const names = Object.keys(env).filter(isCredentialVar)
29
- for (const name of DIR_VARS) if (!names.includes(name)) names.push(name)
30
- return names
31
- }
32
-
33
- /**
34
- * Makes this process safe to run Pi sessions in: credentials come only from an account's own
35
- * store, so inherited credential variables are dropped, and Pi's fallback agent folder is an
36
- * empty one under the state directory rather than `~/.pi`.
37
- */
38
- export function isolateProcess(accountsDir: string, env: NodeJS.ProcessEnv = process.env): void {
39
- for (const name of inheritedCredentialVars(env)) delete env[name]
40
- const fallback = join(accountsDir, '.sidecar', 'pi')
41
- mkdirSync(fallback, { recursive: true })
42
- env.PI_CODING_AGENT_DIR = fallback
43
- }
44
-
45
- export const homeDir = (accountsDir: string, accountId: string): string => join(accountsDir, accountId, 'home')
46
- /** Pi's agent folder for this account. */
47
- export const configDir = (accountsDir: string, account: Pick<Account, 'id'>): string => join(homeDir(accountsDir, account.id), 'pi')
48
- /** The agent-folder entries every account shares. */
49
- export const sharedDir = (accountsDir: string): string => join(accountsDir, '_shared', 'pi')
50
-
51
- function makePrivate(path: string): void {
52
- mkdirSync(path, { recursive: true })
53
- chmodSync(path, 0o700)
54
- }
55
-
56
- // Entries every account shares, and whether each is a folder. Credentials (`auth.json`),
57
- // sessions, and history are never listed.
58
- const SHARED_ENTRIES: readonly (readonly [string, boolean])[] = [
59
- ['settings.json', false],
60
- ['models.json', false],
61
- ['AGENTS.md', false],
62
- ['SYSTEM.md', false],
63
- ['skills', true],
64
- ['prompts', true],
65
- ['extensions', true],
66
- ['themes', true],
67
- // Where Pi keeps installed packages: one install serves every account.
68
- ['npm', true],
69
- ['git', true]
70
- ]
71
-
72
- export interface NativeConfig {
73
- provider: string
74
- path: string
75
- entries: { name: string; directory: boolean; present: boolean }[]
76
- }
77
-
78
- const present = (path: string): boolean => {
79
- try {
80
- lstatSync(path)
81
- return true
82
- } catch {
83
- return false
84
- }
85
- }
86
-
87
- /** What the accounts share, and which of it exists yet. Reads only; nothing is created. */
88
- export function nativeConfig(accountsDir: string): NativeConfig {
89
- const shared = sharedDir(accountsDir)
90
- return { provider: 'pi', path: shared, entries: SHARED_ENTRIES.map(([name, directory]) => ({ name, directory, present: present(join(shared, name)) })) }
91
- }
92
-
93
- /** The shared folder, created private if no account has linked it yet. */
94
- export function ensureSharedDir(accountsDir: string): string {
95
- const shared = sharedDir(accountsDir)
96
- makePrivate(shared)
97
- return shared
98
- }
99
-
100
- const modified = (path: string): number => {
101
- try {
102
- return lstatSync(path).mtimeMs
103
- } catch {
104
- return -1
105
- }
106
- }
107
-
108
- /** Moves a real file or folder aside so the shared link can take its place; returns where it went. */
109
- function backUp(path: string): string {
110
- const backup = join(dirname(path), `${basename(path)}.xagent-backup-${Math.floor(Date.now() / 1000)}`)
111
- renameSync(path, backup)
112
- return backup
113
- }
114
-
115
- /**
116
- * How one shared entry is linked into an account folder. Windows refuses a symbolic link to a
117
- * user without the symlink privilege, so each kind has a fallback that needs none.
118
- */
119
- export interface EntryLinker {
120
- /** A symbolic link to a file, or a junction to a folder (junctions need no privilege on Windows). */
121
- symlink(target: string, path: string, isDir: boolean): void
122
- /** A hard link to a file on the same volume. */
123
- hardLink(target: string, path: string): void
124
- }
125
-
126
- const nodeLinker: EntryLinker = {
127
- symlink: (target, path, isDir) => symlinkSync(resolve(target), path, isDir ? 'junction' : 'file'),
128
- hardLink: (target, path) => linkSync(target, path)
129
- }
130
-
131
- const codeOf = (error: unknown): string => (error as NodeJS.ErrnoException).code ?? String(error)
132
- const PRIVILEGE_CODES = ['EPERM', 'EACCES']
133
-
134
- function createLink(target: string, path: string, isDir: boolean, linker: EntryLinker): void {
135
- try {
136
- linker.symlink(target, path, isDir)
137
- } catch (error) {
138
- // A file can still be hard-linked without the privilege; a folder has no such fallback.
139
- if (isDir || !PRIVILEGE_CODES.includes(codeOf(error))) throw error
140
- linker.hardLink(target, path)
141
- }
142
- }
143
-
144
- const isLink = (path: string): boolean => {
145
- try {
146
- return lstatSync(path).isSymbolicLink()
147
- } catch {
148
- return false
149
- }
150
- }
151
-
152
- // Windows reports some link targets with the `\\?\` prefix.
153
- const LONG_PREFIX = /^\\\\\?\\/
154
- function samePath(a: string, b: string): boolean {
155
- const normal = (path: string): string => {
156
- const full = resolve(path.replace(LONG_PREFIX, ''))
157
- return process.platform === 'win32' ? full.toLowerCase() : full
158
- }
159
- return normal(a) === normal(b)
160
- }
161
-
162
- /** A hard link is the same file on disk as its target, so it has the same device and inode. */
163
- function sameFile(a: string, b: string): boolean {
164
- try {
165
- const left = lstatSync(a)
166
- const right = lstatSync(b)
167
- return left.ino !== 0 && left.dev === right.dev && left.ino === right.ino
168
- } catch {
169
- return false
170
- }
171
- }
172
-
173
- function isLinkTo(path: string, target: string, isDir: boolean): boolean {
174
- try {
175
- const meta = lstatSync(path)
176
- if (meta.isSymbolicLink()) return samePath(readlinkSync(path), target)
177
- return !isDir && meta.isFile() && sameFile(path, target)
178
- } catch {
179
- return false
180
- }
181
- }
182
-
183
- /** Removes a link without touching what it points to. A Windows junction needs `rmdir`. */
184
- function removeLink(path: string, isDir: boolean): void {
185
- try {
186
- unlinkSync(path)
187
- } catch (error) {
188
- if (!isDir) throw error
189
- rmdirSync(path)
190
- }
191
- }
192
-
193
- /**
194
- * A file the account does not have, for an entry whose link was refused: a copy of the shared one
195
- * (with its time kept, so the newest-wins rule does not move it), so the account's settings load.
196
- */
197
- function keepCopy(target: string, path: string, isDir: boolean): void {
198
- if (isDir || present(path) || !present(target)) return
199
- try {
200
- copyFileSync(target, path)
201
- const { atime, mtime } = statSync(target)
202
- utimesSync(path, atime, mtime)
203
- } catch {
204
- // The account simply keeps no copy; its sign-in and its own files are not affected.
205
- }
206
- }
207
-
208
- /** What happened to one shared entry: linked to the shared copy, or left as the account's own. */
209
- export interface SharedEntry {
210
- name: string
211
- state: 'linked' | 'unshared'
212
- /** Why the link was refused, when it was. */
213
- reason?: string
214
- }
215
-
216
- /**
217
- * Links one entry to its shared copy. A real entry found in the account folder (from before
218
- * sharing, or a tool that replaced the link while saving) becomes the shared copy when there is
219
- * none or it is newer; otherwise it is kept as a backup. If the link is then refused, every move
220
- * is undone, so the account keeps what it had.
221
- */
222
- function linkOne(name: string, target: string, path: string, isDir: boolean, linker: EntryLinker): SharedEntry {
223
- if (isLinkTo(path, target, isDir)) {
224
- if (isDir) mkdirSync(target, { recursive: true })
225
- return { name, state: 'linked' }
226
- }
227
- const undo: (() => void)[] = []
228
- try {
229
- if (isLink(path)) {
230
- const previous = readlinkSync(path)
231
- removeLink(path, isDir)
232
- undo.push(() => nodeLinker.symlink(previous, path, isDir))
233
- } else if (present(path)) {
234
- if (!present(target)) {
235
- renameSync(path, target)
236
- undo.push(() => renameSync(target, path))
237
- } else if (!isDir && modified(path) > modified(target)) {
238
- const backup = backUp(target)
239
- undo.push(() => renameSync(backup, target))
240
- renameSync(path, target)
241
- undo.push(() => renameSync(target, path))
242
- } else {
243
- const backup = backUp(path)
244
- undo.push(() => renameSync(backup, path))
245
- }
246
- }
247
- if (isDir) mkdirSync(target, { recursive: true })
248
- createLink(target, path, isDir, linker)
249
- return { name, state: 'linked' }
250
- } catch (error) {
251
- for (const step of undo.reverse()) {
252
- try {
253
- step()
254
- } catch {
255
- // The entry stays where that step left it; nothing further can be restored safely.
256
- }
257
- }
258
- keepCopy(target, path, isDir)
259
- return { name, state: 'unshared', reason: codeOf(error) }
260
- }
261
- }
262
-
263
- /**
264
- * Creates the account's runtime folder and links the shared entries into it. Never throws for a
265
- * refused link: each entry is reported, and the account falls back to its own copy.
266
- */
267
- export function linkSharedEntries(accountsDir: string, account: Pick<Account, 'id'>, linker: EntryLinker = nodeLinker): { dir: string; entries: SharedEntry[] } {
268
- makePrivate(join(accountsDir, account.id))
269
- makePrivate(homeDir(accountsDir, account.id))
270
- const dir = configDir(accountsDir, account)
271
- makePrivate(dir)
272
- const shared = ensureSharedDir(accountsDir)
273
- const entries = SHARED_ENTRIES.map(([name, isDir]) => linkOne(name, join(shared, name), join(dir, name), isDir, linker))
274
- return { dir, entries }
275
- }
276
-
277
- /** Creates the account's runtime folder and links the shared entries into it. */
278
- export function ensureHome(accountsDir: string, account: Pick<Account, 'id'>): string {
279
- return linkSharedEntries(accountsDir, account).dir
280
- }
281
-
282
- const inside = (path: string, parent: string): boolean => path === parent || path.startsWith(parent.endsWith(sep) ? parent : `${parent}${sep}`)
283
-
284
- /**
285
- * Refuses an agent folder that is (or is inside) a default tool folder, or that is not inside
286
- * the harness's own accounts folder.
287
- */
288
- export function assertIsolated(accountsDir: string, dir: string): void {
289
- const defaults = ['.codex', '.claude', '.pi'].map((name) => join(homedir() || '/', name))
290
- if (defaults.some((folder) => inside(dir, folder)) || !inside(dir, accountsDir)) {
291
- throw new HarnessError('account_required', 'A session cannot start outside its isolated account folder.')
292
- }
293
- }
294
-
295
- function sessionEnv(dir: string, inherited: NodeJS.ProcessEnv): Record<string, string | null> {
296
- const env: Record<string, string | null> = {}
297
- for (const name of inheritedCredentialVars(inherited)) env[name] = null
298
- env.PI_CODING_AGENT_DIR = dir
299
- return env
300
- }
301
-
302
- /** Variables to set, or remove (`null`), when launching a session for this account. */
303
- export function launchEnv(accountsDir: string, account: Pick<Account, 'id'>, inherited: NodeJS.ProcessEnv = process.env): Record<string, string | null> {
304
- const dir = ensureHome(accountsDir, account)
305
- assertIsolated(accountsDir, dir)
306
- return sessionEnv(dir, inherited)
307
- }
308
-
309
- /** What a session needs to run for an account. */
310
- export interface AccountContext {
311
- id: string
312
- provider: 'pi'
313
- label: string
314
- /** Variables to set; `null` removes an inherited one. */
315
- env: Record<string, string | null>
316
- /** The account's own agent folder. */
317
- configDir: string
318
- /** Which shared entries are linked, and which the account keeps as its own. */
319
- sharing: SharedEntry[]
320
- }
321
-
322
- export function accountContext(accountsDir: string, account: Account): AccountContext {
323
- const { dir, entries } = linkSharedEntries(accountsDir, account)
324
- assertIsolated(accountsDir, dir)
325
- return { id: account.id, provider: 'pi', label: account.label, env: sessionEnv(dir, process.env), configDir: dir, sharing: entries }
326
- }
327
-
328
- /** The process environment for a `pi` process launched on behalf of this account. */
329
- export function processEnv(account: AccountContext, inherited: NodeJS.ProcessEnv = process.env): Record<string, string> {
330
- const env: Record<string, string> = {}
331
- for (const [name, value] of Object.entries(inherited)) if (value !== undefined) env[name] = value
332
- for (const [name, value] of Object.entries(account.env)) {
333
- if (value === null) delete env[name]
334
- else env[name] = value
335
- }
336
- return env
337
- }
338
-
@@ -1,50 +0,0 @@
1
- // Where credentials live. The harness never writes a secret to its own files: it asks the
2
- // store the embedding application provides (a Keychain, an encrypted vault), by key.
3
- import { chmodSync, mkdirSync } from 'node:fs'
4
- import { dirname } from 'node:path'
5
-
6
- import { atomicWrite, readJsonOr } from '../core/fs'
7
-
8
- export interface SecretStore {
9
- get(key: string): Promise<string | null>
10
- set(key: string, value: string): Promise<void>
11
- delete(key: string): Promise<void>
12
- }
13
-
14
- /** `<account id>/<secret name>`: the key an account's secret is stored under. */
15
- export const secretKey = (accountId: string, name: string): string => `${accountId}/${name}`
16
-
17
- /** Secrets held only for the life of the process. For tests and throwaway runs. */
18
- export function memorySecretStore(initial: Record<string, string> = {}): SecretStore & { values: Map<string, string> } {
19
- const values = new Map(Object.entries(initial))
20
- return {
21
- values,
22
- get: async (key) => values.get(key) ?? null,
23
- set: async (key, value) => void values.set(key, value),
24
- delete: async (key) => void values.delete(key)
25
- }
26
- }
27
-
28
- /**
29
- * Secrets in one owner-only JSON file. For a host with no Keychain to offer; anything that can
30
- * read the file can read every secret in it.
31
- */
32
- export function fileSecretStore(path: string): SecretStore {
33
- const read = (): Record<string, string> => readJsonOr<Record<string, string>>(path, {})
34
- const write = (values: Record<string, string>): void => {
35
- mkdirSync(dirname(path), { recursive: true, mode: 0o700 })
36
- atomicWrite(path, `${JSON.stringify(values, null, 2)}\n`)
37
- chmodSync(path, 0o600)
38
- }
39
- return {
40
- get: async (key) => read()[key] ?? null,
41
- set: async (key, value) => write({ ...read(), [key]: value }),
42
- delete: async (key) => {
43
- const values = read()
44
- if (key in values) {
45
- delete values[key]
46
- write(values)
47
- }
48
- }
49
- }
50
- }