@autoclawd/autoclawd 1.0.2 → 1.0.3
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 +67 -1
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -467,6 +467,32 @@ async function fetchPR(octokit, opts) {
|
|
|
467
467
|
state: data.state
|
|
468
468
|
};
|
|
469
469
|
}
|
|
470
|
+
async function ensureRepoExists(octokit, opts) {
|
|
471
|
+
try {
|
|
472
|
+
await octokit.rest.repos.get({ owner: opts.owner, repo: opts.repo });
|
|
473
|
+
return { created: false };
|
|
474
|
+
} catch (err) {
|
|
475
|
+
const status = err.status;
|
|
476
|
+
if (status !== 404) throw err;
|
|
477
|
+
}
|
|
478
|
+
log.info(`Repo ${opts.owner}/${opts.repo} does not exist, creating...`);
|
|
479
|
+
const { data: authUser } = await octokit.rest.users.getAuthenticated();
|
|
480
|
+
if (authUser.login === opts.owner) {
|
|
481
|
+
await octokit.rest.repos.createForAuthenticatedUser({
|
|
482
|
+
name: opts.repo,
|
|
483
|
+
description: opts.description,
|
|
484
|
+
auto_init: false
|
|
485
|
+
});
|
|
486
|
+
} else {
|
|
487
|
+
await octokit.rest.repos.createInOrg({
|
|
488
|
+
org: opts.owner,
|
|
489
|
+
name: opts.repo,
|
|
490
|
+
description: opts.description,
|
|
491
|
+
auto_init: false
|
|
492
|
+
});
|
|
493
|
+
}
|
|
494
|
+
return { created: true };
|
|
495
|
+
}
|
|
470
496
|
async function fetchFailedChecks(octokit, opts) {
|
|
471
497
|
const { owner, repo } = parseRepoUrl(opts.repoUrl);
|
|
472
498
|
const { data: pr } = await octokit.rest.pulls.get({ owner, repo, pull_number: opts.prNumber });
|
|
@@ -1224,6 +1250,31 @@ function detectDefaultBranch(repoUrl, githubToken) {
|
|
|
1224
1250
|
}
|
|
1225
1251
|
return "main";
|
|
1226
1252
|
}
|
|
1253
|
+
async function pushScaffold(opts) {
|
|
1254
|
+
const scaffoldDir = mkdtempSync(join5(tmpdir(), "autoclawd-scaffold-"));
|
|
1255
|
+
const askpass = createAskpass(opts.githubToken);
|
|
1256
|
+
try {
|
|
1257
|
+
const authedUrl = opts.repoUrl.replace("https://", "https://x-access-token@");
|
|
1258
|
+
const env = gitEnv(askpass.path);
|
|
1259
|
+
const readmeLines = [`# ${opts.ticketTitle}`];
|
|
1260
|
+
if (opts.ticketDescription) {
|
|
1261
|
+
readmeLines.push("", opts.ticketDescription);
|
|
1262
|
+
}
|
|
1263
|
+
writeFileSync(join5(scaffoldDir, "README.md"), readmeLines.join("\n") + "\n");
|
|
1264
|
+
writeFileSync(join5(scaffoldDir, ".autoclawd.yaml"), "base: main\n");
|
|
1265
|
+
execSync("git init", { cwd: scaffoldDir, stdio: "pipe", env });
|
|
1266
|
+
execSync("git checkout -b main", { cwd: scaffoldDir, stdio: "pipe", env });
|
|
1267
|
+
execSync('git config user.email "autoclawd@users.noreply.github.com"', { cwd: scaffoldDir, stdio: "pipe", env });
|
|
1268
|
+
execSync('git config user.name "autoclawd"', { cwd: scaffoldDir, stdio: "pipe", env });
|
|
1269
|
+
execSync("git add .", { cwd: scaffoldDir, stdio: "pipe", env });
|
|
1270
|
+
execSync('git commit -m "chore: initial scaffold"', { cwd: scaffoldDir, stdio: "pipe", env });
|
|
1271
|
+
execSync(`git remote add origin ${authedUrl}`, { cwd: scaffoldDir, stdio: "pipe", env });
|
|
1272
|
+
execSync("git push -u origin main", { cwd: scaffoldDir, stdio: "pipe", timeout: 6e4, env });
|
|
1273
|
+
} finally {
|
|
1274
|
+
rmSync(scaffoldDir, { recursive: true, force: true });
|
|
1275
|
+
rmSync(askpass.dir, { recursive: true, force: true });
|
|
1276
|
+
}
|
|
1277
|
+
}
|
|
1227
1278
|
async function cloneToTemp(repoUrl, baseBranch, githubToken) {
|
|
1228
1279
|
assertSafeRef(baseBranch, "base branch");
|
|
1229
1280
|
return retrySync(() => {
|
|
@@ -1362,7 +1413,22 @@ async function executeTicket(opts) {
|
|
|
1362
1413
|
try {
|
|
1363
1414
|
await claimTicket(linearClient, config, ticket.id);
|
|
1364
1415
|
log.ticket(ticket.identifier, `Claimed \u2014 ${ticket.repoUrl}`);
|
|
1365
|
-
const
|
|
1416
|
+
const { owner: repoOwner, repo: repoName } = parseRepoUrl(ticket.repoUrl);
|
|
1417
|
+
const { created: repoCreated } = await ensureRepoExists(octokit, {
|
|
1418
|
+
owner: repoOwner,
|
|
1419
|
+
repo: repoName,
|
|
1420
|
+
description: ticket.title
|
|
1421
|
+
});
|
|
1422
|
+
if (repoCreated) {
|
|
1423
|
+
await pushScaffold({
|
|
1424
|
+
repoUrl: ticket.repoUrl,
|
|
1425
|
+
ticketTitle: ticket.title,
|
|
1426
|
+
ticketDescription: ticket.description,
|
|
1427
|
+
githubToken: config.github.token
|
|
1428
|
+
});
|
|
1429
|
+
log.ticket(ticket.identifier, "Repo created, pushed scaffold");
|
|
1430
|
+
}
|
|
1431
|
+
const detectedBase = repoCreated ? "main" : detectDefaultBranch(ticket.repoUrl, config.github.token);
|
|
1366
1432
|
log.ticket(ticket.identifier, `Default branch: ${detectedBase}`);
|
|
1367
1433
|
workDir = await cloneToTemp(ticket.repoUrl, detectedBase, config.github.token);
|
|
1368
1434
|
log.ticket(ticket.identifier, "Cloned repo");
|
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/retry.ts","../src/github.ts","../src/webhook.ts","../src/docker.ts","../src/agent.ts","../src/git.ts","../src/worker.ts","../src/db.ts","../src/tunnel.ts","../src/watch.ts","../src/history.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, fixPR } from './worker.js';\nimport { Watcher } from './watch.js';\nimport { readHistory, printHistoryTable, migrateJsonlToSqlite } from './history.js';\nimport type { HistoryRecord } from './history.js';\nimport { checkDockerAvailable, cleanupOrphanedContainers } from './docker.js';\nimport { log, setLogLevel, enableFileLogging, getLogFilePath } from './logger.js';\nimport { checkDeps, installDep, addUserToDockerGroup } from './deps.js';\nimport { existsSync, mkdirSync, writeFileSync, readFileSync, unlinkSync } from 'node:fs';\nimport { execSync, spawn } 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\n// --- PID file helpers for background watcher ---\nconst WATCHER_PID_FILE = join(homedir(), '.autoclawd', 'watcher.pid');\n\nfunction readWatcherPid(): number | null {\n try {\n const content = readFileSync(WATCHER_PID_FILE, 'utf-8').trim();\n const pid = parseInt(content, 10);\n return isNaN(pid) ? null : pid;\n } catch {\n return null;\n }\n}\n\nfunction writeWatcherPid(pid: number): void {\n mkdirSync(join(homedir(), '.autoclawd'), { recursive: true });\n writeFileSync(WATCHER_PID_FILE, String(pid), { mode: 0o600 });\n}\n\nfunction removeWatcherPid(): void {\n try {\n unlinkSync(WATCHER_PID_FILE);\n } catch {\n // File may not exist — that's fine\n }\n}\n\nfunction getRunningWatcherPid(): number | null {\n const pid = readWatcherPid();\n if (pid === null) return null;\n try {\n process.kill(pid, 0); // Signal 0: check if process exists without killing it\n return pid;\n } catch {\n return null; // Process not found\n }\n}\n\nprogram\n .name('autoclawd')\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(`autoclawd 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: 'autoclawd',\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// --- watch ---\nprogram\n .command('watch')\n .description('Poll Linear for tickets (no webhook/tunnel needed)')\n .option('-c, --config <path>', 'Config file path')\n .option('-i, --interval <seconds>', 'Poll interval in seconds', '30')\n .option('--once', 'Poll once and exit (useful for cron)')\n .option('--foreground', 'Run in foreground instead of daemonizing')\n .option('-v, --verbose', 'Verbose logging')\n .action(async (opts) => {\n // Daemonize by default unless --foreground or --once is specified\n if (!opts.foreground && !opts.once) {\n // Refuse to start if another watcher is already running\n const existingPid = getRunningWatcherPid();\n if (existingPid !== null) {\n console.error(`autoclawd watcher is already running (PID ${existingPid})`);\n console.error(`Run 'autoclawd stop' to stop it, or use '--foreground' to run in terminal`);\n process.exit(1);\n }\n\n // Spawn background child with --foreground flag\n const child = spawn(process.argv[0], [...process.argv.slice(1), '--foreground'], {\n detached: true,\n stdio: 'ignore',\n });\n\n // Wait for child to start before printing success\n await new Promise<void>((resolve, reject) => {\n child.once('spawn', resolve);\n child.once('error', reject);\n });\n\n writeWatcherPid(child.pid!);\n const logPath = getLogFilePath();\n console.log(`autoclawd watching in background (PID ${child.pid}, log: ${logPath})`);\n\n child.unref();\n process.exit(0);\n return;\n }\n\n if (opts.verbose) setLogLevel('debug');\n\n enableFileLogging();\n log.info(`autoclawd 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 const orphans = await cleanupOrphanedContainers();\n if (orphans > 0) {\n log.info(`Cleaned up ${orphans} orphaned container(s) from previous session`);\n }\n\n const config = loadConfig(opts.config);\n const intervalSeconds = parseInt(opts.interval);\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 watcher = new Watcher(config, linearClient, octokit);\n\n const shutdown = () => {\n log.info('Shutting down...');\n watcher.stop();\n removeWatcherPid();\n process.exit(0);\n };\n process.on('SIGINT', shutdown);\n process.on('SIGTERM', shutdown);\n\n await watcher.start(intervalSeconds, opts.once ?? false);\n });\n\n// --- stop ---\nprogram\n .command('stop')\n .description('Stop the background watcher')\n .action(() => {\n const pid = readWatcherPid();\n if (pid === null) {\n log.info('No watcher PID file found — watcher is not running');\n return;\n }\n\n const running = getRunningWatcherPid();\n if (running === null) {\n // Stale PID file\n removeWatcherPid();\n log.info(`Removed stale PID file (process ${pid} is not running)`);\n return;\n }\n\n try {\n process.kill(pid, 'SIGTERM');\n removeWatcherPid();\n log.success(`Watcher stopped (PID ${pid})`);\n } catch (err) {\n log.error(`Failed to stop watcher: ${err instanceof Error ? err.message : err}`);\n process.exit(1);\n }\n });\n\n// --- run ---\nprogram\n .command('run <ticket>')\n .description('Run a single ticket (e.g. autoclawd 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 .option('--force', 'Bypass completed-ticket check and re-run')\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 .autoclawd.yaml or main)'}`);\n log.info(` Branch: autoclawd/${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, force: opts.force });\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// --- fix ---\nprogram\n .command('fix <pr-url>')\n .description('Fix failed CI checks on a PR (e.g. autoclawd fix https://github.com/owner/repo/pull/123)')\n .option('-c, --config <path>', 'Config file path')\n .option('-v, --verbose', 'Verbose logging')\n .action(async (prUrl: string, opts) => {\n if (opts.verbose) setLogLevel('debug');\n enableFileLogging();\n\n // Parse PR URL: https://github.com/owner/repo/pull/123\n const match = prUrl.match(/github\\.com\\/([^/]+)\\/([^/]+)\\/pull\\/(\\d+)/);\n if (!match) {\n throw new Error(`Invalid PR URL: \"${prUrl}\"\\nExpected: https://github.com/owner/repo/pull/123`);\n }\n const [, owner, repo, prNumStr] = match;\n const repoUrl = `https://github.com/${owner}/${repo}`;\n const prNumber = parseInt(prNumStr);\n\n const config = loadConfig(opts.config);\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 const octokit = createOctokit(config);\n\n const result = await fixPR({ repoUrl, prNumber, config, octokit });\n if (!result.success) {\n throw new Error(result.error ?? 'Fix failed');\n }\n });\n\n// --- retry ---\nprogram\n .command('retry [ticket]')\n .description('Retry a failed ticket (e.g. autoclawd retry RAH-123)')\n .option('-c, --config <path>', 'Config file path')\n .option('-v, --verbose', 'Verbose logging')\n .option('--last-failed', 'Retry the most recent failed run')\n .option('--all-failed', 'Retry all failed runs (sequentially)')\n .action(async (ticketArg: string | undefined, opts) => {\n if (opts.verbose) setLogLevel('debug');\n enableFileLogging();\n\n if (!ticketArg && !opts.lastFailed && !opts.allFailed) {\n throw new Error(\n 'Provide a ticket ID, --last-failed, or --all-failed.\\n'\n + 'Usage: autoclawd retry RAH-123 | --last-failed | --all-failed'\n );\n }\n\n const config = loadConfig(opts.config);\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 linearClient = createLinearClient(config);\n const octokit = createOctokit(config);\n\n // Determine which ticket(s) to retry\n let ticketIds: string[] = [];\n\n if (ticketArg) {\n // Explicit ticket ID — check history for context but proceed even if not found\n const history = readHistory({ failedOnly: true, limit: 1000 });\n const prev = history.find(\n (r) => r.ticketId.toLowerCase() === ticketArg.toLowerCase()\n );\n if (prev) {\n log.info(`Retrying ${prev.ticketId} — last failure: ${prev.error ?? 'unknown error'}`);\n log.info(` Failed at: ${prev.startedAt}`);\n } else {\n log.info(`No previous failure found for ${ticketArg}, running fresh`);\n }\n ticketIds = [ticketArg];\n } else if (opts.lastFailed) {\n const history = readHistory({ failedOnly: true, limit: 1 });\n if (history.length === 0) {\n throw new Error('No failed runs found in history');\n }\n const last = history[0];\n log.info(`Retrying last failed: ${last.ticketId} — ${last.error ?? 'unknown error'}`);\n log.info(` Failed at: ${last.startedAt}`);\n ticketIds = [last.ticketId];\n } else if (opts.allFailed) {\n // Collect unique ticket IDs from failures that don't have a subsequent success\n const allRecords = readHistory({ limit: 10000 });\n const succeeded = new Set(\n allRecords.filter((r) => r.status === 'success').map((r) => r.ticketId)\n );\n const failedUnique = new Map<string, HistoryRecord>();\n for (const r of allRecords) {\n if (r.status === 'failure' && !succeeded.has(r.ticketId) && !failedUnique.has(r.ticketId)) {\n failedUnique.set(r.ticketId, r);\n }\n }\n if (failedUnique.size === 0) {\n throw new Error('No unresolved failed runs found in history');\n }\n log.info(`Found ${failedUnique.size} failed ticket(s) to retry:`);\n for (const [id, rec] of failedUnique) {\n log.info(` ${id} — ${rec.error ?? 'unknown error'}`);\n }\n ticketIds = [...failedUnique.keys()];\n }\n\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 for (const id of ticketIds) {\n log.info(`\\nRetrying ticket ${id}...`);\n const ticket = await fetchTicket(linearClient, id);\n if (!ticket) {\n log.error(`Ticket ${id} not found in Linear, skipping`);\n continue;\n }\n if (!ticket.repoUrl) {\n log.error(`${id} has no repo: label, skipping`);\n continue;\n }\n const result = await executeTicket({ ticket, config, linearClient, octokit });\n if (result.success) {\n log.success(`${id} completed${result.prUrl ? ` → ${result.prUrl}` : ''}`);\n } else {\n log.error(`${id} failed again: ${result.error ?? 'unknown'}`);\n if (ticketIds.length === 1) {\n throw new Error(result.error ?? 'Retry failed');\n }\n }\n }\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 autoclawd 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// --- history ---\nprogram\n .command('history')\n .description('Show run history')\n .option('-n, --limit <number>', 'Number of records to show', '20')\n .option('--json', 'Output as JSON')\n .option('--failed', 'Show only failures')\n .action((opts) => {\n // Migrate legacy JSONL records into SQLite on first use\n migrateJsonlToSqlite();\n\n const records = readHistory({\n limit: parseInt(opts.limit),\n failedOnly: opts.failed ?? false,\n });\n\n if (opts.json) {\n console.log(JSON.stringify(records, null, 2));\n } else {\n printHistoryTable(records);\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 autoclawd interactively')\n .action(async () => {\n console.log('\\n autoclawd 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: autoclawd 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 (any image works — autoclawd auto-installs git + Claude Code):');\n console.log(' node:20 — Node.js (default, recommended)');\n console.log(' python:3.12 — Python');\n console.log(' ubuntu:24.04 — General purpose');\n const dockerImage = await ask('Docker image', 'node:20');\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). autoclawd resolves\n // these from the environment at runtime.\n const config = `# autoclawd config — generated by autoclawd 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 autoclawd:\n $ autoclawd serve\n\n autoclawd 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 (~/.autoclawd/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/autoclawd/.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 SafetyConfigSchema = z.object({\n allowedRepos: z.array(z.string()).optional(),\n branchPrefix: z.string().default('autoclawd/'),\n maxFileChanges: z.number().min(1).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 safety: SafetyConfigSchema.default({}),\n maxConcurrent: z.number().default(1),\n validate: z.array(z.string()).optional(), // Global default validation commands\n});\n\nexport type Config = z.infer<typeof ConfigSchema>;\nexport type AgentConfig = z.infer<typeof AgentConfigSchema>;\nexport type DockerConfig = z.infer<typeof DockerConfigSchema>;\nexport type SafetyConfig = z.infer<typeof SafetyConfigSchema>;\n\n// Per-repo config (.autoclawd.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 validate: z.array(z.string()).optional(), // Validation commands to run before PR\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(), '.autoclawd');\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: autoclawd 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, '.autoclawd.yaml');\n const ymlPath = join(workspacePath, '.autoclawd.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 validate?: 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 // Repo-local validate overrides host default; undefined means no validation\n const validate = local?.validate ?? host.validate;\n\n return { agent, docker, prompt: local?.prompt, validate };\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:autoclawd/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\n// Check if a repo URL is in the allowedRepos list\n// Matches against \"owner/name\" or full \"https://github.com/owner/name\" formats\nexport function isRepoAllowed(repoUrl: string, allowedRepos?: string[]): boolean {\n if (!allowedRepos) return true; // No allowlist = all repos allowed\n return allowedRepos.some((allowed) => {\n const normalizedAllowed = allowed.includes('/')\n ? (allowed.startsWith('https://') ? allowed : `https://github.com/${allowed}`)\n : allowed;\n return repoUrl.toLowerCase() === normalizedAllowed.toLowerCase();\n });\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';\nimport { retry, isTransientError } from './retry.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 await retry(async () => {\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 await client.updateIssue(ticketId, { stateId: inProgress.id });\n }, { label: 'Linear claim', retryIf: isTransientError });\n}\n\nexport async function completeTicket(\n client: LinearClient,\n config: Config,\n ticketId: string,\n comment: string\n): Promise<void> {\n await retry(async () => {\n await client.createComment({ issueId: ticketId, body: comment });\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 }, { label: 'Linear complete', retryIf: isTransientError });\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: `**autoclawd 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(), '.autoclawd', 'logs');\n if (!existsSync(logDir)) {\n mkdirSync(logDir, { recursive: true });\n }\n const date = new Date().toISOString().slice(0, 10);\n logFilePath = join(logDir, `autoclawd-${date}.log`);\n}\n\nexport function getLogFilePath(): string {\n const date = new Date().toISOString().slice(0, 10);\n return join(homedir(), '.autoclawd', 'logs', `autoclawd-${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 { log } from './logger.js';\n\nexport interface RetryOpts {\n /** Max number of attempts (including first try). Default: 3 */\n attempts?: number;\n /** Base delay in ms (doubled each retry). Default: 1000 */\n baseDelayMs?: number;\n /** Label for log messages, e.g. \"git clone\" */\n label: string;\n /** Optional predicate — only retry if this returns true for the error */\n retryIf?: (err: unknown) => boolean;\n}\n\n/**\n * Retry an async operation with exponential backoff.\n * Logs each retry attempt. Rethrows the last error if all attempts fail.\n */\nexport async function retry<T>(fn: () => Promise<T>, opts: RetryOpts): Promise<T> {\n const attempts = opts.attempts ?? 3;\n const baseDelay = opts.baseDelayMs ?? 1000;\n\n let lastErr: unknown;\n for (let i = 1; i <= attempts; i++) {\n try {\n return await fn();\n } catch (err) {\n lastErr = err;\n\n // Check if this error is retryable\n if (opts.retryIf && !opts.retryIf(err)) {\n throw err; // Not a transient error, bail immediately\n }\n\n if (i < attempts) {\n const delay = baseDelay * Math.pow(2, i - 1);\n const msg = err instanceof Error ? err.message.split('\\n')[0] : String(err);\n log.warn(`${opts.label} failed (attempt ${i}/${attempts}): ${msg} — retrying in ${delay}ms`);\n await sleep(delay);\n }\n }\n }\n\n throw lastErr;\n}\n\n/**\n * Retry a sync function (wraps in async).\n */\nexport function retrySync<T>(fn: () => T, opts: RetryOpts): Promise<T> {\n return retry(() => Promise.resolve(fn()), opts);\n}\n\n/** Returns true if the error looks like a transient network/API failure */\nexport function isTransientError(err: unknown): boolean {\n if (!(err instanceof Error)) return false;\n const msg = err.message.toLowerCase();\n return (\n msg.includes('econnreset') ||\n msg.includes('econnrefused') ||\n msg.includes('etimedout') ||\n msg.includes('eai_again') ||\n msg.includes('epipe') ||\n msg.includes('socket hang up') ||\n msg.includes('network') ||\n msg.includes('timeout') ||\n msg.includes('502') ||\n msg.includes('503') ||\n msg.includes('504') ||\n msg.includes('rate limit') ||\n msg.includes('429') ||\n msg.includes('500') ||\n msg.includes('internal server error')\n );\n}\n\nfunction sleep(ms: number): Promise<void> {\n return new Promise((resolve) => setTimeout(resolve, ms));\n}\n","import { Octokit } from '@octokit/rest';\nimport type { Config } from './config.js';\nimport { log } from './logger.js';\nimport { retry, isTransientError } from './retry.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 draft?: boolean;\n}): Promise<{ url: string; number: number }> {\n return retry(async () => {\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(`Updating existing PR #${pr.number}: ${pr.html_url}`);\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 draft: opts.draft ?? false,\n });\n\n log.success(`Created ${opts.draft ? 'draft ' : ''}PR #${pr.data.number}: ${pr.data.html_url}`);\n return { url: pr.data.html_url, number: pr.data.number };\n }, { label: 'GitHub PR', retryIf: isTransientError });\n}\n\n/** Mark a draft PR as ready for review */\nexport async function markPRReady(octokit: Octokit, opts: {\n repoUrl: string;\n prNumber: number;\n}): Promise<void> {\n return retry(async () => {\n const { owner, repo } = parseRepoUrl(opts.repoUrl);\n await octokit.rest.pulls.update({\n owner,\n repo,\n pull_number: opts.prNumber,\n draft: false,\n });\n log.info(`Marked PR #${opts.prNumber} as ready for review`);\n }, { label: 'GitHub PR ready', retryIf: isTransientError });\n}\n\n/** Update the body of an existing PR */\nexport async function updatePRBody(octokit: Octokit, opts: {\n repoUrl: string;\n prNumber: number;\n body: string;\n}): Promise<void> {\n return retry(async () => {\n const { owner, repo } = parseRepoUrl(opts.repoUrl);\n await octokit.rest.pulls.update({\n owner,\n repo,\n pull_number: opts.prNumber,\n body: opts.body,\n });\n }, { label: 'GitHub PR update', retryIf: isTransientError });\n}\n\n/** Fetch PR metadata */\nexport async function fetchPR(octokit: Octokit, opts: {\n repoUrl: string;\n prNumber: number;\n}): Promise<{ head: string; base: string; title: string; state: string }> {\n const { owner, repo } = parseRepoUrl(opts.repoUrl);\n const { data } = await octokit.rest.pulls.get({ owner, repo, pull_number: opts.prNumber });\n return {\n head: data.head.ref,\n base: data.base.ref,\n title: data.title,\n state: data.state,\n };\n}\n\n/** Fetch failed CI check logs for a PR's head commit */\nexport async function fetchFailedChecks(octokit: Octokit, opts: {\n repoUrl: string;\n prNumber: number;\n}): Promise<Array<{ name: string; conclusion: string; log: string }>> {\n const { owner, repo } = parseRepoUrl(opts.repoUrl);\n\n // Get the head SHA of the PR\n const { data: pr } = await octokit.rest.pulls.get({ owner, repo, pull_number: opts.prNumber });\n const headSha = pr.head.sha;\n\n // Get check runs for that commit\n const { data: checks } = await octokit.rest.checks.listForRef({\n owner, repo, ref: headSha,\n });\n\n const failed = checks.check_runs.filter(\n c => c.conclusion === 'failure' || c.conclusion === 'timed_out'\n );\n\n if (failed.length === 0) return [];\n\n const results: Array<{ name: string; conclusion: string; log: string }> = [];\n\n for (const check of failed) {\n let logText = '';\n\n // Try to get the log from GitHub Actions\n if (check.app?.slug === 'github-actions') {\n try {\n // Find the matching workflow run\n const { data: runs } = await octokit.rest.actions.listWorkflowRunsForRepo({\n owner, repo, head_sha: headSha, per_page: 10,\n });\n\n for (const run of runs.workflow_runs) {\n if (run.conclusion !== 'failure') continue;\n const { data: jobs } = await octokit.rest.actions.listJobsForWorkflowRun({\n owner, repo, run_id: run.id,\n });\n\n for (const job of jobs.jobs) {\n if (job.conclusion !== 'failure') continue;\n try {\n const { data: log } = await octokit.rest.actions.downloadJobLogsForWorkflowRun({\n owner, repo, job_id: job.id,\n });\n // Logs come back as a string, truncate to last 3000 chars to keep prompt manageable\n const logStr = typeof log === 'string' ? log : String(log);\n logText += `\\n--- Job: ${job.name} ---\\n` + logStr.slice(-3000);\n } catch {\n // Log download can fail for older runs\n }\n }\n }\n } catch {\n // Fall back to check run output\n }\n }\n\n // Fall back to check run annotations/output\n if (!logText && check.output?.text) {\n logText = check.output.text.slice(-3000);\n }\n if (!logText && check.output?.summary) {\n logText = check.output.summary.slice(-3000);\n }\n\n results.push({\n name: check.name,\n conclusion: check.conclusion ?? 'failure',\n log: logText || '(no log available)',\n });\n }\n\n return results;\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';\nimport {\n getDb,\n closeDb,\n insertRun,\n finishRun,\n isTicketActive,\n isTicketProcessed,\n getActiveRuns,\n enqueue,\n dequeue,\n getQueueLength,\n getQueuedTickets,\n removeFromQueue,\n} from './db.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 server: ReturnType<typeof createServer> | undefined;\n // Track in-memory active set for concurrency counting (fast path)\n private activeInMemory = new Set<string>();\n\n constructor(\n private config: Config,\n private linearClient: LinearClient,\n private octokit: Octokit,\n ) {}\n\n start(): Promise<void> {\n // Initialize the database on startup\n getDb();\n\n // Resume any queued tickets from a previous run\n this.resumeQueue();\n\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({\n status: 'ok',\n active: this.activeInMemory.size,\n queued: getQueueLength(),\n capacity: this.config.maxConcurrent,\n }));\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 closeDb();\n log.info('Webhook server stopped');\n }\n\n private resumeQueue(): void {\n // Mark any previously \"running\" tickets as failed (unclean shutdown)\n const staleRuns = getActiveRuns();\n for (const run of staleRuns) {\n log.warn(`${run.ticket_id}: was running at shutdown, marking as failed`);\n finishRun(run.ticket_id, 'failed', 'Unclean shutdown — process restarted');\n }\n\n // Re-dispatch queued tickets\n const queued = getQueuedTickets();\n if (queued.length > 0) {\n log.info(`Resuming ${queued.length} queued ticket(s) from database`);\n for (const ticket of queued) {\n removeFromQueue(ticket.id);\n if (this.activeInMemory.size >= this.config.maxConcurrent) {\n // Re-enqueue if still at capacity\n enqueue(ticket);\n break;\n }\n this.dispatch(ticket);\n }\n }\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 this ticket? (in-memory fast check + DB check)\n if (this.activeInMemory.has(data.id) || isTicketActive(data.id)) {\n log.debug(`${data.identifier}: already active, ignoring`);\n return;\n }\n\n // Already processed this ticket? (durable across restarts)\n if (isTicketProcessed(data.id)) {\n log.debug(`${data.identifier}: already processed, ignoring`);\n return;\n }\n\n // Check concurrency — queue if at capacity instead of dropping\n if (this.activeInMemory.size >= this.config.maxConcurrent) {\n log.info(`${data.identifier}: at capacity (${this.activeInMemory.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 enqueue(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.activeInMemory.add(ticket.id);\n insertRun(ticket.id, 'running');\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 }).then(\n () => {\n finishRun(ticket.id, 'success');\n },\n (err: Error) => {\n finishRun(ticket.id, 'failed', err.message);\n },\n ).finally(() => {\n this.activeInMemory.delete(ticket.id);\n this.drainQueue();\n });\n }\n\n private drainQueue(): void {\n while (this.activeInMemory.size < this.config.maxConcurrent) {\n const next = dequeue();\n if (!next) break;\n // Skip if this ticket is already active (duplicate webhook)\n if (this.activeInMemory.has(next.id)) continue;\n log.ticket(next.identifier, `Dequeued (${getQueueLength()} remaining)`);\n this.dispatch(next);\n }\n }\n}\n","import Docker from 'dockerode';\nimport { PassThrough } from 'node:stream';\nimport { homedir } from 'node:os';\nimport { join } from 'node:path';\nimport { existsSync, readFileSync } from 'node:fs';\nimport type { DockerConfig } from './config.js';\nimport { log } from './logger.js';\nimport { retry, isTransientError } from './retry.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\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 // Pull the image (with retry for transient network errors)\n log.info(`Pulling image ${image} (this may take a moment)...`);\n await retry(() => 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 }), { label: 'docker pull', retryIf: isTransientError });\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 autoclawd-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: `autoclawd-${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 + 'autoclawd 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 autoclawd 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 // The install script requires bash; installs to ~/.local/bin/claude\n // We symlink to /usr/local/bin so it's on PATH for all users (including autoclawd)\n // Install script puts binary at ~/.local/bin/claude (symlink chain into ~/.local/share/).\n // The autoclawd user can't traverse /root/, so we copy the resolved binary to /usr/local/bin.\n const standaloneResult = await exec(wrapped, [\n 'bash', '-c',\n 'curl -fsSL https://claude.ai/install.sh | bash'\n + ' && cp -L /root/.local/bin/claude /usr/local/bin/claude'\n + ' && chmod 755 /usr/local/bin/claude',\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 bash and curl are 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 autoclawd >/dev/null 2>&1 ) || '\n + '( adduser --disabled-password --gecos \"\" --uid 1001 --home /home/autoclawd autoclawd 2>/dev/null ) || '\n + '( adduser -D -u 1001 -h /home/autoclawd autoclawd 2>/dev/null ) || ' // Alpine adduser\n + '( useradd -m -u 1001 -d /home/autoclawd autoclawd 2>/dev/null ) || ' // useradd fallback\n + '( echo \"autoclawd:x:1001:1001::/home/autoclawd:/bin/sh\" >> /etc/passwd && mkdir -p /home/autoclawd ); '\n + 'mkdir -p /home/autoclawd && chown -R autoclawd /home/autoclawd /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 .autoclawd.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/autoclawd/.claude && chown autoclawd /home/autoclawd/.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/autoclawd/.claude/.credentials.json && chown autoclawd /home/autoclawd/.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/autoclawd/.claude/settings.json && chown autoclawd /home/autoclawd/.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[autoclawd] 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('/autoclawd-'))\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 /\\[autoclawd: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/autoclawd && echo '${promptB64}' | base64 -d > /tmp/autoclawd/prompt.md && chmod 644 /tmp/autoclawd/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/autoclawd/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: 'autoclawd',\n env: ['HOME=/home/autoclawd', '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: 'autoclawd' };\n await exec(container, ['git', 'config', 'user.name', 'autoclawd'], u);\n await exec(container, ['git', 'config', 'user.email', 'autoclawd@autoclawd.dev'], 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 branchPrefix?: string;\n maxFileChanges?: number;\n}): Promise<{ pushed: boolean; commitCount: number }> {\n const { branchName, ticketId, title, githubToken, branchPrefix, maxFileChanges } = opts;\n\n const u = { user: 'autoclawd' };\n\n // Safety: verify branch starts with configured prefix\n if (branchPrefix && !branchName.startsWith(branchPrefix)) {\n log.error(`Safety: branch \"${branchName}\" does not start with required prefix \"${branchPrefix}\"`);\n throw new Error(`Branch \"${branchName}\" does not start with required prefix \"${branchPrefix}\"`);\n }\n log.info(`Safety: branch prefix check passed for \"${branchName}\"`);\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 // Safety: count changed files and enforce limit\n if (maxFileChanges !== undefined) {\n const diffResult = await exec(container, [\n 'git', 'diff', '--name-only', 'HEAD', '--not', '--remotes',\n ], u);\n const changedFiles = diffResult.stdout.trim().split('\\n').filter(Boolean).length;\n if (changedFiles > maxFileChanges) {\n log.error(`Safety: ${changedFiles} files changed, exceeds maxFileChanges limit of ${maxFileChanges}`);\n throw new Error(`Too many file changes: ${changedFiles} files changed (limit: ${maxFileChanges}). Review changes manually.`);\n }\n log.info(`Safety: file change count (${changedFiles}) within limit (${maxFileChanges})`);\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, isRepoAllowed } from './config.js';\nimport type { Ticket } from './linear.js';\nimport { claimTicket, completeTicket, failTicket, addBranchLabel } from './linear.js';\nimport { createContainer, destroyContainer, exec } from './docker.js';\nimport type { Container } from './docker.js';\nimport { runAgentLoop } from './agent.js';\nimport { setupRepo, commitAndPush } from './git.js';\nimport { openPR, fetchPR, fetchFailedChecks, markPRReady, updatePRBody } 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';\nimport { retrySync, isTransientError } from './retry.js';\nimport { getRunByTicketId, insertRun, updateRun, finishRun } from './db.js';\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 [autoclawd: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 .autoclawd.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(), 'autoclawd-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 .autoclawd.yaml before Docker\n// Retries on transient network errors (ECONNRESET, timeout, etc.)\nasync function cloneToTemp(repoUrl: string, baseBranch: string, githubToken: string): Promise<string> {\n assertSafeRef(baseBranch, 'base branch');\n\n return retrySync(() => {\n const workDir = mkdtempSync(join(tmpdir(), 'autoclawd-'));\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 } catch (err) {\n rmSync(workDir, { recursive: true, force: true });\n throw err;\n } finally {\n rmSync(askpass.dir, { recursive: true, force: true });\n }\n return workDir;\n }, { label: 'git clone', retryIf: isTransientError });\n}\n\nexport interface ValidationFailure {\n command: string;\n exitCode: number;\n output: string;\n}\n\nexport async function runValidation(\n container: Container,\n commands: string[],\n ticketId: string,\n): Promise<ValidationFailure[]> {\n const failures: ValidationFailure[] = [];\n\n for (const cmd of commands) {\n log.ticket(ticketId, `Validating: ${cmd}`);\n const result = await exec(container, ['sh', '-c', cmd], {\n user: 'autoclawd',\n env: ['HOME=/home/autoclawd'],\n timeout: 5 * 60 * 1000, // 5 min per validation command\n });\n\n if (result.exitCode === 0) {\n log.ticket(ticketId, ` PASS: ${cmd}`);\n } else {\n log.ticket(ticketId, ` FAIL: ${cmd} (exit ${result.exitCode})`);\n const output = (result.stdout + result.stderr).trim();\n failures.push({\n command: cmd,\n exitCode: result.exitCode,\n output: output.slice(-3000), // Cap output to avoid huge prompts\n });\n }\n }\n\n return failures;\n}\n\nexport function buildValidationFixPrompt(failures: ValidationFailure[]): string {\n const parts: string[] = [];\n\n parts.push('## Validation Failed');\n parts.push('');\n parts.push('The following validation commands failed after your changes. Please fix the issues and commit your fixes.');\n parts.push('');\n\n for (const f of failures) {\n parts.push(`### Failed: \\`${f.command}\\` (exit code ${f.exitCode})`);\n parts.push('```');\n parts.push(f.output);\n parts.push('```');\n parts.push('');\n }\n\n parts.push('## Instructions');\n parts.push('- Read the error output carefully and fix the root cause');\n parts.push('- Run the failing command(s) to verify your fix');\n parts.push('- Commit your fixes with: git add -A && git commit -m \"fix: address validation failures\"');\n parts.push('- When done, include [autoclawd:done] in your output');\n\n return parts.join('\\n');\n}\n\nexport async function executeTicket(opts: {\n ticket: Ticket;\n config: Config;\n linearClient: LinearClient;\n octokit: Octokit;\n force?: boolean;\n}): Promise<WorkerResult> {\n const { ticket, config, linearClient, octokit, force } = opts;\n const startedAt = new Date();\n\n function recordRun(result: WorkerResult, branch?: string): void {\n const finishedAt = new Date();\n const durationSecs = Math.round((finishedAt.getTime() - startedAt.getTime()) / 1000);\n try {\n // Ensure the run row exists (upsert)\n insertRun(result.ticketId, result.success ? 'success' : 'failed');\n updateRun(result.ticketId, {\n status: result.success ? 'success' : 'failed',\n branch: branch ?? null,\n pr_url: result.prUrl ?? null,\n error: result.error ?? null,\n iterations: result.iterations,\n model: config.agent.model,\n image: config.docker.image,\n finished_at: finishedAt.toISOString(),\n duration_secs: durationSecs,\n });\n } catch {\n // Best effort — don't fail the ticket over history logging\n }\n }\n\n // Check if ticket was already completed (idempotency guard)\n if (!force) {\n const existingRun = getRunByTicketId(ticket.identifier);\n if (existingRun?.status === 'success') {\n log.info(`${ticket.identifier}: already completed, use --force to re-run`);\n return {\n ticketId: ticket.identifier,\n success: true,\n prUrl: existingRun.pr_url ?? undefined,\n iterations: existingRun.iterations,\n };\n }\n }\n\n // Record the run at the START to prevent crash-and-restart from re-dispatching\n insertRun(ticket.identifier, 'running');\n\n if (!ticket.repoUrl) {\n const result: WorkerResult = {\n ticketId: ticket.identifier,\n success: false,\n error: 'No repo:owner/name label on ticket',\n iterations: 0,\n };\n recordRun(result);\n return result;\n }\n\n // Validate repo URL before attempting clone\n if (!ticket.repoUrl.startsWith('https://')) {\n const result: WorkerResult = {\n ticketId: ticket.identifier,\n success: false,\n error: `Invalid repo URL: \"${ticket.repoUrl}\". Only HTTPS URLs are supported.`,\n iterations: 0,\n };\n recordRun(result);\n return result;\n }\n\n // Safety: check repo against allowlist\n if (!isRepoAllowed(ticket.repoUrl, config.safety.allowedRepos)) {\n log.warn(`Safety: repo ${ticket.repoUrl} not in allowedRepos list`);\n return {\n ticketId: ticket.identifier,\n success: false,\n error: `Repo not allowed: \"${ticket.repoUrl}\". Check safety.allowedRepos in config.`,\n iterations: 0,\n };\n }\n log.info(`Safety: repo ${ticket.repoUrl} allowed`);\n\n const branchName = `autoclawd/${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 = await cloneToTemp(ticket.repoUrl, detectedBase, config.github.token);\n log.ticket(ticket.identifier, 'Cloned repo');\n\n // 3. Load .autoclawd.yaml from repo, merge with host config\n const repoLocal = loadRepoLocalConfig(workDir);\n // Priority: ticket \"base:\" label > .autoclawd.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, validate } = mergeConfigs(config, repoLocal);\n\n if (repoLocal) {\n log.ticket(ticket.identifier, 'Loaded .autoclawd.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 = await 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 let agentResult = await runAgentLoop({\n container,\n agentConfig: agent,\n prompt: agentPrompt,\n ticketId: ticket.identifier,\n });\n\n // 6. Push immediately (agent commits incrementally, we just push)\n // Push before validation so code is preserved even if validation hangs\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 branchPrefix: config.safety.branchPrefix,\n maxFileChanges: config.safety.maxFileChanges,\n });\n\n if (!gitResult.pushed) {\n await failTicket(linearClient, ticket.id, 'No changes produced');\n finishRun(ticket.identifier, 'failed', 'No changes produced');\n const result: WorkerResult = {\n ticketId: ticket.identifier,\n success: false,\n error: 'No changes produced',\n iterations: agentResult.iterations,\n };\n recordRun(result, branchName);\n return result;\n }\n\n // 7. Open draft PR so code is visible even if validation fails or hangs\n const buildPRBody = (opts?: { validationWarnings?: ValidationFailure[]; commitCount: number }): string => {\n const prBody: string[] = [\n `Resolves [${ticket.identifier}](${ticket.url})`,\n '',\n ];\n\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 if (opts?.validationWarnings && opts.validationWarnings.length > 0) {\n prBody.push('## :warning: Validation Failures', '');\n prBody.push('The following validation commands were still failing after all iterations:', '');\n for (const f of opts.validationWarnings) {\n prBody.push(`### \\`${f.command}\\` (exit code ${f.exitCode})`, '');\n prBody.push('<details><summary>Output</summary>', '', '```', f.output, '```', '', '</details>', '');\n }\n }\n\n prBody.push(\n '## Details',\n '',\n `| Metric | Value |`,\n `| --- | --- |`,\n `| Iterations | ${agentResult.iterations} |`,\n `| Commits | ${opts?.commitCount ?? gitResult.commitCount} |`,\n `| Model | ${agent.model} |`,\n '',\n '---',\n '*Generated by [autoclawd](https://github.com/rahul-fnu/autoclawd)*',\n );\n\n return prBody.join('\\n');\n };\n\n const hasValidation = validate && validate.length > 0;\n const pr = await openPR(octokit, {\n repoUrl: ticket.repoUrl,\n branch: branchName,\n baseBranch: actualBase,\n title: `${ticket.identifier}: ${ticket.title}`,\n body: buildPRBody({ commitCount: gitResult.commitCount }),\n draft: hasValidation ? true : false,\n });\n\n // 8. Run validation hooks (if configured) after draft PR is created\n if (hasValidation) {\n let iterationsUsed = agentResult.iterations;\n let lastFailures: ValidationFailure[] = [];\n let totalCommitCount = gitResult.commitCount;\n\n // Run validation, feed failures back to agent, repeat until pass or maxIterations\n while (iterationsUsed < agent.maxIterations) {\n const failures = await runValidation(container, validate, ticket.identifier);\n if (failures.length === 0) {\n log.ticket(ticket.identifier, 'All validations passed');\n lastFailures = [];\n break;\n }\n\n lastFailures = failures;\n log.ticket(ticket.identifier, `${failures.length} validation(s) failed, feeding back to Claude`);\n\n // Feed failure output to Claude for another iteration\n const fixPrompt = buildValidationFixPrompt(failures);\n const fixResult = await runAgentLoop({\n container,\n agentConfig: { ...agent, maxIterations: 1 },\n prompt: fixPrompt,\n ticketId: ticket.identifier,\n });\n iterationsUsed += fixResult.iterations;\n agentResult = {\n iterations: iterationsUsed,\n success: fixResult.success,\n lastOutput: fixResult.lastOutput,\n };\n\n // Push after each fix so the draft PR stays updated\n const fixGitResult = await commitAndPush(container, {\n branchName,\n ticketId: ticket.identifier,\n title: ticket.title,\n repoUrl: ticket.repoUrl,\n githubToken: config.github.token,\n branchPrefix: config.safety.branchPrefix,\n maxFileChanges: config.safety.maxFileChanges,\n });\n totalCommitCount += fixGitResult.commitCount;\n }\n\n if (lastFailures.length > 0) {\n // Validation still failing — leave PR as draft with warnings in body\n log.ticket(ticket.identifier, 'Validation still failing after max iterations — leaving PR as draft with warnings');\n await updatePRBody(octokit, {\n repoUrl: ticket.repoUrl,\n prNumber: pr.number,\n body: buildPRBody({ validationWarnings: lastFailures, commitCount: totalCommitCount }),\n });\n } else {\n // All validations passed — mark PR as ready for review\n await updatePRBody(octokit, {\n repoUrl: ticket.repoUrl,\n prNumber: pr.number,\n body: buildPRBody({ commitCount: totalCommitCount }),\n });\n await markPRReady(octokit, {\n repoUrl: ticket.repoUrl,\n prNumber: pr.number,\n });\n log.ticket(ticket.identifier, 'PR marked as ready for review');\n }\n }\n\n // 9. Update Linear ticket\n await completeTicket(linearClient, config, ticket.id, `PR opened: ${pr.url}`);\n\n // 10. Add branch label to ticket so child tickets can stack on it\n // e.g. child ticket adds label \"base:autoclawd/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 const result: WorkerResult = {\n ticketId: ticket.identifier,\n success: true,\n prUrl: pr.url,\n iterations: agentResult.iterations,\n };\n finishRun(ticket.identifier, 'success');\n updateRun(ticket.identifier, { pr_url: pr.url, branch: branchName, iterations: agentResult.iterations });\n recordRun(result, branchName);\n return result;\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 finishRun(ticket.identifier, 'failed', msg);\n const result: WorkerResult = {\n ticketId: ticket.identifier,\n success: false,\n error: msg,\n iterations: 0,\n };\n recordRun(result, branchName);\n return result;\n } finally {\n // 11. 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\n// --- PR fix: fetch failed CI checks, run Claude to fix them ---\n\nfunction buildFixPrompt(pr: { title: string; head: string }, failures: Array<{ name: string; log: string }>): string {\n const parts: string[] = [];\n\n parts.push(`## Task: Fix CI failures on PR \"${pr.title}\"`);\n parts.push('');\n parts.push(`Branch: ${pr.head}`);\n parts.push('');\n parts.push('The following CI checks are failing. Read the logs carefully, identify the root cause, fix the code, and make sure the fix is correct.');\n parts.push('');\n\n for (const f of failures) {\n parts.push(`### Failed check: ${f.name}`);\n parts.push('```');\n parts.push(f.log);\n parts.push('```');\n parts.push('');\n }\n\n parts.push('## Instructions');\n parts.push('- Start by reading CLAUDE.md if it exists');\n parts.push('- Read the failing test/lint/build output carefully before making changes');\n parts.push('- Fix the root cause, not just the symptoms');\n parts.push('- Run the failing command locally to verify your fix');\n parts.push('- Tests MUST import from actual source modules — never duplicate source code in tests');\n parts.push('- After fixing, run: git add -A && git commit -m \"fix: address CI failures\"');\n parts.push('- IMPORTANT: You MUST commit your changes with git before finishing');\n parts.push('- When all fixes are committed, include [autoclawd:done] in your final output');\n\n return parts.join('\\n');\n}\n\nexport interface FixResult {\n success: boolean;\n prUrl: string;\n error?: string;\n iterations: number;\n failedChecks: number;\n}\n\nexport async function fixPR(opts: {\n repoUrl: string;\n prNumber: number;\n config: Config;\n octokit: Octokit;\n}): Promise<FixResult> {\n const { repoUrl, prNumber, config, octokit } = opts;\n const prUrl = `${repoUrl}/pull/${prNumber}`;\n\n let workDir: string | undefined;\n let container: Container | undefined;\n\n try {\n // 1. Fetch PR metadata and failed checks\n const pr = await fetchPR(octokit, { repoUrl, prNumber });\n log.info(`PR #${prNumber}: \"${pr.title}\" (${pr.head} → ${pr.base})`);\n\n if (pr.state !== 'open') {\n return { success: false, prUrl, error: 'PR is not open', iterations: 0, failedChecks: 0 };\n }\n\n const failures = await fetchFailedChecks(octokit, { repoUrl, prNumber });\n if (failures.length === 0) {\n log.success('No failed CI checks — nothing to fix');\n return { success: true, prUrl, iterations: 0, failedChecks: 0 };\n }\n\n log.info(`Found ${failures.length} failed check(s): ${failures.map(f => f.name).join(', ')}`);\n\n // 2. Clone the PR branch\n workDir = await cloneToTemp(repoUrl, pr.head, config.github.token);\n log.info('Cloned PR branch');\n\n // 3. Load per-repo config\n const repoLocal = loadRepoLocalConfig(workDir);\n const { agent, docker } = mergeConfigs(config, repoLocal);\n\n // 4. Spin up container\n const containerName = `fix-pr-${prNumber}-${Date.now()}`.replace(/[^a-z0-9_.-]/g, '-');\n container = await createContainer({\n dockerConfig: docker,\n workspacePath: workDir,\n name: containerName,\n });\n\n await setupRepo(container, { branchName: pr.head });\n\n // 5. Run Claude with CI failure context\n const prompt = buildFixPrompt(pr, failures);\n const agentResult = await runAgentLoop({\n container,\n agentConfig: agent,\n prompt,\n ticketId: `PR-${prNumber}`,\n });\n\n // 6. Push fixes\n const gitResult = await commitAndPush(container, {\n branchName: pr.head,\n ticketId: `PR-${prNumber}`,\n title: 'Fix CI failures',\n repoUrl,\n githubToken: config.github.token,\n branchPrefix: config.safety.branchPrefix,\n maxFileChanges: config.safety.maxFileChanges,\n });\n\n if (!gitResult.pushed) {\n return { success: false, prUrl, error: 'No fix produced', iterations: agentResult.iterations, failedChecks: failures.length };\n }\n\n log.success(`Pushed ${gitResult.commitCount} fix commit(s) to ${pr.head}`);\n return { success: true, prUrl, iterations: agentResult.iterations, failedChecks: failures.length };\n } catch (err) {\n const msg = err instanceof Error ? err.message : String(err);\n log.error(`Fix failed: ${msg}`);\n return { success: false, prUrl, error: msg, iterations: 0, failedChecks: 0 };\n } finally {\n if (container) await destroyContainer(container);\n if (workDir) {\n try { rmSync(workDir, { recursive: true, force: true }); } catch { /* best effort */ }\n }\n }\n}\n","import Database from 'better-sqlite3';\nimport { join } from 'node:path';\nimport { mkdirSync, existsSync } from 'node:fs';\nimport { CONFIG_DIR } from './config.js';\nimport type { Ticket } from './linear.js';\n\nconst DB_PATH = join(CONFIG_DIR, 'autoclawd.db');\n\nexport type RunStatus = 'queued' | 'running' | 'success' | 'failed';\n\nexport interface Run {\n id: string;\n ticket_id: string;\n status: RunStatus;\n branch: string | null;\n pr_url: string | null;\n started_at: string;\n finished_at: string | null;\n error: string | null;\n iterations: number;\n model: string | null;\n image: string | null;\n duration_secs: number | null;\n}\n\nexport interface QueueEntry {\n id: number;\n ticket_id: string;\n payload: string; // JSON-encoded Ticket\n created_at: string;\n}\n\nlet _db: Database.Database | undefined;\n\nexport function getDb(): Database.Database {\n if (_db) return _db;\n if (!existsSync(CONFIG_DIR)) {\n mkdirSync(CONFIG_DIR, { recursive: true });\n }\n _db = new Database(DB_PATH);\n _db.pragma('journal_mode = WAL');\n _db.exec(`\n CREATE TABLE IF NOT EXISTS runs (\n id TEXT PRIMARY KEY,\n ticket_id TEXT NOT NULL,\n status TEXT NOT NULL DEFAULT 'queued',\n branch TEXT,\n pr_url TEXT,\n started_at TEXT NOT NULL DEFAULT (datetime('now')),\n finished_at TEXT,\n error TEXT,\n iterations INTEGER NOT NULL DEFAULT 0,\n model TEXT,\n image TEXT,\n duration_secs INTEGER\n );\n CREATE TABLE IF NOT EXISTS queue (\n id INTEGER PRIMARY KEY AUTOINCREMENT,\n ticket_id TEXT NOT NULL,\n payload TEXT NOT NULL,\n created_at TEXT NOT NULL DEFAULT (datetime('now'))\n );\n `);\n // Migrate: add columns if missing (for databases created before this version)\n const cols = _db.prepare(\"PRAGMA table_info(runs)\").all() as Array<{ name: string }>;\n const colNames = new Set(cols.map((c) => c.name));\n if (!colNames.has('model')) _db.exec('ALTER TABLE runs ADD COLUMN model TEXT');\n if (!colNames.has('image')) _db.exec('ALTER TABLE runs ADD COLUMN image TEXT');\n if (!colNames.has('duration_secs')) _db.exec('ALTER TABLE runs ADD COLUMN duration_secs INTEGER');\n\n return _db;\n}\n\nexport function closeDb(): void {\n _db?.close();\n _db = undefined;\n}\n\n// --- Runs helpers ---\n\nexport function insertRun(ticketId: string, status: RunStatus = 'running'): void {\n const db = getDb();\n db.prepare(\n 'INSERT OR REPLACE INTO runs (id, ticket_id, status, started_at) VALUES (?, ?, ?, datetime(\\'now\\'))'\n ).run(ticketId, ticketId, status);\n}\n\nexport function updateRun(\n ticketId: string,\n update: Partial<Pick<Run, 'status' | 'branch' | 'pr_url' | 'error' | 'iterations' | 'finished_at' | 'model' | 'image' | 'duration_secs'>>,\n): void {\n const db = getDb();\n const sets: string[] = [];\n const values: unknown[] = [];\n for (const [key, val] of Object.entries(update)) {\n sets.push(`${key} = ?`);\n values.push(val);\n }\n if (sets.length === 0) return;\n values.push(ticketId);\n db.prepare(`UPDATE runs SET ${sets.join(', ')} WHERE id = ?`).run(...values);\n}\n\nexport function finishRun(ticketId: string, status: 'success' | 'failed', error?: string): void {\n updateRun(ticketId, { status, finished_at: new Date().toISOString(), error: error ?? null });\n}\n\nexport function getRunByTicketId(ticketId: string): Run | undefined {\n const db = getDb();\n return db.prepare('SELECT * FROM runs WHERE ticket_id = ?').get(ticketId) as Run | undefined;\n}\n\nexport function getActiveRuns(): Run[] {\n const db = getDb();\n return db.prepare(\"SELECT * FROM runs WHERE status = 'running'\").all() as Run[];\n}\n\nexport function isTicketProcessed(ticketId: string): boolean {\n const db = getDb();\n const row = db.prepare(\n \"SELECT 1 FROM runs WHERE ticket_id = ? AND status IN ('success', 'failed')\"\n ).get(ticketId);\n return !!row;\n}\n\nexport function isTicketActive(ticketId: string): boolean {\n const db = getDb();\n const row = db.prepare(\n \"SELECT 1 FROM runs WHERE ticket_id = ? AND status = 'running'\"\n ).get(ticketId);\n return !!row;\n}\n\n// --- Queue helpers ---\n\nexport function enqueue(ticket: Ticket): void {\n const db = getDb();\n db.prepare('INSERT INTO queue (ticket_id, payload) VALUES (?, ?)').run(\n ticket.id,\n JSON.stringify(ticket),\n );\n}\n\nexport function dequeue(): Ticket | undefined {\n const db = getDb();\n const row = db.prepare('SELECT * FROM queue ORDER BY id ASC LIMIT 1').get() as QueueEntry | undefined;\n if (!row) return undefined;\n db.prepare('DELETE FROM queue WHERE id = ?').run(row.id);\n return JSON.parse(row.payload) as Ticket;\n}\n\nexport function removeFromQueue(ticketId: string): void {\n const db = getDb();\n db.prepare('DELETE FROM queue WHERE ticket_id = ?').run(ticketId);\n}\n\nexport function getQueueLength(): number {\n const db = getDb();\n const row = db.prepare('SELECT COUNT(*) as count FROM queue').get() as { count: number };\n return row.count;\n}\n\nexport function getQueuedTickets(): Ticket[] {\n const db = getDb();\n const rows = db.prepare('SELECT * FROM queue ORDER BY id ASC').all() as QueueEntry[];\n return rows.map((r) => JSON.parse(r.payload) as Ticket);\n}\n\n// --- History queries ---\n\nexport function queryRuns(opts?: { limit?: number; failedOnly?: boolean }): Run[] {\n const db = getDb();\n const limit = opts?.limit ?? 20;\n const failedOnly = opts?.failedOnly ?? false;\n\n const where = failedOnly ? \"WHERE status = 'failed'\" : '';\n return db.prepare(\n `SELECT * FROM runs ${where} ORDER BY started_at DESC LIMIT ?`\n ).all(limit) as Run[];\n}\n\nexport function countRuns(): number {\n const db = getDb();\n const row = db.prepare('SELECT COUNT(*) as count FROM runs').get() as { count: number };\n return row.count;\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 type { Config } from './config.js';\nimport type { Ticket } from './linear.js';\nimport { pollTickets } from './linear.js';\nimport { executeTicket } from './worker.js';\nimport type { LinearClient } from '@linear/sdk';\nimport type { Octokit } from '@octokit/rest';\nimport { log } from './logger.js';\nimport {\n getDb,\n closeDb,\n insertRun,\n finishRun,\n isTicketActive,\n isTicketProcessed,\n getActiveRuns,\n enqueue,\n dequeue,\n getQueueLength,\n getQueuedTickets,\n removeFromQueue,\n} from './db.js';\n\nexport interface WatchOptions {\n config: Config;\n linearClient: LinearClient;\n octokit: Octokit;\n intervalSeconds: number;\n once: boolean;\n}\n\nexport class Watcher {\n private activeInMemory = new Set<string>();\n private timer: ReturnType<typeof setInterval> | undefined;\n private stopped = false;\n\n constructor(\n private config: Config,\n private linearClient: LinearClient,\n private octokit: Octokit,\n ) {}\n\n async start(intervalSeconds: number, once: boolean): Promise<void> {\n getDb();\n this.resumeQueue();\n\n // Run first poll immediately\n await this.poll();\n\n if (once) {\n // Wait for all active tickets to finish before exiting\n await this.waitForActive();\n closeDb();\n return;\n }\n\n this.timer = setInterval(() => {\n if (!this.stopped) {\n void this.poll();\n }\n }, intervalSeconds * 1000);\n\n log.info(`Polling every ${intervalSeconds}s (Ctrl+C to stop)`);\n }\n\n stop(): void {\n this.stopped = true;\n if (this.timer) {\n clearInterval(this.timer);\n this.timer = undefined;\n }\n closeDb();\n log.info('Watcher stopped');\n }\n\n private resumeQueue(): void {\n const staleRuns = getActiveRuns();\n for (const run of staleRuns) {\n log.warn(`${run.ticket_id}: was running at shutdown, marking as failed`);\n finishRun(run.ticket_id, 'failed', 'Unclean shutdown — process restarted');\n }\n\n const queued = getQueuedTickets();\n if (queued.length > 0) {\n log.info(`Resuming ${queued.length} queued ticket(s) from database`);\n for (const ticket of queued) {\n removeFromQueue(ticket.id);\n if (this.activeInMemory.size >= this.config.maxConcurrent) {\n enqueue(ticket);\n break;\n }\n this.dispatch(ticket);\n }\n }\n }\n\n private async poll(): Promise<void> {\n try {\n const tickets = await pollTickets(this.linearClient, this.config);\n const newTickets = tickets.filter((t) => this.isNewTicket(t));\n\n log.info(`Poll: ${tickets.length} ticket(s) found, ${newTickets.length} new`);\n\n for (const ticket of newTickets) {\n if (!ticket.repoUrl) {\n log.warn(`${ticket.identifier}: no repo: label, skipping`);\n continue;\n }\n\n if (this.activeInMemory.size >= this.config.maxConcurrent) {\n log.info(`${ticket.identifier}: at capacity (${this.activeInMemory.size}/${this.config.maxConcurrent}), queued`);\n enqueue(ticket);\n continue;\n }\n\n this.dispatch(ticket);\n }\n } catch (err) {\n log.error(`Poll failed: ${err instanceof Error ? err.message : err}`);\n }\n }\n\n private isNewTicket(ticket: Ticket): boolean {\n if (this.activeInMemory.has(ticket.id)) return false;\n if (isTicketActive(ticket.id)) return false;\n if (isTicketProcessed(ticket.id)) return false;\n return true;\n }\n\n private dispatch(ticket: Ticket): void {\n this.activeInMemory.add(ticket.id);\n insertRun(ticket.id, 'running');\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 }).then(\n () => {\n finishRun(ticket.id, 'success');\n },\n (err: Error) => {\n finishRun(ticket.id, 'failed', err.message);\n },\n ).finally(() => {\n this.activeInMemory.delete(ticket.id);\n this.drainQueue();\n });\n }\n\n private drainQueue(): void {\n while (this.activeInMemory.size < this.config.maxConcurrent) {\n const next = dequeue();\n if (!next) break;\n if (this.activeInMemory.has(next.id)) continue;\n log.ticket(next.identifier, `Dequeued (${getQueueLength()} remaining)`);\n this.dispatch(next);\n }\n }\n\n private waitForActive(): Promise<void> {\n if (this.activeInMemory.size === 0) return Promise.resolve();\n return new Promise((resolve) => {\n const check = setInterval(() => {\n if (this.activeInMemory.size === 0) {\n clearInterval(check);\n resolve();\n }\n }, 1000);\n });\n }\n}\n","import { readFileSync, existsSync } from 'node:fs';\nimport { join } from 'node:path';\nimport { homedir } from 'node:os';\nimport chalk from 'chalk';\nimport { getDb, queryRuns, countRuns } from './db.js';\nimport type { Run } from './db.js';\n\nexport interface HistoryRecord {\n ticketId: string;\n status: 'success' | 'failure';\n branch: string;\n prUrl?: string;\n error?: string;\n iterations: number;\n model: string;\n image: string;\n startedAt: string;\n finishedAt: string;\n durationSecs: number;\n}\n\nconst HISTORY_DIR = join(homedir(), '.autoclawd');\nconst HISTORY_FILE = join(HISTORY_DIR, 'history.jsonl');\n\n/** Convert a SQLite Run row to a HistoryRecord for display. */\nfunction runToRecord(run: Run): HistoryRecord {\n return {\n ticketId: run.ticket_id,\n status: run.status === 'failed' ? 'failure' : 'success',\n branch: run.branch ?? '',\n prUrl: run.pr_url ?? undefined,\n error: run.error ?? undefined,\n iterations: run.iterations,\n model: run.model ?? '',\n image: run.image ?? '',\n startedAt: run.started_at,\n finishedAt: run.finished_at ?? '',\n durationSecs: run.duration_secs ?? 0,\n };\n}\n\n/** Read history from SQLite runs table. */\nexport function readHistory(opts?: {\n limit?: number;\n failedOnly?: boolean;\n}): HistoryRecord[] {\n const runs = queryRuns(opts);\n return runs.map(runToRecord);\n}\n\n/**\n * Migrate legacy history.jsonl records into SQLite.\n * Called once on first startup — uses INSERT OR IGNORE so it's idempotent.\n */\nexport function migrateJsonlToSqlite(): number {\n if (!existsSync(HISTORY_FILE)) return 0;\n\n // Only migrate if the runs table is empty\n if (countRuns() > 0) return 0;\n\n const lines = readFileSync(HISTORY_FILE, 'utf-8')\n .split('\\n')\n .filter(Boolean);\n\n if (lines.length === 0) return 0;\n\n const db = getDb();\n const insert = db.prepare(\n `INSERT OR IGNORE INTO runs (id, ticket_id, status, branch, pr_url, started_at, finished_at, error, iterations, model, image, duration_secs)\n VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)`\n );\n\n const tx = db.transaction(() => {\n let count = 0;\n for (const line of lines) {\n try {\n const r = JSON.parse(line) as HistoryRecord;\n // Map 'failure' -> 'failed' for SQLite status convention\n const status = r.status === 'failure' ? 'failed' : r.status;\n insert.run(\n r.ticketId,\n r.ticketId,\n status,\n r.branch || null,\n r.prUrl || null,\n r.startedAt,\n r.finishedAt || null,\n r.error || null,\n r.iterations,\n r.model || null,\n r.image || null,\n r.durationSecs ?? null,\n );\n count++;\n } catch {\n // Skip malformed lines\n }\n }\n return count;\n });\n\n return tx();\n}\n\nfunction formatDuration(secs: number): string {\n if (secs < 60) return `${secs}s`;\n const m = Math.floor(secs / 60);\n const s = secs % 60;\n if (m < 60) return `${m}m ${s}s`;\n const h = Math.floor(m / 60);\n return `${h}h ${m % 60}m`;\n}\n\nfunction formatTime(iso: string): string {\n return iso.replace('T', ' ').slice(0, 19);\n}\n\nfunction pad(s: string, len: number): string {\n return s.length >= len ? s.slice(0, len) : s + ' '.repeat(len - s.length);\n}\n\nexport function printHistoryTable(records: HistoryRecord[]): void {\n if (records.length === 0) {\n console.log('No history records found.');\n return;\n }\n\n // Header\n const header = `${pad('Ticket', 14)} ${pad('Status', 10)} ${pad('PR', 50)} ${pad('Duration', 10)} ${pad('Time', 20)}`;\n console.log(chalk.bold(header));\n console.log('-'.repeat(header.length));\n\n for (const r of records) {\n const status = r.status === 'success'\n ? chalk.green(pad('success', 10))\n : chalk.red(pad('failure', 10));\n const pr = pad(r.prUrl ?? (r.error ? r.error.slice(0, 48) : '-'), 50);\n const dur = pad(formatDuration(r.durationSecs), 10);\n const time = pad(formatTime(r.startedAt), 20);\n\n console.log(`${pad(r.ticketId, 14)} ${status} ${pr} ${dur} ${time}`);\n }\n}\n\nexport { HISTORY_FILE };\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","log","homedir","join","existsSync","readFileSync","homedir","join","existsSync","readFileSync","sleep","join","join","mkdirSync","existsSync","join","existsSync","mkdirSync","join","docker","result","opts","ticket","readFileSync","existsSync","join","homedir","chalk","join","homedir","existsSync","readFileSync","chalk","execSync","existsSync","join","homedir","execSync","existsSync","join","homedir","existsSync","mkdirSync","writeFileSync","readFileSync","execSync","spawn","join","homedir","LinearClient","Octokit","require"]}
|
|
1
|
+
{"version":3,"sources":["../src/index.ts","../src/config.ts","../src/linear.ts","../src/logger.ts","../src/retry.ts","../src/github.ts","../src/webhook.ts","../src/docker.ts","../src/agent.ts","../src/git.ts","../src/worker.ts","../src/db.ts","../src/tunnel.ts","../src/watch.ts","../src/history.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, fixPR } from './worker.js';\nimport { Watcher } from './watch.js';\nimport { readHistory, printHistoryTable, migrateJsonlToSqlite } from './history.js';\nimport type { HistoryRecord } from './history.js';\nimport { checkDockerAvailable, cleanupOrphanedContainers } from './docker.js';\nimport { log, setLogLevel, enableFileLogging, getLogFilePath } from './logger.js';\nimport { checkDeps, installDep, addUserToDockerGroup } from './deps.js';\nimport { existsSync, mkdirSync, writeFileSync, readFileSync, unlinkSync } from 'node:fs';\nimport { execSync, spawn } 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\n// --- PID file helpers for background watcher ---\nconst WATCHER_PID_FILE = join(homedir(), '.autoclawd', 'watcher.pid');\n\nfunction readWatcherPid(): number | null {\n try {\n const content = readFileSync(WATCHER_PID_FILE, 'utf-8').trim();\n const pid = parseInt(content, 10);\n return isNaN(pid) ? null : pid;\n } catch {\n return null;\n }\n}\n\nfunction writeWatcherPid(pid: number): void {\n mkdirSync(join(homedir(), '.autoclawd'), { recursive: true });\n writeFileSync(WATCHER_PID_FILE, String(pid), { mode: 0o600 });\n}\n\nfunction removeWatcherPid(): void {\n try {\n unlinkSync(WATCHER_PID_FILE);\n } catch {\n // File may not exist — that's fine\n }\n}\n\nfunction getRunningWatcherPid(): number | null {\n const pid = readWatcherPid();\n if (pid === null) return null;\n try {\n process.kill(pid, 0); // Signal 0: check if process exists without killing it\n return pid;\n } catch {\n return null; // Process not found\n }\n}\n\nprogram\n .name('autoclawd')\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(`autoclawd 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: 'autoclawd',\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// --- watch ---\nprogram\n .command('watch')\n .description('Poll Linear for tickets (no webhook/tunnel needed)')\n .option('-c, --config <path>', 'Config file path')\n .option('-i, --interval <seconds>', 'Poll interval in seconds', '30')\n .option('--once', 'Poll once and exit (useful for cron)')\n .option('--foreground', 'Run in foreground instead of daemonizing')\n .option('-v, --verbose', 'Verbose logging')\n .action(async (opts) => {\n // Daemonize by default unless --foreground or --once is specified\n if (!opts.foreground && !opts.once) {\n // Refuse to start if another watcher is already running\n const existingPid = getRunningWatcherPid();\n if (existingPid !== null) {\n console.error(`autoclawd watcher is already running (PID ${existingPid})`);\n console.error(`Run 'autoclawd stop' to stop it, or use '--foreground' to run in terminal`);\n process.exit(1);\n }\n\n // Spawn background child with --foreground flag\n const child = spawn(process.argv[0], [...process.argv.slice(1), '--foreground'], {\n detached: true,\n stdio: 'ignore',\n });\n\n // Wait for child to start before printing success\n await new Promise<void>((resolve, reject) => {\n child.once('spawn', resolve);\n child.once('error', reject);\n });\n\n writeWatcherPid(child.pid!);\n const logPath = getLogFilePath();\n console.log(`autoclawd watching in background (PID ${child.pid}, log: ${logPath})`);\n\n child.unref();\n process.exit(0);\n return;\n }\n\n if (opts.verbose) setLogLevel('debug');\n\n enableFileLogging();\n log.info(`autoclawd 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 const orphans = await cleanupOrphanedContainers();\n if (orphans > 0) {\n log.info(`Cleaned up ${orphans} orphaned container(s) from previous session`);\n }\n\n const config = loadConfig(opts.config);\n const intervalSeconds = parseInt(opts.interval);\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 watcher = new Watcher(config, linearClient, octokit);\n\n const shutdown = () => {\n log.info('Shutting down...');\n watcher.stop();\n removeWatcherPid();\n process.exit(0);\n };\n process.on('SIGINT', shutdown);\n process.on('SIGTERM', shutdown);\n\n await watcher.start(intervalSeconds, opts.once ?? false);\n });\n\n// --- stop ---\nprogram\n .command('stop')\n .description('Stop the background watcher')\n .action(() => {\n const pid = readWatcherPid();\n if (pid === null) {\n log.info('No watcher PID file found — watcher is not running');\n return;\n }\n\n const running = getRunningWatcherPid();\n if (running === null) {\n // Stale PID file\n removeWatcherPid();\n log.info(`Removed stale PID file (process ${pid} is not running)`);\n return;\n }\n\n try {\n process.kill(pid, 'SIGTERM');\n removeWatcherPid();\n log.success(`Watcher stopped (PID ${pid})`);\n } catch (err) {\n log.error(`Failed to stop watcher: ${err instanceof Error ? err.message : err}`);\n process.exit(1);\n }\n });\n\n// --- run ---\nprogram\n .command('run <ticket>')\n .description('Run a single ticket (e.g. autoclawd 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 .option('--force', 'Bypass completed-ticket check and re-run')\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 .autoclawd.yaml or main)'}`);\n log.info(` Branch: autoclawd/${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, force: opts.force });\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// --- fix ---\nprogram\n .command('fix <pr-url>')\n .description('Fix failed CI checks on a PR (e.g. autoclawd fix https://github.com/owner/repo/pull/123)')\n .option('-c, --config <path>', 'Config file path')\n .option('-v, --verbose', 'Verbose logging')\n .action(async (prUrl: string, opts) => {\n if (opts.verbose) setLogLevel('debug');\n enableFileLogging();\n\n // Parse PR URL: https://github.com/owner/repo/pull/123\n const match = prUrl.match(/github\\.com\\/([^/]+)\\/([^/]+)\\/pull\\/(\\d+)/);\n if (!match) {\n throw new Error(`Invalid PR URL: \"${prUrl}\"\\nExpected: https://github.com/owner/repo/pull/123`);\n }\n const [, owner, repo, prNumStr] = match;\n const repoUrl = `https://github.com/${owner}/${repo}`;\n const prNumber = parseInt(prNumStr);\n\n const config = loadConfig(opts.config);\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 const octokit = createOctokit(config);\n\n const result = await fixPR({ repoUrl, prNumber, config, octokit });\n if (!result.success) {\n throw new Error(result.error ?? 'Fix failed');\n }\n });\n\n// --- retry ---\nprogram\n .command('retry [ticket]')\n .description('Retry a failed ticket (e.g. autoclawd retry RAH-123)')\n .option('-c, --config <path>', 'Config file path')\n .option('-v, --verbose', 'Verbose logging')\n .option('--last-failed', 'Retry the most recent failed run')\n .option('--all-failed', 'Retry all failed runs (sequentially)')\n .action(async (ticketArg: string | undefined, opts) => {\n if (opts.verbose) setLogLevel('debug');\n enableFileLogging();\n\n if (!ticketArg && !opts.lastFailed && !opts.allFailed) {\n throw new Error(\n 'Provide a ticket ID, --last-failed, or --all-failed.\\n'\n + 'Usage: autoclawd retry RAH-123 | --last-failed | --all-failed'\n );\n }\n\n const config = loadConfig(opts.config);\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 linearClient = createLinearClient(config);\n const octokit = createOctokit(config);\n\n // Determine which ticket(s) to retry\n let ticketIds: string[] = [];\n\n if (ticketArg) {\n // Explicit ticket ID — check history for context but proceed even if not found\n const history = readHistory({ failedOnly: true, limit: 1000 });\n const prev = history.find(\n (r) => r.ticketId.toLowerCase() === ticketArg.toLowerCase()\n );\n if (prev) {\n log.info(`Retrying ${prev.ticketId} — last failure: ${prev.error ?? 'unknown error'}`);\n log.info(` Failed at: ${prev.startedAt}`);\n } else {\n log.info(`No previous failure found for ${ticketArg}, running fresh`);\n }\n ticketIds = [ticketArg];\n } else if (opts.lastFailed) {\n const history = readHistory({ failedOnly: true, limit: 1 });\n if (history.length === 0) {\n throw new Error('No failed runs found in history');\n }\n const last = history[0];\n log.info(`Retrying last failed: ${last.ticketId} — ${last.error ?? 'unknown error'}`);\n log.info(` Failed at: ${last.startedAt}`);\n ticketIds = [last.ticketId];\n } else if (opts.allFailed) {\n // Collect unique ticket IDs from failures that don't have a subsequent success\n const allRecords = readHistory({ limit: 10000 });\n const succeeded = new Set(\n allRecords.filter((r) => r.status === 'success').map((r) => r.ticketId)\n );\n const failedUnique = new Map<string, HistoryRecord>();\n for (const r of allRecords) {\n if (r.status === 'failure' && !succeeded.has(r.ticketId) && !failedUnique.has(r.ticketId)) {\n failedUnique.set(r.ticketId, r);\n }\n }\n if (failedUnique.size === 0) {\n throw new Error('No unresolved failed runs found in history');\n }\n log.info(`Found ${failedUnique.size} failed ticket(s) to retry:`);\n for (const [id, rec] of failedUnique) {\n log.info(` ${id} — ${rec.error ?? 'unknown error'}`);\n }\n ticketIds = [...failedUnique.keys()];\n }\n\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 for (const id of ticketIds) {\n log.info(`\\nRetrying ticket ${id}...`);\n const ticket = await fetchTicket(linearClient, id);\n if (!ticket) {\n log.error(`Ticket ${id} not found in Linear, skipping`);\n continue;\n }\n if (!ticket.repoUrl) {\n log.error(`${id} has no repo: label, skipping`);\n continue;\n }\n const result = await executeTicket({ ticket, config, linearClient, octokit });\n if (result.success) {\n log.success(`${id} completed${result.prUrl ? ` → ${result.prUrl}` : ''}`);\n } else {\n log.error(`${id} failed again: ${result.error ?? 'unknown'}`);\n if (ticketIds.length === 1) {\n throw new Error(result.error ?? 'Retry failed');\n }\n }\n }\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 autoclawd 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// --- history ---\nprogram\n .command('history')\n .description('Show run history')\n .option('-n, --limit <number>', 'Number of records to show', '20')\n .option('--json', 'Output as JSON')\n .option('--failed', 'Show only failures')\n .action((opts) => {\n // Migrate legacy JSONL records into SQLite on first use\n migrateJsonlToSqlite();\n\n const records = readHistory({\n limit: parseInt(opts.limit),\n failedOnly: opts.failed ?? false,\n });\n\n if (opts.json) {\n console.log(JSON.stringify(records, null, 2));\n } else {\n printHistoryTable(records);\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 autoclawd interactively')\n .action(async () => {\n console.log('\\n autoclawd 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: autoclawd 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 (any image works — autoclawd auto-installs git + Claude Code):');\n console.log(' node:20 — Node.js (default, recommended)');\n console.log(' python:3.12 — Python');\n console.log(' ubuntu:24.04 — General purpose');\n const dockerImage = await ask('Docker image', 'node:20');\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). autoclawd resolves\n // these from the environment at runtime.\n const config = `# autoclawd config — generated by autoclawd 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 autoclawd:\n $ autoclawd serve\n\n autoclawd 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 (~/.autoclawd/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/autoclawd/.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 SafetyConfigSchema = z.object({\n allowedRepos: z.array(z.string()).optional(),\n branchPrefix: z.string().default('autoclawd/'),\n maxFileChanges: z.number().min(1).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 safety: SafetyConfigSchema.default({}),\n maxConcurrent: z.number().default(1),\n validate: z.array(z.string()).optional(), // Global default validation commands\n});\n\nexport type Config = z.infer<typeof ConfigSchema>;\nexport type AgentConfig = z.infer<typeof AgentConfigSchema>;\nexport type DockerConfig = z.infer<typeof DockerConfigSchema>;\nexport type SafetyConfig = z.infer<typeof SafetyConfigSchema>;\n\n// Per-repo config (.autoclawd.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 validate: z.array(z.string()).optional(), // Validation commands to run before PR\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(), '.autoclawd');\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: autoclawd 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, '.autoclawd.yaml');\n const ymlPath = join(workspacePath, '.autoclawd.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 validate?: 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 // Repo-local validate overrides host default; undefined means no validation\n const validate = local?.validate ?? host.validate;\n\n return { agent, docker, prompt: local?.prompt, validate };\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:autoclawd/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\n// Check if a repo URL is in the allowedRepos list\n// Matches against \"owner/name\" or full \"https://github.com/owner/name\" formats\nexport function isRepoAllowed(repoUrl: string, allowedRepos?: string[]): boolean {\n if (!allowedRepos) return true; // No allowlist = all repos allowed\n return allowedRepos.some((allowed) => {\n const normalizedAllowed = allowed.includes('/')\n ? (allowed.startsWith('https://') ? allowed : `https://github.com/${allowed}`)\n : allowed;\n return repoUrl.toLowerCase() === normalizedAllowed.toLowerCase();\n });\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';\nimport { retry, isTransientError } from './retry.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 await retry(async () => {\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 await client.updateIssue(ticketId, { stateId: inProgress.id });\n }, { label: 'Linear claim', retryIf: isTransientError });\n}\n\nexport async function completeTicket(\n client: LinearClient,\n config: Config,\n ticketId: string,\n comment: string\n): Promise<void> {\n await retry(async () => {\n await client.createComment({ issueId: ticketId, body: comment });\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 }, { label: 'Linear complete', retryIf: isTransientError });\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: `**autoclawd 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(), '.autoclawd', 'logs');\n if (!existsSync(logDir)) {\n mkdirSync(logDir, { recursive: true });\n }\n const date = new Date().toISOString().slice(0, 10);\n logFilePath = join(logDir, `autoclawd-${date}.log`);\n}\n\nexport function getLogFilePath(): string {\n const date = new Date().toISOString().slice(0, 10);\n return join(homedir(), '.autoclawd', 'logs', `autoclawd-${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 { log } from './logger.js';\n\nexport interface RetryOpts {\n /** Max number of attempts (including first try). Default: 3 */\n attempts?: number;\n /** Base delay in ms (doubled each retry). Default: 1000 */\n baseDelayMs?: number;\n /** Label for log messages, e.g. \"git clone\" */\n label: string;\n /** Optional predicate — only retry if this returns true for the error */\n retryIf?: (err: unknown) => boolean;\n}\n\n/**\n * Retry an async operation with exponential backoff.\n * Logs each retry attempt. Rethrows the last error if all attempts fail.\n */\nexport async function retry<T>(fn: () => Promise<T>, opts: RetryOpts): Promise<T> {\n const attempts = opts.attempts ?? 3;\n const baseDelay = opts.baseDelayMs ?? 1000;\n\n let lastErr: unknown;\n for (let i = 1; i <= attempts; i++) {\n try {\n return await fn();\n } catch (err) {\n lastErr = err;\n\n // Check if this error is retryable\n if (opts.retryIf && !opts.retryIf(err)) {\n throw err; // Not a transient error, bail immediately\n }\n\n if (i < attempts) {\n const delay = baseDelay * Math.pow(2, i - 1);\n const msg = err instanceof Error ? err.message.split('\\n')[0] : String(err);\n log.warn(`${opts.label} failed (attempt ${i}/${attempts}): ${msg} — retrying in ${delay}ms`);\n await sleep(delay);\n }\n }\n }\n\n throw lastErr;\n}\n\n/**\n * Retry a sync function (wraps in async).\n */\nexport function retrySync<T>(fn: () => T, opts: RetryOpts): Promise<T> {\n return retry(() => Promise.resolve(fn()), opts);\n}\n\n/** Returns true if the error looks like a transient network/API failure */\nexport function isTransientError(err: unknown): boolean {\n if (!(err instanceof Error)) return false;\n const msg = err.message.toLowerCase();\n return (\n msg.includes('econnreset') ||\n msg.includes('econnrefused') ||\n msg.includes('etimedout') ||\n msg.includes('eai_again') ||\n msg.includes('epipe') ||\n msg.includes('socket hang up') ||\n msg.includes('network') ||\n msg.includes('timeout') ||\n msg.includes('502') ||\n msg.includes('503') ||\n msg.includes('504') ||\n msg.includes('rate limit') ||\n msg.includes('429') ||\n msg.includes('500') ||\n msg.includes('internal server error')\n );\n}\n\nfunction sleep(ms: number): Promise<void> {\n return new Promise((resolve) => setTimeout(resolve, ms));\n}\n","import { Octokit } from '@octokit/rest';\nimport type { Config } from './config.js';\nimport { log } from './logger.js';\nimport { retry, isTransientError } from './retry.js';\n\nexport function createOctokit(config: Config): Octokit {\n return new Octokit({ auth: config.github.token });\n}\n\nexport function 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 draft?: boolean;\n}): Promise<{ url: string; number: number }> {\n return retry(async () => {\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(`Updating existing PR #${pr.number}: ${pr.html_url}`);\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 draft: opts.draft ?? false,\n });\n\n log.success(`Created ${opts.draft ? 'draft ' : ''}PR #${pr.data.number}: ${pr.data.html_url}`);\n return { url: pr.data.html_url, number: pr.data.number };\n }, { label: 'GitHub PR', retryIf: isTransientError });\n}\n\n/** Mark a draft PR as ready for review */\nexport async function markPRReady(octokit: Octokit, opts: {\n repoUrl: string;\n prNumber: number;\n}): Promise<void> {\n return retry(async () => {\n const { owner, repo } = parseRepoUrl(opts.repoUrl);\n await octokit.rest.pulls.update({\n owner,\n repo,\n pull_number: opts.prNumber,\n draft: false,\n });\n log.info(`Marked PR #${opts.prNumber} as ready for review`);\n }, { label: 'GitHub PR ready', retryIf: isTransientError });\n}\n\n/** Update the body of an existing PR */\nexport async function updatePRBody(octokit: Octokit, opts: {\n repoUrl: string;\n prNumber: number;\n body: string;\n}): Promise<void> {\n return retry(async () => {\n const { owner, repo } = parseRepoUrl(opts.repoUrl);\n await octokit.rest.pulls.update({\n owner,\n repo,\n pull_number: opts.prNumber,\n body: opts.body,\n });\n }, { label: 'GitHub PR update', retryIf: isTransientError });\n}\n\n/** Fetch PR metadata */\nexport async function fetchPR(octokit: Octokit, opts: {\n repoUrl: string;\n prNumber: number;\n}): Promise<{ head: string; base: string; title: string; state: string }> {\n const { owner, repo } = parseRepoUrl(opts.repoUrl);\n const { data } = await octokit.rest.pulls.get({ owner, repo, pull_number: opts.prNumber });\n return {\n head: data.head.ref,\n base: data.base.ref,\n title: data.title,\n state: data.state,\n };\n}\n\n/** Ensure a GitHub repo exists, creating it if not. Returns whether it was created. */\nexport async function ensureRepoExists(octokit: Octokit, opts: {\n owner: string;\n repo: string;\n description?: string;\n}): Promise<{ created: boolean }> {\n try {\n await octokit.rest.repos.get({ owner: opts.owner, repo: opts.repo });\n return { created: false };\n } catch (err: unknown) {\n const status = (err as { status?: number }).status;\n if (status !== 404) throw err;\n }\n\n log.info(`Repo ${opts.owner}/${opts.repo} does not exist, creating...`);\n\n // Determine whether owner is the authenticated user or an org\n const { data: authUser } = await octokit.rest.users.getAuthenticated();\n\n if (authUser.login === opts.owner) {\n await octokit.rest.repos.createForAuthenticatedUser({\n name: opts.repo,\n description: opts.description,\n auto_init: false,\n });\n } else {\n await octokit.rest.repos.createInOrg({\n org: opts.owner,\n name: opts.repo,\n description: opts.description,\n auto_init: false,\n });\n }\n\n return { created: true };\n}\n\n/** Fetch failed CI check logs for a PR's head commit */\nexport async function fetchFailedChecks(octokit: Octokit, opts: {\n repoUrl: string;\n prNumber: number;\n}): Promise<Array<{ name: string; conclusion: string; log: string }>> {\n const { owner, repo } = parseRepoUrl(opts.repoUrl);\n\n // Get the head SHA of the PR\n const { data: pr } = await octokit.rest.pulls.get({ owner, repo, pull_number: opts.prNumber });\n const headSha = pr.head.sha;\n\n // Get check runs for that commit\n const { data: checks } = await octokit.rest.checks.listForRef({\n owner, repo, ref: headSha,\n });\n\n const failed = checks.check_runs.filter(\n c => c.conclusion === 'failure' || c.conclusion === 'timed_out'\n );\n\n if (failed.length === 0) return [];\n\n const results: Array<{ name: string; conclusion: string; log: string }> = [];\n\n for (const check of failed) {\n let logText = '';\n\n // Try to get the log from GitHub Actions\n if (check.app?.slug === 'github-actions') {\n try {\n // Find the matching workflow run\n const { data: runs } = await octokit.rest.actions.listWorkflowRunsForRepo({\n owner, repo, head_sha: headSha, per_page: 10,\n });\n\n for (const run of runs.workflow_runs) {\n if (run.conclusion !== 'failure') continue;\n const { data: jobs } = await octokit.rest.actions.listJobsForWorkflowRun({\n owner, repo, run_id: run.id,\n });\n\n for (const job of jobs.jobs) {\n if (job.conclusion !== 'failure') continue;\n try {\n const { data: log } = await octokit.rest.actions.downloadJobLogsForWorkflowRun({\n owner, repo, job_id: job.id,\n });\n // Logs come back as a string, truncate to last 3000 chars to keep prompt manageable\n const logStr = typeof log === 'string' ? log : String(log);\n logText += `\\n--- Job: ${job.name} ---\\n` + logStr.slice(-3000);\n } catch {\n // Log download can fail for older runs\n }\n }\n }\n } catch {\n // Fall back to check run output\n }\n }\n\n // Fall back to check run annotations/output\n if (!logText && check.output?.text) {\n logText = check.output.text.slice(-3000);\n }\n if (!logText && check.output?.summary) {\n logText = check.output.summary.slice(-3000);\n }\n\n results.push({\n name: check.name,\n conclusion: check.conclusion ?? 'failure',\n log: logText || '(no log available)',\n });\n }\n\n return results;\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';\nimport {\n getDb,\n closeDb,\n insertRun,\n finishRun,\n isTicketActive,\n isTicketProcessed,\n getActiveRuns,\n enqueue,\n dequeue,\n getQueueLength,\n getQueuedTickets,\n removeFromQueue,\n} from './db.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 server: ReturnType<typeof createServer> | undefined;\n // Track in-memory active set for concurrency counting (fast path)\n private activeInMemory = new Set<string>();\n\n constructor(\n private config: Config,\n private linearClient: LinearClient,\n private octokit: Octokit,\n ) {}\n\n start(): Promise<void> {\n // Initialize the database on startup\n getDb();\n\n // Resume any queued tickets from a previous run\n this.resumeQueue();\n\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({\n status: 'ok',\n active: this.activeInMemory.size,\n queued: getQueueLength(),\n capacity: this.config.maxConcurrent,\n }));\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 closeDb();\n log.info('Webhook server stopped');\n }\n\n private resumeQueue(): void {\n // Mark any previously \"running\" tickets as failed (unclean shutdown)\n const staleRuns = getActiveRuns();\n for (const run of staleRuns) {\n log.warn(`${run.ticket_id}: was running at shutdown, marking as failed`);\n finishRun(run.ticket_id, 'failed', 'Unclean shutdown — process restarted');\n }\n\n // Re-dispatch queued tickets\n const queued = getQueuedTickets();\n if (queued.length > 0) {\n log.info(`Resuming ${queued.length} queued ticket(s) from database`);\n for (const ticket of queued) {\n removeFromQueue(ticket.id);\n if (this.activeInMemory.size >= this.config.maxConcurrent) {\n // Re-enqueue if still at capacity\n enqueue(ticket);\n break;\n }\n this.dispatch(ticket);\n }\n }\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 this ticket? (in-memory fast check + DB check)\n if (this.activeInMemory.has(data.id) || isTicketActive(data.id)) {\n log.debug(`${data.identifier}: already active, ignoring`);\n return;\n }\n\n // Already processed this ticket? (durable across restarts)\n if (isTicketProcessed(data.id)) {\n log.debug(`${data.identifier}: already processed, ignoring`);\n return;\n }\n\n // Check concurrency — queue if at capacity instead of dropping\n if (this.activeInMemory.size >= this.config.maxConcurrent) {\n log.info(`${data.identifier}: at capacity (${this.activeInMemory.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 enqueue(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.activeInMemory.add(ticket.id);\n insertRun(ticket.id, 'running');\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 }).then(\n () => {\n finishRun(ticket.id, 'success');\n },\n (err: Error) => {\n finishRun(ticket.id, 'failed', err.message);\n },\n ).finally(() => {\n this.activeInMemory.delete(ticket.id);\n this.drainQueue();\n });\n }\n\n private drainQueue(): void {\n while (this.activeInMemory.size < this.config.maxConcurrent) {\n const next = dequeue();\n if (!next) break;\n // Skip if this ticket is already active (duplicate webhook)\n if (this.activeInMemory.has(next.id)) continue;\n log.ticket(next.identifier, `Dequeued (${getQueueLength()} remaining)`);\n this.dispatch(next);\n }\n }\n}\n","import Docker from 'dockerode';\nimport { PassThrough } from 'node:stream';\nimport { homedir } from 'node:os';\nimport { join } from 'node:path';\nimport { existsSync, readFileSync } from 'node:fs';\nimport type { DockerConfig } from './config.js';\nimport { log } from './logger.js';\nimport { retry, isTransientError } from './retry.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\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 // Pull the image (with retry for transient network errors)\n log.info(`Pulling image ${image} (this may take a moment)...`);\n await retry(() => 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 }), { label: 'docker pull', retryIf: isTransientError });\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 autoclawd-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: `autoclawd-${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 + 'autoclawd 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 autoclawd 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 // The install script requires bash; installs to ~/.local/bin/claude\n // We symlink to /usr/local/bin so it's on PATH for all users (including autoclawd)\n // Install script puts binary at ~/.local/bin/claude (symlink chain into ~/.local/share/).\n // The autoclawd user can't traverse /root/, so we copy the resolved binary to /usr/local/bin.\n const standaloneResult = await exec(wrapped, [\n 'bash', '-c',\n 'curl -fsSL https://claude.ai/install.sh | bash'\n + ' && cp -L /root/.local/bin/claude /usr/local/bin/claude'\n + ' && chmod 755 /usr/local/bin/claude',\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 bash and curl are 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 autoclawd >/dev/null 2>&1 ) || '\n + '( adduser --disabled-password --gecos \"\" --uid 1001 --home /home/autoclawd autoclawd 2>/dev/null ) || '\n + '( adduser -D -u 1001 -h /home/autoclawd autoclawd 2>/dev/null ) || ' // Alpine adduser\n + '( useradd -m -u 1001 -d /home/autoclawd autoclawd 2>/dev/null ) || ' // useradd fallback\n + '( echo \"autoclawd:x:1001:1001::/home/autoclawd:/bin/sh\" >> /etc/passwd && mkdir -p /home/autoclawd ); '\n + 'mkdir -p /home/autoclawd && chown -R autoclawd /home/autoclawd /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 .autoclawd.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/autoclawd/.claude && chown autoclawd /home/autoclawd/.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/autoclawd/.claude/.credentials.json && chown autoclawd /home/autoclawd/.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/autoclawd/.claude/settings.json && chown autoclawd /home/autoclawd/.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[autoclawd] 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('/autoclawd-'))\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 /\\[autoclawd: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/autoclawd && echo '${promptB64}' | base64 -d > /tmp/autoclawd/prompt.md && chmod 644 /tmp/autoclawd/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/autoclawd/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: 'autoclawd',\n env: ['HOME=/home/autoclawd', '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: 'autoclawd' };\n await exec(container, ['git', 'config', 'user.name', 'autoclawd'], u);\n await exec(container, ['git', 'config', 'user.email', 'autoclawd@autoclawd.dev'], 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 branchPrefix?: string;\n maxFileChanges?: number;\n}): Promise<{ pushed: boolean; commitCount: number }> {\n const { branchName, ticketId, title, githubToken, branchPrefix, maxFileChanges } = opts;\n\n const u = { user: 'autoclawd' };\n\n // Safety: verify branch starts with configured prefix\n if (branchPrefix && !branchName.startsWith(branchPrefix)) {\n log.error(`Safety: branch \"${branchName}\" does not start with required prefix \"${branchPrefix}\"`);\n throw new Error(`Branch \"${branchName}\" does not start with required prefix \"${branchPrefix}\"`);\n }\n log.info(`Safety: branch prefix check passed for \"${branchName}\"`);\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 // Safety: count changed files and enforce limit\n if (maxFileChanges !== undefined) {\n const diffResult = await exec(container, [\n 'git', 'diff', '--name-only', 'HEAD', '--not', '--remotes',\n ], u);\n const changedFiles = diffResult.stdout.trim().split('\\n').filter(Boolean).length;\n if (changedFiles > maxFileChanges) {\n log.error(`Safety: ${changedFiles} files changed, exceeds maxFileChanges limit of ${maxFileChanges}`);\n throw new Error(`Too many file changes: ${changedFiles} files changed (limit: ${maxFileChanges}). Review changes manually.`);\n }\n log.info(`Safety: file change count (${changedFiles}) within limit (${maxFileChanges})`);\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, isRepoAllowed } from './config.js';\nimport type { Ticket } from './linear.js';\nimport { claimTicket, completeTicket, failTicket, addBranchLabel } from './linear.js';\nimport { createContainer, destroyContainer, exec } from './docker.js';\nimport type { Container } from './docker.js';\nimport { runAgentLoop } from './agent.js';\nimport { setupRepo, commitAndPush } from './git.js';\nimport { openPR, fetchPR, fetchFailedChecks, markPRReady, updatePRBody, ensureRepoExists, parseRepoUrl } 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';\nimport { retrySync, isTransientError } from './retry.js';\nimport { getRunByTicketId, insertRun, updateRun, finishRun } from './db.js';\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 [autoclawd: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 .autoclawd.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(), 'autoclawd-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// Push a minimal scaffold (README.md + .autoclawd.yaml) to a newly-created repo\nasync function pushScaffold(opts: {\n repoUrl: string;\n ticketTitle: string;\n ticketDescription: string;\n githubToken: string;\n}): Promise<void> {\n const scaffoldDir = mkdtempSync(join(tmpdir(), 'autoclawd-scaffold-'));\n const askpass = createAskpass(opts.githubToken);\n\n try {\n const authedUrl = opts.repoUrl.replace('https://', 'https://x-access-token@');\n const env = gitEnv(askpass.path);\n\n const readmeLines = [`# ${opts.ticketTitle}`];\n if (opts.ticketDescription) {\n readmeLines.push('', opts.ticketDescription);\n }\n writeFileSync(join(scaffoldDir, 'README.md'), readmeLines.join('\\n') + '\\n');\n writeFileSync(join(scaffoldDir, '.autoclawd.yaml'), 'base: main\\n');\n\n execSync('git init', { cwd: scaffoldDir, stdio: 'pipe', env });\n execSync('git checkout -b main', { cwd: scaffoldDir, stdio: 'pipe', env });\n execSync('git config user.email \"autoclawd@users.noreply.github.com\"', { cwd: scaffoldDir, stdio: 'pipe', env });\n execSync('git config user.name \"autoclawd\"', { cwd: scaffoldDir, stdio: 'pipe', env });\n execSync('git add .', { cwd: scaffoldDir, stdio: 'pipe', env });\n execSync('git commit -m \"chore: initial scaffold\"', { cwd: scaffoldDir, stdio: 'pipe', env });\n execSync(`git remote add origin ${authedUrl}`, { cwd: scaffoldDir, stdio: 'pipe', env });\n execSync('git push -u origin main', { cwd: scaffoldDir, stdio: 'pipe', timeout: 60_000, env });\n } finally {\n rmSync(scaffoldDir, { recursive: true, force: true });\n rmSync(askpass.dir, { recursive: true, force: true });\n }\n}\n\n// Clone repo to temp dir on the host so we can read .autoclawd.yaml before Docker\n// Retries on transient network errors (ECONNRESET, timeout, etc.)\nasync function cloneToTemp(repoUrl: string, baseBranch: string, githubToken: string): Promise<string> {\n assertSafeRef(baseBranch, 'base branch');\n\n return retrySync(() => {\n const workDir = mkdtempSync(join(tmpdir(), 'autoclawd-'));\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 } catch (err) {\n rmSync(workDir, { recursive: true, force: true });\n throw err;\n } finally {\n rmSync(askpass.dir, { recursive: true, force: true });\n }\n return workDir;\n }, { label: 'git clone', retryIf: isTransientError });\n}\n\nexport interface ValidationFailure {\n command: string;\n exitCode: number;\n output: string;\n}\n\nexport async function runValidation(\n container: Container,\n commands: string[],\n ticketId: string,\n): Promise<ValidationFailure[]> {\n const failures: ValidationFailure[] = [];\n\n for (const cmd of commands) {\n log.ticket(ticketId, `Validating: ${cmd}`);\n const result = await exec(container, ['sh', '-c', cmd], {\n user: 'autoclawd',\n env: ['HOME=/home/autoclawd'],\n timeout: 5 * 60 * 1000, // 5 min per validation command\n });\n\n if (result.exitCode === 0) {\n log.ticket(ticketId, ` PASS: ${cmd}`);\n } else {\n log.ticket(ticketId, ` FAIL: ${cmd} (exit ${result.exitCode})`);\n const output = (result.stdout + result.stderr).trim();\n failures.push({\n command: cmd,\n exitCode: result.exitCode,\n output: output.slice(-3000), // Cap output to avoid huge prompts\n });\n }\n }\n\n return failures;\n}\n\nexport function buildValidationFixPrompt(failures: ValidationFailure[]): string {\n const parts: string[] = [];\n\n parts.push('## Validation Failed');\n parts.push('');\n parts.push('The following validation commands failed after your changes. Please fix the issues and commit your fixes.');\n parts.push('');\n\n for (const f of failures) {\n parts.push(`### Failed: \\`${f.command}\\` (exit code ${f.exitCode})`);\n parts.push('```');\n parts.push(f.output);\n parts.push('```');\n parts.push('');\n }\n\n parts.push('## Instructions');\n parts.push('- Read the error output carefully and fix the root cause');\n parts.push('- Run the failing command(s) to verify your fix');\n parts.push('- Commit your fixes with: git add -A && git commit -m \"fix: address validation failures\"');\n parts.push('- When done, include [autoclawd:done] in your output');\n\n return parts.join('\\n');\n}\n\nexport async function executeTicket(opts: {\n ticket: Ticket;\n config: Config;\n linearClient: LinearClient;\n octokit: Octokit;\n force?: boolean;\n}): Promise<WorkerResult> {\n const { ticket, config, linearClient, octokit, force } = opts;\n const startedAt = new Date();\n\n function recordRun(result: WorkerResult, branch?: string): void {\n const finishedAt = new Date();\n const durationSecs = Math.round((finishedAt.getTime() - startedAt.getTime()) / 1000);\n try {\n // Ensure the run row exists (upsert)\n insertRun(result.ticketId, result.success ? 'success' : 'failed');\n updateRun(result.ticketId, {\n status: result.success ? 'success' : 'failed',\n branch: branch ?? null,\n pr_url: result.prUrl ?? null,\n error: result.error ?? null,\n iterations: result.iterations,\n model: config.agent.model,\n image: config.docker.image,\n finished_at: finishedAt.toISOString(),\n duration_secs: durationSecs,\n });\n } catch {\n // Best effort — don't fail the ticket over history logging\n }\n }\n\n // Check if ticket was already completed (idempotency guard)\n if (!force) {\n const existingRun = getRunByTicketId(ticket.identifier);\n if (existingRun?.status === 'success') {\n log.info(`${ticket.identifier}: already completed, use --force to re-run`);\n return {\n ticketId: ticket.identifier,\n success: true,\n prUrl: existingRun.pr_url ?? undefined,\n iterations: existingRun.iterations,\n };\n }\n }\n\n // Record the run at the START to prevent crash-and-restart from re-dispatching\n insertRun(ticket.identifier, 'running');\n\n if (!ticket.repoUrl) {\n const result: WorkerResult = {\n ticketId: ticket.identifier,\n success: false,\n error: 'No repo:owner/name label on ticket',\n iterations: 0,\n };\n recordRun(result);\n return result;\n }\n\n // Validate repo URL before attempting clone\n if (!ticket.repoUrl.startsWith('https://')) {\n const result: WorkerResult = {\n ticketId: ticket.identifier,\n success: false,\n error: `Invalid repo URL: \"${ticket.repoUrl}\". Only HTTPS URLs are supported.`,\n iterations: 0,\n };\n recordRun(result);\n return result;\n }\n\n // Safety: check repo against allowlist\n if (!isRepoAllowed(ticket.repoUrl, config.safety.allowedRepos)) {\n log.warn(`Safety: repo ${ticket.repoUrl} not in allowedRepos list`);\n return {\n ticketId: ticket.identifier,\n success: false,\n error: `Repo not allowed: \"${ticket.repoUrl}\". Check safety.allowedRepos in config.`,\n iterations: 0,\n };\n }\n log.info(`Safety: repo ${ticket.repoUrl} allowed`);\n\n const branchName = `autoclawd/${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. Ensure the repo exists on GitHub; create + scaffold if not\n const { owner: repoOwner, repo: repoName } = parseRepoUrl(ticket.repoUrl);\n const { created: repoCreated } = await ensureRepoExists(octokit, {\n owner: repoOwner,\n repo: repoName,\n description: ticket.title,\n });\n\n if (repoCreated) {\n await pushScaffold({\n repoUrl: ticket.repoUrl,\n ticketTitle: ticket.title,\n ticketDescription: ticket.description,\n githubToken: config.github.token,\n });\n log.ticket(ticket.identifier, 'Repo created, pushed scaffold');\n }\n\n // 3. Detect the repo's default branch (main, master, develop, etc.)\n // For a freshly-created repo the default branch is always 'main'\n const detectedBase = repoCreated ? 'main' : detectDefaultBranch(ticket.repoUrl, config.github.token);\n log.ticket(ticket.identifier, `Default branch: ${detectedBase}`);\n\n // Clone with the detected default branch\n workDir = await cloneToTemp(ticket.repoUrl, detectedBase, config.github.token);\n log.ticket(ticket.identifier, 'Cloned repo');\n\n // 3. Load .autoclawd.yaml from repo, merge with host config\n const repoLocal = loadRepoLocalConfig(workDir);\n // Priority: ticket \"base:\" label > .autoclawd.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, validate } = mergeConfigs(config, repoLocal);\n\n if (repoLocal) {\n log.ticket(ticket.identifier, 'Loaded .autoclawd.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 = await 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 let agentResult = await runAgentLoop({\n container,\n agentConfig: agent,\n prompt: agentPrompt,\n ticketId: ticket.identifier,\n });\n\n // 6. Push immediately (agent commits incrementally, we just push)\n // Push before validation so code is preserved even if validation hangs\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 branchPrefix: config.safety.branchPrefix,\n maxFileChanges: config.safety.maxFileChanges,\n });\n\n if (!gitResult.pushed) {\n await failTicket(linearClient, ticket.id, 'No changes produced');\n finishRun(ticket.identifier, 'failed', 'No changes produced');\n const result: WorkerResult = {\n ticketId: ticket.identifier,\n success: false,\n error: 'No changes produced',\n iterations: agentResult.iterations,\n };\n recordRun(result, branchName);\n return result;\n }\n\n // 7. Open draft PR so code is visible even if validation fails or hangs\n const buildPRBody = (opts?: { validationWarnings?: ValidationFailure[]; commitCount: number }): string => {\n const prBody: string[] = [\n `Resolves [${ticket.identifier}](${ticket.url})`,\n '',\n ];\n\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 if (opts?.validationWarnings && opts.validationWarnings.length > 0) {\n prBody.push('## :warning: Validation Failures', '');\n prBody.push('The following validation commands were still failing after all iterations:', '');\n for (const f of opts.validationWarnings) {\n prBody.push(`### \\`${f.command}\\` (exit code ${f.exitCode})`, '');\n prBody.push('<details><summary>Output</summary>', '', '```', f.output, '```', '', '</details>', '');\n }\n }\n\n prBody.push(\n '## Details',\n '',\n `| Metric | Value |`,\n `| --- | --- |`,\n `| Iterations | ${agentResult.iterations} |`,\n `| Commits | ${opts?.commitCount ?? gitResult.commitCount} |`,\n `| Model | ${agent.model} |`,\n '',\n '---',\n '*Generated by [autoclawd](https://github.com/rahul-fnu/autoclawd)*',\n );\n\n return prBody.join('\\n');\n };\n\n const hasValidation = validate && validate.length > 0;\n const pr = await openPR(octokit, {\n repoUrl: ticket.repoUrl,\n branch: branchName,\n baseBranch: actualBase,\n title: `${ticket.identifier}: ${ticket.title}`,\n body: buildPRBody({ commitCount: gitResult.commitCount }),\n draft: hasValidation ? true : false,\n });\n\n // 8. Run validation hooks (if configured) after draft PR is created\n if (hasValidation) {\n let iterationsUsed = agentResult.iterations;\n let lastFailures: ValidationFailure[] = [];\n let totalCommitCount = gitResult.commitCount;\n\n // Run validation, feed failures back to agent, repeat until pass or maxIterations\n while (iterationsUsed < agent.maxIterations) {\n const failures = await runValidation(container, validate, ticket.identifier);\n if (failures.length === 0) {\n log.ticket(ticket.identifier, 'All validations passed');\n lastFailures = [];\n break;\n }\n\n lastFailures = failures;\n log.ticket(ticket.identifier, `${failures.length} validation(s) failed, feeding back to Claude`);\n\n // Feed failure output to Claude for another iteration\n const fixPrompt = buildValidationFixPrompt(failures);\n const fixResult = await runAgentLoop({\n container,\n agentConfig: { ...agent, maxIterations: 1 },\n prompt: fixPrompt,\n ticketId: ticket.identifier,\n });\n iterationsUsed += fixResult.iterations;\n agentResult = {\n iterations: iterationsUsed,\n success: fixResult.success,\n lastOutput: fixResult.lastOutput,\n };\n\n // Push after each fix so the draft PR stays updated\n const fixGitResult = await commitAndPush(container, {\n branchName,\n ticketId: ticket.identifier,\n title: ticket.title,\n repoUrl: ticket.repoUrl,\n githubToken: config.github.token,\n branchPrefix: config.safety.branchPrefix,\n maxFileChanges: config.safety.maxFileChanges,\n });\n totalCommitCount += fixGitResult.commitCount;\n }\n\n if (lastFailures.length > 0) {\n // Validation still failing — leave PR as draft with warnings in body\n log.ticket(ticket.identifier, 'Validation still failing after max iterations — leaving PR as draft with warnings');\n await updatePRBody(octokit, {\n repoUrl: ticket.repoUrl,\n prNumber: pr.number,\n body: buildPRBody({ validationWarnings: lastFailures, commitCount: totalCommitCount }),\n });\n } else {\n // All validations passed — mark PR as ready for review\n await updatePRBody(octokit, {\n repoUrl: ticket.repoUrl,\n prNumber: pr.number,\n body: buildPRBody({ commitCount: totalCommitCount }),\n });\n await markPRReady(octokit, {\n repoUrl: ticket.repoUrl,\n prNumber: pr.number,\n });\n log.ticket(ticket.identifier, 'PR marked as ready for review');\n }\n }\n\n // 9. Update Linear ticket\n await completeTicket(linearClient, config, ticket.id, `PR opened: ${pr.url}`);\n\n // 10. Add branch label to ticket so child tickets can stack on it\n // e.g. child ticket adds label \"base:autoclawd/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 const result: WorkerResult = {\n ticketId: ticket.identifier,\n success: true,\n prUrl: pr.url,\n iterations: agentResult.iterations,\n };\n finishRun(ticket.identifier, 'success');\n updateRun(ticket.identifier, { pr_url: pr.url, branch: branchName, iterations: agentResult.iterations });\n recordRun(result, branchName);\n return result;\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 finishRun(ticket.identifier, 'failed', msg);\n const result: WorkerResult = {\n ticketId: ticket.identifier,\n success: false,\n error: msg,\n iterations: 0,\n };\n recordRun(result, branchName);\n return result;\n } finally {\n // 11. 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\n// --- PR fix: fetch failed CI checks, run Claude to fix them ---\n\nfunction buildFixPrompt(pr: { title: string; head: string }, failures: Array<{ name: string; log: string }>): string {\n const parts: string[] = [];\n\n parts.push(`## Task: Fix CI failures on PR \"${pr.title}\"`);\n parts.push('');\n parts.push(`Branch: ${pr.head}`);\n parts.push('');\n parts.push('The following CI checks are failing. Read the logs carefully, identify the root cause, fix the code, and make sure the fix is correct.');\n parts.push('');\n\n for (const f of failures) {\n parts.push(`### Failed check: ${f.name}`);\n parts.push('```');\n parts.push(f.log);\n parts.push('```');\n parts.push('');\n }\n\n parts.push('## Instructions');\n parts.push('- Start by reading CLAUDE.md if it exists');\n parts.push('- Read the failing test/lint/build output carefully before making changes');\n parts.push('- Fix the root cause, not just the symptoms');\n parts.push('- Run the failing command locally to verify your fix');\n parts.push('- Tests MUST import from actual source modules — never duplicate source code in tests');\n parts.push('- After fixing, run: git add -A && git commit -m \"fix: address CI failures\"');\n parts.push('- IMPORTANT: You MUST commit your changes with git before finishing');\n parts.push('- When all fixes are committed, include [autoclawd:done] in your final output');\n\n return parts.join('\\n');\n}\n\nexport interface FixResult {\n success: boolean;\n prUrl: string;\n error?: string;\n iterations: number;\n failedChecks: number;\n}\n\nexport async function fixPR(opts: {\n repoUrl: string;\n prNumber: number;\n config: Config;\n octokit: Octokit;\n}): Promise<FixResult> {\n const { repoUrl, prNumber, config, octokit } = opts;\n const prUrl = `${repoUrl}/pull/${prNumber}`;\n\n let workDir: string | undefined;\n let container: Container | undefined;\n\n try {\n // 1. Fetch PR metadata and failed checks\n const pr = await fetchPR(octokit, { repoUrl, prNumber });\n log.info(`PR #${prNumber}: \"${pr.title}\" (${pr.head} → ${pr.base})`);\n\n if (pr.state !== 'open') {\n return { success: false, prUrl, error: 'PR is not open', iterations: 0, failedChecks: 0 };\n }\n\n const failures = await fetchFailedChecks(octokit, { repoUrl, prNumber });\n if (failures.length === 0) {\n log.success('No failed CI checks — nothing to fix');\n return { success: true, prUrl, iterations: 0, failedChecks: 0 };\n }\n\n log.info(`Found ${failures.length} failed check(s): ${failures.map(f => f.name).join(', ')}`);\n\n // 2. Clone the PR branch\n workDir = await cloneToTemp(repoUrl, pr.head, config.github.token);\n log.info('Cloned PR branch');\n\n // 3. Load per-repo config\n const repoLocal = loadRepoLocalConfig(workDir);\n const { agent, docker } = mergeConfigs(config, repoLocal);\n\n // 4. Spin up container\n const containerName = `fix-pr-${prNumber}-${Date.now()}`.replace(/[^a-z0-9_.-]/g, '-');\n container = await createContainer({\n dockerConfig: docker,\n workspacePath: workDir,\n name: containerName,\n });\n\n await setupRepo(container, { branchName: pr.head });\n\n // 5. Run Claude with CI failure context\n const prompt = buildFixPrompt(pr, failures);\n const agentResult = await runAgentLoop({\n container,\n agentConfig: agent,\n prompt,\n ticketId: `PR-${prNumber}`,\n });\n\n // 6. Push fixes\n const gitResult = await commitAndPush(container, {\n branchName: pr.head,\n ticketId: `PR-${prNumber}`,\n title: 'Fix CI failures',\n repoUrl,\n githubToken: config.github.token,\n branchPrefix: config.safety.branchPrefix,\n maxFileChanges: config.safety.maxFileChanges,\n });\n\n if (!gitResult.pushed) {\n return { success: false, prUrl, error: 'No fix produced', iterations: agentResult.iterations, failedChecks: failures.length };\n }\n\n log.success(`Pushed ${gitResult.commitCount} fix commit(s) to ${pr.head}`);\n return { success: true, prUrl, iterations: agentResult.iterations, failedChecks: failures.length };\n } catch (err) {\n const msg = err instanceof Error ? err.message : String(err);\n log.error(`Fix failed: ${msg}`);\n return { success: false, prUrl, error: msg, iterations: 0, failedChecks: 0 };\n } finally {\n if (container) await destroyContainer(container);\n if (workDir) {\n try { rmSync(workDir, { recursive: true, force: true }); } catch { /* best effort */ }\n }\n }\n}\n","import Database from 'better-sqlite3';\nimport { join } from 'node:path';\nimport { mkdirSync, existsSync } from 'node:fs';\nimport { CONFIG_DIR } from './config.js';\nimport type { Ticket } from './linear.js';\n\nconst DB_PATH = join(CONFIG_DIR, 'autoclawd.db');\n\nexport type RunStatus = 'queued' | 'running' | 'success' | 'failed';\n\nexport interface Run {\n id: string;\n ticket_id: string;\n status: RunStatus;\n branch: string | null;\n pr_url: string | null;\n started_at: string;\n finished_at: string | null;\n error: string | null;\n iterations: number;\n model: string | null;\n image: string | null;\n duration_secs: number | null;\n}\n\nexport interface QueueEntry {\n id: number;\n ticket_id: string;\n payload: string; // JSON-encoded Ticket\n created_at: string;\n}\n\nlet _db: Database.Database | undefined;\n\nexport function getDb(): Database.Database {\n if (_db) return _db;\n if (!existsSync(CONFIG_DIR)) {\n mkdirSync(CONFIG_DIR, { recursive: true });\n }\n _db = new Database(DB_PATH);\n _db.pragma('journal_mode = WAL');\n _db.exec(`\n CREATE TABLE IF NOT EXISTS runs (\n id TEXT PRIMARY KEY,\n ticket_id TEXT NOT NULL,\n status TEXT NOT NULL DEFAULT 'queued',\n branch TEXT,\n pr_url TEXT,\n started_at TEXT NOT NULL DEFAULT (datetime('now')),\n finished_at TEXT,\n error TEXT,\n iterations INTEGER NOT NULL DEFAULT 0,\n model TEXT,\n image TEXT,\n duration_secs INTEGER\n );\n CREATE TABLE IF NOT EXISTS queue (\n id INTEGER PRIMARY KEY AUTOINCREMENT,\n ticket_id TEXT NOT NULL,\n payload TEXT NOT NULL,\n created_at TEXT NOT NULL DEFAULT (datetime('now'))\n );\n `);\n // Migrate: add columns if missing (for databases created before this version)\n const cols = _db.prepare(\"PRAGMA table_info(runs)\").all() as Array<{ name: string }>;\n const colNames = new Set(cols.map((c) => c.name));\n if (!colNames.has('model')) _db.exec('ALTER TABLE runs ADD COLUMN model TEXT');\n if (!colNames.has('image')) _db.exec('ALTER TABLE runs ADD COLUMN image TEXT');\n if (!colNames.has('duration_secs')) _db.exec('ALTER TABLE runs ADD COLUMN duration_secs INTEGER');\n\n return _db;\n}\n\nexport function closeDb(): void {\n _db?.close();\n _db = undefined;\n}\n\n// --- Runs helpers ---\n\nexport function insertRun(ticketId: string, status: RunStatus = 'running'): void {\n const db = getDb();\n db.prepare(\n 'INSERT OR REPLACE INTO runs (id, ticket_id, status, started_at) VALUES (?, ?, ?, datetime(\\'now\\'))'\n ).run(ticketId, ticketId, status);\n}\n\nexport function updateRun(\n ticketId: string,\n update: Partial<Pick<Run, 'status' | 'branch' | 'pr_url' | 'error' | 'iterations' | 'finished_at' | 'model' | 'image' | 'duration_secs'>>,\n): void {\n const db = getDb();\n const sets: string[] = [];\n const values: unknown[] = [];\n for (const [key, val] of Object.entries(update)) {\n sets.push(`${key} = ?`);\n values.push(val);\n }\n if (sets.length === 0) return;\n values.push(ticketId);\n db.prepare(`UPDATE runs SET ${sets.join(', ')} WHERE id = ?`).run(...values);\n}\n\nexport function finishRun(ticketId: string, status: 'success' | 'failed', error?: string): void {\n updateRun(ticketId, { status, finished_at: new Date().toISOString(), error: error ?? null });\n}\n\nexport function getRunByTicketId(ticketId: string): Run | undefined {\n const db = getDb();\n return db.prepare('SELECT * FROM runs WHERE ticket_id = ?').get(ticketId) as Run | undefined;\n}\n\nexport function getActiveRuns(): Run[] {\n const db = getDb();\n return db.prepare(\"SELECT * FROM runs WHERE status = 'running'\").all() as Run[];\n}\n\nexport function isTicketProcessed(ticketId: string): boolean {\n const db = getDb();\n const row = db.prepare(\n \"SELECT 1 FROM runs WHERE ticket_id = ? AND status IN ('success', 'failed')\"\n ).get(ticketId);\n return !!row;\n}\n\nexport function isTicketActive(ticketId: string): boolean {\n const db = getDb();\n const row = db.prepare(\n \"SELECT 1 FROM runs WHERE ticket_id = ? AND status = 'running'\"\n ).get(ticketId);\n return !!row;\n}\n\n// --- Queue helpers ---\n\nexport function enqueue(ticket: Ticket): void {\n const db = getDb();\n db.prepare('INSERT INTO queue (ticket_id, payload) VALUES (?, ?)').run(\n ticket.id,\n JSON.stringify(ticket),\n );\n}\n\nexport function dequeue(): Ticket | undefined {\n const db = getDb();\n const row = db.prepare('SELECT * FROM queue ORDER BY id ASC LIMIT 1').get() as QueueEntry | undefined;\n if (!row) return undefined;\n db.prepare('DELETE FROM queue WHERE id = ?').run(row.id);\n return JSON.parse(row.payload) as Ticket;\n}\n\nexport function removeFromQueue(ticketId: string): void {\n const db = getDb();\n db.prepare('DELETE FROM queue WHERE ticket_id = ?').run(ticketId);\n}\n\nexport function getQueueLength(): number {\n const db = getDb();\n const row = db.prepare('SELECT COUNT(*) as count FROM queue').get() as { count: number };\n return row.count;\n}\n\nexport function getQueuedTickets(): Ticket[] {\n const db = getDb();\n const rows = db.prepare('SELECT * FROM queue ORDER BY id ASC').all() as QueueEntry[];\n return rows.map((r) => JSON.parse(r.payload) as Ticket);\n}\n\n// --- History queries ---\n\nexport function queryRuns(opts?: { limit?: number; failedOnly?: boolean }): Run[] {\n const db = getDb();\n const limit = opts?.limit ?? 20;\n const failedOnly = opts?.failedOnly ?? false;\n\n const where = failedOnly ? \"WHERE status = 'failed'\" : '';\n return db.prepare(\n `SELECT * FROM runs ${where} ORDER BY started_at DESC LIMIT ?`\n ).all(limit) as Run[];\n}\n\nexport function countRuns(): number {\n const db = getDb();\n const row = db.prepare('SELECT COUNT(*) as count FROM runs').get() as { count: number };\n return row.count;\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 type { Config } from './config.js';\nimport type { Ticket } from './linear.js';\nimport { pollTickets } from './linear.js';\nimport { executeTicket } from './worker.js';\nimport type { LinearClient } from '@linear/sdk';\nimport type { Octokit } from '@octokit/rest';\nimport { log } from './logger.js';\nimport {\n getDb,\n closeDb,\n insertRun,\n finishRun,\n isTicketActive,\n isTicketProcessed,\n getActiveRuns,\n enqueue,\n dequeue,\n getQueueLength,\n getQueuedTickets,\n removeFromQueue,\n} from './db.js';\n\nexport interface WatchOptions {\n config: Config;\n linearClient: LinearClient;\n octokit: Octokit;\n intervalSeconds: number;\n once: boolean;\n}\n\nexport class Watcher {\n private activeInMemory = new Set<string>();\n private timer: ReturnType<typeof setInterval> | undefined;\n private stopped = false;\n\n constructor(\n private config: Config,\n private linearClient: LinearClient,\n private octokit: Octokit,\n ) {}\n\n async start(intervalSeconds: number, once: boolean): Promise<void> {\n getDb();\n this.resumeQueue();\n\n // Run first poll immediately\n await this.poll();\n\n if (once) {\n // Wait for all active tickets to finish before exiting\n await this.waitForActive();\n closeDb();\n return;\n }\n\n this.timer = setInterval(() => {\n if (!this.stopped) {\n void this.poll();\n }\n }, intervalSeconds * 1000);\n\n log.info(`Polling every ${intervalSeconds}s (Ctrl+C to stop)`);\n }\n\n stop(): void {\n this.stopped = true;\n if (this.timer) {\n clearInterval(this.timer);\n this.timer = undefined;\n }\n closeDb();\n log.info('Watcher stopped');\n }\n\n private resumeQueue(): void {\n const staleRuns = getActiveRuns();\n for (const run of staleRuns) {\n log.warn(`${run.ticket_id}: was running at shutdown, marking as failed`);\n finishRun(run.ticket_id, 'failed', 'Unclean shutdown — process restarted');\n }\n\n const queued = getQueuedTickets();\n if (queued.length > 0) {\n log.info(`Resuming ${queued.length} queued ticket(s) from database`);\n for (const ticket of queued) {\n removeFromQueue(ticket.id);\n if (this.activeInMemory.size >= this.config.maxConcurrent) {\n enqueue(ticket);\n break;\n }\n this.dispatch(ticket);\n }\n }\n }\n\n private async poll(): Promise<void> {\n try {\n const tickets = await pollTickets(this.linearClient, this.config);\n const newTickets = tickets.filter((t) => this.isNewTicket(t));\n\n log.info(`Poll: ${tickets.length} ticket(s) found, ${newTickets.length} new`);\n\n for (const ticket of newTickets) {\n if (!ticket.repoUrl) {\n log.warn(`${ticket.identifier}: no repo: label, skipping`);\n continue;\n }\n\n if (this.activeInMemory.size >= this.config.maxConcurrent) {\n log.info(`${ticket.identifier}: at capacity (${this.activeInMemory.size}/${this.config.maxConcurrent}), queued`);\n enqueue(ticket);\n continue;\n }\n\n this.dispatch(ticket);\n }\n } catch (err) {\n log.error(`Poll failed: ${err instanceof Error ? err.message : err}`);\n }\n }\n\n private isNewTicket(ticket: Ticket): boolean {\n if (this.activeInMemory.has(ticket.id)) return false;\n if (isTicketActive(ticket.id)) return false;\n if (isTicketProcessed(ticket.id)) return false;\n return true;\n }\n\n private dispatch(ticket: Ticket): void {\n this.activeInMemory.add(ticket.id);\n insertRun(ticket.id, 'running');\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 }).then(\n () => {\n finishRun(ticket.id, 'success');\n },\n (err: Error) => {\n finishRun(ticket.id, 'failed', err.message);\n },\n ).finally(() => {\n this.activeInMemory.delete(ticket.id);\n this.drainQueue();\n });\n }\n\n private drainQueue(): void {\n while (this.activeInMemory.size < this.config.maxConcurrent) {\n const next = dequeue();\n if (!next) break;\n if (this.activeInMemory.has(next.id)) continue;\n log.ticket(next.identifier, `Dequeued (${getQueueLength()} remaining)`);\n this.dispatch(next);\n }\n }\n\n private waitForActive(): Promise<void> {\n if (this.activeInMemory.size === 0) return Promise.resolve();\n return new Promise((resolve) => {\n const check = setInterval(() => {\n if (this.activeInMemory.size === 0) {\n clearInterval(check);\n resolve();\n }\n }, 1000);\n });\n }\n}\n","import { readFileSync, existsSync } from 'node:fs';\nimport { join } from 'node:path';\nimport { homedir } from 'node:os';\nimport chalk from 'chalk';\nimport { getDb, queryRuns, countRuns } from './db.js';\nimport type { Run } from './db.js';\n\nexport interface HistoryRecord {\n ticketId: string;\n status: 'success' | 'failure';\n branch: string;\n prUrl?: string;\n error?: string;\n iterations: number;\n model: string;\n image: string;\n startedAt: string;\n finishedAt: string;\n durationSecs: number;\n}\n\nconst HISTORY_DIR = join(homedir(), '.autoclawd');\nconst HISTORY_FILE = join(HISTORY_DIR, 'history.jsonl');\n\n/** Convert a SQLite Run row to a HistoryRecord for display. */\nfunction runToRecord(run: Run): HistoryRecord {\n return {\n ticketId: run.ticket_id,\n status: run.status === 'failed' ? 'failure' : 'success',\n branch: run.branch ?? '',\n prUrl: run.pr_url ?? undefined,\n error: run.error ?? undefined,\n iterations: run.iterations,\n model: run.model ?? '',\n image: run.image ?? '',\n startedAt: run.started_at,\n finishedAt: run.finished_at ?? '',\n durationSecs: run.duration_secs ?? 0,\n };\n}\n\n/** Read history from SQLite runs table. */\nexport function readHistory(opts?: {\n limit?: number;\n failedOnly?: boolean;\n}): HistoryRecord[] {\n const runs = queryRuns(opts);\n return runs.map(runToRecord);\n}\n\n/**\n * Migrate legacy history.jsonl records into SQLite.\n * Called once on first startup — uses INSERT OR IGNORE so it's idempotent.\n */\nexport function migrateJsonlToSqlite(): number {\n if (!existsSync(HISTORY_FILE)) return 0;\n\n // Only migrate if the runs table is empty\n if (countRuns() > 0) return 0;\n\n const lines = readFileSync(HISTORY_FILE, 'utf-8')\n .split('\\n')\n .filter(Boolean);\n\n if (lines.length === 0) return 0;\n\n const db = getDb();\n const insert = db.prepare(\n `INSERT OR IGNORE INTO runs (id, ticket_id, status, branch, pr_url, started_at, finished_at, error, iterations, model, image, duration_secs)\n VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)`\n );\n\n const tx = db.transaction(() => {\n let count = 0;\n for (const line of lines) {\n try {\n const r = JSON.parse(line) as HistoryRecord;\n // Map 'failure' -> 'failed' for SQLite status convention\n const status = r.status === 'failure' ? 'failed' : r.status;\n insert.run(\n r.ticketId,\n r.ticketId,\n status,\n r.branch || null,\n r.prUrl || null,\n r.startedAt,\n r.finishedAt || null,\n r.error || null,\n r.iterations,\n r.model || null,\n r.image || null,\n r.durationSecs ?? null,\n );\n count++;\n } catch {\n // Skip malformed lines\n }\n }\n return count;\n });\n\n return tx();\n}\n\nfunction formatDuration(secs: number): string {\n if (secs < 60) return `${secs}s`;\n const m = Math.floor(secs / 60);\n const s = secs % 60;\n if (m < 60) return `${m}m ${s}s`;\n const h = Math.floor(m / 60);\n return `${h}h ${m % 60}m`;\n}\n\nfunction formatTime(iso: string): string {\n return iso.replace('T', ' ').slice(0, 19);\n}\n\nfunction pad(s: string, len: number): string {\n return s.length >= len ? s.slice(0, len) : s + ' '.repeat(len - s.length);\n}\n\nexport function printHistoryTable(records: HistoryRecord[]): void {\n if (records.length === 0) {\n console.log('No history records found.');\n return;\n }\n\n // Header\n const header = `${pad('Ticket', 14)} ${pad('Status', 10)} ${pad('PR', 50)} ${pad('Duration', 10)} ${pad('Time', 20)}`;\n console.log(chalk.bold(header));\n console.log('-'.repeat(header.length));\n\n for (const r of records) {\n const status = r.status === 'success'\n ? chalk.green(pad('success', 10))\n : chalk.red(pad('failure', 10));\n const pr = pad(r.prUrl ?? (r.error ? r.error.slice(0, 48) : '-'), 50);\n const dur = pad(formatDuration(r.durationSecs), 10);\n const time = pad(formatTime(r.startedAt), 20);\n\n console.log(`${pad(r.ticketId, 14)} ${status} ${pr} ${dur} ${time}`);\n }\n}\n\nexport { HISTORY_FILE };\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","log","homedir","join","existsSync","readFileSync","homedir","join","existsSync","readFileSync","sleep","join","join","mkdirSync","existsSync","join","existsSync","mkdirSync","join","docker","result","opts","ticket","readFileSync","existsSync","join","homedir","chalk","join","homedir","existsSync","readFileSync","chalk","execSync","existsSync","join","homedir","execSync","existsSync","join","homedir","existsSync","mkdirSync","writeFileSync","readFileSync","execSync","spawn","join","homedir","LinearClient","Octokit","require"]}
|