import { execFile } from 'node:child_process' import { existsSync } from 'node:fs' import { chmod, mkdir, mkdtemp, readFile, rm, writeFile } from 'node:fs/promises' import { tmpdir } from 'node:os' import { delimiter, join, resolve } from 'node:path' import { promisify } from 'node:util' import { describe, expect, it } from 'vitest' const run = promisify(execFile) const referenceRoot = resolve( import.meta.dirname, '../../skill-guides/orca-per-workspace-env/references' ) const vercel = await readFile(resolve(referenceRoot, 'provider-vercel.md'), 'utf8') const ssh = await readFile(resolve(referenceRoot, 'ssh-host.md'), 'utf8') const cleanup = vercel.match(/```bash\n(cleanup_snapshot\(\) \{[\s\S]*?\n\})\n```/u)?.[1] async function executeShell(shell, script, env = {}) { try { const output = await run(shell, ['-c', script], { env: { ...process.env, ORCA_BACKGROUND_LAUNCH: '1', ...env } }) return { ...output, code: 0 } } catch (error) { return { stdout: error.stdout, stderr: error.stderr, code: error.code } } } // Stock macOS Bash must run even when PATH starts with a newer Bash. const shells = existsSync('/bin/bash') ? ['/bin/bash', 'bash'] : ['bash'] describe.skipIf(process.platform === 'win32').each(shells)( 'recipe shell examples (%s)', (shell) => { const runShell = (script, env) => executeShell(shell, script, env) it.each(['base', 'auth'])('cleans the %s sandbox on failure and success', async (phase) => { expect(cleanup).toBeDefined() const trap = vercel.match(new RegExp(`trap 'cleanup_snapshot "\\$${phase}"' EXIT`, 'u'))?.[0] expect(trap).toBeDefined() expect(vercel.indexOf(trap)).toBeLessThan( vercel.indexOf(`vercel sandbox create --name "$${phase}"`) ) for (const exitCode of [0, 7]) { const result = await runShell(`set -euo pipefail ${cleanup} vercel_args=(--scope test-scope) ${phase}=unique-test-sandbox vercel() { printf '%s\\n' "$@"; } ${trap} exit ${exitCode}`) expect(result.code).toBe(exitCode) expect(result.stderr).toBe('sandbox\nremove\nunique-test-sandbox\n--scope\ntest-scope\n') } }) it('reports failed cleanup even after an otherwise successful snapshot', async () => { const result = await runShell(`set -euo pipefail ${cleanup} vercel_args=() vercel() { return 9; } trap 'cleanup_snapshot unique-test-sandbox' EXIT exit 0`) expect(result.code).toBe(1) expect(result.stderr).toContain('Sandbox cleanup failed for unique-test-sandbox') }) it.each([ { scope: '', project: '' }, { scope: 'scope with spaces *', project: '' }, { scope: '', project: 'project with spaces ?' }, { scope: 'scope with spaces *', project: 'project with spaces ?' } ])( 'runs the full create recipe with scope "$scope" and project "$project"', async ({ scope, project }) => { const result = await runCreateRecipe(shell, { VERCEL_SCOPE: scope, VERCEL_PROJECT: project }) expect(result.code).toBe(0) const output = JSON.parse(result.stdout) expect(output.userData).toMatchObject({ provider: 'vercel-sandbox', resourceId: 'orca-fixture-123', snapshotId: 'snap_fixture' }) expect(result.calls.map((args) => args.slice(0, 2))).toEqual([ ['sandbox', 'create'], ['sandbox', 'exec'], ['sandbox', 'exec'] ]) const expectedFlags = [ ...(scope ? ['--scope', scope] : []), ...(project ? ['--project', project] : []) ] for (const args of result.calls) { const start = args.findIndex((arg) => arg === '--scope' || arg === '--project') if (expectedFlags.length) { expect(args.slice(start, start + expectedFlags.length)).toEqual(expectedFlags) } else { expect(start).toBe(-1) } expect(args).not.toContain('') } } ) it('removes a failed create with no optional flags', async () => { const result = await runCreateRecipe(shell, { VERCEL_CREATE_EXIT: '7' }) expect(result.code).toBe(7) expect(result.calls.map((args) => args.slice(0, 2))).toEqual([ ['sandbox', 'create'], ['sandbox', 'remove'] ]) expect(result.calls[1]).toEqual(['sandbox', 'remove', 'orca-fixture-123']) expect(result.stderr).not.toContain('unbound variable') }) it('disables Git prompts when the Vercel token is absent', async () => { const prefix = vercel.match( /-- bash -lc 'set -euo pipefail; cd "\$ORCA_PROJECT_ROOT"; \\\n([\s\S]*?) git fetch/u )?.[1] expect(prefix).toBeDefined() const result = await runShell( `set -euo pipefail\nunset GH_TOKEN\n${prefix}\nprintf '%s' "$GIT_TERMINAL_PROMPT"` ) expect(result.code).toBe(0) expect(result.stdout).toBe('0') }) it('uses host credentials and refuses unverified SSH hosts without forwarding tokens', async () => { const script = ssh.match(/```bash\n(#!\/usr\/bin\/env bash[\s\S]*?)\n```/u)?.[1] expect(script).toBeDefined() const sync = script.slice(0, script.indexOf('# 2. print')) const result = await runShell( `ssh() { printf '%s\\n' "$@"; } ssh_username=worker host=example.test ssh_port=2222 project_root='/remote/path with spaces' repo_url=https://example.test/org/repo.git repo_ref=main ${sync}`, { GH_TOKEN: 'test-token-must-not-be-forwarded' } ) expect(result.code).toBe(0) expect(result.stderr).toContain('StrictHostKeyChecking=yes') expect(result.stderr).toContain('BatchMode=yes') expect(result.stderr).not.toContain('test-token-must-not-be-forwarded') expect(result.stderr).not.toContain('GH_TOKEN=') expect(script).toContain('export GIT_TERMINAL_PROMPT=0') }) } ) async function runCreateRecipe(shell, overrides) { const script = vercel.match(/```bash\n(#!\/usr\/bin\/env bash[\s\S]*?)\n```/u)?.[1] expect(script).toBeDefined() const directory = await mkdtemp(join(tmpdir(), 'orca-vercel-recipe-')) const bin = join(directory, 'bin') const log = join(directory, 'calls.jsonl') try { await mkdir(bin) const command = join(bin, 'vercel') await writeFile( command, `#!/usr/bin/env node const { appendFileSync } = require('node:fs') const args = process.argv.slice(2) appendFileSync(process.env.VERCEL_FIXTURE_LOG, JSON.stringify(args) + '\\n') if (args[1] === 'create') { if (process.env.VERCEL_CREATE_EXIT) process.exit(Number(process.env.VERCEL_CREATE_EXIT)) console.log('https://fixture.vercel.run') } else if (args[1] === 'exec' && args.includes('60s')) { console.log(JSON.stringify({ userData: {} })) } ` ) await chmod(command, 0o755) const result = await executeShell( shell, `scope="$VERCEL_SCOPE"; project="$VERCEL_PROJECT" snapshot_id=snap_fixture; port=6768; repo_url=https://example.test/repo.git; repo_ref=main; project_root='/fixture repo' ${script}`, { PATH: `${bin}${delimiter}${process.env.PATH}`, VERCEL_FIXTURE_LOG: log, VERCEL_SCOPE: '', VERCEL_PROJECT: '', VERCEL_CREATE_EXIT: '', GH_TOKEN: 'fixture-token', ORCA_RECIPE_ID: 'fixture', ORCA_VM_INSTANCE_ID: '123', ...overrides } ) const calls = (await readFile(log, 'utf8')) .trim() .split('\n') .map((line) => JSON.parse(line)) return { ...result, calls } } finally { await rm(directory, { recursive: true, force: true }) } }