Files
deepseek-harness/packages/fs/tool-fs/src/session-cwd.ts
T
Tianyi Cui 10a55d7a27 Merge remote-tracking branch 'origin/master' into codex/session-scoped-sandbox-roots
# Conflicts:
#	.agents/notes/implemented/feature/2026-07-14-cross-family-fs-sandbox.i18n.yaml
#	.agents/notes/implemented/feature/2026-07-14-cross-family-fs-sandbox.md
#	.agents/notes/implemented/feature/2026-07-14-cross-family-fs-sandbox.zh.md
#	examples/acp-agent/README.md
#	packages/examples/agent-spine-demo/package.json
#	packages/fs/fs-sandbox/src/index.ts
#	packages/fs/tool-fs-search/tests/tools.spec.ts
#	packages/support/acp-snapshot/README.md
#	packages/support/acp-snapshot/src/suite.ts
#	pnpm-lock.yaml
#	scripts/type-equiv.manifest.json
2026-07-22 21:37:30 +08:00

47 lines
2.1 KiB
TypeScript

/**
* Derive the working directory a filesystem tool resolves relative paths against: the calling
* agent's per-session workspace (`exec.agent.session.header.cwd`), so each ACP session's
* `read`/`write`/`edit` act on ITS workspace, not the server's launch dir — mirroring how
* `dsh-tool-bash` defaults a bash `workdir` to the session cwd.
* Non-agent calls return `undefined`, leaving the fallback in the provider rather than reading
* `process.cwd()` at the tool seam.
* @module @deepseek-ai/dsh-tool-fs/session-cwd
*/
import type { ToolExecution } from '@deepseek-ai/dsh-tools'
import { canonicalPath } from '@deepseek-ai/dsh-sandbox'
const PARENT_PATH_SEGMENT = /(?:^|[\\/])\.\.(?:[\\/]|$)/
/**
* The session workspace cwd for this call, or `undefined` when none applies.
* @param exec - the tool-execution context; only its optional `agent` is read.
* @param requestedPath - the path the provider will resolve; parent traversal
* makes a symlinked cwd's filesystem identity observable.
* @returns the calling agent's session cwd, or undefined for a non-agent caller (the backend then applies its own default).
*/
export function sessionCwd(exec: ToolExecution, requestedPath: string): string | undefined {
const cwd = exec.agent?.session.header.cwd
if (cwd === undefined || (!PARENT_PATH_SEGMENT.test(cwd) && !PARENT_PATH_SEGMENT.test(requestedPath))) return cwd
return canonicalPath(cwd)
}
/**
* Resolution options shared by all model-facing filesystem tools.
* @param exec - the tool-execution context supplying session cwd and cancellation.
* @param requestedPath - the path the provider will resolve.
* @param policyWorkspaceRoot - resolved per-call root, when a mutation carries sandbox policy.
* @returns provider resolution options for the current tool call.
*/
export function sessionResolveOptions(
exec: ToolExecution,
requestedPath: string,
policyWorkspaceRoot?: string,
): { cwd?: string; signal?: AbortSignal } {
const cwd = policyWorkspaceRoot ?? sessionCwd(exec, requestedPath)
return {
...cwd !== undefined ? { cwd } : {},
signal: exec.signal,
}
}