@xingular/harness 0.1.6 → 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 (593) hide show
  1. package/CHANGELOG.md +107 -0
  2. package/LICENSE +202 -0
  3. package/NOTICE.md +60 -0
  4. package/README.md +265 -71
  5. package/THIRD_PARTY_LICENSES.md +942 -0
  6. package/dist/cli.js +14842 -9445
  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 +1170 -62
  373. package/docs/README.md +34 -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-0001-owned-terminal.md +87 -0
  403. package/docs/decisions/ADR-0002-native-subagent-lifecycle.md +49 -0
  404. package/docs/decisions/ADR-0003-shared-asynchronous-subagents.md +70 -0
  405. package/docs/decisions/ADR-0004-fullscreen-terminal-layout.md +50 -0
  406. package/docs/decisions/ADR-0005-app-provided-oauth-clients.md +54 -0
  407. package/docs/decisions/ADR-0006-opentui-only-terminal.md +47 -0
  408. package/docs/decisions/ADR-0007-reporting-section.md +33 -0
  409. package/docs/decisions/ADR-0008-flexible-reporting-guidance.md +38 -0
  410. package/docs/decisions/ADR-0009-xharness-command.md +38 -0
  411. package/docs/decisions/ADR-0010-lessons-in-the-wiki.md +31 -0
  412. package/docs/decisions/ADR-0011-foundation-and-variants.md +28 -0
  413. package/docs/decisions/ADR-0012-native-session-names.md +34 -0
  414. package/docs/decisions/ADR-0013-doctor.md +27 -0
  415. package/docs/decisions/ADR-0014-public-release-baseline.md +21 -0
  416. package/docs/doctor.md +74 -0
  417. package/docs/experiments/EXP-0001-terminal-input-latency/plan.md +81 -0
  418. package/docs/experiments/EXP-0001-terminal-input-latency/results.md +46 -0
  419. package/docs/experiments/EXP-0002-opentui-typing-latency/plan.md +70 -0
  420. package/docs/experiments/EXP-0002-opentui-typing-latency/results.md +92 -0
  421. package/docs/features/README.md +20 -0
  422. package/docs/features/automations/README.md +41 -0
  423. package/docs/features/cores/README.md +39 -0
  424. package/docs/features/google-harness2/README.md +52 -0
  425. package/docs/features/integrations/README.md +40 -0
  426. package/docs/features/interfaces/README.md +29 -0
  427. package/docs/features/memory/README.md +28 -0
  428. package/docs/releases/1.0.0.md +40 -0
  429. package/docs/releases/README.md +36 -0
  430. package/docs/study/00-index.md +78 -0
  431. package/docs/study/arms/00-matrix.md +20 -0
  432. package/docs/study/arms/01-system-prompt.md +211 -0
  433. package/docs/study/arms/02-tools.md +79 -0
  434. package/docs/study/arms/03-subagents.md +90 -0
  435. package/docs/study/arms/04-skills.md +75 -0
  436. package/docs/study/arms/05-context-management.md +90 -0
  437. package/docs/study/arms/06-memory.md +90 -0
  438. package/docs/study/arms/07-governance.md +71 -0
  439. package/docs/study/arms/08-execution.md +69 -0
  440. package/docs/study/arms/09-observability.md +60 -0
  441. package/docs/study/arms/10-refinement.md +110 -0
  442. package/docs/study/btw-comparison.md +37 -0
  443. package/docs/study/feature-gap-review.md +42 -0
  444. package/docs/study/insights.md +123 -0
  445. package/docs/study/roadmap.md +72 -0
  446. package/docs/study/sources/claude-code.md +44 -0
  447. package/docs/study/sources/deepseek-harness.md +102 -0
  448. package/docs/study/sources/harness2.md +50 -0
  449. package/docs/study/sources/kimi-cli.md +42 -0
  450. package/docs/study/sources/omp.md +93 -0
  451. package/docs/study/sources/opencode.md +43 -0
  452. package/docs/study/sources/openhands.md +46 -0
  453. package/docs/study/sources/smolagents.md +40 -0
  454. package/docs/study/sources/swe-agent.md +34 -0
  455. package/docs/system-prompt-design.md +196 -0
  456. package/docs/terminal-tui.md +671 -0
  457. package/package.json +48 -12
  458. package/src/accounts/accounts.test.ts +0 -223
  459. package/src/accounts/accounts.ts +0 -522
  460. package/src/accounts/env.test.ts +0 -95
  461. package/src/accounts/env.ts +0 -338
  462. package/src/accounts/secrets.ts +0 -50
  463. package/src/accounts/store.ts +0 -338
  464. package/src/capabilities/api.ts +0 -75
  465. package/src/capabilities/runSnapshot.ts +0 -59
  466. package/src/capabilities/types.ts +0 -34
  467. package/src/cli.ts +0 -114
  468. package/src/core/bus.ts +0 -34
  469. package/src/core/changes.ts +0 -33
  470. package/src/core/env.ts +0 -27
  471. package/src/core/errors.ts +0 -32
  472. package/src/core/frontmatter.ts +0 -47
  473. package/src/core/fs.test.ts +0 -38
  474. package/src/core/fs.ts +0 -92
  475. package/src/core/index.ts +0 -193
  476. package/src/core/path.test.ts +0 -14
  477. package/src/core/path.ts +0 -79
  478. package/src/core/projects.ts +0 -90
  479. package/src/core/text.ts +0 -39
  480. package/src/harness.ts +0 -299
  481. package/src/index.ts +0 -70
  482. package/src/mcp/connections.ts +0 -614
  483. package/src/mcp/manager.ts +0 -130
  484. package/src/mcp/oauth.ts +0 -195
  485. package/src/mcp/scopeMigration.test.ts +0 -79
  486. package/src/mcp/scopeMigration.ts +0 -204
  487. package/src/mcp/service.test.ts +0 -376
  488. package/src/mcp/service.ts +0 -549
  489. package/src/mcp/types.ts +0 -108
  490. package/src/memory/api.test.ts +0 -82
  491. package/src/memory/api.ts +0 -289
  492. package/src/memory/blocks.test.ts +0 -78
  493. package/src/memory/blocks.ts +0 -406
  494. package/src/memory/caller.ts +0 -57
  495. package/src/memory/dispatch.ts +0 -59
  496. package/src/memory/facts.test.ts +0 -41
  497. package/src/memory/facts.ts +0 -248
  498. package/src/memory/graph.ts +0 -103
  499. package/src/memory/health.test.ts +0 -130
  500. package/src/memory/health.ts +0 -74
  501. package/src/memory/maintainer.ts +0 -272
  502. package/src/memory/maintenance.test.ts +0 -176
  503. package/src/memory/maintenance.ts +0 -330
  504. package/src/memory/migrate.ts +0 -79
  505. package/src/memory/operations.ts +0 -138
  506. package/src/memory/proposals.test.ts +0 -168
  507. package/src/memory/proposals.ts +0 -576
  508. package/src/memory/recall.test.ts +0 -104
  509. package/src/memory/recall.ts +0 -271
  510. package/src/memory/references.ts +0 -77
  511. package/src/memory/runContext.ts +0 -93
  512. package/src/memory/secrets.ts +0 -6
  513. package/src/memory/store.test.ts +0 -66
  514. package/src/memory/store.ts +0 -385
  515. package/src/memory/wiki.test.ts +0 -47
  516. package/src/memory/wiki.ts +0 -422
  517. package/src/memory/wikiIndex.test.ts +0 -88
  518. package/src/memory/wikiIndex.ts +0 -116
  519. package/src/plugins/api.ts +0 -181
  520. package/src/plugins/attachments.test.ts +0 -84
  521. package/src/plugins/attachments.ts +0 -141
  522. package/src/plugins/builtin.ts +0 -82
  523. package/src/plugins/catalogue.test.ts +0 -254
  524. package/src/plugins/catalogue.ts +0 -251
  525. package/src/plugins/cli.ts +0 -184
  526. package/src/plugins/discover.ts +0 -151
  527. package/src/plugins/firstParty.test.ts +0 -143
  528. package/src/plugins/firstParty.ts +0 -129
  529. package/src/plugins/hooks.test.ts +0 -250
  530. package/src/plugins/hooks.ts +0 -239
  531. package/src/plugins/identity.ts +0 -37
  532. package/src/plugins/install.test.ts +0 -107
  533. package/src/plugins/install.ts +0 -106
  534. package/src/plugins/inventory.ts +0 -123
  535. package/src/plugins/manifest.ts +0 -76
  536. package/src/plugins/plugins.test.ts +0 -205
  537. package/src/plugins/plugins.ts +0 -189
  538. package/src/plugins/proposal.ts +0 -121
  539. package/src/plugins/runtime.test.ts +0 -40
  540. package/src/plugins/runtime.ts +0 -82
  541. package/src/plugins/trust.ts +0 -142
  542. package/src/plugins/types.ts +0 -149
  543. package/src/prompt/compile.test.ts +0 -261
  544. package/src/prompt/compile.ts +0 -732
  545. package/src/server/methods.ts +0 -314
  546. package/src/server/remote.ts +0 -77
  547. package/src/server/rpc.ts +0 -116
  548. package/src/server/serve.ts +0 -28
  549. package/src/server/server.test.ts +0 -174
  550. package/src/sessions/approvals.ts +0 -118
  551. package/src/sessions/contracts.ts +0 -310
  552. package/src/sessions/conversation.test.ts +0 -150
  553. package/src/sessions/extensionSession.test.ts +0 -74
  554. package/src/sessions/extensionUi.test.ts +0 -65
  555. package/src/sessions/extensionUi.ts +0 -102
  556. package/src/sessions/history.ts +0 -51
  557. package/src/sessions/lineageJoin.ts +0 -75
  558. package/src/sessions/policy.ts +0 -32
  559. package/src/sessions/pricing.ts +0 -60
  560. package/src/sessions/reasoningSummaries.ts +0 -59
  561. package/src/sessions/registry.ts +0 -294
  562. package/src/sessions/runIndex.ts +0 -99
  563. package/src/sessions/runStore.test.ts +0 -152
  564. package/src/sessions/runStore.ts +0 -332
  565. package/src/sessions/runner.ts +0 -569
  566. package/src/sessions/runtimeResources.test.ts +0 -61
  567. package/src/sessions/sessions.test.ts +0 -455
  568. package/src/sessions/sessions.ts +0 -295
  569. package/src/skills/registry.test.ts +0 -104
  570. package/src/skills/registry.ts +0 -407
  571. package/src/terminal/cli.ts +0 -149
  572. package/src/terminal/client.ts +0 -74
  573. package/src/terminal/controller.ts +0 -227
  574. package/src/terminal/launch.test.ts +0 -34
  575. package/src/terminal/launch.ts +0 -88
  576. package/src/terminal/piExtension.ts +0 -210
  577. package/src/terminal/pluginControl.test.ts +0 -146
  578. package/src/terminal/pluginMenu.ts +0 -112
  579. package/src/terminal/socket.test.ts +0 -71
  580. package/src/terminal/socket.ts +0 -221
  581. package/src/terminal/standalone.test.ts +0 -130
  582. package/src/terminal/standalone.ts +0 -144
  583. package/src/terminal/terminal.test.ts +0 -330
  584. package/src/terminal/terminals.ts +0 -443
  585. package/src/tools/askUser.ts +0 -45
  586. package/src/tools/definitions.ts +0 -187
  587. package/src/tools/memoryTools.ts +0 -22
  588. package/src/tools/pluginPropose.ts +0 -41
  589. package/src/tools/types.ts +0 -39
  590. package/src/web/safeRequest.ts +0 -171
  591. package/src/web/text.ts +0 -53
  592. package/src/web/tools.ts +0 -134
  593. package/src/web/web.test.ts +0 -141
