@integrity-labs/agt-cli 0.28.322 → 0.28.323
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-LJT3U3GQ.js → chunk-JTQ6RYGM.js} +12 -12
- package/dist/{chunk-FG7ELAP4.js → chunk-MLXFGOLB.js} +8536 -8536
- package/dist/chunk-MLXFGOLB.js.map +1 -0
- package/dist/{claude-pair-runtime-ZL2U2NZJ.js → claude-pair-runtime-JSOSBAH3.js} +2 -2
- package/dist/lib/manager-worker.js +252 -171
- package/dist/lib/manager-worker.js.map +1 -1
- package/dist/{persistent-session-L6S6HABH.js → persistent-session-5FKI4NCL.js} +2 -2
- package/dist/{responsiveness-probe-X2WATO46.js → responsiveness-probe-R42UJ5ZR.js} +2 -2
- package/package.json +1 -1
- package/dist/chunk-FG7ELAP4.js.map +0 -1
- /package/dist/{chunk-LJT3U3GQ.js.map → chunk-JTQ6RYGM.js.map} +0 -0
- /package/dist/{claude-pair-runtime-ZL2U2NZJ.js.map → claude-pair-runtime-JSOSBAH3.js.map} +0 -0
- /package/dist/{persistent-session-L6S6HABH.js.map → persistent-session-5FKI4NCL.js.map} +0 -0
- /package/dist/{responsiveness-probe-X2WATO46.js.map → responsiveness-probe-R42UJ5ZR.js.map} +0 -0
|
@@ -43,7 +43,7 @@ import {
|
|
|
43
43
|
requireHost,
|
|
44
44
|
safeWriteJsonAtomic,
|
|
45
45
|
setConfigHash
|
|
46
|
-
} from "../chunk-
|
|
46
|
+
} from "../chunk-MLXFGOLB.js";
|
|
47
47
|
import {
|
|
48
48
|
getProjectDir as getProjectDir2,
|
|
49
49
|
getReadyTasks,
|
|
@@ -132,16 +132,16 @@ import {
|
|
|
132
132
|
takeZombieDetection,
|
|
133
133
|
transcriptActivityAgeSeconds,
|
|
134
134
|
writeEgressAllowlist
|
|
135
|
-
} from "../chunk-
|
|
135
|
+
} from "../chunk-JTQ6RYGM.js";
|
|
136
136
|
import {
|
|
137
137
|
reapOrphanChannelMcps
|
|
138
138
|
} from "../chunk-XWVM4KPK.js";
|
|
139
139
|
|
|
140
140
|
// src/lib/manager-worker.ts
|
|
141
141
|
import { createHash as createHash12 } from "crypto";
|
|
142
|
-
import { readFileSync as
|
|
142
|
+
import { readFileSync as readFileSync18, writeFileSync as writeFileSync9, mkdirSync as mkdirSync8, existsSync as existsSync12, rmSync as rmSync4, readdirSync as readdirSync5, statSync as statSync4, copyFileSync } from "fs";
|
|
143
143
|
import { execFileSync as syncExecFile } from "child_process";
|
|
144
|
-
import { join as
|
|
144
|
+
import { join as join21, dirname as dirname6 } from "path";
|
|
145
145
|
import { homedir as homedir11 } from "os";
|
|
146
146
|
import { fileURLToPath } from "url";
|
|
147
147
|
|
|
@@ -4122,10 +4122,14 @@ function isHybridActionable(item) {
|
|
|
4122
4122
|
function kanbanActionableSignature(allowed) {
|
|
4123
4123
|
return allowed.map((i) => `${i.id}:${i.status}`).sort().join("|");
|
|
4124
4124
|
}
|
|
4125
|
-
function
|
|
4125
|
+
function nudgeIntervalForCount(nudgeCount, fullCadenceMs, maxCadenceMs) {
|
|
4126
|
+
const exponent = Math.max(0, Math.min(nudgeCount - 1, 8));
|
|
4127
|
+
return Math.min(fullCadenceMs * 3 ** exponent, Math.max(maxCadenceMs, fullCadenceMs));
|
|
4128
|
+
}
|
|
4129
|
+
function shouldNudgeUnchangedBoard(signature, state7, now, fullCadenceMs, maxCadenceMs = fullCadenceMs) {
|
|
4126
4130
|
if (!state7) return true;
|
|
4127
4131
|
if (state7.signature !== signature) return true;
|
|
4128
|
-
return now - state7.nudgedAt >= fullCadenceMs;
|
|
4132
|
+
return now - state7.nudgedAt >= nudgeIntervalForCount(state7.nudgeCount ?? 1, fullCadenceMs, maxCadenceMs);
|
|
4129
4133
|
}
|
|
4130
4134
|
function isSlashCommand(command) {
|
|
4131
4135
|
return command.trimStart().startsWith("/");
|
|
@@ -4373,6 +4377,49 @@ function formatBoardForPrompt(items, template) {
|
|
|
4373
4377
|
return lines.join("\n");
|
|
4374
4378
|
}
|
|
4375
4379
|
|
|
4380
|
+
// src/lib/manager/kanban/nudge-state-cache.ts
|
|
4381
|
+
import { existsSync as existsSync9, readFileSync as readFileSync15, writeFileSync as writeFileSync6 } from "fs";
|
|
4382
|
+
import { join as join16 } from "path";
|
|
4383
|
+
var CACHE_FILENAME2 = "kanban-nudge-state.json";
|
|
4384
|
+
var KANBAN_NUDGE_STATE_VERSION = 1;
|
|
4385
|
+
function getKanbanNudgeStateFile(configDir) {
|
|
4386
|
+
return join16(configDir, CACHE_FILENAME2);
|
|
4387
|
+
}
|
|
4388
|
+
function loadKanbanNudgeState(target, configDir) {
|
|
4389
|
+
const path = getKanbanNudgeStateFile(configDir);
|
|
4390
|
+
if (!existsSync9(path)) return;
|
|
4391
|
+
let parsed;
|
|
4392
|
+
try {
|
|
4393
|
+
parsed = JSON.parse(readFileSync15(path, "utf-8"));
|
|
4394
|
+
} catch {
|
|
4395
|
+
return;
|
|
4396
|
+
}
|
|
4397
|
+
if (!parsed || typeof parsed !== "object" || Array.isArray(parsed)) return;
|
|
4398
|
+
const obj = parsed;
|
|
4399
|
+
if (obj.version !== KANBAN_NUDGE_STATE_VERSION) return;
|
|
4400
|
+
const entries = obj.agents;
|
|
4401
|
+
if (!entries || typeof entries !== "object" || Array.isArray(entries)) return;
|
|
4402
|
+
for (const [codeName, value] of Object.entries(entries)) {
|
|
4403
|
+
if (!value || typeof value !== "object") continue;
|
|
4404
|
+
const v = value;
|
|
4405
|
+
if (typeof v.signature !== "string" || typeof v.nudgedAt !== "number" || !Number.isFinite(v.nudgedAt)) continue;
|
|
4406
|
+
target.set(codeName, {
|
|
4407
|
+
signature: v.signature,
|
|
4408
|
+
nudgedAt: v.nudgedAt,
|
|
4409
|
+
nudgeCount: typeof v.nudgeCount === "number" && Number.isFinite(v.nudgeCount) && v.nudgeCount >= 1 ? Math.floor(v.nudgeCount) : 1
|
|
4410
|
+
});
|
|
4411
|
+
}
|
|
4412
|
+
}
|
|
4413
|
+
function saveKanbanNudgeState(source, configDir) {
|
|
4414
|
+
const path = getKanbanNudgeStateFile(configDir);
|
|
4415
|
+
const agents = {};
|
|
4416
|
+
for (const [codeName, state7] of source) agents[codeName] = state7;
|
|
4417
|
+
try {
|
|
4418
|
+
writeFileSync6(path, JSON.stringify({ version: KANBAN_NUDGE_STATE_VERSION, agents }, null, 2));
|
|
4419
|
+
} catch {
|
|
4420
|
+
}
|
|
4421
|
+
}
|
|
4422
|
+
|
|
4376
4423
|
// src/lib/manager/kanban/notify.ts
|
|
4377
4424
|
import { createHash as createHash7 } from "crypto";
|
|
4378
4425
|
async function enqueueKanbanNotice(opts) {
|
|
@@ -4904,9 +4951,9 @@ function closeScheduledRunsForCode(codeName, outcome, reason) {
|
|
|
4904
4951
|
|
|
4905
4952
|
// src/lib/manager/scheduler/kanban-route.ts
|
|
4906
4953
|
import { createHash as createHash9 } from "crypto";
|
|
4907
|
-
import { writeFileSync as
|
|
4954
|
+
import { writeFileSync as writeFileSync7, renameSync } from "fs";
|
|
4908
4955
|
import { homedir as homedir7 } from "os";
|
|
4909
|
-
import { join as
|
|
4956
|
+
import { join as join17 } from "path";
|
|
4910
4957
|
|
|
4911
4958
|
// src/lib/manager/delivery/scheduled-output.ts
|
|
4912
4959
|
async function deliverScheduledTaskOutput(agentCodeName, agentId, rawTarget, body, taskId) {
|
|
@@ -5210,10 +5257,10 @@ function resolveScheduledSlackTarget(task) {
|
|
|
5210
5257
|
}
|
|
5211
5258
|
function stampScheduledTurnMarker(codeName, taskId, target) {
|
|
5212
5259
|
try {
|
|
5213
|
-
const file =
|
|
5260
|
+
const file = join17(homedir7(), ".augmented", codeName, SCHEDULED_TURN_MARKER_FILENAME);
|
|
5214
5261
|
const marker = { ts: Date.now(), task_id: taskId, ...target ? { target } : {} };
|
|
5215
5262
|
const tmp = `${file}.tmp`;
|
|
5216
|
-
|
|
5263
|
+
writeFileSync7(tmp, JSON.stringify(marker), "utf8");
|
|
5217
5264
|
renameSync(tmp, file);
|
|
5218
5265
|
} catch (err) {
|
|
5219
5266
|
log(`[scheduled-kanban] scheduled-turn marker write failed for '${codeName}': ${err.message}`);
|
|
@@ -5397,9 +5444,9 @@ async function processClaudeTaskResult(codeName, agentId, templateId, rawOutput,
|
|
|
5397
5444
|
// src/lib/manager/scheduler/execution.ts
|
|
5398
5445
|
import { createHash as createHash10 } from "crypto";
|
|
5399
5446
|
import { homedir as homedir8 } from "os";
|
|
5400
|
-
import { join as
|
|
5447
|
+
import { join as join18 } from "path";
|
|
5401
5448
|
function claudePidFilePath() {
|
|
5402
|
-
return
|
|
5449
|
+
return join18(homedir8(), ".augmented", "manager-claude-pids.json");
|
|
5403
5450
|
}
|
|
5404
5451
|
var inFlightClaudePids = /* @__PURE__ */ new Map();
|
|
5405
5452
|
function registerClaudeSpawn(record) {
|
|
@@ -5463,9 +5510,9 @@ async function syncAndCheckClaudeScheduler(agent, tasks, boardItems, refreshData
|
|
|
5463
5510
|
import { spawn, execSync } from "child_process";
|
|
5464
5511
|
import { createServer } from "net";
|
|
5465
5512
|
import { randomBytes } from "crypto";
|
|
5466
|
-
import { existsSync as
|
|
5513
|
+
import { existsSync as existsSync10, mkdirSync as mkdirSync6, readFileSync as readFileSync16 } from "fs";
|
|
5467
5514
|
import { homedir as homedir9, userInfo } from "os";
|
|
5468
|
-
import { join as
|
|
5515
|
+
import { join as join19 } from "path";
|
|
5469
5516
|
var OPENCODE_BIN = process.env["AGT_OPENCODE_BIN"]?.trim() || "opencode";
|
|
5470
5517
|
var sessions = /* @__PURE__ */ new Map();
|
|
5471
5518
|
var bridges = /* @__PURE__ */ new Map();
|
|
@@ -5473,7 +5520,7 @@ function opencodeTmuxSession(codeName) {
|
|
|
5473
5520
|
return `agt-oc-${codeName}`;
|
|
5474
5521
|
}
|
|
5475
5522
|
function opencodePaneLogPath(codeName) {
|
|
5476
|
-
return
|
|
5523
|
+
return join19(homedir9(), ".augmented", codeName, "opencode-serve.log");
|
|
5477
5524
|
}
|
|
5478
5525
|
function baseUrlFor(port) {
|
|
5479
5526
|
return `http://127.0.0.1:${port}`;
|
|
@@ -5540,7 +5587,7 @@ async function startOpencodeSession(config2) {
|
|
|
5540
5587
|
}
|
|
5541
5588
|
async function spawnServe(config2, session) {
|
|
5542
5589
|
const { codeName, projectDir, log: log2 } = config2;
|
|
5543
|
-
if (!
|
|
5590
|
+
if (!existsSync10(join19(projectDir, "opencode.json"))) {
|
|
5544
5591
|
log2(`[opencode-session] warning: no opencode.json in ${projectDir} for '${codeName}' (provisioning may not have run)`);
|
|
5545
5592
|
}
|
|
5546
5593
|
const tmuxSession = opencodeTmuxSession(codeName);
|
|
@@ -5550,7 +5597,7 @@ async function spawnServe(config2, session) {
|
|
|
5550
5597
|
execSync(`tmux kill-session -t ${tmuxSession} 2>/dev/null`, { stdio: "ignore" });
|
|
5551
5598
|
} catch {
|
|
5552
5599
|
}
|
|
5553
|
-
mkdirSync6(
|
|
5600
|
+
mkdirSync6(join19(homedir9(), ".augmented", codeName), { recursive: true });
|
|
5554
5601
|
const serveEnv = {
|
|
5555
5602
|
...process.env,
|
|
5556
5603
|
...stripUndefined(config2.serveEnv ?? {}),
|
|
@@ -5601,9 +5648,9 @@ function setupPaneLog(tmuxSession, codeName, log2) {
|
|
|
5601
5648
|
}
|
|
5602
5649
|
function readOpencodePaneLogTail(codeName, lines = 40) {
|
|
5603
5650
|
const logPath = opencodePaneLogPath(codeName);
|
|
5604
|
-
if (!
|
|
5651
|
+
if (!existsSync10(logPath)) return null;
|
|
5605
5652
|
try {
|
|
5606
|
-
const all =
|
|
5653
|
+
const all = readFileSync16(logPath, "utf8").split("\n");
|
|
5607
5654
|
return all.slice(-lines).join("\n");
|
|
5608
5655
|
} catch {
|
|
5609
5656
|
return null;
|
|
@@ -6696,24 +6743,24 @@ function partitionActionableByPoison(actionable, states, config2) {
|
|
|
6696
6743
|
}
|
|
6697
6744
|
|
|
6698
6745
|
// src/lib/restart-flags.ts
|
|
6699
|
-
import { existsSync as
|
|
6746
|
+
import { existsSync as existsSync11, mkdirSync as mkdirSync7, readdirSync as readdirSync4, readFileSync as readFileSync17, renameSync as renameSync2, rmSync as rmSync3, writeFileSync as writeFileSync8 } from "fs";
|
|
6700
6747
|
import { homedir as homedir10 } from "os";
|
|
6701
|
-
import { join as
|
|
6748
|
+
import { join as join20 } from "path";
|
|
6702
6749
|
import { randomUUID } from "crypto";
|
|
6703
6750
|
function restartFlagsDir() {
|
|
6704
|
-
return
|
|
6751
|
+
return join20(homedir10(), ".augmented", "restart-flags");
|
|
6705
6752
|
}
|
|
6706
6753
|
function flagPath(codeName) {
|
|
6707
|
-
return
|
|
6754
|
+
return join20(restartFlagsDir(), `${codeName}.flag`);
|
|
6708
6755
|
}
|
|
6709
6756
|
function readRestartFlags() {
|
|
6710
6757
|
const dir = restartFlagsDir();
|
|
6711
|
-
if (!
|
|
6758
|
+
if (!existsSync11(dir)) return [];
|
|
6712
6759
|
const out = [];
|
|
6713
6760
|
for (const entry of readdirSync4(dir)) {
|
|
6714
6761
|
if (!entry.endsWith(".flag")) continue;
|
|
6715
6762
|
try {
|
|
6716
|
-
const raw =
|
|
6763
|
+
const raw = readFileSync17(join20(dir, entry), "utf8");
|
|
6717
6764
|
const parsed = JSON.parse(raw);
|
|
6718
6765
|
if (typeof parsed.codeName !== "string" || parsed.codeName.length === 0) {
|
|
6719
6766
|
parsed.codeName = entry.replace(/\.flag$/, "");
|
|
@@ -6731,7 +6778,7 @@ function readRestartFlags() {
|
|
|
6731
6778
|
}
|
|
6732
6779
|
function deleteRestartFlag(codeName) {
|
|
6733
6780
|
const path = flagPath(codeName);
|
|
6734
|
-
if (
|
|
6781
|
+
if (existsSync11(path)) {
|
|
6735
6782
|
rmSync3(path, { force: true });
|
|
6736
6783
|
}
|
|
6737
6784
|
}
|
|
@@ -7965,7 +8012,7 @@ var runningChannelSecretHashes = /* @__PURE__ */ new Map();
|
|
|
7965
8012
|
var sessionLaunchManagedStructure = /* @__PURE__ */ new Map();
|
|
7966
8013
|
function projectMcpHash(_codeName, projectDir) {
|
|
7967
8014
|
try {
|
|
7968
|
-
const raw =
|
|
8015
|
+
const raw = readFileSync18(join21(projectDir, ".mcp.json"), "utf-8");
|
|
7969
8016
|
return createHash12("sha256").update(canonicalJson(JSON.parse(raw))).digest("hex");
|
|
7970
8017
|
} catch {
|
|
7971
8018
|
return null;
|
|
@@ -7973,7 +8020,7 @@ function projectMcpHash(_codeName, projectDir) {
|
|
|
7973
8020
|
}
|
|
7974
8021
|
function projectMcpKeys(_codeName, projectDir) {
|
|
7975
8022
|
try {
|
|
7976
|
-
const raw =
|
|
8023
|
+
const raw = readFileSync18(join21(projectDir, ".mcp.json"), "utf-8");
|
|
7977
8024
|
const parsed = JSON.parse(raw);
|
|
7978
8025
|
const servers = parsed.mcpServers;
|
|
7979
8026
|
if (!servers || typeof servers !== "object") return /* @__PURE__ */ new Set();
|
|
@@ -7991,7 +8038,7 @@ function seedSessionLaunchBaselines(codeName, projectDir) {
|
|
|
7991
8038
|
else runningMcpServerKeys.delete(codeName);
|
|
7992
8039
|
let launchStructure = null;
|
|
7993
8040
|
try {
|
|
7994
|
-
const raw =
|
|
8041
|
+
const raw = readFileSync18(join21(projectDir, ".mcp.json"), "utf-8");
|
|
7995
8042
|
launchStructure = managedMcpStructureHashFromFile(
|
|
7996
8043
|
JSON.parse(raw),
|
|
7997
8044
|
isManagedMcpServerKey
|
|
@@ -8091,7 +8138,7 @@ async function runAgentSessionToolBindProbes(agent, integrations, projectDir, op
|
|
|
8091
8138
|
if (result && result.rebindCandidates.length > 0 && hostFlagStore().getBoolean("session-tool-rebind")) {
|
|
8092
8139
|
let mcpJsonForRebind = null;
|
|
8093
8140
|
try {
|
|
8094
|
-
mcpJsonForRebind = JSON.parse(
|
|
8141
|
+
mcpJsonForRebind = JSON.parse(readFileSync18(join21(projectDir, ".mcp.json"), "utf-8"));
|
|
8095
8142
|
} catch {
|
|
8096
8143
|
mcpJsonForRebind = null;
|
|
8097
8144
|
}
|
|
@@ -8220,7 +8267,7 @@ function checkMcpConfigDriftAndScheduleRestart(codeName, projectDir) {
|
|
|
8220
8267
|
function projectChannelSecretHash(projectDir) {
|
|
8221
8268
|
try {
|
|
8222
8269
|
const entries = parseEnvIntegrations(
|
|
8223
|
-
|
|
8270
|
+
readFileSync18(join21(projectDir, ".env.integrations"), "utf-8")
|
|
8224
8271
|
);
|
|
8225
8272
|
return channelSecretValueHash(entries, CHANNEL_SECRET_ENV_KEYS);
|
|
8226
8273
|
} catch {
|
|
@@ -8285,6 +8332,7 @@ function clearAgentCaches(agentId, codeName) {
|
|
|
8285
8332
|
stopOpencodeSlackIngest(codeName, log);
|
|
8286
8333
|
agentFrameworkCache.delete(codeName);
|
|
8287
8334
|
kanbanBoardCache.delete(codeName);
|
|
8335
|
+
clearKanbanNudgeState(codeName);
|
|
8288
8336
|
notifyBoardCache.delete(codeName);
|
|
8289
8337
|
notifiedWaitingHumanIds.delete(codeName);
|
|
8290
8338
|
lastHarvestAt.delete(codeName);
|
|
@@ -8309,7 +8357,7 @@ var agentRestartTimezoneInputs = /* @__PURE__ */ new Map();
|
|
|
8309
8357
|
var lastVersionCheckAt = 0;
|
|
8310
8358
|
var VERSION_CHECK_INTERVAL_MS = 5 * 60 * 1e3;
|
|
8311
8359
|
var lastResponsivenessProbeAt = 0;
|
|
8312
|
-
var agtCliVersion = true ? "0.28.
|
|
8360
|
+
var agtCliVersion = true ? "0.28.323" : "dev";
|
|
8313
8361
|
function resolveBrewPath(execFileSync2) {
|
|
8314
8362
|
try {
|
|
8315
8363
|
const out = execFileSync2("which", ["brew"], { timeout: 5e3 }).toString().trim();
|
|
@@ -8322,7 +8370,7 @@ function resolveBrewPath(execFileSync2) {
|
|
|
8322
8370
|
"/usr/local/bin/brew"
|
|
8323
8371
|
];
|
|
8324
8372
|
for (const path of fallbacks) {
|
|
8325
|
-
if (
|
|
8373
|
+
if (existsSync12(path)) return path;
|
|
8326
8374
|
}
|
|
8327
8375
|
return null;
|
|
8328
8376
|
}
|
|
@@ -8332,7 +8380,7 @@ function claudeBinaryInstalled(execFileSync2) {
|
|
|
8332
8380
|
"/opt/homebrew/bin/claude",
|
|
8333
8381
|
"/usr/local/bin/claude"
|
|
8334
8382
|
];
|
|
8335
|
-
if (canonical.some((path) =>
|
|
8383
|
+
if (canonical.some((path) => existsSync12(path))) return true;
|
|
8336
8384
|
try {
|
|
8337
8385
|
execFileSync2("which", ["claude"], { timeout: 5e3 });
|
|
8338
8386
|
return true;
|
|
@@ -8487,8 +8535,8 @@ function claudeManagedSettingsPath() {
|
|
|
8487
8535
|
function ensureClaudeManagedSettings(path = claudeManagedSettingsPath()) {
|
|
8488
8536
|
try {
|
|
8489
8537
|
let settings = {};
|
|
8490
|
-
if (
|
|
8491
|
-
const raw =
|
|
8538
|
+
if (existsSync12(path)) {
|
|
8539
|
+
const raw = readFileSync18(path, "utf-8").trim();
|
|
8492
8540
|
if (raw) {
|
|
8493
8541
|
let parsed;
|
|
8494
8542
|
try {
|
|
@@ -8505,7 +8553,7 @@ function ensureClaudeManagedSettings(path = claudeManagedSettingsPath()) {
|
|
|
8505
8553
|
if (settings.channelsEnabled === true) return "ok";
|
|
8506
8554
|
settings.channelsEnabled = true;
|
|
8507
8555
|
mkdirSync8(dirname6(path), { recursive: true });
|
|
8508
|
-
|
|
8556
|
+
writeFileSync9(path, `${JSON.stringify(settings, null, 2)}
|
|
8509
8557
|
`);
|
|
8510
8558
|
log(`[managed-settings] set channelsEnabled:true in ${path} (ENG-5786 \u2014 unblocks Claude Code channels)`);
|
|
8511
8559
|
return "ok";
|
|
@@ -8550,7 +8598,7 @@ async function ensureFrameworkBinary(frameworkId) {
|
|
|
8550
8598
|
if (!process.env.PATH?.split(":").includes(brewBinDir)) {
|
|
8551
8599
|
process.env.PATH = `${brewBinDir}:${process.env.PATH ?? ""}`;
|
|
8552
8600
|
}
|
|
8553
|
-
if (
|
|
8601
|
+
if (existsSync12("/home/linuxbrew/.linuxbrew/bin/claude")) {
|
|
8554
8602
|
log("Claude Code installed successfully");
|
|
8555
8603
|
} else {
|
|
8556
8604
|
log("Claude Code install completed but binary not found at expected path \u2014 check brew logs");
|
|
@@ -8606,7 +8654,7 @@ ${r.stderr}`;
|
|
|
8606
8654
|
}
|
|
8607
8655
|
var UPDATE_CHECK_INTERVAL_MS = 5 * 60 * 1e3;
|
|
8608
8656
|
function selfUpdateAppliedMarkerPath() {
|
|
8609
|
-
return
|
|
8657
|
+
return join21(homedir11(), ".augmented", ".last-self-update-applied");
|
|
8610
8658
|
}
|
|
8611
8659
|
var selfUpdateUpToDateLogged = false;
|
|
8612
8660
|
var restartAfterUpgrade = false;
|
|
@@ -8630,7 +8678,7 @@ async function checkAndUpdateCli(opts) {
|
|
|
8630
8678
|
const isNpmGlobal = !isBrewFormula && resolvedPath.includes("node_modules");
|
|
8631
8679
|
if (!isBrewFormula && !isNpmGlobal) return "noop";
|
|
8632
8680
|
const { readFileSync: readF, writeFileSync: writeF } = await import("fs");
|
|
8633
|
-
const markerPath =
|
|
8681
|
+
const markerPath = join21(homedir11(), ".augmented", ".last-update-check");
|
|
8634
8682
|
if (!force) {
|
|
8635
8683
|
try {
|
|
8636
8684
|
const lastCheck = parseInt(readF(markerPath, "utf-8").trim(), 10);
|
|
@@ -8908,14 +8956,14 @@ async function checkClaudeAuth() {
|
|
|
8908
8956
|
}
|
|
8909
8957
|
var evalEmptyMcpConfigPath = null;
|
|
8910
8958
|
function ensureEvalEmptyMcpConfig() {
|
|
8911
|
-
if (evalEmptyMcpConfigPath &&
|
|
8912
|
-
const dir =
|
|
8959
|
+
if (evalEmptyMcpConfigPath && existsSync12(evalEmptyMcpConfigPath)) return evalEmptyMcpConfigPath;
|
|
8960
|
+
const dir = join21(homedir11(), ".augmented");
|
|
8913
8961
|
try {
|
|
8914
8962
|
mkdirSync8(dir, { recursive: true });
|
|
8915
8963
|
} catch {
|
|
8916
8964
|
}
|
|
8917
|
-
const p =
|
|
8918
|
-
|
|
8965
|
+
const p = join21(dir, ".eval-empty-mcp.json");
|
|
8966
|
+
writeFileSync9(p, JSON.stringify({ mcpServers: {} }));
|
|
8919
8967
|
evalEmptyMcpConfigPath = p;
|
|
8920
8968
|
return p;
|
|
8921
8969
|
}
|
|
@@ -9006,10 +9054,10 @@ function resolveConversationEvalBackend() {
|
|
|
9006
9054
|
return conversationEvalBackend;
|
|
9007
9055
|
}
|
|
9008
9056
|
function getStateFile() {
|
|
9009
|
-
return
|
|
9057
|
+
return join21(config?.configDir ?? join21(process.env["HOME"] ?? "/tmp", ".augmented"), "manager-state.json");
|
|
9010
9058
|
}
|
|
9011
9059
|
function channelHashCacheDir() {
|
|
9012
|
-
return config?.configDir ??
|
|
9060
|
+
return config?.configDir ?? join21(process.env["HOME"] ?? "/tmp", ".augmented");
|
|
9013
9061
|
}
|
|
9014
9062
|
function loadChannelHashCache2() {
|
|
9015
9063
|
loadChannelHashCache(agentState.knownChannelConfigHashes, channelHashCacheDir());
|
|
@@ -9061,7 +9109,7 @@ function removeDeliveryBaselineEntries(agentId) {
|
|
|
9061
9109
|
var _channelQuarantineStore = null;
|
|
9062
9110
|
function channelQuarantineStore() {
|
|
9063
9111
|
if (!_channelQuarantineStore) {
|
|
9064
|
-
const dir = config?.configDir ??
|
|
9112
|
+
const dir = config?.configDir ?? join21(process.env["HOME"] ?? "/tmp", ".augmented");
|
|
9065
9113
|
_channelQuarantineStore = new ChannelQuarantineStore(defaultQuarantinePath(dir));
|
|
9066
9114
|
}
|
|
9067
9115
|
return _channelQuarantineStore;
|
|
@@ -9069,7 +9117,7 @@ function channelQuarantineStore() {
|
|
|
9069
9117
|
var _hostFlagStore = null;
|
|
9070
9118
|
function hostFlagStore() {
|
|
9071
9119
|
if (!_hostFlagStore) {
|
|
9072
|
-
const dir = config?.configDir ??
|
|
9120
|
+
const dir = config?.configDir ?? join21(process.env["HOME"] ?? "/tmp", ".augmented");
|
|
9073
9121
|
_hostFlagStore = new HostFlagStore({ cachePath: defaultFlagsCachePath(dir), log });
|
|
9074
9122
|
}
|
|
9075
9123
|
return _hostFlagStore;
|
|
@@ -9136,13 +9184,13 @@ function parseSkillFrontmatter(content) {
|
|
|
9136
9184
|
return out;
|
|
9137
9185
|
}
|
|
9138
9186
|
async function refreshSkillsIndexInClaudeMd(configDir, codeName, log2) {
|
|
9139
|
-
const { readdirSync: readdirSync6, readFileSync: rfs, existsSync: ex, writeFileSync:
|
|
9140
|
-
const skillsDir =
|
|
9141
|
-
const claudeMdPath =
|
|
9187
|
+
const { readdirSync: readdirSync6, readFileSync: rfs, existsSync: ex, writeFileSync: writeFileSync10 } = await import("fs");
|
|
9188
|
+
const skillsDir = join21(configDir, codeName, "project", ".claude", "skills");
|
|
9189
|
+
const claudeMdPath = join21(configDir, codeName, "project", "CLAUDE.md");
|
|
9142
9190
|
if (!ex(skillsDir) || !ex(claudeMdPath)) return;
|
|
9143
9191
|
const entries = [];
|
|
9144
9192
|
for (const dir of readdirSync6(skillsDir).sort()) {
|
|
9145
|
-
const skillFile =
|
|
9193
|
+
const skillFile = join21(skillsDir, dir, "SKILL.md");
|
|
9146
9194
|
if (!ex(skillFile)) continue;
|
|
9147
9195
|
try {
|
|
9148
9196
|
const { name, description } = parseSkillFrontmatter(rfs(skillFile, "utf-8"));
|
|
@@ -9184,7 +9232,7 @@ ${SKILLS_INDEX_END}`;
|
|
|
9184
9232
|
next = current.trimEnd() + "\n\n" + section + "\n";
|
|
9185
9233
|
}
|
|
9186
9234
|
if (next !== current) {
|
|
9187
|
-
|
|
9235
|
+
writeFileSync10(claudeMdPath, next, "utf-8");
|
|
9188
9236
|
log2(`Refreshed skills index in CLAUDE.md for '${codeName}' (${entries.length} skills)`);
|
|
9189
9237
|
}
|
|
9190
9238
|
}
|
|
@@ -9205,7 +9253,7 @@ function flushRestartedAgentDiagnostics(hostId, codeNames) {
|
|
|
9205
9253
|
if (codeNames.length === 0) return;
|
|
9206
9254
|
void (async () => {
|
|
9207
9255
|
try {
|
|
9208
|
-
const { collectDiagnostics } = await import("../persistent-session-
|
|
9256
|
+
const { collectDiagnostics } = await import("../persistent-session-5FKI4NCL.js");
|
|
9209
9257
|
await api.post("/host/heartbeat", {
|
|
9210
9258
|
host_id: hostId,
|
|
9211
9259
|
agent_diagnostics: collectDiagnostics(codeNames)
|
|
@@ -9304,7 +9352,7 @@ async function pollCycle() {
|
|
|
9304
9352
|
}
|
|
9305
9353
|
try {
|
|
9306
9354
|
const { detectHostSecurity } = await import("../host-security-6PDFG7F5.js");
|
|
9307
|
-
const { collectDiagnostics } = await import("../persistent-session-
|
|
9355
|
+
const { collectDiagnostics } = await import("../persistent-session-5FKI4NCL.js");
|
|
9308
9356
|
const diagCodeNames = [...agentState.persistentSessionAgents];
|
|
9309
9357
|
const agentDiagnostics = diagCodeNames.length > 0 ? collectDiagnostics(diagCodeNames) : void 0;
|
|
9310
9358
|
let tailscaleHostname;
|
|
@@ -9453,7 +9501,7 @@ async function pollCycle() {
|
|
|
9453
9501
|
const {
|
|
9454
9502
|
collectResponsivenessProbes,
|
|
9455
9503
|
getResponsivenessIntervalMs
|
|
9456
|
-
} = await import("../responsiveness-probe-
|
|
9504
|
+
} = await import("../responsiveness-probe-R42UJ5ZR.js");
|
|
9457
9505
|
const probeIntervalMs = getResponsivenessIntervalMs();
|
|
9458
9506
|
if (now - lastResponsivenessProbeAt > probeIntervalMs) {
|
|
9459
9507
|
const probeCodeNames = [...agentState.persistentSessionAgents];
|
|
@@ -9485,7 +9533,7 @@ async function pollCycle() {
|
|
|
9485
9533
|
collectResponsivenessProbes,
|
|
9486
9534
|
livePendingInboundOldestAgeSeconds,
|
|
9487
9535
|
parkPendingInbound
|
|
9488
|
-
} = await import("../responsiveness-probe-
|
|
9536
|
+
} = await import("../responsiveness-probe-R42UJ5ZR.js");
|
|
9489
9537
|
const { getProjectDir: wedgeProjectDir } = await import("../claude-scheduler-FATCLHDM.js");
|
|
9490
9538
|
const wedgeNow = /* @__PURE__ */ new Date();
|
|
9491
9539
|
const liveAgents = agentState.persistentSessionAgents;
|
|
@@ -9574,13 +9622,13 @@ async function pollCycle() {
|
|
|
9574
9622
|
);
|
|
9575
9623
|
if (hostFlagStore().getBoolean("wedge-transient-notice")) {
|
|
9576
9624
|
try {
|
|
9577
|
-
const paneTail =
|
|
9625
|
+
const paneTail = readFileSync18(paneLogPath(codeName), "utf8").slice(-65536);
|
|
9578
9626
|
const transient = detectTransientApiErrorInLog(paneTail);
|
|
9579
9627
|
if (transient) {
|
|
9580
|
-
const wedgeHome =
|
|
9581
|
-
if (
|
|
9628
|
+
const wedgeHome = join21(homedir11(), ".augmented", codeName);
|
|
9629
|
+
if (existsSync12(wedgeHome)) {
|
|
9582
9630
|
atomicWriteFileSync(
|
|
9583
|
-
|
|
9631
|
+
join21(wedgeHome, "watchdog-give-up.json"),
|
|
9584
9632
|
JSON.stringify({
|
|
9585
9633
|
gave_up_at: wedgeNow.toISOString(),
|
|
9586
9634
|
reason: "transient_overload"
|
|
@@ -9829,7 +9877,7 @@ async function pollCycle() {
|
|
|
9829
9877
|
} catch {
|
|
9830
9878
|
}
|
|
9831
9879
|
killAgentChannelProcesses(prev.codeName, { log });
|
|
9832
|
-
const agentDir =
|
|
9880
|
+
const agentDir = join21(adapter.getAgentDir(prev.codeName), "provision");
|
|
9833
9881
|
await cleanupAgentFiles(prev.codeName, agentDir);
|
|
9834
9882
|
clearAgentCaches(prev.agentId, prev.codeName);
|
|
9835
9883
|
}
|
|
@@ -9916,10 +9964,10 @@ async function pollCycle() {
|
|
|
9916
9964
|
// pending-inbound marker. Best-effort: a write failure is logged by
|
|
9917
9965
|
// the watchdog, never fails the poll cycle.
|
|
9918
9966
|
signalGiveUp: (codeName) => {
|
|
9919
|
-
const dir =
|
|
9920
|
-
if (!
|
|
9967
|
+
const dir = join21(homedir11(), ".augmented", codeName);
|
|
9968
|
+
if (!existsSync12(dir)) return;
|
|
9921
9969
|
atomicWriteFileSync(
|
|
9922
|
-
|
|
9970
|
+
join21(dir, "watchdog-give-up.json"),
|
|
9923
9971
|
JSON.stringify({ gave_up_at: (/* @__PURE__ */ new Date()).toISOString() })
|
|
9924
9972
|
);
|
|
9925
9973
|
}
|
|
@@ -10049,7 +10097,7 @@ async function processAgent(agent, agentStates) {
|
|
|
10049
10097
|
}
|
|
10050
10098
|
const now = (/* @__PURE__ */ new Date()).toISOString();
|
|
10051
10099
|
const adapter = resolveAgentFramework(agent.code_name);
|
|
10052
|
-
let agentDir =
|
|
10100
|
+
let agentDir = join21(adapter.getAgentDir(agent.code_name), "provision");
|
|
10053
10101
|
if (agent.status === "draft" || agent.status === "paused") {
|
|
10054
10102
|
if (previousKnownStatus !== agent.status) {
|
|
10055
10103
|
log(`Agent '${agent.code_name}' is ${agent.status}, skipping provisioning`);
|
|
@@ -10095,7 +10143,7 @@ async function processAgent(agent, agentStates) {
|
|
|
10095
10143
|
const residuals = {
|
|
10096
10144
|
gatewayRunning: false,
|
|
10097
10145
|
portAllocated: false,
|
|
10098
|
-
provisionDirExists:
|
|
10146
|
+
provisionDirExists: existsSync12(agentDir)
|
|
10099
10147
|
};
|
|
10100
10148
|
if (!hasRevokedResiduals(residuals)) {
|
|
10101
10149
|
agentStates.push({
|
|
@@ -10233,7 +10281,7 @@ async function processAgent(agent, agentStates) {
|
|
|
10233
10281
|
const frameworkId = refreshData.agent.framework ?? DEFAULT_FRAMEWORK;
|
|
10234
10282
|
agentFrameworkCache.set(agent.code_name, frameworkId);
|
|
10235
10283
|
const frameworkAdapter = getFramework(frameworkId);
|
|
10236
|
-
agentDir =
|
|
10284
|
+
agentDir = join21(frameworkAdapter.getAgentDir(agent.code_name), "provision");
|
|
10237
10285
|
cacheAgentDeliveryMetadata(agent.code_name, refreshData);
|
|
10238
10286
|
agentRestartTimezoneInputs.set(agent.code_name, {
|
|
10239
10287
|
agentTimezone: typeof refreshData.agent.timezone === "string" ? refreshData.agent.timezone : null,
|
|
@@ -10280,7 +10328,7 @@ async function processAgent(agent, agentStates) {
|
|
|
10280
10328
|
const changedFiles = [];
|
|
10281
10329
|
mkdirSync8(agentDir, { recursive: true });
|
|
10282
10330
|
for (const artifact of artifacts) {
|
|
10283
|
-
const filePath =
|
|
10331
|
+
const filePath = join21(agentDir, artifact.relativePath);
|
|
10284
10332
|
let existingHash;
|
|
10285
10333
|
let newHash;
|
|
10286
10334
|
let writeContent = artifact.content;
|
|
@@ -10299,8 +10347,8 @@ async function processAgent(agent, agentStates) {
|
|
|
10299
10347
|
};
|
|
10300
10348
|
newHash = sha256(stripDynamicSections(artifact.content));
|
|
10301
10349
|
try {
|
|
10302
|
-
const projectClaudeMd =
|
|
10303
|
-
const existing =
|
|
10350
|
+
const projectClaudeMd = join21(config.configDir, agent.code_name, "project", "CLAUDE.md");
|
|
10351
|
+
const existing = readFileSync18(projectClaudeMd, "utf-8");
|
|
10304
10352
|
existingHash = sha256(stripDynamicSections(existing));
|
|
10305
10353
|
} catch {
|
|
10306
10354
|
existingHash = null;
|
|
@@ -10318,7 +10366,7 @@ async function processAgent(agent, agentStates) {
|
|
|
10318
10366
|
const generatorKeys = Object.keys(generatorServers);
|
|
10319
10367
|
let existingRaw = "";
|
|
10320
10368
|
try {
|
|
10321
|
-
existingRaw =
|
|
10369
|
+
existingRaw = readFileSync18(filePath, "utf-8");
|
|
10322
10370
|
} catch {
|
|
10323
10371
|
}
|
|
10324
10372
|
const existingServers = parseMcp(existingRaw);
|
|
@@ -10340,26 +10388,26 @@ async function processAgent(agent, agentStates) {
|
|
|
10340
10388
|
}
|
|
10341
10389
|
}
|
|
10342
10390
|
if (changedFiles.length > 0) {
|
|
10343
|
-
const isFirst = !
|
|
10391
|
+
const isFirst = !existsSync12(join21(agentDir, "CHARTER.md"));
|
|
10344
10392
|
const verb = isFirst ? "Provisioning" : "Updating";
|
|
10345
10393
|
const fileNames = changedFiles.map((f) => f.relativePath).join(", ");
|
|
10346
10394
|
log(`${verb} '${agent.code_name}': ${fileNames}`);
|
|
10347
10395
|
for (const file of changedFiles) {
|
|
10348
|
-
const filePath =
|
|
10396
|
+
const filePath = join21(agentDir, file.relativePath);
|
|
10349
10397
|
mkdirSync8(dirname6(filePath), { recursive: true });
|
|
10350
10398
|
if (file.relativePath === ".mcp.json") {
|
|
10351
10399
|
safeWriteJsonAtomic(filePath, file.content, { mode: 384 });
|
|
10352
10400
|
} else {
|
|
10353
|
-
|
|
10401
|
+
writeFileSync9(filePath, file.content);
|
|
10354
10402
|
}
|
|
10355
10403
|
}
|
|
10356
10404
|
try {
|
|
10357
|
-
const provSkillsDir =
|
|
10358
|
-
if (
|
|
10405
|
+
const provSkillsDir = join21(agentDir, ".claude", "skills");
|
|
10406
|
+
if (existsSync12(provSkillsDir)) {
|
|
10359
10407
|
for (const folder of readdirSync5(provSkillsDir)) {
|
|
10360
10408
|
if (folder.startsWith("knowledge-")) {
|
|
10361
10409
|
try {
|
|
10362
|
-
rmSync4(
|
|
10410
|
+
rmSync4(join21(provSkillsDir, folder), { recursive: true });
|
|
10363
10411
|
} catch {
|
|
10364
10412
|
}
|
|
10365
10413
|
}
|
|
@@ -10372,7 +10420,7 @@ async function processAgent(agent, agentStates) {
|
|
|
10372
10420
|
const trackedFiles2 = frameworkAdapter.driftTrackedFiles();
|
|
10373
10421
|
const hashes = /* @__PURE__ */ new Map();
|
|
10374
10422
|
for (const file of trackedFiles2) {
|
|
10375
|
-
const h = hashFile(
|
|
10423
|
+
const h = hashFile(join21(agentDir, file));
|
|
10376
10424
|
if (h) hashes.set(file, h);
|
|
10377
10425
|
}
|
|
10378
10426
|
agentState.writtenHashes.set(agent.agent_id, hashes);
|
|
@@ -10390,14 +10438,14 @@ async function processAgent(agent, agentStates) {
|
|
|
10390
10438
|
}
|
|
10391
10439
|
if (Array.isArray(refreshData.workflows)) {
|
|
10392
10440
|
try {
|
|
10393
|
-
const provWorkflowsDir =
|
|
10394
|
-
if (
|
|
10441
|
+
const provWorkflowsDir = join21(agentDir, ".claude", "workflows");
|
|
10442
|
+
if (existsSync12(provWorkflowsDir)) {
|
|
10395
10443
|
const expected = new Set(refreshData.workflows.map((w) => `${w.name}.js`));
|
|
10396
10444
|
for (const file of readdirSync5(provWorkflowsDir)) {
|
|
10397
10445
|
if (!file.endsWith(".js")) continue;
|
|
10398
10446
|
if (expected.has(file)) continue;
|
|
10399
10447
|
try {
|
|
10400
|
-
rmSync4(
|
|
10448
|
+
rmSync4(join21(provWorkflowsDir, file));
|
|
10401
10449
|
} catch {
|
|
10402
10450
|
}
|
|
10403
10451
|
}
|
|
@@ -10454,10 +10502,10 @@ async function processAgent(agent, agentStates) {
|
|
|
10454
10502
|
}
|
|
10455
10503
|
let lastDriftCheckAt = now;
|
|
10456
10504
|
const written = agentState.writtenHashes.get(agent.agent_id);
|
|
10457
|
-
if (written &&
|
|
10505
|
+
if (written && existsSync12(agentDir)) {
|
|
10458
10506
|
const driftedFiles = [];
|
|
10459
10507
|
for (const [file, expectedHash] of written) {
|
|
10460
|
-
const localHash = hashFile(
|
|
10508
|
+
const localHash = hashFile(join21(agentDir, file));
|
|
10461
10509
|
if (localHash && localHash !== expectedHash) {
|
|
10462
10510
|
driftedFiles.push(file);
|
|
10463
10511
|
}
|
|
@@ -10468,7 +10516,7 @@ async function processAgent(agent, agentStates) {
|
|
|
10468
10516
|
try {
|
|
10469
10517
|
const localHashes = {};
|
|
10470
10518
|
for (const file of driftedFiles) {
|
|
10471
|
-
localHashes[file] = hashFile(
|
|
10519
|
+
localHashes[file] = hashFile(join21(agentDir, file));
|
|
10472
10520
|
}
|
|
10473
10521
|
await api.post("/host/drift", {
|
|
10474
10522
|
agent_id: agent.agent_id,
|
|
@@ -10655,7 +10703,7 @@ async function processAgent(agent, agentStates) {
|
|
|
10655
10703
|
const addedChannels = [...restartDecision.added];
|
|
10656
10704
|
const writeDmNoticeMarkers = isChannelAddRestart ? () => {
|
|
10657
10705
|
try {
|
|
10658
|
-
const agentAugmentedDir =
|
|
10706
|
+
const agentAugmentedDir = join21(homedir11(), ".augmented", agent.code_name);
|
|
10659
10707
|
mkdirSync8(agentAugmentedDir, { recursive: true });
|
|
10660
10708
|
const markerJson = JSON.stringify({
|
|
10661
10709
|
version: 1,
|
|
@@ -10663,7 +10711,7 @@ async function processAgent(agent, agentStates) {
|
|
|
10663
10711
|
added: addedChannels
|
|
10664
10712
|
});
|
|
10665
10713
|
for (const file of ["slack-channel-add-restart.json", "telegram-channel-add-restart.json"]) {
|
|
10666
|
-
atomicWriteFileSync(
|
|
10714
|
+
atomicWriteFileSync(join21(agentAugmentedDir, file), markerJson);
|
|
10667
10715
|
}
|
|
10668
10716
|
} catch (err) {
|
|
10669
10717
|
log(`[hot-reload] channel-add DM-notice marker write failed for '${agent.code_name}' (non-fatal): ${err.message}`);
|
|
@@ -10852,24 +10900,24 @@ async function processAgent(agent, agentStates) {
|
|
|
10852
10900
|
if (agentSessionMode === "persistent" && (agentFrameworkCache.get(agent.code_name) ?? DEFAULT_FRAMEWORK) === "claude-code") {
|
|
10853
10901
|
try {
|
|
10854
10902
|
const agentProvisionDir = agentDir;
|
|
10855
|
-
const projectDir =
|
|
10903
|
+
const projectDir = join21(homedir11(), ".augmented", agent.code_name, "project");
|
|
10856
10904
|
mkdirSync8(agentProvisionDir, { recursive: true });
|
|
10857
10905
|
mkdirSync8(projectDir, { recursive: true });
|
|
10858
|
-
const provisionMcpPath =
|
|
10859
|
-
const projectMcpPath =
|
|
10906
|
+
const provisionMcpPath = join21(agentProvisionDir, ".mcp.json");
|
|
10907
|
+
const projectMcpPath = join21(projectDir, ".mcp.json");
|
|
10860
10908
|
let mcpConfig = { mcpServers: {} };
|
|
10861
10909
|
try {
|
|
10862
|
-
mcpConfig = JSON.parse(
|
|
10910
|
+
mcpConfig = JSON.parse(readFileSync18(provisionMcpPath, "utf-8"));
|
|
10863
10911
|
if (!mcpConfig.mcpServers) mcpConfig.mcpServers = {};
|
|
10864
10912
|
} catch {
|
|
10865
10913
|
}
|
|
10866
|
-
const localDirectChatChannel =
|
|
10914
|
+
const localDirectChatChannel = join21(homedir11(), ".augmented", "_mcp", "direct-chat-channel.js");
|
|
10867
10915
|
const directChatTeamSettings = refreshData.team?.settings;
|
|
10868
10916
|
const directChatTz = (() => {
|
|
10869
10917
|
const tz = directChatTeamSettings?.["timezone"];
|
|
10870
10918
|
return typeof tz === "string" && tz.trim() !== "" ? tz.trim() : void 0;
|
|
10871
10919
|
})();
|
|
10872
|
-
if (
|
|
10920
|
+
if (existsSync12(localDirectChatChannel)) {
|
|
10873
10921
|
const directChatEnv = {
|
|
10874
10922
|
AGT_HOST: requireHost(),
|
|
10875
10923
|
// ENG-5901 Track D: templated — the manager exports the real
|
|
@@ -10889,7 +10937,7 @@ async function processAgent(agent, agentStates) {
|
|
|
10889
10937
|
// ~/.augmented/<codeName>/.current-turn-initiator.json. Note getAgentDir
|
|
10890
10938
|
// returns the agent root (NOT the /provision subdir `agentDir` points at),
|
|
10891
10939
|
// so it byte-matches the broker readers' path.
|
|
10892
|
-
AGT_TURN_INITIATOR_FILE:
|
|
10940
|
+
AGT_TURN_INITIATOR_FILE: join21(
|
|
10893
10941
|
frameworkAdapter.getAgentDir(agent.code_name),
|
|
10894
10942
|
".current-turn-initiator.json"
|
|
10895
10943
|
)
|
|
@@ -10909,8 +10957,8 @@ async function processAgent(agent, agentStates) {
|
|
|
10909
10957
|
log(`Channel credentials written for '${agent.code_name}/direct-chat'`);
|
|
10910
10958
|
}
|
|
10911
10959
|
}
|
|
10912
|
-
const staleChannelsPath =
|
|
10913
|
-
if (
|
|
10960
|
+
const staleChannelsPath = join21(projectDir, ".mcp-channels.json");
|
|
10961
|
+
if (existsSync12(staleChannelsPath)) {
|
|
10914
10962
|
try {
|
|
10915
10963
|
rmSync4(staleChannelsPath, { force: true });
|
|
10916
10964
|
} catch {
|
|
@@ -10999,7 +11047,7 @@ async function processAgent(agent, agentStates) {
|
|
|
10999
11047
|
}
|
|
11000
11048
|
if (hostFlagStore().getBoolean("connectivity-probe")) {
|
|
11001
11049
|
try {
|
|
11002
|
-
const probeProjectDir =
|
|
11050
|
+
const probeProjectDir = join21(homedir11(), ".augmented", agent.code_name, "project");
|
|
11003
11051
|
await runAgentConnectivityProbes(agent, integrations, probeProjectDir);
|
|
11004
11052
|
} catch (err) {
|
|
11005
11053
|
log(`Connectivity probe failed for '${agent.code_name}': ${err.message}`);
|
|
@@ -11010,7 +11058,7 @@ async function processAgent(agent, agentStates) {
|
|
|
11010
11058
|
const forceDue = attemptsLeft > 0;
|
|
11011
11059
|
let probeRan = false;
|
|
11012
11060
|
try {
|
|
11013
|
-
const probeProjectDir =
|
|
11061
|
+
const probeProjectDir = join21(homedir11(), ".augmented", agent.code_name, "project");
|
|
11014
11062
|
probeRan = await runAgentSessionToolBindProbes(agent, integrations, probeProjectDir, { forceDue });
|
|
11015
11063
|
} catch (err) {
|
|
11016
11064
|
log(`Session-tool-bind probe failed for '${agent.code_name}': ${err.message}`);
|
|
@@ -11023,9 +11071,9 @@ async function processAgent(agent, agentStates) {
|
|
|
11023
11071
|
}
|
|
11024
11072
|
if (frameworkAdapter.removeMcpServer && frameworkAdapter.getMcpPath) {
|
|
11025
11073
|
const mcpPath = frameworkAdapter.getMcpPath(agent.code_name);
|
|
11026
|
-
if (mcpPath &&
|
|
11074
|
+
if (mcpPath && existsSync12(mcpPath)) {
|
|
11027
11075
|
try {
|
|
11028
|
-
const cfg = JSON.parse(
|
|
11076
|
+
const cfg = JSON.parse(readFileSync18(mcpPath, "utf-8"));
|
|
11029
11077
|
const expectedRemoteKeys = new Set(
|
|
11030
11078
|
integrations.map((i) => i.definition_id)
|
|
11031
11079
|
);
|
|
@@ -11050,11 +11098,11 @@ async function processAgent(agent, agentStates) {
|
|
|
11050
11098
|
recordConfigChurnEvent(agent.agent_id, agent.code_name, FLAP_CHANNEL_INTEGRATIONS, intMembership);
|
|
11051
11099
|
}
|
|
11052
11100
|
if (intHash !== prevIntHash) {
|
|
11053
|
-
const projectDir =
|
|
11054
|
-
const envIntPath =
|
|
11101
|
+
const projectDir = join21(homedir11(), ".augmented", agent.code_name, "project");
|
|
11102
|
+
const envIntPath = join21(projectDir, ".env.integrations");
|
|
11055
11103
|
let preWriteEnv;
|
|
11056
11104
|
try {
|
|
11057
|
-
preWriteEnv =
|
|
11105
|
+
preWriteEnv = readFileSync18(envIntPath, "utf-8");
|
|
11058
11106
|
} catch {
|
|
11059
11107
|
preWriteEnv = void 0;
|
|
11060
11108
|
}
|
|
@@ -11066,9 +11114,9 @@ async function processAgent(agent, agentStates) {
|
|
|
11066
11114
|
let rotationHandled = true;
|
|
11067
11115
|
if (fw === "claude-code" && isSessionHealthy(agent.code_name)) {
|
|
11068
11116
|
try {
|
|
11069
|
-
const projectMcpPath =
|
|
11070
|
-
const postWriteEnv =
|
|
11071
|
-
const mcpContent =
|
|
11117
|
+
const projectMcpPath = join21(projectDir, ".mcp.json");
|
|
11118
|
+
const postWriteEnv = readFileSync18(envIntPath, "utf-8");
|
|
11119
|
+
const mcpContent = readFileSync18(projectMcpPath, "utf-8");
|
|
11072
11120
|
const changedVars = diffEnvIntegrations(preWriteEnv, postWriteEnv);
|
|
11073
11121
|
const mcpJsonForReap = JSON.parse(mcpContent);
|
|
11074
11122
|
const affectedServerKeys = findMcpServersUsingVars(mcpJsonForReap, changedVars);
|
|
@@ -11170,8 +11218,8 @@ async function processAgent(agent, agentStates) {
|
|
|
11170
11218
|
const mcpPath = frameworkAdapter.getMcpPath(agent.code_name);
|
|
11171
11219
|
if (mcpPath) {
|
|
11172
11220
|
try {
|
|
11173
|
-
const { readFileSync:
|
|
11174
|
-
const mcpConfig = JSON.parse(
|
|
11221
|
+
const { readFileSync: readFileSync19 } = await import("fs");
|
|
11222
|
+
const mcpConfig = JSON.parse(readFileSync19(mcpPath, "utf-8"));
|
|
11175
11223
|
if (mcpConfig.mcpServers) {
|
|
11176
11224
|
for (const key of Object.keys(mcpConfig.mcpServers)) {
|
|
11177
11225
|
if (isManagedMcpServerKey(key) && !expectedServerIds.has(key)) {
|
|
@@ -11318,14 +11366,14 @@ async function processAgent(agent, agentStates) {
|
|
|
11318
11366
|
const frameworkId2 = frameworkAdapter.id;
|
|
11319
11367
|
const candidateSkillDirs = [
|
|
11320
11368
|
// Claude Code — framework runtime tree
|
|
11321
|
-
|
|
11369
|
+
join21(homedir12(), ".augmented", agent.code_name, "skills"),
|
|
11322
11370
|
// Claude Code — project tree
|
|
11323
|
-
|
|
11371
|
+
join21(homedir12(), ".augmented", agent.code_name, "project", ".claude", "skills"),
|
|
11324
11372
|
// Defensive: legacy provision-side path, not currently an
|
|
11325
11373
|
// install target but cheap to sweep.
|
|
11326
|
-
|
|
11374
|
+
join21(agentDir, ".claude", "skills")
|
|
11327
11375
|
];
|
|
11328
|
-
const existingDirs = candidateSkillDirs.filter((d) =>
|
|
11376
|
+
const existingDirs = candidateSkillDirs.filter((d) => existsSync12(d));
|
|
11329
11377
|
const discoveredEntries = /* @__PURE__ */ new Set();
|
|
11330
11378
|
for (const dir of existingDirs) {
|
|
11331
11379
|
try {
|
|
@@ -11339,8 +11387,8 @@ async function processAgent(agent, agentStates) {
|
|
|
11339
11387
|
}
|
|
11340
11388
|
const removeSkillFolder = (entry, reason) => {
|
|
11341
11389
|
for (const dir of existingDirs) {
|
|
11342
|
-
const p =
|
|
11343
|
-
if (
|
|
11390
|
+
const p = join21(dir, entry);
|
|
11391
|
+
if (existsSync12(p)) {
|
|
11344
11392
|
rmSync5(p, { recursive: true, force: true });
|
|
11345
11393
|
}
|
|
11346
11394
|
}
|
|
@@ -11359,7 +11407,7 @@ async function processAgent(agent, agentStates) {
|
|
|
11359
11407
|
const sharedSkillsPayload = refreshAny.shared_skills;
|
|
11360
11408
|
const desiredResolved = globalSkillsPayload !== void 0 || sharedSkillsPayload !== void 0;
|
|
11361
11409
|
const manifestPath = managedSkillManifestPath(
|
|
11362
|
-
|
|
11410
|
+
join21(homedir11(), ".augmented", agent.code_name)
|
|
11363
11411
|
);
|
|
11364
11412
|
const prevIds = /* @__PURE__ */ new Set([
|
|
11365
11413
|
...agentState.knownGlobalSkillIds.get(agent.agent_id) ?? /* @__PURE__ */ new Set(),
|
|
@@ -11379,15 +11427,15 @@ async function processAgent(agent, agentStates) {
|
|
|
11379
11427
|
}
|
|
11380
11428
|
if (plan.removes.length) {
|
|
11381
11429
|
const globalSkillDirs = [
|
|
11382
|
-
|
|
11383
|
-
|
|
11384
|
-
|
|
11430
|
+
join21(homedir11(), ".augmented", agent.code_name, "skills"),
|
|
11431
|
+
join21(homedir11(), ".augmented", agent.code_name, "project", ".claude", "skills"),
|
|
11432
|
+
join21(agentDir, ".claude", "skills")
|
|
11385
11433
|
];
|
|
11386
11434
|
for (const id of plan.removes) {
|
|
11387
11435
|
let prunedAny = false;
|
|
11388
11436
|
for (const dir of globalSkillDirs) {
|
|
11389
|
-
const p =
|
|
11390
|
-
if (
|
|
11437
|
+
const p = join21(dir, id);
|
|
11438
|
+
if (existsSync12(p) && existsSync12(join21(p, "SKILL.md"))) {
|
|
11391
11439
|
rmSync4(p, { recursive: true, force: true });
|
|
11392
11440
|
prunedAny = true;
|
|
11393
11441
|
}
|
|
@@ -11534,11 +11582,13 @@ async function processAgent(agent, agentStates) {
|
|
|
11534
11582
|
"completed",
|
|
11535
11583
|
"kanban inject suppressed \u2014 suspected poison card(s) (ENG-6171)"
|
|
11536
11584
|
);
|
|
11537
|
-
} else
|
|
11538
|
-
|
|
11539
|
-
openInjectedRunByCode.
|
|
11540
|
-
|
|
11541
|
-
|
|
11585
|
+
} else {
|
|
11586
|
+
clearKanbanNudgeState(agent.code_name);
|
|
11587
|
+
if (openInjectedRunByCode.has(agent.code_name)) {
|
|
11588
|
+
const openRunId = openInjectedRunByCode.get(agent.code_name);
|
|
11589
|
+
openInjectedRunByCode.delete(agent.code_name);
|
|
11590
|
+
void cancelKanbanNoticeOnDrain(agent.code_name, agent.agent_id, openRunId);
|
|
11591
|
+
}
|
|
11542
11592
|
}
|
|
11543
11593
|
}
|
|
11544
11594
|
}
|
|
@@ -11590,8 +11640,8 @@ async function processAgent(agent, agentStates) {
|
|
|
11590
11640
|
const sess = getSessionState(agent.code_name);
|
|
11591
11641
|
let mcpJsonParsed = null;
|
|
11592
11642
|
try {
|
|
11593
|
-
const mcpPath =
|
|
11594
|
-
mcpJsonParsed = JSON.parse(
|
|
11643
|
+
const mcpPath = join21(getProjectDir(agent.code_name), ".mcp.json");
|
|
11644
|
+
mcpJsonParsed = JSON.parse(readFileSync18(mcpPath, "utf-8"));
|
|
11595
11645
|
} catch {
|
|
11596
11646
|
}
|
|
11597
11647
|
reapMissingMcpSessions({
|
|
@@ -11916,10 +11966,10 @@ Retried to the limit after repeated stalls \u2014 needs a look.`).catch(() => {
|
|
|
11916
11966
|
}
|
|
11917
11967
|
}
|
|
11918
11968
|
const trackedFiles = frameworkAdapter.driftTrackedFiles();
|
|
11919
|
-
if (trackedFiles.length > 0 &&
|
|
11969
|
+
if (trackedFiles.length > 0 && existsSync12(agentDir)) {
|
|
11920
11970
|
const hashes = /* @__PURE__ */ new Map();
|
|
11921
11971
|
for (const file of trackedFiles) {
|
|
11922
|
-
const h = hashFile(
|
|
11972
|
+
const h = hashFile(join21(agentDir, file));
|
|
11923
11973
|
if (h) hashes.set(file, h);
|
|
11924
11974
|
}
|
|
11925
11975
|
agentState.writtenHashes.set(agent.agent_id, hashes);
|
|
@@ -11934,7 +11984,7 @@ Retried to the limit after repeated stalls \u2014 needs a look.`).catch(() => {
|
|
|
11934
11984
|
refreshData.agent.onboarding_state
|
|
11935
11985
|
);
|
|
11936
11986
|
const obStep = obState.step;
|
|
11937
|
-
const markerPath =
|
|
11987
|
+
const markerPath = join21(homedir11(), ".augmented", agent.code_name, "onboarding-drive.json");
|
|
11938
11988
|
const marker = readOnboardingDriveMarker(markerPath);
|
|
11939
11989
|
const decision = decideOnboardingDrive(obStep, marker, Date.now(), obState.generation ?? 0);
|
|
11940
11990
|
if (decision.clearMarker) {
|
|
@@ -12002,7 +12052,7 @@ async function ensureOpencodeRuntime(agent, refreshData, agentTimezone) {
|
|
|
12002
12052
|
return { decision: "healthy", spawnAttempted: false, sessionHealthyAfter: true };
|
|
12003
12053
|
}
|
|
12004
12054
|
stopOpencodeSlackIngest(codeName, log);
|
|
12005
|
-
const opencodeProjectDir =
|
|
12055
|
+
const opencodeProjectDir = join21(getFramework("opencode").getAgentDir(codeName), "project");
|
|
12006
12056
|
const openRouterRaw = refreshData.openrouter ?? null;
|
|
12007
12057
|
const serveEnv = {
|
|
12008
12058
|
AGT_HOST: requireHost(),
|
|
@@ -12042,8 +12092,8 @@ async function ensureOpencodeRuntime(agent, refreshData, agentTimezone) {
|
|
|
12042
12092
|
async function ensurePersistentSession(agent, tasks, boardItems, refreshData) {
|
|
12043
12093
|
const codeName = agent.code_name;
|
|
12044
12094
|
const projectDir = getProjectDir(codeName);
|
|
12045
|
-
const mcpConfigPath =
|
|
12046
|
-
const claudeMdPath =
|
|
12095
|
+
const mcpConfigPath = join21(projectDir, ".mcp.json");
|
|
12096
|
+
const claudeMdPath = join21(projectDir, "CLAUDE.md");
|
|
12047
12097
|
if (restartBreaker.isTripped(codeName)) {
|
|
12048
12098
|
const trip = restartBreaker.getTrip(codeName);
|
|
12049
12099
|
return {
|
|
@@ -12581,7 +12631,7 @@ async function handleRestartDoorbell(agentId, requestedAt, restartReason) {
|
|
|
12581
12631
|
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}`));
|
|
12582
12632
|
void (async () => {
|
|
12583
12633
|
try {
|
|
12584
|
-
const { collectDiagnostics } = await import("../persistent-session-
|
|
12634
|
+
const { collectDiagnostics } = await import("../persistent-session-5FKI4NCL.js");
|
|
12585
12635
|
await api.post("/host/heartbeat", {
|
|
12586
12636
|
host_id: hostId,
|
|
12587
12637
|
agent_diagnostics: collectDiagnostics([codeName])
|
|
@@ -12631,7 +12681,7 @@ async function respawnAgentAfterMcpStop(codeName, reason) {
|
|
|
12631
12681
|
}
|
|
12632
12682
|
try {
|
|
12633
12683
|
const hostId = await getHostId();
|
|
12634
|
-
const { collectDiagnostics } = await import("../persistent-session-
|
|
12684
|
+
const { collectDiagnostics } = await import("../persistent-session-5FKI4NCL.js");
|
|
12635
12685
|
await api.post("/host/heartbeat", {
|
|
12636
12686
|
host_id: hostId,
|
|
12637
12687
|
agent_diagnostics: collectDiagnostics([codeName])
|
|
@@ -12918,7 +12968,7 @@ async function processDirectChatMessage(agent, msg) {
|
|
|
12918
12968
|
try {
|
|
12919
12969
|
const doorbell = directChatDoorbellPath(agent.agentId, homedir11());
|
|
12920
12970
|
mkdirSync8(dirname6(doorbell), { recursive: true });
|
|
12921
|
-
|
|
12971
|
+
writeFileSync9(doorbell, String(Date.now()));
|
|
12922
12972
|
log(`[direct-chat] Doorbell rung for '${agent.codeName}' (msg=${msg.id}) \u2014 in-session MCP will pull via the cursor`);
|
|
12923
12973
|
return;
|
|
12924
12974
|
} catch (err) {
|
|
@@ -12950,6 +13000,21 @@ ${escapeXml(msg.content)}
|
|
|
12950
13000
|
}
|
|
12951
13001
|
var lastKanbanInjectAt = /* @__PURE__ */ new Map();
|
|
12952
13002
|
var kanbanNudgeStateByCode = /* @__PURE__ */ new Map();
|
|
13003
|
+
function loadKanbanNudgeStateFromDisk() {
|
|
13004
|
+
loadKanbanNudgeState(kanbanNudgeStateByCode, channelHashCacheDir());
|
|
13005
|
+
}
|
|
13006
|
+
function setKanbanNudgeState(codeName, state7) {
|
|
13007
|
+
kanbanNudgeStateByCode.set(codeName, state7);
|
|
13008
|
+
saveKanbanNudgeState(kanbanNudgeStateByCode, channelHashCacheDir());
|
|
13009
|
+
}
|
|
13010
|
+
function clearKanbanNudgeState(codeName) {
|
|
13011
|
+
if (!kanbanNudgeStateByCode.delete(codeName)) return;
|
|
13012
|
+
saveKanbanNudgeState(kanbanNudgeStateByCode, channelHashCacheDir());
|
|
13013
|
+
}
|
|
13014
|
+
function nextKanbanNudgeCount(codeName, signature) {
|
|
13015
|
+
const prev = kanbanNudgeStateByCode.get(codeName);
|
|
13016
|
+
return prev && prev.signature === signature ? (prev.nudgeCount ?? 1) + 1 : 1;
|
|
13017
|
+
}
|
|
12953
13018
|
var openInjectedRunByCode = /* @__PURE__ */ new Map();
|
|
12954
13019
|
function closeInjectedRunIfOpen(codeName, outcome, outcomeMessage) {
|
|
12955
13020
|
const runId = openInjectedRunByCode.get(codeName);
|
|
@@ -12982,6 +13047,12 @@ var KANBAN_HYBRID_FULL_CADENCE_MS = (() => {
|
|
|
12982
13047
|
if (Number.isFinite(parsed) && parsed > 0) return Math.max(parsed * 1e3, KANBAN_HYBRID_DEBOUNCE_MS);
|
|
12983
13048
|
return Math.max(5 * 6e4, KANBAN_HYBRID_DEBOUNCE_MS);
|
|
12984
13049
|
})();
|
|
13050
|
+
var KANBAN_HYBRID_MAX_CADENCE_MS = (() => {
|
|
13051
|
+
const raw = process.env["AGT_KANBAN_HYBRID_MAX_CADENCE_SECONDS"];
|
|
13052
|
+
const parsed = raw ? parseInt(raw, 10) : NaN;
|
|
13053
|
+
if (Number.isFinite(parsed) && parsed > 0) return Math.max(parsed * 1e3, KANBAN_HYBRID_FULL_CADENCE_MS);
|
|
13054
|
+
return Math.max(60 * 6e4, KANBAN_HYBRID_FULL_CADENCE_MS);
|
|
13055
|
+
})();
|
|
12985
13056
|
async function injectKanbanCheckViaDirectChat(codeName, agentId, actionableCount) {
|
|
12986
13057
|
if (isKanbanHybridDryRun()) {
|
|
12987
13058
|
log(
|
|
@@ -13007,7 +13078,7 @@ ${formatRunMarker(run_id)}` : KANBAN_CHECK_COMMAND;
|
|
|
13007
13078
|
try {
|
|
13008
13079
|
const doorbell = directChatDoorbellPath(agentId, homedir11());
|
|
13009
13080
|
mkdirSync8(dirname6(doorbell), { recursive: true });
|
|
13010
|
-
|
|
13081
|
+
writeFileSync9(doorbell, String(Date.now()));
|
|
13011
13082
|
} catch (err) {
|
|
13012
13083
|
log(`[kanban] doorbell ring failed for '${codeName}': ${err.message} (notice still queued)`);
|
|
13013
13084
|
}
|
|
@@ -13021,7 +13092,8 @@ async function maybeInjectKanbanCheck(codeName, agentId, actionableCount, signat
|
|
|
13021
13092
|
signature,
|
|
13022
13093
|
kanbanNudgeStateByCode.get(codeName),
|
|
13023
13094
|
Date.now(),
|
|
13024
|
-
KANBAN_HYBRID_FULL_CADENCE_MS
|
|
13095
|
+
KANBAN_HYBRID_FULL_CADENCE_MS,
|
|
13096
|
+
KANBAN_HYBRID_MAX_CADENCE_MS
|
|
13025
13097
|
)) {
|
|
13026
13098
|
return;
|
|
13027
13099
|
}
|
|
@@ -13033,7 +13105,11 @@ async function maybeInjectKanbanCheck(codeName, agentId, actionableCount, signat
|
|
|
13033
13105
|
if (hostFlagStore().getBoolean("kanban-doorbell")) {
|
|
13034
13106
|
const ok = await injectKanbanCheckViaDirectChat(codeName, agentId, actionableCount);
|
|
13035
13107
|
if (ok) {
|
|
13036
|
-
|
|
13108
|
+
setKanbanNudgeState(codeName, {
|
|
13109
|
+
signature,
|
|
13110
|
+
nudgedAt: Date.now(),
|
|
13111
|
+
nudgeCount: nextKanbanNudgeCount(codeName, signature)
|
|
13112
|
+
});
|
|
13037
13113
|
return;
|
|
13038
13114
|
}
|
|
13039
13115
|
log(`[manager-worker] kanban direct-chat enqueue failed for '${codeName}' \u2014 falling back to send-keys`);
|
|
@@ -13067,7 +13143,11 @@ ${formatRunMarker(run_id)}` : KANBAN_CHECK_COMMAND;
|
|
|
13067
13143
|
}
|
|
13068
13144
|
if (delivered) {
|
|
13069
13145
|
if (run_id) openInjectedRunByCode.set(codeName, run_id);
|
|
13070
|
-
|
|
13146
|
+
setKanbanNudgeState(codeName, {
|
|
13147
|
+
signature,
|
|
13148
|
+
nudgedAt: Date.now(),
|
|
13149
|
+
nudgeCount: nextKanbanNudgeCount(codeName, signature)
|
|
13150
|
+
});
|
|
13071
13151
|
log(
|
|
13072
13152
|
`[manager-worker] Injected kanban check for '${codeName}' (${actionableCount} actionable items)${run_id ? ` run_id=${run_id}` : ""}`
|
|
13073
13153
|
);
|
|
@@ -13099,7 +13179,7 @@ async function processClaudePairSessions(agents) {
|
|
|
13099
13179
|
killPairSession,
|
|
13100
13180
|
pairTmuxSession,
|
|
13101
13181
|
finalizeClaudePairOnboarding
|
|
13102
|
-
} = await import("../claude-pair-runtime-
|
|
13182
|
+
} = await import("../claude-pair-runtime-JSOSBAH3.js");
|
|
13103
13183
|
for (const pairId of pendingResp.cancelled_pair_ids ?? []) {
|
|
13104
13184
|
log(`[claude-pair] sweeping orphan tmux session for pair ${pairId.slice(0, 8)}`);
|
|
13105
13185
|
const killed = await killPairSession(pairTmuxSession(pairId));
|
|
@@ -13342,8 +13422,8 @@ function parseMemoryFile(raw, fallbackName) {
|
|
|
13342
13422
|
};
|
|
13343
13423
|
}
|
|
13344
13424
|
async function syncMemories(agent, configDir, log2) {
|
|
13345
|
-
const projectDir =
|
|
13346
|
-
const memoryDir =
|
|
13425
|
+
const projectDir = join21(configDir, agent.code_name, "project");
|
|
13426
|
+
const memoryDir = join21(projectDir, "memory");
|
|
13347
13427
|
const isFreshSync = pendingFreshMemorySync.has(agent.agent_id);
|
|
13348
13428
|
if (isFreshSync) {
|
|
13349
13429
|
log2(`[memory-sync] Fresh-sync requested for '${agent.code_name}' \u2014 pulling DB first`);
|
|
@@ -13354,14 +13434,14 @@ async function syncMemories(agent, configDir, log2) {
|
|
|
13354
13434
|
}
|
|
13355
13435
|
pendingFreshMemorySync.delete(agent.agent_id);
|
|
13356
13436
|
}
|
|
13357
|
-
if (
|
|
13437
|
+
if (existsSync12(memoryDir)) {
|
|
13358
13438
|
const prevHashes = memoryFileHashes.get(agent.agent_id) ?? /* @__PURE__ */ new Map();
|
|
13359
13439
|
const currentHashes = /* @__PURE__ */ new Map();
|
|
13360
13440
|
const changedMemories = [];
|
|
13361
13441
|
for (const file of readdirSync5(memoryDir)) {
|
|
13362
13442
|
if (!file.endsWith(".md")) continue;
|
|
13363
13443
|
try {
|
|
13364
|
-
const raw =
|
|
13444
|
+
const raw = readFileSync18(join21(memoryDir, file), "utf-8");
|
|
13365
13445
|
const fileHash = createHash12("sha256").update(raw).digest("hex").slice(0, 16);
|
|
13366
13446
|
currentHashes.set(file, fileHash);
|
|
13367
13447
|
if (prevHashes.get(file) === fileHash) continue;
|
|
@@ -13386,7 +13466,7 @@ async function syncMemories(agent, configDir, log2) {
|
|
|
13386
13466
|
} catch (err) {
|
|
13387
13467
|
for (const mem of changedMemories) {
|
|
13388
13468
|
for (const [file] of currentHashes) {
|
|
13389
|
-
const parsed = parseMemoryFile(
|
|
13469
|
+
const parsed = parseMemoryFile(readFileSync18(join21(memoryDir, file), "utf-8"), file.replace(/\.md$/, ""));
|
|
13390
13470
|
if (parsed?.name === mem.name) currentHashes.delete(file);
|
|
13391
13471
|
}
|
|
13392
13472
|
}
|
|
@@ -13399,7 +13479,7 @@ async function syncMemories(agent, configDir, log2) {
|
|
|
13399
13479
|
}
|
|
13400
13480
|
}
|
|
13401
13481
|
async function downloadMemories(agent, memoryDir, log2, { force }) {
|
|
13402
|
-
const localFiles =
|
|
13482
|
+
const localFiles = existsSync12(memoryDir) ? readdirSync5(memoryDir).filter((f) => f.endsWith(".md")).sort() : [];
|
|
13403
13483
|
const localListHash = createHash12("sha256").update(localFiles.join(",")).digest("hex").slice(0, 16);
|
|
13404
13484
|
const prevLocalHash = lastLocalFileHash.get(agent.agent_id);
|
|
13405
13485
|
const prevDownload = lastDownloadHash.get(agent.agent_id);
|
|
@@ -13421,7 +13501,7 @@ async function downloadMemories(agent, memoryDir, log2, { force }) {
|
|
|
13421
13501
|
const mem = dbMemories.memories[i];
|
|
13422
13502
|
const rawSlug = mem.name.toLowerCase().replace(/[^a-z0-9]+/g, "-").replace(/(^-|-$)/g, "").slice(0, 60);
|
|
13423
13503
|
const slug = rawSlug || `memory-${i}`;
|
|
13424
|
-
const filePath =
|
|
13504
|
+
const filePath = join21(memoryDir, `${slug}.md`);
|
|
13425
13505
|
const desired = `---
|
|
13426
13506
|
name: ${JSON.stringify(mem.name)}
|
|
13427
13507
|
type: ${mem.type}
|
|
@@ -13430,17 +13510,17 @@ description: ${JSON.stringify(mem.content.slice(0, 200))}
|
|
|
13430
13510
|
|
|
13431
13511
|
${mem.content}
|
|
13432
13512
|
`;
|
|
13433
|
-
if (
|
|
13513
|
+
if (existsSync12(filePath)) {
|
|
13434
13514
|
let existing = "";
|
|
13435
13515
|
try {
|
|
13436
|
-
existing =
|
|
13516
|
+
existing = readFileSync18(filePath, "utf-8");
|
|
13437
13517
|
} catch {
|
|
13438
13518
|
}
|
|
13439
13519
|
if (existing === desired) continue;
|
|
13440
|
-
|
|
13520
|
+
writeFileSync9(filePath, desired);
|
|
13441
13521
|
overwritten++;
|
|
13442
13522
|
} else {
|
|
13443
|
-
|
|
13523
|
+
writeFileSync9(filePath, desired);
|
|
13444
13524
|
written++;
|
|
13445
13525
|
}
|
|
13446
13526
|
}
|
|
@@ -13457,7 +13537,7 @@ ${mem.content}
|
|
|
13457
13537
|
}
|
|
13458
13538
|
}
|
|
13459
13539
|
async function cleanupAgentFiles(codeName, agentDir) {
|
|
13460
|
-
if (
|
|
13540
|
+
if (existsSync12(agentDir)) {
|
|
13461
13541
|
try {
|
|
13462
13542
|
rmSync4(agentDir, { recursive: true, force: true });
|
|
13463
13543
|
log(`Removed provision directory for '${codeName}'`);
|
|
@@ -13567,6 +13647,7 @@ function startPolling() {
|
|
|
13567
13647
|
void startCaffeinate();
|
|
13568
13648
|
loadChannelHashCache2();
|
|
13569
13649
|
loadSenderPolicyBaseline2();
|
|
13650
|
+
loadKanbanNudgeStateFromDisk();
|
|
13570
13651
|
hostFlagStore().init();
|
|
13571
13652
|
log(`Starting poll loop (interval=${config.intervalMs}ms, configDir=${config.configDir})`);
|
|
13572
13653
|
void killAllAgtTmuxSessions().catch(() => {
|
|
@@ -13692,8 +13773,8 @@ function startManager(opts) {
|
|
|
13692
13773
|
config = opts;
|
|
13693
13774
|
try {
|
|
13694
13775
|
const stateFile = getStateFile();
|
|
13695
|
-
if (
|
|
13696
|
-
const raw =
|
|
13776
|
+
if (existsSync12(stateFile)) {
|
|
13777
|
+
const raw = readFileSync18(stateFile, "utf-8");
|
|
13697
13778
|
const parsed = JSON.parse(raw);
|
|
13698
13779
|
if (Array.isArray(parsed.agents)) {
|
|
13699
13780
|
state6.agents = parsed.agents;
|
|
@@ -13720,7 +13801,7 @@ function startManager(opts) {
|
|
|
13720
13801
|
log(`[startup] state rehydration failed (continuing with empty state): ${err.message}`);
|
|
13721
13802
|
}
|
|
13722
13803
|
log(
|
|
13723
|
-
`[startup] worker pid=${process.pid} ppid=${process.ppid} node=${process.version} log=${
|
|
13804
|
+
`[startup] worker pid=${process.pid} ppid=${process.ppid} node=${process.version} log=${join21(homedir11(), ".augmented", "manager.log")}`
|
|
13724
13805
|
);
|
|
13725
13806
|
deployMcpAssets();
|
|
13726
13807
|
reapOrphanChannelMcps({ log });
|
|
@@ -13741,7 +13822,7 @@ async function reapOrphanedClaudePids() {
|
|
|
13741
13822
|
const looksLikeClaude = (pid) => {
|
|
13742
13823
|
if (process.platform !== "linux") return true;
|
|
13743
13824
|
try {
|
|
13744
|
-
const comm =
|
|
13825
|
+
const comm = readFileSync18(`/proc/${pid}/comm`, "utf-8").trim().toLowerCase();
|
|
13745
13826
|
return comm.includes("claude");
|
|
13746
13827
|
} catch {
|
|
13747
13828
|
return false;
|
|
@@ -13838,14 +13919,14 @@ function restartRunningChannelMcps(basenames) {
|
|
|
13838
13919
|
}
|
|
13839
13920
|
}
|
|
13840
13921
|
function deployMcpAssets() {
|
|
13841
|
-
const targetDir =
|
|
13922
|
+
const targetDir = join21(homedir11(), ".augmented", "_mcp");
|
|
13842
13923
|
mkdirSync8(targetDir, { recursive: true });
|
|
13843
13924
|
const moduleDir = dirname6(fileURLToPath(import.meta.url));
|
|
13844
13925
|
let mcpSourceDir = "";
|
|
13845
13926
|
let dir = moduleDir;
|
|
13846
13927
|
for (let i = 0; i < 6; i++) {
|
|
13847
|
-
const candidate =
|
|
13848
|
-
if (
|
|
13928
|
+
const candidate = join21(dir, "dist", "mcp");
|
|
13929
|
+
if (existsSync12(join21(candidate, "index.js"))) {
|
|
13849
13930
|
mcpSourceDir = candidate;
|
|
13850
13931
|
break;
|
|
13851
13932
|
}
|
|
@@ -13860,8 +13941,8 @@ function deployMcpAssets() {
|
|
|
13860
13941
|
const changedBasenames = [];
|
|
13861
13942
|
const fileHash = (p) => {
|
|
13862
13943
|
try {
|
|
13863
|
-
if (!
|
|
13864
|
-
return createHash12("sha256").update(
|
|
13944
|
+
if (!existsSync12(p)) return null;
|
|
13945
|
+
return createHash12("sha256").update(readFileSync18(p)).digest("hex");
|
|
13865
13946
|
} catch {
|
|
13866
13947
|
return null;
|
|
13867
13948
|
}
|
|
@@ -13925,9 +14006,9 @@ function deployMcpAssets() {
|
|
|
13925
14006
|
// needs restarting to pick up a token rotation.
|
|
13926
14007
|
"xero.js"
|
|
13927
14008
|
]) {
|
|
13928
|
-
const src =
|
|
13929
|
-
const dst =
|
|
13930
|
-
if (!
|
|
14009
|
+
const src = join21(mcpSourceDir, file);
|
|
14010
|
+
const dst = join21(targetDir, file);
|
|
14011
|
+
if (!existsSync12(src)) continue;
|
|
13931
14012
|
const before = fileHash(dst);
|
|
13932
14013
|
try {
|
|
13933
14014
|
copyFileSync(src, dst);
|
|
@@ -13944,23 +14025,23 @@ function deployMcpAssets() {
|
|
|
13944
14025
|
log(`[manager] Bundle(s) updated: ${changedBasenames.join(", ")} \u2014 signalling running instances to restart`);
|
|
13945
14026
|
restartRunningChannelMcps(changedBasenames);
|
|
13946
14027
|
}
|
|
13947
|
-
const localMcpPath =
|
|
14028
|
+
const localMcpPath = join21(targetDir, "index.js");
|
|
13948
14029
|
try {
|
|
13949
|
-
const agentsDir =
|
|
13950
|
-
if (
|
|
14030
|
+
const agentsDir = join21(homedir11(), ".augmented", "agents");
|
|
14031
|
+
if (existsSync12(agentsDir)) {
|
|
13951
14032
|
for (const entry of readdirSync5(agentsDir, { withFileTypes: true })) {
|
|
13952
14033
|
if (!entry.isDirectory()) continue;
|
|
13953
14034
|
for (const subdir of ["provision", "project"]) {
|
|
13954
|
-
const mcpJsonPath =
|
|
14035
|
+
const mcpJsonPath = join21(agentsDir, entry.name, subdir, ".mcp.json");
|
|
13955
14036
|
try {
|
|
13956
|
-
const raw =
|
|
14037
|
+
const raw = readFileSync18(mcpJsonPath, "utf-8");
|
|
13957
14038
|
if (!raw.includes("@integrity-labs/augmented-mcp")) continue;
|
|
13958
14039
|
const mcpConfig = JSON.parse(raw);
|
|
13959
14040
|
const augServer = mcpConfig.mcpServers?.["augmented"];
|
|
13960
14041
|
if (!augServer) continue;
|
|
13961
14042
|
augServer.command = "node";
|
|
13962
14043
|
augServer.args = [localMcpPath];
|
|
13963
|
-
|
|
14044
|
+
writeFileSync9(mcpJsonPath, JSON.stringify(mcpConfig, null, 2));
|
|
13964
14045
|
log(`[manager] Patched ${entry.name}/${subdir}/.mcp.json: npx \u2192 node`);
|
|
13965
14046
|
} catch {
|
|
13966
14047
|
}
|