@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,255 @@
1
+ // Accounts. One profile (settings, registry, memory) and any number of Pi accounts, each with
2
+ // its own isolated agent folder, stored credentials, sign-in state, limits, health, and audit
3
+ // trail.
4
+ //
5
+ // Device-local layout under `<state dir>/accounts/`:
6
+ // accounts.json accounts, the default, pools (no secrets)
7
+ // <id>/state.json health, plan, limits, last error (no secrets)
8
+ // <id>/home/pi/ Pi's own agent folder for this account
9
+ // _shared/pi/ settings, skills, prompts linked into every account's agent folder
10
+ // audit.jsonl append-only account actions (secrets scrubbed)
11
+ //
12
+ // Switching is always manual. A pool only chooses an account when a session starts; a running
13
+ // or resumed session keeps the account it started with.
14
+ import { mkdirSync, readFileSync } from 'node:fs';
15
+ import { join } from 'node:path';
16
+ import { HarnessError, invalid, notFound } from "../core/errors.js";
17
+ import { appendLine, newId, now, readJsonOr, safeId, writeJson } from "../core/fs.js";
18
+ import { charCount, compareText, lines, takeChars } from "../core/text.js";
19
+ /** The only provider the harness runs. Records of other providers are kept in the file and ignored. */
20
+ export const PROVIDER = 'pi';
21
+ export const emptyState = () => ({ health: 'unknown', signedIn: null, authMethod: null, plan: null, identity: null, limits: [], lastError: null, lastCheckedAt: null, cliVersion: null, capabilities: [], piProviders: [] });
22
+ // ---- Files ------------------------------------------------------------------------------
23
+ const registryPath = (dir) => join(dir, 'accounts.json');
24
+ const statePath = (dir, accountId) => join(dir, safeId(accountId), 'state.json');
25
+ export function loadRegistry(dir) {
26
+ const stored = readJsonOr(registryPath(dir), {}) ?? {};
27
+ return { accounts: stored.accounts ?? [], defaults: stored.defaults ?? {}, pools: stored.pools ?? [], migratedProviderKeys: stored.migratedProviderKeys ?? false };
28
+ }
29
+ export function saveRegistry(dir, registry) {
30
+ mkdirSync(dir, { recursive: true });
31
+ writeJson(registryPath(dir), registry);
32
+ }
33
+ export function loadState(dir, accountId) {
34
+ try {
35
+ return { ...emptyState(), ...(readJsonOr(statePath(dir, accountId), {}) ?? {}) };
36
+ }
37
+ catch {
38
+ return emptyState();
39
+ }
40
+ }
41
+ function saveState(dir, accountId, state) {
42
+ writeJson(statePath(dir, accountId), state);
43
+ }
44
+ /** Replaces anything that looks like a token so audit lines and stored errors never hold secrets. */
45
+ export function scrub(text) {
46
+ const words = text.split(' ').map((word) => {
47
+ const bytes = Buffer.byteLength(word);
48
+ const tokenLike = bytes >= 24 && (word.match(/[A-Za-z0-9]/g)?.length ?? 0) * 10 >= bytes * 8;
49
+ return tokenLike || word.startsWith('sk-') || word.startsWith('sess-') ? '[redacted]' : word;
50
+ });
51
+ return takeChars(words.join(' '), 500);
52
+ }
53
+ export function audit(dir, accountId, action, detail) {
54
+ try {
55
+ mkdirSync(dir, { recursive: true });
56
+ appendLine(join(dir, 'audit.jsonl'), JSON.stringify({ at: now(), accountId, action, detail: scrub(detail) }));
57
+ }
58
+ catch {
59
+ // An audit line that cannot be written never fails the action it describes.
60
+ }
61
+ }
62
+ /** The newest audit entries first, optionally for one account. */
63
+ export function readAudit(dir, accountId, limit = 100) {
64
+ let text = '';
65
+ try {
66
+ text = readFileSync(join(dir, 'audit.jsonl'), 'utf8');
67
+ }
68
+ catch {
69
+ text = '';
70
+ }
71
+ const entries = lines(text).flatMap((line) => {
72
+ try {
73
+ const entry = JSON.parse(line);
74
+ return entry && typeof entry.at === 'string' && typeof entry.action === 'string' && (!accountId || entry.accountId === accountId) ? [entry] : [];
75
+ }
76
+ catch {
77
+ return [];
78
+ }
79
+ });
80
+ return entries.reverse().slice(0, Math.min(limit, 1000));
81
+ }
82
+ // ---- Health -----------------------------------------------------------------------------
83
+ function inFuture(timestamp) {
84
+ const time = timestamp ? Date.parse(timestamp) : Number.NaN;
85
+ return !Number.isNaN(time) && time > Date.now();
86
+ }
87
+ // How long a limit error that came without a reset time keeps the account limited. Providers
88
+ // report no limit windows, so nothing else would ever lift it.
89
+ const UNTIMED_LIMIT_ERROR_SECS = 3600;
90
+ export const isLimitCategory = (category) => category === 'rate_limited' || category === 'quota';
91
+ /**
92
+ * Whether a `rate_limited` or `quota` error still counts. With a reset time it counts until
93
+ * then; without one it counts for a short while after it was recorded.
94
+ */
95
+ export function limitErrorActive(issue) {
96
+ if (issue.resetsAt)
97
+ return inFuture(issue.resetsAt);
98
+ const at = Date.parse(issue.at);
99
+ return !Number.isNaN(at) && Math.trunc((Date.now() - at) / 1000) < UNTIMED_LIMIT_ERROR_SECS;
100
+ }
101
+ export function deriveHealth(state) {
102
+ const limitedByWindow = state.limits.some((limit) => (limit.status === 'rejected' || (limit.usedPercent ?? 0) >= 100) && (!limit.resetsAt || inFuture(limit.resetsAt)));
103
+ const issue = state.lastError;
104
+ if (issue?.category === 'auth_expired')
105
+ return 'auth_expired';
106
+ if (issue && isLimitCategory(issue.category) && limitErrorActive(issue))
107
+ return 'limited';
108
+ if (state.signedIn === false)
109
+ return 'signed_out';
110
+ if (limitedByWindow)
111
+ return 'limited';
112
+ if (issue && !isLimitCategory(issue.category))
113
+ return 'error';
114
+ return state.signedIn === true ? 'ok' : 'unknown';
115
+ }
116
+ /** Read-modify-write on one account's state. Returns the previous health and the new state. */
117
+ export function updateState(dir, accountId, change) {
118
+ const state = loadState(dir, accountId);
119
+ const previous = state.health;
120
+ change(state);
121
+ state.health = deriveHealth(state);
122
+ saveState(dir, accountId, state);
123
+ return { previous, state };
124
+ }
125
+ // ---- Lookup and pinning -----------------------------------------------------------------
126
+ export function find(dir, accountId) {
127
+ const account = loadRegistry(dir).accounts.find((entry) => entry.id === accountId);
128
+ if (!account)
129
+ throw new HarnessError('account_required', "This session's account was removed.", 'Choose another account for it.');
130
+ return account;
131
+ }
132
+ const usable = (state) => state.health === 'ok' || state.health === 'unknown';
133
+ /**
134
+ * Chooses the account for a new session: the explicit account, else the pool's first usable
135
+ * account, else the default, else the first account. It never skips to another one silently.
136
+ */
137
+ export function resolve(dir, accountId, poolId) {
138
+ const registry = loadRegistry(dir);
139
+ if (accountId) {
140
+ const account = find(dir, accountId);
141
+ if (account.provider !== PROVIDER)
142
+ throw invalid('That account belongs to another provider.');
143
+ return account;
144
+ }
145
+ if (poolId) {
146
+ const pool = registry.pools.find((entry) => entry.id === poolId);
147
+ if (!pool)
148
+ throw notFound('Pool');
149
+ const members = pool.accountIds.flatMap((id) => registry.accounts.find((account) => account.id === id) ?? []);
150
+ const ready = members.find((account) => usable(loadState(dir, account.id)));
151
+ if (ready)
152
+ return ready;
153
+ const resets = members.flatMap((account) => {
154
+ const state = loadState(dir, account.id);
155
+ return [...state.limits.map((limit) => limit.resetsAt), state.lastError?.resetsAt].filter((reset) => Boolean(reset));
156
+ });
157
+ const earliest = resets.sort(compareText)[0];
158
+ throw new HarnessError('account_unavailable', `Every account in ${pool.label} is unavailable.`, earliest ? `The earliest reset is ${earliest}.` : 'Reauthenticate an account in Accounts.');
159
+ }
160
+ const account = registry.accounts.find((entry) => entry.id === registry.defaults[PROVIDER]) ?? registry.accounts.find((entry) => entry.provider === PROVIDER);
161
+ if (!account)
162
+ throw new HarnessError('account_required', 'Add a Pi account first.', 'Open Accounts (⌘4) to sign in.');
163
+ return account;
164
+ }
165
+ /** The default account, if any exists. */
166
+ export function defaultAccount(dir) {
167
+ try {
168
+ return resolve(dir);
169
+ }
170
+ catch {
171
+ return null;
172
+ }
173
+ }
174
+ export function summaryAuthentication(dir) {
175
+ const states = loadRegistry(dir).accounts.filter((account) => account.provider === PROVIDER).map((account) => loadState(dir, account.id));
176
+ if (states.some((state) => state.signedIn === true))
177
+ return 'authenticated';
178
+ return states.some((state) => state.signedIn === false) ? 'unauthenticated' : 'unknown';
179
+ }
180
+ export function overview(dir) {
181
+ const registry = loadRegistry(dir);
182
+ return {
183
+ accounts: registry.accounts.filter((account) => account.provider === PROVIDER).map((account) => ({ ...account, isDefault: registry.defaults[account.provider] === account.id, state: loadState(dir, account.id) })),
184
+ pools: registry.pools.filter((pool) => pool.provider === PROVIDER),
185
+ defaults: registry.defaults
186
+ };
187
+ }
188
+ // ---- Changes ----------------------------------------------------------------------------
189
+ export function cleanLabel(label) {
190
+ const cleaned = label.trim();
191
+ if (!cleaned || charCount(cleaned) > 60)
192
+ throw invalid('Give the account a name of 1–60 characters.');
193
+ return cleaned;
194
+ }
195
+ export function addAccount(dir, label, authKind) {
196
+ if (authKind !== 'subscription' && authKind !== 'apiKey')
197
+ throw invalid('Unknown sign-in type.');
198
+ const account = { id: newId(), provider: PROVIDER, label: cleanLabel(label), authKind, credentialStore: 'keyring', createdAt: now() };
199
+ const registry = loadRegistry(dir);
200
+ registry.defaults[PROVIDER] ??= account.id;
201
+ registry.accounts.push(account);
202
+ saveRegistry(dir, registry);
203
+ return account;
204
+ }
205
+ export function renameAccount(dir, accountId, label) {
206
+ const cleaned = cleanLabel(label);
207
+ const registry = loadRegistry(dir);
208
+ const account = registry.accounts.find((entry) => entry.id === accountId);
209
+ if (!account)
210
+ throw notFound('Account');
211
+ account.label = cleaned;
212
+ saveRegistry(dir, registry);
213
+ }
214
+ export function setDefault(dir, accountId) {
215
+ const account = find(dir, accountId);
216
+ const registry = loadRegistry(dir);
217
+ registry.defaults[account.provider] = account.id;
218
+ saveRegistry(dir, registry);
219
+ return account;
220
+ }
221
+ /** Drops the account from the registry, its pools, and the default. Its folder and secrets are the caller's to remove. */
222
+ export function forgetAccount(dir, account) {
223
+ const registry = loadRegistry(dir);
224
+ registry.accounts = registry.accounts.filter((entry) => entry.id !== account.id);
225
+ if (registry.defaults[account.provider] === account.id) {
226
+ const next = registry.accounts.find((entry) => entry.provider === account.provider);
227
+ if (next)
228
+ registry.defaults[account.provider] = next.id;
229
+ else
230
+ delete registry.defaults[account.provider];
231
+ }
232
+ for (const pool of registry.pools)
233
+ pool.accountIds = pool.accountIds.filter((id) => id !== account.id);
234
+ saveRegistry(dir, registry);
235
+ }
236
+ export function savePool(dir, pool) {
237
+ const label = cleanLabel(pool.label);
238
+ const registry = loadRegistry(dir);
239
+ for (const id of pool.accountIds) {
240
+ const account = registry.accounts.find((entry) => entry.id === id);
241
+ if (!account)
242
+ throw notFound('Account');
243
+ if (account.provider !== PROVIDER)
244
+ throw invalid('A pool holds accounts of one provider.');
245
+ }
246
+ const next = { id: pool.id ? safeId(pool.id) : newId(), provider: PROVIDER, label, accountIds: [...pool.accountIds] };
247
+ registry.pools = [...registry.pools.filter((existing) => existing.id !== next.id), next];
248
+ saveRegistry(dir, registry);
249
+ return next;
250
+ }
251
+ export function removePool(dir, poolId) {
252
+ const registry = loadRegistry(dir);
253
+ registry.pools = registry.pools.filter((pool) => pool.id !== poolId);
254
+ saveRegistry(dir, registry);
255
+ }
@@ -0,0 +1,16 @@
1
+ export interface BrowserConfig {
2
+ /** Show the browser window instead of running it headless. */
3
+ headed: boolean;
4
+ /** Attach to a browser a person already runs (its DevTools address) instead of launching one. */
5
+ cdpUrl: string | null;
6
+ /** A browser program to launch; otherwise Chrome, then Edge, then Playwright's Chromium. */
7
+ executablePath: string | null;
8
+ /** Let pages reach this machine and private networks (local development servers). */
9
+ allowPrivate: boolean;
10
+ /** When set, pages may only reach these sites (and their subdomains). */
11
+ allowedDomains: string[];
12
+ }
13
+ export declare const DEFAULT_BROWSER_CONFIG: BrowserConfig;
14
+ export declare const configPath: (stateDir: string) => string;
15
+ export declare function readBrowserConfig(stateDir: string): BrowserConfig;
16
+ export declare function writeBrowserConfig(stateDir: string, change: Partial<BrowserConfig>): BrowserConfig;
@@ -0,0 +1,22 @@
1
+ // How the harness's browser runs, kept on this device: `<state dir>/browser.json`. Only a person
2
+ // (through a command or the application) writes it; no tool argument can point the browser at
3
+ // another endpoint or profile.
4
+ import { join } from 'node:path';
5
+ import { readJsonOr, writeJson } from "../core/fs.js";
6
+ export const DEFAULT_BROWSER_CONFIG = { headed: false, cdpUrl: null, executablePath: null, allowPrivate: false, allowedDomains: [] };
7
+ export const configPath = (stateDir) => join(stateDir, 'browser.json');
8
+ export function readBrowserConfig(stateDir) {
9
+ const saved = readJsonOr(configPath(stateDir), {});
10
+ return {
11
+ headed: saved.headed === true,
12
+ cdpUrl: typeof saved.cdpUrl === 'string' && /^(?:https?|wss?):\/\/(?:127\.0\.0\.1|localhost|\[::1\])(?::\d+)?(?:\/|$)/.test(saved.cdpUrl) ? saved.cdpUrl : null,
13
+ executablePath: typeof saved.executablePath === 'string' && saved.executablePath.trim() ? saved.executablePath : null,
14
+ allowPrivate: saved.allowPrivate === true,
15
+ allowedDomains: Array.isArray(saved.allowedDomains) ? saved.allowedDomains.filter((domain) => typeof domain === 'string' && /^[a-z0-9.-]+$/i.test(domain)).map((domain) => domain.toLowerCase()) : []
16
+ };
17
+ }
18
+ export function writeBrowserConfig(stateDir, change) {
19
+ const next = { ...readBrowserConfig(stateDir), ...change };
20
+ writeJson(configPath(stateDir), next);
21
+ return readBrowserConfig(stateDir);
22
+ }
@@ -0,0 +1,4 @@
1
+ import type { BrowserConfig } from "./config.js";
2
+ import type { DoctorCheck } from "../doctor/types.js";
3
+ /** Exercises the production tool path against a synthetic page in a throwaway profile. */
4
+ export declare function browserDiagnostic(configure: () => BrowserConfig): DoctorCheck;
@@ -0,0 +1,38 @@
1
+ import { accessSync, constants } from 'node:fs';
2
+ const outputText = (result) => typeof result === 'string' ? result : result.text;
3
+ /** Exercises the production tool path against a synthetic page in a throwaway profile. */
4
+ export function browserDiagnostic(configure) {
5
+ return {
6
+ id: 'browser', category: 'browser', title: 'Isolated browser',
7
+ tools: ['browser_navigate', 'browser_read', 'browser_snapshot', 'browser_click'],
8
+ local: async () => {
9
+ const config = configure();
10
+ if (config.executablePath)
11
+ accessSync(config.executablePath, constants.X_OK);
12
+ return { status: 'pass', evidence: `Browser tools are installed. ${config.cdpUrl ? 'A CDP endpoint is configured; diagnostics will not attach to it.' : 'A dedicated browser will be launched only after live-check confirmation.'} Browser launch is unverified.` };
13
+ },
14
+ live: {
15
+ notice: 'Launch a dedicated headless browser with a disposable profile, open an offline synthetic page, read its marker, and click its test button. No existing browser or profile is used.',
16
+ run: async (probe) => {
17
+ if (configure().cdpUrl)
18
+ return { status: 'blocked', evidence: 'This backend is configured to attach to a browser. Isolated diagnostics will not attach to it.', remedy: 'Use a dedicated launch configuration to test browser interaction.' };
19
+ const needed = ['browser_navigate', 'browser_read', 'browser_snapshot', 'browser_click'];
20
+ if (needed.some(name => !probe.context.tools.includes(name)))
21
+ return { status: 'blocked', evidence: 'The browser interaction test requires navigate, read, snapshot, and click capabilities.' };
22
+ const html = '<!doctype html><title>Harness Doctor</title><p>doctor-ready</p><button onclick="document.querySelector(\'p\').textContent=\'doctor-clicked\'">Diagnostic test</button>';
23
+ await probe.call('browser_navigate', { url: `data:text/html,${encodeURIComponent(html)}` });
24
+ const before = outputText(await probe.call('browser_read', {}));
25
+ if (!before.includes('doctor-ready'))
26
+ return { status: 'fail', evidence: 'The diagnostic page marker could not be read.' };
27
+ const snapshot = outputText(await probe.call('browser_snapshot', {}));
28
+ const line = snapshot.split('\n').find(line => line.includes('button') && line.includes('Diagnostic test'));
29
+ const ref = line && /\b(e\d+)\b/.exec(line)?.[1];
30
+ if (!ref)
31
+ return { status: 'fail', evidence: 'The test button was absent from the browser snapshot.' };
32
+ await probe.call('browser_click', { ref });
33
+ const after = outputText(await probe.call('browser_read', {}));
34
+ return after.includes('doctor-clicked') ? { status: 'pass', evidence: 'Navigation, reading, element discovery, and clicking succeeded in the disposable diagnostic browser.' } : { status: 'fail', evidence: 'Clicking did not change the expected page marker.' };
35
+ }
36
+ }
37
+ };
38
+ }
@@ -0,0 +1,17 @@
1
+ import type { PluginDescriptor } from "../plugins/types.js";
2
+ import type { WorldPart } from "../world/world.js";
3
+ import { NetworkPolicy } from "./network.js";
4
+ import { BrowserSession, type Launcher } from "./session.js";
5
+ export declare const BROWSER_PLUGIN: PluginDescriptor;
6
+ /** A browser closes after this long without a call. */
7
+ export declare const IDLE_MS: number;
8
+ export interface BrowserPartOptions {
9
+ stateDir: string;
10
+ launch?: Launcher;
11
+ /** Replaces the address check in tests. */
12
+ network?: NetworkPolicy;
13
+ idleMs?: number;
14
+ }
15
+ export declare function browserPart(options: BrowserPartOptions): WorldPart & {
16
+ sessions: Map<string, BrowserSession>;
17
+ };
@@ -0,0 +1,65 @@
1
+ // The browser, as one part of the harness's world tools: a plugin a person can switch off, and one
2
+ // live browser per session.
3
+ import { rmSync } from 'node:fs';
4
+ import { join } from 'node:path';
5
+ import { readBrowserConfig } from "./config.js";
6
+ import { browserDiagnostic } from "./diagnostics.js";
7
+ import { NetworkPolicy } from "./network.js";
8
+ import { BrowserSession, fileName, launchBrowser } from "./session.js";
9
+ import { BROWSER_TOOL_NAMES, browserTools } from "./tools.js";
10
+ export const BROWSER_PLUGIN = {
11
+ id: 'browser',
12
+ title: 'Browser',
13
+ description: 'A browser the agent drives: open pages that need scripts, read them, click, type and choose. Each session has its own; sign-ins are kept per agent on this device. Sending, buying, deleting, account changes and granting access always ask you.',
14
+ manage: 'tools',
15
+ switchable: { on: true },
16
+ // Its tools are listed in the World group, which the Web plugin owns.
17
+ tools: BROWSER_TOOL_NAMES.map((name) => ({ name }))
18
+ };
19
+ /** A browser closes after this long without a call. */
20
+ export const IDLE_MS = 15 * 60_000;
21
+ export function browserPart(options) {
22
+ const sessions = new Map();
23
+ const diagnosticKeys = new Set();
24
+ const config = () => readBrowserConfig(options.stateDir);
25
+ const network = options.network ?? new NetworkPolicy(config);
26
+ const sessionFor = (context) => {
27
+ let session = sessions.get(context.sessionKey);
28
+ if (!session) {
29
+ const owner = context.caller.agentId ?? context.caller.projectId ?? 'default';
30
+ const key = context.sessionKey;
31
+ const diagnostic = context.caller.surface === 'doctor';
32
+ if (diagnostic)
33
+ diagnosticKeys.add(key);
34
+ session = new BrowserSession({
35
+ key,
36
+ profileDir: diagnostic ? null : join(options.stateDir, 'browser', 'profiles', fileName(owner)),
37
+ downloadsDir: join(options.stateDir, 'browser', 'downloads', fileName(key)),
38
+ config: diagnostic ? () => ({ ...config(), cdpUrl: null, headed: false }) : config,
39
+ network,
40
+ launch: options.launch ?? launchBrowser,
41
+ idleMs: options.idleMs ?? IDLE_MS,
42
+ onIdle: () => void release(key)
43
+ });
44
+ sessions.set(key, session);
45
+ }
46
+ return session;
47
+ };
48
+ const release = async (key) => {
49
+ const session = sessions.get(key);
50
+ sessions.delete(key);
51
+ await session?.close();
52
+ if (diagnosticKeys.delete(key))
53
+ rmSync(join(options.stateDir, 'browser', 'downloads', fileName(key)), { recursive: true, force: true });
54
+ };
55
+ return {
56
+ plugin: BROWSER_PLUGIN,
57
+ diagnostics: () => [browserDiagnostic(config)],
58
+ sessions,
59
+ tools: (context) => browserTools(context, () => sessionFor(context)),
60
+ release,
61
+ close: async () => {
62
+ await Promise.all([...sessions.keys()].map(release));
63
+ }
64
+ };
65
+ }
@@ -0,0 +1,10 @@
1
+ import type { BrowserConfig } from "./config.js";
2
+ export declare class NetworkPolicy {
3
+ private readonly config;
4
+ private readonly resolve;
5
+ private readonly hosts;
6
+ constructor(config: () => BrowserConfig, resolve?: (host: string) => Promise<string[]>);
7
+ /** Why an address may not be loaded, or null when it may. */
8
+ refusal(address: string): Promise<string | null>;
9
+ private isPublic;
10
+ }
@@ -0,0 +1,59 @@
1
+ // What a page in the harness's browser may reach. The same rule as `web_fetch`: public addresses
2
+ // only, unless a person allowed private ones for local development. This filters the browser's
3
+ // requests; it is a guard, not a sandbox (a page's own DNS can still differ from ours).
4
+ import { lookup } from 'node:dns/promises';
5
+ import { isIP } from 'node:net';
6
+ import { isPublicAddress } from "../web/safeRequest.js";
7
+ const OPEN_SCHEMES = new Set(['data:', 'blob:', 'about:']);
8
+ const CACHE_MS = 60_000;
9
+ export class NetworkPolicy {
10
+ config;
11
+ resolve;
12
+ hosts = new Map();
13
+ constructor(config, resolve = async (host) => (await lookup(host, { all: true, verbatim: true })).map((entry) => entry.address)) {
14
+ this.config = config;
15
+ this.resolve = resolve;
16
+ }
17
+ /** Why an address may not be loaded, or null when it may. */
18
+ async refusal(address) {
19
+ let url;
20
+ try {
21
+ url = new URL(address);
22
+ }
23
+ catch {
24
+ return 'That is not a web address.';
25
+ }
26
+ if (OPEN_SCHEMES.has(url.protocol))
27
+ return null;
28
+ if (url.protocol !== 'http:' && url.protocol !== 'https:')
29
+ return `${url.protocol} addresses cannot be opened.`;
30
+ if (url.username || url.password)
31
+ return 'Addresses with a username or password cannot be opened.';
32
+ const host = url.hostname.replace(/^\[|\]$/g, '').toLowerCase();
33
+ const { allowedDomains, allowPrivate } = this.config();
34
+ if (allowedDomains.length && !allowedDomains.some((domain) => host === domain || host.endsWith(`.${domain}`)))
35
+ return `${host} is not among the sites this browser may reach.`;
36
+ if (allowPrivate)
37
+ return null;
38
+ return (await this.isPublic(host)) ? null : `${host} is not a public address. A person can allow private addresses in the browser settings.`;
39
+ }
40
+ async isPublic(host) {
41
+ if (isIP(host))
42
+ return isPublicAddress(host);
43
+ if (host === 'localhost' || host.endsWith('.localhost'))
44
+ return false;
45
+ const cached = this.hosts.get(host);
46
+ if (cached && Date.now() - cached.at < CACHE_MS)
47
+ return cached.ok;
48
+ let ok = false;
49
+ try {
50
+ const addresses = await this.resolve(host);
51
+ ok = addresses.length > 0 && addresses.every(isPublicAddress);
52
+ }
53
+ catch {
54
+ ok = false;
55
+ }
56
+ this.hosts.set(host, { at: Date.now(), ok });
57
+ return ok;
58
+ }
59
+ }
@@ -0,0 +1,84 @@
1
+ import type { Browser, BrowserContext, Page } from 'playwright-core';
2
+ import type { BrowserConfig } from "./config.js";
3
+ import type { NetworkPolicy } from "./network.js";
4
+ /** Any name as a file or folder name: other characters become `_`. */
5
+ export declare const fileName: (name: string) => string;
6
+ export declare const VIEWPORT: {
7
+ width: number;
8
+ height: number;
9
+ };
10
+ export declare const ACTION_TIMEOUT_MS = 15000;
11
+ export declare const NAVIGATION_TIMEOUT_MS = 30000;
12
+ export interface Tab {
13
+ id: string;
14
+ page: Page;
15
+ /** Bumped on every navigation of the tab's main frame: refs of an earlier generation are stale. */
16
+ generation: number;
17
+ /** Refs of the latest snapshot, with the snapshot line that names each. */
18
+ refs: Map<string, string>;
19
+ refsGeneration: number;
20
+ }
21
+ export interface Download {
22
+ tab: string;
23
+ path: string;
24
+ name: string;
25
+ }
26
+ /** Opens a browser context; tests replace it. */
27
+ export type Launcher = (input: {
28
+ profileDir: string | null;
29
+ downloads: string;
30
+ config: BrowserConfig;
31
+ }) => Promise<{
32
+ context: BrowserContext;
33
+ browser: Browser | null;
34
+ attached: boolean;
35
+ }>;
36
+ export declare const launchBrowser: Launcher;
37
+ export interface BrowserSessionOptions {
38
+ key: string;
39
+ /** The profile kept for this caller, or null for a throwaway one. */
40
+ profileDir: string | null;
41
+ downloadsDir: string;
42
+ config: () => BrowserConfig;
43
+ network: NetworkPolicy;
44
+ launch: Launcher;
45
+ idleMs: number;
46
+ onIdle: () => void;
47
+ }
48
+ export declare class BrowserSession {
49
+ private readonly options;
50
+ private closed;
51
+ private context;
52
+ private browser;
53
+ private attached;
54
+ private starting;
55
+ private readonly tabs;
56
+ private current;
57
+ private nextTab;
58
+ private queue;
59
+ private idle;
60
+ private temporaryProfile;
61
+ readonly downloads: Download[];
62
+ /** Set when the kept profile was in use and a throwaway one was opened instead. */
63
+ profileNote: string | null;
64
+ constructor(options: BrowserSessionOptions);
65
+ /** Runs `work` after every earlier call of this session has finished. */
66
+ run<T>(work: () => Promise<T>): Promise<T>;
67
+ private touch;
68
+ private start;
69
+ private adopt;
70
+ /** A tab by id, or the current one, starting the browser and opening a first tab when needed. */
71
+ tab(id?: string | null): Promise<Tab>;
72
+ open(): Promise<Tab>;
73
+ select(id: string): Tab;
74
+ list(): {
75
+ id: string;
76
+ url: string;
77
+ current: boolean;
78
+ }[];
79
+ /** What pages in this browser may reach. */
80
+ get network(): NetworkPolicy;
81
+ get currentId(): string | null;
82
+ get started(): boolean;
83
+ close(): Promise<void>;
84
+ }