@xingular/harness 0.1.6 → 1.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (593) hide show
  1. package/CHANGELOG.md +107 -0
  2. package/LICENSE +202 -0
  3. package/NOTICE.md +60 -0
  4. package/README.md +265 -71
  5. package/THIRD_PARTY_LICENSES.md +942 -0
  6. package/dist/cli.js +14842 -9445
  7. package/dist/sdk/accounts/accounts.d.ts +165 -0
  8. package/dist/sdk/accounts/accounts.js +730 -0
  9. package/dist/sdk/accounts/choices.d.ts +23 -0
  10. package/dist/sdk/accounts/choices.js +62 -0
  11. package/dist/sdk/accounts/env.d.ts +78 -0
  12. package/dist/sdk/accounts/env.js +294 -0
  13. package/dist/sdk/accounts/secrets.d.ts +16 -0
  14. package/dist/sdk/accounts/secrets.js +40 -0
  15. package/dist/sdk/accounts/store.d.ts +114 -0
  16. package/dist/sdk/accounts/store.js +255 -0
  17. package/dist/sdk/browser/config.d.ts +16 -0
  18. package/dist/sdk/browser/config.js +22 -0
  19. package/dist/sdk/browser/diagnostics.d.ts +4 -0
  20. package/dist/sdk/browser/diagnostics.js +38 -0
  21. package/dist/sdk/browser/index.d.ts +17 -0
  22. package/dist/sdk/browser/index.js +65 -0
  23. package/dist/sdk/browser/network.d.ts +10 -0
  24. package/dist/sdk/browser/network.js +59 -0
  25. package/dist/sdk/browser/session.d.ts +84 -0
  26. package/dist/sdk/browser/session.js +192 -0
  27. package/dist/sdk/browser/tools.d.ts +8 -0
  28. package/dist/sdk/browser/tools.js +329 -0
  29. package/dist/sdk/capabilities/api.d.ts +22 -0
  30. package/dist/sdk/capabilities/api.js +54 -0
  31. package/dist/sdk/capabilities/runSnapshot.d.ts +18 -0
  32. package/dist/sdk/capabilities/runSnapshot.js +47 -0
  33. package/dist/sdk/capabilities/types.d.ts +29 -0
  34. package/dist/sdk/capabilities/types.js +1 -0
  35. package/dist/sdk/cli.d.ts +2 -0
  36. package/dist/sdk/cli.js +142 -0
  37. package/dist/sdk/core/bus.d.ts +23 -0
  38. package/dist/sdk/core/bus.js +76 -0
  39. package/dist/sdk/core/caller.d.ts +22 -0
  40. package/dist/sdk/core/caller.js +16 -0
  41. package/dist/sdk/core/changes.d.ts +15 -0
  42. package/dist/sdk/core/changes.js +15 -0
  43. package/dist/sdk/core/effort.d.ts +2 -0
  44. package/dist/sdk/core/effort.js +1 -0
  45. package/dist/sdk/core/env.d.ts +18 -0
  46. package/dist/sdk/core/env.js +8 -0
  47. package/dist/sdk/core/errors.d.ts +15 -0
  48. package/dist/sdk/core/errors.js +24 -0
  49. package/dist/sdk/core/frontmatter.d.ts +12 -0
  50. package/dist/sdk/core/frontmatter.js +50 -0
  51. package/dist/sdk/core/fs.d.ts +18 -0
  52. package/dist/sdk/core/fs.js +106 -0
  53. package/dist/sdk/core/index.d.ts +24 -0
  54. package/dist/sdk/core/index.js +187 -0
  55. package/dist/sdk/core/path.d.ts +7 -0
  56. package/dist/sdk/core/path.js +79 -0
  57. package/dist/sdk/core/projects.d.ts +18 -0
  58. package/dist/sdk/core/projects.js +67 -0
  59. package/dist/sdk/core/secrets.d.ts +2 -0
  60. package/dist/sdk/core/secrets.js +5 -0
  61. package/dist/sdk/core/text.d.ts +7 -0
  62. package/dist/sdk/core/text.js +40 -0
  63. package/dist/sdk/doctor/checks.d.ts +5 -0
  64. package/dist/sdk/doctor/checks.js +208 -0
  65. package/dist/sdk/doctor/probe.d.ts +4 -0
  66. package/dist/sdk/doctor/probe.js +92 -0
  67. package/dist/sdk/doctor/service.d.ts +23 -0
  68. package/dist/sdk/doctor/service.js +144 -0
  69. package/dist/sdk/doctor/types.d.ts +141 -0
  70. package/dist/sdk/doctor/types.js +29 -0
  71. package/dist/sdk/harness.d.ts +133 -0
  72. package/dist/sdk/harness.js +299 -0
  73. package/dist/sdk/history/lessonPrompt.d.ts +2 -0
  74. package/dist/sdk/history/lessonPrompt.js +15 -0
  75. package/dist/sdk/history/lessons.d.ts +52 -0
  76. package/dist/sdk/history/lessons.js +173 -0
  77. package/dist/sdk/history/recall.d.ts +68 -0
  78. package/dist/sdk/history/recall.js +199 -0
  79. package/dist/sdk/history/trajectory.d.ts +7 -0
  80. package/dist/sdk/history/trajectory.js +216 -0
  81. package/dist/sdk/hub/catalog.json +123 -0
  82. package/dist/sdk/hub/cli.d.ts +7 -0
  83. package/dist/sdk/hub/cli.js +81 -0
  84. package/dist/sdk/hub/hub.d.ts +74 -0
  85. package/dist/sdk/hub/hub.js +474 -0
  86. package/dist/sdk/hub/schema.d.ts +280 -0
  87. package/dist/sdk/hub/schema.js +78 -0
  88. package/dist/sdk/index.d.ts +63 -0
  89. package/dist/sdk/index.js +48 -0
  90. package/dist/sdk/mcp/connections.d.ts +83 -0
  91. package/dist/sdk/mcp/connections.js +669 -0
  92. package/dist/sdk/mcp/manager.d.ts +26 -0
  93. package/dist/sdk/mcp/manager.js +124 -0
  94. package/dist/sdk/mcp/oauth.d.ts +35 -0
  95. package/dist/sdk/mcp/oauth.js +171 -0
  96. package/dist/sdk/mcp/scopeMigration.d.ts +19 -0
  97. package/dist/sdk/mcp/scopeMigration.js +198 -0
  98. package/dist/sdk/mcp/service.d.ts +160 -0
  99. package/dist/sdk/mcp/service.js +510 -0
  100. package/dist/sdk/mcp/types.d.ts +131 -0
  101. package/dist/sdk/mcp/types.js +49 -0
  102. package/dist/sdk/pi/runtime.d.ts +13 -0
  103. package/dist/sdk/pi/runtime.js +31 -0
  104. package/dist/sdk/plugins/api.d.ts +66 -0
  105. package/dist/sdk/plugins/api.js +155 -0
  106. package/dist/sdk/plugins/attachments.d.ts +46 -0
  107. package/dist/sdk/plugins/attachments.js +111 -0
  108. package/dist/sdk/plugins/builtin.d.ts +6 -0
  109. package/dist/sdk/plugins/builtin.js +68 -0
  110. package/dist/sdk/plugins/catalogue.d.ts +29 -0
  111. package/dist/sdk/plugins/catalogue.js +196 -0
  112. package/dist/sdk/plugins/cli.d.ts +13 -0
  113. package/dist/sdk/plugins/cli.js +187 -0
  114. package/dist/sdk/plugins/discover.d.ts +42 -0
  115. package/dist/sdk/plugins/discover.js +115 -0
  116. package/dist/sdk/plugins/firstParty.d.ts +50 -0
  117. package/dist/sdk/plugins/firstParty.js +113 -0
  118. package/dist/sdk/plugins/hooks.d.ts +94 -0
  119. package/dist/sdk/plugins/hooks.js +162 -0
  120. package/dist/sdk/plugins/identity.d.ts +19 -0
  121. package/dist/sdk/plugins/identity.js +48 -0
  122. package/dist/sdk/plugins/install.d.ts +20 -0
  123. package/dist/sdk/plugins/install.js +110 -0
  124. package/dist/sdk/plugins/inventory.d.ts +22 -0
  125. package/dist/sdk/plugins/inventory.js +110 -0
  126. package/dist/sdk/plugins/manifest.d.ts +13 -0
  127. package/dist/sdk/plugins/manifest.js +56 -0
  128. package/dist/sdk/plugins/plugins.d.ts +104 -0
  129. package/dist/sdk/plugins/plugins.js +164 -0
  130. package/dist/sdk/plugins/runtime.d.ts +9 -0
  131. package/dist/sdk/plugins/runtime.js +95 -0
  132. package/dist/sdk/plugins/trust.d.ts +44 -0
  133. package/dist/sdk/plugins/trust.js +120 -0
  134. package/dist/sdk/plugins/types.d.ts +159 -0
  135. package/dist/sdk/plugins/types.js +7 -0
  136. package/dist/sdk/prompt/compile.d.ts +174 -0
  137. package/dist/sdk/prompt/compile.js +396 -0
  138. package/dist/sdk/refine/cli.d.ts +4 -0
  139. package/dist/sdk/refine/cli.js +186 -0
  140. package/dist/sdk/refine/demo.d.ts +21 -0
  141. package/dist/sdk/refine/demo.js +114 -0
  142. package/dist/sdk/refine/evidence.d.ts +55 -0
  143. package/dist/sdk/refine/evidence.js +330 -0
  144. package/dist/sdk/refine/host.d.ts +51 -0
  145. package/dist/sdk/refine/host.js +76 -0
  146. package/dist/sdk/refine/ledger.d.ts +48 -0
  147. package/dist/sdk/refine/ledger.js +76 -0
  148. package/dist/sdk/refine/library.d.ts +55 -0
  149. package/dist/sdk/refine/library.js +177 -0
  150. package/dist/sdk/refine/pi.d.ts +72 -0
  151. package/dist/sdk/refine/pi.js +248 -0
  152. package/dist/sdk/refine/prompts.d.ts +45 -0
  153. package/dist/sdk/refine/prompts.js +390 -0
  154. package/dist/sdk/refine/recursion.d.ts +113 -0
  155. package/dist/sdk/refine/recursion.js +258 -0
  156. package/dist/sdk/refine/runner.d.ts +81 -0
  157. package/dist/sdk/refine/runner.js +150 -0
  158. package/dist/sdk/refine/selection.d.ts +57 -0
  159. package/dist/sdk/refine/selection.js +251 -0
  160. package/dist/sdk/refine/service.d.ts +84 -0
  161. package/dist/sdk/refine/service.js +165 -0
  162. package/dist/sdk/refine/suite.d.ts +67 -0
  163. package/dist/sdk/refine/suite.js +174 -0
  164. package/dist/sdk/refine/trajectory.d.ts +9 -0
  165. package/dist/sdk/refine/trajectory.js +68 -0
  166. package/dist/sdk/refine/types.d.ts +77 -0
  167. package/dist/sdk/refine/types.js +10 -0
  168. package/dist/sdk/server/methods.d.ts +3 -0
  169. package/dist/sdk/server/methods.js +370 -0
  170. package/dist/sdk/server/remote.d.ts +19 -0
  171. package/dist/sdk/server/remote.js +84 -0
  172. package/dist/sdk/server/rpc.d.ts +20 -0
  173. package/dist/sdk/server/rpc.js +102 -0
  174. package/dist/sdk/server/serve.d.ts +10 -0
  175. package/dist/sdk/server/serve.js +18 -0
  176. package/dist/sdk/sessions/approvals.d.ts +47 -0
  177. package/dist/sdk/sessions/approvals.js +119 -0
  178. package/dist/sdk/sessions/continuation.d.ts +48 -0
  179. package/dist/sdk/sessions/continuation.js +85 -0
  180. package/dist/sdk/sessions/contracts.d.ts +534 -0
  181. package/dist/sdk/sessions/contracts.js +299 -0
  182. package/dist/sdk/sessions/extensionUi.d.ts +19 -0
  183. package/dist/sdk/sessions/extensionUi.js +64 -0
  184. package/dist/sdk/sessions/history.d.ts +16 -0
  185. package/dist/sdk/sessions/history.js +68 -0
  186. package/dist/sdk/sessions/lineageJoin.d.ts +2 -0
  187. package/dist/sdk/sessions/lineageJoin.js +61 -0
  188. package/dist/sdk/sessions/planMode.d.ts +36 -0
  189. package/dist/sdk/sessions/planMode.js +84 -0
  190. package/dist/sdk/sessions/policy.d.ts +43 -0
  191. package/dist/sdk/sessions/policy.js +1 -0
  192. package/dist/sdk/sessions/pricing.d.ts +34 -0
  193. package/dist/sdk/sessions/pricing.js +40 -0
  194. package/dist/sdk/sessions/reasoningSummaries.d.ts +11 -0
  195. package/dist/sdk/sessions/reasoningSummaries.js +61 -0
  196. package/dist/sdk/sessions/registry.d.ts +102 -0
  197. package/dist/sdk/sessions/registry.js +383 -0
  198. package/dist/sdk/sessions/runIndex.d.ts +21 -0
  199. package/dist/sdk/sessions/runIndex.js +65 -0
  200. package/dist/sdk/sessions/runStore.d.ts +66 -0
  201. package/dist/sdk/sessions/runStore.js +335 -0
  202. package/dist/sdk/sessions/runner.d.ts +213 -0
  203. package/dist/sdk/sessions/runner.js +589 -0
  204. package/dist/sdk/sessions/sessions.d.ts +140 -0
  205. package/dist/sdk/sessions/sessions.js +394 -0
  206. package/dist/sdk/sessions/subagentService.d.ts +41 -0
  207. package/dist/sdk/sessions/subagentService.js +247 -0
  208. package/dist/sdk/sessions/subagents.d.ts +50 -0
  209. package/dist/sdk/sessions/subagents.js +68 -0
  210. package/dist/sdk/terminal/accountsMenu.d.ts +46 -0
  211. package/dist/sdk/terminal/accountsMenu.js +392 -0
  212. package/dist/sdk/terminal/cli.d.ts +20 -0
  213. package/dist/sdk/terminal/cli.js +121 -0
  214. package/dist/sdk/terminal/client.d.ts +15 -0
  215. package/dist/sdk/terminal/client.js +126 -0
  216. package/dist/sdk/terminal/control.d.ts +4 -0
  217. package/dist/sdk/terminal/control.js +25 -0
  218. package/dist/sdk/terminal/controller.d.ts +72 -0
  219. package/dist/sdk/terminal/controller.js +351 -0
  220. package/dist/sdk/terminal/hubMenu.d.ts +10 -0
  221. package/dist/sdk/terminal/hubMenu.js +34 -0
  222. package/dist/sdk/terminal/launch.d.ts +5 -0
  223. package/dist/sdk/terminal/launch.js +27 -0
  224. package/dist/sdk/terminal/logs.d.ts +14 -0
  225. package/dist/sdk/terminal/logs.js +59 -0
  226. package/dist/sdk/terminal/piExtension.d.ts +6 -0
  227. package/dist/sdk/terminal/piExtension.js +392 -0
  228. package/dist/sdk/terminal/pluginMenu.d.ts +34 -0
  229. package/dist/sdk/terminal/pluginMenu.js +101 -0
  230. package/dist/sdk/terminal/socket.d.ts +70 -0
  231. package/dist/sdk/terminal/socket.js +256 -0
  232. package/dist/sdk/terminal/standalone.d.ts +18 -0
  233. package/dist/sdk/terminal/standalone.js +146 -0
  234. package/dist/sdk/terminal/terminals.d.ts +176 -0
  235. package/dist/sdk/terminal/terminals.js +767 -0
  236. package/dist/sdk/terminal/trajectory.d.ts +10 -0
  237. package/dist/sdk/terminal/trajectory.js +30 -0
  238. package/dist/sdk/terminal/tui/chrome.d.ts +64 -0
  239. package/dist/sdk/terminal/tui/chrome.js +169 -0
  240. package/dist/sdk/terminal/tui/clipboardFiles.d.ts +11 -0
  241. package/dist/sdk/terminal/tui/clipboardFiles.js +74 -0
  242. package/dist/sdk/terminal/tui/commandPages.d.ts +7 -0
  243. package/dist/sdk/terminal/tui/commandPages.js +63 -0
  244. package/dist/sdk/terminal/tui/commands.d.ts +42 -0
  245. package/dist/sdk/terminal/tui/commands.js +276 -0
  246. package/dist/sdk/terminal/tui/dialogGeometry.d.ts +27 -0
  247. package/dist/sdk/terminal/tui/dialogGeometry.js +50 -0
  248. package/dist/sdk/terminal/tui/dialogs.d.ts +75 -0
  249. package/dist/sdk/terminal/tui/dialogs.js +363 -0
  250. package/dist/sdk/terminal/tui/keybindings.d.ts +11 -0
  251. package/dist/sdk/terminal/tui/keybindings.js +49 -0
  252. package/dist/sdk/terminal/tui/list.d.ts +73 -0
  253. package/dist/sdk/terminal/tui/list.js +196 -0
  254. package/dist/sdk/terminal/tui/modeChoices.d.ts +42 -0
  255. package/dist/sdk/terminal/tui/modeChoices.js +70 -0
  256. package/dist/sdk/terminal/tui/modelPicker.d.ts +55 -0
  257. package/dist/sdk/terminal/tui/modelPicker.js +155 -0
  258. package/dist/sdk/terminal/tui/mouse.d.ts +3 -0
  259. package/dist/sdk/terminal/tui/mouse.js +3 -0
  260. package/dist/sdk/terminal/tui/page.d.ts +14 -0
  261. package/dist/sdk/terminal/tui/page.js +1 -0
  262. package/dist/sdk/terminal/tui/pageOverlay.d.ts +27 -0
  263. package/dist/sdk/terminal/tui/pageOverlay.js +145 -0
  264. package/dist/sdk/terminal/tui/pages/accountsPage.d.ts +54 -0
  265. package/dist/sdk/terminal/tui/pages/accountsPage.js +181 -0
  266. package/dist/sdk/terminal/tui/pages/componentsPage.d.ts +47 -0
  267. package/dist/sdk/terminal/tui/pages/componentsPage.js +119 -0
  268. package/dist/sdk/terminal/tui/pages/doctorPage.d.ts +37 -0
  269. package/dist/sdk/terminal/tui/pages/doctorPage.js +145 -0
  270. package/dist/sdk/terminal/tui/pages/hubPage.d.ts +39 -0
  271. package/dist/sdk/terminal/tui/pages/hubPage.js +128 -0
  272. package/dist/sdk/terminal/tui/pages/logPage.d.ts +38 -0
  273. package/dist/sdk/terminal/tui/pages/logPage.js +189 -0
  274. package/dist/sdk/terminal/tui/pages/permissionsPage.d.ts +44 -0
  275. package/dist/sdk/terminal/tui/pages/permissionsPage.js +124 -0
  276. package/dist/sdk/terminal/tui/pages/pluginsPage.d.ts +57 -0
  277. package/dist/sdk/terminal/tui/pages/pluginsPage.js +243 -0
  278. package/dist/sdk/terminal/tui/pages/settingsPage.d.ts +55 -0
  279. package/dist/sdk/terminal/tui/pages/settingsPage.js +88 -0
  280. package/dist/sdk/terminal/tui/pages/trajectoryPage.d.ts +58 -0
  281. package/dist/sdk/terminal/tui/pages/trajectoryPage.js +377 -0
  282. package/dist/sdk/terminal/tui/piAdapter.d.ts +18 -0
  283. package/dist/sdk/terminal/tui/piAdapter.js +48 -0
  284. package/dist/sdk/terminal/tui/planMode.d.ts +2 -0
  285. package/dist/sdk/terminal/tui/planMode.js +2 -0
  286. package/dist/sdk/terminal/tui/questionPicker.d.ts +20 -0
  287. package/dist/sdk/terminal/tui/questionPicker.js +150 -0
  288. package/dist/sdk/terminal/tui/questions.d.ts +19 -0
  289. package/dist/sdk/terminal/tui/questions.js +42 -0
  290. package/dist/sdk/terminal/tui/runtime.d.ts +114 -0
  291. package/dist/sdk/terminal/tui/runtime.js +441 -0
  292. package/dist/sdk/terminal/tui/search.d.ts +22 -0
  293. package/dist/sdk/terminal/tui/search.js +60 -0
  294. package/dist/sdk/terminal/tui/selection.d.ts +16 -0
  295. package/dist/sdk/terminal/tui/selection.js +16 -0
  296. package/dist/sdk/terminal/tui/sessionUi.d.ts +3 -0
  297. package/dist/sdk/terminal/tui/sessionUi.js +30 -0
  298. package/dist/sdk/terminal/tui/settingsModel.d.ts +12 -0
  299. package/dist/sdk/terminal/tui/settingsModel.js +84 -0
  300. package/dist/sdk/terminal/tui/sideQuestion.d.ts +53 -0
  301. package/dist/sdk/terminal/tui/sideQuestion.js +197 -0
  302. package/dist/sdk/terminal/tui/skillInvocation.d.ts +9 -0
  303. package/dist/sdk/terminal/tui/skillInvocation.js +43 -0
  304. package/dist/sdk/terminal/tui/status.d.ts +18 -0
  305. package/dist/sdk/terminal/tui/status.js +67 -0
  306. package/dist/sdk/terminal/tui/theme.d.ts +45 -0
  307. package/dist/sdk/terminal/tui/theme.js +176 -0
  308. package/dist/sdk/terminal/tui/treeModel.d.ts +79 -0
  309. package/dist/sdk/terminal/tui/treeModel.js +483 -0
  310. package/dist/sdk/terminal/tui/treePicker.d.ts +49 -0
  311. package/dist/sdk/terminal/tui/treePicker.js +251 -0
  312. package/dist/sdk/terminal/tui/ui.d.ts +47 -0
  313. package/dist/sdk/terminal/tui/ui.js +148 -0
  314. package/dist/sdk/terminal/tui/workingStatus.d.ts +9 -0
  315. package/dist/sdk/terminal/tui/workingStatus.js +229 -0
  316. package/dist/sdk/tools/askUser.d.ts +6 -0
  317. package/dist/sdk/tools/askUser.js +74 -0
  318. package/dist/sdk/tools/checklist.d.ts +9 -0
  319. package/dist/sdk/tools/checklist.js +54 -0
  320. package/dist/sdk/tools/definitions.d.ts +30 -0
  321. package/dist/sdk/tools/definitions.js +117 -0
  322. package/dist/sdk/tools/dispatch.d.ts +16 -0
  323. package/dist/sdk/tools/dispatch.js +67 -0
  324. package/dist/sdk/tools/harnessTools.d.ts +6 -0
  325. package/dist/sdk/tools/harnessTools.js +20 -0
  326. package/dist/sdk/tools/sessionName.d.ts +7 -0
  327. package/dist/sdk/tools/sessionName.js +31 -0
  328. package/dist/sdk/tools/spawnSubagent.d.ts +4 -0
  329. package/dist/sdk/tools/spawnSubagent.js +49 -0
  330. package/dist/sdk/tools/types.d.ts +48 -0
  331. package/dist/sdk/tools/types.js +1 -0
  332. package/dist/sdk/variant/components.d.ts +34 -0
  333. package/dist/sdk/variant/components.js +230 -0
  334. package/dist/sdk/variant/materialise.d.ts +66 -0
  335. package/dist/sdk/variant/materialise.js +81 -0
  336. package/dist/sdk/variant/migrate.d.ts +4 -0
  337. package/dist/sdk/variant/migrate.js +41 -0
  338. package/dist/sdk/variant/seed.d.ts +20 -0
  339. package/dist/sdk/variant/seed.js +116 -0
  340. package/dist/sdk/variant/store.d.ts +82 -0
  341. package/dist/sdk/variant/store.js +151 -0
  342. package/dist/sdk/variant/surface.d.ts +56 -0
  343. package/dist/sdk/variant/surface.js +81 -0
  344. package/dist/sdk/variant/trust.d.ts +27 -0
  345. package/dist/sdk/variant/trust.js +64 -0
  346. package/dist/sdk/variant/variant.d.ts +71 -0
  347. package/dist/sdk/variant/variant.js +331 -0
  348. package/dist/sdk/web/markdown.d.ts +10 -0
  349. package/dist/sdk/web/markdown.js +66 -0
  350. package/dist/sdk/web/safeRequest.d.ts +34 -0
  351. package/dist/sdk/web/safeRequest.js +175 -0
  352. package/dist/sdk/web/search.d.ts +53 -0
  353. package/dist/sdk/web/search.js +168 -0
  354. package/dist/sdk/web/text.d.ts +2 -0
  355. package/dist/sdk/web/text.js +7 -0
  356. package/dist/sdk/web/tools.d.ts +22 -0
  357. package/dist/sdk/web/tools.js +195 -0
  358. package/dist/sdk/web/turndown-plugin-gfm.d.ts +4 -0
  359. package/dist/sdk/wiki/notes.d.ts +68 -0
  360. package/dist/sdk/wiki/notes.js +297 -0
  361. package/dist/sdk/world/actions.d.ts +23 -0
  362. package/dist/sdk/world/actions.js +31 -0
  363. package/dist/sdk/world/cli.d.ts +12 -0
  364. package/dist/sdk/world/cli.js +166 -0
  365. package/dist/sdk/world/images.d.ts +20 -0
  366. package/dist/sdk/world/images.js +48 -0
  367. package/dist/sdk/world/untrusted.d.ts +12 -0
  368. package/dist/sdk/world/untrusted.js +20 -0
  369. package/dist/sdk/world/world.d.ts +65 -0
  370. package/dist/sdk/world/world.js +80 -0
  371. package/dist/terminal-opentui.js +13612 -0
  372. package/dist/terminal-pi.js +1170 -62
  373. package/docs/README.md +34 -0
  374. package/docs/architecture/00-overview.md +159 -0
  375. package/docs/architecture/01-extension-points.md +78 -0
  376. package/docs/architecture/02-sessions-and-runs.md +146 -0
  377. package/docs/architecture/03-variants.md +95 -0
  378. package/docs/architecture/04-prompt.md +102 -0
  379. package/docs/architecture/05-refinement.md +107 -0
  380. package/docs/architecture/06-plugins-and-capabilities.md +93 -0
  381. package/docs/architecture/07-tools-and-gate.md +88 -0
  382. package/docs/architecture/08-memory-and-history.md +94 -0
  383. package/docs/architecture/09-accounts-and-connectors.md +90 -0
  384. package/docs/architecture/10-server-protocol.md +84 -0
  385. package/docs/architecture/11-terminal.md +81 -0
  386. package/docs/architecture/12-storage.md +61 -0
  387. package/docs/architecture/13-world-tools.md +23 -0
  388. package/docs/architecture/README.md +114 -0
  389. package/docs/architecture/proposals/PROP-0001-reporting-section.md +106 -0
  390. package/docs/architecture/proposals/PROP-0002-retain-rollout-workspaces.md +104 -0
  391. package/docs/architecture/proposals/PROP-0003-executor-settings.md +81 -0
  392. package/docs/architecture/proposals/PROP-0004-flexible-reporting-guidance.md +71 -0
  393. package/docs/architecture/proposals/PROP-0005-xharness-cli-name.md +78 -0
  394. package/docs/architecture/proposals/PROP-0006-run-checklist.md +68 -0
  395. package/docs/architecture/proposals/PROP-0007-run-continuation.md +80 -0
  396. package/docs/architecture/proposals/PROP-0008-lessons-from-runs.md +80 -0
  397. package/docs/architecture/proposals/PROP-0009-foundation-and-variants.md +78 -0
  398. package/docs/architecture/proposals/PROP-0010-session-names.md +73 -0
  399. package/docs/architecture/proposals/PROP-0011-doctor.md +63 -0
  400. package/docs/architecture/proposals/PROP-0012-release-baseline.md +56 -0
  401. package/docs/architecture/proposals/README.md +76 -0
  402. package/docs/decisions/ADR-0001-owned-terminal.md +87 -0
  403. package/docs/decisions/ADR-0002-native-subagent-lifecycle.md +49 -0
  404. package/docs/decisions/ADR-0003-shared-asynchronous-subagents.md +70 -0
  405. package/docs/decisions/ADR-0004-fullscreen-terminal-layout.md +50 -0
  406. package/docs/decisions/ADR-0005-app-provided-oauth-clients.md +54 -0
  407. package/docs/decisions/ADR-0006-opentui-only-terminal.md +47 -0
  408. package/docs/decisions/ADR-0007-reporting-section.md +33 -0
  409. package/docs/decisions/ADR-0008-flexible-reporting-guidance.md +38 -0
  410. package/docs/decisions/ADR-0009-xharness-command.md +38 -0
  411. package/docs/decisions/ADR-0010-lessons-in-the-wiki.md +31 -0
  412. package/docs/decisions/ADR-0011-foundation-and-variants.md +28 -0
  413. package/docs/decisions/ADR-0012-native-session-names.md +34 -0
  414. package/docs/decisions/ADR-0013-doctor.md +27 -0
  415. package/docs/decisions/ADR-0014-public-release-baseline.md +21 -0
  416. package/docs/doctor.md +74 -0
  417. package/docs/experiments/EXP-0001-terminal-input-latency/plan.md +81 -0
  418. package/docs/experiments/EXP-0001-terminal-input-latency/results.md +46 -0
  419. package/docs/experiments/EXP-0002-opentui-typing-latency/plan.md +70 -0
  420. package/docs/experiments/EXP-0002-opentui-typing-latency/results.md +92 -0
  421. package/docs/features/README.md +20 -0
  422. package/docs/features/automations/README.md +41 -0
  423. package/docs/features/cores/README.md +39 -0
  424. package/docs/features/google-harness2/README.md +52 -0
  425. package/docs/features/integrations/README.md +40 -0
  426. package/docs/features/interfaces/README.md +29 -0
  427. package/docs/features/memory/README.md +28 -0
  428. package/docs/releases/1.0.0.md +40 -0
  429. package/docs/releases/README.md +36 -0
  430. package/docs/study/00-index.md +78 -0
  431. package/docs/study/arms/00-matrix.md +20 -0
  432. package/docs/study/arms/01-system-prompt.md +211 -0
  433. package/docs/study/arms/02-tools.md +79 -0
  434. package/docs/study/arms/03-subagents.md +90 -0
  435. package/docs/study/arms/04-skills.md +75 -0
  436. package/docs/study/arms/05-context-management.md +90 -0
  437. package/docs/study/arms/06-memory.md +90 -0
  438. package/docs/study/arms/07-governance.md +71 -0
  439. package/docs/study/arms/08-execution.md +69 -0
  440. package/docs/study/arms/09-observability.md +60 -0
  441. package/docs/study/arms/10-refinement.md +110 -0
  442. package/docs/study/btw-comparison.md +37 -0
  443. package/docs/study/feature-gap-review.md +42 -0
  444. package/docs/study/insights.md +123 -0
  445. package/docs/study/roadmap.md +72 -0
  446. package/docs/study/sources/claude-code.md +44 -0
  447. package/docs/study/sources/deepseek-harness.md +102 -0
  448. package/docs/study/sources/harness2.md +50 -0
  449. package/docs/study/sources/kimi-cli.md +42 -0
  450. package/docs/study/sources/omp.md +93 -0
  451. package/docs/study/sources/opencode.md +43 -0
  452. package/docs/study/sources/openhands.md +46 -0
  453. package/docs/study/sources/smolagents.md +40 -0
  454. package/docs/study/sources/swe-agent.md +34 -0
  455. package/docs/system-prompt-design.md +196 -0
  456. package/docs/terminal-tui.md +671 -0
  457. package/package.json +48 -12
  458. package/src/accounts/accounts.test.ts +0 -223
  459. package/src/accounts/accounts.ts +0 -522
  460. package/src/accounts/env.test.ts +0 -95
  461. package/src/accounts/env.ts +0 -338
  462. package/src/accounts/secrets.ts +0 -50
  463. package/src/accounts/store.ts +0 -338
  464. package/src/capabilities/api.ts +0 -75
  465. package/src/capabilities/runSnapshot.ts +0 -59
  466. package/src/capabilities/types.ts +0 -34
  467. package/src/cli.ts +0 -114
  468. package/src/core/bus.ts +0 -34
  469. package/src/core/changes.ts +0 -33
  470. package/src/core/env.ts +0 -27
  471. package/src/core/errors.ts +0 -32
  472. package/src/core/frontmatter.ts +0 -47
  473. package/src/core/fs.test.ts +0 -38
  474. package/src/core/fs.ts +0 -92
  475. package/src/core/index.ts +0 -193
  476. package/src/core/path.test.ts +0 -14
  477. package/src/core/path.ts +0 -79
  478. package/src/core/projects.ts +0 -90
  479. package/src/core/text.ts +0 -39
  480. package/src/harness.ts +0 -299
  481. package/src/index.ts +0 -70
  482. package/src/mcp/connections.ts +0 -614
  483. package/src/mcp/manager.ts +0 -130
  484. package/src/mcp/oauth.ts +0 -195
  485. package/src/mcp/scopeMigration.test.ts +0 -79
  486. package/src/mcp/scopeMigration.ts +0 -204
  487. package/src/mcp/service.test.ts +0 -376
  488. package/src/mcp/service.ts +0 -549
  489. package/src/mcp/types.ts +0 -108
  490. package/src/memory/api.test.ts +0 -82
  491. package/src/memory/api.ts +0 -289
  492. package/src/memory/blocks.test.ts +0 -78
  493. package/src/memory/blocks.ts +0 -406
  494. package/src/memory/caller.ts +0 -57
  495. package/src/memory/dispatch.ts +0 -59
  496. package/src/memory/facts.test.ts +0 -41
  497. package/src/memory/facts.ts +0 -248
  498. package/src/memory/graph.ts +0 -103
  499. package/src/memory/health.test.ts +0 -130
  500. package/src/memory/health.ts +0 -74
  501. package/src/memory/maintainer.ts +0 -272
  502. package/src/memory/maintenance.test.ts +0 -176
  503. package/src/memory/maintenance.ts +0 -330
  504. package/src/memory/migrate.ts +0 -79
  505. package/src/memory/operations.ts +0 -138
  506. package/src/memory/proposals.test.ts +0 -168
  507. package/src/memory/proposals.ts +0 -576
  508. package/src/memory/recall.test.ts +0 -104
  509. package/src/memory/recall.ts +0 -271
  510. package/src/memory/references.ts +0 -77
  511. package/src/memory/runContext.ts +0 -93
  512. package/src/memory/secrets.ts +0 -6
  513. package/src/memory/store.test.ts +0 -66
  514. package/src/memory/store.ts +0 -385
  515. package/src/memory/wiki.test.ts +0 -47
  516. package/src/memory/wiki.ts +0 -422
  517. package/src/memory/wikiIndex.test.ts +0 -88
  518. package/src/memory/wikiIndex.ts +0 -116
  519. package/src/plugins/api.ts +0 -181
  520. package/src/plugins/attachments.test.ts +0 -84
  521. package/src/plugins/attachments.ts +0 -141
  522. package/src/plugins/builtin.ts +0 -82
  523. package/src/plugins/catalogue.test.ts +0 -254
  524. package/src/plugins/catalogue.ts +0 -251
  525. package/src/plugins/cli.ts +0 -184
  526. package/src/plugins/discover.ts +0 -151
  527. package/src/plugins/firstParty.test.ts +0 -143
  528. package/src/plugins/firstParty.ts +0 -129
  529. package/src/plugins/hooks.test.ts +0 -250
  530. package/src/plugins/hooks.ts +0 -239
  531. package/src/plugins/identity.ts +0 -37
  532. package/src/plugins/install.test.ts +0 -107
  533. package/src/plugins/install.ts +0 -106
  534. package/src/plugins/inventory.ts +0 -123
  535. package/src/plugins/manifest.ts +0 -76
  536. package/src/plugins/plugins.test.ts +0 -205
  537. package/src/plugins/plugins.ts +0 -189
  538. package/src/plugins/proposal.ts +0 -121
  539. package/src/plugins/runtime.test.ts +0 -40
  540. package/src/plugins/runtime.ts +0 -82
  541. package/src/plugins/trust.ts +0 -142
  542. package/src/plugins/types.ts +0 -149
  543. package/src/prompt/compile.test.ts +0 -261
  544. package/src/prompt/compile.ts +0 -732
  545. package/src/server/methods.ts +0 -314
  546. package/src/server/remote.ts +0 -77
  547. package/src/server/rpc.ts +0 -116
  548. package/src/server/serve.ts +0 -28
  549. package/src/server/server.test.ts +0 -174
  550. package/src/sessions/approvals.ts +0 -118
  551. package/src/sessions/contracts.ts +0 -310
  552. package/src/sessions/conversation.test.ts +0 -150
  553. package/src/sessions/extensionSession.test.ts +0 -74
  554. package/src/sessions/extensionUi.test.ts +0 -65
  555. package/src/sessions/extensionUi.ts +0 -102
  556. package/src/sessions/history.ts +0 -51
  557. package/src/sessions/lineageJoin.ts +0 -75
  558. package/src/sessions/policy.ts +0 -32
  559. package/src/sessions/pricing.ts +0 -60
  560. package/src/sessions/reasoningSummaries.ts +0 -59
  561. package/src/sessions/registry.ts +0 -294
  562. package/src/sessions/runIndex.ts +0 -99
  563. package/src/sessions/runStore.test.ts +0 -152
  564. package/src/sessions/runStore.ts +0 -332
  565. package/src/sessions/runner.ts +0 -569
  566. package/src/sessions/runtimeResources.test.ts +0 -61
  567. package/src/sessions/sessions.test.ts +0 -455
  568. package/src/sessions/sessions.ts +0 -295
  569. package/src/skills/registry.test.ts +0 -104
  570. package/src/skills/registry.ts +0 -407
  571. package/src/terminal/cli.ts +0 -149
  572. package/src/terminal/client.ts +0 -74
  573. package/src/terminal/controller.ts +0 -227
  574. package/src/terminal/launch.test.ts +0 -34
  575. package/src/terminal/launch.ts +0 -88
  576. package/src/terminal/piExtension.ts +0 -210
  577. package/src/terminal/pluginControl.test.ts +0 -146
  578. package/src/terminal/pluginMenu.ts +0 -112
  579. package/src/terminal/socket.test.ts +0 -71
  580. package/src/terminal/socket.ts +0 -221
  581. package/src/terminal/standalone.test.ts +0 -130
  582. package/src/terminal/standalone.ts +0 -144
  583. package/src/terminal/terminal.test.ts +0 -330
  584. package/src/terminal/terminals.ts +0 -443
  585. package/src/tools/askUser.ts +0 -45
  586. package/src/tools/definitions.ts +0 -187
  587. package/src/tools/memoryTools.ts +0 -22
  588. package/src/tools/pluginPropose.ts +0 -41
  589. package/src/tools/types.ts +0 -39
  590. package/src/web/safeRequest.ts +0 -171
  591. package/src/web/text.ts +0 -53
  592. package/src/web/tools.ts +0 -134
  593. package/src/web/web.test.ts +0 -141
