@schlenkr/ragents 0.1.5 → 0.1.6

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 (1052) hide show
  1. package/README.md +18 -11
  2. package/apps/server/package.json +8 -6
  3. package/apps/server/src/access-projection.ts +3 -3
  4. package/apps/server/src/access-service.ts +19 -8
  5. package/apps/server/src/access-session.ts +6 -2
  6. package/apps/server/src/api/contracts.ts +19 -18
  7. package/apps/server/src/api/core-methods.ts +45 -26
  8. package/apps/server/src/api/delivery.ts +4 -4
  9. package/apps/server/src/api/reference.ts +1 -1
  10. package/apps/server/src/api/rights.ts +86 -7
  11. package/apps/server/src/chat-context.ts +1 -1
  12. package/apps/server/src/chat-handler.ts +14 -7
  13. package/apps/server/src/config-file.ts +25 -6
  14. package/apps/server/src/config.ts +4 -4
  15. package/apps/server/src/data-directory.ts +1 -1
  16. package/apps/server/src/folder-install.ts +115 -0
  17. package/apps/server/src/host-api.json +1256 -0
  18. package/apps/server/src/host-api.ts +190 -0
  19. package/apps/server/src/host-resolution-hooks.mjs +50 -1
  20. package/apps/server/src/host-resolution.ts +26 -1
  21. package/apps/server/src/host-version.ts +41 -0
  22. package/apps/server/src/host-web.ts +59 -0
  23. package/apps/server/src/layout.ts +1 -1
  24. package/apps/server/src/main.ts +3 -2
  25. package/apps/server/src/missing-environment.ts +47 -0
  26. package/apps/server/src/parent-watch.ts +37 -0
  27. package/apps/server/src/plugin-build/build.ts +650 -0
  28. package/apps/server/src/plugin-build/host-api-names.ts +185 -0
  29. package/apps/server/src/plugin-build/plugin-description.ts +118 -0
  30. package/apps/server/src/plugin-build/typecheck.ts +66 -0
  31. package/{plugins/ragents.actor-programs/server → apps/server/src/plugin-support/actor-programs}/app-project.ts +16 -15
  32. package/{plugins/ragents.actor-programs/server → apps/server/src/plugin-support/actor-programs}/client-compiler.ts +4 -4
  33. package/{plugins/ragents.actor-programs/server → apps/server/src/plugin-support/actor-programs}/client-contracts.ts +4 -4
  34. package/apps/server/src/plugin-support/actor-programs/client-runtime.ts +27 -0
  35. package/{plugins/ragents.actor-programs → apps/server/src/plugin-support/actor-programs}/contract.ts +3 -3
  36. package/apps/server/src/plugin-support/actor-programs/service.ts +1 -1
  37. package/{plugins/ragents.actor-programs/server → apps/server/src/plugin-support/actor-programs}/tailwind.ts +2 -3
  38. package/{plugins/ragents.actor-programs → apps/server/src/plugin-support/actor-programs}/workflow/index.ts +48 -48
  39. package/apps/server/src/plugin-support/agent-tool.ts +10 -5
  40. package/apps/server/src/plugin-support/http.ts +1 -1
  41. package/apps/server/src/plugin-support/language-server/contract.ts +37 -6
  42. package/apps/server/src/plugin-support/language-server/plugin.ts +18 -8
  43. package/apps/server/src/plugin-support/language-server/snapshot-method.ts +32 -7
  44. package/apps/server/src/plugin-support/language-server/tools.ts +59 -15
  45. package/apps/server/src/plugin-support/model-aliases.ts +77 -0
  46. package/apps/server/src/plugin-support/model-choice.ts +17 -7
  47. package/apps/server/src/plugin-support/model-completion.ts +58 -0
  48. package/apps/server/src/plugin-support/model-upstreams.ts +2 -2
  49. package/apps/server/src/plugin-support/native-typescript-executor.ts +10 -7
  50. package/apps/server/src/plugin-support/plugin-config.ts +1 -1
  51. package/apps/server/src/plugin-support/plugin-folder.ts +4 -1
  52. package/apps/server/src/plugin-support/plugin-module.ts +1 -1
  53. package/apps/server/src/plugin-support/plugins-root.ts +6 -10
  54. package/apps/server/src/plugin-support/process-sandbox.ts +312 -0
  55. package/apps/server/src/plugin-support/product-model-settings-contract.ts +14 -5
  56. package/apps/server/src/plugin-support/product-model-settings.ts +10 -9
  57. package/{plugins/ragents.product/server/relay.ts → apps/server/src/plugin-support/product-relay.ts} +2 -2
  58. package/apps/server/src/plugin-support/product-start-options.ts +8 -3
  59. package/apps/server/src/plugin-support/prompt.ts +1 -1
  60. package/apps/server/src/plugin-support/provision.ts +6 -0
  61. package/apps/server/src/plugin-support/run-scripts.ts +16 -2
  62. package/apps/server/src/plugin-support/skills.ts +32 -16
  63. package/apps/server/src/plugin-support/start-entries-contract.ts +12 -3
  64. package/apps/server/src/plugin-support/start-options-contract.ts +5 -1
  65. package/apps/server/src/plugin-support/thinking-level.ts +6 -1
  66. package/apps/server/src/plugin-support/tool-availability.ts +1 -7
  67. package/apps/server/src/plugin-support/workspace-ownership.ts +12 -6
  68. package/apps/server/src/plugin-support/workspace-sandbox-host.ts +184 -37
  69. package/apps/server/src/profile/bundle-manifest.ts +183 -0
  70. package/apps/server/src/profile/compose.ts +19 -10
  71. package/apps/server/src/profile/plugin-discovery.ts +98 -46
  72. package/apps/server/src/profile/provisioning.ts +30 -26
  73. package/apps/server/src/profile-target.ts +3 -0
  74. package/apps/server/src/provider.ts +182 -99
  75. package/apps/server/src/ragents/actor-chat-history.ts +23 -22
  76. package/apps/server/src/ragents/chat-projection.ts +25 -14
  77. package/apps/server/src/ragents/chat-text-positions.ts +4 -4
  78. package/apps/server/src/ragents/coordinator.ts +27 -1
  79. package/apps/server/src/ragents/document-store.ts +1 -1
  80. package/apps/server/src/ragents/engine.ts +69 -36
  81. package/apps/server/src/ragents/global-chat.ts +26 -13
  82. package/apps/server/src/ragents/host-services.ts +15 -6
  83. package/apps/server/src/ragents/journal-chat-events.ts +31 -15
  84. package/apps/server/src/ragents/product-runtime.ts +1 -1
  85. package/apps/server/src/ragents/run-owner.ts +17 -0
  86. package/apps/server/src/ragents/runtime-bridge.ts +1 -1
  87. package/apps/server/src/ragents/session.ts +181 -82
  88. package/apps/server/src/ragents/start-option-state.ts +1 -1
  89. package/apps/server/src/ragents/typescript-tools.ts +35 -27
  90. package/apps/server/src/ragents/workspace-runtime.ts +74 -8
  91. package/apps/server/src/rpc/dispatcher.ts +17 -8
  92. package/apps/server/src/rpc/http-transport.ts +1 -3
  93. package/apps/server/src/rpc/stdio-transport.ts +1 -1
  94. package/apps/server/src/run-preparation-contract.ts +1 -1
  95. package/apps/server/src/run-preparation-input.ts +1 -1
  96. package/apps/server/src/run-preparation.ts +13 -20
  97. package/apps/server/src/run-transfer.ts +2 -2
  98. package/apps/server/src/server.ts +112 -33
  99. package/apps/server/src/settings.ts +7 -8
  100. package/apps/server/src/title-compactor.ts +5 -8
  101. package/apps/server/src/title-settings.ts +3 -3
  102. package/apps/server/src/web-bundles.ts +79 -0
  103. package/apps/server/src/web-stylesheet.ts +85 -0
  104. package/apps/server/tsconfig.json +4 -4
  105. package/apps/server/tsconfig.plugin.json +58 -0
  106. package/apps/web/dist/assets/highlighted-body-KPVGNVTW-B9qYBARS.js +1 -0
  107. package/apps/web/dist/assets/main-BCjvD2Hh.js +6 -0
  108. package/apps/web/dist/assets/mermaid-HWGCJPDP-BPn4aV2r.css +1 -0
  109. package/apps/web/dist/assets/mermaid-HWGCJPDP-CvYYFK_n.js +478 -0
  110. package/apps/web/dist/assets/runPanel-CG7kRMJh.js +21 -0
  111. package/apps/web/dist/help/guide-access.html +199 -0
  112. package/apps/web/dist/help/guide-access.md +84 -0
  113. package/apps/web/dist/help/guide-clients.html +421 -0
  114. package/apps/web/dist/help/guide-clients.md +336 -0
  115. package/apps/web/dist/help/guide-distributed.html +320 -0
  116. package/apps/web/dist/help/guide-distributed.md +225 -0
  117. package/apps/web/dist/help/guide-functions.html +231 -0
  118. package/apps/web/dist/help/guide-functions.md +127 -0
  119. package/apps/web/dist/help/guide-getting-started.html +230 -0
  120. package/apps/web/dist/help/guide-getting-started.md +123 -0
  121. package/apps/web/dist/help/guide-ideas.html +183 -0
  122. package/apps/web/dist/help/guide-ideas.md +71 -0
  123. package/apps/web/dist/help/guide-plugins.html +450 -0
  124. package/apps/web/dist/help/guide-plugins.md +341 -0
  125. package/apps/web/dist/help/guide-programs.html +359 -0
  126. package/apps/web/dist/help/guide-programs.md +271 -0
  127. package/apps/web/dist/help/guide-runtime.html +338 -0
  128. package/apps/web/dist/help/guide-runtime.md +225 -0
  129. package/apps/web/dist/help/guide.html +133 -0
  130. package/apps/web/dist/help/guide.md +13 -0
  131. package/apps/web/dist/help/homepage-bullets.js +12 -0
  132. package/apps/web/dist/help/homepage-distributed.js +261 -0
  133. package/apps/web/dist/help/homepage-plugins.js +30 -0
  134. package/apps/web/dist/help/homepage-scenes.js +368 -0
  135. package/apps/web/dist/help/homepage-stickers.js +69 -0
  136. package/apps/web/dist/help/homepage-story-nav.js +11 -0
  137. package/apps/web/dist/help/homepage-subnav.js +61 -0
  138. package/apps/web/dist/help/homepage.css +833 -0
  139. package/apps/web/dist/help/index.html +1167 -0
  140. package/apps/web/dist/help/mini-app.css +7056 -0
  141. package/apps/web/dist/help/mini-app.html +15 -0
  142. package/apps/web/dist/help/mini-app.js +131 -0
  143. package/apps/web/dist/help/screenshots/release-checklist-vscode.png +0 -0
  144. package/apps/web/dist/help/screenshots/release-checklist-web.png +0 -0
  145. package/apps/web/dist/help/scroll-vendor.js +73 -0
  146. package/apps/web/dist/help/site.css +63 -0
  147. package/apps/web/dist/help/site.js +103 -0
  148. package/apps/web/dist/host-web.json +143 -0
  149. package/apps/web/dist/index.html +15 -0
  150. package/apps/web/dist/run-panel.html +15 -0
  151. package/apps/web/package.json +2 -2
  152. package/apps/web/src/App.tsx +8 -6
  153. package/apps/web/src/Overview.tsx +5 -5
  154. package/apps/web/src/PluginActivation.ts +25 -5
  155. package/apps/web/src/PluginChat.tsx +163 -129
  156. package/apps/web/src/PluginFailureNotice.tsx +15 -0
  157. package/apps/web/src/PluginRegistry.tsx +106 -68
  158. package/apps/web/src/RunPreparationChat.tsx +40 -28
  159. package/apps/web/src/RunStore.ts +2 -2
  160. package/apps/web/src/SettingsModal.tsx +37 -37
  161. package/apps/web/src/StartOptions.tsx +81 -26
  162. package/apps/web/src/StartSelection.tsx +111 -0
  163. package/apps/web/src/StartTiles.tsx +73 -0
  164. package/apps/web/src/{CanvasShortcuts.tsx → SurfaceShortcuts.tsx} +2 -2
  165. package/apps/web/src/ThemeSettings.tsx +1 -1
  166. package/apps/web/src/WorkspacePanel.tsx +4 -4
  167. package/apps/web/src/access-session.ts +4 -1
  168. package/{plugins/ragents.orchestration/web → apps/web/src}/actor-conversation.ts +3 -3
  169. package/{plugins/ragents.actor-programs → apps/web/src/actor-programs}/client-ui/DataTable.tsx +9 -9
  170. package/{plugins/ragents.actor-programs → apps/web/src/actor-programs}/client-ui/FilePicker.tsx +4 -4
  171. package/{plugins/ragents.actor-programs → apps/web/src/actor-programs}/client-ui/FlowDiagram.tsx +16 -14
  172. package/{plugins/ragents.actor-programs → apps/web/src/actor-programs}/client-ui/FlowDiagramRenderer.tsx +3 -3
  173. package/{plugins/ragents.actor-programs → apps/web/src/actor-programs}/client-ui/Form.tsx +12 -12
  174. package/{plugins/ragents.actor-programs → apps/web/src/actor-programs}/client-ui/Layout.tsx +1 -1
  175. package/{plugins/ragents.actor-programs → apps/web/src/actor-programs}/client-ui/MessageList.tsx +5 -5
  176. package/{plugins/ragents.actor-programs → apps/web/src/actor-programs}/client-ui/Viewers.tsx +8 -7
  177. package/{plugins/ragents.actor-programs → apps/web/src/actor-programs}/client-ui/WorkflowDiagram.tsx +1 -1
  178. package/apps/web/src/actor-programs/client-ui/chat-contracts.d.ts +64 -0
  179. package/{plugins/ragents.actor-programs → apps/web/src/actor-programs}/client-ui/contracts.d.ts +2 -2
  180. package/{plugins/ragents.actor-programs → apps/web/src/actor-programs}/client-ui/file-selection.ts +5 -5
  181. package/{plugins/ragents.actor-programs → apps/web/src/actor-programs}/client-ui/index.tsx +22 -16
  182. package/{plugins/ragents.actor-programs → apps/web/src/actor-programs}/client-ui/layout-contracts.d.ts +1 -1
  183. package/{plugins/ragents.actor-programs → apps/web/src/actor-programs}/client-ui/message-list-contracts.d.ts +2 -2
  184. package/{plugins/ragents.actor-programs → apps/web/src/actor-programs}/client-ui/workflow-diagram-contracts.d.ts +1 -1
  185. package/apps/web/src/api.ts +43 -22
  186. package/apps/web/src/chat/QuasselHost.tsx +12 -0
  187. package/apps/web/src/chat/StoppedActorNotice.tsx +39 -0
  188. package/apps/web/src/chat/chat-target.ts +14 -5
  189. package/apps/web/src/chat/requests.ts +13 -5
  190. package/apps/web/src/chat/useAttachmentCapabilities.ts +2 -2
  191. package/apps/web/src/chat/useChat.ts +8 -7
  192. package/apps/web/src/chat/user-location.ts +1 -1
  193. package/apps/web/src/chat-view-settings.tsx +49 -0
  194. package/apps/web/src/host-modules.ts +90 -0
  195. package/apps/web/src/language-server/api.ts +24 -0
  196. package/{plugins/ragents.lsp-roslyn/web → apps/web/src/language-server}/language-server-plugin.tsx +133 -6
  197. package/apps/web/src/main.tsx +4 -2
  198. package/apps/web/src/offered-machines.ts +11 -0
  199. package/apps/web/src/panel/ConnectionsPage.tsx +117 -0
  200. package/apps/web/src/panel/LoginForm.tsx +9 -9
  201. package/apps/web/src/panel/PanelDialogs.tsx +44 -27
  202. package/apps/web/src/panel/PanelHeader.tsx +11 -0
  203. package/apps/web/src/panel/PanelPage.tsx +8 -5
  204. package/apps/web/src/panel/RunLine.tsx +48 -0
  205. package/apps/web/src/panel/RunsPage.tsx +84 -0
  206. package/apps/web/src/panel/StartPage.tsx +163 -0
  207. package/apps/web/src/panel/connection-state.ts +40 -0
  208. package/apps/web/src/panel/contract.ts +64 -21
  209. package/apps/web/src/panel/page-props.ts +6 -0
  210. package/apps/web/src/plugin-bootstrap.ts +60 -31
  211. package/{plugins/ragents.product/web → apps/web/src/product}/ModelControl.tsx +3 -3
  212. package/{plugins/ragents.product/web → apps/web/src/product}/ProductModelSettings.tsx +7 -7
  213. package/{plugins/ragents.product/web → apps/web/src/product}/SystemPromptControl.tsx +3 -3
  214. package/{plugins/ragents.product/web → apps/web/src/product}/model-settings.ts +3 -3
  215. package/{plugins/ragents.product/web → apps/web/src/product}/start-options.tsx +2 -2
  216. package/apps/web/src/rpc/client.ts +28 -6
  217. package/apps/web/src/run-panel/RunPanelApp.tsx +334 -0
  218. package/apps/web/src/{column/ColumnRunHeader.tsx → run-panel/RunPanelHeader.tsx} +2 -2
  219. package/apps/web/src/{column/ColumnMenu.tsx → run-panel/RunPanelMenu.tsx} +4 -4
  220. package/apps/web/src/run-panel/RunPanelRail.tsx +38 -0
  221. package/apps/web/src/run-panel/RunPanelWorkspace.tsx +55 -0
  222. package/apps/web/src/{column → run-panel}/clipboard.ts +21 -10
  223. package/apps/web/src/run-panel/host-contract.ts +123 -0
  224. package/apps/web/src/{column → run-panel}/host.ts +31 -23
  225. package/apps/web/src/run-panel/input-bridge.ts +75 -0
  226. package/apps/web/src/run-panel/keyboard.ts +53 -0
  227. package/apps/web/src/run-panel/run-panel-location.ts +35 -0
  228. package/apps/web/src/{column → run-panel}/use-session-list.ts +3 -3
  229. package/apps/web/src/run-panel/workspace-state.ts +43 -0
  230. package/apps/web/src/{column.tsx → run-panel.tsx} +20 -13
  231. package/apps/web/src/run-preparation.ts +1 -1
  232. package/{plugins/ragents.orchestration/web → apps/web/src}/run-view.ts +25 -7
  233. package/apps/web/src/settings-contributions.ts +16 -18
  234. package/apps/web/src/title-model-settings.ts +1 -1
  235. package/apps/web/src/toolLine.ts +1 -1
  236. package/apps/web/src/ui/ListDetail.tsx +1 -1
  237. package/apps/web/src/ui/dialog.tsx +5 -5
  238. package/apps/web/src/ui/frame.css +1 -0
  239. package/apps/web/src/ui/index.ts +5 -0
  240. package/apps/web/src/ui/popover.tsx +2 -2
  241. package/apps/web/src/ui/quassel.css +41 -0
  242. package/apps/web/src/ui/relative-time.ts +36 -0
  243. package/apps/web/src/ui/startup-notice.tsx +22 -0
  244. package/apps/web/src/ui/state-icon.tsx +60 -0
  245. package/apps/web/src/ui/state-vocabulary.ts +31 -0
  246. package/apps/web/src/ui/stop-button.tsx +22 -0
  247. package/apps/web/src/ui/tailwind.css +2 -3
  248. package/apps/web/src/ui/theme.css +19 -19
  249. package/apps/web/tsconfig.json +4 -5
  250. package/apps/web/tsconfig.plugin.json +44 -0
  251. package/bundles/ragents.activity/ragents-bundle.json +38 -0
  252. package/bundles/ragents.activity/server/index.js +14 -0
  253. package/bundles/ragents.activity/server/index.js.map +7 -0
  254. package/bundles/ragents.activity/web/classes.json +1 -0
  255. package/bundles/ragents.activity/web/index.js +2 -0
  256. package/bundles/ragents.activity/web/index.js.map +7 -0
  257. package/bundles/ragents.actor-programs/prompt.hbs +80 -0
  258. package/bundles/ragents.actor-programs/ragents-bundle.json +214 -0
  259. package/bundles/ragents.actor-programs/server/index.js +2071 -0
  260. package/bundles/ragents.actor-programs/server/index.js.map +7 -0
  261. package/bundles/ragents.actor-programs/summary.hbs +17 -0
  262. package/bundles/ragents.actor-programs/web/classes.json +1 -0
  263. package/bundles/ragents.actor-programs/web/index.js +27 -0
  264. package/bundles/ragents.actor-programs/web/index.js.map +7 -0
  265. package/bundles/ragents.ask/ask.hbs +4 -0
  266. package/bundles/ragents.ask/ragents-bundle.json +97 -0
  267. package/bundles/ragents.ask/server/chunks/chunk-PDJO75SQ.js +13 -0
  268. package/bundles/ragents.ask/server/chunks/chunk-PDJO75SQ.js.map +7 -0
  269. package/bundles/ragents.ask/server/exports/server/contract.js +11 -0
  270. package/bundles/ragents.ask/server/exports/server/contract.js.map +7 -0
  271. package/bundles/ragents.ask/server/index.js +279 -0
  272. package/bundles/ragents.ask/server/index.js.map +7 -0
  273. package/bundles/ragents.ask/web/chunks/chunk-4VXWWEG7.js +2 -0
  274. package/bundles/ragents.ask/web/chunks/chunk-4VXWWEG7.js.map +7 -0
  275. package/bundles/ragents.ask/web/chunks/chunk-HGFDGTNC.js +2 -0
  276. package/bundles/ragents.ask/web/chunks/chunk-HGFDGTNC.js.map +7 -0
  277. package/bundles/ragents.ask/web/chunks/chunk-V7W3QDVS.js +25 -0
  278. package/bundles/ragents.ask/web/chunks/chunk-V7W3QDVS.js.map +7 -0
  279. package/bundles/ragents.ask/web/chunks/chunk-VUBJDIKQ.js +2 -0
  280. package/bundles/ragents.ask/web/chunks/chunk-VUBJDIKQ.js.map +7 -0
  281. package/bundles/ragents.ask/web/classes.json +1 -0
  282. package/bundles/ragents.ask/web/exports/ask-payload.js +2 -0
  283. package/bundles/ragents.ask/web/exports/ask-payload.js.map +7 -0
  284. package/bundles/ragents.ask/web/exports/web/QuestionCard.js +2 -0
  285. package/bundles/ragents.ask/web/exports/web/QuestionCard.js.map +7 -0
  286. package/bundles/ragents.ask/web/exports/web/api.js +2 -0
  287. package/bundles/ragents.ask/web/exports/web/api.js.map +7 -0
  288. package/bundles/ragents.ask/web/index.js +2 -0
  289. package/bundles/ragents.ask/web/index.js.map +7 -0
  290. package/bundles/ragents.browser/ragents-bundle.json +53 -0
  291. package/bundles/ragents.browser/server/chunks/chunk-2GKLLCBE.js +11 -0
  292. package/bundles/ragents.browser/server/chunks/chunk-2GKLLCBE.js.map +7 -0
  293. package/bundles/ragents.browser/server/exports/server/contract.js +9 -0
  294. package/bundles/ragents.browser/server/exports/server/contract.js.map +7 -0
  295. package/bundles/ragents.browser/server/index.js +479 -0
  296. package/bundles/ragents.browser/server/index.js.map +7 -0
  297. package/bundles/ragents.browser/skills/browser-testing/SKILL.md +38 -0
  298. package/bundles/ragents.documents/prompt.hbs +18 -0
  299. package/bundles/ragents.documents/ragents-bundle.json +120 -0
  300. package/bundles/ragents.documents/server/chunks/chunk-QIECRZ7C.js +37 -0
  301. package/bundles/ragents.documents/server/chunks/chunk-QIECRZ7C.js.map +7 -0
  302. package/bundles/ragents.documents/server/exports/contract.js +11 -0
  303. package/bundles/ragents.documents/server/exports/contract.js.map +7 -0
  304. package/bundles/ragents.documents/server/index.js +290 -0
  305. package/bundles/ragents.documents/server/index.js.map +7 -0
  306. package/bundles/ragents.documents/web/classes.json +1 -0
  307. package/bundles/ragents.documents/web/index.js +26 -0
  308. package/bundles/ragents.documents/web/index.js.map +7 -0
  309. package/bundles/ragents.lsp-fsharp/ragents-bundle.json +49 -0
  310. package/bundles/ragents.lsp-fsharp/server/index.js +82 -0
  311. package/bundles/ragents.lsp-fsharp/server/index.js.map +7 -0
  312. package/bundles/ragents.lsp-fsharp/web/classes.json +1 -0
  313. package/bundles/ragents.lsp-fsharp/web/index.js +2 -0
  314. package/bundles/ragents.lsp-fsharp/web/index.js.map +7 -0
  315. package/bundles/ragents.lsp-roslyn/ragents-bundle.json +61 -0
  316. package/bundles/ragents.lsp-roslyn/server/index.js +208 -0
  317. package/bundles/ragents.lsp-roslyn/server/index.js.map +7 -0
  318. package/bundles/ragents.lsp-roslyn/web/classes.json +1 -0
  319. package/bundles/ragents.lsp-roslyn/web/index.js +2 -0
  320. package/bundles/ragents.lsp-roslyn/web/index.js.map +7 -0
  321. package/bundles/ragents.lsp-typescript/ragents-bundle.json +36 -0
  322. package/bundles/ragents.lsp-typescript/server/index.js +13 -0
  323. package/bundles/ragents.lsp-typescript/server/index.js.map +7 -0
  324. package/bundles/ragents.lsp-typescript/web/classes.json +1 -0
  325. package/bundles/ragents.lsp-typescript/web/index.js +2 -0
  326. package/bundles/ragents.lsp-typescript/web/index.js.map +7 -0
  327. package/bundles/ragents.model-relay/ragents-bundle.json +33 -0
  328. package/bundles/ragents.model-relay/server/index.js +230 -0
  329. package/bundles/ragents.model-relay/server/index.js.map +7 -0
  330. package/bundles/ragents.orchestration/orchestration.hbs +106 -0
  331. package/bundles/ragents.orchestration/ragents-bundle.json +194 -0
  332. package/bundles/ragents.orchestration/server/index.js +277 -0
  333. package/bundles/ragents.orchestration/server/index.js.map +7 -0
  334. package/bundles/ragents.orchestration/web/chunks/chunk-ODMMQGX2.js +2 -0
  335. package/bundles/ragents.orchestration/web/chunks/chunk-ODMMQGX2.js.map +7 -0
  336. package/bundles/ragents.orchestration/web/chunks/chunk-OQYCNYXN.js +2 -0
  337. package/bundles/ragents.orchestration/web/chunks/chunk-OQYCNYXN.js.map +7 -0
  338. package/bundles/ragents.orchestration/web/chunks/chunk-OSKPH6SZ.js +2 -0
  339. package/bundles/ragents.orchestration/web/chunks/chunk-OSKPH6SZ.js.map +7 -0
  340. package/bundles/ragents.orchestration/web/chunks/chunk-XGPPQCZR.js +2 -0
  341. package/bundles/ragents.orchestration/web/chunks/chunk-XGPPQCZR.js.map +7 -0
  342. package/bundles/ragents.orchestration/web/classes.json +1 -0
  343. package/bundles/ragents.orchestration/web/exports/web/program-slot.js +2 -0
  344. package/bundles/ragents.orchestration/web/exports/web/program-slot.js.map +7 -0
  345. package/bundles/ragents.orchestration/web/exports/web/surface-entities.js +2 -0
  346. package/bundles/ragents.orchestration/web/exports/web/surface-entities.js.map +7 -0
  347. package/bundles/ragents.orchestration/web/exports/web/tile-docking.js +2 -0
  348. package/bundles/ragents.orchestration/web/exports/web/tile-docking.js.map +7 -0
  349. package/bundles/ragents.orchestration/web/index.js +51 -0
  350. package/bundles/ragents.orchestration/web/index.js.map +7 -0
  351. package/bundles/ragents.overseer/ragents-bundle.json +144 -0
  352. package/bundles/ragents.overseer/server/index.js +652 -0
  353. package/bundles/ragents.overseer/server/index.js.map +7 -0
  354. package/bundles/ragents.overseer/web/classes.json +1 -0
  355. package/bundles/ragents.overseer/web/index.js +25 -0
  356. package/bundles/ragents.overseer/web/index.js.map +7 -0
  357. package/bundles/ragents.processes/ragents-bundle.json +93 -0
  358. package/bundles/ragents.processes/server/index.js +204 -0
  359. package/bundles/ragents.processes/server/index.js.map +7 -0
  360. package/bundles/ragents.processes/web/classes.json +1 -0
  361. package/bundles/ragents.processes/web/index.js +4 -0
  362. package/bundles/ragents.processes/web/index.js.map +7 -0
  363. package/bundles/ragents.product/preamble.hbs +9 -0
  364. package/bundles/ragents.product/ragents-bundle.json +93 -0
  365. package/bundles/ragents.product/server/index.js +208 -0
  366. package/bundles/ragents.product/server/index.js.map +7 -0
  367. package/bundles/ragents.product/web/classes.json +1 -0
  368. package/bundles/ragents.product/web/index.js +2 -0
  369. package/bundles/ragents.product/web/index.js.map +7 -0
  370. package/bundles/ragents.profile-distribution/ragents-bundle.json +64 -0
  371. package/bundles/ragents.profile-distribution/server/index.js +241 -0
  372. package/bundles/ragents.profile-distribution/server/index.js.map +7 -0
  373. package/bundles/ragents.reference/ragents-bundle.json +39 -0
  374. package/bundles/ragents.reference/run-scripts/balcony-wizard/RUN.md +27 -0
  375. package/bundles/ragents.reference/run-scripts/balcony-wizard/actors/balcony-app/package.json +10 -0
  376. package/bundles/ragents.reference/run-scripts/balcony-wizard/actors/balcony-app/src/client.tsx +80 -0
  377. package/bundles/ragents.reference/run-scripts/balcony-wizard/actors/balcony-app/src/conversation.ts +82 -0
  378. package/bundles/ragents.reference/run-scripts/balcony-wizard/actors/balcony-app/tests/conversation.test.ts +154 -0
  379. package/bundles/ragents.reference/run-scripts/balcony-wizard/package.json +9 -0
  380. package/bundles/ragents.reference/run-scripts/balcony-wizard/src/server.ts +32 -0
  381. package/bundles/ragents.reference/run-scripts/balcony-wizard/tests/program.test.ts +59 -0
  382. package/bundles/ragents.reference/run-scripts/conversation-circle/RUN.md +13 -0
  383. package/bundles/ragents.reference/run-scripts/conversation-circle/package.json +9 -0
  384. package/bundles/ragents.reference/run-scripts/conversation-circle/src/server.ts +81 -0
  385. package/bundles/ragents.reference/run-scripts/conversation-circle/tests/helpers.ts +26 -0
  386. package/bundles/ragents.reference/run-scripts/conversation-circle/tests/program.test.ts +34 -0
  387. package/bundles/ragents.reference/run-scripts/learning-afternoon/RUN.md +24 -0
  388. package/bundles/ragents.reference/run-scripts/learning-afternoon/package.json +10 -0
  389. package/bundles/ragents.reference/run-scripts/learning-afternoon/prompts/experiment.md +1 -0
  390. package/bundles/ragents.reference/run-scripts/learning-afternoon/prompts/helper.md +5 -0
  391. package/bundles/ragents.reference/run-scripts/learning-afternoon/prompts/quiz.md +1 -0
  392. package/bundles/ragents.reference/run-scripts/learning-afternoon/src/client.tsx +27 -0
  393. package/bundles/ragents.reference/run-scripts/learning-afternoon/src/server.ts +137 -0
  394. package/bundles/ragents.reference/run-scripts/learning-afternoon/src/state.ts +38 -0
  395. package/bundles/ragents.reference/run-scripts/learning-afternoon/src/view.tsx +42 -0
  396. package/bundles/ragents.reference/run-scripts/learning-afternoon/src/workflow.ts +38 -0
  397. package/bundles/ragents.reference/run-scripts/learning-afternoon/tests/program.test.ts +218 -0
  398. package/bundles/ragents.reference/run-scripts/moderated-round/RUN.md +12 -0
  399. package/bundles/ragents.reference/run-scripts/moderated-round/package.json +9 -0
  400. package/bundles/ragents.reference/run-scripts/moderated-round/src/server.ts +60 -0
  401. package/bundles/ragents.reference/run-scripts/moderated-round/tests/helpers.ts +26 -0
  402. package/bundles/ragents.reference/run-scripts/moderated-round/tests/program.test.ts +24 -0
  403. package/bundles/ragents.reference/run-scripts/shared-actor-list/RUN.md +18 -0
  404. package/bundles/ragents.reference/run-scripts/shared-actor-list/actors/shared-list/package.json +16 -0
  405. package/bundles/ragents.reference/run-scripts/shared-actor-list/actors/shared-list/src/client.tsx +39 -0
  406. package/bundles/ragents.reference/run-scripts/shared-actor-list/actors/shared-list/src/contract.ts +15 -0
  407. package/bundles/ragents.reference/run-scripts/shared-actor-list/actors/shared-list/src/server.ts +14 -0
  408. package/bundles/ragents.reference/run-scripts/shared-actor-list/actors/shared-list/tests/program.test.ts +13 -0
  409. package/bundles/ragents.reference/run-scripts/shared-actor-list/package.json +9 -0
  410. package/bundles/ragents.reference/run-scripts/shared-actor-list/src/server.ts +65 -0
  411. package/bundles/ragents.reference/run-scripts/shared-actor-list/tests/helpers.ts +26 -0
  412. package/bundles/ragents.reference/run-scripts/shared-actor-list/tests/program.test.ts +42 -0
  413. package/bundles/ragents.reference/run-scripts/word-game/RUN.md +25 -0
  414. package/bundles/ragents.reference/run-scripts/word-game/package.json +11 -0
  415. package/bundles/ragents.reference/run-scripts/word-game/src/client.tsx +27 -0
  416. package/bundles/ragents.reference/run-scripts/word-game/src/contract.ts +23 -0
  417. package/bundles/ragents.reference/run-scripts/word-game/src/server.ts +105 -0
  418. package/bundles/ragents.reference/run-scripts/word-game/src/state.ts +22 -0
  419. package/bundles/ragents.reference/run-scripts/word-game/src/view.tsx +54 -0
  420. package/bundles/ragents.reference/run-scripts/word-game/tests/program.test.ts +252 -0
  421. package/bundles/ragents.reference/server/index.js +16 -0
  422. package/bundles/ragents.reference/server/index.js.map +7 -0
  423. package/bundles/ragents.reference/skills/100-shared-actor-list/SKILL.md +12 -0
  424. package/bundles/ragents.reference/skills/110-all-card-slots/SKILL.md +12 -0
  425. package/bundles/ragents.reference/skills/150-editorial-workbench/SKILL.md +12 -0
  426. package/bundles/ragents.reference/skills/160-learning-companion/SKILL.md +12 -0
  427. package/bundles/ragents.reference/skills/170-photo-collection/SKILL.md +12 -0
  428. package/bundles/ragents.reference/skills/180-decision-workbench/SKILL.md +12 -0
  429. package/bundles/ragents.reference/skills/190-review-queue/SKILL.md +12 -0
  430. package/bundles/ragents.reference/skills/20-circle-of-four/SKILL.md +12 -0
  431. package/bundles/ragents.reference/skills/200-typescript-diagnostics/SKILL.md +12 -0
  432. package/bundles/ragents.reference/skills/210-moderator-handover/SKILL.md +12 -0
  433. package/bundles/ragents.reference/skills/220-actor-approval-list/SKILL.md +12 -0
  434. package/bundles/ragents.reference/skills/230-shared-state-views/SKILL.md +12 -0
  435. package/bundles/ragents.reference/skills/240-live-result-list/SKILL.md +12 -0
  436. package/bundles/ragents.reference/skills/250-balcony-wizard/SKILL.md +12 -0
  437. package/bundles/ragents.reference/skills/30-llm-without-runtime-knowledge/SKILL.md +12 -0
  438. package/bundles/ragents.reference/skills/35-actor-input-fifo/SKILL.md +12 -0
  439. package/bundles/ragents.reference/skills/40-subscription-matrix/SKILL.md +12 -0
  440. package/bundles/ragents.reference/skills/50-subscription-removal/SKILL.md +12 -0
  441. package/bundles/ragents.reference/skills/60-stop-in-the-circle/SKILL.md +12 -0
  442. package/bundles/ragents.reference/skills/65-artifact-least-privilege/SKILL.md +12 -0
  443. package/bundles/ragents.reference/skills/70-headless-counter/SKILL.md +12 -0
  444. package/bundles/ragents.reference/skills/75-lsp-demo/SKILL.md +12 -0
  445. package/bundles/ragents.reference/skills/80-actor-text-analysis/SKILL.md +12 -0
  446. package/bundles/ragents.reference/skills/90-actor-notes/SKILL.md +12 -0
  447. package/bundles/ragents.reference/skills/95-hello-world/SKILL.md +12 -0
  448. package/bundles/ragents.reference/skills/decision-brief/SKILL.md +33 -0
  449. package/bundles/ragents.reference/skills/learning-sprint/SKILL.md +33 -0
  450. package/bundles/ragents.reference/web/classes.json +1 -0
  451. package/bundles/ragents.reference/web/index.js +2 -0
  452. package/bundles/ragents.reference/web/index.js.map +7 -0
  453. package/bundles/ragents.todo/ragents-bundle.json +48 -0
  454. package/bundles/ragents.todo/server/index.js +108 -0
  455. package/bundles/ragents.todo/server/index.js.map +7 -0
  456. package/bundles/ragents.todo/web/classes.json +1 -0
  457. package/bundles/ragents.todo/web/index.js +2 -0
  458. package/bundles/ragents.todo/web/index.js.map +7 -0
  459. package/bundles/ragents.transcript/ragents-bundle.json +34 -0
  460. package/bundles/ragents.transcript/server/index.js +102 -0
  461. package/bundles/ragents.transcript/server/index.js.map +7 -0
  462. package/bundles/ragents.watch/ragents-bundle.json +39 -0
  463. package/bundles/ragents.watch/server/chunks/chunk-FHAM6OML.js +11 -0
  464. package/bundles/ragents.watch/server/chunks/chunk-FHAM6OML.js.map +7 -0
  465. package/bundles/ragents.watch/server/chunks/chunk-RPBX3J4P.js +10 -0
  466. package/bundles/ragents.watch/server/chunks/chunk-RPBX3J4P.js.map +7 -0
  467. package/bundles/ragents.watch/server/exports/contract.js +9 -0
  468. package/bundles/ragents.watch/server/exports/contract.js.map +7 -0
  469. package/bundles/ragents.watch/server/exports/server/contract.js +9 -0
  470. package/bundles/ragents.watch/server/exports/server/contract.js.map +7 -0
  471. package/bundles/ragents.watch/server/index.js +482 -0
  472. package/bundles/ragents.watch/server/index.js.map +7 -0
  473. package/bundles/ragents.workspace/prompt.hbs +7 -0
  474. package/bundles/ragents.workspace/ragents-bundle.json +148 -0
  475. package/bundles/ragents.workspace/server/index.js +1049 -0
  476. package/bundles/ragents.workspace/server/index.js.map +7 -0
  477. package/bundles/ragents.workspace/web/classes.json +1 -0
  478. package/bundles/ragents.workspace/web/index.js +39 -0
  479. package/bundles/ragents.workspace/web/index.js.map +7 -0
  480. package/package.json +4 -15
  481. package/packages/agent/dist/core/agent-session-runtime.d.ts +33 -0
  482. package/packages/agent/dist/core/agent-session-services.d.ts +35 -0
  483. package/packages/agent/dist/core/agent-session.d.ts +234 -0
  484. package/packages/agent/dist/core/agent-settings.d.ts +27 -0
  485. package/packages/agent/dist/core/auth-guidance.d.ts +4 -0
  486. package/packages/agent/dist/core/compaction/compaction.d.ts +116 -0
  487. package/packages/agent/dist/core/compaction/index.d.ts +6 -0
  488. package/packages/agent/dist/core/compaction/utils.d.ts +39 -0
  489. package/packages/agent/dist/core/defaults.d.ts +3 -0
  490. package/packages/agent/dist/core/extensions/index.d.ts +11 -0
  491. package/packages/agent/dist/core/extensions/loader.d.ts +12 -0
  492. package/packages/agent/dist/core/extensions/runner.d.ts +39 -0
  493. package/packages/agent/dist/core/extensions/types.d.ts +156 -0
  494. package/packages/agent/dist/core/extensions/wrapper.d.ts +12 -0
  495. package/packages/agent/dist/core/messages.d.ts +37 -0
  496. package/packages/agent/dist/core/model-runtime.d.ts +32 -0
  497. package/packages/agent/dist/core/provider-composer.d.ts +25 -0
  498. package/packages/agent/dist/core/resource-loader.d.ts +39 -0
  499. package/packages/agent/dist/core/sdk.d.ts +38 -0
  500. package/packages/agent/dist/core/session-manager.d.ts +189 -0
  501. package/packages/agent/dist/core/skills.d.ts +20 -0
  502. package/packages/agent/dist/core/source-info.d.ts +16 -0
  503. package/packages/agent/dist/core/system-prompt.d.ts +21 -0
  504. package/packages/agent/dist/core/tools/bash.d.ts +63 -0
  505. package/packages/agent/dist/core/tools/edit-diff.d.ts +98 -0
  506. package/packages/agent/dist/core/tools/edit.d.ts +41 -0
  507. package/packages/agent/dist/core/tools/file-mutation-queue.d.ts +6 -0
  508. package/packages/agent/dist/core/tools/index.d.ts +5 -0
  509. package/packages/agent/dist/core/tools/output-accumulator.d.ts +58 -0
  510. package/packages/agent/dist/core/tools/path-utils.d.ts +8 -0
  511. package/packages/agent/dist/core/tools/read.d.ts +33 -0
  512. package/packages/agent/dist/core/tools/truncate.d.ts +61 -0
  513. package/packages/agent/dist/core/tools/write.d.ts +23 -0
  514. package/packages/agent/dist/index.d.ts +13 -0
  515. package/packages/agent/dist/loop/agent-loop.d.ts +13 -0
  516. package/packages/agent/dist/loop/agent.d.ts +103 -0
  517. package/packages/agent/dist/loop/index.d.ts +5 -0
  518. package/packages/agent/dist/loop/types.d.ts +333 -0
  519. package/packages/agent/dist/loop/uuid.d.ts +2 -0
  520. package/packages/agent/dist/utils/child-process.d.ts +17 -0
  521. package/packages/agent/dist/utils/exif-orientation.d.ts +5 -0
  522. package/packages/agent/dist/utils/frontmatter.d.ts +8 -0
  523. package/packages/agent/dist/utils/image-convert.d.ts +2 -0
  524. package/packages/agent/dist/utils/image-process.d.ts +18 -0
  525. package/packages/agent/dist/utils/image-resize-core.d.ts +30 -0
  526. package/packages/agent/dist/utils/image-resize-worker.d.ts +2 -0
  527. package/packages/agent/dist/utils/image-resize.d.ts +16 -0
  528. package/packages/agent/dist/utils/mime.d.ts +3 -0
  529. package/packages/agent/dist/utils/paths.d.ts +15 -0
  530. package/packages/agent/dist/utils/photon.d.ts +21 -0
  531. package/packages/agent/dist/utils/shell.d.ts +17 -0
  532. package/packages/agent/dist/utils/sleep.d.ts +5 -0
  533. package/packages/agent/package.json +3 -32
  534. package/packages/agent/src/core/agent-session-runtime.ts +15 -469
  535. package/packages/agent/src/core/agent-session-services.ts +17 -167
  536. package/packages/agent/src/core/agent-session.ts +154 -2403
  537. package/packages/agent/src/core/agent-settings.ts +20 -0
  538. package/packages/agent/src/core/auth-guidance.ts +0 -4
  539. package/packages/agent/src/core/compaction/compaction.ts +4 -33
  540. package/packages/agent/src/core/compaction/index.ts +0 -1
  541. package/packages/agent/src/core/compaction/utils.ts +2 -2
  542. package/packages/agent/src/core/defaults.ts +1 -1
  543. package/packages/agent/src/core/extensions/index.ts +6 -117
  544. package/packages/agent/src/core/extensions/loader.ts +21 -605
  545. package/packages/agent/src/core/extensions/runner.ts +48 -969
  546. package/packages/agent/src/core/extensions/types.ts +35 -1298
  547. package/packages/agent/src/core/extensions/wrapper.ts +13 -34
  548. package/packages/agent/src/core/messages.ts +5 -109
  549. package/packages/agent/src/core/model-runtime.ts +109 -467
  550. package/packages/agent/src/core/provider-composer.ts +21 -451
  551. package/packages/agent/src/core/resource-loader.ts +18 -822
  552. package/packages/agent/src/core/sdk.ts +46 -281
  553. package/packages/agent/src/core/session-manager.ts +11 -891
  554. package/packages/agent/src/core/skills.ts +8 -440
  555. package/packages/agent/src/core/source-info.ts +0 -12
  556. package/packages/agent/src/core/system-prompt.ts +2 -41
  557. package/packages/agent/src/core/tools/bash.ts +20 -32
  558. package/packages/agent/src/core/tools/edit-diff.ts +0 -60
  559. package/packages/agent/src/core/tools/edit.ts +2 -18
  560. package/packages/agent/src/core/tools/index.ts +4 -130
  561. package/packages/agent/src/core/tools/output-accumulator.ts +33 -5
  562. package/packages/agent/src/core/tools/path-utils.ts +2 -49
  563. package/packages/agent/src/core/tools/read.ts +4 -12
  564. package/packages/agent/src/core/tools/truncate.ts +0 -15
  565. package/packages/agent/src/core/tools/write.ts +1 -8
  566. package/packages/agent/src/index.ts +11 -272
  567. package/packages/{agent-core/src → agent/src/loop}/agent-loop.ts +127 -273
  568. package/packages/{agent-core/src → agent/src/loop}/agent.ts +12 -164
  569. package/packages/{agent-core/src → agent/src/loop}/types.ts +6 -105
  570. package/packages/agent/src/utils/child-process.ts +0 -13
  571. package/packages/agent/src/utils/image-convert.ts +0 -25
  572. package/packages/agent/src/utils/paths.ts +1 -71
  573. package/packages/agent/src/utils/shell.ts +13 -156
  574. package/packages/ai/dist/api/ai-sdk-messages.d.ts +9 -0
  575. package/packages/ai/dist/api/ai-sdk-transport.d.ts +13 -0
  576. package/packages/ai/dist/api/ai-sdk.d.ts +13 -0
  577. package/packages/ai/dist/api/ai-sdk.lazy.d.ts +3 -0
  578. package/packages/ai/dist/api/lazy.d.ts +15 -0
  579. package/packages/ai/dist/api/simple-options.d.ts +4 -0
  580. package/packages/ai/dist/api/transform-messages.d.ts +8 -0
  581. package/packages/ai/dist/api-registry.d.ts +25 -0
  582. package/packages/ai/dist/auth/context.d.ts +4 -0
  583. package/packages/ai/dist/auth/helpers.d.ts +4 -0
  584. package/packages/ai/dist/auth/resolve.d.ts +19 -0
  585. package/packages/ai/dist/auth/types.d.ts +51 -0
  586. package/packages/ai/dist/env-api-keys.d.ts +8 -0
  587. package/packages/ai/dist/index.d.ts +19 -0
  588. package/packages/ai/dist/models.d.ts +71 -0
  589. package/packages/ai/dist/models.generated.d.ts +8021 -0
  590. package/packages/ai/dist/providers/all.d.ts +15 -0
  591. package/packages/ai/dist/providers/faux.d.ts +97 -0
  592. package/packages/ai/dist/providers/openrouter.d.ts +3 -0
  593. package/packages/ai/dist/providers/openrouter.models.d.ts +8019 -0
  594. package/packages/ai/dist/types.d.ts +541 -0
  595. package/packages/ai/dist/utils/diagnostics.d.ts +13 -0
  596. package/packages/ai/dist/utils/error-body.d.ts +25 -0
  597. package/packages/ai/dist/utils/estimate.d.ts +17 -0
  598. package/packages/ai/dist/utils/event-stream.d.ts +21 -0
  599. package/packages/ai/dist/utils/headers.d.ts +2 -0
  600. package/packages/ai/dist/utils/json-parse.d.ts +16 -0
  601. package/packages/ai/dist/utils/overflow.d.ts +54 -0
  602. package/packages/ai/dist/utils/provider-env.d.ts +7 -0
  603. package/packages/ai/dist/utils/retry.d.ts +12 -0
  604. package/packages/ai/dist/utils/sanitize-unicode.d.ts +22 -0
  605. package/packages/ai/dist/utils/typebox-helpers.d.ts +17 -0
  606. package/packages/ai/dist/utils/validation.d.ts +10 -0
  607. package/packages/ai/package.json +2 -6
  608. package/packages/ai/src/api/ai-sdk-transport.ts +2 -2
  609. package/packages/ai/src/api/simple-options.ts +0 -34
  610. package/packages/ai/src/api-registry.ts +1 -12
  611. package/packages/ai/src/auth/context.ts +1 -30
  612. package/packages/ai/src/auth/helpers.ts +3 -34
  613. package/packages/ai/src/auth/resolve.ts +10 -108
  614. package/packages/ai/src/auth/types.ts +9 -176
  615. package/packages/ai/src/index.ts +1 -13
  616. package/packages/ai/src/models.ts +41 -407
  617. package/packages/ai/src/providers/all.ts +3 -31
  618. package/packages/ai/src/providers/openrouter.models.ts +14 -0
  619. package/packages/ai/src/types.ts +0 -104
  620. package/packages/ai/src/utils/diagnostics.ts +0 -32
  621. package/packages/ai/src/utils/headers.ts +0 -11
  622. package/packages/ai/src/utils/overflow.ts +0 -7
  623. package/packages/ai/src/utils/validation.ts +0 -15
  624. package/packages/ragents/package.json +3 -6
  625. package/packages/ragents/src/access.ts +2 -1
  626. package/packages/ragents/src/agents/actor-input.ts +14 -18
  627. package/packages/ragents/src/agents/catalog.ts +3 -3
  628. package/packages/ragents/src/agents/plugins.ts +0 -4
  629. package/packages/ragents/src/agents/scheduler.ts +232 -78
  630. package/packages/ragents/src/agents/schemas.ts +1 -36
  631. package/packages/ragents/src/agents/tool-orientation.ts +1 -1
  632. package/packages/ragents/src/agents/tools.ts +72 -73
  633. package/packages/ragents/src/agents/toolset.ts +5 -5
  634. package/packages/ragents/src/agents/turn.ts +2 -14
  635. package/packages/ragents/src/agents/workspaces.ts +18 -0
  636. package/packages/ragents/src/domain/actor-reference.ts +22 -0
  637. package/packages/ragents/src/domain/driver.ts +0 -9
  638. package/packages/ragents/src/domain/event-semantics.ts +62 -74
  639. package/packages/ragents/src/domain/event-validation.ts +22 -21
  640. package/packages/ragents/src/domain/events.ts +19 -7
  641. package/packages/ragents/src/domain/json.ts +2 -0
  642. package/packages/ragents/src/domain/model.ts +40 -18
  643. package/packages/ragents/src/domain/projection.ts +43 -15
  644. package/packages/ragents/src/domain/schema-errors.ts +3 -3
  645. package/packages/ragents/src/drivers/agent-hooks.ts +40 -0
  646. package/packages/ragents/src/drivers/agent-runtime.ts +118 -186
  647. package/packages/ragents/src/drivers/agent.ts +5 -20
  648. package/packages/ragents/src/drivers/attachments.ts +4 -24
  649. package/packages/ragents/src/drivers/skill-preload.ts +4 -16
  650. package/packages/ragents/src/drivers/types.ts +20 -3
  651. package/packages/ragents/src/http/contracts.ts +16 -3
  652. package/packages/ragents/src/http/methods.ts +32 -33
  653. package/packages/ragents/src/index.ts +5 -15
  654. package/packages/ragents/src/plugin-host.ts +151 -105
  655. package/packages/ragents/src/plugin-types.ts +86 -23
  656. package/packages/ragents/src/rpc/peer.ts +6 -0
  657. package/packages/ragents/src/runtime/decisions/actions.ts +40 -37
  658. package/packages/ragents/src/runtime/decisions/actors.ts +90 -51
  659. package/packages/ragents/src/runtime/decisions/artifacts.ts +2 -2
  660. package/packages/ragents/src/runtime/decisions/inputs.ts +3 -3
  661. package/packages/ragents/src/runtime/decisions/subscriptions.ts +9 -7
  662. package/packages/ragents/src/runtime/decisions/turns.ts +37 -4
  663. package/packages/ragents/src/runtime/guards.ts +12 -21
  664. package/packages/ragents/src/runtime/journal-storage.ts +4 -2
  665. package/packages/ragents/src/runtime/journal.ts +1 -1
  666. package/packages/ragents/src/runtime/orchestration.ts +31 -14
  667. package/packages/ragents/src/runtime/serial-queue.ts +24 -0
  668. package/packages/ragents/src/runtime/stop.ts +19 -44
  669. package/packages/ragents/src/script/mediators.ts +4 -5
  670. package/packages/ragents/src/typescript/index.ts +2 -0
  671. package/packages/ragents/src/typescript/run-context.ts +10 -8
  672. package/packages/ragents/src/typescript/snippet.ts +7 -6
  673. package/packages/workspace-executor/package.json +2 -2
  674. package/packages/workspace-executor/src/bash-launch.ts +45 -0
  675. package/packages/workspace-executor/src/browser/contract.ts +71 -0
  676. package/packages/workspace-executor/src/browser/module.ts +74 -0
  677. package/packages/workspace-executor/src/browser/pages.ts +298 -0
  678. package/packages/workspace-executor/src/browser/playwright.ts +52 -0
  679. package/packages/workspace-executor/src/commands.ts +170 -0
  680. package/packages/workspace-executor/src/context.ts +34 -6
  681. package/packages/workspace-executor/src/errors.ts +12 -0
  682. package/packages/workspace-executor/src/executor.ts +62 -104
  683. package/packages/workspace-executor/src/files.ts +287 -0
  684. package/packages/workspace-executor/src/index.ts +82 -18
  685. package/packages/workspace-executor/src/language-server/adapters/roslyn.ts +1 -0
  686. package/packages/workspace-executor/src/language-server/contract.ts +14 -0
  687. package/packages/workspace-executor/src/language-server/host.ts +82 -26
  688. package/packages/workspace-executor/src/language-server/module.ts +107 -0
  689. package/packages/workspace-executor/src/language-server/workspace-solutions.ts +90 -0
  690. package/packages/workspace-executor/src/managed-process.ts +1 -1
  691. package/packages/workspace-executor/src/module.ts +35 -0
  692. package/packages/workspace-executor/src/modules.ts +25 -0
  693. package/packages/workspace-executor/src/paths.ts +57 -5
  694. package/packages/workspace-executor/src/process-sandbox.ts +16 -0
  695. package/packages/workspace-executor/src/processes/module.ts +48 -0
  696. package/{plugins/ragents.processes/server → packages/workspace-executor/src/processes}/process-table.ts +80 -57
  697. package/packages/workspace-executor/src/processes/scanner.ts +106 -0
  698. package/{plugins/ragents.processes/server → packages/workspace-executor/src/processes}/snapshot.ts +23 -11
  699. package/{plugins/ragents.processes/server → packages/workspace-executor/src/processes}/terminator.ts +19 -20
  700. package/packages/workspace-executor/src/run-folders.ts +33 -0
  701. package/packages/workspace-executor/src/safe-environment.ts +14 -0
  702. package/packages/workspace-executor/src/sandbox-tools.ts +206 -36
  703. package/packages/workspace-executor/src/shell-platform.ts +2 -2
  704. package/plugins/package.json +1 -1
  705. package/plugins/ragents.activity/ragents-plugin.json +3 -0
  706. package/plugins/ragents.activity/server/index.ts +2 -2
  707. package/plugins/ragents.activity/web/ActivityHeader.tsx +2 -2
  708. package/plugins/ragents.activity/web/activity.ts +1 -1
  709. package/plugins/ragents.activity/web/index.tsx +1 -1
  710. package/plugins/ragents.actor-programs/prompt.hbs +8 -7
  711. package/plugins/ragents.actor-programs/ragents-plugin.json +3 -0
  712. package/plugins/ragents.actor-programs/server/agent-tools.ts +3 -3
  713. package/{apps/server/src/plugin-support/actor-programs → plugins/ragents.actor-programs/server}/capability-resolver.ts +1 -16
  714. package/plugins/ragents.actor-programs/server/controls-template.ts +5 -18
  715. package/plugins/ragents.actor-programs/server/controls-tool.ts +8 -11
  716. package/plugins/ragents.actor-programs/server/index.ts +10 -10
  717. package/{apps/server/src/plugin-support/actor-programs → plugins/ragents.actor-programs/server}/limits.ts +4 -4
  718. package/plugins/ragents.actor-programs/server/methods.ts +2 -2
  719. package/{apps/server/src/plugin-support/actor-programs → plugins/ragents.actor-programs/server}/operations.ts +2 -4
  720. package/plugins/ragents.actor-programs/server/project-diagnostics.ts +65 -70
  721. package/plugins/ragents.actor-programs/server/prompts.ts +4 -4
  722. package/plugins/ragents.actor-programs/server/routes.ts +14 -8
  723. package/plugins/ragents.actor-programs/server/runtime.ts +132 -55
  724. package/plugins/ragents.actor-programs/server/templates.ts +35 -80
  725. package/plugins/ragents.actor-programs/server/test-report.ts +106 -0
  726. package/plugins/ragents.actor-programs/server/tool-contributor.ts +4 -4
  727. package/plugins/ragents.actor-programs/summary.hbs +1 -1
  728. package/plugins/ragents.actor-programs/web/ActorViewFrame.tsx +15 -10
  729. package/plugins/ragents.actor-programs/web/AppsPanel.tsx +47 -30
  730. package/plugins/ragents.actor-programs/web/EmbeddedApps.tsx +15 -17
  731. package/plugins/ragents.actor-programs/web/FullscreenHost.tsx +3 -3
  732. package/plugins/ragents.actor-programs/web/FunctionForm.tsx +3 -3
  733. package/plugins/ragents.actor-programs/web/ProgramSource.tsx +12 -3
  734. package/plugins/ragents.actor-programs/web/api.ts +5 -5
  735. package/plugins/ragents.actor-programs/web/bridge.ts +2 -3
  736. package/plugins/ragents.actor-programs/web/chat-state.ts +9 -8
  737. package/plugins/ragents.actor-programs/web/index.tsx +7 -17
  738. package/plugins/ragents.actor-programs/web/program-state.ts +3 -3
  739. package/plugins/ragents.actor-programs/web/state-revision.ts +2 -2
  740. package/plugins/ragents.ask/ask-payload.ts +25 -0
  741. package/plugins/ragents.ask/contract.ts +2 -2
  742. package/plugins/ragents.ask/ragents-plugin.json +7 -0
  743. package/plugins/ragents.ask/server/answer-method.ts +1 -1
  744. package/plugins/ragents.ask/server/ask-service.ts +43 -19
  745. package/plugins/ragents.ask/server/ask-tool.ts +2 -2
  746. package/plugins/ragents.ask/server/contract.ts +9 -1
  747. package/plugins/ragents.ask/server/index.ts +8 -10
  748. package/plugins/ragents.ask/server/tool-contributor.ts +3 -3
  749. package/plugins/ragents.ask/web/AskActionView.tsx +36 -0
  750. package/{apps/web/src/chat → plugins/ragents.ask/web}/QuestionCard.tsx +7 -5
  751. package/plugins/ragents.ask/web/QuestionSection.tsx +22 -21
  752. package/plugins/ragents.ask/web/api.ts +1 -1
  753. package/plugins/ragents.ask/web/index.tsx +11 -8
  754. package/plugins/ragents.browser/provision.ts +9 -8
  755. package/plugins/ragents.browser/ragents-plugin.json +6 -0
  756. package/plugins/ragents.browser/server/browser.ts +165 -286
  757. package/plugins/ragents.browser/server/contract.ts +8 -19
  758. package/plugins/ragents.browser/server/index.ts +8 -7
  759. package/plugins/ragents.browser/server/tools.ts +29 -37
  760. package/plugins/ragents.browser/skills/browser-testing/SKILL.md +3 -1
  761. package/plugins/ragents.documents/contract.ts +4 -2
  762. package/plugins/ragents.documents/ragents-plugin.json +6 -0
  763. package/plugins/ragents.documents/server/config.ts +1 -1
  764. package/plugins/ragents.documents/server/document-write-tool.ts +2 -2
  765. package/plugins/ragents.documents/server/files-route.ts +2 -3
  766. package/plugins/ragents.documents/server/index.ts +10 -11
  767. package/plugins/ragents.documents/server/show-document-tool.ts +2 -2
  768. package/plugins/ragents.documents/server/store.ts +3 -3
  769. package/plugins/ragents.documents/server/tool-contributor.ts +3 -3
  770. package/plugins/ragents.documents/web/DocumentViewer.tsx +5 -6
  771. package/plugins/ragents.documents/web/api.ts +1 -1
  772. package/plugins/ragents.documents/web/index.tsx +4 -4
  773. package/plugins/ragents.lsp-fsharp/provision.ts +2 -2
  774. package/plugins/ragents.lsp-fsharp/ragents-plugin.json +3 -0
  775. package/plugins/ragents.lsp-fsharp/server/index.ts +3 -3
  776. package/plugins/ragents.lsp-fsharp/web/index.tsx +1 -1
  777. package/plugins/ragents.lsp-roslyn/provision.ts +2 -2
  778. package/plugins/ragents.lsp-roslyn/ragents-plugin.json +3 -0
  779. package/plugins/ragents.lsp-roslyn/server/index.ts +47 -8
  780. package/plugins/ragents.lsp-roslyn/server/solution-on-start.ts +145 -0
  781. package/plugins/ragents.lsp-roslyn/web/index.tsx +1 -1
  782. package/plugins/ragents.lsp-typescript/ragents-plugin.json +3 -0
  783. package/plugins/ragents.lsp-typescript/server/index.ts +3 -3
  784. package/plugins/ragents.lsp-typescript/web/index.tsx +1 -1
  785. package/plugins/ragents.model-relay/ragents-plugin.json +3 -0
  786. package/plugins/ragents.model-relay/server/config.ts +5 -31
  787. package/plugins/ragents.model-relay/server/index.ts +5 -6
  788. package/plugins/ragents.model-relay/server/relay.ts +8 -9
  789. package/plugins/ragents.orchestration/contract.ts +13 -14
  790. package/plugins/ragents.orchestration/orchestration.hbs +4 -3
  791. package/plugins/ragents.orchestration/ragents-plugin.json +6 -0
  792. package/plugins/ragents.orchestration/server/index.ts +13 -16
  793. package/plugins/ragents.orchestration/server/run-stop-tool.ts +4 -4
  794. package/plugins/ragents.orchestration/server/{canvas-tool.ts → surface-tool.ts} +42 -43
  795. package/plugins/ragents.orchestration/surface.hbs +34 -0
  796. package/plugins/ragents.orchestration/tiled-layout.ts +16 -16
  797. package/plugins/ragents.orchestration/web/ActorChat.tsx +16 -14
  798. package/plugins/ragents.orchestration/web/ActorChatControls.tsx +23 -26
  799. package/plugins/ragents.orchestration/web/ActorChatPreview.tsx +5 -6
  800. package/plugins/ragents.orchestration/web/ActorPopout.tsx +7 -5
  801. package/plugins/ragents.orchestration/web/ActorShortcut.tsx +16 -16
  802. package/plugins/ragents.orchestration/web/{ActorCanvasControls.tsx → ActorSurfaceControls.tsx} +23 -28
  803. package/plugins/ragents.orchestration/web/ActorTile.tsx +2 -2
  804. package/plugins/ragents.orchestration/web/Center.tsx +47 -55
  805. package/plugins/ragents.orchestration/web/DocumentsSection.tsx +4 -4
  806. package/plugins/ragents.orchestration/web/ExecutionsPanel.tsx +7 -7
  807. package/plugins/ragents.orchestration/web/FlowInspector.tsx +24 -42
  808. package/plugins/ragents.orchestration/web/JournalStatus.tsx +8 -8
  809. package/plugins/ragents.orchestration/web/MaterialBody.tsx +5 -5
  810. package/plugins/ragents.orchestration/web/StopRunButton.tsx +6 -6
  811. package/plugins/ragents.orchestration/web/SurfaceStartup.tsx +8 -0
  812. package/plugins/ragents.orchestration/web/{CanvasTiles.tsx → SurfaceTiles.tsx} +18 -18
  813. package/plugins/ragents.orchestration/web/{TiledCanvas.tsx → TiledSurface.tsx} +22 -22
  814. package/plugins/ragents.orchestration/web/actor-header-settings.ts +2 -2
  815. package/plugins/ragents.orchestration/web/api.ts +4 -10
  816. package/plugins/ragents.orchestration/web/constants.ts +0 -1
  817. package/plugins/ragents.orchestration/web/executions.ts +3 -3
  818. package/plugins/ragents.orchestration/web/index.tsx +19 -124
  819. package/plugins/ragents.orchestration/web/program-slot.ts +14 -0
  820. package/plugins/ragents.orchestration/web/run-panel/AddresseeControl.tsx +95 -0
  821. package/plugins/ragents.orchestration/web/run-panel/AddresseeTree.tsx +109 -0
  822. package/plugins/ragents.orchestration/web/{column/RunColumn.tsx → run-panel/RunPanel.tsx} +211 -83
  823. package/plugins/ragents.orchestration/web/{column/ColumnSettings.tsx → run-panel/RunPanelSettings.tsx} +13 -13
  824. package/plugins/ragents.orchestration/web/run-panel/addressee-tree.ts +165 -0
  825. package/plugins/ragents.orchestration/web/{column/column-actors.ts → run-panel/run-panel-actors.ts} +14 -13
  826. package/plugins/ragents.orchestration/web/run-panel/run-panel-settings.ts +47 -0
  827. package/plugins/ragents.orchestration/web/run-panel/run-panel-startup.ts +30 -0
  828. package/plugins/ragents.orchestration/web/run-panel/run-panel-state.ts +71 -0
  829. package/plugins/ragents.orchestration/web/{column → run-panel}/sheet-status.ts +4 -4
  830. package/plugins/ragents.orchestration/web/{canvas-stage.ts → surface-entities.ts} +2 -2
  831. package/plugins/ragents.orchestration/web/{canvas-startup.ts → surface-startup.ts} +7 -10
  832. package/plugins/ragents.orchestration/web/surface-view-settings.ts +42 -0
  833. package/plugins/ragents.orchestration/web/tile-docking.ts +14 -14
  834. package/plugins/ragents.orchestration/web/tiled-view-settings.ts +26 -26
  835. package/plugins/ragents.overseer/contract.ts +20 -14
  836. package/plugins/ragents.overseer/ragents-plugin.json +3 -0
  837. package/plugins/ragents.overseer/server/api.ts +34 -23
  838. package/plugins/ragents.overseer/server/coordinator-prompt.ts +3 -3
  839. package/plugins/ragents.overseer/server/coordinator.ts +19 -0
  840. package/plugins/ragents.overseer/server/index.ts +39 -27
  841. package/plugins/ragents.overseer/server/orientation.ts +4 -5
  842. package/plugins/ragents.overseer/server/quick-answer.ts +5 -4
  843. package/plugins/ragents.overseer/server/reset-method.ts +4 -3
  844. package/plugins/ragents.overseer/server/run-directory.ts +5 -5
  845. package/plugins/ragents.overseer/server/settings-method.ts +1 -1
  846. package/plugins/ragents.overseer/server/settings.ts +6 -6
  847. package/plugins/ragents.overseer/server/user-location.ts +20 -19
  848. package/plugins/ragents.overseer/web/ModelSettings.tsx +4 -4
  849. package/plugins/ragents.overseer/web/chat-display.ts +1 -1
  850. package/plugins/ragents.overseer/web/index.tsx +51 -26
  851. package/plugins/ragents.overseer/web/model-settings.ts +1 -1
  852. package/plugins/ragents.overseer/web/quick-answers.ts +2 -2
  853. package/plugins/ragents.processes/contract.ts +5 -5
  854. package/plugins/ragents.processes/ragents-plugin.json +3 -0
  855. package/plugins/ragents.processes/server/index.ts +13 -19
  856. package/plugins/ragents.processes/server/methods.ts +18 -20
  857. package/plugins/ragents.processes/server/observer.ts +64 -104
  858. package/plugins/ragents.processes/server/run-processes.ts +24 -0
  859. package/plugins/ragents.processes/web/ProcessHeader.tsx +13 -16
  860. package/plugins/ragents.processes/web/index.tsx +2 -1
  861. package/plugins/ragents.processes/web/processes.ts +1 -1
  862. package/plugins/ragents.product/ragents-plugin.json +3 -0
  863. package/plugins/ragents.product/server/config.ts +12 -13
  864. package/plugins/ragents.product/server/index.ts +15 -16
  865. package/plugins/ragents.product/server/runtime.ts +2 -2
  866. package/plugins/ragents.product/web/index.tsx +3 -3
  867. package/plugins/ragents.profile-distribution/contract.ts +6 -9
  868. package/plugins/ragents.profile-distribution/ragents-plugin.json +3 -0
  869. package/plugins/ragents.profile-distribution/server/archive.ts +26 -51
  870. package/plugins/ragents.profile-distribution/server/config.ts +2 -2
  871. package/plugins/ragents.profile-distribution/server/index.ts +9 -16
  872. package/plugins/ragents.reference/examples.ts +1 -1
  873. package/plugins/ragents.reference/ragents-plugin.json +3 -0
  874. package/plugins/ragents.reference/run-scripts/balcony-wizard/RUN.md +2 -2
  875. package/plugins/ragents.reference/run-scripts/balcony-wizard/actors/balcony-app/src/client.tsx +1 -1
  876. package/plugins/ragents.reference/run-scripts/balcony-wizard/src/server.ts +1 -1
  877. package/plugins/ragents.reference/run-scripts/balcony-wizard/tests/program.test.ts +4 -4
  878. package/plugins/ragents.reference/run-scripts/conversation-circle/RUN.md +1 -1
  879. package/plugins/ragents.reference/run-scripts/conversation-circle/src/server.ts +1 -1
  880. package/plugins/ragents.reference/run-scripts/conversation-circle/tests/helpers.ts +1 -1
  881. package/plugins/ragents.reference/run-scripts/learning-afternoon/RUN.md +2 -2
  882. package/plugins/ragents.reference/run-scripts/learning-afternoon/src/client.tsx +1 -1
  883. package/plugins/ragents.reference/run-scripts/learning-afternoon/src/server.ts +1 -1
  884. package/plugins/ragents.reference/run-scripts/learning-afternoon/src/state.ts +2 -2
  885. package/plugins/ragents.reference/run-scripts/learning-afternoon/src/view.tsx +11 -11
  886. package/plugins/ragents.reference/run-scripts/learning-afternoon/src/workflow.ts +15 -15
  887. package/plugins/ragents.reference/run-scripts/learning-afternoon/tests/program.test.ts +3 -8
  888. package/plugins/ragents.reference/run-scripts/moderated-round/src/server.ts +1 -1
  889. package/plugins/ragents.reference/run-scripts/moderated-round/tests/helpers.ts +1 -1
  890. package/plugins/ragents.reference/run-scripts/moderated-round/tests/program.test.ts +2 -2
  891. package/plugins/ragents.reference/run-scripts/shared-actor-list/actors/shared-list/src/client.tsx +6 -6
  892. package/plugins/ragents.reference/run-scripts/shared-actor-list/src/server.ts +3 -3
  893. package/plugins/ragents.reference/run-scripts/shared-actor-list/tests/helpers.ts +1 -1
  894. package/plugins/ragents.reference/run-scripts/word-game/RUN.md +1 -1
  895. package/plugins/ragents.reference/run-scripts/word-game/src/client.tsx +1 -1
  896. package/plugins/ragents.reference/run-scripts/word-game/src/server.ts +1 -2
  897. package/plugins/ragents.reference/run-scripts/word-game/src/state.ts +6 -6
  898. package/plugins/ragents.reference/run-scripts/word-game/src/view.tsx +14 -14
  899. package/plugins/ragents.reference/run-scripts/word-game/tests/program.test.ts +4 -5
  900. package/plugins/ragents.reference/server/index.ts +2 -2
  901. package/plugins/ragents.reference/skills/160-learning-companion/SKILL.md +1 -1
  902. package/plugins/ragents.reference/skills/240-live-result-list/SKILL.md +1 -1
  903. package/plugins/ragents.reference/skills/250-balcony-wizard/SKILL.md +1 -1
  904. package/plugins/ragents.reference/skills/90-actor-notes/SKILL.md +1 -1
  905. package/plugins/ragents.reference/skills/95-hello-world/SKILL.md +2 -2
  906. package/plugins/ragents.reference/skills/decision-brief/SKILL.md +2 -2
  907. package/plugins/ragents.reference/walkthroughs.ts +19 -19
  908. package/plugins/ragents.reference/web/StartGuides.tsx +2 -2
  909. package/plugins/ragents.reference/web/index.tsx +1 -1
  910. package/plugins/ragents.todo/ragents-plugin.json +3 -0
  911. package/plugins/ragents.todo/server/index.ts +2 -2
  912. package/plugins/ragents.todo/server/todo-tool.ts +4 -5
  913. package/plugins/ragents.todo/server/tool-contributor.ts +2 -2
  914. package/plugins/ragents.todo/web/TodoSection.tsx +3 -3
  915. package/plugins/ragents.todo/web/index.ts +1 -1
  916. package/plugins/ragents.transcript/ragents-plugin.json +3 -0
  917. package/plugins/ragents.transcript/server/index.ts +4 -4
  918. package/plugins/ragents.transcript/server/transcript.ts +2 -3
  919. package/plugins/ragents.watch/ragents-plugin.json +6 -0
  920. package/plugins/ragents.watch/server/condition.ts +2 -2
  921. package/plugins/ragents.watch/server/contract.ts +1 -1
  922. package/plugins/ragents.watch/server/functions.ts +3 -3
  923. package/plugins/ragents.watch/server/index.ts +3 -3
  924. package/plugins/ragents.watch/server/observation.ts +6 -6
  925. package/plugins/ragents.watch/server/service.ts +5 -5
  926. package/plugins/ragents.workspace/client/workspace-client.ts +129 -58
  927. package/plugins/ragents.workspace/contract.ts +98 -35
  928. package/plugins/ragents.workspace/prompt.hbs +1 -8
  929. package/plugins/ragents.workspace/ragents-plugin.json +3 -0
  930. package/plugins/ragents.workspace/server/binding.ts +122 -39
  931. package/plugins/ragents.workspace/server/browse-route.ts +96 -103
  932. package/plugins/ragents.workspace/server/clients.ts +236 -68
  933. package/plugins/ragents.workspace/server/config.ts +30 -0
  934. package/plugins/ragents.workspace/server/index.ts +61 -26
  935. package/plugins/ragents.workspace/server/runtime.ts +271 -46
  936. package/{apps/server/src/plugin-support → plugins/ragents.workspace/server}/shell-platform.ts +3 -5
  937. package/{apps/server/src/plugin-support → plugins/ragents.workspace/server}/workspace-tool-naming.ts +7 -1
  938. package/plugins/ragents.workspace/web/FileBrowser.tsx +11 -8
  939. package/plugins/ragents.workspace/web/WorkspaceBinding.tsx +115 -61
  940. package/plugins/ragents.workspace/web/api.ts +1 -1
  941. package/plugins/ragents.workspace/web/index.tsx +1 -1
  942. package/ragents.config.core.ts +2 -7
  943. package/ragents.config.showcase.ts +2 -5
  944. package/scripts/agent/agent-cli.ts +265 -107
  945. package/scripts/agent/journal.ts +3 -1
  946. package/scripts/agent/turn-control.ts +19 -0
  947. package/scripts/package/build-package.ts +68 -13
  948. package/scripts/package/ragents.mjs +4 -2
  949. package/scripts/plugin/build-builtin-plugins.ts +52 -0
  950. package/scripts/plugin/plugin-cli.ts +99 -0
  951. package/scripts/provision/run-provision.ts +20 -18
  952. package/scripts/remote/connect.ts +75 -53
  953. package/scripts/remote/start.ts +2 -3
  954. package/scripts/workspace-client/run-workspace-client.ts +15 -9
  955. package/apps/server/agent-home/settings.json +0 -3
  956. package/apps/server/src/chat-attachments.ts +0 -52
  957. package/apps/server/src/chat-events.ts +0 -185
  958. package/apps/server/src/plugin-support/asset-path.ts +0 -4
  959. package/apps/server/src/profile/plugin-list.ts +0 -19
  960. package/apps/server/src/web-build.ts +0 -82
  961. package/apps/web/column.html +0 -12
  962. package/apps/web/index.html +0 -12
  963. package/apps/web/src/StartSurface.tsx +0 -161
  964. package/apps/web/src/chat/ChatInputToolbar.tsx +0 -488
  965. package/apps/web/src/chat/ChatMessages.tsx +0 -666
  966. package/apps/web/src/chat/ChatPanel.tsx +0 -61
  967. package/apps/web/src/chat/DetailModeSwitch.tsx +0 -58
  968. package/apps/web/src/chat/Markdown.tsx +0 -104
  969. package/apps/web/src/chat/StepPopover.tsx +0 -82
  970. package/apps/web/src/chat/WorkingScenes.tsx +0 -235
  971. package/apps/web/src/chat/attachments.ts +0 -53
  972. package/apps/web/src/chat/chat-scroll.ts +0 -41
  973. package/apps/web/src/chat/texts.ts +0 -61
  974. package/apps/web/src/chat/types.ts +0 -26
  975. package/apps/web/src/column/ColumnApp.tsx +0 -234
  976. package/apps/web/src/column/column-location.ts +0 -30
  977. package/apps/web/src/column/host-contract.ts +0 -93
  978. package/apps/web/src/panel/OverviewPage.tsx +0 -215
  979. package/apps/web/src/panel/SettingsPage.tsx +0 -98
  980. package/apps/web/src/panel/target-state.ts +0 -78
  981. package/apps/web/src/plugin-discovery.ts +0 -5
  982. package/apps/web/src/virtual-plugins.d.ts +0 -3
  983. package/apps/web/vite.config.ts +0 -140
  984. package/packages/agent/src/config.ts +0 -161
  985. package/packages/agent/src/core/auth-storage.ts +0 -271
  986. package/packages/agent/src/core/bash-executor.ts +0 -156
  987. package/packages/agent/src/core/compaction/branch-summarization.ts +0 -372
  988. package/packages/agent/src/core/diagnostics.ts +0 -15
  989. package/packages/agent/src/core/event-bus.ts +0 -33
  990. package/packages/agent/src/core/exec.ts +0 -107
  991. package/packages/agent/src/core/experimental.ts +0 -3
  992. package/packages/agent/src/core/footer-data-provider.ts +0 -388
  993. package/packages/agent/src/core/http-dispatcher.ts +0 -106
  994. package/packages/agent/src/core/index.ts +0 -78
  995. package/packages/agent/src/core/model-config.ts +0 -287
  996. package/packages/agent/src/core/model-registry.ts +0 -126
  997. package/packages/agent/src/core/model-resolver.ts +0 -675
  998. package/packages/agent/src/core/output-guard.ts +0 -108
  999. package/packages/agent/src/core/package-manager.ts +0 -2441
  1000. package/packages/agent/src/core/prompt-templates.ts +0 -284
  1001. package/packages/agent/src/core/resolve-config-value.ts +0 -287
  1002. package/packages/agent/src/core/runtime-credentials.ts +0 -48
  1003. package/packages/agent/src/core/session-cwd.ts +0 -59
  1004. package/packages/agent/src/core/settings-manager.ts +0 -1212
  1005. package/packages/agent/src/core/slash-commands.ts +0 -41
  1006. package/packages/agent/src/core/timings.ts +0 -50
  1007. package/packages/agent/src/core/tools/tool-definition-wrapper.ts +0 -45
  1008. package/packages/agent/src/core/trust-manager.ts +0 -244
  1009. package/packages/agent/src/utils/ansi.ts +0 -60
  1010. package/packages/agent/src/utils/fs-watch.ts +0 -30
  1011. package/packages/agent/src/utils/git.ts +0 -226
  1012. package/packages/agent/src/utils/json.ts +0 -6
  1013. package/packages/agent/src/utils/tools-manager.ts +0 -63
  1014. package/packages/agent-core/package.json +0 -32
  1015. package/packages/ai/src/api/openrouter-images.lazy.ts +0 -10
  1016. package/packages/ai/src/api/openrouter-images.ts +0 -98
  1017. package/packages/ai/src/auth/credential-store.ts +0 -51
  1018. package/packages/ai/src/compat/extension-oauth-types.ts +0 -45
  1019. package/packages/ai/src/image-models.generated.ts +0 -533
  1020. package/packages/ai/src/images-models.ts +0 -274
  1021. package/packages/ai/src/models-store.ts +0 -38
  1022. package/packages/ai/src/oauth.ts +0 -10
  1023. package/packages/ai/src/providers/openrouter-images.ts +0 -14
  1024. package/packages/ai/src/session-resources.ts +0 -24
  1025. package/packages/ai/src/utils/abort-signals.ts +0 -41
  1026. package/packages/ai/src/utils/deferred-tools.ts +0 -39
  1027. package/packages/ai/src/utils/hash.ts +0 -13
  1028. package/packages/ai/src/utils/node-http-proxy.ts +0 -112
  1029. package/plugins/ragents.actor-programs/server/client-runtime.ts +0 -16
  1030. package/plugins/ragents.ask/web/constants.ts +0 -1
  1031. package/plugins/ragents.lsp-roslyn/web/api.ts +0 -10
  1032. package/plugins/ragents.orchestration/web/CanvasStartup.tsx +0 -14
  1033. package/plugins/ragents.orchestration/web/canvas-view-settings.ts +0 -42
  1034. package/plugins/ragents.orchestration/web/column/AddresseeControl.tsx +0 -116
  1035. package/plugins/ragents.orchestration/web/column/column-settings.ts +0 -47
  1036. package/plugins/ragents.orchestration/web/column/column-state.ts +0 -68
  1037. package/plugins/ragents.orchestration/web/contract.ts +0 -25
  1038. package/plugins/ragents.product/model-settings-contract.ts +0 -10
  1039. package/plugins/ragents.profile-distribution/server/web.ts +0 -24
  1040. /package/{plugins/ragents.actor-programs/server → apps/server/src/plugin-support/actor-programs}/authoring-contracts.ts +0 -0
  1041. /package/{plugins/ragents.actor-programs/server → apps/server/src/plugin-support/actor-programs}/runtime-libraries.ts +0 -0
  1042. /package/{plugins/ragents.actor-programs → apps/server/src/plugin-support/actor-programs}/workflow/prompt-reader.ts +0 -0
  1043. /package/{plugins/ragents.actor-programs → apps/web/src/actor-programs}/client-ui/file-contracts.d.ts +0 -0
  1044. /package/{plugins/ragents.actor-programs → apps/web/src/actor-programs}/client-ui/flow-diagram-contracts.d.ts +0 -0
  1045. /package/{plugins/ragents.actor-programs → apps/web/src/actor-programs}/client-ui/flow-diagram.css +0 -0
  1046. /package/{plugins/ragents.actor-programs → apps/web/src/actor-programs}/client-ui/form-contracts.d.ts +0 -0
  1047. /package/{plugins/ragents.actor-programs → apps/web/src/actor-programs}/client-ui/frame-layout.ts +0 -0
  1048. /package/{plugins/ragents.actor-programs → apps/web/src/actor-programs}/client-ui/table-contracts.d.ts +0 -0
  1049. /package/{plugins/ragents.actor-programs → apps/web/src/actor-programs}/client-ui/viewer-contracts.d.ts +0 -0
  1050. /package/{plugins/ragents.orchestration/canvas.hbs → bundles/ragents.orchestration/surface.hbs} +0 -0
  1051. /package/packages/{agent-core/src → agent/src/loop}/index.ts +0 -0
  1052. /package/packages/{agent-core/src → agent/src/loop}/uuid.ts +0 -0
