@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
@@ -0,0 +1,4 @@
1
+ import { type SocketConnection } from "./client.js";
2
+ /** A process owns the claim across native session replacement; it never enters the environment. */
3
+ export declare function claimTerminalControl(connection?: SocketConnection): Promise<string>;
4
+ export declare function controlCall<T = unknown>(call: string, params?: Record<string, unknown>, timeoutMs?: number): Promise<T>;
@@ -0,0 +1,25 @@
1
+ import { connectionFromEnv, socketCall } from "./client.js";
2
+ const claims = new Map();
3
+ /** A process owns the claim across native session replacement; it never enters the environment. */
4
+ export function claimTerminalControl(connection = connectionFromEnv()) {
5
+ const identity = JSON.stringify([connection.socket, connection.token]);
6
+ let claim = claims.get(identity);
7
+ if (!claim) {
8
+ claim = socketCall(connection, 'control.claim', {}, 15_000).then(({ key }) => {
9
+ if (!key)
10
+ throw new Error('The terminal controller returned no control key.');
11
+ return key;
12
+ }).catch((error) => {
13
+ // A failed claim is retried by the next call; only a claim that succeeded is kept.
14
+ claims.delete(identity);
15
+ throw error;
16
+ });
17
+ claims.set(identity, claim);
18
+ }
19
+ return claim;
20
+ }
21
+ export async function controlCall(call, params = {}, timeoutMs = 120_000) {
22
+ const connection = connectionFromEnv();
23
+ const control = await claimTerminalControl(connection);
24
+ return socketCall(connection, call, params, timeoutMs, control);
25
+ }
@@ -0,0 +1,72 @@
1
+ import type { RunEvent } from "../sessions/contracts.js";
2
+ import type { ActiveRun, ApprovalDecision, QuestionAnswer } from "../sessions/registry.js";
3
+ export interface PolicyReply {
4
+ allowed: boolean;
5
+ reason?: string | null;
6
+ requiresApproval?: boolean;
7
+ rememberable?: boolean;
8
+ standing?: 'full' | 'switch' | 'none';
9
+ }
10
+ export interface ControllerHooks {
11
+ sessionId: string;
12
+ nativeSessionId: string | null;
13
+ /** Reserves or creates the run for a native turn and starts tracking it. */
14
+ begin(input: {
15
+ reservedRunId: string | null;
16
+ nativeTurnId: string;
17
+ text: string;
18
+ }): ActiveRun;
19
+ /** Whether a native tool call may run. */
20
+ policy(run: ActiveRun, tool: string, args: unknown): Promise<PolicyReply>;
21
+ /** Saves a user-selected tool grant in the shared local approval store. */
22
+ allowToolGlobally(target: string): void;
23
+ /** The native conversation identity changed. */
24
+ native(nativeSessionId: string): void;
25
+ telemetry(event: string): void;
26
+ interrupt?(runId: string): Promise<void>;
27
+ resolveApproval?(runId: string, requestId: string, decision: ApprovalDecision): void;
28
+ answerQuestion?(runId: string, requestId: string, answer: QuestionAnswer): void;
29
+ answerQuestions?(runId: string, batchId: string, answers: Array<{
30
+ questionId: string;
31
+ answer: QuestionAnswer;
32
+ }>): void;
33
+ }
34
+ export declare class TerminalController {
35
+ private readonly hooks;
36
+ private run;
37
+ private readonly pending;
38
+ private ready;
39
+ private disposed;
40
+ private dirty;
41
+ private multilineDraft;
42
+ private startupError;
43
+ private startupPhase;
44
+ private delivery;
45
+ private nativeId;
46
+ private readonly seen;
47
+ private readonly commands;
48
+ constructor(hooks: ControllerHooks);
49
+ get nativeSessionId(): string | null;
50
+ get activeRun(): ActiveRun | null;
51
+ state(): {
52
+ ready: boolean;
53
+ dirty: boolean;
54
+ active: boolean;
55
+ };
56
+ private requestId;
57
+ private begin;
58
+ private finish;
59
+ /** Hands the native process an instruction and waits until it acknowledges the prompt. */
60
+ send(runId: string, text: string): Promise<void>;
61
+ /** What the person typed into the terminal, so an instruction is never sent over their draft. */
62
+ onInput(data: string): void;
63
+ /** The native process hung up while it was waiting for a decision. */
64
+ disconnected(): void;
65
+ /** Project registry-owned questions, including grouped requests, into the terminal inbox. */
66
+ observe(event: RunEvent, descendant?: boolean): void;
67
+ /** The socket grants this interface only to the process that owns terminal input. */
68
+ control(call: string, data: Record<string, any>): Promise<unknown>;
69
+ private requestNativeApproval;
70
+ accept(event: string, data: Record<string, any>): Promise<unknown>;
71
+ dispose(): void;
72
+ }
@@ -0,0 +1,351 @@
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
+ import { HarnessError } from "../core/errors.js";
7
+ const READY_TIMEOUT_MS = 90_000;
8
+ const ACK_TIMEOUT_MS = 25_000;
9
+ export class TerminalController {
10
+ hooks;
11
+ run = null;
12
+ pending = new Map();
13
+ ready = false;
14
+ disposed = false;
15
+ dirty = false;
16
+ multilineDraft = false;
17
+ startupError = null;
18
+ startupPhase = 'Waiting for the native extension';
19
+ delivery = null;
20
+ nativeId;
21
+ seen = new Map();
22
+ commands = [];
23
+ constructor(hooks) {
24
+ this.hooks = hooks;
25
+ this.nativeId = hooks.nativeSessionId;
26
+ }
27
+ get nativeSessionId() {
28
+ return this.nativeId;
29
+ }
30
+ get activeRun() {
31
+ return this.run && !this.run.finished ? this.run : null;
32
+ }
33
+ state() {
34
+ return { ready: this.ready, dirty: this.dirty, active: !!this.activeRun || !!this.delivery };
35
+ }
36
+ requestId(nativeId) {
37
+ return createHash('sha256').update(`${this.hooks.sessionId}:${this.run?.runId}:${nativeId}`).digest('hex');
38
+ }
39
+ begin(nativeTurnId, text) {
40
+ if (this.startupError)
41
+ throw new Error(this.startupError);
42
+ this.dirty = false;
43
+ this.multilineDraft = false;
44
+ if (this.run && !this.run.finished)
45
+ return this.run;
46
+ const delivery = this.delivery;
47
+ if (delivery && text && delivery.text !== text)
48
+ throw new Error('The native prompt did not match the reserved delivery. Inspect the terminal before continuing.');
49
+ const run = this.hooks.begin({ reservedRunId: delivery?.runId ?? null, nativeTurnId, text });
50
+ this.run = run;
51
+ run.onInterrupt(() => void this.commands.push({ type: 'interrupt' }));
52
+ if (text)
53
+ run.emit('message.completed', { messageId: nativeTurnId, role: 'user', text });
54
+ delivery?.resolve();
55
+ this.delivery = null;
56
+ return run;
57
+ }
58
+ finish(outcome, message) {
59
+ this.run?.finish(outcome, message ? { code: 'terminal_attention', message } : undefined);
60
+ this.run = null;
61
+ this.seen.clear();
62
+ this.pending.clear();
63
+ }
64
+ /** Hands the native process an instruction and waits until it acknowledges the prompt. */
65
+ async send(runId, text) {
66
+ if (this.disposed)
67
+ throw new HarnessError('terminal_not_ready', 'Reopen the terminal before sending instructions.');
68
+ if (this.activeRun || this.delivery)
69
+ throw new HarnessError('session_busy', 'This terminal has an active task or delivery.');
70
+ const deadline = Date.now() + READY_TIMEOUT_MS;
71
+ while (!this.ready && !this.startupError && !this.disposed && Date.now() < deadline)
72
+ await new Promise((resolve) => setTimeout(resolve, 50));
73
+ if (this.disposed)
74
+ throw new HarnessError('terminal_not_ready', 'The terminal stopped during initialization.');
75
+ if (this.startupError)
76
+ throw new HarnessError('terminal_not_ready', this.startupError);
77
+ if (!this.ready)
78
+ throw new HarnessError('terminal_not_ready', `The native telemetry handshake is missing (${this.startupPhase}). Inspect the terminal sign-in or trust screen.`);
79
+ if (this.dirty)
80
+ throw new HarnessError('terminal_has_draft', 'The terminal contains user input. Submit or clear it before handing back control.');
81
+ let timer;
82
+ const ack = new Promise((resolve, reject) => {
83
+ 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);
84
+ this.delivery = { runId, text, resolve, reject };
85
+ });
86
+ // Delivery can fail while the native process is still starting the turn. Observe it immediately.
87
+ void ack.catch(() => { });
88
+ try {
89
+ this.commands.push({ type: 'send', text });
90
+ await ack;
91
+ }
92
+ catch (error) {
93
+ this.ready = false;
94
+ this.startupError = error instanceof Error ? error.message : String(error);
95
+ this.delivery = null;
96
+ this.commands.length = 0;
97
+ this.commands.push({ type: 'interrupt' });
98
+ this.finish('failed', this.startupError);
99
+ throw error;
100
+ }
101
+ finally {
102
+ clearTimeout(timer);
103
+ }
104
+ }
105
+ /** What the person typed into the terminal, so an instruction is never sent over their draft. */
106
+ onInput(data) {
107
+ if (!this.ready || this.activeRun || data === '\u0003')
108
+ return;
109
+ if (data.includes('\n') || data.includes('\r'))
110
+ this.multilineDraft = true;
111
+ this.dirty = data !== '\u0015' || this.multilineDraft;
112
+ }
113
+ /** The native process hung up while it was waiting for a decision. */
114
+ disconnected() {
115
+ if (this.disposed)
116
+ return;
117
+ this.ready = false;
118
+ this.commands.push({ type: 'interrupt' });
119
+ this.finish('failed', 'The native decision callback disconnected. Inspect the terminal before continuing.');
120
+ }
121
+ /** Project registry-owned questions, including grouped requests, into the terminal inbox. */
122
+ observe(event, descendant = false) {
123
+ if (this.disposed || !this.activeRun || (!descendant && event.runId !== this.activeRun.runId))
124
+ return;
125
+ if (event.type === 'question.requested') {
126
+ const payload = event.payload;
127
+ this.pending.set(String(payload.questionId), { ...payload, type: 'question', requestId: payload.questionId, runId: event.runId });
128
+ }
129
+ else if (descendant && event.type === 'approval.requested') {
130
+ const payload = event.payload;
131
+ if (!payload.automatic)
132
+ this.pending.set(String(payload.approvalId), { ...payload, type: 'approval', requestId: payload.approvalId, runId: event.runId });
133
+ }
134
+ else if (event.type === 'approval.resolved') {
135
+ this.pending.delete(String(event.payload.approvalId));
136
+ }
137
+ else if (event.type === 'question.answered') {
138
+ this.pending.delete(String(event.payload.questionId));
139
+ }
140
+ }
141
+ /** The socket grants this interface only to the process that owns terminal input. */
142
+ async control(call, data) {
143
+ if (this.disposed)
144
+ throw new HarnessError('terminal_not_ready', 'This terminal has ended.');
145
+ if (call === 'terminal.draft') {
146
+ this.dirty = data.dirty === true;
147
+ this.multilineDraft = false;
148
+ return {};
149
+ }
150
+ if (call === 'terminal.pending')
151
+ return { requests: [...this.pending.values()] };
152
+ if (call === 'terminal.interrupt')
153
+ return this.activeRun && this.hooks.interrupt ? this.hooks.interrupt(this.activeRun.runId) : {};
154
+ if (call === 'terminal.policy') {
155
+ const run = this.activeRun;
156
+ if (!run || typeof data.tool !== 'string' || !data.tool)
157
+ throw new HarnessError('invalid_request', 'An active run and tool name are required.');
158
+ return this.hooks.policy(run, data.tool, data.args ?? {});
159
+ }
160
+ if (call === 'terminal.approval')
161
+ return this.requestNativeApproval(data);
162
+ if (call === 'terminal.answers' && this.hooks.answerQuestions) {
163
+ const run = this.activeRun;
164
+ const batchId = String(data.batchId ?? '');
165
+ const requests = [...this.pending.values()].filter(request => request.batchId === batchId);
166
+ if (!run || !batchId || !requests.length || !Array.isArray(data.answers))
167
+ throw new HarnessError('invalid_request', 'This question batch is no longer pending.');
168
+ this.hooks.answerQuestions(String(requests[0].runId ?? run.runId), batchId, data.answers);
169
+ return {};
170
+ }
171
+ const requestId = String(data.requestId ?? '');
172
+ const request = this.pending.get(requestId);
173
+ const run = this.activeRun;
174
+ if (!request || !run)
175
+ throw new HarnessError('invalid_request', 'This terminal decision is no longer pending.');
176
+ if (call === 'terminal.approve' && request.type === 'approval' && this.hooks.resolveApproval) {
177
+ if (data.decision !== 'approved' && data.decision !== 'denied')
178
+ throw new HarnessError('invalid_request', 'Choose approve or deny.');
179
+ const alwaysAllow = data.alwaysAllow === true;
180
+ if (alwaysAllow && request.rememberable !== true)
181
+ throw new HarnessError('invalid_request', 'This approval cannot be remembered for other sessions.');
182
+ let decision = data.decision;
183
+ if (decision === 'approved' && request.direct === true) {
184
+ const operation = request.operation;
185
+ const tool = typeof operation?.tool === 'string' ? operation.tool : '';
186
+ const current = await this.hooks.policy(run, tool, operation?.args ?? {});
187
+ if (!current.allowed && !current.requiresApproval)
188
+ decision = 'denied';
189
+ if (alwaysAllow && current.rememberable !== true) {
190
+ request.rememberable = false;
191
+ throw new HarnessError('invalid_request', 'This tool can no longer be allowed across sessions. Review the approval again.');
192
+ }
193
+ }
194
+ if (decision === 'approved' && alwaysAllow)
195
+ this.hooks.allowToolGlobally(String(request.target ?? ''));
196
+ this.hooks.resolveApproval(String(request.runId ?? run.runId), requestId, decision);
197
+ return {};
198
+ }
199
+ if (call === 'terminal.answer' && request.type === 'question' && this.hooks.answerQuestion) {
200
+ if (!data.answer || !Array.isArray(data.answer.selected))
201
+ throw new HarnessError('invalid_request', 'A question answer is required.');
202
+ this.hooks.answerQuestion(String(request.runId ?? run.runId), requestId, data.answer);
203
+ return {};
204
+ }
205
+ throw new HarnessError('unknown_method', `Unknown terminal control ${call}.`);
206
+ }
207
+ async requestNativeApproval(data) {
208
+ const run = this.activeRun;
209
+ const requestId = typeof data.requestId === 'string' ? data.requestId : '';
210
+ const tool = typeof data.tool === 'string' ? data.tool : '';
211
+ if (!run || !requestId || !tool)
212
+ throw new HarnessError('invalid_request', 'An active run, request id, and tool name are required.');
213
+ const args = data.args && typeof data.args === 'object' && !Array.isArray(data.args) ? data.args : {};
214
+ const policy = await this.hooks.policy(run, tool, args);
215
+ if (!policy.allowed && !policy.requiresApproval)
216
+ return { decision: 'denied' };
217
+ if (policy.allowed && !policy.requiresApproval)
218
+ return { decision: 'approved' };
219
+ const key = this.requestId(`approval:${requestId}`);
220
+ const existing = this.seen.get(key);
221
+ if (existing)
222
+ return { decision: await existing };
223
+ const action = JSON.stringify(args);
224
+ const operation = { tool, args };
225
+ const response = run.requestApproval({
226
+ requestId: key,
227
+ target: tool,
228
+ action,
229
+ operation,
230
+ rememberable: policy.rememberable === true,
231
+ standing: policy.standing
232
+ });
233
+ this.pending.set(key, {
234
+ type: 'approval', requestId: key, runId: run.runId, target: tool, action,
235
+ operation, rememberable: policy.rememberable === true, direct: true
236
+ });
237
+ this.seen.set(key, response);
238
+ try {
239
+ return { decision: await response };
240
+ }
241
+ finally {
242
+ this.pending.delete(key);
243
+ }
244
+ }
245
+ async accept(event, data) {
246
+ if (this.disposed)
247
+ throw new Error('This terminal controller was disposed.');
248
+ if (event !== 'poll')
249
+ this.hooks.telemetry(event);
250
+ if (event === 'startup') {
251
+ this.startupPhase = String(data.phase);
252
+ return {};
253
+ }
254
+ if (event === 'startupFailed') {
255
+ this.startupError = String(data.reason ?? 'The native extension could not initialize.');
256
+ this.ready = false;
257
+ this.finish('failed', this.startupError);
258
+ return {};
259
+ }
260
+ if (event === 'poll')
261
+ return { command: this.commands.shift() ?? null };
262
+ if (event === 'ready') {
263
+ if (!this.ready) {
264
+ this.dirty = false;
265
+ this.multilineDraft = false;
266
+ }
267
+ this.ready = true;
268
+ if (typeof data.nativeSessionId === 'string' && data.nativeSessionId) {
269
+ this.nativeId = data.nativeSessionId;
270
+ this.hooks.native(data.nativeSessionId);
271
+ }
272
+ return {};
273
+ }
274
+ if (event === 'begin') {
275
+ const run = this.begin(String(data.turnId ?? randomUUID()), String(data.text ?? ''));
276
+ return { runId: run.runId };
277
+ }
278
+ if (event === 'shutdown') {
279
+ this.ready = false;
280
+ this.finish('interrupted');
281
+ return {};
282
+ }
283
+ if (event === 'settled') {
284
+ this.finish(data.aborted ? 'interrupted' : data.error ? 'failed' : 'completed', data.error ? String(data.error) : undefined);
285
+ return {};
286
+ }
287
+ const run = this.run;
288
+ if (!run)
289
+ throw new Error('Native telemetry arrived without an active turn.');
290
+ if (event === 'policy')
291
+ return this.hooks.policy(run, String(data.tool), data.args ?? {});
292
+ if (event === 'questions') {
293
+ if (!Array.isArray(data.questions) || !data.questions.length || data.questions.length > 5)
294
+ throw new HarnessError('invalid_request', 'Ask between one and five questions.');
295
+ const questions = data.questions.map(question => ({ ...question, requestId: randomUUID() }));
296
+ return run.requestAnswers(questions);
297
+ }
298
+ if (event === 'approval' || event === 'question') {
299
+ const key = this.requestId(`${event}:${String(data.requestId ?? JSON.stringify(data))}`);
300
+ const existing = this.seen.get(key);
301
+ if (existing)
302
+ return event === 'approval' ? { decision: await existing } : existing;
303
+ if (event === 'question') {
304
+ const response = run.requestAnswer({ requestId: key, question: String(data.question ?? ''), options: data.options ?? [], multiSelect: !!data.multiSelect, allowText: true });
305
+ this.pending.set(key, { type: 'question', requestId: key, question: String(data.question ?? ''), options: data.options ?? [], multiSelect: !!data.multiSelect });
306
+ this.seen.set(key, response);
307
+ return response.finally(() => this.pending.delete(key));
308
+ }
309
+ const response = run.requestApproval({
310
+ requestId: key,
311
+ target: String(data.target ?? 'Native action'),
312
+ action: String(data.action ?? '{}'),
313
+ operation: { tool: String(data.tool ?? data.target), args: data.args ?? {} },
314
+ rememberable: false
315
+ });
316
+ this.pending.set(key, { type: 'approval', requestId: key, target: String(data.target ?? 'Action'), action: String(data.action ?? '{}') });
317
+ this.seen.set(key, response);
318
+ try {
319
+ return { decision: await response };
320
+ }
321
+ finally {
322
+ this.pending.delete(key);
323
+ }
324
+ }
325
+ if (event === 'usage')
326
+ run.emit('usage.updated', data);
327
+ else if (event === 'file')
328
+ run.emit('file.changed', data);
329
+ else if (event === 'message')
330
+ run.emit('message.completed', { messageId: data.id ?? randomUUID(), role: data.role ?? 'assistant', text: String(data.text) });
331
+ else if (event === 'tool') {
332
+ run.emit(data.phase === 'start' ? 'tool.started' : 'tool.completed', {
333
+ toolCallId: String(data.id),
334
+ name: String(data.name),
335
+ ...(data.phase === 'start'
336
+ ? { summary: String(data.summary ?? ''), ...(typeof data.input === 'string' ? { input: data.input.slice(0, 24_000) } : {}) }
337
+ : { ok: data.ok !== false, ...(typeof data.durationMs === 'number' ? { durationMs: data.durationMs } : {}), ...(typeof data.resultChars === 'number' ? { resultChars: data.resultChars } : {}), ...(typeof data.output === 'string' ? { output: data.output.slice(0, 24_000) } : {}), ...(data.outputTruncated === true ? { outputTruncated: true } : {}) })
338
+ });
339
+ }
340
+ return {};
341
+ }
342
+ dispose() {
343
+ if (this.disposed)
344
+ return;
345
+ this.disposed = true;
346
+ this.ready = false;
347
+ this.delivery?.reject(new Error('The terminal stopped before prompt acknowledgement.'));
348
+ this.delivery = null;
349
+ this.finish('interrupted');
350
+ }
351
+ }
@@ -0,0 +1,10 @@
1
+ import type { HubOverview } from "../hub/schema.js";
2
+ import type { MenuCall, MenuUi } from "./pluginMenu.js";
3
+ type HubEntry = HubOverview['entries'][number];
4
+ /** What the person is told before installing: the entry, who published it, and what installing does. */
5
+ export declare function hubSummary(entry: HubEntry): string;
6
+ /** Asks, then installs exactly this version. A refusal or a failure is reported and changes nothing. */
7
+ export declare function installHubEntry(ui: MenuUi, call: MenuCall, entry: HubEntry): Promise<void>;
8
+ /** The terminal's catalog uses the same exact-version installer as embedding applications. */
9
+ export declare function runHubMenu(ui: MenuUi, call: MenuCall): Promise<void>;
10
+ export {};
@@ -0,0 +1,34 @@
1
+ /** What the person is told before installing: the entry, who published it, and what installing does. */
2
+ export function hubSummary(entry) {
3
+ return `${entry.description}\n\nPublisher: ${entry.publisher}\nLicense: ${entry.license}\nSource: ${entry.sourceUrl}\n\n${entry.delivery.kind === 'document' ? 'Saved as data for a compatible application. Nothing is created or enabled.' : 'Installed switched off. Code remains untrusted and approvals remain unchanged.'}`;
4
+ }
5
+ /** Asks, then installs exactly this version. A refusal or a failure is reported and changes nothing. */
6
+ export async function installHubEntry(ui, call, entry) {
7
+ if (!await ui.confirm(`Install ${entry.title} ${entry.version}?`, hubSummary(entry)))
8
+ return;
9
+ try {
10
+ const receipt = await call('hub.install', { id: entry.id, version: entry.version });
11
+ ui.notify(receipt.document ? 'Saved in this library for a compatible application.' : 'Installed, switched off. Use /plugins to review and attach it. Changes apply after restarting the session.', 'info');
12
+ }
13
+ catch (error) {
14
+ ui.notify(error instanceof Error ? error.message : String(error), 'error');
15
+ }
16
+ }
17
+ /** The terminal's catalog uses the same exact-version installer as embedding applications. */
18
+ export async function runHubMenu(ui, call) {
19
+ for (;;) {
20
+ const catalog = await call('hub.list');
21
+ const labels = catalog.entries.map((entry) => `${entry.title} · ${entry.category} · ${entry.id}@${entry.version}`);
22
+ const picked = await ui.select('Hub', [...labels, 'Refresh catalog', 'Done']);
23
+ if (picked === 'Refresh catalog') {
24
+ const refreshed = await call('hub.list', { refresh: true });
25
+ if (refreshed.error)
26
+ ui.notify(`${refreshed.error} Using ${refreshed.origin} content.`, 'warning');
27
+ continue;
28
+ }
29
+ const entry = catalog.entries[labels.indexOf(picked ?? '')];
30
+ if (!entry)
31
+ return;
32
+ await installHubEntry(ui, call, entry);
33
+ }
34
+ }
@@ -0,0 +1,5 @@
1
+ /** Files Pi's Git Bash shell and native Windows shells use to call Harness subcommands. */
2
+ export declare function terminalCommandFiles(platform: NodeJS.Platform, node: string, cli: string, name: string, mode: string): Array<{
3
+ name: string;
4
+ content: string;
5
+ }>;
@@ -0,0 +1,27 @@
1
+ function bashPath(path) {
2
+ const drive = /^([a-z]):[\\/](.*)$/i.exec(path);
3
+ if (drive)
4
+ return `/${drive[1].toLowerCase()}/${drive[2].replaceAll('\\', '/')}`;
5
+ if (path.startsWith('\\\\'))
6
+ return `//${path.slice(2).replaceAll('\\', '/')}`;
7
+ return path;
8
+ }
9
+ function shellQuote(value) {
10
+ return `'${value.replaceAll("'", "'\\''")}'`;
11
+ }
12
+ /** Files Pi's Git Bash shell and native Windows shells use to call Harness subcommands. */
13
+ export function terminalCommandFiles(platform, node, cli, name, mode) {
14
+ const shellNode = platform === 'win32' ? bashPath(node) : node;
15
+ const shellCli = platform === 'win32' ? bashPath(cli) : cli;
16
+ const files = [{
17
+ name,
18
+ content: `#!/bin/sh\nexec ${shellQuote(shellNode)} ${shellQuote(shellCli)} ${mode} "$@"\n`
19
+ }];
20
+ if (platform === 'win32') {
21
+ files.push({
22
+ name: `${name}.cmd`,
23
+ content: `@echo off\r\n"%XINGULAR_HARNESS_NODE%" "%XINGULAR_HARNESS_CLI%" ${mode} %*\r\nexit /b %ERRORLEVEL%\r\n`
24
+ });
25
+ }
26
+ return files;
27
+ }
@@ -0,0 +1,14 @@
1
+ export declare const LOG_READ_CHUNK_BYTES: number;
2
+ export interface HarnessLogInfo {
3
+ size: number | null;
4
+ }
5
+ export interface HarnessLogChunk {
6
+ data: string;
7
+ nextOffset: number;
8
+ }
9
+ /** Captures the byte length of the host-owned diagnostics file; callers never supply a path. */
10
+ export declare function harnessLogInfo(stateDir: string): HarnessLogInfo;
11
+ /** Reads one bounded range from the file size captured by `harnessLogInfo`. */
12
+ export declare function readHarnessLogChunk(stateDir: string, snapshotSize: number, offset: number): HarnessLogChunk;
13
+ /** Collects a fixed-size snapshot while keeping each socket reply bounded. */
14
+ export declare function readHarnessLogSnapshot(info: () => Promise<HarnessLogInfo>, chunk: (snapshotSize: number, offset: number) => Promise<HarnessLogChunk>): Promise<string>;
@@ -0,0 +1,59 @@
1
+ import { closeSync, openSync, readSync, statSync } from 'node:fs';
2
+ import { join } from 'node:path';
3
+ export const LOG_READ_CHUNK_BYTES = 32 * 1024;
4
+ /** Captures the byte length of the host-owned diagnostics file; callers never supply a path. */
5
+ export function harnessLogInfo(stateDir) {
6
+ try {
7
+ const stat = statSync(join(stateDir, 'harness.log'));
8
+ if (!stat.isFile())
9
+ throw new Error('The Harness diagnostics path is not a regular file.');
10
+ return { size: stat.size };
11
+ }
12
+ catch (error) {
13
+ if (error.code === 'ENOENT')
14
+ return { size: null };
15
+ throw error;
16
+ }
17
+ }
18
+ /** Reads one bounded range from the file size captured by `harnessLogInfo`. */
19
+ export function readHarnessLogChunk(stateDir, snapshotSize, offset) {
20
+ if (!Number.isSafeInteger(snapshotSize) || snapshotSize < 0 || !Number.isSafeInteger(offset) || offset < 0 || offset >= snapshotSize) {
21
+ throw new Error('The Harness diagnostics snapshot range is invalid.');
22
+ }
23
+ const path = join(stateDir, 'harness.log');
24
+ const current = statSync(path);
25
+ if (!current.isFile() || current.size < snapshotSize)
26
+ throw new Error('The Harness diagnostics file changed while it was being read.');
27
+ const length = Math.min(LOG_READ_CHUNK_BYTES, snapshotSize - offset);
28
+ const buffer = Buffer.allocUnsafe(length);
29
+ const descriptor = openSync(path, 'r');
30
+ try {
31
+ const bytesRead = readSync(descriptor, buffer, 0, length, offset);
32
+ if (bytesRead !== length)
33
+ throw new Error('The Harness diagnostics file changed while it was being read.');
34
+ return { data: buffer.toString('base64'), nextOffset: offset + bytesRead };
35
+ }
36
+ finally {
37
+ closeSync(descriptor);
38
+ }
39
+ }
40
+ /** Collects a fixed-size snapshot while keeping each socket reply bounded. */
41
+ export async function readHarnessLogSnapshot(info, chunk) {
42
+ const { size } = await info();
43
+ if (size === null || size === 0)
44
+ return '';
45
+ if (!Number.isSafeInteger(size) || size < 0)
46
+ throw new Error('The Harness returned an invalid diagnostics file size.');
47
+ const buffers = [];
48
+ let offset = 0;
49
+ while (offset < size) {
50
+ const page = await chunk(size, offset);
51
+ const buffer = Buffer.from(page.data, 'base64');
52
+ if (!buffer.length || page.nextOffset !== offset + buffer.length || page.nextOffset > size) {
53
+ throw new Error('The Harness returned an invalid diagnostics file page.');
54
+ }
55
+ buffers.push(buffer);
56
+ offset = page.nextOffset;
57
+ }
58
+ return Buffer.concat(buffers).toString('utf8');
59
+ }
@@ -0,0 +1,6 @@
1
+ import type { AgentSession, ExtensionAPI } from '@earendil-works/pi-coding-agent';
2
+ export interface TerminalPlanRunState {
3
+ active: boolean;
4
+ allowedTools: ReadonlySet<string>;
5
+ }
6
+ export default function (pi: ExtensionAPI, planRun?: TerminalPlanRunState, getSession?: () => AgentSession): Promise<void>;