@greppleai/grip 0.0.1 → 0.1.3
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/CHANGELOG.md +93 -0
- package/README.md +13 -7
- package/dist/bun/cli.d.ts.map +1 -1
- package/dist/bun/cli.js +4 -2
- package/dist/bun/cli.js.map +1 -1
- package/dist/bun/embedded-assets.d.ts +3 -0
- package/dist/bun/embedded-assets.d.ts.map +1 -0
- package/dist/bun/embedded-assets.js +52 -0
- package/dist/bun/embedded-assets.js.map +1 -0
- package/dist/cli/args.d.ts.map +1 -1
- package/dist/cli/args.js +1 -0
- package/dist/cli/args.js.map +1 -1
- package/dist/config.d.ts.map +1 -1
- package/dist/config.js +3 -3
- package/dist/config.js.map +1 -1
- package/dist/core/agent-session.d.ts.map +1 -1
- package/dist/core/agent-session.js +17 -2
- package/dist/core/agent-session.js.map +1 -1
- package/dist/core/remote-workspace-protocol/contract.d.ts +13 -4
- package/dist/core/remote-workspace-protocol/contract.d.ts.map +1 -1
- package/dist/core/remote-workspace-protocol/contract.js +17 -1
- package/dist/core/remote-workspace-protocol/contract.js.map +1 -1
- package/dist/core/remote-workspace-protocol/guest-shared-client.d.ts +16 -0
- package/dist/core/remote-workspace-protocol/guest-shared-client.d.ts.map +1 -0
- package/dist/core/remote-workspace-protocol/guest-shared-client.js +54 -0
- package/dist/core/remote-workspace-protocol/guest-shared-client.js.map +1 -0
- package/dist/core/remote-workspace-protocol/guest-shared-outbound-scheduler.d.ts +23 -0
- package/dist/core/remote-workspace-protocol/guest-shared-outbound-scheduler.d.ts.map +1 -0
- package/dist/core/remote-workspace-protocol/guest-shared-outbound-scheduler.js +112 -0
- package/dist/core/remote-workspace-protocol/guest-shared-outbound-scheduler.js.map +1 -0
- package/dist/core/remote-workspace-protocol/guest-shared-uplink.d.ts +30 -0
- package/dist/core/remote-workspace-protocol/guest-shared-uplink.d.ts.map +1 -0
- package/dist/core/remote-workspace-protocol/guest-shared-uplink.js +243 -0
- package/dist/core/remote-workspace-protocol/guest-shared-uplink.js.map +1 -0
- package/dist/core/remote-workspace-protocol/lima-owner-directory.d.ts +3 -0
- package/dist/core/remote-workspace-protocol/lima-owner-directory.d.ts.map +1 -0
- package/dist/core/remote-workspace-protocol/lima-owner-directory.js +31 -0
- package/dist/core/remote-workspace-protocol/lima-owner-directory.js.map +1 -0
- package/dist/core/remote-workspace-protocol/lima-owner-lock.d.ts +9 -0
- package/dist/core/remote-workspace-protocol/lima-owner-lock.d.ts.map +1 -0
- package/dist/core/remote-workspace-protocol/lima-owner-lock.js +89 -0
- package/dist/core/remote-workspace-protocol/lima-owner-lock.js.map +1 -0
- package/dist/core/remote-workspace-protocol/session.d.ts +2 -0
- package/dist/core/remote-workspace-protocol/session.d.ts.map +1 -1
- package/dist/core/remote-workspace-protocol/session.js +3 -0
- package/dist/core/remote-workspace-protocol/session.js.map +1 -1
- package/dist/core/remote-workspace-protocol/shared-transport.d.ts +71 -0
- package/dist/core/remote-workspace-protocol/shared-transport.d.ts.map +1 -0
- package/dist/core/remote-workspace-protocol/shared-transport.js +68 -0
- package/dist/core/remote-workspace-protocol/shared-transport.js.map +1 -0
- package/dist/core/sandbox/command.d.ts +2 -4
- package/dist/core/sandbox/command.d.ts.map +1 -1
- package/dist/core/sandbox/command.js +24 -46
- package/dist/core/sandbox/command.js.map +1 -1
- package/dist/core/sandbox/config.d.ts +91 -0
- package/dist/core/sandbox/config.d.ts.map +1 -0
- package/dist/core/sandbox/config.js +88 -0
- package/dist/core/sandbox/config.js.map +1 -0
- package/dist/core/sandbox/lima-guest-binary.d.ts +11 -0
- package/dist/core/sandbox/lima-guest-binary.d.ts.map +1 -0
- package/dist/core/sandbox/lima-guest-binary.js +140 -0
- package/dist/core/sandbox/lima-guest-binary.js.map +1 -0
- package/dist/core/sandbox/lima.d.ts +22 -3
- package/dist/core/sandbox/lima.d.ts.map +1 -1
- package/dist/core/sandbox/lima.js +434 -42
- package/dist/core/sandbox/lima.js.map +1 -1
- package/dist/core/sandbox/shared-lima-roots.d.ts +11 -0
- package/dist/core/sandbox/shared-lima-roots.d.ts.map +1 -0
- package/dist/core/sandbox/shared-lima-roots.js +25 -0
- package/dist/core/sandbox/shared-lima-roots.js.map +1 -0
- package/dist/core/sandbox/update-shared-guest-binary.d.ts +8 -0
- package/dist/core/sandbox/update-shared-guest-binary.d.ts.map +1 -0
- package/dist/core/sandbox/update-shared-guest-binary.js +100 -0
- package/dist/core/sandbox/update-shared-guest-binary.js.map +1 -0
- package/dist/core/settings-manager.d.ts +1 -5
- package/dist/core/settings-manager.d.ts.map +1 -1
- package/dist/core/settings-manager.js.map +1 -1
- package/dist/core/tools/bash.d.ts.map +1 -1
- package/dist/core/tools/bash.js +25 -14
- package/dist/core/tools/bash.js.map +1 -1
- package/dist/core/tools/file-mutation-queue.d.ts +2 -0
- package/dist/core/tools/file-mutation-queue.d.ts.map +1 -1
- package/dist/core/tools/file-mutation-queue.js +9 -0
- package/dist/core/tools/file-mutation-queue.js.map +1 -1
- package/dist/core/tools/operations.d.ts +13 -2
- package/dist/core/tools/operations.d.ts.map +1 -1
- package/dist/core/tools/operations.js +132 -36
- package/dist/core/tools/operations.js.map +1 -1
- package/dist/daemon/activity-budget.d.ts +10 -0
- package/dist/daemon/activity-budget.d.ts.map +1 -0
- package/dist/daemon/activity-budget.js +34 -0
- package/dist/daemon/activity-budget.js.map +1 -0
- package/dist/daemon/config.d.ts +2 -0
- package/dist/daemon/config.d.ts.map +1 -1
- package/dist/daemon/config.js +15 -0
- package/dist/daemon/config.js.map +1 -1
- package/dist/daemon/outbound-budget.d.ts +10 -0
- package/dist/daemon/outbound-budget.d.ts.map +1 -0
- package/dist/daemon/outbound-budget.js +30 -0
- package/dist/daemon/outbound-budget.js.map +1 -0
- package/dist/daemon/security.d.ts.map +1 -1
- package/dist/daemon/security.js +3 -1
- package/dist/daemon/security.js.map +1 -1
- package/dist/daemon/server.d.ts.map +1 -1
- package/dist/daemon/server.js +104 -24
- package/dist/daemon/server.js.map +1 -1
- package/dist/daemon/shared-connection.d.ts +33 -0
- package/dist/daemon/shared-connection.d.ts.map +1 -0
- package/dist/daemon/shared-connection.js +271 -0
- package/dist/daemon/shared-connection.js.map +1 -0
- package/dist/daemon/shared-revision.d.ts +5 -0
- package/dist/daemon/shared-revision.d.ts.map +1 -0
- package/dist/daemon/shared-revision.js +61 -0
- package/dist/daemon/shared-revision.js.map +1 -0
- package/dist/daemon/shared-roots.d.ts +9 -0
- package/dist/daemon/shared-roots.d.ts.map +1 -0
- package/dist/daemon/shared-roots.js +33 -0
- package/dist/daemon/shared-roots.js.map +1 -0
- package/dist/daemon/workspace-runtime.d.ts +1 -1
- package/dist/daemon/workspace-runtime.d.ts.map +1 -1
- package/dist/daemon/workspace-runtime.js +42 -10
- package/dist/daemon/workspace-runtime.js.map +1 -1
- package/dist/main.d.ts.map +1 -1
- package/dist/main.js +5 -3
- package/dist/main.js.map +1 -1
- package/dist/modes/interactive/components/assistant-message.d.ts +1 -0
- package/dist/modes/interactive/components/assistant-message.d.ts.map +1 -1
- package/dist/modes/interactive/components/assistant-message.js +13 -3
- package/dist/modes/interactive/components/assistant-message.js.map +1 -1
- package/dist/modes/interactive/components/branch-summary-message.d.ts +4 -3
- package/dist/modes/interactive/components/branch-summary-message.d.ts.map +1 -1
- package/dist/modes/interactive/components/branch-summary-message.js +5 -4
- package/dist/modes/interactive/components/branch-summary-message.js.map +1 -1
- package/dist/modes/interactive/components/compaction-summary-message.d.ts +4 -3
- package/dist/modes/interactive/components/compaction-summary-message.d.ts.map +1 -1
- package/dist/modes/interactive/components/compaction-summary-message.js +5 -4
- package/dist/modes/interactive/components/compaction-summary-message.js.map +1 -1
- package/dist/modes/interactive/components/custom-message.d.ts.map +1 -1
- package/dist/modes/interactive/components/custom-message.js +4 -3
- package/dist/modes/interactive/components/custom-message.js.map +1 -1
- package/dist/modes/interactive/components/hook-execution.d.ts.map +1 -1
- package/dist/modes/interactive/components/hook-execution.js +3 -2
- package/dist/modes/interactive/components/hook-execution.js.map +1 -1
- package/dist/modes/interactive/components/message-card.d.ts +9 -0
- package/dist/modes/interactive/components/message-card.d.ts.map +1 -0
- package/dist/modes/interactive/components/message-card.js +24 -0
- package/dist/modes/interactive/components/message-card.js.map +1 -0
- package/dist/modes/interactive/components/skill-invocation-message.d.ts +4 -3
- package/dist/modes/interactive/components/skill-invocation-message.d.ts.map +1 -1
- package/dist/modes/interactive/components/skill-invocation-message.js +5 -4
- package/dist/modes/interactive/components/skill-invocation-message.js.map +1 -1
- package/dist/modes/interactive/components/tool-execution.d.ts +1 -1
- package/dist/modes/interactive/components/tool-execution.d.ts.map +1 -1
- package/dist/modes/interactive/components/tool-execution.js +27 -21
- package/dist/modes/interactive/components/tool-execution.js.map +1 -1
- package/dist/modes/interactive/components/user-message.d.ts.map +1 -1
- package/dist/modes/interactive/components/user-message.js +3 -2
- package/dist/modes/interactive/components/user-message.js.map +1 -1
- package/dist/modes/interactive/interactive-mode.d.ts +0 -3
- package/dist/modes/interactive/interactive-mode.d.ts.map +1 -1
- package/dist/modes/interactive/interactive-mode.js +55 -44
- package/dist/modes/interactive/interactive-mode.js.map +1 -1
- package/dist/modes/interactive/theme/theme.d.ts +3 -0
- package/dist/modes/interactive/theme/theme.d.ts.map +1 -1
- package/dist/modes/interactive/theme/theme.js +10 -0
- package/dist/modes/interactive/theme/theme.js.map +1 -1
- package/dist/utils/clipboard-native.d.ts.map +1 -1
- package/dist/utils/clipboard-native.js +1 -1
- package/dist/utils/clipboard-native.js.map +1 -1
- package/dist/utils/image-resize.d.ts.map +1 -1
- package/dist/utils/image-resize.js +5 -0
- package/dist/utils/image-resize.js.map +1 -1
- package/dist/utils/photon.d.ts.map +1 -1
- package/dist/utils/photon.js +1 -0
- package/dist/utils/photon.js.map +1 -1
- package/docs/daemon.md +6 -4
- package/docs/docs.json +1 -1
- package/docs/index.md +8 -12
- package/docs/packages.md +3 -3
- package/docs/quickstart.md +11 -19
- package/docs/sandbox.md +40 -117
- package/docs/settings.md +12 -11
- package/docs/termux.md +1 -18
- package/docs/usage.md +2 -2
- package/examples/README.md +0 -2
- package/examples/extensions/custom-provider-anthropic/package.json +1 -1
- package/examples/extensions/custom-provider-gitlab-duo/package.json +1 -1
- package/examples/extensions/sandbox/package.json +1 -1
- package/examples/extensions/with-deps/package.json +1 -1
- package/npm-shrinkwrap.json +12 -12
- package/package.json +5 -6
- package/dist/core/sandbox/docker.d.ts +0 -169
- package/dist/core/sandbox/docker.d.ts.map +0 -1
- package/dist/core/sandbox/docker.js +0 -633
- package/dist/core/sandbox/docker.js.map +0 -1
- package/examples/sandbox-docker/Dockerfile +0 -274
- package/examples/sandbox-docker/README.md +0 -88
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"workspace-runtime.d.ts","sourceRoot":"","sources":["../../src/daemon/workspace-runtime.ts"],"names":[],"mappings":"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","sourcesContent":["import { spawn } from \"node:child_process\";\nimport { randomUUID } from \"node:crypto\";\nimport { mkdir as fsMkdir, lstat, open, readFile, realpath, rename, rm } from \"node:fs/promises\";\nimport { basename, isAbsolute, relative, resolve, sep } from \"node:path\";\nimport type { AgentToolResult } from \"@greppleai/grip-agent-core\";\nimport { createLspRuntimeState, createLspToolDefinitions, type LspRuntimeState } from \"../core/lsp/integration.ts\";\nimport type { LspServerStatus } from \"../core/lsp/manager.ts\";\nimport { createManagedStdioConnectionFactory, resolveLspConnectionFactory } from \"../core/lsp/transport.ts\";\nimport {\n\thashRemoteWorkspaceJson,\n\ttype RemoteWorkspaceCapability,\n\ttype RemoteWorkspaceCatalog,\n\ttype RemoteWorkspaceIdentity,\n\ttype RemoteWorkspaceMethod,\n\ttype RemoteWorkspaceOperationKind,\n} from \"../core/remote-workspace-protocol/contract.ts\";\nimport {\n\tRemoteWorkspaceRequestError,\n\ttype RemoteWorkspaceServerHandler,\n\ttype RemoteWorkspaceServerRequestContext,\n\ttype RemoteWorkspaceTypedRequest,\n} from \"../core/remote-workspace-protocol/session.ts\";\nimport { withFileMutationQueue } from \"../core/tools/file-mutation-queue.ts\";\nimport {\n\tGRIP_SESSION_ENVIRONMENT_NAMES,\n\tLocalToolOperations,\n\ttype ToolAccessMode,\n\ttype ToolBackendInfo,\n\ttype ToolExecOptions,\n\ttype ToolExecResult,\n\ttype ToolFileStat,\n\ttype ToolGlobOptions,\n\ttype ToolGrepMatch,\n\ttype ToolGrepOptions,\n\ttype ToolGrepResult,\n\ttype ToolMkdirOptions,\n\ttype ToolOperations,\n\ttype WorkspaceToolExecutionOptions,\n} from \"../core/tools/operations.ts\";\nimport { WorkspaceToolHost, type WorkspaceToolName } from \"../core/tools/workspace-tool-host.ts\";\nimport type { DaemonConfiguration } from \"./config.ts\";\nimport { loadDaemonLspConfiguration } from \"./lsp-config.ts\";\nimport { redactDaemonText } from \"./security.ts\";\n\nconst PRIMITIVE_OPERATIONS: RemoteWorkspaceMethod[] = [\n\t\"workspace.access\",\n\t\"workspace.read\",\n\t\"workspace.write\",\n\t\"workspace.mkdir\",\n\t\"workspace.stat\",\n\t\"workspace.readdir\",\n\t\"workspace.glob\",\n\t\"workspace.grep\",\n\t\"workspace.detect_image_mime\",\n\t\"workspace.exec\",\n];\n\nconst SECRET_ENVIRONMENT_SUFFIX = /_(?:API_KEY|TOKEN|SECRET|PASSWORD|PRIVATE_KEY|CREDENTIALS)$/iu;\nconst BASELINE_ENVIRONMENT =\n\tprocess.platform === \"win32\"\n\t\t? [\"PATH\", \"PATHEXT\", \"SYSTEMROOT\", \"COMSPEC\", \"TEMP\", \"TMP\", \"USER\", \"USERNAME\"]\n\t\t: [\"PATH\", \"HOME\", \"USER\", \"LOGNAME\", \"SHELL\", \"LANG\", \"TERM\", \"COLORTERM\", \"NO_COLOR\", \"TMPDIR\"];\n\nfunction isSecretEnvironmentName(name: string): boolean {\n\tconst upper = name.toUpperCase();\n\treturn (\n\t\tupper === \"GRIP_DAEMON_TOKEN\" ||\n\t\tupper === \"PI_DAEMON_TOKEN\" ||\n\t\tupper === \"GRIP_REMOTE_TOKEN\" ||\n\t\tupper.startsWith(\"GRIP_DAEMON_TLS_\") ||\n\t\tupper.startsWith(\"PI_DAEMON_TLS_\") ||\n\t\tSECRET_ENVIRONMENT_SUFFIX.test(upper)\n\t);\n}\nprocess.platform === \"win32\"\n\t? [\"PATH\", \"PATHEXT\", \"SYSTEMROOT\", \"TEMP\", \"TMP\"]\n\t: [\"PATH\", \"HOME\", \"LANG\", \"LC_ALL\", \"TERM\", \"TMPDIR\"];\n\nfunction isMissingPath(error: unknown): boolean {\n\treturn error instanceof Error && \"code\" in error && error.code === \"ENOENT\";\n}\n\nfunction sanitizeLspStatus(\n\tstatus: LspServerStatus,\n\tconfiguration: DaemonConfiguration,\n): Omit<LspServerStatus, \"capabilities\"> {\n\tconst { capabilities: _capabilities, ...safe } = status;\n\tconst secrets = [configuration.token, configuration.tls?.passphrase];\n\tconst redact = (value: string | undefined) => (value ? redactDaemonText(value, secrets) : undefined);\n\treturn {\n\t\t...safe,\n\t\tserverId: redact(safe.serverId)!,\n\t\tlanguageIds: safe.languageIds.map((value) => redact(value)!),\n\t\ttransport: redact(safe.transport)!,\n\t\t...(safe.instanceKey ? { instanceKey: redact(safe.instanceKey) } : {}),\n\t\t...(safe.workspaceRoot ? { workspaceRoot: redact(safe.workspaceRoot) } : {}),\n\t\t...(safe.rootUri ? { rootUri: redact(safe.rootUri) } : {}),\n\t\t...(safe.endpoint ? { endpoint: redact(safe.endpoint) } : {}),\n\t\t...(safe.lastError ? { lastError: redact(safe.lastError) } : {}),\n\t\t...(safe.lastRequestError ? { lastRequestError: redact(safe.lastRequestError) } : {}),\n\t\t...(safe.stderr ? { stderr: redact(safe.stderr) } : {}),\n\t\t...(safe.synchronizationError ? { synchronizationError: redact(safe.synchronizationError) } : {}),\n\t};\n}\n\nfunction portableToolResult(result: AgentToolResult<unknown>): AgentToolResult<unknown> {\n\tconst clone = JSON.parse(JSON.stringify(result)) as AgentToolResult<unknown>;\n\tconst details = clone.details;\n\tif (!details || typeof details !== \"object\" || !(\"fullOutputPath\" in details)) return clone;\n\tconst fullOutputPath = (details as { fullOutputPath?: unknown }).fullOutputPath;\n\tif (typeof fullOutputPath !== \"string\") return clone;\n\tdelete (details as { fullOutputPath?: unknown }).fullOutputPath;\n\tfor (const content of clone.content) {\n\t\tif (content.type === \"text\") {\n\t\t\tcontent.text = content.text.replaceAll(fullOutputPath, \"[remote full output is not transferable]\");\n\t\t}\n\t}\n\treturn clone;\n}\n\nfunction operationKind(name: string): RemoteWorkspaceOperationKind {\n\tif (name.startsWith(\"lsp_\")) return \"service\";\n\tswitch (name) {\n\t\tcase \"read\":\n\t\tcase \"grep\":\n\t\tcase \"find\":\n\t\tcase \"ls\":\n\t\t\treturn \"read\";\n\t\tcase \"edit\":\n\t\tcase \"write\":\n\t\t\treturn \"mutation\";\n\t\tcase \"bash\":\n\t\t\treturn \"process\";\n\t}\n\tthrow new Error(`Unknown daemon tool: ${name}`);\n}\n\nfunction runCommand(\n\tcommand: string,\n\targs: string[],\n\tenvironment: NodeJS.ProcessEnv,\n\tmaxBufferedBytes: number,\n): Promise<Buffer> {\n\treturn new Promise((resolvePromise, reject) => {\n\t\tconst child = spawn(command, args, { stdio: [\"ignore\", \"pipe\", \"pipe\"], windowsHide: true, env: environment });\n\t\tconst stdout: Buffer[] = [];\n\t\tconst stderr: Buffer[] = [];\n\t\tlet bufferedBytes = 0;\n\t\tlet settled = false;\n\t\tconst append = (target: Buffer[], chunk: Buffer) => {\n\t\t\tif (settled) return;\n\t\t\tbufferedBytes += chunk.byteLength;\n\t\t\tif (bufferedBytes > maxBufferedBytes) {\n\t\t\t\tsettled = true;\n\t\t\t\tchild.kill();\n\t\t\t\treject(new Error(`${command} output exceeded the daemon buffered-output limit`));\n\t\t\t\treturn;\n\t\t\t}\n\t\t\ttarget.push(Buffer.from(chunk));\n\t\t};\n\t\tchild.stdout.on(\"data\", (chunk: Buffer) => append(stdout, chunk));\n\t\tchild.stderr.on(\"data\", (chunk: Buffer) => append(stderr, chunk));\n\t\tchild.once(\"error\", (error) => {\n\t\t\tif (settled) return;\n\t\t\tsettled = true;\n\t\t\treject(error);\n\t\t});\n\t\tchild.once(\"close\", (code) => {\n\t\t\tif (settled) return;\n\t\t\tsettled = true;\n\t\t\tif (code === 0 || (command === \"rg\" && code === 1)) {\n\t\t\t\tresolvePromise(Buffer.concat(stdout));\n\t\t\t\treturn;\n\t\t\t}\n\t\t\treject(new Error(Buffer.concat(stderr).toString(\"utf8\").trim() || `${command} exited with code ${code}`));\n\t\t});\n\t});\n}\n\nfunction isUnknownRecord(value: unknown): value is Record<string, unknown> {\n\treturn typeof value === \"object\" && value !== null;\n}\n\nfunction nestedText(record: Record<string, unknown> | undefined, key: string): string | undefined {\n\tconst nested = record?.[key];\n\treturn isUnknownRecord(nested) && typeof nested.text === \"string\" ? nested.text : undefined;\n}\n\nfunction parseDaemonGrepMatch(line: string): ToolGrepMatch | undefined {\n\tif (!line) return undefined;\n\tlet event: unknown;\n\ttry {\n\t\tevent = JSON.parse(line) as unknown;\n\t} catch {\n\t\treturn undefined;\n\t}\n\tconst eventRecord = isUnknownRecord(event) ? event : undefined;\n\tif (eventRecord?.type !== \"match\") return undefined;\n\tconst data = isUnknownRecord(eventRecord.data) ? eventRecord.data : undefined;\n\tconst filePath = nestedText(data, \"path\");\n\tconst lineNumber = data?.line_number;\n\tif (!filePath || typeof lineNumber !== \"number\") return undefined;\n\tconst lineText = nestedText(data, \"lines\");\n\treturn { filePath, lineNumber, ...(lineText === undefined ? {} : { lineText }) };\n}\n\nexport class ConfinedDaemonToolOperations implements ToolOperations {\n\treadonly cwd: string;\n\tprivate readonly local: LocalToolOperations;\n\tprivate readonly allowedRoots: readonly string[];\n\tprivate readonly allowProcessExec: boolean;\n\tprivate readonly environment: NodeJS.ProcessEnv;\n\tprivate readonly maxBufferedOutputBytes: number;\n\n\tconstructor(configuration: DaemonConfiguration) {\n\t\tthis.cwd = configuration.workspaceRoot;\n\t\tthis.local = new LocalToolOperations(this.cwd);\n\t\tthis.allowedRoots = Object.freeze([\n\t\t\tthis.cwd,\n\t\t\t...(configuration.temporaryRoot ? [configuration.temporaryRoot] : []),\n\t\t]);\n\t\tthis.allowProcessExec = configuration.allowProcessExec;\n\t\tthis.maxBufferedOutputBytes = configuration.maxBufferedOutputBytes;\n\t\tconst localeNames = Object.keys(process.env).filter((name) => /^LC_/iu.test(name));\n\t\tconst names = new Set([...BASELINE_ENVIRONMENT, ...localeNames, ...configuration.forwardedEnvironment]);\n\t\tthis.environment = {};\n\t\tfor (const name of names) {\n\t\t\tif (isSecretEnvironmentName(name)) continue;\n\t\t\tconst value = process.env[name];\n\t\t\tif (value !== undefined) this.environment[name] = value;\n\t\t}\n\t}\n\n\tcreateChildEnvironment(extra: Record<string, string> = {}): Record<string, string> {\n\t\tconst environment: Record<string, string> = {};\n\t\tfor (const [name, value] of Object.entries(this.environment)) {\n\t\t\tif (value !== undefined) environment[name] = value;\n\t\t}\n\t\tObject.assign(environment, extra);\n\t\tfor (const name of Object.keys(environment)) {\n\t\t\tif (isSecretEnvironmentName(name)) delete environment[name];\n\t\t}\n\t\treturn environment;\n\t}\n\tprivate isWithinAllowedRoot(candidate: string, root: string): boolean {\n\t\tconst pathRelative = relative(root, candidate);\n\t\treturn pathRelative !== \"..\" && !pathRelative.startsWith(`..${sep}`) && !isAbsolute(pathRelative);\n\t}\n\n\tprivate lexicalPath(path: string): string {\n\t\tconst candidate = resolve(this.cwd, path);\n\t\tif (!this.allowedRoots.some((root) => this.isWithinAllowedRoot(candidate, root))) {\n\t\t\tthrow new Error(`Path escapes the daemon workspace and allowed temporary root: ${path}`);\n\t\t}\n\t\treturn candidate;\n\t}\n\n\tprivate async existingPath(path: string): Promise<string> {\n\t\tconst candidate = this.lexicalPath(path);\n\t\tconst canonical = await realpath(candidate);\n\t\treturn this.lexicalPath(canonical);\n\t}\n\n\tprivate async existingWritablePath(candidate: string, path: string): Promise<string | undefined> {\n\t\ttry {\n\t\t\tconst stat = await lstat(candidate);\n\t\t\tif (stat.isSymbolicLink()) {\n\t\t\t\ttry {\n\t\t\t\t\tthis.lexicalPath(await realpath(candidate));\n\t\t\t\t} catch (error) {\n\t\t\t\t\tif (isMissingPath(error)) throw new Error(`Writable path uses a broken symbolic link: ${path}`);\n\t\t\t\t\tthrow error;\n\t\t\t\t}\n\t\t\t\tthrow new Error(`Writable path uses a symbolic link: ${path}`);\n\t\t\t}\n\t\t\tconst canonical = await realpath(candidate);\n\t\t\tthis.lexicalPath(canonical);\n\t\t\treturn this.lexicalPath(canonical);\n\t\t} catch (error) {\n\t\t\tif (isMissingPath(error)) return undefined;\n\t\t\tthrow error;\n\t\t}\n\t}\n\n\tprivate async ensureConfinedWritableParent(candidate: string, path: string): Promise<void> {\n\t\tlet parent = resolve(candidate, \"..\");\n\t\twhile (true) {\n\t\t\ttry {\n\t\t\t\tconst parentStat = await lstat(parent);\n\t\t\t\tif (parentStat.isSymbolicLink()) {\n\t\t\t\t\tthis.lexicalPath(await realpath(parent));\n\t\t\t\t\tthrow new Error(`Writable parent uses a symbolic link: ${path}`);\n\t\t\t\t}\n\t\t\t\tconst canonicalParent = await realpath(parent);\n\t\t\t\tthis.lexicalPath(canonicalParent);\n\t\t\t\treturn;\n\t\t\t} catch (error) {\n\t\t\t\tif (!isMissingPath(error)) throw error;\n\t\t\t\tconst next = resolve(parent, \"..\");\n\t\t\t\tif (next === parent) throw new Error(`No confined parent exists for path: ${path}`);\n\t\t\t\tparent = next;\n\t\t\t}\n\t\t}\n\t}\n\n\tprivate async writablePath(path: string): Promise<string> {\n\t\tconst candidate = this.lexicalPath(path);\n\t\tconst existing = await this.existingWritablePath(candidate, path);\n\t\tif (existing) return existing;\n\t\tawait this.ensureConfinedWritableParent(candidate, path);\n\t\treturn candidate;\n\t}\n\n\tprivate async atomicWriteFile(path: string, content: string | Buffer): Promise<void> {\n\t\tconst target = await this.writablePath(path);\n\t\tconst parent = resolve(target, \"..\");\n\t\tconst temporary = resolve(parent, `.grip-remote-write-${process.pid}-${randomUUID()}-${basename(target)}.tmp`);\n\t\tthis.lexicalPath(temporary);\n\t\tlet wroteTemporary = false;\n\t\ttry {\n\t\t\tconst handle = await open(temporary, \"wx\", 0o600);\n\t\t\ttry {\n\t\t\t\tawait handle.writeFile(content, typeof content === \"string\" ? \"utf8\" : undefined);\n\t\t\t} finally {\n\t\t\t\tawait handle.close();\n\t\t\t}\n\t\t\twroteTemporary = true;\n\t\t\tthis.lexicalPath(await realpath(temporary));\n\t\t\ttry {\n\t\t\t\tif ((await lstat(target)).isSymbolicLink()) throw new Error(`Writable path uses a symbolic link: ${path}`);\n\t\t\t} catch (error) {\n\t\t\t\tif (!isMissingPath(error)) throw error;\n\t\t\t}\n\t\t\tawait rename(temporary, target);\n\t\t\twroteTemporary = false;\n\t\t\tthis.lexicalPath(await realpath(target));\n\t\t} finally {\n\t\t\tif (wroteTemporary) await rm(temporary, { force: true });\n\t\t}\n\t}\n\n\tasync exec(command: string, options: ToolExecOptions): Promise<ToolExecResult> {\n\t\tif (!this.allowProcessExec) throw new Error(\"Process execution is disabled by daemon policy\");\n\t\tconst cwd = await this.existingPath(options.cwd ?? this.cwd);\n\t\tconst environment = { ...this.environment };\n\t\tfor (const name of GRIP_SESSION_ENVIRONMENT_NAMES) {\n\t\t\tconst value = options.env?.[name];\n\t\t\tif (value !== undefined) environment[name] = value;\n\t\t}\n\t\treturn this.local.exec(command, { ...options, cwd, env: environment });\n\t}\n\n\tasync access(path: string, mode?: ToolAccessMode): Promise<void> {\n\t\tawait this.local.access(await this.existingPath(path), mode);\n\t}\n\n\tasync readFile(path: string): Promise<Buffer> {\n\t\treturn this.local.readFile(await this.existingPath(path));\n\t}\n\n\tasync writeFile(path: string, content: string | Buffer): Promise<void> {\n\t\tawait this.atomicWriteFile(path, content);\n\t}\n\n\tasync mkdir(path: string, options?: ToolMkdirOptions): Promise<void> {\n\t\tawait fsMkdir(await this.writablePath(path), options);\n\t}\n\n\tasync stat(path: string): Promise<ToolFileStat> {\n\t\treturn this.local.stat(await this.existingPath(path));\n\t}\n\n\tasync readdir(path: string): Promise<string[]> {\n\t\treturn this.local.readdir(await this.existingPath(path));\n\t}\n\n\tasync glob(pattern: string, cwd: string, options: ToolGlobOptions): Promise<string[]> {\n\t\tconst searchRoot = await this.existingPath(cwd);\n\t\tconst args = [\"--glob\", \"--color=never\", \"--hidden\", \"--no-require-git\", \"--max-results\", String(options.limit)];\n\t\tfor (const ignored of options.ignore) args.push(\"--exclude\", ignored);\n\t\tlet effectivePattern = pattern;\n\t\tif (pattern.includes(\"/\")) {\n\t\t\targs.push(\"--full-path\");\n\t\t\tif (!pattern.startsWith(\"/\") && !pattern.startsWith(\"**/\") && pattern !== \"**\")\n\t\t\t\teffectivePattern = `**/${pattern}`;\n\t\t}\n\t\targs.push(\"--\", effectivePattern, searchRoot);\n\t\tconst output = await runCommand(\"fd\", args, this.environment, this.maxBufferedOutputBytes);\n\t\tconst results: string[] = [];\n\t\tfor (const entry of output.toString(\"utf8\").split(\"\\n\")) {\n\t\t\tif (!entry) continue;\n\t\t\ttry {\n\t\t\t\tresults.push(await this.existingPath(entry));\n\t\t\t} catch {\n\t\t\t\t// Symlinks escaping the workspace are deliberately omitted.\n\t\t\t}\n\t\t}\n\t\treturn results;\n\t}\n\n\tasync grep(options: ToolGrepOptions): Promise<ToolGrepResult> {\n\t\tconst searchPath = await this.existingPath(options.path);\n\t\tconst isDirectory = (await this.local.stat(searchPath)).isDirectory();\n\t\tconst args = [\"--json\", \"--line-number\", \"--color=never\", \"--hidden\"];\n\t\tif (options.ignoreCase) args.push(\"--ignore-case\");\n\t\tif (options.literal) args.push(\"--fixed-strings\");\n\t\tif (options.glob) args.push(\"--glob\", options.glob);\n\t\targs.push(\"--\", options.pattern, searchPath);\n\t\tconst output = await runCommand(\"rg\", args, this.environment, this.maxBufferedOutputBytes);\n\t\tconst matches: ToolGrepMatch[] = [];\n\t\tfor (const line of output.toString(\"utf8\").split(\"\\n\")) {\n\t\t\tif (matches.length >= options.limit) continue;\n\t\t\tconst match = parseDaemonGrepMatch(line);\n\t\t\tif (!match) continue;\n\t\t\ttry {\n\t\t\t\tawait this.existingPath(match.filePath);\n\t\t\t} catch {\n\t\t\t\tcontinue;\n\t\t\t}\n\t\t\tmatches.push(match);\n\t\t}\n\t\treturn { isDirectory, matches };\n\t}\n\n\tasync detectImageMimeType(path: string): Promise<string | null | undefined> {\n\t\treturn this.local.detectImageMimeType(await this.existingPath(path));\n\t}\n\n\tgetBackendInfo(): ToolBackendInfo {\n\t\treturn { type: \"local\", cwd: this.cwd };\n\t}\n}\n\nexport interface DaemonWorkspaceRuntime {\n\treadonly operations: ConfinedDaemonToolOperations;\n\treadonly host: WorkspaceToolHost;\n\treadonly lspRuntime?: LspRuntimeState;\n\treadonly catalog: RemoteWorkspaceCatalog;\n\treadonly capabilities: readonly RemoteWorkspaceCapability[];\n\tcreateHandler(workspace: RemoteWorkspaceIdentity): RemoteWorkspaceServerHandler;\n\tretire(): Promise<void>;\n\tdispose(): Promise<void>;\n}\n\ntype DaemonRequestInterruptionCode = \"cancelled\" | \"deadline_exceeded\";\ntype DaemonInterruptedExecutionState = \"not_started\" | \"indeterminate\";\n\nfunction requestError(code: DaemonRequestInterruptionCode, message: string, state: DaemonInterruptedExecutionState) {\n\treturn new RemoteWorkspaceRequestError({ code, message, executionState: state, retryable: false });\n}\ninterface DaemonRequestRuntime {\n\tconfiguration: DaemonConfiguration;\n\toperations: ConfinedDaemonToolOperations;\n\thost: WorkspaceToolHost;\n\tlspRuntime: LspRuntimeState | undefined;\n\tworkspace: RemoteWorkspaceIdentity;\n}\n\nfunction withDaemonWorkspace<T extends Record<string, unknown>>(result: T, workspace: RemoteWorkspaceIdentity) {\n\treturn { ...result, workspace };\n}\n\nasync function synchronizeDaemonToolFile(\n\ttoolName: string,\n\tinvocationArguments: unknown,\n\truntime: DaemonRequestRuntime,\n): Promise<void> {\n\tif (!runtime.lspRuntime) return;\n\tconst args = invocationArguments as { path?: unknown };\n\tif (typeof args.path !== \"string\") return;\n\ttry {\n\t\tif (toolName === \"read\") {\n\t\t\tawait runtime.lspRuntime.fileSync.handleFileRead(args.path, runtime.operations);\n\t\t} else if (toolName === \"write\" || toolName === \"edit\") {\n\t\t\tawait runtime.lspRuntime.fileSync.handleFileWrite(args.path, runtime.operations);\n\t\t}\n\t} catch {\n\t\t// Synchronization remains best-effort, matching local AgentSession behavior.\n\t}\n}\n\nasync function invokeDaemonTool(\n\trequest: RemoteWorkspaceTypedRequest,\n\tparams: Record<string, unknown>,\n\tcontext: RemoteWorkspaceServerRequestContext,\n\truntime: DaemonRequestRuntime,\n): Promise<AgentToolResult<unknown>> {\n\tconst toolName = params.toolName as string;\n\tconst kind = operationKind(toolName);\n\tif (kind !== \"read\") context.markSideEffectStarted();\n\tlet updateQueue = Promise.resolve();\n\ttry {\n\t\tconst result = await runtime.host.executePrepared(toolName, {\n\t\t\ttoolCallId: request.id,\n\t\t\targuments: params.arguments,\n\t\t\tsignal: context.signal,\n\t\t\texecutionOptions: params.executionOptions as WorkspaceToolExecutionOptions,\n\t\t\tonUpdate: (update) => {\n\t\t\t\tupdateQueue = updateQueue.then(() => context.sendUpdate(portableToolResult(update)));\n\t\t\t},\n\t\t});\n\t\tawait updateQueue;\n\t\tawait synchronizeDaemonToolFile(toolName, params.arguments, runtime);\n\t\tif (kind !== \"read\") context.markCommitted();\n\t\treturn portableToolResult(result);\n\t} catch (error) {\n\t\tawait updateQueue.catch(() => undefined);\n\t\tif (context.signal.aborted) {\n\t\t\tthrow requestError(\n\t\t\t\t\"cancelled\",\n\t\t\t\t\"Remote workspace tool invocation was cancelled\",\n\t\t\t\tkind === \"read\" ? \"not_started\" : \"indeterminate\",\n\t\t\t);\n\t\t}\n\t\tthrow new RemoteWorkspaceRequestError({\n\t\t\tcode: \"internal_error\",\n\t\t\tmessage: error instanceof Error ? error.message.slice(0, 4096) : \"Workspace tool failed\",\n\t\t\texecutionState: kind === \"read\" ? \"not_started\" : \"indeterminate\",\n\t\t\tretryable: false,\n\t\t});\n\t}\n}\n\nasync function executeDaemonWorkspaceProcess(\n\tparams: Record<string, unknown>,\n\tcontext: RemoteWorkspaceServerRequestContext,\n\truntime: DaemonRequestRuntime,\n): Promise<ToolExecResult> {\n\tcontext.markSideEffectStarted();\n\tlet updateQueue = Promise.resolve();\n\tlet pendingOutputBytes = 0;\n\tlet outputLimitExceeded = false;\n\tconst outputController = new AbortController();\n\tconst signal = AbortSignal.any([context.signal, outputController.signal]);\n\tlet result: ToolExecResult;\n\ttry {\n\t\tresult = await runtime.operations.exec(params.command as string, {\n\t\t\tcwd: params.cwd as string,\n\t\t\tsignal,\n\t\t\tonData: (data) => {\n\t\t\t\tif (outputLimitExceeded) return;\n\t\t\t\tconst chunk = Buffer.from(data);\n\t\t\t\tpendingOutputBytes += chunk.byteLength;\n\t\t\t\tif (pendingOutputBytes > runtime.configuration.maxBufferedOutputBytes) {\n\t\t\t\t\toutputLimitExceeded = true;\n\t\t\t\t\toutputController.abort();\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t\tupdateQueue = updateQueue\n\t\t\t\t\t.then(() => context.sendUpdate({ dataBase64: chunk.toString(\"base64\") }))\n\t\t\t\t\t.finally(() => {\n\t\t\t\t\t\tpendingOutputBytes -= chunk.byteLength;\n\t\t\t\t\t});\n\t\t\t},\n\t\t});\n\t} catch (error) {\n\t\tif (outputLimitExceeded) throw new Error(\"Process output exceeded the daemon buffered-output limit\");\n\t\tthrow error;\n\t}\n\tawait updateQueue;\n\tcontext.markCommitted();\n\treturn result;\n}\n\nasync function readDaemonResource(\n\tparams: Record<string, unknown>,\n\truntime: DaemonRequestRuntime,\n): Promise<Record<string, unknown>> {\n\tconst path = params.path as string;\n\tconst resourcePath =\n\t\tpath === \"SANDBOX.md\"\n\t\t\t? runtime.configuration.sandboxInstructionsPath\n\t\t\t: path === \"AGENTS.md\"\n\t\t\t\t? runtime.configuration.userAgentsPath\n\t\t\t\t: undefined;\n\tif (!resourcePath) {\n\t\tthrow new RemoteWorkspaceRequestError({\n\t\t\tcode: \"not_available\",\n\t\t\tmessage: \"Requested daemon resource is not available\",\n\t\t\texecutionState: \"not_started\",\n\t\t\tretryable: false,\n\t\t});\n\t}\n\treturn withDaemonWorkspace({ contentBase64: (await readFile(resourcePath)).toString(\"base64\") }, runtime.workspace);\n}\n\nfunction getDaemonLspStatus(runtime: DaemonRequestRuntime): Record<string, unknown> {\n\tif (!runtime.lspRuntime) {\n\t\tthrow new RemoteWorkspaceRequestError({\n\t\t\tcode: \"not_available\",\n\t\t\tmessage: \"Daemon LSP is not configured\",\n\t\t\texecutionState: \"not_started\",\n\t\t\tretryable: false,\n\t\t});\n\t}\n\treturn {\n\t\tenabled: true,\n\t\tservers: runtime.lspRuntime.manager.getStatus().map((status) => sanitizeLspStatus(status, runtime.configuration)),\n\t};\n}\n\nasync function dispatchDaemonWorkspaceRequest(\n\trequest: RemoteWorkspaceTypedRequest,\n\tcontext: RemoteWorkspaceServerRequestContext,\n\truntime: DaemonRequestRuntime,\n): Promise<unknown> {\n\tconst params = request.params as Record<string, unknown>;\n\tswitch (request.method) {\n\t\tcase \"tool.invoke\":\n\t\t\treturn invokeDaemonTool(request, params, context, runtime);\n\t\tcase \"workspace.access\":\n\t\t\tawait runtime.operations.access(params.path as string, params.mode as ToolAccessMode | undefined);\n\t\t\treturn {};\n\t\tcase \"workspace.read\":\n\t\t\treturn withDaemonWorkspace(\n\t\t\t\t{ contentBase64: (await runtime.operations.readFile(params.path as string)).toString(\"base64\") },\n\t\t\t\truntime.workspace,\n\t\t\t);\n\t\tcase \"workspace.write\":\n\t\t\tcontext.markSideEffectStarted();\n\t\t\tawait withFileMutationQueue(resolve(runtime.configuration.workspaceRoot, params.path as string), () =>\n\t\t\t\truntime.operations.writeFile(params.path as string, Buffer.from(params.contentBase64 as string, \"base64\")),\n\t\t\t);\n\t\t\tcontext.markCommitted();\n\t\t\treturn {};\n\t\tcase \"workspace.mkdir\":\n\t\t\tcontext.markSideEffectStarted();\n\t\t\tawait withFileMutationQueue(resolve(runtime.configuration.workspaceRoot, params.path as string), () =>\n\t\t\t\truntime.operations.mkdir(params.path as string, { recursive: params.recursive === true }),\n\t\t\t);\n\t\t\tcontext.markCommitted();\n\t\t\treturn {};\n\t\tcase \"workspace.stat\": {\n\t\t\tconst value = await runtime.operations.stat(params.path as string);\n\t\t\treturn withDaemonWorkspace(\n\t\t\t\t{ kind: value.isDirectory() ? \"directory\" : value.isFile() ? \"file\" : \"other\" },\n\t\t\t\truntime.workspace,\n\t\t\t);\n\t\t}\n\t\tcase \"workspace.readdir\":\n\t\t\treturn withDaemonWorkspace(\n\t\t\t\t{ entries: await runtime.operations.readdir(params.path as string) },\n\t\t\t\truntime.workspace,\n\t\t\t);\n\t\tcase \"workspace.glob\":\n\t\t\treturn withDaemonWorkspace(\n\t\t\t\t{\n\t\t\t\t\tmatches: await runtime.operations.glob(params.pattern as string, params.cwd as string, {\n\t\t\t\t\t\tignore: params.ignore as string[],\n\t\t\t\t\t\tlimit: params.limit as number,\n\t\t\t\t\t}),\n\t\t\t\t},\n\t\t\t\truntime.workspace,\n\t\t\t);\n\t\tcase \"workspace.grep\": {\n\t\t\tconst result = await runtime.operations.grep(params as unknown as ToolGrepOptions);\n\t\t\treturn withDaemonWorkspace(result as unknown as Record<string, unknown>, runtime.workspace);\n\t\t}\n\t\tcase \"workspace.detect_image_mime\":\n\t\t\treturn withDaemonWorkspace(\n\t\t\t\t{ mimeType: (await runtime.operations.detectImageMimeType(params.path as string)) ?? null },\n\t\t\t\truntime.workspace,\n\t\t\t);\n\t\tcase \"workspace.exec\":\n\t\t\treturn executeDaemonWorkspaceProcess(params, context, runtime);\n\t\tcase \"resource.read\":\n\t\t\treturn readDaemonResource(params, runtime);\n\t\tcase \"lsp.status\":\n\t\t\treturn getDaemonLspStatus(runtime);\n\t\tdefault:\n\t\t\tthrow new RemoteWorkspaceRequestError({\n\t\t\t\tcode: \"method_not_supported\",\n\t\t\t\tmessage: `Workspace operation is not implemented: ${request.method}`,\n\t\t\t\texecutionState: \"not_started\",\n\t\t\t\tretryable: false,\n\t\t\t});\n\t}\n}\n\nexport function createDaemonWorkspaceRuntime(configuration: DaemonConfiguration): DaemonWorkspaceRuntime {\n\tconst operations = new ConfinedDaemonToolOperations(configuration);\n\tconst toolNames: WorkspaceToolName[] = [\"read\", \"edit\", \"write\", \"grep\", \"find\", \"ls\"];\n\tif (configuration.allowProcessExec) toolNames.splice(1, 0, \"bash\");\n\tconst lspConfiguration = loadDaemonLspConfiguration(configuration);\n\tconst lspRuntime = lspConfiguration.enabled\n\t\t? createLspRuntimeState(configuration.workspaceRoot, {\n\t\t\t\tconfiguration: lspConfiguration,\n\t\t\t\tgetToolBackendInfo: () => operations.getBackendInfo(),\n\t\t\t\tgetToolOperations: () => operations,\n\t\t\t\tresolveConnectionFactory: (transport) =>\n\t\t\t\t\ttransport.type === \"spawn\"\n\t\t\t\t\t\t? createManagedStdioConnectionFactory({\n\t\t\t\t\t\t\t\t...transport,\n\t\t\t\t\t\t\t\tenv: operations.createChildEnvironment(transport.env),\n\t\t\t\t\t\t\t\tinheritEnvironment: false,\n\t\t\t\t\t\t\t})\n\t\t\t\t\t\t: resolveLspConnectionFactory(transport),\n\t\t\t})\n\t\t: undefined;\n\tconst host = new WorkspaceToolHost({\n\t\tcwd: configuration.workspaceRoot,\n\t\toperations,\n\t\ttoolNames,\n\t\tadditionalDefinitions: lspRuntime\n\t\t\t? createLspToolDefinitions(\n\t\t\t\t\t() => lspRuntime,\n\t\t\t\t\t() => operations,\n\t\t\t\t)\n\t\t\t: undefined,\n\t\tdisposeTimeoutMs: Math.min(configuration.shutdownTimeoutMs, 60_000),\n\t});\n\tconst catalog: RemoteWorkspaceCatalog = {\n\t\tgeneration: 1,\n\t\ttools: host.getCatalog().map((entry) => ({\n\t\t\tname: entry.name,\n\t\t\texecutionMode: operationKind(entry.name),\n\t\t\tparameterSchema: structuredClone(entry.parameters) as Record<string, unknown>,\n\t\t\tschemaHash: hashRemoteWorkspaceJson(entry.parameters),\n\t\t\tfeatureFlags: [],\n\t\t})),\n\t\toperations: [\n\t\t\t...PRIMITIVE_OPERATIONS.filter((method) => method !== \"workspace.exec\" || configuration.allowProcessExec),\n\t\t\t...(configuration.sandboxInstructionsPath || configuration.userAgentsPath ? ([\"resource.read\"] as const) : []),\n\t\t\t...(lspRuntime ? ([\"lsp.status\"] as const) : []),\n\t\t],\n\t};\n\tconst capabilities: RemoteWorkspaceCapability[] = [\n\t\t\"catalog_refresh\",\n\t\t\"primitive_operations\",\n\t\t\"tool_updates\",\n\t\t...(lspRuntime ? ([\"lsp_status\"] as const) : []),\n\t];\n\tlet activeRequests = 0;\n\n\treturn {\n\t\toperations,\n\t\thost,\n\t\tlspRuntime,\n\t\tcatalog,\n\t\tcapabilities,\n\t\tcreateHandler(workspace) {\n\t\t\tconst requestRuntime: DaemonRequestRuntime = { configuration, operations, host, lspRuntime, workspace };\n\t\t\treturn {\n\t\t\t\tvalidateToolArguments: (toolName, value) => host.validatePreparedArguments(toolName, value),\n\t\t\t\tasync handleRequest(request, context) {\n\t\t\t\t\tif (activeRequests >= configuration.maxGlobalRequests) {\n\t\t\t\t\t\tthrow new RemoteWorkspaceRequestError({\n\t\t\t\t\t\t\tcode: \"limit_exceeded\",\n\t\t\t\t\t\t\tmessage: \"Daemon global active request limit reached\",\n\t\t\t\t\t\t\texecutionState: \"not_started\",\n\t\t\t\t\t\t\tretryable: true,\n\t\t\t\t\t\t});\n\t\t\t\t\t}\n\t\t\t\t\tactiveRequests++;\n\t\t\t\t\ttry {\n\t\t\t\t\t\treturn await dispatchDaemonWorkspaceRequest(request, context, requestRuntime);\n\t\t\t\t\t} finally {\n\t\t\t\t\t\tactiveRequests--;\n\t\t\t\t\t}\n\t\t\t\t},\n\t\t\t};\n\t\t},\n\t\tretire: async () => {\n\t\t\tawait host.waitForIdle(configuration.shutdownTimeoutMs);\n\t\t\tawait lspRuntime?.manager.shutdownAll();\n\t\t\tawait host.dispose();\n\t\t},\n\t\tdispose: async () => {\n\t\t\tawait Promise.all([lspRuntime?.manager.shutdownAll(), host.dispose()]);\n\t\t},\n\t};\n}\n"]}
|
|
1
|
+
{"version":3,"file":"workspace-runtime.d.ts","sourceRoot":"","sources":["../../src/daemon/workspace-runtime.ts"],"names":[],"mappings":"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","sourcesContent":["import { spawn } from \"node:child_process\";\nimport { randomUUID } from \"node:crypto\";\nimport { mkdir as fsMkdir, lstat, open, readFile, realpath, rename, rm } from \"node:fs/promises\";\nimport { basename, isAbsolute, relative, resolve, sep } from \"node:path\";\nimport type { AgentToolResult } from \"@greppleai/grip-agent-core\";\nimport { createLspRuntimeState, createLspToolDefinitions, type LspRuntimeState } from \"../core/lsp/integration.ts\";\nimport type { LspServerStatus } from \"../core/lsp/manager.ts\";\nimport { createManagedStdioConnectionFactory, resolveLspConnectionFactory } from \"../core/lsp/transport.ts\";\nimport {\n\thashRemoteWorkspaceJson,\n\ttype RemoteWorkspaceCapability,\n\ttype RemoteWorkspaceCatalog,\n\ttype RemoteWorkspaceIdentity,\n\ttype RemoteWorkspaceMethod,\n\ttype RemoteWorkspaceOperationKind,\n} from \"../core/remote-workspace-protocol/contract.ts\";\nimport {\n\tRemoteWorkspaceRequestError,\n\ttype RemoteWorkspaceServerHandler,\n\ttype RemoteWorkspaceServerRequestContext,\n\ttype RemoteWorkspaceTypedRequest,\n} from \"../core/remote-workspace-protocol/session.ts\";\nimport { withFileMutationQueue } from \"../core/tools/file-mutation-queue.ts\";\nimport {\n\tGRIP_SESSION_ENVIRONMENT_NAMES,\n\tLocalToolOperations,\n\ttype ToolAccessMode,\n\ttype ToolBackendInfo,\n\ttype ToolExecOptions,\n\ttype ToolExecResult,\n\ttype ToolFileStat,\n\ttype ToolGlobOptions,\n\ttype ToolGrepMatch,\n\ttype ToolGrepOptions,\n\ttype ToolGrepResult,\n\ttype ToolMkdirOptions,\n\ttype ToolOperations,\n\ttype WorkspaceToolExecutionOptions,\n} from \"../core/tools/operations.ts\";\nimport { WorkspaceToolHost, type WorkspaceToolName } from \"../core/tools/workspace-tool-host.ts\";\nimport type { DaemonConfiguration } from \"./config.ts\";\nimport { loadDaemonLspConfiguration } from \"./lsp-config.ts\";\nimport { redactDaemonText } from \"./security.ts\";\n\nconst PRIMITIVE_OPERATIONS: RemoteWorkspaceMethod[] = [\n\t\"workspace.access\",\n\t\"workspace.read\",\n\t\"workspace.write\",\n\t\"workspace.mkdir\",\n\t\"workspace.stat\",\n\t\"workspace.readdir\",\n\t\"workspace.glob\",\n\t\"workspace.grep\",\n\t\"workspace.detect_image_mime\",\n\t\"workspace.exec\",\n];\n\nconst SECRET_ENVIRONMENT_SUFFIX = /_(?:API_KEY|TOKEN|SECRET|PASSWORD|PRIVATE_KEY|CREDENTIALS)$/iu;\nconst BASELINE_ENVIRONMENT =\n\tprocess.platform === \"win32\"\n\t\t? [\"PATH\", \"PATHEXT\", \"SYSTEMROOT\", \"COMSPEC\", \"TEMP\", \"TMP\", \"USER\", \"USERNAME\"]\n\t\t: [\"PATH\", \"HOME\", \"USER\", \"LOGNAME\", \"SHELL\", \"LANG\", \"TERM\", \"COLORTERM\", \"NO_COLOR\", \"TMPDIR\"];\n\nfunction isSecretEnvironmentName(name: string): boolean {\n\tconst upper = name.toUpperCase();\n\treturn (\n\t\tupper === \"GRIP_DAEMON_TOKEN\" ||\n\t\tupper === \"PI_DAEMON_TOKEN\" ||\n\t\tupper === \"GRIP_REMOTE_TOKEN\" ||\n\t\tupper.startsWith(\"GRIP_DAEMON_TLS_\") ||\n\t\tupper.startsWith(\"PI_DAEMON_TLS_\") ||\n\t\tSECRET_ENVIRONMENT_SUFFIX.test(upper)\n\t);\n}\nprocess.platform === \"win32\"\n\t? [\"PATH\", \"PATHEXT\", \"SYSTEMROOT\", \"TEMP\", \"TMP\"]\n\t: [\"PATH\", \"HOME\", \"LANG\", \"LC_ALL\", \"TERM\", \"TMPDIR\"];\n\nfunction isMissingPath(error: unknown): boolean {\n\treturn error instanceof Error && \"code\" in error && error.code === \"ENOENT\";\n}\n\nfunction sanitizeLspStatus(\n\tstatus: LspServerStatus,\n\tconfiguration: DaemonConfiguration,\n): Omit<LspServerStatus, \"capabilities\"> {\n\tconst { capabilities: _capabilities, ...safe } = status;\n\tconst secrets = [configuration.token, configuration.tls?.passphrase];\n\tconst redact = (value: string | undefined) => (value ? redactDaemonText(value, secrets) : undefined);\n\treturn {\n\t\t...safe,\n\t\tserverId: redact(safe.serverId)!,\n\t\tlanguageIds: safe.languageIds.map((value) => redact(value)!),\n\t\ttransport: redact(safe.transport)!,\n\t\t...(safe.instanceKey ? { instanceKey: redact(safe.instanceKey) } : {}),\n\t\t...(safe.workspaceRoot ? { workspaceRoot: redact(safe.workspaceRoot) } : {}),\n\t\t...(safe.rootUri ? { rootUri: redact(safe.rootUri) } : {}),\n\t\t...(safe.endpoint ? { endpoint: redact(safe.endpoint) } : {}),\n\t\t...(safe.lastError ? { lastError: redact(safe.lastError) } : {}),\n\t\t...(safe.lastRequestError ? { lastRequestError: redact(safe.lastRequestError) } : {}),\n\t\t...(safe.stderr ? { stderr: redact(safe.stderr) } : {}),\n\t\t...(safe.synchronizationError ? { synchronizationError: redact(safe.synchronizationError) } : {}),\n\t};\n}\n\nfunction portableToolResult(result: AgentToolResult<unknown>): AgentToolResult<unknown> {\n\tconst clone = JSON.parse(JSON.stringify(result)) as AgentToolResult<unknown>;\n\tconst details = clone.details;\n\tif (!details || typeof details !== \"object\" || !(\"fullOutputPath\" in details)) return clone;\n\tconst fullOutputPath = (details as { fullOutputPath?: unknown }).fullOutputPath;\n\tif (typeof fullOutputPath !== \"string\") return clone;\n\tdelete (details as { fullOutputPath?: unknown }).fullOutputPath;\n\tfor (const content of clone.content) {\n\t\tif (content.type === \"text\") {\n\t\t\tcontent.text = content.text.replaceAll(fullOutputPath, \"[remote full output is not transferable]\");\n\t\t}\n\t}\n\treturn clone;\n}\n\nfunction operationKind(name: string): RemoteWorkspaceOperationKind {\n\tif (name.startsWith(\"lsp_\")) return \"service\";\n\tswitch (name) {\n\t\tcase \"read\":\n\t\tcase \"grep\":\n\t\tcase \"find\":\n\t\tcase \"ls\":\n\t\t\treturn \"read\";\n\t\tcase \"edit\":\n\t\tcase \"write\":\n\t\t\treturn \"mutation\";\n\t\tcase \"bash\":\n\t\t\treturn \"process\";\n\t}\n\tthrow new Error(`Unknown daemon tool: ${name}`);\n}\n\nfunction runCommand(\n\tcommand: string,\n\targs: string[],\n\tenvironment: NodeJS.ProcessEnv,\n\tmaxBufferedBytes: number,\n): Promise<Buffer> {\n\treturn new Promise((resolvePromise, reject) => {\n\t\tconst child = spawn(command, args, { stdio: [\"ignore\", \"pipe\", \"pipe\"], windowsHide: true, env: environment });\n\t\tconst stdout: Buffer[] = [];\n\t\tconst stderr: Buffer[] = [];\n\t\tlet bufferedBytes = 0;\n\t\tlet settled = false;\n\t\tconst append = (target: Buffer[], chunk: Buffer) => {\n\t\t\tif (settled) return;\n\t\t\tbufferedBytes += chunk.byteLength;\n\t\t\tif (bufferedBytes > maxBufferedBytes) {\n\t\t\t\tsettled = true;\n\t\t\t\tchild.kill();\n\t\t\t\treject(new Error(`${command} output exceeded the daemon buffered-output limit`));\n\t\t\t\treturn;\n\t\t\t}\n\t\t\ttarget.push(Buffer.from(chunk));\n\t\t};\n\t\tchild.stdout.on(\"data\", (chunk: Buffer) => append(stdout, chunk));\n\t\tchild.stderr.on(\"data\", (chunk: Buffer) => append(stderr, chunk));\n\t\tchild.once(\"error\", (error) => {\n\t\t\tif (settled) return;\n\t\t\tsettled = true;\n\t\t\treject(error);\n\t\t});\n\t\tchild.once(\"close\", (code) => {\n\t\t\tif (settled) return;\n\t\t\tsettled = true;\n\t\t\tif (code === 0 || (command === \"rg\" && code === 1)) {\n\t\t\t\tresolvePromise(Buffer.concat(stdout));\n\t\t\t\treturn;\n\t\t\t}\n\t\t\treject(new Error(Buffer.concat(stderr).toString(\"utf8\").trim() || `${command} exited with code ${code}`));\n\t\t});\n\t});\n}\n\nfunction isUnknownRecord(value: unknown): value is Record<string, unknown> {\n\treturn typeof value === \"object\" && value !== null;\n}\n\nfunction nestedText(record: Record<string, unknown> | undefined, key: string): string | undefined {\n\tconst nested = record?.[key];\n\treturn isUnknownRecord(nested) && typeof nested.text === \"string\" ? nested.text : undefined;\n}\n\nfunction parseDaemonGrepMatch(line: string): ToolGrepMatch | undefined {\n\tif (!line) return undefined;\n\tlet event: unknown;\n\ttry {\n\t\tevent = JSON.parse(line) as unknown;\n\t} catch {\n\t\treturn undefined;\n\t}\n\tconst eventRecord = isUnknownRecord(event) ? event : undefined;\n\tif (eventRecord?.type !== \"match\") return undefined;\n\tconst data = isUnknownRecord(eventRecord.data) ? eventRecord.data : undefined;\n\tconst filePath = nestedText(data, \"path\");\n\tconst lineNumber = data?.line_number;\n\tif (!filePath || typeof lineNumber !== \"number\") return undefined;\n\tconst lineText = nestedText(data, \"lines\");\n\treturn { filePath, lineNumber, ...(lineText === undefined ? {} : { lineText }) };\n}\n\nexport class ConfinedDaemonToolOperations implements ToolOperations {\n\treadonly cwd: string;\n\tprivate readonly local: LocalToolOperations;\n\tprivate readonly allowedRoots: readonly string[];\n\tprivate readonly allowProcessExec: boolean;\n\tprivate readonly environment: NodeJS.ProcessEnv;\n\tprivate readonly maxBufferedOutputBytes: number;\n\n\tconstructor(configuration: DaemonConfiguration) {\n\t\tthis.cwd = configuration.workspaceRoot;\n\t\tthis.local = new LocalToolOperations(this.cwd);\n\t\tthis.allowedRoots = Object.freeze([\n\t\t\tthis.cwd,\n\t\t\t...(configuration.temporaryRoot ? [configuration.temporaryRoot] : []),\n\t\t]);\n\t\tthis.allowProcessExec = configuration.allowProcessExec;\n\t\tthis.maxBufferedOutputBytes = configuration.maxBufferedOutputBytes;\n\t\tconst localeNames = Object.keys(process.env).filter((name) => /^LC_/iu.test(name));\n\t\tconst names = new Set([...BASELINE_ENVIRONMENT, ...localeNames, ...configuration.forwardedEnvironment]);\n\t\tthis.environment = {};\n\t\tfor (const name of names) {\n\t\t\tif (isSecretEnvironmentName(name)) continue;\n\t\t\tconst value = process.env[name];\n\t\t\tif (value !== undefined) this.environment[name] = value;\n\t\t}\n\t}\n\n\tcreateChildEnvironment(extra: Record<string, string> = {}): Record<string, string> {\n\t\tconst environment: Record<string, string> = {};\n\t\tfor (const [name, value] of Object.entries(this.environment)) {\n\t\t\tif (value !== undefined) environment[name] = value;\n\t\t}\n\t\tObject.assign(environment, extra);\n\t\tfor (const name of Object.keys(environment)) {\n\t\t\tif (isSecretEnvironmentName(name)) delete environment[name];\n\t\t}\n\t\treturn environment;\n\t}\n\tprivate isWithinAllowedRoot(candidate: string, root: string): boolean {\n\t\tconst pathRelative = relative(root, candidate);\n\t\treturn pathRelative !== \"..\" && !pathRelative.startsWith(`..${sep}`) && !isAbsolute(pathRelative);\n\t}\n\n\tprivate lexicalPath(path: string): string {\n\t\tconst candidate = resolve(this.cwd, path);\n\t\tif (!this.allowedRoots.some((root) => this.isWithinAllowedRoot(candidate, root))) {\n\t\t\tthrow new Error(`Path escapes the daemon workspace and allowed temporary root: ${path}`);\n\t\t}\n\t\treturn candidate;\n\t}\n\n\tprivate async existingPath(path: string): Promise<string> {\n\t\tconst candidate = this.lexicalPath(path);\n\t\tconst canonical = await realpath(candidate);\n\t\treturn this.lexicalPath(canonical);\n\t}\n\n\tprivate async existingWritablePath(candidate: string, path: string): Promise<string | undefined> {\n\t\ttry {\n\t\t\tconst stat = await lstat(candidate);\n\t\t\tif (stat.isSymbolicLink()) {\n\t\t\t\ttry {\n\t\t\t\t\tthis.lexicalPath(await realpath(candidate));\n\t\t\t\t} catch (error) {\n\t\t\t\t\tif (isMissingPath(error)) throw new Error(`Writable path uses a broken symbolic link: ${path}`);\n\t\t\t\t\tthrow error;\n\t\t\t\t}\n\t\t\t\tthrow new Error(`Writable path uses a symbolic link: ${path}`);\n\t\t\t}\n\t\t\tconst canonical = await realpath(candidate);\n\t\t\tthis.lexicalPath(canonical);\n\t\t\treturn this.lexicalPath(canonical);\n\t\t} catch (error) {\n\t\t\tif (isMissingPath(error)) return undefined;\n\t\t\tthrow error;\n\t\t}\n\t}\n\n\tprivate async ensureConfinedWritableParent(candidate: string, path: string): Promise<void> {\n\t\tlet parent = resolve(candidate, \"..\");\n\t\twhile (true) {\n\t\t\ttry {\n\t\t\t\tconst parentStat = await lstat(parent);\n\t\t\t\tif (parentStat.isSymbolicLink()) {\n\t\t\t\t\tthis.lexicalPath(await realpath(parent));\n\t\t\t\t\tthrow new Error(`Writable parent uses a symbolic link: ${path}`);\n\t\t\t\t}\n\t\t\t\tconst canonicalParent = await realpath(parent);\n\t\t\t\tthis.lexicalPath(canonicalParent);\n\t\t\t\treturn;\n\t\t\t} catch (error) {\n\t\t\t\tif (!isMissingPath(error)) throw error;\n\t\t\t\tconst next = resolve(parent, \"..\");\n\t\t\t\tif (next === parent) throw new Error(`No confined parent exists for path: ${path}`);\n\t\t\t\tparent = next;\n\t\t\t}\n\t\t}\n\t}\n\n\tprivate async writablePath(path: string): Promise<string> {\n\t\tconst candidate = this.lexicalPath(path);\n\t\tconst existing = await this.existingWritablePath(candidate, path);\n\t\tif (existing) return existing;\n\t\tawait this.ensureConfinedWritableParent(candidate, path);\n\t\treturn candidate;\n\t}\n\n\tprivate async atomicWriteFile(path: string, content: string | Buffer): Promise<void> {\n\t\tconst target = await this.writablePath(path);\n\t\tconst parent = resolve(target, \"..\");\n\t\tconst temporary = resolve(parent, `.grip-remote-write-${process.pid}-${randomUUID()}-${basename(target)}.tmp`);\n\t\tthis.lexicalPath(temporary);\n\t\tlet wroteTemporary = false;\n\t\ttry {\n\t\t\tconst handle = await open(temporary, \"wx\", 0o600);\n\t\t\ttry {\n\t\t\t\tawait handle.writeFile(content, typeof content === \"string\" ? \"utf8\" : undefined);\n\t\t\t} finally {\n\t\t\t\tawait handle.close();\n\t\t\t}\n\t\t\twroteTemporary = true;\n\t\t\tthis.lexicalPath(await realpath(temporary));\n\t\t\ttry {\n\t\t\t\tif ((await lstat(target)).isSymbolicLink()) throw new Error(`Writable path uses a symbolic link: ${path}`);\n\t\t\t} catch (error) {\n\t\t\t\tif (!isMissingPath(error)) throw error;\n\t\t\t}\n\t\t\tawait rename(temporary, target);\n\t\t\twroteTemporary = false;\n\t\t\tthis.lexicalPath(await realpath(target));\n\t\t} finally {\n\t\t\tif (wroteTemporary) await rm(temporary, { force: true });\n\t\t}\n\t}\n\n\tasync exec(command: string, options: ToolExecOptions): Promise<ToolExecResult> {\n\t\tif (!this.allowProcessExec) throw new Error(\"Process execution is disabled by daemon policy\");\n\t\tconst cwd = await this.existingPath(options.cwd ?? this.cwd);\n\t\tconst environment = { ...this.environment };\n\t\tfor (const name of GRIP_SESSION_ENVIRONMENT_NAMES) {\n\t\t\tconst value = options.env?.[name];\n\t\t\tif (value !== undefined) environment[name] = value;\n\t\t}\n\t\treturn this.local.exec(command, { ...options, cwd, env: environment });\n\t}\n\n\tasync access(path: string, mode?: ToolAccessMode): Promise<void> {\n\t\tawait this.local.access(await this.existingPath(path), mode);\n\t}\n\n\tasync readFile(path: string): Promise<Buffer> {\n\t\treturn this.local.readFile(await this.existingPath(path));\n\t}\n\n\tasync writeFile(path: string, content: string | Buffer): Promise<void> {\n\t\tawait this.atomicWriteFile(path, content);\n\t}\n\n\tasync mkdir(path: string, options?: ToolMkdirOptions): Promise<void> {\n\t\tawait fsMkdir(await this.writablePath(path), options);\n\t}\n\n\tasync stat(path: string): Promise<ToolFileStat> {\n\t\treturn this.local.stat(await this.existingPath(path));\n\t}\n\n\tasync readdir(path: string): Promise<string[]> {\n\t\treturn this.local.readdir(await this.existingPath(path));\n\t}\n\n\tasync glob(pattern: string, cwd: string, options: ToolGlobOptions): Promise<string[]> {\n\t\tconst searchRoot = await this.existingPath(cwd);\n\t\tconst args = [\"--glob\", \"--color=never\", \"--hidden\", \"--no-require-git\", \"--max-results\", String(options.limit)];\n\t\tfor (const ignored of options.ignore) args.push(\"--exclude\", ignored);\n\t\tlet effectivePattern = pattern;\n\t\tif (pattern.includes(\"/\")) {\n\t\t\targs.push(\"--full-path\");\n\t\t\tif (!pattern.startsWith(\"/\") && !pattern.startsWith(\"**/\") && pattern !== \"**\")\n\t\t\t\teffectivePattern = `**/${pattern}`;\n\t\t}\n\t\targs.push(\"--\", effectivePattern, searchRoot);\n\t\tconst output = await runCommand(\"fd\", args, this.environment, this.maxBufferedOutputBytes);\n\t\tconst results: string[] = [];\n\t\tfor (const entry of output.toString(\"utf8\").split(\"\\n\")) {\n\t\t\tif (!entry) continue;\n\t\t\ttry {\n\t\t\t\tresults.push(await this.existingPath(entry));\n\t\t\t} catch {\n\t\t\t\t// Symlinks escaping the workspace are deliberately omitted.\n\t\t\t}\n\t\t}\n\t\treturn results;\n\t}\n\n\tasync grep(options: ToolGrepOptions): Promise<ToolGrepResult> {\n\t\tconst searchPath = await this.existingPath(options.path);\n\t\tconst isDirectory = (await this.local.stat(searchPath)).isDirectory();\n\t\tconst args = [\"--json\", \"--line-number\", \"--color=never\", \"--hidden\"];\n\t\tif (options.ignoreCase) args.push(\"--ignore-case\");\n\t\tif (options.literal) args.push(\"--fixed-strings\");\n\t\tif (options.glob) args.push(\"--glob\", options.glob);\n\t\targs.push(\"--\", options.pattern, searchPath);\n\t\tconst output = await runCommand(\"rg\", args, this.environment, this.maxBufferedOutputBytes);\n\t\tconst matches: ToolGrepMatch[] = [];\n\t\tfor (const line of output.toString(\"utf8\").split(\"\\n\")) {\n\t\t\tif (matches.length >= options.limit) continue;\n\t\t\tconst match = parseDaemonGrepMatch(line);\n\t\t\tif (!match) continue;\n\t\t\ttry {\n\t\t\t\tawait this.existingPath(match.filePath);\n\t\t\t} catch {\n\t\t\t\tcontinue;\n\t\t\t}\n\t\t\tmatches.push(match);\n\t\t}\n\t\treturn { isDirectory, matches };\n\t}\n\n\tasync detectImageMimeType(path: string): Promise<string | null | undefined> {\n\t\treturn this.local.detectImageMimeType(await this.existingPath(path));\n\t}\n\n\tgetBackendInfo(): ToolBackendInfo {\n\t\treturn { type: \"local\", cwd: this.cwd };\n\t}\n}\n\nexport interface DaemonWorkspaceRuntime {\n\treadonly operations: ConfinedDaemonToolOperations;\n\treadonly host: WorkspaceToolHost;\n\treadonly lspRuntime?: LspRuntimeState;\n\treadonly catalog: RemoteWorkspaceCatalog;\n\treadonly capabilities: readonly RemoteWorkspaceCapability[];\n\tcreateHandler(workspace: RemoteWorkspaceIdentity, sharedMode?: boolean): RemoteWorkspaceServerHandler;\n\tretire(): Promise<void>;\n\tdispose(): Promise<void>;\n}\n\ntype DaemonRequestInterruptionCode = \"cancelled\" | \"deadline_exceeded\";\ntype DaemonInterruptedExecutionState = \"not_started\" | \"indeterminate\";\n\nfunction requestError(code: DaemonRequestInterruptionCode, message: string, state: DaemonInterruptedExecutionState) {\n\treturn new RemoteWorkspaceRequestError({ code, message, executionState: state, retryable: false });\n}\ninterface DaemonRequestRuntime {\n\tconfiguration: DaemonConfiguration;\n\toperations: ConfinedDaemonToolOperations;\n\thost: WorkspaceToolHost;\n\tlspRuntime: LspRuntimeState | undefined;\n\tworkspace: RemoteWorkspaceIdentity;\n\tsharedMode: boolean;\n}\n\nfunction withDaemonWorkspace<T extends Record<string, unknown>>(result: T, workspace: RemoteWorkspaceIdentity) {\n\treturn { ...result, workspace };\n}\n\nasync function synchronizeDaemonToolFile(\n\ttoolName: string,\n\tinvocationArguments: unknown,\n\truntime: DaemonRequestRuntime,\n): Promise<void> {\n\tif (!runtime.lspRuntime) return;\n\tconst args = invocationArguments as { path?: unknown };\n\tif (typeof args.path !== \"string\") return;\n\ttry {\n\t\tif (toolName === \"read\") {\n\t\t\tawait runtime.lspRuntime.fileSync.handleFileRead(args.path, runtime.operations);\n\t\t} else if (toolName === \"write\" || toolName === \"edit\") {\n\t\t\tawait runtime.lspRuntime.fileSync.handleFileWrite(args.path, runtime.operations);\n\t\t}\n\t} catch {\n\t\t// Synchronization remains best-effort, matching local AgentSession behavior.\n\t}\n}\n\nfunction marksToolSideEffect(kind: RemoteWorkspaceOperationKind, toolName: string, sharedMode: boolean): boolean {\n\treturn kind !== \"read\" && !(sharedMode && (toolName === \"edit\" || toolName === \"write\"));\n}\n\nasync function invokeDaemonTool(\n\trequest: RemoteWorkspaceTypedRequest,\n\tparams: Record<string, unknown>,\n\tcontext: RemoteWorkspaceServerRequestContext,\n\truntime: DaemonRequestRuntime,\n): Promise<AgentToolResult<unknown>> {\n\tconst toolName = params.toolName as string;\n\tconst kind = operationKind(toolName);\n\tif (marksToolSideEffect(kind, toolName, runtime.sharedMode)) context.markSideEffectStarted();\n\tlet updateQueue = Promise.resolve();\n\ttry {\n\t\tconst result = await runtime.host.executePrepared(toolName, {\n\t\t\ttoolCallId: request.id,\n\t\t\targuments: params.arguments,\n\t\t\tsignal: context.signal,\n\t\t\texecutionOptions: params.executionOptions as WorkspaceToolExecutionOptions,\n\t\t\tonUpdate: (update) => {\n\t\t\t\tupdateQueue = updateQueue.then(() => context.sendUpdate(portableToolResult(update)));\n\t\t\t},\n\t\t});\n\t\tawait updateQueue;\n\t\tawait synchronizeDaemonToolFile(toolName, params.arguments, runtime);\n\t\tif (kind !== \"read\") context.markCommitted();\n\t\treturn portableToolResult(result);\n\t} catch (error) {\n\t\tawait updateQueue.catch(() => undefined);\n\t\tif (context.signal.aborted) {\n\t\t\tthrow requestError(\n\t\t\t\t\"cancelled\",\n\t\t\t\t\"Remote workspace tool invocation was cancelled\",\n\t\t\t\tkind === \"read\" ? \"not_started\" : \"indeterminate\",\n\t\t\t);\n\t\t}\n\t\tif (error instanceof RemoteWorkspaceRequestError) throw error;\n\t\tthrow new RemoteWorkspaceRequestError({\n\t\t\tcode: \"internal_error\",\n\t\t\tmessage: error instanceof Error ? error.message.slice(0, 4096) : \"Workspace tool failed\",\n\t\t\texecutionState: kind === \"read\" ? \"not_started\" : \"indeterminate\",\n\t\t\tretryable: false,\n\t\t});\n\t}\n}\n\nasync function executeDaemonWorkspaceProcess(\n\tparams: Record<string, unknown>,\n\tcontext: RemoteWorkspaceServerRequestContext,\n\truntime: DaemonRequestRuntime,\n): Promise<ToolExecResult> {\n\tcontext.markSideEffectStarted();\n\tlet updateQueue = Promise.resolve();\n\tlet pendingOutputBytes = 0;\n\tlet outputLimitExceeded = false;\n\tconst outputController = new AbortController();\n\tconst signal = AbortSignal.any([context.signal, outputController.signal]);\n\tlet result: ToolExecResult;\n\ttry {\n\t\tresult = await runtime.operations.exec(params.command as string, {\n\t\t\tcwd: params.cwd as string,\n\t\t\tsignal,\n\t\t\tonData: (data) => {\n\t\t\t\tif (outputLimitExceeded) return;\n\t\t\t\tconst chunk = Buffer.from(data);\n\t\t\t\tpendingOutputBytes += chunk.byteLength;\n\t\t\t\tif (pendingOutputBytes > runtime.configuration.maxBufferedOutputBytes) {\n\t\t\t\t\toutputLimitExceeded = true;\n\t\t\t\t\toutputController.abort();\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t\tupdateQueue = updateQueue\n\t\t\t\t\t.then(() => context.sendUpdate({ dataBase64: chunk.toString(\"base64\") }))\n\t\t\t\t\t.finally(() => {\n\t\t\t\t\t\tpendingOutputBytes -= chunk.byteLength;\n\t\t\t\t\t});\n\t\t\t\t// The process may run after an update fails; observe rejection until the final await.\n\t\t\t\tvoid updateQueue.catch(() => undefined);\n\t\t\t},\n\t\t});\n\t} catch (error) {\n\t\tif (outputLimitExceeded) throw new Error(\"Process output exceeded the daemon buffered-output limit\");\n\t\tthrow error;\n\t}\n\tawait updateQueue;\n\tcontext.markCommitted();\n\treturn result;\n}\n\nasync function readDaemonResource(\n\tparams: Record<string, unknown>,\n\truntime: DaemonRequestRuntime,\n): Promise<Record<string, unknown>> {\n\tconst path = params.path as string;\n\tconst resourcePath =\n\t\tpath === \"SANDBOX.md\"\n\t\t\t? runtime.configuration.sandboxInstructionsPath\n\t\t\t: path === \"AGENTS.md\"\n\t\t\t\t? runtime.configuration.userAgentsPath\n\t\t\t\t: undefined;\n\tif (!resourcePath) {\n\t\tthrow new RemoteWorkspaceRequestError({\n\t\t\tcode: \"not_available\",\n\t\t\tmessage: \"Requested daemon resource is not available\",\n\t\t\texecutionState: \"not_started\",\n\t\t\tretryable: false,\n\t\t});\n\t}\n\treturn withDaemonWorkspace({ contentBase64: (await readFile(resourcePath)).toString(\"base64\") }, runtime.workspace);\n}\n\nfunction getDaemonLspStatus(runtime: DaemonRequestRuntime): Record<string, unknown> {\n\tif (!runtime.lspRuntime) {\n\t\tthrow new RemoteWorkspaceRequestError({\n\t\t\tcode: \"not_available\",\n\t\t\tmessage: \"Daemon LSP is not configured\",\n\t\t\texecutionState: \"not_started\",\n\t\t\tretryable: false,\n\t\t});\n\t}\n\treturn {\n\t\tenabled: true,\n\t\tservers: runtime.lspRuntime.manager.getStatus().map((status) => sanitizeLspStatus(status, runtime.configuration)),\n\t};\n}\nasync function statDaemonWorkspace(path: string, runtime: DaemonRequestRuntime): Promise<unknown> {\n\ttry {\n\t\tconst value = await runtime.operations.stat(path);\n\t\treturn withDaemonWorkspace(\n\t\t\t{ kind: value.isDirectory() ? \"directory\" : value.isFile() ? \"file\" : \"other\" },\n\t\t\truntime.workspace,\n\t\t);\n\t} catch (error) {\n\t\tif (!runtime.sharedMode || !isMissingPath(error)) throw error;\n\t\treturn withDaemonWorkspace({ kind: \"absent\" }, runtime.workspace);\n\t}\n}\n\nasync function dispatchDaemonWorkspaceRequest(\n\trequest: RemoteWorkspaceTypedRequest,\n\tcontext: RemoteWorkspaceServerRequestContext,\n\truntime: DaemonRequestRuntime,\n): Promise<unknown> {\n\tconst params = request.params as Record<string, unknown>;\n\tswitch (request.method) {\n\t\tcase \"tool.invoke\":\n\t\t\treturn invokeDaemonTool(request, params, context, runtime);\n\t\tcase \"workspace.access\":\n\t\t\tawait runtime.operations.access(params.path as string, params.mode as ToolAccessMode | undefined);\n\t\t\treturn {};\n\t\tcase \"workspace.read\":\n\t\t\treturn withDaemonWorkspace(\n\t\t\t\t{ contentBase64: (await runtime.operations.readFile(params.path as string)).toString(\"base64\") },\n\t\t\t\truntime.workspace,\n\t\t\t);\n\t\tcase \"workspace.write\":\n\t\t\tif (!runtime.sharedMode) context.markSideEffectStarted();\n\t\t\tawait withFileMutationQueue(resolve(runtime.configuration.workspaceRoot, params.path as string), () =>\n\t\t\t\truntime.operations.writeFile(params.path as string, Buffer.from(params.contentBase64 as string, \"base64\")),\n\t\t\t);\n\t\t\tcontext.markCommitted();\n\t\t\treturn {};\n\t\tcase \"workspace.mkdir\":\n\t\t\tif (!runtime.sharedMode) context.markSideEffectStarted();\n\t\t\tawait withFileMutationQueue(resolve(runtime.configuration.workspaceRoot, params.path as string), () => {\n\t\t\t\tif (runtime.sharedMode) {\n\t\t\t\t\tif (context.signal.aborted)\n\t\t\t\t\t\tthrow requestError(\n\t\t\t\t\t\t\t\"cancelled\",\n\t\t\t\t\t\t\t\"Shared directory creation was cancelled before starting\",\n\t\t\t\t\t\t\t\"not_started\",\n\t\t\t\t\t\t);\n\t\t\t\t\tcontext.markSideEffectStarted();\n\t\t\t\t}\n\t\t\t\treturn runtime.operations.mkdir(params.path as string, { recursive: params.recursive === true });\n\t\t\t});\n\t\t\tcontext.markCommitted();\n\t\t\treturn {};\n\t\tcase \"workspace.stat\":\n\t\t\treturn statDaemonWorkspace(params.path as string, runtime);\n\t\tcase \"workspace.readdir\":\n\t\t\treturn withDaemonWorkspace(\n\t\t\t\t{ entries: await runtime.operations.readdir(params.path as string) },\n\t\t\t\truntime.workspace,\n\t\t\t);\n\t\tcase \"workspace.glob\":\n\t\t\treturn withDaemonWorkspace(\n\t\t\t\t{\n\t\t\t\t\tmatches: await runtime.operations.glob(params.pattern as string, params.cwd as string, {\n\t\t\t\t\t\tignore: params.ignore as string[],\n\t\t\t\t\t\tlimit: params.limit as number,\n\t\t\t\t\t}),\n\t\t\t\t},\n\t\t\t\truntime.workspace,\n\t\t\t);\n\t\tcase \"workspace.grep\": {\n\t\t\tconst result = await runtime.operations.grep(params as unknown as ToolGrepOptions);\n\t\t\treturn withDaemonWorkspace(result as unknown as Record<string, unknown>, runtime.workspace);\n\t\t}\n\t\tcase \"workspace.detect_image_mime\":\n\t\t\treturn withDaemonWorkspace(\n\t\t\t\t{ mimeType: (await runtime.operations.detectImageMimeType(params.path as string)) ?? null },\n\t\t\t\truntime.workspace,\n\t\t\t);\n\t\tcase \"workspace.exec\":\n\t\t\treturn executeDaemonWorkspaceProcess(params, context, runtime);\n\t\tcase \"resource.read\":\n\t\t\treturn readDaemonResource(params, runtime);\n\t\tcase \"lsp.status\":\n\t\t\treturn getDaemonLspStatus(runtime);\n\t\tdefault:\n\t\t\tthrow new RemoteWorkspaceRequestError({\n\t\t\t\tcode: \"method_not_supported\",\n\t\t\t\tmessage: `Workspace operation is not implemented: ${request.method}`,\n\t\t\t\texecutionState: \"not_started\",\n\t\t\t\tretryable: false,\n\t\t\t});\n\t}\n}\n\nexport function createDaemonWorkspaceRuntime(configuration: DaemonConfiguration): DaemonWorkspaceRuntime {\n\tconst operations = new ConfinedDaemonToolOperations(configuration);\n\tconst toolNames: WorkspaceToolName[] = [\"read\", \"edit\", \"write\", \"grep\", \"find\", \"ls\"];\n\tif (configuration.allowProcessExec) toolNames.splice(1, 0, \"bash\");\n\tconst lspConfiguration = loadDaemonLspConfiguration(configuration);\n\tconst lspRuntime = lspConfiguration.enabled\n\t\t? createLspRuntimeState(configuration.workspaceRoot, {\n\t\t\t\tconfiguration: lspConfiguration,\n\t\t\t\tgetToolBackendInfo: () => operations.getBackendInfo(),\n\t\t\t\tgetToolOperations: () => operations,\n\t\t\t\tresolveConnectionFactory: (transport) =>\n\t\t\t\t\ttransport.type === \"spawn\"\n\t\t\t\t\t\t? createManagedStdioConnectionFactory({\n\t\t\t\t\t\t\t\t...transport,\n\t\t\t\t\t\t\t\tenv: operations.createChildEnvironment(transport.env),\n\t\t\t\t\t\t\t\tinheritEnvironment: false,\n\t\t\t\t\t\t\t})\n\t\t\t\t\t\t: resolveLspConnectionFactory(transport),\n\t\t\t})\n\t\t: undefined;\n\tconst host = new WorkspaceToolHost({\n\t\tcwd: configuration.workspaceRoot,\n\t\toperations,\n\t\ttoolNames,\n\t\tadditionalDefinitions: lspRuntime\n\t\t\t? createLspToolDefinitions(\n\t\t\t\t\t() => lspRuntime,\n\t\t\t\t\t() => operations,\n\t\t\t\t)\n\t\t\t: undefined,\n\t\tdisposeTimeoutMs: Math.min(configuration.shutdownTimeoutMs, 60_000),\n\t});\n\tconst catalog: RemoteWorkspaceCatalog = {\n\t\tgeneration: 1,\n\t\ttools: host.getCatalog().map((entry) => ({\n\t\t\tname: entry.name,\n\t\t\texecutionMode: operationKind(entry.name),\n\t\t\tparameterSchema: structuredClone(entry.parameters) as Record<string, unknown>,\n\t\t\tschemaHash: hashRemoteWorkspaceJson(entry.parameters),\n\t\t\tfeatureFlags: [],\n\t\t})),\n\t\toperations: [\n\t\t\t...PRIMITIVE_OPERATIONS.filter((method) => method !== \"workspace.exec\" || configuration.allowProcessExec),\n\t\t\t...(configuration.sandboxInstructionsPath || configuration.userAgentsPath ? ([\"resource.read\"] as const) : []),\n\t\t\t...(lspRuntime ? ([\"lsp.status\"] as const) : []),\n\t\t],\n\t};\n\tconst capabilities: RemoteWorkspaceCapability[] = [\n\t\t\"catalog_refresh\",\n\t\t\"primitive_operations\",\n\t\t\"tool_updates\",\n\t\t...(lspRuntime ? ([\"lsp_status\"] as const) : []),\n\t];\n\tlet activeRequests = 0;\n\n\treturn {\n\t\toperations,\n\t\thost,\n\t\tlspRuntime,\n\t\tcatalog,\n\t\tcapabilities,\n\t\tcreateHandler(workspace, sharedMode = false) {\n\t\t\tconst requestRuntime: DaemonRequestRuntime = {\n\t\t\t\tconfiguration,\n\t\t\t\toperations,\n\t\t\t\thost,\n\t\t\t\tlspRuntime,\n\t\t\t\tworkspace,\n\t\t\t\tsharedMode,\n\t\t\t};\n\t\t\treturn {\n\t\t\t\tvalidateToolArguments: (toolName, value) => host.validatePreparedArguments(toolName, value),\n\t\t\t\tasync handleRequest(request, context) {\n\t\t\t\t\tif (activeRequests >= configuration.maxGlobalRequests) {\n\t\t\t\t\t\tthrow new RemoteWorkspaceRequestError({\n\t\t\t\t\t\t\tcode: \"limit_exceeded\",\n\t\t\t\t\t\t\tmessage: \"Daemon global active request limit reached\",\n\t\t\t\t\t\t\texecutionState: \"not_started\",\n\t\t\t\t\t\t\tretryable: true,\n\t\t\t\t\t\t});\n\t\t\t\t\t}\n\t\t\t\t\tactiveRequests++;\n\t\t\t\t\ttry {\n\t\t\t\t\t\treturn await dispatchDaemonWorkspaceRequest(request, context, requestRuntime);\n\t\t\t\t\t} finally {\n\t\t\t\t\t\tactiveRequests--;\n\t\t\t\t\t}\n\t\t\t\t},\n\t\t\t};\n\t\t},\n\t\tretire: async () => {\n\t\t\tawait host.waitForIdle(configuration.shutdownTimeoutMs);\n\t\t\tawait lspRuntime?.manager.shutdownAll();\n\t\t\tawait host.dispose();\n\t\t},\n\t\tdispose: async () => {\n\t\t\tawait Promise.all([lspRuntime?.manager.shutdownAll(), host.dispose()]);\n\t\t},\n\t};\n}\n"]}
|
|
@@ -421,10 +421,13 @@ async function synchronizeDaemonToolFile(toolName, invocationArguments, runtime)
|
|
|
421
421
|
// Synchronization remains best-effort, matching local AgentSession behavior.
|
|
422
422
|
}
|
|
423
423
|
}
|
|
424
|
+
function marksToolSideEffect(kind, toolName, sharedMode) {
|
|
425
|
+
return kind !== "read" && !(sharedMode && (toolName === "edit" || toolName === "write"));
|
|
426
|
+
}
|
|
424
427
|
async function invokeDaemonTool(request, params, context, runtime) {
|
|
425
428
|
const toolName = params.toolName;
|
|
426
429
|
const kind = operationKind(toolName);
|
|
427
|
-
if (kind
|
|
430
|
+
if (marksToolSideEffect(kind, toolName, runtime.sharedMode))
|
|
428
431
|
context.markSideEffectStarted();
|
|
429
432
|
let updateQueue = Promise.resolve();
|
|
430
433
|
try {
|
|
@@ -448,6 +451,8 @@ async function invokeDaemonTool(request, params, context, runtime) {
|
|
|
448
451
|
if (context.signal.aborted) {
|
|
449
452
|
throw requestError("cancelled", "Remote workspace tool invocation was cancelled", kind === "read" ? "not_started" : "indeterminate");
|
|
450
453
|
}
|
|
454
|
+
if (error instanceof RemoteWorkspaceRequestError)
|
|
455
|
+
throw error;
|
|
451
456
|
throw new RemoteWorkspaceRequestError({
|
|
452
457
|
code: "internal_error",
|
|
453
458
|
message: error instanceof Error ? error.message.slice(0, 4096) : "Workspace tool failed",
|
|
@@ -483,6 +488,8 @@ async function executeDaemonWorkspaceProcess(params, context, runtime) {
|
|
|
483
488
|
.finally(() => {
|
|
484
489
|
pendingOutputBytes -= chunk.byteLength;
|
|
485
490
|
});
|
|
491
|
+
// The process may run after an update fails; observe rejection until the final await.
|
|
492
|
+
void updateQueue.catch(() => undefined);
|
|
486
493
|
},
|
|
487
494
|
});
|
|
488
495
|
}
|
|
@@ -526,6 +533,17 @@ function getDaemonLspStatus(runtime) {
|
|
|
526
533
|
servers: runtime.lspRuntime.manager.getStatus().map((status) => sanitizeLspStatus(status, runtime.configuration)),
|
|
527
534
|
};
|
|
528
535
|
}
|
|
536
|
+
async function statDaemonWorkspace(path, runtime) {
|
|
537
|
+
try {
|
|
538
|
+
const value = await runtime.operations.stat(path);
|
|
539
|
+
return withDaemonWorkspace({ kind: value.isDirectory() ? "directory" : value.isFile() ? "file" : "other" }, runtime.workspace);
|
|
540
|
+
}
|
|
541
|
+
catch (error) {
|
|
542
|
+
if (!runtime.sharedMode || !isMissingPath(error))
|
|
543
|
+
throw error;
|
|
544
|
+
return withDaemonWorkspace({ kind: "absent" }, runtime.workspace);
|
|
545
|
+
}
|
|
546
|
+
}
|
|
529
547
|
async function dispatchDaemonWorkspaceRequest(request, context, runtime) {
|
|
530
548
|
const params = request.params;
|
|
531
549
|
switch (request.method) {
|
|
@@ -537,19 +555,26 @@ async function dispatchDaemonWorkspaceRequest(request, context, runtime) {
|
|
|
537
555
|
case "workspace.read":
|
|
538
556
|
return withDaemonWorkspace({ contentBase64: (await runtime.operations.readFile(params.path)).toString("base64") }, runtime.workspace);
|
|
539
557
|
case "workspace.write":
|
|
540
|
-
|
|
558
|
+
if (!runtime.sharedMode)
|
|
559
|
+
context.markSideEffectStarted();
|
|
541
560
|
await withFileMutationQueue(resolve(runtime.configuration.workspaceRoot, params.path), () => runtime.operations.writeFile(params.path, Buffer.from(params.contentBase64, "base64")));
|
|
542
561
|
context.markCommitted();
|
|
543
562
|
return {};
|
|
544
563
|
case "workspace.mkdir":
|
|
545
|
-
|
|
546
|
-
|
|
564
|
+
if (!runtime.sharedMode)
|
|
565
|
+
context.markSideEffectStarted();
|
|
566
|
+
await withFileMutationQueue(resolve(runtime.configuration.workspaceRoot, params.path), () => {
|
|
567
|
+
if (runtime.sharedMode) {
|
|
568
|
+
if (context.signal.aborted)
|
|
569
|
+
throw requestError("cancelled", "Shared directory creation was cancelled before starting", "not_started");
|
|
570
|
+
context.markSideEffectStarted();
|
|
571
|
+
}
|
|
572
|
+
return runtime.operations.mkdir(params.path, { recursive: params.recursive === true });
|
|
573
|
+
});
|
|
547
574
|
context.markCommitted();
|
|
548
575
|
return {};
|
|
549
|
-
case "workspace.stat":
|
|
550
|
-
|
|
551
|
-
return withDaemonWorkspace({ kind: value.isDirectory() ? "directory" : value.isFile() ? "file" : "other" }, runtime.workspace);
|
|
552
|
-
}
|
|
576
|
+
case "workspace.stat":
|
|
577
|
+
return statDaemonWorkspace(params.path, runtime);
|
|
553
578
|
case "workspace.readdir":
|
|
554
579
|
return withDaemonWorkspace({ entries: await runtime.operations.readdir(params.path) }, runtime.workspace);
|
|
555
580
|
case "workspace.glob":
|
|
@@ -637,8 +662,15 @@ export function createDaemonWorkspaceRuntime(configuration) {
|
|
|
637
662
|
lspRuntime,
|
|
638
663
|
catalog,
|
|
639
664
|
capabilities,
|
|
640
|
-
createHandler(workspace) {
|
|
641
|
-
const requestRuntime = {
|
|
665
|
+
createHandler(workspace, sharedMode = false) {
|
|
666
|
+
const requestRuntime = {
|
|
667
|
+
configuration,
|
|
668
|
+
operations,
|
|
669
|
+
host,
|
|
670
|
+
lspRuntime,
|
|
671
|
+
workspace,
|
|
672
|
+
sharedMode,
|
|
673
|
+
};
|
|
642
674
|
return {
|
|
643
675
|
validateToolArguments: (toolName, value) => host.validatePreparedArguments(toolName, value),
|
|
644
676
|
async handleRequest(request, context) {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"workspace-runtime.js","sourceRoot":"","sources":["../../src/daemon/workspace-runtime.ts"],"names":[],"mappings":"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","sourcesContent":["import { spawn } from \"node:child_process\";\nimport { randomUUID } from \"node:crypto\";\nimport { mkdir as fsMkdir, lstat, open, readFile, realpath, rename, rm } from \"node:fs/promises\";\nimport { basename, isAbsolute, relative, resolve, sep } from \"node:path\";\nimport type { AgentToolResult } from \"@greppleai/grip-agent-core\";\nimport { createLspRuntimeState, createLspToolDefinitions, type LspRuntimeState } from \"../core/lsp/integration.ts\";\nimport type { LspServerStatus } from \"../core/lsp/manager.ts\";\nimport { createManagedStdioConnectionFactory, resolveLspConnectionFactory } from \"../core/lsp/transport.ts\";\nimport {\n\thashRemoteWorkspaceJson,\n\ttype RemoteWorkspaceCapability,\n\ttype RemoteWorkspaceCatalog,\n\ttype RemoteWorkspaceIdentity,\n\ttype RemoteWorkspaceMethod,\n\ttype RemoteWorkspaceOperationKind,\n} from \"../core/remote-workspace-protocol/contract.ts\";\nimport {\n\tRemoteWorkspaceRequestError,\n\ttype RemoteWorkspaceServerHandler,\n\ttype RemoteWorkspaceServerRequestContext,\n\ttype RemoteWorkspaceTypedRequest,\n} from \"../core/remote-workspace-protocol/session.ts\";\nimport { withFileMutationQueue } from \"../core/tools/file-mutation-queue.ts\";\nimport {\n\tGRIP_SESSION_ENVIRONMENT_NAMES,\n\tLocalToolOperations,\n\ttype ToolAccessMode,\n\ttype ToolBackendInfo,\n\ttype ToolExecOptions,\n\ttype ToolExecResult,\n\ttype ToolFileStat,\n\ttype ToolGlobOptions,\n\ttype ToolGrepMatch,\n\ttype ToolGrepOptions,\n\ttype ToolGrepResult,\n\ttype ToolMkdirOptions,\n\ttype ToolOperations,\n\ttype WorkspaceToolExecutionOptions,\n} from \"../core/tools/operations.ts\";\nimport { WorkspaceToolHost, type WorkspaceToolName } from \"../core/tools/workspace-tool-host.ts\";\nimport type { DaemonConfiguration } from \"./config.ts\";\nimport { loadDaemonLspConfiguration } from \"./lsp-config.ts\";\nimport { redactDaemonText } from \"./security.ts\";\n\nconst PRIMITIVE_OPERATIONS: RemoteWorkspaceMethod[] = [\n\t\"workspace.access\",\n\t\"workspace.read\",\n\t\"workspace.write\",\n\t\"workspace.mkdir\",\n\t\"workspace.stat\",\n\t\"workspace.readdir\",\n\t\"workspace.glob\",\n\t\"workspace.grep\",\n\t\"workspace.detect_image_mime\",\n\t\"workspace.exec\",\n];\n\nconst SECRET_ENVIRONMENT_SUFFIX = /_(?:API_KEY|TOKEN|SECRET|PASSWORD|PRIVATE_KEY|CREDENTIALS)$/iu;\nconst BASELINE_ENVIRONMENT =\n\tprocess.platform === \"win32\"\n\t\t? [\"PATH\", \"PATHEXT\", \"SYSTEMROOT\", \"COMSPEC\", \"TEMP\", \"TMP\", \"USER\", \"USERNAME\"]\n\t\t: [\"PATH\", \"HOME\", \"USER\", \"LOGNAME\", \"SHELL\", \"LANG\", \"TERM\", \"COLORTERM\", \"NO_COLOR\", \"TMPDIR\"];\n\nfunction isSecretEnvironmentName(name: string): boolean {\n\tconst upper = name.toUpperCase();\n\treturn (\n\t\tupper === \"GRIP_DAEMON_TOKEN\" ||\n\t\tupper === \"PI_DAEMON_TOKEN\" ||\n\t\tupper === \"GRIP_REMOTE_TOKEN\" ||\n\t\tupper.startsWith(\"GRIP_DAEMON_TLS_\") ||\n\t\tupper.startsWith(\"PI_DAEMON_TLS_\") ||\n\t\tSECRET_ENVIRONMENT_SUFFIX.test(upper)\n\t);\n}\nprocess.platform === \"win32\"\n\t? [\"PATH\", \"PATHEXT\", \"SYSTEMROOT\", \"TEMP\", \"TMP\"]\n\t: [\"PATH\", \"HOME\", \"LANG\", \"LC_ALL\", \"TERM\", \"TMPDIR\"];\n\nfunction isMissingPath(error: unknown): boolean {\n\treturn error instanceof Error && \"code\" in error && error.code === \"ENOENT\";\n}\n\nfunction sanitizeLspStatus(\n\tstatus: LspServerStatus,\n\tconfiguration: DaemonConfiguration,\n): Omit<LspServerStatus, \"capabilities\"> {\n\tconst { capabilities: _capabilities, ...safe } = status;\n\tconst secrets = [configuration.token, configuration.tls?.passphrase];\n\tconst redact = (value: string | undefined) => (value ? redactDaemonText(value, secrets) : undefined);\n\treturn {\n\t\t...safe,\n\t\tserverId: redact(safe.serverId)!,\n\t\tlanguageIds: safe.languageIds.map((value) => redact(value)!),\n\t\ttransport: redact(safe.transport)!,\n\t\t...(safe.instanceKey ? { instanceKey: redact(safe.instanceKey) } : {}),\n\t\t...(safe.workspaceRoot ? { workspaceRoot: redact(safe.workspaceRoot) } : {}),\n\t\t...(safe.rootUri ? { rootUri: redact(safe.rootUri) } : {}),\n\t\t...(safe.endpoint ? { endpoint: redact(safe.endpoint) } : {}),\n\t\t...(safe.lastError ? { lastError: redact(safe.lastError) } : {}),\n\t\t...(safe.lastRequestError ? { lastRequestError: redact(safe.lastRequestError) } : {}),\n\t\t...(safe.stderr ? { stderr: redact(safe.stderr) } : {}),\n\t\t...(safe.synchronizationError ? { synchronizationError: redact(safe.synchronizationError) } : {}),\n\t};\n}\n\nfunction portableToolResult(result: AgentToolResult<unknown>): AgentToolResult<unknown> {\n\tconst clone = JSON.parse(JSON.stringify(result)) as AgentToolResult<unknown>;\n\tconst details = clone.details;\n\tif (!details || typeof details !== \"object\" || !(\"fullOutputPath\" in details)) return clone;\n\tconst fullOutputPath = (details as { fullOutputPath?: unknown }).fullOutputPath;\n\tif (typeof fullOutputPath !== \"string\") return clone;\n\tdelete (details as { fullOutputPath?: unknown }).fullOutputPath;\n\tfor (const content of clone.content) {\n\t\tif (content.type === \"text\") {\n\t\t\tcontent.text = content.text.replaceAll(fullOutputPath, \"[remote full output is not transferable]\");\n\t\t}\n\t}\n\treturn clone;\n}\n\nfunction operationKind(name: string): RemoteWorkspaceOperationKind {\n\tif (name.startsWith(\"lsp_\")) return \"service\";\n\tswitch (name) {\n\t\tcase \"read\":\n\t\tcase \"grep\":\n\t\tcase \"find\":\n\t\tcase \"ls\":\n\t\t\treturn \"read\";\n\t\tcase \"edit\":\n\t\tcase \"write\":\n\t\t\treturn \"mutation\";\n\t\tcase \"bash\":\n\t\t\treturn \"process\";\n\t}\n\tthrow new Error(`Unknown daemon tool: ${name}`);\n}\n\nfunction runCommand(\n\tcommand: string,\n\targs: string[],\n\tenvironment: NodeJS.ProcessEnv,\n\tmaxBufferedBytes: number,\n): Promise<Buffer> {\n\treturn new Promise((resolvePromise, reject) => {\n\t\tconst child = spawn(command, args, { stdio: [\"ignore\", \"pipe\", \"pipe\"], windowsHide: true, env: environment });\n\t\tconst stdout: Buffer[] = [];\n\t\tconst stderr: Buffer[] = [];\n\t\tlet bufferedBytes = 0;\n\t\tlet settled = false;\n\t\tconst append = (target: Buffer[], chunk: Buffer) => {\n\t\t\tif (settled) return;\n\t\t\tbufferedBytes += chunk.byteLength;\n\t\t\tif (bufferedBytes > maxBufferedBytes) {\n\t\t\t\tsettled = true;\n\t\t\t\tchild.kill();\n\t\t\t\treject(new Error(`${command} output exceeded the daemon buffered-output limit`));\n\t\t\t\treturn;\n\t\t\t}\n\t\t\ttarget.push(Buffer.from(chunk));\n\t\t};\n\t\tchild.stdout.on(\"data\", (chunk: Buffer) => append(stdout, chunk));\n\t\tchild.stderr.on(\"data\", (chunk: Buffer) => append(stderr, chunk));\n\t\tchild.once(\"error\", (error) => {\n\t\t\tif (settled) return;\n\t\t\tsettled = true;\n\t\t\treject(error);\n\t\t});\n\t\tchild.once(\"close\", (code) => {\n\t\t\tif (settled) return;\n\t\t\tsettled = true;\n\t\t\tif (code === 0 || (command === \"rg\" && code === 1)) {\n\t\t\t\tresolvePromise(Buffer.concat(stdout));\n\t\t\t\treturn;\n\t\t\t}\n\t\t\treject(new Error(Buffer.concat(stderr).toString(\"utf8\").trim() || `${command} exited with code ${code}`));\n\t\t});\n\t});\n}\n\nfunction isUnknownRecord(value: unknown): value is Record<string, unknown> {\n\treturn typeof value === \"object\" && value !== null;\n}\n\nfunction nestedText(record: Record<string, unknown> | undefined, key: string): string | undefined {\n\tconst nested = record?.[key];\n\treturn isUnknownRecord(nested) && typeof nested.text === \"string\" ? nested.text : undefined;\n}\n\nfunction parseDaemonGrepMatch(line: string): ToolGrepMatch | undefined {\n\tif (!line) return undefined;\n\tlet event: unknown;\n\ttry {\n\t\tevent = JSON.parse(line) as unknown;\n\t} catch {\n\t\treturn undefined;\n\t}\n\tconst eventRecord = isUnknownRecord(event) ? event : undefined;\n\tif (eventRecord?.type !== \"match\") return undefined;\n\tconst data = isUnknownRecord(eventRecord.data) ? eventRecord.data : undefined;\n\tconst filePath = nestedText(data, \"path\");\n\tconst lineNumber = data?.line_number;\n\tif (!filePath || typeof lineNumber !== \"number\") return undefined;\n\tconst lineText = nestedText(data, \"lines\");\n\treturn { filePath, lineNumber, ...(lineText === undefined ? {} : { lineText }) };\n}\n\nexport class ConfinedDaemonToolOperations implements ToolOperations {\n\treadonly cwd: string;\n\tprivate readonly local: LocalToolOperations;\n\tprivate readonly allowedRoots: readonly string[];\n\tprivate readonly allowProcessExec: boolean;\n\tprivate readonly environment: NodeJS.ProcessEnv;\n\tprivate readonly maxBufferedOutputBytes: number;\n\n\tconstructor(configuration: DaemonConfiguration) {\n\t\tthis.cwd = configuration.workspaceRoot;\n\t\tthis.local = new LocalToolOperations(this.cwd);\n\t\tthis.allowedRoots = Object.freeze([\n\t\t\tthis.cwd,\n\t\t\t...(configuration.temporaryRoot ? [configuration.temporaryRoot] : []),\n\t\t]);\n\t\tthis.allowProcessExec = configuration.allowProcessExec;\n\t\tthis.maxBufferedOutputBytes = configuration.maxBufferedOutputBytes;\n\t\tconst localeNames = Object.keys(process.env).filter((name) => /^LC_/iu.test(name));\n\t\tconst names = new Set([...BASELINE_ENVIRONMENT, ...localeNames, ...configuration.forwardedEnvironment]);\n\t\tthis.environment = {};\n\t\tfor (const name of names) {\n\t\t\tif (isSecretEnvironmentName(name)) continue;\n\t\t\tconst value = process.env[name];\n\t\t\tif (value !== undefined) this.environment[name] = value;\n\t\t}\n\t}\n\n\tcreateChildEnvironment(extra: Record<string, string> = {}): Record<string, string> {\n\t\tconst environment: Record<string, string> = {};\n\t\tfor (const [name, value] of Object.entries(this.environment)) {\n\t\t\tif (value !== undefined) environment[name] = value;\n\t\t}\n\t\tObject.assign(environment, extra);\n\t\tfor (const name of Object.keys(environment)) {\n\t\t\tif (isSecretEnvironmentName(name)) delete environment[name];\n\t\t}\n\t\treturn environment;\n\t}\n\tprivate isWithinAllowedRoot(candidate: string, root: string): boolean {\n\t\tconst pathRelative = relative(root, candidate);\n\t\treturn pathRelative !== \"..\" && !pathRelative.startsWith(`..${sep}`) && !isAbsolute(pathRelative);\n\t}\n\n\tprivate lexicalPath(path: string): string {\n\t\tconst candidate = resolve(this.cwd, path);\n\t\tif (!this.allowedRoots.some((root) => this.isWithinAllowedRoot(candidate, root))) {\n\t\t\tthrow new Error(`Path escapes the daemon workspace and allowed temporary root: ${path}`);\n\t\t}\n\t\treturn candidate;\n\t}\n\n\tprivate async existingPath(path: string): Promise<string> {\n\t\tconst candidate = this.lexicalPath(path);\n\t\tconst canonical = await realpath(candidate);\n\t\treturn this.lexicalPath(canonical);\n\t}\n\n\tprivate async existingWritablePath(candidate: string, path: string): Promise<string | undefined> {\n\t\ttry {\n\t\t\tconst stat = await lstat(candidate);\n\t\t\tif (stat.isSymbolicLink()) {\n\t\t\t\ttry {\n\t\t\t\t\tthis.lexicalPath(await realpath(candidate));\n\t\t\t\t} catch (error) {\n\t\t\t\t\tif (isMissingPath(error)) throw new Error(`Writable path uses a broken symbolic link: ${path}`);\n\t\t\t\t\tthrow error;\n\t\t\t\t}\n\t\t\t\tthrow new Error(`Writable path uses a symbolic link: ${path}`);\n\t\t\t}\n\t\t\tconst canonical = await realpath(candidate);\n\t\t\tthis.lexicalPath(canonical);\n\t\t\treturn this.lexicalPath(canonical);\n\t\t} catch (error) {\n\t\t\tif (isMissingPath(error)) return undefined;\n\t\t\tthrow error;\n\t\t}\n\t}\n\n\tprivate async ensureConfinedWritableParent(candidate: string, path: string): Promise<void> {\n\t\tlet parent = resolve(candidate, \"..\");\n\t\twhile (true) {\n\t\t\ttry {\n\t\t\t\tconst parentStat = await lstat(parent);\n\t\t\t\tif (parentStat.isSymbolicLink()) {\n\t\t\t\t\tthis.lexicalPath(await realpath(parent));\n\t\t\t\t\tthrow new Error(`Writable parent uses a symbolic link: ${path}`);\n\t\t\t\t}\n\t\t\t\tconst canonicalParent = await realpath(parent);\n\t\t\t\tthis.lexicalPath(canonicalParent);\n\t\t\t\treturn;\n\t\t\t} catch (error) {\n\t\t\t\tif (!isMissingPath(error)) throw error;\n\t\t\t\tconst next = resolve(parent, \"..\");\n\t\t\t\tif (next === parent) throw new Error(`No confined parent exists for path: ${path}`);\n\t\t\t\tparent = next;\n\t\t\t}\n\t\t}\n\t}\n\n\tprivate async writablePath(path: string): Promise<string> {\n\t\tconst candidate = this.lexicalPath(path);\n\t\tconst existing = await this.existingWritablePath(candidate, path);\n\t\tif (existing) return existing;\n\t\tawait this.ensureConfinedWritableParent(candidate, path);\n\t\treturn candidate;\n\t}\n\n\tprivate async atomicWriteFile(path: string, content: string | Buffer): Promise<void> {\n\t\tconst target = await this.writablePath(path);\n\t\tconst parent = resolve(target, \"..\");\n\t\tconst temporary = resolve(parent, `.grip-remote-write-${process.pid}-${randomUUID()}-${basename(target)}.tmp`);\n\t\tthis.lexicalPath(temporary);\n\t\tlet wroteTemporary = false;\n\t\ttry {\n\t\t\tconst handle = await open(temporary, \"wx\", 0o600);\n\t\t\ttry {\n\t\t\t\tawait handle.writeFile(content, typeof content === \"string\" ? \"utf8\" : undefined);\n\t\t\t} finally {\n\t\t\t\tawait handle.close();\n\t\t\t}\n\t\t\twroteTemporary = true;\n\t\t\tthis.lexicalPath(await realpath(temporary));\n\t\t\ttry {\n\t\t\t\tif ((await lstat(target)).isSymbolicLink()) throw new Error(`Writable path uses a symbolic link: ${path}`);\n\t\t\t} catch (error) {\n\t\t\t\tif (!isMissingPath(error)) throw error;\n\t\t\t}\n\t\t\tawait rename(temporary, target);\n\t\t\twroteTemporary = false;\n\t\t\tthis.lexicalPath(await realpath(target));\n\t\t} finally {\n\t\t\tif (wroteTemporary) await rm(temporary, { force: true });\n\t\t}\n\t}\n\n\tasync exec(command: string, options: ToolExecOptions): Promise<ToolExecResult> {\n\t\tif (!this.allowProcessExec) throw new Error(\"Process execution is disabled by daemon policy\");\n\t\tconst cwd = await this.existingPath(options.cwd ?? this.cwd);\n\t\tconst environment = { ...this.environment };\n\t\tfor (const name of GRIP_SESSION_ENVIRONMENT_NAMES) {\n\t\t\tconst value = options.env?.[name];\n\t\t\tif (value !== undefined) environment[name] = value;\n\t\t}\n\t\treturn this.local.exec(command, { ...options, cwd, env: environment });\n\t}\n\n\tasync access(path: string, mode?: ToolAccessMode): Promise<void> {\n\t\tawait this.local.access(await this.existingPath(path), mode);\n\t}\n\n\tasync readFile(path: string): Promise<Buffer> {\n\t\treturn this.local.readFile(await this.existingPath(path));\n\t}\n\n\tasync writeFile(path: string, content: string | Buffer): Promise<void> {\n\t\tawait this.atomicWriteFile(path, content);\n\t}\n\n\tasync mkdir(path: string, options?: ToolMkdirOptions): Promise<void> {\n\t\tawait fsMkdir(await this.writablePath(path), options);\n\t}\n\n\tasync stat(path: string): Promise<ToolFileStat> {\n\t\treturn this.local.stat(await this.existingPath(path));\n\t}\n\n\tasync readdir(path: string): Promise<string[]> {\n\t\treturn this.local.readdir(await this.existingPath(path));\n\t}\n\n\tasync glob(pattern: string, cwd: string, options: ToolGlobOptions): Promise<string[]> {\n\t\tconst searchRoot = await this.existingPath(cwd);\n\t\tconst args = [\"--glob\", \"--color=never\", \"--hidden\", \"--no-require-git\", \"--max-results\", String(options.limit)];\n\t\tfor (const ignored of options.ignore) args.push(\"--exclude\", ignored);\n\t\tlet effectivePattern = pattern;\n\t\tif (pattern.includes(\"/\")) {\n\t\t\targs.push(\"--full-path\");\n\t\t\tif (!pattern.startsWith(\"/\") && !pattern.startsWith(\"**/\") && pattern !== \"**\")\n\t\t\t\teffectivePattern = `**/${pattern}`;\n\t\t}\n\t\targs.push(\"--\", effectivePattern, searchRoot);\n\t\tconst output = await runCommand(\"fd\", args, this.environment, this.maxBufferedOutputBytes);\n\t\tconst results: string[] = [];\n\t\tfor (const entry of output.toString(\"utf8\").split(\"\\n\")) {\n\t\t\tif (!entry) continue;\n\t\t\ttry {\n\t\t\t\tresults.push(await this.existingPath(entry));\n\t\t\t} catch {\n\t\t\t\t// Symlinks escaping the workspace are deliberately omitted.\n\t\t\t}\n\t\t}\n\t\treturn results;\n\t}\n\n\tasync grep(options: ToolGrepOptions): Promise<ToolGrepResult> {\n\t\tconst searchPath = await this.existingPath(options.path);\n\t\tconst isDirectory = (await this.local.stat(searchPath)).isDirectory();\n\t\tconst args = [\"--json\", \"--line-number\", \"--color=never\", \"--hidden\"];\n\t\tif (options.ignoreCase) args.push(\"--ignore-case\");\n\t\tif (options.literal) args.push(\"--fixed-strings\");\n\t\tif (options.glob) args.push(\"--glob\", options.glob);\n\t\targs.push(\"--\", options.pattern, searchPath);\n\t\tconst output = await runCommand(\"rg\", args, this.environment, this.maxBufferedOutputBytes);\n\t\tconst matches: ToolGrepMatch[] = [];\n\t\tfor (const line of output.toString(\"utf8\").split(\"\\n\")) {\n\t\t\tif (matches.length >= options.limit) continue;\n\t\t\tconst match = parseDaemonGrepMatch(line);\n\t\t\tif (!match) continue;\n\t\t\ttry {\n\t\t\t\tawait this.existingPath(match.filePath);\n\t\t\t} catch {\n\t\t\t\tcontinue;\n\t\t\t}\n\t\t\tmatches.push(match);\n\t\t}\n\t\treturn { isDirectory, matches };\n\t}\n\n\tasync detectImageMimeType(path: string): Promise<string | null | undefined> {\n\t\treturn this.local.detectImageMimeType(await this.existingPath(path));\n\t}\n\n\tgetBackendInfo(): ToolBackendInfo {\n\t\treturn { type: \"local\", cwd: this.cwd };\n\t}\n}\n\nexport interface DaemonWorkspaceRuntime {\n\treadonly operations: ConfinedDaemonToolOperations;\n\treadonly host: WorkspaceToolHost;\n\treadonly lspRuntime?: LspRuntimeState;\n\treadonly catalog: RemoteWorkspaceCatalog;\n\treadonly capabilities: readonly RemoteWorkspaceCapability[];\n\tcreateHandler(workspace: RemoteWorkspaceIdentity): RemoteWorkspaceServerHandler;\n\tretire(): Promise<void>;\n\tdispose(): Promise<void>;\n}\n\ntype DaemonRequestInterruptionCode = \"cancelled\" | \"deadline_exceeded\";\ntype DaemonInterruptedExecutionState = \"not_started\" | \"indeterminate\";\n\nfunction requestError(code: DaemonRequestInterruptionCode, message: string, state: DaemonInterruptedExecutionState) {\n\treturn new RemoteWorkspaceRequestError({ code, message, executionState: state, retryable: false });\n}\ninterface DaemonRequestRuntime {\n\tconfiguration: DaemonConfiguration;\n\toperations: ConfinedDaemonToolOperations;\n\thost: WorkspaceToolHost;\n\tlspRuntime: LspRuntimeState | undefined;\n\tworkspace: RemoteWorkspaceIdentity;\n}\n\nfunction withDaemonWorkspace<T extends Record<string, unknown>>(result: T, workspace: RemoteWorkspaceIdentity) {\n\treturn { ...result, workspace };\n}\n\nasync function synchronizeDaemonToolFile(\n\ttoolName: string,\n\tinvocationArguments: unknown,\n\truntime: DaemonRequestRuntime,\n): Promise<void> {\n\tif (!runtime.lspRuntime) return;\n\tconst args = invocationArguments as { path?: unknown };\n\tif (typeof args.path !== \"string\") return;\n\ttry {\n\t\tif (toolName === \"read\") {\n\t\t\tawait runtime.lspRuntime.fileSync.handleFileRead(args.path, runtime.operations);\n\t\t} else if (toolName === \"write\" || toolName === \"edit\") {\n\t\t\tawait runtime.lspRuntime.fileSync.handleFileWrite(args.path, runtime.operations);\n\t\t}\n\t} catch {\n\t\t// Synchronization remains best-effort, matching local AgentSession behavior.\n\t}\n}\n\nasync function invokeDaemonTool(\n\trequest: RemoteWorkspaceTypedRequest,\n\tparams: Record<string, unknown>,\n\tcontext: RemoteWorkspaceServerRequestContext,\n\truntime: DaemonRequestRuntime,\n): Promise<AgentToolResult<unknown>> {\n\tconst toolName = params.toolName as string;\n\tconst kind = operationKind(toolName);\n\tif (kind !== \"read\") context.markSideEffectStarted();\n\tlet updateQueue = Promise.resolve();\n\ttry {\n\t\tconst result = await runtime.host.executePrepared(toolName, {\n\t\t\ttoolCallId: request.id,\n\t\t\targuments: params.arguments,\n\t\t\tsignal: context.signal,\n\t\t\texecutionOptions: params.executionOptions as WorkspaceToolExecutionOptions,\n\t\t\tonUpdate: (update) => {\n\t\t\t\tupdateQueue = updateQueue.then(() => context.sendUpdate(portableToolResult(update)));\n\t\t\t},\n\t\t});\n\t\tawait updateQueue;\n\t\tawait synchronizeDaemonToolFile(toolName, params.arguments, runtime);\n\t\tif (kind !== \"read\") context.markCommitted();\n\t\treturn portableToolResult(result);\n\t} catch (error) {\n\t\tawait updateQueue.catch(() => undefined);\n\t\tif (context.signal.aborted) {\n\t\t\tthrow requestError(\n\t\t\t\t\"cancelled\",\n\t\t\t\t\"Remote workspace tool invocation was cancelled\",\n\t\t\t\tkind === \"read\" ? \"not_started\" : \"indeterminate\",\n\t\t\t);\n\t\t}\n\t\tthrow new RemoteWorkspaceRequestError({\n\t\t\tcode: \"internal_error\",\n\t\t\tmessage: error instanceof Error ? error.message.slice(0, 4096) : \"Workspace tool failed\",\n\t\t\texecutionState: kind === \"read\" ? \"not_started\" : \"indeterminate\",\n\t\t\tretryable: false,\n\t\t});\n\t}\n}\n\nasync function executeDaemonWorkspaceProcess(\n\tparams: Record<string, unknown>,\n\tcontext: RemoteWorkspaceServerRequestContext,\n\truntime: DaemonRequestRuntime,\n): Promise<ToolExecResult> {\n\tcontext.markSideEffectStarted();\n\tlet updateQueue = Promise.resolve();\n\tlet pendingOutputBytes = 0;\n\tlet outputLimitExceeded = false;\n\tconst outputController = new AbortController();\n\tconst signal = AbortSignal.any([context.signal, outputController.signal]);\n\tlet result: ToolExecResult;\n\ttry {\n\t\tresult = await runtime.operations.exec(params.command as string, {\n\t\t\tcwd: params.cwd as string,\n\t\t\tsignal,\n\t\t\tonData: (data) => {\n\t\t\t\tif (outputLimitExceeded) return;\n\t\t\t\tconst chunk = Buffer.from(data);\n\t\t\t\tpendingOutputBytes += chunk.byteLength;\n\t\t\t\tif (pendingOutputBytes > runtime.configuration.maxBufferedOutputBytes) {\n\t\t\t\t\toutputLimitExceeded = true;\n\t\t\t\t\toutputController.abort();\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t\tupdateQueue = updateQueue\n\t\t\t\t\t.then(() => context.sendUpdate({ dataBase64: chunk.toString(\"base64\") }))\n\t\t\t\t\t.finally(() => {\n\t\t\t\t\t\tpendingOutputBytes -= chunk.byteLength;\n\t\t\t\t\t});\n\t\t\t},\n\t\t});\n\t} catch (error) {\n\t\tif (outputLimitExceeded) throw new Error(\"Process output exceeded the daemon buffered-output limit\");\n\t\tthrow error;\n\t}\n\tawait updateQueue;\n\tcontext.markCommitted();\n\treturn result;\n}\n\nasync function readDaemonResource(\n\tparams: Record<string, unknown>,\n\truntime: DaemonRequestRuntime,\n): Promise<Record<string, unknown>> {\n\tconst path = params.path as string;\n\tconst resourcePath =\n\t\tpath === \"SANDBOX.md\"\n\t\t\t? runtime.configuration.sandboxInstructionsPath\n\t\t\t: path === \"AGENTS.md\"\n\t\t\t\t? runtime.configuration.userAgentsPath\n\t\t\t\t: undefined;\n\tif (!resourcePath) {\n\t\tthrow new RemoteWorkspaceRequestError({\n\t\t\tcode: \"not_available\",\n\t\t\tmessage: \"Requested daemon resource is not available\",\n\t\t\texecutionState: \"not_started\",\n\t\t\tretryable: false,\n\t\t});\n\t}\n\treturn withDaemonWorkspace({ contentBase64: (await readFile(resourcePath)).toString(\"base64\") }, runtime.workspace);\n}\n\nfunction getDaemonLspStatus(runtime: DaemonRequestRuntime): Record<string, unknown> {\n\tif (!runtime.lspRuntime) {\n\t\tthrow new RemoteWorkspaceRequestError({\n\t\t\tcode: \"not_available\",\n\t\t\tmessage: \"Daemon LSP is not configured\",\n\t\t\texecutionState: \"not_started\",\n\t\t\tretryable: false,\n\t\t});\n\t}\n\treturn {\n\t\tenabled: true,\n\t\tservers: runtime.lspRuntime.manager.getStatus().map((status) => sanitizeLspStatus(status, runtime.configuration)),\n\t};\n}\n\nasync function dispatchDaemonWorkspaceRequest(\n\trequest: RemoteWorkspaceTypedRequest,\n\tcontext: RemoteWorkspaceServerRequestContext,\n\truntime: DaemonRequestRuntime,\n): Promise<unknown> {\n\tconst params = request.params as Record<string, unknown>;\n\tswitch (request.method) {\n\t\tcase \"tool.invoke\":\n\t\t\treturn invokeDaemonTool(request, params, context, runtime);\n\t\tcase \"workspace.access\":\n\t\t\tawait runtime.operations.access(params.path as string, params.mode as ToolAccessMode | undefined);\n\t\t\treturn {};\n\t\tcase \"workspace.read\":\n\t\t\treturn withDaemonWorkspace(\n\t\t\t\t{ contentBase64: (await runtime.operations.readFile(params.path as string)).toString(\"base64\") },\n\t\t\t\truntime.workspace,\n\t\t\t);\n\t\tcase \"workspace.write\":\n\t\t\tcontext.markSideEffectStarted();\n\t\t\tawait withFileMutationQueue(resolve(runtime.configuration.workspaceRoot, params.path as string), () =>\n\t\t\t\truntime.operations.writeFile(params.path as string, Buffer.from(params.contentBase64 as string, \"base64\")),\n\t\t\t);\n\t\t\tcontext.markCommitted();\n\t\t\treturn {};\n\t\tcase \"workspace.mkdir\":\n\t\t\tcontext.markSideEffectStarted();\n\t\t\tawait withFileMutationQueue(resolve(runtime.configuration.workspaceRoot, params.path as string), () =>\n\t\t\t\truntime.operations.mkdir(params.path as string, { recursive: params.recursive === true }),\n\t\t\t);\n\t\t\tcontext.markCommitted();\n\t\t\treturn {};\n\t\tcase \"workspace.stat\": {\n\t\t\tconst value = await runtime.operations.stat(params.path as string);\n\t\t\treturn withDaemonWorkspace(\n\t\t\t\t{ kind: value.isDirectory() ? \"directory\" : value.isFile() ? \"file\" : \"other\" },\n\t\t\t\truntime.workspace,\n\t\t\t);\n\t\t}\n\t\tcase \"workspace.readdir\":\n\t\t\treturn withDaemonWorkspace(\n\t\t\t\t{ entries: await runtime.operations.readdir(params.path as string) },\n\t\t\t\truntime.workspace,\n\t\t\t);\n\t\tcase \"workspace.glob\":\n\t\t\treturn withDaemonWorkspace(\n\t\t\t\t{\n\t\t\t\t\tmatches: await runtime.operations.glob(params.pattern as string, params.cwd as string, {\n\t\t\t\t\t\tignore: params.ignore as string[],\n\t\t\t\t\t\tlimit: params.limit as number,\n\t\t\t\t\t}),\n\t\t\t\t},\n\t\t\t\truntime.workspace,\n\t\t\t);\n\t\tcase \"workspace.grep\": {\n\t\t\tconst result = await runtime.operations.grep(params as unknown as ToolGrepOptions);\n\t\t\treturn withDaemonWorkspace(result as unknown as Record<string, unknown>, runtime.workspace);\n\t\t}\n\t\tcase \"workspace.detect_image_mime\":\n\t\t\treturn withDaemonWorkspace(\n\t\t\t\t{ mimeType: (await runtime.operations.detectImageMimeType(params.path as string)) ?? null },\n\t\t\t\truntime.workspace,\n\t\t\t);\n\t\tcase \"workspace.exec\":\n\t\t\treturn executeDaemonWorkspaceProcess(params, context, runtime);\n\t\tcase \"resource.read\":\n\t\t\treturn readDaemonResource(params, runtime);\n\t\tcase \"lsp.status\":\n\t\t\treturn getDaemonLspStatus(runtime);\n\t\tdefault:\n\t\t\tthrow new RemoteWorkspaceRequestError({\n\t\t\t\tcode: \"method_not_supported\",\n\t\t\t\tmessage: `Workspace operation is not implemented: ${request.method}`,\n\t\t\t\texecutionState: \"not_started\",\n\t\t\t\tretryable: false,\n\t\t\t});\n\t}\n}\n\nexport function createDaemonWorkspaceRuntime(configuration: DaemonConfiguration): DaemonWorkspaceRuntime {\n\tconst operations = new ConfinedDaemonToolOperations(configuration);\n\tconst toolNames: WorkspaceToolName[] = [\"read\", \"edit\", \"write\", \"grep\", \"find\", \"ls\"];\n\tif (configuration.allowProcessExec) toolNames.splice(1, 0, \"bash\");\n\tconst lspConfiguration = loadDaemonLspConfiguration(configuration);\n\tconst lspRuntime = lspConfiguration.enabled\n\t\t? createLspRuntimeState(configuration.workspaceRoot, {\n\t\t\t\tconfiguration: lspConfiguration,\n\t\t\t\tgetToolBackendInfo: () => operations.getBackendInfo(),\n\t\t\t\tgetToolOperations: () => operations,\n\t\t\t\tresolveConnectionFactory: (transport) =>\n\t\t\t\t\ttransport.type === \"spawn\"\n\t\t\t\t\t\t? createManagedStdioConnectionFactory({\n\t\t\t\t\t\t\t\t...transport,\n\t\t\t\t\t\t\t\tenv: operations.createChildEnvironment(transport.env),\n\t\t\t\t\t\t\t\tinheritEnvironment: false,\n\t\t\t\t\t\t\t})\n\t\t\t\t\t\t: resolveLspConnectionFactory(transport),\n\t\t\t})\n\t\t: undefined;\n\tconst host = new WorkspaceToolHost({\n\t\tcwd: configuration.workspaceRoot,\n\t\toperations,\n\t\ttoolNames,\n\t\tadditionalDefinitions: lspRuntime\n\t\t\t? createLspToolDefinitions(\n\t\t\t\t\t() => lspRuntime,\n\t\t\t\t\t() => operations,\n\t\t\t\t)\n\t\t\t: undefined,\n\t\tdisposeTimeoutMs: Math.min(configuration.shutdownTimeoutMs, 60_000),\n\t});\n\tconst catalog: RemoteWorkspaceCatalog = {\n\t\tgeneration: 1,\n\t\ttools: host.getCatalog().map((entry) => ({\n\t\t\tname: entry.name,\n\t\t\texecutionMode: operationKind(entry.name),\n\t\t\tparameterSchema: structuredClone(entry.parameters) as Record<string, unknown>,\n\t\t\tschemaHash: hashRemoteWorkspaceJson(entry.parameters),\n\t\t\tfeatureFlags: [],\n\t\t})),\n\t\toperations: [\n\t\t\t...PRIMITIVE_OPERATIONS.filter((method) => method !== \"workspace.exec\" || configuration.allowProcessExec),\n\t\t\t...(configuration.sandboxInstructionsPath || configuration.userAgentsPath ? ([\"resource.read\"] as const) : []),\n\t\t\t...(lspRuntime ? ([\"lsp.status\"] as const) : []),\n\t\t],\n\t};\n\tconst capabilities: RemoteWorkspaceCapability[] = [\n\t\t\"catalog_refresh\",\n\t\t\"primitive_operations\",\n\t\t\"tool_updates\",\n\t\t...(lspRuntime ? ([\"lsp_status\"] as const) : []),\n\t];\n\tlet activeRequests = 0;\n\n\treturn {\n\t\toperations,\n\t\thost,\n\t\tlspRuntime,\n\t\tcatalog,\n\t\tcapabilities,\n\t\tcreateHandler(workspace) {\n\t\t\tconst requestRuntime: DaemonRequestRuntime = { configuration, operations, host, lspRuntime, workspace };\n\t\t\treturn {\n\t\t\t\tvalidateToolArguments: (toolName, value) => host.validatePreparedArguments(toolName, value),\n\t\t\t\tasync handleRequest(request, context) {\n\t\t\t\t\tif (activeRequests >= configuration.maxGlobalRequests) {\n\t\t\t\t\t\tthrow new RemoteWorkspaceRequestError({\n\t\t\t\t\t\t\tcode: \"limit_exceeded\",\n\t\t\t\t\t\t\tmessage: \"Daemon global active request limit reached\",\n\t\t\t\t\t\t\texecutionState: \"not_started\",\n\t\t\t\t\t\t\tretryable: true,\n\t\t\t\t\t\t});\n\t\t\t\t\t}\n\t\t\t\t\tactiveRequests++;\n\t\t\t\t\ttry {\n\t\t\t\t\t\treturn await dispatchDaemonWorkspaceRequest(request, context, requestRuntime);\n\t\t\t\t\t} finally {\n\t\t\t\t\t\tactiveRequests--;\n\t\t\t\t\t}\n\t\t\t\t},\n\t\t\t};\n\t\t},\n\t\tretire: async () => {\n\t\t\tawait host.waitForIdle(configuration.shutdownTimeoutMs);\n\t\t\tawait lspRuntime?.manager.shutdownAll();\n\t\t\tawait host.dispose();\n\t\t},\n\t\tdispose: async () => {\n\t\t\tawait Promise.all([lspRuntime?.manager.shutdownAll(), host.dispose()]);\n\t\t},\n\t};\n}\n"]}
|
|
1
|
+
{"version":3,"file":"workspace-runtime.js","sourceRoot":"","sources":["../../src/daemon/workspace-runtime.ts"],"names":[],"mappings":"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","sourcesContent":["import { spawn } from \"node:child_process\";\nimport { randomUUID } from \"node:crypto\";\nimport { mkdir as fsMkdir, lstat, open, readFile, realpath, rename, rm } from \"node:fs/promises\";\nimport { basename, isAbsolute, relative, resolve, sep } from \"node:path\";\nimport type { AgentToolResult } from \"@greppleai/grip-agent-core\";\nimport { createLspRuntimeState, createLspToolDefinitions, type LspRuntimeState } from \"../core/lsp/integration.ts\";\nimport type { LspServerStatus } from \"../core/lsp/manager.ts\";\nimport { createManagedStdioConnectionFactory, resolveLspConnectionFactory } from \"../core/lsp/transport.ts\";\nimport {\n\thashRemoteWorkspaceJson,\n\ttype RemoteWorkspaceCapability,\n\ttype RemoteWorkspaceCatalog,\n\ttype RemoteWorkspaceIdentity,\n\ttype RemoteWorkspaceMethod,\n\ttype RemoteWorkspaceOperationKind,\n} from \"../core/remote-workspace-protocol/contract.ts\";\nimport {\n\tRemoteWorkspaceRequestError,\n\ttype RemoteWorkspaceServerHandler,\n\ttype RemoteWorkspaceServerRequestContext,\n\ttype RemoteWorkspaceTypedRequest,\n} from \"../core/remote-workspace-protocol/session.ts\";\nimport { withFileMutationQueue } from \"../core/tools/file-mutation-queue.ts\";\nimport {\n\tGRIP_SESSION_ENVIRONMENT_NAMES,\n\tLocalToolOperations,\n\ttype ToolAccessMode,\n\ttype ToolBackendInfo,\n\ttype ToolExecOptions,\n\ttype ToolExecResult,\n\ttype ToolFileStat,\n\ttype ToolGlobOptions,\n\ttype ToolGrepMatch,\n\ttype ToolGrepOptions,\n\ttype ToolGrepResult,\n\ttype ToolMkdirOptions,\n\ttype ToolOperations,\n\ttype WorkspaceToolExecutionOptions,\n} from \"../core/tools/operations.ts\";\nimport { WorkspaceToolHost, type WorkspaceToolName } from \"../core/tools/workspace-tool-host.ts\";\nimport type { DaemonConfiguration } from \"./config.ts\";\nimport { loadDaemonLspConfiguration } from \"./lsp-config.ts\";\nimport { redactDaemonText } from \"./security.ts\";\n\nconst PRIMITIVE_OPERATIONS: RemoteWorkspaceMethod[] = [\n\t\"workspace.access\",\n\t\"workspace.read\",\n\t\"workspace.write\",\n\t\"workspace.mkdir\",\n\t\"workspace.stat\",\n\t\"workspace.readdir\",\n\t\"workspace.glob\",\n\t\"workspace.grep\",\n\t\"workspace.detect_image_mime\",\n\t\"workspace.exec\",\n];\n\nconst SECRET_ENVIRONMENT_SUFFIX = /_(?:API_KEY|TOKEN|SECRET|PASSWORD|PRIVATE_KEY|CREDENTIALS)$/iu;\nconst BASELINE_ENVIRONMENT =\n\tprocess.platform === \"win32\"\n\t\t? [\"PATH\", \"PATHEXT\", \"SYSTEMROOT\", \"COMSPEC\", \"TEMP\", \"TMP\", \"USER\", \"USERNAME\"]\n\t\t: [\"PATH\", \"HOME\", \"USER\", \"LOGNAME\", \"SHELL\", \"LANG\", \"TERM\", \"COLORTERM\", \"NO_COLOR\", \"TMPDIR\"];\n\nfunction isSecretEnvironmentName(name: string): boolean {\n\tconst upper = name.toUpperCase();\n\treturn (\n\t\tupper === \"GRIP_DAEMON_TOKEN\" ||\n\t\tupper === \"PI_DAEMON_TOKEN\" ||\n\t\tupper === \"GRIP_REMOTE_TOKEN\" ||\n\t\tupper.startsWith(\"GRIP_DAEMON_TLS_\") ||\n\t\tupper.startsWith(\"PI_DAEMON_TLS_\") ||\n\t\tSECRET_ENVIRONMENT_SUFFIX.test(upper)\n\t);\n}\nprocess.platform === \"win32\"\n\t? [\"PATH\", \"PATHEXT\", \"SYSTEMROOT\", \"TEMP\", \"TMP\"]\n\t: [\"PATH\", \"HOME\", \"LANG\", \"LC_ALL\", \"TERM\", \"TMPDIR\"];\n\nfunction isMissingPath(error: unknown): boolean {\n\treturn error instanceof Error && \"code\" in error && error.code === \"ENOENT\";\n}\n\nfunction sanitizeLspStatus(\n\tstatus: LspServerStatus,\n\tconfiguration: DaemonConfiguration,\n): Omit<LspServerStatus, \"capabilities\"> {\n\tconst { capabilities: _capabilities, ...safe } = status;\n\tconst secrets = [configuration.token, configuration.tls?.passphrase];\n\tconst redact = (value: string | undefined) => (value ? redactDaemonText(value, secrets) : undefined);\n\treturn {\n\t\t...safe,\n\t\tserverId: redact(safe.serverId)!,\n\t\tlanguageIds: safe.languageIds.map((value) => redact(value)!),\n\t\ttransport: redact(safe.transport)!,\n\t\t...(safe.instanceKey ? { instanceKey: redact(safe.instanceKey) } : {}),\n\t\t...(safe.workspaceRoot ? { workspaceRoot: redact(safe.workspaceRoot) } : {}),\n\t\t...(safe.rootUri ? { rootUri: redact(safe.rootUri) } : {}),\n\t\t...(safe.endpoint ? { endpoint: redact(safe.endpoint) } : {}),\n\t\t...(safe.lastError ? { lastError: redact(safe.lastError) } : {}),\n\t\t...(safe.lastRequestError ? { lastRequestError: redact(safe.lastRequestError) } : {}),\n\t\t...(safe.stderr ? { stderr: redact(safe.stderr) } : {}),\n\t\t...(safe.synchronizationError ? { synchronizationError: redact(safe.synchronizationError) } : {}),\n\t};\n}\n\nfunction portableToolResult(result: AgentToolResult<unknown>): AgentToolResult<unknown> {\n\tconst clone = JSON.parse(JSON.stringify(result)) as AgentToolResult<unknown>;\n\tconst details = clone.details;\n\tif (!details || typeof details !== \"object\" || !(\"fullOutputPath\" in details)) return clone;\n\tconst fullOutputPath = (details as { fullOutputPath?: unknown }).fullOutputPath;\n\tif (typeof fullOutputPath !== \"string\") return clone;\n\tdelete (details as { fullOutputPath?: unknown }).fullOutputPath;\n\tfor (const content of clone.content) {\n\t\tif (content.type === \"text\") {\n\t\t\tcontent.text = content.text.replaceAll(fullOutputPath, \"[remote full output is not transferable]\");\n\t\t}\n\t}\n\treturn clone;\n}\n\nfunction operationKind(name: string): RemoteWorkspaceOperationKind {\n\tif (name.startsWith(\"lsp_\")) return \"service\";\n\tswitch (name) {\n\t\tcase \"read\":\n\t\tcase \"grep\":\n\t\tcase \"find\":\n\t\tcase \"ls\":\n\t\t\treturn \"read\";\n\t\tcase \"edit\":\n\t\tcase \"write\":\n\t\t\treturn \"mutation\";\n\t\tcase \"bash\":\n\t\t\treturn \"process\";\n\t}\n\tthrow new Error(`Unknown daemon tool: ${name}`);\n}\n\nfunction runCommand(\n\tcommand: string,\n\targs: string[],\n\tenvironment: NodeJS.ProcessEnv,\n\tmaxBufferedBytes: number,\n): Promise<Buffer> {\n\treturn new Promise((resolvePromise, reject) => {\n\t\tconst child = spawn(command, args, { stdio: [\"ignore\", \"pipe\", \"pipe\"], windowsHide: true, env: environment });\n\t\tconst stdout: Buffer[] = [];\n\t\tconst stderr: Buffer[] = [];\n\t\tlet bufferedBytes = 0;\n\t\tlet settled = false;\n\t\tconst append = (target: Buffer[], chunk: Buffer) => {\n\t\t\tif (settled) return;\n\t\t\tbufferedBytes += chunk.byteLength;\n\t\t\tif (bufferedBytes > maxBufferedBytes) {\n\t\t\t\tsettled = true;\n\t\t\t\tchild.kill();\n\t\t\t\treject(new Error(`${command} output exceeded the daemon buffered-output limit`));\n\t\t\t\treturn;\n\t\t\t}\n\t\t\ttarget.push(Buffer.from(chunk));\n\t\t};\n\t\tchild.stdout.on(\"data\", (chunk: Buffer) => append(stdout, chunk));\n\t\tchild.stderr.on(\"data\", (chunk: Buffer) => append(stderr, chunk));\n\t\tchild.once(\"error\", (error) => {\n\t\t\tif (settled) return;\n\t\t\tsettled = true;\n\t\t\treject(error);\n\t\t});\n\t\tchild.once(\"close\", (code) => {\n\t\t\tif (settled) return;\n\t\t\tsettled = true;\n\t\t\tif (code === 0 || (command === \"rg\" && code === 1)) {\n\t\t\t\tresolvePromise(Buffer.concat(stdout));\n\t\t\t\treturn;\n\t\t\t}\n\t\t\treject(new Error(Buffer.concat(stderr).toString(\"utf8\").trim() || `${command} exited with code ${code}`));\n\t\t});\n\t});\n}\n\nfunction isUnknownRecord(value: unknown): value is Record<string, unknown> {\n\treturn typeof value === \"object\" && value !== null;\n}\n\nfunction nestedText(record: Record<string, unknown> | undefined, key: string): string | undefined {\n\tconst nested = record?.[key];\n\treturn isUnknownRecord(nested) && typeof nested.text === \"string\" ? nested.text : undefined;\n}\n\nfunction parseDaemonGrepMatch(line: string): ToolGrepMatch | undefined {\n\tif (!line) return undefined;\n\tlet event: unknown;\n\ttry {\n\t\tevent = JSON.parse(line) as unknown;\n\t} catch {\n\t\treturn undefined;\n\t}\n\tconst eventRecord = isUnknownRecord(event) ? event : undefined;\n\tif (eventRecord?.type !== \"match\") return undefined;\n\tconst data = isUnknownRecord(eventRecord.data) ? eventRecord.data : undefined;\n\tconst filePath = nestedText(data, \"path\");\n\tconst lineNumber = data?.line_number;\n\tif (!filePath || typeof lineNumber !== \"number\") return undefined;\n\tconst lineText = nestedText(data, \"lines\");\n\treturn { filePath, lineNumber, ...(lineText === undefined ? {} : { lineText }) };\n}\n\nexport class ConfinedDaemonToolOperations implements ToolOperations {\n\treadonly cwd: string;\n\tprivate readonly local: LocalToolOperations;\n\tprivate readonly allowedRoots: readonly string[];\n\tprivate readonly allowProcessExec: boolean;\n\tprivate readonly environment: NodeJS.ProcessEnv;\n\tprivate readonly maxBufferedOutputBytes: number;\n\n\tconstructor(configuration: DaemonConfiguration) {\n\t\tthis.cwd = configuration.workspaceRoot;\n\t\tthis.local = new LocalToolOperations(this.cwd);\n\t\tthis.allowedRoots = Object.freeze([\n\t\t\tthis.cwd,\n\t\t\t...(configuration.temporaryRoot ? [configuration.temporaryRoot] : []),\n\t\t]);\n\t\tthis.allowProcessExec = configuration.allowProcessExec;\n\t\tthis.maxBufferedOutputBytes = configuration.maxBufferedOutputBytes;\n\t\tconst localeNames = Object.keys(process.env).filter((name) => /^LC_/iu.test(name));\n\t\tconst names = new Set([...BASELINE_ENVIRONMENT, ...localeNames, ...configuration.forwardedEnvironment]);\n\t\tthis.environment = {};\n\t\tfor (const name of names) {\n\t\t\tif (isSecretEnvironmentName(name)) continue;\n\t\t\tconst value = process.env[name];\n\t\t\tif (value !== undefined) this.environment[name] = value;\n\t\t}\n\t}\n\n\tcreateChildEnvironment(extra: Record<string, string> = {}): Record<string, string> {\n\t\tconst environment: Record<string, string> = {};\n\t\tfor (const [name, value] of Object.entries(this.environment)) {\n\t\t\tif (value !== undefined) environment[name] = value;\n\t\t}\n\t\tObject.assign(environment, extra);\n\t\tfor (const name of Object.keys(environment)) {\n\t\t\tif (isSecretEnvironmentName(name)) delete environment[name];\n\t\t}\n\t\treturn environment;\n\t}\n\tprivate isWithinAllowedRoot(candidate: string, root: string): boolean {\n\t\tconst pathRelative = relative(root, candidate);\n\t\treturn pathRelative !== \"..\" && !pathRelative.startsWith(`..${sep}`) && !isAbsolute(pathRelative);\n\t}\n\n\tprivate lexicalPath(path: string): string {\n\t\tconst candidate = resolve(this.cwd, path);\n\t\tif (!this.allowedRoots.some((root) => this.isWithinAllowedRoot(candidate, root))) {\n\t\t\tthrow new Error(`Path escapes the daemon workspace and allowed temporary root: ${path}`);\n\t\t}\n\t\treturn candidate;\n\t}\n\n\tprivate async existingPath(path: string): Promise<string> {\n\t\tconst candidate = this.lexicalPath(path);\n\t\tconst canonical = await realpath(candidate);\n\t\treturn this.lexicalPath(canonical);\n\t}\n\n\tprivate async existingWritablePath(candidate: string, path: string): Promise<string | undefined> {\n\t\ttry {\n\t\t\tconst stat = await lstat(candidate);\n\t\t\tif (stat.isSymbolicLink()) {\n\t\t\t\ttry {\n\t\t\t\t\tthis.lexicalPath(await realpath(candidate));\n\t\t\t\t} catch (error) {\n\t\t\t\t\tif (isMissingPath(error)) throw new Error(`Writable path uses a broken symbolic link: ${path}`);\n\t\t\t\t\tthrow error;\n\t\t\t\t}\n\t\t\t\tthrow new Error(`Writable path uses a symbolic link: ${path}`);\n\t\t\t}\n\t\t\tconst canonical = await realpath(candidate);\n\t\t\tthis.lexicalPath(canonical);\n\t\t\treturn this.lexicalPath(canonical);\n\t\t} catch (error) {\n\t\t\tif (isMissingPath(error)) return undefined;\n\t\t\tthrow error;\n\t\t}\n\t}\n\n\tprivate async ensureConfinedWritableParent(candidate: string, path: string): Promise<void> {\n\t\tlet parent = resolve(candidate, \"..\");\n\t\twhile (true) {\n\t\t\ttry {\n\t\t\t\tconst parentStat = await lstat(parent);\n\t\t\t\tif (parentStat.isSymbolicLink()) {\n\t\t\t\t\tthis.lexicalPath(await realpath(parent));\n\t\t\t\t\tthrow new Error(`Writable parent uses a symbolic link: ${path}`);\n\t\t\t\t}\n\t\t\t\tconst canonicalParent = await realpath(parent);\n\t\t\t\tthis.lexicalPath(canonicalParent);\n\t\t\t\treturn;\n\t\t\t} catch (error) {\n\t\t\t\tif (!isMissingPath(error)) throw error;\n\t\t\t\tconst next = resolve(parent, \"..\");\n\t\t\t\tif (next === parent) throw new Error(`No confined parent exists for path: ${path}`);\n\t\t\t\tparent = next;\n\t\t\t}\n\t\t}\n\t}\n\n\tprivate async writablePath(path: string): Promise<string> {\n\t\tconst candidate = this.lexicalPath(path);\n\t\tconst existing = await this.existingWritablePath(candidate, path);\n\t\tif (existing) return existing;\n\t\tawait this.ensureConfinedWritableParent(candidate, path);\n\t\treturn candidate;\n\t}\n\n\tprivate async atomicWriteFile(path: string, content: string | Buffer): Promise<void> {\n\t\tconst target = await this.writablePath(path);\n\t\tconst parent = resolve(target, \"..\");\n\t\tconst temporary = resolve(parent, `.grip-remote-write-${process.pid}-${randomUUID()}-${basename(target)}.tmp`);\n\t\tthis.lexicalPath(temporary);\n\t\tlet wroteTemporary = false;\n\t\ttry {\n\t\t\tconst handle = await open(temporary, \"wx\", 0o600);\n\t\t\ttry {\n\t\t\t\tawait handle.writeFile(content, typeof content === \"string\" ? \"utf8\" : undefined);\n\t\t\t} finally {\n\t\t\t\tawait handle.close();\n\t\t\t}\n\t\t\twroteTemporary = true;\n\t\t\tthis.lexicalPath(await realpath(temporary));\n\t\t\ttry {\n\t\t\t\tif ((await lstat(target)).isSymbolicLink()) throw new Error(`Writable path uses a symbolic link: ${path}`);\n\t\t\t} catch (error) {\n\t\t\t\tif (!isMissingPath(error)) throw error;\n\t\t\t}\n\t\t\tawait rename(temporary, target);\n\t\t\twroteTemporary = false;\n\t\t\tthis.lexicalPath(await realpath(target));\n\t\t} finally {\n\t\t\tif (wroteTemporary) await rm(temporary, { force: true });\n\t\t}\n\t}\n\n\tasync exec(command: string, options: ToolExecOptions): Promise<ToolExecResult> {\n\t\tif (!this.allowProcessExec) throw new Error(\"Process execution is disabled by daemon policy\");\n\t\tconst cwd = await this.existingPath(options.cwd ?? this.cwd);\n\t\tconst environment = { ...this.environment };\n\t\tfor (const name of GRIP_SESSION_ENVIRONMENT_NAMES) {\n\t\t\tconst value = options.env?.[name];\n\t\t\tif (value !== undefined) environment[name] = value;\n\t\t}\n\t\treturn this.local.exec(command, { ...options, cwd, env: environment });\n\t}\n\n\tasync access(path: string, mode?: ToolAccessMode): Promise<void> {\n\t\tawait this.local.access(await this.existingPath(path), mode);\n\t}\n\n\tasync readFile(path: string): Promise<Buffer> {\n\t\treturn this.local.readFile(await this.existingPath(path));\n\t}\n\n\tasync writeFile(path: string, content: string | Buffer): Promise<void> {\n\t\tawait this.atomicWriteFile(path, content);\n\t}\n\n\tasync mkdir(path: string, options?: ToolMkdirOptions): Promise<void> {\n\t\tawait fsMkdir(await this.writablePath(path), options);\n\t}\n\n\tasync stat(path: string): Promise<ToolFileStat> {\n\t\treturn this.local.stat(await this.existingPath(path));\n\t}\n\n\tasync readdir(path: string): Promise<string[]> {\n\t\treturn this.local.readdir(await this.existingPath(path));\n\t}\n\n\tasync glob(pattern: string, cwd: string, options: ToolGlobOptions): Promise<string[]> {\n\t\tconst searchRoot = await this.existingPath(cwd);\n\t\tconst args = [\"--glob\", \"--color=never\", \"--hidden\", \"--no-require-git\", \"--max-results\", String(options.limit)];\n\t\tfor (const ignored of options.ignore) args.push(\"--exclude\", ignored);\n\t\tlet effectivePattern = pattern;\n\t\tif (pattern.includes(\"/\")) {\n\t\t\targs.push(\"--full-path\");\n\t\t\tif (!pattern.startsWith(\"/\") && !pattern.startsWith(\"**/\") && pattern !== \"**\")\n\t\t\t\teffectivePattern = `**/${pattern}`;\n\t\t}\n\t\targs.push(\"--\", effectivePattern, searchRoot);\n\t\tconst output = await runCommand(\"fd\", args, this.environment, this.maxBufferedOutputBytes);\n\t\tconst results: string[] = [];\n\t\tfor (const entry of output.toString(\"utf8\").split(\"\\n\")) {\n\t\t\tif (!entry) continue;\n\t\t\ttry {\n\t\t\t\tresults.push(await this.existingPath(entry));\n\t\t\t} catch {\n\t\t\t\t// Symlinks escaping the workspace are deliberately omitted.\n\t\t\t}\n\t\t}\n\t\treturn results;\n\t}\n\n\tasync grep(options: ToolGrepOptions): Promise<ToolGrepResult> {\n\t\tconst searchPath = await this.existingPath(options.path);\n\t\tconst isDirectory = (await this.local.stat(searchPath)).isDirectory();\n\t\tconst args = [\"--json\", \"--line-number\", \"--color=never\", \"--hidden\"];\n\t\tif (options.ignoreCase) args.push(\"--ignore-case\");\n\t\tif (options.literal) args.push(\"--fixed-strings\");\n\t\tif (options.glob) args.push(\"--glob\", options.glob);\n\t\targs.push(\"--\", options.pattern, searchPath);\n\t\tconst output = await runCommand(\"rg\", args, this.environment, this.maxBufferedOutputBytes);\n\t\tconst matches: ToolGrepMatch[] = [];\n\t\tfor (const line of output.toString(\"utf8\").split(\"\\n\")) {\n\t\t\tif (matches.length >= options.limit) continue;\n\t\t\tconst match = parseDaemonGrepMatch(line);\n\t\t\tif (!match) continue;\n\t\t\ttry {\n\t\t\t\tawait this.existingPath(match.filePath);\n\t\t\t} catch {\n\t\t\t\tcontinue;\n\t\t\t}\n\t\t\tmatches.push(match);\n\t\t}\n\t\treturn { isDirectory, matches };\n\t}\n\n\tasync detectImageMimeType(path: string): Promise<string | null | undefined> {\n\t\treturn this.local.detectImageMimeType(await this.existingPath(path));\n\t}\n\n\tgetBackendInfo(): ToolBackendInfo {\n\t\treturn { type: \"local\", cwd: this.cwd };\n\t}\n}\n\nexport interface DaemonWorkspaceRuntime {\n\treadonly operations: ConfinedDaemonToolOperations;\n\treadonly host: WorkspaceToolHost;\n\treadonly lspRuntime?: LspRuntimeState;\n\treadonly catalog: RemoteWorkspaceCatalog;\n\treadonly capabilities: readonly RemoteWorkspaceCapability[];\n\tcreateHandler(workspace: RemoteWorkspaceIdentity, sharedMode?: boolean): RemoteWorkspaceServerHandler;\n\tretire(): Promise<void>;\n\tdispose(): Promise<void>;\n}\n\ntype DaemonRequestInterruptionCode = \"cancelled\" | \"deadline_exceeded\";\ntype DaemonInterruptedExecutionState = \"not_started\" | \"indeterminate\";\n\nfunction requestError(code: DaemonRequestInterruptionCode, message: string, state: DaemonInterruptedExecutionState) {\n\treturn new RemoteWorkspaceRequestError({ code, message, executionState: state, retryable: false });\n}\ninterface DaemonRequestRuntime {\n\tconfiguration: DaemonConfiguration;\n\toperations: ConfinedDaemonToolOperations;\n\thost: WorkspaceToolHost;\n\tlspRuntime: LspRuntimeState | undefined;\n\tworkspace: RemoteWorkspaceIdentity;\n\tsharedMode: boolean;\n}\n\nfunction withDaemonWorkspace<T extends Record<string, unknown>>(result: T, workspace: RemoteWorkspaceIdentity) {\n\treturn { ...result, workspace };\n}\n\nasync function synchronizeDaemonToolFile(\n\ttoolName: string,\n\tinvocationArguments: unknown,\n\truntime: DaemonRequestRuntime,\n): Promise<void> {\n\tif (!runtime.lspRuntime) return;\n\tconst args = invocationArguments as { path?: unknown };\n\tif (typeof args.path !== \"string\") return;\n\ttry {\n\t\tif (toolName === \"read\") {\n\t\t\tawait runtime.lspRuntime.fileSync.handleFileRead(args.path, runtime.operations);\n\t\t} else if (toolName === \"write\" || toolName === \"edit\") {\n\t\t\tawait runtime.lspRuntime.fileSync.handleFileWrite(args.path, runtime.operations);\n\t\t}\n\t} catch {\n\t\t// Synchronization remains best-effort, matching local AgentSession behavior.\n\t}\n}\n\nfunction marksToolSideEffect(kind: RemoteWorkspaceOperationKind, toolName: string, sharedMode: boolean): boolean {\n\treturn kind !== \"read\" && !(sharedMode && (toolName === \"edit\" || toolName === \"write\"));\n}\n\nasync function invokeDaemonTool(\n\trequest: RemoteWorkspaceTypedRequest,\n\tparams: Record<string, unknown>,\n\tcontext: RemoteWorkspaceServerRequestContext,\n\truntime: DaemonRequestRuntime,\n): Promise<AgentToolResult<unknown>> {\n\tconst toolName = params.toolName as string;\n\tconst kind = operationKind(toolName);\n\tif (marksToolSideEffect(kind, toolName, runtime.sharedMode)) context.markSideEffectStarted();\n\tlet updateQueue = Promise.resolve();\n\ttry {\n\t\tconst result = await runtime.host.executePrepared(toolName, {\n\t\t\ttoolCallId: request.id,\n\t\t\targuments: params.arguments,\n\t\t\tsignal: context.signal,\n\t\t\texecutionOptions: params.executionOptions as WorkspaceToolExecutionOptions,\n\t\t\tonUpdate: (update) => {\n\t\t\t\tupdateQueue = updateQueue.then(() => context.sendUpdate(portableToolResult(update)));\n\t\t\t},\n\t\t});\n\t\tawait updateQueue;\n\t\tawait synchronizeDaemonToolFile(toolName, params.arguments, runtime);\n\t\tif (kind !== \"read\") context.markCommitted();\n\t\treturn portableToolResult(result);\n\t} catch (error) {\n\t\tawait updateQueue.catch(() => undefined);\n\t\tif (context.signal.aborted) {\n\t\t\tthrow requestError(\n\t\t\t\t\"cancelled\",\n\t\t\t\t\"Remote workspace tool invocation was cancelled\",\n\t\t\t\tkind === \"read\" ? \"not_started\" : \"indeterminate\",\n\t\t\t);\n\t\t}\n\t\tif (error instanceof RemoteWorkspaceRequestError) throw error;\n\t\tthrow new RemoteWorkspaceRequestError({\n\t\t\tcode: \"internal_error\",\n\t\t\tmessage: error instanceof Error ? error.message.slice(0, 4096) : \"Workspace tool failed\",\n\t\t\texecutionState: kind === \"read\" ? \"not_started\" : \"indeterminate\",\n\t\t\tretryable: false,\n\t\t});\n\t}\n}\n\nasync function executeDaemonWorkspaceProcess(\n\tparams: Record<string, unknown>,\n\tcontext: RemoteWorkspaceServerRequestContext,\n\truntime: DaemonRequestRuntime,\n): Promise<ToolExecResult> {\n\tcontext.markSideEffectStarted();\n\tlet updateQueue = Promise.resolve();\n\tlet pendingOutputBytes = 0;\n\tlet outputLimitExceeded = false;\n\tconst outputController = new AbortController();\n\tconst signal = AbortSignal.any([context.signal, outputController.signal]);\n\tlet result: ToolExecResult;\n\ttry {\n\t\tresult = await runtime.operations.exec(params.command as string, {\n\t\t\tcwd: params.cwd as string,\n\t\t\tsignal,\n\t\t\tonData: (data) => {\n\t\t\t\tif (outputLimitExceeded) return;\n\t\t\t\tconst chunk = Buffer.from(data);\n\t\t\t\tpendingOutputBytes += chunk.byteLength;\n\t\t\t\tif (pendingOutputBytes > runtime.configuration.maxBufferedOutputBytes) {\n\t\t\t\t\toutputLimitExceeded = true;\n\t\t\t\t\toutputController.abort();\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t\tupdateQueue = updateQueue\n\t\t\t\t\t.then(() => context.sendUpdate({ dataBase64: chunk.toString(\"base64\") }))\n\t\t\t\t\t.finally(() => {\n\t\t\t\t\t\tpendingOutputBytes -= chunk.byteLength;\n\t\t\t\t\t});\n\t\t\t\t// The process may run after an update fails; observe rejection until the final await.\n\t\t\t\tvoid updateQueue.catch(() => undefined);\n\t\t\t},\n\t\t});\n\t} catch (error) {\n\t\tif (outputLimitExceeded) throw new Error(\"Process output exceeded the daemon buffered-output limit\");\n\t\tthrow error;\n\t}\n\tawait updateQueue;\n\tcontext.markCommitted();\n\treturn result;\n}\n\nasync function readDaemonResource(\n\tparams: Record<string, unknown>,\n\truntime: DaemonRequestRuntime,\n): Promise<Record<string, unknown>> {\n\tconst path = params.path as string;\n\tconst resourcePath =\n\t\tpath === \"SANDBOX.md\"\n\t\t\t? runtime.configuration.sandboxInstructionsPath\n\t\t\t: path === \"AGENTS.md\"\n\t\t\t\t? runtime.configuration.userAgentsPath\n\t\t\t\t: undefined;\n\tif (!resourcePath) {\n\t\tthrow new RemoteWorkspaceRequestError({\n\t\t\tcode: \"not_available\",\n\t\t\tmessage: \"Requested daemon resource is not available\",\n\t\t\texecutionState: \"not_started\",\n\t\t\tretryable: false,\n\t\t});\n\t}\n\treturn withDaemonWorkspace({ contentBase64: (await readFile(resourcePath)).toString(\"base64\") }, runtime.workspace);\n}\n\nfunction getDaemonLspStatus(runtime: DaemonRequestRuntime): Record<string, unknown> {\n\tif (!runtime.lspRuntime) {\n\t\tthrow new RemoteWorkspaceRequestError({\n\t\t\tcode: \"not_available\",\n\t\t\tmessage: \"Daemon LSP is not configured\",\n\t\t\texecutionState: \"not_started\",\n\t\t\tretryable: false,\n\t\t});\n\t}\n\treturn {\n\t\tenabled: true,\n\t\tservers: runtime.lspRuntime.manager.getStatus().map((status) => sanitizeLspStatus(status, runtime.configuration)),\n\t};\n}\nasync function statDaemonWorkspace(path: string, runtime: DaemonRequestRuntime): Promise<unknown> {\n\ttry {\n\t\tconst value = await runtime.operations.stat(path);\n\t\treturn withDaemonWorkspace(\n\t\t\t{ kind: value.isDirectory() ? \"directory\" : value.isFile() ? \"file\" : \"other\" },\n\t\t\truntime.workspace,\n\t\t);\n\t} catch (error) {\n\t\tif (!runtime.sharedMode || !isMissingPath(error)) throw error;\n\t\treturn withDaemonWorkspace({ kind: \"absent\" }, runtime.workspace);\n\t}\n}\n\nasync function dispatchDaemonWorkspaceRequest(\n\trequest: RemoteWorkspaceTypedRequest,\n\tcontext: RemoteWorkspaceServerRequestContext,\n\truntime: DaemonRequestRuntime,\n): Promise<unknown> {\n\tconst params = request.params as Record<string, unknown>;\n\tswitch (request.method) {\n\t\tcase \"tool.invoke\":\n\t\t\treturn invokeDaemonTool(request, params, context, runtime);\n\t\tcase \"workspace.access\":\n\t\t\tawait runtime.operations.access(params.path as string, params.mode as ToolAccessMode | undefined);\n\t\t\treturn {};\n\t\tcase \"workspace.read\":\n\t\t\treturn withDaemonWorkspace(\n\t\t\t\t{ contentBase64: (await runtime.operations.readFile(params.path as string)).toString(\"base64\") },\n\t\t\t\truntime.workspace,\n\t\t\t);\n\t\tcase \"workspace.write\":\n\t\t\tif (!runtime.sharedMode) context.markSideEffectStarted();\n\t\t\tawait withFileMutationQueue(resolve(runtime.configuration.workspaceRoot, params.path as string), () =>\n\t\t\t\truntime.operations.writeFile(params.path as string, Buffer.from(params.contentBase64 as string, \"base64\")),\n\t\t\t);\n\t\t\tcontext.markCommitted();\n\t\t\treturn {};\n\t\tcase \"workspace.mkdir\":\n\t\t\tif (!runtime.sharedMode) context.markSideEffectStarted();\n\t\t\tawait withFileMutationQueue(resolve(runtime.configuration.workspaceRoot, params.path as string), () => {\n\t\t\t\tif (runtime.sharedMode) {\n\t\t\t\t\tif (context.signal.aborted)\n\t\t\t\t\t\tthrow requestError(\n\t\t\t\t\t\t\t\"cancelled\",\n\t\t\t\t\t\t\t\"Shared directory creation was cancelled before starting\",\n\t\t\t\t\t\t\t\"not_started\",\n\t\t\t\t\t\t);\n\t\t\t\t\tcontext.markSideEffectStarted();\n\t\t\t\t}\n\t\t\t\treturn runtime.operations.mkdir(params.path as string, { recursive: params.recursive === true });\n\t\t\t});\n\t\t\tcontext.markCommitted();\n\t\t\treturn {};\n\t\tcase \"workspace.stat\":\n\t\t\treturn statDaemonWorkspace(params.path as string, runtime);\n\t\tcase \"workspace.readdir\":\n\t\t\treturn withDaemonWorkspace(\n\t\t\t\t{ entries: await runtime.operations.readdir(params.path as string) },\n\t\t\t\truntime.workspace,\n\t\t\t);\n\t\tcase \"workspace.glob\":\n\t\t\treturn withDaemonWorkspace(\n\t\t\t\t{\n\t\t\t\t\tmatches: await runtime.operations.glob(params.pattern as string, params.cwd as string, {\n\t\t\t\t\t\tignore: params.ignore as string[],\n\t\t\t\t\t\tlimit: params.limit as number,\n\t\t\t\t\t}),\n\t\t\t\t},\n\t\t\t\truntime.workspace,\n\t\t\t);\n\t\tcase \"workspace.grep\": {\n\t\t\tconst result = await runtime.operations.grep(params as unknown as ToolGrepOptions);\n\t\t\treturn withDaemonWorkspace(result as unknown as Record<string, unknown>, runtime.workspace);\n\t\t}\n\t\tcase \"workspace.detect_image_mime\":\n\t\t\treturn withDaemonWorkspace(\n\t\t\t\t{ mimeType: (await runtime.operations.detectImageMimeType(params.path as string)) ?? null },\n\t\t\t\truntime.workspace,\n\t\t\t);\n\t\tcase \"workspace.exec\":\n\t\t\treturn executeDaemonWorkspaceProcess(params, context, runtime);\n\t\tcase \"resource.read\":\n\t\t\treturn readDaemonResource(params, runtime);\n\t\tcase \"lsp.status\":\n\t\t\treturn getDaemonLspStatus(runtime);\n\t\tdefault:\n\t\t\tthrow new RemoteWorkspaceRequestError({\n\t\t\t\tcode: \"method_not_supported\",\n\t\t\t\tmessage: `Workspace operation is not implemented: ${request.method}`,\n\t\t\t\texecutionState: \"not_started\",\n\t\t\t\tretryable: false,\n\t\t\t});\n\t}\n}\n\nexport function createDaemonWorkspaceRuntime(configuration: DaemonConfiguration): DaemonWorkspaceRuntime {\n\tconst operations = new ConfinedDaemonToolOperations(configuration);\n\tconst toolNames: WorkspaceToolName[] = [\"read\", \"edit\", \"write\", \"grep\", \"find\", \"ls\"];\n\tif (configuration.allowProcessExec) toolNames.splice(1, 0, \"bash\");\n\tconst lspConfiguration = loadDaemonLspConfiguration(configuration);\n\tconst lspRuntime = lspConfiguration.enabled\n\t\t? createLspRuntimeState(configuration.workspaceRoot, {\n\t\t\t\tconfiguration: lspConfiguration,\n\t\t\t\tgetToolBackendInfo: () => operations.getBackendInfo(),\n\t\t\t\tgetToolOperations: () => operations,\n\t\t\t\tresolveConnectionFactory: (transport) =>\n\t\t\t\t\ttransport.type === \"spawn\"\n\t\t\t\t\t\t? createManagedStdioConnectionFactory({\n\t\t\t\t\t\t\t\t...transport,\n\t\t\t\t\t\t\t\tenv: operations.createChildEnvironment(transport.env),\n\t\t\t\t\t\t\t\tinheritEnvironment: false,\n\t\t\t\t\t\t\t})\n\t\t\t\t\t\t: resolveLspConnectionFactory(transport),\n\t\t\t})\n\t\t: undefined;\n\tconst host = new WorkspaceToolHost({\n\t\tcwd: configuration.workspaceRoot,\n\t\toperations,\n\t\ttoolNames,\n\t\tadditionalDefinitions: lspRuntime\n\t\t\t? createLspToolDefinitions(\n\t\t\t\t\t() => lspRuntime,\n\t\t\t\t\t() => operations,\n\t\t\t\t)\n\t\t\t: undefined,\n\t\tdisposeTimeoutMs: Math.min(configuration.shutdownTimeoutMs, 60_000),\n\t});\n\tconst catalog: RemoteWorkspaceCatalog = {\n\t\tgeneration: 1,\n\t\ttools: host.getCatalog().map((entry) => ({\n\t\t\tname: entry.name,\n\t\t\texecutionMode: operationKind(entry.name),\n\t\t\tparameterSchema: structuredClone(entry.parameters) as Record<string, unknown>,\n\t\t\tschemaHash: hashRemoteWorkspaceJson(entry.parameters),\n\t\t\tfeatureFlags: [],\n\t\t})),\n\t\toperations: [\n\t\t\t...PRIMITIVE_OPERATIONS.filter((method) => method !== \"workspace.exec\" || configuration.allowProcessExec),\n\t\t\t...(configuration.sandboxInstructionsPath || configuration.userAgentsPath ? ([\"resource.read\"] as const) : []),\n\t\t\t...(lspRuntime ? ([\"lsp.status\"] as const) : []),\n\t\t],\n\t};\n\tconst capabilities: RemoteWorkspaceCapability[] = [\n\t\t\"catalog_refresh\",\n\t\t\"primitive_operations\",\n\t\t\"tool_updates\",\n\t\t...(lspRuntime ? ([\"lsp_status\"] as const) : []),\n\t];\n\tlet activeRequests = 0;\n\n\treturn {\n\t\toperations,\n\t\thost,\n\t\tlspRuntime,\n\t\tcatalog,\n\t\tcapabilities,\n\t\tcreateHandler(workspace, sharedMode = false) {\n\t\t\tconst requestRuntime: DaemonRequestRuntime = {\n\t\t\t\tconfiguration,\n\t\t\t\toperations,\n\t\t\t\thost,\n\t\t\t\tlspRuntime,\n\t\t\t\tworkspace,\n\t\t\t\tsharedMode,\n\t\t\t};\n\t\t\treturn {\n\t\t\t\tvalidateToolArguments: (toolName, value) => host.validatePreparedArguments(toolName, value),\n\t\t\t\tasync handleRequest(request, context) {\n\t\t\t\t\tif (activeRequests >= configuration.maxGlobalRequests) {\n\t\t\t\t\t\tthrow new RemoteWorkspaceRequestError({\n\t\t\t\t\t\t\tcode: \"limit_exceeded\",\n\t\t\t\t\t\t\tmessage: \"Daemon global active request limit reached\",\n\t\t\t\t\t\t\texecutionState: \"not_started\",\n\t\t\t\t\t\t\tretryable: true,\n\t\t\t\t\t\t});\n\t\t\t\t\t}\n\t\t\t\t\tactiveRequests++;\n\t\t\t\t\ttry {\n\t\t\t\t\t\treturn await dispatchDaemonWorkspaceRequest(request, context, requestRuntime);\n\t\t\t\t\t} finally {\n\t\t\t\t\t\tactiveRequests--;\n\t\t\t\t\t}\n\t\t\t\t},\n\t\t\t};\n\t\t},\n\t\tretire: async () => {\n\t\t\tawait host.waitForIdle(configuration.shutdownTimeoutMs);\n\t\t\tawait lspRuntime?.manager.shutdownAll();\n\t\t\tawait host.dispose();\n\t\t},\n\t\tdispose: async () => {\n\t\t\tawait Promise.all([lspRuntime?.manager.shutdownAll(), host.dispose()]);\n\t\t},\n\t};\n}\n"]}
|