@autoclawd/autoclawd 1.1.2 → 1.1.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 CHANGED
@@ -712,120 +712,16 @@ import { PassThrough } from "stream";
712
712
  import { homedir as homedir3, platform } from "os";
713
713
  import { join as join4 } from "path";
714
714
  import { existsSync as existsSync3, readFileSync as readFileSync2 } from "fs";
715
- import { execSync as execSync2 } from "child_process";
716
715
  var docker = new Docker();
717
- function sleep2(ms) {
718
- return new Promise((r) => setTimeout(r, ms));
719
- }
720
- async function tryStartDocker() {
721
- const os = platform();
722
- if (os === "darwin") {
723
- if (existsSync3("/Applications/Docker.app")) {
724
- log.info("Docker not running \u2014 starting Docker Desktop...");
725
- try {
726
- execSync2("open -a Docker", { stdio: "pipe" });
727
- } catch {
728
- return false;
729
- }
730
- } else {
731
- return false;
732
- }
733
- } else if (os === "linux") {
734
- log.info("Docker not running \u2014 attempting to start...");
735
- try {
736
- execSync2("sudo systemctl start docker 2>/dev/null || sudo service docker start 2>/dev/null", {
737
- stdio: "pipe",
738
- timeout: 3e4
739
- });
740
- } catch {
741
- return false;
742
- }
743
- } else {
744
- return false;
745
- }
746
- for (let i = 0; i < 30; i++) {
747
- await sleep2(1e3);
748
- try {
749
- await docker.ping();
750
- log.success("Docker started");
751
- return true;
752
- } catch {
753
- }
754
- if (i > 0 && i % 5 === 0) {
755
- log.info(`Waiting for Docker daemon... (${i}s)`);
756
- }
757
- }
758
- return false;
759
- }
760
- async function tryInstallDocker() {
761
- const os = platform();
762
- if (os === "darwin") {
763
- try {
764
- execSync2("which brew", { stdio: "pipe" });
765
- } catch {
766
- log.warn("Docker not installed and Homebrew not found \u2014 cannot auto-install");
767
- return false;
768
- }
769
- log.info("Docker not installed \u2014 installing via Homebrew (this may take a few minutes)...");
770
- try {
771
- execSync2("brew install --cask docker", { stdio: "inherit", timeout: 6e5 });
772
- log.success("Docker Desktop installed");
773
- return true;
774
- } catch {
775
- log.warn("Docker install via Homebrew failed");
776
- return false;
777
- }
778
- } else if (os === "linux") {
779
- const cmds = [
780
- { check: "apt-get", install: "sudo apt-get update -qq && sudo apt-get install -y docker.io && sudo systemctl enable docker" },
781
- { check: "dnf", install: "sudo dnf install -y docker && sudo systemctl enable docker" },
782
- { check: "yum", install: "sudo yum install -y docker && sudo systemctl enable docker" },
783
- { check: "pacman", install: "sudo pacman -Sy --noconfirm docker && sudo systemctl enable docker" }
784
- ];
785
- for (const { check, install } of cmds) {
786
- try {
787
- execSync2(`which ${check}`, { stdio: "pipe" });
788
- log.info(`Docker not installed \u2014 installing via ${check}...`);
789
- execSync2(install, { stdio: "inherit", timeout: 3e5 });
790
- log.success("Docker installed");
791
- return true;
792
- } catch {
793
- }
794
- }
795
- return false;
796
- }
797
- return false;
798
- }
799
716
  async function checkDockerAvailable() {
800
717
  try {
801
718
  await docker.ping();
802
- return;
803
- } catch {
804
- }
805
- const started = await tryStartDocker();
806
- if (started) return;
807
- let installed = false;
808
- try {
809
- execSync2("which docker", { stdio: "pipe" });
810
- installed = true;
811
719
  } catch {
812
- }
813
- if (installed) {
814
- throw new Error(
815
- "Docker is installed but the daemon is not running and could not be started automatically.\nStart it manually:\n" + (platform() === "darwin" ? " open -a Docker\n" : " sudo systemctl start docker\n")
816
- );
817
- }
818
- const didInstall = await tryInstallDocker();
819
- if (didInstall) {
820
- const started2 = await tryStartDocker();
821
- if (started2) return;
720
+ const isMac = platform() === "darwin";
822
721
  throw new Error(
823
- "Docker was installed but could not be started.\n" + (platform() === "darwin" ? "Open Docker Desktop from Applications and try again.\n" : "Run: sudo systemctl start docker\n")
722
+ "Cannot connect to Docker daemon.\n\n" + (isMac ? "Install: brew install --cask docker\nStart: open -a Docker\n" : "Install: https://docs.docker.com/get-docker/\nStart: sudo systemctl start docker\n")
824
723
  );
825
724
  }
826
- throw new Error(
827
- "Docker is not installed and could not be auto-installed.\n" + (platform() === "darwin" ? "Install manually: brew install --cask docker\n" : "Install manually: https://docs.docker.com/get-docker/\n")
828
- );
829
725
  }
