@integrity-labs/agt-cli 0.28.433 → 0.28.435
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 +6 -5
- package/dist/bin/agt.js.map +1 -1
- package/dist/{chunk-RUVNJO63.js → chunk-VIOLJEBT.js} +6 -8
- package/dist/chunk-VIOLJEBT.js.map +1 -0
- package/dist/{chunk-NUKNLJNJ.js → chunk-ZLFZXMNL.js} +181 -137
- package/dist/chunk-ZLFZXMNL.js.map +1 -0
- package/dist/{claude-pair-runtime-YAHBPFYL.js → claude-pair-runtime-CHKX4WH2.js} +2 -2
- package/dist/lib/manager-worker.js +330 -266
- package/dist/lib/manager-worker.js.map +1 -1
- package/dist/{persistent-session-ISBR3BBX.js → persistent-session-D2POY3KV.js} +2 -2
- package/dist/{responsiveness-probe-OT6JVP43.js → responsiveness-probe-ARRF5CAQ.js} +2 -2
- package/package.json +1 -1
- package/dist/chunk-NUKNLJNJ.js.map +0 -1
- package/dist/chunk-RUVNJO63.js.map +0 -1
- /package/dist/{claude-pair-runtime-YAHBPFYL.js.map → claude-pair-runtime-CHKX4WH2.js.map} +0 -0
- /package/dist/{persistent-session-ISBR3BBX.js.map → persistent-session-D2POY3KV.js.map} +0 -0
- /package/dist/{responsiveness-probe-OT6JVP43.js.map → responsiveness-probe-ARRF5CAQ.js.map} +0 -0
|
@@ -42,7 +42,7 @@ import {
|
|
|
42
42
|
resolveEffectivePinRaw,
|
|
43
43
|
safeWriteJsonAtomic,
|
|
44
44
|
setConfigHash
|
|
45
|
-
} from "../chunk-
|
|
45
|
+
} from "../chunk-VIOLJEBT.js";
|
|
46
46
|
import {
|
|
47
47
|
getProjectDir as getProjectDir2,
|
|
48
48
|
getReadyTasks,
|
|
@@ -66,7 +66,6 @@ import {
|
|
|
66
66
|
SCHEDULED_TURN_MARKER_FILENAME,
|
|
67
67
|
SUPPRESS_SENTINEL,
|
|
68
68
|
StreamEncoder,
|
|
69
|
-
USAGE_LIMIT_MARKER_FILENAME,
|
|
70
69
|
appendDmFooter,
|
|
71
70
|
attributeTranscriptUsageByRun,
|
|
72
71
|
buildEgressAllowlist,
|
|
@@ -75,6 +74,7 @@ import {
|
|
|
75
74
|
checkChannelInputs,
|
|
76
75
|
classifyActor,
|
|
77
76
|
classifyOutput,
|
|
77
|
+
clearUsageLimitMarker,
|
|
78
78
|
coerceOnboardingState,
|
|
79
79
|
creditWatchdogGiveUpCount,
|
|
80
80
|
describeOnboardingChannel,
|
|
@@ -139,7 +139,6 @@ import {
|
|
|
139
139
|
restartEgressSidecar,
|
|
140
140
|
rotateSessionForWedge,
|
|
141
141
|
serializeAccountEnforcementMarker,
|
|
142
|
-
serializeUsageLimitMarker,
|
|
143
142
|
sessionTranscriptDir,
|
|
144
143
|
sha256,
|
|
145
144
|
sharedBusyBuckets,
|
|
@@ -154,17 +153,18 @@ import {
|
|
|
154
153
|
takeZombieDetection,
|
|
155
154
|
toOpencodeModel,
|
|
156
155
|
transcriptActivityAgeSeconds,
|
|
157
|
-
writeEgressAllowlist
|
|
158
|
-
|
|
156
|
+
writeEgressAllowlist,
|
|
157
|
+
writeUsageLimitMarker
|
|
158
|
+
} from "../chunk-ZLFZXMNL.js";
|
|
159
159
|
import {
|
|
160
160
|
reapOrphanChannelMcps
|
|
161
161
|
} from "../chunk-XWVM4KPK.js";
|
|
162
162
|
|
|
163
163
|
// src/lib/manager-worker.ts
|
|
164
|
-
import { createHash as
|
|
165
|
-
import { readFileSync as readFileSync20, writeFileSync as
|
|
164
|
+
import { createHash as createHash16 } from "crypto";
|
|
165
|
+
import { readFileSync as readFileSync20, writeFileSync as writeFileSync12, mkdirSync as mkdirSync10, existsSync as existsSync11, rmSync as rmSync5, readdirSync as readdirSync6, statSync as statSync5, copyFileSync } from "fs";
|
|
166
166
|
import { execFileSync as syncExecFile } from "child_process";
|
|
167
|
-
import { join as join24, dirname as
|
|
167
|
+
import { join as join24, dirname as dirname8, delimiter as pathDelimiter } from "path";
|
|
168
168
|
import { homedir as homedir11 } from "os";
|
|
169
169
|
import { fileURLToPath } from "url";
|
|
170
170
|
|
|
@@ -2052,29 +2052,12 @@ var nodeArtifactFs = {
|
|
|
2052
2052
|
};
|
|
2053
2053
|
|
|
2054
2054
|
// src/lib/usage-banner-monitor.ts
|
|
2055
|
-
import { mkdirSync as mkdirSync4, rmSync as rmSync2, writeFileSync as writeFileSync4 } from "fs";
|
|
2056
|
-
import { homedir as homedir3 } from "os";
|
|
2057
|
-
import { join as join6 } from "path";
|
|
2058
2055
|
function syncUsageLimitMarker(args) {
|
|
2059
2056
|
if (args.pct < 100) {
|
|
2060
2057
|
clearUsageLimitMarker(args.codeName, args.log);
|
|
2061
2058
|
return;
|
|
2062
2059
|
}
|
|
2063
|
-
|
|
2064
|
-
try {
|
|
2065
|
-
mkdirSync4(join6(homedir3(), ".augmented", args.codeName), { recursive: true });
|
|
2066
|
-
writeFileSync4(path, serializeUsageLimitMarker(args.weekResetsAt), "utf-8");
|
|
2067
|
-
} catch (err) {
|
|
2068
|
-
args.log(`[usage-banner] usage-limit marker sync failed for '${args.codeName}': ${err.message}`);
|
|
2069
|
-
}
|
|
2070
|
-
}
|
|
2071
|
-
function clearUsageLimitMarker(codeName, log2) {
|
|
2072
|
-
const path = join6(homedir3(), ".augmented", codeName, USAGE_LIMIT_MARKER_FILENAME);
|
|
2073
|
-
try {
|
|
2074
|
-
rmSync2(path, { force: true });
|
|
2075
|
-
} catch (err) {
|
|
2076
|
-
log2(`[usage-banner] usage-limit marker clear failed for '${codeName}': ${err.message}`);
|
|
2077
|
-
}
|
|
2060
|
+
writeUsageLimitMarker(args.codeName, args.weekResetsAt, args.log);
|
|
2078
2061
|
}
|
|
2079
2062
|
var SPAWN_MARKER = /--- spawn \S+ \(session [^)]*\) ---/g;
|
|
2080
2063
|
function scopeToCurrentPaneEpoch(tail) {
|
|
@@ -2151,12 +2134,196 @@ async function maybeReportUsageBanner(args) {
|
|
|
2151
2134
|
}
|
|
2152
2135
|
}
|
|
2153
2136
|
|
|
2137
|
+
// src/lib/claude-account-fingerprint.ts
|
|
2138
|
+
import { createHash as createHash6 } from "crypto";
|
|
2139
|
+
import { readFile as readFile3, readdir as readdir3 } from "fs/promises";
|
|
2140
|
+
import { homedir as homedir4, platform as platform2 } from "os";
|
|
2141
|
+
import { dirname as dirname4, join as join7 } from "path";
|
|
2142
|
+
|
|
2143
|
+
// src/lib/claude-auth-detect.ts
|
|
2144
|
+
import { readFile as readFile2, readdir as readdir2 } from "fs/promises";
|
|
2145
|
+
import { homedir as homedir3, platform } from "os";
|
|
2146
|
+
import { join as join6 } from "path";
|
|
2147
|
+
import { execFile } from "child_process";
|
|
2148
|
+
import { promisify } from "util";
|
|
2149
|
+
var execFileAsync = promisify(execFile);
|
|
2150
|
+
var EXPIRING_SOON_MS = 48 * 60 * 60 * 1e3;
|
|
2151
|
+
async function detectClaudeAuth() {
|
|
2152
|
+
if (process.env["ANTHROPIC_API_KEY"] || process.env["ANTHROPIC_AUTH_TOKEN"]) {
|
|
2153
|
+
return { mode: "api_key", status: "valid", expires_at: null };
|
|
2154
|
+
}
|
|
2155
|
+
const creds = await readOauthCredentials();
|
|
2156
|
+
if (!creds) return null;
|
|
2157
|
+
return computeSubscriptionStatus(creds);
|
|
2158
|
+
}
|
|
2159
|
+
async function findClaudeCredentialsPaths() {
|
|
2160
|
+
const candidates = [
|
|
2161
|
+
join6(homedir3(), ".claude", ".credentials.json"),
|
|
2162
|
+
join6(homedir3(), ".claude", "credentials.json")
|
|
2163
|
+
];
|
|
2164
|
+
const isLinuxRoot = platform() === "linux" && typeof process.getuid === "function" && process.getuid() === 0;
|
|
2165
|
+
if (isLinuxRoot) {
|
|
2166
|
+
try {
|
|
2167
|
+
const entries = await readdir2("/home", { withFileTypes: true });
|
|
2168
|
+
for (const entry of entries.filter((entry2) => entry2.isDirectory()).sort((a, b) => a.name.localeCompare(b.name))) {
|
|
2169
|
+
candidates.push(join6("/home", entry.name, ".claude", ".credentials.json"));
|
|
2170
|
+
candidates.push(join6("/home", entry.name, ".claude", "credentials.json"));
|
|
2171
|
+
}
|
|
2172
|
+
} catch {
|
|
2173
|
+
}
|
|
2174
|
+
}
|
|
2175
|
+
return candidates;
|
|
2176
|
+
}
|
|
2177
|
+
async function readOauthCredentials() {
|
|
2178
|
+
if (platform() === "darwin") {
|
|
2179
|
+
const fromKeychain = await readMacKeychain();
|
|
2180
|
+
if (fromKeychain) return fromKeychain;
|
|
2181
|
+
}
|
|
2182
|
+
const candidates = await findClaudeCredentialsPaths();
|
|
2183
|
+
for (const path of candidates) {
|
|
2184
|
+
const parsed = await readJsonSilently(path);
|
|
2185
|
+
if (parsed) {
|
|
2186
|
+
return parsed.claudeAiOauth ?? parsed.oauth ?? parsed;
|
|
2187
|
+
}
|
|
2188
|
+
}
|
|
2189
|
+
return null;
|
|
2190
|
+
}
|
|
2191
|
+
async function readMacKeychain() {
|
|
2192
|
+
try {
|
|
2193
|
+
const { stdout } = await execFileAsync(
|
|
2194
|
+
"security",
|
|
2195
|
+
["find-generic-password", "-s", "Claude Code-credentials", "-w"],
|
|
2196
|
+
{ timeout: 3e3 }
|
|
2197
|
+
);
|
|
2198
|
+
const parsed = JSON.parse(stdout.trim());
|
|
2199
|
+
return parsed.claudeAiOauth ?? parsed;
|
|
2200
|
+
} catch {
|
|
2201
|
+
return null;
|
|
2202
|
+
}
|
|
2203
|
+
}
|
|
2204
|
+
async function readJsonSilently(path) {
|
|
2205
|
+
try {
|
|
2206
|
+
const raw = await readFile2(path, "utf-8");
|
|
2207
|
+
return JSON.parse(raw);
|
|
2208
|
+
} catch {
|
|
2209
|
+
return null;
|
|
2210
|
+
}
|
|
2211
|
+
}
|
|
2212
|
+
function computeSubscriptionStatus(creds) {
|
|
2213
|
+
const expiresAtMs = parseExpiresAt(creds.expiresAt);
|
|
2214
|
+
const hasRefreshToken = typeof creds.refreshToken === "string" && creds.refreshToken.trim().length > 0;
|
|
2215
|
+
if (expiresAtMs === null) {
|
|
2216
|
+
return {
|
|
2217
|
+
mode: "subscription",
|
|
2218
|
+
status: "unknown",
|
|
2219
|
+
expires_at: null
|
|
2220
|
+
};
|
|
2221
|
+
}
|
|
2222
|
+
const msUntilExpiry = expiresAtMs - Date.now();
|
|
2223
|
+
let status;
|
|
2224
|
+
if (hasRefreshToken) {
|
|
2225
|
+
status = "valid";
|
|
2226
|
+
} else {
|
|
2227
|
+
status = msUntilExpiry <= 0 ? "expired" : msUntilExpiry <= EXPIRING_SOON_MS ? "expiring_soon" : "valid";
|
|
2228
|
+
}
|
|
2229
|
+
return {
|
|
2230
|
+
mode: "subscription",
|
|
2231
|
+
status,
|
|
2232
|
+
expires_at: new Date(expiresAtMs).toISOString()
|
|
2233
|
+
};
|
|
2234
|
+
}
|
|
2235
|
+
function parseExpiresAt(raw) {
|
|
2236
|
+
if (typeof raw === "number" && Number.isFinite(raw)) {
|
|
2237
|
+
return raw < 1e12 ? raw * 1e3 : raw;
|
|
2238
|
+
}
|
|
2239
|
+
if (typeof raw === "string") {
|
|
2240
|
+
const parsed = Date.parse(raw);
|
|
2241
|
+
return Number.isNaN(parsed) ? null : parsed;
|
|
2242
|
+
}
|
|
2243
|
+
return null;
|
|
2244
|
+
}
|
|
2245
|
+
|
|
2246
|
+
// src/lib/claude-account-fingerprint.ts
|
|
2247
|
+
async function candidateHomes() {
|
|
2248
|
+
const homes = [homedir4()];
|
|
2249
|
+
const isLinuxRoot = platform2() === "linux" && typeof process.getuid === "function" && process.getuid() === 0;
|
|
2250
|
+
if (isLinuxRoot) {
|
|
2251
|
+
try {
|
|
2252
|
+
const entries = await readdir3("/home", { withFileTypes: true });
|
|
2253
|
+
for (const entry of entries.filter((e) => e.isDirectory()).sort((a, b) => a.name.localeCompare(b.name))) {
|
|
2254
|
+
homes.push(join7("/home", entry.name));
|
|
2255
|
+
}
|
|
2256
|
+
} catch {
|
|
2257
|
+
}
|
|
2258
|
+
}
|
|
2259
|
+
return homes;
|
|
2260
|
+
}
|
|
2261
|
+
async function homeOfActiveCredentials() {
|
|
2262
|
+
for (const path of await findClaudeCredentialsPaths()) {
|
|
2263
|
+
try {
|
|
2264
|
+
await readFile3(path, "utf-8");
|
|
2265
|
+
return dirname4(dirname4(path));
|
|
2266
|
+
} catch {
|
|
2267
|
+
}
|
|
2268
|
+
}
|
|
2269
|
+
return null;
|
|
2270
|
+
}
|
|
2271
|
+
async function claudeConfigCandidatePaths() {
|
|
2272
|
+
const paths = [];
|
|
2273
|
+
const configDir = process.env["CLAUDE_CONFIG_DIR"]?.trim();
|
|
2274
|
+
if (configDir) paths.push(join7(configDir, ".claude.json"));
|
|
2275
|
+
const activeHome = await homeOfActiveCredentials();
|
|
2276
|
+
if (activeHome) paths.push(join7(activeHome, ".claude.json"));
|
|
2277
|
+
for (const home of await candidateHomes()) {
|
|
2278
|
+
const path = join7(home, ".claude.json");
|
|
2279
|
+
if (!paths.includes(path)) paths.push(path);
|
|
2280
|
+
}
|
|
2281
|
+
return paths;
|
|
2282
|
+
}
|
|
2283
|
+
function hashAccount(accountUuid, organizationUuid) {
|
|
2284
|
+
return createHash6("sha256").update(`claude-account:${accountUuid}:${organizationUuid ?? ""}`).digest("hex").slice(0, 12);
|
|
2285
|
+
}
|
|
2286
|
+
async function detectClaudeAccountFingerprint(paths) {
|
|
2287
|
+
const candidates = paths ?? await claudeConfigCandidatePaths();
|
|
2288
|
+
for (const path of candidates) {
|
|
2289
|
+
let parsed;
|
|
2290
|
+
try {
|
|
2291
|
+
parsed = JSON.parse(await readFile3(path, "utf-8"));
|
|
2292
|
+
} catch {
|
|
2293
|
+
continue;
|
|
2294
|
+
}
|
|
2295
|
+
if (typeof parsed !== "object" || parsed === null) continue;
|
|
2296
|
+
const account = parsed.oauthAccount;
|
|
2297
|
+
if (typeof account !== "object" || account === null) continue;
|
|
2298
|
+
const accountUuid = account.accountUuid;
|
|
2299
|
+
if (typeof accountUuid !== "string" || accountUuid.trim().length === 0) continue;
|
|
2300
|
+
const organizationUuid = account.organizationUuid;
|
|
2301
|
+
return hashAccount(
|
|
2302
|
+
accountUuid.trim(),
|
|
2303
|
+
typeof organizationUuid === "string" && organizationUuid.trim().length > 0 ? organizationUuid.trim() : null
|
|
2304
|
+
);
|
|
2305
|
+
}
|
|
2306
|
+
return null;
|
|
2307
|
+
}
|
|
2308
|
+
var lastKnownFingerprint = null;
|
|
2309
|
+
var lastDetectAtMs = 0;
|
|
2310
|
+
var DETECT_TTL_MS = 6e4;
|
|
2311
|
+
async function getClaudeAccountFingerprint(paths, nowMs = Date.now()) {
|
|
2312
|
+
if (!paths && lastKnownFingerprint !== null && nowMs - lastDetectAtMs < DETECT_TTL_MS) {
|
|
2313
|
+
return lastKnownFingerprint;
|
|
2314
|
+
}
|
|
2315
|
+
const detected = await detectClaudeAccountFingerprint(paths);
|
|
2316
|
+
if (!paths) lastDetectAtMs = nowMs;
|
|
2317
|
+
if (detected) lastKnownFingerprint = detected;
|
|
2318
|
+
return lastKnownFingerprint;
|
|
2319
|
+
}
|
|
2320
|
+
|
|
2154
2321
|
// src/lib/account-enforcement-marker.ts
|
|
2155
|
-
import { mkdirSync as
|
|
2156
|
-
import { homedir as
|
|
2157
|
-
import { join as
|
|
2322
|
+
import { mkdirSync as mkdirSync4, renameSync, rmSync as rmSync2, writeFileSync as writeFileSync4 } from "fs";
|
|
2323
|
+
import { homedir as homedir5 } from "os";
|
|
2324
|
+
import { join as join8 } from "path";
|
|
2158
2325
|
function accountEnforcementMarkerPath(codeName) {
|
|
2159
|
-
return
|
|
2326
|
+
return join8(homedir5(), ".augmented", codeName, ACCOUNT_ENFORCEMENT_MARKER_FILENAME);
|
|
2160
2327
|
}
|
|
2161
2328
|
function syncAccountEnforcementMarker(codeName, level, log2 = (m) => process.stderr.write(`${m}
|
|
2162
2329
|
`)) {
|
|
@@ -2164,16 +2331,16 @@ function syncAccountEnforcementMarker(codeName, level, log2 = (m) => process.std
|
|
|
2164
2331
|
clearAccountEnforcementMarker(codeName, log2);
|
|
2165
2332
|
return;
|
|
2166
2333
|
}
|
|
2167
|
-
const dir =
|
|
2168
|
-
const path =
|
|
2334
|
+
const dir = join8(homedir5(), ".augmented", codeName);
|
|
2335
|
+
const path = join8(dir, ACCOUNT_ENFORCEMENT_MARKER_FILENAME);
|
|
2169
2336
|
const tempPath = `${path}.${process.pid}.tmp`;
|
|
2170
2337
|
try {
|
|
2171
|
-
|
|
2172
|
-
|
|
2338
|
+
mkdirSync4(dir, { recursive: true });
|
|
2339
|
+
writeFileSync4(tempPath, serializeAccountEnforcementMarker(level), "utf-8");
|
|
2173
2340
|
renameSync(tempPath, path);
|
|
2174
2341
|
} catch (err) {
|
|
2175
2342
|
try {
|
|
2176
|
-
|
|
2343
|
+
rmSync2(tempPath, { force: true });
|
|
2177
2344
|
} catch {
|
|
2178
2345
|
}
|
|
2179
2346
|
log2(`[account-enforcement] marker sync failed for '${codeName}': ${err.message}`);
|
|
@@ -2183,7 +2350,7 @@ function clearAccountEnforcementMarker(codeName, log2 = (m) => process.stderr.wr
|
|
|
2183
2350
|
`)) {
|
|
2184
2351
|
const path = accountEnforcementMarkerPath(codeName);
|
|
2185
2352
|
try {
|
|
2186
|
-
|
|
2353
|
+
rmSync2(path, { force: true });
|
|
2187
2354
|
} catch (err) {
|
|
2188
2355
|
log2(`[account-enforcement] marker clear failed for '${codeName}': ${err.message}`);
|
|
2189
2356
|
}
|
|
@@ -2191,7 +2358,7 @@ function clearAccountEnforcementMarker(codeName, log2 = (m) => process.stderr.wr
|
|
|
2191
2358
|
|
|
2192
2359
|
// src/lib/token-usage-monitor.ts
|
|
2193
2360
|
import { readdirSync, readFileSync as readFileSync7, statSync } from "fs";
|
|
2194
|
-
import { join as
|
|
2361
|
+
import { join as join9 } from "path";
|
|
2195
2362
|
var MIN_CHECK_INTERVAL_MS2 = 6e4;
|
|
2196
2363
|
var TRANSCRIPT_MTIME_WINDOW_MS = 2 * 24 * 60 * 60 * 1e3;
|
|
2197
2364
|
var MAX_ENTRIES_PER_POST = 200;
|
|
@@ -2220,7 +2387,7 @@ async function maybeReportTokenUsage(args) {
|
|
|
2220
2387
|
if (!name.endsWith(".jsonl")) continue;
|
|
2221
2388
|
const sessionId = name.slice(0, -".jsonl".length);
|
|
2222
2389
|
if (!sessionId) continue;
|
|
2223
|
-
const path =
|
|
2390
|
+
const path = join9(dir, name);
|
|
2224
2391
|
let st;
|
|
2225
2392
|
try {
|
|
2226
2393
|
st = statSync(path);
|
|
@@ -2318,7 +2485,7 @@ async function maybeReportTokenUsage(args) {
|
|
|
2318
2485
|
|
|
2319
2486
|
// src/lib/workflow-run-reconciler.ts
|
|
2320
2487
|
import { readdirSync as readdirSync2, readFileSync as readFileSync8, statSync as statSync2 } from "fs";
|
|
2321
|
-
import { join as
|
|
2488
|
+
import { join as join10 } from "path";
|
|
2322
2489
|
var MIN_CHECK_INTERVAL_MS3 = 5 * 6e4;
|
|
2323
2490
|
var SETTLE_MS = 3e4;
|
|
2324
2491
|
var TRANSCRIPT_MTIME_WINDOW_MS2 = 2 * 24 * 60 * 60 * 1e3;
|
|
@@ -2337,7 +2504,7 @@ function collectJsonlRecursive(dir, minMtimeMs, out, depth) {
|
|
|
2337
2504
|
return;
|
|
2338
2505
|
}
|
|
2339
2506
|
for (const name of entries) {
|
|
2340
|
-
const p =
|
|
2507
|
+
const p = join10(dir, name);
|
|
2341
2508
|
let st;
|
|
2342
2509
|
try {
|
|
2343
2510
|
st = statSync2(p);
|
|
@@ -2360,7 +2527,7 @@ function enumerateTranscriptFiles(transcriptDir, nowMs, minMtimeMs = nowMs - TRA
|
|
|
2360
2527
|
return out;
|
|
2361
2528
|
}
|
|
2362
2529
|
for (const name of entries) {
|
|
2363
|
-
const path =
|
|
2530
|
+
const path = join10(transcriptDir, name);
|
|
2364
2531
|
let st;
|
|
2365
2532
|
try {
|
|
2366
2533
|
st = statSync2(path);
|
|
@@ -2372,7 +2539,7 @@ function enumerateTranscriptFiles(transcriptDir, nowMs, minMtimeMs = nowMs - TRA
|
|
|
2372
2539
|
continue;
|
|
2373
2540
|
}
|
|
2374
2541
|
if (st.isDirectory()) {
|
|
2375
|
-
collectJsonlRecursive(
|
|
2542
|
+
collectJsonlRecursive(join10(path, "subagents"), minMtimeMs, out, 0);
|
|
2376
2543
|
}
|
|
2377
2544
|
}
|
|
2378
2545
|
return out;
|
|
@@ -2463,7 +2630,7 @@ async function maybeReconcileWorkflowRunTokens(args) {
|
|
|
2463
2630
|
|
|
2464
2631
|
// src/lib/conversation-evaluator.ts
|
|
2465
2632
|
import { readdirSync as readdirSync3, readFileSync as readFileSync9, statSync as statSync3 } from "fs";
|
|
2466
|
-
import { join as
|
|
2633
|
+
import { join as join11 } from "path";
|
|
2467
2634
|
var MIN_CHECK_INTERVAL_MS4 = 5 * 6e4;
|
|
2468
2635
|
var TRANSCRIPT_MTIME_WINDOW_MS3 = 7 * 24 * 60 * 60 * 1e3;
|
|
2469
2636
|
var WINDOW_PAD_MS = 5 * 6e4;
|
|
@@ -2899,7 +3066,7 @@ function readRecentTurns(dir, nowMs) {
|
|
|
2899
3066
|
return;
|
|
2900
3067
|
}
|
|
2901
3068
|
for (const ent of entries) {
|
|
2902
|
-
const full =
|
|
3069
|
+
const full = join11(d, ent.name);
|
|
2903
3070
|
if (ent.isDirectory()) {
|
|
2904
3071
|
visit(full);
|
|
2905
3072
|
continue;
|
|
@@ -3205,10 +3372,10 @@ async function reportSkip2(api2, agentId, conversationId, log2, codeName) {
|
|
|
3205
3372
|
|
|
3206
3373
|
// src/lib/activity-cache-monitor.ts
|
|
3207
3374
|
import { existsSync as existsSync2, readFileSync as readFileSync10 } from "fs";
|
|
3208
|
-
import { homedir as
|
|
3209
|
-
import { join as
|
|
3375
|
+
import { homedir as homedir6 } from "os";
|
|
3376
|
+
import { join as join12 } from "path";
|
|
3210
3377
|
var MIN_CHECK_INTERVAL_MS6 = 6e4;
|
|
3211
|
-
var STATS_CACHE_PATH =
|
|
3378
|
+
var STATS_CACHE_PATH = join12(homedir6(), ".claude", "stats-cache.json");
|
|
3212
3379
|
var ISO_DATE_RE = /^\d{4}-\d{2}-\d{2}$/;
|
|
3213
3380
|
var state5 = { lastObservedDate: null, lastCheckedAt: 0 };
|
|
3214
3381
|
function selectNewDailyRows(raw, lastObservedDate) {
|
|
@@ -3440,115 +3607,11 @@ function bundleFingerprint(files) {
|
|
|
3440
3607
|
return sorted.map((f) => `${f.relativePath}\0${f.content}`).join("");
|
|
3441
3608
|
}
|
|
3442
3609
|
|
|
3443
|
-
// src/lib/claude-auth-detect.ts
|
|
3444
|
-
import { readFile as readFile2, readdir as readdir2 } from "fs/promises";
|
|
3445
|
-
import { homedir as homedir6, platform } from "os";
|
|
3446
|
-
import { join as join12 } from "path";
|
|
3447
|
-
import { execFile } from "child_process";
|
|
3448
|
-
import { promisify } from "util";
|
|
3449
|
-
var execFileAsync = promisify(execFile);
|
|
3450
|
-
var EXPIRING_SOON_MS = 48 * 60 * 60 * 1e3;
|
|
3451
|
-
async function detectClaudeAuth() {
|
|
3452
|
-
if (process.env["ANTHROPIC_API_KEY"] || process.env["ANTHROPIC_AUTH_TOKEN"]) {
|
|
3453
|
-
return { mode: "api_key", status: "valid", expires_at: null };
|
|
3454
|
-
}
|
|
3455
|
-
const creds = await readOauthCredentials();
|
|
3456
|
-
if (!creds) return null;
|
|
3457
|
-
return computeSubscriptionStatus(creds);
|
|
3458
|
-
}
|
|
3459
|
-
async function findClaudeCredentialsPaths() {
|
|
3460
|
-
const candidates = [
|
|
3461
|
-
join12(homedir6(), ".claude", ".credentials.json"),
|
|
3462
|
-
join12(homedir6(), ".claude", "credentials.json")
|
|
3463
|
-
];
|
|
3464
|
-
const isLinuxRoot = platform() === "linux" && typeof process.getuid === "function" && process.getuid() === 0;
|
|
3465
|
-
if (isLinuxRoot) {
|
|
3466
|
-
try {
|
|
3467
|
-
const entries = await readdir2("/home", { withFileTypes: true });
|
|
3468
|
-
for (const entry of entries) {
|
|
3469
|
-
if (!entry.isDirectory()) continue;
|
|
3470
|
-
candidates.push(join12("/home", entry.name, ".claude", ".credentials.json"));
|
|
3471
|
-
candidates.push(join12("/home", entry.name, ".claude", "credentials.json"));
|
|
3472
|
-
}
|
|
3473
|
-
} catch {
|
|
3474
|
-
}
|
|
3475
|
-
}
|
|
3476
|
-
return candidates;
|
|
3477
|
-
}
|
|
3478
|
-
async function readOauthCredentials() {
|
|
3479
|
-
if (platform() === "darwin") {
|
|
3480
|
-
const fromKeychain = await readMacKeychain();
|
|
3481
|
-
if (fromKeychain) return fromKeychain;
|
|
3482
|
-
}
|
|
3483
|
-
const candidates = await findClaudeCredentialsPaths();
|
|
3484
|
-
for (const path of candidates) {
|
|
3485
|
-
const parsed = await readJsonSilently(path);
|
|
3486
|
-
if (parsed) {
|
|
3487
|
-
return parsed.claudeAiOauth ?? parsed.oauth ?? parsed;
|
|
3488
|
-
}
|
|
3489
|
-
}
|
|
3490
|
-
return null;
|
|
3491
|
-
}
|
|
3492
|
-
async function readMacKeychain() {
|
|
3493
|
-
try {
|
|
3494
|
-
const { stdout } = await execFileAsync(
|
|
3495
|
-
"security",
|
|
3496
|
-
["find-generic-password", "-s", "Claude Code-credentials", "-w"],
|
|
3497
|
-
{ timeout: 3e3 }
|
|
3498
|
-
);
|
|
3499
|
-
const parsed = JSON.parse(stdout.trim());
|
|
3500
|
-
return parsed.claudeAiOauth ?? parsed;
|
|
3501
|
-
} catch {
|
|
3502
|
-
return null;
|
|
3503
|
-
}
|
|
3504
|
-
}
|
|
3505
|
-
async function readJsonSilently(path) {
|
|
3506
|
-
try {
|
|
3507
|
-
const raw = await readFile2(path, "utf-8");
|
|
3508
|
-
return JSON.parse(raw);
|
|
3509
|
-
} catch {
|
|
3510
|
-
return null;
|
|
3511
|
-
}
|
|
3512
|
-
}
|
|
3513
|
-
function computeSubscriptionStatus(creds) {
|
|
3514
|
-
const expiresAtMs = parseExpiresAt(creds.expiresAt);
|
|
3515
|
-
const hasRefreshToken = typeof creds.refreshToken === "string" && creds.refreshToken.trim().length > 0;
|
|
3516
|
-
if (expiresAtMs === null) {
|
|
3517
|
-
return {
|
|
3518
|
-
mode: "subscription",
|
|
3519
|
-
status: "unknown",
|
|
3520
|
-
expires_at: null
|
|
3521
|
-
};
|
|
3522
|
-
}
|
|
3523
|
-
const msUntilExpiry = expiresAtMs - Date.now();
|
|
3524
|
-
let status;
|
|
3525
|
-
if (hasRefreshToken) {
|
|
3526
|
-
status = "valid";
|
|
3527
|
-
} else {
|
|
3528
|
-
status = msUntilExpiry <= 0 ? "expired" : msUntilExpiry <= EXPIRING_SOON_MS ? "expiring_soon" : "valid";
|
|
3529
|
-
}
|
|
3530
|
-
return {
|
|
3531
|
-
mode: "subscription",
|
|
3532
|
-
status,
|
|
3533
|
-
expires_at: new Date(expiresAtMs).toISOString()
|
|
3534
|
-
};
|
|
3535
|
-
}
|
|
3536
|
-
function parseExpiresAt(raw) {
|
|
3537
|
-
if (typeof raw === "number" && Number.isFinite(raw)) {
|
|
3538
|
-
return raw < 1e12 ? raw * 1e3 : raw;
|
|
3539
|
-
}
|
|
3540
|
-
if (typeof raw === "string") {
|
|
3541
|
-
const parsed = Date.parse(raw);
|
|
3542
|
-
return Number.isNaN(parsed) ? null : parsed;
|
|
3543
|
-
}
|
|
3544
|
-
return null;
|
|
3545
|
-
}
|
|
3546
|
-
|
|
3547
3610
|
// src/lib/channel-config-hash.ts
|
|
3548
|
-
import { createHash as
|
|
3611
|
+
import { createHash as createHash7 } from "crypto";
|
|
3549
3612
|
var CHANNEL_WRITE_VERSION = 9;
|
|
3550
3613
|
function computeChannelConfigHash(input) {
|
|
3551
|
-
return
|
|
3614
|
+
return createHash7("sha256").update(
|
|
3552
3615
|
canonicalJson({
|
|
3553
3616
|
writeVersion: CHANNEL_WRITE_VERSION,
|
|
3554
3617
|
cliVersion: input.cliVersion,
|
|
@@ -3564,7 +3627,7 @@ function computeChannelConfigHash(input) {
|
|
|
3564
3627
|
}
|
|
3565
3628
|
|
|
3566
3629
|
// src/lib/channel-hash-cache.ts
|
|
3567
|
-
import { existsSync as existsSync3, readFileSync as readFileSync11, writeFileSync as
|
|
3630
|
+
import { existsSync as existsSync3, readFileSync as readFileSync11, writeFileSync as writeFileSync5 } from "fs";
|
|
3568
3631
|
import { join as join13 } from "path";
|
|
3569
3632
|
var CACHE_FILENAME = "channel-hash-cache.json";
|
|
3570
3633
|
function getChannelHashCacheFile(configDir) {
|
|
@@ -3589,7 +3652,7 @@ function saveChannelHashCache(source, configDir) {
|
|
|
3589
3652
|
const obj = {};
|
|
3590
3653
|
for (const [key, value] of source) obj[key] = value;
|
|
3591
3654
|
try {
|
|
3592
|
-
|
|
3655
|
+
writeFileSync5(path, JSON.stringify(obj, null, 2));
|
|
3593
3656
|
} catch {
|
|
3594
3657
|
}
|
|
3595
3658
|
}
|
|
@@ -4138,8 +4201,8 @@ function planGlobalSkillSync(globalSkills, prevIds, hashOf, knownHash, options)
|
|
|
4138
4201
|
}
|
|
4139
4202
|
|
|
4140
4203
|
// src/lib/manager/managed-skill-manifest.ts
|
|
4141
|
-
import { existsSync as existsSync5, mkdirSync as
|
|
4142
|
-
import { dirname as
|
|
4204
|
+
import { existsSync as existsSync5, mkdirSync as mkdirSync5, readFileSync as readFileSync13, writeFileSync as writeFileSync6 } from "fs";
|
|
4205
|
+
import { dirname as dirname5, join as join15 } from "path";
|
|
4143
4206
|
var MANIFEST_VERSION = 1;
|
|
4144
4207
|
function managedSkillManifestPath(agentRootDir) {
|
|
4145
4208
|
return join15(agentRootDir, "managed-skills.json");
|
|
@@ -4156,12 +4219,12 @@ function readManagedSkillManifest(path) {
|
|
|
4156
4219
|
}
|
|
4157
4220
|
function writeManagedSkillManifest(path, ids) {
|
|
4158
4221
|
try {
|
|
4159
|
-
|
|
4222
|
+
mkdirSync5(dirname5(path), { recursive: true });
|
|
4160
4223
|
const body = {
|
|
4161
4224
|
version: MANIFEST_VERSION,
|
|
4162
4225
|
globalSkillIds: [...ids].sort()
|
|
4163
4226
|
};
|
|
4164
|
-
|
|
4227
|
+
writeFileSync6(path, JSON.stringify(body, null, 2));
|
|
4165
4228
|
} catch {
|
|
4166
4229
|
}
|
|
4167
4230
|
}
|
|
@@ -4238,7 +4301,7 @@ function clearRestartTiming(codeName) {
|
|
|
4238
4301
|
function resolveModelChain(refreshData) {
|
|
4239
4302
|
const agent = refreshData.agent;
|
|
4240
4303
|
const modelDefaults = refreshData.model_defaults;
|
|
4241
|
-
const
|
|
4304
|
+
const platform3 = modelDefaults?.platform ?? {};
|
|
4242
4305
|
const org = modelDefaults?.org ?? {};
|
|
4243
4306
|
function resolve(tier) {
|
|
4244
4307
|
const agentField = `${tier}_model`;
|
|
@@ -4247,7 +4310,7 @@ function resolveModelChain(refreshData) {
|
|
|
4247
4310
|
if (agentVal) return agentVal;
|
|
4248
4311
|
const orgVal = org?.[platformField];
|
|
4249
4312
|
if (orgVal) return orgVal;
|
|
4250
|
-
const platformVal =
|
|
4313
|
+
const platformVal = platform3?.[platformField];
|
|
4251
4314
|
if (platformVal) return platformVal;
|
|
4252
4315
|
return void 0;
|
|
4253
4316
|
}
|
|
@@ -4259,7 +4322,7 @@ function resolveModelChain(refreshData) {
|
|
|
4259
4322
|
}
|
|
4260
4323
|
|
|
4261
4324
|
// src/lib/manager/claude-auth.ts
|
|
4262
|
-
import { existsSync as existsSync6, rmSync as
|
|
4325
|
+
import { existsSync as existsSync6, rmSync as rmSync3 } from "fs";
|
|
4263
4326
|
import { join as join16 } from "path";
|
|
4264
4327
|
import { homedir as homedir7 } from "os";
|
|
4265
4328
|
async function applyClaudeAuthToEnv(childEnv, label) {
|
|
@@ -4278,7 +4341,7 @@ async function applyClaudeAuthToEnv(childEnv, label) {
|
|
|
4278
4341
|
const p = join16(claudeDir, filename);
|
|
4279
4342
|
if (existsSync6(p)) {
|
|
4280
4343
|
try {
|
|
4281
|
-
|
|
4344
|
+
rmSync3(p, { force: true });
|
|
4282
4345
|
log(`[${label}] Removed ${p} (api_key mode \u2014 preventing OAuth fallback)`);
|
|
4283
4346
|
} catch {
|
|
4284
4347
|
}
|
|
@@ -4576,7 +4639,7 @@ function formatBoardForPrompt(items, template) {
|
|
|
4576
4639
|
}
|
|
4577
4640
|
|
|
4578
4641
|
// src/lib/manager/kanban/nudge-state-cache.ts
|
|
4579
|
-
import { existsSync as existsSync8, readFileSync as readFileSync15, writeFileSync as
|
|
4642
|
+
import { existsSync as existsSync8, readFileSync as readFileSync15, writeFileSync as writeFileSync7 } from "fs";
|
|
4580
4643
|
import { join as join18 } from "path";
|
|
4581
4644
|
var CACHE_FILENAME2 = "kanban-nudge-state.json";
|
|
4582
4645
|
var KANBAN_NUDGE_STATE_VERSION = 1;
|
|
@@ -4613,13 +4676,13 @@ function saveKanbanNudgeState(source, configDir) {
|
|
|
4613
4676
|
const agents = {};
|
|
4614
4677
|
for (const [codeName, state7] of source) agents[codeName] = state7;
|
|
4615
4678
|
try {
|
|
4616
|
-
|
|
4679
|
+
writeFileSync7(path, JSON.stringify({ version: KANBAN_NUDGE_STATE_VERSION, agents }, null, 2));
|
|
4617
4680
|
} catch {
|
|
4618
4681
|
}
|
|
4619
4682
|
}
|
|
4620
4683
|
|
|
4621
4684
|
// src/lib/manager/kanban/notify.ts
|
|
4622
|
-
import { createHash as
|
|
4685
|
+
import { createHash as createHash8 } from "crypto";
|
|
4623
4686
|
async function enqueueKanbanNotice(opts) {
|
|
4624
4687
|
try {
|
|
4625
4688
|
const res = await api.post(
|
|
@@ -4634,7 +4697,7 @@ async function enqueueKanbanNotice(opts) {
|
|
|
4634
4697
|
return res.ok === true;
|
|
4635
4698
|
} catch (err) {
|
|
4636
4699
|
const errText = err instanceof Error ? err.message : String(err);
|
|
4637
|
-
const errId =
|
|
4700
|
+
const errId = createHash8("sha256").update(errText).digest("hex").slice(0, 12);
|
|
4638
4701
|
log(`[kanban] notice enqueue failed for agent_id=${opts.agentId} error_id=${errId}`);
|
|
4639
4702
|
return false;
|
|
4640
4703
|
}
|
|
@@ -4649,7 +4712,7 @@ async function cancelKanbanNotice(agentId) {
|
|
|
4649
4712
|
return typeof res.cancelled === "number" ? res.cancelled : 0;
|
|
4650
4713
|
} catch (err) {
|
|
4651
4714
|
const errText = err instanceof Error ? err.message : String(err);
|
|
4652
|
-
const errId =
|
|
4715
|
+
const errId = createHash8("sha256").update(errText).digest("hex").slice(0, 12);
|
|
4653
4716
|
log(`[kanban] notice cancel failed for agent_id=${agentId} error_id=${errId}`);
|
|
4654
4717
|
return null;
|
|
4655
4718
|
}
|
|
@@ -5055,7 +5118,7 @@ function deriveScheduledTaskNotify(task) {
|
|
|
5055
5118
|
}
|
|
5056
5119
|
|
|
5057
5120
|
// src/lib/manager/scheduler/runs.ts
|
|
5058
|
-
import { createHash as
|
|
5121
|
+
import { createHash as createHash9 } from "crypto";
|
|
5059
5122
|
async function startRun(opts) {
|
|
5060
5123
|
try {
|
|
5061
5124
|
const res = await api.post(
|
|
@@ -5070,7 +5133,7 @@ async function startRun(opts) {
|
|
|
5070
5133
|
};
|
|
5071
5134
|
} catch (err) {
|
|
5072
5135
|
const errText = err instanceof Error ? err.message : String(err);
|
|
5073
|
-
const errId =
|
|
5136
|
+
const errId = createHash9("sha256").update(errText).digest("hex").slice(0, 12);
|
|
5074
5137
|
log(`[runs] start failed for agent_id=${opts.agent_id} source_type=${opts.source_type} error_id=${errId}`);
|
|
5075
5138
|
return { run_id: null, kanban_item_id: null };
|
|
5076
5139
|
}
|
|
@@ -5087,7 +5150,7 @@ async function finishRun(runId, outcome, options = {}) {
|
|
|
5087
5150
|
});
|
|
5088
5151
|
} catch (err) {
|
|
5089
5152
|
const errText = err instanceof Error ? err.message : String(err);
|
|
5090
|
-
const errId =
|
|
5153
|
+
const errId = createHash9("sha256").update(errText).digest("hex").slice(0, 12);
|
|
5091
5154
|
log(`[runs] finish failed for run_id=${runId} outcome=${outcome} error_id=${errId}`);
|
|
5092
5155
|
}
|
|
5093
5156
|
}
|
|
@@ -5104,7 +5167,7 @@ async function fetchPriorScheduledRuns(agentId, taskId) {
|
|
|
5104
5167
|
return rows.filter((r) => typeof r.output_text === "string" && r.output_text.length > 0).map((r) => ({ startedAt: r.started_at, output: r.output_text }));
|
|
5105
5168
|
} catch (err) {
|
|
5106
5169
|
const errText = err instanceof Error ? err.message : String(err);
|
|
5107
|
-
const errId =
|
|
5170
|
+
const errId = createHash9("sha256").update(errText).digest("hex").slice(0, 12);
|
|
5108
5171
|
log(`[runs] prior-runs lookup failed for task_id=${taskId} error_id=${errId}`);
|
|
5109
5172
|
return [];
|
|
5110
5173
|
}
|
|
@@ -5153,13 +5216,13 @@ function closeScheduledRunsForCode(codeName, outcome, reason) {
|
|
|
5153
5216
|
}
|
|
5154
5217
|
|
|
5155
5218
|
// src/lib/manager/scheduler/kanban-route.ts
|
|
5156
|
-
import { createHash as
|
|
5157
|
-
import { writeFileSync as
|
|
5219
|
+
import { createHash as createHash11 } from "crypto";
|
|
5220
|
+
import { writeFileSync as writeFileSync8, renameSync as renameSync2, mkdirSync as mkdirSync6, readFileSync as readFileSync16, unlinkSync } from "fs";
|
|
5158
5221
|
import { homedir as homedir8 } from "os";
|
|
5159
|
-
import { join as join19, dirname as
|
|
5222
|
+
import { join as join19, dirname as dirname6 } from "path";
|
|
5160
5223
|
|
|
5161
5224
|
// src/lib/manager/scheduler/notify.ts
|
|
5162
|
-
import { createHash as
|
|
5225
|
+
import { createHash as createHash10 } from "crypto";
|
|
5163
5226
|
async function enqueueScheduledTaskNotice(opts) {
|
|
5164
5227
|
try {
|
|
5165
5228
|
const res = await api.post(
|
|
@@ -5175,7 +5238,7 @@ async function enqueueScheduledTaskNotice(opts) {
|
|
|
5175
5238
|
return res.ok === true;
|
|
5176
5239
|
} catch (err) {
|
|
5177
5240
|
const errText = err instanceof Error ? err.message : String(err);
|
|
5178
|
-
const errId =
|
|
5241
|
+
const errId = createHash10("sha256").update(errText).digest("hex").slice(0, 12);
|
|
5179
5242
|
log(
|
|
5180
5243
|
`[scheduled-kanban] notice enqueue failed for agent_id=${opts.agentId} task_id=${opts.taskId} error_id=${errId}`
|
|
5181
5244
|
);
|
|
@@ -5499,7 +5562,7 @@ function stampScheduledTurnMarker(codeName, taskId, target) {
|
|
|
5499
5562
|
const file = join19(homedir8(), ".augmented", codeName, SCHEDULED_TURN_MARKER_FILENAME);
|
|
5500
5563
|
const marker = { ts: Date.now(), task_id: taskId, ...target ? { target } : {} };
|
|
5501
5564
|
const tmp = `${file}.tmp`;
|
|
5502
|
-
|
|
5565
|
+
writeFileSync8(tmp, JSON.stringify(marker), "utf8");
|
|
5503
5566
|
renameSync2(tmp, file);
|
|
5504
5567
|
} catch (err) {
|
|
5505
5568
|
log(`[scheduled-kanban] scheduled-turn marker write failed for '${codeName}': ${err.message}`);
|
|
@@ -5563,8 +5626,8 @@ async function routeScheduledTaskViaKanban(codeName, agentId, task, prompt, dura
|
|
|
5563
5626
|
}
|
|
5564
5627
|
try {
|
|
5565
5628
|
const doorbell = directChatDoorbellPath(agentId, homedir8());
|
|
5566
|
-
|
|
5567
|
-
|
|
5629
|
+
mkdirSync6(dirname6(doorbell), { recursive: true });
|
|
5630
|
+
writeFileSync8(doorbell, String(Date.now()));
|
|
5568
5631
|
} catch (err) {
|
|
5569
5632
|
log(`[scheduled-kanban] doorbell ring failed for '${codeName}': ${err.message} (notice still queued)`);
|
|
5570
5633
|
}
|
|
@@ -5630,24 +5693,24 @@ async function processClaudeTaskResult(codeName, agentId, templateId, rawOutput,
|
|
|
5630
5693
|
const assertion = parseDeliverAssertion(rawOutput);
|
|
5631
5694
|
if (!assertion.deliver) {
|
|
5632
5695
|
const trimmed = (rawOutput ?? "").trim();
|
|
5633
|
-
const outputHash = trimmed.length === 0 ? "empty" :
|
|
5696
|
+
const outputHash = trimmed.length === 0 ? "empty" : createHash11("sha256").update(trimmed).digest("hex").slice(0, 12);
|
|
5634
5697
|
log(`[claude-scheduler] Suppressed by delivery_policy=conditional for '${codeName}' (template=${templateId}, task=${delivery?.taskId ?? "n/a"}) \u2014 ${assertion.vacuous ? "deliver marker had a vacuous reason" : "no deliver marker"}; output_len=${trimmed.length} output_hash=${outputHash}`);
|
|
5635
5698
|
if (delivery?.mode === "announce" && delivery.to) {
|
|
5636
5699
|
await reportDeliveryStatus(agentId, delivery.taskId, { status: "skipped", error_code: "SUPPRESSED_BY_POLICY" });
|
|
5637
5700
|
}
|
|
5638
5701
|
return { ok: true };
|
|
5639
5702
|
}
|
|
5640
|
-
const reasonHash =
|
|
5703
|
+
const reasonHash = createHash11("sha256").update(assertion.reason ?? "").digest("hex").slice(0, 12);
|
|
5641
5704
|
log(`[claude-scheduler] Delivering conditional run for '${codeName}' (template=${templateId}, task=${delivery?.taskId ?? "n/a"}) \u2014 agent asserted a concrete trigger (reason_len=${(assertion.reason ?? "").length} reason_hash=${reasonHash})`);
|
|
5642
5705
|
rawOutput = assertion.deliverable;
|
|
5643
5706
|
}
|
|
5644
5707
|
const classification = classifyOutput(rawOutput);
|
|
5645
5708
|
if (classification.action === "suppress") {
|
|
5646
5709
|
const trimmed = (rawOutput ?? "").trim();
|
|
5647
|
-
const outputHash = trimmed.length === 0 ? "empty" :
|
|
5710
|
+
const outputHash = trimmed.length === 0 ? "empty" : createHash11("sha256").update(trimmed).digest("hex").slice(0, 12);
|
|
5648
5711
|
log(`[claude-scheduler] Suppressing delivery for '${codeName}' (template=${templateId}, task=${delivery?.taskId ?? "n/a"}) \u2014 output_len=${trimmed.length} output_hash=${outputHash}`);
|
|
5649
5712
|
if (classification.suppressedNotes) {
|
|
5650
|
-
const notesHash =
|
|
5713
|
+
const notesHash = createHash11("sha256").update(classification.suppressedNotes).digest("hex").slice(0, 12);
|
|
5651
5714
|
log(`[claude-scheduler] Suppressed notes for '${codeName}' (task=${delivery?.taskId ?? "n/a"}) \u2014 notes_len=${classification.suppressedNotes.length} notes_hash=${notesHash}`);
|
|
5652
5715
|
}
|
|
5653
5716
|
if (delivery?.mode === "announce" && delivery.to) {
|
|
@@ -5713,7 +5776,7 @@ async function processClaudeTaskResult(codeName, agentId, templateId, rawOutput,
|
|
|
5713
5776
|
}
|
|
5714
5777
|
|
|
5715
5778
|
// src/lib/manager/scheduler/execution.ts
|
|
5716
|
-
import { createHash as
|
|
5779
|
+
import { createHash as createHash12 } from "crypto";
|
|
5717
5780
|
import { homedir as homedir9 } from "os";
|
|
5718
5781
|
import { join as join20 } from "path";
|
|
5719
5782
|
function claudePidFilePath() {
|
|
@@ -5737,10 +5800,10 @@ function unregisterClaudeSpawn(pid) {
|
|
|
5737
5800
|
}
|
|
5738
5801
|
async function syncAndCheckClaudeScheduler(agent, tasks, boardItems, refreshData, durableScheduledNudge = false) {
|
|
5739
5802
|
const codeName = agent.code_name;
|
|
5740
|
-
const stableTasksHash =
|
|
5741
|
-
const boardHash = boardItems.length > 0 ?
|
|
5803
|
+
const stableTasksHash = createHash12("sha256").update(JSON.stringify(tasks)).digest("hex").slice(0, 16);
|
|
5804
|
+
const boardHash = boardItems.length > 0 ? createHash12("sha256").update(JSON.stringify(boardItems.map((b) => ({ id: b.id, title: b.title, status: b.status, priority: b.priority, deliverable: b.deliverable })))).digest("hex").slice(0, 16) : "empty";
|
|
5742
5805
|
const resolvedModels = resolveModelChain(refreshData);
|
|
5743
|
-
const modelsHash =
|
|
5806
|
+
const modelsHash = createHash12("sha256").update(JSON.stringify(resolvedModels)).digest("hex").slice(0, 16);
|
|
5744
5807
|
const combinedHash = `${stableTasksHash}:${boardHash}:${modelsHash}`;
|
|
5745
5808
|
const prevHash = agentState.knownTasksHashes.get(agent.agent_id);
|
|
5746
5809
|
if (combinedHash !== prevHash) {
|
|
@@ -5831,7 +5894,7 @@ function stopPaneOccupancySampler() {
|
|
|
5831
5894
|
}
|
|
5832
5895
|
|
|
5833
5896
|
// src/lib/opencode-slack-ingest.ts
|
|
5834
|
-
import { createHash as
|
|
5897
|
+
import { createHash as createHash13 } from "crypto";
|
|
5835
5898
|
|
|
5836
5899
|
// ../../packages/core/dist/channels/slack-rich-text.js
|
|
5837
5900
|
var MAX_DEPTH = 12;
|
|
@@ -6767,7 +6830,7 @@ function startSlackIngest(config2) {
|
|
|
6767
6830
|
// src/lib/opencode-slack-ingest.ts
|
|
6768
6831
|
var ingests = /* @__PURE__ */ new Map();
|
|
6769
6832
|
function fingerprint(params) {
|
|
6770
|
-
return
|
|
6833
|
+
return createHash13("sha256").update(
|
|
6771
6834
|
JSON.stringify({
|
|
6772
6835
|
appToken: params.appToken,
|
|
6773
6836
|
botToken: params.botToken,
|
|
@@ -6848,7 +6911,7 @@ function stopAllOpencodeSlackIngests(log2) {
|
|
|
6848
6911
|
}
|
|
6849
6912
|
|
|
6850
6913
|
// src/lib/manager/opencode-scheduler.ts
|
|
6851
|
-
import { createHash as
|
|
6914
|
+
import { createHash as createHash14 } from "crypto";
|
|
6852
6915
|
var MAX_OPENCODE_SCHED_CONCURRENCY = 2;
|
|
6853
6916
|
var opencodeSchedulerStates = /* @__PURE__ */ new Map();
|
|
6854
6917
|
var inFlightOpencodeTasks = /* @__PURE__ */ new Set();
|
|
@@ -6862,7 +6925,7 @@ function shouldDeliver(task, reply) {
|
|
|
6862
6925
|
}
|
|
6863
6926
|
async function syncAndCheckOpencodeScheduler(agent, tasks, refreshData) {
|
|
6864
6927
|
const codeName = agent.code_name;
|
|
6865
|
-
const tasksHash =
|
|
6928
|
+
const tasksHash = createHash14("sha256").update(JSON.stringify(tasks)).digest("hex").slice(0, 16);
|
|
6866
6929
|
if (knownOpencodeTaskHashes.get(agent.agent_id) !== tasksHash) {
|
|
6867
6930
|
const taskInputs = tasks.map((t) => buildSchedulerTaskInput(t));
|
|
6868
6931
|
const state8 = syncTasksToScheduler(codeName, agent.agent_id, taskInputs);
|
|
@@ -6940,8 +7003,8 @@ async function fireOpencodeScheduledTask(agent, task) {
|
|
|
6940
7003
|
}
|
|
6941
7004
|
|
|
6942
7005
|
// src/lib/opencode-telegram-ingest.ts
|
|
6943
|
-
import { createHash as
|
|
6944
|
-
import { existsSync as existsSync9, mkdirSync as
|
|
7006
|
+
import { createHash as createHash15 } from "crypto";
|
|
7007
|
+
import { existsSync as existsSync9, mkdirSync as mkdirSync7, readFileSync as readFileSync17, renameSync as renameSync3, unlinkSync as unlinkSync2, writeFileSync as writeFileSync9 } from "fs";
|
|
6945
7008
|
import { randomUUID } from "crypto";
|
|
6946
7009
|
import { join as join21 } from "path";
|
|
6947
7010
|
|
|
@@ -7476,7 +7539,7 @@ function anySignal(signals) {
|
|
|
7476
7539
|
// src/lib/opencode-telegram-ingest.ts
|
|
7477
7540
|
var ingests2 = /* @__PURE__ */ new Map();
|
|
7478
7541
|
function fingerprint2(params) {
|
|
7479
|
-
return
|
|
7542
|
+
return createHash15("sha256").update(
|
|
7480
7543
|
JSON.stringify({
|
|
7481
7544
|
botToken: params.botToken,
|
|
7482
7545
|
allowedChats: [...params.allowedChats].sort(),
|
|
@@ -7518,8 +7581,8 @@ function createFileOffsetStore(codeName, log2, currentBotId) {
|
|
|
7518
7581
|
if (!filePath || !dir) return;
|
|
7519
7582
|
const tmpPath = `${filePath}.${process.pid}.${randomUUID()}.tmp`;
|
|
7520
7583
|
try {
|
|
7521
|
-
|
|
7522
|
-
|
|
7584
|
+
mkdirSync7(dir, { recursive: true, mode: 448 });
|
|
7585
|
+
writeFileSync9(
|
|
7523
7586
|
tmpPath,
|
|
7524
7587
|
JSON.stringify({
|
|
7525
7588
|
offset,
|
|
@@ -7750,7 +7813,7 @@ function partitionActionableByPoison(actionable, states, config2) {
|
|
|
7750
7813
|
}
|
|
7751
7814
|
|
|
7752
7815
|
// src/lib/restart-flags.ts
|
|
7753
|
-
import { existsSync as existsSync10, mkdirSync as
|
|
7816
|
+
import { existsSync as existsSync10, mkdirSync as mkdirSync8, readdirSync as readdirSync4, readFileSync as readFileSync18, renameSync as renameSync4, rmSync as rmSync4, writeFileSync as writeFileSync10 } from "fs";
|
|
7754
7817
|
import { homedir as homedir10 } from "os";
|
|
7755
7818
|
import { join as join22 } from "path";
|
|
7756
7819
|
import { randomUUID as randomUUID2 } from "crypto";
|
|
@@ -7786,7 +7849,7 @@ function readRestartFlags() {
|
|
|
7786
7849
|
function deleteRestartFlag(codeName) {
|
|
7787
7850
|
const path = flagPath(codeName);
|
|
7788
7851
|
if (existsSync10(path)) {
|
|
7789
|
-
|
|
7852
|
+
rmSync4(path, { force: true });
|
|
7790
7853
|
}
|
|
7791
7854
|
}
|
|
7792
7855
|
|
|
@@ -7885,8 +7948,8 @@ async function sendError(flag, opts, text) {
|
|
|
7885
7948
|
}
|
|
7886
7949
|
|
|
7887
7950
|
// src/lib/restart-context.ts
|
|
7888
|
-
import { readdirSync as readdirSync5, readFileSync as readFileSync19, writeFileSync as
|
|
7889
|
-
import { dirname as
|
|
7951
|
+
import { readdirSync as readdirSync5, readFileSync as readFileSync19, writeFileSync as writeFileSync11, mkdirSync as mkdirSync9, unlinkSync as unlinkSync3 } from "fs";
|
|
7952
|
+
import { dirname as dirname7, join as join23 } from "path";
|
|
7890
7953
|
var SLACK_PENDING_INBOUND_DIRNAME = "slack-pending-inbound";
|
|
7891
7954
|
var SLACK_RESTART_CONTEXT_DIRNAME = "slack-restart-context";
|
|
7892
7955
|
var MAX_TOPIC_CHARS = 140;
|
|
@@ -7895,7 +7958,7 @@ var RECONSTRUCT_WINDOW_MS = 7 * 24 * 60 * 60 * 1e3;
|
|
|
7895
7958
|
var WINDOW_PAD_MS3 = 5 * 6e4;
|
|
7896
7959
|
var DEFAULT_MAX_MARKERS_PER_AGENT = 25;
|
|
7897
7960
|
function augmentedAgentDir(codeName) {
|
|
7898
|
-
return
|
|
7961
|
+
return dirname7(getProjectDir(codeName));
|
|
7899
7962
|
}
|
|
7900
7963
|
function slackPendingInboundDir(codeName) {
|
|
7901
7964
|
return join23(augmentedAgentDir(codeName), SLACK_PENDING_INBOUND_DIRNAME);
|
|
@@ -7952,8 +8015,8 @@ function readStrandedMarker(path) {
|
|
|
7952
8015
|
return null;
|
|
7953
8016
|
}
|
|
7954
8017
|
function writeHintFile(path, dir, hint) {
|
|
7955
|
-
|
|
7956
|
-
|
|
8018
|
+
mkdirSync9(dir, { recursive: true, mode: 448 });
|
|
8019
|
+
writeFileSync11(path, JSON.stringify(hint), { mode: 384 });
|
|
7957
8020
|
}
|
|
7958
8021
|
function pruneHintsExcept(codeName, freshFilenames) {
|
|
7959
8022
|
const ctxDir = slackRestartContextDir(codeName);
|
|
@@ -9228,7 +9291,7 @@ var sessionLaunchManagedStructure = /* @__PURE__ */ new Map();
|
|
|
9228
9291
|
function projectMcpHash(_codeName, projectDir) {
|
|
9229
9292
|
try {
|
|
9230
9293
|
const raw = readFileSync20(join24(projectDir, ".mcp.json"), "utf-8");
|
|
9231
|
-
return
|
|
9294
|
+
return createHash16("sha256").update(canonicalJson(JSON.parse(raw))).digest("hex");
|
|
9232
9295
|
} catch {
|
|
9233
9296
|
return null;
|
|
9234
9297
|
}
|
|
@@ -9604,7 +9667,7 @@ var agentRestartTimezoneInputs = /* @__PURE__ */ new Map();
|
|
|
9604
9667
|
var lastVersionCheckAt = 0;
|
|
9605
9668
|
var VERSION_CHECK_INTERVAL_MS = 5 * 60 * 1e3;
|
|
9606
9669
|
var lastResponsivenessProbeAt = 0;
|
|
9607
|
-
var agtCliVersion = true ? "0.28.
|
|
9670
|
+
var agtCliVersion = true ? "0.28.435" : "dev";
|
|
9608
9671
|
function resolveBrewPath(execFileSync2) {
|
|
9609
9672
|
try {
|
|
9610
9673
|
const out = execFileSync2("which", ["brew"], { timeout: 5e3 }).toString().trim();
|
|
@@ -9699,7 +9762,7 @@ async function ensureToolkitCli(toolkitSlug) {
|
|
|
9699
9762
|
toolkitCliEnsured.add(toolkitSlug);
|
|
9700
9763
|
return;
|
|
9701
9764
|
}
|
|
9702
|
-
brewBinDir =
|
|
9765
|
+
brewBinDir = dirname8(brewPath);
|
|
9703
9766
|
const isRoot = typeof process.getuid === "function" && process.getuid() === 0;
|
|
9704
9767
|
log(`[toolkit-install] ${toolkitSlug}: installing via brew (${pkg})\u2026`);
|
|
9705
9768
|
if (isRoot) {
|
|
@@ -9909,8 +9972,8 @@ function ensureClaudeManagedSettings(path = claudeManagedSettingsPath()) {
|
|
|
9909
9972
|
}
|
|
9910
9973
|
if (settings.channelsEnabled === true) return "ok";
|
|
9911
9974
|
settings.channelsEnabled = true;
|
|
9912
|
-
|
|
9913
|
-
|
|
9975
|
+
mkdirSync10(dirname8(path), { recursive: true });
|
|
9976
|
+
writeFileSync12(path, `${JSON.stringify(settings, null, 2)}
|
|
9914
9977
|
`);
|
|
9915
9978
|
log(`[managed-settings] set channelsEnabled:true in ${path} (ENG-5786 \u2014 unblocks Claude Code channels)`);
|
|
9916
9979
|
return "ok";
|
|
@@ -10005,7 +10068,7 @@ async function ensureFrameworkBinary(frameworkId) {
|
|
|
10005
10068
|
log(`Claude Code install failed: ${err.message}`);
|
|
10006
10069
|
return;
|
|
10007
10070
|
}
|
|
10008
|
-
const brewBinDir =
|
|
10071
|
+
const brewBinDir = dirname8(brewPath);
|
|
10009
10072
|
if (!process.env.PATH?.split(":").includes(brewBinDir)) {
|
|
10010
10073
|
process.env.PATH = `${brewBinDir}:${process.env.PATH ?? ""}`;
|
|
10011
10074
|
}
|
|
@@ -10455,11 +10518,11 @@ function ensureEvalEmptyMcpConfig() {
|
|
|
10455
10518
|
if (evalEmptyMcpConfigPath && existsSync11(evalEmptyMcpConfigPath)) return evalEmptyMcpConfigPath;
|
|
10456
10519
|
const dir = join24(homedir11(), ".augmented");
|
|
10457
10520
|
try {
|
|
10458
|
-
|
|
10521
|
+
mkdirSync10(dir, { recursive: true });
|
|
10459
10522
|
} catch {
|
|
10460
10523
|
}
|
|
10461
10524
|
const p = join24(dir, ".eval-empty-mcp.json");
|
|
10462
|
-
|
|
10525
|
+
writeFileSync12(p, JSON.stringify({ mcpServers: {} }));
|
|
10463
10526
|
evalEmptyMcpConfigPath = p;
|
|
10464
10527
|
return p;
|
|
10465
10528
|
}
|
|
@@ -10689,7 +10752,7 @@ function parseSkillFrontmatter(content) {
|
|
|
10689
10752
|
return out;
|
|
10690
10753
|
}
|
|
10691
10754
|
async function refreshSkillsIndexInClaudeMd(configDir, codeName, log2) {
|
|
10692
|
-
const { readdirSync: readdirSync7, readFileSync: rfs, existsSync: ex, writeFileSync:
|
|
10755
|
+
const { readdirSync: readdirSync7, readFileSync: rfs, existsSync: ex, writeFileSync: writeFileSync13 } = await import("fs");
|
|
10693
10756
|
const skillsDir = join24(configDir, codeName, "project", ".claude", "skills");
|
|
10694
10757
|
const claudeMdPath = join24(configDir, codeName, "project", "CLAUDE.md");
|
|
10695
10758
|
if (!ex(skillsDir) || !ex(claudeMdPath)) return;
|
|
@@ -10739,7 +10802,7 @@ ${SKILLS_INDEX_END}`;
|
|
|
10739
10802
|
next = current.trimEnd() + "\n\n" + section + "\n";
|
|
10740
10803
|
}
|
|
10741
10804
|
if (next !== current) {
|
|
10742
|
-
|
|
10805
|
+
writeFileSync13(claudeMdPath, next, "utf-8");
|
|
10743
10806
|
log2(
|
|
10744
10807
|
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)`
|
|
10745
10808
|
);
|
|
@@ -10762,7 +10825,7 @@ function flushRestartedAgentDiagnostics(hostId, codeNames) {
|
|
|
10762
10825
|
if (codeNames.length === 0) return;
|
|
10763
10826
|
void (async () => {
|
|
10764
10827
|
try {
|
|
10765
|
-
const { collectDiagnostics } = await import("../persistent-session-
|
|
10828
|
+
const { collectDiagnostics } = await import("../persistent-session-D2POY3KV.js");
|
|
10766
10829
|
await api.post("/host/heartbeat", {
|
|
10767
10830
|
host_id: hostId,
|
|
10768
10831
|
agent_diagnostics: collectDiagnostics(codeNames, quarantineEntriesFor, claudeMdSizeFor)
|
|
@@ -10869,7 +10932,7 @@ async function pollCycle() {
|
|
|
10869
10932
|
}
|
|
10870
10933
|
try {
|
|
10871
10934
|
const { detectHostSecurity } = await import("../host-security-6PDFG7F5.js");
|
|
10872
|
-
const { collectDiagnostics } = await import("../persistent-session-
|
|
10935
|
+
const { collectDiagnostics } = await import("../persistent-session-D2POY3KV.js");
|
|
10873
10936
|
const diagCodeNames = [...agentState.persistentSessionAgents];
|
|
10874
10937
|
const agentDiagnostics = diagCodeNames.length > 0 ? collectDiagnostics(diagCodeNames, quarantineEntriesFor, claudeMdSizeFor) : void 0;
|
|
10875
10938
|
let tailscaleHostname;
|
|
@@ -10899,7 +10962,7 @@ async function pollCycle() {
|
|
|
10899
10962
|
claudeAuth = await detectClaudeAuth();
|
|
10900
10963
|
} catch (err) {
|
|
10901
10964
|
const errText = err instanceof Error ? err.message : String(err);
|
|
10902
|
-
const errId =
|
|
10965
|
+
const errId = createHash16("sha256").update(errText).digest("hex").slice(0, 12);
|
|
10903
10966
|
log(`Claude auth detection failed (error_id=${errId})`);
|
|
10904
10967
|
}
|
|
10905
10968
|
const hostHasClaudeCode = state6.agents.some(
|
|
@@ -10983,7 +11046,7 @@ async function pollCycle() {
|
|
|
10983
11046
|
collectResponsivenessProbes,
|
|
10984
11047
|
collectPanelessActivityProbes,
|
|
10985
11048
|
getResponsivenessIntervalMs
|
|
10986
|
-
} = await import("../responsiveness-probe-
|
|
11049
|
+
} = await import("../responsiveness-probe-ARRF5CAQ.js");
|
|
10987
11050
|
const probeIntervalMs = getResponsivenessIntervalMs();
|
|
10988
11051
|
if (now - lastResponsivenessProbeAt > probeIntervalMs) {
|
|
10989
11052
|
const probeCodeNames = [...agentState.persistentSessionAgents];
|
|
@@ -11047,7 +11110,7 @@ async function pollCycle() {
|
|
|
11047
11110
|
collectResponsivenessProbes,
|
|
11048
11111
|
livePendingInboundOldestAgeSeconds,
|
|
11049
11112
|
parkPendingInbound
|
|
11050
|
-
} = await import("../responsiveness-probe-
|
|
11113
|
+
} = await import("../responsiveness-probe-ARRF5CAQ.js");
|
|
11051
11114
|
const { getProjectDir: wedgeProjectDir } = await import("../scheduler-engine-NDP36U7O.js");
|
|
11052
11115
|
const wedgeNow = /* @__PURE__ */ new Date();
|
|
11053
11116
|
const liveAgents = agentState.persistentSessionAgents;
|
|
@@ -11863,7 +11926,7 @@ async function processAgent(agent, agentStates) {
|
|
|
11863
11926
|
try {
|
|
11864
11927
|
const artifacts = generateArtifacts(agent, refreshData, frameworkAdapter);
|
|
11865
11928
|
const changedFiles = [];
|
|
11866
|
-
|
|
11929
|
+
mkdirSync10(agentDir, { recursive: true });
|
|
11867
11930
|
for (const artifact of artifacts) {
|
|
11868
11931
|
const filePath = join24(agentDir, artifact.relativePath);
|
|
11869
11932
|
let existingHash;
|
|
@@ -11941,11 +12004,11 @@ async function processAgent(agent, agentStates) {
|
|
|
11941
12004
|
log(`${verb} '${agent.code_name}': ${fileNames}`);
|
|
11942
12005
|
for (const file of changedFiles) {
|
|
11943
12006
|
const filePath = join24(agentDir, file.relativePath);
|
|
11944
|
-
|
|
12007
|
+
mkdirSync10(dirname8(filePath), { recursive: true });
|
|
11945
12008
|
if (file.relativePath === ".mcp.json") {
|
|
11946
12009
|
safeWriteJsonAtomic(filePath, file.content, { mode: 384 });
|
|
11947
12010
|
} else {
|
|
11948
|
-
|
|
12011
|
+
writeFileSync12(filePath, file.content);
|
|
11949
12012
|
}
|
|
11950
12013
|
}
|
|
11951
12014
|
try {
|
|
@@ -11954,7 +12017,7 @@ async function processAgent(agent, agentStates) {
|
|
|
11954
12017
|
for (const folder of readdirSync6(provSkillsDir)) {
|
|
11955
12018
|
if (folder.startsWith("knowledge-")) {
|
|
11956
12019
|
try {
|
|
11957
|
-
|
|
12020
|
+
rmSync5(join24(provSkillsDir, folder), { recursive: true });
|
|
11958
12021
|
} catch {
|
|
11959
12022
|
}
|
|
11960
12023
|
}
|
|
@@ -11992,7 +12055,7 @@ async function processAgent(agent, agentStates) {
|
|
|
11992
12055
|
if (!file.endsWith(".js")) continue;
|
|
11993
12056
|
if (expected.has(file)) continue;
|
|
11994
12057
|
try {
|
|
11995
|
-
|
|
12058
|
+
rmSync5(join24(provWorkflowsDir, file));
|
|
11996
12059
|
} catch {
|
|
11997
12060
|
}
|
|
11998
12061
|
}
|
|
@@ -12273,7 +12336,7 @@ async function processAgent(agent, agentStates) {
|
|
|
12273
12336
|
const writeDmNoticeMarkers = isChannelAddRestart ? () => {
|
|
12274
12337
|
try {
|
|
12275
12338
|
const agentAugmentedDir = join24(homedir11(), ".augmented", agent.code_name);
|
|
12276
|
-
|
|
12339
|
+
mkdirSync10(agentAugmentedDir, { recursive: true });
|
|
12277
12340
|
const markerJson = JSON.stringify({
|
|
12278
12341
|
version: 1,
|
|
12279
12342
|
at: (/* @__PURE__ */ new Date()).toISOString(),
|
|
@@ -12356,7 +12419,7 @@ async function processAgent(agent, agentStates) {
|
|
|
12356
12419
|
const behaviourSubset = extractMsTeamsBehaviourSubset(
|
|
12357
12420
|
msteamsEntry?.config
|
|
12358
12421
|
);
|
|
12359
|
-
const behaviourHash =
|
|
12422
|
+
const behaviourHash = createHash16("sha256").update(canonicalJson(behaviourSubset)).digest("hex");
|
|
12360
12423
|
const prevBehaviourHash = agentState.knownMsTeamsBehaviourHashes.get(agent.agent_id);
|
|
12361
12424
|
const msteamsBehaviourRestrictive = isMsTeamsBehaviourRestrictive(behaviourSubset);
|
|
12362
12425
|
const behaviourDecision = decideSenderPolicyRestart({
|
|
@@ -12412,7 +12475,7 @@ async function processAgent(agent, agentStates) {
|
|
|
12412
12475
|
const slackBehaviourSubset = extractSlackBehaviourSubset(
|
|
12413
12476
|
slackEntry?.config
|
|
12414
12477
|
);
|
|
12415
|
-
const slackBehaviourHash =
|
|
12478
|
+
const slackBehaviourHash = createHash16("sha256").update(canonicalJson(slackBehaviourSubset)).digest("hex");
|
|
12416
12479
|
const prevSlackBehaviourHash = agentState.knownSlackBehaviourHashes.get(agent.agent_id);
|
|
12417
12480
|
const slackBehaviourRestrictive = isSlackBehaviourRestrictive(slackBehaviourSubset);
|
|
12418
12481
|
const slackBehaviourDecision = decideSenderPolicyRestart({
|
|
@@ -12470,8 +12533,8 @@ async function processAgent(agent, agentStates) {
|
|
|
12470
12533
|
try {
|
|
12471
12534
|
const agentProvisionDir = agentDir;
|
|
12472
12535
|
const projectDir = join24(homedir11(), ".augmented", agent.code_name, "project");
|
|
12473
|
-
|
|
12474
|
-
|
|
12536
|
+
mkdirSync10(agentProvisionDir, { recursive: true });
|
|
12537
|
+
mkdirSync10(projectDir, { recursive: true });
|
|
12475
12538
|
const provisionMcpPath = join24(agentProvisionDir, ".mcp.json");
|
|
12476
12539
|
const projectMcpPath = join24(projectDir, ".mcp.json");
|
|
12477
12540
|
let mcpConfig = { mcpServers: {} };
|
|
@@ -12529,7 +12592,7 @@ async function processAgent(agent, agentStates) {
|
|
|
12529
12592
|
const staleChannelsPath = join24(projectDir, ".mcp-channels.json");
|
|
12530
12593
|
if (existsSync11(staleChannelsPath)) {
|
|
12531
12594
|
try {
|
|
12532
|
-
|
|
12595
|
+
rmSync5(staleChannelsPath, { force: true });
|
|
12533
12596
|
} catch {
|
|
12534
12597
|
}
|
|
12535
12598
|
}
|
|
@@ -12845,10 +12908,10 @@ async function processAgent(agent, agentStates) {
|
|
|
12845
12908
|
desiredEntries.push({ serverId, url, headers: mcpHeaders, name: tk.toolkit_name });
|
|
12846
12909
|
}
|
|
12847
12910
|
const hashBasis = desiredEntries.slice().sort((a, b) => a.serverId.localeCompare(b.serverId)).map((e) => {
|
|
12848
|
-
const headersHash =
|
|
12911
|
+
const headersHash = createHash16("sha256").update(canonicalJson(e.headers ?? {})).digest("hex").slice(0, 16);
|
|
12849
12912
|
return `${e.serverId}|${e.url}|${headersHash}`;
|
|
12850
12913
|
}).join("\n");
|
|
12851
|
-
const mcpHash =
|
|
12914
|
+
const mcpHash = createHash16("sha256").update(hashBasis).digest("hex").slice(0, 16);
|
|
12852
12915
|
const prevMcpHash = agentState.knownManagedMcpHashes.get(agent.agent_id);
|
|
12853
12916
|
const structureHash = managedMcpStructureHash(desiredEntries);
|
|
12854
12917
|
const prevStructureHash = agentState.knownManagedMcpStructure.get(agent.agent_id);
|
|
@@ -12863,7 +12926,7 @@ async function processAgent(agent, agentStates) {
|
|
|
12863
12926
|
if (mcpHash !== prevMcpHash) {
|
|
12864
12927
|
for (const e of desiredEntries) {
|
|
12865
12928
|
frameworkAdapter.writeMcpServer(agent.code_name, e.serverId, { url: e.url, headers: e.headers });
|
|
12866
|
-
const urlHash =
|
|
12929
|
+
const urlHash = createHash16("sha256").update(e.url).digest("hex").slice(0, 12);
|
|
12867
12930
|
log(`[managed-toolkit] ${agent.code_name}: wrote '${e.name}' (serverId=${e.serverId}, url_hash=${urlHash})`);
|
|
12868
12931
|
}
|
|
12869
12932
|
if (frameworkAdapter.removeMcpServer && frameworkAdapter.readMcpServers) {
|
|
@@ -12965,7 +13028,7 @@ async function processAgent(agent, agentStates) {
|
|
|
12965
13028
|
if (frameworkAdapter.installSkillFiles) {
|
|
12966
13029
|
const currentIntegrationSkillIds = /* @__PURE__ */ new Set();
|
|
12967
13030
|
const installedIntegrationSkills = [];
|
|
12968
|
-
const { createHash:
|
|
13031
|
+
const { createHash: createHash17 } = await import("crypto");
|
|
12969
13032
|
const refreshAny = refreshData;
|
|
12970
13033
|
const contexts = refreshAny.integration_contexts ?? refreshAny.plugin_contexts ?? [];
|
|
12971
13034
|
const contextBySlug = /* @__PURE__ */ new Map();
|
|
@@ -12994,7 +13057,7 @@ async function processAgent(agent, agentStates) {
|
|
|
12994
13057
|
)
|
|
12995
13058
|
}));
|
|
12996
13059
|
const bundle = buildIntegrationBundle(renderedScopes);
|
|
12997
|
-
const contentHash =
|
|
13060
|
+
const contentHash = createHash17("sha256").update(bundleFingerprint(bundle.files)).digest("hex").slice(0, 12);
|
|
12998
13061
|
const hashKey = `plugin-skill:${agent.agent_id}:${integrationSkillId}`;
|
|
12999
13062
|
if (agentState.knownSkillHashes.get(hashKey) === contentHash) continue;
|
|
13000
13063
|
frameworkAdapter.installSkillFiles(agent.code_name, integrationSkillId, bundle.files);
|
|
@@ -13006,7 +13069,7 @@ async function processAgent(agent, agentStates) {
|
|
|
13006
13069
|
}
|
|
13007
13070
|
}
|
|
13008
13071
|
try {
|
|
13009
|
-
const { readdirSync: readdirSync7, rmSync:
|
|
13072
|
+
const { readdirSync: readdirSync7, rmSync: rmSync6 } = await import("fs");
|
|
13010
13073
|
const { homedir: homedir12 } = await import("os");
|
|
13011
13074
|
const frameworkId2 = frameworkAdapter.id;
|
|
13012
13075
|
const candidateSkillDirs = [
|
|
@@ -13034,7 +13097,7 @@ async function processAgent(agent, agentStates) {
|
|
|
13034
13097
|
for (const dir of existingDirs) {
|
|
13035
13098
|
const p = join24(dir, entry);
|
|
13036
13099
|
if (existsSync11(p)) {
|
|
13037
|
-
|
|
13100
|
+
rmSync6(p, { recursive: true, force: true });
|
|
13038
13101
|
}
|
|
13039
13102
|
}
|
|
13040
13103
|
log(`Removed ${reason} '${entry}' for '${agent.code_name}' (framework=${frameworkId2})`);
|
|
@@ -13061,7 +13124,7 @@ async function processAgent(agent, agentStates) {
|
|
|
13061
13124
|
const plan = planGlobalSkillSync(
|
|
13062
13125
|
[...globalSkillsPayload ?? [], ...sharedSkillsPayload ?? []],
|
|
13063
13126
|
prevIds,
|
|
13064
|
-
(content) =>
|
|
13127
|
+
(content) => createHash17("sha256").update(content).digest("hex").slice(0, 12),
|
|
13065
13128
|
(skillId) => agentState.knownSkillHashes.get(`global-skill:${agent.agent_id}:${skillId}`),
|
|
13066
13129
|
{ desiredResolved }
|
|
13067
13130
|
);
|
|
@@ -13081,7 +13144,7 @@ async function processAgent(agent, agentStates) {
|
|
|
13081
13144
|
for (const dir of globalSkillDirs) {
|
|
13082
13145
|
const p = join24(dir, id);
|
|
13083
13146
|
if (existsSync11(p) && existsSync11(join24(p, "SKILL.md"))) {
|
|
13084
|
-
|
|
13147
|
+
rmSync5(p, { recursive: true, force: true });
|
|
13085
13148
|
prunedAny = true;
|
|
13086
13149
|
}
|
|
13087
13150
|
}
|
|
@@ -13112,7 +13175,7 @@ async function processAgent(agent, agentStates) {
|
|
|
13112
13175
|
const slug = hook.integration_slug ?? hook.plugin_slug;
|
|
13113
13176
|
if (!slug) continue;
|
|
13114
13177
|
try {
|
|
13115
|
-
const scriptHash =
|
|
13178
|
+
const scriptHash = createHash17("sha256").update(hook.script).digest("hex").slice(0, 12);
|
|
13116
13179
|
const hookKey = `${agent.agent_id}:${frameworkAdapter.id}:plugin-hook:${slug}:on_install`;
|
|
13117
13180
|
if (agentState.knownSkillHashes.get(hookKey) === scriptHash) continue;
|
|
13118
13181
|
const result = await frameworkAdapter.executePluginHook({
|
|
@@ -13127,9 +13190,9 @@ async function processAgent(agent, agentStates) {
|
|
|
13127
13190
|
} else if (result.timedOut) {
|
|
13128
13191
|
log(`Integration hook on_install '${slug}' TIMED OUT for '${agent.code_name}' after ${result.durationMs}ms`);
|
|
13129
13192
|
} else {
|
|
13130
|
-
const stderrHash =
|
|
13193
|
+
const stderrHash = createHash17("sha256").update(result.stderr).digest("hex").slice(0, 12);
|
|
13131
13194
|
const missingCmd = result.exitCode === 127 ? extractCommandNotFound(result.stderr) : null;
|
|
13132
|
-
const missingCmdHash = missingCmd ?
|
|
13195
|
+
const missingCmdHash = missingCmd ? createHash17("sha256").update(missingCmd).digest("hex").slice(0, 8) : null;
|
|
13133
13196
|
log(
|
|
13134
13197
|
`Integration hook on_install '${slug}' exited ${result.exitCode} for '${agent.code_name}' ` + (missingCmdHash ? `[missing_command_hash=${missingCmdHash}] ` : "") + `[stderr_hash=${stderrHash} stderr_len=${result.stderr.length}]`
|
|
13135
13198
|
);
|
|
@@ -13921,7 +13984,8 @@ async function ensurePersistentSession(agent, tasks, boardItems, refreshData) {
|
|
|
13921
13984
|
let restartTrigger = null;
|
|
13922
13985
|
let dayRolloverDeferred = false;
|
|
13923
13986
|
let dayRolloverForced = false;
|
|
13924
|
-
const
|
|
13987
|
+
const claudeAccountFingerprint = !openRouterForAgent && claudeAuthMode === "subscription" ? await getClaudeAccountFingerprint() : null;
|
|
13988
|
+
const currentAuthTuple = openRouterForAgent ? `openrouter:${openRouterForAgent.fingerprint ?? openRouterForAgent.model}` : `${claudeAuthMode}:${anthropicApiKeyFingerprint ?? "none"}${claudeAccountFingerprint ? `:${claudeAccountFingerprint}` : ""}`;
|
|
13925
13989
|
const recordedAuthTuple = claudeAuthTupleBySession.get(codeName);
|
|
13926
13990
|
if (recordedAuthTuple && recordedAuthTuple !== currentAuthTuple && isSessionHealthy(codeName)) {
|
|
13927
13991
|
log(`[persistent-session] Auth config changed for '${codeName}' (${recordedAuthTuple} \u2192 ${currentAuthTuple}) \u2014 restarting session`);
|
|
@@ -13973,7 +14037,7 @@ async function ensurePersistentSession(agent, tasks, boardItems, refreshData) {
|
|
|
13973
14037
|
const ctx = getLastFailureContext(codeName);
|
|
13974
14038
|
const recovery = prepareForRespawn(codeName);
|
|
13975
14039
|
const tailSummary = !ctx.tail ? "" : KNOWN_SAFE_TAIL_SIGNATURES.has(ctx.signature) ? `; last pane output (${PANE_TAIL_PREVIEW_LINES} of ~20 lines):
|
|
13976
|
-
${truncateForLog(ctx.tail)}` : `; pane_tail_hash=sha256:${
|
|
14040
|
+
${truncateForLog(ctx.tail)}` : `; pane_tail_hash=sha256:${createHash16("sha256").update(ctx.tail).digest("hex").slice(0, 12)} (raw at ~/.augmented/${codeName}/pane.log)`;
|
|
13977
14041
|
const sigSummary = ctx.signature !== "unknown" ? `; signature=${ctx.signature}` : "";
|
|
13978
14042
|
const recoverySummary = recovery ? `; recovery=${recovery}` : "";
|
|
13979
14043
|
log(
|
|
@@ -13987,7 +14051,7 @@ ${truncateForLog(ctx.tail)}` : `; pane_tail_hash=sha256:${createHash15("sha256")
|
|
|
13987
14051
|
);
|
|
13988
14052
|
getHostId().then((hostId) => {
|
|
13989
14053
|
if (!hostId) return;
|
|
13990
|
-
const paneTailHash = zombie.paneTail ? `sha256:${
|
|
14054
|
+
const paneTailHash = zombie.paneTail ? `sha256:${createHash16("sha256").update(zombie.paneTail).digest("hex").slice(0, 12)}` : null;
|
|
13991
14055
|
return api.post("/host/events", {
|
|
13992
14056
|
host_id: hostId,
|
|
13993
14057
|
agent_code_name: codeName,
|
|
@@ -14136,7 +14200,7 @@ ${truncateForLog(ctx.tail)}` : `; pane_tail_hash=sha256:${createHash15("sha256")
|
|
|
14136
14200
|
if (!claudeAuthTupleBySession.has(codeName)) {
|
|
14137
14201
|
claudeAuthTupleBySession.set(codeName, currentAuthTuple);
|
|
14138
14202
|
}
|
|
14139
|
-
const stableTasksHash =
|
|
14203
|
+
const stableTasksHash = createHash16("sha256").update(JSON.stringify(tasks)).digest("hex").slice(0, 16);
|
|
14140
14204
|
const prevHash = agentState.knownTasksHashes.get(agent.agent_id);
|
|
14141
14205
|
if (stableTasksHash !== prevHash) {
|
|
14142
14206
|
const taskInputs = tasks.map((t) => buildSchedulerTaskInput(t));
|
|
@@ -14364,7 +14428,7 @@ async function handleRestartDoorbell(agentId, requestedAt, restartReason) {
|
|
|
14364
14428
|
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}`));
|
|
14365
14429
|
void (async () => {
|
|
14366
14430
|
try {
|
|
14367
|
-
const { collectDiagnostics } = await import("../persistent-session-
|
|
14431
|
+
const { collectDiagnostics } = await import("../persistent-session-D2POY3KV.js");
|
|
14368
14432
|
await api.post("/host/heartbeat", {
|
|
14369
14433
|
host_id: hostId,
|
|
14370
14434
|
agent_diagnostics: collectDiagnostics([codeName], quarantineEntriesFor, claudeMdSizeFor)
|
|
@@ -14414,7 +14478,7 @@ async function respawnAgentAfterMcpStop(codeName, reason) {
|
|
|
14414
14478
|
}
|
|
14415
14479
|
try {
|
|
14416
14480
|
const hostId = await getHostId();
|
|
14417
|
-
const { collectDiagnostics } = await import("../persistent-session-
|
|
14481
|
+
const { collectDiagnostics } = await import("../persistent-session-D2POY3KV.js");
|
|
14418
14482
|
await api.post("/host/heartbeat", {
|
|
14419
14483
|
host_id: hostId,
|
|
14420
14484
|
agent_diagnostics: collectDiagnostics([codeName], quarantineEntriesFor, claudeMdSizeFor)
|
|
@@ -14700,8 +14764,8 @@ async function processDirectChatMessage(agent, msg) {
|
|
|
14700
14764
|
if (useDoorbell) {
|
|
14701
14765
|
try {
|
|
14702
14766
|
const doorbell = directChatDoorbellPath(agent.agentId, homedir11());
|
|
14703
|
-
|
|
14704
|
-
|
|
14767
|
+
mkdirSync10(dirname8(doorbell), { recursive: true });
|
|
14768
|
+
writeFileSync12(doorbell, String(Date.now()));
|
|
14705
14769
|
log(`[direct-chat] Doorbell rung for '${agent.codeName}' (msg=${msg.id}) \u2014 in-session MCP will pull via the cursor`);
|
|
14706
14770
|
return;
|
|
14707
14771
|
} catch (err) {
|
|
@@ -14810,8 +14874,8 @@ ${formatRunMarker(run_id)}` : KANBAN_CHECK_COMMAND;
|
|
|
14810
14874
|
if (run_id) openInjectedRunByCode.set(codeName, run_id);
|
|
14811
14875
|
try {
|
|
14812
14876
|
const doorbell = directChatDoorbellPath(agentId, homedir11());
|
|
14813
|
-
|
|
14814
|
-
|
|
14877
|
+
mkdirSync10(dirname8(doorbell), { recursive: true });
|
|
14878
|
+
writeFileSync12(doorbell, String(Date.now()));
|
|
14815
14879
|
} catch (err) {
|
|
14816
14880
|
log(`[kanban] doorbell ring failed for '${codeName}': ${err.message} (notice still queued)`);
|
|
14817
14881
|
}
|
|
@@ -14867,7 +14931,7 @@ async function processClaudePairSessions(agents) {
|
|
|
14867
14931
|
killPairSession,
|
|
14868
14932
|
pairTmuxSession,
|
|
14869
14933
|
finalizeClaudePairOnboarding
|
|
14870
|
-
} = await import("../claude-pair-runtime-
|
|
14934
|
+
} = await import("../claude-pair-runtime-CHKX4WH2.js");
|
|
14871
14935
|
for (const pairId of pendingResp.cancelled_pair_ids ?? []) {
|
|
14872
14936
|
log(`[claude-pair] sweeping orphan tmux session for pair ${pairId.slice(0, 8)}`);
|
|
14873
14937
|
const killed = await killPairSession(pairTmuxSession(pairId));
|
|
@@ -15137,7 +15201,7 @@ async function syncMemories(agent, configDir, log2) {
|
|
|
15137
15201
|
if (!file.endsWith(".md")) continue;
|
|
15138
15202
|
try {
|
|
15139
15203
|
const raw = readFileSync20(join24(memoryDir, file), "utf-8");
|
|
15140
|
-
const fileHash =
|
|
15204
|
+
const fileHash = createHash16("sha256").update(raw).digest("hex").slice(0, 16);
|
|
15141
15205
|
currentHashes.set(file, fileHash);
|
|
15142
15206
|
if (prevHashes.get(file) === fileHash) continue;
|
|
15143
15207
|
const parsed = parseMemoryFile(raw, file.replace(/\.md$/, ""));
|
|
@@ -15175,21 +15239,21 @@ async function syncMemories(agent, configDir, log2) {
|
|
|
15175
15239
|
}
|
|
15176
15240
|
async function downloadMemories(agent, memoryDir, log2, { force }) {
|
|
15177
15241
|
const localFiles = existsSync11(memoryDir) ? readdirSync6(memoryDir).filter((f) => f.endsWith(".md")).sort() : [];
|
|
15178
|
-
const localListHash =
|
|
15242
|
+
const localListHash = createHash16("sha256").update(localFiles.join(",")).digest("hex").slice(0, 16);
|
|
15179
15243
|
const prevLocalHash = lastLocalFileHash.get(agent.agent_id);
|
|
15180
15244
|
const prevDownload = lastDownloadHash.get(agent.agent_id);
|
|
15181
15245
|
try {
|
|
15182
15246
|
const dbMemories = await api.post("/host/memories", {
|
|
15183
15247
|
agent_id: agent.agent_id
|
|
15184
15248
|
});
|
|
15185
|
-
const responseHash =
|
|
15249
|
+
const responseHash = createHash16("sha256").update(JSON.stringify(dbMemories.memories ?? [])).digest("hex").slice(0, 16);
|
|
15186
15250
|
if (!force && prevDownload && prevLocalHash === localListHash && lastDownloadHash.get(agent.agent_id) === responseHash) {
|
|
15187
15251
|
return true;
|
|
15188
15252
|
}
|
|
15189
15253
|
lastDownloadHash.set(agent.agent_id, responseHash);
|
|
15190
15254
|
lastLocalFileHash.set(agent.agent_id, localListHash);
|
|
15191
15255
|
if (dbMemories.memories?.length) {
|
|
15192
|
-
|
|
15256
|
+
mkdirSync10(memoryDir, { recursive: true });
|
|
15193
15257
|
let written = 0;
|
|
15194
15258
|
let overwritten = 0;
|
|
15195
15259
|
for (let i = 0; i < dbMemories.memories.length; i++) {
|
|
@@ -15212,16 +15276,16 @@ ${mem.content}
|
|
|
15212
15276
|
} catch {
|
|
15213
15277
|
}
|
|
15214
15278
|
if (existing === desired) continue;
|
|
15215
|
-
|
|
15279
|
+
writeFileSync12(filePath, desired);
|
|
15216
15280
|
overwritten++;
|
|
15217
15281
|
} else {
|
|
15218
|
-
|
|
15282
|
+
writeFileSync12(filePath, desired);
|
|
15219
15283
|
written++;
|
|
15220
15284
|
}
|
|
15221
15285
|
}
|
|
15222
15286
|
if (written > 0 || overwritten > 0) {
|
|
15223
15287
|
const updatedFiles = readdirSync6(memoryDir).filter((f) => f.endsWith(".md")).sort();
|
|
15224
|
-
lastLocalFileHash.set(agent.agent_id,
|
|
15288
|
+
lastLocalFileHash.set(agent.agent_id, createHash16("sha256").update(updatedFiles.join(",")).digest("hex").slice(0, 16));
|
|
15225
15289
|
log2(`Memory download for '${agent.code_name}': wrote ${written} new, overwrote ${overwritten} stale`);
|
|
15226
15290
|
}
|
|
15227
15291
|
}
|
|
@@ -15234,7 +15298,7 @@ ${mem.content}
|
|
|
15234
15298
|
async function cleanupAgentFiles(codeName, agentDir) {
|
|
15235
15299
|
if (existsSync11(agentDir)) {
|
|
15236
15300
|
try {
|
|
15237
|
-
|
|
15301
|
+
rmSync5(agentDir, { recursive: true, force: true });
|
|
15238
15302
|
log(`Removed provision directory for '${codeName}'`);
|
|
15239
15303
|
} catch (err) {
|
|
15240
15304
|
log(`Failed to remove provision dir for '${codeName}': ${err.message}`);
|
|
@@ -15626,8 +15690,8 @@ function restartRunningChannelMcps(basenames) {
|
|
|
15626
15690
|
}
|
|
15627
15691
|
function deployMcpAssets() {
|
|
15628
15692
|
const targetDir = join24(homedir11(), ".augmented", "_mcp");
|
|
15629
|
-
|
|
15630
|
-
const moduleDir =
|
|
15693
|
+
mkdirSync10(targetDir, { recursive: true });
|
|
15694
|
+
const moduleDir = dirname8(fileURLToPath(import.meta.url));
|
|
15631
15695
|
let mcpSourceDir = "";
|
|
15632
15696
|
let dir = moduleDir;
|
|
15633
15697
|
for (let i = 0; i < 6; i++) {
|
|
@@ -15636,7 +15700,7 @@ function deployMcpAssets() {
|
|
|
15636
15700
|
mcpSourceDir = candidate;
|
|
15637
15701
|
break;
|
|
15638
15702
|
}
|
|
15639
|
-
const parent =
|
|
15703
|
+
const parent = dirname8(dir);
|
|
15640
15704
|
if (parent === dir) break;
|
|
15641
15705
|
dir = parent;
|
|
15642
15706
|
}
|
|
@@ -15648,7 +15712,7 @@ function deployMcpAssets() {
|
|
|
15648
15712
|
const fileHash = (p) => {
|
|
15649
15713
|
try {
|
|
15650
15714
|
if (!existsSync11(p)) return null;
|
|
15651
|
-
return
|
|
15715
|
+
return createHash16("sha256").update(readFileSync20(p)).digest("hex");
|
|
15652
15716
|
} catch {
|
|
15653
15717
|
return null;
|
|
15654
15718
|
}
|
|
@@ -15747,7 +15811,7 @@ function deployMcpAssets() {
|
|
|
15747
15811
|
if (!augServer) continue;
|
|
15748
15812
|
augServer.command = "node";
|
|
15749
15813
|
augServer.args = [localMcpPath];
|
|
15750
|
-
|
|
15814
|
+
writeFileSync12(mcpJsonPath, JSON.stringify(mcpConfig, null, 2));
|
|
15751
15815
|
log(`[manager] Patched ${entry.name}/${subdir}/.mcp.json: npx \u2192 node`);
|
|
15752
15816
|
} catch {
|
|
15753
15817
|
}
|