@integrity-labs/agt-cli 0.28.714 → 0.28.716
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 +619 -66
- package/dist/bin/agt.js.map +1 -1
- package/dist/{chunk-F6AZ6KPI.js → chunk-ILDRNSOB.js} +8 -5
- package/dist/chunk-ILDRNSOB.js.map +1 -0
- package/dist/{chunk-FM63TWR3.js → chunk-LHYYO4NY.js} +1 -1
- package/dist/{chunk-FBYIO3Z6.js → chunk-OOYUWMTR.js} +367 -63
- package/dist/chunk-OOYUWMTR.js.map +1 -0
- package/dist/{claude-pair-runtime-WW55WS2Q.js → claude-pair-runtime-JK7GQU25.js} +2 -2
- package/dist/lib/manager-worker.js +420 -700
- package/dist/lib/manager-worker.js.map +1 -1
- package/dist/{persistent-session-XLYRD2CU.js → persistent-session-DJSSEIR6.js} +5 -3
- package/dist/{responsiveness-probe-QDNULLSM.js → responsiveness-probe-A5335ORT.js} +3 -3
- package/dist/{session-auth-dead-OAOR7OS4.js → session-auth-dead-KUYVUOK5.js} +2 -2
- package/package.json +1 -1
- package/dist/chunk-F6AZ6KPI.js.map +0 -1
- package/dist/chunk-FBYIO3Z6.js.map +0 -1
- /package/dist/{chunk-FM63TWR3.js.map → chunk-LHYYO4NY.js.map} +0 -0
- /package/dist/{claude-pair-runtime-WW55WS2Q.js.map → claude-pair-runtime-JK7GQU25.js.map} +0 -0
- /package/dist/{persistent-session-XLYRD2CU.js.map → persistent-session-DJSSEIR6.js.map} +0 -0
- /package/dist/{responsiveness-probe-QDNULLSM.js.map → responsiveness-probe-A5335ORT.js.map} +0 -0
- /package/dist/{session-auth-dead-OAOR7OS4.js.map → session-auth-dead-KUYVUOK5.js.map} +0 -0
|
@@ -16,12 +16,14 @@ import {
|
|
|
16
16
|
deriveMcpServerKey,
|
|
17
17
|
describeStartupCompletion,
|
|
18
18
|
diffEnvIntegrations,
|
|
19
|
+
drainTranscriptFlushDeps,
|
|
19
20
|
envOnlyRespawnVars,
|
|
20
21
|
exchangeApiKey,
|
|
21
22
|
exchangeFailureKind,
|
|
22
23
|
executeConnectivityProbe,
|
|
23
24
|
extractCommandNotFound,
|
|
24
25
|
findMcpServersUsingVars,
|
|
26
|
+
flushAgentTranscriptsOnDrain,
|
|
25
27
|
gatherSessionToolBindProbe,
|
|
26
28
|
getApiKey,
|
|
27
29
|
getCachedClaudeAuthMode,
|
|
@@ -45,6 +47,7 @@ import {
|
|
|
45
47
|
provisionSessionStateHook,
|
|
46
48
|
provisionStopHook,
|
|
47
49
|
readEnvNumber,
|
|
50
|
+
readHostArchiveAddress,
|
|
48
51
|
reapMissingMcpSessions,
|
|
49
52
|
reapStaleMcpChildren,
|
|
50
53
|
reaperRestartBreakerReason,
|
|
@@ -54,7 +57,7 @@ import {
|
|
|
54
57
|
safeWriteJsonAtomic,
|
|
55
58
|
setConfigHash,
|
|
56
59
|
tripClass
|
|
57
|
-
} from "../chunk-
|
|
60
|
+
} from "../chunk-OOYUWMTR.js";
|
|
58
61
|
import {
|
|
59
62
|
getProjectDir as getProjectDir2,
|
|
60
63
|
getReadyTasks,
|
|
@@ -112,7 +115,7 @@ import {
|
|
|
112
115
|
takeZombieDetection,
|
|
113
116
|
toOpencodeModel,
|
|
114
117
|
writeEgressAllowlist
|
|
115
|
-
} from "../chunk-
|
|
118
|
+
} from "../chunk-ILDRNSOB.js";
|
|
116
119
|
import {
|
|
117
120
|
ACCOUNT_ENFORCEMENT_MARKER_FILENAME,
|
|
118
121
|
AnchorSessionClient,
|
|
@@ -186,7 +189,6 @@ import {
|
|
|
186
189
|
parseUsageReport,
|
|
187
190
|
peekCurrentSession,
|
|
188
191
|
pickNewerClassification,
|
|
189
|
-
readDailySessionPin,
|
|
190
192
|
remoteMcpServerKey,
|
|
191
193
|
resolveAgentTimezone,
|
|
192
194
|
resolveAvatarEnvUrl,
|
|
@@ -198,14 +200,14 @@ import {
|
|
|
198
200
|
subagentActivityAgeSeconds,
|
|
199
201
|
sumTranscriptUsageInWindow,
|
|
200
202
|
transcriptActivityAgeSeconds
|
|
201
|
-
} from "../chunk-
|
|
203
|
+
} from "../chunk-LHYYO4NY.js";
|
|
202
204
|
import {
|
|
203
205
|
reapOrphanChannelMcps
|
|
204
206
|
} from "../chunk-XWVM4KPK.js";
|
|
205
207
|
|
|
206
208
|
// src/lib/manager-worker.ts
|
|
207
209
|
import { createHash as createHash17 } from "crypto";
|
|
208
|
-
import { readFileSync as
|
|
210
|
+
import { readFileSync as readFileSync29, writeFileSync as writeFileSync15, mkdirSync as mkdirSync11, existsSync as existsSync16, rmSync as rmSync5, readdirSync as readdirSync9, statSync as statSync8, unlinkSync as unlinkSync6, renameSync as renameSync8, utimesSync } from "fs";
|
|
209
211
|
|
|
210
212
|
// src/lib/atomic-file-replace.ts
|
|
211
213
|
import { copyFileSync, renameSync, unlinkSync } from "fs";
|
|
@@ -231,8 +233,8 @@ function defaultUnique() {
|
|
|
231
233
|
|
|
232
234
|
// src/lib/manager-worker.ts
|
|
233
235
|
import { execFileSync as syncExecFile } from "child_process";
|
|
234
|
-
import { join as
|
|
235
|
-
import { homedir as
|
|
236
|
+
import { join as join38, dirname as dirname10, delimiter as pathDelimiter } from "path";
|
|
237
|
+
import { homedir as homedir17 } from "os";
|
|
236
238
|
import { fileURLToPath } from "url";
|
|
237
239
|
|
|
238
240
|
// src/lib/single-flight.ts
|
|
@@ -299,288 +301,6 @@ function claudeCodeUpgradeThrottled() {
|
|
|
299
301
|
}
|
|
300
302
|
}
|
|
301
303
|
|
|
302
|
-
// src/lib/drain-transcript-flush.ts
|
|
303
|
-
import { existsSync, readdirSync } from "fs";
|
|
304
|
-
import { homedir as homedir2 } from "os";
|
|
305
|
-
import { dirname as dirname3, join as join3, relative, sep } from "path";
|
|
306
|
-
import { spawn } from "child_process";
|
|
307
|
-
|
|
308
|
-
// src/lib/host-archive-address.ts
|
|
309
|
-
import { readFileSync as readFileSync2 } from "fs";
|
|
310
|
-
var DEFAULT_ARCHIVE_ADDRESS_PATH = "/var/lib/augmented/session-archive-address.json";
|
|
311
|
-
var CACHE_TTL_MS = 5 * 60 * 1e3;
|
|
312
|
-
var cache = /* @__PURE__ */ new Map();
|
|
313
|
-
function str(value) {
|
|
314
|
-
if (typeof value !== "string") return null;
|
|
315
|
-
const trimmed = value.trim();
|
|
316
|
-
return trimmed.length > 0 ? trimmed : null;
|
|
317
|
-
}
|
|
318
|
-
function readHostArchiveAddress(path) {
|
|
319
|
-
const file = path ?? process.env["ARCHIVE_ADDRESS_FILE"]?.trim() ?? process.env["AGT_SESSION_ARCHIVE_ADDRESS_FILE"]?.trim() ?? DEFAULT_ARCHIVE_ADDRESS_PATH;
|
|
320
|
-
const now = Date.now();
|
|
321
|
-
const hit = cache.get(file);
|
|
322
|
-
if (hit && now - hit.at < CACHE_TTL_MS) return hit.value;
|
|
323
|
-
let value = null;
|
|
324
|
-
try {
|
|
325
|
-
const raw = readFileSync2(file, "utf-8");
|
|
326
|
-
const parsed = JSON.parse(raw);
|
|
327
|
-
if (parsed && typeof parsed === "object" && !Array.isArray(parsed)) {
|
|
328
|
-
const obj = parsed;
|
|
329
|
-
const bucket = str(obj["bucket"]);
|
|
330
|
-
const keyPrefix = str(obj["key_prefix"]);
|
|
331
|
-
if (bucket && keyPrefix) {
|
|
332
|
-
value = {
|
|
333
|
-
bucket,
|
|
334
|
-
region: str(obj["region"]),
|
|
335
|
-
instanceId: str(obj["instance_id"]),
|
|
336
|
-
keyPrefix
|
|
337
|
-
};
|
|
338
|
-
}
|
|
339
|
-
}
|
|
340
|
-
} catch {
|
|
341
|
-
value = null;
|
|
342
|
-
}
|
|
343
|
-
cache.set(file, { at: now, value });
|
|
344
|
-
return value;
|
|
345
|
-
}
|
|
346
|
-
|
|
347
|
-
// src/lib/drain-transcript-flush.ts
|
|
348
|
-
function sessionsBaseDir() {
|
|
349
|
-
return join3(homedir2(), ".claude", "projects");
|
|
350
|
-
}
|
|
351
|
-
var PER_FILE_UPLOAD_TIMEOUT_MS = 3e4;
|
|
352
|
-
var UPLOAD_CONCURRENCY = 4;
|
|
353
|
-
var DRAIN_MANIFEST_VERSION = 1;
|
|
354
|
-
var DRAIN_MANIFEST_FILENAME = "_augmented-drain-manifest.json";
|
|
355
|
-
function listJsonlFiles(dir) {
|
|
356
|
-
if (!existsSync(dir)) return [];
|
|
357
|
-
const out = [];
|
|
358
|
-
const walk = (d) => {
|
|
359
|
-
for (const entry of readdirSync(d, { withFileTypes: true })) {
|
|
360
|
-
const full = join3(d, entry.name);
|
|
361
|
-
if (entry.isDirectory()) walk(full);
|
|
362
|
-
else if (entry.isFile() && entry.name.endsWith(".jsonl")) out.push(full);
|
|
363
|
-
}
|
|
364
|
-
};
|
|
365
|
-
try {
|
|
366
|
-
walk(dir);
|
|
367
|
-
} catch {
|
|
368
|
-
}
|
|
369
|
-
return out;
|
|
370
|
-
}
|
|
371
|
-
function transcriptObjectKey(keyPrefix, baseDir, file) {
|
|
372
|
-
const rel = relative(baseDir, file).split(sep).join("/");
|
|
373
|
-
if (!rel || rel.startsWith("../") || rel === "..") return null;
|
|
374
|
-
return `${keyPrefix.replace(/\/+$/, "")}/${rel}`;
|
|
375
|
-
}
|
|
376
|
-
function drainManifestObjectKey(keyPrefix, baseDir, transcriptDir) {
|
|
377
|
-
return transcriptObjectKey(keyPrefix, baseDir, join3(transcriptDir, DRAIN_MANIFEST_FILENAME));
|
|
378
|
-
}
|
|
379
|
-
async function flushAgentTranscriptsOnDrain(codeName, deps) {
|
|
380
|
-
const dir = deps.resolveTranscriptDir(codeName);
|
|
381
|
-
const files = deps.listTranscripts(dir);
|
|
382
|
-
if (files.length === 0) {
|
|
383
|
-
return {
|
|
384
|
-
status: "no-transcripts",
|
|
385
|
-
uploaded: 0,
|
|
386
|
-
failed: 0,
|
|
387
|
-
total: 0,
|
|
388
|
-
manifest: "skipped",
|
|
389
|
-
manifestKey: null
|
|
390
|
-
};
|
|
391
|
-
}
|
|
392
|
-
const address = deps.readAddress();
|
|
393
|
-
if (!address || !address.bucket || !address.keyPrefix) {
|
|
394
|
-
deps.log(
|
|
395
|
-
`[drain-flush] NO S3 ADDRESS for '${codeName}' \u2014 ${files.length} transcript file(s) will NOT be shipped before teardown; this session may be lost (ENG-9491). The host archive address is unresolved (agt-session-archiver has published none).`
|
|
396
|
-
);
|
|
397
|
-
return {
|
|
398
|
-
status: "no-address",
|
|
399
|
-
uploaded: 0,
|
|
400
|
-
failed: files.length,
|
|
401
|
-
total: files.length,
|
|
402
|
-
manifest: "skipped",
|
|
403
|
-
manifestKey: null
|
|
404
|
-
};
|
|
405
|
-
}
|
|
406
|
-
const { bucket, keyPrefix, region } = address;
|
|
407
|
-
let uploaded = 0;
|
|
408
|
-
let failed = 0;
|
|
409
|
-
const keys = [];
|
|
410
|
-
const missing = [];
|
|
411
|
-
let cursor = 0;
|
|
412
|
-
const worker = async () => {
|
|
413
|
-
for (; ; ) {
|
|
414
|
-
const i = cursor;
|
|
415
|
-
cursor += 1;
|
|
416
|
-
if (i >= files.length) return;
|
|
417
|
-
const file = files[i];
|
|
418
|
-
const key = transcriptObjectKey(keyPrefix, deps.baseDir, file);
|
|
419
|
-
if (!key) {
|
|
420
|
-
failed += 1;
|
|
421
|
-
missing.push(file);
|
|
422
|
-
deps.log(
|
|
423
|
-
`[drain-flush] SKIP '${file}' for '${codeName}' \u2014 outside sessions base dir '${deps.baseDir}', cannot key it (ENG-9491)`
|
|
424
|
-
);
|
|
425
|
-
continue;
|
|
426
|
-
}
|
|
427
|
-
const res = await deps.uploadFile({ file, bucket, key, region });
|
|
428
|
-
if (res.ok) {
|
|
429
|
-
uploaded += 1;
|
|
430
|
-
keys.push(key);
|
|
431
|
-
} else {
|
|
432
|
-
failed += 1;
|
|
433
|
-
missing.push(file);
|
|
434
|
-
deps.log(
|
|
435
|
-
`[drain-flush] UPLOAD FAILED for '${codeName}' '${file}' \u2192 s3://${bucket}/${key}: ${res.detail} (ENG-9491)`
|
|
436
|
-
);
|
|
437
|
-
}
|
|
438
|
-
}
|
|
439
|
-
};
|
|
440
|
-
await Promise.all(
|
|
441
|
-
Array.from({ length: Math.min(UPLOAD_CONCURRENCY, files.length) }, () => worker())
|
|
442
|
-
);
|
|
443
|
-
const uploadStatus = failed === 0 ? "flushed" : uploaded === 0 ? "failed" : "partial";
|
|
444
|
-
if (uploadStatus !== "flushed") {
|
|
445
|
-
deps.log(
|
|
446
|
-
`[drain-flush] INCOMPLETE for '${codeName}': ${uploaded}/${files.length} transcript file(s) shipped, ${failed} FAILED before teardown \u2014 session data may be lost (ENG-9491).`
|
|
447
|
-
);
|
|
448
|
-
}
|
|
449
|
-
const { manifest, manifestKey } = await writeDrainManifest(codeName, deps, {
|
|
450
|
-
bucket,
|
|
451
|
-
keyPrefix,
|
|
452
|
-
region,
|
|
453
|
-
transcriptDir: dir,
|
|
454
|
-
keys,
|
|
455
|
-
missing,
|
|
456
|
-
complete: failed === 0
|
|
457
|
-
});
|
|
458
|
-
const status = uploadStatus === "flushed" && manifest !== "written" ? "no-manifest" : uploadStatus;
|
|
459
|
-
return { status, uploaded, failed, total: files.length, manifest, manifestKey };
|
|
460
|
-
}
|
|
461
|
-
async function writeDrainManifest(codeName, deps, ctx) {
|
|
462
|
-
const manifestKey = drainManifestObjectKey(ctx.keyPrefix, deps.baseDir, ctx.transcriptDir);
|
|
463
|
-
if (!manifestKey) {
|
|
464
|
-
deps.log(
|
|
465
|
-
`[drain-flush] NO MANIFEST for '${codeName}' \u2014 transcript dir '${ctx.transcriptDir}' is outside sessions base dir '${deps.baseDir}', so no manifest key could be computed. Any shipped object is UNRESTORABLE: nothing records the session pin or the source layout (ENG-9566).`
|
|
466
|
-
);
|
|
467
|
-
return { manifest: "unkeyable", manifestKey: null };
|
|
468
|
-
}
|
|
469
|
-
let layout = null;
|
|
470
|
-
try {
|
|
471
|
-
layout = deps.readSourceLayout(codeName);
|
|
472
|
-
} catch (err) {
|
|
473
|
-
deps.log(
|
|
474
|
-
`[drain-flush] could not resolve source layout for '${codeName}': ${err.message} \u2014 manifest will record it as unknown (ENG-9566)`
|
|
475
|
-
);
|
|
476
|
-
}
|
|
477
|
-
let sessionPin = null;
|
|
478
|
-
try {
|
|
479
|
-
sessionPin = deps.readSessionPin(codeName);
|
|
480
|
-
} catch (err) {
|
|
481
|
-
deps.log(
|
|
482
|
-
`[drain-flush] could not read the session pin for '${codeName}': ${err.message} \u2014 a restore will not be able to identify the live conversation (ENG-9566)`
|
|
483
|
-
);
|
|
484
|
-
}
|
|
485
|
-
const manifestBody = {
|
|
486
|
-
version: DRAIN_MANIFEST_VERSION,
|
|
487
|
-
codeName,
|
|
488
|
-
writtenAt: deps.now().toISOString(),
|
|
489
|
-
sourceLayout: layout?.layout ?? null,
|
|
490
|
-
sourceAgentDir: layout?.agentDir ?? null,
|
|
491
|
-
sourceTranscriptDir: ctx.transcriptDir,
|
|
492
|
-
sourceBaseDir: deps.baseDir,
|
|
493
|
-
bucket: ctx.bucket,
|
|
494
|
-
keyPrefix: ctx.keyPrefix,
|
|
495
|
-
keys: ctx.keys,
|
|
496
|
-
missing: ctx.missing,
|
|
497
|
-
complete: ctx.complete,
|
|
498
|
-
sessionPin
|
|
499
|
-
};
|
|
500
|
-
const res = await deps.uploadManifest({
|
|
501
|
-
body: `${JSON.stringify(manifestBody, null, 2)}
|
|
502
|
-
`,
|
|
503
|
-
bucket: ctx.bucket,
|
|
504
|
-
key: manifestKey,
|
|
505
|
-
region: ctx.region
|
|
506
|
-
});
|
|
507
|
-
if (!res.ok) {
|
|
508
|
-
deps.log(
|
|
509
|
-
`[drain-flush] MANIFEST UPLOAD FAILED for '${codeName}' \u2192 s3://${ctx.bucket}/${manifestKey}: ${res.detail}. ${ctx.keys.length} shipped object(s) are UNRESTORABLE without it (ENG-9566).`
|
|
510
|
-
);
|
|
511
|
-
return { manifest: "failed", manifestKey: null };
|
|
512
|
-
}
|
|
513
|
-
return { manifest: "written", manifestKey };
|
|
514
|
-
}
|
|
515
|
-
function drainTranscriptFlushDeps(log2) {
|
|
516
|
-
return {
|
|
517
|
-
resolveTranscriptDir: (codeName) => sessionTranscriptDir(getProjectDir(codeName)),
|
|
518
|
-
readAddress: () => readHostArchiveAddress(),
|
|
519
|
-
listTranscripts: listJsonlFiles,
|
|
520
|
-
baseDir: sessionsBaseDir(),
|
|
521
|
-
now: () => /* @__PURE__ */ new Date(),
|
|
522
|
-
// ENG-9566: derive the layout from the seam's OUTPUT rather than re-running
|
|
523
|
-
// its lstat. getProjectDir already resolved the codename symlink (or didn't);
|
|
524
|
-
// if what came back is not under the codename dir, this host is id-keyed.
|
|
525
|
-
// Observing the resolver keeps a second copy of ADR-0049's rule out of the
|
|
526
|
-
// tree — the thing host-archive-address.ts's header warns about.
|
|
527
|
-
readSourceLayout: (codeName) => {
|
|
528
|
-
const agentDir = dirname3(getProjectDir(codeName));
|
|
529
|
-
const codeNameDir = join3(homedir2(), ".augmented", codeName);
|
|
530
|
-
return { layout: agentDir === codeNameDir ? "codename-keyed" : "id-keyed", agentDir };
|
|
531
|
-
},
|
|
532
|
-
readSessionPin: (codeName) => readDailySessionPin(codeName),
|
|
533
|
-
uploadFile: ({ file, bucket, key, region }) => runAwsCp(awsCpArgs(file, bucket, key, region), null),
|
|
534
|
-
uploadManifest: ({ body, bucket, key, region }) => (
|
|
535
|
-
// `-` is `aws s3 cp`'s stdin source, so the manifest never touches disk.
|
|
536
|
-
runAwsCp(
|
|
537
|
-
[...awsCpArgs("-", bucket, key, region), "--content-type", "application/json"],
|
|
538
|
-
body
|
|
539
|
-
)
|
|
540
|
-
),
|
|
541
|
-
log: log2
|
|
542
|
-
};
|
|
543
|
-
}
|
|
544
|
-
function awsCpArgs(source, bucket, key, region) {
|
|
545
|
-
const args = ["s3", "cp", source, `s3://${bucket}/${key}`, "--only-show-errors"];
|
|
546
|
-
if (region) args.push("--region", region);
|
|
547
|
-
return args;
|
|
548
|
-
}
|
|
549
|
-
function runAwsCp(args, body) {
|
|
550
|
-
return new Promise((resolve2) => {
|
|
551
|
-
const child = spawn("aws", args, {
|
|
552
|
-
stdio: [body === null ? "ignore" : "pipe", "ignore", "pipe"]
|
|
553
|
-
});
|
|
554
|
-
let stderr = "";
|
|
555
|
-
let settled = false;
|
|
556
|
-
const finish = (r) => {
|
|
557
|
-
if (settled) return;
|
|
558
|
-
settled = true;
|
|
559
|
-
clearTimeout(timer3);
|
|
560
|
-
resolve2(r);
|
|
561
|
-
};
|
|
562
|
-
const timer3 = setTimeout(() => {
|
|
563
|
-
child.kill("SIGKILL");
|
|
564
|
-
finish({ ok: false, detail: `aws s3 cp timed out after ${PER_FILE_UPLOAD_TIMEOUT_MS}ms` });
|
|
565
|
-
}, PER_FILE_UPLOAD_TIMEOUT_MS);
|
|
566
|
-
child.stderr?.on("data", (d) => {
|
|
567
|
-
stderr += String(d);
|
|
568
|
-
});
|
|
569
|
-
child.on("error", (err) => finish({ ok: false, detail: err.message }));
|
|
570
|
-
child.on(
|
|
571
|
-
"close",
|
|
572
|
-
(code) => finish(
|
|
573
|
-
code === 0 ? { ok: true, detail: "" } : { ok: false, detail: stderr.trim().slice(0, 500) || `aws exited with code ${code ?? "null"}` }
|
|
574
|
-
)
|
|
575
|
-
);
|
|
576
|
-
if (body !== null) {
|
|
577
|
-
child.stdin?.on("error", () => {
|
|
578
|
-
});
|
|
579
|
-
child.stdin?.end(body);
|
|
580
|
-
}
|
|
581
|
-
});
|
|
582
|
-
}
|
|
583
|
-
|
|
584
304
|
// src/lib/mcp-config-drift.ts
|
|
585
305
|
import { createHash } from "crypto";
|
|
586
306
|
function decideMcpDriftAction(currentHash, knownHash) {
|
|
@@ -1007,8 +727,8 @@ function isSlackBehaviourRestrictive(subset) {
|
|
|
1007
727
|
}
|
|
1008
728
|
|
|
1009
729
|
// src/lib/onboarding-drive.ts
|
|
1010
|
-
import { mkdirSync as mkdirSync2, readFileSync as
|
|
1011
|
-
import { dirname as
|
|
730
|
+
import { mkdirSync as mkdirSync2, readFileSync as readFileSync2, rmSync, writeFileSync as writeFileSync2 } from "fs";
|
|
731
|
+
import { dirname as dirname3 } from "path";
|
|
1012
732
|
var ONBOARDING_REINJECT_INTERVAL_MS = 45 * 6e4;
|
|
1013
733
|
var ONBOARDING_MAX_NUDGES = 3;
|
|
1014
734
|
var ONBOARDING_MIN_STANDDOWN_AGE_MS = 60 * 6e4;
|
|
@@ -1134,7 +854,7 @@ function onboardingNudgeReachedSession(result) {
|
|
|
1134
854
|
}
|
|
1135
855
|
function readOnboardingDriveMarker(path) {
|
|
1136
856
|
try {
|
|
1137
|
-
const raw = JSON.parse(
|
|
857
|
+
const raw = JSON.parse(readFileSync2(path, "utf8"));
|
|
1138
858
|
if (typeof raw.step === "string" && isOnboardingArea(raw.step) && typeof raw.injectedAtMs === "number" && Number.isFinite(raw.injectedAtMs)) {
|
|
1139
859
|
const legacyInjects = typeof raw.nudgeCount === "number" && Number.isFinite(raw.nudgeCount) && raw.nudgeCount >= 1 ? Math.floor(raw.nudgeCount) : 1;
|
|
1140
860
|
const hasNewCounters = typeof raw.injectCount === "number" && Number.isFinite(raw.injectCount) && raw.injectCount >= 1;
|
|
@@ -1159,7 +879,7 @@ function readOnboardingDriveMarker(path) {
|
|
|
1159
879
|
return null;
|
|
1160
880
|
}
|
|
1161
881
|
function writeOnboardingDriveMarker(path, marker) {
|
|
1162
|
-
mkdirSync2(
|
|
882
|
+
mkdirSync2(dirname3(path), { recursive: true });
|
|
1163
883
|
writeFileSync2(path, JSON.stringify(marker) + "\n", "utf8");
|
|
1164
884
|
}
|
|
1165
885
|
function clearOnboardingDriveMarker(path) {
|
|
@@ -1170,8 +890,8 @@ function clearOnboardingDriveMarker(path) {
|
|
|
1170
890
|
}
|
|
1171
891
|
|
|
1172
892
|
// src/lib/channel-quarantine.ts
|
|
1173
|
-
import { readFileSync as
|
|
1174
|
-
import { join as
|
|
893
|
+
import { readFileSync as readFileSync3 } from "fs";
|
|
894
|
+
import { join as join3 } from "path";
|
|
1175
895
|
var ESSENTIAL_CHANNEL_KEYS = /* @__PURE__ */ new Set(["direct-chat", "augmented"]);
|
|
1176
896
|
var OPTIONAL_CHANNEL_KEYS = /* @__PURE__ */ new Set([
|
|
1177
897
|
"telegram",
|
|
@@ -1203,7 +923,7 @@ function classifyChannelCriticality(serverKey, entry) {
|
|
|
1203
923
|
return "essential";
|
|
1204
924
|
}
|
|
1205
925
|
function defaultQuarantinePath(configDir) {
|
|
1206
|
-
return
|
|
926
|
+
return join3(configDir, "channel-quarantine.json");
|
|
1207
927
|
}
|
|
1208
928
|
var ChannelQuarantineStore = class {
|
|
1209
929
|
path;
|
|
@@ -1214,7 +934,7 @@ var ChannelQuarantineStore = class {
|
|
|
1214
934
|
load() {
|
|
1215
935
|
if (this.cache) return this.cache;
|
|
1216
936
|
try {
|
|
1217
|
-
const raw =
|
|
937
|
+
const raw = readFileSync3(this.path, "utf-8");
|
|
1218
938
|
const parsed = JSON.parse(raw);
|
|
1219
939
|
this.cache = isQuarantineFile(parsed) ? parsed : {};
|
|
1220
940
|
} catch {
|
|
@@ -1302,13 +1022,13 @@ function isQuarantineFile(value) {
|
|
|
1302
1022
|
}
|
|
1303
1023
|
|
|
1304
1024
|
// src/lib/claude-md-size.ts
|
|
1305
|
-
import { readFileSync as
|
|
1306
|
-
import { join as
|
|
1025
|
+
import { readFileSync as readFileSync4 } from "fs";
|
|
1026
|
+
import { join as join4 } from "path";
|
|
1307
1027
|
function measureClaudeMd(configDir, codeName, ceiling = CLAUDE_MD_CONTEXT_ALARM_CHARS) {
|
|
1308
1028
|
let chars;
|
|
1309
1029
|
let bytes;
|
|
1310
1030
|
try {
|
|
1311
|
-
const buf =
|
|
1031
|
+
const buf = readFileSync4(join4(configDir, codeName, "project", "CLAUDE.md"));
|
|
1312
1032
|
chars = buf.toString("utf8").length;
|
|
1313
1033
|
bytes = buf.length;
|
|
1314
1034
|
} catch {
|
|
@@ -1328,8 +1048,8 @@ function measureClaudeMd(configDir, codeName, ceiling = CLAUDE_MD_CONTEXT_ALARM_
|
|
|
1328
1048
|
function measureCoreKnowledgeDescription(configDir, codeName) {
|
|
1329
1049
|
let text;
|
|
1330
1050
|
try {
|
|
1331
|
-
text =
|
|
1332
|
-
|
|
1051
|
+
text = readFileSync4(
|
|
1052
|
+
join4(configDir, codeName, "project", ".claude", "skills", "core-knowledge", "SKILL.md"),
|
|
1333
1053
|
"utf8"
|
|
1334
1054
|
);
|
|
1335
1055
|
} catch {
|
|
@@ -1363,16 +1083,16 @@ function logClaudeMdCeilingTransition(codeName, report, log2) {
|
|
|
1363
1083
|
}
|
|
1364
1084
|
|
|
1365
1085
|
// ../../packages/core/dist/integrations/forwarded-tools-report.js
|
|
1366
|
-
import { readFileSync as
|
|
1367
|
-
import { join as
|
|
1086
|
+
import { readFileSync as readFileSync5, writeFileSync as writeFileSync3 } from "fs";
|
|
1087
|
+
import { join as join5 } from "path";
|
|
1368
1088
|
var FORWARDED_TOOLS_REPORT_FILENAME = "forwarded-tools.json";
|
|
1369
1089
|
function forwardedToolsReportPath(agentDir) {
|
|
1370
|
-
return
|
|
1090
|
+
return join5(agentDir, FORWARDED_TOOLS_REPORT_FILENAME);
|
|
1371
1091
|
}
|
|
1372
1092
|
function readForwardedToolsReport(agentDir) {
|
|
1373
1093
|
let raw;
|
|
1374
1094
|
try {
|
|
1375
|
-
raw =
|
|
1095
|
+
raw = readFileSync5(forwardedToolsReportPath(agentDir), "utf-8");
|
|
1376
1096
|
} catch {
|
|
1377
1097
|
return null;
|
|
1378
1098
|
}
|
|
@@ -1959,24 +1679,24 @@ var DependencyRecoveryLedger = class {
|
|
|
1959
1679
|
|
|
1960
1680
|
// src/lib/mcp-assets-ready.ts
|
|
1961
1681
|
import { existsSync as nodeExistsSync, readFileSync as nodeReadFileSync } from "fs";
|
|
1962
|
-
import { homedir as
|
|
1963
|
-
import { join as
|
|
1964
|
-
function getSharedMcpDir(homeDir =
|
|
1965
|
-
return
|
|
1682
|
+
import { homedir as homedir2 } from "os";
|
|
1683
|
+
import { join as join6, resolve, sep } from "path";
|
|
1684
|
+
function getSharedMcpDir(homeDir = homedir2()) {
|
|
1685
|
+
return join6(homeDir, ".augmented", "_mcp");
|
|
1966
1686
|
}
|
|
1967
1687
|
function isPathInsideDir(candidate, dir) {
|
|
1968
1688
|
const resolvedDir = resolve(dir);
|
|
1969
1689
|
const resolvedCandidate = resolve(candidate);
|
|
1970
1690
|
if (resolvedCandidate === resolvedDir) return false;
|
|
1971
|
-
return resolvedCandidate.startsWith(resolvedDir.endsWith(
|
|
1691
|
+
return resolvedCandidate.startsWith(resolvedDir.endsWith(sep) ? resolvedDir : resolvedDir + sep);
|
|
1972
1692
|
}
|
|
1973
1693
|
function findMissingMcpBundles(mcpConfigPath, deps = {}) {
|
|
1974
|
-
const
|
|
1975
|
-
const
|
|
1694
|
+
const existsSync17 = deps.existsSync ?? nodeExistsSync;
|
|
1695
|
+
const readFileSync30 = deps.readFileSync ?? nodeReadFileSync;
|
|
1976
1696
|
const mcpDir = deps.mcpDir ?? getSharedMcpDir();
|
|
1977
1697
|
let parsed;
|
|
1978
1698
|
try {
|
|
1979
|
-
parsed = JSON.parse(
|
|
1699
|
+
parsed = JSON.parse(readFileSync30(mcpConfigPath, "utf-8"));
|
|
1980
1700
|
} catch {
|
|
1981
1701
|
return [];
|
|
1982
1702
|
}
|
|
@@ -1996,7 +1716,7 @@ function findMissingMcpBundles(mcpConfigPath, deps = {}) {
|
|
|
1996
1716
|
if (seenPaths.has(resolvedBundlePath)) continue;
|
|
1997
1717
|
let present;
|
|
1998
1718
|
try {
|
|
1999
|
-
present =
|
|
1719
|
+
present = existsSync17(bundlePath);
|
|
2000
1720
|
} catch {
|
|
2001
1721
|
continue;
|
|
2002
1722
|
}
|
|
@@ -2014,8 +1734,8 @@ function formatMissingMcpBundles(missing) {
|
|
|
2014
1734
|
}
|
|
2015
1735
|
|
|
2016
1736
|
// src/lib/self-update-coalesce.ts
|
|
2017
|
-
import { readFileSync as
|
|
2018
|
-
import { dirname as
|
|
1737
|
+
import { readFileSync as readFileSync6, writeFileSync as writeFileSync4, mkdirSync as mkdirSync3 } from "fs";
|
|
1738
|
+
import { dirname as dirname4 } from "path";
|
|
2019
1739
|
var DEFAULT_SELF_UPDATE_COALESCE_MS = 30 * 60 * 1e3;
|
|
2020
1740
|
function resolveCoalesceWindowMs(env = process.env) {
|
|
2021
1741
|
const raw = env.AGT_SELF_UPDATE_COALESCE_MS;
|
|
@@ -2024,7 +1744,7 @@ function resolveCoalesceWindowMs(env = process.env) {
|
|
|
2024
1744
|
if (!Number.isFinite(parsed) || parsed < 0) return DEFAULT_SELF_UPDATE_COALESCE_MS;
|
|
2025
1745
|
return Math.trunc(parsed);
|
|
2026
1746
|
}
|
|
2027
|
-
function readLastSelfUpdateAppliedMs(markerPath, now = Date.now(), read = (p) =>
|
|
1747
|
+
function readLastSelfUpdateAppliedMs(markerPath, now = Date.now(), read = (p) => readFileSync6(p, "utf-8")) {
|
|
2028
1748
|
let raw;
|
|
2029
1749
|
try {
|
|
2030
1750
|
raw = read(markerPath);
|
|
@@ -2037,7 +1757,7 @@ function readLastSelfUpdateAppliedMs(markerPath, now = Date.now(), read = (p) =>
|
|
|
2037
1757
|
return v;
|
|
2038
1758
|
}
|
|
2039
1759
|
function stampLastSelfUpdateApplied(markerPath, now = Date.now(), write = (p, v) => {
|
|
2040
|
-
mkdirSync3(
|
|
1760
|
+
mkdirSync3(dirname4(p), { recursive: true });
|
|
2041
1761
|
writeFileSync4(p, v);
|
|
2042
1762
|
}) {
|
|
2043
1763
|
try {
|
|
@@ -2328,11 +2048,11 @@ async function reportModelApiError(opts) {
|
|
|
2328
2048
|
}
|
|
2329
2049
|
|
|
2330
2050
|
// src/lib/claude-pid-tracker.ts
|
|
2331
|
-
import { existsSync
|
|
2051
|
+
import { existsSync, readFileSync as readFileSync7 } from "fs";
|
|
2332
2052
|
function readPidFile(path) {
|
|
2333
|
-
if (!
|
|
2053
|
+
if (!existsSync(path)) return { version: 1, spawns: [] };
|
|
2334
2054
|
try {
|
|
2335
|
-
const raw = JSON.parse(
|
|
2055
|
+
const raw = JSON.parse(readFileSync7(path, "utf-8"));
|
|
2336
2056
|
if (raw.version !== 1 || !Array.isArray(raw.spawns)) return { version: 1, spawns: [] };
|
|
2337
2057
|
const spawns = raw.spawns.filter(
|
|
2338
2058
|
(s) => !!s && typeof s.pid === "number" && Number.isFinite(s.pid) && s.pid > 0
|
|
@@ -2382,14 +2102,14 @@ function formatReaperBootLine(opts) {
|
|
|
2382
2102
|
}
|
|
2383
2103
|
|
|
2384
2104
|
// src/lib/direct-chat-delivery.ts
|
|
2385
|
-
import { join as
|
|
2105
|
+
import { join as join7 } from "path";
|
|
2386
2106
|
var DEFAULT_DIRECT_CHAT_MAX_AGE_MS = 30 * 6e4;
|
|
2387
2107
|
function directChatMaxAgeMs() {
|
|
2388
2108
|
const raw = parseInt(process.env["AGT_DIRECT_CHAT_MAX_AGE_MS"] ?? "", 10);
|
|
2389
2109
|
return Number.isFinite(raw) && raw >= 0 ? raw : DEFAULT_DIRECT_CHAT_MAX_AGE_MS;
|
|
2390
2110
|
}
|
|
2391
2111
|
function directChatDoorbellPath(agentId, home) {
|
|
2392
|
-
return
|
|
2112
|
+
return join7(home, ".augmented", agentId, "direct-chat-doorbell");
|
|
2393
2113
|
}
|
|
2394
2114
|
function isDirectChatMessageExpired(createdAt, nowMs, maxAgeMs) {
|
|
2395
2115
|
if (!maxAgeMs || maxAgeMs <= 0) return false;
|
|
@@ -2400,16 +2120,16 @@ function isDirectChatMessageExpired(createdAt, nowMs, maxAgeMs) {
|
|
|
2400
2120
|
}
|
|
2401
2121
|
|
|
2402
2122
|
// src/lib/id-keyed-migration.ts
|
|
2403
|
-
import { existsSync as
|
|
2404
|
-
import { join as
|
|
2405
|
-
import { homedir as
|
|
2123
|
+
import { existsSync as existsSync2, lstatSync, readlinkSync, renameSync as renameSync2 } from "fs";
|
|
2124
|
+
import { join as join8 } from "path";
|
|
2125
|
+
import { homedir as homedir3 } from "os";
|
|
2406
2126
|
var ID_KEYED_MIGRATION_FLAG = "id-keyed-layout-migration";
|
|
2407
2127
|
function agentHasActiveWhatsapp(channelConfigs, codeNameDir) {
|
|
2408
2128
|
if (channelConfigs && Object.prototype.hasOwnProperty.call(channelConfigs, "whatsapp")) {
|
|
2409
2129
|
return true;
|
|
2410
2130
|
}
|
|
2411
2131
|
try {
|
|
2412
|
-
if (
|
|
2132
|
+
if (existsSync2(join8(codeNameDir, "whatsapp-pending-inbound"))) return true;
|
|
2413
2133
|
} catch {
|
|
2414
2134
|
}
|
|
2415
2135
|
return false;
|
|
@@ -2421,12 +2141,12 @@ function finishTranscriptMove(oldCwd, newCwd, codeName, log2) {
|
|
|
2421
2141
|
let fromExists = false;
|
|
2422
2142
|
let toExists = false;
|
|
2423
2143
|
try {
|
|
2424
|
-
fromExists =
|
|
2144
|
+
fromExists = existsSync2(from);
|
|
2425
2145
|
} catch {
|
|
2426
2146
|
}
|
|
2427
2147
|
if (!fromExists) return;
|
|
2428
2148
|
try {
|
|
2429
|
-
toExists =
|
|
2149
|
+
toExists = existsSync2(to);
|
|
2430
2150
|
} catch {
|
|
2431
2151
|
}
|
|
2432
2152
|
if (toExists) {
|
|
@@ -2439,19 +2159,19 @@ function finishTranscriptMove(oldCwd, newCwd, codeName, log2) {
|
|
|
2439
2159
|
log2(`[id-keyed-migration] moved transcript store for '${codeName}' to the id-keyed key`);
|
|
2440
2160
|
}
|
|
2441
2161
|
function maybeMigrateAgentToIdKeyedLayout(agent, deps) {
|
|
2442
|
-
const home = deps.home ??
|
|
2162
|
+
const home = deps.home ?? homedir3();
|
|
2443
2163
|
const { code_name: codeName, agent_id: agentId } = agent;
|
|
2444
|
-
const codeNamePath =
|
|
2445
|
-
const idPath =
|
|
2446
|
-
const oldCwd =
|
|
2447
|
-
const newCwd =
|
|
2164
|
+
const codeNamePath = join8(home, ".augmented", codeName);
|
|
2165
|
+
const idPath = join8(home, ".augmented", agentId);
|
|
2166
|
+
const oldCwd = join8(home, ".augmented", codeName, "project");
|
|
2167
|
+
const newCwd = join8(idPath, "project");
|
|
2448
2168
|
let codeNameKind;
|
|
2449
2169
|
try {
|
|
2450
2170
|
codeNameKind = lstatSync(codeNamePath).isSymbolicLink() ? "symlink" : "realdir";
|
|
2451
2171
|
} catch {
|
|
2452
2172
|
codeNameKind = "absent";
|
|
2453
2173
|
}
|
|
2454
|
-
const idExists =
|
|
2174
|
+
const idExists = existsSync2(idPath);
|
|
2455
2175
|
try {
|
|
2456
2176
|
if (codeNameKind === "symlink") {
|
|
2457
2177
|
const target = readlinkSync(codeNamePath);
|
|
@@ -2571,8 +2291,8 @@ function collectEnvGates(env) {
|
|
|
2571
2291
|
}
|
|
2572
2292
|
|
|
2573
2293
|
// ../../packages/core/dist/direct-chat/cursor-advance-telemetry.js
|
|
2574
|
-
import { readFileSync as
|
|
2575
|
-
import { join as
|
|
2294
|
+
import { readFileSync as readFileSync8, writeFileSync as writeFileSync5 } from "fs";
|
|
2295
|
+
import { join as join9 } from "path";
|
|
2576
2296
|
var CURSOR_SHORTFALL_COUNTER_SUFFIX = "-cursor-advance-classifications.json";
|
|
2577
2297
|
function recordCursorAdvanceOutcome(agentDir, source, route, verdict) {
|
|
2578
2298
|
if (!agentDir)
|
|
@@ -2580,10 +2300,10 @@ function recordCursorAdvanceOutcome(agentDir, source, route, verdict) {
|
|
|
2580
2300
|
const key = cursorAdvanceCounterKey(route, verdict);
|
|
2581
2301
|
if (key === null)
|
|
2582
2302
|
return;
|
|
2583
|
-
const path =
|
|
2303
|
+
const path = join9(agentDir, `${source}${CURSOR_SHORTFALL_COUNTER_SUFFIX}`);
|
|
2584
2304
|
const counts = {};
|
|
2585
2305
|
try {
|
|
2586
|
-
const parsed = JSON.parse(
|
|
2306
|
+
const parsed = JSON.parse(readFileSync8(path, "utf-8"));
|
|
2587
2307
|
if (parsed && typeof parsed === "object" && !Array.isArray(parsed)) {
|
|
2588
2308
|
for (const [k, v] of Object.entries(parsed)) {
|
|
2589
2309
|
if (typeof v === "number" && Number.isInteger(v) && v >= 0)
|
|
@@ -2600,8 +2320,8 @@ function recordCursorAdvanceOutcome(agentDir, source, route, verdict) {
|
|
|
2600
2320
|
}
|
|
2601
2321
|
|
|
2602
2322
|
// src/lib/artifact-stream.ts
|
|
2603
|
-
import { join as
|
|
2604
|
-
import { homedir as
|
|
2323
|
+
import { join as join10 } from "path";
|
|
2324
|
+
import { homedir as homedir4 } from "os";
|
|
2605
2325
|
import { readdir, stat, readFile } from "fs/promises";
|
|
2606
2326
|
var ARTEFACT_ENTRY_FILE = "index.html";
|
|
2607
2327
|
function errMessage(err) {
|
|
@@ -2686,7 +2406,7 @@ var ArtifactStreamScanner = class {
|
|
|
2686
2406
|
return;
|
|
2687
2407
|
}
|
|
2688
2408
|
for (const name of names) {
|
|
2689
|
-
const file =
|
|
2409
|
+
const file = join10(this.artifactsDir, name, ARTEFACT_ENTRY_FILE);
|
|
2690
2410
|
const mtime = await this.fsDeps.mtimeMs(file).catch(() => null);
|
|
2691
2411
|
if (mtime === null) continue;
|
|
2692
2412
|
if (this.seenMtime.get(name) === mtime) continue;
|
|
@@ -2717,7 +2437,7 @@ var ArtifactStreamScanner = class {
|
|
|
2717
2437
|
}
|
|
2718
2438
|
};
|
|
2719
2439
|
function artifactsDirFor(codeName) {
|
|
2720
|
-
return
|
|
2440
|
+
return join10(homedir4(), ".augmented", codeName, "artifacts");
|
|
2721
2441
|
}
|
|
2722
2442
|
var nodeArtifactFs = {
|
|
2723
2443
|
async listArtefactNames(artifactsDir) {
|
|
@@ -2970,13 +2690,13 @@ async function maybePollHostUsage(deps) {
|
|
|
2970
2690
|
// src/lib/claude-account-fingerprint.ts
|
|
2971
2691
|
import { createHash as createHash6 } from "crypto";
|
|
2972
2692
|
import { readFile as readFile3, readdir as readdir3 } from "fs/promises";
|
|
2973
|
-
import { homedir as
|
|
2974
|
-
import { dirname as
|
|
2693
|
+
import { homedir as homedir6, platform as platform2 } from "os";
|
|
2694
|
+
import { dirname as dirname5, join as join12 } from "path";
|
|
2975
2695
|
|
|
2976
2696
|
// src/lib/claude-auth-detect.ts
|
|
2977
2697
|
import { readFile as readFile2, readdir as readdir2 } from "fs/promises";
|
|
2978
|
-
import { homedir as
|
|
2979
|
-
import { join as
|
|
2698
|
+
import { homedir as homedir5, platform } from "os";
|
|
2699
|
+
import { join as join11 } from "path";
|
|
2980
2700
|
import { execFile } from "child_process";
|
|
2981
2701
|
import { promisify } from "util";
|
|
2982
2702
|
var execFileAsync = promisify(execFile);
|
|
@@ -2991,16 +2711,16 @@ async function detectClaudeAuth() {
|
|
|
2991
2711
|
}
|
|
2992
2712
|
async function findClaudeCredentialsPaths() {
|
|
2993
2713
|
const candidates = [
|
|
2994
|
-
|
|
2995
|
-
|
|
2714
|
+
join11(homedir5(), ".claude", ".credentials.json"),
|
|
2715
|
+
join11(homedir5(), ".claude", "credentials.json")
|
|
2996
2716
|
];
|
|
2997
2717
|
const isLinuxRoot = platform() === "linux" && typeof process.getuid === "function" && process.getuid() === 0;
|
|
2998
2718
|
if (isLinuxRoot) {
|
|
2999
2719
|
try {
|
|
3000
2720
|
const entries = await readdir2("/home", { withFileTypes: true });
|
|
3001
2721
|
for (const entry of entries.filter((entry2) => entry2.isDirectory()).sort((a, b) => a.name.localeCompare(b.name))) {
|
|
3002
|
-
candidates.push(
|
|
3003
|
-
candidates.push(
|
|
2722
|
+
candidates.push(join11("/home", entry.name, ".claude", ".credentials.json"));
|
|
2723
|
+
candidates.push(join11("/home", entry.name, ".claude", "credentials.json"));
|
|
3004
2724
|
}
|
|
3005
2725
|
} catch {
|
|
3006
2726
|
}
|
|
@@ -3078,13 +2798,13 @@ function parseExpiresAt(raw) {
|
|
|
3078
2798
|
|
|
3079
2799
|
// src/lib/claude-account-fingerprint.ts
|
|
3080
2800
|
async function candidateHomes() {
|
|
3081
|
-
const homes = [
|
|
2801
|
+
const homes = [homedir6()];
|
|
3082
2802
|
const isLinuxRoot = platform2() === "linux" && typeof process.getuid === "function" && process.getuid() === 0;
|
|
3083
2803
|
if (isLinuxRoot) {
|
|
3084
2804
|
try {
|
|
3085
2805
|
const entries = await readdir3("/home", { withFileTypes: true });
|
|
3086
2806
|
for (const entry of entries.filter((e) => e.isDirectory()).sort((a, b) => a.name.localeCompare(b.name))) {
|
|
3087
|
-
homes.push(
|
|
2807
|
+
homes.push(join12("/home", entry.name));
|
|
3088
2808
|
}
|
|
3089
2809
|
} catch {
|
|
3090
2810
|
}
|
|
@@ -3095,7 +2815,7 @@ async function homeOfActiveCredentials() {
|
|
|
3095
2815
|
for (const path of await findClaudeCredentialsPaths()) {
|
|
3096
2816
|
try {
|
|
3097
2817
|
await readFile3(path, "utf-8");
|
|
3098
|
-
return
|
|
2818
|
+
return dirname5(dirname5(path));
|
|
3099
2819
|
} catch {
|
|
3100
2820
|
}
|
|
3101
2821
|
}
|
|
@@ -3104,11 +2824,11 @@ async function homeOfActiveCredentials() {
|
|
|
3104
2824
|
async function claudeConfigCandidatePaths() {
|
|
3105
2825
|
const paths = [];
|
|
3106
2826
|
const configDir = process.env["CLAUDE_CONFIG_DIR"]?.trim();
|
|
3107
|
-
if (configDir) paths.push(
|
|
2827
|
+
if (configDir) paths.push(join12(configDir, ".claude.json"));
|
|
3108
2828
|
const activeHome = await homeOfActiveCredentials();
|
|
3109
|
-
if (activeHome) paths.push(
|
|
2829
|
+
if (activeHome) paths.push(join12(activeHome, ".claude.json"));
|
|
3110
2830
|
for (const home of await candidateHomes()) {
|
|
3111
|
-
const path =
|
|
2831
|
+
const path = join12(home, ".claude.json");
|
|
3112
2832
|
if (!paths.includes(path)) paths.push(path);
|
|
3113
2833
|
}
|
|
3114
2834
|
return paths;
|
|
@@ -3206,10 +2926,10 @@ function diffAuthTuples(recorded, current) {
|
|
|
3206
2926
|
|
|
3207
2927
|
// src/lib/account-enforcement-marker.ts
|
|
3208
2928
|
import { mkdirSync as mkdirSync4, renameSync as renameSync3, rmSync as rmSync2, writeFileSync as writeFileSync6 } from "fs";
|
|
3209
|
-
import { homedir as
|
|
3210
|
-
import { join as
|
|
2929
|
+
import { homedir as homedir7 } from "os";
|
|
2930
|
+
import { join as join13 } from "path";
|
|
3211
2931
|
function accountEnforcementMarkerPath(codeName) {
|
|
3212
|
-
return
|
|
2932
|
+
return join13(homedir7(), ".augmented", codeName, ACCOUNT_ENFORCEMENT_MARKER_FILENAME);
|
|
3213
2933
|
}
|
|
3214
2934
|
function syncAccountEnforcementMarker(codeName, level, log2 = (m) => process.stderr.write(`${m}
|
|
3215
2935
|
`), text) {
|
|
@@ -3217,8 +2937,8 @@ function syncAccountEnforcementMarker(codeName, level, log2 = (m) => process.std
|
|
|
3217
2937
|
clearAccountEnforcementMarker(codeName, log2);
|
|
3218
2938
|
return;
|
|
3219
2939
|
}
|
|
3220
|
-
const dir =
|
|
3221
|
-
const path =
|
|
2940
|
+
const dir = join13(homedir7(), ".augmented", codeName);
|
|
2941
|
+
const path = join13(dir, ACCOUNT_ENFORCEMENT_MARKER_FILENAME);
|
|
3222
2942
|
const tempPath = `${path}.${process.pid}.tmp`;
|
|
3223
2943
|
try {
|
|
3224
2944
|
mkdirSync4(dir, { recursive: true });
|
|
@@ -3243,8 +2963,8 @@ function clearAccountEnforcementMarker(codeName, log2 = (m) => process.stderr.wr
|
|
|
3243
2963
|
}
|
|
3244
2964
|
|
|
3245
2965
|
// src/lib/token-usage-monitor.ts
|
|
3246
|
-
import { readdirSync
|
|
3247
|
-
import { join as
|
|
2966
|
+
import { readdirSync, readFileSync as readFileSync9, statSync } from "fs";
|
|
2967
|
+
import { join as join14 } from "path";
|
|
3248
2968
|
var MIN_CHECK_INTERVAL_MS2 = 6e4;
|
|
3249
2969
|
var TRANSCRIPT_MTIME_WINDOW_MS = 2 * 24 * 60 * 60 * 1e3;
|
|
3250
2970
|
var MAX_ENTRIES_PER_POST = 200;
|
|
@@ -3262,7 +2982,7 @@ async function maybeReportTokenUsage(args) {
|
|
|
3262
2982
|
const next = { files, lastCheckedAt: nowMs };
|
|
3263
2983
|
let dirEntries;
|
|
3264
2984
|
try {
|
|
3265
|
-
dirEntries =
|
|
2985
|
+
dirEntries = readdirSync(dir);
|
|
3266
2986
|
} catch {
|
|
3267
2987
|
state3.set(codeName, next);
|
|
3268
2988
|
return;
|
|
@@ -3273,7 +2993,7 @@ async function maybeReportTokenUsage(args) {
|
|
|
3273
2993
|
if (!name.endsWith(".jsonl")) continue;
|
|
3274
2994
|
const sessionId = name.slice(0, -".jsonl".length);
|
|
3275
2995
|
if (!sessionId) continue;
|
|
3276
|
-
const path =
|
|
2996
|
+
const path = join14(dir, name);
|
|
3277
2997
|
let st;
|
|
3278
2998
|
try {
|
|
3279
2999
|
st = statSync(path);
|
|
@@ -3289,7 +3009,7 @@ async function maybeReportTokenUsage(args) {
|
|
|
3289
3009
|
}
|
|
3290
3010
|
let content;
|
|
3291
3011
|
try {
|
|
3292
|
-
content =
|
|
3012
|
+
content = readFileSync9(path, "utf-8");
|
|
3293
3013
|
} catch (err) {
|
|
3294
3014
|
log2(`[token-usage] read failed for '${codeName}/${name}': ${err.message}`);
|
|
3295
3015
|
continue;
|
|
@@ -3370,8 +3090,8 @@ async function maybeReportTokenUsage(args) {
|
|
|
3370
3090
|
}
|
|
3371
3091
|
|
|
3372
3092
|
// src/lib/workflow-run-reconciler.ts
|
|
3373
|
-
import { readdirSync as
|
|
3374
|
-
import { join as
|
|
3093
|
+
import { readdirSync as readdirSync2, readFileSync as readFileSync10, statSync as statSync2 } from "fs";
|
|
3094
|
+
import { join as join15 } from "path";
|
|
3375
3095
|
var MIN_CHECK_INTERVAL_MS3 = 5 * 6e4;
|
|
3376
3096
|
var SETTLE_MS = 3e4;
|
|
3377
3097
|
var TRANSCRIPT_MTIME_WINDOW_MS2 = 2 * 24 * 60 * 60 * 1e3;
|
|
@@ -3385,12 +3105,12 @@ function collectJsonlRecursive(dir, minMtimeMs, out, depth) {
|
|
|
3385
3105
|
if (depth > MAX_SUBAGENT_DEPTH) return;
|
|
3386
3106
|
let entries;
|
|
3387
3107
|
try {
|
|
3388
|
-
entries =
|
|
3108
|
+
entries = readdirSync2(dir);
|
|
3389
3109
|
} catch {
|
|
3390
3110
|
return;
|
|
3391
3111
|
}
|
|
3392
3112
|
for (const name of entries) {
|
|
3393
|
-
const p =
|
|
3113
|
+
const p = join15(dir, name);
|
|
3394
3114
|
let st;
|
|
3395
3115
|
try {
|
|
3396
3116
|
st = statSync2(p);
|
|
@@ -3408,12 +3128,12 @@ function enumerateTranscriptFiles(transcriptDir, nowMs, minMtimeMs = nowMs - TRA
|
|
|
3408
3128
|
const out = [];
|
|
3409
3129
|
let entries;
|
|
3410
3130
|
try {
|
|
3411
|
-
entries =
|
|
3131
|
+
entries = readdirSync2(transcriptDir);
|
|
3412
3132
|
} catch {
|
|
3413
3133
|
return out;
|
|
3414
3134
|
}
|
|
3415
3135
|
for (const name of entries) {
|
|
3416
|
-
const path =
|
|
3136
|
+
const path = join15(transcriptDir, name);
|
|
3417
3137
|
let st;
|
|
3418
3138
|
try {
|
|
3419
3139
|
st = statSync2(path);
|
|
@@ -3425,7 +3145,7 @@ function enumerateTranscriptFiles(transcriptDir, nowMs, minMtimeMs = nowMs - TRA
|
|
|
3425
3145
|
continue;
|
|
3426
3146
|
}
|
|
3427
3147
|
if (st.isDirectory()) {
|
|
3428
|
-
collectJsonlRecursive(
|
|
3148
|
+
collectJsonlRecursive(join15(path, "subagents"), minMtimeMs, out, 0);
|
|
3429
3149
|
}
|
|
3430
3150
|
}
|
|
3431
3151
|
return out;
|
|
@@ -3470,7 +3190,7 @@ async function maybeReconcileWorkflowRunTokens(args) {
|
|
|
3470
3190
|
const contents = [];
|
|
3471
3191
|
for (const path of files) {
|
|
3472
3192
|
try {
|
|
3473
|
-
contents.push(
|
|
3193
|
+
contents.push(readFileSync10(path, "utf-8"));
|
|
3474
3194
|
} catch {
|
|
3475
3195
|
}
|
|
3476
3196
|
}
|
|
@@ -3515,8 +3235,8 @@ async function maybeReconcileWorkflowRunTokens(args) {
|
|
|
3515
3235
|
}
|
|
3516
3236
|
|
|
3517
3237
|
// src/lib/conversation-evaluator.ts
|
|
3518
|
-
import { readdirSync as
|
|
3519
|
-
import { join as
|
|
3238
|
+
import { readdirSync as readdirSync3, readFileSync as readFileSync11, statSync as statSync3 } from "fs";
|
|
3239
|
+
import { join as join16 } from "path";
|
|
3520
3240
|
var MIN_CHECK_INTERVAL_MS4 = 5 * 6e4;
|
|
3521
3241
|
var TRANSCRIPT_MTIME_WINDOW_MS3 = 7 * 24 * 60 * 60 * 1e3;
|
|
3522
3242
|
var WINDOW_PAD_MS = 5 * 6e4;
|
|
@@ -3947,12 +3667,12 @@ function readRecentTurns(dir, nowMs) {
|
|
|
3947
3667
|
const visit = (d) => {
|
|
3948
3668
|
let entries;
|
|
3949
3669
|
try {
|
|
3950
|
-
entries =
|
|
3670
|
+
entries = readdirSync3(d, { withFileTypes: true });
|
|
3951
3671
|
} catch {
|
|
3952
3672
|
return;
|
|
3953
3673
|
}
|
|
3954
3674
|
for (const ent of entries) {
|
|
3955
|
-
const full =
|
|
3675
|
+
const full = join16(d, ent.name);
|
|
3956
3676
|
if (ent.isDirectory()) {
|
|
3957
3677
|
visit(full);
|
|
3958
3678
|
continue;
|
|
@@ -3967,7 +3687,7 @@ function readRecentTurns(dir, nowMs) {
|
|
|
3967
3687
|
if (nowMs - mtimeMs > TRANSCRIPT_MTIME_WINDOW_MS3) continue;
|
|
3968
3688
|
let content;
|
|
3969
3689
|
try {
|
|
3970
|
-
content =
|
|
3690
|
+
content = readFileSync11(full, "utf8");
|
|
3971
3691
|
} catch {
|
|
3972
3692
|
continue;
|
|
3973
3693
|
}
|
|
@@ -4257,23 +3977,23 @@ async function reportSkip2(api2, agentId, conversationId, log2, codeName) {
|
|
|
4257
3977
|
}
|
|
4258
3978
|
|
|
4259
3979
|
// src/lib/tool-call-audit.ts
|
|
4260
|
-
import { homedir as
|
|
4261
|
-
import { join as
|
|
3980
|
+
import { homedir as homedir11 } from "os";
|
|
3981
|
+
import { join as join21 } from "path";
|
|
4262
3982
|
|
|
4263
3983
|
// src/lib/agent-logging-mode.ts
|
|
4264
|
-
import { readFileSync as
|
|
4265
|
-
import { homedir as
|
|
4266
|
-
import { join as
|
|
3984
|
+
import { readFileSync as readFileSync12 } from "fs";
|
|
3985
|
+
import { homedir as homedir8 } from "os";
|
|
3986
|
+
import { join as join17 } from "path";
|
|
4267
3987
|
var LOGGING_MODES = ["hash-only", "redacted", "full-local"];
|
|
4268
3988
|
function charterPath(codeName, homeDir) {
|
|
4269
|
-
const home = homeDir ?? (process.env["HOME"]?.trim() ||
|
|
3989
|
+
const home = homeDir ?? (process.env["HOME"]?.trim() || homedir8());
|
|
4270
3990
|
const key = agentRuntimeKey(codeName, homeDir);
|
|
4271
|
-
return
|
|
3991
|
+
return join17(home, ".augmented", key, "provision", "CHARTER.md");
|
|
4272
3992
|
}
|
|
4273
3993
|
function readAgentLoggingMode(codeName, homeDir) {
|
|
4274
3994
|
let raw;
|
|
4275
3995
|
try {
|
|
4276
|
-
raw =
|
|
3996
|
+
raw = readFileSync12(charterPath(codeName, homeDir), "utf-8");
|
|
4277
3997
|
} catch {
|
|
4278
3998
|
return { mode: null, reason: "no-charter" };
|
|
4279
3999
|
}
|
|
@@ -4297,15 +4017,15 @@ function loggingModeWithholdsTargets(reading) {
|
|
|
4297
4017
|
|
|
4298
4018
|
// src/lib/tool-call-path-salt.ts
|
|
4299
4019
|
import { randomBytes } from "crypto";
|
|
4300
|
-
import { existsSync as
|
|
4301
|
-
import { homedir as
|
|
4302
|
-
import { dirname as
|
|
4020
|
+
import { existsSync as existsSync3, mkdirSync as mkdirSync5, readFileSync as readFileSync13, renameSync as renameSync4, unlinkSync as unlinkSync2, writeFileSync as writeFileSync7 } from "fs";
|
|
4021
|
+
import { homedir as homedir9 } from "os";
|
|
4022
|
+
import { dirname as dirname6, join as join18 } from "path";
|
|
4303
4023
|
var SALT_BYTES = 32;
|
|
4304
4024
|
var SALT_RE = /^[0-9a-f]{64}$/;
|
|
4305
4025
|
function pathSaltPath(codeName, homeDir) {
|
|
4306
|
-
const home = homeDir ?? (process.env["HOME"]?.trim() ||
|
|
4026
|
+
const home = homeDir ?? (process.env["HOME"]?.trim() || homedir9());
|
|
4307
4027
|
const key = agentRuntimeKey(codeName, homeDir);
|
|
4308
|
-
return
|
|
4028
|
+
return join18(home, ".augmented", key, "tool-call-path-salt");
|
|
4309
4029
|
}
|
|
4310
4030
|
function readToolCallPathSalt(codeName, homeDir) {
|
|
4311
4031
|
let file;
|
|
@@ -4315,8 +4035,8 @@ function readToolCallPathSalt(codeName, homeDir) {
|
|
|
4315
4035
|
return null;
|
|
4316
4036
|
}
|
|
4317
4037
|
try {
|
|
4318
|
-
if (
|
|
4319
|
-
const existing =
|
|
4038
|
+
if (existsSync3(file)) {
|
|
4039
|
+
const existing = readFileSync13(file, "utf-8").trim();
|
|
4320
4040
|
if (SALT_RE.test(existing)) return existing;
|
|
4321
4041
|
}
|
|
4322
4042
|
} catch {
|
|
@@ -4324,7 +4044,7 @@ function readToolCallPathSalt(codeName, homeDir) {
|
|
|
4324
4044
|
const salt = randomBytes(SALT_BYTES).toString("hex");
|
|
4325
4045
|
const tmp = `${file}.tmp.${process.pid}`;
|
|
4326
4046
|
try {
|
|
4327
|
-
mkdirSync5(
|
|
4047
|
+
mkdirSync5(dirname6(file), { recursive: true, mode: 448 });
|
|
4328
4048
|
writeFileSync7(tmp, `${salt}
|
|
4329
4049
|
`, { encoding: "utf-8", mode: 384 });
|
|
4330
4050
|
renameSync4(tmp, file);
|
|
@@ -4342,8 +4062,8 @@ function readToolCallPathSalt(codeName, homeDir) {
|
|
|
4342
4062
|
import { statSync as statSync4 } from "fs";
|
|
4343
4063
|
|
|
4344
4064
|
// src/lib/tool-call-extractor.ts
|
|
4345
|
-
import { closeSync, fstatSync, openSync, readFileSync as
|
|
4346
|
-
import { basename as basename2, join as
|
|
4065
|
+
import { closeSync, fstatSync, openSync, readFileSync as readFileSync14, readSync, readdirSync as readdirSync4 } from "fs";
|
|
4066
|
+
import { basename as basename2, join as join19, relative } from "path";
|
|
4347
4067
|
import { StringDecoder } from "string_decoder";
|
|
4348
4068
|
|
|
4349
4069
|
// src/lib/tool-call-redaction.ts
|
|
@@ -4472,28 +4192,28 @@ function redactToolTargetInner(toolName, input, ctx) {
|
|
|
4472
4192
|
var EXTRACTOR_VERSION = "e1";
|
|
4473
4193
|
function enumerateSessionTranscripts(transcriptDir, sessionId, projectsRoot) {
|
|
4474
4194
|
const files = [];
|
|
4475
|
-
const mainAbs =
|
|
4195
|
+
const mainAbs = join19(transcriptDir, `${sessionId}.jsonl`);
|
|
4476
4196
|
files.push({
|
|
4477
4197
|
absPath: mainAbs,
|
|
4478
|
-
relPath:
|
|
4198
|
+
relPath: relative(projectsRoot, mainAbs),
|
|
4479
4199
|
ref: "main",
|
|
4480
4200
|
isSubagent: false,
|
|
4481
4201
|
subagentId: null
|
|
4482
4202
|
});
|
|
4483
|
-
const subDir =
|
|
4203
|
+
const subDir = join19(transcriptDir, sessionId, "subagents");
|
|
4484
4204
|
let entries;
|
|
4485
4205
|
try {
|
|
4486
|
-
entries =
|
|
4206
|
+
entries = readdirSync4(subDir);
|
|
4487
4207
|
} catch {
|
|
4488
4208
|
return files;
|
|
4489
4209
|
}
|
|
4490
4210
|
for (const name of entries) {
|
|
4491
4211
|
if (!name.endsWith(".jsonl")) continue;
|
|
4492
|
-
const abs =
|
|
4212
|
+
const abs = join19(subDir, name);
|
|
4493
4213
|
const stem = basename2(name, ".jsonl");
|
|
4494
4214
|
files.push({
|
|
4495
4215
|
absPath: abs,
|
|
4496
|
-
relPath:
|
|
4216
|
+
relPath: relative(projectsRoot, abs),
|
|
4497
4217
|
ref: `subagent:${stem}`,
|
|
4498
4218
|
isSubagent: true,
|
|
4499
4219
|
subagentId: stem.startsWith("agent-") ? stem.slice("agent-".length) : stem
|
|
@@ -4687,9 +4407,9 @@ function extractTranscriptWindow(file, opts, from) {
|
|
|
4687
4407
|
}
|
|
4688
4408
|
|
|
4689
4409
|
// src/lib/tool-call-cursor.ts
|
|
4690
|
-
import { existsSync as
|
|
4691
|
-
import { homedir as
|
|
4692
|
-
import { join as
|
|
4410
|
+
import { existsSync as existsSync4, readFileSync as readFileSync15 } from "fs";
|
|
4411
|
+
import { homedir as homedir10 } from "os";
|
|
4412
|
+
import { join as join20 } from "path";
|
|
4693
4413
|
var COVERAGE_DISPOSITIONS = [
|
|
4694
4414
|
"ok",
|
|
4695
4415
|
"not_entitled",
|
|
@@ -4742,15 +4462,15 @@ function parseCursorKey(key) {
|
|
|
4742
4462
|
return { sessionId: sessionId.length > 0 ? sessionId : null, transcriptRef: key.slice(i + 1) };
|
|
4743
4463
|
}
|
|
4744
4464
|
function cursorStatePath(codeName, homeDir) {
|
|
4745
|
-
const home = homeDir ?? (process.env["HOME"]?.trim() ||
|
|
4465
|
+
const home = homeDir ?? (process.env["HOME"]?.trim() || homedir10());
|
|
4746
4466
|
const key = agentRuntimeKey(codeName, homeDir);
|
|
4747
|
-
return
|
|
4467
|
+
return join20(home, ".augmented", key, "tool-call-cursors.json");
|
|
4748
4468
|
}
|
|
4749
4469
|
function loadCursors(path) {
|
|
4750
4470
|
const out = /* @__PURE__ */ new Map();
|
|
4751
|
-
if (!
|
|
4471
|
+
if (!existsSync4(path)) return out;
|
|
4752
4472
|
try {
|
|
4753
|
-
const parsed = JSON.parse(
|
|
4473
|
+
const parsed = JSON.parse(readFileSync15(path, "utf-8"));
|
|
4754
4474
|
if (!parsed || parsed.version !== 1 || typeof parsed.files !== "object") return out;
|
|
4755
4475
|
for (const [k, v] of Object.entries(parsed.files)) {
|
|
4756
4476
|
if (!v || typeof v !== "object") continue;
|
|
@@ -5156,8 +4876,8 @@ async function maybeScanToolCalls(args) {
|
|
|
5156
4876
|
if (!salt && !hashOnly) {
|
|
5157
4877
|
log2(`[tool-call-audit] ${codeName}: no path-hash salt available \u2014 file targets withheld`);
|
|
5158
4878
|
}
|
|
5159
|
-
const home = args.homeDir ?? (process.env["HOME"]?.trim() ||
|
|
5160
|
-
const projectsRoot = args.projectsRoot ??
|
|
4879
|
+
const home = args.homeDir ?? (process.env["HOME"]?.trim() || homedir11());
|
|
4880
|
+
const projectsRoot = args.projectsRoot ?? join21(home, ".claude", "projects");
|
|
5161
4881
|
const transcriptDir = args.transcriptDir ?? sessionTranscriptDir(getProjectDir(codeName));
|
|
5162
4882
|
const current = peekCurrentSession(codeName);
|
|
5163
4883
|
const sessionIds = current ? [current.sessionId] : [];
|
|
@@ -5186,11 +4906,11 @@ async function maybeScanToolCalls(args) {
|
|
|
5186
4906
|
}
|
|
5187
4907
|
|
|
5188
4908
|
// src/lib/activity-cache-monitor.ts
|
|
5189
|
-
import { existsSync as
|
|
5190
|
-
import { homedir as
|
|
5191
|
-
import { join as
|
|
4909
|
+
import { existsSync as existsSync5, readFileSync as readFileSync16 } from "fs";
|
|
4910
|
+
import { homedir as homedir12 } from "os";
|
|
4911
|
+
import { join as join22 } from "path";
|
|
5192
4912
|
var MIN_CHECK_INTERVAL_MS7 = 6e4;
|
|
5193
|
-
var STATS_CACHE_PATH =
|
|
4913
|
+
var STATS_CACHE_PATH = join22(homedir12(), ".claude", "stats-cache.json");
|
|
5194
4914
|
var ISO_DATE_RE = /^\d{4}-\d{2}-\d{2}$/;
|
|
5195
4915
|
var state7 = { lastObservedDate: null, lastCheckedAt: 0 };
|
|
5196
4916
|
function selectNewDailyRows(raw, lastObservedDate) {
|
|
@@ -5233,12 +4953,12 @@ async function maybeReportActivityCache(args) {
|
|
|
5233
4953
|
const nowMs = now.getTime();
|
|
5234
4954
|
if (nowMs - state7.lastCheckedAt < MIN_CHECK_INTERVAL_MS7) return;
|
|
5235
4955
|
state7.lastCheckedAt = nowMs;
|
|
5236
|
-
if (!
|
|
4956
|
+
if (!existsSync5(STATS_CACHE_PATH)) {
|
|
5237
4957
|
return;
|
|
5238
4958
|
}
|
|
5239
4959
|
let raw;
|
|
5240
4960
|
try {
|
|
5241
|
-
raw =
|
|
4961
|
+
raw = readFileSync16(STATS_CACHE_PATH, "utf-8");
|
|
5242
4962
|
} catch (err) {
|
|
5243
4963
|
log2(`[activity-cache] readFileSync failed: ${err.message}`);
|
|
5244
4964
|
return;
|
|
@@ -5475,18 +5195,18 @@ function computeChannelConfigHash(input) {
|
|
|
5475
5195
|
}
|
|
5476
5196
|
|
|
5477
5197
|
// src/lib/channel-hash-cache.ts
|
|
5478
|
-
import { existsSync as
|
|
5479
|
-
import { join as
|
|
5198
|
+
import { existsSync as existsSync6, readFileSync as readFileSync17, writeFileSync as writeFileSync8 } from "fs";
|
|
5199
|
+
import { join as join23 } from "path";
|
|
5480
5200
|
var CACHE_FILENAME = "channel-hash-cache.json";
|
|
5481
5201
|
function getChannelHashCacheFile(configDir) {
|
|
5482
|
-
return
|
|
5202
|
+
return join23(configDir, CACHE_FILENAME);
|
|
5483
5203
|
}
|
|
5484
5204
|
function loadChannelHashCache(target, configDir) {
|
|
5485
5205
|
const path = getChannelHashCacheFile(configDir);
|
|
5486
|
-
if (!
|
|
5206
|
+
if (!existsSync6(path)) return;
|
|
5487
5207
|
let parsed;
|
|
5488
5208
|
try {
|
|
5489
|
-
parsed = JSON.parse(
|
|
5209
|
+
parsed = JSON.parse(readFileSync17(path, "utf-8"));
|
|
5490
5210
|
} catch {
|
|
5491
5211
|
return;
|
|
5492
5212
|
}
|
|
@@ -5506,8 +5226,8 @@ function saveChannelHashCache(source, configDir) {
|
|
|
5506
5226
|
}
|
|
5507
5227
|
|
|
5508
5228
|
// src/lib/sender-policy-baseline.ts
|
|
5509
|
-
import { existsSync as
|
|
5510
|
-
import { join as
|
|
5229
|
+
import { existsSync as existsSync7, readFileSync as readFileSync18 } from "fs";
|
|
5230
|
+
import { join as join24 } from "path";
|
|
5511
5231
|
var BASELINE_FILENAME = "sender-policy-baseline.json";
|
|
5512
5232
|
var SENDER_POLICY_BASELINE_VERSION = 1;
|
|
5513
5233
|
var BASELINE_CONCERNS = ["senderPolicy", "slackBehaviour", "msteamsBehaviour"];
|
|
@@ -5519,14 +5239,14 @@ function createDeliveryBaselineMaps() {
|
|
|
5519
5239
|
};
|
|
5520
5240
|
}
|
|
5521
5241
|
function getSenderPolicyBaselineFile(configDir) {
|
|
5522
|
-
return
|
|
5242
|
+
return join24(configDir, BASELINE_FILENAME);
|
|
5523
5243
|
}
|
|
5524
5244
|
function loadSenderPolicyBaseline(target, configDir, log2) {
|
|
5525
5245
|
const path = getSenderPolicyBaselineFile(configDir);
|
|
5526
|
-
if (!
|
|
5246
|
+
if (!existsSync7(path)) return;
|
|
5527
5247
|
let parsed;
|
|
5528
5248
|
try {
|
|
5529
|
-
parsed = JSON.parse(
|
|
5249
|
+
parsed = JSON.parse(readFileSync18(path, "utf-8"));
|
|
5530
5250
|
} catch (err) {
|
|
5531
5251
|
log2?.(
|
|
5532
5252
|
`[sender-policy] discarding corrupt ${BASELINE_FILENAME} (${err.message}) - restrictive-policy agents will take one fail-closed restart`
|
|
@@ -5575,8 +5295,8 @@ function saveSenderPolicyBaseline(source, configDir, log2) {
|
|
|
5575
5295
|
}
|
|
5576
5296
|
|
|
5577
5297
|
// src/lib/stuck-streak-store.ts
|
|
5578
|
-
import { existsSync as
|
|
5579
|
-
import { join as
|
|
5298
|
+
import { existsSync as existsSync8, readFileSync as readFileSync19 } from "fs";
|
|
5299
|
+
import { join as join25 } from "path";
|
|
5580
5300
|
var STORE_FILENAME = "stuck-streaks.json";
|
|
5581
5301
|
var STUCK_STREAK_STORE_VERSION = 1;
|
|
5582
5302
|
var STUCK_STREAK_CONCERNS = ["channelSync", "realtimeRebind"];
|
|
@@ -5584,7 +5304,7 @@ function createStuckStreakMaps() {
|
|
|
5584
5304
|
return { channelSync: /* @__PURE__ */ new Map(), realtimeRebind: /* @__PURE__ */ new Map() };
|
|
5585
5305
|
}
|
|
5586
5306
|
function getStuckStreakStoreFile(configDir) {
|
|
5587
|
-
return
|
|
5307
|
+
return join25(configDir, STORE_FILENAME);
|
|
5588
5308
|
}
|
|
5589
5309
|
function isValidPersistedStreak(value) {
|
|
5590
5310
|
if (!value || typeof value !== "object" || Array.isArray(value)) return false;
|
|
@@ -5623,10 +5343,10 @@ function buildStuckStreakPayload(source) {
|
|
|
5623
5343
|
}
|
|
5624
5344
|
function loadStuckStreaks(target, configDir, log2) {
|
|
5625
5345
|
const path = getStuckStreakStoreFile(configDir);
|
|
5626
|
-
if (!
|
|
5346
|
+
if (!existsSync8(path)) return;
|
|
5627
5347
|
let parsed;
|
|
5628
5348
|
try {
|
|
5629
|
-
parsed = JSON.parse(
|
|
5349
|
+
parsed = JSON.parse(readFileSync19(path, "utf-8"));
|
|
5630
5350
|
} catch (err) {
|
|
5631
5351
|
log2?.(
|
|
5632
5352
|
`[stuck-streaks] discarding corrupt ${STORE_FILENAME} (${err.message}) \u2014 stuck-streak ages restart from zero and one spurious "recovered" close may follow`
|
|
@@ -6143,37 +5863,37 @@ function planGlobalSkillSync(globalSkills, prevIds, hashOf, knownHash, options)
|
|
|
6143
5863
|
}
|
|
6144
5864
|
|
|
6145
5865
|
// src/lib/manager/integration-skill-cache.ts
|
|
6146
|
-
import { join as
|
|
5866
|
+
import { join as join26 } from "path";
|
|
6147
5867
|
function integrationSkillHashKey(agentId, skillId) {
|
|
6148
5868
|
return `plugin-skill:${agentId}:${skillId}`;
|
|
6149
5869
|
}
|
|
6150
|
-
function shouldWriteIntegrationSkill(
|
|
6151
|
-
return
|
|
5870
|
+
function shouldWriteIntegrationSkill(cache2, agentId, skillId, contentHash) {
|
|
5871
|
+
return cache2.get(integrationSkillHashKey(agentId, skillId)) !== contentHash;
|
|
6152
5872
|
}
|
|
6153
|
-
function rememberIntegrationSkill(
|
|
6154
|
-
|
|
5873
|
+
function rememberIntegrationSkill(cache2, agentId, skillId, contentHash) {
|
|
5874
|
+
cache2.set(integrationSkillHashKey(agentId, skillId), contentHash);
|
|
6155
5875
|
}
|
|
6156
|
-
function forgetIntegrationSkill(
|
|
6157
|
-
|
|
5876
|
+
function forgetIntegrationSkill(cache2, agentId, skillId) {
|
|
5877
|
+
cache2.delete(integrationSkillHashKey(agentId, skillId));
|
|
6158
5878
|
}
|
|
6159
5879
|
function removeIntegrationSkillFolder(opts) {
|
|
6160
5880
|
forgetIntegrationSkill(opts.cache, opts.agentId, opts.entry);
|
|
6161
5881
|
for (const dir of opts.dirs) {
|
|
6162
|
-
opts.removeDir(
|
|
5882
|
+
opts.removeDir(join26(dir, opts.entry));
|
|
6163
5883
|
}
|
|
6164
5884
|
}
|
|
6165
5885
|
|
|
6166
5886
|
// src/lib/manager/managed-skill-manifest.ts
|
|
6167
|
-
import { existsSync as
|
|
6168
|
-
import { dirname as
|
|
5887
|
+
import { existsSync as existsSync9, mkdirSync as mkdirSync6, readFileSync as readFileSync20, writeFileSync as writeFileSync9 } from "fs";
|
|
5888
|
+
import { dirname as dirname7, join as join27 } from "path";
|
|
6169
5889
|
var MANIFEST_VERSION = 1;
|
|
6170
5890
|
function managedSkillManifestPath(agentRootDir) {
|
|
6171
|
-
return
|
|
5891
|
+
return join27(agentRootDir, "managed-skills.json");
|
|
6172
5892
|
}
|
|
6173
5893
|
function readManagedSkillManifest(path) {
|
|
6174
5894
|
try {
|
|
6175
|
-
if (!
|
|
6176
|
-
const parsed = JSON.parse(
|
|
5895
|
+
if (!existsSync9(path)) return /* @__PURE__ */ new Set();
|
|
5896
|
+
const parsed = JSON.parse(readFileSync20(path, "utf-8"));
|
|
6177
5897
|
const ids = Array.isArray(parsed?.globalSkillIds) ? parsed.globalSkillIds : [];
|
|
6178
5898
|
return new Set(ids.filter((id) => typeof id === "string" && id.length > 0));
|
|
6179
5899
|
} catch {
|
|
@@ -6182,7 +5902,7 @@ function readManagedSkillManifest(path) {
|
|
|
6182
5902
|
}
|
|
6183
5903
|
function writeManagedSkillManifest(path, ids) {
|
|
6184
5904
|
try {
|
|
6185
|
-
mkdirSync6(
|
|
5905
|
+
mkdirSync6(dirname7(path), { recursive: true });
|
|
6186
5906
|
const body = {
|
|
6187
5907
|
version: MANIFEST_VERSION,
|
|
6188
5908
|
globalSkillIds: [...ids].sort()
|
|
@@ -6299,9 +6019,9 @@ function resolveModelChain(refreshData) {
|
|
|
6299
6019
|
}
|
|
6300
6020
|
|
|
6301
6021
|
// src/lib/manager/claude-auth.ts
|
|
6302
|
-
import { existsSync as
|
|
6303
|
-
import { join as
|
|
6304
|
-
import { homedir as
|
|
6022
|
+
import { existsSync as existsSync10, rmSync as rmSync3 } from "fs";
|
|
6023
|
+
import { join as join28 } from "path";
|
|
6024
|
+
import { homedir as homedir13 } from "os";
|
|
6305
6025
|
async function applyClaudeAuthToEnv(childEnv, label) {
|
|
6306
6026
|
const apiKey = getApiKey();
|
|
6307
6027
|
if (!apiKey) {
|
|
@@ -6313,10 +6033,10 @@ async function applyClaudeAuthToEnv(childEnv, label) {
|
|
|
6313
6033
|
throw new Error("claude_auth_mode=api_key but /host/exchange returned no decrypted key");
|
|
6314
6034
|
}
|
|
6315
6035
|
childEnv.ANTHROPIC_API_KEY = exchange.anthropicApiKey;
|
|
6316
|
-
const claudeDir =
|
|
6036
|
+
const claudeDir = join28(homedir13(), ".claude");
|
|
6317
6037
|
for (const filename of [".credentials.json", "credentials.json"]) {
|
|
6318
|
-
const p =
|
|
6319
|
-
if (
|
|
6038
|
+
const p = join28(claudeDir, filename);
|
|
6039
|
+
if (existsSync10(p)) {
|
|
6320
6040
|
try {
|
|
6321
6041
|
rmSync3(p, { force: true });
|
|
6322
6042
|
log(`[${label}] Removed ${p} (api_key mode \u2014 preventing OAuth fallback)`);
|
|
@@ -6397,8 +6117,8 @@ function heartbeatRuntimeAuthFields(probeVerdict) {
|
|
|
6397
6117
|
}
|
|
6398
6118
|
|
|
6399
6119
|
// src/lib/manager/kanban/parsers.ts
|
|
6400
|
-
import { existsSync as
|
|
6401
|
-
import { join as
|
|
6120
|
+
import { existsSync as existsSync11, readFileSync as readFileSync21 } from "fs";
|
|
6121
|
+
import { join as join29 } from "path";
|
|
6402
6122
|
var STANDUP_TEMPLATES = /* @__PURE__ */ new Set(["daily-standup", "end-of-day-summary"]);
|
|
6403
6123
|
var TASK_UPDATE_TEMPLATES = /* @__PURE__ */ new Set(["hourly-status", "task-update"]);
|
|
6404
6124
|
var PLAN_TEMPLATES = /* @__PURE__ */ new Set(["morning-plan"]);
|
|
@@ -6550,12 +6270,12 @@ function getBuiltInSkillContent(skillId) {
|
|
|
6550
6270
|
if (builtInSkillCache.has(skillId)) return builtInSkillCache.get(skillId);
|
|
6551
6271
|
try {
|
|
6552
6272
|
const candidates = [
|
|
6553
|
-
|
|
6554
|
-
|
|
6273
|
+
join29(process.cwd(), "skills", skillId, "SKILL.md"),
|
|
6274
|
+
join29(new URL(".", import.meta.url).pathname, "..", "..", "..", "..", "..", "..", "skills", skillId, "SKILL.md")
|
|
6555
6275
|
];
|
|
6556
6276
|
for (const candidate of candidates) {
|
|
6557
|
-
if (
|
|
6558
|
-
const content =
|
|
6277
|
+
if (existsSync11(candidate)) {
|
|
6278
|
+
const content = readFileSync21(candidate, "utf-8");
|
|
6559
6279
|
const files = [{ relativePath: "SKILL.md", content }];
|
|
6560
6280
|
builtInSkillCache.set(skillId, files);
|
|
6561
6281
|
return files;
|
|
@@ -6696,19 +6416,19 @@ function formatBoardForPrompt(items, template) {
|
|
|
6696
6416
|
}
|
|
6697
6417
|
|
|
6698
6418
|
// src/lib/manager/kanban/nudge-state-cache.ts
|
|
6699
|
-
import { existsSync as
|
|
6700
|
-
import { join as
|
|
6419
|
+
import { existsSync as existsSync12, readFileSync as readFileSync22, writeFileSync as writeFileSync10 } from "fs";
|
|
6420
|
+
import { join as join30 } from "path";
|
|
6701
6421
|
var CACHE_FILENAME2 = "kanban-nudge-state.json";
|
|
6702
6422
|
var KANBAN_NUDGE_STATE_VERSION = 1;
|
|
6703
6423
|
function getKanbanNudgeStateFile(configDir) {
|
|
6704
|
-
return
|
|
6424
|
+
return join30(configDir, CACHE_FILENAME2);
|
|
6705
6425
|
}
|
|
6706
6426
|
function loadKanbanNudgeState(target, configDir) {
|
|
6707
6427
|
const path = getKanbanNudgeStateFile(configDir);
|
|
6708
|
-
if (!
|
|
6428
|
+
if (!existsSync12(path)) return;
|
|
6709
6429
|
let parsed;
|
|
6710
6430
|
try {
|
|
6711
|
-
parsed = JSON.parse(
|
|
6431
|
+
parsed = JSON.parse(readFileSync22(path, "utf-8"));
|
|
6712
6432
|
} catch {
|
|
6713
6433
|
return;
|
|
6714
6434
|
}
|
|
@@ -7326,9 +7046,9 @@ function closeSessionRunForCode(codeName, outcome, reason) {
|
|
|
7326
7046
|
|
|
7327
7047
|
// src/lib/manager/scheduler/kanban-route.ts
|
|
7328
7048
|
import { createHash as createHash12 } from "crypto";
|
|
7329
|
-
import { writeFileSync as writeFileSync11, renameSync as renameSync5, mkdirSync as mkdirSync7, readFileSync as
|
|
7330
|
-
import { homedir as
|
|
7331
|
-
import { join as
|
|
7049
|
+
import { writeFileSync as writeFileSync11, renameSync as renameSync5, mkdirSync as mkdirSync7, readFileSync as readFileSync23, unlinkSync as unlinkSync3 } from "fs";
|
|
7050
|
+
import { homedir as homedir14 } from "os";
|
|
7051
|
+
import { join as join31, dirname as dirname8 } from "path";
|
|
7332
7052
|
|
|
7333
7053
|
// src/lib/manager/scheduler/notify.ts
|
|
7334
7054
|
import { createHash as createHash11 } from "crypto";
|
|
@@ -7687,7 +7407,7 @@ function resolveScheduledSlackTarget(task) {
|
|
|
7687
7407
|
}
|
|
7688
7408
|
function stampScheduledTurnMarker(codeName, taskId, target) {
|
|
7689
7409
|
try {
|
|
7690
|
-
const file =
|
|
7410
|
+
const file = join31(homedir14(), ".augmented", codeName, SCHEDULED_TURN_MARKER_FILENAME);
|
|
7691
7411
|
const marker = { ts: Date.now(), task_id: taskId, ...target ? { target } : {} };
|
|
7692
7412
|
const tmp = `${file}.tmp`;
|
|
7693
7413
|
writeFileSync11(tmp, JSON.stringify(marker), "utf8");
|
|
@@ -7697,9 +7417,9 @@ function stampScheduledTurnMarker(codeName, taskId, target) {
|
|
|
7697
7417
|
}
|
|
7698
7418
|
}
|
|
7699
7419
|
function clearScheduledTurnMarkerForTask(codeName, taskId) {
|
|
7700
|
-
const file =
|
|
7420
|
+
const file = join31(homedir14(), ".augmented", codeName, SCHEDULED_TURN_MARKER_FILENAME);
|
|
7701
7421
|
try {
|
|
7702
|
-
const raw = JSON.parse(
|
|
7422
|
+
const raw = JSON.parse(readFileSync23(file, "utf8"));
|
|
7703
7423
|
if (typeof raw?.task_id !== "string" || raw.task_id !== taskId) return;
|
|
7704
7424
|
unlinkSync3(file);
|
|
7705
7425
|
log(`[scheduled-kanban] scheduled-turn marker cleared for '${codeName}' (task ${taskId} complete)`);
|
|
@@ -7759,8 +7479,8 @@ async function routeScheduledTaskViaKanban(codeName, agentId, task, prompt, dura
|
|
|
7759
7479
|
return false;
|
|
7760
7480
|
}
|
|
7761
7481
|
try {
|
|
7762
|
-
const doorbell = directChatDoorbellPath(agentId,
|
|
7763
|
-
mkdirSync7(
|
|
7482
|
+
const doorbell = directChatDoorbellPath(agentId, homedir14());
|
|
7483
|
+
mkdirSync7(dirname8(doorbell), { recursive: true });
|
|
7764
7484
|
writeFileSync11(doorbell, String(Date.now()));
|
|
7765
7485
|
} catch (err) {
|
|
7766
7486
|
log(`[scheduled-kanban] doorbell ring failed for '${codeName}': ${err.message} (notice still queued)`);
|
|
@@ -7911,12 +7631,12 @@ async function processClaudeTaskResult(codeName, agentId, templateId, rawOutput,
|
|
|
7911
7631
|
|
|
7912
7632
|
// src/lib/manager/scheduler/execution.ts
|
|
7913
7633
|
import { createHash as createHash13 } from "crypto";
|
|
7914
|
-
import { homedir as
|
|
7915
|
-
import { join as
|
|
7634
|
+
import { homedir as homedir15 } from "os";
|
|
7635
|
+
import { join as join33 } from "path";
|
|
7916
7636
|
|
|
7917
7637
|
// src/lib/agent-serving-probe.ts
|
|
7918
|
-
import { readFileSync as
|
|
7919
|
-
import { join as
|
|
7638
|
+
import { readFileSync as readFileSync24, readdirSync as readdirSync5, statSync as statSync5 } from "fs";
|
|
7639
|
+
import { join as join32 } from "path";
|
|
7920
7640
|
var RATE_LIMIT_WINDOW_MS = 6 * 60 * 60 * 1e3;
|
|
7921
7641
|
function probeRateLimit(args) {
|
|
7922
7642
|
const now = args.now ?? /* @__PURE__ */ new Date();
|
|
@@ -7925,14 +7645,14 @@ function probeRateLimit(args) {
|
|
|
7925
7645
|
const dir = args.transcriptDir ?? sessionTranscriptDir(args.projectDir);
|
|
7926
7646
|
let entries;
|
|
7927
7647
|
try {
|
|
7928
|
-
entries =
|
|
7648
|
+
entries = readdirSync5(dir);
|
|
7929
7649
|
} catch {
|
|
7930
7650
|
return UNKNOWN_RATE_LIMIT;
|
|
7931
7651
|
}
|
|
7932
7652
|
let newest = UNKNOWN_RATE_LIMIT;
|
|
7933
7653
|
for (const name of entries) {
|
|
7934
7654
|
if (!name.endsWith(".jsonl")) continue;
|
|
7935
|
-
const path =
|
|
7655
|
+
const path = join32(dir, name);
|
|
7936
7656
|
try {
|
|
7937
7657
|
const st = statSync5(path);
|
|
7938
7658
|
if (!st.isFile() || st.mtimeMs < startMs) continue;
|
|
@@ -7941,7 +7661,7 @@ function probeRateLimit(args) {
|
|
|
7941
7661
|
}
|
|
7942
7662
|
let content;
|
|
7943
7663
|
try {
|
|
7944
|
-
content =
|
|
7664
|
+
content = readFileSync24(path, "utf-8");
|
|
7945
7665
|
} catch {
|
|
7946
7666
|
continue;
|
|
7947
7667
|
}
|
|
@@ -8003,7 +7723,7 @@ function shouldLogUsageCapDeferral(site, codeName, limitedUntil) {
|
|
|
8003
7723
|
|
|
8004
7724
|
// src/lib/manager/scheduler/execution.ts
|
|
8005
7725
|
function claudePidFilePath() {
|
|
8006
|
-
return
|
|
7726
|
+
return join33(homedir15(), ".augmented", "manager-claude-pids.json");
|
|
8007
7727
|
}
|
|
8008
7728
|
var inFlightClaudePids = /* @__PURE__ */ new Map();
|
|
8009
7729
|
function registerClaudeSpawn(record) {
|
|
@@ -8073,8 +7793,8 @@ async function syncAndCheckClaudeScheduler(agent, tasks, boardItems, refreshData
|
|
|
8073
7793
|
}
|
|
8074
7794
|
|
|
8075
7795
|
// src/lib/occupancy-gate.ts
|
|
8076
|
-
import { closeSync as closeSync2, openSync as openSync2, readdirSync as
|
|
8077
|
-
import { join as
|
|
7796
|
+
import { closeSync as closeSync2, openSync as openSync2, readdirSync as readdirSync6, readSync as readSync2, statSync as statSync6 } from "fs";
|
|
7797
|
+
import { join as join34 } from "path";
|
|
8078
7798
|
function rostersMeasuredZero(mode, attested, runtimeRunning) {
|
|
8079
7799
|
return mode === "enforce" && attested && runtimeRunning;
|
|
8080
7800
|
}
|
|
@@ -8083,7 +7803,7 @@ var MAX_RECORD_ALIGN_BYTES = 8 * 1024 * 1024;
|
|
|
8083
7803
|
var GATE_MAX_BUCKET_AGE_MS = 30 * 6e4;
|
|
8084
7804
|
var MAX_BRACKET_DEFERRAL_MS = 25 * 6e4;
|
|
8085
7805
|
var TRANSCRIPT_MTIME_WINDOW_MS4 = GATE_MAX_BUCKET_AGE_MS + DEFAULT_NEIGHBOURHOOD_MS + 6e4;
|
|
8086
|
-
var
|
|
7806
|
+
var cache = /* @__PURE__ */ new Map();
|
|
8087
7807
|
var brackets = /* @__PURE__ */ new Map();
|
|
8088
7808
|
function readAlignedTail(path, tailBytes, maxAlignBytes) {
|
|
8089
7809
|
let fd = null;
|
|
@@ -8158,26 +7878,26 @@ function candidateTranscriptPaths(dir) {
|
|
|
8158
7878
|
const paths = [];
|
|
8159
7879
|
let top;
|
|
8160
7880
|
try {
|
|
8161
|
-
top =
|
|
7881
|
+
top = readdirSync6(dir);
|
|
8162
7882
|
} catch {
|
|
8163
7883
|
return { paths, complete: false };
|
|
8164
7884
|
}
|
|
8165
7885
|
let complete = true;
|
|
8166
7886
|
for (const name of top) {
|
|
8167
7887
|
if (name.endsWith(".jsonl")) {
|
|
8168
|
-
paths.push(
|
|
7888
|
+
paths.push(join34(dir, name));
|
|
8169
7889
|
continue;
|
|
8170
7890
|
}
|
|
8171
|
-
const subDir =
|
|
7891
|
+
const subDir = join34(dir, name, "subagents");
|
|
8172
7892
|
let subs;
|
|
8173
7893
|
try {
|
|
8174
|
-
subs =
|
|
7894
|
+
subs = readdirSync6(subDir);
|
|
8175
7895
|
} catch (err) {
|
|
8176
7896
|
if (!isAbsentDirError(err)) complete = false;
|
|
8177
7897
|
continue;
|
|
8178
7898
|
}
|
|
8179
7899
|
for (const sub of subs) {
|
|
8180
|
-
if (sub.endsWith(".jsonl")) paths.push(
|
|
7900
|
+
if (sub.endsWith(".jsonl")) paths.push(join34(subDir, sub));
|
|
8181
7901
|
}
|
|
8182
7902
|
}
|
|
8183
7903
|
return { paths, complete };
|
|
@@ -8218,7 +7938,7 @@ function collectQualifyingTurns(codeName, nowMs, opts = {}) {
|
|
|
8218
7938
|
const tailBytes = opts.tailBytes ?? TAIL_BYTES;
|
|
8219
7939
|
const maxAlignBytes = opts.maxAlignBytes ?? MAX_RECORD_ALIGN_BYTES;
|
|
8220
7940
|
const sinceMs = nowMs - TRANSCRIPT_MTIME_WINDOW_MS4;
|
|
8221
|
-
const agentCache =
|
|
7941
|
+
const agentCache = cache.get(codeName) ?? /* @__PURE__ */ new Map();
|
|
8222
7942
|
const nextCache = /* @__PURE__ */ new Map();
|
|
8223
7943
|
const all = /* @__PURE__ */ new Set();
|
|
8224
7944
|
const eventsByPath = /* @__PURE__ */ new Map();
|
|
@@ -8271,7 +7991,7 @@ function collectQualifyingTurns(codeName, nowMs, opts = {}) {
|
|
|
8271
7991
|
}
|
|
8272
7992
|
for (const t of turns) all.add(t);
|
|
8273
7993
|
}
|
|
8274
|
-
|
|
7994
|
+
cache.set(codeName, nextCache);
|
|
8275
7995
|
const { toolCallBrackets, openToolCalls } = foldToolCallBrackets(codeName, eventsByPath, nowMs);
|
|
8276
7996
|
return {
|
|
8277
7997
|
turns: [...all].sort((a, b) => a - b),
|
|
@@ -8404,7 +8124,7 @@ function stopPaneOccupancySampler() {
|
|
|
8404
8124
|
|
|
8405
8125
|
// src/lib/pid-pressure-sampler.ts
|
|
8406
8126
|
import { execFileSync as execFileSync2 } from "child_process";
|
|
8407
|
-
import { existsSync as
|
|
8127
|
+
import { existsSync as existsSync13, readFileSync as readFileSync25 } from "fs";
|
|
8408
8128
|
var SAMPLE_INTERVAL_MS2 = 3e4;
|
|
8409
8129
|
function warnFraction() {
|
|
8410
8130
|
const raw = Number(process.env.AGT_PID_PRESSURE_WARN_FRACTION);
|
|
@@ -8417,7 +8137,7 @@ function configuredCeiling() {
|
|
|
8417
8137
|
}
|
|
8418
8138
|
function readTextReal(path) {
|
|
8419
8139
|
try {
|
|
8420
|
-
return
|
|
8140
|
+
return readFileSync25(path, "utf-8");
|
|
8421
8141
|
} catch {
|
|
8422
8142
|
return null;
|
|
8423
8143
|
}
|
|
@@ -8426,7 +8146,7 @@ var cgroupDirCache = /* @__PURE__ */ new Map();
|
|
|
8426
8146
|
var resolveRetryAfter = /* @__PURE__ */ new Map();
|
|
8427
8147
|
var RESOLVE_RETRY_BACKOFF_MS = 5 * 6e4;
|
|
8428
8148
|
function resolveCgroupDirReal(codeName, deps = {}) {
|
|
8429
|
-
const exists = deps.exists ??
|
|
8149
|
+
const exists = deps.exists ?? existsSync13;
|
|
8430
8150
|
const inspectId = deps.inspectId ?? inspectContainerId;
|
|
8431
8151
|
const now = deps.now ?? Date.now;
|
|
8432
8152
|
const cached = cgroupDirCache.get(codeName);
|
|
@@ -9725,9 +9445,9 @@ async function fireOpencodeScheduledTask(agent, task) {
|
|
|
9725
9445
|
|
|
9726
9446
|
// src/lib/opencode-telegram-ingest.ts
|
|
9727
9447
|
import { createHash as createHash16 } from "crypto";
|
|
9728
|
-
import { existsSync as
|
|
9448
|
+
import { existsSync as existsSync14, mkdirSync as mkdirSync8, readFileSync as readFileSync26, renameSync as renameSync6, unlinkSync as unlinkSync4, writeFileSync as writeFileSync12 } from "fs";
|
|
9729
9449
|
import { randomUUID } from "crypto";
|
|
9730
|
-
import { join as
|
|
9450
|
+
import { join as join35 } from "path";
|
|
9731
9451
|
|
|
9732
9452
|
// src/lib/telegram-ingest.ts
|
|
9733
9453
|
import https2 from "https";
|
|
@@ -10275,7 +9995,7 @@ function createFileOffsetStore(codeName, log2, currentBotId) {
|
|
|
10275
9995
|
let filePath;
|
|
10276
9996
|
try {
|
|
10277
9997
|
dir = getFramework("opencode").getAgentDir(codeName);
|
|
10278
|
-
filePath =
|
|
9998
|
+
filePath = join35(dir, "telegram-getupdates-offset-opencode.json");
|
|
10279
9999
|
} catch {
|
|
10280
10000
|
dir = null;
|
|
10281
10001
|
filePath = null;
|
|
@@ -10284,7 +10004,7 @@ function createFileOffsetStore(codeName, log2, currentBotId) {
|
|
|
10284
10004
|
load() {
|
|
10285
10005
|
if (!filePath) return 0;
|
|
10286
10006
|
try {
|
|
10287
|
-
const parsed = JSON.parse(
|
|
10007
|
+
const parsed = JSON.parse(readFileSync26(filePath, "utf-8"));
|
|
10288
10008
|
if (currentBotId != null && typeof parsed?.bot_id === "number" && parsed.bot_id !== currentBotId) {
|
|
10289
10009
|
log2(`[telegram-ingest:${codeName}] offset cursor belongs to a different bot; ignoring (bot swap)`);
|
|
10290
10010
|
return 0;
|
|
@@ -10317,7 +10037,7 @@ function createFileOffsetStore(codeName, log2, currentBotId) {
|
|
|
10317
10037
|
} catch (err) {
|
|
10318
10038
|
log2(`[telegram-ingest:${codeName}] offset persist failed: ${err instanceof Error ? err.message : String(err)}`);
|
|
10319
10039
|
try {
|
|
10320
|
-
if (
|
|
10040
|
+
if (existsSync14(tmpPath)) unlinkSync4(tmpPath);
|
|
10321
10041
|
} catch {
|
|
10322
10042
|
}
|
|
10323
10043
|
}
|
|
@@ -10554,24 +10274,24 @@ function partitionActionableByPoison(actionable, states, config2) {
|
|
|
10554
10274
|
}
|
|
10555
10275
|
|
|
10556
10276
|
// src/lib/restart-flags.ts
|
|
10557
|
-
import { existsSync as
|
|
10558
|
-
import { homedir as
|
|
10559
|
-
import { join as
|
|
10277
|
+
import { existsSync as existsSync15, mkdirSync as mkdirSync9, readdirSync as readdirSync7, readFileSync as readFileSync27, renameSync as renameSync7, rmSync as rmSync4, writeFileSync as writeFileSync13 } from "fs";
|
|
10278
|
+
import { homedir as homedir16 } from "os";
|
|
10279
|
+
import { join as join36 } from "path";
|
|
10560
10280
|
import { randomUUID as randomUUID2 } from "crypto";
|
|
10561
10281
|
function restartFlagsDir() {
|
|
10562
|
-
return
|
|
10282
|
+
return join36(homedir16(), ".augmented", "restart-flags");
|
|
10563
10283
|
}
|
|
10564
10284
|
function flagPath(codeName) {
|
|
10565
|
-
return
|
|
10285
|
+
return join36(restartFlagsDir(), `${codeName}.flag`);
|
|
10566
10286
|
}
|
|
10567
10287
|
function readRestartFlags() {
|
|
10568
10288
|
const dir = restartFlagsDir();
|
|
10569
|
-
if (!
|
|
10289
|
+
if (!existsSync15(dir)) return [];
|
|
10570
10290
|
const out = [];
|
|
10571
|
-
for (const entry of
|
|
10291
|
+
for (const entry of readdirSync7(dir)) {
|
|
10572
10292
|
if (!entry.endsWith(".flag")) continue;
|
|
10573
10293
|
try {
|
|
10574
|
-
const raw =
|
|
10294
|
+
const raw = readFileSync27(join36(dir, entry), "utf8");
|
|
10575
10295
|
const parsed = JSON.parse(raw);
|
|
10576
10296
|
if (typeof parsed.codeName !== "string" || parsed.codeName.length === 0) {
|
|
10577
10297
|
parsed.codeName = entry.replace(/\.flag$/, "");
|
|
@@ -10589,7 +10309,7 @@ function readRestartFlags() {
|
|
|
10589
10309
|
}
|
|
10590
10310
|
function deleteRestartFlag(codeName) {
|
|
10591
10311
|
const path = flagPath(codeName);
|
|
10592
|
-
if (
|
|
10312
|
+
if (existsSync15(path)) {
|
|
10593
10313
|
rmSync4(path, { force: true });
|
|
10594
10314
|
}
|
|
10595
10315
|
}
|
|
@@ -10689,8 +10409,8 @@ async function sendError(flag, opts, text) {
|
|
|
10689
10409
|
}
|
|
10690
10410
|
|
|
10691
10411
|
// src/lib/restart-context.ts
|
|
10692
|
-
import { readdirSync as
|
|
10693
|
-
import { dirname as
|
|
10412
|
+
import { readdirSync as readdirSync8, readFileSync as readFileSync28, writeFileSync as writeFileSync14, mkdirSync as mkdirSync10, unlinkSync as unlinkSync5 } from "fs";
|
|
10413
|
+
import { dirname as dirname9, join as join37 } from "path";
|
|
10694
10414
|
var SLACK_PENDING_INBOUND_DIRNAME = "slack-pending-inbound";
|
|
10695
10415
|
var SLACK_RESTART_CONTEXT_DIRNAME = "slack-restart-context";
|
|
10696
10416
|
var MAX_TOPIC_CHARS = 140;
|
|
@@ -10699,13 +10419,13 @@ var RECONSTRUCT_WINDOW_MS = 7 * 24 * 60 * 60 * 1e3;
|
|
|
10699
10419
|
var WINDOW_PAD_MS3 = 5 * 6e4;
|
|
10700
10420
|
var DEFAULT_MAX_MARKERS_PER_AGENT = 25;
|
|
10701
10421
|
function augmentedAgentDir(codeName) {
|
|
10702
|
-
return
|
|
10422
|
+
return dirname9(getProjectDir(codeName));
|
|
10703
10423
|
}
|
|
10704
10424
|
function slackPendingInboundDir(codeName) {
|
|
10705
|
-
return
|
|
10425
|
+
return join37(augmentedAgentDir(codeName), SLACK_PENDING_INBOUND_DIRNAME);
|
|
10706
10426
|
}
|
|
10707
10427
|
function slackRestartContextDir(codeName) {
|
|
10708
|
-
return
|
|
10428
|
+
return join37(augmentedAgentDir(codeName), SLACK_RESTART_CONTEXT_DIRNAME);
|
|
10709
10429
|
}
|
|
10710
10430
|
function sanitizeTopic(raw) {
|
|
10711
10431
|
const cleaned = raw.replace(/\s+/g, " ").trim().replace(/[<>]/g, " ").replace(/\s+/g, " ").trim();
|
|
@@ -10740,14 +10460,14 @@ function computeRestartContextHints(markers, allTurns, nowMs, reconstruct = reco
|
|
|
10740
10460
|
}
|
|
10741
10461
|
function safeReaddir(dir) {
|
|
10742
10462
|
try {
|
|
10743
|
-
return
|
|
10463
|
+
return readdirSync8(dir);
|
|
10744
10464
|
} catch {
|
|
10745
10465
|
return [];
|
|
10746
10466
|
}
|
|
10747
10467
|
}
|
|
10748
10468
|
function readStrandedMarker(path) {
|
|
10749
10469
|
try {
|
|
10750
|
-
const parsed = JSON.parse(
|
|
10470
|
+
const parsed = JSON.parse(readFileSync28(path, "utf-8"));
|
|
10751
10471
|
if (typeof parsed.channel === "string" && typeof parsed.thread_ts === "string") {
|
|
10752
10472
|
return { channel: parsed.channel, thread_ts: parsed.thread_ts };
|
|
10753
10473
|
}
|
|
@@ -10765,7 +10485,7 @@ function pruneHintsExcept(codeName, freshFilenames) {
|
|
|
10765
10485
|
if (!filename.endsWith(".json")) continue;
|
|
10766
10486
|
if (freshFilenames.has(filename)) continue;
|
|
10767
10487
|
try {
|
|
10768
|
-
unlinkSync5(
|
|
10488
|
+
unlinkSync5(join37(ctxDir, filename));
|
|
10769
10489
|
} catch {
|
|
10770
10490
|
}
|
|
10771
10491
|
}
|
|
@@ -10786,7 +10506,7 @@ function refreshSlackRestartContextHints(codeNames, opts = {}) {
|
|
|
10786
10506
|
}
|
|
10787
10507
|
const markers = [];
|
|
10788
10508
|
for (const filename of markerFilenames.slice(0, cap)) {
|
|
10789
|
-
const parsed = readStrandedMarker(
|
|
10509
|
+
const parsed = readStrandedMarker(join37(markerDir, filename));
|
|
10790
10510
|
if (parsed) markers.push({ filename, channel: parsed.channel, thread_ts: parsed.thread_ts });
|
|
10791
10511
|
}
|
|
10792
10512
|
if (markers.length === 0) {
|
|
@@ -10800,7 +10520,7 @@ function refreshSlackRestartContextHints(codeNames, opts = {}) {
|
|
|
10800
10520
|
const freshFilenames = /* @__PURE__ */ new Set();
|
|
10801
10521
|
for (const { filename, hint } of hints) {
|
|
10802
10522
|
try {
|
|
10803
|
-
writeHintFile(
|
|
10523
|
+
writeHintFile(join37(ctxDir, filename), ctxDir, hint);
|
|
10804
10524
|
freshFilenames.add(filename);
|
|
10805
10525
|
} catch (err) {
|
|
10806
10526
|
log2(`[restart-context] ${codeName}: hint write failed for ${filename}: ${err.message}`);
|
|
@@ -12178,8 +11898,8 @@ var pendingDayRolloverReset = /* @__PURE__ */ new Set();
|
|
|
12178
11898
|
var dayRolloverInboundHold = /* @__PURE__ */ new Map();
|
|
12179
11899
|
var INBOUND_HOLD_EPISODE_GAP_MS = 12e4;
|
|
12180
11900
|
async function channelInboundActivityAgeSecondsFor(codeName) {
|
|
12181
|
-
const { newestPendingInboundActivityMtimeMs } = await import("../responsiveness-probe-
|
|
12182
|
-
const newest = newestPendingInboundActivityMtimeMs(
|
|
11901
|
+
const { newestPendingInboundActivityMtimeMs } = await import("../responsiveness-probe-A5335ORT.js");
|
|
11902
|
+
const newest = newestPendingInboundActivityMtimeMs(dirname10(paneLogPath(codeName)));
|
|
12183
11903
|
if (newest === null) return null;
|
|
12184
11904
|
return Math.max(0, Math.floor((Date.now() - newest) / 1e3));
|
|
12185
11905
|
}
|
|
@@ -12428,7 +12148,7 @@ var runningChannelSecretHashes = /* @__PURE__ */ new Map();
|
|
|
12428
12148
|
var sessionLaunchManagedStructure = /* @__PURE__ */ new Map();
|
|
12429
12149
|
function projectMcpHash(_codeName, projectDir) {
|
|
12430
12150
|
try {
|
|
12431
|
-
const raw =
|
|
12151
|
+
const raw = readFileSync29(join38(projectDir, ".mcp.json"), "utf-8");
|
|
12432
12152
|
return createHash17("sha256").update(canonicalJson(JSON.parse(raw))).digest("hex");
|
|
12433
12153
|
} catch {
|
|
12434
12154
|
return null;
|
|
@@ -12436,7 +12156,7 @@ function projectMcpHash(_codeName, projectDir) {
|
|
|
12436
12156
|
}
|
|
12437
12157
|
function projectMcpKeys(_codeName, projectDir) {
|
|
12438
12158
|
try {
|
|
12439
|
-
const raw =
|
|
12159
|
+
const raw = readFileSync29(join38(projectDir, ".mcp.json"), "utf-8");
|
|
12440
12160
|
const parsed = JSON.parse(raw);
|
|
12441
12161
|
const servers = parsed.mcpServers;
|
|
12442
12162
|
if (!servers || typeof servers !== "object") return /* @__PURE__ */ new Set();
|
|
@@ -12454,7 +12174,7 @@ function seedSessionLaunchBaselines(codeName, projectDir) {
|
|
|
12454
12174
|
else runningMcpServerKeys.delete(codeName);
|
|
12455
12175
|
let launchStructure = null;
|
|
12456
12176
|
try {
|
|
12457
|
-
const raw =
|
|
12177
|
+
const raw = readFileSync29(join38(projectDir, ".mcp.json"), "utf-8");
|
|
12458
12178
|
launchStructure = managedMcpStructureHashFromFile(
|
|
12459
12179
|
JSON.parse(raw),
|
|
12460
12180
|
isManagedMcpServerKey
|
|
@@ -12580,7 +12300,7 @@ async function runAgentSessionToolBindProbes(agent, integrations, projectDir, op
|
|
|
12580
12300
|
if (result && result.rebindCandidates.length > 0 && hostFlagStore().getBoolean("session-tool-rebind")) {
|
|
12581
12301
|
let mcpJsonForRebind = null;
|
|
12582
12302
|
try {
|
|
12583
|
-
mcpJsonForRebind = JSON.parse(
|
|
12303
|
+
mcpJsonForRebind = JSON.parse(readFileSync29(join38(projectDir, ".mcp.json"), "utf-8"));
|
|
12584
12304
|
} catch {
|
|
12585
12305
|
mcpJsonForRebind = null;
|
|
12586
12306
|
}
|
|
@@ -12728,7 +12448,7 @@ function shouldInjectChannelSecrets(agentId) {
|
|
|
12728
12448
|
function projectChannelSecretHash(projectDir) {
|
|
12729
12449
|
try {
|
|
12730
12450
|
const entries = parseEnvIntegrations(
|
|
12731
|
-
|
|
12451
|
+
readFileSync29(join38(projectDir, ".env.integrations"), "utf-8")
|
|
12732
12452
|
);
|
|
12733
12453
|
return channelSecretValueHash(entries, CHANNEL_SECRET_ENV_KEYS);
|
|
12734
12454
|
} catch {
|
|
@@ -12826,7 +12546,7 @@ var agentRestartTimezoneInputs = /* @__PURE__ */ new Map();
|
|
|
12826
12546
|
var lastVersionCheckAt = 0;
|
|
12827
12547
|
var VERSION_CHECK_INTERVAL_MS = 5 * 60 * 1e3;
|
|
12828
12548
|
var lastResponsivenessProbeAt = 0;
|
|
12829
|
-
var agtCliVersion = true ? "0.28.
|
|
12549
|
+
var agtCliVersion = true ? "0.28.716" : "dev";
|
|
12830
12550
|
function resolveBrewPath(execFileSync3) {
|
|
12831
12551
|
try {
|
|
12832
12552
|
const out = execFileSync3("which", ["brew"], { timeout: 5e3 }).toString().trim();
|
|
@@ -12839,7 +12559,7 @@ function resolveBrewPath(execFileSync3) {
|
|
|
12839
12559
|
"/usr/local/bin/brew"
|
|
12840
12560
|
];
|
|
12841
12561
|
for (const path of fallbacks) {
|
|
12842
|
-
if (
|
|
12562
|
+
if (existsSync16(path)) return path;
|
|
12843
12563
|
}
|
|
12844
12564
|
return null;
|
|
12845
12565
|
}
|
|
@@ -12849,7 +12569,7 @@ function claudeBinaryInstalled(execFileSync3) {
|
|
|
12849
12569
|
"/opt/homebrew/bin/claude",
|
|
12850
12570
|
"/usr/local/bin/claude"
|
|
12851
12571
|
];
|
|
12852
|
-
if (canonical.some((path) =>
|
|
12572
|
+
if (canonical.some((path) => existsSync16(path))) return true;
|
|
12853
12573
|
try {
|
|
12854
12574
|
execFileSync3("which", ["claude"], { timeout: 5e3 });
|
|
12855
12575
|
return true;
|
|
@@ -12921,7 +12641,7 @@ async function ensureToolkitCli(toolkitSlug) {
|
|
|
12921
12641
|
toolkitCliEnsured.add(toolkitSlug);
|
|
12922
12642
|
return;
|
|
12923
12643
|
}
|
|
12924
|
-
brewBinDir =
|
|
12644
|
+
brewBinDir = dirname10(brewPath);
|
|
12925
12645
|
const isRoot = typeof process.getuid === "function" && process.getuid() === 0;
|
|
12926
12646
|
log(`[toolkit-install] ${toolkitSlug}: installing via brew (${pkg})\u2026`);
|
|
12927
12647
|
if (isRoot) {
|
|
@@ -13114,8 +12834,8 @@ async function reapSupersededRuntimeImages(imageUri, localTag) {
|
|
|
13114
12834
|
}
|
|
13115
12835
|
function runAsync(cmd, args, opts) {
|
|
13116
12836
|
return new Promise((resolve2, reject) => {
|
|
13117
|
-
import("child_process").then(({ spawn
|
|
13118
|
-
const child =
|
|
12837
|
+
import("child_process").then(({ spawn }) => {
|
|
12838
|
+
const child = spawn(cmd, args, { stdio: ["ignore", "pipe", "pipe"], cwd: opts.cwd });
|
|
13119
12839
|
let stdout = "";
|
|
13120
12840
|
let stderr = "";
|
|
13121
12841
|
let settled = false;
|
|
@@ -13159,8 +12879,8 @@ var MANAGED_SETTINGS_KEYS = ["channelsEnabled", "enableAllProjectMcpServers"];
|
|
|
13159
12879
|
function ensureClaudeManagedSettings(path = claudeManagedSettingsPath()) {
|
|
13160
12880
|
try {
|
|
13161
12881
|
let settings = {};
|
|
13162
|
-
if (
|
|
13163
|
-
const raw =
|
|
12882
|
+
if (existsSync16(path)) {
|
|
12883
|
+
const raw = readFileSync29(path, "utf-8").trim();
|
|
13164
12884
|
if (raw) {
|
|
13165
12885
|
let parsed;
|
|
13166
12886
|
try {
|
|
@@ -13177,7 +12897,7 @@ function ensureClaudeManagedSettings(path = claudeManagedSettingsPath()) {
|
|
|
13177
12897
|
const missing = MANAGED_SETTINGS_KEYS.filter((key) => settings[key] !== true);
|
|
13178
12898
|
if (missing.length === 0) return "ok";
|
|
13179
12899
|
for (const key of missing) settings[key] = true;
|
|
13180
|
-
mkdirSync11(
|
|
12900
|
+
mkdirSync11(dirname10(path), { recursive: true });
|
|
13181
12901
|
writeFileSync15(path, `${JSON.stringify(settings, null, 2)}
|
|
13182
12902
|
`);
|
|
13183
12903
|
log(`[managed-settings] set ${missing.map((k) => `${k}:true`).join(", ")} in ${path} (ENG-5786 unblocks Claude Code channels; ENG-9223 pre-approves project MCP servers so a headless session never freezes on the trust prompt)`);
|
|
@@ -13216,7 +12936,7 @@ async function ensureOpencodeBinary() {
|
|
|
13216
12936
|
try {
|
|
13217
12937
|
const prefix = execFileSync3("npm", ["prefix", "-g"], { encoding: "utf-8", timeout: 1e4 }).trim();
|
|
13218
12938
|
if (prefix) {
|
|
13219
|
-
const npmBin =
|
|
12939
|
+
const npmBin = join38(prefix, "bin");
|
|
13220
12940
|
const current = (process.env.PATH ?? "").split(pathDelimiter);
|
|
13221
12941
|
if (!current.includes(npmBin)) {
|
|
13222
12942
|
process.env.PATH = [npmBin, ...current.filter(Boolean)].join(pathDelimiter);
|
|
@@ -13273,11 +12993,11 @@ async function ensureFrameworkBinary(frameworkId) {
|
|
|
13273
12993
|
log(`Claude Code install failed: ${err.message}`);
|
|
13274
12994
|
return;
|
|
13275
12995
|
}
|
|
13276
|
-
const brewBinDir =
|
|
12996
|
+
const brewBinDir = dirname10(brewPath);
|
|
13277
12997
|
if (!process.env.PATH?.split(":").includes(brewBinDir)) {
|
|
13278
12998
|
process.env.PATH = `${brewBinDir}:${process.env.PATH ?? ""}`;
|
|
13279
12999
|
}
|
|
13280
|
-
if (
|
|
13000
|
+
if (existsSync16("/home/linuxbrew/.linuxbrew/bin/claude")) {
|
|
13281
13001
|
log("Claude Code installed successfully");
|
|
13282
13002
|
} else {
|
|
13283
13003
|
log("Claude Code install completed but binary not found at expected path \u2014 check brew logs");
|
|
@@ -13333,7 +13053,7 @@ ${r.stderr}`;
|
|
|
13333
13053
|
}
|
|
13334
13054
|
var UPDATE_CHECK_INTERVAL_MS = 5 * 60 * 1e3;
|
|
13335
13055
|
function selfUpdateAppliedMarkerPath() {
|
|
13336
|
-
return
|
|
13056
|
+
return join38(homedir17(), ".augmented", ".last-self-update-applied");
|
|
13337
13057
|
}
|
|
13338
13058
|
var selfUpdateUpToDateLogged = false;
|
|
13339
13059
|
var selfUpdatePinnedLogged = false;
|
|
@@ -13384,7 +13104,7 @@ async function checkAndUpdateCli(opts) {
|
|
|
13384
13104
|
const isNpmGlobal = !isBrewFormula && resolvedPath.includes("node_modules");
|
|
13385
13105
|
if (!isBrewFormula && !isNpmGlobal) return "noop";
|
|
13386
13106
|
const { readFileSync: readF, writeFileSync: writeF } = await import("fs");
|
|
13387
|
-
const markerPath =
|
|
13107
|
+
const markerPath = join38(homedir17(), ".augmented", ".last-update-check");
|
|
13388
13108
|
if (!force) {
|
|
13389
13109
|
try {
|
|
13390
13110
|
const lastCheck = parseInt(readF(markerPath, "utf-8").trim(), 10);
|
|
@@ -13791,7 +13511,7 @@ async function runClaudeRuntimeAuthProbe() {
|
|
|
13791
13511
|
];
|
|
13792
13512
|
try {
|
|
13793
13513
|
const { stdout, stderr } = await execFilePromiseLong(resolveClaudeBinary(), args, {
|
|
13794
|
-
cwd:
|
|
13514
|
+
cwd: homedir17(),
|
|
13795
13515
|
timeout: RUNTIME_AUTH_PROBE_TIMEOUT_MS,
|
|
13796
13516
|
stdin: "ignore",
|
|
13797
13517
|
env: childEnv,
|
|
@@ -13831,7 +13551,7 @@ async function runHostUsageCommand() {
|
|
|
13831
13551
|
""
|
|
13832
13552
|
];
|
|
13833
13553
|
const { stdout } = await execFilePromiseLong(resolveClaudeBinary(), args, {
|
|
13834
|
-
cwd:
|
|
13554
|
+
cwd: homedir17(),
|
|
13835
13555
|
timeout: HOST_USAGE_POLL_TIMEOUT_MS,
|
|
13836
13556
|
stdin: "ignore",
|
|
13837
13557
|
env: childEnv,
|
|
@@ -13877,13 +13597,13 @@ async function checkClaudeAuth() {
|
|
|
13877
13597
|
}
|
|
13878
13598
|
var evalEmptyMcpConfigPath = null;
|
|
13879
13599
|
function ensureEvalEmptyMcpConfig() {
|
|
13880
|
-
if (evalEmptyMcpConfigPath &&
|
|
13881
|
-
const dir =
|
|
13600
|
+
if (evalEmptyMcpConfigPath && existsSync16(evalEmptyMcpConfigPath)) return evalEmptyMcpConfigPath;
|
|
13601
|
+
const dir = join38(homedir17(), ".augmented");
|
|
13882
13602
|
try {
|
|
13883
13603
|
mkdirSync11(dir, { recursive: true });
|
|
13884
13604
|
} catch {
|
|
13885
13605
|
}
|
|
13886
|
-
const p =
|
|
13606
|
+
const p = join38(dir, ".eval-empty-mcp.json");
|
|
13887
13607
|
writeFileSync15(p, JSON.stringify({ mcpServers: {} }));
|
|
13888
13608
|
evalEmptyMcpConfigPath = p;
|
|
13889
13609
|
return p;
|
|
@@ -13909,7 +13629,7 @@ async function runEvalClaude(prompt, model) {
|
|
|
13909
13629
|
""
|
|
13910
13630
|
];
|
|
13911
13631
|
const { stdout } = await execFilePromiseLong(resolveClaudeBinary(), args, {
|
|
13912
|
-
cwd:
|
|
13632
|
+
cwd: homedir17(),
|
|
13913
13633
|
timeout: 12e4,
|
|
13914
13634
|
stdin: "ignore",
|
|
13915
13635
|
env: childEnv,
|
|
@@ -13978,10 +13698,10 @@ function resolveConversationEvalBackend() {
|
|
|
13978
13698
|
return conversationEvalBackend;
|
|
13979
13699
|
}
|
|
13980
13700
|
function getStateFile() {
|
|
13981
|
-
return
|
|
13701
|
+
return join38(config?.configDir ?? join38(process.env["HOME"] ?? "/tmp", ".augmented"), "manager-state.json");
|
|
13982
13702
|
}
|
|
13983
13703
|
function channelHashCacheDir() {
|
|
13984
|
-
return config?.configDir ??
|
|
13704
|
+
return config?.configDir ?? join38(process.env["HOME"] ?? "/tmp", ".augmented");
|
|
13985
13705
|
}
|
|
13986
13706
|
function loadChannelHashCache2() {
|
|
13987
13707
|
loadChannelHashCache(agentState.knownChannelConfigHashes, channelHashCacheDir());
|
|
@@ -14186,7 +13906,7 @@ function removeDeliveryBaselineEntries(agentId) {
|
|
|
14186
13906
|
var _channelQuarantineStore = null;
|
|
14187
13907
|
function channelQuarantineStore() {
|
|
14188
13908
|
if (!_channelQuarantineStore) {
|
|
14189
|
-
const dir = config?.configDir ??
|
|
13909
|
+
const dir = config?.configDir ?? join38(process.env["HOME"] ?? "/tmp", ".augmented");
|
|
14190
13910
|
_channelQuarantineStore = new ChannelQuarantineStore(defaultQuarantinePath(dir));
|
|
14191
13911
|
}
|
|
14192
13912
|
return _channelQuarantineStore;
|
|
@@ -14202,12 +13922,12 @@ function claudeMdSizeFor(codeName) {
|
|
|
14202
13922
|
}
|
|
14203
13923
|
function forwardedToolsFor(codeName) {
|
|
14204
13924
|
if (!config?.configDir) return null;
|
|
14205
|
-
return readForwardedToolsReport(
|
|
13925
|
+
return readForwardedToolsReport(join38(config.configDir, codeName));
|
|
14206
13926
|
}
|
|
14207
13927
|
var _hostFlagStore = null;
|
|
14208
13928
|
function hostFlagStore() {
|
|
14209
13929
|
if (!_hostFlagStore) {
|
|
14210
|
-
const dir = config?.configDir ??
|
|
13930
|
+
const dir = config?.configDir ?? join38(process.env["HOME"] ?? "/tmp", ".augmented");
|
|
14211
13931
|
_hostFlagStore = new HostFlagStore({ cachePath: defaultFlagsCachePath(dir), log });
|
|
14212
13932
|
}
|
|
14213
13933
|
return _hostFlagStore;
|
|
@@ -14280,13 +14000,13 @@ function parseSkillFrontmatter(content) {
|
|
|
14280
14000
|
return out;
|
|
14281
14001
|
}
|
|
14282
14002
|
async function refreshSkillsIndexInClaudeMd(configDir, codeName, log2) {
|
|
14283
|
-
const { readdirSync:
|
|
14284
|
-
const skillsDir =
|
|
14285
|
-
const claudeMdPath =
|
|
14003
|
+
const { readdirSync: readdirSync10, readFileSync: rfs, existsSync: ex, writeFileSync: writeFileSync16 } = await import("fs");
|
|
14004
|
+
const skillsDir = join38(configDir, codeName, "project", ".claude", "skills");
|
|
14005
|
+
const claudeMdPath = join38(configDir, codeName, "project", "CLAUDE.md");
|
|
14286
14006
|
if (!ex(skillsDir) || !ex(claudeMdPath)) return;
|
|
14287
14007
|
const entries = [];
|
|
14288
|
-
for (const dir of
|
|
14289
|
-
const skillFile =
|
|
14008
|
+
for (const dir of readdirSync10(skillsDir).sort()) {
|
|
14009
|
+
const skillFile = join38(skillsDir, dir, "SKILL.md");
|
|
14290
14010
|
if (!ex(skillFile)) continue;
|
|
14291
14011
|
try {
|
|
14292
14012
|
const { name, description } = parseSkillFrontmatter(rfs(skillFile, "utf-8"));
|
|
@@ -14353,7 +14073,7 @@ function flushRestartedAgentDiagnostics(hostId, codeNames) {
|
|
|
14353
14073
|
if (codeNames.length === 0) return;
|
|
14354
14074
|
void (async () => {
|
|
14355
14075
|
try {
|
|
14356
|
-
const { collectDiagnostics } = await import("../persistent-session-
|
|
14076
|
+
const { collectDiagnostics } = await import("../persistent-session-DJSSEIR6.js");
|
|
14357
14077
|
await api.post("/host/heartbeat", {
|
|
14358
14078
|
host_id: hostId,
|
|
14359
14079
|
agent_diagnostics: collectDiagnostics(codeNames, quarantineEntriesFor, claudeMdSizeFor, spawnOutcomeForDiagnostics, pidPressureFor, forwardedToolsFor)
|
|
@@ -14471,7 +14191,7 @@ async function pollCycleInner() {
|
|
|
14471
14191
|
}
|
|
14472
14192
|
try {
|
|
14473
14193
|
const { detectHostSecurity } = await import("../host-security-6PDFG7F5.js");
|
|
14474
|
-
const { collectDiagnostics } = await import("../persistent-session-
|
|
14194
|
+
const { collectDiagnostics } = await import("../persistent-session-DJSSEIR6.js");
|
|
14475
14195
|
const diagCodeNames = [...agentState.persistentSessionAgents];
|
|
14476
14196
|
const agentDiagnostics = diagCodeNames.length > 0 ? collectDiagnostics(diagCodeNames, quarantineEntriesFor, claudeMdSizeFor, spawnOutcomeForDiagnostics, pidPressureFor, forwardedToolsFor) : void 0;
|
|
14477
14197
|
let tailscaleHostname;
|
|
@@ -14640,7 +14360,7 @@ async function pollCycleInner() {
|
|
|
14640
14360
|
collectPanelessActivityProbes,
|
|
14641
14361
|
getResponsivenessIntervalMs,
|
|
14642
14362
|
occupancyQualificationClassifications
|
|
14643
|
-
} = await import("../responsiveness-probe-
|
|
14363
|
+
} = await import("../responsiveness-probe-A5335ORT.js");
|
|
14644
14364
|
const probeIntervalMs = getResponsivenessIntervalMs();
|
|
14645
14365
|
if (now - lastResponsivenessProbeAt > probeIntervalMs) {
|
|
14646
14366
|
const probeCodeNames = [...agentState.persistentSessionAgents];
|
|
@@ -14750,7 +14470,7 @@ async function pollCycleInner() {
|
|
|
14750
14470
|
collectResponsivenessProbes,
|
|
14751
14471
|
livePendingInboundOldestAgeSeconds,
|
|
14752
14472
|
parkPendingInbound
|
|
14753
|
-
} = await import("../responsiveness-probe-
|
|
14473
|
+
} = await import("../responsiveness-probe-A5335ORT.js");
|
|
14754
14474
|
const { getProjectDir: wedgeProjectDir } = await import("../scheduler-engine-NDP36U7O.js");
|
|
14755
14475
|
const wedgeNow = /* @__PURE__ */ new Date();
|
|
14756
14476
|
const liveAgents = agentState.persistentSessionAgents;
|
|
@@ -14839,13 +14559,13 @@ async function pollCycleInner() {
|
|
|
14839
14559
|
);
|
|
14840
14560
|
if (hostFlagStore().getBoolean("wedge-transient-notice")) {
|
|
14841
14561
|
try {
|
|
14842
|
-
const paneTail =
|
|
14562
|
+
const paneTail = readFileSync29(paneLogPath(codeName), "utf8").slice(-65536);
|
|
14843
14563
|
const transient = detectTransientApiErrorInLog(paneTail);
|
|
14844
14564
|
if (transient) {
|
|
14845
|
-
const wedgeHome =
|
|
14846
|
-
if (
|
|
14565
|
+
const wedgeHome = join38(homedir17(), ".augmented", codeName);
|
|
14566
|
+
if (existsSync16(wedgeHome)) {
|
|
14847
14567
|
atomicWriteFileSync(
|
|
14848
|
-
|
|
14568
|
+
join38(wedgeHome, "watchdog-give-up.json"),
|
|
14849
14569
|
JSON.stringify({
|
|
14850
14570
|
gave_up_at: wedgeNow.toISOString(),
|
|
14851
14571
|
reason: "transient_overload"
|
|
@@ -14906,7 +14626,7 @@ async function pollCycleInner() {
|
|
|
14906
14626
|
}
|
|
14907
14627
|
try {
|
|
14908
14628
|
const { scrapeMcpFailedBannerCount } = await import("../pane-mcp-banner-scraper-JA437JIB.js");
|
|
14909
|
-
const { probeSessionAuth } = await import("../session-auth-dead-
|
|
14629
|
+
const { probeSessionAuth } = await import("../session-auth-dead-KUYVUOK5.js");
|
|
14910
14630
|
const observations = [];
|
|
14911
14631
|
const pendingCacheCommits = [];
|
|
14912
14632
|
const modelApiErrorReportingOn = hostFlagStore().getBoolean("model-api-error-reporting");
|
|
@@ -15161,7 +14881,7 @@ async function pollCycleInner() {
|
|
|
15161
14881
|
`[drain-flush] FAILED for '${prev.codeName}': ${err.message} \u2014 proceeding to teardown; this session was NOT shipped (ENG-9491)`
|
|
15162
14882
|
);
|
|
15163
14883
|
}
|
|
15164
|
-
const agentDir =
|
|
14884
|
+
const agentDir = join38(adapter.getAgentDir(prev.codeName), "provision");
|
|
15165
14885
|
await cleanupAgentFiles(prev.codeName, agentDir);
|
|
15166
14886
|
clearAgentCaches(prev.agentId, prev.codeName);
|
|
15167
14887
|
}
|
|
@@ -15248,10 +14968,10 @@ async function pollCycleInner() {
|
|
|
15248
14968
|
// pending-inbound marker. Best-effort: a write failure is logged by
|
|
15249
14969
|
// the watchdog, never fails the poll cycle.
|
|
15250
14970
|
signalGiveUp: (codeName) => {
|
|
15251
|
-
const dir =
|
|
15252
|
-
if (!
|
|
14971
|
+
const dir = join38(homedir17(), ".augmented", codeName);
|
|
14972
|
+
if (!existsSync16(dir)) return;
|
|
15253
14973
|
atomicWriteFileSync(
|
|
15254
|
-
|
|
14974
|
+
join38(dir, "watchdog-give-up.json"),
|
|
15255
14975
|
JSON.stringify({ gave_up_at: (/* @__PURE__ */ new Date()).toISOString() })
|
|
15256
14976
|
);
|
|
15257
14977
|
},
|
|
@@ -15270,9 +14990,9 @@ async function pollCycleInner() {
|
|
|
15270
14990
|
// parser elsewhere can only reconstruct an hour (ENG-8901).
|
|
15271
14991
|
signalUsageLimit: (codeName, resetsHint) => {
|
|
15272
14992
|
const dir = getFramework("claude-code").getAgentDir(codeName);
|
|
15273
|
-
if (!
|
|
14993
|
+
if (!existsSync16(dir)) return;
|
|
15274
14994
|
atomicWriteFileSync(
|
|
15275
|
-
|
|
14995
|
+
join38(dir, "watchdog-give-up.json"),
|
|
15276
14996
|
JSON.stringify({
|
|
15277
14997
|
gave_up_at: (/* @__PURE__ */ new Date()).toISOString(),
|
|
15278
14998
|
reason: "usage_limit",
|
|
@@ -15534,7 +15254,7 @@ async function processAgent(agent, agentStates, managedToolkits) {
|
|
|
15534
15254
|
}
|
|
15535
15255
|
const now = (/* @__PURE__ */ new Date()).toISOString();
|
|
15536
15256
|
const adapter = resolveAgentFramework(agent.code_name);
|
|
15537
|
-
let agentDir =
|
|
15257
|
+
let agentDir = join38(adapter.getAgentDir(agent.code_name), "provision");
|
|
15538
15258
|
if (agent.status === "draft" || agent.status === "paused") {
|
|
15539
15259
|
forgetChannelSyncState(agent.agent_id);
|
|
15540
15260
|
if (previousKnownStatus !== agent.status) {
|
|
@@ -15575,7 +15295,7 @@ async function processAgent(agent, agentStates, managedToolkits) {
|
|
|
15575
15295
|
const residuals = {
|
|
15576
15296
|
gatewayRunning: false,
|
|
15577
15297
|
portAllocated: false,
|
|
15578
|
-
provisionDirExists:
|
|
15298
|
+
provisionDirExists: existsSync16(agentDir)
|
|
15579
15299
|
};
|
|
15580
15300
|
if (!hasRevokedResiduals(residuals)) {
|
|
15581
15301
|
agentStates.push({
|
|
@@ -15709,7 +15429,7 @@ async function processAgent(agent, agentStates, managedToolkits) {
|
|
|
15709
15429
|
const frameworkId = refreshData.agent.framework ?? DEFAULT_FRAMEWORK;
|
|
15710
15430
|
agentFrameworkCache.set(agent.code_name, frameworkId);
|
|
15711
15431
|
const frameworkAdapter = getFramework(frameworkId);
|
|
15712
|
-
agentDir =
|
|
15432
|
+
agentDir = join38(frameworkAdapter.getAgentDir(agent.code_name), "provision");
|
|
15713
15433
|
cacheAgentDeliveryMetadata(agent.code_name, refreshData);
|
|
15714
15434
|
agentRestartTimezoneInputs.set(agent.code_name, {
|
|
15715
15435
|
agentTimezone: typeof refreshData.agent.timezone === "string" ? refreshData.agent.timezone : null,
|
|
@@ -15767,7 +15487,7 @@ async function processAgent(agent, agentStates, managedToolkits) {
|
|
|
15767
15487
|
const changedFiles = [];
|
|
15768
15488
|
mkdirSync11(agentDir, { recursive: true });
|
|
15769
15489
|
for (const artifact of artifacts) {
|
|
15770
|
-
const filePath =
|
|
15490
|
+
const filePath = join38(agentDir, artifact.relativePath);
|
|
15771
15491
|
let existingHash;
|
|
15772
15492
|
let newHash;
|
|
15773
15493
|
let writeContent = artifact.content;
|
|
@@ -15786,8 +15506,8 @@ async function processAgent(agent, agentStates, managedToolkits) {
|
|
|
15786
15506
|
};
|
|
15787
15507
|
newHash = sha256(stripDynamicSections(artifact.content));
|
|
15788
15508
|
try {
|
|
15789
|
-
const projectClaudeMd =
|
|
15790
|
-
const existing =
|
|
15509
|
+
const projectClaudeMd = join38(config.configDir, agent.code_name, "project", "CLAUDE.md");
|
|
15510
|
+
const existing = readFileSync29(projectClaudeMd, "utf-8");
|
|
15791
15511
|
existingHash = sha256(stripDynamicSections(existing));
|
|
15792
15512
|
} catch {
|
|
15793
15513
|
existingHash = null;
|
|
@@ -15805,7 +15525,7 @@ async function processAgent(agent, agentStates, managedToolkits) {
|
|
|
15805
15525
|
const generatorKeys = Object.keys(generatorServers);
|
|
15806
15526
|
let existingRaw = "";
|
|
15807
15527
|
try {
|
|
15808
|
-
existingRaw =
|
|
15528
|
+
existingRaw = readFileSync29(filePath, "utf-8");
|
|
15809
15529
|
} catch {
|
|
15810
15530
|
}
|
|
15811
15531
|
const existingServers = parseMcp(existingRaw);
|
|
@@ -15821,7 +15541,7 @@ async function processAgent(agent, agentStates, managedToolkits) {
|
|
|
15821
15541
|
} else if (artifact.relativePath === "opencode.json") {
|
|
15822
15542
|
let existingRaw = null;
|
|
15823
15543
|
try {
|
|
15824
|
-
existingRaw =
|
|
15544
|
+
existingRaw = readFileSync29(filePath, "utf-8");
|
|
15825
15545
|
} catch {
|
|
15826
15546
|
}
|
|
15827
15547
|
const mergeResult = mergeOpencodeConfigArtifact(artifact.content, existingRaw);
|
|
@@ -15837,13 +15557,13 @@ async function processAgent(agent, agentStates, managedToolkits) {
|
|
|
15837
15557
|
}
|
|
15838
15558
|
}
|
|
15839
15559
|
if (changedFiles.length > 0) {
|
|
15840
|
-
const isFirst = !
|
|
15560
|
+
const isFirst = !existsSync16(join38(agentDir, "CHARTER.md"));
|
|
15841
15561
|
const verb = isFirst ? "Provisioning" : "Updating";
|
|
15842
15562
|
const fileNames = changedFiles.map((f) => f.relativePath).join(", ");
|
|
15843
15563
|
log(`${verb} '${agent.code_name}': ${fileNames}`);
|
|
15844
15564
|
for (const file of changedFiles) {
|
|
15845
|
-
const filePath =
|
|
15846
|
-
mkdirSync11(
|
|
15565
|
+
const filePath = join38(agentDir, file.relativePath);
|
|
15566
|
+
mkdirSync11(dirname10(filePath), { recursive: true });
|
|
15847
15567
|
if (file.relativePath === ".mcp.json") {
|
|
15848
15568
|
safeWriteJsonAtomic(filePath, file.content, { mode: 384 });
|
|
15849
15569
|
} else {
|
|
@@ -15851,12 +15571,12 @@ async function processAgent(agent, agentStates, managedToolkits) {
|
|
|
15851
15571
|
}
|
|
15852
15572
|
}
|
|
15853
15573
|
try {
|
|
15854
|
-
const provSkillsDir =
|
|
15855
|
-
if (
|
|
15856
|
-
for (const folder of
|
|
15574
|
+
const provSkillsDir = join38(agentDir, ".claude", "skills");
|
|
15575
|
+
if (existsSync16(provSkillsDir)) {
|
|
15576
|
+
for (const folder of readdirSync9(provSkillsDir)) {
|
|
15857
15577
|
if (folder.startsWith("knowledge-")) {
|
|
15858
15578
|
try {
|
|
15859
|
-
rmSync5(
|
|
15579
|
+
rmSync5(join38(provSkillsDir, folder), { recursive: true });
|
|
15860
15580
|
} catch {
|
|
15861
15581
|
}
|
|
15862
15582
|
}
|
|
@@ -15869,7 +15589,7 @@ async function processAgent(agent, agentStates, managedToolkits) {
|
|
|
15869
15589
|
const trackedFiles2 = frameworkAdapter.driftTrackedFiles();
|
|
15870
15590
|
const hashes = /* @__PURE__ */ new Map();
|
|
15871
15591
|
for (const file of trackedFiles2) {
|
|
15872
|
-
const h = hashFile(
|
|
15592
|
+
const h = hashFile(join38(agentDir, file));
|
|
15873
15593
|
if (h) hashes.set(file, h);
|
|
15874
15594
|
}
|
|
15875
15595
|
agentState.writtenHashes.set(agent.agent_id, hashes);
|
|
@@ -15887,14 +15607,14 @@ async function processAgent(agent, agentStates, managedToolkits) {
|
|
|
15887
15607
|
}
|
|
15888
15608
|
if (Array.isArray(refreshData.workflows)) {
|
|
15889
15609
|
try {
|
|
15890
|
-
const provWorkflowsDir =
|
|
15891
|
-
if (
|
|
15610
|
+
const provWorkflowsDir = join38(agentDir, ".claude", "workflows");
|
|
15611
|
+
if (existsSync16(provWorkflowsDir)) {
|
|
15892
15612
|
const expected = new Set(refreshData.workflows.map((w) => `${w.name}.js`));
|
|
15893
|
-
for (const file of
|
|
15613
|
+
for (const file of readdirSync9(provWorkflowsDir)) {
|
|
15894
15614
|
if (!file.endsWith(".js")) continue;
|
|
15895
15615
|
if (expected.has(file)) continue;
|
|
15896
15616
|
try {
|
|
15897
|
-
rmSync5(
|
|
15617
|
+
rmSync5(join38(provWorkflowsDir, file));
|
|
15898
15618
|
} catch {
|
|
15899
15619
|
}
|
|
15900
15620
|
}
|
|
@@ -15973,10 +15693,10 @@ async function processAgent(agent, agentStates, managedToolkits) {
|
|
|
15973
15693
|
}
|
|
15974
15694
|
let lastDriftCheckAt = now;
|
|
15975
15695
|
const written = agentState.writtenHashes.get(agent.agent_id);
|
|
15976
|
-
if (written &&
|
|
15696
|
+
if (written && existsSync16(agentDir)) {
|
|
15977
15697
|
const driftedFiles = [];
|
|
15978
15698
|
for (const [file, expectedHash] of written) {
|
|
15979
|
-
const localHash = hashFile(
|
|
15699
|
+
const localHash = hashFile(join38(agentDir, file));
|
|
15980
15700
|
if (localHash && localHash !== expectedHash) {
|
|
15981
15701
|
driftedFiles.push(file);
|
|
15982
15702
|
}
|
|
@@ -15987,7 +15707,7 @@ async function processAgent(agent, agentStates, managedToolkits) {
|
|
|
15987
15707
|
try {
|
|
15988
15708
|
const localHashes = {};
|
|
15989
15709
|
for (const file of driftedFiles) {
|
|
15990
|
-
localHashes[file] = hashFile(
|
|
15710
|
+
localHashes[file] = hashFile(join38(agentDir, file));
|
|
15991
15711
|
}
|
|
15992
15712
|
await api.post("/host/drift", {
|
|
15993
15713
|
agent_id: agent.agent_id,
|
|
@@ -16255,7 +15975,7 @@ async function processAgent(agent, agentStates, managedToolkits) {
|
|
|
16255
15975
|
const addedChannels = [...restartDecision.added];
|
|
16256
15976
|
const writeDmNoticeMarkers = isChannelAddRestart ? () => {
|
|
16257
15977
|
try {
|
|
16258
|
-
const agentAugmentedDir =
|
|
15978
|
+
const agentAugmentedDir = join38(homedir17(), ".augmented", agent.code_name);
|
|
16259
15979
|
mkdirSync11(agentAugmentedDir, { recursive: true });
|
|
16260
15980
|
const markerJson = JSON.stringify({
|
|
16261
15981
|
version: 1,
|
|
@@ -16263,7 +15983,7 @@ async function processAgent(agent, agentStates, managedToolkits) {
|
|
|
16263
15983
|
added: addedChannels
|
|
16264
15984
|
});
|
|
16265
15985
|
for (const file of ["slack-channel-add-restart.json", "telegram-channel-add-restart.json"]) {
|
|
16266
|
-
atomicWriteFileSync(
|
|
15986
|
+
atomicWriteFileSync(join38(agentAugmentedDir, file), markerJson);
|
|
16267
15987
|
}
|
|
16268
15988
|
} catch (err) {
|
|
16269
15989
|
log(`[hot-reload] channel-add DM-notice marker write failed for '${agent.code_name}' (non-fatal): ${err.message}`);
|
|
@@ -16452,24 +16172,24 @@ async function processAgent(agent, agentStates, managedToolkits) {
|
|
|
16452
16172
|
if (agentSessionMode === "persistent" && (agentFrameworkCache.get(agent.code_name) ?? DEFAULT_FRAMEWORK) === "claude-code") {
|
|
16453
16173
|
try {
|
|
16454
16174
|
const agentProvisionDir = agentDir;
|
|
16455
|
-
const projectDir =
|
|
16175
|
+
const projectDir = join38(homedir17(), ".augmented", agent.code_name, "project");
|
|
16456
16176
|
mkdirSync11(agentProvisionDir, { recursive: true });
|
|
16457
16177
|
mkdirSync11(projectDir, { recursive: true });
|
|
16458
|
-
const provisionMcpPath =
|
|
16459
|
-
const projectMcpPath =
|
|
16178
|
+
const provisionMcpPath = join38(agentProvisionDir, ".mcp.json");
|
|
16179
|
+
const projectMcpPath = join38(projectDir, ".mcp.json");
|
|
16460
16180
|
let mcpConfig = { mcpServers: {} };
|
|
16461
16181
|
try {
|
|
16462
|
-
mcpConfig = JSON.parse(
|
|
16182
|
+
mcpConfig = JSON.parse(readFileSync29(provisionMcpPath, "utf-8"));
|
|
16463
16183
|
if (!mcpConfig.mcpServers) mcpConfig.mcpServers = {};
|
|
16464
16184
|
} catch {
|
|
16465
16185
|
}
|
|
16466
|
-
const localDirectChatChannel =
|
|
16186
|
+
const localDirectChatChannel = join38(homedir17(), ".augmented", "_mcp", "direct-chat-channel.js");
|
|
16467
16187
|
const directChatTeamSettings = refreshData.team?.settings;
|
|
16468
16188
|
const directChatTz = (() => {
|
|
16469
16189
|
const tz = directChatTeamSettings?.["timezone"];
|
|
16470
16190
|
return typeof tz === "string" && tz.trim() !== "" ? tz.trim() : void 0;
|
|
16471
16191
|
})();
|
|
16472
|
-
if (
|
|
16192
|
+
if (existsSync16(localDirectChatChannel)) {
|
|
16473
16193
|
const directChatEnv = {
|
|
16474
16194
|
AGT_HOST: requireHost(),
|
|
16475
16195
|
// ENG-5901 Track D: templated — the manager exports the real
|
|
@@ -16489,7 +16209,7 @@ async function processAgent(agent, agentStates, managedToolkits) {
|
|
|
16489
16209
|
// ~/.augmented/<codeName>/.current-turn-initiator.json. Note getAgentDir
|
|
16490
16210
|
// returns the agent root (NOT the /provision subdir `agentDir` points at),
|
|
16491
16211
|
// so it byte-matches the broker readers' path.
|
|
16492
|
-
AGT_TURN_INITIATOR_FILE:
|
|
16212
|
+
AGT_TURN_INITIATOR_FILE: join38(
|
|
16493
16213
|
frameworkAdapter.getAgentDir(agent.code_name),
|
|
16494
16214
|
".current-turn-initiator.json"
|
|
16495
16215
|
)
|
|
@@ -16509,8 +16229,8 @@ async function processAgent(agent, agentStates, managedToolkits) {
|
|
|
16509
16229
|
log(`Channel credentials written for '${agent.code_name}/direct-chat'`);
|
|
16510
16230
|
}
|
|
16511
16231
|
}
|
|
16512
|
-
const staleChannelsPath =
|
|
16513
|
-
if (
|
|
16232
|
+
const staleChannelsPath = join38(projectDir, ".mcp-channels.json");
|
|
16233
|
+
if (existsSync16(staleChannelsPath)) {
|
|
16514
16234
|
try {
|
|
16515
16235
|
rmSync5(staleChannelsPath, { force: true });
|
|
16516
16236
|
} catch {
|
|
@@ -16599,7 +16319,7 @@ async function processAgent(agent, agentStates, managedToolkits) {
|
|
|
16599
16319
|
}
|
|
16600
16320
|
if (hostFlagStore().getBoolean("connectivity-probe")) {
|
|
16601
16321
|
try {
|
|
16602
|
-
const probeProjectDir =
|
|
16322
|
+
const probeProjectDir = join38(homedir17(), ".augmented", agent.code_name, "project");
|
|
16603
16323
|
let probeSet = integrations;
|
|
16604
16324
|
try {
|
|
16605
16325
|
const quarantined = await api.post("/host/agent-integrations/quarantined", { agent_id: agent.agent_id });
|
|
@@ -16645,7 +16365,7 @@ async function processAgent(agent, agentStates, managedToolkits) {
|
|
|
16645
16365
|
const forceDue = attemptsLeft > 0;
|
|
16646
16366
|
let probeRan = false;
|
|
16647
16367
|
try {
|
|
16648
|
-
const probeProjectDir =
|
|
16368
|
+
const probeProjectDir = join38(homedir17(), ".augmented", agent.code_name, "project");
|
|
16649
16369
|
probeRan = await runAgentSessionToolBindProbes(agent, integrations, probeProjectDir, { forceDue });
|
|
16650
16370
|
} catch (err) {
|
|
16651
16371
|
log(`Session-tool-bind probe failed for '${agent.code_name}': ${err.message}`);
|
|
@@ -16722,11 +16442,11 @@ async function processAgent(agent, agentStates, managedToolkits) {
|
|
|
16722
16442
|
const intHash = computeIntegrationsHash(integrations);
|
|
16723
16443
|
const prevIntHash = agentState.knownIntegrationHashes.get(agent.agent_id);
|
|
16724
16444
|
if (intHash !== prevIntHash) {
|
|
16725
|
-
const projectDir =
|
|
16726
|
-
const envIntPath =
|
|
16445
|
+
const projectDir = join38(homedir17(), ".augmented", agent.code_name, "project");
|
|
16446
|
+
const envIntPath = join38(projectDir, ".env.integrations");
|
|
16727
16447
|
let preWriteEnv;
|
|
16728
16448
|
try {
|
|
16729
|
-
preWriteEnv =
|
|
16449
|
+
preWriteEnv = readFileSync29(envIntPath, "utf-8");
|
|
16730
16450
|
} catch {
|
|
16731
16451
|
preWriteEnv = void 0;
|
|
16732
16452
|
}
|
|
@@ -16745,9 +16465,9 @@ async function processAgent(agent, agentStates, managedToolkits) {
|
|
|
16745
16465
|
}
|
|
16746
16466
|
if (fw === "claude-code" && isSessionHealthy(agent.code_name)) {
|
|
16747
16467
|
try {
|
|
16748
|
-
const projectMcpPath =
|
|
16749
|
-
const postWriteEnv =
|
|
16750
|
-
const mcpContent =
|
|
16468
|
+
const projectMcpPath = join38(projectDir, ".mcp.json");
|
|
16469
|
+
const postWriteEnv = readFileSync29(envIntPath, "utf-8");
|
|
16470
|
+
const mcpContent = readFileSync29(projectMcpPath, "utf-8");
|
|
16751
16471
|
const changedVars = diffEnvIntegrations(preWriteEnv, postWriteEnv);
|
|
16752
16472
|
const mcpJsonForReap = JSON.parse(mcpContent);
|
|
16753
16473
|
const affectedServerKeys = findMcpServersUsingVars(mcpJsonForReap, changedVars);
|
|
@@ -17010,23 +16730,23 @@ async function processAgent(agent, agentStates, managedToolkits) {
|
|
|
17010
16730
|
}
|
|
17011
16731
|
}
|
|
17012
16732
|
try {
|
|
17013
|
-
const { readdirSync:
|
|
17014
|
-
const { homedir:
|
|
16733
|
+
const { readdirSync: readdirSync10, rmSync: rmSync6 } = await import("fs");
|
|
16734
|
+
const { homedir: homedir18 } = await import("os");
|
|
17015
16735
|
const frameworkId2 = frameworkAdapter.id;
|
|
17016
16736
|
const candidateSkillDirs = [
|
|
17017
16737
|
// Claude Code — framework runtime tree
|
|
17018
|
-
|
|
16738
|
+
join38(homedir18(), ".augmented", agent.code_name, "skills"),
|
|
17019
16739
|
// Claude Code — project tree
|
|
17020
|
-
|
|
16740
|
+
join38(homedir18(), ".augmented", agent.code_name, "project", ".claude", "skills"),
|
|
17021
16741
|
// Defensive: legacy provision-side path, not currently an
|
|
17022
16742
|
// install target but cheap to sweep.
|
|
17023
|
-
|
|
16743
|
+
join38(agentDir, ".claude", "skills")
|
|
17024
16744
|
];
|
|
17025
|
-
const existingDirs = candidateSkillDirs.filter((d) =>
|
|
16745
|
+
const existingDirs = candidateSkillDirs.filter((d) => existsSync16(d));
|
|
17026
16746
|
const discoveredEntries = /* @__PURE__ */ new Set();
|
|
17027
16747
|
for (const dir of existingDirs) {
|
|
17028
16748
|
try {
|
|
17029
|
-
for (const entry of
|
|
16749
|
+
for (const entry of readdirSync10(dir)) {
|
|
17030
16750
|
if (entry.startsWith("plugin-") || entry.startsWith("integration-")) {
|
|
17031
16751
|
discoveredEntries.add(entry);
|
|
17032
16752
|
}
|
|
@@ -17041,7 +16761,7 @@ async function processAgent(agent, agentStates, managedToolkits) {
|
|
|
17041
16761
|
entry,
|
|
17042
16762
|
dirs: existingDirs,
|
|
17043
16763
|
removeDir: (p) => {
|
|
17044
|
-
if (
|
|
16764
|
+
if (existsSync16(p)) {
|
|
17045
16765
|
rmSync6(p, { recursive: true, force: true });
|
|
17046
16766
|
}
|
|
17047
16767
|
}
|
|
@@ -17061,7 +16781,7 @@ async function processAgent(agent, agentStates, managedToolkits) {
|
|
|
17061
16781
|
const sharedSkillsPayload = refreshAny.shared_skills;
|
|
17062
16782
|
const desiredResolved = globalSkillsPayload !== void 0 || sharedSkillsPayload !== void 0;
|
|
17063
16783
|
const manifestPath = managedSkillManifestPath(
|
|
17064
|
-
|
|
16784
|
+
join38(homedir17(), ".augmented", agent.code_name)
|
|
17065
16785
|
);
|
|
17066
16786
|
const prevIds = /* @__PURE__ */ new Set([
|
|
17067
16787
|
...agentState.knownGlobalSkillIds.get(agent.agent_id) ?? /* @__PURE__ */ new Set(),
|
|
@@ -17081,15 +16801,15 @@ async function processAgent(agent, agentStates, managedToolkits) {
|
|
|
17081
16801
|
}
|
|
17082
16802
|
if (plan.removes.length) {
|
|
17083
16803
|
const globalSkillDirs = [
|
|
17084
|
-
|
|
17085
|
-
|
|
17086
|
-
|
|
16804
|
+
join38(homedir17(), ".augmented", agent.code_name, "skills"),
|
|
16805
|
+
join38(homedir17(), ".augmented", agent.code_name, "project", ".claude", "skills"),
|
|
16806
|
+
join38(agentDir, ".claude", "skills")
|
|
17087
16807
|
];
|
|
17088
16808
|
for (const id of plan.removes) {
|
|
17089
16809
|
let prunedAny = false;
|
|
17090
16810
|
for (const dir of globalSkillDirs) {
|
|
17091
|
-
const p =
|
|
17092
|
-
if (
|
|
16811
|
+
const p = join38(dir, id);
|
|
16812
|
+
if (existsSync16(p) && existsSync16(join38(p, "SKILL.md"))) {
|
|
17093
16813
|
rmSync5(p, { recursive: true, force: true });
|
|
17094
16814
|
prunedAny = true;
|
|
17095
16815
|
}
|
|
@@ -17325,8 +17045,8 @@ async function processAgent(agent, agentStates, managedToolkits) {
|
|
|
17325
17045
|
const sess = getSessionState(agent.code_name);
|
|
17326
17046
|
let mcpJsonParsed = null;
|
|
17327
17047
|
try {
|
|
17328
|
-
const mcpPath =
|
|
17329
|
-
mcpJsonParsed = JSON.parse(
|
|
17048
|
+
const mcpPath = join38(getProjectDir(agent.code_name), ".mcp.json");
|
|
17049
|
+
mcpJsonParsed = JSON.parse(readFileSync29(mcpPath, "utf-8"));
|
|
17330
17050
|
} catch {
|
|
17331
17051
|
}
|
|
17332
17052
|
reapMissingMcpSessions({
|
|
@@ -17757,10 +17477,10 @@ Retried to the limit after repeated stalls \u2014 needs a look.`).catch(() => {
|
|
|
17757
17477
|
}
|
|
17758
17478
|
}
|
|
17759
17479
|
const trackedFiles = frameworkAdapter.driftTrackedFiles();
|
|
17760
|
-
if (trackedFiles.length > 0 &&
|
|
17480
|
+
if (trackedFiles.length > 0 && existsSync16(agentDir)) {
|
|
17761
17481
|
const hashes = /* @__PURE__ */ new Map();
|
|
17762
17482
|
for (const file of trackedFiles) {
|
|
17763
|
-
const h = hashFile(
|
|
17483
|
+
const h = hashFile(join38(agentDir, file));
|
|
17764
17484
|
if (h) hashes.set(file, h);
|
|
17765
17485
|
}
|
|
17766
17486
|
agentState.writtenHashes.set(agent.agent_id, hashes);
|
|
@@ -17775,7 +17495,7 @@ Retried to the limit after repeated stalls \u2014 needs a look.`).catch(() => {
|
|
|
17775
17495
|
refreshData.agent.onboarding_state
|
|
17776
17496
|
);
|
|
17777
17497
|
const obStep = obState.step;
|
|
17778
|
-
const markerPath =
|
|
17498
|
+
const markerPath = join38(homedir17(), ".augmented", agent.code_name, "onboarding-drive.json");
|
|
17779
17499
|
const marker = readOnboardingDriveMarker(markerPath);
|
|
17780
17500
|
const obContactRaw = refreshData.agent.manager_last_contacted_at;
|
|
17781
17501
|
const obContact = typeof obContactRaw === "string" && obContactRaw ? obContactRaw : null;
|
|
@@ -17877,7 +17597,7 @@ async function ensureOpencodeRuntime(agent, refreshData, agentTimezone) {
|
|
|
17877
17597
|
}
|
|
17878
17598
|
stopOpencodeSlackIngest(codeName, log);
|
|
17879
17599
|
stopOpencodeTelegramIngest(codeName, log);
|
|
17880
|
-
const opencodeProjectDir =
|
|
17600
|
+
const opencodeProjectDir = join38(getFramework("opencode").getAgentDir(codeName), "provision");
|
|
17881
17601
|
const serveEnv = {
|
|
17882
17602
|
AGT_HOST: requireHost(),
|
|
17883
17603
|
AGT_API_KEY: getApiKey() ?? void 0,
|
|
@@ -17932,8 +17652,8 @@ async function ensurePersistentSession(agent, tasks, boardItems, refreshData) {
|
|
|
17932
17652
|
});
|
|
17933
17653
|
}
|
|
17934
17654
|
const projectDir = getProjectDir(codeName);
|
|
17935
|
-
const mcpConfigPath =
|
|
17936
|
-
const claudeMdPath =
|
|
17655
|
+
const mcpConfigPath = join38(projectDir, ".mcp.json");
|
|
17656
|
+
const claudeMdPath = join38(projectDir, "CLAUDE.md");
|
|
17937
17657
|
if (restartBreaker.isTripped(codeName)) {
|
|
17938
17658
|
const trip = restartBreaker.getTrip(codeName);
|
|
17939
17659
|
return {
|
|
@@ -18708,7 +18428,7 @@ async function handleRestartDoorbell(agentId, requestedAt, restartReason) {
|
|
|
18708
18428
|
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}`));
|
|
18709
18429
|
void (async () => {
|
|
18710
18430
|
try {
|
|
18711
|
-
const { collectDiagnostics } = await import("../persistent-session-
|
|
18431
|
+
const { collectDiagnostics } = await import("../persistent-session-DJSSEIR6.js");
|
|
18712
18432
|
await api.post("/host/heartbeat", {
|
|
18713
18433
|
host_id: hostId,
|
|
18714
18434
|
agent_diagnostics: collectDiagnostics([codeName], quarantineEntriesFor, claudeMdSizeFor, spawnOutcomeForDiagnostics, pidPressureFor, forwardedToolsFor)
|
|
@@ -18759,7 +18479,7 @@ async function respawnAgentAfterMcpStop(codeName, reason) {
|
|
|
18759
18479
|
}
|
|
18760
18480
|
try {
|
|
18761
18481
|
const hostId = await getHostId();
|
|
18762
|
-
const { collectDiagnostics } = await import("../persistent-session-
|
|
18482
|
+
const { collectDiagnostics } = await import("../persistent-session-DJSSEIR6.js");
|
|
18763
18483
|
await api.post("/host/heartbeat", {
|
|
18764
18484
|
host_id: hostId,
|
|
18765
18485
|
agent_diagnostics: collectDiagnostics([codeName], quarantineEntriesFor, claudeMdSizeFor, spawnOutcomeForDiagnostics, pidPressureFor, forwardedToolsFor)
|
|
@@ -19075,7 +18795,7 @@ async function processDirectChatMessageOpencode(agent, msg) {
|
|
|
19075
18795
|
body
|
|
19076
18796
|
});
|
|
19077
18797
|
recordCursorAdvanceOutcome(
|
|
19078
|
-
|
|
18798
|
+
dirname10(paneLogPath(agent.codeName)),
|
|
19079
18799
|
"direct-chat-manager",
|
|
19080
18800
|
"reply",
|
|
19081
18801
|
verdict
|
|
@@ -19105,7 +18825,7 @@ async function processDirectChatMessageOpencode(agent, msg) {
|
|
|
19105
18825
|
} catch (err) {
|
|
19106
18826
|
if (!recorded) {
|
|
19107
18827
|
recordCursorAdvanceOutcome(
|
|
19108
|
-
|
|
18828
|
+
dirname10(paneLogPath(agent.codeName)),
|
|
19109
18829
|
"direct-chat-manager",
|
|
19110
18830
|
"reply",
|
|
19111
18831
|
{ outcome: "failed", error: err.message, expected: 1 }
|
|
@@ -19156,8 +18876,8 @@ async function processDirectChatMessage(agent, msg) {
|
|
|
19156
18876
|
const useDoorbell = hostFlagStore().getBoolean("direct-chat-doorbell") || isolationMode(agent.codeName) === "docker";
|
|
19157
18877
|
if (useDoorbell) {
|
|
19158
18878
|
try {
|
|
19159
|
-
const doorbell = directChatDoorbellPath(agent.agentId,
|
|
19160
|
-
mkdirSync11(
|
|
18879
|
+
const doorbell = directChatDoorbellPath(agent.agentId, homedir17());
|
|
18880
|
+
mkdirSync11(dirname10(doorbell), { recursive: true });
|
|
19161
18881
|
writeFileSync15(doorbell, String(Date.now()));
|
|
19162
18882
|
log(`[direct-chat] Doorbell rung for '${agent.codeName}' (msg=${msg.id}) \u2014 in-session MCP will pull via the cursor`);
|
|
19163
18883
|
return;
|
|
@@ -19285,8 +19005,8 @@ ${formatRunMarker(run_id)}` : KANBAN_CHECK_COMMAND;
|
|
|
19285
19005
|
}
|
|
19286
19006
|
if (run_id) openInjectedRunByCode.set(codeName, run_id);
|
|
19287
19007
|
try {
|
|
19288
|
-
const doorbell = directChatDoorbellPath(agentId,
|
|
19289
|
-
mkdirSync11(
|
|
19008
|
+
const doorbell = directChatDoorbellPath(agentId, homedir17());
|
|
19009
|
+
mkdirSync11(dirname10(doorbell), { recursive: true });
|
|
19290
19010
|
writeFileSync15(doorbell, String(Date.now()));
|
|
19291
19011
|
} catch (err) {
|
|
19292
19012
|
log(`[kanban] doorbell ring failed for '${codeName}': ${err.message} (notice still queued)`);
|
|
@@ -19391,7 +19111,7 @@ async function processClaudePairSessions(agents) {
|
|
|
19391
19111
|
killPairSession,
|
|
19392
19112
|
pairTmuxSession,
|
|
19393
19113
|
finalizeClaudePairOnboarding
|
|
19394
|
-
} = await import("../claude-pair-runtime-
|
|
19114
|
+
} = await import("../claude-pair-runtime-JK7GQU25.js");
|
|
19395
19115
|
for (const pairId of pendingResp.cancelled_pair_ids ?? []) {
|
|
19396
19116
|
log(`[claude-pair] sweeping orphan tmux session for pair ${pairId.slice(0, 8)}`);
|
|
19397
19117
|
const killed = await killPairSession(pairTmuxSession(pairId));
|
|
@@ -19426,12 +19146,12 @@ async function processClaudePairSessions(agents) {
|
|
|
19426
19146
|
try {
|
|
19427
19147
|
if (session.status === "initiating") {
|
|
19428
19148
|
log(`[claude-pair] spawning pair session ${pairSession} for '${codeName}'`);
|
|
19429
|
-
const
|
|
19430
|
-
if (!
|
|
19149
|
+
const spawn = await spawnPairSession(pairSession);
|
|
19150
|
+
if (!spawn.ok) {
|
|
19431
19151
|
await reportAndCleanup(session.pair_id, {
|
|
19432
19152
|
status: "failure",
|
|
19433
|
-
error_code:
|
|
19434
|
-
error_message:
|
|
19153
|
+
error_code: spawn.error.kind,
|
|
19154
|
+
error_message: spawn.error.kind === "unknown" ? spawn.error.message : void 0
|
|
19435
19155
|
});
|
|
19436
19156
|
continue;
|
|
19437
19157
|
}
|
|
@@ -19616,17 +19336,17 @@ var lastDownloadHash = /* @__PURE__ */ new Map();
|
|
|
19616
19336
|
var lastLocalFileHash = /* @__PURE__ */ new Map();
|
|
19617
19337
|
var memoryManifests = /* @__PURE__ */ new Map();
|
|
19618
19338
|
function memoryRetirementDir(configDir, codeName) {
|
|
19619
|
-
return
|
|
19339
|
+
return join38(configDir, "_memory-retirement", codeName);
|
|
19620
19340
|
}
|
|
19621
19341
|
function memoryManifestPath(configDir, codeName) {
|
|
19622
|
-
return
|
|
19342
|
+
return join38(memoryRetirementDir(configDir, codeName), "manifest.json");
|
|
19623
19343
|
}
|
|
19624
19344
|
function loadMemoryManifest(agentId, configDir, codeName) {
|
|
19625
19345
|
const cached = memoryManifests.get(agentId);
|
|
19626
19346
|
if (cached) return cached;
|
|
19627
19347
|
let manifest = {};
|
|
19628
19348
|
try {
|
|
19629
|
-
const raw =
|
|
19349
|
+
const raw = readFileSync29(memoryManifestPath(configDir, codeName), "utf-8");
|
|
19630
19350
|
const parsed = JSON.parse(raw);
|
|
19631
19351
|
if (parsed && typeof parsed === "object" && !Array.isArray(parsed)) {
|
|
19632
19352
|
for (const [name, entry] of Object.entries(parsed)) {
|
|
@@ -19654,7 +19374,7 @@ function saveMemoryManifest(agentId, configDir, codeName) {
|
|
|
19654
19374
|
}
|
|
19655
19375
|
}
|
|
19656
19376
|
function retiredMemoryDir(configDir, codeName) {
|
|
19657
|
-
return
|
|
19377
|
+
return join38(memoryRetirementDir(configDir, codeName), "retired");
|
|
19658
19378
|
}
|
|
19659
19379
|
var RETIRED_MEMORY_TTL_MS = 30 * 24 * 60 * 60 * 1e3;
|
|
19660
19380
|
var lastRetirementReport = /* @__PURE__ */ new Map();
|
|
@@ -19732,15 +19452,15 @@ function applyMemoryTombstones(opts) {
|
|
|
19732
19452
|
log2(`[memory-retire] ${agent.code_name}: KEPT '${tomb.name}' \u2014 no write record, not ours to remove`);
|
|
19733
19453
|
continue;
|
|
19734
19454
|
}
|
|
19735
|
-
const filePath =
|
|
19736
|
-
if (!
|
|
19455
|
+
const filePath = join38(memoryDir, entry.file);
|
|
19456
|
+
if (!existsSync16(filePath)) {
|
|
19737
19457
|
outcomes.already_gone++;
|
|
19738
19458
|
delete manifest[tomb.name];
|
|
19739
19459
|
manifestDirty = true;
|
|
19740
19460
|
continue;
|
|
19741
19461
|
}
|
|
19742
19462
|
try {
|
|
19743
|
-
const actual = createHash17("sha256").update(
|
|
19463
|
+
const actual = createHash17("sha256").update(readFileSync29(filePath)).digest("hex");
|
|
19744
19464
|
if (actual !== entry.sha) {
|
|
19745
19465
|
outcomes.kept_modified++;
|
|
19746
19466
|
outcomes.unapplied.push({ name: tomb.name, reason: "kept_modified" });
|
|
@@ -19752,9 +19472,9 @@ function applyMemoryTombstones(opts) {
|
|
|
19752
19472
|
const destDir = retiredMemoryDir(configDir, agent.code_name);
|
|
19753
19473
|
mkdirSync11(destDir, { recursive: true });
|
|
19754
19474
|
const stamp = Date.now();
|
|
19755
|
-
let dest =
|
|
19756
|
-
for (let n = 1;
|
|
19757
|
-
dest =
|
|
19475
|
+
let dest = join38(destDir, `${entry.file}.${stamp}.retired`);
|
|
19476
|
+
for (let n = 1; existsSync16(dest); n++) {
|
|
19477
|
+
dest = join38(destDir, `${entry.file}.${stamp}-${n}.retired`);
|
|
19758
19478
|
}
|
|
19759
19479
|
renameSync8(filePath, dest);
|
|
19760
19480
|
try {
|
|
@@ -19787,13 +19507,13 @@ function applyMemoryTombstones(opts) {
|
|
|
19787
19507
|
}
|
|
19788
19508
|
function reapRetiredMemories(configDir, codeName, log2) {
|
|
19789
19509
|
const dir = retiredMemoryDir(configDir, codeName);
|
|
19790
|
-
if (!
|
|
19510
|
+
if (!existsSync16(dir)) return;
|
|
19791
19511
|
const cutoff = Date.now() - RETIRED_MEMORY_TTL_MS;
|
|
19792
19512
|
let reaped = 0;
|
|
19793
19513
|
try {
|
|
19794
|
-
for (const file of
|
|
19514
|
+
for (const file of readdirSync9(dir)) {
|
|
19795
19515
|
if (!file.endsWith(".retired")) continue;
|
|
19796
|
-
const path =
|
|
19516
|
+
const path = join38(dir, file);
|
|
19797
19517
|
try {
|
|
19798
19518
|
if (statSync8(path).mtimeMs < cutoff) {
|
|
19799
19519
|
unlinkSync6(path);
|
|
@@ -19808,8 +19528,8 @@ function reapRetiredMemories(configDir, codeName, log2) {
|
|
|
19808
19528
|
if (reaped > 0) log2(`[memory-retire] ${codeName}: reaped ${reaped} retired memory file(s) past TTL`);
|
|
19809
19529
|
}
|
|
19810
19530
|
async function syncMemories(agent, configDir, log2) {
|
|
19811
|
-
const projectDir =
|
|
19812
|
-
const memoryDir =
|
|
19531
|
+
const projectDir = join38(configDir, agent.code_name, "project");
|
|
19532
|
+
const memoryDir = join38(projectDir, "memory");
|
|
19813
19533
|
const isFreshSync = pendingFreshMemorySync.has(agent.agent_id);
|
|
19814
19534
|
if (isFreshSync) {
|
|
19815
19535
|
log2(`[memory-sync] Fresh-sync requested for '${agent.code_name}' \u2014 pulling DB first`);
|
|
@@ -19833,14 +19553,14 @@ async function syncMemories(agent, configDir, log2) {
|
|
|
19833
19553
|
}
|
|
19834
19554
|
pendingFreshMemorySync.delete(agent.agent_id);
|
|
19835
19555
|
}
|
|
19836
|
-
if (
|
|
19556
|
+
if (existsSync16(memoryDir)) {
|
|
19837
19557
|
const prevHashes = memoryFileHashes.get(agent.agent_id) ?? /* @__PURE__ */ new Map();
|
|
19838
19558
|
const currentHashes = /* @__PURE__ */ new Map();
|
|
19839
19559
|
const changedMemories = [];
|
|
19840
|
-
for (const file of
|
|
19560
|
+
for (const file of readdirSync9(memoryDir)) {
|
|
19841
19561
|
if (!file.endsWith(".md")) continue;
|
|
19842
19562
|
try {
|
|
19843
|
-
const raw =
|
|
19563
|
+
const raw = readFileSync29(join38(memoryDir, file), "utf-8");
|
|
19844
19564
|
const fileHash = createHash17("sha256").update(raw).digest("hex").slice(0, 16);
|
|
19845
19565
|
currentHashes.set(file, fileHash);
|
|
19846
19566
|
if (prevHashes.get(file) === fileHash) continue;
|
|
@@ -19865,7 +19585,7 @@ async function syncMemories(agent, configDir, log2) {
|
|
|
19865
19585
|
} catch (err) {
|
|
19866
19586
|
for (const mem of changedMemories) {
|
|
19867
19587
|
for (const [file] of currentHashes) {
|
|
19868
|
-
const parsed = parseMemoryFile(
|
|
19588
|
+
const parsed = parseMemoryFile(readFileSync29(join38(memoryDir, file), "utf-8"), file.replace(/\.md$/, ""));
|
|
19869
19589
|
if (parsed?.name === mem.name) currentHashes.delete(file);
|
|
19870
19590
|
}
|
|
19871
19591
|
}
|
|
@@ -19891,7 +19611,7 @@ async function syncMemories(agent, configDir, log2) {
|
|
|
19891
19611
|
}
|
|
19892
19612
|
}
|
|
19893
19613
|
async function downloadMemories(agent, memoryDir, log2, { force, configDir }) {
|
|
19894
|
-
const localFiles =
|
|
19614
|
+
const localFiles = existsSync16(memoryDir) ? readdirSync9(memoryDir).filter((f) => f.endsWith(".md")).sort() : [];
|
|
19895
19615
|
const localListHash = createHash17("sha256").update(localFiles.join(",")).digest("hex").slice(0, 16);
|
|
19896
19616
|
const prevLocalHash = lastLocalFileHash.get(agent.agent_id);
|
|
19897
19617
|
const prevDownload = lastDownloadHash.get(agent.agent_id);
|
|
@@ -19916,7 +19636,7 @@ async function downloadMemories(agent, memoryDir, log2, { force, configDir }) {
|
|
|
19916
19636
|
const rawSlug = mem.name.toLowerCase().replace(/[^a-z0-9]+/g, "-").replace(/(^-|-$)/g, "").slice(0, 60);
|
|
19917
19637
|
const slug = rawSlug || `memory-${i}`;
|
|
19918
19638
|
const fileName = `${slug}.md`;
|
|
19919
|
-
const filePath =
|
|
19639
|
+
const filePath = join38(memoryDir, fileName);
|
|
19920
19640
|
const desired = `---
|
|
19921
19641
|
name: ${JSON.stringify(mem.name)}
|
|
19922
19642
|
type: ${mem.type}
|
|
@@ -19933,10 +19653,10 @@ ${mem.content}
|
|
|
19933
19653
|
return true;
|
|
19934
19654
|
};
|
|
19935
19655
|
let manifestDirty = false;
|
|
19936
|
-
if (
|
|
19656
|
+
if (existsSync16(filePath)) {
|
|
19937
19657
|
let existing = "";
|
|
19938
19658
|
try {
|
|
19939
|
-
existing =
|
|
19659
|
+
existing = readFileSync29(filePath, "utf-8");
|
|
19940
19660
|
} catch {
|
|
19941
19661
|
}
|
|
19942
19662
|
if (existing === desired) {
|
|
@@ -19954,7 +19674,7 @@ ${mem.content}
|
|
|
19954
19674
|
if (manifestDirty) saveMemoryManifest(agent.agent_id, configDir, agent.code_name);
|
|
19955
19675
|
}
|
|
19956
19676
|
if (written > 0 || overwritten > 0) {
|
|
19957
|
-
const updatedFiles =
|
|
19677
|
+
const updatedFiles = readdirSync9(memoryDir).filter((f) => f.endsWith(".md")).sort();
|
|
19958
19678
|
lastLocalFileHash.set(agent.agent_id, createHash17("sha256").update(updatedFiles.join(",")).digest("hex").slice(0, 16));
|
|
19959
19679
|
log2(`Memory download for '${agent.code_name}': wrote ${written} new, overwrote ${overwritten} stale`);
|
|
19960
19680
|
}
|
|
@@ -19966,7 +19686,7 @@ ${mem.content}
|
|
|
19966
19686
|
}
|
|
19967
19687
|
}
|
|
19968
19688
|
async function cleanupAgentFiles(codeName, agentDir) {
|
|
19969
|
-
if (
|
|
19689
|
+
if (existsSync16(agentDir)) {
|
|
19970
19690
|
try {
|
|
19971
19691
|
rmSync5(agentDir, { recursive: true, force: true });
|
|
19972
19692
|
log(`Removed provision directory for '${codeName}'`);
|
|
@@ -19990,8 +19710,8 @@ var caffeinateProc = null;
|
|
|
19990
19710
|
async function startCaffeinate() {
|
|
19991
19711
|
if (process.platform !== "darwin") return;
|
|
19992
19712
|
try {
|
|
19993
|
-
const { spawn
|
|
19994
|
-
caffeinateProc =
|
|
19713
|
+
const { spawn } = await import("child_process");
|
|
19714
|
+
caffeinateProc = spawn("caffeinate", ["-dims"], {
|
|
19995
19715
|
stdio: "ignore",
|
|
19996
19716
|
detached: false
|
|
19997
19717
|
});
|
|
@@ -20236,8 +19956,8 @@ function startManager(opts) {
|
|
|
20236
19956
|
config = opts;
|
|
20237
19957
|
try {
|
|
20238
19958
|
const stateFile = getStateFile();
|
|
20239
|
-
if (
|
|
20240
|
-
const raw =
|
|
19959
|
+
if (existsSync16(stateFile)) {
|
|
19960
|
+
const raw = readFileSync29(stateFile, "utf-8");
|
|
20241
19961
|
const parsed = JSON.parse(raw);
|
|
20242
19962
|
if (Array.isArray(parsed.agents)) {
|
|
20243
19963
|
state8.agents = parsed.agents;
|
|
@@ -20264,7 +19984,7 @@ function startManager(opts) {
|
|
|
20264
19984
|
log(`[startup] state rehydration failed (continuing with empty state): ${err.message}`);
|
|
20265
19985
|
}
|
|
20266
19986
|
log(
|
|
20267
|
-
`[startup] worker pid=${process.pid} ppid=${process.ppid} node=${process.version} log=${
|
|
19987
|
+
`[startup] worker pid=${process.pid} ppid=${process.ppid} node=${process.version} log=${join38(homedir17(), ".augmented", "manager.log")}`
|
|
20268
19988
|
);
|
|
20269
19989
|
deployMcpAssets();
|
|
20270
19990
|
reapOrphanChannelMcps({ log });
|
|
@@ -20293,7 +20013,7 @@ async function reapOrphanedClaudePids() {
|
|
|
20293
20013
|
const looksLikeClaude = (pid) => {
|
|
20294
20014
|
if (process.platform !== "linux") return true;
|
|
20295
20015
|
try {
|
|
20296
|
-
const comm =
|
|
20016
|
+
const comm = readFileSync29(`/proc/${pid}/comm`, "utf-8").trim().toLowerCase();
|
|
20297
20017
|
return comm.includes("claude");
|
|
20298
20018
|
} catch {
|
|
20299
20019
|
return false;
|
|
@@ -20311,16 +20031,16 @@ async function reapOrphanedClaudePids() {
|
|
|
20311
20031
|
},
|
|
20312
20032
|
looksLikeClaude
|
|
20313
20033
|
);
|
|
20314
|
-
for (const
|
|
20034
|
+
for (const spawn of decision.toKill) {
|
|
20315
20035
|
try {
|
|
20316
|
-
process.kill(
|
|
20036
|
+
process.kill(spawn.pid, "SIGKILL");
|
|
20317
20037
|
} catch (err) {
|
|
20318
|
-
log(`[drain] reaper SIGKILL pid=${
|
|
20038
|
+
log(`[drain] reaper SIGKILL pid=${spawn.pid} failed: ${err.message}`);
|
|
20319
20039
|
}
|
|
20320
20040
|
}
|
|
20321
|
-
for (const
|
|
20041
|
+
for (const spawn of decision.pidReusedSkipped) {
|
|
20322
20042
|
log(
|
|
20323
|
-
`[drain] reaper skipped pid=${
|
|
20043
|
+
`[drain] reaper skipped pid=${spawn.pid} \u2014 PID reuse suspected (identity probe rejected)`
|
|
20324
20044
|
);
|
|
20325
20045
|
}
|
|
20326
20046
|
log(formatReaperBootLine({
|
|
@@ -20390,18 +20110,18 @@ function restartRunningChannelMcps(basenames) {
|
|
|
20390
20110
|
}
|
|
20391
20111
|
}
|
|
20392
20112
|
function deployMcpAssets() {
|
|
20393
|
-
const targetDir =
|
|
20113
|
+
const targetDir = join38(homedir17(), ".augmented", "_mcp");
|
|
20394
20114
|
mkdirSync11(targetDir, { recursive: true });
|
|
20395
|
-
const moduleDir =
|
|
20115
|
+
const moduleDir = dirname10(fileURLToPath(import.meta.url));
|
|
20396
20116
|
let mcpSourceDir = "";
|
|
20397
20117
|
let dir = moduleDir;
|
|
20398
20118
|
for (let i = 0; i < 6; i++) {
|
|
20399
|
-
const candidate =
|
|
20400
|
-
if (
|
|
20119
|
+
const candidate = join38(dir, "dist", "mcp");
|
|
20120
|
+
if (existsSync16(join38(candidate, "index.js"))) {
|
|
20401
20121
|
mcpSourceDir = candidate;
|
|
20402
20122
|
break;
|
|
20403
20123
|
}
|
|
20404
|
-
const parent =
|
|
20124
|
+
const parent = dirname10(dir);
|
|
20405
20125
|
if (parent === dir) break;
|
|
20406
20126
|
dir = parent;
|
|
20407
20127
|
}
|
|
@@ -20414,8 +20134,8 @@ function deployMcpAssets() {
|
|
|
20414
20134
|
const failedFiles = [];
|
|
20415
20135
|
const fileHash = (p) => {
|
|
20416
20136
|
try {
|
|
20417
|
-
if (!
|
|
20418
|
-
return createHash17("sha256").update(
|
|
20137
|
+
if (!existsSync16(p)) return null;
|
|
20138
|
+
return createHash17("sha256").update(readFileSync29(p)).digest("hex");
|
|
20419
20139
|
} catch {
|
|
20420
20140
|
return null;
|
|
20421
20141
|
}
|
|
@@ -20486,9 +20206,9 @@ function deployMcpAssets() {
|
|
|
20486
20206
|
// needs restarting to pick up a token rotation.
|
|
20487
20207
|
"xero.js"
|
|
20488
20208
|
]) {
|
|
20489
|
-
const src =
|
|
20490
|
-
const dst =
|
|
20491
|
-
if (!
|
|
20209
|
+
const src = join38(mcpSourceDir, file);
|
|
20210
|
+
const dst = join38(targetDir, file);
|
|
20211
|
+
if (!existsSync16(src)) continue;
|
|
20492
20212
|
attemptedFiles.push(file);
|
|
20493
20213
|
const before = fileHash(dst);
|
|
20494
20214
|
try {
|
|
@@ -20513,16 +20233,16 @@ function deployMcpAssets() {
|
|
|
20513
20233
|
log(`[manager] Bundle(s) updated: ${changedBasenames.join(", ")} \u2014 signalling running instances to restart`);
|
|
20514
20234
|
restartRunningChannelMcps(changedBasenames);
|
|
20515
20235
|
}
|
|
20516
|
-
const localMcpPath =
|
|
20236
|
+
const localMcpPath = join38(targetDir, "index.js");
|
|
20517
20237
|
try {
|
|
20518
|
-
const agentsDir =
|
|
20519
|
-
if (
|
|
20520
|
-
for (const entry of
|
|
20238
|
+
const agentsDir = join38(homedir17(), ".augmented", "agents");
|
|
20239
|
+
if (existsSync16(agentsDir)) {
|
|
20240
|
+
for (const entry of readdirSync9(agentsDir, { withFileTypes: true })) {
|
|
20521
20241
|
if (!entry.isDirectory()) continue;
|
|
20522
20242
|
for (const subdir of ["provision", "project"]) {
|
|
20523
|
-
const mcpJsonPath =
|
|
20243
|
+
const mcpJsonPath = join38(agentsDir, entry.name, subdir, ".mcp.json");
|
|
20524
20244
|
try {
|
|
20525
|
-
const raw =
|
|
20245
|
+
const raw = readFileSync29(mcpJsonPath, "utf-8");
|
|
20526
20246
|
if (!raw.includes("@integrity-labs/augmented-mcp")) continue;
|
|
20527
20247
|
const mcpConfig = JSON.parse(raw);
|
|
20528
20248
|
const augServer = mcpConfig.mcpServers?.["augmented"];
|