@schlenkr/ragents 0.1.8 → 0.1.9
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/apps/server/src/config-definition.ts +24 -2
- package/apps/server/src/config.ts +0 -6
- package/apps/server/src/host-api.json +3 -10
- package/apps/server/src/host-api.ts +6 -7
- package/apps/server/src/plugin-build/build.ts +28 -5
- package/apps/server/src/plugin-build/plugin-description.ts +1 -1
- package/apps/server/src/plugin-build/typecheck.ts +2 -2
- package/apps/server/src/plugin-support/language-server/plugin.ts +8 -7
- package/apps/server/src/plugin-support/language-server/tools.ts +7 -6
- package/apps/server/src/plugin-support/model-aliases.ts +55 -25
- package/apps/server/src/plugin-support/product-relay.ts +10 -2
- package/apps/server/src/plugin-support/workspace-sandbox-host.ts +18 -9
- package/apps/server/src/profile/bundle-manifest.ts +7 -3
- package/apps/server/src/profile/compose.ts +6 -0
- package/apps/server/src/profile/plugin-discovery.ts +6 -1
- package/apps/server/src/profile/provisioning.ts +6 -5
- package/apps/server/src/ragents/engine.ts +0 -1
- package/apps/server/src/ragents/host-services.ts +4 -0
- package/apps/server/src/ragents/session.ts +1 -1
- package/apps/server/src/server.ts +1 -0
- package/apps/server/tsconfig.json +2 -0
- package/apps/web/dist/help/guide-clients.html +14 -6
- package/apps/web/dist/help/guide-clients.md +14 -6
- package/apps/web/dist/help/guide-distributed.html +12 -4
- package/apps/web/dist/help/guide-distributed.md +12 -4
- package/apps/web/dist/help/guide-getting-started.html +12 -8
- package/apps/web/dist/help/guide-getting-started.md +12 -8
- package/apps/web/dist/help/guide-plugins.html +6 -2
- package/apps/web/dist/help/guide-plugins.md +6 -2
- package/apps/web/dist/help/guide-runtime.html +2 -1
- package/apps/web/dist/help/guide-runtime.md +2 -1
- package/apps/web/dist/help/index.html +3328 -1135
- package/apps/web/dist/host-web.json +3 -3
- package/bundles/ragents.activity/ragents-bundle.json +3 -3
- package/bundles/ragents.actor-programs/ragents-bundle.json +3 -3
- package/bundles/ragents.ask/ragents-bundle.json +4 -4
- package/bundles/ragents.ask/server/index.js +42 -11
- package/bundles/ragents.ask/server/index.js.map +3 -3
- package/bundles/ragents.ask/web/chunks/chunk-WFN4374U.js +2 -0
- package/bundles/ragents.ask/web/chunks/chunk-WFN4374U.js.map +7 -0
- package/bundles/ragents.ask/web/classes.json +1 -1
- package/bundles/ragents.ask/web/exports/ask-payload.js +1 -1
- package/bundles/ragents.ask/web/index.js +1 -1
- package/bundles/ragents.ask/web/index.js.map +3 -3
- package/bundles/ragents.browser/executor/index.mjs +357 -0
- package/bundles/ragents.browser/executor/index.mjs.map +7 -0
- package/bundles/ragents.browser/ragents-bundle.json +5 -8
- package/bundles/ragents.browser/server/chunks/{chunk-2GKLLCBE.js → chunk-CWLX4VA5.js} +1 -1
- package/bundles/ragents.browser/server/chunks/chunk-CWLX4VA5.js.map +7 -0
- package/bundles/ragents.browser/server/exports/server/contract.js +1 -1
- package/bundles/ragents.browser/server/index.js +20 -9
- package/bundles/ragents.browser/server/index.js.map +4 -4
- package/bundles/ragents.documents/ragents-bundle.json +3 -3
- package/bundles/ragents.lsp-fsharp/executor/index.mjs +68 -0
- package/bundles/ragents.lsp-fsharp/executor/index.mjs.map +7 -0
- package/bundles/ragents.lsp-fsharp/ragents-bundle.json +5 -9
- package/bundles/ragents.lsp-fsharp/server/index.js +21 -6
- package/bundles/ragents.lsp-fsharp/server/index.js.map +4 -4
- package/bundles/ragents.lsp-roslyn/executor/index.mjs +68 -0
- package/bundles/ragents.lsp-roslyn/executor/index.mjs.map +7 -0
- package/bundles/ragents.lsp-roslyn/ragents-bundle.json +6 -8
- package/bundles/ragents.lsp-roslyn/server/index.js +54 -15
- package/bundles/ragents.lsp-roslyn/server/index.js.map +4 -4
- package/bundles/ragents.lsp-typescript/executor/index.mjs +49 -0
- package/bundles/ragents.lsp-typescript/executor/index.mjs.map +7 -0
- package/bundles/ragents.lsp-typescript/ragents-bundle.json +5 -7
- package/bundles/ragents.lsp-typescript/server/index.js +22 -2
- package/bundles/ragents.lsp-typescript/server/index.js.map +3 -3
- package/bundles/ragents.model-relay/ragents-bundle.json +4 -4
- package/bundles/ragents.model-relay/server/index.js +3 -2
- package/bundles/ragents.model-relay/server/index.js.map +2 -2
- package/bundles/ragents.orchestration/ragents-bundle.json +3 -3
- package/bundles/ragents.overseer/ragents-bundle.json +3 -3
- package/bundles/ragents.processes/ragents-bundle.json +3 -3
- package/bundles/ragents.product/ragents-bundle.json +3 -3
- package/bundles/ragents.profile-distribution/ragents-bundle.json +4 -4
- package/bundles/ragents.profile-distribution/server/index.js +1 -1
- package/bundles/ragents.profile-distribution/server/index.js.map +2 -2
- package/bundles/ragents.reference/ragents-bundle.json +3 -3
- package/bundles/ragents.todo/ragents-bundle.json +3 -3
- package/bundles/ragents.transcript/ragents-bundle.json +3 -3
- package/bundles/ragents.watch/ragents-bundle.json +3 -3
- package/bundles/ragents.workspace/ragents-bundle.json +11 -5
- package/bundles/ragents.workspace/server/index.js +101 -28
- package/bundles/ragents.workspace/server/index.js.map +3 -3
- package/bundles/ragents.workspace/web/classes.json +1 -1
- package/bundles/ragents.workspace/web/index.js +1 -1
- package/bundles/ragents.workspace/web/index.js.map +3 -3
- package/package.json +2 -2
- package/packages/agent/dist/core/agent-settings.d.ts +1 -7
- package/packages/agent/dist/core/compaction/compaction.d.ts +17 -13
- package/packages/agent/dist/core/model-runtime.d.ts +5 -4
- package/packages/agent/dist/core/provider-composer.d.ts +2 -1
- package/packages/agent/dist/core/tools/bash.d.ts +9 -3
- package/packages/agent/dist/index.d.ts +1 -1
- package/packages/agent/src/core/agent-settings.ts +1 -4
- package/packages/agent/src/core/compaction/compaction.ts +68 -30
- package/packages/agent/src/core/model-runtime.ts +12 -5
- package/packages/agent/src/core/provider-composer.ts +5 -0
- package/packages/agent/src/core/tools/bash.ts +36 -30
- package/packages/agent/src/index.ts +3 -0
- package/packages/ai/dist/types.d.ts +11 -0
- package/packages/ai/src/types.ts +12 -0
- package/packages/ragents/src/domain/event-semantics.ts +3 -0
- package/packages/ragents/src/domain/event-validation.ts +15 -2
- package/packages/ragents/src/domain/events.ts +3 -0
- package/packages/ragents/src/domain/model.ts +2 -0
- package/packages/ragents/src/domain/projection.ts +1 -0
- package/packages/ragents/src/drivers/agent-runtime.ts +1 -1
- package/packages/ragents/src/drivers/agent-turn.ts +8 -6
- package/packages/ragents/src/runtime/decisions/inputs.ts +6 -2
- package/packages/ragents/src/runtime/journal-storage.ts +5 -4
- package/packages/workspace-executor/package.json +0 -1
- package/packages/workspace-executor/src/bash-launch.ts +56 -10
- package/packages/workspace-executor/src/context.ts +4 -0
- package/packages/workspace-executor/src/contributions.ts +150 -0
- package/packages/workspace-executor/src/executor.ts +1 -1
- package/packages/workspace-executor/src/index.ts +16 -19
- package/packages/workspace-executor/src/language-server/host.ts +3 -0
- package/packages/workspace-executor/src/language-server/module.ts +12 -2
- package/packages/workspace-executor/src/language-server/roots.ts +0 -5
- package/packages/workspace-executor/src/modules.ts +7 -6
- package/packages/workspace-executor/src/sandbox-tools.ts +3 -9
- package/packages/workspace-executor/src/shell-platform.ts +14 -3
- package/packages/workspace-executor/src/tools.ts +0 -3
- package/plugins/ragents.ask/ask-payload.ts +9 -0
- package/plugins/ragents.ask/server/ask-service.ts +53 -13
- package/plugins/ragents.ask/web/AskActionView.tsx +3 -2
- package/plugins/ragents.browser/executor/index.ts +5 -0
- package/{packages/workspace-executor/src/browser → plugins/ragents.browser/executor}/module.ts +25 -31
- package/{packages/workspace-executor/src/browser → plugins/ragents.browser/executor}/playwright.ts +9 -23
- package/plugins/ragents.browser/provision.ts +1 -1
- package/plugins/ragents.browser/server/browser.ts +3 -3
- package/plugins/ragents.browser/server/contract.ts +2 -2
- package/plugins/ragents.browser/server/index.ts +1 -1
- package/plugins/ragents.lsp-fsharp/executor.ts +80 -0
- package/plugins/ragents.lsp-fsharp/provision.ts +1 -1
- package/plugins/ragents.lsp-fsharp/server/index.ts +2 -2
- package/plugins/ragents.lsp-roslyn/executor.ts +64 -0
- package/plugins/ragents.lsp-roslyn/provision.ts +1 -1
- package/plugins/ragents.lsp-roslyn/server/index.ts +28 -5
- package/plugins/ragents.lsp-roslyn/server/solution-on-start.ts +18 -6
- package/plugins/ragents.lsp-typescript/executor.ts +50 -0
- package/plugins/ragents.lsp-typescript/server/index.ts +2 -2
- package/plugins/ragents.model-relay/server/config.ts +1 -1
- package/plugins/ragents.model-relay/server/relay.ts +4 -2
- package/plugins/ragents.profile-distribution/server/archive.ts +2 -1
- package/plugins/ragents.workspace/client/workspace-client.ts +111 -28
- package/plugins/ragents.workspace/contract.ts +33 -2
- package/plugins/ragents.workspace/server/binding.ts +10 -4
- package/plugins/ragents.workspace/server/clients.ts +56 -9
- package/plugins/ragents.workspace/server/config.ts +9 -0
- package/plugins/ragents.workspace/server/index.ts +13 -4
- package/plugins/ragents.workspace/server/runtime.ts +10 -0
- package/plugins/ragents.workspace/server/shell-platform.ts +6 -5
- package/plugins/ragents.workspace/web/WorkspaceBinding.tsx +1 -1
- package/ragents.config.core.ts +4 -1
- package/ragents.config.showcase.ts +4 -1
- package/scripts/agent/journal.ts +3 -1
- package/scripts/package/build-package.ts +3 -1
- package/scripts/provision/run-provision.ts +2 -2
- package/scripts/workspace-client/run-workspace-client.ts +7 -4
- package/apps/web/dist/help/screenshots/release-checklist-vscode.png +0 -0
- package/apps/web/dist/help/screenshots/release-checklist-web.png +0 -0
- package/bundles/ragents.ask/web/chunks/chunk-HGFDGTNC.js +0 -2
- package/bundles/ragents.ask/web/chunks/chunk-HGFDGTNC.js.map +0 -7
- package/bundles/ragents.browser/server/chunks/chunk-2GKLLCBE.js.map +0 -7
- package/packages/workspace-executor/src/language-server/adapters/fsharp.ts +0 -60
- package/packages/workspace-executor/src/language-server/adapters/index.ts +0 -7
- package/packages/workspace-executor/src/language-server/adapters/roslyn.ts +0 -56
- package/packages/workspace-executor/src/language-server/adapters/typescript.ts +0 -74
- package/packages/workspace-executor/src/language-server/solution.ts +0 -13
- /package/{packages/workspace-executor/src/browser → plugins/ragents.browser/executor}/contract.ts +0 -0
- /package/{packages/workspace-executor/src/browser → plugins/ragents.browser/executor}/pages.ts +0 -0
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../../../plugins/ragents.workspace/server/index.ts", "../../../plugins/ragents.workspace/server/shell-platform.ts", "../../../plugins/ragents.workspace/server/workspace-tool-naming.ts", "../../../plugins/ragents.workspace/contract.ts", "../../../plugins/ragents.workspace/server/binding.ts", "../../../plugins/ragents.workspace/server/browse-route.ts", "../../../plugins/ragents.workspace/server/clients.ts", "../../../plugins/ragents.workspace/server/config.ts", "../../../plugins/ragents.workspace/server/runtime.ts"],
|
|
4
|
-
"sourcesContent": ["import path from \"node:path\";\nimport { DomainError, type JsonValue, type RAgentsPlugin, type RunState } from \"@ragents/engine\";\nimport { documentStoreToken } from \"@ragents/host/ragents/document-store.js\";\nimport { workspaceResolverToken, workspaceRuntimeToken, type WorkspaceResolver } from \"@ragents/host/ragents/workspace-runtime.js\";\nimport { sandboxServicesToken } from \"@ragents/host/plugin-support/workspace-sandbox-host.js\";\nimport {\n hostAddressToken,\n runtimeProviderToken,\n runGuardToken,\n runWorkspaceProviderToken,\n workspaceGuardToken,\n} from \"@ragents/host/ragents/host-services.js\";\nimport { pluginAsset } from \"@ragents/host/plugin-support/plugin-folder.js\";\nimport { ServerProcessSandbox } from \"@ragents/host/plugin-support/process-sandbox.js\";\nimport type { PluginModule } from \"@ragents/host/plugin-support/plugin-module.js\";\nimport { boundToTools, handlebarsPrompt } from \"@ragents/host/plugin-support/prompt.js\";\nimport { shellPlatformPrompt } from \"./shell-platform.js\";\nimport { agentWorkspaceToolNames } from \"./workspace-tool-naming.js\";\nimport { startOptionScope } from \"@ragents/host/ragents/start-option-state.js\";\nimport { WORKSPACE_BINDING_OPTION_ID, WORKSPACE_METADATA_ID } from \"../contract.js\";\nimport { bindingOf, executorShellChapter, sessionMetadataOf, workspaceBindingOption, workspaceLocation, workspaceOwnerOf } from \"./binding.js\";\nimport { createBrowseChannel, createBrowseMethods } from \"./browse-route.js\";\nimport { clientMethods, WorkspaceClientRegistry } from \"./clients.js\";\nimport { bashSetting, processSandboxSetting, workspaceConfigDescriptors } from \"./config.js\";\nimport { RunWorkspaceRuntime } from \"./runtime.js\";\n\nconst warnWithoutSandbox = (): void => {\n console.warn(\"Prozess-Sandbox ausgeschaltet (PROCESS_SANDBOX: \\\"off\\\" in der Sektion ragents.workspace): Prozesse der Runs laufen auf dem Server ohne Sandbox.\");\n};\n\nconst ragentsWorkspacePlugin = (skillPaths: () => Promise<readonly string[]>): RAgentsPlugin => ({\n manifest: { id: \"ragents.workspace\" },\n register: (host) => {\n const sessionWorkspaceFor = host.service(runWorkspaceProviderToken);\n const orchestration = host.service(runtimeProviderToken);\n const runState = (runId: string): RunState | null => {\n try {\n return orchestration().state(runId);\n } catch (error) {\n if (error instanceof DomainError && error.code === \"run-not-found\") return null;\n throw error;\n }\n };\n const documentsFor = (runId: string): Promise<string | undefined> =>\n host.optionalService(documentStoreToken)?.directoryFor(runId) ?? Promise.resolve(undefined);\n const documentsRoot = async (runId: string): Promise<string> => {\n const directory = await documentsFor(runId);\n if (!directory) throw new Error(\"In diesem Profil gibt es keine Dateiablage; das Plugin ragents.documents fehlt\");\n return directory;\n };\n const clients = new WorkspaceClientRegistry();\n const contribution = (): WorkspaceResolver | undefined => host.optionalService(workspaceResolverToken);\n host.config(...workspaceConfigDescriptors);\n const sandboxSetting = processSandboxSetting();\n const processSandbox = sandboxSetting.enabled\n ? new ServerProcessSandbox({\n network: sandboxSetting.network,\n serverAddress: host.service(hostAddressToken)(),\n dataDirectory: path.dirname(host.storage.sessionsRoot),\n })\n : undefined;\n const bash = bashSetting();\n const runtime = new RunWorkspaceRuntime({\n clients,\n ...(processSandbox ? { processSandbox } : {}),\n ...(bash === undefined ? {} : { bash }),\n globalDirectory: host.storage.root(),\n sessionDirectory: (runId, ...segments) => host.storage.session(runId, ...segments),\n storageRootFor: (runId) => path.join(host.storage.sessionsRoot, runId),\n sessionsDirectoryPattern: path.join(host.storage.sessionsRoot, \"{runId}\", \"plugins\", host.manifest.id),\n sessionWorkspaceFor,\n skillPaths,\n resolver: contribution,\n runState,\n storeBinding: (runId, binding) => {\n const state = orchestration().state(runId);\n orchestration().replacePluginState(\n { actorId: state.ownerId, commandId: `workspace-binding:${runId}:${state.revision}` },\n runId,\n { pluginId: WORKSPACE_BINDING_OPTION_ID, scope: startOptionScope, state: binding as unknown as JsonValue },\n );\n },\n });\n host.provide(workspaceRuntimeToken, runtime);\n host.provide(sandboxServicesToken, runtime.sandbox);\n host.functions(runtime.sandbox.workspaceTools());\n const rules = handlebarsPrompt(\"ragents.workspace.prompt\", 100, pluginAsset(\"ragents.workspace\", \"prompt.hbs\"));\n host.prompts(\n boundToTools({\n ...rules,\n delivery: \"initial\",\n // Die Regeln gelten f\u00FCr die Arbeitsbereiche des Hosts; eine beigesteuerte Art beschreibt ihre eigenen.\n render: (context) => contribution()?.kind ? \"\" : rules.render(context),\n }, ...agentWorkspaceToolNames),\n shellPlatformPrompt(\"ragents.workspace.shell.prompt\", 102, (runId) => {\n const state = runState(runId);\n return executorShellChapter(clients, workspaceOwnerOf(state), bindingOf(state));\n }),\n );\n const browseOptions = {\n ensureSession: host.service(runGuardToken),\n ensureWorkspaceAccess: host.service(workspaceGuardToken),\n execute: runtime.sandbox.execute.bind(runtime.sandbox),\n documentsFor: documentsRoot,\n locationOf: (runId: string, location: string) => workspaceLocation(bindingOf(runState(runId)), location),\n };\n host.methods(...createBrowseMethods(browseOptions), ...clientMethods(clients));\n host.channels(createBrowseChannel(browseOptions));\n host.startOptions(workspaceBindingOption(clients, contribution));\n host.sessionMetadata({ id: WORKSPACE_METADATA_ID, describe: ({ runId }) => sessionMetadataOf(runState(runId), contribution()) });\n host.lifecycle({\n id: \"ragents.workspace.lifecycle\",\n initialize: () => processSandbox ? processSandbox.start() : warnWithoutSandbox(),\n stopSession: ({ runId }) => runtime.stopSession(runId),\n deleteSession: ({ runId }) => runtime.deleteSession(runId),\n shutdown: async () => {\n await runtime.shutdown();\n await processSandbox?.stop();\n },\n });\n },\n});\n\nexport const plugin: PluginModule = {\n create: (host) => ragentsWorkspacePlugin(() => host.skills.global()),\n};\n", "import type { PromptContribution } from \"@ragents/engine\";\nimport { shellPlatformText } from \"@ragents/workspace-executor\";\nimport { boundToTools } from \"@ragents/host/plugin-support/prompt.js\";\n\nexport const shellPlatformChapter = (platform: NodeJS.Platform): string =>\n `## Shell platform\\n\\n${shellPlatformText(platform)}`;\n\n/** Ohne Angabe gilt die Plattform des Servers; `chapterFor` nennt die des Executors, der den Run ausf\u00FChrt. */\nexport const shellPlatformPrompt = (\n id: string,\n order: number,\n chapterFor?: (runId: string) => string,\n): PromptContribution => boundToTools({\n id,\n order,\n delivery: \"initial\",\n render: () => shellPlatformChapter(process.platform),\n ...(chapterFor ? { renderForRun: chapterFor } : {}),\n}, \"bash\");\n", "import type { WorkspaceToolNaming } from \"@ragents/engine\";\n\nconst workspaceToolTable = {\n manual: { read: [], write: [], execute: [] },\n script: { read: [], write: [], execute: [] },\n agent: { read: [\"read\"], write: [\"edit\", \"write\"], execute: [\"bash\"] },\n} as const;\n\nexport const sandboxToolNaming: WorkspaceToolNaming = {\n agentToolNames: (driver) => workspaceToolTable[driver],\n};\n\nexport const agentWorkspaceToolNames: readonly string[] = [\n ...workspaceToolTable.agent.read,\n ...workspaceToolTable.agent.write,\n ...workspaceToolTable.agent.execute,\n];\n", "import { Type } from \"typebox\";\nimport { openJson } from \"@ragents/engine/src/http/contracts\";\nimport { defineChannel, defineOperation } from \"@ragents/engine/src/rpc/contract\";\n\nexport const WORKSPACE_PLUGIN_ID = \"ragents.workspace\";\n\nexport const BROWSE_ROOTS = [\"workspace\", \"files\"] as const;\nexport type BrowseRoot = typeof BROWSE_ROOTS[number];\n\nexport interface BrowseEntry {\n name: string;\n kind: \"directory\" | \"file\";\n size: number;\n modifiedAt: string;\n}\n\nexport interface BrowseListing {\n root: BrowseRoot;\n /** Wo die Wurzel liegt; bei einem Arbeitsplatz mit dessen Label. */\n location: string;\n path: string;\n entries: BrowseEntry[];\n truncated: boolean;\n}\n\nexport type BrowsePreview =\n | { root: BrowseRoot; path: string; size: number; previewable: true; content: string }\n | { root: BrowseRoot; path: string; size: number; previewable: false; reason: string };\n\nexport const WORKSPACE_BINDING_OPTION_ID = \"ragents.workspace.binding\";\n\nexport const WORKSPACE_METADATA_ID = \"ragents.workspace\";\n\n/** Auf welchem Rechner der Arbeitsbereich eines Runs liegt: dem Server oder einem Arbeitsplatz, dessen Label die Bindung festh\u00E4lt. */\nexport type WorkspaceMachine = \"server\" | { client: string; label: string };\n\n/** Ein vorhandener Ordner, den der Run weder anlegt noch l\u00F6scht. */\nexport type ExistingWorkspaceFolder = {\n path: string;\n};\n\n/** Der neue Ordner je Run auf einem Arbeitsplatz; seinen Pfad dort h\u00E4lt die Bindung ab dem W\u00E4hlen fest. */\nexport type FreshWorkstationFolder = {\n path: string;\n fresh: true;\n};\n\n/** Welcher Ordner: ein neuer je Run oder ein vorhandener; `fresh` auf dem Server legt der Host je Run in seiner Ablage an. */\nexport type WorkspaceFolder = \"fresh\" | ExistingWorkspaceFolder | FreshWorkstationFolder;\n\n/** Wo und in welchem Ordner ein Run arbeitet; wird beim Start als Startoption ins Journal eingefroren. */\nexport type WorkspaceBinding = {\n machine: WorkspaceMachine;\n folder: WorkspaceFolder;\n};\n\nexport const freshServerBinding = (): WorkspaceBinding => ({ machine: \"server\", folder: \"fresh\" });\n\nexport const WORKSPACE_CLIENT_ID_PATTERN = /^[A-Za-z0-9_-]{8,64}$/;\n\n/** Was ein Arbeitsplatz bei der Anmeldung \u00FCber sich sagt. */\nexport interface WorkspaceClientDescription {\n label: string;\n hostname: string;\n platform: string;\n folders: string[];\n /** Wo der Arbeitsplatz die neuen Ordner je Run anlegt, je Run ein Unterordner mit dessen Kennung. */\n runsDirectory: string;\n}\n\nexport interface WorkspaceClientInfo extends WorkspaceClientDescription {\n id: string;\n}\n\n/** Wie der neue Ordner je Run auf jedem Rechner hei\u00DFt: der leere Ordner oder der Beitrag eines Plugins; null, wo es keinen gibt. */\nexport interface FreshWorkspaceLabels {\n server: string;\n client: string | null;\n}\n\nexport interface WorkspaceBindingPresentation {\n kind: \"workspace-binding\";\n clients: WorkspaceClientInfo[];\n fresh: FreshWorkspaceLabels;\n /** Ob ein vorhandener Ordner des Serverrechners gebunden werden darf. */\n serverFolders: boolean;\n}\n\nexport interface WorkspaceSessionMetadata {\n binding: WorkspaceBinding;\n summary: string;\n}\n\nconst clientId = Type.String({ pattern: \"^[A-Za-z0-9_-]{8,64}$\", description: \"Stabile Kennung des Arbeitsplatzes\" });\n\nconst executorVersion = Type.String({ minLength: 1, maxLength: 64, description: \"Stand des Executors, den der Arbeitsplatz mitbringt\" });\n\nconst clientDescription = {\n label: Type.String({ minLength: 1, maxLength: 120 }),\n hostname: Type.String({ minLength: 1 }),\n platform: Type.String({ minLength: 1 }),\n folders: Type.Array(Type.String({ minLength: 1 }), { maxItems: 32 }),\n runsDirectory: Type.String({ minLength: 1, description: \"Absoluter Ordner, unter dem der Arbeitsplatz die neuen Ordner je Run anlegt\" }),\n};\n\nexport const clientInfoSchema = Type.Object({\n id: Type.String(),\n ...clientDescription,\n}, { additionalProperties: false });\n\nconst absolutePath = Type.String({ minLength: 1, description: \"Absoluter Pfad im gebundenen Ordner\" });\n\n/** Keine Operation eines Moduls: gibt frei, was der Executor des Arbeitsplatzes f\u00FCr den Run h\u00E4lt. */\nexport const WORKSPACE_CLIENT_STOP_OPERATION = \"stop\";\n\n/** Die eine Operation, die der Server auf dem Arbeitsplatz ruft; Fortschritt ist der JSON-Wert der Operation, bei Bash { text }. */\nexport const workspaceClientContracts = {\n execute: defineOperation({\n id: \"ragents.workspace.client.execute\",\n description: \"Eine Operation des Executors auf dem Arbeitsplatz ausf\u00FChren, etwa ein Werkzeug, eine Dateiabfrage oder die Prozessanzeige; das Ergebnis ist ihr Wert, Fortschritt ihr JSON-Wert. stop gibt frei, was der Arbeitsplatz f\u00FCr den Run h\u00E4lt.\",\n implementedBy: \"client\",\n input: Type.Object({\n runId: Type.String({ minLength: 1, maxLength: 64, description: \"Kennung des Runs\" }),\n operation: Type.String({ minLength: 1, maxLength: 64, description: \"Name der Operation, etwa read, bash, roslyn_open, files.list oder stop\" }),\n toolCallId: Type.Optional(Type.String({ minLength: 1, maxLength: 200, description: \"Nur bei einem Werkzeugaufruf des Modells\" })),\n cwd: absolutePath,\n env: Type.Record(Type.String(), Type.String(), { description: \"Was der Server beitr\u00E4gt: Run-Marker und Git-Regeln der Sandbox\" }),\n input: Type.Unknown({ description: \"Die Eingabe der Operation\" }),\n }, { additionalProperties: false }),\n result: Type.Object({ value: Type.Unknown() }, { additionalProperties: false }),\n }),\n} as const;\n\nconst browseTarget = {\n runId: Type.String({ minLength: 1, maxLength: 64, description: \"Kennung des Runs\" }),\n root: Type.Union([Type.Literal(\"workspace\"), Type.Literal(\"files\")]),\n path: Type.String({ description: \"Pfad unterhalb der Wurzel; leer ist die Wurzel selbst\" }),\n};\n\n/** Die Anmeldung eines Arbeitsplatzes bindet die aufrufende Verbindung; \u00FCber sie ruft der Server zur\u00FCck. */\nexport const workspaceContracts = {\n browse: {\n list: defineOperation({\n id: \"ragents.workspace.browse.list\",\n description: \"Ein Verzeichnis im Arbeitsverzeichnis oder in der Dateiablage eines Runs auflisten.\",\n rights: [\"runs.read\", \"runs.inspect\"],\n input: Type.Object(browseTarget, { additionalProperties: false }),\n result: openJson<BrowseListing>(\"BrowseListing\"),\n }),\n preview: defineOperation({\n id: \"ragents.workspace.browse.preview\",\n description: \"Eine Datei als Text vorschauen; zu gro\u00DFe und bin\u00E4re Dateien nennen stattdessen den Grund.\",\n rights: [\"runs.read\", \"runs.inspect\"],\n input: Type.Object(browseTarget, { additionalProperties: false }),\n result: openJson<BrowsePreview>(\"BrowsePreview\"),\n }),\n },\n channels: {\n browse: defineChannel({\n id: \"ragents.workspace.browse\",\n description: \"Meldet jede \u00C4nderung unterhalb der beobachteten Wurzel eines Runs.\",\n rights: [\"runs.read\", \"runs.inspect\"],\n params: Type.Object({ runId: browseTarget.runId, root: browseTarget.root }, { additionalProperties: false }),\n message: Type.Object({ changed: Type.Literal(true) }, { additionalProperties: false }),\n }),\n },\n clients: {\n list: defineOperation({\n id: \"ragents.workspace.clients.list\",\n description: \"Die angemeldeten Arbeitspl\u00E4tze des Aufrufers; fremde erscheinen auch mit runs.read.all nicht.\",\n rights: [\"runs.read\"],\n input: Type.Object({}, { additionalProperties: false }),\n result: Type.Array(clientInfoSchema),\n }),\n register: defineOperation({\n id: \"ragents.workspace.clients.register\",\n description: \"Einen Arbeitsplatz anmelden oder seine Ordner erneuern; die Verbindung dieser Anfrage wird sein R\u00FCckweg und braucht einen Ereignisstrom.\",\n rights: [\"runs.write\"],\n input: Type.Object({ id: clientId, ...clientDescription, executor: executorVersion }, { additionalProperties: false }),\n result: clientInfoSchema,\n }),\n unregister: defineOperation({\n id: \"ragents.workspace.clients.unregister\",\n description: \"Einen eigenen Arbeitsplatz abmelden; offene Auftr\u00E4ge scheitern.\",\n rights: [\"runs.write\"],\n input: Type.Object({ id: clientId }, { additionalProperties: false }),\n result: Type.Null(),\n }),\n },\n} as const;\n\nconst isRecord = (value: unknown): value is Record<string, unknown> => typeof value === \"object\" && value !== null;\n\nconst hasExactly = (value: Record<string, unknown>, keys: readonly string[]): boolean =>\n Object.keys(value).length === keys.length && keys.every((key) => Object.hasOwn(value, key));\n\nconst isMachine = (value: unknown): value is WorkspaceMachine =>\n value === \"server\" || (isRecord(value) && hasExactly(value, [\"client\", \"label\"])\n && typeof value.client === \"string\" && WORKSPACE_CLIENT_ID_PATTERN.test(value.client) && typeof value.label === \"string\");\n\nconst isFolder = (value: unknown): value is WorkspaceFolder => {\n if (value === \"fresh\") return true;\n if (!isRecord(value) || typeof value.path !== \"string\" || value.path.length === 0) return false;\n return hasExactly(value, [\"path\"]) || (hasExactly(value, [\"path\", \"fresh\"]) && value.fresh === true);\n};\n\n/** Einen neuen Ordner mit Pfad gibt es nur auf einem Arbeitsplatz; auf dem Server legt ihn der Host selbst an. */\nexport const isWorkspaceBinding = (value: unknown): value is WorkspaceBinding =>\n isRecord(value) && hasExactly(value, [\"machine\", \"folder\"]) && isMachine(value.machine) && isFolder(value.folder)\n && !(value.machine === \"server\" && typeof value.folder === \"object\" && \"fresh\" in value.folder);\n\nexport const isFreshFolder = (folder: WorkspaceFolder): folder is \"fresh\" | FreshWorkstationFolder =>\n folder === \"fresh\" || \"fresh\" in folder;\n\n/** Die Form vor der Trennung von Rechner und Ordner, `{ kind: \"fresh\" | \"path\" | \"client\" }`, eindeutig in der heutigen. */\nconst fromKind = (value: Record<string, unknown>): unknown => {\n switch (value.kind) {\n case \"fresh\": return hasExactly(value, [\"kind\"]) ? freshServerBinding() : undefined;\n case \"path\": return hasExactly(value, [\"kind\", \"path\"]) ? { machine: \"server\", folder: { path: value.path } } : undefined;\n case \"client\": return hasExactly(value, [\"kind\", \"client\", \"label\", \"path\"])\n ? { machine: { client: value.client, label: value.label }, folder: { path: value.path } }\n : undefined;\n default: return undefined;\n }\n};\n\n/** Die gespeicherte Bindung; \u00E4ltere, unver\u00E4nderliche Journale tragen die Form mit `kind`, und nur hier wird sie abgebildet. */\nexport const storedWorkspaceBinding = (value: unknown): WorkspaceBinding | undefined => {\n if (isWorkspaceBinding(value)) return value;\n const mapped = isRecord(value) && Object.hasOwn(value, \"kind\") ? fromKind(value) : undefined;\n return isWorkspaceBinding(mapped) ? mapped : undefined;\n};\n\nexport const FRESH_WORKSPACE_LABEL = \"Leerer Ordner je Run\";\n\n/** Wie der neue Ordner je Run auf dem Rechner der Bindung hei\u00DFt; ohne Beitrag dort der leere Ordner. */\nconst freshLabelOf = (binding: WorkspaceBinding, labels: FreshWorkspaceLabels): string =>\n (binding.machine === \"server\" ? labels.server : labels.client) ?? FRESH_WORKSPACE_LABEL;\n\nexport const workspaceBindingSummary = (binding: WorkspaceBinding, labels: FreshWorkspaceLabels): string => {\n const { machine, folder } = binding;\n const fresh = freshLabelOf(binding, labels);\n const where = folder === \"fresh\" ? fresh : \"fresh\" in folder ? `${folder.path} (${fresh})` : folder.path;\n return machine === \"server\" ? where : `${machine.label}: ${where}`;\n};\n", "import { statSync } from \"node:fs\";\nimport path from \"node:path\";\nimport { Type } from \"typebox\";\nimport { DomainError, type JsonValue, type RunState, type StartOptionContribution } from \"@ragents/engine\";\nimport { shellPlatformChapter } from \"./shell-platform.js\";\nimport { storedStartOption } from \"@ragents/host/ragents/start-option-state.js\";\nimport type { WorkspaceResolver } from \"@ragents/host/ragents/workspace-runtime.js\";\nimport {\n freshServerBinding,\n FRESH_WORKSPACE_LABEL,\n isFreshFolder,\n isWorkspaceBinding,\n storedWorkspaceBinding,\n WORKSPACE_BINDING_OPTION_ID,\n workspaceBindingSummary,\n type ExistingWorkspaceFolder,\n type FreshWorkspaceLabels,\n type FreshWorkstationFolder,\n type WorkspaceBinding,\n type WorkspaceBindingPresentation,\n type WorkspaceClientInfo,\n type WorkspaceSessionMetadata,\n} from \"../contract.js\";\nimport type { WorkspaceClientRegistry } from \"./clients.js\";\n\nconst machineSchema = Type.Union([\n Type.Literal(\"server\"),\n Type.Object({ client: Type.String({ minLength: 8, maxLength: 64 }), label: Type.String() }, { additionalProperties: false }),\n]);\n\nconst folderSchema = Type.Union([\n Type.Literal(\"fresh\"),\n Type.Object({ path: Type.String({ minLength: 1 }), fresh: Type.Optional(Type.Literal(true)) }, { additionalProperties: false }),\n]);\n\nconst bindingSchema = Type.Object({ machine: machineSchema, folder: folderSchema }, { additionalProperties: false });\n\n/** Ein Run auf einem Arbeitsplatz mit dessen Kennung, Label und dem Ordner dort; `fresh` tr\u00E4gt dann schon seinen Pfad. */\nexport type WorkstationBinding = {\n machine: { client: string; label: string };\n folder: ExistingWorkspaceFolder | FreshWorkstationFolder;\n};\n\nconst insideFolder = (folder: string, candidate: string): boolean => {\n const separator = folder.includes(\"\\\\\") ? \"\\\\\" : \"/\";\n const root = folder.endsWith(separator) ? folder.slice(0, -separator.length) : folder;\n return candidate === root || candidate.startsWith(root + separator);\n};\n\n/** Der Ordner eines Runs unter dem Ordner, in dem ein Arbeitsplatz die neuen Ordner je Run anlegt; mit dessen Trennzeichen. */\nexport const workstationRunFolder = (runsDirectory: string, runId: string): string => {\n const separator = runsDirectory.includes(\"\\\\\") ? \"\\\\\" : \"/\";\n const root = runsDirectory.endsWith(separator) ? runsDirectory.slice(0, -separator.length) : runsDirectory;\n return `${root}${separator}${runId}`;\n};\n\n/** Die Bindung eines Runs; ohne gespeicherte Wahl der neue Ordner auf dem Server, eine unlesbare sperrt den Run mit Ursache. */\nexport const bindingOf = (state: RunState | null): WorkspaceBinding => {\n const stored = storedStartOption(state, WORKSPACE_BINDING_OPTION_ID);\n if (stored === undefined) return freshServerBinding();\n const binding = storedWorkspaceBinding(stored);\n if (!binding || (binding.machine !== \"server\" && binding.folder === \"fresh\")) {\n throw new Error(`Die gespeicherte Arbeitsbereich-Bindung ist ung\u00FCltig: ${JSON.stringify(stored)}`);\n }\n return binding;\n};\n\nexport const isWorkstationBinding = (binding: WorkspaceBinding): binding is WorkstationBinding =>\n binding.machine !== \"server\" && binding.folder !== \"fresh\";\n\n/** Ein Run benutzt nur Arbeitspl\u00E4tze seines Eigent\u00FCmers, ein Run ohne Eigent\u00FCmer nur ohne Benutzer angemeldete. */\nexport const workspaceOwnerOf = (state: RunState | null): string | null => state?.ownerUserId ?? null;\n\n/** Der vorhandene Ordner auf dem Serverrechner, an den der Run gebunden ist; ein neuer Ordner und ein Arbeitsplatz liegen nicht dort. */\nexport const boundServerDirectory = (state: RunState | null): string | null => {\n const { machine, folder } = bindingOf(state);\n return machine === \"server\" && folder !== \"fresh\" ? folder.path : null;\n};\n\n/** Ein vorhandener Ordner dieses Servers; dieselbe Pr\u00FCfung wie beim W\u00E4hlen der Startoption. */\nexport const serverDirectoryFolder = (directory: string): ExistingWorkspaceFolder => {\n if (!path.isAbsolute(directory)) throw new DomainError(\"workspace-path-relative\", \"Der Ordner muss ein absoluter Pfad sein.\", 400);\n const resolved = path.resolve(directory);\n if (!statSync(resolved, { throwIfNoEntry: false })?.isDirectory()) {\n throw new DomainError(\"workspace-path-missing\", `Der Ordner ${resolved} existiert auf dem Server nicht.`, 400);\n }\n return { path: resolved };\n};\n\n/** Die Bash eines Runs l\u00E4uft auf dem Executor seiner Bindung; der Prompt nennt deshalb dessen Plattform, nicht die des Servers. */\nexport const executorShellChapter = (registry: WorkspaceClientRegistry, owner: string | null, binding: WorkspaceBinding): string => {\n const { machine } = binding;\n if (machine === \"server\") return shellPlatformChapter(process.platform);\n const client = registry.info(owner, machine.client);\n return client\n ? shellPlatformChapter(client.platform as NodeJS.Platform)\n : `## Shell platform\\n\\nThe workstation ${machine.label} that holds this project is not registered right now, `\n + \"so the platform of its shell is unknown; the workspace tools fail until it connects again.\";\n};\n\n/** Wo die Wurzel eines Runs liegt, in Worten: bei einem Arbeitsplatz mit dessen Label, sonst der Pfad selbst. */\nexport const workspaceLocation = (binding: WorkspaceBinding, location: string): string =>\n binding.machine === \"server\" ? location : `Arbeitsplatz ${binding.machine.label}: ${location}`;\n\n/** Den neuen Ordner je Run stellt der Beitrag, sobald es einen gibt; auf einem Arbeitsplatz nur, wenn er es dort ausdr\u00FCcklich kann. */\nexport const freshLabels = (contribution: WorkspaceResolver | undefined): FreshWorkspaceLabels => ({\n server: contribution?.kind?.label ?? FRESH_WORKSPACE_LABEL,\n client: contribution ? contribution.workstation?.label ?? null : FRESH_WORKSPACE_LABEL,\n});\n\nexport const sessionMetadataOf = (state: RunState | null, contribution: WorkspaceResolver | undefined): WorkspaceSessionMetadata => {\n const binding = bindingOf(state);\n return { binding, summary: workspaceBindingSummary(binding, freshLabels(contribution)) };\n};\n\nconst unsupported = (message: string): DomainError => new DomainError(\"workspace-binding-unsupported\", message, 400);\n\n/** Ein Arbeitsplatz des Handelnden, der den Ordner anbietet; ein neuer Ordner je Run bekommt dort seinen Pfad unter dessen Ordner f\u00FCr Runs. */\nconst workstationBinding = (\n client: WorkspaceClientInfo,\n folder: WorkspaceBinding[\"folder\"],\n runId: string,\n labels: FreshWorkspaceLabels,\n): WorkstationBinding => {\n const machine = { client: client.id, label: client.label };\n if (isFreshFolder(folder)) {\n if (labels.client === null) {\n throw unsupported(`Einen neuen Ordner je Run gibt es hier nur auf dem Server (${labels.server}); w\u00E4hle dort einen oder einen vorhandenen Ordner des Arbeitsplatzes.`);\n }\n return { machine, folder: { path: workstationRunFolder(client.runsDirectory, runId), fresh: true } };\n }\n if (!client.folders.some((offered) => insideFolder(offered, folder.path))) {\n throw new DomainError(\"workspace-client-folder\", `Der Arbeitsplatz ${client.label} bietet den Ordner ${folder.path} nicht an.`, 400);\n }\n return { machine, folder: { path: folder.path } };\n};\n\nexport const workspaceBindingOption = (\n registry: WorkspaceClientRegistry,\n contribution: () => WorkspaceResolver | undefined,\n): StartOptionContribution => ({\n id: WORKSPACE_BINDING_OPTION_ID,\n schema: bindingSchema,\n selectable: () => true,\n defaultValue: () => freshServerBinding(),\n accept: (value, { runId, userId }) => {\n if (!isWorkspaceBinding(value)) throw new DomainError(\"workspace-binding-invalid\", \"Die Arbeitsbereich-Bindung hat kein g\u00FCltiges Format.\", 400);\n const labels = freshLabels(contribution());\n const { machine, folder } = value;\n if (machine === \"server\") {\n if (folder === \"fresh\") return freshServerBinding();\n if (\"fresh\" in folder) throw new DomainError(\"workspace-binding-invalid\", \"Einen neuen Ordner je Run legt auf dem Server der Host an; er hat keinen gew\u00E4hlten Pfad.\", 400);\n if (!(contribution()?.kind?.serverFolders ?? true)) {\n throw unsupported(`Ein vorhandener Ordner auf dem Serverrechner ist hier keine Bindung; w\u00E4hle ${labels.server} oder einen Arbeitsplatz.`);\n }\n return { machine, folder: serverDirectoryFolder(folder.path) };\n }\n const client = registry.info(userId, machine.client);\n if (!client) throw new DomainError(\"workspace-client-disconnected\", `Der Arbeitsplatz ${machine.label || machine.client} ist nicht verbunden.`, 409);\n return workstationBinding(client, folder, runId, labels);\n },\n describe: (_value, { userId }) => {\n const presentation: WorkspaceBindingPresentation = {\n kind: \"workspace-binding\",\n clients: registry.list(userId),\n fresh: freshLabels(contribution()),\n serverFolders: contribution()?.kind?.serverFolders ?? true,\n };\n return presentation as unknown as JsonValue;\n },\n ownerOnly: (value) => {\n const binding = storedWorkspaceBinding(value);\n return binding !== undefined && binding.machine !== \"server\";\n },\n});\n", "import {\n implement,\n implementChannel,\n type AccessContext,\n type ChannelContribution,\n type MethodContribution,\n} from \"@ragents/engine\";\nimport {\n FILE_OPERATIONS,\n listDirectory,\n readTextFile,\n watchDirectory,\n type FileListing,\n type FileText,\n type FileWatchProgress,\n} from \"@ragents/workspace-executor\";\nimport { withDomainCause, type SandboxServices } from \"@ragents/host/plugin-support/workspace-sandbox-host.js\";\nimport {\n workspaceContracts,\n type BrowseListing,\n type BrowsePreview,\n type BrowseRoot,\n} from \"../contract.js\";\n\nexport interface BrowseOptions {\n ensureSession: (runId: string) => void;\n /** Der Arbeitsbereich eines Runs, den nur sein Eigent\u00FCmer bedient, liegt bei ihm; die Dateiablage des Servers nicht. */\n ensureWorkspaceAccess: (access: AccessContext, runId: string) => void;\n /** Der Arbeitsbereich ist nur \u00FCber den Executor des Runs erreichbar, wo immer er liegt. */\n execute: SandboxServices[\"execute\"];\n /** Die Dateiablage liegt auf dem Server und geh\u00F6rt nicht zum Arbeitsbereich. */\n documentsFor: (runId: string) => Promise<string>;\n /** Wie die Wurzel eines Runs hei\u00DFt, etwa mit dem Label seines Arbeitsplatzes. */\n locationOf: (runId: string, location: string) => string;\n}\n\nconst onServer = async <T>(operation: () => Promise<T>): Promise<T> => {\n try {\n return await operation();\n } catch (error) {\n throw withDomainCause(error);\n }\n};\n\nconst listingOf = async (options: BrowseOptions, runId: string, root: BrowseRoot, target: string): Promise<BrowseListing> => {\n if (root === \"files\") {\n const listing = await onServer(async () => listDirectory(await options.documentsFor(runId), target));\n return { root, ...listing };\n }\n const listing = await options.execute(runId, FILE_OPERATIONS.list, { path: target }) as FileListing;\n return { root, ...listing, location: options.locationOf(runId, listing.location) };\n};\n\nconst previewOf = async (options: BrowseOptions, runId: string, root: BrowseRoot, target: string): Promise<BrowsePreview> => {\n const text = root === \"files\"\n ? await onServer(async () => readTextFile(await options.documentsFor(runId), target))\n : await options.execute(runId, FILE_OPERATIONS.read, { path: target }) as FileText;\n return { root, ...text };\n};\n\nconst ensureRoot = (options: BrowseOptions, access: AccessContext, runId: string, root: BrowseRoot): void => {\n if (root === \"workspace\") options.ensureWorkspaceAccess(access, runId);\n else options.ensureSession(runId);\n};\n\nexport const createBrowseMethods = (options: BrowseOptions): MethodContribution[] => [\n implement(workspaceContracts.browse.list, ({ runId, root, path: target }, { access }) => {\n ensureRoot(options, access, runId, root);\n return listingOf(options, runId, root, target);\n }),\n implement(workspaceContracts.browse.preview, ({ runId, root, path: target }, { access }) => {\n ensureRoot(options, access, runId, root);\n return previewOf(options, runId, root, target);\n }),\n];\n\n/** Nach dem Ende einer laufenden Beobachtung, etwa weil der Arbeitsplatz weg war, versucht der Kanal es in diesem Abstand erneut. */\nconst WATCH_RETRY_MS = 5_000;\n\n/** Beobachtet den Arbeitsbereich beim Executor des Runs bis zum Abbruch; steht die Beobachtung, ist der Kanal offen, und endet sie, beginnt er eine neue. */\nconst watchWorkspace = (options: BrowseOptions, runId: string, changed: () => void): Promise<() => void> =>\n new Promise((ready, failed) => {\n const controller = new AbortController();\n let opened = false;\n let retry: NodeJS.Timeout | undefined;\n const stop = (): void => {\n controller.abort();\n clearTimeout(retry);\n };\n const start = (): void => {\n let watching = false;\n const ended = (error?: unknown): void => {\n if (controller.signal.aborted) return;\n if (!opened) {\n failed(error ?? new Error(\"Die Beobachtung des Arbeitsbereichs endete, bevor sie stand\"));\n return;\n }\n // Endet eine laufende Beobachtung, l\u00E4dt die Ansicht neu und zeigt die Ursache; steht die n\u00E4chste, l\u00E4dt sie noch einmal.\n if (watching) changed();\n retry = setTimeout(start, WATCH_RETRY_MS);\n };\n options.execute(runId, FILE_OPERATIONS.watch, {}, {\n signal: controller.signal,\n untilAborted: true,\n onProgress: (value) => {\n if ((value as FileWatchProgress).kind === \"changed\") changed();\n else if (!watching) {\n watching = true;\n if (opened) changed();\n else {\n opened = true;\n ready(stop);\n }\n }\n },\n }).then(() => ended(), ended);\n };\n start();\n });\n\nexport const createBrowseChannel = (options: BrowseOptions): ChannelContribution =>\n implementChannel(workspaceContracts.channels.browse, async ({ runId, root }, emit, { access }) => {\n ensureRoot(options, access, runId, root);\n const changed = (): void => emit({ changed: true });\n if (root === \"workspace\") return watchWorkspace(options, runId, changed);\n return onServer(async () => watchDirectory(await options.documentsFor(runId), { onChange: changed, onError: changed }));\n });\n", "import {\n DomainError,\n RPC_ERROR_CODES,\n RpcError,\n implement,\n type AccessContext,\n type MethodConnection,\n type MethodContribution,\n} from \"@ragents/engine\";\nimport {\n WORKSPACE_EXECUTOR_VERSION,\n sandboxRunEnvironment,\n type WorkspaceExecuteOptions,\n type WorkspaceExecutor,\n} from \"@ragents/workspace-executor\";\nimport {\n WORKSPACE_CLIENT_STOP_OPERATION,\n workspaceClientContracts,\n workspaceContracts,\n type WorkspaceClientDescription,\n type WorkspaceClientInfo,\n} from \"../contract.js\";\n\ninterface ClientEntry {\n readonly info: WorkspaceClientInfo;\n readonly owner: string | null;\n readonly connection: MethodConnection;\n readonly release: () => void;\n /** Die offenen Aufrufe \u00FCber diese Anmeldung; l\u00F6st eine neue Verbindung sie ab, scheitern sie sofort. */\n readonly calls: Set<AbortController>;\n /** Die Stopps, die gerade \u00FCber diese Anmeldung zugestellt werden, je Run. */\n readonly stops: Map<string, Promise<void>>;\n}\n\n/** Die einzige Grenze gegen einen h\u00E4ngenden Arbeitsplatz; seine eigenen Zeitgrenzen hat der Executor. */\nconst CLIENT_TIMEOUT_MS = 15 * 60 * 1000;\n\n/** So lange wartet Aufr\u00E4umen (Stopp, `whenReachable`) auf den Arbeitsplatz; es bleibt unter der Stoppgrenze der Plugins. */\nconst CLEANUP_TIMEOUT_MS = 10_000;\n\n/** Nach so langer Zeit versucht der Server einen ausstehenden Stopp erneut, solange der Arbeitsplatz angemeldet ist. */\nconst STOP_RETRY_MS = 30_000;\n\nexport const ownerOf = (access: AccessContext): string | null => access.user?.id ?? null;\n\n/** Eine Beobachtung l\u00E4uft bis zum Abbruch, Aufr\u00E4umen kurz; alles andere wartet die Sicherheitsgrenze plus der Dauer, die der Aufruf selbst verlangt. */\nconst timeoutFor = (options: WorkspaceExecuteOptions): { timeoutMs?: number } => {\n if (options.untilAborted) return {};\n if (options.whenReachable) return { timeoutMs: CLEANUP_TIMEOUT_MS };\n return { timeoutMs: CLIENT_TIMEOUT_MS + (options.durationMs ?? 0) };\n};\n\nconst disconnected = (label: string, detail: string): DomainError =>\n new DomainError(\"workspace-client-disconnected\", `Der Arbeitsplatz ${label} hat die Verbindung verloren: ${detail}`, 409);\n\n/** Bricht die Verbindung mitten im Aufruf, muss die Ursache den Arbeitsplatz nennen, nicht den Server; ein fachlicher Fehler bleibt einer. */\nconst withClientCause = (cause: unknown, label: string): unknown => {\n if (!(cause instanceof RpcError)) return cause;\n if (cause.code === RPC_ERROR_CODES.connectionClosed) return disconnected(label, cause.message);\n if (cause.code === RPC_ERROR_CODES.timeout) {\n return new DomainError(\"workspace-client-timeout\", `Der Arbeitsplatz ${label} hat nicht geantwortet: ${cause.message}`, 504);\n }\n if (cause.code === RPC_ERROR_CODES.application && cause.domainCode !== undefined && cause.status !== undefined) {\n return new DomainError(cause.domainCode, cause.message, cause.status);\n }\n return cause;\n};\n\n/** Der Arbeitsplatz war nicht da oder hat nicht rechtzeitig geantwortet; ein fachlicher Fehler z\u00E4hlt nicht dazu. */\nconst unreached = (cause: unknown): boolean =>\n cause instanceof DomainError && (cause.code === \"workspace-client-disconnected\" || cause.code === \"workspace-client-timeout\");\n\nconst messageOf = (cause: unknown): string => cause instanceof Error ? cause.message : String(cause);\n\n/** Ein Arbeitsplatz ist erst durch Besitzer und Kennung bestimmt; zwei Benutzer mit derselben Kennung teilen nichts. */\nconst keyOf = (owner: string | null, id: string): string => JSON.stringify([owner, id]);\n\n/** \u00DCber das Netz nimmt der Server Arbeitspl\u00E4tze nur von angemeldeten Benutzern an; ohne Benutzer g\u00E4be es nur einen Besitzer f\u00FCr alle Zug\u00E4nge. */\nexport const assertMayRegister = (access: AccessContext, local: boolean): void => {\n if (local || (access.enabled && access.user !== null)) return;\n throw new DomainError(\n \"workspace-client-login-required\",\n \"Dieser Server kennt keine Benutzeranmeldung; einen Arbeitsplatz nimmt er deshalb nur \u00FCber eine Loopback-Verbindung an \"\n + \"(etwa http://127.0.0.1 auf seinem eigenen Rechner). \u00DCber das Netz braucht ein Arbeitsplatz ein Profil mit Benutzern.\",\n 403,\n );\n};\n\n/** Kennt die angemeldeten Arbeitspl\u00E4tze je Besitzer, h\u00E4lt je Client die Verbindung, \u00FCber die der Server ihn zur\u00FCckruft, und die Stopps, die ihn nicht erreicht haben. */\nexport class WorkspaceClientRegistry {\n readonly #clients = new Map<string, ClientEntry>();\n /** Stopps, die den Arbeitsplatz noch nicht erreicht haben, je Arbeitsplatz und Run mit dem Ordner der Bindung. */\n readonly #pendingStops = new Map<string, Map<string, string>>();\n readonly #stopRetries = new Map<string, NodeJS.Timeout>();\n\n async register(\n id: string,\n description: WorkspaceClientDescription,\n executor: string,\n connection: MethodConnection,\n ): Promise<WorkspaceClientInfo> {\n if (connection.streamless) {\n throw new DomainError(\"stream-required\", \"Die Anmeldung eines Arbeitsplatzes braucht einen Ereignisstrom.\", 409);\n }\n if (executor !== WORKSPACE_EXECUTOR_VERSION) {\n throw new DomainError(\n \"workspace-executor-version\",\n `Der Arbeitsplatz ${description.label} bringt den Executor ${executor} mit, der Server verlangt ${WORKSPACE_EXECUTOR_VERSION}.`,\n 409,\n );\n }\n const owner = connection.userId;\n const key = keyOf(owner, id);\n const previous = this.#clients.get(key);\n previous?.release();\n const info: WorkspaceClientInfo = { ...description, id };\n const renewed = previous?.connection === connection;\n const entry: ClientEntry = {\n info,\n owner,\n connection,\n release: connection.onClose(() => this.#disconnected(key, connection)),\n calls: renewed ? previous.calls : new Set(),\n stops: renewed ? previous.stops : new Map(),\n };\n this.#clients.set(key, entry);\n if (previous && !renewed) this.#abandon(previous);\n this.#deliverPendingStops(key);\n return info;\n }\n\n /** Nur die Verbindung, die den Eintrag h\u00E4lt, meldet ihn ab; eine Abmeldung ohne Eintrag ist nach einer Trennung kein Fehler. */\n unregister(owner: string | null, id: string, connection: MethodConnection): void {\n const key = keyOf(owner, id);\n const entry = this.#clients.get(key);\n if (entry?.connection !== connection) return;\n this.#remove(key, entry);\n }\n\n list(owner: string | null): WorkspaceClientInfo[] {\n return [...this.#clients.values()].filter((entry) => entry.owner === owner).map((entry) => entry.info);\n }\n\n info(owner: string | null, id: string): WorkspaceClientInfo | undefined {\n return this.#clients.get(keyOf(owner, id))?.info;\n }\n\n /** Die Runs, deren Stopp diesen Arbeitsplatz noch nicht erreicht hat. */\n pendingStops(owner: string | null, id: string): readonly string[] {\n return this.#pendingRuns(keyOf(owner, id));\n }\n\n /** Der Executor eines gebundenen Runs: dieselbe Schnittstelle wie im Server, nur \u00FCber die Verbindung des Arbeitsplatzes seines Besitzers. */\n executorFor(owner: string | null, id: string, label: string, cwd: string): WorkspaceExecutor {\n const key = keyOf(owner, id);\n const call = async (runId: string, operation: string, input: unknown, options: WorkspaceExecuteOptions): Promise<unknown> => {\n if (options.untilAborted && !options.signal) throw new Error(`Die Operation ${operation} l\u00E4uft bis zum Abbruch und braucht daf\u00FCr ein Abbruchsignal`);\n if (this.#pendingStops.get(key)?.has(runId)) {\n // Aufr\u00E4umen neben einem ausstehenden Stopp erledigt dieser mit; alles andere wartet, bis er zugestellt ist.\n if (options.whenReachable) return null;\n if (this.#clients.has(key)) await this.#deliverStop(key, runId);\n }\n const entry = this.#clients.get(key);\n if (!entry) {\n if (options.whenReachable) return null;\n throw new DomainError(\"workspace-client-disconnected\", `Der Arbeitsplatz ${label} ist nicht verbunden.`, 409);\n }\n try {\n return await this.#send(entry, runId, operation, input, cwd, options);\n } catch (cause) {\n if (options.whenReachable && unreached(cause)) return null;\n throw cause;\n }\n };\n return {\n version: WORKSPACE_EXECUTOR_VERSION,\n execute: (runId, operation, input, options = {}) => call(runId, operation, input, options),\n stopRun: async (runId) => {\n this.#pendingStopsOf(key).set(runId, cwd);\n await this.#deliverStop(key, runId);\n },\n shutdown: async () => undefined,\n };\n }\n\n shutdown(): void {\n for (const entry of this.#clients.values()) {\n entry.release();\n this.#abandon(entry);\n }\n this.#clients.clear();\n for (const timer of this.#stopRetries.values()) clearTimeout(timer);\n this.#stopRetries.clear();\n this.#pendingStops.clear();\n }\n\n /** Ein getrennter Arbeitsplatz verl\u00E4sst die Registry; eine sp\u00E4tere Anmeldung \u00FCber eine neue Verbindung bleibt stehen. */\n #disconnected(key: string, connection: MethodConnection): void {\n const entry = this.#clients.get(key);\n if (entry?.connection !== connection) return;\n this.#remove(key, entry);\n }\n\n #remove(key: string, entry: ClientEntry): void {\n entry.release();\n this.#clients.delete(key);\n this.#abandon(entry);\n }\n\n /** Eine Verbindung, die niemand mehr h\u00E4lt, bekommt keine Antworten mehr zugestellt; ihre offenen Aufrufe scheitern sofort. */\n #abandon(entry: ClientEntry): void {\n for (const controller of entry.calls) controller.abort();\n entry.calls.clear();\n }\n\n async #send(\n entry: ClientEntry,\n runId: string,\n operation: string,\n input: unknown,\n cwd: string,\n options: WorkspaceExecuteOptions,\n ): Promise<unknown> {\n const label = entry.info.label;\n const abandoned = new AbortController();\n entry.calls.add(abandoned);\n const signal = options.signal ? AbortSignal.any([options.signal, abandoned.signal]) : abandoned.signal;\n try {\n const { value } = await Promise.race([\n entry.connection.call(\n workspaceClientContracts.execute,\n {\n runId,\n operation,\n ...(options.toolCallId ? { toolCallId: options.toolCallId } : {}),\n cwd,\n env: sandboxRunEnvironment(runId),\n input,\n },\n {\n signal,\n ...timeoutFor(options),\n ...(options.onProgress ? { onProgress: options.onProgress } : {}),\n },\n ),\n new Promise<never>((_settle, fail) => abandoned.signal.addEventListener(\"abort\", () =>\n fail(disconnected(label, \"eine neue Verbindung hat die Anmeldung abgel\u00F6st\")), { once: true })),\n ]);\n return value;\n } catch (cause) {\n throw withClientCause(cause, label);\n } finally {\n entry.calls.delete(abandoned);\n }\n }\n\n #pendingStopsOf(key: string): Map<string, string> {\n const known = this.#pendingStops.get(key);\n if (known) return known;\n const created = new Map<string, string>();\n this.#pendingStops.set(key, created);\n return created;\n }\n\n /** Stellt einen ausstehenden Stopp zu; erreicht er den Arbeitsplatz nicht, bleibt er ausstehend, und die n\u00E4chste Anmeldung holt ihn nach. */\n #deliverStop(key: string, runId: string): Promise<void> {\n const entry = this.#clients.get(key);\n const cwd = this.#pendingStops.get(key)?.get(runId);\n if (cwd === undefined) return Promise.resolve();\n if (!entry) {\n console.warn(`Der Stopp des Runs ${runId} erreicht seinen Arbeitsplatz erst bei dessen n\u00E4chster Anmeldung.`);\n return Promise.resolve();\n }\n const running = entry.stops.get(runId);\n if (running) return running;\n const delivery = this.#send(entry, runId, WORKSPACE_CLIENT_STOP_OPERATION, null, cwd, { whenReachable: true })\n .then(() => this.#stopDelivered(key, runId, cwd), (cause: unknown) => {\n if (!unreached(cause)) {\n this.#stopDelivered(key, runId, cwd);\n throw cause;\n }\n console.warn(`Der Stopp des Runs ${runId} hat den Arbeitsplatz ${entry.info.label} nicht erreicht und bleibt ausstehend: ${messageOf(cause)}`);\n this.#retryStops(key);\n })\n .finally(() => entry.stops.delete(runId));\n entry.stops.set(runId, delivery);\n return delivery;\n }\n\n #stopDelivered(key: string, runId: string, cwd: string): void {\n const pending = this.#pendingStops.get(key);\n if (pending?.get(runId) === cwd) pending.delete(runId);\n if (pending?.size === 0) this.#pendingStops.delete(key);\n }\n\n #deliverPendingStops(key: string): void {\n for (const runId of this.#pendingRuns(key)) {\n void this.#deliverStop(key, runId).catch((cause: unknown) =>\n console.warn(`Der nachgeholte Stopp des Runs ${runId} ist gescheitert: ${messageOf(cause)}`));\n }\n }\n\n #pendingRuns(key: string): readonly string[] {\n return [...this.#pendingStops.get(key)?.keys() ?? []];\n }\n\n /** Ein Arbeitsplatz, der angemeldet bleibt, aber nicht antwortet, bekommt seine ausstehenden Stopps sp\u00E4ter noch einmal. */\n #retryStops(key: string): void {\n if (this.#stopRetries.has(key)) return;\n const timer = setTimeout(() => {\n this.#stopRetries.delete(key);\n if (this.#clients.has(key)) this.#deliverPendingStops(key);\n }, STOP_RETRY_MS);\n timer.unref();\n this.#stopRetries.set(key, timer);\n }\n}\n\nexport const clientMethods = (registry: WorkspaceClientRegistry): MethodContribution[] => [\n implement(workspaceContracts.clients.list, (_input, { access }) => registry.list(ownerOf(access))),\n implement(workspaceContracts.clients.register, ({ id, executor, ...description }, { access, connection, local }) => {\n assertMayRegister(access, local);\n return registry.register(id, description, executor, connection);\n }),\n implement(workspaceContracts.clients.unregister, ({ id }, { access, connection }) => {\n registry.unregister(ownerOf(access), id, connection);\n return null;\n }),\n];\n", "import { declaredEnvironment } from \"@ragents/host/plugin-support/plugin-config.js\";\nimport { PROCESS_SANDBOX_DEFAULT_NETWORK } from \"@ragents/host/plugin-support/process-sandbox.js\";\n\nexport const workspaceConfigDescriptors = [\n { key: \"PROCESS_SANDBOX\", source: \"environment\" },\n { key: \"PROCESS_SANDBOX_NETWORK\", source: \"environment\" },\n { key: \"RAGENTS_BASH\", source: \"environment\" },\n] as const;\n\nconst env = declaredEnvironment(workspaceConfigDescriptors);\n\nexport interface ProcessSandboxSetting {\n readonly enabled: boolean;\n readonly network: readonly string[];\n}\n\n/** Ohne Angabe ist die Sandbox an; abschalten geht nur ausdr\u00FCcklich mit \"off\". */\nexport const processSandboxSetting = (): ProcessSandboxSetting => {\n const mode = env.optional(\"PROCESS_SANDBOX\") ?? \"on\";\n if (mode !== \"on\" && mode !== \"off\") {\n throw new Error(`PROCESS_SANDBOX in der Sektion ragents.workspace ist \"on\" oder \"off\", nicht \"${mode}\"`);\n }\n const network = env.optional(\"PROCESS_SANDBOX_NETWORK\") === undefined\n ? PROCESS_SANDBOX_DEFAULT_NETWORK\n : env.list(\"PROCESS_SANDBOX_NETWORK\");\n return { enabled: mode === \"on\", network };\n};\n\n/** Die Bash, mit der der Executor dieses Servers das Werkzeug bash startet; unter Windows setzt sie die VS-Code-Erweiterung f\u00FCr ihren lokalen Host. */\nexport const bashSetting = (): string | undefined => env.optional(\"RAGENTS_BASH\") || undefined;\n", "import { mkdir, realpath } from \"node:fs/promises\";\nimport path from \"node:path\";\nimport type { JsonValue, RunState, WorkspaceToolNaming } from \"@ragents/engine\";\nimport { DomainError } from \"@ragents/engine\";\nimport {\n RUN_FOLDER_OPERATIONS,\n type RunFolderCreated,\n type SandboxHomeEnvironment,\n type WorkspaceExecuteOptions,\n type WorkspaceExecutor,\n} from \"@ragents/workspace-executor\";\nimport type {\n SessionWorkspace,\n WorkspaceFolderStep,\n WorkspacePlacement,\n WorkspaceResolver,\n WorkspaceRuntime,\n WorkspaceRuntimeDescription,\n WorkspaceTransfer,\n WorkstationFolderContext,\n} from \"@ragents/host/ragents/workspace-runtime.js\";\nimport { storedStartOption } from \"@ragents/host/ragents/start-option-state.js\";\nimport { sandboxToolNaming } from \"./workspace-tool-naming.js\";\nimport { WorkspaceSandboxHost, type ServerRootDescription } from \"@ragents/host/plugin-support/workspace-sandbox-host.js\";\nimport type { RunProcessSandboxes } from \"@ragents/host/plugin-support/process-sandbox.js\";\nimport { FRESH_WORKSPACE_LABEL, isFreshFolder, type ExistingWorkspaceFolder, type WorkspaceBinding } from \"../contract.js\";\nimport {\n bindingOf,\n boundServerDirectory,\n isWorkstationBinding,\n serverDirectoryFolder,\n workspaceOwnerOf,\n type WorkstationBinding,\n} from \"./binding.js\";\nimport type { WorkspaceClientRegistry } from \"./clients.js\";\n\nexport interface RunWorkspaceRuntimeOptions {\n globalDirectory: string;\n sessionDirectory: (runId: string, ...segments: string[]) => string;\n /** Die Speichergrenze eines Runs; innerhalb davon geh\u00F6ren private Arbeitsdateien seinem Konto. */\n storageRootFor: (runId: string) => string;\n sessionsDirectoryPattern: string;\n sessionWorkspaceFor: (runId: string) => Promise<SessionWorkspace>;\n skillPaths: () => Promise<readonly string[]>;\n resolver: () => WorkspaceResolver | undefined;\n runState: (runId: string) => RunState | null;\n storeBinding: (runId: string, binding: WorkspaceBinding) => void;\n clients: WorkspaceClientRegistry;\n /** Die Prozess-Sandbox des Servers; ohne sie laufen die Prozesse des Servers ohne. */\n processSandbox?: RunProcessSandboxes;\n /** Die Bash des Servers aus RAGENTS_BASH; unter Windows Pflicht f\u00FCr das Werkzeug bash. */\n bash?: string;\n}\n\nconst runNotStarted = (): DomainError => new DomainError(\n \"run-not-started\",\n \"Der Run ist noch nicht gestartet; das Arbeitsverzeichnis entsteht mit der ersten Nachricht.\",\n 409,\n);\n\nconst lookAround = \"Look around in it before you say anything about the project.\";\n\nconst serverProjectDescription = (cwd: string): string => [\n \"# Working directory\",\n \"\",\n `Your working directory is \\`${cwd}\\` on the server: the project folder the user picked.`,\n `It is a real project. Work inside it, keep its structure, and never delete or reorganize files unless you are asked to. ${lookAround}`,\n].join(\"\\n\");\n\nconst clientProjectDescription = (projectPath: string, label: string): string => [\n \"# Working directory\",\n \"\",\n `Your working directory is the project folder \\`${projectPath}\\` on the workstation \"${label}\", not on the server.`,\n \"Every workspace tool runs there, and a relative path refers to that folder.\",\n `It is a real project. Keep its structure, and never delete or reorganize files unless you are asked to. ${lookAround}`,\n].join(\"\\n\");\n\nconst freshWorkstationDescription = (folderPath: string, label: string): string => [\n \"# Working directory\",\n \"\",\n `Your working directory is \\`${folderPath}\\` on the workstation \"${label}\", not on the server: a folder of this run alone.`,\n \"Every workspace tool runs there, and a relative path refers to that folder.\",\n \"It starts empty unless the profile prepared content in it. Look around in it before you say anything about what is already there.\",\n].join(\"\\n\");\n\nconst freshDescription = (cwd: string): string => [\n \"# Working directory\",\n \"\",\n `Your working directory is \\`${cwd}\\`, a private folder of this conversation on the server.`,\n \"No other conversation sees it, and it starts empty unless the profile prepared content in it.\",\n \"Look around in it before you say anything about what is already there.\",\n].join(\"\\n\");\n\nconst listed = (entries: readonly string[]): string =>\n entries.length === 1 ? entries[0]! : `${entries.slice(0, -1).join(\", \")} and ${entries.at(-1)!}`;\n\nconst rootList = (roots: readonly ServerRootDescription[]): string =>\n listed(roots.map((root) => `\\`${root.alias}\\` (${root.writable ? \"read and write\" : \"read only\"})`));\n\nconst variableList = (roots: readonly ServerRootDescription[]): string => listed(roots\n .flatMap((root) => root.environmentVariable === undefined ? [] : [`\\`$${root.environmentVariable}\\` for \\`${root.alias}\\``]));\n\nconst hasVariables = (roots: readonly ServerRootDescription[]): boolean => roots.some((root) => root.environmentVariable !== undefined);\n\n/** Auf dem Server liegen Arbeitsbereich und Wurzeln auf einer Maschine; jede Bash sieht beide. */\nconst serverRootsDescription = (roots: readonly ServerRootDescription[]): string => [\n \"## Roots besides the working directory\",\n \"\",\n `This run also reaches ${rootList(roots)}. File tools and language servers take a path that starts with the alias, `\n + `such as \\`${roots[0]!.alias}/<path>\\`; \\`bash\\` runs in such a root with that path as \\`cwd\\`.`\n + (hasVariables(roots) ? ` \\`bash\\` also has ${variableList(roots)}.` : \"\"),\n].join(\"\\n\");\n\n/** Die Wurzeln liegen auf dem Server, der Arbeitsbereich auf dem Arbeitsplatz; eine Bash sieht immer nur eine der beiden Maschinen. */\nconst workstationRootsDescription = (roots: readonly ServerRootDescription[]): string => [\n \"## Roots on the server\",\n \"\",\n `This run also reaches roots on the server: ${rootList(roots)}. File tools and language servers reach them from the `\n + `workstation as well: pass a path that starts with the alias, such as \\`${roots[0]!.alias}/<path>\\`. \\`bash\\` runs on `\n + \"the workstation; with a `cwd` that starts with an alias it runs on the server instead and sees only the server\"\n + (hasVariables(roots) ? `, and only that bash has ${variableList(roots)}` : \"\")\n + \". One call reaches one machine: never combine a path with an alias and a path in the working directory in one call.\",\n].join(\"\\n\");\n\nexport class RunWorkspaceRuntime implements WorkspaceRuntime {\n readonly sandbox: WorkspaceSandboxHost;\n readonly toolNaming: WorkspaceToolNaming = sandboxToolNaming;\n readonly transfer: WorkspaceTransfer;\n readonly #options: RunWorkspaceRuntimeOptions;\n readonly #nugetCacheDirectory: string;\n /** Die neuen Ordner auf Arbeitspl\u00E4tzen, die in diesem Serverlauf schon angelegt oder in Arbeit sind. */\n readonly #preparations = new Map<string, Promise<void>>();\n\n constructor(options: RunWorkspaceRuntimeOptions) {\n this.#options = options;\n this.transfer = {\n boundDirectory: (runId) => boundServerDirectory(options.runState(runId)),\n assertDirectory: (directory) => void serverDirectoryFolder(directory),\n rebind: (runId, directory) => options.storeBinding(runId, { machine: \"server\", folder: serverDirectoryFolder(directory) }),\n };\n this.#nugetCacheDirectory = path.join(options.globalDirectory, \"nuget-cache\");\n this.sandbox = new WorkspaceSandboxHost({\n contributorName: \"ragents.workspace.sandbox\",\n workspaceFor: options.sessionWorkspaceFor,\n identFor: () => Promise.resolve(undefined),\n skillPaths: options.skillPaths,\n storageRootFor: options.storageRootFor,\n homeFor: (runId) => this.#homeFor(runId),\n executorFor: (runId) => Promise.resolve(this.#executorFor(runId)),\n serverDirectoryFor: (runId) => this.#serverDirectoryFor(runId),\n ...(options.processSandbox ? { processSandbox: options.processSandbox } : {}),\n ...(options.bash === undefined ? {} : { bash: options.bash }),\n });\n }\n\n /** Arbeit eines Runs, die auf dem Server l\u00E4uft, w\u00E4hrend sein Arbeitsbereich auf einem Arbeitsplatz liegt. */\n async #serverDirectoryFor(runId: string): Promise<string> {\n const directory = this.#options.sessionDirectory(runId, \"server\");\n await mkdir(directory, { recursive: true });\n return realpath(directory);\n }\n\n async #homeFor(runId: string): Promise<SandboxHomeEnvironment> {\n const home = this.#options.sessionDirectory(runId, \"home\");\n await mkdir(home, { recursive: true });\n await mkdir(this.#nugetCacheDirectory, { recursive: true });\n return { home, nugetPackages: this.#nugetCacheDirectory };\n }\n\n /** Auf einem Arbeitsplatz f\u00FChrt dessen Executor im Namen des Run-Eigent\u00FCmers aus, sonst der des Servers. */\n #executorFor(runId: string): WorkspaceExecutor | undefined {\n const state = this.#options.runState(runId);\n const binding = bindingOf(state);\n if (!isWorkstationBinding(binding)) return undefined;\n const { machine, folder } = binding;\n const executor = this.#options.clients.executorFor(workspaceOwnerOf(state), machine.client, machine.label, folder.path);\n return \"fresh\" in folder ? this.#preparing(state, binding, executor) : executor;\n }\n\n /** Vor dem ersten Auftrag eines Runs legt der Arbeitsplatz dessen neuen Ordner an; Aufr\u00E4umen legt nie einen an. */\n #preparing(state: RunState | null, binding: WorkstationBinding, executor: WorkspaceExecutor): WorkspaceExecutor {\n return {\n ...executor,\n execute: async (runId, operation, input, options = {}) => {\n if (!options.whenReachable) await this.#prepared(runId, state, binding, executor);\n return executor.execute(runId, operation, input, options);\n },\n };\n }\n\n #prepared(runId: string, state: RunState | null, binding: WorkstationBinding, executor: WorkspaceExecutor): Promise<void> {\n const known = this.#preparations.get(runId);\n if (known) return known;\n const preparation = this.#prepare(runId, state, binding, executor).catch((error: unknown) => {\n this.#preparations.delete(runId);\n throw error;\n });\n this.#preparations.set(runId, preparation);\n return preparation;\n }\n\n /** Nur ein eben angelegter Ordner bekommt die Schritte des Beitrags; scheitert einer, verschwindet er wieder, und der n\u00E4chste Auftrag beginnt neu. */\n async #prepare(runId: string, state: RunState | null, binding: WorkstationBinding, executor: WorkspaceExecutor): Promise<void> {\n const { created } = await executor.execute(runId, RUN_FOLDER_OPERATIONS.create, null) as RunFolderCreated;\n const steps = created ? this.#contribution()?.workstation?.prepare(this.#workstationContext(runId, state, binding)) ?? [] : [];\n try {\n await this.#runSteps(runId, executor, steps);\n } catch (error) {\n await executor.execute(runId, RUN_FOLDER_OPERATIONS.remove, null, { whenReachable: true });\n throw error;\n }\n }\n\n async #runSteps(runId: string, executor: WorkspaceExecutor, steps: readonly WorkspaceFolderStep[], options: WorkspaceExecuteOptions = {}): Promise<void> {\n for (const step of steps) await executor.execute(runId, step.operation, step.input, options);\n }\n\n #workstationContext(runId: string, state: RunState | null, binding: WorkstationBinding): WorkstationFolderContext {\n const contribution = this.#contribution();\n return {\n runId,\n path: binding.folder.path,\n label: binding.machine.label,\n choice: contribution && state ? this.#choiceFor(state, contribution) : null,\n };\n }\n\n async resolve(runId: string, emitSystem: (text: string) => void): Promise<SessionWorkspace> {\n const state = this.#options.runState(runId);\n if (!state) throw runNotStarted();\n const binding = bindingOf(state);\n const { folder } = binding;\n const onWorkstation = isWorkstationBinding(binding);\n const workspace = onWorkstation ? this.#workstation(runId, state, binding, emitSystem)\n : isFreshFolder(folder) ? await this.#fresh(runId, state, emitSystem) : this.#bound(folder, emitSystem);\n return this.#withRoots(workspace, onWorkstation);\n }\n\n /** Was der Prompt \u00FCber Wurzeln sagt, h\u00E4ngt an der Maschine des Runs: nur eine Bash auf dem Server kennt ihre Variablen. */\n async #withRoots(workspace: SessionWorkspace, onWorkstation: boolean): Promise<SessionWorkspace> {\n const roots = await this.sandbox.serverRoots();\n if (roots.length === 0) return workspace;\n const described = onWorkstation ? workstationRootsDescription(roots) : serverRootsDescription(roots);\n return { ...workspace, description: [workspace.description, described].filter(Boolean).join(\"\\n\\n\") };\n }\n\n placementOf(runId: string): WorkspacePlacement {\n const { machine, folder } = bindingOf(this.#options.runState(runId));\n const placement: WorkspacePlacement = {\n machine: machine === \"server\" ? \"server\" : \"client\",\n folder: isFreshFolder(folder) ? \"fresh\" : \"existing\",\n };\n const contribution = this.#contribution();\n const contributed = placement.folder === \"fresh\" && (placement.machine === \"server\" || contribution?.workstation !== undefined);\n const kind = contributed ? contribution?.kind?.id : undefined;\n return kind === undefined ? placement : { ...placement, kind };\n }\n\n async #fresh(runId: string, state: RunState, emitSystem: (text: string) => void): Promise<SessionWorkspace> {\n const resolver = this.#options.resolver();\n const directory = resolver?.kind\n ? this.#options.sessionDirectory(runId, \"workspace\")\n : await this.#sessionWorkspace(runId);\n if (!resolver) return this.#directory(directory, freshDescription(directory));\n const { cwd, description, currentRoot, runOperation, ...rest } = await resolver.resolve({\n runId,\n directory,\n choice: this.#choiceFor(state, resolver),\n emitSystem,\n });\n const resolved = path.resolve(cwd);\n return {\n ...this.#directory(resolved, description ?? freshDescription(resolved)),\n ...rest,\n ...(currentRoot ? { currentRoot } : {}),\n ...(runOperation ? { runOperation } : {}),\n };\n }\n\n #bound(folder: ExistingWorkspaceFolder, emitSystem: (text: string) => void): SessionWorkspace {\n const cwd = path.resolve(folder.path);\n const existing = async (): Promise<string> => {\n try {\n return await realpath(cwd);\n } catch {\n throw new DomainError(\"workspace-path-missing\", `Der gebundene Ordner ${cwd} existiert auf dem Server nicht mehr.`, 409);\n }\n };\n emitSystem(`Arbeitsbereich: ${cwd} (Projektordner auf dem Server)`);\n return {\n cwd,\n description: serverProjectDescription(cwd),\n currentRoot: existing,\n runOperation: (operation) => operation(),\n };\n }\n\n /** Der Arbeitsbereich liegt auf dem Arbeitsplatz; der Server kennt nur seinen Pfad, und jeder lokale Griff darauf scheitert laut. */\n #workstation(runId: string, state: RunState, binding: WorkstationBinding, emitSystem: (text: string) => void): SessionWorkspace {\n const { machine: { label }, folder } = binding;\n const fresh = \"fresh\" in folder;\n const workstation = this.#contribution()?.workstation;\n emitSystem(fresh\n ? `Arbeitsbereich: ${folder.path} (${workstation?.label ?? FRESH_WORKSPACE_LABEL} auf dem Arbeitsplatz ${label})`\n : `Arbeitsbereich: ${folder.path} (Projektordner auf dem Arbeitsplatz ${label})`);\n const remote = (): Promise<string> => Promise.reject(new Error(\n `Der Arbeitsbereich ${folder.path} liegt auf dem Arbeitsplatz ${label}, nicht auf dem Server; `\n + \"er ist nur \u00FCber den Executor des Runs (SandboxServices.execute) erreichbar.\",\n ));\n const description = !fresh\n ? clientProjectDescription(folder.path, label)\n : workstation?.description?.(this.#workstationContext(runId, state, binding)) ?? freshWorkstationDescription(folder.path, label);\n return {\n cwd: folder.path,\n description,\n currentRoot: remote,\n runOperation: (operation) => operation(),\n };\n }\n\n async #sessionWorkspace(runId: string): Promise<string> {\n const directory = this.#options.sessionDirectory(runId, \"workspace\");\n await mkdir(directory, { recursive: true });\n return directory;\n }\n\n #directory(cwd: string, description: string, extraEnv?: NodeJS.ProcessEnv): SessionWorkspace {\n return {\n cwd,\n description,\n ...(extraEnv ? { extraEnv } : {}),\n currentRoot: () => realpath(cwd),\n runOperation: (operation) => operation(),\n };\n }\n\n #choiceFor(state: RunState, resolver: WorkspaceResolver): JsonValue | null {\n if (resolver.optionId === undefined) return null;\n const choice = storedStartOption(state, resolver.optionId);\n if (choice === undefined) {\n throw new Error(`Die Startoption ${resolver.optionId} des Workspace-Resolvers ist im Run nicht gespeichert`);\n }\n return choice;\n }\n\n describe(): WorkspaceRuntimeDescription {\n return {\n mode: \"per-run\",\n directoryPattern: this.#contribution()?.kind?.directoryPattern\n ?? path.join(this.#options.sessionsDirectoryPattern, \"workspace\"),\n };\n }\n\n #contribution(): WorkspaceResolver | undefined {\n return this.#options.resolver();\n }\n\n /** Auf dem Server geh\u00F6rt ein neuer Ordner samt Stopp und L\u00F6schen dem Beitrag; auf einem Arbeitsplatz r\u00E4umt ihn der Host weg. */\n #serverContributionFor(runId: string): WorkspaceResolver | undefined {\n const { machine, folder } = bindingOf(this.#options.runState(runId));\n return machine === \"server\" && isFreshFolder(folder) ? this.#contribution() : undefined;\n }\n\n /** Ist der Arbeitsplatz nicht erreichbar, bleibt der Ordner dort mit Hinweis liegen; der Run ist trotzdem gel\u00F6scht. */\n async #removeWorkstationFolder(runId: string): Promise<void> {\n this.#preparations.delete(runId);\n const state = this.#options.runState(runId);\n const binding = bindingOf(state);\n if (!isWorkstationBinding(binding) || !(\"fresh\" in binding.folder)) return;\n const { machine, folder } = binding;\n const executor = this.#options.clients.executorFor(workspaceOwnerOf(state), machine.client, machine.label, folder.path);\n const steps = this.#contribution()?.workstation?.release?.(this.#workstationContext(runId, state, binding)) ?? [];\n await this.#runSteps(runId, executor, steps, { whenReachable: true });\n if (await executor.execute(runId, RUN_FOLDER_OPERATIONS.remove, null, { whenReachable: true }) !== null) return;\n console.warn(`Der Ordner ${folder.path} des Runs ${runId} bleibt auf dem Arbeitsplatz ${machine.label}, weil er nicht erreichbar war.`);\n }\n\n async deleteSession(runId: string): Promise<void> {\n const contribution = this.#serverContributionFor(runId);\n await this.stopSession(runId);\n await this.#removeWorkstationFolder(runId);\n await contribution?.deleteSession?.(runId);\n }\n\n stopSession(runId: string): Promise<void> {\n const contribution = this.#serverContributionFor(runId);\n const sandbox = (): Promise<void> => this.sandbox.shutdown(runId);\n return contribution?.stopSession ? contribution.stopSession(runId, sandbox) : sandbox();\n }\n\n async shutdown(): Promise<void> {\n await this.sandbox.shutdownAll();\n this.#options.clients.shutdown();\n }\n}\n"],
|
|
5
|
-
"mappings": "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",
|
|
6
|
-
"names": ["path", "DomainError", "boundToTools", "Type", "Type", "listing", "DomainError", "implement", "DomainError", "implement", "path", "DomainError", "storedStartOption", "DomainError", "path", "storedStartOption", "DomainError", "path", "boundToTools"]
|
|
4
|
+
"sourcesContent": ["import path from \"node:path\";\nimport { DomainError, type JsonValue, type RAgentsPlugin, type RunState } from \"@ragents/engine\";\nimport { documentStoreToken } from \"@ragents/host/ragents/document-store.js\";\nimport { workspaceResolverToken, workspaceRuntimeToken, type WorkspaceResolver } from \"@ragents/host/ragents/workspace-runtime.js\";\nimport { sandboxServicesToken } from \"@ragents/host/plugin-support/workspace-sandbox-host.js\";\nimport {\n executorContributionsToken,\n hostAddressToken,\n runtimeProviderToken,\n runGuardToken,\n runWorkspaceProviderToken,\n workspaceGuardToken,\n} from \"@ragents/host/ragents/host-services.js\";\nimport { pluginAsset } from \"@ragents/host/plugin-support/plugin-folder.js\";\nimport { ServerProcessSandbox } from \"@ragents/host/plugin-support/process-sandbox.js\";\nimport { ripgrepAvailable } from \"@ragents/workspace-executor\";\nimport type { PluginModule } from \"@ragents/host/plugin-support/plugin-module.js\";\nimport { boundToTools, handlebarsPrompt } from \"@ragents/host/plugin-support/prompt.js\";\nimport { shellPlatformPrompt } from \"./shell-platform.js\";\nimport { agentWorkspaceToolNames } from \"./workspace-tool-naming.js\";\nimport { startOptionScope } from \"@ragents/host/ragents/start-option-state.js\";\nimport { WORKSPACE_BINDING_OPTION_ID, WORKSPACE_METADATA_ID } from \"../contract.js\";\nimport { bindingOf, executorShellChapter, sessionMetadataOf, workspaceBindingOption, workspaceLocation, workspaceOwnerOf } from \"./binding.js\";\nimport { createBrowseChannel, createBrowseMethods } from \"./browse-route.js\";\nimport { clientMethods, WorkspaceClientRegistry } from \"./clients.js\";\nimport { bashSetting, bashTimeoutSetting, processSandboxSetting, rgSetting, workspaceConfigDescriptors } from \"./config.js\";\nimport { RunWorkspaceRuntime } from \"./runtime.js\";\n\nconst warnWithoutSandbox = (): void => {\n console.warn(\"Prozess-Sandbox ausgeschaltet (PROCESS_SANDBOX: \\\"off\\\" in der Sektion ragents.workspace): Prozesse der Runs laufen auf dem Server ohne Sandbox.\");\n};\n\nconst ragentsWorkspacePlugin = (skillPaths: () => Promise<readonly string[]>): RAgentsPlugin => ({\n manifest: { id: \"ragents.workspace\" },\n register: (host) => {\n const sessionWorkspaceFor = host.service(runWorkspaceProviderToken);\n const orchestration = host.service(runtimeProviderToken);\n const runState = (runId: string): RunState | null => {\n try {\n return orchestration().state(runId);\n } catch (error) {\n if (error instanceof DomainError && error.code === \"run-not-found\") return null;\n throw error;\n }\n };\n const documentsFor = (runId: string): Promise<string | undefined> =>\n host.optionalService(documentStoreToken)?.directoryFor(runId) ?? Promise.resolve(undefined);\n const documentsRoot = async (runId: string): Promise<string> => {\n const directory = await documentsFor(runId);\n if (!directory) throw new Error(\"In diesem Profil gibt es keine Dateiablage; das Plugin ragents.documents fehlt\");\n return directory;\n };\n const contributions = host.service(executorContributionsToken);\n const clients = new WorkspaceClientRegistry(contributions);\n const contribution = (): WorkspaceResolver | undefined => host.optionalService(workspaceResolverToken);\n host.config(...workspaceConfigDescriptors);\n const sandboxSetting = processSandboxSetting();\n const processSandbox = sandboxSetting.enabled\n ? new ServerProcessSandbox({\n network: sandboxSetting.network,\n serverAddress: host.service(hostAddressToken)(),\n dataDirectory: path.dirname(host.storage.sessionsRoot),\n })\n : undefined;\n const bash = bashSetting();\n const rg = rgSetting();\n const bashTimeoutSeconds = bashTimeoutSetting();\n const serverTools = { ripgrep: ripgrepAvailable(rg, process.env) };\n const runtime = new RunWorkspaceRuntime({\n clients,\n contributions: contributions.map((contribution) => contribution.parts),\n ...(processSandbox ? { processSandbox } : {}),\n ...(bash === undefined ? {} : { bash }),\n ...(rg === undefined ? {} : { rg }),\n ...(bashTimeoutSeconds === undefined ? {} : { bashTimeoutSeconds }),\n globalDirectory: host.storage.root(),\n sessionDirectory: (runId, ...segments) => host.storage.session(runId, ...segments),\n storageRootFor: (runId) => path.join(host.storage.sessionsRoot, runId),\n sessionsDirectoryPattern: path.join(host.storage.sessionsRoot, \"{runId}\", \"plugins\", host.manifest.id),\n sessionWorkspaceFor,\n skillPaths,\n resolver: contribution,\n runState,\n storeBinding: (runId, binding) => {\n const state = orchestration().state(runId);\n orchestration().replacePluginState(\n { actorId: state.ownerId, commandId: `workspace-binding:${runId}:${state.revision}` },\n runId,\n { pluginId: WORKSPACE_BINDING_OPTION_ID, scope: startOptionScope, state: binding as unknown as JsonValue },\n );\n },\n });\n host.provide(workspaceRuntimeToken, runtime);\n host.provide(sandboxServicesToken, runtime.sandbox);\n host.functions(runtime.sandbox.workspaceTools());\n const rules = handlebarsPrompt(\"ragents.workspace.prompt\", 100, pluginAsset(\"ragents.workspace\", \"prompt.hbs\"));\n host.prompts(\n boundToTools({\n ...rules,\n delivery: \"initial\",\n // Die Regeln gelten f\u00FCr die Arbeitsbereiche des Hosts; eine beigesteuerte Art beschreibt ihre eigenen.\n render: (context) => contribution()?.kind ? \"\" : rules.render(context),\n }, ...agentWorkspaceToolNames),\n shellPlatformPrompt(\"ragents.workspace.shell.prompt\", 102, serverTools, (runId) => {\n const state = runState(runId);\n return executorShellChapter(clients, workspaceOwnerOf(state), bindingOf(state), serverTools);\n }),\n );\n const browseOptions = {\n ensureSession: host.service(runGuardToken),\n ensureWorkspaceAccess: host.service(workspaceGuardToken),\n execute: runtime.sandbox.execute.bind(runtime.sandbox),\n documentsFor: documentsRoot,\n locationOf: (runId: string, location: string) => workspaceLocation(bindingOf(runState(runId)), location),\n };\n host.methods(...createBrowseMethods(browseOptions), ...clientMethods(clients));\n host.channels(createBrowseChannel(browseOptions));\n host.startOptions(workspaceBindingOption(clients, contribution));\n host.sessionMetadata({ id: WORKSPACE_METADATA_ID, describe: ({ runId }) => sessionMetadataOf(runState(runId), contribution()) });\n host.lifecycle({\n id: \"ragents.workspace.lifecycle\",\n initialize: () => processSandbox ? processSandbox.start() : warnWithoutSandbox(),\n stopSession: ({ runId }) => runtime.stopSession(runId),\n deleteSession: ({ runId }) => runtime.deleteSession(runId),\n shutdown: async () => {\n await runtime.shutdown();\n await processSandbox?.stop();\n },\n });\n },\n});\n\nexport const plugin: PluginModule = {\n create: (host) => ragentsWorkspacePlugin(() => host.skills.global()),\n};\n", "import type { PromptContribution } from \"@ragents/engine\";\nimport { shellPlatformText, type ShellTools } from \"@ragents/workspace-executor\";\nimport { boundToTools } from \"@ragents/host/plugin-support/prompt.js\";\n\nexport const shellPlatformChapter = (platform: NodeJS.Platform, tools: ShellTools): string =>\n `## Shell platform\\n\\n${shellPlatformText(platform, tools)}`;\n\n/** Ohne Angabe gelten Plattform und Werkzeuge des Servers; `chapterFor` nennt die des Executors, der den Run ausf\u00FChrt. */\nexport const shellPlatformPrompt = (\n id: string,\n order: number,\n serverTools: ShellTools,\n chapterFor?: (runId: string) => string,\n): PromptContribution => boundToTools({\n id,\n order,\n delivery: \"initial\",\n render: () => shellPlatformChapter(process.platform, serverTools),\n ...(chapterFor ? { renderForRun: chapterFor } : {}),\n}, \"bash\");\n", "import type { WorkspaceToolNaming } from \"@ragents/engine\";\n\nconst workspaceToolTable = {\n manual: { read: [], write: [], execute: [] },\n script: { read: [], write: [], execute: [] },\n agent: { read: [\"read\"], write: [\"edit\", \"write\"], execute: [\"bash\"] },\n} as const;\n\nexport const sandboxToolNaming: WorkspaceToolNaming = {\n agentToolNames: (driver) => workspaceToolTable[driver],\n};\n\nexport const agentWorkspaceToolNames: readonly string[] = [\n ...workspaceToolTable.agent.read,\n ...workspaceToolTable.agent.write,\n ...workspaceToolTable.agent.execute,\n];\n", "import { Type } from \"typebox\";\nimport { openJson } from \"@ragents/engine/src/http/contracts\";\nimport { defineChannel, defineOperation } from \"@ragents/engine/src/rpc/contract\";\n\nexport const WORKSPACE_PLUGIN_ID = \"ragents.workspace\";\n\nexport const BROWSE_ROOTS = [\"workspace\", \"files\"] as const;\nexport type BrowseRoot = typeof BROWSE_ROOTS[number];\n\nexport interface BrowseEntry {\n name: string;\n kind: \"directory\" | \"file\";\n size: number;\n modifiedAt: string;\n}\n\nexport interface BrowseListing {\n root: BrowseRoot;\n /** Wo die Wurzel liegt; bei einem Arbeitsplatz mit dessen Label. */\n location: string;\n path: string;\n entries: BrowseEntry[];\n truncated: boolean;\n}\n\nexport type BrowsePreview =\n | { root: BrowseRoot; path: string; size: number; previewable: true; content: string }\n | { root: BrowseRoot; path: string; size: number; previewable: false; reason: string };\n\nexport const WORKSPACE_BINDING_OPTION_ID = \"ragents.workspace.binding\";\n\nexport const WORKSPACE_METADATA_ID = \"ragents.workspace\";\n\n/** Auf welchem Rechner der Arbeitsbereich eines Runs liegt: dem Server oder einem Arbeitsplatz, dessen Label die Bindung festh\u00E4lt. */\nexport type WorkspaceMachine = \"server\" | { client: string; label: string };\n\n/** Ein vorhandener Ordner, den der Run weder anlegt noch l\u00F6scht. */\nexport type ExistingWorkspaceFolder = {\n path: string;\n};\n\n/** Der neue Ordner je Run auf einem Arbeitsplatz; seinen Pfad dort h\u00E4lt die Bindung ab dem W\u00E4hlen fest. */\nexport type FreshWorkstationFolder = {\n path: string;\n fresh: true;\n};\n\n/** Welcher Ordner: ein neuer je Run oder ein vorhandener; `fresh` auf dem Server legt der Host je Run in seiner Ablage an. */\nexport type WorkspaceFolder = \"fresh\" | ExistingWorkspaceFolder | FreshWorkstationFolder;\n\n/** Wo und in welchem Ordner ein Run arbeitet; wird beim Start als Startoption ins Journal eingefroren. */\nexport type WorkspaceBinding = {\n machine: WorkspaceMachine;\n folder: WorkspaceFolder;\n};\n\nexport const freshServerBinding = (): WorkspaceBinding => ({ machine: \"server\", folder: \"fresh\" });\n\nexport const WORKSPACE_CLIENT_ID_PATTERN = /^[A-Za-z0-9_-]{8,64}$/;\n\n/** Was ein Arbeitsplatz bei der Anmeldung \u00FCber sich sagt. */\nexport interface WorkspaceClientDescription {\n label: string;\n hostname: string;\n platform: string;\n folders: string[];\n /** Wo der Arbeitsplatz die neuen Ordner je Run anlegt, je Run ein Unterordner mit dessen Kennung. */\n runsDirectory: string;\n /** Ob die Bash des Arbeitsplatzes rg findet; der Prompt richtet die Suche danach. */\n ripgrep: boolean;\n}\n\nexport interface WorkspaceClientInfo extends WorkspaceClientDescription {\n id: string;\n}\n\n/** Wie der neue Ordner je Run auf jedem Rechner hei\u00DFt: der leere Ordner oder der Beitrag eines Plugins; null, wo es keinen gibt. */\nexport interface FreshWorkspaceLabels {\n server: string;\n client: string | null;\n}\n\nexport interface WorkspaceBindingPresentation {\n kind: \"workspace-binding\";\n clients: WorkspaceClientInfo[];\n fresh: FreshWorkspaceLabels;\n /** Ob ein vorhandener Ordner des Serverrechners gebunden werden darf. */\n serverFolders: boolean;\n}\n\nexport interface WorkspaceSessionMetadata {\n binding: WorkspaceBinding;\n summary: string;\n}\n\nconst clientId = Type.String({ pattern: \"^[A-Za-z0-9_-]{8,64}$\", description: \"Stabile Kennung des Arbeitsplatzes\" });\n\nconst executorVersion = Type.String({ minLength: 1, maxLength: 64, description: \"Stand des Executors, den der Arbeitsplatz mitbringt\" });\n\n/** Die Kennung eines Plugins; ein Arbeitsplatz sucht dessen Bundle unter genau diesem Namen, ein Pfad kann darin nicht stecken. */\nexport const PLUGIN_ID_PATTERN = /^[a-z0-9]+(?:[.-][a-z0-9]+)*$/;\n\nconst executorContributions = Type.Array(Type.Object({\n plugin: Type.String({ pattern: PLUGIN_ID_PATTERN.source, maxLength: 128, description: \"Kennung des Plugins\" }),\n stand: Type.String({ pattern: \"^[0-9a-f]{64}$\", description: \"SHA-256 der Datei des Beitrags\" }),\n}, { additionalProperties: false }), { maxItems: 64, description: \"Die Beitr\u00E4ge der Plugins zum Executor, in der Reihenfolge der Pluginliste des Servers\" });\n\nconst clientDescription = {\n label: Type.String({ minLength: 1, maxLength: 120 }),\n hostname: Type.String({ minLength: 1 }),\n platform: Type.String({ minLength: 1 }),\n folders: Type.Array(Type.String({ minLength: 1 }), { maxItems: 32 }),\n runsDirectory: Type.String({ minLength: 1, description: \"Absoluter Ordner, unter dem der Arbeitsplatz die neuen Ordner je Run anlegt\" }),\n ripgrep: Type.Boolean({ description: \"Ob die Bash des Arbeitsplatzes rg findet\" }),\n};\n\nexport const clientInfoSchema = Type.Object({\n id: Type.String(),\n ...clientDescription,\n}, { additionalProperties: false });\n\n/** Die Anmeldung, wie ein Arbeitsplatz mit dem Executor des Servers sie sendet. */\nexport const clientRegistrationSchema = Type.Object({\n id: clientId,\n ...clientDescription,\n executor: executorVersion,\n contributions: executorContributions,\n}, { additionalProperties: false });\n\n/** Ein Arbeitsplatz mit einem anderen Executor kennt die Form dieses Stands nicht; der Server lehnt ihn an seinem Stand ab, nicht an der Form. */\nconst otherExecutorRegistration = Type.Object({ label: clientDescription.label, executor: executorVersion }, {\n description: \"Anmeldung mit einem anderen Executor-Stand in beliebiger Form; der Server lehnt sie mit workspace-executor-version ab\",\n});\n\nconst absolutePath = Type.String({ minLength: 1, description: \"Absoluter Pfad im gebundenen Ordner\" });\n\n/** Keine Operation eines Moduls: gibt frei, was der Executor des Arbeitsplatzes f\u00FCr den Run h\u00E4lt. */\nexport const WORKSPACE_CLIENT_STOP_OPERATION = \"stop\";\n\n/** Die eine Operation, die der Server auf dem Arbeitsplatz ruft; Fortschritt ist der JSON-Wert der Operation, bei Bash { text }. */\nexport const workspaceClientContracts = {\n execute: defineOperation({\n id: \"ragents.workspace.client.execute\",\n description: \"Eine Operation des Executors auf dem Arbeitsplatz ausf\u00FChren, etwa ein Werkzeug, eine Dateiabfrage oder die Prozessanzeige; das Ergebnis ist ihr Wert, Fortschritt ihr JSON-Wert. stop gibt frei, was der Arbeitsplatz f\u00FCr den Run h\u00E4lt.\",\n implementedBy: \"client\",\n input: Type.Object({\n runId: Type.String({ minLength: 1, maxLength: 64, description: \"Kennung des Runs\" }),\n operation: Type.String({ minLength: 1, maxLength: 64, description: \"Name der Operation, etwa read, bash, roslyn_open, files.list oder stop\" }),\n toolCallId: Type.Optional(Type.String({ minLength: 1, maxLength: 200, description: \"Nur bei einem Werkzeugaufruf des Modells\" })),\n cwd: absolutePath,\n env: Type.Record(Type.String(), Type.String(), { description: \"Was der Server beitr\u00E4gt: Run-Marker und Git-Regeln der Sandbox\" }),\n input: Type.Unknown({ description: \"Die Eingabe der Operation\" }),\n }, { additionalProperties: false }),\n result: Type.Object({ value: Type.Unknown() }, { additionalProperties: false }),\n }),\n} as const;\n\nconst browseTarget = {\n runId: Type.String({ minLength: 1, maxLength: 64, description: \"Kennung des Runs\" }),\n root: Type.Union([Type.Literal(\"workspace\"), Type.Literal(\"files\")]),\n path: Type.String({ description: \"Pfad unterhalb der Wurzel; leer ist die Wurzel selbst\" }),\n};\n\n/** Die Anmeldung eines Arbeitsplatzes bindet die aufrufende Verbindung; \u00FCber sie ruft der Server zur\u00FCck. */\nexport const workspaceContracts = {\n browse: {\n list: defineOperation({\n id: \"ragents.workspace.browse.list\",\n description: \"Ein Verzeichnis im Arbeitsverzeichnis oder in der Dateiablage eines Runs auflisten.\",\n rights: [\"runs.read\", \"runs.inspect\"],\n input: Type.Object(browseTarget, { additionalProperties: false }),\n result: openJson<BrowseListing>(\"BrowseListing\"),\n }),\n preview: defineOperation({\n id: \"ragents.workspace.browse.preview\",\n description: \"Eine Datei als Text vorschauen; zu gro\u00DFe und bin\u00E4re Dateien nennen stattdessen den Grund.\",\n rights: [\"runs.read\", \"runs.inspect\"],\n input: Type.Object(browseTarget, { additionalProperties: false }),\n result: openJson<BrowsePreview>(\"BrowsePreview\"),\n }),\n },\n channels: {\n browse: defineChannel({\n id: \"ragents.workspace.browse\",\n description: \"Meldet jede \u00C4nderung unterhalb der beobachteten Wurzel eines Runs.\",\n rights: [\"runs.read\", \"runs.inspect\"],\n params: Type.Object({ runId: browseTarget.runId, root: browseTarget.root }, { additionalProperties: false }),\n message: Type.Object({ changed: Type.Literal(true) }, { additionalProperties: false }),\n }),\n },\n clients: {\n list: defineOperation({\n id: \"ragents.workspace.clients.list\",\n description: \"Die angemeldeten Arbeitspl\u00E4tze des Aufrufers; fremde erscheinen auch mit runs.read.all nicht.\",\n rights: [\"runs.read\"],\n input: Type.Object({}, { additionalProperties: false }),\n result: Type.Array(clientInfoSchema),\n }),\n contributions: defineOperation({\n id: \"ragents.workspace.clients.contributions\",\n description: \"Die Beitr\u00E4ge der Plugins zum Executor, die ein Arbeitsplatz vor der Anmeldung l\u00E4dt und mit ihr zur\u00FCckmeldet. Ein Arbeitsplatz mit anderem Executor-Stand scheitert an seinem Stand; weitere Felder z\u00E4hlen nicht.\",\n rights: [\"runs.write\"],\n input: Type.Object({ label: clientDescription.label, executor: executorVersion }),\n result: executorContributions,\n }),\n register: defineOperation({\n id: \"ragents.workspace.clients.register\",\n description: \"Einen Arbeitsplatz anmelden oder seine Ordner erneuern; die Verbindung dieser Anfrage wird sein R\u00FCckweg und braucht einen Ereignisstrom. Ein Arbeitsplatz mit anderem Executor-Stand scheitert an seinem Stand, bevor die \u00FCbrige Form z\u00E4hlt.\",\n rights: [\"runs.write\"],\n input: Type.Union([clientRegistrationSchema, otherExecutorRegistration]),\n result: clientInfoSchema,\n }),\n unregister: defineOperation({\n id: \"ragents.workspace.clients.unregister\",\n description: \"Einen eigenen Arbeitsplatz abmelden; offene Auftr\u00E4ge scheitern.\",\n rights: [\"runs.write\"],\n input: Type.Object({ id: clientId }, { additionalProperties: false }),\n result: Type.Null(),\n }),\n },\n} as const;\n\nconst isRecord = (value: unknown): value is Record<string, unknown> => typeof value === \"object\" && value !== null;\n\nconst hasExactly = (value: Record<string, unknown>, keys: readonly string[]): boolean =>\n Object.keys(value).length === keys.length && keys.every((key) => Object.hasOwn(value, key));\n\nconst isMachine = (value: unknown): value is WorkspaceMachine =>\n value === \"server\" || (isRecord(value) && hasExactly(value, [\"client\", \"label\"])\n && typeof value.client === \"string\" && WORKSPACE_CLIENT_ID_PATTERN.test(value.client) && typeof value.label === \"string\");\n\nconst isFolder = (value: unknown): value is WorkspaceFolder => {\n if (value === \"fresh\") return true;\n if (!isRecord(value) || typeof value.path !== \"string\" || value.path.length === 0) return false;\n return hasExactly(value, [\"path\"]) || (hasExactly(value, [\"path\", \"fresh\"]) && value.fresh === true);\n};\n\n/** Einen neuen Ordner mit Pfad gibt es nur auf einem Arbeitsplatz; auf dem Server legt ihn der Host selbst an. */\nexport const isWorkspaceBinding = (value: unknown): value is WorkspaceBinding =>\n isRecord(value) && hasExactly(value, [\"machine\", \"folder\"]) && isMachine(value.machine) && isFolder(value.folder)\n && !(value.machine === \"server\" && typeof value.folder === \"object\" && \"fresh\" in value.folder);\n\nexport const isFreshFolder = (folder: WorkspaceFolder): folder is \"fresh\" | FreshWorkstationFolder =>\n folder === \"fresh\" || \"fresh\" in folder;\n\n/** Die Form vor der Trennung von Rechner und Ordner, `{ kind: \"fresh\" | \"path\" | \"client\" }`, eindeutig in der heutigen. */\nconst fromKind = (value: Record<string, unknown>): unknown => {\n switch (value.kind) {\n case \"fresh\": return hasExactly(value, [\"kind\"]) ? freshServerBinding() : undefined;\n case \"path\": return hasExactly(value, [\"kind\", \"path\"]) ? { machine: \"server\", folder: { path: value.path } } : undefined;\n case \"client\": return hasExactly(value, [\"kind\", \"client\", \"label\", \"path\"])\n ? { machine: { client: value.client, label: value.label }, folder: { path: value.path } }\n : undefined;\n default: return undefined;\n }\n};\n\n/** Die gespeicherte Bindung; \u00E4ltere, unver\u00E4nderliche Journale tragen die Form mit `kind`, und nur hier wird sie abgebildet. */\nexport const storedWorkspaceBinding = (value: unknown): WorkspaceBinding | undefined => {\n if (isWorkspaceBinding(value)) return value;\n const mapped = isRecord(value) && Object.hasOwn(value, \"kind\") ? fromKind(value) : undefined;\n return isWorkspaceBinding(mapped) ? mapped : undefined;\n};\n\nexport const FRESH_WORKSPACE_LABEL = \"Leerer Ordner je Run\";\n\n/** Wie der neue Ordner je Run auf dem Rechner der Bindung hei\u00DFt; ohne Beitrag dort der leere Ordner. */\nconst freshLabelOf = (binding: WorkspaceBinding, labels: FreshWorkspaceLabels): string =>\n (binding.machine === \"server\" ? labels.server : labels.client) ?? FRESH_WORKSPACE_LABEL;\n\nexport const workspaceBindingSummary = (binding: WorkspaceBinding, labels: FreshWorkspaceLabels): string => {\n const { machine, folder } = binding;\n const fresh = freshLabelOf(binding, labels);\n const where = folder === \"fresh\" ? fresh : \"fresh\" in folder ? `${folder.path} (${fresh})` : folder.path;\n return machine === \"server\" ? where : `${machine.label}: ${where}`;\n};\n", "import { statSync } from \"node:fs\";\nimport path from \"node:path\";\nimport { Type } from \"typebox\";\nimport { DomainError, type JsonValue, type RunState, type StartOptionContribution } from \"@ragents/engine\";\nimport type { ShellTools } from \"@ragents/workspace-executor\";\nimport { shellPlatformChapter } from \"./shell-platform.js\";\nimport { storedStartOption } from \"@ragents/host/ragents/start-option-state.js\";\nimport type { WorkspaceResolver } from \"@ragents/host/ragents/workspace-runtime.js\";\nimport {\n freshServerBinding,\n FRESH_WORKSPACE_LABEL,\n isFreshFolder,\n isWorkspaceBinding,\n storedWorkspaceBinding,\n WORKSPACE_BINDING_OPTION_ID,\n workspaceBindingSummary,\n type ExistingWorkspaceFolder,\n type FreshWorkspaceLabels,\n type FreshWorkstationFolder,\n type WorkspaceBinding,\n type WorkspaceBindingPresentation,\n type WorkspaceClientInfo,\n type WorkspaceSessionMetadata,\n} from \"../contract.js\";\nimport type { WorkspaceClientRegistry } from \"./clients.js\";\n\nconst machineSchema = Type.Union([\n Type.Literal(\"server\"),\n Type.Object({ client: Type.String({ minLength: 8, maxLength: 64 }), label: Type.String() }, { additionalProperties: false }),\n]);\n\nconst folderSchema = Type.Union([\n Type.Literal(\"fresh\"),\n Type.Object({ path: Type.String({ minLength: 1 }), fresh: Type.Optional(Type.Literal(true)) }, { additionalProperties: false }),\n]);\n\nconst bindingSchema = Type.Object({ machine: machineSchema, folder: folderSchema }, { additionalProperties: false });\n\n/** Ein Run auf einem Arbeitsplatz mit dessen Kennung, Label und dem Ordner dort; `fresh` tr\u00E4gt dann schon seinen Pfad. */\nexport type WorkstationBinding = {\n machine: { client: string; label: string };\n folder: ExistingWorkspaceFolder | FreshWorkstationFolder;\n};\n\nconst insideFolder = (folder: string, candidate: string): boolean => {\n const separator = folder.includes(\"\\\\\") ? \"\\\\\" : \"/\";\n const root = folder.endsWith(separator) ? folder.slice(0, -separator.length) : folder;\n return candidate === root || candidate.startsWith(root + separator);\n};\n\n/** Der Ordner eines Runs unter dem Ordner, in dem ein Arbeitsplatz die neuen Ordner je Run anlegt; mit dessen Trennzeichen. */\nexport const workstationRunFolder = (runsDirectory: string, runId: string): string => {\n const separator = runsDirectory.includes(\"\\\\\") ? \"\\\\\" : \"/\";\n const root = runsDirectory.endsWith(separator) ? runsDirectory.slice(0, -separator.length) : runsDirectory;\n return `${root}${separator}${runId}`;\n};\n\n/** Die Bindung eines Runs; ohne gespeicherte Wahl der neue Ordner auf dem Server, eine unlesbare sperrt den Run mit Ursache. */\nexport const bindingOf = (state: RunState | null): WorkspaceBinding => {\n const stored = storedStartOption(state, WORKSPACE_BINDING_OPTION_ID);\n if (stored === undefined) return freshServerBinding();\n const binding = storedWorkspaceBinding(stored);\n if (!binding || (binding.machine !== \"server\" && binding.folder === \"fresh\")) {\n throw new Error(`Die gespeicherte Arbeitsbereich-Bindung ist ung\u00FCltig: ${JSON.stringify(stored)}`);\n }\n return binding;\n};\n\nexport const isWorkstationBinding = (binding: WorkspaceBinding): binding is WorkstationBinding =>\n binding.machine !== \"server\" && binding.folder !== \"fresh\";\n\n/** Ein Run benutzt nur Arbeitspl\u00E4tze seines Eigent\u00FCmers, ein Run ohne Eigent\u00FCmer nur ohne Benutzer angemeldete. */\nexport const workspaceOwnerOf = (state: RunState | null): string | null => state?.ownerUserId ?? null;\n\n/** Der vorhandene Ordner auf dem Serverrechner, an den der Run gebunden ist; ein neuer Ordner und ein Arbeitsplatz liegen nicht dort. */\nexport const boundServerDirectory = (state: RunState | null): string | null => {\n const { machine, folder } = bindingOf(state);\n return machine === \"server\" && folder !== \"fresh\" ? folder.path : null;\n};\n\n/** Ein vorhandener Ordner dieses Servers; dieselbe Pr\u00FCfung wie beim W\u00E4hlen der Startoption. */\nexport const serverDirectoryFolder = (directory: string): ExistingWorkspaceFolder => {\n if (!path.isAbsolute(directory)) throw new DomainError(\"workspace-path-relative\", \"Der Ordner muss ein absoluter Pfad sein.\", 400);\n const resolved = path.resolve(directory);\n if (!statSync(resolved, { throwIfNoEntry: false })?.isDirectory()) {\n throw new DomainError(\"workspace-path-missing\", `Der Ordner ${resolved} existiert auf dem Server nicht.`, 400);\n }\n return { path: resolved };\n};\n\n/** Die Bash eines Runs l\u00E4uft auf dem Executor seiner Bindung; der Prompt nennt deshalb dessen Plattform und Werkzeuge, nicht die des Servers. */\nexport const executorShellChapter = (\n registry: WorkspaceClientRegistry,\n owner: string | null,\n binding: WorkspaceBinding,\n serverTools: ShellTools,\n): string => {\n const { machine } = binding;\n if (machine === \"server\") return shellPlatformChapter(process.platform, serverTools);\n const client = registry.info(owner, machine.client);\n return client\n ? shellPlatformChapter(client.platform as NodeJS.Platform, { ripgrep: client.ripgrep })\n : `## Shell platform\\n\\nThe workstation ${machine.label} that holds this project is not registered right now, `\n + \"so the platform of its shell is unknown; the workspace tools fail until it connects again.\";\n};\n\n/** Wo die Wurzel eines Runs liegt, in Worten: bei einem Arbeitsplatz mit dessen Label, sonst der Pfad selbst. */\nexport const workspaceLocation = (binding: WorkspaceBinding, location: string): string =>\n binding.machine === \"server\" ? location : `Arbeitsplatz ${binding.machine.label}: ${location}`;\n\n/** Den neuen Ordner je Run stellt der Beitrag, sobald es einen gibt; auf einem Arbeitsplatz nur, wenn er es dort ausdr\u00FCcklich kann. */\nexport const freshLabels = (contribution: WorkspaceResolver | undefined): FreshWorkspaceLabels => ({\n server: contribution?.kind?.label ?? FRESH_WORKSPACE_LABEL,\n client: contribution ? contribution.workstation?.label ?? null : FRESH_WORKSPACE_LABEL,\n});\n\nexport const sessionMetadataOf = (state: RunState | null, contribution: WorkspaceResolver | undefined): WorkspaceSessionMetadata => {\n const binding = bindingOf(state);\n return { binding, summary: workspaceBindingSummary(binding, freshLabels(contribution)) };\n};\n\nconst unsupported = (message: string): DomainError => new DomainError(\"workspace-binding-unsupported\", message, 400);\n\n/** Ein Arbeitsplatz des Handelnden, der den Ordner anbietet; ein neuer Ordner je Run bekommt dort seinen Pfad unter dessen Ordner f\u00FCr Runs. */\nconst workstationBinding = (\n client: WorkspaceClientInfo,\n folder: WorkspaceBinding[\"folder\"],\n runId: string,\n labels: FreshWorkspaceLabels,\n): WorkstationBinding => {\n const machine = { client: client.id, label: client.label };\n if (isFreshFolder(folder)) {\n if (labels.client === null) {\n throw unsupported(`Einen neuen Ordner je Run gibt es hier nur auf dem Server (${labels.server}); w\u00E4hle dort einen oder einen vorhandenen Ordner des Arbeitsplatzes.`);\n }\n return { machine, folder: { path: workstationRunFolder(client.runsDirectory, runId), fresh: true } };\n }\n if (!client.folders.some((offered) => insideFolder(offered, folder.path))) {\n throw new DomainError(\"workspace-client-folder\", `Der Arbeitsplatz ${client.label} bietet den Ordner ${folder.path} nicht an.`, 400);\n }\n return { machine, folder: { path: folder.path } };\n};\n\nexport const workspaceBindingOption = (\n registry: WorkspaceClientRegistry,\n contribution: () => WorkspaceResolver | undefined,\n): StartOptionContribution => ({\n id: WORKSPACE_BINDING_OPTION_ID,\n schema: bindingSchema,\n selectable: () => true,\n defaultValue: () => freshServerBinding(),\n accept: (value, { runId, userId }) => {\n if (!isWorkspaceBinding(value)) throw new DomainError(\"workspace-binding-invalid\", \"Die Arbeitsbereich-Bindung hat kein g\u00FCltiges Format.\", 400);\n const labels = freshLabels(contribution());\n const { machine, folder } = value;\n if (machine === \"server\") {\n if (folder === \"fresh\") return freshServerBinding();\n if (\"fresh\" in folder) throw new DomainError(\"workspace-binding-invalid\", \"Einen neuen Ordner je Run legt auf dem Server der Host an; er hat keinen gew\u00E4hlten Pfad.\", 400);\n if (!(contribution()?.kind?.serverFolders ?? true)) {\n throw unsupported(`Ein vorhandener Ordner auf dem Serverrechner ist hier keine Bindung; w\u00E4hle ${labels.server} oder einen Arbeitsplatz.`);\n }\n return { machine, folder: serverDirectoryFolder(folder.path) };\n }\n const client = registry.info(userId, machine.client);\n if (!client) throw new DomainError(\"workspace-client-disconnected\", `Der Arbeitsplatz ${machine.label || machine.client} ist nicht verbunden.`, 409);\n return workstationBinding(client, folder, runId, labels);\n },\n describe: (_value, { userId }) => {\n const presentation: WorkspaceBindingPresentation = {\n kind: \"workspace-binding\",\n clients: registry.list(userId),\n fresh: freshLabels(contribution()),\n serverFolders: contribution()?.kind?.serverFolders ?? true,\n };\n return presentation as unknown as JsonValue;\n },\n ownerOnly: (value) => {\n const binding = storedWorkspaceBinding(value);\n return binding !== undefined && binding.machine !== \"server\";\n },\n});\n", "import {\n implement,\n implementChannel,\n type AccessContext,\n type ChannelContribution,\n type MethodContribution,\n} from \"@ragents/engine\";\nimport {\n FILE_OPERATIONS,\n listDirectory,\n readTextFile,\n watchDirectory,\n type FileListing,\n type FileText,\n type FileWatchProgress,\n} from \"@ragents/workspace-executor\";\nimport { withDomainCause, type SandboxServices } from \"@ragents/host/plugin-support/workspace-sandbox-host.js\";\nimport {\n workspaceContracts,\n type BrowseListing,\n type BrowsePreview,\n type BrowseRoot,\n} from \"../contract.js\";\n\nexport interface BrowseOptions {\n ensureSession: (runId: string) => void;\n /** Der Arbeitsbereich eines Runs, den nur sein Eigent\u00FCmer bedient, liegt bei ihm; die Dateiablage des Servers nicht. */\n ensureWorkspaceAccess: (access: AccessContext, runId: string) => void;\n /** Der Arbeitsbereich ist nur \u00FCber den Executor des Runs erreichbar, wo immer er liegt. */\n execute: SandboxServices[\"execute\"];\n /** Die Dateiablage liegt auf dem Server und geh\u00F6rt nicht zum Arbeitsbereich. */\n documentsFor: (runId: string) => Promise<string>;\n /** Wie die Wurzel eines Runs hei\u00DFt, etwa mit dem Label seines Arbeitsplatzes. */\n locationOf: (runId: string, location: string) => string;\n}\n\nconst onServer = async <T>(operation: () => Promise<T>): Promise<T> => {\n try {\n return await operation();\n } catch (error) {\n throw withDomainCause(error);\n }\n};\n\nconst listingOf = async (options: BrowseOptions, runId: string, root: BrowseRoot, target: string): Promise<BrowseListing> => {\n if (root === \"files\") {\n const listing = await onServer(async () => listDirectory(await options.documentsFor(runId), target));\n return { root, ...listing };\n }\n const listing = await options.execute(runId, FILE_OPERATIONS.list, { path: target }) as FileListing;\n return { root, ...listing, location: options.locationOf(runId, listing.location) };\n};\n\nconst previewOf = async (options: BrowseOptions, runId: string, root: BrowseRoot, target: string): Promise<BrowsePreview> => {\n const text = root === \"files\"\n ? await onServer(async () => readTextFile(await options.documentsFor(runId), target))\n : await options.execute(runId, FILE_OPERATIONS.read, { path: target }) as FileText;\n return { root, ...text };\n};\n\nconst ensureRoot = (options: BrowseOptions, access: AccessContext, runId: string, root: BrowseRoot): void => {\n if (root === \"workspace\") options.ensureWorkspaceAccess(access, runId);\n else options.ensureSession(runId);\n};\n\nexport const createBrowseMethods = (options: BrowseOptions): MethodContribution[] => [\n implement(workspaceContracts.browse.list, ({ runId, root, path: target }, { access }) => {\n ensureRoot(options, access, runId, root);\n return listingOf(options, runId, root, target);\n }),\n implement(workspaceContracts.browse.preview, ({ runId, root, path: target }, { access }) => {\n ensureRoot(options, access, runId, root);\n return previewOf(options, runId, root, target);\n }),\n];\n\n/** Nach dem Ende einer laufenden Beobachtung, etwa weil der Arbeitsplatz weg war, versucht der Kanal es in diesem Abstand erneut. */\nconst WATCH_RETRY_MS = 5_000;\n\n/** Beobachtet den Arbeitsbereich beim Executor des Runs bis zum Abbruch; steht die Beobachtung, ist der Kanal offen, und endet sie, beginnt er eine neue. */\nconst watchWorkspace = (options: BrowseOptions, runId: string, changed: () => void): Promise<() => void> =>\n new Promise((ready, failed) => {\n const controller = new AbortController();\n let opened = false;\n let retry: NodeJS.Timeout | undefined;\n const stop = (): void => {\n controller.abort();\n clearTimeout(retry);\n };\n const start = (): void => {\n let watching = false;\n const ended = (error?: unknown): void => {\n if (controller.signal.aborted) return;\n if (!opened) {\n failed(error ?? new Error(\"Die Beobachtung des Arbeitsbereichs endete, bevor sie stand\"));\n return;\n }\n // Endet eine laufende Beobachtung, l\u00E4dt die Ansicht neu und zeigt die Ursache; steht die n\u00E4chste, l\u00E4dt sie noch einmal.\n if (watching) changed();\n retry = setTimeout(start, WATCH_RETRY_MS);\n };\n options.execute(runId, FILE_OPERATIONS.watch, {}, {\n signal: controller.signal,\n untilAborted: true,\n onProgress: (value) => {\n if ((value as FileWatchProgress).kind === \"changed\") changed();\n else if (!watching) {\n watching = true;\n if (opened) changed();\n else {\n opened = true;\n ready(stop);\n }\n }\n },\n }).then(() => ended(), ended);\n };\n start();\n });\n\nexport const createBrowseChannel = (options: BrowseOptions): ChannelContribution =>\n implementChannel(workspaceContracts.channels.browse, async ({ runId, root }, emit, { access }) => {\n ensureRoot(options, access, runId, root);\n const changed = (): void => emit({ changed: true });\n if (root === \"workspace\") return watchWorkspace(options, runId, changed);\n return onServer(async () => watchDirectory(await options.documentsFor(runId), { onChange: changed, onError: changed }));\n });\n", "import { Value } from \"typebox/value\";\nimport {\n DomainError,\n RPC_ERROR_CODES,\n RpcError,\n implement,\n schemaComplaints,\n type AccessContext,\n type MethodConnection,\n type MethodContribution,\n} from \"@ragents/engine\";\nimport {\n WORKSPACE_EXECUTOR_VERSION,\n sandboxRunEnvironment,\n type ExecutorContributionStand,\n type WorkspaceExecuteOptions,\n type WorkspaceExecutor,\n} from \"@ragents/workspace-executor\";\nimport {\n WORKSPACE_CLIENT_STOP_OPERATION,\n clientRegistrationSchema,\n workspaceClientContracts,\n workspaceContracts,\n type WorkspaceClientDescription,\n type WorkspaceClientInfo,\n} from \"../contract.js\";\n\ninterface ClientEntry {\n readonly info: WorkspaceClientInfo;\n readonly owner: string | null;\n readonly connection: MethodConnection;\n readonly release: () => void;\n /** Die offenen Aufrufe \u00FCber diese Anmeldung; l\u00F6st eine neue Verbindung sie ab, scheitern sie sofort. */\n readonly calls: Set<AbortController>;\n /** Die Stopps, die gerade \u00FCber diese Anmeldung zugestellt werden, je Run. */\n readonly stops: Map<string, Promise<void>>;\n}\n\n/** Die einzige Grenze gegen einen h\u00E4ngenden Arbeitsplatz; seine eigenen Zeitgrenzen hat der Executor. */\nconst CLIENT_TIMEOUT_MS = 15 * 60 * 1000;\n\n/** So lange wartet Aufr\u00E4umen (Stopp, `whenReachable`) auf den Arbeitsplatz; es bleibt unter der Stoppgrenze der Plugins. */\nconst CLEANUP_TIMEOUT_MS = 10_000;\n\n/** Nach so langer Zeit versucht der Server einen ausstehenden Stopp erneut, solange der Arbeitsplatz angemeldet ist. */\nconst STOP_RETRY_MS = 30_000;\n\nexport const ownerOf = (access: AccessContext): string | null => access.user?.id ?? null;\n\n/** Eine Beobachtung l\u00E4uft bis zum Abbruch, Aufr\u00E4umen kurz; alles andere wartet die Sicherheitsgrenze plus der Dauer, die der Aufruf selbst verlangt. */\nconst timeoutFor = (options: WorkspaceExecuteOptions): { timeoutMs?: number } => {\n if (options.untilAborted) return {};\n if (options.whenReachable) return { timeoutMs: CLEANUP_TIMEOUT_MS };\n return { timeoutMs: CLIENT_TIMEOUT_MS + (options.durationMs ?? 0) };\n};\n\nconst disconnected = (label: string, detail: string): DomainError =>\n new DomainError(\"workspace-client-disconnected\", `Der Arbeitsplatz ${label} hat die Verbindung verloren: ${detail}`, 409);\n\n/** Bricht die Verbindung mitten im Aufruf, muss die Ursache den Arbeitsplatz nennen, nicht den Server; ein fachlicher Fehler bleibt einer. */\nconst withClientCause = (cause: unknown, label: string): unknown => {\n if (!(cause instanceof RpcError)) return cause;\n if (cause.code === RPC_ERROR_CODES.connectionClosed) return disconnected(label, cause.message);\n if (cause.code === RPC_ERROR_CODES.timeout) {\n return new DomainError(\"workspace-client-timeout\", `Der Arbeitsplatz ${label} hat nicht geantwortet: ${cause.message}`, 504);\n }\n if (cause.code === RPC_ERROR_CODES.application && cause.domainCode !== undefined && cause.status !== undefined) {\n return new DomainError(cause.domainCode, cause.message, cause.status);\n }\n return cause;\n};\n\n/** Der Arbeitsplatz war nicht da oder hat nicht rechtzeitig geantwortet; ein fachlicher Fehler z\u00E4hlt nicht dazu. */\nconst unreached = (cause: unknown): boolean =>\n cause instanceof DomainError && (cause.code === \"workspace-client-disconnected\" || cause.code === \"workspace-client-timeout\");\n\nconst messageOf = (cause: unknown): string => cause instanceof Error ? cause.message : String(cause);\n\n/** Ein Arbeitsplatz ist erst durch Besitzer und Kennung bestimmt; zwei Benutzer mit derselben Kennung teilen nichts. */\nconst keyOf = (owner: string | null, id: string): string => JSON.stringify([owner, id]);\n\n/** Server und Arbeitsplatz brauchen denselben Executor; die Meldung sagt, wer von beiden zu alt ist. */\nconst assertExecutor = (label: string, executor: string): void => {\n if (executor === WORKSPACE_EXECUTOR_VERSION) return;\n const action = Number(executor) > Number(WORKSPACE_EXECUTOR_VERSION)\n ? \"Den Server auf die Fassung des Arbeitsplatzes aktualisieren.\"\n : \"Die RAgents-Erweiterung in VS Code beziehungsweise das Paket @schlenkr/ragents auf dem Arbeitsplatz aktualisieren.\";\n throw new DomainError(\n \"workspace-executor-version\",\n `Der Arbeitsplatz ${label} bringt den Executor ${executor} mit, der Server verlangt ${WORKSPACE_EXECUTOR_VERSION}. ${action}`,\n 409,\n );\n};\n\nconst described = (contributions: readonly ExecutorContributionStand[]): string =>\n contributions.map(({ plugin, stand }) => `${plugin} (${stand.slice(0, 12)})`).join(\", \") || \"keine\";\n\n/** Ein Arbeitsplatz f\u00FChrt aus, was die Plugins des Servers beitragen; mit anderen Beitr\u00E4gen liefen dieselben Werkzeuge dort anders als auf dem Server. */\nconst assertContributions = (label: string, expected: readonly ExecutorContributionStand[], given: readonly ExecutorContributionStand[]): void => {\n const key = (entry: ExecutorContributionStand): string => `${entry.plugin}\\0${entry.stand}`;\n const same = expected.length === given.length && expected.every((entry) => given.some((other) => key(other) === key(entry)));\n if (same) return;\n throw new DomainError(\n \"workspace-executor-contributions\",\n `Der Arbeitsplatz ${label} bringt die Executor-Beitr\u00E4ge ${described(given)} mit, der Server verlangt ${described(expected)}. `\n + \"Der Arbeitsplatz fragt sie mit ragents.workspace.clients.contributions ab und meldet sich danach erneut an.\",\n 409,\n );\n};\n\n/** \u00DCber das Netz nimmt der Server Arbeitspl\u00E4tze nur von angemeldeten Benutzern an; ohne Benutzer g\u00E4be es nur einen Besitzer f\u00FCr alle Zug\u00E4nge. */\nexport const assertMayRegister = (access: AccessContext, local: boolean): void => {\n if (local || (access.enabled && access.user !== null)) return;\n throw new DomainError(\n \"workspace-client-login-required\",\n \"Dieser Server kennt keine Benutzeranmeldung; einen Arbeitsplatz nimmt er deshalb nur \u00FCber eine Loopback-Verbindung an \"\n + \"(etwa http://127.0.0.1 auf seinem eigenen Rechner). \u00DCber das Netz braucht ein Arbeitsplatz ein Profil mit Benutzern.\",\n 403,\n );\n};\n\n/** Kennt die angemeldeten Arbeitspl\u00E4tze je Besitzer, h\u00E4lt je Client die Verbindung, \u00FCber die der Server ihn zur\u00FCckruft, und die Stopps, die ihn nicht erreicht haben. */\nexport class WorkspaceClientRegistry {\n /** Was die Plugins des Servers zum Executor beitragen; jeder Arbeitsplatz muss genau diese Beitr\u00E4ge tragen. */\n readonly contributions: readonly ExecutorContributionStand[];\n readonly #clients = new Map<string, ClientEntry>();\n /** Stopps, die den Arbeitsplatz noch nicht erreicht haben, je Arbeitsplatz und Run mit dem Ordner der Bindung. */\n readonly #pendingStops = new Map<string, Map<string, string>>();\n readonly #stopRetries = new Map<string, NodeJS.Timeout>();\n\n constructor(contributions: readonly ExecutorContributionStand[]) {\n this.contributions = contributions.map(({ plugin, stand }) => ({ plugin, stand }));\n }\n\n async register(\n id: string,\n description: WorkspaceClientDescription,\n executor: string,\n contributions: readonly ExecutorContributionStand[],\n connection: MethodConnection,\n ): Promise<WorkspaceClientInfo> {\n if (connection.streamless) {\n throw new DomainError(\"stream-required\", \"Die Anmeldung eines Arbeitsplatzes braucht einen Ereignisstrom.\", 409);\n }\n assertExecutor(description.label, executor);\n assertContributions(description.label, this.contributions, contributions);\n const owner = connection.userId;\n const key = keyOf(owner, id);\n const previous = this.#clients.get(key);\n previous?.release();\n const info: WorkspaceClientInfo = { ...description, id };\n const renewed = previous?.connection === connection;\n const entry: ClientEntry = {\n info,\n owner,\n connection,\n release: connection.onClose(() => this.#disconnected(key, connection)),\n calls: renewed ? previous.calls : new Set(),\n stops: renewed ? previous.stops : new Map(),\n };\n this.#clients.set(key, entry);\n if (previous && !renewed) this.#abandon(previous);\n this.#deliverPendingStops(key);\n return info;\n }\n\n /** Nur die Verbindung, die den Eintrag h\u00E4lt, meldet ihn ab; eine Abmeldung ohne Eintrag ist nach einer Trennung kein Fehler. */\n unregister(owner: string | null, id: string, connection: MethodConnection): void {\n const key = keyOf(owner, id);\n const entry = this.#clients.get(key);\n if (entry?.connection !== connection) return;\n this.#remove(key, entry);\n }\n\n list(owner: string | null): WorkspaceClientInfo[] {\n return [...this.#clients.values()].filter((entry) => entry.owner === owner).map((entry) => entry.info);\n }\n\n info(owner: string | null, id: string): WorkspaceClientInfo | undefined {\n return this.#clients.get(keyOf(owner, id))?.info;\n }\n\n /** Die Runs, deren Stopp diesen Arbeitsplatz noch nicht erreicht hat. */\n pendingStops(owner: string | null, id: string): readonly string[] {\n return this.#pendingRuns(keyOf(owner, id));\n }\n\n /** Der Executor eines gebundenen Runs: dieselbe Schnittstelle wie im Server, nur \u00FCber die Verbindung des Arbeitsplatzes seines Besitzers. */\n executorFor(owner: string | null, id: string, label: string, cwd: string): WorkspaceExecutor {\n const key = keyOf(owner, id);\n const call = async (runId: string, operation: string, input: unknown, options: WorkspaceExecuteOptions): Promise<unknown> => {\n if (options.untilAborted && !options.signal) throw new Error(`Die Operation ${operation} l\u00E4uft bis zum Abbruch und braucht daf\u00FCr ein Abbruchsignal`);\n if (this.#pendingStops.get(key)?.has(runId)) {\n // Aufr\u00E4umen neben einem ausstehenden Stopp erledigt dieser mit; alles andere wartet, bis er zugestellt ist.\n if (options.whenReachable) return null;\n if (this.#clients.has(key)) await this.#deliverStop(key, runId);\n }\n const entry = this.#clients.get(key);\n if (!entry) {\n if (options.whenReachable) return null;\n throw new DomainError(\"workspace-client-disconnected\", `Der Arbeitsplatz ${label} ist nicht verbunden.`, 409);\n }\n try {\n return await this.#send(entry, runId, operation, input, cwd, options);\n } catch (cause) {\n if (options.whenReachable && unreached(cause)) return null;\n throw cause;\n }\n };\n return {\n version: WORKSPACE_EXECUTOR_VERSION,\n execute: (runId, operation, input, options = {}) => call(runId, operation, input, options),\n stopRun: async (runId) => {\n this.#pendingStopsOf(key).set(runId, cwd);\n await this.#deliverStop(key, runId);\n },\n shutdown: async () => undefined,\n };\n }\n\n shutdown(): void {\n for (const entry of this.#clients.values()) {\n entry.release();\n this.#abandon(entry);\n }\n this.#clients.clear();\n for (const timer of this.#stopRetries.values()) clearTimeout(timer);\n this.#stopRetries.clear();\n this.#pendingStops.clear();\n }\n\n /** Ein getrennter Arbeitsplatz verl\u00E4sst die Registry; eine sp\u00E4tere Anmeldung \u00FCber eine neue Verbindung bleibt stehen. */\n #disconnected(key: string, connection: MethodConnection): void {\n const entry = this.#clients.get(key);\n if (entry?.connection !== connection) return;\n this.#remove(key, entry);\n }\n\n #remove(key: string, entry: ClientEntry): void {\n entry.release();\n this.#clients.delete(key);\n this.#abandon(entry);\n }\n\n /** Eine Verbindung, die niemand mehr h\u00E4lt, bekommt keine Antworten mehr zugestellt; ihre offenen Aufrufe scheitern sofort. */\n #abandon(entry: ClientEntry): void {\n for (const controller of entry.calls) controller.abort();\n entry.calls.clear();\n }\n\n async #send(\n entry: ClientEntry,\n runId: string,\n operation: string,\n input: unknown,\n cwd: string,\n options: WorkspaceExecuteOptions,\n ): Promise<unknown> {\n const label = entry.info.label;\n const abandoned = new AbortController();\n entry.calls.add(abandoned);\n const signal = options.signal ? AbortSignal.any([options.signal, abandoned.signal]) : abandoned.signal;\n try {\n const { value } = await Promise.race([\n entry.connection.call(\n workspaceClientContracts.execute,\n {\n runId,\n operation,\n ...(options.toolCallId ? { toolCallId: options.toolCallId } : {}),\n cwd,\n env: sandboxRunEnvironment(runId),\n input,\n },\n {\n signal,\n ...timeoutFor(options),\n ...(options.onProgress ? { onProgress: options.onProgress } : {}),\n },\n ),\n new Promise<never>((_settle, fail) => abandoned.signal.addEventListener(\"abort\", () =>\n fail(disconnected(label, \"eine neue Verbindung hat die Anmeldung abgel\u00F6st\")), { once: true })),\n ]);\n return value;\n } catch (cause) {\n throw withClientCause(cause, label);\n } finally {\n entry.calls.delete(abandoned);\n }\n }\n\n #pendingStopsOf(key: string): Map<string, string> {\n const known = this.#pendingStops.get(key);\n if (known) return known;\n const created = new Map<string, string>();\n this.#pendingStops.set(key, created);\n return created;\n }\n\n /** Stellt einen ausstehenden Stopp zu; erreicht er den Arbeitsplatz nicht, bleibt er ausstehend, und die n\u00E4chste Anmeldung holt ihn nach. */\n #deliverStop(key: string, runId: string): Promise<void> {\n const entry = this.#clients.get(key);\n const cwd = this.#pendingStops.get(key)?.get(runId);\n if (cwd === undefined) return Promise.resolve();\n if (!entry) {\n console.warn(`Der Stopp des Runs ${runId} erreicht seinen Arbeitsplatz erst bei dessen n\u00E4chster Anmeldung.`);\n return Promise.resolve();\n }\n const running = entry.stops.get(runId);\n if (running) return running;\n const delivery = this.#send(entry, runId, WORKSPACE_CLIENT_STOP_OPERATION, null, cwd, { whenReachable: true })\n .then(() => this.#stopDelivered(key, runId, cwd), (cause: unknown) => {\n if (!unreached(cause)) {\n this.#stopDelivered(key, runId, cwd);\n throw cause;\n }\n console.warn(`Der Stopp des Runs ${runId} hat den Arbeitsplatz ${entry.info.label} nicht erreicht und bleibt ausstehend: ${messageOf(cause)}`);\n this.#retryStops(key);\n })\n .finally(() => entry.stops.delete(runId));\n entry.stops.set(runId, delivery);\n return delivery;\n }\n\n #stopDelivered(key: string, runId: string, cwd: string): void {\n const pending = this.#pendingStops.get(key);\n if (pending?.get(runId) === cwd) pending.delete(runId);\n if (pending?.size === 0) this.#pendingStops.delete(key);\n }\n\n #deliverPendingStops(key: string): void {\n for (const runId of this.#pendingRuns(key)) {\n void this.#deliverStop(key, runId).catch((cause: unknown) =>\n console.warn(`Der nachgeholte Stopp des Runs ${runId} ist gescheitert: ${messageOf(cause)}`));\n }\n }\n\n #pendingRuns(key: string): readonly string[] {\n return [...this.#pendingStops.get(key)?.keys() ?? []];\n }\n\n /** Ein Arbeitsplatz, der angemeldet bleibt, aber nicht antwortet, bekommt seine ausstehenden Stopps sp\u00E4ter noch einmal. */\n #retryStops(key: string): void {\n if (this.#stopRetries.has(key)) return;\n const timer = setTimeout(() => {\n this.#stopRetries.delete(key);\n if (this.#clients.has(key)) this.#deliverPendingStops(key);\n }, STOP_RETRY_MS);\n timer.unref();\n this.#stopRetries.set(key, timer);\n }\n}\n\nexport const clientMethods = (registry: WorkspaceClientRegistry): MethodContribution[] => [\n implement(workspaceContracts.clients.list, (_input, { access }) => registry.list(ownerOf(access))),\n implement(workspaceContracts.clients.contributions, ({ label, executor }, { access, local }) => {\n assertMayRegister(access, local);\n assertExecutor(label, executor);\n return registry.contributions.map((entry) => ({ ...entry }));\n }),\n implement(workspaceContracts.clients.register, (input, { access, connection, local }) => {\n assertMayRegister(access, local);\n // Erst der Stand: ein Arbeitsplatz mit einem anderen kennt die Form dieses Stands nicht, mit diesem gilt sie ganz.\n assertExecutor(input.label, input.executor);\n if (!Value.Check(clientRegistrationSchema, input)) {\n throw new RpcError(RPC_ERROR_CODES.invalidParams,\n `Ung\u00FCltige Eingabe f\u00FCr ${workspaceContracts.clients.register.id}: ${schemaComplaints(clientRegistrationSchema, input, \"params\")}`);\n }\n const { id, executor, contributions, ...description } = input;\n return registry.register(id, description, executor, contributions, connection);\n }),\n implement(workspaceContracts.clients.unregister, ({ id }, { access, connection }) => {\n registry.unregister(ownerOf(access), id, connection);\n return null;\n }),\n];\n", "import { declaredEnvironment } from \"@ragents/host/plugin-support/plugin-config.js\";\nimport { PROCESS_SANDBOX_DEFAULT_NETWORK } from \"@ragents/host/plugin-support/process-sandbox.js\";\n\nexport const workspaceConfigDescriptors = [\n { key: \"PROCESS_SANDBOX\", source: \"environment\" },\n { key: \"PROCESS_SANDBOX_NETWORK\", source: \"environment\" },\n { key: \"RAGENTS_BASH\", source: \"environment\" },\n { key: \"RAGENTS_RG\", source: \"environment\" },\n { key: \"RAGENTS_BASH_TIMEOUT_SECONDS\", source: \"environment\" },\n] as const;\n\nconst env = declaredEnvironment(workspaceConfigDescriptors);\n\nexport interface ProcessSandboxSetting {\n readonly enabled: boolean;\n readonly network: readonly string[];\n}\n\n/** Ohne Angabe ist die Sandbox an; abschalten geht nur ausdr\u00FCcklich mit \"off\". */\nexport const processSandboxSetting = (): ProcessSandboxSetting => {\n const mode = env.optional(\"PROCESS_SANDBOX\") ?? \"on\";\n if (mode !== \"on\" && mode !== \"off\") {\n throw new Error(`PROCESS_SANDBOX in der Sektion ragents.workspace ist \"on\" oder \"off\", nicht \"${mode}\"`);\n }\n const network = env.optional(\"PROCESS_SANDBOX_NETWORK\") === undefined\n ? PROCESS_SANDBOX_DEFAULT_NETWORK\n : env.list(\"PROCESS_SANDBOX_NETWORK\");\n return { enabled: mode === \"on\", network };\n};\n\n/** Die Bash, mit der der Executor dieses Servers das Werkzeug bash startet; unter Windows setzt sie die VS-Code-Erweiterung f\u00FCr ihren lokalen Host. */\nexport const bashSetting = (): string | undefined => env.optional(\"RAGENTS_BASH\") || undefined;\n\n/** Das rg, das der Executor dieses Servers vorn in den PATH der Bash setzt; die VS-Code-Erweiterung setzt es f\u00FCr ihren lokalen Host. */\nexport const rgSetting = (): string | undefined => env.optional(\"RAGENTS_RG\") || undefined;\n\n/** Die Zeitgrenze von bash in Sekunden f\u00FCr Aufrufe ohne eigene; mehr als die gr\u00F6\u00DFte, die ein Aufruf nennen darf, lehnt das Werkzeug beim Start ab. */\nexport const bashTimeoutSetting = (): number | undefined =>\n env.optional(\"RAGENTS_BASH_TIMEOUT_SECONDS\") ? env.positiveNumber(\"RAGENTS_BASH_TIMEOUT_SECONDS\", \"\") : undefined;\n", "import { mkdir, realpath } from \"node:fs/promises\";\nimport path from \"node:path\";\nimport type { JsonValue, RunState, WorkspaceToolNaming } from \"@ragents/engine\";\nimport { DomainError } from \"@ragents/engine\";\nimport {\n RUN_FOLDER_OPERATIONS,\n type RunFolderCreated,\n type SandboxHomeEnvironment,\n type WorkspaceExecuteOptions,\n type WorkspaceExecutor,\n type WorkspaceExecutorParts,\n} from \"@ragents/workspace-executor\";\nimport type {\n SessionWorkspace,\n WorkspaceFolderStep,\n WorkspacePlacement,\n WorkspaceResolver,\n WorkspaceRuntime,\n WorkspaceRuntimeDescription,\n WorkspaceTransfer,\n WorkstationFolderContext,\n} from \"@ragents/host/ragents/workspace-runtime.js\";\nimport { storedStartOption } from \"@ragents/host/ragents/start-option-state.js\";\nimport { sandboxToolNaming } from \"./workspace-tool-naming.js\";\nimport { WorkspaceSandboxHost, type ServerRootDescription } from \"@ragents/host/plugin-support/workspace-sandbox-host.js\";\nimport type { RunProcessSandboxes } from \"@ragents/host/plugin-support/process-sandbox.js\";\nimport { FRESH_WORKSPACE_LABEL, isFreshFolder, type ExistingWorkspaceFolder, type WorkspaceBinding } from \"../contract.js\";\nimport {\n bindingOf,\n boundServerDirectory,\n isWorkstationBinding,\n serverDirectoryFolder,\n workspaceOwnerOf,\n type WorkstationBinding,\n} from \"./binding.js\";\nimport type { WorkspaceClientRegistry } from \"./clients.js\";\n\nexport interface RunWorkspaceRuntimeOptions {\n globalDirectory: string;\n sessionDirectory: (runId: string, ...segments: string[]) => string;\n /** Die Speichergrenze eines Runs; innerhalb davon geh\u00F6ren private Arbeitsdateien seinem Konto. */\n storageRootFor: (runId: string) => string;\n sessionsDirectoryPattern: string;\n sessionWorkspaceFor: (runId: string) => Promise<SessionWorkspace>;\n skillPaths: () => Promise<readonly string[]>;\n resolver: () => WorkspaceResolver | undefined;\n runState: (runId: string) => RunState | null;\n storeBinding: (runId: string, binding: WorkspaceBinding) => void;\n clients: WorkspaceClientRegistry;\n /** Was die Plugins des Profils zum Executor des Servers beitragen; die Arbeitspl\u00E4tze laden dieselben Beitr\u00E4ge selbst. */\n contributions: readonly WorkspaceExecutorParts[];\n /** Die Prozess-Sandbox des Servers; ohne sie laufen die Prozesse des Servers ohne. */\n processSandbox?: RunProcessSandboxes;\n /** Die Bash des Servers aus RAGENTS_BASH; unter Windows Pflicht f\u00FCr das Werkzeug bash. */\n bash?: string;\n /** Das rg des Servers aus RAGENTS_RG; ohne Angabe gilt eines im PATH. */\n rg?: string;\n /** Die Zeitgrenze von bash aus RAGENTS_BASH_TIMEOUT_SECONDS; ohne Angabe die des Werkzeugs. */\n bashTimeoutSeconds?: number;\n}\n\nconst runNotStarted = (): DomainError => new DomainError(\n \"run-not-started\",\n \"Der Run ist noch nicht gestartet; das Arbeitsverzeichnis entsteht mit der ersten Nachricht.\",\n 409,\n);\n\nconst lookAround = \"Look around in it before you say anything about the project.\";\n\nconst serverProjectDescription = (cwd: string): string => [\n \"# Working directory\",\n \"\",\n `Your working directory is \\`${cwd}\\` on the server: the project folder the user picked.`,\n `It is a real project. Work inside it, keep its structure, and never delete or reorganize files unless you are asked to. ${lookAround}`,\n].join(\"\\n\");\n\nconst clientProjectDescription = (projectPath: string, label: string): string => [\n \"# Working directory\",\n \"\",\n `Your working directory is the project folder \\`${projectPath}\\` on the workstation \"${label}\", not on the server.`,\n \"Every workspace tool runs there, and a relative path refers to that folder.\",\n `It is a real project. Keep its structure, and never delete or reorganize files unless you are asked to. ${lookAround}`,\n].join(\"\\n\");\n\nconst freshWorkstationDescription = (folderPath: string, label: string): string => [\n \"# Working directory\",\n \"\",\n `Your working directory is \\`${folderPath}\\` on the workstation \"${label}\", not on the server: a folder of this run alone.`,\n \"Every workspace tool runs there, and a relative path refers to that folder.\",\n \"It starts empty unless the profile prepared content in it. Look around in it before you say anything about what is already there.\",\n].join(\"\\n\");\n\nconst freshDescription = (cwd: string): string => [\n \"# Working directory\",\n \"\",\n `Your working directory is \\`${cwd}\\`, a private folder of this conversation on the server.`,\n \"No other conversation sees it, and it starts empty unless the profile prepared content in it.\",\n \"Look around in it before you say anything about what is already there.\",\n].join(\"\\n\");\n\nconst listed = (entries: readonly string[]): string =>\n entries.length === 1 ? entries[0]! : `${entries.slice(0, -1).join(\", \")} and ${entries.at(-1)!}`;\n\nconst rootList = (roots: readonly ServerRootDescription[]): string =>\n listed(roots.map((root) => `\\`${root.alias}\\` (${root.writable ? \"read and write\" : \"read only\"})`));\n\nconst variableList = (roots: readonly ServerRootDescription[]): string => listed(roots\n .flatMap((root) => root.environmentVariable === undefined ? [] : [`\\`$${root.environmentVariable}\\` for \\`${root.alias}\\``]));\n\nconst hasVariables = (roots: readonly ServerRootDescription[]): boolean => roots.some((root) => root.environmentVariable !== undefined);\n\n/** Auf dem Server liegen Arbeitsbereich und Wurzeln auf einer Maschine; jede Bash sieht beide. */\nconst serverRootsDescription = (roots: readonly ServerRootDescription[]): string => [\n \"## Roots besides the working directory\",\n \"\",\n `This run also reaches ${rootList(roots)}. File tools and language servers take a path that starts with the alias, `\n + `such as \\`${roots[0]!.alias}/<path>\\`; \\`bash\\` runs in such a root with that path as \\`cwd\\`.`\n + (hasVariables(roots) ? ` \\`bash\\` also has ${variableList(roots)}.` : \"\"),\n].join(\"\\n\");\n\n/** Die Wurzeln liegen auf dem Server, der Arbeitsbereich auf dem Arbeitsplatz; eine Bash sieht immer nur eine der beiden Maschinen. */\nconst workstationRootsDescription = (roots: readonly ServerRootDescription[]): string => [\n \"## Roots on the server\",\n \"\",\n `This run also reaches roots on the server: ${rootList(roots)}. File tools and language servers reach them from the `\n + `workstation as well: pass a path that starts with the alias, such as \\`${roots[0]!.alias}/<path>\\`. \\`bash\\` runs on `\n + \"the workstation; with a `cwd` that starts with an alias it runs on the server instead and sees only the server\"\n + (hasVariables(roots) ? `, and only that bash has ${variableList(roots)}` : \"\")\n + \". One call reaches one machine: never combine a path with an alias and a path in the working directory in one call.\",\n].join(\"\\n\");\n\nexport class RunWorkspaceRuntime implements WorkspaceRuntime {\n readonly sandbox: WorkspaceSandboxHost;\n readonly toolNaming: WorkspaceToolNaming = sandboxToolNaming;\n readonly transfer: WorkspaceTransfer;\n readonly #options: RunWorkspaceRuntimeOptions;\n readonly #nugetCacheDirectory: string;\n /** Die neuen Ordner auf Arbeitspl\u00E4tzen, die in diesem Serverlauf schon angelegt oder in Arbeit sind. */\n readonly #preparations = new Map<string, Promise<void>>();\n\n constructor(options: RunWorkspaceRuntimeOptions) {\n this.#options = options;\n this.transfer = {\n boundDirectory: (runId) => boundServerDirectory(options.runState(runId)),\n assertDirectory: (directory) => void serverDirectoryFolder(directory),\n rebind: (runId, directory) => options.storeBinding(runId, { machine: \"server\", folder: serverDirectoryFolder(directory) }),\n };\n this.#nugetCacheDirectory = path.join(options.globalDirectory, \"nuget-cache\");\n this.sandbox = new WorkspaceSandboxHost({\n contributorName: \"ragents.workspace.sandbox\",\n contributions: options.contributions,\n workspaceFor: options.sessionWorkspaceFor,\n identFor: () => Promise.resolve(undefined),\n skillPaths: options.skillPaths,\n storageRootFor: options.storageRootFor,\n homeFor: (runId) => this.#homeFor(runId),\n executorFor: (runId) => Promise.resolve(this.#executorFor(runId)),\n serverDirectoryFor: (runId) => this.#serverDirectoryFor(runId),\n ...(options.processSandbox ? { processSandbox: options.processSandbox } : {}),\n ...(options.bash === undefined ? {} : { bash: options.bash }),\n ...(options.rg === undefined ? {} : { rg: options.rg }),\n ...(options.bashTimeoutSeconds === undefined ? {} : { bashTimeoutSeconds: options.bashTimeoutSeconds }),\n });\n }\n\n /** Arbeit eines Runs, die auf dem Server l\u00E4uft, w\u00E4hrend sein Arbeitsbereich auf einem Arbeitsplatz liegt. */\n async #serverDirectoryFor(runId: string): Promise<string> {\n const directory = this.#options.sessionDirectory(runId, \"server\");\n await mkdir(directory, { recursive: true });\n return realpath(directory);\n }\n\n async #homeFor(runId: string): Promise<SandboxHomeEnvironment> {\n const home = this.#options.sessionDirectory(runId, \"home\");\n await mkdir(home, { recursive: true });\n await mkdir(this.#nugetCacheDirectory, { recursive: true });\n return { home, nugetPackages: this.#nugetCacheDirectory };\n }\n\n /** Auf einem Arbeitsplatz f\u00FChrt dessen Executor im Namen des Run-Eigent\u00FCmers aus, sonst der des Servers. */\n #executorFor(runId: string): WorkspaceExecutor | undefined {\n const state = this.#options.runState(runId);\n const binding = bindingOf(state);\n if (!isWorkstationBinding(binding)) return undefined;\n const { machine, folder } = binding;\n const executor = this.#options.clients.executorFor(workspaceOwnerOf(state), machine.client, machine.label, folder.path);\n return \"fresh\" in folder ? this.#preparing(state, binding, executor) : executor;\n }\n\n /** Vor dem ersten Auftrag eines Runs legt der Arbeitsplatz dessen neuen Ordner an; Aufr\u00E4umen legt nie einen an. */\n #preparing(state: RunState | null, binding: WorkstationBinding, executor: WorkspaceExecutor): WorkspaceExecutor {\n return {\n ...executor,\n execute: async (runId, operation, input, options = {}) => {\n if (!options.whenReachable) await this.#prepared(runId, state, binding, executor);\n return executor.execute(runId, operation, input, options);\n },\n };\n }\n\n #prepared(runId: string, state: RunState | null, binding: WorkstationBinding, executor: WorkspaceExecutor): Promise<void> {\n const known = this.#preparations.get(runId);\n if (known) return known;\n const preparation = this.#prepare(runId, state, binding, executor).catch((error: unknown) => {\n this.#preparations.delete(runId);\n throw error;\n });\n this.#preparations.set(runId, preparation);\n return preparation;\n }\n\n /** Nur ein eben angelegter Ordner bekommt die Schritte des Beitrags; scheitert einer, verschwindet er wieder, und der n\u00E4chste Auftrag beginnt neu. */\n async #prepare(runId: string, state: RunState | null, binding: WorkstationBinding, executor: WorkspaceExecutor): Promise<void> {\n const { created } = await executor.execute(runId, RUN_FOLDER_OPERATIONS.create, null) as RunFolderCreated;\n const steps = created ? this.#contribution()?.workstation?.prepare(this.#workstationContext(runId, state, binding)) ?? [] : [];\n try {\n await this.#runSteps(runId, executor, steps);\n } catch (error) {\n await executor.execute(runId, RUN_FOLDER_OPERATIONS.remove, null, { whenReachable: true });\n throw error;\n }\n }\n\n async #runSteps(runId: string, executor: WorkspaceExecutor, steps: readonly WorkspaceFolderStep[], options: WorkspaceExecuteOptions = {}): Promise<void> {\n for (const step of steps) await executor.execute(runId, step.operation, step.input, options);\n }\n\n #workstationContext(runId: string, state: RunState | null, binding: WorkstationBinding): WorkstationFolderContext {\n const contribution = this.#contribution();\n return {\n runId,\n path: binding.folder.path,\n label: binding.machine.label,\n choice: contribution && state ? this.#choiceFor(state, contribution) : null,\n };\n }\n\n async resolve(runId: string, emitSystem: (text: string) => void): Promise<SessionWorkspace> {\n const state = this.#options.runState(runId);\n if (!state) throw runNotStarted();\n const binding = bindingOf(state);\n const { folder } = binding;\n const onWorkstation = isWorkstationBinding(binding);\n const workspace = onWorkstation ? this.#workstation(runId, state, binding, emitSystem)\n : isFreshFolder(folder) ? await this.#fresh(runId, state, emitSystem) : this.#bound(folder, emitSystem);\n return this.#withRoots(workspace, onWorkstation);\n }\n\n /** Was der Prompt \u00FCber Wurzeln sagt, h\u00E4ngt an der Maschine des Runs: nur eine Bash auf dem Server kennt ihre Variablen. */\n async #withRoots(workspace: SessionWorkspace, onWorkstation: boolean): Promise<SessionWorkspace> {\n const roots = await this.sandbox.serverRoots();\n if (roots.length === 0) return workspace;\n const described = onWorkstation ? workstationRootsDescription(roots) : serverRootsDescription(roots);\n return { ...workspace, description: [workspace.description, described].filter(Boolean).join(\"\\n\\n\") };\n }\n\n placementOf(runId: string): WorkspacePlacement {\n const { machine, folder } = bindingOf(this.#options.runState(runId));\n const placement: WorkspacePlacement = {\n machine: machine === \"server\" ? \"server\" : \"client\",\n folder: isFreshFolder(folder) ? \"fresh\" : \"existing\",\n };\n const contribution = this.#contribution();\n const contributed = placement.folder === \"fresh\" && (placement.machine === \"server\" || contribution?.workstation !== undefined);\n const kind = contributed ? contribution?.kind?.id : undefined;\n return kind === undefined ? placement : { ...placement, kind };\n }\n\n async #fresh(runId: string, state: RunState, emitSystem: (text: string) => void): Promise<SessionWorkspace> {\n const resolver = this.#options.resolver();\n const directory = resolver?.kind\n ? this.#options.sessionDirectory(runId, \"workspace\")\n : await this.#sessionWorkspace(runId);\n if (!resolver) return this.#directory(directory, freshDescription(directory));\n const { cwd, description, currentRoot, runOperation, ...rest } = await resolver.resolve({\n runId,\n directory,\n choice: this.#choiceFor(state, resolver),\n emitSystem,\n });\n const resolved = path.resolve(cwd);\n return {\n ...this.#directory(resolved, description ?? freshDescription(resolved)),\n ...rest,\n ...(currentRoot ? { currentRoot } : {}),\n ...(runOperation ? { runOperation } : {}),\n };\n }\n\n #bound(folder: ExistingWorkspaceFolder, emitSystem: (text: string) => void): SessionWorkspace {\n const cwd = path.resolve(folder.path);\n const existing = async (): Promise<string> => {\n try {\n return await realpath(cwd);\n } catch {\n throw new DomainError(\"workspace-path-missing\", `Der gebundene Ordner ${cwd} existiert auf dem Server nicht mehr.`, 409);\n }\n };\n emitSystem(`Arbeitsbereich: ${cwd} (Projektordner auf dem Server)`);\n return {\n cwd,\n description: serverProjectDescription(cwd),\n currentRoot: existing,\n runOperation: (operation) => operation(),\n };\n }\n\n /** Der Arbeitsbereich liegt auf dem Arbeitsplatz; der Server kennt nur seinen Pfad, und jeder lokale Griff darauf scheitert laut. */\n #workstation(runId: string, state: RunState, binding: WorkstationBinding, emitSystem: (text: string) => void): SessionWorkspace {\n const { machine: { label }, folder } = binding;\n const fresh = \"fresh\" in folder;\n const workstation = this.#contribution()?.workstation;\n emitSystem(fresh\n ? `Arbeitsbereich: ${folder.path} (${workstation?.label ?? FRESH_WORKSPACE_LABEL} auf dem Arbeitsplatz ${label})`\n : `Arbeitsbereich: ${folder.path} (Projektordner auf dem Arbeitsplatz ${label})`);\n const remote = (): Promise<string> => Promise.reject(new Error(\n `Der Arbeitsbereich ${folder.path} liegt auf dem Arbeitsplatz ${label}, nicht auf dem Server; `\n + \"er ist nur \u00FCber den Executor des Runs (SandboxServices.execute) erreichbar.\",\n ));\n const description = !fresh\n ? clientProjectDescription(folder.path, label)\n : workstation?.description?.(this.#workstationContext(runId, state, binding)) ?? freshWorkstationDescription(folder.path, label);\n return {\n cwd: folder.path,\n description,\n currentRoot: remote,\n runOperation: (operation) => operation(),\n };\n }\n\n async #sessionWorkspace(runId: string): Promise<string> {\n const directory = this.#options.sessionDirectory(runId, \"workspace\");\n await mkdir(directory, { recursive: true });\n return directory;\n }\n\n #directory(cwd: string, description: string, extraEnv?: NodeJS.ProcessEnv): SessionWorkspace {\n return {\n cwd,\n description,\n ...(extraEnv ? { extraEnv } : {}),\n currentRoot: () => realpath(cwd),\n runOperation: (operation) => operation(),\n };\n }\n\n #choiceFor(state: RunState, resolver: WorkspaceResolver): JsonValue | null {\n if (resolver.optionId === undefined) return null;\n const choice = storedStartOption(state, resolver.optionId);\n if (choice === undefined) {\n throw new Error(`Die Startoption ${resolver.optionId} des Workspace-Resolvers ist im Run nicht gespeichert`);\n }\n return choice;\n }\n\n describe(): WorkspaceRuntimeDescription {\n return {\n mode: \"per-run\",\n directoryPattern: this.#contribution()?.kind?.directoryPattern\n ?? path.join(this.#options.sessionsDirectoryPattern, \"workspace\"),\n };\n }\n\n #contribution(): WorkspaceResolver | undefined {\n return this.#options.resolver();\n }\n\n /** Auf dem Server geh\u00F6rt ein neuer Ordner samt Stopp und L\u00F6schen dem Beitrag; auf einem Arbeitsplatz r\u00E4umt ihn der Host weg. */\n #serverContributionFor(runId: string): WorkspaceResolver | undefined {\n const { machine, folder } = bindingOf(this.#options.runState(runId));\n return machine === \"server\" && isFreshFolder(folder) ? this.#contribution() : undefined;\n }\n\n /** Ist der Arbeitsplatz nicht erreichbar, bleibt der Ordner dort mit Hinweis liegen; der Run ist trotzdem gel\u00F6scht. */\n async #removeWorkstationFolder(runId: string): Promise<void> {\n this.#preparations.delete(runId);\n const state = this.#options.runState(runId);\n const binding = bindingOf(state);\n if (!isWorkstationBinding(binding) || !(\"fresh\" in binding.folder)) return;\n const { machine, folder } = binding;\n const executor = this.#options.clients.executorFor(workspaceOwnerOf(state), machine.client, machine.label, folder.path);\n const steps = this.#contribution()?.workstation?.release?.(this.#workstationContext(runId, state, binding)) ?? [];\n await this.#runSteps(runId, executor, steps, { whenReachable: true });\n if (await executor.execute(runId, RUN_FOLDER_OPERATIONS.remove, null, { whenReachable: true }) !== null) return;\n console.warn(`Der Ordner ${folder.path} des Runs ${runId} bleibt auf dem Arbeitsplatz ${machine.label}, weil er nicht erreichbar war.`);\n }\n\n async deleteSession(runId: string): Promise<void> {\n const contribution = this.#serverContributionFor(runId);\n await this.stopSession(runId);\n await this.#removeWorkstationFolder(runId);\n await contribution?.deleteSession?.(runId);\n }\n\n stopSession(runId: string): Promise<void> {\n const contribution = this.#serverContributionFor(runId);\n const sandbox = (): Promise<void> => this.sandbox.shutdown(runId);\n return contribution?.stopSession ? contribution.stopSession(runId, sandbox) : sandbox();\n }\n\n async shutdown(): Promise<void> {\n await this.sandbox.shutdownAll();\n this.#options.clients.shutdown();\n }\n}\n"],
|
|
5
|
+
"mappings": "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",
|
|
6
|
+
"names": ["path", "DomainError", "boundToTools", "Type", "Type", "listing", "DomainError", "implement", "DomainError", "plugin", "implement", "path", "DomainError", "storedStartOption", "DomainError", "path", "described", "storedStartOption", "DomainError", "path", "contribution", "boundToTools"]
|
|
7
7
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
["--accent","--destructive","--row-indent","--warning","[&>svg]:rotate-90","ab","absolutePath","additionalProperties","aktualisieren","alert","alive","all","als","angemeldeten","animate-spin","anlegt","anmelden","anzeigen","aria-hidden","aria-label","as","async","at","auch","auf","aufrufende","aus","ausblenden","available","await","bash","bei","beim","beobachteten","bg-destructive/8","bindet","binding","bindingFrom","bindingOf","blue","boolean","border-b-border-soft","border-border-soft","border-t","border-t-0","border-x-0","braucht","break-words","browse","browseTarget","busy","byExtension","byName","bytes","case","catch","cause","changed","channels","chooseFolder","chooseMachine","chooseOffered","chosenRoot","cjs","className","client","clientDescription","clientId","clientInfoSchema","clients","commit","const","content","cs","csproj","css","cts","current","currentColor","cwd","damit","das","data-selected","data-selected:bg-primary/12","data-selected:text-primary","de-DE","default","defineOperation","dem","den","depth","der","des","description","dessen","destructive","die","dieselbe","dieser","directory","disabled","dockerfile","dort","draft","eigenen","ein","eindeutig","eine","einem","einen","eines","eingefroren","eingefrorener","else","emptyHints","entries","entry","env","errorClass","erscheinen","es","etwa","execute","executor","executorVersion","existing","expanded","expandedRef","export","extends","extension","false","fetchBrowseListing","fetchBrowsePreview","file","fileIconFor","fileToneClass","files","fill","finally","flex","flex-1","flex-col","flex-none","flex-wrap","folder","folderChoices","folderDraft","folderOf","folders","font-medium","font-mono","font-normal","font-semibold","fremde","fresh","freshLabelOf","freshLabelsOf","freshServerBinding","from","fromKind","fs","fsproj","fsx","full","function","gap-1","gap-1.5","gap-2","gebunden","gebundenen","gespeicherte","ghost","gibt","gif","gitignore","gone","green","gt","gz","h-7","h-auto","h-full","hasExactly","hbs","height","hier","hostname","htm","html","htmlFor","ico","icon","id","if","ihn","ihr","im","implementedBy","import","in","indent","ini","inline-flex","input","ins","inspect","instanceof","interface","is","isClientInfo","isFolder","isFreshFolder","isFreshLabels","isMachine","isRecord","isWorkspaceBinding","ist","items","items-center","items-end","items-start","je","jede","jedem","jpeg","jpg","js","json","jsx","justify-center","justify-start","keine","keinen","key","keyRef","keys","kind","label","labelClass","labels","leading-[1.45]","leer","leere","left","legt","length","lesbar","let","liefert","liegt","list","listing","load","location","lock","lucide-react","machine","machineDraft","machineOf","machines","mapped","max-w-full","maxItems","maxLength","md","message","messageOf","metadata","min-h-0","min-h-30","min-w-0","min-w-[15rem]","minLength","missing","mit","mitbringt","mjs","modifiedAt","mts","muted","name","named","nennen","neue","neuen","neuer","new","next","nextFolder","nextMachine","nextPath","nicht","noch","none","null","number","nur","ob","object","oder","offene","offered","ohne","onBlur","onChange","onClick","onKeyDown","onPressedChange","onValueChange","open","openFile","openJson","operation","option","optionId","orange","order","outline","overflow-auto","overflow-hidden","p-7","params","parse","parsed","path","pathId","pathOf","pattern","pb-1.5","pb-2","pb-2.5","pdf","pink","pl-(--row-indent)","pl-px","placeholder","platform","png","pr-2.5","presentation","presentationFrom","pressed","preview","previewSourceClass","previewable","pt-0","pt-0.5","px","px-2.5","py","py-1","py-1.5","py-2","py-[3px]","raw","reachable","react","read","readRight","readonly","reason","red","register","renderLevel","result","results","return","right","rights","role","root","rootLabels","rootListing","roots","round","rounded-none","rowClass","rpc","ruft","runId","runsDirectory","sameBinding","saved","schon","sein","seine","seinen","seiner","selbst","selected","server","serverFolders","session","sessionMetadata","setDraft","setError","setExpanded","setFolder","setListings","setMachine","setPending","setPreview","setReload","setRoot","setSelected","setShowHidden","setValue","sh","showHidden","shrink-0","sich","sie","sind","size","size-3","size-3.5","sizeLabel","sln","slnx","sm","startOptions","stateKey","stattdessen","stop","storedWorkspaceBinding","string","stroke","strokeLinecap","strokeLinejoin","strokeWidth","style","summary","svg","switch","tabular-nums","tar","targets","teal","text","text-[0.64rem]","text-[0.66rem]","text-[0.68rem]","text-[0.72rem]","text-[0.75rem]","text-[0.7rem]","text-[color-mix(in_srgb,var(--destructive)_65%,var(--accent))]","text-[color-mix(in_srgb,var(--warning)_75%,var(--destructive))]","text-destructive","text-info","text-left","text-muted-foreground","text-primary","text-sm","text-success","text-teal","text-warning","text-xs","throw","timeLabel","timer","title","toggleDirectory","toml","tone","toolCallId","tragen","treeMemory","truncate","truncated","try","ts","tsx","txt","type","typebox","typeof","und","undefined","unknown","unlesbar","unregister","unsubscribe","unter","unterhalb","useState","value","variant","verbundenen","viewBox","violet","visible","void","von","vor","vorhandenen","vorhandener","w-3","w-full","was","webPlugin","webp","weder","welchem","werden","where","whitespace-pre-wrap","width","wie","wird","wo","workspace","workspace-binding","workspaceBindingSummary","workspaceClientContracts","workspaceContracts","workspaceFolderChoices","workspaceMachineChoices","workspaceMetadataFrom","workspaceTabs","write","yaml","yellow","yml","zip","zsh","zu"]
|
|
1
|
+
["--accent","--destructive","--row-indent","--warning","[&>svg]:rotate-90","ab","absolutePath","additionalProperties","aktualisieren","alert","alive","all","als","an","anderem","anderen","angemeldeten","animate-spin","anlegt","anmelden","anzeigen","aria-hidden","aria-label","as","async","at","auch","auf","aufrufende","aus","ausblenden","available","await","bash","bei","beim","beliebiger","beobachteten","bevor","bg-destructive/8","bindet","binding","bindingFrom","bindingOf","blue","boolean","border-b-border-soft","border-border-soft","border-t","border-t-0","border-x-0","braucht","break-words","browse","browseTarget","busy","byExtension","byName","bytes","case","catch","cause","changed","channels","chooseFolder","chooseMachine","chooseOffered","chosenRoot","cjs","className","client","clientDescription","clientId","clientInfoSchema","clientRegistrationSchema","clients","commit","const","content","contributions","cs","csproj","css","cts","current","currentColor","cwd","damit","darin","das","data-selected","data-selected:bg-primary/12","data-selected:text-primary","de-DE","default","defineOperation","dem","den","depth","der","des","description","dessen","destructive","die","dieselbe","diesem","dieser","dieses","directory","disabled","dockerfile","dort","draft","eigenen","ein","eindeutig","eine","einem","einen","eines","eingefroren","eingefrorener","else","emptyHints","entries","entry","env","errorClass","erscheinen","es","etwa","execute","executor","executorContributions","executorVersion","existing","expanded","expandedRef","export","extends","extension","false","fetchBrowseListing","fetchBrowsePreview","file","fileIconFor","fileToneClass","files","fill","finally","findet","flex","flex-1","flex-col","flex-none","flex-wrap","folder","folderChoices","folderDraft","folderOf","folders","font-medium","font-mono","font-normal","font-semibold","fremde","fresh","freshLabelOf","freshLabelsOf","freshServerBinding","from","fromKind","fs","fsproj","fsx","full","function","gap-1","gap-1.5","gap-2","gebunden","gebundenen","genau","gespeicherte","ghost","gibt","gif","gitignore","gone","green","gt","gz","h-7","h-auto","h-full","hasExactly","hbs","height","hier","hostname","htm","html","htmlFor","ico","icon","id","if","ihn","ihr","im","implementedBy","import","in","indent","ini","inline-flex","input","ins","inspect","instanceof","interface","is","isClientInfo","isFolder","isFreshFolder","isFreshLabels","isMachine","isRecord","isWorkspaceBinding","ist","items","items-center","items-end","items-start","je","jede","jedem","jpeg","jpg","js","json","jsx","justify-center","justify-start","kann","keine","keinen","kennt","key","keyRef","keys","kind","label","labelClass","labels","leading-[1.45]","leer","leere","left","legt","lehnt","length","lesbar","let","liefert","liegt","list","listing","load","location","lock","lucide-react","machine","machineDraft","machineOf","machines","mapped","max-w-full","maxItems","maxLength","md","message","messageOf","metadata","min-h-0","min-h-30","min-w-0","min-w-[15rem]","minLength","missing","mit","mitbringt","mjs","modifiedAt","mts","muted","name","named","nennen","neue","neuen","neuer","new","next","nextFolder","nextMachine","nextPath","nicht","noch","none","null","number","nur","ob","object","oder","offene","offered","ohne","onBlur","onChange","onClick","onKeyDown","onPressedChange","onValueChange","open","openFile","openJson","operation","option","optionId","orange","order","otherExecutorRegistration","outline","overflow-auto","overflow-hidden","p-7","params","parse","parsed","path","pathId","pathOf","pattern","pb-1.5","pb-2","pb-2.5","pdf","pink","pl-(--row-indent)","pl-px","placeholder","platform","plugin","png","pr-2.5","presentation","presentationFrom","pressed","preview","previewSourceClass","previewable","pt-0","pt-0.5","px","px-2.5","py","py-1","py-1.5","py-2","py-[3px]","raw","reachable","react","read","readRight","readonly","reason","red","register","renderLevel","result","results","return","rg","richtet","right","rights","ripgrep","role","root","rootLabels","rootListing","roots","round","rounded-none","rowClass","rpc","ruft","runId","runsDirectory","sameBinding","saved","scheitert","schon","sein","seine","seinem","seinen","seiner","selbst","selected","server","serverFolders","session","sessionMetadata","setDraft","setError","setExpanded","setFolder","setListings","setMachine","setPending","setPreview","setReload","setRoot","setSelected","setShowHidden","setValue","sh","showHidden","shrink-0","sich","sie","sind","size","size-3","size-3.5","sizeLabel","sln","slnx","sm","stand","startOptions","stateKey","stattdessen","stop","storedWorkspaceBinding","string","stroke","strokeLinecap","strokeLinejoin","strokeWidth","style","sucht","summary","svg","switch","tabular-nums","tar","targets","teal","text","text-[0.64rem]","text-[0.66rem]","text-[0.68rem]","text-[0.72rem]","text-[0.75rem]","text-[0.7rem]","text-[color-mix(in_srgb,var(--destructive)_65%,var(--accent))]","text-[color-mix(in_srgb,var(--warning)_75%,var(--destructive))]","text-destructive","text-info","text-left","text-muted-foreground","text-primary","text-sm","text-success","text-teal","text-warning","text-xs","throw","timeLabel","timer","title","toggleDirectory","toml","tone","toolCallId","tragen","treeMemory","truncate","truncated","try","ts","tsx","txt","type","typebox","typeof","und","undefined","unknown","unlesbar","unregister","unsubscribe","unter","unterhalb","useState","value","variant","verbundenen","viewBox","violet","visible","void","von","vor","vorhandenen","vorhandener","w-3","w-full","was","webPlugin","webp","weder","weitere","welchem","werden","where","whitespace-pre-wrap","width","wie","wird","wo","workspace","workspace-binding","workspace-executor-version","workspaceBindingSummary","workspaceClientContracts","workspaceContracts","workspaceFolderChoices","workspaceMachineChoices","workspaceMetadataFrom","workspaceTabs","write","yaml","yellow","yml","zip","zsh","zu","zum"]
|