@@ -0,0 +1,115 @@
1
+ // What Pi would load for a session, found with Pi's own resolver so the list matches Pi's
2
+ // rules. Resolving reads folders and manifests; it never runs an extension.
3
+ import { existsSync } from 'node:fs';
4
+ import { homedir } from 'node:os';
5
+ import { join, sep } from 'node:path';
6
+ import { log } from "../core/bus.js";
7
+ import { loadPi } from "../pi/runtime.js";
8
+ import { packageManifest } from "./manifest.js";
9
+ /** The extensions built into the `pi` command. A terminal loads them; an SDK session has none. */
10
+ export const PI_BUILTINS = ['llama.cpp', 'codemode', 'tool-search', 'mcp'];
11
+ export const BUILTIN_PREFIX = 'builtin:';
12
+ const inside = (path, parent) => path === parent || path.startsWith(parent.endsWith(sep) ? parent : `${parent}${sep}`);
13
+ function origin(path, metadata) {
14
+ if (path.startsWith(BUILTIN_PREFIX))
15
+ return 'builtin';
16
+ if (metadata.origin === 'package')
17
+ return 'package';
18
+ if (metadata.scope === 'project')
19
+ return 'project';
20
+ return metadata.baseDir && inside(metadata.baseDir, join(process.env.HOME || homedir(), '.agents')) ? 'home' : 'shared';
21
+ }
22
+ /**
23
+ * Runs an install with the package manager's install scripts switched off, so fetching a
24
+ * package runs none of its code. A package that builds itself on install then fails to load,
25
+ * and says so; that is the price of installing being safe to do before trust.
26
+ */
27
+ export async function withoutInstallScripts(action) {
28
+ const before = process.env.npm_config_ignore_scripts;
29
+ process.env.npm_config_ignore_scripts = 'true';
30
+ try {
31
+ return await action();
32
+ }
33
+ finally {
34
+ if (before === undefined)
35
+ delete process.env.npm_config_ignore_scripts;
36
+ else
37
+ process.env.npm_config_ignore_scripts = before;
38
+ }
39
+ }
40
+ export const piResolver = async ({ cwd, agentDir, install, packages }) => {
41
+ const pi = await loadPi();
42
+ const settings = pi.SettingsManager.create(cwd, agentDir);
43
+ const shared = new Set((settings.getGlobalSettings().packages ?? []).map((entry) => (typeof entry === 'string' ? entry : entry.source)));
44
+ const manager = () => new pi.DefaultPackageManager({ cwd, agentDir, settingsManager: settings, builtinExtensions: [...PI_BUILTINS] });
45
+ const resolve = (installing) => manager().resolve(async (source) => (installing && shared.has(source) ? 'install' : 'skip'));
46
+ let resolved;
47
+ try {
48
+ resolved = install ? await withoutInstallScripts(() => resolve(true)) : await resolve(false);
49
+ }
50
+ catch (error) {
51
+ if (!install)
52
+ throw error;
53
+ // A package that cannot be installed must not stop the session; it is found again next time.
54
+ log('a plugin package could not be installed', error instanceof Error ? error.message : String(error));
55
+ resolved = await resolve(false);
56
+ }
57
+ const found = [];
58
+ const add = (paths) => {
59
+ const kinds = [['extension', paths.extensions], ['skill', paths.skills], ['prompt', paths.prompts], ['theme', paths.themes]];
60
+ for (const [kind, resources] of kinds) {
61
+ for (const resource of resources) {
62
+ const metadata = resource.metadata;
63
+ const packaged = metadata.origin === 'package';
64
+ found.push({
65
+ kind,
66
+ path: resource.path,
67
+ origin: origin(resource.path, metadata),
68
+ project: metadata.scope === 'project',
69
+ packageRoot: packaged ? (metadata.packageRoot ?? metadata.baseDir ?? null) : null,
70
+ source: packaged ? metadata.source : null,
71
+ enabled: resource.enabled
72
+ });
73
+ }
74
+ }
75
+ };
76
+ add(resolved);
77
+ // Packages a person keeps beside their data are read where they are; nothing is fetched for them.
78
+ if (packages?.length) {
79
+ try {
80
+ add(await manager().resolveExtensionSources([...packages]));
81
+ }
82
+ catch (error) {
83
+ log('a local plugin could not be read', error instanceof Error ? error.message : String(error));
84
+ }
85
+ }
86
+ // A package may name a hooks file for the harness. Only a package a person installed counts:
87
+ // a working folder's package cannot put code into the harness's own process.
88
+ const roots = new Map();
89
+ for (const configured of manager().listConfiguredPackages())
90
+ if (configured.scope === 'user' && configured.installedPath)
91
+ roots.set(configured.installedPath, configured.source);
92
+ for (const folder of packages ?? [])
93
+ roots.set(folder, folder);
94
+ for (const [root, source] of roots) {
95
+ const hooks = packageManifest(root).hooks;
96
+ if (!hooks || !existsSync(join(root, hooks)))
97
+ continue;
98
+ found.push({ kind: 'hook', path: join(root, hooks), origin: 'package', project: false, packageRoot: root, source, enabled: true });
99
+ // Pi takes a folder with none of its own resources to be an extension itself. A package that
100
+ // only brings hooks is not one, and must not be handed to Pi as code to load.
101
+ const fallback = found.findIndex((item) => item.kind === 'extension' && item.path === root);
102
+ if (fallback !== -1)
103
+ found.splice(fallback, 1);
104
+ }
105
+ // Pi reads these itself, whatever else is switched off. They are text, so they are only listed.
106
+ const context = [
107
+ ...pi.loadProjectContextFiles({ cwd, agentDir }).map((file) => file.path),
108
+ ...[join(agentDir, 'SYSTEM.md'), join(agentDir, 'APPEND_SYSTEM.md'), join(cwd, '.pi', 'SYSTEM.md'), join(cwd, '.pi', 'APPEND_SYSTEM.md')].filter((path) => existsSync(path))
109
+ ];
110
+ for (const path of context) {
111
+ const shared = inside(path, agentDir);
112
+ found.push({ kind: 'context', path, origin: shared ? 'shared' : 'project', project: !shared, packageRoot: null, source: null, enabled: true });
113
+ }
114
+ return found;
115
+ };
@@ -0,0 +1,50 @@
1
+ import type { PluginDescriptor, PluginSetting } from "./types.js";
2
+ /** The part of Pi's extension API these two use. */
3
+ interface Api {
4
+ on(event: 'tool_result', handler: (event: ToolResult) => unknown): void;
5
+ on(event: 'tool_call', handler: (event: {
6
+ toolName: string;
7
+ }) => unknown): void;
8
+ on(event: 'turn_start', handler: () => unknown): void;
9
+ on(event: 'message_end', handler: (event: {
10
+ message: {
11
+ role: string;
12
+ usage?: {
13
+ input?: number;
14
+ output?: number;
15
+ cacheRead?: number;
16
+ cacheWrite?: number;
17
+ };
18
+ };
19
+ }) => unknown): void;
20
+ }
21
+ interface ToolResult {
22
+ toolName: string;
23
+ content: ({
24
+ type: 'text';
25
+ text: string;
26
+ } | {
27
+ type: string;
28
+ [key: string]: unknown;
29
+ })[];
30
+ }
31
+ export declare const OUTPUT_TRIM = "output-trim";
32
+ export declare const BUDGET_GUARD = "budget-guard";
33
+ export declare const LESSONS = "lessons";
34
+ export declare const LESSONS_CODE = "Reflect after a run";
35
+ export declare const LESSONS_SETTINGS: PluginSetting[];
36
+ export declare const FIRST_PARTY_PLUGINS: readonly PluginDescriptor[];
37
+ /** A setting's value: what a person saved when it is a number inside the setting's range, else its default. */
38
+ export declare function settingValue(setting: PluginSetting, saved: Record<string, unknown> | undefined): number;
39
+ /** The text of a long result, cut to its first 70% and its last 30% of `maxChars`, with a line between that says what is missing. */
40
+ export declare function trimText(text: string, maxChars: number): string;
41
+ export declare function outputTrim(saved: Record<string, unknown> | undefined): (pi: Api) => void;
42
+ export declare function budgetGuard(saved: Record<string, unknown> | undefined): (pi: Api) => void;
43
+ export interface InlineExtension {
44
+ name: string;
45
+ /** A Pi extension factory. Typed loosely so this module needs nothing of Pi's to be loaded. */
46
+ factory: unknown;
47
+ }
48
+ /** The first-party extensions switched on for a caller, each with the settings a person saved. */
49
+ export declare function firstPartyExtensions(on: (pluginId: string) => boolean, settings: Record<string, Record<string, unknown>>): InlineExtension[];
50
+ export {};
@@ -0,0 +1,113 @@
1
+ export const OUTPUT_TRIM = 'output-trim';
2
+ export const BUDGET_GUARD = 'budget-guard';
3
+ export const LESSONS = 'lessons';
4
+ export const LESSONS_CODE = 'Reflect after a run';
5
+ const OUTPUT_TRIM_SETTINGS = [
6
+ { key: 'maxChars', label: 'Longest tool result', description: 'A tool result longer than this many characters is cut to its beginning and its end.', default: 20_000, min: 2_000, max: 400_000 }
7
+ ];
8
+ const BUDGET_GUARD_SETTINGS = [
9
+ { key: 'maxRequests', label: 'Model requests in one reply', description: 'After this many model requests in one reply or one run of work, tool calls are refused so the agent wraps up.', default: 60, min: 5, max: 2_000 },
10
+ { key: 'maxTokens', label: 'Tokens in one reply', description: 'The same, counted in tokens of every kind (cached ones included). 0 means no token limit.', default: 0, min: 0, max: 500_000_000 }
11
+ ];
12
+ export const LESSONS_SETTINGS = [
13
+ { key: 'minToolCalls', label: 'Tool calls before reflecting', description: 'Only a run that made at least this many tool calls is reflected on; shorter runs rarely teach anything.', default: 4, min: 1, max: 1_000 },
14
+ { key: 'maxLessons', label: 'Most lessons kept', description: 'Once the Wiki holds this many lessons, no new one is written until some are removed.', default: 100, min: 1, max: 1_000 },
15
+ { key: 'maxChars', label: 'Longest lesson', description: 'A lesson longer than this many characters is not kept.', default: 2_000, min: 200, max: 10_000 }
16
+ ];
17
+ export const FIRST_PARTY_PLUGINS = [
18
+ {
19
+ id: OUTPUT_TRIM,
20
+ title: 'Output trim',
21
+ description: 'Cuts a very long tool result to its beginning and its end before the model reads it, and says how much was cut.',
22
+ switchable: { on: false },
23
+ settings: OUTPUT_TRIM_SETTINGS,
24
+ code: [{ name: 'Trim long tool results', description: 'Runs after every tool call, in conversations, task threads and unattended work. Not in terminal sessions yet.' }]
25
+ },
26
+ {
27
+ id: BUDGET_GUARD,
28
+ title: 'Budget guard',
29
+ description: 'Stops a reply that keeps going: past a limit of model requests or tokens, further tool calls are refused and the agent is told to wrap up.',
30
+ switchable: { on: false },
31
+ settings: BUDGET_GUARD_SETTINGS,
32
+ code: [{ name: 'Refuse tool calls past the limit', description: 'Counts model requests and tokens in one reply, in conversations, task threads and unattended work. Not in terminal sessions yet.' }]
33
+ },
34
+ {
35
+ id: LESSONS,
36
+ title: 'Lessons',
37
+ description: 'After a finished run, a short reflection reads what happened and may keep one general lesson in the Wiki under library/lessons, for later runs to find. It uses the same account and model as the run, so it costs tokens.',
38
+ switchable: { on: false },
39
+ settings: LESSONS_SETTINGS,
40
+ code: [{ name: LESSONS_CODE, description: 'Runs in the background after a completed top-level run with enough tool calls. It reads only that run\'s record, has no tools that change anything, and writes at most one Wiki note.' }]
41
+ }
42
+ ];
43
+ /** A setting's value: what a person saved when it is a number inside the setting's range, else its default. */
44
+ export function settingValue(setting, saved) {
45
+ const value = saved?.[setting.key];
46
+ return typeof value === 'number' && Number.isFinite(value) && value >= setting.min && value <= setting.max ? Math.floor(value) : setting.default;
47
+ }
48
+ const values = (settings, saved) => Object.fromEntries(settings.map((setting) => [setting.key, settingValue(setting, saved)]));
49
+ /** The text of a long result, cut to its first 70% and its last 30% of `maxChars`, with a line between that says what is missing. */
50
+ export function trimText(text, maxChars) {
51
+ if (text.length <= maxChars)
52
+ return text;
53
+ const head = Math.floor(maxChars * 0.7);
54
+ const tail = maxChars - head;
55
+ const cut = text.length - maxChars;
56
+ return `${text.slice(0, head)}\n\n[… ${cut} of ${text.length} characters were cut here by the Output trim plugin. Ask for a narrower result (a line range, a filter, a smaller file) to see them. …]\n\n${text.slice(text.length - tail)}`;
57
+ }
58
+ export function outputTrim(saved) {
59
+ const { maxChars } = values(OUTPUT_TRIM_SETTINGS, saved);
60
+ return (pi) => {
61
+ pi.on('tool_result', (event) => {
62
+ const texts = event.content.filter((part) => part.type === 'text' && typeof part.text === 'string');
63
+ const total = texts.reduce((sum, part) => sum + part.text.length, 0);
64
+ if (total <= maxChars)
65
+ return undefined;
66
+ // Several text parts are read as one result; pictures and anything else pass through untouched.
67
+ const trimmed = trimText(texts.map((part) => part.text).join('\n'), maxChars);
68
+ return { content: [{ type: 'text', text: trimmed }, ...event.content.filter((part) => part.type !== 'text')] };
69
+ });
70
+ };
71
+ }
72
+ export function budgetGuard(saved) {
73
+ const { maxRequests, maxTokens } = values(BUDGET_GUARD_SETTINGS, saved);
74
+ return (pi) => {
75
+ let requests = 0;
76
+ let tokens = 0;
77
+ let refusedInRequest = 0;
78
+ pi.on('turn_start', () => {
79
+ requests += 1;
80
+ });
81
+ pi.on('message_end', (event) => {
82
+ if (event.message.role !== 'assistant' || !event.message.usage)
83
+ return;
84
+ const usage = event.message.usage;
85
+ tokens += (usage.input ?? 0) + (usage.output ?? 0) + (usage.cacheRead ?? 0) + (usage.cacheWrite ?? 0);
86
+ });
87
+ // Pi's own event before a request can change what is sent and cannot refuse it, so the limit
88
+ // is held where the loop can be stopped: at the tool calls that keep it going.
89
+ pi.on('tool_call', () => {
90
+ const over = requests >= maxRequests ? `${maxRequests} model requests` : maxTokens > 0 && tokens >= maxTokens ? `${maxTokens} tokens` : null;
91
+ if (!over)
92
+ return undefined;
93
+ // The first refusal leaves the agent one request to say what is done. If it calls tools
94
+ // again instead, the batch ends the reply.
95
+ const again = refusedInRequest !== 0 && refusedInRequest !== requests;
96
+ refusedInRequest ||= requests;
97
+ return {
98
+ block: true,
99
+ terminate: again,
100
+ reason: `This reply reached its limit of ${over} (the Budget guard plugin). Call no more tools. Tell the user what is done and what is left; they can raise the limit on the Plugins page.`
101
+ };
102
+ });
103
+ };
104
+ }
105
+ /** The first-party extensions switched on for a caller, each with the settings a person saved. */
106
+ export function firstPartyExtensions(on, settings) {
107
+ const extensions = [];
108
+ if (on(OUTPUT_TRIM))
109
+ extensions.push({ name: OUTPUT_TRIM, factory: outputTrim(settings[OUTPUT_TRIM]) });
110
+ if (on(BUDGET_GUARD))
111
+ extensions.push({ name: BUDGET_GUARD, factory: budgetGuard(settings[BUDGET_GUARD]) });
112
+ return extensions;
113
+ }
@@ -0,0 +1,94 @@
1
+ import type { Bus } from "../core/bus.js";
2
+ import { type Change } from "../core/changes.js";
3
+ export declare const HOOK_EVENTS: readonly ["wiki.page.saved", "history.run.ended"];
4
+ export type HookEventType = (typeof HOOK_EVENTS)[number];
5
+ /** A Wiki note, as it is after the change. */
6
+ export interface EntryEvent {
7
+ type: 'wiki.page.saved';
8
+ id: string;
9
+ path: string;
10
+ title: string;
11
+ /** The entry without its front matter. */
12
+ body: string;
13
+ /** The whole file. */
14
+ text: string;
15
+ /** Who made the change: `user`, an agent's name, or the background upkeep. */
16
+ actor: string;
17
+ reason: string;
18
+ at: string;
19
+ }
20
+ export interface RunEndedEvent {
21
+ type: 'history.run.ended';
22
+ runId: string;
23
+ sessionId: string;
24
+ status: string;
25
+ goal: string | null;
26
+ agentId: string | null;
27
+ projectId: string | null;
28
+ startedAt: string;
29
+ endedAt: string | null;
30
+ at: string;
31
+ }
32
+ export type HookEvent = EntryEvent | RunEndedEvent;
33
+ export interface HookContext {
34
+ /** Calls a tool of a connected app that is on for everyone, if a person marked that tool to run without asking. */
35
+ call(connection: string, tool: string, args?: Record<string, unknown>): Promise<unknown>;
36
+ log(message: string): void;
37
+ }
38
+ type Handler = (event: HookEvent, context: HookContext) => unknown;
39
+ /** What a hooks file is given: `export default function (harness) { harness.on('wiki.page.saved', …) }`. */
40
+ export interface HookApi {
41
+ on(event: HookEventType, handler: Handler): void;
42
+ }
43
+ export interface HookTarget {
44
+ /** The hooks file. */
45
+ path: string;
46
+ /** A hash of the package's code, so a changed file is loaded again. */
47
+ hash: string;
48
+ }
49
+ export interface HookStatus {
50
+ /** The events it listens for. */
51
+ events: string[];
52
+ lastRunAt: string | null;
53
+ /** Why it could not be loaded, or what its last failing run threw. */
54
+ lastError: string | null;
55
+ }
56
+ export interface HooksOptions {
57
+ stateDir: string;
58
+ bus: Bus;
59
+ /** The hooks files that should run now: attached for everyone, and trusted. */
60
+ wanted: () => Promise<HookTarget[]>;
61
+ call: HookContext['call'];
62
+ /** How long one handler may take. */
63
+ timeoutMs?: number;
64
+ /** Reads a hooks file as a module. Replaced in tests, where the runner owns `import()`. */
65
+ importFile?: (address: string) => Promise<unknown>;
66
+ }
67
+ /** Which event a written file is, from where it is in the Wiki. */
68
+ export declare function entryEvent(change: Change): EntryEvent;
69
+ export declare class Hooks {
70
+ private readonly options;
71
+ private loaded;
72
+ private readonly queue;
73
+ private working;
74
+ private reloading;
75
+ private readonly statusPath;
76
+ private wiki;
77
+ private readonly stop;
78
+ constructor(options: HooksOptions);
79
+ /** The Wiki whose changes these hooks hear about. */
80
+ watch(wiki: string | null): void;
81
+ /** What each hooks file listens for, and how its last run went. */
82
+ status(): Record<string, HookStatus>;
83
+ private record;
84
+ /** Loads the hooks files that should run and drops the ones that should not. Safe to call often. */
85
+ reload(): Promise<void>;
86
+ /** Takes an event down. It is delivered afterwards, in the order events arrived. */
87
+ emit(event: HookEvent): void;
88
+ private drain;
89
+ private run;
90
+ /** Resolves when every event taken down so far was delivered. */
91
+ settled(): Promise<void>;
92
+ close(): void;
93
+ }
94
+ export {};
@@ -0,0 +1,162 @@
1
+ // Hooks: code a plugin gives the harness to run after something changed. A Pi extension lives
2
+ // only while a session is open, and most memory is written outside one (a person accepts an
3
+ // Inbox item, edits a fact, the background upkeep runs), so these are the harness's own events,
4
+ // delivered in its own process.
5
+ //
6
+ // A hook is told after the fact. It cannot stop or change a write, it runs with a time limit,
7
+ // and what it throws is recorded and shown on its plugin. It reaches outside only through
8
+ // `ctx.call`, which the harness limits to connected-app tools a person marked to run without asking.
9
+ import { chmodSync } from 'node:fs';
10
+ import { join } from 'node:path';
11
+ import { pathToFileURL } from 'node:url';
12
+ import { log } from "../core/bus.js";
13
+ import { onChange } from "../core/changes.js";
14
+ import * as frontmatter from "../core/frontmatter.js";
15
+ import { now, readJsonOr, writeJson } from "../core/fs.js";
16
+ export const HOOK_EVENTS = ['wiki.page.saved', 'history.run.ended'];
17
+ // Node's own `import()`, out of reach of a bundler or a test runner that would rewrite it: a hooks
18
+ // file is a person's file on disk, loaded as it is, and its address must reach Node unchanged.
19
+ const importFile = new Function('address', 'return import(address)');
20
+ /** Which event a written file is, from where it is in the Wiki. */
21
+ export function entryEvent(change) {
22
+ const type = 'wiki.page.saved';
23
+ const parsed = frontmatter.parse(change.text);
24
+ const front = (parsed?.front ?? {});
25
+ const title = typeof front.title === 'string' ? front.title : typeof front.label === 'string' ? front.label : change.id;
26
+ return { type, id: change.id, path: change.path, title, body: (parsed?.body ?? change.text).trim(), text: change.text, actor: change.actor, reason: change.reason, at: now() };
27
+ }
28
+ export class Hooks {
29
+ options;
30
+ loaded = [];
31
+ queue = [];
32
+ working = Promise.resolve();
33
+ reloading = Promise.resolve();
34
+ statusPath;
35
+ wiki = null;
36
+ stop;
37
+ constructor(options) {
38
+ this.options = options;
39
+ this.statusPath = join(options.stateDir, 'plugin-hooks.json');
40
+ this.stop = onChange((change) => {
41
+ // Several harnesses can share a process; each hears only about its own Wiki.
42
+ if (change.wiki === this.wiki)
43
+ this.emit(entryEvent(change));
44
+ });
45
+ }
46
+ /** The Wiki whose changes these hooks hear about. */
47
+ watch(wiki) {
48
+ this.wiki = wiki;
49
+ }
50
+ /** What each hooks file listens for, and how its last run went. */
51
+ status() {
52
+ return readJsonOr(this.statusPath, {});
53
+ }
54
+ record(path, change) {
55
+ const all = this.status();
56
+ const before = all[path] ?? { events: [], lastRunAt: null, lastError: null };
57
+ const next = { ...before, ...change };
58
+ if (JSON.stringify(before) === JSON.stringify(next) && all[path])
59
+ return;
60
+ all[path] = next;
61
+ writeJson(this.statusPath, all);
62
+ chmodSync(this.statusPath, 0o600);
63
+ // A new failure, or a failure that cleared, is something a person looking at the plugin should see.
64
+ if (before.lastError !== next.lastError || before.events.join() !== next.events.join())
65
+ this.options.bus.emit({ type: 'plugins.changed' });
66
+ }
67
+ /** Loads the hooks files that should run and drops the ones that should not. Safe to call often. */
68
+ reload() {
69
+ this.reloading = this.reloading.then(async () => {
70
+ let wanted;
71
+ try {
72
+ wanted = await this.options.wanted();
73
+ }
74
+ catch (error) {
75
+ log('plugin hooks', error instanceof Error ? error.message : String(error));
76
+ return;
77
+ }
78
+ const next = [];
79
+ for (const target of wanted) {
80
+ const kept = this.loaded.find((hook) => hook.path === target.path && hook.hash === target.hash);
81
+ if (kept) {
82
+ next.push(kept);
83
+ continue;
84
+ }
85
+ const handlers = new Map();
86
+ try {
87
+ // The hash is part of the address, so a changed file is read again and not served from the module cache.
88
+ const module = (await (this.options.importFile ?? importFile)(`${pathToFileURL(target.path).href}?v=${target.hash}`));
89
+ if (typeof module.default !== 'function')
90
+ throw new Error('It must export a default function.');
91
+ const api = {
92
+ on: (event, handler) => {
93
+ if (!HOOK_EVENTS.includes(event))
94
+ throw new Error(`There is no event called "${String(event)}". The events are ${HOOK_EVENTS.join(', ')}.`);
95
+ if (typeof handler !== 'function')
96
+ throw new Error('A handler must be a function.');
97
+ handlers.set(event, [...(handlers.get(event) ?? []), handler]);
98
+ }
99
+ };
100
+ await module.default(api);
101
+ next.push({ ...target, handlers });
102
+ this.record(target.path, { events: [...handlers.keys()], lastError: null });
103
+ }
104
+ catch (error) {
105
+ this.record(target.path, { events: [], lastError: `It could not be loaded: ${error instanceof Error ? error.message : String(error)}` });
106
+ }
107
+ }
108
+ this.loaded = next;
109
+ });
110
+ return this.reloading;
111
+ }
112
+ /** Takes an event down. It is delivered afterwards, in the order events arrived. */
113
+ emit(event) {
114
+ this.queue.push(event);
115
+ this.working = this.working.then(() => this.drain());
116
+ }
117
+ async drain() {
118
+ // A file can change on disk without anyone telling the harness. What is loaded is checked
119
+ // against what should run before it is told anything, so code that changed since it was
120
+ // trusted stops here. With nothing loaded there is nothing to check: a new hook arrives
121
+ // with a `plugins.changed` notice.
122
+ if (this.loaded.length)
123
+ await this.reload();
124
+ else
125
+ await this.reloading;
126
+ for (let event = this.queue.shift(); event; event = this.queue.shift()) {
127
+ for (const hook of this.loaded) {
128
+ for (const handler of hook.handlers.get(event.type) ?? [])
129
+ await this.run(hook, handler, event);
130
+ }
131
+ }
132
+ }
133
+ async run(hook, handler, event) {
134
+ const context = { call: this.options.call, log: (message) => log(`plugin hook ${hook.path}`, String(message)) };
135
+ let timer;
136
+ try {
137
+ await Promise.race([
138
+ Promise.resolve().then(() => handler(event, context)),
139
+ new Promise((_, reject) => {
140
+ timer = setTimeout(() => reject(new Error(`It took longer than ${Math.round((this.options.timeoutMs ?? 30_000) / 1000)} seconds and was left behind.`)), this.options.timeoutMs ?? 30_000);
141
+ })
142
+ ]);
143
+ this.record(hook.path, { lastRunAt: now(), lastError: null });
144
+ }
145
+ catch (error) {
146
+ this.record(hook.path, { lastRunAt: now(), lastError: `${event.type}: ${error instanceof Error ? error.message : String(error)}`.slice(0, 1000) });
147
+ }
148
+ finally {
149
+ if (timer)
150
+ clearTimeout(timer);
151
+ }
152
+ }
153
+ /** Resolves when every event taken down so far was delivered. */
154
+ async settled() {
155
+ await this.reloading;
156
+ await this.working;
157
+ }
158
+ close() {
159
+ this.stop();
160
+ this.loaded = [];
161
+ }
162
+ }
@@ -0,0 +1,19 @@
1
+ import { type Found } from "./discover.js";
2
+ import type { ContributionKind } from "./types.js";
3
+ export { packageManifest } from "./manifest.js";
4
+ export declare const FOUND_KINDS: Record<Found['kind'], ContributionKind>;
5
+ /** The id of the plugin a found item is listed under. */
6
+ export declare function pluginIdOf(item: Found): string;
7
+ /** A found item's name and description as a person reads them. */
8
+ export declare function describeFound(item: Found): {
9
+ name: string;
10
+ description: string | null;
11
+ };
12
+ export declare const contributionId: (pluginId: string, kind: ContributionKind, name: string) => string;
13
+ /** The ids a choice about a found item is stored under: the item itself, then its plugin. */
14
+ export declare function foundIds(item: Found): [string, string];
15
+ /** A Markdown file's `name` and `description` frontmatter; a `SKILL.md` is named after its folder. */
16
+ export declare function describeFile(path: string): {
17
+ name: string;
18
+ description: string;
19
+ } | null;
@@ -0,0 +1,48 @@
1
+ // Which plugin a found file belongs to, and what it is called there. The list a person sees and
2
+ // the choice of what loads both use this, so a switch on the page names exactly what stops loading.
3
+ import { readFileSync } from 'node:fs';
4
+ import { basename, dirname } from 'node:path';
5
+ import * as frontmatter from "../core/frontmatter.js";
6
+ import { BUILTIN_PREFIX } from "./discover.js";
7
+ import { packageManifest } from "./manifest.js";
8
+ export { packageManifest } from "./manifest.js";
9
+ export const FOUND_KINDS = { extension: 'code', hook: 'code', skill: 'skill', prompt: 'command', theme: 'theme', context: 'instruction' };
10
+ /** The id of the plugin a found item is listed under. */
11
+ export function pluginIdOf(item) {
12
+ if (item.origin === 'builtin')
13
+ return 'pi';
14
+ if (item.packageRoot)
15
+ return `package:${packageManifest(item.packageRoot).name}`;
16
+ return item.origin === 'home' ? 'home' : item.origin === 'project' ? 'project' : 'shared';
17
+ }
18
+ /** A found item's name and description as a person reads them. */
19
+ export function describeFound(item) {
20
+ if (item.path.startsWith(BUILTIN_PREFIX))
21
+ return { name: item.path.slice(BUILTIN_PREFIX.length), description: null };
22
+ const file = basename(item.path);
23
+ if (item.kind === 'extension')
24
+ return { name: file.startsWith('index.') ? basename(dirname(item.path)) : file, description: null };
25
+ if (item.kind === 'context' || item.kind === 'theme' || item.kind === 'hook')
26
+ return { name: file, description: null };
27
+ const described = describeFile(item.path);
28
+ return { name: described?.name ?? file, description: described?.description ?? '' };
29
+ }
30
+ export const contributionId = (pluginId, kind, name) => `${pluginId}/${kind}/${name}`;
31
+ /** The ids a choice about a found item is stored under: the item itself, then its plugin. */
32
+ export function foundIds(item) {
33
+ const pluginId = pluginIdOf(item);
34
+ return [contributionId(pluginId, FOUND_KINDS[item.kind], describeFound(item).name), pluginId];
35
+ }
36
+ /** A Markdown file's `name` and `description` frontmatter; a `SKILL.md` is named after its folder. */
37
+ export function describeFile(path) {
38
+ let text;
39
+ try {
40
+ text = readFileSync(path, 'utf8');
41
+ }
42
+ catch {
43
+ return null;
44
+ }
45
+ const front = frontmatter.parse(text)?.front ?? {};
46
+ const fallback = basename(path) === 'SKILL.md' ? basename(dirname(path)) : basename(path).replace(/\.md$/, '');
47
+ return { name: typeof front.name === 'string' && front.name.trim() ? front.name.trim() : fallback, description: typeof front.description === 'string' ? front.description.trim() : '' };
48
+ }
@@ -0,0 +1,20 @@
1
+ import type { Harness } from "../harness.js";
2
+ import { type PluginScope } from "./api.js";
3
+ import type { Plugin } from "./types.js";
4
+ /** A folder on this machine, or a package as Pi's settings name it. A bare name is an npm package. */
5
+ export declare function normalizeSource(input: string): string;
6
+ /**
7
+ * Installs a package for every account. It arrives switched off, and if it brings code, not
8
+ * trusted: nothing of it reaches a session until a person switches it on and trusts it.
9
+ */
10
+ export declare function install(harness: Harness, params: PluginScope & {
11
+ source: string;
12
+ }): Promise<Plugin[]>;
13
+ /** Removes an installed package. One kept as a folder beside a person's data is moved to the trash there. */
14
+ export declare function remove(harness: Harness, params: PluginScope & {
15
+ pluginId: string;
16
+ }): Promise<Plugin[]>;
17
+ /** Fetches a newer version of one installed package, or of all of them. Changed code waits for trust again. */
18
+ export declare function update(harness: Harness, params: PluginScope & {
19
+ pluginId?: string | null;
20
+ }): Promise<Plugin[]>;