830
726
  async function ensureImage(image) {
831
727
  try {
@@ -1218,7 +1114,7 @@ async function runAgentLoop(opts) {
1218
1114
  }
1219
1115
  const waitMs = estimateResetMs(combined);
1220
1116
  log.ticket(ticketId, `Rate limited (${rateLimitRetries}/${MAX_RATE_LIMIT_RETRIES}) \u2014 pausing ${Math.round(waitMs / 1e3)}s`);
1221
- await sleep3(waitMs);
1117
+ await sleep2(waitMs);
1222
1118
  i--;
1223
1119
  continue;
1224
1120
  }
@@ -1229,7 +1125,7 @@ async function runAgentLoop(opts) {
1229
1125
  log.ticket(ticketId, `Max iterations (${agentConfig.maxIterations}) reached`);
1230
1126
  return { iterations: agentConfig.maxIterations, success: false, lastOutput };
1231
1127
  }
1232
- function sleep3(ms) {
1128
+ function sleep2(ms) {
1233
1129
  return new Promise((resolve) => setTimeout(resolve, ms));
1234
1130
  }
1235
1131
 
@@ -1303,7 +1199,7 @@ async function commitAndPush(container, opts) {
1303
1199
  import { mkdtempSync as mkdtempSync2, rmSync as rmSync2, writeFileSync as writeFileSync2 } from "fs";
1304
1200
  import { join as join6 } from "path";
1305
1201
  import { tmpdir as tmpdir2 } from "os";
1306
- import { execSync as execSync3 } from "child_process";
1202
+ import { execSync as execSync2 } from "child_process";
1307
1203
 
1308
1204
  // src/db.ts
1309
1205
  import Database from "better-sqlite3";
@@ -1491,7 +1387,7 @@ function detectDefaultBranch2(repoUrl, githubToken) {
1491
1387
  const askpass = createAskpass2(githubToken);
1492
1388
  const authedUrl = repoUrl.replace("https://", "https://x-access-token@");
1493
1389
  try {
1494
- const output = execSync3(
1390
+ const output = execSync2(
1495
1391
  `git ls-remote --symref -- ${authedUrl} HEAD`,
1496
1392
  { stdio: "pipe", timeout: 3e4, env: gitEnv2(askpass.path), encoding: "utf-8" }
1497
1393
  );
@@ -1515,14 +1411,14 @@ async function pushScaffold(opts) {
1515
1411
  }
1516
1412
  writeFileSync2(join6(scaffoldDir, "README.md"), readmeLines.join("\n") + "\n");
1517
1413
  writeFileSync2(join6(scaffoldDir, ".autoclawd.yaml"), "base: main\n");
1518
- execSync3("git init", { cwd: scaffoldDir, stdio: "pipe", env });
1519
- execSync3("git checkout -b main", { cwd: scaffoldDir, stdio: "pipe", env });
1520
- execSync3('git config user.email "autoclawd@users.noreply.github.com"', { cwd: scaffoldDir, stdio: "pipe", env });
1521
- execSync3('git config user.name "autoclawd"', { cwd: scaffoldDir, stdio: "pipe", env });
1522
- execSync3("git add .", { cwd: scaffoldDir, stdio: "pipe", env });
1523
- execSync3('git commit -m "chore: initial scaffold"', { cwd: scaffoldDir, stdio: "pipe", env });
1524
- execSync3(`git remote add origin ${authedUrl}`, { cwd: scaffoldDir, stdio: "pipe", env });
1525
- execSync3("git push -u origin main", { cwd: scaffoldDir, stdio: "pipe", timeout: 6e4, env });
1414
+ execSync2("git init", { cwd: scaffoldDir, stdio: "pipe", env });
1415
+ execSync2("git checkout -b main", { cwd: scaffoldDir, stdio: "pipe", env });
1416
+ execSync2('git config user.email "autoclawd@users.noreply.github.com"', { cwd: scaffoldDir, stdio: "pipe", env });
1417
+ execSync2('git config user.name "autoclawd"', { cwd: scaffoldDir, stdio: "pipe", env });
1418
+ execSync2("git add .", { cwd: scaffoldDir, stdio: "pipe", env });
1419
+ execSync2('git commit -m "chore: initial scaffold"', { cwd: scaffoldDir, stdio: "pipe", env });
1420
+ execSync2(`git remote add origin ${authedUrl}`, { cwd: scaffoldDir, stdio: "pipe", env });
1421
+ execSync2("git push -u origin main", { cwd: scaffoldDir, stdio: "pipe", timeout: 6e4, env });
1526
1422
  } finally {
1527
1423
  rmSync2(scaffoldDir, { recursive: true, force: true });
1528
1424
  rmSync2(askpass.dir, { recursive: true, force: true });
@@ -1535,7 +1431,7 @@ async function cloneToTemp(repoUrl, baseBranch, githubToken) {
1535
1431
  const askpass = createAskpass2(githubToken);
1536
1432
  const authedUrl = repoUrl.replace("https://", "https://x-access-token@");
1537
1433
  try {
1538
- execSync3(`git clone --depth=50 -b ${baseBranch} -- ${authedUrl} ${workDir}`, {
1434
+ execSync2(`git clone --depth=50 -b ${baseBranch} -- ${authedUrl} ${workDir}`, {
1539
1435
  stdio: "pipe",
1540
1436
  timeout: 12e4,
1541
1437
  env: gitEnv2(askpass.path)
@@ -1712,7 +1608,7 @@ async function executeTicket(opts) {
1712
1608
  throw err;
1713
1609
  }
1714
1610
  }
1715
- execSync3(`git checkout -B ${branchName} --`, { cwd: workDir, stdio: "pipe" });
1611
+ execSync2(`git checkout -B ${branchName} --`, { cwd: workDir, stdio: "pipe" });
1716
1612
  container = await createContainer({
1717
1613
  dockerConfig: docker2,
1718
1614
  workspacePath: workDir,
@@ -2501,131 +2397,38 @@ function printHistoryTable(records) {
2501
2397
  }
2502
2398
 
2503
2399
  // src/deps.ts
2504
- import { execSync as execSync4 } from "child_process";
2400
+ import { execSync as execSync3 } from "child_process";
2505
2401
  import { existsSync as existsSync6 } from "fs";
2506
2402
  import { join as join8 } from "path";
2507
2403
  import { homedir as homedir5 } from "os";
2508
- function detectPackageManager() {
2509
- const checks = [
2510
- ["apt", "apt-get"],
2511
- ["dnf", "dnf"],
2512
- ["yum", "yum"],
2513
- ["pacman", "pacman"],
2514
- ["apk", "apk"],
2515
- ["brew", "brew"]
2516
- ];
2517
- for (const [name, cmd] of checks) {
2518
- try {
2519
- execSync4(`which ${cmd}`, { stdio: "pipe" });
2520
- return name;
2521
- } catch {
2522
- }
2523
- }
2524
- return "unknown";
2525
- }
2526
- var DOCKER_INSTALL = {
2527
- apt: [
2528
- "apt-get update -qq",
2529
- "apt-get install -y docker.io",
2530
- "systemctl enable docker",
2531
- "systemctl start docker"
2532
- ],
2533
- dnf: [
2534
- "dnf install -y docker",
2535
- "systemctl enable docker",
2536
- "systemctl start docker"
2537
- ],
2538
- yum: [
2539
- "yum install -y docker",
2540
- "systemctl enable docker",
2541
- "systemctl start docker"
2542
- ],
2543
- pacman: [
2544
- "pacman -Sy --noconfirm docker",
2545
- "systemctl enable docker",
2546
- "systemctl start docker"
2547
- ],
2548
- apk: [
2549
- "apk add docker",
2550
- "rc-update add docker boot",
2551
- "service docker start"
2552
- ],
2553
- brew: [
2554
- "brew install --cask docker"
2555
- ],
2556
- unknown: []
2557
- };
2558
- var CLOUDFLARED_INSTALL = {
2559
- apt: [
2560
- "apt-get update -qq",
2561
- '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)'
2562
- ],
2563
- dnf: ["dnf install -y cloudflared || npm install -g cloudflared"],
2564
- yum: ["yum install -y cloudflared || npm install -g cloudflared"],
2565
- pacman: ["pacman -Sy --noconfirm cloudflared"],
2566
- apk: ["apk add cloudflared"],
2567
- brew: ["brew install cloudflared"],
2568
- unknown: []
2569
- };
2570
2404
  function checkDeps() {
2571
- const pm = detectPackageManager();
2572
- const needsSudo = pm !== "brew" && pm !== "unknown" && process.getuid?.() !== 0;
2573
- const sudo = needsSudo ? "sudo " : "";
2574
2405
  return [
2575
2406
  {
2576
2407
  name: "Docker",
2577
2408
  installed: commandExists("docker"),
2578
2409
  running: isDockerRunning(),
2579
- installable: pm !== "unknown",
2580
- installCommands: DOCKER_INSTALL[pm].map((c) => `${sudo}${c}`),
2581
- manualInstructions: "https://docs.docker.com/get-docker/"
2410
+ instructions: process.platform === "darwin" ? "brew install --cask docker && open -a Docker" : "https://docs.docker.com/get-docker/"
2582
2411
  },
2583
2412
  {
2584
2413
  name: "Claude Code",
2585
2414
  installed: commandExists("claude"),
2586
- installable: true,
2587
- installCommands: ["curl -fsSL https://claude.ai/install.sh | bash"],
2588
- manualInstructions: "curl -fsSL https://claude.ai/install.sh | bash"
2415
+ instructions: "curl -fsSL https://claude.ai/install.sh | bash\n Then run: claude (to log in)"
2589
2416
  },
2590
2417
  {
2591
2418
  name: "Claude credentials",
2592
2419
  installed: existsSync6(join8(homedir5(), ".claude", ".credentials.json")),
2593
- installable: false,
2594
- installCommands: [],
2595
- manualInstructions: 'Run "claude" and complete the login flow'
2420
+ instructions: "Run: claude (and complete the login flow)"
2596
2421
  },
2597
2422
  {
2598
2423
  name: "cloudflared",
2599
2424
  installed: commandExists("cloudflared"),
2600
- installable: pm !== "unknown",
2601
- installCommands: CLOUDFLARED_INSTALL[pm].map((c) => `${sudo}${c}`),
2602
- manualInstructions: "https://developers.cloudflare.com/cloudflare-one/connections/connect-networks/downloads/"
2425
+ instructions: process.platform === "darwin" ? "brew install cloudflared" : "https://developers.cloudflare.com/cloudflare-one/connections/connect-networks/downloads/"
2603
2426
  }
2604
2427
  ];
2605
2428
  }
2606
- function installDep(dep) {
2607
- if (dep.installCommands.length === 0) return false;
2608
- for (const cmd of dep.installCommands) {
2609
- try {
2610
- execSync4(cmd, { stdio: "inherit", timeout: 3e5 });
2611
- } catch {
2612
- return false;
2613
- }
2614
- }
2615
- return true;
2616
- }
2617
- function addUserToDockerGroup() {
2618
- if (process.platform !== "linux") return;
2619
- try {
2620
- const user = execSync4("whoami", { encoding: "utf-8" }).trim();
2621
- execSync4(`sudo usermod -aG docker ${user}`, { stdio: "pipe" });
2622
- log.info(`Added ${user} to docker group \u2014 log out and back in to apply`);
2623
- } catch {
2624
- }
2625
- }
2626
2429
  function commandExists(cmd) {
2627
2430
  try {
2628
- execSync4(`which ${cmd}`, { stdio: "pipe" });
2431
+ execSync3(`which ${cmd}`, { stdio: "pipe" });
2629
2432
  return true;
2630
2433
  } catch {
2631
2434
  return false;
@@ -2633,7 +2436,7 @@ function commandExists(cmd) {
2633
2436
  }
2634
2437
  function isDockerRunning() {
2635
2438
  try {
2636
- execSync4("docker info", { stdio: "pipe", timeout: 1e4 });
2439
+ execSync3("docker info", { stdio: "pipe", timeout: 1e4 });
2637
2440
  return true;
2638
2441
  } catch {
2639
2442
  return false;
@@ -2642,7 +2445,7 @@ function isDockerRunning() {
2642
2445
 
2643
2446
  // src/index.ts
2644
2447
  import { existsSync as existsSync7, mkdirSync as mkdirSync3, writeFileSync as writeFileSync3, readFileSync as readFileSync4, unlinkSync } from "fs";
2645
- import { execSync as execSync5, spawn as spawn2 } from "child_process";
2448
+ import { execSync as execSync4, spawn as spawn2 } from "child_process";
2646
2449
  import { createInterface } from "readline";
2647
2450
  import { join as join9 } from "path";
2648
2451
  import { homedir as homedir6 } from "os";
@@ -3060,51 +2863,22 @@ program.command("init").description("Set up autoclawd interactively").action(asy
3060
2863
  console.log("\n autoclawd setup\n");
3061
2864
  console.log(" Checking dependencies...\n");
3062
2865
  const deps = checkDeps();
3063
- const stillMissing = [];
2866
+ const missing = [];
3064
2867
  for (const dep of deps) {
3065
2868
  if (dep.installed && dep.running !== false) {
3066
2869
  log.success(`${dep.name}`);
3067
- continue;
3068
- }
3069
- if (dep.installed && dep.running === false) {
2870
+ } else if (dep.installed && dep.running === false) {
3070
2871
  log.warn(`${dep.name} \u2014 installed but not running`);
3071
- stillMissing.push(`${dep.name} (needs restart)`);
3072
- continue;
3073
- }
3074
- if (dep.installable && dep.installCommands.length > 0) {
3075
- const answer = await ask(` ${dep.name} not found. Install? (Y/n)`, "Y");
3076
- if (answer.toLowerCase() !== "n") {
3077
- console.log(`
3078
- Installing ${dep.name} via system package manager...
3079
- `);
3080
- const ok = installDep(dep);
3081
- if (ok) {
3082
- log.success(`${dep.name} installed`);
3083
- if (dep.name === "Docker") addUserToDockerGroup();
3084
- if (dep.name === "Claude Code") {
3085
- console.log('\n Run "claude" in your terminal to log in, then re-run: autoclawd init\n');
3086
- stillMissing.push("Claude Code login");
3087
- }
3088
- } else {
3089
- log.error(`${dep.name} install failed`);
3090
- console.log(` Install manually: ${dep.manualInstructions}`);
3091
- stillMissing.push(dep.name);
3092
- }
3093
- } else {
3094
- console.log(` Install manually: ${dep.manualInstructions}`);
3095
- stillMissing.push(dep.name);
3096
- }
3097
- } else if (dep.name === "Claude credentials") {
3098
- log.warn(`${dep.name} \u2014 run "claude" to log in`);
3099
- stillMissing.push(dep.name);
2872
+ missing.push(dep.name);
3100
2873
  } else {
3101
- log.warn(`${dep.name} \u2014 ${dep.manualInstructions}`);
3102
- stillMissing.push(dep.name);
2874
+ log.error(`${dep.name} \u2014 not installed`);
2875
+ console.log(` ${dep.instructions}`);
2876
+ missing.push(dep.name);
3103
2877
  }
3104
2878
  }
3105
- if (stillMissing.length > 0) {
2879
+ if (missing.length > 0) {
3106
2880
  console.log(`
3107
- Continuing setup \u2014 install ${stillMissing.join(", ")} before running.
2881
+ Install the above dependencies before running autoclawd.
3108
2882
  `);
3109
2883
  } else {
3110
2884
  console.log("");
@@ -3148,7 +2922,7 @@ program.command("init").description("Set up autoclawd interactively").action(asy
3148
2922
  }
3149
2923
  let ghToken = "";
3150
2924
  try {
3151
- ghToken = execSync5("gh auth token", { encoding: "utf-8" }).trim();
2925
+ ghToken = execSync4("gh auth token", { encoding: "utf-8" }).trim();
3152
2926
  log.success(`GitHub token detected from gh CLI`);
3153
2927
  } catch {
3154
2928
  ghToken = await ask("GitHub personal access token");