@integrity-labs/agt-cli 0.27.66 → 0.27.67
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/bin/agt.js +186 -15
- package/dist/bin/agt.js.map +1 -1
- package/dist/{chunk-CF3SEPE3.js → chunk-DA3KY3D2.js} +107 -23
- package/dist/chunk-DA3KY3D2.js.map +1 -0
- package/dist/{chunk-TIS3QVYS.js → chunk-EYWW624B.js} +241 -160
- package/dist/chunk-EYWW624B.js.map +1 -0
- package/dist/{chunk-PM3CC2SJ.js → chunk-KPD5KJY7.js} +80 -1
- package/dist/chunk-KPD5KJY7.js.map +1 -0
- package/dist/{claude-pair-runtime-R7PGK4LT.js → claude-pair-runtime-6GSA5KRH.js} +2 -2
- package/dist/lib/manager-worker.js +30 -9
- package/dist/lib/manager-worker.js.map +1 -1
- package/dist/{persistent-session-BN3PGV3A.js → persistent-session-2WJIWIMQ.js} +3 -3
- package/dist/{responsiveness-probe-QR6VWUKX.js → responsiveness-probe-RAWYP7LQ.js} +3 -3
- package/package.json +1 -1
- package/dist/chunk-CF3SEPE3.js.map +0 -1
- package/dist/chunk-PM3CC2SJ.js.map +0 -1
- package/dist/chunk-TIS3QVYS.js.map +0 -1
- /package/dist/{claude-pair-runtime-R7PGK4LT.js.map → claude-pair-runtime-6GSA5KRH.js.map} +0 -0
- /package/dist/{persistent-session-BN3PGV3A.js.map → persistent-session-2WJIWIMQ.js.map} +0 -0
- /package/dist/{responsiveness-probe-QR6VWUKX.js.map → responsiveness-probe-RAWYP7LQ.js.map} +0 -0
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import {
|
|
2
2
|
claudeModelAlias,
|
|
3
3
|
isClaudeFastMode
|
|
4
|
-
} from "./chunk-
|
|
4
|
+
} from "./chunk-KPD5KJY7.js";
|
|
5
5
|
import {
|
|
6
6
|
reapOrphanChannelMcps
|
|
7
7
|
} from "./chunk-XWVM4KPK.js";
|
|
@@ -10,7 +10,7 @@ import {
|
|
|
10
10
|
import { spawn, execSync, execFileSync as execFileSync2 } from "child_process";
|
|
11
11
|
import { join as join2, dirname } from "path";
|
|
12
12
|
import { homedir as homedir2, platform, userInfo } from "os";
|
|
13
|
-
import { existsSync as
|
|
13
|
+
import { existsSync as existsSync3, readFileSync as readFileSync4, readdirSync, writeFileSync as writeFileSync3, appendFileSync, mkdirSync as mkdirSync2, chmodSync, copyFileSync, rmSync } from "fs";
|
|
14
14
|
import { fileURLToPath } from "url";
|
|
15
15
|
|
|
16
16
|
// src/lib/mcp-sanitize.ts
|
|
@@ -62,12 +62,84 @@ function buildAllowedTools(mcpServerNames) {
|
|
|
62
62
|
return [...mcpPatterns, ...BASE_TOOLS].join(",");
|
|
63
63
|
}
|
|
64
64
|
|
|
65
|
+
// src/lib/mcp-env-probe.ts
|
|
66
|
+
import { existsSync, readFileSync as readFileSync2 } from "fs";
|
|
67
|
+
var LATE_BOUND_VARS = /* @__PURE__ */ new Set(["AGT_RUN_ID"]);
|
|
68
|
+
var TEMPLATE_VAR_RE = /\$\{([A-Za-z_][A-Za-z0-9_]*)\}/g;
|
|
69
|
+
function collectVarsFromValue(value, into) {
|
|
70
|
+
if (typeof value === "string") {
|
|
71
|
+
for (const m of value.matchAll(TEMPLATE_VAR_RE)) into.add(m[1]);
|
|
72
|
+
} else if (Array.isArray(value)) {
|
|
73
|
+
for (const v of value) collectVarsFromValue(v, into);
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
function findMissingSubstitutionVars(mcpConfig, env) {
|
|
77
|
+
const findings = [];
|
|
78
|
+
if (typeof mcpConfig !== "object" || mcpConfig === null) return findings;
|
|
79
|
+
const servers = mcpConfig.mcpServers;
|
|
80
|
+
if (typeof servers !== "object" || servers === null) return findings;
|
|
81
|
+
for (const [server, raw] of Object.entries(servers)) {
|
|
82
|
+
if (typeof raw !== "object" || raw === null) continue;
|
|
83
|
+
const entry = raw;
|
|
84
|
+
const vars = /* @__PURE__ */ new Set();
|
|
85
|
+
collectVarsFromValue(entry["command"], vars);
|
|
86
|
+
collectVarsFromValue(entry["args"], vars);
|
|
87
|
+
collectVarsFromValue(entry["url"], vars);
|
|
88
|
+
for (const block of [entry["env"], entry["headers"]]) {
|
|
89
|
+
if (typeof block !== "object" || block === null) continue;
|
|
90
|
+
for (const v of Object.values(block)) collectVarsFromValue(v, vars);
|
|
91
|
+
}
|
|
92
|
+
for (const varName of vars) {
|
|
93
|
+
if (LATE_BOUND_VARS.has(varName)) continue;
|
|
94
|
+
const value = env[varName];
|
|
95
|
+
if (value === void 0) {
|
|
96
|
+
findings.push({ varName, server, state: "unset" });
|
|
97
|
+
} else if (value.trim() === "") {
|
|
98
|
+
findings.push({ varName, server, state: "empty" });
|
|
99
|
+
}
|
|
100
|
+
}
|
|
101
|
+
}
|
|
102
|
+
return findings;
|
|
103
|
+
}
|
|
104
|
+
function formatMissingVar(f) {
|
|
105
|
+
return `[mcp-env-substitution] missing var=${f.varName} server=${f.server} state=${f.state}`;
|
|
106
|
+
}
|
|
107
|
+
function parseEnvIntegrations(content) {
|
|
108
|
+
const out = {};
|
|
109
|
+
for (const line of content.split("\n")) {
|
|
110
|
+
if (!line || line.startsWith("#") || !line.includes("=")) continue;
|
|
111
|
+
const eqIdx = line.indexOf("=");
|
|
112
|
+
const key = line.slice(0, eqIdx);
|
|
113
|
+
let value = line.slice(eqIdx + 1);
|
|
114
|
+
if (value.length >= 2 && value.startsWith("'") && value.endsWith("'")) {
|
|
115
|
+
value = value.slice(1, -1).replaceAll("'\\''", "'");
|
|
116
|
+
}
|
|
117
|
+
out[key] = value;
|
|
118
|
+
}
|
|
119
|
+
return out;
|
|
120
|
+
}
|
|
121
|
+
function probeMcpEnvSubstitution(args) {
|
|
122
|
+
try {
|
|
123
|
+
const config = JSON.parse(readFileSync2(args.mcpConfigPath, "utf-8"));
|
|
124
|
+
let env = args.baseEnv;
|
|
125
|
+
if (args.envIntegrationsPath && existsSync(args.envIntegrationsPath)) {
|
|
126
|
+
env = {
|
|
127
|
+
...args.baseEnv,
|
|
128
|
+
...parseEnvIntegrations(readFileSync2(args.envIntegrationsPath, "utf-8"))
|
|
129
|
+
};
|
|
130
|
+
}
|
|
131
|
+
return findMissingSubstitutionVars(config, env);
|
|
132
|
+
} catch {
|
|
133
|
+
return [];
|
|
134
|
+
}
|
|
135
|
+
}
|
|
136
|
+
|
|
65
137
|
// src/lib/persistent-session.ts
|
|
66
138
|
import { randomUUID as randomUUID2 } from "crypto";
|
|
67
139
|
|
|
68
140
|
// src/lib/daily-session.ts
|
|
69
141
|
import { randomUUID } from "crypto";
|
|
70
|
-
import { existsSync, mkdirSync, readFileSync as
|
|
142
|
+
import { existsSync as existsSync2, mkdirSync, readFileSync as readFileSync3, renameSync, statSync, writeFileSync as writeFileSync2 } from "fs";
|
|
71
143
|
import { homedir } from "os";
|
|
72
144
|
import { join } from "path";
|
|
73
145
|
var HISTORY_DAYS = 7;
|
|
@@ -97,9 +169,9 @@ function todayLocalIso(now = /* @__PURE__ */ new Date(), timezone) {
|
|
|
97
169
|
}
|
|
98
170
|
function readFile(codeName) {
|
|
99
171
|
const path = dailySessionPath(codeName);
|
|
100
|
-
if (!
|
|
172
|
+
if (!existsSync2(path)) return { current: null, history: [] };
|
|
101
173
|
try {
|
|
102
|
-
const raw =
|
|
174
|
+
const raw = readFileSync3(path, "utf-8");
|
|
103
175
|
const parsed = JSON.parse(raw);
|
|
104
176
|
return {
|
|
105
177
|
current: parsed.current ?? null,
|
|
@@ -168,7 +240,7 @@ function sessionFilePath(projectDir, sessionId) {
|
|
|
168
240
|
}
|
|
169
241
|
function isAgentIdle(projectDir, sessionId, idleSeconds = 60, now = /* @__PURE__ */ new Date()) {
|
|
170
242
|
const path = sessionFilePath(projectDir, sessionId);
|
|
171
|
-
if (!
|
|
243
|
+
if (!existsSync2(path)) return true;
|
|
172
244
|
try {
|
|
173
245
|
const mtimeMs = statSync(path).mtimeMs;
|
|
174
246
|
return now.getTime() - mtimeMs >= idleSeconds * 1e3;
|
|
@@ -212,7 +284,7 @@ function syncClaudeCredsToRoot() {
|
|
|
212
284
|
if (platform() !== "linux") return true;
|
|
213
285
|
if (typeof process.getuid !== "function" || process.getuid() !== 0) return true;
|
|
214
286
|
for (const filename of [".credentials.json", "credentials.json"]) {
|
|
215
|
-
if (
|
|
287
|
+
if (existsSync3(join2("/root/.claude", filename))) return true;
|
|
216
288
|
}
|
|
217
289
|
let sourcePath = null;
|
|
218
290
|
try {
|
|
@@ -221,7 +293,7 @@ function syncClaudeCredsToRoot() {
|
|
|
221
293
|
if (!entry.isDirectory()) continue;
|
|
222
294
|
for (const filename of [".credentials.json", "credentials.json"]) {
|
|
223
295
|
const candidate = join2("/home", entry.name, ".claude", filename);
|
|
224
|
-
if (
|
|
296
|
+
if (existsSync3(candidate)) {
|
|
225
297
|
sourcePath = candidate;
|
|
226
298
|
break outer;
|
|
227
299
|
}
|
|
@@ -234,7 +306,7 @@ function syncClaudeCredsToRoot() {
|
|
|
234
306
|
const sourceFilename = sourcePath.endsWith("credentials.json") && !sourcePath.endsWith(".credentials.json") ? "credentials.json" : ".credentials.json";
|
|
235
307
|
const targetPath = join2(targetDir, sourceFilename);
|
|
236
308
|
try {
|
|
237
|
-
if (!
|
|
309
|
+
if (!existsSync3(targetDir)) mkdirSync2(targetDir, { recursive: true, mode: 448 });
|
|
238
310
|
copyFileSync(sourcePath, targetPath);
|
|
239
311
|
chmodSync(targetPath, 384);
|
|
240
312
|
return true;
|
|
@@ -246,13 +318,13 @@ var cachedClaudePath = null;
|
|
|
246
318
|
function resolveClaudeBinary() {
|
|
247
319
|
if (cachedClaudePath) return cachedClaudePath;
|
|
248
320
|
const override = process.env.CLAUDE_PATH;
|
|
249
|
-
if (override &&
|
|
321
|
+
if (override && existsSync3(override)) {
|
|
250
322
|
cachedClaudePath = override;
|
|
251
323
|
return override;
|
|
252
324
|
}
|
|
253
325
|
try {
|
|
254
326
|
const out = execSync("which claude 2>/dev/null", { encoding: "utf-8" }).trim();
|
|
255
|
-
if (out &&
|
|
327
|
+
if (out && existsSync3(out)) {
|
|
256
328
|
cachedClaudePath = out;
|
|
257
329
|
return out;
|
|
258
330
|
}
|
|
@@ -264,7 +336,7 @@ function resolveClaudeBinary() {
|
|
|
264
336
|
"/usr/local/bin/claude"
|
|
265
337
|
];
|
|
266
338
|
for (const p of candidates) {
|
|
267
|
-
if (
|
|
339
|
+
if (existsSync3(p)) {
|
|
268
340
|
cachedClaudePath = p;
|
|
269
341
|
return p;
|
|
270
342
|
}
|
|
@@ -282,7 +354,7 @@ function writePersistentClaudeWrapper(args) {
|
|
|
282
354
|
// --dangerously-skip-permissions on dedicated EC2 hosts.
|
|
283
355
|
"export IS_SANDBOX=1"
|
|
284
356
|
];
|
|
285
|
-
if (
|
|
357
|
+
if (existsSync3(envIntegrationsPath)) {
|
|
286
358
|
wrapperLines.push(
|
|
287
359
|
"set -a",
|
|
288
360
|
`source ${JSON.stringify(envIntegrationsPath)}`,
|
|
@@ -299,9 +371,9 @@ function writePersistentClaudeWrapper(args) {
|
|
|
299
371
|
return wrapperPath;
|
|
300
372
|
}
|
|
301
373
|
function collectMcpServerNames(mcpConfigPath) {
|
|
302
|
-
if (!
|
|
374
|
+
if (!existsSync3(mcpConfigPath)) return [];
|
|
303
375
|
try {
|
|
304
|
-
const data = JSON.parse(
|
|
376
|
+
const data = JSON.parse(readFileSync4(mcpConfigPath, "utf-8"));
|
|
305
377
|
const servers = data.mcpServers;
|
|
306
378
|
return servers ? Object.keys(servers) : [];
|
|
307
379
|
} catch {
|
|
@@ -315,7 +387,7 @@ function getAcpxBin() {
|
|
|
315
387
|
let dir = moduleDir;
|
|
316
388
|
for (let i = 0; i < 6; i++) {
|
|
317
389
|
const candidate = join2(dir, "node_modules", ".bin", "acpx");
|
|
318
|
-
if (
|
|
390
|
+
if (existsSync3(candidate)) {
|
|
319
391
|
_acpxBin = candidate;
|
|
320
392
|
return _acpxBin;
|
|
321
393
|
}
|
|
@@ -379,9 +451,9 @@ function setupPaneLog(tmuxSession, codeName, log) {
|
|
|
379
451
|
}
|
|
380
452
|
function readPaneLogTail(codeName, lines = PANE_TAIL_LINES) {
|
|
381
453
|
const logPath = paneLogPath(codeName);
|
|
382
|
-
if (!
|
|
454
|
+
if (!existsSync3(logPath)) return null;
|
|
383
455
|
try {
|
|
384
|
-
const raw =
|
|
456
|
+
const raw = readFileSync4(logPath, "utf-8");
|
|
385
457
|
if (!raw) return null;
|
|
386
458
|
const stripped = raw.replace(/\x1b\[[0-9;?]*[A-Za-z]/g, "");
|
|
387
459
|
const all = stripped.split("\n").filter((l) => l.length > 0);
|
|
@@ -469,7 +541,7 @@ function spawnSession(config, session) {
|
|
|
469
541
|
const claudeDir = join2(homedir2(), ".claude");
|
|
470
542
|
for (const filename of [".credentials.json", "credentials.json"]) {
|
|
471
543
|
const p = join2(claudeDir, filename);
|
|
472
|
-
if (
|
|
544
|
+
if (existsSync3(p)) {
|
|
473
545
|
try {
|
|
474
546
|
rmSync(p, { force: true });
|
|
475
547
|
log(`[persistent-session] Removed ${p} (api_key mode active \u2014 preventing OAuth fallback)`);
|
|
@@ -495,7 +567,7 @@ function spawnSession(config, session) {
|
|
|
495
567
|
if (channels.length > 0) args.push("--channels", ...channels);
|
|
496
568
|
if (devChannels.length > 0) args.push("--dangerously-load-development-channels", ...devChannels);
|
|
497
569
|
args.push("--mcp-config", mcpConfigPath);
|
|
498
|
-
if (
|
|
570
|
+
if (existsSync3(claudeMdPath)) args.push("--system-prompt-file", claudeMdPath);
|
|
499
571
|
const modelAlias = claudeModelAlias(config.primaryModel);
|
|
500
572
|
if (modelAlias) args.push("--model", modelAlias);
|
|
501
573
|
args.push("--allow-dangerously-skip-permissions");
|
|
@@ -529,6 +601,16 @@ function spawnSession(config, session) {
|
|
|
529
601
|
if (config.runId) {
|
|
530
602
|
tmuxEnv["AGT_RUN_ID"] = config.runId;
|
|
531
603
|
}
|
|
604
|
+
for (const f of probeMcpEnvSubstitution({
|
|
605
|
+
mcpConfigPath,
|
|
606
|
+
envIntegrationsPath: join2(projectDir, ".env.integrations"),
|
|
607
|
+
baseEnv: {
|
|
608
|
+
...tmuxEnv,
|
|
609
|
+
...claudeAuthMode === "api_key" && config.anthropicApiKey ? { ANTHROPIC_API_KEY: config.anthropicApiKey } : {}
|
|
610
|
+
}
|
|
611
|
+
})) {
|
|
612
|
+
log(`[persistent-session] ${formatMissingVar(f)} agent=${codeName}`);
|
|
613
|
+
}
|
|
532
614
|
const child = spawn("tmux", [
|
|
533
615
|
"new-session",
|
|
534
616
|
"-d",
|
|
@@ -1061,7 +1143,7 @@ function writeAcpxConfig(config) {
|
|
|
1061
1143
|
if (channels.length > 0) claudeArgs.push("--channels", ...channels);
|
|
1062
1144
|
if (devChannels.length > 0) claudeArgs.push("--dangerously-load-development-channels", ...devChannels);
|
|
1063
1145
|
claudeArgs.push("--mcp-config", mcpConfigPath);
|
|
1064
|
-
if (
|
|
1146
|
+
if (existsSync3(claudeMdPath)) claudeArgs.push("--system-prompt-file", claudeMdPath);
|
|
1065
1147
|
const acpModelAlias = claudeModelAlias(config.primaryModel);
|
|
1066
1148
|
if (acpModelAlias) claudeArgs.push("--model", acpModelAlias);
|
|
1067
1149
|
claudeArgs.push("--allow-dangerously-skip-permissions");
|
|
@@ -1073,7 +1155,7 @@ function writeAcpxConfig(config) {
|
|
|
1073
1155
|
const envIntegrationsPath = join2(projectDir, ".env.integrations");
|
|
1074
1156
|
const wrapperPath = join2(projectDir, ".claude", "acpx-agent.sh");
|
|
1075
1157
|
const wrapperLines = ["#!/usr/bin/env bash"];
|
|
1076
|
-
if (
|
|
1158
|
+
if (existsSync3(envIntegrationsPath)) {
|
|
1077
1159
|
wrapperLines.push(`set -a`, `source ${JSON.stringify(envIntegrationsPath)}`, `set +a`);
|
|
1078
1160
|
}
|
|
1079
1161
|
if (claudeAuthMode === "api_key" && anthropicApiKey) {
|
|
@@ -1096,6 +1178,8 @@ function writeAcpxConfig(config) {
|
|
|
1096
1178
|
}
|
|
1097
1179
|
|
|
1098
1180
|
export {
|
|
1181
|
+
formatMissingVar,
|
|
1182
|
+
probeMcpEnvSubstitution,
|
|
1099
1183
|
sanitizeMcpJson,
|
|
1100
1184
|
buildAllowedTools,
|
|
1101
1185
|
sessionTranscriptDir,
|
|
@@ -1125,4 +1209,4 @@ export {
|
|
|
1125
1209
|
stopAllSessionsAndWait,
|
|
1126
1210
|
getProjectDir
|
|
1127
1211
|
};
|
|
1128
|
-
//# sourceMappingURL=chunk-
|
|
1212
|
+
//# sourceMappingURL=chunk-DA3KY3D2.js.map
|