@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,110 @@
1
+ // Installing, updating and removing a package. Pi's own package manager does the work, against
2
+ // the settings every account shares, so the `pi` command and the harness agree on what is
3
+ // installed. Fetching runs none of a package's code, and what was installed is switched off and
4
+ // untrusted until a person has looked at it.
5
+ import { existsSync, mkdirSync, renameSync, statSync } from 'node:fs';
6
+ import { homedir } from 'node:os';
7
+ import { basename, isAbsolute, join, resolve } from 'node:path';
8
+ import { ensureSharedDir } from "../accounts/env.js";
9
+ import { invalid, notFound } from "../core/errors.js";
10
+ import { now } from "../core/fs.js";
11
+ import { loadPi } from "../pi/runtime.js";
12
+ import { ensureAdopted, list } from "./api.js";
13
+ import * as attachments from "./attachments.js";
14
+ import { withoutInstallScripts } from "./discover.js";
15
+ /** A folder on this machine, or a package as Pi's settings name it. A bare name is an npm package. */
16
+ export function normalizeSource(input) {
17
+ const source = input.trim();
18
+ if (!source)
19
+ throw invalid('Name a package: a folder, an npm name, or a git address.');
20
+ if (source.startsWith('~/'))
21
+ return join(process.env.HOME || homedir(), source.slice(2));
22
+ if (isAbsolute(source))
23
+ return resolve(source);
24
+ if (source.startsWith('./') || source.startsWith('../'))
25
+ throw invalid('Give the whole path of the folder.');
26
+ return /^(npm:|git:|https?:\/\/|ssh:\/\/|git@)/.test(source) ? source : `npm:${source}`;
27
+ }
28
+ async function manager(harness) {
29
+ const pi = await loadPi();
30
+ // The shared folder is where `settings.json` really is; an account's own is a link to it.
31
+ const agentDir = ensureSharedDir(harness.accounts.dir);
32
+ const settings = pi.SettingsManager.create(harness.stateDir, agentDir);
33
+ return { settings, packages: new pi.DefaultPackageManager({ cwd: harness.stateDir, agentDir, settingsManager: settings }) };
34
+ }
35
+ const changed = (harness) => harness.bus.emit({ type: 'plugins.changed' });
36
+ /**
37
+ * Installs a package for every account. It arrives switched off, and if it brings code, not
38
+ * trusted: nothing of it reaches a session until a person switches it on and trusts it.
39
+ */
40
+ export async function install(harness, params) {
41
+ const source = normalizeSource(params.source);
42
+ if (isAbsolute(source) && !(existsSync(source) && statSync(source).isDirectory()))
43
+ throw invalid('That folder does not exist.');
44
+ // What was already there is taken over as trusted before anything new arrives, never after.
45
+ await ensureAdopted(harness);
46
+ const before = new Set((await list(harness, params)).map((plugin) => plugin.id));
47
+ const { settings, packages } = await manager(harness);
48
+ if (isAbsolute(source)) {
49
+ // Pi would save a folder as a path relative to the settings file, and each account reads
50
+ // that file through a link in its own folder, where a relative path points somewhere else.
51
+ const named = settings.getGlobalSettings().packages ?? [];
52
+ if (!named.some((entry) => (typeof entry === 'string' ? entry : entry.source) === source))
53
+ settings.setPackages([...named, source]);
54
+ await settings.flush();
55
+ }
56
+ else {
57
+ await withoutInstallScripts(() => packages.installAndPersist(source));
58
+ }
59
+ const after = await list(harness, params);
60
+ const added = after.filter((plugin) => plugin.install && !before.has(plugin.id));
61
+ if (added.length) {
62
+ const choices = attachments.load(harness.env.root);
63
+ for (const plugin of added)
64
+ attachments.set(choices, [plugin.id], {}, false, true);
65
+ attachments.save(harness.env.root, choices);
66
+ }
67
+ changed(harness);
68
+ return added.length ? list(harness, params) : after;
69
+ }
70
+ function installed(plugins, pluginId) {
71
+ const plugin = plugins.find((candidate) => candidate.id === pluginId);
72
+ if (!plugin)
73
+ throw notFound('Plugin');
74
+ if (!plugin.install)
75
+ throw invalid(`${plugin.title} was not installed as a package, so it cannot be removed or updated here.`);
76
+ return plugin;
77
+ }
78
+ /** Removes an installed package. One kept as a folder beside a person's data is moved to the trash there. */
79
+ export async function remove(harness, params) {
80
+ const plugin = installed(await list(harness, params), params.pluginId);
81
+ if (plugin.install.kind === 'folder') {
82
+ const trash = join(harness.env.root, 'trash', 'plugins');
83
+ mkdirSync(trash, { recursive: true });
84
+ renameSync(plugin.install.source, join(trash, `${basename(plugin.install.source)}-${now().replace(/[:.]/g, '-')}`));
85
+ }
86
+ else {
87
+ await (await manager(harness)).packages.removeAndPersist(plugin.install.source);
88
+ }
89
+ const choices = attachments.load(harness.env.root);
90
+ for (const scope of [choices.global, ...Object.values(choices.agents), ...Object.values(choices.projects)]) {
91
+ scope.on = scope.on.filter((id) => id !== plugin.id && !id.startsWith(`${plugin.id}/`));
92
+ scope.off = scope.off.filter((id) => id !== plugin.id && !id.startsWith(`${plugin.id}/`));
93
+ }
94
+ delete choices.settings[plugin.id];
95
+ attachments.save(harness.env.root, choices);
96
+ if (plugin.code)
97
+ harness.plugins.trust.revoke(plugin.code.hash);
98
+ changed(harness);
99
+ return list(harness, params);
100
+ }
101
+ /** Fetches a newer version of one installed package, or of all of them. Changed code waits for trust again. */
102
+ export async function update(harness, params) {
103
+ const plugin = params.pluginId ? installed(await list(harness, params), params.pluginId) : null;
104
+ if (plugin?.install.kind === 'folder')
105
+ throw invalid(`${plugin.title} is a folder on this machine. Change its files to update it.`);
106
+ const { packages } = await manager(harness);
107
+ await withoutInstallScripts(() => packages.update(plugin?.install.source));
108
+ changed(harness);
109
+ return list(harness, params);
110
+ }
@@ -0,0 +1,22 @@
1
+ import type { HarnessEnv } from "../core/env.js";
2
+ import type { Connection } from "../mcp/types.js";
3
+ import type { CallerContext } from "../core/caller.js";
4
+ import { type Launch } from "../prompt/compile.js";
5
+ import type { Materialised } from "../variant/materialise.js";
6
+ import type { Inventory, Plugin, PluginDescriptor } from "./types.js";
7
+ export interface InventoryInput {
8
+ env: HarnessEnv;
9
+ context: CallerContext;
10
+ /** What the application adds to the prompt for this caller, as it would for a session. */
11
+ launch: Launch;
12
+ /** The tools the caller has switched on, as a session's `allow` list. */
13
+ tools: readonly string[];
14
+ /** Whether the caller gets the connected-apps tools. */
15
+ connections: boolean;
16
+ plugins: readonly Plugin[];
17
+ descriptors: readonly PluginDescriptor[];
18
+ saved: readonly Connection[];
19
+ /** The variant the caller runs, when it has one. */
20
+ variant?: Materialised | null;
21
+ }
22
+ export declare function inventory(input: InventoryInput): Inventory;
@@ -0,0 +1,110 @@
1
+ // What reaches one caller: every prompt section, tool, skill, connection and extension, each
2
+ // attributed to the plugin it comes from. Anything no plugin accounts for is reported, so a new
3
+ // source of model-visible text cannot appear without showing up here.
4
+ import { readFileSync } from 'node:fs';
5
+ import { charCount } from "../core/text.js";
6
+ import { allowed } from "../mcp/connections.js";
7
+ import { BUILT_IN_DYNAMIC, compile, toolGroups } from "../prompt/compile.js";
8
+ import { ASK_USER } from "../tools/askUser.js";
9
+ import { CHECKLIST_WRITE } from "../tools/checklist.js";
10
+ import { DEFAULT_TOOL_NAMES } from "../tools/definitions.js";
11
+ import { VARIANT_PLUGIN } from "./builtin.js";
12
+ const size = (path) => {
13
+ if (!path)
14
+ return null;
15
+ try {
16
+ return charCount(readFileSync(path, 'utf8'));
17
+ }
18
+ catch {
19
+ return null;
20
+ }
21
+ };
22
+ export function inventory(input) {
23
+ const { env, context, launch, descriptors } = input;
24
+ const items = [];
25
+ const unattributed = [];
26
+ const item = (pluginId, kind, name, delivery, chars, rest = {}) => {
27
+ items.push({ pluginId, contributionId: null, kind, name, delivery, chars, cut: false, ...rest });
28
+ };
29
+ const pack = compile(env, context, launch, input.variant ?? null);
30
+ const dynamic = new Set([...BUILT_IN_DYNAMIC.map((entry) => entry.id), ...(launch.sections ?? []).filter((section) => section.dynamic).map((section) => section.id)]);
31
+ let systemChars = 0;
32
+ let contextChars = 0;
33
+ for (const section of pack.sections) {
34
+ const delivery = dynamic.has(section.id) ? 'context' : 'system';
35
+ if (delivery === 'context')
36
+ contextChars += section.size;
37
+ else
38
+ systemChars += section.size;
39
+ if (section.id === 'tools') {
40
+ // One paragraph per tool group; each belongs to the plugin that provides the group.
41
+ for (const group of toolGroups(context, launch)) {
42
+ if (!group.guidance)
43
+ continue;
44
+ const plugin = descriptors.find((descriptor) => descriptor.toolGroups?.includes(group.group));
45
+ if (!plugin)
46
+ unattributed.push({ kind: 'toolGroup', id: group.group });
47
+ item(plugin?.id ?? '', 'instruction', `Tool guidance: ${group.group}`, delivery, charCount(group.guidance), { cut: section.cut });
48
+ }
49
+ continue;
50
+ }
51
+ const plugin = descriptors.find((descriptor) => descriptor.sections?.some((declared) => declared.id === section.id));
52
+ if (!plugin)
53
+ unattributed.push({ kind: 'section', id: section.id });
54
+ const name = plugin?.sections?.find((declared) => declared.id === section.id)?.name ?? section.title;
55
+ item(plugin?.id ?? '', 'instruction', name, delivery, section.size, { contributionId: plugin ? `${plugin.id}/instruction/${name}` : null, cut: section.cut });
56
+ }
57
+ // The variant's skills are loaded only when used; its plugins run in the tool loop.
58
+ const variant = input.variant ?? null;
59
+ if (variant) {
60
+ for (const rel of Object.keys(variant.files).filter((path) => /^skills\/[^/]+\/SKILL\.md$/.test(path)).sort()) {
61
+ const name = rel.split('/')[1];
62
+ item(VARIANT_PLUGIN.id, 'skill', name, 'on-demand', charCount(variant.files[rel]), { contributionId: `${VARIANT_PLUGIN.id}/skill/${name}` });
63
+ }
64
+ for (const path of variant.extensionPaths) {
65
+ const name = path.split('/').pop();
66
+ item(VARIANT_PLUGIN.id, 'code', name, 'code', size(path), { contributionId: `${VARIANT_PLUGIN.id}/code/${name}` });
67
+ }
68
+ }
69
+ const names = [...input.tools];
70
+ const extensionToolNames = new Set(input.plugins.filter((plugin) => ['project', 'package', 'shared', 'home'].includes(plugin.source)).flatMap((plugin) => plugin.contributions.filter((entry) => entry.kind === 'tool' && entry.state === 'on').map((entry) => entry.name)));
71
+ for (const name of [ASK_USER, CHECKLIST_WRITE, ...DEFAULT_TOOL_NAMES, ...(input.connections ? ['mcp_list_tools', 'mcp_call_tool'] : [])])
72
+ if (!names.includes(name))
73
+ names.push(name);
74
+ for (const name of names) {
75
+ if (extensionToolNames.has(name))
76
+ continue;
77
+ const plugin = descriptors.find((descriptor) => descriptor.tools?.some((tool) => tool.name === name));
78
+ if (!plugin)
79
+ unattributed.push({ kind: 'tool', id: name });
80
+ item(plugin?.id ?? '', 'tool', name, 'tool', null, { contributionId: plugin ? `${plugin.id}/tool/${name}` : null });
81
+ }
82
+ if (input.connections) {
83
+ for (const connection of input.saved.filter((candidate) => allowed(candidate, { agentId: context.agentId ?? null, projectId: context.projectId ?? null }))) {
84
+ item('connected-apps', 'connection', connection.name || connection.id, 'tool', null, { contributionId: `connected-apps/connection/${connection.id}` });
85
+ }
86
+ }
87
+ // What the harness found on disk and lets load. Pi's command's own extensions exist only in a terminal.
88
+ const delivered = { code: 'code', skill: 'on-demand', command: 'on-demand', instruction: 'system', theme: 'code', tool: 'tool', connection: 'tool' };
89
+ const terminal = context.surface === 'cli';
90
+ for (const plugin of input.plugins) {
91
+ if (!['project', 'package', 'shared', 'home', 'pi'].includes(plugin.source))
92
+ continue;
93
+ for (const found of plugin.contributions) {
94
+ if (found.state !== 'on' || (plugin.source === 'pi' && (found.kind !== 'code' || !terminal)) || (found.kind === 'theme' && !terminal))
95
+ continue;
96
+ item(plugin.id, found.kind, found.name, found.background ? 'background' : delivered[found.kind], ['instruction', 'skill', 'command'].includes(found.kind) ? size(found.path) : null, { contributionId: found.id });
97
+ }
98
+ }
99
+ // The harness's own switched-on extensions.
100
+ for (const plugin of input.plugins) {
101
+ if (plugin.source !== 'builtin')
102
+ continue;
103
+ for (const own of plugin.contributions)
104
+ if (own.kind === 'code' && own.state === 'on')
105
+ item(plugin.id, 'code', own.name, 'code', null, { contributionId: own.id });
106
+ }
107
+ item('pi', 'instruction', 'Base prompt', 'system', null);
108
+ const used = new Set(items.map((entry) => entry.pluginId));
109
+ return { plugins: input.plugins.filter((plugin) => used.has(plugin.id)), others: input.plugins.filter((plugin) => !used.has(plugin.id)), items, unattributed, systemChars, contextChars };
110
+ }
@@ -0,0 +1,13 @@
1
+ import type { ConnectorTemplate } from "./types.js";
2
+ export interface PackageManifest {
3
+ name: string;
4
+ description: string;
5
+ version: string | null;
6
+ /** The parts it adds to, by id: `memory`, `wiki`, `history`. */
7
+ extends: string[];
8
+ /** The hooks file, inside the package, or `null` when it has none. */
9
+ hooks: string | null;
10
+ /** Data-only remote connector forms. Invalid templates are ignored; none can carry credentials. */
11
+ connectorTemplates: ConnectorTemplate[];
12
+ }
13
+ export declare function packageManifest(packageRoot: string): PackageManifest;
@@ -0,0 +1,56 @@
1
+ // What a package says about itself in its `package.json`: Pi's own fields, and under `harness`
2
+ // which part of the harness it extends and the file of hooks the harness runs for it.
3
+ import { basename, join } from 'node:path';
4
+ import { z } from 'zod';
5
+ import { readJsonOr, safeRelative } from "../core/fs.js";
6
+ const connectorTemplateSchema = z.object({
7
+ id: z.string().regex(/^[a-z0-9-]+$/),
8
+ name: z.string().min(1).max(120),
9
+ description: z.string().max(500),
10
+ url: z.string().url().startsWith('https://'),
11
+ auth: z.enum(['none', 'headers', 'oauth']),
12
+ oauthClient: z.enum(['dynamic', 'user']).nullable(),
13
+ oauthScopes: z.array(z.string().max(500)).max(30),
14
+ docsUrl: z.string().url().startsWith('https://').nullable(),
15
+ fields: z.array(z.object({
16
+ header: z.string().regex(/^[A-Za-z0-9_-]+$/),
17
+ label: z.string().min(1).max(120),
18
+ prefix: z.string().max(100),
19
+ help: z.string().max(500)
20
+ }).strict()).max(12),
21
+ setup: z.array(z.string().max(1000)).max(20),
22
+ notice: z.string().max(1000).nullable()
23
+ }).strict().superRefine((template, context) => {
24
+ const oauth = template.auth === 'oauth';
25
+ const headers = template.auth === 'headers';
26
+ if (oauth !== (template.oauthClient !== null))
27
+ context.addIssue({ code: 'custom', message: 'OAuth templates must state a client type and other templates must not.', path: ['oauthClient'] });
28
+ if (headers !== (template.fields.length > 0))
29
+ context.addIssue({ code: 'custom', message: 'Header templates must declare input fields and other templates must not.', path: ['fields'] });
30
+ });
31
+ /** A path inside the package, or `null` for one that is missing, absolute, or climbs out of it. */
32
+ function inside(path) {
33
+ if (typeof path !== 'string' || !path.trim())
34
+ return null;
35
+ try {
36
+ return safeRelative(path.replace(/^\.\//, ''));
37
+ }
38
+ catch {
39
+ return null;
40
+ }
41
+ }
42
+ export function packageManifest(packageRoot) {
43
+ const manifest = readJsonOr(join(packageRoot, 'package.json'), {});
44
+ const own = (manifest.harness && typeof manifest.harness === 'object' && !Array.isArray(manifest.harness) ? manifest.harness : {});
45
+ return {
46
+ name: typeof manifest.name === 'string' && manifest.name ? manifest.name : basename(packageRoot),
47
+ description: typeof manifest.description === 'string' ? manifest.description : '',
48
+ version: typeof manifest.version === 'string' ? manifest.version : null,
49
+ extends: (Array.isArray(own.extends) ? own.extends : typeof own.extends === 'string' ? [own.extends] : []).filter((id) => typeof id === 'string' && !!id),
50
+ hooks: inside(own.hooks),
51
+ connectorTemplates: (Array.isArray(own.connectors) ? own.connectors : []).flatMap((value) => {
52
+ const parsed = connectorTemplateSchema.safeParse(value);
53
+ return parsed.success ? [parsed.data] : [];
54
+ })
55
+ };
56
+ }
@@ -0,0 +1,104 @@
1
+ import type { Bus } from "../core/bus.js";
2
+ import { type Attachments, type AttachScope } from "./attachments.js";
3
+ import { type Found, type ResolveInput, type Resolver } from "./discover.js";
4
+ import { Trust, type ProjectCode } from "./trust.js";
5
+ /** What one session or terminal loads besides the registry's own items. */
6
+ export interface Loading {
7
+ /** Extension files and folders, in the order Pi would have loaded them. */
8
+ extensionPaths: string[];
9
+ skillPaths: string[];
10
+ promptPaths: string[];
11
+ themePaths: string[];
12
+ /** The `pi` command's own extensions left on, as `builtin:<name>`. Only a terminal has them. */
13
+ builtins: string[];
14
+ /** Hooks files the harness runs itself. Pi is never given them. */
15
+ hooks: {
16
+ path: string;
17
+ packageRoot: string;
18
+ hash: string;
19
+ }[];
20
+ /** Everything found, loaded or not. */
21
+ found: Found[];
22
+ /** Paths of found items a person switched off for this caller. */
23
+ detached: string[];
24
+ /** Applies the same attachment policy to resources supplied by a trusted extension. */
25
+ resourceAllowed?: (item: Found) => boolean;
26
+ /** Code the working folder brings, and whether a person trusted it. */
27
+ projectCode: (ProjectCode & {
28
+ trusted: boolean;
29
+ }) | null;
30
+ /** Each installed package that brings code, by its folder, and whether a person trusted it. */
31
+ packageCode: Record<string, ProjectCode & {
32
+ trusted: boolean;
33
+ }>;
34
+ }
35
+ /** What one loaded extension added to a session. */
36
+ export interface Registered {
37
+ path: string;
38
+ hooks: string[];
39
+ tools: string[];
40
+ commands: string[];
41
+ flags: string[];
42
+ shortcuts: string[];
43
+ /** Fingerprint at observation time; stale registrations are not presented as current. */
44
+ hash?: string | null;
45
+ seenAt?: string;
46
+ resources?: RuntimeResource[];
47
+ }
48
+ export interface RuntimeResource {
49
+ kind: 'skill' | 'command' | 'theme';
50
+ name: string;
51
+ path: string;
52
+ chars: number | null;
53
+ }
54
+ export interface PluginsOptions {
55
+ stateDir: string;
56
+ bus: Bus;
57
+ resolver?: Resolver;
58
+ /** The choices a person made about what is switched on, or `null` while there is no data root. */
59
+ attachments?: () => Attachments | null;
60
+ /** The folder of packages kept with a person's data, or `null` while there is no data root. */
61
+ packagesDir?: () => string | null;
62
+ }
63
+ /** The package folders inside a folder: each direct child that is a folder and not hidden. */
64
+ export declare function packageFolders(directory: string | null): string[];
65
+ export interface LoadingInput extends ResolveInput {
66
+ /** Who the session is for. Something switched off for this agent or project does not load. */
67
+ caller?: AttachScope;
68
+ /** The contributions frozen for a run. When present, this snapshot governs loading. */
69
+ contributions?: readonly string[];
70
+ }
71
+ /** Which code a person trusted: the working folder's as a whole, and each installed package's. */
72
+ export interface Trusted {
73
+ project: boolean;
74
+ /** Folders of installed packages whose code is not trusted. */
75
+ untrustedPackages: ReadonlySet<string>;
76
+ }
77
+ export declare const trustedBy: (loading: Pick<Loading, "projectCode" | "packageCode"> | null) => Trusted;
78
+ /**
79
+ * Whether a found item loads: it is on in Pi's settings, and if it is code, a person trusted it.
80
+ * A loose file in the shared folder was put there by hand and needs no trust. Text always loads.
81
+ */
82
+ export declare function loads(item: Found, trusted: Trusted): boolean;
83
+ /**
84
+ * Whether a person left a found item switched on for a caller. Pi reads its instruction files
85
+ * itself and its command owns its built-in extensions, so neither can be switched off here.
86
+ */
87
+ export declare function switchable(item: Found): boolean;
88
+ export declare class Plugins {
89
+ private readonly options;
90
+ readonly trust: Trust;
91
+ private readonly resolver;
92
+ private readonly registeredPath;
93
+ constructor(options: PluginsOptions);
94
+ /** Finds what Pi would load in this folder, and chooses what does. */
95
+ loading(input: LoadingInput): Promise<Loading>;
96
+ /** What each extension registered the last time a session loaded it. */
97
+ registered(): Record<string, Registered & {
98
+ seenAt: string;
99
+ }>;
100
+ /** Records what a session's extensions registered, so the list can show it without loading code. */
101
+ loaded(extensions: readonly Registered[]): void;
102
+ }
103
+ /** Removes the skill links an earlier version of the harness kept in a Pi agent folder's `skills/`. */
104
+ export declare function removeLinkedSkills(skillsDir: string): void;
@@ -0,0 +1,164 @@
1
+ // The harness decides what a Pi session loads. Pi's own discovery is switched off for sessions
2
+ // and terminals; they receive the paths chosen here, so nothing reaches a model unlisted.
3
+ import { chmodSync, lstatSync, readdirSync, rmSync, unlinkSync } from 'node:fs';
4
+ import { join } from 'node:path';
5
+ import { now, readJsonOr, writeJson } from "../core/fs.js";
6
+ import { attached } from "./attachments.js";
7
+ import { piResolver } from "./discover.js";
8
+ import { foundIds, pluginIdOf } from "./identity.js";
9
+ import { packageCode, projectCode, Trust } from "./trust.js";
10
+ /** The package folders inside a folder: each direct child that is a folder and not hidden. */
11
+ export function packageFolders(directory) {
12
+ if (!directory)
13
+ return [];
14
+ try {
15
+ return readdirSync(directory, { withFileTypes: true }).filter((entry) => entry.isDirectory() && !entry.name.startsWith('.')).map((entry) => join(directory, entry.name)).sort();
16
+ }
17
+ catch {
18
+ return [];
19
+ }
20
+ }
21
+ export const trustedBy = (loading) => ({
22
+ project: !!loading?.projectCode?.trusted,
23
+ untrustedPackages: new Set(Object.entries(loading?.packageCode ?? {}).filter(([, code]) => !code.trusted).map(([root]) => root))
24
+ });
25
+ /**
26
+ * Whether a found item loads: it is on in Pi's settings, and if it is code, a person trusted it.
27
+ * A loose file in the shared folder was put there by hand and needs no trust. Text always loads.
28
+ */
29
+ export function loads(item, trusted) {
30
+ if (!item.enabled)
31
+ return false;
32
+ if (item.kind !== 'extension' && item.kind !== 'hook')
33
+ return true;
34
+ if (item.project)
35
+ return trusted.project;
36
+ return !(item.packageRoot && trusted.untrustedPackages.has(item.packageRoot));
37
+ }
38
+ /**
39
+ * Whether a person left a found item switched on for a caller. Pi reads its instruction files
40
+ * itself and its command owns its built-in extensions, so neither can be switched off here.
41
+ */
42
+ export function switchable(item) {
43
+ return item.kind !== 'context' && item.origin !== 'builtin';
44
+ }
45
+ export class Plugins {
46
+ options;
47
+ trust;
48
+ resolver;
49
+ registeredPath;
50
+ constructor(options) {
51
+ this.options = options;
52
+ this.trust = new Trust(options.stateDir, options.bus);
53
+ this.resolver = options.resolver ?? piResolver;
54
+ this.registeredPath = join(options.stateDir, 'plugin-registered.json');
55
+ }
56
+ /** Finds what Pi would load in this folder, and chooses what does. */
57
+ async loading(input) {
58
+ // Links an earlier version put in the shared skills folder would be found as skills again.
59
+ removeLinkedSkills(join(input.agentDir, 'skills'));
60
+ const found = await this.resolver({ ...input, packages: packageFolders(this.options.packagesDir?.() ?? null) });
61
+ const code = projectCode(found, input.cwd);
62
+ const packages = packageCode(found);
63
+ // Packages that loaded before trust was asked per package keep loading: they are taken over once.
64
+ if (!this.trust.adopted)
65
+ this.trust.adopt([...packages].map(([folder, packaged]) => ({ code: packaged, folder })));
66
+ const trustedHashes = new Set(this.trust.list().map((record) => record.hash));
67
+ const projectCodeState = code ? { ...code, trusted: trustedHashes.has(code.hash) } : null;
68
+ const packageCodeState = Object.fromEntries([...packages].map(([folder, packaged]) => [folder, { ...packaged, trusted: trustedHashes.has(packaged.hash) }]));
69
+ const trusted = trustedBy({ projectCode: projectCodeState, packageCode: packageCodeState });
70
+ const choices = this.options.attachments?.() ?? null;
71
+ const off = (item) => {
72
+ if (!choices || !switchable(item))
73
+ return false;
74
+ // A hook runs for everyone or not at all, so only its plugin's switch for everyone counts.
75
+ if (item.kind === 'hook')
76
+ return !attached(choices, [pluginIdOf(item)], {}, true);
77
+ return !attached(choices, foundIds(item), input.caller ?? {}, true);
78
+ };
79
+ const allowed = (item) => input.contributions === undefined
80
+ ? !off(item)
81
+ : input.contributions.includes(foundIds(item)[0]);
82
+ const detached = found.filter((item) => !allowed(item)).map((item) => item.path);
83
+ const chosen = found.filter((item) => loads(item, trusted) && allowed(item));
84
+ const paths = (kind, builtin) => chosen.filter((item) => item.kind === kind && (item.origin === 'builtin') === builtin).map((item) => item.path);
85
+ return {
86
+ extensionPaths: paths('extension', false),
87
+ skillPaths: paths('skill', false),
88
+ promptPaths: paths('prompt', false),
89
+ themePaths: paths('theme', false),
90
+ builtins: paths('extension', true),
91
+ hooks: chosen.filter((item) => item.kind === 'hook' && item.packageRoot).map((item) => ({ path: item.path, packageRoot: item.packageRoot, hash: packageCodeState[item.packageRoot]?.hash ?? '' })),
92
+ found,
93
+ detached,
94
+ resourceAllowed: allowed,
95
+ projectCode: projectCodeState,
96
+ packageCode: packageCodeState
97
+ };
98
+ }
99
+ /** What each extension registered the last time a session loaded it. */
100
+ registered() {
101
+ return readJsonOr(this.registeredPath, {});
102
+ }
103
+ /** Records what a session's extensions registered, so the list can show it without loading code. */
104
+ loaded(extensions) {
105
+ if (!extensions.length)
106
+ return;
107
+ const stored = this.registered();
108
+ let changed = false;
109
+ for (const extension of extensions) {
110
+ const { seenAt: _seenAt, ...before } = stored[extension.path] ?? {};
111
+ if (JSON.stringify(before) === JSON.stringify(extension))
112
+ continue;
113
+ stored[extension.path] = { ...extension, seenAt: now() };
114
+ changed = true;
115
+ }
116
+ if (!changed)
117
+ return;
118
+ writeJson(this.registeredPath, stored);
119
+ chmodSync(this.registeredPath, 0o600);
120
+ this.options.bus.emit({ type: 'plugins.changed' });
121
+ }
122
+ }
123
+ // Prefix of the entries an earlier version of the harness linked into a Pi agent folder's `skills/`.
124
+ const LINKED_SKILL_PREFIX = 'agentx-';
125
+ function isLinkedSkill(path) {
126
+ let meta;
127
+ try {
128
+ meta = lstatSync(path);
129
+ }
130
+ catch {
131
+ return false;
132
+ }
133
+ if (meta.isSymbolicLink())
134
+ return true;
135
+ if (!meta.isDirectory())
136
+ return false;
137
+ // A single-file skill was linked as `agentx-<name>/SKILL.md` inside a folder the harness made.
138
+ try {
139
+ const entries = readdirSync(path);
140
+ return entries.length === 1 && entries[0] === 'SKILL.md' && lstatSync(join(path, 'SKILL.md')).isSymbolicLink();
141
+ }
142
+ catch {
143
+ return false;
144
+ }
145
+ }
146
+ /** Removes the skill links an earlier version of the harness kept in a Pi agent folder's `skills/`. */
147
+ export function removeLinkedSkills(skillsDir) {
148
+ let names;
149
+ try {
150
+ names = readdirSync(skillsDir);
151
+ }
152
+ catch {
153
+ return;
154
+ }
155
+ for (const name of names) {
156
+ const path = join(skillsDir, name);
157
+ if (!name.startsWith(LINKED_SKILL_PREFIX) || !isLinkedSkill(path))
158
+ continue;
159
+ if (lstatSync(path).isSymbolicLink())
160
+ unlinkSync(path);
161
+ else
162
+ rmSync(path, { recursive: true, force: true });
163
+ }
164
+ }
@@ -0,0 +1,9 @@
1
+ import type * as Pi from '@earendil-works/pi-coding-agent';
2
+ import type { Found } from "./discover.js";
3
+ import type { Loading, Registered, RuntimeResource } from "./plugins.js";
4
+ export declare function runtimeOwner(loading: Loading, path: string): Found | undefined;
5
+ export declare function registrationHash(loading: Loading, path: string): string | null;
6
+ /** A discovered resource has the same identity for its switch, catalogue and load decision. */
7
+ export declare function resourceOf(owner: Found, kind: 'skill' | 'prompt' | 'theme', path: string): RuntimeResource;
8
+ /** Wrap each handler separately so identical extension basenames never lose their owner. */
9
+ export declare function observeResources(pi: typeof Pi, loader: Pi.DefaultResourceLoader, loading: Loading, records: Registered[], publish: () => void): void;