@madarco/agentbox 0.4.0 → 0.5.0
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/dist/{chunk-3NCUES35.js → chunk-6VTAPD4H.js} +123 -112
- package/dist/chunk-6VTAPD4H.js.map +1 -0
- package/dist/{chunk-J35IH7W5.js → chunk-7J5AJLWG.js} +61 -23
- package/dist/chunk-7J5AJLWG.js.map +1 -0
- package/dist/{chunk-3JKQNOXP.js → chunk-FJNIFTWK.js} +66 -65
- package/dist/chunk-FJNIFTWK.js.map +1 -0
- package/dist/{chunk-IDR4HVIC.js → chunk-HPZMD5DE.js} +2 -2
- package/dist/chunk-HPZMD5DE.js.map +1 -0
- package/dist/{chunk-MOC54XL6.js → chunk-PXUBE5KS.js} +376 -245
- package/dist/chunk-PXUBE5KS.js.map +1 -0
- package/dist/{chunk-SOMIKEN2.js → chunk-RFC5F5HR.js} +272 -214
- package/dist/chunk-RFC5F5HR.js.map +1 -0
- package/dist/create-AHZ3GVEZ-TGEDL7UX.js +15 -0
- package/dist/index.js +2760 -1857
- package/dist/index.js.map +1 -1
- package/dist/{lifecycle-YTMZYKOE-TD5S5FTS.js → lifecycle-LFOL6YFM-TCHDX3J5.js} +5 -5
- package/dist/{state-ZSP3ORXW-WI6KOIG3.js → state-KD7M46ZP-KHFTHFUS.js} +2 -2
- package/dist/stats-Z4BVJODD-HEC4TMUZ.js +19 -0
- package/package.json +3 -2
- package/runtime/docker/Dockerfile.box +53 -20
- package/runtime/docker/apps/cli/share/agentbox-setup/SKILL.md +39 -50
- package/runtime/docker/packages/ctl/dist/bin.cjs +219 -148
- package/runtime/docker/packages/sandbox-docker/scripts/agentbox-checkpoint-cleanup +42 -0
- package/runtime/docker/packages/sandbox-docker/scripts/custom-system-CLAUDE.md +26 -15
- package/runtime/relay/bin.cjs +288 -12
- package/share/agentbox-setup/SKILL.md +39 -50
- package/dist/chunk-3JKQNOXP.js.map +0 -1
- package/dist/chunk-3NCUES35.js.map +0 -1
- package/dist/chunk-IDR4HVIC.js.map +0 -1
- package/dist/chunk-J35IH7W5.js.map +0 -1
- package/dist/chunk-MOC54XL6.js.map +0 -1
- package/dist/chunk-SOMIKEN2.js.map +0 -1
- package/dist/create-SE6H4B5U-IWAZHJHV.js +0 -15
- package/dist/stats-GZFLPYTU-DBJ2DVBJ.js +0 -19
- /package/dist/{create-SE6H4B5U-IWAZHJHV.js.map → create-AHZ3GVEZ-TGEDL7UX.js.map} +0 -0
- /package/dist/{lifecycle-YTMZYKOE-TD5S5FTS.js.map → lifecycle-LFOL6YFM-TCHDX3J5.js.map} +0 -0
- /package/dist/{state-ZSP3ORXW-WI6KOIG3.js.map → state-KD7M46ZP-KHFTHFUS.js.map} +0 -0
- /package/dist/{stats-GZFLPYTU-DBJ2DVBJ.js.map → stats-Z4BVJODD-HEC4TMUZ.js.map} +0 -0
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../packages/sandbox-docker/src/docker.ts","../../../packages/sandbox-docker/src/host-export.ts","../../../packages/sandbox-docker/src/image.ts","../../../packages/sandbox-docker/src/checkpoint.ts","../../../packages/config/src/types.ts","../../../packages/config/src/parse.ts","../../../packages/config/src/paths.ts","../../../packages/config/src/load.ts","../../../packages/config/src/write.ts"],"sourcesContent":["import { execa, type Result } from 'execa';\n\nexport interface DockerExecResult {\n exitCode: number;\n stdout: string;\n stderr: string;\n}\n\nexport type ContainerRuntimeState = 'running' | 'paused' | 'stopped' | 'missing';\n\nexport async function dockerInfo(): Promise<void> {\n const result: Result = await execa('docker', ['info'], { reject: false });\n if (result.exitCode !== 0) {\n throw new Error(\n `docker info failed (exit ${String(result.exitCode)}). Is the Docker daemon running?\\n${String(result.stderr)}`,\n );\n }\n}\n\n/**\n * Engine-agnostic resource ceilings. Memory in bytes, cpus fractional, disk a\n * raw engine-native size string. `null`/absent = unlimited.\n */\nexport interface BoxLimitSpec {\n memoryBytes?: number | null;\n cpus?: number | null;\n pidsLimit?: number | null;\n disk?: string | null;\n}\n\nexport interface RunBoxSpec {\n name: string;\n image: string;\n lowerPath: string;\n upperVolume: string;\n extraVolumes?: string[];\n env?: Record<string, string>;\n limits?: BoxLimitSpec;\n /**\n * docker `-p` mappings to forward host ports into the container. `hostPort: 0`\n * lets Docker pick a free ephemeral port; resolve it back with\n * {@link publishedHostPort}. `hostIp` defaults to all interfaces — pin it to\n * `127.0.0.1` for loopback-only exposure.\n */\n portMappings?: Array<{ hostPort: number; containerPort: number; hostIp?: string }>;\n}\n\nexport async function runBox(spec: RunBoxSpec): Promise<string> {\n const args: string[] = [\n 'run',\n '-d',\n '--name',\n spec.name,\n '--hostname',\n spec.name,\n '--cap-add=SYS_ADMIN',\n // dockerd inside the box (always-on, see launchDockerdDaemon) needs\n // NET_ADMIN to set up its bridge + iptables NAT for inner containers.\n // seccomp:unconfined is required because the default profile blocks\n // syscalls (notably keyctl, clone3 in some kernels) that nested containers\n // need. Both are scoped to the outer box's namespaces — inner containers\n // can't escape it. We still avoid --privileged for cloud portability.\n '--cap-add=NET_ADMIN',\n '--device=/dev/fuse',\n '--security-opt=apparmor:unconfined',\n '--security-opt=seccomp=unconfined',\n // cgroup v2 + DinD: with --cgroupns=host (the OrbStack default) the\n // outer container sees the host's read-only cgroup hierarchy at\n // /sys/fs/cgroup, so the inner dockerd can't `mkdir /sys/fs/cgroup/docker`\n // for its own slice and inner `docker run` fails with \"read-only file\n // system\". Private gives the box its own writable cgroup namespace; runc\n // creates the docker slice there and inner containers nest under it.\n '--cgroupns=private',\n // Make the host reachable from inside the container at the well-known DNS\n // name host.docker.internal. Docker Desktop / OrbStack ship this alias by\n // default; on Linux native Docker it requires this explicit flag (no-op\n // on the macOS engines). Boxes use it to reach the host relay process.\n '--add-host=host.docker.internal:host-gateway',\n '-v',\n `${spec.lowerPath}:/host-src:ro`,\n '-v',\n `${spec.upperVolume}:/upper`,\n ];\n const lim = spec.limits;\n if (lim) {\n if (lim.memoryBytes && lim.memoryBytes > 0) {\n args.push('--memory', String(Math.floor(lim.memoryBytes)));\n }\n if (lim.cpus && lim.cpus > 0) {\n args.push('--cpus', String(lim.cpus));\n }\n if (lim.pidsLimit && lim.pidsLimit > 0) {\n args.push('--pids-limit', String(Math.floor(lim.pidsLimit)));\n }\n // Best-effort: a no-op on overlay2 / the macOS engines. createBox() drops\n // this on those drivers (and warns) so `docker run` doesn't hard-error.\n if (lim.disk) {\n args.push('--storage-opt', `size=${lim.disk}`);\n }\n }\n for (const v of spec.extraVolumes ?? []) {\n args.push('-v', v);\n }\n for (const pm of spec.portMappings ?? []) {\n const host = pm.hostIp ? `${pm.hostIp}:${String(pm.hostPort)}` : String(pm.hostPort);\n args.push('-p', `${host}:${String(pm.containerPort)}`);\n }\n for (const [k, val] of Object.entries(spec.env ?? {})) {\n args.push('-e', `${k}=${val}`);\n }\n args.push(spec.image, 'sleep', 'infinity');\n\n const { stdout } = await execa('docker', args);\n return stdout.trim();\n}\n\n/**\n * The engine's storage driver (`overlay2`, `fuse-overlayfs`, `btrfs`, …).\n * `--storage-opt size=` is only enforced by devicemapper/btrfs/zfs/windowsfilter\n * — a no-op everywhere the macOS engines run. Empty string on probe failure.\n */\nexport async function dockerStorageDriver(): Promise<string> {\n const result = await execa('docker', ['info', '--format', '{{.Driver}}'], { reject: false });\n if (result.exitCode !== 0) return '';\n return (result.stdout ?? '').trim();\n}\n\nexport async function execInBox(\n container: string,\n cmd: string[],\n opts: { user?: string; detach?: boolean; timeoutMs?: number } = {},\n): Promise<DockerExecResult> {\n const args: string[] = ['exec'];\n if (opts.detach) args.push('-d');\n if (opts.user) args.push('--user', opts.user);\n args.push(container, ...cmd);\n const result = await execa('docker', args, {\n reject: false,\n ...(opts.timeoutMs ? { timeout: opts.timeoutMs } : {}),\n });\n return {\n exitCode: result.exitCode ?? -1,\n stdout: result.stdout ?? '',\n stderr: result.stderr ?? '',\n };\n}\n\nexport async function removeContainer(container: string): Promise<void> {\n await execa('docker', ['rm', '-f', container], { reject: false });\n}\n\nexport async function removeVolume(name: string): Promise<void> {\n await execa('docker', ['volume', 'rm', name], { reject: false });\n}\n\n/**\n * Best-effort `docker image rm`. Returns true when the image was actually\n * removed, false when it was already absent (or removal failed). `-f` is\n * passed by default so a stale tagged image with no live containers goes away\n * even if other tags point at the same layers.\n */\nexport async function removeImage(\n ref: string,\n opts: { force?: boolean } = {},\n): Promise<boolean> {\n const args = ['image', 'rm'];\n if (opts.force !== false) args.push('-f');\n args.push(ref);\n const result = await execa('docker', args, { reject: false });\n return result.exitCode === 0;\n}\n\nexport async function containerExists(name: string): Promise<boolean> {\n const result = await execa('docker', ['container', 'inspect', '--format', '{{.Id}}', name], {\n reject: false,\n });\n return result.exitCode === 0;\n}\n\nexport async function volumeExists(name: string): Promise<boolean> {\n const result = await execa('docker', ['volume', 'inspect', name], { reject: false });\n return result.exitCode === 0;\n}\n\nexport async function ensureVolume(name: string): Promise<void> {\n if (await volumeExists(name)) return;\n await execa('docker', ['volume', 'create', name]);\n}\n\nexport async function networkExists(name: string): Promise<boolean> {\n const result = await execa('docker', ['network', 'inspect', name], { reject: false });\n return result.exitCode === 0;\n}\n\nexport async function ensureNetwork(name: string): Promise<void> {\n if (await networkExists(name)) return;\n await execa('docker', ['network', 'create', name]);\n}\n\nexport async function removeNetwork(name: string): Promise<void> {\n await execa('docker', ['network', 'rm', name], { reject: false });\n}\n\nexport async function containerIsRunning(name: string): Promise<boolean> {\n return (await inspectContainerStatus(name)) === 'running';\n}\n\nexport async function pauseContainer(name: string): Promise<void> {\n await execa('docker', ['pause', name]);\n}\n\nexport async function unpauseContainer(name: string): Promise<void> {\n await execa('docker', ['unpause', name]);\n}\n\nexport async function stopContainer(name: string): Promise<void> {\n await execa('docker', ['stop', name]);\n}\n\nexport async function startContainer(name: string): Promise<void> {\n await execa('docker', ['start', name]);\n}\n\nexport async function inspectContainerStatus(name: string): Promise<ContainerRuntimeState> {\n const result = await execa('docker', ['inspect', '--format', '{{.State.Status}}', name], {\n reject: false,\n });\n if (result.exitCode !== 0) return 'missing';\n const status = (result.stdout ?? '').trim();\n switch (status) {\n case 'running':\n return 'running';\n case 'paused':\n return 'paused';\n case 'created':\n case 'exited':\n case 'dead':\n case 'restarting':\n case 'removing':\n return 'stopped';\n default:\n return 'missing';\n }\n}\n\nexport async function inspectContainer(name: string): Promise<unknown | null> {\n const result = await execa('docker', ['inspect', name], { reject: false });\n if (result.exitCode !== 0) return null;\n try {\n const parsed = JSON.parse(result.stdout ?? 'null') as unknown[];\n return Array.isArray(parsed) ? (parsed[0] ?? null) : null;\n } catch {\n return null;\n }\n}\n\nexport async function inspectVolumeMountpoint(name: string): Promise<string | null> {\n const result = await execa('docker', ['volume', 'inspect', '--format', '{{.Mountpoint}}', name], {\n reject: false,\n });\n if (result.exitCode !== 0) return null;\n return (result.stdout ?? '').trim() || null;\n}\n\nconst AGENTBOX_PREFIX = 'agentbox-';\n\nexport async function listAgentboxContainers(): Promise<string[]> {\n const result = await execa(\n 'docker',\n ['ps', '-a', '--filter', `name=^${AGENTBOX_PREFIX}`, '--format', '{{.Names}}'],\n { reject: false },\n );\n if (result.exitCode !== 0) return [];\n return (result.stdout ?? '')\n .split('\\n')\n .map((s) => s.trim())\n .filter((s) => s.startsWith(AGENTBOX_PREFIX));\n}\n\n/**\n * Resolve the host port Docker assigned to a `-p hostPort:containerPort` mapping\n * that used `hostPort=0`. Returns null when the port isn't published or the\n * container is gone. `docker port <name> 6080/tcp` prints e.g.\n * `127.0.0.1:54321` (one line per binding); we take the first.\n */\nexport async function publishedHostPort(\n container: string,\n containerPort: number,\n): Promise<number | null> {\n const result = await execa('docker', ['port', container, `${String(containerPort)}/tcp`], {\n reject: false,\n });\n if (result.exitCode !== 0) return null;\n const first = (result.stdout ?? '').split('\\n')[0]?.trim();\n if (!first) return null;\n const m = /:(\\d+)$/.exec(first);\n return m ? Number(m[1]) : null;\n}\n\nexport async function listAgentboxVolumes(): Promise<string[]> {\n const result = await execa(\n 'docker',\n ['volume', 'ls', '--filter', `name=^${AGENTBOX_PREFIX}`, '--format', '{{.Name}}'],\n { reject: false },\n );\n if (result.exitCode !== 0) return [];\n return (result.stdout ?? '')\n .split('\\n')\n .map((s) => s.trim())\n .filter((s) => s.startsWith(AGENTBOX_PREFIX));\n}\n","import { mkdir, readFile, stat } from 'node:fs/promises';\nimport { homedir } from 'node:os';\nimport { join } from 'node:path';\nimport { execa } from 'execa';\nimport type { BoxStatus } from '@agentbox/ctl';\nimport { execInBox, inspectVolumeMountpoint } from './docker.js';\nimport type { BoxRecord } from './state.js';\n\nexport type DockerEngine = 'orbstack' | 'docker-desktop' | 'other';\n\n/** In-container paths bind-mounted to per-box host dirs by createBox. */\nexport const CONTAINER_EXPORT_MERGED = '/host-export';\nexport const CONTAINER_EXPORT_UPPER = '/host-export-upper';\n\n/** Layer the user wants to look at. */\nexport type ExportLayer = 'merged' | 'upper';\n\nexport interface HostPaths {\n /** Per-box runtime dir on host, e.g. ~/.agentbox/boxes/<id>. */\n boxDir: string;\n /** Snapshot target for the merged /workspace view. */\n mergedExport: string;\n /** Snapshot target for /upper/upper (used on engines without a live host path). */\n upperExport: string;\n /**\n * Native host path to the upper named volume's `upper/` subdir on OrbStack —\n * a live, zero-copy view of the writes layer. Null on Docker Desktop and any\n * engine where the volume isn't browsable from the Mac filesystem.\n */\n upperLiveOnHost: string | null;\n}\n\nlet cachedEngine: DockerEngine | null = null;\n\n/**\n * Inspect the docker daemon to decide which host-side conventions apply.\n * `docker info --format '{{.OperatingSystem}}'` returns strings like\n * \"OrbStack\" or \"Docker Desktop\" — we only care about those two on macOS.\n */\nexport async function detectEngine(): Promise<DockerEngine> {\n if (cachedEngine !== null) return cachedEngine;\n const result = await execa('docker', ['info', '--format', '{{.OperatingSystem}}'], {\n reject: false,\n });\n const os = (result.stdout ?? '').trim().toLowerCase();\n if (os.includes('orbstack')) cachedEngine = 'orbstack';\n else if (os.includes('docker desktop')) cachedEngine = 'docker-desktop';\n else cachedEngine = 'other';\n return cachedEngine;\n}\n\n/**\n * Pin the engine to a specific value, bypassing the `docker info` probe. Two\n * callers today:\n * 1. The CLI bootstrap (apps/cli) when the user has set `engine.kind` in\n * ~/.agentbox/config.yaml — the override applies for the rest of the\n * process so every `detectEngine()` returns the user's choice.\n * 2. Tests, via `__setEngineForTesting` (kept as an alias for back-compat).\n */\nexport function setEngineOverride(engine: DockerEngine | null): void {\n cachedEngine = engine;\n}\n\n/** @deprecated alias for `setEngineOverride`; kept so existing tests don't churn. */\nexport function __setEngineForTesting(engine: DockerEngine | null): void {\n cachedEngine = engine;\n}\n\nexport const BOXES_ROOT = join(homedir(), '.agentbox', 'boxes');\n\nexport function boxRunDirFor(id: string): string {\n return join(BOXES_ROOT, id);\n}\n\n/**\n * Per-box durable status file. The host relay writes it (atomic tmp+rename)\n * when the in-box daemon pushes a `box-status` snapshot; it persists here on\n * the host fs even while the box is paused/stopped. Path must stay in sync\n * with `boxStatusPathFor` in @agentbox/relay's status-store.\n */\nexport function boxStatusPathFor(id: string): string {\n return join(boxRunDirFor(id), 'status.json');\n}\n\n/**\n * Read the persisted box status, or null when there is none (box predates the\n * feature, relay never received a push, corrupt JSON, or a future-incompatible\n * schema). Never throws — callers fall back to live/“unknown”.\n */\nexport async function readBoxStatus(id: string): Promise<BoxStatus | null> {\n try {\n const raw = await readFile(boxStatusPathFor(id), 'utf8');\n const parsed = JSON.parse(raw) as BoxStatus;\n if (parsed.schema !== 1) return null;\n return parsed;\n } catch {\n return null;\n }\n}\n\nasync function pathExists(p: string): Promise<boolean> {\n try {\n await stat(p);\n return true;\n } catch {\n return false;\n }\n}\n\n/**\n * Host path to a subpath inside an OrbStack-managed named volume.\n *\n * OrbStack exposes named volumes at `~/OrbStack/docker/volumes/<name>/` —\n * note: NO `_data` subdir; volume contents appear directly under `<name>/`.\n * `docker volume inspect` reports the in-VM `/var/lib/docker/...` mountpoint\n * instead, which isn't reachable from macOS. Returns the path regardless of\n * whether it exists; callers stat it themselves.\n */\nexport function orbstackVolumePath(volume: string, ...sub: string[]): string {\n return join(homedir(), 'OrbStack', 'docker', 'volumes', volume, ...sub);\n}\n\n/**\n * Resolve the host-visible path to the upper volume's writes layer for live\n * browsing.\n *\n * Docker Desktop has no equivalent host path — returns null.\n */\nexport async function resolveUpperLiveOnHost(\n upperVolume: string,\n engine: DockerEngine,\n): Promise<string | null> {\n if (engine !== 'orbstack') return null;\n // Primary: OrbStack's documented shared folder. Contents of the volume sit\n // directly under <vol>/ — no _data wrapper.\n const orbPath = orbstackVolumePath(upperVolume, 'upper');\n if (await pathExists(orbPath)) return orbPath;\n // Fallback: if docker reports a real-looking host mountpoint (e.g. on Linux\n // hosts or unusual setups), trust it.\n const mp = await inspectVolumeMountpoint(upperVolume);\n if (mp && !mp.startsWith('/var/lib/docker')) {\n const candidate = join(mp, 'upper');\n if (await pathExists(candidate)) return candidate;\n }\n return null;\n}\n\nexport async function getHostPaths(\n record: Pick<BoxRecord, 'id' | 'upperVolume'>,\n engine?: DockerEngine,\n): Promise<HostPaths> {\n const eng = engine ?? (await detectEngine());\n const boxDir = boxRunDirFor(record.id);\n return {\n boxDir,\n mergedExport: join(boxDir, 'workspace'),\n upperExport: join(boxDir, 'upper'),\n upperLiveOnHost: await resolveUpperLiveOnHost(record.upperVolume, eng),\n };\n}\n\nexport interface RefreshOptions {\n layer: ExportLayer;\n /** When true, include /workspace/node_modules in the merged export. Off by default. */\n includeNodeModules?: boolean;\n}\n\nexport interface RefreshResult {\n /** Host path that now reflects the box's current state. */\n hostPath: string;\n /** True when an rsync/tar copy actually ran. False when the OrbStack live path was used directly. */\n copied: boolean;\n /** True when the box predates the /host-export bind and we used the tar-pipe fallback. */\n usedFallback: boolean;\n}\n\ninterface RefreshContext {\n hostBoxDir: string;\n hostTarget: string;\n containerSource: string;\n containerBind: string;\n excludeNodeModules: boolean;\n}\n\nasync function hasContainerPath(container: string, path: string): Promise<boolean> {\n const probe = await execInBox(container, ['test', '-d', path], { user: 'root' });\n return probe.exitCode === 0;\n}\n\n/**\n * Refresh a per-box host export so Finder sees the box's current state.\n *\n * Strategy:\n * - For OrbStack + layer=upper, no copy is needed — the named volume is live\n * on disk. Caller should prefer `hostPaths.upperLiveOnHost`.\n * - Otherwise rsync from the in-container source (`/workspace` or\n * `/upper/upper`) to the bind-mounted host dir (`/host-export` or\n * `/host-export-upper`).\n * - Boxes created before the bind-mounts existed fall back to streaming a\n * `tar | tar` through `docker exec` into the host dir directly.\n */\nexport async function refreshExport(\n record: Pick<BoxRecord, 'id' | 'container' | 'upperVolume'>,\n opts: RefreshOptions,\n): Promise<RefreshResult> {\n const engine = await detectEngine();\n const paths = await getHostPaths(record, engine);\n\n if (opts.layer === 'upper' && engine === 'orbstack' && paths.upperLiveOnHost) {\n await mkdir(paths.boxDir, { recursive: true });\n return { hostPath: paths.upperLiveOnHost, copied: false, usedFallback: false };\n }\n\n const ctx: RefreshContext =\n opts.layer === 'merged'\n ? {\n hostBoxDir: paths.boxDir,\n hostTarget: paths.mergedExport,\n containerSource: '/workspace',\n containerBind: CONTAINER_EXPORT_MERGED,\n excludeNodeModules: !opts.includeNodeModules,\n }\n : {\n hostBoxDir: paths.boxDir,\n hostTarget: paths.upperExport,\n containerSource: '/upper/upper',\n containerBind: CONTAINER_EXPORT_UPPER,\n excludeNodeModules: false,\n };\n\n await mkdir(ctx.hostTarget, { recursive: true });\n\n const bindAvailable = await hasContainerPath(record.container, ctx.containerBind);\n if (bindAvailable) {\n const args = ['rsync', '-a', '--delete'];\n if (ctx.excludeNodeModules) args.push('--exclude=node_modules');\n args.push(`${ctx.containerSource}/`, `${ctx.containerBind}/`);\n const r = await execInBox(record.container, args, { user: 'root' });\n if (r.exitCode !== 0) {\n throw new ExportError(`rsync into ${ctx.containerBind} failed`, r.stdout, r.stderr);\n }\n return { hostPath: ctx.hostTarget, copied: true, usedFallback: false };\n }\n\n // Fallback for pre-existing boxes: stream a tar through docker exec into the\n // host target. Slower and skips the in-place delete that rsync gives us, but\n // it works without recreating the container.\n const excludes = ctx.excludeNodeModules ? ['--exclude=node_modules'] : [];\n const result = await execa(\n 'docker',\n ['exec', '--user', 'root', record.container, 'tar', '-cf', '-', ...excludes, '-C', ctx.containerSource, '.'],\n { reject: false, encoding: 'buffer' },\n );\n if (result.exitCode !== 0) {\n throw new ExportError(\n `tar from ${ctx.containerSource} failed`,\n '',\n typeof result.stderr === 'string' ? result.stderr : (result.stderr as Buffer).toString('utf8'),\n );\n }\n const extract = await execa('tar', ['-xf', '-', '-C', ctx.hostTarget], {\n input: result.stdout as Buffer,\n reject: false,\n });\n if (extract.exitCode !== 0) {\n throw new ExportError('tar extract on host failed', extract.stdout, extract.stderr);\n }\n return { hostPath: ctx.hostTarget, copied: true, usedFallback: true };\n}\n\n/**\n * Default env/config file basename globs for `pull env` / `pull --with-env`.\n * These are almost always gitignored, so a normal gitignore-aware `pull`\n * skips them; this list opts them back in explicitly. `agentbox.yaml` is\n * included so a file generated in-box by `/agentbox-setup` lands on the host\n * even before it's committed.\n */\nexport const DEFAULT_ENV_PATTERNS = [\n '.env',\n '.env.*',\n '.envrc',\n '.dev.vars',\n 'secrets.toml',\n 'local.settings.json',\n 'appsettings.*.json',\n 'agentbox.yaml',\n];\n\n/** Directories the env-file `find` prunes — heavy or never-relevant. */\nconst ENV_PRUNE_DIRS = [\n 'node_modules',\n '.git',\n '.venv',\n 'venv',\n '__pycache__',\n 'dist',\n '.next',\n 'build',\n];\n\n/**\n * Build the in-box `find` argv that enumerates env/config files by basename\n * glob, pruning `ENV_PRUNE_DIRS`. `-printf '%P\\0'` emits NUL-delimited paths\n * already relative to /workspace (so they feed rsync --files-from --from0\n * directly, exactly like `git ls-files -z`).\n */\nfunction buildEnvFindArgs(patterns: string[]): string[] {\n const nameGroup = (names: string[]): string[] => {\n const out: string[] = [];\n names.forEach((n, i) => {\n if (i > 0) out.push('-o');\n out.push('-name', n);\n });\n return out;\n };\n return [\n 'find',\n '/workspace',\n '(',\n '-type',\n 'd',\n '(',\n ...nameGroup(ENV_PRUNE_DIRS),\n ')',\n '-prune',\n ')',\n '-o',\n '(',\n '-type',\n 'f',\n '(',\n ...nameGroup(patterns),\n ')',\n '-printf',\n '%P\\\\0',\n ')',\n ];\n}\n\n/**\n * Host-side mirror of `buildEnvFindArgs` for the reverse direction (host →\n * box). Rooted at `.` (run with cwd = the host workspace) and uses `-print0`\n * instead of `-printf '%P\\0'` because macOS's BSD `find` has no `-printf`;\n * `./relpath` entries feed `tar -C <workspace> --null -T -` directly, exactly\n * like the untracked-file pipe in git-worktree.ts.\n */\nexport function buildHostEnvFindArgs(patterns: string[]): string[] {\n const nameGroup = (names: string[]): string[] => {\n const out: string[] = [];\n names.forEach((n, i) => {\n if (i > 0) out.push('-o');\n out.push('-name', n);\n });\n return out;\n };\n return [\n 'find',\n '.',\n '(',\n '-type',\n 'd',\n '(',\n ...nameGroup(ENV_PRUNE_DIRS),\n ')',\n '-prune',\n ')',\n '-o',\n '(',\n '-type',\n 'f',\n '(',\n ...nameGroup(patterns),\n ')',\n '-print0',\n ')',\n ];\n}\n\nexport interface CopyHostEnvOptions {\n /** Target container name (must be running with the overlay mounted). */\n container: string;\n /** Absolute host workspace dir — the same dir that maps to /workspace. */\n workspaceDir: string;\n /** Basename globs to copy (normally DEFAULT_ENV_PATTERNS). */\n patterns: string[];\n onLog?: (line: string) => void;\n}\n\n/**\n * Copy the host's env/config files (selected by `patterns`, gitignore ignored)\n * into the running box's `/workspace`. The reverse of `pullToHost`'s env\n * segment. Writes land in the overlay's writable upper layer (the container is\n * up + mounted at call time), so they survive pause/stop/start.\n *\n * Best-effort: a tar/exec failure or an empty match set logs and returns the\n * count rather than throwing — a missing secret shouldn't abort an otherwise\n * healthy box. Files extract as uid 1000 so they're owned by `vscode` like the\n * rest of /workspace.\n */\nexport async function copyHostEnvFilesToBox(\n opts: CopyHostEnvOptions,\n): Promise<{ copied: number }> {\n const log = opts.onLog ?? (() => {});\n\n // Default (utf8) encoding: `find` output is NUL-delimited path text, and\n // `encoding:'buffer'` would hand back a Uint8Array whose .toString() is\n // comma-joined byte codes, not the paths.\n const found = await execa('find', buildHostEnvFindArgs(opts.patterns).slice(1), {\n cwd: opts.workspaceDir,\n reject: false,\n });\n if (found.exitCode !== 0) {\n log(`warning: env-file scan failed: ${String(found.stderr).slice(0, 300)}`);\n return { copied: 0 };\n }\n const list = String(found.stdout)\n .split('\\0')\n .filter((p) => p.length > 0);\n if (list.length === 0) return { copied: 0 };\n\n // Same fork-and-stream as the untracked-file carry-over in git-worktree.ts.\n const packed = await execa('tar', ['-C', opts.workspaceDir, '--null', '-T', '-', '-cf', '-'], {\n input: list.join('\\0'),\n encoding: 'buffer',\n reject: false,\n });\n if (packed.exitCode !== 0) {\n log(`warning: env-file tar pack failed: ${String(packed.stderr).slice(0, 300)}`);\n return { copied: 0 };\n }\n const extract = await execa(\n 'docker',\n ['exec', '-i', '--user', '1000:1000', opts.container, 'tar', '-xf', '-', '-C', '/workspace'],\n { input: packed.stdout as Buffer, reject: false },\n );\n if (extract.exitCode !== 0) {\n log(`warning: env-file copy into box failed: ${String(extract.stderr).slice(0, 300)}`);\n return { copied: 0 };\n }\n return { copied: list.length };\n}\n\nexport interface PullOptions {\n /** Default true. When false, skip git ls-files and use the static exclude-list. */\n respectGitignore?: boolean;\n /** Default false. When true, don't filter node_modules even in fallback mode. */\n includeNodeModules?: boolean;\n /** Default false. Skip the initial refreshExport — pull whatever's already in the scratch dir. */\n noRefresh?: boolean;\n /** Default false. Run rsync with --dry-run; return the change list without writing. */\n dryRun?: boolean;\n /**\n * Extra env/config files to pull, selected by these basename globs via an\n * in-box `find` (heavy dirs pruned). Composes WITH gitignore selection: the\n * rsync file list is the union of the git-tracked set (unless\n * respectGitignore is false) and these matches. Empty/undefined = no env\n * segment.\n */\n envPatterns?: string[];\n}\n\nexport interface PullResult {\n /** Absolute host workspace path the pull targeted (record.workspacePath). */\n hostPath: string;\n /** Per-file rsync change list (itemized `-i` lines, transfers/deletes only). */\n changes: string[];\n /** True when an actual write happened. False on dry-run. */\n applied: boolean;\n /** True when gitignore-mode was used (vs. the fallback exclude-list). */\n usedGitignore: boolean;\n}\n\n/**\n * Keep only itemized lines that represent an actual file transfer or delete.\n * rsync `-i` emits a leading 11-char code: char 0 is the update type\n * (`>`/`<`/`c`/`*` = transfer/change/delete; `.` = attr-only, skipped) and\n * char 1 is the entry type (`f` file, `d` dir, ...). Directory lines (`d`)\n * are pruned: rsync creates parent dirs as a side effect of transferring\n * files, so counting them would overstate \"files changed\".\n */\nfunction parseItemizedChanges(stdout: string): string[] {\n return stdout\n .split('\\n')\n .map((l) => l.trimEnd())\n .filter((l) => l.length > 0)\n .filter((l) => {\n const code = l[0];\n const kind = l[1];\n return (code === '>' || code === '<' || code === 'c' || code === '*') && kind !== 'd';\n });\n}\n\n/**\n * Reverse of `refreshExport`: bring the box's merged `/workspace` view back\n * into the user's actual host working directory (`record.workspacePath`).\n *\n * Two-stage: (1) `refreshExport` materializes `/workspace` in the per-box\n * scratch dir (`~/.agentbox/boxes/<id>/workspace`) — that path is the only\n * way to read the in-container FUSE overlay from the Mac; (2) a host-side\n * rsync copies scratch → `workspacePath`.\n *\n * Filtering: by default we ask git *inside the box* which files it would\n * track (`git ls-files --cached --others --exclude-standard`) so node_modules\n * / build dirs / gitignored secrets never leak back. Non-git workspaces (or\n * `respectGitignore: false`) fall back to a static `--exclude` list.\n *\n * Never passes `--delete`: files that exist on the host but not in the box\n * are preserved. Removals are the user's call.\n */\nexport async function pullToHost(\n record: Pick<BoxRecord, 'id' | 'container' | 'upperVolume' | 'workspacePath'>,\n opts: PullOptions = {},\n): Promise<PullResult> {\n const engine = await detectEngine();\n const paths = await getHostPaths(record, engine);\n\n let scratchDir: string;\n if (opts.noRefresh) {\n scratchDir = paths.mergedExport;\n await mkdir(scratchDir, { recursive: true });\n } else {\n const refreshed = await refreshExport(record, {\n layer: 'merged',\n includeNodeModules: opts.includeNodeModules,\n });\n scratchDir = refreshed.hostPath;\n }\n\n // The rsync file list is the union of up to two independent NUL-delimited\n // segments: git-tracked (gitignore-aware) and env-pattern (gitignore\n // bypassed). If neither is produced we fall through to the static\n // exclude-list (non-git workspace, no env patterns).\n const segments: string[] = [];\n let usedGitignore = false;\n if (opts.respectGitignore !== false) {\n const isGit = await execInBox(\n record.container,\n ['git', '-C', '/workspace', 'rev-parse', '--is-inside-work-tree'],\n { user: 'root' },\n );\n if (isGit.exitCode === 0 && isGit.stdout.trim() === 'true') {\n const ls = await execInBox(\n record.container,\n ['git', '-C', '/workspace', 'ls-files', '-z', '--cached', '--others', '--exclude-standard'],\n { user: 'root' },\n );\n if (ls.exitCode !== 0) {\n throw new ExportError('git ls-files in box failed', ls.stdout, ls.stderr);\n }\n // git -z is NUL-delimited; rsync --from0 wants the same.\n const tracked = ls.stdout.replace(/\\0$/, '');\n if (tracked.length > 0) segments.push(tracked);\n usedGitignore = true;\n }\n }\n if (opts.envPatterns && opts.envPatterns.length > 0) {\n const found = await execInBox(\n record.container,\n buildEnvFindArgs(opts.envPatterns),\n { user: 'root' },\n );\n if (found.exitCode !== 0) {\n throw new ExportError('find env files in box failed', found.stdout, found.stderr);\n }\n const envFiles = found.stdout.replace(/\\0$/, '');\n if (envFiles.length > 0) segments.push(envFiles);\n }\n const fileList =\n segments.length > 0\n ? Array.from(new Set(segments.join('\\0').split('\\0'))).join('\\0')\n : null;\n\n // --checksum, not the default size+mtime quick-check: the box runs on a\n // fresh git worktree so every file's mtime differs from the user's working\n // tree even when the content is byte-identical. Without -c, rsync would\n // \"update\" the entire tree. -c compares content hashes so only genuinely\n // changed files are written.\n const baseArgs = ['-a', '--checksum'];\n if (fileList === null) {\n baseArgs.push('--exclude=.git');\n if (!opts.includeNodeModules) baseArgs.push('--exclude=node_modules');\n } else {\n baseArgs.push('--files-from=-', '--from0');\n }\n const src = `${scratchDir}/`;\n const dst = `${record.workspacePath}/`;\n\n const dry = await execa('rsync', [...baseArgs, '--dry-run', '-i', src, dst], {\n reject: false,\n input: fileList !== null ? fileList : undefined,\n });\n if (dry.exitCode !== 0) {\n throw new ExportError('rsync dry-run failed', dry.stdout, dry.stderr);\n }\n const changes = parseItemizedChanges(dry.stdout);\n\n if (opts.dryRun) {\n return { hostPath: record.workspacePath, changes, applied: false, usedGitignore };\n }\n\n const real = await execa('rsync', [...baseArgs, src, dst], {\n reject: false,\n input: fileList !== null ? fileList : undefined,\n });\n if (real.exitCode !== 0) {\n throw new ExportError(`rsync into ${record.workspacePath} failed`, real.stdout, real.stderr);\n }\n return { hostPath: record.workspacePath, changes, applied: true, usedGitignore };\n}\n\nexport interface OpenOptions extends RefreshOptions {\n /** When true, skip rsync and just open whatever's already on disk. */\n noRefresh?: boolean;\n /** When true, refresh as usual but don't launch macOS `open` on the resulting path. */\n noOpen?: boolean;\n}\n\nexport interface OpenResult {\n hostPath: string;\n copied: boolean;\n usedFallback: boolean;\n engine: DockerEngine;\n}\n\n/**\n * Refresh the requested export (unless suppressed) and launch the macOS\n * `open` command on it. Returns the host path that was opened.\n *\n * Set `noOpen: true` to refresh and return the path without launching\n * Finder — used by `agentbox open --print` so scripted callers get a\n * fresh path in one call.\n */\nexport async function openInFinder(\n record: Pick<BoxRecord, 'id' | 'container' | 'upperVolume'>,\n opts: OpenOptions,\n): Promise<OpenResult> {\n const engine = await detectEngine();\n let hostPath: string;\n let copied = false;\n let usedFallback = false;\n\n if (opts.noRefresh) {\n const paths = await getHostPaths(record, engine);\n if (opts.layer === 'upper' && engine === 'orbstack' && paths.upperLiveOnHost) {\n hostPath = paths.upperLiveOnHost;\n } else {\n hostPath = opts.layer === 'merged' ? paths.mergedExport : paths.upperExport;\n await mkdir(hostPath, { recursive: true });\n }\n } else {\n const refreshed = await refreshExport(record, opts);\n hostPath = refreshed.hostPath;\n copied = refreshed.copied;\n usedFallback = refreshed.usedFallback;\n }\n\n if (!opts.noOpen) {\n const opened = await execa('open', [hostPath], { reject: false });\n if (opened.exitCode !== 0) {\n throw new ExportError(`open ${hostPath} failed`, opened.stdout, opened.stderr);\n }\n }\n\n return { hostPath, copied, usedFallback, engine };\n}\n\nexport class ExportError extends Error {\n constructor(\n message: string,\n public readonly stdout: string,\n public readonly stderr: string,\n ) {\n super(`${message}${stderr ? `: ${stderr.trim()}` : ''}`);\n this.name = 'ExportError';\n }\n}\n","import { execa } from 'execa';\nimport { existsSync } from 'node:fs';\nimport { fileURLToPath } from 'node:url';\nimport { dirname, resolve } from 'node:path';\n\nexport const DEFAULT_BOX_IMAGE = 'agentbox/box:dev';\n\nconst here = dirname(fileURLToPath(import.meta.url));\n\n// The Dockerfile's COPY lines reference monorepo-relative paths\n// (packages/ctl/dist/bin.cjs, apps/cli/share/..., packages/sandbox-docker/scripts/*),\n// so the build context must be a dir containing that tree.\n//\n// Resolution order:\n// 0. AGENTBOX_DOCKER_CONTEXT env override (dir holding Dockerfile.box).\n// 1. Staged context shipped with the bundled `agent-box` package: this\n// module is bundled into the CLI at <root>/dist, the stage step mirrors\n// the COPY tree at <root>/runtime/docker (sibling of dist/, uniform in\n// dev and when installed).\n// 2. Legacy monorepo: Dockerfile.box at the sandbox-docker package root,\n// build context = monorepo root.\nfunction resolveDockerBuild(): { dockerfile: string; context: string } {\n const override = process.env.AGENTBOX_DOCKER_CONTEXT;\n if (override && existsSync(resolve(override, 'Dockerfile.box'))) {\n return { dockerfile: resolve(override, 'Dockerfile.box'), context: override };\n }\n const staged = resolve(here, '..', 'runtime', 'docker');\n if (existsSync(resolve(staged, 'Dockerfile.box'))) {\n return { dockerfile: resolve(staged, 'Dockerfile.box'), context: staged };\n }\n // Legacy: src/ (or the unbundled package dist/) is one level under the\n // package root; the monorepo root is two more up.\n const packageRoot = resolve(here, '..');\n return {\n dockerfile: resolve(packageRoot, 'Dockerfile.box'),\n context: resolve(packageRoot, '..', '..'),\n };\n}\n\nconst { dockerfile: DOCKERFILE_PATH_RESOLVED, context: BUILD_CONTEXT_DIR_RESOLVED } =\n resolveDockerBuild();\nexport const DOCKERFILE_PATH = DOCKERFILE_PATH_RESOLVED;\nexport const BUILD_CONTEXT_DIR = BUILD_CONTEXT_DIR_RESOLVED;\n\nexport async function imageExists(ref: string): Promise<boolean> {\n const result = await execa('docker', ['image', 'inspect', ref], { reject: false });\n return result.exitCode === 0;\n}\n\nexport interface BuildImageOptions {\n ref?: string;\n dockerfile?: string;\n contextDir?: string;\n onProgress?: (line: string) => void;\n}\n\nexport async function buildImage(opts: BuildImageOptions = {}): Promise<string> {\n const ref = opts.ref ?? DEFAULT_BOX_IMAGE;\n const dockerfile = opts.dockerfile ?? DOCKERFILE_PATH;\n const contextDir = opts.contextDir ?? BUILD_CONTEXT_DIR;\n\n const subprocess = execa('docker', ['build', '-t', ref, '-f', dockerfile, contextDir], {\n stderr: 'pipe',\n stdout: 'pipe',\n });\n\n if (opts.onProgress) {\n const forward = (chunk: Buffer | string): void => {\n const text = typeof chunk === 'string' ? chunk : chunk.toString('utf8');\n for (const line of text.split(/\\r?\\n/)) {\n if (line.length > 0) opts.onProgress?.(line);\n }\n };\n subprocess.stdout?.on('data', forward);\n subprocess.stderr?.on('data', forward);\n }\n\n await subprocess;\n return ref;\n}\n\nexport interface EnsureImageOptions {\n onProgress?: (line: string) => void;\n /** Dockerfile path. Defaults to `Dockerfile.box` next to this package. */\n dockerfile?: string;\n /** Build context directory. Defaults to the monorepo root. */\n contextDir?: string;\n}\n\nexport async function ensureImage(\n ref: string = DEFAULT_BOX_IMAGE,\n opts: EnsureImageOptions = {},\n): Promise<{ ref: string; built: boolean }> {\n if (await imageExists(ref)) {\n return { ref, built: false };\n }\n await buildImage({\n ref,\n dockerfile: opts.dockerfile,\n contextDir: opts.contextDir,\n onProgress: opts.onProgress,\n });\n return { ref, built: true };\n}\n\n","import { mkdir, readFile, readdir, rm, writeFile } from 'node:fs/promises';\nimport { homedir } from 'node:os';\nimport { join } from 'node:path';\nimport { execa } from 'execa';\nimport { hashProjectPath, setConfigValue } from '@agentbox/config';\nimport { ensureVolume } from './docker.js';\nimport { DEFAULT_BOX_IMAGE } from './image.js';\nimport type { BoxRecord } from './state.js';\n\nexport const CHECKPOINTS_ROOT = join(homedir(), '.agentbox', 'checkpoints');\n\n/** All per-project checkpoint volumes share this prefix (prune allowlist). */\nexport const CHECKPOINT_VOLUME_PREFIX = 'agentbox-ckpt-';\n\n/** Read-only mount point of the per-project checkpoint volume inside a box. */\nexport const CHECKPOINT_MOUNT = '/agentbox-checkpoints';\n\n/**\n * One Docker volume per project; each checkpoint is a `<name>` subdir inside\n * it. Deterministic from the project root (same hash the per-project config\n * dir uses), so it survives box destroy and is shared read-only across boxes.\n * Pure — unit-tested directly.\n */\nexport function checkpointVolumeName(projectRoot: string): string {\n return `${CHECKPOINT_VOLUME_PREFIX}${hashProjectPath(projectRoot)}`;\n}\n\nexport type CheckpointType = 'layered' | 'merged';\n\nexport interface CheckpointManifest {\n schema: 1;\n name: string;\n type: CheckpointType;\n /**\n * For a layered checkpoint, the older checkpoint refs this delta stacks on\n * (upper-most first, base-most last) — i.e. the chain the *source* box was\n * built from. `[]` for a merged checkpoint (self-contained) or a layered\n * checkpoint taken from a box that itself started from bare host code.\n */\n parents: string[];\n base: 'worktree' | 'workspace';\n sourceBoxId: string;\n sourceBoxName: string;\n /** Per-project Docker volume the captured tree lives in (subdir = `name`). */\n volume: string;\n createdAt: string;\n}\n\nexport interface CheckpointInfo {\n name: string;\n /** Host dir holding `manifest.json` (`~/.agentbox/checkpoints/<hash>/<name>`). */\n dir: string;\n manifest: CheckpointManifest;\n}\n\n/** Resolved lower spec a new box should mount when starting from a checkpoint. */\nexport interface CheckpointLowerSpec {\n type: CheckpointType;\n /** The single per-project checkpoint volume (mounted ro once at CHECKPOINT_MOUNT). */\n volume: string;\n /**\n * Checkpoint subdir names within `volume`, upper-most first. For `layered`\n * the caller appends the base lower (`/host-src`) after these; for `merged`\n * this is the sole lower (single entry).\n */\n subpaths: string[];\n /** Checkpoint refs composing the chain, base-most last (for BoxRecord.checkpointSource). */\n chain: string[];\n}\n\nexport function projectCheckpointsDir(projectRoot: string): string {\n return join(CHECKPOINTS_ROOT, hashProjectPath(projectRoot));\n}\n\nfunction checkpointDir(projectRoot: string, name: string): string {\n return join(projectCheckpointsDir(projectRoot), name);\n}\n\nasync function readManifest(dir: string): Promise<CheckpointManifest | null> {\n try {\n const raw = await readFile(join(dir, 'manifest.json'), 'utf8');\n const m = JSON.parse(raw) as CheckpointManifest;\n if (m.schema !== 1) return null;\n return m;\n } catch {\n return null;\n }\n}\n\nexport async function listCheckpoints(projectRoot: string): Promise<CheckpointInfo[]> {\n const root = projectCheckpointsDir(projectRoot);\n let entries: string[];\n try {\n entries = (await readdir(root, { withFileTypes: true }))\n .filter((e) => e.isDirectory())\n .map((e) => e.name);\n } catch {\n return [];\n }\n const out: CheckpointInfo[] = [];\n for (const name of entries) {\n const dir = join(root, name);\n const manifest = await readManifest(dir);\n if (manifest) out.push({ name, dir, manifest });\n }\n out.sort((a, b) => a.manifest.createdAt.localeCompare(b.manifest.createdAt));\n return out;\n}\n\nexport async function resolveCheckpoint(\n projectRoot: string,\n ref: string,\n): Promise<CheckpointInfo | null> {\n const dir = checkpointDir(projectRoot, ref);\n const manifest = await readManifest(dir);\n if (!manifest) return null;\n return { name: ref, dir, manifest };\n}\n\nexport async function removeCheckpoint(projectRoot: string, ref: string): Promise<boolean> {\n const dir = checkpointDir(projectRoot, ref);\n const manifest = await readManifest(dir);\n if (!manifest) return false;\n await rm(dir, { recursive: true, force: true });\n // Delete only this checkpoint's subdir; the per-project volume stays for the\n // project's other checkpoints. Best-effort (volume may already be gone).\n const volume = manifest.volume || checkpointVolumeName(projectRoot);\n await execa(\n 'docker',\n ['run', '--rm', '--user', '0:0', '-v', `${volume}:/dst`, DEFAULT_BOX_IMAGE, 'rm', '-rf', `/dst/${ref}`],\n { reject: false },\n );\n return true;\n}\n\n/**\n * Next `<boxName>-<n>` given the names already present. Monotonic per\n * box-name; gaps from deleted checkpoints are skipped (max+1, never\n * recycled). Pure — unit-tested directly.\n */\nexport function computeNextCheckpointName(existingNames: string[], boxName: string): string {\n const re = new RegExp(`^${boxName.replace(/[.*+?^${}()|[\\]\\\\]/g, '\\\\$&')}-(\\\\d+)$`);\n let max = 0;\n for (const n of existingNames) {\n const m = re.exec(n);\n if (m) max = Math.max(max, Number(m[1]));\n }\n return `${boxName}-${String(max + 1)}`;\n}\n\nasync function nextCheckpointName(projectRoot: string, boxName: string): Promise<string> {\n const existing = await listCheckpoints(projectRoot);\n return computeNextCheckpointName(\n existing.map((c) => c.name),\n boxName,\n );\n}\n\nfunction chainDepth(box: BoxRecord): number {\n return box.checkpointSource?.chain.length ?? 0;\n}\n\n/** Quote a string for safe single-quoted embedding in a bash -lc script. */\nfunction shq(s: string): string {\n return `'${s.replace(/'/g, `'\\\\''`)}'`;\n}\n\nexport interface CreateCheckpointOptions {\n box: BoxRecord;\n projectRoot: string;\n name?: string;\n merged?: boolean;\n setDefault?: boolean;\n /** checkpoint.maxLayers — auto-merge when the source chain is at/over this. */\n maxLayers: number;\n onLog?: (line: string) => void;\n}\n\n/**\n * Capture a box's accumulated state as a project checkpoint, into a `<name>`\n * subdir of the per-project Docker volume.\n *\n * - `layered`: copy the box's overlay write delta (`/upper/upper`, which now\n * holds node_modules/build caches/env files) volume→volume in a throwaway\n * root container. The destination is ext4, so overlay char-device whiteouts\n * survive `cp -a` natively (no `.wh.` translation needed) and the copy\n * never crosses the VM↔host bridge.\n * - `merged`: tar the box's merged `/workspace` (everything) into the subdir,\n * used later as a single sole lower.\n *\n * Merged is chosen when `--merged` is passed or the source box's checkpoint\n * chain is already `>= maxLayers` deep (caps the lowerdir stack).\n */\nexport async function createCheckpoint(opts: CreateCheckpointOptions): Promise<CheckpointInfo> {\n const log = opts.onLog ?? (() => {});\n const { box } = opts;\n\n const type: CheckpointType =\n opts.merged === true || chainDepth(box) >= opts.maxLayers ? 'merged' : 'layered';\n const name = opts.name ?? (await nextCheckpointName(opts.projectRoot, box.name));\n const dir = checkpointDir(opts.projectRoot, name);\n if (await readManifest(dir)) {\n throw new CheckpointError(`checkpoint ${name} already exists (rm it first)`, '', '');\n }\n const volume = checkpointVolumeName(opts.projectRoot);\n await ensureVolume(volume);\n await mkdir(dir, { recursive: true });\n const qn = shq(name);\n\n if (type === 'layered') {\n log(`capturing upper delta of ${box.container} -> ${volume}/${name} (layered)`);\n // Volume→volume copy in a throwaway root container: all VM-local ext4, no\n // virtiofs bridge crossing, and overlay char-device whiteouts are\n // preserved as-is (fuse-overlayfs honors them in a lowerdir).\n const script = [\n 'set -u',\n `rm -rf /dst/${qn}`,\n `mkdir -p /dst/${qn}`,\n `cp -a /src/upper/. /dst/${qn}/ 2>/dev/null || true`,\n `ls -A /dst/${qn} >/dev/null`,\n ].join('\\n');\n const r = await execa(\n 'docker',\n [\n 'run',\n '--rm',\n '--user',\n '0:0',\n '-v',\n `${box.upperVolume}:/src:ro`,\n '-v',\n `${volume}:/dst`,\n box.image,\n 'bash',\n '-lc',\n script,\n ],\n { reject: false },\n );\n if (r.exitCode !== 0) {\n throw new CheckpointError(`failed to copy upper layer for ${box.name}`, r.stdout, r.stderr);\n }\n } else {\n log(`capturing merged /workspace of ${box.container} -> ${volume}/${name} (merged)`);\n const packed = await execa(\n 'docker',\n ['exec', '--user', 'root', box.container, 'tar', '-C', '/workspace', '-cf', '-', '.'],\n { reject: false, encoding: 'buffer' },\n );\n if (packed.exitCode !== 0) {\n throw new CheckpointError(\n `failed to tar merged /workspace for ${box.name} (is the box running?)`,\n '',\n typeof packed.stderr === 'string'\n ? packed.stderr\n : (packed.stderr as Buffer).toString('utf8'),\n );\n }\n const extract = await execa(\n 'docker',\n [\n 'run',\n '-i',\n '--rm',\n '--user',\n '0:0',\n '-v',\n `${volume}:/dst`,\n box.image,\n 'bash',\n '-lc',\n `set -u; rm -rf /dst/${qn}; mkdir -p /dst/${qn}; tar -xf - -C /dst/${qn}`,\n ],\n { input: packed.stdout as Buffer, reject: false },\n );\n if (extract.exitCode !== 0) {\n throw new CheckpointError(\n 'tar extract into checkpoint volume failed',\n extract.stdout,\n extract.stderr,\n );\n }\n }\n\n const base: 'worktree' | 'workspace' = (box.gitWorktrees ?? []).some((w) => w.kind === 'root')\n ? 'worktree'\n : 'workspace';\n const manifest: CheckpointManifest = {\n schema: 1,\n name,\n type,\n parents: type === 'layered' ? (box.checkpointSource?.chain ?? []) : [],\n base,\n sourceBoxId: box.id,\n sourceBoxName: box.name,\n volume,\n createdAt: new Date().toISOString(),\n };\n await writeFile(join(dir, 'manifest.json'), JSON.stringify(manifest, null, 2) + '\\n', 'utf8');\n\n if (opts.setDefault) {\n await setConfigValue('project', 'box.defaultCheckpoint', name, opts.projectRoot);\n log(`set project default checkpoint -> ${name}`);\n }\n\n return { name, dir, manifest };\n}\n\n/**\n * Resolve the lower spec a new box should stack when starting from checkpoint\n * `ref`. All layers in a chain live in the one per-project volume, so the box\n * mounts it once; `subpaths` are the per-layer subdir names (upper-most\n * first). For `layered` the caller appends the base lower after these; for\n * `merged` `subpaths` is the sole lower.\n */\nexport async function resolveCheckpointLower(\n projectRoot: string,\n ref: string,\n): Promise<CheckpointLowerSpec> {\n const head = await resolveCheckpoint(projectRoot, ref);\n if (!head) throw new CheckpointError(`checkpoint not found: ${ref}`, '', '');\n if (!head.manifest.volume) {\n throw new CheckpointError(\n `checkpoint ${ref} is a legacy host-dir checkpoint; recreate it`,\n '',\n '',\n );\n }\n const volume = head.manifest.volume;\n\n if (head.manifest.type === 'merged') {\n return { type: 'merged', volume, subpaths: [head.name], chain: [head.name] };\n }\n\n const subpaths = [head.name];\n const chain = [head.name];\n for (const parentRef of head.manifest.parents) {\n const p = await resolveCheckpoint(projectRoot, parentRef);\n if (!p) {\n throw new CheckpointError(\n `checkpoint ${ref} references missing parent ${parentRef}`,\n '',\n '',\n );\n }\n subpaths.push(p.name);\n chain.push(p.name);\n }\n return { type: 'layered', volume, subpaths, chain };\n}\n\nexport class CheckpointError extends Error {\n constructor(\n message: string,\n public readonly stdout: string,\n public readonly stderr: string,\n ) {\n super(`${message}${stderr ? `: ${stderr.trim()}` : ''}`);\n this.name = 'CheckpointError';\n }\n}\n","/**\n * Layered user config. The same shape is accepted at three layers:\n * - global ~/.agentbox/config.yaml\n * - project ~/.agentbox/projects/<hash>/config.yaml\n * - workspace defaults: block in ./agentbox.yaml\n *\n * Plus a CLI-flag layer at runtime. Precedence (highest wins):\n * cli > workspace > project > global > built-in defaults.\n */\n\nexport type IdeFlavor = 'vscode' | 'cursor' | 'auto';\nexport type EngineKind = 'orbstack' | 'docker-desktop' | 'other' | 'auto';\nexport type BrowserKind = 'agent-browser' | 'playwright' | 'both';\n\nexport interface UserConfig {\n box?: {\n hostSnapshot?: boolean;\n defaultCheckpoint?: string;\n withPlaywright?: boolean;\n withEnv?: boolean;\n vnc?: boolean;\n isolateClaudeConfig?: boolean;\n image?: string;\n dockerCacheShared?: boolean;\n memory?: number;\n cpus?: number;\n pidsLimit?: number;\n disk?: string;\n };\n checkpoint?: {\n maxLayers?: number;\n };\n claude?: {\n sessionName?: string;\n };\n code?: {\n ide?: IdeFlavor;\n wait?: boolean;\n timeoutMs?: number;\n autoTerminals?: boolean;\n };\n shell?: {\n user?: string;\n login?: boolean;\n };\n engine?: {\n kind?: EngineKind;\n };\n browser?: {\n default?: BrowserKind;\n };\n relay?: {\n port?: number;\n };\n vnc?: {\n containerPort?: number;\n };\n autopause?: {\n enabled?: boolean;\n maxRunningBoxes?: number;\n idleMinutes?: number;\n };\n maintenance?: {\n pruneProjectConfigs?: boolean;\n pruneProjectConfigsEvery?: number;\n };\n}\n\n/**\n * Required-everywhere variant returned as the merged effective config. Each\n * leaf is filled from BUILT_IN_DEFAULTS when no layer set it.\n *\n * `box.hostSnapshot` is intentionally `boolean | undefined` (unprompted): the\n * default is \"ask the user\", expressed as undefined.\n */\nexport interface EffectiveConfig {\n box: {\n hostSnapshot: boolean | undefined;\n defaultCheckpoint: string;\n withPlaywright: boolean;\n withEnv: boolean;\n vnc: boolean;\n isolateClaudeConfig: boolean;\n image: string;\n dockerCacheShared: boolean;\n memory: number;\n cpus: number;\n pidsLimit: number;\n disk: string;\n };\n checkpoint: {\n maxLayers: number;\n };\n claude: {\n sessionName: string;\n };\n code: {\n ide: IdeFlavor;\n wait: boolean;\n timeoutMs: number;\n autoTerminals: boolean;\n };\n shell: {\n user: string;\n login: boolean;\n };\n engine: {\n kind: EngineKind;\n };\n browser: {\n default: BrowserKind;\n };\n relay: {\n port: number;\n };\n vnc: {\n containerPort: number;\n };\n autopause: {\n enabled: boolean;\n maxRunningBoxes: number;\n idleMinutes: number;\n };\n maintenance: {\n pruneProjectConfigs: boolean;\n pruneProjectConfigsEvery: number;\n };\n}\n\nexport type ConfigSource = 'cli' | 'workspace' | 'project' | 'global' | 'default';\n\nexport interface ConfigLayer {\n source: ConfigSource;\n /** File path the layer was loaded from. Absent for `cli` and `default`. */\n path?: string;\n values: Partial<UserConfig>;\n}\n\nexport interface LoadedConfig {\n effective: EffectiveConfig;\n layers: {\n cli: { values: Partial<UserConfig> };\n workspace: { path: string | null; values: Partial<UserConfig> };\n project: { path: string; values: Partial<UserConfig> };\n global: { path: string; values: Partial<UserConfig> };\n defaults: EffectiveConfig;\n };\n /** Per-leaf source map: 'box.hostSnapshot' -> 'workspace'. Powers `config get --all`. */\n sources: Record<string, ConfigSource>;\n /** Resolved project root used for the project layer (cwd if no agentbox.yaml found). */\n projectRoot: string;\n projectHash: string;\n /** True if we walked up to an agentbox.yaml; false if we fell back to cwd. */\n hasAgentboxYaml: boolean;\n}\n\nexport const BUILT_IN_DEFAULTS: EffectiveConfig = {\n box: {\n hostSnapshot: undefined,\n defaultCheckpoint: '',\n withPlaywright: false,\n withEnv: false,\n vnc: true,\n isolateClaudeConfig: false,\n image: 'agentbox/box:dev',\n dockerCacheShared: false,\n memory: 0,\n cpus: 0,\n pidsLimit: 0,\n disk: '',\n },\n checkpoint: {\n maxLayers: 3,\n },\n claude: {\n sessionName: 'claude',\n },\n code: {\n ide: 'auto',\n wait: true,\n timeoutMs: 120_000,\n autoTerminals: true,\n },\n shell: {\n user: 'vscode',\n login: true,\n },\n engine: {\n kind: 'auto',\n },\n browser: {\n default: 'agent-browser',\n },\n relay: {\n port: 8787,\n },\n vnc: {\n containerPort: 6080,\n },\n autopause: {\n enabled: true,\n maxRunningBoxes: 5,\n idleMinutes: 5,\n },\n maintenance: {\n pruneProjectConfigs: true,\n pruneProjectConfigsEvery: 50,\n },\n};\n\nexport type KeyType = 'bool' | 'string' | 'int' | 'enum';\n\nexport interface KeyDescriptor {\n /** Dot-path, e.g. \"box.snapshot\". */\n key: string;\n type: KeyType;\n enumValues?: readonly string[];\n description: string;\n /** True for keys most users shouldn't touch (image, ports). Hidden from `list` by default. */\n advanced?: boolean;\n}\n\n/**\n * Single source of truth for which keys are addressable from the CLI. The\n * parser, `set`/`unset`, and `list` all walk this. Adding a key here is the\n * one place a new field has to be registered (plus the type interface above\n * and the JSON schema).\n */\nexport const KEY_REGISTRY: readonly KeyDescriptor[] = [\n {\n key: 'box.hostSnapshot',\n type: 'bool',\n description:\n 'Use a frozen APFS clone of the host workspace as the overlay lower (default: prompt). Was box.snapshot.',\n },\n {\n key: 'box.defaultCheckpoint',\n type: 'string',\n description:\n 'Checkpoint ref new boxes in this project start from when --snapshot is not given (set via `agentbox checkpoint set-default`).',\n },\n {\n key: 'checkpoint.maxLayers',\n type: 'int',\n description:\n 'Max stacked checkpoint layers before a new checkpoint is materialized merged (flattened) instead of layered.',\n advanced: true,\n },\n {\n key: 'box.withPlaywright',\n type: 'bool',\n description: 'Install @playwright/cli@latest in the box at create time.',\n },\n {\n key: 'box.withEnv',\n type: 'bool',\n description:\n 'Copy host env/config files (.env*, secrets.toml, agentbox.yaml, ...) into /workspace at box create time (gitignore-bypassing).',\n },\n {\n key: 'box.vnc',\n type: 'bool',\n description: 'Run the per-box Xvnc + noVNC stack.',\n },\n {\n key: 'box.isolateClaudeConfig',\n type: 'bool',\n description: 'Use a per-box ~/.claude volume instead of the shared one.',\n },\n {\n key: 'box.image',\n type: 'string',\n description: 'Box image ref (advanced).',\n advanced: true,\n },\n {\n key: 'box.dockerCacheShared',\n type: 'bool',\n description:\n \"Share the in-box docker image cache across boxes via the 'agentbox-docker-cache' volume (preserved on destroy/prune; only one box can run at a time when set).\",\n },\n {\n key: 'box.memory',\n type: 'int',\n description:\n 'Hard memory ceiling in MiB for new boxes (0 = unlimited). Use --memory on create/claude for byte/k/m/g strings.',\n },\n {\n key: 'box.cpus',\n type: 'int',\n description:\n 'CPU count cap for new boxes (0 = unlimited). Whole cores via config; use --cpus for fractional (e.g. 1.5).',\n },\n {\n key: 'box.pidsLimit',\n type: 'int',\n description: 'Max process count (PIDs cgroup) for new boxes (0 = unlimited).',\n },\n {\n key: 'box.disk',\n type: 'string',\n description:\n \"Best-effort writable-layer size for new boxes, e.g. '10G'. No-op on overlay2 / the macOS engines.\",\n advanced: true,\n },\n {\n key: 'claude.sessionName',\n type: 'string',\n description: 'tmux session name for `agentbox claude`.',\n },\n {\n key: 'code.ide',\n type: 'enum',\n enumValues: ['vscode', 'cursor', 'auto'] as const,\n description: 'Which IDE `agentbox code` launches; \"auto\" prefers code, falls back to cursor.',\n },\n {\n key: 'code.wait',\n type: 'bool',\n description: 'Block on agentbox-ctl wait-ready before opening the IDE.',\n },\n {\n key: 'code.timeoutMs',\n type: 'int',\n description: 'wait-ready timeout in milliseconds.',\n },\n {\n key: 'code.autoTerminals',\n type: 'bool',\n description: 'Generate /workspace/.vscode/tasks.json so the IDE auto-opens log panels.',\n },\n {\n key: 'shell.user',\n type: 'string',\n description: 'Default in-container user for `agentbox shell`.',\n },\n {\n key: 'shell.login',\n type: 'bool',\n description: 'Pass `-l` to bash so the login profile loads.',\n },\n {\n key: 'engine.kind',\n type: 'enum',\n enumValues: ['orbstack', 'docker-desktop', 'other', 'auto'] as const,\n description: 'Override the docker-engine auto-detection (used for OrbStack-only optimisations).',\n },\n {\n key: 'browser.default',\n type: 'enum',\n enumValues: ['agent-browser', 'playwright', 'both'] as const,\n description: 'Default browser stack inside the box. \"playwright\" or \"both\" implies box.withPlaywright.',\n },\n {\n key: 'relay.port',\n type: 'int',\n description: 'Host relay TCP port (advanced).',\n advanced: true,\n },\n {\n key: 'vnc.containerPort',\n type: 'int',\n description: 'Container-side noVNC port (advanced).',\n advanced: true,\n },\n {\n key: 'autopause.enabled',\n type: 'bool',\n description:\n 'Let the host relay periodically pause idle boxes when more than autopause.maxRunningBoxes are running.',\n },\n {\n key: 'autopause.maxRunningBoxes',\n type: 'int',\n description:\n 'Target maximum number of simultaneously-running boxes before idle ones get auto-paused.',\n },\n {\n key: 'autopause.idleMinutes',\n type: 'int',\n description:\n 'Minutes a box must be continuously idle (claude state) before it is eligible for auto-pause.',\n },\n {\n key: 'maintenance.pruneProjectConfigs',\n type: 'bool',\n description:\n 'Periodically delete ~/.agentbox/projects/<hash>/ dirs whose source workspace folder no longer exists.',\n },\n {\n key: 'maintenance.pruneProjectConfigsEvery',\n type: 'int',\n description: 'Run the orphan project-config sweep every N successful `agentbox create`.',\n },\n];\n\nconst REGISTRY_BY_KEY = new Map<string, KeyDescriptor>(KEY_REGISTRY.map((d) => [d.key, d]));\n\nexport function lookupKey(key: string): KeyDescriptor | undefined {\n return REGISTRY_BY_KEY.get(key);\n}\n\nexport class UserConfigError extends Error {\n constructor(message: string) {\n super(message);\n this.name = 'UserConfigError';\n }\n}\n\nexport type ConfigScope = 'global' | 'project';\n","import { parse as parseYaml } from 'yaml';\nimport {\n KEY_REGISTRY,\n type KeyDescriptor,\n type UserConfig,\n UserConfigError,\n} from './types.js';\n\nfunction isPlainObject(v: unknown): v is Record<string, unknown> {\n return typeof v === 'object' && v !== null && !Array.isArray(v);\n}\n\n/** Keys removed in a rename. Surfaced with a migration hint instead of a bare \"unknown key\". */\nconst RENAMED_KEYS: ReadonlyMap<string, string> = new Map([['box.snapshot', 'box.hostSnapshot']]);\n\ninterface BranchSpec {\n name: string;\n /** Map of leaf-key (dot-suffix) → descriptor whose `key` starts with this branch. */\n leaves: Map<string, KeyDescriptor>;\n}\n\nconst BRANCHES: Map<string, BranchSpec> = (() => {\n const out = new Map<string, BranchSpec>();\n for (const desc of KEY_REGISTRY) {\n const idx = desc.key.indexOf('.');\n if (idx < 0) {\n throw new Error(`KEY_REGISTRY entry ${desc.key} must use dot-path form (branch.leaf)`);\n }\n const branch = desc.key.slice(0, idx);\n const leaf = desc.key.slice(idx + 1);\n let entry = out.get(branch);\n if (!entry) {\n entry = { name: branch, leaves: new Map() };\n out.set(branch, entry);\n }\n entry.leaves.set(leaf, desc);\n }\n return out;\n})();\n\n/**\n * Coerce a typed YAML scalar (already typed by the YAML parser) into the\n * descriptor's expected type. Strings from the CLI go through `coerceFromString`\n * instead — that path accepts e.g. \"true\" or \"120000\".\n */\nfunction coerceTypedValue(raw: unknown, desc: KeyDescriptor, where: string): unknown {\n if (raw === null) {\n throw new UserConfigError(`${where} must not be null (use \\`agentbox config unset\\` to clear)`);\n }\n switch (desc.type) {\n case 'bool':\n if (typeof raw !== 'boolean') {\n throw new UserConfigError(`${where} must be a boolean (got ${typeof raw})`);\n }\n return raw;\n case 'string':\n if (typeof raw !== 'string') {\n throw new UserConfigError(`${where} must be a string (got ${typeof raw})`);\n }\n if (raw.length === 0) {\n throw new UserConfigError(`${where} must not be empty`);\n }\n return raw;\n case 'int':\n if (typeof raw !== 'number' || !Number.isInteger(raw)) {\n throw new UserConfigError(`${where} must be an integer (got ${String(raw)})`);\n }\n return raw;\n case 'enum':\n if (typeof raw !== 'string' || !desc.enumValues!.includes(raw)) {\n throw new UserConfigError(\n `${where} must be one of: ${desc.enumValues!.join(', ')} (got ${String(raw)})`,\n );\n }\n return raw;\n }\n}\n\n/**\n * Parse a UserConfig document text (YAML). Strict: unknown branches and\n * unknown leaves throw UserConfigError so typos surface early.\n *\n * `where` is the human-readable origin for error messages, e.g. the file path.\n * Empty / whitespace-only input parses to `{}`.\n */\nexport function parseUserConfig(text: string, where: string): Partial<UserConfig> {\n let doc: unknown;\n try {\n doc = parseYaml(text);\n } catch (err) {\n throw new UserConfigError(\n `${where}: yaml parse error: ${err instanceof Error ? err.message : String(err)}`,\n );\n }\n if (doc === null || doc === undefined) return {};\n if (!isPlainObject(doc)) {\n throw new UserConfigError(`${where}: top-level must be a mapping`);\n }\n return parseUserConfigObject(doc, where);\n}\n\n/**\n * Same validation as `parseUserConfig` but starting from an already-decoded\n * object. Used when the caller has the YAML parsed (e.g. agentbox.yaml's\n * `defaults:` block).\n */\nexport function parseUserConfigObject(doc: unknown, where: string): Partial<UserConfig> {\n if (doc === null || doc === undefined) return {};\n if (!isPlainObject(doc)) {\n throw new UserConfigError(`${where}: must be a mapping`);\n }\n\n const out: Partial<UserConfig> = {};\n for (const [branchName, branchRaw] of Object.entries(doc)) {\n const branchSpec = BRANCHES.get(branchName);\n if (!branchSpec) {\n throw new UserConfigError(\n `${where}: unknown config section \"${branchName}\" (known: ${[...BRANCHES.keys()].join(', ')})`,\n );\n }\n if (branchRaw === null || branchRaw === undefined) continue;\n if (!isPlainObject(branchRaw)) {\n throw new UserConfigError(`${where}.${branchName}: must be a mapping`);\n }\n const branchOut: Record<string, unknown> = {};\n for (const [leafName, leafRaw] of Object.entries(branchRaw)) {\n const desc = branchSpec.leaves.get(leafName);\n if (!desc) {\n const renamedTo = RENAMED_KEYS.get(`${branchName}.${leafName}`);\n if (renamedTo) {\n throw new UserConfigError(\n `${where}.${branchName}.${leafName} was renamed to ${renamedTo} — update your config`,\n );\n }\n throw new UserConfigError(\n `${where}.${branchName}: unknown key \"${leafName}\" (known: ${[...branchSpec.leaves.keys()].join(', ')})`,\n );\n }\n if (leafRaw === undefined) continue;\n branchOut[leafName] = coerceTypedValue(leafRaw, desc, `${where}.${desc.key}`);\n }\n if (Object.keys(branchOut).length > 0) {\n // We've validated that each branch matches one of UserConfig's known\n // sub-objects; the indexed write keeps the union type happy.\n (out as Record<string, unknown>)[branchName] = branchOut;\n }\n }\n return out;\n}\n\n/**\n * Coerce a string (e.g. typed at the CLI by `agentbox config set`) into the\n * declared type for `key`. Booleans accept true/false/yes/no/1/0 (case\n * insensitive). Returns the typed value or throws UserConfigError.\n */\nexport function coerceFromString(key: string, raw: string): unknown {\n const desc = lookupKeyOrThrow(key);\n switch (desc.type) {\n case 'bool': {\n const v = raw.trim().toLowerCase();\n if (v === 'true' || v === 'yes' || v === '1' || v === 'on') return true;\n if (v === 'false' || v === 'no' || v === '0' || v === 'off') return false;\n throw new UserConfigError(`${key}: expected a boolean (true/false), got \"${raw}\"`);\n }\n case 'string':\n if (raw.length === 0) throw new UserConfigError(`${key}: must not be empty`);\n return raw;\n case 'int': {\n const n = Number(raw);\n if (!Number.isFinite(n) || !Number.isInteger(n)) {\n throw new UserConfigError(`${key}: expected an integer, got \"${raw}\"`);\n }\n return n;\n }\n case 'enum':\n if (!desc.enumValues!.includes(raw)) {\n throw new UserConfigError(\n `${key}: expected one of ${desc.enumValues!.join(', ')}, got \"${raw}\"`,\n );\n }\n return raw;\n }\n}\n\nfunction lookupKeyOrThrow(key: string): KeyDescriptor {\n const renamedTo = RENAMED_KEYS.get(key);\n if (renamedTo) {\n throw new UserConfigError(`${key} was renamed to ${renamedTo} — use ${renamedTo} instead`);\n }\n const idx = key.indexOf('.');\n if (idx < 0) {\n throw new UserConfigError(`unknown key \"${key}\" (must be in branch.leaf form)`);\n }\n const branch = BRANCHES.get(key.slice(0, idx));\n if (!branch) {\n throw new UserConfigError(\n `unknown config section \"${key.slice(0, idx)}\" (known: ${[...BRANCHES.keys()].join(', ')})`,\n );\n }\n const desc = branch.leaves.get(key.slice(idx + 1));\n if (!desc) {\n throw new UserConfigError(\n `unknown key \"${key}\" (known in ${branch.name}: ${[...branch.leaves.keys()].join(', ')})`,\n );\n }\n return desc;\n}\n","import { createHash } from 'node:crypto';\nimport { realpath, stat } from 'node:fs/promises';\nimport { homedir } from 'node:os';\nimport { dirname, join, resolve } from 'node:path';\nimport type { ConfigScope } from './types.js';\n\nexport const STATE_DIR = join(homedir(), '.agentbox');\nexport const GLOBAL_CONFIG_FILE = join(STATE_DIR, 'config.yaml');\nexport const PROJECTS_DIR = join(STATE_DIR, 'projects');\nexport const WORKSPACE_CONFIG_BASENAME = 'agentbox.yaml';\n\nexport interface ProjectRoot {\n /** Absolute path to the resolved project root (host filesystem). */\n root: string;\n hasAgentboxYaml: boolean;\n}\n\n/**\n * Walk up from `cwd` until we find an `agentbox.yaml`. That dir is the\n * \"project\". If no ancestor has one, we fall back to `cwd` (per spec) so\n * `agentbox config` still does something sane in dirs without a workspace\n * file. The returned path is always absolute and **symlink-canonicalised**\n * via `realpath` — without this, macOS's `/tmp` symlink to `/private/tmp`\n * makes `findProjectRoot('/tmp/x')` (at create time, --workspace) and\n * `findProjectRoot(process.cwd())` (at resolve time, the same dir) return\n * different roots, breaking the per-project box index match.\n */\nexport async function findProjectRoot(cwd: string): Promise<ProjectRoot> {\n const start = await canonicalize(cwd);\n let dir = start;\n // Defensive cap on iterations: filesystem roots end with `dirname(x) === x`.\n for (let i = 0; i < 64; i++) {\n if (await fileExists(join(dir, WORKSPACE_CONFIG_BASENAME))) {\n return { root: dir, hasAgentboxYaml: true };\n }\n const parent = dirname(dir);\n if (parent === dir) break;\n dir = parent;\n }\n return { root: start, hasAgentboxYaml: false };\n}\n\nasync function canonicalize(p: string): Promise<string> {\n const abs = resolve(p);\n // realpath only works for paths that exist. cwd and create-time\n // workspaces always do; fall back to the resolved (non-canonicalised)\n // path for anything else (e.g. config get from a deleted dir).\n try {\n return await realpath(abs);\n } catch {\n return abs;\n }\n}\n\nasync function fileExists(p: string): Promise<boolean> {\n try {\n const st = await stat(p);\n return st.isFile();\n } catch {\n return false;\n }\n}\n\n/**\n * SHA-1 (first 16 hex chars) of the *normalised* absolute path. We strip a\n * single trailing slash so `/foo/` and `/foo` hash identically. Case is\n * preserved — macOS APFS is case-preserving and so is the user's intent.\n */\nexport function hashProjectPath(absPath: string): string {\n const normalised = absPath.length > 1 && absPath.endsWith('/')\n ? absPath.slice(0, -1)\n : absPath;\n return createHash('sha1').update(normalised).digest('hex').slice(0, 16);\n}\n\nexport function projectConfigDir(absPath: string): string {\n return join(PROJECTS_DIR, hashProjectPath(absPath));\n}\n\nexport function projectConfigFile(absPath: string): string {\n return join(projectConfigDir(absPath), 'config.yaml');\n}\n\nexport function projectMetaFile(absPath: string): string {\n return join(projectConfigDir(absPath), 'meta.json');\n}\n\nexport function workspaceConfigFile(workspacePath: string): string {\n return join(workspacePath, WORKSPACE_CONFIG_BASENAME);\n}\n\n/**\n * Resolve a file path for a given scope. For `global`, no cwd is needed;\n * for `project`, `cwd` selects which project hash. Workspace path uses the\n * resolved project root (the dir holding `agentbox.yaml`, or cwd as fallback).\n */\nexport async function configPathFor(\n scope: ConfigScope | 'workspace',\n cwd: string,\n): Promise<string> {\n if (scope === 'global') return GLOBAL_CONFIG_FILE;\n const root = await findProjectRoot(cwd);\n if (scope === 'project') return projectConfigFile(root.root);\n return workspaceConfigFile(root.root);\n}\n","import { readFile } from 'node:fs/promises';\nimport { parse as parseYaml } from 'yaml';\nimport {\n findProjectRoot,\n GLOBAL_CONFIG_FILE,\n hashProjectPath,\n projectConfigFile,\n workspaceConfigFile,\n} from './paths.js';\nimport { parseUserConfig, parseUserConfigObject } from './parse.js';\nimport {\n BUILT_IN_DEFAULTS,\n type ConfigSource,\n type EffectiveConfig,\n KEY_REGISTRY,\n type LoadedConfig,\n type UserConfig,\n} from './types.js';\n\n/**\n * ENOENT-tolerant read of a UserConfig file. Anything else propagates.\n */\nasync function loadOptionalUserConfig(path: string): Promise<Partial<UserConfig>> {\n let text: string;\n try {\n text = await readFile(path, 'utf8');\n } catch (err) {\n if ((err as NodeJS.ErrnoException).code === 'ENOENT') return {};\n throw err;\n }\n return parseUserConfig(text, path);\n}\n\n/**\n * Read the `defaults:` block from `<workspacePath>/agentbox.yaml`. Returns\n * `{}` if the file is missing or has no `defaults:` key. Throws on YAML\n * parse errors or invalid `defaults:` content (so typos surface as soon as\n * the user runs anything in the workspace).\n *\n * The rest of `agentbox.yaml` is owned by `@agentbox/ctl` — we don't validate\n * it here and we don't depend on that package.\n */\nexport async function loadProjectAgentboxDefaults(\n workspacePath: string,\n): Promise<Partial<UserConfig>> {\n const path = workspaceConfigFile(workspacePath);\n let text: string;\n try {\n text = await readFile(path, 'utf8');\n } catch (err) {\n if ((err as NodeJS.ErrnoException).code === 'ENOENT') return {};\n throw err;\n }\n let doc: unknown;\n try {\n doc = parseYaml(text);\n } catch {\n // The ctl parser will surface its own error on the next box action; we\n // only throw if defaults: is present and broken (validated below).\n return {};\n }\n if (doc === null || doc === undefined || typeof doc !== 'object' || Array.isArray(doc)) {\n return {};\n }\n const defaults = (doc as Record<string, unknown>)['defaults'];\n if (defaults === undefined || defaults === null) return {};\n return parseUserConfigObject(defaults, `${path} defaults`);\n}\n\nexport interface LoadEffectiveConfigOptions {\n /** Highest-precedence layer; values supplied by command-line flags. */\n cliOverrides?: Partial<UserConfig>;\n}\n\n/**\n * Load and merge all four config sources for the cwd. Per-leaf precedence\n * (highest wins): cli > workspace > project > global > built-in defaults.\n *\n * The returned `sources` map has one entry per leaf in the registry — useful\n * for `agentbox config get --all` to show provenance.\n */\nexport async function loadEffectiveConfig(\n cwd: string,\n opts: LoadEffectiveConfigOptions = {},\n): Promise<LoadedConfig> {\n const projectRoot = await findProjectRoot(cwd);\n const projectPath = projectConfigFile(projectRoot.root);\n const workspacePath = projectRoot.hasAgentboxYaml ? workspaceConfigFile(projectRoot.root) : null;\n\n const [globalValues, projectValues, workspaceValues] = await Promise.all([\n loadOptionalUserConfig(GLOBAL_CONFIG_FILE),\n loadOptionalUserConfig(projectPath),\n workspacePath ? loadProjectAgentboxDefaults(projectRoot.root) : Promise.resolve({}),\n ]);\n\n const cliValues = opts.cliOverrides ?? {};\n\n const { effective, sources } = mergeLayers({\n cli: cliValues,\n workspace: workspaceValues,\n project: projectValues,\n global: globalValues,\n });\n\n return {\n effective,\n layers: {\n cli: { values: cliValues },\n workspace: { path: workspacePath, values: workspaceValues },\n project: { path: projectPath, values: projectValues },\n global: { path: GLOBAL_CONFIG_FILE, values: globalValues },\n defaults: BUILT_IN_DEFAULTS,\n },\n sources,\n projectRoot: projectRoot.root,\n projectHash: hashProjectPath(projectRoot.root),\n hasAgentboxYaml: projectRoot.hasAgentboxYaml,\n };\n}\n\ninterface MergeInput {\n cli: Partial<UserConfig>;\n workspace: Partial<UserConfig>;\n project: Partial<UserConfig>;\n global: Partial<UserConfig>;\n}\n\n/**\n * Walk every key in KEY_REGISTRY, pick the highest-precedence layer that has\n * a leaf value, and record the source. Lower-precedence layers never\n * overwrite a higher-precedence definition; absent leaves don't shadow.\n */\nfunction mergeLayers(input: MergeInput): {\n effective: EffectiveConfig;\n sources: Record<string, ConfigSource>;\n} {\n // Deep-clone the defaults; we'll overwrite leaves in place.\n const effective: EffectiveConfig = JSON.parse(JSON.stringify(BUILT_IN_DEFAULTS)) as EffectiveConfig;\n const sources: Record<string, ConfigSource> = {};\n\n const layerOrder: Array<{ source: ConfigSource; values: Partial<UserConfig> }> = [\n { source: 'cli', values: input.cli },\n { source: 'workspace', values: input.workspace },\n { source: 'project', values: input.project },\n { source: 'global', values: input.global },\n ];\n\n for (const desc of KEY_REGISTRY) {\n const idx = desc.key.indexOf('.');\n const branch = desc.key.slice(0, idx);\n const leaf = desc.key.slice(idx + 1);\n\n let chosen: { source: ConfigSource; value: unknown } | null = null;\n for (const layer of layerOrder) {\n const v = readLeaf(layer.values, branch, leaf);\n if (v !== undefined) {\n chosen = { source: layer.source, value: v };\n break;\n }\n }\n\n if (chosen) {\n writeLeaf(effective, branch, leaf, chosen.value);\n sources[desc.key] = chosen.source;\n } else {\n sources[desc.key] = 'default';\n }\n }\n\n return { effective, sources };\n}\n\nfunction readLeaf(\n obj: Partial<UserConfig>,\n branch: string,\n leaf: string,\n): unknown {\n const b = (obj as Record<string, unknown>)[branch];\n if (b === undefined || b === null || typeof b !== 'object') return undefined;\n return (b as Record<string, unknown>)[leaf];\n}\n\nfunction writeLeaf(\n obj: EffectiveConfig,\n branch: string,\n leaf: string,\n value: unknown,\n): void {\n const b = (obj as unknown as Record<string, Record<string, unknown>>)[branch];\n if (!b) return; // BUILT_IN_DEFAULTS guarantees the branch exists\n b[leaf] = value;\n}\n","import { mkdir, readFile, rename, rm, stat, writeFile } from 'node:fs/promises';\nimport { dirname, isAbsolute, join } from 'node:path';\nimport { stringify as stringifyYaml } from 'yaml';\nimport {\n configPathFor,\n findProjectRoot,\n hashProjectPath,\n PROJECTS_DIR,\n projectConfigFile,\n projectMetaFile,\n} from './paths.js';\nimport { coerceFromString, parseUserConfig } from './parse.js';\nimport { type ConfigScope, lookupKey, type UserConfig, UserConfigError } from './types.js';\nimport { readdir } from 'node:fs/promises';\n\ninterface WriteResult {\n path: string;\n /** The value we coerced and stored, after string→typed conversion. */\n coerced: unknown;\n}\n\ninterface SetOptions {\n /**\n * When true (the CLI `set` path), accept a string and coerce. When false\n * (programmatic), accept any typed value and write it through after a\n * round-trip parse for validation.\n */\n raw?: boolean;\n}\n\n/**\n * Write a single key into the chosen scope's config file. Creates parent\n * dirs and (for project scope) the meta.json sidecar. Atomic via tmp-rename.\n */\nexport async function setConfigValue(\n scope: ConfigScope,\n key: string,\n value: unknown,\n cwd: string,\n opts: SetOptions = {},\n): Promise<WriteResult> {\n if (!lookupKey(key)) {\n throw new UserConfigError(`unknown key \"${key}\"`);\n }\n\n const coerced = opts.raw && typeof value === 'string'\n ? coerceFromString(key, value)\n : value;\n\n const path = await configPathFor(scope, cwd);\n const current = await readExistingDoc(path);\n setLeaf(current, key, coerced);\n // Re-parse to validate the merged document; any change that produces an\n // invalid file (shouldn't be possible here, but defence-in-depth) throws.\n parseUserConfig(stringifyYaml(current), path);\n await atomicWriteYaml(path, current);\n\n if (scope === 'project') {\n const root = (await findProjectRoot(cwd)).root;\n await touchProjectMeta(root);\n }\n\n return { path, coerced };\n}\n\n/**\n * Remove a key from the chosen scope's config file. Empty parent objects are\n * pruned so the file stays tidy. ENOENT is treated as success.\n */\nexport async function unsetConfigValue(\n scope: ConfigScope,\n key: string,\n cwd: string,\n): Promise<{ path: string; existed: boolean }> {\n if (!lookupKey(key)) {\n throw new UserConfigError(`unknown key \"${key}\"`);\n }\n const path = await configPathFor(scope, cwd);\n const current = await readExistingDoc(path);\n const existed = unsetLeaf(current, key);\n if (!existed) return { path, existed: false };\n await atomicWriteYaml(path, current);\n if (scope === 'project') {\n const root = (await findProjectRoot(cwd)).root;\n await touchProjectMeta(root);\n }\n return { path, existed: true };\n}\n\ninterface ProjectEntry {\n hash: string;\n originalPath: string;\n createdAt: string | null;\n lastSeenAt: string | null;\n configPath: string;\n hasConfigFile: boolean;\n}\n\n/**\n * Enumerate per-project config dirs. The meta.json's recorded\n * `originalPath` is what we report — the hash on disk is opaque.\n */\nexport async function listProjectsConfigured(): Promise<ProjectEntry[]> {\n let entries: string[];\n try {\n entries = await readdir(PROJECTS_DIR);\n } catch (err) {\n if ((err as NodeJS.ErrnoException).code === 'ENOENT') return [];\n throw err;\n }\n const out: ProjectEntry[] = [];\n for (const hash of entries) {\n if (!/^[0-9a-f]{16}$/.test(hash)) continue;\n const meta = await readMeta(hash);\n if (!meta) continue;\n const cfgPath = projectConfigFile(meta.originalPath);\n const hasConfig = await fileExists(cfgPath);\n out.push({\n hash,\n originalPath: meta.originalPath,\n createdAt: meta.createdAt,\n lastSeenAt: meta.lastSeenAt,\n configPath: cfgPath,\n hasConfigFile: hasConfig,\n });\n }\n out.sort((a, b) => a.originalPath.localeCompare(b.originalPath));\n return out;\n}\n\nexport interface PruneOrphanProjectConfigsOptions {\n dryRun?: boolean;\n /** Absolute project roots of live boxes — kept even if the folder is gone. */\n protectedPaths?: string[];\n}\n\nexport interface PruneOrphanProjectConfigsResult {\n removed: { hash: string; originalPath: string }[];\n dryRun: boolean;\n}\n\n/**\n * Delete `~/.agentbox/projects/<hash>/` dirs whose recorded `originalPath`\n * workspace folder no longer exists on disk. Conservative by construction:\n * only an ENOENT on `originalPath` counts as orphaned (a transient/permission\n * error is never treated as \"deleted\"), and any path in `protectedPaths` (the\n * project roots of still-live boxes) is left alone. Best-effort and\n * idempotent — a failed `rm` is swallowed.\n */\nexport async function pruneOrphanProjectConfigs(\n opts: PruneOrphanProjectConfigsOptions = {},\n): Promise<PruneOrphanProjectConfigsResult> {\n const dryRun = opts.dryRun ?? false;\n const keep = new Set(opts.protectedPaths ?? []);\n const removed: { hash: string; originalPath: string }[] = [];\n for (const entry of await listProjectsConfigured()) {\n if (!isAbsolute(entry.originalPath) || keep.has(entry.originalPath)) continue;\n let missing = false;\n try {\n await stat(entry.originalPath);\n } catch (err) {\n if ((err as NodeJS.ErrnoException).code === 'ENOENT') missing = true;\n }\n if (!missing) continue;\n removed.push({ hash: entry.hash, originalPath: entry.originalPath });\n if (!dryRun) {\n try {\n // Remove by the on-disk hash dir name (originalPath is gone, so\n // recomputing the hash from it would be pointless).\n await rm(join(PROJECTS_DIR, entry.hash), { recursive: true, force: true });\n } catch {\n /* best-effort */\n }\n }\n }\n return { removed, dryRun };\n}\n\n/**\n * Sidecar counter for the periodic create-time sweep. Lives inside\n * `PROJECTS_DIR` but `listProjectsConfigured` only reads 16-hex-named dirs, so\n * a dotfile here is invisible to it.\n */\nconst PROJECT_GC_COUNTER_FILE = join(PROJECTS_DIR, '.gc.json');\n\n/** Read `{creates}` (0 if missing/corrupt), increment, atomic-write, return new value. */\nexport async function bumpProjectGcCounter(): Promise<number> {\n let prior = 0;\n try {\n const parsed = JSON.parse(await readFile(PROJECT_GC_COUNTER_FILE, 'utf8')) as {\n creates?: unknown;\n };\n if (typeof parsed.creates === 'number' && Number.isFinite(parsed.creates)) {\n prior = parsed.creates;\n }\n } catch {\n /* missing or corrupt -> start from 0 */\n }\n const next = prior + 1;\n await mkdir(PROJECTS_DIR, { recursive: true });\n const tmp = `${PROJECT_GC_COUNTER_FILE}.tmp-${process.pid.toString()}-${Date.now().toString(36)}`;\n await writeFile(tmp, JSON.stringify({ creates: next }) + '\\n', { encoding: 'utf8', mode: 0o644 });\n await rename(tmp, PROJECT_GC_COUNTER_FILE);\n return next;\n}\n\nasync function readMeta(\n hash: string,\n): Promise<{ originalPath: string; createdAt: string | null; lastSeenAt: string | null } | null> {\n const metaPath = `${PROJECTS_DIR}/${hash}/meta.json`;\n try {\n const text = await readFile(metaPath, 'utf8');\n const parsed = JSON.parse(text) as Record<string, unknown>;\n if (typeof parsed['originalPath'] !== 'string') return null;\n return {\n originalPath: parsed['originalPath'],\n createdAt: typeof parsed['createdAt'] === 'string' ? parsed['createdAt'] : null,\n lastSeenAt: typeof parsed['lastSeenAt'] === 'string' ? parsed['lastSeenAt'] : null,\n };\n } catch {\n return null;\n }\n}\n\nasync function fileExists(p: string): Promise<boolean> {\n try {\n const st = await stat(p);\n return st.isFile();\n } catch {\n return false;\n }\n}\n\nasync function readExistingDoc(path: string): Promise<Partial<UserConfig>> {\n let text: string;\n try {\n text = await readFile(path, 'utf8');\n } catch (err) {\n if ((err as NodeJS.ErrnoException).code === 'ENOENT') return {};\n throw err;\n }\n return parseUserConfig(text, path);\n}\n\nfunction setLeaf(doc: Partial<UserConfig>, key: string, value: unknown): void {\n const idx = key.indexOf('.');\n const branch = key.slice(0, idx);\n const leaf = key.slice(idx + 1);\n const root = doc as unknown as Record<string, Record<string, unknown>>;\n if (!root[branch] || typeof root[branch] !== 'object') {\n root[branch] = {};\n }\n root[branch][leaf] = value;\n}\n\nfunction unsetLeaf(doc: Partial<UserConfig>, key: string): boolean {\n const idx = key.indexOf('.');\n const branch = key.slice(0, idx);\n const leaf = key.slice(idx + 1);\n const root = doc as unknown as Record<string, Record<string, unknown>>;\n const b = root[branch];\n if (!b || typeof b !== 'object' || !(leaf in b)) return false;\n delete b[leaf];\n if (Object.keys(b).length === 0) {\n delete root[branch];\n }\n return true;\n}\n\nasync function atomicWriteYaml(path: string, doc: Partial<UserConfig>): Promise<void> {\n await mkdir(dirname(path), { recursive: true });\n // YAML serialises empty objects as `{}` which is correct but ugly; if the\n // doc is empty we still want a usable placeholder file.\n const text = Object.keys(doc).length === 0\n ? '# managed by agentbox config — empty\\n'\n : stringifyYaml(doc);\n const tmp = `${path}.tmp-${process.pid.toString()}-${Date.now().toString(36)}`;\n await writeFile(tmp, text, { encoding: 'utf8', mode: 0o644 });\n await rename(tmp, path);\n}\n\nasync function touchProjectMeta(absPath: string): Promise<void> {\n const dir = dirname(projectMetaFile(absPath));\n await mkdir(dir, { recursive: true });\n const metaPath = projectMetaFile(absPath);\n let prior: { originalPath?: string; createdAt?: string } = {};\n try {\n prior = JSON.parse(await readFile(metaPath, 'utf8')) as typeof prior;\n } catch {\n /* fresh file */\n }\n const now = new Date().toISOString();\n const next = {\n originalPath: absPath,\n hash: hashProjectPath(absPath),\n createdAt: prior.createdAt ?? now,\n lastSeenAt: now,\n };\n const tmp = `${metaPath}.tmp-${process.pid.toString()}-${Date.now().toString(36)}`;\n await writeFile(tmp, JSON.stringify(next, null, 2) + '\\n', { encoding: 'utf8', mode: 0o644 });\n await rename(tmp, metaPath);\n}\n\n// Re-export for ergonomics; same path resolution as the loader uses.\nexport { configPathFor };\n"],"mappings":";;;AAAA,SAAS,aAA0B;ACAnC,SAAS,SAAAA,QAAO,YAAAC,WAAU,QAAAC,aAAY;AACtC,SAAS,WAAAC,gBAAe;AACxB,SAAS,QAAAC,aAAY;AACrB,SAAS,SAAAC,cAAa;ACHtB,SAAS,SAAAA,cAAa;AACtB,SAAS,kBAAkB;AAC3B,SAAS,qBAAqB;AAC9B,SAAS,WAAAC,UAAS,WAAAC,gBAAe;ACHjC,SAAS,SAAAP,SAAO,YAAAC,YAAU,WAAAO,UAAS,MAAAC,KAAI,aAAAC,kBAAiB;AACxD,SAAS,WAAAP,iBAAe;AACxB,SAAS,QAAAC,cAAY;AACrB,SAAS,SAAAC,cAAa;;;AEHtB,SAAS,SAAS,iBAAiB;ACAnC,SAAS,kBAAkB;AAC3B,SAAS,UAAU,YAAY;AAC/B,SAAS,eAAe;AACxB,SAAS,SAAS,MAAM,eAAe;ACHvC,SAAS,gBAAgB;AACzB,SAAS,SAASM,kBAAiB;ACDnC,SAAS,OAAO,YAAAC,WAAU,QAAQ,IAAI,QAAAC,OAAM,iBAAiB;AAC7D,SAAS,WAAAC,UAAS,YAAY,QAAAC,aAAY;AAC1C,SAAS,aAAa,qBAAqB;AAW3C,SAAS,eAAe;AJ+IjB,IAAM,oBAAqC;EAChD,KAAK;IACH,cAAc;IACd,mBAAmB;IACnB,gBAAgB;IAChB,SAAS;IACT,KAAK;IACL,qBAAqB;IACrB,OAAO;IACP,mBAAmB;IACnB,QAAQ;IACR,MAAM;IACN,WAAW;IACX,MAAM;EACR;EACA,YAAY;IACV,WAAW;EACb;EACA,QAAQ;IACN,aAAa;EACf;EACA,MAAM;IACJ,KAAK;IACL,MAAM;IACN,WAAW;IACX,eAAe;EACjB;EACA,OAAO;IACL,MAAM;IACN,OAAO;EACT;EACA,QAAQ;IACN,MAAM;EACR;EACA,SAAS;IACP,SAAS;EACX;EACA,OAAO;IACL,MAAM;EACR;EACA,KAAK;IACH,eAAe;EACjB;EACA,WAAW;IACT,SAAS;IACT,iBAAiB;IACjB,aAAa;EACf;EACA,aAAa;IACX,qBAAqB;IACrB,0BAA0B;EAC5B;AACF;AAoBO,IAAM,eAAyC;EACpD;IACE,KAAK;IACL,MAAM;IACN,aACE;EACJ;EACA;IACE,KAAK;IACL,MAAM;IACN,aACE;EACJ;EACA;IACE,KAAK;IACL,MAAM;IACN,aACE;IACF,UAAU;EACZ;EACA;IACE,KAAK;IACL,MAAM;IACN,aAAa;EACf;EACA;IACE,KAAK;IACL,MAAM;IACN,aACE;EACJ;EACA;IACE,KAAK;IACL,MAAM;IACN,aAAa;EACf;EACA;IACE,KAAK;IACL,MAAM;IACN,aAAa;EACf;EACA;IACE,KAAK;IACL,MAAM;IACN,aAAa;IACb,UAAU;EACZ;EACA;IACE,KAAK;IACL,MAAM;IACN,aACE;EACJ;EACA;IACE,KAAK;IACL,MAAM;IACN,aACE;EACJ;EACA;IACE,KAAK;IACL,MAAM;IACN,aACE;EACJ;EACA;IACE,KAAK;IACL,MAAM;IACN,aAAa;EACf;EACA;IACE,KAAK;IACL,MAAM;IACN,aACE;IACF,UAAU;EACZ;EACA;IACE,KAAK;IACL,MAAM;IACN,aAAa;EACf;EACA;IACE,KAAK;IACL,MAAM;IACN,YAAY,CAAC,UAAU,UAAU,MAAM;IACvC,aAAa;EACf;EACA;IACE,KAAK;IACL,MAAM;IACN,aAAa;EACf;EACA;IACE,KAAK;IACL,MAAM;IACN,aAAa;EACf;EACA;IACE,KAAK;IACL,MAAM;IACN,aAAa;EACf;EACA;IACE,KAAK;IACL,MAAM;IACN,aAAa;EACf;EACA;IACE,KAAK;IACL,MAAM;IACN,aAAa;EACf;EACA;IACE,KAAK;IACL,MAAM;IACN,YAAY,CAAC,YAAY,kBAAkB,SAAS,MAAM;IAC1D,aAAa;EACf;EACA;IACE,KAAK;IACL,MAAM;IACN,YAAY,CAAC,iBAAiB,cAAc,MAAM;IAClD,aAAa;EACf;EACA;IACE,KAAK;IACL,MAAM;IACN,aAAa;IACb,UAAU;EACZ;EACA;IACE,KAAK;IACL,MAAM;IACN,aAAa;IACb,UAAU;EACZ;EACA;IACE,KAAK;IACL,MAAM;IACN,aACE;EACJ;EACA;IACE,KAAK;IACL,MAAM;IACN,aACE;EACJ;EACA;IACE,KAAK;IACL,MAAM;IACN,aACE;EACJ;EACA;IACE,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","names":["mkdir","readFile","stat","homedir","join","execa","dirname","resolve","readdir","rm","writeFile","parseYaml","readFile","stat","dirname","join","fileExists","execa","join","homedir","readFile","stat","mkdir","dirname","resolve","readdir","rm","writeFile"]}
|
|
@@ -1,15 +0,0 @@
|
|
|
1
|
-
#!/usr/bin/env node
|
|
2
|
-
import {
|
|
3
|
-
createBox,
|
|
4
|
-
defaultBoxName,
|
|
5
|
-
sanitizeBasename
|
|
6
|
-
} from "./chunk-3NCUES35.js";
|
|
7
|
-
import "./chunk-MOC54XL6.js";
|
|
8
|
-
import "./chunk-IDR4HVIC.js";
|
|
9
|
-
import "./chunk-SOMIKEN2.js";
|
|
10
|
-
export {
|
|
11
|
-
createBox,
|
|
12
|
-
defaultBoxName,
|
|
13
|
-
sanitizeBasename
|
|
14
|
-
};
|
|
15
|
-
//# sourceMappingURL=create-SE6H4B5U-IWAZHJHV.js.map
|
|
@@ -1,19 +0,0 @@
|
|
|
1
|
-
#!/usr/bin/env node
|
|
2
|
-
import {
|
|
3
|
-
agentboxHomeBytes,
|
|
4
|
-
allCheckpointVolumesBytes,
|
|
5
|
-
boxResourceStats,
|
|
6
|
-
parseDockerSize,
|
|
7
|
-
projectCheckpointVolumeBytes,
|
|
8
|
-
volumeSizeBytes
|
|
9
|
-
} from "./chunk-J35IH7W5.js";
|
|
10
|
-
import "./chunk-SOMIKEN2.js";
|
|
11
|
-
export {
|
|
12
|
-
agentboxHomeBytes,
|
|
13
|
-
allCheckpointVolumesBytes,
|
|
14
|
-
boxResourceStats,
|
|
15
|
-
parseDockerSize,
|
|
16
|
-
projectCheckpointVolumeBytes,
|
|
17
|
-
volumeSizeBytes
|
|
18
|
-
};
|
|
19
|
-
//# sourceMappingURL=stats-GZFLPYTU-DBJ2DVBJ.js.map
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|