@integrity-labs/agt-cli 0.27.9-test.12 → 0.27.9-test.14
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 +4 -4
- package/dist/chunk-354FAVQR.js +173 -0
- package/dist/chunk-354FAVQR.js.map +1 -0
- package/dist/{chunk-MQJ5DMPT.js → chunk-7GKJZBTB.js} +111 -204
- package/dist/chunk-7GKJZBTB.js.map +1 -0
- package/dist/{chunk-HR5T2RQF.js → chunk-I3YS5WFV.js} +3 -1
- package/dist/chunk-I3YS5WFV.js.map +1 -0
- package/dist/{chunk-SXBZDUKN.js → chunk-R7NKCGWN.js} +341 -46
- package/dist/chunk-R7NKCGWN.js.map +1 -0
- package/dist/{chunk-I2OTQJH3.js → chunk-WOOYOAPG.js} +2644 -2142
- package/dist/chunk-WOOYOAPG.js.map +1 -0
- package/dist/{claude-pair-runtime-F6USL3EW.js → claude-pair-runtime-GIUCD7IG.js} +2 -2
- package/dist/{claude-scheduler-EM24LTGV.js → claude-scheduler-FATCLHDM.js} +2 -2
- package/dist/daily-session-PNQX5URX.js +27 -0
- package/dist/lib/manager-worker.js +1125 -149
- package/dist/lib/manager-worker.js.map +1 -1
- package/dist/mcp/augmented-admin.js +21335 -0
- package/dist/mcp/index.js +121 -4
- package/dist/mcp/slack-channel.js +845 -208
- package/dist/mcp/teams-channel.js +73 -29
- package/dist/mcp/telegram-channel.js +579 -157
- package/dist/{persistent-session-OL5EDYB4.js → persistent-session-35PWSTLO.js} +10 -3
- package/dist/persistent-session-35PWSTLO.js.map +1 -0
- package/dist/responsiveness-probe-MA4M2QM4.js +158 -0
- package/dist/responsiveness-probe-MA4M2QM4.js.map +1 -0
- package/package.json +3 -2
- package/dist/chunk-HR5T2RQF.js.map +0 -1
- package/dist/chunk-I2OTQJH3.js.map +0 -1
- package/dist/chunk-MQJ5DMPT.js.map +0 -1
- package/dist/chunk-SXBZDUKN.js.map +0 -1
- package/dist/responsiveness-probe-B6LJJRUD.js +0 -74
- package/dist/responsiveness-probe-B6LJJRUD.js.map +0 -1
- /package/dist/{claude-pair-runtime-F6USL3EW.js.map → claude-pair-runtime-GIUCD7IG.js.map} +0 -0
- /package/dist/{claude-scheduler-EM24LTGV.js.map → claude-scheduler-FATCLHDM.js.map} +0 -0
- /package/dist/{persistent-session-OL5EDYB4.js.map → daily-session-PNQX5URX.js.map} +0 -0
|
@@ -1,16 +1,22 @@
|
|
|
1
1
|
import {
|
|
2
2
|
claudeModelAlias,
|
|
3
3
|
isClaudeFastMode
|
|
4
|
-
} from "./chunk-
|
|
4
|
+
} from "./chunk-WOOYOAPG.js";
|
|
5
|
+
import {
|
|
6
|
+
getOrCreateDailySession,
|
|
7
|
+
markDailySessionSpawn,
|
|
8
|
+
rotateDailySession,
|
|
9
|
+
sessionFileExists
|
|
10
|
+
} from "./chunk-354FAVQR.js";
|
|
5
11
|
import {
|
|
6
12
|
reapOrphanChannelMcps
|
|
7
13
|
} from "./chunk-XWVM4KPK.js";
|
|
8
14
|
|
|
9
15
|
// src/lib/persistent-session.ts
|
|
10
16
|
import { spawn, execSync, execFileSync as execFileSync3 } from "child_process";
|
|
11
|
-
import { join
|
|
12
|
-
import { homedir
|
|
13
|
-
import { existsSync as
|
|
17
|
+
import { join, dirname } from "path";
|
|
18
|
+
import { homedir, platform, userInfo } from "os";
|
|
19
|
+
import { existsSync as existsSync2, readFileSync as readFileSync3, readdirSync, writeFileSync as writeFileSync2, appendFileSync, mkdirSync, chmodSync, copyFileSync, rmSync } from "fs";
|
|
14
20
|
import { fileURLToPath } from "url";
|
|
15
21
|
|
|
16
22
|
// src/lib/mcp-sanitize.ts
|
|
@@ -108,6 +114,20 @@ function findMissingSubstitutionVars(mcpConfig, env) {
|
|
|
108
114
|
function formatMissingVar(f) {
|
|
109
115
|
return `[mcp-env-substitution] missing var=${f.varName} server=${f.server} state=${f.state}`;
|
|
110
116
|
}
|
|
117
|
+
function expandTemplateVars(value, env) {
|
|
118
|
+
const unresolved = /* @__PURE__ */ new Set();
|
|
119
|
+
const expanded = value.replace(TEMPLATE_VAR_RE, (literal, name) => {
|
|
120
|
+
if (LATE_BOUND_VARS.has(name)) {
|
|
121
|
+
unresolved.add(name);
|
|
122
|
+
return literal;
|
|
123
|
+
}
|
|
124
|
+
const resolved = env[name];
|
|
125
|
+
if (resolved !== void 0 && resolved.trim() !== "") return resolved;
|
|
126
|
+
unresolved.add(name);
|
|
127
|
+
return literal;
|
|
128
|
+
});
|
|
129
|
+
return { value: expanded, unresolved: [...unresolved] };
|
|
130
|
+
}
|
|
111
131
|
function parseEnvIntegrations(content) {
|
|
112
132
|
const out = {};
|
|
113
133
|
for (const line of content.split("\n")) {
|
|
@@ -139,156 +159,7 @@ function probeMcpEnvSubstitution(args) {
|
|
|
139
159
|
}
|
|
140
160
|
|
|
141
161
|
// src/lib/persistent-session.ts
|
|
142
|
-
import { randomUUID as randomUUID2 } from "crypto";
|
|
143
|
-
|
|
144
|
-
// src/lib/daily-session.ts
|
|
145
162
|
import { randomUUID } from "crypto";
|
|
146
|
-
import { existsSync as existsSync2, mkdirSync, readFileSync as readFileSync3, renameSync, statSync, writeFileSync as writeFileSync2 } from "fs";
|
|
147
|
-
import { homedir } from "os";
|
|
148
|
-
import { join } from "path";
|
|
149
|
-
var HISTORY_DAYS = 7;
|
|
150
|
-
function profileDir(codeName) {
|
|
151
|
-
return join(homedir(), ".augmented", codeName);
|
|
152
|
-
}
|
|
153
|
-
function dailySessionPath(codeName) {
|
|
154
|
-
return join(profileDir(codeName), "daily-session.json");
|
|
155
|
-
}
|
|
156
|
-
function todayLocalIso(now = /* @__PURE__ */ new Date(), timezone) {
|
|
157
|
-
if (timezone) {
|
|
158
|
-
try {
|
|
159
|
-
const fmt = new Intl.DateTimeFormat("en-CA", {
|
|
160
|
-
timeZone: timezone,
|
|
161
|
-
year: "numeric",
|
|
162
|
-
month: "2-digit",
|
|
163
|
-
day: "2-digit"
|
|
164
|
-
});
|
|
165
|
-
return fmt.format(now);
|
|
166
|
-
} catch {
|
|
167
|
-
}
|
|
168
|
-
}
|
|
169
|
-
const y = now.getFullYear();
|
|
170
|
-
const m = String(now.getMonth() + 1).padStart(2, "0");
|
|
171
|
-
const d = String(now.getDate()).padStart(2, "0");
|
|
172
|
-
return `${y}-${m}-${d}`;
|
|
173
|
-
}
|
|
174
|
-
function readFile(codeName) {
|
|
175
|
-
const path = dailySessionPath(codeName);
|
|
176
|
-
if (!existsSync2(path)) return { current: null, history: [] };
|
|
177
|
-
try {
|
|
178
|
-
const raw = readFileSync3(path, "utf-8");
|
|
179
|
-
const parsed = JSON.parse(raw);
|
|
180
|
-
return {
|
|
181
|
-
current: parsed.current ?? null,
|
|
182
|
-
history: Array.isArray(parsed.history) ? parsed.history : []
|
|
183
|
-
};
|
|
184
|
-
} catch {
|
|
185
|
-
return { current: null, history: [] };
|
|
186
|
-
}
|
|
187
|
-
}
|
|
188
|
-
function writeFile(codeName, data) {
|
|
189
|
-
const dir = profileDir(codeName);
|
|
190
|
-
mkdirSync(dir, { recursive: true });
|
|
191
|
-
const finalPath = dailySessionPath(codeName);
|
|
192
|
-
const tmpPath = `${finalPath}.${process.pid}.${randomUUID()}.tmp`;
|
|
193
|
-
writeFileSync2(tmpPath, JSON.stringify(data, null, 2), "utf-8");
|
|
194
|
-
renameSync(tmpPath, finalPath);
|
|
195
|
-
}
|
|
196
|
-
function trimHistory(history, now, timezone) {
|
|
197
|
-
const cutoff = new Date(now);
|
|
198
|
-
cutoff.setDate(cutoff.getDate() - HISTORY_DAYS);
|
|
199
|
-
const cutoffIso = todayLocalIso(cutoff, timezone);
|
|
200
|
-
return history.filter((h) => h.date >= cutoffIso).slice(0, HISTORY_DAYS);
|
|
201
|
-
}
|
|
202
|
-
function getOrCreateDailySession(codeName, now = /* @__PURE__ */ new Date(), timezone) {
|
|
203
|
-
const today = todayLocalIso(now, timezone);
|
|
204
|
-
const file = readFile(codeName);
|
|
205
|
-
if (file.current && file.current.date === today) {
|
|
206
|
-
return { sessionId: file.current.sessionId, isNew: false };
|
|
207
|
-
}
|
|
208
|
-
const next = {
|
|
209
|
-
date: today,
|
|
210
|
-
sessionId: randomUUID(),
|
|
211
|
-
startedAt: now.toISOString()
|
|
212
|
-
};
|
|
213
|
-
const history = trimHistory(
|
|
214
|
-
[...file.current ? [file.current] : [], ...file.history],
|
|
215
|
-
now,
|
|
216
|
-
timezone
|
|
217
|
-
);
|
|
218
|
-
writeFile(codeName, { current: next, history });
|
|
219
|
-
return { sessionId: next.sessionId, isNew: true };
|
|
220
|
-
}
|
|
221
|
-
function markDailySessionSpawn(codeName, sessionId, now = /* @__PURE__ */ new Date(), timezone) {
|
|
222
|
-
const today = todayLocalIso(now, timezone);
|
|
223
|
-
const file = readFile(codeName);
|
|
224
|
-
if (file.current && file.current.date === today && file.current.sessionId === sessionId) {
|
|
225
|
-
return;
|
|
226
|
-
}
|
|
227
|
-
const next = {
|
|
228
|
-
date: today,
|
|
229
|
-
sessionId,
|
|
230
|
-
startedAt: now.toISOString()
|
|
231
|
-
};
|
|
232
|
-
const history = trimHistory(
|
|
233
|
-
[...file.current ? [file.current] : [], ...file.history],
|
|
234
|
-
now,
|
|
235
|
-
timezone
|
|
236
|
-
);
|
|
237
|
-
writeFile(codeName, { current: next, history });
|
|
238
|
-
}
|
|
239
|
-
function rotateDailySession(codeName, now = /* @__PURE__ */ new Date(), timezone) {
|
|
240
|
-
const today = todayLocalIso(now, timezone);
|
|
241
|
-
const file = readFile(codeName);
|
|
242
|
-
const next = {
|
|
243
|
-
date: today,
|
|
244
|
-
sessionId: randomUUID(),
|
|
245
|
-
startedAt: now.toISOString()
|
|
246
|
-
};
|
|
247
|
-
const history = trimHistory(
|
|
248
|
-
[...file.current ? [file.current] : [], ...file.history],
|
|
249
|
-
now,
|
|
250
|
-
timezone
|
|
251
|
-
);
|
|
252
|
-
writeFile(codeName, { current: next, history });
|
|
253
|
-
return next.sessionId;
|
|
254
|
-
}
|
|
255
|
-
function encodeProjectPath(projectDir) {
|
|
256
|
-
return "-" + projectDir.replace(/^\//, "").replace(/[/.]/g, "-");
|
|
257
|
-
}
|
|
258
|
-
function sessionFileExists(projectDir, sessionId) {
|
|
259
|
-
const path = join(
|
|
260
|
-
homedir(),
|
|
261
|
-
".claude",
|
|
262
|
-
"projects",
|
|
263
|
-
encodeProjectPath(projectDir),
|
|
264
|
-
`${sessionId}.jsonl`
|
|
265
|
-
);
|
|
266
|
-
return existsSync2(path);
|
|
267
|
-
}
|
|
268
|
-
function sessionTranscriptDir(projectDir) {
|
|
269
|
-
return join(homedir(), ".claude", "projects", encodeProjectPath(projectDir));
|
|
270
|
-
}
|
|
271
|
-
function sessionFilePath(projectDir, sessionId) {
|
|
272
|
-
return join(sessionTranscriptDir(projectDir), `${sessionId}.jsonl`);
|
|
273
|
-
}
|
|
274
|
-
function isAgentIdle(projectDir, sessionId, idleSeconds = 60, now = /* @__PURE__ */ new Date()) {
|
|
275
|
-
const path = sessionFilePath(projectDir, sessionId);
|
|
276
|
-
if (!existsSync2(path)) return true;
|
|
277
|
-
try {
|
|
278
|
-
const mtimeMs = statSync(path).mtimeMs;
|
|
279
|
-
return now.getTime() - mtimeMs >= idleSeconds * 1e3;
|
|
280
|
-
} catch {
|
|
281
|
-
return false;
|
|
282
|
-
}
|
|
283
|
-
}
|
|
284
|
-
function isStaleForToday(codeName, now = /* @__PURE__ */ new Date(), timezone) {
|
|
285
|
-
const file = readFile(codeName);
|
|
286
|
-
if (!file.current) return false;
|
|
287
|
-
return file.current.date !== todayLocalIso(now, timezone);
|
|
288
|
-
}
|
|
289
|
-
function peekCurrentSession(codeName) {
|
|
290
|
-
return readFile(codeName).current;
|
|
291
|
-
}
|
|
292
163
|
|
|
293
164
|
// ../../packages/core/dist/runtime/session-probe.js
|
|
294
165
|
import { execFileSync } from "child_process";
|
|
@@ -570,7 +441,7 @@ function syncClaudeCredsToRoot() {
|
|
|
570
441
|
if (platform() !== "linux") return true;
|
|
571
442
|
if (typeof process.getuid !== "function" || process.getuid() !== 0) return true;
|
|
572
443
|
for (const filename of [".credentials.json", "credentials.json"]) {
|
|
573
|
-
if (
|
|
444
|
+
if (existsSync2(join("/root/.claude", filename))) return true;
|
|
574
445
|
}
|
|
575
446
|
let sourcePath = null;
|
|
576
447
|
try {
|
|
@@ -578,8 +449,8 @@ function syncClaudeCredsToRoot() {
|
|
|
578
449
|
outer: for (const entry of entries) {
|
|
579
450
|
if (!entry.isDirectory()) continue;
|
|
580
451
|
for (const filename of [".credentials.json", "credentials.json"]) {
|
|
581
|
-
const candidate =
|
|
582
|
-
if (
|
|
452
|
+
const candidate = join("/home", entry.name, ".claude", filename);
|
|
453
|
+
if (existsSync2(candidate)) {
|
|
583
454
|
sourcePath = candidate;
|
|
584
455
|
break outer;
|
|
585
456
|
}
|
|
@@ -590,9 +461,9 @@ function syncClaudeCredsToRoot() {
|
|
|
590
461
|
if (!sourcePath) return false;
|
|
591
462
|
const targetDir = "/root/.claude";
|
|
592
463
|
const sourceFilename = sourcePath.endsWith("credentials.json") && !sourcePath.endsWith(".credentials.json") ? "credentials.json" : ".credentials.json";
|
|
593
|
-
const targetPath =
|
|
464
|
+
const targetPath = join(targetDir, sourceFilename);
|
|
594
465
|
try {
|
|
595
|
-
if (!
|
|
466
|
+
if (!existsSync2(targetDir)) mkdirSync(targetDir, { recursive: true, mode: 448 });
|
|
596
467
|
copyFileSync(sourcePath, targetPath);
|
|
597
468
|
chmodSync(targetPath, 384);
|
|
598
469
|
return true;
|
|
@@ -604,13 +475,13 @@ var cachedClaudePath = null;
|
|
|
604
475
|
function resolveClaudeBinary() {
|
|
605
476
|
if (cachedClaudePath) return cachedClaudePath;
|
|
606
477
|
const override = process.env.CLAUDE_PATH;
|
|
607
|
-
if (override &&
|
|
478
|
+
if (override && existsSync2(override)) {
|
|
608
479
|
cachedClaudePath = override;
|
|
609
480
|
return override;
|
|
610
481
|
}
|
|
611
482
|
try {
|
|
612
483
|
const out = execSync("which claude 2>/dev/null", { encoding: "utf-8" }).trim();
|
|
613
|
-
if (out &&
|
|
484
|
+
if (out && existsSync2(out)) {
|
|
614
485
|
cachedClaudePath = out;
|
|
615
486
|
return out;
|
|
616
487
|
}
|
|
@@ -622,7 +493,7 @@ function resolveClaudeBinary() {
|
|
|
622
493
|
"/usr/local/bin/claude"
|
|
623
494
|
];
|
|
624
495
|
for (const p of candidates) {
|
|
625
|
-
if (
|
|
496
|
+
if (existsSync2(p)) {
|
|
626
497
|
cachedClaudePath = p;
|
|
627
498
|
return p;
|
|
628
499
|
}
|
|
@@ -631,8 +502,8 @@ function resolveClaudeBinary() {
|
|
|
631
502
|
}
|
|
632
503
|
function writePersistentClaudeWrapper(args) {
|
|
633
504
|
const { projectDir, claudeBin, initPrompt, claudeArgsJoined } = args;
|
|
634
|
-
const envIntegrationsPath =
|
|
635
|
-
const wrapperPath =
|
|
505
|
+
const envIntegrationsPath = join(projectDir, ".env.integrations");
|
|
506
|
+
const wrapperPath = join(projectDir, ".claude", "persistent-claude.sh");
|
|
636
507
|
const wrapperLines = [
|
|
637
508
|
"#!/usr/bin/env bash",
|
|
638
509
|
"set -e",
|
|
@@ -640,7 +511,7 @@ function writePersistentClaudeWrapper(args) {
|
|
|
640
511
|
// --dangerously-skip-permissions on dedicated EC2 hosts.
|
|
641
512
|
"export IS_SANDBOX=1"
|
|
642
513
|
];
|
|
643
|
-
if (
|
|
514
|
+
if (existsSync2(envIntegrationsPath)) {
|
|
644
515
|
wrapperLines.push(
|
|
645
516
|
"set -a",
|
|
646
517
|
`source ${JSON.stringify(envIntegrationsPath)}`,
|
|
@@ -651,15 +522,15 @@ function writePersistentClaudeWrapper(args) {
|
|
|
651
522
|
wrapperLines.push(
|
|
652
523
|
`exec ${JSON.stringify(claudeBin)} ${initPromptArg}${claudeArgsJoined}`
|
|
653
524
|
);
|
|
654
|
-
|
|
655
|
-
|
|
525
|
+
mkdirSync(join(projectDir, ".claude"), { recursive: true });
|
|
526
|
+
writeFileSync2(wrapperPath, wrapperLines.join("\n") + "\n", { mode: 448 });
|
|
656
527
|
chmodSync(wrapperPath, 448);
|
|
657
528
|
return wrapperPath;
|
|
658
529
|
}
|
|
659
530
|
function collectMcpServerNames(mcpConfigPath) {
|
|
660
|
-
if (!
|
|
531
|
+
if (!existsSync2(mcpConfigPath)) return [];
|
|
661
532
|
try {
|
|
662
|
-
const data = JSON.parse(
|
|
533
|
+
const data = JSON.parse(readFileSync3(mcpConfigPath, "utf-8"));
|
|
663
534
|
const servers = data.mcpServers;
|
|
664
535
|
return servers ? Object.keys(servers) : [];
|
|
665
536
|
} catch {
|
|
@@ -672,8 +543,8 @@ function getAcpxBin() {
|
|
|
672
543
|
const moduleDir = dirname(fileURLToPath(import.meta.url));
|
|
673
544
|
let dir = moduleDir;
|
|
674
545
|
for (let i = 0; i < 6; i++) {
|
|
675
|
-
const candidate =
|
|
676
|
-
if (
|
|
546
|
+
const candidate = join(dir, "node_modules", ".bin", "acpx");
|
|
547
|
+
if (existsSync2(candidate)) {
|
|
677
548
|
_acpxBin = candidate;
|
|
678
549
|
return _acpxBin;
|
|
679
550
|
}
|
|
@@ -703,6 +574,16 @@ function defaultAcpxSessionProbe(acpxBin, projectDir) {
|
|
|
703
574
|
}
|
|
704
575
|
var acpxSessionProbe = defaultAcpxSessionProbe;
|
|
705
576
|
var acpxSessionAvailableCache = /* @__PURE__ */ new Map();
|
|
577
|
+
var acpxExecFailureCounts = /* @__PURE__ */ new Map();
|
|
578
|
+
function takeAcpxExecFailureCount(codeName) {
|
|
579
|
+
const count = acpxExecFailureCounts.get(codeName) ?? 0;
|
|
580
|
+
acpxExecFailureCounts.delete(codeName);
|
|
581
|
+
return count;
|
|
582
|
+
}
|
|
583
|
+
function creditAcpxExecFailureCount(codeName, count) {
|
|
584
|
+
if (count <= 0) return;
|
|
585
|
+
acpxExecFailureCounts.set(codeName, (acpxExecFailureCounts.get(codeName) ?? 0) + count);
|
|
586
|
+
}
|
|
706
587
|
function hasAcpxSession(acpxBin, projectDir, codeName) {
|
|
707
588
|
const cached = acpxSessionAvailableCache.get(codeName);
|
|
708
589
|
if (cached !== void 0) return cached;
|
|
@@ -711,15 +592,15 @@ function hasAcpxSession(acpxBin, projectDir, codeName) {
|
|
|
711
592
|
return available;
|
|
712
593
|
}
|
|
713
594
|
var sessions = /* @__PURE__ */ new Map();
|
|
714
|
-
var PANE_LOG_DIR =
|
|
595
|
+
var PANE_LOG_DIR = join(homedir(), ".augmented");
|
|
715
596
|
var PANE_TAIL_LINES = 20;
|
|
716
597
|
function paneLogPath(codeName) {
|
|
717
|
-
return
|
|
598
|
+
return join(PANE_LOG_DIR, codeName, "pane.log");
|
|
718
599
|
}
|
|
719
600
|
function setupPaneLog(tmuxSession, codeName, log) {
|
|
720
601
|
const logPath = paneLogPath(codeName);
|
|
721
602
|
try {
|
|
722
|
-
|
|
603
|
+
mkdirSync(dirname(logPath), { recursive: true });
|
|
723
604
|
appendFileSync(
|
|
724
605
|
logPath,
|
|
725
606
|
`
|
|
@@ -737,9 +618,9 @@ function setupPaneLog(tmuxSession, codeName, log) {
|
|
|
737
618
|
}
|
|
738
619
|
function readPaneLogTail(codeName, lines = PANE_TAIL_LINES) {
|
|
739
620
|
const logPath = paneLogPath(codeName);
|
|
740
|
-
if (!
|
|
621
|
+
if (!existsSync2(logPath)) return null;
|
|
741
622
|
try {
|
|
742
|
-
const raw =
|
|
623
|
+
const raw = readFileSync3(logPath, "utf-8");
|
|
743
624
|
if (!raw) return null;
|
|
744
625
|
const stripped = raw.replace(/\x1b\[[0-9;?]*[A-Za-z]/g, "");
|
|
745
626
|
const all = stripped.split("\n").filter((l) => l.length > 0);
|
|
@@ -770,6 +651,15 @@ function prepareForRespawn(codeName) {
|
|
|
770
651
|
}
|
|
771
652
|
return null;
|
|
772
653
|
}
|
|
654
|
+
function rotateSessionForWedge(codeName, now = /* @__PURE__ */ new Date()) {
|
|
655
|
+
const session = sessions.get(codeName);
|
|
656
|
+
const newId = rotateDailySession(codeName, now, session?.agentTimezone ?? void 0);
|
|
657
|
+
if (session) {
|
|
658
|
+
session.consecutiveSameUuidFailures = 0;
|
|
659
|
+
session.lastFailureSessionId = null;
|
|
660
|
+
}
|
|
661
|
+
return newId;
|
|
662
|
+
}
|
|
773
663
|
function getLastFailureContext(codeName) {
|
|
774
664
|
const session = sessions.get(codeName);
|
|
775
665
|
return {
|
|
@@ -785,7 +675,7 @@ function resolveSessionSpawnDecision(args) {
|
|
|
785
675
|
const disableFlag = process.env["AGT_DISABLE_SESSION_RESUME"];
|
|
786
676
|
const resumeDisabled = disableFlag === "1" || disableFlag?.toLowerCase() === "true";
|
|
787
677
|
if (resumeDisabled) {
|
|
788
|
-
return { flag: "--session-id", sessionId:
|
|
678
|
+
return { flag: "--session-id", sessionId: randomUUID(), reason: "resume-disabled" };
|
|
789
679
|
}
|
|
790
680
|
const daily = getOrCreateDailySession(codeName, now, agentTimezone);
|
|
791
681
|
if (!daily.isNew && sessionFileExists(projectDir, daily.sessionId)) {
|
|
@@ -845,10 +735,10 @@ function spawnSession(config, session) {
|
|
|
845
735
|
log(`[persistent-session] No Claude Code credentials found under /root/.claude or /home/*. Pair via browser from the host page, or run 'claude /login' on the host.`);
|
|
846
736
|
}
|
|
847
737
|
} else {
|
|
848
|
-
const claudeDir =
|
|
738
|
+
const claudeDir = join(homedir(), ".claude");
|
|
849
739
|
for (const filename of [".credentials.json", "credentials.json"]) {
|
|
850
|
-
const p =
|
|
851
|
-
if (
|
|
740
|
+
const p = join(claudeDir, filename);
|
|
741
|
+
if (existsSync2(p)) {
|
|
852
742
|
try {
|
|
853
743
|
rmSync(p, { force: true });
|
|
854
744
|
log(`[persistent-session] Removed ${p} (api_key mode active \u2014 preventing OAuth fallback)`);
|
|
@@ -882,7 +772,7 @@ function spawnSession(config, session) {
|
|
|
882
772
|
if (channels.length > 0) args.push("--channels", ...channels);
|
|
883
773
|
if (devChannels.length > 0) args.push("--dangerously-load-development-channels", ...devChannels);
|
|
884
774
|
args.push("--mcp-config", mcpConfigPath);
|
|
885
|
-
if (
|
|
775
|
+
if (existsSync2(claudeMdPath)) args.push("--system-prompt-file", claudeMdPath);
|
|
886
776
|
const modelAlias = claudeModelAlias(config.primaryModel);
|
|
887
777
|
if (modelAlias) args.push("--model", modelAlias);
|
|
888
778
|
args.push("--allow-dangerously-skip-permissions");
|
|
@@ -910,7 +800,7 @@ function spawnSession(config, session) {
|
|
|
910
800
|
// Treat empty-string as missing too — `HOME=""` makes ~ resolve
|
|
911
801
|
// to cwd, which is the same broken outcome as no HOME, just
|
|
912
802
|
// better hidden.
|
|
913
|
-
HOME: process.env.HOME?.trim() ||
|
|
803
|
+
HOME: process.env.HOME?.trim() || homedir(),
|
|
914
804
|
USER: process.env.USER?.trim() || userInfo().username
|
|
915
805
|
};
|
|
916
806
|
if (config.runId) {
|
|
@@ -918,7 +808,7 @@ function spawnSession(config, session) {
|
|
|
918
808
|
}
|
|
919
809
|
for (const f of probeMcpEnvSubstitution({
|
|
920
810
|
mcpConfigPath,
|
|
921
|
-
envIntegrationsPath:
|
|
811
|
+
envIntegrationsPath: join(projectDir, ".env.integrations"),
|
|
922
812
|
baseEnv: {
|
|
923
813
|
...tmuxEnv,
|
|
924
814
|
...claudeAuthMode === "api_key" && config.anthropicApiKey ? { ANTHROPIC_API_KEY: config.anthropicApiKey } : {}
|
|
@@ -1234,10 +1124,10 @@ async function injectMessageWithStatus(codeName, type, content, meta, log) {
|
|
|
1234
1124
|
const acpx = getAcpxBin();
|
|
1235
1125
|
if (acpx && hasAcpxSession(acpx, projectDir, codeName)) {
|
|
1236
1126
|
try {
|
|
1237
|
-
const tmpDir =
|
|
1238
|
-
|
|
1239
|
-
const tmpFile =
|
|
1240
|
-
|
|
1127
|
+
const tmpDir = join(projectDir, ".claude");
|
|
1128
|
+
mkdirSync(tmpDir, { recursive: true });
|
|
1129
|
+
const tmpFile = join(tmpDir, ".agt-inject-prompt.txt");
|
|
1130
|
+
writeFileSync2(tmpFile, text);
|
|
1241
1131
|
_log(`[inject] acpx exec (fire-and-forget): cwd=${projectDir}, file=${tmpFile}`);
|
|
1242
1132
|
const child = spawn(acpx, ["claude", "exec", "-f", tmpFile], {
|
|
1243
1133
|
cwd: projectDir,
|
|
@@ -1246,10 +1136,15 @@ async function injectMessageWithStatus(codeName, type, content, meta, log) {
|
|
|
1246
1136
|
});
|
|
1247
1137
|
child.on("error", (err) => {
|
|
1248
1138
|
_log(`[inject] acpx spawn error for '${codeName}': ${err.message}`);
|
|
1139
|
+
acpxExecFailureCounts.set(codeName, (acpxExecFailureCounts.get(codeName) ?? 0) + 1);
|
|
1249
1140
|
});
|
|
1250
1141
|
child.on("exit", (code) => {
|
|
1251
1142
|
if (code && code !== 0) {
|
|
1252
|
-
|
|
1143
|
+
const exit4Detail = code === 4 ? " (no acpx session)" : "";
|
|
1144
|
+
_log(
|
|
1145
|
+
`[inject] acpx exec exited ${code}${exit4Detail} for '${codeName}' \u2014 type=${type} input_hash=${simpleTextHash(text)} len=${text.length} \u2014 message may not have been delivered`
|
|
1146
|
+
);
|
|
1147
|
+
acpxExecFailureCounts.set(codeName, (acpxExecFailureCounts.get(codeName) ?? 0) + 1);
|
|
1253
1148
|
acpxSessionAvailableCache.delete(codeName);
|
|
1254
1149
|
}
|
|
1255
1150
|
});
|
|
@@ -1279,8 +1174,15 @@ function stopPersistentSession(codeName, log) {
|
|
|
1279
1174
|
log(`[persistent-session] Stopping session for '${codeName}'`);
|
|
1280
1175
|
session.status = "stopped";
|
|
1281
1176
|
try {
|
|
1282
|
-
|
|
1283
|
-
} catch {
|
|
1177
|
+
execFileSync3("tmux", ["kill-session", "-t", `agt-${codeName}`], { stdio: ["ignore", "ignore", "pipe"] });
|
|
1178
|
+
} catch (err) {
|
|
1179
|
+
const stderr = (err.stderr ?? "").toString().trim();
|
|
1180
|
+
const alreadyGone = /can't find session|no server running/i.test(stderr);
|
|
1181
|
+
if (!alreadyGone) {
|
|
1182
|
+
log(
|
|
1183
|
+
`[persistent-session] WARN tmux kill-session for '${codeName}' failed unexpectedly: ${stderr || err.message} \u2014 the session may still be running (ENG-6174)`
|
|
1184
|
+
);
|
|
1185
|
+
}
|
|
1284
1186
|
}
|
|
1285
1187
|
try {
|
|
1286
1188
|
const acpx = getAcpxBin();
|
|
@@ -1288,10 +1190,15 @@ function stopPersistentSession(codeName, log) {
|
|
|
1288
1190
|
execFileSync3(acpx, ["claude", "sessions", "close", `agt-${codeName}`], {
|
|
1289
1191
|
cwd: getProjectDir(codeName),
|
|
1290
1192
|
timeout: 5e3,
|
|
1291
|
-
stdio: "ignore"
|
|
1193
|
+
stdio: ["ignore", "ignore", "pipe"]
|
|
1292
1194
|
});
|
|
1293
1195
|
}
|
|
1294
|
-
} catch {
|
|
1196
|
+
} catch (err) {
|
|
1197
|
+
const stderr = (err.stderr ?? "").toString().trim();
|
|
1198
|
+
const benign = /not found|no such session|unknown session/i.test(stderr);
|
|
1199
|
+
if (stderr && !benign) {
|
|
1200
|
+
log(`[persistent-session] acpx sessions close for '${codeName}' failed: ${stderr} (ENG-6174)`);
|
|
1201
|
+
}
|
|
1295
1202
|
}
|
|
1296
1203
|
sessions.delete(codeName);
|
|
1297
1204
|
acpxSessionAvailableCache.delete(codeName);
|
|
@@ -1470,7 +1377,7 @@ async function stopAllSessionsAndWait(log, opts) {
|
|
|
1470
1377
|
await new Promise((resolve) => setTimeout(resolve, Math.min(opts.timeoutMs, 2e3)));
|
|
1471
1378
|
}
|
|
1472
1379
|
function getProjectDir(codeName) {
|
|
1473
|
-
return
|
|
1380
|
+
return join(homedir(), ".augmented", codeName, "project");
|
|
1474
1381
|
}
|
|
1475
1382
|
function writeAcpxConfig(config) {
|
|
1476
1383
|
const {
|
|
@@ -1486,7 +1393,7 @@ function writeAcpxConfig(config) {
|
|
|
1486
1393
|
if (channels.length > 0) claudeArgs.push("--channels", ...channels);
|
|
1487
1394
|
if (devChannels.length > 0) claudeArgs.push("--dangerously-load-development-channels", ...devChannels);
|
|
1488
1395
|
claudeArgs.push("--mcp-config", mcpConfigPath);
|
|
1489
|
-
if (
|
|
1396
|
+
if (existsSync2(claudeMdPath)) claudeArgs.push("--system-prompt-file", claudeMdPath);
|
|
1490
1397
|
const acpModelAlias = claudeModelAlias(config.primaryModel);
|
|
1491
1398
|
if (acpModelAlias) claudeArgs.push("--model", acpModelAlias);
|
|
1492
1399
|
claudeArgs.push("--allow-dangerously-skip-permissions");
|
|
@@ -1495,18 +1402,18 @@ function writeAcpxConfig(config) {
|
|
|
1495
1402
|
const mcpServerNames2 = collectMcpServerNames(mcpConfigPath);
|
|
1496
1403
|
claudeArgs.push("--allowedTools", buildAllowedTools(mcpServerNames2));
|
|
1497
1404
|
const acpCmd = `npx -y @agentclientprotocol/claude-agent-acp ${claudeArgs.map((a) => a.includes(" ") || a.includes("*") ? JSON.stringify(a) : a).join(" ")}`;
|
|
1498
|
-
const envIntegrationsPath =
|
|
1499
|
-
const wrapperPath =
|
|
1405
|
+
const envIntegrationsPath = join(projectDir, ".env.integrations");
|
|
1406
|
+
const wrapperPath = join(projectDir, ".claude", "acpx-agent.sh");
|
|
1500
1407
|
const wrapperLines = ["#!/usr/bin/env bash"];
|
|
1501
|
-
if (
|
|
1408
|
+
if (existsSync2(envIntegrationsPath)) {
|
|
1502
1409
|
wrapperLines.push(`set -a`, `source ${JSON.stringify(envIntegrationsPath)}`, `set +a`);
|
|
1503
1410
|
}
|
|
1504
1411
|
if (claudeAuthMode === "api_key" && anthropicApiKey) {
|
|
1505
1412
|
wrapperLines.push(`export ANTHROPIC_API_KEY=${JSON.stringify(anthropicApiKey)}`);
|
|
1506
1413
|
}
|
|
1507
1414
|
wrapperLines.push(`exec ${acpCmd}`);
|
|
1508
|
-
|
|
1509
|
-
|
|
1415
|
+
mkdirSync(join(projectDir, ".claude"), { recursive: true });
|
|
1416
|
+
writeFileSync2(wrapperPath, wrapperLines.join("\n") + "\n", { mode: 493 });
|
|
1510
1417
|
chmodSync(wrapperPath, 493);
|
|
1511
1418
|
const acpxConfig = {
|
|
1512
1419
|
defaultAgent: "claude",
|
|
@@ -1517,27 +1424,27 @@ function writeAcpxConfig(config) {
|
|
|
1517
1424
|
}
|
|
1518
1425
|
}
|
|
1519
1426
|
};
|
|
1520
|
-
|
|
1427
|
+
writeFileSync2(join(projectDir, ".acpxrc.json"), JSON.stringify(acpxConfig, null, 2));
|
|
1521
1428
|
}
|
|
1522
1429
|
|
|
1523
1430
|
export {
|
|
1524
1431
|
formatMissingVar,
|
|
1432
|
+
expandTemplateVars,
|
|
1525
1433
|
parseEnvIntegrations,
|
|
1526
1434
|
probeMcpEnvSubstitution,
|
|
1527
1435
|
sanitizeMcpJson,
|
|
1528
1436
|
buildAllowedTools,
|
|
1529
|
-
sessionTranscriptDir,
|
|
1530
|
-
isAgentIdle,
|
|
1531
|
-
isStaleForToday,
|
|
1532
|
-
peekCurrentSession,
|
|
1533
1437
|
checkChannelInputs,
|
|
1534
1438
|
takeWatchdogGiveUpCount,
|
|
1535
1439
|
creditWatchdogGiveUpCount,
|
|
1536
1440
|
resolveClaudeBinary,
|
|
1537
1441
|
writePersistentClaudeWrapper,
|
|
1442
|
+
takeAcpxExecFailureCount,
|
|
1443
|
+
creditAcpxExecFailureCount,
|
|
1538
1444
|
paneLogPath,
|
|
1539
1445
|
readPaneLogTail,
|
|
1540
1446
|
prepareForRespawn,
|
|
1447
|
+
rotateSessionForWedge,
|
|
1541
1448
|
getLastFailureContext,
|
|
1542
1449
|
resolveSessionSpawnDecision,
|
|
1543
1450
|
startPersistentSession,
|
|
@@ -1557,4 +1464,4 @@ export {
|
|
|
1557
1464
|
stopAllSessionsAndWait,
|
|
1558
1465
|
getProjectDir
|
|
1559
1466
|
};
|
|
1560
|
-
//# sourceMappingURL=chunk-
|
|
1467
|
+
//# sourceMappingURL=chunk-7GKJZBTB.js.map
|