@snappedly-tools/shipyard 0.4.2 → 0.4.4-staging.35699051936

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.
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/sandboxes/copyIntoContainer.ts","../src/DockerLifecycle.ts","../src/RepositoryRunnerLifecycle.ts","../src/sandboxes/docker.ts"],"names":["execFile","promisify","resolve","Effect"],"mappings":"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","file":"chunk-DP5MP533.js","sourcesContent":["import { execFile } from \"node:child_process\";\nimport { posix } from \"node:path\";\nimport { promisify } from \"node:util\";\n\nconst exec = promisify(execFile);\n\n/** Container cp creates root-owned files; session files may have mode 0600. */\nexport const copyIntoContainer = async (\n engine: \"docker\",\n container: string,\n owner: string,\n hostPath: string,\n sandboxPath: string,\n): Promise<void> => {\n try {\n await exec(engine, [\n \"exec\",\n container,\n \"mkdir\",\n \"-p\",\n \"--\",\n posix.dirname(sandboxPath),\n ]);\n await exec(engine, [\"cp\", hostPath, `${container}:${sandboxPath}`]);\n await exec(engine, [\n \"exec\",\n \"--user\",\n \"0:0\",\n container,\n \"chown\",\n \"-hR\",\n \"--\",\n owner,\n sandboxPath,\n ]);\n } catch (error) {\n throw new Error(\n `${engine} cp (in) failed: ${error instanceof Error ? error.message : String(error)}`,\n );\n }\n};\n","import { Effect } from \"effect\";\nimport { execFile } from \"node:child_process\";\nimport { resolve } from \"node:path\";\nimport { DockerError } from \"./errors.js\";\nimport { formatVolumeMount, type SelinuxLabel } from \"./mountUtils.js\";\n\nconst dockerExec = (args: string[]): Effect.Effect<string, DockerError> =>\n Effect.async((resume) => {\n execFile(\n \"docker\",\n args,\n { maxBuffer: 10 * 1024 * 1024 },\n (error, stdout, stderr) => {\n if (error) {\n resume(\n Effect.fail(\n new DockerError({\n message: `docker ${args[0]} failed: ${stderr?.toString() || error.message}`,\n }),\n ),\n );\n } else {\n resume(Effect.succeed(stdout.toString()));\n }\n },\n );\n });\n\n/**\n * Build the shipyard Docker image.\n *\n * When `dockerfile` is provided, uses `docker build -f <dockerfile> <cwd>`\n * so COPY instructions resolve relative to the current working directory.\n * Otherwise, uses `docker build <dockerfileDir>` (the default .shipyard/ directory).\n */\nexport const buildImage = (\n imageName: string,\n dockerfileDir: string,\n options?: {\n readonly dockerfile?: string;\n readonly buildArgs?: Record<string, string>;\n },\n): Effect.Effect<void, DockerError> =>\n Effect.gen(function* () {\n const buildArgFlags = Object.entries(options?.buildArgs ?? {}).flatMap(\n ([k, v]) => [\"--build-arg\", `${k}=${v}`],\n );\n if (options?.dockerfile) {\n yield* dockerExec([\n \"build\",\n \"-t\",\n imageName,\n ...buildArgFlags,\n \"-f\",\n resolve(options.dockerfile),\n process.cwd(),\n ]);\n } else {\n yield* dockerExec([\n \"build\",\n \"-t\",\n imageName,\n ...buildArgFlags,\n resolve(dockerfileDir),\n ]);\n }\n });\n\nexport interface VolumeMount {\n readonly hostPath: string;\n readonly sandboxPath: string;\n readonly readonly?: boolean;\n}\n\nexport interface StartContainerOptions {\n readonly volumeMounts?: readonly VolumeMount[];\n readonly workdir?: string;\n /** Run the container as this uid:gid instead of the Dockerfile's USER. */\n readonly user?: string;\n /** Docker network(s) to attach the container to. Passed as `--network` flags. */\n readonly network?: string | readonly string[];\n /** Supplementary groups to add the container user to. Passed as `--group-add` flags. */\n readonly groups?: readonly (string | number)[];\n /** Host devices to expose to the container. Passed as `--device` flags. */\n readonly devices?: readonly string[];\n /** Limit CPU resources via `--cpus` (e.g. `1.5`). Fractional values allowed. */\n readonly cpus?: number;\n /** Docker labels used to scope repository-runner crash recovery. */\n readonly labels?: Readonly<Record<string, string>>;\n /**\n * SELinux volume label suffix applied to bind mounts (default `\"z\"`).\n *\n * - `\"z\"` — shared label. No-op on non-SELinux systems.\n * - `\"Z\"` — private label; only this container can access the mount.\n * - `false` — disable labeling entirely.\n */\n readonly selinuxLabel?: SelinuxLabel;\n}\n\n/**\n * Start a new container with environment variables injected.\n */\nexport const startContainer = (\n containerName: string,\n imageName: string,\n env: Record<string, string>,\n options?: StartContainerOptions,\n): Effect.Effect<void, DockerError> =>\n Effect.gen(function* () {\n // Check if container already exists\n const existing = yield* dockerExec([\n \"ps\",\n \"-a\",\n \"--filter\",\n `name=^${containerName}$`,\n \"--format\",\n \"{{.Names}}\",\n ]);\n\n if (existing.trim() === containerName) {\n yield* Effect.fail(\n new DockerError({\n message: `Container '${containerName}' already exists. Run cleanup first.`,\n }),\n );\n }\n\n const envFlags = Object.entries(env).flatMap(([k, v]) => [\n \"-e\",\n `${k}=${v}`,\n ]);\n\n const selinuxLabel = options?.selinuxLabel ?? \"z\";\n const volumeFlags = (options?.volumeMounts ?? []).flatMap((mount) => [\n \"-v\",\n formatVolumeMount(mount, selinuxLabel),\n ]);\n\n const workdirFlags = options?.workdir ? [\"-w\", options.workdir] : [];\n const userFlags = options?.user ? [\"--user\", options.user] : [];\n const networks = options?.network\n ? Array.isArray(options.network)\n ? options.network\n : [options.network]\n : [];\n const networkFlags = networks.flatMap((n) => [\"--network\", n]);\n const groupAddFlags = (options?.groups ?? []).flatMap((g) => [\n \"--group-add\",\n String(g),\n ]);\n const deviceFlags = (options?.devices ?? []).flatMap((d) => [\n \"--device\",\n d,\n ]);\n const cpusFlags =\n options?.cpus !== undefined ? [\"--cpus\", String(options.cpus)] : [];\n const labelFlags = Object.entries(options?.labels ?? {}).flatMap(\n ([key, value]) => [\"--label\", `${key}=${value}`],\n );\n\n yield* dockerExec([\n \"run\",\n \"-d\",\n \"--init\",\n \"--name\",\n containerName,\n ...labelFlags,\n ...envFlags,\n ...volumeFlags,\n ...workdirFlags,\n ...userFlags,\n ...networkFlags,\n ...groupAddFlags,\n ...deviceFlags,\n ...cpusFlags,\n imageName,\n ]);\n });\n\n/**\n * Stop and remove a container without removing the image.\n */\nexport const removeContainer = (\n containerName: string,\n): Effect.Effect<void, DockerError> =>\n Effect.gen(function* () {\n // Stop container (ignore errors if already stopped)\n yield* Effect.ignore(dockerExec([\"stop\", containerName]));\n // Remove container (ignore errors if not found)\n yield* Effect.ignore(dockerExec([\"rm\", containerName]));\n });\n\n/**\n * Remove a Docker image.\n */\nexport const removeImage = (\n imageName: string,\n): Effect.Effect<void, DockerError> =>\n Effect.gen(function* () {\n yield* dockerExec([\"rmi\", imageName]);\n });\n","import { execFile } from \"node:child_process\";\nimport { constants } from \"node:fs\";\nimport { access, lstat, mkdir, readFile, realpath, rm } from \"node:fs/promises\";\nimport { join } from \"node:path\";\nimport { promisify } from \"node:util\";\nimport {\n ACTIVATION_LABEL,\n CONFIG_DIR,\n RUNNER_DIR,\n RUNNER_SANDBOX_MASK_DIR,\n} from \"./runtimeNames.js\";\nimport {\n assertProtectedDirectoryIdentities,\n repositoryRunnerEnvironment,\n type ProtectedDirectoryIdentity,\n} from \"./runnerSecurity.js\";\n\nconst execFileAsync = promisify(execFile);\n\nexport const RUNNER_INSTALL_METADATA = \".shipyard-install.json\";\nexport const RUNNER_CONTROLLER_LOCK = \".shipyard-controller.lock\";\nexport const RUNNER_WORK_DIR = \"_work\";\nexport const REPOSITORY_RUNNER_OWNER_LABEL =\n \"com.snappedly.shipyard.repository-runner-owner\";\nexport const REPOSITORY_RUNNER_OWNER_ENV = \"SHIPYARD_RUNNER_OWNER\";\nconst REGISTRATION_FILES = [\n \".credentials\",\n \".credentials_rsaparams\",\n \".runner\",\n] as const;\n\ninterface CommandResult {\n readonly stdout: string;\n readonly stderr: string;\n}\n\ninterface CommandOptions {\n readonly cwd: string;\n readonly env: NodeJS.ProcessEnv;\n}\n\nexport interface RunnerInstallMetadata {\n readonly schemaVersion: 1;\n readonly repository: string;\n readonly repositoryUrl: string;\n readonly name: string;\n readonly label: string;\n readonly version: string;\n}\n\ninterface RunnerControllerLock {\n readonly schemaVersion: 1;\n readonly pid: number;\n readonly repository: string;\n readonly processStartedAt: string;\n}\n\nexport class RunnerLifecycleError extends Error {\n readonly name = \"RunnerLifecycleError\";\n}\n\n/** Internal seams for validating an existing runner installation. */\nexport interface RunnerInstallValidationAdapters {\n readonly environment: () => NodeJS.ProcessEnv;\n readonly exists: (path: string) => Promise<boolean>;\n readonly readText: (path: string) => Promise<string>;\n readonly makeDirectory: (path: string) => Promise<void>;\n readonly inspectDirectory?: (\n path: string,\n ) => Promise<ProtectedDirectoryIdentity>;\n readonly run: (\n command: string,\n args: readonly string[],\n options: CommandOptions,\n ) => Promise<CommandResult>;\n}\n\n/** Internal seams for runner registration, filesystem cleanup, and process control. */\nexport interface RunnerLifecycleAdapters extends RunnerInstallValidationAdapters {\n readonly remove: (path: string) => Promise<void>;\n readonly isProcessRunning: (pid: number) => boolean;\n readonly signalProcess: (pid: number, signal: NodeJS.Signals) => void;\n readonly pause: (milliseconds: number) => Promise<void>;\n readonly processIdentity: (pid: number) => Promise<string | undefined>;\n}\n\nconst defaultAdapters: RunnerLifecycleAdapters = {\n environment: () => process.env,\n exists: async (path) => {\n try {\n await access(path, constants.F_OK);\n return true;\n } catch {\n return false;\n }\n },\n readText: (path) => readFile(path, \"utf8\"),\n makeDirectory: async (path) => {\n await mkdir(path, { recursive: true, mode: 0o700 });\n },\n inspectDirectory: async (path) => {\n const [stat, resolved] = await Promise.all([lstat(path), realpath(path)]);\n return {\n realPath: resolved,\n directory: stat.isDirectory(),\n symbolicLink: stat.isSymbolicLink(),\n };\n },\n remove: (path) => rm(path, { recursive: true, force: true }),\n run: async (command, args, options) => {\n const result = await execFileAsync(command, [...args], {\n cwd: options.cwd,\n env: options.env,\n maxBuffer: 10 * 1024 * 1024,\n });\n return { stdout: result.stdout, stderr: result.stderr };\n },\n processIdentity: async (pid) => {\n try {\n const result = await execFileAsync(\"ps\", [\n \"-p\",\n String(pid),\n \"-o\",\n \"lstart=\",\n ]);\n const identity = result.stdout.trim().replace(/\\s+/g, \" \");\n return identity.length > 0 ? identity : undefined;\n } catch {\n return undefined;\n }\n },\n isProcessRunning: (pid) => {\n try {\n process.kill(pid, 0);\n return true;\n } catch {\n return false;\n }\n },\n signalProcess: (pid, signal) => process.kill(pid, signal),\n pause: (milliseconds) =>\n new Promise((resolve) => setTimeout(resolve, milliseconds)),\n};\n\nconst lockOwnsProcess = async (\n lock: RunnerControllerLock | undefined,\n adapters: Pick<\n RunnerLifecycleAdapters,\n \"isProcessRunning\" | \"processIdentity\"\n >,\n): Promise<boolean> =>\n lock !== undefined &&\n Number.isInteger(lock.pid) &&\n typeof lock.processStartedAt === \"string\" &&\n lock.processStartedAt.length > 0 &&\n adapters.isProcessRunning(lock.pid) &&\n (await adapters.processIdentity(lock.pid)) === lock.processStartedAt;\n\nconst lifecycleFailure = (\n purpose: string,\n error: unknown,\n): RunnerLifecycleError =>\n error instanceof RunnerLifecycleError\n ? error\n : new RunnerLifecycleError(\n `${purpose} failed: ${error instanceof Error ? error.message : String(error)}`,\n );\n\nconst runCommand = async (\n adapters: Pick<RunnerInstallValidationAdapters, \"run\">,\n purpose: string,\n command: string,\n args: readonly string[],\n options: CommandOptions,\n): Promise<CommandResult> => {\n try {\n return await adapters.run(command, args, options);\n } catch (error) {\n throw lifecycleFailure(purpose, error);\n }\n};\n\nconst readJson = async <T>(\n path: string,\n adapters: Pick<RunnerInstallValidationAdapters, \"exists\" | \"readText\">,\n): Promise<T | undefined> => {\n if (!(await adapters.exists(path))) return undefined;\n try {\n return JSON.parse(await adapters.readText(path)) as T;\n } catch (error) {\n throw lifecycleFailure(`Reading repository runner state at ${path}`, error);\n }\n};\n\nconst requireInstallMetadata = async (\n runnerDir: string,\n adapters: Pick<RunnerInstallValidationAdapters, \"exists\" | \"readText\">,\n): Promise<RunnerInstallMetadata> => {\n const metadata = await readJson<RunnerInstallMetadata>(\n join(runnerDir, RUNNER_INSTALL_METADATA),\n adapters,\n );\n if (\n metadata?.schemaVersion !== 1 ||\n typeof metadata.repository !== \"string\" ||\n typeof metadata.repositoryUrl !== \"string\" ||\n typeof metadata.name !== \"string\" ||\n metadata.label !== ACTIVATION_LABEL ||\n typeof metadata.version !== \"string\"\n ) {\n throw new RunnerLifecycleError(\n `The existing directory at ${runnerDir} is not a valid Shipyard repository runner installation. Refusing to replace it.`,\n );\n }\n return metadata;\n};\n\ninterface RemoteRunner {\n readonly name: string;\n readonly status: string;\n readonly labels: ReadonlySet<string>;\n}\n\nconst parseRemoteRunners = (stdout: string): readonly RemoteRunner[] =>\n stdout\n .split(/\\r?\\n/)\n .filter((line) => line.length > 0)\n .map((line) => {\n const [name = \"\", status = \"\", labels = \"\"] = line.split(\"\\t\");\n return {\n name,\n status,\n labels: new Set(labels.split(\",\").filter(Boolean)),\n };\n });\n\nconst listRemoteRunners = async (\n repository: string,\n repoDir: string,\n environment: NodeJS.ProcessEnv,\n adapters: RunnerInstallValidationAdapters,\n): Promise<readonly RemoteRunner[]> => {\n const response = await runCommand(\n adapters,\n \"Checking registered GitHub repository runners\",\n \"gh\",\n [\n \"api\",\n \"--paginate\",\n `repos/${repository}/actions/runners`,\n \"--jq\",\n '.runners[] | [.name, .status, ([.labels[].name] | join(\",\"))] | @tsv',\n ],\n { cwd: repoDir, env: environment },\n );\n return parseRemoteRunners(response.stdout);\n};\n\nexport const validateExistingRepositoryRunner = async (\n options: {\n readonly repoDir: string;\n readonly runnerDir: string;\n readonly maskDir: string;\n readonly repository: string;\n readonly runnerName: string;\n },\n adapters: RunnerInstallValidationAdapters = defaultAdapters,\n): Promise<RunnerInstallMetadata> => {\n if (!(await adapters.exists(options.maskDir))) {\n await adapters.makeDirectory(options.maskDir);\n }\n await assertProtectedDirectoryIdentities(\n options.runnerDir,\n options.maskDir,\n adapters.inspectDirectory,\n ).catch((error) => {\n throw lifecycleFailure(\"Validating protected runner directories\", error);\n });\n const metadata = await requireInstallMetadata(options.runnerDir, adapters);\n if (metadata.repository !== options.repository) {\n throw new RunnerLifecycleError(\n `The existing repository runner belongs to ${metadata.repository}, not ${options.repository}. Refusing to replace it.`,\n );\n }\n if (metadata.name !== options.runnerName) {\n throw new RunnerLifecycleError(\n `The existing installation belongs to runner ${metadata.name}, not ${options.runnerName}. A Mac rename does not rename a registered runner; remove and reinstall it explicitly.`,\n );\n }\n for (const required of [\".credentials\", \"run.sh\"] as const) {\n if (!(await adapters.exists(join(options.runnerDir, required)))) {\n throw new RunnerLifecycleError(\n `The existing repository runner is missing ${required}. Refusing to replace its registration; remove it explicitly first.`,\n );\n }\n }\n\n const remoteRunners = await listRemoteRunners(\n options.repository,\n options.repoDir,\n adapters.environment(),\n adapters,\n );\n const labelled = remoteRunners.filter(({ labels }) =>\n labels.has(ACTIVATION_LABEL),\n );\n if (labelled.length > 1) {\n throw new RunnerLifecycleError(\n `Multiple repository runners carry the ${ACTIVATION_LABEL} label (${labelled.map(({ name }) => name).join(\", \")}). Remove duplicates before continuing.`,\n );\n }\n const matching = remoteRunners.find(({ name }) => name === metadata.name);\n if (!matching) {\n throw new RunnerLifecycleError(\n `Runner ${metadata.name} is installed locally but is no longer registered with GitHub. Run \\`shipyard runner start\\` to repair it, or remove it explicitly.`,\n );\n }\n if (!matching.labels.has(ACTIVATION_LABEL)) {\n throw new RunnerLifecycleError(\n `Registered runner ${metadata.name} does not carry the ${ACTIVATION_LABEL} label. Refusing to replace a customized registration.`,\n );\n }\n\n return metadata;\n};\n\nconst removeRegistrationFiles = async (\n runnerDir: string,\n adapters: RunnerLifecycleAdapters,\n): Promise<void> => {\n for (const name of REGISTRATION_FILES) {\n const path = join(runnerDir, name);\n if (await adapters.exists(path)) await adapters.remove(path);\n }\n};\n\nconst readOneTimeToken = (stdout: string, purpose: string): string => {\n try {\n const parsed = JSON.parse(stdout) as { token?: unknown };\n if (typeof parsed.token !== \"string\" || parsed.token.length === 0) {\n throw new Error(\"response did not contain a token\");\n }\n return parsed.token;\n } catch (error) {\n throw lifecycleFailure(purpose, error);\n }\n};\n\nconst requestRegistrationToken = async (\n repository: string,\n repoDir: string,\n environment: NodeJS.ProcessEnv,\n adapters: RunnerLifecycleAdapters,\n): Promise<string> => {\n await runCommand(\n adapters,\n \"Checking current administrative GitHub authorization\",\n \"gh\",\n [\"auth\", \"status\", \"--hostname\", \"github.com\"],\n { cwd: repoDir, env: environment },\n );\n const response = await runCommand(\n adapters,\n \"Requesting a one-time repository runner registration token\",\n \"gh\",\n [\n \"api\",\n \"--method\",\n \"POST\",\n `repos/${repository}/actions/runners/registration-token`,\n ],\n { cwd: repoDir, env: environment },\n );\n return readOneTimeToken(response.stdout, \"Reading the registration token\");\n};\n\nexport const recoverRepositoryRunner = async (\n options: {\n readonly repoDir: string;\n readonly runnerDir: string;\n readonly maskDir: string;\n readonly metadata: RunnerInstallMetadata;\n readonly runnerEnvironment: NodeJS.ProcessEnv;\n readonly dockerEnvironment?: NodeJS.ProcessEnv;\n },\n adapters: RunnerLifecycleAdapters = defaultAdapters,\n): Promise<{ readonly reRegistered: boolean }> => {\n const lockPath = join(options.runnerDir, RUNNER_CONTROLLER_LOCK);\n const lock = await readJson<RunnerControllerLock>(lockPath, adapters);\n if (await lockOwnsProcess(lock, adapters)) {\n throw new RunnerLifecycleError(\n `The repository runner is already running with process ${lock!.pid}.`,\n );\n }\n if (lock) await adapters.remove(lockPath);\n\n const workDir = join(options.runnerDir, RUNNER_WORK_DIR);\n if (await adapters.exists(workDir)) await adapters.remove(workDir);\n if (await adapters.exists(options.maskDir))\n await adapters.remove(options.maskDir);\n await adapters.makeDirectory(options.maskDir);\n await assertProtectedDirectoryIdentities(\n options.runnerDir,\n options.maskDir,\n adapters.inspectDirectory,\n ).catch((error) => {\n throw lifecycleFailure(\"Validating protected runner directories\", error);\n });\n\n await removeOwnedRepositoryRunnerContainers(\n {\n repoDir: options.repoDir,\n repository: options.metadata.repository,\n environment: options.dockerEnvironment ?? options.runnerEnvironment,\n },\n adapters,\n );\n\n const adminEnvironment = adapters.environment();\n const remoteRunners = await listRemoteRunners(\n options.metadata.repository,\n options.repoDir,\n adminEnvironment,\n adapters,\n );\n const labelled = remoteRunners.filter(({ labels }) =>\n labels.has(ACTIVATION_LABEL),\n );\n if (labelled.length > 1) {\n throw new RunnerLifecycleError(\n `Multiple repository runners carry the ${ACTIVATION_LABEL} label (${labelled.map(({ name }) => name).join(\", \")}). Remove duplicates before continuing.`,\n );\n }\n const matching = remoteRunners.find(\n ({ name }) => name === options.metadata.name,\n );\n if (matching) {\n if (!matching.labels.has(ACTIVATION_LABEL)) {\n throw new RunnerLifecycleError(\n `Registered runner ${matching.name} does not carry the ${ACTIVATION_LABEL} label. Refusing to replace a customized registration.`,\n );\n }\n if (!(await adapters.exists(join(options.runnerDir, \".credentials\")))) {\n throw new RunnerLifecycleError(\n `Registered runner ${matching.name} is missing local credentials. Remove and reinstall it explicitly.`,\n );\n }\n return { reRegistered: false };\n }\n\n const collision = labelled[0];\n if (collision) {\n throw new RunnerLifecycleError(\n `Repository runner ${collision.name} already carries the ${ACTIVATION_LABEL} label. Refusing to create a conflicting registration.`,\n );\n }\n\n const registrationToken = await requestRegistrationToken(\n options.metadata.repository,\n options.repoDir,\n adminEnvironment,\n adapters,\n );\n await removeRegistrationFiles(options.runnerDir, adapters);\n try {\n await adapters.run(\n \"./config.sh\",\n [\n \"--url\",\n options.metadata.repositoryUrl,\n \"--token\",\n registrationToken,\n \"--name\",\n options.metadata.name,\n \"--labels\",\n ACTIVATION_LABEL,\n \"--work\",\n RUNNER_WORK_DIR,\n \"--unattended\",\n ],\n { cwd: options.runnerDir, env: options.runnerEnvironment },\n );\n } catch {\n await removeRegistrationFiles(options.runnerDir, adapters);\n throw new RunnerLifecycleError(\n `Re-registering ${options.metadata.name} failed. Partial local registration files were removed; check GitHub Settings > Actions > Runners for an orphan registration, then retry \\`shipyard runner start\\`. The one-time token was not stored.`,\n );\n }\n return { reRegistered: true };\n};\n\nexport const removeOwnedRepositoryRunnerContainers = async (\n options: {\n readonly repoDir: string;\n readonly repository: string;\n readonly environment: NodeJS.ProcessEnv;\n },\n adapters: Pick<RunnerLifecycleAdapters, \"run\"> = defaultAdapters,\n): Promise<void> => {\n const ownedContainers = await runCommand(\n adapters,\n \"Finding stale repository-runner containers\",\n \"docker\",\n [\n \"ps\",\n \"-aq\",\n \"--filter\",\n `label=${REPOSITORY_RUNNER_OWNER_LABEL}=${options.repository}`,\n ],\n { cwd: options.repoDir, env: options.environment },\n );\n const containerIds = ownedContainers.stdout.split(/\\s+/).filter(Boolean);\n if (containerIds.length === 0) return;\n await runCommand(\n adapters,\n \"Removing stale repository-runner containers\",\n \"docker\",\n [\"rm\", \"-f\", ...containerIds],\n { cwd: options.repoDir, env: options.environment },\n );\n};\n\nconst waitForProcessToStop = async (\n pid: number,\n adapters: RunnerLifecycleAdapters,\n): Promise<void> => {\n adapters.signalProcess(pid, \"SIGTERM\");\n for (let attempt = 0; attempt < 50; attempt += 1) {\n if (!adapters.isProcessRunning(pid)) return;\n await adapters.pause(100);\n }\n throw new RunnerLifecycleError(\n `Repository runner process ${pid} did not stop within 5 seconds. Local runner files were preserved.`,\n );\n};\n\nconst unregisterRepositoryRunner = async (\n metadata: RunnerInstallMetadata,\n repoDir: string,\n runnerDir: string,\n environment: NodeJS.ProcessEnv,\n adapters: RunnerLifecycleAdapters,\n): Promise<void> => {\n await runCommand(\n adapters,\n \"Checking current administrative GitHub authorization\",\n \"gh\",\n [\"auth\", \"status\", \"--hostname\", \"github.com\"],\n { cwd: repoDir, env: environment },\n );\n const response = await runCommand(\n adapters,\n \"Requesting a one-time repository runner removal token\",\n \"gh\",\n [\n \"api\",\n \"--method\",\n \"POST\",\n `repos/${metadata.repository}/actions/runners/remove-token`,\n ],\n { cwd: repoDir, env: environment },\n );\n const token = readOneTimeToken(response.stdout, \"Reading the removal token\");\n try {\n await adapters.run(\n \"./config.sh\",\n [\"remove\", \"--token\", token, \"--unattended\"],\n { cwd: runnerDir, env: repositoryRunnerEnvironment(environment) },\n );\n } catch {\n throw new RunnerLifecycleError(\n `Unregistering ${metadata.name} from GitHub failed. Local runner files were preserved; retry after restoring repository administration access.`,\n );\n }\n};\n\nexport interface RepositoryRunnerRemoveResult {\n readonly removed: true;\n readonly forced: boolean;\n readonly manualCleanup?: string;\n}\n\nexport const removeRepositoryRunner = async (\n options: { readonly repoDir: string; readonly force?: boolean },\n adapters: RunnerLifecycleAdapters = defaultAdapters,\n): Promise<RepositoryRunnerRemoveResult> => {\n const configDir = join(options.repoDir, CONFIG_DIR);\n const runnerDir = join(configDir, RUNNER_DIR);\n const maskDir = join(configDir, RUNNER_SANDBOX_MASK_DIR);\n if (!(await adapters.exists(runnerDir))) {\n throw new RunnerLifecycleError(\n `No repository runner is installed at ${runnerDir}.`,\n );\n }\n let metadata: RunnerInstallMetadata;\n try {\n metadata = await requireInstallMetadata(runnerDir, adapters);\n } catch (error) {\n if (!options.force) throw error;\n await adapters.remove(runnerDir);\n if (await adapters.exists(maskDir)) await adapters.remove(maskDir);\n return {\n removed: true,\n forced: true,\n manualCleanup:\n \"Check GitHub Settings > Actions > Runners and manually remove any orphan repository runner registration.\",\n };\n }\n const lock = await readJson<RunnerControllerLock>(\n join(runnerDir, RUNNER_CONTROLLER_LOCK),\n adapters,\n );\n if (await lockOwnsProcess(lock, adapters)) {\n await waitForProcessToStop(lock!.pid, adapters);\n }\n\n try {\n await unregisterRepositoryRunner(\n metadata,\n options.repoDir,\n runnerDir,\n adapters.environment(),\n adapters,\n );\n } catch (error) {\n if (!options.force) {\n const failure = lifecycleFailure(\"Removing the repository runner\", error);\n throw new RunnerLifecycleError(\n `${failure.message} Local runner files were preserved.`,\n );\n }\n await adapters.remove(runnerDir);\n if (await adapters.exists(maskDir)) await adapters.remove(maskDir);\n return {\n removed: true,\n forced: true,\n manualCleanup: `Remove runner ${metadata.name} from ${metadata.repository} in GitHub Settings > Actions > Runners.`,\n };\n }\n\n if (await adapters.exists(maskDir)) await adapters.remove(maskDir);\n await adapters.remove(runnerDir);\n return { removed: true, forced: false };\n};\n","import { copyIntoContainer } from \"./copyIntoContainer.js\";\n/**\n * Docker sandbox provider — wraps DockerLifecycle into a SandboxProvider.\n *\n * Usage:\n * import { docker } from \"@snappedly-tools/shipyard/sandboxes/docker\";\n * await run({ agent: codex(CODEX_MODELS.routine), sandbox: docker() });\n */\n\nimport {\n execFile,\n execFileSync,\n spawn,\n type StdioOptions,\n} from \"node:child_process\";\nimport { randomUUID } from \"node:crypto\";\nimport { createInterface } from \"node:readline\";\nimport { Effect } from \"effect\";\nimport { startContainer, removeContainer } from \"../DockerLifecycle.js\";\nimport {\n createIsolatedSandboxProvider,\n type IsolatedSandboxProvider,\n type IsolatedCreateOptions,\n type IsolatedSandboxHandle,\n type ExecResult,\n type InteractiveExecOptions,\n} from \"../SandboxProvider.js\";\nimport type { MountConfig } from \"../MountConfig.js\";\nimport type { SelinuxLabel } from \"../mountUtils.js\";\nimport {\n defaultImageName,\n resolveUserMounts,\n assertIsolatedWorkspaceMounts,\n processFileMountParents,\n} from \"../mountUtils.js\";\nimport {\n BoundedTail,\n MAX_TAIL_CHARS,\n OutputByteCounter,\n} from \"../boundedTail.js\";\nimport { registerShutdown } from \"../shutdownRegistry.js\";\nimport {\n REPOSITORY_RUNNER_OWNER_ENV,\n REPOSITORY_RUNNER_OWNER_LABEL,\n} from \"../RepositoryRunnerLifecycle.js\";\n\nexport interface DockerOptions {\n /** Docker image name (default: derived from repo directory name). */\n readonly imageName?: string;\n /**\n * The UID of the `agent` user inside the container image (default: host UID via `process.getuid()`, or 1000).\n *\n * Must match the UID baked into the image at build time. Used as the `--user` flag value\n * and checked against the image's configured UID in the pre-flight diagnostic.\n */\n readonly containerUid?: number;\n /**\n * The GID of the `agent` user inside the container image (default: host GID via `process.getgid()`, or 1000).\n *\n * Must match the GID baked into the image at build time. Used as the `--user` flag value.\n */\n readonly containerGid?: number;\n /**\n * SELinux volume label suffix applied to bind mounts.\n *\n * - `\"z\"` — shared label (default). No-op on non-SELinux systems.\n * - `\"Z\"` — private label; only this container can access the mount.\n * - `false` — disable labeling entirely.\n */\n readonly selinuxLabel?: SelinuxLabel;\n /**\n * Additional host directories to bind-mount into the sandbox.\n *\n * Each entry specifies a `hostPath` (tilde-expanded) and `sandboxPath`.\n * If `hostPath` does not exist, sandbox creation fails with a clear error.\n */\n readonly mounts?: readonly MountConfig[];\n /** Environment variables injected by this provider. Merged at launch time with env resolver and agent provider env. */\n readonly env?: Record<string, string>;\n /**\n * Docker network(s) to attach the container to.\n *\n * - `\"my-network\"` → `--network my-network`\n * - `[\"net1\", \"net2\"]` → `--network net1 --network net2`\n *\n * When omitted, Docker's default bridge network is used.\n */\n readonly network?: string | readonly string[];\n /**\n * Supplementary groups to add the container user to, via `--group-add`.\n *\n * Accepts group names or numeric GIDs:\n *\n * - `[\"docker\"]` → `--group-add docker`\n * - `[999]` → `--group-add 999`\n * - `[\"docker\", 999]` → `--group-add docker --group-add 999`\n *\n * Useful for granting access to a bind-mounted Docker socket (Docker-outside-of-Docker).\n * When omitted, no `--group-add` flags are added.\n */\n readonly groups?: readonly (string | number)[];\n /**\n * Host devices to expose to the container, via `--device`.\n *\n * Each entry is a full device spec in `host[:container[:permissions]]` form:\n *\n * - `[\"/dev/kvm\"]` → `--device /dev/kvm`\n * - `[\"/dev/sda:/dev/xvda:rwm\"]` → `--device /dev/sda:/dev/xvda:rwm`\n * - `[\"/dev/kvm\", \"/dev/fuse\"]` → `--device /dev/kvm --device /dev/fuse`\n *\n * When omitted, no `--device` flags are added.\n */\n readonly devices?: readonly string[];\n /**\n * Maximum number of characters of streamed `exec` output retained per stream\n * (stdout and stderr) when an `onLine` callback is supplied (default: 64KiB).\n *\n * Output is delivered live to `onLine` regardless; this only bounds the tail\n * returned in `ExecResult`, preventing a long-running agent's output from\n * overflowing V8's max string length and crashing the run.\n */\n readonly maxOutputTailChars?: number;\n /**\n * Limit the CPU resources available to the container, via `--cpus`.\n *\n * Maps directly to `docker run --cpus`. Accepts fractional values:\n *\n * - `2` → `--cpus 2` (at most 2 CPUs)\n * - `1.5` → `--cpus 1.5` (at most 1.5 CPUs)\n *\n * When omitted, no `--cpus` flag is added and the container is unconstrained.\n */\n readonly cpus?: number;\n}\n\n/**\n * Create a Docker sandbox provider.\n *\n * The returned provider creates Docker containers with isolated repository and Git storage.\n * Changes are transferred through git bundle and validated sync-out.\n */\nexport const docker = (options?: DockerOptions): IsolatedSandboxProvider => {\n const configuredImageName = options?.imageName;\n const selinuxLabel = options?.selinuxLabel ?? \"z\";\n const maxOutputTailChars = options?.maxOutputTailChars ?? MAX_TAIL_CHARS;\n const sandboxHomedir = \"/home/agent\";\n const userMounts = options?.mounts\n ? resolveUserMounts(options.mounts, sandboxHomedir)\n : [];\n assertIsolatedWorkspaceMounts(userMounts);\n // Validate file mounts and collect parent dirs to create at container start.\n // Throws at construction time if any file mount parent is outside sandboxHomedir.\n const parentDirsToCreate = processFileMountParents(\n userMounts,\n sandboxHomedir,\n );\n\n return createIsolatedSandboxProvider({\n name: \"docker\",\n env: options?.env,\n create: async (\n createOptions: IsolatedCreateOptions,\n ): Promise<IsolatedSandboxHandle> => {\n const containerName = `shipyard-${randomUUID()}`;\n\n const worktreePath = \"/home/agent/workspace\";\n\n // Repository and Git storage are container-owned. Only explicitly\n // configured mounts cross the host boundary.\n const allMounts = userMounts;\n const volumeMounts = allMounts.map((m) => ({\n hostPath: m.hostPath,\n sandboxPath: m.sandboxPath,\n readonly: m.readonly,\n }));\n\n // Resolve image name\n const imageName =\n configuredImageName ??\n defaultImageName(createOptions.hostRepoPath ?? process.cwd());\n\n const containerUid = options?.containerUid ?? process.getuid?.() ?? 1000;\n const containerGid = options?.containerGid ?? process.getgid?.() ?? 1000;\n\n // Pre-flight: verify image exists and UID matches\n await checkImageUid(imageName, containerUid);\n\n // Start container\n await Effect.runPromise(\n startContainer(\n containerName,\n imageName,\n {\n ...createOptions.env,\n HOME: \"/home/agent\",\n },\n {\n volumeMounts,\n workdir: worktreePath,\n user: `${containerUid}:${containerGid}`,\n network: options?.network,\n groups: options?.groups,\n devices: options?.devices,\n cpus: options?.cpus,\n selinuxLabel,\n labels: process.env[REPOSITORY_RUNNER_OWNER_ENV]\n ? {\n [REPOSITORY_RUNNER_OWNER_LABEL]:\n process.env[REPOSITORY_RUNNER_OWNER_ENV],\n }\n : undefined,\n },\n ),\n );\n\n // Create parent directories for file mounts and chown to the container user\n for (const dir of parentDirsToCreate) {\n await new Promise<void>((resolve, reject) => {\n execFile(\n \"docker\",\n [\n \"exec\",\n \"--user\",\n \"0:0\",\n containerName,\n \"sh\",\n \"-c\",\n `mkdir -p \"$1\" && chown \"$2\" \"$1\"`,\n \"sh\",\n dir,\n `${containerUid}:${containerGid}`,\n ],\n (error) => {\n if (error) {\n reject(\n new Error(\n `Failed to create parent directory '${dir}' in container: ${error.message}`,\n ),\n );\n } else {\n resolve();\n }\n },\n );\n });\n }\n\n // Register synchronous container cleanup via the shared shutdown registry\n // so concurrent sandboxes share a single exit/SIGINT/SIGTERM listener\n // instead of tripping Node's MaxListenersExceededWarning.\n const removeContainerSync = () => {\n try {\n execFileSync(\"docker\", [\"rm\", \"-f\", containerName], {\n stdio: \"ignore\",\n });\n } catch {\n /* best-effort */\n }\n };\n const unregisterShutdown = registerShutdown(removeContainerSync);\n\n const handle: IsolatedSandboxHandle = {\n worktreePath,\n\n exec: (\n command: string,\n opts?: {\n onLine?: (line: string) => void;\n cwd?: string;\n sudo?: boolean;\n stdin?: string;\n signal?: AbortSignal;\n maxOutputBytes?: number;\n },\n ): Promise<ExecResult> => {\n const effectiveCommand = opts?.sudo ? `sudo ${command}` : command;\n const args = [\"exec\"];\n if (opts?.stdin !== undefined) args.push(\"-i\");\n if (opts?.cwd) args.push(\"-w\", opts.cwd);\n args.push(containerName, \"sh\", \"-c\", effectiveCommand);\n\n return new Promise((resolve, reject) => {\n const proc = spawn(\"docker\", args, {\n signal: opts?.signal,\n stdio: [\n opts?.stdin !== undefined ? \"pipe\" : \"ignore\",\n \"pipe\",\n \"pipe\",\n ],\n });\n\n if (opts?.stdin !== undefined) {\n proc.stdin!.write(opts.stdin);\n proc.stdin!.end();\n }\n\n proc.on(\"error\", (error) => {\n reject(new Error(`docker exec failed: ${error.message}`));\n });\n\n if (opts?.onLine || opts?.maxOutputBytes !== undefined) {\n const onLine = opts?.onLine ?? (() => {});\n const outputLimit =\n opts?.maxOutputBytes === undefined\n ? undefined\n : new OutputByteCounter(opts.maxOutputBytes);\n const tailChars = opts?.maxOutputBytes ?? maxOutputTailChars;\n const stdoutTail = new BoundedTail(tailChars, \"\\n\");\n const stderrTail = new BoundedTail(tailChars, \"\");\n let limitError: Error | undefined;\n const checkOutputLimit = (chunk: Buffer): void => {\n if (outputLimit === undefined || limitError !== undefined) {\n return;\n }\n outputLimit.add(chunk);\n if (outputLimit.exceeded) {\n limitError = new Error(\n `Sandbox command output exceeded ${opts.maxOutputBytes} bytes`,\n );\n proc.kill(\"SIGKILL\");\n }\n };\n proc.stdout!.on(\"data\", checkOutputLimit);\n proc.stderr!.on(\"data\", checkOutputLimit);\n const rl = createInterface({ input: proc.stdout! });\n rl.on(\"line\", (line) => {\n stdoutTail.push(line);\n onLine(line);\n });\n proc.stderr!.on(\"data\", (chunk: Buffer) => {\n stderrTail.push(chunk.toString());\n });\n proc.on(\"close\", (code) => {\n if (limitError !== undefined) {\n reject(limitError);\n return;\n }\n resolve({\n stdout: stdoutTail.toString(),\n stderr: stderrTail.toString(),\n exitCode: code ?? 0,\n });\n });\n } else {\n const stdoutChunks: string[] = [];\n const stderrChunks: string[] = [];\n proc.stdout!.on(\"data\", (chunk: Buffer) => {\n stdoutChunks.push(chunk.toString());\n });\n proc.stderr!.on(\"data\", (chunk: Buffer) => {\n stderrChunks.push(chunk.toString());\n });\n proc.on(\"close\", (code) => {\n resolve({\n stdout: stdoutChunks.join(\"\"),\n stderr: stderrChunks.join(\"\"),\n exitCode: code ?? 0,\n });\n });\n }\n });\n },\n\n interactiveExec: (\n args: string[],\n opts: InteractiveExecOptions,\n ): Promise<{ exitCode: number }> => {\n return new Promise((resolve, reject) => {\n opts.signal?.throwIfAborted();\n const executionId = randomUUID();\n const pidFile = `/tmp/shipyard-interactive-${executionId}.pid`;\n const cancelFile = `/tmp/shipyard-interactive-${executionId}.cancel`;\n const dockerArgs = [\"exec\"];\n // Allocate a pseudo-terminal when stdin looks like a TTY\n if (\n \"isTTY\" in opts.stdin &&\n (opts.stdin as { isTTY?: boolean }).isTTY\n ) {\n dockerArgs.push(\"-it\");\n } else {\n dockerArgs.push(\"-i\");\n }\n if (opts.cwd) dockerArgs.push(\"-w\", opts.cwd);\n dockerArgs.push(\n containerName,\n \"sh\",\n \"-c\",\n 'pid_file=$1; cancel_file=$2; shift 2; command -v setsid >/dev/null 2>&1 && command -v ps >/dev/null 2>&1 && command -v awk >/dev/null 2>&1 || { printf \"%s\\\\n\" \"setsid, ps, and awk are required for cancellable interactive execution\" >&2; exit 127; }; if [ -e \"$cancel_file\" ]; then rm -f \"$pid_file\" \"$cancel_file\"; exit 130; fi; setsid \"$@\" & child=$!; printf \"%s\\\\n\" \"$child\" > \"$pid_file\"; wait \"$child\"; status=$?; rm -f \"$pid_file\" \"$cancel_file\"; exit \"$status\"',\n \"shipyard-interactive\",\n pidFile,\n cancelFile,\n ...args,\n );\n\n const proc = spawn(\"docker\", dockerArgs, {\n stdio: [opts.stdin, opts.stdout, opts.stderr] as StdioOptions,\n });\n\n let settled = false;\n let cancelling = false;\n const finish = (\n result:\n | { readonly exitCode: number }\n | { readonly error: unknown },\n ): void => {\n if (settled) return;\n settled = true;\n opts.signal?.removeEventListener(\"abort\", onAbort);\n if (\"error\" in result) reject(result.error);\n else resolve(result);\n };\n\n const onAbort = (): void => {\n if (cancelling || settled) return;\n cancelling = true;\n const cancellationScript =\n 'touch \"$1\"; attempts=0; while [ ! -s \"$2\" ] && [ \"$attempts\" -lt 50 ]; do sleep 0.1; attempts=$((attempts + 1)); done; if [ -s \"$2\" ]; then pid=$(cat \"$2\"); group_running() { ps -eo pgid=,stat= | awk -v pg=\"$pid\" \\'$1 == pg && $2 !~ /^Z/ { found=1 } END { exit found ? 0 : 1 }\\'; }; kill -TERM \"-$pid\" 2>/dev/null || true; attempts=0; while group_running && [ \"$attempts\" -lt 20 ]; do sleep 0.1; attempts=$((attempts + 1)); done; kill -KILL \"-$pid\" 2>/dev/null || true; attempts=0; while group_running && [ \"$attempts\" -lt 20 ]; do sleep 0.1; attempts=$((attempts + 1)); done; if group_running; then exit 1; fi; rm -f \"$1\" \"$2\"; fi';\n execFile(\n \"docker\",\n [\n \"exec\",\n containerName,\n \"sh\",\n \"-c\",\n cancellationScript,\n \"shipyard-cancel\",\n cancelFile,\n pidFile,\n ],\n { timeout: 7_000 },\n (error) => {\n proc.kill(\"SIGKILL\");\n if (error) {\n finish({\n error: new Error(\n `Failed to terminate interactive process in Docker sandbox: ${error.message}`,\n ),\n });\n return;\n }\n finish({\n error:\n opts.signal?.reason ??\n new Error(\"Interactive execution aborted\"),\n });\n },\n );\n };\n\n opts.signal?.addEventListener(\"abort\", onAbort, { once: true });\n if (opts.signal?.aborted) onAbort();\n\n proc.on(\"error\", (error: Error) => {\n if (!cancelling) {\n finish({\n error: new Error(`docker exec failed: ${error.message}`),\n });\n }\n });\n\n proc.on(\"close\", (code: number | null) => {\n if (cancelling) return;\n execFile(\n \"docker\",\n [\"exec\", containerName, \"rm\", \"-f\", pidFile, cancelFile],\n () => {},\n );\n finish({ exitCode: code ?? 0 });\n });\n });\n },\n\n copyIn: (hostPath, sandboxPath) =>\n copyIntoContainer(\n \"docker\",\n containerName,\n `${containerUid}:${containerGid}`,\n hostPath,\n sandboxPath,\n ),\n\n copyFileOut: (sandboxPath: string, hostPath: string): Promise<void> =>\n new Promise((resolve, reject) => {\n execFile(\n \"docker\",\n [\"cp\", `${containerName}:${sandboxPath}`, hostPath],\n (error) => {\n if (error) {\n reject(new Error(`docker cp (out) failed: ${error.message}`));\n } else {\n resolve();\n }\n },\n );\n }),\n\n close: async (): Promise<void> => {\n unregisterShutdown();\n await Effect.runPromise(removeContainer(containerName));\n },\n };\n\n return handle;\n },\n });\n};\n\n// Re-export for backwards compatibility\nexport { defaultImageName };\n\nconst checkImageUid = (imageName: string, expectedUid: number): Promise<void> =>\n new Promise<void>((resolve, reject) => {\n execFile(\n \"docker\",\n [\"image\", \"inspect\", imageName, \"--format\", \"{{.Config.User}}\"],\n (error, stdout) => {\n if (error) {\n reject(\n new Error(\n `Image '${imageName}' not found locally. Build it first with 'shipyard docker build-image'.`,\n ),\n );\n return;\n }\n const imageUser = (stdout ?? \"\").toString().trim();\n if (!imageUser) {\n // No USER directive in image — skip check\n resolve();\n return;\n }\n const uidPart = imageUser.split(\":\")[0]!;\n const imageUid = parseInt(uidPart, 10);\n if (isNaN(imageUid)) {\n // Non-numeric user (e.g. \"agent\") — can't compare, skip check\n resolve();\n return;\n }\n if (imageUid !== expectedUid) {\n reject(\n new Error(\n `UID mismatch: image '${imageName}' was built with UID ${imageUid}, ` +\n `but the expected UID is ${expectedUid}. ` +\n `Rebuild the image with 'shipyard docker build-image', ` +\n `or pass containerUid: ${imageUid} to docker() to match the image.`,\n ),\n );\n } else {\n resolve();\n }\n },\n );\n });\n"]}
@@ -1,5 +1,5 @@
1
1
  import { toSessionTransferHandle, shellQuote } from './chunk-KMGNFXKN.js';
