@integrity-labs/agt-cli 0.28.383 → 0.28.385
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/bin/agt.js +4 -4
- package/dist/{chunk-Q433LFRY.js → chunk-MQHDPJZD.js} +1 -1
- package/dist/{chunk-RBXCFAWL.js → chunk-P3SY6KTF.js} +15 -7
- package/dist/{chunk-RBXCFAWL.js.map → chunk-P3SY6KTF.js.map} +1 -1
- package/dist/{claude-pair-runtime-PERAQ2PL.js → claude-pair-runtime-OIK6HKPS.js} +2 -2
- package/dist/lib/manager-worker.js +93 -110
- package/dist/lib/manager-worker.js.map +1 -1
- package/dist/{persistent-session-4LAOXUQD.js → persistent-session-MDQVHXKX.js} +2 -2
- package/dist/{responsiveness-probe-XLANB346.js → responsiveness-probe-CG7XM7GL.js} +2 -2
- package/package.json +1 -1
- /package/dist/{chunk-Q433LFRY.js.map → chunk-MQHDPJZD.js.map} +0 -0
- /package/dist/{claude-pair-runtime-PERAQ2PL.js.map → claude-pair-runtime-OIK6HKPS.js.map} +0 -0
- /package/dist/{persistent-session-4LAOXUQD.js.map → persistent-session-MDQVHXKX.js.map} +0 -0
- /package/dist/{responsiveness-probe-XLANB346.js.map → responsiveness-probe-CG7XM7GL.js.map} +0 -0
|
@@ -100,7 +100,7 @@ async function spawnPairSession(session) {
|
|
|
100
100
|
return { ok: true };
|
|
101
101
|
} catch {
|
|
102
102
|
}
|
|
103
|
-
const { resolveClaudeBinary } = await import("./persistent-session-
|
|
103
|
+
const { resolveClaudeBinary } = await import("./persistent-session-MDQVHXKX.js");
|
|
104
104
|
const claudeBin = resolveClaudeBinary();
|
|
105
105
|
const pairEnv = {
|
|
106
106
|
...process.env,
|
|
@@ -373,4 +373,4 @@ export {
|
|
|
373
373
|
startClaudePair,
|
|
374
374
|
submitClaudePairCode
|
|
375
375
|
};
|
|
376
|
-
//# sourceMappingURL=claude-pair-runtime-
|
|
376
|
+
//# sourceMappingURL=claude-pair-runtime-OIK6HKPS.js.map
|
|
@@ -43,7 +43,7 @@ import {
|
|
|
43
43
|
resolveEffectivePinRaw,
|
|
44
44
|
safeWriteJsonAtomic,
|
|
45
45
|
setConfigHash
|
|
46
|
-
} from "../chunk-
|
|
46
|
+
} from "../chunk-P3SY6KTF.js";
|
|
47
47
|
import {
|
|
48
48
|
getProjectDir as getProjectDir2,
|
|
49
49
|
getReadyTasks,
|
|
@@ -145,16 +145,16 @@ import {
|
|
|
145
145
|
toOpencodeModel,
|
|
146
146
|
transcriptActivityAgeSeconds,
|
|
147
147
|
writeEgressAllowlist
|
|
148
|
-
} from "../chunk-
|
|
148
|
+
} from "../chunk-MQHDPJZD.js";
|
|
149
149
|
import {
|
|
150
150
|
reapOrphanChannelMcps
|
|
151
151
|
} from "../chunk-XWVM4KPK.js";
|
|
152
152
|
|
|
153
153
|
// src/lib/manager-worker.ts
|
|
154
|
-
import { createHash as
|
|
155
|
-
import { readFileSync as readFileSync17, writeFileSync as writeFileSync11, mkdirSync as
|
|
154
|
+
import { createHash as createHash13 } from "crypto";
|
|
155
|
+
import { readFileSync as readFileSync17, writeFileSync as writeFileSync11, mkdirSync as mkdirSync8, existsSync as existsSync11, rmSync as rmSync5, readdirSync as readdirSync5, statSync as statSync4, copyFileSync } from "fs";
|
|
156
156
|
import { execFileSync as syncExecFile } from "child_process";
|
|
157
|
-
import { join as join21, dirname as
|
|
157
|
+
import { join as join21, dirname as dirname5, delimiter as pathDelimiter } from "path";
|
|
158
158
|
import { homedir as homedir10 } from "os";
|
|
159
159
|
import { fileURLToPath } from "url";
|
|
160
160
|
|
|
@@ -4987,35 +4987,10 @@ function closeScheduledRunsForCode(codeName, outcome, reason) {
|
|
|
4987
4987
|
}
|
|
4988
4988
|
|
|
4989
4989
|
// src/lib/manager/scheduler/kanban-route.ts
|
|
4990
|
-
import { createHash as createHash9 } from "crypto";
|
|
4991
|
-
import { writeFileSync as writeFileSync8, renameSync, mkdirSync as mkdirSync6 } from "fs";
|
|
4992
|
-
import { homedir as homedir7 } from "os";
|
|
4993
|
-
import { join as join17, dirname as dirname5 } from "path";
|
|
4994
|
-
|
|
4995
|
-
// src/lib/manager/scheduler/notify.ts
|
|
4996
4990
|
import { createHash as createHash8 } from "crypto";
|
|
4997
|
-
|
|
4998
|
-
|
|
4999
|
-
|
|
5000
|
-
"/host/scheduled-task/notify",
|
|
5001
|
-
{
|
|
5002
|
-
agent_id: opts.agentId,
|
|
5003
|
-
task_id: opts.taskId,
|
|
5004
|
-
card_id: opts.cardId,
|
|
5005
|
-
content: opts.content,
|
|
5006
|
-
run_id: opts.runId ?? void 0
|
|
5007
|
-
}
|
|
5008
|
-
);
|
|
5009
|
-
return res.ok === true;
|
|
5010
|
-
} catch (err) {
|
|
5011
|
-
const errText = err instanceof Error ? err.message : String(err);
|
|
5012
|
-
const errId = createHash8("sha256").update(errText).digest("hex").slice(0, 12);
|
|
5013
|
-
log(
|
|
5014
|
-
`[scheduled-kanban] notice enqueue failed for agent_id=${opts.agentId} task_id=${opts.taskId} error_id=${errId}`
|
|
5015
|
-
);
|
|
5016
|
-
return false;
|
|
5017
|
-
}
|
|
5018
|
-
}
|
|
4991
|
+
import { writeFileSync as writeFileSync8, renameSync } from "fs";
|
|
4992
|
+
import { homedir as homedir7 } from "os";
|
|
4993
|
+
import { join as join17 } from "path";
|
|
5019
4994
|
|
|
5020
4995
|
// src/lib/manager/delivery/scheduled-output.ts
|
|
5021
4996
|
async function deliverScheduledTaskOutput(agentCodeName, agentId, rawTarget, body, taskId) {
|
|
@@ -5361,24 +5336,22 @@ async function routeScheduledTaskViaKanban(codeName, agentId, task, prompt) {
|
|
|
5361
5336
|
` + formatRunMarker(run_id) : `A scheduled task just fired and it is now a card on YOUR board that YOU work. The schedule only controls WHEN this card arrives, not who executes it: nothing else runs it for you, so do the work yourself now. Card: id=${kanban_item_id} title=${JSON.stringify(task.name)}. Call kanban_move("${kanban_item_id}", "in_progress"), do the work described on the card, then write the finished result onto the card and mark it done. Do NOT send, post, or message the result to anyone yourself \u2014 the result you write on the card IS the message that will be delivered to the user; delivery happens automatically from the card.
|
|
5362
5337
|
` + suppressionTeaching + formatRunMarker(run_id);
|
|
5363
5338
|
stampScheduledTurnMarker(codeName, task.taskId, resolveScheduledSlackTarget(task));
|
|
5364
|
-
|
|
5365
|
-
agentId,
|
|
5366
|
-
taskId: task.taskId,
|
|
5367
|
-
cardId: kanban_item_id,
|
|
5368
|
-
content: nudge,
|
|
5369
|
-
runId: run_id
|
|
5370
|
-
});
|
|
5371
|
-
if (!enqueued) {
|
|
5372
|
-
log(`[scheduled-kanban] durable nudge enqueue failed for task '${task.name}' on '${codeName}' - closing card + run`);
|
|
5373
|
-
void finishRun(run_id, "failed", { outcomeMessage: "scheduled-task durable nudge enqueue failed", completeKanbanItemId: kanban_item_id });
|
|
5374
|
-
return false;
|
|
5375
|
-
}
|
|
5339
|
+
let injectStatus;
|
|
5376
5340
|
try {
|
|
5377
|
-
|
|
5378
|
-
mkdirSync6(dirname5(doorbell), { recursive: true });
|
|
5379
|
-
writeFileSync8(doorbell, String(Date.now()));
|
|
5341
|
+
injectStatus = await injectMessageWithStatus(codeName, "task", nudge, { task_name: "scheduled-task-do-now" }, log);
|
|
5380
5342
|
} catch (err) {
|
|
5381
|
-
log(`[scheduled-kanban]
|
|
5343
|
+
log(`[scheduled-kanban] nudge injection threw for task '${task.name}' on '${codeName}': ${err.message} \u2014 closing card + falling back to claude -p`);
|
|
5344
|
+
void finishRun(run_id, "failed", { outcomeMessage: "scheduled-task nudge delivery threw", completeKanbanItemId: kanban_item_id });
|
|
5345
|
+
return false;
|
|
5346
|
+
}
|
|
5347
|
+
const { delivered, fallbackUsed } = injectStatus;
|
|
5348
|
+
if (!delivered && !fallbackUsed) {
|
|
5349
|
+
log(`[scheduled-kanban] nudge delivery failed for task '${task.name}' on '${codeName}' \u2014 closing card + falling back to claude -p`);
|
|
5350
|
+
void finishRun(run_id, "failed", { outcomeMessage: "scheduled-task nudge delivery failed", completeKanbanItemId: kanban_item_id });
|
|
5351
|
+
return false;
|
|
5352
|
+
}
|
|
5353
|
+
if (!delivered && fallbackUsed) {
|
|
5354
|
+
log(`[scheduled-kanban] nudge sent via send-keys (unverified) for task '${task.name}' on '${codeName}' \u2014 proceeding without oneshot fallback`);
|
|
5382
5355
|
}
|
|
5383
5356
|
trackScheduledRun(codeName, kanban_item_id, run_id);
|
|
5384
5357
|
log(`[scheduled-kanban] Routed task '${task.name}' for '${codeName}' via todo card ${kanban_item_id} run_id=${run_id}`);
|
|
@@ -5423,24 +5396,24 @@ async function processClaudeTaskResult(codeName, agentId, templateId, rawOutput,
|
|
|
5423
5396
|
const assertion = parseDeliverAssertion(rawOutput);
|
|
5424
5397
|
if (!assertion.deliver) {
|
|
5425
5398
|
const trimmed = (rawOutput ?? "").trim();
|
|
5426
|
-
const outputHash = trimmed.length === 0 ? "empty" :
|
|
5399
|
+
const outputHash = trimmed.length === 0 ? "empty" : createHash8("sha256").update(trimmed).digest("hex").slice(0, 12);
|
|
5427
5400
|
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}`);
|
|
5428
5401
|
if (delivery?.mode === "announce" && delivery.to) {
|
|
5429
5402
|
await reportDeliveryStatus(agentId, delivery.taskId, { status: "skipped", error_code: "SUPPRESSED_BY_POLICY" });
|
|
5430
5403
|
}
|
|
5431
5404
|
return { ok: true };
|
|
5432
5405
|
}
|
|
5433
|
-
const reasonHash =
|
|
5406
|
+
const reasonHash = createHash8("sha256").update(assertion.reason ?? "").digest("hex").slice(0, 12);
|
|
5434
5407
|
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})`);
|
|
5435
5408
|
rawOutput = assertion.deliverable;
|
|
5436
5409
|
}
|
|
5437
5410
|
const classification = classifyOutput(rawOutput);
|
|
5438
5411
|
if (classification.action === "suppress") {
|
|
5439
5412
|
const trimmed = (rawOutput ?? "").trim();
|
|
5440
|
-
const outputHash = trimmed.length === 0 ? "empty" :
|
|
5413
|
+
const outputHash = trimmed.length === 0 ? "empty" : createHash8("sha256").update(trimmed).digest("hex").slice(0, 12);
|
|
5441
5414
|
log(`[claude-scheduler] Suppressing delivery for '${codeName}' (template=${templateId}, task=${delivery?.taskId ?? "n/a"}) \u2014 output_len=${trimmed.length} output_hash=${outputHash}`);
|
|
5442
5415
|
if (classification.suppressedNotes) {
|
|
5443
|
-
const notesHash =
|
|
5416
|
+
const notesHash = createHash8("sha256").update(classification.suppressedNotes).digest("hex").slice(0, 12);
|
|
5444
5417
|
log(`[claude-scheduler] Suppressed notes for '${codeName}' (task=${delivery?.taskId ?? "n/a"}) \u2014 notes_len=${classification.suppressedNotes.length} notes_hash=${notesHash}`);
|
|
5445
5418
|
}
|
|
5446
5419
|
if (delivery?.mode === "announce" && delivery.to) {
|
|
@@ -5506,7 +5479,7 @@ async function processClaudeTaskResult(codeName, agentId, templateId, rawOutput,
|
|
|
5506
5479
|
}
|
|
5507
5480
|
|
|
5508
5481
|
// src/lib/manager/scheduler/execution.ts
|
|
5509
|
-
import { createHash as
|
|
5482
|
+
import { createHash as createHash9 } from "crypto";
|
|
5510
5483
|
import { homedir as homedir8 } from "os";
|
|
5511
5484
|
import { join as join18 } from "path";
|
|
5512
5485
|
function claudePidFilePath() {
|
|
@@ -5530,10 +5503,10 @@ function unregisterClaudeSpawn(pid) {
|
|
|
5530
5503
|
}
|
|
5531
5504
|
async function syncAndCheckClaudeScheduler(agent, tasks, boardItems, refreshData) {
|
|
5532
5505
|
const codeName = agent.code_name;
|
|
5533
|
-
const stableTasksHash =
|
|
5534
|
-
const boardHash = boardItems.length > 0 ?
|
|
5506
|
+
const stableTasksHash = createHash9("sha256").update(JSON.stringify(tasks)).digest("hex").slice(0, 16);
|
|
5507
|
+
const boardHash = boardItems.length > 0 ? createHash9("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";
|
|
5535
5508
|
const resolvedModels = resolveModelChain(refreshData);
|
|
5536
|
-
const modelsHash =
|
|
5509
|
+
const modelsHash = createHash9("sha256").update(JSON.stringify(resolvedModels)).digest("hex").slice(0, 16);
|
|
5537
5510
|
const combinedHash = `${stableTasksHash}:${boardHash}:${modelsHash}`;
|
|
5538
5511
|
const prevHash = agentState.knownTasksHashes.get(agent.agent_id);
|
|
5539
5512
|
if (combinedHash !== prevHash) {
|
|
@@ -5571,7 +5544,7 @@ async function syncAndCheckClaudeScheduler(agent, tasks, boardItems, refreshData
|
|
|
5571
5544
|
}
|
|
5572
5545
|
|
|
5573
5546
|
// src/lib/opencode-slack-ingest.ts
|
|
5574
|
-
import { createHash as
|
|
5547
|
+
import { createHash as createHash10 } from "crypto";
|
|
5575
5548
|
|
|
5576
5549
|
// ../../packages/core/dist/channels/slack-rich-text.js
|
|
5577
5550
|
var MAX_DEPTH = 12;
|
|
@@ -6507,7 +6480,7 @@ function startSlackIngest(config2) {
|
|
|
6507
6480
|
// src/lib/opencode-slack-ingest.ts
|
|
6508
6481
|
var ingests = /* @__PURE__ */ new Map();
|
|
6509
6482
|
function fingerprint(params) {
|
|
6510
|
-
return
|
|
6483
|
+
return createHash10("sha256").update(
|
|
6511
6484
|
JSON.stringify({
|
|
6512
6485
|
appToken: params.appToken,
|
|
6513
6486
|
botToken: params.botToken,
|
|
@@ -6588,7 +6561,7 @@ function stopAllOpencodeSlackIngests(log2) {
|
|
|
6588
6561
|
}
|
|
6589
6562
|
|
|
6590
6563
|
// src/lib/manager/opencode-scheduler.ts
|
|
6591
|
-
import { createHash as
|
|
6564
|
+
import { createHash as createHash11 } from "crypto";
|
|
6592
6565
|
var MAX_OPENCODE_SCHED_CONCURRENCY = 2;
|
|
6593
6566
|
var opencodeSchedulerStates = /* @__PURE__ */ new Map();
|
|
6594
6567
|
var inFlightOpencodeTasks = /* @__PURE__ */ new Set();
|
|
@@ -6602,7 +6575,7 @@ function shouldDeliver(task, reply) {
|
|
|
6602
6575
|
}
|
|
6603
6576
|
async function syncAndCheckOpencodeScheduler(agent, tasks, refreshData) {
|
|
6604
6577
|
const codeName = agent.code_name;
|
|
6605
|
-
const tasksHash =
|
|
6578
|
+
const tasksHash = createHash11("sha256").update(JSON.stringify(tasks)).digest("hex").slice(0, 16);
|
|
6606
6579
|
if (knownOpencodeTaskHashes.get(agent.agent_id) !== tasksHash) {
|
|
6607
6580
|
const taskInputs = tasks.map((t) => buildSchedulerTaskInput(t));
|
|
6608
6581
|
const state8 = syncTasksToScheduler(codeName, agent.agent_id, taskInputs);
|
|
@@ -6680,8 +6653,8 @@ async function fireOpencodeScheduledTask(agent, task) {
|
|
|
6680
6653
|
}
|
|
6681
6654
|
|
|
6682
6655
|
// src/lib/opencode-telegram-ingest.ts
|
|
6683
|
-
import { createHash as
|
|
6684
|
-
import { existsSync as existsSync9, mkdirSync as
|
|
6656
|
+
import { createHash as createHash12 } from "crypto";
|
|
6657
|
+
import { existsSync as existsSync9, mkdirSync as mkdirSync6, readFileSync as readFileSync15, renameSync as renameSync2, unlinkSync, writeFileSync as writeFileSync9 } from "fs";
|
|
6685
6658
|
import { randomUUID } from "crypto";
|
|
6686
6659
|
import { join as join19 } from "path";
|
|
6687
6660
|
|
|
@@ -7216,7 +7189,7 @@ function anySignal(signals) {
|
|
|
7216
7189
|
// src/lib/opencode-telegram-ingest.ts
|
|
7217
7190
|
var ingests2 = /* @__PURE__ */ new Map();
|
|
7218
7191
|
function fingerprint2(params) {
|
|
7219
|
-
return
|
|
7192
|
+
return createHash12("sha256").update(
|
|
7220
7193
|
JSON.stringify({
|
|
7221
7194
|
botToken: params.botToken,
|
|
7222
7195
|
allowedChats: [...params.allowedChats].sort(),
|
|
@@ -7258,7 +7231,7 @@ function createFileOffsetStore(codeName, log2, currentBotId) {
|
|
|
7258
7231
|
if (!filePath || !dir) return;
|
|
7259
7232
|
const tmpPath = `${filePath}.${process.pid}.${randomUUID()}.tmp`;
|
|
7260
7233
|
try {
|
|
7261
|
-
|
|
7234
|
+
mkdirSync6(dir, { recursive: true, mode: 448 });
|
|
7262
7235
|
writeFileSync9(
|
|
7263
7236
|
tmpPath,
|
|
7264
7237
|
JSON.stringify({
|
|
@@ -7490,7 +7463,7 @@ function partitionActionableByPoison(actionable, states, config2) {
|
|
|
7490
7463
|
}
|
|
7491
7464
|
|
|
7492
7465
|
// src/lib/restart-flags.ts
|
|
7493
|
-
import { existsSync as existsSync10, mkdirSync as
|
|
7466
|
+
import { existsSync as existsSync10, mkdirSync as mkdirSync7, readdirSync as readdirSync4, readFileSync as readFileSync16, renameSync as renameSync3, rmSync as rmSync4, writeFileSync as writeFileSync10 } from "fs";
|
|
7494
7467
|
import { homedir as homedir9 } from "os";
|
|
7495
7468
|
import { join as join20 } from "path";
|
|
7496
7469
|
import { randomUUID as randomUUID2 } from "crypto";
|
|
@@ -8234,6 +8207,7 @@ function hasRevokedResiduals(state7) {
|
|
|
8234
8207
|
return state7.gatewayRunning || state7.portAllocated || state7.provisionDirExists;
|
|
8235
8208
|
}
|
|
8236
8209
|
var pendingSessionRestarts = /* @__PURE__ */ new Map();
|
|
8210
|
+
var lastRestartWasExternal = /* @__PURE__ */ new Map();
|
|
8237
8211
|
var pendingRestartVerifications = /* @__PURE__ */ new Map();
|
|
8238
8212
|
var restartBreaker = new RestartBreaker();
|
|
8239
8213
|
var reportedTrips = /* @__PURE__ */ new Map();
|
|
@@ -8772,7 +8746,7 @@ var sessionLaunchManagedStructure = /* @__PURE__ */ new Map();
|
|
|
8772
8746
|
function projectMcpHash(_codeName, projectDir) {
|
|
8773
8747
|
try {
|
|
8774
8748
|
const raw = readFileSync17(join21(projectDir, ".mcp.json"), "utf-8");
|
|
8775
|
-
return
|
|
8749
|
+
return createHash13("sha256").update(canonicalJson(JSON.parse(raw))).digest("hex");
|
|
8776
8750
|
} catch {
|
|
8777
8751
|
return null;
|
|
8778
8752
|
}
|
|
@@ -8934,6 +8908,7 @@ function stopPersistentSessionAndForgetMcpBaseline(codeName, breakerReason, gate
|
|
|
8934
8908
|
}
|
|
8935
8909
|
cancelPendingSessionRestart(codeName);
|
|
8936
8910
|
stopPersistentSession(codeName, log);
|
|
8911
|
+
lastRestartWasExternal.set(codeName, gateReason !== "mcp-presence-reaper");
|
|
8937
8912
|
runningMcpHashes.delete(codeName);
|
|
8938
8913
|
runningMcpServerKeys.delete(codeName);
|
|
8939
8914
|
runningChannelSecretHashes.delete(codeName);
|
|
@@ -9120,7 +9095,7 @@ var agentRestartTimezoneInputs = /* @__PURE__ */ new Map();
|
|
|
9120
9095
|
var lastVersionCheckAt = 0;
|
|
9121
9096
|
var VERSION_CHECK_INTERVAL_MS = 5 * 60 * 1e3;
|
|
9122
9097
|
var lastResponsivenessProbeAt = 0;
|
|
9123
|
-
var agtCliVersion = true ? "0.28.
|
|
9098
|
+
var agtCliVersion = true ? "0.28.385" : "dev";
|
|
9124
9099
|
function resolveBrewPath(execFileSync2) {
|
|
9125
9100
|
try {
|
|
9126
9101
|
const out = execFileSync2("which", ["brew"], { timeout: 5e3 }).toString().trim();
|
|
@@ -9215,7 +9190,7 @@ async function ensureToolkitCli(toolkitSlug) {
|
|
|
9215
9190
|
toolkitCliEnsured.add(toolkitSlug);
|
|
9216
9191
|
return;
|
|
9217
9192
|
}
|
|
9218
|
-
brewBinDir =
|
|
9193
|
+
brewBinDir = dirname5(brewPath);
|
|
9219
9194
|
const isRoot = typeof process.getuid === "function" && process.getuid() === 0;
|
|
9220
9195
|
log(`[toolkit-install] ${toolkitSlug}: installing via brew (${pkg})\u2026`);
|
|
9221
9196
|
if (isRoot) {
|
|
@@ -9425,7 +9400,7 @@ function ensureClaudeManagedSettings(path = claudeManagedSettingsPath()) {
|
|
|
9425
9400
|
}
|
|
9426
9401
|
if (settings.channelsEnabled === true) return "ok";
|
|
9427
9402
|
settings.channelsEnabled = true;
|
|
9428
|
-
|
|
9403
|
+
mkdirSync8(dirname5(path), { recursive: true });
|
|
9429
9404
|
writeFileSync11(path, `${JSON.stringify(settings, null, 2)}
|
|
9430
9405
|
`);
|
|
9431
9406
|
log(`[managed-settings] set channelsEnabled:true in ${path} (ENG-5786 \u2014 unblocks Claude Code channels)`);
|
|
@@ -9521,7 +9496,7 @@ async function ensureFrameworkBinary(frameworkId) {
|
|
|
9521
9496
|
log(`Claude Code install failed: ${err.message}`);
|
|
9522
9497
|
return;
|
|
9523
9498
|
}
|
|
9524
|
-
const brewBinDir =
|
|
9499
|
+
const brewBinDir = dirname5(brewPath);
|
|
9525
9500
|
if (!process.env.PATH?.split(":").includes(brewBinDir)) {
|
|
9526
9501
|
process.env.PATH = `${brewBinDir}:${process.env.PATH ?? ""}`;
|
|
9527
9502
|
}
|
|
@@ -9955,7 +9930,7 @@ function ensureEvalEmptyMcpConfig() {
|
|
|
9955
9930
|
if (evalEmptyMcpConfigPath && existsSync11(evalEmptyMcpConfigPath)) return evalEmptyMcpConfigPath;
|
|
9956
9931
|
const dir = join21(homedir10(), ".augmented");
|
|
9957
9932
|
try {
|
|
9958
|
-
|
|
9933
|
+
mkdirSync8(dir, { recursive: true });
|
|
9959
9934
|
} catch {
|
|
9960
9935
|
}
|
|
9961
9936
|
const p = join21(dir, ".eval-empty-mcp.json");
|
|
@@ -10249,7 +10224,7 @@ function flushRestartedAgentDiagnostics(hostId, codeNames) {
|
|
|
10249
10224
|
if (codeNames.length === 0) return;
|
|
10250
10225
|
void (async () => {
|
|
10251
10226
|
try {
|
|
10252
|
-
const { collectDiagnostics } = await import("../persistent-session-
|
|
10227
|
+
const { collectDiagnostics } = await import("../persistent-session-MDQVHXKX.js");
|
|
10253
10228
|
await api.post("/host/heartbeat", {
|
|
10254
10229
|
host_id: hostId,
|
|
10255
10230
|
agent_diagnostics: collectDiagnostics(codeNames)
|
|
@@ -10348,7 +10323,7 @@ async function pollCycle() {
|
|
|
10348
10323
|
}
|
|
10349
10324
|
try {
|
|
10350
10325
|
const { detectHostSecurity } = await import("../host-security-6PDFG7F5.js");
|
|
10351
|
-
const { collectDiagnostics } = await import("../persistent-session-
|
|
10326
|
+
const { collectDiagnostics } = await import("../persistent-session-MDQVHXKX.js");
|
|
10352
10327
|
const diagCodeNames = [...agentState.persistentSessionAgents];
|
|
10353
10328
|
const agentDiagnostics = diagCodeNames.length > 0 ? collectDiagnostics(diagCodeNames) : void 0;
|
|
10354
10329
|
let tailscaleHostname;
|
|
@@ -10378,7 +10353,7 @@ async function pollCycle() {
|
|
|
10378
10353
|
claudeAuth = await detectClaudeAuth();
|
|
10379
10354
|
} catch (err) {
|
|
10380
10355
|
const errText = err instanceof Error ? err.message : String(err);
|
|
10381
|
-
const errId =
|
|
10356
|
+
const errId = createHash13("sha256").update(errText).digest("hex").slice(0, 12);
|
|
10382
10357
|
log(`Claude auth detection failed (error_id=${errId})`);
|
|
10383
10358
|
}
|
|
10384
10359
|
const hostHasClaudeCode = state6.agents.some(
|
|
@@ -10503,7 +10478,7 @@ async function pollCycle() {
|
|
|
10503
10478
|
const {
|
|
10504
10479
|
collectResponsivenessProbes,
|
|
10505
10480
|
getResponsivenessIntervalMs
|
|
10506
|
-
} = await import("../responsiveness-probe-
|
|
10481
|
+
} = await import("../responsiveness-probe-CG7XM7GL.js");
|
|
10507
10482
|
const probeIntervalMs = getResponsivenessIntervalMs();
|
|
10508
10483
|
if (now - lastResponsivenessProbeAt > probeIntervalMs) {
|
|
10509
10484
|
const probeCodeNames = [...agentState.persistentSessionAgents];
|
|
@@ -10535,7 +10510,7 @@ async function pollCycle() {
|
|
|
10535
10510
|
collectResponsivenessProbes,
|
|
10536
10511
|
livePendingInboundOldestAgeSeconds,
|
|
10537
10512
|
parkPendingInbound
|
|
10538
|
-
} = await import("../responsiveness-probe-
|
|
10513
|
+
} = await import("../responsiveness-probe-CG7XM7GL.js");
|
|
10539
10514
|
const { getProjectDir: wedgeProjectDir } = await import("../scheduler-engine-HYOOQV4A.js");
|
|
10540
10515
|
const wedgeNow = /* @__PURE__ */ new Date();
|
|
10541
10516
|
const liveAgents = agentState.persistentSessionAgents;
|
|
@@ -11337,7 +11312,7 @@ async function processAgent(agent, agentStates) {
|
|
|
11337
11312
|
try {
|
|
11338
11313
|
const artifacts = generateArtifacts(agent, refreshData, frameworkAdapter);
|
|
11339
11314
|
const changedFiles = [];
|
|
11340
|
-
|
|
11315
|
+
mkdirSync8(agentDir, { recursive: true });
|
|
11341
11316
|
for (const artifact of artifacts) {
|
|
11342
11317
|
const filePath = join21(agentDir, artifact.relativePath);
|
|
11343
11318
|
let existingHash;
|
|
@@ -11415,7 +11390,7 @@ async function processAgent(agent, agentStates) {
|
|
|
11415
11390
|
log(`${verb} '${agent.code_name}': ${fileNames}`);
|
|
11416
11391
|
for (const file of changedFiles) {
|
|
11417
11392
|
const filePath = join21(agentDir, file.relativePath);
|
|
11418
|
-
|
|
11393
|
+
mkdirSync8(dirname5(filePath), { recursive: true });
|
|
11419
11394
|
if (file.relativePath === ".mcp.json") {
|
|
11420
11395
|
safeWriteJsonAtomic(filePath, file.content, { mode: 384 });
|
|
11421
11396
|
} else {
|
|
@@ -11747,7 +11722,7 @@ async function processAgent(agent, agentStates) {
|
|
|
11747
11722
|
const writeDmNoticeMarkers = isChannelAddRestart ? () => {
|
|
11748
11723
|
try {
|
|
11749
11724
|
const agentAugmentedDir = join21(homedir10(), ".augmented", agent.code_name);
|
|
11750
|
-
|
|
11725
|
+
mkdirSync8(agentAugmentedDir, { recursive: true });
|
|
11751
11726
|
const markerJson = JSON.stringify({
|
|
11752
11727
|
version: 1,
|
|
11753
11728
|
at: (/* @__PURE__ */ new Date()).toISOString(),
|
|
@@ -11830,7 +11805,7 @@ async function processAgent(agent, agentStates) {
|
|
|
11830
11805
|
const behaviourSubset = extractMsTeamsBehaviourSubset(
|
|
11831
11806
|
msteamsEntry?.config
|
|
11832
11807
|
);
|
|
11833
|
-
const behaviourHash =
|
|
11808
|
+
const behaviourHash = createHash13("sha256").update(canonicalJson(behaviourSubset)).digest("hex");
|
|
11834
11809
|
const prevBehaviourHash = agentState.knownMsTeamsBehaviourHashes.get(agent.agent_id);
|
|
11835
11810
|
const msteamsBehaviourRestrictive = isMsTeamsBehaviourRestrictive(behaviourSubset);
|
|
11836
11811
|
const behaviourDecision = decideSenderPolicyRestart({
|
|
@@ -11886,7 +11861,7 @@ async function processAgent(agent, agentStates) {
|
|
|
11886
11861
|
const slackBehaviourSubset = extractSlackBehaviourSubset(
|
|
11887
11862
|
slackEntry?.config
|
|
11888
11863
|
);
|
|
11889
|
-
const slackBehaviourHash =
|
|
11864
|
+
const slackBehaviourHash = createHash13("sha256").update(canonicalJson(slackBehaviourSubset)).digest("hex");
|
|
11890
11865
|
const prevSlackBehaviourHash = agentState.knownSlackBehaviourHashes.get(agent.agent_id);
|
|
11891
11866
|
const slackBehaviourRestrictive = isSlackBehaviourRestrictive(slackBehaviourSubset);
|
|
11892
11867
|
const slackBehaviourDecision = decideSenderPolicyRestart({
|
|
@@ -11944,8 +11919,8 @@ async function processAgent(agent, agentStates) {
|
|
|
11944
11919
|
try {
|
|
11945
11920
|
const agentProvisionDir = agentDir;
|
|
11946
11921
|
const projectDir = join21(homedir10(), ".augmented", agent.code_name, "project");
|
|
11947
|
-
|
|
11948
|
-
|
|
11922
|
+
mkdirSync8(agentProvisionDir, { recursive: true });
|
|
11923
|
+
mkdirSync8(projectDir, { recursive: true });
|
|
11949
11924
|
const provisionMcpPath = join21(agentProvisionDir, ".mcp.json");
|
|
11950
11925
|
const projectMcpPath = join21(projectDir, ".mcp.json");
|
|
11951
11926
|
let mcpConfig = { mcpServers: {} };
|
|
@@ -12270,10 +12245,10 @@ async function processAgent(agent, agentStates) {
|
|
|
12270
12245
|
desiredEntries.push({ serverId, url, headers: mcpHeaders, name: tk.toolkit_name });
|
|
12271
12246
|
}
|
|
12272
12247
|
const hashBasis = desiredEntries.slice().sort((a, b) => a.serverId.localeCompare(b.serverId)).map((e) => {
|
|
12273
|
-
const headersHash =
|
|
12248
|
+
const headersHash = createHash13("sha256").update(canonicalJson(e.headers ?? {})).digest("hex").slice(0, 16);
|
|
12274
12249
|
return `${e.serverId}|${e.url}|${headersHash}`;
|
|
12275
12250
|
}).join("\n");
|
|
12276
|
-
const mcpHash =
|
|
12251
|
+
const mcpHash = createHash13("sha256").update(hashBasis).digest("hex").slice(0, 16);
|
|
12277
12252
|
const prevMcpHash = agentState.knownManagedMcpHashes.get(agent.agent_id);
|
|
12278
12253
|
const structureHash = managedMcpStructureHash(desiredEntries);
|
|
12279
12254
|
const prevStructureHash = agentState.knownManagedMcpStructure.get(agent.agent_id);
|
|
@@ -12288,7 +12263,7 @@ async function processAgent(agent, agentStates) {
|
|
|
12288
12263
|
if (mcpHash !== prevMcpHash) {
|
|
12289
12264
|
for (const e of desiredEntries) {
|
|
12290
12265
|
frameworkAdapter.writeMcpServer(agent.code_name, e.serverId, { url: e.url, headers: e.headers });
|
|
12291
|
-
const urlHash =
|
|
12266
|
+
const urlHash = createHash13("sha256").update(e.url).digest("hex").slice(0, 12);
|
|
12292
12267
|
log(`[managed-toolkit] ${agent.code_name}: wrote '${e.name}' (serverId=${e.serverId}, url_hash=${urlHash})`);
|
|
12293
12268
|
}
|
|
12294
12269
|
if (frameworkAdapter.removeMcpServer && frameworkAdapter.getMcpPath) {
|
|
@@ -12397,7 +12372,7 @@ async function processAgent(agent, agentStates) {
|
|
|
12397
12372
|
if (frameworkAdapter.installSkillFiles) {
|
|
12398
12373
|
const currentIntegrationSkillIds = /* @__PURE__ */ new Set();
|
|
12399
12374
|
const installedIntegrationSkills = [];
|
|
12400
|
-
const { createHash:
|
|
12375
|
+
const { createHash: createHash14 } = await import("crypto");
|
|
12401
12376
|
const refreshAny = refreshData;
|
|
12402
12377
|
const contexts = refreshAny.integration_contexts ?? refreshAny.plugin_contexts ?? [];
|
|
12403
12378
|
const contextBySlug = /* @__PURE__ */ new Map();
|
|
@@ -12426,7 +12401,7 @@ async function processAgent(agent, agentStates) {
|
|
|
12426
12401
|
)
|
|
12427
12402
|
}));
|
|
12428
12403
|
const bundle = buildIntegrationBundle(renderedScopes);
|
|
12429
|
-
const contentHash =
|
|
12404
|
+
const contentHash = createHash14("sha256").update(bundleFingerprint(bundle.files)).digest("hex").slice(0, 12);
|
|
12430
12405
|
const hashKey = `plugin-skill:${agent.agent_id}:${integrationSkillId}`;
|
|
12431
12406
|
if (agentState.knownSkillHashes.get(hashKey) === contentHash) continue;
|
|
12432
12407
|
frameworkAdapter.installSkillFiles(agent.code_name, integrationSkillId, bundle.files);
|
|
@@ -12493,7 +12468,7 @@ async function processAgent(agent, agentStates) {
|
|
|
12493
12468
|
const plan = planGlobalSkillSync(
|
|
12494
12469
|
[...globalSkillsPayload ?? [], ...sharedSkillsPayload ?? []],
|
|
12495
12470
|
prevIds,
|
|
12496
|
-
(content) =>
|
|
12471
|
+
(content) => createHash14("sha256").update(content).digest("hex").slice(0, 12),
|
|
12497
12472
|
(skillId) => agentState.knownSkillHashes.get(`global-skill:${agent.agent_id}:${skillId}`),
|
|
12498
12473
|
{ desiredResolved }
|
|
12499
12474
|
);
|
|
@@ -12544,7 +12519,7 @@ async function processAgent(agent, agentStates) {
|
|
|
12544
12519
|
const slug = hook.integration_slug ?? hook.plugin_slug;
|
|
12545
12520
|
if (!slug) continue;
|
|
12546
12521
|
try {
|
|
12547
|
-
const scriptHash =
|
|
12522
|
+
const scriptHash = createHash14("sha256").update(hook.script).digest("hex").slice(0, 12);
|
|
12548
12523
|
const hookKey = `${agent.agent_id}:${frameworkAdapter.id}:plugin-hook:${slug}:on_install`;
|
|
12549
12524
|
if (agentState.knownSkillHashes.get(hookKey) === scriptHash) continue;
|
|
12550
12525
|
const result = await frameworkAdapter.executePluginHook({
|
|
@@ -12559,9 +12534,9 @@ async function processAgent(agent, agentStates) {
|
|
|
12559
12534
|
} else if (result.timedOut) {
|
|
12560
12535
|
log(`Integration hook on_install '${slug}' TIMED OUT for '${agent.code_name}' after ${result.durationMs}ms`);
|
|
12561
12536
|
} else {
|
|
12562
|
-
const stderrHash =
|
|
12537
|
+
const stderrHash = createHash14("sha256").update(result.stderr).digest("hex").slice(0, 12);
|
|
12563
12538
|
const missingCmd = result.exitCode === 127 ? extractCommandNotFound(result.stderr) : null;
|
|
12564
|
-
const missingCmdHash = missingCmd ?
|
|
12539
|
+
const missingCmdHash = missingCmd ? createHash14("sha256").update(missingCmd).digest("hex").slice(0, 8) : null;
|
|
12565
12540
|
log(
|
|
12566
12541
|
`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}]`
|
|
12567
12542
|
);
|
|
@@ -12750,6 +12725,14 @@ async function processAgent(agent, agentStates) {
|
|
|
12750
12725
|
// but-not-yet-live MCP, so don't let the reaper re-fire + inflate the
|
|
12751
12726
|
// McpReaperRestartsHourly metric into a false flapping alarm.
|
|
12752
12727
|
restartPending: pendingSessionRestarts.has(agent.code_name),
|
|
12728
|
+
// ENG-8013 (storm-awareness): tell the reaper whether THIS session
|
|
12729
|
+
// generation was born from an external respawn (integration-change /
|
|
12730
|
+
// channel-set-change / day-rollover / wedge / operator restart, or a
|
|
12731
|
+
// storm) vs the reaper's own recovery restart. When external, a missing
|
|
12732
|
+
// channel MCP is churn collateral and must not accrue quarantine budget,
|
|
12733
|
+
// the durable fix for the ENG-8003 storm-quarantine incident. Absent map
|
|
12734
|
+
// entry (first boot) → false → count normally.
|
|
12735
|
+
currentGenerationExternallyStarted: lastRestartWasExternal.get(agent.code_name) ?? false,
|
|
12753
12736
|
// ENG-5441 / ENG-5547: a mcp-presence-reaper restart counts against
|
|
12754
12737
|
// the agent-wide breaker ONLY when several distinct MCP servers are
|
|
12755
12738
|
// missing at once — a thrashing collection that rotates restarts of
|
|
@@ -13350,7 +13333,7 @@ async function ensurePersistentSession(agent, tasks, boardItems, refreshData) {
|
|
|
13350
13333
|
const ctx = getLastFailureContext(codeName);
|
|
13351
13334
|
const recovery = prepareForRespawn(codeName);
|
|
13352
13335
|
const tailSummary = !ctx.tail ? "" : KNOWN_SAFE_TAIL_SIGNATURES.has(ctx.signature) ? `; last pane output (${PANE_TAIL_PREVIEW_LINES} of ~20 lines):
|
|
13353
|
-
${truncateForLog(ctx.tail)}` : `; pane_tail_hash=sha256:${
|
|
13336
|
+
${truncateForLog(ctx.tail)}` : `; pane_tail_hash=sha256:${createHash13("sha256").update(ctx.tail).digest("hex").slice(0, 12)} (raw at ~/.augmented/${codeName}/pane.log)`;
|
|
13354
13337
|
const sigSummary = ctx.signature !== "unknown" ? `; signature=${ctx.signature}` : "";
|
|
13355
13338
|
const recoverySummary = recovery ? `; recovery=${recovery}` : "";
|
|
13356
13339
|
log(
|
|
@@ -13364,7 +13347,7 @@ ${truncateForLog(ctx.tail)}` : `; pane_tail_hash=sha256:${createHash14("sha256")
|
|
|
13364
13347
|
);
|
|
13365
13348
|
getHostId().then((hostId) => {
|
|
13366
13349
|
if (!hostId) return;
|
|
13367
|
-
const paneTailHash = zombie.paneTail ? `sha256:${
|
|
13350
|
+
const paneTailHash = zombie.paneTail ? `sha256:${createHash13("sha256").update(zombie.paneTail).digest("hex").slice(0, 12)}` : null;
|
|
13368
13351
|
return api.post("/host/events", {
|
|
13369
13352
|
host_id: hostId,
|
|
13370
13353
|
agent_code_name: codeName,
|
|
@@ -13513,7 +13496,7 @@ ${truncateForLog(ctx.tail)}` : `; pane_tail_hash=sha256:${createHash14("sha256")
|
|
|
13513
13496
|
if (!claudeAuthTupleBySession.has(codeName)) {
|
|
13514
13497
|
claudeAuthTupleBySession.set(codeName, currentAuthTuple);
|
|
13515
13498
|
}
|
|
13516
|
-
const stableTasksHash =
|
|
13499
|
+
const stableTasksHash = createHash13("sha256").update(JSON.stringify(tasks)).digest("hex").slice(0, 16);
|
|
13517
13500
|
const prevHash = agentState.knownTasksHashes.get(agent.agent_id);
|
|
13518
13501
|
if (stableTasksHash !== prevHash) {
|
|
13519
13502
|
const taskInputs = tasks.map((t) => buildSchedulerTaskInput(t));
|
|
@@ -13730,7 +13713,7 @@ async function handleRestartDoorbell(agentId, requestedAt, restartReason) {
|
|
|
13730
13713
|
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}`));
|
|
13731
13714
|
void (async () => {
|
|
13732
13715
|
try {
|
|
13733
|
-
const { collectDiagnostics } = await import("../persistent-session-
|
|
13716
|
+
const { collectDiagnostics } = await import("../persistent-session-MDQVHXKX.js");
|
|
13734
13717
|
await api.post("/host/heartbeat", {
|
|
13735
13718
|
host_id: hostId,
|
|
13736
13719
|
agent_diagnostics: collectDiagnostics([codeName])
|
|
@@ -13780,7 +13763,7 @@ async function respawnAgentAfterMcpStop(codeName, reason) {
|
|
|
13780
13763
|
}
|
|
13781
13764
|
try {
|
|
13782
13765
|
const hostId = await getHostId();
|
|
13783
|
-
const { collectDiagnostics } = await import("../persistent-session-
|
|
13766
|
+
const { collectDiagnostics } = await import("../persistent-session-MDQVHXKX.js");
|
|
13784
13767
|
await api.post("/host/heartbeat", {
|
|
13785
13768
|
host_id: hostId,
|
|
13786
13769
|
agent_diagnostics: collectDiagnostics([codeName])
|
|
@@ -14066,7 +14049,7 @@ async function processDirectChatMessage(agent, msg) {
|
|
|
14066
14049
|
if (useDoorbell) {
|
|
14067
14050
|
try {
|
|
14068
14051
|
const doorbell = directChatDoorbellPath(agent.agentId, homedir10());
|
|
14069
|
-
|
|
14052
|
+
mkdirSync8(dirname5(doorbell), { recursive: true });
|
|
14070
14053
|
writeFileSync11(doorbell, String(Date.now()));
|
|
14071
14054
|
log(`[direct-chat] Doorbell rung for '${agent.codeName}' (msg=${msg.id}) \u2014 in-session MCP will pull via the cursor`);
|
|
14072
14055
|
return;
|
|
@@ -14176,7 +14159,7 @@ ${formatRunMarker(run_id)}` : KANBAN_CHECK_COMMAND;
|
|
|
14176
14159
|
if (run_id) openInjectedRunByCode.set(codeName, run_id);
|
|
14177
14160
|
try {
|
|
14178
14161
|
const doorbell = directChatDoorbellPath(agentId, homedir10());
|
|
14179
|
-
|
|
14162
|
+
mkdirSync8(dirname5(doorbell), { recursive: true });
|
|
14180
14163
|
writeFileSync11(doorbell, String(Date.now()));
|
|
14181
14164
|
} catch (err) {
|
|
14182
14165
|
log(`[kanban] doorbell ring failed for '${codeName}': ${err.message} (notice still queued)`);
|
|
@@ -14233,7 +14216,7 @@ async function processClaudePairSessions(agents) {
|
|
|
14233
14216
|
killPairSession,
|
|
14234
14217
|
pairTmuxSession,
|
|
14235
14218
|
finalizeClaudePairOnboarding
|
|
14236
|
-
} = await import("../claude-pair-runtime-
|
|
14219
|
+
} = await import("../claude-pair-runtime-OIK6HKPS.js");
|
|
14237
14220
|
for (const pairId of pendingResp.cancelled_pair_ids ?? []) {
|
|
14238
14221
|
log(`[claude-pair] sweeping orphan tmux session for pair ${pairId.slice(0, 8)}`);
|
|
14239
14222
|
const killed = await killPairSession(pairTmuxSession(pairId));
|
|
@@ -14503,7 +14486,7 @@ async function syncMemories(agent, configDir, log2) {
|
|
|
14503
14486
|
if (!file.endsWith(".md")) continue;
|
|
14504
14487
|
try {
|
|
14505
14488
|
const raw = readFileSync17(join21(memoryDir, file), "utf-8");
|
|
14506
|
-
const fileHash =
|
|
14489
|
+
const fileHash = createHash13("sha256").update(raw).digest("hex").slice(0, 16);
|
|
14507
14490
|
currentHashes.set(file, fileHash);
|
|
14508
14491
|
if (prevHashes.get(file) === fileHash) continue;
|
|
14509
14492
|
const parsed = parseMemoryFile(raw, file.replace(/\.md$/, ""));
|
|
@@ -14541,21 +14524,21 @@ async function syncMemories(agent, configDir, log2) {
|
|
|
14541
14524
|
}
|
|
14542
14525
|
async function downloadMemories(agent, memoryDir, log2, { force }) {
|
|
14543
14526
|
const localFiles = existsSync11(memoryDir) ? readdirSync5(memoryDir).filter((f) => f.endsWith(".md")).sort() : [];
|
|
14544
|
-
const localListHash =
|
|
14527
|
+
const localListHash = createHash13("sha256").update(localFiles.join(",")).digest("hex").slice(0, 16);
|
|
14545
14528
|
const prevLocalHash = lastLocalFileHash.get(agent.agent_id);
|
|
14546
14529
|
const prevDownload = lastDownloadHash.get(agent.agent_id);
|
|
14547
14530
|
try {
|
|
14548
14531
|
const dbMemories = await api.post("/host/memories", {
|
|
14549
14532
|
agent_id: agent.agent_id
|
|
14550
14533
|
});
|
|
14551
|
-
const responseHash =
|
|
14534
|
+
const responseHash = createHash13("sha256").update(JSON.stringify(dbMemories.memories ?? [])).digest("hex").slice(0, 16);
|
|
14552
14535
|
if (!force && prevDownload && prevLocalHash === localListHash && lastDownloadHash.get(agent.agent_id) === responseHash) {
|
|
14553
14536
|
return true;
|
|
14554
14537
|
}
|
|
14555
14538
|
lastDownloadHash.set(agent.agent_id, responseHash);
|
|
14556
14539
|
lastLocalFileHash.set(agent.agent_id, localListHash);
|
|
14557
14540
|
if (dbMemories.memories?.length) {
|
|
14558
|
-
|
|
14541
|
+
mkdirSync8(memoryDir, { recursive: true });
|
|
14559
14542
|
let written = 0;
|
|
14560
14543
|
let overwritten = 0;
|
|
14561
14544
|
for (let i = 0; i < dbMemories.memories.length; i++) {
|
|
@@ -14587,7 +14570,7 @@ ${mem.content}
|
|
|
14587
14570
|
}
|
|
14588
14571
|
if (written > 0 || overwritten > 0) {
|
|
14589
14572
|
const updatedFiles = readdirSync5(memoryDir).filter((f) => f.endsWith(".md")).sort();
|
|
14590
|
-
lastLocalFileHash.set(agent.agent_id,
|
|
14573
|
+
lastLocalFileHash.set(agent.agent_id, createHash13("sha256").update(updatedFiles.join(",")).digest("hex").slice(0, 16));
|
|
14591
14574
|
log2(`Memory download for '${agent.code_name}': wrote ${written} new, overwrote ${overwritten} stale`);
|
|
14592
14575
|
}
|
|
14593
14576
|
}
|
|
@@ -14982,8 +14965,8 @@ function restartRunningChannelMcps(basenames) {
|
|
|
14982
14965
|
}
|
|
14983
14966
|
function deployMcpAssets() {
|
|
14984
14967
|
const targetDir = join21(homedir10(), ".augmented", "_mcp");
|
|
14985
|
-
|
|
14986
|
-
const moduleDir =
|
|
14968
|
+
mkdirSync8(targetDir, { recursive: true });
|
|
14969
|
+
const moduleDir = dirname5(fileURLToPath(import.meta.url));
|
|
14987
14970
|
let mcpSourceDir = "";
|
|
14988
14971
|
let dir = moduleDir;
|
|
14989
14972
|
for (let i = 0; i < 6; i++) {
|
|
@@ -14992,7 +14975,7 @@ function deployMcpAssets() {
|
|
|
14992
14975
|
mcpSourceDir = candidate;
|
|
14993
14976
|
break;
|
|
14994
14977
|
}
|
|
14995
|
-
const parent =
|
|
14978
|
+
const parent = dirname5(dir);
|
|
14996
14979
|
if (parent === dir) break;
|
|
14997
14980
|
dir = parent;
|
|
14998
14981
|
}
|
|
@@ -15004,7 +14987,7 @@ function deployMcpAssets() {
|
|
|
15004
14987
|
const fileHash = (p) => {
|
|
15005
14988
|
try {
|
|
15006
14989
|
if (!existsSync11(p)) return null;
|
|
15007
|
-
return
|
|
14990
|
+
return createHash13("sha256").update(readFileSync17(p)).digest("hex");
|
|
15008
14991
|
} catch {
|
|
15009
14992
|
return null;
|
|
15010
14993
|
}
|