@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.
@@ -42,7 +42,7 @@ import {
42
42
  resolveEffectivePinRaw,
43
43
  safeWriteJsonAtomic,
44
44
  setConfigHash
45
- } from "../chunk-RUVNJO63.js";
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
- } from "../chunk-NUKNLJNJ.js";
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 createHash15 } from "crypto";
165
- import { readFileSync as readFileSync20, writeFileSync as writeFileSync13, mkdirSync as mkdirSync11, existsSync as existsSync11, rmSync as rmSync6, readdirSync as readdirSync6, statSync as statSync5, copyFileSync } from "fs";
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 dirname7, delimiter as pathDelimiter } from "path";
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
- const path = join6(homedir3(), ".augmented", args.codeName, USAGE_LIMIT_MARKER_FILENAME);
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 mkdirSync5, renameSync, rmSync as rmSync3, writeFileSync as writeFileSync5 } from "fs";
2156
- import { homedir as homedir4 } from "os";
2157
- import { join as join7 } from "path";
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 join7(homedir4(), ".augmented", codeName, ACCOUNT_ENFORCEMENT_MARKER_FILENAME);
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 = join7(homedir4(), ".augmented", codeName);
2168
- const path = join7(dir, ACCOUNT_ENFORCEMENT_MARKER_FILENAME);
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
- mkdirSync5(dir, { recursive: true });
2172
- writeFileSync5(tempPath, serializeAccountEnforcementMarker(level), "utf-8");
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
- rmSync3(tempPath, { force: true });
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
- rmSync3(path, { force: true });
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 join8 } from "path";
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 = join8(dir, name);
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 join9 } from "path";
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 = join9(dir, name);
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 = join9(transcriptDir, name);
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(join9(path, "subagents"), minMtimeMs, out, 0);
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 join10 } from "path";
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 = join10(d, ent.name);
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 homedir5 } from "os";
3209
- import { join as join11 } from "path";
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 = join11(homedir5(), ".claude", "stats-cache.json");
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 createHash6 } from "crypto";
3611
+ import { createHash as createHash7 } from "crypto";
3549
3612
  var CHANNEL_WRITE_VERSION = 9;
3550
3613
  function computeChannelConfigHash(input) {
3551
- return createHash6("sha256").update(
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 writeFileSync6 } from "fs";
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
- writeFileSync6(path, JSON.stringify(obj, null, 2));
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 mkdirSync6, readFileSync as readFileSync13, writeFileSync as writeFileSync7 } from "fs";
4142
- import { dirname as dirname4, join as join15 } from "path";
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
- mkdirSync6(dirname4(path), { recursive: true });
4222
+ mkdirSync5(dirname5(path), { recursive: true });
4160
4223
  const body = {
4161
4224
  version: MANIFEST_VERSION,
4162
4225
  globalSkillIds: [...ids].sort()
4163
4226
  };
4164
- writeFileSync7(path, JSON.stringify(body, null, 2));
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 platform2 = modelDefaults?.platform ?? {};
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 = platform2?.[platformField];
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 rmSync4 } from "fs";
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
- rmSync4(p, { force: true });
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 writeFileSync8 } from "fs";
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
- writeFileSync8(path, JSON.stringify({ version: KANBAN_NUDGE_STATE_VERSION, agents }, null, 2));
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 createHash7 } from "crypto";
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 = createHash7("sha256").update(errText).digest("hex").slice(0, 12);
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 = createHash7("sha256").update(errText).digest("hex").slice(0, 12);
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 createHash8 } from "crypto";
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 = createHash8("sha256").update(errText).digest("hex").slice(0, 12);
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 = createHash8("sha256").update(errText).digest("hex").slice(0, 12);
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 = createHash8("sha256").update(errText).digest("hex").slice(0, 12);
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 createHash10 } from "crypto";
5157
- import { writeFileSync as writeFileSync9, renameSync as renameSync2, mkdirSync as mkdirSync7, readFileSync as readFileSync16, unlinkSync } from "fs";
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 dirname5 } from "path";
5222
+ import { join as join19, dirname as dirname6 } from "path";
5160
5223
 
5161
5224
  // src/lib/manager/scheduler/notify.ts