2
- import { existsSync, constants, statSync } from 'fs';
2
+ import { existsSync, constants, lstatSync, realpathSync, statSync } from 'fs';
3
3
  import { mkdtemp, writeFile, chmod, mkdir, stat, copyFile, rm, readdir, lstat, readFile, open } from 'fs/promises';
4
4
  import * as clack from '@clack/prompts';
5
5
  import { FileSystem } from '@effect/platform';
@@ -306,11 +306,14 @@ var SessionCaptureError = class extends Data.TaggedError(
306
306
  var PRODUCT_NAME = "Shipyard";
307
307
  var CLI_NAME = "shipyard";
308
308
  var RUNTIME_NAMESPACE = "shipyard";
309
+ var ACTIVATION_LABEL = "shipyard";
309
310
  var CONFIG_DIR = ".shipyard";
310
311
  var LOGS_DIR = "logs";
311
312
  var WORKTREES_DIR = "worktrees";
312
313
  var PATCHES_DIR = "patches";
313
314
  var LOCKS_DIR = "locks";
315
+ var RUNNER_DIR = "runner";
316
+ var RUNNER_SANDBOX_MASK_DIR = "runner-sandbox-mask";
314
317
  var PARENT_GIT_SANDBOX_DIR = "/.shipyard-parent-git";
315
318
  var SYNC_BASE_REF = "refs/shipyard/sync-base";
316
319
  var CONTAINER_NAME_PREFIX = "shipyard-";
@@ -815,6 +818,79 @@ var pruneStale = (repoDir) => Effect.gen(function* () {
815
818
  })
816
819
  )
