@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.
- package/LICENSE +166 -0
- package/README.md +88 -0
- package/apps/server/agent-home/settings.json +3 -0
- package/apps/server/package.json +29 -0
- package/apps/server/src/access-projection.ts +97 -0
- package/apps/server/src/access-service.ts +22 -0
- package/apps/server/src/access-session.ts +204 -0
- package/apps/server/src/api/contracts.ts +203 -0
- package/apps/server/src/api/core-methods.ts +163 -0
- package/apps/server/src/api/delivery.ts +40 -0
- package/apps/server/src/api/reference.ts +146 -0
- package/apps/server/src/api/rights.ts +26 -0
- package/apps/server/src/chat-attachments.ts +52 -0
- package/apps/server/src/chat-context.ts +6 -0
- package/apps/server/src/chat-events.ts +185 -0
- package/apps/server/src/chat-handler.ts +37 -0
- package/apps/server/src/config-definition.ts +80 -0
- package/apps/server/src/config-file.ts +324 -0
- package/apps/server/src/config.ts +46 -0
- package/apps/server/src/data-directory.ts +42 -0
- package/apps/server/src/external-access.ts +40 -0
- package/apps/server/src/help-files.ts +63 -0
- package/apps/server/src/host-resolution-hooks.mjs +31 -0
- package/apps/server/src/host-resolution.ts +3 -0
- package/apps/server/src/host-version.ts +74 -0
- package/apps/server/src/layout.ts +36 -0
- package/apps/server/src/main.ts +54 -0
- package/apps/server/src/plugin-support/actor-programs/capability-resolver.ts +107 -0
- package/apps/server/src/plugin-support/actor-programs/limits.ts +33 -0
- package/apps/server/src/plugin-support/actor-programs/operations.ts +19 -0
- package/apps/server/src/plugin-support/actor-programs/service.ts +16 -0
- package/apps/server/src/plugin-support/agent-tool.ts +60 -0
- package/apps/server/src/plugin-support/asset-path.ts +4 -0
- package/apps/server/src/plugin-support/await-with-signal.ts +18 -0
- package/apps/server/src/plugin-support/chat-display-contract.ts +7 -0
- package/apps/server/src/plugin-support/chat-display-policy.ts +55 -0
- package/apps/server/src/plugin-support/front-matter.ts +44 -0
- package/apps/server/src/plugin-support/http.ts +93 -0
- package/apps/server/src/plugin-support/language-server/contract.ts +18 -0
- package/apps/server/src/plugin-support/language-server/plugin.ts +32 -0
- package/apps/server/src/plugin-support/language-server/snapshot-method.ts +17 -0
- package/apps/server/src/plugin-support/language-server/tools.ts +73 -0
- package/apps/server/src/plugin-support/model-choice.ts +109 -0
- package/apps/server/src/plugin-support/model-upstreams.ts +12 -0
- package/apps/server/src/plugin-support/native-typescript-child.ts +78 -0
- package/apps/server/src/plugin-support/native-typescript-executor.ts +260 -0
- package/apps/server/src/plugin-support/plugin-config.ts +48 -0
- package/apps/server/src/plugin-support/plugin-folder.ts +81 -0
- package/apps/server/src/plugin-support/plugin-module.ts +14 -0
- package/apps/server/src/plugin-support/plugins-root.ts +41 -0
- package/apps/server/src/plugin-support/product-model-settings-contract.ts +24 -0
- package/apps/server/src/plugin-support/product-model-settings.ts +120 -0
- package/apps/server/src/plugin-support/product-start-options.ts +104 -0
- package/apps/server/src/plugin-support/prompt.ts +68 -0
- package/apps/server/src/plugin-support/provision.ts +85 -0
- package/apps/server/src/plugin-support/run-scripts.ts +88 -0
- package/apps/server/src/plugin-support/shell-platform.ts +21 -0
- package/apps/server/src/plugin-support/skills.ts +97 -0
- package/apps/server/src/plugin-support/start-entries-contract.ts +71 -0
- package/apps/server/src/plugin-support/start-options-contract.ts +65 -0
- package/apps/server/src/plugin-support/system-prompts.ts +138 -0
- package/apps/server/src/plugin-support/thinking-level.ts +8 -0
- package/apps/server/src/plugin-support/tool-availability.ts +20 -0
- package/apps/server/src/plugin-support/workspace-ownership.ts +36 -0
- package/apps/server/src/plugin-support/workspace-sandbox-host.ts +213 -0
- package/apps/server/src/plugin-support/workspace-tool-naming.ts +11 -0
- package/apps/server/src/plugin-support/zip.ts +69 -0
- package/apps/server/src/profile/compose.ts +69 -0
- package/apps/server/src/profile/plugin-discovery.ts +112 -0
- package/apps/server/src/profile/plugin-list.ts +19 -0
- package/apps/server/src/profile/provisioning.ts +81 -0
- package/apps/server/src/protocol.ts +106 -0
- package/apps/server/src/provider.ts +817 -0
- package/apps/server/src/ragents/actor-chat-history.ts +111 -0
- package/apps/server/src/ragents/chat-projection.ts +55 -0
- package/apps/server/src/ragents/chat-text-positions.ts +43 -0
- package/apps/server/src/ragents/coordinator.ts +5 -0
- package/apps/server/src/ragents/document-store.ts +12 -0
- package/apps/server/src/ragents/engine.ts +417 -0
- package/apps/server/src/ragents/global-chat.ts +40 -0
- package/apps/server/src/ragents/host-services.ts +26 -0
- package/apps/server/src/ragents/journal-chat-events.ts +52 -0
- package/apps/server/src/ragents/product-runtime.ts +31 -0
- package/apps/server/src/ragents/runtime-bridge.ts +7 -0
- package/apps/server/src/ragents/session.ts +859 -0
- package/apps/server/src/ragents/start-option-state.ts +37 -0
- package/apps/server/src/ragents/typescript-tools.ts +182 -0
- package/apps/server/src/ragents/workspace-runtime.ts +64 -0
- package/apps/server/src/rpc/dispatcher.ts +178 -0
- package/apps/server/src/rpc/http-transport.ts +178 -0
- package/apps/server/src/rpc/stdio-transport.ts +44 -0
- package/apps/server/src/run-preparation-contract.ts +20 -0
- package/apps/server/src/run-preparation-input.ts +16 -0
- package/apps/server/src/run-preparation.ts +147 -0
- package/apps/server/src/run-transfer.ts +264 -0
- package/apps/server/src/server.ts +312 -0
- package/apps/server/src/settings.ts +209 -0
- package/apps/server/src/startup.ts +13 -0
- package/apps/server/src/title-compactor.ts +131 -0
- package/apps/server/src/title-settings-contract.ts +9 -0
- package/apps/server/src/title-settings.ts +67 -0
- package/apps/web/package.json +41 -0
- package/apps/web/src/AccessContext.tsx +125 -0
- package/apps/web/src/App.tsx +315 -0
- package/apps/web/src/CanvasShortcuts.tsx +60 -0
- package/apps/web/src/DiffCode.tsx +89 -0
- package/apps/web/src/HelpDialog.tsx +87 -0
- package/apps/web/src/MaterialSettings.tsx +40 -0
- package/apps/web/src/Overview.tsx +201 -0
- package/apps/web/src/PluginActivation.ts +41 -0
- package/apps/web/src/PluginChat.tsx +552 -0
- package/apps/web/src/PluginRegistry.tsx +689 -0
- package/apps/web/src/RunPreparationChat.tsx +111 -0
- package/apps/web/src/RunStore.ts +86 -0
- package/apps/web/src/SessionList.tsx +148 -0
- package/apps/web/src/SettingsModal.tsx +949 -0
- package/apps/web/src/SourceCode.tsx +49 -0
- package/apps/web/src/StartOptions.tsx +231 -0
- package/apps/web/src/StartSurface.tsx +161 -0
- package/apps/web/src/StatusGroup.tsx +18 -0
- package/apps/web/src/ThemeSettings.tsx +46 -0
- package/apps/web/src/TitleModelSettings.tsx +100 -0
- package/apps/web/src/Toolbar.tsx +28 -0
- package/apps/web/src/WorkspacePanel.tsx +309 -0
- package/apps/web/src/access-session.ts +27 -0
- package/apps/web/src/access-token.ts +31 -0
- package/apps/web/src/api.ts +368 -0
- package/apps/web/src/chat/ChatInputToolbar.tsx +488 -0
- package/apps/web/src/chat/ChatMessages.tsx +666 -0
- package/apps/web/src/chat/ChatPanel.tsx +61 -0
- package/apps/web/src/chat/DetailModeSwitch.tsx +58 -0
- package/apps/web/src/chat/Markdown.tsx +104 -0
- package/apps/web/src/chat/QuestionCard.tsx +107 -0
- package/apps/web/src/chat/StepPopover.tsx +82 -0
- package/apps/web/src/chat/WorkingScenes.tsx +235 -0
- package/apps/web/src/chat/attachments.ts +53 -0
- package/apps/web/src/chat/chat-scroll.ts +41 -0
- package/apps/web/src/chat/chat-target.ts +21 -0
- package/apps/web/src/chat/requests.ts +23 -0
- package/apps/web/src/chat/texts.ts +61 -0
- package/apps/web/src/chat/types.ts +26 -0
- package/apps/web/src/chat/useAttachmentCapabilities.ts +35 -0
- package/apps/web/src/chat/useChat.ts +46 -0
- package/apps/web/src/chat/user-location.ts +22 -0
- package/apps/web/src/column/ColumnApp.tsx +158 -0
- package/apps/web/src/column/ColumnMenu.tsx +37 -0
- package/apps/web/src/column/ColumnRunHeader.tsx +43 -0
- package/apps/web/src/column/column-location.ts +30 -0
- package/apps/web/src/column/host-contract.ts +83 -0
- package/apps/web/src/column/host.ts +101 -0
- package/apps/web/src/column/use-session-list.ts +42 -0
- package/apps/web/src/column.tsx +43 -0
- package/apps/web/src/diff-view.css +38 -0
- package/apps/web/src/help-samples.ts +11 -0
- package/apps/web/src/highlighting.css +74 -0
- package/apps/web/src/highlighting.ts +262 -0
- package/apps/web/src/lib/format.ts +5 -0
- package/apps/web/src/lib/guards.ts +8 -0
- package/apps/web/src/lib/http.ts +9 -0
- package/apps/web/src/lib/labels.ts +11 -0
- package/apps/web/src/lib/local-storage-setting.ts +39 -0
- package/apps/web/src/main.tsx +30 -0
- package/apps/web/src/material-settings.ts +104 -0
- package/apps/web/src/model-settings-events.ts +1 -0
- package/apps/web/src/page-opener.tsx +14 -0
- package/apps/web/src/panel/LoginForm.tsx +31 -0
- package/apps/web/src/panel/OverviewPage.tsx +90 -0
- package/apps/web/src/panel/PanelPage.tsx +9 -0
- package/apps/web/src/panel/SettingsPage.tsx +102 -0
- package/apps/web/src/panel/contract.ts +101 -0
- package/apps/web/src/panel/target-state.ts +53 -0
- package/apps/web/src/panel.tsx +30 -0
- package/apps/web/src/plugin-bootstrap.ts +90 -0
- package/apps/web/src/plugin-discovery.ts +5 -0
- package/apps/web/src/rpc/client.ts +301 -0
- package/apps/web/src/rpc.ts +4 -0
- package/apps/web/src/run-overview.ts +34 -0
- package/apps/web/src/run-preparation.ts +16 -0
- package/apps/web/src/run-read-state.ts +33 -0
- package/apps/web/src/settings-contributions.ts +274 -0
- package/apps/web/src/theme.ts +135 -0
- package/apps/web/src/title-model-settings.ts +51 -0
- package/apps/web/src/toolLine.ts +67 -0
- package/apps/web/src/ui/ListDetail.tsx +149 -0
- package/apps/web/src/ui/SectionLabel.tsx +7 -0
- package/apps/web/src/ui/SvgEdge.tsx +39 -0
- package/apps/web/src/ui/alert.tsx +75 -0
- package/apps/web/src/ui/badge.tsx +51 -0
- package/apps/web/src/ui/button.tsx +57 -0
- package/apps/web/src/ui/card.tsx +102 -0
- package/apps/web/src/ui/checkbox.tsx +26 -0
- package/apps/web/src/ui/dialog.tsx +250 -0
- package/apps/web/src/ui/dropdown-menu.tsx +265 -0
- package/apps/web/src/ui/empty.tsx +103 -0
- package/apps/web/src/ui/field.tsx +236 -0
- package/apps/web/src/ui/frame.css +4 -0
- package/apps/web/src/ui/index.ts +43 -0
- package/apps/web/src/ui/input.tsx +19 -0
- package/apps/web/src/ui/label.tsx +17 -0
- package/apps/web/src/ui/modal-controller.ts +70 -0
- package/apps/web/src/ui/modal.tsx +62 -0
- package/apps/web/src/ui/popover.tsx +102 -0
- package/apps/web/src/ui/progress.tsx +80 -0
- package/apps/web/src/ui/radio-group.tsx +35 -0
- package/apps/web/src/ui/select.tsx +198 -0
- package/apps/web/src/ui/separator.tsx +22 -0
- package/apps/web/src/ui/skeleton.tsx +13 -0
- package/apps/web/src/ui/spinner.tsx +10 -0
- package/apps/web/src/ui/switch.tsx +29 -0
- package/apps/web/src/ui/table.tsx +113 -0
- package/apps/web/src/ui/tabs.tsx +79 -0
- package/apps/web/src/ui/tailwind.css +21 -0
- package/apps/web/src/ui/textarea.tsx +17 -0
- package/apps/web/src/ui/theme.css +300 -0
- package/apps/web/src/ui/toggle-group.tsx +87 -0
- package/apps/web/src/ui/toggle.tsx +42 -0
- package/apps/web/src/ui/tooltip.tsx +63 -0
- package/apps/web/src/ui/useFileInput.ts +50 -0
- package/apps/web/src/virtual-plugins.d.ts +3 -0
- package/apps/web/src/vite-env.d.ts +1 -0
- package/package.json +82 -0
- package/packages/agent/package.json +64 -0
- package/packages/agent/src/config.ts +161 -0
- package/packages/agent/src/core/agent-session-runtime.ts +548 -0
- package/packages/agent/src/core/agent-session-services.ts +224 -0
- package/packages/agent/src/core/agent-session.ts +3357 -0
- package/packages/agent/src/core/auth-guidance.ts +18 -0
- package/packages/agent/src/core/auth-storage.ts +271 -0
- package/packages/agent/src/core/bash-executor.ts +156 -0
- package/packages/agent/src/core/compaction/branch-summarization.ts +372 -0
- package/packages/agent/src/core/compaction/compaction.ts +875 -0
- package/packages/agent/src/core/compaction/index.ts +7 -0
- package/packages/agent/src/core/compaction/utils.ts +174 -0
- package/packages/agent/src/core/defaults.ts +3 -0
- package/packages/agent/src/core/diagnostics.ts +15 -0
- package/packages/agent/src/core/event-bus.ts +33 -0
- package/packages/agent/src/core/exec.ts +107 -0
- package/packages/agent/src/core/experimental.ts +3 -0
- package/packages/agent/src/core/extensions/index.ts +149 -0
- package/packages/agent/src/core/extensions/loader.ts +709 -0
- package/packages/agent/src/core/extensions/runner.ts +1132 -0
- package/packages/agent/src/core/extensions/types.ts +1460 -0
- package/packages/agent/src/core/extensions/wrapper.ts +45 -0
- package/packages/agent/src/core/footer-data-provider.ts +388 -0
- package/packages/agent/src/core/http-dispatcher.ts +106 -0
- package/packages/agent/src/core/index.ts +78 -0
- package/packages/agent/src/core/messages.ts +195 -0
- package/packages/agent/src/core/model-config.ts +287 -0
- package/packages/agent/src/core/model-registry.ts +126 -0
- package/packages/agent/src/core/model-resolver.ts +675 -0
- package/packages/agent/src/core/model-runtime.ts +517 -0
- package/packages/agent/src/core/output-guard.ts +108 -0
- package/packages/agent/src/core/package-manager.ts +2441 -0
- package/packages/agent/src/core/prompt-templates.ts +284 -0
- package/packages/agent/src/core/provider-composer.ts +549 -0
- package/packages/agent/src/core/resolve-config-value.ts +287 -0
- package/packages/agent/src/core/resource-loader.ts +946 -0
- package/packages/agent/src/core/runtime-credentials.ts +48 -0
- package/packages/agent/src/core/sdk.ts +358 -0
- package/packages/agent/src/core/session-cwd.ts +59 -0
- package/packages/agent/src/core/session-manager.ts +1623 -0
- package/packages/agent/src/core/settings-manager.ts +1212 -0
- package/packages/agent/src/core/skills.ts +487 -0
- package/packages/agent/src/core/slash-commands.ts +41 -0
- package/packages/agent/src/core/source-info.ts +40 -0
- package/packages/agent/src/core/system-prompt.ts +147 -0
- package/packages/agent/src/core/timings.ts +50 -0
- package/packages/agent/src/core/tools/bash.ts +314 -0
- package/packages/agent/src/core/tools/edit-diff.ts +704 -0
- package/packages/agent/src/core/tools/edit.ts +222 -0
- package/packages/agent/src/core/tools/file-mutation-queue.ts +61 -0
- package/packages/agent/src/core/tools/index.ts +130 -0
- package/packages/agent/src/core/tools/output-accumulator.ts +222 -0
- package/packages/agent/src/core/tools/path-utils.ts +118 -0
- package/packages/agent/src/core/tools/read.ts +195 -0
- package/packages/agent/src/core/tools/tool-definition-wrapper.ts +45 -0
- package/packages/agent/src/core/tools/truncate.ts +276 -0
- package/packages/agent/src/core/tools/write.ts +90 -0
- package/packages/agent/src/core/trust-manager.ts +244 -0
- package/packages/agent/src/index.ts +287 -0
- package/packages/agent/src/utils/ansi.ts +60 -0
- package/packages/agent/src/utils/child-process.ts +137 -0
- package/packages/agent/src/utils/exif-orientation.ts +183 -0
- package/packages/agent/src/utils/frontmatter.ts +39 -0
- package/packages/agent/src/utils/fs-watch.ts +30 -0
- package/packages/agent/src/utils/git.ts +226 -0
- package/packages/agent/src/utils/image-convert.ts +49 -0
- package/packages/agent/src/utils/image-process.ts +119 -0
- package/packages/agent/src/utils/image-resize-core.ts +164 -0
- package/packages/agent/src/utils/image-resize-worker.ts +42 -0
- package/packages/agent/src/utils/image-resize.ts +123 -0
- package/packages/agent/src/utils/json.ts +6 -0
- package/packages/agent/src/utils/mime.ts +116 -0
- package/packages/agent/src/utils/paths.ts +118 -0
- package/packages/agent/src/utils/photon.ts +139 -0
- package/packages/agent/src/utils/shell.ts +225 -0
- package/packages/agent/src/utils/sleep.ts +18 -0
- package/packages/agent/src/utils/tools-manager.ts +63 -0
- package/packages/agent-core/package.json +32 -0
- package/packages/agent-core/src/agent-loop.ts +877 -0
- package/packages/agent-core/src/agent.ts +598 -0
- package/packages/agent-core/src/index.ts +4 -0
- package/packages/agent-core/src/types.ts +455 -0
- package/packages/agent-core/src/uuid.ts +54 -0
- package/packages/ai/package.json +46 -0
- package/packages/ai/src/api/ai-sdk-messages.ts +102 -0
- package/packages/ai/src/api/ai-sdk-transport.ts +53 -0
- package/packages/ai/src/api/ai-sdk.lazy.ts +4 -0
- package/packages/ai/src/api/ai-sdk.ts +273 -0
- package/packages/ai/src/api/lazy.ts +75 -0
- package/packages/ai/src/api/openrouter-images.lazy.ts +10 -0
- package/packages/ai/src/api/openrouter-images.ts +98 -0
- package/packages/ai/src/api/simple-options.ts +77 -0
- package/packages/ai/src/api/transform-messages.ts +185 -0
- package/packages/ai/src/api-registry.ts +226 -0
- package/packages/ai/src/auth/context.ts +45 -0
- package/packages/ai/src/auth/credential-store.ts +51 -0
- package/packages/ai/src/auth/helpers.ts +47 -0
- package/packages/ai/src/auth/resolve.ts +139 -0
- package/packages/ai/src/auth/types.ts +220 -0
- package/packages/ai/src/compat/extension-oauth-types.ts +45 -0
- package/packages/ai/src/env-api-keys.ts +24 -0
- package/packages/ai/src/image-models.generated.ts +533 -0
- package/packages/ai/src/images-models.ts +274 -0
- package/packages/ai/src/index.ts +33 -0
- package/packages/ai/src/models-store.ts +38 -0
- package/packages/ai/src/models.generated.ts +6 -0
- package/packages/ai/src/models.ts +705 -0
- package/packages/ai/src/oauth.ts +10 -0
- package/packages/ai/src/providers/all.ts +64 -0
- package/packages/ai/src/providers/faux.ts +539 -0
- package/packages/ai/src/providers/openrouter-images.ts +14 -0
- package/packages/ai/src/providers/openrouter.models.ts +6050 -0
- package/packages/ai/src/providers/openrouter.ts +15 -0
- package/packages/ai/src/session-resources.ts +24 -0
- package/packages/ai/src/types.ts +692 -0
- package/packages/ai/src/utils/abort-signals.ts +41 -0
- package/packages/ai/src/utils/deferred-tools.ts +39 -0
- package/packages/ai/src/utils/diagnostics.ts +45 -0
- package/packages/ai/src/utils/error-body.ts +129 -0
- package/packages/ai/src/utils/estimate.ts +146 -0
- package/packages/ai/src/utils/event-stream.ts +88 -0
- package/packages/ai/src/utils/hash.ts +13 -0
- package/packages/ai/src/utils/headers.ts +18 -0
- package/packages/ai/src/utils/json-parse.ts +124 -0
- package/packages/ai/src/utils/node-http-proxy.ts +112 -0
- package/packages/ai/src/utils/overflow.ts +165 -0
- package/packages/ai/src/utils/provider-env.ts +52 -0
- package/packages/ai/src/utils/retry.ts +101 -0
- package/packages/ai/src/utils/sanitize-unicode.ts +25 -0
- package/packages/ai/src/utils/typebox-helpers.ts +24 -0
- package/packages/ai/src/utils/validation.ts +383 -0
- package/packages/ragents/package.json +31 -0
- package/packages/ragents/src/access.ts +54 -0
- package/packages/ragents/src/agents/actor-input.ts +191 -0
- package/packages/ragents/src/agents/catalog.ts +220 -0
- package/packages/ragents/src/agents/delivery.ts +187 -0
- package/packages/ragents/src/agents/live.ts +71 -0
- package/packages/ragents/src/agents/plugins.ts +130 -0
- package/packages/ragents/src/agents/scheduler.ts +1048 -0
- package/packages/ragents/src/agents/schemas.ts +64 -0
- package/packages/ragents/src/agents/tool-orientation.ts +12 -0
- package/packages/ragents/src/agents/tools.ts +709 -0
- package/packages/ragents/src/agents/toolset.ts +324 -0
- package/packages/ragents/src/agents/turn.ts +65 -0
- package/packages/ragents/src/agents/workspace-tools.ts +11 -0
- package/packages/ragents/src/agents/workspaces.ts +15 -0
- package/packages/ragents/src/domain/draft.ts +11 -0
- package/packages/ragents/src/domain/driver.ts +56 -0
- package/packages/ragents/src/domain/event-semantics.ts +668 -0
- package/packages/ragents/src/domain/event-validation.ts +620 -0
- package/packages/ragents/src/domain/events.ts +236 -0
- package/packages/ragents/src/domain/json-patch.ts +77 -0
- package/packages/ragents/src/domain/json.ts +86 -0
- package/packages/ragents/src/domain/model.ts +267 -0
- package/packages/ragents/src/domain/plugin-state.ts +33 -0
- package/packages/ragents/src/domain/portable-id.ts +9 -0
- package/packages/ragents/src/domain/projection.ts +506 -0
- package/packages/ragents/src/domain/schema-errors.ts +56 -0
- package/packages/ragents/src/domain/vocabulary.ts +37 -0
- package/packages/ragents/src/drivers/agent-runtime.ts +1503 -0
- package/packages/ragents/src/drivers/agent.ts +108 -0
- package/packages/ragents/src/drivers/attachments.ts +56 -0
- package/packages/ragents/src/drivers/skill-preload.ts +205 -0
- package/packages/ragents/src/drivers/types.ts +77 -0
- package/packages/ragents/src/http/contracts.ts +80 -0
- package/packages/ragents/src/http/methods.ts +150 -0
- package/packages/ragents/src/index.ts +161 -0
- package/packages/ragents/src/plugin-host.ts +1184 -0
- package/packages/ragents/src/plugin-types.ts +373 -0
- package/packages/ragents/src/rpc/contract.ts +76 -0
- package/packages/ragents/src/rpc/contribution.ts +67 -0
- package/packages/ragents/src/rpc/peer.ts +208 -0
- package/packages/ragents/src/rpc/protocol.ts +129 -0
- package/packages/ragents/src/runtime/artifacts.ts +95 -0
- package/packages/ragents/src/runtime/canonical-hash.ts +5 -0
- package/packages/ragents/src/runtime/canonical-json.ts +41 -0
- package/packages/ragents/src/runtime/command.ts +35 -0
- package/packages/ragents/src/runtime/decisions/actions.ts +77 -0
- package/packages/ragents/src/runtime/decisions/actors.ts +283 -0
- package/packages/ragents/src/runtime/decisions/artifacts.ts +28 -0
- package/packages/ragents/src/runtime/decisions/inputs.ts +79 -0
- package/packages/ragents/src/runtime/decisions/subscriptions.ts +135 -0
- package/packages/ragents/src/runtime/decisions/turns.ts +166 -0
- package/packages/ragents/src/runtime/domain-error.ts +10 -0
- package/packages/ragents/src/runtime/durable-fs.ts +13 -0
- package/packages/ragents/src/runtime/failures.ts +18 -0
- package/packages/ragents/src/runtime/guards.ts +196 -0
- package/packages/ragents/src/runtime/journal-storage.ts +228 -0
- package/packages/ragents/src/runtime/journal.ts +952 -0
- package/packages/ragents/src/runtime/orchestration.ts +711 -0
- package/packages/ragents/src/runtime/serial-queue.ts +13 -0
- package/packages/ragents/src/runtime/services.ts +15 -0
- package/packages/ragents/src/runtime/stop.ts +186 -0
- package/packages/ragents/src/script/driver.ts +18 -0
- package/packages/ragents/src/script/mediators.ts +386 -0
- package/packages/ragents/src/script/programs.ts +10 -0
- package/packages/ragents/src/script/std.ts +27 -0
- package/packages/ragents/src/script/types.ts +6 -0
- package/packages/ragents/src/typescript/async-compiler.ts +322 -0
- package/packages/ragents/src/typescript/build-contract.ts +14 -0
- package/packages/ragents/src/typescript/compiler-worker.ts +52 -0
- package/packages/ragents/src/typescript/compiler.ts +304 -0
- package/packages/ragents/src/typescript/index.ts +48 -0
- package/packages/ragents/src/typescript/native-executor.ts +40 -0
- package/packages/ragents/src/typescript/native-program.ts +5 -0
- package/packages/ragents/src/typescript/run-context.ts +199 -0
- package/packages/ragents/src/typescript/schema.ts +176 -0
- package/packages/ragents/src/typescript/snippet.ts +121 -0
- package/packages/workspace-executor/package.json +25 -0
- package/packages/workspace-executor/src/context.ts +123 -0
- package/packages/workspace-executor/src/executor.ts +134 -0
- package/packages/workspace-executor/src/git-config-environment.ts +10 -0
- package/packages/workspace-executor/src/index.ts +52 -0
- package/packages/workspace-executor/src/language-server/adapters/fsharp.ts +59 -0
- package/packages/workspace-executor/src/language-server/adapters/index.ts +7 -0
- package/packages/workspace-executor/src/language-server/adapters/roslyn.ts +54 -0
- package/packages/workspace-executor/src/language-server/adapters/typescript.ts +46 -0
- package/packages/workspace-executor/src/language-server/contract.ts +23 -0
- package/packages/workspace-executor/src/language-server/diagnostics.ts +62 -0
- package/packages/workspace-executor/src/language-server/host.ts +409 -0
- package/packages/workspace-executor/src/language-server/json-rpc.ts +103 -0
- package/packages/workspace-executor/src/language-server/roots.ts +29 -0
- package/packages/workspace-executor/src/language-server/session.ts +442 -0
- package/packages/workspace-executor/src/language-server/solution.ts +13 -0
- package/packages/workspace-executor/src/managed-process.ts +329 -0
- package/packages/workspace-executor/src/paths.ts +43 -0
- package/packages/workspace-executor/src/run-marker.ts +6 -0
- package/packages/workspace-executor/src/safe-environment.ts +47 -0
- package/packages/workspace-executor/src/sandbox-tools.ts +258 -0
- package/packages/workspace-executor/src/session-ident.ts +37 -0
- package/packages/workspace-executor/src/shell-platform.ts +11 -0
- package/packages/workspace-executor/src/tools.ts +28 -0
- package/plugins/package.json +8 -0
- package/plugins/ragents.activity/server/index.ts +9 -0
- package/plugins/ragents.activity/web/ActivityHeader.tsx +58 -0
- package/plugins/ragents.activity/web/activity.ts +144 -0
- package/plugins/ragents.activity/web/index.tsx +13 -0
- package/plugins/ragents.actor-programs/client-ui/DataTable.tsx +100 -0
- package/plugins/ragents.actor-programs/client-ui/FilePicker.tsx +65 -0
- package/plugins/ragents.actor-programs/client-ui/FlowDiagram.tsx +234 -0
- package/plugins/ragents.actor-programs/client-ui/FlowDiagramRenderer.tsx +85 -0
- package/plugins/ragents.actor-programs/client-ui/Form.tsx +126 -0
- package/plugins/ragents.actor-programs/client-ui/Layout.tsx +27 -0
- package/plugins/ragents.actor-programs/client-ui/MessageList.tsx +30 -0
- package/plugins/ragents.actor-programs/client-ui/Viewers.tsx +41 -0
- package/plugins/ragents.actor-programs/client-ui/WorkflowDiagram.tsx +14 -0
- package/plugins/ragents.actor-programs/client-ui/contracts.d.ts +84 -0
- package/plugins/ragents.actor-programs/client-ui/file-contracts.d.ts +19 -0
- package/plugins/ragents.actor-programs/client-ui/file-selection.ts +24 -0
- package/plugins/ragents.actor-programs/client-ui/flow-diagram-contracts.d.ts +27 -0
- package/plugins/ragents.actor-programs/client-ui/flow-diagram.css +23 -0
- package/plugins/ragents.actor-programs/client-ui/form-contracts.d.ts +38 -0
- package/plugins/ragents.actor-programs/client-ui/frame-layout.ts +4 -0
- package/plugins/ragents.actor-programs/client-ui/index.tsx +81 -0
- package/plugins/ragents.actor-programs/client-ui/layout-contracts.d.ts +33 -0
- package/plugins/ragents.actor-programs/client-ui/message-list-contracts.d.ts +33 -0
- package/plugins/ragents.actor-programs/client-ui/table-contracts.d.ts +35 -0
- package/plugins/ragents.actor-programs/client-ui/viewer-contracts.d.ts +37 -0
- package/plugins/ragents.actor-programs/client-ui/workflow-diagram-contracts.d.ts +10 -0
- package/plugins/ragents.actor-programs/contract.ts +180 -0
- package/plugins/ragents.actor-programs/parameter-types.ts +3 -0
- package/plugins/ragents.actor-programs/prompt.hbs +79 -0
- package/plugins/ragents.actor-programs/server/agent-tools.ts +31 -0
- package/plugins/ragents.actor-programs/server/app-project.ts +284 -0
- package/plugins/ragents.actor-programs/server/authoring-contracts.ts +10 -0
- package/plugins/ragents.actor-programs/server/client-compiler.ts +174 -0
- package/plugins/ragents.actor-programs/server/client-contracts.ts +187 -0
- package/plugins/ragents.actor-programs/server/client-runtime.ts +16 -0
- package/plugins/ragents.actor-programs/server/controls-template.ts +118 -0
- package/plugins/ragents.actor-programs/server/controls-tool.ts +48 -0
- package/plugins/ragents.actor-programs/server/index.ts +51 -0
- package/plugins/ragents.actor-programs/server/methods.ts +72 -0
- package/plugins/ragents.actor-programs/server/project-diagnostics.ts +138 -0
- package/plugins/ragents.actor-programs/server/prompts.ts +21 -0
- package/plugins/ragents.actor-programs/server/routes.ts +235 -0
- package/plugins/ragents.actor-programs/server/runtime-libraries.ts +4 -0
- package/plugins/ragents.actor-programs/server/runtime.ts +721 -0
- package/plugins/ragents.actor-programs/server/tailwind.ts +22 -0
- package/plugins/ragents.actor-programs/server/templates.ts +400 -0
- package/plugins/ragents.actor-programs/server/tool-contributor.ts +29 -0
- package/plugins/ragents.actor-programs/summary.hbs +17 -0
- package/plugins/ragents.actor-programs/web/ActorViewFrame.tsx +463 -0
- package/plugins/ragents.actor-programs/web/AppsPanel.tsx +436 -0
- package/plugins/ragents.actor-programs/web/EmbeddedApps.tsx +116 -0
- package/plugins/ragents.actor-programs/web/ExpandIcon.tsx +5 -0
- package/plugins/ragents.actor-programs/web/FullscreenHost.tsx +31 -0
- package/plugins/ragents.actor-programs/web/FunctionForm.tsx +102 -0
- package/plugins/ragents.actor-programs/web/ProgramSource.tsx +81 -0
- package/plugins/ragents.actor-programs/web/api.ts +353 -0
- package/plugins/ragents.actor-programs/web/bridge.ts +122 -0
- package/plugins/ragents.actor-programs/web/chat-state.ts +37 -0
- package/plugins/ragents.actor-programs/web/context.ts +30 -0
- package/plugins/ragents.actor-programs/web/function-call.ts +28 -0
- package/plugins/ragents.actor-programs/web/function-input.ts +40 -0
- package/plugins/ragents.actor-programs/web/index.tsx +96 -0
- package/plugins/ragents.actor-programs/web/invocations.ts +43 -0
- package/plugins/ragents.actor-programs/web/program-state.ts +68 -0
- package/plugins/ragents.actor-programs/web/state-revision.ts +16 -0
- package/plugins/ragents.actor-programs/workflow/index.ts +202 -0
- package/plugins/ragents.actor-programs/workflow/prompt-reader.ts +15 -0
- package/plugins/ragents.ask/ask.hbs +4 -0
- package/plugins/ragents.ask/contract.ts +17 -0
- package/plugins/ragents.ask/server/answer-method.ts +15 -0
- package/plugins/ragents.ask/server/ask-service.ts +152 -0
- package/plugins/ragents.ask/server/ask-tool.ts +39 -0
- package/plugins/ragents.ask/server/contract.ts +22 -0
- package/plugins/ragents.ask/server/index.ts +26 -0
- package/plugins/ragents.ask/server/tool-contributor.ts +11 -0
- package/plugins/ragents.ask/web/QuestionSection.tsx +47 -0
- package/plugins/ragents.ask/web/api.ts +6 -0
- package/plugins/ragents.ask/web/constants.ts +1 -0
- package/plugins/ragents.ask/web/index.tsx +50 -0
- package/plugins/ragents.browser/provision.ts +48 -0
- package/plugins/ragents.browser/server/browser.ts +393 -0
- package/plugins/ragents.browser/server/contract.ts +36 -0
- package/plugins/ragents.browser/server/index.ts +35 -0
- package/plugins/ragents.browser/server/tools.ts +197 -0
- package/plugins/ragents.browser/skills/browser-testing/SKILL.md +36 -0
- package/plugins/ragents.documents/contract.ts +33 -0
- package/plugins/ragents.documents/prompt.hbs +18 -0
- package/plugins/ragents.documents/server/config.ts +14 -0
- package/plugins/ragents.documents/server/document-write-tool.ts +45 -0
- package/plugins/ragents.documents/server/files-route.ts +137 -0
- package/plugins/ragents.documents/server/index.ts +38 -0
- package/plugins/ragents.documents/server/show-document-tool.ts +73 -0
- package/plugins/ragents.documents/server/store.ts +35 -0
- package/plugins/ragents.documents/server/tool-contributor.ts +16 -0
- package/plugins/ragents.documents/web/DocumentViewer.tsx +450 -0
- package/plugins/ragents.documents/web/api.ts +8 -0
- package/plugins/ragents.documents/web/index.tsx +279 -0
- package/plugins/ragents.lsp-fsharp/provision.ts +74 -0
- package/plugins/ragents.lsp-fsharp/server/index.ts +16 -0
- package/plugins/ragents.lsp-fsharp/web/index.tsx +7 -0
- package/plugins/ragents.lsp-roslyn/provision.ts +54 -0
- package/plugins/ragents.lsp-roslyn/server/index.ts +15 -0
- package/plugins/ragents.lsp-roslyn/web/api.ts +10 -0
- package/plugins/ragents.lsp-roslyn/web/index.tsx +7 -0
- package/plugins/ragents.lsp-roslyn/web/language-server-plugin.tsx +236 -0
- package/plugins/ragents.lsp-typescript/server/index.ts +7 -0
- package/plugins/ragents.lsp-typescript/web/index.tsx +7 -0
- package/plugins/ragents.model-relay/server/config.ts +37 -0
- package/plugins/ragents.model-relay/server/index.ts +31 -0
- package/plugins/ragents.model-relay/server/relay.ts +213 -0
- package/plugins/ragents.orchestration/canvas.hbs +50 -0
- package/plugins/ragents.orchestration/contract.ts +322 -0
- package/plugins/ragents.orchestration/orchestration.hbs +105 -0
- package/plugins/ragents.orchestration/server/canvas-tool.ts +248 -0
- package/plugins/ragents.orchestration/server/index.ts +64 -0
- package/plugins/ragents.orchestration/server/run-stop-tool.ts +30 -0
- package/plugins/ragents.orchestration/tiled-layout.ts +47 -0
- package/plugins/ragents.orchestration/web/ActorCanvasControls.tsx +159 -0
- package/plugins/ragents.orchestration/web/ActorChat.tsx +56 -0
- package/plugins/ragents.orchestration/web/ActorChatControls.tsx +64 -0
- package/plugins/ragents.orchestration/web/ActorChatPreview.tsx +36 -0
- package/plugins/ragents.orchestration/web/ActorNet.tsx +607 -0
- package/plugins/ragents.orchestration/web/ActorPopout.tsx +36 -0
- package/plugins/ragents.orchestration/web/ActorShortcut.tsx +76 -0
- package/plugins/ragents.orchestration/web/ActorTile.tsx +22 -0
- package/plugins/ragents.orchestration/web/CanvasStartup.tsx +14 -0
- package/plugins/ragents.orchestration/web/CanvasTiles.tsx +47 -0
- package/plugins/ragents.orchestration/web/CardSizeSettings.tsx +42 -0
- package/plugins/ragents.orchestration/web/Center.tsx +576 -0
- package/plugins/ragents.orchestration/web/DocumentsSection.tsx +37 -0
- package/plugins/ragents.orchestration/web/ExecutionsPanel.tsx +109 -0
- package/plugins/ragents.orchestration/web/FlowInspector.tsx +932 -0
- package/plugins/ragents.orchestration/web/JournalStatus.tsx +87 -0
- package/plugins/ragents.orchestration/web/MaterialBody.tsx +104 -0
- package/plugins/ragents.orchestration/web/ScriptActorCard.tsx +56 -0
- package/plugins/ragents.orchestration/web/StopRunButton.tsx +52 -0
- package/plugins/ragents.orchestration/web/TiledCanvas.tsx +281 -0
- package/plugins/ragents.orchestration/web/ZoomSettings.tsx +38 -0
- package/plugins/ragents.orchestration/web/actor-conversation.ts +64 -0
- package/plugins/ragents.orchestration/web/actor-header-settings.ts +41 -0
- package/plugins/ragents.orchestration/web/api.ts +33 -0
- package/plugins/ragents.orchestration/web/canvas-layout-storage.ts +39 -0
- package/plugins/ragents.orchestration/web/canvas-layout.ts +326 -0
- package/plugins/ragents.orchestration/web/canvas-scene.ts +311 -0
- package/plugins/ragents.orchestration/web/canvas-stage.ts +21 -0
- package/plugins/ragents.orchestration/web/canvas-startup.ts +36 -0
- package/plugins/ragents.orchestration/web/canvas-view-settings.ts +48 -0
- package/plugins/ragents.orchestration/web/card-size-settings.ts +36 -0
- package/plugins/ragents.orchestration/web/column/AddresseeControl.tsx +116 -0
- package/plugins/ragents.orchestration/web/column/ColumnSettings.tsx +50 -0
- package/plugins/ragents.orchestration/web/column/RunColumn.tsx +370 -0
- package/plugins/ragents.orchestration/web/column/column-actors.ts +38 -0
- package/plugins/ragents.orchestration/web/column/column-settings.ts +47 -0
- package/plugins/ragents.orchestration/web/column/column-state.ts +59 -0
- package/plugins/ragents.orchestration/web/column/sheet-status.ts +30 -0
- package/plugins/ragents.orchestration/web/constants.ts +10 -0
- package/plugins/ragents.orchestration/web/contract.ts +25 -0
- package/plugins/ragents.orchestration/web/executions.ts +124 -0
- package/plugins/ragents.orchestration/web/format.ts +4 -0
- package/plugins/ragents.orchestration/web/index.tsx +182 -0
- package/plugins/ragents.orchestration/web/keyboard-navigation.ts +55 -0
- package/plugins/ragents.orchestration/web/material-layout.ts +14 -0
- package/plugins/ragents.orchestration/web/run-view.ts +199 -0
- package/plugins/ragents.orchestration/web/tile-docking.ts +99 -0
- package/plugins/ragents.orchestration/web/tiled-view-settings.ts +76 -0
- package/plugins/ragents.orchestration/web/useCanvasMeasurements.ts +78 -0
- package/plugins/ragents.orchestration/web/zoom-settings.ts +28 -0
- package/plugins/ragents.overseer/contract.ts +165 -0
- package/plugins/ragents.overseer/server/api.ts +82 -0
- package/plugins/ragents.overseer/server/coordinator-prompt.ts +13 -0
- package/plugins/ragents.overseer/server/index.ts +71 -0
- package/plugins/ragents.overseer/server/orientation.ts +33 -0
- package/plugins/ragents.overseer/server/quick-answer.ts +54 -0
- package/plugins/ragents.overseer/server/reset-method.ts +5 -0
- package/plugins/ragents.overseer/server/run-directory.ts +49 -0
- package/plugins/ragents.overseer/server/settings-method.ts +8 -0
- package/plugins/ragents.overseer/server/settings.ts +83 -0
- package/plugins/ragents.overseer/server/user-location.ts +96 -0
- package/plugins/ragents.overseer/web/ModelSettings.tsx +70 -0
- package/plugins/ragents.overseer/web/chat-display.ts +10 -0
- package/plugins/ragents.overseer/web/index.tsx +208 -0
- package/plugins/ragents.overseer/web/model-settings.ts +61 -0
- package/plugins/ragents.overseer/web/quick-answers.ts +64 -0
- package/plugins/ragents.processes/contract.ts +61 -0
- package/plugins/ragents.processes/server/index.ts +36 -0
- package/plugins/ragents.processes/server/methods.ts +39 -0
- package/plugins/ragents.processes/server/observer.ts +179 -0
- package/plugins/ragents.processes/server/process-table.ts +395 -0
- package/plugins/ragents.processes/server/snapshot.ts +63 -0
- package/plugins/ragents.processes/server/terminator.ts +164 -0
- package/plugins/ragents.processes/web/ProcessHeader.tsx +157 -0
- package/plugins/ragents.processes/web/index.tsx +23 -0
- package/plugins/ragents.processes/web/processes.ts +75 -0
- package/plugins/ragents.product/model-settings-contract.ts +10 -0
- package/plugins/ragents.product/preamble.hbs +9 -0
- package/plugins/ragents.product/server/config.ts +73 -0
- package/plugins/ragents.product/server/index.ts +117 -0
- package/plugins/ragents.product/server/relay.ts +118 -0
- package/plugins/ragents.product/server/runtime.ts +30 -0
- package/plugins/ragents.product/web/ModelControl.tsx +81 -0
- package/plugins/ragents.product/web/ProductModelSettings.tsx +131 -0
- package/plugins/ragents.product/web/SystemPromptControl.tsx +136 -0
- package/plugins/ragents.product/web/index.tsx +29 -0
- package/plugins/ragents.product/web/model-settings.ts +39 -0
- package/plugins/ragents.product/web/start-options.tsx +12 -0
- package/plugins/ragents.profile-distribution/contract.ts +38 -0
- package/plugins/ragents.profile-distribution/server/archive.ts +159 -0
- package/plugins/ragents.profile-distribution/server/config.ts +27 -0
- package/plugins/ragents.profile-distribution/server/index.ts +93 -0
- package/plugins/ragents.profile-distribution/server/web.ts +48 -0
- package/plugins/ragents.reference/examples.ts +33 -0
- package/plugins/ragents.reference/run-scripts/balcony-wizard/RUN.md +27 -0
- package/plugins/ragents.reference/run-scripts/balcony-wizard/actors/balcony-app/package.json +10 -0
- package/plugins/ragents.reference/run-scripts/balcony-wizard/actors/balcony-app/src/client.tsx +80 -0
- package/plugins/ragents.reference/run-scripts/balcony-wizard/actors/balcony-app/src/conversation.ts +82 -0
- package/plugins/ragents.reference/run-scripts/balcony-wizard/actors/balcony-app/tests/conversation.test.ts +154 -0
- package/plugins/ragents.reference/run-scripts/balcony-wizard/package.json +9 -0
- package/plugins/ragents.reference/run-scripts/balcony-wizard/src/server.ts +32 -0
- package/plugins/ragents.reference/run-scripts/balcony-wizard/tests/program.test.ts +59 -0
- package/plugins/ragents.reference/run-scripts/conversation-circle/RUN.md +14 -0
- package/plugins/ragents.reference/run-scripts/conversation-circle/package.json +9 -0
- package/plugins/ragents.reference/run-scripts/conversation-circle/src/server.ts +87 -0
- package/plugins/ragents.reference/run-scripts/conversation-circle/tests/helpers.ts +26 -0
- package/plugins/ragents.reference/run-scripts/conversation-circle/tests/program.test.ts +32 -0
- package/plugins/ragents.reference/run-scripts/learning-afternoon/RUN.md +24 -0
- package/plugins/ragents.reference/run-scripts/learning-afternoon/package.json +10 -0
- package/plugins/ragents.reference/run-scripts/learning-afternoon/prompts/experiment.md +1 -0
- package/plugins/ragents.reference/run-scripts/learning-afternoon/prompts/helper.md +5 -0
- package/plugins/ragents.reference/run-scripts/learning-afternoon/prompts/quiz.md +1 -0
- package/plugins/ragents.reference/run-scripts/learning-afternoon/src/client.tsx +27 -0
- package/plugins/ragents.reference/run-scripts/learning-afternoon/src/server.ts +127 -0
- package/plugins/ragents.reference/run-scripts/learning-afternoon/src/state.ts +38 -0
- package/plugins/ragents.reference/run-scripts/learning-afternoon/src/view.tsx +42 -0
- package/plugins/ragents.reference/run-scripts/learning-afternoon/src/workflow.ts +38 -0
- package/plugins/ragents.reference/run-scripts/learning-afternoon/tests/program.test.ts +223 -0
- package/plugins/ragents.reference/run-scripts/moderated-round/RUN.md +12 -0
- package/plugins/ragents.reference/run-scripts/moderated-round/package.json +9 -0
- package/plugins/ragents.reference/run-scripts/moderated-round/src/server.ts +60 -0
- package/plugins/ragents.reference/run-scripts/moderated-round/tests/helpers.ts +26 -0
- package/plugins/ragents.reference/run-scripts/moderated-round/tests/program.test.ts +24 -0
- package/plugins/ragents.reference/run-scripts/shared-actor-list/RUN.md +18 -0
- package/plugins/ragents.reference/run-scripts/shared-actor-list/actors/shared-list/package.json +16 -0
- package/plugins/ragents.reference/run-scripts/shared-actor-list/actors/shared-list/src/client.tsx +39 -0
- package/plugins/ragents.reference/run-scripts/shared-actor-list/actors/shared-list/src/contract.ts +15 -0
- package/plugins/ragents.reference/run-scripts/shared-actor-list/actors/shared-list/src/server.ts +14 -0
- package/plugins/ragents.reference/run-scripts/shared-actor-list/actors/shared-list/tests/program.test.ts +13 -0
- package/plugins/ragents.reference/run-scripts/shared-actor-list/package.json +9 -0
- package/plugins/ragents.reference/run-scripts/shared-actor-list/src/server.ts +65 -0
- package/plugins/ragents.reference/run-scripts/shared-actor-list/tests/helpers.ts +26 -0
- package/plugins/ragents.reference/run-scripts/shared-actor-list/tests/program.test.ts +42 -0
- package/plugins/ragents.reference/run-scripts/word-game/RUN.md +25 -0
- package/plugins/ragents.reference/run-scripts/word-game/package.json +11 -0
- package/plugins/ragents.reference/run-scripts/word-game/src/client.tsx +27 -0
- package/plugins/ragents.reference/run-scripts/word-game/src/contract.ts +23 -0
- package/plugins/ragents.reference/run-scripts/word-game/src/server.ts +106 -0
- package/plugins/ragents.reference/run-scripts/word-game/src/state.ts +22 -0
- package/plugins/ragents.reference/run-scripts/word-game/src/view.tsx +54 -0
- package/plugins/ragents.reference/run-scripts/word-game/tests/program.test.ts +253 -0
- package/plugins/ragents.reference/server/index.ts +12 -0
- package/plugins/ragents.reference/skills/100-shared-actor-list/SKILL.md +12 -0
- package/plugins/ragents.reference/skills/110-all-card-slots/SKILL.md +12 -0
- package/plugins/ragents.reference/skills/120-canvas-conversation-circle/SKILL.md +12 -0
- package/plugins/ragents.reference/skills/130-canvas-pipeline-with-approval/SKILL.md +12 -0
- package/plugins/ragents.reference/skills/140-canvas-team-tree-and-topic-grid/SKILL.md +12 -0
- package/plugins/ragents.reference/skills/150-editorial-workbench/SKILL.md +12 -0
- package/plugins/ragents.reference/skills/160-learning-companion/SKILL.md +12 -0
- package/plugins/ragents.reference/skills/170-photo-collection/SKILL.md +12 -0
- package/plugins/ragents.reference/skills/180-decision-workbench/SKILL.md +12 -0
- package/plugins/ragents.reference/skills/190-review-queue/SKILL.md +12 -0
- package/plugins/ragents.reference/skills/20-circle-of-four/SKILL.md +12 -0
- package/plugins/ragents.reference/skills/200-typescript-diagnostics/SKILL.md +12 -0
- package/plugins/ragents.reference/skills/210-moderator-handover/SKILL.md +12 -0
- package/plugins/ragents.reference/skills/220-actor-approval-list/SKILL.md +12 -0
- package/plugins/ragents.reference/skills/230-shared-state-views/SKILL.md +12 -0
- package/plugins/ragents.reference/skills/240-live-result-list/SKILL.md +12 -0
- package/plugins/ragents.reference/skills/250-balcony-wizard/SKILL.md +12 -0
- package/plugins/ragents.reference/skills/30-llm-without-runtime-knowledge/SKILL.md +12 -0
- package/plugins/ragents.reference/skills/35-actor-input-fifo/SKILL.md +12 -0
- package/plugins/ragents.reference/skills/40-subscription-matrix/SKILL.md +12 -0
- package/plugins/ragents.reference/skills/50-subscription-removal/SKILL.md +12 -0
- package/plugins/ragents.reference/skills/60-stop-in-the-circle/SKILL.md +12 -0
- package/plugins/ragents.reference/skills/65-artifact-least-privilege/SKILL.md +12 -0
- package/plugins/ragents.reference/skills/70-headless-counter/SKILL.md +12 -0
- package/plugins/ragents.reference/skills/75-lsp-demo/SKILL.md +12 -0
- package/plugins/ragents.reference/skills/80-actor-text-analysis/SKILL.md +12 -0
- package/plugins/ragents.reference/skills/90-actor-notes/SKILL.md +12 -0
- package/plugins/ragents.reference/skills/95-hello-world/SKILL.md +12 -0
- package/plugins/ragents.reference/skills/decision-brief/SKILL.md +33 -0
- package/plugins/ragents.reference/skills/learning-sprint/SKILL.md +33 -0
- package/plugins/ragents.reference/walkthroughs.ts +219 -0
- package/plugins/ragents.reference/web/StartGuides.tsx +89 -0
- package/plugins/ragents.reference/web/index.tsx +10 -0
- package/plugins/ragents.todo/contract.ts +60 -0
- package/plugins/ragents.todo/server/index.ts +10 -0
- package/plugins/ragents.todo/server/todo-tool.ts +70 -0
- package/plugins/ragents.todo/server/tool-contributor.ts +9 -0
- package/plugins/ragents.todo/web/TodoSection.tsx +47 -0
- package/plugins/ragents.todo/web/index.ts +12 -0
- package/plugins/ragents.transcript/server/index.ts +20 -0
- package/plugins/ragents.transcript/server/transcript.ts +78 -0
- package/plugins/ragents.watch/contract.ts +48 -0
- package/plugins/ragents.watch/server/condition.ts +56 -0
- package/plugins/ragents.watch/server/contract.ts +4 -0
- package/plugins/ragents.watch/server/functions.ts +62 -0
- package/plugins/ragents.watch/server/index.ts +39 -0
- package/plugins/ragents.watch/server/observation.ts +69 -0
- package/plugins/ragents.watch/server/service.ts +294 -0
- package/plugins/ragents.workspace/client/transport.ts +13 -0
- package/plugins/ragents.workspace/client/workspace-client.ts +247 -0
- package/plugins/ragents.workspace/contract.ts +182 -0
- package/plugins/ragents.workspace/prompt.hbs +14 -0
- package/plugins/ragents.workspace/server/binding.ts +92 -0
- package/plugins/ragents.workspace/server/browse-route.ts +134 -0
- package/plugins/ragents.workspace/server/clients.ts +161 -0
- package/plugins/ragents.workspace/server/index.ts +91 -0
- package/plugins/ragents.workspace/server/runtime.ts +170 -0
- package/plugins/ragents.workspace/web/FileBrowser.tsx +271 -0
- package/plugins/ragents.workspace/web/WorkspaceBinding.tsx +216 -0
- package/plugins/ragents.workspace/web/api.ts +8 -0
- package/plugins/ragents.workspace/web/file-icons.tsx +94 -0
- package/plugins/ragents.workspace/web/index.tsx +37 -0
- package/ragents.config.core.ts +65 -0
- package/ragents.config.developer.ts +46 -0
- package/scripts/agent/agent-cli.ts +461 -0
- package/scripts/agent/journal.ts +125 -0
- package/scripts/package/build-package.ts +249 -0
- package/scripts/package/host-links.d.mts +1 -0
- package/scripts/package/host-links.mjs +39 -0
- package/scripts/package/publish-package.ts +129 -0
- package/scripts/package/ragents.mjs +59 -0
- package/scripts/provision/run-provision.ts +72 -0
- package/scripts/remote/connect.ts +265 -0
- package/scripts/remote/start.ts +91 -0
- package/scripts/workspace-client/run-workspace-client.ts +112 -0
|
@@ -0,0 +1,234 @@
|
|
|
1
|
+
import React, { lazy, Suspense, useEffect, useMemo, useState } from "react";
|
|
2
|
+
import { cn } from "../../../apps/web/src/ui";
|
|
3
|
+
import type { Edge, Node } from "@xyflow/react";
|
|
4
|
+
import type { ElkNode } from "elkjs/lib/elk-api";
|
|
5
|
+
import type { FlowDiagramProps } from "./flow-diagram-contracts";
|
|
6
|
+
|
|
7
|
+
type CardItem = NonNullable<FlowDiagramProps["nodes"][number]["items"]>[number] & { labelLines: string; detailLines?: string };
|
|
8
|
+
export interface GraphBounds { x: number; y: number; width: number; height: number }
|
|
9
|
+
type CardData = FlowDiagramProps["nodes"][number] & { labelLines: string; detailLines?: string; itemLines: CardItem[]; direction: "right" | "down"; detailLevel: "full" | "summary"; onAction?: FlowDiagramProps["onAction"] };
|
|
10
|
+
export type CardNode = Node<CardData, "card">;
|
|
11
|
+
type EdgeStatus = NonNullable<FlowDiagramProps["edges"][number]["status"]>;
|
|
12
|
+
export type RouteEdge = Edge<{ path: string; x: number; y: number; rotated?: boolean; labelWidth?: number; status?: EdgeStatus }, "route">;
|
|
13
|
+
export type Link = FlowDiagramProps["edges"][number] & { id: string };
|
|
14
|
+
export interface Placement { nodes: CardNode[]; edges: RouteEdge[]; bounds: GraphBounds }
|
|
15
|
+
interface Layout { key: string; nodes: CardNode[]; edges: RouteEdge[]; bounds?: GraphBounds; error?: string }
|
|
16
|
+
interface Point { x: number; y: number }
|
|
17
|
+
|
|
18
|
+
function textMeasure(): (text: string) => number {
|
|
19
|
+
const canvas = typeof document === "undefined" ? undefined : document.createElement("canvas").getContext("2d");
|
|
20
|
+
if (canvas) canvas.font = `600 16px ${getComputedStyle(document.documentElement).getPropertyValue("--font-sans").trim() || "sans-serif"}`;
|
|
21
|
+
return text => canvas ? canvas.measureText(text).width : text.length * 10;
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
function wrap(text: string, width = 204): string {
|
|
25
|
+
const textWidth = textMeasure();
|
|
26
|
+
return text.split("\n").flatMap((paragraph) => {
|
|
27
|
+
const lines: string[] = [];
|
|
28
|
+
let line = "";
|
|
29
|
+
for (const word of paragraph.split(/\s+/)) {
|
|
30
|
+
const next = line ? `${line} ${word}` : word;
|
|
31
|
+
if (textWidth(next) <= width) { line = next; continue; }
|
|
32
|
+
if (line) { lines.push(line); line = ""; }
|
|
33
|
+
for (const character of word) {
|
|
34
|
+
if (line && textWidth(line + character) > width) { lines.push(line); line = character; }
|
|
35
|
+
else line += character;
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
lines.push(line);
|
|
39
|
+
return lines;
|
|
40
|
+
}).join("\n");
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
function summarize(text: string, width: number, count: number): string {
|
|
44
|
+
const lines = wrap(text, width).split("\n");
|
|
45
|
+
if (lines.length <= count) return lines.join("\n");
|
|
46
|
+
const textWidth = textMeasure();
|
|
47
|
+
let last = lines[count - 1]!;
|
|
48
|
+
while (last && textWidth(last + "...") > width) last = last.slice(0, -1);
|
|
49
|
+
return [...lines.slice(0, count - 1), last.trimEnd() + "..."].join("\n");
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
const edgeStatuses = ["pending", "active", "done", "blocked"];
|
|
53
|
+
|
|
54
|
+
function prepare({ nodes, edges, direction = "right", height = 360, viewport = "interactive", detailLevel = "summary", layout = "layered" }: FlowDiagramProps) {
|
|
55
|
+
if (viewport !== "interactive" && viewport !== "fit-width" && viewport !== "fit") throw new Error("Unbekannter Diagrammansichtsmodus.");
|
|
56
|
+
if (!Number.isFinite(height) || height <= 0) throw new Error("Die Diagrammhöhe muss positiv sein.");
|
|
57
|
+
if (direction !== "right" && direction !== "down") throw new Error("Unbekannte Diagrammrichtung.");
|
|
58
|
+
if (detailLevel !== "full" && detailLevel !== "summary") throw new Error("Unbekannte Diagrammdetailstufe.");
|
|
59
|
+
if (layout !== "layered" && layout !== "star") throw new Error("Unbekannte Diagrammanordnung.");
|
|
60
|
+
const summary = detailLevel === "summary";
|
|
61
|
+
const textWidth = textMeasure();
|
|
62
|
+
const ids = new Set<string>();
|
|
63
|
+
const cards = nodes.map((node): CardNode => {
|
|
64
|
+
if (typeof node.id !== "string" || !node.id.trim() || ids.has(node.id)) throw new Error("Knoten benötigen eindeutige, nicht leere IDs.");
|
|
65
|
+
ids.add(node.id);
|
|
66
|
+
if (typeof node.label !== "string" || (node.detail !== undefined && typeof node.detail !== "string")) throw new Error("Knotenbeschriftungen müssen Text sein.");
|
|
67
|
+
if (node.status !== undefined && !["pending", "active", "done", "blocked"].includes(node.status)) throw new Error("Unbekannter Knotenstatus.");
|
|
68
|
+
if (node.running !== undefined && typeof node.running !== "boolean") throw new Error("Knotenaktivität muss ein Wahrheitswert sein.");
|
|
69
|
+
if (node.kind !== undefined && !["actor", "agent", "service"].includes(node.kind)) throw new Error("Unbekannte Knotenart.");
|
|
70
|
+
const labelLines = summary ? summarize(node.label, 284, 2) : wrap(node.label);
|
|
71
|
+
const detailLines = summary || node.detail === undefined ? undefined : wrap(node.detail);
|
|
72
|
+
if (node.items !== undefined && !Array.isArray(node.items)) throw new Error("Knotenpunkte müssen eine Liste sein.");
|
|
73
|
+
const itemLines = (node.items ?? []).map((item) => {
|
|
74
|
+
if (typeof item.label !== "string" || (item.detail !== undefined && typeof item.detail !== "string")) throw new Error("Punktbeschriftungen müssen Text sein.");
|
|
75
|
+
if (item.status !== undefined && !["pending", "active", "done", "blocked", "skipped"].includes(item.status)) throw new Error("Unbekannter Punktstatus.");
|
|
76
|
+
return { ...item, labelLines: wrap(item.label, summary ? 256 : 176), detailLines: summary || item.detail === undefined ? undefined : wrap(item.detail) };
|
|
77
|
+
});
|
|
78
|
+
if (node.actions !== undefined && !Array.isArray(node.actions)) throw new Error("Knotenaktionen müssen eine Liste sein.");
|
|
79
|
+
const actionIds = new Set<string>();
|
|
80
|
+
for (const action of node.actions ?? []) {
|
|
81
|
+
if (typeof action.id !== "string" || !action.id.trim() || actionIds.has(action.id)) throw new Error("Aktionen benötigen eindeutige, nicht leere IDs.");
|
|
82
|
+
actionIds.add(action.id);
|
|
83
|
+
if (typeof action.label !== "string") throw new Error("Aktionsbeschriftungen müssen Text sein.");
|
|
84
|
+
}
|
|
85
|
+
const itemsHeight = summary ? itemLines.reduce((height, item) => height + 12 + item.labelLines.split("\n").length * 24, 0) : itemLines.reduce((height, item) => height + 24 + item.labelLines.split("\n").length * 24 + 24 + (item.detailLines === undefined ? 0 : item.detailLines.split("\n").length * 24), 0);
|
|
86
|
+
const actionsHeight = node.actions?.length ? 49 : 0;
|
|
87
|
+
const height = itemsHeight + actionsHeight + (summary ? 50 : 60) + labelLines.split("\n").length * 24 + (detailLines === undefined ? 0 : 24 + detailLines.split("\n").length * 24);
|
|
88
|
+
return { id: node.id, type: "card", position: { x: 0, y: 0 }, width: summary ? 320 : 240, height, data: { ...node, labelLines, detailLines, itemLines, direction, detailLevel } };
|
|
89
|
+
});
|
|
90
|
+
const edgeIds = new Set<string>();
|
|
91
|
+
const links = edges.map((edge, index): Link => {
|
|
92
|
+
const id = edge.id ?? `flow-edge-${index}`;
|
|
93
|
+
if (typeof id !== "string" || !id.trim() || edgeIds.has(id)) throw new Error("Verbindungen benötigen eindeutige, nicht leere IDs.");
|
|
94
|
+
edgeIds.add(id);
|
|
95
|
+
if (!ids.has(edge.source) || !ids.has(edge.target)) throw new Error("Eine Verbindung verweist auf einen fehlenden Knoten.");
|
|
96
|
+
if (edge.kind !== undefined && edge.kind !== "return") throw new Error("Unbekannte Verbindungsart.");
|
|
97
|
+
if (edge.status !== undefined && !edgeStatuses.includes(edge.status)) throw new Error("Unbekannter Verbindungsstatus.");
|
|
98
|
+
if (edge.label !== undefined && typeof edge.label !== "string") throw new Error("Verbindungsbeschriftungen müssen Text sein.");
|
|
99
|
+
return { ...edge, id };
|
|
100
|
+
});
|
|
101
|
+
const key = JSON.stringify([layout, direction, cards.map(({ id, width, height }) => [id, width, height]), links.map(({ id, source, target, label, kind }) => [id, source, target, kind, label === undefined ? 0 : Math.ceil(textWidth(label))])]);
|
|
102
|
+
return { key, cards, links, direction, layout };
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
function bounds(points: Point[]): GraphBounds {
|
|
106
|
+
const x = Math.min(...points.map(point => point.x)) - 16;
|
|
107
|
+
const y = Math.min(...points.map(point => point.y)) - 16;
|
|
108
|
+
return { x, y, width: Math.max(...points.map(point => point.x)) + 16 - x, height: Math.max(...points.map(point => point.y)) + 16 - y };
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
const corners = (nodes: CardNode[]): Point[] => nodes.flatMap(node => [{ x: node.position.x, y: node.position.y }, { x: node.position.x + node.width!, y: node.position.y + node.height! }]);
|
|
112
|
+
|
|
113
|
+
export function starLayout(cards: CardNode[], links: Link[]): Placement {
|
|
114
|
+
const [hub, ...rest] = cards;
|
|
115
|
+
const gap = 24;
|
|
116
|
+
const rightCount = Math.ceil(rest.length / 2);
|
|
117
|
+
const columns = [{ side: 1, cards: rest.slice(0, rightCount) }, { side: -1, cards: rest.slice(rightCount) }];
|
|
118
|
+
const rows = new Map<string, { side: number; relativeY: number }>();
|
|
119
|
+
const placed = columns.flatMap(({ side, cards: column }) => {
|
|
120
|
+
const total = column.reduce((sum, card) => sum + card.height!, 0) + gap * (column.length - 1);
|
|
121
|
+
let top = -total / 2;
|
|
122
|
+
return column.map((card, index) => {
|
|
123
|
+
const relativeY = column.length < 2 ? 0 : index * 2 / (column.length - 1) - 1;
|
|
124
|
+
const distance = hub!.width! / 2 + 120 + card.width! / 2;
|
|
125
|
+
const y = top + card.height! / 2;
|
|
126
|
+
top += card.height! + gap;
|
|
127
|
+
rows.set(card.id, { side, relativeY });
|
|
128
|
+
return { ...card, position: { x: side * distance - card.width! / 2, y: y - card.height! / 2 } };
|
|
129
|
+
});
|
|
130
|
+
});
|
|
131
|
+
const nodes = [{ ...hub!, position: { x: -hub!.width! / 2, y: -hub!.height! / 2 } }, ...placed];
|
|
132
|
+
const center = (node: CardNode): Point => ({ x: node.position.x + node.width! / 2, y: node.position.y + node.height! / 2 });
|
|
133
|
+
const pairs = new Map<string, Link[]>();
|
|
134
|
+
for (const link of links) {
|
|
135
|
+
const pair = [link.source, link.target].sort().join("\n");
|
|
136
|
+
pairs.set(pair, [...(pairs.get(pair) ?? []), link]);
|
|
137
|
+
}
|
|
138
|
+
const edges = links.map((link): RouteEdge => {
|
|
139
|
+
const siblings = pairs.get([link.source, link.target].sort().join("\n"))!;
|
|
140
|
+
const offset = (siblings.indexOf(link) - (siblings.length - 1) / 2) * 16;
|
|
141
|
+
const source = nodes.find(node => node.id === link.source)!;
|
|
142
|
+
const target = nodes.find(node => node.id === link.target)!;
|
|
143
|
+
const spoke = source.id === hub!.id ? target : target.id === hub!.id ? source : undefined;
|
|
144
|
+
const data = { status: link.status, labelWidth: link.label ? Math.ceil(textMeasure()(link.label)) : 0 };
|
|
145
|
+
if (!spoke) {
|
|
146
|
+
const start = center(source);
|
|
147
|
+
const end = center(target);
|
|
148
|
+
return { ...link, type: "route", data: { ...data, path: `M ${start.x} ${start.y} L ${end.x} ${end.y}`, x: (start.x + end.x) / 2, y: (start.y + end.y) / 2 } };
|
|
149
|
+
}
|
|
150
|
+
const { side, relativeY } = rows.get(spoke.id)!;
|
|
151
|
+
const hubPort = { x: side * hub!.width! / 2, y: relativeY * (hub!.height! / 2 - 24) + offset };
|
|
152
|
+
const spokePort = { x: center(spoke).x - side * spoke.width! / 2, y: center(spoke).y + offset };
|
|
153
|
+
const [start, end] = source.id === hub!.id ? [hubPort, spokePort] : [spokePort, hubPort];
|
|
154
|
+
const reach = side * Math.abs(end.x - start.x) / 2 * (source.id === hub!.id ? 1 : -1);
|
|
155
|
+
const path = `M ${start.x} ${start.y} C ${start.x + reach} ${start.y} ${end.x - reach} ${end.y} ${end.x} ${end.y}`;
|
|
156
|
+
return { ...link, type: "route", data: { ...data, path, x: (start.x + end.x) / 2, y: (start.y + end.y) / 2 } };
|
|
157
|
+
});
|
|
158
|
+
return { nodes, edges, bounds: bounds(corners(nodes)) };
|
|
159
|
+
}
|
|
160
|
+
|
|
161
|
+
async function layeredLayout(cards: CardNode[], links: Link[], direction: "right" | "down"): Promise<Placement> {
|
|
162
|
+
const { default: ELK } = await import("elkjs/lib/elk.bundled.js");
|
|
163
|
+
const result: ElkNode = await new ELK().layout({
|
|
164
|
+
id: "root", layoutOptions: { "elk.algorithm": "layered", "elk.direction": direction === "right" ? "RIGHT" : "DOWN", "elk.edgeRouting": "ORTHOGONAL", "elk.spacing.nodeNode": "52", "elk.layered.spacing.nodeNodeBetweenLayers": "94" },
|
|
165
|
+
children: cards.map(({ id, width, height }) => ({ id, width, height })),
|
|
166
|
+
edges: links.filter(edge => edge.kind !== "return").map(({ id, source, target, label }) => ({ id, sources: [source], targets: [target], ...(label ? { labels: [{ text: label, width: Math.max(40, Math.ceil(textMeasure()(label))), height: 24 }] } : {}) })),
|
|
167
|
+
});
|
|
168
|
+
const nodes = cards.map((card, index) => ({ ...card, position: { x: result.children![index]!.x!, y: result.children![index]!.y! } }));
|
|
169
|
+
const extraPoints: Point[] = [];
|
|
170
|
+
let lane = Math.max(...nodes.map(node => node.position.x + node.width!)) + 48;
|
|
171
|
+
const edges: RouteEdge[] = links.map((edge) => {
|
|
172
|
+
if (edge.kind === "return") {
|
|
173
|
+
const source = nodes.find(node => node.id === edge.source)!;
|
|
174
|
+
const target = nodes.find(node => node.id === edge.target)!;
|
|
175
|
+
const start = { x: source.position.x + source.width!, y: source.position.y + source.height! * (edge.source === edge.target ? 2 / 3 : 1 / 2) };
|
|
176
|
+
const end = { x: target.position.x + target.width!, y: target.position.y + target.height! * (edge.source === edge.target ? 1 / 3 : 1 / 2) };
|
|
177
|
+
const labelWidth = edge.label ? Math.ceil(textMeasure()(edge.label)) : 0;
|
|
178
|
+
const x = lane;
|
|
179
|
+
const y = (start.y + end.y) / 2;
|
|
180
|
+
const path = `M ${start.x} ${start.y} L ${lane} ${start.y} L ${lane} ${end.y} L ${end.x} ${end.y}`;
|
|
181
|
+
extraPoints.push(start, end, { x: lane, y: start.y }, { x: lane, y: end.y }, { x: lane + 16, y: y + labelWidth / 2 + 8 }, { x: lane - 16, y: y - labelWidth / 2 - 8 });
|
|
182
|
+
lane += 32;
|
|
183
|
+
return { ...edge, type: "route", data: { path, x, y, rotated: true, labelWidth, status: edge.status } };
|
|
184
|
+
}
|
|
185
|
+
const route = result.edges!.find(route => route.id === edge.id)!;
|
|
186
|
+
if (!route.sections?.length) throw new Error("Für eine Verbindung fehlt die automatische Linienführung.");
|
|
187
|
+
const path = route.sections.map((section) => [section.startPoint, ...(section.bendPoints ?? []), section.endPoint].map((point, index) => `${index ? "L" : "M"} ${point.x} ${point.y}`).join(" ")).join(" ");
|
|
188
|
+
const section = route.sections[0]!;
|
|
189
|
+
const label = route.labels?.[0];
|
|
190
|
+
return { ...edge, type: "route", data: { path, status: edge.status, x: label?.x === undefined ? (section.startPoint.x + section.endPoint.x) / 2 : label.x + (label.width ?? 0) / 2, y: label?.y === undefined ? (section.startPoint.y + section.endPoint.y) / 2 : label.y + (label.height ?? 0) / 2 } };
|
|
191
|
+
});
|
|
192
|
+
const points = [...corners(nodes), ...extraPoints];
|
|
193
|
+
for (const edge of result.edges ?? []) {
|
|
194
|
+
for (const section of edge.sections ?? []) points.push(section.startPoint, ...(section.bendPoints ?? []), section.endPoint);
|
|
195
|
+
for (const label of edge.labels ?? []) {
|
|
196
|
+
if (label.x !== undefined && label.y !== undefined) points.push({ x: label.x - 8, y: label.y - 8 }, { x: label.x + (label.width ?? 0) + 8, y: label.y + (label.height ?? 0) + 8 });
|
|
197
|
+
}
|
|
198
|
+
}
|
|
199
|
+
return { nodes, edges, bounds: bounds(points) };
|
|
200
|
+
}
|
|
201
|
+
|
|
202
|
+
const FlowDiagramRenderer = lazy(() => import("./FlowDiagramRenderer"));
|
|
203
|
+
|
|
204
|
+
const flowSurface = "w-full min-w-0 overflow-hidden bg-transparent text-[16px]/[1.5] text-foreground [&>p]:p-4 [&_[role=alert]]:text-destructive data-[viewport=fit-width]:flex-none data-[viewport=fit]:h-full data-[viewport=fit]:min-h-0 data-[viewport=fit]:flex-auto";
|
|
205
|
+
|
|
206
|
+
export function FlowDiagram(props: FlowDiagramProps) {
|
|
207
|
+
const inputKey = JSON.stringify([props.nodes, props.edges, props.direction, props.height, props.viewport, props.detailLevel, props.layout]);
|
|
208
|
+
const prepared = useMemo(() => {
|
|
209
|
+
try { return { graph: prepare(props) }; }
|
|
210
|
+
catch (error) { return { error: error instanceof Error ? error.message : String(error) }; }
|
|
211
|
+
}, [inputKey]);
|
|
212
|
+
const graph = prepared.graph;
|
|
213
|
+
const [layout, setLayout] = useState<Layout>();
|
|
214
|
+
const key = graph?.key;
|
|
215
|
+
useEffect(() => {
|
|
216
|
+
if (!graph || graph.cards.length === 0) return;
|
|
217
|
+
let current = true;
|
|
218
|
+
void (async () => {
|
|
219
|
+
const placement = graph.layout === "star" ? starLayout(graph.cards, graph.links) : await layeredLayout(graph.cards, graph.links, graph.direction);
|
|
220
|
+
if (current) setLayout({ key: graph.key, ...placement });
|
|
221
|
+
})().catch((error: unknown) => { if (current) setLayout({ key: graph.key, nodes: [], edges: [], error: error instanceof Error ? error.message : String(error) }); });
|
|
222
|
+
return () => { current = false; };
|
|
223
|
+
}, [key]);
|
|
224
|
+
const active = layout?.key === key ? layout : undefined;
|
|
225
|
+
const error = prepared.error ?? active?.error;
|
|
226
|
+
const cards = active?.nodes.map((node, index) => ({ ...node, data: { ...graph!.cards[index]!.data, onAction: props.onAction } })) ?? [];
|
|
227
|
+
const viewport = props.viewport ?? "interactive";
|
|
228
|
+
return <section aria-label={props.label} className={cn(flowSurface, props.className)} data-viewport={viewport} style={{ height: viewport !== "interactive" ? undefined : Number.isFinite(props.height) && props.height! > 0 ? props.height : 360 }}>
|
|
229
|
+
{error ? <p role="alert">Das Diagramm konnte nicht angezeigt werden: {error}</p>
|
|
230
|
+
: graph?.cards.length === 0 ? <p role="status">Keine Knoten vorhanden.</p>
|
|
231
|
+
: !active ? <p role="status">Diagramm wird geladen ...</p>
|
|
232
|
+
: <Suspense fallback={<p role="status">Diagramm wird geladen ...</p>}><FlowDiagramRenderer key={key} mode={viewport} bounds={active.bounds!} nodes={cards} edges={active.edges.map((edge, index) => ({ ...edge, label: graph!.links[index]!.label, data: { ...edge.data!, status: graph!.links[index]!.status } }))} /></Suspense>}
|
|
233
|
+
</section>;
|
|
234
|
+
}
|
|
@@ -0,0 +1,85 @@
|
|
|
1
|
+
import React, { useEffect, useRef, useState } from "react";
|
|
2
|
+
import { BaseEdge, Controls, Handle, MarkerType, Position, ReactFlow, type EdgeProps, type NodeProps } from "@xyflow/react";
|
|
3
|
+
import { Button, cn } from "../../../apps/web/src/ui";
|
|
4
|
+
import type { CardNode, GraphBounds, RouteEdge } from "./FlowDiagram";
|
|
5
|
+
|
|
6
|
+
const statusLabels = { pending: "Ausstehend", active: "Aktiv", done: "Fertig", blocked: "Blockiert", skipped: "Übersprungen" };
|
|
7
|
+
const edgeColors = { pending: "var(--muted-foreground)", active: "var(--info)", done: "var(--success)", blocked: "var(--destructive)" };
|
|
8
|
+
const edgeClasses = {
|
|
9
|
+
pending: "[--xy-edge-stroke:var(--muted-foreground)] [stroke-dasharray:4_6]",
|
|
10
|
+
active: "[--xy-edge-stroke:var(--info)] [stroke-dasharray:9_5] animate-edge-flow motion-reduce:animate-none",
|
|
11
|
+
done: "[--xy-edge-stroke:var(--success)]",
|
|
12
|
+
blocked: "[--xy-edge-stroke:var(--destructive)]",
|
|
13
|
+
};
|
|
14
|
+
const statusIconClass = "size-[18px] flex-none text-muted-foreground data-[status=active]:text-info data-[status=done]:text-success data-[status=blocked]:text-destructive in-data-[running=true]:data-[status=active]:animate-spin in-data-[running=true]:data-[status=active]:[animation-duration:1.3s] in-data-[running=true]:data-[status=active]:motion-reduce:animate-none";
|
|
15
|
+
const cardStatusTones = "[--flow-status:var(--muted-foreground)] data-[status=active]:[--flow-status:var(--info)] data-[status=done]:[--flow-status:var(--success)] data-[status=blocked]:[--flow-status:var(--destructive)]";
|
|
16
|
+
|
|
17
|
+
function StatusIcon({ status, className }: { status: keyof typeof statusLabels; className?: string }) {
|
|
18
|
+
return <svg className={cn(statusIconClass, className)} data-status={status} role="img" aria-label={statusLabels[status]} viewBox="0 0 20 20" fill="none" stroke="currentColor" strokeWidth="1.8" strokeLinecap="round" strokeLinejoin="round">
|
|
19
|
+
{status === "pending" ? <circle cx="10" cy="10" r="7" />
|
|
20
|
+
: status === "done" ? <path d="M4 10 L8 14 L16 5" />
|
|
21
|
+
: status === "active" ? <path d="M10 3 A7 7 0 1 1 3 10" />
|
|
22
|
+
: status === "blocked" ? <><circle cx="10" cy="10" r="7" /><path d="M10 6 V10 M10 14 H10.01" /></>
|
|
23
|
+
: <path d="M4 10 H16" />}
|
|
24
|
+
</svg>;
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
function Card({ data }: NodeProps<CardNode>) {
|
|
28
|
+
return <div className={cn(cardStatusTones, "pointer-events-auto h-full overflow-hidden rounded-[12px] border border-[color-mix(in_srgb,var(--flow-status)_60%,var(--border))] bg-card text-[16px]/[24px] shadow-[0_3px_9px_#49384e20] data-[running=true]:animate-ring-pulse data-[running=true]:motion-reduce:animate-none")}
|
|
29
|
+
data-status={data.status ?? "pending"} data-kind={data.kind} data-detail-level={data.detailLevel} data-running={data.status === "active" && data.running === true}>
|
|
30
|
+
<Handle type="target" position={data.direction === "right" ? Position.Left : Position.Top} />
|
|
31
|
+
<div className="relative rounded-t-[11px] bg-[color-mix(in_srgb,var(--flow-status)_12%,var(--card))] px-[17px] py-[15px] in-data-[detail-level=summary]:py-[10px]">
|
|
32
|
+
<h3 className="font-semibold whitespace-pre" title={[data.label, statusLabels[data.status ?? "pending"], data.detail].filter(Boolean).join("\n")}>{data.labelLines}</h3>
|
|
33
|
+
<span className="mt-[4px] flex h-[24px] w-max items-center gap-[7px] rounded-[12px] bg-[color-mix(in_srgb,var(--flow-status)_23%,var(--card))] px-[7px] font-semibold text-[var(--flow-status)]"><StatusIcon status={data.status ?? "pending"} />{statusLabels[data.status ?? "pending"]}</span>
|
|
34
|
+
</div>
|
|
35
|
+
{data.detailLines !== undefined && <div className="border-t border-border px-[17px] pt-[11px] pb-[12px] whitespace-pre">{data.detailLines}</div>}
|
|
36
|
+
{data.itemLines.length > 0 && <ul>{data.itemLines.map((item, index) => <li className="group border-t border-border px-[17px] pt-[11px] pb-[12px] whitespace-pre in-data-[detail-level=summary]:pt-[5px] in-data-[detail-level=summary]:pb-[6px]"
|
|
37
|
+
key={index} data-status={item.status ?? "pending"} title={[item.label, statusLabels[item.status ?? "pending"], item.detail].filter(Boolean).join("\n")}>
|
|
38
|
+
<div className="flex items-start gap-[10px] font-semibold in-data-[detail-level=summary]:font-normal"><StatusIcon className="mt-[3px]" status={item.status ?? "pending"} /><span>{item.labelLines}</span></div>
|
|
39
|
+
{data.detailLevel !== "summary" && <div className="text-muted-foreground group-data-[status=active]:text-info group-data-[status=done]:text-success group-data-[status=blocked]:text-destructive">{statusLabels[item.status ?? "pending"]}</div>}
|
|
40
|
+
{item.detailLines !== undefined && <div>{item.detailLines}</div>}
|
|
41
|
+
</li>)}</ul>}
|
|
42
|
+
{data.actions !== undefined && data.actions.length > 0 && <div className="nodrag nopan flex flex-wrap gap-2 border-t border-border px-[17px] py-[10px]">{data.actions.map((action) =>
|
|
43
|
+
<Button key={action.id} disabled={action.disabled} onClick={() => data.onAction?.(data.id, action.id)} size="sm" variant={action.primary ? "default" : "outline"}>{action.label}</Button>)}</div>}
|
|
44
|
+
<Handle type="source" position={data.direction === "right" ? Position.Right : Position.Bottom} />
|
|
45
|
+
</div>;
|
|
46
|
+
}
|
|
47
|
+
function Route({ id, data, label, markerEnd }: EdgeProps<RouteEdge>) {
|
|
48
|
+
if (!data) return null;
|
|
49
|
+
return <><BaseEdge className={data.status ? edgeClasses[data.status] : undefined} data-status={data.status} id={id} path={data.path} markerEnd={markerEnd} label={data.rotated ? undefined : label} labelX={data.x} labelY={data.y} />
|
|
50
|
+
{data.rotated && label && <g data-kind="return" transform={`translate(${data.x} ${data.y}) rotate(-90)`}>
|
|
51
|
+
<rect className="fill-background" x={-(data.labelWidth ?? 0) / 2 - 4} y={-12} width={(data.labelWidth ?? 0) + 8} height={24} rx={4} />
|
|
52
|
+
<text className="fill-foreground text-[16px]" textAnchor="middle" dominantBaseline="central">{label}</text>
|
|
53
|
+
</g>}
|
|
54
|
+
</>;
|
|
55
|
+
|
|
56
|
+
}
|
|
57
|
+
const nodeTypes = { card: Card };
|
|
58
|
+
const edgeTypes = { route: Route };
|
|
59
|
+
const diagramScale = 0.8;
|
|
60
|
+
|
|
61
|
+
export default function FlowDiagramRenderer({ nodes, edges, bounds, mode }: { nodes: CardNode[]; edges: RouteEdge[]; bounds: GraphBounds; mode: "interactive" | "fit-width" | "fit" }) {
|
|
62
|
+
const host = useRef<HTMLDivElement>(null);
|
|
63
|
+
const [size, setSize] = useState({ width: 0, height: 0 });
|
|
64
|
+
const fitted = mode !== "interactive";
|
|
65
|
+
useEffect(() => {
|
|
66
|
+
if (!fitted || !host.current) return;
|
|
67
|
+
const element = host.current;
|
|
68
|
+
const measure = () => setSize({ width: element.clientWidth, height: element.clientHeight });
|
|
69
|
+
const observer = new ResizeObserver(measure);
|
|
70
|
+
observer.observe(element);
|
|
71
|
+
measure();
|
|
72
|
+
return () => observer.disconnect();
|
|
73
|
+
}, [fitted]);
|
|
74
|
+
const zoom = size.width > 0 ? Math.min(diagramScale, size.width / bounds.width, mode === "fit" ? size.height / bounds.height : Infinity) : diagramScale;
|
|
75
|
+
const offsetX = Math.max(0, size.width - bounds.width * zoom) / 2;
|
|
76
|
+
const offsetY = mode === "fit" ? Math.max(0, size.height - bounds.height * zoom) / 2 : 0;
|
|
77
|
+
return <div ref={host} className="w-full min-w-0" style={{ height: mode === "fit-width" ? Math.ceil(bounds.height * zoom) : "100%" }}><ReactFlow
|
|
78
|
+
viewport={fitted ? { x: offsetX - bounds.x * zoom, y: offsetY - bounds.y * zoom, zoom } : undefined}
|
|
79
|
+
zoomOnScroll={!fitted} zoomOnPinch={!fitted} zoomOnDoubleClick={!fitted} panOnDrag={!fitted} panOnScroll={false}
|
|
80
|
+
preventScrolling={!fitted} disableKeyboardA11y={fitted} autoPanOnNodeFocus={false}
|
|
81
|
+
zoomActivationKeyCode={fitted ? null : "Meta"} panActivationKeyCode={fitted ? null : "Space"}
|
|
82
|
+
ariaLabelConfig={{ "controls.zoomIn.ariaLabel": "Zoom vergrößern", "controls.zoomOut.ariaLabel": "Zoom verkleinern", "controls.fitView.ariaLabel": "Ansicht zentrieren" }} nodes={nodes} edges={edges.map(edge => ({ ...edge, markerEnd: { type: MarkerType.ArrowClosed, color: edgeColors[edge.data?.status ?? "pending"] } }))} nodeTypes={nodeTypes} edgeTypes={edgeTypes} nodesDraggable={false} nodesConnectable={false} elementsSelectable={false} nodesFocusable={false} edgesFocusable={false} fitView={!fitted} fitViewOptions={{ minZoom: diagramScale, maxZoom: diagramScale, padding: 0.15 }} minZoom={fitted ? zoom : 0.3} maxZoom={fitted ? zoom : 2} proOptions={{ hideAttribution: true }}>
|
|
83
|
+
{!fitted && <Controls showInteractive={false} fitViewOptions={{ minZoom: diagramScale, maxZoom: diagramScale }} />}
|
|
84
|
+
</ReactFlow></div>;
|
|
85
|
+
}
|
|
@@ -0,0 +1,126 @@
|
|
|
1
|
+
import React, { useId, useRef, useState, type FormEvent } from "react";
|
|
2
|
+
import { Button, Checkbox, Field, FieldDescription, FieldError, FieldLabel, Input, Select, SelectContent, SelectItem, SelectTrigger, SelectValue, Textarea } from "../../../apps/web/src/ui";
|
|
3
|
+
import type { FormErrors, FormField, FormProps, FormValue, FormValues } from "./form-contracts";
|
|
4
|
+
|
|
5
|
+
export function validateForm(fields: readonly FormField[], values: FormValues, validate?: FormProps["validate"]): FormErrors {
|
|
6
|
+
const errors: Record<string, string> = {};
|
|
7
|
+
for (const field of fields) {
|
|
8
|
+
if (field.disabled) continue;
|
|
9
|
+
const value = values[field.id];
|
|
10
|
+
const empty = value === undefined || value === null || typeof value === "string" && value.trim() === "";
|
|
11
|
+
if (field.required && (empty || field.type === "checkbox" && value !== true)) {
|
|
12
|
+
errors[field.id] = "Bitte ausfüllen.";
|
|
13
|
+
} else if (!empty) {
|
|
14
|
+
if (field.type === "number") {
|
|
15
|
+
if (typeof value !== "number" || !Number.isFinite(value)) errors[field.id] = "Bitte eine gültige Zahl eingeben.";
|
|
16
|
+
else if (field.min !== undefined && value < field.min) errors[field.id] = `Mindestens ${field.min}.`;
|
|
17
|
+
else if (field.max !== undefined && value > field.max) errors[field.id] = `Höchstens ${field.max}.`;
|
|
18
|
+
} else if (field.type === "checkbox") {
|
|
19
|
+
if (typeof value !== "boolean") errors[field.id] = "Bitte eine gültige Auswahl treffen.";
|
|
20
|
+
} else if (typeof value !== "string") {
|
|
21
|
+
errors[field.id] = "Bitte Text eingeben.";
|
|
22
|
+
} else if (field.type === "select" && !field.options.some((option) => option.value === value)) {
|
|
23
|
+
errors[field.id] = "Bitte einen angebotenen Wert auswählen.";
|
|
24
|
+
}
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
return { ...validate?.(values), ...errors };
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
export function Form({ title, fields, values, onChange, onSubmit, validate, submitLabel = "Speichern", disabled = false, readOnly = false }: FormProps) {
|
|
31
|
+
const prefix = useId();
|
|
32
|
+
const form = useRef<HTMLFormElement>(null);
|
|
33
|
+
const sending = useRef(false);
|
|
34
|
+
const [pending, setPending] = useState(false);
|
|
35
|
+
const [errors, setErrors] = useState<FormErrors>({});
|
|
36
|
+
const [error, setError] = useState<string>();
|
|
37
|
+
const ids = new Set(fields.map((field) => field.id));
|
|
38
|
+
if (ids.size !== fields.length || fields.some((field) => !field.id.trim())) throw new Error("Formularfelder benötigen eindeutige, nicht leere IDs.");
|
|
39
|
+
|
|
40
|
+
const change = (field: FormField, value: FormValue) => {
|
|
41
|
+
if (sending.current || disabled || readOnly || field.disabled || field.readOnly) return;
|
|
42
|
+
setErrors((current) => Object.fromEntries(Object.entries(current).filter(([id]) => id !== field.id)));
|
|
43
|
+
setError(undefined);
|
|
44
|
+
onChange({ ...values, [field.id]: value }, field.id);
|
|
45
|
+
};
|
|
46
|
+
const submit = async (event: FormEvent<HTMLFormElement>) => {
|
|
47
|
+
event.preventDefault();
|
|
48
|
+
if (!onSubmit || sending.current || disabled || readOnly) return;
|
|
49
|
+
setError(undefined);
|
|
50
|
+
try {
|
|
51
|
+
const nextErrors = validateForm(fields, values, validate);
|
|
52
|
+
setErrors(nextErrors);
|
|
53
|
+
if (Object.values(nextErrors).some(Boolean)) {
|
|
54
|
+
const index = fields.findIndex((field) => nextErrors[field.id]);
|
|
55
|
+
form.current?.querySelector<HTMLElement>(`[data-field-index="${index}"] input, [data-field-index="${index}"] textarea, [data-field-index="${index}"] button`)?.focus();
|
|
56
|
+
return;
|
|
57
|
+
}
|
|
58
|
+
sending.current = true;
|
|
59
|
+
setPending(true);
|
|
60
|
+
await onSubmit({ ...values });
|
|
61
|
+
} catch (cause) {
|
|
62
|
+
setError(cause instanceof Error ? cause.message : String(cause));
|
|
63
|
+
} finally {
|
|
64
|
+
sending.current = false;
|
|
65
|
+
setPending(false);
|
|
66
|
+
}
|
|
67
|
+
};
|
|
68
|
+
return (
|
|
69
|
+
<form aria-label={title ?? "Formular"} aria-busy={pending} className="flex min-w-0 flex-col gap-4" noValidate onSubmit={(event) => void submit(event)} ref={form}>
|
|
70
|
+
{title && <h2 className="text-base font-semibold">{title}</h2>}
|
|
71
|
+
{fields.map((field, index) => {
|
|
72
|
+
const id = `${prefix}-${index}`;
|
|
73
|
+
const fieldError = errors[field.id];
|
|
74
|
+
const locked = readOnly || field.readOnly;
|
|
75
|
+
const inactive = disabled || pending || field.disabled;
|
|
76
|
+
const describedBy = [field.hint && `${id}-hint`, fieldError && `${id}-error`].filter(Boolean).join(" ") || undefined;
|
|
77
|
+
const value = values[field.id];
|
|
78
|
+
const label = `${field.label}${field.required ? " *" : ""}`;
|
|
79
|
+
const shared = { id, disabled: inactive, readOnly: locked, required: field.required, "aria-invalid": Boolean(fieldError), "aria-describedby": describedBy };
|
|
80
|
+
const hint = field.hint && <FieldDescription id={`${id}-hint`}>{field.hint}</FieldDescription>;
|
|
81
|
+
const problem = fieldError && <FieldError id={`${id}-error`}>{fieldError}</FieldError>;
|
|
82
|
+
if (field.type === "checkbox") {
|
|
83
|
+
return (
|
|
84
|
+
<Field data-disabled={inactive || locked} data-field-index={index} data-invalid={Boolean(fieldError)} key={field.id} orientation="horizontal">
|
|
85
|
+
<Checkbox {...shared} checked={value === true} disabled={inactive || locked} onCheckedChange={(checked) => change(field, checked)} />
|
|
86
|
+
<div className="flex flex-col gap-0.5">
|
|
87
|
+
<FieldLabel htmlFor={id}>{label}</FieldLabel>
|
|
88
|
+
{hint}
|
|
89
|
+
{problem}
|
|
90
|
+
</div>
|
|
91
|
+
</Field>
|
|
92
|
+
);
|
|
93
|
+
}
|
|
94
|
+
if (field.type === "select") {
|
|
95
|
+
return (
|
|
96
|
+
<Field data-disabled={inactive} data-field-index={index} data-invalid={Boolean(fieldError)} key={field.id}>
|
|
97
|
+
<FieldLabel htmlFor={id}>{label}</FieldLabel>
|
|
98
|
+
{locked
|
|
99
|
+
? <p className="text-sm">{field.options.find((option) => option.value === value)?.label ?? String(value ?? "")}</p>
|
|
100
|
+
: <Select disabled={inactive} items={field.options} value={typeof value === "string" ? value : ""} onValueChange={(next) => { if (next !== null) change(field, next); }}>
|
|
101
|
+
<SelectTrigger aria-describedby={describedBy} aria-invalid={Boolean(fieldError)} className="w-full" id={id}><SelectValue /></SelectTrigger>
|
|
102
|
+
<SelectContent>{field.options.map((option) => <SelectItem key={option.value} value={option.value}>{option.label}</SelectItem>)}</SelectContent>
|
|
103
|
+
</Select>}
|
|
104
|
+
{hint}
|
|
105
|
+
{problem}
|
|
106
|
+
</Field>
|
|
107
|
+
);
|
|
108
|
+
}
|
|
109
|
+
return (
|
|
110
|
+
<Field data-disabled={inactive} data-field-index={index} data-invalid={Boolean(fieldError)} key={field.id}>
|
|
111
|
+
<FieldLabel htmlFor={id}>{label}</FieldLabel>
|
|
112
|
+
{field.type === "textarea"
|
|
113
|
+
? <Textarea {...shared} onChange={(event) => change(field, event.target.value)} placeholder={field.placeholder} rows={field.rows ?? 2} value={typeof value === "string" ? value : ""} />
|
|
114
|
+
: field.type === "number"
|
|
115
|
+
? <Input {...shared} max={field.max} min={field.min} onChange={(event) => change(field, Number.isNaN(event.target.valueAsNumber) ? null : event.target.valueAsNumber)} placeholder={field.placeholder} step={field.step ?? "any"} type="number" value={typeof value === "number" && Number.isFinite(value) ? value : ""} />
|
|
116
|
+
: <Input {...shared} onChange={(event) => change(field, event.target.value)} placeholder={field.placeholder} type="text" value={typeof value === "string" ? value : ""} />}
|
|
117
|
+
{hint}
|
|
118
|
+
{problem}
|
|
119
|
+
</Field>
|
|
120
|
+
);
|
|
121
|
+
})}
|
|
122
|
+
{error && <FieldError>{error}</FieldError>}
|
|
123
|
+
{onSubmit && !readOnly && <Button className="self-start" disabled={disabled || pending} type="submit">{pending ? "Wird gespeichert ..." : submitLabel}</Button>}
|
|
124
|
+
</form>
|
|
125
|
+
);
|
|
126
|
+
}
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
import React, { useId } from "react";
|
|
2
|
+
import { cn } from "../../../apps/web/src/ui";
|
|
3
|
+
import type { AppLayoutProps, GridProps, LayoutGap, StackProps } from "./layout-contracts";
|
|
4
|
+
|
|
5
|
+
const gaps: Record<LayoutGap, string> = { small: "gap-1.5", normal: "gap-3", large: "gap-5" };
|
|
6
|
+
|
|
7
|
+
export function AppLayout({ title, description, actions, children, fill = false }: AppLayoutProps) {
|
|
8
|
+
const titleId = useId();
|
|
9
|
+
return <section aria-labelledby={title ? titleId : undefined} className={cn("flex min-w-0 flex-col gap-4 p-4 text-sm break-words [#root>&]:p-0", fill && "h-full min-h-0")} data-fill={fill}>
|
|
10
|
+
{(title || description) && <header className="flex min-w-0 flex-none flex-col gap-1">
|
|
11
|
+
{title && <h1 className="text-xl leading-tight font-semibold" id={titleId}>{title}</h1>}
|
|
12
|
+
{description && <div className="text-muted-foreground">{description}</div>}
|
|
13
|
+
</header>}
|
|
14
|
+
<div className={cn("min-w-0", fill && "-m-1 min-h-0 flex-1 overflow-auto p-1 [scrollbar-gutter:stable]")}>{children}</div>
|
|
15
|
+
{actions && <footer className="flex min-w-0 flex-none flex-wrap items-center gap-2">{actions}</footer>}
|
|
16
|
+
</section>;
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
export function Stack({ children, gap = "normal", direction = "column" }: StackProps) {
|
|
20
|
+
return <div className={cn("flex min-w-0 *:max-w-full *:min-w-0", gaps[gap], direction === "row" ? "flex-row flex-wrap items-center" : "flex-col")}>{children}</div>;
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
export function Grid({ children, columns = 2, gap = "normal" }: GridProps) {
|
|
24
|
+
return <div className="@container min-w-0">
|
|
25
|
+
<div className={cn("grid grid-cols-1 items-start *:max-w-full *:min-w-0 @[520px]:grid-cols-2", gaps[gap], columns === 3 && "@[760px]:grid-cols-3")}>{children}</div>
|
|
26
|
+
</div>;
|
|
27
|
+
}
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
import React, { useMemo } from "react";
|
|
2
|
+
import { cn } from "../../../apps/web/src/ui";
|
|
3
|
+
import { ChatMessages } from "../../../apps/web/src/chat/ChatMessages";
|
|
4
|
+
import type { Message } from "../../../apps/server/src/chat-events";
|
|
5
|
+
import type { MessageListProps } from "./message-list-contracts";
|
|
6
|
+
|
|
7
|
+
const hues = [212, 158, 28, 283, 350, 190, 95, 320, 55, 245];
|
|
8
|
+
const senderColor = (sender: string): string => {
|
|
9
|
+
let hash = 0;
|
|
10
|
+
for (const character of sender) hash = (Math.imul(hash, 31) + character.codePointAt(0)!) >>> 0;
|
|
11
|
+
return `hsl(${hues[hash % hues.length]} 45% 42%)`;
|
|
12
|
+
};
|
|
13
|
+
|
|
14
|
+
export function MessageList({ messages, label = "Nachrichten", className, ...props }: MessageListProps) {
|
|
15
|
+
const rendered = useMemo(() => messages.map((message): Message => ({
|
|
16
|
+
key: message.key,
|
|
17
|
+
role: "assistant",
|
|
18
|
+
sender: message.sender,
|
|
19
|
+
text: message.text,
|
|
20
|
+
closed: true,
|
|
21
|
+
at: message.at,
|
|
22
|
+
attachments: message.attachments,
|
|
23
|
+
bubble: { label: message.sender, color: message.color ?? senderColor(message.sender), side: message.side ?? "start" },
|
|
24
|
+
})), [messages]);
|
|
25
|
+
return (
|
|
26
|
+
<section aria-label={label} className={cn("flex h-full min-h-0 w-full min-w-0 flex-col text-foreground", className)}>
|
|
27
|
+
<ChatMessages {...props} detailMode="off" messages={rendered} />
|
|
28
|
+
</section>
|
|
29
|
+
);
|
|
30
|
+
}
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
import React from "react";
|
|
2
|
+
import { Markdown } from "../../../apps/web/src/chat/Markdown";
|
|
3
|
+
import { DiffCode } from "../../../apps/web/src/DiffCode";
|
|
4
|
+
import { SourceCode } from "../../../apps/web/src/SourceCode";
|
|
5
|
+
import { cn, Progress } from "../../../apps/web/src/ui";
|
|
6
|
+
import type { DiffViewerProps, DocumentViewerProps, TaskProgressProps } from "./viewer-contracts";
|
|
7
|
+
|
|
8
|
+
const taskLabels = { pending: "Offen", running: "In Arbeit", done: "Erledigt", error: "Fehlgeschlagen", skipped: "Übersprungen" };
|
|
9
|
+
const taskTones = { pending: "text-muted-foreground", running: "text-primary", done: "text-muted-foreground", error: "text-destructive", skipped: "text-muted-foreground" };
|
|
10
|
+
|
|
11
|
+
export function TaskProgress({ title = "Aufgaben", tasks, showProgress = true }: TaskProgressProps) {
|
|
12
|
+
const completed = tasks.filter((task) => task.status === "done" || task.status === "skipped").length;
|
|
13
|
+
return <section aria-label={title} className="min-w-0 text-sm">
|
|
14
|
+
<h3 className="mb-2 text-[15px] font-semibold">{title}</h3>
|
|
15
|
+
{showProgress && tasks.length > 0 && <div className="mb-2 flex flex-wrap items-center gap-2 text-muted-foreground">
|
|
16
|
+
<Progress aria-label={title} className="min-w-20 flex-1" max={tasks.length} value={completed} />
|
|
17
|
+
<span>{completed} von {tasks.length} abgeschlossen</span>
|
|
18
|
+
</div>}
|
|
19
|
+
{!tasks.length && <p>Noch keine Aufgaben.</p>}
|
|
20
|
+
<ol className="divide-y">{tasks.map((task) => <li className="py-1.5" data-status={task.status} key={task.id}>
|
|
21
|
+
<div className="flex justify-between gap-3"><strong>{task.label}</strong><span className={cn("whitespace-nowrap", taskTones[task.status])}>{taskLabels[task.status]}</span></div>
|
|
22
|
+
{task.description && <p className="mt-1 text-muted-foreground">{task.description}</p>}
|
|
23
|
+
</li>)}</ol>
|
|
24
|
+
</section>;
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
export function DocumentViewer({ title, content, format = "text", language, filename }: DocumentViewerProps) {
|
|
28
|
+
return <section aria-label={title ?? filename ?? "Dokument"} className="min-w-0 text-sm">
|
|
29
|
+
{(title || filename) && <h3 className="mb-2 text-[15px] font-semibold">{title ?? filename}</h3>}
|
|
30
|
+
{format === "markdown" ? <Markdown text={content} />
|
|
31
|
+
: format === "code" ? <SourceCode content={content} language={language} path={filename ?? ""} />
|
|
32
|
+
: <pre className="m-0 font-[inherit] break-words whitespace-pre-wrap">{content}</pre>}
|
|
33
|
+
</section>;
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
export function DiffViewer({ title = "Änderungen", patch, emptyText = "Keine Änderungen.", language, filename }: DiffViewerProps) {
|
|
37
|
+
return <section aria-label={title} className="min-w-0 text-sm">
|
|
38
|
+
<h3 className="mb-2 text-[15px] font-semibold">{title}</h3>
|
|
39
|
+
{!patch ? <p>{emptyText}</p> : <div className="max-w-full overflow-auto rounded-lg border"><DiffCode content={patch} emptyText={emptyText} language={language} path={filename} /></div>}
|
|
40
|
+
</section>;
|
|
41
|
+
}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import React, { useMemo } from "react";
|
|
2
|
+
import { workflowGraph } from "../workflow/index";
|
|
3
|
+
import { FlowDiagram } from "./FlowDiagram";
|
|
4
|
+
import type { WorkflowDiagramProps } from "./workflow-diagram-contracts";
|
|
5
|
+
|
|
6
|
+
export function WorkflowDiagram({ definition, state, ...props }: WorkflowDiagramProps) {
|
|
7
|
+
const projection = useMemo(() => {
|
|
8
|
+
try { return { graph: workflowGraph(definition, state) }; }
|
|
9
|
+
catch (error) { return { error: error instanceof Error ? error.message : String(error) }; }
|
|
10
|
+
}, [definition, state]);
|
|
11
|
+
return projection.graph
|
|
12
|
+
? <FlowDiagram direction="down" viewport="fit-width" {...props} {...projection.graph} />
|
|
13
|
+
: <section aria-label={props.label} className={props.className}><p role="alert">Der Ablauf konnte nicht angezeigt werden: {projection.error}</p></section>;
|
|
14
|
+
}
|