@integrity-labs/agt-cli 0.28.438 → 0.28.439
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.
|
@@ -42,7 +42,7 @@ import {
|
|
|
42
42
|
resolveEffectivePinRaw,
|
|
43
43
|
safeWriteJsonAtomic,
|
|
44
44
|
setConfigHash
|
|
45
|
-
} from "../chunk-
|
|
45
|
+
} from "../chunk-CM7DWCO4.js";
|
|
46
46
|
import {
|
|
47
47
|
getProjectDir as getProjectDir2,
|
|
48
48
|
getReadyTasks,
|
|
@@ -162,9 +162,9 @@ import {
|
|
|
162
162
|
|
|
163
163
|
// src/lib/manager-worker.ts
|
|
164
164
|
import { createHash as createHash16 } from "crypto";
|
|
165
|
-
import { readFileSync as
|
|
165
|
+
import { readFileSync as readFileSync21, writeFileSync as writeFileSync12, mkdirSync as mkdirSync10, existsSync as existsSync11, rmSync as rmSync5, readdirSync as readdirSync7, statSync as statSync6, copyFileSync } from "fs";
|
|
166
166
|
import { execFileSync as syncExecFile } from "child_process";
|
|
167
|
-
import { join as
|
|
167
|
+
import { join as join25, dirname as dirname8, delimiter as pathDelimiter } from "path";
|
|
168
168
|
import { homedir as homedir11 } from "os";
|
|
169
169
|
import { fileURLToPath } from "url";
|
|
170
170
|
|
|
@@ -2051,12 +2051,100 @@ var nodeArtifactFs = {
|
|
|
2051
2051
|
}
|
|
2052
2052
|
};
|
|
2053
2053
|
|
|
2054
|
+
// src/lib/agent-serving-probe.ts
|
|
2055
|
+
import { readFileSync as readFileSync7, readdirSync, statSync } from "fs";
|
|
2056
|
+
import { join as join6 } from "path";
|
|
2057
|
+
var RATE_LIMIT_WINDOW_MS = 15 * 60 * 1e3;
|
|
2058
|
+
function classifyLine(line, startMs, endMs) {
|
|
2059
|
+
const trimmed = line.trim();
|
|
2060
|
+
if (!trimmed) return null;
|
|
2061
|
+
let obj;
|
|
2062
|
+
try {
|
|
2063
|
+
obj = JSON.parse(trimmed);
|
|
2064
|
+
} catch {
|
|
2065
|
+
return null;
|
|
2066
|
+
}
|
|
2067
|
+
if (typeof obj !== "object" || obj === null) return null;
|
|
2068
|
+
const record = obj;
|
|
2069
|
+
if (record.type !== "assistant") return null;
|
|
2070
|
+
const ts = record.timestamp;
|
|
2071
|
+
if (typeof ts !== "string" || !ts) return null;
|
|
2072
|
+
const tsMs = new Date(ts).getTime();
|
|
2073
|
+
if (!Number.isFinite(tsMs) || tsMs < startMs || tsMs > endMs) return null;
|
|
2074
|
+
if (record.error === "rate_limit" || record.apiErrorStatus === 429) {
|
|
2075
|
+
return { tsMs, verdict: "capped" };
|
|
2076
|
+
}
|
|
2077
|
+
if (record.isApiErrorMessage === true) return null;
|
|
2078
|
+
const message = record.message;
|
|
2079
|
+
if (typeof message !== "object" || message === null) return null;
|
|
2080
|
+
const msg = message;
|
|
2081
|
+
if (msg.model === "<synthetic>") return null;
|
|
2082
|
+
const usage = msg.usage;
|
|
2083
|
+
if (typeof usage !== "object" || usage === null) return null;
|
|
2084
|
+
const u = usage;
|
|
2085
|
+
const spent = Number(u.input_tokens ?? 0) + Number(u.output_tokens ?? 0) + Number(u.cache_creation_input_tokens ?? 0) + Number(u.cache_read_input_tokens ?? 0);
|
|
2086
|
+
if (!Number.isFinite(spent) || spent <= 0) return null;
|
|
2087
|
+
return { tsMs, verdict: "serving" };
|
|
2088
|
+
}
|
|
2089
|
+
function probeRateLimitState(args) {
|
|
2090
|
+
const now = args.now ?? /* @__PURE__ */ new Date();
|
|
2091
|
+
const endMs = now.getTime();
|
|
2092
|
+
const startMs = endMs - (args.windowMs ?? RATE_LIMIT_WINDOW_MS);
|
|
2093
|
+
const dir = args.transcriptDir ?? sessionTranscriptDir(args.projectDir);
|
|
2094
|
+
let entries;
|
|
2095
|
+
try {
|
|
2096
|
+
entries = readdirSync(dir);
|
|
2097
|
+
} catch {
|
|
2098
|
+
return "unknown";
|
|
2099
|
+
}
|
|
2100
|
+
let newest = null;
|
|
2101
|
+
for (const name of entries) {
|
|
2102
|
+
if (!name.endsWith(".jsonl")) continue;
|
|
2103
|
+
const path = join6(dir, name);
|
|
2104
|
+
try {
|
|
2105
|
+
const st = statSync(path);
|
|
2106
|
+
if (!st.isFile() || st.mtimeMs < startMs) continue;
|
|
2107
|
+
} catch {
|
|
2108
|
+
continue;
|
|
2109
|
+
}
|
|
2110
|
+
let content;
|
|
2111
|
+
try {
|
|
2112
|
+
content = readFileSync7(path, "utf-8");
|
|
2113
|
+
} catch {
|
|
2114
|
+
continue;
|
|
2115
|
+
}
|
|
2116
|
+
for (const line of content.split("\n")) {
|
|
2117
|
+
const c = classifyLine(line, startMs, endMs);
|
|
2118
|
+
if (c && (newest === null || c.tsMs >= newest.tsMs)) newest = c;
|
|
2119
|
+
}
|
|
2120
|
+
}
|
|
2121
|
+
return newest?.verdict ?? "unknown";
|
|
2122
|
+
}
|
|
2123
|
+
|
|
2054
2124
|
// src/lib/usage-banner-monitor.ts
|
|
2055
2125
|
function syncUsageLimitMarker(args) {
|
|
2056
2126
|
if (args.pct < 100) {
|
|
2057
2127
|
clearUsageLimitMarker(args.codeName, args.log);
|
|
2058
2128
|
return;
|
|
2059
2129
|
}
|
|
2130
|
+
const verdict = args.verdict ?? probeRateLimitState({
|
|
2131
|
+
codeName: args.codeName,
|
|
2132
|
+
projectDir: getProjectDir(args.codeName),
|
|
2133
|
+
now: args.now
|
|
2134
|
+
});
|
|
2135
|
+
if (verdict === "serving") {
|
|
2136
|
+
args.log(
|
|
2137
|
+
`[usage-banner] saturated banner for '${args.codeName}' NOT armed - a turn completed, so the agent is serving (ENG-8198)`
|
|
2138
|
+
);
|
|
2139
|
+
clearUsageLimitMarker(args.codeName, args.log);
|
|
2140
|
+
return;
|
|
2141
|
+
}
|
|
2142
|
+
if (verdict === "unknown") {
|
|
2143
|
+
args.log(
|
|
2144
|
+
`[usage-banner] saturated banner for '${args.codeName}' NOT armed - no classifiable turn in the transcript; leaving any existing marker untouched (ENG-8198)`
|
|
2145
|
+
);
|
|
2146
|
+
return;
|
|
2147
|
+
}
|
|
2060
2148
|
writeUsageLimitMarker(args.codeName, args.weekResetsAt, args.log);
|
|
2061
2149
|
}
|
|
2062
2150
|
var SPAWN_MARKER = /--- spawn \S+ \(session [^)]*\) ---/g;
|
|
@@ -2110,7 +2198,8 @@ async function maybeReportUsageBanner(args) {
|
|
|
2110
2198
|
codeName,
|
|
2111
2199
|
pct: observation.pct,
|
|
2112
2200
|
weekResetsAt: observation.weekResetsAt,
|
|
2113
|
-
log: log2
|
|
2201
|
+
log: log2,
|
|
2202
|
+
now
|
|
2114
2203
|
});
|
|
2115
2204
|
const observedAtIso = next.lastWeekResetsAt;
|
|
2116
2205
|
const weekResetsAtIso = observation.weekResetsAt.toISOString();
|
|
@@ -2138,12 +2227,12 @@ async function maybeReportUsageBanner(args) {
|
|
|
2138
2227
|
import { createHash as createHash6 } from "crypto";
|
|
2139
2228
|
import { readFile as readFile3, readdir as readdir3 } from "fs/promises";
|
|
2140
2229
|
import { homedir as homedir4, platform as platform2 } from "os";
|
|
2141
|
-
import { dirname as dirname4, join as
|
|
2230
|
+
import { dirname as dirname4, join as join8 } from "path";
|
|
2142
2231
|
|
|
2143
2232
|
// src/lib/claude-auth-detect.ts
|
|
2144
2233
|
import { readFile as readFile2, readdir as readdir2 } from "fs/promises";
|
|
2145
2234
|
import { homedir as homedir3, platform } from "os";
|
|
2146
|
-
import { join as
|
|
2235
|
+
import { join as join7 } from "path";
|
|
2147
2236
|
import { execFile } from "child_process";
|
|
2148
2237
|
import { promisify } from "util";
|
|
2149
2238
|
var execFileAsync = promisify(execFile);
|
|
@@ -2158,16 +2247,16 @@ async function detectClaudeAuth() {
|
|
|
2158
2247
|
}
|
|
2159
2248
|
async function findClaudeCredentialsPaths() {
|
|
2160
2249
|
const candidates = [
|
|
2161
|
-
|
|
2162
|
-
|
|
2250
|
+
join7(homedir3(), ".claude", ".credentials.json"),
|
|
2251
|
+
join7(homedir3(), ".claude", "credentials.json")
|
|
2163
2252
|
];
|
|
2164
2253
|
const isLinuxRoot = platform() === "linux" && typeof process.getuid === "function" && process.getuid() === 0;
|
|
2165
2254
|
if (isLinuxRoot) {
|
|
2166
2255
|
try {
|
|
2167
2256
|
const entries = await readdir2("/home", { withFileTypes: true });
|
|
2168
2257
|
for (const entry of entries.filter((entry2) => entry2.isDirectory()).sort((a, b) => a.name.localeCompare(b.name))) {
|
|
2169
|
-
candidates.push(
|
|
2170
|
-
candidates.push(
|
|
2258
|
+
candidates.push(join7("/home", entry.name, ".claude", ".credentials.json"));
|
|
2259
|
+
candidates.push(join7("/home", entry.name, ".claude", "credentials.json"));
|
|
2171
2260
|
}
|
|
2172
2261
|
} catch {
|
|
2173
2262
|
}
|
|
@@ -2251,7 +2340,7 @@ async function candidateHomes() {
|
|
|
2251
2340
|
try {
|
|
2252
2341
|
const entries = await readdir3("/home", { withFileTypes: true });
|
|
2253
2342
|
for (const entry of entries.filter((e) => e.isDirectory()).sort((a, b) => a.name.localeCompare(b.name))) {
|
|
2254
|
-
homes.push(
|
|
2343
|
+
homes.push(join8("/home", entry.name));
|
|
2255
2344
|
}
|
|
2256
2345
|
} catch {
|
|
2257
2346
|
}
|
|
@@ -2271,11 +2360,11 @@ async function homeOfActiveCredentials() {
|
|
|
2271
2360
|
async function claudeConfigCandidatePaths() {
|
|
2272
2361
|
const paths = [];
|
|
2273
2362
|
const configDir = process.env["CLAUDE_CONFIG_DIR"]?.trim();
|
|
2274
|
-
if (configDir) paths.push(
|
|
2363
|
+
if (configDir) paths.push(join8(configDir, ".claude.json"));
|
|
2275
2364
|
const activeHome = await homeOfActiveCredentials();
|
|
2276
|
-
if (activeHome) paths.push(
|
|
2365
|
+
if (activeHome) paths.push(join8(activeHome, ".claude.json"));
|
|
2277
2366
|
for (const home of await candidateHomes()) {
|
|
2278
|
-
const path =
|
|
2367
|
+
const path = join8(home, ".claude.json");
|
|
2279
2368
|
if (!paths.includes(path)) paths.push(path);
|
|
2280
2369
|
}
|
|
2281
2370
|
return paths;
|
|
@@ -2321,9 +2410,9 @@ async function getClaudeAccountFingerprint(paths, nowMs = Date.now()) {
|
|
|
2321
2410
|
// src/lib/account-enforcement-marker.ts
|
|
2322
2411
|
import { mkdirSync as mkdirSync4, renameSync, rmSync as rmSync2, writeFileSync as writeFileSync4 } from "fs";
|
|
2323
2412
|
import { homedir as homedir5 } from "os";
|
|
2324
|
-
import { join as
|
|
2413
|
+
import { join as join9 } from "path";
|
|
2325
2414
|
function accountEnforcementMarkerPath(codeName) {
|
|
2326
|
-
return
|
|
2415
|
+
return join9(homedir5(), ".augmented", codeName, ACCOUNT_ENFORCEMENT_MARKER_FILENAME);
|
|
2327
2416
|
}
|
|
2328
2417
|
function syncAccountEnforcementMarker(codeName, level, log2 = (m) => process.stderr.write(`${m}
|
|
2329
2418
|
`)) {
|
|
@@ -2331,8 +2420,8 @@ function syncAccountEnforcementMarker(codeName, level, log2 = (m) => process.std
|
|
|
2331
2420
|
clearAccountEnforcementMarker(codeName, log2);
|
|
2332
2421
|
return;
|
|
2333
2422
|
}
|
|
2334
|
-
const dir =
|
|
2335
|
-
const path =
|
|
2423
|
+
const dir = join9(homedir5(), ".augmented", codeName);
|
|
2424
|
+
const path = join9(dir, ACCOUNT_ENFORCEMENT_MARKER_FILENAME);
|
|
2336
2425
|
const tempPath = `${path}.${process.pid}.tmp`;
|
|
2337
2426
|
try {
|
|
2338
2427
|
mkdirSync4(dir, { recursive: true });
|
|
@@ -2357,8 +2446,8 @@ function clearAccountEnforcementMarker(codeName, log2 = (m) => process.stderr.wr
|
|
|
2357
2446
|
}
|
|
2358
2447
|
|
|
2359
2448
|
// src/lib/token-usage-monitor.ts
|
|
2360
|
-
import { readdirSync, readFileSync as
|
|
2361
|
-
import { join as
|
|
2449
|
+
import { readdirSync as readdirSync2, readFileSync as readFileSync8, statSync as statSync2 } from "fs";
|
|
2450
|
+
import { join as join10 } from "path";
|
|
2362
2451
|
var MIN_CHECK_INTERVAL_MS2 = 6e4;
|
|
2363
2452
|
var TRANSCRIPT_MTIME_WINDOW_MS = 2 * 24 * 60 * 60 * 1e3;
|
|
2364
2453
|
var MAX_ENTRIES_PER_POST = 200;
|
|
@@ -2376,7 +2465,7 @@ async function maybeReportTokenUsage(args) {
|
|
|
2376
2465
|
const next = { files, lastCheckedAt: nowMs };
|
|
2377
2466
|
let dirEntries;
|
|
2378
2467
|
try {
|
|
2379
|
-
dirEntries =
|
|
2468
|
+
dirEntries = readdirSync2(dir);
|
|
2380
2469
|
} catch {
|
|
2381
2470
|
state2.set(codeName, next);
|
|
2382
2471
|
return;
|
|
@@ -2387,10 +2476,10 @@ async function maybeReportTokenUsage(args) {
|
|
|
2387
2476
|
if (!name.endsWith(".jsonl")) continue;
|
|
2388
2477
|
const sessionId = name.slice(0, -".jsonl".length);
|
|
2389
2478
|
if (!sessionId) continue;
|
|
2390
|
-
const path =
|
|
2479
|
+
const path = join10(dir, name);
|
|
2391
2480
|
let st;
|
|
2392
2481
|
try {
|
|
2393
|
-
st =
|
|
2482
|
+
st = statSync2(path);
|
|
2394
2483
|
} catch {
|
|
2395
2484
|
continue;
|
|
2396
2485
|
}
|
|
@@ -2403,7 +2492,7 @@ async function maybeReportTokenUsage(args) {
|
|
|
2403
2492
|
}
|
|
2404
2493
|
let content;
|
|
2405
2494
|
try {
|
|
2406
|
-
content =
|
|
2495
|
+
content = readFileSync8(path, "utf-8");
|
|
2407
2496
|
} catch (err) {
|
|
2408
2497
|
log2(`[token-usage] read failed for '${codeName}/${name}': ${err.message}`);
|
|
2409
2498
|
continue;
|
|
@@ -2484,8 +2573,8 @@ async function maybeReportTokenUsage(args) {
|
|
|
2484
2573
|
}
|
|
2485
2574
|
|
|
2486
2575
|
// src/lib/workflow-run-reconciler.ts
|
|
2487
|
-
import { readdirSync as
|
|
2488
|
-
import { join as
|
|
2576
|
+
import { readdirSync as readdirSync3, readFileSync as readFileSync9, statSync as statSync3 } from "fs";
|
|
2577
|
+
import { join as join11 } from "path";
|
|
2489
2578
|
var MIN_CHECK_INTERVAL_MS3 = 5 * 6e4;
|
|
2490
2579
|
var SETTLE_MS = 3e4;
|
|
2491
2580
|
var TRANSCRIPT_MTIME_WINDOW_MS2 = 2 * 24 * 60 * 60 * 1e3;
|
|
@@ -2499,15 +2588,15 @@ function collectJsonlRecursive(dir, minMtimeMs, out, depth) {
|
|
|
2499
2588
|
if (depth > MAX_SUBAGENT_DEPTH) return;
|
|
2500
2589
|
let entries;
|
|
2501
2590
|
try {
|
|
2502
|
-
entries =
|
|
2591
|
+
entries = readdirSync3(dir);
|
|
2503
2592
|
} catch {
|
|
2504
2593
|
return;
|
|
2505
2594
|
}
|
|
2506
2595
|
for (const name of entries) {
|
|
2507
|
-
const p =
|
|
2596
|
+
const p = join11(dir, name);
|
|
2508
2597
|
let st;
|
|
2509
2598
|
try {
|
|
2510
|
-
st =
|
|
2599
|
+
st = statSync3(p);
|
|
2511
2600
|
} catch {
|
|
2512
2601
|
continue;
|
|
2513
2602
|
}
|
|
@@ -2522,15 +2611,15 @@ function enumerateTranscriptFiles(transcriptDir, nowMs, minMtimeMs = nowMs - TRA
|
|
|
2522
2611
|
const out = [];
|
|
2523
2612
|
let entries;
|
|
2524
2613
|
try {
|
|
2525
|
-
entries =
|
|
2614
|
+
entries = readdirSync3(transcriptDir);
|
|
2526
2615
|
} catch {
|
|
2527
2616
|
return out;
|
|
2528
2617
|
}
|
|
2529
2618
|
for (const name of entries) {
|
|
2530
|
-
const path =
|
|
2619
|
+
const path = join11(transcriptDir, name);
|
|
2531
2620
|
let st;
|
|
2532
2621
|
try {
|
|
2533
|
-
st =
|
|
2622
|
+
st = statSync3(path);
|
|
2534
2623
|
} catch {
|
|
2535
2624
|
continue;
|
|
2536
2625
|
}
|
|
@@ -2539,7 +2628,7 @@ function enumerateTranscriptFiles(transcriptDir, nowMs, minMtimeMs = nowMs - TRA
|
|
|
2539
2628
|
continue;
|
|
2540
2629
|
}
|
|
2541
2630
|
if (st.isDirectory()) {
|
|
2542
|
-
collectJsonlRecursive(
|
|
2631
|
+
collectJsonlRecursive(join11(path, "subagents"), minMtimeMs, out, 0);
|
|
2543
2632
|
}
|
|
2544
2633
|
}
|
|
2545
2634
|
return out;
|
|
@@ -2584,7 +2673,7 @@ async function maybeReconcileWorkflowRunTokens(args) {
|
|
|
2584
2673
|
const contents = [];
|
|
2585
2674
|
for (const path of files) {
|
|
2586
2675
|
try {
|
|
2587
|
-
contents.push(
|
|
2676
|
+
contents.push(readFileSync9(path, "utf-8"));
|
|
2588
2677
|
} catch {
|
|
2589
2678
|
}
|
|
2590
2679
|
}
|
|
@@ -2629,8 +2718,8 @@ async function maybeReconcileWorkflowRunTokens(args) {
|
|
|
2629
2718
|
}
|
|
2630
2719
|
|
|
2631
2720
|
// src/lib/conversation-evaluator.ts
|
|
2632
|
-
import { readdirSync as
|
|
2633
|
-
import { join as
|
|
2721
|
+
import { readdirSync as readdirSync4, readFileSync as readFileSync10, statSync as statSync4 } from "fs";
|
|
2722
|
+
import { join as join12 } from "path";
|
|
2634
2723
|
var MIN_CHECK_INTERVAL_MS4 = 5 * 6e4;
|
|
2635
2724
|
var TRANSCRIPT_MTIME_WINDOW_MS3 = 7 * 24 * 60 * 60 * 1e3;
|
|
2636
2725
|
var WINDOW_PAD_MS = 5 * 6e4;
|
|
@@ -3061,12 +3150,12 @@ function readRecentTurns(dir, nowMs) {
|
|
|
3061
3150
|
const visit = (d) => {
|
|
3062
3151
|
let entries;
|
|
3063
3152
|
try {
|
|
3064
|
-
entries =
|
|
3153
|
+
entries = readdirSync4(d, { withFileTypes: true });
|
|
3065
3154
|
} catch {
|
|
3066
3155
|
return;
|
|
3067
3156
|
}
|
|
3068
3157
|
for (const ent of entries) {
|
|
3069
|
-
const full =
|
|
3158
|
+
const full = join12(d, ent.name);
|
|
3070
3159
|
if (ent.isDirectory()) {
|
|
3071
3160
|
visit(full);
|
|
3072
3161
|
continue;
|
|
@@ -3074,14 +3163,14 @@ function readRecentTurns(dir, nowMs) {
|
|
|
3074
3163
|
if (!ent.isFile() || !ent.name.endsWith(".jsonl")) continue;
|
|
3075
3164
|
let mtimeMs;
|
|
3076
3165
|
try {
|
|
3077
|
-
mtimeMs =
|
|
3166
|
+
mtimeMs = statSync4(full).mtimeMs;
|
|
3078
3167
|
} catch {
|
|
3079
3168
|
continue;
|
|
3080
3169
|
}
|
|
3081
3170
|
if (nowMs - mtimeMs > TRANSCRIPT_MTIME_WINDOW_MS3) continue;
|
|
3082
3171
|
let content;
|
|
3083
3172
|
try {
|
|
3084
|
-
content =
|
|
3173
|
+
content = readFileSync10(full, "utf8");
|
|
3085
3174
|
} catch {
|
|
3086
3175
|
continue;
|
|
3087
3176
|
}
|
|
@@ -3371,11 +3460,11 @@ async function reportSkip2(api2, agentId, conversationId, log2, codeName) {
|
|
|
3371
3460
|
}
|
|
3372
3461
|
|
|
3373
3462
|
// src/lib/activity-cache-monitor.ts
|
|
3374
|
-
import { existsSync as existsSync2, readFileSync as
|
|
3463
|
+
import { existsSync as existsSync2, readFileSync as readFileSync11 } from "fs";
|
|
3375
3464
|
import { homedir as homedir6 } from "os";
|
|
3376
|
-
import { join as
|
|
3465
|
+
import { join as join13 } from "path";
|
|
3377
3466
|
var MIN_CHECK_INTERVAL_MS6 = 6e4;
|
|
3378
|
-
var STATS_CACHE_PATH =
|
|
3467
|
+
var STATS_CACHE_PATH = join13(homedir6(), ".claude", "stats-cache.json");
|
|
3379
3468
|
var ISO_DATE_RE = /^\d{4}-\d{2}-\d{2}$/;
|
|
3380
3469
|
var state5 = { lastObservedDate: null, lastCheckedAt: 0 };
|
|
3381
3470
|
function selectNewDailyRows(raw, lastObservedDate) {
|
|
@@ -3423,7 +3512,7 @@ async function maybeReportActivityCache(args) {
|
|
|
3423
3512
|
}
|
|
3424
3513
|
let raw;
|
|
3425
3514
|
try {
|
|
3426
|
-
raw =
|
|
3515
|
+
raw = readFileSync11(STATS_CACHE_PATH, "utf-8");
|
|
3427
3516
|
} catch (err) {
|
|
3428
3517
|
log2(`[activity-cache] readFileSync failed: ${err.message}`);
|
|
3429
3518
|
return;
|
|
@@ -3627,18 +3716,18 @@ function computeChannelConfigHash(input) {
|
|
|
3627
3716
|
}
|
|
3628
3717
|
|
|
3629
3718
|
// src/lib/channel-hash-cache.ts
|
|
3630
|
-
import { existsSync as existsSync3, readFileSync as
|
|
3631
|
-
import { join as
|
|
3719
|
+
import { existsSync as existsSync3, readFileSync as readFileSync12, writeFileSync as writeFileSync5 } from "fs";
|
|
3720
|
+
import { join as join14 } from "path";
|
|
3632
3721
|
var CACHE_FILENAME = "channel-hash-cache.json";
|
|
3633
3722
|
function getChannelHashCacheFile(configDir) {
|
|
3634
|
-
return
|
|
3723
|
+
return join14(configDir, CACHE_FILENAME);
|
|
3635
3724
|
}
|
|
3636
3725
|
function loadChannelHashCache(target, configDir) {
|
|
3637
3726
|
const path = getChannelHashCacheFile(configDir);
|
|
3638
3727
|
if (!existsSync3(path)) return;
|
|
3639
3728
|
let parsed;
|
|
3640
3729
|
try {
|
|
3641
|
-
parsed = JSON.parse(
|
|
3730
|
+
parsed = JSON.parse(readFileSync12(path, "utf-8"));
|
|
3642
3731
|
} catch {
|
|
3643
3732
|
return;
|
|
3644
3733
|
}
|
|
@@ -3658,8 +3747,8 @@ function saveChannelHashCache(source, configDir) {
|
|
|
3658
3747
|
}
|
|
3659
3748
|
|
|
3660
3749
|
// src/lib/sender-policy-baseline.ts
|
|
3661
|
-
import { existsSync as existsSync4, readFileSync as
|
|
3662
|
-
import { join as
|
|
3750
|
+
import { existsSync as existsSync4, readFileSync as readFileSync13 } from "fs";
|
|
3751
|
+
import { join as join15 } from "path";
|
|
3663
3752
|
var BASELINE_FILENAME = "sender-policy-baseline.json";
|
|
3664
3753
|
var SENDER_POLICY_BASELINE_VERSION = 1;
|
|
3665
3754
|
var BASELINE_CONCERNS = ["senderPolicy", "slackBehaviour", "msteamsBehaviour"];
|
|
@@ -3671,14 +3760,14 @@ function createDeliveryBaselineMaps() {
|
|
|
3671
3760
|
};
|
|
3672
3761
|
}
|
|
3673
3762
|
function getSenderPolicyBaselineFile(configDir) {
|
|
3674
|
-
return
|
|
3763
|
+
return join15(configDir, BASELINE_FILENAME);
|
|
3675
3764
|
}
|
|
3676
3765
|
function loadSenderPolicyBaseline(target, configDir, log2) {
|
|
3677
3766
|
const path = getSenderPolicyBaselineFile(configDir);
|
|
3678
3767
|
if (!existsSync4(path)) return;
|
|
3679
3768
|
let parsed;
|
|
3680
3769
|
try {
|
|
3681
|
-
parsed = JSON.parse(
|
|
3770
|
+
parsed = JSON.parse(readFileSync13(path, "utf-8"));
|
|
3682
3771
|
} catch (err) {
|
|
3683
3772
|
log2?.(
|
|
3684
3773
|
`[sender-policy] discarding corrupt ${BASELINE_FILENAME} (${err.message}) - restrictive-policy agents will take one fail-closed restart`
|
|
@@ -4201,16 +4290,16 @@ function planGlobalSkillSync(globalSkills, prevIds, hashOf, knownHash, options)
|
|
|
4201
4290
|
}
|
|
4202
4291
|
|
|
4203
4292
|
// src/lib/manager/managed-skill-manifest.ts
|
|
4204
|
-
import { existsSync as existsSync5, mkdirSync as mkdirSync5, readFileSync as
|
|
4205
|
-
import { dirname as dirname5, join as
|
|
4293
|
+
import { existsSync as existsSync5, mkdirSync as mkdirSync5, readFileSync as readFileSync14, writeFileSync as writeFileSync6 } from "fs";
|
|
4294
|
+
import { dirname as dirname5, join as join16 } from "path";
|
|
4206
4295
|
var MANIFEST_VERSION = 1;
|
|
4207
4296
|
function managedSkillManifestPath(agentRootDir) {
|
|
4208
|
-
return
|
|
4297
|
+
return join16(agentRootDir, "managed-skills.json");
|
|
4209
4298
|
}
|
|
4210
4299
|
function readManagedSkillManifest(path) {
|
|
4211
4300
|
try {
|
|
4212
4301
|
if (!existsSync5(path)) return /* @__PURE__ */ new Set();
|
|
4213
|
-
const parsed = JSON.parse(
|
|
4302
|
+
const parsed = JSON.parse(readFileSync14(path, "utf-8"));
|
|
4214
4303
|
const ids = Array.isArray(parsed?.globalSkillIds) ? parsed.globalSkillIds : [];
|
|
4215
4304
|
return new Set(ids.filter((id) => typeof id === "string" && id.length > 0));
|
|
4216
4305
|
} catch {
|
|
@@ -4323,7 +4412,7 @@ function resolveModelChain(refreshData) {
|
|
|
4323
4412
|
|
|
4324
4413
|
// src/lib/manager/claude-auth.ts
|
|
4325
4414
|
import { existsSync as existsSync6, rmSync as rmSync3 } from "fs";
|
|
4326
|
-
import { join as
|
|
4415
|
+
import { join as join17 } from "path";
|
|
4327
4416
|
import { homedir as homedir7 } from "os";
|
|
4328
4417
|
async function applyClaudeAuthToEnv(childEnv, label) {
|
|
4329
4418
|
const apiKey = getApiKey();
|
|
@@ -4336,9 +4425,9 @@ async function applyClaudeAuthToEnv(childEnv, label) {
|
|
|
4336
4425
|
throw new Error("claude_auth_mode=api_key but /host/exchange returned no decrypted key");
|
|
4337
4426
|
}
|
|
4338
4427
|
childEnv.ANTHROPIC_API_KEY = exchange.anthropicApiKey;
|
|
4339
|
-
const claudeDir =
|
|
4428
|
+
const claudeDir = join17(homedir7(), ".claude");
|
|
4340
4429
|
for (const filename of [".credentials.json", "credentials.json"]) {
|
|
4341
|
-
const p =
|
|
4430
|
+
const p = join17(claudeDir, filename);
|
|
4342
4431
|
if (existsSync6(p)) {
|
|
4343
4432
|
try {
|
|
4344
4433
|
rmSync3(p, { force: true });
|
|
@@ -4353,8 +4442,8 @@ async function applyClaudeAuthToEnv(childEnv, label) {
|
|
|
4353
4442
|
}
|
|
4354
4443
|
|
|
4355
4444
|
// src/lib/manager/kanban/parsers.ts
|
|
4356
|
-
import { existsSync as existsSync7, readFileSync as
|
|
4357
|
-
import { join as
|
|
4445
|
+
import { existsSync as existsSync7, readFileSync as readFileSync15 } from "fs";
|
|
4446
|
+
import { join as join18 } from "path";
|
|
4358
4447
|
var STANDUP_TEMPLATES = /* @__PURE__ */ new Set(["daily-standup", "end-of-day-summary"]);
|
|
4359
4448
|
var TASK_UPDATE_TEMPLATES = /* @__PURE__ */ new Set(["hourly-status", "task-update"]);
|
|
4360
4449
|
var PLAN_TEMPLATES = /* @__PURE__ */ new Set(["morning-plan"]);
|
|
@@ -4493,12 +4582,12 @@ function getBuiltInSkillContent(skillId) {
|
|
|
4493
4582
|
if (builtInSkillCache.has(skillId)) return builtInSkillCache.get(skillId);
|
|
4494
4583
|
try {
|
|
4495
4584
|
const candidates = [
|
|
4496
|
-
|
|
4497
|
-
|
|
4585
|
+
join18(process.cwd(), "skills", skillId, "SKILL.md"),
|
|
4586
|
+
join18(new URL(".", import.meta.url).pathname, "..", "..", "..", "..", "..", "..", "skills", skillId, "SKILL.md")
|
|
4498
4587
|
];
|
|
4499
4588
|
for (const candidate of candidates) {
|
|
4500
4589
|
if (existsSync7(candidate)) {
|
|
4501
|
-
const content =
|
|
4590
|
+
const content = readFileSync15(candidate, "utf-8");
|
|
4502
4591
|
const files = [{ relativePath: "SKILL.md", content }];
|
|
4503
4592
|
builtInSkillCache.set(skillId, files);
|
|
4504
4593
|
return files;
|
|
@@ -4639,19 +4728,19 @@ function formatBoardForPrompt(items, template) {
|
|
|
4639
4728
|
}
|
|
4640
4729
|
|
|
4641
4730
|
// src/lib/manager/kanban/nudge-state-cache.ts
|
|
4642
|
-
import { existsSync as existsSync8, readFileSync as
|
|
4643
|
-
import { join as
|
|
4731
|
+
import { existsSync as existsSync8, readFileSync as readFileSync16, writeFileSync as writeFileSync7 } from "fs";
|
|
4732
|
+
import { join as join19 } from "path";
|
|
4644
4733
|
var CACHE_FILENAME2 = "kanban-nudge-state.json";
|
|
4645
4734
|
var KANBAN_NUDGE_STATE_VERSION = 1;
|
|
4646
4735
|
function getKanbanNudgeStateFile(configDir) {
|
|
4647
|
-
return
|
|
4736
|
+
return join19(configDir, CACHE_FILENAME2);
|
|
4648
4737
|
}
|
|
4649
4738
|
function loadKanbanNudgeState(target, configDir) {
|
|
4650
4739
|
const path = getKanbanNudgeStateFile(configDir);
|
|
4651
4740
|
if (!existsSync8(path)) return;
|
|
4652
4741
|
let parsed;
|
|
4653
4742
|
try {
|
|
4654
|
-
parsed = JSON.parse(
|
|
4743
|
+
parsed = JSON.parse(readFileSync16(path, "utf-8"));
|
|
4655
4744
|
} catch {
|
|
4656
4745
|
return;
|
|
4657
4746
|
}
|
|
@@ -5217,9 +5306,9 @@ function closeScheduledRunsForCode(codeName, outcome, reason) {
|
|
|
5217
5306
|
|
|
5218
5307
|
// src/lib/manager/scheduler/kanban-route.ts
|
|
5219
5308
|
import { createHash as createHash11 } from "crypto";
|
|
5220
|
-
import { writeFileSync as writeFileSync8, renameSync as renameSync2, mkdirSync as mkdirSync6, readFileSync as
|
|
5309
|
+
import { writeFileSync as writeFileSync8, renameSync as renameSync2, mkdirSync as mkdirSync6, readFileSync as readFileSync17, unlinkSync } from "fs";
|
|
5221
5310
|
import { homedir as homedir8 } from "os";
|
|
5222
|
-
import { join as
|
|
5311
|
+
import { join as join20, dirname as dirname6 } from "path";
|
|
5223
5312
|
|
|
5224
5313
|
// src/lib/manager/scheduler/notify.ts
|
|
5225
5314
|
import { createHash as createHash10 } from "crypto";
|
|
@@ -5559,7 +5648,7 @@ function resolveScheduledSlackTarget(task) {
|
|
|
5559
5648
|
}
|
|
5560
5649
|
function stampScheduledTurnMarker(codeName, taskId, target) {
|
|
5561
5650
|
try {
|
|
5562
|
-
const file =
|
|
5651
|
+
const file = join20(homedir8(), ".augmented", codeName, SCHEDULED_TURN_MARKER_FILENAME);
|
|
5563
5652
|
const marker = { ts: Date.now(), task_id: taskId, ...target ? { target } : {} };
|
|
5564
5653
|
const tmp = `${file}.tmp`;
|
|
5565
5654
|
writeFileSync8(tmp, JSON.stringify(marker), "utf8");
|
|
@@ -5569,9 +5658,9 @@ function stampScheduledTurnMarker(codeName, taskId, target) {
|
|
|
5569
5658
|
}
|
|
5570
5659
|
}
|
|
5571
5660
|
function clearScheduledTurnMarkerForTask(codeName, taskId) {
|
|
5572
|
-
const file =
|
|
5661
|
+
const file = join20(homedir8(), ".augmented", codeName, SCHEDULED_TURN_MARKER_FILENAME);
|
|
5573
5662
|
try {
|
|
5574
|
-
const raw = JSON.parse(
|
|
5663
|
+
const raw = JSON.parse(readFileSync17(file, "utf8"));
|
|
5575
5664
|
if (typeof raw?.task_id !== "string" || raw.task_id !== taskId) return;
|
|
5576
5665
|
unlinkSync(file);
|
|
5577
5666
|
log(`[scheduled-kanban] scheduled-turn marker cleared for '${codeName}' (task ${taskId} complete)`);
|
|
@@ -5778,9 +5867,9 @@ async function processClaudeTaskResult(codeName, agentId, templateId, rawOutput,
|
|
|
5778
5867
|
// src/lib/manager/scheduler/execution.ts
|
|
5779
5868
|
import { createHash as createHash12 } from "crypto";
|
|
5780
5869
|
import { homedir as homedir9 } from "os";
|
|
5781
|
-
import { join as
|
|
5870
|
+
import { join as join21 } from "path";
|
|
5782
5871
|
function claudePidFilePath() {
|
|
5783
|
-
return
|
|
5872
|
+
return join21(homedir9(), ".augmented", "manager-claude-pids.json");
|
|
5784
5873
|
}
|
|
5785
5874
|
var inFlightClaudePids = /* @__PURE__ */ new Map();
|
|
5786
5875
|
function registerClaudeSpawn(record) {
|
|
@@ -5841,14 +5930,14 @@ async function syncAndCheckClaudeScheduler(agent, tasks, boardItems, refreshData
|
|
|
5841
5930
|
}
|
|
5842
5931
|
|
|
5843
5932
|
// src/lib/pane-occupancy-sampler.ts
|
|
5844
|
-
import { statSync as
|
|
5933
|
+
import { statSync as statSync5 } from "fs";
|
|
5845
5934
|
var SAMPLE_INTERVAL_MS = 1e4;
|
|
5846
5935
|
var IDLE_GAP_MS = 12e4;
|
|
5847
5936
|
var POST_IDLE_CREDIT_MS = 6e4;
|
|
5848
5937
|
var lastMtimeMs = /* @__PURE__ */ new Map();
|
|
5849
5938
|
function paneMtimeMs(codeName) {
|
|
5850
5939
|
try {
|
|
5851
|
-
return
|
|
5940
|
+
return statSync5(paneLogPath(codeName)).mtimeMs;
|
|
5852
5941
|
} catch {
|
|
5853
5942
|
return null;
|
|
5854
5943
|
}
|
|
@@ -7004,9 +7093,9 @@ async function fireOpencodeScheduledTask(agent, task) {
|
|
|
7004
7093
|
|
|
7005
7094
|
// src/lib/opencode-telegram-ingest.ts
|
|
7006
7095
|
import { createHash as createHash15 } from "crypto";
|
|
7007
|
-
import { existsSync as existsSync9, mkdirSync as mkdirSync7, readFileSync as
|
|
7096
|
+
import { existsSync as existsSync9, mkdirSync as mkdirSync7, readFileSync as readFileSync18, renameSync as renameSync3, unlinkSync as unlinkSync2, writeFileSync as writeFileSync9 } from "fs";
|
|
7008
7097
|
import { randomUUID } from "crypto";
|
|
7009
|
-
import { join as
|
|
7098
|
+
import { join as join22 } from "path";
|
|
7010
7099
|
|
|
7011
7100
|
// src/lib/telegram-ingest.ts
|
|
7012
7101
|
import https2 from "https";
|
|
@@ -7554,7 +7643,7 @@ function createFileOffsetStore(codeName, log2, currentBotId) {
|
|
|
7554
7643
|
let filePath;
|
|
7555
7644
|
try {
|
|
7556
7645
|
dir = getFramework("opencode").getAgentDir(codeName);
|
|
7557
|
-
filePath =
|
|
7646
|
+
filePath = join22(dir, "telegram-getupdates-offset-opencode.json");
|
|
7558
7647
|
} catch {
|
|
7559
7648
|
dir = null;
|
|
7560
7649
|
filePath = null;
|
|
@@ -7563,7 +7652,7 @@ function createFileOffsetStore(codeName, log2, currentBotId) {
|
|
|
7563
7652
|
load() {
|
|
7564
7653
|
if (!filePath) return 0;
|
|
7565
7654
|
try {
|
|
7566
|
-
const parsed = JSON.parse(
|
|
7655
|
+
const parsed = JSON.parse(readFileSync18(filePath, "utf-8"));
|
|
7567
7656
|
if (currentBotId != null && typeof parsed?.bot_id === "number" && parsed.bot_id !== currentBotId) {
|
|
7568
7657
|
log2(`[telegram-ingest:${codeName}] offset cursor belongs to a different bot; ignoring (bot swap)`);
|
|
7569
7658
|
return 0;
|
|
@@ -7813,24 +7902,24 @@ function partitionActionableByPoison(actionable, states, config2) {
|
|
|
7813
7902
|
}
|
|
7814
7903
|
|
|
7815
7904
|
// src/lib/restart-flags.ts
|
|
7816
|
-
import { existsSync as existsSync10, mkdirSync as mkdirSync8, readdirSync as
|
|
7905
|
+
import { existsSync as existsSync10, mkdirSync as mkdirSync8, readdirSync as readdirSync5, readFileSync as readFileSync19, renameSync as renameSync4, rmSync as rmSync4, writeFileSync as writeFileSync10 } from "fs";
|
|
7817
7906
|
import { homedir as homedir10 } from "os";
|
|
7818
|
-
import { join as
|
|
7907
|
+
import { join as join23 } from "path";
|
|
7819
7908
|
import { randomUUID as randomUUID2 } from "crypto";
|
|
7820
7909
|
function restartFlagsDir() {
|
|
7821
|
-
return
|
|
7910
|
+
return join23(homedir10(), ".augmented", "restart-flags");
|
|
7822
7911
|
}
|
|
7823
7912
|
function flagPath(codeName) {
|
|
7824
|
-
return
|
|
7913
|
+
return join23(restartFlagsDir(), `${codeName}.flag`);
|
|
7825
7914
|
}
|
|
7826
7915
|
function readRestartFlags() {
|
|
7827
7916
|
const dir = restartFlagsDir();
|
|
7828
7917
|
if (!existsSync10(dir)) return [];
|
|
7829
7918
|
const out = [];
|
|
7830
|
-
for (const entry of
|
|
7919
|
+
for (const entry of readdirSync5(dir)) {
|
|
7831
7920
|
if (!entry.endsWith(".flag")) continue;
|
|
7832
7921
|
try {
|
|
7833
|
-
const raw =
|
|
7922
|
+
const raw = readFileSync19(join23(dir, entry), "utf8");
|
|
7834
7923
|
const parsed = JSON.parse(raw);
|
|
7835
7924
|
if (typeof parsed.codeName !== "string" || parsed.codeName.length === 0) {
|
|
7836
7925
|
parsed.codeName = entry.replace(/\.flag$/, "");
|
|
@@ -7948,8 +8037,8 @@ async function sendError(flag, opts, text) {
|
|
|
7948
8037
|
}
|
|
7949
8038
|
|
|
7950
8039
|
// src/lib/restart-context.ts
|
|
7951
|
-
import { readdirSync as
|
|
7952
|
-
import { dirname as dirname7, join as
|
|
8040
|
+
import { readdirSync as readdirSync6, readFileSync as readFileSync20, writeFileSync as writeFileSync11, mkdirSync as mkdirSync9, unlinkSync as unlinkSync3 } from "fs";
|
|
8041
|
+
import { dirname as dirname7, join as join24 } from "path";
|
|
7953
8042
|
var SLACK_PENDING_INBOUND_DIRNAME = "slack-pending-inbound";
|
|
7954
8043
|
var SLACK_RESTART_CONTEXT_DIRNAME = "slack-restart-context";
|
|
7955
8044
|
var MAX_TOPIC_CHARS = 140;
|
|
@@ -7961,10 +8050,10 @@ function augmentedAgentDir(codeName) {
|
|
|
7961
8050
|
return dirname7(getProjectDir(codeName));
|
|
7962
8051
|
}
|
|
7963
8052
|
function slackPendingInboundDir(codeName) {
|
|
7964
|
-
return
|
|
8053
|
+
return join24(augmentedAgentDir(codeName), SLACK_PENDING_INBOUND_DIRNAME);
|
|
7965
8054
|
}
|
|
7966
8055
|
function slackRestartContextDir(codeName) {
|
|
7967
|
-
return
|
|
8056
|
+
return join24(augmentedAgentDir(codeName), SLACK_RESTART_CONTEXT_DIRNAME);
|
|
7968
8057
|
}
|
|
7969
8058
|
function sanitizeTopic(raw) {
|
|
7970
8059
|
const cleaned = raw.replace(/\s+/g, " ").trim().replace(/[<>]/g, " ").replace(/\s+/g, " ").trim();
|
|
@@ -7999,14 +8088,14 @@ function computeRestartContextHints(markers, allTurns, nowMs, reconstruct = reco
|
|
|
7999
8088
|
}
|
|
8000
8089
|
function safeReaddir(dir) {
|
|
8001
8090
|
try {
|
|
8002
|
-
return
|
|
8091
|
+
return readdirSync6(dir);
|
|
8003
8092
|
} catch {
|
|
8004
8093
|
return [];
|
|
8005
8094
|
}
|
|
8006
8095
|
}
|
|
8007
8096
|
function readStrandedMarker(path) {
|
|
8008
8097
|
try {
|
|
8009
|
-
const parsed = JSON.parse(
|
|
8098
|
+
const parsed = JSON.parse(readFileSync20(path, "utf-8"));
|
|
8010
8099
|
if (typeof parsed.channel === "string" && typeof parsed.thread_ts === "string") {
|
|
8011
8100
|
return { channel: parsed.channel, thread_ts: parsed.thread_ts };
|
|
8012
8101
|
}
|
|
@@ -8024,7 +8113,7 @@ function pruneHintsExcept(codeName, freshFilenames) {
|
|
|
8024
8113
|
if (!filename.endsWith(".json")) continue;
|
|
8025
8114
|
if (freshFilenames.has(filename)) continue;
|
|
8026
8115
|
try {
|
|
8027
|
-
unlinkSync3(
|
|
8116
|
+
unlinkSync3(join24(ctxDir, filename));
|
|
8028
8117
|
} catch {
|
|
8029
8118
|
}
|
|
8030
8119
|
}
|
|
@@ -8045,7 +8134,7 @@ function refreshSlackRestartContextHints(codeNames, opts = {}) {
|
|
|
8045
8134
|
}
|
|
8046
8135
|
const markers = [];
|
|
8047
8136
|
for (const filename of markerFilenames.slice(0, cap)) {
|
|
8048
|
-
const parsed = readStrandedMarker(
|
|
8137
|
+
const parsed = readStrandedMarker(join24(markerDir, filename));
|
|
8049
8138
|
if (parsed) markers.push({ filename, channel: parsed.channel, thread_ts: parsed.thread_ts });
|
|
8050
8139
|
}
|
|
8051
8140
|
if (markers.length === 0) {
|
|
@@ -8059,7 +8148,7 @@ function refreshSlackRestartContextHints(codeNames, opts = {}) {
|
|
|
8059
8148
|
const freshFilenames = /* @__PURE__ */ new Set();
|
|
8060
8149
|
for (const { filename, hint } of hints) {
|
|
8061
8150
|
try {
|
|
8062
|
-
writeHintFile(
|
|
8151
|
+
writeHintFile(join24(ctxDir, filename), ctxDir, hint);
|
|
8063
8152
|
freshFilenames.add(filename);
|
|
8064
8153
|
} catch (err) {
|
|
8065
8154
|
log2(`[restart-context] ${codeName}: hint write failed for ${filename}: ${err.message}`);
|
|
@@ -9168,7 +9257,7 @@ function inboundAgeSecondsFor(codeName) {
|
|
|
9168
9257
|
}
|
|
9169
9258
|
function paneLogAgeSecondsFor(codeName) {
|
|
9170
9259
|
try {
|
|
9171
|
-
const mtimeMs =
|
|
9260
|
+
const mtimeMs = statSync6(paneLogPath(codeName)).mtimeMs;
|
|
9172
9261
|
return Math.max(0, Math.floor((Date.now() - mtimeMs) / 1e3));
|
|
9173
9262
|
} catch (err) {
|
|
9174
9263
|
if (err?.code === "ENOENT") return null;
|
|
@@ -9290,7 +9379,7 @@ var runningChannelSecretHashes = /* @__PURE__ */ new Map();
|
|
|
9290
9379
|
var sessionLaunchManagedStructure = /* @__PURE__ */ new Map();
|
|
9291
9380
|
function projectMcpHash(_codeName, projectDir) {
|
|
9292
9381
|
try {
|
|
9293
|
-
const raw =
|
|
9382
|
+
const raw = readFileSync21(join25(projectDir, ".mcp.json"), "utf-8");
|
|
9294
9383
|
return createHash16("sha256").update(canonicalJson(JSON.parse(raw))).digest("hex");
|
|
9295
9384
|
} catch {
|
|
9296
9385
|
return null;
|
|
@@ -9298,7 +9387,7 @@ function projectMcpHash(_codeName, projectDir) {
|
|
|
9298
9387
|
}
|
|
9299
9388
|
function projectMcpKeys(_codeName, projectDir) {
|
|
9300
9389
|
try {
|
|
9301
|
-
const raw =
|
|
9390
|
+
const raw = readFileSync21(join25(projectDir, ".mcp.json"), "utf-8");
|
|
9302
9391
|
const parsed = JSON.parse(raw);
|
|
9303
9392
|
const servers = parsed.mcpServers;
|
|
9304
9393
|
if (!servers || typeof servers !== "object") return /* @__PURE__ */ new Set();
|
|
@@ -9316,7 +9405,7 @@ function seedSessionLaunchBaselines(codeName, projectDir) {
|
|
|
9316
9405
|
else runningMcpServerKeys.delete(codeName);
|
|
9317
9406
|
let launchStructure = null;
|
|
9318
9407
|
try {
|
|
9319
|
-
const raw =
|
|
9408
|
+
const raw = readFileSync21(join25(projectDir, ".mcp.json"), "utf-8");
|
|
9320
9409
|
launchStructure = managedMcpStructureHashFromFile(
|
|
9321
9410
|
JSON.parse(raw),
|
|
9322
9411
|
isManagedMcpServerKey
|
|
@@ -9420,7 +9509,7 @@ async function runAgentSessionToolBindProbes(agent, integrations, projectDir, op
|
|
|
9420
9509
|
if (result && result.rebindCandidates.length > 0 && hostFlagStore().getBoolean("session-tool-rebind")) {
|
|
9421
9510
|
let mcpJsonForRebind = null;
|
|
9422
9511
|
try {
|
|
9423
|
-
mcpJsonForRebind = JSON.parse(
|
|
9512
|
+
mcpJsonForRebind = JSON.parse(readFileSync21(join25(projectDir, ".mcp.json"), "utf-8"));
|
|
9424
9513
|
} catch {
|
|
9425
9514
|
mcpJsonForRebind = null;
|
|
9426
9515
|
}
|
|
@@ -9571,7 +9660,7 @@ function checkMcpConfigDriftAndScheduleRestart(codeName, projectDir) {
|
|
|
9571
9660
|
function projectChannelSecretHash(projectDir) {
|
|
9572
9661
|
try {
|
|
9573
9662
|
const entries = parseEnvIntegrations(
|
|
9574
|
-
|
|
9663
|
+
readFileSync21(join25(projectDir, ".env.integrations"), "utf-8")
|
|
9575
9664
|
);
|
|
9576
9665
|
return channelSecretValueHash(entries, CHANNEL_SECRET_ENV_KEYS);
|
|
9577
9666
|
} catch {
|
|
@@ -9667,7 +9756,7 @@ var agentRestartTimezoneInputs = /* @__PURE__ */ new Map();
|
|
|
9667
9756
|
var lastVersionCheckAt = 0;
|
|
9668
9757
|
var VERSION_CHECK_INTERVAL_MS = 5 * 60 * 1e3;
|
|
9669
9758
|
var lastResponsivenessProbeAt = 0;
|
|
9670
|
-
var agtCliVersion = true ? "0.28.
|
|
9759
|
+
var agtCliVersion = true ? "0.28.439" : "dev";
|
|
9671
9760
|
function resolveBrewPath(execFileSync2) {
|
|
9672
9761
|
try {
|
|
9673
9762
|
const out = execFileSync2("which", ["brew"], { timeout: 5e3 }).toString().trim();
|
|
@@ -9956,7 +10045,7 @@ function ensureClaudeManagedSettings(path = claudeManagedSettingsPath()) {
|
|
|
9956
10045
|
try {
|
|
9957
10046
|
let settings = {};
|
|
9958
10047
|
if (existsSync11(path)) {
|
|
9959
|
-
const raw =
|
|
10048
|
+
const raw = readFileSync21(path, "utf-8").trim();
|
|
9960
10049
|
if (raw) {
|
|
9961
10050
|
let parsed;
|
|
9962
10051
|
try {
|
|
@@ -10011,7 +10100,7 @@ async function ensureOpencodeBinary() {
|
|
|
10011
10100
|
try {
|
|
10012
10101
|
const prefix = execFileSync2("npm", ["prefix", "-g"], { encoding: "utf-8", timeout: 1e4 }).trim();
|
|
10013
10102
|
if (prefix) {
|
|
10014
|
-
const npmBin =
|
|
10103
|
+
const npmBin = join25(prefix, "bin");
|
|
10015
10104
|
const current = (process.env.PATH ?? "").split(pathDelimiter);
|
|
10016
10105
|
if (!current.includes(npmBin)) {
|
|
10017
10106
|
process.env.PATH = [npmBin, ...current.filter(Boolean)].join(pathDelimiter);
|
|
@@ -10128,7 +10217,7 @@ ${r.stderr}`;
|
|
|
10128
10217
|
}
|
|
10129
10218
|
var UPDATE_CHECK_INTERVAL_MS = 5 * 60 * 1e3;
|
|
10130
10219
|
function selfUpdateAppliedMarkerPath() {
|
|
10131
|
-
return
|
|
10220
|
+
return join25(homedir11(), ".augmented", ".last-self-update-applied");
|
|
10132
10221
|
}
|
|
10133
10222
|
var selfUpdateUpToDateLogged = false;
|
|
10134
10223
|
var selfUpdatePinnedLogged = false;
|
|
@@ -10156,7 +10245,7 @@ async function checkAndUpdateCli(opts) {
|
|
|
10156
10245
|
const isNpmGlobal = !isBrewFormula && resolvedPath.includes("node_modules");
|
|
10157
10246
|
if (!isBrewFormula && !isNpmGlobal) return "noop";
|
|
10158
10247
|
const { readFileSync: readF, writeFileSync: writeF } = await import("fs");
|
|
10159
|
-
const markerPath =
|
|
10248
|
+
const markerPath = join25(homedir11(), ".augmented", ".last-update-check");
|
|
10160
10249
|
if (!force) {
|
|
10161
10250
|
try {
|
|
10162
10251
|
const lastCheck = parseInt(readF(markerPath, "utf-8").trim(), 10);
|
|
@@ -10516,12 +10605,12 @@ async function checkClaudeAuth() {
|
|
|
10516
10605
|
var evalEmptyMcpConfigPath = null;
|
|
10517
10606
|
function ensureEvalEmptyMcpConfig() {
|
|
10518
10607
|
if (evalEmptyMcpConfigPath && existsSync11(evalEmptyMcpConfigPath)) return evalEmptyMcpConfigPath;
|
|
10519
|
-
const dir =
|
|
10608
|
+
const dir = join25(homedir11(), ".augmented");
|
|
10520
10609
|
try {
|
|
10521
10610
|
mkdirSync10(dir, { recursive: true });
|
|
10522
10611
|
} catch {
|
|
10523
10612
|
}
|
|
10524
|
-
const p =
|
|
10613
|
+
const p = join25(dir, ".eval-empty-mcp.json");
|
|
10525
10614
|
writeFileSync12(p, JSON.stringify({ mcpServers: {} }));
|
|
10526
10615
|
evalEmptyMcpConfigPath = p;
|
|
10527
10616
|
return p;
|
|
@@ -10613,10 +10702,10 @@ function resolveConversationEvalBackend() {
|
|
|
10613
10702
|
return conversationEvalBackend;
|
|
10614
10703
|
}
|
|
10615
10704
|
function getStateFile() {
|
|
10616
|
-
return
|
|
10705
|
+
return join25(config?.configDir ?? join25(process.env["HOME"] ?? "/tmp", ".augmented"), "manager-state.json");
|
|
10617
10706
|
}
|
|
10618
10707
|
function channelHashCacheDir() {
|
|
10619
|
-
return config?.configDir ??
|
|
10708
|
+
return config?.configDir ?? join25(process.env["HOME"] ?? "/tmp", ".augmented");
|
|
10620
10709
|
}
|
|
10621
10710
|
function loadChannelHashCache2() {
|
|
10622
10711
|
loadChannelHashCache(agentState.knownChannelConfigHashes, channelHashCacheDir());
|
|
@@ -10668,7 +10757,7 @@ function removeDeliveryBaselineEntries(agentId) {
|
|
|
10668
10757
|
var _channelQuarantineStore = null;
|
|
10669
10758
|
function channelQuarantineStore() {
|
|
10670
10759
|
if (!_channelQuarantineStore) {
|
|
10671
|
-
const dir = config?.configDir ??
|
|
10760
|
+
const dir = config?.configDir ?? join25(process.env["HOME"] ?? "/tmp", ".augmented");
|
|
10672
10761
|
_channelQuarantineStore = new ChannelQuarantineStore(defaultQuarantinePath(dir));
|
|
10673
10762
|
}
|
|
10674
10763
|
return _channelQuarantineStore;
|
|
@@ -10685,7 +10774,7 @@ function claudeMdSizeFor(codeName) {
|
|
|
10685
10774
|
var _hostFlagStore = null;
|
|
10686
10775
|
function hostFlagStore() {
|
|
10687
10776
|
if (!_hostFlagStore) {
|
|
10688
|
-
const dir = config?.configDir ??
|
|
10777
|
+
const dir = config?.configDir ?? join25(process.env["HOME"] ?? "/tmp", ".augmented");
|
|
10689
10778
|
_hostFlagStore = new HostFlagStore({ cachePath: defaultFlagsCachePath(dir), log });
|
|
10690
10779
|
}
|
|
10691
10780
|
return _hostFlagStore;
|
|
@@ -10752,13 +10841,13 @@ function parseSkillFrontmatter(content) {
|
|
|
10752
10841
|
return out;
|
|
10753
10842
|
}
|
|
10754
10843
|
async function refreshSkillsIndexInClaudeMd(configDir, codeName, log2) {
|
|
10755
|
-
const { readdirSync:
|
|
10756
|
-
const skillsDir =
|
|
10757
|
-
const claudeMdPath =
|
|
10844
|
+
const { readdirSync: readdirSync8, readFileSync: rfs, existsSync: ex, writeFileSync: writeFileSync13 } = await import("fs");
|
|
10845
|
+
const skillsDir = join25(configDir, codeName, "project", ".claude", "skills");
|
|
10846
|
+
const claudeMdPath = join25(configDir, codeName, "project", "CLAUDE.md");
|
|
10758
10847
|
if (!ex(skillsDir) || !ex(claudeMdPath)) return;
|
|
10759
10848
|
const entries = [];
|
|
10760
|
-
for (const dir of
|
|
10761
|
-
const skillFile =
|
|
10849
|
+
for (const dir of readdirSync8(skillsDir).sort()) {
|
|
10850
|
+
const skillFile = join25(skillsDir, dir, "SKILL.md");
|
|
10762
10851
|
if (!ex(skillFile)) continue;
|
|
10763
10852
|
try {
|
|
10764
10853
|
const { name, description } = parseSkillFrontmatter(rfs(skillFile, "utf-8"));
|
|
@@ -11199,13 +11288,13 @@ async function pollCycle() {
|
|
|
11199
11288
|
);
|
|
11200
11289
|
if (hostFlagStore().getBoolean("wedge-transient-notice")) {
|
|
11201
11290
|
try {
|
|
11202
|
-
const paneTail =
|
|
11291
|
+
const paneTail = readFileSync21(paneLogPath(codeName), "utf8").slice(-65536);
|
|
11203
11292
|
const transient = detectTransientApiErrorInLog(paneTail);
|
|
11204
11293
|
if (transient) {
|
|
11205
|
-
const wedgeHome =
|
|
11294
|
+
const wedgeHome = join25(homedir11(), ".augmented", codeName);
|
|
11206
11295
|
if (existsSync11(wedgeHome)) {
|
|
11207
11296
|
atomicWriteFileSync(
|
|
11208
|
-
|
|
11297
|
+
join25(wedgeHome, "watchdog-give-up.json"),
|
|
11209
11298
|
JSON.stringify({
|
|
11210
11299
|
gave_up_at: wedgeNow.toISOString(),
|
|
11211
11300
|
reason: "transient_overload"
|
|
@@ -11476,7 +11565,7 @@ async function pollCycle() {
|
|
|
11476
11565
|
const adapter = resolveAgentFramework(prev.codeName);
|
|
11477
11566
|
stopAgentRuntime2(prev.codeName, "removed-from-host");
|
|
11478
11567
|
killAgentChannelProcesses(prev.codeName, { log });
|
|
11479
|
-
const agentDir =
|
|
11568
|
+
const agentDir = join25(adapter.getAgentDir(prev.codeName), "provision");
|
|
11480
11569
|
await cleanupAgentFiles(prev.codeName, agentDir);
|
|
11481
11570
|
clearAgentCaches(prev.agentId, prev.codeName);
|
|
11482
11571
|
}
|
|
@@ -11563,10 +11652,10 @@ async function pollCycle() {
|
|
|
11563
11652
|
// pending-inbound marker. Best-effort: a write failure is logged by
|
|
11564
11653
|
// the watchdog, never fails the poll cycle.
|
|
11565
11654
|
signalGiveUp: (codeName) => {
|
|
11566
|
-
const dir =
|
|
11655
|
+
const dir = join25(homedir11(), ".augmented", codeName);
|
|
11567
11656
|
if (!existsSync11(dir)) return;
|
|
11568
11657
|
atomicWriteFileSync(
|
|
11569
|
-
|
|
11658
|
+
join25(dir, "watchdog-give-up.json"),
|
|
11570
11659
|
JSON.stringify({ gave_up_at: (/* @__PURE__ */ new Date()).toISOString() })
|
|
11571
11660
|
);
|
|
11572
11661
|
}
|
|
@@ -11706,7 +11795,7 @@ async function processAgent(agent, agentStates) {
|
|
|
11706
11795
|
}
|
|
11707
11796
|
const now = (/* @__PURE__ */ new Date()).toISOString();
|
|
11708
11797
|
const adapter = resolveAgentFramework(agent.code_name);
|
|
11709
|
-
let agentDir =
|
|
11798
|
+
let agentDir = join25(adapter.getAgentDir(agent.code_name), "provision");
|
|
11710
11799
|
if (agent.status === "draft" || agent.status === "paused") {
|
|
11711
11800
|
if (previousKnownStatus !== agent.status) {
|
|
11712
11801
|
log(`Agent '${agent.code_name}' is ${agent.status}, skipping provisioning`);
|
|
@@ -11879,7 +11968,7 @@ async function processAgent(agent, agentStates) {
|
|
|
11879
11968
|
const frameworkId = refreshData.agent.framework ?? DEFAULT_FRAMEWORK;
|
|
11880
11969
|
agentFrameworkCache.set(agent.code_name, frameworkId);
|
|
11881
11970
|
const frameworkAdapter = getFramework(frameworkId);
|
|
11882
|
-
agentDir =
|
|
11971
|
+
agentDir = join25(frameworkAdapter.getAgentDir(agent.code_name), "provision");
|
|
11883
11972
|
cacheAgentDeliveryMetadata(agent.code_name, refreshData);
|
|
11884
11973
|
agentRestartTimezoneInputs.set(agent.code_name, {
|
|
11885
11974
|
agentTimezone: typeof refreshData.agent.timezone === "string" ? refreshData.agent.timezone : null,
|
|
@@ -11928,7 +12017,7 @@ async function processAgent(agent, agentStates) {
|
|
|
11928
12017
|
const changedFiles = [];
|
|
11929
12018
|
mkdirSync10(agentDir, { recursive: true });
|
|
11930
12019
|
for (const artifact of artifacts) {
|
|
11931
|
-
const filePath =
|
|
12020
|
+
const filePath = join25(agentDir, artifact.relativePath);
|
|
11932
12021
|
let existingHash;
|
|
11933
12022
|
let newHash;
|
|
11934
12023
|
let writeContent = artifact.content;
|
|
@@ -11947,8 +12036,8 @@ async function processAgent(agent, agentStates) {
|
|
|
11947
12036
|
};
|
|
11948
12037
|
newHash = sha256(stripDynamicSections(artifact.content));
|
|
11949
12038
|
try {
|
|
11950
|
-
const projectClaudeMd =
|
|
11951
|
-
const existing =
|
|
12039
|
+
const projectClaudeMd = join25(config.configDir, agent.code_name, "project", "CLAUDE.md");
|
|
12040
|
+
const existing = readFileSync21(projectClaudeMd, "utf-8");
|
|
11952
12041
|
existingHash = sha256(stripDynamicSections(existing));
|
|
11953
12042
|
} catch {
|
|
11954
12043
|
existingHash = null;
|
|
@@ -11966,7 +12055,7 @@ async function processAgent(agent, agentStates) {
|
|
|
11966
12055
|
const generatorKeys = Object.keys(generatorServers);
|
|
11967
12056
|
let existingRaw = "";
|
|
11968
12057
|
try {
|
|
11969
|
-
existingRaw =
|
|
12058
|
+
existingRaw = readFileSync21(filePath, "utf-8");
|
|
11970
12059
|
} catch {
|
|
11971
12060
|
}
|
|
11972
12061
|
const existingServers = parseMcp(existingRaw);
|
|
@@ -11982,7 +12071,7 @@ async function processAgent(agent, agentStates) {
|
|
|
11982
12071
|
} else if (artifact.relativePath === "opencode.json") {
|
|
11983
12072
|
let existingRaw = null;
|
|
11984
12073
|
try {
|
|
11985
|
-
existingRaw =
|
|
12074
|
+
existingRaw = readFileSync21(filePath, "utf-8");
|
|
11986
12075
|
} catch {
|
|
11987
12076
|
}
|
|
11988
12077
|
const mergeResult = mergeOpencodeConfigArtifact(artifact.content, existingRaw);
|
|
@@ -11998,12 +12087,12 @@ async function processAgent(agent, agentStates) {
|
|
|
11998
12087
|
}
|
|
11999
12088
|
}
|
|
12000
12089
|
if (changedFiles.length > 0) {
|
|
12001
|
-
const isFirst = !existsSync11(
|
|
12090
|
+
const isFirst = !existsSync11(join25(agentDir, "CHARTER.md"));
|
|
12002
12091
|
const verb = isFirst ? "Provisioning" : "Updating";
|
|
12003
12092
|
const fileNames = changedFiles.map((f) => f.relativePath).join(", ");
|
|
12004
12093
|
log(`${verb} '${agent.code_name}': ${fileNames}`);
|
|
12005
12094
|
for (const file of changedFiles) {
|
|
12006
|
-
const filePath =
|
|
12095
|
+
const filePath = join25(agentDir, file.relativePath);
|
|
12007
12096
|
mkdirSync10(dirname8(filePath), { recursive: true });
|
|
12008
12097
|
if (file.relativePath === ".mcp.json") {
|
|
12009
12098
|
safeWriteJsonAtomic(filePath, file.content, { mode: 384 });
|
|
@@ -12012,12 +12101,12 @@ async function processAgent(agent, agentStates) {
|
|
|
12012
12101
|
}
|
|
12013
12102
|
}
|
|
12014
12103
|
try {
|
|
12015
|
-
const provSkillsDir =
|
|
12104
|
+
const provSkillsDir = join25(agentDir, ".claude", "skills");
|
|
12016
12105
|
if (existsSync11(provSkillsDir)) {
|
|
12017
|
-
for (const folder of
|
|
12106
|
+
for (const folder of readdirSync7(provSkillsDir)) {
|
|
12018
12107
|
if (folder.startsWith("knowledge-")) {
|
|
12019
12108
|
try {
|
|
12020
|
-
rmSync5(
|
|
12109
|
+
rmSync5(join25(provSkillsDir, folder), { recursive: true });
|
|
12021
12110
|
} catch {
|
|
12022
12111
|
}
|
|
12023
12112
|
}
|
|
@@ -12030,7 +12119,7 @@ async function processAgent(agent, agentStates) {
|
|
|
12030
12119
|
const trackedFiles2 = frameworkAdapter.driftTrackedFiles();
|
|
12031
12120
|
const hashes = /* @__PURE__ */ new Map();
|
|
12032
12121
|
for (const file of trackedFiles2) {
|
|
12033
|
-
const h = hashFile(
|
|
12122
|
+
const h = hashFile(join25(agentDir, file));
|
|
12034
12123
|
if (h) hashes.set(file, h);
|
|
12035
12124
|
}
|
|
12036
12125
|
agentState.writtenHashes.set(agent.agent_id, hashes);
|
|
@@ -12048,14 +12137,14 @@ async function processAgent(agent, agentStates) {
|
|
|
12048
12137
|
}
|
|
12049
12138
|
if (Array.isArray(refreshData.workflows)) {
|
|
12050
12139
|
try {
|
|
12051
|
-
const provWorkflowsDir =
|
|
12140
|
+
const provWorkflowsDir = join25(agentDir, ".claude", "workflows");
|
|
12052
12141
|
if (existsSync11(provWorkflowsDir)) {
|
|
12053
12142
|
const expected = new Set(refreshData.workflows.map((w) => `${w.name}.js`));
|
|
12054
|
-
for (const file of
|
|
12143
|
+
for (const file of readdirSync7(provWorkflowsDir)) {
|
|
12055
12144
|
if (!file.endsWith(".js")) continue;
|
|
12056
12145
|
if (expected.has(file)) continue;
|
|
12057
12146
|
try {
|
|
12058
|
-
rmSync5(
|
|
12147
|
+
rmSync5(join25(provWorkflowsDir, file));
|
|
12059
12148
|
} catch {
|
|
12060
12149
|
}
|
|
12061
12150
|
}
|
|
@@ -12137,7 +12226,7 @@ async function processAgent(agent, agentStates) {
|
|
|
12137
12226
|
if (written && existsSync11(agentDir)) {
|
|
12138
12227
|
const driftedFiles = [];
|
|
12139
12228
|
for (const [file, expectedHash] of written) {
|
|
12140
|
-
const localHash = hashFile(
|
|
12229
|
+
const localHash = hashFile(join25(agentDir, file));
|
|
12141
12230
|
if (localHash && localHash !== expectedHash) {
|
|
12142
12231
|
driftedFiles.push(file);
|
|
12143
12232
|
}
|
|
@@ -12148,7 +12237,7 @@ async function processAgent(agent, agentStates) {
|
|
|
12148
12237
|
try {
|
|
12149
12238
|
const localHashes = {};
|
|
12150
12239
|
for (const file of driftedFiles) {
|
|
12151
|
-
localHashes[file] = hashFile(
|
|
12240
|
+
localHashes[file] = hashFile(join25(agentDir, file));
|
|
12152
12241
|
}
|
|
12153
12242
|
await api.post("/host/drift", {
|
|
12154
12243
|
agent_id: agent.agent_id,
|
|
@@ -12335,7 +12424,7 @@ async function processAgent(agent, agentStates) {
|
|
|
12335
12424
|
const addedChannels = [...restartDecision.added];
|
|
12336
12425
|
const writeDmNoticeMarkers = isChannelAddRestart ? () => {
|
|
12337
12426
|
try {
|
|
12338
|
-
const agentAugmentedDir =
|
|
12427
|
+
const agentAugmentedDir = join25(homedir11(), ".augmented", agent.code_name);
|
|
12339
12428
|
mkdirSync10(agentAugmentedDir, { recursive: true });
|
|
12340
12429
|
const markerJson = JSON.stringify({
|
|
12341
12430
|
version: 1,
|
|
@@ -12343,7 +12432,7 @@ async function processAgent(agent, agentStates) {
|
|
|
12343
12432
|
added: addedChannels
|
|
12344
12433
|
});
|
|
12345
12434
|
for (const file of ["slack-channel-add-restart.json", "telegram-channel-add-restart.json"]) {
|
|
12346
|
-
atomicWriteFileSync(
|
|
12435
|
+
atomicWriteFileSync(join25(agentAugmentedDir, file), markerJson);
|
|
12347
12436
|
}
|
|
12348
12437
|
} catch (err) {
|
|
12349
12438
|
log(`[hot-reload] channel-add DM-notice marker write failed for '${agent.code_name}' (non-fatal): ${err.message}`);
|
|
@@ -12532,18 +12621,18 @@ async function processAgent(agent, agentStates) {
|
|
|
12532
12621
|
if (agentSessionMode === "persistent" && (agentFrameworkCache.get(agent.code_name) ?? DEFAULT_FRAMEWORK) === "claude-code") {
|
|
12533
12622
|
try {
|
|
12534
12623
|
const agentProvisionDir = agentDir;
|
|
12535
|
-
const projectDir =
|
|
12624
|
+
const projectDir = join25(homedir11(), ".augmented", agent.code_name, "project");
|
|
12536
12625
|
mkdirSync10(agentProvisionDir, { recursive: true });
|
|
12537
12626
|
mkdirSync10(projectDir, { recursive: true });
|
|
12538
|
-
const provisionMcpPath =
|
|
12539
|
-
const projectMcpPath =
|
|
12627
|
+
const provisionMcpPath = join25(agentProvisionDir, ".mcp.json");
|
|
12628
|
+
const projectMcpPath = join25(projectDir, ".mcp.json");
|
|
12540
12629
|
let mcpConfig = { mcpServers: {} };
|
|
12541
12630
|
try {
|
|
12542
|
-
mcpConfig = JSON.parse(
|
|
12631
|
+
mcpConfig = JSON.parse(readFileSync21(provisionMcpPath, "utf-8"));
|
|
12543
12632
|
if (!mcpConfig.mcpServers) mcpConfig.mcpServers = {};
|
|
12544
12633
|
} catch {
|
|
12545
12634
|
}
|
|
12546
|
-
const localDirectChatChannel =
|
|
12635
|
+
const localDirectChatChannel = join25(homedir11(), ".augmented", "_mcp", "direct-chat-channel.js");
|
|
12547
12636
|
const directChatTeamSettings = refreshData.team?.settings;
|
|
12548
12637
|
const directChatTz = (() => {
|
|
12549
12638
|
const tz = directChatTeamSettings?.["timezone"];
|
|
@@ -12569,7 +12658,7 @@ async function processAgent(agent, agentStates) {
|
|
|
12569
12658
|
// ~/.augmented/<codeName>/.current-turn-initiator.json. Note getAgentDir
|
|
12570
12659
|
// returns the agent root (NOT the /provision subdir `agentDir` points at),
|
|
12571
12660
|
// so it byte-matches the broker readers' path.
|
|
12572
|
-
AGT_TURN_INITIATOR_FILE:
|
|
12661
|
+
AGT_TURN_INITIATOR_FILE: join25(
|
|
12573
12662
|
frameworkAdapter.getAgentDir(agent.code_name),
|
|
12574
12663
|
".current-turn-initiator.json"
|
|
12575
12664
|
)
|
|
@@ -12589,7 +12678,7 @@ async function processAgent(agent, agentStates) {
|
|
|
12589
12678
|
log(`Channel credentials written for '${agent.code_name}/direct-chat'`);
|
|
12590
12679
|
}
|
|
12591
12680
|
}
|
|
12592
|
-
const staleChannelsPath =
|
|
12681
|
+
const staleChannelsPath = join25(projectDir, ".mcp-channels.json");
|
|
12593
12682
|
if (existsSync11(staleChannelsPath)) {
|
|
12594
12683
|
try {
|
|
12595
12684
|
rmSync5(staleChannelsPath, { force: true });
|
|
@@ -12679,7 +12768,7 @@ async function processAgent(agent, agentStates) {
|
|
|
12679
12768
|
}
|
|
12680
12769
|
if (hostFlagStore().getBoolean("connectivity-probe")) {
|
|
12681
12770
|
try {
|
|
12682
|
-
const probeProjectDir =
|
|
12771
|
+
const probeProjectDir = join25(homedir11(), ".augmented", agent.code_name, "project");
|
|
12683
12772
|
let probeSet = integrations;
|
|
12684
12773
|
try {
|
|
12685
12774
|
const quarantined = await api.post("/host/agent-integrations/quarantined", { agent_id: agent.agent_id });
|
|
@@ -12725,7 +12814,7 @@ async function processAgent(agent, agentStates) {
|
|
|
12725
12814
|
const forceDue = attemptsLeft > 0;
|
|
12726
12815
|
let probeRan = false;
|
|
12727
12816
|
try {
|
|
12728
|
-
const probeProjectDir =
|
|
12817
|
+
const probeProjectDir = join25(homedir11(), ".augmented", agent.code_name, "project");
|
|
12729
12818
|
probeRan = await runAgentSessionToolBindProbes(agent, integrations, probeProjectDir, { forceDue });
|
|
12730
12819
|
} catch (err) {
|
|
12731
12820
|
log(`Session-tool-bind probe failed for '${agent.code_name}': ${err.message}`);
|
|
@@ -12800,11 +12889,11 @@ async function processAgent(agent, agentStates) {
|
|
|
12800
12889
|
const intHash = computeIntegrationsHash(integrations);
|
|
12801
12890
|
const prevIntHash = agentState.knownIntegrationHashes.get(agent.agent_id);
|
|
12802
12891
|
if (intHash !== prevIntHash) {
|
|
12803
|
-
const projectDir =
|
|
12804
|
-
const envIntPath =
|
|
12892
|
+
const projectDir = join25(homedir11(), ".augmented", agent.code_name, "project");
|
|
12893
|
+
const envIntPath = join25(projectDir, ".env.integrations");
|
|
12805
12894
|
let preWriteEnv;
|
|
12806
12895
|
try {
|
|
12807
|
-
preWriteEnv =
|
|
12896
|
+
preWriteEnv = readFileSync21(envIntPath, "utf-8");
|
|
12808
12897
|
} catch {
|
|
12809
12898
|
preWriteEnv = void 0;
|
|
12810
12899
|
}
|
|
@@ -12821,9 +12910,9 @@ async function processAgent(agent, agentStates) {
|
|
|
12821
12910
|
}
|
|
12822
12911
|
if (fw === "claude-code" && isSessionHealthy(agent.code_name)) {
|
|
12823
12912
|
try {
|
|
12824
|
-
const projectMcpPath =
|
|
12825
|
-
const postWriteEnv =
|
|
12826
|
-
const mcpContent =
|
|
12913
|
+
const projectMcpPath = join25(projectDir, ".mcp.json");
|
|
12914
|
+
const postWriteEnv = readFileSync21(envIntPath, "utf-8");
|
|
12915
|
+
const mcpContent = readFileSync21(projectMcpPath, "utf-8");
|
|
12827
12916
|
const changedVars = diffEnvIntegrations(preWriteEnv, postWriteEnv);
|
|
12828
12917
|
const mcpJsonForReap = JSON.parse(mcpContent);
|
|
12829
12918
|
const affectedServerKeys = findMcpServersUsingVars(mcpJsonForReap, changedVars);
|
|
@@ -13069,23 +13158,23 @@ async function processAgent(agent, agentStates) {
|
|
|
13069
13158
|
}
|
|
13070
13159
|
}
|
|
13071
13160
|
try {
|
|
13072
|
-
const { readdirSync:
|
|
13161
|
+
const { readdirSync: readdirSync8, rmSync: rmSync6 } = await import("fs");
|
|
13073
13162
|
const { homedir: homedir12 } = await import("os");
|
|
13074
13163
|
const frameworkId2 = frameworkAdapter.id;
|
|
13075
13164
|
const candidateSkillDirs = [
|
|
13076
13165
|
// Claude Code — framework runtime tree
|
|
13077
|
-
|
|
13166
|
+
join25(homedir12(), ".augmented", agent.code_name, "skills"),
|
|
13078
13167
|
// Claude Code — project tree
|
|
13079
|
-
|
|
13168
|
+
join25(homedir12(), ".augmented", agent.code_name, "project", ".claude", "skills"),
|
|
13080
13169
|
// Defensive: legacy provision-side path, not currently an
|
|
13081
13170
|
// install target but cheap to sweep.
|
|
13082
|
-
|
|
13171
|
+
join25(agentDir, ".claude", "skills")
|
|
13083
13172
|
];
|
|
13084
13173
|
const existingDirs = candidateSkillDirs.filter((d) => existsSync11(d));
|
|
13085
13174
|
const discoveredEntries = /* @__PURE__ */ new Set();
|
|
13086
13175
|
for (const dir of existingDirs) {
|
|
13087
13176
|
try {
|
|
13088
|
-
for (const entry of
|
|
13177
|
+
for (const entry of readdirSync8(dir)) {
|
|
13089
13178
|
if (entry.startsWith("plugin-") || entry.startsWith("integration-")) {
|
|
13090
13179
|
discoveredEntries.add(entry);
|
|
13091
13180
|
}
|
|
@@ -13095,7 +13184,7 @@ async function processAgent(agent, agentStates) {
|
|
|
13095
13184
|
}
|
|
13096
13185
|
const removeSkillFolder = (entry, reason) => {
|
|
13097
13186
|
for (const dir of existingDirs) {
|
|
13098
|
-
const p =
|
|
13187
|
+
const p = join25(dir, entry);
|
|
13099
13188
|
if (existsSync11(p)) {
|
|
13100
13189
|
rmSync6(p, { recursive: true, force: true });
|
|
13101
13190
|
}
|
|
@@ -13115,7 +13204,7 @@ async function processAgent(agent, agentStates) {
|
|
|
13115
13204
|
const sharedSkillsPayload = refreshAny.shared_skills;
|
|
13116
13205
|
const desiredResolved = globalSkillsPayload !== void 0 || sharedSkillsPayload !== void 0;
|
|
13117
13206
|
const manifestPath = managedSkillManifestPath(
|
|
13118
|
-
|
|
13207
|
+
join25(homedir11(), ".augmented", agent.code_name)
|
|
13119
13208
|
);
|
|
13120
13209
|
const prevIds = /* @__PURE__ */ new Set([
|
|
13121
13210
|
...agentState.knownGlobalSkillIds.get(agent.agent_id) ?? /* @__PURE__ */ new Set(),
|
|
@@ -13135,15 +13224,15 @@ async function processAgent(agent, agentStates) {
|
|
|
13135
13224
|
}
|
|
13136
13225
|
if (plan.removes.length) {
|
|
13137
13226
|
const globalSkillDirs = [
|
|
13138
|
-
|
|
13139
|
-
|
|
13140
|
-
|
|
13227
|
+
join25(homedir11(), ".augmented", agent.code_name, "skills"),
|
|
13228
|
+
join25(homedir11(), ".augmented", agent.code_name, "project", ".claude", "skills"),
|
|
13229
|
+
join25(agentDir, ".claude", "skills")
|
|
13141
13230
|
];
|
|
13142
13231
|
for (const id of plan.removes) {
|
|
13143
13232
|
let prunedAny = false;
|
|
13144
13233
|
for (const dir of globalSkillDirs) {
|
|
13145
|
-
const p =
|
|
13146
|
-
if (existsSync11(p) && existsSync11(
|
|
13234
|
+
const p = join25(dir, id);
|
|
13235
|
+
if (existsSync11(p) && existsSync11(join25(p, "SKILL.md"))) {
|
|
13147
13236
|
rmSync5(p, { recursive: true, force: true });
|
|
13148
13237
|
prunedAny = true;
|
|
13149
13238
|
}
|
|
@@ -13362,8 +13451,8 @@ async function processAgent(agent, agentStates) {
|
|
|
13362
13451
|
const sess = getSessionState(agent.code_name);
|
|
13363
13452
|
let mcpJsonParsed = null;
|
|
13364
13453
|
try {
|
|
13365
|
-
const mcpPath =
|
|
13366
|
-
mcpJsonParsed = JSON.parse(
|
|
13454
|
+
const mcpPath = join25(getProjectDir(agent.code_name), ".mcp.json");
|
|
13455
|
+
mcpJsonParsed = JSON.parse(readFileSync21(mcpPath, "utf-8"));
|
|
13367
13456
|
} catch {
|
|
13368
13457
|
}
|
|
13369
13458
|
reapMissingMcpSessions({
|
|
@@ -13728,7 +13817,7 @@ Retried to the limit after repeated stalls \u2014 needs a look.`).catch(() => {
|
|
|
13728
13817
|
if (trackedFiles.length > 0 && existsSync11(agentDir)) {
|
|
13729
13818
|
const hashes = /* @__PURE__ */ new Map();
|
|
13730
13819
|
for (const file of trackedFiles) {
|
|
13731
|
-
const h = hashFile(
|
|
13820
|
+
const h = hashFile(join25(agentDir, file));
|
|
13732
13821
|
if (h) hashes.set(file, h);
|
|
13733
13822
|
}
|
|
13734
13823
|
agentState.writtenHashes.set(agent.agent_id, hashes);
|
|
@@ -13743,7 +13832,7 @@ Retried to the limit after repeated stalls \u2014 needs a look.`).catch(() => {
|
|
|
13743
13832
|
refreshData.agent.onboarding_state
|
|
13744
13833
|
);
|
|
13745
13834
|
const obStep = obState.step;
|
|
13746
|
-
const markerPath =
|
|
13835
|
+
const markerPath = join25(homedir11(), ".augmented", agent.code_name, "onboarding-drive.json");
|
|
13747
13836
|
const marker = readOnboardingDriveMarker(markerPath);
|
|
13748
13837
|
const decision = decideOnboardingDrive(obStep, marker, Date.now(), obState.generation ?? 0);
|
|
13749
13838
|
if (decision.clearMarker) {
|
|
@@ -13831,7 +13920,7 @@ async function ensureOpencodeRuntime(agent, refreshData, agentTimezone) {
|
|
|
13831
13920
|
}
|
|
13832
13921
|
stopOpencodeSlackIngest(codeName, log);
|
|
13833
13922
|
stopOpencodeTelegramIngest(codeName, log);
|
|
13834
|
-
const opencodeProjectDir =
|
|
13923
|
+
const opencodeProjectDir = join25(getFramework("opencode").getAgentDir(codeName), "provision");
|
|
13835
13924
|
const serveEnv = {
|
|
13836
13925
|
AGT_HOST: requireHost(),
|
|
13837
13926
|
AGT_API_KEY: getApiKey() ?? void 0,
|
|
@@ -13874,8 +13963,8 @@ async function ensureOpencodeRuntime(agent, refreshData, agentTimezone) {
|
|
|
13874
13963
|
async function ensurePersistentSession(agent, tasks, boardItems, refreshData) {
|
|
13875
13964
|
const codeName = agent.code_name;
|
|
13876
13965
|
const projectDir = getProjectDir(codeName);
|
|
13877
|
-
const mcpConfigPath =
|
|
13878
|
-
const claudeMdPath =
|
|
13966
|
+
const mcpConfigPath = join25(projectDir, ".mcp.json");
|
|
13967
|
+
const claudeMdPath = join25(projectDir, "CLAUDE.md");
|
|
13879
13968
|
if (restartBreaker.isTripped(codeName)) {
|
|
13880
13969
|
const trip = restartBreaker.getTrip(codeName);
|
|
13881
13970
|
return {
|
|
@@ -15181,8 +15270,8 @@ function parseMemoryFile(raw, fallbackName) {
|
|
|
15181
15270
|
};
|
|
15182
15271
|
}
|
|
15183
15272
|
async function syncMemories(agent, configDir, log2) {
|
|
15184
|
-
const projectDir =
|
|
15185
|
-
const memoryDir =
|
|
15273
|
+
const projectDir = join25(configDir, agent.code_name, "project");
|
|
15274
|
+
const memoryDir = join25(projectDir, "memory");
|
|
15186
15275
|
const isFreshSync = pendingFreshMemorySync.has(agent.agent_id);
|
|
15187
15276
|
if (isFreshSync) {
|
|
15188
15277
|
log2(`[memory-sync] Fresh-sync requested for '${agent.code_name}' \u2014 pulling DB first`);
|
|
@@ -15197,10 +15286,10 @@ async function syncMemories(agent, configDir, log2) {
|
|
|
15197
15286
|
const prevHashes = memoryFileHashes.get(agent.agent_id) ?? /* @__PURE__ */ new Map();
|
|
15198
15287
|
const currentHashes = /* @__PURE__ */ new Map();
|
|
15199
15288
|
const changedMemories = [];
|
|
15200
|
-
for (const file of
|
|
15289
|
+
for (const file of readdirSync7(memoryDir)) {
|
|
15201
15290
|
if (!file.endsWith(".md")) continue;
|
|
15202
15291
|
try {
|
|
15203
|
-
const raw =
|
|
15292
|
+
const raw = readFileSync21(join25(memoryDir, file), "utf-8");
|
|
15204
15293
|
const fileHash = createHash16("sha256").update(raw).digest("hex").slice(0, 16);
|
|
15205
15294
|
currentHashes.set(file, fileHash);
|
|
15206
15295
|
if (prevHashes.get(file) === fileHash) continue;
|
|
@@ -15225,7 +15314,7 @@ async function syncMemories(agent, configDir, log2) {
|
|
|
15225
15314
|
} catch (err) {
|
|
15226
15315
|
for (const mem of changedMemories) {
|
|
15227
15316
|
for (const [file] of currentHashes) {
|
|
15228
|
-
const parsed = parseMemoryFile(
|
|
15317
|
+
const parsed = parseMemoryFile(readFileSync21(join25(memoryDir, file), "utf-8"), file.replace(/\.md$/, ""));
|
|
15229
15318
|
if (parsed?.name === mem.name) currentHashes.delete(file);
|
|
15230
15319
|
}
|
|
15231
15320
|
}
|
|
@@ -15238,7 +15327,7 @@ async function syncMemories(agent, configDir, log2) {
|
|
|
15238
15327
|
}
|
|
15239
15328
|
}
|
|
15240
15329
|
async function downloadMemories(agent, memoryDir, log2, { force }) {
|
|
15241
|
-
const localFiles = existsSync11(memoryDir) ?
|
|
15330
|
+
const localFiles = existsSync11(memoryDir) ? readdirSync7(memoryDir).filter((f) => f.endsWith(".md")).sort() : [];
|
|
15242
15331
|
const localListHash = createHash16("sha256").update(localFiles.join(",")).digest("hex").slice(0, 16);
|
|
15243
15332
|
const prevLocalHash = lastLocalFileHash.get(agent.agent_id);
|
|
15244
15333
|
const prevDownload = lastDownloadHash.get(agent.agent_id);
|
|
@@ -15260,7 +15349,7 @@ async function downloadMemories(agent, memoryDir, log2, { force }) {
|
|
|
15260
15349
|
const mem = dbMemories.memories[i];
|
|
15261
15350
|
const rawSlug = mem.name.toLowerCase().replace(/[^a-z0-9]+/g, "-").replace(/(^-|-$)/g, "").slice(0, 60);
|
|
15262
15351
|
const slug = rawSlug || `memory-${i}`;
|
|
15263
|
-
const filePath =
|
|
15352
|
+
const filePath = join25(memoryDir, `${slug}.md`);
|
|
15264
15353
|
const desired = `---
|
|
15265
15354
|
name: ${JSON.stringify(mem.name)}
|
|
15266
15355
|
type: ${mem.type}
|
|
@@ -15272,7 +15361,7 @@ ${mem.content}
|
|
|
15272
15361
|
if (existsSync11(filePath)) {
|
|
15273
15362
|
let existing = "";
|
|
15274
15363
|
try {
|
|
15275
|
-
existing =
|
|
15364
|
+
existing = readFileSync21(filePath, "utf-8");
|
|
15276
15365
|
} catch {
|
|
15277
15366
|
}
|
|
15278
15367
|
if (existing === desired) continue;
|
|
@@ -15284,7 +15373,7 @@ ${mem.content}
|
|
|
15284
15373
|
}
|
|
15285
15374
|
}
|
|
15286
15375
|
if (written > 0 || overwritten > 0) {
|
|
15287
|
-
const updatedFiles =
|
|
15376
|
+
const updatedFiles = readdirSync7(memoryDir).filter((f) => f.endsWith(".md")).sort();
|
|
15288
15377
|
lastLocalFileHash.set(agent.agent_id, createHash16("sha256").update(updatedFiles.join(",")).digest("hex").slice(0, 16));
|
|
15289
15378
|
log2(`Memory download for '${agent.code_name}': wrote ${written} new, overwrote ${overwritten} stale`);
|
|
15290
15379
|
}
|
|
@@ -15536,7 +15625,7 @@ function startManager(opts) {
|
|
|
15536
15625
|
try {
|
|
15537
15626
|
const stateFile = getStateFile();
|
|
15538
15627
|
if (existsSync11(stateFile)) {
|
|
15539
|
-
const raw =
|
|
15628
|
+
const raw = readFileSync21(stateFile, "utf-8");
|
|
15540
15629
|
const parsed = JSON.parse(raw);
|
|
15541
15630
|
if (Array.isArray(parsed.agents)) {
|
|
15542
15631
|
state6.agents = parsed.agents;
|
|
@@ -15563,7 +15652,7 @@ function startManager(opts) {
|
|
|
15563
15652
|
log(`[startup] state rehydration failed (continuing with empty state): ${err.message}`);
|
|
15564
15653
|
}
|
|
15565
15654
|
log(
|
|
15566
|
-
`[startup] worker pid=${process.pid} ppid=${process.ppid} node=${process.version} log=${
|
|
15655
|
+
`[startup] worker pid=${process.pid} ppid=${process.ppid} node=${process.version} log=${join25(homedir11(), ".augmented", "manager.log")}`
|
|
15567
15656
|
);
|
|
15568
15657
|
deployMcpAssets();
|
|
15569
15658
|
reapOrphanChannelMcps({ log });
|
|
@@ -15592,7 +15681,7 @@ async function reapOrphanedClaudePids() {
|
|
|
15592
15681
|
const looksLikeClaude = (pid) => {
|
|
15593
15682
|
if (process.platform !== "linux") return true;
|
|
15594
15683
|
try {
|
|
15595
|
-
const comm =
|
|
15684
|
+
const comm = readFileSync21(`/proc/${pid}/comm`, "utf-8").trim().toLowerCase();
|
|
15596
15685
|
return comm.includes("claude");
|
|
15597
15686
|
} catch {
|
|
15598
15687
|
return false;
|
|
@@ -15689,14 +15778,14 @@ function restartRunningChannelMcps(basenames) {
|
|
|
15689
15778
|
}
|
|
15690
15779
|
}
|
|
15691
15780
|
function deployMcpAssets() {
|
|
15692
|
-
const targetDir =
|
|
15781
|
+
const targetDir = join25(homedir11(), ".augmented", "_mcp");
|
|
15693
15782
|
mkdirSync10(targetDir, { recursive: true });
|
|
15694
15783
|
const moduleDir = dirname8(fileURLToPath(import.meta.url));
|
|
15695
15784
|
let mcpSourceDir = "";
|
|
15696
15785
|
let dir = moduleDir;
|
|
15697
15786
|
for (let i = 0; i < 6; i++) {
|
|
15698
|
-
const candidate =
|
|
15699
|
-
if (existsSync11(
|
|
15787
|
+
const candidate = join25(dir, "dist", "mcp");
|
|
15788
|
+
if (existsSync11(join25(candidate, "index.js"))) {
|
|
15700
15789
|
mcpSourceDir = candidate;
|
|
15701
15790
|
break;
|
|
15702
15791
|
}
|
|
@@ -15712,7 +15801,7 @@ function deployMcpAssets() {
|
|
|
15712
15801
|
const fileHash = (p) => {
|
|
15713
15802
|
try {
|
|
15714
15803
|
if (!existsSync11(p)) return null;
|
|
15715
|
-
return createHash16("sha256").update(
|
|
15804
|
+
return createHash16("sha256").update(readFileSync21(p)).digest("hex");
|
|
15716
15805
|
} catch {
|
|
15717
15806
|
return null;
|
|
15718
15807
|
}
|
|
@@ -15776,8 +15865,8 @@ function deployMcpAssets() {
|
|
|
15776
15865
|
// needs restarting to pick up a token rotation.
|
|
15777
15866
|
"xero.js"
|
|
15778
15867
|
]) {
|
|
15779
|
-
const src =
|
|
15780
|
-
const dst =
|
|
15868
|
+
const src = join25(mcpSourceDir, file);
|
|
15869
|
+
const dst = join25(targetDir, file);
|
|
15781
15870
|
if (!existsSync11(src)) continue;
|
|
15782
15871
|
const before = fileHash(dst);
|
|
15783
15872
|
try {
|
|
@@ -15795,16 +15884,16 @@ function deployMcpAssets() {
|
|
|
15795
15884
|
log(`[manager] Bundle(s) updated: ${changedBasenames.join(", ")} \u2014 signalling running instances to restart`);
|
|
15796
15885
|
restartRunningChannelMcps(changedBasenames);
|
|
15797
15886
|
}
|
|
15798
|
-
const localMcpPath =
|
|
15887
|
+
const localMcpPath = join25(targetDir, "index.js");
|
|
15799
15888
|
try {
|
|
15800
|
-
const agentsDir =
|
|
15889
|
+
const agentsDir = join25(homedir11(), ".augmented", "agents");
|
|
15801
15890
|
if (existsSync11(agentsDir)) {
|
|
15802
|
-
for (const entry of
|
|
15891
|
+
for (const entry of readdirSync7(agentsDir, { withFileTypes: true })) {
|
|
15803
15892
|
if (!entry.isDirectory()) continue;
|
|
15804
15893
|
for (const subdir of ["provision", "project"]) {
|
|
15805
|
-
const mcpJsonPath =
|
|
15894
|
+
const mcpJsonPath = join25(agentsDir, entry.name, subdir, ".mcp.json");
|
|
15806
15895
|
try {
|
|
15807
|
-
const raw =
|
|
15896
|
+
const raw = readFileSync21(mcpJsonPath, "utf-8");
|
|
15808
15897
|
if (!raw.includes("@integrity-labs/augmented-mcp")) continue;
|
|
15809
15898
|
const mcpConfig = JSON.parse(raw);
|
|
15810
15899
|
const augServer = mcpConfig.mcpServers?.["augmented"];
|