@integrity-labs/agt-cli 0.28.440 → 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-V3G7G4QM.js → chunk-6KTN6GTT.js} +3 -3
- package/dist/{chunk-R6GVWACQ.js → chunk-NQP2W2RD.js} +45 -91
- package/dist/chunk-NQP2W2RD.js.map +1 -0
- package/dist/{claude-pair-runtime-Z4DP2IQA.js → claude-pair-runtime-YU6KOA6R.js} +2 -2
- package/dist/lib/manager-worker.js +327 -265
- package/dist/lib/manager-worker.js.map +1 -1
- package/dist/{persistent-session-4MIMM3TN.js → persistent-session-PWLMLDVX.js} +2 -2
- package/dist/{responsiveness-probe-5SRDBI4B.js → responsiveness-probe-ZKUDFRIU.js} +2 -2
- package/package.json +1 -1
- package/dist/chunk-R6GVWACQ.js.map +0 -1
- /package/dist/{chunk-V3G7G4QM.js.map → chunk-6KTN6GTT.js.map} +0 -0
- /package/dist/{claude-pair-runtime-Z4DP2IQA.js.map → claude-pair-runtime-YU6KOA6R.js.map} +0 -0
- /package/dist/{persistent-session-4MIMM3TN.js.map → persistent-session-PWLMLDVX.js.map} +0 -0
- /package/dist/{responsiveness-probe-5SRDBI4B.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,
|
|
@@ -129,7 +130,6 @@ import {
|
|
|
129
130
|
readOpencodePaneLogTail,
|
|
130
131
|
readPaneLogTail,
|
|
131
132
|
readProvisionedOpencodeModel,
|
|
132
|
-
readUsageLimitUntil,
|
|
133
133
|
reloadEgressSidecar,
|
|
134
134
|
resetRestartCount,
|
|
135
135
|
resolveAgentTimezone,
|
|
@@ -137,13 +137,14 @@ import {
|
|
|
137
137
|
resolveChannels,
|
|
138
138
|
resolveClaudeBinary,
|
|
139
139
|
resolveDmTarget,
|
|
140
|
+
resolveUsageLimitUntil,
|
|
140
141
|
restartEgressSidecar,
|
|
141
142
|
rotateSessionForWedge,
|
|
142
143
|
serializeAccountEnforcementMarker,
|
|
144
|
+
serializeUsageLimitMarker,
|
|
143
145
|
sessionTranscriptDir,
|
|
144
146
|
sha256,
|
|
145
147
|
sharedBusyBuckets,
|
|
146
|
-
shouldLogUsageCapDeferral,
|
|
147
148
|
startOpencodeSession,
|
|
148
149
|
startPersistentSession,
|
|
149
150
|
stopAllSessionsAndWait,
|
|
@@ -155,19 +156,18 @@ import {
|
|
|
155
156
|
takeZombieDetection,
|
|
156
157
|
toOpencodeModel,
|
|
157
158
|
transcriptActivityAgeSeconds,
|
|
158
|
-
writeEgressAllowlist
|
|
159
|
-
|
|
160
|
-
} from "../chunk-R6GVWACQ.js";
|
|
159
|
+
writeEgressAllowlist
|
|
160
|
+
} from "../chunk-NQP2W2RD.js";
|
|
161
161
|
import {
|
|
162
162
|
reapOrphanChannelMcps
|
|
163
163
|
} from "../chunk-XWVM4KPK.js";
|
|
164
164
|
|
|
165
165
|
// src/lib/manager-worker.ts
|
|
166
166
|
import { createHash as createHash16 } from "crypto";
|
|
167
|
-
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";
|
|
168
168
|
import { execFileSync as syncExecFile } from "child_process";
|
|
169
|
-
import { join as
|
|
170
|
-
import { homedir as
|
|
169
|
+
import { join as join26, dirname as dirname8, delimiter as pathDelimiter } from "path";
|
|
170
|
+
import { homedir as homedir12 } from "os";
|
|
171
171
|
import { fileURLToPath } from "url";
|
|
172
172
|
|
|
173
173
|
// src/lib/claude-code-upgrade-throttle.ts
|
|
@@ -2053,10 +2053,55 @@ var nodeArtifactFs = {
|
|
|
2053
2053
|
}
|
|
2054
2054
|
};
|
|
2055
2055
|
|
|
2056
|
-
// src/lib/
|
|
2057
|
-
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";
|
|
2058
2059
|
import { join as join6 } from "path";
|
|
2059
|
-
|
|
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;
|
|
2060
2105
|
function classifyLine(line, startMs, endMs) {
|
|
2061
2106
|
const trimmed = line.trim();
|
|
2062
2107
|
if (!trimmed) return null;
|
|
@@ -2102,7 +2147,7 @@ function probeRateLimitState(args) {
|
|
|
2102
2147
|
let newest = null;
|
|
2103
2148
|
for (const name of entries) {
|
|
2104
2149
|
if (!name.endsWith(".jsonl")) continue;
|
|
2105
|
-
const path =
|
|
2150
|
+
const path = join7(dir, name);
|
|
2106
2151
|
try {
|
|
2107
2152
|
const st = statSync(path);
|
|
2108
2153
|
if (!st.isFile() || st.mtimeMs < startMs) continue;
|
|
@@ -2111,7 +2156,7 @@ function probeRateLimitState(args) {
|
|
|
2111
2156
|
}
|
|
2112
2157
|
let content;
|
|
2113
2158
|
try {
|
|
2114
|
-
content =
|
|
2159
|
+
content = readFileSync8(path, "utf-8");
|
|
2115
2160
|
} catch {
|
|
2116
2161
|
continue;
|
|
2117
2162
|
}
|
|
@@ -2228,13 +2273,13 @@ async function maybeReportUsageBanner(args) {
|
|
|
2228
2273
|
// src/lib/claude-account-fingerprint.ts
|
|
2229
2274
|
import { createHash as createHash6 } from "crypto";
|
|
2230
2275
|
import { readFile as readFile3, readdir as readdir3 } from "fs/promises";
|
|
2231
|
-
import { homedir as
|
|
2232
|
-
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";
|
|
2233
2278
|
|
|
2234
2279
|
// src/lib/claude-auth-detect.ts
|
|
2235
2280
|
import { readFile as readFile2, readdir as readdir2 } from "fs/promises";
|
|
2236
|
-
import { homedir as
|
|
2237
|
-
import { join as
|
|
2281
|
+
import { homedir as homedir4, platform } from "os";
|
|
2282
|
+
import { join as join8 } from "path";
|
|
2238
2283
|
import { execFile } from "child_process";
|
|
2239
2284
|
import { promisify } from "util";
|
|
2240
2285
|
var execFileAsync = promisify(execFile);
|
|
@@ -2249,16 +2294,16 @@ async function detectClaudeAuth() {
|
|
|
2249
2294
|
}
|
|
2250
2295
|
async function findClaudeCredentialsPaths() {
|
|
2251
2296
|
const candidates = [
|
|
2252
|
-
|
|
2253
|
-
|
|
2297
|
+
join8(homedir4(), ".claude", ".credentials.json"),
|
|
2298
|
+
join8(homedir4(), ".claude", "credentials.json")
|
|
2254
2299
|
];
|
|
2255
2300
|
const isLinuxRoot = platform() === "linux" && typeof process.getuid === "function" && process.getuid() === 0;
|
|
2256
2301
|
if (isLinuxRoot) {
|
|
2257
2302
|
try {
|
|
2258
2303
|
const entries = await readdir2("/home", { withFileTypes: true });
|
|
2259
2304
|
for (const entry of entries.filter((entry2) => entry2.isDirectory()).sort((a, b) => a.name.localeCompare(b.name))) {
|
|
2260
|
-
candidates.push(
|
|
2261
|
-
candidates.push(
|
|
2305
|
+
candidates.push(join8("/home", entry.name, ".claude", ".credentials.json"));
|
|
2306
|
+
candidates.push(join8("/home", entry.name, ".claude", "credentials.json"));
|
|
2262
2307
|
}
|
|
2263
2308
|
} catch {
|
|
2264
2309
|
}
|
|
@@ -2336,13 +2381,13 @@ function parseExpiresAt(raw) {
|
|
|
2336
2381
|
|
|
2337
2382
|
// src/lib/claude-account-fingerprint.ts
|
|
2338
2383
|
async function candidateHomes() {
|
|
2339
|
-
const homes = [
|
|
2384
|
+
const homes = [homedir5()];
|
|
2340
2385
|
const isLinuxRoot = platform2() === "linux" && typeof process.getuid === "function" && process.getuid() === 0;
|
|
2341
2386
|
if (isLinuxRoot) {
|
|
2342
2387
|
try {
|
|
2343
2388
|
const entries = await readdir3("/home", { withFileTypes: true });
|
|
2344
2389
|
for (const entry of entries.filter((e) => e.isDirectory()).sort((a, b) => a.name.localeCompare(b.name))) {
|
|
2345
|
-
homes.push(
|
|
2390
|
+
homes.push(join9("/home", entry.name));
|
|
2346
2391
|
}
|
|
2347
2392
|
} catch {
|
|
2348
2393
|
}
|
|
@@ -2362,11 +2407,11 @@ async function homeOfActiveCredentials() {
|
|
|
2362
2407
|
async function claudeConfigCandidatePaths() {
|
|
2363
2408
|
const paths = [];
|
|
2364
2409
|
const configDir = process.env["CLAUDE_CONFIG_DIR"]?.trim();
|
|
2365
|
-
if (configDir) paths.push(
|
|
2410
|
+
if (configDir) paths.push(join9(configDir, ".claude.json"));
|
|
2366
2411
|
const activeHome = await homeOfActiveCredentials();
|
|
2367
|
-
if (activeHome) paths.push(
|
|
2412
|
+
if (activeHome) paths.push(join9(activeHome, ".claude.json"));
|
|
2368
2413
|
for (const home of await candidateHomes()) {
|
|
2369
|
-
const path =
|
|
2414
|
+
const path = join9(home, ".claude.json");
|
|
2370
2415
|
if (!paths.includes(path)) paths.push(path);
|
|
2371
2416
|
}
|
|
2372
2417
|
return paths;
|
|
@@ -2410,11 +2455,11 @@ async function getClaudeAccountFingerprint(paths, nowMs = Date.now()) {
|
|
|
2410
2455
|
}
|
|
2411
2456
|
|
|
2412
2457
|
// src/lib/account-enforcement-marker.ts
|
|
2413
|
-
import { mkdirSync as
|
|
2414
|
-
import { homedir as
|
|
2415
|
-
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";
|
|
2416
2461
|
function accountEnforcementMarkerPath(codeName) {
|
|
2417
|
-
return
|
|
2462
|
+
return join10(homedir6(), ".augmented", codeName, ACCOUNT_ENFORCEMENT_MARKER_FILENAME);
|
|
2418
2463
|
}
|
|
2419
2464
|
function syncAccountEnforcementMarker(codeName, level, log2 = (m) => process.stderr.write(`${m}
|
|
2420
2465
|
`)) {
|
|
@@ -2422,16 +2467,16 @@ function syncAccountEnforcementMarker(codeName, level, log2 = (m) => process.std
|
|
|
2422
2467
|
clearAccountEnforcementMarker(codeName, log2);
|
|
2423
2468
|
return;
|
|
2424
2469
|
}
|
|
2425
|
-
const dir =
|
|
2426
|
-
const path =
|
|
2470
|
+
const dir = join10(homedir6(), ".augmented", codeName);
|
|
2471
|
+
const path = join10(dir, ACCOUNT_ENFORCEMENT_MARKER_FILENAME);
|
|
2427
2472
|
const tempPath = `${path}.${process.pid}.tmp`;
|
|
2428
2473
|
try {
|
|
2429
|
-
|
|
2430
|
-
|
|
2474
|
+
mkdirSync5(dir, { recursive: true });
|
|
2475
|
+
writeFileSync5(tempPath, serializeAccountEnforcementMarker(level), "utf-8");
|
|
2431
2476
|
renameSync(tempPath, path);
|
|
2432
2477
|
} catch (err) {
|
|
2433
2478
|
try {
|
|
2434
|
-
|
|
2479
|
+
rmSync3(tempPath, { force: true });
|
|
2435
2480
|
} catch {
|
|
2436
2481
|
}
|
|
2437
2482
|
log2(`[account-enforcement] marker sync failed for '${codeName}': ${err.message}`);
|
|
@@ -2441,15 +2486,15 @@ function clearAccountEnforcementMarker(codeName, log2 = (m) => process.stderr.wr
|
|
|
2441
2486
|
`)) {
|
|
2442
2487
|
const path = accountEnforcementMarkerPath(codeName);
|
|
2443
2488
|
try {
|
|
2444
|
-
|
|
2489
|
+
rmSync3(path, { force: true });
|
|
2445
2490
|
} catch (err) {
|
|
2446
2491
|
log2(`[account-enforcement] marker clear failed for '${codeName}': ${err.message}`);
|
|
2447
2492
|
}
|
|
2448
2493
|
}
|
|
2449
2494
|
|
|
2450
2495
|
// src/lib/token-usage-monitor.ts
|
|
2451
|
-
import { readdirSync as readdirSync2, readFileSync as
|
|
2452
|
-
import { join as
|
|
2496
|
+
import { readdirSync as readdirSync2, readFileSync as readFileSync9, statSync as statSync2 } from "fs";
|
|
2497
|
+
import { join as join11 } from "path";
|
|
2453
2498
|
var MIN_CHECK_INTERVAL_MS2 = 6e4;
|
|
2454
2499
|
var TRANSCRIPT_MTIME_WINDOW_MS = 2 * 24 * 60 * 60 * 1e3;
|
|
2455
2500
|
var MAX_ENTRIES_PER_POST = 200;
|
|
@@ -2478,7 +2523,7 @@ async function maybeReportTokenUsage(args) {
|
|
|
2478
2523
|
if (!name.endsWith(".jsonl")) continue;
|
|
2479
2524
|
const sessionId = name.slice(0, -".jsonl".length);
|
|
2480
2525
|
if (!sessionId) continue;
|
|
2481
|
-
const path =
|
|
2526
|
+
const path = join11(dir, name);
|
|
2482
2527
|
let st;
|
|
2483
2528
|
try {
|
|
2484
2529
|
st = statSync2(path);
|
|
@@ -2494,7 +2539,7 @@ async function maybeReportTokenUsage(args) {
|
|
|
2494
2539
|
}
|
|
2495
2540
|
let content;
|
|
2496
2541
|
try {
|
|
2497
|
-
content =
|
|
2542
|
+
content = readFileSync9(path, "utf-8");
|
|
2498
2543
|
} catch (err) {
|
|
2499
2544
|
log2(`[token-usage] read failed for '${codeName}/${name}': ${err.message}`);
|
|
2500
2545
|
continue;
|
|
@@ -2575,8 +2620,8 @@ async function maybeReportTokenUsage(args) {
|
|
|
2575
2620
|
}
|
|
2576
2621
|
|
|
2577
2622
|
// src/lib/workflow-run-reconciler.ts
|
|
2578
|
-
import { readdirSync as readdirSync3, readFileSync as
|
|
2579
|
-
import { join as
|
|
2623
|
+
import { readdirSync as readdirSync3, readFileSync as readFileSync10, statSync as statSync3 } from "fs";
|
|
2624
|
+
import { join as join12 } from "path";
|
|
2580
2625
|
var MIN_CHECK_INTERVAL_MS3 = 5 * 6e4;
|
|
2581
2626
|
var SETTLE_MS = 3e4;
|
|
2582
2627
|
var TRANSCRIPT_MTIME_WINDOW_MS2 = 2 * 24 * 60 * 60 * 1e3;
|
|
@@ -2595,7 +2640,7 @@ function collectJsonlRecursive(dir, minMtimeMs, out, depth) {
|
|
|
2595
2640
|
return;
|
|
2596
2641
|
}
|
|
2597
2642
|
for (const name of entries) {
|
|
2598
|
-
const p =
|
|
2643
|
+
const p = join12(dir, name);
|
|
2599
2644
|
let st;
|
|
2600
2645
|
try {
|
|
2601
2646
|
st = statSync3(p);
|
|
@@ -2618,7 +2663,7 @@ function enumerateTranscriptFiles(transcriptDir, nowMs, minMtimeMs = nowMs - TRA
|
|
|
2618
2663
|
return out;
|
|
2619
2664
|
}
|
|
2620
2665
|
for (const name of entries) {
|
|
2621
|
-
const path =
|
|
2666
|
+
const path = join12(transcriptDir, name);
|
|
2622
2667
|
let st;
|
|
2623
2668
|
try {
|
|
2624
2669
|
st = statSync3(path);
|
|
@@ -2630,7 +2675,7 @@ function enumerateTranscriptFiles(transcriptDir, nowMs, minMtimeMs = nowMs - TRA
|
|
|
2630
2675
|
continue;
|
|
2631
2676
|
}
|
|
2632
2677
|
if (st.isDirectory()) {
|
|
2633
|
-
collectJsonlRecursive(
|
|
2678
|
+
collectJsonlRecursive(join12(path, "subagents"), minMtimeMs, out, 0);
|
|
2634
2679
|
}
|
|
2635
2680
|
}
|
|
2636
2681
|
return out;
|
|
@@ -2675,7 +2720,7 @@ async function maybeReconcileWorkflowRunTokens(args) {
|
|
|
2675
2720
|
const contents = [];
|
|
2676
2721
|
for (const path of files) {
|
|
2677
2722
|
try {
|
|
2678
|
-
contents.push(
|
|
2723
|
+
contents.push(readFileSync10(path, "utf-8"));
|
|
2679
2724
|
} catch {
|
|
2680
2725
|
}
|
|
2681
2726
|
}
|
|
@@ -2720,8 +2765,8 @@ async function maybeReconcileWorkflowRunTokens(args) {
|
|
|
2720
2765
|
}
|
|
2721
2766
|
|
|
2722
2767
|
// src/lib/conversation-evaluator.ts
|
|
2723
|
-
import { readdirSync as readdirSync4, readFileSync as
|
|
2724
|
-
import { join as
|
|
2768
|
+
import { readdirSync as readdirSync4, readFileSync as readFileSync11, statSync as statSync4 } from "fs";
|
|
2769
|
+
import { join as join13 } from "path";
|
|
2725
2770
|
var MIN_CHECK_INTERVAL_MS4 = 5 * 6e4;
|
|
2726
2771
|
var TRANSCRIPT_MTIME_WINDOW_MS3 = 7 * 24 * 60 * 60 * 1e3;
|
|
2727
2772
|
var WINDOW_PAD_MS = 5 * 6e4;
|
|
@@ -3157,7 +3202,7 @@ function readRecentTurns(dir, nowMs) {
|
|
|
3157
3202
|
return;
|
|
3158
3203
|
}
|
|
3159
3204
|
for (const ent of entries) {
|
|
3160
|
-
const full =
|
|
3205
|
+
const full = join13(d, ent.name);
|
|
3161
3206
|
if (ent.isDirectory()) {
|
|
3162
3207
|
visit(full);
|
|
3163
3208
|
continue;
|
|
@@ -3172,7 +3217,7 @@ function readRecentTurns(dir, nowMs) {
|
|
|
3172
3217
|
if (nowMs - mtimeMs > TRANSCRIPT_MTIME_WINDOW_MS3) continue;
|
|
3173
3218
|
let content;
|
|
3174
3219
|
try {
|
|
3175
|
-
content =
|
|
3220
|
+
content = readFileSync11(full, "utf8");
|
|
3176
3221
|
} catch {
|
|
3177
3222
|
continue;
|
|
3178
3223
|
}
|
|
@@ -3462,11 +3507,11 @@ async function reportSkip2(api2, agentId, conversationId, log2, codeName) {
|
|
|
3462
3507
|
}
|
|
3463
3508
|
|
|
3464
3509
|
// src/lib/activity-cache-monitor.ts
|
|
3465
|
-
import { existsSync as existsSync2, readFileSync as
|
|
3466
|
-
import { homedir as
|
|
3467
|
-
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";
|
|
3468
3513
|
var MIN_CHECK_INTERVAL_MS6 = 6e4;
|
|
3469
|
-
var STATS_CACHE_PATH =
|
|
3514
|
+
var STATS_CACHE_PATH = join14(homedir7(), ".claude", "stats-cache.json");
|
|
3470
3515
|
var ISO_DATE_RE = /^\d{4}-\d{2}-\d{2}$/;
|
|
3471
3516
|
var state5 = { lastObservedDate: null, lastCheckedAt: 0 };
|
|
3472
3517
|
function selectNewDailyRows(raw, lastObservedDate) {
|
|
@@ -3514,7 +3559,7 @@ async function maybeReportActivityCache(args) {
|
|
|
3514
3559
|
}
|
|
3515
3560
|
let raw;
|
|
3516
3561
|
try {
|
|
3517
|
-
raw =
|
|
3562
|
+
raw = readFileSync12(STATS_CACHE_PATH, "utf-8");
|
|
3518
3563
|
} catch (err) {
|
|
3519
3564
|
log2(`[activity-cache] readFileSync failed: ${err.message}`);
|
|
3520
3565
|
return;
|
|
@@ -3718,18 +3763,18 @@ function computeChannelConfigHash(input) {
|
|
|
3718
3763
|
}
|
|
3719
3764
|
|
|
3720
3765
|
// src/lib/channel-hash-cache.ts
|
|
3721
|
-
import { existsSync as existsSync3, readFileSync as
|
|
3722
|
-
import { join as
|
|
3766
|
+
import { existsSync as existsSync3, readFileSync as readFileSync13, writeFileSync as writeFileSync6 } from "fs";
|
|
3767
|
+
import { join as join15 } from "path";
|
|
3723
3768
|
var CACHE_FILENAME = "channel-hash-cache.json";
|
|
3724
3769
|
function getChannelHashCacheFile(configDir) {
|
|
3725
|
-
return
|
|
3770
|
+
return join15(configDir, CACHE_FILENAME);
|
|
3726
3771
|
}
|
|
3727
3772
|
function loadChannelHashCache(target, configDir) {
|
|
3728
3773
|
const path = getChannelHashCacheFile(configDir);
|
|
3729
3774
|
if (!existsSync3(path)) return;
|
|
3730
3775
|
let parsed;
|
|
3731
3776
|
try {
|
|
3732
|
-
parsed = JSON.parse(
|
|
3777
|
+
parsed = JSON.parse(readFileSync13(path, "utf-8"));
|
|
3733
3778
|
} catch {
|
|
3734
3779
|
return;
|
|
3735
3780
|
}
|
|
@@ -3743,14 +3788,14 @@ function saveChannelHashCache(source, configDir) {
|
|
|
3743
3788
|
const obj = {};
|
|
3744
3789
|
for (const [key, value] of source) obj[key] = value;
|
|
3745
3790
|
try {
|
|
3746
|
-
|
|
3791
|
+
writeFileSync6(path, JSON.stringify(obj, null, 2));
|
|
3747
3792
|
} catch {
|
|
3748
3793
|
}
|
|
3749
3794
|
}
|
|
3750
3795
|
|
|
3751
3796
|
// src/lib/sender-policy-baseline.ts
|
|
3752
|
-
import { existsSync as existsSync4, readFileSync as
|
|
3753
|
-
import { join as
|
|
3797
|
+
import { existsSync as existsSync4, readFileSync as readFileSync14 } from "fs";
|
|
3798
|
+
import { join as join16 } from "path";
|
|
3754
3799
|
var BASELINE_FILENAME = "sender-policy-baseline.json";
|
|
3755
3800
|
var SENDER_POLICY_BASELINE_VERSION = 1;
|
|
3756
3801
|
var BASELINE_CONCERNS = ["senderPolicy", "slackBehaviour", "msteamsBehaviour"];
|
|
@@ -3762,14 +3807,14 @@ function createDeliveryBaselineMaps() {
|
|
|
3762
3807
|
};
|
|
3763
3808
|
}
|
|
3764
3809
|
function getSenderPolicyBaselineFile(configDir) {
|
|
3765
|
-
return
|
|
3810
|
+
return join16(configDir, BASELINE_FILENAME);
|
|
3766
3811
|
}
|
|
3767
3812
|
function loadSenderPolicyBaseline(target, configDir, log2) {
|
|
3768
3813
|
const path = getSenderPolicyBaselineFile(configDir);
|
|
3769
3814
|
if (!existsSync4(path)) return;
|
|
3770
3815
|
let parsed;
|
|
3771
3816
|
try {
|
|
3772
|
-
parsed = JSON.parse(
|
|
3817
|
+
parsed = JSON.parse(readFileSync14(path, "utf-8"));
|
|
3773
3818
|
} catch (err) {
|
|
3774
3819
|
log2?.(
|
|
3775
3820
|
`[sender-policy] discarding corrupt ${BASELINE_FILENAME} (${err.message}) - restrictive-policy agents will take one fail-closed restart`
|
|
@@ -4292,16 +4337,16 @@ function planGlobalSkillSync(globalSkills, prevIds, hashOf, knownHash, options)
|
|
|
4292
4337
|
}
|
|
4293
4338
|
|
|
4294
4339
|
// src/lib/manager/managed-skill-manifest.ts
|
|
4295
|
-
import { existsSync as existsSync5, mkdirSync as
|
|
4296
|
-
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";
|
|
4297
4342
|
var MANIFEST_VERSION = 1;
|
|
4298
4343
|
function managedSkillManifestPath(agentRootDir) {
|
|
4299
|
-
return
|
|
4344
|
+
return join17(agentRootDir, "managed-skills.json");
|
|
4300
4345
|
}
|
|
4301
4346
|
function readManagedSkillManifest(path) {
|
|
4302
4347
|
try {
|
|
4303
4348
|
if (!existsSync5(path)) return /* @__PURE__ */ new Set();
|
|
4304
|
-
const parsed = JSON.parse(
|
|
4349
|
+
const parsed = JSON.parse(readFileSync15(path, "utf-8"));
|
|
4305
4350
|
const ids = Array.isArray(parsed?.globalSkillIds) ? parsed.globalSkillIds : [];
|
|
4306
4351
|
return new Set(ids.filter((id) => typeof id === "string" && id.length > 0));
|
|
4307
4352
|
} catch {
|
|
@@ -4310,12 +4355,12 @@ function readManagedSkillManifest(path) {
|
|
|
4310
4355
|
}
|
|
4311
4356
|
function writeManagedSkillManifest(path, ids) {
|
|
4312
4357
|
try {
|
|
4313
|
-
|
|
4358
|
+
mkdirSync6(dirname5(path), { recursive: true });
|
|
4314
4359
|
const body = {
|
|
4315
4360
|
version: MANIFEST_VERSION,
|
|
4316
4361
|
globalSkillIds: [...ids].sort()
|
|
4317
4362
|
};
|
|
4318
|
-
|
|
4363
|
+
writeFileSync7(path, JSON.stringify(body, null, 2));
|
|
4319
4364
|
} catch {
|
|
4320
4365
|
}
|
|
4321
4366
|
}
|
|
@@ -4413,9 +4458,9 @@ function resolveModelChain(refreshData) {
|
|
|
4413
4458
|
}
|
|
4414
4459
|
|
|
4415
4460
|
// src/lib/manager/claude-auth.ts
|
|
4416
|
-
import { existsSync as existsSync6, rmSync as
|
|
4417
|
-
import { join as
|
|
4418
|
-
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";
|
|
4419
4464
|
async function applyClaudeAuthToEnv(childEnv, label) {
|
|
4420
4465
|
const apiKey = getApiKey();
|
|
4421
4466
|
if (!apiKey) {
|
|
@@ -4427,12 +4472,12 @@ async function applyClaudeAuthToEnv(childEnv, label) {
|
|
|
4427
4472
|
throw new Error("claude_auth_mode=api_key but /host/exchange returned no decrypted key");
|
|
4428
4473
|
}
|
|
4429
4474
|
childEnv.ANTHROPIC_API_KEY = exchange.anthropicApiKey;
|
|
4430
|
-
const claudeDir =
|
|
4475
|
+
const claudeDir = join18(homedir8(), ".claude");
|
|
4431
4476
|
for (const filename of [".credentials.json", "credentials.json"]) {
|
|
4432
|
-
const p =
|
|
4477
|
+
const p = join18(claudeDir, filename);
|
|
4433
4478
|
if (existsSync6(p)) {
|
|
4434
4479
|
try {
|
|
4435
|
-
|
|
4480
|
+
rmSync4(p, { force: true });
|
|
4436
4481
|
log(`[${label}] Removed ${p} (api_key mode \u2014 preventing OAuth fallback)`);
|
|
4437
4482
|
} catch {
|
|
4438
4483
|
}
|
|
@@ -4444,8 +4489,8 @@ async function applyClaudeAuthToEnv(childEnv, label) {
|
|
|
4444
4489
|
}
|
|
4445
4490
|
|
|
4446
4491
|
// src/lib/manager/kanban/parsers.ts
|
|
4447
|
-
import { existsSync as existsSync7, readFileSync as
|
|
4448
|
-
import { join as
|
|
4492
|
+
import { existsSync as existsSync7, readFileSync as readFileSync16 } from "fs";
|
|
4493
|
+
import { join as join19 } from "path";
|
|
4449
4494
|
var STANDUP_TEMPLATES = /* @__PURE__ */ new Set(["daily-standup", "end-of-day-summary"]);
|
|
4450
4495
|
var TASK_UPDATE_TEMPLATES = /* @__PURE__ */ new Set(["hourly-status", "task-update"]);
|
|
4451
4496
|
var PLAN_TEMPLATES = /* @__PURE__ */ new Set(["morning-plan"]);
|
|
@@ -4584,12 +4629,12 @@ function getBuiltInSkillContent(skillId) {
|
|
|
4584
4629
|
if (builtInSkillCache.has(skillId)) return builtInSkillCache.get(skillId);
|
|
4585
4630
|
try {
|
|
4586
4631
|
const candidates = [
|
|
4587
|
-
|
|
4588
|
-
|
|
4632
|
+
join19(process.cwd(), "skills", skillId, "SKILL.md"),
|
|
4633
|
+
join19(new URL(".", import.meta.url).pathname, "..", "..", "..", "..", "..", "..", "skills", skillId, "SKILL.md")
|
|
4589
4634
|
];
|
|
4590
4635
|
for (const candidate of candidates) {
|
|
4591
4636
|
if (existsSync7(candidate)) {
|
|
4592
|
-
const content =
|
|
4637
|
+
const content = readFileSync16(candidate, "utf-8");
|
|
4593
4638
|
const files = [{ relativePath: "SKILL.md", content }];
|
|
4594
4639
|
builtInSkillCache.set(skillId, files);
|
|
4595
4640
|
return files;
|
|
@@ -4730,19 +4775,19 @@ function formatBoardForPrompt(items, template) {
|
|
|
4730
4775
|
}
|
|
4731
4776
|
|
|
4732
4777
|
// src/lib/manager/kanban/nudge-state-cache.ts
|
|
4733
|
-
import { existsSync as existsSync8, readFileSync as
|
|
4734
|
-
import { join as
|
|
4778
|
+
import { existsSync as existsSync8, readFileSync as readFileSync17, writeFileSync as writeFileSync8 } from "fs";
|
|
4779
|
+
import { join as join20 } from "path";
|
|
4735
4780
|
var CACHE_FILENAME2 = "kanban-nudge-state.json";
|
|
4736
4781
|
var KANBAN_NUDGE_STATE_VERSION = 1;
|
|
4737
4782
|
function getKanbanNudgeStateFile(configDir) {
|
|
4738
|
-
return
|
|
4783
|
+
return join20(configDir, CACHE_FILENAME2);
|
|
4739
4784
|
}
|
|
4740
4785
|
function loadKanbanNudgeState(target, configDir) {
|
|
4741
4786
|
const path = getKanbanNudgeStateFile(configDir);
|
|
4742
4787
|
if (!existsSync8(path)) return;
|
|
4743
4788
|
let parsed;
|
|
4744
4789
|
try {
|
|
4745
|
-
parsed = JSON.parse(
|
|
4790
|
+
parsed = JSON.parse(readFileSync17(path, "utf-8"));
|
|
4746
4791
|
} catch {
|
|
4747
4792
|
return;
|
|
4748
4793
|
}
|
|
@@ -4767,7 +4812,7 @@ function saveKanbanNudgeState(source, configDir) {
|
|
|
4767
4812
|
const agents = {};
|
|
4768
4813
|
for (const [codeName, state7] of source) agents[codeName] = state7;
|
|
4769
4814
|
try {
|
|
4770
|
-
|
|
4815
|
+
writeFileSync8(path, JSON.stringify({ version: KANBAN_NUDGE_STATE_VERSION, agents }, null, 2));
|
|
4771
4816
|
} catch {
|
|
4772
4817
|
}
|
|
4773
4818
|
}
|
|
@@ -5308,9 +5353,9 @@ function closeScheduledRunsForCode(codeName, outcome, reason) {
|
|
|
5308
5353
|
|
|
5309
5354
|
// src/lib/manager/scheduler/kanban-route.ts
|
|
5310
5355
|
import { createHash as createHash11 } from "crypto";
|
|
5311
|
-
import { writeFileSync as
|
|
5312
|
-
import { homedir as
|
|
5313
|
-
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";
|
|
5314
5359
|
|
|
5315
5360
|
// src/lib/manager/scheduler/notify.ts
|
|
5316
5361
|
import { createHash as createHash10 } from "crypto";
|
|
@@ -5650,19 +5695,19 @@ function resolveScheduledSlackTarget(task) {
|
|
|
5650
5695
|
}
|
|
5651
5696
|
function stampScheduledTurnMarker(codeName, taskId, target) {
|
|
5652
5697
|
try {
|
|
5653
|
-
const file =
|
|
5698
|
+
const file = join21(homedir9(), ".augmented", codeName, SCHEDULED_TURN_MARKER_FILENAME);
|
|
5654
5699
|
const marker = { ts: Date.now(), task_id: taskId, ...target ? { target } : {} };
|
|
5655
5700
|
const tmp = `${file}.tmp`;
|
|
5656
|
-
|
|
5701
|
+
writeFileSync9(tmp, JSON.stringify(marker), "utf8");
|
|
5657
5702
|
renameSync2(tmp, file);
|
|
5658
5703
|
} catch (err) {
|
|
5659
5704
|
log(`[scheduled-kanban] scheduled-turn marker write failed for '${codeName}': ${err.message}`);
|
|
5660
5705
|
}
|
|
5661
5706
|
}
|
|
5662
5707
|
function clearScheduledTurnMarkerForTask(codeName, taskId) {
|
|
5663
|
-
const file =
|
|
5708
|
+
const file = join21(homedir9(), ".augmented", codeName, SCHEDULED_TURN_MARKER_FILENAME);
|
|
5664
5709
|
try {
|
|
5665
|
-
const raw = JSON.parse(
|
|
5710
|
+
const raw = JSON.parse(readFileSync18(file, "utf8"));
|
|
5666
5711
|
if (typeof raw?.task_id !== "string" || raw.task_id !== taskId) return;
|
|
5667
5712
|
unlinkSync(file);
|
|
5668
5713
|
log(`[scheduled-kanban] scheduled-turn marker cleared for '${codeName}' (task ${taskId} complete)`);
|
|
@@ -5716,9 +5761,9 @@ async function routeScheduledTaskViaKanban(codeName, agentId, task, prompt, dura
|
|
|
5716
5761
|
return false;
|
|
5717
5762
|
}
|
|
5718
5763
|
try {
|
|
5719
|
-
const doorbell = directChatDoorbellPath(agentId,
|
|
5720
|
-
|
|
5721
|
-
|
|
5764
|
+
const doorbell = directChatDoorbellPath(agentId, homedir9());
|
|
5765
|
+
mkdirSync7(dirname6(doorbell), { recursive: true });
|
|
5766
|
+
writeFileSync9(doorbell, String(Date.now()));
|
|
5722
5767
|
} catch (err) {
|
|
5723
5768
|
log(`[scheduled-kanban] doorbell ring failed for '${codeName}': ${err.message} (notice still queued)`);
|
|
5724
5769
|
}
|
|
@@ -5868,10 +5913,10 @@ async function processClaudeTaskResult(codeName, agentId, templateId, rawOutput,
|
|
|
5868
5913
|
|
|
5869
5914
|
// src/lib/manager/scheduler/execution.ts
|
|
5870
5915
|
import { createHash as createHash12 } from "crypto";
|
|
5871
|
-
import { homedir as
|
|
5872
|
-
import { join as
|
|
5916
|
+
import { homedir as homedir10 } from "os";
|
|
5917
|
+
import { join as join22 } from "path";
|
|
5873
5918
|
function claudePidFilePath() {
|
|
5874
|
-
return
|
|
5919
|
+
return join22(homedir10(), ".augmented", "manager-claude-pids.json");
|
|
5875
5920
|
}
|
|
5876
5921
|
var inFlightClaudePids = /* @__PURE__ */ new Map();
|
|
5877
5922
|
function registerClaudeSpawn(record) {
|
|
@@ -7104,9 +7149,9 @@ async function fireOpencodeScheduledTask(agent, task) {
|
|
|
7104
7149
|
|
|
7105
7150
|
// src/lib/opencode-telegram-ingest.ts
|
|
7106
7151
|
import { createHash as createHash15 } from "crypto";
|
|
7107
|
-
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";
|
|
7108
7153
|
import { randomUUID } from "crypto";
|
|
7109
|
-
import { join as
|
|
7154
|
+
import { join as join23 } from "path";
|
|
7110
7155
|
|
|
7111
7156
|
// src/lib/telegram-ingest.ts
|
|
7112
7157
|
import https2 from "https";
|
|
@@ -7654,7 +7699,7 @@ function createFileOffsetStore(codeName, log2, currentBotId) {
|
|
|
7654
7699
|
let filePath;
|
|
7655
7700
|
try {
|
|
7656
7701
|
dir = getFramework("opencode").getAgentDir(codeName);
|
|
7657
|
-
filePath =
|
|
7702
|
+
filePath = join23(dir, "telegram-getupdates-offset-opencode.json");
|
|
7658
7703
|
} catch {
|
|
7659
7704
|
dir = null;
|
|
7660
7705
|
filePath = null;
|
|
@@ -7663,7 +7708,7 @@ function createFileOffsetStore(codeName, log2, currentBotId) {
|
|
|
7663
7708
|
load() {
|
|
7664
7709
|
if (!filePath) return 0;
|
|
7665
7710
|
try {
|
|
7666
|
-
const parsed = JSON.parse(
|
|
7711
|
+
const parsed = JSON.parse(readFileSync19(filePath, "utf-8"));
|
|
7667
7712
|
if (currentBotId != null && typeof parsed?.bot_id === "number" && parsed.bot_id !== currentBotId) {
|
|
7668
7713
|
log2(`[telegram-ingest:${codeName}] offset cursor belongs to a different bot; ignoring (bot swap)`);
|
|
7669
7714
|
return 0;
|
|
@@ -7681,8 +7726,8 @@ function createFileOffsetStore(codeName, log2, currentBotId) {
|
|
|
7681
7726
|
if (!filePath || !dir) return;
|
|
7682
7727
|
const tmpPath = `${filePath}.${process.pid}.${randomUUID()}.tmp`;
|
|
7683
7728
|
try {
|
|
7684
|
-
|
|
7685
|
-
|
|
7729
|
+
mkdirSync8(dir, { recursive: true, mode: 448 });
|
|
7730
|
+
writeFileSync10(
|
|
7686
7731
|
tmpPath,
|
|
7687
7732
|
JSON.stringify({
|
|
7688
7733
|
offset,
|
|
@@ -7913,15 +7958,15 @@ function partitionActionableByPoison(actionable, states, config2) {
|
|
|
7913
7958
|
}
|
|
7914
7959
|
|
|
7915
7960
|
// src/lib/restart-flags.ts
|
|
7916
|
-
import { existsSync as existsSync10, mkdirSync as
|
|
7917
|
-
import { homedir as
|
|
7918
|
-
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";
|
|
7919
7964
|
import { randomUUID as randomUUID2 } from "crypto";
|
|
7920
7965
|
function restartFlagsDir() {
|
|
7921
|
-
return
|
|
7966
|
+
return join24(homedir11(), ".augmented", "restart-flags");
|
|
7922
7967
|
}
|
|
7923
7968
|
function flagPath(codeName) {
|
|
7924
|
-
return
|
|
7969
|
+
return join24(restartFlagsDir(), `${codeName}.flag`);
|
|
7925
7970
|
}
|
|
7926
7971
|
function readRestartFlags() {
|
|
7927
7972
|
const dir = restartFlagsDir();
|
|
@@ -7930,7 +7975,7 @@ function readRestartFlags() {
|
|
|
7930
7975
|
for (const entry of readdirSync5(dir)) {
|
|
7931
7976
|
if (!entry.endsWith(".flag")) continue;
|
|
7932
7977
|
try {
|
|
7933
|
-
const raw =
|
|
7978
|
+
const raw = readFileSync20(join24(dir, entry), "utf8");
|
|
7934
7979
|
const parsed = JSON.parse(raw);
|
|
7935
7980
|
if (typeof parsed.codeName !== "string" || parsed.codeName.length === 0) {
|
|
7936
7981
|
parsed.codeName = entry.replace(/\.flag$/, "");
|
|
@@ -7949,7 +7994,7 @@ function readRestartFlags() {
|
|
|
7949
7994
|
function deleteRestartFlag(codeName) {
|
|
7950
7995
|
const path = flagPath(codeName);
|
|
7951
7996
|
if (existsSync10(path)) {
|
|
7952
|
-
|
|
7997
|
+
rmSync5(path, { force: true });
|
|
7953
7998
|
}
|
|
7954
7999
|
}
|
|
7955
8000
|
|
|
@@ -8048,8 +8093,8 @@ async function sendError(flag, opts, text) {
|
|
|
8048
8093
|
}
|
|
8049
8094
|
|
|
8050
8095
|
// src/lib/restart-context.ts
|
|
8051
|
-
import { readdirSync as readdirSync6, readFileSync as
|
|
8052
|
-
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";
|
|
8053
8098
|
var SLACK_PENDING_INBOUND_DIRNAME = "slack-pending-inbound";
|
|
8054
8099
|
var SLACK_RESTART_CONTEXT_DIRNAME = "slack-restart-context";
|
|
8055
8100
|
var MAX_TOPIC_CHARS = 140;
|
|
@@ -8061,10 +8106,10 @@ function augmentedAgentDir(codeName) {
|
|
|
8061
8106
|
return dirname7(getProjectDir(codeName));
|
|
8062
8107
|
}
|
|
8063
8108
|
function slackPendingInboundDir(codeName) {
|
|
8064
|
-
return
|
|
8109
|
+
return join25(augmentedAgentDir(codeName), SLACK_PENDING_INBOUND_DIRNAME);
|
|
8065
8110
|
}
|
|
8066
8111
|
function slackRestartContextDir(codeName) {
|
|
8067
|
-
return
|
|
8112
|
+
return join25(augmentedAgentDir(codeName), SLACK_RESTART_CONTEXT_DIRNAME);
|
|
8068
8113
|
}
|
|
8069
8114
|
function sanitizeTopic(raw) {
|
|
8070
8115
|
const cleaned = raw.replace(/\s+/g, " ").trim().replace(/[<>]/g, " ").replace(/\s+/g, " ").trim();
|
|
@@ -8106,7 +8151,7 @@ function safeReaddir(dir) {
|
|
|
8106
8151
|
}
|
|
8107
8152
|
function readStrandedMarker(path) {
|
|
8108
8153
|
try {
|
|
8109
|
-
const parsed = JSON.parse(
|
|
8154
|
+
const parsed = JSON.parse(readFileSync21(path, "utf-8"));
|
|
8110
8155
|
if (typeof parsed.channel === "string" && typeof parsed.thread_ts === "string") {
|
|
8111
8156
|
return { channel: parsed.channel, thread_ts: parsed.thread_ts };
|
|
8112
8157
|
}
|
|
@@ -8115,8 +8160,8 @@ function readStrandedMarker(path) {
|
|
|
8115
8160
|
return null;
|
|
8116
8161
|
}
|
|
8117
8162
|
function writeHintFile(path, dir, hint) {
|
|
8118
|
-
|
|
8119
|
-
|
|
8163
|
+
mkdirSync10(dir, { recursive: true, mode: 448 });
|
|
8164
|
+
writeFileSync12(path, JSON.stringify(hint), { mode: 384 });
|
|
8120
8165
|
}
|
|
8121
8166
|
function pruneHintsExcept(codeName, freshFilenames) {
|
|
8122
8167
|
const ctxDir = slackRestartContextDir(codeName);
|
|
@@ -8124,7 +8169,7 @@ function pruneHintsExcept(codeName, freshFilenames) {
|
|
|
8124
8169
|
if (!filename.endsWith(".json")) continue;
|
|
8125
8170
|
if (freshFilenames.has(filename)) continue;
|
|
8126
8171
|
try {
|
|
8127
|
-
unlinkSync3(
|
|
8172
|
+
unlinkSync3(join25(ctxDir, filename));
|
|
8128
8173
|
} catch {
|
|
8129
8174
|
}
|
|
8130
8175
|
}
|
|
@@ -8145,7 +8190,7 @@ function refreshSlackRestartContextHints(codeNames, opts = {}) {
|
|
|
8145
8190
|
}
|
|
8146
8191
|
const markers = [];
|
|
8147
8192
|
for (const filename of markerFilenames.slice(0, cap)) {
|
|
8148
|
-
const parsed = readStrandedMarker(
|
|
8193
|
+
const parsed = readStrandedMarker(join25(markerDir, filename));
|
|
8149
8194
|
if (parsed) markers.push({ filename, channel: parsed.channel, thread_ts: parsed.thread_ts });
|
|
8150
8195
|
}
|
|
8151
8196
|
if (markers.length === 0) {
|
|
@@ -8159,7 +8204,7 @@ function refreshSlackRestartContextHints(codeNames, opts = {}) {
|
|
|
8159
8204
|
const freshFilenames = /* @__PURE__ */ new Set();
|
|
8160
8205
|
for (const { filename, hint } of hints) {
|
|
8161
8206
|
try {
|
|
8162
|
-
writeHintFile(
|
|
8207
|
+
writeHintFile(join25(ctxDir, filename), ctxDir, hint);
|
|
8163
8208
|
freshFilenames.add(filename);
|
|
8164
8209
|
} catch (err) {
|
|
8165
8210
|
log2(`[restart-context] ${codeName}: hint write failed for ${filename}: ${err.message}`);
|
|
@@ -9390,7 +9435,7 @@ var runningChannelSecretHashes = /* @__PURE__ */ new Map();
|
|
|
9390
9435
|
var sessionLaunchManagedStructure = /* @__PURE__ */ new Map();
|
|
9391
9436
|
function projectMcpHash(_codeName, projectDir) {
|
|
9392
9437
|
try {
|
|
9393
|
-
const raw =
|
|
9438
|
+
const raw = readFileSync22(join26(projectDir, ".mcp.json"), "utf-8");
|
|
9394
9439
|
return createHash16("sha256").update(canonicalJson(JSON.parse(raw))).digest("hex");
|
|
9395
9440
|
} catch {
|
|
9396
9441
|
return null;
|
|
@@ -9398,7 +9443,7 @@ function projectMcpHash(_codeName, projectDir) {
|
|
|
9398
9443
|
}
|
|
9399
9444
|
function projectMcpKeys(_codeName, projectDir) {
|
|
9400
9445
|
try {
|
|
9401
|
-
const raw =
|
|
9446
|
+
const raw = readFileSync22(join26(projectDir, ".mcp.json"), "utf-8");
|
|
9402
9447
|
const parsed = JSON.parse(raw);
|
|
9403
9448
|
const servers = parsed.mcpServers;
|
|
9404
9449
|
if (!servers || typeof servers !== "object") return /* @__PURE__ */ new Set();
|
|
@@ -9416,7 +9461,7 @@ function seedSessionLaunchBaselines(codeName, projectDir) {
|
|
|
9416
9461
|
else runningMcpServerKeys.delete(codeName);
|
|
9417
9462
|
let launchStructure = null;
|
|
9418
9463
|
try {
|
|
9419
|
-
const raw =
|
|
9464
|
+
const raw = readFileSync22(join26(projectDir, ".mcp.json"), "utf-8");
|
|
9420
9465
|
launchStructure = managedMcpStructureHashFromFile(
|
|
9421
9466
|
JSON.parse(raw),
|
|
9422
9467
|
isManagedMcpServerKey
|
|
@@ -9520,7 +9565,7 @@ async function runAgentSessionToolBindProbes(agent, integrations, projectDir, op
|
|
|
9520
9565
|
if (result && result.rebindCandidates.length > 0 && hostFlagStore().getBoolean("session-tool-rebind")) {
|
|
9521
9566
|
let mcpJsonForRebind = null;
|
|
9522
9567
|
try {
|
|
9523
|
-
mcpJsonForRebind = JSON.parse(
|
|
9568
|
+
mcpJsonForRebind = JSON.parse(readFileSync22(join26(projectDir, ".mcp.json"), "utf-8"));
|
|
9524
9569
|
} catch {
|
|
9525
9570
|
mcpJsonForRebind = null;
|
|
9526
9571
|
}
|
|
@@ -9671,7 +9716,7 @@ function checkMcpConfigDriftAndScheduleRestart(codeName, projectDir) {
|
|
|
9671
9716
|
function projectChannelSecretHash(projectDir) {
|
|
9672
9717
|
try {
|
|
9673
9718
|
const entries = parseEnvIntegrations(
|
|
9674
|
-
|
|
9719
|
+
readFileSync22(join26(projectDir, ".env.integrations"), "utf-8")
|
|
9675
9720
|
);
|
|
9676
9721
|
return channelSecretValueHash(entries, CHANNEL_SECRET_ENV_KEYS);
|
|
9677
9722
|
} catch {
|
|
@@ -9767,7 +9812,7 @@ var agentRestartTimezoneInputs = /* @__PURE__ */ new Map();
|
|
|
9767
9812
|
var lastVersionCheckAt = 0;
|
|
9768
9813
|
var VERSION_CHECK_INTERVAL_MS = 5 * 60 * 1e3;
|
|
9769
9814
|
var lastResponsivenessProbeAt = 0;
|
|
9770
|
-
var agtCliVersion = true ? "0.28.
|
|
9815
|
+
var agtCliVersion = true ? "0.28.441" : "dev";
|
|
9771
9816
|
function resolveBrewPath(execFileSync2) {
|
|
9772
9817
|
try {
|
|
9773
9818
|
const out = execFileSync2("which", ["brew"], { timeout: 5e3 }).toString().trim();
|
|
@@ -10056,7 +10101,7 @@ function ensureClaudeManagedSettings(path = claudeManagedSettingsPath()) {
|
|
|
10056
10101
|
try {
|
|
10057
10102
|
let settings = {};
|
|
10058
10103
|
if (existsSync11(path)) {
|
|
10059
|
-
const raw =
|
|
10104
|
+
const raw = readFileSync22(path, "utf-8").trim();
|
|
10060
10105
|
if (raw) {
|
|
10061
10106
|
let parsed;
|
|
10062
10107
|
try {
|
|
@@ -10072,8 +10117,8 @@ function ensureClaudeManagedSettings(path = claudeManagedSettingsPath()) {
|
|
|
10072
10117
|
}
|
|
10073
10118
|
if (settings.channelsEnabled === true) return "ok";
|
|
10074
10119
|
settings.channelsEnabled = true;
|
|
10075
|
-
|
|
10076
|
-
|
|
10120
|
+
mkdirSync11(dirname8(path), { recursive: true });
|
|
10121
|
+
writeFileSync13(path, `${JSON.stringify(settings, null, 2)}
|
|
10077
10122
|
`);
|
|
10078
10123
|
log(`[managed-settings] set channelsEnabled:true in ${path} (ENG-5786 \u2014 unblocks Claude Code channels)`);
|
|
10079
10124
|
return "ok";
|
|
@@ -10111,7 +10156,7 @@ async function ensureOpencodeBinary() {
|
|
|
10111
10156
|
try {
|
|
10112
10157
|
const prefix = execFileSync2("npm", ["prefix", "-g"], { encoding: "utf-8", timeout: 1e4 }).trim();
|
|
10113
10158
|
if (prefix) {
|
|
10114
|
-
const npmBin =
|
|
10159
|
+
const npmBin = join26(prefix, "bin");
|
|
10115
10160
|
const current = (process.env.PATH ?? "").split(pathDelimiter);
|
|
10116
10161
|
if (!current.includes(npmBin)) {
|
|
10117
10162
|
process.env.PATH = [npmBin, ...current.filter(Boolean)].join(pathDelimiter);
|
|
@@ -10228,7 +10273,7 @@ ${r.stderr}`;
|
|
|
10228
10273
|
}
|
|
10229
10274
|
var UPDATE_CHECK_INTERVAL_MS = 5 * 60 * 1e3;
|
|
10230
10275
|
function selfUpdateAppliedMarkerPath() {
|
|
10231
|
-
return
|
|
10276
|
+
return join26(homedir12(), ".augmented", ".last-self-update-applied");
|
|
10232
10277
|
}
|
|
10233
10278
|
var selfUpdateUpToDateLogged = false;
|
|
10234
10279
|
var selfUpdatePinnedLogged = false;
|
|
@@ -10256,7 +10301,7 @@ async function checkAndUpdateCli(opts) {
|
|
|
10256
10301
|
const isNpmGlobal = !isBrewFormula && resolvedPath.includes("node_modules");
|
|
10257
10302
|
if (!isBrewFormula && !isNpmGlobal) return "noop";
|
|
10258
10303
|
const { readFileSync: readF, writeFileSync: writeF } = await import("fs");
|
|
10259
|
-
const markerPath =
|
|
10304
|
+
const markerPath = join26(homedir12(), ".augmented", ".last-update-check");
|
|
10260
10305
|
if (!force) {
|
|
10261
10306
|
try {
|
|
10262
10307
|
const lastCheck = parseInt(readF(markerPath, "utf-8").trim(), 10);
|
|
@@ -10616,13 +10661,13 @@ async function checkClaudeAuth() {
|
|
|
10616
10661
|
var evalEmptyMcpConfigPath = null;
|
|
10617
10662
|
function ensureEvalEmptyMcpConfig() {
|
|
10618
10663
|
if (evalEmptyMcpConfigPath && existsSync11(evalEmptyMcpConfigPath)) return evalEmptyMcpConfigPath;
|
|
10619
|
-
const dir =
|
|
10664
|
+
const dir = join26(homedir12(), ".augmented");
|
|
10620
10665
|
try {
|
|
10621
|
-
|
|
10666
|
+
mkdirSync11(dir, { recursive: true });
|
|
10622
10667
|
} catch {
|
|
10623
10668
|
}
|
|
10624
|
-
const p =
|
|
10625
|
-
|
|
10669
|
+
const p = join26(dir, ".eval-empty-mcp.json");
|
|
10670
|
+
writeFileSync13(p, JSON.stringify({ mcpServers: {} }));
|
|
10626
10671
|
evalEmptyMcpConfigPath = p;
|
|
10627
10672
|
return p;
|
|
10628
10673
|
}
|
|
@@ -10647,7 +10692,7 @@ async function runEvalClaude(prompt, model) {
|
|
|
10647
10692
|
""
|
|
10648
10693
|
];
|
|
10649
10694
|
const { stdout } = await execFilePromiseLong(resolveClaudeBinary(), args, {
|
|
10650
|
-
cwd:
|
|
10695
|
+
cwd: homedir12(),
|
|
10651
10696
|
timeout: 12e4,
|
|
10652
10697
|
stdin: "ignore",
|
|
10653
10698
|
env: childEnv,
|
|
@@ -10713,10 +10758,10 @@ function resolveConversationEvalBackend() {
|
|
|
10713
10758
|
return conversationEvalBackend;
|
|
10714
10759
|
}
|
|
10715
10760
|
function getStateFile() {
|
|
10716
|
-
return
|
|
10761
|
+
return join26(config?.configDir ?? join26(process.env["HOME"] ?? "/tmp", ".augmented"), "manager-state.json");
|
|
10717
10762
|
}
|
|
10718
10763
|
function channelHashCacheDir() {
|
|
10719
|
-
return config?.configDir ??
|
|
10764
|
+
return config?.configDir ?? join26(process.env["HOME"] ?? "/tmp", ".augmented");
|
|
10720
10765
|
}
|
|
10721
10766
|
function loadChannelHashCache2() {
|
|
10722
10767
|
loadChannelHashCache(agentState.knownChannelConfigHashes, channelHashCacheDir());
|
|
@@ -10768,7 +10813,7 @@ function removeDeliveryBaselineEntries(agentId) {
|
|
|
10768
10813
|
var _channelQuarantineStore = null;
|
|
10769
10814
|
function channelQuarantineStore() {
|
|
10770
10815
|
if (!_channelQuarantineStore) {
|
|
10771
|
-
const dir = config?.configDir ??
|
|
10816
|
+
const dir = config?.configDir ?? join26(process.env["HOME"] ?? "/tmp", ".augmented");
|
|
10772
10817
|
_channelQuarantineStore = new ChannelQuarantineStore(defaultQuarantinePath(dir));
|
|
10773
10818
|
}
|
|
10774
10819
|
return _channelQuarantineStore;
|
|
@@ -10785,7 +10830,7 @@ function claudeMdSizeFor(codeName) {
|
|
|
10785
10830
|
var _hostFlagStore = null;
|
|
10786
10831
|
function hostFlagStore() {
|
|
10787
10832
|
if (!_hostFlagStore) {
|
|
10788
|
-
const dir = config?.configDir ??
|
|
10833
|
+
const dir = config?.configDir ?? join26(process.env["HOME"] ?? "/tmp", ".augmented");
|
|
10789
10834
|
_hostFlagStore = new HostFlagStore({ cachePath: defaultFlagsCachePath(dir), log });
|
|
10790
10835
|
}
|
|
10791
10836
|
return _hostFlagStore;
|
|
@@ -10852,13 +10897,13 @@ function parseSkillFrontmatter(content) {
|
|
|
10852
10897
|
return out;
|
|
10853
10898
|
}
|
|
10854
10899
|
async function refreshSkillsIndexInClaudeMd(configDir, codeName, log2) {
|
|
10855
|
-
const { readdirSync: readdirSync8, readFileSync: rfs, existsSync: ex, writeFileSync:
|
|
10856
|
-
const skillsDir =
|
|
10857
|
-
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");
|
|
10858
10903
|
if (!ex(skillsDir) || !ex(claudeMdPath)) return;
|
|
10859
10904
|
const entries = [];
|
|
10860
10905
|
for (const dir of readdirSync8(skillsDir).sort()) {
|
|
10861
|
-
const skillFile =
|
|
10906
|
+
const skillFile = join26(skillsDir, dir, "SKILL.md");
|
|
10862
10907
|
if (!ex(skillFile)) continue;
|
|
10863
10908
|
try {
|
|
10864
10909
|
const { name, description } = parseSkillFrontmatter(rfs(skillFile, "utf-8"));
|
|
@@ -10902,7 +10947,7 @@ ${SKILLS_INDEX_END}`;
|
|
|
10902
10947
|
next = current.trimEnd() + "\n\n" + section + "\n";
|
|
10903
10948
|
}
|
|
10904
10949
|
if (next !== current) {
|
|
10905
|
-
|
|
10950
|
+
writeFileSync14(claudeMdPath, next, "utf-8");
|
|
10906
10951
|
log2(
|
|
10907
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)`
|
|
10908
10953
|
);
|
|
@@ -10925,7 +10970,7 @@ function flushRestartedAgentDiagnostics(hostId, codeNames) {
|
|
|
10925
10970
|
if (codeNames.length === 0) return;
|
|
10926
10971
|
void (async () => {
|
|
10927
10972
|
try {
|
|
10928
|
-
const { collectDiagnostics } = await import("../persistent-session-
|
|
10973
|
+
const { collectDiagnostics } = await import("../persistent-session-PWLMLDVX.js");
|
|
10929
10974
|
await api.post("/host/heartbeat", {
|
|
10930
10975
|
host_id: hostId,
|
|
10931
10976
|
agent_diagnostics: collectDiagnostics(codeNames, quarantineEntriesFor, claudeMdSizeFor)
|
|
@@ -11032,7 +11077,7 @@ async function pollCycle() {
|
|
|
11032
11077
|
}
|
|
11033
11078
|
try {
|
|
11034
11079
|
const { detectHostSecurity } = await import("../host-security-6PDFG7F5.js");
|
|
11035
|
-
const { collectDiagnostics } = await import("../persistent-session-
|
|
11080
|
+
const { collectDiagnostics } = await import("../persistent-session-PWLMLDVX.js");
|
|
11036
11081
|
const diagCodeNames = [...agentState.persistentSessionAgents];
|
|
11037
11082
|
const agentDiagnostics = diagCodeNames.length > 0 ? collectDiagnostics(diagCodeNames, quarantineEntriesFor, claudeMdSizeFor) : void 0;
|
|
11038
11083
|
let tailscaleHostname;
|
|
@@ -11146,7 +11191,7 @@ async function pollCycle() {
|
|
|
11146
11191
|
collectResponsivenessProbes,
|
|
11147
11192
|
collectPanelessActivityProbes,
|
|
11148
11193
|
getResponsivenessIntervalMs
|
|
11149
|
-
} = await import("../responsiveness-probe-
|
|
11194
|
+
} = await import("../responsiveness-probe-ZKUDFRIU.js");
|
|
11150
11195
|
const probeIntervalMs = getResponsivenessIntervalMs();
|
|
11151
11196
|
if (now - lastResponsivenessProbeAt > probeIntervalMs) {
|
|
11152
11197
|
const probeCodeNames = [...agentState.persistentSessionAgents];
|
|
@@ -11210,7 +11255,7 @@ async function pollCycle() {
|
|
|
11210
11255
|
collectResponsivenessProbes,
|
|
11211
11256
|
livePendingInboundOldestAgeSeconds,
|
|
11212
11257
|
parkPendingInbound
|
|
11213
|
-
} = await import("../responsiveness-probe-
|
|
11258
|
+
} = await import("../responsiveness-probe-ZKUDFRIU.js");
|
|
11214
11259
|
const { getProjectDir: wedgeProjectDir } = await import("../scheduler-engine-NDP36U7O.js");
|
|
11215
11260
|
const wedgeNow = /* @__PURE__ */ new Date();
|
|
11216
11261
|
const liveAgents = agentState.persistentSessionAgents;
|
|
@@ -11299,13 +11344,13 @@ async function pollCycle() {
|
|
|
11299
11344
|
);
|
|
11300
11345
|
if (hostFlagStore().getBoolean("wedge-transient-notice")) {
|
|
11301
11346
|
try {
|
|
11302
|
-
const paneTail =
|
|
11347
|
+
const paneTail = readFileSync22(paneLogPath(codeName), "utf8").slice(-65536);
|
|
11303
11348
|
const transient = detectTransientApiErrorInLog(paneTail);
|
|
11304
11349
|
if (transient) {
|
|
11305
|
-
const wedgeHome =
|
|
11350
|
+
const wedgeHome = join26(homedir12(), ".augmented", codeName);
|
|
11306
11351
|
if (existsSync11(wedgeHome)) {
|
|
11307
11352
|
atomicWriteFileSync(
|
|
11308
|
-
|
|
11353
|
+
join26(wedgeHome, "watchdog-give-up.json"),
|
|
11309
11354
|
JSON.stringify({
|
|
11310
11355
|
gave_up_at: wedgeNow.toISOString(),
|
|
11311
11356
|
reason: "transient_overload"
|
|
@@ -11576,8 +11621,8 @@ async function pollCycle() {
|
|
|
11576
11621
|
const adapter = resolveAgentFramework(prev.codeName);
|
|
11577
11622
|
stopAgentRuntime2(prev.codeName, "removed-from-host");
|
|
11578
11623
|
killAgentChannelProcesses(prev.codeName, { log });
|
|
11579
|
-
const
|
|
11580
|
-
await cleanupAgentFiles(prev.codeName,
|
|
11624
|
+
const agentDir2 = join26(adapter.getAgentDir(prev.codeName), "provision");
|
|
11625
|
+
await cleanupAgentFiles(prev.codeName, agentDir2);
|
|
11581
11626
|
clearAgentCaches(prev.agentId, prev.codeName);
|
|
11582
11627
|
}
|
|
11583
11628
|
}
|
|
@@ -11663,10 +11708,10 @@ async function pollCycle() {
|
|
|
11663
11708
|
// pending-inbound marker. Best-effort: a write failure is logged by
|
|
11664
11709
|
// the watchdog, never fails the poll cycle.
|
|
11665
11710
|
signalGiveUp: (codeName) => {
|
|
11666
|
-
const dir =
|
|
11711
|
+
const dir = join26(homedir12(), ".augmented", codeName);
|
|
11667
11712
|
if (!existsSync11(dir)) return;
|
|
11668
11713
|
atomicWriteFileSync(
|
|
11669
|
-
|
|
11714
|
+
join26(dir, "watchdog-give-up.json"),
|
|
11670
11715
|
JSON.stringify({ gave_up_at: (/* @__PURE__ */ new Date()).toISOString() })
|
|
11671
11716
|
);
|
|
11672
11717
|
}
|
|
@@ -11806,7 +11851,7 @@ async function processAgent(agent, agentStates) {
|
|
|
11806
11851
|
}
|
|
11807
11852
|
const now = (/* @__PURE__ */ new Date()).toISOString();
|
|
11808
11853
|
const adapter = resolveAgentFramework(agent.code_name);
|
|
11809
|
-
let
|
|
11854
|
+
let agentDir2 = join26(adapter.getAgentDir(agent.code_name), "provision");
|
|
11810
11855
|
if (agent.status === "draft" || agent.status === "paused") {
|
|
11811
11856
|
if (previousKnownStatus !== agent.status) {
|
|
11812
11857
|
log(`Agent '${agent.code_name}' is ${agent.status}, skipping provisioning`);
|
|
@@ -11846,7 +11891,7 @@ async function processAgent(agent, agentStates) {
|
|
|
11846
11891
|
const residuals = {
|
|
11847
11892
|
gatewayRunning: false,
|
|
11848
11893
|
portAllocated: false,
|
|
11849
|
-
provisionDirExists: existsSync11(
|
|
11894
|
+
provisionDirExists: existsSync11(agentDir2)
|
|
11850
11895
|
};
|
|
11851
11896
|
if (!hasRevokedResiduals(residuals)) {
|
|
11852
11897
|
agentStates.push({
|
|
@@ -11871,7 +11916,7 @@ async function processAgent(agent, agentStates) {
|
|
|
11871
11916
|
log(`Agent '${agent.code_name}' is revoked, cleaning up`);
|
|
11872
11917
|
stopAgentRuntime2(agent.code_name, "revoked");
|
|
11873
11918
|
killAgentChannelProcesses(agent.code_name, { log });
|
|
11874
|
-
await cleanupAgentFiles(agent.code_name,
|
|
11919
|
+
await cleanupAgentFiles(agent.code_name, agentDir2);
|
|
11875
11920
|
clearAgentCaches(agent.agent_id, agent.code_name);
|
|
11876
11921
|
agentState.knownStatuses.set(agent.agent_id, agent.status);
|
|
11877
11922
|
agentStates.push({
|
|
@@ -11979,7 +12024,7 @@ async function processAgent(agent, agentStates) {
|
|
|
11979
12024
|
const frameworkId = refreshData.agent.framework ?? DEFAULT_FRAMEWORK;
|
|
11980
12025
|
agentFrameworkCache.set(agent.code_name, frameworkId);
|
|
11981
12026
|
const frameworkAdapter = getFramework(frameworkId);
|
|
11982
|
-
|
|
12027
|
+
agentDir2 = join26(frameworkAdapter.getAgentDir(agent.code_name), "provision");
|
|
11983
12028
|
cacheAgentDeliveryMetadata(agent.code_name, refreshData);
|
|
11984
12029
|
agentRestartTimezoneInputs.set(agent.code_name, {
|
|
11985
12030
|
agentTimezone: typeof refreshData.agent.timezone === "string" ? refreshData.agent.timezone : null,
|
|
@@ -12026,9 +12071,9 @@ async function processAgent(agent, agentStates) {
|
|
|
12026
12071
|
try {
|
|
12027
12072
|
const artifacts = generateArtifacts(agent, refreshData, frameworkAdapter);
|
|
12028
12073
|
const changedFiles = [];
|
|
12029
|
-
|
|
12074
|
+
mkdirSync11(agentDir2, { recursive: true });
|
|
12030
12075
|
for (const artifact of artifacts) {
|
|
12031
|
-
const filePath =
|
|
12076
|
+
const filePath = join26(agentDir2, artifact.relativePath);
|
|
12032
12077
|
let existingHash;
|
|
12033
12078
|
let newHash;
|
|
12034
12079
|
let writeContent = artifact.content;
|
|
@@ -12047,8 +12092,8 @@ async function processAgent(agent, agentStates) {
|
|
|
12047
12092
|
};
|
|
12048
12093
|
newHash = sha256(stripDynamicSections(artifact.content));
|
|
12049
12094
|
try {
|
|
12050
|
-
const projectClaudeMd =
|
|
12051
|
-
const existing =
|
|
12095
|
+
const projectClaudeMd = join26(config.configDir, agent.code_name, "project", "CLAUDE.md");
|
|
12096
|
+
const existing = readFileSync22(projectClaudeMd, "utf-8");
|
|
12052
12097
|
existingHash = sha256(stripDynamicSections(existing));
|
|
12053
12098
|
} catch {
|
|
12054
12099
|
existingHash = null;
|
|
@@ -12066,7 +12111,7 @@ async function processAgent(agent, agentStates) {
|
|
|
12066
12111
|
const generatorKeys = Object.keys(generatorServers);
|
|
12067
12112
|
let existingRaw = "";
|
|
12068
12113
|
try {
|
|
12069
|
-
existingRaw =
|
|
12114
|
+
existingRaw = readFileSync22(filePath, "utf-8");
|
|
12070
12115
|
} catch {
|
|
12071
12116
|
}
|
|
12072
12117
|
const existingServers = parseMcp(existingRaw);
|
|
@@ -12082,7 +12127,7 @@ async function processAgent(agent, agentStates) {
|
|
|
12082
12127
|
} else if (artifact.relativePath === "opencode.json") {
|
|
12083
12128
|
let existingRaw = null;
|
|
12084
12129
|
try {
|
|
12085
|
-
existingRaw =
|
|
12130
|
+
existingRaw = readFileSync22(filePath, "utf-8");
|
|
12086
12131
|
} catch {
|
|
12087
12132
|
}
|
|
12088
12133
|
const mergeResult = mergeOpencodeConfigArtifact(artifact.content, existingRaw);
|
|
@@ -12098,26 +12143,26 @@ async function processAgent(agent, agentStates) {
|
|
|
12098
12143
|
}
|
|
12099
12144
|
}
|
|
12100
12145
|
if (changedFiles.length > 0) {
|
|
12101
|
-
const isFirst = !existsSync11(
|
|
12146
|
+
const isFirst = !existsSync11(join26(agentDir2, "CHARTER.md"));
|
|
12102
12147
|
const verb = isFirst ? "Provisioning" : "Updating";
|
|
12103
12148
|
const fileNames = changedFiles.map((f) => f.relativePath).join(", ");
|
|
12104
12149
|
log(`${verb} '${agent.code_name}': ${fileNames}`);
|
|
12105
12150
|
for (const file of changedFiles) {
|
|
12106
|
-
const filePath =
|
|
12107
|
-
|
|
12151
|
+
const filePath = join26(agentDir2, file.relativePath);
|
|
12152
|
+
mkdirSync11(dirname8(filePath), { recursive: true });
|
|
12108
12153
|
if (file.relativePath === ".mcp.json") {
|
|
12109
12154
|
safeWriteJsonAtomic(filePath, file.content, { mode: 384 });
|
|
12110
12155
|
} else {
|
|
12111
|
-
|
|
12156
|
+
writeFileSync13(filePath, file.content);
|
|
12112
12157
|
}
|
|
12113
12158
|
}
|
|
12114
12159
|
try {
|
|
12115
|
-
const provSkillsDir =
|
|
12160
|
+
const provSkillsDir = join26(agentDir2, ".claude", "skills");
|
|
12116
12161
|
if (existsSync11(provSkillsDir)) {
|
|
12117
12162
|
for (const folder of readdirSync7(provSkillsDir)) {
|
|
12118
12163
|
if (folder.startsWith("knowledge-")) {
|
|
12119
12164
|
try {
|
|
12120
|
-
|
|
12165
|
+
rmSync6(join26(provSkillsDir, folder), { recursive: true });
|
|
12121
12166
|
} catch {
|
|
12122
12167
|
}
|
|
12123
12168
|
}
|
|
@@ -12130,7 +12175,7 @@ async function processAgent(agent, agentStates) {
|
|
|
12130
12175
|
const trackedFiles2 = frameworkAdapter.driftTrackedFiles();
|
|
12131
12176
|
const hashes = /* @__PURE__ */ new Map();
|
|
12132
12177
|
for (const file of trackedFiles2) {
|
|
12133
|
-
const h = hashFile(
|
|
12178
|
+
const h = hashFile(join26(agentDir2, file));
|
|
12134
12179
|
if (h) hashes.set(file, h);
|
|
12135
12180
|
}
|
|
12136
12181
|
agentState.writtenHashes.set(agent.agent_id, hashes);
|
|
@@ -12138,7 +12183,7 @@ async function processAgent(agent, agentStates) {
|
|
|
12138
12183
|
const primaryModel2 = resolvedModelsForRegistration.primary ?? refreshData.agent.primary_model;
|
|
12139
12184
|
const registeredAgents = await getOrCacheRegisteredAgents(frameworkAdapter, agent.code_name);
|
|
12140
12185
|
if (!registeredAgents.has(agent.code_name)) {
|
|
12141
|
-
const registered = await frameworkAdapter.registerAgent(agent.code_name,
|
|
12186
|
+
const registered = await frameworkAdapter.registerAgent(agent.code_name, agentDir2, primaryModel2, agent.agent_id);
|
|
12142
12187
|
if (registered) {
|
|
12143
12188
|
registeredAgents.add(agent.code_name);
|
|
12144
12189
|
log(`Registered '${agent.code_name}' in ${frameworkAdapter.label}`);
|
|
@@ -12148,14 +12193,14 @@ async function processAgent(agent, agentStates) {
|
|
|
12148
12193
|
}
|
|
12149
12194
|
if (Array.isArray(refreshData.workflows)) {
|
|
12150
12195
|
try {
|
|
12151
|
-
const provWorkflowsDir =
|
|
12196
|
+
const provWorkflowsDir = join26(agentDir2, ".claude", "workflows");
|
|
12152
12197
|
if (existsSync11(provWorkflowsDir)) {
|
|
12153
12198
|
const expected = new Set(refreshData.workflows.map((w) => `${w.name}.js`));
|
|
12154
12199
|
for (const file of readdirSync7(provWorkflowsDir)) {
|
|
12155
12200
|
if (!file.endsWith(".js")) continue;
|
|
12156
12201
|
if (expected.has(file)) continue;
|
|
12157
12202
|
try {
|
|
12158
|
-
|
|
12203
|
+
rmSync6(join26(provWorkflowsDir, file));
|
|
12159
12204
|
} catch {
|
|
12160
12205
|
}
|
|
12161
12206
|
}
|
|
@@ -12164,7 +12209,7 @@ async function processAgent(agent, agentStates) {
|
|
|
12164
12209
|
}
|
|
12165
12210
|
}
|
|
12166
12211
|
if (frameworkAdapter.deployArtifactsToProject) {
|
|
12167
|
-
frameworkAdapter.deployArtifactsToProject(agent.code_name,
|
|
12212
|
+
frameworkAdapter.deployArtifactsToProject(agent.code_name, agentDir2);
|
|
12168
12213
|
}
|
|
12169
12214
|
} catch (err) {
|
|
12170
12215
|
log(`Provision failed for '${agent.code_name}': ${err.message}`);
|
|
@@ -12234,10 +12279,10 @@ async function processAgent(agent, agentStates) {
|
|
|
12234
12279
|
}
|
|
12235
12280
|
let lastDriftCheckAt = now;
|
|
12236
12281
|
const written = agentState.writtenHashes.get(agent.agent_id);
|
|
12237
|
-
if (written && existsSync11(
|
|
12282
|
+
if (written && existsSync11(agentDir2)) {
|
|
12238
12283
|
const driftedFiles = [];
|
|
12239
12284
|
for (const [file, expectedHash] of written) {
|
|
12240
|
-
const localHash = hashFile(
|
|
12285
|
+
const localHash = hashFile(join26(agentDir2, file));
|
|
12241
12286
|
if (localHash && localHash !== expectedHash) {
|
|
12242
12287
|
driftedFiles.push(file);
|
|
12243
12288
|
}
|
|
@@ -12248,7 +12293,7 @@ async function processAgent(agent, agentStates) {
|
|
|
12248
12293
|
try {
|
|
12249
12294
|
const localHashes = {};
|
|
12250
12295
|
for (const file of driftedFiles) {
|
|
12251
|
-
localHashes[file] = hashFile(
|
|
12296
|
+
localHashes[file] = hashFile(join26(agentDir2, file));
|
|
12252
12297
|
}
|
|
12253
12298
|
await api.post("/host/drift", {
|
|
12254
12299
|
agent_id: agent.agent_id,
|
|
@@ -12435,15 +12480,15 @@ async function processAgent(agent, agentStates) {
|
|
|
12435
12480
|
const addedChannels = [...restartDecision.added];
|
|
12436
12481
|
const writeDmNoticeMarkers = isChannelAddRestart ? () => {
|
|
12437
12482
|
try {
|
|
12438
|
-
const agentAugmentedDir =
|
|
12439
|
-
|
|
12483
|
+
const agentAugmentedDir = join26(homedir12(), ".augmented", agent.code_name);
|
|
12484
|
+
mkdirSync11(agentAugmentedDir, { recursive: true });
|
|
12440
12485
|
const markerJson = JSON.stringify({
|
|
12441
12486
|
version: 1,
|
|
12442
12487
|
at: (/* @__PURE__ */ new Date()).toISOString(),
|
|
12443
12488
|
added: addedChannels
|
|
12444
12489
|
});
|
|
12445
12490
|
for (const file of ["slack-channel-add-restart.json", "telegram-channel-add-restart.json"]) {
|
|
12446
|
-
atomicWriteFileSync(
|
|
12491
|
+
atomicWriteFileSync(join26(agentAugmentedDir, file), markerJson);
|
|
12447
12492
|
}
|
|
12448
12493
|
} catch (err) {
|
|
12449
12494
|
log(`[hot-reload] channel-add DM-notice marker write failed for '${agent.code_name}' (non-fatal): ${err.message}`);
|
|
@@ -12631,19 +12676,19 @@ async function processAgent(agent, agentStates) {
|
|
|
12631
12676
|
const agentSessionMode = refreshData.agent.session_mode;
|
|
12632
12677
|
if (agentSessionMode === "persistent" && (agentFrameworkCache.get(agent.code_name) ?? DEFAULT_FRAMEWORK) === "claude-code") {
|
|
12633
12678
|
try {
|
|
12634
|
-
const agentProvisionDir =
|
|
12635
|
-
const projectDir =
|
|
12636
|
-
|
|
12637
|
-
|
|
12638
|
-
const provisionMcpPath =
|
|
12639
|
-
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");
|
|
12640
12685
|
let mcpConfig = { mcpServers: {} };
|
|
12641
12686
|
try {
|
|
12642
|
-
mcpConfig = JSON.parse(
|
|
12687
|
+
mcpConfig = JSON.parse(readFileSync22(provisionMcpPath, "utf-8"));
|
|
12643
12688
|
if (!mcpConfig.mcpServers) mcpConfig.mcpServers = {};
|
|
12644
12689
|
} catch {
|
|
12645
12690
|
}
|
|
12646
|
-
const localDirectChatChannel =
|
|
12691
|
+
const localDirectChatChannel = join26(homedir12(), ".augmented", "_mcp", "direct-chat-channel.js");
|
|
12647
12692
|
const directChatTeamSettings = refreshData.team?.settings;
|
|
12648
12693
|
const directChatTz = (() => {
|
|
12649
12694
|
const tz = directChatTeamSettings?.["timezone"];
|
|
@@ -12669,7 +12714,7 @@ async function processAgent(agent, agentStates) {
|
|
|
12669
12714
|
// ~/.augmented/<codeName>/.current-turn-initiator.json. Note getAgentDir
|
|
12670
12715
|
// returns the agent root (NOT the /provision subdir `agentDir` points at),
|
|
12671
12716
|
// so it byte-matches the broker readers' path.
|
|
12672
|
-
AGT_TURN_INITIATOR_FILE:
|
|
12717
|
+
AGT_TURN_INITIATOR_FILE: join26(
|
|
12673
12718
|
frameworkAdapter.getAgentDir(agent.code_name),
|
|
12674
12719
|
".current-turn-initiator.json"
|
|
12675
12720
|
)
|
|
@@ -12689,10 +12734,10 @@ async function processAgent(agent, agentStates) {
|
|
|
12689
12734
|
log(`Channel credentials written for '${agent.code_name}/direct-chat'`);
|
|
12690
12735
|
}
|
|
12691
12736
|
}
|
|
12692
|
-
const staleChannelsPath =
|
|
12737
|
+
const staleChannelsPath = join26(projectDir, ".mcp-channels.json");
|
|
12693
12738
|
if (existsSync11(staleChannelsPath)) {
|
|
12694
12739
|
try {
|
|
12695
|
-
|
|
12740
|
+
rmSync6(staleChannelsPath, { force: true });
|
|
12696
12741
|
} catch {
|
|
12697
12742
|
}
|
|
12698
12743
|
}
|
|
@@ -12779,7 +12824,7 @@ async function processAgent(agent, agentStates) {
|
|
|
12779
12824
|
}
|
|
12780
12825
|
if (hostFlagStore().getBoolean("connectivity-probe")) {
|
|
12781
12826
|
try {
|
|
12782
|
-
const probeProjectDir =
|
|
12827
|
+
const probeProjectDir = join26(homedir12(), ".augmented", agent.code_name, "project");
|
|
12783
12828
|
let probeSet = integrations;
|
|
12784
12829
|
try {
|
|
12785
12830
|
const quarantined = await api.post("/host/agent-integrations/quarantined", { agent_id: agent.agent_id });
|
|
@@ -12825,7 +12870,7 @@ async function processAgent(agent, agentStates) {
|
|
|
12825
12870
|
const forceDue = attemptsLeft > 0;
|
|
12826
12871
|
let probeRan = false;
|
|
12827
12872
|
try {
|
|
12828
|
-
const probeProjectDir =
|
|
12873
|
+
const probeProjectDir = join26(homedir12(), ".augmented", agent.code_name, "project");
|
|
12829
12874
|
probeRan = await runAgentSessionToolBindProbes(agent, integrations, probeProjectDir, { forceDue });
|
|
12830
12875
|
} catch (err) {
|
|
12831
12876
|
log(`Session-tool-bind probe failed for '${agent.code_name}': ${err.message}`);
|
|
@@ -12900,11 +12945,11 @@ async function processAgent(agent, agentStates) {
|
|
|
12900
12945
|
const intHash = computeIntegrationsHash(integrations);
|
|
12901
12946
|
const prevIntHash = agentState.knownIntegrationHashes.get(agent.agent_id);
|
|
12902
12947
|
if (intHash !== prevIntHash) {
|
|
12903
|
-
const projectDir =
|
|
12904
|
-
const envIntPath =
|
|
12948
|
+
const projectDir = join26(homedir12(), ".augmented", agent.code_name, "project");
|
|
12949
|
+
const envIntPath = join26(projectDir, ".env.integrations");
|
|
12905
12950
|
let preWriteEnv;
|
|
12906
12951
|
try {
|
|
12907
|
-
preWriteEnv =
|
|
12952
|
+
preWriteEnv = readFileSync22(envIntPath, "utf-8");
|
|
12908
12953
|
} catch {
|
|
12909
12954
|
preWriteEnv = void 0;
|
|
12910
12955
|
}
|
|
@@ -12921,9 +12966,9 @@ async function processAgent(agent, agentStates) {
|
|
|
12921
12966
|
}
|
|
12922
12967
|
if (fw === "claude-code" && isSessionHealthy(agent.code_name)) {
|
|
12923
12968
|
try {
|
|
12924
|
-
const projectMcpPath =
|
|
12925
|
-
const postWriteEnv =
|
|
12926
|
-
const mcpContent =
|
|
12969
|
+
const projectMcpPath = join26(projectDir, ".mcp.json");
|
|
12970
|
+
const postWriteEnv = readFileSync22(envIntPath, "utf-8");
|
|
12971
|
+
const mcpContent = readFileSync22(projectMcpPath, "utf-8");
|
|
12927
12972
|
const changedVars = diffEnvIntegrations(preWriteEnv, postWriteEnv);
|
|
12928
12973
|
const mcpJsonForReap = JSON.parse(mcpContent);
|
|
12929
12974
|
const affectedServerKeys = findMcpServersUsingVars(mcpJsonForReap, changedVars);
|
|
@@ -13169,17 +13214,17 @@ async function processAgent(agent, agentStates) {
|
|
|
13169
13214
|
}
|
|
13170
13215
|
}
|
|
13171
13216
|
try {
|
|
13172
|
-
const { readdirSync: readdirSync8, rmSync:
|
|
13173
|
-
const { homedir:
|
|
13217
|
+
const { readdirSync: readdirSync8, rmSync: rmSync7 } = await import("fs");
|
|
13218
|
+
const { homedir: homedir13 } = await import("os");
|
|
13174
13219
|
const frameworkId2 = frameworkAdapter.id;
|
|
13175
13220
|
const candidateSkillDirs = [
|
|
13176
13221
|
// Claude Code — framework runtime tree
|
|
13177
|
-
|
|
13222
|
+
join26(homedir13(), ".augmented", agent.code_name, "skills"),
|
|
13178
13223
|
// Claude Code — project tree
|
|
13179
|
-
|
|
13224
|
+
join26(homedir13(), ".augmented", agent.code_name, "project", ".claude", "skills"),
|
|
13180
13225
|
// Defensive: legacy provision-side path, not currently an
|
|
13181
13226
|
// install target but cheap to sweep.
|
|
13182
|
-
|
|
13227
|
+
join26(agentDir2, ".claude", "skills")
|
|
13183
13228
|
];
|
|
13184
13229
|
const existingDirs = candidateSkillDirs.filter((d) => existsSync11(d));
|
|
13185
13230
|
const discoveredEntries = /* @__PURE__ */ new Set();
|
|
@@ -13195,9 +13240,9 @@ async function processAgent(agent, agentStates) {
|
|
|
13195
13240
|
}
|
|
13196
13241
|
const removeSkillFolder = (entry, reason) => {
|
|
13197
13242
|
for (const dir of existingDirs) {
|
|
13198
|
-
const p =
|
|
13243
|
+
const p = join26(dir, entry);
|
|
13199
13244
|
if (existsSync11(p)) {
|
|
13200
|
-
|
|
13245
|
+
rmSync7(p, { recursive: true, force: true });
|
|
13201
13246
|
}
|
|
13202
13247
|
}
|
|
13203
13248
|
log(`Removed ${reason} '${entry}' for '${agent.code_name}' (framework=${frameworkId2})`);
|
|
@@ -13215,7 +13260,7 @@ async function processAgent(agent, agentStates) {
|
|
|
13215
13260
|
const sharedSkillsPayload = refreshAny.shared_skills;
|
|
13216
13261
|
const desiredResolved = globalSkillsPayload !== void 0 || sharedSkillsPayload !== void 0;
|
|
13217
13262
|
const manifestPath = managedSkillManifestPath(
|
|
13218
|
-
|
|
13263
|
+
join26(homedir12(), ".augmented", agent.code_name)
|
|
13219
13264
|
);
|
|
13220
13265
|
const prevIds = /* @__PURE__ */ new Set([
|
|
13221
13266
|
...agentState.knownGlobalSkillIds.get(agent.agent_id) ?? /* @__PURE__ */ new Set(),
|
|
@@ -13235,16 +13280,16 @@ async function processAgent(agent, agentStates) {
|
|
|
13235
13280
|
}
|
|
13236
13281
|
if (plan.removes.length) {
|
|
13237
13282
|
const globalSkillDirs = [
|
|
13238
|
-
|
|
13239
|
-
|
|
13240
|
-
|
|
13283
|
+
join26(homedir12(), ".augmented", agent.code_name, "skills"),
|
|
13284
|
+
join26(homedir12(), ".augmented", agent.code_name, "project", ".claude", "skills"),
|
|
13285
|
+
join26(agentDir2, ".claude", "skills")
|
|
13241
13286
|
];
|
|
13242
13287
|
for (const id of plan.removes) {
|
|
13243
13288
|
let prunedAny = false;
|
|
13244
13289
|
for (const dir of globalSkillDirs) {
|
|
13245
|
-
const p =
|
|
13246
|
-
if (existsSync11(p) && existsSync11(
|
|
13247
|
-
|
|
13290
|
+
const p = join26(dir, id);
|
|
13291
|
+
if (existsSync11(p) && existsSync11(join26(p, "SKILL.md"))) {
|
|
13292
|
+
rmSync6(p, { recursive: true, force: true });
|
|
13248
13293
|
prunedAny = true;
|
|
13249
13294
|
}
|
|
13250
13295
|
}
|
|
@@ -13471,8 +13516,8 @@ async function processAgent(agent, agentStates) {
|
|
|
13471
13516
|
const sess = getSessionState(agent.code_name);
|
|
13472
13517
|
let mcpJsonParsed = null;
|
|
13473
13518
|
try {
|
|
13474
|
-
const mcpPath =
|
|
13475
|
-
mcpJsonParsed = JSON.parse(
|
|
13519
|
+
const mcpPath = join26(getProjectDir(agent.code_name), ".mcp.json");
|
|
13520
|
+
mcpJsonParsed = JSON.parse(readFileSync22(mcpPath, "utf-8"));
|
|
13476
13521
|
} catch {
|
|
13477
13522
|
}
|
|
13478
13523
|
reapMissingMcpSessions({
|
|
@@ -13834,10 +13879,10 @@ Retried to the limit after repeated stalls \u2014 needs a look.`).catch(() => {
|
|
|
13834
13879
|
}
|
|
13835
13880
|
}
|
|
13836
13881
|
const trackedFiles = frameworkAdapter.driftTrackedFiles();
|
|
13837
|
-
if (trackedFiles.length > 0 && existsSync11(
|
|
13882
|
+
if (trackedFiles.length > 0 && existsSync11(agentDir2)) {
|
|
13838
13883
|
const hashes = /* @__PURE__ */ new Map();
|
|
13839
13884
|
for (const file of trackedFiles) {
|
|
13840
|
-
const h = hashFile(
|
|
13885
|
+
const h = hashFile(join26(agentDir2, file));
|
|
13841
13886
|
if (h) hashes.set(file, h);
|
|
13842
13887
|
}
|
|
13843
13888
|
agentState.writtenHashes.set(agent.agent_id, hashes);
|
|
@@ -13852,7 +13897,7 @@ Retried to the limit after repeated stalls \u2014 needs a look.`).catch(() => {
|
|
|
13852
13897
|
refreshData.agent.onboarding_state
|
|
13853
13898
|
);
|
|
13854
13899
|
const obStep = obState.step;
|
|
13855
|
-
const markerPath =
|
|
13900
|
+
const markerPath = join26(homedir12(), ".augmented", agent.code_name, "onboarding-drive.json");
|
|
13856
13901
|
const marker = readOnboardingDriveMarker(markerPath);
|
|
13857
13902
|
const decision = decideOnboardingDrive(obStep, marker, Date.now(), obState.generation ?? 0);
|
|
13858
13903
|
if (decision.clearMarker) {
|
|
@@ -13906,6 +13951,20 @@ var lastModelApiErrorSig = /* @__PURE__ */ new Map();
|
|
|
13906
13951
|
var DAY_ROLLOVER_FORCE_GRACE_MIN = 30;
|
|
13907
13952
|
var persistentSessionStuckTracker = new PersistentSessionStuckTracker();
|
|
13908
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
|
+
}
|
|
13909
13968
|
var opencodeCredentialFingerprintBySession = /* @__PURE__ */ new Map();
|
|
13910
13969
|
var egressAllowlistBySession = /* @__PURE__ */ new Map();
|
|
13911
13970
|
function deriveEgressAllowlist(toolsRaw) {
|
|
@@ -13940,7 +13999,7 @@ async function ensureOpencodeRuntime(agent, refreshData, agentTimezone) {
|
|
|
13940
13999
|
}
|
|
13941
14000
|
stopOpencodeSlackIngest(codeName, log);
|
|
13942
14001
|
stopOpencodeTelegramIngest(codeName, log);
|
|
13943
|
-
const opencodeProjectDir =
|
|
14002
|
+
const opencodeProjectDir = join26(getFramework("opencode").getAgentDir(codeName), "provision");
|
|
13944
14003
|
const serveEnv = {
|
|
13945
14004
|
AGT_HOST: requireHost(),
|
|
13946
14005
|
AGT_API_KEY: getApiKey() ?? void 0,
|
|
@@ -13983,8 +14042,8 @@ async function ensureOpencodeRuntime(agent, refreshData, agentTimezone) {
|
|
|
13983
14042
|
async function ensurePersistentSession(agent, tasks, boardItems, refreshData) {
|
|
13984
14043
|
const codeName = agent.code_name;
|
|
13985
14044
|
const projectDir = getProjectDir(codeName);
|
|
13986
|
-
const mcpConfigPath =
|
|
13987
|
-
const claudeMdPath =
|
|
14045
|
+
const mcpConfigPath = join26(projectDir, ".mcp.json");
|
|
14046
|
+
const claudeMdPath = join26(projectDir, "CLAUDE.md");
|
|
13988
14047
|
if (restartBreaker.isTripped(codeName)) {
|
|
13989
14048
|
const trip = restartBreaker.getTrip(codeName);
|
|
13990
14049
|
return {
|
|
@@ -14094,6 +14153,7 @@ async function ensurePersistentSession(agent, tasks, boardItems, refreshData) {
|
|
|
14094
14153
|
let dayRolloverDeferred = false;
|
|
14095
14154
|
let dayRolloverForced = false;
|
|
14096
14155
|
const claudeAccountFingerprint = !openRouterForAgent && claudeAuthMode === "subscription" ? await getClaudeAccountFingerprint() : null;
|
|
14156
|
+
clearUsageLimitMarkerOnAccountChange(codeName, claudeAccountFingerprint, log);
|
|
14097
14157
|
const currentAuthTuple = openRouterForAgent ? `openrouter:${openRouterForAgent.fingerprint ?? openRouterForAgent.model}` : `${claudeAuthMode}:${anthropicApiKeyFingerprint ?? "none"}${claudeAccountFingerprint ? `:${claudeAccountFingerprint}` : ""}`;
|
|
14098
14158
|
const recordedAuthTuple = claudeAuthTupleBySession.get(codeName);
|
|
14099
14159
|
if (recordedAuthTuple && recordedAuthTuple !== currentAuthTuple && isSessionHealthy(codeName)) {
|
|
@@ -14549,7 +14609,7 @@ async function handleRestartDoorbell(agentId, requestedAt, restartReason) {
|
|
|
14549
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}`));
|
|
14550
14610
|
void (async () => {
|
|
14551
14611
|
try {
|
|
14552
|
-
const { collectDiagnostics } = await import("../persistent-session-
|
|
14612
|
+
const { collectDiagnostics } = await import("../persistent-session-PWLMLDVX.js");
|
|
14553
14613
|
await api.post("/host/heartbeat", {
|
|
14554
14614
|
host_id: hostId,
|
|
14555
14615
|
agent_diagnostics: collectDiagnostics([codeName], quarantineEntriesFor, claudeMdSizeFor)
|
|
@@ -14599,7 +14659,7 @@ async function respawnAgentAfterMcpStop(codeName, reason) {
|
|
|
14599
14659
|
}
|
|
14600
14660
|
try {
|
|
14601
14661
|
const hostId = await getHostId();
|
|
14602
|
-
const { collectDiagnostics } = await import("../persistent-session-
|
|
14662
|
+
const { collectDiagnostics } = await import("../persistent-session-PWLMLDVX.js");
|
|
14603
14663
|
await api.post("/host/heartbeat", {
|
|
14604
14664
|
host_id: hostId,
|
|
14605
14665
|
agent_diagnostics: collectDiagnostics([codeName], quarantineEntriesFor, claudeMdSizeFor)
|
|
@@ -14884,9 +14944,9 @@ async function processDirectChatMessage(agent, msg) {
|
|
|
14884
14944
|
const useDoorbell = hostFlagStore().getBoolean("direct-chat-doorbell") || isolationMode(agent.codeName) === "docker";
|
|
14885
14945
|
if (useDoorbell) {
|
|
14886
14946
|
try {
|
|
14887
|
-
const doorbell = directChatDoorbellPath(agent.agentId,
|
|
14888
|
-
|
|
14889
|
-
|
|
14947
|
+
const doorbell = directChatDoorbellPath(agent.agentId, homedir12());
|
|
14948
|
+
mkdirSync11(dirname8(doorbell), { recursive: true });
|
|
14949
|
+
writeFileSync13(doorbell, String(Date.now()));
|
|
14890
14950
|
log(`[direct-chat] Doorbell rung for '${agent.codeName}' (msg=${msg.id}) \u2014 in-session MCP will pull via the cursor`);
|
|
14891
14951
|
return;
|
|
14892
14952
|
} catch (err) {
|
|
@@ -14994,9 +15054,9 @@ ${formatRunMarker(run_id)}` : KANBAN_CHECK_COMMAND;
|
|
|
14994
15054
|
}
|
|
14995
15055
|
if (run_id) openInjectedRunByCode.set(codeName, run_id);
|
|
14996
15056
|
try {
|
|
14997
|
-
const doorbell = directChatDoorbellPath(agentId,
|
|
14998
|
-
|
|
14999
|
-
|
|
15057
|
+
const doorbell = directChatDoorbellPath(agentId, homedir12());
|
|
15058
|
+
mkdirSync11(dirname8(doorbell), { recursive: true });
|
|
15059
|
+
writeFileSync13(doorbell, String(Date.now()));
|
|
15000
15060
|
} catch (err) {
|
|
15001
15061
|
log(`[kanban] doorbell ring failed for '${codeName}': ${err.message} (notice still queued)`);
|
|
15002
15062
|
}
|
|
@@ -15052,7 +15112,7 @@ async function processClaudePairSessions(agents) {
|
|
|
15052
15112
|
killPairSession,
|
|
15053
15113
|
pairTmuxSession,
|
|
15054
15114
|
finalizeClaudePairOnboarding
|
|
15055
|
-
} = await import("../claude-pair-runtime-
|
|
15115
|
+
} = await import("../claude-pair-runtime-YU6KOA6R.js");
|
|
15056
15116
|
for (const pairId of pendingResp.cancelled_pair_ids ?? []) {
|
|
15057
15117
|
log(`[claude-pair] sweeping orphan tmux session for pair ${pairId.slice(0, 8)}`);
|
|
15058
15118
|
const killed = await killPairSession(pairTmuxSession(pairId));
|
|
@@ -15302,8 +15362,8 @@ function parseMemoryFile(raw, fallbackName) {
|
|
|
15302
15362
|
};
|
|
15303
15363
|
}
|
|
15304
15364
|
async function syncMemories(agent, configDir, log2) {
|
|
15305
|
-
const projectDir =
|
|
15306
|
-
const memoryDir =
|
|
15365
|
+
const projectDir = join26(configDir, agent.code_name, "project");
|
|
15366
|
+
const memoryDir = join26(projectDir, "memory");
|
|
15307
15367
|
const isFreshSync = pendingFreshMemorySync.has(agent.agent_id);
|
|
15308
15368
|
if (isFreshSync) {
|
|
15309
15369
|
log2(`[memory-sync] Fresh-sync requested for '${agent.code_name}' \u2014 pulling DB first`);
|
|
@@ -15321,7 +15381,7 @@ async function syncMemories(agent, configDir, log2) {
|
|
|
15321
15381
|
for (const file of readdirSync7(memoryDir)) {
|
|
15322
15382
|
if (!file.endsWith(".md")) continue;
|
|
15323
15383
|
try {
|
|
15324
|
-
const raw =
|
|
15384
|
+
const raw = readFileSync22(join26(memoryDir, file), "utf-8");
|
|
15325
15385
|
const fileHash = createHash16("sha256").update(raw).digest("hex").slice(0, 16);
|
|
15326
15386
|
currentHashes.set(file, fileHash);
|
|
15327
15387
|
if (prevHashes.get(file) === fileHash) continue;
|
|
@@ -15346,7 +15406,7 @@ async function syncMemories(agent, configDir, log2) {
|
|
|
15346
15406
|
} catch (err) {
|
|
15347
15407
|
for (const mem of changedMemories) {
|
|
15348
15408
|
for (const [file] of currentHashes) {
|
|
15349
|
-
const parsed = parseMemoryFile(
|
|
15409
|
+
const parsed = parseMemoryFile(readFileSync22(join26(memoryDir, file), "utf-8"), file.replace(/\.md$/, ""));
|
|
15350
15410
|
if (parsed?.name === mem.name) currentHashes.delete(file);
|
|
15351
15411
|
}
|
|
15352
15412
|
}
|
|
@@ -15374,14 +15434,14 @@ async function downloadMemories(agent, memoryDir, log2, { force }) {
|
|
|
15374
15434
|
lastDownloadHash.set(agent.agent_id, responseHash);
|
|
15375
15435
|
lastLocalFileHash.set(agent.agent_id, localListHash);
|
|
15376
15436
|
if (dbMemories.memories?.length) {
|
|
15377
|
-
|
|
15437
|
+
mkdirSync11(memoryDir, { recursive: true });
|
|
15378
15438
|
let written = 0;
|
|
15379
15439
|
let overwritten = 0;
|
|
15380
15440
|
for (let i = 0; i < dbMemories.memories.length; i++) {
|
|
15381
15441
|
const mem = dbMemories.memories[i];
|
|
15382
15442
|
const rawSlug = mem.name.toLowerCase().replace(/[^a-z0-9]+/g, "-").replace(/(^-|-$)/g, "").slice(0, 60);
|
|
15383
15443
|
const slug = rawSlug || `memory-${i}`;
|
|
15384
|
-
const filePath =
|
|
15444
|
+
const filePath = join26(memoryDir, `${slug}.md`);
|
|
15385
15445
|
const desired = `---
|
|
15386
15446
|
name: ${JSON.stringify(mem.name)}
|
|
15387
15447
|
type: ${mem.type}
|
|
@@ -15393,14 +15453,14 @@ ${mem.content}
|
|
|
15393
15453
|
if (existsSync11(filePath)) {
|
|
15394
15454
|
let existing = "";
|
|
15395
15455
|
try {
|
|
15396
|
-
existing =
|
|
15456
|
+
existing = readFileSync22(filePath, "utf-8");
|
|
15397
15457
|
} catch {
|
|
15398
15458
|
}
|
|
15399
15459
|
if (existing === desired) continue;
|
|
15400
|
-
|
|
15460
|
+
writeFileSync13(filePath, desired);
|
|
15401
15461
|
overwritten++;
|
|
15402
15462
|
} else {
|
|
15403
|
-
|
|
15463
|
+
writeFileSync13(filePath, desired);
|
|
15404
15464
|
written++;
|
|
15405
15465
|
}
|
|
15406
15466
|
}
|
|
@@ -15416,10 +15476,10 @@ ${mem.content}
|
|
|
15416
15476
|
return false;
|
|
15417
15477
|
}
|
|
15418
15478
|
}
|
|
15419
|
-
async function cleanupAgentFiles(codeName,
|
|
15420
|
-
if (existsSync11(
|
|
15479
|
+
async function cleanupAgentFiles(codeName, agentDir2) {
|
|
15480
|
+
if (existsSync11(agentDir2)) {
|
|
15421
15481
|
try {
|
|
15422
|
-
|
|
15482
|
+
rmSync6(agentDir2, { recursive: true, force: true });
|
|
15423
15483
|
log(`Removed provision directory for '${codeName}'`);
|
|
15424
15484
|
} catch (err) {
|
|
15425
15485
|
log(`Failed to remove provision dir for '${codeName}': ${err.message}`);
|
|
@@ -15657,7 +15717,7 @@ function startManager(opts) {
|
|
|
15657
15717
|
try {
|
|
15658
15718
|
const stateFile = getStateFile();
|
|
15659
15719
|
if (existsSync11(stateFile)) {
|
|
15660
|
-
const raw =
|
|
15720
|
+
const raw = readFileSync22(stateFile, "utf-8");
|
|
15661
15721
|
const parsed = JSON.parse(raw);
|
|
15662
15722
|
if (Array.isArray(parsed.agents)) {
|
|
15663
15723
|
state6.agents = parsed.agents;
|
|
@@ -15684,7 +15744,7 @@ function startManager(opts) {
|
|
|
15684
15744
|
log(`[startup] state rehydration failed (continuing with empty state): ${err.message}`);
|
|
15685
15745
|
}
|
|
15686
15746
|
log(
|
|
15687
|
-
`[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")}`
|
|
15688
15748
|
);
|
|
15689
15749
|
deployMcpAssets();
|
|
15690
15750
|
reapOrphanChannelMcps({ log });
|
|
@@ -15713,7 +15773,7 @@ async function reapOrphanedClaudePids() {
|
|
|
15713
15773
|
const looksLikeClaude = (pid) => {
|
|
15714
15774
|
if (process.platform !== "linux") return true;
|
|
15715
15775
|
try {
|
|
15716
|
-
const comm =
|
|
15776
|
+
const comm = readFileSync22(`/proc/${pid}/comm`, "utf-8").trim().toLowerCase();
|
|
15717
15777
|
return comm.includes("claude");
|
|
15718
15778
|
} catch {
|
|
15719
15779
|
return false;
|
|
@@ -15810,14 +15870,14 @@ function restartRunningChannelMcps(basenames) {
|
|
|
15810
15870
|
}
|
|
15811
15871
|
}
|
|
15812
15872
|
function deployMcpAssets() {
|
|
15813
|
-
const targetDir =
|
|
15814
|
-
|
|
15873
|
+
const targetDir = join26(homedir12(), ".augmented", "_mcp");
|
|
15874
|
+
mkdirSync11(targetDir, { recursive: true });
|
|
15815
15875
|
const moduleDir = dirname8(fileURLToPath(import.meta.url));
|
|
15816
15876
|
let mcpSourceDir = "";
|
|
15817
15877
|
let dir = moduleDir;
|
|
15818
15878
|
for (let i = 0; i < 6; i++) {
|
|
15819
|
-
const candidate =
|
|
15820
|
-
if (existsSync11(
|
|
15879
|
+
const candidate = join26(dir, "dist", "mcp");
|
|
15880
|
+
if (existsSync11(join26(candidate, "index.js"))) {
|
|
15821
15881
|
mcpSourceDir = candidate;
|
|
15822
15882
|
break;
|
|
15823
15883
|
}
|
|
@@ -15833,7 +15893,7 @@ function deployMcpAssets() {
|
|
|
15833
15893
|
const fileHash = (p) => {
|
|
15834
15894
|
try {
|
|
15835
15895
|
if (!existsSync11(p)) return null;
|
|
15836
|
-
return createHash16("sha256").update(
|
|
15896
|
+
return createHash16("sha256").update(readFileSync22(p)).digest("hex");
|
|
15837
15897
|
} catch {
|
|
15838
15898
|
return null;
|
|
15839
15899
|
}
|
|
@@ -15897,8 +15957,8 @@ function deployMcpAssets() {
|
|
|
15897
15957
|
// needs restarting to pick up a token rotation.
|
|
15898
15958
|
"xero.js"
|
|
15899
15959
|
]) {
|
|
15900
|
-
const src =
|
|
15901
|
-
const dst =
|
|
15960
|
+
const src = join26(mcpSourceDir, file);
|
|
15961
|
+
const dst = join26(targetDir, file);
|
|
15902
15962
|
if (!existsSync11(src)) continue;
|
|
15903
15963
|
const before = fileHash(dst);
|
|
15904
15964
|
try {
|
|
@@ -15916,23 +15976,23 @@ function deployMcpAssets() {
|
|
|
15916
15976
|
log(`[manager] Bundle(s) updated: ${changedBasenames.join(", ")} \u2014 signalling running instances to restart`);
|
|
15917
15977
|
restartRunningChannelMcps(changedBasenames);
|
|
15918
15978
|
}
|
|
15919
|
-
const localMcpPath =
|
|
15979
|
+
const localMcpPath = join26(targetDir, "index.js");
|
|
15920
15980
|
try {
|
|
15921
|
-
const agentsDir =
|
|
15981
|
+
const agentsDir = join26(homedir12(), ".augmented", "agents");
|
|
15922
15982
|
if (existsSync11(agentsDir)) {
|
|
15923
15983
|
for (const entry of readdirSync7(agentsDir, { withFileTypes: true })) {
|
|
15924
15984
|
if (!entry.isDirectory()) continue;
|
|
15925
15985
|
for (const subdir of ["provision", "project"]) {
|
|
15926
|
-
const mcpJsonPath =
|
|
15986
|
+
const mcpJsonPath = join26(agentsDir, entry.name, subdir, ".mcp.json");
|
|
15927
15987
|
try {
|
|
15928
|
-
const raw =
|
|
15988
|
+
const raw = readFileSync22(mcpJsonPath, "utf-8");
|
|
15929
15989
|
if (!raw.includes("@integrity-labs/augmented-mcp")) continue;
|
|
15930
15990
|
const mcpConfig = JSON.parse(raw);
|
|
15931
15991
|
const augServer = mcpConfig.mcpServers?.["augmented"];
|
|
15932
15992
|
if (!augServer) continue;
|
|
15933
15993
|
augServer.command = "node";
|
|
15934
15994
|
augServer.args = [localMcpPath];
|
|
15935
|
-
|
|
15995
|
+
writeFileSync13(mcpJsonPath, JSON.stringify(mcpConfig, null, 2));
|
|
15936
15996
|
log(`[manager] Patched ${entry.name}/${subdir}/.mcp.json: npx \u2192 node`);
|
|
15937
15997
|
} catch {
|
|
15938
15998
|
}
|
|
@@ -15969,11 +16029,13 @@ process.on("disconnect", () => {
|
|
|
15969
16029
|
export {
|
|
15970
16030
|
BACK_ONLINE_GREETING_GUIDANCE,
|
|
15971
16031
|
DAY_ROLLOVER_FORCE_GRACE_MIN,
|
|
16032
|
+
_resetClaudeAccountByAgent,
|
|
15972
16033
|
applyRestartAcks,
|
|
15973
16034
|
cancelKanbanNoticeOnDrain,
|
|
15974
16035
|
claudeCodeUpgradeMarkerPath,
|
|
15975
16036
|
claudeCodeUpgradeThrottled,
|
|
15976
16037
|
claudeManagedSettingsPath,
|
|
16038
|
+
clearUsageLimitMarkerOnAccountChange,
|
|
15977
16039
|
dashboardRestartBreakerReason,
|
|
15978
16040
|
ensureClaudeManagedSettings,
|
|
15979
16041
|
extractCharterSlackPeers,
|