@autoclawd/autoclawd 1.1.2 → 1.1.4
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 +56 -257
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
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
719
|
} 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
|
-
} catch {
|
|
812
|
-
}
|
|
813
|
-
if (installed) {
|
|
720
|
+
const isMac = platform() === "darwin";
|
|
814
721
|
throw new Error(
|
|
815
|
-
"
|
|
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")
|
|
816
723
|
);
|
|
817
724
|
}
|
|
818
|
-
const didInstall = await tryInstallDocker();
|
|
819
|
-
if (didInstall) {
|
|
820
|
-
const started2 = await tryStartDocker();
|
|
821
|
-
if (started2) return;
|
|
822
|
-
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")
|
|
824
|
-
);
|
|
825
|
-
}
|
|
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
|
|
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
|
|
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
|
|
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 =
|
|
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
|
-
|
|
1519
|
-
|
|
1520
|
-
|
|
1521
|
-
|
|
1522
|
-
|
|
1523
|
-
|
|
1524
|
-
|
|
1525
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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,51 @@ function printHistoryTable(records) {
|
|
|
2501
2397
|
}
|
|
2502
2398
|
|
|
2503
2399
|
// src/deps.ts
|
|
2504
|
-
import { execSync as
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
installed:
|
|
2593
|
-
|
|
2594
|
-
installCommands: [],
|
|
2595
|
-
manualInstructions: 'Run "claude" and complete the login flow'
|
|
2419
|
+
installed: hasClaudeAuth(),
|
|
2420
|
+
instructions: "Run: claude (and complete the login flow)"
|
|
2596
2421
|
},
|
|
2597
2422
|
{
|
|
2598
2423
|
name: "cloudflared",
|
|
2599
2424
|
installed: commandExists("cloudflared"),
|
|
2600
|
-
|
|
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
|
|
2607
|
-
|
|
2608
|
-
|
|
2609
|
-
|
|
2610
|
-
|
|
2611
|
-
|
|
2612
|
-
return false;
|
|
2613
|
-
}
|
|
2614
|
-
}
|
|
2615
|
-
return true;
|
|
2616
|
-
}
|
|
2617
|
-
function addUserToDockerGroup() {
|
|
2618
|
-
if (process.platform !== "linux") return;
|
|
2429
|
+
function hasClaudeAuth() {
|
|
2430
|
+
const credPaths = [
|
|
2431
|
+
join8(homedir5(), ".claude", ".credentials.json"),
|
|
2432
|
+
join8(homedir5(), ".claude", "credentials.json")
|
|
2433
|
+
];
|
|
2434
|
+
if (credPaths.some((p) => existsSync6(p))) return true;
|
|
2619
2435
|
try {
|
|
2620
|
-
|
|
2621
|
-
|
|
2622
|
-
log.info(`Added ${user} to docker group \u2014 log out and back in to apply`);
|
|
2436
|
+
execSync3("claude --version", { stdio: "pipe", timeout: 5e3 });
|
|
2437
|
+
return existsSync6(join8(homedir5(), ".claude"));
|
|
2623
2438
|
} catch {
|
|
2439
|
+
return false;
|
|
2624
2440
|
}
|
|
2625
2441
|
}
|
|
2626
2442
|
function commandExists(cmd) {
|
|
2627
2443
|
try {
|
|
2628
|
-
|
|
2444
|
+
execSync3(`which ${cmd}`, { stdio: "pipe" });
|
|
2629
2445
|
return true;
|
|
2630
2446
|
} catch {
|
|
2631
2447
|
return false;
|
|
@@ -2633,7 +2449,7 @@ function commandExists(cmd) {
|
|
|
2633
2449
|
}
|
|
2634
2450
|
function isDockerRunning() {
|
|
2635
2451
|
try {
|
|
2636
|
-
|
|
2452
|
+
execSync3("docker info", { stdio: "pipe", timeout: 1e4 });
|
|
2637
2453
|
return true;
|
|
2638
2454
|
} catch {
|
|
2639
2455
|
return false;
|
|
@@ -2642,7 +2458,7 @@ function isDockerRunning() {
|
|
|
2642
2458
|
|
|
2643
2459
|
// src/index.ts
|
|
2644
2460
|
import { existsSync as existsSync7, mkdirSync as mkdirSync3, writeFileSync as writeFileSync3, readFileSync as readFileSync4, unlinkSync } from "fs";
|
|
2645
|
-
import { execSync as
|
|
2461
|
+
import { execSync as execSync4, spawn as spawn2 } from "child_process";
|
|
2646
2462
|
import { createInterface } from "readline";
|
|
2647
2463
|
import { join as join9 } from "path";
|
|
2648
2464
|
import { homedir as homedir6 } from "os";
|
|
@@ -3045,7 +2861,19 @@ program.command("history").description("Show run history").option("-n, --limit <
|
|
|
3045
2861
|
}
|
|
3046
2862
|
});
|
|
3047
2863
|
function checkClaudeCredentials() {
|
|
3048
|
-
|
|
2864
|
+
const home = homedir6();
|
|
2865
|
+
if (existsSync7(join9(home, ".claude", ".credentials.json"))) return true;
|
|
2866
|
+
if (existsSync7(join9(home, ".claude", "credentials.json"))) return true;
|
|
2867
|
+
if (existsSync7(join9(home, ".claude")) && commandExistsSync("claude")) return true;
|
|
2868
|
+
return false;
|
|
2869
|
+
}
|
|
2870
|
+
function commandExistsSync(cmd) {
|
|
2871
|
+
try {
|
|
2872
|
+
execSync4(`which ${cmd}`, { stdio: "pipe" });
|
|
2873
|
+
return true;
|
|
2874
|
+
} catch {
|
|
2875
|
+
return false;
|
|
2876
|
+
}
|
|
3049
2877
|
}
|
|
3050
2878
|
async function validateGitHubToken(token) {
|
|
3051
2879
|
try {
|
|
@@ -3060,51 +2888,22 @@ program.command("init").description("Set up autoclawd interactively").action(asy
|
|
|
3060
2888
|
console.log("\n autoclawd setup\n");
|
|
3061
2889
|
console.log(" Checking dependencies...\n");
|
|
3062
2890
|
const deps = checkDeps();
|
|
3063
|
-
const
|
|
2891
|
+
const missing = [];
|
|
3064
2892
|
for (const dep of deps) {
|
|
3065
2893
|
if (dep.installed && dep.running !== false) {
|
|
3066
2894
|
log.success(`${dep.name}`);
|
|
3067
|
-
|
|
3068
|
-
}
|
|
3069
|
-
if (dep.installed && dep.running === false) {
|
|
2895
|
+
} else if (dep.installed && dep.running === false) {
|
|
3070
2896
|
log.warn(`${dep.name} \u2014 installed but not running`);
|
|
3071
|
-
|
|
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);
|
|
2897
|
+
missing.push(dep.name);
|
|
3100
2898
|
} else {
|
|
3101
|
-
log.
|
|
3102
|
-
|
|
2899
|
+
log.error(`${dep.name} \u2014 not installed`);
|
|
2900
|
+
console.log(` ${dep.instructions}`);
|
|
2901
|
+
missing.push(dep.name);
|
|
3103
2902
|
}
|
|
3104
2903
|
}
|
|
3105
|
-
if (
|
|
2904
|
+
if (missing.length > 0) {
|
|
3106
2905
|
console.log(`
|
|
3107
|
-
|
|
2906
|
+
Install the above dependencies before running autoclawd.
|
|
3108
2907
|
`);
|
|
3109
2908
|
} else {
|
|
3110
2909
|
console.log("");
|
|
@@ -3148,7 +2947,7 @@ program.command("init").description("Set up autoclawd interactively").action(asy
|
|
|
3148
2947
|
}
|
|
3149
2948
|
let ghToken = "";
|
|
3150
2949
|
try {
|
|
3151
|
-
ghToken =
|
|
2950
|
+
ghToken = execSync4("gh auth token", { encoding: "utf-8" }).trim();
|
|
3152
2951
|
log.success(`GitHub token detected from gh CLI`);
|
|
3153
2952
|
} catch {
|
|
3154
2953
|
ghToken = await ask("GitHub personal access token");
|