5162
- import { createHash as createHash9 } from "crypto";
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 = createHash9("sha256").update(errText).digest("hex").slice(0, 12);
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
- writeFileSync9(tmp, JSON.stringify(marker), "utf8");
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
- mkdirSync7(dirname5(doorbell), { recursive: true });
5567
- writeFileSync9(doorbell, String(Date.now()));
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" : createHash10("sha256").update(trimmed).digest("hex").slice(0, 12);
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 = createHash10("sha256").update(assertion.reason ?? "").digest("hex").slice(0, 12);
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" : createHash10("sha256").update(trimmed).digest("hex").slice(0, 12);
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 = createHash10("sha256").update(classification.suppressedNotes).digest("hex").slice(0, 12);
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 createHash11 } from "crypto";
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 = createHash11("sha256").update(JSON.stringify(tasks)).digest("hex").slice(0, 16);
5741
- const boardHash = boardItems.length > 0 ? createHash11("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";
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 = createHash11("sha256").update(JSON.stringify(resolvedModels)).digest("hex").slice(0, 16);
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 createHash12 } from "crypto";
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 createHash12("sha256").update(
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 createHash13 } from "crypto";
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 = createHash13("sha256").update(JSON.stringify(tasks)).digest("hex").slice(0, 16);
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 createHash14 } from "crypto";
6944
- import { existsSync as existsSync9, mkdirSync as mkdirSync8, readFileSync as readFileSync17, renameSync as renameSync3, unlinkSync as unlinkSync2, writeFileSync as writeFileSync10 } from "fs";
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 createHash14("sha256").update(
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
- mkdirSync8(dir, { recursive: true, mode: 448 });
7522
- writeFileSync10(
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 mkdirSync9, readdirSync as readdirSync4, readFileSync as readFileSync18, renameSync as renameSync4, rmSync as rmSync5, writeFileSync as writeFileSync11 } from "fs";
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
- rmSync5(path, { force: true });
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 writeFileSync12, mkdirSync as mkdirSync10, unlinkSync as unlinkSync3 } from "fs";
7889
- import { dirname as dirname6, join as join23 } from "path";
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 dirname6(getProjectDir(codeName));
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
- mkdirSync10(dir, { recursive: true, mode: 448 });
7956
- writeFileSync12(path, JSON.stringify(hint), { mode: 384 });
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 createHash15("sha256").update(canonicalJson(JSON.parse(raw))).digest("hex");
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.433" : "dev";
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 = dirname7(brewPath);
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
- mkdirSync11(dirname7(path), { recursive: true });
9913
- writeFileSync13(path, `${JSON.stringify(settings, null, 2)}
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 = dirname7(brewPath);
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
- mkdirSync11(dir, { recursive: true });
10521
+ mkdirSync10(dir, { recursive: true });
10459
10522
  } catch {
10460
10523
  }
10461
10524
  const p = join24(dir, ".eval-empty-mcp.json");
10462
- writeFileSync13(p, JSON.stringify({ mcpServers: {} }));
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: writeFileSync14 } = await import("fs");
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
- writeFileSync14(claudeMdPath, next, "utf-8");
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-ISBR3BBX.js");
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-ISBR3BBX.js");
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 = createHash15("sha256").update(errText).digest("hex").slice(0, 12);
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-OT6JVP43.js");
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-OT6JVP43.js");
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
- mkdirSync11(agentDir, { recursive: true });
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
- mkdirSync11(dirname7(filePath), { recursive: true });
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
- writeFileSync13(filePath, file.content);
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
- rmSync6(join24(provSkillsDir, folder), { recursive: true });
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
- rmSync6(join24(provWorkflowsDir, file));
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
- mkdirSync11(agentAugmentedDir, { recursive: true });
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 = createHash15("sha256").update(canonicalJson(behaviourSubset)).digest("hex");
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 = createHash15("sha256").update(canonicalJson(slackBehaviourSubset)).digest("hex");
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
- mkdirSync11(agentProvisionDir, { recursive: true });
12474
- mkdirSync11(projectDir, { recursive: true });
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
- rmSync6(staleChannelsPath, { force: true });
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 = createHash15("sha256").update(canonicalJson(e.headers ?? {})).digest("hex").slice(0, 16);
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 = createHash15("sha256").update(hashBasis).digest("hex").slice(0, 16);
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 = createHash15("sha256").update(e.url).digest("hex").slice(0, 12);
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: createHash16 } = await import("crypto");
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 = createHash16("sha256").update(bundleFingerprint(bundle.files)).digest("hex").slice(0, 12);
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: rmSync7 } = await import("fs");
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
- rmSync7(p, { recursive: true, force: true });
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) => createHash16("sha256").update(content).digest("hex").slice(0, 12),
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
- rmSync6(p, { recursive: true, force: true });
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 = createHash16("sha256").update(hook.script).digest("hex").slice(0, 12);
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 = createHash16("sha256").update(result.stderr).digest("hex").slice(0, 12);
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 ? createHash16("sha256").update(missingCmd).digest("hex").slice(0, 8) : null;
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 currentAuthTuple = openRouterForAgent ? `openrouter:${openRouterForAgent.fingerprint ?? openRouterForAgent.model}` : `${claudeAuthMode}:${anthropicApiKeyFingerprint ?? "none"}`;
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:${createHash15("sha256").update(ctx.tail).digest("hex").slice(0, 12)} (raw at ~/.augmented/${codeName}/pane.log)`;
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:${createHash15("sha256").update(zombie.paneTail).digest("hex").slice(0, 12)}` : null;
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 = createHash15("sha256").update(JSON.stringify(tasks)).digest("hex").slice(0, 16);
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-ISBR3BBX.js");
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-ISBR3BBX.js");
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
- mkdirSync11(dirname7(doorbell), { recursive: true });
14704
- writeFileSync13(doorbell, String(Date.now()));
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
- mkdirSync11(dirname7(doorbell), { recursive: true });
14814
- writeFileSync13(doorbell, String(Date.now()));
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-YAHBPFYL.js");
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 = createHash15("sha256").update(raw).digest("hex").slice(0, 16);
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 = createHash15("sha256").update(localFiles.join(",")).digest("hex").slice(0, 16);
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 = createHash15("sha256").update(JSON.stringify(dbMemories.memories ?? [])).digest("hex").slice(0, 16);
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
- mkdirSync11(memoryDir, { recursive: true });
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
- writeFileSync13(filePath, desired);
15279
+ writeFileSync12(filePath, desired);
15216
15280
  overwritten++;
15217
15281
  } else {
15218
- writeFileSync13(filePath, desired);
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, createHash15("sha256").update(updatedFiles.join(",")).digest("hex").slice(0, 16));
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
- rmSync6(agentDir, { recursive: true, force: true });
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
- mkdirSync11(targetDir, { recursive: true });
15630
- const moduleDir = dirname7(fileURLToPath(import.meta.url));
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 = dirname7(dir);
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 createHash15("sha256").update(readFileSync20(p)).digest("hex");
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
- writeFileSync13(mcpJsonPath, JSON.stringify(mcpConfig, null, 2));
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
  }