@integrity-labs/agt-cli 0.10.14 → 0.10.16
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.
|
@@ -10,7 +10,7 @@ import {
|
|
|
10
10
|
provisionStopHook,
|
|
11
11
|
requireHost,
|
|
12
12
|
resolveChannels
|
|
13
|
-
} from "../chunk-
|
|
13
|
+
} from "../chunk-XTETZ2D5.js";
|
|
14
14
|
import {
|
|
15
15
|
findTaskByTemplate,
|
|
16
16
|
getProjectDir,
|
|
@@ -340,7 +340,7 @@ var GatewayClientPool = class extends EventEmitter {
|
|
|
340
340
|
};
|
|
341
341
|
|
|
342
342
|
// src/lib/claude-auth-detect.ts
|
|
343
|
-
import { readFile } from "fs/promises";
|
|
343
|
+
import { readFile, readdir } from "fs/promises";
|
|
344
344
|
import { homedir, platform } from "os";
|
|
345
345
|
import { join } from "path";
|
|
346
346
|
import { execFile } from "child_process";
|
|
@@ -364,6 +364,18 @@ async function readOauthCredentials() {
|
|
|
364
364
|
join(homedir(), ".claude", ".credentials.json"),
|
|
365
365
|
join(homedir(), ".claude", "credentials.json")
|
|
366
366
|
];
|
|
367
|
+
const isLinuxRoot = platform() === "linux" && typeof process.getuid === "function" && process.getuid() === 0;
|
|
368
|
+
if (isLinuxRoot) {
|
|
369
|
+
try {
|
|
370
|
+
const entries = await readdir("/home", { withFileTypes: true });
|
|
371
|
+
for (const entry of entries) {
|
|
372
|
+
if (!entry.isDirectory()) continue;
|
|
373
|
+
candidates.push(join("/home", entry.name, ".claude", ".credentials.json"));
|
|
374
|
+
candidates.push(join("/home", entry.name, ".claude", "credentials.json"));
|
|
375
|
+
}
|
|
376
|
+
} catch {
|
|
377
|
+
}
|
|
378
|
+
}
|
|
367
379
|
for (const path of candidates) {
|
|
368
380
|
const parsed = await readJsonSilently(path);
|
|
369
381
|
if (parsed) {
|
|
@@ -781,48 +793,60 @@ function clearAgentCaches(agentId, codeName) {
|
|
|
781
793
|
var cachedFrameworkVersion = null;
|
|
782
794
|
var lastVersionCheckAt = 0;
|
|
783
795
|
var VERSION_CHECK_INTERVAL_MS = 5 * 60 * 1e3;
|
|
796
|
+
function resolveBrewPath(execFileSync) {
|
|
797
|
+
try {
|
|
798
|
+
const out = execFileSync("which", ["brew"], { timeout: 5e3 }).toString().trim();
|
|
799
|
+
if (out) return out;
|
|
800
|
+
} catch {
|
|
801
|
+
}
|
|
802
|
+
const fallback = "/home/linuxbrew/.linuxbrew/bin/brew";
|
|
803
|
+
if (existsSync(fallback)) return fallback;
|
|
804
|
+
return null;
|
|
805
|
+
}
|
|
784
806
|
async function ensureFrameworkBinary(frameworkId) {
|
|
785
807
|
if (frameworkId !== "claude-code") return;
|
|
786
808
|
if (frameworkBinaryChecked.has(frameworkId)) return;
|
|
787
809
|
frameworkBinaryChecked.add(frameworkId);
|
|
788
810
|
const { execFileSync } = await import("child_process");
|
|
789
|
-
|
|
790
|
-
|
|
791
|
-
|
|
792
|
-
} catch {
|
|
793
|
-
log("Homebrew not found \u2014 cannot auto-install/upgrade Claude Code. Install manually: https://claude.ai/download");
|
|
811
|
+
const brewPath = resolveBrewPath(execFileSync);
|
|
812
|
+
if (!brewPath) {
|
|
813
|
+
log("Homebrew not found (no `brew` on PATH, no /home/linuxbrew/.linuxbrew/bin/brew). Cannot auto-install Claude Code. Install manually: https://claude.ai/download");
|
|
794
814
|
return;
|
|
795
815
|
}
|
|
796
|
-
|
|
797
|
-
|
|
798
|
-
|
|
799
|
-
|
|
800
|
-
|
|
816
|
+
log(`Using brew at ${brewPath}`);
|
|
817
|
+
const isRoot = typeof process.getuid === "function" && process.getuid() === 0;
|
|
818
|
+
const runBrew = (args, opts) => {
|
|
819
|
+
if (isRoot) {
|
|
820
|
+
const sudoArgs = ["-u", "ec2-user", "-H", brewPath, ...args];
|
|
821
|
+
return execFileSync("sudo", sudoArgs, { ...opts, stdio: "pipe" }).toString();
|
|
822
|
+
}
|
|
823
|
+
return execFileSync(brewPath, args, { ...opts, stdio: "pipe" }).toString();
|
|
824
|
+
};
|
|
825
|
+
let claudeExists = existsSync("/home/linuxbrew/.linuxbrew/bin/claude");
|
|
826
|
+
if (!claudeExists) {
|
|
827
|
+
try {
|
|
828
|
+
execFileSync("which", ["claude"], { timeout: 5e3 });
|
|
829
|
+
claudeExists = true;
|
|
830
|
+
} catch {
|
|
831
|
+
}
|
|
801
832
|
}
|
|
802
833
|
if (!claudeExists) {
|
|
803
|
-
log(
|
|
834
|
+
log(`Claude Code binary not found \u2014 installing via Homebrew${isRoot ? " (as ec2-user via sudo)" : ""}...`);
|
|
804
835
|
try {
|
|
805
|
-
|
|
806
|
-
timeout: 12e4,
|
|
807
|
-
stdio: "pipe"
|
|
808
|
-
});
|
|
836
|
+
runBrew(["install", "--cask", "claude-code"], { timeout: 12e4 });
|
|
809
837
|
} catch (err) {
|
|
810
838
|
log(`Claude Code install failed: ${err.message}`);
|
|
811
839
|
return;
|
|
812
840
|
}
|
|
813
|
-
|
|
814
|
-
execFileSync("which", ["claude"], { timeout: 5e3 });
|
|
841
|
+
if (existsSync("/home/linuxbrew/.linuxbrew/bin/claude")) {
|
|
815
842
|
log("Claude Code installed successfully");
|
|
816
|
-
}
|
|
817
|
-
log("Claude Code install completed but binary not found
|
|
843
|
+
} else {
|
|
844
|
+
log("Claude Code install completed but binary not found at expected path \u2014 check brew logs");
|
|
818
845
|
}
|
|
819
846
|
} else {
|
|
820
|
-
log(
|
|
847
|
+
log(`Checking for Claude Code updates${isRoot ? " (as ec2-user via sudo)" : ""}...`);
|
|
821
848
|
try {
|
|
822
|
-
const output =
|
|
823
|
-
timeout: 12e4,
|
|
824
|
-
stdio: "pipe"
|
|
825
|
-
}).toString();
|
|
849
|
+
const output = runBrew(["upgrade", "--cask", "claude-code"], { timeout: 12e4 });
|
|
826
850
|
if (output.includes("already installed") || output.includes("up-to-date")) {
|
|
827
851
|
log("Claude Code is already up to date");
|
|
828
852
|
} else {
|
|
@@ -837,7 +861,7 @@ async function ensureFrameworkBinary(frameworkId) {
|
|
|
837
861
|
}
|
|
838
862
|
}
|
|
839
863
|
}
|
|
840
|
-
agentRuntimeAuthenticated = checkClaudeAuth(
|
|
864
|
+
agentRuntimeAuthenticated = await checkClaudeAuth();
|
|
841
865
|
}
|
|
842
866
|
var UPDATE_CHECK_INTERVAL_MS = 5 * 60 * 1e3;
|
|
843
867
|
async function checkAndUpdateCli() {
|
|
@@ -889,28 +913,23 @@ async function checkAndUpdateCli() {
|
|
|
889
913
|
} catch {
|
|
890
914
|
}
|
|
891
915
|
}
|
|
892
|
-
function checkClaudeAuth(
|
|
916
|
+
async function checkClaudeAuth() {
|
|
893
917
|
try {
|
|
894
|
-
const
|
|
895
|
-
|
|
896
|
-
|
|
897
|
-
const parsed = JSON.parse(authOutput);
|
|
898
|
-
if (typeof parsed.loggedIn === "boolean") loggedIn = parsed.loggedIn;
|
|
899
|
-
} catch {
|
|
900
|
-
const lower = authOutput.toLowerCase();
|
|
901
|
-
if (lower.includes("not logged in") || lower.includes("logged out")) loggedIn = false;
|
|
902
|
-
else if (lower.includes("logged in")) loggedIn = true;
|
|
903
|
-
}
|
|
904
|
-
if (loggedIn === false) {
|
|
905
|
-
log('\u26A0\uFE0F Claude Code is not authenticated. Run "claude" in a terminal to log in, then restart the manager.');
|
|
918
|
+
const report = await detectClaudeAuth();
|
|
919
|
+
if (!report) {
|
|
920
|
+
log("\u26A0\uFE0F Claude Code is not authenticated. Run `claude /login` (or set `ANTHROPIC_API_KEY`) on the host, then the manager will pick it up on the next cycle.");
|
|
906
921
|
return false;
|
|
907
|
-
}
|
|
908
|
-
|
|
922
|
+
}
|
|
923
|
+
if (report.status === "expired") {
|
|
924
|
+
log(`\u26A0\uFE0F Claude Code auth expired (${report.mode}). Re-run \`claude /login\` to refresh.`);
|
|
909
925
|
return false;
|
|
910
926
|
}
|
|
927
|
+
if (report.status === "expiring_soon") {
|
|
928
|
+
log(`[auth] Claude Code token expiring soon (expires_at=${report.expires_at}) \u2014 still valid, proceeding`);
|
|
929
|
+
}
|
|
911
930
|
return true;
|
|
912
|
-
} catch {
|
|
913
|
-
log(
|
|
931
|
+
} catch (err) {
|
|
932
|
+
log(`\u26A0\uFE0F Claude Code auth probe failed: ${err.message}`);
|
|
914
933
|
return false;
|
|
915
934
|
}
|
|
916
935
|
}
|
|
@@ -2792,8 +2811,7 @@ async function ensurePersistentSession(agent, tasks, boardItems, refreshData) {
|
|
|
2792
2811
|
}
|
|
2793
2812
|
devChannels.push("server:direct-chat");
|
|
2794
2813
|
if (!agentRuntimeAuthenticated) {
|
|
2795
|
-
|
|
2796
|
-
agentRuntimeAuthenticated = checkClaudeAuth(execFileSync);
|
|
2814
|
+
agentRuntimeAuthenticated = await checkClaudeAuth();
|
|
2797
2815
|
if (!agentRuntimeAuthenticated) {
|
|
2798
2816
|
log(`[persistent-session] Skipping '${codeName}' \u2014 Claude Code not authenticated`);
|
|
2799
2817
|
return;
|
|
@@ -4213,8 +4231,27 @@ async function stopPolling() {
|
|
|
4213
4231
|
function startManager(opts) {
|
|
4214
4232
|
config = opts;
|
|
4215
4233
|
deployMcpAssets();
|
|
4234
|
+
void ensureHostFrameworkBinaries();
|
|
4216
4235
|
startPolling();
|
|
4217
4236
|
}
|
|
4237
|
+
async function ensureHostFrameworkBinaries() {
|
|
4238
|
+
const apiKey = getApiKey();
|
|
4239
|
+
if (!apiKey) {
|
|
4240
|
+
log("[framework-install] AGT_API_KEY not set \u2014 skipping host framework binary check");
|
|
4241
|
+
return;
|
|
4242
|
+
}
|
|
4243
|
+
try {
|
|
4244
|
+
const exchange = await exchangeApiKey(apiKey);
|
|
4245
|
+
if (!exchange.framework) {
|
|
4246
|
+
log("[framework-install] host has no framework set \u2014 skipping");
|
|
4247
|
+
return;
|
|
4248
|
+
}
|
|
4249
|
+
log(`[framework-install] host framework = ${exchange.framework}`);
|
|
4250
|
+
await ensureFrameworkBinary(exchange.framework);
|
|
4251
|
+
} catch (err) {
|
|
4252
|
+
log(`[framework-install] failed: ${err.message}`);
|
|
4253
|
+
}
|
|
4254
|
+
}
|
|
4218
4255
|
function deployMcpAssets() {
|
|
4219
4256
|
const targetDir = join2(homedir2(), ".augmented", "_mcp");
|
|
4220
4257
|
mkdirSync(targetDir, { recursive: true });
|