@integrity-labs/agt-cli 0.28.715 → 0.28.717
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-RPWLPRGP.js → chunk-JN4D7534.js} +8 -5
- package/dist/chunk-JN4D7534.js.map +1 -0
- package/dist/{chunk-LHYYO4NY.js → chunk-KVR5KNED.js} +119 -1
- package/dist/chunk-KVR5KNED.js.map +1 -0
- package/dist/{chunk-VZPXV57A.js → chunk-XSBRGOGL.js} +351 -62
- package/dist/chunk-XSBRGOGL.js.map +1 -0
- package/dist/{claude-pair-runtime-GYS4MOPM.js → claude-pair-runtime-KWBCSCZO.js} +2 -2
- package/dist/lib/manager-worker.js +459 -613
- package/dist/lib/manager-worker.js.map +1 -1
- package/dist/mcp/direct-chat-channel.js +118 -0
- package/dist/mcp/index.js +118 -0
- package/dist/mcp/origami.js +118 -0
- package/dist/mcp/slack-channel.js +118 -0
- package/dist/mcp/telegram-channel.js +127 -9
- package/dist/{persistent-session-Z4UOM4V6.js → persistent-session-GB3D5OIA.js} +5 -3
- package/dist/{responsiveness-probe-XJZSVXMW.js → responsiveness-probe-TDZDQXBU.js} +3 -3
- package/dist/{session-auth-dead-KUYVUOK5.js → session-auth-dead-CPY4UZI7.js} +2 -2
- package/package.json +1 -1
- package/dist/chunk-LHYYO4NY.js.map +0 -1
- package/dist/chunk-RPWLPRGP.js.map +0 -1
- package/dist/chunk-VZPXV57A.js.map +0 -1
- /package/dist/{claude-pair-runtime-GYS4MOPM.js.map → claude-pair-runtime-KWBCSCZO.js.map} +0 -0
- /package/dist/{persistent-session-Z4UOM4V6.js.map → persistent-session-GB3D5OIA.js.map} +0 -0
- /package/dist/{responsiveness-probe-XJZSVXMW.js.map → responsiveness-probe-TDZDQXBU.js.map} +0 -0
- /package/dist/{session-auth-dead-KUYVUOK5.js.map → session-auth-dead-CPY4UZI7.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-XSBRGOGL.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-JN4D7534.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-KVR5KNED.js";
|
|
202
204
|
import {
|
|
203
205
|
reapOrphanChannelMcps
|
|
204
206
|
} from "../chunk-XWVM4KPK.js";
|
|
205
207
|
|
|
206
208
|
// src/lib/manager-worker.ts
|
|
207
|
-
import { createHash as
|
|
208
|
-
import { readFileSync as readFileSync30, writeFileSync as
|
|
209
|
+
import { createHash as createHash18 } from "crypto";
|
|
210
|
+
import { readFileSync as readFileSync30, writeFileSync as writeFileSync16, mkdirSync as mkdirSync12, existsSync as existsSync17, rmSync as rmSync6, readdirSync as readdirSync10, statSync as statSync9, unlinkSync as unlinkSync6, renameSync as renameSync9, utimesSync as utimesSync2 } 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 join39, dirname as
|
|
235
|
-
import { homedir as
|
|
236
|
+
import { join as join39, 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,16 +1679,16 @@ 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
1694
|
const existsSync18 = deps.existsSync ?? nodeExistsSync;
|
|
@@ -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;
|
|
@@ -5474,8 +5194,111 @@ function computeChannelConfigHash(input) {
|
|
|
5474
5194
|
).digest("hex");
|
|
5475
5195
|
}
|
|
5476
5196
|
|
|
5197
|
+
// src/lib/knowledge-cache.ts
|
|
5198
|
+
import { createHash as createHash9 } from "crypto";
|
|
5199
|
+
import {
|
|
5200
|
+
existsSync as existsSync6,
|
|
5201
|
+
mkdirSync as mkdirSync6,
|
|
5202
|
+
readFileSync as readFileSync17,
|
|
5203
|
+
readdirSync as readdirSync5,
|
|
5204
|
+
renameSync as renameSync5,
|
|
5205
|
+
rmSync as rmSync3,
|
|
5206
|
+
statSync as statSync5,
|
|
5207
|
+
utimesSync,
|
|
5208
|
+
writeFileSync as writeFileSync8
|
|
5209
|
+
} from "fs";
|
|
5210
|
+
import { join as join23 } from "path";
|
|
5211
|
+
var KNOWLEDGE_FETCH_CHUNK = 100;
|
|
5212
|
+
var CACHE_TTL_MS = 30 * 24 * 60 * 60 * 1e3;
|
|
5213
|
+
var SWEEP_INTERVAL_MS = 24 * 60 * 60 * 1e3;
|
|
5214
|
+
var lastSweepAt = 0;
|
|
5215
|
+
function knowledgeHash(content) {
|
|
5216
|
+
return createHash9("sha256").update(content, "utf8").digest("hex");
|
|
5217
|
+
}
|
|
5218
|
+
function cachePath(cacheDir, hash) {
|
|
5219
|
+
return join23(cacheDir, hash);
|
|
5220
|
+
}
|
|
5221
|
+
function readCachedKnowledge(cacheDir, hash) {
|
|
5222
|
+
const path = cachePath(cacheDir, hash);
|
|
5223
|
+
try {
|
|
5224
|
+
const content = readFileSync17(path, "utf-8");
|
|
5225
|
+
try {
|
|
5226
|
+
const now = /* @__PURE__ */ new Date();
|
|
5227
|
+
utimesSync(path, now, now);
|
|
5228
|
+
} catch {
|
|
5229
|
+
}
|
|
5230
|
+
return content;
|
|
5231
|
+
} catch {
|
|
5232
|
+
return null;
|
|
5233
|
+
}
|
|
5234
|
+
}
|
|
5235
|
+
function writeCachedKnowledge(cacheDir, hash, content) {
|
|
5236
|
+
if (knowledgeHash(content) !== hash) return false;
|
|
5237
|
+
try {
|
|
5238
|
+
mkdirSync6(cacheDir, { recursive: true });
|
|
5239
|
+
const tmp = `${cachePath(cacheDir, hash)}.tmp-${process.pid}`;
|
|
5240
|
+
writeFileSync8(tmp, content, "utf-8");
|
|
5241
|
+
renameSync5(tmp, cachePath(cacheDir, hash));
|
|
5242
|
+
return true;
|
|
5243
|
+
} catch {
|
|
5244
|
+
return false;
|
|
5245
|
+
}
|
|
5246
|
+
}
|
|
5247
|
+
function sweepKnowledgeCache(cacheDir, now = Date.now()) {
|
|
5248
|
+
if (now - lastSweepAt < SWEEP_INTERVAL_MS) return;
|
|
5249
|
+
lastSweepAt = now;
|
|
5250
|
+
try {
|
|
5251
|
+
if (!existsSync6(cacheDir)) return;
|
|
5252
|
+
for (const name of readdirSync5(cacheDir)) {
|
|
5253
|
+
const path = join23(cacheDir, name);
|
|
5254
|
+
try {
|
|
5255
|
+
if (now - statSync5(path).mtimeMs > CACHE_TTL_MS) rmSync3(path, { force: true });
|
|
5256
|
+
} catch {
|
|
5257
|
+
}
|
|
5258
|
+
}
|
|
5259
|
+
} catch {
|
|
5260
|
+
}
|
|
5261
|
+
}
|
|
5262
|
+
async function resolveKnowledgeFromManifest(args) {
|
|
5263
|
+
const { manifest, cacheDir, delivery, fetchContents, log: log2 } = args;
|
|
5264
|
+
const meta = (e) => ({ title: e.title, slug: e.slug, scope: e.scope });
|
|
5265
|
+
if (delivery === "search") {
|
|
5266
|
+
sweepKnowledgeCache(cacheDir);
|
|
5267
|
+
return manifest.map((e) => ({ ...meta(e), content: null }));
|
|
5268
|
+
}
|
|
5269
|
+
const bodies = /* @__PURE__ */ new Map();
|
|
5270
|
+
const missing = [];
|
|
5271
|
+
for (const entry of manifest) {
|
|
5272
|
+
if (!entry.hash || bodies.has(entry.hash)) continue;
|
|
5273
|
+
const cached = readCachedKnowledge(cacheDir, entry.hash);
|
|
5274
|
+
if (cached !== null) bodies.set(entry.hash, cached);
|
|
5275
|
+
else if (!missing.includes(entry.hash)) missing.push(entry.hash);
|
|
5276
|
+
}
|
|
5277
|
+
if (missing.length > 0) {
|
|
5278
|
+
for (let i = 0; i < missing.length; i += KNOWLEDGE_FETCH_CHUNK) {
|
|
5279
|
+
const chunk2 = missing.slice(i, i + KNOWLEDGE_FETCH_CHUNK);
|
|
5280
|
+
try {
|
|
5281
|
+
for (const { hash, content } of await fetchContents(chunk2)) {
|
|
5282
|
+
if (!writeCachedKnowledge(cacheDir, hash, content)) {
|
|
5283
|
+
log2?.(`[knowledge] hash mismatch for ${hash} \u2014 dropping this poll`);
|
|
5284
|
+
continue;
|
|
5285
|
+
}
|
|
5286
|
+
bodies.set(hash, content);
|
|
5287
|
+
}
|
|
5288
|
+
} catch (err) {
|
|
5289
|
+
log2?.(`[knowledge] fetch failed for ${chunk2.length} entries: ${err.message}`);
|
|
5290
|
+
}
|
|
5291
|
+
}
|
|
5292
|
+
}
|
|
5293
|
+
sweepKnowledgeCache(cacheDir);
|
|
5294
|
+
return manifest.map((e) => ({
|
|
5295
|
+
...meta(e),
|
|
5296
|
+
content: (e.hash ? bodies.get(e.hash) : void 0) ?? null
|
|
5297
|
+
}));
|
|
5298
|
+
}
|
|
5299
|
+
|
|
5477
5300
|
// src/lib/channel-hash-cache.ts
|
|
5478
|
-
import { existsSync as existsSync7, readFileSync as readFileSync18, writeFileSync as
|
|
5301
|
+
import { existsSync as existsSync7, readFileSync as readFileSync18, writeFileSync as writeFileSync9 } from "fs";
|
|
5479
5302
|
import { join as join24 } from "path";
|
|
5480
5303
|
var CACHE_FILENAME = "channel-hash-cache.json";
|
|
5481
5304
|
function getChannelHashCacheFile(configDir) {
|
|
@@ -5500,7 +5323,7 @@ function saveChannelHashCache(source, configDir) {
|
|
|
5500
5323
|
const obj = {};
|
|
5501
5324
|
for (const [key, value] of source) obj[key] = value;
|
|
5502
5325
|
try {
|
|
5503
|
-
|
|
5326
|
+
writeFileSync9(path, JSON.stringify(obj, null, 2));
|
|
5504
5327
|
} catch {
|
|
5505
5328
|
}
|
|
5506
5329
|
}
|
|
@@ -6147,14 +5970,14 @@ import { join as join27 } from "path";
|
|
|
6147
5970
|
function integrationSkillHashKey(agentId, skillId) {
|
|
6148
5971
|
return `plugin-skill:${agentId}:${skillId}`;
|
|
6149
5972
|
}
|
|
6150
|
-
function shouldWriteIntegrationSkill(
|
|
6151
|
-
return
|
|
5973
|
+
function shouldWriteIntegrationSkill(cache2, agentId, skillId, contentHash) {
|
|
5974
|
+
return cache2.get(integrationSkillHashKey(agentId, skillId)) !== contentHash;
|
|
6152
5975
|
}
|
|
6153
|
-
function rememberIntegrationSkill(
|
|
6154
|
-
|
|
5976
|
+
function rememberIntegrationSkill(cache2, agentId, skillId, contentHash) {
|
|
5977
|
+
cache2.set(integrationSkillHashKey(agentId, skillId), contentHash);
|
|
6155
5978
|
}
|
|
6156
|
-
function forgetIntegrationSkill(
|
|
6157
|
-
|
|
5979
|
+
function forgetIntegrationSkill(cache2, agentId, skillId) {
|
|
5980
|
+
cache2.delete(integrationSkillHashKey(agentId, skillId));
|
|
6158
5981
|
}
|
|
6159
5982
|
function removeIntegrationSkillFolder(opts) {
|
|
6160
5983
|
forgetIntegrationSkill(opts.cache, opts.agentId, opts.entry);
|
|
@@ -6164,8 +5987,8 @@ function removeIntegrationSkillFolder(opts) {
|
|
|
6164
5987
|
}
|
|
6165
5988
|
|
|
6166
5989
|
// src/lib/manager/managed-skill-manifest.ts
|
|
6167
|
-
import { existsSync as existsSync10, mkdirSync as
|
|
6168
|
-
import { dirname as
|
|
5990
|
+
import { existsSync as existsSync10, mkdirSync as mkdirSync7, readFileSync as readFileSync21, writeFileSync as writeFileSync10 } from "fs";
|
|
5991
|
+
import { dirname as dirname7, join as join28 } from "path";
|
|
6169
5992
|
var MANIFEST_VERSION = 1;
|
|
6170
5993
|
function managedSkillManifestPath(agentRootDir) {
|
|
6171
5994
|
return join28(agentRootDir, "managed-skills.json");
|
|
@@ -6182,12 +6005,12 @@ function readManagedSkillManifest(path) {
|
|
|
6182
6005
|
}
|
|
6183
6006
|
function writeManagedSkillManifest(path, ids) {
|
|
6184
6007
|
try {
|
|
6185
|
-
|
|
6008
|
+
mkdirSync7(dirname7(path), { recursive: true });
|
|
6186
6009
|
const body = {
|
|
6187
6010
|
version: MANIFEST_VERSION,
|
|
6188
6011
|
globalSkillIds: [...ids].sort()
|
|
6189
6012
|
};
|
|
6190
|
-
|
|
6013
|
+
writeFileSync10(path, JSON.stringify(body, null, 2));
|
|
6191
6014
|
} catch {
|
|
6192
6015
|
}
|
|
6193
6016
|
}
|
|
@@ -6299,9 +6122,9 @@ function resolveModelChain(refreshData) {
|
|
|
6299
6122
|
}
|
|
6300
6123
|
|
|
6301
6124
|
// src/lib/manager/claude-auth.ts
|
|
6302
|
-
import { existsSync as existsSync11, rmSync as
|
|
6125
|
+
import { existsSync as existsSync11, rmSync as rmSync4 } from "fs";
|
|
6303
6126
|
import { join as join29 } from "path";
|
|
6304
|
-
import { homedir as
|
|
6127
|
+
import { homedir as homedir13 } from "os";
|
|
6305
6128
|
async function applyClaudeAuthToEnv(childEnv, label) {
|
|
6306
6129
|
const apiKey = getApiKey();
|
|
6307
6130
|
if (!apiKey) {
|
|
@@ -6313,12 +6136,12 @@ async function applyClaudeAuthToEnv(childEnv, label) {
|
|
|
6313
6136
|
throw new Error("claude_auth_mode=api_key but /host/exchange returned no decrypted key");
|
|
6314
6137
|
}
|
|
6315
6138
|
childEnv.ANTHROPIC_API_KEY = exchange.anthropicApiKey;
|
|
6316
|
-
const claudeDir = join29(
|
|
6139
|
+
const claudeDir = join29(homedir13(), ".claude");
|
|
6317
6140
|
for (const filename of [".credentials.json", "credentials.json"]) {
|
|
6318
6141
|
const p = join29(claudeDir, filename);
|
|
6319
6142
|
if (existsSync11(p)) {
|
|
6320
6143
|
try {
|
|
6321
|
-
|
|
6144
|
+
rmSync4(p, { force: true });
|
|
6322
6145
|
log(`[${label}] Removed ${p} (api_key mode \u2014 preventing OAuth fallback)`);
|
|
6323
6146
|
} catch {
|
|
6324
6147
|
}
|
|
@@ -6696,7 +6519,7 @@ function formatBoardForPrompt(items, template) {
|
|
|
6696
6519
|
}
|
|
6697
6520
|
|
|
6698
6521
|
// src/lib/manager/kanban/nudge-state-cache.ts
|
|
6699
|
-
import { existsSync as existsSync13, readFileSync as readFileSync23, writeFileSync as
|
|
6522
|
+
import { existsSync as existsSync13, readFileSync as readFileSync23, writeFileSync as writeFileSync11 } from "fs";
|
|
6700
6523
|
import { join as join31 } from "path";
|
|
6701
6524
|
var CACHE_FILENAME2 = "kanban-nudge-state.json";
|
|
6702
6525
|
var KANBAN_NUDGE_STATE_VERSION = 1;
|
|
@@ -6740,13 +6563,13 @@ function saveKanbanNudgeState(source, configDir) {
|
|
|
6740
6563
|
const agents = {};
|
|
6741
6564
|
for (const [codeName, state9] of source) agents[codeName] = state9;
|
|
6742
6565
|
try {
|
|
6743
|
-
|
|
6566
|
+
writeFileSync11(path, JSON.stringify({ version: KANBAN_NUDGE_STATE_VERSION, agents }, null, 2));
|
|
6744
6567
|
} catch {
|
|
6745
6568
|
}
|
|
6746
6569
|
}
|
|
6747
6570
|
|
|
6748
6571
|
// src/lib/manager/kanban/notify.ts
|
|
6749
|
-
import { createHash as
|
|
6572
|
+
import { createHash as createHash10 } from "crypto";
|
|
6750
6573
|
async function enqueueKanbanNotice(opts) {
|
|
6751
6574
|
try {
|
|
6752
6575
|
const res = await api.post(
|
|
@@ -6761,7 +6584,7 @@ async function enqueueKanbanNotice(opts) {
|
|
|
6761
6584
|
return res.ok === true;
|
|
6762
6585
|
} catch (err) {
|
|
6763
6586
|
const errText = err instanceof Error ? err.message : String(err);
|
|
6764
|
-
const errId =
|
|
6587
|
+
const errId = createHash10("sha256").update(errText).digest("hex").slice(0, 12);
|
|
6765
6588
|
log(`[kanban] notice enqueue failed for agent_id=${opts.agentId} error_id=${errId}`);
|
|
6766
6589
|
return false;
|
|
6767
6590
|
}
|
|
@@ -6776,7 +6599,7 @@ async function cancelKanbanNotice(agentId) {
|
|
|
6776
6599
|
return typeof res.cancelled === "number" ? res.cancelled : 0;
|
|
6777
6600
|
} catch (err) {
|
|
6778
6601
|
const errText = err instanceof Error ? err.message : String(err);
|
|
6779
|
-
const errId =
|
|
6602
|
+
const errId = createHash10("sha256").update(errText).digest("hex").slice(0, 12);
|
|
6780
6603
|
log(`[kanban] notice cancel failed for agent_id=${agentId} error_id=${errId}`);
|
|
6781
6604
|
return null;
|
|
6782
6605
|
}
|
|
@@ -7182,7 +7005,7 @@ function deriveScheduledTaskNotify(task) {
|
|
|
7182
7005
|
}
|
|
7183
7006
|
|
|
7184
7007
|
// src/lib/manager/scheduler/runs.ts
|
|
7185
|
-
import { createHash as
|
|
7008
|
+
import { createHash as createHash11 } from "crypto";
|
|
7186
7009
|
async function startRun(opts) {
|
|
7187
7010
|
try {
|
|
7188
7011
|
const res = await api.post(
|
|
@@ -7197,7 +7020,7 @@ async function startRun(opts) {
|
|
|
7197
7020
|
};
|
|
7198
7021
|
} catch (err) {
|
|
7199
7022
|
const errText = err instanceof Error ? err.message : String(err);
|
|
7200
|
-
const errId =
|
|
7023
|
+
const errId = createHash11("sha256").update(errText).digest("hex").slice(0, 12);
|
|
7201
7024
|
log(`[runs] start failed for agent_id=${opts.agent_id} source_type=${opts.source_type} error_id=${errId}`);
|
|
7202
7025
|
return { run_id: null, kanban_item_id: null };
|
|
7203
7026
|
}
|
|
@@ -7236,7 +7059,7 @@ async function finishRun(runId, outcome, options = {}) {
|
|
|
7236
7059
|
return;
|
|
7237
7060
|
} catch (err) {
|
|
7238
7061
|
const errText = err instanceof Error ? err.message : String(err);
|
|
7239
|
-
const errId =
|
|
7062
|
+
const errId = createHash11("sha256").update(errText).digest("hex").slice(0, 12);
|
|
7240
7063
|
const status = err instanceof ApiError ? err.status : 0;
|
|
7241
7064
|
if (isRetryableFinishError(err) && attempt < maxRetries) {
|
|
7242
7065
|
log(
|
|
@@ -7265,7 +7088,7 @@ async function fetchPriorScheduledRuns(agentId, taskId) {
|
|
|
7265
7088
|
return rows.filter((r) => typeof r.output_text === "string" && r.output_text.length > 0).map((r) => ({ startedAt: r.started_at, output: r.output_text }));
|
|
7266
7089
|
} catch (err) {
|
|
7267
7090
|
const errText = err instanceof Error ? err.message : String(err);
|
|
7268
|
-
const errId =
|
|
7091
|
+
const errId = createHash11("sha256").update(errText).digest("hex").slice(0, 12);
|
|
7269
7092
|
log(`[runs] prior-runs lookup failed for task_id=${taskId} error_id=${errId}`);
|
|
7270
7093
|
return [];
|
|
7271
7094
|
}
|
|
@@ -7325,13 +7148,13 @@ function closeSessionRunForCode(codeName, outcome, reason) {
|
|
|
7325
7148
|
}
|
|
7326
7149
|
|
|
7327
7150
|
// src/lib/manager/scheduler/kanban-route.ts
|
|
7328
|
-
import { createHash as
|
|
7329
|
-
import { writeFileSync as
|
|
7330
|
-
import { homedir as
|
|
7331
|
-
import { join as join32, dirname as
|
|
7151
|
+
import { createHash as createHash13 } from "crypto";
|
|
7152
|
+
import { writeFileSync as writeFileSync12, renameSync as renameSync6, mkdirSync as mkdirSync8, readFileSync as readFileSync24, unlinkSync as unlinkSync3 } from "fs";
|
|
7153
|
+
import { homedir as homedir14 } from "os";
|
|
7154
|
+
import { join as join32, dirname as dirname8 } from "path";
|
|
7332
7155
|
|
|
7333
7156
|
// src/lib/manager/scheduler/notify.ts
|
|
7334
|
-
import { createHash as
|
|
7157
|
+
import { createHash as createHash12 } from "crypto";
|
|
7335
7158
|
async function enqueueScheduledTaskNotice(opts) {
|
|
7336
7159
|
try {
|
|
7337
7160
|
const res = await api.post(
|
|
@@ -7348,7 +7171,7 @@ async function enqueueScheduledTaskNotice(opts) {
|
|
|
7348
7171
|
return res.ok === true;
|
|
7349
7172
|
} catch (err) {
|
|
7350
7173
|
const errText = err instanceof Error ? err.message : String(err);
|
|
7351
|
-
const errId =
|
|
7174
|
+
const errId = createHash12("sha256").update(errText).digest("hex").slice(0, 12);
|
|
7352
7175
|
log(
|
|
7353
7176
|
`[scheduled-kanban] notice enqueue failed for agent_id=${opts.agentId} task_id=${opts.taskId} error_id=${errId}`
|
|
7354
7177
|
);
|
|
@@ -7687,17 +7510,17 @@ function resolveScheduledSlackTarget(task) {
|
|
|
7687
7510
|
}
|
|
7688
7511
|
function stampScheduledTurnMarker(codeName, taskId, target) {
|
|
7689
7512
|
try {
|
|
7690
|
-
const file = join32(
|
|
7513
|
+
const file = join32(homedir14(), ".augmented", codeName, SCHEDULED_TURN_MARKER_FILENAME);
|
|
7691
7514
|
const marker = { ts: Date.now(), task_id: taskId, ...target ? { target } : {} };
|
|
7692
7515
|
const tmp = `${file}.tmp`;
|
|
7693
|
-
|
|
7694
|
-
|
|
7516
|
+
writeFileSync12(tmp, JSON.stringify(marker), "utf8");
|
|
7517
|
+
renameSync6(tmp, file);
|
|
7695
7518
|
} catch (err) {
|
|
7696
7519
|
log(`[scheduled-kanban] scheduled-turn marker write failed for '${codeName}': ${err.message}`);
|
|
7697
7520
|
}
|
|
7698
7521
|
}
|
|
7699
7522
|
function clearScheduledTurnMarkerForTask(codeName, taskId) {
|
|
7700
|
-
const file = join32(
|
|
7523
|
+
const file = join32(homedir14(), ".augmented", codeName, SCHEDULED_TURN_MARKER_FILENAME);
|
|
7701
7524
|
try {
|
|
7702
7525
|
const raw = JSON.parse(readFileSync24(file, "utf8"));
|
|
7703
7526
|
if (typeof raw?.task_id !== "string" || raw.task_id !== taskId) return;
|
|
@@ -7759,9 +7582,9 @@ async function routeScheduledTaskViaKanban(codeName, agentId, task, prompt, dura
|
|
|
7759
7582
|
return false;
|
|
7760
7583
|
}
|
|
7761
7584
|
try {
|
|
7762
|
-
const doorbell = directChatDoorbellPath(agentId,
|
|
7763
|
-
|
|
7764
|
-
|
|
7585
|
+
const doorbell = directChatDoorbellPath(agentId, homedir14());
|
|
7586
|
+
mkdirSync8(dirname8(doorbell), { recursive: true });
|
|
7587
|
+
writeFileSync12(doorbell, String(Date.now()));
|
|
7765
7588
|
} catch (err) {
|
|
7766
7589
|
log(`[scheduled-kanban] doorbell ring failed for '${codeName}': ${err.message} (notice still queued)`);
|
|
7767
7590
|
}
|
|
@@ -7827,24 +7650,24 @@ async function processClaudeTaskResult(codeName, agentId, templateId, rawOutput,
|
|
|
7827
7650
|
const assertion = parseDeliverAssertion(rawOutput);
|
|
7828
7651
|
if (!assertion.deliver) {
|
|
7829
7652
|
const trimmed = (rawOutput ?? "").trim();
|
|
7830
|
-
const outputHash = trimmed.length === 0 ? "empty" :
|
|
7653
|
+
const outputHash = trimmed.length === 0 ? "empty" : createHash13("sha256").update(trimmed).digest("hex").slice(0, 12);
|
|
7831
7654
|
log(`[claude-scheduler] Suppressed by delivery_policy=conditional for '${codeName}' (template=${templateId}, task=${delivery?.taskId ?? "n/a"}) \u2014 ${assertion.vacuous ? "deliver marker had a vacuous reason" : "no deliver marker"}; output_len=${trimmed.length} output_hash=${outputHash}`);
|
|
7832
7655
|
if (delivery?.mode === "announce" && delivery.to) {
|
|
7833
7656
|
await reportDeliveryStatus(agentId, delivery.taskId, { status: "skipped", error_code: "SUPPRESSED_BY_POLICY" });
|
|
7834
7657
|
}
|
|
7835
7658
|
return { ok: true };
|
|
7836
7659
|
}
|
|
7837
|
-
const reasonHash =
|
|
7660
|
+
const reasonHash = createHash13("sha256").update(assertion.reason ?? "").digest("hex").slice(0, 12);
|
|
7838
7661
|
log(`[claude-scheduler] Delivering conditional run for '${codeName}' (template=${templateId}, task=${delivery?.taskId ?? "n/a"}) \u2014 agent asserted a concrete trigger (reason_len=${(assertion.reason ?? "").length} reason_hash=${reasonHash})`);
|
|
7839
7662
|
rawOutput = assertion.deliverable;
|
|
7840
7663
|
}
|
|
7841
7664
|
const classification = classifyOutput(rawOutput);
|
|
7842
7665
|
if (classification.action === "suppress") {
|
|
7843
7666
|
const trimmed = (rawOutput ?? "").trim();
|
|
7844
|
-
const outputHash = trimmed.length === 0 ? "empty" :
|
|
7667
|
+
const outputHash = trimmed.length === 0 ? "empty" : createHash13("sha256").update(trimmed).digest("hex").slice(0, 12);
|
|
7845
7668
|
log(`[claude-scheduler] Suppressing delivery for '${codeName}' (template=${templateId}, task=${delivery?.taskId ?? "n/a"}) \u2014 output_len=${trimmed.length} output_hash=${outputHash}`);
|
|
7846
7669
|
if (classification.suppressedNotes) {
|
|
7847
|
-
const notesHash =
|
|
7670
|
+
const notesHash = createHash13("sha256").update(classification.suppressedNotes).digest("hex").slice(0, 12);
|
|
7848
7671
|
log(`[claude-scheduler] Suppressed notes for '${codeName}' (task=${delivery?.taskId ?? "n/a"}) \u2014 notes_len=${classification.suppressedNotes.length} notes_hash=${notesHash}`);
|
|
7849
7672
|
}
|
|
7850
7673
|
if (delivery?.mode === "announce" && delivery.to) {
|
|
@@ -7910,12 +7733,12 @@ async function processClaudeTaskResult(codeName, agentId, templateId, rawOutput,
|
|
|
7910
7733
|
}
|
|
7911
7734
|
|
|
7912
7735
|
// src/lib/manager/scheduler/execution.ts
|
|
7913
|
-
import { createHash as
|
|
7914
|
-
import { homedir as
|
|
7736
|
+
import { createHash as createHash14 } from "crypto";
|
|
7737
|
+
import { homedir as homedir15 } from "os";
|
|
7915
7738
|
import { join as join34 } from "path";
|
|
7916
7739
|
|
|
7917
7740
|
// src/lib/agent-serving-probe.ts
|
|
7918
|
-
import { readFileSync as readFileSync25, readdirSync as readdirSync6, statSync as
|
|
7741
|
+
import { readFileSync as readFileSync25, readdirSync as readdirSync6, statSync as statSync6 } from "fs";
|
|
7919
7742
|
import { join as join33 } from "path";
|
|
7920
7743
|
var RATE_LIMIT_WINDOW_MS = 6 * 60 * 60 * 1e3;
|
|
7921
7744
|
function probeRateLimit(args) {
|
|
@@ -7934,7 +7757,7 @@ function probeRateLimit(args) {
|
|
|
7934
7757
|
if (!name.endsWith(".jsonl")) continue;
|
|
7935
7758
|
const path = join33(dir, name);
|
|
7936
7759
|
try {
|
|
7937
|
-
const st =
|
|
7760
|
+
const st = statSync6(path);
|
|
7938
7761
|
if (!st.isFile() || st.mtimeMs < startMs) continue;
|
|
7939
7762
|
} catch {
|
|
7940
7763
|
continue;
|
|
@@ -8003,7 +7826,7 @@ function shouldLogUsageCapDeferral(site, codeName, limitedUntil) {
|
|
|
8003
7826
|
|
|
8004
7827
|
// src/lib/manager/scheduler/execution.ts
|
|
8005
7828
|
function claudePidFilePath() {
|
|
8006
|
-
return join34(
|
|
7829
|
+
return join34(homedir15(), ".augmented", "manager-claude-pids.json");
|
|
8007
7830
|
}
|
|
8008
7831
|
var inFlightClaudePids = /* @__PURE__ */ new Map();
|
|
8009
7832
|
function registerClaudeSpawn(record) {
|
|
@@ -8023,10 +7846,10 @@ function unregisterClaudeSpawn(pid) {
|
|
|
8023
7846
|
}
|
|
8024
7847
|
async function syncAndCheckClaudeScheduler(agent, tasks, boardItems, refreshData, durableScheduledNudge = false) {
|
|
8025
7848
|
const codeName = agent.code_name;
|
|
8026
|
-
const stableTasksHash =
|
|
8027
|
-
const boardHash = boardItems.length > 0 ?
|
|
7849
|
+
const stableTasksHash = createHash14("sha256").update(JSON.stringify(tasks)).digest("hex").slice(0, 16);
|
|
7850
|
+
const boardHash = boardItems.length > 0 ? createHash14("sha256").update(JSON.stringify(boardItems.map((b) => ({ id: b.id, title: b.title, status: b.status, priority: b.priority, deliverable: b.deliverable })))).digest("hex").slice(0, 16) : "empty";
|
|
8028
7851
|
const resolvedModels = resolveModelChain(refreshData);
|
|
8029
|
-
const modelsHash =
|
|
7852
|
+
const modelsHash = createHash14("sha256").update(JSON.stringify(resolvedModels)).digest("hex").slice(0, 16);
|
|
8030
7853
|
const combinedHash = `${stableTasksHash}:${boardHash}:${modelsHash}`;
|
|
8031
7854
|
const prevHash = agentState.knownTasksHashes.get(agent.agent_id);
|
|
8032
7855
|
if (combinedHash !== prevHash) {
|
|
@@ -8073,7 +7896,7 @@ async function syncAndCheckClaudeScheduler(agent, tasks, boardItems, refreshData
|
|
|
8073
7896
|
}
|
|
8074
7897
|
|
|
8075
7898
|
// src/lib/occupancy-gate.ts
|
|
8076
|
-
import { closeSync as closeSync2, openSync as openSync2, readdirSync as readdirSync7, readSync as readSync2, statSync as
|
|
7899
|
+
import { closeSync as closeSync2, openSync as openSync2, readdirSync as readdirSync7, readSync as readSync2, statSync as statSync7 } from "fs";
|
|
8077
7900
|
import { join as join35 } from "path";
|
|
8078
7901
|
function rostersMeasuredZero(mode, attested, runtimeRunning) {
|
|
8079
7902
|
return mode === "enforce" && attested && runtimeRunning;
|
|
@@ -8083,12 +7906,12 @@ var MAX_RECORD_ALIGN_BYTES = 8 * 1024 * 1024;
|
|
|
8083
7906
|
var GATE_MAX_BUCKET_AGE_MS = 30 * 6e4;
|
|
8084
7907
|
var MAX_BRACKET_DEFERRAL_MS = 25 * 6e4;
|
|
8085
7908
|
var TRANSCRIPT_MTIME_WINDOW_MS4 = GATE_MAX_BUCKET_AGE_MS + DEFAULT_NEIGHBOURHOOD_MS + 6e4;
|
|
8086
|
-
var
|
|
7909
|
+
var cache = /* @__PURE__ */ new Map();
|
|
8087
7910
|
var brackets = /* @__PURE__ */ new Map();
|
|
8088
7911
|
function readAlignedTail(path, tailBytes, maxAlignBytes) {
|
|
8089
7912
|
let fd = null;
|
|
8090
7913
|
try {
|
|
8091
|
-
const size =
|
|
7914
|
+
const size = statSync7(path).size;
|
|
8092
7915
|
if (size <= 0) return { content: "", complete: true, truncated: false };
|
|
8093
7916
|
fd = openSync2(path, "r");
|
|
8094
7917
|
let readStart = Math.max(0, size - tailBytes);
|
|
@@ -8218,7 +8041,7 @@ function collectQualifyingTurns(codeName, nowMs, opts = {}) {
|
|
|
8218
8041
|
const tailBytes = opts.tailBytes ?? TAIL_BYTES;
|
|
8219
8042
|
const maxAlignBytes = opts.maxAlignBytes ?? MAX_RECORD_ALIGN_BYTES;
|
|
8220
8043
|
const sinceMs = nowMs - TRANSCRIPT_MTIME_WINDOW_MS4;
|
|
8221
|
-
const agentCache =
|
|
8044
|
+
const agentCache = cache.get(codeName) ?? /* @__PURE__ */ new Map();
|
|
8222
8045
|
const nextCache = /* @__PURE__ */ new Map();
|
|
8223
8046
|
const all = /* @__PURE__ */ new Set();
|
|
8224
8047
|
const eventsByPath = /* @__PURE__ */ new Map();
|
|
@@ -8232,7 +8055,7 @@ function collectQualifyingTurns(codeName, nowMs, opts = {}) {
|
|
|
8232
8055
|
for (const path of paths) {
|
|
8233
8056
|
let st;
|
|
8234
8057
|
try {
|
|
8235
|
-
st =
|
|
8058
|
+
st = statSync7(path);
|
|
8236
8059
|
} catch (err) {
|
|
8237
8060
|
if (!isAbsentDirError(err)) complete = false;
|
|
8238
8061
|
continue;
|
|
@@ -8271,7 +8094,7 @@ function collectQualifyingTurns(codeName, nowMs, opts = {}) {
|
|
|
8271
8094
|
}
|
|
8272
8095
|
for (const t of turns) all.add(t);
|
|
8273
8096
|
}
|
|
8274
|
-
|
|
8097
|
+
cache.set(codeName, nextCache);
|
|
8275
8098
|
const { toolCallBrackets, openToolCalls } = foldToolCallBrackets(codeName, eventsByPath, nowMs);
|
|
8276
8099
|
return {
|
|
8277
8100
|
turns: [...all].sort((a, b) => a - b),
|
|
@@ -8338,7 +8161,7 @@ function qualifyBuckets(buckets, qualifying, mode, nowMs, neighbourhoodMs = DEFA
|
|
|
8338
8161
|
}
|
|
8339
8162
|
|
|
8340
8163
|
// src/lib/pane-occupancy-sampler.ts
|
|
8341
|
-
import { statSync as
|
|
8164
|
+
import { statSync as statSync8 } from "fs";
|
|
8342
8165
|
var SAMPLE_INTERVAL_MS = 1e4;
|
|
8343
8166
|
var IDLE_GAP_MS = 12e4;
|
|
8344
8167
|
var POST_IDLE_CREDIT_MS = 6e4;
|
|
@@ -8352,7 +8175,7 @@ function hasFreshPaneObservation(codeName, nowMs, maxAgeMs = OBSERVATION_FRESH_M
|
|
|
8352
8175
|
}
|
|
8353
8176
|
function paneMtimeMs(codeName) {
|
|
8354
8177
|
try {
|
|
8355
|
-
return
|
|
8178
|
+
return statSync8(paneLogPath(codeName)).mtimeMs;
|
|
8356
8179
|
} catch {
|
|
8357
8180
|
return null;
|
|
8358
8181
|
}
|
|
@@ -8544,7 +8367,7 @@ function stopPidPressureSampler() {
|
|
|
8544
8367
|
}
|
|
8545
8368
|
|
|
8546
8369
|
// src/lib/opencode-slack-ingest.ts
|
|
8547
|
-
import { createHash as
|
|
8370
|
+
import { createHash as createHash15 } from "crypto";
|
|
8548
8371
|
|
|
8549
8372
|
// ../../packages/core/dist/channels/slack-rich-text.js
|
|
8550
8373
|
var MAX_DEPTH = 12;
|
|
@@ -9551,7 +9374,7 @@ function startSlackIngest(config2) {
|
|
|
9551
9374
|
// src/lib/opencode-slack-ingest.ts
|
|
9552
9375
|
var ingests = /* @__PURE__ */ new Map();
|
|
9553
9376
|
function fingerprint(params) {
|
|
9554
|
-
return
|
|
9377
|
+
return createHash15("sha256").update(
|
|
9555
9378
|
JSON.stringify({
|
|
9556
9379
|
appToken: params.appToken,
|
|
9557
9380
|
botToken: params.botToken,
|
|
@@ -9632,7 +9455,7 @@ function stopAllOpencodeSlackIngests(log2) {
|
|
|
9632
9455
|
}
|
|
9633
9456
|
|
|
9634
9457
|
// src/lib/manager/opencode-scheduler.ts
|
|
9635
|
-
import { createHash as
|
|
9458
|
+
import { createHash as createHash16 } from "crypto";
|
|
9636
9459
|
var MAX_OPENCODE_SCHED_CONCURRENCY = 2;
|
|
9637
9460
|
var opencodeSchedulerStates = /* @__PURE__ */ new Map();
|
|
9638
9461
|
var inFlightOpencodeTasks = /* @__PURE__ */ new Set();
|
|
@@ -9646,7 +9469,7 @@ function shouldDeliver(task, reply) {
|
|
|
9646
9469
|
}
|
|
9647
9470
|
async function syncAndCheckOpencodeScheduler(agent, tasks, refreshData) {
|
|
9648
9471
|
const codeName = agent.code_name;
|
|
9649
|
-
const tasksHash =
|
|
9472
|
+
const tasksHash = createHash16("sha256").update(JSON.stringify(tasks)).digest("hex").slice(0, 16);
|
|
9650
9473
|
if (knownOpencodeTaskHashes.get(agent.agent_id) !== tasksHash) {
|
|
9651
9474
|
const taskInputs = tasks.map((t) => buildSchedulerTaskInput(t));
|
|
9652
9475
|
const state10 = syncTasksToScheduler(codeName, agent.agent_id, taskInputs);
|
|
@@ -9724,8 +9547,8 @@ async function fireOpencodeScheduledTask(agent, task) {
|
|
|
9724
9547
|
}
|
|
9725
9548
|
|
|
9726
9549
|
// src/lib/opencode-telegram-ingest.ts
|
|
9727
|
-
import { createHash as
|
|
9728
|
-
import { existsSync as existsSync15, mkdirSync as
|
|
9550
|
+
import { createHash as createHash17 } from "crypto";
|
|
9551
|
+
import { existsSync as existsSync15, mkdirSync as mkdirSync9, readFileSync as readFileSync27, renameSync as renameSync7, unlinkSync as unlinkSync4, writeFileSync as writeFileSync13 } from "fs";
|
|
9729
9552
|
import { randomUUID } from "crypto";
|
|
9730
9553
|
import { join as join36 } from "path";
|
|
9731
9554
|
|
|
@@ -10260,7 +10083,7 @@ function anySignal(signals) {
|
|
|
10260
10083
|
// src/lib/opencode-telegram-ingest.ts
|
|
10261
10084
|
var ingests2 = /* @__PURE__ */ new Map();
|
|
10262
10085
|
function fingerprint2(params) {
|
|
10263
|
-
return
|
|
10086
|
+
return createHash17("sha256").update(
|
|
10264
10087
|
JSON.stringify({
|
|
10265
10088
|
botToken: params.botToken,
|
|
10266
10089
|
allowedChats: [...params.allowedChats].sort(),
|
|
@@ -10302,8 +10125,8 @@ function createFileOffsetStore(codeName, log2, currentBotId) {
|
|
|
10302
10125
|
if (!filePath || !dir) return;
|
|
10303
10126
|
const tmpPath = `${filePath}.${process.pid}.${randomUUID()}.tmp`;
|
|
10304
10127
|
try {
|
|
10305
|
-
|
|
10306
|
-
|
|
10128
|
+
mkdirSync9(dir, { recursive: true, mode: 448 });
|
|
10129
|
+
writeFileSync13(
|
|
10307
10130
|
tmpPath,
|
|
10308
10131
|
JSON.stringify({
|
|
10309
10132
|
offset,
|
|
@@ -10313,7 +10136,7 @@ function createFileOffsetStore(codeName, log2, currentBotId) {
|
|
|
10313
10136
|
}),
|
|
10314
10137
|
{ mode: 384 }
|
|
10315
10138
|
);
|
|
10316
|
-
|
|
10139
|
+
renameSync7(tmpPath, filePath);
|
|
10317
10140
|
} catch (err) {
|
|
10318
10141
|
log2(`[telegram-ingest:${codeName}] offset persist failed: ${err instanceof Error ? err.message : String(err)}`);
|
|
10319
10142
|
try {
|
|
@@ -10554,12 +10377,12 @@ function partitionActionableByPoison(actionable, states, config2) {
|
|
|
10554
10377
|
}
|
|
10555
10378
|
|
|
10556
10379
|
// src/lib/restart-flags.ts
|
|
10557
|
-
import { existsSync as existsSync16, mkdirSync as
|
|
10558
|
-
import { homedir as
|
|
10380
|
+
import { existsSync as existsSync16, mkdirSync as mkdirSync10, readdirSync as readdirSync8, readFileSync as readFileSync28, renameSync as renameSync8, rmSync as rmSync5, writeFileSync as writeFileSync14 } from "fs";
|
|
10381
|
+
import { homedir as homedir16 } from "os";
|
|
10559
10382
|
import { join as join37 } from "path";
|
|
10560
10383
|
import { randomUUID as randomUUID2 } from "crypto";
|
|
10561
10384
|
function restartFlagsDir() {
|
|
10562
|
-
return join37(
|
|
10385
|
+
return join37(homedir16(), ".augmented", "restart-flags");
|
|
10563
10386
|
}
|
|
10564
10387
|
function flagPath(codeName) {
|
|
10565
10388
|
return join37(restartFlagsDir(), `${codeName}.flag`);
|
|
@@ -10590,7 +10413,7 @@ function readRestartFlags() {
|
|
|
10590
10413
|
function deleteRestartFlag(codeName) {
|
|
10591
10414
|
const path = flagPath(codeName);
|
|
10592
10415
|
if (existsSync16(path)) {
|
|
10593
|
-
|
|
10416
|
+
rmSync5(path, { force: true });
|
|
10594
10417
|
}
|
|
10595
10418
|
}
|
|
10596
10419
|
|
|
@@ -10689,8 +10512,8 @@ async function sendError(flag, opts, text) {
|
|
|
10689
10512
|
}
|
|
10690
10513
|
|
|
10691
10514
|
// src/lib/restart-context.ts
|
|
10692
|
-
import { readdirSync as readdirSync9, readFileSync as readFileSync29, writeFileSync as
|
|
10693
|
-
import { dirname as
|
|
10515
|
+
import { readdirSync as readdirSync9, readFileSync as readFileSync29, writeFileSync as writeFileSync15, mkdirSync as mkdirSync11, unlinkSync as unlinkSync5 } from "fs";
|
|
10516
|
+
import { dirname as dirname9, join as join38 } from "path";
|
|
10694
10517
|
var SLACK_PENDING_INBOUND_DIRNAME = "slack-pending-inbound";
|
|
10695
10518
|
var SLACK_RESTART_CONTEXT_DIRNAME = "slack-restart-context";
|
|
10696
10519
|
var MAX_TOPIC_CHARS = 140;
|
|
@@ -10699,7 +10522,7 @@ var RECONSTRUCT_WINDOW_MS = 7 * 24 * 60 * 60 * 1e3;
|
|
|
10699
10522
|
var WINDOW_PAD_MS3 = 5 * 6e4;
|
|
10700
10523
|
var DEFAULT_MAX_MARKERS_PER_AGENT = 25;
|
|
10701
10524
|
function augmentedAgentDir(codeName) {
|
|
10702
|
-
return
|
|
10525
|
+
return dirname9(getProjectDir(codeName));
|
|
10703
10526
|
}
|
|
10704
10527
|
function slackPendingInboundDir(codeName) {
|
|
10705
10528
|
return join38(augmentedAgentDir(codeName), SLACK_PENDING_INBOUND_DIRNAME);
|
|
@@ -10756,8 +10579,8 @@ function readStrandedMarker(path) {
|
|
|
10756
10579
|
return null;
|
|
10757
10580
|
}
|
|
10758
10581
|
function writeHintFile(path, dir, hint) {
|
|
10759
|
-
|
|
10760
|
-
|
|
10582
|
+
mkdirSync11(dir, { recursive: true, mode: 448 });
|
|
10583
|
+
writeFileSync15(path, JSON.stringify(hint), { mode: 384 });
|
|
10761
10584
|
}
|
|
10762
10585
|
function pruneHintsExcept(codeName, freshFilenames) {
|
|
10763
10586
|
const ctxDir = slackRestartContextDir(codeName);
|
|
@@ -12178,8 +12001,8 @@ var pendingDayRolloverReset = /* @__PURE__ */ new Set();
|
|
|
12178
12001
|
var dayRolloverInboundHold = /* @__PURE__ */ new Map();
|
|
12179
12002
|
var INBOUND_HOLD_EPISODE_GAP_MS = 12e4;
|
|
12180
12003
|
async function channelInboundActivityAgeSecondsFor(codeName) {
|
|
12181
|
-
const { newestPendingInboundActivityMtimeMs } = await import("../responsiveness-probe-
|
|
12182
|
-
const newest = newestPendingInboundActivityMtimeMs(
|
|
12004
|
+
const { newestPendingInboundActivityMtimeMs } = await import("../responsiveness-probe-TDZDQXBU.js");
|
|
12005
|
+
const newest = newestPendingInboundActivityMtimeMs(dirname10(paneLogPath(codeName)));
|
|
12183
12006
|
if (newest === null) return null;
|
|
12184
12007
|
return Math.max(0, Math.floor((Date.now() - newest) / 1e3));
|
|
12185
12008
|
}
|
|
@@ -12278,7 +12101,7 @@ function performLazyDayRolloverReset(codeName, agentTimezone) {
|
|
|
12278
12101
|
}
|
|
12279
12102
|
function paneLogAgeSecondsFor(codeName) {
|
|
12280
12103
|
try {
|
|
12281
|
-
const mtimeMs =
|
|
12104
|
+
const mtimeMs = statSync9(paneLogPath(codeName)).mtimeMs;
|
|
12282
12105
|
return Math.max(0, Math.floor((Date.now() - mtimeMs) / 1e3));
|
|
12283
12106
|
} catch (err) {
|
|
12284
12107
|
if (err?.code === "ENOENT") return null;
|
|
@@ -12429,7 +12252,7 @@ var sessionLaunchManagedStructure = /* @__PURE__ */ new Map();
|
|
|
12429
12252
|
function projectMcpHash(_codeName, projectDir) {
|
|
12430
12253
|
try {
|
|
12431
12254
|
const raw = readFileSync30(join39(projectDir, ".mcp.json"), "utf-8");
|
|
12432
|
-
return
|
|
12255
|
+
return createHash18("sha256").update(canonicalJson(JSON.parse(raw))).digest("hex");
|
|
12433
12256
|
} catch {
|
|
12434
12257
|
return null;
|
|
12435
12258
|
}
|
|
@@ -12826,7 +12649,7 @@ var agentRestartTimezoneInputs = /* @__PURE__ */ new Map();
|
|
|
12826
12649
|
var lastVersionCheckAt = 0;
|
|
12827
12650
|
var VERSION_CHECK_INTERVAL_MS = 5 * 60 * 1e3;
|
|
12828
12651
|
var lastResponsivenessProbeAt = 0;
|
|
12829
|
-
var agtCliVersion = true ? "0.28.
|
|
12652
|
+
var agtCliVersion = true ? "0.28.717" : "dev";
|
|
12830
12653
|
function resolveBrewPath(execFileSync3) {
|
|
12831
12654
|
try {
|
|
12832
12655
|
const out = execFileSync3("which", ["brew"], { timeout: 5e3 }).toString().trim();
|
|
@@ -12921,7 +12744,7 @@ async function ensureToolkitCli(toolkitSlug) {
|
|
|
12921
12744
|
toolkitCliEnsured.add(toolkitSlug);
|
|
12922
12745
|
return;
|
|
12923
12746
|
}
|
|
12924
|
-
brewBinDir =
|
|
12747
|
+
brewBinDir = dirname10(brewPath);
|
|
12925
12748
|
const isRoot = typeof process.getuid === "function" && process.getuid() === 0;
|
|
12926
12749
|
log(`[toolkit-install] ${toolkitSlug}: installing via brew (${pkg})\u2026`);
|
|
12927
12750
|
if (isRoot) {
|
|
@@ -13114,8 +12937,8 @@ async function reapSupersededRuntimeImages(imageUri, localTag) {
|
|
|
13114
12937
|
}
|
|
13115
12938
|
function runAsync(cmd, args, opts) {
|
|
13116
12939
|
return new Promise((resolve2, reject) => {
|
|
13117
|
-
import("child_process").then(({ spawn
|
|
13118
|
-
const child =
|
|
12940
|
+
import("child_process").then(({ spawn }) => {
|
|
12941
|
+
const child = spawn(cmd, args, { stdio: ["ignore", "pipe", "pipe"], cwd: opts.cwd });
|
|
13119
12942
|
let stdout = "";
|
|
13120
12943
|
let stderr = "";
|
|
13121
12944
|
let settled = false;
|
|
@@ -13177,8 +13000,8 @@ function ensureClaudeManagedSettings(path = claudeManagedSettingsPath()) {
|
|
|
13177
13000
|
const missing = MANAGED_SETTINGS_KEYS.filter((key) => settings[key] !== true);
|
|
13178
13001
|
if (missing.length === 0) return "ok";
|
|
13179
13002
|
for (const key of missing) settings[key] = true;
|
|
13180
|
-
|
|
13181
|
-
|
|
13003
|
+
mkdirSync12(dirname10(path), { recursive: true });
|
|
13004
|
+
writeFileSync16(path, `${JSON.stringify(settings, null, 2)}
|
|
13182
13005
|
`);
|
|
13183
13006
|
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)`);
|
|
13184
13007
|
return "ok";
|
|
@@ -13273,7 +13096,7 @@ async function ensureFrameworkBinary(frameworkId) {
|
|
|
13273
13096
|
log(`Claude Code install failed: ${err.message}`);
|
|
13274
13097
|
return;
|
|
13275
13098
|
}
|
|
13276
|
-
const brewBinDir =
|
|
13099
|
+
const brewBinDir = dirname10(brewPath);
|
|
13277
13100
|
if (!process.env.PATH?.split(":").includes(brewBinDir)) {
|
|
13278
13101
|
process.env.PATH = `${brewBinDir}:${process.env.PATH ?? ""}`;
|
|
13279
13102
|
}
|
|
@@ -13333,7 +13156,7 @@ ${r.stderr}`;
|
|
|
13333
13156
|
}
|
|
13334
13157
|
var UPDATE_CHECK_INTERVAL_MS = 5 * 60 * 1e3;
|
|
13335
13158
|
function selfUpdateAppliedMarkerPath() {
|
|
13336
|
-
return join39(
|
|
13159
|
+
return join39(homedir17(), ".augmented", ".last-self-update-applied");
|
|
13337
13160
|
}
|
|
13338
13161
|
var selfUpdateUpToDateLogged = false;
|
|
13339
13162
|
var selfUpdatePinnedLogged = false;
|
|
@@ -13384,7 +13207,7 @@ async function checkAndUpdateCli(opts) {
|
|
|
13384
13207
|
const isNpmGlobal = !isBrewFormula && resolvedPath.includes("node_modules");
|
|
13385
13208
|
if (!isBrewFormula && !isNpmGlobal) return "noop";
|
|
13386
13209
|
const { readFileSync: readF, writeFileSync: writeF } = await import("fs");
|
|
13387
|
-
const markerPath = join39(
|
|
13210
|
+
const markerPath = join39(homedir17(), ".augmented", ".last-update-check");
|
|
13388
13211
|
if (!force) {
|
|
13389
13212
|
try {
|
|
13390
13213
|
const lastCheck = parseInt(readF(markerPath, "utf-8").trim(), 10);
|
|
@@ -13791,7 +13614,7 @@ async function runClaudeRuntimeAuthProbe() {
|
|
|
13791
13614
|
];
|
|
13792
13615
|
try {
|
|
13793
13616
|
const { stdout, stderr } = await execFilePromiseLong(resolveClaudeBinary(), args, {
|
|
13794
|
-
cwd:
|
|
13617
|
+
cwd: homedir17(),
|
|
13795
13618
|
timeout: RUNTIME_AUTH_PROBE_TIMEOUT_MS,
|
|
13796
13619
|
stdin: "ignore",
|
|
13797
13620
|
env: childEnv,
|
|
@@ -13831,7 +13654,7 @@ async function runHostUsageCommand() {
|
|
|
13831
13654
|
""
|
|
13832
13655
|
];
|
|
13833
13656
|
const { stdout } = await execFilePromiseLong(resolveClaudeBinary(), args, {
|
|
13834
|
-
cwd:
|
|
13657
|
+
cwd: homedir17(),
|
|
13835
13658
|
timeout: HOST_USAGE_POLL_TIMEOUT_MS,
|
|
13836
13659
|
stdin: "ignore",
|
|
13837
13660
|
env: childEnv,
|
|
@@ -13878,13 +13701,13 @@ async function checkClaudeAuth() {
|
|
|
13878
13701
|
var evalEmptyMcpConfigPath = null;
|
|
13879
13702
|
function ensureEvalEmptyMcpConfig() {
|
|
13880
13703
|
if (evalEmptyMcpConfigPath && existsSync17(evalEmptyMcpConfigPath)) return evalEmptyMcpConfigPath;
|
|
13881
|
-
const dir = join39(
|
|
13704
|
+
const dir = join39(homedir17(), ".augmented");
|
|
13882
13705
|
try {
|
|
13883
|
-
|
|
13706
|
+
mkdirSync12(dir, { recursive: true });
|
|
13884
13707
|
} catch {
|
|
13885
13708
|
}
|
|
13886
13709
|
const p = join39(dir, ".eval-empty-mcp.json");
|
|
13887
|
-
|
|
13710
|
+
writeFileSync16(p, JSON.stringify({ mcpServers: {} }));
|
|
13888
13711
|
evalEmptyMcpConfigPath = p;
|
|
13889
13712
|
return p;
|
|
13890
13713
|
}
|
|
@@ -13909,7 +13732,7 @@ async function runEvalClaude(prompt, model) {
|
|
|
13909
13732
|
""
|
|
13910
13733
|
];
|
|
13911
13734
|
const { stdout } = await execFilePromiseLong(resolveClaudeBinary(), args, {
|
|
13912
|
-
cwd:
|
|
13735
|
+
cwd: homedir17(),
|
|
13913
13736
|
timeout: 12e4,
|
|
13914
13737
|
stdin: "ignore",
|
|
13915
13738
|
env: childEnv,
|
|
@@ -14280,7 +14103,7 @@ function parseSkillFrontmatter(content) {
|
|
|
14280
14103
|
return out;
|
|
14281
14104
|
}
|
|
14282
14105
|
async function refreshSkillsIndexInClaudeMd(configDir, codeName, log2) {
|
|
14283
|
-
const { readdirSync: readdirSync11, readFileSync: rfs, existsSync: ex, writeFileSync:
|
|
14106
|
+
const { readdirSync: readdirSync11, readFileSync: rfs, existsSync: ex, writeFileSync: writeFileSync17 } = await import("fs");
|
|
14284
14107
|
const skillsDir = join39(configDir, codeName, "project", ".claude", "skills");
|
|
14285
14108
|
const claudeMdPath = join39(configDir, codeName, "project", "CLAUDE.md");
|
|
14286
14109
|
if (!ex(skillsDir) || !ex(claudeMdPath)) return;
|
|
@@ -14330,7 +14153,7 @@ ${SKILLS_INDEX_END}`;
|
|
|
14330
14153
|
next = current.trimEnd() + "\n\n" + section + "\n";
|
|
14331
14154
|
}
|
|
14332
14155
|
if (next !== current) {
|
|
14333
|
-
|
|
14156
|
+
writeFileSync17(claudeMdPath, next, "utf-8");
|
|
14334
14157
|
log2(
|
|
14335
14158
|
injectSkillList ? `Refreshed skills index in CLAUDE.md for '${codeName}' (${entries.length} skills)` : `Refreshed CLAUDE.md managed block for '${codeName}' (skill list suppressed by claude-md-skills-index=false; ${entries.length} skills on disk)`
|
|
14336
14159
|
);
|
|
@@ -14353,7 +14176,7 @@ function flushRestartedAgentDiagnostics(hostId, codeNames) {
|
|
|
14353
14176
|
if (codeNames.length === 0) return;
|
|
14354
14177
|
void (async () => {
|
|
14355
14178
|
try {
|
|
14356
|
-
const { collectDiagnostics } = await import("../persistent-session-
|
|
14179
|
+
const { collectDiagnostics } = await import("../persistent-session-GB3D5OIA.js");
|
|
14357
14180
|
await api.post("/host/heartbeat", {
|
|
14358
14181
|
host_id: hostId,
|
|
14359
14182
|
agent_diagnostics: collectDiagnostics(codeNames, quarantineEntriesFor, claudeMdSizeFor, spawnOutcomeForDiagnostics, pidPressureFor, forwardedToolsFor)
|
|
@@ -14471,7 +14294,7 @@ async function pollCycleInner() {
|
|
|
14471
14294
|
}
|
|
14472
14295
|
try {
|
|
14473
14296
|
const { detectHostSecurity } = await import("../host-security-6PDFG7F5.js");
|
|
14474
|
-
const { collectDiagnostics } = await import("../persistent-session-
|
|
14297
|
+
const { collectDiagnostics } = await import("../persistent-session-GB3D5OIA.js");
|
|
14475
14298
|
const diagCodeNames = [...agentState.persistentSessionAgents];
|
|
14476
14299
|
const agentDiagnostics = diagCodeNames.length > 0 ? collectDiagnostics(diagCodeNames, quarantineEntriesFor, claudeMdSizeFor, spawnOutcomeForDiagnostics, pidPressureFor, forwardedToolsFor) : void 0;
|
|
14477
14300
|
let tailscaleHostname;
|
|
@@ -14501,7 +14324,7 @@ async function pollCycleInner() {
|
|
|
14501
14324
|
claudeAuth = await detectClaudeAuth();
|
|
14502
14325
|
} catch (err) {
|
|
14503
14326
|
const errText = err instanceof Error ? err.message : String(err);
|
|
14504
|
-
const errId =
|
|
14327
|
+
const errId = createHash18("sha256").update(errText).digest("hex").slice(0, 12);
|
|
14505
14328
|
log(`Claude auth detection failed (error_id=${errId})`);
|
|
14506
14329
|
}
|
|
14507
14330
|
const hostHasClaudeCode = state8.agents.some(
|
|
@@ -14640,7 +14463,7 @@ async function pollCycleInner() {
|
|
|
14640
14463
|
collectPanelessActivityProbes,
|
|
14641
14464
|
getResponsivenessIntervalMs,
|
|
14642
14465
|
occupancyQualificationClassifications
|
|
14643
|
-
} = await import("../responsiveness-probe-
|
|
14466
|
+
} = await import("../responsiveness-probe-TDZDQXBU.js");
|
|
14644
14467
|
const probeIntervalMs = getResponsivenessIntervalMs();
|
|
14645
14468
|
if (now - lastResponsivenessProbeAt > probeIntervalMs) {
|
|
14646
14469
|
const probeCodeNames = [...agentState.persistentSessionAgents];
|
|
@@ -14750,7 +14573,7 @@ async function pollCycleInner() {
|
|
|
14750
14573
|
collectResponsivenessProbes,
|
|
14751
14574
|
livePendingInboundOldestAgeSeconds,
|
|
14752
14575
|
parkPendingInbound
|
|
14753
|
-
} = await import("../responsiveness-probe-
|
|
14576
|
+
} = await import("../responsiveness-probe-TDZDQXBU.js");
|
|
14754
14577
|
const { getProjectDir: wedgeProjectDir } = await import("../scheduler-engine-NDP36U7O.js");
|
|
14755
14578
|
const wedgeNow = /* @__PURE__ */ new Date();
|
|
14756
14579
|
const liveAgents = agentState.persistentSessionAgents;
|
|
@@ -14842,7 +14665,7 @@ async function pollCycleInner() {
|
|
|
14842
14665
|
const paneTail = readFileSync30(paneLogPath(codeName), "utf8").slice(-65536);
|
|
14843
14666
|
const transient = detectTransientApiErrorInLog(paneTail);
|
|
14844
14667
|
if (transient) {
|
|
14845
|
-
const wedgeHome = join39(
|
|
14668
|
+
const wedgeHome = join39(homedir17(), ".augmented", codeName);
|
|
14846
14669
|
if (existsSync17(wedgeHome)) {
|
|
14847
14670
|
atomicWriteFileSync(
|
|
14848
14671
|
join39(wedgeHome, "watchdog-give-up.json"),
|
|
@@ -14906,7 +14729,7 @@ async function pollCycleInner() {
|
|
|
14906
14729
|
}
|
|
14907
14730
|
try {
|
|
14908
14731
|
const { scrapeMcpFailedBannerCount } = await import("../pane-mcp-banner-scraper-JA437JIB.js");
|
|
14909
|
-
const { probeSessionAuth } = await import("../session-auth-dead-
|
|
14732
|
+
const { probeSessionAuth } = await import("../session-auth-dead-CPY4UZI7.js");
|
|
14910
14733
|
const observations = [];
|
|
14911
14734
|
const pendingCacheCommits = [];
|
|
14912
14735
|
const modelApiErrorReportingOn = hostFlagStore().getBoolean("model-api-error-reporting");
|
|
@@ -15248,7 +15071,7 @@ async function pollCycleInner() {
|
|
|
15248
15071
|
// pending-inbound marker. Best-effort: a write failure is logged by
|
|
15249
15072
|
// the watchdog, never fails the poll cycle.
|
|
15250
15073
|
signalGiveUp: (codeName) => {
|
|
15251
|
-
const dir = join39(
|
|
15074
|
+
const dir = join39(homedir17(), ".augmented", codeName);
|
|
15252
15075
|
if (!existsSync17(dir)) return;
|
|
15253
15076
|
atomicWriteFileSync(
|
|
15254
15077
|
join39(dir, "watchdog-give-up.json"),
|
|
@@ -15663,8 +15486,28 @@ async function processAgent(agent, agentStates, managedToolkits) {
|
|
|
15663
15486
|
let refreshData;
|
|
15664
15487
|
try {
|
|
15665
15488
|
refreshData = await api.post("/host/refresh", {
|
|
15666
|
-
agent_id: agent.agent_id
|
|
15489
|
+
agent_id: agent.agent_id,
|
|
15490
|
+
// ENG-9585: ask for hashes instead of knowledge bodies. An API build that
|
|
15491
|
+
// predates the manifest ignores this and answers with `knowledge` as
|
|
15492
|
+
// before, which the resolution below handles without a version check.
|
|
15493
|
+
knowledge_manifest: true
|
|
15667
15494
|
});
|
|
15495
|
+
if (refreshData.knowledge_manifest) {
|
|
15496
|
+
const resolved = await resolveKnowledgeFromManifest({
|
|
15497
|
+
manifest: refreshData.knowledge_manifest,
|
|
15498
|
+
cacheDir: join39(config.configDir, "_knowledge"),
|
|
15499
|
+
delivery: refreshData.agent?.knowledge_delivery ?? "both",
|
|
15500
|
+
fetchContents: async (hashes) => {
|
|
15501
|
+
const res = await api.post(
|
|
15502
|
+
"/host/knowledge/contents",
|
|
15503
|
+
{ agent_id: agent.agent_id, hashes }
|
|
15504
|
+
);
|
|
15505
|
+
return res.contents ?? [];
|
|
15506
|
+
},
|
|
15507
|
+
log
|
|
15508
|
+
});
|
|
15509
|
+
refreshData.knowledge = resolved;
|
|
15510
|
+
}
|
|
15668
15511
|
} catch (err) {
|
|
15669
15512
|
log(`Refresh failed for '${agent.code_name}': ${err.message}`);
|
|
15670
15513
|
const existing = state8.agents.find((a) => a.agentId === agent.agent_id);
|
|
@@ -15765,7 +15608,7 @@ async function processAgent(agent, agentStates, managedToolkits) {
|
|
|
15765
15608
|
try {
|
|
15766
15609
|
const artifacts = generateArtifacts(agent, refreshData, frameworkAdapter, renderIntegrationsSection);
|
|
15767
15610
|
const changedFiles = [];
|
|
15768
|
-
|
|
15611
|
+
mkdirSync12(agentDir, { recursive: true });
|
|
15769
15612
|
for (const artifact of artifacts) {
|
|
15770
15613
|
const filePath = join39(agentDir, artifact.relativePath);
|
|
15771
15614
|
let existingHash;
|
|
@@ -15843,11 +15686,11 @@ async function processAgent(agent, agentStates, managedToolkits) {
|
|
|
15843
15686
|
log(`${verb} '${agent.code_name}': ${fileNames}`);
|
|
15844
15687
|
for (const file of changedFiles) {
|
|
15845
15688
|
const filePath = join39(agentDir, file.relativePath);
|
|
15846
|
-
|
|
15689
|
+
mkdirSync12(dirname10(filePath), { recursive: true });
|
|
15847
15690
|
if (file.relativePath === ".mcp.json") {
|
|
15848
15691
|
safeWriteJsonAtomic(filePath, file.content, { mode: 384 });
|
|
15849
15692
|
} else {
|
|
15850
|
-
|
|
15693
|
+
writeFileSync16(filePath, file.content);
|
|
15851
15694
|
}
|
|
15852
15695
|
}
|
|
15853
15696
|
try {
|
|
@@ -15856,7 +15699,7 @@ async function processAgent(agent, agentStates, managedToolkits) {
|
|
|
15856
15699
|
for (const folder of readdirSync10(provSkillsDir)) {
|
|
15857
15700
|
if (folder.startsWith("knowledge-")) {
|
|
15858
15701
|
try {
|
|
15859
|
-
|
|
15702
|
+
rmSync6(join39(provSkillsDir, folder), { recursive: true });
|
|
15860
15703
|
} catch {
|
|
15861
15704
|
}
|
|
15862
15705
|
}
|
|
@@ -15894,7 +15737,7 @@ async function processAgent(agent, agentStates, managedToolkits) {
|
|
|
15894
15737
|
if (!file.endsWith(".js")) continue;
|
|
15895
15738
|
if (expected.has(file)) continue;
|
|
15896
15739
|
try {
|
|
15897
|
-
|
|
15740
|
+
rmSync6(join39(provWorkflowsDir, file));
|
|
15898
15741
|
} catch {
|
|
15899
15742
|
}
|
|
15900
15743
|
}
|
|
@@ -16255,8 +16098,8 @@ async function processAgent(agent, agentStates, managedToolkits) {
|
|
|
16255
16098
|
const addedChannels = [...restartDecision.added];
|
|
16256
16099
|
const writeDmNoticeMarkers = isChannelAddRestart ? () => {
|
|
16257
16100
|
try {
|
|
16258
|
-
const agentAugmentedDir = join39(
|
|
16259
|
-
|
|
16101
|
+
const agentAugmentedDir = join39(homedir17(), ".augmented", agent.code_name);
|
|
16102
|
+
mkdirSync12(agentAugmentedDir, { recursive: true });
|
|
16260
16103
|
const markerJson = JSON.stringify({
|
|
16261
16104
|
version: 1,
|
|
16262
16105
|
at: (/* @__PURE__ */ new Date()).toISOString(),
|
|
@@ -16339,7 +16182,7 @@ async function processAgent(agent, agentStates, managedToolkits) {
|
|
|
16339
16182
|
const behaviourSubset = extractMsTeamsBehaviourSubset(
|
|
16340
16183
|
msteamsEntry?.config
|
|
16341
16184
|
);
|
|
16342
|
-
const behaviourHash =
|
|
16185
|
+
const behaviourHash = createHash18("sha256").update(canonicalJson(behaviourSubset)).digest("hex");
|
|
16343
16186
|
const prevBehaviourHash = agentState.knownMsTeamsBehaviourHashes.get(agent.agent_id);
|
|
16344
16187
|
const msteamsBehaviourRestrictive = isMsTeamsBehaviourRestrictive(behaviourSubset);
|
|
16345
16188
|
const behaviourDecision = decideSenderPolicyRestart({
|
|
@@ -16395,7 +16238,7 @@ async function processAgent(agent, agentStates, managedToolkits) {
|
|
|
16395
16238
|
const slackBehaviourSubset = extractSlackBehaviourSubset(
|
|
16396
16239
|
slackEntry?.config
|
|
16397
16240
|
);
|
|
16398
|
-
const slackBehaviourHash =
|
|
16241
|
+
const slackBehaviourHash = createHash18("sha256").update(canonicalJson(slackBehaviourSubset)).digest("hex");
|
|
16399
16242
|
const prevSlackBehaviourHash = agentState.knownSlackBehaviourHashes.get(agent.agent_id);
|
|
16400
16243
|
const slackBehaviourRestrictive = isSlackBehaviourRestrictive(slackBehaviourSubset);
|
|
16401
16244
|
const slackBehaviourDecision = decideSenderPolicyRestart({
|
|
@@ -16452,9 +16295,9 @@ async function processAgent(agent, agentStates, managedToolkits) {
|
|
|
16452
16295
|
if (agentSessionMode === "persistent" && (agentFrameworkCache.get(agent.code_name) ?? DEFAULT_FRAMEWORK) === "claude-code") {
|
|
16453
16296
|
try {
|
|
16454
16297
|
const agentProvisionDir = agentDir;
|
|
16455
|
-
const projectDir = join39(
|
|
16456
|
-
|
|
16457
|
-
|
|
16298
|
+
const projectDir = join39(homedir17(), ".augmented", agent.code_name, "project");
|
|
16299
|
+
mkdirSync12(agentProvisionDir, { recursive: true });
|
|
16300
|
+
mkdirSync12(projectDir, { recursive: true });
|
|
16458
16301
|
const provisionMcpPath = join39(agentProvisionDir, ".mcp.json");
|
|
16459
16302
|
const projectMcpPath = join39(projectDir, ".mcp.json");
|
|
16460
16303
|
let mcpConfig = { mcpServers: {} };
|
|
@@ -16463,7 +16306,7 @@ async function processAgent(agent, agentStates, managedToolkits) {
|
|
|
16463
16306
|
if (!mcpConfig.mcpServers) mcpConfig.mcpServers = {};
|
|
16464
16307
|
} catch {
|
|
16465
16308
|
}
|
|
16466
|
-
const localDirectChatChannel = join39(
|
|
16309
|
+
const localDirectChatChannel = join39(homedir17(), ".augmented", "_mcp", "direct-chat-channel.js");
|
|
16467
16310
|
const directChatTeamSettings = refreshData.team?.settings;
|
|
16468
16311
|
const directChatTz = (() => {
|
|
16469
16312
|
const tz = directChatTeamSettings?.["timezone"];
|
|
@@ -16512,7 +16355,7 @@ async function processAgent(agent, agentStates, managedToolkits) {
|
|
|
16512
16355
|
const staleChannelsPath = join39(projectDir, ".mcp-channels.json");
|
|
16513
16356
|
if (existsSync17(staleChannelsPath)) {
|
|
16514
16357
|
try {
|
|
16515
|
-
|
|
16358
|
+
rmSync6(staleChannelsPath, { force: true });
|
|
16516
16359
|
} catch {
|
|
16517
16360
|
}
|
|
16518
16361
|
}
|
|
@@ -16599,7 +16442,7 @@ async function processAgent(agent, agentStates, managedToolkits) {
|
|
|
16599
16442
|
}
|
|
16600
16443
|
if (hostFlagStore().getBoolean("connectivity-probe")) {
|
|
16601
16444
|
try {
|
|
16602
|
-
const probeProjectDir = join39(
|
|
16445
|
+
const probeProjectDir = join39(homedir17(), ".augmented", agent.code_name, "project");
|
|
16603
16446
|
let probeSet = integrations;
|
|
16604
16447
|
try {
|
|
16605
16448
|
const quarantined = await api.post("/host/agent-integrations/quarantined", { agent_id: agent.agent_id });
|
|
@@ -16645,7 +16488,7 @@ async function processAgent(agent, agentStates, managedToolkits) {
|
|
|
16645
16488
|
const forceDue = attemptsLeft > 0;
|
|
16646
16489
|
let probeRan = false;
|
|
16647
16490
|
try {
|
|
16648
|
-
const probeProjectDir = join39(
|
|
16491
|
+
const probeProjectDir = join39(homedir17(), ".augmented", agent.code_name, "project");
|
|
16649
16492
|
probeRan = await runAgentSessionToolBindProbes(agent, integrations, probeProjectDir, { forceDue });
|
|
16650
16493
|
} catch (err) {
|
|
16651
16494
|
log(`Session-tool-bind probe failed for '${agent.code_name}': ${err.message}`);
|
|
@@ -16722,7 +16565,7 @@ async function processAgent(agent, agentStates, managedToolkits) {
|
|
|
16722
16565
|
const intHash = computeIntegrationsHash(integrations);
|
|
16723
16566
|
const prevIntHash = agentState.knownIntegrationHashes.get(agent.agent_id);
|
|
16724
16567
|
if (intHash !== prevIntHash) {
|
|
16725
|
-
const projectDir = join39(
|
|
16568
|
+
const projectDir = join39(homedir17(), ".augmented", agent.code_name, "project");
|
|
16726
16569
|
const envIntPath = join39(projectDir, ".env.integrations");
|
|
16727
16570
|
let preWriteEnv;
|
|
16728
16571
|
try {
|
|
@@ -16837,10 +16680,10 @@ async function processAgent(agent, agentStates, managedToolkits) {
|
|
|
16837
16680
|
desiredEntries.push({ serverId, url, headers: mcpHeaders, name: tk.toolkit_name });
|
|
16838
16681
|
}
|
|
16839
16682
|
const hashBasis = desiredEntries.slice().sort((a, b) => a.serverId.localeCompare(b.serverId)).map((e) => {
|
|
16840
|
-
const headersHash =
|
|
16683
|
+
const headersHash = createHash18("sha256").update(canonicalJson(e.headers ?? {})).digest("hex").slice(0, 16);
|
|
16841
16684
|
return `${e.serverId}|${e.url}|${headersHash}`;
|
|
16842
16685
|
}).join("\n");
|
|
16843
|
-
const mcpHash =
|
|
16686
|
+
const mcpHash = createHash18("sha256").update(hashBasis).digest("hex").slice(0, 16);
|
|
16844
16687
|
const prevMcpHash = agentState.knownManagedMcpHashes.get(agent.agent_id);
|
|
16845
16688
|
const structureHash = managedMcpStructureHash(desiredEntries);
|
|
16846
16689
|
const prevStructureHash = agentState.knownManagedMcpStructure.get(agent.agent_id);
|
|
@@ -16855,7 +16698,7 @@ async function processAgent(agent, agentStates, managedToolkits) {
|
|
|
16855
16698
|
if (mcpHash !== prevMcpHash) {
|
|
16856
16699
|
for (const e of desiredEntries) {
|
|
16857
16700
|
frameworkAdapter.writeMcpServer(agent.code_name, e.serverId, { url: e.url, headers: e.headers });
|
|
16858
|
-
const urlHash =
|
|
16701
|
+
const urlHash = createHash18("sha256").update(e.url).digest("hex").slice(0, 12);
|
|
16859
16702
|
log(`[managed-toolkit] ${agent.code_name}: wrote '${e.name}' (serverId=${e.serverId}, url_hash=${urlHash})`);
|
|
16860
16703
|
}
|
|
16861
16704
|
if (frameworkAdapter.removeMcpServer && frameworkAdapter.readMcpServers) {
|
|
@@ -16935,7 +16778,10 @@ async function processAgent(agent, agentStates, managedToolkits) {
|
|
|
16935
16778
|
if (missing.length > 0) {
|
|
16936
16779
|
log(`Auto-provisioned ${missing.length} default schedule(s) for '${agent.code_name}': ${missing.map((s) => s.template_id).join(", ")}`);
|
|
16937
16780
|
}
|
|
16938
|
-
const freshData = await api.post("/host/refresh", {
|
|
16781
|
+
const freshData = await api.post("/host/refresh", {
|
|
16782
|
+
agent_id: agent.agent_id,
|
|
16783
|
+
knowledge_manifest: true
|
|
16784
|
+
});
|
|
16939
16785
|
tasks = freshData.scheduled_tasks ?? tasks;
|
|
16940
16786
|
}
|
|
16941
16787
|
} catch (err) {
|
|
@@ -16958,7 +16804,7 @@ async function processAgent(agent, agentStates, managedToolkits) {
|
|
|
16958
16804
|
if (frameworkAdapter.installSkillFiles) {
|
|
16959
16805
|
const currentIntegrationSkillIds = /* @__PURE__ */ new Set();
|
|
16960
16806
|
const installedIntegrationSkills = [];
|
|
16961
|
-
const { createHash:
|
|
16807
|
+
const { createHash: createHash19 } = await import("crypto");
|
|
16962
16808
|
const refreshAny = refreshData;
|
|
16963
16809
|
const contexts = refreshAny.integration_contexts ?? refreshAny.plugin_contexts ?? [];
|
|
16964
16810
|
const contextBySlug = /* @__PURE__ */ new Map();
|
|
@@ -16987,7 +16833,7 @@ async function processAgent(agent, agentStates, managedToolkits) {
|
|
|
16987
16833
|
)
|
|
16988
16834
|
}));
|
|
16989
16835
|
const bundle = buildIntegrationBundle(renderedScopes);
|
|
16990
|
-
const contentHash =
|
|
16836
|
+
const contentHash = createHash19("sha256").update(bundleFingerprint(bundle.files)).digest("hex").slice(0, 12);
|
|
16991
16837
|
if (!shouldWriteIntegrationSkill(
|
|
16992
16838
|
agentState.knownSkillHashes,
|
|
16993
16839
|
agent.agent_id,
|
|
@@ -17010,14 +16856,14 @@ async function processAgent(agent, agentStates, managedToolkits) {
|
|
|
17010
16856
|
}
|
|
17011
16857
|
}
|
|
17012
16858
|
try {
|
|
17013
|
-
const { readdirSync: readdirSync11, rmSync:
|
|
17014
|
-
const { homedir:
|
|
16859
|
+
const { readdirSync: readdirSync11, rmSync: rmSync7 } = await import("fs");
|
|
16860
|
+
const { homedir: homedir18 } = await import("os");
|
|
17015
16861
|
const frameworkId2 = frameworkAdapter.id;
|
|
17016
16862
|
const candidateSkillDirs = [
|
|
17017
16863
|
// Claude Code — framework runtime tree
|
|
17018
|
-
join39(
|
|
16864
|
+
join39(homedir18(), ".augmented", agent.code_name, "skills"),
|
|
17019
16865
|
// Claude Code — project tree
|
|
17020
|
-
join39(
|
|
16866
|
+
join39(homedir18(), ".augmented", agent.code_name, "project", ".claude", "skills"),
|
|
17021
16867
|
// Defensive: legacy provision-side path, not currently an
|
|
17022
16868
|
// install target but cheap to sweep.
|
|
17023
16869
|
join39(agentDir, ".claude", "skills")
|
|
@@ -17042,7 +16888,7 @@ async function processAgent(agent, agentStates, managedToolkits) {
|
|
|
17042
16888
|
dirs: existingDirs,
|
|
17043
16889
|
removeDir: (p) => {
|
|
17044
16890
|
if (existsSync17(p)) {
|
|
17045
|
-
|
|
16891
|
+
rmSync7(p, { recursive: true, force: true });
|
|
17046
16892
|
}
|
|
17047
16893
|
}
|
|
17048
16894
|
});
|
|
@@ -17061,7 +16907,7 @@ async function processAgent(agent, agentStates, managedToolkits) {
|
|
|
17061
16907
|
const sharedSkillsPayload = refreshAny.shared_skills;
|
|
17062
16908
|
const desiredResolved = globalSkillsPayload !== void 0 || sharedSkillsPayload !== void 0;
|
|
17063
16909
|
const manifestPath = managedSkillManifestPath(
|
|
17064
|
-
join39(
|
|
16910
|
+
join39(homedir17(), ".augmented", agent.code_name)
|
|
17065
16911
|
);
|
|
17066
16912
|
const prevIds = /* @__PURE__ */ new Set([
|
|
17067
16913
|
...agentState.knownGlobalSkillIds.get(agent.agent_id) ?? /* @__PURE__ */ new Set(),
|
|
@@ -17070,7 +16916,7 @@ async function processAgent(agent, agentStates, managedToolkits) {
|
|
|
17070
16916
|
const plan = planGlobalSkillSync(
|
|
17071
16917
|
[...globalSkillsPayload ?? [], ...sharedSkillsPayload ?? []],
|
|
17072
16918
|
prevIds,
|
|
17073
|
-
(content) =>
|
|
16919
|
+
(content) => createHash19("sha256").update(content).digest("hex").slice(0, 12),
|
|
17074
16920
|
(skillId) => agentState.knownSkillHashes.get(`global-skill:${agent.agent_id}:${skillId}`),
|
|
17075
16921
|
{ desiredResolved }
|
|
17076
16922
|
);
|
|
@@ -17081,8 +16927,8 @@ async function processAgent(agent, agentStates, managedToolkits) {
|
|
|
17081
16927
|
}
|
|
17082
16928
|
if (plan.removes.length) {
|
|
17083
16929
|
const globalSkillDirs = [
|
|
17084
|
-
join39(
|
|
17085
|
-
join39(
|
|
16930
|
+
join39(homedir17(), ".augmented", agent.code_name, "skills"),
|
|
16931
|
+
join39(homedir17(), ".augmented", agent.code_name, "project", ".claude", "skills"),
|
|
17086
16932
|
join39(agentDir, ".claude", "skills")
|
|
17087
16933
|
];
|
|
17088
16934
|
for (const id of plan.removes) {
|
|
@@ -17090,7 +16936,7 @@ async function processAgent(agent, agentStates, managedToolkits) {
|
|
|
17090
16936
|
for (const dir of globalSkillDirs) {
|
|
17091
16937
|
const p = join39(dir, id);
|
|
17092
16938
|
if (existsSync17(p) && existsSync17(join39(p, "SKILL.md"))) {
|
|
17093
|
-
|
|
16939
|
+
rmSync6(p, { recursive: true, force: true });
|
|
17094
16940
|
prunedAny = true;
|
|
17095
16941
|
}
|
|
17096
16942
|
}
|
|
@@ -17121,7 +16967,7 @@ async function processAgent(agent, agentStates, managedToolkits) {
|
|
|
17121
16967
|
const slug = hook.integration_slug ?? hook.plugin_slug;
|
|
17122
16968
|
if (!slug) continue;
|
|
17123
16969
|
try {
|
|
17124
|
-
const scriptHash =
|
|
16970
|
+
const scriptHash = createHash19("sha256").update(hook.script).digest("hex").slice(0, 12);
|
|
17125
16971
|
const hookKey = `${agent.agent_id}:${frameworkAdapter.id}:plugin-hook:${slug}:on_install`;
|
|
17126
16972
|
if (agentState.knownSkillHashes.get(hookKey) === scriptHash) continue;
|
|
17127
16973
|
const result = await frameworkAdapter.executePluginHook({
|
|
@@ -17136,9 +16982,9 @@ async function processAgent(agent, agentStates, managedToolkits) {
|
|
|
17136
16982
|
} else if (result.timedOut) {
|
|
17137
16983
|
log(`Integration hook on_install '${slug}' TIMED OUT for '${agent.code_name}' after ${result.durationMs}ms`);
|
|
17138
16984
|
} else {
|
|
17139
|
-
const stderrHash =
|
|
16985
|
+
const stderrHash = createHash19("sha256").update(result.stderr).digest("hex").slice(0, 12);
|
|
17140
16986
|
const missingCmd = result.exitCode === 127 ? extractCommandNotFound(result.stderr) : null;
|
|
17141
|
-
const missingCmdHash = missingCmd ?
|
|
16987
|
+
const missingCmdHash = missingCmd ? createHash19("sha256").update(missingCmd).digest("hex").slice(0, 8) : null;
|
|
17142
16988
|
log(
|
|
17143
16989
|
`Integration hook on_install '${slug}' exited ${result.exitCode} for '${agent.code_name}' ` + (missingCmdHash ? `[missing_command_hash=${missingCmdHash}] ` : "") + `[stderr_hash=${stderrHash} stderr_len=${result.stderr.length}]`
|
|
17144
16990
|
);
|
|
@@ -17709,7 +17555,7 @@ async function processAgent(agent, agentStates, managedToolkits) {
|
|
|
17709
17555
|
freshDoneIds.add(item.id);
|
|
17710
17556
|
}
|
|
17711
17557
|
} catch (err) {
|
|
17712
|
-
const errId =
|
|
17558
|
+
const errId = createHash18("sha256").update(err instanceof Error ? err.message : String(err)).digest("hex").slice(0, 12);
|
|
17713
17559
|
log(`Reap API error for item_id=${item.id} error_id=${errId}`);
|
|
17714
17560
|
}
|
|
17715
17561
|
if (reapAction === "dead_letter") {
|
|
@@ -17775,7 +17621,7 @@ Retried to the limit after repeated stalls \u2014 needs a look.`).catch(() => {
|
|
|
17775
17621
|
refreshData.agent.onboarding_state
|
|
17776
17622
|
);
|
|
17777
17623
|
const obStep = obState.step;
|
|
17778
|
-
const markerPath = join39(
|
|
17624
|
+
const markerPath = join39(homedir17(), ".augmented", agent.code_name, "onboarding-drive.json");
|
|
17779
17625
|
const marker = readOnboardingDriveMarker(markerPath);
|
|
17780
17626
|
const obContactRaw = refreshData.agent.manager_last_contacted_at;
|
|
17781
17627
|
const obContact = typeof obContactRaw === "string" && obContactRaw ? obContactRaw : null;
|
|
@@ -18182,7 +18028,7 @@ async function ensurePersistentSession(agent, tasks, boardItems, refreshData) {
|
|
|
18182
18028
|
const ctx = getLastFailureContext(codeName);
|
|
18183
18029
|
const recovery = prepareForRespawn(codeName);
|
|
18184
18030
|
const tailSummary = !ctx.tail ? "" : KNOWN_SAFE_TAIL_SIGNATURES.has(ctx.signature) ? `; last pane output (${PANE_TAIL_PREVIEW_LINES} of ~20 lines):
|
|
18185
|
-
${truncateForLog(ctx.tail)}` : `; pane_tail_hash=sha256:${
|
|
18031
|
+
${truncateForLog(ctx.tail)}` : `; pane_tail_hash=sha256:${createHash18("sha256").update(ctx.tail).digest("hex").slice(0, 12)} (raw at ~/.augmented/${codeName}/pane.log)`;
|
|
18186
18032
|
const sigSummary = ctx.signature !== "unknown" ? `; signature=${ctx.signature}` : "";
|
|
18187
18033
|
const recoverySummary = recovery ? `; recovery=${recovery}` : "";
|
|
18188
18034
|
log(
|
|
@@ -18196,7 +18042,7 @@ ${truncateForLog(ctx.tail)}` : `; pane_tail_hash=sha256:${createHash17("sha256")
|
|
|
18196
18042
|
);
|
|
18197
18043
|
getHostId().then((hostId) => {
|
|
18198
18044
|
if (!hostId) return;
|
|
18199
|
-
const paneTailHash = zombie.paneTail ? `sha256:${
|
|
18045
|
+
const paneTailHash = zombie.paneTail ? `sha256:${createHash18("sha256").update(zombie.paneTail).digest("hex").slice(0, 12)}` : null;
|
|
18200
18046
|
return api.post("/host/events", {
|
|
18201
18047
|
host_id: hostId,
|
|
18202
18048
|
agent_code_name: codeName,
|
|
@@ -18393,7 +18239,7 @@ ${truncateForLog(ctx.tail)}` : `; pane_tail_hash=sha256:${createHash17("sha256")
|
|
|
18393
18239
|
if (!claudeAuthTupleBySession.has(codeName)) {
|
|
18394
18240
|
claudeAuthTupleBySession.set(codeName, currentAuthTuple);
|
|
18395
18241
|
}
|
|
18396
|
-
const stableTasksHash =
|
|
18242
|
+
const stableTasksHash = createHash18("sha256").update(JSON.stringify(tasks)).digest("hex").slice(0, 16);
|
|
18397
18243
|
const prevHash = agentState.knownTasksHashes.get(agent.agent_id);
|
|
18398
18244
|
if (stableTasksHash !== prevHash) {
|
|
18399
18245
|
const taskInputs = tasks.map((t) => buildSchedulerTaskInput(t));
|
|
@@ -18708,7 +18554,7 @@ async function handleRestartDoorbell(agentId, requestedAt, restartReason) {
|
|
|
18708
18554
|
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
18555
|
void (async () => {
|
|
18710
18556
|
try {
|
|
18711
|
-
const { collectDiagnostics } = await import("../persistent-session-
|
|
18557
|
+
const { collectDiagnostics } = await import("../persistent-session-GB3D5OIA.js");
|
|
18712
18558
|
await api.post("/host/heartbeat", {
|
|
18713
18559
|
host_id: hostId,
|
|
18714
18560
|
agent_diagnostics: collectDiagnostics([codeName], quarantineEntriesFor, claudeMdSizeFor, spawnOutcomeForDiagnostics, pidPressureFor, forwardedToolsFor)
|
|
@@ -18759,7 +18605,7 @@ async function respawnAgentAfterMcpStop(codeName, reason) {
|
|
|
18759
18605
|
}
|
|
18760
18606
|
try {
|
|
18761
18607
|
const hostId = await getHostId();
|
|
18762
|
-
const { collectDiagnostics } = await import("../persistent-session-
|
|
18608
|
+
const { collectDiagnostics } = await import("../persistent-session-GB3D5OIA.js");
|
|
18763
18609
|
await api.post("/host/heartbeat", {
|
|
18764
18610
|
host_id: hostId,
|
|
18765
18611
|
agent_diagnostics: collectDiagnostics([codeName], quarantineEntriesFor, claudeMdSizeFor, spawnOutcomeForDiagnostics, pidPressureFor, forwardedToolsFor)
|
|
@@ -18867,7 +18713,7 @@ function ensureRealtimeKanbanStarted(agentStates) {
|
|
|
18867
18713
|
);
|
|
18868
18714
|
}
|
|
18869
18715
|
}).catch((err) => {
|
|
18870
|
-
const errId =
|
|
18716
|
+
const errId = createHash18("sha256").update(err instanceof Error ? err.message : String(err)).digest("hex").slice(0, 12);
|
|
18871
18717
|
log(
|
|
18872
18718
|
`[realtime] Work trigger enqueue threw for '${agent.codeName}' item_id=${item.id} error_id=${errId} \u2014 hybrid nudge will retry`
|
|
18873
18719
|
);
|
|
@@ -19075,7 +18921,7 @@ async function processDirectChatMessageOpencode(agent, msg) {
|
|
|
19075
18921
|
body
|
|
19076
18922
|
});
|
|
19077
18923
|
recordCursorAdvanceOutcome(
|
|
19078
|
-
|
|
18924
|
+
dirname10(paneLogPath(agent.codeName)),
|
|
19079
18925
|
"direct-chat-manager",
|
|
19080
18926
|
"reply",
|
|
19081
18927
|
verdict
|
|
@@ -19105,7 +18951,7 @@ async function processDirectChatMessageOpencode(agent, msg) {
|
|
|
19105
18951
|
} catch (err) {
|
|
19106
18952
|
if (!recorded) {
|
|
19107
18953
|
recordCursorAdvanceOutcome(
|
|
19108
|
-
|
|
18954
|
+
dirname10(paneLogPath(agent.codeName)),
|
|
19109
18955
|
"direct-chat-manager",
|
|
19110
18956
|
"reply",
|
|
19111
18957
|
{ outcome: "failed", error: err.message, expected: 1 }
|
|
@@ -19156,9 +19002,9 @@ async function processDirectChatMessage(agent, msg) {
|
|
|
19156
19002
|
const useDoorbell = hostFlagStore().getBoolean("direct-chat-doorbell") || isolationMode(agent.codeName) === "docker";
|
|
19157
19003
|
if (useDoorbell) {
|
|
19158
19004
|
try {
|
|
19159
|
-
const doorbell = directChatDoorbellPath(agent.agentId,
|
|
19160
|
-
|
|
19161
|
-
|
|
19005
|
+
const doorbell = directChatDoorbellPath(agent.agentId, homedir17());
|
|
19006
|
+
mkdirSync12(dirname10(doorbell), { recursive: true });
|
|
19007
|
+
writeFileSync16(doorbell, String(Date.now()));
|
|
19162
19008
|
log(`[direct-chat] Doorbell rung for '${agent.codeName}' (msg=${msg.id}) \u2014 in-session MCP will pull via the cursor`);
|
|
19163
19009
|
return;
|
|
19164
19010
|
} catch (err) {
|
|
@@ -19285,9 +19131,9 @@ ${formatRunMarker(run_id)}` : KANBAN_CHECK_COMMAND;
|
|
|
19285
19131
|
}
|
|
19286
19132
|
if (run_id) openInjectedRunByCode.set(codeName, run_id);
|
|
19287
19133
|
try {
|
|
19288
|
-
const doorbell = directChatDoorbellPath(agentId,
|
|
19289
|
-
|
|
19290
|
-
|
|
19134
|
+
const doorbell = directChatDoorbellPath(agentId, homedir17());
|
|
19135
|
+
mkdirSync12(dirname10(doorbell), { recursive: true });
|
|
19136
|
+
writeFileSync16(doorbell, String(Date.now()));
|
|
19291
19137
|
} catch (err) {
|
|
19292
19138
|
log(`[kanban] doorbell ring failed for '${codeName}': ${err.message} (notice still queued)`);
|
|
19293
19139
|
}
|
|
@@ -19391,7 +19237,7 @@ async function processClaudePairSessions(agents) {
|
|
|
19391
19237
|
killPairSession,
|
|
19392
19238
|
pairTmuxSession,
|
|
19393
19239
|
finalizeClaudePairOnboarding
|
|
19394
|
-
} = await import("../claude-pair-runtime-
|
|
19240
|
+
} = await import("../claude-pair-runtime-KWBCSCZO.js");
|
|
19395
19241
|
for (const pairId of pendingResp.cancelled_pair_ids ?? []) {
|
|
19396
19242
|
log(`[claude-pair] sweeping orphan tmux session for pair ${pairId.slice(0, 8)}`);
|
|
19397
19243
|
const killed = await killPairSession(pairTmuxSession(pairId));
|
|
@@ -19426,12 +19272,12 @@ async function processClaudePairSessions(agents) {
|
|
|
19426
19272
|
try {
|
|
19427
19273
|
if (session.status === "initiating") {
|
|
19428
19274
|
log(`[claude-pair] spawning pair session ${pairSession} for '${codeName}'`);
|
|
19429
|
-
const
|
|
19430
|
-
if (!
|
|
19275
|
+
const spawn = await spawnPairSession(pairSession);
|
|
19276
|
+
if (!spawn.ok) {
|
|
19431
19277
|
await reportAndCleanup(session.pair_id, {
|
|
19432
19278
|
status: "failure",
|
|
19433
|
-
error_code:
|
|
19434
|
-
error_message:
|
|
19279
|
+
error_code: spawn.error.kind,
|
|
19280
|
+
error_message: spawn.error.kind === "unknown" ? spawn.error.message : void 0
|
|
19435
19281
|
});
|
|
19436
19282
|
continue;
|
|
19437
19283
|
}
|
|
@@ -19646,10 +19492,10 @@ function saveMemoryManifest(agentId, configDir, codeName) {
|
|
|
19646
19492
|
if (!manifest) return;
|
|
19647
19493
|
try {
|
|
19648
19494
|
const path = memoryManifestPath(configDir, codeName);
|
|
19649
|
-
|
|
19495
|
+
mkdirSync12(memoryRetirementDir(configDir, codeName), { recursive: true });
|
|
19650
19496
|
const tmp = `${path}.tmp`;
|
|
19651
|
-
|
|
19652
|
-
|
|
19497
|
+
writeFileSync16(tmp, JSON.stringify(manifest, null, 2));
|
|
19498
|
+
renameSync9(tmp, path);
|
|
19653
19499
|
} catch {
|
|
19654
19500
|
}
|
|
19655
19501
|
}
|
|
@@ -19740,7 +19586,7 @@ function applyMemoryTombstones(opts) {
|
|
|
19740
19586
|
continue;
|
|
19741
19587
|
}
|
|
19742
19588
|
try {
|
|
19743
|
-
const actual =
|
|
19589
|
+
const actual = createHash18("sha256").update(readFileSync30(filePath)).digest("hex");
|
|
19744
19590
|
if (actual !== entry.sha) {
|
|
19745
19591
|
outcomes.kept_modified++;
|
|
19746
19592
|
outcomes.unapplied.push({ name: tomb.name, reason: "kept_modified" });
|
|
@@ -19750,16 +19596,16 @@ function applyMemoryTombstones(opts) {
|
|
|
19750
19596
|
continue;
|
|
19751
19597
|
}
|
|
19752
19598
|
const destDir = retiredMemoryDir(configDir, agent.code_name);
|
|
19753
|
-
|
|
19599
|
+
mkdirSync12(destDir, { recursive: true });
|
|
19754
19600
|
const stamp = Date.now();
|
|
19755
19601
|
let dest = join39(destDir, `${entry.file}.${stamp}.retired`);
|
|
19756
19602
|
for (let n = 1; existsSync17(dest); n++) {
|
|
19757
19603
|
dest = join39(destDir, `${entry.file}.${stamp}-${n}.retired`);
|
|
19758
19604
|
}
|
|
19759
|
-
|
|
19605
|
+
renameSync9(filePath, dest);
|
|
19760
19606
|
try {
|
|
19761
19607
|
const now = Date.now() / 1e3;
|
|
19762
|
-
|
|
19608
|
+
utimesSync2(dest, now, now);
|
|
19763
19609
|
} catch {
|
|
19764
19610
|
}
|
|
19765
19611
|
delete manifest[tomb.name];
|
|
@@ -19795,7 +19641,7 @@ function reapRetiredMemories(configDir, codeName, log2) {
|
|
|
19795
19641
|
if (!file.endsWith(".retired")) continue;
|
|
19796
19642
|
const path = join39(dir, file);
|
|
19797
19643
|
try {
|
|
19798
|
-
if (
|
|
19644
|
+
if (statSync9(path).mtimeMs < cutoff) {
|
|
19799
19645
|
unlinkSync6(path);
|
|
19800
19646
|
reaped++;
|
|
19801
19647
|
}
|
|
@@ -19841,7 +19687,7 @@ async function syncMemories(agent, configDir, log2) {
|
|
|
19841
19687
|
if (!file.endsWith(".md")) continue;
|
|
19842
19688
|
try {
|
|
19843
19689
|
const raw = readFileSync30(join39(memoryDir, file), "utf-8");
|
|
19844
|
-
const fileHash =
|
|
19690
|
+
const fileHash = createHash18("sha256").update(raw).digest("hex").slice(0, 16);
|
|
19845
19691
|
currentHashes.set(file, fileHash);
|
|
19846
19692
|
if (prevHashes.get(file) === fileHash) continue;
|
|
19847
19693
|
const parsed = parseMemoryFile(raw, file.replace(/\.md$/, ""));
|
|
@@ -19892,7 +19738,7 @@ async function syncMemories(agent, configDir, log2) {
|
|
|
19892
19738
|
}
|
|
19893
19739
|
async function downloadMemories(agent, memoryDir, log2, { force, configDir }) {
|
|
19894
19740
|
const localFiles = existsSync17(memoryDir) ? readdirSync10(memoryDir).filter((f) => f.endsWith(".md")).sort() : [];
|
|
19895
|
-
const localListHash =
|
|
19741
|
+
const localListHash = createHash18("sha256").update(localFiles.join(",")).digest("hex").slice(0, 16);
|
|
19896
19742
|
const prevLocalHash = lastLocalFileHash.get(agent.agent_id);
|
|
19897
19743
|
const prevDownload = lastDownloadHash.get(agent.agent_id);
|
|
19898
19744
|
try {
|
|
@@ -19900,14 +19746,14 @@ async function downloadMemories(agent, memoryDir, log2, { force, configDir }) {
|
|
|
19900
19746
|
agent_id: agent.agent_id
|
|
19901
19747
|
});
|
|
19902
19748
|
const tombstones = Array.isArray(dbMemories.tombstones) ? dbMemories.tombstones : null;
|
|
19903
|
-
const responseHash =
|
|
19749
|
+
const responseHash = createHash18("sha256").update(JSON.stringify({ m: dbMemories.memories ?? [], t: tombstones })).digest("hex").slice(0, 16);
|
|
19904
19750
|
if (!force && prevDownload && prevLocalHash === localListHash && lastDownloadHash.get(agent.agent_id) === responseHash) {
|
|
19905
19751
|
return { status: "skipped", tombstones, truncated: dbMemories.tombstones_truncated === true };
|
|
19906
19752
|
}
|
|
19907
19753
|
lastDownloadHash.set(agent.agent_id, responseHash);
|
|
19908
19754
|
lastLocalFileHash.set(agent.agent_id, localListHash);
|
|
19909
19755
|
if (dbMemories.memories?.length) {
|
|
19910
|
-
|
|
19756
|
+
mkdirSync12(memoryDir, { recursive: true });
|
|
19911
19757
|
const manifest = loadMemoryManifest(agent.agent_id, configDir, agent.code_name);
|
|
19912
19758
|
let written = 0;
|
|
19913
19759
|
let overwritten = 0;
|
|
@@ -19926,7 +19772,7 @@ description: ${JSON.stringify(mem.content.slice(0, 200))}
|
|
|
19926
19772
|
${mem.content}
|
|
19927
19773
|
`;
|
|
19928
19774
|
const record = () => {
|
|
19929
|
-
const sha =
|
|
19775
|
+
const sha = createHash18("sha256").update(desired).digest("hex");
|
|
19930
19776
|
const prev = manifest[mem.name];
|
|
19931
19777
|
if (prev?.file === fileName && prev.sha === sha) return false;
|
|
19932
19778
|
manifest[mem.name] = { file: fileName, sha };
|
|
@@ -19944,10 +19790,10 @@ ${mem.content}
|
|
|
19944
19790
|
if (manifestDirty) saveMemoryManifest(agent.agent_id, configDir, agent.code_name);
|
|
19945
19791
|
continue;
|
|
19946
19792
|
}
|
|
19947
|
-
|
|
19793
|
+
writeFileSync16(filePath, desired);
|
|
19948
19794
|
overwritten++;
|
|
19949
19795
|
} else {
|
|
19950
|
-
|
|
19796
|
+
writeFileSync16(filePath, desired);
|
|
19951
19797
|
written++;
|
|
19952
19798
|
}
|
|
19953
19799
|
if (record()) manifestDirty = true;
|
|
@@ -19955,7 +19801,7 @@ ${mem.content}
|
|
|
19955
19801
|
}
|
|
19956
19802
|
if (written > 0 || overwritten > 0) {
|
|
19957
19803
|
const updatedFiles = readdirSync10(memoryDir).filter((f) => f.endsWith(".md")).sort();
|
|
19958
|
-
lastLocalFileHash.set(agent.agent_id,
|
|
19804
|
+
lastLocalFileHash.set(agent.agent_id, createHash18("sha256").update(updatedFiles.join(",")).digest("hex").slice(0, 16));
|
|
19959
19805
|
log2(`Memory download for '${agent.code_name}': wrote ${written} new, overwrote ${overwritten} stale`);
|
|
19960
19806
|
}
|
|
19961
19807
|
}
|
|
@@ -19968,7 +19814,7 @@ ${mem.content}
|
|
|
19968
19814
|
async function cleanupAgentFiles(codeName, agentDir) {
|
|
19969
19815
|
if (existsSync17(agentDir)) {
|
|
19970
19816
|
try {
|
|
19971
|
-
|
|
19817
|
+
rmSync6(agentDir, { recursive: true, force: true });
|
|
19972
19818
|
log(`Removed provision directory for '${codeName}'`);
|
|
19973
19819
|
} catch (err) {
|
|
19974
19820
|
log(`Failed to remove provision dir for '${codeName}': ${err.message}`);
|
|
@@ -19990,8 +19836,8 @@ var caffeinateProc = null;
|
|
|
19990
19836
|
async function startCaffeinate() {
|
|
19991
19837
|
if (process.platform !== "darwin") return;
|
|
19992
19838
|
try {
|
|
19993
|
-
const { spawn
|
|
19994
|
-
caffeinateProc =
|
|
19839
|
+
const { spawn } = await import("child_process");
|
|
19840
|
+
caffeinateProc = spawn("caffeinate", ["-dims"], {
|
|
19995
19841
|
stdio: "ignore",
|
|
19996
19842
|
detached: false
|
|
19997
19843
|
});
|
|
@@ -20264,7 +20110,7 @@ function startManager(opts) {
|
|
|
20264
20110
|
log(`[startup] state rehydration failed (continuing with empty state): ${err.message}`);
|
|
20265
20111
|
}
|
|
20266
20112
|
log(
|
|
20267
|
-
`[startup] worker pid=${process.pid} ppid=${process.ppid} node=${process.version} log=${join39(
|
|
20113
|
+
`[startup] worker pid=${process.pid} ppid=${process.ppid} node=${process.version} log=${join39(homedir17(), ".augmented", "manager.log")}`
|
|
20268
20114
|
);
|
|
20269
20115
|
deployMcpAssets();
|
|
20270
20116
|
reapOrphanChannelMcps({ log });
|
|
@@ -20311,16 +20157,16 @@ async function reapOrphanedClaudePids() {
|
|
|
20311
20157
|
},
|
|
20312
20158
|
looksLikeClaude
|
|
20313
20159
|
);
|
|
20314
|
-
for (const
|
|
20160
|
+
for (const spawn of decision.toKill) {
|
|
20315
20161
|
try {
|
|
20316
|
-
process.kill(
|
|
20162
|
+
process.kill(spawn.pid, "SIGKILL");
|
|
20317
20163
|
} catch (err) {
|
|
20318
|
-
log(`[drain] reaper SIGKILL pid=${
|
|
20164
|
+
log(`[drain] reaper SIGKILL pid=${spawn.pid} failed: ${err.message}`);
|
|
20319
20165
|
}
|
|
20320
20166
|
}
|
|
20321
|
-
for (const
|
|
20167
|
+
for (const spawn of decision.pidReusedSkipped) {
|
|
20322
20168
|
log(
|
|
20323
|
-
`[drain] reaper skipped pid=${
|
|
20169
|
+
`[drain] reaper skipped pid=${spawn.pid} \u2014 PID reuse suspected (identity probe rejected)`
|
|
20324
20170
|
);
|
|
20325
20171
|
}
|
|
20326
20172
|
log(formatReaperBootLine({
|
|
@@ -20390,9 +20236,9 @@ function restartRunningChannelMcps(basenames) {
|
|
|
20390
20236
|
}
|
|
20391
20237
|
}
|
|
20392
20238
|
function deployMcpAssets() {
|
|
20393
|
-
const targetDir = join39(
|
|
20394
|
-
|
|
20395
|
-
const moduleDir =
|
|
20239
|
+
const targetDir = join39(homedir17(), ".augmented", "_mcp");
|
|
20240
|
+
mkdirSync12(targetDir, { recursive: true });
|
|
20241
|
+
const moduleDir = dirname10(fileURLToPath(import.meta.url));
|
|
20396
20242
|
let mcpSourceDir = "";
|
|
20397
20243
|
let dir = moduleDir;
|
|
20398
20244
|
for (let i = 0; i < 6; i++) {
|
|
@@ -20401,7 +20247,7 @@ function deployMcpAssets() {
|
|
|
20401
20247
|
mcpSourceDir = candidate;
|
|
20402
20248
|
break;
|
|
20403
20249
|
}
|
|
20404
|
-
const parent =
|
|
20250
|
+
const parent = dirname10(dir);
|
|
20405
20251
|
if (parent === dir) break;
|
|
20406
20252
|
dir = parent;
|
|
20407
20253
|
}
|
|
@@ -20415,7 +20261,7 @@ function deployMcpAssets() {
|
|
|
20415
20261
|
const fileHash = (p) => {
|
|
20416
20262
|
try {
|
|
20417
20263
|
if (!existsSync17(p)) return null;
|
|
20418
|
-
return
|
|
20264
|
+
return createHash18("sha256").update(readFileSync30(p)).digest("hex");
|
|
20419
20265
|
} catch {
|
|
20420
20266
|
return null;
|
|
20421
20267
|
}
|
|
@@ -20515,7 +20361,7 @@ function deployMcpAssets() {
|
|
|
20515
20361
|
}
|
|
20516
20362
|
const localMcpPath = join39(targetDir, "index.js");
|
|
20517
20363
|
try {
|
|
20518
|
-
const agentsDir = join39(
|
|
20364
|
+
const agentsDir = join39(homedir17(), ".augmented", "agents");
|
|
20519
20365
|
if (existsSync17(agentsDir)) {
|
|
20520
20366
|
for (const entry of readdirSync10(agentsDir, { withFileTypes: true })) {
|
|
20521
20367
|
if (!entry.isDirectory()) continue;
|
|
@@ -20529,7 +20375,7 @@ function deployMcpAssets() {
|
|
|
20529
20375
|
if (!augServer) continue;
|
|
20530
20376
|
augServer.command = "node";
|
|
20531
20377
|
augServer.args = [localMcpPath];
|
|
20532
|
-
|
|
20378
|
+
writeFileSync16(mcpJsonPath, JSON.stringify(mcpConfig, null, 2));
|
|
20533
20379
|
log(`[manager] Patched ${entry.name}/${subdir}/.mcp.json: npx \u2192 node`);
|
|
20534
20380
|
} catch {
|
|
20535
20381
|
}
|