817
820
  );
821
+ var PROTECTED_RUNNER_PATH = `${CONFIG_DIR}/${RUNNER_DIR}`;
822
+ var pathKey = (value) => value.normalize("NFC").toLocaleLowerCase("en-US");
823
+ var SAFE_RUNNER_ENV_KEYS = /* @__PURE__ */ new Set([
824
+ "HOME",
825
+ "LANG",
826
+ "LC_ALL",
827
+ "LOGNAME",
828
+ "PATH",
829
+ "SHELL",
830
+ "TEMP",
831
+ "TERM",
832
+ "TMP",
833
+ "TMPDIR",
834
+ "USER"
835
+ ]);
836
+ var repositoryRunnerEnvironment = (source) => Object.fromEntries(
837
+ Object.entries(source).filter(
838
+ ([key, value]) => SAFE_RUNNER_ENV_KEYS.has(key) && value !== void 0
839
+ )
840
+ );
841
+ var assertExcludesRepositoryRunner = (relativePath) => {
842
+ const normalized = pathKey(
843
+ posix.normalize(relativePath.replace(/\\/g, "/")).replace(/^\.\//, "").replace(/\/$/, "")
844
+ );
845
+ const protectedPath = pathKey(PROTECTED_RUNNER_PATH);
846
+ if (normalized === "." || normalized === protectedPath || normalized.startsWith(`${protectedPath}/`) || protectedPath.startsWith(`${normalized}/`)) {
847
+ throw new Error(
848
+ `Copy path ${relativePath} would expose the protected repository runner to an agent sandbox.`
849
+ );
850
+ }
851
+ };
852
+ var assertSafeRepositoryRunnerDirectories = (repoDir) => {
853
+ const runnerDir = join(repoDir, CONFIG_DIR, RUNNER_DIR);
854
+ const maskDir = join(repoDir, CONFIG_DIR, RUNNER_SANDBOX_MASK_DIR);
855
+ for (const [name, path] of [
856
+ ["repository runner", runnerDir],
857
+ ["repository runner sandbox mask", maskDir]
858
+ ]) {
859
+ const stat2 = lstatSync(path);
860
+ if (stat2.isSymbolicLink() || !stat2.isDirectory()) {
861
+ throw new Error(
862
+ `The protected ${name} path must be a real directory: ${path}`
863
+ );
864
+ }
865
+ }
866
+ if (pathKey(realpathSync(runnerDir)) === pathKey(realpathSync(maskDir))) {
867
+ throw new Error(
868
+ "The protected repository runner and sandbox mask paths must be distinct directories."
869
+ );
870
+ }
871
+ };
872
+ var assertProtectedDirectoryIdentities = async (runnerDir, maskDir, inspect) => {
873
+ if (!inspect) return;
874
+ const runner = await inspect(runnerDir);
875
+ const mask = await inspect(maskDir);
876
+ if (!runner.directory || runner.symbolicLink) {
877
+ throw new Error(
878
+ `The protected repository runner path must be a real directory: ${runnerDir}`
879
+ );
880
+ }
881
+ if (!mask.directory || mask.symbolicLink) {
882
+ throw new Error(
883
+ `The protected repository runner sandbox mask path must be a real directory: ${maskDir}`
884
+ );
885
+ }
886
+ if (pathKey(runner.realPath) === pathKey(mask.realPath)) {
887
+ throw new Error(
888
+ "The protected repository runner and sandbox mask paths must be distinct directories."
889
+ );
890
+ }
891
+ };
892
+
893
+ // src/CopyToWorktree.ts
818
894
  var COPY_TO_WORKTREE_TIMEOUT_MS = 6e4;
819
895
  var getCopyOnWriteFlags = (platform) => platform === "darwin" ? ["-cR"] : ["-R", "--reflink=auto"];
820
896
  var copyToWorktree = (paths, hostRepoDir, worktreePath, timeoutMs) => {
@@ -825,6 +901,7 @@ var copyToWorktree = (paths, hostRepoDir, worktreePath, timeoutMs) => {
825
901
  let src;
826
902
  let dest;
827
903
  try {
904
+ assertExcludesRepositoryRunner(relativePath);
828
905
  src = resolveSafeRelativePath(hostRepoDir, relativePath, "copy path");
829
906
  dest = resolveSafeRelativePath(worktreePath, relativePath, "copy path");
830
907
  } catch (error) {
@@ -1109,7 +1186,35 @@ var syncOut = (hostRepoDir, handle) => Effect.gen(function* () {
1109
1186
  const hasUntracked = lsFilesResult.stdout.length > 0;
1110
1187
  const untrackedFiles = hasUntracked ? lsFilesResult.stdout.split("\0").filter((f) => f.length > 0) : [];
1111
1188
  yield* Effect.try({
1112
- try: () => untrackedFiles.forEach(assertSafeGitWorktreePath),
1189
+ try: () => untrackedFiles.forEach((path) => {
1190
+ assertSafeGitWorktreePath(path);
1191
+ assertExcludesRepositoryRunner(path);
1192
+ }),
1193
+ catch: (error) => new SyncError({ message: String(error) })
1194
+ });
1195
+ const changedPaths = [];
1196
+ if (hasCommits) {
1197
+ const committedNames = yield* execOk(
1198
+ handle,
1199
+ `git diff --name-only -z ${shellQuote(`${base}..HEAD`)}`,
1200
+ { cwd: worktreePath }
1201
+ );
1202
+ changedPaths.push(
1203
+ ...committedNames.stdout.split("\0").filter((path) => path.length > 0)
1204
+ );
1205
+ }
1206
+ if (hasDiff) {
1207
+ const uncommittedNames = yield* execOk(
1208
+ handle,
1209
+ "git diff --name-only -z HEAD",
1210
+ { cwd: worktreePath }
1211
+ );
1212
+ changedPaths.push(
1213
+ ...uncommittedNames.stdout.split("\0").filter((path) => path.length > 0)
1214
+ );
1215
+ }
1216
+ yield* Effect.try({
1217
+ try: () => changedPaths.forEach(assertExcludesRepositoryRunner),
1113
1218
  catch: (error) => new SyncError({ message: String(error) })
1114
1219
  });
1115
1220
  if (!hasCommits && !hasDiff && !hasUntracked) {
@@ -1727,6 +1832,18 @@ ${result.stderr}`
1727
1832
  )
1728
1833
  );
1729
1834
  var syncIn = (hostRepoDir, handle) => Effect.gen(function* () {
1835
+ const protectedRunnerPath = `${CONFIG_DIR}/${RUNNER_DIR}`;
1836
+ const runnerObjects = yield* execHostGit3(
1837
+ ["rev-list", "--objects", "--all", "--", protectedRunnerPath],
1838
+ hostRepoDir
1839
+ );
1840
+ if (runnerObjects.trim().length > 0) {
1841
+ return yield* Effect.fail(
1842
+ new SyncError({
1843
+ message: `Refusing to copy repository history into the sandbox because it contains protected repository runner files under ${protectedRunnerPath}. Remove those files from all refs before retrying.`
1844
+ })
1845
+ );
1846
+ }
1730
1847
  const branch = (yield* execHostGit3(
1731
1848
  ["rev-parse", "--abbrev-ref", "HEAD"],
1732
1849
  hostRepoDir
@@ -1823,12 +1940,33 @@ var startNoSandbox = (options) => Effect.tryPromise({
1823
1940
  );
1824
1941
  var startBindMountSandbox = (options) => Effect.tryPromise({
1825
1942
  try: () => {
1943
+ const usesRunnerMask = options.worktreeOrRepoPath === options.hostRepoDir && existsSync(join(options.hostRepoDir, CONFIG_DIR, RUNNER_DIR)) && existsSync(
1944
+ join(options.hostRepoDir, CONFIG_DIR, RUNNER_SANDBOX_MASK_DIR)
1945
+ );
1946
+ if (usesRunnerMask) {
1947
+ assertSafeRepositoryRunnerDirectories(options.hostRepoDir);
1948
+ }
1826
1949
  const rawMounts = [
1827
1950
  {
1828
1951
  hostPath: options.worktreeOrRepoPath,
1829
1952
  sandboxPath: options.repoDir
1830
1953
  },
1831
- ...options.gitMounts
1954
+ ...options.gitMounts,
1955
+ ...usesRunnerMask ? [
1956
+ {
1957
+ hostPath: join(
1958
+ options.hostRepoDir,
1959
+ CONFIG_DIR,
1960
+ RUNNER_SANDBOX_MASK_DIR
1961
+ ),
1962
+ sandboxPath: posix.join(
1963
+ options.repoDir,
1964
+ CONFIG_DIR,
1965
+ RUNNER_DIR
1966
+ ),
1967
+ readonly: true
1968
+ }
1969
+ ] : []
1832
1970
  ];
1833
1971
  const mounts = normalizeMounts(
1834
1972
  rawMounts,
@@ -1895,6 +2033,7 @@ var startIsolatedSandbox = (options) => Effect.gen(function* () {
1895
2033
  let hostPath;
1896
2034
  let sandboxPath;
1897
2035
  try {
2036
+ assertExcludesRepositoryRunner(relativePath);
1898
2037
  hostPath = resolveSafeRelativePath(
1899
2038
  options.sourceRepoDir ?? options.hostRepoDir,
1900
2039
  relativePath,
@@ -2615,6 +2754,6 @@ var registerShutdown = (teardown) => {
2615
2754
  };
2616
2755
  };
2617
2756
 
2618
- export { AgentError, AgentIdleTimeoutError, CLI_NAME, CONFIG_DIR, ClackDisplay, ConfigDirError, CwdError, Display, DockerError, ExecHostError, FileDisplay, InitError, LOCKS_DIR, LOGS_DIR, PRODUCT_NAME, PromptError, PromptExpansionTimeoutError, SANDBOX_REPO_DIR, SandboxConfig, SandboxFactory, SessionCaptureError, SilentDisplay, WorktreeDockerSandboxFactory, assertIsolatedWorkspaceMounts, assertNoSymlinkComponents, copyToWorktree, create, defaultImageName, formatVolumeMount, generateTempBranchName, getCurrentBranch, hasUncommittedChanges, makeSandboxFromHandle, patchGitMountsForWindows, processFileMountParents, pruneStale, registerShutdown, remove, resolveCwd, resolveGitMounts, resolveUserMounts, runHostHooks, startSandbox, syncOut, withSandboxLifecycle };
2619
- //# sourceMappingURL=chunk-2GT3OPO5.js.map
2620
- //# sourceMappingURL=chunk-2GT3OPO5.js.map
2757
+ export { ACTIVATION_LABEL, AgentError, AgentIdleTimeoutError, CLI_NAME, CONFIG_DIR, ClackDisplay, ConfigDirError, CwdError, Display, DockerError, ExecHostError, FileDisplay, InitError, LOCKS_DIR, LOGS_DIR, PRODUCT_NAME, PromptError, PromptExpansionTimeoutError, RUNNER_DIR, RUNNER_SANDBOX_MASK_DIR, SANDBOX_REPO_DIR, SandboxConfig, SandboxFactory, SessionCaptureError, SilentDisplay, WorktreeDockerSandboxFactory, assertIsolatedWorkspaceMounts, assertNoSymlinkComponents, assertProtectedDirectoryIdentities, copyToWorktree, create, defaultImageName, formatVolumeMount, generateTempBranchName, getCurrentBranch, hasUncommittedChanges, makeSandboxFromHandle, patchGitMountsForWindows, processFileMountParents, pruneStale, registerShutdown, remove, repositoryRunnerEnvironment, resolveCwd, resolveGitMounts, resolveUserMounts, runHostHooks, startSandbox, syncOut, withSandboxLifecycle };
2758
+ //# sourceMappingURL=chunk-KPJFCYX5.js.map
2759
+ //# sourceMappingURL=chunk-KPJFCYX5.js.map