@schlenkr/ragents 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (788) hide show
  1. package/LICENSE +166 -0
  2. package/README.md +88 -0
  3. package/apps/server/agent-home/settings.json +3 -0
  4. package/apps/server/package.json +29 -0
  5. package/apps/server/src/access-projection.ts +97 -0
  6. package/apps/server/src/access-service.ts +22 -0
  7. package/apps/server/src/access-session.ts +204 -0
  8. package/apps/server/src/api/contracts.ts +203 -0
  9. package/apps/server/src/api/core-methods.ts +163 -0
  10. package/apps/server/src/api/delivery.ts +40 -0
  11. package/apps/server/src/api/reference.ts +146 -0
  12. package/apps/server/src/api/rights.ts +26 -0
  13. package/apps/server/src/chat-attachments.ts +52 -0
  14. package/apps/server/src/chat-context.ts +6 -0
  15. package/apps/server/src/chat-events.ts +185 -0
  16. package/apps/server/src/chat-handler.ts +37 -0
  17. package/apps/server/src/config-definition.ts +80 -0
  18. package/apps/server/src/config-file.ts +324 -0
  19. package/apps/server/src/config.ts +46 -0
  20. package/apps/server/src/data-directory.ts +42 -0
  21. package/apps/server/src/external-access.ts +40 -0
  22. package/apps/server/src/help-files.ts +63 -0
  23. package/apps/server/src/host-resolution-hooks.mjs +31 -0
  24. package/apps/server/src/host-resolution.ts +3 -0
  25. package/apps/server/src/host-version.ts +74 -0
  26. package/apps/server/src/layout.ts +36 -0
  27. package/apps/server/src/main.ts +54 -0
  28. package/apps/server/src/plugin-support/actor-programs/capability-resolver.ts +107 -0
  29. package/apps/server/src/plugin-support/actor-programs/limits.ts +33 -0
  30. package/apps/server/src/plugin-support/actor-programs/operations.ts +19 -0
  31. package/apps/server/src/plugin-support/actor-programs/service.ts +16 -0
  32. package/apps/server/src/plugin-support/agent-tool.ts +60 -0
  33. package/apps/server/src/plugin-support/asset-path.ts +4 -0
  34. package/apps/server/src/plugin-support/await-with-signal.ts +18 -0
  35. package/apps/server/src/plugin-support/chat-display-contract.ts +7 -0
  36. package/apps/server/src/plugin-support/chat-display-policy.ts +55 -0
  37. package/apps/server/src/plugin-support/front-matter.ts +44 -0
  38. package/apps/server/src/plugin-support/http.ts +93 -0
  39. package/apps/server/src/plugin-support/language-server/contract.ts +18 -0
  40. package/apps/server/src/plugin-support/language-server/plugin.ts +32 -0
  41. package/apps/server/src/plugin-support/language-server/snapshot-method.ts +17 -0
  42. package/apps/server/src/plugin-support/language-server/tools.ts +73 -0
  43. package/apps/server/src/plugin-support/model-choice.ts +109 -0
  44. package/apps/server/src/plugin-support/model-upstreams.ts +12 -0
  45. package/apps/server/src/plugin-support/native-typescript-child.ts +78 -0
  46. package/apps/server/src/plugin-support/native-typescript-executor.ts +260 -0
  47. package/apps/server/src/plugin-support/plugin-config.ts +48 -0
  48. package/apps/server/src/plugin-support/plugin-folder.ts +81 -0
  49. package/apps/server/src/plugin-support/plugin-module.ts +14 -0
  50. package/apps/server/src/plugin-support/plugins-root.ts +41 -0
  51. package/apps/server/src/plugin-support/product-model-settings-contract.ts +24 -0
  52. package/apps/server/src/plugin-support/product-model-settings.ts +120 -0
  53. package/apps/server/src/plugin-support/product-start-options.ts +104 -0
  54. package/apps/server/src/plugin-support/prompt.ts +68 -0
  55. package/apps/server/src/plugin-support/provision.ts +85 -0
  56. package/apps/server/src/plugin-support/run-scripts.ts +88 -0
  57. package/apps/server/src/plugin-support/shell-platform.ts +21 -0
  58. package/apps/server/src/plugin-support/skills.ts +97 -0
  59. package/apps/server/src/plugin-support/start-entries-contract.ts +71 -0
  60. package/apps/server/src/plugin-support/start-options-contract.ts +65 -0
  61. package/apps/server/src/plugin-support/system-prompts.ts +138 -0
  62. package/apps/server/src/plugin-support/thinking-level.ts +8 -0
  63. package/apps/server/src/plugin-support/tool-availability.ts +20 -0
  64. package/apps/server/src/plugin-support/workspace-ownership.ts +36 -0
  65. package/apps/server/src/plugin-support/workspace-sandbox-host.ts +213 -0
  66. package/apps/server/src/plugin-support/workspace-tool-naming.ts +11 -0
  67. package/apps/server/src/plugin-support/zip.ts +69 -0
  68. package/apps/server/src/profile/compose.ts +69 -0
  69. package/apps/server/src/profile/plugin-discovery.ts +112 -0
  70. package/apps/server/src/profile/plugin-list.ts +19 -0
  71. package/apps/server/src/profile/provisioning.ts +81 -0
  72. package/apps/server/src/protocol.ts +106 -0
  73. package/apps/server/src/provider.ts +817 -0
  74. package/apps/server/src/ragents/actor-chat-history.ts +111 -0
  75. package/apps/server/src/ragents/chat-projection.ts +55 -0
  76. package/apps/server/src/ragents/chat-text-positions.ts +43 -0
  77. package/apps/server/src/ragents/coordinator.ts +5 -0
  78. package/apps/server/src/ragents/document-store.ts +12 -0
  79. package/apps/server/src/ragents/engine.ts +417 -0
  80. package/apps/server/src/ragents/global-chat.ts +40 -0
  81. package/apps/server/src/ragents/host-services.ts +26 -0
  82. package/apps/server/src/ragents/journal-chat-events.ts +52 -0
  83. package/apps/server/src/ragents/product-runtime.ts +31 -0
  84. package/apps/server/src/ragents/runtime-bridge.ts +7 -0
  85. package/apps/server/src/ragents/session.ts +859 -0
  86. package/apps/server/src/ragents/start-option-state.ts +37 -0
  87. package/apps/server/src/ragents/typescript-tools.ts +182 -0
  88. package/apps/server/src/ragents/workspace-runtime.ts +64 -0
  89. package/apps/server/src/rpc/dispatcher.ts +178 -0
  90. package/apps/server/src/rpc/http-transport.ts +178 -0
  91. package/apps/server/src/rpc/stdio-transport.ts +44 -0
  92. package/apps/server/src/run-preparation-contract.ts +20 -0
  93. package/apps/server/src/run-preparation-input.ts +16 -0
  94. package/apps/server/src/run-preparation.ts +147 -0
  95. package/apps/server/src/run-transfer.ts +264 -0
  96. package/apps/server/src/server.ts +312 -0
  97. package/apps/server/src/settings.ts +209 -0
  98. package/apps/server/src/startup.ts +13 -0
  99. package/apps/server/src/title-compactor.ts +131 -0
  100. package/apps/server/src/title-settings-contract.ts +9 -0
  101. package/apps/server/src/title-settings.ts +67 -0
  102. package/apps/web/package.json +41 -0
  103. package/apps/web/src/AccessContext.tsx +125 -0
  104. package/apps/web/src/App.tsx +315 -0
  105. package/apps/web/src/CanvasShortcuts.tsx +60 -0
  106. package/apps/web/src/DiffCode.tsx +89 -0
  107. package/apps/web/src/HelpDialog.tsx +87 -0
  108. package/apps/web/src/MaterialSettings.tsx +40 -0
  109. package/apps/web/src/Overview.tsx +201 -0
  110. package/apps/web/src/PluginActivation.ts +41 -0
  111. package/apps/web/src/PluginChat.tsx +552 -0
  112. package/apps/web/src/PluginRegistry.tsx +689 -0
  113. package/apps/web/src/RunPreparationChat.tsx +111 -0
  114. package/apps/web/src/RunStore.ts +86 -0
  115. package/apps/web/src/SessionList.tsx +148 -0
  116. package/apps/web/src/SettingsModal.tsx +949 -0
  117. package/apps/web/src/SourceCode.tsx +49 -0
  118. package/apps/web/src/StartOptions.tsx +231 -0
  119. package/apps/web/src/StartSurface.tsx +161 -0
  120. package/apps/web/src/StatusGroup.tsx +18 -0
  121. package/apps/web/src/ThemeSettings.tsx +46 -0
  122. package/apps/web/src/TitleModelSettings.tsx +100 -0
  123. package/apps/web/src/Toolbar.tsx +28 -0
  124. package/apps/web/src/WorkspacePanel.tsx +309 -0
  125. package/apps/web/src/access-session.ts +27 -0
  126. package/apps/web/src/access-token.ts +31 -0
  127. package/apps/web/src/api.ts +368 -0
  128. package/apps/web/src/chat/ChatInputToolbar.tsx +488 -0
  129. package/apps/web/src/chat/ChatMessages.tsx +666 -0
  130. package/apps/web/src/chat/ChatPanel.tsx +61 -0
  131. package/apps/web/src/chat/DetailModeSwitch.tsx +58 -0
  132. package/apps/web/src/chat/Markdown.tsx +104 -0
  133. package/apps/web/src/chat/QuestionCard.tsx +107 -0
  134. package/apps/web/src/chat/StepPopover.tsx +82 -0
  135. package/apps/web/src/chat/WorkingScenes.tsx +235 -0
  136. package/apps/web/src/chat/attachments.ts +53 -0
  137. package/apps/web/src/chat/chat-scroll.ts +41 -0
  138. package/apps/web/src/chat/chat-target.ts +21 -0
  139. package/apps/web/src/chat/requests.ts +23 -0
  140. package/apps/web/src/chat/texts.ts +61 -0
  141. package/apps/web/src/chat/types.ts +26 -0
  142. package/apps/web/src/chat/useAttachmentCapabilities.ts +35 -0
  143. package/apps/web/src/chat/useChat.ts +46 -0
  144. package/apps/web/src/chat/user-location.ts +22 -0
  145. package/apps/web/src/column/ColumnApp.tsx +158 -0
  146. package/apps/web/src/column/ColumnMenu.tsx +37 -0
  147. package/apps/web/src/column/ColumnRunHeader.tsx +43 -0
  148. package/apps/web/src/column/column-location.ts +30 -0
  149. package/apps/web/src/column/host-contract.ts +83 -0
  150. package/apps/web/src/column/host.ts +101 -0
  151. package/apps/web/src/column/use-session-list.ts +42 -0
  152. package/apps/web/src/column.tsx +43 -0
  153. package/apps/web/src/diff-view.css +38 -0
  154. package/apps/web/src/help-samples.ts +11 -0
  155. package/apps/web/src/highlighting.css +74 -0
  156. package/apps/web/src/highlighting.ts +262 -0
  157. package/apps/web/src/lib/format.ts +5 -0
  158. package/apps/web/src/lib/guards.ts +8 -0
  159. package/apps/web/src/lib/http.ts +9 -0
  160. package/apps/web/src/lib/labels.ts +11 -0
  161. package/apps/web/src/lib/local-storage-setting.ts +39 -0
  162. package/apps/web/src/main.tsx +30 -0
  163. package/apps/web/src/material-settings.ts +104 -0
  164. package/apps/web/src/model-settings-events.ts +1 -0
  165. package/apps/web/src/page-opener.tsx +14 -0
  166. package/apps/web/src/panel/LoginForm.tsx +31 -0
  167. package/apps/web/src/panel/OverviewPage.tsx +90 -0
  168. package/apps/web/src/panel/PanelPage.tsx +9 -0
  169. package/apps/web/src/panel/SettingsPage.tsx +102 -0
  170. package/apps/web/src/panel/contract.ts +101 -0
  171. package/apps/web/src/panel/target-state.ts +53 -0
  172. package/apps/web/src/panel.tsx +30 -0
  173. package/apps/web/src/plugin-bootstrap.ts +90 -0
  174. package/apps/web/src/plugin-discovery.ts +5 -0
  175. package/apps/web/src/rpc/client.ts +301 -0
  176. package/apps/web/src/rpc.ts +4 -0
  177. package/apps/web/src/run-overview.ts +34 -0
  178. package/apps/web/src/run-preparation.ts +16 -0
  179. package/apps/web/src/run-read-state.ts +33 -0
  180. package/apps/web/src/settings-contributions.ts +274 -0
  181. package/apps/web/src/theme.ts +135 -0
  182. package/apps/web/src/title-model-settings.ts +51 -0
  183. package/apps/web/src/toolLine.ts +67 -0
  184. package/apps/web/src/ui/ListDetail.tsx +149 -0
  185. package/apps/web/src/ui/SectionLabel.tsx +7 -0
  186. package/apps/web/src/ui/SvgEdge.tsx +39 -0
  187. package/apps/web/src/ui/alert.tsx +75 -0
  188. package/apps/web/src/ui/badge.tsx +51 -0
  189. package/apps/web/src/ui/button.tsx +57 -0
  190. package/apps/web/src/ui/card.tsx +102 -0
  191. package/apps/web/src/ui/checkbox.tsx +26 -0
  192. package/apps/web/src/ui/dialog.tsx +250 -0
  193. package/apps/web/src/ui/dropdown-menu.tsx +265 -0
  194. package/apps/web/src/ui/empty.tsx +103 -0
  195. package/apps/web/src/ui/field.tsx +236 -0
  196. package/apps/web/src/ui/frame.css +4 -0
  197. package/apps/web/src/ui/index.ts +43 -0
  198. package/apps/web/src/ui/input.tsx +19 -0
  199. package/apps/web/src/ui/label.tsx +17 -0
  200. package/apps/web/src/ui/modal-controller.ts +70 -0
  201. package/apps/web/src/ui/modal.tsx +62 -0
  202. package/apps/web/src/ui/popover.tsx +102 -0
  203. package/apps/web/src/ui/progress.tsx +80 -0
  204. package/apps/web/src/ui/radio-group.tsx +35 -0
  205. package/apps/web/src/ui/select.tsx +198 -0
  206. package/apps/web/src/ui/separator.tsx +22 -0
  207. package/apps/web/src/ui/skeleton.tsx +13 -0
  208. package/apps/web/src/ui/spinner.tsx +10 -0
  209. package/apps/web/src/ui/switch.tsx +29 -0
  210. package/apps/web/src/ui/table.tsx +113 -0
  211. package/apps/web/src/ui/tabs.tsx +79 -0
  212. package/apps/web/src/ui/tailwind.css +21 -0
  213. package/apps/web/src/ui/textarea.tsx +17 -0
  214. package/apps/web/src/ui/theme.css +300 -0
  215. package/apps/web/src/ui/toggle-group.tsx +87 -0
  216. package/apps/web/src/ui/toggle.tsx +42 -0
  217. package/apps/web/src/ui/tooltip.tsx +63 -0
  218. package/apps/web/src/ui/useFileInput.ts +50 -0
  219. package/apps/web/src/virtual-plugins.d.ts +3 -0
  220. package/apps/web/src/vite-env.d.ts +1 -0
  221. package/package.json +82 -0
  222. package/packages/agent/package.json +64 -0
  223. package/packages/agent/src/config.ts +161 -0
  224. package/packages/agent/src/core/agent-session-runtime.ts +548 -0
  225. package/packages/agent/src/core/agent-session-services.ts +224 -0
  226. package/packages/agent/src/core/agent-session.ts +3357 -0
  227. package/packages/agent/src/core/auth-guidance.ts +18 -0
  228. package/packages/agent/src/core/auth-storage.ts +271 -0
  229. package/packages/agent/src/core/bash-executor.ts +156 -0
  230. package/packages/agent/src/core/compaction/branch-summarization.ts +372 -0
  231. package/packages/agent/src/core/compaction/compaction.ts +875 -0
  232. package/packages/agent/src/core/compaction/index.ts +7 -0
  233. package/packages/agent/src/core/compaction/utils.ts +174 -0
  234. package/packages/agent/src/core/defaults.ts +3 -0
  235. package/packages/agent/src/core/diagnostics.ts +15 -0
  236. package/packages/agent/src/core/event-bus.ts +33 -0
  237. package/packages/agent/src/core/exec.ts +107 -0
  238. package/packages/agent/src/core/experimental.ts +3 -0
  239. package/packages/agent/src/core/extensions/index.ts +149 -0
  240. package/packages/agent/src/core/extensions/loader.ts +709 -0
  241. package/packages/agent/src/core/extensions/runner.ts +1132 -0
  242. package/packages/agent/src/core/extensions/types.ts +1460 -0
  243. package/packages/agent/src/core/extensions/wrapper.ts +45 -0
  244. package/packages/agent/src/core/footer-data-provider.ts +388 -0
  245. package/packages/agent/src/core/http-dispatcher.ts +106 -0
  246. package/packages/agent/src/core/index.ts +78 -0
  247. package/packages/agent/src/core/messages.ts +195 -0
  248. package/packages/agent/src/core/model-config.ts +287 -0
  249. package/packages/agent/src/core/model-registry.ts +126 -0
  250. package/packages/agent/src/core/model-resolver.ts +675 -0
  251. package/packages/agent/src/core/model-runtime.ts +517 -0
  252. package/packages/agent/src/core/output-guard.ts +108 -0
  253. package/packages/agent/src/core/package-manager.ts +2441 -0
  254. package/packages/agent/src/core/prompt-templates.ts +284 -0
  255. package/packages/agent/src/core/provider-composer.ts +549 -0
  256. package/packages/agent/src/core/resolve-config-value.ts +287 -0
  257. package/packages/agent/src/core/resource-loader.ts +946 -0
  258. package/packages/agent/src/core/runtime-credentials.ts +48 -0
  259. package/packages/agent/src/core/sdk.ts +358 -0
  260. package/packages/agent/src/core/session-cwd.ts +59 -0
  261. package/packages/agent/src/core/session-manager.ts +1623 -0
  262. package/packages/agent/src/core/settings-manager.ts +1212 -0
  263. package/packages/agent/src/core/skills.ts +487 -0
  264. package/packages/agent/src/core/slash-commands.ts +41 -0
  265. package/packages/agent/src/core/source-info.ts +40 -0
  266. package/packages/agent/src/core/system-prompt.ts +147 -0
  267. package/packages/agent/src/core/timings.ts +50 -0
  268. package/packages/agent/src/core/tools/bash.ts +314 -0
  269. package/packages/agent/src/core/tools/edit-diff.ts +704 -0
  270. package/packages/agent/src/core/tools/edit.ts +222 -0
  271. package/packages/agent/src/core/tools/file-mutation-queue.ts +61 -0
  272. package/packages/agent/src/core/tools/index.ts +130 -0
  273. package/packages/agent/src/core/tools/output-accumulator.ts +222 -0
  274. package/packages/agent/src/core/tools/path-utils.ts +118 -0
  275. package/packages/agent/src/core/tools/read.ts +195 -0
  276. package/packages/agent/src/core/tools/tool-definition-wrapper.ts +45 -0
  277. package/packages/agent/src/core/tools/truncate.ts +276 -0
  278. package/packages/agent/src/core/tools/write.ts +90 -0
  279. package/packages/agent/src/core/trust-manager.ts +244 -0
  280. package/packages/agent/src/index.ts +287 -0
  281. package/packages/agent/src/utils/ansi.ts +60 -0
  282. package/packages/agent/src/utils/child-process.ts +137 -0
  283. package/packages/agent/src/utils/exif-orientation.ts +183 -0
  284. package/packages/agent/src/utils/frontmatter.ts +39 -0
  285. package/packages/agent/src/utils/fs-watch.ts +30 -0
  286. package/packages/agent/src/utils/git.ts +226 -0
  287. package/packages/agent/src/utils/image-convert.ts +49 -0
  288. package/packages/agent/src/utils/image-process.ts +119 -0
  289. package/packages/agent/src/utils/image-resize-core.ts +164 -0
  290. package/packages/agent/src/utils/image-resize-worker.ts +42 -0
  291. package/packages/agent/src/utils/image-resize.ts +123 -0
  292. package/packages/agent/src/utils/json.ts +6 -0
  293. package/packages/agent/src/utils/mime.ts +116 -0
  294. package/packages/agent/src/utils/paths.ts +118 -0
  295. package/packages/agent/src/utils/photon.ts +139 -0
  296. package/packages/agent/src/utils/shell.ts +225 -0
  297. package/packages/agent/src/utils/sleep.ts +18 -0
  298. package/packages/agent/src/utils/tools-manager.ts +63 -0
  299. package/packages/agent-core/package.json +32 -0
  300. package/packages/agent-core/src/agent-loop.ts +877 -0
  301. package/packages/agent-core/src/agent.ts +598 -0
  302. package/packages/agent-core/src/index.ts +4 -0
  303. package/packages/agent-core/src/types.ts +455 -0
  304. package/packages/agent-core/src/uuid.ts +54 -0
  305. package/packages/ai/package.json +46 -0
  306. package/packages/ai/src/api/ai-sdk-messages.ts +102 -0
  307. package/packages/ai/src/api/ai-sdk-transport.ts +53 -0
  308. package/packages/ai/src/api/ai-sdk.lazy.ts +4 -0
  309. package/packages/ai/src/api/ai-sdk.ts +273 -0
  310. package/packages/ai/src/api/lazy.ts +75 -0
  311. package/packages/ai/src/api/openrouter-images.lazy.ts +10 -0
  312. package/packages/ai/src/api/openrouter-images.ts +98 -0
  313. package/packages/ai/src/api/simple-options.ts +77 -0
  314. package/packages/ai/src/api/transform-messages.ts +185 -0
  315. package/packages/ai/src/api-registry.ts +226 -0
  316. package/packages/ai/src/auth/context.ts +45 -0
  317. package/packages/ai/src/auth/credential-store.ts +51 -0
  318. package/packages/ai/src/auth/helpers.ts +47 -0
  319. package/packages/ai/src/auth/resolve.ts +139 -0
  320. package/packages/ai/src/auth/types.ts +220 -0
  321. package/packages/ai/src/compat/extension-oauth-types.ts +45 -0
  322. package/packages/ai/src/env-api-keys.ts +24 -0
  323. package/packages/ai/src/image-models.generated.ts +533 -0
  324. package/packages/ai/src/images-models.ts +274 -0
  325. package/packages/ai/src/index.ts +33 -0
  326. package/packages/ai/src/models-store.ts +38 -0
  327. package/packages/ai/src/models.generated.ts +6 -0
  328. package/packages/ai/src/models.ts +705 -0
  329. package/packages/ai/src/oauth.ts +10 -0
  330. package/packages/ai/src/providers/all.ts +64 -0
  331. package/packages/ai/src/providers/faux.ts +539 -0
  332. package/packages/ai/src/providers/openrouter-images.ts +14 -0
  333. package/packages/ai/src/providers/openrouter.models.ts +6050 -0
  334. package/packages/ai/src/providers/openrouter.ts +15 -0
  335. package/packages/ai/src/session-resources.ts +24 -0
  336. package/packages/ai/src/types.ts +692 -0
  337. package/packages/ai/src/utils/abort-signals.ts +41 -0
  338. package/packages/ai/src/utils/deferred-tools.ts +39 -0
  339. package/packages/ai/src/utils/diagnostics.ts +45 -0
  340. package/packages/ai/src/utils/error-body.ts +129 -0
  341. package/packages/ai/src/utils/estimate.ts +146 -0
  342. package/packages/ai/src/utils/event-stream.ts +88 -0
  343. package/packages/ai/src/utils/hash.ts +13 -0
  344. package/packages/ai/src/utils/headers.ts +18 -0
  345. package/packages/ai/src/utils/json-parse.ts +124 -0
  346. package/packages/ai/src/utils/node-http-proxy.ts +112 -0
  347. package/packages/ai/src/utils/overflow.ts +165 -0
  348. package/packages/ai/src/utils/provider-env.ts +52 -0
  349. package/packages/ai/src/utils/retry.ts +101 -0
  350. package/packages/ai/src/utils/sanitize-unicode.ts +25 -0
  351. package/packages/ai/src/utils/typebox-helpers.ts +24 -0
  352. package/packages/ai/src/utils/validation.ts +383 -0
  353. package/packages/ragents/package.json +31 -0
  354. package/packages/ragents/src/access.ts +54 -0
  355. package/packages/ragents/src/agents/actor-input.ts +191 -0
  356. package/packages/ragents/src/agents/catalog.ts +220 -0
  357. package/packages/ragents/src/agents/delivery.ts +187 -0
  358. package/packages/ragents/src/agents/live.ts +71 -0
  359. package/packages/ragents/src/agents/plugins.ts +130 -0
  360. package/packages/ragents/src/agents/scheduler.ts +1048 -0
  361. package/packages/ragents/src/agents/schemas.ts +64 -0
  362. package/packages/ragents/src/agents/tool-orientation.ts +12 -0
  363. package/packages/ragents/src/agents/tools.ts +709 -0
  364. package/packages/ragents/src/agents/toolset.ts +324 -0
  365. package/packages/ragents/src/agents/turn.ts +65 -0
  366. package/packages/ragents/src/agents/workspace-tools.ts +11 -0
  367. package/packages/ragents/src/agents/workspaces.ts +15 -0
  368. package/packages/ragents/src/domain/draft.ts +11 -0
  369. package/packages/ragents/src/domain/driver.ts +56 -0
  370. package/packages/ragents/src/domain/event-semantics.ts +668 -0
  371. package/packages/ragents/src/domain/event-validation.ts +620 -0
  372. package/packages/ragents/src/domain/events.ts +236 -0
  373. package/packages/ragents/src/domain/json-patch.ts +77 -0
  374. package/packages/ragents/src/domain/json.ts +86 -0
  375. package/packages/ragents/src/domain/model.ts +267 -0
  376. package/packages/ragents/src/domain/plugin-state.ts +33 -0
  377. package/packages/ragents/src/domain/portable-id.ts +9 -0
  378. package/packages/ragents/src/domain/projection.ts +506 -0
  379. package/packages/ragents/src/domain/schema-errors.ts +56 -0
  380. package/packages/ragents/src/domain/vocabulary.ts +37 -0
  381. package/packages/ragents/src/drivers/agent-runtime.ts +1503 -0
  382. package/packages/ragents/src/drivers/agent.ts +108 -0
  383. package/packages/ragents/src/drivers/attachments.ts +56 -0
  384. package/packages/ragents/src/drivers/skill-preload.ts +205 -0
  385. package/packages/ragents/src/drivers/types.ts +77 -0
  386. package/packages/ragents/src/http/contracts.ts +80 -0
  387. package/packages/ragents/src/http/methods.ts +150 -0
  388. package/packages/ragents/src/index.ts +161 -0
  389. package/packages/ragents/src/plugin-host.ts +1184 -0
  390. package/packages/ragents/src/plugin-types.ts +373 -0
  391. package/packages/ragents/src/rpc/contract.ts +76 -0
  392. package/packages/ragents/src/rpc/contribution.ts +67 -0
  393. package/packages/ragents/src/rpc/peer.ts +208 -0
  394. package/packages/ragents/src/rpc/protocol.ts +129 -0
  395. package/packages/ragents/src/runtime/artifacts.ts +95 -0
  396. package/packages/ragents/src/runtime/canonical-hash.ts +5 -0
  397. package/packages/ragents/src/runtime/canonical-json.ts +41 -0
  398. package/packages/ragents/src/runtime/command.ts +35 -0
  399. package/packages/ragents/src/runtime/decisions/actions.ts +77 -0
  400. package/packages/ragents/src/runtime/decisions/actors.ts +283 -0
  401. package/packages/ragents/src/runtime/decisions/artifacts.ts +28 -0
  402. package/packages/ragents/src/runtime/decisions/inputs.ts +79 -0
  403. package/packages/ragents/src/runtime/decisions/subscriptions.ts +135 -0
  404. package/packages/ragents/src/runtime/decisions/turns.ts +166 -0
  405. package/packages/ragents/src/runtime/domain-error.ts +10 -0
  406. package/packages/ragents/src/runtime/durable-fs.ts +13 -0
  407. package/packages/ragents/src/runtime/failures.ts +18 -0
  408. package/packages/ragents/src/runtime/guards.ts +196 -0
  409. package/packages/ragents/src/runtime/journal-storage.ts +228 -0
  410. package/packages/ragents/src/runtime/journal.ts +952 -0
  411. package/packages/ragents/src/runtime/orchestration.ts +711 -0
  412. package/packages/ragents/src/runtime/serial-queue.ts +13 -0
  413. package/packages/ragents/src/runtime/services.ts +15 -0
  414. package/packages/ragents/src/runtime/stop.ts +186 -0
  415. package/packages/ragents/src/script/driver.ts +18 -0
  416. package/packages/ragents/src/script/mediators.ts +386 -0
  417. package/packages/ragents/src/script/programs.ts +10 -0
  418. package/packages/ragents/src/script/std.ts +27 -0
  419. package/packages/ragents/src/script/types.ts +6 -0
  420. package/packages/ragents/src/typescript/async-compiler.ts +322 -0
  421. package/packages/ragents/src/typescript/build-contract.ts +14 -0
  422. package/packages/ragents/src/typescript/compiler-worker.ts +52 -0
  423. package/packages/ragents/src/typescript/compiler.ts +304 -0
  424. package/packages/ragents/src/typescript/index.ts +48 -0
  425. package/packages/ragents/src/typescript/native-executor.ts +40 -0
  426. package/packages/ragents/src/typescript/native-program.ts +5 -0
  427. package/packages/ragents/src/typescript/run-context.ts +199 -0
  428. package/packages/ragents/src/typescript/schema.ts +176 -0
  429. package/packages/ragents/src/typescript/snippet.ts +121 -0
  430. package/packages/workspace-executor/package.json +25 -0
  431. package/packages/workspace-executor/src/context.ts +123 -0
  432. package/packages/workspace-executor/src/executor.ts +134 -0
  433. package/packages/workspace-executor/src/git-config-environment.ts +10 -0
  434. package/packages/workspace-executor/src/index.ts +52 -0
  435. package/packages/workspace-executor/src/language-server/adapters/fsharp.ts +59 -0
  436. package/packages/workspace-executor/src/language-server/adapters/index.ts +7 -0
  437. package/packages/workspace-executor/src/language-server/adapters/roslyn.ts +54 -0
  438. package/packages/workspace-executor/src/language-server/adapters/typescript.ts +46 -0
  439. package/packages/workspace-executor/src/language-server/contract.ts +23 -0
  440. package/packages/workspace-executor/src/language-server/diagnostics.ts +62 -0
  441. package/packages/workspace-executor/src/language-server/host.ts +409 -0
  442. package/packages/workspace-executor/src/language-server/json-rpc.ts +103 -0
  443. package/packages/workspace-executor/src/language-server/roots.ts +29 -0
  444. package/packages/workspace-executor/src/language-server/session.ts +442 -0
  445. package/packages/workspace-executor/src/language-server/solution.ts +13 -0
  446. package/packages/workspace-executor/src/managed-process.ts +329 -0
  447. package/packages/workspace-executor/src/paths.ts +43 -0
  448. package/packages/workspace-executor/src/run-marker.ts +6 -0
  449. package/packages/workspace-executor/src/safe-environment.ts +47 -0
  450. package/packages/workspace-executor/src/sandbox-tools.ts +258 -0
  451. package/packages/workspace-executor/src/session-ident.ts +37 -0
  452. package/packages/workspace-executor/src/shell-platform.ts +11 -0
  453. package/packages/workspace-executor/src/tools.ts +28 -0
  454. package/plugins/package.json +8 -0
  455. package/plugins/ragents.activity/server/index.ts +9 -0
  456. package/plugins/ragents.activity/web/ActivityHeader.tsx +58 -0
  457. package/plugins/ragents.activity/web/activity.ts +144 -0
  458. package/plugins/ragents.activity/web/index.tsx +13 -0
  459. package/plugins/ragents.actor-programs/client-ui/DataTable.tsx +100 -0
  460. package/plugins/ragents.actor-programs/client-ui/FilePicker.tsx +65 -0
  461. package/plugins/ragents.actor-programs/client-ui/FlowDiagram.tsx +234 -0
  462. package/plugins/ragents.actor-programs/client-ui/FlowDiagramRenderer.tsx +85 -0
  463. package/plugins/ragents.actor-programs/client-ui/Form.tsx +126 -0
  464. package/plugins/ragents.actor-programs/client-ui/Layout.tsx +27 -0
  465. package/plugins/ragents.actor-programs/client-ui/MessageList.tsx +30 -0
  466. package/plugins/ragents.actor-programs/client-ui/Viewers.tsx +41 -0
  467. package/plugins/ragents.actor-programs/client-ui/WorkflowDiagram.tsx +14 -0
  468. package/plugins/ragents.actor-programs/client-ui/contracts.d.ts +84 -0
  469. package/plugins/ragents.actor-programs/client-ui/file-contracts.d.ts +19 -0
  470. package/plugins/ragents.actor-programs/client-ui/file-selection.ts +24 -0
  471. package/plugins/ragents.actor-programs/client-ui/flow-diagram-contracts.d.ts +27 -0
  472. package/plugins/ragents.actor-programs/client-ui/flow-diagram.css +23 -0
  473. package/plugins/ragents.actor-programs/client-ui/form-contracts.d.ts +38 -0
  474. package/plugins/ragents.actor-programs/client-ui/frame-layout.ts +4 -0
  475. package/plugins/ragents.actor-programs/client-ui/index.tsx +81 -0
  476. package/plugins/ragents.actor-programs/client-ui/layout-contracts.d.ts +33 -0
  477. package/plugins/ragents.actor-programs/client-ui/message-list-contracts.d.ts +33 -0
  478. package/plugins/ragents.actor-programs/client-ui/table-contracts.d.ts +35 -0
  479. package/plugins/ragents.actor-programs/client-ui/viewer-contracts.d.ts +37 -0
  480. package/plugins/ragents.actor-programs/client-ui/workflow-diagram-contracts.d.ts +10 -0
  481. package/plugins/ragents.actor-programs/contract.ts +180 -0
  482. package/plugins/ragents.actor-programs/parameter-types.ts +3 -0
  483. package/plugins/ragents.actor-programs/prompt.hbs +79 -0
  484. package/plugins/ragents.actor-programs/server/agent-tools.ts +31 -0
  485. package/plugins/ragents.actor-programs/server/app-project.ts +284 -0
  486. package/plugins/ragents.actor-programs/server/authoring-contracts.ts +10 -0
  487. package/plugins/ragents.actor-programs/server/client-compiler.ts +174 -0
  488. package/plugins/ragents.actor-programs/server/client-contracts.ts +187 -0
  489. package/plugins/ragents.actor-programs/server/client-runtime.ts +16 -0
  490. package/plugins/ragents.actor-programs/server/controls-template.ts +118 -0
  491. package/plugins/ragents.actor-programs/server/controls-tool.ts +48 -0
  492. package/plugins/ragents.actor-programs/server/index.ts +51 -0
  493. package/plugins/ragents.actor-programs/server/methods.ts +72 -0
  494. package/plugins/ragents.actor-programs/server/project-diagnostics.ts +138 -0
  495. package/plugins/ragents.actor-programs/server/prompts.ts +21 -0
  496. package/plugins/ragents.actor-programs/server/routes.ts +235 -0
  497. package/plugins/ragents.actor-programs/server/runtime-libraries.ts +4 -0
  498. package/plugins/ragents.actor-programs/server/runtime.ts +721 -0
  499. package/plugins/ragents.actor-programs/server/tailwind.ts +22 -0
  500. package/plugins/ragents.actor-programs/server/templates.ts +400 -0
  501. package/plugins/ragents.actor-programs/server/tool-contributor.ts +29 -0
  502. package/plugins/ragents.actor-programs/summary.hbs +17 -0
  503. package/plugins/ragents.actor-programs/web/ActorViewFrame.tsx +463 -0
  504. package/plugins/ragents.actor-programs/web/AppsPanel.tsx +436 -0
  505. package/plugins/ragents.actor-programs/web/EmbeddedApps.tsx +116 -0
  506. package/plugins/ragents.actor-programs/web/ExpandIcon.tsx +5 -0
  507. package/plugins/ragents.actor-programs/web/FullscreenHost.tsx +31 -0
  508. package/plugins/ragents.actor-programs/web/FunctionForm.tsx +102 -0
  509. package/plugins/ragents.actor-programs/web/ProgramSource.tsx +81 -0
  510. package/plugins/ragents.actor-programs/web/api.ts +353 -0
  511. package/plugins/ragents.actor-programs/web/bridge.ts +122 -0
  512. package/plugins/ragents.actor-programs/web/chat-state.ts +37 -0
  513. package/plugins/ragents.actor-programs/web/context.ts +30 -0
  514. package/plugins/ragents.actor-programs/web/function-call.ts +28 -0
  515. package/plugins/ragents.actor-programs/web/function-input.ts +40 -0
  516. package/plugins/ragents.actor-programs/web/index.tsx +96 -0
  517. package/plugins/ragents.actor-programs/web/invocations.ts +43 -0
  518. package/plugins/ragents.actor-programs/web/program-state.ts +68 -0
  519. package/plugins/ragents.actor-programs/web/state-revision.ts +16 -0
  520. package/plugins/ragents.actor-programs/workflow/index.ts +202 -0
  521. package/plugins/ragents.actor-programs/workflow/prompt-reader.ts +15 -0
  522. package/plugins/ragents.ask/ask.hbs +4 -0
  523. package/plugins/ragents.ask/contract.ts +17 -0
  524. package/plugins/ragents.ask/server/answer-method.ts +15 -0
  525. package/plugins/ragents.ask/server/ask-service.ts +152 -0
  526. package/plugins/ragents.ask/server/ask-tool.ts +39 -0
  527. package/plugins/ragents.ask/server/contract.ts +22 -0
  528. package/plugins/ragents.ask/server/index.ts +26 -0
  529. package/plugins/ragents.ask/server/tool-contributor.ts +11 -0
  530. package/plugins/ragents.ask/web/QuestionSection.tsx +47 -0
  531. package/plugins/ragents.ask/web/api.ts +6 -0
  532. package/plugins/ragents.ask/web/constants.ts +1 -0
  533. package/plugins/ragents.ask/web/index.tsx +50 -0
  534. package/plugins/ragents.browser/provision.ts +48 -0
  535. package/plugins/ragents.browser/server/browser.ts +393 -0
  536. package/plugins/ragents.browser/server/contract.ts +36 -0
  537. package/plugins/ragents.browser/server/index.ts +35 -0
  538. package/plugins/ragents.browser/server/tools.ts +197 -0
  539. package/plugins/ragents.browser/skills/browser-testing/SKILL.md +36 -0
  540. package/plugins/ragents.documents/contract.ts +33 -0
  541. package/plugins/ragents.documents/prompt.hbs +18 -0
  542. package/plugins/ragents.documents/server/config.ts +14 -0
  543. package/plugins/ragents.documents/server/document-write-tool.ts +45 -0
  544. package/plugins/ragents.documents/server/files-route.ts +137 -0
  545. package/plugins/ragents.documents/server/index.ts +38 -0
  546. package/plugins/ragents.documents/server/show-document-tool.ts +73 -0
  547. package/plugins/ragents.documents/server/store.ts +35 -0
  548. package/plugins/ragents.documents/server/tool-contributor.ts +16 -0
  549. package/plugins/ragents.documents/web/DocumentViewer.tsx +450 -0
  550. package/plugins/ragents.documents/web/api.ts +8 -0
  551. package/plugins/ragents.documents/web/index.tsx +279 -0
  552. package/plugins/ragents.lsp-fsharp/provision.ts +74 -0
  553. package/plugins/ragents.lsp-fsharp/server/index.ts +16 -0
  554. package/plugins/ragents.lsp-fsharp/web/index.tsx +7 -0
  555. package/plugins/ragents.lsp-roslyn/provision.ts +54 -0
  556. package/plugins/ragents.lsp-roslyn/server/index.ts +15 -0
  557. package/plugins/ragents.lsp-roslyn/web/api.ts +10 -0
  558. package/plugins/ragents.lsp-roslyn/web/index.tsx +7 -0
  559. package/plugins/ragents.lsp-roslyn/web/language-server-plugin.tsx +236 -0
  560. package/plugins/ragents.lsp-typescript/server/index.ts +7 -0
  561. package/plugins/ragents.lsp-typescript/web/index.tsx +7 -0
  562. package/plugins/ragents.model-relay/server/config.ts +37 -0
  563. package/plugins/ragents.model-relay/server/index.ts +31 -0
  564. package/plugins/ragents.model-relay/server/relay.ts +213 -0
  565. package/plugins/ragents.orchestration/canvas.hbs +50 -0
  566. package/plugins/ragents.orchestration/contract.ts +322 -0
  567. package/plugins/ragents.orchestration/orchestration.hbs +105 -0
  568. package/plugins/ragents.orchestration/server/canvas-tool.ts +248 -0
  569. package/plugins/ragents.orchestration/server/index.ts +64 -0
  570. package/plugins/ragents.orchestration/server/run-stop-tool.ts +30 -0
  571. package/plugins/ragents.orchestration/tiled-layout.ts +47 -0
  572. package/plugins/ragents.orchestration/web/ActorCanvasControls.tsx +159 -0
  573. package/plugins/ragents.orchestration/web/ActorChat.tsx +56 -0
  574. package/plugins/ragents.orchestration/web/ActorChatControls.tsx +64 -0
  575. package/plugins/ragents.orchestration/web/ActorChatPreview.tsx +36 -0
  576. package/plugins/ragents.orchestration/web/ActorNet.tsx +607 -0
  577. package/plugins/ragents.orchestration/web/ActorPopout.tsx +36 -0
  578. package/plugins/ragents.orchestration/web/ActorShortcut.tsx +76 -0
  579. package/plugins/ragents.orchestration/web/ActorTile.tsx +22 -0
  580. package/plugins/ragents.orchestration/web/CanvasStartup.tsx +14 -0
  581. package/plugins/ragents.orchestration/web/CanvasTiles.tsx +47 -0
  582. package/plugins/ragents.orchestration/web/CardSizeSettings.tsx +42 -0
  583. package/plugins/ragents.orchestration/web/Center.tsx +576 -0
  584. package/plugins/ragents.orchestration/web/DocumentsSection.tsx +37 -0
  585. package/plugins/ragents.orchestration/web/ExecutionsPanel.tsx +109 -0
  586. package/plugins/ragents.orchestration/web/FlowInspector.tsx +932 -0
  587. package/plugins/ragents.orchestration/web/JournalStatus.tsx +87 -0
  588. package/plugins/ragents.orchestration/web/MaterialBody.tsx +104 -0
  589. package/plugins/ragents.orchestration/web/ScriptActorCard.tsx +56 -0
  590. package/plugins/ragents.orchestration/web/StopRunButton.tsx +52 -0
  591. package/plugins/ragents.orchestration/web/TiledCanvas.tsx +281 -0
  592. package/plugins/ragents.orchestration/web/ZoomSettings.tsx +38 -0
  593. package/plugins/ragents.orchestration/web/actor-conversation.ts +64 -0
  594. package/plugins/ragents.orchestration/web/actor-header-settings.ts +41 -0
  595. package/plugins/ragents.orchestration/web/api.ts +33 -0
  596. package/plugins/ragents.orchestration/web/canvas-layout-storage.ts +39 -0
  597. package/plugins/ragents.orchestration/web/canvas-layout.ts +326 -0
  598. package/plugins/ragents.orchestration/web/canvas-scene.ts +311 -0
  599. package/plugins/ragents.orchestration/web/canvas-stage.ts +21 -0
  600. package/plugins/ragents.orchestration/web/canvas-startup.ts +36 -0
  601. package/plugins/ragents.orchestration/web/canvas-view-settings.ts +48 -0
  602. package/plugins/ragents.orchestration/web/card-size-settings.ts +36 -0
  603. package/plugins/ragents.orchestration/web/column/AddresseeControl.tsx +116 -0
  604. package/plugins/ragents.orchestration/web/column/ColumnSettings.tsx +50 -0
  605. package/plugins/ragents.orchestration/web/column/RunColumn.tsx +370 -0
  606. package/plugins/ragents.orchestration/web/column/column-actors.ts +38 -0
  607. package/plugins/ragents.orchestration/web/column/column-settings.ts +47 -0
  608. package/plugins/ragents.orchestration/web/column/column-state.ts +59 -0
  609. package/plugins/ragents.orchestration/web/column/sheet-status.ts +30 -0
  610. package/plugins/ragents.orchestration/web/constants.ts +10 -0
  611. package/plugins/ragents.orchestration/web/contract.ts +25 -0
  612. package/plugins/ragents.orchestration/web/executions.ts +124 -0
  613. package/plugins/ragents.orchestration/web/format.ts +4 -0
  614. package/plugins/ragents.orchestration/web/index.tsx +182 -0
  615. package/plugins/ragents.orchestration/web/keyboard-navigation.ts +55 -0
  616. package/plugins/ragents.orchestration/web/material-layout.ts +14 -0
  617. package/plugins/ragents.orchestration/web/run-view.ts +199 -0
  618. package/plugins/ragents.orchestration/web/tile-docking.ts +99 -0
  619. package/plugins/ragents.orchestration/web/tiled-view-settings.ts +76 -0
  620. package/plugins/ragents.orchestration/web/useCanvasMeasurements.ts +78 -0
  621. package/plugins/ragents.orchestration/web/zoom-settings.ts +28 -0
  622. package/plugins/ragents.overseer/contract.ts +165 -0
  623. package/plugins/ragents.overseer/server/api.ts +82 -0
  624. package/plugins/ragents.overseer/server/coordinator-prompt.ts +13 -0
  625. package/plugins/ragents.overseer/server/index.ts +71 -0
  626. package/plugins/ragents.overseer/server/orientation.ts +33 -0
  627. package/plugins/ragents.overseer/server/quick-answer.ts +54 -0
  628. package/plugins/ragents.overseer/server/reset-method.ts +5 -0
  629. package/plugins/ragents.overseer/server/run-directory.ts +49 -0
  630. package/plugins/ragents.overseer/server/settings-method.ts +8 -0
  631. package/plugins/ragents.overseer/server/settings.ts +83 -0
  632. package/plugins/ragents.overseer/server/user-location.ts +96 -0
  633. package/plugins/ragents.overseer/web/ModelSettings.tsx +70 -0
  634. package/plugins/ragents.overseer/web/chat-display.ts +10 -0
  635. package/plugins/ragents.overseer/web/index.tsx +208 -0
  636. package/plugins/ragents.overseer/web/model-settings.ts +61 -0
  637. package/plugins/ragents.overseer/web/quick-answers.ts +64 -0
  638. package/plugins/ragents.processes/contract.ts +61 -0
  639. package/plugins/ragents.processes/server/index.ts +36 -0
  640. package/plugins/ragents.processes/server/methods.ts +39 -0
  641. package/plugins/ragents.processes/server/observer.ts +179 -0
  642. package/plugins/ragents.processes/server/process-table.ts +395 -0
  643. package/plugins/ragents.processes/server/snapshot.ts +63 -0
  644. package/plugins/ragents.processes/server/terminator.ts +164 -0
  645. package/plugins/ragents.processes/web/ProcessHeader.tsx +157 -0
  646. package/plugins/ragents.processes/web/index.tsx +23 -0
  647. package/plugins/ragents.processes/web/processes.ts +75 -0
  648. package/plugins/ragents.product/model-settings-contract.ts +10 -0
  649. package/plugins/ragents.product/preamble.hbs +9 -0
  650. package/plugins/ragents.product/server/config.ts +73 -0
  651. package/plugins/ragents.product/server/index.ts +117 -0
  652. package/plugins/ragents.product/server/relay.ts +118 -0
  653. package/plugins/ragents.product/server/runtime.ts +30 -0
  654. package/plugins/ragents.product/web/ModelControl.tsx +81 -0
  655. package/plugins/ragents.product/web/ProductModelSettings.tsx +131 -0
  656. package/plugins/ragents.product/web/SystemPromptControl.tsx +136 -0
  657. package/plugins/ragents.product/web/index.tsx +29 -0
  658. package/plugins/ragents.product/web/model-settings.ts +39 -0
  659. package/plugins/ragents.product/web/start-options.tsx +12 -0
  660. package/plugins/ragents.profile-distribution/contract.ts +38 -0
  661. package/plugins/ragents.profile-distribution/server/archive.ts +159 -0
  662. package/plugins/ragents.profile-distribution/server/config.ts +27 -0
  663. package/plugins/ragents.profile-distribution/server/index.ts +93 -0
  664. package/plugins/ragents.profile-distribution/server/web.ts +48 -0
  665. package/plugins/ragents.reference/examples.ts +33 -0
  666. package/plugins/ragents.reference/run-scripts/balcony-wizard/RUN.md +27 -0
  667. package/plugins/ragents.reference/run-scripts/balcony-wizard/actors/balcony-app/package.json +10 -0
  668. package/plugins/ragents.reference/run-scripts/balcony-wizard/actors/balcony-app/src/client.tsx +80 -0
  669. package/plugins/ragents.reference/run-scripts/balcony-wizard/actors/balcony-app/src/conversation.ts +82 -0
  670. package/plugins/ragents.reference/run-scripts/balcony-wizard/actors/balcony-app/tests/conversation.test.ts +154 -0
  671. package/plugins/ragents.reference/run-scripts/balcony-wizard/package.json +9 -0
  672. package/plugins/ragents.reference/run-scripts/balcony-wizard/src/server.ts +32 -0
  673. package/plugins/ragents.reference/run-scripts/balcony-wizard/tests/program.test.ts +59 -0
  674. package/plugins/ragents.reference/run-scripts/conversation-circle/RUN.md +14 -0
  675. package/plugins/ragents.reference/run-scripts/conversation-circle/package.json +9 -0
  676. package/plugins/ragents.reference/run-scripts/conversation-circle/src/server.ts +87 -0
  677. package/plugins/ragents.reference/run-scripts/conversation-circle/tests/helpers.ts +26 -0
  678. package/plugins/ragents.reference/run-scripts/conversation-circle/tests/program.test.ts +32 -0
  679. package/plugins/ragents.reference/run-scripts/learning-afternoon/RUN.md +24 -0
  680. package/plugins/ragents.reference/run-scripts/learning-afternoon/package.json +10 -0
  681. package/plugins/ragents.reference/run-scripts/learning-afternoon/prompts/experiment.md +1 -0
  682. package/plugins/ragents.reference/run-scripts/learning-afternoon/prompts/helper.md +5 -0
  683. package/plugins/ragents.reference/run-scripts/learning-afternoon/prompts/quiz.md +1 -0
  684. package/plugins/ragents.reference/run-scripts/learning-afternoon/src/client.tsx +27 -0
  685. package/plugins/ragents.reference/run-scripts/learning-afternoon/src/server.ts +127 -0
  686. package/plugins/ragents.reference/run-scripts/learning-afternoon/src/state.ts +38 -0
  687. package/plugins/ragents.reference/run-scripts/learning-afternoon/src/view.tsx +42 -0
  688. package/plugins/ragents.reference/run-scripts/learning-afternoon/src/workflow.ts +38 -0
  689. package/plugins/ragents.reference/run-scripts/learning-afternoon/tests/program.test.ts +223 -0
  690. package/plugins/ragents.reference/run-scripts/moderated-round/RUN.md +12 -0
  691. package/plugins/ragents.reference/run-scripts/moderated-round/package.json +9 -0
  692. package/plugins/ragents.reference/run-scripts/moderated-round/src/server.ts +60 -0
  693. package/plugins/ragents.reference/run-scripts/moderated-round/tests/helpers.ts +26 -0
  694. package/plugins/ragents.reference/run-scripts/moderated-round/tests/program.test.ts +24 -0
  695. package/plugins/ragents.reference/run-scripts/shared-actor-list/RUN.md +18 -0
  696. package/plugins/ragents.reference/run-scripts/shared-actor-list/actors/shared-list/package.json +16 -0
  697. package/plugins/ragents.reference/run-scripts/shared-actor-list/actors/shared-list/src/client.tsx +39 -0
  698. package/plugins/ragents.reference/run-scripts/shared-actor-list/actors/shared-list/src/contract.ts +15 -0
  699. package/plugins/ragents.reference/run-scripts/shared-actor-list/actors/shared-list/src/server.ts +14 -0
  700. package/plugins/ragents.reference/run-scripts/shared-actor-list/actors/shared-list/tests/program.test.ts +13 -0
  701. package/plugins/ragents.reference/run-scripts/shared-actor-list/package.json +9 -0
  702. package/plugins/ragents.reference/run-scripts/shared-actor-list/src/server.ts +65 -0
  703. package/plugins/ragents.reference/run-scripts/shared-actor-list/tests/helpers.ts +26 -0
  704. package/plugins/ragents.reference/run-scripts/shared-actor-list/tests/program.test.ts +42 -0
  705. package/plugins/ragents.reference/run-scripts/word-game/RUN.md +25 -0
  706. package/plugins/ragents.reference/run-scripts/word-game/package.json +11 -0
  707. package/plugins/ragents.reference/run-scripts/word-game/src/client.tsx +27 -0
  708. package/plugins/ragents.reference/run-scripts/word-game/src/contract.ts +23 -0
  709. package/plugins/ragents.reference/run-scripts/word-game/src/server.ts +106 -0
  710. package/plugins/ragents.reference/run-scripts/word-game/src/state.ts +22 -0
  711. package/plugins/ragents.reference/run-scripts/word-game/src/view.tsx +54 -0
  712. package/plugins/ragents.reference/run-scripts/word-game/tests/program.test.ts +253 -0
  713. package/plugins/ragents.reference/server/index.ts +12 -0
  714. package/plugins/ragents.reference/skills/100-shared-actor-list/SKILL.md +12 -0
  715. package/plugins/ragents.reference/skills/110-all-card-slots/SKILL.md +12 -0
  716. package/plugins/ragents.reference/skills/120-canvas-conversation-circle/SKILL.md +12 -0
  717. package/plugins/ragents.reference/skills/130-canvas-pipeline-with-approval/SKILL.md +12 -0
  718. package/plugins/ragents.reference/skills/140-canvas-team-tree-and-topic-grid/SKILL.md +12 -0
  719. package/plugins/ragents.reference/skills/150-editorial-workbench/SKILL.md +12 -0
  720. package/plugins/ragents.reference/skills/160-learning-companion/SKILL.md +12 -0
  721. package/plugins/ragents.reference/skills/170-photo-collection/SKILL.md +12 -0
  722. package/plugins/ragents.reference/skills/180-decision-workbench/SKILL.md +12 -0
  723. package/plugins/ragents.reference/skills/190-review-queue/SKILL.md +12 -0
  724. package/plugins/ragents.reference/skills/20-circle-of-four/SKILL.md +12 -0
  725. package/plugins/ragents.reference/skills/200-typescript-diagnostics/SKILL.md +12 -0
  726. package/plugins/ragents.reference/skills/210-moderator-handover/SKILL.md +12 -0
  727. package/plugins/ragents.reference/skills/220-actor-approval-list/SKILL.md +12 -0
  728. package/plugins/ragents.reference/skills/230-shared-state-views/SKILL.md +12 -0
  729. package/plugins/ragents.reference/skills/240-live-result-list/SKILL.md +12 -0
  730. package/plugins/ragents.reference/skills/250-balcony-wizard/SKILL.md +12 -0
  731. package/plugins/ragents.reference/skills/30-llm-without-runtime-knowledge/SKILL.md +12 -0
  732. package/plugins/ragents.reference/skills/35-actor-input-fifo/SKILL.md +12 -0
  733. package/plugins/ragents.reference/skills/40-subscription-matrix/SKILL.md +12 -0
  734. package/plugins/ragents.reference/skills/50-subscription-removal/SKILL.md +12 -0
  735. package/plugins/ragents.reference/skills/60-stop-in-the-circle/SKILL.md +12 -0
  736. package/plugins/ragents.reference/skills/65-artifact-least-privilege/SKILL.md +12 -0
  737. package/plugins/ragents.reference/skills/70-headless-counter/SKILL.md +12 -0
  738. package/plugins/ragents.reference/skills/75-lsp-demo/SKILL.md +12 -0
  739. package/plugins/ragents.reference/skills/80-actor-text-analysis/SKILL.md +12 -0
  740. package/plugins/ragents.reference/skills/90-actor-notes/SKILL.md +12 -0
  741. package/plugins/ragents.reference/skills/95-hello-world/SKILL.md +12 -0
  742. package/plugins/ragents.reference/skills/decision-brief/SKILL.md +33 -0
  743. package/plugins/ragents.reference/skills/learning-sprint/SKILL.md +33 -0
  744. package/plugins/ragents.reference/walkthroughs.ts +219 -0
  745. package/plugins/ragents.reference/web/StartGuides.tsx +89 -0
  746. package/plugins/ragents.reference/web/index.tsx +10 -0
  747. package/plugins/ragents.todo/contract.ts +60 -0
  748. package/plugins/ragents.todo/server/index.ts +10 -0
  749. package/plugins/ragents.todo/server/todo-tool.ts +70 -0
  750. package/plugins/ragents.todo/server/tool-contributor.ts +9 -0
  751. package/plugins/ragents.todo/web/TodoSection.tsx +47 -0
  752. package/plugins/ragents.todo/web/index.ts +12 -0
  753. package/plugins/ragents.transcript/server/index.ts +20 -0
  754. package/plugins/ragents.transcript/server/transcript.ts +78 -0
  755. package/plugins/ragents.watch/contract.ts +48 -0
  756. package/plugins/ragents.watch/server/condition.ts +56 -0
  757. package/plugins/ragents.watch/server/contract.ts +4 -0
  758. package/plugins/ragents.watch/server/functions.ts +62 -0
  759. package/plugins/ragents.watch/server/index.ts +39 -0
  760. package/plugins/ragents.watch/server/observation.ts +69 -0
  761. package/plugins/ragents.watch/server/service.ts +294 -0
  762. package/plugins/ragents.workspace/client/transport.ts +13 -0
  763. package/plugins/ragents.workspace/client/workspace-client.ts +247 -0
  764. package/plugins/ragents.workspace/contract.ts +182 -0
  765. package/plugins/ragents.workspace/prompt.hbs +14 -0
  766. package/plugins/ragents.workspace/server/binding.ts +92 -0
  767. package/plugins/ragents.workspace/server/browse-route.ts +134 -0
  768. package/plugins/ragents.workspace/server/clients.ts +161 -0
  769. package/plugins/ragents.workspace/server/index.ts +91 -0
  770. package/plugins/ragents.workspace/server/runtime.ts +170 -0
  771. package/plugins/ragents.workspace/web/FileBrowser.tsx +271 -0
  772. package/plugins/ragents.workspace/web/WorkspaceBinding.tsx +216 -0
  773. package/plugins/ragents.workspace/web/api.ts +8 -0
  774. package/plugins/ragents.workspace/web/file-icons.tsx +94 -0
  775. package/plugins/ragents.workspace/web/index.tsx +37 -0
  776. package/ragents.config.core.ts +65 -0
  777. package/ragents.config.developer.ts +46 -0
  778. package/scripts/agent/agent-cli.ts +461 -0
  779. package/scripts/agent/journal.ts +125 -0
  780. package/scripts/package/build-package.ts +249 -0
  781. package/scripts/package/host-links.d.mts +1 -0
  782. package/scripts/package/host-links.mjs +39 -0
  783. package/scripts/package/publish-package.ts +129 -0
  784. package/scripts/package/ragents.mjs +59 -0
  785. package/scripts/provision/run-provision.ts +72 -0
  786. package/scripts/remote/connect.ts +265 -0
  787. package/scripts/remote/start.ts +91 -0
  788. package/scripts/workspace-client/run-workspace-client.ts +112 -0
