@integrity-labs/agt-cli 0.28.702 → 0.28.703
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.
|
@@ -54,7 +54,7 @@ import {
|
|
|
54
54
|
safeWriteJsonAtomic,
|
|
55
55
|
setConfigHash,
|
|
56
56
|
tripClass
|
|
57
|
-
} from "../chunk-
|
|
57
|
+
} from "../chunk-K5RGYOQ2.js";
|
|
58
58
|
import {
|
|
59
59
|
getProjectDir as getProjectDir2,
|
|
60
60
|
getReadyTasks,
|
|
@@ -204,7 +204,7 @@ import {
|
|
|
204
204
|
|
|
205
205
|
// src/lib/manager-worker.ts
|
|
206
206
|
import { createHash as createHash17 } from "crypto";
|
|
207
|
-
import { readFileSync as readFileSync29, writeFileSync as writeFileSync14, mkdirSync as mkdirSync11, existsSync as
|
|
207
|
+
import { readFileSync as readFileSync29, writeFileSync as writeFileSync14, mkdirSync as mkdirSync11, existsSync as existsSync17, rmSync as rmSync5, readdirSync as readdirSync10, statSync as statSync8, unlinkSync as unlinkSync6, renameSync as renameSync8, utimesSync } from "fs";
|
|
208
208
|
|
|
209
209
|
// src/lib/atomic-file-replace.ts
|
|
210
210
|
import { copyFileSync, renameSync, unlinkSync } from "fs";
|
|
@@ -230,8 +230,8 @@ function defaultUnique() {
|
|
|
230
230
|
|
|
231
231
|
// src/lib/manager-worker.ts
|
|
232
232
|
import { execFileSync as syncExecFile } from "child_process";
|
|
233
|
-
import { join as
|
|
234
|
-
import { homedir as
|
|
233
|
+
import { join as join38, dirname as dirname10, delimiter as pathDelimiter } from "path";
|
|
234
|
+
import { homedir as homedir18 } from "os";
|
|
235
235
|
import { fileURLToPath } from "url";
|
|
236
236
|
|
|
237
237
|
// src/lib/single-flight.ts
|
|
@@ -298,6 +298,168 @@ function claudeCodeUpgradeThrottled() {
|
|
|
298
298
|
}
|
|
299
299
|
}
|
|
300
300
|
|
|
301
|
+
// src/lib/drain-transcript-flush.ts
|
|
302
|
+
import { existsSync, readdirSync } from "fs";
|
|
303
|
+
import { homedir as homedir2 } from "os";
|
|
304
|
+
import { join as join3, relative, sep } from "path";
|
|
305
|
+
import { spawn } from "child_process";
|
|
306
|
+
|
|
307
|
+
// src/lib/host-archive-address.ts
|
|
308
|
+
import { readFileSync as readFileSync2 } from "fs";
|
|
309
|
+
var DEFAULT_ARCHIVE_ADDRESS_PATH = "/var/lib/augmented/session-archive-address.json";
|
|
310
|
+
var CACHE_TTL_MS = 5 * 60 * 1e3;
|
|
311
|
+
var cache = /* @__PURE__ */ new Map();
|
|
312
|
+
function str(value) {
|
|
313
|
+
if (typeof value !== "string") return null;
|
|
314
|
+
const trimmed = value.trim();
|
|
315
|
+
return trimmed.length > 0 ? trimmed : null;
|
|
316
|
+
}
|
|
317
|
+
function readHostArchiveAddress(path) {
|
|
318
|
+
const file = path ?? process.env["ARCHIVE_ADDRESS_FILE"]?.trim() ?? process.env["AGT_SESSION_ARCHIVE_ADDRESS_FILE"]?.trim() ?? DEFAULT_ARCHIVE_ADDRESS_PATH;
|
|
319
|
+
const now = Date.now();
|
|
320
|
+
const hit = cache.get(file);
|
|
321
|
+
if (hit && now - hit.at < CACHE_TTL_MS) return hit.value;
|
|
322
|
+
let value = null;
|
|
323
|
+
try {
|
|
324
|
+
const raw = readFileSync2(file, "utf-8");
|
|
325
|
+
const parsed = JSON.parse(raw);
|
|
326
|
+
if (parsed && typeof parsed === "object" && !Array.isArray(parsed)) {
|
|
327
|
+
const obj = parsed;
|
|
328
|
+
const bucket = str(obj["bucket"]);
|
|
329
|
+
const keyPrefix = str(obj["key_prefix"]);
|
|
330
|
+
if (bucket && keyPrefix) {
|
|
331
|
+
value = {
|
|
332
|
+
bucket,
|
|
333
|
+
region: str(obj["region"]),
|
|
334
|
+
instanceId: str(obj["instance_id"]),
|
|
335
|
+
keyPrefix
|
|
336
|
+
};
|
|
337
|
+
}
|
|
338
|
+
}
|
|
339
|
+
} catch {
|
|
340
|
+
value = null;
|
|
341
|
+
}
|
|
342
|
+
cache.set(file, { at: now, value });
|
|
343
|
+
return value;
|
|
344
|
+
}
|
|
345
|
+
|
|
346
|
+
// src/lib/drain-transcript-flush.ts
|
|
347
|
+
function sessionsBaseDir() {
|
|
348
|
+
return join3(homedir2(), ".claude", "projects");
|
|
349
|
+
}
|
|
350
|
+
var PER_FILE_UPLOAD_TIMEOUT_MS = 3e4;
|
|
351
|
+
var UPLOAD_CONCURRENCY = 4;
|
|
352
|
+
function listJsonlFiles(dir) {
|
|
353
|
+
if (!existsSync(dir)) return [];
|
|
354
|
+
const out = [];
|
|
355
|
+
const walk = (d) => {
|
|
356
|
+
for (const entry of readdirSync(d, { withFileTypes: true })) {
|
|
357
|
+
const full = join3(d, entry.name);
|
|
358
|
+
if (entry.isDirectory()) walk(full);
|
|
359
|
+
else if (entry.isFile() && entry.name.endsWith(".jsonl")) out.push(full);
|
|
360
|
+
}
|
|
361
|
+
};
|
|
362
|
+
try {
|
|
363
|
+
walk(dir);
|
|
364
|
+
} catch {
|
|
365
|
+
}
|
|
366
|
+
return out;
|
|
367
|
+
}
|
|
368
|
+
function transcriptObjectKey(keyPrefix, baseDir, file) {
|
|
369
|
+
const rel = relative(baseDir, file).split(sep).join("/");
|
|
370
|
+
if (!rel || rel.startsWith("../") || rel === "..") return null;
|
|
371
|
+
return `${keyPrefix.replace(/\/+$/, "")}/${rel}`;
|
|
372
|
+
}
|
|
373
|
+
async function flushAgentTranscriptsOnDrain(codeName, deps) {
|
|
374
|
+
const dir = deps.resolveTranscriptDir(codeName);
|
|
375
|
+
const files = deps.listTranscripts(dir);
|
|
376
|
+
if (files.length === 0) {
|
|
377
|
+
return { status: "no-transcripts", uploaded: 0, failed: 0, total: 0 };
|
|
378
|
+
}
|
|
379
|
+
const address = deps.readAddress();
|
|
380
|
+
if (!address || !address.bucket || !address.keyPrefix) {
|
|
381
|
+
deps.log(
|
|
382
|
+
`[drain-flush] NO S3 ADDRESS for '${codeName}' \u2014 ${files.length} transcript file(s) will NOT be shipped before teardown; this session may be lost (ENG-9491). The host archive address is unresolved (agt-session-archiver has published none).`
|
|
383
|
+
);
|
|
384
|
+
return { status: "no-address", uploaded: 0, failed: files.length, total: files.length };
|
|
385
|
+
}
|
|
386
|
+
const { bucket, keyPrefix, region } = address;
|
|
387
|
+
let uploaded = 0;
|
|
388
|
+
let failed = 0;
|
|
389
|
+
let cursor = 0;
|
|
390
|
+
const worker = async () => {
|
|
391
|
+
for (; ; ) {
|
|
392
|
+
const i = cursor;
|
|
393
|
+
cursor += 1;
|
|
394
|
+
if (i >= files.length) return;
|
|
395
|
+
const file = files[i];
|
|
396
|
+
const key = transcriptObjectKey(keyPrefix, deps.baseDir, file);
|
|
397
|
+
if (!key) {
|
|
398
|
+
failed += 1;
|
|
399
|
+
deps.log(
|
|
400
|
+
`[drain-flush] SKIP '${file}' for '${codeName}' \u2014 outside sessions base dir '${deps.baseDir}', cannot key it (ENG-9491)`
|
|
401
|
+
);
|
|
402
|
+
continue;
|
|
403
|
+
}
|
|
404
|
+
const res = await deps.uploadFile({ file, bucket, key, region });
|
|
405
|
+
if (res.ok) {
|
|
406
|
+
uploaded += 1;
|
|
407
|
+
} else {
|
|
408
|
+
failed += 1;
|
|
409
|
+
deps.log(
|
|
410
|
+
`[drain-flush] UPLOAD FAILED for '${codeName}' '${file}' \u2192 s3://${bucket}/${key}: ${res.detail} (ENG-9491)`
|
|
411
|
+
);
|
|
412
|
+
}
|
|
413
|
+
}
|
|
414
|
+
};
|
|
415
|
+
await Promise.all(
|
|
416
|
+
Array.from({ length: Math.min(UPLOAD_CONCURRENCY, files.length) }, () => worker())
|
|
417
|
+
);
|
|
418
|
+
const status = failed === 0 ? "flushed" : uploaded === 0 ? "failed" : "partial";
|
|
419
|
+
if (status !== "flushed") {
|
|
420
|
+
deps.log(
|
|
421
|
+
`[drain-flush] INCOMPLETE for '${codeName}': ${uploaded}/${files.length} transcript file(s) shipped, ${failed} FAILED before teardown \u2014 session data may be lost (ENG-9491).`
|
|
422
|
+
);
|
|
423
|
+
}
|
|
424
|
+
return { status, uploaded, failed, total: files.length };
|
|
425
|
+
}
|
|
426
|
+
function drainTranscriptFlushDeps(log2) {
|
|
427
|
+
return {
|
|
428
|
+
resolveTranscriptDir: (codeName) => sessionTranscriptDir(getProjectDir(codeName)),
|
|
429
|
+
readAddress: () => readHostArchiveAddress(),
|
|
430
|
+
listTranscripts: listJsonlFiles,
|
|
431
|
+
baseDir: sessionsBaseDir(),
|
|
432
|
+
uploadFile: ({ file, bucket, key, region }) => new Promise((resolve2) => {
|
|
433
|
+
const args = ["s3", "cp", file, `s3://${bucket}/${key}`, "--only-show-errors"];
|
|
434
|
+
if (region) args.push("--region", region);
|
|
435
|
+
const child = spawn("aws", args, { stdio: ["ignore", "ignore", "pipe"] });
|
|
436
|
+
let stderr = "";
|
|
437
|
+
let settled = false;
|
|
438
|
+
const finish = (r) => {
|
|
439
|
+
if (settled) return;
|
|
440
|
+
settled = true;
|
|
441
|
+
clearTimeout(timer3);
|
|
442
|
+
resolve2(r);
|
|
443
|
+
};
|
|
444
|
+
const timer3 = setTimeout(() => {
|
|
445
|
+
child.kill("SIGKILL");
|
|
446
|
+
finish({ ok: false, detail: `aws s3 cp timed out after ${PER_FILE_UPLOAD_TIMEOUT_MS}ms` });
|
|
447
|
+
}, PER_FILE_UPLOAD_TIMEOUT_MS);
|
|
448
|
+
child.stderr?.on("data", (d) => {
|
|
449
|
+
stderr += String(d);
|
|
450
|
+
});
|
|
451
|
+
child.on("error", (err) => finish({ ok: false, detail: err.message }));
|
|
452
|
+
child.on(
|
|
453
|
+
"close",
|
|
454
|
+
(code) => finish(
|
|
455
|
+
code === 0 ? { ok: true, detail: "" } : { ok: false, detail: stderr.trim().slice(0, 500) || `aws exited with code ${code ?? "null"}` }
|
|
456
|
+
)
|
|
457
|
+
);
|
|
458
|
+
}),
|
|
459
|
+
log: log2
|
|
460
|
+
};
|
|
461
|
+
}
|
|
462
|
+
|
|
301
463
|
// src/lib/mcp-config-drift.ts
|
|
302
464
|
import { createHash } from "crypto";
|
|
303
465
|
function decideMcpDriftAction(currentHash, knownHash) {
|
|
@@ -724,7 +886,7 @@ function isSlackBehaviourRestrictive(subset) {
|
|
|
724
886
|
}
|
|
725
887
|
|
|
726
888
|
// src/lib/onboarding-drive.ts
|
|
727
|
-
import { mkdirSync as mkdirSync2, readFileSync as
|
|
889
|
+
import { mkdirSync as mkdirSync2, readFileSync as readFileSync3, rmSync, writeFileSync as writeFileSync2 } from "fs";
|
|
728
890
|
import { dirname as dirname3 } from "path";
|
|
729
891
|
var ONBOARDING_REINJECT_INTERVAL_MS = 45 * 6e4;
|
|
730
892
|
var ONBOARDING_MAX_NUDGES = 3;
|
|
@@ -851,7 +1013,7 @@ function onboardingNudgeReachedSession(result) {
|
|
|
851
1013
|
}
|
|
852
1014
|
function readOnboardingDriveMarker(path) {
|
|
853
1015
|
try {
|
|
854
|
-
const raw = JSON.parse(
|
|
1016
|
+
const raw = JSON.parse(readFileSync3(path, "utf8"));
|
|
855
1017
|
if (typeof raw.step === "string" && isOnboardingArea(raw.step) && typeof raw.injectedAtMs === "number" && Number.isFinite(raw.injectedAtMs)) {
|
|
856
1018
|
const legacyInjects = typeof raw.nudgeCount === "number" && Number.isFinite(raw.nudgeCount) && raw.nudgeCount >= 1 ? Math.floor(raw.nudgeCount) : 1;
|
|
857
1019
|
const hasNewCounters = typeof raw.injectCount === "number" && Number.isFinite(raw.injectCount) && raw.injectCount >= 1;
|
|
@@ -887,8 +1049,8 @@ function clearOnboardingDriveMarker(path) {
|
|
|
887
1049
|
}
|
|
888
1050
|
|
|
889
1051
|
// src/lib/channel-quarantine.ts
|
|
890
|
-
import { readFileSync as
|
|
891
|
-
import { join as
|
|
1052
|
+
import { readFileSync as readFileSync4 } from "fs";
|
|
1053
|
+
import { join as join4 } from "path";
|
|
892
1054
|
var ESSENTIAL_CHANNEL_KEYS = /* @__PURE__ */ new Set(["direct-chat", "augmented"]);
|
|
893
1055
|
var OPTIONAL_CHANNEL_KEYS = /* @__PURE__ */ new Set([
|
|
894
1056
|
"telegram",
|
|
@@ -920,7 +1082,7 @@ function classifyChannelCriticality(serverKey, entry) {
|
|
|
920
1082
|
return "essential";
|
|
921
1083
|
}
|
|
922
1084
|
function defaultQuarantinePath(configDir) {
|
|
923
|
-
return
|
|
1085
|
+
return join4(configDir, "channel-quarantine.json");
|
|
924
1086
|
}
|
|
925
1087
|
var ChannelQuarantineStore = class {
|
|
926
1088
|
path;
|
|
@@ -931,7 +1093,7 @@ var ChannelQuarantineStore = class {
|
|
|
931
1093
|
load() {
|
|
932
1094
|
if (this.cache) return this.cache;
|
|
933
1095
|
try {
|
|
934
|
-
const raw =
|
|
1096
|
+
const raw = readFileSync4(this.path, "utf-8");
|
|
935
1097
|
const parsed = JSON.parse(raw);
|
|
936
1098
|
this.cache = isQuarantineFile(parsed) ? parsed : {};
|
|
937
1099
|
} catch {
|
|
@@ -1019,13 +1181,13 @@ function isQuarantineFile(value) {
|
|
|
1019
1181
|
}
|
|
1020
1182
|
|
|
1021
1183
|
// src/lib/claude-md-size.ts
|
|
1022
|
-
import { readFileSync as
|
|
1023
|
-
import { join as
|
|
1184
|
+
import { readFileSync as readFileSync5 } from "fs";
|
|
1185
|
+
import { join as join5 } from "path";
|
|
1024
1186
|
function measureClaudeMd(configDir, codeName, ceiling = CLAUDE_MD_CONTEXT_ALARM_CHARS) {
|
|
1025
1187
|
let chars;
|
|
1026
1188
|
let bytes;
|
|
1027
1189
|
try {
|
|
1028
|
-
const buf =
|
|
1190
|
+
const buf = readFileSync5(join5(configDir, codeName, "project", "CLAUDE.md"));
|
|
1029
1191
|
chars = buf.toString("utf8").length;
|
|
1030
1192
|
bytes = buf.length;
|
|
1031
1193
|
} catch {
|
|
@@ -1045,8 +1207,8 @@ function measureClaudeMd(configDir, codeName, ceiling = CLAUDE_MD_CONTEXT_ALARM_
|
|
|
1045
1207
|
function measureCoreKnowledgeDescription(configDir, codeName) {
|
|
1046
1208
|
let text;
|
|
1047
1209
|
try {
|
|
1048
|
-
text =
|
|
1049
|
-
|
|
1210
|
+
text = readFileSync5(
|
|
1211
|
+
join5(configDir, codeName, "project", ".claude", "skills", "core-knowledge", "SKILL.md"),
|
|
1050
1212
|
"utf8"
|
|
1051
1213
|
);
|
|
1052
1214
|
} catch {
|
|
@@ -1634,19 +1796,19 @@ var DependencyRecoveryLedger = class {
|
|
|
1634
1796
|
|
|
1635
1797
|
// src/lib/mcp-assets-ready.ts
|
|
1636
1798
|
import { existsSync as nodeExistsSync, readFileSync as nodeReadFileSync } from "fs";
|
|
1637
|
-
import { homedir as
|
|
1638
|
-
import { join as
|
|
1639
|
-
function getSharedMcpDir(homeDir =
|
|
1640
|
-
return
|
|
1799
|
+
import { homedir as homedir3 } from "os";
|
|
1800
|
+
import { join as join6, resolve, sep as sep2 } from "path";
|
|
1801
|
+
function getSharedMcpDir(homeDir = homedir3()) {
|
|
1802
|
+
return join6(homeDir, ".augmented", "_mcp");
|
|
1641
1803
|
}
|
|
1642
1804
|
function isPathInsideDir(candidate, dir) {
|
|
1643
1805
|
const resolvedDir = resolve(dir);
|
|
1644
1806
|
const resolvedCandidate = resolve(candidate);
|
|
1645
1807
|
if (resolvedCandidate === resolvedDir) return false;
|
|
1646
|
-
return resolvedCandidate.startsWith(resolvedDir.endsWith(
|
|
1808
|
+
return resolvedCandidate.startsWith(resolvedDir.endsWith(sep2) ? resolvedDir : resolvedDir + sep2);
|
|
1647
1809
|
}
|
|
1648
1810
|
function findMissingMcpBundles(mcpConfigPath, deps = {}) {
|
|
1649
|
-
const
|
|
1811
|
+
const existsSync18 = deps.existsSync ?? nodeExistsSync;
|
|
1650
1812
|
const readFileSync30 = deps.readFileSync ?? nodeReadFileSync;
|
|
1651
1813
|
const mcpDir = deps.mcpDir ?? getSharedMcpDir();
|
|
1652
1814
|
let parsed;
|
|
@@ -1671,7 +1833,7 @@ function findMissingMcpBundles(mcpConfigPath, deps = {}) {
|
|
|
1671
1833
|
if (seenPaths.has(resolvedBundlePath)) continue;
|
|
1672
1834
|
let present;
|
|
1673
1835
|
try {
|
|
1674
|
-
present =
|
|
1836
|
+
present = existsSync18(bundlePath);
|
|
1675
1837
|
} catch {
|
|
1676
1838
|
continue;
|
|
1677
1839
|
}
|
|
@@ -1689,7 +1851,7 @@ function formatMissingMcpBundles(missing) {
|
|
|
1689
1851
|
}
|
|
1690
1852
|
|
|
1691
1853
|
// src/lib/self-update-coalesce.ts
|
|
1692
|
-
import { readFileSync as
|
|
1854
|
+
import { readFileSync as readFileSync6, writeFileSync as writeFileSync3, mkdirSync as mkdirSync3 } from "fs";
|
|
1693
1855
|
import { dirname as dirname4 } from "path";
|
|
1694
1856
|
var DEFAULT_SELF_UPDATE_COALESCE_MS = 30 * 60 * 1e3;
|
|
1695
1857
|
function resolveCoalesceWindowMs(env = process.env) {
|
|
@@ -1699,7 +1861,7 @@ function resolveCoalesceWindowMs(env = process.env) {
|
|
|
1699
1861
|
if (!Number.isFinite(parsed) || parsed < 0) return DEFAULT_SELF_UPDATE_COALESCE_MS;
|
|
1700
1862
|
return Math.trunc(parsed);
|
|
1701
1863
|
}
|
|
1702
|
-
function readLastSelfUpdateAppliedMs(markerPath, now = Date.now(), read = (p) =>
|
|
1864
|
+
function readLastSelfUpdateAppliedMs(markerPath, now = Date.now(), read = (p) => readFileSync6(p, "utf-8")) {
|
|
1703
1865
|
let raw;
|
|
1704
1866
|
try {
|
|
1705
1867
|
raw = read(markerPath);
|
|
@@ -2003,11 +2165,11 @@ async function reportModelApiError(opts) {
|
|
|
2003
2165
|
}
|
|
2004
2166
|
|
|
2005
2167
|
// src/lib/claude-pid-tracker.ts
|
|
2006
|
-
import { existsSync, readFileSync as
|
|
2168
|
+
import { existsSync as existsSync2, readFileSync as readFileSync7 } from "fs";
|
|
2007
2169
|
function readPidFile(path) {
|
|
2008
|
-
if (!
|
|
2170
|
+
if (!existsSync2(path)) return { version: 1, spawns: [] };
|
|
2009
2171
|
try {
|
|
2010
|
-
const raw = JSON.parse(
|
|
2172
|
+
const raw = JSON.parse(readFileSync7(path, "utf-8"));
|
|
2011
2173
|
if (raw.version !== 1 || !Array.isArray(raw.spawns)) return { version: 1, spawns: [] };
|
|
2012
2174
|
const spawns = raw.spawns.filter(
|
|
2013
2175
|
(s) => !!s && typeof s.pid === "number" && Number.isFinite(s.pid) && s.pid > 0
|
|
@@ -2057,14 +2219,14 @@ function formatReaperBootLine(opts) {
|
|
|
2057
2219
|
}
|
|
2058
2220
|
|
|
2059
2221
|
// src/lib/direct-chat-delivery.ts
|
|
2060
|
-
import { join as
|
|
2222
|
+
import { join as join7 } from "path";
|
|
2061
2223
|
var DEFAULT_DIRECT_CHAT_MAX_AGE_MS = 30 * 6e4;
|
|
2062
2224
|
function directChatMaxAgeMs() {
|
|
2063
2225
|
const raw = parseInt(process.env["AGT_DIRECT_CHAT_MAX_AGE_MS"] ?? "", 10);
|
|
2064
2226
|
return Number.isFinite(raw) && raw >= 0 ? raw : DEFAULT_DIRECT_CHAT_MAX_AGE_MS;
|
|
2065
2227
|
}
|
|
2066
2228
|
function directChatDoorbellPath(agentId, home) {
|
|
2067
|
-
return
|
|
2229
|
+
return join7(home, ".augmented", agentId, "direct-chat-doorbell");
|
|
2068
2230
|
}
|
|
2069
2231
|
function isDirectChatMessageExpired(createdAt, nowMs, maxAgeMs) {
|
|
2070
2232
|
if (!maxAgeMs || maxAgeMs <= 0) return false;
|
|
@@ -2075,16 +2237,16 @@ function isDirectChatMessageExpired(createdAt, nowMs, maxAgeMs) {
|
|
|
2075
2237
|
}
|
|
2076
2238
|
|
|
2077
2239
|
// src/lib/id-keyed-migration.ts
|
|
2078
|
-
import { existsSync as
|
|
2079
|
-
import { join as
|
|
2080
|
-
import { homedir as
|
|
2240
|
+
import { existsSync as existsSync3, lstatSync, readlinkSync, renameSync as renameSync2 } from "fs";
|
|
2241
|
+
import { join as join8 } from "path";
|
|
2242
|
+
import { homedir as homedir4 } from "os";
|
|
2081
2243
|
var ID_KEYED_MIGRATION_FLAG = "id-keyed-layout-migration";
|
|
2082
2244
|
function agentHasActiveWhatsapp(channelConfigs, codeNameDir) {
|
|
2083
2245
|
if (channelConfigs && Object.prototype.hasOwnProperty.call(channelConfigs, "whatsapp")) {
|
|
2084
2246
|
return true;
|
|
2085
2247
|
}
|
|
2086
2248
|
try {
|
|
2087
|
-
if (
|
|
2249
|
+
if (existsSync3(join8(codeNameDir, "whatsapp-pending-inbound"))) return true;
|
|
2088
2250
|
} catch {
|
|
2089
2251
|
}
|
|
2090
2252
|
return false;
|
|
@@ -2096,12 +2258,12 @@ function finishTranscriptMove(oldCwd, newCwd, codeName, log2) {
|
|
|
2096
2258
|
let fromExists = false;
|
|
2097
2259
|
let toExists = false;
|
|
2098
2260
|
try {
|
|
2099
|
-
fromExists =
|
|
2261
|
+
fromExists = existsSync3(from);
|
|
2100
2262
|
} catch {
|
|
2101
2263
|
}
|
|
2102
2264
|
if (!fromExists) return;
|
|
2103
2265
|
try {
|
|
2104
|
-
toExists =
|
|
2266
|
+
toExists = existsSync3(to);
|
|
2105
2267
|
} catch {
|
|
2106
2268
|
}
|
|
2107
2269
|
if (toExists) {
|
|
@@ -2114,19 +2276,19 @@ function finishTranscriptMove(oldCwd, newCwd, codeName, log2) {
|
|
|
2114
2276
|
log2(`[id-keyed-migration] moved transcript store for '${codeName}' to the id-keyed key`);
|
|
2115
2277
|
}
|
|
2116
2278
|
function maybeMigrateAgentToIdKeyedLayout(agent, deps) {
|
|
2117
|
-
const home = deps.home ??
|
|
2279
|
+
const home = deps.home ?? homedir4();
|
|
2118
2280
|
const { code_name: codeName, agent_id: agentId } = agent;
|
|
2119
|
-
const codeNamePath =
|
|
2120
|
-
const idPath =
|
|
2121
|
-
const oldCwd =
|
|
2122
|
-
const newCwd =
|
|
2281
|
+
const codeNamePath = join8(home, ".augmented", codeName);
|
|
2282
|
+
const idPath = join8(home, ".augmented", agentId);
|
|
2283
|
+
const oldCwd = join8(home, ".augmented", codeName, "project");
|
|
2284
|
+
const newCwd = join8(idPath, "project");
|
|
2123
2285
|
let codeNameKind;
|
|
2124
2286
|
try {
|
|
2125
2287
|
codeNameKind = lstatSync(codeNamePath).isSymbolicLink() ? "symlink" : "realdir";
|
|
2126
2288
|
} catch {
|
|
2127
2289
|
codeNameKind = "absent";
|
|
2128
2290
|
}
|
|
2129
|
-
const idExists =
|
|
2291
|
+
const idExists = existsSync3(idPath);
|
|
2130
2292
|
try {
|
|
2131
2293
|
if (codeNameKind === "symlink") {
|
|
2132
2294
|
const target = readlinkSync(codeNamePath);
|
|
@@ -2246,8 +2408,8 @@ function collectEnvGates(env) {
|
|
|
2246
2408
|
}
|
|
2247
2409
|
|
|
2248
2410
|
// ../../packages/core/dist/direct-chat/cursor-advance-telemetry.js
|
|
2249
|
-
import { readFileSync as
|
|
2250
|
-
import { join as
|
|
2411
|
+
import { readFileSync as readFileSync8, writeFileSync as writeFileSync4 } from "fs";
|
|
2412
|
+
import { join as join9 } from "path";
|
|
2251
2413
|
var CURSOR_SHORTFALL_COUNTER_SUFFIX = "-cursor-advance-classifications.json";
|
|
2252
2414
|
function recordCursorAdvanceOutcome(agentDir, source, route, verdict) {
|
|
2253
2415
|
if (!agentDir)
|
|
@@ -2255,10 +2417,10 @@ function recordCursorAdvanceOutcome(agentDir, source, route, verdict) {
|
|
|
2255
2417
|
const key = cursorAdvanceCounterKey(route, verdict);
|
|
2256
2418
|
if (key === null)
|
|
2257
2419
|
return;
|
|
2258
|
-
const path =
|
|
2420
|
+
const path = join9(agentDir, `${source}${CURSOR_SHORTFALL_COUNTER_SUFFIX}`);
|
|
2259
2421
|
const counts = {};
|
|
2260
2422
|
try {
|
|
2261
|
-
const parsed = JSON.parse(
|
|
2423
|
+
const parsed = JSON.parse(readFileSync8(path, "utf-8"));
|
|
2262
2424
|
if (parsed && typeof parsed === "object" && !Array.isArray(parsed)) {
|
|
2263
2425
|
for (const [k, v] of Object.entries(parsed)) {
|
|
2264
2426
|
if (typeof v === "number" && Number.isInteger(v) && v >= 0)
|
|
@@ -2275,8 +2437,8 @@ function recordCursorAdvanceOutcome(agentDir, source, route, verdict) {
|
|
|
2275
2437
|
}
|
|
2276
2438
|
|
|
2277
2439
|
// src/lib/artifact-stream.ts
|
|
2278
|
-
import { join as
|
|
2279
|
-
import { homedir as
|
|
2440
|
+
import { join as join10 } from "path";
|
|
2441
|
+
import { homedir as homedir5 } from "os";
|
|
2280
2442
|
import { readdir, stat, readFile } from "fs/promises";
|
|
2281
2443
|
var ARTEFACT_ENTRY_FILE = "index.html";
|
|
2282
2444
|
function errMessage(err) {
|
|
@@ -2361,7 +2523,7 @@ var ArtifactStreamScanner = class {
|
|
|
2361
2523
|
return;
|
|
2362
2524
|
}
|
|
2363
2525
|
for (const name of names) {
|
|
2364
|
-
const file =
|
|
2526
|
+
const file = join10(this.artifactsDir, name, ARTEFACT_ENTRY_FILE);
|
|
2365
2527
|
const mtime = await this.fsDeps.mtimeMs(file).catch(() => null);
|
|
2366
2528
|
if (mtime === null) continue;
|
|
2367
2529
|
if (this.seenMtime.get(name) === mtime) continue;
|
|
@@ -2392,7 +2554,7 @@ var ArtifactStreamScanner = class {
|
|
|
2392
2554
|
}
|
|
2393
2555
|
};
|
|
2394
2556
|
function artifactsDirFor(codeName) {
|
|
2395
|
-
return
|
|
2557
|
+
return join10(homedir5(), ".augmented", codeName, "artifacts");
|
|
2396
2558
|
}
|
|
2397
2559
|
var nodeArtifactFs = {
|
|
2398
2560
|
async listArtefactNames(artifactsDir) {
|
|
@@ -2645,13 +2807,13 @@ async function maybePollHostUsage(deps) {
|
|
|
2645
2807
|
// src/lib/claude-account-fingerprint.ts
|
|
2646
2808
|
import { createHash as createHash6 } from "crypto";
|
|
2647
2809
|
import { readFile as readFile3, readdir as readdir3 } from "fs/promises";
|
|
2648
|
-
import { homedir as
|
|
2649
|
-
import { dirname as dirname5, join as
|
|
2810
|
+
import { homedir as homedir7, platform as platform2 } from "os";
|
|
2811
|
+
import { dirname as dirname5, join as join12 } from "path";
|
|
2650
2812
|
|
|
2651
2813
|
// src/lib/claude-auth-detect.ts
|
|
2652
2814
|
import { readFile as readFile2, readdir as readdir2 } from "fs/promises";
|
|
2653
|
-
import { homedir as
|
|
2654
|
-
import { join as
|
|
2815
|
+
import { homedir as homedir6, platform } from "os";
|
|
2816
|
+
import { join as join11 } from "path";
|
|
2655
2817
|
import { execFile } from "child_process";
|
|
2656
2818
|
import { promisify } from "util";
|
|
2657
2819
|
var execFileAsync = promisify(execFile);
|
|
@@ -2666,16 +2828,16 @@ async function detectClaudeAuth() {
|
|
|
2666
2828
|
}
|
|
2667
2829
|
async function findClaudeCredentialsPaths() {
|
|
2668
2830
|
const candidates = [
|
|
2669
|
-
|
|
2670
|
-
|
|
2831
|
+
join11(homedir6(), ".claude", ".credentials.json"),
|
|
2832
|
+
join11(homedir6(), ".claude", "credentials.json")
|
|
2671
2833
|
];
|
|
2672
2834
|
const isLinuxRoot = platform() === "linux" && typeof process.getuid === "function" && process.getuid() === 0;
|
|
2673
2835
|
if (isLinuxRoot) {
|
|
2674
2836
|
try {
|
|
2675
2837
|
const entries = await readdir2("/home", { withFileTypes: true });
|
|
2676
2838
|
for (const entry of entries.filter((entry2) => entry2.isDirectory()).sort((a, b) => a.name.localeCompare(b.name))) {
|
|
2677
|
-
candidates.push(
|
|
2678
|
-
candidates.push(
|
|
2839
|
+
candidates.push(join11("/home", entry.name, ".claude", ".credentials.json"));
|
|
2840
|
+
candidates.push(join11("/home", entry.name, ".claude", "credentials.json"));
|
|
2679
2841
|
}
|
|
2680
2842
|
} catch {
|
|
2681
2843
|
}
|
|
@@ -2753,13 +2915,13 @@ function parseExpiresAt(raw) {
|
|
|
2753
2915
|
|
|
2754
2916
|
// src/lib/claude-account-fingerprint.ts
|
|
2755
2917
|
async function candidateHomes() {
|
|
2756
|
-
const homes = [
|
|
2918
|
+
const homes = [homedir7()];
|
|
2757
2919
|
const isLinuxRoot = platform2() === "linux" && typeof process.getuid === "function" && process.getuid() === 0;
|
|
2758
2920
|
if (isLinuxRoot) {
|
|
2759
2921
|
try {
|
|
2760
2922
|
const entries = await readdir3("/home", { withFileTypes: true });
|
|
2761
2923
|
for (const entry of entries.filter((e) => e.isDirectory()).sort((a, b) => a.name.localeCompare(b.name))) {
|
|
2762
|
-
homes.push(
|
|
2924
|
+
homes.push(join12("/home", entry.name));
|
|
2763
2925
|
}
|
|
2764
2926
|
} catch {
|
|
2765
2927
|
}
|
|
@@ -2779,11 +2941,11 @@ async function homeOfActiveCredentials() {
|
|
|
2779
2941
|
async function claudeConfigCandidatePaths() {
|
|
2780
2942
|
const paths = [];
|
|
2781
2943
|
const configDir = process.env["CLAUDE_CONFIG_DIR"]?.trim();
|
|
2782
|
-
if (configDir) paths.push(
|
|
2944
|
+
if (configDir) paths.push(join12(configDir, ".claude.json"));
|
|
2783
2945
|
const activeHome = await homeOfActiveCredentials();
|
|
2784
|
-
if (activeHome) paths.push(
|
|
2946
|
+
if (activeHome) paths.push(join12(activeHome, ".claude.json"));
|
|
2785
2947
|
for (const home of await candidateHomes()) {
|
|
2786
|
-
const path =
|
|
2948
|
+
const path = join12(home, ".claude.json");
|
|
2787
2949
|
if (!paths.includes(path)) paths.push(path);
|
|
2788
2950
|
}
|
|
2789
2951
|
return paths;
|
|
@@ -2881,10 +3043,10 @@ function diffAuthTuples(recorded, current) {
|
|
|
2881
3043
|
|
|
2882
3044
|
// src/lib/account-enforcement-marker.ts
|
|
2883
3045
|
import { mkdirSync as mkdirSync4, renameSync as renameSync3, rmSync as rmSync2, writeFileSync as writeFileSync5 } from "fs";
|
|
2884
|
-
import { homedir as
|
|
2885
|
-
import { join as
|
|
3046
|
+
import { homedir as homedir8 } from "os";
|
|
3047
|
+
import { join as join13 } from "path";
|
|
2886
3048
|
function accountEnforcementMarkerPath(codeName) {
|
|
2887
|
-
return
|
|
3049
|
+
return join13(homedir8(), ".augmented", codeName, ACCOUNT_ENFORCEMENT_MARKER_FILENAME);
|
|
2888
3050
|
}
|
|
2889
3051
|
function syncAccountEnforcementMarker(codeName, level, log2 = (m) => process.stderr.write(`${m}
|
|
2890
3052
|
`), text) {
|
|
@@ -2892,8 +3054,8 @@ function syncAccountEnforcementMarker(codeName, level, log2 = (m) => process.std
|
|
|
2892
3054
|
clearAccountEnforcementMarker(codeName, log2);
|
|
2893
3055
|
return;
|
|
2894
3056
|
}
|
|
2895
|
-
const dir =
|
|
2896
|
-
const path =
|
|
3057
|
+
const dir = join13(homedir8(), ".augmented", codeName);
|
|
3058
|
+
const path = join13(dir, ACCOUNT_ENFORCEMENT_MARKER_FILENAME);
|
|
2897
3059
|
const tempPath = `${path}.${process.pid}.tmp`;
|
|
2898
3060
|
try {
|
|
2899
3061
|
mkdirSync4(dir, { recursive: true });
|
|
@@ -2918,8 +3080,8 @@ function clearAccountEnforcementMarker(codeName, log2 = (m) => process.stderr.wr
|
|
|
2918
3080
|
}
|
|
2919
3081
|
|
|
2920
3082
|
// src/lib/token-usage-monitor.ts
|
|
2921
|
-
import { readdirSync, readFileSync as
|
|
2922
|
-
import { join as
|
|
3083
|
+
import { readdirSync as readdirSync2, readFileSync as readFileSync9, statSync } from "fs";
|
|
3084
|
+
import { join as join14 } from "path";
|
|
2923
3085
|
var MIN_CHECK_INTERVAL_MS2 = 6e4;
|
|
2924
3086
|
var TRANSCRIPT_MTIME_WINDOW_MS = 2 * 24 * 60 * 60 * 1e3;
|
|
2925
3087
|
var MAX_ENTRIES_PER_POST = 200;
|
|
@@ -2937,7 +3099,7 @@ async function maybeReportTokenUsage(args) {
|
|
|
2937
3099
|
const next = { files, lastCheckedAt: nowMs };
|
|
2938
3100
|
let dirEntries;
|
|
2939
3101
|
try {
|
|
2940
|
-
dirEntries =
|
|
3102
|
+
dirEntries = readdirSync2(dir);
|
|
2941
3103
|
} catch {
|
|
2942
3104
|
state3.set(codeName, next);
|
|
2943
3105
|
return;
|
|
@@ -2948,7 +3110,7 @@ async function maybeReportTokenUsage(args) {
|
|
|
2948
3110
|
if (!name.endsWith(".jsonl")) continue;
|
|
2949
3111
|
const sessionId = name.slice(0, -".jsonl".length);
|
|
2950
3112
|
if (!sessionId) continue;
|
|
2951
|
-
const path =
|
|
3113
|
+
const path = join14(dir, name);
|
|
2952
3114
|
let st;
|
|
2953
3115
|
try {
|
|
2954
3116
|
st = statSync(path);
|
|
@@ -2964,7 +3126,7 @@ async function maybeReportTokenUsage(args) {
|
|
|
2964
3126
|
}
|
|
2965
3127
|
let content;
|
|
2966
3128
|
try {
|
|
2967
|
-
content =
|
|
3129
|
+
content = readFileSync9(path, "utf-8");
|
|
2968
3130
|
} catch (err) {
|
|
2969
3131
|
log2(`[token-usage] read failed for '${codeName}/${name}': ${err.message}`);
|
|
2970
3132
|
continue;
|
|
@@ -3045,8 +3207,8 @@ async function maybeReportTokenUsage(args) {
|
|
|
3045
3207
|
}
|
|
3046
3208
|
|
|
3047
3209
|
// src/lib/workflow-run-reconciler.ts
|
|
3048
|
-
import { readdirSync as
|
|
3049
|
-
import { join as
|
|
3210
|
+
import { readdirSync as readdirSync3, readFileSync as readFileSync10, statSync as statSync2 } from "fs";
|
|
3211
|
+
import { join as join15 } from "path";
|
|
3050
3212
|
var MIN_CHECK_INTERVAL_MS3 = 5 * 6e4;
|
|
3051
3213
|
var SETTLE_MS = 3e4;
|
|
3052
3214
|
var TRANSCRIPT_MTIME_WINDOW_MS2 = 2 * 24 * 60 * 60 * 1e3;
|
|
@@ -3060,12 +3222,12 @@ function collectJsonlRecursive(dir, minMtimeMs, out, depth) {
|
|
|
3060
3222
|
if (depth > MAX_SUBAGENT_DEPTH) return;
|
|
3061
3223
|
let entries;
|
|
3062
3224
|
try {
|
|
3063
|
-
entries =
|
|
3225
|
+
entries = readdirSync3(dir);
|
|
3064
3226
|
} catch {
|
|
3065
3227
|
return;
|
|
3066
3228
|
}
|
|
3067
3229
|
for (const name of entries) {
|
|
3068
|
-
const p =
|
|
3230
|
+
const p = join15(dir, name);
|
|
3069
3231
|
let st;
|
|
3070
3232
|
try {
|
|
3071
3233
|
st = statSync2(p);
|
|
@@ -3083,12 +3245,12 @@ function enumerateTranscriptFiles(transcriptDir, nowMs, minMtimeMs = nowMs - TRA
|
|
|
3083
3245
|
const out = [];
|
|
3084
3246
|
let entries;
|
|
3085
3247
|
try {
|
|
3086
|
-
entries =
|
|
3248
|
+
entries = readdirSync3(transcriptDir);
|
|
3087
3249
|
} catch {
|
|
3088
3250
|
return out;
|
|
3089
3251
|
}
|
|
3090
3252
|
for (const name of entries) {
|
|
3091
|
-
const path =
|
|
3253
|
+
const path = join15(transcriptDir, name);
|
|
3092
3254
|
let st;
|
|
3093
3255
|
try {
|
|
3094
3256
|
st = statSync2(path);
|
|
@@ -3100,7 +3262,7 @@ function enumerateTranscriptFiles(transcriptDir, nowMs, minMtimeMs = nowMs - TRA
|
|
|
3100
3262
|
continue;
|
|
3101
3263
|
}
|
|
3102
3264
|
if (st.isDirectory()) {
|
|
3103
|
-
collectJsonlRecursive(
|
|
3265
|
+
collectJsonlRecursive(join15(path, "subagents"), minMtimeMs, out, 0);
|
|
3104
3266
|
}
|
|
3105
3267
|
}
|
|
3106
3268
|
return out;
|
|
@@ -3145,7 +3307,7 @@ async function maybeReconcileWorkflowRunTokens(args) {
|
|
|
3145
3307
|
const contents = [];
|
|
3146
3308
|
for (const path of files) {
|
|
3147
3309
|
try {
|
|
3148
|
-
contents.push(
|
|
3310
|
+
contents.push(readFileSync10(path, "utf-8"));
|
|
3149
3311
|
} catch {
|
|
3150
3312
|
}
|
|
3151
3313
|
}
|
|
@@ -3190,8 +3352,8 @@ async function maybeReconcileWorkflowRunTokens(args) {
|
|
|
3190
3352
|
}
|
|
3191
3353
|
|
|
3192
3354
|
// src/lib/conversation-evaluator.ts
|
|
3193
|
-
import { readdirSync as
|
|
3194
|
-
import { join as
|
|
3355
|
+
import { readdirSync as readdirSync4, readFileSync as readFileSync11, statSync as statSync3 } from "fs";
|
|
3356
|
+
import { join as join16 } from "path";
|
|
3195
3357
|
var MIN_CHECK_INTERVAL_MS4 = 5 * 6e4;
|
|
3196
3358
|
var TRANSCRIPT_MTIME_WINDOW_MS3 = 7 * 24 * 60 * 60 * 1e3;
|
|
3197
3359
|
var WINDOW_PAD_MS = 5 * 6e4;
|
|
@@ -3622,12 +3784,12 @@ function readRecentTurns(dir, nowMs) {
|
|
|
3622
3784
|
const visit = (d) => {
|
|
3623
3785
|
let entries;
|
|
3624
3786
|
try {
|
|
3625
|
-
entries =
|
|
3787
|
+
entries = readdirSync4(d, { withFileTypes: true });
|
|
3626
3788
|
} catch {
|
|
3627
3789
|
return;
|
|
3628
3790
|
}
|
|
3629
3791
|
for (const ent of entries) {
|
|
3630
|
-
const full =
|
|
3792
|
+
const full = join16(d, ent.name);
|
|
3631
3793
|
if (ent.isDirectory()) {
|
|
3632
3794
|
visit(full);
|
|
3633
3795
|
continue;
|
|
@@ -3642,7 +3804,7 @@ function readRecentTurns(dir, nowMs) {
|
|
|
3642
3804
|
if (nowMs - mtimeMs > TRANSCRIPT_MTIME_WINDOW_MS3) continue;
|
|
3643
3805
|
let content;
|
|
3644
3806
|
try {
|
|
3645
|
-
content =
|
|
3807
|
+
content = readFileSync11(full, "utf8");
|
|
3646
3808
|
} catch {
|
|
3647
3809
|
continue;
|
|
3648
3810
|
}
|
|
@@ -3932,23 +4094,23 @@ async function reportSkip2(api2, agentId, conversationId, log2, codeName) {
|
|
|
3932
4094
|
}
|
|
3933
4095
|
|
|
3934
4096
|
// src/lib/tool-call-audit.ts
|
|
3935
|
-
import { homedir as
|
|
3936
|
-
import { join as
|
|
4097
|
+
import { homedir as homedir12 } from "os";
|
|
4098
|
+
import { join as join21 } from "path";
|
|
3937
4099
|
|
|
3938
4100
|
// src/lib/agent-logging-mode.ts
|
|
3939
|
-
import { readFileSync as
|
|
3940
|
-
import { homedir as
|
|
3941
|
-
import { join as
|
|
4101
|
+
import { readFileSync as readFileSync12 } from "fs";
|
|
4102
|
+
import { homedir as homedir9 } from "os";
|
|
4103
|
+
import { join as join17 } from "path";
|
|
3942
4104
|
var LOGGING_MODES = ["hash-only", "redacted", "full-local"];
|
|
3943
4105
|
function charterPath(codeName, homeDir) {
|
|
3944
|
-
const home = homeDir ?? (process.env["HOME"]?.trim() ||
|
|
4106
|
+
const home = homeDir ?? (process.env["HOME"]?.trim() || homedir9());
|
|
3945
4107
|
const key = agentRuntimeKey(codeName, homeDir);
|
|
3946
|
-
return
|
|
4108
|
+
return join17(home, ".augmented", key, "provision", "CHARTER.md");
|
|
3947
4109
|
}
|
|
3948
4110
|
function readAgentLoggingMode(codeName, homeDir) {
|
|
3949
4111
|
let raw;
|
|
3950
4112
|
try {
|
|
3951
|
-
raw =
|
|
4113
|
+
raw = readFileSync12(charterPath(codeName, homeDir), "utf-8");
|
|
3952
4114
|
} catch {
|
|
3953
4115
|
return { mode: null, reason: "no-charter" };
|
|
3954
4116
|
}
|
|
@@ -3972,15 +4134,15 @@ function loggingModeWithholdsTargets(reading) {
|
|
|
3972
4134
|
|
|
3973
4135
|
// src/lib/tool-call-path-salt.ts
|
|
3974
4136
|
import { randomBytes } from "crypto";
|
|
3975
|
-
import { existsSync as
|
|
3976
|
-
import { homedir as
|
|
3977
|
-
import { dirname as dirname6, join as
|
|
4137
|
+
import { existsSync as existsSync4, mkdirSync as mkdirSync5, readFileSync as readFileSync13, renameSync as renameSync4, unlinkSync as unlinkSync2, writeFileSync as writeFileSync6 } from "fs";
|
|
4138
|
+
import { homedir as homedir10 } from "os";
|
|
4139
|
+
import { dirname as dirname6, join as join18 } from "path";
|
|
3978
4140
|
var SALT_BYTES = 32;
|
|
3979
4141
|
var SALT_RE = /^[0-9a-f]{64}$/;
|
|
3980
4142
|
function pathSaltPath(codeName, homeDir) {
|
|
3981
|
-
const home = homeDir ?? (process.env["HOME"]?.trim() ||
|
|
4143
|
+
const home = homeDir ?? (process.env["HOME"]?.trim() || homedir10());
|
|
3982
4144
|
const key = agentRuntimeKey(codeName, homeDir);
|
|
3983
|
-
return
|
|
4145
|
+
return join18(home, ".augmented", key, "tool-call-path-salt");
|
|
3984
4146
|
}
|
|
3985
4147
|
function readToolCallPathSalt(codeName, homeDir) {
|
|
3986
4148
|
let file;
|
|
@@ -3990,8 +4152,8 @@ function readToolCallPathSalt(codeName, homeDir) {
|
|
|
3990
4152
|
return null;
|
|
3991
4153
|
}
|
|
3992
4154
|
try {
|
|
3993
|
-
if (
|
|
3994
|
-
const existing =
|
|
4155
|
+
if (existsSync4(file)) {
|
|
4156
|
+
const existing = readFileSync13(file, "utf-8").trim();
|
|
3995
4157
|
if (SALT_RE.test(existing)) return existing;
|
|
3996
4158
|
}
|
|
3997
4159
|
} catch {
|
|
@@ -4016,48 +4178,9 @@ function readToolCallPathSalt(codeName, homeDir) {
|
|
|
4016
4178
|
// src/lib/tool-call-scan.ts
|
|
4017
4179
|
import { statSync as statSync4 } from "fs";
|
|
4018
4180
|
|
|
4019
|
-
// src/lib/host-archive-address.ts
|
|
4020
|
-
import { readFileSync as readFileSync13 } from "fs";
|
|
4021
|
-
var DEFAULT_ARCHIVE_ADDRESS_PATH = "/var/lib/augmented/session-archive-address.json";
|
|
4022
|
-
var CACHE_TTL_MS = 5 * 60 * 1e3;
|
|
4023
|
-
var cache = /* @__PURE__ */ new Map();
|
|
4024
|
-
function str(value) {
|
|
4025
|
-
if (typeof value !== "string") return null;
|
|
4026
|
-
const trimmed = value.trim();
|
|
4027
|
-
return trimmed.length > 0 ? trimmed : null;
|
|
4028
|
-
}
|
|
4029
|
-
function readHostArchiveAddress(path) {
|
|
4030
|
-
const file = path ?? process.env["ARCHIVE_ADDRESS_FILE"]?.trim() ?? process.env["AGT_SESSION_ARCHIVE_ADDRESS_FILE"]?.trim() ?? DEFAULT_ARCHIVE_ADDRESS_PATH;
|
|
4031
|
-
const now = Date.now();
|
|
4032
|
-
const hit = cache.get(file);
|
|
4033
|
-
if (hit && now - hit.at < CACHE_TTL_MS) return hit.value;
|
|
4034
|
-
let value = null;
|
|
4035
|
-
try {
|
|
4036
|
-
const raw = readFileSync13(file, "utf-8");
|
|
4037
|
-
const parsed = JSON.parse(raw);
|
|
4038
|
-
if (parsed && typeof parsed === "object" && !Array.isArray(parsed)) {
|
|
4039
|
-
const obj = parsed;
|
|
4040
|
-
const bucket = str(obj["bucket"]);
|
|
4041
|
-
const keyPrefix = str(obj["key_prefix"]);
|
|
4042
|
-
if (bucket && keyPrefix) {
|
|
4043
|
-
value = {
|
|
4044
|
-
bucket,
|
|
4045
|
-
region: str(obj["region"]),
|
|
4046
|
-
instanceId: str(obj["instance_id"]),
|
|
4047
|
-
keyPrefix
|
|
4048
|
-
};
|
|
4049
|
-
}
|
|
4050
|
-
}
|
|
4051
|
-
} catch {
|
|
4052
|
-
value = null;
|
|
4053
|
-
}
|
|
4054
|
-
cache.set(file, { at: now, value });
|
|
4055
|
-
return value;
|
|
4056
|
-
}
|
|
4057
|
-
|
|
4058
4181
|
// src/lib/tool-call-extractor.ts
|
|
4059
|
-
import { closeSync, fstatSync, openSync, readFileSync as readFileSync14, readSync, readdirSync as
|
|
4060
|
-
import { basename as basename2, join as
|
|
4182
|
+
import { closeSync, fstatSync, openSync, readFileSync as readFileSync14, readSync, readdirSync as readdirSync5 } from "fs";
|
|
4183
|
+
import { basename as basename2, join as join19, relative as relative2 } from "path";
|
|
4061
4184
|
import { StringDecoder } from "string_decoder";
|
|
4062
4185
|
|
|
4063
4186
|
// src/lib/tool-call-redaction.ts
|
|
@@ -4186,28 +4309,28 @@ function redactToolTargetInner(toolName, input, ctx) {
|
|
|
4186
4309
|
var EXTRACTOR_VERSION = "e1";
|
|
4187
4310
|
function enumerateSessionTranscripts(transcriptDir, sessionId, projectsRoot) {
|
|
4188
4311
|
const files = [];
|
|
4189
|
-
const mainAbs =
|
|
4312
|
+
const mainAbs = join19(transcriptDir, `${sessionId}.jsonl`);
|
|
4190
4313
|
files.push({
|
|
4191
4314
|
absPath: mainAbs,
|
|
4192
|
-
relPath:
|
|
4315
|
+
relPath: relative2(projectsRoot, mainAbs),
|
|
4193
4316
|
ref: "main",
|
|
4194
4317
|
isSubagent: false,
|
|
4195
4318
|
subagentId: null
|
|
4196
4319
|
});
|
|
4197
|
-
const subDir =
|
|
4320
|
+
const subDir = join19(transcriptDir, sessionId, "subagents");
|
|
4198
4321
|
let entries;
|
|
4199
4322
|
try {
|
|
4200
|
-
entries =
|
|
4323
|
+
entries = readdirSync5(subDir);
|
|
4201
4324
|
} catch {
|
|
4202
4325
|
return files;
|
|
4203
4326
|
}
|
|
4204
4327
|
for (const name of entries) {
|
|
4205
4328
|
if (!name.endsWith(".jsonl")) continue;
|
|
4206
|
-
const abs =
|
|
4329
|
+
const abs = join19(subDir, name);
|
|
4207
4330
|
const stem = basename2(name, ".jsonl");
|
|
4208
4331
|
files.push({
|
|
4209
4332
|
absPath: abs,
|
|
4210
|
-
relPath:
|
|
4333
|
+
relPath: relative2(projectsRoot, abs),
|
|
4211
4334
|
ref: `subagent:${stem}`,
|
|
4212
4335
|
isSubagent: true,
|
|
4213
4336
|
subagentId: stem.startsWith("agent-") ? stem.slice("agent-".length) : stem
|
|
@@ -4401,9 +4524,9 @@ function extractTranscriptWindow(file, opts, from) {
|
|
|
4401
4524
|
}
|
|
4402
4525
|
|
|
4403
4526
|
// src/lib/tool-call-cursor.ts
|
|
4404
|
-
import { existsSync as
|
|
4405
|
-
import { homedir as
|
|
4406
|
-
import { join as
|
|
4527
|
+
import { existsSync as existsSync5, readFileSync as readFileSync15 } from "fs";
|
|
4528
|
+
import { homedir as homedir11 } from "os";
|
|
4529
|
+
import { join as join20 } from "path";
|
|
4407
4530
|
var COVERAGE_DISPOSITIONS = [
|
|
4408
4531
|
"ok",
|
|
4409
4532
|
"not_entitled",
|
|
@@ -4456,13 +4579,13 @@ function parseCursorKey(key) {
|
|
|
4456
4579
|
return { sessionId: sessionId.length > 0 ? sessionId : null, transcriptRef: key.slice(i + 1) };
|
|
4457
4580
|
}
|
|
4458
4581
|
function cursorStatePath(codeName, homeDir) {
|
|
4459
|
-
const home = homeDir ?? (process.env["HOME"]?.trim() ||
|
|
4582
|
+
const home = homeDir ?? (process.env["HOME"]?.trim() || homedir11());
|
|
4460
4583
|
const key = agentRuntimeKey(codeName, homeDir);
|
|
4461
|
-
return
|
|
4584
|
+
return join20(home, ".augmented", key, "tool-call-cursors.json");
|
|
4462
4585
|
}
|
|
4463
4586
|
function loadCursors(path) {
|
|
4464
4587
|
const out = /* @__PURE__ */ new Map();
|
|
4465
|
-
if (!
|
|
4588
|
+
if (!existsSync5(path)) return out;
|
|
4466
4589
|
try {
|
|
4467
4590
|
const parsed = JSON.parse(readFileSync15(path, "utf-8"));
|
|
4468
4591
|
if (!parsed || parsed.version !== 1 || typeof parsed.files !== "object") return out;
|
|
@@ -4870,8 +4993,8 @@ async function maybeScanToolCalls(args) {
|
|
|
4870
4993
|
if (!salt && !hashOnly) {
|
|
4871
4994
|
log2(`[tool-call-audit] ${codeName}: no path-hash salt available \u2014 file targets withheld`);
|
|
4872
4995
|
}
|
|
4873
|
-
const home = args.homeDir ?? (process.env["HOME"]?.trim() ||
|
|
4874
|
-
const projectsRoot = args.projectsRoot ??
|
|
4996
|
+
const home = args.homeDir ?? (process.env["HOME"]?.trim() || homedir12());
|
|
4997
|
+
const projectsRoot = args.projectsRoot ?? join21(home, ".claude", "projects");
|
|
4875
4998
|
const transcriptDir = args.transcriptDir ?? sessionTranscriptDir(getProjectDir(codeName));
|
|
4876
4999
|
const current = peekCurrentSession(codeName);
|
|
4877
5000
|
const sessionIds = current ? [current.sessionId] : [];
|
|
@@ -4900,11 +5023,11 @@ async function maybeScanToolCalls(args) {
|
|
|
4900
5023
|
}
|
|
4901
5024
|
|
|
4902
5025
|
// src/lib/activity-cache-monitor.ts
|
|
4903
|
-
import { existsSync as
|
|
4904
|
-
import { homedir as
|
|
4905
|
-
import { join as
|
|
5026
|
+
import { existsSync as existsSync6, readFileSync as readFileSync16 } from "fs";
|
|
5027
|
+
import { homedir as homedir13 } from "os";
|
|
5028
|
+
import { join as join22 } from "path";
|
|
4906
5029
|
var MIN_CHECK_INTERVAL_MS7 = 6e4;
|
|
4907
|
-
var STATS_CACHE_PATH =
|
|
5030
|
+
var STATS_CACHE_PATH = join22(homedir13(), ".claude", "stats-cache.json");
|
|
4908
5031
|
var ISO_DATE_RE = /^\d{4}-\d{2}-\d{2}$/;
|
|
4909
5032
|
var state7 = { lastObservedDate: null, lastCheckedAt: 0 };
|
|
4910
5033
|
function selectNewDailyRows(raw, lastObservedDate) {
|
|
@@ -4947,7 +5070,7 @@ async function maybeReportActivityCache(args) {
|
|
|
4947
5070
|
const nowMs = now.getTime();
|
|
4948
5071
|
if (nowMs - state7.lastCheckedAt < MIN_CHECK_INTERVAL_MS7) return;
|
|
4949
5072
|
state7.lastCheckedAt = nowMs;
|
|
4950
|
-
if (!
|
|
5073
|
+
if (!existsSync6(STATS_CACHE_PATH)) {
|
|
4951
5074
|
return;
|
|
4952
5075
|
}
|
|
4953
5076
|
let raw;
|
|
@@ -5189,15 +5312,15 @@ function computeChannelConfigHash(input) {
|
|
|
5189
5312
|
}
|
|
5190
5313
|
|
|
5191
5314
|
// src/lib/channel-hash-cache.ts
|
|
5192
|
-
import { existsSync as
|
|
5193
|
-
import { join as
|
|
5315
|
+
import { existsSync as existsSync7, readFileSync as readFileSync17, writeFileSync as writeFileSync7 } from "fs";
|
|
5316
|
+
import { join as join23 } from "path";
|
|
5194
5317
|
var CACHE_FILENAME = "channel-hash-cache.json";
|
|
5195
5318
|
function getChannelHashCacheFile(configDir) {
|
|
5196
|
-
return
|
|
5319
|
+
return join23(configDir, CACHE_FILENAME);
|
|
5197
5320
|
}
|
|
5198
5321
|
function loadChannelHashCache(target, configDir) {
|
|
5199
5322
|
const path = getChannelHashCacheFile(configDir);
|
|
5200
|
-
if (!
|
|
5323
|
+
if (!existsSync7(path)) return;
|
|
5201
5324
|
let parsed;
|
|
5202
5325
|
try {
|
|
5203
5326
|
parsed = JSON.parse(readFileSync17(path, "utf-8"));
|
|
@@ -5220,8 +5343,8 @@ function saveChannelHashCache(source, configDir) {
|
|
|
5220
5343
|
}
|
|
5221
5344
|
|
|
5222
5345
|
// src/lib/sender-policy-baseline.ts
|
|
5223
|
-
import { existsSync as
|
|
5224
|
-
import { join as
|
|
5346
|
+
import { existsSync as existsSync8, readFileSync as readFileSync18 } from "fs";
|
|
5347
|
+
import { join as join24 } from "path";
|
|
5225
5348
|
var BASELINE_FILENAME = "sender-policy-baseline.json";
|
|
5226
5349
|
var SENDER_POLICY_BASELINE_VERSION = 1;
|
|
5227
5350
|
var BASELINE_CONCERNS = ["senderPolicy", "slackBehaviour", "msteamsBehaviour"];
|
|
@@ -5233,11 +5356,11 @@ function createDeliveryBaselineMaps() {
|
|
|
5233
5356
|
};
|
|
5234
5357
|
}
|
|
5235
5358
|
function getSenderPolicyBaselineFile(configDir) {
|
|
5236
|
-
return
|
|
5359
|
+
return join24(configDir, BASELINE_FILENAME);
|
|
5237
5360
|
}
|
|
5238
5361
|
function loadSenderPolicyBaseline(target, configDir, log2) {
|
|
5239
5362
|
const path = getSenderPolicyBaselineFile(configDir);
|
|
5240
|
-
if (!
|
|
5363
|
+
if (!existsSync8(path)) return;
|
|
5241
5364
|
let parsed;
|
|
5242
5365
|
try {
|
|
5243
5366
|
parsed = JSON.parse(readFileSync18(path, "utf-8"));
|
|
@@ -5289,8 +5412,8 @@ function saveSenderPolicyBaseline(source, configDir, log2) {
|
|
|
5289
5412
|
}
|
|
5290
5413
|
|
|
5291
5414
|
// src/lib/stuck-streak-store.ts
|
|
5292
|
-
import { existsSync as
|
|
5293
|
-
import { join as
|
|
5415
|
+
import { existsSync as existsSync9, readFileSync as readFileSync19 } from "fs";
|
|
5416
|
+
import { join as join25 } from "path";
|
|
5294
5417
|
var STORE_FILENAME = "stuck-streaks.json";
|
|
5295
5418
|
var STUCK_STREAK_STORE_VERSION = 1;
|
|
5296
5419
|
var STUCK_STREAK_CONCERNS = ["channelSync", "realtimeRebind"];
|
|
@@ -5298,7 +5421,7 @@ function createStuckStreakMaps() {
|
|
|
5298
5421
|
return { channelSync: /* @__PURE__ */ new Map(), realtimeRebind: /* @__PURE__ */ new Map() };
|
|
5299
5422
|
}
|
|
5300
5423
|
function getStuckStreakStoreFile(configDir) {
|
|
5301
|
-
return
|
|
5424
|
+
return join25(configDir, STORE_FILENAME);
|
|
5302
5425
|
}
|
|
5303
5426
|
function isValidPersistedStreak(value) {
|
|
5304
5427
|
if (!value || typeof value !== "object" || Array.isArray(value)) return false;
|
|
@@ -5337,7 +5460,7 @@ function buildStuckStreakPayload(source) {
|
|
|
5337
5460
|
}
|
|
5338
5461
|
function loadStuckStreaks(target, configDir, log2) {
|
|
5339
5462
|
const path = getStuckStreakStoreFile(configDir);
|
|
5340
|
-
if (!
|
|
5463
|
+
if (!existsSync9(path)) return;
|
|
5341
5464
|
let parsed;
|
|
5342
5465
|
try {
|
|
5343
5466
|
parsed = JSON.parse(readFileSync19(path, "utf-8"));
|
|
@@ -5857,7 +5980,7 @@ function planGlobalSkillSync(globalSkills, prevIds, hashOf, knownHash, options)
|
|
|
5857
5980
|
}
|
|
5858
5981
|
|
|
5859
5982
|
// src/lib/manager/integration-skill-cache.ts
|
|
5860
|
-
import { join as
|
|
5983
|
+
import { join as join26 } from "path";
|
|
5861
5984
|
function integrationSkillHashKey(agentId, skillId) {
|
|
5862
5985
|
return `plugin-skill:${agentId}:${skillId}`;
|
|
5863
5986
|
}
|
|
@@ -5873,20 +5996,20 @@ function forgetIntegrationSkill(cache3, agentId, skillId) {
|
|
|
5873
5996
|
function removeIntegrationSkillFolder(opts) {
|
|
5874
5997
|
forgetIntegrationSkill(opts.cache, opts.agentId, opts.entry);
|
|
5875
5998
|
for (const dir of opts.dirs) {
|
|
5876
|
-
opts.removeDir(
|
|
5999
|
+
opts.removeDir(join26(dir, opts.entry));
|
|
5877
6000
|
}
|
|
5878
6001
|
}
|
|
5879
6002
|
|
|
5880
6003
|
// src/lib/manager/managed-skill-manifest.ts
|
|
5881
|
-
import { existsSync as
|
|
5882
|
-
import { dirname as dirname7, join as
|
|
6004
|
+
import { existsSync as existsSync10, mkdirSync as mkdirSync6, readFileSync as readFileSync20, writeFileSync as writeFileSync8 } from "fs";
|
|
6005
|
+
import { dirname as dirname7, join as join27 } from "path";
|
|
5883
6006
|
var MANIFEST_VERSION = 1;
|
|
5884
6007
|
function managedSkillManifestPath(agentRootDir) {
|
|
5885
|
-
return
|
|
6008
|
+
return join27(agentRootDir, "managed-skills.json");
|
|
5886
6009
|
}
|
|
5887
6010
|
function readManagedSkillManifest(path) {
|
|
5888
6011
|
try {
|
|
5889
|
-
if (!
|
|
6012
|
+
if (!existsSync10(path)) return /* @__PURE__ */ new Set();
|
|
5890
6013
|
const parsed = JSON.parse(readFileSync20(path, "utf-8"));
|
|
5891
6014
|
const ids = Array.isArray(parsed?.globalSkillIds) ? parsed.globalSkillIds : [];
|
|
5892
6015
|
return new Set(ids.filter((id) => typeof id === "string" && id.length > 0));
|
|
@@ -6013,9 +6136,9 @@ function resolveModelChain(refreshData) {
|
|
|
6013
6136
|
}
|
|
6014
6137
|
|
|
6015
6138
|
// src/lib/manager/claude-auth.ts
|
|
6016
|
-
import { existsSync as
|
|
6017
|
-
import { join as
|
|
6018
|
-
import { homedir as
|
|
6139
|
+
import { existsSync as existsSync11, rmSync as rmSync3 } from "fs";
|
|
6140
|
+
import { join as join28 } from "path";
|
|
6141
|
+
import { homedir as homedir14 } from "os";
|
|
6019
6142
|
async function applyClaudeAuthToEnv(childEnv, label) {
|
|
6020
6143
|
const apiKey = getApiKey();
|
|
6021
6144
|
if (!apiKey) {
|
|
@@ -6027,10 +6150,10 @@ async function applyClaudeAuthToEnv(childEnv, label) {
|
|
|
6027
6150
|
throw new Error("claude_auth_mode=api_key but /host/exchange returned no decrypted key");
|
|
6028
6151
|
}
|
|
6029
6152
|
childEnv.ANTHROPIC_API_KEY = exchange.anthropicApiKey;
|
|
6030
|
-
const claudeDir =
|
|
6153
|
+
const claudeDir = join28(homedir14(), ".claude");
|
|
6031
6154
|
for (const filename of [".credentials.json", "credentials.json"]) {
|
|
6032
|
-
const p =
|
|
6033
|
-
if (
|
|
6155
|
+
const p = join28(claudeDir, filename);
|
|
6156
|
+
if (existsSync11(p)) {
|
|
6034
6157
|
try {
|
|
6035
6158
|
rmSync3(p, { force: true });
|
|
6036
6159
|
log(`[${label}] Removed ${p} (api_key mode \u2014 preventing OAuth fallback)`);
|
|
@@ -6111,8 +6234,8 @@ function heartbeatRuntimeAuthFields(probeVerdict) {
|
|
|
6111
6234
|
}
|
|
6112
6235
|
|
|
6113
6236
|
// src/lib/manager/kanban/parsers.ts
|
|
6114
|
-
import { existsSync as
|
|
6115
|
-
import { join as
|
|
6237
|
+
import { existsSync as existsSync12, readFileSync as readFileSync21 } from "fs";
|
|
6238
|
+
import { join as join29 } from "path";
|
|
6116
6239
|
var STANDUP_TEMPLATES = /* @__PURE__ */ new Set(["daily-standup", "end-of-day-summary"]);
|
|
6117
6240
|
var TASK_UPDATE_TEMPLATES = /* @__PURE__ */ new Set(["hourly-status", "task-update"]);
|
|
6118
6241
|
var PLAN_TEMPLATES = /* @__PURE__ */ new Set(["morning-plan"]);
|
|
@@ -6264,11 +6387,11 @@ function getBuiltInSkillContent(skillId) {
|
|
|
6264
6387
|
if (builtInSkillCache.has(skillId)) return builtInSkillCache.get(skillId);
|
|
6265
6388
|
try {
|
|
6266
6389
|
const candidates = [
|
|
6267
|
-
|
|
6268
|
-
|
|
6390
|
+
join29(process.cwd(), "skills", skillId, "SKILL.md"),
|
|
6391
|
+
join29(new URL(".", import.meta.url).pathname, "..", "..", "..", "..", "..", "..", "skills", skillId, "SKILL.md")
|
|
6269
6392
|
];
|
|
6270
6393
|
for (const candidate of candidates) {
|
|
6271
|
-
if (
|
|
6394
|
+
if (existsSync12(candidate)) {
|
|
6272
6395
|
const content = readFileSync21(candidate, "utf-8");
|
|
6273
6396
|
const files = [{ relativePath: "SKILL.md", content }];
|
|
6274
6397
|
builtInSkillCache.set(skillId, files);
|
|
@@ -6410,16 +6533,16 @@ function formatBoardForPrompt(items, template) {
|
|
|
6410
6533
|
}
|
|
6411
6534
|
|
|
6412
6535
|
// src/lib/manager/kanban/nudge-state-cache.ts
|
|
6413
|
-
import { existsSync as
|
|
6414
|
-
import { join as
|
|
6536
|
+
import { existsSync as existsSync13, readFileSync as readFileSync22, writeFileSync as writeFileSync9 } from "fs";
|
|
6537
|
+
import { join as join30 } from "path";
|
|
6415
6538
|
var CACHE_FILENAME2 = "kanban-nudge-state.json";
|
|
6416
6539
|
var KANBAN_NUDGE_STATE_VERSION = 1;
|
|
6417
6540
|
function getKanbanNudgeStateFile(configDir) {
|
|
6418
|
-
return
|
|
6541
|
+
return join30(configDir, CACHE_FILENAME2);
|
|
6419
6542
|
}
|
|
6420
6543
|
function loadKanbanNudgeState(target, configDir) {
|
|
6421
6544
|
const path = getKanbanNudgeStateFile(configDir);
|
|
6422
|
-
if (!
|
|
6545
|
+
if (!existsSync13(path)) return;
|
|
6423
6546
|
let parsed;
|
|
6424
6547
|
try {
|
|
6425
6548
|
parsed = JSON.parse(readFileSync22(path, "utf-8"));
|
|
@@ -7041,8 +7164,8 @@ function closeSessionRunForCode(codeName, outcome, reason) {
|
|
|
7041
7164
|
// src/lib/manager/scheduler/kanban-route.ts
|
|
7042
7165
|
import { createHash as createHash12 } from "crypto";
|
|
7043
7166
|
import { writeFileSync as writeFileSync10, renameSync as renameSync5, mkdirSync as mkdirSync7, readFileSync as readFileSync23, unlinkSync as unlinkSync3 } from "fs";
|
|
7044
|
-
import { homedir as
|
|
7045
|
-
import { join as
|
|
7167
|
+
import { homedir as homedir15 } from "os";
|
|
7168
|
+
import { join as join31, dirname as dirname8 } from "path";
|
|
7046
7169
|
|
|
7047
7170
|
// src/lib/manager/scheduler/notify.ts
|
|
7048
7171
|
import { createHash as createHash11 } from "crypto";
|
|
@@ -7401,7 +7524,7 @@ function resolveScheduledSlackTarget(task) {
|
|
|
7401
7524
|
}
|
|
7402
7525
|
function stampScheduledTurnMarker(codeName, taskId, target) {
|
|
7403
7526
|
try {
|
|
7404
|
-
const file =
|
|
7527
|
+
const file = join31(homedir15(), ".augmented", codeName, SCHEDULED_TURN_MARKER_FILENAME);
|
|
7405
7528
|
const marker = { ts: Date.now(), task_id: taskId, ...target ? { target } : {} };
|
|
7406
7529
|
const tmp = `${file}.tmp`;
|
|
7407
7530
|
writeFileSync10(tmp, JSON.stringify(marker), "utf8");
|
|
@@ -7411,7 +7534,7 @@ function stampScheduledTurnMarker(codeName, taskId, target) {
|
|
|
7411
7534
|
}
|
|
7412
7535
|
}
|
|
7413
7536
|
function clearScheduledTurnMarkerForTask(codeName, taskId) {
|
|
7414
|
-
const file =
|
|
7537
|
+
const file = join31(homedir15(), ".augmented", codeName, SCHEDULED_TURN_MARKER_FILENAME);
|
|
7415
7538
|
try {
|
|
7416
7539
|
const raw = JSON.parse(readFileSync23(file, "utf8"));
|
|
7417
7540
|
if (typeof raw?.task_id !== "string" || raw.task_id !== taskId) return;
|
|
@@ -7473,7 +7596,7 @@ async function routeScheduledTaskViaKanban(codeName, agentId, task, prompt, dura
|
|
|
7473
7596
|
return false;
|
|
7474
7597
|
}
|
|
7475
7598
|
try {
|
|
7476
|
-
const doorbell = directChatDoorbellPath(agentId,
|
|
7599
|
+
const doorbell = directChatDoorbellPath(agentId, homedir15());
|
|
7477
7600
|
mkdirSync7(dirname8(doorbell), { recursive: true });
|
|
7478
7601
|
writeFileSync10(doorbell, String(Date.now()));
|
|
7479
7602
|
} catch (err) {
|
|
@@ -7625,12 +7748,12 @@ async function processClaudeTaskResult(codeName, agentId, templateId, rawOutput,
|
|
|
7625
7748
|
|
|
7626
7749
|
// src/lib/manager/scheduler/execution.ts
|
|
7627
7750
|
import { createHash as createHash13 } from "crypto";
|
|
7628
|
-
import { homedir as
|
|
7629
|
-
import { join as
|
|
7751
|
+
import { homedir as homedir16 } from "os";
|
|
7752
|
+
import { join as join33 } from "path";
|
|
7630
7753
|
|
|
7631
7754
|
// src/lib/agent-serving-probe.ts
|
|
7632
|
-
import { readFileSync as readFileSync24, readdirSync as
|
|
7633
|
-
import { join as
|
|
7755
|
+
import { readFileSync as readFileSync24, readdirSync as readdirSync6, statSync as statSync5 } from "fs";
|
|
7756
|
+
import { join as join32 } from "path";
|
|
7634
7757
|
var RATE_LIMIT_WINDOW_MS = 6 * 60 * 60 * 1e3;
|
|
7635
7758
|
function probeRateLimit(args) {
|
|
7636
7759
|
const now = args.now ?? /* @__PURE__ */ new Date();
|
|
@@ -7639,14 +7762,14 @@ function probeRateLimit(args) {
|
|
|
7639
7762
|
const dir = args.transcriptDir ?? sessionTranscriptDir(args.projectDir);
|
|
7640
7763
|
let entries;
|
|
7641
7764
|
try {
|
|
7642
|
-
entries =
|
|
7765
|
+
entries = readdirSync6(dir);
|
|
7643
7766
|
} catch {
|
|
7644
7767
|
return UNKNOWN_RATE_LIMIT;
|
|
7645
7768
|
}
|
|
7646
7769
|
let newest = UNKNOWN_RATE_LIMIT;
|
|
7647
7770
|
for (const name of entries) {
|
|
7648
7771
|
if (!name.endsWith(".jsonl")) continue;
|
|
7649
|
-
const path =
|
|
7772
|
+
const path = join32(dir, name);
|
|
7650
7773
|
try {
|
|
7651
7774
|
const st = statSync5(path);
|
|
7652
7775
|
if (!st.isFile() || st.mtimeMs < startMs) continue;
|
|
@@ -7717,7 +7840,7 @@ function shouldLogUsageCapDeferral(site, codeName, limitedUntil) {
|
|
|
7717
7840
|
|
|
7718
7841
|
// src/lib/manager/scheduler/execution.ts
|
|
7719
7842
|
function claudePidFilePath() {
|
|
7720
|
-
return
|
|
7843
|
+
return join33(homedir16(), ".augmented", "manager-claude-pids.json");
|
|
7721
7844
|
}
|
|
7722
7845
|
var inFlightClaudePids = /* @__PURE__ */ new Map();
|
|
7723
7846
|
function registerClaudeSpawn(record) {
|
|
@@ -7787,8 +7910,8 @@ async function syncAndCheckClaudeScheduler(agent, tasks, boardItems, refreshData
|
|
|
7787
7910
|
}
|
|
7788
7911
|
|
|
7789
7912
|
// src/lib/occupancy-gate.ts
|
|
7790
|
-
import { closeSync as closeSync2, openSync as openSync2, readdirSync as
|
|
7791
|
-
import { join as
|
|
7913
|
+
import { closeSync as closeSync2, openSync as openSync2, readdirSync as readdirSync7, readSync as readSync2, statSync as statSync6 } from "fs";
|
|
7914
|
+
import { join as join34 } from "path";
|
|
7792
7915
|
function rostersMeasuredZero(mode, attested, runtimeRunning) {
|
|
7793
7916
|
return mode === "enforce" && attested && runtimeRunning;
|
|
7794
7917
|
}
|
|
@@ -7872,26 +7995,26 @@ function candidateTranscriptPaths(dir) {
|
|
|
7872
7995
|
const paths = [];
|
|
7873
7996
|
let top;
|
|
7874
7997
|
try {
|
|
7875
|
-
top =
|
|
7998
|
+
top = readdirSync7(dir);
|
|
7876
7999
|
} catch {
|
|
7877
8000
|
return { paths, complete: false };
|
|
7878
8001
|
}
|
|
7879
8002
|
let complete = true;
|
|
7880
8003
|
for (const name of top) {
|
|
7881
8004
|
if (name.endsWith(".jsonl")) {
|
|
7882
|
-
paths.push(
|
|
8005
|
+
paths.push(join34(dir, name));
|
|
7883
8006
|
continue;
|
|
7884
8007
|
}
|
|
7885
|
-
const subDir =
|
|
8008
|
+
const subDir = join34(dir, name, "subagents");
|
|
7886
8009
|
let subs;
|
|
7887
8010
|
try {
|
|
7888
|
-
subs =
|
|
8011
|
+
subs = readdirSync7(subDir);
|
|
7889
8012
|
} catch (err) {
|
|
7890
8013
|
if (!isAbsentDirError(err)) complete = false;
|
|
7891
8014
|
continue;
|
|
7892
8015
|
}
|
|
7893
8016
|
for (const sub of subs) {
|
|
7894
|
-
if (sub.endsWith(".jsonl")) paths.push(
|
|
8017
|
+
if (sub.endsWith(".jsonl")) paths.push(join34(subDir, sub));
|
|
7895
8018
|
}
|
|
7896
8019
|
}
|
|
7897
8020
|
return { paths, complete };
|
|
@@ -8118,7 +8241,7 @@ function stopPaneOccupancySampler() {
|
|
|
8118
8241
|
|
|
8119
8242
|
// src/lib/pid-pressure-sampler.ts
|
|
8120
8243
|
import { execFileSync as execFileSync2 } from "child_process";
|
|
8121
|
-
import { existsSync as
|
|
8244
|
+
import { existsSync as existsSync14, readFileSync as readFileSync25 } from "fs";
|
|
8122
8245
|
var SAMPLE_INTERVAL_MS2 = 3e4;
|
|
8123
8246
|
function warnFraction() {
|
|
8124
8247
|
const raw = Number(process.env.AGT_PID_PRESSURE_WARN_FRACTION);
|
|
@@ -8140,7 +8263,7 @@ var cgroupDirCache = /* @__PURE__ */ new Map();
|
|
|
8140
8263
|
var resolveRetryAfter = /* @__PURE__ */ new Map();
|
|
8141
8264
|
var RESOLVE_RETRY_BACKOFF_MS = 5 * 6e4;
|
|
8142
8265
|
function resolveCgroupDirReal(codeName, deps = {}) {
|
|
8143
|
-
const exists = deps.exists ??
|
|
8266
|
+
const exists = deps.exists ?? existsSync14;
|
|
8144
8267
|
const inspectId = deps.inspectId ?? inspectContainerId;
|
|
8145
8268
|
const now = deps.now ?? Date.now;
|
|
8146
8269
|
const cached = cgroupDirCache.get(codeName);
|
|
@@ -9439,9 +9562,9 @@ async function fireOpencodeScheduledTask(agent, task) {
|
|
|
9439
9562
|
|
|
9440
9563
|
// src/lib/opencode-telegram-ingest.ts
|
|
9441
9564
|
import { createHash as createHash16 } from "crypto";
|
|
9442
|
-
import { existsSync as
|
|
9565
|
+
import { existsSync as existsSync15, mkdirSync as mkdirSync8, readFileSync as readFileSync26, renameSync as renameSync6, unlinkSync as unlinkSync4, writeFileSync as writeFileSync11 } from "fs";
|
|
9443
9566
|
import { randomUUID } from "crypto";
|
|
9444
|
-
import { join as
|
|
9567
|
+
import { join as join35 } from "path";
|
|
9445
9568
|
|
|
9446
9569
|
// src/lib/telegram-ingest.ts
|
|
9447
9570
|
import https2 from "https";
|
|
@@ -9989,7 +10112,7 @@ function createFileOffsetStore(codeName, log2, currentBotId) {
|
|
|
9989
10112
|
let filePath;
|
|
9990
10113
|
try {
|
|
9991
10114
|
dir = getFramework("opencode").getAgentDir(codeName);
|
|
9992
|
-
filePath =
|
|
10115
|
+
filePath = join35(dir, "telegram-getupdates-offset-opencode.json");
|
|
9993
10116
|
} catch {
|
|
9994
10117
|
dir = null;
|
|
9995
10118
|
filePath = null;
|
|
@@ -10031,7 +10154,7 @@ function createFileOffsetStore(codeName, log2, currentBotId) {
|
|
|
10031
10154
|
} catch (err) {
|
|
10032
10155
|
log2(`[telegram-ingest:${codeName}] offset persist failed: ${err instanceof Error ? err.message : String(err)}`);
|
|
10033
10156
|
try {
|
|
10034
|
-
if (
|
|
10157
|
+
if (existsSync15(tmpPath)) unlinkSync4(tmpPath);
|
|
10035
10158
|
} catch {
|
|
10036
10159
|
}
|
|
10037
10160
|
}
|
|
@@ -10268,24 +10391,24 @@ function partitionActionableByPoison(actionable, states, config2) {
|
|
|
10268
10391
|
}
|
|
10269
10392
|
|
|
10270
10393
|
// src/lib/restart-flags.ts
|
|
10271
|
-
import { existsSync as
|
|
10272
|
-
import { homedir as
|
|
10273
|
-
import { join as
|
|
10394
|
+
import { existsSync as existsSync16, mkdirSync as mkdirSync9, readdirSync as readdirSync8, readFileSync as readFileSync27, renameSync as renameSync7, rmSync as rmSync4, writeFileSync as writeFileSync12 } from "fs";
|
|
10395
|
+
import { homedir as homedir17 } from "os";
|
|
10396
|
+
import { join as join36 } from "path";
|
|
10274
10397
|
import { randomUUID as randomUUID2 } from "crypto";
|
|
10275
10398
|
function restartFlagsDir() {
|
|
10276
|
-
return
|
|
10399
|
+
return join36(homedir17(), ".augmented", "restart-flags");
|
|
10277
10400
|
}
|
|
10278
10401
|
function flagPath(codeName) {
|
|
10279
|
-
return
|
|
10402
|
+
return join36(restartFlagsDir(), `${codeName}.flag`);
|
|
10280
10403
|
}
|
|
10281
10404
|
function readRestartFlags() {
|
|
10282
10405
|
const dir = restartFlagsDir();
|
|
10283
|
-
if (!
|
|
10406
|
+
if (!existsSync16(dir)) return [];
|
|
10284
10407
|
const out = [];
|
|
10285
|
-
for (const entry of
|
|
10408
|
+
for (const entry of readdirSync8(dir)) {
|
|
10286
10409
|
if (!entry.endsWith(".flag")) continue;
|
|
10287
10410
|
try {
|
|
10288
|
-
const raw = readFileSync27(
|
|
10411
|
+
const raw = readFileSync27(join36(dir, entry), "utf8");
|
|
10289
10412
|
const parsed = JSON.parse(raw);
|
|
10290
10413
|
if (typeof parsed.codeName !== "string" || parsed.codeName.length === 0) {
|
|
10291
10414
|
parsed.codeName = entry.replace(/\.flag$/, "");
|
|
@@ -10303,7 +10426,7 @@ function readRestartFlags() {
|
|
|
10303
10426
|
}
|
|
10304
10427
|
function deleteRestartFlag(codeName) {
|
|
10305
10428
|
const path = flagPath(codeName);
|
|
10306
|
-
if (
|
|
10429
|
+
if (existsSync16(path)) {
|
|
10307
10430
|
rmSync4(path, { force: true });
|
|
10308
10431
|
}
|
|
10309
10432
|
}
|
|
@@ -10403,8 +10526,8 @@ async function sendError(flag, opts, text) {
|
|
|
10403
10526
|
}
|
|
10404
10527
|
|
|
10405
10528
|
// src/lib/restart-context.ts
|
|
10406
|
-
import { readdirSync as
|
|
10407
|
-
import { dirname as dirname9, join as
|
|
10529
|
+
import { readdirSync as readdirSync9, readFileSync as readFileSync28, writeFileSync as writeFileSync13, mkdirSync as mkdirSync10, unlinkSync as unlinkSync5 } from "fs";
|
|
10530
|
+
import { dirname as dirname9, join as join37 } from "path";
|
|
10408
10531
|
var SLACK_PENDING_INBOUND_DIRNAME = "slack-pending-inbound";
|
|
10409
10532
|
var SLACK_RESTART_CONTEXT_DIRNAME = "slack-restart-context";
|
|
10410
10533
|
var MAX_TOPIC_CHARS = 140;
|
|
@@ -10416,10 +10539,10 @@ function augmentedAgentDir(codeName) {
|
|
|
10416
10539
|
return dirname9(getProjectDir(codeName));
|
|
10417
10540
|
}
|
|
10418
10541
|
function slackPendingInboundDir(codeName) {
|
|
10419
|
-
return
|
|
10542
|
+
return join37(augmentedAgentDir(codeName), SLACK_PENDING_INBOUND_DIRNAME);
|
|
10420
10543
|
}
|
|
10421
10544
|
function slackRestartContextDir(codeName) {
|
|
10422
|
-
return
|
|
10545
|
+
return join37(augmentedAgentDir(codeName), SLACK_RESTART_CONTEXT_DIRNAME);
|
|
10423
10546
|
}
|
|
10424
10547
|
function sanitizeTopic(raw) {
|
|
10425
10548
|
const cleaned = raw.replace(/\s+/g, " ").trim().replace(/[<>]/g, " ").replace(/\s+/g, " ").trim();
|
|
@@ -10454,7 +10577,7 @@ function computeRestartContextHints(markers, allTurns, nowMs, reconstruct = reco
|
|
|
10454
10577
|
}
|
|
10455
10578
|
function safeReaddir(dir) {
|
|
10456
10579
|
try {
|
|
10457
|
-
return
|
|
10580
|
+
return readdirSync9(dir);
|
|
10458
10581
|
} catch {
|
|
10459
10582
|
return [];
|
|
10460
10583
|
}
|
|
@@ -10479,7 +10602,7 @@ function pruneHintsExcept(codeName, freshFilenames) {
|
|
|
10479
10602
|
if (!filename.endsWith(".json")) continue;
|
|
10480
10603
|
if (freshFilenames.has(filename)) continue;
|
|
10481
10604
|
try {
|
|
10482
|
-
unlinkSync5(
|
|
10605
|
+
unlinkSync5(join37(ctxDir, filename));
|
|
10483
10606
|
} catch {
|
|
10484
10607
|
}
|
|
10485
10608
|
}
|
|
@@ -10500,7 +10623,7 @@ function refreshSlackRestartContextHints(codeNames, opts = {}) {
|
|
|
10500
10623
|
}
|
|
10501
10624
|
const markers = [];
|
|
10502
10625
|
for (const filename of markerFilenames.slice(0, cap)) {
|
|
10503
|
-
const parsed = readStrandedMarker(
|
|
10626
|
+
const parsed = readStrandedMarker(join37(markerDir, filename));
|
|
10504
10627
|
if (parsed) markers.push({ filename, channel: parsed.channel, thread_ts: parsed.thread_ts });
|
|
10505
10628
|
}
|
|
10506
10629
|
if (markers.length === 0) {
|
|
@@ -10514,7 +10637,7 @@ function refreshSlackRestartContextHints(codeNames, opts = {}) {
|
|
|
10514
10637
|
const freshFilenames = /* @__PURE__ */ new Set();
|
|
10515
10638
|
for (const { filename, hint } of hints) {
|
|
10516
10639
|
try {
|
|
10517
|
-
writeHintFile(
|
|
10640
|
+
writeHintFile(join37(ctxDir, filename), ctxDir, hint);
|
|
10518
10641
|
freshFilenames.add(filename);
|
|
10519
10642
|
} catch (err) {
|
|
10520
10643
|
log2(`[restart-context] ${codeName}: hint write failed for ${filename}: ${err.message}`);
|
|
@@ -12142,7 +12265,7 @@ var runningChannelSecretHashes = /* @__PURE__ */ new Map();
|
|
|
12142
12265
|
var sessionLaunchManagedStructure = /* @__PURE__ */ new Map();
|
|
12143
12266
|
function projectMcpHash(_codeName, projectDir) {
|
|
12144
12267
|
try {
|
|
12145
|
-
const raw = readFileSync29(
|
|
12268
|
+
const raw = readFileSync29(join38(projectDir, ".mcp.json"), "utf-8");
|
|
12146
12269
|
return createHash17("sha256").update(canonicalJson(JSON.parse(raw))).digest("hex");
|
|
12147
12270
|
} catch {
|
|
12148
12271
|
return null;
|
|
@@ -12150,7 +12273,7 @@ function projectMcpHash(_codeName, projectDir) {
|
|
|
12150
12273
|
}
|
|
12151
12274
|
function projectMcpKeys(_codeName, projectDir) {
|
|
12152
12275
|
try {
|
|
12153
|
-
const raw = readFileSync29(
|
|
12276
|
+
const raw = readFileSync29(join38(projectDir, ".mcp.json"), "utf-8");
|
|
12154
12277
|
const parsed = JSON.parse(raw);
|
|
12155
12278
|
const servers = parsed.mcpServers;
|
|
12156
12279
|
if (!servers || typeof servers !== "object") return /* @__PURE__ */ new Set();
|
|
@@ -12168,7 +12291,7 @@ function seedSessionLaunchBaselines(codeName, projectDir) {
|
|
|
12168
12291
|
else runningMcpServerKeys.delete(codeName);
|
|
12169
12292
|
let launchStructure = null;
|
|
12170
12293
|
try {
|
|
12171
|
-
const raw = readFileSync29(
|
|
12294
|
+
const raw = readFileSync29(join38(projectDir, ".mcp.json"), "utf-8");
|
|
12172
12295
|
launchStructure = managedMcpStructureHashFromFile(
|
|
12173
12296
|
JSON.parse(raw),
|
|
12174
12297
|
isManagedMcpServerKey
|
|
@@ -12294,7 +12417,7 @@ async function runAgentSessionToolBindProbes(agent, integrations, projectDir, op
|
|
|
12294
12417
|
if (result && result.rebindCandidates.length > 0 && hostFlagStore().getBoolean("session-tool-rebind")) {
|
|
12295
12418
|
let mcpJsonForRebind = null;
|
|
12296
12419
|
try {
|
|
12297
|
-
mcpJsonForRebind = JSON.parse(readFileSync29(
|
|
12420
|
+
mcpJsonForRebind = JSON.parse(readFileSync29(join38(projectDir, ".mcp.json"), "utf-8"));
|
|
12298
12421
|
} catch {
|
|
12299
12422
|
mcpJsonForRebind = null;
|
|
12300
12423
|
}
|
|
@@ -12442,7 +12565,7 @@ function shouldInjectChannelSecrets(agentId) {
|
|
|
12442
12565
|
function projectChannelSecretHash(projectDir) {
|
|
12443
12566
|
try {
|
|
12444
12567
|
const entries = parseEnvIntegrations(
|
|
12445
|
-
readFileSync29(
|
|
12568
|
+
readFileSync29(join38(projectDir, ".env.integrations"), "utf-8")
|
|
12446
12569
|
);
|
|
12447
12570
|
return channelSecretValueHash(entries, CHANNEL_SECRET_ENV_KEYS);
|
|
12448
12571
|
} catch {
|
|
@@ -12540,7 +12663,7 @@ var agentRestartTimezoneInputs = /* @__PURE__ */ new Map();
|
|
|
12540
12663
|
var lastVersionCheckAt = 0;
|
|
12541
12664
|
var VERSION_CHECK_INTERVAL_MS = 5 * 60 * 1e3;
|
|
12542
12665
|
var lastResponsivenessProbeAt = 0;
|
|
12543
|
-
var agtCliVersion = true ? "0.28.
|
|
12666
|
+
var agtCliVersion = true ? "0.28.703" : "dev";
|
|
12544
12667
|
function resolveBrewPath(execFileSync3) {
|
|
12545
12668
|
try {
|
|
12546
12669
|
const out = execFileSync3("which", ["brew"], { timeout: 5e3 }).toString().trim();
|
|
@@ -12553,7 +12676,7 @@ function resolveBrewPath(execFileSync3) {
|
|
|
12553
12676
|
"/usr/local/bin/brew"
|
|
12554
12677
|
];
|
|
12555
12678
|
for (const path of fallbacks) {
|
|
12556
|
-
if (
|
|
12679
|
+
if (existsSync17(path)) return path;
|
|
12557
12680
|
}
|
|
12558
12681
|
return null;
|
|
12559
12682
|
}
|
|
@@ -12563,7 +12686,7 @@ function claudeBinaryInstalled(execFileSync3) {
|
|
|
12563
12686
|
"/opt/homebrew/bin/claude",
|
|
12564
12687
|
"/usr/local/bin/claude"
|
|
12565
12688
|
];
|
|
12566
|
-
if (canonical.some((path) =>
|
|
12689
|
+
if (canonical.some((path) => existsSync17(path))) return true;
|
|
12567
12690
|
try {
|
|
12568
12691
|
execFileSync3("which", ["claude"], { timeout: 5e3 });
|
|
12569
12692
|
return true;
|
|
@@ -12828,8 +12951,8 @@ async function reapSupersededRuntimeImages(imageUri, localTag) {
|
|
|
12828
12951
|
}
|
|
12829
12952
|
function runAsync(cmd, args, opts) {
|
|
12830
12953
|
return new Promise((resolve2, reject) => {
|
|
12831
|
-
import("child_process").then(({ spawn }) => {
|
|
12832
|
-
const child =
|
|
12954
|
+
import("child_process").then(({ spawn: spawn2 }) => {
|
|
12955
|
+
const child = spawn2(cmd, args, { stdio: ["ignore", "pipe", "pipe"], cwd: opts.cwd });
|
|
12833
12956
|
let stdout = "";
|
|
12834
12957
|
let stderr = "";
|
|
12835
12958
|
let settled = false;
|
|
@@ -12873,7 +12996,7 @@ var MANAGED_SETTINGS_KEYS = ["channelsEnabled", "enableAllProjectMcpServers"];
|
|
|
12873
12996
|
function ensureClaudeManagedSettings(path = claudeManagedSettingsPath()) {
|
|
12874
12997
|
try {
|
|
12875
12998
|
let settings = {};
|
|
12876
|
-
if (
|
|
12999
|
+
if (existsSync17(path)) {
|
|
12877
13000
|
const raw = readFileSync29(path, "utf-8").trim();
|
|
12878
13001
|
if (raw) {
|
|
12879
13002
|
let parsed;
|
|
@@ -12930,7 +13053,7 @@ async function ensureOpencodeBinary() {
|
|
|
12930
13053
|
try {
|
|
12931
13054
|
const prefix = execFileSync3("npm", ["prefix", "-g"], { encoding: "utf-8", timeout: 1e4 }).trim();
|
|
12932
13055
|
if (prefix) {
|
|
12933
|
-
const npmBin =
|
|
13056
|
+
const npmBin = join38(prefix, "bin");
|
|
12934
13057
|
const current = (process.env.PATH ?? "").split(pathDelimiter);
|
|
12935
13058
|
if (!current.includes(npmBin)) {
|
|
12936
13059
|
process.env.PATH = [npmBin, ...current.filter(Boolean)].join(pathDelimiter);
|
|
@@ -12991,7 +13114,7 @@ async function ensureFrameworkBinary(frameworkId) {
|
|
|
12991
13114
|
if (!process.env.PATH?.split(":").includes(brewBinDir)) {
|
|
12992
13115
|
process.env.PATH = `${brewBinDir}:${process.env.PATH ?? ""}`;
|
|
12993
13116
|
}
|
|
12994
|
-
if (
|
|
13117
|
+
if (existsSync17("/home/linuxbrew/.linuxbrew/bin/claude")) {
|
|
12995
13118
|
log("Claude Code installed successfully");
|
|
12996
13119
|
} else {
|
|
12997
13120
|
log("Claude Code install completed but binary not found at expected path \u2014 check brew logs");
|
|
@@ -13047,7 +13170,7 @@ ${r.stderr}`;
|
|
|
13047
13170
|
}
|
|
13048
13171
|
var UPDATE_CHECK_INTERVAL_MS = 5 * 60 * 1e3;
|
|
13049
13172
|
function selfUpdateAppliedMarkerPath() {
|
|
13050
|
-
return
|
|
13173
|
+
return join38(homedir18(), ".augmented", ".last-self-update-applied");
|
|
13051
13174
|
}
|
|
13052
13175
|
var selfUpdateUpToDateLogged = false;
|
|
13053
13176
|
var selfUpdatePinnedLogged = false;
|
|
@@ -13098,7 +13221,7 @@ async function checkAndUpdateCli(opts) {
|
|
|
13098
13221
|
const isNpmGlobal = !isBrewFormula && resolvedPath.includes("node_modules");
|
|
13099
13222
|
if (!isBrewFormula && !isNpmGlobal) return "noop";
|
|
13100
13223
|
const { readFileSync: readF, writeFileSync: writeF } = await import("fs");
|
|
13101
|
-
const markerPath =
|
|
13224
|
+
const markerPath = join38(homedir18(), ".augmented", ".last-update-check");
|
|
13102
13225
|
if (!force) {
|
|
13103
13226
|
try {
|
|
13104
13227
|
const lastCheck = parseInt(readF(markerPath, "utf-8").trim(), 10);
|
|
@@ -13505,7 +13628,7 @@ async function runClaudeRuntimeAuthProbe() {
|
|
|
13505
13628
|
];
|
|
13506
13629
|
try {
|
|
13507
13630
|
const { stdout, stderr } = await execFilePromiseLong(resolveClaudeBinary(), args, {
|
|
13508
|
-
cwd:
|
|
13631
|
+
cwd: homedir18(),
|
|
13509
13632
|
timeout: RUNTIME_AUTH_PROBE_TIMEOUT_MS,
|
|
13510
13633
|
stdin: "ignore",
|
|
13511
13634
|
env: childEnv,
|
|
@@ -13545,7 +13668,7 @@ async function runHostUsageCommand() {
|
|
|
13545
13668
|
""
|
|
13546
13669
|
];
|
|
13547
13670
|
const { stdout } = await execFilePromiseLong(resolveClaudeBinary(), args, {
|
|
13548
|
-
cwd:
|
|
13671
|
+
cwd: homedir18(),
|
|
13549
13672
|
timeout: HOST_USAGE_POLL_TIMEOUT_MS,
|
|
13550
13673
|
stdin: "ignore",
|
|
13551
13674
|
env: childEnv,
|
|
@@ -13591,13 +13714,13 @@ async function checkClaudeAuth() {
|
|
|
13591
13714
|
}
|
|
13592
13715
|
var evalEmptyMcpConfigPath = null;
|
|
13593
13716
|
function ensureEvalEmptyMcpConfig() {
|
|
13594
|
-
if (evalEmptyMcpConfigPath &&
|
|
13595
|
-
const dir =
|
|
13717
|
+
if (evalEmptyMcpConfigPath && existsSync17(evalEmptyMcpConfigPath)) return evalEmptyMcpConfigPath;
|
|
13718
|
+
const dir = join38(homedir18(), ".augmented");
|
|
13596
13719
|
try {
|
|
13597
13720
|
mkdirSync11(dir, { recursive: true });
|
|
13598
13721
|
} catch {
|
|
13599
13722
|
}
|
|
13600
|
-
const p =
|
|
13723
|
+
const p = join38(dir, ".eval-empty-mcp.json");
|
|
13601
13724
|
writeFileSync14(p, JSON.stringify({ mcpServers: {} }));
|
|
13602
13725
|
evalEmptyMcpConfigPath = p;
|
|
13603
13726
|
return p;
|
|
@@ -13623,7 +13746,7 @@ async function runEvalClaude(prompt, model) {
|
|
|
13623
13746
|
""
|
|
13624
13747
|
];
|
|
13625
13748
|
const { stdout } = await execFilePromiseLong(resolveClaudeBinary(), args, {
|
|
13626
|
-
cwd:
|
|
13749
|
+
cwd: homedir18(),
|
|
13627
13750
|
timeout: 12e4,
|
|
13628
13751
|
stdin: "ignore",
|
|
13629
13752
|
env: childEnv,
|
|
@@ -13692,10 +13815,10 @@ function resolveConversationEvalBackend() {
|
|
|
13692
13815
|
return conversationEvalBackend;
|
|
13693
13816
|
}
|
|
13694
13817
|
function getStateFile() {
|
|
13695
|
-
return
|
|
13818
|
+
return join38(config?.configDir ?? join38(process.env["HOME"] ?? "/tmp", ".augmented"), "manager-state.json");
|
|
13696
13819
|
}
|
|
13697
13820
|
function channelHashCacheDir() {
|
|
13698
|
-
return config?.configDir ??
|
|
13821
|
+
return config?.configDir ?? join38(process.env["HOME"] ?? "/tmp", ".augmented");
|
|
13699
13822
|
}
|
|
13700
13823
|
function loadChannelHashCache2() {
|
|
13701
13824
|
loadChannelHashCache(agentState.knownChannelConfigHashes, channelHashCacheDir());
|
|
@@ -13878,7 +14001,7 @@ function removeDeliveryBaselineEntries(agentId) {
|
|
|
13878
14001
|
var _channelQuarantineStore = null;
|
|
13879
14002
|
function channelQuarantineStore() {
|
|
13880
14003
|
if (!_channelQuarantineStore) {
|
|
13881
|
-
const dir = config?.configDir ??
|
|
14004
|
+
const dir = config?.configDir ?? join38(process.env["HOME"] ?? "/tmp", ".augmented");
|
|
13882
14005
|
_channelQuarantineStore = new ChannelQuarantineStore(defaultQuarantinePath(dir));
|
|
13883
14006
|
}
|
|
13884
14007
|
return _channelQuarantineStore;
|
|
@@ -13895,7 +14018,7 @@ function claudeMdSizeFor(codeName) {
|
|
|
13895
14018
|
var _hostFlagStore = null;
|
|
13896
14019
|
function hostFlagStore() {
|
|
13897
14020
|
if (!_hostFlagStore) {
|
|
13898
|
-
const dir = config?.configDir ??
|
|
14021
|
+
const dir = config?.configDir ?? join38(process.env["HOME"] ?? "/tmp", ".augmented");
|
|
13899
14022
|
_hostFlagStore = new HostFlagStore({ cachePath: defaultFlagsCachePath(dir), log });
|
|
13900
14023
|
}
|
|
13901
14024
|
return _hostFlagStore;
|
|
@@ -13968,13 +14091,13 @@ function parseSkillFrontmatter(content) {
|
|
|
13968
14091
|
return out;
|
|
13969
14092
|
}
|
|
13970
14093
|
async function refreshSkillsIndexInClaudeMd(configDir, codeName, log2) {
|
|
13971
|
-
const { readdirSync:
|
|
13972
|
-
const skillsDir =
|
|
13973
|
-
const claudeMdPath =
|
|
14094
|
+
const { readdirSync: readdirSync11, readFileSync: rfs, existsSync: ex, writeFileSync: writeFileSync15 } = await import("fs");
|
|
14095
|
+
const skillsDir = join38(configDir, codeName, "project", ".claude", "skills");
|
|
14096
|
+
const claudeMdPath = join38(configDir, codeName, "project", "CLAUDE.md");
|
|
13974
14097
|
if (!ex(skillsDir) || !ex(claudeMdPath)) return;
|
|
13975
14098
|
const entries = [];
|
|
13976
|
-
for (const dir of
|
|
13977
|
-
const skillFile =
|
|
14099
|
+
for (const dir of readdirSync11(skillsDir).sort()) {
|
|
14100
|
+
const skillFile = join38(skillsDir, dir, "SKILL.md");
|
|
13978
14101
|
if (!ex(skillFile)) continue;
|
|
13979
14102
|
try {
|
|
13980
14103
|
const { name, description } = parseSkillFrontmatter(rfs(skillFile, "utf-8"));
|
|
@@ -14513,10 +14636,10 @@ async function pollCycleInner() {
|
|
|
14513
14636
|
const paneTail = readFileSync29(paneLogPath(codeName), "utf8").slice(-65536);
|
|
14514
14637
|
const transient = detectTransientApiErrorInLog(paneTail);
|
|
14515
14638
|
if (transient) {
|
|
14516
|
-
const wedgeHome =
|
|
14517
|
-
if (
|
|
14639
|
+
const wedgeHome = join38(homedir18(), ".augmented", codeName);
|
|
14640
|
+
if (existsSync17(wedgeHome)) {
|
|
14518
14641
|
atomicWriteFileSync(
|
|
14519
|
-
|
|
14642
|
+
join38(wedgeHome, "watchdog-give-up.json"),
|
|
14520
14643
|
JSON.stringify({
|
|
14521
14644
|
gave_up_at: wedgeNow.toISOString(),
|
|
14522
14645
|
reason: "transient_overload"
|
|
@@ -14813,7 +14936,26 @@ async function pollCycleInner() {
|
|
|
14813
14936
|
const adapter = resolveAgentFramework(prev.codeName);
|
|
14814
14937
|
stopAgentRuntime2(prev.codeName, "removed-from-host");
|
|
14815
14938
|
killAgentChannelProcesses(prev.codeName, { log });
|
|
14816
|
-
|
|
14939
|
+
try {
|
|
14940
|
+
const flush = await flushAgentTranscriptsOnDrain(
|
|
14941
|
+
prev.codeName,
|
|
14942
|
+
drainTranscriptFlushDeps(log)
|
|
14943
|
+
);
|
|
14944
|
+
if (flush.status === "flushed") {
|
|
14945
|
+
log(
|
|
14946
|
+
`[drain-flush] shipped ${flush.uploaded} transcript file(s) for '${prev.codeName}' before teardown (ENG-9491)`
|
|
14947
|
+
);
|
|
14948
|
+
} else if (flush.status === "no-transcripts") {
|
|
14949
|
+
log(
|
|
14950
|
+
`[drain-flush] no transcripts on disk for '${prev.codeName}' \u2014 nothing to flush (ENG-9491)`
|
|
14951
|
+
);
|
|
14952
|
+
}
|
|
14953
|
+
} catch (err) {
|
|
14954
|
+
log(
|
|
14955
|
+
`[drain-flush] FAILED for '${prev.codeName}': ${err.message} \u2014 proceeding to teardown; this session was NOT shipped (ENG-9491)`
|
|
14956
|
+
);
|
|
14957
|
+
}
|
|
14958
|
+
const agentDir = join38(adapter.getAgentDir(prev.codeName), "provision");
|
|
14817
14959
|
await cleanupAgentFiles(prev.codeName, agentDir);
|
|
14818
14960
|
clearAgentCaches(prev.agentId, prev.codeName);
|
|
14819
14961
|
}
|
|
@@ -14900,10 +15042,10 @@ async function pollCycleInner() {
|
|
|
14900
15042
|
// pending-inbound marker. Best-effort: a write failure is logged by
|
|
14901
15043
|
// the watchdog, never fails the poll cycle.
|
|
14902
15044
|
signalGiveUp: (codeName) => {
|
|
14903
|
-
const dir =
|
|
14904
|
-
if (!
|
|
15045
|
+
const dir = join38(homedir18(), ".augmented", codeName);
|
|
15046
|
+
if (!existsSync17(dir)) return;
|
|
14905
15047
|
atomicWriteFileSync(
|
|
14906
|
-
|
|
15048
|
+
join38(dir, "watchdog-give-up.json"),
|
|
14907
15049
|
JSON.stringify({ gave_up_at: (/* @__PURE__ */ new Date()).toISOString() })
|
|
14908
15050
|
);
|
|
14909
15051
|
},
|
|
@@ -14922,9 +15064,9 @@ async function pollCycleInner() {
|
|
|
14922
15064
|
// parser elsewhere can only reconstruct an hour (ENG-8901).
|
|
14923
15065
|
signalUsageLimit: (codeName, resetsHint) => {
|
|
14924
15066
|
const dir = getFramework("claude-code").getAgentDir(codeName);
|
|
14925
|
-
if (!
|
|
15067
|
+
if (!existsSync17(dir)) return;
|
|
14926
15068
|
atomicWriteFileSync(
|
|
14927
|
-
|
|
15069
|
+
join38(dir, "watchdog-give-up.json"),
|
|
14928
15070
|
JSON.stringify({
|
|
14929
15071
|
gave_up_at: (/* @__PURE__ */ new Date()).toISOString(),
|
|
14930
15072
|
reason: "usage_limit",
|
|
@@ -15186,7 +15328,7 @@ async function processAgent(agent, agentStates, managedToolkits) {
|
|
|
15186
15328
|
}
|
|
15187
15329
|
const now = (/* @__PURE__ */ new Date()).toISOString();
|
|
15188
15330
|
const adapter = resolveAgentFramework(agent.code_name);
|
|
15189
|
-
let agentDir =
|
|
15331
|
+
let agentDir = join38(adapter.getAgentDir(agent.code_name), "provision");
|
|
15190
15332
|
if (agent.status === "draft" || agent.status === "paused") {
|
|
15191
15333
|
forgetChannelSyncState(agent.agent_id);
|
|
15192
15334
|
if (previousKnownStatus !== agent.status) {
|
|
@@ -15227,7 +15369,7 @@ async function processAgent(agent, agentStates, managedToolkits) {
|
|
|
15227
15369
|
const residuals = {
|
|
15228
15370
|
gatewayRunning: false,
|
|
15229
15371
|
portAllocated: false,
|
|
15230
|
-
provisionDirExists:
|
|
15372
|
+
provisionDirExists: existsSync17(agentDir)
|
|
15231
15373
|
};
|
|
15232
15374
|
if (!hasRevokedResiduals(residuals)) {
|
|
15233
15375
|
agentStates.push({
|
|
@@ -15361,7 +15503,7 @@ async function processAgent(agent, agentStates, managedToolkits) {
|
|
|
15361
15503
|
const frameworkId = refreshData.agent.framework ?? DEFAULT_FRAMEWORK;
|
|
15362
15504
|
agentFrameworkCache.set(agent.code_name, frameworkId);
|
|
15363
15505
|
const frameworkAdapter = getFramework(frameworkId);
|
|
15364
|
-
agentDir =
|
|
15506
|
+
agentDir = join38(frameworkAdapter.getAgentDir(agent.code_name), "provision");
|
|
15365
15507
|
cacheAgentDeliveryMetadata(agent.code_name, refreshData);
|
|
15366
15508
|
agentRestartTimezoneInputs.set(agent.code_name, {
|
|
15367
15509
|
agentTimezone: typeof refreshData.agent.timezone === "string" ? refreshData.agent.timezone : null,
|
|
@@ -15419,7 +15561,7 @@ async function processAgent(agent, agentStates, managedToolkits) {
|
|
|
15419
15561
|
const changedFiles = [];
|
|
15420
15562
|
mkdirSync11(agentDir, { recursive: true });
|
|
15421
15563
|
for (const artifact of artifacts) {
|
|
15422
|
-
const filePath =
|
|
15564
|
+
const filePath = join38(agentDir, artifact.relativePath);
|
|
15423
15565
|
let existingHash;
|
|
15424
15566
|
let newHash;
|
|
15425
15567
|
let writeContent = artifact.content;
|
|
@@ -15438,7 +15580,7 @@ async function processAgent(agent, agentStates, managedToolkits) {
|
|
|
15438
15580
|
};
|
|
15439
15581
|
newHash = sha256(stripDynamicSections(artifact.content));
|
|
15440
15582
|
try {
|
|
15441
|
-
const projectClaudeMd =
|
|
15583
|
+
const projectClaudeMd = join38(config.configDir, agent.code_name, "project", "CLAUDE.md");
|
|
15442
15584
|
const existing = readFileSync29(projectClaudeMd, "utf-8");
|
|
15443
15585
|
existingHash = sha256(stripDynamicSections(existing));
|
|
15444
15586
|
} catch {
|
|
@@ -15489,12 +15631,12 @@ async function processAgent(agent, agentStates, managedToolkits) {
|
|
|
15489
15631
|
}
|
|
15490
15632
|
}
|
|
15491
15633
|
if (changedFiles.length > 0) {
|
|
15492
|
-
const isFirst = !
|
|
15634
|
+
const isFirst = !existsSync17(join38(agentDir, "CHARTER.md"));
|
|
15493
15635
|
const verb = isFirst ? "Provisioning" : "Updating";
|
|
15494
15636
|
const fileNames = changedFiles.map((f) => f.relativePath).join(", ");
|
|
15495
15637
|
log(`${verb} '${agent.code_name}': ${fileNames}`);
|
|
15496
15638
|
for (const file of changedFiles) {
|
|
15497
|
-
const filePath =
|
|
15639
|
+
const filePath = join38(agentDir, file.relativePath);
|
|
15498
15640
|
mkdirSync11(dirname10(filePath), { recursive: true });
|
|
15499
15641
|
if (file.relativePath === ".mcp.json") {
|
|
15500
15642
|
safeWriteJsonAtomic(filePath, file.content, { mode: 384 });
|
|
@@ -15503,12 +15645,12 @@ async function processAgent(agent, agentStates, managedToolkits) {
|
|
|
15503
15645
|
}
|
|
15504
15646
|
}
|
|
15505
15647
|
try {
|
|
15506
|
-
const provSkillsDir =
|
|
15507
|
-
if (
|
|
15508
|
-
for (const folder of
|
|
15648
|
+
const provSkillsDir = join38(agentDir, ".claude", "skills");
|
|
15649
|
+
if (existsSync17(provSkillsDir)) {
|
|
15650
|
+
for (const folder of readdirSync10(provSkillsDir)) {
|
|
15509
15651
|
if (folder.startsWith("knowledge-")) {
|
|
15510
15652
|
try {
|
|
15511
|
-
rmSync5(
|
|
15653
|
+
rmSync5(join38(provSkillsDir, folder), { recursive: true });
|
|
15512
15654
|
} catch {
|
|
15513
15655
|
}
|
|
15514
15656
|
}
|
|
@@ -15521,7 +15663,7 @@ async function processAgent(agent, agentStates, managedToolkits) {
|
|
|
15521
15663
|
const trackedFiles2 = frameworkAdapter.driftTrackedFiles();
|
|
15522
15664
|
const hashes = /* @__PURE__ */ new Map();
|
|
15523
15665
|
for (const file of trackedFiles2) {
|
|
15524
|
-
const h = hashFile(
|
|
15666
|
+
const h = hashFile(join38(agentDir, file));
|
|
15525
15667
|
if (h) hashes.set(file, h);
|
|
15526
15668
|
}
|
|
15527
15669
|
agentState.writtenHashes.set(agent.agent_id, hashes);
|
|
@@ -15539,14 +15681,14 @@ async function processAgent(agent, agentStates, managedToolkits) {
|
|
|
15539
15681
|
}
|
|
15540
15682
|
if (Array.isArray(refreshData.workflows)) {
|
|
15541
15683
|
try {
|
|
15542
|
-
const provWorkflowsDir =
|
|
15543
|
-
if (
|
|
15684
|
+
const provWorkflowsDir = join38(agentDir, ".claude", "workflows");
|
|
15685
|
+
if (existsSync17(provWorkflowsDir)) {
|
|
15544
15686
|
const expected = new Set(refreshData.workflows.map((w) => `${w.name}.js`));
|
|
15545
|
-
for (const file of
|
|
15687
|
+
for (const file of readdirSync10(provWorkflowsDir)) {
|
|
15546
15688
|
if (!file.endsWith(".js")) continue;
|
|
15547
15689
|
if (expected.has(file)) continue;
|
|
15548
15690
|
try {
|
|
15549
|
-
rmSync5(
|
|
15691
|
+
rmSync5(join38(provWorkflowsDir, file));
|
|
15550
15692
|
} catch {
|
|
15551
15693
|
}
|
|
15552
15694
|
}
|
|
@@ -15625,10 +15767,10 @@ async function processAgent(agent, agentStates, managedToolkits) {
|
|
|
15625
15767
|
}
|
|
15626
15768
|
let lastDriftCheckAt = now;
|
|
15627
15769
|
const written = agentState.writtenHashes.get(agent.agent_id);
|
|
15628
|
-
if (written &&
|
|
15770
|
+
if (written && existsSync17(agentDir)) {
|
|
15629
15771
|
const driftedFiles = [];
|
|
15630
15772
|
for (const [file, expectedHash] of written) {
|
|
15631
|
-
const localHash = hashFile(
|
|
15773
|
+
const localHash = hashFile(join38(agentDir, file));
|
|
15632
15774
|
if (localHash && localHash !== expectedHash) {
|
|
15633
15775
|
driftedFiles.push(file);
|
|
15634
15776
|
}
|
|
@@ -15639,7 +15781,7 @@ async function processAgent(agent, agentStates, managedToolkits) {
|
|
|
15639
15781
|
try {
|
|
15640
15782
|
const localHashes = {};
|
|
15641
15783
|
for (const file of driftedFiles) {
|
|
15642
|
-
localHashes[file] = hashFile(
|
|
15784
|
+
localHashes[file] = hashFile(join38(agentDir, file));
|
|
15643
15785
|
}
|
|
15644
15786
|
await api.post("/host/drift", {
|
|
15645
15787
|
agent_id: agent.agent_id,
|
|
@@ -15884,7 +16026,7 @@ async function processAgent(agent, agentStates, managedToolkits) {
|
|
|
15884
16026
|
const addedChannels = [...restartDecision.added];
|
|
15885
16027
|
const writeDmNoticeMarkers = isChannelAddRestart ? () => {
|
|
15886
16028
|
try {
|
|
15887
|
-
const agentAugmentedDir =
|
|
16029
|
+
const agentAugmentedDir = join38(homedir18(), ".augmented", agent.code_name);
|
|
15888
16030
|
mkdirSync11(agentAugmentedDir, { recursive: true });
|
|
15889
16031
|
const markerJson = JSON.stringify({
|
|
15890
16032
|
version: 1,
|
|
@@ -15892,7 +16034,7 @@ async function processAgent(agent, agentStates, managedToolkits) {
|
|
|
15892
16034
|
added: addedChannels
|
|
15893
16035
|
});
|
|
15894
16036
|
for (const file of ["slack-channel-add-restart.json", "telegram-channel-add-restart.json"]) {
|
|
15895
|
-
atomicWriteFileSync(
|
|
16037
|
+
atomicWriteFileSync(join38(agentAugmentedDir, file), markerJson);
|
|
15896
16038
|
}
|
|
15897
16039
|
} catch (err) {
|
|
15898
16040
|
log(`[hot-reload] channel-add DM-notice marker write failed for '${agent.code_name}' (non-fatal): ${err.message}`);
|
|
@@ -16081,24 +16223,24 @@ async function processAgent(agent, agentStates, managedToolkits) {
|
|
|
16081
16223
|
if (agentSessionMode === "persistent" && (agentFrameworkCache.get(agent.code_name) ?? DEFAULT_FRAMEWORK) === "claude-code") {
|
|
16082
16224
|
try {
|
|
16083
16225
|
const agentProvisionDir = agentDir;
|
|
16084
|
-
const projectDir =
|
|
16226
|
+
const projectDir = join38(homedir18(), ".augmented", agent.code_name, "project");
|
|
16085
16227
|
mkdirSync11(agentProvisionDir, { recursive: true });
|
|
16086
16228
|
mkdirSync11(projectDir, { recursive: true });
|
|
16087
|
-
const provisionMcpPath =
|
|
16088
|
-
const projectMcpPath =
|
|
16229
|
+
const provisionMcpPath = join38(agentProvisionDir, ".mcp.json");
|
|
16230
|
+
const projectMcpPath = join38(projectDir, ".mcp.json");
|
|
16089
16231
|
let mcpConfig = { mcpServers: {} };
|
|
16090
16232
|
try {
|
|
16091
16233
|
mcpConfig = JSON.parse(readFileSync29(provisionMcpPath, "utf-8"));
|
|
16092
16234
|
if (!mcpConfig.mcpServers) mcpConfig.mcpServers = {};
|
|
16093
16235
|
} catch {
|
|
16094
16236
|
}
|
|
16095
|
-
const localDirectChatChannel =
|
|
16237
|
+
const localDirectChatChannel = join38(homedir18(), ".augmented", "_mcp", "direct-chat-channel.js");
|
|
16096
16238
|
const directChatTeamSettings = refreshData.team?.settings;
|
|
16097
16239
|
const directChatTz = (() => {
|
|
16098
16240
|
const tz = directChatTeamSettings?.["timezone"];
|
|
16099
16241
|
return typeof tz === "string" && tz.trim() !== "" ? tz.trim() : void 0;
|
|
16100
16242
|
})();
|
|
16101
|
-
if (
|
|
16243
|
+
if (existsSync17(localDirectChatChannel)) {
|
|
16102
16244
|
const directChatEnv = {
|
|
16103
16245
|
AGT_HOST: requireHost(),
|
|
16104
16246
|
// ENG-5901 Track D: templated — the manager exports the real
|
|
@@ -16118,7 +16260,7 @@ async function processAgent(agent, agentStates, managedToolkits) {
|
|
|
16118
16260
|
// ~/.augmented/<codeName>/.current-turn-initiator.json. Note getAgentDir
|
|
16119
16261
|
// returns the agent root (NOT the /provision subdir `agentDir` points at),
|
|
16120
16262
|
// so it byte-matches the broker readers' path.
|
|
16121
|
-
AGT_TURN_INITIATOR_FILE:
|
|
16263
|
+
AGT_TURN_INITIATOR_FILE: join38(
|
|
16122
16264
|
frameworkAdapter.getAgentDir(agent.code_name),
|
|
16123
16265
|
".current-turn-initiator.json"
|
|
16124
16266
|
)
|
|
@@ -16138,8 +16280,8 @@ async function processAgent(agent, agentStates, managedToolkits) {
|
|
|
16138
16280
|
log(`Channel credentials written for '${agent.code_name}/direct-chat'`);
|
|
16139
16281
|
}
|
|
16140
16282
|
}
|
|
16141
|
-
const staleChannelsPath =
|
|
16142
|
-
if (
|
|
16283
|
+
const staleChannelsPath = join38(projectDir, ".mcp-channels.json");
|
|
16284
|
+
if (existsSync17(staleChannelsPath)) {
|
|
16143
16285
|
try {
|
|
16144
16286
|
rmSync5(staleChannelsPath, { force: true });
|
|
16145
16287
|
} catch {
|
|
@@ -16228,7 +16370,7 @@ async function processAgent(agent, agentStates, managedToolkits) {
|
|
|
16228
16370
|
}
|
|
16229
16371
|
if (hostFlagStore().getBoolean("connectivity-probe")) {
|
|
16230
16372
|
try {
|
|
16231
|
-
const probeProjectDir =
|
|
16373
|
+
const probeProjectDir = join38(homedir18(), ".augmented", agent.code_name, "project");
|
|
16232
16374
|
let probeSet = integrations;
|
|
16233
16375
|
try {
|
|
16234
16376
|
const quarantined = await api.post("/host/agent-integrations/quarantined", { agent_id: agent.agent_id });
|
|
@@ -16274,7 +16416,7 @@ async function processAgent(agent, agentStates, managedToolkits) {
|
|
|
16274
16416
|
const forceDue = attemptsLeft > 0;
|
|
16275
16417
|
let probeRan = false;
|
|
16276
16418
|
try {
|
|
16277
|
-
const probeProjectDir =
|
|
16419
|
+
const probeProjectDir = join38(homedir18(), ".augmented", agent.code_name, "project");
|
|
16278
16420
|
probeRan = await runAgentSessionToolBindProbes(agent, integrations, probeProjectDir, { forceDue });
|
|
16279
16421
|
} catch (err) {
|
|
16280
16422
|
log(`Session-tool-bind probe failed for '${agent.code_name}': ${err.message}`);
|
|
@@ -16351,8 +16493,8 @@ async function processAgent(agent, agentStates, managedToolkits) {
|
|
|
16351
16493
|
const intHash = computeIntegrationsHash(integrations);
|
|
16352
16494
|
const prevIntHash = agentState.knownIntegrationHashes.get(agent.agent_id);
|
|
16353
16495
|
if (intHash !== prevIntHash) {
|
|
16354
|
-
const projectDir =
|
|
16355
|
-
const envIntPath =
|
|
16496
|
+
const projectDir = join38(homedir18(), ".augmented", agent.code_name, "project");
|
|
16497
|
+
const envIntPath = join38(projectDir, ".env.integrations");
|
|
16356
16498
|
let preWriteEnv;
|
|
16357
16499
|
try {
|
|
16358
16500
|
preWriteEnv = readFileSync29(envIntPath, "utf-8");
|
|
@@ -16374,7 +16516,7 @@ async function processAgent(agent, agentStates, managedToolkits) {
|
|
|
16374
16516
|
}
|
|
16375
16517
|
if (fw === "claude-code" && isSessionHealthy(agent.code_name)) {
|
|
16376
16518
|
try {
|
|
16377
|
-
const projectMcpPath =
|
|
16519
|
+
const projectMcpPath = join38(projectDir, ".mcp.json");
|
|
16378
16520
|
const postWriteEnv = readFileSync29(envIntPath, "utf-8");
|
|
16379
16521
|
const mcpContent = readFileSync29(projectMcpPath, "utf-8");
|
|
16380
16522
|
const changedVars = diffEnvIntegrations(preWriteEnv, postWriteEnv);
|
|
@@ -16639,23 +16781,23 @@ async function processAgent(agent, agentStates, managedToolkits) {
|
|
|
16639
16781
|
}
|
|
16640
16782
|
}
|
|
16641
16783
|
try {
|
|
16642
|
-
const { readdirSync:
|
|
16643
|
-
const { homedir:
|
|
16784
|
+
const { readdirSync: readdirSync11, rmSync: rmSync6 } = await import("fs");
|
|
16785
|
+
const { homedir: homedir19 } = await import("os");
|
|
16644
16786
|
const frameworkId2 = frameworkAdapter.id;
|
|
16645
16787
|
const candidateSkillDirs = [
|
|
16646
16788
|
// Claude Code — framework runtime tree
|
|
16647
|
-
|
|
16789
|
+
join38(homedir19(), ".augmented", agent.code_name, "skills"),
|
|
16648
16790
|
// Claude Code — project tree
|
|
16649
|
-
|
|
16791
|
+
join38(homedir19(), ".augmented", agent.code_name, "project", ".claude", "skills"),
|
|
16650
16792
|
// Defensive: legacy provision-side path, not currently an
|
|
16651
16793
|
// install target but cheap to sweep.
|
|
16652
|
-
|
|
16794
|
+
join38(agentDir, ".claude", "skills")
|
|
16653
16795
|
];
|
|
16654
|
-
const existingDirs = candidateSkillDirs.filter((d) =>
|
|
16796
|
+
const existingDirs = candidateSkillDirs.filter((d) => existsSync17(d));
|
|
16655
16797
|
const discoveredEntries = /* @__PURE__ */ new Set();
|
|
16656
16798
|
for (const dir of existingDirs) {
|
|
16657
16799
|
try {
|
|
16658
|
-
for (const entry of
|
|
16800
|
+
for (const entry of readdirSync11(dir)) {
|
|
16659
16801
|
if (entry.startsWith("plugin-") || entry.startsWith("integration-")) {
|
|
16660
16802
|
discoveredEntries.add(entry);
|
|
16661
16803
|
}
|
|
@@ -16670,7 +16812,7 @@ async function processAgent(agent, agentStates, managedToolkits) {
|
|
|
16670
16812
|
entry,
|
|
16671
16813
|
dirs: existingDirs,
|
|
16672
16814
|
removeDir: (p) => {
|
|
16673
|
-
if (
|
|
16815
|
+
if (existsSync17(p)) {
|
|
16674
16816
|
rmSync6(p, { recursive: true, force: true });
|
|
16675
16817
|
}
|
|
16676
16818
|
}
|
|
@@ -16690,7 +16832,7 @@ async function processAgent(agent, agentStates, managedToolkits) {
|
|
|
16690
16832
|
const sharedSkillsPayload = refreshAny.shared_skills;
|
|
16691
16833
|
const desiredResolved = globalSkillsPayload !== void 0 || sharedSkillsPayload !== void 0;
|
|
16692
16834
|
const manifestPath = managedSkillManifestPath(
|
|
16693
|
-
|
|
16835
|
+
join38(homedir18(), ".augmented", agent.code_name)
|
|
16694
16836
|
);
|
|
16695
16837
|
const prevIds = /* @__PURE__ */ new Set([
|
|
16696
16838
|
...agentState.knownGlobalSkillIds.get(agent.agent_id) ?? /* @__PURE__ */ new Set(),
|
|
@@ -16710,15 +16852,15 @@ async function processAgent(agent, agentStates, managedToolkits) {
|
|
|
16710
16852
|
}
|
|
16711
16853
|
if (plan.removes.length) {
|
|
16712
16854
|
const globalSkillDirs = [
|
|
16713
|
-
|
|
16714
|
-
|
|
16715
|
-
|
|
16855
|
+
join38(homedir18(), ".augmented", agent.code_name, "skills"),
|
|
16856
|
+
join38(homedir18(), ".augmented", agent.code_name, "project", ".claude", "skills"),
|
|
16857
|
+
join38(agentDir, ".claude", "skills")
|
|
16716
16858
|
];
|
|
16717
16859
|
for (const id of plan.removes) {
|
|
16718
16860
|
let prunedAny = false;
|
|
16719
16861
|
for (const dir of globalSkillDirs) {
|
|
16720
|
-
const p =
|
|
16721
|
-
if (
|
|
16862
|
+
const p = join38(dir, id);
|
|
16863
|
+
if (existsSync17(p) && existsSync17(join38(p, "SKILL.md"))) {
|
|
16722
16864
|
rmSync5(p, { recursive: true, force: true });
|
|
16723
16865
|
prunedAny = true;
|
|
16724
16866
|
}
|
|
@@ -16954,7 +17096,7 @@ async function processAgent(agent, agentStates, managedToolkits) {
|
|
|
16954
17096
|
const sess = getSessionState(agent.code_name);
|
|
16955
17097
|
let mcpJsonParsed = null;
|
|
16956
17098
|
try {
|
|
16957
|
-
const mcpPath =
|
|
17099
|
+
const mcpPath = join38(getProjectDir(agent.code_name), ".mcp.json");
|
|
16958
17100
|
mcpJsonParsed = JSON.parse(readFileSync29(mcpPath, "utf-8"));
|
|
16959
17101
|
} catch {
|
|
16960
17102
|
}
|
|
@@ -17386,10 +17528,10 @@ Retried to the limit after repeated stalls \u2014 needs a look.`).catch(() => {
|
|
|
17386
17528
|
}
|
|
17387
17529
|
}
|
|
17388
17530
|
const trackedFiles = frameworkAdapter.driftTrackedFiles();
|
|
17389
|
-
if (trackedFiles.length > 0 &&
|
|
17531
|
+
if (trackedFiles.length > 0 && existsSync17(agentDir)) {
|
|
17390
17532
|
const hashes = /* @__PURE__ */ new Map();
|
|
17391
17533
|
for (const file of trackedFiles) {
|
|
17392
|
-
const h = hashFile(
|
|
17534
|
+
const h = hashFile(join38(agentDir, file));
|
|
17393
17535
|
if (h) hashes.set(file, h);
|
|
17394
17536
|
}
|
|
17395
17537
|
agentState.writtenHashes.set(agent.agent_id, hashes);
|
|
@@ -17404,7 +17546,7 @@ Retried to the limit after repeated stalls \u2014 needs a look.`).catch(() => {
|
|
|
17404
17546
|
refreshData.agent.onboarding_state
|
|
17405
17547
|
);
|
|
17406
17548
|
const obStep = obState.step;
|
|
17407
|
-
const markerPath =
|
|
17549
|
+
const markerPath = join38(homedir18(), ".augmented", agent.code_name, "onboarding-drive.json");
|
|
17408
17550
|
const marker = readOnboardingDriveMarker(markerPath);
|
|
17409
17551
|
const obContactRaw = refreshData.agent.manager_last_contacted_at;
|
|
17410
17552
|
const obContact = typeof obContactRaw === "string" && obContactRaw ? obContactRaw : null;
|
|
@@ -17506,7 +17648,7 @@ async function ensureOpencodeRuntime(agent, refreshData, agentTimezone) {
|
|
|
17506
17648
|
}
|
|
17507
17649
|
stopOpencodeSlackIngest(codeName, log);
|
|
17508
17650
|
stopOpencodeTelegramIngest(codeName, log);
|
|
17509
|
-
const opencodeProjectDir =
|
|
17651
|
+
const opencodeProjectDir = join38(getFramework("opencode").getAgentDir(codeName), "provision");
|
|
17510
17652
|
const serveEnv = {
|
|
17511
17653
|
AGT_HOST: requireHost(),
|
|
17512
17654
|
AGT_API_KEY: getApiKey() ?? void 0,
|
|
@@ -17561,8 +17703,8 @@ async function ensurePersistentSession(agent, tasks, boardItems, refreshData) {
|
|
|
17561
17703
|
});
|
|
17562
17704
|
}
|
|
17563
17705
|
const projectDir = getProjectDir(codeName);
|
|
17564
|
-
const mcpConfigPath =
|
|
17565
|
-
const claudeMdPath =
|
|
17706
|
+
const mcpConfigPath = join38(projectDir, ".mcp.json");
|
|
17707
|
+
const claudeMdPath = join38(projectDir, "CLAUDE.md");
|
|
17566
17708
|
if (restartBreaker.isTripped(codeName)) {
|
|
17567
17709
|
const trip = restartBreaker.getTrip(codeName);
|
|
17568
17710
|
return {
|
|
@@ -18785,7 +18927,7 @@ async function processDirectChatMessage(agent, msg) {
|
|
|
18785
18927
|
const useDoorbell = hostFlagStore().getBoolean("direct-chat-doorbell") || isolationMode(agent.codeName) === "docker";
|
|
18786
18928
|
if (useDoorbell) {
|
|
18787
18929
|
try {
|
|
18788
|
-
const doorbell = directChatDoorbellPath(agent.agentId,
|
|
18930
|
+
const doorbell = directChatDoorbellPath(agent.agentId, homedir18());
|
|
18789
18931
|
mkdirSync11(dirname10(doorbell), { recursive: true });
|
|
18790
18932
|
writeFileSync14(doorbell, String(Date.now()));
|
|
18791
18933
|
log(`[direct-chat] Doorbell rung for '${agent.codeName}' (msg=${msg.id}) \u2014 in-session MCP will pull via the cursor`);
|
|
@@ -18914,7 +19056,7 @@ ${formatRunMarker(run_id)}` : KANBAN_CHECK_COMMAND;
|
|
|
18914
19056
|
}
|
|
18915
19057
|
if (run_id) openInjectedRunByCode.set(codeName, run_id);
|
|
18916
19058
|
try {
|
|
18917
|
-
const doorbell = directChatDoorbellPath(agentId,
|
|
19059
|
+
const doorbell = directChatDoorbellPath(agentId, homedir18());
|
|
18918
19060
|
mkdirSync11(dirname10(doorbell), { recursive: true });
|
|
18919
19061
|
writeFileSync14(doorbell, String(Date.now()));
|
|
18920
19062
|
} catch (err) {
|
|
@@ -19055,12 +19197,12 @@ async function processClaudePairSessions(agents) {
|
|
|
19055
19197
|
try {
|
|
19056
19198
|
if (session.status === "initiating") {
|
|
19057
19199
|
log(`[claude-pair] spawning pair session ${pairSession} for '${codeName}'`);
|
|
19058
|
-
const
|
|
19059
|
-
if (!
|
|
19200
|
+
const spawn2 = await spawnPairSession(pairSession);
|
|
19201
|
+
if (!spawn2.ok) {
|
|
19060
19202
|
await reportAndCleanup(session.pair_id, {
|
|
19061
19203
|
status: "failure",
|
|
19062
|
-
error_code:
|
|
19063
|
-
error_message:
|
|
19204
|
+
error_code: spawn2.error.kind,
|
|
19205
|
+
error_message: spawn2.error.kind === "unknown" ? spawn2.error.message : void 0
|
|
19064
19206
|
});
|
|
19065
19207
|
continue;
|
|
19066
19208
|
}
|
|
@@ -19245,10 +19387,10 @@ var lastDownloadHash = /* @__PURE__ */ new Map();
|
|
|
19245
19387
|
var lastLocalFileHash = /* @__PURE__ */ new Map();
|
|
19246
19388
|
var memoryManifests = /* @__PURE__ */ new Map();
|
|
19247
19389
|
function memoryRetirementDir(configDir, codeName) {
|
|
19248
|
-
return
|
|
19390
|
+
return join38(configDir, "_memory-retirement", codeName);
|
|
19249
19391
|
}
|
|
19250
19392
|
function memoryManifestPath(configDir, codeName) {
|
|
19251
|
-
return
|
|
19393
|
+
return join38(memoryRetirementDir(configDir, codeName), "manifest.json");
|
|
19252
19394
|
}
|
|
19253
19395
|
function loadMemoryManifest(agentId, configDir, codeName) {
|
|
19254
19396
|
const cached = memoryManifests.get(agentId);
|
|
@@ -19283,7 +19425,7 @@ function saveMemoryManifest(agentId, configDir, codeName) {
|
|
|
19283
19425
|
}
|
|
19284
19426
|
}
|
|
19285
19427
|
function retiredMemoryDir(configDir, codeName) {
|
|
19286
|
-
return
|
|
19428
|
+
return join38(memoryRetirementDir(configDir, codeName), "retired");
|
|
19287
19429
|
}
|
|
19288
19430
|
var RETIRED_MEMORY_TTL_MS = 30 * 24 * 60 * 60 * 1e3;
|
|
19289
19431
|
var lastRetirementReport = /* @__PURE__ */ new Map();
|
|
@@ -19361,8 +19503,8 @@ function applyMemoryTombstones(opts) {
|
|
|
19361
19503
|
log2(`[memory-retire] ${agent.code_name}: KEPT '${tomb.name}' \u2014 no write record, not ours to remove`);
|
|
19362
19504
|
continue;
|
|
19363
19505
|
}
|
|
19364
|
-
const filePath =
|
|
19365
|
-
if (!
|
|
19506
|
+
const filePath = join38(memoryDir, entry.file);
|
|
19507
|
+
if (!existsSync17(filePath)) {
|
|
19366
19508
|
outcomes.already_gone++;
|
|
19367
19509
|
delete manifest[tomb.name];
|
|
19368
19510
|
manifestDirty = true;
|
|
@@ -19381,9 +19523,9 @@ function applyMemoryTombstones(opts) {
|
|
|
19381
19523
|
const destDir = retiredMemoryDir(configDir, agent.code_name);
|
|
19382
19524
|
mkdirSync11(destDir, { recursive: true });
|
|
19383
19525
|
const stamp = Date.now();
|
|
19384
|
-
let dest =
|
|
19385
|
-
for (let n = 1;
|
|
19386
|
-
dest =
|
|
19526
|
+
let dest = join38(destDir, `${entry.file}.${stamp}.retired`);
|
|
19527
|
+
for (let n = 1; existsSync17(dest); n++) {
|
|
19528
|
+
dest = join38(destDir, `${entry.file}.${stamp}-${n}.retired`);
|
|
19387
19529
|
}
|
|
19388
19530
|
renameSync8(filePath, dest);
|
|
19389
19531
|
try {
|
|
@@ -19416,13 +19558,13 @@ function applyMemoryTombstones(opts) {
|
|
|
19416
19558
|
}
|
|
19417
19559
|
function reapRetiredMemories(configDir, codeName, log2) {
|
|
19418
19560
|
const dir = retiredMemoryDir(configDir, codeName);
|
|
19419
|
-
if (!
|
|
19561
|
+
if (!existsSync17(dir)) return;
|
|
19420
19562
|
const cutoff = Date.now() - RETIRED_MEMORY_TTL_MS;
|
|
19421
19563
|
let reaped = 0;
|
|
19422
19564
|
try {
|
|
19423
|
-
for (const file of
|
|
19565
|
+
for (const file of readdirSync10(dir)) {
|
|
19424
19566
|
if (!file.endsWith(".retired")) continue;
|
|
19425
|
-
const path =
|
|
19567
|
+
const path = join38(dir, file);
|
|
19426
19568
|
try {
|
|
19427
19569
|
if (statSync8(path).mtimeMs < cutoff) {
|
|
19428
19570
|
unlinkSync6(path);
|
|
@@ -19437,8 +19579,8 @@ function reapRetiredMemories(configDir, codeName, log2) {
|
|
|
19437
19579
|
if (reaped > 0) log2(`[memory-retire] ${codeName}: reaped ${reaped} retired memory file(s) past TTL`);
|
|
19438
19580
|
}
|
|
19439
19581
|
async function syncMemories(agent, configDir, log2) {
|
|
19440
|
-
const projectDir =
|
|
19441
|
-
const memoryDir =
|
|
19582
|
+
const projectDir = join38(configDir, agent.code_name, "project");
|
|
19583
|
+
const memoryDir = join38(projectDir, "memory");
|
|
19442
19584
|
const isFreshSync = pendingFreshMemorySync.has(agent.agent_id);
|
|
19443
19585
|
if (isFreshSync) {
|
|
19444
19586
|
log2(`[memory-sync] Fresh-sync requested for '${agent.code_name}' \u2014 pulling DB first`);
|
|
@@ -19462,14 +19604,14 @@ async function syncMemories(agent, configDir, log2) {
|
|
|
19462
19604
|
}
|
|
19463
19605
|
pendingFreshMemorySync.delete(agent.agent_id);
|
|
19464
19606
|
}
|
|
19465
|
-
if (
|
|
19607
|
+
if (existsSync17(memoryDir)) {
|
|
19466
19608
|
const prevHashes = memoryFileHashes.get(agent.agent_id) ?? /* @__PURE__ */ new Map();
|
|
19467
19609
|
const currentHashes = /* @__PURE__ */ new Map();
|
|
19468
19610
|
const changedMemories = [];
|
|
19469
|
-
for (const file of
|
|
19611
|
+
for (const file of readdirSync10(memoryDir)) {
|
|
19470
19612
|
if (!file.endsWith(".md")) continue;
|
|
19471
19613
|
try {
|
|
19472
|
-
const raw = readFileSync29(
|
|
19614
|
+
const raw = readFileSync29(join38(memoryDir, file), "utf-8");
|
|
19473
19615
|
const fileHash = createHash17("sha256").update(raw).digest("hex").slice(0, 16);
|
|
19474
19616
|
currentHashes.set(file, fileHash);
|
|
19475
19617
|
if (prevHashes.get(file) === fileHash) continue;
|
|
@@ -19494,7 +19636,7 @@ async function syncMemories(agent, configDir, log2) {
|
|
|
19494
19636
|
} catch (err) {
|
|
19495
19637
|
for (const mem of changedMemories) {
|
|
19496
19638
|
for (const [file] of currentHashes) {
|
|
19497
|
-
const parsed = parseMemoryFile(readFileSync29(
|
|
19639
|
+
const parsed = parseMemoryFile(readFileSync29(join38(memoryDir, file), "utf-8"), file.replace(/\.md$/, ""));
|
|
19498
19640
|
if (parsed?.name === mem.name) currentHashes.delete(file);
|
|
19499
19641
|
}
|
|
19500
19642
|
}
|
|
@@ -19520,7 +19662,7 @@ async function syncMemories(agent, configDir, log2) {
|
|
|
19520
19662
|
}
|
|
19521
19663
|
}
|
|
19522
19664
|
async function downloadMemories(agent, memoryDir, log2, { force, configDir }) {
|
|
19523
|
-
const localFiles =
|
|
19665
|
+
const localFiles = existsSync17(memoryDir) ? readdirSync10(memoryDir).filter((f) => f.endsWith(".md")).sort() : [];
|
|
19524
19666
|
const localListHash = createHash17("sha256").update(localFiles.join(",")).digest("hex").slice(0, 16);
|
|
19525
19667
|
const prevLocalHash = lastLocalFileHash.get(agent.agent_id);
|
|
19526
19668
|
const prevDownload = lastDownloadHash.get(agent.agent_id);
|
|
@@ -19545,7 +19687,7 @@ async function downloadMemories(agent, memoryDir, log2, { force, configDir }) {
|
|
|
19545
19687
|
const rawSlug = mem.name.toLowerCase().replace(/[^a-z0-9]+/g, "-").replace(/(^-|-$)/g, "").slice(0, 60);
|
|
19546
19688
|
const slug = rawSlug || `memory-${i}`;
|
|
19547
19689
|
const fileName = `${slug}.md`;
|
|
19548
|
-
const filePath =
|
|
19690
|
+
const filePath = join38(memoryDir, fileName);
|
|
19549
19691
|
const desired = `---
|
|
19550
19692
|
name: ${JSON.stringify(mem.name)}
|
|
19551
19693
|
type: ${mem.type}
|
|
@@ -19562,7 +19704,7 @@ ${mem.content}
|
|
|
19562
19704
|
return true;
|
|
19563
19705
|
};
|
|
19564
19706
|
let manifestDirty = false;
|
|
19565
|
-
if (
|
|
19707
|
+
if (existsSync17(filePath)) {
|
|
19566
19708
|
let existing = "";
|
|
19567
19709
|
try {
|
|
19568
19710
|
existing = readFileSync29(filePath, "utf-8");
|
|
@@ -19583,7 +19725,7 @@ ${mem.content}
|
|
|
19583
19725
|
if (manifestDirty) saveMemoryManifest(agent.agent_id, configDir, agent.code_name);
|
|
19584
19726
|
}
|
|
19585
19727
|
if (written > 0 || overwritten > 0) {
|
|
19586
|
-
const updatedFiles =
|
|
19728
|
+
const updatedFiles = readdirSync10(memoryDir).filter((f) => f.endsWith(".md")).sort();
|
|
19587
19729
|
lastLocalFileHash.set(agent.agent_id, createHash17("sha256").update(updatedFiles.join(",")).digest("hex").slice(0, 16));
|
|
19588
19730
|
log2(`Memory download for '${agent.code_name}': wrote ${written} new, overwrote ${overwritten} stale`);
|
|
19589
19731
|
}
|
|
@@ -19595,7 +19737,7 @@ ${mem.content}
|
|
|
19595
19737
|
}
|
|
19596
19738
|
}
|
|
19597
19739
|
async function cleanupAgentFiles(codeName, agentDir) {
|
|
19598
|
-
if (
|
|
19740
|
+
if (existsSync17(agentDir)) {
|
|
19599
19741
|
try {
|
|
19600
19742
|
rmSync5(agentDir, { recursive: true, force: true });
|
|
19601
19743
|
log(`Removed provision directory for '${codeName}'`);
|
|
@@ -19619,8 +19761,8 @@ var caffeinateProc = null;
|
|
|
19619
19761
|
async function startCaffeinate() {
|
|
19620
19762
|
if (process.platform !== "darwin") return;
|
|
19621
19763
|
try {
|
|
19622
|
-
const { spawn } = await import("child_process");
|
|
19623
|
-
caffeinateProc =
|
|
19764
|
+
const { spawn: spawn2 } = await import("child_process");
|
|
19765
|
+
caffeinateProc = spawn2("caffeinate", ["-dims"], {
|
|
19624
19766
|
stdio: "ignore",
|
|
19625
19767
|
detached: false
|
|
19626
19768
|
});
|
|
@@ -19864,7 +20006,7 @@ function startManager(opts) {
|
|
|
19864
20006
|
config = opts;
|
|
19865
20007
|
try {
|
|
19866
20008
|
const stateFile = getStateFile();
|
|
19867
|
-
if (
|
|
20009
|
+
if (existsSync17(stateFile)) {
|
|
19868
20010
|
const raw = readFileSync29(stateFile, "utf-8");
|
|
19869
20011
|
const parsed = JSON.parse(raw);
|
|
19870
20012
|
if (Array.isArray(parsed.agents)) {
|
|
@@ -19892,7 +20034,7 @@ function startManager(opts) {
|
|
|
19892
20034
|
log(`[startup] state rehydration failed (continuing with empty state): ${err.message}`);
|
|
19893
20035
|
}
|
|
19894
20036
|
log(
|
|
19895
|
-
`[startup] worker pid=${process.pid} ppid=${process.ppid} node=${process.version} log=${
|
|
20037
|
+
`[startup] worker pid=${process.pid} ppid=${process.ppid} node=${process.version} log=${join38(homedir18(), ".augmented", "manager.log")}`
|
|
19896
20038
|
);
|
|
19897
20039
|
deployMcpAssets();
|
|
19898
20040
|
reapOrphanChannelMcps({ log });
|
|
@@ -19939,16 +20081,16 @@ async function reapOrphanedClaudePids() {
|
|
|
19939
20081
|
},
|
|
19940
20082
|
looksLikeClaude
|
|
19941
20083
|
);
|
|
19942
|
-
for (const
|
|
20084
|
+
for (const spawn2 of decision.toKill) {
|
|
19943
20085
|
try {
|
|
19944
|
-
process.kill(
|
|
20086
|
+
process.kill(spawn2.pid, "SIGKILL");
|
|
19945
20087
|
} catch (err) {
|
|
19946
|
-
log(`[drain] reaper SIGKILL pid=${
|
|
20088
|
+
log(`[drain] reaper SIGKILL pid=${spawn2.pid} failed: ${err.message}`);
|
|
19947
20089
|
}
|
|
19948
20090
|
}
|
|
19949
|
-
for (const
|
|
20091
|
+
for (const spawn2 of decision.pidReusedSkipped) {
|
|
19950
20092
|
log(
|
|
19951
|
-
`[drain] reaper skipped pid=${
|
|
20093
|
+
`[drain] reaper skipped pid=${spawn2.pid} \u2014 PID reuse suspected (identity probe rejected)`
|
|
19952
20094
|
);
|
|
19953
20095
|
}
|
|
19954
20096
|
log(formatReaperBootLine({
|
|
@@ -20018,14 +20160,14 @@ function restartRunningChannelMcps(basenames) {
|
|
|
20018
20160
|
}
|
|
20019
20161
|
}
|
|
20020
20162
|
function deployMcpAssets() {
|
|
20021
|
-
const targetDir =
|
|
20163
|
+
const targetDir = join38(homedir18(), ".augmented", "_mcp");
|
|
20022
20164
|
mkdirSync11(targetDir, { recursive: true });
|
|
20023
20165
|
const moduleDir = dirname10(fileURLToPath(import.meta.url));
|
|
20024
20166
|
let mcpSourceDir = "";
|
|
20025
20167
|
let dir = moduleDir;
|
|
20026
20168
|
for (let i = 0; i < 6; i++) {
|
|
20027
|
-
const candidate =
|
|
20028
|
-
if (
|
|
20169
|
+
const candidate = join38(dir, "dist", "mcp");
|
|
20170
|
+
if (existsSync17(join38(candidate, "index.js"))) {
|
|
20029
20171
|
mcpSourceDir = candidate;
|
|
20030
20172
|
break;
|
|
20031
20173
|
}
|
|
@@ -20042,7 +20184,7 @@ function deployMcpAssets() {
|
|
|
20042
20184
|
const failedFiles = [];
|
|
20043
20185
|
const fileHash = (p) => {
|
|
20044
20186
|
try {
|
|
20045
|
-
if (!
|
|
20187
|
+
if (!existsSync17(p)) return null;
|
|
20046
20188
|
return createHash17("sha256").update(readFileSync29(p)).digest("hex");
|
|
20047
20189
|
} catch {
|
|
20048
20190
|
return null;
|
|
@@ -20114,9 +20256,9 @@ function deployMcpAssets() {
|
|
|
20114
20256
|
// needs restarting to pick up a token rotation.
|
|
20115
20257
|
"xero.js"
|
|
20116
20258
|
]) {
|
|
20117
|
-
const src =
|
|
20118
|
-
const dst =
|
|
20119
|
-
if (!
|
|
20259
|
+
const src = join38(mcpSourceDir, file);
|
|
20260
|
+
const dst = join38(targetDir, file);
|
|
20261
|
+
if (!existsSync17(src)) continue;
|
|
20120
20262
|
attemptedFiles.push(file);
|
|
20121
20263
|
const before = fileHash(dst);
|
|
20122
20264
|
try {
|
|
@@ -20141,14 +20283,14 @@ function deployMcpAssets() {
|
|
|
20141
20283
|
log(`[manager] Bundle(s) updated: ${changedBasenames.join(", ")} \u2014 signalling running instances to restart`);
|
|
20142
20284
|
restartRunningChannelMcps(changedBasenames);
|
|
20143
20285
|
}
|
|
20144
|
-
const localMcpPath =
|
|
20286
|
+
const localMcpPath = join38(targetDir, "index.js");
|
|
20145
20287
|
try {
|
|
20146
|
-
const agentsDir =
|
|
20147
|
-
if (
|
|
20148
|
-
for (const entry of
|
|
20288
|
+
const agentsDir = join38(homedir18(), ".augmented", "agents");
|
|
20289
|
+
if (existsSync17(agentsDir)) {
|
|
20290
|
+
for (const entry of readdirSync10(agentsDir, { withFileTypes: true })) {
|
|
20149
20291
|
if (!entry.isDirectory()) continue;
|
|
20150
20292
|
for (const subdir of ["provision", "project"]) {
|
|
20151
|
-
const mcpJsonPath =
|
|
20293
|
+
const mcpJsonPath = join38(agentsDir, entry.name, subdir, ".mcp.json");
|
|
20152
20294
|
try {
|
|
20153
20295
|
const raw = readFileSync29(mcpJsonPath, "utf-8");
|
|
20154
20296
|
if (!raw.includes("@integrity-labs/augmented-mcp")) continue;
|