Files
trebuchet/apps/cli/src/paths.ts
T
ezl-keygraph 77e300d52a feat: mount user repo as read-only with writable shannon overlay (#273)
* feat: mount user repo as read-only with deliverables bind-mount overlay

* feat: add playground and .playwright-cli overlay mounts

* feat: add filesystem context to pipeline-testing prompts

* fix: use explicit REPO_PATH in filesystem prompt for clarity

* fix: update filesystem prompts with playground notes and absolute screenshot paths

* feat: namespace writable overlays under .shannon/ to avoid polluting host repo

* refactor: rename playground to scratchpad

* fix: redirect playwright-cli output to writable .shannon/ overlay

* fix: pre-create .shannon/ overlay mount points for Linux compatibility

* fix: exclude nested node_modules and dist from Docker build context

* fix: enforce LF line endings for shell scripts on Windows
2026-04-03 23:46:28 +05:30

79 lines
2.1 KiB
TypeScript

/**
* Path resolution for --repo and --config arguments.
*
* Local mode supports bare repo names (e.g. "my-repo" → ./repos/my-repo).
* Both modes resolve relative paths against CWD.
*/
import fs from 'node:fs';
import path from 'node:path';
import { isLocal } from './mode.js';
export interface MountPair {
hostPath: string;
containerPath: string;
}
/**
* Resolve --repo to absolute path and container mount.
* Dev mode: bare names (no / or . prefix) check ./repos/<name> first.
*/
export function resolveRepo(repoArg: string): MountPair {
let hostPath: string;
if (isLocal() && !repoArg.startsWith('/') && !repoArg.startsWith('.')) {
// Bare name — check ./repos/<name> for backward compatibility
const barePath = path.resolve('repos', repoArg);
if (fs.existsSync(barePath)) {
hostPath = barePath;
} else {
console.error(`ERROR: Repository not found at ./repos/${repoArg}`);
console.error('');
console.error('Place your target repository under the ./repos/ directory,');
console.error('or pass an absolute/relative path: -r /path/to/repo');
process.exit(1);
}
} else {
hostPath = path.resolve(repoArg);
}
if (!fs.existsSync(hostPath)) {
console.error(`ERROR: Repository not found: ${hostPath}`);
process.exit(1);
}
if (!fs.statSync(hostPath).isDirectory()) {
console.error(`ERROR: Not a directory: ${hostPath}`);
process.exit(1);
}
const basename = path.basename(hostPath);
return {
hostPath,
containerPath: `/repos/${basename}`,
};
}
/**
* Resolve --config to absolute path and container mount.
*/
export function resolveConfig(configArg: string): MountPair {
const hostPath = path.resolve(configArg);
if (!fs.existsSync(hostPath)) {
console.error(`ERROR: Config file not found: ${hostPath}`);
process.exit(1);
}
if (!fs.statSync(hostPath).isFile()) {
console.error(`ERROR: Not a file: ${hostPath}`);
process.exit(1);
}
const basename = path.basename(hostPath);
return {
hostPath,
containerPath: `/app/configs/${basename}`,
};
}