Files
AgentCompany/src/main/services/files/workspace-path.ts
T
ZacharyZhang-NY 07d0b4587d Promote AgentCompany-New to the repository root and retire the old app
The legacy application - its src, tests, landing site, promo assets, docs,
release tooling, CI workflows, and root configs - leaves the tree; it stays
reachable in history. Everything under AgentCompany-New moves up unchanged:
same package name, so the production userData/database path is untouched,
and e2e/build scripts already resolved paths relative to the project. The
developer cred.txt stays gitignored at its new location. Full verify:ci
passes from the new root.
2026-07-07 00:04:13 -04:00

22 lines
1.1 KiB
TypeScript

import { isAbsolute, relative, resolve, sep } from "node:path";
/**
* Resolves a caller-supplied relative path against a workspace root and rejects
* anything that escapes it (absolute paths or `..` traversal). Both writing a
* deliverable and ingesting one back as a file object go through here, so an
* agent-supplied path can only ever land inside the folder the operator bound
* to the company — never `../../.ssh/id_rsa`.
*/
export function resolveWorkspacePath(workspaceRoot: string, relativePath: string): { absolute: string; relativePosix: string } {
const root = resolve(workspaceRoot);
const requested = relativePath.trim().replace(/^[\\/]+/, "");
if (!requested) throw new Error("Workspace path is required.");
if (isAbsolute(requested)) throw new Error("Workspace path must be relative to the workspace.");
const absolute = resolve(root, requested);
const rel = relative(root, absolute);
if (rel === "" || rel.startsWith("..") || isAbsolute(rel)) {
throw new Error("Workspace path escapes the workspace root.");
}
return { absolute, relativePosix: rel.split(sep).join("/") };
}