@@ -1,227 +0,0 @@
1
- // One `pi` command running in a terminal, as the harness sees it. The terminal itself belongs
2
- // to whoever embeds the harness; this follows the native process through its extension's
3
- // telemetry (never by reading the screen), turns each native turn into a run, and answers the
4
- // extension's questions about policy, approvals, and what to do next.
5
- import { createHash, randomUUID } from 'node:crypto'
6
-
7
- import { HarnessError } from '../core/errors'
8
- import type { ActiveRun, ApprovalDecision, QuestionAnswer } from '../sessions/registry'
9
-
10
- export interface PolicyReply {
11
- allowed: boolean
12
- reason?: string | null
13
- requiresApproval?: boolean
14
- }
15
-
16
- export interface ControllerHooks {
17
- sessionId: string
18
- nativeSessionId: string | null
19
- /** Reserves or creates the run for a native turn and starts tracking it. */
20
- begin(input: { reservedRunId: string | null; nativeTurnId: string; text: string }): ActiveRun
21
- /** Whether a native tool call may run. */
22
- policy(run: ActiveRun, tool: string, args: unknown): Promise<PolicyReply>
23
- /** The native conversation identity changed. */
24
- native(nativeSessionId: string): void
25
- telemetry(event: string): void
26
- }
27
-
28
- interface Delivery {
29
- runId: string
30
- text: string
31
- resolve: () => void
32
- reject: (error: Error) => void
33
- }
34
-
35
- type Command = { type: 'interrupt' } | { type: 'send'; text: string }
36
-
37
- const READY_TIMEOUT_MS = 90_000
38
- const ACK_TIMEOUT_MS = 25_000
39
-
40
- export class TerminalController {
41
- private run: ActiveRun | null = null
42
- private ready = false
43
- private disposed = false
44
- private dirty = false
45
- private multilineDraft = false
46
- private startupError: string | null = null
47
- private startupPhase = 'Waiting for the native extension'
48
- private delivery: Delivery | null = null
49
- private nativeId: string | null
50
- private readonly seen = new Map<string, Promise<unknown>>()
51
- private readonly commands: Command[] = []
52
-
53
- constructor(private readonly hooks: ControllerHooks) {
54
- this.nativeId = hooks.nativeSessionId
55
- }
56
-
57
- get nativeSessionId(): string | null {
58
- return this.nativeId
59
- }
60
-
61
- get activeRun(): ActiveRun | null {
62
- return this.run && !this.run.finished ? this.run : null
63
- }
64
-
65
- state(): { ready: boolean; dirty: boolean; active: boolean } {
66
- return { ready: this.ready, dirty: this.dirty, active: !!this.activeRun || !!this.delivery }
67
- }
68
-
69
- private requestId(nativeId: string): string {
70
- return createHash('sha256').update(`${this.hooks.sessionId}:${this.run?.runId}:${nativeId}`).digest('hex')
71
- }
72
-
73
- private begin(nativeTurnId: string, text: string): ActiveRun {
74
- if (this.startupError) throw new Error(this.startupError)
75
- this.dirty = false
76
- this.multilineDraft = false
77
- if (this.run && !this.run.finished) return this.run
78
- const delivery = this.delivery
79
- if (delivery && text && delivery.text !== text) throw new Error('The native prompt did not match the reserved delivery. Inspect the terminal before continuing.')
80
- const run = this.hooks.begin({ reservedRunId: delivery?.runId ?? null, nativeTurnId, text })
81
- this.run = run
82
- run.onInterrupt(() => void this.commands.push({ type: 'interrupt' }))
83
- if (text) run.emit('message.completed', { messageId: nativeTurnId, role: 'user', text })
84
- delivery?.resolve()
85
- this.delivery = null
86
- return run
87
- }
88
-
89
- private finish(outcome: 'completed' | 'failed' | 'interrupted', message?: string): void {
90
- this.run?.finish(outcome, message ? { code: 'terminal_attention', message } : undefined)
91
- this.run = null
92
- this.seen.clear()
93
- }
94
-
95
- /** Hands the native process an instruction and waits until it acknowledges the prompt. */
96
- async send(runId: string, text: string): Promise<void> {
97
- if (this.disposed) throw new HarnessError('terminal_not_ready', 'Reopen the terminal before sending instructions.')
98
- if (this.activeRun || this.delivery) throw new HarnessError('session_busy', 'This terminal has an active task or delivery.')
99
- const deadline = Date.now() + READY_TIMEOUT_MS
100
- while (!this.ready && !this.startupError && !this.disposed && Date.now() < deadline) await new Promise((resolve) => setTimeout(resolve, 50))
101
- if (this.disposed) throw new HarnessError('terminal_not_ready', 'The terminal stopped during initialization.')
102
- if (this.startupError) throw new HarnessError('terminal_not_ready', this.startupError)
103
- if (!this.ready) throw new HarnessError('terminal_not_ready', `The native telemetry handshake is missing (${this.startupPhase}). Inspect the terminal sign-in or trust screen.`)
104
- if (this.dirty) throw new HarnessError('terminal_has_draft', 'The terminal contains user input. Submit or clear it before handing back control.')
105
- let timer: ReturnType<typeof setTimeout>
106
- const ack = new Promise<void>((resolve, reject) => {
107
- timer = setTimeout(() => reject(new HarnessError('delivery_uncertain', 'The native prompt acknowledgement was not received. Inspect the terminal; this instruction will not be resent.')), ACK_TIMEOUT_MS)
108
- this.delivery = { runId, text, resolve, reject }
109
- })
110
- // Delivery can fail while the native process is still starting the turn. Observe it immediately.
111
- void ack.catch(() => {})
112
- try {
113
- this.commands.push({ type: 'send', text })
114
- await ack
115
- } catch (error) {
116
- this.ready = false
117
- this.startupError = error instanceof Error ? error.message : String(error)
118
- this.delivery = null
119
- this.commands.length = 0
120
- this.commands.push({ type: 'interrupt' })
121
- this.finish('failed', this.startupError)
122
- throw error
123
- } finally {
124
- clearTimeout(timer!)
125
- }
126
- }
127
-
128
- /** What the person typed into the terminal, so an instruction is never sent over their draft. */
129
- onInput(data: string): void {
130
- if (!this.ready || this.activeRun || data === '\u0003') return
131
- if (data.includes('\n') || data.includes('\r')) this.multilineDraft = true
132
- this.dirty = data !== '\u0015' || this.multilineDraft
133
- }
134
-
135
- /** The native process hung up while it was waiting for a decision. */
136
- disconnected(): void {
137
- if (this.disposed) return
138
- this.ready = false
139
- this.commands.push({ type: 'interrupt' })
140
- this.finish('failed', 'The native decision callback disconnected. Inspect the terminal before continuing.')
141
- }
142
-
143
- async accept(event: string, data: Record<string, any>): Promise<unknown> {
144
- if (this.disposed) throw new Error('This terminal controller was disposed.')
145
- if (event !== 'poll') this.hooks.telemetry(event)
146
- if (event === 'startup') {
147
- this.startupPhase = String(data.phase)
148
- return {}
149
- }
150
- if (event === 'startupFailed') {
151
- this.startupError = String(data.reason ?? 'The native extension could not initialize.')
152
- this.ready = false
153
- this.finish('failed', this.startupError)
154
- return {}
155
- }
156
- if (event === 'poll') return { command: this.commands.shift() ?? null }
157
- if (event === 'ready') {
158
- if (!this.ready) {
159
- this.dirty = false
160
- this.multilineDraft = false
161
- }
162
- this.ready = true
163
- if (typeof data.nativeSessionId === 'string' && data.nativeSessionId) {
164
- this.nativeId = data.nativeSessionId
165
- this.hooks.native(data.nativeSessionId)
166
- }
167
- return {}
168
- }
169
- if (event === 'begin') {
170
- this.begin(String(data.turnId ?? randomUUID()), String(data.text ?? ''))
171
- return {}
172
- }
173
- if (event === 'shutdown') {
174
- this.ready = false
175
- this.finish('interrupted')
176
- return {}
177
- }
178
- if (event === 'settled') {
179
- this.finish(data.error ? 'failed' : 'completed', data.error ? String(data.error) : undefined)
180
- return {}
181
- }
182
- const run = this.run
183
- if (!run) throw new Error('Native telemetry arrived without an active turn.')
184
- if (event === 'policy') return this.hooks.policy(run, String(data.tool), data.args ?? {})
185
- if (event === 'approval' || event === 'question') {
186
- const key = this.requestId(String(data.requestId ?? JSON.stringify(data)))
187
- const existing = this.seen.get(key)
188
- if (existing) return event === 'approval' ? { decision: await existing } : existing
189
- if (event === 'question') {
190
- const response: Promise<QuestionAnswer> = run.requestAnswer({ requestId: key, question: String(data.question ?? ''), options: data.options ?? [], multiSelect: !!data.multiSelect, allowText: true })
191
- this.seen.set(key, response)
192
- return response
193
- }
194
- const response: Promise<ApprovalDecision> = run.requestApproval({
195
- requestId: key,
196
- target: String(data.target ?? 'Native action'),
197
- action: String(data.action ?? '{}'),
198
- operation: { tool: String(data.tool ?? data.target), args: data.args ?? {} },
199
- rememberable: false
200
- })
201
- this.seen.set(key, response)
202
- return { decision: await response }
203
- }
204
- if (event === 'usage') run.emit('usage.updated', data)
205
- else if (event === 'file') run.emit('file.changed', data)
206
- else if (event === 'message') run.emit('message.completed', { messageId: data.id ?? randomUUID(), role: data.role ?? 'assistant', text: String(data.text) })
207
- else if (event === 'tool') {
208
- run.emit(data.phase === 'start' ? 'tool.started' : 'tool.completed', {
209
- toolCallId: String(data.id),
210
- name: String(data.name),
211
- ...(data.phase === 'start'
212
- ? { summary: String(data.summary ?? '') }
213
- : { ok: data.ok !== false, ...(typeof data.durationMs === 'number' ? { durationMs: data.durationMs } : {}), ...(typeof data.resultChars === 'number' ? { resultChars: data.resultChars } : {}) })
214
- })
215
- }
216
- return {}
217
- }
218
-
219
- dispose(): void {
220
- if (this.disposed) return
221
- this.disposed = true
222
- this.ready = false
223
- this.delivery?.reject(new Error('The terminal stopped before prompt acknowledgement.'))
224
- this.delivery = null
225
- this.finish('interrupted')
226
- }
227
- }
@@ -1,34 +0,0 @@
1
- import { spawnSync } from 'node:child_process'
2
- import { describe, expect, it } from 'vitest'
3
-
4
- import { bundledPiCli, resolvePiCommand, terminalCommandFiles } from './launch'
5
-
6
- describe('terminal launch commands', () => {
7
- it('runs the pinned Pi CLI with the active Node runtime on Windows', () => {
8
- const launch = resolvePiCommand({ platform: 'win32', node: 'C:\\Program Files\\nodejs\\node.exe' })
9
-
10
- expect(launch.program).toBe('C:\\Program Files\\nodejs\\node.exe')
11
- expect(launch.argsPrefix[0]).toMatch(/[\\/]node_modules[\\/]@earendil-works[\\/]pi-coding-agent[\\/]dist[\\/]bundle[\\/]cli\.js$/)
12
- })
13
-
14
- it('runs the package CLI through Node for a no-model help smoke', () => {
15
- const result = spawnSync(process.execPath, [bundledPiCli(), '--help'], { encoding: 'utf8', timeout: 20_000 })
16
-
17
- expect(result.error).toBeUndefined()
18
- expect(result.status).toBe(0)
19
- expect(`${result.stdout}${result.stderr}`).toMatch(/usage|options|pi/i)
20
- })
21
-
22
- it('keeps an explicitly configured executable even on Windows', () => {
23
- expect(resolvePiCommand({ platform: 'win32', node: 'node.exe', programOverride: () => 'C:\\Tools\\pi.exe' }))
24
- .toEqual({ program: 'C:\\Tools\\pi.exe', argsPrefix: [] })
25
- })
26
-
27
- it('provides Git Bash and native Windows launchers for each Harness command', () => {
28
- expect(terminalCommandFiles('win32', 'C:\\Program Files\\nodejs\\node.exe', 'C:\\Harness\\cli.js', 'xagent-wiki', 'wiki'))
29
- .toEqual([
30
- { name: 'xagent-wiki', content: "#!/bin/sh\nexec '/c/Program Files/nodejs/node.exe' '/c/Harness/cli.js' wiki \"$@\"\n" },
31
- { name: 'xagent-wiki.cmd', content: '@echo off\r\n"%XINGULAR_HARNESS_NODE%" "%XINGULAR_HARNESS_CLI%" wiki %*\r\nexit /b %ERRORLEVEL%\r\n' }
32
- ])
33
- })
34
- })
@@ -1,88 +0,0 @@
1
- import { existsSync, readFileSync } from 'node:fs'
2
- import { createRequire } from 'node:module'
3
- import { join, resolve } from 'node:path'
4
-
5
- import { HarnessError } from '../core/errors'
6
- import { findBinary } from '../core/path'
7
-
8
- const PI_PACKAGE = '@earendil-works/pi-coding-agent'
9
-
10
- export interface PiCommand {
11
- program: string
12
- argsPrefix: string[]
13
- }
14
-
15
- /** Resolve the Pi package's declared command instead of depending on its POSIX npm shim. */
16
- export function bundledPiCli(): string {
17
- const require = createRequire(import.meta.url)
18
- for (const nodeModules of require.resolve.paths(PI_PACKAGE) ?? []) {
19
- const directory = join(nodeModules, ...PI_PACKAGE.split('/'))
20
- const manifestPath = join(directory, 'package.json')
21
- if (!existsSync(manifestPath)) continue
22
- try {
23
- const manifest = JSON.parse(readFileSync(manifestPath, 'utf8')) as {
24
- name?: unknown
25
- bin?: unknown
26
- }
27
- if (manifest.name === PI_PACKAGE) {
28
- const executable = typeof manifest.bin === 'string'
29
- ? manifest.bin
30
- : manifest.bin && typeof manifest.bin === 'object' && typeof (manifest.bin as Record<string, unknown>).pi === 'string'
31
- ? (manifest.bin as Record<string, string>).pi
32
- : null
33
- if (!executable) throw new Error('the package does not declare its pi command')
34
- const cli = resolve(directory, executable)
35
- if (!existsSync(cli)) throw new Error(`the declared command does not exist at ${cli}`)
36
- return cli
37
- }
38
- } catch {
39
- continue
40
- }
41
- }
42
-
43
- throw new HarnessError('harness_unavailable', `The bundled ${PI_PACKAGE} package does not expose a usable pi command. Reinstall the Harness package and try again.`)
44
- }
45
-
46
- export function resolvePiCommand(options: {
47
- platform: NodeJS.Platform
48
- node: string
49
- programOverride?: () => string | null
50
- }): PiCommand {
51
- if (options.programOverride) {
52
- const program = options.programOverride()
53
- if (!program) throw new HarnessError('harness_unavailable', 'The Pi CLI was not found on PATH.')
54
- return { program, argsPrefix: [] }
55
- }
56
- if (options.platform === 'win32') return { program: options.node, argsPrefix: [bundledPiCli()] }
57
- const program = findBinary('pi')
58
- if (!program) throw new HarnessError('harness_unavailable', 'The Pi CLI was not found on PATH.')
59
- return { program, argsPrefix: [] }
60
- }
61
-
62
- function bashPath(path: string): string {
63
- const drive = /^([a-z]):[\\/](.*)$/i.exec(path)
64
- if (drive) return `/${drive[1].toLowerCase()}/${drive[2].replaceAll('\\', '/')}`
65
- if (path.startsWith('\\\\')) return `//${path.slice(2).replaceAll('\\', '/')}`
66
- return path
67
- }
68
-
69
- function shellQuote(value: string): string {
70
- return `'${value.replaceAll("'", "'\\''")}'`
71
- }
72
-
73
- /** Files Pi's Git Bash shell and native Windows shells use to call Harness subcommands. */
74
- export function terminalCommandFiles(platform: NodeJS.Platform, node: string, cli: string, name: string, mode: string): Array<{ name: string; content: string }> {
75
- const shellNode = platform === 'win32' ? bashPath(node) : node
76
- const shellCli = platform === 'win32' ? bashPath(cli) : cli
77
- const files = [{
78
- name,
79
- content: `#!/bin/sh\nexec ${shellQuote(shellNode)} ${shellQuote(shellCli)} ${mode} "$@"\n`
80
- }]
81
- if (platform === 'win32') {
82
- files.push({
83
- name: `${name}.cmd`,
84
- content: `@echo off\r\n"%XINGULAR_HARNESS_NODE%" "%XINGULAR_HARNESS_CLI%" ${mode} %*\r\nexit /b %ERRORLEVEL%\r\n`
85
- })
86
- }
87
- return files
88
- }
@@ -1,210 +0,0 @@
1
- // Loaded by the `pi` command in a terminal session (`--extension`). It reports what the native
2
- // session does to the harness, asks before each tool call, takes instructions the harness
3
- // queues for it, and gives the session the harness's own tools. It runs in the `pi` process,
4
- // so everything it knows about the harness comes through the session socket.
5
- import type { ExtensionAPI, ExtensionContext } from '@earendil-works/pi-coding-agent'
6
- import { Type } from 'typebox'
7
-
8
- import { connectionFromEnv, socketCall, terminalCall } from './client'
9
- import { runPluginsMenu } from './pluginMenu'
10
-
11
- interface SocketTool {
12
- name: string
13
- label: string
14
- description: string
15
- parameters: Record<string, unknown>
16
- }
17
-
18
- /** How much text a tool handed back to the model. */
19
- function resultSize(result: unknown): number | null {
20
- const content = (result as { content?: unknown } | null | undefined)?.content
21
- if (!Array.isArray(content)) return typeof result === 'string' ? result.length : null
22
- return content.reduce((total: number, part: { type?: string; text?: unknown }) => total + (part?.type === 'text' && typeof part.text === 'string' ? part.text.length : 0), 0)
23
- }
24
-
25
- export default async function (pi: ExtensionAPI) {
26
- await terminalCall('startup', { phase: 'Pi extension loaded' })
27
- let context: ExtensionContext | null = null
28
- let timer: ReturnType<typeof setInterval> | null = null
29
- let polling = false
30
- let failure: string | undefined
31
- const emptyUsage = () => ({ inputTokens: 0, outputTokens: 0, cacheReadTokens: 0, cacheWriteTokens: 0, requests: 0, costUsd: 0 })
32
- let usage = emptyUsage()
33
- let reasoningTokens: number | undefined
34
- let costReported = false
35
- let requestStartedAt: number | null = null
36
- const toolStartedAt = new Map<string, number>()
37
- const fileTools = new Map<string, string>()
38
-
39
- // The harness's own tools for this session (connected apps and what the application offers).
40
- let stage = 'Tool discovery'
41
- try {
42
- await terminalCall('startup', { phase: stage })
43
- const connection = connectionFromEnv()
44
- // Claimed here, before the model has run anything, and kept in this process's memory: a
45
- // command the model runs can read the session token from its environment, never this key.
46
- const control = await socketCall<{ key: string }>(connection, 'control.claim', {}, 15_000).then((claimed) => claimed.key).catch(() => null)
47
- pi.registerCommand('plugins', {
48
- description: 'See what this session loads, and switch a plugin on or off or trust its code',
49
- handler: async (_args, ctx) => {
50
- if (!control) return ctx.ui.notify('This session cannot change plugins.', 'warning')
51
- const { projectId } = await socketCall<{ projectId: string | null }>(connection, 'plugins.session', {}, 15_000, control).catch(() => ({ projectId: null }))
52
- await runPluginsMenu(
53
- { select: (title, options) => ctx.ui.select(title, options), confirm: (title, message) => ctx.ui.confirm(title, message), notify: (message, level) => ctx.ui.notify(message, level) },
54
- (method, params) => socketCall(connection, method, params ?? {}, 60_000, control),
55
- projectId
56
- )
57
- }
58
- })
59
- const { tools } = await socketCall<{ tools: SocketTool[] }>(connection, 'tools.list', {}, 15_000)
60
- stage = 'Tool registration'
61
- for (const tool of tools) {
62
- pi.registerTool({
63
- name: tool.name,
64
- label: tool.label,
65
- description: tool.description,
66
- parameters: Type.Unsafe(tool.parameters),
67
- async execute(_id, input) {
68
- const result = await socketCall<{ text: string }>(connection, 'tools.call', { name: tool.name, input: input as Record<string, unknown> }, 1_230_000)
69
- return { content: [{ type: 'text', text: result.text }], details: undefined }
70
- }
71
- })
72
- }
73
- } catch (error) {
74
- await terminalCall('startupFailed', { reason: `${stage} failed: ${error instanceof Error ? error.message : 'Unavailable'}` }).catch(() => {})
75
- throw error
76
- }
77
-
78
- pi.on('session_start', async (_event, ctx) => {
79
- context = ctx
80
- await terminalCall('ready', { nativeSessionId: ctx.sessionManager.getSessionFile() })
81
- timer = setInterval(() => {
82
- if (polling || !context) return
83
- polling = true
84
- void terminalCall<{ command: { type: string; text?: string } | null }>('poll', {}, 5_000)
85
- .then(({ command }) => {
86
- if (command?.type === 'interrupt') context?.abort()
87
- else if (command?.type === 'send') {
88
- if (context?.ui.getEditorText().trim()) throw new Error('The terminal contains a user draft.')
89
- // Pi 1.2 needs deliverAs while a run is busy; a message sent then waits for that run to finish.
90
- pi.sendUserMessage(command.text!, context?.isIdle() === false ? { deliverAs: 'followUp' } : undefined)
91
- }
92
- })
93
- .catch(() => {
94
- context?.abort()
95
- if (timer) clearInterval(timer)
96
- })
97
- .finally(() => {
98
- polling = false
99
- })
100
- }, 100)
101
- })
102
- pi.on('before_agent_start', async (event, ctx) => {
103
- context = ctx
104
- failure = undefined
105
- usage = emptyUsage()
106
- reasoningTokens = undefined
107
- costReported = false
108
- // A run a plugin starts with a custom message has no user prompt to record; it still begins a turn.
109
- await terminalCall('begin', { text: event.messageType === 'user' ? event.prompt : '' })
110
- })
111
- pi.on('message_end', async (event) => {
112
- if (event.message.role !== 'assistant') return
113
- if (event.message.stopReason === 'error' || event.message.stopReason === 'aborted') failure = event.message.errorMessage ?? `Pi stopped: ${event.message.stopReason}`
114
- const text = event.message.content.filter((part) => part.type === 'text').map((part) => part.text).join('\n')
115
- if (text) await terminalCall('message', { text })
116
- if (event.message.usage) {
117
- const reported = event.message.usage
118
- usage.inputTokens += reported.input ?? 0
119
- usage.outputTokens += reported.output ?? 0
120
- usage.cacheReadTokens += reported.cacheRead ?? 0
121
- usage.cacheWriteTokens += reported.cacheWrite ?? 0
122
- usage.requests += 1
123
- if (typeof reported.reasoning === 'number') reasoningTokens = (reasoningTokens ?? 0) + reported.reasoning
124
- const cost = reported.cost?.total
125
- if (typeof cost === 'number') {
126
- usage.costUsd += cost
127
- costReported = true
128
- }
129
- const identity = { model: event.message.model, provider: event.message.provider }
130
- const { costUsd, ...tokens } = usage
131
- await terminalCall('usage', {
132
- ...tokens,
133
- ...(costReported ? { costUsd, costSource: 'harness' } : {}),
134
- ...(reasoningTokens === undefined ? {} : { reasoningTokens }),
135
- contextTokens: (reported.input ?? 0) + (reported.cacheRead ?? 0) + (reported.cacheWrite ?? 0),
136
- ...(context?.model?.contextWindow ? { contextWindow: context.model.contextWindow } : {}),
137
- ...identity,
138
- request: {
139
- index: usage.requests,
140
- ...identity,
141
- responseId: event.message.responseId,
142
- inputTokens: reported.input ?? 0,
143
- cacheReadTokens: reported.cacheRead ?? 0,
144
- cacheWriteTokens: reported.cacheWrite ?? 0,
145
- outputTokens: reported.output ?? 0,
146
- ...(typeof reported.reasoning === 'number' ? { reasoningTokens: reported.reasoning } : {}),
147
- ...(typeof cost === 'number' ? { costUsd: cost, costSource: 'harness' } : {}),
148
- ...(requestStartedAt === null ? {} : { durationMs: Date.now() - requestStartedAt }),
149
- stopReason: event.message.stopReason
150
- }
151
- })
152
- requestStartedAt = null
153
- }
154
- })
155
- pi.on('turn_start', async () => {
156
- requestStartedAt = Date.now()
157
- })
158
- pi.on('tool_call', async (event) => {
159
- try {
160
- const policy = await terminalCall<{ allowed: boolean; reason?: string; requiresApproval?: boolean }>('policy', { tool: event.toolName, args: event.input })
161
- if (policy.requiresApproval) {
162
- const approval = await terminalCall<{ decision: string }>('approval', { requestId: event.toolCallId, target: event.toolName, action: JSON.stringify(event.input), tool: event.toolName, args: event.input })
163
- if (approval.decision === 'approved') return
164
- return { block: true, reason: 'The user denied this action. Ask how they would like to proceed.' }
165
- }
166
- if (!policy.allowed) return { block: true, reason: policy.reason ?? 'Outside what this session may do.' }
167
- } catch {
168
- return { block: true, reason: 'The terminal controller is unavailable.' }
169
- }
170
- })
171
- pi.on('tool_execution_start', async (event) => {
172
- if (['edit', 'write'].includes(event.toolName) && typeof event.args.path === 'string') fileTools.set(event.toolCallId, event.args.path)
173
- toolStartedAt.set(event.toolCallId, Date.now())
174
- await terminalCall('tool', { phase: 'start', id: event.toolCallId, name: event.toolName, summary: JSON.stringify(event.args).slice(0, 200) })
175
- })
176
- pi.on('tool_execution_end', async (event) => {
177
- const started = toolStartedAt.get(event.toolCallId)
178
- toolStartedAt.delete(event.toolCallId)
179
- const resultChars = resultSize(event.result)
180
- await terminalCall('tool', { phase: 'end', id: event.toolCallId, name: event.toolName, ok: !event.isError, ...(started === undefined ? {} : { durationMs: Date.now() - started }), ...(resultChars === null ? {} : { resultChars }) })
181
- const path = fileTools.get(event.toolCallId)
182
- fileTools.delete(event.toolCallId)
183
- if (!event.isError && path) await terminalCall('file', { path, change: 'modified' })
184
- })
185
- pi.on('agent_settled', async () => {
186
- await terminalCall('settled', { error: failure })
187
- })
188
- pi.on('user_bash', async () => {
189
- throw new Error('Use the bash tool so this action can be checked.')
190
- })
191
- pi.on('session_shutdown', async () => {
192
- if (timer) clearInterval(timer)
193
- await terminalCall('shutdown').catch(() => {})
194
- })
195
- pi.registerTool({
196
- name: 'ask_user_question',
197
- label: 'Ask a question',
198
- description: 'Ask the user a question and wait for their answer.',
199
- parameters: Type.Object({
200
- question: Type.String(),
201
- options: Type.Optional(Type.Array(Type.Object({ label: Type.String(), description: Type.Optional(Type.String()) }))),
202
- multiSelect: Type.Optional(Type.Boolean())
203
- }),
204
- async execute(id, input) {
205
- const answer = await terminalCall('question', { requestId: id, ...input })
206
- return { content: [{ type: 'text', text: JSON.stringify(answer) }], details: undefined }
207
- }
208
- })
209
- await terminalCall('startup', { phase: 'Pi hooks registered' })
210
- }