@autoclawd/autocode 0.4.0 → 0.4.1

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/index.js CHANGED
@@ -875,6 +875,8 @@ function buildPrompt(ticket, repoPrompt) {
875
875
  parts.push('- After making changes, run: git add -A && git commit -m "description of changes"');
876
876
  parts.push("- Commit after each logical step (do not batch all changes into one commit)");
877
877
  parts.push("- If the task has a checklist, work through items in order and commit after each one");
878
+ parts.push("- Tests MUST import from the actual source modules \u2014 never re-implement or duplicate source code in tests");
879
+ parts.push("- If the project uses TypeScript but tests are plain JS, install tsx or ts-node so tests can import .ts files");
878
880
  parts.push("- Run any existing tests before finishing to verify your changes");
879
881
  parts.push("- IMPORTANT: You MUST commit your changes with git before finishing");
880
882
  parts.push("- When all work is complete and committed, include [autocode:done] in your final output");
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/index.ts","../src/config.ts","../src/linear.ts","../src/logger.ts","../src/github.ts","../src/webhook.ts","../src/docker.ts","../src/agent.ts","../src/git.ts","../src/worker.ts","../src/tunnel.ts","../src/deps.ts"],"sourcesContent":["import { Command } from 'commander';\nimport { loadConfig, CONFIG_DIR, CONFIG_FILE } from './config.js';\nimport { createLinearClient, fetchTicket } from './linear.js';\nimport { createOctokit } from './github.js';\nimport { WebhookServer } from './webhook.js';\nimport { startQuickTunnel, stopTunnel } from './tunnel.js';\nimport type { TunnelInfo } from './tunnel.js';\nimport { executeTicket } from './worker.js';\nimport { checkDockerAvailable, cleanupOrphanedContainers } from './docker.js';\nimport { log, setLogLevel, enableFileLogging } from './logger.js';\nimport { checkDeps, installDep, addUserToDockerGroup } from './deps.js';\nimport { existsSync, mkdirSync, writeFileSync } from 'node:fs';\nimport { execSync } from 'node:child_process';\nimport { createInterface } from 'node:readline';\nimport { join } from 'node:path';\nimport { homedir } from 'node:os';\nimport { LinearClient } from '@linear/sdk';\nimport { Octokit } from '@octokit/rest';\n\nimport { createRequire } from 'node:module';\nconst require = createRequire(import.meta.url);\nconst pkg = require('../package.json') as { version: string };\n\nconst program = new Command();\n\nprogram\n .name('autocode')\n .description('Linear webhooks → Claude Code in Docker → PRs')\n .version(pkg.version);\n\n// --- Helper: prompt user for input ---\nfunction ask(question: string, defaultVal?: string): Promise<string> {\n const rl = createInterface({ input: process.stdin, output: process.stdout });\n const hint = defaultVal ? ` (${defaultVal})` : '';\n return new Promise((resolve) => {\n rl.question(`${question}${hint}: `, (answer) => {\n rl.close();\n resolve(answer.trim() || defaultVal || '');\n });\n });\n}\n\n// --- serve ---\nprogram\n .command('serve')\n .description('Start webhook server with auto-tunnel')\n .option('-c, --config <path>', 'Config file path')\n .option('-p, --port <number>', 'Override webhook port')\n .option('--no-tunnel', 'Skip auto-tunnel (use if you have your own reverse proxy)')\n .option('-v, --verbose', 'Verbose logging')\n .action(async (opts) => {\n if (opts.verbose) setLogLevel('debug');\n\n enableFileLogging();\n log.info(`autocode v${pkg.version}`);\n await checkDockerAvailable();\n if (!checkClaudeCredentials()) {\n throw new Error(\n 'Claude Code credentials not found (~/.claude/.credentials.json)\\n'\n + 'Run: claude (and complete login) to create credentials'\n );\n }\n\n // Clean up any orphaned containers from previous runs\n const orphans = await cleanupOrphanedContainers();\n if (orphans > 0) {\n log.info(`Cleaned up ${orphans} orphaned container(s) from previous session`);\n }\n const config = loadConfig(opts.config);\n if (opts.port) config.webhook.port = parseInt(opts.port);\n\n log.info(`Team: ${config.linear.teamId} | Statuses: ${config.linear.statuses.join(', ')} | Model: ${config.agent.model} | Max concurrent: ${config.maxConcurrent}`);\n\n const linearClient = createLinearClient(config);\n const octokit = createOctokit(config);\n\n const server = new WebhookServer(config, linearClient, octokit);\n\n let tunnel: TunnelInfo | undefined;\n\n // Start tunnel if enabled\n if (opts.tunnel !== false) {\n log.info('Starting tunnel...');\n try {\n tunnel = await startQuickTunnel(config.webhook.port);\n const webhookUrl = `${tunnel.url}/api/v1/linear/webhook`;\n log.success(`Tunnel: ${tunnel.url}`);\n log.info(`Webhook URL: ${webhookUrl}`);\n\n // Update the Linear webhook if we have a webhookId stored\n if (config.webhook.webhookId) {\n try {\n await linearClient.deleteWebhook(config.webhook.webhookId);\n } catch {\n // Old webhook may already be gone\n }\n }\n\n // Resolve team UUID from key\n const team = await linearClient.team(config.linear.teamId);\n\n // Create/update Linear webhook with new tunnel URL\n const result = await linearClient.createWebhook({\n url: webhookUrl,\n resourceTypes: ['Issue'],\n label: 'autocode',\n teamId: team.id,\n });\n const webhook = await result.webhook;\n if (webhook) {\n log.success(`Linear webhook created → ${webhookUrl}`);\n // Store webhook ID and secret for next time\n config.webhook.webhookId = webhook.id;\n // Note: the signing secret is set when creating via API - we disable verification for auto-created webhooks\n config.webhook.signingSecret = undefined;\n }\n } catch (err) {\n log.warn(`Tunnel failed: ${err instanceof Error ? err.message : err}`);\n log.info('Falling back to local-only mode. Set up your own reverse proxy.');\n }\n }\n\n await server.start();\n\n const shutdown = () => {\n log.info('Shutting down...');\n server.stop();\n if (tunnel) stopTunnel(tunnel);\n process.exit(0);\n };\n process.on('SIGINT', shutdown);\n process.on('SIGTERM', shutdown);\n });\n\n// --- run ---\nprogram\n .command('run <ticket>')\n .description('Run a single ticket (e.g. autocode run RAH-123)')\n .option('-c, --config <path>', 'Config file path')\n .option('-v, --verbose', 'Verbose logging')\n .option('--dry-run', 'Show what would happen without executing')\n .action(async (ticketId: string, opts) => {\n if (opts.verbose) setLogLevel('debug');\n enableFileLogging();\n\n const config = loadConfig(opts.config);\n const linearClient = createLinearClient(config);\n\n const ticket = await fetchTicket(linearClient, ticketId);\n if (!ticket) throw new Error(`Ticket ${ticketId} not found`);\n if (!ticket.repoUrl) {\n throw new Error(`${ticketId} has no repo: label. Add \"repo:owner/name\" label to the ticket.`);\n }\n\n if (opts.dryRun) {\n log.info('Dry run — no changes will be made\\n');\n log.info(` Ticket: ${ticket.identifier} — ${ticket.title}`);\n log.info(` Repo: ${ticket.repoUrl}`);\n log.info(` Base: ${ticket.baseBranch ?? '(from .autocode.yaml or main)'}`);\n log.info(` Branch: autocode/${ticket.identifier}-...`);\n log.info(` Image: ${config.docker.image}`);\n log.info(` Model: ${config.agent.model}`);\n log.info(` Max iter: ${config.agent.maxIterations}`);\n if (ticket.description) {\n log.info(`\\n Description:\\n ${ticket.description.split('\\n').join('\\n ')}`);\n }\n return;\n }\n\n await checkDockerAvailable();\n if (!checkClaudeCredentials()) {\n throw new Error(\n 'Claude Code credentials not found (~/.claude/.credentials.json)\\n'\n + 'Run: claude (and complete login) to create credentials'\n );\n }\n const octokit = createOctokit(config);\n\n // Let the worker's finally block clean up containers on signals\n const abort = new AbortController();\n const onSignal = () => {\n log.info('Received signal, cleaning up...');\n abort.abort();\n };\n process.on('SIGINT', onSignal);\n process.on('SIGTERM', onSignal);\n\n try {\n const result = await executeTicket({ ticket, config, linearClient, octokit });\n if (!result.success) throw new Error(result.error ?? 'Unknown failure');\n } finally {\n process.off('SIGINT', onSignal);\n process.off('SIGTERM', onSignal);\n }\n });\n\n// --- validate ---\nprogram\n .command('validate')\n .description('Validate config without running anything')\n .option('-c, --config <path>', 'Config file path')\n .action(async (opts) => {\n try {\n const config = loadConfig(opts.config);\n log.success('Config is valid');\n log.info(` Linear team: ${config.linear.teamId}`);\n log.info(` Trigger statuses: ${config.linear.statuses.join(', ')}`);\n log.info(` Docker image: ${config.docker.image}`);\n log.info(` Agent model: ${config.agent.model}`);\n log.info(` Max iterations: ${config.agent.maxIterations}`);\n log.info(` Max concurrent: ${config.maxConcurrent}`);\n log.info(` Webhook port: ${config.webhook.port}`);\n } catch (err) {\n log.error(err instanceof Error ? err.message : String(err));\n process.exit(1);\n }\n });\n\n// --- cleanup ---\nprogram\n .command('cleanup')\n .description('Remove orphaned autocode Docker containers')\n .action(async () => {\n await checkDockerAvailable();\n const count = await cleanupOrphanedContainers();\n if (count === 0) {\n log.info('No orphaned containers found');\n } else {\n log.success(`Cleaned up ${count} orphaned container(s)`);\n }\n });\n\n// --- Runtime checks ---\nfunction checkClaudeCredentials(): boolean {\n return existsSync(join(homedir(), '.claude', '.credentials.json'));\n}\n\nasync function validateGitHubToken(token: string): Promise<string | undefined> {\n try {\n const octokit = new Octokit({ auth: token });\n const { data } = await octokit.rest.users.getAuthenticated();\n return data.login;\n } catch {\n return undefined;\n }\n}\n\n// --- init ---\nprogram\n .command('init')\n .description('Set up autocode interactively')\n .action(async () => {\n console.log('\\n autocode setup\\n');\n\n // Preflight: check and install prerequisites\n console.log(' Checking dependencies...\\n');\n const deps = checkDeps();\n const stillMissing: string[] = [];\n\n for (const dep of deps) {\n if (dep.installed && dep.running !== false) {\n log.success(`${dep.name}`);\n continue;\n }\n\n if (dep.installed && dep.running === false) {\n log.warn(`${dep.name} — installed but not running`);\n stillMissing.push(`${dep.name} (needs restart)`);\n continue;\n }\n\n // Not installed — offer to install if possible\n if (dep.installable && dep.installCommands.length > 0) {\n const answer = await ask(` ${dep.name} not found. Install? (Y/n)`, 'Y');\n\n if (answer.toLowerCase() !== 'n') {\n console.log(`\\n Installing ${dep.name} via system package manager...\\n`);\n const ok = installDep(dep);\n if (ok) {\n log.success(`${dep.name} installed`);\n if (dep.name === 'Docker') addUserToDockerGroup();\n if (dep.name === 'Claude Code') {\n console.log('\\n Run \"claude\" in your terminal to log in, then re-run: autocode init\\n');\n stillMissing.push('Claude Code login');\n }\n } else {\n log.error(`${dep.name} install failed`);\n console.log(` Install manually: ${dep.manualInstructions}`);\n stillMissing.push(dep.name);\n }\n } else {\n console.log(` Install manually: ${dep.manualInstructions}`);\n stillMissing.push(dep.name);\n }\n } else if (dep.name === 'Claude credentials') {\n log.warn(`${dep.name} — run \"claude\" to log in`);\n stillMissing.push(dep.name);\n } else {\n log.warn(`${dep.name} — ${dep.manualInstructions}`);\n stillMissing.push(dep.name);\n }\n }\n\n if (stillMissing.length > 0) {\n console.log(`\\n Continuing setup — install ${stillMissing.join(', ')} before running.\\n`);\n } else {\n console.log('');\n }\n\n if (!existsSync(CONFIG_DIR)) {\n mkdirSync(CONFIG_DIR, { recursive: true });\n }\n\n if (existsSync(CONFIG_FILE)) {\n const overwrite = await ask('Config already exists. Overwrite? (y/N)', 'N');\n if (overwrite.toLowerCase() !== 'y') {\n log.info('Keeping existing config.');\n return;\n }\n }\n\n // 1. Linear API key\n const linearKey = await ask('Linear API key', process.env.LINEAR_API_KEY);\n if (!linearKey) {\n log.error('Linear API key is required');\n process.exit(1);\n }\n\n // Validate and get teams\n let teamId = '';\n try {\n const client = new LinearClient({ apiKey: linearKey });\n const teams = await client.teams();\n if (teams.nodes.length === 0) {\n log.error('No teams found in your Linear workspace');\n process.exit(1);\n }\n if (teams.nodes.length === 1) {\n teamId = teams.nodes[0].key;\n log.success(`Linear team: ${teams.nodes[0].name} (${teamId})`);\n } else {\n console.log('\\n Available teams:');\n for (const t of teams.nodes) {\n console.log(` ${t.key} — ${t.name}`);\n }\n teamId = await ask('\\n Team key');\n }\n } catch (err) {\n log.error(`Invalid Linear API key: ${err instanceof Error ? err.message : err}`);\n process.exit(1);\n }\n\n // 2. GitHub token\n let ghToken = '';\n try {\n ghToken = execSync('gh auth token', { encoding: 'utf-8' }).trim();\n log.success(`GitHub token detected from gh CLI`);\n } catch {\n ghToken = await ask('GitHub personal access token');\n }\n if (!ghToken) {\n log.error('GitHub token is required');\n process.exit(1);\n }\n\n // Validate the GitHub token\n const ghUser = await validateGitHubToken(ghToken);\n if (ghUser) {\n log.success(`GitHub authenticated as ${ghUser}`);\n } else {\n log.error('GitHub token is invalid or expired');\n process.exit(1);\n }\n\n // 3. Docker image\n console.log('\\n Docker image options:');\n console.log(' autocode-base — All runtimes: Node, Python, Go, Rust, Ruby (~1.5GB)');\n console.log(' Works with any repo, no per-repo config needed');\n console.log(' node:20 — Node.js only (fast, ~300MB)');\n const dockerImage = await ask('Docker image', 'autocode-base');\n\n if (dockerImage === 'autocode-base') {\n try {\n execSync('docker image inspect autocode-base', { stdio: 'pipe' });\n log.success('autocode-base image found');\n } catch {\n log.info('autocode-base will be built automatically on first run (~3 min)');\n }\n }\n\n // 4. Agent config\n const model = await ask('Claude model', 'claude-sonnet-4-6');\n const maxIter = await ask('Max iterations per ticket', '10');\n\n // 4. Write config\n // Tip: to avoid storing secrets in the file, you can replace values\n // with env:VAR_NAME (e.g. env:LINEAR_API_KEY). autocode resolves\n // these from the environment at runtime.\n const config = `# autocode config — generated by autocode init\n# Tip: use \"env:VAR_NAME\" to read secrets from environment variables\n# e.g. apiKey: env:LINEAR_API_KEY\n\nlinear:\n apiKey: \"${linearKey}\"\n teamId: ${teamId}\n statuses: [Todo]\n assignToMe: false\n inProgressStatus: In Progress\n doneStatus: Done\n\ngithub:\n token: \"${ghToken}\"\n\nwebhook:\n port: 3000\n\ndocker:\n image: ${dockerImage}\n memory: 4g\n\nagent:\n model: ${model}\n maxIterations: ${parseInt(maxIter) || 10}\n\nmaxConcurrent: 1\n`;\n\n writeFileSync(CONFIG_FILE, config, { mode: 0o600 });\n log.success(`Config saved to ${CONFIG_FILE}`);\n\n console.log(`\n Setup complete! Next steps:\n\n 1. Add repo: labels to your Linear team\n (e.g. \"repo:your-org/your-repo\")\n\n 2. Tag tickets with a repo: label\n\n 3. Start autocode:\n $ autocode serve\n\n autocode serve will auto-create a tunnel and\n register the webhook with Linear. Just run it.\n`);\n });\n\n// Catch errors at CLI boundary\nprogram.parseAsync().catch((err) => {\n log.error(err instanceof Error ? err.message : String(err));\n process.exit(1);\n});\n","import { z } from 'zod';\nimport { readFileSync, existsSync } from 'node:fs';\nimport { join } from 'node:path';\nimport { homedir } from 'node:os';\nimport yaml from 'js-yaml';\n\n// --- Schema ---\n\n// Host config (~/.autocode/config.yaml) — just tokens + global defaults\nconst AgentConfigSchema = z.object({\n model: z.string().default('claude-sonnet-4-6'),\n maxIterations: z.number().min(1).max(50).default(10),\n timeout: z.number().optional(),\n});\n\nconst DockerConfigSchema = z.object({\n image: z.string().default('node:20'),\n memory: z.string().default('4g'),\n cpus: z.number().optional(),\n setup: z.array(z.string()).optional(), // Shell commands to run before Claude Code\n volumes: z.array(z.string()).optional(), // Extra bind mounts, e.g. [\"~/.ssh:/home/autocode/.ssh:ro\"]\n network: z.enum(['bridge', 'host', 'none']).default('bridge'), // Container network mode\n});\n\nconst LinearConfigSchema = z.object({\n apiKey: z.string(),\n teamId: z.string(),\n statuses: z.array(z.string()).default(['Todo']),\n assignToMe: z.boolean().default(true),\n doneStatus: z.string().default('Done'),\n inProgressStatus: z.string().default('In Progress'),\n});\n\nconst GitHubConfigSchema = z.object({\n token: z.string(),\n});\n\nconst WebhookConfigSchema = z.object({\n port: z.number().default(3000),\n url: z.string().optional(),\n signingSecret: z.string().optional(),\n webhookId: z.string().optional(),\n});\n\nconst ConfigSchema = z.object({\n linear: LinearConfigSchema,\n github: GitHubConfigSchema,\n docker: DockerConfigSchema.default({}),\n agent: AgentConfigSchema.default({}),\n webhook: WebhookConfigSchema.default({}),\n maxConcurrent: z.number().default(1),\n});\n\nexport type Config = z.infer<typeof ConfigSchema>;\nexport type AgentConfig = z.infer<typeof AgentConfigSchema>;\nexport type DockerConfig = z.infer<typeof DockerConfigSchema>;\n\n// Per-repo config (.autocode.yaml in repo root) — loaded after clone\nconst RepoLocalConfigSchema = z.object({\n prompt: z.string().optional(),\n base: z.string().default('main'),\n agent: AgentConfigSchema.partial().optional(),\n docker: DockerConfigSchema.partial().optional(),\n});\n\nexport type RepoLocalConfig = z.infer<typeof RepoLocalConfigSchema>;\n\n// --- Loader ---\n\nfunction resolveEnvVars(obj: unknown): unknown {\n if (typeof obj === 'string') {\n if (obj.startsWith('env:')) {\n const envName = obj.slice(4);\n const val = process.env[envName];\n if (!val) throw new Error(`Environment variable ${envName} is not set`);\n return val;\n }\n return obj;\n }\n if (Array.isArray(obj)) return obj.map(resolveEnvVars);\n if (obj && typeof obj === 'object') {\n return Object.fromEntries(\n Object.entries(obj as Record<string, unknown>).map(([k, v]) => [k, resolveEnvVars(v)])\n );\n }\n return obj;\n}\n\nconst CONFIG_DIR = join(homedir(), '.autocode');\nconst CONFIG_FILE = join(CONFIG_DIR, 'config.yaml');\n\nexport function loadConfig(path?: string): Config {\n const configPath = path ?? CONFIG_FILE;\n if (!existsSync(configPath)) {\n throw new Error(`Config not found: ${configPath}\\nRun: autocode init`);\n }\n const content = readFileSync(configPath, 'utf-8');\n const raw = yaml.load(content);\n if (!raw || typeof raw !== 'object') {\n throw new Error(`Config file is empty or invalid: ${configPath}`);\n }\n const resolved = resolveEnvVars(raw);\n const result = ConfigSchema.safeParse(resolved);\n if (!result.success) {\n const issues = result.error.issues.map(\n (i) => ` - ${i.path.join('.')}: ${i.message}`\n ).join('\\n');\n throw new Error(`Invalid config (${configPath}):\\n${issues}`);\n }\n return result.data;\n}\n\nexport function loadRepoLocalConfig(workspacePath: string): RepoLocalConfig | undefined {\n // Support both .yaml and .yml extensions\n const yamlPath = join(workspacePath, '.autocode.yaml');\n const ymlPath = join(workspacePath, '.autocode.yml');\n const configPath = existsSync(yamlPath) ? yamlPath : existsSync(ymlPath) ? ymlPath : undefined;\n if (!configPath) return undefined;\n const raw = yaml.load(readFileSync(configPath, 'utf-8'));\n if (!raw || typeof raw !== 'object') return undefined;\n return RepoLocalConfigSchema.parse(raw);\n}\n\nexport function mergeConfigs(host: Config, local?: RepoLocalConfig): {\n agent: AgentConfig;\n docker: DockerConfig;\n prompt?: string;\n} {\n const agent = AgentConfigSchema.parse({\n ...host.agent,\n ...local?.agent,\n });\n\n const docker = DockerConfigSchema.parse({\n ...host.docker,\n ...local?.docker,\n });\n\n return { agent, docker, prompt: local?.prompt };\n}\n\n// Parse repo from Linear label like \"repo:owner/name\" or \"repo:https://github.com/owner/name\"\nexport function parseRepoFromLabels(labels: string[]): string | undefined {\n for (const label of labels) {\n // \"repo:owner/name\" format\n const match = label.match(/^repo:(.+)/i);\n if (match) {\n const value = match[1].trim();\n // Already a full URL\n if (value.startsWith('https://')) return value;\n // owner/name → full URL\n if (value.includes('/')) return `https://github.com/${value}`;\n }\n }\n return undefined;\n}\n\n// Parse base branch override from labels like \"base:feature-branch\" or \"base:autocode/T-123-fix\"\n// This enables stacked diffs: ticket B can branch from ticket A's PR branch\nexport function parseBaseFromLabels(labels: string[]): string | undefined {\n for (const label of labels) {\n const match = label.match(/^base:(.+)/i);\n if (match) {\n return match[1].trim();\n }\n }\n return undefined;\n}\n\nexport { CONFIG_DIR, CONFIG_FILE };\n","import { LinearClient } from '@linear/sdk';\nimport type { Config } from './config.js';\nimport { parseRepoFromLabels, parseBaseFromLabels } from './config.js';\nimport { log } from './logger.js';\n\nexport interface Ticket {\n id: string; // Linear issue UUID\n identifier: string; // e.g. \"RAH-123\"\n title: string;\n description: string;\n labels: string[];\n repoUrl?: string; // resolved from \"repo:owner/name\" label\n baseBranch?: string; // resolved from \"base:branch-name\" label (for stacked diffs)\n url: string;\n}\n\nexport function createLinearClient(config: Config): LinearClient {\n return new LinearClient({ apiKey: config.linear.apiKey });\n}\n\nexport async function pollTickets(client: LinearClient, config: Config): Promise<Ticket[]> {\n const team = await client.team(config.linear.teamId);\n const issues = await team.issues({\n filter: {\n state: { name: { in: config.linear.statuses } },\n assignee: config.linear.assignToMe ? { isMe: { eq: true } } : undefined,\n },\n first: 50,\n });\n\n const tickets: Ticket[] = [];\n for (const issue of issues.nodes) {\n const labels = await issue.labels();\n const labelNames = labels.nodes.map((l) => l.name);\n const repoUrl = parseRepoFromLabels(labelNames);\n const baseBranch = parseBaseFromLabels(labelNames);\n\n tickets.push({\n id: issue.id,\n identifier: issue.identifier,\n title: issue.title,\n description: issue.description ?? '',\n labels: labelNames,\n repoUrl,\n baseBranch,\n url: issue.url,\n });\n }\n\n return tickets;\n}\n\nexport async function fetchTicket(client: LinearClient, identifier: string): Promise<Ticket | undefined> {\n // Parse team key and number from identifier (e.g. \"RAH-249\", \"rah-249\")\n const match = identifier.match(/^([A-Za-z]+)-(\\d+)$/);\n if (!match) return undefined;\n const [, teamKey, numStr] = match;\n const normalizedKey = teamKey.toUpperCase();\n\n // Fetch via team issues filtered by number\n const team = await client.team(normalizedKey);\n const result = await team.issues({\n filter: { number: { eq: parseInt(numStr) } },\n first: 1,\n });\n const issue = result.nodes[0];\n if (!issue) return undefined;\n\n const labels = await issue.labels();\n const labelNames = labels.nodes.map((l) => l.name);\n const repoUrl = parseRepoFromLabels(labelNames);\n const baseBranch = parseBaseFromLabels(labelNames);\n\n return {\n id: issue.id,\n identifier: issue.identifier,\n title: issue.title,\n description: issue.description ?? '',\n labels: labelNames,\n repoUrl,\n baseBranch,\n url: issue.url,\n };\n}\n\nexport async function claimTicket(\n client: LinearClient,\n config: Config,\n ticketId: string\n): Promise<void> {\n log.info(`Claiming ticket, moving to \"${config.linear.inProgressStatus}\"`);\n\n const team = await client.team(config.linear.teamId);\n const states = await team.states();\n const target = config.linear.inProgressStatus.toLowerCase();\n const inProgress = states.nodes.find((s) => s.name.toLowerCase() === target);\n if (!inProgress) {\n log.warn(`State \"${config.linear.inProgressStatus}\" not found, skipping status update`);\n return;\n }\n\n await client.updateIssue(ticketId, { stateId: inProgress.id });\n}\n\nexport async function completeTicket(\n client: LinearClient,\n config: Config,\n ticketId: string,\n comment: string\n): Promise<void> {\n await client.createComment({ issueId: ticketId, body: comment });\n\n const team = await client.team(config.linear.teamId);\n const states = await team.states();\n const doneTarget = config.linear.doneStatus.toLowerCase();\n const done = states.nodes.find((s) => s.name.toLowerCase() === doneTarget);\n if (done) {\n await client.updateIssue(ticketId, { stateId: done.id });\n }\n}\n\nexport async function addBranchLabel(\n client: LinearClient,\n ticketId: string,\n branchName: string,\n): Promise<void> {\n try {\n // Create/find a label with the branch name so child tickets can stack on it\n const issue = await client.issue(ticketId);\n const team = await issue.team;\n if (!team) return;\n\n // Check if label already exists on this team\n const teamLabels = await team.labels();\n const labelName = `base:${branchName}`;\n let labelId = teamLabels.nodes.find(l => l.name === labelName)?.id;\n\n if (!labelId) {\n // Create the label on the team\n const result = await client.createIssueLabel({\n name: labelName,\n teamId: team.id,\n });\n const label = await result.issueLabel;\n labelId = label?.id;\n }\n\n if (labelId) {\n // Add label to the issue\n const currentLabels = await issue.labels();\n const labelIds = currentLabels.nodes.map(l => l.id);\n if (!labelIds.includes(labelId)) {\n await client.updateIssue(ticketId, {\n labelIds: [...labelIds, labelId],\n });\n log.info(`Added \"base:${branchName}\" label to ticket for stacked diffs`);\n }\n }\n } catch (err) {\n // Non-critical — log and continue\n log.debug(`Could not add branch label: ${err instanceof Error ? err.message : err}`);\n }\n}\n\nexport async function failTicket(\n client: LinearClient,\n ticketId: string,\n reason: string\n): Promise<void> {\n await client.createComment({\n issueId: ticketId,\n body: `**autocode failed:**\\n\\n${reason}`,\n });\n}\n","import chalk from 'chalk';\nimport { appendFileSync, mkdirSync, existsSync } from 'node:fs';\nimport { join } from 'node:path';\nimport { homedir } from 'node:os';\n\nexport type LogLevel = 'debug' | 'info' | 'warn' | 'error';\n\nlet currentLevel: LogLevel = 'info';\nlet logFilePath: string | undefined;\n\nconst levels: Record<LogLevel, number> = {\n debug: 0,\n info: 1,\n warn: 2,\n error: 3,\n};\n\nexport function setLogLevel(level: LogLevel): void {\n currentLevel = level;\n}\n\nexport function enableFileLogging(): void {\n const logDir = join(homedir(), '.autocode', 'logs');\n if (!existsSync(logDir)) {\n mkdirSync(logDir, { recursive: true });\n }\n const date = new Date().toISOString().slice(0, 10);\n logFilePath = join(logDir, `autocode-${date}.log`);\n}\n\nfunction shouldLog(level: LogLevel): boolean {\n return levels[level] >= levels[currentLevel];\n}\n\nfunction timestamp(): string {\n return new Date().toISOString().slice(11, 19);\n}\n\nfunction fullTimestamp(): string {\n return new Date().toISOString();\n}\n\nfunction writeToFile(level: string, msg: string): void {\n if (!logFilePath) return;\n try {\n appendFileSync(logFilePath, `${fullTimestamp()} [${level.padEnd(5)}] ${msg}\\n`);\n } catch {\n // Don't crash on log file write failure\n }\n}\n\nexport const log = {\n debug(msg: string, ...args: unknown[]) {\n writeToFile('DEBUG', msg);\n if (shouldLog('debug')) console.log(chalk.gray(`[${timestamp()}] ${msg}`), ...args);\n },\n info(msg: string, ...args: unknown[]) {\n writeToFile('INFO', msg);\n if (shouldLog('info')) console.log(chalk.blue(`[${timestamp()}]`), msg, ...args);\n },\n warn(msg: string, ...args: unknown[]) {\n writeToFile('WARN', msg);\n if (shouldLog('warn')) console.log(chalk.yellow(`[${timestamp()}] WARN`), msg, ...args);\n },\n error(msg: string, ...args: unknown[]) {\n writeToFile('ERROR', msg);\n if (shouldLog('error')) console.log(chalk.red(`[${timestamp()}] ERROR`), msg, ...args);\n },\n success(msg: string, ...args: unknown[]) {\n writeToFile('INFO', `✓ ${msg}`);\n if (shouldLog('info')) console.log(chalk.green(`[${timestamp()}] ✓`), msg, ...args);\n },\n ticket(id: string, msg: string, ...args: unknown[]) {\n writeToFile('INFO', `[${id}] ${msg}`);\n if (shouldLog('info')) console.log(chalk.cyan(`[${timestamp()}] [${id}]`), msg, ...args);\n },\n};\n","import { Octokit } from '@octokit/rest';\nimport type { Config } from './config.js';\nimport { log } from './logger.js';\n\nexport function createOctokit(config: Config): Octokit {\n return new Octokit({ auth: config.github.token });\n}\n\nfunction parseRepoUrl(url: string): { owner: string; repo: string } {\n // https://github.com/owner/repo or https://github.com/owner/repo.git\n const match = url.match(/github\\.com[/:]([^/]+)\\/([^/.]+)/);\n if (!match) throw new Error(`Cannot parse GitHub URL: ${url}`);\n return { owner: match[1], repo: match[2] };\n}\n\nexport async function openPR(octokit: Octokit, opts: {\n repoUrl: string;\n branch: string;\n baseBranch: string;\n title: string;\n body: string;\n}): Promise<{ url: string; number: number }> {\n const { owner, repo } = parseRepoUrl(opts.repoUrl);\n\n // Check for existing PR on this branch\n const existing = await octokit.rest.pulls.list({\n owner,\n repo,\n head: `${owner}:${opts.branch}`,\n state: 'open',\n });\n\n if (existing.data.length > 0) {\n const pr = existing.data[0];\n log.info(`PR already exists: ${pr.html_url}`);\n // Update body\n await octokit.rest.pulls.update({\n owner,\n repo,\n pull_number: pr.number,\n body: opts.body,\n });\n return { url: pr.html_url, number: pr.number };\n }\n\n const pr = await octokit.rest.pulls.create({\n owner,\n repo,\n title: opts.title,\n body: opts.body,\n head: opts.branch,\n base: opts.baseBranch,\n });\n\n log.success(`PR opened: ${pr.data.html_url}`);\n return { url: pr.data.html_url, number: pr.data.number };\n}\n","import { createServer } from 'node:http';\nimport { createHmac, timingSafeEqual } from 'node:crypto';\nimport type { Config } from './config.js';\nimport type { Ticket } from './linear.js';\nimport { parseRepoFromLabels, parseBaseFromLabels } from './config.js';\nimport { executeTicket } from './worker.js';\nimport type { LinearClient } from '@linear/sdk';\nimport type { Octokit } from '@octokit/rest';\nimport { log } from './logger.js';\n\ninterface WebhookPayload {\n action: string;\n type: string;\n data: {\n id: string;\n identifier: string;\n title: string;\n description: string | null;\n labels: Array<{ id: string; name: string }>;\n state: { id: string; name: string; type: string };\n url: string;\n team: { id: string; key: string; name: string };\n };\n updatedFrom?: Record<string, unknown>;\n}\n\nfunction verifySignature(body: string, signature: string, secret: string): boolean {\n const expected = createHmac('sha256', secret).update(body).digest('hex');\n try {\n return timingSafeEqual(Buffer.from(expected), Buffer.from(signature));\n } catch {\n return false;\n }\n}\n\nexport class WebhookServer {\n private active = new Set<string>();\n private queue: Ticket[] = [];\n private processed = new Set<string>(); // Track processed ticket IDs to prevent duplicate dispatch\n private server: ReturnType<typeof createServer> | undefined;\n\n constructor(\n private config: Config,\n private linearClient: LinearClient,\n private octokit: Octokit,\n ) {}\n\n start(): Promise<void> {\n const port = this.config.webhook?.port ?? 3000;\n const MAX_BODY_BYTES = 1024 * 1024; // 1 MB — Linear payloads are typically < 10 KB\n\n this.server = createServer((req, res) => {\n // Health check endpoint\n if (req.method === 'GET' && (req.url === '/health' || req.url === '/healthz')) {\n res.writeHead(200, { 'Content-Type': 'application/json' });\n res.end(JSON.stringify({ status: 'ok', active: this.active.size, queued: this.queue.length, capacity: this.config.maxConcurrent }));\n return;\n }\n\n // Accept both /webhook and /api/v1/linear/webhook (for CF worker compatibility)\n if (req.method !== 'POST' || (req.url !== '/webhook' && req.url !== '/api/v1/linear/webhook')) {\n res.writeHead(404);\n res.end();\n return;\n }\n\n let body = '';\n let bodyBytes = 0;\n req.on('data', (chunk: Buffer) => {\n bodyBytes += chunk.length;\n if (bodyBytes > MAX_BODY_BYTES) {\n res.writeHead(413);\n res.end('Payload too large');\n req.destroy();\n return;\n }\n body += chunk;\n });\n req.on('end', () => {\n // Verify signature if signing secret configured\n if (this.config.webhook?.signingSecret) {\n const sig = req.headers['linear-signature'] as string | undefined;\n if (!sig || !verifySignature(body, sig, this.config.webhook.signingSecret)) {\n log.warn('Invalid webhook signature, rejecting');\n res.writeHead(401);\n res.end('Invalid signature');\n return;\n }\n }\n\n // Respond immediately so Linear doesn't retry\n res.writeHead(200);\n res.end('ok');\n\n // Process async\n void this.handleWebhook(body);\n });\n });\n\n return new Promise((resolve) => {\n this.server!.listen(port, () => {\n log.info(`Webhook server listening on port ${port}`);\n resolve();\n });\n });\n }\n\n stop(): void {\n this.server?.close();\n log.info('Webhook server stopped');\n }\n\n private async handleWebhook(body: string): Promise<void> {\n let payload: WebhookPayload;\n try {\n payload = JSON.parse(body);\n } catch {\n log.warn('Invalid webhook JSON');\n return;\n }\n\n // Only handle Issue events\n if (payload.type !== 'Issue') return;\n\n const { action, data } = payload;\n const triggerStatuses = this.config.linear.statuses.map((s) => s.toLowerCase());\n const currentStatus = data.state.name.toLowerCase();\n\n // Trigger on: issue created/updated into a watched status\n if (action === 'create' || action === 'update') {\n // Check if the issue is now in a trigger status\n if (!triggerStatuses.includes(currentStatus)) {\n log.debug(`${data.identifier}: status \"${data.state.name}\" not in trigger list, ignoring`);\n return;\n }\n\n // For updates, only trigger if status actually changed\n if (action === 'update' && !payload.updatedFrom?.stateId) {\n log.debug(`${data.identifier}: update but status didn't change, ignoring`);\n return;\n }\n } else {\n return; // Ignore 'remove' and other actions\n }\n\n // Already processing or recently processed this ticket?\n if (this.active.has(data.id)) {\n log.debug(`${data.identifier}: already active, ignoring`);\n return;\n }\n if (this.processed.has(data.id)) {\n log.debug(`${data.identifier}: already processed in this session, ignoring`);\n return;\n }\n\n // Check concurrency — queue if at capacity instead of dropping\n if (this.active.size >= this.config.maxConcurrent) {\n log.info(`${data.identifier}: at capacity (${this.active.size}/${this.config.maxConcurrent}), queued`);\n const queueLabels = data.labels.map((l) => l.name);\n const ticket: Ticket = {\n id: data.id,\n identifier: data.identifier,\n title: data.title,\n description: data.description ?? '',\n labels: queueLabels,\n repoUrl: parseRepoFromLabels(queueLabels)!,\n baseBranch: parseBaseFromLabels(queueLabels),\n url: data.url,\n };\n this.queue.push(ticket);\n return;\n }\n\n // Resolve repo from labels\n const labelNames = data.labels.map((l) => l.name);\n const repoUrl = parseRepoFromLabels(labelNames);\n if (!repoUrl) {\n log.warn(`${data.identifier}: no repo: label, ignoring`);\n return;\n }\n\n const ticket: Ticket = {\n id: data.id,\n identifier: data.identifier,\n title: data.title,\n description: data.description ?? '',\n labels: labelNames,\n repoUrl,\n baseBranch: parseBaseFromLabels(labelNames),\n url: data.url,\n };\n\n this.dispatch(ticket);\n }\n\n private dispatch(ticket: Ticket): void {\n this.active.add(ticket.id);\n log.ticket(ticket.identifier, `Dispatching → ${ticket.repoUrl}`);\n\n void executeTicket({\n ticket,\n config: this.config,\n linearClient: this.linearClient,\n octokit: this.octokit,\n }).finally(() => {\n this.active.delete(ticket.id);\n this.processed.add(ticket.id);\n this.drainQueue();\n });\n }\n\n private drainQueue(): void {\n while (this.queue.length > 0 && this.active.size < this.config.maxConcurrent) {\n const next = this.queue.shift()!;\n // Skip if this ticket is already active (duplicate webhook)\n if (this.active.has(next.id)) continue;\n log.ticket(next.identifier, `Dequeued (${this.queue.length} remaining)`);\n this.dispatch(next);\n }\n }\n}\n","import Docker from 'dockerode';\nimport { PassThrough } from 'node:stream';\nimport { homedir, tmpdir } from 'node:os';\nimport { join } from 'node:path';\nimport { existsSync, readFileSync, writeFileSync, mkdtempSync, rmSync } from 'node:fs';\nimport { execSync } from 'node:child_process';\nimport type { DockerConfig } from './config.js';\nimport { log } from './logger.js';\n\nconst docker = new Docker();\n\nexport async function checkDockerAvailable(): Promise<void> {\n try {\n await docker.ping();\n } catch (err) {\n throw new Error(\n 'Cannot connect to Docker daemon. Is Docker running?\\n'\n + 'Install: https://docs.docker.com/get-docker/'\n );\n }\n}\n\n// Embedded Dockerfile for autocode-base — auto-built on first use\n// Includes Node.js 20, Python 3, Go, Ruby + Claude Code (~1.2GB)\n// Rust is omitted to keep image size manageable — use docker.setup for Rust repos\nconst AUTOCODE_BASE_DOCKERFILE = `FROM node:20-bookworm\nENV DEBIAN_FRONTEND=noninteractive\nRUN apt-get update && apt-get install -y --no-install-recommends \\\\\n build-essential git curl wget ca-certificates openssh-client jq unzip \\\\\n python3 python3-pip python3-venv python3-dev \\\\\n ruby ruby-dev \\\\\n && rm -rf /var/lib/apt/lists/*\nARG GO_VERSION=1.22.2\nRUN curl -fsSL \"https://go.dev/dl/go\\${GO_VERSION}.linux-$(dpkg --print-architecture).tar.gz\" \\\\\n | tar -xz -C /usr/local\nENV PATH=\"/usr/local/go/bin:\\${PATH}\"\nRUN npm install -g @anthropic-ai/claude-code@latest\nWORKDIR /workspace\n`;\n\nasync function ensureImage(image: string): Promise<void> {\n try {\n await docker.getImage(image).inspect();\n log.debug(`Image ${image} found locally`);\n return;\n } catch {\n // Image not found locally\n }\n\n // Auto-build autocode-base from embedded Dockerfile\n if (image === 'autocode-base') {\n log.info('Building autocode-base image (first time only, takes a few minutes)...');\n const buildDir = mkdtempSync(join(tmpdir(), 'autocode-build-'));\n try {\n writeFileSync(join(buildDir, 'Dockerfile'), AUTOCODE_BASE_DOCKERFILE);\n execSync(`docker build -t autocode-base ${buildDir}`, {\n stdio: 'inherit',\n timeout: 600_000,\n });\n log.success('autocode-base image built');\n return;\n } catch (err) {\n throw new Error(\n 'Failed to build autocode-base image.\\n'\n + 'You can build manually: docker build -t autocode-base .\\n'\n + `Or use a different image in your config (e.g. node:20).\\n`\n + `Error: ${err instanceof Error ? err.message : err}`\n );\n } finally {\n rmSync(buildDir, { recursive: true, force: true });\n }\n }\n\n // For other images, try to pull\n log.info(`Pulling image ${image} (this may take a moment)...`);\n await new Promise<void>((resolve, reject) => {\n docker.pull(image, (err: Error | null, stream: NodeJS.ReadableStream) => {\n if (err) {\n if (err.message?.includes('not found') || err.message?.includes('404')) {\n return reject(new Error(`Docker image \"${image}\" not found. Check the image name in your config.`));\n }\n return reject(err);\n }\n docker.modem.followProgress(stream, (err2: Error | null) => {\n if (err2) reject(err2);\n else {\n log.success(`Image ${image} pulled`);\n resolve();\n }\n });\n });\n });\n}\n\nexport interface Container {\n id: string;\n instance: Docker.Container;\n}\n\nexport async function createContainer(opts: {\n dockerConfig: DockerConfig;\n workspacePath: string;\n name: string;\n}): Promise<Container> {\n const { dockerConfig, name } = opts;\n\n // Ensure image exists — auto-build autocode-base if needed\n await ensureImage(dockerConfig.image);\n\n // Resolve volume mounts: expand ~ to host home directory\n const binds = [`${opts.workspacePath}:/workspace`];\n if (dockerConfig.volumes?.length) {\n for (const vol of dockerConfig.volumes) {\n binds.push(vol.replace(/^~(?=\\/|:)/, homedir()));\n }\n }\n\n const container = await docker.createContainer({\n Image: dockerConfig.image,\n name: `autocode-${name}`,\n Cmd: ['sleep', 'infinity'],\n WorkingDir: '/workspace',\n User: 'root',\n HostConfig: {\n Binds: binds,\n Memory: parseMemory(dockerConfig.memory),\n NanoCpus: dockerConfig.cpus ? dockerConfig.cpus * 1e9 : undefined,\n NetworkMode: dockerConfig.network ?? 'bridge',\n },\n Env: ['HOME=/root'],\n });\n\n await container.start();\n log.info(`Container ${name} started (${container.id.slice(0, 12)})`);\n\n const wrapped: Container = { id: container.id, instance: container };\n\n // Validate image has a shell (required for all operations)\n const shellCheck = await exec(wrapped, ['sh', '-c', 'echo ok']);\n if (shellCheck.exitCode !== 0 || !shellCheck.stdout.includes('ok')) {\n await destroyContainer(wrapped);\n throw new Error(\n `Docker image \"${dockerConfig.image}\" has no working shell (sh).\\n`\n + 'autocode requires a shell to set up the container. Use a standard base image\\n'\n + '(e.g. node:20, python:3.12, ubuntu:24.04) or ensure /bin/sh is available.'\n );\n }\n\n // Verify curl is available (needed for standalone Claude Code install)\n const curlCheck = await exec(wrapped, ['which', 'curl']);\n if (curlCheck.exitCode !== 0) {\n log.debug('curl not found, installing...');\n await exec(wrapped, [\n 'sh', '-c',\n '(apt-get update -qq && apt-get install -y -qq curl 2>/dev/null) || '\n + '(apk add --no-cache curl 2>/dev/null) || '\n + '(yum install -y curl 2>/dev/null) || true',\n ]);\n }\n\n // Verify git is available (custom images may not have it)\n const gitCheck = await exec(wrapped, ['git', '--version']);\n if (gitCheck.exitCode !== 0) {\n log.info('Git not found in image, installing...');\n // Try apt (Debian/Ubuntu) then apk (Alpine) then yum (RHEL/CentOS)\n const installGit = await exec(wrapped, [\n 'sh', '-c',\n '(apt-get update -qq && apt-get install -y -qq git 2>/dev/null) || '\n + '(apk add --no-cache git 2>/dev/null) || '\n + '(yum install -y git 2>/dev/null) || '\n + '(echo \"Cannot install git\" && exit 1)',\n ]);\n if (installGit.exitCode !== 0) {\n throw new Error(`Docker image \"${dockerConfig.image}\" has no git and autocode could not install it. Use an image with git pre-installed.`);\n }\n }\n\n // Install Claude Code if not already present (prebuilt images have it)\n const claudeCheck = await exec(wrapped, ['which', 'claude']);\n if (claudeCheck.exitCode !== 0) {\n log.info('Installing Claude Code in container...');\n\n // Try npm first (fastest if Node.js is available)\n const npmCheck = await exec(wrapped, ['which', 'npm']);\n let installed = false;\n\n if (npmCheck.exitCode === 0) {\n const npmResult = await exec(wrapped, [\n 'npm', 'install', '-g', '@anthropic-ai/claude-code@latest',\n ]);\n installed = npmResult.exitCode === 0;\n }\n\n // Fall back to standalone binary (works without Node.js)\n if (!installed) {\n log.info('npm not available, installing Claude Code standalone binary...');\n const standaloneResult = await exec(wrapped, [\n 'sh', '-c',\n 'curl -fsSL https://claude.ai/install.sh | sh',\n ], { timeout: 120_000 });\n if (standaloneResult.exitCode !== 0) {\n throw new Error(\n 'Failed to install Claude Code. Tried npm and standalone installer.\\n'\n + `Error: ${standaloneResult.stderr}\\n`\n + 'Use an image with Claude Code pre-installed, or ensure curl is available.'\n );\n }\n }\n\n log.info('Claude Code installed');\n } else {\n log.debug('Claude Code already installed in image');\n }\n\n // Create non-root user (--dangerously-skip-permissions can't run as root)\n // UID 1001 to avoid conflict with node:20's built-in 'node' user at UID 1000\n await exec(wrapped, [\n 'sh', '-c',\n '( getent passwd autocode >/dev/null 2>&1 ) || '\n + '( adduser --disabled-password --gecos \"\" --uid 1001 --home /home/autocode autocode 2>/dev/null ) || '\n + '( adduser -D -u 1001 -h /home/autocode autocode 2>/dev/null ) || ' // Alpine adduser\n + '( useradd -m -u 1001 -d /home/autocode autocode 2>/dev/null ) || ' // useradd fallback\n + '( echo \"autocode:x:1001:1001::/home/autocode:/bin/sh\" >> /etc/passwd && mkdir -p /home/autocode ); '\n + 'mkdir -p /home/autocode && chown -R autocode /home/autocode /workspace',\n ]);\n\n // Auto-detect and install missing language runtimes based on repo files\n await autoInstallRuntimes(wrapped);\n\n // Run user-defined setup commands from .autocode.yaml docker.setup\n if (dockerConfig.setup?.length) {\n log.info(`Running ${dockerConfig.setup.length} setup command(s)...`);\n for (const cmd of dockerConfig.setup) {\n const result = await exec(wrapped, ['sh', '-c', cmd]);\n if (result.exitCode !== 0) {\n throw new Error(`Setup command failed: ${cmd}\\n${result.stderr}`);\n }\n }\n }\n\n // Copy Claude credentials into container (read-write, not bind-mount)\n await copyClaudeCredentials(wrapped);\n\n return wrapped;\n}\n\n// Detect language stack from workspace files and install missing runtimes\nasync function autoInstallRuntimes(container: Container): Promise<void> {\n const detect = await exec(container, [\n 'sh', '-c',\n 'ls /workspace/package.json /workspace/pyproject.toml /workspace/setup.py '\n + '/workspace/requirements.txt /workspace/Pipfile /workspace/go.mod '\n + '/workspace/Cargo.toml /workspace/Gemfile /workspace/pom.xml '\n + '/workspace/build.gradle /workspace/build.gradle.kts '\n + '/workspace/composer.json /workspace/mix.exs 2>/dev/null || true',\n ]);\n const files = detect.stdout.trim().split('\\n').filter(Boolean);\n if (files.length === 0) return;\n\n const needs: string[] = [];\n\n // Check what's already installed\n const checks = await exec(container, [\n 'sh', '-c',\n 'echo \"node:$(which node 2>/dev/null || echo missing)\";'\n + 'echo \"python:$(which python3 2>/dev/null || which python 2>/dev/null || echo missing)\";'\n + 'echo \"go:$(which go 2>/dev/null || echo missing)\";'\n + 'echo \"ruby:$(which ruby 2>/dev/null || echo missing)\";',\n ]);\n const installed = new Map<string, boolean>();\n for (const line of checks.stdout.trim().split('\\n')) {\n const [lang, path] = line.split(':');\n installed.set(lang, path !== 'missing');\n }\n\n const hasPython = files.some(f =>\n f.includes('pyproject.toml') || f.includes('setup.py') ||\n f.includes('requirements.txt') || f.includes('Pipfile')\n );\n const hasGo = files.some(f => f.includes('go.mod'));\n const hasRuby = files.some(f => f.includes('Gemfile'));\n\n if (hasPython && !installed.get('python')) {\n needs.push('python3 python3-pip python3-venv');\n }\n if (hasGo && !installed.get('go')) {\n needs.push('golang');\n }\n if (hasRuby && !installed.get('ruby')) {\n needs.push('ruby ruby-dev');\n }\n\n if (needs.length === 0) return;\n\n const packages = needs.join(' ');\n log.info(`Detected stack requires: ${packages}`);\n\n // Try apt (Debian/Ubuntu), then apk (Alpine)\n const installResult = await exec(container, [\n 'sh', '-c',\n `(apt-get update -qq && apt-get install -y -qq ${packages} 2>/dev/null) || `\n + `(apk add --no-cache ${packages.replace('python3-pip', 'py3-pip').replace('python3-venv', '').replace('ruby-dev', 'ruby-dev build-base')} 2>/dev/null) || `\n + `echo \"Warning: could not auto-install ${packages}\"`,\n ]);\n\n if (installResult.exitCode === 0) {\n log.success('Runtime dependencies installed');\n } else {\n log.warn(`Could not auto-install ${packages} — Claude may not be able to run tests for this stack`);\n }\n}\n\nasync function copyClaudeCredentials(container: Container): Promise<void> {\n const home = homedir();\n\n // Ensure .claude directory exists in container\n await exec(container, [\n 'sh', '-c', 'mkdir -p /home/autocode/.claude && chown autocode /home/autocode/.claude',\n ]);\n\n // Copy credentials file\n const credFile = join(home, '.claude', '.credentials.json');\n if (existsSync(credFile)) {\n const content = readFileSync(credFile, 'utf-8');\n const b64 = Buffer.from(content).toString('base64');\n await exec(container, [\n 'sh', '-c',\n `echo '${b64}' | base64 -d > /home/autocode/.claude/.credentials.json && chown autocode /home/autocode/.claude/.credentials.json`,\n ]);\n log.debug('Copied .credentials.json');\n }\n\n // Copy settings if present\n const settingsFile = join(home, '.claude', 'settings.json');\n if (existsSync(settingsFile)) {\n const content = readFileSync(settingsFile, 'utf-8');\n const b64 = Buffer.from(content).toString('base64');\n await exec(container, [\n 'sh', '-c',\n `echo '${b64}' | base64 -d > /home/autocode/.claude/settings.json && chown autocode /home/autocode/.claude/settings.json`,\n ]);\n }\n\n log.info('Claude credentials copied into container');\n}\n\nexport interface ExecResult {\n exitCode: number;\n stdout: string;\n stderr: string;\n}\n\nexport async function exec(container: Container, cmd: string[], opts?: {\n workdir?: string;\n env?: string[];\n user?: string;\n timeout?: number;\n}): Promise<ExecResult> {\n const execution = await container.instance.exec({\n Cmd: cmd,\n AttachStdout: true,\n AttachStderr: true,\n WorkingDir: opts?.workdir ?? '/workspace',\n Env: opts?.env,\n User: opts?.user,\n });\n\n const stream = await execution.start({ hijack: true, stdin: false });\n\n let stdout = '';\n let stderr = '';\n\n return new Promise((resolve, reject) => {\n const stdoutStream = new PassThrough();\n const stderrStream = new PassThrough();\n\n docker.modem.demuxStream(stream, stdoutStream, stderrStream);\n\n stdoutStream.on('data', (chunk: Buffer) => { stdout += chunk.toString(); });\n stderrStream.on('data', (chunk: Buffer) => { stderr += chunk.toString(); });\n\n let timer: ReturnType<typeof setTimeout> | undefined;\n if (opts?.timeout) {\n timer = setTimeout(() => {\n stream.destroy();\n resolve({ exitCode: 124, stdout, stderr: stderr + '\\n[autocode] exec timed out' });\n }, opts.timeout);\n }\n\n stream.on('end', async () => {\n if (timer) clearTimeout(timer);\n try {\n const info = await execution.inspect();\n resolve({ exitCode: info.ExitCode ?? 1, stdout, stderr });\n } catch (e) {\n reject(e);\n }\n });\n\n stream.on('error', (e) => {\n if (timer) clearTimeout(timer);\n reject(e);\n });\n });\n}\n\nexport async function cleanupOrphanedContainers(): Promise<number> {\n const containers = await docker.listContainers({ all: true });\n const orphans = containers.filter(c =>\n c.Names.some(n => n.startsWith('/autocode-'))\n );\n let cleaned = 0;\n for (const c of orphans) {\n try {\n const container = docker.getContainer(c.Id);\n if (c.State === 'running') {\n await container.stop({ t: 5 });\n }\n await container.remove({ force: true });\n log.info(`Cleaned up orphaned container ${c.Names[0]} (${c.Id.slice(0, 12)})`);\n cleaned++;\n } catch {\n // Best effort\n }\n }\n return cleaned;\n}\n\nexport async function destroyContainer(container: Container): Promise<void> {\n try {\n await container.instance.stop({ t: 5 });\n } catch {\n // Already stopped\n }\n try {\n await container.instance.remove({ force: true });\n } catch {\n // Already removed\n }\n log.info(`Container ${container.id.slice(0, 12)} destroyed`);\n}\n\nfunction parseMemory(mem: string): number {\n const match = mem.match(/^(\\d+(?:\\.\\d+)?)(k|m|g|t)$/i);\n if (!match) throw new Error(`Invalid memory format: \"${mem}\". Use a number followed by k, m, g, or t (e.g. \"4g\", \"512m\")`);\n const [, num, unit] = match;\n const value = parseFloat(num);\n if (value <= 0) throw new Error(`Memory must be greater than 0: \"${mem}\"`);\n const multipliers: Record<string, number> = {\n k: 1024,\n m: 1024 * 1024,\n g: 1024 * 1024 * 1024,\n t: 1024 * 1024 * 1024 * 1024,\n };\n return Math.round(value * multipliers[unit.toLowerCase()]);\n}\n","import type { Container } from './docker.js';\nimport { exec } from './docker.js';\nimport type { AgentConfig } from './config.js';\nimport { log } from './logger.js';\n\n// Default timeout per Claude invocation: 30 minutes\nconst DEFAULT_ITERATION_TIMEOUT_MS = 30 * 60 * 1000;\n\nexport interface AgentResult {\n iteration: number;\n exitCode: number;\n stdout: string;\n stderr: string;\n rateLimited: boolean;\n completed: boolean;\n}\n\n// Rate limit patterns in Claude Code output\n// These patterns require error-adjacent context to reduce false positives\n// (e.g. \"429\" appearing in a filename or \"capacity\" in normal prose)\nconst RATE_LIMIT_PATTERNS = [\n /rate.?limit/i,\n /too many requests/i,\n /\\b429\\b.*(?:error|too many|rate|limit|retry)/i,\n /(?:error|status|code|http)[:\\s]*429\\b/i,\n /(?:api|server|model)\\s+(?:is\\s+)?overloaded/i,\n /over\\s*capacity/i,\n];\n\nconst COMPLETION_PATTERNS = [\n /\\[autocode:done\\]/i,\n /all tasks? completed/i,\n];\n\nfunction isRateLimited(output: string): boolean {\n return RATE_LIMIT_PATTERNS.some((p) => p.test(output));\n}\n\nfunction isCompleted(output: string): boolean {\n return COMPLETION_PATTERNS.some((p) => p.test(output));\n}\n\nfunction estimateResetMs(output: string): number {\n const match = output.match(/retry.?after[:\\s]*(\\d+)/i);\n if (match) return parseInt(match[1]) * 1000;\n return 60_000;\n}\n\nconst MAX_RATE_LIMIT_RETRIES = 10;\n\nexport async function runAgentLoop(opts: {\n container: Container;\n agentConfig: AgentConfig;\n prompt: string;\n ticketId: string;\n onIteration?: (result: AgentResult) => void;\n}): Promise<{ iterations: number; success: boolean; lastOutput: string }> {\n const { container, agentConfig, prompt, ticketId, onIteration } = opts;\n let lastOutput = '';\n let rateLimitRetries = 0;\n\n // Write prompt to a file inside the container (avoids ARG_MAX for long prompts)\n const promptB64 = Buffer.from(prompt).toString('base64');\n await exec(container, [\n 'sh', '-c',\n `mkdir -p /tmp/autocode && echo '${promptB64}' | base64 -d > /tmp/autocode/prompt.md && chmod 644 /tmp/autocode/prompt.md`,\n ]);\n\n for (let i = 1; i <= agentConfig.maxIterations; i++) {\n log.ticket(ticketId, `Iteration ${i}/${agentConfig.maxIterations}`);\n\n // claude -p \"$(cat file)\" reads prompt from file via shell substitution\n // --dangerously-skip-permissions needed for non-interactive container use\n const cmd = [\n 'sh', '-c',\n [\n 'claude',\n '-p', '\"$(cat /tmp/autocode/prompt.md)\"',\n '--model', agentConfig.model,\n '--output-format', 'text',\n '--max-turns', '50',\n '--dangerously-skip-permissions',\n '--verbose',\n ].join(' '),\n ];\n\n const timeoutMs = agentConfig.timeout\n ? agentConfig.timeout * 1000\n : DEFAULT_ITERATION_TIMEOUT_MS;\n\n const result = await exec(container, cmd, {\n user: 'autocode',\n env: ['HOME=/home/autocode', 'CLAUDE_CODE_DISABLE_NONINTERACTIVE_TUTORIAL=1'],\n timeout: timeoutMs,\n });\n\n const combined = result.stdout + result.stderr;\n lastOutput = combined;\n\n // Log a snippet of the output for debugging\n const snippet = combined.slice(-500).trim();\n if (snippet) {\n log.debug(`Agent output (last 500 chars): ${snippet}`);\n }\n\n const rateLimited = isRateLimited(combined);\n const completed = isCompleted(combined) || (result.exitCode === 0 && i > 1);\n\n const agentResult: AgentResult = {\n iteration: i,\n exitCode: result.exitCode,\n stdout: result.stdout,\n stderr: result.stderr,\n rateLimited,\n completed,\n };\n\n onIteration?.(agentResult);\n\n if (completed) {\n log.ticket(ticketId, `Completed after ${i} iterations`);\n return { iterations: i, success: true, lastOutput };\n }\n\n if (rateLimited) {\n rateLimitRetries++;\n if (rateLimitRetries > MAX_RATE_LIMIT_RETRIES) {\n log.ticket(ticketId, `Rate limited ${rateLimitRetries} times, giving up`);\n return { iterations: i, success: false, lastOutput };\n }\n const waitMs = estimateResetMs(combined);\n log.ticket(ticketId, `Rate limited (${rateLimitRetries}/${MAX_RATE_LIMIT_RETRIES}) — pausing ${Math.round(waitMs / 1000)}s`);\n await sleep(waitMs);\n // Don't count rate-limited iteration\n i--;\n continue;\n }\n\n if (result.exitCode !== 0) {\n log.ticket(ticketId, `Non-zero exit (${result.exitCode}), continuing...`);\n }\n\n // Ralph Wiggum: Claude sees its own work from previous iterations\n // via the git history and file state in the workspace.\n // We just re-run with the same prompt.\n }\n\n log.ticket(ticketId, `Max iterations (${agentConfig.maxIterations}) reached`);\n return { iterations: agentConfig.maxIterations, success: false, lastOutput };\n}\n\nfunction sleep(ms: number): Promise<void> {\n return new Promise((resolve) => setTimeout(resolve, ms));\n}\n","import type { Container } from './docker.js';\nimport { exec } from './docker.js';\nimport { log } from './logger.js';\n\n// Configure git inside container (repo already cloned + branch created on host)\nexport async function setupRepo(container: Container, opts: {\n branchName: string;\n}): Promise<void> {\n const u = { user: 'autocode' };\n await exec(container, ['git', 'config', 'user.name', 'autocode'], u);\n await exec(container, ['git', 'config', 'user.email', 'autocode@localhost'], u);\n await exec(container, ['git', 'config', '--global', 'safe.directory', '/workspace'], u);\n log.info(`Git configured, on branch ${opts.branchName}`);\n}\n\nexport async function commitAndPush(container: Container, opts: {\n branchName: string;\n ticketId: string;\n title: string;\n repoUrl: string;\n githubToken: string;\n}): Promise<{ pushed: boolean; commitCount: number }> {\n const { branchName, ticketId, title, githubToken } = opts;\n\n const u = { user: 'autocode' };\n\n // Stage and commit any uncommitted changes (agent may have left some unstaged)\n const status = await exec(container, ['git', 'status', '--porcelain'], u);\n if (status.stdout.trim()) {\n await exec(container, ['git', 'add', '-A'], u);\n const message = `${ticketId}: ${title}`;\n await exec(container, ['git', 'commit', '-m', message], u);\n }\n\n // Count commits on branch vs origin\n const countResult = await exec(container, [\n 'git', 'rev-list', '--count', `HEAD`, '--not', '--remotes',\n ], u);\n const commitCount = parseInt(countResult.stdout.trim()) || 0;\n\n if (commitCount === 0) {\n log.warn('No commits to push');\n return { pushed: false, commitCount: 0 };\n }\n\n // Configure token via git credential helper to avoid token in remote URL / process list\n await exec(container, [\n 'sh', '-c',\n `git config credential.helper '!f() { echo \"password=${githubToken}\"; echo \"username=x-access-token\"; }; f'`,\n ], u);\n\n // Push\n const pushResult = await exec(container, ['git', 'push', '-u', 'origin', branchName], u);\n if (pushResult.exitCode !== 0) {\n // Redact any token that may appear in stderr\n const safeStderr = pushResult.stderr.replace(/x-access-token:[^\\s@]+/g, 'x-access-token:***');\n log.error(`Push failed: ${safeStderr}`);\n return { pushed: false, commitCount };\n }\n\n log.success(`Pushed ${commitCount} commit(s) to ${branchName}`);\n return { pushed: true, commitCount };\n}\n","import type { Config } from './config.js';\nimport { loadRepoLocalConfig, mergeConfigs } from './config.js';\nimport type { Ticket } from './linear.js';\nimport { claimTicket, completeTicket, failTicket, addBranchLabel } from './linear.js';\nimport { createContainer, destroyContainer } from './docker.js';\nimport type { Container } from './docker.js';\nimport { runAgentLoop } from './agent.js';\nimport { setupRepo, commitAndPush } from './git.js';\nimport { openPR } from './github.js';\nimport type { Octokit } from '@octokit/rest';\nimport type { LinearClient } from '@linear/sdk';\nimport { log } from './logger.js';\nimport { mkdtempSync, rmSync, writeFileSync } from 'node:fs';\nimport { join } from 'node:path';\nimport { tmpdir } from 'node:os';\nimport { execSync } from 'node:child_process';\n\nexport interface WorkerResult {\n ticketId: string;\n success: boolean;\n prUrl?: string;\n error?: string;\n iterations: number;\n}\n\nfunction buildPrompt(ticket: Ticket, repoPrompt?: string): string {\n const parts: string[] = [];\n\n if (repoPrompt) {\n parts.push(repoPrompt);\n parts.push('');\n }\n\n parts.push(`## Task: ${ticket.identifier} — ${ticket.title}`);\n parts.push('');\n\n if (ticket.description) {\n parts.push(ticket.description);\n }\n\n parts.push('');\n parts.push('## Instructions');\n parts.push('- Start by reading CLAUDE.md if it exists — it has project-specific guidance');\n parts.push('- Read the codebase to understand the context before making changes');\n parts.push('- Work through the task step by step');\n parts.push('- After making changes, run: git add -A && git commit -m \"description of changes\"');\n parts.push('- Commit after each logical step (do not batch all changes into one commit)');\n parts.push('- If the task has a checklist, work through items in order and commit after each one');\n parts.push('- Run any existing tests before finishing to verify your changes');\n parts.push('- IMPORTANT: You MUST commit your changes with git before finishing');\n parts.push('- When all work is complete and committed, include [autocode:done] in your final output');\n\n return parts.join('\\n');\n}\n\nfunction slugify(s: string): string {\n return s.toLowerCase().replace(/[^a-z0-9]+/g, '-').replace(/^-|-$/g, '').slice(0, 50);\n}\n\n// Validate ref names to prevent shell injection (branch names come from .autocode.yaml)\nfunction assertSafeRef(name: string, label: string): void {\n // Git ref rules: no space, ~, ^, :, ?, *, [, \\, control chars, or ..\n if (!name || /[\\s~^:?*\\[\\\\]|\\.\\./.test(name) || name.startsWith('-')) {\n throw new Error(`Invalid ${label}: \"${name}\"`);\n }\n}\n\n// Create a GIT_ASKPASS script that provides the token without exposing it in process args\nfunction createAskpass(githubToken: string): { dir: string; path: string } {\n const dir = mkdtempSync(join(tmpdir(), 'autocode-cred-'));\n const path = join(dir, 'askpass.sh');\n writeFileSync(path, `#!/bin/sh\\necho \"${githubToken}\"\\n`, { mode: 0o700 });\n return { dir, path };\n}\n\nfunction gitEnv(askpassPath: string): NodeJS.ProcessEnv {\n return { ...process.env, GIT_ASKPASS: askpassPath, GIT_TERMINAL_PROMPT: '0' };\n}\n\n// Detect the default branch of a remote repo (main, master, develop, etc.)\nfunction detectDefaultBranch(repoUrl: string, githubToken: string): string {\n const askpass = createAskpass(githubToken);\n const authedUrl = repoUrl.replace('https://', 'https://x-access-token@');\n try {\n // git ls-remote --symref gives us HEAD → refs/heads/main (or whatever the default is)\n const output = execSync(\n `git ls-remote --symref -- ${authedUrl} HEAD`,\n { stdio: 'pipe', timeout: 30_000, env: gitEnv(askpass.path), encoding: 'utf-8' }\n );\n // Parse: \"ref: refs/heads/main\\tHEAD\"\n const match = output.match(/ref:\\s+refs\\/heads\\/(\\S+)\\s+HEAD/);\n if (match) return match[1];\n } catch {\n // Fall through to default\n } finally {\n rmSync(askpass.dir, { recursive: true, force: true });\n }\n return 'main'; // fallback\n}\n\n// Clone repo to temp dir on the host so we can read .autocode.yaml before Docker\nfunction cloneToTemp(repoUrl: string, baseBranch: string, githubToken: string): string {\n assertSafeRef(baseBranch, 'base branch');\n const workDir = mkdtempSync(join(tmpdir(), 'autocode-'));\n const askpass = createAskpass(githubToken);\n const authedUrl = repoUrl.replace('https://', 'https://x-access-token@');\n\n try {\n execSync(`git clone --depth=50 -b ${baseBranch} -- ${authedUrl} ${workDir}`, {\n stdio: 'pipe',\n timeout: 120_000,\n env: gitEnv(askpass.path),\n });\n } finally {\n rmSync(askpass.dir, { recursive: true, force: true });\n }\n return workDir;\n}\n\nexport async function executeTicket(opts: {\n ticket: Ticket;\n config: Config;\n linearClient: LinearClient;\n octokit: Octokit;\n}): Promise<WorkerResult> {\n const { ticket, config, linearClient, octokit } = opts;\n\n if (!ticket.repoUrl) {\n return {\n ticketId: ticket.identifier,\n success: false,\n error: 'No repo:owner/name label on ticket',\n iterations: 0,\n };\n }\n\n // Validate repo URL before attempting clone\n if (!ticket.repoUrl.startsWith('https://')) {\n return {\n ticketId: ticket.identifier,\n success: false,\n error: `Invalid repo URL: \"${ticket.repoUrl}\". Only HTTPS URLs are supported.`,\n iterations: 0,\n };\n }\n\n const branchName = `autocode/${ticket.identifier}-${slugify(ticket.title)}`;\n // Docker container names: [a-zA-Z0-9_.-] only\n const containerName = `${ticket.identifier}-${Date.now()}`.toLowerCase().replace(/[^a-z0-9_.-]/g, '-');\n let workDir: string | undefined;\n let container: Container | undefined;\n\n try {\n // 1. Claim the ticket in Linear\n await claimTicket(linearClient, config, ticket.id);\n log.ticket(ticket.identifier, `Claimed — ${ticket.repoUrl}`);\n\n // 2. Detect the repo's default branch (main, master, develop, etc.)\n const detectedBase = detectDefaultBranch(ticket.repoUrl, config.github.token);\n log.ticket(ticket.identifier, `Default branch: ${detectedBase}`);\n\n // Clone with the detected default branch\n workDir = cloneToTemp(ticket.repoUrl, detectedBase, config.github.token);\n log.ticket(ticket.identifier, 'Cloned repo');\n\n // 3. Load .autocode.yaml from repo, merge with host config\n const repoLocal = loadRepoLocalConfig(workDir);\n // Priority: ticket \"base:\" label > .autocode.yaml base > detected default branch\n // Ticket label enables stacked diffs (branching from another PR's branch)\n const actualBase = ticket.baseBranch ?? repoLocal?.base ?? detectedBase;\n const { agent, docker, prompt } = mergeConfigs(config, repoLocal);\n\n if (repoLocal) {\n log.ticket(ticket.identifier, 'Loaded .autocode.yaml from repo');\n }\n if (ticket.baseBranch) {\n log.ticket(ticket.identifier, `Stacked on branch: ${ticket.baseBranch}`);\n }\n\n // If base branch differs from what we cloned, re-clone with the correct base\n if (actualBase !== detectedBase) {\n rmSync(workDir, { recursive: true, force: true });\n workDir = cloneToTemp(ticket.repoUrl, actualBase, config.github.token);\n }\n\n // Create working branch on host\n // Use -B (force-create) so retried tickets don't fail with \"branch already exists\"\n execSync(`git checkout -B ${branchName} --`, { cwd: workDir, stdio: 'pipe' });\n\n // 4. Spin up Docker container with workspace mounted\n container = await createContainer({\n dockerConfig: docker,\n workspacePath: workDir,\n name: containerName,\n });\n\n // Configure git inside container\n await setupRepo(container, { branchName });\n\n // 5. Run Claude Code in Ralph Wiggum loop\n const agentPrompt = buildPrompt(ticket, prompt);\n const agentResult = await runAgentLoop({\n container,\n agentConfig: agent,\n prompt: agentPrompt,\n ticketId: ticket.identifier,\n });\n\n // 6. Push (agent commits incrementally, we just push)\n const gitResult = await commitAndPush(container, {\n branchName,\n ticketId: ticket.identifier,\n title: ticket.title,\n repoUrl: ticket.repoUrl,\n githubToken: config.github.token,\n });\n\n if (!gitResult.pushed) {\n await failTicket(linearClient, ticket.id, 'No changes produced');\n return {\n ticketId: ticket.identifier,\n success: false,\n error: 'No changes produced',\n iterations: agentResult.iterations,\n };\n }\n\n // 7. Open PR\n const prBody: string[] = [\n `Resolves [${ticket.identifier}](${ticket.url})`,\n '',\n ];\n\n // Include ticket description if present (truncated for very long descriptions)\n if (ticket.description) {\n const desc = ticket.description.length > 2000\n ? ticket.description.slice(0, 2000) + '\\n\\n*[description truncated]*'\n : ticket.description;\n prBody.push('## Description', '', desc, '');\n }\n\n prBody.push(\n '## Details',\n '',\n `| Metric | Value |`,\n `| --- | --- |`,\n `| Iterations | ${agentResult.iterations} |`,\n `| Commits | ${gitResult.commitCount} |`,\n `| Model | ${agent.model} |`,\n '',\n '---',\n '*Generated by [autocode](https://github.com/rahulrai/autocode)*',\n );\n\n const pr = await openPR(octokit, {\n repoUrl: ticket.repoUrl,\n branch: branchName,\n baseBranch: actualBase,\n title: `${ticket.identifier}: ${ticket.title}`,\n body: prBody.join('\\n'),\n });\n\n // 8. Update Linear ticket\n await completeTicket(linearClient, config, ticket.id, `PR opened: ${pr.url}`);\n\n // 9. Add branch label to ticket so child tickets can stack on it\n // e.g. child ticket adds label \"base:autocode/T-123-fix-login\" to branch from this PR\n await addBranchLabel(linearClient, ticket.id, branchName);\n\n log.success(`${ticket.identifier} done — ${pr.url}`);\n return {\n ticketId: ticket.identifier,\n success: true,\n prUrl: pr.url,\n iterations: agentResult.iterations,\n };\n } catch (err) {\n const msg = err instanceof Error ? err.message : String(err);\n log.error(`${ticket.identifier} failed: ${msg}`);\n\n try {\n await failTicket(linearClient, ticket.id, msg);\n } catch {\n // Best effort\n }\n\n return {\n ticketId: ticket.identifier,\n success: false,\n error: msg,\n iterations: 0,\n };\n } finally {\n // 9. Kill the container\n if (container) {\n await destroyContainer(container);\n }\n\n // Clean up temp dir\n if (workDir) {\n try {\n rmSync(workDir, { recursive: true, force: true });\n } catch {\n // Best effort\n }\n }\n }\n}\n","import { spawn } from 'node:child_process';\nimport { log } from './logger.js';\n\nexport interface TunnelInfo {\n url: string;\n process: ReturnType<typeof spawn>;\n}\n\nexport async function startQuickTunnel(port: number): Promise<TunnelInfo> {\n return new Promise((resolve, reject) => {\n const proc = spawn('cloudflared', ['tunnel', '--url', `http://127.0.0.1:${port}`], {\n stdio: ['ignore', 'pipe', 'pipe'],\n });\n\n let resolved = false;\n const timeout = setTimeout(() => {\n if (!resolved) {\n reject(new Error('Tunnel startup timed out after 30s'));\n }\n }, 30_000);\n\n const handleOutput = (data: Buffer) => {\n const line = data.toString();\n // Quick tunnel URL appears in stderr as: https://xxx.trycloudflare.com\n const match = line.match(/(https:\\/\\/[a-z0-9-]+\\.trycloudflare\\.com)/);\n if (match && !resolved) {\n resolved = true;\n clearTimeout(timeout);\n resolve({ url: match[1], process: proc });\n }\n };\n\n proc.stdout.on('data', handleOutput);\n proc.stderr.on('data', handleOutput);\n\n proc.on('error', (err) => {\n if (!resolved) {\n clearTimeout(timeout);\n if ((err as NodeJS.ErrnoException).code === 'ENOENT') {\n reject(new Error('cloudflared not found. Install it: https://developers.cloudflare.com/cloudflare-one/connections/connect-networks/downloads/'));\n } else {\n reject(err);\n }\n }\n });\n\n proc.on('exit', (code) => {\n if (!resolved) {\n clearTimeout(timeout);\n reject(new Error(`cloudflared exited with code ${code}`));\n }\n });\n });\n}\n\nexport function stopTunnel(tunnel: TunnelInfo): void {\n tunnel.process.kill('SIGTERM');\n log.info('Tunnel stopped');\n}\n","import { execSync } from 'node:child_process';\nimport { existsSync } from 'node:fs';\nimport { join } from 'node:path';\nimport { homedir } from 'node:os';\nimport { log } from './logger.js';\n\n// --- Package manager detection ---\n\ntype PackageManager = 'apt' | 'yum' | 'dnf' | 'pacman' | 'apk' | 'brew' | 'unknown';\n\nfunction detectPackageManager(): PackageManager {\n const checks: [PackageManager, string][] = [\n ['apt', 'apt-get'],\n ['dnf', 'dnf'],\n ['yum', 'yum'],\n ['pacman', 'pacman'],\n ['apk', 'apk'],\n ['brew', 'brew'],\n ];\n for (const [name, cmd] of checks) {\n try {\n execSync(`which ${cmd}`, { stdio: 'pipe' });\n return name;\n } catch { /* not found */ }\n }\n return 'unknown';\n}\n\n// --- Install commands per package manager ---\n\nconst DOCKER_INSTALL: Record<PackageManager, string[]> = {\n apt: [\n 'apt-get update -qq',\n 'apt-get install -y docker.io',\n 'systemctl enable docker',\n 'systemctl start docker',\n ],\n dnf: [\n 'dnf install -y docker',\n 'systemctl enable docker',\n 'systemctl start docker',\n ],\n yum: [\n 'yum install -y docker',\n 'systemctl enable docker',\n 'systemctl start docker',\n ],\n pacman: [\n 'pacman -Sy --noconfirm docker',\n 'systemctl enable docker',\n 'systemctl start docker',\n ],\n apk: [\n 'apk add docker',\n 'rc-update add docker boot',\n 'service docker start',\n ],\n brew: [\n 'brew install --cask docker',\n ],\n unknown: [],\n};\n\nconst CLOUDFLARED_INSTALL: Record<PackageManager, string[]> = {\n apt: [\n 'apt-get update -qq',\n 'apt-get install -y cloudflared || (curl -fsSL https://pkg.cloudflare.com/cloudflare-main.gpg | tee /usr/share/keyrings/cloudflare-main.gpg >/dev/null && echo \"deb [signed-by=/usr/share/keyrings/cloudflare-main.gpg] https://pkg.cloudflare.com/cloudflared $(lsb_release -cs) main\" | tee /etc/apt/sources.list.d/cloudflared.list && apt-get update -qq && apt-get install -y cloudflared)',\n ],\n dnf: ['dnf install -y cloudflared || npm install -g cloudflared'],\n yum: ['yum install -y cloudflared || npm install -g cloudflared'],\n pacman: ['pacman -Sy --noconfirm cloudflared'],\n apk: ['apk add cloudflared'],\n brew: ['brew install cloudflared'],\n unknown: [],\n};\n\n// --- Dependency status ---\n\nexport interface DepStatus {\n name: string;\n installed: boolean;\n running?: boolean; // for services like Docker\n installable: boolean;\n installCommands: string[];\n manualInstructions: string;\n}\n\nexport function checkDeps(): DepStatus[] {\n const pm = detectPackageManager();\n const needsSudo = pm !== 'brew' && pm !== 'unknown' && process.getuid?.() !== 0;\n const sudo = needsSudo ? 'sudo ' : '';\n\n return [\n {\n name: 'Docker',\n installed: commandExists('docker'),\n running: isDockerRunning(),\n installable: pm !== 'unknown',\n installCommands: DOCKER_INSTALL[pm].map(c => `${sudo}${c}`),\n manualInstructions: 'https://docs.docker.com/get-docker/',\n },\n {\n name: 'Claude Code',\n installed: commandExists('claude'),\n installable: commandExists('npm'),\n installCommands: ['npm install -g @anthropic-ai/claude-code@latest'],\n manualInstructions: 'npm install -g @anthropic-ai/claude-code',\n },\n {\n name: 'Claude credentials',\n installed: existsSync(join(homedir(), '.claude', '.credentials.json')),\n installable: false,\n installCommands: [],\n manualInstructions: 'Run \"claude\" and complete the login flow',\n },\n {\n name: 'cloudflared',\n installed: commandExists('cloudflared'),\n installable: pm !== 'unknown',\n installCommands: CLOUDFLARED_INSTALL[pm].map(c => `${sudo}${c}`),\n manualInstructions: 'https://developers.cloudflare.com/cloudflare-one/connections/connect-networks/downloads/',\n },\n ];\n}\n\nexport function installDep(dep: DepStatus): boolean {\n if (dep.installCommands.length === 0) return false;\n for (const cmd of dep.installCommands) {\n try {\n execSync(cmd, { stdio: 'inherit', timeout: 300_000 });\n } catch {\n return false;\n }\n }\n return true;\n}\n\n// After Docker install, add user to docker group so sudo isn't needed\nexport function addUserToDockerGroup(): void {\n if (process.platform !== 'linux') return;\n try {\n const user = execSync('whoami', { encoding: 'utf-8' }).trim();\n execSync(`sudo usermod -aG docker ${user}`, { stdio: 'pipe' });\n log.info(`Added ${user} to docker group — log out and back in to apply`);\n } catch {\n // Non-fatal\n }\n}\n\nfunction commandExists(cmd: string): boolean {\n try {\n execSync(`which ${cmd}`, { stdio: 'pipe' });\n return true;\n } catch {\n return false;\n }\n}\n\nfunction isDockerRunning(): boolean {\n try {\n execSync('docker info', { stdio: 'pipe', timeout: 10_000 });\n return true;\n } catch {\n return false;\n }\n}\n"],"mappings":";;;AAAA,SAAS,eAAe;;;ACAxB,SAAS,SAAS;AAClB,SAAS,cAAc,kBAAkB;AACzC,SAAS,YAAY;AACrB,SAAS,eAAe;AACxB,OAAO,UAAU;AAKjB,IAAM,oBAAoB,EAAE,OAAO;AAAA,EACjC,OAAO,EAAE,OAAO,EAAE,QAAQ,mBAAmB;AAAA,EAC7C,eAAe,EAAE,OAAO,EAAE,IAAI,CAAC,EAAE,IAAI,EAAE,EAAE,QAAQ,EAAE;AAAA,EACnD,SAAS,EAAE,OAAO,EAAE,SAAS;AAC/B,CAAC;AAED,IAAM,qBAAqB,EAAE,OAAO;AAAA,EAClC,OAAO,EAAE,OAAO,EAAE,QAAQ,SAAS;AAAA,EACnC,QAAQ,EAAE,OAAO,EAAE,QAAQ,IAAI;AAAA,EAC/B,MAAM,EAAE,OAAO,EAAE,SAAS;AAAA,EAC1B,OAAO,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,SAAS;AAAA;AAAA,EACpC,SAAS,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,SAAS;AAAA;AAAA,EACtC,SAAS,EAAE,KAAK,CAAC,UAAU,QAAQ,MAAM,CAAC,EAAE,QAAQ,QAAQ;AAAA;AAC9D,CAAC;AAED,IAAM,qBAAqB,EAAE,OAAO;AAAA,EAClC,QAAQ,EAAE,OAAO;AAAA,EACjB,QAAQ,EAAE,OAAO;AAAA,EACjB,UAAU,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,QAAQ,CAAC,MAAM,CAAC;AAAA,EAC9C,YAAY,EAAE,QAAQ,EAAE,QAAQ,IAAI;AAAA,EACpC,YAAY,EAAE,OAAO,EAAE,QAAQ,MAAM;AAAA,EACrC,kBAAkB,EAAE,OAAO,EAAE,QAAQ,aAAa;AACpD,CAAC;AAED,IAAM,qBAAqB,EAAE,OAAO;AAAA,EAClC,OAAO,EAAE,OAAO;AAClB,CAAC;AAED,IAAM,sBAAsB,EAAE,OAAO;AAAA,EACnC,MAAM,EAAE,OAAO,EAAE,QAAQ,GAAI;AAAA,EAC7B,KAAK,EAAE,OAAO,EAAE,SAAS;AAAA,EACzB,eAAe,EAAE,OAAO,EAAE,SAAS;AAAA,EACnC,WAAW,EAAE,OAAO,EAAE,SAAS;AACjC,CAAC;AAED,IAAM,eAAe,EAAE,OAAO;AAAA,EAC5B,QAAQ;AAAA,EACR,QAAQ;AAAA,EACR,QAAQ,mBAAmB,QAAQ,CAAC,CAAC;AAAA,EACrC,OAAO,kBAAkB,QAAQ,CAAC,CAAC;AAAA,EACnC,SAAS,oBAAoB,QAAQ,CAAC,CAAC;AAAA,EACvC,eAAe,EAAE,OAAO,EAAE,QAAQ,CAAC;AACrC,CAAC;AAOD,IAAM,wBAAwB,EAAE,OAAO;AAAA,EACrC,QAAQ,EAAE,OAAO,EAAE,SAAS;AAAA,EAC5B,MAAM,EAAE,OAAO,EAAE,QAAQ,MAAM;AAAA,EAC/B,OAAO,kBAAkB,QAAQ,EAAE,SAAS;AAAA,EAC5C,QAAQ,mBAAmB,QAAQ,EAAE,SAAS;AAChD,CAAC;AAMD,SAAS,eAAe,KAAuB;AAC7C,MAAI,OAAO,QAAQ,UAAU;AAC3B,QAAI,IAAI,WAAW,MAAM,GAAG;AAC1B,YAAM,UAAU,IAAI,MAAM,CAAC;AAC3B,YAAM,MAAM,QAAQ,IAAI,OAAO;AAC/B,UAAI,CAAC,IAAK,OAAM,IAAI,MAAM,wBAAwB,OAAO,aAAa;AACtE,aAAO;AAAA,IACT;AACA,WAAO;AAAA,EACT;AACA,MAAI,MAAM,QAAQ,GAAG,EAAG,QAAO,IAAI,IAAI,cAAc;AACrD,MAAI,OAAO,OAAO,QAAQ,UAAU;AAClC,WAAO,OAAO;AAAA,MACZ,OAAO,QAAQ,GAA8B,EAAE,IAAI,CAAC,CAAC,GAAG,CAAC,MAAM,CAAC,GAAG,eAAe,CAAC,CAAC,CAAC;AAAA,IACvF;AAAA,EACF;AACA,SAAO;AACT;AAEA,IAAM,aAAa,KAAK,QAAQ,GAAG,WAAW;AAC9C,IAAM,cAAc,KAAK,YAAY,aAAa;AAE3C,SAAS,WAAW,MAAuB;AAChD,QAAM,aAAa,QAAQ;AAC3B,MAAI,CAAC,WAAW,UAAU,GAAG;AAC3B,UAAM,IAAI,MAAM,qBAAqB,UAAU;AAAA,mBAAsB;AAAA,EACvE;AACA,QAAM,UAAU,aAAa,YAAY,OAAO;AAChD,QAAM,MAAM,KAAK,KAAK,OAAO;AAC7B,MAAI,CAAC,OAAO,OAAO,QAAQ,UAAU;AACnC,UAAM,IAAI,MAAM,oCAAoC,UAAU,EAAE;AAAA,EAClE;AACA,QAAM,WAAW,eAAe,GAAG;AACnC,QAAM,SAAS,aAAa,UAAU,QAAQ;AAC9C,MAAI,CAAC,OAAO,SAAS;AACnB,UAAM,SAAS,OAAO,MAAM,OAAO;AAAA,MACjC,CAAC,MAAM,OAAO,EAAE,KAAK,KAAK,GAAG,CAAC,KAAK,EAAE,OAAO;AAAA,IAC9C,EAAE,KAAK,IAAI;AACX,UAAM,IAAI,MAAM,mBAAmB,UAAU;AAAA,EAAO,MAAM,EAAE;AAAA,EAC9D;AACA,SAAO,OAAO;AAChB;AAEO,SAAS,oBAAoB,eAAoD;AAEtF,QAAM,WAAW,KAAK,eAAe,gBAAgB;AACrD,QAAM,UAAU,KAAK,eAAe,eAAe;AACnD,QAAM,aAAa,WAAW,QAAQ,IAAI,WAAW,WAAW,OAAO,IAAI,UAAU;AACrF,MAAI,CAAC,WAAY,QAAO;AACxB,QAAM,MAAM,KAAK,KAAK,aAAa,YAAY,OAAO,CAAC;AACvD,MAAI,CAAC,OAAO,OAAO,QAAQ,SAAU,QAAO;AAC5C,SAAO,sBAAsB,MAAM,GAAG;AACxC;AAEO,SAAS,aAAa,MAAc,OAIzC;AACA,QAAM,QAAQ,kBAAkB,MAAM;AAAA,IACpC,GAAG,KAAK;AAAA,IACR,GAAG,OAAO;AAAA,EACZ,CAAC;AAED,QAAMA,UAAS,mBAAmB,MAAM;AAAA,IACtC,GAAG,KAAK;AAAA,IACR,GAAG,OAAO;AAAA,EACZ,CAAC;AAED,SAAO,EAAE,OAAO,QAAAA,SAAQ,QAAQ,OAAO,OAAO;AAChD;AAGO,SAAS,oBAAoB,QAAsC;AACxE,aAAW,SAAS,QAAQ;AAE1B,UAAM,QAAQ,MAAM,MAAM,aAAa;AACvC,QAAI,OAAO;AACT,YAAM,QAAQ,MAAM,CAAC,EAAE,KAAK;AAE5B,UAAI,MAAM,WAAW,UAAU,EAAG,QAAO;AAEzC,UAAI,MAAM,SAAS,GAAG,EAAG,QAAO,sBAAsB,KAAK;AAAA,IAC7D;AAAA,EACF;AACA,SAAO;AACT;AAIO,SAAS,oBAAoB,QAAsC;AACxE,aAAW,SAAS,QAAQ;AAC1B,UAAM,QAAQ,MAAM,MAAM,aAAa;AACvC,QAAI,OAAO;AACT,aAAO,MAAM,CAAC,EAAE,KAAK;AAAA,IACvB;AAAA,EACF;AACA,SAAO;AACT;;;ACvKA,SAAS,oBAAoB;;;ACA7B,OAAO,WAAW;AAClB,SAAS,gBAAgB,WAAW,cAAAC,mBAAkB;AACtD,SAAS,QAAAC,aAAY;AACrB,SAAS,WAAAC,gBAAe;AAIxB,IAAI,eAAyB;AAC7B,IAAI;AAEJ,IAAM,SAAmC;AAAA,EACvC,OAAO;AAAA,EACP,MAAM;AAAA,EACN,MAAM;AAAA,EACN,OAAO;AACT;AAEO,SAAS,YAAY,OAAuB;AACjD,iBAAe;AACjB;AAEO,SAAS,oBAA0B;AACxC,QAAM,SAASD,MAAKC,SAAQ,GAAG,aAAa,MAAM;AAClD,MAAI,CAACF,YAAW,MAAM,GAAG;AACvB,cAAU,QAAQ,EAAE,WAAW,KAAK,CAAC;AAAA,EACvC;AACA,QAAM,QAAO,oBAAI,KAAK,GAAE,YAAY,EAAE,MAAM,GAAG,EAAE;AACjD,gBAAcC,MAAK,QAAQ,YAAY,IAAI,MAAM;AACnD;AAEA,SAAS,UAAU,OAA0B;AAC3C,SAAO,OAAO,KAAK,KAAK,OAAO,YAAY;AAC7C;AAEA,SAAS,YAAoB;AAC3B,UAAO,oBAAI,KAAK,GAAE,YAAY,EAAE,MAAM,IAAI,EAAE;AAC9C;AAEA,SAAS,gBAAwB;AAC/B,UAAO,oBAAI,KAAK,GAAE,YAAY;AAChC;AAEA,SAAS,YAAY,OAAe,KAAmB;AACrD,MAAI,CAAC,YAAa;AAClB,MAAI;AACF,mBAAe,aAAa,GAAG,cAAc,CAAC,KAAK,MAAM,OAAO,CAAC,CAAC,KAAK,GAAG;AAAA,CAAI;AAAA,EAChF,QAAQ;AAAA,EAER;AACF;AAEO,IAAM,MAAM;AAAA,EACjB,MAAM,QAAgB,MAAiB;AACrC,gBAAY,SAAS,GAAG;AACxB,QAAI,UAAU,OAAO,EAAG,SAAQ,IAAI,MAAM,KAAK,IAAI,UAAU,CAAC,KAAK,GAAG,EAAE,GAAG,GAAG,IAAI;AAAA,EACpF;AAAA,EACA,KAAK,QAAgB,MAAiB;AACpC,gBAAY,QAAQ,GAAG;AACvB,QAAI,UAAU,MAAM,EAAG,SAAQ,IAAI,MAAM,KAAK,IAAI,UAAU,CAAC,GAAG,GAAG,KAAK,GAAG,IAAI;AAAA,EACjF;AAAA,EACA,KAAK,QAAgB,MAAiB;AACpC,gBAAY,QAAQ,GAAG;AACvB,QAAI,UAAU,MAAM,EAAG,SAAQ,IAAI,MAAM,OAAO,IAAI,UAAU,CAAC,QAAQ,GAAG,KAAK,GAAG,IAAI;AAAA,EACxF;AAAA,EACA,MAAM,QAAgB,MAAiB;AACrC,gBAAY,SAAS,GAAG;AACxB,QAAI,UAAU,OAAO,EAAG,SAAQ,IAAI,MAAM,IAAI,IAAI,UAAU,CAAC,SAAS,GAAG,KAAK,GAAG,IAAI;AAAA,EACvF;AAAA,EACA,QAAQ,QAAgB,MAAiB;AACvC,gBAAY,QAAQ,UAAK,GAAG,EAAE;AAC9B,QAAI,UAAU,MAAM,EAAG,SAAQ,IAAI,MAAM,MAAM,IAAI,UAAU,CAAC,UAAK,GAAG,KAAK,GAAG,IAAI;AAAA,EACpF;AAAA,EACA,OAAO,IAAY,QAAgB,MAAiB;AAClD,gBAAY,QAAQ,IAAI,EAAE,KAAK,GAAG,EAAE;AACpC,QAAI,UAAU,MAAM,EAAG,SAAQ,IAAI,MAAM,KAAK,IAAI,UAAU,CAAC,MAAM,EAAE,GAAG,GAAG,KAAK,GAAG,IAAI;AAAA,EACzF;AACF;;;AD5DO,SAAS,mBAAmB,QAA8B;AAC/D,SAAO,IAAI,aAAa,EAAE,QAAQ,OAAO,OAAO,OAAO,CAAC;AAC1D;AAkCA,eAAsB,YAAY,QAAsB,YAAiD;AAEvG,QAAM,QAAQ,WAAW,MAAM,qBAAqB;AACpD,MAAI,CAAC,MAAO,QAAO;AACnB,QAAM,CAAC,EAAE,SAAS,MAAM,IAAI;AAC5B,QAAM,gBAAgB,QAAQ,YAAY;AAG1C,QAAM,OAAO,MAAM,OAAO,KAAK,aAAa;AAC5C,QAAM,SAAS,MAAM,KAAK,OAAO;AAAA,IAC/B,QAAQ,EAAE,QAAQ,EAAE,IAAI,SAAS,MAAM,EAAE,EAAE;AAAA,IAC3C,OAAO;AAAA,EACT,CAAC;AACD,QAAM,QAAQ,OAAO,MAAM,CAAC;AAC5B,MAAI,CAAC,MAAO,QAAO;AAEnB,QAAM,SAAS,MAAM,MAAM,OAAO;AAClC,QAAM,aAAa,OAAO,MAAM,IAAI,CAAC,MAAM,EAAE,IAAI;AACjD,QAAM,UAAU,oBAAoB,UAAU;AAC9C,QAAM,aAAa,oBAAoB,UAAU;AAEjD,SAAO;AAAA,IACL,IAAI,MAAM;AAAA,IACV,YAAY,MAAM;AAAA,IAClB,OAAO,MAAM;AAAA,IACb,aAAa,MAAM,eAAe;AAAA,IAClC,QAAQ;AAAA,IACR;AAAA,IACA;AAAA,IACA,KAAK,MAAM;AAAA,EACb;AACF;AAEA,eAAsB,YACpB,QACA,QACA,UACe;AACf,MAAI,KAAK,+BAA+B,OAAO,OAAO,gBAAgB,GAAG;AAEzE,QAAM,OAAO,MAAM,OAAO,KAAK,OAAO,OAAO,MAAM;AACnD,QAAM,SAAS,MAAM,KAAK,OAAO;AACjC,QAAM,SAAS,OAAO,OAAO,iBAAiB,YAAY;AAC1D,QAAM,aAAa,OAAO,MAAM,KAAK,CAAC,MAAM,EAAE,KAAK,YAAY,MAAM,MAAM;AAC3E,MAAI,CAAC,YAAY;AACf,QAAI,KAAK,UAAU,OAAO,OAAO,gBAAgB,qCAAqC;AACtF;AAAA,EACF;AAEA,QAAM,OAAO,YAAY,UAAU,EAAE,SAAS,WAAW,GAAG,CAAC;AAC/D;AAEA,eAAsB,eACpB,QACA,QACA,UACA,SACe;AACf,QAAM,OAAO,cAAc,EAAE,SAAS,UAAU,MAAM,QAAQ,CAAC;AAE/D,QAAM,OAAO,MAAM,OAAO,KAAK,OAAO,OAAO,MAAM;AACnD,QAAM,SAAS,MAAM,KAAK,OAAO;AACjC,QAAM,aAAa,OAAO,OAAO,WAAW,YAAY;AACxD,QAAM,OAAO,OAAO,MAAM,KAAK,CAAC,MAAM,EAAE,KAAK,YAAY,MAAM,UAAU;AACzE,MAAI,MAAM;AACR,UAAM,OAAO,YAAY,UAAU,EAAE,SAAS,KAAK,GAAG,CAAC;AAAA,EACzD;AACF;AAEA,eAAsB,eACpB,QACA,UACA,YACe;AACf,MAAI;AAEF,UAAM,QAAQ,MAAM,OAAO,MAAM,QAAQ;AACzC,UAAM,OAAO,MAAM,MAAM;AACzB,QAAI,CAAC,KAAM;AAGX,UAAM,aAAa,MAAM,KAAK,OAAO;AACrC,UAAM,YAAY,QAAQ,UAAU;AACpC,QAAI,UAAU,WAAW,MAAM,KAAK,OAAK,EAAE,SAAS,SAAS,GAAG;AAEhE,QAAI,CAAC,SAAS;AAEZ,YAAM,SAAS,MAAM,OAAO,iBAAiB;AAAA,QAC3C,MAAM;AAAA,QACN,QAAQ,KAAK;AAAA,MACf,CAAC;AACD,YAAM,QAAQ,MAAM,OAAO;AAC3B,gBAAU,OAAO;AAAA,IACnB;AAEA,QAAI,SAAS;AAEX,YAAM,gBAAgB,MAAM,MAAM,OAAO;AACzC,YAAM,WAAW,cAAc,MAAM,IAAI,OAAK,EAAE,EAAE;AAClD,UAAI,CAAC,SAAS,SAAS,OAAO,GAAG;AAC/B,cAAM,OAAO,YAAY,UAAU;AAAA,UACjC,UAAU,CAAC,GAAG,UAAU,OAAO;AAAA,QACjC,CAAC;AACD,YAAI,KAAK,eAAe,UAAU,qCAAqC;AAAA,MACzE;AAAA,IACF;AAAA,EACF,SAAS,KAAK;AAEZ,QAAI,MAAM,+BAA+B,eAAe,QAAQ,IAAI,UAAU,GAAG,EAAE;AAAA,EACrF;AACF;AAEA,eAAsB,WACpB,QACA,UACA,QACe;AACf,QAAM,OAAO,cAAc;AAAA,IACzB,SAAS;AAAA,IACT,MAAM;AAAA;AAAA,EAA2B,MAAM;AAAA,EACzC,CAAC;AACH;;;AE7KA,SAAS,eAAe;AAIjB,SAAS,cAAc,QAAyB;AACrD,SAAO,IAAI,QAAQ,EAAE,MAAM,OAAO,OAAO,MAAM,CAAC;AAClD;AAEA,SAAS,aAAa,KAA8C;AAElE,QAAM,QAAQ,IAAI,MAAM,kCAAkC;AAC1D,MAAI,CAAC,MAAO,OAAM,IAAI,MAAM,4BAA4B,GAAG,EAAE;AAC7D,SAAO,EAAE,OAAO,MAAM,CAAC,GAAG,MAAM,MAAM,CAAC,EAAE;AAC3C;AAEA,eAAsB,OAAO,SAAkB,MAMF;AAC3C,QAAM,EAAE,OAAO,KAAK,IAAI,aAAa,KAAK,OAAO;AAGjD,QAAM,WAAW,MAAM,QAAQ,KAAK,MAAM,KAAK;AAAA,IAC7C;AAAA,IACA;AAAA,IACA,MAAM,GAAG,KAAK,IAAI,KAAK,MAAM;AAAA,IAC7B,OAAO;AAAA,EACT,CAAC;AAED,MAAI,SAAS,KAAK,SAAS,GAAG;AAC5B,UAAME,MAAK,SAAS,KAAK,CAAC;AAC1B,QAAI,KAAK,sBAAsBA,IAAG,QAAQ,EAAE;AAE5C,UAAM,QAAQ,KAAK,MAAM,OAAO;AAAA,MAC9B;AAAA,MACA;AAAA,MACA,aAAaA,IAAG;AAAA,MAChB,MAAM,KAAK;AAAA,IACb,CAAC;AACD,WAAO,EAAE,KAAKA,IAAG,UAAU,QAAQA,IAAG,OAAO;AAAA,EAC/C;AAEA,QAAM,KAAK,MAAM,QAAQ,KAAK,MAAM,OAAO;AAAA,IACzC;AAAA,IACA;AAAA,IACA,OAAO,KAAK;AAAA,IACZ,MAAM,KAAK;AAAA,IACX,MAAM,KAAK;AAAA,IACX,MAAM,KAAK;AAAA,EACb,CAAC;AAED,MAAI,QAAQ,cAAc,GAAG,KAAK,QAAQ,EAAE;AAC5C,SAAO,EAAE,KAAK,GAAG,KAAK,UAAU,QAAQ,GAAG,KAAK,OAAO;AACzD;;;ACxDA,SAAS,oBAAoB;AAC7B,SAAS,YAAY,uBAAuB;;;ACD5C,OAAO,YAAY;AACnB,SAAS,mBAAmB;AAC5B,SAAS,WAAAC,UAAS,cAAc;AAChC,SAAS,QAAAC,aAAY;AACrB,SAAS,cAAAC,aAAY,gBAAAC,eAAc,eAAe,aAAa,cAAc;AAC7E,SAAS,gBAAgB;AAIzB,IAAM,SAAS,IAAI,OAAO;AAE1B,eAAsB,uBAAsC;AAC1D,MAAI;AACF,UAAM,OAAO,KAAK;AAAA,EACpB,SAAS,KAAK;AACZ,UAAM,IAAI;AAAA,MACR;AAAA,IAEF;AAAA,EACF;AACF;AAKA,IAAM,2BAA2B;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAejC,eAAe,YAAY,OAA8B;AACvD,MAAI;AACF,UAAM,OAAO,SAAS,KAAK,EAAE,QAAQ;AACrC,QAAI,MAAM,SAAS,KAAK,gBAAgB;AACxC;AAAA,EACF,QAAQ;AAAA,EAER;AAGA,MAAI,UAAU,iBAAiB;AAC7B,QAAI,KAAK,wEAAwE;AACjF,UAAM,WAAW,YAAYC,MAAK,OAAO,GAAG,iBAAiB,CAAC;AAC9D,QAAI;AACF,oBAAcA,MAAK,UAAU,YAAY,GAAG,wBAAwB;AACpE,eAAS,iCAAiC,QAAQ,IAAI;AAAA,QACpD,OAAO;AAAA,QACP,SAAS;AAAA,MACX,CAAC;AACD,UAAI,QAAQ,2BAA2B;AACvC;AAAA,IACF,SAAS,KAAK;AACZ,YAAM,IAAI;AAAA,QACR;AAAA;AAAA;AAAA,SAGY,eAAe,QAAQ,IAAI,UAAU,GAAG;AAAA,MACtD;AAAA,IACF,UAAE;AACA,aAAO,UAAU,EAAE,WAAW,MAAM,OAAO,KAAK,CAAC;AAAA,IACnD;AAAA,EACF;AAGA,MAAI,KAAK,iBAAiB,KAAK,8BAA8B;AAC7D,QAAM,IAAI,QAAc,CAAC,SAAS,WAAW;AAC3C,WAAO,KAAK,OAAO,CAAC,KAAmB,WAAkC;AACvE,UAAI,KAAK;AACP,YAAI,IAAI,SAAS,SAAS,WAAW,KAAK,IAAI,SAAS,SAAS,KAAK,GAAG;AACtE,iBAAO,OAAO,IAAI,MAAM,iBAAiB,KAAK,mDAAmD,CAAC;AAAA,QACpG;AACA,eAAO,OAAO,GAAG;AAAA,MACnB;AACA,aAAO,MAAM,eAAe,QAAQ,CAAC,SAAuB;AAC1D,YAAI,KAAM,QAAO,IAAI;AAAA,aAChB;AACH,cAAI,QAAQ,SAAS,KAAK,SAAS;AACnC,kBAAQ;AAAA,QACV;AAAA,MACF,CAAC;AAAA,IACH,CAAC;AAAA,EACH,CAAC;AACH;AAOA,eAAsB,gBAAgB,MAIf;AACrB,QAAM,EAAE,cAAc,KAAK,IAAI;AAG/B,QAAM,YAAY,aAAa,KAAK;AAGpC,QAAM,QAAQ,CAAC,GAAG,KAAK,aAAa,aAAa;AACjD,MAAI,aAAa,SAAS,QAAQ;AAChC,eAAW,OAAO,aAAa,SAAS;AACtC,YAAM,KAAK,IAAI,QAAQ,cAAcC,SAAQ,CAAC,CAAC;AAAA,IACjD;AAAA,EACF;AAEA,QAAM,YAAY,MAAM,OAAO,gBAAgB;AAAA,IAC7C,OAAO,aAAa;AAAA,IACpB,MAAM,YAAY,IAAI;AAAA,IACtB,KAAK,CAAC,SAAS,UAAU;AAAA,IACzB,YAAY;AAAA,IACZ,MAAM;AAAA,IACN,YAAY;AAAA,MACV,OAAO;AAAA,MACP,QAAQ,YAAY,aAAa,MAAM;AAAA,MACvC,UAAU,aAAa,OAAO,aAAa,OAAO,MAAM;AAAA,MACxD,aAAa,aAAa,WAAW;AAAA,IACvC;AAAA,IACA,KAAK,CAAC,YAAY;AAAA,EACpB,CAAC;AAED,QAAM,UAAU,MAAM;AACtB,MAAI,KAAK,aAAa,IAAI,aAAa,UAAU,GAAG,MAAM,GAAG,EAAE,CAAC,GAAG;AAEnE,QAAM,UAAqB,EAAE,IAAI,UAAU,IAAI,UAAU,UAAU;AAGnE,QAAM,aAAa,MAAM,KAAK,SAAS,CAAC,MAAM,MAAM,SAAS,CAAC;AAC9D,MAAI,WAAW,aAAa,KAAK,CAAC,WAAW,OAAO,SAAS,IAAI,GAAG;AAClE,UAAM,iBAAiB,OAAO;AAC9B,UAAM,IAAI;AAAA,MACR,iBAAiB,aAAa,KAAK;AAAA;AAAA;AAAA,IAGrC;AAAA,EACF;AAGA,QAAM,YAAY,MAAM,KAAK,SAAS,CAAC,SAAS,MAAM,CAAC;AACvD,MAAI,UAAU,aAAa,GAAG;AAC5B,QAAI,MAAM,+BAA+B;AACzC,UAAM,KAAK,SAAS;AAAA,MAClB;AAAA,MAAM;AAAA,MACN;AAAA,IAGF,CAAC;AAAA,EACH;AAGA,QAAM,WAAW,MAAM,KAAK,SAAS,CAAC,OAAO,WAAW,CAAC;AACzD,MAAI,SAAS,aAAa,GAAG;AAC3B,QAAI,KAAK,uCAAuC;AAEhD,UAAM,aAAa,MAAM,KAAK,SAAS;AAAA,MACrC;AAAA,MAAM;AAAA,MACN;AAAA,IAIF,CAAC;AACD,QAAI,WAAW,aAAa,GAAG;AAC7B,YAAM,IAAI,MAAM,iBAAiB,aAAa,KAAK,sFAAsF;AAAA,IAC3I;AAAA,EACF;AAGA,QAAM,cAAc,MAAM,KAAK,SAAS,CAAC,SAAS,QAAQ,CAAC;AAC3D,MAAI,YAAY,aAAa,GAAG;AAC9B,QAAI,KAAK,wCAAwC;AAGjD,UAAM,WAAW,MAAM,KAAK,SAAS,CAAC,SAAS,KAAK,CAAC;AACrD,QAAI,YAAY;AAEhB,QAAI,SAAS,aAAa,GAAG;AAC3B,YAAM,YAAY,MAAM,KAAK,SAAS;AAAA,QACpC;AAAA,QAAO;AAAA,QAAW;AAAA,QAAM;AAAA,MAC1B,CAAC;AACD,kBAAY,UAAU,aAAa;AAAA,IACrC;AAGA,QAAI,CAAC,WAAW;AACd,UAAI,KAAK,gEAAgE;AACzE,YAAM,mBAAmB,MAAM,KAAK,SAAS;AAAA,QAC3C;AAAA,QAAM;AAAA,QACN;AAAA,MACF,GAAG,EAAE,SAAS,KAAQ,CAAC;AACvB,UAAI,iBAAiB,aAAa,GAAG;AACnC,cAAM,IAAI;AAAA,UACR;AAAA,SACY,iBAAiB,MAAM;AAAA;AAAA,QAErC;AAAA,MACF;AAAA,IACF;AAEA,QAAI,KAAK,uBAAuB;AAAA,EAClC,OAAO;AACL,QAAI,MAAM,wCAAwC;AAAA,EACpD;AAIA,QAAM,KAAK,SAAS;AAAA,IAClB;AAAA,IAAM;AAAA,IACN;AAAA,EAMF,CAAC;AAGD,QAAM,oBAAoB,OAAO;AAGjC,MAAI,aAAa,OAAO,QAAQ;AAC9B,QAAI,KAAK,WAAW,aAAa,MAAM,MAAM,sBAAsB;AACnE,eAAW,OAAO,aAAa,OAAO;AACpC,YAAM,SAAS,MAAM,KAAK,SAAS,CAAC,MAAM,MAAM,GAAG,CAAC;AACpD,UAAI,OAAO,aAAa,GAAG;AACzB,cAAM,IAAI,MAAM,yBAAyB,GAAG;AAAA,EAAK,OAAO,MAAM,EAAE;AAAA,MAClE;AAAA,IACF;AAAA,EACF;AAGA,QAAM,sBAAsB,OAAO;AAEnC,SAAO;AACT;AAGA,eAAe,oBAAoB,WAAqC;AACtE,QAAM,SAAS,MAAM,KAAK,WAAW;AAAA,IACnC;AAAA,IAAM;AAAA,IACN;AAAA,EAKF,CAAC;AACD,QAAM,QAAQ,OAAO,OAAO,KAAK,EAAE,MAAM,IAAI,EAAE,OAAO,OAAO;AAC7D,MAAI,MAAM,WAAW,EAAG;AAExB,QAAM,QAAkB,CAAC;AAGzB,QAAM,SAAS,MAAM,KAAK,WAAW;AAAA,IACnC;AAAA,IAAM;AAAA,IACN;AAAA,EAIF,CAAC;AACD,QAAM,YAAY,oBAAI,IAAqB;AAC3C,aAAW,QAAQ,OAAO,OAAO,KAAK,EAAE,MAAM,IAAI,GAAG;AACnD,UAAM,CAAC,MAAM,IAAI,IAAI,KAAK,MAAM,GAAG;AACnC,cAAU,IAAI,MAAM,SAAS,SAAS;AAAA,EACxC;AAEA,QAAM,YAAY,MAAM;AAAA,IAAK,OAC3B,EAAE,SAAS,gBAAgB,KAAK,EAAE,SAAS,UAAU,KACrD,EAAE,SAAS,kBAAkB,KAAK,EAAE,SAAS,SAAS;AAAA,EACxD;AACA,QAAM,QAAQ,MAAM,KAAK,OAAK,EAAE,SAAS,QAAQ,CAAC;AAClD,QAAM,UAAU,MAAM,KAAK,OAAK,EAAE,SAAS,SAAS,CAAC;AAErD,MAAI,aAAa,CAAC,UAAU,IAAI,QAAQ,GAAG;AACzC,UAAM,KAAK,kCAAkC;AAAA,EAC/C;AACA,MAAI,SAAS,CAAC,UAAU,IAAI,IAAI,GAAG;AACjC,UAAM,KAAK,QAAQ;AAAA,EACrB;AACA,MAAI,WAAW,CAAC,UAAU,IAAI,MAAM,GAAG;AACrC,UAAM,KAAK,eAAe;AAAA,EAC5B;AAEA,MAAI,MAAM,WAAW,EAAG;AAExB,QAAM,WAAW,MAAM,KAAK,GAAG;AAC/B,MAAI,KAAK,4BAA4B,QAAQ,EAAE;AAG/C,QAAM,gBAAgB,MAAM,KAAK,WAAW;AAAA,IAC1C;AAAA,IAAM;AAAA,IACN,iDAAiD,QAAQ,wCAChC,SAAS,QAAQ,eAAe,SAAS,EAAE,QAAQ,gBAAgB,EAAE,EAAE,QAAQ,YAAY,qBAAqB,CAAC,0DAC/F,QAAQ;AAAA,EACrD,CAAC;AAED,MAAI,cAAc,aAAa,GAAG;AAChC,QAAI,QAAQ,gCAAgC;AAAA,EAC9C,OAAO;AACL,QAAI,KAAK,0BAA0B,QAAQ,4DAAuD;AAAA,EACpG;AACF;AAEA,eAAe,sBAAsB,WAAqC;AACxE,QAAM,OAAOA,SAAQ;AAGrB,QAAM,KAAK,WAAW;AAAA,IACpB;AAAA,IAAM;AAAA,IAAM;AAAA,EACd,CAAC;AAGD,QAAM,WAAWD,MAAK,MAAM,WAAW,mBAAmB;AAC1D,MAAIE,YAAW,QAAQ,GAAG;AACxB,UAAM,UAAUC,cAAa,UAAU,OAAO;AAC9C,UAAM,MAAM,OAAO,KAAK,OAAO,EAAE,SAAS,QAAQ;AAClD,UAAM,KAAK,WAAW;AAAA,MACpB;AAAA,MAAM;AAAA,MACN,SAAS,GAAG;AAAA,IACd,CAAC;AACD,QAAI,MAAM,0BAA0B;AAAA,EACtC;AAGA,QAAM,eAAeH,MAAK,MAAM,WAAW,eAAe;AAC1D,MAAIE,YAAW,YAAY,GAAG;AAC5B,UAAM,UAAUC,cAAa,cAAc,OAAO;AAClD,UAAM,MAAM,OAAO,KAAK,OAAO,EAAE,SAAS,QAAQ;AAClD,UAAM,KAAK,WAAW;AAAA,MACpB;AAAA,MAAM;AAAA,MACN,SAAS,GAAG;AAAA,IACd,CAAC;AAAA,EACH;AAEA,MAAI,KAAK,0CAA0C;AACrD;AAQA,eAAsB,KAAK,WAAsB,KAAe,MAKxC;AACtB,QAAM,YAAY,MAAM,UAAU,SAAS,KAAK;AAAA,IAC9C,KAAK;AAAA,IACL,cAAc;AAAA,IACd,cAAc;AAAA,IACd,YAAY,MAAM,WAAW;AAAA,IAC7B,KAAK,MAAM;AAAA,IACX,MAAM,MAAM;AAAA,EACd,CAAC;AAED,QAAM,SAAS,MAAM,UAAU,MAAM,EAAE,QAAQ,MAAM,OAAO,MAAM,CAAC;AAEnE,MAAI,SAAS;AACb,MAAI,SAAS;AAEb,SAAO,IAAI,QAAQ,CAAC,SAAS,WAAW;AACtC,UAAM,eAAe,IAAI,YAAY;AACrC,UAAM,eAAe,IAAI,YAAY;AAErC,WAAO,MAAM,YAAY,QAAQ,cAAc,YAAY;AAE3D,iBAAa,GAAG,QAAQ,CAAC,UAAkB;AAAE,gBAAU,MAAM,SAAS;AAAA,IAAG,CAAC;AAC1E,iBAAa,GAAG,QAAQ,CAAC,UAAkB;AAAE,gBAAU,MAAM,SAAS;AAAA,IAAG,CAAC;AAE1E,QAAI;AACJ,QAAI,MAAM,SAAS;AACjB,cAAQ,WAAW,MAAM;AACvB,eAAO,QAAQ;AACf,gBAAQ,EAAE,UAAU,KAAK,QAAQ,QAAQ,SAAS,8BAA8B,CAAC;AAAA,MACnF,GAAG,KAAK,OAAO;AAAA,IACjB;AAEA,WAAO,GAAG,OAAO,YAAY;AAC3B,UAAI,MAAO,cAAa,KAAK;AAC7B,UAAI;AACF,cAAM,OAAO,MAAM,UAAU,QAAQ;AACrC,gBAAQ,EAAE,UAAU,KAAK,YAAY,GAAG,QAAQ,OAAO,CAAC;AAAA,MAC1D,SAAS,GAAG;AACV,eAAO,CAAC;AAAA,MACV;AAAA,IACF,CAAC;AAED,WAAO,GAAG,SAAS,CAAC,MAAM;AACxB,UAAI,MAAO,cAAa,KAAK;AAC7B,aAAO,CAAC;AAAA,IACV,CAAC;AAAA,EACH,CAAC;AACH;AAEA,eAAsB,4BAA6C;AACjE,QAAM,aAAa,MAAM,OAAO,eAAe,EAAE,KAAK,KAAK,CAAC;AAC5D,QAAM,UAAU,WAAW;AAAA,IAAO,OAChC,EAAE,MAAM,KAAK,OAAK,EAAE,WAAW,YAAY,CAAC;AAAA,EAC9C;AACA,MAAI,UAAU;AACd,aAAW,KAAK,SAAS;AACvB,QAAI;AACF,YAAM,YAAY,OAAO,aAAa,EAAE,EAAE;AAC1C,UAAI,EAAE,UAAU,WAAW;AACzB,cAAM,UAAU,KAAK,EAAE,GAAG,EAAE,CAAC;AAAA,MAC/B;AACA,YAAM,UAAU,OAAO,EAAE,OAAO,KAAK,CAAC;AACtC,UAAI,KAAK,iCAAiC,EAAE,MAAM,CAAC,CAAC,KAAK,EAAE,GAAG,MAAM,GAAG,EAAE,CAAC,GAAG;AAC7E;AAAA,IACF,QAAQ;AAAA,IAER;AAAA,EACF;AACA,SAAO;AACT;AAEA,eAAsB,iBAAiB,WAAqC;AAC1E,MAAI;AACF,UAAM,UAAU,SAAS,KAAK,EAAE,GAAG,EAAE,CAAC;AAAA,EACxC,QAAQ;AAAA,EAER;AACA,MAAI;AACF,UAAM,UAAU,SAAS,OAAO,EAAE,OAAO,KAAK,CAAC;AAAA,EACjD,QAAQ;AAAA,EAER;AACA,MAAI,KAAK,aAAa,UAAU,GAAG,MAAM,GAAG,EAAE,CAAC,YAAY;AAC7D;AAEA,SAAS,YAAY,KAAqB;AACxC,QAAM,QAAQ,IAAI,MAAM,6BAA6B;AACrD,MAAI,CAAC,MAAO,OAAM,IAAI,MAAM,2BAA2B,GAAG,+DAA+D;AACzH,QAAM,CAAC,EAAE,KAAK,IAAI,IAAI;AACtB,QAAM,QAAQ,WAAW,GAAG;AAC5B,MAAI,SAAS,EAAG,OAAM,IAAI,MAAM,mCAAmC,GAAG,GAAG;AACzE,QAAM,cAAsC;AAAA,IAC1C,GAAG;AAAA,IACH,GAAG,OAAO;AAAA,IACV,GAAG,OAAO,OAAO;AAAA,IACjB,GAAG,OAAO,OAAO,OAAO;AAAA,EAC1B;AACA,SAAO,KAAK,MAAM,QAAQ,YAAY,KAAK,YAAY,CAAC,CAAC;AAC3D;;;ACjcA,IAAM,+BAA+B,KAAK,KAAK;AAc/C,IAAM,sBAAsB;AAAA,EAC1B;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF;AAEA,IAAM,sBAAsB;AAAA,EAC1B;AAAA,EACA;AACF;AAEA,SAAS,cAAc,QAAyB;AAC9C,SAAO,oBAAoB,KAAK,CAAC,MAAM,EAAE,KAAK,MAAM,CAAC;AACvD;AAEA,SAAS,YAAY,QAAyB;AAC5C,SAAO,oBAAoB,KAAK,CAAC,MAAM,EAAE,KAAK,MAAM,CAAC;AACvD;AAEA,SAAS,gBAAgB,QAAwB;AAC/C,QAAM,QAAQ,OAAO,MAAM,0BAA0B;AACrD,MAAI,MAAO,QAAO,SAAS,MAAM,CAAC,CAAC,IAAI;AACvC,SAAO;AACT;AAEA,IAAM,yBAAyB;AAE/B,eAAsB,aAAa,MAMuC;AACxE,QAAM,EAAE,WAAW,aAAa,QAAQ,UAAU,YAAY,IAAI;AAClE,MAAI,aAAa;AACjB,MAAI,mBAAmB;AAGvB,QAAM,YAAY,OAAO,KAAK,MAAM,EAAE,SAAS,QAAQ;AACvD,QAAM,KAAK,WAAW;AAAA,IACpB;AAAA,IAAM;AAAA,IACN,mCAAmC,SAAS;AAAA,EAC9C,CAAC;AAED,WAAS,IAAI,GAAG,KAAK,YAAY,eAAe,KAAK;AACnD,QAAI,OAAO,UAAU,aAAa,CAAC,IAAI,YAAY,aAAa,EAAE;AAIlE,UAAM,MAAM;AAAA,MACV;AAAA,MAAM;AAAA,MACN;AAAA,QACE;AAAA,QACA;AAAA,QAAM;AAAA,QACN;AAAA,QAAW,YAAY;AAAA,QACvB;AAAA,QAAmB;AAAA,QACnB;AAAA,QAAe;AAAA,QACf;AAAA,QACA;AAAA,MACF,EAAE,KAAK,GAAG;AAAA,IACZ;AAEA,UAAM,YAAY,YAAY,UAC1B,YAAY,UAAU,MACtB;AAEJ,UAAM,SAAS,MAAM,KAAK,WAAW,KAAK;AAAA,MACxC,MAAM;AAAA,MACN,KAAK,CAAC,uBAAuB,+CAA+C;AAAA,MAC5E,SAAS;AAAA,IACX,CAAC;AAED,UAAM,WAAW,OAAO,SAAS,OAAO;AACxC,iBAAa;AAGb,UAAM,UAAU,SAAS,MAAM,IAAI,EAAE,KAAK;AAC1C,QAAI,SAAS;AACX,UAAI,MAAM,kCAAkC,OAAO,EAAE;AAAA,IACvD;AAEA,UAAM,cAAc,cAAc,QAAQ;AAC1C,UAAM,YAAY,YAAY,QAAQ,KAAM,OAAO,aAAa,KAAK,IAAI;AAEzE,UAAM,cAA2B;AAAA,MAC/B,WAAW;AAAA,MACX,UAAU,OAAO;AAAA,MACjB,QAAQ,OAAO;AAAA,MACf,QAAQ,OAAO;AAAA,MACf;AAAA,MACA;AAAA,IACF;AAEA,kBAAc,WAAW;AAEzB,QAAI,WAAW;AACb,UAAI,OAAO,UAAU,mBAAmB,CAAC,aAAa;AACtD,aAAO,EAAE,YAAY,GAAG,SAAS,MAAM,WAAW;AAAA,IACpD;AAEA,QAAI,aAAa;AACf;AACA,UAAI,mBAAmB,wBAAwB;AAC7C,YAAI,OAAO,UAAU,gBAAgB,gBAAgB,mBAAmB;AACxE,eAAO,EAAE,YAAY,GAAG,SAAS,OAAO,WAAW;AAAA,MACrD;AACA,YAAM,SAAS,gBAAgB,QAAQ;AACvC,UAAI,OAAO,UAAU,iBAAiB,gBAAgB,IAAI,sBAAsB,oBAAe,KAAK,MAAM,SAAS,GAAI,CAAC,GAAG;AAC3H,YAAM,MAAM,MAAM;AAElB;AACA;AAAA,IACF;AAEA,QAAI,OAAO,aAAa,GAAG;AACzB,UAAI,OAAO,UAAU,kBAAkB,OAAO,QAAQ,kBAAkB;AAAA,IAC1E;AAAA,EAKF;AAEA,MAAI,OAAO,UAAU,mBAAmB,YAAY,aAAa,WAAW;AAC5E,SAAO,EAAE,YAAY,YAAY,eAAe,SAAS,OAAO,WAAW;AAC7E;AAEA,SAAS,MAAM,IAA2B;AACxC,SAAO,IAAI,QAAQ,CAAC,YAAY,WAAW,SAAS,EAAE,CAAC;AACzD;;;ACpJA,eAAsB,UAAU,WAAsB,MAEpC;AAChB,QAAM,IAAI,EAAE,MAAM,WAAW;AAC7B,QAAM,KAAK,WAAW,CAAC,OAAO,UAAU,aAAa,UAAU,GAAG,CAAC;AACnE,QAAM,KAAK,WAAW,CAAC,OAAO,UAAU,cAAc,oBAAoB,GAAG,CAAC;AAC9E,QAAM,KAAK,WAAW,CAAC,OAAO,UAAU,YAAY,kBAAkB,YAAY,GAAG,CAAC;AACtF,MAAI,KAAK,6BAA6B,KAAK,UAAU,EAAE;AACzD;AAEA,eAAsB,cAAc,WAAsB,MAMJ;AACpD,QAAM,EAAE,YAAY,UAAU,OAAO,YAAY,IAAI;AAErD,QAAM,IAAI,EAAE,MAAM,WAAW;AAG7B,QAAM,SAAS,MAAM,KAAK,WAAW,CAAC,OAAO,UAAU,aAAa,GAAG,CAAC;AACxE,MAAI,OAAO,OAAO,KAAK,GAAG;AACxB,UAAM,KAAK,WAAW,CAAC,OAAO,OAAO,IAAI,GAAG,CAAC;AAC7C,UAAM,UAAU,GAAG,QAAQ,KAAK,KAAK;AACrC,UAAM,KAAK,WAAW,CAAC,OAAO,UAAU,MAAM,OAAO,GAAG,CAAC;AAAA,EAC3D;AAGA,QAAM,cAAc,MAAM,KAAK,WAAW;AAAA,IACxC;AAAA,IAAO;AAAA,IAAY;AAAA,IAAW;AAAA,IAAQ;AAAA,IAAS;AAAA,EACjD,GAAG,CAAC;AACJ,QAAM,cAAc,SAAS,YAAY,OAAO,KAAK,CAAC,KAAK;AAE3D,MAAI,gBAAgB,GAAG;AACrB,QAAI,KAAK,oBAAoB;AAC7B,WAAO,EAAE,QAAQ,OAAO,aAAa,EAAE;AAAA,EACzC;AAGA,QAAM,KAAK,WAAW;AAAA,IACpB;AAAA,IAAM;AAAA,IACN,uDAAuD,WAAW;AAAA,EACpE,GAAG,CAAC;AAGJ,QAAM,aAAa,MAAM,KAAK,WAAW,CAAC,OAAO,QAAQ,MAAM,UAAU,UAAU,GAAG,CAAC;AACvF,MAAI,WAAW,aAAa,GAAG;AAE7B,UAAM,aAAa,WAAW,OAAO,QAAQ,2BAA2B,oBAAoB;AAC5F,QAAI,MAAM,gBAAgB,UAAU,EAAE;AACtC,WAAO,EAAE,QAAQ,OAAO,YAAY;AAAA,EACtC;AAEA,MAAI,QAAQ,UAAU,WAAW,iBAAiB,UAAU,EAAE;AAC9D,SAAO,EAAE,QAAQ,MAAM,YAAY;AACrC;;;AClDA,SAAS,eAAAC,cAAa,UAAAC,SAAQ,iBAAAC,sBAAqB;AACnD,SAAS,QAAAC,aAAY;AACrB,SAAS,UAAAC,eAAc;AACvB,SAAS,YAAAC,iBAAgB;AAUzB,SAAS,YAAY,QAAgB,YAA6B;AAChE,QAAM,QAAkB,CAAC;AAEzB,MAAI,YAAY;AACd,UAAM,KAAK,UAAU;AACrB,UAAM,KAAK,EAAE;AAAA,EACf;AAEA,QAAM,KAAK,YAAY,OAAO,UAAU,WAAM,OAAO,KAAK,EAAE;AAC5D,QAAM,KAAK,EAAE;AAEb,MAAI,OAAO,aAAa;AACtB,UAAM,KAAK,OAAO,WAAW;AAAA,EAC/B;AAEA,QAAM,KAAK,EAAE;AACb,QAAM,KAAK,iBAAiB;AAC5B,QAAM,KAAK,mFAA8E;AACzF,QAAM,KAAK,qEAAqE;AAChF,QAAM,KAAK,sCAAsC;AACjD,QAAM,KAAK,mFAAmF;AAC9F,QAAM,KAAK,6EAA6E;AACxF,QAAM,KAAK,sFAAsF;AACjG,QAAM,KAAK,kEAAkE;AAC7E,QAAM,KAAK,qEAAqE;AAChF,QAAM,KAAK,yFAAyF;AAEpG,SAAO,MAAM,KAAK,IAAI;AACxB;AAEA,SAAS,QAAQ,GAAmB;AAClC,SAAO,EAAE,YAAY,EAAE,QAAQ,eAAe,GAAG,EAAE,QAAQ,UAAU,EAAE,EAAE,MAAM,GAAG,EAAE;AACtF;AAGA,SAAS,cAAc,MAAc,OAAqB;AAExD,MAAI,CAAC,QAAQ,qBAAqB,KAAK,IAAI,KAAK,KAAK,WAAW,GAAG,GAAG;AACpE,UAAM,IAAI,MAAM,WAAW,KAAK,MAAM,IAAI,GAAG;AAAA,EAC/C;AACF;AAGA,SAAS,cAAc,aAAoD;AACzE,QAAM,MAAML,aAAYG,MAAKC,QAAO,GAAG,gBAAgB,CAAC;AACxD,QAAM,OAAOD,MAAK,KAAK,YAAY;AACnC,EAAAD,eAAc,MAAM;AAAA,QAAoB,WAAW;AAAA,GAAO,EAAE,MAAM,IAAM,CAAC;AACzE,SAAO,EAAE,KAAK,KAAK;AACrB;AAEA,SAAS,OAAO,aAAwC;AACtD,SAAO,EAAE,GAAG,QAAQ,KAAK,aAAa,aAAa,qBAAqB,IAAI;AAC9E;AAGA,SAAS,oBAAoB,SAAiB,aAA6B;AACzE,QAAM,UAAU,cAAc,WAAW;AACzC,QAAM,YAAY,QAAQ,QAAQ,YAAY,yBAAyB;AACvE,MAAI;AAEF,UAAM,SAASG;AAAA,MACb,6BAA6B,SAAS;AAAA,MACtC,EAAE,OAAO,QAAQ,SAAS,KAAQ,KAAK,OAAO,QAAQ,IAAI,GAAG,UAAU,QAAQ;AAAA,IACjF;AAEA,UAAM,QAAQ,OAAO,MAAM,kCAAkC;AAC7D,QAAI,MAAO,QAAO,MAAM,CAAC;AAAA,EAC3B,QAAQ;AAAA,EAER,UAAE;AACA,IAAAJ,QAAO,QAAQ,KAAK,EAAE,WAAW,MAAM,OAAO,KAAK,CAAC;AAAA,EACtD;AACA,SAAO;AACT;AAGA,SAAS,YAAY,SAAiB,YAAoB,aAA6B;AACrF,gBAAc,YAAY,aAAa;AACvC,QAAM,UAAUD,aAAYG,MAAKC,QAAO,GAAG,WAAW,CAAC;AACvD,QAAM,UAAU,cAAc,WAAW;AACzC,QAAM,YAAY,QAAQ,QAAQ,YAAY,yBAAyB;AAEvE,MAAI;AACF,IAAAC,UAAS,2BAA2B,UAAU,OAAO,SAAS,IAAI,OAAO,IAAI;AAAA,MAC3E,OAAO;AAAA,MACP,SAAS;AAAA,MACT,KAAK,OAAO,QAAQ,IAAI;AAAA,IAC1B,CAAC;AAAA,EACH,UAAE;AACA,IAAAJ,QAAO,QAAQ,KAAK,EAAE,WAAW,MAAM,OAAO,KAAK,CAAC;AAAA,EACtD;AACA,SAAO;AACT;AAEA,eAAsB,cAAc,MAKV;AACxB,QAAM,EAAE,QAAQ,QAAQ,cAAc,QAAQ,IAAI;AAElD,MAAI,CAAC,OAAO,SAAS;AACnB,WAAO;AAAA,MACL,UAAU,OAAO;AAAA,MACjB,SAAS;AAAA,MACT,OAAO;AAAA,MACP,YAAY;AAAA,IACd;AAAA,EACF;AAGA,MAAI,CAAC,OAAO,QAAQ,WAAW,UAAU,GAAG;AAC1C,WAAO;AAAA,MACL,UAAU,OAAO;AAAA,MACjB,SAAS;AAAA,MACT,OAAO,sBAAsB,OAAO,OAAO;AAAA,MAC3C,YAAY;AAAA,IACd;AAAA,EACF;AAEA,QAAM,aAAa,YAAY,OAAO,UAAU,IAAI,QAAQ,OAAO,KAAK,CAAC;AAEzE,QAAM,gBAAgB,GAAG,OAAO,UAAU,IAAI,KAAK,IAAI,CAAC,GAAG,YAAY,EAAE,QAAQ,iBAAiB,GAAG;AACrG,MAAI;AACJ,MAAI;AAEJ,MAAI;AAEF,UAAM,YAAY,cAAc,QAAQ,OAAO,EAAE;AACjD,QAAI,OAAO,OAAO,YAAY,kBAAa,OAAO,OAAO,EAAE;AAG3D,UAAM,eAAe,oBAAoB,OAAO,SAAS,OAAO,OAAO,KAAK;AAC5E,QAAI,OAAO,OAAO,YAAY,mBAAmB,YAAY,EAAE;AAG/D,cAAU,YAAY,OAAO,SAAS,cAAc,OAAO,OAAO,KAAK;AACvE,QAAI,OAAO,OAAO,YAAY,aAAa;AAG3C,UAAM,YAAY,oBAAoB,OAAO;AAG7C,UAAM,aAAa,OAAO,cAAc,WAAW,QAAQ;AAC3D,UAAM,EAAE,OAAO,QAAAK,SAAQ,OAAO,IAAI,aAAa,QAAQ,SAAS;AAEhE,QAAI,WAAW;AACb,UAAI,OAAO,OAAO,YAAY,iCAAiC;AAAA,IACjE;AACA,QAAI,OAAO,YAAY;AACrB,UAAI,OAAO,OAAO,YAAY,sBAAsB,OAAO,UAAU,EAAE;AAAA,IACzE;AAGA,QAAI,eAAe,cAAc;AAC/B,MAAAL,QAAO,SAAS,EAAE,WAAW,MAAM,OAAO,KAAK,CAAC;AAChD,gBAAU,YAAY,OAAO,SAAS,YAAY,OAAO,OAAO,KAAK;AAAA,IACvE;AAIA,IAAAI,UAAS,mBAAmB,UAAU,OAAO,EAAE,KAAK,SAAS,OAAO,OAAO,CAAC;AAG5E,gBAAY,MAAM,gBAAgB;AAAA,MAChC,cAAcC;AAAA,MACd,eAAe;AAAA,MACf,MAAM;AAAA,IACR,CAAC;AAGD,UAAM,UAAU,WAAW,EAAE,WAAW,CAAC;AAGzC,UAAM,cAAc,YAAY,QAAQ,MAAM;AAC9C,UAAM,cAAc,MAAM,aAAa;AAAA,MACrC;AAAA,MACA,aAAa;AAAA,MACb,QAAQ;AAAA,MACR,UAAU,OAAO;AAAA,IACnB,CAAC;AAGD,UAAM,YAAY,MAAM,cAAc,WAAW;AAAA,MAC/C;AAAA,MACA,UAAU,OAAO;AAAA,MACjB,OAAO,OAAO;AAAA,MACd,SAAS,OAAO;AAAA,MAChB,aAAa,OAAO,OAAO;AAAA,IAC7B,CAAC;AAED,QAAI,CAAC,UAAU,QAAQ;AACrB,YAAM,WAAW,cAAc,OAAO,IAAI,qBAAqB;AAC/D,aAAO;AAAA,QACL,UAAU,OAAO;AAAA,QACjB,SAAS;AAAA,QACT,OAAO;AAAA,QACP,YAAY,YAAY;AAAA,MAC1B;AAAA,IACF;AAGA,UAAM,SAAmB;AAAA,MACvB,aAAa,OAAO,UAAU,KAAK,OAAO,GAAG;AAAA,MAC7C;AAAA,IACF;AAGA,QAAI,OAAO,aAAa;AACtB,YAAM,OAAO,OAAO,YAAY,SAAS,MACrC,OAAO,YAAY,MAAM,GAAG,GAAI,IAAI,kCACpC,OAAO;AACX,aAAO,KAAK,kBAAkB,IAAI,MAAM,EAAE;AAAA,IAC5C;AAEA,WAAO;AAAA,MACL;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA,kBAAkB,YAAY,UAAU;AAAA,MACxC,eAAe,UAAU,WAAW;AAAA,MACpC,aAAa,MAAM,KAAK;AAAA,MACxB;AAAA,MACA;AAAA,MACA;AAAA,IACF;AAEA,UAAM,KAAK,MAAM,OAAO,SAAS;AAAA,MAC/B,SAAS,OAAO;AAAA,MAChB,QAAQ;AAAA,MACR,YAAY;AAAA,MACZ,OAAO,GAAG,OAAO,UAAU,KAAK,OAAO,KAAK;AAAA,MAC5C,MAAM,OAAO,KAAK,IAAI;AAAA,IACxB,CAAC;AAGD,UAAM,eAAe,cAAc,QAAQ,OAAO,IAAI,cAAc,GAAG,GAAG,EAAE;AAI5E,UAAM,eAAe,cAAc,OAAO,IAAI,UAAU;AAExD,QAAI,QAAQ,GAAG,OAAO,UAAU,gBAAW,GAAG,GAAG,EAAE;AACnD,WAAO;AAAA,MACL,UAAU,OAAO;AAAA,MACjB,SAAS;AAAA,MACT,OAAO,GAAG;AAAA,MACV,YAAY,YAAY;AAAA,IAC1B;AAAA,EACF,SAAS,KAAK;AACZ,UAAM,MAAM,eAAe,QAAQ,IAAI,UAAU,OAAO,GAAG;AAC3D,QAAI,MAAM,GAAG,OAAO,UAAU,YAAY,GAAG,EAAE;AAE/C,QAAI;AACF,YAAM,WAAW,cAAc,OAAO,IAAI,GAAG;AAAA,IAC/C,QAAQ;AAAA,IAER;AAEA,WAAO;AAAA,MACL,UAAU,OAAO;AAAA,MACjB,SAAS;AAAA,MACT,OAAO;AAAA,MACP,YAAY;AAAA,IACd;AAAA,EACF,UAAE;AAEA,QAAI,WAAW;AACb,YAAM,iBAAiB,SAAS;AAAA,IAClC;AAGA,QAAI,SAAS;AACX,UAAI;AACF,QAAAL,QAAO,SAAS,EAAE,WAAW,MAAM,OAAO,KAAK,CAAC;AAAA,MAClD,QAAQ;AAAA,MAER;AAAA,IACF;AAAA,EACF;AACF;;;AJzRA,SAAS,gBAAgB,MAAc,WAAmB,QAAyB;AACjF,QAAM,WAAW,WAAW,UAAU,MAAM,EAAE,OAAO,IAAI,EAAE,OAAO,KAAK;AACvE,MAAI;AACF,WAAO,gBAAgB,OAAO,KAAK,QAAQ,GAAG,OAAO,KAAK,SAAS,CAAC;AAAA,EACtE,QAAQ;AACN,WAAO;AAAA,EACT;AACF;AAEO,IAAM,gBAAN,MAAoB;AAAA,EAMzB,YACU,QACA,cACA,SACR;AAHQ;AACA;AACA;AAAA,EACP;AAAA,EAHO;AAAA,EACA;AAAA,EACA;AAAA,EARF,SAAS,oBAAI,IAAY;AAAA,EACzB,QAAkB,CAAC;AAAA,EACnB,YAAY,oBAAI,IAAY;AAAA;AAAA,EAC5B;AAAA,EAQR,QAAuB;AACrB,UAAM,OAAO,KAAK,OAAO,SAAS,QAAQ;AAC1C,UAAM,iBAAiB,OAAO;AAE9B,SAAK,SAAS,aAAa,CAAC,KAAK,QAAQ;AAEvC,UAAI,IAAI,WAAW,UAAU,IAAI,QAAQ,aAAa,IAAI,QAAQ,aAAa;AAC7E,YAAI,UAAU,KAAK,EAAE,gBAAgB,mBAAmB,CAAC;AACzD,YAAI,IAAI,KAAK,UAAU,EAAE,QAAQ,MAAM,QAAQ,KAAK,OAAO,MAAM,QAAQ,KAAK,MAAM,QAAQ,UAAU,KAAK,OAAO,cAAc,CAAC,CAAC;AAClI;AAAA,MACF;AAGA,UAAI,IAAI,WAAW,UAAW,IAAI,QAAQ,cAAc,IAAI,QAAQ,0BAA2B;AAC7F,YAAI,UAAU,GAAG;AACjB,YAAI,IAAI;AACR;AAAA,MACF;AAEA,UAAI,OAAO;AACX,UAAI,YAAY;AAChB,UAAI,GAAG,QAAQ,CAAC,UAAkB;AAChC,qBAAa,MAAM;AACnB,YAAI,YAAY,gBAAgB;AAC9B,cAAI,UAAU,GAAG;AACjB,cAAI,IAAI,mBAAmB;AAC3B,cAAI,QAAQ;AACZ;AAAA,QACF;AACA,gBAAQ;AAAA,MACV,CAAC;AACD,UAAI,GAAG,OAAO,MAAM;AAElB,YAAI,KAAK,OAAO,SAAS,eAAe;AACtC,gBAAM,MAAM,IAAI,QAAQ,kBAAkB;AAC1C,cAAI,CAAC,OAAO,CAAC,gBAAgB,MAAM,KAAK,KAAK,OAAO,QAAQ,aAAa,GAAG;AAC1E,gBAAI,KAAK,sCAAsC;AAC/C,gBAAI,UAAU,GAAG;AACjB,gBAAI,IAAI,mBAAmB;AAC3B;AAAA,UACF;AAAA,QACF;AAGA,YAAI,UAAU,GAAG;AACjB,YAAI,IAAI,IAAI;AAGZ,aAAK,KAAK,cAAc,IAAI;AAAA,MAC9B,CAAC;AAAA,IACH,CAAC;AAED,WAAO,IAAI,QAAQ,CAAC,YAAY;AAC9B,WAAK,OAAQ,OAAO,MAAM,MAAM;AAC9B,YAAI,KAAK,oCAAoC,IAAI,EAAE;AACnD,gBAAQ;AAAA,MACV,CAAC;AAAA,IACH,CAAC;AAAA,EACH;AAAA,EAEA,OAAa;AACX,SAAK,QAAQ,MAAM;AACnB,QAAI,KAAK,wBAAwB;AAAA,EACnC;AAAA,EAEA,MAAc,cAAc,MAA6B;AACvD,QAAI;AACJ,QAAI;AACF,gBAAU,KAAK,MAAM,IAAI;AAAA,IAC3B,QAAQ;AACN,UAAI,KAAK,sBAAsB;AAC/B;AAAA,IACF;AAGA,QAAI,QAAQ,SAAS,QAAS;AAE9B,UAAM,EAAE,QAAQ,KAAK,IAAI;AACzB,UAAM,kBAAkB,KAAK,OAAO,OAAO,SAAS,IAAI,CAAC,MAAM,EAAE,YAAY,CAAC;AAC9E,UAAM,gBAAgB,KAAK,MAAM,KAAK,YAAY;AAGlD,QAAI,WAAW,YAAY,WAAW,UAAU;AAE9C,UAAI,CAAC,gBAAgB,SAAS,aAAa,GAAG;AAC5C,YAAI,MAAM,GAAG,KAAK,UAAU,aAAa,KAAK,MAAM,IAAI,iCAAiC;AACzF;AAAA,MACF;AAGA,UAAI,WAAW,YAAY,CAAC,QAAQ,aAAa,SAAS;AACxD,YAAI,MAAM,GAAG,KAAK,UAAU,6CAA6C;AACzE;AAAA,MACF;AAAA,IACF,OAAO;AACL;AAAA,IACF;AAGA,QAAI,KAAK,OAAO,IAAI,KAAK,EAAE,GAAG;AAC5B,UAAI,MAAM,GAAG,KAAK,UAAU,4BAA4B;AACxD;AAAA,IACF;AACA,QAAI,KAAK,UAAU,IAAI,KAAK,EAAE,GAAG;AAC/B,UAAI,MAAM,GAAG,KAAK,UAAU,+CAA+C;AAC3E;AAAA,IACF;AAGA,QAAI,KAAK,OAAO,QAAQ,KAAK,OAAO,eAAe;AACjD,UAAI,KAAK,GAAG,KAAK,UAAU,kBAAkB,KAAK,OAAO,IAAI,IAAI,KAAK,OAAO,aAAa,WAAW;AACrG,YAAM,cAAc,KAAK,OAAO,IAAI,CAAC,MAAM,EAAE,IAAI;AACjD,YAAMM,UAAiB;AAAA,QACrB,IAAI,KAAK;AAAA,QACT,YAAY,KAAK;AAAA,QACjB,OAAO,KAAK;AAAA,QACZ,aAAa,KAAK,eAAe;AAAA,QACjC,QAAQ;AAAA,QACR,SAAS,oBAAoB,WAAW;AAAA,QACxC,YAAY,oBAAoB,WAAW;AAAA,QAC3C,KAAK,KAAK;AAAA,MACZ;AACA,WAAK,MAAM,KAAKA,OAAM;AACtB;AAAA,IACF;AAGA,UAAM,aAAa,KAAK,OAAO,IAAI,CAAC,MAAM,EAAE,IAAI;AAChD,UAAM,UAAU,oBAAoB,UAAU;AAC9C,QAAI,CAAC,SAAS;AACZ,UAAI,KAAK,GAAG,KAAK,UAAU,4BAA4B;AACvD;AAAA,IACF;AAEA,UAAM,SAAiB;AAAA,MACrB,IAAI,KAAK;AAAA,MACT,YAAY,KAAK;AAAA,MACjB,OAAO,KAAK;AAAA,MACZ,aAAa,KAAK,eAAe;AAAA,MACjC,QAAQ;AAAA,MACR;AAAA,MACA,YAAY,oBAAoB,UAAU;AAAA,MAC1C,KAAK,KAAK;AAAA,IACZ;AAEA,SAAK,SAAS,MAAM;AAAA,EACtB;AAAA,EAEQ,SAAS,QAAsB;AACrC,SAAK,OAAO,IAAI,OAAO,EAAE;AACzB,QAAI,OAAO,OAAO,YAAY,sBAAiB,OAAO,OAAO,EAAE;AAE/D,SAAK,cAAc;AAAA,MACjB;AAAA,MACA,QAAQ,KAAK;AAAA,MACb,cAAc,KAAK;AAAA,MACnB,SAAS,KAAK;AAAA,IAChB,CAAC,EAAE,QAAQ,MAAM;AACf,WAAK,OAAO,OAAO,OAAO,EAAE;AAC5B,WAAK,UAAU,IAAI,OAAO,EAAE;AAC5B,WAAK,WAAW;AAAA,IAClB,CAAC;AAAA,EACH;AAAA,EAEQ,aAAmB;AACzB,WAAO,KAAK,MAAM,SAAS,KAAK,KAAK,OAAO,OAAO,KAAK,OAAO,eAAe;AAC5E,YAAM,OAAO,KAAK,MAAM,MAAM;AAE9B,UAAI,KAAK,OAAO,IAAI,KAAK,EAAE,EAAG;AAC9B,UAAI,OAAO,KAAK,YAAY,aAAa,KAAK,MAAM,MAAM,aAAa;AACvE,WAAK,SAAS,IAAI;AAAA,IACpB;AAAA,EACF;AACF;;;AK5NA,SAAS,aAAa;AAQtB,eAAsB,iBAAiB,MAAmC;AACxE,SAAO,IAAI,QAAQ,CAAC,SAAS,WAAW;AACtC,UAAM,OAAO,MAAM,eAAe,CAAC,UAAU,SAAS,oBAAoB,IAAI,EAAE,GAAG;AAAA,MACjF,OAAO,CAAC,UAAU,QAAQ,MAAM;AAAA,IAClC,CAAC;AAED,QAAI,WAAW;AACf,UAAM,UAAU,WAAW,MAAM;AAC/B,UAAI,CAAC,UAAU;AACb,eAAO,IAAI,MAAM,oCAAoC,CAAC;AAAA,MACxD;AAAA,IACF,GAAG,GAAM;AAET,UAAM,eAAe,CAAC,SAAiB;AACrC,YAAM,OAAO,KAAK,SAAS;AAE3B,YAAM,QAAQ,KAAK,MAAM,4CAA4C;AACrE,UAAI,SAAS,CAAC,UAAU;AACtB,mBAAW;AACX,qBAAa,OAAO;AACpB,gBAAQ,EAAE,KAAK,MAAM,CAAC,GAAG,SAAS,KAAK,CAAC;AAAA,MAC1C;AAAA,IACF;AAEA,SAAK,OAAO,GAAG,QAAQ,YAAY;AACnC,SAAK,OAAO,GAAG,QAAQ,YAAY;AAEnC,SAAK,GAAG,SAAS,CAAC,QAAQ;AACxB,UAAI,CAAC,UAAU;AACb,qBAAa,OAAO;AACpB,YAAK,IAA8B,SAAS,UAAU;AACpD,iBAAO,IAAI,MAAM,6HAA6H,CAAC;AAAA,QACjJ,OAAO;AACL,iBAAO,GAAG;AAAA,QACZ;AAAA,MACF;AAAA,IACF,CAAC;AAED,SAAK,GAAG,QAAQ,CAAC,SAAS;AACxB,UAAI,CAAC,UAAU;AACb,qBAAa,OAAO;AACpB,eAAO,IAAI,MAAM,gCAAgC,IAAI,EAAE,CAAC;AAAA,MAC1D;AAAA,IACF,CAAC;AAAA,EACH,CAAC;AACH;AAEO,SAAS,WAAW,QAA0B;AACnD,SAAO,QAAQ,KAAK,SAAS;AAC7B,MAAI,KAAK,gBAAgB;AAC3B;;;AC1DA,SAAS,YAAAC,iBAAgB;AACzB,SAAS,cAAAC,mBAAkB;AAC3B,SAAS,QAAAC,aAAY;AACrB,SAAS,WAAAC,gBAAe;AAOxB,SAAS,uBAAuC;AAC9C,QAAM,SAAqC;AAAA,IACzC,CAAC,OAAO,SAAS;AAAA,IACjB,CAAC,OAAO,KAAK;AAAA,IACb,CAAC,OAAO,KAAK;AAAA,IACb,CAAC,UAAU,QAAQ;AAAA,IACnB,CAAC,OAAO,KAAK;AAAA,IACb,CAAC,QAAQ,MAAM;AAAA,EACjB;AACA,aAAW,CAAC,MAAM,GAAG,KAAK,QAAQ;AAChC,QAAI;AACF,MAAAC,UAAS,SAAS,GAAG,IAAI,EAAE,OAAO,OAAO,CAAC;AAC1C,aAAO;AAAA,IACT,QAAQ;AAAA,IAAkB;AAAA,EAC5B;AACA,SAAO;AACT;AAIA,IAAM,iBAAmD;AAAA,EACvD,KAAK;AAAA,IACH;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EACF;AAAA,EACA,KAAK;AAAA,IACH;AAAA,IACA;AAAA,IACA;AAAA,EACF;AAAA,EACA,KAAK;AAAA,IACH;AAAA,IACA;AAAA,IACA;AAAA,EACF;AAAA,EACA,QAAQ;AAAA,IACN;AAAA,IACA;AAAA,IACA;AAAA,EACF;AAAA,EACA,KAAK;AAAA,IACH;AAAA,IACA;AAAA,IACA;AAAA,EACF;AAAA,EACA,MAAM;AAAA,IACJ;AAAA,EACF;AAAA,EACA,SAAS,CAAC;AACZ;AAEA,IAAM,sBAAwD;AAAA,EAC5D,KAAK;AAAA,IACH;AAAA,IACA;AAAA,EACF;AAAA,EACA,KAAK,CAAC,0DAA0D;AAAA,EAChE,KAAK,CAAC,0DAA0D;AAAA,EAChE,QAAQ,CAAC,oCAAoC;AAAA,EAC7C,KAAK,CAAC,qBAAqB;AAAA,EAC3B,MAAM,CAAC,0BAA0B;AAAA,EACjC,SAAS,CAAC;AACZ;AAaO,SAAS,YAAyB;AACvC,QAAM,KAAK,qBAAqB;AAChC,QAAM,YAAY,OAAO,UAAU,OAAO,aAAa,QAAQ,SAAS,MAAM;AAC9E,QAAM,OAAO,YAAY,UAAU;AAEnC,SAAO;AAAA,IACL;AAAA,MACE,MAAM;AAAA,MACN,WAAW,cAAc,QAAQ;AAAA,MACjC,SAAS,gBAAgB;AAAA,MACzB,aAAa,OAAO;AAAA,MACpB,iBAAiB,eAAe,EAAE,EAAE,IAAI,OAAK,GAAG,IAAI,GAAG,CAAC,EAAE;AAAA,MAC1D,oBAAoB;AAAA,IACtB;AAAA,IACA;AAAA,MACE,MAAM;AAAA,MACN,WAAW,cAAc,QAAQ;AAAA,MACjC,aAAa,cAAc,KAAK;AAAA,MAChC,iBAAiB,CAAC,iDAAiD;AAAA,MACnE,oBAAoB;AAAA,IACtB;AAAA,IACA;AAAA,MACE,MAAM;AAAA,MACN,WAAWC,YAAWC,MAAKC,SAAQ,GAAG,WAAW,mBAAmB,CAAC;AAAA,MACrE,aAAa;AAAA,MACb,iBAAiB,CAAC;AAAA,MAClB,oBAAoB;AAAA,IACtB;AAAA,IACA;AAAA,MACE,MAAM;AAAA,MACN,WAAW,cAAc,aAAa;AAAA,MACtC,aAAa,OAAO;AAAA,MACpB,iBAAiB,oBAAoB,EAAE,EAAE,IAAI,OAAK,GAAG,IAAI,GAAG,CAAC,EAAE;AAAA,MAC/D,oBAAoB;AAAA,IACtB;AAAA,EACF;AACF;AAEO,SAAS,WAAW,KAAyB;AAClD,MAAI,IAAI,gBAAgB,WAAW,EAAG,QAAO;AAC7C,aAAW,OAAO,IAAI,iBAAiB;AACrC,QAAI;AACF,MAAAH,UAAS,KAAK,EAAE,OAAO,WAAW,SAAS,IAAQ,CAAC;AAAA,IACtD,QAAQ;AACN,aAAO;AAAA,IACT;AAAA,EACF;AACA,SAAO;AACT;AAGO,SAAS,uBAA6B;AAC3C,MAAI,QAAQ,aAAa,QAAS;AAClC,MAAI;AACF,UAAM,OAAOA,UAAS,UAAU,EAAE,UAAU,QAAQ,CAAC,EAAE,KAAK;AAC5D,IAAAA,UAAS,2BAA2B,IAAI,IAAI,EAAE,OAAO,OAAO,CAAC;AAC7D,QAAI,KAAK,SAAS,IAAI,sDAAiD;AAAA,EACzE,QAAQ;AAAA,EAER;AACF;AAEA,SAAS,cAAc,KAAsB;AAC3C,MAAI;AACF,IAAAA,UAAS,SAAS,GAAG,IAAI,EAAE,OAAO,OAAO,CAAC;AAC1C,WAAO;AAAA,EACT,QAAQ;AACN,WAAO;AAAA,EACT;AACF;AAEA,SAAS,kBAA2B;AAClC,MAAI;AACF,IAAAA,UAAS,eAAe,EAAE,OAAO,QAAQ,SAAS,IAAO,CAAC;AAC1D,WAAO;AAAA,EACT,QAAQ;AACN,WAAO;AAAA,EACT;AACF;;;AX1JA,SAAS,cAAAI,aAAY,aAAAC,YAAW,iBAAAC,sBAAqB;AACrD,SAAS,YAAAC,iBAAgB;AACzB,SAAS,uBAAuB;AAChC,SAAS,QAAAC,aAAY;AACrB,SAAS,WAAAC,gBAAe;AACxB,SAAS,gBAAAC,qBAAoB;AAC7B,SAAS,WAAAC,gBAAe;AAExB,SAAS,qBAAqB;AAC9B,IAAMC,WAAU,cAAc,YAAY,GAAG;AAC7C,IAAM,MAAMA,SAAQ,iBAAiB;AAErC,IAAM,UAAU,IAAI,QAAQ;AAE5B,QACG,KAAK,UAAU,EACf,YAAY,yDAA+C,EAC3D,QAAQ,IAAI,OAAO;AAGtB,SAAS,IAAI,UAAkB,YAAsC;AACnE,QAAM,KAAK,gBAAgB,EAAE,OAAO,QAAQ,OAAO,QAAQ,QAAQ,OAAO,CAAC;AAC3E,QAAM,OAAO,aAAa,KAAK,UAAU,MAAM;AAC/C,SAAO,IAAI,QAAQ,CAAC,YAAY;AAC9B,OAAG,SAAS,GAAG,QAAQ,GAAG,IAAI,MAAM,CAAC,WAAW;AAC9C,SAAG,MAAM;AACT,cAAQ,OAAO,KAAK,KAAK,cAAc,EAAE;AAAA,IAC3C,CAAC;AAAA,EACH,CAAC;AACH;AAGA,QACG,QAAQ,OAAO,EACf,YAAY,uCAAuC,EACnD,OAAO,uBAAuB,kBAAkB,EAChD,OAAO,uBAAuB,uBAAuB,EACrD,OAAO,eAAe,2DAA2D,EACjF,OAAO,iBAAiB,iBAAiB,EACzC,OAAO,OAAO,SAAS;AACtB,MAAI,KAAK,QAAS,aAAY,OAAO;AAErC,oBAAkB;AAClB,MAAI,KAAK,aAAa,IAAI,OAAO,EAAE;AACnC,QAAM,qBAAqB;AAC3B,MAAI,CAAC,uBAAuB,GAAG;AAC7B,UAAM,IAAI;AAAA,MACR;AAAA,IAEF;AAAA,EACF;AAGA,QAAM,UAAU,MAAM,0BAA0B;AAChD,MAAI,UAAU,GAAG;AACf,QAAI,KAAK,cAAc,OAAO,8CAA8C;AAAA,EAC9E;AACA,QAAM,SAAS,WAAW,KAAK,MAAM;AACrC,MAAI,KAAK,KAAM,QAAO,QAAQ,OAAO,SAAS,KAAK,IAAI;AAEvD,MAAI,KAAK,SAAS,OAAO,OAAO,MAAM,gBAAgB,OAAO,OAAO,SAAS,KAAK,IAAI,CAAC,aAAa,OAAO,MAAM,KAAK,sBAAsB,OAAO,aAAa,EAAE;AAElK,QAAM,eAAe,mBAAmB,MAAM;AAC9C,QAAM,UAAU,cAAc,MAAM;AAEpC,QAAM,SAAS,IAAI,cAAc,QAAQ,cAAc,OAAO;AAE9D,MAAI;AAGJ,MAAI,KAAK,WAAW,OAAO;AACzB,QAAI,KAAK,oBAAoB;AAC7B,QAAI;AACF,eAAS,MAAM,iBAAiB,OAAO,QAAQ,IAAI;AACnD,YAAM,aAAa,GAAG,OAAO,GAAG;AAChC,UAAI,QAAQ,WAAW,OAAO,GAAG,EAAE;AACnC,UAAI,KAAK,gBAAgB,UAAU,EAAE;AAGrC,UAAI,OAAO,QAAQ,WAAW;AAC5B,YAAI;AACF,gBAAM,aAAa,cAAc,OAAO,QAAQ,SAAS;AAAA,QAC3D,QAAQ;AAAA,QAER;AAAA,MACF;AAGA,YAAM,OAAO,MAAM,aAAa,KAAK,OAAO,OAAO,MAAM;AAGzD,YAAM,SAAS,MAAM,aAAa,cAAc;AAAA,QAC9C,KAAK;AAAA,QACL,eAAe,CAAC,OAAO;AAAA,QACvB,OAAO;AAAA,QACP,QAAQ,KAAK;AAAA,MACf,CAAC;AACD,YAAM,UAAU,MAAM,OAAO;AAC7B,UAAI,SAAS;AACX,YAAI,QAAQ,iCAA4B,UAAU,EAAE;AAEpD,eAAO,QAAQ,YAAY,QAAQ;AAEnC,eAAO,QAAQ,gBAAgB;AAAA,MACjC;AAAA,IACF,SAAS,KAAK;AACZ,UAAI,KAAK,kBAAkB,eAAe,QAAQ,IAAI,UAAU,GAAG,EAAE;AACrE,UAAI,KAAK,iEAAiE;AAAA,IAC5E;AAAA,EACF;AAEA,QAAM,OAAO,MAAM;AAEnB,QAAM,WAAW,MAAM;AACrB,QAAI,KAAK,kBAAkB;AAC3B,WAAO,KAAK;AACZ,QAAI,OAAQ,YAAW,MAAM;AAC7B,YAAQ,KAAK,CAAC;AAAA,EAChB;AACA,UAAQ,GAAG,UAAU,QAAQ;AAC7B,UAAQ,GAAG,WAAW,QAAQ;AAChC,CAAC;AAGH,QACG,QAAQ,cAAc,EACtB,YAAY,iDAAiD,EAC7D,OAAO,uBAAuB,kBAAkB,EAChD,OAAO,iBAAiB,iBAAiB,EACzC,OAAO,aAAa,0CAA0C,EAC9D,OAAO,OAAO,UAAkB,SAAS;AACxC,MAAI,KAAK,QAAS,aAAY,OAAO;AACrC,oBAAkB;AAElB,QAAM,SAAS,WAAW,KAAK,MAAM;AACrC,QAAM,eAAe,mBAAmB,MAAM;AAE9C,QAAM,SAAS,MAAM,YAAY,cAAc,QAAQ;AACvD,MAAI,CAAC,OAAQ,OAAM,IAAI,MAAM,UAAU,QAAQ,YAAY;AAC3D,MAAI,CAAC,OAAO,SAAS;AACnB,UAAM,IAAI,MAAM,GAAG,QAAQ,iEAAiE;AAAA,EAC9F;AAEA,MAAI,KAAK,QAAQ;AACf,QAAI,KAAK,0CAAqC;AAC9C,QAAI,KAAK,eAAe,OAAO,UAAU,WAAM,OAAO,KAAK,EAAE;AAC7D,QAAI,KAAK,eAAe,OAAO,OAAO,EAAE;AACxC,QAAI,KAAK,eAAe,OAAO,cAAc,+BAA+B,EAAE;AAC9E,QAAI,KAAK,wBAAwB,OAAO,UAAU,MAAM;AACxD,QAAI,KAAK,eAAe,OAAO,OAAO,KAAK,EAAE;AAC7C,QAAI,KAAK,eAAe,OAAO,MAAM,KAAK,EAAE;AAC5C,QAAI,KAAK,eAAe,OAAO,MAAM,aAAa,EAAE;AACpD,QAAI,OAAO,aAAa;AACtB,UAAI,KAAK;AAAA;AAAA,MAAyB,OAAO,YAAY,MAAM,IAAI,EAAE,KAAK,QAAQ,CAAC,EAAE;AAAA,IACnF;AACA;AAAA,EACF;AAEA,QAAM,qBAAqB;AAC3B,MAAI,CAAC,uBAAuB,GAAG;AAC7B,UAAM,IAAI;AAAA,MACR;AAAA,IAEF;AAAA,EACF;AACA,QAAM,UAAU,cAAc,MAAM;AAGpC,QAAM,QAAQ,IAAI,gBAAgB;AAClC,QAAM,WAAW,MAAM;AACrB,QAAI,KAAK,iCAAiC;AAC1C,UAAM,MAAM;AAAA,EACd;AACA,UAAQ,GAAG,UAAU,QAAQ;AAC7B,UAAQ,GAAG,WAAW,QAAQ;AAE9B,MAAI;AACF,UAAM,SAAS,MAAM,cAAc,EAAE,QAAQ,QAAQ,cAAc,QAAQ,CAAC;AAC5E,QAAI,CAAC,OAAO,QAAS,OAAM,IAAI,MAAM,OAAO,SAAS,iBAAiB;AAAA,EACxE,UAAE;AACA,YAAQ,IAAI,UAAU,QAAQ;AAC9B,YAAQ,IAAI,WAAW,QAAQ;AAAA,EACjC;AACF,CAAC;AAGH,QACG,QAAQ,UAAU,EAClB,YAAY,0CAA0C,EACtD,OAAO,uBAAuB,kBAAkB,EAChD,OAAO,OAAO,SAAS;AACtB,MAAI;AACF,UAAM,SAAS,WAAW,KAAK,MAAM;AACrC,QAAI,QAAQ,iBAAiB;AAC7B,QAAI,KAAK,kBAAkB,OAAO,OAAO,MAAM,EAAE;AACjD,QAAI,KAAK,uBAAuB,OAAO,OAAO,SAAS,KAAK,IAAI,CAAC,EAAE;AACnE,QAAI,KAAK,mBAAmB,OAAO,OAAO,KAAK,EAAE;AACjD,QAAI,KAAK,kBAAkB,OAAO,MAAM,KAAK,EAAE;AAC/C,QAAI,KAAK,qBAAqB,OAAO,MAAM,aAAa,EAAE;AAC1D,QAAI,KAAK,qBAAqB,OAAO,aAAa,EAAE;AACpD,QAAI,KAAK,mBAAmB,OAAO,QAAQ,IAAI,EAAE;AAAA,EACnD,SAAS,KAAK;AACZ,QAAI,MAAM,eAAe,QAAQ,IAAI,UAAU,OAAO,GAAG,CAAC;AAC1D,YAAQ,KAAK,CAAC;AAAA,EAChB;AACF,CAAC;AAGH,QACG,QAAQ,SAAS,EACjB,YAAY,4CAA4C,EACxD,OAAO,YAAY;AAClB,QAAM,qBAAqB;AAC3B,QAAM,QAAQ,MAAM,0BAA0B;AAC9C,MAAI,UAAU,GAAG;AACf,QAAI,KAAK,8BAA8B;AAAA,EACzC,OAAO;AACL,QAAI,QAAQ,cAAc,KAAK,wBAAwB;AAAA,EACzD;AACF,CAAC;AAGH,SAAS,yBAAkC;AACzC,SAAOR,YAAWI,MAAKC,SAAQ,GAAG,WAAW,mBAAmB,CAAC;AACnE;AAEA,eAAe,oBAAoB,OAA4C;AAC7E,MAAI;AACF,UAAM,UAAU,IAAIE,SAAQ,EAAE,MAAM,MAAM,CAAC;AAC3C,UAAM,EAAE,KAAK,IAAI,MAAM,QAAQ,KAAK,MAAM,iBAAiB;AAC3D,WAAO,KAAK;AAAA,EACd,QAAQ;AACN,WAAO;AAAA,EACT;AACF;AAGA,QACG,QAAQ,MAAM,EACd,YAAY,+BAA+B,EAC3C,OAAO,YAAY;AAClB,UAAQ,IAAI,sBAAsB;AAGlC,UAAQ,IAAI,8BAA8B;AAC1C,QAAM,OAAO,UAAU;AACvB,QAAM,eAAyB,CAAC;AAEhC,aAAW,OAAO,MAAM;AACtB,QAAI,IAAI,aAAa,IAAI,YAAY,OAAO;AAC1C,UAAI,QAAQ,GAAG,IAAI,IAAI,EAAE;AACzB;AAAA,IACF;AAEA,QAAI,IAAI,aAAa,IAAI,YAAY,OAAO;AAC1C,UAAI,KAAK,GAAG,IAAI,IAAI,mCAA8B;AAClD,mBAAa,KAAK,GAAG,IAAI,IAAI,kBAAkB;AAC/C;AAAA,IACF;AAGA,QAAI,IAAI,eAAe,IAAI,gBAAgB,SAAS,GAAG;AACrD,YAAM,SAAS,MAAM,IAAI,KAAK,IAAI,IAAI,8BAA8B,GAAG;AAEvE,UAAI,OAAO,YAAY,MAAM,KAAK;AAChC,gBAAQ,IAAI;AAAA,eAAkB,IAAI,IAAI;AAAA,CAAkC;AACxE,cAAM,KAAK,WAAW,GAAG;AACzB,YAAI,IAAI;AACN,cAAI,QAAQ,GAAG,IAAI,IAAI,YAAY;AACnC,cAAI,IAAI,SAAS,SAAU,sBAAqB;AAChD,cAAI,IAAI,SAAS,eAAe;AAC9B,oBAAQ,IAAI,2EAA2E;AACvF,yBAAa,KAAK,mBAAmB;AAAA,UACvC;AAAA,QACF,OAAO;AACL,cAAI,MAAM,GAAG,IAAI,IAAI,iBAAiB;AACtC,kBAAQ,IAAI,yBAAyB,IAAI,kBAAkB,EAAE;AAC7D,uBAAa,KAAK,IAAI,IAAI;AAAA,QAC5B;AAAA,MACF,OAAO;AACL,gBAAQ,IAAI,yBAAyB,IAAI,kBAAkB,EAAE;AAC7D,qBAAa,KAAK,IAAI,IAAI;AAAA,MAC5B;AAAA,IACF,WAAW,IAAI,SAAS,sBAAsB;AAC5C,UAAI,KAAK,GAAG,IAAI,IAAI,gCAA2B;AAC/C,mBAAa,KAAK,IAAI,IAAI;AAAA,IAC5B,OAAO;AACL,UAAI,KAAK,GAAG,IAAI,IAAI,WAAM,IAAI,kBAAkB,EAAE;AAClD,mBAAa,KAAK,IAAI,IAAI;AAAA,IAC5B;AAAA,EACF;AAEA,MAAI,aAAa,SAAS,GAAG;AAC3B,YAAQ,IAAI;AAAA,oCAAkC,aAAa,KAAK,IAAI,CAAC;AAAA,CAAoB;AAAA,EAC3F,OAAO;AACL,YAAQ,IAAI,EAAE;AAAA,EAChB;AAEA,MAAI,CAACP,YAAW,UAAU,GAAG;AAC3B,IAAAC,WAAU,YAAY,EAAE,WAAW,KAAK,CAAC;AAAA,EAC3C;AAEA,MAAID,YAAW,WAAW,GAAG;AAC3B,UAAM,YAAY,MAAM,IAAI,2CAA2C,GAAG;AAC1E,QAAI,UAAU,YAAY,MAAM,KAAK;AACnC,UAAI,KAAK,0BAA0B;AACnC;AAAA,IACF;AAAA,EACF;AAGA,QAAM,YAAY,MAAM,IAAI,kBAAkB,QAAQ,IAAI,cAAc;AACxE,MAAI,CAAC,WAAW;AACd,QAAI,MAAM,4BAA4B;AACtC,YAAQ,KAAK,CAAC;AAAA,EAChB;AAGA,MAAI,SAAS;AACb,MAAI;AACF,UAAM,SAAS,IAAIM,cAAa,EAAE,QAAQ,UAAU,CAAC;AACrD,UAAM,QAAQ,MAAM,OAAO,MAAM;AACjC,QAAI,MAAM,MAAM,WAAW,GAAG;AAC5B,UAAI,MAAM,yCAAyC;AACnD,cAAQ,KAAK,CAAC;AAAA,IAChB;AACA,QAAI,MAAM,MAAM,WAAW,GAAG;AAC5B,eAAS,MAAM,MAAM,CAAC,EAAE;AACxB,UAAI,QAAQ,gBAAgB,MAAM,MAAM,CAAC,EAAE,IAAI,KAAK,MAAM,GAAG;AAAA,IAC/D,OAAO;AACL,cAAQ,IAAI,sBAAsB;AAClC,iBAAW,KAAK,MAAM,OAAO;AAC3B,gBAAQ,IAAI,OAAO,EAAE,GAAG,WAAM,EAAE,IAAI,EAAE;AAAA,MACxC;AACA,eAAS,MAAM,IAAI,cAAc;AAAA,IACnC;AAAA,EACF,SAAS,KAAK;AACZ,QAAI,MAAM,2BAA2B,eAAe,QAAQ,IAAI,UAAU,GAAG,EAAE;AAC/E,YAAQ,KAAK,CAAC;AAAA,EAChB;AAGA,MAAI,UAAU;AACd,MAAI;AACF,cAAUH,UAAS,iBAAiB,EAAE,UAAU,QAAQ,CAAC,EAAE,KAAK;AAChE,QAAI,QAAQ,mCAAmC;AAAA,EACjD,QAAQ;AACN,cAAU,MAAM,IAAI,8BAA8B;AAAA,EACpD;AACA,MAAI,CAAC,SAAS;AACZ,QAAI,MAAM,0BAA0B;AACpC,YAAQ,KAAK,CAAC;AAAA,EAChB;AAGA,QAAM,SAAS,MAAM,oBAAoB,OAAO;AAChD,MAAI,QAAQ;AACV,QAAI,QAAQ,2BAA2B,MAAM,EAAE;AAAA,EACjD,OAAO;AACL,QAAI,MAAM,oCAAoC;AAC9C,YAAQ,KAAK,CAAC;AAAA,EAChB;AAGA,UAAQ,IAAI,2BAA2B;AACvC,UAAQ,IAAI,iFAA4E;AACxF,UAAQ,IAAI,uEAAuE;AACnF,UAAQ,IAAI,yDAAoD;AAChE,QAAM,cAAc,MAAM,IAAI,gBAAgB,eAAe;AAE7D,MAAI,gBAAgB,iBAAiB;AACnC,QAAI;AACF,MAAAA,UAAS,sCAAsC,EAAE,OAAO,OAAO,CAAC;AAChE,UAAI,QAAQ,2BAA2B;AAAA,IACzC,QAAQ;AACN,UAAI,KAAK,iEAAiE;AAAA,IAC5E;AAAA,EACF;AAGA,QAAM,QAAQ,MAAM,IAAI,gBAAgB,mBAAmB;AAC3D,QAAM,UAAU,MAAM,IAAI,6BAA6B,IAAI;AAM3D,QAAM,SAAS;AAAA;AAAA;AAAA;AAAA;AAAA,aAKN,SAAS;AAAA,YACV,MAAM;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,YAON,OAAO;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,WAMR,WAAW;AAAA;AAAA;AAAA;AAAA,WAIX,KAAK;AAAA,mBACG,SAAS,OAAO,KAAK,EAAE;AAAA;AAAA;AAAA;AAKtC,EAAAD,eAAc,aAAa,QAAQ,EAAE,MAAM,IAAM,CAAC;AAClD,MAAI,QAAQ,mBAAmB,WAAW,EAAE;AAE5C,UAAQ,IAAI;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,CAaf;AACC,CAAC;AAGH,QAAQ,WAAW,EAAE,MAAM,CAAC,QAAQ;AAClC,MAAI,MAAM,eAAe,QAAQ,IAAI,UAAU,OAAO,GAAG,CAAC;AAC1D,UAAQ,KAAK,CAAC;AAChB,CAAC;","names":["docker","existsSync","join","homedir","pr","homedir","join","existsSync","readFileSync","join","homedir","existsSync","readFileSync","mkdtempSync","rmSync","writeFileSync","join","tmpdir","execSync","docker","ticket","execSync","existsSync","join","homedir","execSync","existsSync","join","homedir","existsSync","mkdirSync","writeFileSync","execSync","join","homedir","LinearClient","Octokit","require"]}
1
+ {"version":3,"sources":["../src/index.ts","../src/config.ts","../src/linear.ts","../src/logger.ts","../src/github.ts","../src/webhook.ts","../src/docker.ts","../src/agent.ts","../src/git.ts","../src/worker.ts","../src/tunnel.ts","../src/deps.ts"],"sourcesContent":["import { Command } from 'commander';\nimport { loadConfig, CONFIG_DIR, CONFIG_FILE } from './config.js';\nimport { createLinearClient, fetchTicket } from './linear.js';\nimport { createOctokit } from './github.js';\nimport { WebhookServer } from './webhook.js';\nimport { startQuickTunnel, stopTunnel } from './tunnel.js';\nimport type { TunnelInfo } from './tunnel.js';\nimport { executeTicket } from './worker.js';\nimport { checkDockerAvailable, cleanupOrphanedContainers } from './docker.js';\nimport { log, setLogLevel, enableFileLogging } from './logger.js';\nimport { checkDeps, installDep, addUserToDockerGroup } from './deps.js';\nimport { existsSync, mkdirSync, writeFileSync } from 'node:fs';\nimport { execSync } from 'node:child_process';\nimport { createInterface } from 'node:readline';\nimport { join } from 'node:path';\nimport { homedir } from 'node:os';\nimport { LinearClient } from '@linear/sdk';\nimport { Octokit } from '@octokit/rest';\n\nimport { createRequire } from 'node:module';\nconst require = createRequire(import.meta.url);\nconst pkg = require('../package.json') as { version: string };\n\nconst program = new Command();\n\nprogram\n .name('autocode')\n .description('Linear webhooks → Claude Code in Docker → PRs')\n .version(pkg.version);\n\n// --- Helper: prompt user for input ---\nfunction ask(question: string, defaultVal?: string): Promise<string> {\n const rl = createInterface({ input: process.stdin, output: process.stdout });\n const hint = defaultVal ? ` (${defaultVal})` : '';\n return new Promise((resolve) => {\n rl.question(`${question}${hint}: `, (answer) => {\n rl.close();\n resolve(answer.trim() || defaultVal || '');\n });\n });\n}\n\n// --- serve ---\nprogram\n .command('serve')\n .description('Start webhook server with auto-tunnel')\n .option('-c, --config <path>', 'Config file path')\n .option('-p, --port <number>', 'Override webhook port')\n .option('--no-tunnel', 'Skip auto-tunnel (use if you have your own reverse proxy)')\n .option('-v, --verbose', 'Verbose logging')\n .action(async (opts) => {\n if (opts.verbose) setLogLevel('debug');\n\n enableFileLogging();\n log.info(`autocode v${pkg.version}`);\n await checkDockerAvailable();\n if (!checkClaudeCredentials()) {\n throw new Error(\n 'Claude Code credentials not found (~/.claude/.credentials.json)\\n'\n + 'Run: claude (and complete login) to create credentials'\n );\n }\n\n // Clean up any orphaned containers from previous runs\n const orphans = await cleanupOrphanedContainers();\n if (orphans > 0) {\n log.info(`Cleaned up ${orphans} orphaned container(s) from previous session`);\n }\n const config = loadConfig(opts.config);\n if (opts.port) config.webhook.port = parseInt(opts.port);\n\n log.info(`Team: ${config.linear.teamId} | Statuses: ${config.linear.statuses.join(', ')} | Model: ${config.agent.model} | Max concurrent: ${config.maxConcurrent}`);\n\n const linearClient = createLinearClient(config);\n const octokit = createOctokit(config);\n\n const server = new WebhookServer(config, linearClient, octokit);\n\n let tunnel: TunnelInfo | undefined;\n\n // Start tunnel if enabled\n if (opts.tunnel !== false) {\n log.info('Starting tunnel...');\n try {\n tunnel = await startQuickTunnel(config.webhook.port);\n const webhookUrl = `${tunnel.url}/api/v1/linear/webhook`;\n log.success(`Tunnel: ${tunnel.url}`);\n log.info(`Webhook URL: ${webhookUrl}`);\n\n // Update the Linear webhook if we have a webhookId stored\n if (config.webhook.webhookId) {\n try {\n await linearClient.deleteWebhook(config.webhook.webhookId);\n } catch {\n // Old webhook may already be gone\n }\n }\n\n // Resolve team UUID from key\n const team = await linearClient.team(config.linear.teamId);\n\n // Create/update Linear webhook with new tunnel URL\n const result = await linearClient.createWebhook({\n url: webhookUrl,\n resourceTypes: ['Issue'],\n label: 'autocode',\n teamId: team.id,\n });\n const webhook = await result.webhook;\n if (webhook) {\n log.success(`Linear webhook created → ${webhookUrl}`);\n // Store webhook ID and secret for next time\n config.webhook.webhookId = webhook.id;\n // Note: the signing secret is set when creating via API - we disable verification for auto-created webhooks\n config.webhook.signingSecret = undefined;\n }\n } catch (err) {\n log.warn(`Tunnel failed: ${err instanceof Error ? err.message : err}`);\n log.info('Falling back to local-only mode. Set up your own reverse proxy.');\n }\n }\n\n await server.start();\n\n const shutdown = () => {\n log.info('Shutting down...');\n server.stop();\n if (tunnel) stopTunnel(tunnel);\n process.exit(0);\n };\n process.on('SIGINT', shutdown);\n process.on('SIGTERM', shutdown);\n });\n\n// --- run ---\nprogram\n .command('run <ticket>')\n .description('Run a single ticket (e.g. autocode run RAH-123)')\n .option('-c, --config <path>', 'Config file path')\n .option('-v, --verbose', 'Verbose logging')\n .option('--dry-run', 'Show what would happen without executing')\n .action(async (ticketId: string, opts) => {\n if (opts.verbose) setLogLevel('debug');\n enableFileLogging();\n\n const config = loadConfig(opts.config);\n const linearClient = createLinearClient(config);\n\n const ticket = await fetchTicket(linearClient, ticketId);\n if (!ticket) throw new Error(`Ticket ${ticketId} not found`);\n if (!ticket.repoUrl) {\n throw new Error(`${ticketId} has no repo: label. Add \"repo:owner/name\" label to the ticket.`);\n }\n\n if (opts.dryRun) {\n log.info('Dry run — no changes will be made\\n');\n log.info(` Ticket: ${ticket.identifier} — ${ticket.title}`);\n log.info(` Repo: ${ticket.repoUrl}`);\n log.info(` Base: ${ticket.baseBranch ?? '(from .autocode.yaml or main)'}`);\n log.info(` Branch: autocode/${ticket.identifier}-...`);\n log.info(` Image: ${config.docker.image}`);\n log.info(` Model: ${config.agent.model}`);\n log.info(` Max iter: ${config.agent.maxIterations}`);\n if (ticket.description) {\n log.info(`\\n Description:\\n ${ticket.description.split('\\n').join('\\n ')}`);\n }\n return;\n }\n\n await checkDockerAvailable();\n if (!checkClaudeCredentials()) {\n throw new Error(\n 'Claude Code credentials not found (~/.claude/.credentials.json)\\n'\n + 'Run: claude (and complete login) to create credentials'\n );\n }\n const octokit = createOctokit(config);\n\n // Let the worker's finally block clean up containers on signals\n const abort = new AbortController();\n const onSignal = () => {\n log.info('Received signal, cleaning up...');\n abort.abort();\n };\n process.on('SIGINT', onSignal);\n process.on('SIGTERM', onSignal);\n\n try {\n const result = await executeTicket({ ticket, config, linearClient, octokit });\n if (!result.success) throw new Error(result.error ?? 'Unknown failure');\n } finally {\n process.off('SIGINT', onSignal);\n process.off('SIGTERM', onSignal);\n }\n });\n\n// --- validate ---\nprogram\n .command('validate')\n .description('Validate config without running anything')\n .option('-c, --config <path>', 'Config file path')\n .action(async (opts) => {\n try {\n const config = loadConfig(opts.config);\n log.success('Config is valid');\n log.info(` Linear team: ${config.linear.teamId}`);\n log.info(` Trigger statuses: ${config.linear.statuses.join(', ')}`);\n log.info(` Docker image: ${config.docker.image}`);\n log.info(` Agent model: ${config.agent.model}`);\n log.info(` Max iterations: ${config.agent.maxIterations}`);\n log.info(` Max concurrent: ${config.maxConcurrent}`);\n log.info(` Webhook port: ${config.webhook.port}`);\n } catch (err) {\n log.error(err instanceof Error ? err.message : String(err));\n process.exit(1);\n }\n });\n\n// --- cleanup ---\nprogram\n .command('cleanup')\n .description('Remove orphaned autocode Docker containers')\n .action(async () => {\n await checkDockerAvailable();\n const count = await cleanupOrphanedContainers();\n if (count === 0) {\n log.info('No orphaned containers found');\n } else {\n log.success(`Cleaned up ${count} orphaned container(s)`);\n }\n });\n\n// --- Runtime checks ---\nfunction checkClaudeCredentials(): boolean {\n return existsSync(join(homedir(), '.claude', '.credentials.json'));\n}\n\nasync function validateGitHubToken(token: string): Promise<string | undefined> {\n try {\n const octokit = new Octokit({ auth: token });\n const { data } = await octokit.rest.users.getAuthenticated();\n return data.login;\n } catch {\n return undefined;\n }\n}\n\n// --- init ---\nprogram\n .command('init')\n .description('Set up autocode interactively')\n .action(async () => {\n console.log('\\n autocode setup\\n');\n\n // Preflight: check and install prerequisites\n console.log(' Checking dependencies...\\n');\n const deps = checkDeps();\n const stillMissing: string[] = [];\n\n for (const dep of deps) {\n if (dep.installed && dep.running !== false) {\n log.success(`${dep.name}`);\n continue;\n }\n\n if (dep.installed && dep.running === false) {\n log.warn(`${dep.name} — installed but not running`);\n stillMissing.push(`${dep.name} (needs restart)`);\n continue;\n }\n\n // Not installed — offer to install if possible\n if (dep.installable && dep.installCommands.length > 0) {\n const answer = await ask(` ${dep.name} not found. Install? (Y/n)`, 'Y');\n\n if (answer.toLowerCase() !== 'n') {\n console.log(`\\n Installing ${dep.name} via system package manager...\\n`);\n const ok = installDep(dep);\n if (ok) {\n log.success(`${dep.name} installed`);\n if (dep.name === 'Docker') addUserToDockerGroup();\n if (dep.name === 'Claude Code') {\n console.log('\\n Run \"claude\" in your terminal to log in, then re-run: autocode init\\n');\n stillMissing.push('Claude Code login');\n }\n } else {\n log.error(`${dep.name} install failed`);\n console.log(` Install manually: ${dep.manualInstructions}`);\n stillMissing.push(dep.name);\n }\n } else {\n console.log(` Install manually: ${dep.manualInstructions}`);\n stillMissing.push(dep.name);\n }\n } else if (dep.name === 'Claude credentials') {\n log.warn(`${dep.name} — run \"claude\" to log in`);\n stillMissing.push(dep.name);\n } else {\n log.warn(`${dep.name} — ${dep.manualInstructions}`);\n stillMissing.push(dep.name);\n }\n }\n\n if (stillMissing.length > 0) {\n console.log(`\\n Continuing setup — install ${stillMissing.join(', ')} before running.\\n`);\n } else {\n console.log('');\n }\n\n if (!existsSync(CONFIG_DIR)) {\n mkdirSync(CONFIG_DIR, { recursive: true });\n }\n\n if (existsSync(CONFIG_FILE)) {\n const overwrite = await ask('Config already exists. Overwrite? (y/N)', 'N');\n if (overwrite.toLowerCase() !== 'y') {\n log.info('Keeping existing config.');\n return;\n }\n }\n\n // 1. Linear API key\n const linearKey = await ask('Linear API key', process.env.LINEAR_API_KEY);\n if (!linearKey) {\n log.error('Linear API key is required');\n process.exit(1);\n }\n\n // Validate and get teams\n let teamId = '';\n try {\n const client = new LinearClient({ apiKey: linearKey });\n const teams = await client.teams();\n if (teams.nodes.length === 0) {\n log.error('No teams found in your Linear workspace');\n process.exit(1);\n }\n if (teams.nodes.length === 1) {\n teamId = teams.nodes[0].key;\n log.success(`Linear team: ${teams.nodes[0].name} (${teamId})`);\n } else {\n console.log('\\n Available teams:');\n for (const t of teams.nodes) {\n console.log(` ${t.key} — ${t.name}`);\n }\n teamId = await ask('\\n Team key');\n }\n } catch (err) {\n log.error(`Invalid Linear API key: ${err instanceof Error ? err.message : err}`);\n process.exit(1);\n }\n\n // 2. GitHub token\n let ghToken = '';\n try {\n ghToken = execSync('gh auth token', { encoding: 'utf-8' }).trim();\n log.success(`GitHub token detected from gh CLI`);\n } catch {\n ghToken = await ask('GitHub personal access token');\n }\n if (!ghToken) {\n log.error('GitHub token is required');\n process.exit(1);\n }\n\n // Validate the GitHub token\n const ghUser = await validateGitHubToken(ghToken);\n if (ghUser) {\n log.success(`GitHub authenticated as ${ghUser}`);\n } else {\n log.error('GitHub token is invalid or expired');\n process.exit(1);\n }\n\n // 3. Docker image\n console.log('\\n Docker image options:');\n console.log(' autocode-base — All runtimes: Node, Python, Go, Rust, Ruby (~1.5GB)');\n console.log(' Works with any repo, no per-repo config needed');\n console.log(' node:20 — Node.js only (fast, ~300MB)');\n const dockerImage = await ask('Docker image', 'autocode-base');\n\n if (dockerImage === 'autocode-base') {\n try {\n execSync('docker image inspect autocode-base', { stdio: 'pipe' });\n log.success('autocode-base image found');\n } catch {\n log.info('autocode-base will be built automatically on first run (~3 min)');\n }\n }\n\n // 4. Agent config\n const model = await ask('Claude model', 'claude-sonnet-4-6');\n const maxIter = await ask('Max iterations per ticket', '10');\n\n // 4. Write config\n // Tip: to avoid storing secrets in the file, you can replace values\n // with env:VAR_NAME (e.g. env:LINEAR_API_KEY). autocode resolves\n // these from the environment at runtime.\n const config = `# autocode config — generated by autocode init\n# Tip: use \"env:VAR_NAME\" to read secrets from environment variables\n# e.g. apiKey: env:LINEAR_API_KEY\n\nlinear:\n apiKey: \"${linearKey}\"\n teamId: ${teamId}\n statuses: [Todo]\n assignToMe: false\n inProgressStatus: In Progress\n doneStatus: Done\n\ngithub:\n token: \"${ghToken}\"\n\nwebhook:\n port: 3000\n\ndocker:\n image: ${dockerImage}\n memory: 4g\n\nagent:\n model: ${model}\n maxIterations: ${parseInt(maxIter) || 10}\n\nmaxConcurrent: 1\n`;\n\n writeFileSync(CONFIG_FILE, config, { mode: 0o600 });\n log.success(`Config saved to ${CONFIG_FILE}`);\n\n console.log(`\n Setup complete! Next steps:\n\n 1. Add repo: labels to your Linear team\n (e.g. \"repo:your-org/your-repo\")\n\n 2. Tag tickets with a repo: label\n\n 3. Start autocode:\n $ autocode serve\n\n autocode serve will auto-create a tunnel and\n register the webhook with Linear. Just run it.\n`);\n });\n\n// Catch errors at CLI boundary\nprogram.parseAsync().catch((err) => {\n log.error(err instanceof Error ? err.message : String(err));\n process.exit(1);\n});\n","import { z } from 'zod';\nimport { readFileSync, existsSync } from 'node:fs';\nimport { join } from 'node:path';\nimport { homedir } from 'node:os';\nimport yaml from 'js-yaml';\n\n// --- Schema ---\n\n// Host config (~/.autocode/config.yaml) — just tokens + global defaults\nconst AgentConfigSchema = z.object({\n model: z.string().default('claude-sonnet-4-6'),\n maxIterations: z.number().min(1).max(50).default(10),\n timeout: z.number().optional(),\n});\n\nconst DockerConfigSchema = z.object({\n image: z.string().default('node:20'),\n memory: z.string().default('4g'),\n cpus: z.number().optional(),\n setup: z.array(z.string()).optional(), // Shell commands to run before Claude Code\n volumes: z.array(z.string()).optional(), // Extra bind mounts, e.g. [\"~/.ssh:/home/autocode/.ssh:ro\"]\n network: z.enum(['bridge', 'host', 'none']).default('bridge'), // Container network mode\n});\n\nconst LinearConfigSchema = z.object({\n apiKey: z.string(),\n teamId: z.string(),\n statuses: z.array(z.string()).default(['Todo']),\n assignToMe: z.boolean().default(true),\n doneStatus: z.string().default('Done'),\n inProgressStatus: z.string().default('In Progress'),\n});\n\nconst GitHubConfigSchema = z.object({\n token: z.string(),\n});\n\nconst WebhookConfigSchema = z.object({\n port: z.number().default(3000),\n url: z.string().optional(),\n signingSecret: z.string().optional(),\n webhookId: z.string().optional(),\n});\n\nconst ConfigSchema = z.object({\n linear: LinearConfigSchema,\n github: GitHubConfigSchema,\n docker: DockerConfigSchema.default({}),\n agent: AgentConfigSchema.default({}),\n webhook: WebhookConfigSchema.default({}),\n maxConcurrent: z.number().default(1),\n});\n\nexport type Config = z.infer<typeof ConfigSchema>;\nexport type AgentConfig = z.infer<typeof AgentConfigSchema>;\nexport type DockerConfig = z.infer<typeof DockerConfigSchema>;\n\n// Per-repo config (.autocode.yaml in repo root) — loaded after clone\nconst RepoLocalConfigSchema = z.object({\n prompt: z.string().optional(),\n base: z.string().default('main'),\n agent: AgentConfigSchema.partial().optional(),\n docker: DockerConfigSchema.partial().optional(),\n});\n\nexport type RepoLocalConfig = z.infer<typeof RepoLocalConfigSchema>;\n\n// --- Loader ---\n\nfunction resolveEnvVars(obj: unknown): unknown {\n if (typeof obj === 'string') {\n if (obj.startsWith('env:')) {\n const envName = obj.slice(4);\n const val = process.env[envName];\n if (!val) throw new Error(`Environment variable ${envName} is not set`);\n return val;\n }\n return obj;\n }\n if (Array.isArray(obj)) return obj.map(resolveEnvVars);\n if (obj && typeof obj === 'object') {\n return Object.fromEntries(\n Object.entries(obj as Record<string, unknown>).map(([k, v]) => [k, resolveEnvVars(v)])\n );\n }\n return obj;\n}\n\nconst CONFIG_DIR = join(homedir(), '.autocode');\nconst CONFIG_FILE = join(CONFIG_DIR, 'config.yaml');\n\nexport function loadConfig(path?: string): Config {\n const configPath = path ?? CONFIG_FILE;\n if (!existsSync(configPath)) {\n throw new Error(`Config not found: ${configPath}\\nRun: autocode init`);\n }\n const content = readFileSync(configPath, 'utf-8');\n const raw = yaml.load(content);\n if (!raw || typeof raw !== 'object') {\n throw new Error(`Config file is empty or invalid: ${configPath}`);\n }\n const resolved = resolveEnvVars(raw);\n const result = ConfigSchema.safeParse(resolved);\n if (!result.success) {\n const issues = result.error.issues.map(\n (i) => ` - ${i.path.join('.')}: ${i.message}`\n ).join('\\n');\n throw new Error(`Invalid config (${configPath}):\\n${issues}`);\n }\n return result.data;\n}\n\nexport function loadRepoLocalConfig(workspacePath: string): RepoLocalConfig | undefined {\n // Support both .yaml and .yml extensions\n const yamlPath = join(workspacePath, '.autocode.yaml');\n const ymlPath = join(workspacePath, '.autocode.yml');\n const configPath = existsSync(yamlPath) ? yamlPath : existsSync(ymlPath) ? ymlPath : undefined;\n if (!configPath) return undefined;\n const raw = yaml.load(readFileSync(configPath, 'utf-8'));\n if (!raw || typeof raw !== 'object') return undefined;\n return RepoLocalConfigSchema.parse(raw);\n}\n\nexport function mergeConfigs(host: Config, local?: RepoLocalConfig): {\n agent: AgentConfig;\n docker: DockerConfig;\n prompt?: string;\n} {\n const agent = AgentConfigSchema.parse({\n ...host.agent,\n ...local?.agent,\n });\n\n const docker = DockerConfigSchema.parse({\n ...host.docker,\n ...local?.docker,\n });\n\n return { agent, docker, prompt: local?.prompt };\n}\n\n// Parse repo from Linear label like \"repo:owner/name\" or \"repo:https://github.com/owner/name\"\nexport function parseRepoFromLabels(labels: string[]): string | undefined {\n for (const label of labels) {\n // \"repo:owner/name\" format\n const match = label.match(/^repo:(.+)/i);\n if (match) {\n const value = match[1].trim();\n // Already a full URL\n if (value.startsWith('https://')) return value;\n // owner/name → full URL\n if (value.includes('/')) return `https://github.com/${value}`;\n }\n }\n return undefined;\n}\n\n// Parse base branch override from labels like \"base:feature-branch\" or \"base:autocode/T-123-fix\"\n// This enables stacked diffs: ticket B can branch from ticket A's PR branch\nexport function parseBaseFromLabels(labels: string[]): string | undefined {\n for (const label of labels) {\n const match = label.match(/^base:(.+)/i);\n if (match) {\n return match[1].trim();\n }\n }\n return undefined;\n}\n\nexport { CONFIG_DIR, CONFIG_FILE };\n","import { LinearClient } from '@linear/sdk';\nimport type { Config } from './config.js';\nimport { parseRepoFromLabels, parseBaseFromLabels } from './config.js';\nimport { log } from './logger.js';\n\nexport interface Ticket {\n id: string; // Linear issue UUID\n identifier: string; // e.g. \"RAH-123\"\n title: string;\n description: string;\n labels: string[];\n repoUrl?: string; // resolved from \"repo:owner/name\" label\n baseBranch?: string; // resolved from \"base:branch-name\" label (for stacked diffs)\n url: string;\n}\n\nexport function createLinearClient(config: Config): LinearClient {\n return new LinearClient({ apiKey: config.linear.apiKey });\n}\n\nexport async function pollTickets(client: LinearClient, config: Config): Promise<Ticket[]> {\n const team = await client.team(config.linear.teamId);\n const issues = await team.issues({\n filter: {\n state: { name: { in: config.linear.statuses } },\n assignee: config.linear.assignToMe ? { isMe: { eq: true } } : undefined,\n },\n first: 50,\n });\n\n const tickets: Ticket[] = [];\n for (const issue of issues.nodes) {\n const labels = await issue.labels();\n const labelNames = labels.nodes.map((l) => l.name);\n const repoUrl = parseRepoFromLabels(labelNames);\n const baseBranch = parseBaseFromLabels(labelNames);\n\n tickets.push({\n id: issue.id,\n identifier: issue.identifier,\n title: issue.title,\n description: issue.description ?? '',\n labels: labelNames,\n repoUrl,\n baseBranch,\n url: issue.url,\n });\n }\n\n return tickets;\n}\n\nexport async function fetchTicket(client: LinearClient, identifier: string): Promise<Ticket | undefined> {\n // Parse team key and number from identifier (e.g. \"RAH-249\", \"rah-249\")\n const match = identifier.match(/^([A-Za-z]+)-(\\d+)$/);\n if (!match) return undefined;\n const [, teamKey, numStr] = match;\n const normalizedKey = teamKey.toUpperCase();\n\n // Fetch via team issues filtered by number\n const team = await client.team(normalizedKey);\n const result = await team.issues({\n filter: { number: { eq: parseInt(numStr) } },\n first: 1,\n });\n const issue = result.nodes[0];\n if (!issue) return undefined;\n\n const labels = await issue.labels();\n const labelNames = labels.nodes.map((l) => l.name);\n const repoUrl = parseRepoFromLabels(labelNames);\n const baseBranch = parseBaseFromLabels(labelNames);\n\n return {\n id: issue.id,\n identifier: issue.identifier,\n title: issue.title,\n description: issue.description ?? '',\n labels: labelNames,\n repoUrl,\n baseBranch,\n url: issue.url,\n };\n}\n\nexport async function claimTicket(\n client: LinearClient,\n config: Config,\n ticketId: string\n): Promise<void> {\n log.info(`Claiming ticket, moving to \"${config.linear.inProgressStatus}\"`);\n\n const team = await client.team(config.linear.teamId);\n const states = await team.states();\n const target = config.linear.inProgressStatus.toLowerCase();\n const inProgress = states.nodes.find((s) => s.name.toLowerCase() === target);\n if (!inProgress) {\n log.warn(`State \"${config.linear.inProgressStatus}\" not found, skipping status update`);\n return;\n }\n\n await client.updateIssue(ticketId, { stateId: inProgress.id });\n}\n\nexport async function completeTicket(\n client: LinearClient,\n config: Config,\n ticketId: string,\n comment: string\n): Promise<void> {\n await client.createComment({ issueId: ticketId, body: comment });\n\n const team = await client.team(config.linear.teamId);\n const states = await team.states();\n const doneTarget = config.linear.doneStatus.toLowerCase();\n const done = states.nodes.find((s) => s.name.toLowerCase() === doneTarget);\n if (done) {\n await client.updateIssue(ticketId, { stateId: done.id });\n }\n}\n\nexport async function addBranchLabel(\n client: LinearClient,\n ticketId: string,\n branchName: string,\n): Promise<void> {\n try {\n // Create/find a label with the branch name so child tickets can stack on it\n const issue = await client.issue(ticketId);\n const team = await issue.team;\n if (!team) return;\n\n // Check if label already exists on this team\n const teamLabels = await team.labels();\n const labelName = `base:${branchName}`;\n let labelId = teamLabels.nodes.find(l => l.name === labelName)?.id;\n\n if (!labelId) {\n // Create the label on the team\n const result = await client.createIssueLabel({\n name: labelName,\n teamId: team.id,\n });\n const label = await result.issueLabel;\n labelId = label?.id;\n }\n\n if (labelId) {\n // Add label to the issue\n const currentLabels = await issue.labels();\n const labelIds = currentLabels.nodes.map(l => l.id);\n if (!labelIds.includes(labelId)) {\n await client.updateIssue(ticketId, {\n labelIds: [...labelIds, labelId],\n });\n log.info(`Added \"base:${branchName}\" label to ticket for stacked diffs`);\n }\n }\n } catch (err) {\n // Non-critical — log and continue\n log.debug(`Could not add branch label: ${err instanceof Error ? err.message : err}`);\n }\n}\n\nexport async function failTicket(\n client: LinearClient,\n ticketId: string,\n reason: string\n): Promise<void> {\n await client.createComment({\n issueId: ticketId,\n body: `**autocode failed:**\\n\\n${reason}`,\n });\n}\n","import chalk from 'chalk';\nimport { appendFileSync, mkdirSync, existsSync } from 'node:fs';\nimport { join } from 'node:path';\nimport { homedir } from 'node:os';\n\nexport type LogLevel = 'debug' | 'info' | 'warn' | 'error';\n\nlet currentLevel: LogLevel = 'info';\nlet logFilePath: string | undefined;\n\nconst levels: Record<LogLevel, number> = {\n debug: 0,\n info: 1,\n warn: 2,\n error: 3,\n};\n\nexport function setLogLevel(level: LogLevel): void {\n currentLevel = level;\n}\n\nexport function enableFileLogging(): void {\n const logDir = join(homedir(), '.autocode', 'logs');\n if (!existsSync(logDir)) {\n mkdirSync(logDir, { recursive: true });\n }\n const date = new Date().toISOString().slice(0, 10);\n logFilePath = join(logDir, `autocode-${date}.log`);\n}\n\nfunction shouldLog(level: LogLevel): boolean {\n return levels[level] >= levels[currentLevel];\n}\n\nfunction timestamp(): string {\n return new Date().toISOString().slice(11, 19);\n}\n\nfunction fullTimestamp(): string {\n return new Date().toISOString();\n}\n\nfunction writeToFile(level: string, msg: string): void {\n if (!logFilePath) return;\n try {\n appendFileSync(logFilePath, `${fullTimestamp()} [${level.padEnd(5)}] ${msg}\\n`);\n } catch {\n // Don't crash on log file write failure\n }\n}\n\nexport const log = {\n debug(msg: string, ...args: unknown[]) {\n writeToFile('DEBUG', msg);\n if (shouldLog('debug')) console.log(chalk.gray(`[${timestamp()}] ${msg}`), ...args);\n },\n info(msg: string, ...args: unknown[]) {\n writeToFile('INFO', msg);\n if (shouldLog('info')) console.log(chalk.blue(`[${timestamp()}]`), msg, ...args);\n },\n warn(msg: string, ...args: unknown[]) {\n writeToFile('WARN', msg);\n if (shouldLog('warn')) console.log(chalk.yellow(`[${timestamp()}] WARN`), msg, ...args);\n },\n error(msg: string, ...args: unknown[]) {\n writeToFile('ERROR', msg);\n if (shouldLog('error')) console.log(chalk.red(`[${timestamp()}] ERROR`), msg, ...args);\n },\n success(msg: string, ...args: unknown[]) {\n writeToFile('INFO', `✓ ${msg}`);\n if (shouldLog('info')) console.log(chalk.green(`[${timestamp()}] ✓`), msg, ...args);\n },\n ticket(id: string, msg: string, ...args: unknown[]) {\n writeToFile('INFO', `[${id}] ${msg}`);\n if (shouldLog('info')) console.log(chalk.cyan(`[${timestamp()}] [${id}]`), msg, ...args);\n },\n};\n","import { Octokit } from '@octokit/rest';\nimport type { Config } from './config.js';\nimport { log } from './logger.js';\n\nexport function createOctokit(config: Config): Octokit {\n return new Octokit({ auth: config.github.token });\n}\n\nfunction parseRepoUrl(url: string): { owner: string; repo: string } {\n // https://github.com/owner/repo or https://github.com/owner/repo.git\n const match = url.match(/github\\.com[/:]([^/]+)\\/([^/.]+)/);\n if (!match) throw new Error(`Cannot parse GitHub URL: ${url}`);\n return { owner: match[1], repo: match[2] };\n}\n\nexport async function openPR(octokit: Octokit, opts: {\n repoUrl: string;\n branch: string;\n baseBranch: string;\n title: string;\n body: string;\n}): Promise<{ url: string; number: number }> {\n const { owner, repo } = parseRepoUrl(opts.repoUrl);\n\n // Check for existing PR on this branch\n const existing = await octokit.rest.pulls.list({\n owner,\n repo,\n head: `${owner}:${opts.branch}`,\n state: 'open',\n });\n\n if (existing.data.length > 0) {\n const pr = existing.data[0];\n log.info(`PR already exists: ${pr.html_url}`);\n // Update body\n await octokit.rest.pulls.update({\n owner,\n repo,\n pull_number: pr.number,\n body: opts.body,\n });\n return { url: pr.html_url, number: pr.number };\n }\n\n const pr = await octokit.rest.pulls.create({\n owner,\n repo,\n title: opts.title,\n body: opts.body,\n head: opts.branch,\n base: opts.baseBranch,\n });\n\n log.success(`PR opened: ${pr.data.html_url}`);\n return { url: pr.data.html_url, number: pr.data.number };\n}\n","import { createServer } from 'node:http';\nimport { createHmac, timingSafeEqual } from 'node:crypto';\nimport type { Config } from './config.js';\nimport type { Ticket } from './linear.js';\nimport { parseRepoFromLabels, parseBaseFromLabels } from './config.js';\nimport { executeTicket } from './worker.js';\nimport type { LinearClient } from '@linear/sdk';\nimport type { Octokit } from '@octokit/rest';\nimport { log } from './logger.js';\n\ninterface WebhookPayload {\n action: string;\n type: string;\n data: {\n id: string;\n identifier: string;\n title: string;\n description: string | null;\n labels: Array<{ id: string; name: string }>;\n state: { id: string; name: string; type: string };\n url: string;\n team: { id: string; key: string; name: string };\n };\n updatedFrom?: Record<string, unknown>;\n}\n\nfunction verifySignature(body: string, signature: string, secret: string): boolean {\n const expected = createHmac('sha256', secret).update(body).digest('hex');\n try {\n return timingSafeEqual(Buffer.from(expected), Buffer.from(signature));\n } catch {\n return false;\n }\n}\n\nexport class WebhookServer {\n private active = new Set<string>();\n private queue: Ticket[] = [];\n private processed = new Set<string>(); // Track processed ticket IDs to prevent duplicate dispatch\n private server: ReturnType<typeof createServer> | undefined;\n\n constructor(\n private config: Config,\n private linearClient: LinearClient,\n private octokit: Octokit,\n ) {}\n\n start(): Promise<void> {\n const port = this.config.webhook?.port ?? 3000;\n const MAX_BODY_BYTES = 1024 * 1024; // 1 MB — Linear payloads are typically < 10 KB\n\n this.server = createServer((req, res) => {\n // Health check endpoint\n if (req.method === 'GET' && (req.url === '/health' || req.url === '/healthz')) {\n res.writeHead(200, { 'Content-Type': 'application/json' });\n res.end(JSON.stringify({ status: 'ok', active: this.active.size, queued: this.queue.length, capacity: this.config.maxConcurrent }));\n return;\n }\n\n // Accept both /webhook and /api/v1/linear/webhook (for CF worker compatibility)\n if (req.method !== 'POST' || (req.url !== '/webhook' && req.url !== '/api/v1/linear/webhook')) {\n res.writeHead(404);\n res.end();\n return;\n }\n\n let body = '';\n let bodyBytes = 0;\n req.on('data', (chunk: Buffer) => {\n bodyBytes += chunk.length;\n if (bodyBytes > MAX_BODY_BYTES) {\n res.writeHead(413);\n res.end('Payload too large');\n req.destroy();\n return;\n }\n body += chunk;\n });\n req.on('end', () => {\n // Verify signature if signing secret configured\n if (this.config.webhook?.signingSecret) {\n const sig = req.headers['linear-signature'] as string | undefined;\n if (!sig || !verifySignature(body, sig, this.config.webhook.signingSecret)) {\n log.warn('Invalid webhook signature, rejecting');\n res.writeHead(401);\n res.end('Invalid signature');\n return;\n }\n }\n\n // Respond immediately so Linear doesn't retry\n res.writeHead(200);\n res.end('ok');\n\n // Process async\n void this.handleWebhook(body);\n });\n });\n\n return new Promise((resolve) => {\n this.server!.listen(port, () => {\n log.info(`Webhook server listening on port ${port}`);\n resolve();\n });\n });\n }\n\n stop(): void {\n this.server?.close();\n log.info('Webhook server stopped');\n }\n\n private async handleWebhook(body: string): Promise<void> {\n let payload: WebhookPayload;\n try {\n payload = JSON.parse(body);\n } catch {\n log.warn('Invalid webhook JSON');\n return;\n }\n\n // Only handle Issue events\n if (payload.type !== 'Issue') return;\n\n const { action, data } = payload;\n const triggerStatuses = this.config.linear.statuses.map((s) => s.toLowerCase());\n const currentStatus = data.state.name.toLowerCase();\n\n // Trigger on: issue created/updated into a watched status\n if (action === 'create' || action === 'update') {\n // Check if the issue is now in a trigger status\n if (!triggerStatuses.includes(currentStatus)) {\n log.debug(`${data.identifier}: status \"${data.state.name}\" not in trigger list, ignoring`);\n return;\n }\n\n // For updates, only trigger if status actually changed\n if (action === 'update' && !payload.updatedFrom?.stateId) {\n log.debug(`${data.identifier}: update but status didn't change, ignoring`);\n return;\n }\n } else {\n return; // Ignore 'remove' and other actions\n }\n\n // Already processing or recently processed this ticket?\n if (this.active.has(data.id)) {\n log.debug(`${data.identifier}: already active, ignoring`);\n return;\n }\n if (this.processed.has(data.id)) {\n log.debug(`${data.identifier}: already processed in this session, ignoring`);\n return;\n }\n\n // Check concurrency — queue if at capacity instead of dropping\n if (this.active.size >= this.config.maxConcurrent) {\n log.info(`${data.identifier}: at capacity (${this.active.size}/${this.config.maxConcurrent}), queued`);\n const queueLabels = data.labels.map((l) => l.name);\n const ticket: Ticket = {\n id: data.id,\n identifier: data.identifier,\n title: data.title,\n description: data.description ?? '',\n labels: queueLabels,\n repoUrl: parseRepoFromLabels(queueLabels)!,\n baseBranch: parseBaseFromLabels(queueLabels),\n url: data.url,\n };\n this.queue.push(ticket);\n return;\n }\n\n // Resolve repo from labels\n const labelNames = data.labels.map((l) => l.name);\n const repoUrl = parseRepoFromLabels(labelNames);\n if (!repoUrl) {\n log.warn(`${data.identifier}: no repo: label, ignoring`);\n return;\n }\n\n const ticket: Ticket = {\n id: data.id,\n identifier: data.identifier,\n title: data.title,\n description: data.description ?? '',\n labels: labelNames,\n repoUrl,\n baseBranch: parseBaseFromLabels(labelNames),\n url: data.url,\n };\n\n this.dispatch(ticket);\n }\n\n private dispatch(ticket: Ticket): void {\n this.active.add(ticket.id);\n log.ticket(ticket.identifier, `Dispatching → ${ticket.repoUrl}`);\n\n void executeTicket({\n ticket,\n config: this.config,\n linearClient: this.linearClient,\n octokit: this.octokit,\n }).finally(() => {\n this.active.delete(ticket.id);\n this.processed.add(ticket.id);\n this.drainQueue();\n });\n }\n\n private drainQueue(): void {\n while (this.queue.length > 0 && this.active.size < this.config.maxConcurrent) {\n const next = this.queue.shift()!;\n // Skip if this ticket is already active (duplicate webhook)\n if (this.active.has(next.id)) continue;\n log.ticket(next.identifier, `Dequeued (${this.queue.length} remaining)`);\n this.dispatch(next);\n }\n }\n}\n","import Docker from 'dockerode';\nimport { PassThrough } from 'node:stream';\nimport { homedir, tmpdir } from 'node:os';\nimport { join } from 'node:path';\nimport { existsSync, readFileSync, writeFileSync, mkdtempSync, rmSync } from 'node:fs';\nimport { execSync } from 'node:child_process';\nimport type { DockerConfig } from './config.js';\nimport { log } from './logger.js';\n\nconst docker = new Docker();\n\nexport async function checkDockerAvailable(): Promise<void> {\n try {\n await docker.ping();\n } catch (err) {\n throw new Error(\n 'Cannot connect to Docker daemon. Is Docker running?\\n'\n + 'Install: https://docs.docker.com/get-docker/'\n );\n }\n}\n\n// Embedded Dockerfile for autocode-base — auto-built on first use\n// Includes Node.js 20, Python 3, Go, Ruby + Claude Code (~1.2GB)\n// Rust is omitted to keep image size manageable — use docker.setup for Rust repos\nconst AUTOCODE_BASE_DOCKERFILE = `FROM node:20-bookworm\nENV DEBIAN_FRONTEND=noninteractive\nRUN apt-get update && apt-get install -y --no-install-recommends \\\\\n build-essential git curl wget ca-certificates openssh-client jq unzip \\\\\n python3 python3-pip python3-venv python3-dev \\\\\n ruby ruby-dev \\\\\n && rm -rf /var/lib/apt/lists/*\nARG GO_VERSION=1.22.2\nRUN curl -fsSL \"https://go.dev/dl/go\\${GO_VERSION}.linux-$(dpkg --print-architecture).tar.gz\" \\\\\n | tar -xz -C /usr/local\nENV PATH=\"/usr/local/go/bin:\\${PATH}\"\nRUN npm install -g @anthropic-ai/claude-code@latest\nWORKDIR /workspace\n`;\n\nasync function ensureImage(image: string): Promise<void> {\n try {\n await docker.getImage(image).inspect();\n log.debug(`Image ${image} found locally`);\n return;\n } catch {\n // Image not found locally\n }\n\n // Auto-build autocode-base from embedded Dockerfile\n if (image === 'autocode-base') {\n log.info('Building autocode-base image (first time only, takes a few minutes)...');\n const buildDir = mkdtempSync(join(tmpdir(), 'autocode-build-'));\n try {\n writeFileSync(join(buildDir, 'Dockerfile'), AUTOCODE_BASE_DOCKERFILE);\n execSync(`docker build -t autocode-base ${buildDir}`, {\n stdio: 'inherit',\n timeout: 600_000,\n });\n log.success('autocode-base image built');\n return;\n } catch (err) {\n throw new Error(\n 'Failed to build autocode-base image.\\n'\n + 'You can build manually: docker build -t autocode-base .\\n'\n + `Or use a different image in your config (e.g. node:20).\\n`\n + `Error: ${err instanceof Error ? err.message : err}`\n );\n } finally {\n rmSync(buildDir, { recursive: true, force: true });\n }\n }\n\n // For other images, try to pull\n log.info(`Pulling image ${image} (this may take a moment)...`);\n await new Promise<void>((resolve, reject) => {\n docker.pull(image, (err: Error | null, stream: NodeJS.ReadableStream) => {\n if (err) {\n if (err.message?.includes('not found') || err.message?.includes('404')) {\n return reject(new Error(`Docker image \"${image}\" not found. Check the image name in your config.`));\n }\n return reject(err);\n }\n docker.modem.followProgress(stream, (err2: Error | null) => {\n if (err2) reject(err2);\n else {\n log.success(`Image ${image} pulled`);\n resolve();\n }\n });\n });\n });\n}\n\nexport interface Container {\n id: string;\n instance: Docker.Container;\n}\n\nexport async function createContainer(opts: {\n dockerConfig: DockerConfig;\n workspacePath: string;\n name: string;\n}): Promise<Container> {\n const { dockerConfig, name } = opts;\n\n // Ensure image exists — auto-build autocode-base if needed\n await ensureImage(dockerConfig.image);\n\n // Resolve volume mounts: expand ~ to host home directory\n const binds = [`${opts.workspacePath}:/workspace`];\n if (dockerConfig.volumes?.length) {\n for (const vol of dockerConfig.volumes) {\n binds.push(vol.replace(/^~(?=\\/|:)/, homedir()));\n }\n }\n\n const container = await docker.createContainer({\n Image: dockerConfig.image,\n name: `autocode-${name}`,\n Cmd: ['sleep', 'infinity'],\n WorkingDir: '/workspace',\n User: 'root',\n HostConfig: {\n Binds: binds,\n Memory: parseMemory(dockerConfig.memory),\n NanoCpus: dockerConfig.cpus ? dockerConfig.cpus * 1e9 : undefined,\n NetworkMode: dockerConfig.network ?? 'bridge',\n },\n Env: ['HOME=/root'],\n });\n\n await container.start();\n log.info(`Container ${name} started (${container.id.slice(0, 12)})`);\n\n const wrapped: Container = { id: container.id, instance: container };\n\n // Validate image has a shell (required for all operations)\n const shellCheck = await exec(wrapped, ['sh', '-c', 'echo ok']);\n if (shellCheck.exitCode !== 0 || !shellCheck.stdout.includes('ok')) {\n await destroyContainer(wrapped);\n throw new Error(\n `Docker image \"${dockerConfig.image}\" has no working shell (sh).\\n`\n + 'autocode requires a shell to set up the container. Use a standard base image\\n'\n + '(e.g. node:20, python:3.12, ubuntu:24.04) or ensure /bin/sh is available.'\n );\n }\n\n // Verify curl is available (needed for standalone Claude Code install)\n const curlCheck = await exec(wrapped, ['which', 'curl']);\n if (curlCheck.exitCode !== 0) {\n log.debug('curl not found, installing...');\n await exec(wrapped, [\n 'sh', '-c',\n '(apt-get update -qq && apt-get install -y -qq curl 2>/dev/null) || '\n + '(apk add --no-cache curl 2>/dev/null) || '\n + '(yum install -y curl 2>/dev/null) || true',\n ]);\n }\n\n // Verify git is available (custom images may not have it)\n const gitCheck = await exec(wrapped, ['git', '--version']);\n if (gitCheck.exitCode !== 0) {\n log.info('Git not found in image, installing...');\n // Try apt (Debian/Ubuntu) then apk (Alpine) then yum (RHEL/CentOS)\n const installGit = await exec(wrapped, [\n 'sh', '-c',\n '(apt-get update -qq && apt-get install -y -qq git 2>/dev/null) || '\n + '(apk add --no-cache git 2>/dev/null) || '\n + '(yum install -y git 2>/dev/null) || '\n + '(echo \"Cannot install git\" && exit 1)',\n ]);\n if (installGit.exitCode !== 0) {\n throw new Error(`Docker image \"${dockerConfig.image}\" has no git and autocode could not install it. Use an image with git pre-installed.`);\n }\n }\n\n // Install Claude Code if not already present (prebuilt images have it)\n const claudeCheck = await exec(wrapped, ['which', 'claude']);\n if (claudeCheck.exitCode !== 0) {\n log.info('Installing Claude Code in container...');\n\n // Try npm first (fastest if Node.js is available)\n const npmCheck = await exec(wrapped, ['which', 'npm']);\n let installed = false;\n\n if (npmCheck.exitCode === 0) {\n const npmResult = await exec(wrapped, [\n 'npm', 'install', '-g', '@anthropic-ai/claude-code@latest',\n ]);\n installed = npmResult.exitCode === 0;\n }\n\n // Fall back to standalone binary (works without Node.js)\n if (!installed) {\n log.info('npm not available, installing Claude Code standalone binary...');\n const standaloneResult = await exec(wrapped, [\n 'sh', '-c',\n 'curl -fsSL https://claude.ai/install.sh | sh',\n ], { timeout: 120_000 });\n if (standaloneResult.exitCode !== 0) {\n throw new Error(\n 'Failed to install Claude Code. Tried npm and standalone installer.\\n'\n + `Error: ${standaloneResult.stderr}\\n`\n + 'Use an image with Claude Code pre-installed, or ensure curl is available.'\n );\n }\n }\n\n log.info('Claude Code installed');\n } else {\n log.debug('Claude Code already installed in image');\n }\n\n // Create non-root user (--dangerously-skip-permissions can't run as root)\n // UID 1001 to avoid conflict with node:20's built-in 'node' user at UID 1000\n await exec(wrapped, [\n 'sh', '-c',\n '( getent passwd autocode >/dev/null 2>&1 ) || '\n + '( adduser --disabled-password --gecos \"\" --uid 1001 --home /home/autocode autocode 2>/dev/null ) || '\n + '( adduser -D -u 1001 -h /home/autocode autocode 2>/dev/null ) || ' // Alpine adduser\n + '( useradd -m -u 1001 -d /home/autocode autocode 2>/dev/null ) || ' // useradd fallback\n + '( echo \"autocode:x:1001:1001::/home/autocode:/bin/sh\" >> /etc/passwd && mkdir -p /home/autocode ); '\n + 'mkdir -p /home/autocode && chown -R autocode /home/autocode /workspace',\n ]);\n\n // Auto-detect and install missing language runtimes based on repo files\n await autoInstallRuntimes(wrapped);\n\n // Run user-defined setup commands from .autocode.yaml docker.setup\n if (dockerConfig.setup?.length) {\n log.info(`Running ${dockerConfig.setup.length} setup command(s)...`);\n for (const cmd of dockerConfig.setup) {\n const result = await exec(wrapped, ['sh', '-c', cmd]);\n if (result.exitCode !== 0) {\n throw new Error(`Setup command failed: ${cmd}\\n${result.stderr}`);\n }\n }\n }\n\n // Copy Claude credentials into container (read-write, not bind-mount)\n await copyClaudeCredentials(wrapped);\n\n return wrapped;\n}\n\n// Detect language stack from workspace files and install missing runtimes\nasync function autoInstallRuntimes(container: Container): Promise<void> {\n const detect = await exec(container, [\n 'sh', '-c',\n 'ls /workspace/package.json /workspace/pyproject.toml /workspace/setup.py '\n + '/workspace/requirements.txt /workspace/Pipfile /workspace/go.mod '\n + '/workspace/Cargo.toml /workspace/Gemfile /workspace/pom.xml '\n + '/workspace/build.gradle /workspace/build.gradle.kts '\n + '/workspace/composer.json /workspace/mix.exs 2>/dev/null || true',\n ]);\n const files = detect.stdout.trim().split('\\n').filter(Boolean);\n if (files.length === 0) return;\n\n const needs: string[] = [];\n\n // Check what's already installed\n const checks = await exec(container, [\n 'sh', '-c',\n 'echo \"node:$(which node 2>/dev/null || echo missing)\";'\n + 'echo \"python:$(which python3 2>/dev/null || which python 2>/dev/null || echo missing)\";'\n + 'echo \"go:$(which go 2>/dev/null || echo missing)\";'\n + 'echo \"ruby:$(which ruby 2>/dev/null || echo missing)\";',\n ]);\n const installed = new Map<string, boolean>();\n for (const line of checks.stdout.trim().split('\\n')) {\n const [lang, path] = line.split(':');\n installed.set(lang, path !== 'missing');\n }\n\n const hasPython = files.some(f =>\n f.includes('pyproject.toml') || f.includes('setup.py') ||\n f.includes('requirements.txt') || f.includes('Pipfile')\n );\n const hasGo = files.some(f => f.includes('go.mod'));\n const hasRuby = files.some(f => f.includes('Gemfile'));\n\n if (hasPython && !installed.get('python')) {\n needs.push('python3 python3-pip python3-venv');\n }\n if (hasGo && !installed.get('go')) {\n needs.push('golang');\n }\n if (hasRuby && !installed.get('ruby')) {\n needs.push('ruby ruby-dev');\n }\n\n if (needs.length === 0) return;\n\n const packages = needs.join(' ');\n log.info(`Detected stack requires: ${packages}`);\n\n // Try apt (Debian/Ubuntu), then apk (Alpine)\n const installResult = await exec(container, [\n 'sh', '-c',\n `(apt-get update -qq && apt-get install -y -qq ${packages} 2>/dev/null) || `\n + `(apk add --no-cache ${packages.replace('python3-pip', 'py3-pip').replace('python3-venv', '').replace('ruby-dev', 'ruby-dev build-base')} 2>/dev/null) || `\n + `echo \"Warning: could not auto-install ${packages}\"`,\n ]);\n\n if (installResult.exitCode === 0) {\n log.success('Runtime dependencies installed');\n } else {\n log.warn(`Could not auto-install ${packages} — Claude may not be able to run tests for this stack`);\n }\n}\n\nasync function copyClaudeCredentials(container: Container): Promise<void> {\n const home = homedir();\n\n // Ensure .claude directory exists in container\n await exec(container, [\n 'sh', '-c', 'mkdir -p /home/autocode/.claude && chown autocode /home/autocode/.claude',\n ]);\n\n // Copy credentials file\n const credFile = join(home, '.claude', '.credentials.json');\n if (existsSync(credFile)) {\n const content = readFileSync(credFile, 'utf-8');\n const b64 = Buffer.from(content).toString('base64');\n await exec(container, [\n 'sh', '-c',\n `echo '${b64}' | base64 -d > /home/autocode/.claude/.credentials.json && chown autocode /home/autocode/.claude/.credentials.json`,\n ]);\n log.debug('Copied .credentials.json');\n }\n\n // Copy settings if present\n const settingsFile = join(home, '.claude', 'settings.json');\n if (existsSync(settingsFile)) {\n const content = readFileSync(settingsFile, 'utf-8');\n const b64 = Buffer.from(content).toString('base64');\n await exec(container, [\n 'sh', '-c',\n `echo '${b64}' | base64 -d > /home/autocode/.claude/settings.json && chown autocode /home/autocode/.claude/settings.json`,\n ]);\n }\n\n log.info('Claude credentials copied into container');\n}\n\nexport interface ExecResult {\n exitCode: number;\n stdout: string;\n stderr: string;\n}\n\nexport async function exec(container: Container, cmd: string[], opts?: {\n workdir?: string;\n env?: string[];\n user?: string;\n timeout?: number;\n}): Promise<ExecResult> {\n const execution = await container.instance.exec({\n Cmd: cmd,\n AttachStdout: true,\n AttachStderr: true,\n WorkingDir: opts?.workdir ?? '/workspace',\n Env: opts?.env,\n User: opts?.user,\n });\n\n const stream = await execution.start({ hijack: true, stdin: false });\n\n let stdout = '';\n let stderr = '';\n\n return new Promise((resolve, reject) => {\n const stdoutStream = new PassThrough();\n const stderrStream = new PassThrough();\n\n docker.modem.demuxStream(stream, stdoutStream, stderrStream);\n\n stdoutStream.on('data', (chunk: Buffer) => { stdout += chunk.toString(); });\n stderrStream.on('data', (chunk: Buffer) => { stderr += chunk.toString(); });\n\n let timer: ReturnType<typeof setTimeout> | undefined;\n if (opts?.timeout) {\n timer = setTimeout(() => {\n stream.destroy();\n resolve({ exitCode: 124, stdout, stderr: stderr + '\\n[autocode] exec timed out' });\n }, opts.timeout);\n }\n\n stream.on('end', async () => {\n if (timer) clearTimeout(timer);\n try {\n const info = await execution.inspect();\n resolve({ exitCode: info.ExitCode ?? 1, stdout, stderr });\n } catch (e) {\n reject(e);\n }\n });\n\n stream.on('error', (e) => {\n if (timer) clearTimeout(timer);\n reject(e);\n });\n });\n}\n\nexport async function cleanupOrphanedContainers(): Promise<number> {\n const containers = await docker.listContainers({ all: true });\n const orphans = containers.filter(c =>\n c.Names.some(n => n.startsWith('/autocode-'))\n );\n let cleaned = 0;\n for (const c of orphans) {\n try {\n const container = docker.getContainer(c.Id);\n if (c.State === 'running') {\n await container.stop({ t: 5 });\n }\n await container.remove({ force: true });\n log.info(`Cleaned up orphaned container ${c.Names[0]} (${c.Id.slice(0, 12)})`);\n cleaned++;\n } catch {\n // Best effort\n }\n }\n return cleaned;\n}\n\nexport async function destroyContainer(container: Container): Promise<void> {\n try {\n await container.instance.stop({ t: 5 });\n } catch {\n // Already stopped\n }\n try {\n await container.instance.remove({ force: true });\n } catch {\n // Already removed\n }\n log.info(`Container ${container.id.slice(0, 12)} destroyed`);\n}\n\nfunction parseMemory(mem: string): number {\n const match = mem.match(/^(\\d+(?:\\.\\d+)?)(k|m|g|t)$/i);\n if (!match) throw new Error(`Invalid memory format: \"${mem}\". Use a number followed by k, m, g, or t (e.g. \"4g\", \"512m\")`);\n const [, num, unit] = match;\n const value = parseFloat(num);\n if (value <= 0) throw new Error(`Memory must be greater than 0: \"${mem}\"`);\n const multipliers: Record<string, number> = {\n k: 1024,\n m: 1024 * 1024,\n g: 1024 * 1024 * 1024,\n t: 1024 * 1024 * 1024 * 1024,\n };\n return Math.round(value * multipliers[unit.toLowerCase()]);\n}\n","import type { Container } from './docker.js';\nimport { exec } from './docker.js';\nimport type { AgentConfig } from './config.js';\nimport { log } from './logger.js';\n\n// Default timeout per Claude invocation: 30 minutes\nconst DEFAULT_ITERATION_TIMEOUT_MS = 30 * 60 * 1000;\n\nexport interface AgentResult {\n iteration: number;\n exitCode: number;\n stdout: string;\n stderr: string;\n rateLimited: boolean;\n completed: boolean;\n}\n\n// Rate limit patterns in Claude Code output\n// These patterns require error-adjacent context to reduce false positives\n// (e.g. \"429\" appearing in a filename or \"capacity\" in normal prose)\nconst RATE_LIMIT_PATTERNS = [\n /rate.?limit/i,\n /too many requests/i,\n /\\b429\\b.*(?:error|too many|rate|limit|retry)/i,\n /(?:error|status|code|http)[:\\s]*429\\b/i,\n /(?:api|server|model)\\s+(?:is\\s+)?overloaded/i,\n /over\\s*capacity/i,\n];\n\nconst COMPLETION_PATTERNS = [\n /\\[autocode:done\\]/i,\n /all tasks? completed/i,\n];\n\nfunction isRateLimited(output: string): boolean {\n return RATE_LIMIT_PATTERNS.some((p) => p.test(output));\n}\n\nfunction isCompleted(output: string): boolean {\n return COMPLETION_PATTERNS.some((p) => p.test(output));\n}\n\nfunction estimateResetMs(output: string): number {\n const match = output.match(/retry.?after[:\\s]*(\\d+)/i);\n if (match) return parseInt(match[1]) * 1000;\n return 60_000;\n}\n\nconst MAX_RATE_LIMIT_RETRIES = 10;\n\nexport async function runAgentLoop(opts: {\n container: Container;\n agentConfig: AgentConfig;\n prompt: string;\n ticketId: string;\n onIteration?: (result: AgentResult) => void;\n}): Promise<{ iterations: number; success: boolean; lastOutput: string }> {\n const { container, agentConfig, prompt, ticketId, onIteration } = opts;\n let lastOutput = '';\n let rateLimitRetries = 0;\n\n // Write prompt to a file inside the container (avoids ARG_MAX for long prompts)\n const promptB64 = Buffer.from(prompt).toString('base64');\n await exec(container, [\n 'sh', '-c',\n `mkdir -p /tmp/autocode && echo '${promptB64}' | base64 -d > /tmp/autocode/prompt.md && chmod 644 /tmp/autocode/prompt.md`,\n ]);\n\n for (let i = 1; i <= agentConfig.maxIterations; i++) {\n log.ticket(ticketId, `Iteration ${i}/${agentConfig.maxIterations}`);\n\n // claude -p \"$(cat file)\" reads prompt from file via shell substitution\n // --dangerously-skip-permissions needed for non-interactive container use\n const cmd = [\n 'sh', '-c',\n [\n 'claude',\n '-p', '\"$(cat /tmp/autocode/prompt.md)\"',\n '--model', agentConfig.model,\n '--output-format', 'text',\n '--max-turns', '50',\n '--dangerously-skip-permissions',\n '--verbose',\n ].join(' '),\n ];\n\n const timeoutMs = agentConfig.timeout\n ? agentConfig.timeout * 1000\n : DEFAULT_ITERATION_TIMEOUT_MS;\n\n const result = await exec(container, cmd, {\n user: 'autocode',\n env: ['HOME=/home/autocode', 'CLAUDE_CODE_DISABLE_NONINTERACTIVE_TUTORIAL=1'],\n timeout: timeoutMs,\n });\n\n const combined = result.stdout + result.stderr;\n lastOutput = combined;\n\n // Log a snippet of the output for debugging\n const snippet = combined.slice(-500).trim();\n if (snippet) {\n log.debug(`Agent output (last 500 chars): ${snippet}`);\n }\n\n const rateLimited = isRateLimited(combined);\n const completed = isCompleted(combined) || (result.exitCode === 0 && i > 1);\n\n const agentResult: AgentResult = {\n iteration: i,\n exitCode: result.exitCode,\n stdout: result.stdout,\n stderr: result.stderr,\n rateLimited,\n completed,\n };\n\n onIteration?.(agentResult);\n\n if (completed) {\n log.ticket(ticketId, `Completed after ${i} iterations`);\n return { iterations: i, success: true, lastOutput };\n }\n\n if (rateLimited) {\n rateLimitRetries++;\n if (rateLimitRetries > MAX_RATE_LIMIT_RETRIES) {\n log.ticket(ticketId, `Rate limited ${rateLimitRetries} times, giving up`);\n return { iterations: i, success: false, lastOutput };\n }\n const waitMs = estimateResetMs(combined);\n log.ticket(ticketId, `Rate limited (${rateLimitRetries}/${MAX_RATE_LIMIT_RETRIES}) — pausing ${Math.round(waitMs / 1000)}s`);\n await sleep(waitMs);\n // Don't count rate-limited iteration\n i--;\n continue;\n }\n\n if (result.exitCode !== 0) {\n log.ticket(ticketId, `Non-zero exit (${result.exitCode}), continuing...`);\n }\n\n // Ralph Wiggum: Claude sees its own work from previous iterations\n // via the git history and file state in the workspace.\n // We just re-run with the same prompt.\n }\n\n log.ticket(ticketId, `Max iterations (${agentConfig.maxIterations}) reached`);\n return { iterations: agentConfig.maxIterations, success: false, lastOutput };\n}\n\nfunction sleep(ms: number): Promise<void> {\n return new Promise((resolve) => setTimeout(resolve, ms));\n}\n","import type { Container } from './docker.js';\nimport { exec } from './docker.js';\nimport { log } from './logger.js';\n\n// Configure git inside container (repo already cloned + branch created on host)\nexport async function setupRepo(container: Container, opts: {\n branchName: string;\n}): Promise<void> {\n const u = { user: 'autocode' };\n await exec(container, ['git', 'config', 'user.name', 'autocode'], u);\n await exec(container, ['git', 'config', 'user.email', 'autocode@localhost'], u);\n await exec(container, ['git', 'config', '--global', 'safe.directory', '/workspace'], u);\n log.info(`Git configured, on branch ${opts.branchName}`);\n}\n\nexport async function commitAndPush(container: Container, opts: {\n branchName: string;\n ticketId: string;\n title: string;\n repoUrl: string;\n githubToken: string;\n}): Promise<{ pushed: boolean; commitCount: number }> {\n const { branchName, ticketId, title, githubToken } = opts;\n\n const u = { user: 'autocode' };\n\n // Stage and commit any uncommitted changes (agent may have left some unstaged)\n const status = await exec(container, ['git', 'status', '--porcelain'], u);\n if (status.stdout.trim()) {\n await exec(container, ['git', 'add', '-A'], u);\n const message = `${ticketId}: ${title}`;\n await exec(container, ['git', 'commit', '-m', message], u);\n }\n\n // Count commits on branch vs origin\n const countResult = await exec(container, [\n 'git', 'rev-list', '--count', `HEAD`, '--not', '--remotes',\n ], u);\n const commitCount = parseInt(countResult.stdout.trim()) || 0;\n\n if (commitCount === 0) {\n log.warn('No commits to push');\n return { pushed: false, commitCount: 0 };\n }\n\n // Configure token via git credential helper to avoid token in remote URL / process list\n await exec(container, [\n 'sh', '-c',\n `git config credential.helper '!f() { echo \"password=${githubToken}\"; echo \"username=x-access-token\"; }; f'`,\n ], u);\n\n // Push\n const pushResult = await exec(container, ['git', 'push', '-u', 'origin', branchName], u);\n if (pushResult.exitCode !== 0) {\n // Redact any token that may appear in stderr\n const safeStderr = pushResult.stderr.replace(/x-access-token:[^\\s@]+/g, 'x-access-token:***');\n log.error(`Push failed: ${safeStderr}`);\n return { pushed: false, commitCount };\n }\n\n log.success(`Pushed ${commitCount} commit(s) to ${branchName}`);\n return { pushed: true, commitCount };\n}\n","import type { Config } from './config.js';\nimport { loadRepoLocalConfig, mergeConfigs } from './config.js';\nimport type { Ticket } from './linear.js';\nimport { claimTicket, completeTicket, failTicket, addBranchLabel } from './linear.js';\nimport { createContainer, destroyContainer } from './docker.js';\nimport type { Container } from './docker.js';\nimport { runAgentLoop } from './agent.js';\nimport { setupRepo, commitAndPush } from './git.js';\nimport { openPR } from './github.js';\nimport type { Octokit } from '@octokit/rest';\nimport type { LinearClient } from '@linear/sdk';\nimport { log } from './logger.js';\nimport { mkdtempSync, rmSync, writeFileSync } from 'node:fs';\nimport { join } from 'node:path';\nimport { tmpdir } from 'node:os';\nimport { execSync } from 'node:child_process';\n\nexport interface WorkerResult {\n ticketId: string;\n success: boolean;\n prUrl?: string;\n error?: string;\n iterations: number;\n}\n\nfunction buildPrompt(ticket: Ticket, repoPrompt?: string): string {\n const parts: string[] = [];\n\n if (repoPrompt) {\n parts.push(repoPrompt);\n parts.push('');\n }\n\n parts.push(`## Task: ${ticket.identifier} — ${ticket.title}`);\n parts.push('');\n\n if (ticket.description) {\n parts.push(ticket.description);\n }\n\n parts.push('');\n parts.push('## Instructions');\n parts.push('- Start by reading CLAUDE.md if it exists — it has project-specific guidance');\n parts.push('- Read the codebase to understand the context before making changes');\n parts.push('- Work through the task step by step');\n parts.push('- After making changes, run: git add -A && git commit -m \"description of changes\"');\n parts.push('- Commit after each logical step (do not batch all changes into one commit)');\n parts.push('- If the task has a checklist, work through items in order and commit after each one');\n parts.push('- Tests MUST import from the actual source modules — never re-implement or duplicate source code in tests');\n parts.push('- If the project uses TypeScript but tests are plain JS, install tsx or ts-node so tests can import .ts files');\n parts.push('- Run any existing tests before finishing to verify your changes');\n parts.push('- IMPORTANT: You MUST commit your changes with git before finishing');\n parts.push('- When all work is complete and committed, include [autocode:done] in your final output');\n\n return parts.join('\\n');\n}\n\nfunction slugify(s: string): string {\n return s.toLowerCase().replace(/[^a-z0-9]+/g, '-').replace(/^-|-$/g, '').slice(0, 50);\n}\n\n// Validate ref names to prevent shell injection (branch names come from .autocode.yaml)\nfunction assertSafeRef(name: string, label: string): void {\n // Git ref rules: no space, ~, ^, :, ?, *, [, \\, control chars, or ..\n if (!name || /[\\s~^:?*\\[\\\\]|\\.\\./.test(name) || name.startsWith('-')) {\n throw new Error(`Invalid ${label}: \"${name}\"`);\n }\n}\n\n// Create a GIT_ASKPASS script that provides the token without exposing it in process args\nfunction createAskpass(githubToken: string): { dir: string; path: string } {\n const dir = mkdtempSync(join(tmpdir(), 'autocode-cred-'));\n const path = join(dir, 'askpass.sh');\n writeFileSync(path, `#!/bin/sh\\necho \"${githubToken}\"\\n`, { mode: 0o700 });\n return { dir, path };\n}\n\nfunction gitEnv(askpassPath: string): NodeJS.ProcessEnv {\n return { ...process.env, GIT_ASKPASS: askpassPath, GIT_TERMINAL_PROMPT: '0' };\n}\n\n// Detect the default branch of a remote repo (main, master, develop, etc.)\nfunction detectDefaultBranch(repoUrl: string, githubToken: string): string {\n const askpass = createAskpass(githubToken);\n const authedUrl = repoUrl.replace('https://', 'https://x-access-token@');\n try {\n // git ls-remote --symref gives us HEAD → refs/heads/main (or whatever the default is)\n const output = execSync(\n `git ls-remote --symref -- ${authedUrl} HEAD`,\n { stdio: 'pipe', timeout: 30_000, env: gitEnv(askpass.path), encoding: 'utf-8' }\n );\n // Parse: \"ref: refs/heads/main\\tHEAD\"\n const match = output.match(/ref:\\s+refs\\/heads\\/(\\S+)\\s+HEAD/);\n if (match) return match[1];\n } catch {\n // Fall through to default\n } finally {\n rmSync(askpass.dir, { recursive: true, force: true });\n }\n return 'main'; // fallback\n}\n\n// Clone repo to temp dir on the host so we can read .autocode.yaml before Docker\nfunction cloneToTemp(repoUrl: string, baseBranch: string, githubToken: string): string {\n assertSafeRef(baseBranch, 'base branch');\n const workDir = mkdtempSync(join(tmpdir(), 'autocode-'));\n const askpass = createAskpass(githubToken);\n const authedUrl = repoUrl.replace('https://', 'https://x-access-token@');\n\n try {\n execSync(`git clone --depth=50 -b ${baseBranch} -- ${authedUrl} ${workDir}`, {\n stdio: 'pipe',\n timeout: 120_000,\n env: gitEnv(askpass.path),\n });\n } finally {\n rmSync(askpass.dir, { recursive: true, force: true });\n }\n return workDir;\n}\n\nexport async function executeTicket(opts: {\n ticket: Ticket;\n config: Config;\n linearClient: LinearClient;\n octokit: Octokit;\n}): Promise<WorkerResult> {\n const { ticket, config, linearClient, octokit } = opts;\n\n if (!ticket.repoUrl) {\n return {\n ticketId: ticket.identifier,\n success: false,\n error: 'No repo:owner/name label on ticket',\n iterations: 0,\n };\n }\n\n // Validate repo URL before attempting clone\n if (!ticket.repoUrl.startsWith('https://')) {\n return {\n ticketId: ticket.identifier,\n success: false,\n error: `Invalid repo URL: \"${ticket.repoUrl}\". Only HTTPS URLs are supported.`,\n iterations: 0,\n };\n }\n\n const branchName = `autocode/${ticket.identifier}-${slugify(ticket.title)}`;\n // Docker container names: [a-zA-Z0-9_.-] only\n const containerName = `${ticket.identifier}-${Date.now()}`.toLowerCase().replace(/[^a-z0-9_.-]/g, '-');\n let workDir: string | undefined;\n let container: Container | undefined;\n\n try {\n // 1. Claim the ticket in Linear\n await claimTicket(linearClient, config, ticket.id);\n log.ticket(ticket.identifier, `Claimed — ${ticket.repoUrl}`);\n\n // 2. Detect the repo's default branch (main, master, develop, etc.)\n const detectedBase = detectDefaultBranch(ticket.repoUrl, config.github.token);\n log.ticket(ticket.identifier, `Default branch: ${detectedBase}`);\n\n // Clone with the detected default branch\n workDir = cloneToTemp(ticket.repoUrl, detectedBase, config.github.token);\n log.ticket(ticket.identifier, 'Cloned repo');\n\n // 3. Load .autocode.yaml from repo, merge with host config\n const repoLocal = loadRepoLocalConfig(workDir);\n // Priority: ticket \"base:\" label > .autocode.yaml base > detected default branch\n // Ticket label enables stacked diffs (branching from another PR's branch)\n const actualBase = ticket.baseBranch ?? repoLocal?.base ?? detectedBase;\n const { agent, docker, prompt } = mergeConfigs(config, repoLocal);\n\n if (repoLocal) {\n log.ticket(ticket.identifier, 'Loaded .autocode.yaml from repo');\n }\n if (ticket.baseBranch) {\n log.ticket(ticket.identifier, `Stacked on branch: ${ticket.baseBranch}`);\n }\n\n // If base branch differs from what we cloned, re-clone with the correct base\n if (actualBase !== detectedBase) {\n rmSync(workDir, { recursive: true, force: true });\n workDir = cloneToTemp(ticket.repoUrl, actualBase, config.github.token);\n }\n\n // Create working branch on host\n // Use -B (force-create) so retried tickets don't fail with \"branch already exists\"\n execSync(`git checkout -B ${branchName} --`, { cwd: workDir, stdio: 'pipe' });\n\n // 4. Spin up Docker container with workspace mounted\n container = await createContainer({\n dockerConfig: docker,\n workspacePath: workDir,\n name: containerName,\n });\n\n // Configure git inside container\n await setupRepo(container, { branchName });\n\n // 5. Run Claude Code in Ralph Wiggum loop\n const agentPrompt = buildPrompt(ticket, prompt);\n const agentResult = await runAgentLoop({\n container,\n agentConfig: agent,\n prompt: agentPrompt,\n ticketId: ticket.identifier,\n });\n\n // 6. Push (agent commits incrementally, we just push)\n const gitResult = await commitAndPush(container, {\n branchName,\n ticketId: ticket.identifier,\n title: ticket.title,\n repoUrl: ticket.repoUrl,\n githubToken: config.github.token,\n });\n\n if (!gitResult.pushed) {\n await failTicket(linearClient, ticket.id, 'No changes produced');\n return {\n ticketId: ticket.identifier,\n success: false,\n error: 'No changes produced',\n iterations: agentResult.iterations,\n };\n }\n\n // 7. Open PR\n const prBody: string[] = [\n `Resolves [${ticket.identifier}](${ticket.url})`,\n '',\n ];\n\n // Include ticket description if present (truncated for very long descriptions)\n if (ticket.description) {\n const desc = ticket.description.length > 2000\n ? ticket.description.slice(0, 2000) + '\\n\\n*[description truncated]*'\n : ticket.description;\n prBody.push('## Description', '', desc, '');\n }\n\n prBody.push(\n '## Details',\n '',\n `| Metric | Value |`,\n `| --- | --- |`,\n `| Iterations | ${agentResult.iterations} |`,\n `| Commits | ${gitResult.commitCount} |`,\n `| Model | ${agent.model} |`,\n '',\n '---',\n '*Generated by [autocode](https://github.com/rahulrai/autocode)*',\n );\n\n const pr = await openPR(octokit, {\n repoUrl: ticket.repoUrl,\n branch: branchName,\n baseBranch: actualBase,\n title: `${ticket.identifier}: ${ticket.title}`,\n body: prBody.join('\\n'),\n });\n\n // 8. Update Linear ticket\n await completeTicket(linearClient, config, ticket.id, `PR opened: ${pr.url}`);\n\n // 9. Add branch label to ticket so child tickets can stack on it\n // e.g. child ticket adds label \"base:autocode/T-123-fix-login\" to branch from this PR\n await addBranchLabel(linearClient, ticket.id, branchName);\n\n log.success(`${ticket.identifier} done — ${pr.url}`);\n return {\n ticketId: ticket.identifier,\n success: true,\n prUrl: pr.url,\n iterations: agentResult.iterations,\n };\n } catch (err) {\n const msg = err instanceof Error ? err.message : String(err);\n log.error(`${ticket.identifier} failed: ${msg}`);\n\n try {\n await failTicket(linearClient, ticket.id, msg);\n } catch {\n // Best effort\n }\n\n return {\n ticketId: ticket.identifier,\n success: false,\n error: msg,\n iterations: 0,\n };\n } finally {\n // 9. Kill the container\n if (container) {\n await destroyContainer(container);\n }\n\n // Clean up temp dir\n if (workDir) {\n try {\n rmSync(workDir, { recursive: true, force: true });\n } catch {\n // Best effort\n }\n }\n }\n}\n","import { spawn } from 'node:child_process';\nimport { log } from './logger.js';\n\nexport interface TunnelInfo {\n url: string;\n process: ReturnType<typeof spawn>;\n}\n\nexport async function startQuickTunnel(port: number): Promise<TunnelInfo> {\n return new Promise((resolve, reject) => {\n const proc = spawn('cloudflared', ['tunnel', '--url', `http://127.0.0.1:${port}`], {\n stdio: ['ignore', 'pipe', 'pipe'],\n });\n\n let resolved = false;\n const timeout = setTimeout(() => {\n if (!resolved) {\n reject(new Error('Tunnel startup timed out after 30s'));\n }\n }, 30_000);\n\n const handleOutput = (data: Buffer) => {\n const line = data.toString();\n // Quick tunnel URL appears in stderr as: https://xxx.trycloudflare.com\n const match = line.match(/(https:\\/\\/[a-z0-9-]+\\.trycloudflare\\.com)/);\n if (match && !resolved) {\n resolved = true;\n clearTimeout(timeout);\n resolve({ url: match[1], process: proc });\n }\n };\n\n proc.stdout.on('data', handleOutput);\n proc.stderr.on('data', handleOutput);\n\n proc.on('error', (err) => {\n if (!resolved) {\n clearTimeout(timeout);\n if ((err as NodeJS.ErrnoException).code === 'ENOENT') {\n reject(new Error('cloudflared not found. Install it: https://developers.cloudflare.com/cloudflare-one/connections/connect-networks/downloads/'));\n } else {\n reject(err);\n }\n }\n });\n\n proc.on('exit', (code) => {\n if (!resolved) {\n clearTimeout(timeout);\n reject(new Error(`cloudflared exited with code ${code}`));\n }\n });\n });\n}\n\nexport function stopTunnel(tunnel: TunnelInfo): void {\n tunnel.process.kill('SIGTERM');\n log.info('Tunnel stopped');\n}\n","import { execSync } from 'node:child_process';\nimport { existsSync } from 'node:fs';\nimport { join } from 'node:path';\nimport { homedir } from 'node:os';\nimport { log } from './logger.js';\n\n// --- Package manager detection ---\n\ntype PackageManager = 'apt' | 'yum' | 'dnf' | 'pacman' | 'apk' | 'brew' | 'unknown';\n\nfunction detectPackageManager(): PackageManager {\n const checks: [PackageManager, string][] = [\n ['apt', 'apt-get'],\n ['dnf', 'dnf'],\n ['yum', 'yum'],\n ['pacman', 'pacman'],\n ['apk', 'apk'],\n ['brew', 'brew'],\n ];\n for (const [name, cmd] of checks) {\n try {\n execSync(`which ${cmd}`, { stdio: 'pipe' });\n return name;\n } catch { /* not found */ }\n }\n return 'unknown';\n}\n\n// --- Install commands per package manager ---\n\nconst DOCKER_INSTALL: Record<PackageManager, string[]> = {\n apt: [\n 'apt-get update -qq',\n 'apt-get install -y docker.io',\n 'systemctl enable docker',\n 'systemctl start docker',\n ],\n dnf: [\n 'dnf install -y docker',\n 'systemctl enable docker',\n 'systemctl start docker',\n ],\n yum: [\n 'yum install -y docker',\n 'systemctl enable docker',\n 'systemctl start docker',\n ],\n pacman: [\n 'pacman -Sy --noconfirm docker',\n 'systemctl enable docker',\n 'systemctl start docker',\n ],\n apk: [\n 'apk add docker',\n 'rc-update add docker boot',\n 'service docker start',\n ],\n brew: [\n 'brew install --cask docker',\n ],\n unknown: [],\n};\n\nconst CLOUDFLARED_INSTALL: Record<PackageManager, string[]> = {\n apt: [\n 'apt-get update -qq',\n 'apt-get install -y cloudflared || (curl -fsSL https://pkg.cloudflare.com/cloudflare-main.gpg | tee /usr/share/keyrings/cloudflare-main.gpg >/dev/null && echo \"deb [signed-by=/usr/share/keyrings/cloudflare-main.gpg] https://pkg.cloudflare.com/cloudflared $(lsb_release -cs) main\" | tee /etc/apt/sources.list.d/cloudflared.list && apt-get update -qq && apt-get install -y cloudflared)',\n ],\n dnf: ['dnf install -y cloudflared || npm install -g cloudflared'],\n yum: ['yum install -y cloudflared || npm install -g cloudflared'],\n pacman: ['pacman -Sy --noconfirm cloudflared'],\n apk: ['apk add cloudflared'],\n brew: ['brew install cloudflared'],\n unknown: [],\n};\n\n// --- Dependency status ---\n\nexport interface DepStatus {\n name: string;\n installed: boolean;\n running?: boolean; // for services like Docker\n installable: boolean;\n installCommands: string[];\n manualInstructions: string;\n}\n\nexport function checkDeps(): DepStatus[] {\n const pm = detectPackageManager();\n const needsSudo = pm !== 'brew' && pm !== 'unknown' && process.getuid?.() !== 0;\n const sudo = needsSudo ? 'sudo ' : '';\n\n return [\n {\n name: 'Docker',\n installed: commandExists('docker'),\n running: isDockerRunning(),\n installable: pm !== 'unknown',\n installCommands: DOCKER_INSTALL[pm].map(c => `${sudo}${c}`),\n manualInstructions: 'https://docs.docker.com/get-docker/',\n },\n {\n name: 'Claude Code',\n installed: commandExists('claude'),\n installable: commandExists('npm'),\n installCommands: ['npm install -g @anthropic-ai/claude-code@latest'],\n manualInstructions: 'npm install -g @anthropic-ai/claude-code',\n },\n {\n name: 'Claude credentials',\n installed: existsSync(join(homedir(), '.claude', '.credentials.json')),\n installable: false,\n installCommands: [],\n manualInstructions: 'Run \"claude\" and complete the login flow',\n },\n {\n name: 'cloudflared',\n installed: commandExists('cloudflared'),\n installable: pm !== 'unknown',\n installCommands: CLOUDFLARED_INSTALL[pm].map(c => `${sudo}${c}`),\n manualInstructions: 'https://developers.cloudflare.com/cloudflare-one/connections/connect-networks/downloads/',\n },\n ];\n}\n\nexport function installDep(dep: DepStatus): boolean {\n if (dep.installCommands.length === 0) return false;\n for (const cmd of dep.installCommands) {\n try {\n execSync(cmd, { stdio: 'inherit', timeout: 300_000 });\n } catch {\n return false;\n }\n }\n return true;\n}\n\n// After Docker install, add user to docker group so sudo isn't needed\nexport function addUserToDockerGroup(): void {\n if (process.platform !== 'linux') return;\n try {\n const user = execSync('whoami', { encoding: 'utf-8' }).trim();\n execSync(`sudo usermod -aG docker ${user}`, { stdio: 'pipe' });\n log.info(`Added ${user} to docker group — log out and back in to apply`);\n } catch {\n // Non-fatal\n }\n}\n\nfunction commandExists(cmd: string): boolean {\n try {\n execSync(`which ${cmd}`, { stdio: 'pipe' });\n return true;\n } catch {\n return false;\n }\n}\n\nfunction isDockerRunning(): boolean {\n try {\n execSync('docker info', { stdio: 'pipe', timeout: 10_000 });\n return true;\n } catch {\n return false;\n }\n}\n"],"mappings":"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","names":["docker","existsSync","join","homedir","pr","homedir","join","existsSync","readFileSync","join","homedir","existsSync","readFileSync","mkdtempSync","rmSync","writeFileSync","join","tmpdir","execSync","docker","ticket","execSync","existsSync","join","homedir","execSync","existsSync","join","homedir","existsSync","mkdirSync","writeFileSync","execSync","join","homedir","LinearClient","Octokit","require"]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@autoclawd/autocode",
3
- "version": "0.4.0",
3
+ "version": "0.4.1",
4
4
  "description": "Linear tickets → Claude Code in Docker → PRs",
5
5
  "type": "module",
6
6
  "bin": {