@integrity-labs/agt-cli 0.28.439 → 0.28.441
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/bin/agt.js +4 -4
- package/dist/{chunk-CM7DWCO4.js → chunk-6KTN6GTT.js} +3 -3
- package/dist/{chunk-MOASN7XT.js → chunk-NQP2W2RD.js} +63 -67
- package/dist/chunk-NQP2W2RD.js.map +1 -0
- package/dist/{claude-pair-runtime-QDNXOLED.js → claude-pair-runtime-YU6KOA6R.js} +2 -2
- package/dist/lib/manager-worker.js +364 -270
- package/dist/lib/manager-worker.js.map +1 -1
- package/dist/{persistent-session-2TTEAJDH.js → persistent-session-PWLMLDVX.js} +2 -2
- package/dist/{responsiveness-probe-PMDNQ4J4.js → responsiveness-probe-ZKUDFRIU.js} +2 -2
- package/package.json +1 -1
- package/dist/chunk-MOASN7XT.js.map +0 -1
- /package/dist/{chunk-CM7DWCO4.js.map → chunk-6KTN6GTT.js.map} +0 -0
- /package/dist/{claude-pair-runtime-QDNXOLED.js.map → claude-pair-runtime-YU6KOA6R.js.map} +0 -0
- /package/dist/{persistent-session-2TTEAJDH.js.map → persistent-session-PWLMLDVX.js.map} +0 -0
- /package/dist/{responsiveness-probe-PMDNQ4J4.js.map → responsiveness-probe-ZKUDFRIU.js.map} +0 -0
|
@@ -42,7 +42,7 @@ import {
|
|
|
42
42
|
resolveEffectivePinRaw,
|
|
43
43
|
safeWriteJsonAtomic,
|
|
44
44
|
setConfigHash
|
|
45
|
-
} from "../chunk-
|
|
45
|
+
} from "../chunk-6KTN6GTT.js";
|
|
46
46
|
import {
|
|
47
47
|
getProjectDir as getProjectDir2,
|
|
48
48
|
getReadyTasks,
|
|
@@ -66,6 +66,7 @@ import {
|
|
|
66
66
|
SCHEDULED_TURN_MARKER_FILENAME,
|
|
67
67
|
SUPPRESS_SENTINEL,
|
|
68
68
|
StreamEncoder,
|
|
69
|
+
USAGE_LIMIT_MARKER_FILENAME,
|
|
69
70
|
appendDmFooter,
|
|
70
71
|
attributeTranscriptUsageByRun,
|
|
71
72
|
buildEgressAllowlist,
|
|
@@ -74,7 +75,6 @@ import {
|
|
|
74
75
|
checkChannelInputs,
|
|
75
76
|
classifyActor,
|
|
76
77
|
classifyOutput,
|
|
77
|
-
clearUsageLimitMarker,
|
|
78
78
|
coerceOnboardingState,
|
|
79
79
|
creditWatchdogGiveUpCount,
|
|
80
80
|
describeOnboardingChannel,
|
|
@@ -122,6 +122,7 @@ import {
|
|
|
122
122
|
parseEnvIntegrations,
|
|
123
123
|
parseTranscriptUsage,
|
|
124
124
|
parseUsageBanner,
|
|
125
|
+
parseUsageLimitMarker,
|
|
125
126
|
peekCurrentSession,
|
|
126
127
|
prepareForRespawn,
|
|
127
128
|
readChannelServerEnv,
|
|
@@ -136,9 +137,11 @@ import {
|
|
|
136
137
|
resolveChannels,
|
|
137
138
|
resolveClaudeBinary,
|
|
138
139
|
resolveDmTarget,
|
|
140
|
+
resolveUsageLimitUntil,
|
|
139
141
|
restartEgressSidecar,
|
|
140
142
|
rotateSessionForWedge,
|
|
141
143
|
serializeAccountEnforcementMarker,
|
|
144
|
+
serializeUsageLimitMarker,
|
|
142
145
|
sessionTranscriptDir,
|
|
143
146
|
sha256,
|
|
144
147
|
sharedBusyBuckets,
|
|
@@ -153,19 +156,18 @@ import {
|
|
|
153
156
|
takeZombieDetection,
|
|
154
157
|
toOpencodeModel,
|
|
155
158
|
transcriptActivityAgeSeconds,
|
|
156
|
-
writeEgressAllowlist
|
|
157
|
-
|
|
158
|
-
} from "../chunk-MOASN7XT.js";
|
|
159
|
+
writeEgressAllowlist
|
|
160
|
+
} from "../chunk-NQP2W2RD.js";
|
|
159
161
|
import {
|
|
160
162
|
reapOrphanChannelMcps
|
|
161
163
|
} from "../chunk-XWVM4KPK.js";
|
|
162
164
|
|
|
163
165
|
// src/lib/manager-worker.ts
|
|
164
166
|
import { createHash as createHash16 } from "crypto";
|
|
165
|
-
import { readFileSync as
|
|
167
|
+
import { readFileSync as readFileSync22, writeFileSync as writeFileSync13, mkdirSync as mkdirSync11, existsSync as existsSync11, rmSync as rmSync6, readdirSync as readdirSync7, statSync as statSync6, copyFileSync } from "fs";
|
|
166
168
|
import { execFileSync as syncExecFile } from "child_process";
|
|
167
|
-
import { join as
|
|
168
|
-
import { homedir as
|
|
169
|
+
import { join as join26, dirname as dirname8, delimiter as pathDelimiter } from "path";
|
|
170
|
+
import { homedir as homedir12 } from "os";
|
|
169
171
|
import { fileURLToPath } from "url";
|
|
170
172
|
|
|
171
173
|
// src/lib/claude-code-upgrade-throttle.ts
|
|
@@ -2051,10 +2053,55 @@ var nodeArtifactFs = {
|
|
|
2051
2053
|
}
|
|
2052
2054
|
};
|
|
2053
2055
|
|
|
2054
|
-
// src/lib/
|
|
2055
|
-
import { readFileSync as readFileSync7,
|
|
2056
|
+
// src/lib/usage-limit-marker-file.ts
|
|
2057
|
+
import { mkdirSync as mkdirSync4, readFileSync as readFileSync7, rmSync as rmSync2, writeFileSync as writeFileSync4 } from "fs";
|
|
2058
|
+
import { homedir as homedir3 } from "os";
|
|
2056
2059
|
import { join as join6 } from "path";
|
|
2057
|
-
|
|
2060
|
+
function agentDir(codeName) {
|
|
2061
|
+
return join6(homedir3(), ".augmented", codeName);
|
|
2062
|
+
}
|
|
2063
|
+
function usageLimitMarkerPath(codeName) {
|
|
2064
|
+
return join6(agentDir(codeName), USAGE_LIMIT_MARKER_FILENAME);
|
|
2065
|
+
}
|
|
2066
|
+
function writeUsageLimitMarker(codeName, limitedUntil, log2) {
|
|
2067
|
+
try {
|
|
2068
|
+
mkdirSync4(agentDir(codeName), { recursive: true });
|
|
2069
|
+
writeFileSync4(usageLimitMarkerPath(codeName), serializeUsageLimitMarker(limitedUntil), "utf-8");
|
|
2070
|
+
} catch (err) {
|
|
2071
|
+
log2(`[usage-banner] usage-limit marker sync failed for '${codeName}': ${err.message}`);
|
|
2072
|
+
}
|
|
2073
|
+
}
|
|
2074
|
+
function clearUsageLimitMarker(codeName, log2) {
|
|
2075
|
+
try {
|
|
2076
|
+
rmSync2(usageLimitMarkerPath(codeName), { force: true });
|
|
2077
|
+
} catch (err) {
|
|
2078
|
+
log2(`[usage-banner] usage-limit marker clear failed for '${codeName}': ${err.message}`);
|
|
2079
|
+
}
|
|
2080
|
+
}
|
|
2081
|
+
function readUsageLimitUntil(opts) {
|
|
2082
|
+
const path = opts.filePath ?? (opts.codeName ? usageLimitMarkerPath(opts.codeName) : null);
|
|
2083
|
+
if (!path) return null;
|
|
2084
|
+
let raw;
|
|
2085
|
+
try {
|
|
2086
|
+
raw = readFileSync7(path, "utf-8");
|
|
2087
|
+
} catch {
|
|
2088
|
+
return null;
|
|
2089
|
+
}
|
|
2090
|
+
return resolveUsageLimitUntil(parseUsageLimitMarker(raw), opts.now ?? /* @__PURE__ */ new Date());
|
|
2091
|
+
}
|
|
2092
|
+
var loggedUsageCapDeferral = /* @__PURE__ */ new Map();
|
|
2093
|
+
function shouldLogUsageCapDeferral(site, codeName, limitedUntil) {
|
|
2094
|
+
const key = `${site}:${codeName}`;
|
|
2095
|
+
const at = limitedUntil.getTime();
|
|
2096
|
+
if (loggedUsageCapDeferral.get(key) === at) return false;
|
|
2097
|
+
loggedUsageCapDeferral.set(key, at);
|
|
2098
|
+
return true;
|
|
2099
|
+
}
|
|
2100
|
+
|
|
2101
|
+
// src/lib/agent-serving-probe.ts
|
|
2102
|
+
import { readFileSync as readFileSync8, readdirSync, statSync } from "fs";
|
|
2103
|
+
import { join as join7 } from "path";
|
|
2104
|
+
var RATE_LIMIT_WINDOW_MS = 6 * 60 * 60 * 1e3;
|
|
2058
2105
|
function classifyLine(line, startMs, endMs) {
|
|
2059
2106
|
const trimmed = line.trim();
|
|
2060
2107
|
if (!trimmed) return null;
|
|
@@ -2100,7 +2147,7 @@ function probeRateLimitState(args) {
|
|
|
2100
2147
|
let newest = null;
|
|
2101
2148
|
for (const name of entries) {
|
|
2102
2149
|
if (!name.endsWith(".jsonl")) continue;
|
|
2103
|
-
const path =
|
|
2150
|
+
const path = join7(dir, name);
|
|
2104
2151
|
try {
|
|
2105
2152
|
const st = statSync(path);
|
|
2106
2153
|
if (!st.isFile() || st.mtimeMs < startMs) continue;
|
|
@@ -2109,7 +2156,7 @@ function probeRateLimitState(args) {
|
|
|
2109
2156
|
}
|
|
2110
2157
|
let content;
|
|
2111
2158
|
try {
|
|
2112
|
-
content =
|
|
2159
|
+
content = readFileSync8(path, "utf-8");
|
|
2113
2160
|
} catch {
|
|
2114
2161
|
continue;
|
|
2115
2162
|
}
|
|
@@ -2226,13 +2273,13 @@ async function maybeReportUsageBanner(args) {
|
|
|
2226
2273
|
// src/lib/claude-account-fingerprint.ts
|
|
2227
2274
|
import { createHash as createHash6 } from "crypto";
|
|
2228
2275
|
import { readFile as readFile3, readdir as readdir3 } from "fs/promises";
|
|
2229
|
-
import { homedir as
|
|
2230
|
-
import { dirname as dirname4, join as
|
|
2276
|
+
import { homedir as homedir5, platform as platform2 } from "os";
|
|
2277
|
+
import { dirname as dirname4, join as join9 } from "path";
|
|
2231
2278
|
|
|
2232
2279
|
// src/lib/claude-auth-detect.ts
|
|
2233
2280
|
import { readFile as readFile2, readdir as readdir2 } from "fs/promises";
|
|
2234
|
-
import { homedir as
|
|
2235
|
-
import { join as
|
|
2281
|
+
import { homedir as homedir4, platform } from "os";
|
|
2282
|
+
import { join as join8 } from "path";
|
|
2236
2283
|
import { execFile } from "child_process";
|
|
2237
2284
|
import { promisify } from "util";
|
|
2238
2285
|
var execFileAsync = promisify(execFile);
|
|
@@ -2247,16 +2294,16 @@ async function detectClaudeAuth() {
|
|
|
2247
2294
|
}
|
|
2248
2295
|
async function findClaudeCredentialsPaths() {
|
|
2249
2296
|
const candidates = [
|
|
2250
|
-
|
|
2251
|
-
|
|
2297
|
+
join8(homedir4(), ".claude", ".credentials.json"),
|
|
2298
|
+
join8(homedir4(), ".claude", "credentials.json")
|
|
2252
2299
|
];
|
|
2253
2300
|
const isLinuxRoot = platform() === "linux" && typeof process.getuid === "function" && process.getuid() === 0;
|
|
2254
2301
|
if (isLinuxRoot) {
|
|
2255
2302
|
try {
|
|
2256
2303
|
const entries = await readdir2("/home", { withFileTypes: true });
|
|
2257
2304
|
for (const entry of entries.filter((entry2) => entry2.isDirectory()).sort((a, b) => a.name.localeCompare(b.name))) {
|
|
2258
|
-
candidates.push(
|
|
2259
|
-
candidates.push(
|
|
2305
|
+
candidates.push(join8("/home", entry.name, ".claude", ".credentials.json"));
|
|
2306
|
+
candidates.push(join8("/home", entry.name, ".claude", "credentials.json"));
|
|
2260
2307
|
}
|
|
2261
2308
|
} catch {
|
|
2262
2309
|
}
|
|
@@ -2334,13 +2381,13 @@ function parseExpiresAt(raw) {
|
|
|
2334
2381
|
|
|
2335
2382
|
// src/lib/claude-account-fingerprint.ts
|
|
2336
2383
|
async function candidateHomes() {
|
|
2337
|
-
const homes = [
|
|
2384
|
+
const homes = [homedir5()];
|
|
2338
2385
|
const isLinuxRoot = platform2() === "linux" && typeof process.getuid === "function" && process.getuid() === 0;
|
|
2339
2386
|
if (isLinuxRoot) {
|
|
2340
2387
|
try {
|
|
2341
2388
|
const entries = await readdir3("/home", { withFileTypes: true });
|
|
2342
2389
|
for (const entry of entries.filter((e) => e.isDirectory()).sort((a, b) => a.name.localeCompare(b.name))) {
|
|
2343
|
-
homes.push(
|
|
2390
|
+
homes.push(join9("/home", entry.name));
|
|
2344
2391
|
}
|
|
2345
2392
|
} catch {
|
|
2346
2393
|
}
|
|
@@ -2360,11 +2407,11 @@ async function homeOfActiveCredentials() {
|
|
|
2360
2407
|
async function claudeConfigCandidatePaths() {
|
|
2361
2408
|
const paths = [];
|
|
2362
2409
|
const configDir = process.env["CLAUDE_CONFIG_DIR"]?.trim();
|
|
2363
|
-
if (configDir) paths.push(
|
|
2410
|
+
if (configDir) paths.push(join9(configDir, ".claude.json"));
|
|
2364
2411
|
const activeHome = await homeOfActiveCredentials();
|
|
2365
|
-
if (activeHome) paths.push(
|
|
2412
|
+
if (activeHome) paths.push(join9(activeHome, ".claude.json"));
|
|
2366
2413
|
for (const home of await candidateHomes()) {
|
|
2367
|
-
const path =
|
|
2414
|
+
const path = join9(home, ".claude.json");
|
|
2368
2415
|
if (!paths.includes(path)) paths.push(path);
|
|
2369
2416
|
}
|
|
2370
2417
|
return paths;
|
|
@@ -2408,11 +2455,11 @@ async function getClaudeAccountFingerprint(paths, nowMs = Date.now()) {
|
|
|
2408
2455
|
}
|
|
2409
2456
|
|
|
2410
2457
|
// src/lib/account-enforcement-marker.ts
|
|
2411
|
-
import { mkdirSync as
|
|
2412
|
-
import { homedir as
|
|
2413
|
-
import { join as
|
|
2458
|
+
import { mkdirSync as mkdirSync5, renameSync, rmSync as rmSync3, writeFileSync as writeFileSync5 } from "fs";
|
|
2459
|
+
import { homedir as homedir6 } from "os";
|
|
2460
|
+
import { join as join10 } from "path";
|
|
2414
2461
|
function accountEnforcementMarkerPath(codeName) {
|
|
2415
|
-
return
|
|
2462
|
+
return join10(homedir6(), ".augmented", codeName, ACCOUNT_ENFORCEMENT_MARKER_FILENAME);
|
|
2416
2463
|
}
|
|
2417
2464
|
function syncAccountEnforcementMarker(codeName, level, log2 = (m) => process.stderr.write(`${m}
|
|
2418
2465
|
`)) {
|
|
@@ -2420,16 +2467,16 @@ function syncAccountEnforcementMarker(codeName, level, log2 = (m) => process.std
|
|
|
2420
2467
|
clearAccountEnforcementMarker(codeName, log2);
|
|
2421
2468
|
return;
|
|
2422
2469
|
}
|
|
2423
|
-
const dir =
|
|
2424
|
-
const path =
|
|
2470
|
+
const dir = join10(homedir6(), ".augmented", codeName);
|
|
2471
|
+
const path = join10(dir, ACCOUNT_ENFORCEMENT_MARKER_FILENAME);
|
|
2425
2472
|
const tempPath = `${path}.${process.pid}.tmp`;
|
|
2426
2473
|
try {
|
|
2427
|
-
|
|
2428
|
-
|
|
2474
|
+
mkdirSync5(dir, { recursive: true });
|
|
2475
|
+
writeFileSync5(tempPath, serializeAccountEnforcementMarker(level), "utf-8");
|
|
2429
2476
|
renameSync(tempPath, path);
|
|
2430
2477
|
} catch (err) {
|
|
2431
2478
|
try {
|
|
2432
|
-
|
|
2479
|
+
rmSync3(tempPath, { force: true });
|
|
2433
2480
|
} catch {
|
|
2434
2481
|
}
|
|
2435
2482
|
log2(`[account-enforcement] marker sync failed for '${codeName}': ${err.message}`);
|
|
@@ -2439,15 +2486,15 @@ function clearAccountEnforcementMarker(codeName, log2 = (m) => process.stderr.wr
|
|
|
2439
2486
|
`)) {
|
|
2440
2487
|
const path = accountEnforcementMarkerPath(codeName);
|
|
2441
2488
|
try {
|
|
2442
|
-
|
|
2489
|
+
rmSync3(path, { force: true });
|
|
2443
2490
|
} catch (err) {
|
|
2444
2491
|
log2(`[account-enforcement] marker clear failed for '${codeName}': ${err.message}`);
|
|
2445
2492
|
}
|
|
2446
2493
|
}
|
|
2447
2494
|
|
|
2448
2495
|
// src/lib/token-usage-monitor.ts
|
|
2449
|
-
import { readdirSync as readdirSync2, readFileSync as
|
|
2450
|
-
import { join as
|
|
2496
|
+
import { readdirSync as readdirSync2, readFileSync as readFileSync9, statSync as statSync2 } from "fs";
|
|
2497
|
+
import { join as join11 } from "path";
|
|
2451
2498
|
var MIN_CHECK_INTERVAL_MS2 = 6e4;
|
|
2452
2499
|
var TRANSCRIPT_MTIME_WINDOW_MS = 2 * 24 * 60 * 60 * 1e3;
|
|
2453
2500
|
var MAX_ENTRIES_PER_POST = 200;
|
|
@@ -2476,7 +2523,7 @@ async function maybeReportTokenUsage(args) {
|
|
|
2476
2523
|
if (!name.endsWith(".jsonl")) continue;
|
|
2477
2524
|
const sessionId = name.slice(0, -".jsonl".length);
|
|
2478
2525
|
if (!sessionId) continue;
|
|
2479
|
-
const path =
|
|
2526
|
+
const path = join11(dir, name);
|
|
2480
2527
|
let st;
|
|
2481
2528
|
try {
|
|
2482
2529
|
st = statSync2(path);
|
|
@@ -2492,7 +2539,7 @@ async function maybeReportTokenUsage(args) {
|
|
|
2492
2539
|
}
|
|
2493
2540
|
let content;
|
|
2494
2541
|
try {
|
|
2495
|
-
content =
|
|
2542
|
+
content = readFileSync9(path, "utf-8");
|
|
2496
2543
|
} catch (err) {
|
|
2497
2544
|
log2(`[token-usage] read failed for '${codeName}/${name}': ${err.message}`);
|
|
2498
2545
|
continue;
|
|
@@ -2573,8 +2620,8 @@ async function maybeReportTokenUsage(args) {
|
|
|
2573
2620
|
}
|
|
2574
2621
|
|
|
2575
2622
|
// src/lib/workflow-run-reconciler.ts
|
|
2576
|
-
import { readdirSync as readdirSync3, readFileSync as
|
|
2577
|
-
import { join as
|
|
2623
|
+
import { readdirSync as readdirSync3, readFileSync as readFileSync10, statSync as statSync3 } from "fs";
|
|
2624
|
+
import { join as join12 } from "path";
|
|
2578
2625
|
var MIN_CHECK_INTERVAL_MS3 = 5 * 6e4;
|
|
2579
2626
|
var SETTLE_MS = 3e4;
|
|
2580
2627
|
var TRANSCRIPT_MTIME_WINDOW_MS2 = 2 * 24 * 60 * 60 * 1e3;
|
|
@@ -2593,7 +2640,7 @@ function collectJsonlRecursive(dir, minMtimeMs, out, depth) {
|
|
|
2593
2640
|
return;
|
|
2594
2641
|
}
|
|
2595
2642
|
for (const name of entries) {
|
|
2596
|
-
const p =
|
|
2643
|
+
const p = join12(dir, name);
|
|
2597
2644
|
let st;
|
|
2598
2645
|
try {
|
|
2599
2646
|
st = statSync3(p);
|
|
@@ -2616,7 +2663,7 @@ function enumerateTranscriptFiles(transcriptDir, nowMs, minMtimeMs = nowMs - TRA
|
|
|
2616
2663
|
return out;
|
|
2617
2664
|
}
|
|
2618
2665
|
for (const name of entries) {
|
|
2619
|
-
const path =
|
|
2666
|
+
const path = join12(transcriptDir, name);
|
|
2620
2667
|
let st;
|
|
2621
2668
|
try {
|
|
2622
2669
|
st = statSync3(path);
|
|
@@ -2628,7 +2675,7 @@ function enumerateTranscriptFiles(transcriptDir, nowMs, minMtimeMs = nowMs - TRA
|
|
|
2628
2675
|
continue;
|
|
2629
2676
|
}
|
|
2630
2677
|
if (st.isDirectory()) {
|
|
2631
|
-
collectJsonlRecursive(
|
|
2678
|
+
collectJsonlRecursive(join12(path, "subagents"), minMtimeMs, out, 0);
|
|
2632
2679
|
}
|
|
2633
2680
|
}
|
|
2634
2681
|
return out;
|
|
@@ -2673,7 +2720,7 @@ async function maybeReconcileWorkflowRunTokens(args) {
|
|
|
2673
2720
|
const contents = [];
|
|
2674
2721
|
for (const path of files) {
|
|
2675
2722
|
try {
|
|
2676
|
-
contents.push(
|
|
2723
|
+
contents.push(readFileSync10(path, "utf-8"));
|
|
2677
2724
|
} catch {
|
|
2678
2725
|
}
|
|
2679
2726
|
}
|
|
@@ -2718,8 +2765,8 @@ async function maybeReconcileWorkflowRunTokens(args) {
|
|
|
2718
2765
|
}
|
|
2719
2766
|
|
|
2720
2767
|
// src/lib/conversation-evaluator.ts
|
|
2721
|
-
import { readdirSync as readdirSync4, readFileSync as
|
|
2722
|
-
import { join as
|
|
2768
|
+
import { readdirSync as readdirSync4, readFileSync as readFileSync11, statSync as statSync4 } from "fs";
|
|
2769
|
+
import { join as join13 } from "path";
|
|
2723
2770
|
var MIN_CHECK_INTERVAL_MS4 = 5 * 6e4;
|
|
2724
2771
|
var TRANSCRIPT_MTIME_WINDOW_MS3 = 7 * 24 * 60 * 60 * 1e3;
|
|
2725
2772
|
var WINDOW_PAD_MS = 5 * 6e4;
|
|
@@ -3155,7 +3202,7 @@ function readRecentTurns(dir, nowMs) {
|
|
|
3155
3202
|
return;
|
|
3156
3203
|
}
|
|
3157
3204
|
for (const ent of entries) {
|
|
3158
|
-
const full =
|
|
3205
|
+
const full = join13(d, ent.name);
|
|
3159
3206
|
if (ent.isDirectory()) {
|
|
3160
3207
|
visit(full);
|
|
3161
3208
|
continue;
|
|
@@ -3170,7 +3217,7 @@ function readRecentTurns(dir, nowMs) {
|
|
|
3170
3217
|
if (nowMs - mtimeMs > TRANSCRIPT_MTIME_WINDOW_MS3) continue;
|
|
3171
3218
|
let content;
|
|
3172
3219
|
try {
|
|
3173
|
-
content =
|
|
3220
|
+
content = readFileSync11(full, "utf8");
|
|
3174
3221
|
} catch {
|
|
3175
3222
|
continue;
|
|
3176
3223
|
}
|
|
@@ -3460,11 +3507,11 @@ async function reportSkip2(api2, agentId, conversationId, log2, codeName) {
|
|
|
3460
3507
|
}
|
|
3461
3508
|
|
|
3462
3509
|
// src/lib/activity-cache-monitor.ts
|
|
3463
|
-
import { existsSync as existsSync2, readFileSync as
|
|
3464
|
-
import { homedir as
|
|
3465
|
-
import { join as
|
|
3510
|
+
import { existsSync as existsSync2, readFileSync as readFileSync12 } from "fs";
|
|
3511
|
+
import { homedir as homedir7 } from "os";
|
|
3512
|
+
import { join as join14 } from "path";
|
|
3466
3513
|
var MIN_CHECK_INTERVAL_MS6 = 6e4;
|
|
3467
|
-
var STATS_CACHE_PATH =
|
|
3514
|
+
var STATS_CACHE_PATH = join14(homedir7(), ".claude", "stats-cache.json");
|
|
3468
3515
|
var ISO_DATE_RE = /^\d{4}-\d{2}-\d{2}$/;
|
|
3469
3516
|
var state5 = { lastObservedDate: null, lastCheckedAt: 0 };
|
|
3470
3517
|
function selectNewDailyRows(raw, lastObservedDate) {
|
|
@@ -3512,7 +3559,7 @@ async function maybeReportActivityCache(args) {
|
|
|
3512
3559
|
}
|
|
3513
3560
|
let raw;
|
|
3514
3561
|
try {
|
|
3515
|
-
raw =
|
|
3562
|
+
raw = readFileSync12(STATS_CACHE_PATH, "utf-8");
|
|
3516
3563
|
} catch (err) {
|
|
3517
3564
|
log2(`[activity-cache] readFileSync failed: ${err.message}`);
|
|
3518
3565
|
return;
|
|
@@ -3716,18 +3763,18 @@ function computeChannelConfigHash(input) {
|
|
|
3716
3763
|
}
|
|
3717
3764
|
|
|
3718
3765
|
// src/lib/channel-hash-cache.ts
|
|
3719
|
-
import { existsSync as existsSync3, readFileSync as
|
|
3720
|
-
import { join as
|
|
3766
|
+
import { existsSync as existsSync3, readFileSync as readFileSync13, writeFileSync as writeFileSync6 } from "fs";
|
|
3767
|
+
import { join as join15 } from "path";
|
|
3721
3768
|
var CACHE_FILENAME = "channel-hash-cache.json";
|
|
3722
3769
|
function getChannelHashCacheFile(configDir) {
|
|
3723
|
-
return
|
|
3770
|
+
return join15(configDir, CACHE_FILENAME);
|
|
3724
3771
|
}
|
|
3725
3772
|
function loadChannelHashCache(target, configDir) {
|
|
3726
3773
|
const path = getChannelHashCacheFile(configDir);
|
|
3727
3774
|
if (!existsSync3(path)) return;
|
|
3728
3775
|
let parsed;
|
|
3729
3776
|
try {
|
|
3730
|
-
parsed = JSON.parse(
|
|
3777
|
+
parsed = JSON.parse(readFileSync13(path, "utf-8"));
|
|
3731
3778
|
} catch {
|
|
3732
3779
|
return;
|
|
3733
3780
|
}
|
|
@@ -3741,14 +3788,14 @@ function saveChannelHashCache(source, configDir) {
|
|
|
3741
3788
|
const obj = {};
|
|
3742
3789
|
for (const [key, value] of source) obj[key] = value;
|
|
3743
3790
|
try {
|
|
3744
|
-
|
|
3791
|
+
writeFileSync6(path, JSON.stringify(obj, null, 2));
|
|
3745
3792
|
} catch {
|
|
3746
3793
|
}
|
|
3747
3794
|
}
|
|
3748
3795
|
|
|
3749
3796
|
// src/lib/sender-policy-baseline.ts
|
|
3750
|
-
import { existsSync as existsSync4, readFileSync as
|
|
3751
|
-
import { join as
|
|
3797
|
+
import { existsSync as existsSync4, readFileSync as readFileSync14 } from "fs";
|
|
3798
|
+
import { join as join16 } from "path";
|
|
3752
3799
|
var BASELINE_FILENAME = "sender-policy-baseline.json";
|
|
3753
3800
|
var SENDER_POLICY_BASELINE_VERSION = 1;
|
|
3754
3801
|
var BASELINE_CONCERNS = ["senderPolicy", "slackBehaviour", "msteamsBehaviour"];
|
|
@@ -3760,14 +3807,14 @@ function createDeliveryBaselineMaps() {
|
|
|
3760
3807
|
};
|
|
3761
3808
|
}
|
|
3762
3809
|
function getSenderPolicyBaselineFile(configDir) {
|
|
3763
|
-
return
|
|
3810
|
+
return join16(configDir, BASELINE_FILENAME);
|
|
3764
3811
|
}
|
|
3765
3812
|
function loadSenderPolicyBaseline(target, configDir, log2) {
|
|
3766
3813
|
const path = getSenderPolicyBaselineFile(configDir);
|
|
3767
3814
|
if (!existsSync4(path)) return;
|
|
3768
3815
|
let parsed;
|
|
3769
3816
|
try {
|
|
3770
|
-
parsed = JSON.parse(
|
|
3817
|
+
parsed = JSON.parse(readFileSync14(path, "utf-8"));
|
|
3771
3818
|
} catch (err) {
|
|
3772
3819
|
log2?.(
|
|
3773
3820
|
`[sender-policy] discarding corrupt ${BASELINE_FILENAME} (${err.message}) - restrictive-policy agents will take one fail-closed restart`
|
|
@@ -4290,16 +4337,16 @@ function planGlobalSkillSync(globalSkills, prevIds, hashOf, knownHash, options)
|
|
|
4290
4337
|
}
|
|
4291
4338
|
|
|
4292
4339
|
// src/lib/manager/managed-skill-manifest.ts
|
|
4293
|
-
import { existsSync as existsSync5, mkdirSync as
|
|
4294
|
-
import { dirname as dirname5, join as
|
|
4340
|
+
import { existsSync as existsSync5, mkdirSync as mkdirSync6, readFileSync as readFileSync15, writeFileSync as writeFileSync7 } from "fs";
|
|
4341
|
+
import { dirname as dirname5, join as join17 } from "path";
|
|
4295
4342
|
var MANIFEST_VERSION = 1;
|
|
4296
4343
|
function managedSkillManifestPath(agentRootDir) {
|
|
4297
|
-
return
|
|
4344
|
+
return join17(agentRootDir, "managed-skills.json");
|
|
4298
4345
|
}
|
|
4299
4346
|
function readManagedSkillManifest(path) {
|
|
4300
4347
|
try {
|
|
4301
4348
|
if (!existsSync5(path)) return /* @__PURE__ */ new Set();
|
|
4302
|
-
const parsed = JSON.parse(
|
|
4349
|
+
const parsed = JSON.parse(readFileSync15(path, "utf-8"));
|
|
4303
4350
|
const ids = Array.isArray(parsed?.globalSkillIds) ? parsed.globalSkillIds : [];
|
|
4304
4351
|
return new Set(ids.filter((id) => typeof id === "string" && id.length > 0));
|
|
4305
4352
|
} catch {
|
|
@@ -4308,12 +4355,12 @@ function readManagedSkillManifest(path) {
|
|
|
4308
4355
|
}
|
|
4309
4356
|
function writeManagedSkillManifest(path, ids) {
|
|
4310
4357
|
try {
|
|
4311
|
-
|
|
4358
|
+
mkdirSync6(dirname5(path), { recursive: true });
|
|
4312
4359
|
const body = {
|
|
4313
4360
|
version: MANIFEST_VERSION,
|
|
4314
4361
|
globalSkillIds: [...ids].sort()
|
|
4315
4362
|
};
|
|
4316
|
-
|
|
4363
|
+
writeFileSync7(path, JSON.stringify(body, null, 2));
|
|
4317
4364
|
} catch {
|
|
4318
4365
|
}
|
|
4319
4366
|
}
|
|
@@ -4411,9 +4458,9 @@ function resolveModelChain(refreshData) {
|
|
|
4411
4458
|
}
|
|
4412
4459
|
|
|
4413
4460
|
// src/lib/manager/claude-auth.ts
|
|
4414
|
-
import { existsSync as existsSync6, rmSync as
|
|
4415
|
-
import { join as
|
|
4416
|
-
import { homedir as
|
|
4461
|
+
import { existsSync as existsSync6, rmSync as rmSync4 } from "fs";
|
|
4462
|
+
import { join as join18 } from "path";
|
|
4463
|
+
import { homedir as homedir8 } from "os";
|
|
4417
4464
|
async function applyClaudeAuthToEnv(childEnv, label) {
|
|
4418
4465
|
const apiKey = getApiKey();
|
|
4419
4466
|
if (!apiKey) {
|
|
@@ -4425,12 +4472,12 @@ async function applyClaudeAuthToEnv(childEnv, label) {
|
|
|
4425
4472
|
throw new Error("claude_auth_mode=api_key but /host/exchange returned no decrypted key");
|
|
4426
4473
|
}
|
|
4427
4474
|
childEnv.ANTHROPIC_API_KEY = exchange.anthropicApiKey;
|
|
4428
|
-
const claudeDir =
|
|
4475
|
+
const claudeDir = join18(homedir8(), ".claude");
|
|
4429
4476
|
for (const filename of [".credentials.json", "credentials.json"]) {
|
|
4430
|
-
const p =
|
|
4477
|
+
const p = join18(claudeDir, filename);
|
|
4431
4478
|
if (existsSync6(p)) {
|
|
4432
4479
|
try {
|
|
4433
|
-
|
|
4480
|
+
rmSync4(p, { force: true });
|
|
4434
4481
|
log(`[${label}] Removed ${p} (api_key mode \u2014 preventing OAuth fallback)`);
|
|
4435
4482
|
} catch {
|
|
4436
4483
|
}
|
|
@@ -4442,8 +4489,8 @@ async function applyClaudeAuthToEnv(childEnv, label) {
|
|
|
4442
4489
|
}
|
|
4443
4490
|
|
|
4444
4491
|
// src/lib/manager/kanban/parsers.ts
|
|
4445
|
-
import { existsSync as existsSync7, readFileSync as
|
|
4446
|
-
import { join as
|
|
4492
|
+
import { existsSync as existsSync7, readFileSync as readFileSync16 } from "fs";
|
|
4493
|
+
import { join as join19 } from "path";
|
|
4447
4494
|
var STANDUP_TEMPLATES = /* @__PURE__ */ new Set(["daily-standup", "end-of-day-summary"]);
|
|
4448
4495
|
var TASK_UPDATE_TEMPLATES = /* @__PURE__ */ new Set(["hourly-status", "task-update"]);
|
|
4449
4496
|
var PLAN_TEMPLATES = /* @__PURE__ */ new Set(["morning-plan"]);
|
|
@@ -4582,12 +4629,12 @@ function getBuiltInSkillContent(skillId) {
|
|
|
4582
4629
|
if (builtInSkillCache.has(skillId)) return builtInSkillCache.get(skillId);
|
|
4583
4630
|
try {
|
|
4584
4631
|
const candidates = [
|
|
4585
|
-
|
|
4586
|
-
|
|
4632
|
+
join19(process.cwd(), "skills", skillId, "SKILL.md"),
|
|
4633
|
+
join19(new URL(".", import.meta.url).pathname, "..", "..", "..", "..", "..", "..", "skills", skillId, "SKILL.md")
|
|
4587
4634
|
];
|
|
4588
4635
|
for (const candidate of candidates) {
|
|
4589
4636
|
if (existsSync7(candidate)) {
|
|
4590
|
-
const content =
|
|
4637
|
+
const content = readFileSync16(candidate, "utf-8");
|
|
4591
4638
|
const files = [{ relativePath: "SKILL.md", content }];
|
|
4592
4639
|
builtInSkillCache.set(skillId, files);
|
|
4593
4640
|
return files;
|
|
@@ -4728,19 +4775,19 @@ function formatBoardForPrompt(items, template) {
|
|
|
4728
4775
|
}
|
|
4729
4776
|
|
|
4730
4777
|
// src/lib/manager/kanban/nudge-state-cache.ts
|
|
4731
|
-
import { existsSync as existsSync8, readFileSync as
|
|
4732
|
-
import { join as
|
|
4778
|
+
import { existsSync as existsSync8, readFileSync as readFileSync17, writeFileSync as writeFileSync8 } from "fs";
|
|
4779
|
+
import { join as join20 } from "path";
|
|
4733
4780
|
var CACHE_FILENAME2 = "kanban-nudge-state.json";
|
|
4734
4781
|
var KANBAN_NUDGE_STATE_VERSION = 1;
|
|
4735
4782
|
function getKanbanNudgeStateFile(configDir) {
|
|
4736
|
-
return
|
|
4783
|
+
return join20(configDir, CACHE_FILENAME2);
|
|
4737
4784
|
}
|
|
4738
4785
|
function loadKanbanNudgeState(target, configDir) {
|
|
4739
4786
|
const path = getKanbanNudgeStateFile(configDir);
|
|
4740
4787
|
if (!existsSync8(path)) return;
|
|
4741
4788
|
let parsed;
|
|
4742
4789
|
try {
|
|
4743
|
-
parsed = JSON.parse(
|
|
4790
|
+
parsed = JSON.parse(readFileSync17(path, "utf-8"));
|
|
4744
4791
|
} catch {
|
|
4745
4792
|
return;
|
|
4746
4793
|
}
|
|
@@ -4765,7 +4812,7 @@ function saveKanbanNudgeState(source, configDir) {
|
|
|
4765
4812
|
const agents = {};
|
|
4766
4813
|
for (const [codeName, state7] of source) agents[codeName] = state7;
|
|
4767
4814
|
try {
|
|
4768
|
-
|
|
4815
|
+
writeFileSync8(path, JSON.stringify({ version: KANBAN_NUDGE_STATE_VERSION, agents }, null, 2));
|
|
4769
4816
|
} catch {
|
|
4770
4817
|
}
|
|
4771
4818
|
}
|
|
@@ -5306,9 +5353,9 @@ function closeScheduledRunsForCode(codeName, outcome, reason) {
|
|
|
5306
5353
|
|
|
5307
5354
|
// src/lib/manager/scheduler/kanban-route.ts
|
|
5308
5355
|
import { createHash as createHash11 } from "crypto";
|
|
5309
|
-
import { writeFileSync as
|
|
5310
|
-
import { homedir as
|
|
5311
|
-
import { join as
|
|
5356
|
+
import { writeFileSync as writeFileSync9, renameSync as renameSync2, mkdirSync as mkdirSync7, readFileSync as readFileSync18, unlinkSync } from "fs";
|
|
5357
|
+
import { homedir as homedir9 } from "os";
|
|
5358
|
+
import { join as join21, dirname as dirname6 } from "path";
|
|
5312
5359
|
|
|
5313
5360
|
// src/lib/manager/scheduler/notify.ts
|
|
5314
5361
|
import { createHash as createHash10 } from "crypto";
|
|
@@ -5648,19 +5695,19 @@ function resolveScheduledSlackTarget(task) {
|
|
|
5648
5695
|
}
|
|
5649
5696
|
function stampScheduledTurnMarker(codeName, taskId, target) {
|
|
5650
5697
|
try {
|
|
5651
|
-
const file =
|
|
5698
|
+
const file = join21(homedir9(), ".augmented", codeName, SCHEDULED_TURN_MARKER_FILENAME);
|
|
5652
5699
|
const marker = { ts: Date.now(), task_id: taskId, ...target ? { target } : {} };
|
|
5653
5700
|
const tmp = `${file}.tmp`;
|
|
5654
|
-
|
|
5701
|
+
writeFileSync9(tmp, JSON.stringify(marker), "utf8");
|
|
5655
5702
|
renameSync2(tmp, file);
|
|
5656
5703
|
} catch (err) {
|
|
5657
5704
|
log(`[scheduled-kanban] scheduled-turn marker write failed for '${codeName}': ${err.message}`);
|
|
5658
5705
|
}
|
|
5659
5706
|
}
|
|
5660
5707
|
function clearScheduledTurnMarkerForTask(codeName, taskId) {
|
|
5661
|
-
const file =
|
|
5708
|
+
const file = join21(homedir9(), ".augmented", codeName, SCHEDULED_TURN_MARKER_FILENAME);
|
|
5662
5709
|
try {
|
|
5663
|
-
const raw = JSON.parse(
|
|
5710
|
+
const raw = JSON.parse(readFileSync18(file, "utf8"));
|
|
5664
5711
|
if (typeof raw?.task_id !== "string" || raw.task_id !== taskId) return;
|
|
5665
5712
|
unlinkSync(file);
|
|
5666
5713
|
log(`[scheduled-kanban] scheduled-turn marker cleared for '${codeName}' (task ${taskId} complete)`);
|
|
@@ -5714,9 +5761,9 @@ async function routeScheduledTaskViaKanban(codeName, agentId, task, prompt, dura
|
|
|
5714
5761
|
return false;
|
|
5715
5762
|
}
|
|
5716
5763
|
try {
|
|
5717
|
-
const doorbell = directChatDoorbellPath(agentId,
|
|
5718
|
-
|
|
5719
|
-
|
|
5764
|
+
const doorbell = directChatDoorbellPath(agentId, homedir9());
|
|
5765
|
+
mkdirSync7(dirname6(doorbell), { recursive: true });
|
|
5766
|
+
writeFileSync9(doorbell, String(Date.now()));
|
|
5720
5767
|
} catch (err) {
|
|
5721
5768
|
log(`[scheduled-kanban] doorbell ring failed for '${codeName}': ${err.message} (notice still queued)`);
|
|
5722
5769
|
}
|
|
@@ -5866,10 +5913,10 @@ async function processClaudeTaskResult(codeName, agentId, templateId, rawOutput,
|
|
|
5866
5913
|
|
|
5867
5914
|
// src/lib/manager/scheduler/execution.ts
|
|
5868
5915
|
import { createHash as createHash12 } from "crypto";
|
|
5869
|
-
import { homedir as
|
|
5870
|
-
import { join as
|
|
5916
|
+
import { homedir as homedir10 } from "os";
|
|
5917
|
+
import { join as join22 } from "path";
|
|
5871
5918
|
function claudePidFilePath() {
|
|
5872
|
-
return
|
|
5919
|
+
return join22(homedir10(), ".augmented", "manager-claude-pids.json");
|
|
5873
5920
|
}
|
|
5874
5921
|
var inFlightClaudePids = /* @__PURE__ */ new Map();
|
|
5875
5922
|
function registerClaudeSpawn(record) {
|
|
@@ -5908,6 +5955,15 @@ async function syncAndCheckClaudeScheduler(agent, tasks, boardItems, refreshData
|
|
|
5908
5955
|
const state7 = claudeSchedulerStates.get(codeName);
|
|
5909
5956
|
const ready = getReadyTasks(state7, inFlightClaudeTasks);
|
|
5910
5957
|
if (ready.length === 0) return;
|
|
5958
|
+
const limitedUntil = readUsageLimitUntil({ codeName });
|
|
5959
|
+
if (limitedUntil) {
|
|
5960
|
+
if (shouldLogUsageCapDeferral("claude-scheduler", codeName, limitedUntil)) {
|
|
5961
|
+
log(
|
|
5962
|
+
`[claude-scheduler] Deferring ${ready.length} ready task(s) for '${codeName}' \u2014 agent is at its Claude usage limit until ${limitedUntil.toISOString()}; schedule NOT advanced, will fire after the limit resets (further deferrals this window are not logged)`
|
|
5963
|
+
);
|
|
5964
|
+
}
|
|
5965
|
+
return;
|
|
5966
|
+
}
|
|
5911
5967
|
for (const task of ready) {
|
|
5912
5968
|
if ((claudeTaskConcurrency.get(codeName) ?? 0) >= MAX_CLAUDE_CONCURRENCY) break;
|
|
5913
5969
|
if (KANBAN_WORK_TEMPLATES.has(task.templateId)) {
|
|
@@ -7093,9 +7149,9 @@ async function fireOpencodeScheduledTask(agent, task) {
|
|
|
7093
7149
|
|
|
7094
7150
|
// src/lib/opencode-telegram-ingest.ts
|
|
7095
7151
|
import { createHash as createHash15 } from "crypto";
|
|
7096
|
-
import { existsSync as existsSync9, mkdirSync as
|
|
7152
|
+
import { existsSync as existsSync9, mkdirSync as mkdirSync8, readFileSync as readFileSync19, renameSync as renameSync3, unlinkSync as unlinkSync2, writeFileSync as writeFileSync10 } from "fs";
|
|
7097
7153
|
import { randomUUID } from "crypto";
|
|
7098
|
-
import { join as
|
|
7154
|
+
import { join as join23 } from "path";
|
|
7099
7155
|
|
|
7100
7156
|
// src/lib/telegram-ingest.ts
|
|
7101
7157
|
import https2 from "https";
|
|
@@ -7643,7 +7699,7 @@ function createFileOffsetStore(codeName, log2, currentBotId) {
|
|
|
7643
7699
|
let filePath;
|
|
7644
7700
|
try {
|
|
7645
7701
|
dir = getFramework("opencode").getAgentDir(codeName);
|
|
7646
|
-
filePath =
|
|
7702
|
+
filePath = join23(dir, "telegram-getupdates-offset-opencode.json");
|
|
7647
7703
|
} catch {
|
|
7648
7704
|
dir = null;
|
|
7649
7705
|
filePath = null;
|
|
@@ -7652,7 +7708,7 @@ function createFileOffsetStore(codeName, log2, currentBotId) {
|
|
|
7652
7708
|
load() {
|
|
7653
7709
|
if (!filePath) return 0;
|
|
7654
7710
|
try {
|
|
7655
|
-
const parsed = JSON.parse(
|
|
7711
|
+
const parsed = JSON.parse(readFileSync19(filePath, "utf-8"));
|
|
7656
7712
|
if (currentBotId != null && typeof parsed?.bot_id === "number" && parsed.bot_id !== currentBotId) {
|
|
7657
7713
|
log2(`[telegram-ingest:${codeName}] offset cursor belongs to a different bot; ignoring (bot swap)`);
|
|
7658
7714
|
return 0;
|
|
@@ -7670,8 +7726,8 @@ function createFileOffsetStore(codeName, log2, currentBotId) {
|
|
|
7670
7726
|
if (!filePath || !dir) return;
|
|
7671
7727
|
const tmpPath = `${filePath}.${process.pid}.${randomUUID()}.tmp`;
|
|
7672
7728
|
try {
|
|
7673
|
-
|
|
7674
|
-
|
|
7729
|
+
mkdirSync8(dir, { recursive: true, mode: 448 });
|
|
7730
|
+
writeFileSync10(
|
|
7675
7731
|
tmpPath,
|
|
7676
7732
|
JSON.stringify({
|
|
7677
7733
|
offset,
|
|
@@ -7902,15 +7958,15 @@ function partitionActionableByPoison(actionable, states, config2) {
|
|
|
7902
7958
|
}
|
|
7903
7959
|
|
|
7904
7960
|
// src/lib/restart-flags.ts
|
|
7905
|
-
import { existsSync as existsSync10, mkdirSync as
|
|
7906
|
-
import { homedir as
|
|
7907
|
-
import { join as
|
|
7961
|
+
import { existsSync as existsSync10, mkdirSync as mkdirSync9, readdirSync as readdirSync5, readFileSync as readFileSync20, renameSync as renameSync4, rmSync as rmSync5, writeFileSync as writeFileSync11 } from "fs";
|
|
7962
|
+
import { homedir as homedir11 } from "os";
|
|
7963
|
+
import { join as join24 } from "path";
|
|
7908
7964
|
import { randomUUID as randomUUID2 } from "crypto";
|
|
7909
7965
|
function restartFlagsDir() {
|
|
7910
|
-
return
|
|
7966
|
+
return join24(homedir11(), ".augmented", "restart-flags");
|
|
7911
7967
|
}
|
|
7912
7968
|
function flagPath(codeName) {
|
|
7913
|
-
return
|
|
7969
|
+
return join24(restartFlagsDir(), `${codeName}.flag`);
|
|
7914
7970
|
}
|
|
7915
7971
|
function readRestartFlags() {
|
|
7916
7972
|
const dir = restartFlagsDir();
|
|
@@ -7919,7 +7975,7 @@ function readRestartFlags() {
|
|
|
7919
7975
|
for (const entry of readdirSync5(dir)) {
|
|
7920
7976
|
if (!entry.endsWith(".flag")) continue;
|
|
7921
7977
|
try {
|
|
7922
|
-
const raw =
|
|
7978
|
+
const raw = readFileSync20(join24(dir, entry), "utf8");
|
|
7923
7979
|
const parsed = JSON.parse(raw);
|
|
7924
7980
|
if (typeof parsed.codeName !== "string" || parsed.codeName.length === 0) {
|
|
7925
7981
|
parsed.codeName = entry.replace(/\.flag$/, "");
|
|
@@ -7938,7 +7994,7 @@ function readRestartFlags() {
|
|
|
7938
7994
|
function deleteRestartFlag(codeName) {
|
|
7939
7995
|
const path = flagPath(codeName);
|
|
7940
7996
|
if (existsSync10(path)) {
|
|
7941
|
-
|
|
7997
|
+
rmSync5(path, { force: true });
|
|
7942
7998
|
}
|
|
7943
7999
|
}
|
|
7944
8000
|
|
|
@@ -8037,8 +8093,8 @@ async function sendError(flag, opts, text) {
|
|
|
8037
8093
|
}
|
|
8038
8094
|
|
|
8039
8095
|
// src/lib/restart-context.ts
|
|
8040
|
-
import { readdirSync as readdirSync6, readFileSync as
|
|
8041
|
-
import { dirname as dirname7, join as
|
|
8096
|
+
import { readdirSync as readdirSync6, readFileSync as readFileSync21, writeFileSync as writeFileSync12, mkdirSync as mkdirSync10, unlinkSync as unlinkSync3 } from "fs";
|
|
8097
|
+
import { dirname as dirname7, join as join25 } from "path";
|
|
8042
8098
|
var SLACK_PENDING_INBOUND_DIRNAME = "slack-pending-inbound";
|
|
8043
8099
|
var SLACK_RESTART_CONTEXT_DIRNAME = "slack-restart-context";
|
|
8044
8100
|
var MAX_TOPIC_CHARS = 140;
|
|
@@ -8050,10 +8106,10 @@ function augmentedAgentDir(codeName) {
|
|
|
8050
8106
|
return dirname7(getProjectDir(codeName));
|
|
8051
8107
|
}
|
|
8052
8108
|
function slackPendingInboundDir(codeName) {
|
|
8053
|
-
return
|
|
8109
|
+
return join25(augmentedAgentDir(codeName), SLACK_PENDING_INBOUND_DIRNAME);
|
|
8054
8110
|
}
|
|
8055
8111
|
function slackRestartContextDir(codeName) {
|
|
8056
|
-
return
|
|
8112
|
+
return join25(augmentedAgentDir(codeName), SLACK_RESTART_CONTEXT_DIRNAME);
|
|
8057
8113
|
}
|
|
8058
8114
|
function sanitizeTopic(raw) {
|
|
8059
8115
|
const cleaned = raw.replace(/\s+/g, " ").trim().replace(/[<>]/g, " ").replace(/\s+/g, " ").trim();
|
|
@@ -8095,7 +8151,7 @@ function safeReaddir(dir) {
|
|
|
8095
8151
|
}
|
|
8096
8152
|
function readStrandedMarker(path) {
|
|
8097
8153
|
try {
|
|
8098
|
-
const parsed = JSON.parse(
|
|
8154
|
+
const parsed = JSON.parse(readFileSync21(path, "utf-8"));
|
|
8099
8155
|
if (typeof parsed.channel === "string" && typeof parsed.thread_ts === "string") {
|
|
8100
8156
|
return { channel: parsed.channel, thread_ts: parsed.thread_ts };
|
|
8101
8157
|
}
|
|
@@ -8104,8 +8160,8 @@ function readStrandedMarker(path) {
|
|
|
8104
8160
|
return null;
|
|
8105
8161
|
}
|
|
8106
8162
|
function writeHintFile(path, dir, hint) {
|
|
8107
|
-
|
|
8108
|
-
|
|
8163
|
+
mkdirSync10(dir, { recursive: true, mode: 448 });
|
|
8164
|
+
writeFileSync12(path, JSON.stringify(hint), { mode: 384 });
|
|
8109
8165
|
}
|
|
8110
8166
|
function pruneHintsExcept(codeName, freshFilenames) {
|
|
8111
8167
|
const ctxDir = slackRestartContextDir(codeName);
|
|
@@ -8113,7 +8169,7 @@ function pruneHintsExcept(codeName, freshFilenames) {
|
|
|
8113
8169
|
if (!filename.endsWith(".json")) continue;
|
|
8114
8170
|
if (freshFilenames.has(filename)) continue;
|
|
8115
8171
|
try {
|
|
8116
|
-
unlinkSync3(
|
|
8172
|
+
unlinkSync3(join25(ctxDir, filename));
|
|
8117
8173
|
} catch {
|
|
8118
8174
|
}
|
|
8119
8175
|
}
|
|
@@ -8134,7 +8190,7 @@ function refreshSlackRestartContextHints(codeNames, opts = {}) {
|
|
|
8134
8190
|
}
|
|
8135
8191
|
const markers = [];
|
|
8136
8192
|
for (const filename of markerFilenames.slice(0, cap)) {
|
|
8137
|
-
const parsed = readStrandedMarker(
|
|
8193
|
+
const parsed = readStrandedMarker(join25(markerDir, filename));
|
|
8138
8194
|
if (parsed) markers.push({ filename, channel: parsed.channel, thread_ts: parsed.thread_ts });
|
|
8139
8195
|
}
|
|
8140
8196
|
if (markers.length === 0) {
|
|
@@ -8148,7 +8204,7 @@ function refreshSlackRestartContextHints(codeNames, opts = {}) {
|
|
|
8148
8204
|
const freshFilenames = /* @__PURE__ */ new Set();
|
|
8149
8205
|
for (const { filename, hint } of hints) {
|
|
8150
8206
|
try {
|
|
8151
|
-
writeHintFile(
|
|
8207
|
+
writeHintFile(join25(ctxDir, filename), ctxDir, hint);
|
|
8152
8208
|
freshFilenames.add(filename);
|
|
8153
8209
|
} catch (err) {
|
|
8154
8210
|
log2(`[restart-context] ${codeName}: hint write failed for ${filename}: ${err.message}`);
|
|
@@ -9379,7 +9435,7 @@ var runningChannelSecretHashes = /* @__PURE__ */ new Map();
|
|
|
9379
9435
|
var sessionLaunchManagedStructure = /* @__PURE__ */ new Map();
|
|
9380
9436
|
function projectMcpHash(_codeName, projectDir) {
|
|
9381
9437
|
try {
|
|
9382
|
-
const raw =
|
|
9438
|
+
const raw = readFileSync22(join26(projectDir, ".mcp.json"), "utf-8");
|
|
9383
9439
|
return createHash16("sha256").update(canonicalJson(JSON.parse(raw))).digest("hex");
|
|
9384
9440
|
} catch {
|
|
9385
9441
|
return null;
|
|
@@ -9387,7 +9443,7 @@ function projectMcpHash(_codeName, projectDir) {
|
|
|
9387
9443
|
}
|
|
9388
9444
|
function projectMcpKeys(_codeName, projectDir) {
|
|
9389
9445
|
try {
|
|
9390
|
-
const raw =
|
|
9446
|
+
const raw = readFileSync22(join26(projectDir, ".mcp.json"), "utf-8");
|
|
9391
9447
|
const parsed = JSON.parse(raw);
|
|
9392
9448
|
const servers = parsed.mcpServers;
|
|
9393
9449
|
if (!servers || typeof servers !== "object") return /* @__PURE__ */ new Set();
|
|
@@ -9405,7 +9461,7 @@ function seedSessionLaunchBaselines(codeName, projectDir) {
|
|
|
9405
9461
|
else runningMcpServerKeys.delete(codeName);
|
|
9406
9462
|
let launchStructure = null;
|
|
9407
9463
|
try {
|
|
9408
|
-
const raw =
|
|
9464
|
+
const raw = readFileSync22(join26(projectDir, ".mcp.json"), "utf-8");
|
|
9409
9465
|
launchStructure = managedMcpStructureHashFromFile(
|
|
9410
9466
|
JSON.parse(raw),
|
|
9411
9467
|
isManagedMcpServerKey
|
|
@@ -9509,7 +9565,7 @@ async function runAgentSessionToolBindProbes(agent, integrations, projectDir, op
|
|
|
9509
9565
|
if (result && result.rebindCandidates.length > 0 && hostFlagStore().getBoolean("session-tool-rebind")) {
|
|
9510
9566
|
let mcpJsonForRebind = null;
|
|
9511
9567
|
try {
|
|
9512
|
-
mcpJsonForRebind = JSON.parse(
|
|
9568
|
+
mcpJsonForRebind = JSON.parse(readFileSync22(join26(projectDir, ".mcp.json"), "utf-8"));
|
|
9513
9569
|
} catch {
|
|
9514
9570
|
mcpJsonForRebind = null;
|
|
9515
9571
|
}
|
|
@@ -9660,7 +9716,7 @@ function checkMcpConfigDriftAndScheduleRestart(codeName, projectDir) {
|
|
|
9660
9716
|
function projectChannelSecretHash(projectDir) {
|
|
9661
9717
|
try {
|
|
9662
9718
|
const entries = parseEnvIntegrations(
|
|
9663
|
-
|
|
9719
|
+
readFileSync22(join26(projectDir, ".env.integrations"), "utf-8")
|
|
9664
9720
|
);
|
|
9665
9721
|
return channelSecretValueHash(entries, CHANNEL_SECRET_ENV_KEYS);
|
|
9666
9722
|
} catch {
|
|
@@ -9756,7 +9812,7 @@ var agentRestartTimezoneInputs = /* @__PURE__ */ new Map();
|
|
|
9756
9812
|
var lastVersionCheckAt = 0;
|
|
9757
9813
|
var VERSION_CHECK_INTERVAL_MS = 5 * 60 * 1e3;
|
|
9758
9814
|
var lastResponsivenessProbeAt = 0;
|
|
9759
|
-
var agtCliVersion = true ? "0.28.
|
|
9815
|
+
var agtCliVersion = true ? "0.28.441" : "dev";
|
|
9760
9816
|
function resolveBrewPath(execFileSync2) {
|
|
9761
9817
|
try {
|
|
9762
9818
|
const out = execFileSync2("which", ["brew"], { timeout: 5e3 }).toString().trim();
|
|
@@ -10045,7 +10101,7 @@ function ensureClaudeManagedSettings(path = claudeManagedSettingsPath()) {
|
|
|
10045
10101
|
try {
|
|
10046
10102
|
let settings = {};
|
|
10047
10103
|
if (existsSync11(path)) {
|
|
10048
|
-
const raw =
|
|
10104
|
+
const raw = readFileSync22(path, "utf-8").trim();
|
|
10049
10105
|
if (raw) {
|
|
10050
10106
|
let parsed;
|
|
10051
10107
|
try {
|
|
@@ -10061,8 +10117,8 @@ function ensureClaudeManagedSettings(path = claudeManagedSettingsPath()) {
|
|
|
10061
10117
|
}
|
|
10062
10118
|
if (settings.channelsEnabled === true) return "ok";
|
|
10063
10119
|
settings.channelsEnabled = true;
|
|
10064
|
-
|
|
10065
|
-
|
|
10120
|
+
mkdirSync11(dirname8(path), { recursive: true });
|
|
10121
|
+
writeFileSync13(path, `${JSON.stringify(settings, null, 2)}
|
|
10066
10122
|
`);
|
|
10067
10123
|
log(`[managed-settings] set channelsEnabled:true in ${path} (ENG-5786 \u2014 unblocks Claude Code channels)`);
|
|
10068
10124
|
return "ok";
|
|
@@ -10100,7 +10156,7 @@ async function ensureOpencodeBinary() {
|
|
|
10100
10156
|
try {
|
|
10101
10157
|
const prefix = execFileSync2("npm", ["prefix", "-g"], { encoding: "utf-8", timeout: 1e4 }).trim();
|
|
10102
10158
|
if (prefix) {
|
|
10103
|
-
const npmBin =
|
|
10159
|
+
const npmBin = join26(prefix, "bin");
|
|
10104
10160
|
const current = (process.env.PATH ?? "").split(pathDelimiter);
|
|
10105
10161
|
if (!current.includes(npmBin)) {
|
|
10106
10162
|
process.env.PATH = [npmBin, ...current.filter(Boolean)].join(pathDelimiter);
|
|
@@ -10217,7 +10273,7 @@ ${r.stderr}`;
|
|
|
10217
10273
|
}
|
|
10218
10274
|
var UPDATE_CHECK_INTERVAL_MS = 5 * 60 * 1e3;
|
|
10219
10275
|
function selfUpdateAppliedMarkerPath() {
|
|
10220
|
-
return
|
|
10276
|
+
return join26(homedir12(), ".augmented", ".last-self-update-applied");
|
|
10221
10277
|
}
|
|
10222
10278
|
var selfUpdateUpToDateLogged = false;
|
|
10223
10279
|
var selfUpdatePinnedLogged = false;
|
|
@@ -10245,7 +10301,7 @@ async function checkAndUpdateCli(opts) {
|
|
|
10245
10301
|
const isNpmGlobal = !isBrewFormula && resolvedPath.includes("node_modules");
|
|
10246
10302
|
if (!isBrewFormula && !isNpmGlobal) return "noop";
|
|
10247
10303
|
const { readFileSync: readF, writeFileSync: writeF } = await import("fs");
|
|
10248
|
-
const markerPath =
|
|
10304
|
+
const markerPath = join26(homedir12(), ".augmented", ".last-update-check");
|
|
10249
10305
|
if (!force) {
|
|
10250
10306
|
try {
|
|
10251
10307
|
const lastCheck = parseInt(readF(markerPath, "utf-8").trim(), 10);
|
|
@@ -10605,13 +10661,13 @@ async function checkClaudeAuth() {
|
|
|
10605
10661
|
var evalEmptyMcpConfigPath = null;
|
|
10606
10662
|
function ensureEvalEmptyMcpConfig() {
|
|
10607
10663
|
if (evalEmptyMcpConfigPath && existsSync11(evalEmptyMcpConfigPath)) return evalEmptyMcpConfigPath;
|
|
10608
|
-
const dir =
|
|
10664
|
+
const dir = join26(homedir12(), ".augmented");
|
|
10609
10665
|
try {
|
|
10610
|
-
|
|
10666
|
+
mkdirSync11(dir, { recursive: true });
|
|
10611
10667
|
} catch {
|
|
10612
10668
|
}
|
|
10613
|
-
const p =
|
|
10614
|
-
|
|
10669
|
+
const p = join26(dir, ".eval-empty-mcp.json");
|
|
10670
|
+
writeFileSync13(p, JSON.stringify({ mcpServers: {} }));
|
|
10615
10671
|
evalEmptyMcpConfigPath = p;
|
|
10616
10672
|
return p;
|
|
10617
10673
|
}
|
|
@@ -10636,7 +10692,7 @@ async function runEvalClaude(prompt, model) {
|
|
|
10636
10692
|
""
|
|
10637
10693
|
];
|
|
10638
10694
|
const { stdout } = await execFilePromiseLong(resolveClaudeBinary(), args, {
|
|
10639
|
-
cwd:
|
|
10695
|
+
cwd: homedir12(),
|
|
10640
10696
|
timeout: 12e4,
|
|
10641
10697
|
stdin: "ignore",
|
|
10642
10698
|
env: childEnv,
|
|
@@ -10702,10 +10758,10 @@ function resolveConversationEvalBackend() {
|
|
|
10702
10758
|
return conversationEvalBackend;
|
|
10703
10759
|
}
|
|
10704
10760
|
function getStateFile() {
|
|
10705
|
-
return
|
|
10761
|
+
return join26(config?.configDir ?? join26(process.env["HOME"] ?? "/tmp", ".augmented"), "manager-state.json");
|
|
10706
10762
|
}
|
|
10707
10763
|
function channelHashCacheDir() {
|
|
10708
|
-
return config?.configDir ??
|
|
10764
|
+
return config?.configDir ?? join26(process.env["HOME"] ?? "/tmp", ".augmented");
|
|
10709
10765
|
}
|
|
10710
10766
|
function loadChannelHashCache2() {
|
|
10711
10767
|
loadChannelHashCache(agentState.knownChannelConfigHashes, channelHashCacheDir());
|
|
@@ -10757,7 +10813,7 @@ function removeDeliveryBaselineEntries(agentId) {
|
|
|
10757
10813
|
var _channelQuarantineStore = null;
|
|
10758
10814
|
function channelQuarantineStore() {
|
|
10759
10815
|
if (!_channelQuarantineStore) {
|
|
10760
|
-
const dir = config?.configDir ??
|
|
10816
|
+
const dir = config?.configDir ?? join26(process.env["HOME"] ?? "/tmp", ".augmented");
|
|
10761
10817
|
_channelQuarantineStore = new ChannelQuarantineStore(defaultQuarantinePath(dir));
|
|
10762
10818
|
}
|
|
10763
10819
|
return _channelQuarantineStore;
|
|
@@ -10774,7 +10830,7 @@ function claudeMdSizeFor(codeName) {
|
|
|
10774
10830
|
var _hostFlagStore = null;
|
|
10775
10831
|
function hostFlagStore() {
|
|
10776
10832
|
if (!_hostFlagStore) {
|
|
10777
|
-
const dir = config?.configDir ??
|
|
10833
|
+
const dir = config?.configDir ?? join26(process.env["HOME"] ?? "/tmp", ".augmented");
|
|
10778
10834
|
_hostFlagStore = new HostFlagStore({ cachePath: defaultFlagsCachePath(dir), log });
|
|
10779
10835
|
}
|
|
10780
10836
|
return _hostFlagStore;
|
|
@@ -10841,13 +10897,13 @@ function parseSkillFrontmatter(content) {
|
|
|
10841
10897
|
return out;
|
|
10842
10898
|
}
|
|
10843
10899
|
async function refreshSkillsIndexInClaudeMd(configDir, codeName, log2) {
|
|
10844
|
-
const { readdirSync: readdirSync8, readFileSync: rfs, existsSync: ex, writeFileSync:
|
|
10845
|
-
const skillsDir =
|
|
10846
|
-
const claudeMdPath =
|
|
10900
|
+
const { readdirSync: readdirSync8, readFileSync: rfs, existsSync: ex, writeFileSync: writeFileSync14 } = await import("fs");
|
|
10901
|
+
const skillsDir = join26(configDir, codeName, "project", ".claude", "skills");
|
|
10902
|
+
const claudeMdPath = join26(configDir, codeName, "project", "CLAUDE.md");
|
|
10847
10903
|
if (!ex(skillsDir) || !ex(claudeMdPath)) return;
|
|
10848
10904
|
const entries = [];
|
|
10849
10905
|
for (const dir of readdirSync8(skillsDir).sort()) {
|
|
10850
|
-
const skillFile =
|
|
10906
|
+
const skillFile = join26(skillsDir, dir, "SKILL.md");
|
|
10851
10907
|
if (!ex(skillFile)) continue;
|
|
10852
10908
|
try {
|
|
10853
10909
|
const { name, description } = parseSkillFrontmatter(rfs(skillFile, "utf-8"));
|
|
@@ -10891,7 +10947,7 @@ ${SKILLS_INDEX_END}`;
|
|
|
10891
10947
|
next = current.trimEnd() + "\n\n" + section + "\n";
|
|
10892
10948
|
}
|
|
10893
10949
|
if (next !== current) {
|
|
10894
|
-
|
|
10950
|
+
writeFileSync14(claudeMdPath, next, "utf-8");
|
|
10895
10951
|
log2(
|
|
10896
10952
|
injectSkillList ? `Refreshed skills index in CLAUDE.md for '${codeName}' (${entries.length} skills)` : `Refreshed CLAUDE.md managed block for '${codeName}' (skill list suppressed by claude-md-skills-index=false; ${entries.length} skills on disk)`
|
|
10897
10953
|
);
|
|
@@ -10914,7 +10970,7 @@ function flushRestartedAgentDiagnostics(hostId, codeNames) {
|
|
|
10914
10970
|
if (codeNames.length === 0) return;
|
|
10915
10971
|
void (async () => {
|
|
10916
10972
|
try {
|
|
10917
|
-
const { collectDiagnostics } = await import("../persistent-session-
|
|
10973
|
+
const { collectDiagnostics } = await import("../persistent-session-PWLMLDVX.js");
|
|
10918
10974
|
await api.post("/host/heartbeat", {
|
|
10919
10975
|
host_id: hostId,
|
|
10920
10976
|
agent_diagnostics: collectDiagnostics(codeNames, quarantineEntriesFor, claudeMdSizeFor)
|
|
@@ -11021,7 +11077,7 @@ async function pollCycle() {
|
|
|
11021
11077
|
}
|
|
11022
11078
|
try {
|
|
11023
11079
|
const { detectHostSecurity } = await import("../host-security-6PDFG7F5.js");
|
|
11024
|
-
const { collectDiagnostics } = await import("../persistent-session-
|
|
11080
|
+
const { collectDiagnostics } = await import("../persistent-session-PWLMLDVX.js");
|
|
11025
11081
|
const diagCodeNames = [...agentState.persistentSessionAgents];
|
|
11026
11082
|
const agentDiagnostics = diagCodeNames.length > 0 ? collectDiagnostics(diagCodeNames, quarantineEntriesFor, claudeMdSizeFor) : void 0;
|
|
11027
11083
|
let tailscaleHostname;
|
|
@@ -11135,7 +11191,7 @@ async function pollCycle() {
|
|
|
11135
11191
|
collectResponsivenessProbes,
|
|
11136
11192
|
collectPanelessActivityProbes,
|
|
11137
11193
|
getResponsivenessIntervalMs
|
|
11138
|
-
} = await import("../responsiveness-probe-
|
|
11194
|
+
} = await import("../responsiveness-probe-ZKUDFRIU.js");
|
|
11139
11195
|
const probeIntervalMs = getResponsivenessIntervalMs();
|
|
11140
11196
|
if (now - lastResponsivenessProbeAt > probeIntervalMs) {
|
|
11141
11197
|
const probeCodeNames = [...agentState.persistentSessionAgents];
|
|
@@ -11199,7 +11255,7 @@ async function pollCycle() {
|
|
|
11199
11255
|
collectResponsivenessProbes,
|
|
11200
11256
|
livePendingInboundOldestAgeSeconds,
|
|
11201
11257
|
parkPendingInbound
|
|
11202
|
-
} = await import("../responsiveness-probe-
|
|
11258
|
+
} = await import("../responsiveness-probe-ZKUDFRIU.js");
|
|
11203
11259
|
const { getProjectDir: wedgeProjectDir } = await import("../scheduler-engine-NDP36U7O.js");
|
|
11204
11260
|
const wedgeNow = /* @__PURE__ */ new Date();
|
|
11205
11261
|
const liveAgents = agentState.persistentSessionAgents;
|
|
@@ -11288,13 +11344,13 @@ async function pollCycle() {
|
|
|
11288
11344
|
);
|
|
11289
11345
|
if (hostFlagStore().getBoolean("wedge-transient-notice")) {
|
|
11290
11346
|
try {
|
|
11291
|
-
const paneTail =
|
|
11347
|
+
const paneTail = readFileSync22(paneLogPath(codeName), "utf8").slice(-65536);
|
|
11292
11348
|
const transient = detectTransientApiErrorInLog(paneTail);
|
|
11293
11349
|
if (transient) {
|
|
11294
|
-
const wedgeHome =
|
|
11350
|
+
const wedgeHome = join26(homedir12(), ".augmented", codeName);
|
|
11295
11351
|
if (existsSync11(wedgeHome)) {
|
|
11296
11352
|
atomicWriteFileSync(
|
|
11297
|
-
|
|
11353
|
+
join26(wedgeHome, "watchdog-give-up.json"),
|
|
11298
11354
|
JSON.stringify({
|
|
11299
11355
|
gave_up_at: wedgeNow.toISOString(),
|
|
11300
11356
|
reason: "transient_overload"
|
|
@@ -11565,8 +11621,8 @@ async function pollCycle() {
|
|
|
11565
11621
|
const adapter = resolveAgentFramework(prev.codeName);
|
|
11566
11622
|
stopAgentRuntime2(prev.codeName, "removed-from-host");
|
|
11567
11623
|
killAgentChannelProcesses(prev.codeName, { log });
|
|
11568
|
-
const
|
|
11569
|
-
await cleanupAgentFiles(prev.codeName,
|
|
11624
|
+
const agentDir2 = join26(adapter.getAgentDir(prev.codeName), "provision");
|
|
11625
|
+
await cleanupAgentFiles(prev.codeName, agentDir2);
|
|
11570
11626
|
clearAgentCaches(prev.agentId, prev.codeName);
|
|
11571
11627
|
}
|
|
11572
11628
|
}
|
|
@@ -11652,10 +11708,10 @@ async function pollCycle() {
|
|
|
11652
11708
|
// pending-inbound marker. Best-effort: a write failure is logged by
|
|
11653
11709
|
// the watchdog, never fails the poll cycle.
|
|
11654
11710
|
signalGiveUp: (codeName) => {
|
|
11655
|
-
const dir =
|
|
11711
|
+
const dir = join26(homedir12(), ".augmented", codeName);
|
|
11656
11712
|
if (!existsSync11(dir)) return;
|
|
11657
11713
|
atomicWriteFileSync(
|
|
11658
|
-
|
|
11714
|
+
join26(dir, "watchdog-give-up.json"),
|
|
11659
11715
|
JSON.stringify({ gave_up_at: (/* @__PURE__ */ new Date()).toISOString() })
|
|
11660
11716
|
);
|
|
11661
11717
|
}
|
|
@@ -11795,7 +11851,7 @@ async function processAgent(agent, agentStates) {
|
|
|
11795
11851
|
}
|
|
11796
11852
|
const now = (/* @__PURE__ */ new Date()).toISOString();
|
|
11797
11853
|
const adapter = resolveAgentFramework(agent.code_name);
|
|
11798
|
-
let
|
|
11854
|
+
let agentDir2 = join26(adapter.getAgentDir(agent.code_name), "provision");
|
|
11799
11855
|
if (agent.status === "draft" || agent.status === "paused") {
|
|
11800
11856
|
if (previousKnownStatus !== agent.status) {
|
|
11801
11857
|
log(`Agent '${agent.code_name}' is ${agent.status}, skipping provisioning`);
|
|
@@ -11835,7 +11891,7 @@ async function processAgent(agent, agentStates) {
|
|
|
11835
11891
|
const residuals = {
|
|
11836
11892
|
gatewayRunning: false,
|
|
11837
11893
|
portAllocated: false,
|
|
11838
|
-
provisionDirExists: existsSync11(
|
|
11894
|
+
provisionDirExists: existsSync11(agentDir2)
|
|
11839
11895
|
};
|
|
11840
11896
|
if (!hasRevokedResiduals(residuals)) {
|
|
11841
11897
|
agentStates.push({
|
|
@@ -11860,7 +11916,7 @@ async function processAgent(agent, agentStates) {
|
|
|
11860
11916
|
log(`Agent '${agent.code_name}' is revoked, cleaning up`);
|
|
11861
11917
|
stopAgentRuntime2(agent.code_name, "revoked");
|
|
11862
11918
|
killAgentChannelProcesses(agent.code_name, { log });
|
|
11863
|
-
await cleanupAgentFiles(agent.code_name,
|
|
11919
|
+
await cleanupAgentFiles(agent.code_name, agentDir2);
|
|
11864
11920
|
clearAgentCaches(agent.agent_id, agent.code_name);
|
|
11865
11921
|
agentState.knownStatuses.set(agent.agent_id, agent.status);
|
|
11866
11922
|
agentStates.push({
|
|
@@ -11968,7 +12024,7 @@ async function processAgent(agent, agentStates) {
|
|
|
11968
12024
|
const frameworkId = refreshData.agent.framework ?? DEFAULT_FRAMEWORK;
|
|
11969
12025
|
agentFrameworkCache.set(agent.code_name, frameworkId);
|
|
11970
12026
|
const frameworkAdapter = getFramework(frameworkId);
|
|
11971
|
-
|
|
12027
|
+
agentDir2 = join26(frameworkAdapter.getAgentDir(agent.code_name), "provision");
|
|
11972
12028
|
cacheAgentDeliveryMetadata(agent.code_name, refreshData);
|
|
11973
12029
|
agentRestartTimezoneInputs.set(agent.code_name, {
|
|
11974
12030
|
agentTimezone: typeof refreshData.agent.timezone === "string" ? refreshData.agent.timezone : null,
|
|
@@ -12015,9 +12071,9 @@ async function processAgent(agent, agentStates) {
|
|
|
12015
12071
|
try {
|
|
12016
12072
|
const artifacts = generateArtifacts(agent, refreshData, frameworkAdapter);
|
|
12017
12073
|
const changedFiles = [];
|
|
12018
|
-
|
|
12074
|
+
mkdirSync11(agentDir2, { recursive: true });
|
|
12019
12075
|
for (const artifact of artifacts) {
|
|
12020
|
-
const filePath =
|
|
12076
|
+
const filePath = join26(agentDir2, artifact.relativePath);
|
|
12021
12077
|
let existingHash;
|
|
12022
12078
|
let newHash;
|
|
12023
12079
|
let writeContent = artifact.content;
|
|
@@ -12036,8 +12092,8 @@ async function processAgent(agent, agentStates) {
|
|
|
12036
12092
|
};
|
|
12037
12093
|
newHash = sha256(stripDynamicSections(artifact.content));
|
|
12038
12094
|
try {
|
|
12039
|
-
const projectClaudeMd =
|
|
12040
|
-
const existing =
|
|
12095
|
+
const projectClaudeMd = join26(config.configDir, agent.code_name, "project", "CLAUDE.md");
|
|
12096
|
+
const existing = readFileSync22(projectClaudeMd, "utf-8");
|
|
12041
12097
|
existingHash = sha256(stripDynamicSections(existing));
|
|
12042
12098
|
} catch {
|
|
12043
12099
|
existingHash = null;
|
|
@@ -12055,7 +12111,7 @@ async function processAgent(agent, agentStates) {
|
|
|
12055
12111
|
const generatorKeys = Object.keys(generatorServers);
|
|
12056
12112
|
let existingRaw = "";
|
|
12057
12113
|
try {
|
|
12058
|
-
existingRaw =
|
|
12114
|
+
existingRaw = readFileSync22(filePath, "utf-8");
|
|
12059
12115
|
} catch {
|
|
12060
12116
|
}
|
|
12061
12117
|
const existingServers = parseMcp(existingRaw);
|
|
@@ -12071,7 +12127,7 @@ async function processAgent(agent, agentStates) {
|
|
|
12071
12127
|
} else if (artifact.relativePath === "opencode.json") {
|
|
12072
12128
|
let existingRaw = null;
|
|
12073
12129
|
try {
|
|
12074
|
-
existingRaw =
|
|
12130
|
+
existingRaw = readFileSync22(filePath, "utf-8");
|
|
12075
12131
|
} catch {
|
|
12076
12132
|
}
|
|
12077
12133
|
const mergeResult = mergeOpencodeConfigArtifact(artifact.content, existingRaw);
|
|
@@ -12087,26 +12143,26 @@ async function processAgent(agent, agentStates) {
|
|
|
12087
12143
|
}
|
|
12088
12144
|
}
|
|
12089
12145
|
if (changedFiles.length > 0) {
|
|
12090
|
-
const isFirst = !existsSync11(
|
|
12146
|
+
const isFirst = !existsSync11(join26(agentDir2, "CHARTER.md"));
|
|
12091
12147
|
const verb = isFirst ? "Provisioning" : "Updating";
|
|
12092
12148
|
const fileNames = changedFiles.map((f) => f.relativePath).join(", ");
|
|
12093
12149
|
log(`${verb} '${agent.code_name}': ${fileNames}`);
|
|
12094
12150
|
for (const file of changedFiles) {
|
|
12095
|
-
const filePath =
|
|
12096
|
-
|
|
12151
|
+
const filePath = join26(agentDir2, file.relativePath);
|
|
12152
|
+
mkdirSync11(dirname8(filePath), { recursive: true });
|
|
12097
12153
|
if (file.relativePath === ".mcp.json") {
|
|
12098
12154
|
safeWriteJsonAtomic(filePath, file.content, { mode: 384 });
|
|
12099
12155
|
} else {
|
|
12100
|
-
|
|
12156
|
+
writeFileSync13(filePath, file.content);
|
|
12101
12157
|
}
|
|
12102
12158
|
}
|
|
12103
12159
|
try {
|
|
12104
|
-
const provSkillsDir =
|
|
12160
|
+
const provSkillsDir = join26(agentDir2, ".claude", "skills");
|
|
12105
12161
|
if (existsSync11(provSkillsDir)) {
|
|
12106
12162
|
for (const folder of readdirSync7(provSkillsDir)) {
|
|
12107
12163
|
if (folder.startsWith("knowledge-")) {
|
|
12108
12164
|
try {
|
|
12109
|
-
|
|
12165
|
+
rmSync6(join26(provSkillsDir, folder), { recursive: true });
|
|
12110
12166
|
} catch {
|
|
12111
12167
|
}
|
|
12112
12168
|
}
|
|
@@ -12119,7 +12175,7 @@ async function processAgent(agent, agentStates) {
|
|
|
12119
12175
|
const trackedFiles2 = frameworkAdapter.driftTrackedFiles();
|
|
12120
12176
|
const hashes = /* @__PURE__ */ new Map();
|
|
12121
12177
|
for (const file of trackedFiles2) {
|
|
12122
|
-
const h = hashFile(
|
|
12178
|
+
const h = hashFile(join26(agentDir2, file));
|
|
12123
12179
|
if (h) hashes.set(file, h);
|
|
12124
12180
|
}
|
|
12125
12181
|
agentState.writtenHashes.set(agent.agent_id, hashes);
|
|
@@ -12127,7 +12183,7 @@ async function processAgent(agent, agentStates) {
|
|
|
12127
12183
|
const primaryModel2 = resolvedModelsForRegistration.primary ?? refreshData.agent.primary_model;
|
|
12128
12184
|
const registeredAgents = await getOrCacheRegisteredAgents(frameworkAdapter, agent.code_name);
|
|
12129
12185
|
if (!registeredAgents.has(agent.code_name)) {
|
|
12130
|
-
const registered = await frameworkAdapter.registerAgent(agent.code_name,
|
|
12186
|
+
const registered = await frameworkAdapter.registerAgent(agent.code_name, agentDir2, primaryModel2, agent.agent_id);
|
|
12131
12187
|
if (registered) {
|
|
12132
12188
|
registeredAgents.add(agent.code_name);
|
|
12133
12189
|
log(`Registered '${agent.code_name}' in ${frameworkAdapter.label}`);
|
|
@@ -12137,14 +12193,14 @@ async function processAgent(agent, agentStates) {
|
|
|
12137
12193
|
}
|
|
12138
12194
|
if (Array.isArray(refreshData.workflows)) {
|
|
12139
12195
|
try {
|
|
12140
|
-
const provWorkflowsDir =
|
|
12196
|
+
const provWorkflowsDir = join26(agentDir2, ".claude", "workflows");
|
|
12141
12197
|
if (existsSync11(provWorkflowsDir)) {
|
|
12142
12198
|
const expected = new Set(refreshData.workflows.map((w) => `${w.name}.js`));
|
|
12143
12199
|
for (const file of readdirSync7(provWorkflowsDir)) {
|
|
12144
12200
|
if (!file.endsWith(".js")) continue;
|
|
12145
12201
|
if (expected.has(file)) continue;
|
|
12146
12202
|
try {
|
|
12147
|
-
|
|
12203
|
+
rmSync6(join26(provWorkflowsDir, file));
|
|
12148
12204
|
} catch {
|
|
12149
12205
|
}
|
|
12150
12206
|
}
|
|
@@ -12153,7 +12209,7 @@ async function processAgent(agent, agentStates) {
|
|
|
12153
12209
|
}
|
|
12154
12210
|
}
|
|
12155
12211
|
if (frameworkAdapter.deployArtifactsToProject) {
|
|
12156
|
-
frameworkAdapter.deployArtifactsToProject(agent.code_name,
|
|
12212
|
+
frameworkAdapter.deployArtifactsToProject(agent.code_name, agentDir2);
|
|
12157
12213
|
}
|
|
12158
12214
|
} catch (err) {
|
|
12159
12215
|
log(`Provision failed for '${agent.code_name}': ${err.message}`);
|
|
@@ -12223,10 +12279,10 @@ async function processAgent(agent, agentStates) {
|
|
|
12223
12279
|
}
|
|
12224
12280
|
let lastDriftCheckAt = now;
|
|
12225
12281
|
const written = agentState.writtenHashes.get(agent.agent_id);
|
|
12226
|
-
if (written && existsSync11(
|
|
12282
|
+
if (written && existsSync11(agentDir2)) {
|
|
12227
12283
|
const driftedFiles = [];
|
|
12228
12284
|
for (const [file, expectedHash] of written) {
|
|
12229
|
-
const localHash = hashFile(
|
|
12285
|
+
const localHash = hashFile(join26(agentDir2, file));
|
|
12230
12286
|
if (localHash && localHash !== expectedHash) {
|
|
12231
12287
|
driftedFiles.push(file);
|
|
12232
12288
|
}
|
|
@@ -12237,7 +12293,7 @@ async function processAgent(agent, agentStates) {
|
|
|
12237
12293
|
try {
|
|
12238
12294
|
const localHashes = {};
|
|
12239
12295
|
for (const file of driftedFiles) {
|
|
12240
|
-
localHashes[file] = hashFile(
|
|
12296
|
+
localHashes[file] = hashFile(join26(agentDir2, file));
|
|
12241
12297
|
}
|
|
12242
12298
|
await api.post("/host/drift", {
|
|
12243
12299
|
agent_id: agent.agent_id,
|
|
@@ -12424,15 +12480,15 @@ async function processAgent(agent, agentStates) {
|
|
|
12424
12480
|
const addedChannels = [...restartDecision.added];
|
|
12425
12481
|
const writeDmNoticeMarkers = isChannelAddRestart ? () => {
|
|
12426
12482
|
try {
|
|
12427
|
-
const agentAugmentedDir =
|
|
12428
|
-
|
|
12483
|
+
const agentAugmentedDir = join26(homedir12(), ".augmented", agent.code_name);
|
|
12484
|
+
mkdirSync11(agentAugmentedDir, { recursive: true });
|
|
12429
12485
|
const markerJson = JSON.stringify({
|
|
12430
12486
|
version: 1,
|
|
12431
12487
|
at: (/* @__PURE__ */ new Date()).toISOString(),
|
|
12432
12488
|
added: addedChannels
|
|
12433
12489
|
});
|
|
12434
12490
|
for (const file of ["slack-channel-add-restart.json", "telegram-channel-add-restart.json"]) {
|
|
12435
|
-
atomicWriteFileSync(
|
|
12491
|
+
atomicWriteFileSync(join26(agentAugmentedDir, file), markerJson);
|
|
12436
12492
|
}
|
|
12437
12493
|
} catch (err) {
|
|
12438
12494
|
log(`[hot-reload] channel-add DM-notice marker write failed for '${agent.code_name}' (non-fatal): ${err.message}`);
|
|
@@ -12620,19 +12676,19 @@ async function processAgent(agent, agentStates) {
|
|
|
12620
12676
|
const agentSessionMode = refreshData.agent.session_mode;
|
|
12621
12677
|
if (agentSessionMode === "persistent" && (agentFrameworkCache.get(agent.code_name) ?? DEFAULT_FRAMEWORK) === "claude-code") {
|
|
12622
12678
|
try {
|
|
12623
|
-
const agentProvisionDir =
|
|
12624
|
-
const projectDir =
|
|
12625
|
-
|
|
12626
|
-
|
|
12627
|
-
const provisionMcpPath =
|
|
12628
|
-
const projectMcpPath =
|
|
12679
|
+
const agentProvisionDir = agentDir2;
|
|
12680
|
+
const projectDir = join26(homedir12(), ".augmented", agent.code_name, "project");
|
|
12681
|
+
mkdirSync11(agentProvisionDir, { recursive: true });
|
|
12682
|
+
mkdirSync11(projectDir, { recursive: true });
|
|
12683
|
+
const provisionMcpPath = join26(agentProvisionDir, ".mcp.json");
|
|
12684
|
+
const projectMcpPath = join26(projectDir, ".mcp.json");
|
|
12629
12685
|
let mcpConfig = { mcpServers: {} };
|
|
12630
12686
|
try {
|
|
12631
|
-
mcpConfig = JSON.parse(
|
|
12687
|
+
mcpConfig = JSON.parse(readFileSync22(provisionMcpPath, "utf-8"));
|
|
12632
12688
|
if (!mcpConfig.mcpServers) mcpConfig.mcpServers = {};
|
|
12633
12689
|
} catch {
|
|
12634
12690
|
}
|
|
12635
|
-
const localDirectChatChannel =
|
|
12691
|
+
const localDirectChatChannel = join26(homedir12(), ".augmented", "_mcp", "direct-chat-channel.js");
|
|
12636
12692
|
const directChatTeamSettings = refreshData.team?.settings;
|
|
12637
12693
|
const directChatTz = (() => {
|
|
12638
12694
|
const tz = directChatTeamSettings?.["timezone"];
|
|
@@ -12658,7 +12714,7 @@ async function processAgent(agent, agentStates) {
|
|
|
12658
12714
|
// ~/.augmented/<codeName>/.current-turn-initiator.json. Note getAgentDir
|
|
12659
12715
|
// returns the agent root (NOT the /provision subdir `agentDir` points at),
|
|
12660
12716
|
// so it byte-matches the broker readers' path.
|
|
12661
|
-
AGT_TURN_INITIATOR_FILE:
|
|
12717
|
+
AGT_TURN_INITIATOR_FILE: join26(
|
|
12662
12718
|
frameworkAdapter.getAgentDir(agent.code_name),
|
|
12663
12719
|
".current-turn-initiator.json"
|
|
12664
12720
|
)
|
|
@@ -12678,10 +12734,10 @@ async function processAgent(agent, agentStates) {
|
|
|
12678
12734
|
log(`Channel credentials written for '${agent.code_name}/direct-chat'`);
|
|
12679
12735
|
}
|
|
12680
12736
|
}
|
|
12681
|
-
const staleChannelsPath =
|
|
12737
|
+
const staleChannelsPath = join26(projectDir, ".mcp-channels.json");
|
|
12682
12738
|
if (existsSync11(staleChannelsPath)) {
|
|
12683
12739
|
try {
|
|
12684
|
-
|
|
12740
|
+
rmSync6(staleChannelsPath, { force: true });
|
|
12685
12741
|
} catch {
|
|
12686
12742
|
}
|
|
12687
12743
|
}
|
|
@@ -12768,7 +12824,7 @@ async function processAgent(agent, agentStates) {
|
|
|
12768
12824
|
}
|
|
12769
12825
|
if (hostFlagStore().getBoolean("connectivity-probe")) {
|
|
12770
12826
|
try {
|
|
12771
|
-
const probeProjectDir =
|
|
12827
|
+
const probeProjectDir = join26(homedir12(), ".augmented", agent.code_name, "project");
|
|
12772
12828
|
let probeSet = integrations;
|
|
12773
12829
|
try {
|
|
12774
12830
|
const quarantined = await api.post("/host/agent-integrations/quarantined", { agent_id: agent.agent_id });
|
|
@@ -12814,7 +12870,7 @@ async function processAgent(agent, agentStates) {
|
|
|
12814
12870
|
const forceDue = attemptsLeft > 0;
|
|
12815
12871
|
let probeRan = false;
|
|
12816
12872
|
try {
|
|
12817
|
-
const probeProjectDir =
|
|
12873
|
+
const probeProjectDir = join26(homedir12(), ".augmented", agent.code_name, "project");
|
|
12818
12874
|
probeRan = await runAgentSessionToolBindProbes(agent, integrations, probeProjectDir, { forceDue });
|
|
12819
12875
|
} catch (err) {
|
|
12820
12876
|
log(`Session-tool-bind probe failed for '${agent.code_name}': ${err.message}`);
|
|
@@ -12889,11 +12945,11 @@ async function processAgent(agent, agentStates) {
|
|
|
12889
12945
|
const intHash = computeIntegrationsHash(integrations);
|
|
12890
12946
|
const prevIntHash = agentState.knownIntegrationHashes.get(agent.agent_id);
|
|
12891
12947
|
if (intHash !== prevIntHash) {
|
|
12892
|
-
const projectDir =
|
|
12893
|
-
const envIntPath =
|
|
12948
|
+
const projectDir = join26(homedir12(), ".augmented", agent.code_name, "project");
|
|
12949
|
+
const envIntPath = join26(projectDir, ".env.integrations");
|
|
12894
12950
|
let preWriteEnv;
|
|
12895
12951
|
try {
|
|
12896
|
-
preWriteEnv =
|
|
12952
|
+
preWriteEnv = readFileSync22(envIntPath, "utf-8");
|
|
12897
12953
|
} catch {
|
|
12898
12954
|
preWriteEnv = void 0;
|
|
12899
12955
|
}
|
|
@@ -12910,9 +12966,9 @@ async function processAgent(agent, agentStates) {
|
|
|
12910
12966
|
}
|
|
12911
12967
|
if (fw === "claude-code" && isSessionHealthy(agent.code_name)) {
|
|
12912
12968
|
try {
|
|
12913
|
-
const projectMcpPath =
|
|
12914
|
-
const postWriteEnv =
|
|
12915
|
-
const mcpContent =
|
|
12969
|
+
const projectMcpPath = join26(projectDir, ".mcp.json");
|
|
12970
|
+
const postWriteEnv = readFileSync22(envIntPath, "utf-8");
|
|
12971
|
+
const mcpContent = readFileSync22(projectMcpPath, "utf-8");
|
|
12916
12972
|
const changedVars = diffEnvIntegrations(preWriteEnv, postWriteEnv);
|
|
12917
12973
|
const mcpJsonForReap = JSON.parse(mcpContent);
|
|
12918
12974
|
const affectedServerKeys = findMcpServersUsingVars(mcpJsonForReap, changedVars);
|
|
@@ -13158,17 +13214,17 @@ async function processAgent(agent, agentStates) {
|
|
|
13158
13214
|
}
|
|
13159
13215
|
}
|
|
13160
13216
|
try {
|
|
13161
|
-
const { readdirSync: readdirSync8, rmSync:
|
|
13162
|
-
const { homedir:
|
|
13217
|
+
const { readdirSync: readdirSync8, rmSync: rmSync7 } = await import("fs");
|
|
13218
|
+
const { homedir: homedir13 } = await import("os");
|
|
13163
13219
|
const frameworkId2 = frameworkAdapter.id;
|
|
13164
13220
|
const candidateSkillDirs = [
|
|
13165
13221
|
// Claude Code — framework runtime tree
|
|
13166
|
-
|
|
13222
|
+
join26(homedir13(), ".augmented", agent.code_name, "skills"),
|
|
13167
13223
|
// Claude Code — project tree
|
|
13168
|
-
|
|
13224
|
+
join26(homedir13(), ".augmented", agent.code_name, "project", ".claude", "skills"),
|
|
13169
13225
|
// Defensive: legacy provision-side path, not currently an
|
|
13170
13226
|
// install target but cheap to sweep.
|
|
13171
|
-
|
|
13227
|
+
join26(agentDir2, ".claude", "skills")
|
|
13172
13228
|
];
|
|
13173
13229
|
const existingDirs = candidateSkillDirs.filter((d) => existsSync11(d));
|
|
13174
13230
|
const discoveredEntries = /* @__PURE__ */ new Set();
|
|
@@ -13184,9 +13240,9 @@ async function processAgent(agent, agentStates) {
|
|
|
13184
13240
|
}
|
|
13185
13241
|
const removeSkillFolder = (entry, reason) => {
|
|
13186
13242
|
for (const dir of existingDirs) {
|
|
13187
|
-
const p =
|
|
13243
|
+
const p = join26(dir, entry);
|
|
13188
13244
|
if (existsSync11(p)) {
|
|
13189
|
-
|
|
13245
|
+
rmSync7(p, { recursive: true, force: true });
|
|
13190
13246
|
}
|
|
13191
13247
|
}
|
|
13192
13248
|
log(`Removed ${reason} '${entry}' for '${agent.code_name}' (framework=${frameworkId2})`);
|
|
@@ -13204,7 +13260,7 @@ async function processAgent(agent, agentStates) {
|
|
|
13204
13260
|
const sharedSkillsPayload = refreshAny.shared_skills;
|
|
13205
13261
|
const desiredResolved = globalSkillsPayload !== void 0 || sharedSkillsPayload !== void 0;
|
|
13206
13262
|
const manifestPath = managedSkillManifestPath(
|
|
13207
|
-
|
|
13263
|
+
join26(homedir12(), ".augmented", agent.code_name)
|
|
13208
13264
|
);
|
|
13209
13265
|
const prevIds = /* @__PURE__ */ new Set([
|
|
13210
13266
|
...agentState.knownGlobalSkillIds.get(agent.agent_id) ?? /* @__PURE__ */ new Set(),
|
|
@@ -13224,16 +13280,16 @@ async function processAgent(agent, agentStates) {
|
|
|
13224
13280
|
}
|
|
13225
13281
|
if (plan.removes.length) {
|
|
13226
13282
|
const globalSkillDirs = [
|
|
13227
|
-
|
|
13228
|
-
|
|
13229
|
-
|
|
13283
|
+
join26(homedir12(), ".augmented", agent.code_name, "skills"),
|
|
13284
|
+
join26(homedir12(), ".augmented", agent.code_name, "project", ".claude", "skills"),
|
|
13285
|
+
join26(agentDir2, ".claude", "skills")
|
|
13230
13286
|
];
|
|
13231
13287
|
for (const id of plan.removes) {
|
|
13232
13288
|
let prunedAny = false;
|
|
13233
13289
|
for (const dir of globalSkillDirs) {
|
|
13234
|
-
const p =
|
|
13235
|
-
if (existsSync11(p) && existsSync11(
|
|
13236
|
-
|
|
13290
|
+
const p = join26(dir, id);
|
|
13291
|
+
if (existsSync11(p) && existsSync11(join26(p, "SKILL.md"))) {
|
|
13292
|
+
rmSync6(p, { recursive: true, force: true });
|
|
13237
13293
|
prunedAny = true;
|
|
13238
13294
|
}
|
|
13239
13295
|
}
|
|
@@ -13380,12 +13436,21 @@ async function processAgent(agent, agentStates) {
|
|
|
13380
13436
|
);
|
|
13381
13437
|
}
|
|
13382
13438
|
} else if (nudgeAction === "nudge") {
|
|
13383
|
-
|
|
13384
|
-
|
|
13385
|
-
agent.
|
|
13386
|
-
|
|
13387
|
-
|
|
13388
|
-
|
|
13439
|
+
const tickLimitedUntil = readUsageLimitUntil({ codeName: agent.code_name });
|
|
13440
|
+
if (tickLimitedUntil) {
|
|
13441
|
+
if (shouldLogUsageCapDeferral("kanban-tick", agent.code_name, tickLimitedUntil)) {
|
|
13442
|
+
log(
|
|
13443
|
+
`[manager-worker] kanban inject skipped for '${agent.code_name}' - agent is at its Claude usage limit until ${tickLimitedUntil.toISOString()} (${allowed.length} actionable card(s) left on the board); further skips this window are not logged`
|
|
13444
|
+
);
|
|
13445
|
+
}
|
|
13446
|
+
} else {
|
|
13447
|
+
void maybeInjectKanbanCheck(
|
|
13448
|
+
agent.code_name,
|
|
13449
|
+
agent.agent_id,
|
|
13450
|
+
allowed.length,
|
|
13451
|
+
kanbanActionableSignature(allowed)
|
|
13452
|
+
);
|
|
13453
|
+
}
|
|
13389
13454
|
} else if (nudgeAction === "close-suppressed") {
|
|
13390
13455
|
closeInjectedRunIfOpen(
|
|
13391
13456
|
agent.code_name,
|
|
@@ -13451,8 +13516,8 @@ async function processAgent(agent, agentStates) {
|
|
|
13451
13516
|
const sess = getSessionState(agent.code_name);
|
|
13452
13517
|
let mcpJsonParsed = null;
|
|
13453
13518
|
try {
|
|
13454
|
-
const mcpPath =
|
|
13455
|
-
mcpJsonParsed = JSON.parse(
|
|
13519
|
+
const mcpPath = join26(getProjectDir(agent.code_name), ".mcp.json");
|
|
13520
|
+
mcpJsonParsed = JSON.parse(readFileSync22(mcpPath, "utf-8"));
|
|
13456
13521
|
} catch {
|
|
13457
13522
|
}
|
|
13458
13523
|
reapMissingMcpSessions({
|
|
@@ -13814,10 +13879,10 @@ Retried to the limit after repeated stalls \u2014 needs a look.`).catch(() => {
|
|
|
13814
13879
|
}
|
|
13815
13880
|
}
|
|
13816
13881
|
const trackedFiles = frameworkAdapter.driftTrackedFiles();
|
|
13817
|
-
if (trackedFiles.length > 0 && existsSync11(
|
|
13882
|
+
if (trackedFiles.length > 0 && existsSync11(agentDir2)) {
|
|
13818
13883
|
const hashes = /* @__PURE__ */ new Map();
|
|
13819
13884
|
for (const file of trackedFiles) {
|
|
13820
|
-
const h = hashFile(
|
|
13885
|
+
const h = hashFile(join26(agentDir2, file));
|
|
13821
13886
|
if (h) hashes.set(file, h);
|
|
13822
13887
|
}
|
|
13823
13888
|
agentState.writtenHashes.set(agent.agent_id, hashes);
|
|
@@ -13832,7 +13897,7 @@ Retried to the limit after repeated stalls \u2014 needs a look.`).catch(() => {
|
|
|
13832
13897
|
refreshData.agent.onboarding_state
|
|
13833
13898
|
);
|
|
13834
13899
|
const obStep = obState.step;
|
|
13835
|
-
const markerPath =
|
|
13900
|
+
const markerPath = join26(homedir12(), ".augmented", agent.code_name, "onboarding-drive.json");
|
|
13836
13901
|
const marker = readOnboardingDriveMarker(markerPath);
|
|
13837
13902
|
const decision = decideOnboardingDrive(obStep, marker, Date.now(), obState.generation ?? 0);
|
|
13838
13903
|
if (decision.clearMarker) {
|
|
@@ -13886,6 +13951,20 @@ var lastModelApiErrorSig = /* @__PURE__ */ new Map();
|
|
|
13886
13951
|
var DAY_ROLLOVER_FORCE_GRACE_MIN = 30;
|
|
13887
13952
|
var persistentSessionStuckTracker = new PersistentSessionStuckTracker();
|
|
13888
13953
|
var claudeAuthTupleBySession = /* @__PURE__ */ new Map();
|
|
13954
|
+
var claudeAccountByAgent = /* @__PURE__ */ new Map();
|
|
13955
|
+
function _resetClaudeAccountByAgent() {
|
|
13956
|
+
claudeAccountByAgent.clear();
|
|
13957
|
+
}
|
|
13958
|
+
function clearUsageLimitMarkerOnAccountChange(codeName, fingerprint3, log2) {
|
|
13959
|
+
if (!fingerprint3) return;
|
|
13960
|
+
const previous = claudeAccountByAgent.get(codeName);
|
|
13961
|
+
claudeAccountByAgent.set(codeName, fingerprint3);
|
|
13962
|
+
if (previous === void 0 || previous === fingerprint3) return;
|
|
13963
|
+
log2(
|
|
13964
|
+
`[usage-banner] signed-in Claude account changed for '${codeName}' (${previous} \u2192 ${fingerprint3}) \u2014 clearing the usage-limit marker; the cap belonged to the previous account (ENG-8202)`
|
|
13965
|
+
);
|
|
13966
|
+
clearUsageLimitMarker(codeName, log2);
|
|
13967
|
+
}
|
|
13889
13968
|
var opencodeCredentialFingerprintBySession = /* @__PURE__ */ new Map();
|
|
13890
13969
|
var egressAllowlistBySession = /* @__PURE__ */ new Map();
|
|
13891
13970
|
function deriveEgressAllowlist(toolsRaw) {
|
|
@@ -13920,7 +13999,7 @@ async function ensureOpencodeRuntime(agent, refreshData, agentTimezone) {
|
|
|
13920
13999
|
}
|
|
13921
14000
|
stopOpencodeSlackIngest(codeName, log);
|
|
13922
14001
|
stopOpencodeTelegramIngest(codeName, log);
|
|
13923
|
-
const opencodeProjectDir =
|
|
14002
|
+
const opencodeProjectDir = join26(getFramework("opencode").getAgentDir(codeName), "provision");
|
|
13924
14003
|
const serveEnv = {
|
|
13925
14004
|
AGT_HOST: requireHost(),
|
|
13926
14005
|
AGT_API_KEY: getApiKey() ?? void 0,
|
|
@@ -13963,8 +14042,8 @@ async function ensureOpencodeRuntime(agent, refreshData, agentTimezone) {
|
|
|
13963
14042
|
async function ensurePersistentSession(agent, tasks, boardItems, refreshData) {
|
|
13964
14043
|
const codeName = agent.code_name;
|
|
13965
14044
|
const projectDir = getProjectDir(codeName);
|
|
13966
|
-
const mcpConfigPath =
|
|
13967
|
-
const claudeMdPath =
|
|
14045
|
+
const mcpConfigPath = join26(projectDir, ".mcp.json");
|
|
14046
|
+
const claudeMdPath = join26(projectDir, "CLAUDE.md");
|
|
13968
14047
|
if (restartBreaker.isTripped(codeName)) {
|
|
13969
14048
|
const trip = restartBreaker.getTrip(codeName);
|
|
13970
14049
|
return {
|
|
@@ -14074,6 +14153,7 @@ async function ensurePersistentSession(agent, tasks, boardItems, refreshData) {
|
|
|
14074
14153
|
let dayRolloverDeferred = false;
|
|
14075
14154
|
let dayRolloverForced = false;
|
|
14076
14155
|
const claudeAccountFingerprint = !openRouterForAgent && claudeAuthMode === "subscription" ? await getClaudeAccountFingerprint() : null;
|
|
14156
|
+
clearUsageLimitMarkerOnAccountChange(codeName, claudeAccountFingerprint, log);
|
|
14077
14157
|
const currentAuthTuple = openRouterForAgent ? `openrouter:${openRouterForAgent.fingerprint ?? openRouterForAgent.model}` : `${claudeAuthMode}:${anthropicApiKeyFingerprint ?? "none"}${claudeAccountFingerprint ? `:${claudeAccountFingerprint}` : ""}`;
|
|
14078
14158
|
const recordedAuthTuple = claudeAuthTupleBySession.get(codeName);
|
|
14079
14159
|
if (recordedAuthTuple && recordedAuthTuple !== currentAuthTuple && isSessionHealthy(codeName)) {
|
|
@@ -14306,7 +14386,19 @@ ${truncateForLog(ctx.tail)}` : `; pane_tail_hash=sha256:${createHash16("sha256")
|
|
|
14306
14386
|
if (ready.length > 0) {
|
|
14307
14387
|
log(`[persistent-session] ${ready.length} ready task(s) for '${codeName}': ${ready.map((t) => `${t.name}(next=${t.nextFireAt ? new Date(t.nextFireAt).toISOString() : "null"})`).join(", ")}`);
|
|
14308
14388
|
}
|
|
14309
|
-
|
|
14389
|
+
let deferReadyForUsageCap = false;
|
|
14390
|
+
if (ready.length > 0) {
|
|
14391
|
+
const schedLimitedUntil = readUsageLimitUntil({ codeName });
|
|
14392
|
+
if (schedLimitedUntil) {
|
|
14393
|
+
if (shouldLogUsageCapDeferral("persistent-scheduler", codeName, schedLimitedUntil)) {
|
|
14394
|
+
log(
|
|
14395
|
+
`[persistent-session] Deferring ${ready.length} ready task(s) for '${codeName}' \u2014 agent is at its Claude usage limit until ${schedLimitedUntil.toISOString()}; schedule NOT advanced, will fire after the limit resets (further deferrals this window are not logged)`
|
|
14396
|
+
);
|
|
14397
|
+
}
|
|
14398
|
+
deferReadyForUsageCap = true;
|
|
14399
|
+
}
|
|
14400
|
+
}
|
|
14401
|
+
for (const task of deferReadyForUsageCap ? [] : ready) {
|
|
14310
14402
|
if (KANBAN_WORK_TEMPLATES.has(task.templateId)) {
|
|
14311
14403
|
const updated = markTaskFired(codeName, task.taskId, "ok");
|
|
14312
14404
|
claudeSchedulerStates.set(codeName, updated);
|
|
@@ -14517,7 +14609,7 @@ async function handleRestartDoorbell(agentId, requestedAt, restartReason) {
|
|
|
14517
14609
|
void api.post("/host/restart-ack", { host_id: hostId, agent_id: agentId, restart_requested_at: requestedAt }).catch((err) => log(`[restart-lane] ack failed for '${codeName}': ${err.message}`));
|
|
14518
14610
|
void (async () => {
|
|
14519
14611
|
try {
|
|
14520
|
-
const { collectDiagnostics } = await import("../persistent-session-
|
|
14612
|
+
const { collectDiagnostics } = await import("../persistent-session-PWLMLDVX.js");
|
|
14521
14613
|
await api.post("/host/heartbeat", {
|
|
14522
14614
|
host_id: hostId,
|
|
14523
14615
|
agent_diagnostics: collectDiagnostics([codeName], quarantineEntriesFor, claudeMdSizeFor)
|
|
@@ -14567,7 +14659,7 @@ async function respawnAgentAfterMcpStop(codeName, reason) {
|
|
|
14567
14659
|
}
|
|
14568
14660
|
try {
|
|
14569
14661
|
const hostId = await getHostId();
|
|
14570
|
-
const { collectDiagnostics } = await import("../persistent-session-
|
|
14662
|
+
const { collectDiagnostics } = await import("../persistent-session-PWLMLDVX.js");
|
|
14571
14663
|
await api.post("/host/heartbeat", {
|
|
14572
14664
|
host_id: hostId,
|
|
14573
14665
|
agent_diagnostics: collectDiagnostics([codeName], quarantineEntriesFor, claudeMdSizeFor)
|
|
@@ -14852,9 +14944,9 @@ async function processDirectChatMessage(agent, msg) {
|
|
|
14852
14944
|
const useDoorbell = hostFlagStore().getBoolean("direct-chat-doorbell") || isolationMode(agent.codeName) === "docker";
|
|
14853
14945
|
if (useDoorbell) {
|
|
14854
14946
|
try {
|
|
14855
|
-
const doorbell = directChatDoorbellPath(agent.agentId,
|
|
14856
|
-
|
|
14857
|
-
|
|
14947
|
+
const doorbell = directChatDoorbellPath(agent.agentId, homedir12());
|
|
14948
|
+
mkdirSync11(dirname8(doorbell), { recursive: true });
|
|
14949
|
+
writeFileSync13(doorbell, String(Date.now()));
|
|
14858
14950
|
log(`[direct-chat] Doorbell rung for '${agent.codeName}' (msg=${msg.id}) \u2014 in-session MCP will pull via the cursor`);
|
|
14859
14951
|
return;
|
|
14860
14952
|
} catch (err) {
|
|
@@ -14962,9 +15054,9 @@ ${formatRunMarker(run_id)}` : KANBAN_CHECK_COMMAND;
|
|
|
14962
15054
|
}
|
|
14963
15055
|
if (run_id) openInjectedRunByCode.set(codeName, run_id);
|
|
14964
15056
|
try {
|
|
14965
|
-
const doorbell = directChatDoorbellPath(agentId,
|
|
14966
|
-
|
|
14967
|
-
|
|
15057
|
+
const doorbell = directChatDoorbellPath(agentId, homedir12());
|
|
15058
|
+
mkdirSync11(dirname8(doorbell), { recursive: true });
|
|
15059
|
+
writeFileSync13(doorbell, String(Date.now()));
|
|
14968
15060
|
} catch (err) {
|
|
14969
15061
|
log(`[kanban] doorbell ring failed for '${codeName}': ${err.message} (notice still queued)`);
|
|
14970
15062
|
}
|
|
@@ -15020,7 +15112,7 @@ async function processClaudePairSessions(agents) {
|
|
|
15020
15112
|
killPairSession,
|
|
15021
15113
|
pairTmuxSession,
|
|
15022
15114
|
finalizeClaudePairOnboarding
|
|
15023
|
-
} = await import("../claude-pair-runtime-
|
|
15115
|
+
} = await import("../claude-pair-runtime-YU6KOA6R.js");
|
|
15024
15116
|
for (const pairId of pendingResp.cancelled_pair_ids ?? []) {
|
|
15025
15117
|
log(`[claude-pair] sweeping orphan tmux session for pair ${pairId.slice(0, 8)}`);
|
|
15026
15118
|
const killed = await killPairSession(pairTmuxSession(pairId));
|
|
@@ -15270,8 +15362,8 @@ function parseMemoryFile(raw, fallbackName) {
|
|
|
15270
15362
|
};
|
|
15271
15363
|
}
|
|
15272
15364
|
async function syncMemories(agent, configDir, log2) {
|
|
15273
|
-
const projectDir =
|
|
15274
|
-
const memoryDir =
|
|
15365
|
+
const projectDir = join26(configDir, agent.code_name, "project");
|
|
15366
|
+
const memoryDir = join26(projectDir, "memory");
|
|
15275
15367
|
const isFreshSync = pendingFreshMemorySync.has(agent.agent_id);
|
|
15276
15368
|
if (isFreshSync) {
|
|
15277
15369
|
log2(`[memory-sync] Fresh-sync requested for '${agent.code_name}' \u2014 pulling DB first`);
|
|
@@ -15289,7 +15381,7 @@ async function syncMemories(agent, configDir, log2) {
|
|
|
15289
15381
|
for (const file of readdirSync7(memoryDir)) {
|
|
15290
15382
|
if (!file.endsWith(".md")) continue;
|
|
15291
15383
|
try {
|
|
15292
|
-
const raw =
|
|
15384
|
+
const raw = readFileSync22(join26(memoryDir, file), "utf-8");
|
|
15293
15385
|
const fileHash = createHash16("sha256").update(raw).digest("hex").slice(0, 16);
|
|
15294
15386
|
currentHashes.set(file, fileHash);
|
|
15295
15387
|
if (prevHashes.get(file) === fileHash) continue;
|
|
@@ -15314,7 +15406,7 @@ async function syncMemories(agent, configDir, log2) {
|
|
|
15314
15406
|
} catch (err) {
|
|
15315
15407
|
for (const mem of changedMemories) {
|
|
15316
15408
|
for (const [file] of currentHashes) {
|
|
15317
|
-
const parsed = parseMemoryFile(
|
|
15409
|
+
const parsed = parseMemoryFile(readFileSync22(join26(memoryDir, file), "utf-8"), file.replace(/\.md$/, ""));
|
|
15318
15410
|
if (parsed?.name === mem.name) currentHashes.delete(file);
|
|
15319
15411
|
}
|
|
15320
15412
|
}
|
|
@@ -15342,14 +15434,14 @@ async function downloadMemories(agent, memoryDir, log2, { force }) {
|
|
|
15342
15434
|
lastDownloadHash.set(agent.agent_id, responseHash);
|
|
15343
15435
|
lastLocalFileHash.set(agent.agent_id, localListHash);
|
|
15344
15436
|
if (dbMemories.memories?.length) {
|
|
15345
|
-
|
|
15437
|
+
mkdirSync11(memoryDir, { recursive: true });
|
|
15346
15438
|
let written = 0;
|
|
15347
15439
|
let overwritten = 0;
|
|
15348
15440
|
for (let i = 0; i < dbMemories.memories.length; i++) {
|
|
15349
15441
|
const mem = dbMemories.memories[i];
|
|
15350
15442
|
const rawSlug = mem.name.toLowerCase().replace(/[^a-z0-9]+/g, "-").replace(/(^-|-$)/g, "").slice(0, 60);
|
|
15351
15443
|
const slug = rawSlug || `memory-${i}`;
|
|
15352
|
-
const filePath =
|
|
15444
|
+
const filePath = join26(memoryDir, `${slug}.md`);
|
|
15353
15445
|
const desired = `---
|
|
15354
15446
|
name: ${JSON.stringify(mem.name)}
|
|
15355
15447
|
type: ${mem.type}
|
|
@@ -15361,14 +15453,14 @@ ${mem.content}
|
|
|
15361
15453
|
if (existsSync11(filePath)) {
|
|
15362
15454
|
let existing = "";
|
|
15363
15455
|
try {
|
|
15364
|
-
existing =
|
|
15456
|
+
existing = readFileSync22(filePath, "utf-8");
|
|
15365
15457
|
} catch {
|
|
15366
15458
|
}
|
|
15367
15459
|
if (existing === desired) continue;
|
|
15368
|
-
|
|
15460
|
+
writeFileSync13(filePath, desired);
|
|
15369
15461
|
overwritten++;
|
|
15370
15462
|
} else {
|
|
15371
|
-
|
|
15463
|
+
writeFileSync13(filePath, desired);
|
|
15372
15464
|
written++;
|
|
15373
15465
|
}
|
|
15374
15466
|
}
|
|
@@ -15384,10 +15476,10 @@ ${mem.content}
|
|
|
15384
15476
|
return false;
|
|
15385
15477
|
}
|
|
15386
15478
|
}
|
|
15387
|
-
async function cleanupAgentFiles(codeName,
|
|
15388
|
-
if (existsSync11(
|
|
15479
|
+
async function cleanupAgentFiles(codeName, agentDir2) {
|
|
15480
|
+
if (existsSync11(agentDir2)) {
|
|
15389
15481
|
try {
|
|
15390
|
-
|
|
15482
|
+
rmSync6(agentDir2, { recursive: true, force: true });
|
|
15391
15483
|
log(`Removed provision directory for '${codeName}'`);
|
|
15392
15484
|
} catch (err) {
|
|
15393
15485
|
log(`Failed to remove provision dir for '${codeName}': ${err.message}`);
|
|
@@ -15625,7 +15717,7 @@ function startManager(opts) {
|
|
|
15625
15717
|
try {
|
|
15626
15718
|
const stateFile = getStateFile();
|
|
15627
15719
|
if (existsSync11(stateFile)) {
|
|
15628
|
-
const raw =
|
|
15720
|
+
const raw = readFileSync22(stateFile, "utf-8");
|
|
15629
15721
|
const parsed = JSON.parse(raw);
|
|
15630
15722
|
if (Array.isArray(parsed.agents)) {
|
|
15631
15723
|
state6.agents = parsed.agents;
|
|
@@ -15652,7 +15744,7 @@ function startManager(opts) {
|
|
|
15652
15744
|
log(`[startup] state rehydration failed (continuing with empty state): ${err.message}`);
|
|
15653
15745
|
}
|
|
15654
15746
|
log(
|
|
15655
|
-
`[startup] worker pid=${process.pid} ppid=${process.ppid} node=${process.version} log=${
|
|
15747
|
+
`[startup] worker pid=${process.pid} ppid=${process.ppid} node=${process.version} log=${join26(homedir12(), ".augmented", "manager.log")}`
|
|
15656
15748
|
);
|
|
15657
15749
|
deployMcpAssets();
|
|
15658
15750
|
reapOrphanChannelMcps({ log });
|
|
@@ -15681,7 +15773,7 @@ async function reapOrphanedClaudePids() {
|
|
|
15681
15773
|
const looksLikeClaude = (pid) => {
|
|
15682
15774
|
if (process.platform !== "linux") return true;
|
|
15683
15775
|
try {
|
|
15684
|
-
const comm =
|
|
15776
|
+
const comm = readFileSync22(`/proc/${pid}/comm`, "utf-8").trim().toLowerCase();
|
|
15685
15777
|
return comm.includes("claude");
|
|
15686
15778
|
} catch {
|
|
15687
15779
|
return false;
|
|
@@ -15778,14 +15870,14 @@ function restartRunningChannelMcps(basenames) {
|
|
|
15778
15870
|
}
|
|
15779
15871
|
}
|
|
15780
15872
|
function deployMcpAssets() {
|
|
15781
|
-
const targetDir =
|
|
15782
|
-
|
|
15873
|
+
const targetDir = join26(homedir12(), ".augmented", "_mcp");
|
|
15874
|
+
mkdirSync11(targetDir, { recursive: true });
|
|
15783
15875
|
const moduleDir = dirname8(fileURLToPath(import.meta.url));
|
|
15784
15876
|
let mcpSourceDir = "";
|
|
15785
15877
|
let dir = moduleDir;
|
|
15786
15878
|
for (let i = 0; i < 6; i++) {
|
|
15787
|
-
const candidate =
|
|
15788
|
-
if (existsSync11(
|
|
15879
|
+
const candidate = join26(dir, "dist", "mcp");
|
|
15880
|
+
if (existsSync11(join26(candidate, "index.js"))) {
|
|
15789
15881
|
mcpSourceDir = candidate;
|
|
15790
15882
|
break;
|
|
15791
15883
|
}
|
|
@@ -15801,7 +15893,7 @@ function deployMcpAssets() {
|
|
|
15801
15893
|
const fileHash = (p) => {
|
|
15802
15894
|
try {
|
|
15803
15895
|
if (!existsSync11(p)) return null;
|
|
15804
|
-
return createHash16("sha256").update(
|
|
15896
|
+
return createHash16("sha256").update(readFileSync22(p)).digest("hex");
|
|
15805
15897
|
} catch {
|
|
15806
15898
|
return null;
|
|
15807
15899
|
}
|
|
@@ -15865,8 +15957,8 @@ function deployMcpAssets() {
|
|
|
15865
15957
|
// needs restarting to pick up a token rotation.
|
|
15866
15958
|
"xero.js"
|
|
15867
15959
|
]) {
|
|
15868
|
-
const src =
|
|
15869
|
-
const dst =
|
|
15960
|
+
const src = join26(mcpSourceDir, file);
|
|
15961
|
+
const dst = join26(targetDir, file);
|
|
15870
15962
|
if (!existsSync11(src)) continue;
|
|
15871
15963
|
const before = fileHash(dst);
|
|
15872
15964
|
try {
|
|
@@ -15884,23 +15976,23 @@ function deployMcpAssets() {
|
|
|
15884
15976
|
log(`[manager] Bundle(s) updated: ${changedBasenames.join(", ")} \u2014 signalling running instances to restart`);
|
|
15885
15977
|
restartRunningChannelMcps(changedBasenames);
|
|
15886
15978
|
}
|
|
15887
|
-
const localMcpPath =
|
|
15979
|
+
const localMcpPath = join26(targetDir, "index.js");
|
|
15888
15980
|
try {
|
|
15889
|
-
const agentsDir =
|
|
15981
|
+
const agentsDir = join26(homedir12(), ".augmented", "agents");
|
|
15890
15982
|
if (existsSync11(agentsDir)) {
|
|
15891
15983
|
for (const entry of readdirSync7(agentsDir, { withFileTypes: true })) {
|
|
15892
15984
|
if (!entry.isDirectory()) continue;
|
|
15893
15985
|
for (const subdir of ["provision", "project"]) {
|
|
15894
|
-
const mcpJsonPath =
|
|
15986
|
+
const mcpJsonPath = join26(agentsDir, entry.name, subdir, ".mcp.json");
|
|
15895
15987
|
try {
|
|
15896
|
-
const raw =
|
|
15988
|
+
const raw = readFileSync22(mcpJsonPath, "utf-8");
|
|
15897
15989
|
if (!raw.includes("@integrity-labs/augmented-mcp")) continue;
|
|
15898
15990
|
const mcpConfig = JSON.parse(raw);
|
|
15899
15991
|
const augServer = mcpConfig.mcpServers?.["augmented"];
|
|
15900
15992
|
if (!augServer) continue;
|
|
15901
15993
|
augServer.command = "node";
|
|
15902
15994
|
augServer.args = [localMcpPath];
|
|
15903
|
-
|
|
15995
|
+
writeFileSync13(mcpJsonPath, JSON.stringify(mcpConfig, null, 2));
|
|
15904
15996
|
log(`[manager] Patched ${entry.name}/${subdir}/.mcp.json: npx \u2192 node`);
|
|
15905
15997
|
} catch {
|
|
15906
15998
|
}
|
|
@@ -15937,11 +16029,13 @@ process.on("disconnect", () => {
|
|
|
15937
16029
|
export {
|
|
15938
16030
|
BACK_ONLINE_GREETING_GUIDANCE,
|
|
15939
16031
|
DAY_ROLLOVER_FORCE_GRACE_MIN,
|
|
16032
|
+
_resetClaudeAccountByAgent,
|
|
15940
16033
|
applyRestartAcks,
|
|
15941
16034
|
cancelKanbanNoticeOnDrain,
|
|
15942
16035
|
claudeCodeUpgradeMarkerPath,
|
|
15943
16036
|
claudeCodeUpgradeThrottled,
|
|
15944
16037
|
claudeManagedSettingsPath,
|
|
16038
|
+
clearUsageLimitMarkerOnAccountChange,
|
|
15945
16039
|
dashboardRestartBreakerReason,
|
|
15946
16040
|
ensureClaudeManagedSettings,
|
|
15947
16041
|
extractCharterSlackPeers,
|