@@ -0,0 +1,949 @@
1
+ import { useAccess } from "./AccessContext";
2
+ import { ArrowLeftIcon, CheckIcon, ChevronRightIcon, CircleAlertIcon, CopyIcon, InfoIcon, SettingsIcon, XIcon } from "lucide-react";
3
+ import { cn } from "cn";
4
+ import { Button, Card, Dialog, DialogContent, DialogTitle, Input, Spinner, Toggle, ToggleGroup, ToggleGroupItem } from "./ui";
5
+ import { useEffect, useMemo, useRef, useState, type ReactNode } from "react";
6
+ import { Markdown } from "./chat/Markdown";
7
+ import { SourceCode } from "./SourceCode";
8
+ import { formatBytes } from "./lib/format";
9
+ import { ThemeSettings } from "./ThemeSettings";
10
+ import { TitleModelSettings } from "./TitleModelSettings";
11
+ import { modelDefaultsChangedEvent } from "./model-settings-events";
12
+ import {
13
+ getSettings,
14
+ getSettingsSkill,
15
+ type SettingsAgentExtension,
16
+ type SettingsModel,
17
+ type SettingsProfile,
18
+ type SettingsResponse,
19
+ type SettingsSkill,
20
+ type SettingsSkillDetail,
21
+ type SettingsSkillFile,
22
+ type SettingsTool,
23
+ } from "./api";
24
+ import type { PluginRegistry } from "./PluginRegistry";
25
+ import {
26
+ capabilityGroups,
27
+ contributionFilters,
28
+ countContributions,
29
+ entryActionLabel,
30
+ filterGroup,
31
+ groupContributions,
32
+ settingsForCategory,
33
+ skillAudienceLabel,
34
+ toolAvailabilityLabel,
35
+ toolKindLabel,
36
+ toolScopeLabel,
37
+ functionSurfaceLabel,
38
+ type ContributionFilter,
39
+ type ContributionKind,
40
+ type PluginGroup,
41
+ } from "./settings-contributions";
42
+
43
+ type SettingsPageSelection =
44
+ | { kind: "models" | "appearance" | "runtime" | "extensions" }
45
+ | { kind: "plugin"; id: string }
46
+ | { kind: "capability"; id: ContributionKind };
47
+
48
+ const settingsAreas = [
49
+ { id: "models", label: "Modelle" },
50
+ { id: "appearance", label: "Darstellung" },
51
+ { id: "extensions", label: "Erweiterungen" },
52
+ { id: "runtime", label: "Laufzeit" },
53
+ ] as const;
54
+ const capabilities = contributionFilters.filter(
55
+ (option): option is { id: ContributionKind; label: string } => option.id !== "all",
56
+ );
57
+
58
+ export const settingsPageClass = "mx-auto flex max-w-[1020px] flex-col gap-6 px-[clamp(20px,4vw,46px)] pt-7 pb-12 max-sm:px-3.5 max-sm:pt-5 max-sm:pb-9";
59
+ const pageTitleClass = "min-w-0 text-[1.08rem] font-semibold text-foreground";
60
+ const pageLeadClass = "mt-1.5 max-w-[780px] text-[0.76rem] leading-[1.55] text-muted-foreground";
61
+ const sectionCopyClass = "-mt-1 mb-0.5 text-[0.72rem] leading-normal text-muted-foreground";
62
+ const settingsPanelsClass = "grid gap-5";
63
+ const panelSectionClass = "gap-4 p-5.5 max-md:p-4";
64
+ const settingsAreaClass = "min-h-11 flex-none cursor-pointer border-b-2 border-transparent px-3.5 py-2.5 text-[0.8rem] focus-visible:outline-2 focus-visible:outline-primary focus-visible:-outline-offset-4 max-md:px-2.5 max-md:text-[0.75rem]";
65
+ const navigationItemClass = "flex min-h-[37px] w-full cursor-pointer items-center justify-between gap-2 rounded-lg px-2.5 py-1.5 text-left text-[0.75rem] max-md:w-auto max-md:min-h-8 max-md:flex-none max-md:whitespace-nowrap";
66
+ const navigationItemActiveClass = "bg-primary/12 font-semibold text-primary";
67
+ const navigationItemQuietClass = "text-muted-foreground hover:bg-foreground/6 hover:text-foreground";
68
+ const navigationCountClass = "min-w-5 flex-shrink-0 rounded-full bg-current/11 px-1.5 py-px text-center text-[0.63rem] tabular-nums";
69
+ const loadStateClass = "flex min-h-full items-center justify-center gap-2 p-8 text-[0.78rem] text-muted-foreground";
70
+ const ownerLinkClass = "flex w-full min-w-0 cursor-pointer items-center justify-between gap-2.5 text-left font-semibold text-foreground [overflow-wrap:anywhere] hover:text-primary focus-visible:outline-2 focus-visible:outline-primary focus-visible:outline-offset-2";
71
+ const ownerLinkNoteClass = "flex-shrink-0 text-[0.7rem] font-normal text-primary";
72
+ const cardListClass = "grid gap-2";
73
+ const cardClass = "min-w-0 rounded-xl border border-border-soft bg-background/76 px-3.5 py-3";
74
+ const cardHeaderClass = "flex items-start justify-between gap-3";
75
+ const cardCopyClass = "grid min-w-0 gap-0.5";
76
+ const cardTitleClass = "truncate text-[0.78rem] text-foreground";
77
+ const cardNoteClass = "truncate text-[0.64rem] text-muted-foreground";
78
+ const cardCopyTextClass = "my-2 text-[0.7rem] leading-normal text-muted-foreground";
79
+ const chipClass = "flex-shrink-0 rounded-full bg-foreground/7 px-1.5 py-0.5 text-[0.62rem] font-medium text-muted-foreground";
80
+ const tagClass = "inline-flex items-center gap-1.5 rounded-full bg-foreground/7 px-1.5 py-0.5 text-[0.62rem] text-foreground";
81
+ const statusListClass = "flex flex-wrap justify-end gap-1";
82
+ const disclosureClass = "overflow-hidden rounded-xl border border-border-soft bg-background/76 open:[&>summary]:border-b open:[&>summary]:border-border-soft";
83
+ const summaryClass = "flex cursor-pointer list-none items-center justify-between gap-3 px-3 py-2.5 text-foreground [&::-webkit-details-marker]:hidden";
84
+ const preClass = "m-0 overflow-auto rounded-lg border border-border-soft bg-foreground/4 font-mono text-[0.7rem] leading-[1.55] whitespace-pre-wrap text-foreground [overflow-wrap:anywhere]";
85
+ const valueLabelClass = "text-[0.67rem] font-medium text-muted-foreground";
86
+
87
+ interface SettingsModalProps {
88
+ onClose: () => void;
89
+ registry: PluginRegistry;
90
+ }
91
+
92
+ type LoadState =
93
+ | { status: "loading"; settings?: SettingsResponse }
94
+ | { status: "ready"; settings: SettingsResponse }
95
+ | { status: "failed"; error: string; settings?: SettingsResponse };
96
+
97
+ export function SettingsModal({ onClose, registry }: SettingsModalProps) {
98
+ const access = useAccess();
99
+ const [selection, setSelection] = useState<SettingsPageSelection>({ kind: "models" });
100
+ const catalogVisible = selection.kind === "extensions" || selection.kind === "plugin" || selection.kind === "capability";
101
+ const activeArea = catalogVisible ? "extensions" : selection.kind;
102
+ const [axis, setAxis] = useState<"plugin" | "capability">("plugin");
103
+ const [lastPlugin, setLastPlugin] = useState<string | null>(null);
104
+ const [lastCapability, setLastCapability] = useState<ContributionKind>("tools");
105
+ const contentRef = useRef<HTMLDivElement>(null);
106
+ const navigationRef = useRef<HTMLElement>(null);
107
+ const [filter, setFilter] = useState<ContributionFilter>("all");
108
+ const [query, setQuery] = useState("");
109
+ const [reload, setReload] = useState(0);
110
+ const [catalogRequested, setCatalogRequested] = useState(false);
111
+ const [state, setState] = useState<LoadState>({ status: "loading" });
112
+ const closeRef = useRef<HTMLButtonElement>(null);
113
+
114
+ useEffect(() => {
115
+ if (catalogVisible || selection.kind === "runtime") setCatalogRequested(true);
116
+ }, [catalogVisible, selection.kind]);
117
+
118
+ useEffect(() => {
119
+ if (!catalogRequested) return;
120
+ const controller = new AbortController();
121
+ setState((current) => ({ status: "loading", settings: current.settings }));
122
+ void getSettings(controller.signal)
123
+ .then((settings) => { if (!controller.signal.aborted) setState({ status: "ready", settings }); })
124
+ .catch((caught: unknown) => {
125
+ if (controller.signal.aborted) return;
126
+ setState((current) => ({ status: "failed", settings: current.settings, error: caught instanceof Error ? caught.message : String(caught) }));
127
+ });
128
+ return () => controller.abort();
129
+ }, [catalogRequested, reload]);
130
+
131
+ useEffect(() => {
132
+ const changed = () => { if (catalogRequested) setReload((value) => value + 1); };
133
+ window.addEventListener(modelDefaultsChangedEvent, changed);
134
+ return () => window.removeEventListener(modelDefaultsChangedEvent, changed);
135
+ }, [catalogRequested]);
136
+
137
+ const settings = state.settings ?? null;
138
+ const groups = useMemo(
139
+ () => settings === null ? [] : groupContributions(settings, registry),
140
+ [settings, registry],
141
+ );
142
+ const filtered = useMemo(
143
+ () => groups.map((group) => filterGroup(group, filter, query)),
144
+ [groups, filter, query],
145
+ );
146
+ const active = selection.kind === "plugin"
147
+ ? filtered.find((group) => group.id === selection.id)
148
+ : undefined;
149
+ const modelSettings = settingsForCategory(registry.settings, "models", access.can);
150
+ const appearanceSettings = settingsForCategory(registry.settings, "appearance", access.can);
151
+ const capabilityResults = useMemo(
152
+ () => capabilities.map((option) => ({ ...option, groups: capabilityGroups(groups, option.id, query) })),
153
+ [groups, query],
154
+ );
155
+ const activeCapability = selection.kind === "capability"
156
+ ? capabilityResults.find((option) => option.id === selection.id)
157
+ : undefined;
158
+
159
+ useEffect(() => {
160
+ contentRef.current?.scrollTo({ top: 0 });
161
+ }, [selection]);
162
+
163
+ useEffect(() => {
164
+ const navigation = navigationRef.current;
165
+ if (!navigation) return;
166
+ const revealSelection = () => navigation.querySelector<HTMLElement>('[aria-current="page"]')
167
+ ?.scrollIntoView({ block: "nearest", inline: "nearest" });
168
+ revealSelection();
169
+ const observer = new ResizeObserver(revealSelection);
170
+ observer.observe(navigation);
171
+ return () => observer.disconnect();
172
+ }, [axis, selection, state.status]);
173
+
174
+ function openPlugin(id: string) {
175
+ setAxis("plugin");
176
+ setLastPlugin(id);
177
+ setSelection({ kind: "plugin", id });
178
+ }
179
+
180
+ function changeAxis(next: "plugin" | "capability") {
181
+ setAxis(next);
182
+ setSelection(next === "capability"
183
+ ? { kind: "capability", id: lastCapability }
184
+ : lastPlugin === null ? { kind: "extensions" } : { kind: "plugin", id: lastPlugin });
185
+ }
186
+
187
+ return (
188
+ <Dialog open onOpenChange={(open) => { if (!open) onClose(); }}>
189
+ <DialogContent className="mx-auto flex h-[calc(100vh-2*clamp(14px,4vh,42px))] max-h-none w-[min(1220px,calc(100vw-2*clamp(14px,4vw,58px)))] max-w-none min-h-0 min-w-0 flex-col gap-0 overflow-hidden rounded-xl bg-card p-0 shadow-[0_34px_90px_color-mix(in_srgb,var(--foreground)_45%,transparent)] max-md:h-[calc(100vh-16px)] max-md:w-[calc(100vw-16px)]" initialFocus={closeRef} scope="page" showCloseButton={false} size="full">
190
+ <header className="grid flex-none grid-cols-[auto_minmax(0,1fr)_auto] items-center gap-3 border-b border-border px-3.5 py-2.5">
191
+ <span className="flex size-[34px] items-center justify-center rounded-[10px] bg-[color-mix(in_srgb,var(--primary)_12%,var(--background))] text-primary"><SettingsIcon size={18} /></span>
192
+ <span className="grid min-w-0 gap-px">
193
+ <DialogTitle render={<strong />}>Einstellungen</DialogTitle>
194
+ <span className="truncate text-[0.7rem] text-muted-foreground max-[520px]:hidden">Modelle und Darstellung anpassen</span>
195
+ </span>
196
+ <Button aria-label="Schließen" className="rounded-full" onClick={onClose} ref={closeRef} size="icon" variant="outline">
197
+ <XIcon />
198
+ </Button>
199
+ </header>
200
+ <nav aria-label="Einstellungsbereiche" className="flex flex-none gap-1 overflow-x-auto border-b border-border px-4.5 max-md:px-2">
201
+ {settingsAreas.map((area) => <button
202
+ aria-current={activeArea === area.id ? "page" : undefined}
203
+ className={cn(settingsAreaClass, activeArea === area.id ? "border-b-primary font-bold text-primary" : "text-muted-foreground hover:text-foreground")}
204
+ key={area.id}
205
+ onClick={() => area.id === "extensions" ? changeAxis(axis) : setSelection({ kind: area.id })}
206
+ type="button"
207
+ >{area.label}</button>)}
208
+ </nav>
209
+ {catalogVisible && <div className="flex flex-none gap-1 border-b border-border-soft px-3.5 py-2.5">
210
+ <ToggleGroup aria-label="Erweiterungen ordnen" size="sm" spacing={0} value={[axis]} variant="outline"
211
+ onValueChange={([value]) => { if (value) changeAxis(value === "capability" ? "capability" : "plugin"); }}>
212
+ <ToggleGroupItem value="plugin">Nach Extension</ToggleGroupItem>
213
+ <ToggleGroupItem value="capability">Nach Fähigkeit</ToggleGroupItem>
214
+ </ToggleGroup>
215
+ </div>}
216
+ <div className={cn("grid min-h-0 flex-1", catalogVisible ? "grid-cols-[230px_minmax(0,1fr)] max-[900px]:grid-cols-[190px_minmax(0,1fr)] max-md:grid-cols-[minmax(0,1fr)] max-md:grid-rows-[auto_minmax(0,1fr)]" : "grid-cols-[minmax(0,1fr)]")}>
217
+ {catalogVisible && <nav aria-label="Erweiterungen durchsuchen" className="flex min-w-0 flex-col gap-[3px] overflow-y-auto border-r border-border-soft bg-background/72 px-2.5 py-4 max-md:flex-row max-md:overflow-x-auto max-md:border-r-0 max-md:border-b max-md:border-border-soft max-md:p-2" ref={navigationRef}>
218
+ {axis === "plugin" && filtered.map((group) => {
219
+ const count = countContributions(group);
220
+ const selected = selection.kind === "plugin" && selection.id === group.id;
221
+ const classNames = cn(navigationItemClass, selected ? navigationItemActiveClass : navigationItemQuietClass, count === 0 && "opacity-42");
222
+ return (
223
+ <button
224
+ aria-current={selected ? "page" : undefined}
225
+ className={classNames}
226
+ key={group.id}
227
+ onClick={() => openPlugin(group.id)}
228
+ type="button"
229
+ >
230
+ {group.id}
231
+ <span className={navigationCountClass}>{count}</span>
232
+ </button>
233
+ );
234
+ })}
235
+ {axis === "capability" && capabilityResults.map((option) => {
236
+ const selected = selection.kind === "capability" && selection.id === option.id;
237
+ const count = option.groups.reduce((sum, group) => sum + countContributions(group), 0);
238
+ return (
239
+ <button
240
+ aria-current={selected ? "page" : undefined}
241
+ className={cn(navigationItemClass, selected ? navigationItemActiveClass : navigationItemQuietClass)}
242
+ key={option.id}
243
+ onClick={() => {
244
+ setLastCapability(option.id);
245
+ setSelection({ kind: "capability", id: option.id });
246
+ }}
247
+ type="button"
248
+ >
249
+ {option.label}
250
+ <span className={navigationCountClass}>{count}</span>
251
+ </button>
252
+ );
253
+ })}
254
+ </nav>}
255
+ <div className="min-h-0 min-w-0 overflow-y-auto bg-app [scrollbar-width:thin]" ref={contentRef}>
256
+ {selection.kind === "models" && <SettingsPage title="Modelle" description="Wähle Modell und Reasoning-Tiefe für die jeweiligen Aufgaben.">
257
+ <div className={settingsPanelsClass}>
258
+ <PluginSettings contributions={modelSettings} panel />
259
+ {access.can("settings.read") && <SettingsSection panel title="Überschriften"><TitleModelSettings /></SettingsSection>}
260
+ </div>
261
+ {modelSettings.length === 0 && !access.can("settings.read") && <SettingsEmpty>Für deine Zugriffsrechte sind keine Modelleinstellungen verfügbar.</SettingsEmpty>}
262
+ </SettingsPage>}
263
+ {selection.kind === "appearance" && <div className="[&>:first-child]:pb-0">
264
+ <ThemeSettings />
265
+ {appearanceSettings.length > 0 && <div className={settingsPageClass}>
266
+ <div className={settingsPanelsClass}><PluginSettings contributions={appearanceSettings} panel /></div>
267
+ </div>}
268
+ </div>}
269
+ {(catalogVisible || selection.kind === "runtime") && settings !== null && state.status !== "ready" && <p className="border-b border-border-soft px-5 py-2.5 text-[0.72rem] text-muted-foreground" role={state.status === "failed" ? "alert" : "status"}>
270
+ {state.status === "loading" ? "Katalog wird aktualisiert ..." : <>Katalog konnte nicht aktualisiert werden: {state.error} <Button onClick={() => setReload((value) => value + 1)} size="sm" variant="outline">Erneut laden</Button></>}
271
+ </p>}
272
+ {(catalogVisible || selection.kind === "runtime") && settings === null && state.status === "loading" && (
273
+ <div className={loadStateClass}>
274
+ <Spinner aria-hidden className="size-3" />
275
+ Laufzeit und Erweiterungen werden geladen.
276
+ </div>
277
+ )}
278
+ {(catalogVisible || selection.kind === "runtime") && settings === null && state.status === "failed" && (
279
+ <div className={cn(loadStateClass, "flex-col text-center text-destructive")} role="alert">
280
+ <CircleAlertIcon size={14} />
281
+ <strong className="text-[0.86rem] text-foreground">Katalog nicht erreichbar</strong>
282
+ <span className="max-w-[560px]">{state.error}</span>
283
+ <Button className="mt-1.5" onClick={() => setReload((value) => value + 1)} size="sm" variant="outline">Erneut laden</Button>
284
+ </div>
285
+ )}
286
+ {settings !== null && selection.kind === "runtime" && <RuntimePage groups={groups} registry={registry} settings={settings} />}
287
+ {settings !== null && selection.kind === "extensions" && <SettingsPage title="Erweiterungen" description="Durchsuche die installierten Beiträge nach Extension oder Fähigkeit. Wähle eine Extension für ihre Details.">
288
+ <div className="grid gap-4">{groups.map((group) => <button className={ownerLinkClass} key={group.id} onClick={() => openPlugin(group.id)} type="button">
289
+ {group.id}<span className={ownerLinkNoteClass}>{countContributions(group)} Beiträge</span>
290
+ </button>)}</div>
291
+ </SettingsPage>}
292
+ {settings !== null && (selection.kind === "plugin" || selection.kind === "capability") && (
293
+ <ContributionFilterBar filter={filter} onFilter={setFilter} onQuery={setQuery} query={query} showKinds={selection.kind === "plugin"} />
294
+ )}
295
+ {settings !== null && selection.kind === "plugin" && (
296
+ active === undefined
297
+ ? <div className={settingsPageClass}><SettingsEmpty>Dieses Plugin ist nicht mehr geladen.</SettingsEmpty></div>
298
+ : <PluginPage group={active} key={active.id} settings={registry.settings} />
299
+ )}
300
+ {settings !== null && activeCapability !== undefined && (
301
+ <SettingsPage title={activeCapability.label} description={`${activeCapability.groups.length} Extensions liefern passende Beiträge. Öffne eine Extension für ihre vollständigen Details.`}>
302
+ {activeCapability.groups.length === 0 && <SettingsEmpty>Keine Beiträge gefunden. Wähle eine andere Fähigkeit oder ändere die Suche.</SettingsEmpty>}
303
+ {activeCapability.groups.map((group) => (
304
+ <PluginPage
305
+ group={group} key={`${activeCapability.id}:${group.id}`} settings={group.settings}
306
+ onOpenPlugin={() => { setFilter("all"); setQuery(""); openPlugin(group.id); }}
307
+ />
308
+ ))}
309
+ </SettingsPage>
310
+ )}
311
+ </div>
312
+ </div>
313
+ </DialogContent>
314
+ </Dialog>
315
+ );
316
+ }
317
+
318
+ function ContributionFilterBar({ filter, onFilter, onQuery, query, showKinds }: {
319
+ showKinds: boolean;
320
+ filter: ContributionFilter;
321
+ onFilter: (filter: ContributionFilter) => void;
322
+ onQuery: (query: string) => void;
323
+ query: string;
324
+ }) {
325
+ return (
326
+ <div className="sticky top-0 z-[2] grid gap-2.5 border-b border-border-soft bg-background/92 px-[clamp(20px,4vw,46px)] py-3 backdrop-blur-[6px] max-md:px-3.5">
327
+ {showKinds && <div aria-label="Beitragsarten" className="flex flex-wrap gap-1.5" role="group">
328
+ {contributionFilters.map((option) => (
329
+ <Toggle key={option.id} pressed={filter === option.id} onPressedChange={() => onFilter(option.id)} size="sm" variant="outline">
330
+ {option.label}
331
+ </Toggle>
332
+ ))}
333
+ </div>}
334
+ <label className="grid gap-1.5">
335
+ <span className="text-[0.67rem] font-medium text-muted-foreground">Beiträge durchsuchen</span>
336
+ <Input
337
+ onChange={(event) => onQuery(event.target.value)}
338
+ placeholder="Kennung, Name, Titel oder Beschreibung"
339
+ type="search"
340
+ value={query}
341
+ />
342
+ </label>
343
+ </div>
344
+ );
345
+ }
346
+
347
+ function RuntimePage({ groups, registry, settings }: {
348
+ groups: readonly PluginGroup[];
349
+ registry: PluginRegistry;
350
+ settings: SettingsResponse;
351
+ }) {
352
+ const workspace = settings.runtime.workspace;
353
+ const documents = settings.runtime.documents;
354
+ const internalExtensions = settings.agentExtensions.filter((extension) => extension.kind === "internal");
355
+ return (
356
+ <SettingsPage
357
+ description={`Die Werte stammen aus der aktuell laufenden ${registry.brand.title}-Instanz. Konfigurationswerte mit Geheimnissen werden vom Server nicht ausgeliefert.`}
358
+ title="Laufzeit"
359
+ >
360
+ <div className="grid grid-cols-4 gap-2.5 max-[900px]:grid-cols-2 max-[520px]:grid-cols-1">
361
+ <SettingsFact label="Produkt" value={settings.product.title} detail={settings.product.id} />
362
+ <SettingsFact label="Profil" value={settings.runtime.profile} detail={settings.product.id} />
363
+ <SettingsFact label="Workspace-Modus" value={settings.runtime.workspaceMode} detail="je Run" />
364
+ <SettingsFact label="Modelle" value={String(settings.models.length)} detail={`${settings.profiles.length} Profile`} />
365
+ <SettingsFact label="Plugins" value={String(groups.length)} detail={`${settings.tools.length} Funktionen`} />
366
+ </div>
367
+ <SettingsSection title="Laufzeit und Arbeitsverzeichnisse">
368
+ <SettingsValue label="Working Directory" value={settings.runtime.host.workingDirectory} copy />
369
+ <SettingsValue
370
+ label="Host"
371
+ value={`${settings.runtime.host.mode === "native" ? "Lokal" : "Container"} / ${settings.runtime.host.platform}`}
372
+ />
373
+ <SettingsValue label="Datenverzeichnis" value={settings.runtime.dataDirectory} copy />
374
+ <SettingsValue
375
+ label="Konfigurationsdatei"
376
+ value={settings.runtime.configFile ?? "keine geladen"}
377
+ copy={settings.runtime.configFile !== null}
378
+ />
379
+ <SettingsValue label="Workspace-Muster je Run" value={workspace.directoryPattern} copy />
380
+ <SettingsValue
381
+ label="Dateiablage je Run"
382
+ value={documents?.directoryPattern ?? "kein Dokumentenstore geladen"}
383
+ copy={documents !== null}
384
+ />
385
+ </SettingsSection>
386
+ <SettingsNote>
387
+ Ein Agent kann innerhalb eines Runs ein eigenes Rollenprompt erhalten. Dieses run-spezifische Prompt ist kein
388
+ statischer Modellwert und wird deshalb nicht in dieser Produktübersicht dargestellt.
389
+ </SettingsNote>
390
+ <SettingsSection count={settings.models.length} title="Verfügbare Modelle">
391
+ <p className={sectionCopyClass}>
392
+ Modelle sind auswählbare Laufzeitziele. Profile bündeln Modell, Treiber, Denktiefe und Ausführungsgrenzen.
393
+ </p>
394
+ <div className="grid grid-cols-2 gap-2.5 max-md:grid-cols-1">
395
+ {settings.models.map((model) => <ModelCard key={modelKey(model)} model={model} />)}
396
+ </div>
397
+ </SettingsSection>
398
+ <SettingsSection count={settings.profiles.length} title="Profile">
399
+ <p className={sectionCopyClass}>
400
+ Retries gelten pro Agenten-Turn nach technischen Fehlern. Die erste Ausführung zählt nicht als Retry.
401
+ Nicht replay-sichere oder terminal blockierte Turns werden nicht erneut ausgeführt.
402
+ </p>
403
+ <div className={cardListClass}>
404
+ {settings.profiles.map((profile) => <ProfileCard key={profile.name} profile={profile} />)}
405
+ </div>
406
+ </SettingsSection>
407
+ <SettingsSection title="Zusammengesetzter Produkt-Systemprompt">
408
+ <p className={sectionCopyClass}>
409
+ {settings.systemPrompt.composition} Der endgültige Agentenprompt ist run-spezifisch und deshalb keine feste
410
+ Modelleinstellung.
411
+ </p>
412
+ <PromptCode content={settings.systemPrompt.content} copyLabel="Produkt-Systemprompt kopieren" />
413
+ </SettingsSection>
414
+ <SettingsSection count={settings.systemPrompt.runtimeContracts.length} title="RAgents-Laufzeitverträge">
415
+ <div className={cardListClass}>
416
+ {settings.systemPrompt.runtimeContracts.map((contract) => (
417
+ <details className={disclosureClass} key={contract.audience}>
418
+ <summary className={summaryClass}>
419
+ <span className={cardCopyClass}>
420
+ <strong className={cardTitleClass}>{contract.audience === "coordinator" ? "Koordinator" : "Agent"}</strong>
421
+ <small className={cardNoteClass}>Wird zur Laufzeit ergänzt</small>
422
+ </span>
423
+ </summary>
424
+ <PromptCode content={contract.content} copyLabel={`${contract.audience} Laufzeitvertrag kopieren`} />
425
+ </details>
426
+ ))}
427
+ </div>
428
+ </SettingsSection>
429
+ <SettingsSection count={internalExtensions.length} title="Interne Erweiterungen">
430
+ <p className={sectionCopyClass}>
431
+ Diese Extensions gehören der Agentenlaufzeit selbst und stammen aus keinem Plugin. Plugin-Erweiterungen
432
+ stehen auf der Seite ihres Plugins.
433
+ </p>
434
+ {internalExtensions.length === 0
435
+ ? <SettingsEmpty>Keine interne Agent-Extension registriert.</SettingsEmpty>
436
+ : (
437
+ <div className={cardListClass}>
438
+ {internalExtensions.map((extension) => (
439
+ <ExtensionCard extension={extension} key={extension.id} />
440
+ ))}
441
+ </div>
442
+ )}
443
+ </SettingsSection>
444
+ </SettingsPage>
445
+ );
446
+ }
447
+
448
+ function PluginSettings({ contributions, panel }: { contributions: PluginRegistry["settings"]; panel?: boolean }) {
449
+ const access = useAccess();
450
+ return contributions.filter((item) => !item.readRight || access.can(item.readRight)).map(({ id, label, Settings }) => (
451
+ <SettingsSection key={id} panel={panel} title={label}>
452
+ <Settings />
453
+ </SettingsSection>
454
+ ));
455
+ }
456
+
457
+ function PluginPage({ group, settings, onOpenPlugin }: {
458
+ group: PluginGroup;
459
+ settings: PluginRegistry["settings"];
460
+ onOpenPlugin?: () => void;
461
+ }) {
462
+ const [selectedSkill, setSelectedSkill] = useState<SettingsSkill | null>(null);
463
+ if (selectedSkill) return <SkillDetail onBack={() => setSelectedSkill(null)} skill={selectedSkill} />;
464
+ const publicConfig = group.clientConfig === undefined ? undefined : sanitizedValue(group.clientConfig);
465
+ const publicConfigText = publicConfig === undefined ? undefined : JSON.stringify(publicConfig, null, 2) ?? "{}";
466
+ const contributions = settings.filter((contribution) => contribution.owner === group.id);
467
+ const empty = contributions.length === 0 && countContributions(group) === 0 && group.web.state === "hidden";
468
+ return (
469
+ <div className={onOpenPlugin ? "flex min-w-0 flex-col gap-4.5 border-t border-border pt-5.5" : settingsPageClass}>
470
+ <header>
471
+ <div className="flex items-center justify-between gap-3">
472
+ {onOpenPlugin
473
+ ? <button className={ownerLinkClass} onClick={onOpenPlugin} type="button">{group.id}<span className={ownerLinkNoteClass}>Extension öffnen</span></button>
474
+ : <h2 className={`${pageTitleClass} truncate font-mono`}>{group.id}</h2>}
475
+ {!onOpenPlugin && <span className={statusListClass}>
476
+ <StatusBadge active={group.serverRegistered} label={group.serverRegistered ? "Server registriert" : "Server unbekannt"} />
477
+ <StatusBadge active={group.webActive} label={group.webActive ? "Web aktiv" : "Web inaktiv"} />
478
+ </span>}
479
+ </div>
480
+ {!onOpenPlugin && <p className={pageLeadClass}>Abhängigkeiten: {group.requires.length === 0 ? "keine" : group.requires.join(", ")}</p>}
481
+ </header>
482
+ <PluginSettings contributions={contributions} />
483
+ {group.tools.length > 0 && (
484
+ <SettingsSection count={group.tools.length} title="Funktionen">
485
+ <div className={cardListClass}>
486
+ {group.tools.map((tool) => <ToolCard key={tool.id} tool={tool} />)}
487
+ </div>
488
+ </SettingsSection>
489
+ )}
490
+ {group.prompts.length > 0 && (
491
+ <SettingsSection count={group.prompts.length} title="Prompts">
492
+ <div className={cardListClass}>
493
+ {group.prompts.map((contribution) => (
494
+ <details className={disclosureClass} key={contribution.id}>
495
+ <summary className={summaryClass}>
496
+ <span className={cardCopyClass}>
497
+ <strong className={cardTitleClass}>{contribution.id}</strong>
498
+ <small className={cardNoteClass}>{contribution.owner}</small>
499
+ </span>
500
+ <span className={chipClass}>Reihenfolge {contribution.order}</span>
501
+ </summary>
502
+ <PromptCode content={contribution.content} copyLabel={`${contribution.id} kopieren`} />
503
+ </details>
504
+ ))}
505
+ </div>
506
+ </SettingsSection>
507
+ )}
508
+ {group.startEntries.length > 0 && (
509
+ <SettingsSection count={group.startEntries.length} title="Einstiege">
510
+ <p className={sectionCopyClass}>
511
+ Was das Plugin auf die Startfläche legt. Ein Skill öffnet einen bearbeitbaren Auftrag;
512
+ ein Run-Script baut den Run selbst auf, bevor
513
+ der Chat beginnt. Nennt ein Einstieg einen Leitfaden, öffnet der Klick zuerst dessen Dialog.
514
+ </p>
515
+ <div className={cardListClass}>
516
+ {group.startEntries.map((entry) => (
517
+ <article className={cardClass} key={entry.id}>
518
+ <header className={cardHeaderClass}>
519
+ <span className={cardCopyClass}>
520
+ <strong className={cardTitleClass}>{entry.title}</strong>
521
+ <small className={cardNoteClass}>{entry.owner} / {entry.id}</small>
522
+ </span>
523
+ <span className={chipClass}>{entryActionLabel(entry)}</span>
524
+ {entry.action === "skill" && <CopyButton label={`${entry.title} kopieren`} text={entry.prompt} />}
525
+ </header>
526
+ <p className={cardCopyTextClass}>{entry.description}</p>
527
+ {entry.action === "skill" && <p className={cardCopyTextClass}>Kategorie: {entry.category}</p>}
528
+ {entry.action === "skill" && <pre className={`${preClass} max-h-[180px] px-3 py-2.5`}>{entry.prompt}</pre>}
529
+ {entry.action === "skill" && (
530
+ <p className={cardCopyTextClass}>
531
+ Skill <code>{entry.skill}</code>
532
+ {entry.guide ? <> · Leitfaden <code>{entry.guide}</code></> : " · ohne Leitfaden"}
533
+ </p>
534
+ )}
535
+ {entry.action === "script" && (
536
+ <p className={cardCopyTextClass}>
537
+ {entry.coordinator ? "Mit Koordinator" : "Ohne Koordinator, das Script wählt den Primary-Actor"}
538
+ {entry.guide ? <> · Leitfaden <code>{entry.guide}</code></> : " · ohne Leitfaden"}
539
+ </p>
540
+ )}
541
+ </article>
542
+ ))}
543
+ </div>
544
+ </SettingsSection>
545
+ )}
546
+ {group.skills.length > 0 && (
547
+ <SettingsSection count={group.skills.length} title="Skills">
548
+ <div className={cardListClass}>
549
+ {group.skills.map((skill) => (
550
+ <button
551
+ className={cn(cardClass, "group relative grid w-full cursor-pointer gap-2 pr-[34px] text-left hover:border-[color-mix(in_srgb,var(--primary)_45%,var(--border))] hover:bg-[color-mix(in_srgb,var(--primary)_6%,var(--background))] focus-visible:border-[color-mix(in_srgb,var(--primary)_45%,var(--border))] focus-visible:bg-[color-mix(in_srgb,var(--primary)_6%,var(--background))]")}
552
+ key={skill.id}
553
+ onClick={() => setSelectedSkill(skill)}
554
+ type="button"
555
+ >
556
+ <header className={cardCopyClass}>
557
+ <strong className={cardTitleClass}>{skill.id}</strong>
558
+ <small className={cardNoteClass}>{skill.owner}</small>
559
+ </header>
560
+ <span className={statusListClass}>
561
+ {skill.audiences.map((audience) => (
562
+ <StatusBadge active key={audience} label={skillAudienceLabel(audience)} />
563
+ ))}
564
+ </span>
565
+ <span className="grid min-w-0 gap-[3px]">
566
+ {skill.paths.map((path) => <code className="truncate font-mono text-[0.66rem] text-muted-foreground" key={path} title={path}>{path}</code>)}
567
+ </span>
568
+ <span aria-hidden className="absolute top-1/2 right-3 flex -translate-y-1/2 text-muted-foreground group-hover:text-primary group-focus-visible:text-primary"><ChevronRightIcon size={13} /></span>
569
+ </button>
570
+ ))}
571
+ </div>
572
+ </SettingsSection>
573
+ )}
574
+ {group.extensions.length > 0 && (
575
+ <SettingsSection count={group.extensions.length} title="Erweiterungen">
576
+ <div className={cardListClass}>
577
+ {group.extensions.map((extension) => (
578
+ <ExtensionCard extension={extension} key={extension.id} />
579
+ ))}
580
+ </div>
581
+ </SettingsSection>
582
+ )}
583
+ {(group.configuration.length > 0 || publicConfigText !== undefined) && (
584
+ <SettingsSection count={group.configuration.length} title="Konfiguration">
585
+ <p className={sectionCopyClass}>
586
+ Angezeigt werden die Herkunft der Konfigurationsschlüssel und die öffentliche Client-Konfiguration,
587
+ niemals geheime Werte.
588
+ </p>
589
+ {group.configuration.length > 0 && (
590
+ <div className="grid gap-1.5 rounded-lg border border-border-soft bg-background/68 px-2.5 py-2">
591
+ <span className={valueLabelClass}>Konfigurationsquellen</span>
592
+ <div className="flex flex-wrap gap-1.5">
593
+ {group.configuration.map((entry) => (
594
+ <span className={tagClass} key={entry.key}>
595
+ <code className="font-mono">{entry.key}</code>
596
+ <small className="text-[0.59rem] text-muted-foreground">{entry.secret ? `${entry.source} (geheim)` : entry.source}</small>
597
+ </span>
598
+ ))}
599
+ </div>
600
+ </div>
601
+ )}
602
+ {publicConfigText !== undefined && (
603
+ <PromptCode content={publicConfigText} copyLabel={`${group.id} Client-Konfiguration kopieren`} />
604
+ )}
605
+ </SettingsSection>
606
+ )}
607
+ {group.web.state !== "hidden" && (
608
+ <SettingsSection
609
+ count={group.web.state === "contributions" ? group.web.contributions.length : undefined}
610
+ title="Web"
611
+ >
612
+ {group.web.state === "none" && <SettingsEmpty>Kein Web-Modul</SettingsEmpty>}
613
+ {group.web.state === "withoutContributions" && <SettingsEmpty>Web-Modul ohne Beiträge</SettingsEmpty>}
614
+ {group.web.state === "contributions" && (
615
+ <div className="grid gap-[7px]">
616
+ {group.web.contributions.map((contribution) => (
617
+ <article className="grid min-w-0 gap-1.5 rounded-lg border border-border-soft bg-background/68 px-3 py-2.5" key={contribution.kind}>
618
+ <header className="flex items-center justify-between gap-2.5">
619
+ <strong className="text-[0.73rem] text-foreground">{contribution.kind}</strong>
620
+ <span className={chipClass}>{contribution.count}</span>
621
+ </header>
622
+ {contribution.details.length > 0 && (
623
+ <span className="flex flex-wrap gap-1.5">
624
+ {contribution.details.map((detail) => (
625
+ <span className={tagClass} key={detail}><code className="font-mono">{detail}</code></span>
626
+ ))}
627
+ </span>
628
+ )}
629
+ </article>
630
+ ))}
631
+ </div>
632
+ )}
633
+ </SettingsSection>
634
+ )}
635
+ {empty && <SettingsEmpty>Keine Beiträge entsprechen Filter und Suche.</SettingsEmpty>}
636
+ </div>
637
+ );
638
+ }
639
+
640
+ type SkillLoadState =
641
+ | { status: "loading" }
642
+ | { status: "ready"; detail: SettingsSkillDetail }
643
+ | { status: "failed"; error: string };
644
+
645
+ function SkillDetail({ onBack, skill }: { onBack: () => void; skill: SettingsSkill }) {
646
+ const [state, setState] = useState<SkillLoadState>({ status: "loading" });
647
+ const [activeFile, setActiveFile] = useState<string | null>(null);
648
+
649
+ useEffect(() => {
650
+ const controller = new AbortController();
651
+ setState({ status: "loading" });
652
+ setActiveFile(null);
653
+ void getSettingsSkill(skill.id, controller.signal)
654
+ .then((detail) => setState({ status: "ready", detail }))
655
+ .catch((caught: unknown) => {
656
+ if (controller.signal.aborted) return;
657
+ setState({ status: "failed", error: caught instanceof Error ? caught.message : String(caught) });
658
+ });
659
+ return () => controller.abort();
660
+ }, [skill.id]);
661
+
662
+ const files = state.status === "ready" ? state.detail.files : [];
663
+ const active = files.find((file) => skillFileKey(file) === activeFile) ?? files[0];
664
+
665
+ return (
666
+ <div className={settingsPageClass}>
667
+ <header className="grid justify-items-start gap-2.5">
668
+ <Button aria-label="Zurück zu den Beiträgen" className="rounded-full" onClick={onBack} size="icon" variant="outline"><ArrowLeftIcon /></Button>
669
+ <span className="grid gap-1">
670
+ <h2 className={pageTitleClass}>{skill.id}</h2>
671
+ <p className="text-[0.73rem] text-muted-foreground">{skill.owner}{files.length > 0 && ` / ${files.length} ${files.length === 1 ? "Datei" : "Dateien"}`}</p>
672
+ </span>
673
+ </header>
674
+ <SettingsSection title="Verfügbarkeit">
675
+ <SettingsValue label="Zielgruppe" value={skill.audiences.map(skillAudienceLabel).join(", ")} />
676
+ </SettingsSection>
677
+ <SettingsSection title="Registrierte Pfade">
678
+ {skill.paths.map((path) => <SettingsValue copy key={path} label="Pfad" value={path} />)}
679
+ </SettingsSection>
680
+ {state.status === "loading" && (
681
+ <div className={loadStateClass}>
682
+ <Spinner aria-hidden className="size-3" />
683
+ Skill wird gelesen.
684
+ </div>
685
+ )}
686
+ {state.status === "failed" && (
687
+ <div className={cn(loadStateClass, "flex-col text-center text-destructive")} role="alert">
688
+ <CircleAlertIcon size={14} />
689
+ <strong className="text-[0.86rem] text-foreground">Skill nicht lesbar</strong>
690
+ <span className="max-w-[560px]">{state.error}</span>
691
+ </div>
692
+ )}
693
+ {state.status === "ready" && files.length === 0 && (
694
+ <SettingsEmpty>Der Skill-Pfad enthält keine Dateien.</SettingsEmpty>
695
+ )}
696
+ {files.length > 1 && (
697
+ <div className="flex flex-wrap gap-1.5">
698
+ {files.map((file) => (
699
+ <Toggle key={skillFileKey(file)} pressed={file === active} onPressedChange={() => setActiveFile(skillFileKey(file))} size="sm" variant="outline">
700
+ {file.path}
701
+ </Toggle>
702
+ ))}
703
+ </div>
704
+ )}
705
+ {active && <SkillDocument file={active} />}
706
+ </div>
707
+ );
708
+ }
709
+
710
+ function SkillDocument({ file }: { file: SettingsSkillFile }) {
711
+ return (
712
+ <article className="min-w-0 rounded-xl border border-border-soft bg-background/76">
713
+ <header className="flex items-center justify-between gap-3 border-b border-border-soft px-3 py-2.5">
714
+ <span className={cardCopyClass}>
715
+ <strong className={cardTitleClass}>{file.path}</strong>
716
+ <small className="text-[0.63rem] text-muted-foreground">{formatBytes(file.bytes)}</small>
717
+ </span>
718
+ {file.content !== null && <CopyButton label={`${file.path} kopieren`} text={skillFileText(file)} />}
719
+ </header>
720
+ {file.frontMatter !== null && (
721
+ <details className={cn(disclosureClass, "mt-3 mr-3 ml-3")}>
722
+ <summary className={summaryClass}>
723
+ <span className={cardCopyClass}>
724
+ <strong className={cardTitleClass}>Frontmatter</strong>
725
+ <small className={cardNoteClass}>Kopfdaten, die die Agentenlaufzeit aus der Datei liest</small>
726
+ </span>
727
+ </summary>
728
+ <PromptCode content={file.frontMatter} copyLabel="Frontmatter kopieren" />
729
+ </details>
730
+ )}
731
+ {file.content === null
732
+ ? <SettingsEmpty className="m-3">Diese Datei ist nicht als Text darstellbar.</SettingsEmpty>
733
+ : file.path.toLowerCase().endsWith(".md")
734
+ ? <div className="px-4.5 pt-4 pb-5 text-[0.79rem] leading-[1.62] text-foreground"><Markdown text={file.content} /></div>
735
+ : <div className="overflow-auto"><SourceCode className="px-4 pt-4 pb-5 text-[0.7rem] leading-[1.55]" content={file.content} path={file.path} /></div>}
736
+ </article>
737
+ );
738
+ }
739
+
740
+ function ModelCard({ model }: { model: SettingsModel }) {
741
+ return (
742
+ <article className={cn(cardClass, "grid gap-[3px] px-3.5 py-3")}>
743
+ <strong className="truncate text-[0.79rem]">{model.label}</strong>
744
+ <span className="truncate text-[0.67rem] text-muted-foreground">{model.provider} / {model.model}</span>
745
+ <small className="truncate text-[0.67rem] text-muted-foreground">Treiber: {model.driver}</small>
746
+ </article>
747
+ );
748
+ }
749
+
750
+ function ProfileCard({ profile }: { profile: SettingsProfile }) {
751
+ const details = profile.driver === "agent"
752
+ ? [
753
+ profile.driver,
754
+ profile.provider,
755
+ profile.model,
756
+ ...(profile.thinking ? [`Denktiefe ${profile.thinking}`] : []),
757
+ ]
758
+ : [profile.driver];
759
+ return (
760
+ <article className={cardClass}>
761
+ <header className={cardHeaderClass}>
762
+ <span className={cardCopyClass}>
763
+ <strong className={cardTitleClass}>{profile.name}</strong>
764
+ <small className={cardNoteClass}>{details.join(" / ")}</small>
765
+ </span>
766
+ </header>
767
+ <p className={cardCopyTextClass}>{profile.description}</p>
768
+ <footer className="flex flex-wrap gap-x-3 gap-y-1.5 text-[0.64rem] text-muted-foreground">
769
+ <span>{profile.turnTimeoutMs === null ? "Kein Turn-Timeout" : `Turn-Timeout ${formatDuration(profile.turnTimeoutMs)}`}</span>
770
+ <span>{profile.isolateWorkspace ? "Eigener Agenten-Workspace" : "Gemeinsamer Run-Workspace"}</span>
771
+ </footer>
772
+ </article>
773
+ );
774
+ }
775
+
776
+ function ExtensionCard({ extension }: { extension: SettingsAgentExtension }) {
777
+ return (
778
+ <article className={cn(cardClass, "grid gap-2")}>
779
+ <header className={cardHeaderClass}>
780
+ <span className={cardCopyClass}>
781
+ <strong className={cardTitleClass}>{extension.id}</strong>
782
+ <small className={cardNoteClass}>{extension.owner}</small>
783
+ </span>
784
+ <StatusBadge active label={extension.kind === "internal" ? "Intern" : "Plugin-Beitrag"} />
785
+ </header>
786
+ <SettingsValue label="Auflösung je Agent" value={extension.resolvesPerAgent ? "Ja" : "Nein"} />
787
+ {extension.factories.length > 0 && (
788
+ <SettingsValue
789
+ label="Factories"
790
+ value={extension.factories
791
+ .map((factory) => `${factory.name ?? "anonym"} (${factory.scope})`)
792
+ .join(", ")}
793
+ />
794
+ )}
795
+ </article>
796
+ );
797
+ }
798
+
799
+ function ToolCard({ tool }: { tool: SettingsTool }) {
800
+ return (
801
+ <article className={cn(cardClass, "grid gap-2.5")}>
802
+ <header className={cardHeaderClass}>
803
+ <span className={cardCopyClass}>
804
+ <strong className={cardTitleClass}>{tool.name}</strong>
805
+ <small className={cardNoteClass}>{tool.id}</small>
806
+ </span>
807
+ <span className={statusListClass}>
808
+ <span className={cn(chipClass, "bg-primary/12 text-primary")}>{toolKindLabel(tool.kind)}</span>
809
+ <span className={chipClass}>{toolAvailabilityLabel(tool.availability)}</span>
810
+ <span className={chipClass}>{functionSurfaceLabel(tool.nativeTool)}</span>
811
+ </span>
812
+ </header>
813
+ <p className={cn(cardCopyTextClass, "my-0")}>{tool.description}</p>
814
+ <dl className="grid grid-cols-2 gap-1.5 max-md:grid-cols-1">
815
+ {[["Eigentümer", tool.owner], ["Herkunft", tool.source], ["Scope", toolScopeLabel(tool.scope)], ["Verfügbarkeit", tool.availabilityDetail]].map(([label, value]) => (
816
+ <div className="grid min-w-0 gap-0.5 rounded-lg border border-border-soft bg-background/68 px-2 py-1.5" key={label}>
817
+ <dt className="text-[0.61rem] text-muted-foreground">{label}</dt>
818
+ <dd className="min-w-0 text-[0.68rem] text-foreground [overflow-wrap:anywhere]">{value}</dd>
819
+ </div>
820
+ ))}
821
+ </dl>
822
+ </article>
823
+ );
824
+ }
825
+
826
+ function SettingsPage({ children, description, title }: { children: ReactNode; description: string; title: string }) {
827
+ return (
828
+ <div className={settingsPageClass}>
829
+ <header>
830
+ <h2 className={pageTitleClass}>{title}</h2>
831
+ <p className={pageLeadClass}>{description}</p>
832
+ </header>
833
+ {children}
834
+ </div>
835
+ );
836
+ }
837
+
838
+ function SettingsSection({ children, count, panel, title }: { children: ReactNode; count?: number; panel?: boolean; title: string }) {
839
+ const body = (
840
+ <>
841
+ <header className="flex min-h-6 items-center gap-2">
842
+ <h3 className={cn("text-[0.79rem] font-bold tracking-[0.015em] text-foreground", panel && "text-[0.94rem]")}>{title}</h3>
843
+ {count !== undefined && <span className="min-w-5 rounded-full bg-foreground/7 px-1.5 py-px text-center text-[0.62rem] text-muted-foreground">{count}</span>}
844
+ </header>
845
+ {children}
846
+ </>
847
+ );
848
+ if (panel) return <Card className={panelSectionClass}>{body}</Card>;
849
+ return <section className="grid gap-2.5">{body}</section>;
850
+ }
851
+
852
+ function SettingsFact({ detail, label, value }: { detail: string; label: string; value: string }) {
853
+ return (
854
+ <article className="grid min-w-0 gap-[3px] rounded-xl border border-border-soft bg-background/78 px-3.5 py-3">
855
+ <span className="text-[0.62rem] text-muted-foreground uppercase">{label}</span>
856
+ <strong className="truncate text-[0.91rem] text-foreground">{value}</strong>
857
+ <small className="truncate text-[0.66rem] text-muted-foreground">{detail}</small>
858
+ </article>
859
+ );
860
+ }
861
+
862
+ function SettingsValue({ copy = false, label, value }: { copy?: boolean; label: string; value: string }) {
863
+ return (
864
+ <div className="grid min-h-[38px] grid-cols-[minmax(130px,0.28fr)_minmax(0,1fr)_auto] items-center gap-2.5 rounded-lg border border-border-soft bg-background/68 px-2.5 py-1.5 max-[520px]:grid-cols-[minmax(0,1fr)_auto]">
865
+ <span className={cn(valueLabelClass, "max-[520px]:col-span-full")}>{label}</span>
866
+ <code className="min-w-0 truncate font-mono text-[0.7rem] text-foreground" title={value}>{value}</code>
867
+ {copy && <CopyButton label={`${label} kopieren`} text={value} />}
868
+ </div>
869
+ );
870
+ }
871
+
872
+ function PromptCode({ content, copyLabel }: { content: string; copyLabel: string }) {
873
+ return (
874
+ <div className="relative min-w-0">
875
+ <CopyButton className="absolute top-2 right-2 z-1" label={copyLabel} text={content} />
876
+ <pre className={`${preClass} max-h-[520px] px-3 pt-11 pb-3`}>{content}</pre>
877
+ </div>
878
+ );
879
+ }
880
+
881
+ function CopyButton({ className, label, text }: { className?: string; label: string; text: string }) {
882
+ const [status, setStatus] = useState<"idle" | "copied" | "failed">("idle");
883
+ useEffect(() => {
884
+ if (status === "idle") return;
885
+ const timer = window.setTimeout(() => setStatus("idle"), 1800);
886
+ return () => window.clearTimeout(timer);
887
+ }, [status]);
888
+ const copy = () => {
889
+ if (!navigator.clipboard) {
890
+ setStatus("failed");
891
+ return;
892
+ }
893
+ void navigator.clipboard.writeText(text)
894
+ .then(() => setStatus("copied"))
895
+ .catch(() => setStatus("failed"));
896
+ };
897
+ const statusLabel = status === "copied" ? "Kopiert" : status === "failed" ? "Nicht kopiert" : "Kopieren";
898
+ return (
899
+ <Button
900
+ aria-label={label}
901
+ className={cn("flex-shrink-0", className)}
902
+ onClick={copy}
903
+ size="sm"
904
+ title={statusLabel}
905
+ variant="outline"
906
+ >
907
+ {status === "copied" ? <CheckIcon /> : status === "failed" ? <CircleAlertIcon /> : <CopyIcon />}
908
+ <span className="max-[520px]:hidden">{statusLabel}</span>
909
+ </Button>
910
+ );
911
+ }
912
+
913
+ function StatusBadge({ active, label }: { active: boolean; label: string }) {
914
+ return <span className={cn(chipClass, active && "bg-primary/12 text-primary")}>{label}</span>;
915
+ }
916
+
917
+ function SettingsNote({ children }: { children: ReactNode }) {
918
+ return <p className="flex items-start gap-2 rounded-lg border border-[color-mix(in_srgb,var(--primary)_22%,var(--border))] bg-primary/6 px-3 py-2.5 text-[0.71rem] leading-normal text-muted-foreground [&>svg]:mt-px [&>svg]:flex-shrink-0 [&>svg]:text-primary"><InfoIcon size={15} />{children}</p>;
919
+ }
920
+
921
+ function SettingsEmpty({ children, className }: { children: ReactNode; className?: string }) {
922
+ return <p className={cn("rounded-lg border border-dashed border-border p-4.5 text-center text-[0.72rem] text-muted-foreground", className)}>{children}</p>;
923
+ }
924
+
925
+ const modelKey = (model: SettingsModel) => `${model.driver}/${model.provider ?? ""}/${model.model ?? ""}`;
926
+
927
+ const skillFileKey = (file: SettingsSkillFile) => `${file.root}/${file.path}`;
928
+
929
+ const skillFileText = (file: SettingsSkillFile) =>
930
+ file.frontMatter === null ? file.content ?? "" : `---\n${file.frontMatter}\n---\n\n${file.content ?? ""}`;
931
+
932
+ const formatDuration = (milliseconds: number) => {
933
+ const seconds = milliseconds / 1000;
934
+ if (seconds < 60) return `${seconds.toLocaleString("de-DE")} s`;
935
+ const minutes = seconds / 60;
936
+ if (minutes < 60) return `${minutes.toLocaleString("de-DE")} min`;
937
+ return `${(minutes / 60).toLocaleString("de-DE")} h`;
938
+ };
939
+
940
+ const sensitiveKey = (key: string) => /secret|token|password|credential|api.?key|authorization|cookie/i.test(key);
941
+
942
+ const sanitizedValue = (value: unknown, key = ""): unknown => {
943
+ if (key && sensitiveKey(key)) return "[ausgeblendet]";
944
+ if (Array.isArray(value)) return value.map((entry) => sanitizedValue(entry));
945
+ if (typeof value !== "object" || value === null) return value;
946
+ return Object.fromEntries(
947
+ Object.entries(value).map(([entryKey, entryValue]) => [entryKey, sanitizedValue(entryValue, entryKey)]),
948
+ );
949
+ };