@xingular/harness 0.1.7 → 1.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (683) hide show
  1. package/CHANGELOG.md +97 -1
  2. package/LICENSE +202 -0
  3. package/NOTICE.md +22 -0
  4. package/README.md +187 -85
  5. package/THIRD_PARTY_LICENSES.md +942 -0
  6. package/dist/cli.js +13701 -13498
  7. package/dist/sdk/accounts/accounts.d.ts +165 -0
  8. package/dist/sdk/accounts/accounts.js +730 -0
  9. package/dist/sdk/accounts/choices.d.ts +23 -0
  10. package/dist/sdk/accounts/choices.js +62 -0
  11. package/dist/sdk/accounts/env.d.ts +78 -0
  12. package/dist/sdk/accounts/env.js +294 -0
  13. package/dist/sdk/accounts/secrets.d.ts +16 -0
  14. package/dist/sdk/accounts/secrets.js +40 -0
  15. package/dist/sdk/accounts/store.d.ts +114 -0
  16. package/dist/sdk/accounts/store.js +255 -0
  17. package/dist/sdk/browser/config.d.ts +16 -0
  18. package/dist/sdk/browser/config.js +22 -0
  19. package/dist/sdk/browser/diagnostics.d.ts +4 -0
  20. package/dist/sdk/browser/diagnostics.js +38 -0
  21. package/dist/sdk/browser/index.d.ts +17 -0
  22. package/dist/sdk/browser/index.js +65 -0
  23. package/dist/sdk/browser/network.d.ts +10 -0
  24. package/dist/sdk/browser/network.js +59 -0
  25. package/dist/sdk/browser/session.d.ts +84 -0
  26. package/dist/sdk/browser/session.js +192 -0
  27. package/dist/sdk/browser/tools.d.ts +8 -0
  28. package/dist/sdk/browser/tools.js +329 -0
  29. package/dist/sdk/capabilities/api.d.ts +22 -0
  30. package/dist/sdk/capabilities/api.js +54 -0
  31. package/dist/sdk/capabilities/runSnapshot.d.ts +18 -0
  32. package/dist/sdk/capabilities/runSnapshot.js +47 -0
  33. package/dist/sdk/capabilities/types.d.ts +29 -0
  34. package/dist/sdk/capabilities/types.js +1 -0
  35. package/dist/sdk/cli.d.ts +2 -0
  36. package/dist/sdk/cli.js +142 -0
  37. package/dist/sdk/core/bus.d.ts +23 -0
  38. package/dist/sdk/core/bus.js +76 -0
  39. package/dist/sdk/core/caller.d.ts +22 -0
  40. package/dist/sdk/core/caller.js +16 -0
  41. package/dist/sdk/core/changes.d.ts +15 -0
  42. package/dist/sdk/core/changes.js +15 -0
  43. package/dist/sdk/core/effort.d.ts +2 -0
  44. package/dist/sdk/core/effort.js +1 -0
  45. package/dist/sdk/core/env.d.ts +18 -0
  46. package/dist/sdk/core/env.js +8 -0
  47. package/dist/sdk/core/errors.d.ts +15 -0
  48. package/dist/sdk/core/errors.js +24 -0
  49. package/dist/sdk/core/frontmatter.d.ts +12 -0
  50. package/dist/sdk/core/frontmatter.js +50 -0
  51. package/dist/sdk/core/fs.d.ts +18 -0
  52. package/dist/sdk/core/fs.js +106 -0
  53. package/dist/sdk/core/index.d.ts +24 -0
  54. package/dist/sdk/core/index.js +187 -0
  55. package/dist/sdk/core/path.d.ts +7 -0
  56. package/dist/sdk/core/path.js +79 -0
  57. package/dist/sdk/core/projects.d.ts +18 -0
  58. package/dist/sdk/core/projects.js +67 -0
  59. package/dist/sdk/core/secrets.d.ts +2 -0
  60. package/dist/sdk/core/secrets.js +5 -0
  61. package/dist/sdk/core/text.d.ts +7 -0
  62. package/dist/sdk/core/text.js +40 -0
  63. package/dist/sdk/doctor/checks.d.ts +5 -0
  64. package/dist/sdk/doctor/checks.js +208 -0
  65. package/dist/sdk/doctor/probe.d.ts +4 -0
  66. package/dist/sdk/doctor/probe.js +92 -0
  67. package/dist/sdk/doctor/service.d.ts +23 -0
  68. package/dist/sdk/doctor/service.js +144 -0
  69. package/dist/sdk/doctor/types.d.ts +141 -0
  70. package/dist/sdk/doctor/types.js +29 -0
  71. package/dist/sdk/harness.d.ts +133 -0
  72. package/dist/sdk/harness.js +299 -0
  73. package/dist/sdk/history/lessonPrompt.d.ts +2 -0
  74. package/dist/sdk/history/lessonPrompt.js +15 -0
  75. package/dist/sdk/history/lessons.d.ts +52 -0
  76. package/dist/sdk/history/lessons.js +173 -0
  77. package/dist/sdk/history/recall.d.ts +68 -0
  78. package/dist/sdk/history/recall.js +199 -0
  79. package/dist/sdk/history/trajectory.d.ts +7 -0
  80. package/dist/sdk/history/trajectory.js +216 -0
  81. package/dist/sdk/hub/catalog.json +123 -0
  82. package/dist/sdk/hub/cli.d.ts +7 -0
  83. package/dist/sdk/hub/cli.js +81 -0
  84. package/dist/sdk/hub/hub.d.ts +74 -0
  85. package/dist/sdk/hub/hub.js +474 -0
  86. package/dist/sdk/hub/schema.d.ts +280 -0
  87. package/dist/sdk/hub/schema.js +78 -0
  88. package/dist/sdk/index.d.ts +63 -0
  89. package/dist/sdk/index.js +48 -0
  90. package/dist/sdk/mcp/connections.d.ts +83 -0
  91. package/dist/sdk/mcp/connections.js +669 -0
  92. package/dist/sdk/mcp/manager.d.ts +26 -0
  93. package/dist/sdk/mcp/manager.js +124 -0
  94. package/dist/sdk/mcp/oauth.d.ts +35 -0
  95. package/dist/sdk/mcp/oauth.js +171 -0
  96. package/dist/sdk/mcp/scopeMigration.d.ts +19 -0
  97. package/dist/sdk/mcp/scopeMigration.js +198 -0
  98. package/dist/sdk/mcp/service.d.ts +160 -0
  99. package/dist/sdk/mcp/service.js +510 -0
  100. package/dist/sdk/mcp/types.d.ts +131 -0
  101. package/dist/sdk/mcp/types.js +49 -0
  102. package/dist/sdk/pi/runtime.d.ts +13 -0
  103. package/dist/sdk/pi/runtime.js +31 -0
  104. package/dist/sdk/plugins/api.d.ts +66 -0
  105. package/dist/sdk/plugins/api.js +155 -0
  106. package/dist/sdk/plugins/attachments.d.ts +46 -0
  107. package/dist/sdk/plugins/attachments.js +111 -0
  108. package/dist/sdk/plugins/builtin.d.ts +6 -0
  109. package/dist/sdk/plugins/builtin.js +68 -0
  110. package/dist/sdk/plugins/catalogue.d.ts +29 -0
  111. package/dist/sdk/plugins/catalogue.js +196 -0
  112. package/dist/sdk/plugins/cli.d.ts +13 -0
  113. package/dist/sdk/plugins/cli.js +187 -0
  114. package/dist/sdk/plugins/discover.d.ts +42 -0
  115. package/dist/sdk/plugins/discover.js +115 -0
  116. package/dist/sdk/plugins/firstParty.d.ts +50 -0
  117. package/dist/sdk/plugins/firstParty.js +113 -0
  118. package/dist/sdk/plugins/hooks.d.ts +94 -0
  119. package/dist/sdk/plugins/hooks.js +162 -0
  120. package/dist/sdk/plugins/identity.d.ts +19 -0
  121. package/dist/sdk/plugins/identity.js +48 -0
  122. package/dist/sdk/plugins/install.d.ts +20 -0
  123. package/dist/sdk/plugins/install.js +110 -0
  124. package/dist/sdk/plugins/inventory.d.ts +22 -0
  125. package/dist/sdk/plugins/inventory.js +110 -0
  126. package/dist/sdk/plugins/manifest.d.ts +13 -0
  127. package/dist/sdk/plugins/manifest.js +56 -0
  128. package/dist/sdk/plugins/plugins.d.ts +104 -0
  129. package/dist/sdk/plugins/plugins.js +164 -0
  130. package/dist/sdk/plugins/runtime.d.ts +9 -0
  131. package/dist/sdk/plugins/runtime.js +95 -0
  132. package/dist/sdk/plugins/trust.d.ts +44 -0
  133. package/dist/sdk/plugins/trust.js +120 -0
  134. package/dist/sdk/plugins/types.d.ts +159 -0
  135. package/dist/sdk/plugins/types.js +7 -0
  136. package/dist/sdk/prompt/compile.d.ts +174 -0
  137. package/dist/sdk/prompt/compile.js +396 -0
  138. package/dist/sdk/refine/cli.d.ts +4 -0
  139. package/dist/sdk/refine/cli.js +186 -0
  140. package/dist/sdk/refine/demo.d.ts +21 -0
  141. package/dist/sdk/refine/demo.js +114 -0
  142. package/dist/sdk/refine/evidence.d.ts +55 -0
  143. package/dist/sdk/refine/evidence.js +330 -0
  144. package/dist/sdk/refine/host.d.ts +51 -0
  145. package/dist/sdk/refine/host.js +76 -0
  146. package/dist/sdk/refine/ledger.d.ts +48 -0
  147. package/dist/sdk/refine/ledger.js +76 -0
  148. package/dist/sdk/refine/library.d.ts +55 -0
  149. package/dist/sdk/refine/library.js +177 -0
  150. package/dist/sdk/refine/pi.d.ts +72 -0
  151. package/dist/sdk/refine/pi.js +248 -0
  152. package/dist/sdk/refine/prompts.d.ts +45 -0
  153. package/dist/sdk/refine/prompts.js +390 -0
  154. package/dist/sdk/refine/recursion.d.ts +113 -0
  155. package/dist/sdk/refine/recursion.js +258 -0
  156. package/dist/sdk/refine/runner.d.ts +81 -0
  157. package/dist/sdk/refine/runner.js +150 -0
  158. package/dist/sdk/refine/selection.d.ts +57 -0
  159. package/dist/sdk/refine/selection.js +251 -0
  160. package/dist/sdk/refine/service.d.ts +84 -0
  161. package/dist/sdk/refine/service.js +165 -0
  162. package/dist/sdk/refine/suite.d.ts +67 -0
  163. package/dist/sdk/refine/suite.js +174 -0
  164. package/dist/sdk/refine/trajectory.d.ts +9 -0
  165. package/dist/sdk/refine/trajectory.js +68 -0
  166. package/dist/sdk/refine/types.d.ts +77 -0
  167. package/dist/sdk/refine/types.js +10 -0
  168. package/dist/sdk/server/methods.d.ts +3 -0
  169. package/dist/sdk/server/methods.js +370 -0
  170. package/dist/sdk/server/remote.d.ts +19 -0
  171. package/dist/sdk/server/remote.js +84 -0
  172. package/dist/sdk/server/rpc.d.ts +20 -0
  173. package/dist/sdk/server/rpc.js +102 -0
  174. package/dist/sdk/server/serve.d.ts +10 -0
  175. package/dist/sdk/server/serve.js +18 -0
  176. package/dist/sdk/sessions/approvals.d.ts +47 -0
  177. package/dist/sdk/sessions/approvals.js +119 -0
  178. package/dist/sdk/sessions/continuation.d.ts +48 -0
  179. package/dist/sdk/sessions/continuation.js +85 -0
  180. package/dist/sdk/sessions/contracts.d.ts +534 -0
  181. package/dist/sdk/sessions/contracts.js +299 -0
  182. package/dist/sdk/sessions/extensionUi.d.ts +19 -0
  183. package/dist/sdk/sessions/extensionUi.js +64 -0
  184. package/dist/sdk/sessions/history.d.ts +16 -0
  185. package/dist/sdk/sessions/history.js +68 -0
  186. package/dist/sdk/sessions/lineageJoin.d.ts +2 -0
  187. package/dist/sdk/sessions/lineageJoin.js +61 -0
  188. package/dist/sdk/sessions/planMode.d.ts +36 -0
  189. package/dist/sdk/sessions/planMode.js +84 -0
  190. package/dist/sdk/sessions/policy.d.ts +43 -0
  191. package/dist/sdk/sessions/policy.js +1 -0
  192. package/dist/sdk/sessions/pricing.d.ts +34 -0
  193. package/dist/sdk/sessions/pricing.js +40 -0
  194. package/dist/sdk/sessions/reasoningSummaries.d.ts +11 -0
  195. package/dist/sdk/sessions/reasoningSummaries.js +61 -0
  196. package/dist/sdk/sessions/registry.d.ts +102 -0
  197. package/dist/sdk/sessions/registry.js +383 -0
  198. package/dist/sdk/sessions/runIndex.d.ts +21 -0
  199. package/dist/sdk/sessions/runIndex.js +65 -0
  200. package/dist/sdk/sessions/runStore.d.ts +66 -0
  201. package/dist/sdk/sessions/runStore.js +335 -0
  202. package/dist/sdk/sessions/runner.d.ts +213 -0
  203. package/dist/sdk/sessions/runner.js +589 -0
  204. package/dist/sdk/sessions/sessions.d.ts +140 -0
  205. package/dist/sdk/sessions/sessions.js +394 -0
  206. package/dist/sdk/sessions/subagentService.d.ts +41 -0
  207. package/dist/sdk/sessions/subagentService.js +247 -0
  208. package/dist/sdk/sessions/subagents.d.ts +50 -0
  209. package/dist/sdk/sessions/subagents.js +68 -0
  210. package/dist/sdk/terminal/accountsMenu.d.ts +46 -0
  211. package/dist/sdk/terminal/accountsMenu.js +392 -0
  212. package/dist/sdk/terminal/cli.d.ts +20 -0
  213. package/dist/sdk/terminal/cli.js +121 -0
  214. package/dist/sdk/terminal/client.d.ts +15 -0
  215. package/dist/sdk/terminal/client.js +126 -0
  216. package/dist/sdk/terminal/control.d.ts +4 -0
  217. package/dist/sdk/terminal/control.js +25 -0
  218. package/dist/sdk/terminal/controller.d.ts +72 -0
  219. package/dist/sdk/terminal/controller.js +351 -0
  220. package/dist/sdk/terminal/hubMenu.d.ts +10 -0
  221. package/dist/sdk/terminal/hubMenu.js +34 -0
  222. package/dist/sdk/terminal/launch.d.ts +5 -0
  223. package/dist/sdk/terminal/launch.js +27 -0
  224. package/dist/sdk/terminal/logs.d.ts +14 -0
  225. package/dist/sdk/terminal/logs.js +59 -0
  226. package/dist/sdk/terminal/piExtension.d.ts +6 -0
  227. package/dist/sdk/terminal/piExtension.js +392 -0
  228. package/dist/sdk/terminal/pluginMenu.d.ts +34 -0
  229. package/dist/sdk/terminal/pluginMenu.js +101 -0
  230. package/dist/sdk/terminal/socket.d.ts +70 -0
  231. package/dist/sdk/terminal/socket.js +256 -0
  232. package/dist/sdk/terminal/standalone.d.ts +18 -0
  233. package/dist/sdk/terminal/standalone.js +146 -0
  234. package/dist/sdk/terminal/terminals.d.ts +176 -0
  235. package/dist/sdk/terminal/terminals.js +767 -0
  236. package/dist/sdk/terminal/trajectory.d.ts +10 -0
  237. package/dist/sdk/terminal/trajectory.js +30 -0
  238. package/dist/sdk/terminal/tui/chrome.d.ts +64 -0
  239. package/dist/sdk/terminal/tui/chrome.js +169 -0
  240. package/dist/sdk/terminal/tui/clipboardFiles.d.ts +11 -0
  241. package/dist/sdk/terminal/tui/clipboardFiles.js +74 -0
  242. package/dist/sdk/terminal/tui/commandPages.d.ts +7 -0
  243. package/dist/sdk/terminal/tui/commandPages.js +63 -0
  244. package/dist/sdk/terminal/tui/commands.d.ts +42 -0
  245. package/dist/sdk/terminal/tui/commands.js +276 -0
  246. package/dist/sdk/terminal/tui/dialogGeometry.d.ts +27 -0
  247. package/dist/sdk/terminal/tui/dialogGeometry.js +50 -0
  248. package/dist/sdk/terminal/tui/dialogs.d.ts +75 -0
  249. package/dist/sdk/terminal/tui/dialogs.js +363 -0
  250. package/dist/sdk/terminal/tui/keybindings.d.ts +11 -0
  251. package/dist/sdk/terminal/tui/keybindings.js +49 -0
  252. package/dist/sdk/terminal/tui/list.d.ts +73 -0
  253. package/dist/sdk/terminal/tui/list.js +196 -0
  254. package/dist/sdk/terminal/tui/modeChoices.d.ts +42 -0
  255. package/dist/sdk/terminal/tui/modeChoices.js +70 -0
  256. package/dist/sdk/terminal/tui/modelPicker.d.ts +55 -0
  257. package/dist/sdk/terminal/tui/modelPicker.js +155 -0
  258. package/dist/sdk/terminal/tui/mouse.d.ts +3 -0
  259. package/dist/sdk/terminal/tui/mouse.js +3 -0
  260. package/dist/sdk/terminal/tui/page.d.ts +14 -0
  261. package/dist/sdk/terminal/tui/page.js +1 -0
  262. package/dist/sdk/terminal/tui/pageOverlay.d.ts +27 -0
  263. package/dist/sdk/terminal/tui/pageOverlay.js +145 -0
  264. package/dist/sdk/terminal/tui/pages/accountsPage.d.ts +54 -0
  265. package/dist/sdk/terminal/tui/pages/accountsPage.js +181 -0
  266. package/dist/sdk/terminal/tui/pages/componentsPage.d.ts +47 -0
  267. package/dist/sdk/terminal/tui/pages/componentsPage.js +119 -0
  268. package/dist/sdk/terminal/tui/pages/doctorPage.d.ts +37 -0
  269. package/dist/sdk/terminal/tui/pages/doctorPage.js +145 -0
  270. package/dist/sdk/terminal/tui/pages/hubPage.d.ts +39 -0
  271. package/dist/sdk/terminal/tui/pages/hubPage.js +128 -0
  272. package/dist/sdk/terminal/tui/pages/logPage.d.ts +38 -0
  273. package/dist/sdk/terminal/tui/pages/logPage.js +189 -0
  274. package/dist/sdk/terminal/tui/pages/permissionsPage.d.ts +44 -0
  275. package/dist/sdk/terminal/tui/pages/permissionsPage.js +124 -0
  276. package/dist/sdk/terminal/tui/pages/pluginsPage.d.ts +57 -0
  277. package/dist/sdk/terminal/tui/pages/pluginsPage.js +243 -0
  278. package/dist/sdk/terminal/tui/pages/settingsPage.d.ts +55 -0
  279. package/dist/sdk/terminal/tui/pages/settingsPage.js +88 -0
  280. package/dist/sdk/terminal/tui/pages/trajectoryPage.d.ts +58 -0
  281. package/dist/sdk/terminal/tui/pages/trajectoryPage.js +377 -0
  282. package/dist/sdk/terminal/tui/piAdapter.d.ts +18 -0
  283. package/dist/sdk/terminal/tui/piAdapter.js +48 -0
  284. package/dist/sdk/terminal/tui/planMode.d.ts +2 -0
  285. package/dist/sdk/terminal/tui/planMode.js +2 -0
  286. package/dist/sdk/terminal/tui/questionPicker.d.ts +20 -0
  287. package/dist/sdk/terminal/tui/questionPicker.js +150 -0
  288. package/dist/sdk/terminal/tui/questions.d.ts +19 -0
  289. package/dist/sdk/terminal/tui/questions.js +42 -0
  290. package/dist/sdk/terminal/tui/runtime.d.ts +114 -0
  291. package/dist/sdk/terminal/tui/runtime.js +441 -0
  292. package/dist/sdk/terminal/tui/search.d.ts +22 -0
  293. package/dist/sdk/terminal/tui/search.js +60 -0
  294. package/dist/sdk/terminal/tui/selection.d.ts +16 -0
  295. package/dist/sdk/terminal/tui/selection.js +16 -0
  296. package/dist/sdk/terminal/tui/sessionUi.d.ts +3 -0
  297. package/dist/sdk/terminal/tui/sessionUi.js +30 -0
  298. package/dist/sdk/terminal/tui/settingsModel.d.ts +12 -0
  299. package/dist/sdk/terminal/tui/settingsModel.js +84 -0
  300. package/dist/sdk/terminal/tui/sideQuestion.d.ts +53 -0
  301. package/dist/sdk/terminal/tui/sideQuestion.js +197 -0
  302. package/dist/sdk/terminal/tui/skillInvocation.d.ts +9 -0
  303. package/dist/sdk/terminal/tui/skillInvocation.js +43 -0
  304. package/dist/sdk/terminal/tui/status.d.ts +18 -0
  305. package/dist/sdk/terminal/tui/status.js +67 -0
  306. package/dist/sdk/terminal/tui/theme.d.ts +45 -0
  307. package/dist/sdk/terminal/tui/theme.js +176 -0
  308. package/dist/sdk/terminal/tui/treeModel.d.ts +79 -0
  309. package/dist/sdk/terminal/tui/treeModel.js +483 -0
  310. package/dist/sdk/terminal/tui/treePicker.d.ts +49 -0
  311. package/dist/sdk/terminal/tui/treePicker.js +251 -0
  312. package/dist/sdk/terminal/tui/ui.d.ts +47 -0
  313. package/dist/sdk/terminal/tui/ui.js +148 -0
  314. package/dist/sdk/terminal/tui/workingStatus.d.ts +9 -0
  315. package/dist/sdk/terminal/tui/workingStatus.js +229 -0
  316. package/dist/sdk/tools/askUser.d.ts +6 -0
  317. package/dist/sdk/tools/askUser.js +74 -0
  318. package/dist/sdk/tools/checklist.d.ts +9 -0
  319. package/dist/sdk/tools/checklist.js +54 -0
  320. package/dist/sdk/tools/definitions.d.ts +30 -0
  321. package/dist/sdk/tools/definitions.js +117 -0
  322. package/dist/sdk/tools/dispatch.d.ts +16 -0
  323. package/dist/sdk/tools/dispatch.js +67 -0
  324. package/dist/sdk/tools/harnessTools.d.ts +6 -0
  325. package/dist/sdk/tools/harnessTools.js +20 -0
  326. package/dist/sdk/tools/sessionName.d.ts +7 -0
  327. package/dist/sdk/tools/sessionName.js +31 -0
  328. package/dist/sdk/tools/spawnSubagent.d.ts +4 -0
  329. package/dist/sdk/tools/spawnSubagent.js +49 -0
  330. package/dist/sdk/tools/types.d.ts +48 -0
  331. package/dist/sdk/tools/types.js +1 -0
  332. package/dist/sdk/variant/components.d.ts +34 -0
  333. package/dist/sdk/variant/components.js +230 -0
  334. package/dist/sdk/variant/materialise.d.ts +66 -0
  335. package/dist/sdk/variant/materialise.js +81 -0
  336. package/dist/sdk/variant/migrate.d.ts +4 -0
  337. package/dist/sdk/variant/migrate.js +41 -0
  338. package/dist/sdk/variant/seed.d.ts +20 -0
  339. package/dist/sdk/variant/seed.js +116 -0
  340. package/dist/sdk/variant/store.d.ts +82 -0
  341. package/dist/sdk/variant/store.js +151 -0
  342. package/dist/sdk/variant/surface.d.ts +56 -0
  343. package/dist/sdk/variant/surface.js +81 -0
  344. package/dist/sdk/variant/trust.d.ts +27 -0
  345. package/dist/sdk/variant/trust.js +64 -0
  346. package/dist/sdk/variant/variant.d.ts +71 -0
  347. package/dist/sdk/variant/variant.js +331 -0
  348. package/dist/sdk/web/markdown.d.ts +10 -0
  349. package/dist/sdk/web/markdown.js +66 -0
  350. package/dist/sdk/web/safeRequest.d.ts +34 -0
  351. package/dist/sdk/web/safeRequest.js +175 -0
  352. package/dist/sdk/web/search.d.ts +53 -0
  353. package/dist/sdk/web/search.js +168 -0
  354. package/dist/sdk/web/text.d.ts +2 -0
  355. package/dist/sdk/web/text.js +7 -0
  356. package/dist/sdk/web/tools.d.ts +22 -0
  357. package/dist/sdk/web/tools.js +195 -0
  358. package/dist/sdk/web/turndown-plugin-gfm.d.ts +4 -0
  359. package/dist/sdk/wiki/notes.d.ts +68 -0
  360. package/dist/sdk/wiki/notes.js +297 -0
  361. package/dist/sdk/world/actions.d.ts +23 -0
  362. package/dist/sdk/world/actions.js +31 -0
  363. package/dist/sdk/world/cli.d.ts +12 -0
  364. package/dist/sdk/world/cli.js +166 -0
  365. package/dist/sdk/world/images.d.ts +20 -0
  366. package/dist/sdk/world/images.js +48 -0
  367. package/dist/sdk/world/untrusted.d.ts +12 -0
  368. package/dist/sdk/world/untrusted.js +20 -0
  369. package/dist/sdk/world/world.d.ts +65 -0
  370. package/dist/sdk/world/world.js +80 -0
  371. package/dist/terminal-opentui.js +13612 -0
  372. package/dist/terminal-pi.js +808 -151
  373. package/docs/README.md +22 -0
  374. package/docs/architecture/00-overview.md +159 -0
  375. package/docs/architecture/01-extension-points.md +78 -0
  376. package/docs/architecture/02-sessions-and-runs.md +146 -0
  377. package/docs/architecture/03-variants.md +95 -0
  378. package/docs/architecture/04-prompt.md +102 -0
  379. package/docs/architecture/05-refinement.md +107 -0
  380. package/docs/architecture/06-plugins-and-capabilities.md +93 -0
  381. package/docs/architecture/07-tools-and-gate.md +88 -0
  382. package/docs/architecture/08-memory-and-history.md +94 -0
  383. package/docs/architecture/09-accounts-and-connectors.md +90 -0
  384. package/docs/architecture/10-server-protocol.md +84 -0
  385. package/docs/architecture/11-terminal.md +81 -0
  386. package/docs/architecture/12-storage.md +61 -0
  387. package/docs/architecture/13-world-tools.md +23 -0
  388. package/docs/architecture/README.md +114 -0
  389. package/docs/architecture/proposals/PROP-0001-reporting-section.md +106 -0
  390. package/docs/architecture/proposals/PROP-0002-retain-rollout-workspaces.md +104 -0
  391. package/docs/architecture/proposals/PROP-0003-executor-settings.md +81 -0
  392. package/docs/architecture/proposals/PROP-0004-flexible-reporting-guidance.md +71 -0
  393. package/docs/architecture/proposals/PROP-0005-xharness-cli-name.md +78 -0
  394. package/docs/architecture/proposals/PROP-0006-run-checklist.md +68 -0
  395. package/docs/architecture/proposals/PROP-0007-run-continuation.md +80 -0
  396. package/docs/architecture/proposals/PROP-0008-lessons-from-runs.md +80 -0
  397. package/docs/architecture/proposals/PROP-0009-foundation-and-variants.md +78 -0
  398. package/docs/architecture/proposals/PROP-0010-session-names.md +73 -0
  399. package/docs/architecture/proposals/PROP-0011-doctor.md +63 -0
  400. package/docs/architecture/proposals/PROP-0012-release-baseline.md +56 -0
  401. package/docs/architecture/proposals/README.md +76 -0
  402. package/docs/decisions/ADR-0002-native-subagent-lifecycle.md +49 -0
  403. package/docs/decisions/ADR-0003-shared-asynchronous-subagents.md +70 -0
  404. package/docs/decisions/ADR-0004-fullscreen-terminal-layout.md +50 -0
  405. package/docs/decisions/ADR-0005-app-provided-oauth-clients.md +54 -0
  406. package/docs/decisions/ADR-0006-opentui-only-terminal.md +47 -0
  407. package/docs/decisions/ADR-0007-reporting-section.md +33 -0
  408. package/docs/decisions/ADR-0008-flexible-reporting-guidance.md +38 -0
  409. package/docs/decisions/ADR-0009-xharness-command.md +38 -0
  410. package/docs/decisions/ADR-0010-lessons-in-the-wiki.md +31 -0
  411. package/docs/decisions/ADR-0011-foundation-and-variants.md +28 -0
  412. package/docs/decisions/ADR-0012-native-session-names.md +34 -0
  413. package/docs/decisions/ADR-0013-doctor.md +27 -0
  414. package/docs/decisions/ADR-0014-public-release-baseline.md +21 -0
  415. package/docs/doctor.md +74 -0
  416. package/docs/experiments/EXP-0001-terminal-input-latency/plan.md +81 -0
  417. package/docs/experiments/EXP-0001-terminal-input-latency/results.md +46 -0
  418. package/docs/experiments/EXP-0002-opentui-typing-latency/plan.md +70 -0
  419. package/docs/experiments/EXP-0002-opentui-typing-latency/results.md +92 -0
  420. package/docs/features/README.md +20 -0
  421. package/docs/features/automations/README.md +41 -0
  422. package/docs/features/cores/README.md +39 -0
  423. package/docs/features/google-harness2/README.md +52 -0
  424. package/docs/features/integrations/README.md +40 -0
  425. package/docs/features/interfaces/README.md +29 -0
  426. package/docs/features/memory/README.md +28 -0
  427. package/docs/releases/1.0.0.md +40 -0
  428. package/docs/releases/README.md +36 -0
  429. package/docs/study/00-index.md +78 -0
  430. package/docs/study/arms/00-matrix.md +20 -0
  431. package/docs/study/arms/01-system-prompt.md +211 -0
  432. package/docs/study/arms/02-tools.md +79 -0
  433. package/docs/study/arms/03-subagents.md +90 -0
  434. package/docs/study/arms/04-skills.md +75 -0
  435. package/docs/study/arms/05-context-management.md +90 -0
  436. package/docs/study/arms/06-memory.md +90 -0
  437. package/docs/study/arms/07-governance.md +71 -0
  438. package/docs/study/arms/08-execution.md +69 -0
  439. package/docs/study/arms/09-observability.md +60 -0
  440. package/docs/study/arms/10-refinement.md +110 -0
  441. package/docs/study/btw-comparison.md +37 -0
  442. package/docs/study/feature-gap-review.md +42 -0
  443. package/docs/study/insights.md +123 -0
  444. package/docs/study/roadmap.md +72 -0
  445. package/docs/study/sources/claude-code.md +44 -0
  446. package/docs/study/sources/deepseek-harness.md +102 -0
  447. package/docs/study/sources/harness2.md +50 -0
  448. package/docs/study/sources/kimi-cli.md +42 -0
  449. package/docs/study/sources/omp.md +93 -0
  450. package/docs/study/sources/opencode.md +43 -0
  451. package/docs/study/sources/openhands.md +46 -0
  452. package/docs/study/sources/smolagents.md +40 -0
  453. package/docs/study/sources/swe-agent.md +34 -0
  454. package/docs/system-prompt-design.md +196 -0
  455. package/docs/terminal-tui.md +473 -56
  456. package/package.json +43 -13
  457. package/docs/evidence/terminal-2026-10-17/120x40-completed-transcript.ansi.gz +0 -0
  458. package/docs/evidence/terminal-2026-10-17/40x20-settings-interaction.ansi.gz +0 -0
  459. package/docs/evidence/terminal-2026-10-17/40x20-settings-keyboard.ansi.gz +0 -0
  460. package/docs/evidence/terminal-2026-10-17/40x20-welcome.ansi.gz +0 -0
  461. package/docs/evidence/terminal-2026-10-17/80x24-approval-0.ansi.gz +0 -0
  462. package/docs/evidence/terminal-2026-10-17/80x24-question.ansi.gz +0 -0
  463. package/docs/evidence/terminal-2026-10-17/verification.json +0 -130
  464. package/docs/evidence/terminal-2026-10-17-followup/120x40-completed-transcript.ansi.gz +0 -0
  465. package/docs/evidence/terminal-2026-10-17-followup/40x20-settings-interaction.ansi.gz +0 -0
  466. package/docs/evidence/terminal-2026-10-17-followup/40x20-settings-keyboard.ansi.gz +0 -0
  467. package/docs/evidence/terminal-2026-10-17-followup/40x20-welcome.ansi.gz +0 -0
  468. package/docs/evidence/terminal-2026-10-17-followup/80x24-approval-0.ansi.gz +0 -0
  469. package/docs/evidence/terminal-2026-10-17-followup/80x24-plugin-light.ansi.gz +0 -0
  470. package/docs/evidence/terminal-2026-10-17-followup/80x24-question-batch.ansi.gz +0 -0
  471. package/docs/evidence/terminal-2026-10-17-followup/80x24-question.ansi.gz +0 -0
  472. package/docs/evidence/terminal-2026-10-17-followup/app-bundle/80x24-approval-0.ansi.gz +0 -0
  473. package/docs/evidence/terminal-2026-10-17-followup/app-bundle/80x24-plugin-light.ansi.gz +0 -0
  474. package/docs/evidence/terminal-2026-10-17-followup/app-bundle/80x24-question-batch.ansi.gz +0 -0
  475. package/docs/evidence/terminal-2026-10-17-followup/app-bundle/80x24-question.ansi.gz +0 -0
  476. package/docs/evidence/terminal-2026-10-17-followup/app-bundle/verification.json +0 -95
  477. package/docs/evidence/terminal-2026-10-17-followup/global-install/80x24-approval-0.ansi.gz +0 -0
  478. package/docs/evidence/terminal-2026-10-17-followup/global-install/80x24-plugin-light.ansi.gz +0 -0
  479. package/docs/evidence/terminal-2026-10-17-followup/global-install/80x24-question-batch.ansi.gz +0 -0
  480. package/docs/evidence/terminal-2026-10-17-followup/global-install/80x24-question.ansi.gz +0 -0
  481. package/docs/evidence/terminal-2026-10-17-followup/global-install/README.md +0 -27
  482. package/docs/evidence/terminal-2026-10-17-followup/global-install/shell-command-80x24.ansi.gz +0 -0
  483. package/docs/evidence/terminal-2026-10-17-followup/global-install/shell-command.json +0 -18
  484. package/docs/evidence/terminal-2026-10-17-followup/global-install/verification.json +0 -95
  485. package/docs/evidence/terminal-2026-10-17-followup/harness-reference-80x24.json.gz +0 -0
  486. package/docs/evidence/terminal-2026-10-17-followup/harness-reference-final-80x24.json.gz +0 -0
  487. package/docs/evidence/terminal-2026-10-17-followup/harness-reference-scenario.json +0 -60
  488. package/docs/evidence/terminal-2026-10-17-followup/live-codex/README.md +0 -24
  489. package/docs/evidence/terminal-2026-10-17-followup/live-codex/complete-80x24.ansi.gz +0 -0
  490. package/docs/evidence/terminal-2026-10-17-followup/live-codex/verification.json +0 -57
  491. package/docs/evidence/terminal-2026-10-17-followup/omp-reference-80x24-early.json.gz +0 -0
  492. package/docs/evidence/terminal-2026-10-17-followup/omp-reference-80x24.json.gz +0 -0
  493. package/docs/evidence/terminal-2026-10-17-followup/omp-reference-scenario.json +0 -58
  494. package/docs/evidence/terminal-2026-10-17-followup/omp-supplemental-static.json.gz +0 -0
  495. package/docs/evidence/terminal-2026-10-17-followup/rea-artifacts.json +0 -320
  496. package/docs/evidence/terminal-2026-10-17-followup/reference-comparison.json +0 -30
  497. package/docs/evidence/terminal-2026-10-17-followup/reference-comparison.md +0 -133
  498. package/docs/evidence/terminal-2026-10-17-followup/reference-source-observations.json +0 -20
  499. package/docs/evidence/terminal-2026-10-17-followup/verification.json +0 -207
  500. package/src/accounts/accounts.test.ts +0 -333
  501. package/src/accounts/accounts.ts +0 -658
  502. package/src/accounts/env.test.ts +0 -95
  503. package/src/accounts/env.ts +0 -338
  504. package/src/accounts/secrets.ts +0 -50
  505. package/src/accounts/store.ts +0 -338
  506. package/src/capabilities/api.ts +0 -75
  507. package/src/capabilities/runSnapshot.ts +0 -59
  508. package/src/capabilities/types.ts +0 -34
  509. package/src/cli.ts +0 -118
  510. package/src/core/bus.ts +0 -34
  511. package/src/core/changes.ts +0 -33
  512. package/src/core/env.ts +0 -27
  513. package/src/core/errors.ts +0 -32
  514. package/src/core/frontmatter.ts +0 -47
  515. package/src/core/fs.test.ts +0 -38
  516. package/src/core/fs.ts +0 -92
  517. package/src/core/index.ts +0 -193
  518. package/src/core/path.test.ts +0 -14
  519. package/src/core/path.ts +0 -79
  520. package/src/core/projects.ts +0 -90
  521. package/src/core/text.ts +0 -39
  522. package/src/harness.ts +0 -312
  523. package/src/hub/catalog.json +0 -123
  524. package/src/hub/cli.ts +0 -59
  525. package/src/hub/hub.test.ts +0 -205
  526. package/src/hub/hub.ts +0 -256
  527. package/src/hub/schema.ts +0 -81
  528. package/src/index.ts +0 -75
  529. package/src/mcp/connections.ts +0 -614
  530. package/src/mcp/manager.ts +0 -130
  531. package/src/mcp/oauth.ts +0 -195
  532. package/src/mcp/scopeMigration.test.ts +0 -79
  533. package/src/mcp/scopeMigration.ts +0 -204
  534. package/src/mcp/service.test.ts +0 -376
  535. package/src/mcp/service.ts +0 -549
  536. package/src/mcp/types.ts +0 -108
  537. package/src/memory/api.test.ts +0 -82
  538. package/src/memory/api.ts +0 -303
  539. package/src/memory/blocks.test.ts +0 -78
  540. package/src/memory/blocks.ts +0 -408
  541. package/src/memory/caller.ts +0 -69
  542. package/src/memory/curation.test.ts +0 -163
  543. package/src/memory/curation.ts +0 -64
  544. package/src/memory/dispatch.ts +0 -59
  545. package/src/memory/facts.test.ts +0 -41
  546. package/src/memory/facts.ts +0 -248
  547. package/src/memory/graph.ts +0 -103
  548. package/src/memory/health.test.ts +0 -130
  549. package/src/memory/health.ts +0 -74
  550. package/src/memory/maintainer.ts +0 -272
  551. package/src/memory/maintenance.test.ts +0 -176
  552. package/src/memory/maintenance.ts +0 -518
  553. package/src/memory/migrate.ts +0 -79
  554. package/src/memory/operations.ts +0 -150
  555. package/src/memory/proposals.test.ts +0 -168
  556. package/src/memory/proposals.ts +0 -584
  557. package/src/memory/recall.test.ts +0 -115
  558. package/src/memory/recall.ts +0 -278
  559. package/src/memory/references.ts +0 -77
  560. package/src/memory/runContext.ts +0 -93
  561. package/src/memory/secrets.ts +0 -6
  562. package/src/memory/store.test.ts +0 -66
  563. package/src/memory/store.ts +0 -385
  564. package/src/memory/wiki.test.ts +0 -47
  565. package/src/memory/wiki.ts +0 -422
  566. package/src/memory/wikiIndex.test.ts +0 -88
  567. package/src/memory/wikiIndex.ts +0 -116
  568. package/src/plugins/api.ts +0 -181
  569. package/src/plugins/attachments.test.ts +0 -84
  570. package/src/plugins/attachments.ts +0 -141
  571. package/src/plugins/builtin.ts +0 -82
  572. package/src/plugins/catalogue.test.ts +0 -254
  573. package/src/plugins/catalogue.ts +0 -251
  574. package/src/plugins/cli.ts +0 -184
  575. package/src/plugins/discover.ts +0 -151
  576. package/src/plugins/firstParty.test.ts +0 -143
  577. package/src/plugins/firstParty.ts +0 -129
  578. package/src/plugins/hooks.test.ts +0 -250
  579. package/src/plugins/hooks.ts +0 -239
  580. package/src/plugins/identity.ts +0 -37
  581. package/src/plugins/install.test.ts +0 -107
  582. package/src/plugins/install.ts +0 -106
  583. package/src/plugins/inventory.ts +0 -123
  584. package/src/plugins/manifest.ts +0 -76
  585. package/src/plugins/plugins.test.ts +0 -205
  586. package/src/plugins/plugins.ts +0 -189
  587. package/src/plugins/proposal.ts +0 -121
  588. package/src/plugins/runtime.test.ts +0 -40
  589. package/src/plugins/runtime.ts +0 -82
  590. package/src/plugins/trust.ts +0 -142
  591. package/src/plugins/types.ts +0 -149
  592. package/src/prompt/compile.test.ts +0 -261
  593. package/src/prompt/compile.ts +0 -732
  594. package/src/server/methods.ts +0 -349
  595. package/src/server/remote.ts +0 -77
  596. package/src/server/rpc.ts +0 -116
  597. package/src/server/serve.ts +0 -28
  598. package/src/server/server.test.ts +0 -174
  599. package/src/sessions/approvals.ts +0 -118
  600. package/src/sessions/contracts.ts +0 -336
  601. package/src/sessions/conversation.test.ts +0 -177
  602. package/src/sessions/extensionSession.test.ts +0 -74
  603. package/src/sessions/extensionUi.test.ts +0 -65
  604. package/src/sessions/extensionUi.ts +0 -102
  605. package/src/sessions/history.ts +0 -51
  606. package/src/sessions/lineageJoin.ts +0 -75
  607. package/src/sessions/policy.ts +0 -36
  608. package/src/sessions/pricing.ts +0 -60
  609. package/src/sessions/questionBatches.test.ts +0 -110
  610. package/src/sessions/reasoningSummaries.ts +0 -59
  611. package/src/sessions/registry.ts +0 -381
  612. package/src/sessions/runIndex.ts +0 -99
  613. package/src/sessions/runStore.test.ts +0 -152
  614. package/src/sessions/runStore.ts +0 -332
  615. package/src/sessions/runner.ts +0 -604
  616. package/src/sessions/runtimeResources.test.ts +0 -61
  617. package/src/sessions/sessions.test.ts +0 -549
  618. package/src/sessions/sessions.ts +0 -339
  619. package/src/skills/registry.test.ts +0 -104
  620. package/src/skills/registry.ts +0 -413
  621. package/src/terminal/accountsMenu.test.ts +0 -225
  622. package/src/terminal/accountsMenu.ts +0 -382
  623. package/src/terminal/cli.ts +0 -149
  624. package/src/terminal/client.ts +0 -74
  625. package/src/terminal/control.test.ts +0 -23
  626. package/src/terminal/control.ts +0 -23
  627. package/src/terminal/controller.ts +0 -291
  628. package/src/terminal/hubMenu.ts +0 -24
  629. package/src/terminal/launch.test.ts +0 -25
  630. package/src/terminal/launch.ts +0 -48
  631. package/src/terminal/piExtension.lifecycle.test.ts +0 -55
  632. package/src/terminal/piExtension.ts +0 -259
  633. package/src/terminal/pluginControl.test.ts +0 -146
  634. package/src/terminal/pluginMenu.ts +0 -112
  635. package/src/terminal/socket.test.ts +0 -71
  636. package/src/terminal/socket.ts +0 -232
  637. package/src/terminal/standalone.test.ts +0 -167
  638. package/src/terminal/standalone.ts +0 -153
  639. package/src/terminal/terminal.test.ts +0 -399
  640. package/src/terminal/terminals.ts +0 -553
  641. package/src/terminal/tui/application.test.ts +0 -114
  642. package/src/terminal/tui/application.ts +0 -491
  643. package/src/terminal/tui/commands.test.ts +0 -218
  644. package/src/terminal/tui/commands.ts +0 -361
  645. package/src/terminal/tui/dialogs.ts +0 -301
  646. package/src/terminal/tui/editor.test.ts +0 -84
  647. package/src/terminal/tui/editor.ts +0 -79
  648. package/src/terminal/tui/keybindings.test.ts +0 -22
  649. package/src/terminal/tui/keybindings.ts +0 -50
  650. package/src/terminal/tui/piAdapter.ts +0 -62
  651. package/src/terminal/tui/presentation.test.ts +0 -79
  652. package/src/terminal/tui/questions.test.ts +0 -41
  653. package/src/terminal/tui/questions.ts +0 -47
  654. package/src/terminal/tui/runtime.socket.test.ts +0 -104
  655. package/src/terminal/tui/runtime.test.ts +0 -215
  656. package/src/terminal/tui/runtime.ts +0 -388
  657. package/src/terminal/tui/sessionUi.ts +0 -24
  658. package/src/terminal/tui/settings.test.ts +0 -150
  659. package/src/terminal/tui/settings.ts +0 -188
  660. package/src/terminal/tui/status.test.ts +0 -70
  661. package/src/terminal/tui/status.ts +0 -109
  662. package/src/terminal/tui/theme.ts +0 -174
  663. package/src/terminal/tui/tools.test.ts +0 -145
  664. package/src/terminal/tui/tools.ts +0 -142
  665. package/src/terminal/tui/transcript.test.ts +0 -25
  666. package/src/terminal/tui/transcript.ts +0 -124
  667. package/src/terminal/tui/ui.test.ts +0 -313
  668. package/src/terminal/tui/ui.ts +0 -166
  669. package/src/terminal/tui/welcome.ts +0 -102
  670. package/src/tools/askUser.test.ts +0 -69
  671. package/src/tools/askUser.ts +0 -59
  672. package/src/tools/definitions.ts +0 -187
  673. package/src/tools/maintenance.ts +0 -24
  674. package/src/tools/memoryTools.ts +0 -22
  675. package/src/tools/pluginPropose.ts +0 -41
  676. package/src/tools/registryWrite.test.ts +0 -101
  677. package/src/tools/registryWrite.ts +0 -182
  678. package/src/tools/spawnSubagent.ts +0 -92
  679. package/src/tools/types.ts +0 -39
  680. package/src/web/safeRequest.ts +0 -171
  681. package/src/web/text.ts +0 -53
  682. package/src/web/tools.ts +0 -134
  683. package/src/web/web.test.ts +0 -141
@@ -0,0 +1,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;