@@ -1,2441 +0,0 @@
1
- import type { ChildProcess, ChildProcessByStdio } from "node:child_process";
2
- import { createHash } from "node:crypto";
3
- import { chmodSync, existsSync, mkdirSync, readdirSync, readFileSync, rmSync, statSync, writeFileSync } from "node:fs";
4
- import { homedir } from "node:os";
5
-
6
- function getEnv(): NodeJS.ProcessEnv {
7
- if (process.platform !== "linux" || Object.keys(process.env).length > 0) {
8
- return process.env;
9
- }
10
- try {
11
- const data = readFileSync("/proc/self/environ", "utf-8");
12
- const env: NodeJS.ProcessEnv = {};
13
- for (const entry of data.split("\0")) {
14
- const idx = entry.indexOf("=");
15
- if (idx > 0) {
16
- env[entry.slice(0, idx)] = entry.slice(idx + 1);
17
- }
18
- }
19
- return env;
20
- } catch {
21
- return process.env;
22
- }
23
- }
24
-
25
- import { basename, dirname, join, relative, resolve, sep } from "node:path";
26
- import type { Readable } from "node:stream";
27
- import { globSync } from "glob";
28
- import ignore from "ignore";
29
- import { minimatch } from "minimatch";
30
- import { satisfies, valid, validRange } from "semver";
31
- import { CONFIG_DIR_NAME } from "../config.ts";
32
- import { spawnProcess, spawnProcessSync } from "../utils/child-process.ts";
33
- import { type GitSource, parseGitUrl } from "../utils/git.ts";
34
- import { canonicalizePath, isLocalPath, markPathIgnoredByCloudSync, resolvePath } from "../utils/paths.ts";
35
- import { isStdoutTakenOver } from "./output-guard.ts";
36
- import type { PackageSource, SettingsManager } from "./settings-manager.ts";
37
-
38
- const NETWORK_TIMEOUT_MS = 10000;
39
- const GIT_UPDATE_CONCURRENCY = 4;
40
-
41
- function isExactNpmVersion(version: string | undefined): boolean {
42
- return valid(version ?? "") !== null;
43
- }
44
-
45
- function getNpmVersionRange(version: string | undefined): string | undefined {
46
- return version ? (validRange(version) ?? undefined) : undefined;
47
- }
48
-
49
- export interface PathMetadata {
50
- source: string;
51
- scope: SourceScope;
52
- origin: "package" | "top-level";
53
- baseDir?: string;
54
- }
55
-
56
- export interface ResolvedResource {
57
- path: string;
58
- enabled: boolean;
59
- metadata: PathMetadata;
60
- }
61
-
62
- export interface ResolvedPaths {
63
- extensions: ResolvedResource[];
64
- skills: ResolvedResource[];
65
- prompts: ResolvedResource[];
66
- themes: ResolvedResource[];
67
- }
68
-
69
- export type MissingSourceAction = "install" | "skip" | "error";
70
-
71
- export interface ProgressEvent {
72
- type: "start" | "progress" | "complete" | "error";
73
- action: "install" | "remove" | "update" | "clone" | "pull";
74
- source: string;
75
- message?: string;
76
- }
77
-
78
- export type ProgressCallback = (event: ProgressEvent) => void;
79
-
80
- export interface ConfiguredPackage {
81
- source: string;
82
- scope: "user" | "project";
83
- filtered: boolean;
84
- installedPath?: string;
85
- }
86
-
87
- export interface PackageManager {
88
- resolve(onMissing?: (source: string) => Promise<MissingSourceAction>): Promise<ResolvedPaths>;
89
- install(source: string, options?: { local?: boolean }): Promise<void>;
90
- installAndPersist(source: string, options?: { local?: boolean }): Promise<void>;
91
- remove(source: string, options?: { local?: boolean }): Promise<void>;
92
- removeAndPersist(source: string, options?: { local?: boolean }): Promise<boolean>;
93
- update(source?: string): Promise<void>;
94
- listConfiguredPackages(): ConfiguredPackage[];
95
- resolveExtensionSources(
96
- sources: string[],
97
- options?: { local?: boolean; temporary?: boolean },
98
- ): Promise<ResolvedPaths>;
99
- addSourceToSettings(source: string, options?: { local?: boolean }): boolean;
100
- removeSourceFromSettings(source: string, options?: { local?: boolean }): boolean;
101
- setProgressCallback(callback: ProgressCallback | undefined): void;
102
- getInstalledPath(source: string, scope: "user" | "project"): string | undefined;
103
- }
104
-
105
- interface PackageManagerOptions {
106
- cwd: string;
107
- agentDir: string;
108
- settingsManager: SettingsManager;
109
- }
110
-
111
- type SourceScope = "user" | "project" | "temporary";
112
-
113
- type NpmSource = {
114
- type: "npm";
115
- spec: string;
116
- name: string;
117
- version?: string;
118
- range?: string;
119
- pinned: boolean;
120
- };
121
-
122
- type LocalSource = {
123
- type: "local";
124
- path: string;
125
- };
126
-
127
- type ParsedSource = NpmSource | GitSource | LocalSource;
128
-
129
- type InstalledSourceScope = Exclude<SourceScope, "temporary">;
130
-
131
- interface ConfiguredUpdateSource {
132
- source: string;
133
- scope: InstalledSourceScope;
134
- }
135
-
136
- interface NpmUpdateTarget extends ConfiguredUpdateSource {
137
- parsed: NpmSource;
138
- }
139
-
140
- interface GitUpdateTarget extends ConfiguredUpdateSource {
141
- parsed: GitSource;
142
- }
143
-
144
- interface AgentManifest {
145
- extensions?: string[];
146
- skills?: string[];
147
- prompts?: string[];
148
- themes?: string[];
149
- }
150
-
151
- interface ResourceAccumulator {
152
- extensions: Map<string, { metadata: PathMetadata; enabled: boolean }>;
153
- skills: Map<string, { metadata: PathMetadata; enabled: boolean }>;
154
- prompts: Map<string, { metadata: PathMetadata; enabled: boolean }>;
155
- themes: Map<string, { metadata: PathMetadata; enabled: boolean }>;
156
- }
157
-
158
- /**
159
- * Compute a numeric precedence rank for a resource based on its metadata.
160
- * Lower rank = higher precedence. Used to sort resolved resources so that
161
- * name-collision resolution ("first wins") produces the correct outcome.
162
- *
163
- * Precedence (highest to lowest):
164
- * 0 project + settings entry (source: "local", scope: "project")
165
- * 1 project + auto-discovered (source: "auto", scope: "project")
166
- * 2 user + settings entry (source: "local", scope: "user")
167
- * 3 user + auto-discovered (source: "auto", scope: "user")
168
- * 4 package resource (origin: "package")
169
- */
170
- function resourcePrecedenceRank(m: PathMetadata): number {
171
- if (m.origin === "package") return 4;
172
- const scopeBase = m.scope === "project" ? 0 : 2;
173
- return scopeBase + (m.source === "local" ? 0 : 1);
174
- }
175
-
176
- interface PackageFilter {
177
- autoload?: boolean;
178
- extensions?: string[];
179
- skills?: string[];
180
- prompts?: string[];
181
- themes?: string[];
182
- }
183
-
184
- type ResourceType = "extensions" | "skills" | "prompts" | "themes";
185
-
186
- const RESOURCE_TYPES: ResourceType[] = ["extensions", "skills", "prompts", "themes"];
187
-
188
- const FILE_PATTERNS: Record<ResourceType, RegExp> = {
189
- extensions: /\.(ts|js)$/,
190
- skills: /\.md$/,
191
- prompts: /\.md$/,
192
- themes: /\.json$/,
193
- };
194
-
195
- const IGNORE_FILE_NAMES = [".gitignore", ".ignore", ".fdignore"];
196
-
197
- type IgnoreMatcher = ReturnType<typeof ignore>;
198
-
199
- function toPosixPath(p: string): string {
200
- return p.split(sep).join("/");
201
- }
202
-
203
- function getHomeDir(): string {
204
- return process.env.HOME || homedir();
205
- }
206
-
207
- export function getExtensionTempFolder(agentDir: string): string {
208
- const tempFolder = join(agentDir, "tmp", "extensions");
209
- mkdirSync(tempFolder, { recursive: true, mode: 0o700 });
210
- chmodSync(tempFolder, 0o700);
211
- return tempFolder;
212
- }
213
-
214
- function prefixIgnorePattern(line: string, prefix: string): string | null {
215
- const trimmed = line.trim();
216
- if (!trimmed) return null;
217
- if (trimmed.startsWith("#") && !trimmed.startsWith("\\#")) return null;
218
-
219
- let pattern = line;
220
- let negated = false;
221
-
222
- if (pattern.startsWith("!")) {
223
- negated = true;
224
- pattern = pattern.slice(1);
225
- } else if (pattern.startsWith("\\!")) {
226
- pattern = pattern.slice(1);
227
- }
228
-
229
- if (pattern.startsWith("/")) {
230
- pattern = pattern.slice(1);
231
- }
232
-
233
- const prefixed = prefix ? `${prefix}${pattern}` : pattern;
234
- return negated ? `!${prefixed}` : prefixed;
235
- }
236
-
237
- function addIgnoreRules(ig: IgnoreMatcher, dir: string, rootDir: string): void {
238
- const relativeDir = relative(rootDir, dir);
239
- const prefix = relativeDir ? `${toPosixPath(relativeDir)}/` : "";
240
-
241
- for (const filename of IGNORE_FILE_NAMES) {
242
- const ignorePath = join(dir, filename);
243
- if (!existsSync(ignorePath)) continue;
244
- try {
245
- const content = readFileSync(ignorePath, "utf-8");
246
- const patterns = content
247
- .split(/\r?\n/)
248
- .map((line) => prefixIgnorePattern(line, prefix))
249
- .filter((line): line is string => Boolean(line));
250
- if (patterns.length > 0) {
251
- ig.add(patterns);
252
- }
253
- } catch {}
254
- }
255
- }
256
-
257
- function isPattern(s: string): boolean {
258
- return s.startsWith("!") || s.startsWith("+") || s.startsWith("-") || s.includes("*") || s.includes("?");
259
- }
260
-
261
- function isOverridePattern(s: string): boolean {
262
- return s.startsWith("!") || s.startsWith("+") || s.startsWith("-");
263
- }
264
-
265
- function hasGlobPattern(s: string): boolean {
266
- return s.includes("*") || s.includes("?");
267
- }
268
-
269
- function splitPatterns(entries: string[]): { plain: string[]; patterns: string[] } {
270
- const plain: string[] = [];
271
- const patterns: string[] = [];
272
- for (const entry of entries) {
273
- if (isPattern(entry)) {
274
- patterns.push(entry);
275
- } else {
276
- plain.push(entry);
277
- }
278
- }
279
- return { plain, patterns };
280
- }
281
-
282
- function collectFiles(
283
- dir: string,
284
- filePattern: RegExp,
285
- skipNodeModules = true,
286
- ignoreMatcher?: IgnoreMatcher,
287
- rootDir?: string,
288
- ): string[] {
289
- const files: string[] = [];
290
- if (!existsSync(dir)) return files;
291
-
292
- const root = rootDir ?? dir;
293
- const ig = ignoreMatcher ?? ignore();
294
- addIgnoreRules(ig, dir, root);
295
-
296
- try {
297
- const entries = readdirSync(dir, { withFileTypes: true });
298
- for (const entry of entries) {
299
- if (entry.name.startsWith(".")) continue;
300
- if (skipNodeModules && entry.name === "node_modules") continue;
301
-
302
- const fullPath = join(dir, entry.name);
303
- let isDir = entry.isDirectory();
304
- let isFile = entry.isFile();
305
-
306
- if (entry.isSymbolicLink()) {
307
- try {
308
- const stats = statSync(fullPath);
309
- isDir = stats.isDirectory();
310
- isFile = stats.isFile();
311
- } catch {
312
- continue;
313
- }
314
- }
315
-
316
- const relPath = toPosixPath(relative(root, fullPath));
317
- const ignorePath = isDir ? `${relPath}/` : relPath;
318
- if (ig.ignores(ignorePath)) continue;
319
-
320
- if (isDir) {
321
- files.push(...collectFiles(fullPath, filePattern, skipNodeModules, ig, root));
322
- } else if (isFile && filePattern.test(entry.name)) {
323
- files.push(fullPath);
324
- }
325
- }
326
- } catch {
327
- // Ignore errors
328
- }
329
-
330
- return files;
331
- }
332
-
333
- type SkillDiscoveryMode = "native" | "agents";
334
-
335
- function collectSkillEntries(
336
- dir: string,
337
- mode: SkillDiscoveryMode,
338
- ignoreMatcher?: IgnoreMatcher,
339
- rootDir?: string,
340
- ): string[] {
341
- const entries: string[] = [];
342
- if (!existsSync(dir)) return entries;
343
-
344
- const root = rootDir ?? dir;
345
- const ig = ignoreMatcher ?? ignore();
346
- addIgnoreRules(ig, dir, root);
347
-
348
- try {
349
- const dirEntries = readdirSync(dir, { withFileTypes: true });
350
-
351
- for (const entry of dirEntries) {
352
- if (entry.name !== "SKILL.md") {
353
- continue;
354
- }
355
-
356
- const fullPath = join(dir, entry.name);
357
- let isFile = entry.isFile();
358
- if (entry.isSymbolicLink()) {
359
- try {
360
- isFile = statSync(fullPath).isFile();
361
- } catch {
362
- continue;
363
- }
364
- }
365
-
366
- const relPath = toPosixPath(relative(root, fullPath));
367
- if (isFile && !ig.ignores(relPath)) {
368
- entries.push(fullPath);
369
- return entries;
370
- }
371
- }
372
-
373
- for (const entry of dirEntries) {
374
- if (entry.name.startsWith(".")) continue;
375
- if (entry.name === "node_modules") continue;
376
-
377
- const fullPath = join(dir, entry.name);
378
- let isDir = entry.isDirectory();
379
- let isFile = entry.isFile();
380
-
381
- if (entry.isSymbolicLink()) {
382
- try {
383
- const stats = statSync(fullPath);
384
- isDir = stats.isDirectory();
385
- isFile = stats.isFile();
386
- } catch {
387
- continue;
388
- }
389
- }
390
-
391
- const relPath = toPosixPath(relative(root, fullPath));
392
- if (mode === "native" && dir === root && isFile && entry.name.endsWith(".md") && !ig.ignores(relPath)) {
393
- entries.push(fullPath);
394
- continue;
395
- }
396
-
397
- if (!isDir) continue;
398
- if (ig.ignores(`${relPath}/`)) continue;
399
-
400
- entries.push(...collectSkillEntries(fullPath, mode, ig, root));
401
- }
402
- } catch {
403
- // Ignore errors
404
- }
405
-
406
- return entries;
407
- }
408
-
409
- function collectAutoSkillEntries(dir: string, mode: SkillDiscoveryMode): string[] {
410
- return collectSkillEntries(dir, mode);
411
- }
412
-
413
- function findGitRepoRoot(startDir: string): string | null {
414
- let dir = resolve(startDir);
415
- while (true) {
416
- if (existsSync(join(dir, ".git"))) {
417
- return dir;
418
- }
419
- const parent = dirname(dir);
420
- if (parent === dir) {
421
- return null;
422
- }
423
- dir = parent;
424
- }
425
- }
426
-
427
- function collectAncestorAgentsSkillDirs(startDir: string): string[] {
428
- const skillDirs: string[] = [];
429
- const resolvedStartDir = resolve(startDir);
430
- const gitRepoRoot = findGitRepoRoot(resolvedStartDir);
431
-
432
- let dir = resolvedStartDir;
433
- while (true) {
434
- skillDirs.push(join(dir, ".agents", "skills"));
435
- if (gitRepoRoot && dir === gitRepoRoot) {
436
- break;
437
- }
438
- const parent = dirname(dir);
439
- if (parent === dir) {
440
- break;
441
- }
442
- dir = parent;
443
- }
444
-
445
- return skillDirs;
446
- }
447
-
448
- function collectAutoPromptEntries(dir: string): string[] {
449
- const entries: string[] = [];
450
- if (!existsSync(dir)) return entries;
451
-
452
- const ig = ignore();
453
- addIgnoreRules(ig, dir, dir);
454
-
455
- try {
456
- const dirEntries = readdirSync(dir, { withFileTypes: true });
457
- for (const entry of dirEntries) {
458
- if (entry.name.startsWith(".")) continue;
459
- if (entry.name === "node_modules") continue;
460
-
461
- const fullPath = join(dir, entry.name);
462
- let isFile = entry.isFile();
463
- if (entry.isSymbolicLink()) {
464
- try {
465
- isFile = statSync(fullPath).isFile();
466
- } catch {
467
- continue;
468
- }
469
- }
470
-
471
- const relPath = toPosixPath(relative(dir, fullPath));
472
- if (ig.ignores(relPath)) continue;
473
-
474
- if (isFile && entry.name.endsWith(".md")) {
475
- entries.push(fullPath);
476
- }
477
- }
478
- } catch {
479
- // Ignore errors
480
- }
481
-
482
- return entries;
483
- }
484
-
485
- function collectAutoThemeEntries(dir: string): string[] {
486
- const entries: string[] = [];
487
- if (!existsSync(dir)) return entries;
488
-
489
- const ig = ignore();
490
- addIgnoreRules(ig, dir, dir);
491
-
492
- try {
493
- const dirEntries = readdirSync(dir, { withFileTypes: true });
494
- for (const entry of dirEntries) {
495
- if (entry.name.startsWith(".")) continue;
496
- if (entry.name === "node_modules") continue;
497
-
498
- const fullPath = join(dir, entry.name);
499
- let isFile = entry.isFile();
500
- if (entry.isSymbolicLink()) {
501
- try {
502
- isFile = statSync(fullPath).isFile();
503
- } catch {
504
- continue;
505
- }
506
- }
507
-
508
- const relPath = toPosixPath(relative(dir, fullPath));
509
- if (ig.ignores(relPath)) continue;
510
-
511
- if (isFile && entry.name.endsWith(".json")) {
512
- entries.push(fullPath);
513
- }
514
- }
515
- } catch {
516
- // Ignore errors
517
- }
518
-
519
- return entries;
520
- }
521
-
522
- function readAgentManifestFile(packageJsonPath: string): AgentManifest | null {
523
- try {
524
- const content = readFileSync(packageJsonPath, "utf-8");
525
- const pkg = JSON.parse(content) as { agent?: AgentManifest };
526
- return pkg.agent ?? null;
527
- } catch {
528
- return null;
529
- }
530
- }
531
-
532
- function resolveExtensionEntries(dir: string): string[] | null {
533
- const packageJsonPath = join(dir, "package.json");
534
- if (existsSync(packageJsonPath)) {
535
- const manifest = readAgentManifestFile(packageJsonPath);
536
- if (manifest?.extensions?.length) {
537
- const entries: string[] = [];
538
- for (const extPath of manifest.extensions) {
539
- const resolvedExtPath = resolve(dir, extPath);
540
- if (existsSync(resolvedExtPath)) {
541
- entries.push(resolvedExtPath);
542
- }
543
- }
544
- if (entries.length > 0) {
545
- return entries;
546
- }
547
- }
548
- }
549
-
550
- const indexTs = join(dir, "index.ts");
551
- const indexJs = join(dir, "index.js");
552
- if (existsSync(indexTs)) {
553
- return [indexTs];
554
- }
555
- if (existsSync(indexJs)) {
556
- return [indexJs];
557
- }
558
-
559
- return null;
560
- }
561
-
562
- function collectAutoExtensionEntries(dir: string): string[] {
563
- const entries: string[] = [];
564
- if (!existsSync(dir)) return entries;
565
-
566
- // First check if this directory itself has explicit extension entries (package.json or index)
567
- const rootEntries = resolveExtensionEntries(dir);
568
- if (rootEntries) {
569
- return rootEntries;
570
- }
571
-
572
- // Otherwise, discover extensions from directory contents
573
- const ig = ignore();
574
- addIgnoreRules(ig, dir, dir);
575
-
576
- try {
577
- const dirEntries = readdirSync(dir, { withFileTypes: true });
578
- for (const entry of dirEntries) {
579
- if (entry.name.startsWith(".")) continue;
580
- if (entry.name === "node_modules") continue;
581
-
582
- const fullPath = join(dir, entry.name);
583
- let isDir = entry.isDirectory();
584
- let isFile = entry.isFile();
585
-
586
- if (entry.isSymbolicLink()) {
587
- try {
588
- const stats = statSync(fullPath);
589
- isDir = stats.isDirectory();
590
- isFile = stats.isFile();
591
- } catch {
592
- continue;
593
- }
594
- }
595
-
596
- const relPath = toPosixPath(relative(dir, fullPath));
597
- const ignorePath = isDir ? `${relPath}/` : relPath;
598
- if (ig.ignores(ignorePath)) continue;
599
-
600
- if (isFile && (entry.name.endsWith(".ts") || entry.name.endsWith(".js"))) {
601
- entries.push(fullPath);
602
- } else if (isDir) {
603
- const resolvedEntries = resolveExtensionEntries(fullPath);
604
- if (resolvedEntries) {
605
- entries.push(...resolvedEntries);
606
- }
607
- }
608
- }
609
- } catch {
610
- // Ignore errors
611
- }
612
-
613
- return entries;
614
- }
615
-
616
- /**
617
- * Collect resource files from a directory based on resource type.
618
- * Extensions use smart discovery (index.ts in subdirs), others use recursive collection.
619
- */
620
- function collectResourceFiles(dir: string, resourceType: ResourceType): string[] {
621
- if (resourceType === "skills") {
622
- return collectSkillEntries(dir, "native");
623
- }
624
- if (resourceType === "extensions") {
625
- return collectAutoExtensionEntries(dir);
626
- }
627
- return collectFiles(dir, FILE_PATTERNS[resourceType]);
628
- }
629
-
630
- function matchesAnyPattern(filePath: string, patterns: string[], baseDir: string): boolean {
631
- const rel = toPosixPath(relative(baseDir, filePath));
632
- const name = basename(filePath);
633
- const filePathPosix = toPosixPath(filePath);
634
- const isSkillFile = name === "SKILL.md";
635
- const parentDir = isSkillFile ? dirname(filePath) : undefined;
636
- const parentRel = isSkillFile ? toPosixPath(relative(baseDir, parentDir!)) : undefined;
637
- const parentName = isSkillFile ? basename(parentDir!) : undefined;
638
- const parentDirPosix = isSkillFile ? toPosixPath(parentDir!) : undefined;
639
-
640
- return patterns.some((pattern) => {
641
- const normalizedPattern = toPosixPath(pattern);
642
- if (
643
- minimatch(rel, normalizedPattern) ||
644
- minimatch(name, normalizedPattern) ||
645
- minimatch(filePathPosix, normalizedPattern)
646
- ) {
647
- return true;
648
- }
649
- if (!isSkillFile) return false;
650
- return (
651
- minimatch(parentRel!, normalizedPattern) ||
652
- minimatch(parentName!, normalizedPattern) ||
653
- minimatch(parentDirPosix!, normalizedPattern)
654
- );
655
- });
656
- }
657
-
658
- function normalizeExactPattern(pattern: string): string {
659
- const normalized = pattern.startsWith("./") || pattern.startsWith(".\\") ? pattern.slice(2) : pattern;
660
- return toPosixPath(normalized);
661
- }
662
-
663
- function matchesAnyExactPattern(filePath: string, patterns: string[], baseDir: string): boolean {
664
- if (patterns.length === 0) return false;
665
- const rel = toPosixPath(relative(baseDir, filePath));
666
- const name = basename(filePath);
667
- const filePathPosix = toPosixPath(filePath);
668
- const isSkillFile = name === "SKILL.md";
669
- const parentDir = isSkillFile ? dirname(filePath) : undefined;
670
- const parentRel = isSkillFile ? toPosixPath(relative(baseDir, parentDir!)) : undefined;
671
- const parentDirPosix = isSkillFile ? toPosixPath(parentDir!) : undefined;
672
-
673
- return patterns.some((pattern) => {
674
- const normalized = normalizeExactPattern(pattern);
675
- if (normalized === rel || normalized === filePathPosix) {
676
- return true;
677
- }
678
- if (!isSkillFile) return false;
679
- return normalized === parentRel || normalized === parentDirPosix;
680
- });
681
- }
682
-
683
- function getOverridePatterns(entries: string[]): string[] {
684
- return entries.filter((pattern) => pattern.startsWith("!") || pattern.startsWith("+") || pattern.startsWith("-"));
685
- }
686
-
687
- function isEnabledByOverrides(filePath: string, patterns: string[], baseDir: string): boolean {
688
- const overrides = getOverridePatterns(patterns);
689
- const excludes = overrides.filter((pattern) => pattern.startsWith("!")).map((pattern) => pattern.slice(1));
690
- const forceIncludes = overrides.filter((pattern) => pattern.startsWith("+")).map((pattern) => pattern.slice(1));
691
- const forceExcludes = overrides.filter((pattern) => pattern.startsWith("-")).map((pattern) => pattern.slice(1));
692
-
693
- let enabled = true;
694
- if (excludes.length > 0 && matchesAnyPattern(filePath, excludes, baseDir)) {
695
- enabled = false;
696
- }
697
- if (forceIncludes.length > 0 && matchesAnyExactPattern(filePath, forceIncludes, baseDir)) {
698
- enabled = true;
699
- }
700
- if (forceExcludes.length > 0 && matchesAnyExactPattern(filePath, forceExcludes, baseDir)) {
701
- enabled = false;
702
- }
703
- return enabled;
704
- }
705
-
706
- /**
707
- * Apply patterns to paths and return a Set of enabled paths.
708
- * Pattern types:
709
- * - Plain patterns: include matching paths
710
- * - `!pattern`: exclude matching paths
711
- * - `+path`: force-include exact path (overrides exclusions)
712
- * - `-path`: force-exclude exact path (overrides force-includes)
713
- */
714
- function applyPatterns(allPaths: string[], patterns: string[], baseDir: string): Set<string> {
715
- const includes: string[] = [];
716
- const excludes: string[] = [];
717
- const forceIncludes: string[] = [];
718
- const forceExcludes: string[] = [];
719
-
720
- for (const p of patterns) {
721
- if (p.startsWith("+")) {
722
- forceIncludes.push(p.slice(1));
723
- } else if (p.startsWith("-")) {
724
- forceExcludes.push(p.slice(1));
725
- } else if (p.startsWith("!")) {
726
- excludes.push(p.slice(1));
727
- } else {
728
- includes.push(p);
729
- }
730
- }
731
-
732
- // Step 1: Apply includes (or all if no includes)
733
- let result: string[];
734
- if (includes.length === 0) {
735
- result = [...allPaths];
736
- } else {
737
- result = allPaths.filter((filePath) => matchesAnyPattern(filePath, includes, baseDir));
738
- }
739
-
740
- // Step 2: Apply excludes
741
- if (excludes.length > 0) {
742
- result = result.filter((filePath) => !matchesAnyPattern(filePath, excludes, baseDir));
743
- }
744
-
745
- // Step 3: Force-include (add back from allPaths, overriding exclusions)
746
- if (forceIncludes.length > 0) {
747
- for (const filePath of allPaths) {
748
- if (!result.includes(filePath) && matchesAnyExactPattern(filePath, forceIncludes, baseDir)) {
749
- result.push(filePath);
750
- }
751
- }
752
- }
753
-
754
- // Step 4: Force-exclude (remove even if included or force-included)
755
- if (forceExcludes.length > 0) {
756
- result = result.filter((filePath) => !matchesAnyExactPattern(filePath, forceExcludes, baseDir));
757
- }
758
-
759
- return new Set(result);
760
- }
761
-
762
- function applyAutoloadDisabledPatterns(allPaths: string[], patterns: string[], baseDir: string): Map<string, boolean> {
763
- const result = new Map<string, boolean>();
764
- for (const pattern of patterns) {
765
- const target = pattern.slice(
766
- pattern.startsWith("+") || pattern.startsWith("-") || pattern.startsWith("!") ? 1 : 0,
767
- );
768
- const enabled = !pattern.startsWith("-") && !pattern.startsWith("!");
769
- const exact = pattern.startsWith("+") || pattern.startsWith("-");
770
- for (const filePath of allPaths) {
771
- if (
772
- exact ? matchesAnyExactPattern(filePath, [target], baseDir) : matchesAnyPattern(filePath, [target], baseDir)
773
- ) {
774
- result.set(filePath, enabled);
775
- }
776
- }
777
- }
778
- return result;
779
- }
780
-
781
- export class DefaultPackageManager implements PackageManager {
782
- private cwd: string;
783
- private agentDir: string;
784
- private settingsManager: SettingsManager;
785
- private globalNpmRoot: string | undefined;
786
- private globalNpmRootCommandKey: string | undefined;
787
- private progressCallback: ProgressCallback | undefined;
788
-
789
- constructor(options: PackageManagerOptions) {
790
- this.cwd = resolvePath(options.cwd);
791
- this.agentDir = resolvePath(options.agentDir);
792
- this.settingsManager = options.settingsManager;
793
- }
794
-
795
- setProgressCallback(callback: ProgressCallback | undefined): void {
796
- this.progressCallback = callback;
797
- }
798
-
799
- addSourceToSettings(source: string, options?: { local?: boolean }): boolean {
800
- const scope: SourceScope = options?.local ? "project" : "user";
801
- const currentSettings =
802
- scope === "project" ? this.settingsManager.getProjectSettings() : this.settingsManager.getGlobalSettings();
803
- const currentPackages = currentSettings.packages ?? [];
804
- const normalizedSource = this.normalizePackageSourceForSettings(source, scope);
805
- const matchIndex = currentPackages.findIndex((existing) => this.packageSourcesMatch(existing, source, scope));
806
- if (matchIndex !== -1) {
807
- const existing = currentPackages[matchIndex];
808
- if (this.getPackageSourceString(existing) === normalizedSource) {
809
- return false;
810
- }
811
- const nextPackages = [...currentPackages];
812
- nextPackages[matchIndex] =
813
- typeof existing === "string" ? normalizedSource : { ...existing, source: normalizedSource };
814
- if (scope === "project") {
815
- this.settingsManager.setProjectPackages(nextPackages);
816
- } else {
817
- this.settingsManager.setPackages(nextPackages);
818
- }
819
- return true;
820
- }
821
- const nextPackages = [...currentPackages, normalizedSource];
822
- if (scope === "project") {
823
- this.settingsManager.setProjectPackages(nextPackages);
824
- } else {
825
- this.settingsManager.setPackages(nextPackages);
826
- }
827
- return true;
828
- }
829
-
830
- removeSourceFromSettings(source: string, options?: { local?: boolean }): boolean {
831
- const scope: SourceScope = options?.local ? "project" : "user";
832
- const currentSettings =
833
- scope === "project" ? this.settingsManager.getProjectSettings() : this.settingsManager.getGlobalSettings();
834
- const currentPackages = currentSettings.packages ?? [];
835
- const nextPackages = currentPackages.filter((existing) => !this.packageSourcesMatch(existing, source, scope));
836
- const changed = nextPackages.length !== currentPackages.length;
837
- if (!changed) {
838
- return false;
839
- }
840
- if (scope === "project") {
841
- this.settingsManager.setProjectPackages(nextPackages);
842
- } else {
843
- this.settingsManager.setPackages(nextPackages);
844
- }
845
- return true;
846
- }
847
-
848
- getInstalledPath(source: string, scope: "user" | "project"): string | undefined {
849
- const parsed = this.parseSource(source);
850
- if (parsed.type === "npm") {
851
- const path = this.getNpmInstallPath(parsed, scope);
852
- return existsSync(path) ? path : undefined;
853
- }
854
- if (parsed.type === "git") {
855
- const path = this.getGitInstallPath(parsed, scope);
856
- return existsSync(path) ? path : undefined;
857
- }
858
- if (parsed.type === "local") {
859
- const baseDir = this.getBaseDirForScope(scope);
860
- const path = this.resolvePathFromBase(parsed.path, baseDir);
861
- return existsSync(path) ? path : undefined;
862
- }
863
- return undefined;
864
- }
865
-
866
- private emitProgress(event: ProgressEvent): void {
867
- this.progressCallback?.(event);
868
- }
869
-
870
- private async withProgress(
871
- action: ProgressEvent["action"],
872
- source: string,
873
- message: string,
874
- operation: () => Promise<void>,
875
- ): Promise<void> {
876
- this.emitProgress({ type: "start", action, source, message });
877
- try {
878
- await operation();
879
- this.emitProgress({ type: "complete", action, source });
880
- } catch (error) {
881
- const errorMessage = error instanceof Error ? error.message : String(error);
882
- this.emitProgress({ type: "error", action, source, message: errorMessage });
883
- throw error;
884
- }
885
- }
886
-
887
- async resolve(onMissing?: (source: string) => Promise<MissingSourceAction>): Promise<ResolvedPaths> {
888
- const accumulator = this.createAccumulator();
889
- const globalSettings = this.settingsManager.getGlobalSettings();
890
- const projectSettings = this.settingsManager.getProjectSettings();
891
-
892
- // Collect all packages with scope (project first so cwd resources win collisions)
893
- const allPackages: Array<{ pkg: PackageSource; scope: SourceScope }> = [];
894
- for (const pkg of projectSettings.packages ?? []) {
895
- allPackages.push({ pkg, scope: "project" });
896
- }
897
- for (const pkg of globalSettings.packages ?? []) {
898
- allPackages.push({ pkg, scope: "user" });
899
- }
900
-
901
- // Dedupe: project scope wins over global for same package identity
902
- const packageSources = this.dedupePackages(allPackages);
903
- await this.resolvePackageSources(packageSources, accumulator, onMissing);
904
-
905
- const globalBaseDir = this.agentDir;
906
- const projectBaseDir = join(this.cwd, CONFIG_DIR_NAME);
907
-
908
- for (const resourceType of RESOURCE_TYPES) {
909
- const target = this.getTargetMap(accumulator, resourceType);
910
- const globalEntries = (globalSettings[resourceType] ?? []) as string[];
911
- const projectEntries = (projectSettings[resourceType] ?? []) as string[];
912
- this.resolveLocalEntries(
913
- projectEntries,
914
- resourceType,
915
- target,
916
- {
917
- source: "local",
918
- scope: "project",
919
- origin: "top-level",
920
- },
921
- projectBaseDir,
922
- );
923
- this.resolveLocalEntries(
924
- globalEntries,
925
- resourceType,
926
- target,
927
- {
928
- source: "local",
929
- scope: "user",
930
- origin: "top-level",
931
- },
932
- globalBaseDir,
933
- );
934
- }
935
-
936
- this.addAutoDiscoveredResources(accumulator, globalSettings, projectSettings, globalBaseDir, projectBaseDir);
937
-
938
- return this.toResolvedPaths(accumulator);
939
- }
940
-
941
- async resolveExtensionSources(
942
- sources: string[],
943
- options?: { local?: boolean; temporary?: boolean },
944
- ): Promise<ResolvedPaths> {
945
- const accumulator = this.createAccumulator();
946
- const scope: SourceScope = options?.temporary ? "temporary" : options?.local ? "project" : "user";
947
- const packageSources = sources.map((source) => ({ pkg: source as PackageSource, scope }));
948
- await this.resolvePackageSources(packageSources, accumulator);
949
- return this.toResolvedPaths(accumulator);
950
- }
951
-
952
- listConfiguredPackages(): ConfiguredPackage[] {
953
- const globalSettings = this.settingsManager.getGlobalSettings();
954
- const projectSettings = this.settingsManager.getProjectSettings();
955
- const configuredPackages: ConfiguredPackage[] = [];
956
-
957
- for (const pkg of globalSettings.packages ?? []) {
958
- const source = typeof pkg === "string" ? pkg : pkg.source;
959
- configuredPackages.push({
960
- source,
961
- scope: "user",
962
- filtered: typeof pkg === "object",
963
- installedPath: this.getInstalledPath(source, "user"),
964
- });
965
- }
966
-
967
- for (const pkg of projectSettings.packages ?? []) {
968
- const source = typeof pkg === "string" ? pkg : pkg.source;
969
- configuredPackages.push({
970
- source,
971
- scope: "project",
972
- filtered: typeof pkg === "object",
973
- installedPath: this.getInstalledPath(source, "project"),
974
- });
975
- }
976
-
977
- return configuredPackages;
978
- }
979
-
980
- async install(source: string, options?: { local?: boolean }): Promise<void> {
981
- const parsed = this.parseSource(source);
982
- const scope: SourceScope = options?.local ? "project" : "user";
983
- this.assertProjectTrustedForScope(scope);
984
- await this.withProgress("install", source, `Installing ${source}...`, async () => {
985
- if (parsed.type === "npm") {
986
- await this.installNpm(parsed, scope, false);
987
- return;
988
- }
989
- if (parsed.type === "git") {
990
- await this.installGit(parsed, scope);
991
- return;
992
- }
993
- if (parsed.type === "local") {
994
- const resolved = this.resolvePath(parsed.path);
995
- if (!existsSync(resolved)) {
996
- throw new Error(`Path does not exist: ${resolved}`);
997
- }
998
- return;
999
- }
1000
- throw new Error(`Unsupported install source: ${source}`);
1001
- });
1002
- }
1003
-
1004
- async installAndPersist(source: string, options?: { local?: boolean }): Promise<void> {
1005
- await this.install(source, options);
1006
- this.addSourceToSettings(source, options);
1007
- }
1008
-
1009
- async remove(source: string, options?: { local?: boolean }): Promise<void> {
1010
- const parsed = this.parseSource(source);
1011
- const scope: SourceScope = options?.local ? "project" : "user";
1012
- this.assertProjectTrustedForScope(scope);
1013
- await this.withProgress("remove", source, `Removing ${source}...`, async () => {
1014
- if (parsed.type === "npm") {
1015
- await this.uninstallNpm(parsed, scope);
1016
- return;
1017
- }
1018
- if (parsed.type === "git") {
1019
- await this.removeGit(parsed, scope);
1020
- return;
1021
- }
1022
- if (parsed.type === "local") {
1023
- return;
1024
- }
1025
- throw new Error(`Unsupported remove source: ${source}`);
1026
- });
1027
- }
1028
-
1029
- async removeAndPersist(source: string, options?: { local?: boolean }): Promise<boolean> {
1030
- await this.remove(source, options);
1031
- return this.removeSourceFromSettings(source, options);
1032
- }
1033
-
1034
- async update(source?: string): Promise<void> {
1035
- const globalSettings = this.settingsManager.getGlobalSettings();
1036
- const projectSettings = this.settingsManager.getProjectSettings();
1037
- const identity = source ? this.getPackageIdentity(source) : undefined;
1038
- let matched = false;
1039
- const updateSources: ConfiguredUpdateSource[] = [];
1040
-
1041
- for (const pkg of globalSettings.packages ?? []) {
1042
- const sourceStr = typeof pkg === "string" ? pkg : pkg.source;
1043
- if (identity && this.getPackageIdentity(sourceStr, "user") !== identity) continue;
1044
- matched = true;
1045
- updateSources.push({ source: sourceStr, scope: "user" });
1046
- }
1047
- for (const pkg of projectSettings.packages ?? []) {
1048
- const sourceStr = typeof pkg === "string" ? pkg : pkg.source;
1049
- if (identity && this.getPackageIdentity(sourceStr, "project") !== identity) continue;
1050
- matched = true;
1051
- updateSources.push({ source: sourceStr, scope: "project" });
1052
- }
1053
-
1054
- if (source && !matched) {
1055
- throw new Error(
1056
- this.buildNoMatchingPackageMessage(source, [
1057
- ...(globalSettings.packages ?? []),
1058
- ...(projectSettings.packages ?? []),
1059
- ]),
1060
- );
1061
- }
1062
-
1063
- await this.updateConfiguredSources(updateSources);
1064
- }
1065
-
1066
- private async updateConfiguredSources(sources: ConfiguredUpdateSource[]): Promise<void> {
1067
- if (sources.length === 0) {
1068
- return;
1069
- }
1070
-
1071
- const npmCandidates: NpmUpdateTarget[] = [];
1072
- const gitCandidates: GitUpdateTarget[] = [];
1073
-
1074
- for (const entry of sources) {
1075
- const parsed = this.parseSource(entry.source);
1076
- // Pinned npm versions are fixed. Pinned git refs are configured checkout targets,
1077
- // so include them to reconcile an existing clone when the configured ref changes.
1078
- if (parsed.type === "npm") {
1079
- if (!parsed.pinned) {
1080
- npmCandidates.push({ ...entry, parsed });
1081
- }
1082
- } else if (parsed.type === "git") {
1083
- gitCandidates.push({ ...entry, parsed });
1084
- }
1085
- }
1086
-
1087
- const userNpmUpdates: NpmUpdateTarget[] = [];
1088
- const projectNpmUpdates: NpmUpdateTarget[] = [];
1089
- for (const entry of npmCandidates) {
1090
- if (entry.scope === "user") {
1091
- userNpmUpdates.push(entry);
1092
- } else {
1093
- projectNpmUpdates.push(entry);
1094
- }
1095
- }
1096
-
1097
- const tasks: Promise<void>[] = [];
1098
- if (userNpmUpdates.length > 0) {
1099
- tasks.push(this.updateNpmBatch(userNpmUpdates, "user"));
1100
- }
1101
- if (projectNpmUpdates.length > 0) {
1102
- tasks.push(this.updateNpmBatch(projectNpmUpdates, "project"));
1103
- }
1104
- if (gitCandidates.length > 0) {
1105
- const gitTasks = gitCandidates.map(
1106
- (entry) => async () =>
1107
- this.withProgress("update", entry.source, `Updating ${entry.source}...`, async () => {
1108
- await this.updateGit(entry.parsed, entry.scope);
1109
- }),
1110
- );
1111
- tasks.push(this.runWithConcurrency(gitTasks, GIT_UPDATE_CONCURRENCY).then(() => {}));
1112
- }
1113
-
1114
- await Promise.all(tasks);
1115
- }
1116
-
1117
- private async updateNpmBatch(sources: NpmUpdateTarget[], scope: InstalledSourceScope): Promise<void> {
1118
- if (sources.length === 0) {
1119
- return;
1120
- }
1121
-
1122
- const sourceLabel = sources.length === 1 ? sources[0].source : `${scope} npm packages`;
1123
- const message = sources.length === 1 ? `Updating ${sources[0].source}...` : `Updating ${scope} npm packages...`;
1124
- const specs = sources.map((entry) => (entry.parsed.version ? entry.parsed.spec : `${entry.parsed.name}@latest`));
1125
-
1126
- await this.withProgress("update", sourceLabel, message, async () => {
1127
- await this.installNpmBatch(specs, scope);
1128
- });
1129
- }
1130
-
1131
- private async installNpmBatch(specs: string[], scope: InstalledSourceScope): Promise<void> {
1132
- const installRoot = this.getNpmInstallRoot(scope, false);
1133
- this.ensureNpmProject(installRoot);
1134
- await this.runNpmCommand(this.getNpmInstallArgs(specs, installRoot));
1135
- }
1136
-
1137
- private async resolvePackageSources(
1138
- sources: Array<{ pkg: PackageSource; scope: SourceScope }>,
1139
- accumulator: ResourceAccumulator,
1140
- onMissing?: (source: string) => Promise<MissingSourceAction>,
1141
- ): Promise<void> {
1142
- for (const { pkg, scope } of sources) {
1143
- const sourceStr = typeof pkg === "string" ? pkg : pkg.source;
1144
- const filter = typeof pkg === "object" ? pkg : undefined;
1145
- const deltaBase = this.findAutoloadDeltaBase(pkg, scope, sources);
1146
- const resolvedSource = deltaBase?.source ?? sourceStr;
1147
- const resolvedScope = deltaBase?.scope ?? scope;
1148
- const parsed = this.parseSource(resolvedSource);
1149
- const metadata: PathMetadata = { source: sourceStr, scope, origin: "package" };
1150
-
1151
- if (parsed.type === "local") {
1152
- const baseDir = this.getBaseDirForScope(resolvedScope);
1153
- this.resolveLocalExtensionSource(parsed, accumulator, filter, metadata, baseDir);
1154
- continue;
1155
- }
1156
-
1157
- const installMissing = async (): Promise<boolean> => {
1158
- if (!onMissing) {
1159
- await this.installParsedSource(parsed, resolvedScope);
1160
- return true;
1161
- }
1162
- const action = await onMissing(resolvedSource);
1163
- if (action === "skip") return false;
1164
- if (action === "error") throw new Error(`Missing source: ${resolvedSource}`);
1165
- await this.installParsedSource(parsed, resolvedScope);
1166
- return true;
1167
- };
1168
-
1169
- if (parsed.type === "npm") {
1170
- let installedPath = this.getNpmInstallPath(parsed, resolvedScope);
1171
- const needsInstall =
1172
- !existsSync(installedPath) || !(await this.installedNpmMatchesConfiguredVersion(parsed, installedPath));
1173
- if (needsInstall) {
1174
- const installed = await installMissing();
1175
- if (!installed) continue;
1176
- installedPath = this.getNpmInstallPath(parsed, resolvedScope);
1177
- }
1178
- metadata.baseDir = installedPath;
1179
- this.collectPackageResources(installedPath, accumulator, filter, metadata);
1180
- continue;
1181
- }
1182
-
1183
- if (parsed.type === "git") {
1184
- const installedPath = this.getGitInstallPath(parsed, resolvedScope);
1185
- if (!existsSync(installedPath)) {
1186
- const installed = await installMissing();
1187
- if (!installed) continue;
1188
- } else if (resolvedScope === "temporary" && !parsed.pinned) {
1189
- await this.refreshTemporaryGitSource(parsed, resolvedSource);
1190
- }
1191
- metadata.baseDir = installedPath;
1192
- this.collectPackageResources(installedPath, accumulator, filter, metadata);
1193
- }
1194
- }
1195
- }
1196
-
1197
- private findAutoloadDeltaBase(
1198
- pkg: PackageSource,
1199
- scope: SourceScope,
1200
- sources: Array<{ pkg: PackageSource; scope: SourceScope }>,
1201
- ): { source: string; scope: SourceScope } | undefined {
1202
- if (scope !== "project" || typeof pkg !== "object" || pkg.autoload !== false) return undefined;
1203
- const identity = this.getPackageIdentity(pkg.source, scope);
1204
- const userEntry = sources.find(
1205
- (entry) =>
1206
- entry.scope === "user" &&
1207
- this.getPackageIdentity(this.getPackageSourceString(entry.pkg), "user") === identity,
1208
- );
1209
- return userEntry ? { source: this.getPackageSourceString(userEntry.pkg), scope: "user" } : undefined;
1210
- }
1211
-
1212
- private resolveLocalExtensionSource(
1213
- source: LocalSource,
1214
- accumulator: ResourceAccumulator,
1215
- filter: PackageFilter | undefined,
1216
- metadata: PathMetadata,
1217
- baseDir: string,
1218
- ): void {
1219
- const resolved = this.resolvePathFromBase(source.path, baseDir);
1220
- if (!existsSync(resolved)) {
1221
- return;
1222
- }
1223
-
1224
- try {
1225
- const stats = statSync(resolved);
1226
- if (stats.isFile()) {
1227
- metadata.baseDir = dirname(resolved);
1228
- this.addResource(accumulator.extensions, resolved, metadata, true);
1229
- return;
1230
- }
1231
- if (stats.isDirectory()) {
1232
- metadata.baseDir = resolved;
1233
- const resources = this.collectPackageResources(resolved, accumulator, filter, metadata);
1234
- if (!resources) {
1235
- this.addResource(accumulator.extensions, resolved, metadata, true);
1236
- }
1237
- }
1238
- } catch {
1239
- return;
1240
- }
1241
- }
1242
-
1243
- private async installParsedSource(parsed: ParsedSource, scope: SourceScope): Promise<void> {
1244
- if (parsed.type === "npm") {
1245
- await this.installNpm(parsed, scope, scope === "temporary");
1246
- return;
1247
- }
1248
- if (parsed.type === "git") {
1249
- await this.installGit(parsed, scope);
1250
- return;
1251
- }
1252
- }
1253
-
1254
- private getPackageSourceString(pkg: PackageSource): string {
1255
- return typeof pkg === "string" ? pkg : pkg.source;
1256
- }
1257
-
1258
- private getSourceMatchKeyForInput(source: string): string {
1259
- const parsed = this.parseSource(source);
1260
- if (parsed.type === "npm") {
1261
- return `npm:${parsed.name}`;
1262
- }
1263
- if (parsed.type === "git") {
1264
- return `git:${parsed.host}/${parsed.path}`;
1265
- }
1266
- return `local:${this.resolvePath(parsed.path)}`;
1267
- }
1268
-
1269
- private getSourceMatchKeyForSettings(source: string, scope: SourceScope): string {
1270
- const parsed = this.parseSource(source);
1271
- if (parsed.type === "npm") {
1272
- return `npm:${parsed.name}`;
1273
- }
1274
- if (parsed.type === "git") {
1275
- return `git:${parsed.host}/${parsed.path}`;
1276
- }
1277
- const baseDir = this.getBaseDirForScope(scope);
1278
- return `local:${this.resolvePathFromBase(parsed.path, baseDir)}`;
1279
- }
1280
-
1281
- private buildNoMatchingPackageMessage(source: string, configuredPackages: PackageSource[]): string {
1282
- const suggestion = this.findSuggestedConfiguredSource(source, configuredPackages);
1283
- if (!suggestion) {
1284
- return `No matching package found for ${source}`;
1285
- }
1286
- return `No matching package found for ${source}. Did you mean ${suggestion}?`;
1287
- }
1288
-
1289
- private findSuggestedConfiguredSource(source: string, configuredPackages: PackageSource[]): string | undefined {
1290
- const trimmedSource = source.trim();
1291
- const suggestions = new Set<string>();
1292
-
1293
- for (const pkg of configuredPackages) {
1294
- const sourceStr = this.getPackageSourceString(pkg);
1295
- const parsed = this.parseSource(sourceStr);
1296
- if (parsed.type === "npm") {
1297
- if (trimmedSource === parsed.name || trimmedSource === parsed.spec) {
1298
- suggestions.add(sourceStr);
1299
- }
1300
- continue;
1301
- }
1302
- if (parsed.type === "git") {
1303
- const shorthand = `${parsed.host}/${parsed.path}`;
1304
- const shorthandWithRef = parsed.ref ? `${shorthand}@${parsed.ref}` : undefined;
1305
- if (trimmedSource === shorthand || (shorthandWithRef && trimmedSource === shorthandWithRef)) {
1306
- suggestions.add(sourceStr);
1307
- }
1308
- }
1309
- }
1310
-
1311
- return suggestions.values().next().value;
1312
- }
1313
-
1314
- private packageSourcesMatch(existing: PackageSource, inputSource: string, scope: SourceScope): boolean {
1315
- const left = this.getSourceMatchKeyForSettings(this.getPackageSourceString(existing), scope);
1316
- const right = this.getSourceMatchKeyForInput(inputSource);
1317
- return left === right;
1318
- }
1319
-
1320
- private normalizePackageSourceForSettings(source: string, scope: SourceScope): string {
1321
- const parsed = this.parseSource(source);
1322
- if (parsed.type !== "local") {
1323
- return source;
1324
- }
1325
- const baseDir = this.getBaseDirForScope(scope);
1326
- const resolved = this.resolvePath(parsed.path);
1327
- const rel = relative(baseDir, resolved);
1328
- return rel || ".";
1329
- }
1330
-
1331
- private parseSource(source: string): ParsedSource {
1332
- if (source.startsWith("npm:")) {
1333
- const spec = source.slice("npm:".length).trim();
1334
- const { name, version } = this.parseNpmSpec(spec);
1335
- return {
1336
- type: "npm",
1337
- spec,
1338
- name,
1339
- version,
1340
- range: getNpmVersionRange(version),
1341
- pinned: isExactNpmVersion(version),
1342
- };
1343
- }
1344
-
1345
- if (isLocalPath(source)) {
1346
- return { type: "local", path: source };
1347
- }
1348
-
1349
- // Try parsing as git URL
1350
- const gitParsed = parseGitUrl(source);
1351
- if (gitParsed) {
1352
- return gitParsed;
1353
- }
1354
-
1355
- return { type: "local", path: source };
1356
- }
1357
-
1358
- private async installedNpmMatchesConfiguredVersion(source: NpmSource, installedPath: string): Promise<boolean> {
1359
- const installedVersion = this.getInstalledNpmVersion(installedPath);
1360
- if (!installedVersion) {
1361
- return false;
1362
- }
1363
- return source.range ? satisfies(installedVersion, source.range) : true;
1364
- }
1365
-
1366
- private getInstalledNpmVersion(installedPath: string): string | undefined {
1367
- const packageJsonPath = join(installedPath, "package.json");
1368
- if (!existsSync(packageJsonPath)) return undefined;
1369
- try {
1370
- const content = readFileSync(packageJsonPath, "utf-8");
1371
- const pkg = JSON.parse(content) as { version?: string };
1372
- return pkg.version;
1373
- } catch {
1374
- return undefined;
1375
- }
1376
- }
1377
-
1378
- private async getLocalGitUpdateTarget(
1379
- installedPath: string,
1380
- ): Promise<{ ref: string; head: string; fetchArgs: string[] }> {
1381
- try {
1382
- const upstream = await this.runCommandCapture("git", ["rev-parse", "--abbrev-ref", "@{upstream}"], {
1383
- cwd: installedPath,
1384
- timeoutMs: NETWORK_TIMEOUT_MS,
1385
- });
1386
- const trimmedUpstream = upstream.trim();
1387
- if (!trimmedUpstream.startsWith("origin/")) {
1388
- throw new Error(`Unsupported upstream remote: ${trimmedUpstream}`);
1389
- }
1390
- const branch = trimmedUpstream.slice("origin/".length);
1391
- if (!branch) {
1392
- throw new Error("Missing upstream branch name");
1393
- }
1394
- const head = await this.runCommandCapture("git", ["rev-parse", "@{upstream}"], {
1395
- cwd: installedPath,
1396
- timeoutMs: NETWORK_TIMEOUT_MS,
1397
- });
1398
- return {
1399
- ref: "@{upstream}",
1400
- head,
1401
- fetchArgs: [
1402
- "fetch",
1403
- "--prune",
1404
- "--no-tags",
1405
- "origin",
1406
- `+refs/heads/${branch}:refs/remotes/origin/${branch}`,
1407
- ],
1408
- };
1409
- } catch {
1410
- await this.runCommand("git", ["remote", "set-head", "origin", "-a"], { cwd: installedPath }).catch(() => {});
1411
- const head = await this.runCommandCapture("git", ["rev-parse", "origin/HEAD"], {
1412
- cwd: installedPath,
1413
- timeoutMs: NETWORK_TIMEOUT_MS,
1414
- });
1415
- const originHeadRef = await this.runCommandCapture("git", ["symbolic-ref", "refs/remotes/origin/HEAD"], {
1416
- cwd: installedPath,
1417
- timeoutMs: NETWORK_TIMEOUT_MS,
1418
- }).catch(() => "");
1419
- const branch = originHeadRef.trim().replace(/^refs\/remotes\/origin\//, "");
1420
- if (branch) {
1421
- return {
1422
- ref: "origin/HEAD",
1423
- head,
1424
- fetchArgs: [
1425
- "fetch",
1426
- "--prune",
1427
- "--no-tags",
1428
- "origin",
1429
- `+refs/heads/${branch}:refs/remotes/origin/${branch}`,
1430
- ],
1431
- };
1432
- }
1433
- return {
1434
- ref: "origin/HEAD",
1435
- head,
1436
- fetchArgs: ["fetch", "--prune", "--no-tags", "origin", "+HEAD:refs/remotes/origin/HEAD"],
1437
- };
1438
- }
1439
- }
1440
-
1441
- private async runWithConcurrency<T>(tasks: Array<() => Promise<T>>, limit: number): Promise<T[]> {
1442
- if (tasks.length === 0) {
1443
- return [];
1444
- }
1445
-
1446
- const results: T[] = new Array(tasks.length);
1447
- let nextIndex = 0;
1448
- const workerCount = Math.max(1, Math.min(limit, tasks.length));
1449
-
1450
- const worker = async () => {
1451
- while (true) {
1452
- const index = nextIndex;
1453
- nextIndex += 1;
1454
- if (index >= tasks.length) {
1455
- return;
1456
- }
1457
- results[index] = await tasks[index]();
1458
- }
1459
- };
1460
-
1461
- await Promise.all(Array.from({ length: workerCount }, () => worker()));
1462
- return results;
1463
- }
1464
-
1465
- /**
1466
- * Get a unique identity for a package, ignoring version/ref.
1467
- * Used to detect when the same package is in both global and project settings.
1468
- * For git packages, uses normalized host/path to ensure SSH and HTTPS URLs
1469
- * for the same repository are treated as identical.
1470
- */
1471
- private getPackageIdentity(source: string, scope?: SourceScope): string {
1472
- const parsed = this.parseSource(source);
1473
- if (parsed.type === "npm") {
1474
- return `npm:${parsed.name}`;
1475
- }
1476
- if (parsed.type === "git") {
1477
- // Use host/path for identity to normalize SSH and HTTPS
1478
- return `git:${parsed.host}/${parsed.path}`;
1479
- }
1480
- if (scope) {
1481
- const baseDir = this.getBaseDirForScope(scope);
1482
- return `local:${this.resolvePathFromBase(parsed.path, baseDir)}`;
1483
- }
1484
- return `local:${this.resolvePath(parsed.path)}`;
1485
- }
1486
-
1487
- /**
1488
- * Dedupe packages: if same package identity appears in both global and project,
1489
- * keep only the project one (project wins). A project entry with autoload=false
1490
- * is a delta over the global entry, so both are kept (delta first).
1491
- */
1492
- private dedupePackages(
1493
- packages: Array<{ pkg: PackageSource; scope: SourceScope }>,
1494
- ): Array<{ pkg: PackageSource; scope: SourceScope }> {
1495
- const result: Array<{ pkg: PackageSource; scope: SourceScope }> = [];
1496
- const seen = new Map<string, number>();
1497
- for (const entry of packages) {
1498
- const identity = this.getPackageIdentity(this.getPackageSourceString(entry.pkg), entry.scope);
1499
- const index = seen.get(identity);
1500
- if (index === undefined) {
1501
- seen.set(identity, result.length);
1502
- result.push(entry);
1503
- continue;
1504
- }
1505
- const existing = result[index];
1506
- if (existing?.scope === "project" && entry.scope === "user") {
1507
- if (typeof existing.pkg === "object" && existing.pkg.autoload === false) result.push(entry);
1508
- } else if (entry.scope === "project") {
1509
- result[index] = entry;
1510
- }
1511
- }
1512
- return result;
1513
- }
1514
-
1515
- private parseNpmSpec(spec: string): { name: string; version?: string } {
1516
- const match = spec.match(/^(@?[^@]+(?:\/[^@]+)?)(?:@(.+))?$/);
1517
- if (!match) {
1518
- return { name: spec };
1519
- }
1520
- const name = match[1] ?? spec;
1521
- const version = match[2];
1522
- return { name, version };
1523
- }
1524
-
1525
- private assertProjectTrustedForScope(scope: SourceScope): void {
1526
- if (scope === "project" && !this.settingsManager.isProjectTrusted()) {
1527
- throw new Error("Project is not trusted; refusing to access project package storage");
1528
- }
1529
- }
1530
-
1531
- private getNpmCommand(): { command: string; args: string[] } {
1532
- const configuredCommand = this.settingsManager.getNpmCommand();
1533
- if (!configuredCommand || configuredCommand.length === 0) {
1534
- return { command: "npm", args: [] };
1535
- }
1536
- const [command, ...args] = configuredCommand;
1537
- if (!command) {
1538
- throw new Error("Invalid npmCommand: first array entry must be a non-empty command");
1539
- }
1540
- return { command, args };
1541
- }
1542
-
1543
- private getPackageManagerName(): string {
1544
- const npmCommand = this.getNpmCommand();
1545
- const commandParts = [npmCommand.command, ...npmCommand.args];
1546
- const separatorIndex = commandParts.lastIndexOf("--");
1547
- const packageManagerCommand = separatorIndex >= 0 ? commandParts[separatorIndex + 1] : npmCommand.command;
1548
- return packageManagerCommand ? basename(packageManagerCommand).replace(/\.(cmd|exe)$/i, "") : "";
1549
- }
1550
-
1551
- private async runNpmCommand(args: string[], options?: { cwd?: string }): Promise<void> {
1552
- const npmCommand = this.getNpmCommand();
1553
- await this.runCommand(npmCommand.command, [...npmCommand.args, ...args], options);
1554
- }
1555
-
1556
- private getGitDependencyInstallArgs(): string[] {
1557
- const configuredCommand = this.settingsManager.getNpmCommand();
1558
- if (configuredCommand && configuredCommand.length > 0) {
1559
- return ["install"];
1560
- }
1561
- return ["install", "--omit=dev"];
1562
- }
1563
-
1564
- private runNpmCommandSync(args: string[]): string {
1565
- const npmCommand = this.getNpmCommand();
1566
- return this.runCommandSync(npmCommand.command, [...npmCommand.args, ...args]);
1567
- }
1568
-
1569
- private getNpmInstallArgs(specs: string[], installRoot: string): string[] {
1570
- const packageManagerName = this.getPackageManagerName();
1571
- // Erweiterungen laufen im Agenten und lösen dessen APIs über die Loader-Aliase auf.
1572
- // Peer-Auflösung bei verwalteten Installationen abschalten, damit Paketmanager keine
1573
- // vom Host bereitgestellten Peers nachinstallieren.
1574
- if (packageManagerName === "bun") {
1575
- return ["install", ...specs, "--cwd", installRoot, "--omit=peer"];
1576
- }
1577
- if (packageManagerName === "pnpm") {
1578
- return [
1579
- "install",
1580
- ...specs,
1581
- "--prefix",
1582
- installRoot,
1583
- "--config.auto-install-peers=false",
1584
- "--config.strict-peer-dependencies=false",
1585
- "--config.strict-dep-builds=false",
1586
- ];
1587
- }
1588
- return ["install", ...specs, "--prefix", installRoot, "--legacy-peer-deps"];
1589
- }
1590
-
1591
- private async installNpm(source: NpmSource, scope: SourceScope, temporary: boolean): Promise<void> {
1592
- const installRoot = this.getNpmInstallRoot(scope, temporary);
1593
- this.ensureNpmProject(installRoot);
1594
- await this.runNpmCommand(this.getNpmInstallArgs([source.spec], installRoot));
1595
- }
1596
-
1597
- private async uninstallNpm(source: NpmSource, scope: SourceScope): Promise<void> {
1598
- const installRoot = this.getNpmInstallRoot(scope, false);
1599
- if (!existsSync(installRoot)) {
1600
- return;
1601
- }
1602
- const packageManagerName = this.getPackageManagerName();
1603
- if (packageManagerName === "bun") {
1604
- await this.runNpmCommand(["uninstall", source.name, "--cwd", installRoot]);
1605
- return;
1606
- }
1607
- const args = ["uninstall", source.name, "--prefix", installRoot];
1608
- if (packageManagerName !== "pnpm") {
1609
- args.push("--legacy-peer-deps");
1610
- }
1611
- await this.runNpmCommand(args);
1612
- }
1613
-
1614
- private async installGit(source: GitSource, scope: SourceScope): Promise<void> {
1615
- const targetDir = this.getGitInstallPath(source, scope);
1616
- if (existsSync(targetDir)) {
1617
- if (source.ref) {
1618
- await this.ensureGitRef(targetDir, ["fetch", "origin", source.ref], "FETCH_HEAD");
1619
- return;
1620
- }
1621
- const target = await this.getLocalGitUpdateTarget(targetDir);
1622
- await this.ensureGitRef(targetDir, target.fetchArgs, target.ref);
1623
- return;
1624
- }
1625
- const gitRoot = this.getGitInstallRoot(scope);
1626
- if (gitRoot) {
1627
- this.ensureGitIgnore(gitRoot);
1628
- }
1629
- mkdirSync(dirname(targetDir), { recursive: true });
1630
-
1631
- await this.runCommand("git", ["clone", source.repo, targetDir]);
1632
- if (source.ref) {
1633
- await this.runCommand("git", ["checkout", source.ref], { cwd: targetDir });
1634
- }
1635
- const packageJsonPath = join(targetDir, "package.json");
1636
- if (existsSync(packageJsonPath)) {
1637
- await this.runNpmCommand(this.getGitDependencyInstallArgs(), { cwd: targetDir });
1638
- }
1639
- }
1640
-
1641
- private async updateGit(source: GitSource, scope: SourceScope): Promise<void> {
1642
- const targetDir = this.getGitInstallPath(source, scope);
1643
- if (!existsSync(targetDir)) {
1644
- await this.installGit(source, scope);
1645
- return;
1646
- }
1647
-
1648
- if (source.ref) {
1649
- await this.ensureGitRef(targetDir, ["fetch", "origin", source.ref], "FETCH_HEAD");
1650
- return;
1651
- }
1652
-
1653
- const target = await this.getLocalGitUpdateTarget(targetDir);
1654
- await this.ensureGitRef(targetDir, target.fetchArgs, target.ref);
1655
- }
1656
-
1657
- private async ensureGitRef(targetDir: string, fetchArgs: string[], ref: string): Promise<void> {
1658
- // Fetch only the ref we will reset to, avoiding unrelated branch/tag noise.
1659
- await this.runCommand("git", fetchArgs, { cwd: targetDir });
1660
-
1661
- const localHead = await this.runCommandCapture("git", ["rev-parse", "HEAD"], {
1662
- cwd: targetDir,
1663
- timeoutMs: NETWORK_TIMEOUT_MS,
1664
- });
1665
- const commitRef = `${ref}^{commit}`;
1666
- const targetHead = await this.runCommandCapture("git", ["rev-parse", commitRef], {
1667
- cwd: targetDir,
1668
- timeoutMs: NETWORK_TIMEOUT_MS,
1669
- });
1670
- if (localHead.trim() === targetHead.trim()) {
1671
- return;
1672
- }
1673
-
1674
- await this.runCommand("git", ["reset", "--hard", commitRef], { cwd: targetDir });
1675
-
1676
- // Clean untracked files (extensions should be pristine)
1677
- await this.runCommand("git", ["clean", "-fdx"], { cwd: targetDir });
1678
-
1679
- const packageJsonPath = join(targetDir, "package.json");
1680
- if (existsSync(packageJsonPath)) {
1681
- await this.runNpmCommand(this.getGitDependencyInstallArgs(), { cwd: targetDir });
1682
- }
1683
- }
1684
-
1685
- private async refreshTemporaryGitSource(source: GitSource, sourceStr: string): Promise<void> {
1686
- try {
1687
- await this.withProgress("pull", sourceStr, `Refreshing ${sourceStr}...`, async () => {
1688
- await this.updateGit(source, "temporary");
1689
- });
1690
- } catch {
1691
- // Keep cached temporary checkout if refresh fails.
1692
- }
1693
- }
1694
-
1695
- private async removeGit(source: GitSource, scope: SourceScope): Promise<void> {
1696
- const targetDir = this.getGitInstallPath(source, scope);
1697
- if (!existsSync(targetDir)) return;
1698
- rmSync(targetDir, { recursive: true, force: true });
1699
- this.pruneEmptyGitParents(targetDir, this.getGitInstallRoot(scope));
1700
- }
1701
-
1702
- private pruneEmptyGitParents(targetDir: string, installRoot: string | undefined): void {
1703
- if (!installRoot) return;
1704
- const resolvedRoot = resolve(installRoot);
1705
- let current = dirname(targetDir);
1706
- while (current.startsWith(resolvedRoot) && current !== resolvedRoot) {
1707
- if (!existsSync(current)) {
1708
- current = dirname(current);
1709
- continue;
1710
- }
1711
- const entries = readdirSync(current);
1712
- if (entries.length > 0) {
1713
- break;
1714
- }
1715
- try {
1716
- rmSync(current, { recursive: true, force: true });
1717
- } catch {
1718
- break;
1719
- }
1720
- current = dirname(current);
1721
- }
1722
- }
1723
-
1724
- private ensureNpmProject(installRoot: string): void {
1725
- if (!existsSync(installRoot)) {
1726
- mkdirSync(installRoot, { recursive: true });
1727
- }
1728
- markPathIgnoredByCloudSync(installRoot);
1729
- this.ensureGitIgnore(installRoot);
1730
- const packageJsonPath = join(installRoot, "package.json");
1731
- if (!existsSync(packageJsonPath)) {
1732
- const pkgJson = { name: "agent-extensions", private: true };
1733
- writeFileSync(packageJsonPath, JSON.stringify(pkgJson, null, 2), "utf-8");
1734
- }
1735
- }
1736
-
1737
- private ensureGitIgnore(dir: string): void {
1738
- if (!existsSync(dir)) {
1739
- mkdirSync(dir, { recursive: true });
1740
- }
1741
- const ignorePath = join(dir, ".gitignore");
1742
- if (!existsSync(ignorePath)) {
1743
- writeFileSync(ignorePath, "*\n!.gitignore\n", "utf-8");
1744
- }
1745
- }
1746
-
1747
- private getNpmInstallRoot(scope: SourceScope, temporary: boolean): string {
1748
- if (temporary) {
1749
- return this.getTemporaryDir("npm");
1750
- }
1751
- if (scope === "project") {
1752
- this.assertProjectTrustedForScope(scope);
1753
- return join(this.cwd, CONFIG_DIR_NAME, "npm");
1754
- }
1755
- return join(this.agentDir, "npm");
1756
- }
1757
-
1758
- private getGlobalNpmRoot(): string {
1759
- const npmCommand = this.getNpmCommand();
1760
- const commandKey = [npmCommand.command, ...npmCommand.args].join("\0");
1761
- if (this.globalNpmRoot && this.globalNpmRootCommandKey === commandKey) {
1762
- return this.globalNpmRoot;
1763
- }
1764
- if (this.getPackageManagerName() === "bun") {
1765
- const binDir = this.runNpmCommandSync(["pm", "bin", "-g"]).trim();
1766
- this.globalNpmRoot = join(dirname(binDir), "install", "global", "node_modules");
1767
- } else {
1768
- this.globalNpmRoot = this.runNpmCommandSync(["root", "-g"]).trim();
1769
- }
1770
- this.globalNpmRootCommandKey = commandKey;
1771
- return this.globalNpmRoot;
1772
- }
1773
-
1774
- private getPnpmGlobalPackagePath(packageName: string): string | undefined {
1775
- if (this.getPackageManagerName() !== "pnpm") {
1776
- return undefined;
1777
- }
1778
-
1779
- const output = this.runNpmCommandSync(["list", "-g", "--depth", "0", "--json"]);
1780
- const entries = JSON.parse(output) as Array<{ dependencies?: Record<string, { path?: string }> }>;
1781
- for (const entry of entries) {
1782
- const path = entry.dependencies?.[packageName]?.path;
1783
- if (path) return path;
1784
- }
1785
- return undefined;
1786
- }
1787
-
1788
- private getManagedNpmInstallPath(source: NpmSource, scope: SourceScope): string {
1789
- if (scope === "temporary") {
1790
- return join(this.getTemporaryDir("npm"), "node_modules", source.name);
1791
- }
1792
- if (scope === "project") {
1793
- this.assertProjectTrustedForScope(scope);
1794
- return join(this.cwd, CONFIG_DIR_NAME, "npm", "node_modules", source.name);
1795
- }
1796
- return join(this.agentDir, "npm", "node_modules", source.name);
1797
- }
1798
-
1799
- private getLegacyGlobalNpmInstallPath(source: NpmSource): string | undefined {
1800
- try {
1801
- return this.getPnpmGlobalPackagePath(source.name) ?? join(this.getGlobalNpmRoot(), source.name);
1802
- } catch {
1803
- return undefined;
1804
- }
1805
- }
1806
-
1807
- private getNpmInstallPath(source: NpmSource, scope: SourceScope): string {
1808
- const managedPath = this.getManagedNpmInstallPath(source, scope);
1809
- if (scope !== "user" || existsSync(managedPath)) {
1810
- return managedPath;
1811
- }
1812
- const legacyPath = this.getLegacyGlobalNpmInstallPath(source);
1813
- return legacyPath && existsSync(legacyPath) ? legacyPath : managedPath;
1814
- }
1815
-
1816
- private getGitInstallPath(source: GitSource, scope: SourceScope): string {
1817
- if (scope === "temporary") {
1818
- return this.getTemporaryDir(`git-${source.host}`, source.path);
1819
- }
1820
- const installRoot = this.getGitInstallRoot(scope);
1821
- if (!installRoot) {
1822
- throw new Error("Missing git install root");
1823
- }
1824
- return this.resolveManagedPath(installRoot, source.host, source.path);
1825
- }
1826
-
1827
- private getGitInstallRoot(scope: SourceScope): string | undefined {
1828
- if (scope === "temporary") {
1829
- return undefined;
1830
- }
1831
- if (scope === "project") {
1832
- this.assertProjectTrustedForScope(scope);
1833
- return join(this.cwd, CONFIG_DIR_NAME, "git");
1834
- }
1835
- return join(this.agentDir, "git");
1836
- }
1837
-
1838
- private getTemporaryDir(prefix: string, suffix?: string): string {
1839
- const root = this.resolveManagedPath(getExtensionTempFolder(this.agentDir), prefix);
1840
- const hash = createHash("sha256")
1841
- .update(`${prefix}-${suffix ?? ""}`)
1842
- .digest("hex")
1843
- .slice(0, 8);
1844
- return this.resolveManagedPath(root, hash, suffix ?? "");
1845
- }
1846
-
1847
- private resolveManagedPath(root: string, ...parts: string[]): string {
1848
- const resolvedRoot = resolve(root);
1849
- const resolvedPath = resolve(resolvedRoot, ...parts);
1850
- if (resolvedPath !== resolvedRoot && !resolvedPath.startsWith(`${resolvedRoot}${sep}`)) {
1851
- throw new Error(`Refusing to use path outside package install root: ${resolvedPath}`);
1852
- }
1853
- return resolvedPath;
1854
- }
1855
-
1856
- private getBaseDirForScope(scope: SourceScope): string {
1857
- if (scope === "project") {
1858
- this.assertProjectTrustedForScope(scope);
1859
- return join(this.cwd, CONFIG_DIR_NAME);
1860
- }
1861
- if (scope === "user") {
1862
- return this.agentDir;
1863
- }
1864
- return this.cwd;
1865
- }
1866
-
1867
- private resolvePath(input: string): string {
1868
- return resolvePath(input, this.cwd, { homeDir: getHomeDir(), trim: true });
1869
- }
1870
-
1871
- private resolvePathFromBase(input: string, baseDir: string): string {
1872
- return resolvePath(input, baseDir, { homeDir: getHomeDir(), trim: true });
1873
- }
1874
-
1875
- private collectPackageResources(
1876
- packageRoot: string,
1877
- accumulator: ResourceAccumulator,
1878
- filter: PackageFilter | undefined,
1879
- metadata: PathMetadata,
1880
- ): boolean {
1881
- if (filter) {
1882
- for (const resourceType of RESOURCE_TYPES) {
1883
- const patterns = filter[resourceType];
1884
- const target = this.getTargetMap(accumulator, resourceType);
1885
- if (filter.autoload === false) {
1886
- this.applyPackageDeltaFilter(packageRoot, patterns ?? [], resourceType, target, metadata);
1887
- } else if (patterns !== undefined) {
1888
- this.applyPackageFilter(packageRoot, patterns, resourceType, target, metadata);
1889
- } else {
1890
- this.collectDefaultResources(packageRoot, resourceType, target, metadata);
1891
- }
1892
- }
1893
- return true;
1894
- }
1895
-
1896
- const manifest = this.readAgentManifest(packageRoot);
1897
- if (manifest) {
1898
- for (const resourceType of RESOURCE_TYPES) {
1899
- const entries = manifest[resourceType as keyof AgentManifest];
1900
- this.addManifestEntries(
1901
- entries,
1902
- packageRoot,
1903
- resourceType,
1904
- this.getTargetMap(accumulator, resourceType),
1905
- metadata,
1906
- );
1907
- }
1908
- return true;
1909
- }
1910
-
1911
- let hasAnyDir = false;
1912
- for (const resourceType of RESOURCE_TYPES) {
1913
- const dir = join(packageRoot, resourceType);
1914
- if (existsSync(dir)) {
1915
- // Collect all files from the directory (all enabled by default)
1916
- const files = collectResourceFiles(dir, resourceType);
1917
- for (const f of files) {
1918
- this.addResource(this.getTargetMap(accumulator, resourceType), f, metadata, true);
1919
- }
1920
- hasAnyDir = true;
1921
- }
1922
- }
1923
- return hasAnyDir;
1924
- }
1925
-
1926
- private collectDefaultResources(
1927
- packageRoot: string,
1928
- resourceType: ResourceType,
1929
- target: Map<string, { metadata: PathMetadata; enabled: boolean }>,
1930
- metadata: PathMetadata,
1931
- ): void {
1932
- const manifest = this.readAgentManifest(packageRoot);
1933
- const entries = manifest?.[resourceType as keyof AgentManifest];
1934
- if (entries) {
1935
- this.addManifestEntries(entries, packageRoot, resourceType, target, metadata);
1936
- return;
1937
- }
1938
- const dir = join(packageRoot, resourceType);
1939
- if (existsSync(dir)) {
1940
- // Collect all files from the directory (all enabled by default)
1941
- const files = collectResourceFiles(dir, resourceType);
1942
- for (const f of files) {
1943
- this.addResource(target, f, metadata, true);
1944
- }
1945
- }
1946
- }
1947
-
1948
- private applyPackageFilter(
1949
- packageRoot: string,
1950
- userPatterns: string[],
1951
- resourceType: ResourceType,
1952
- target: Map<string, { metadata: PathMetadata; enabled: boolean }>,
1953
- metadata: PathMetadata,
1954
- ): void {
1955
- const { allFiles } = this.collectManifestFiles(packageRoot, resourceType);
1956
-
1957
- if (userPatterns.length === 0) {
1958
- // Empty array explicitly disables all resources of this type
1959
- for (const f of allFiles) {
1960
- this.addResource(target, f, metadata, false);
1961
- }
1962
- return;
1963
- }
1964
-
1965
- // Apply user patterns
1966
- const enabledByUser = applyPatterns(allFiles, userPatterns, packageRoot);
1967
-
1968
- for (const f of allFiles) {
1969
- const enabled = enabledByUser.has(f);
1970
- this.addResource(target, f, metadata, enabled);
1971
- }
1972
- }
1973
-
1974
- private applyPackageDeltaFilter(
1975
- packageRoot: string,
1976
- userPatterns: string[],
1977
- resourceType: ResourceType,
1978
- target: Map<string, { metadata: PathMetadata; enabled: boolean }>,
1979
- metadata: PathMetadata,
1980
- ): void {
1981
- if (userPatterns.length === 0) {
1982
- return;
1983
- }
1984
-
1985
- const { allFiles } = this.collectManifestFiles(packageRoot, resourceType);
1986
- const enabledByUser = applyAutoloadDisabledPatterns(allFiles, userPatterns, packageRoot);
1987
- for (const [filePath, enabled] of enabledByUser) {
1988
- this.addResource(target, filePath, metadata, enabled);
1989
- }
1990
- }
1991
-
1992
- /**
1993
- * Collect all files from a package for a resource type, applying manifest patterns.
1994
- * Returns { allFiles, enabledByManifest } where enabledByManifest is the set of files
1995
- * that pass the manifest's own patterns.
1996
- */
1997
- private collectManifestFiles(
1998
- packageRoot: string,
1999
- resourceType: ResourceType,
2000
- ): { allFiles: string[]; enabledByManifest: Set<string> } {
2001
- const manifest = this.readAgentManifest(packageRoot);
2002
- const entries = manifest?.[resourceType as keyof AgentManifest];
2003
- if (entries && entries.length > 0) {
2004
- const allFiles = this.collectFilesFromManifestEntries(entries, packageRoot, resourceType);
2005
- const manifestPatterns = entries.filter(isOverridePattern);
2006
- const enabledByManifest =
2007
- manifestPatterns.length > 0 ? applyPatterns(allFiles, manifestPatterns, packageRoot) : new Set(allFiles);
2008
- return { allFiles: Array.from(enabledByManifest), enabledByManifest };
2009
- }
2010
-
2011
- const conventionDir = join(packageRoot, resourceType);
2012
- if (!existsSync(conventionDir)) {
2013
- return { allFiles: [], enabledByManifest: new Set() };
2014
- }
2015
- const allFiles = collectResourceFiles(conventionDir, resourceType);
2016
- return { allFiles, enabledByManifest: new Set(allFiles) };
2017
- }
2018
-
2019
- private readAgentManifest(packageRoot: string): AgentManifest | null {
2020
- const packageJsonPath = join(packageRoot, "package.json");
2021
- if (!existsSync(packageJsonPath)) {
2022
- return null;
2023
- }
2024
-
2025
- try {
2026
- const content = readFileSync(packageJsonPath, "utf-8");
2027
- const pkg = JSON.parse(content) as { agent?: AgentManifest };
2028
- return pkg.agent ?? null;
2029
- } catch {
2030
- return null;
2031
- }
2032
- }
2033
-
2034
- private addManifestEntries(
2035
- entries: string[] | undefined,
2036
- root: string,
2037
- resourceType: ResourceType,
2038
- target: Map<string, { metadata: PathMetadata; enabled: boolean }>,
2039
- metadata: PathMetadata,
2040
- ): void {
2041
- if (!entries) return;
2042
-
2043
- const allFiles = this.collectFilesFromManifestEntries(entries, root, resourceType);
2044
- const patterns = entries.filter(isOverridePattern);
2045
- const enabledPaths = applyPatterns(allFiles, patterns, root);
2046
-
2047
- for (const f of allFiles) {
2048
- if (enabledPaths.has(f)) {
2049
- this.addResource(target, f, metadata, true);
2050
- }
2051
- }
2052
- }
2053
-
2054
- private collectFilesFromManifestEntries(entries: string[], root: string, resourceType: ResourceType): string[] {
2055
- const sourceEntries = entries.filter((entry) => !isOverridePattern(entry));
2056
- const resolved = sourceEntries.flatMap((entry) => {
2057
- if (!hasGlobPattern(entry)) {
2058
- return [resolve(root, entry)];
2059
- }
2060
-
2061
- return globSync(entry, {
2062
- cwd: root,
2063
- absolute: true,
2064
- dot: false,
2065
- nodir: false,
2066
- }).map((match) => resolve(match));
2067
- });
2068
- return this.collectFilesFromPaths(resolved, resourceType);
2069
- }
2070
-
2071
- private resolveLocalEntries(
2072
- entries: string[],
2073
- resourceType: ResourceType,
2074
- target: Map<string, { metadata: PathMetadata; enabled: boolean }>,
2075
- metadata: PathMetadata,
2076
- baseDir: string,
2077
- ): void {
2078
- if (entries.length === 0) return;
2079
-
2080
- // Collect all files from plain entries (non-pattern entries)
2081
- const { plain, patterns } = splitPatterns(entries);
2082
- const resolvedPlain = plain.map((p) => this.resolvePathFromBase(p, baseDir));
2083
- const allFiles = this.collectFilesFromPaths(resolvedPlain, resourceType);
2084
-
2085
- // Determine which files are enabled based on patterns
2086
- const enabledPaths = applyPatterns(allFiles, patterns, baseDir);
2087
-
2088
- // Add all files with their enabled state
2089
- for (const f of allFiles) {
2090
- this.addResource(target, f, metadata, enabledPaths.has(f));
2091
- }
2092
- }
2093
-
2094
- private addAutoDiscoveredResources(
2095
- accumulator: ResourceAccumulator,
2096
- globalSettings: ReturnType<SettingsManager["getGlobalSettings"]>,
2097
- projectSettings: ReturnType<SettingsManager["getProjectSettings"]>,
2098
- globalBaseDir: string,
2099
- projectBaseDir: string,
2100
- ): void {
2101
- const userMetadata: PathMetadata = {
2102
- source: "auto",
2103
- scope: "user",
2104
- origin: "top-level",
2105
- baseDir: globalBaseDir,
2106
- };
2107
- const projectMetadata: PathMetadata = {
2108
- source: "auto",
2109
- scope: "project",
2110
- origin: "top-level",
2111
- baseDir: projectBaseDir,
2112
- };
2113
-
2114
- const userOverrides = {
2115
- extensions: (globalSettings.extensions ?? []) as string[],
2116
- skills: (globalSettings.skills ?? []) as string[],
2117
- prompts: (globalSettings.prompts ?? []) as string[],
2118
- themes: (globalSettings.themes ?? []) as string[],
2119
- };
2120
- const projectOverrides = {
2121
- extensions: (projectSettings.extensions ?? []) as string[],
2122
- skills: (projectSettings.skills ?? []) as string[],
2123
- prompts: (projectSettings.prompts ?? []) as string[],
2124
- themes: (projectSettings.themes ?? []) as string[],
2125
- };
2126
-
2127
- const userDirs = {
2128
- extensions: join(globalBaseDir, "extensions"),
2129
- skills: join(globalBaseDir, "skills"),
2130
- prompts: join(globalBaseDir, "prompts"),
2131
- themes: join(globalBaseDir, "themes"),
2132
- };
2133
- const projectDirs = {
2134
- extensions: join(projectBaseDir, "extensions"),
2135
- skills: join(projectBaseDir, "skills"),
2136
- prompts: join(projectBaseDir, "prompts"),
2137
- themes: join(projectBaseDir, "themes"),
2138
- };
2139
- const userAgentsSkillsDir = join(getHomeDir(), ".agents", "skills");
2140
- const projectTrusted = this.settingsManager.isProjectTrusted();
2141
- const projectAgentsSkillDirs = projectTrusted
2142
- ? collectAncestorAgentsSkillDirs(this.cwd).filter((dir) => resolve(dir) !== resolve(userAgentsSkillsDir))
2143
- : [];
2144
-
2145
- const addResources = (
2146
- resourceType: ResourceType,
2147
- paths: string[],
2148
- metadata: PathMetadata,
2149
- overrides: string[],
2150
- baseDir: string,
2151
- ) => {
2152
- const target = this.getTargetMap(accumulator, resourceType);
2153
- for (const path of paths) {
2154
- const enabled = isEnabledByOverrides(path, overrides, baseDir);
2155
- this.addResource(target, path, metadata, enabled);
2156
- }
2157
- };
2158
-
2159
- if (projectTrusted) {
2160
- // Project extensions from the project config dir
2161
- addResources(
2162
- "extensions",
2163
- collectAutoExtensionEntries(projectDirs.extensions),
2164
- projectMetadata,
2165
- projectOverrides.extensions,
2166
- projectBaseDir,
2167
- );
2168
-
2169
- // Project skills from the project config dir
2170
- addResources(
2171
- "skills",
2172
- collectAutoSkillEntries(projectDirs.skills, "native"),
2173
- projectMetadata,
2174
- projectOverrides.skills,
2175
- projectBaseDir,
2176
- );
2177
- }
2178
-
2179
- // Project skills from .agents/ (each with its own baseDir)
2180
- for (const agentsSkillsDir of projectAgentsSkillDirs) {
2181
- const agentsBaseDir = dirname(agentsSkillsDir); // the .agents directory
2182
- const agentsMetadata: PathMetadata = {
2183
- ...projectMetadata,
2184
- baseDir: agentsBaseDir,
2185
- };
2186
- addResources(
2187
- "skills",
2188
- collectAutoSkillEntries(agentsSkillsDir, "agents"),
2189
- agentsMetadata,
2190
- projectOverrides.skills,
2191
- agentsBaseDir,
2192
- );
2193
- }
2194
-
2195
- if (projectTrusted) {
2196
- addResources(
2197
- "prompts",
2198
- collectAutoPromptEntries(projectDirs.prompts),
2199
- projectMetadata,
2200
- projectOverrides.prompts,
2201
- projectBaseDir,
2202
- );
2203
- addResources(
2204
- "themes",
2205
- collectAutoThemeEntries(projectDirs.themes),
2206
- projectMetadata,
2207
- projectOverrides.themes,
2208
- projectBaseDir,
2209
- );
2210
- }
2211
-
2212
- // User extensions from the user config dir
2213
- addResources(
2214
- "extensions",
2215
- collectAutoExtensionEntries(userDirs.extensions),
2216
- userMetadata,
2217
- userOverrides.extensions,
2218
- globalBaseDir,
2219
- );
2220
-
2221
- // User skills from the user config dir
2222
- addResources(
2223
- "skills",
2224
- collectAutoSkillEntries(userDirs.skills, "native"),
2225
- userMetadata,
2226
- userOverrides.skills,
2227
- globalBaseDir,
2228
- );
2229
-
2230
- // User skills from ~/.agents/ (with its own baseDir)
2231
- const userAgentsBaseDir = dirname(userAgentsSkillsDir);
2232
- const userAgentsMetadata: PathMetadata = {
2233
- ...userMetadata,
2234
- baseDir: userAgentsBaseDir,
2235
- };
2236
- addResources(
2237
- "skills",
2238
- collectAutoSkillEntries(userAgentsSkillsDir, "agents"),
2239
- userAgentsMetadata,
2240
- userOverrides.skills,
2241
- userAgentsBaseDir,
2242
- );
2243
-
2244
- addResources(
2245
- "prompts",
2246
- collectAutoPromptEntries(userDirs.prompts),
2247
- userMetadata,
2248
- userOverrides.prompts,
2249
- globalBaseDir,
2250
- );
2251
- addResources(
2252
- "themes",
2253
- collectAutoThemeEntries(userDirs.themes),
2254
- userMetadata,
2255
- userOverrides.themes,
2256
- globalBaseDir,
2257
- );
2258
- }
2259
-
2260
- private collectFilesFromPaths(paths: string[], resourceType: ResourceType): string[] {
2261
- const files: string[] = [];
2262
- for (const p of paths) {
2263
- if (!existsSync(p)) continue;
2264
-
2265
- try {
2266
- const stats = statSync(p);
2267
- if (stats.isFile()) {
2268
- files.push(p);
2269
- } else if (stats.isDirectory()) {
2270
- files.push(...collectResourceFiles(p, resourceType));
2271
- }
2272
- } catch {
2273
- // Ignore errors
2274
- }
2275
- }
2276
- return files;
2277
- }
2278
-
2279
- private getTargetMap(
2280
- accumulator: ResourceAccumulator,
2281
- resourceType: ResourceType,
2282
- ): Map<string, { metadata: PathMetadata; enabled: boolean }> {
2283
- switch (resourceType) {
2284
- case "extensions":
2285
- return accumulator.extensions;
2286
- case "skills":
2287
- return accumulator.skills;
2288
- case "prompts":
2289
- return accumulator.prompts;
2290
- case "themes":
2291
- return accumulator.themes;
2292
- default:
2293
- throw new Error(`Unknown resource type: ${resourceType}`);
2294
- }
2295
- }
2296
-
2297
- private addResource(
2298
- map: Map<string, { metadata: PathMetadata; enabled: boolean }>,
2299
- path: string,
2300
- metadata: PathMetadata,
2301
- enabled: boolean,
2302
- ): void {
2303
- if (!path) return;
2304
- if (!map.has(path)) {
2305
- map.set(path, { metadata, enabled });
2306
- }
2307
- }
2308
-
2309
- private createAccumulator(): ResourceAccumulator {
2310
- return {
2311
- extensions: new Map(),
2312
- skills: new Map(),
2313
- prompts: new Map(),
2314
- themes: new Map(),
2315
- };
2316
- }
2317
-
2318
- private toResolvedPaths(accumulator: ResourceAccumulator): ResolvedPaths {
2319
- const mapToResolved = (
2320
- entries: Map<string, { metadata: PathMetadata; enabled: boolean }>,
2321
- ): ResolvedResource[] => {
2322
- const resolved = Array.from(entries.entries()).map(([path, { metadata, enabled }]) => ({
2323
- path,
2324
- enabled,
2325
- metadata,
2326
- }));
2327
- resolved.sort((a, b) => resourcePrecedenceRank(a.metadata) - resourcePrecedenceRank(b.metadata));
2328
-
2329
- const seen = new Set<string>();
2330
- return resolved.filter((entry) => {
2331
- const canonicalPath = canonicalizePath(entry.path);
2332
- if (seen.has(canonicalPath)) return false;
2333
- seen.add(canonicalPath);
2334
- return true;
2335
- });
2336
- };
2337
-
2338
- return {
2339
- extensions: mapToResolved(accumulator.extensions),
2340
- skills: mapToResolved(accumulator.skills),
2341
- prompts: mapToResolved(accumulator.prompts),
2342
- themes: mapToResolved(accumulator.themes),
2343
- };
2344
- }
2345
-
2346
- private spawnCommand(command: string, args: string[], options?: { cwd?: string }): ChildProcess {
2347
- const env = getEnv();
2348
- return spawnProcess(command, args, {
2349
- cwd: options?.cwd,
2350
- stdio: isStdoutTakenOver() ? ["ignore", 2, 2] : "inherit",
2351
- env,
2352
- });
2353
- }
2354
-
2355
- private spawnCaptureCommand(
2356
- command: string,
2357
- args: string[],
2358
- options?: { cwd?: string; env?: Record<string, string> },
2359
- ): ChildProcessByStdio<null, Readable, Readable> {
2360
- const baseEnv = getEnv();
2361
- const env = options?.env ? { ...baseEnv, ...options.env } : baseEnv;
2362
- return spawnProcess(command, args, {
2363
- cwd: options?.cwd,
2364
- stdio: ["ignore", "pipe", "pipe"],
2365
- env,
2366
- });
2367
- }
2368
-
2369
- private runCommandCapture(
2370
- command: string,
2371
- args: string[],
2372
- options?: { cwd?: string; timeoutMs?: number; env?: Record<string, string> },
2373
- ): Promise<string> {
2374
- return new Promise((resolvePromise, reject) => {
2375
- const child = this.spawnCaptureCommand(command, args, options);
2376
- let stdout = "";
2377
- let stderr = "";
2378
- let timedOut = false;
2379
- const timeout =
2380
- typeof options?.timeoutMs === "number"
2381
- ? setTimeout(() => {
2382
- timedOut = true;
2383
- child.kill();
2384
- }, options.timeoutMs)
2385
- : undefined;
2386
-
2387
- child.stdout?.on("data", (data) => {
2388
- stdout += data.toString();
2389
- });
2390
- child.stderr?.on("data", (data) => {
2391
- stderr += data.toString();
2392
- });
2393
- child.once("error", (error) => {
2394
- if (timeout) clearTimeout(timeout);
2395
- reject(error);
2396
- });
2397
- child.once("close", (code, signal) => {
2398
- if (timeout) clearTimeout(timeout);
2399
- if (timedOut) {
2400
- reject(new Error(`${command} ${args.join(" ")} timed out after ${options?.timeoutMs}ms`));
2401
- return;
2402
- }
2403
- if (code === 0) {
2404
- resolvePromise(stdout.trim());
2405
- return;
2406
- }
2407
- const exitStatus = code === null ? `signal ${signal ?? "unknown"}` : `code ${code}`;
2408
- reject(new Error(`${command} ${args.join(" ")} failed with ${exitStatus}: ${stderr || stdout}`));
2409
- });
2410
- });
2411
- }
2412
-
2413
- private runCommand(command: string, args: string[], options?: { cwd?: string }): Promise<void> {
2414
- return new Promise((resolvePromise, reject) => {
2415
- const child = this.spawnCommand(command, args, options);
2416
- child.on("error", reject);
2417
- child.on("exit", (code) => {
2418
- if (code === 0) {
2419
- resolvePromise();
2420
- } else {
2421
- reject(new Error(`${command} ${args.join(" ")} failed with code ${code}`));
2422
- }
2423
- });
2424
- });
2425
- }
2426
-
2427
- private runCommandSync(command: string, args: string[]): string {
2428
- const env = getEnv();
2429
- const result = spawnProcessSync(command, args, {
2430
- stdio: ["ignore", "pipe", "pipe"],
2431
- encoding: "utf-8",
2432
- env,
2433
- });
2434
- if (result.error || result.status !== 0) {
2435
- throw new Error(
2436
- `Failed to run ${command} ${args.join(" ")}: ${result.error?.message || result.stderr || result.stdout}`,
2437
- );
2438
- }
2439
- return (result.stdout || result.stderr || "").trim();
2440
- }
2441
- }