@integrity-labs/agt-cli 0.28.528 → 0.28.529
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-7N55RDMG.js → chunk-MKSL2EQU.js} +38 -3
- package/dist/chunk-MKSL2EQU.js.map +1 -0
- package/dist/{chunk-PR3QSOLI.js → chunk-Q4XGKOHZ.js} +229 -9
- package/dist/chunk-Q4XGKOHZ.js.map +1 -0
- package/dist/{claude-pair-runtime-KQOPJSUJ.js → claude-pair-runtime-TC2TTMIJ.js} +2 -2
- package/dist/lib/manager-worker.js +336 -137
- package/dist/lib/manager-worker.js.map +1 -1
- package/dist/mcp/augmented-help-kb.js +21231 -0
- package/dist/mcp/direct-chat-channel.js +99 -7
- package/dist/mcp/origami.js +74 -0
- package/dist/mcp/slack-channel.js +99 -7
- package/dist/mcp/telegram-channel.js +99 -7
- package/dist/{persistent-session-KAHG73SM.js → persistent-session-T4IY7AJU.js} +2 -2
- package/dist/{responsiveness-probe-MKUXLX4F.js → responsiveness-probe-WYGR4B2F.js} +22 -2
- package/dist/{responsiveness-probe-MKUXLX4F.js.map → responsiveness-probe-WYGR4B2F.js.map} +1 -1
- package/package.json +3 -2
- package/dist/chunk-7N55RDMG.js.map +0 -1
- package/dist/chunk-PR3QSOLI.js.map +0 -1
- /package/dist/{claude-pair-runtime-KQOPJSUJ.js.map → claude-pair-runtime-TC2TTMIJ.js.map} +0 -0
- /package/dist/{persistent-session-KAHG73SM.js.map → persistent-session-T4IY7AJU.js.map} +0 -0
|
@@ -53,7 +53,7 @@ import {
|
|
|
53
53
|
safeWriteJsonAtomic,
|
|
54
54
|
setConfigHash,
|
|
55
55
|
tripClass
|
|
56
|
-
} from "../chunk-
|
|
56
|
+
} from "../chunk-MKSL2EQU.js";
|
|
57
57
|
import {
|
|
58
58
|
getProjectDir as getProjectDir2,
|
|
59
59
|
getReadyTasks,
|
|
@@ -67,6 +67,7 @@ import {
|
|
|
67
67
|
CLAUDE_MD_MAX_CHARS,
|
|
68
68
|
CONVERSATION_FAILURE_CATEGORIES,
|
|
69
69
|
DEFAULT_FRAMEWORK,
|
|
70
|
+
DEFAULT_NEIGHBOURHOOD_MS,
|
|
70
71
|
FLAGS_SCHEMA_VERSION,
|
|
71
72
|
FLAG_REGISTRY,
|
|
72
73
|
FORCED_UPDATE_HARD_DEADLINE_MS,
|
|
@@ -99,6 +100,7 @@ import {
|
|
|
99
100
|
estimateActiveTasksTokens,
|
|
100
101
|
execFilePromiseLong,
|
|
101
102
|
extractFrontmatter,
|
|
103
|
+
extractQualifyingTurns,
|
|
102
104
|
forcedUpdatePendingForMs,
|
|
103
105
|
formatActorId,
|
|
104
106
|
formatCursorAdvanceShortfall,
|
|
@@ -118,6 +120,7 @@ import {
|
|
|
118
120
|
isAgentIdle,
|
|
119
121
|
isAgentTimezoneOverrideExpired,
|
|
120
122
|
isBareAck,
|
|
123
|
+
isBucketQualified,
|
|
121
124
|
isConversationFailureCategory,
|
|
122
125
|
isEmptyTotals,
|
|
123
126
|
isForcedUpdatePastDeadline,
|
|
@@ -177,16 +180,16 @@ import {
|
|
|
177
180
|
toOpencodeModel,
|
|
178
181
|
transcriptActivityAgeSeconds,
|
|
179
182
|
writeEgressAllowlist
|
|
180
|
-
} from "../chunk-
|
|
183
|
+
} from "../chunk-Q4XGKOHZ.js";
|
|
181
184
|
import {
|
|
182
185
|
reapOrphanChannelMcps
|
|
183
186
|
} from "../chunk-XWVM4KPK.js";
|
|
184
187
|
|
|
185
188
|
// src/lib/manager-worker.ts
|
|
186
189
|
import { createHash as createHash16 } from "crypto";
|
|
187
|
-
import { readFileSync as readFileSync22, writeFileSync as writeFileSync13, mkdirSync as mkdirSync10, existsSync as existsSync12, rmSync as rmSync5, readdirSync as
|
|
190
|
+
import { readFileSync as readFileSync22, writeFileSync as writeFileSync13, mkdirSync as mkdirSync10, existsSync as existsSync12, rmSync as rmSync5, readdirSync as readdirSync8, statSync as statSync7, copyFileSync } from "fs";
|
|
188
191
|
import { execFileSync as syncExecFile } from "child_process";
|
|
189
|
-
import { join as
|
|
192
|
+
import { join as join29, dirname as dirname8, delimiter as pathDelimiter } from "path";
|
|
190
193
|
import { homedir as homedir12 } from "os";
|
|
191
194
|
import { fileURLToPath } from "url";
|
|
192
195
|
|
|
@@ -2427,7 +2430,7 @@ function accountEnforcementMarkerPath(codeName) {
|
|
|
2427
2430
|
return join10(homedir6(), ".augmented", codeName, ACCOUNT_ENFORCEMENT_MARKER_FILENAME);
|
|
2428
2431
|
}
|
|
2429
2432
|
function syncAccountEnforcementMarker(codeName, level, log2 = (m) => process.stderr.write(`${m}
|
|
2430
|
-
`)) {
|
|
2433
|
+
`), text) {
|
|
2431
2434
|
if (level !== "warn" && level !== "mute") {
|
|
2432
2435
|
clearAccountEnforcementMarker(codeName, log2);
|
|
2433
2436
|
return;
|
|
@@ -2437,7 +2440,7 @@ function syncAccountEnforcementMarker(codeName, level, log2 = (m) => process.std
|
|
|
2437
2440
|
const tempPath = `${path}.${process.pid}.tmp`;
|
|
2438
2441
|
try {
|
|
2439
2442
|
mkdirSync4(dir, { recursive: true });
|
|
2440
|
-
writeFileSync5(tempPath, serializeAccountEnforcementMarker(level), "utf-8");
|
|
2443
|
+
writeFileSync5(tempPath, serializeAccountEnforcementMarker(level, text), "utf-8");
|
|
2441
2444
|
renameSync2(tempPath, path);
|
|
2442
2445
|
} catch (err) {
|
|
2443
2446
|
try {
|
|
@@ -4327,14 +4330,14 @@ import { join as join17 } from "path";
|
|
|
4327
4330
|
function integrationSkillHashKey(agentId, skillId) {
|
|
4328
4331
|
return `plugin-skill:${agentId}:${skillId}`;
|
|
4329
4332
|
}
|
|
4330
|
-
function shouldWriteIntegrationSkill(
|
|
4331
|
-
return
|
|
4333
|
+
function shouldWriteIntegrationSkill(cache2, agentId, skillId, contentHash) {
|
|
4334
|
+
return cache2.get(integrationSkillHashKey(agentId, skillId)) !== contentHash;
|
|
4332
4335
|
}
|
|
4333
|
-
function rememberIntegrationSkill(
|
|
4334
|
-
|
|
4336
|
+
function rememberIntegrationSkill(cache2, agentId, skillId, contentHash) {
|
|
4337
|
+
cache2.set(integrationSkillHashKey(agentId, skillId), contentHash);
|
|
4335
4338
|
}
|
|
4336
|
-
function forgetIntegrationSkill(
|
|
4337
|
-
|
|
4339
|
+
function forgetIntegrationSkill(cache2, agentId, skillId) {
|
|
4340
|
+
cache2.delete(integrationSkillHashKey(agentId, skillId));
|
|
4338
4341
|
}
|
|
4339
4342
|
function removeIntegrationSkillFolder(opts) {
|
|
4340
4343
|
forgetIntegrationSkill(opts.cache, opts.agentId, opts.entry);
|
|
@@ -6122,15 +6125,174 @@ async function syncAndCheckClaudeScheduler(agent, tasks, boardItems, refreshData
|
|
|
6122
6125
|
}
|
|
6123
6126
|
}
|
|
6124
6127
|
|
|
6128
|
+
// src/lib/occupancy-gate.ts
|
|
6129
|
+
import { closeSync, openSync, readdirSync as readdirSync5, readSync, statSync as statSync5 } from "fs";
|
|
6130
|
+
import { join as join25 } from "path";
|
|
6131
|
+
var TAIL_BYTES = 256 * 1024;
|
|
6132
|
+
var MAX_RECORD_ALIGN_BYTES = 8 * 1024 * 1024;
|
|
6133
|
+
var GATE_MAX_BUCKET_AGE_MS = 30 * 6e4;
|
|
6134
|
+
var TRANSCRIPT_MTIME_WINDOW_MS4 = GATE_MAX_BUCKET_AGE_MS + DEFAULT_NEIGHBOURHOOD_MS + 6e4;
|
|
6135
|
+
var cache = /* @__PURE__ */ new Map();
|
|
6136
|
+
function readAlignedTail(path, tailBytes, maxAlignBytes) {
|
|
6137
|
+
let fd = null;
|
|
6138
|
+
try {
|
|
6139
|
+
const size = statSync5(path).size;
|
|
6140
|
+
if (size <= 0) return { content: "", complete: true };
|
|
6141
|
+
fd = openSync(path, "r");
|
|
6142
|
+
let readStart = Math.max(0, size - tailBytes);
|
|
6143
|
+
if (readStart > 0) {
|
|
6144
|
+
const scanFloor = Math.max(0, readStart - maxAlignBytes);
|
|
6145
|
+
const CHUNK = 64 * 1024;
|
|
6146
|
+
let pos = readStart;
|
|
6147
|
+
let boundary = -1;
|
|
6148
|
+
while (pos > scanFloor) {
|
|
6149
|
+
const from = Math.max(scanFloor, pos - CHUNK);
|
|
6150
|
+
const len2 = pos - from;
|
|
6151
|
+
const b = Buffer.allocUnsafe(len2);
|
|
6152
|
+
if (readSync(fd, b, 0, len2, from) !== len2) return null;
|
|
6153
|
+
const idx = b.lastIndexOf(10);
|
|
6154
|
+
if (idx !== -1) {
|
|
6155
|
+
boundary = from + idx + 1;
|
|
6156
|
+
break;
|
|
6157
|
+
}
|
|
6158
|
+
pos = from;
|
|
6159
|
+
}
|
|
6160
|
+
if (boundary !== -1) {
|
|
6161
|
+
readStart = boundary;
|
|
6162
|
+
} else if (scanFloor === 0) {
|
|
6163
|
+
readStart = 0;
|
|
6164
|
+
} else {
|
|
6165
|
+
return { content: "", complete: false };
|
|
6166
|
+
}
|
|
6167
|
+
}
|
|
6168
|
+
const len = size - readStart;
|
|
6169
|
+
const buf = Buffer.allocUnsafe(len);
|
|
6170
|
+
if (readSync(fd, buf, 0, len, readStart) !== len) return null;
|
|
6171
|
+
return { content: buf.toString("utf-8", 0, len), complete: true };
|
|
6172
|
+
} catch {
|
|
6173
|
+
return null;
|
|
6174
|
+
} finally {
|
|
6175
|
+
if (fd != null) {
|
|
6176
|
+
try {
|
|
6177
|
+
closeSync(fd);
|
|
6178
|
+
} catch {
|
|
6179
|
+
}
|
|
6180
|
+
}
|
|
6181
|
+
}
|
|
6182
|
+
}
|
|
6183
|
+
function isAbsentDirError(err) {
|
|
6184
|
+
const code = err.code;
|
|
6185
|
+
return code === "ENOENT" || code === "ENOTDIR";
|
|
6186
|
+
}
|
|
6187
|
+
function candidateTranscriptPaths(dir) {
|
|
6188
|
+
const paths = [];
|
|
6189
|
+
let top;
|
|
6190
|
+
try {
|
|
6191
|
+
top = readdirSync5(dir);
|
|
6192
|
+
} catch {
|
|
6193
|
+
return { paths, complete: false };
|
|
6194
|
+
}
|
|
6195
|
+
let complete = true;
|
|
6196
|
+
for (const name of top) {
|
|
6197
|
+
if (name.endsWith(".jsonl")) {
|
|
6198
|
+
paths.push(join25(dir, name));
|
|
6199
|
+
continue;
|
|
6200
|
+
}
|
|
6201
|
+
const subDir = join25(dir, name, "subagents");
|
|
6202
|
+
let subs;
|
|
6203
|
+
try {
|
|
6204
|
+
subs = readdirSync5(subDir);
|
|
6205
|
+
} catch (err) {
|
|
6206
|
+
if (!isAbsentDirError(err)) complete = false;
|
|
6207
|
+
continue;
|
|
6208
|
+
}
|
|
6209
|
+
for (const sub of subs) {
|
|
6210
|
+
if (sub.endsWith(".jsonl")) paths.push(join25(subDir, sub));
|
|
6211
|
+
}
|
|
6212
|
+
}
|
|
6213
|
+
return { paths, complete };
|
|
6214
|
+
}
|
|
6215
|
+
function collectQualifyingTurns(codeName, nowMs, opts = {}) {
|
|
6216
|
+
const dir = opts.transcriptDir ?? sessionTranscriptDir(getProjectDir(codeName));
|
|
6217
|
+
const tailBytes = opts.tailBytes ?? TAIL_BYTES;
|
|
6218
|
+
const maxAlignBytes = opts.maxAlignBytes ?? MAX_RECORD_ALIGN_BYTES;
|
|
6219
|
+
const sinceMs = nowMs - TRANSCRIPT_MTIME_WINDOW_MS4;
|
|
6220
|
+
const agentCache = cache.get(codeName) ?? /* @__PURE__ */ new Map();
|
|
6221
|
+
const nextCache = /* @__PURE__ */ new Map();
|
|
6222
|
+
const all = /* @__PURE__ */ new Set();
|
|
6223
|
+
let transcriptsRead = 0;
|
|
6224
|
+
const { paths, complete: scanComplete } = candidateTranscriptPaths(dir);
|
|
6225
|
+
let complete = scanComplete;
|
|
6226
|
+
for (const path of paths) {
|
|
6227
|
+
let st;
|
|
6228
|
+
try {
|
|
6229
|
+
st = statSync5(path);
|
|
6230
|
+
} catch (err) {
|
|
6231
|
+
if (!isAbsentDirError(err)) complete = false;
|
|
6232
|
+
continue;
|
|
6233
|
+
}
|
|
6234
|
+
if (!st.isFile()) continue;
|
|
6235
|
+
if (st.mtimeMs < sinceMs) continue;
|
|
6236
|
+
const seen = agentCache.get(path);
|
|
6237
|
+
if (seen && seen.mtimeMs === st.mtimeMs && seen.size === st.size) {
|
|
6238
|
+
transcriptsRead += 1;
|
|
6239
|
+
nextCache.set(path, seen);
|
|
6240
|
+
for (const t of seen.turns) all.add(t);
|
|
6241
|
+
continue;
|
|
6242
|
+
}
|
|
6243
|
+
const aligned = readAlignedTail(path, tailBytes, maxAlignBytes);
|
|
6244
|
+
if (aligned === null) {
|
|
6245
|
+
complete = false;
|
|
6246
|
+
continue;
|
|
6247
|
+
}
|
|
6248
|
+
if (!aligned.complete) {
|
|
6249
|
+
complete = false;
|
|
6250
|
+
continue;
|
|
6251
|
+
}
|
|
6252
|
+
const content = aligned.content;
|
|
6253
|
+
transcriptsRead += 1;
|
|
6254
|
+
const turns = extractQualifyingTurns(content, { startMs: sinceMs });
|
|
6255
|
+
nextCache.set(path, { mtimeMs: st.mtimeMs, size: st.size, turns });
|
|
6256
|
+
for (const t of turns) all.add(t);
|
|
6257
|
+
}
|
|
6258
|
+
cache.set(codeName, nextCache);
|
|
6259
|
+
return { turns: [...all].sort((a, b) => a - b), transcriptsRead, complete };
|
|
6260
|
+
}
|
|
6261
|
+
function qualifyBuckets(buckets, qualifying, mode, nowMs, neighbourhoodMs = DEFAULT_NEIGHBOURHOOD_MS) {
|
|
6262
|
+
const failOpen = !qualifying.complete;
|
|
6263
|
+
const kept = [];
|
|
6264
|
+
let qualified = 0;
|
|
6265
|
+
let unqualifiedDropped = 0;
|
|
6266
|
+
let unreadable = 0;
|
|
6267
|
+
for (const b of buckets) {
|
|
6268
|
+
const startMs = Date.parse(b.bucket);
|
|
6269
|
+
const parsed = Number.isFinite(startMs);
|
|
6270
|
+
const tooOld = parsed && nowMs - startMs > GATE_MAX_BUCKET_AGE_MS;
|
|
6271
|
+
if (failOpen || tooOld || !parsed) {
|
|
6272
|
+
if (failOpen || !parsed) unreadable += 1;
|
|
6273
|
+
kept.push(b);
|
|
6274
|
+
continue;
|
|
6275
|
+
}
|
|
6276
|
+
if (isBucketQualified(startMs, qualifying.turns, neighbourhoodMs)) {
|
|
6277
|
+
qualified += 1;
|
|
6278
|
+
kept.push(b);
|
|
6279
|
+
} else {
|
|
6280
|
+
unqualifiedDropped += 1;
|
|
6281
|
+
if (mode === "shadow") kept.push(b);
|
|
6282
|
+
}
|
|
6283
|
+
}
|
|
6284
|
+
return { kept, qualified, unqualifiedDropped, unreadable };
|
|
6285
|
+
}
|
|
6286
|
+
|
|
6125
6287
|
// src/lib/pane-occupancy-sampler.ts
|
|
6126
|
-
import { statSync as
|
|
6288
|
+
import { statSync as statSync6 } from "fs";
|
|
6127
6289
|
var SAMPLE_INTERVAL_MS = 1e4;
|
|
6128
6290
|
var IDLE_GAP_MS = 12e4;
|
|
6129
6291
|
var POST_IDLE_CREDIT_MS = 6e4;
|
|
6130
6292
|
var lastMtimeMs = /* @__PURE__ */ new Map();
|
|
6131
6293
|
function paneMtimeMs(codeName) {
|
|
6132
6294
|
try {
|
|
6133
|
-
return
|
|
6295
|
+
return statSync6(paneLogPath(codeName)).mtimeMs;
|
|
6134
6296
|
} catch {
|
|
6135
6297
|
return null;
|
|
6136
6298
|
}
|
|
@@ -7293,7 +7455,7 @@ async function fireOpencodeScheduledTask(agent, task) {
|
|
|
7293
7455
|
import { createHash as createHash15 } from "crypto";
|
|
7294
7456
|
import { existsSync as existsSync10, mkdirSync as mkdirSync7, readFileSync as readFileSync19, renameSync as renameSync4, unlinkSync as unlinkSync2, writeFileSync as writeFileSync10 } from "fs";
|
|
7295
7457
|
import { randomUUID } from "crypto";
|
|
7296
|
-
import { join as
|
|
7458
|
+
import { join as join26 } from "path";
|
|
7297
7459
|
|
|
7298
7460
|
// src/lib/telegram-ingest.ts
|
|
7299
7461
|
import https2 from "https";
|
|
@@ -7841,7 +8003,7 @@ function createFileOffsetStore(codeName, log2, currentBotId) {
|
|
|
7841
8003
|
let filePath;
|
|
7842
8004
|
try {
|
|
7843
8005
|
dir = getFramework("opencode").getAgentDir(codeName);
|
|
7844
|
-
filePath =
|
|
8006
|
+
filePath = join26(dir, "telegram-getupdates-offset-opencode.json");
|
|
7845
8007
|
} catch {
|
|
7846
8008
|
dir = null;
|
|
7847
8009
|
filePath = null;
|
|
@@ -8120,24 +8282,24 @@ function partitionActionableByPoison(actionable, states, config2) {
|
|
|
8120
8282
|
}
|
|
8121
8283
|
|
|
8122
8284
|
// src/lib/restart-flags.ts
|
|
8123
|
-
import { existsSync as existsSync11, mkdirSync as mkdirSync8, readdirSync as
|
|
8285
|
+
import { existsSync as existsSync11, mkdirSync as mkdirSync8, readdirSync as readdirSync6, readFileSync as readFileSync20, renameSync as renameSync5, rmSync as rmSync4, writeFileSync as writeFileSync11 } from "fs";
|
|
8124
8286
|
import { homedir as homedir11 } from "os";
|
|
8125
|
-
import { join as
|
|
8287
|
+
import { join as join27 } from "path";
|
|
8126
8288
|
import { randomUUID as randomUUID2 } from "crypto";
|
|
8127
8289
|
function restartFlagsDir() {
|
|
8128
|
-
return
|
|
8290
|
+
return join27(homedir11(), ".augmented", "restart-flags");
|
|
8129
8291
|
}
|
|
8130
8292
|
function flagPath(codeName) {
|
|
8131
|
-
return
|
|
8293
|
+
return join27(restartFlagsDir(), `${codeName}.flag`);
|
|
8132
8294
|
}
|
|
8133
8295
|
function readRestartFlags() {
|
|
8134
8296
|
const dir = restartFlagsDir();
|
|
8135
8297
|
if (!existsSync11(dir)) return [];
|
|
8136
8298
|
const out = [];
|
|
8137
|
-
for (const entry of
|
|
8299
|
+
for (const entry of readdirSync6(dir)) {
|
|
8138
8300
|
if (!entry.endsWith(".flag")) continue;
|
|
8139
8301
|
try {
|
|
8140
|
-
const raw = readFileSync20(
|
|
8302
|
+
const raw = readFileSync20(join27(dir, entry), "utf8");
|
|
8141
8303
|
const parsed = JSON.parse(raw);
|
|
8142
8304
|
if (typeof parsed.codeName !== "string" || parsed.codeName.length === 0) {
|
|
8143
8305
|
parsed.codeName = entry.replace(/\.flag$/, "");
|
|
@@ -8255,8 +8417,8 @@ async function sendError(flag, opts, text) {
|
|
|
8255
8417
|
}
|
|
8256
8418
|
|
|
8257
8419
|
// src/lib/restart-context.ts
|
|
8258
|
-
import { readdirSync as
|
|
8259
|
-
import { dirname as dirname7, join as
|
|
8420
|
+
import { readdirSync as readdirSync7, readFileSync as readFileSync21, writeFileSync as writeFileSync12, mkdirSync as mkdirSync9, unlinkSync as unlinkSync3 } from "fs";
|
|
8421
|
+
import { dirname as dirname7, join as join28 } from "path";
|
|
8260
8422
|
var SLACK_PENDING_INBOUND_DIRNAME = "slack-pending-inbound";
|
|
8261
8423
|
var SLACK_RESTART_CONTEXT_DIRNAME = "slack-restart-context";
|
|
8262
8424
|
var MAX_TOPIC_CHARS = 140;
|
|
@@ -8268,10 +8430,10 @@ function augmentedAgentDir(codeName) {
|
|
|
8268
8430
|
return dirname7(getProjectDir(codeName));
|
|
8269
8431
|
}
|
|
8270
8432
|
function slackPendingInboundDir(codeName) {
|
|
8271
|
-
return
|
|
8433
|
+
return join28(augmentedAgentDir(codeName), SLACK_PENDING_INBOUND_DIRNAME);
|
|
8272
8434
|
}
|
|
8273
8435
|
function slackRestartContextDir(codeName) {
|
|
8274
|
-
return
|
|
8436
|
+
return join28(augmentedAgentDir(codeName), SLACK_RESTART_CONTEXT_DIRNAME);
|
|
8275
8437
|
}
|
|
8276
8438
|
function sanitizeTopic(raw) {
|
|
8277
8439
|
const cleaned = raw.replace(/\s+/g, " ").trim().replace(/[<>]/g, " ").replace(/\s+/g, " ").trim();
|
|
@@ -8306,7 +8468,7 @@ function computeRestartContextHints(markers, allTurns, nowMs, reconstruct = reco
|
|
|
8306
8468
|
}
|
|
8307
8469
|
function safeReaddir(dir) {
|
|
8308
8470
|
try {
|
|
8309
|
-
return
|
|
8471
|
+
return readdirSync7(dir);
|
|
8310
8472
|
} catch {
|
|
8311
8473
|
return [];
|
|
8312
8474
|
}
|
|
@@ -8331,7 +8493,7 @@ function pruneHintsExcept(codeName, freshFilenames) {
|
|
|
8331
8493
|
if (!filename.endsWith(".json")) continue;
|
|
8332
8494
|
if (freshFilenames.has(filename)) continue;
|
|
8333
8495
|
try {
|
|
8334
|
-
unlinkSync3(
|
|
8496
|
+
unlinkSync3(join28(ctxDir, filename));
|
|
8335
8497
|
} catch {
|
|
8336
8498
|
}
|
|
8337
8499
|
}
|
|
@@ -8352,7 +8514,7 @@ function refreshSlackRestartContextHints(codeNames, opts = {}) {
|
|
|
8352
8514
|
}
|
|
8353
8515
|
const markers = [];
|
|
8354
8516
|
for (const filename of markerFilenames.slice(0, cap)) {
|
|
8355
|
-
const parsed = readStrandedMarker(
|
|
8517
|
+
const parsed = readStrandedMarker(join28(markerDir, filename));
|
|
8356
8518
|
if (parsed) markers.push({ filename, channel: parsed.channel, thread_ts: parsed.thread_ts });
|
|
8357
8519
|
}
|
|
8358
8520
|
if (markers.length === 0) {
|
|
@@ -8366,7 +8528,7 @@ function refreshSlackRestartContextHints(codeNames, opts = {}) {
|
|
|
8366
8528
|
const freshFilenames = /* @__PURE__ */ new Set();
|
|
8367
8529
|
for (const { filename, hint } of hints) {
|
|
8368
8530
|
try {
|
|
8369
|
-
writeHintFile(
|
|
8531
|
+
writeHintFile(join28(ctxDir, filename), ctxDir, hint);
|
|
8370
8532
|
freshFilenames.add(filename);
|
|
8371
8533
|
} catch (err) {
|
|
8372
8534
|
log2(`[restart-context] ${codeName}: hint write failed for ${filename}: ${err.message}`);
|
|
@@ -9646,7 +9808,7 @@ function performLazyDayRolloverReset(codeName, agentTimezone) {
|
|
|
9646
9808
|
}
|
|
9647
9809
|
function paneLogAgeSecondsFor(codeName) {
|
|
9648
9810
|
try {
|
|
9649
|
-
const mtimeMs =
|
|
9811
|
+
const mtimeMs = statSync7(paneLogPath(codeName)).mtimeMs;
|
|
9650
9812
|
return Math.max(0, Math.floor((Date.now() - mtimeMs) / 1e3));
|
|
9651
9813
|
} catch (err) {
|
|
9652
9814
|
if (err?.code === "ENOENT") return null;
|
|
@@ -9796,7 +9958,7 @@ var runningChannelSecretHashes = /* @__PURE__ */ new Map();
|
|
|
9796
9958
|
var sessionLaunchManagedStructure = /* @__PURE__ */ new Map();
|
|
9797
9959
|
function projectMcpHash(_codeName, projectDir) {
|
|
9798
9960
|
try {
|
|
9799
|
-
const raw = readFileSync22(
|
|
9961
|
+
const raw = readFileSync22(join29(projectDir, ".mcp.json"), "utf-8");
|
|
9800
9962
|
return createHash16("sha256").update(canonicalJson(JSON.parse(raw))).digest("hex");
|
|
9801
9963
|
} catch {
|
|
9802
9964
|
return null;
|
|
@@ -9804,7 +9966,7 @@ function projectMcpHash(_codeName, projectDir) {
|
|
|
9804
9966
|
}
|
|
9805
9967
|
function projectMcpKeys(_codeName, projectDir) {
|
|
9806
9968
|
try {
|
|
9807
|
-
const raw = readFileSync22(
|
|
9969
|
+
const raw = readFileSync22(join29(projectDir, ".mcp.json"), "utf-8");
|
|
9808
9970
|
const parsed = JSON.parse(raw);
|
|
9809
9971
|
const servers = parsed.mcpServers;
|
|
9810
9972
|
if (!servers || typeof servers !== "object") return /* @__PURE__ */ new Set();
|
|
@@ -9822,7 +9984,7 @@ function seedSessionLaunchBaselines(codeName, projectDir) {
|
|
|
9822
9984
|
else runningMcpServerKeys.delete(codeName);
|
|
9823
9985
|
let launchStructure = null;
|
|
9824
9986
|
try {
|
|
9825
|
-
const raw = readFileSync22(
|
|
9987
|
+
const raw = readFileSync22(join29(projectDir, ".mcp.json"), "utf-8");
|
|
9826
9988
|
launchStructure = managedMcpStructureHashFromFile(
|
|
9827
9989
|
JSON.parse(raw),
|
|
9828
9990
|
isManagedMcpServerKey
|
|
@@ -9932,7 +10094,7 @@ async function runAgentSessionToolBindProbes(agent, integrations, projectDir, op
|
|
|
9932
10094
|
if (result && result.rebindCandidates.length > 0 && hostFlagStore().getBoolean("session-tool-rebind")) {
|
|
9933
10095
|
let mcpJsonForRebind = null;
|
|
9934
10096
|
try {
|
|
9935
|
-
mcpJsonForRebind = JSON.parse(readFileSync22(
|
|
10097
|
+
mcpJsonForRebind = JSON.parse(readFileSync22(join29(projectDir, ".mcp.json"), "utf-8"));
|
|
9936
10098
|
} catch {
|
|
9937
10099
|
mcpJsonForRebind = null;
|
|
9938
10100
|
}
|
|
@@ -10076,7 +10238,7 @@ function checkMcpConfigDriftAndScheduleRestart(codeName, projectDir) {
|
|
|
10076
10238
|
function projectChannelSecretHash(projectDir) {
|
|
10077
10239
|
try {
|
|
10078
10240
|
const entries = parseEnvIntegrations(
|
|
10079
|
-
readFileSync22(
|
|
10241
|
+
readFileSync22(join29(projectDir, ".env.integrations"), "utf-8")
|
|
10080
10242
|
);
|
|
10081
10243
|
return channelSecretValueHash(entries, CHANNEL_SECRET_ENV_KEYS);
|
|
10082
10244
|
} catch {
|
|
@@ -10172,7 +10334,7 @@ var agentRestartTimezoneInputs = /* @__PURE__ */ new Map();
|
|
|
10172
10334
|
var lastVersionCheckAt = 0;
|
|
10173
10335
|
var VERSION_CHECK_INTERVAL_MS = 5 * 60 * 1e3;
|
|
10174
10336
|
var lastResponsivenessProbeAt = 0;
|
|
10175
|
-
var agtCliVersion = true ? "0.28.
|
|
10337
|
+
var agtCliVersion = true ? "0.28.529" : "dev";
|
|
10176
10338
|
function resolveBrewPath(execFileSync2) {
|
|
10177
10339
|
try {
|
|
10178
10340
|
const out = execFileSync2("which", ["brew"], { timeout: 5e3 }).toString().trim();
|
|
@@ -10560,7 +10722,7 @@ async function ensureOpencodeBinary() {
|
|
|
10560
10722
|
try {
|
|
10561
10723
|
const prefix = execFileSync2("npm", ["prefix", "-g"], { encoding: "utf-8", timeout: 1e4 }).trim();
|
|
10562
10724
|
if (prefix) {
|
|
10563
|
-
const npmBin =
|
|
10725
|
+
const npmBin = join29(prefix, "bin");
|
|
10564
10726
|
const current = (process.env.PATH ?? "").split(pathDelimiter);
|
|
10565
10727
|
if (!current.includes(npmBin)) {
|
|
10566
10728
|
process.env.PATH = [npmBin, ...current.filter(Boolean)].join(pathDelimiter);
|
|
@@ -10677,7 +10839,7 @@ ${r.stderr}`;
|
|
|
10677
10839
|
}
|
|
10678
10840
|
var UPDATE_CHECK_INTERVAL_MS = 5 * 60 * 1e3;
|
|
10679
10841
|
function selfUpdateAppliedMarkerPath() {
|
|
10680
|
-
return
|
|
10842
|
+
return join29(homedir12(), ".augmented", ".last-self-update-applied");
|
|
10681
10843
|
}
|
|
10682
10844
|
var selfUpdateUpToDateLogged = false;
|
|
10683
10845
|
var selfUpdatePinnedLogged = false;
|
|
@@ -10706,7 +10868,7 @@ async function checkAndUpdateCli(opts) {
|
|
|
10706
10868
|
const isNpmGlobal = !isBrewFormula && resolvedPath.includes("node_modules");
|
|
10707
10869
|
if (!isBrewFormula && !isNpmGlobal) return "noop";
|
|
10708
10870
|
const { readFileSync: readF, writeFileSync: writeF } = await import("fs");
|
|
10709
|
-
const markerPath =
|
|
10871
|
+
const markerPath = join29(homedir12(), ".augmented", ".last-update-check");
|
|
10710
10872
|
if (!force) {
|
|
10711
10873
|
try {
|
|
10712
10874
|
const lastCheck = parseInt(readF(markerPath, "utf-8").trim(), 10);
|
|
@@ -11066,12 +11228,12 @@ async function checkClaudeAuth() {
|
|
|
11066
11228
|
var evalEmptyMcpConfigPath = null;
|
|
11067
11229
|
function ensureEvalEmptyMcpConfig() {
|
|
11068
11230
|
if (evalEmptyMcpConfigPath && existsSync12(evalEmptyMcpConfigPath)) return evalEmptyMcpConfigPath;
|
|
11069
|
-
const dir =
|
|
11231
|
+
const dir = join29(homedir12(), ".augmented");
|
|
11070
11232
|
try {
|
|
11071
11233
|
mkdirSync10(dir, { recursive: true });
|
|
11072
11234
|
} catch {
|
|
11073
11235
|
}
|
|
11074
|
-
const p =
|
|
11236
|
+
const p = join29(dir, ".eval-empty-mcp.json");
|
|
11075
11237
|
writeFileSync13(p, JSON.stringify({ mcpServers: {} }));
|
|
11076
11238
|
evalEmptyMcpConfigPath = p;
|
|
11077
11239
|
return p;
|
|
@@ -11163,10 +11325,10 @@ function resolveConversationEvalBackend() {
|
|
|
11163
11325
|
return conversationEvalBackend;
|
|
11164
11326
|
}
|
|
11165
11327
|
function getStateFile() {
|
|
11166
|
-
return
|
|
11328
|
+
return join29(config?.configDir ?? join29(process.env["HOME"] ?? "/tmp", ".augmented"), "manager-state.json");
|
|
11167
11329
|
}
|
|
11168
11330
|
function channelHashCacheDir() {
|
|
11169
|
-
return config?.configDir ??
|
|
11331
|
+
return config?.configDir ?? join29(process.env["HOME"] ?? "/tmp", ".augmented");
|
|
11170
11332
|
}
|
|
11171
11333
|
function loadChannelHashCache2() {
|
|
11172
11334
|
loadChannelHashCache(agentState.knownChannelConfigHashes, channelHashCacheDir());
|
|
@@ -11220,7 +11382,7 @@ function removeDeliveryBaselineEntries(agentId) {
|
|
|
11220
11382
|
var _channelQuarantineStore = null;
|
|
11221
11383
|
function channelQuarantineStore() {
|
|
11222
11384
|
if (!_channelQuarantineStore) {
|
|
11223
|
-
const dir = config?.configDir ??
|
|
11385
|
+
const dir = config?.configDir ?? join29(process.env["HOME"] ?? "/tmp", ".augmented");
|
|
11224
11386
|
_channelQuarantineStore = new ChannelQuarantineStore(defaultQuarantinePath(dir));
|
|
11225
11387
|
}
|
|
11226
11388
|
return _channelQuarantineStore;
|
|
@@ -11237,7 +11399,7 @@ function claudeMdSizeFor(codeName) {
|
|
|
11237
11399
|
var _hostFlagStore = null;
|
|
11238
11400
|
function hostFlagStore() {
|
|
11239
11401
|
if (!_hostFlagStore) {
|
|
11240
|
-
const dir = config?.configDir ??
|
|
11402
|
+
const dir = config?.configDir ?? join29(process.env["HOME"] ?? "/tmp", ".augmented");
|
|
11241
11403
|
_hostFlagStore = new HostFlagStore({ cachePath: defaultFlagsCachePath(dir), log });
|
|
11242
11404
|
}
|
|
11243
11405
|
return _hostFlagStore;
|
|
@@ -11264,6 +11426,9 @@ function reportManagerModelCallError(source, err, modelId) {
|
|
|
11264
11426
|
function channelQuarantineMode() {
|
|
11265
11427
|
return hostFlagStore().getString("channel-quarantine-mode");
|
|
11266
11428
|
}
|
|
11429
|
+
function occupancyQualifierMode() {
|
|
11430
|
+
return hostFlagStore().getString("utilization-occupancy-qualifier") === "enforce" ? "enforce" : "shadow";
|
|
11431
|
+
}
|
|
11267
11432
|
function channelQuarantineDwellMs() {
|
|
11268
11433
|
const raw = parseInt(process.env["AGT_CHANNEL_QUARANTINE_DWELL_MS"] ?? "", 10);
|
|
11269
11434
|
return Number.isFinite(raw) && raw >= 0 ? raw : 18e4;
|
|
@@ -11307,13 +11472,13 @@ function parseSkillFrontmatter(content) {
|
|
|
11307
11472
|
return out;
|
|
11308
11473
|
}
|
|
11309
11474
|
async function refreshSkillsIndexInClaudeMd(configDir, codeName, log2) {
|
|
11310
|
-
const { readdirSync:
|
|
11311
|
-
const skillsDir =
|
|
11312
|
-
const claudeMdPath =
|
|
11475
|
+
const { readdirSync: readdirSync9, readFileSync: rfs, existsSync: ex, writeFileSync: writeFileSync14 } = await import("fs");
|
|
11476
|
+
const skillsDir = join29(configDir, codeName, "project", ".claude", "skills");
|
|
11477
|
+
const claudeMdPath = join29(configDir, codeName, "project", "CLAUDE.md");
|
|
11313
11478
|
if (!ex(skillsDir) || !ex(claudeMdPath)) return;
|
|
11314
11479
|
const entries = [];
|
|
11315
|
-
for (const dir of
|
|
11316
|
-
const skillFile =
|
|
11480
|
+
for (const dir of readdirSync9(skillsDir).sort()) {
|
|
11481
|
+
const skillFile = join29(skillsDir, dir, "SKILL.md");
|
|
11317
11482
|
if (!ex(skillFile)) continue;
|
|
11318
11483
|
try {
|
|
11319
11484
|
const { name, description } = parseSkillFrontmatter(rfs(skillFile, "utf-8"));
|
|
@@ -11380,7 +11545,7 @@ function flushRestartedAgentDiagnostics(hostId, codeNames) {
|
|
|
11380
11545
|
if (codeNames.length === 0) return;
|
|
11381
11546
|
void (async () => {
|
|
11382
11547
|
try {
|
|
11383
|
-
const { collectDiagnostics } = await import("../persistent-session-
|
|
11548
|
+
const { collectDiagnostics } = await import("../persistent-session-T4IY7AJU.js");
|
|
11384
11549
|
await api.post("/host/heartbeat", {
|
|
11385
11550
|
host_id: hostId,
|
|
11386
11551
|
agent_diagnostics: collectDiagnostics(codeNames, quarantineEntriesFor, claudeMdSizeFor)
|
|
@@ -11487,7 +11652,7 @@ async function pollCycle() {
|
|
|
11487
11652
|
}
|
|
11488
11653
|
try {
|
|
11489
11654
|
const { detectHostSecurity } = await import("../host-security-6PDFG7F5.js");
|
|
11490
|
-
const { collectDiagnostics } = await import("../persistent-session-
|
|
11655
|
+
const { collectDiagnostics } = await import("../persistent-session-T4IY7AJU.js");
|
|
11491
11656
|
const diagCodeNames = [...agentState.persistentSessionAgents];
|
|
11492
11657
|
const agentDiagnostics = diagCodeNames.length > 0 ? collectDiagnostics(diagCodeNames, quarantineEntriesFor, claudeMdSizeFor) : void 0;
|
|
11493
11658
|
let tailscaleHostname;
|
|
@@ -11601,8 +11766,9 @@ async function pollCycle() {
|
|
|
11601
11766
|
const {
|
|
11602
11767
|
collectResponsivenessProbes,
|
|
11603
11768
|
collectPanelessActivityProbes,
|
|
11604
|
-
getResponsivenessIntervalMs
|
|
11605
|
-
|
|
11769
|
+
getResponsivenessIntervalMs,
|
|
11770
|
+
occupancyQualificationClassifications
|
|
11771
|
+
} = await import("../responsiveness-probe-WYGR4B2F.js");
|
|
11606
11772
|
const probeIntervalMs = getResponsivenessIntervalMs();
|
|
11607
11773
|
if (now - lastResponsivenessProbeAt > probeIntervalMs) {
|
|
11608
11774
|
const probeCodeNames = [...agentState.persistentSessionAgents];
|
|
@@ -11617,27 +11783,48 @@ async function pollCycle() {
|
|
|
11617
11783
|
});
|
|
11618
11784
|
const drainedBuckets = /* @__PURE__ */ new Map();
|
|
11619
11785
|
const drainedCodeNames = /* @__PURE__ */ new Set();
|
|
11786
|
+
const qualifierMode = occupancyQualifierMode();
|
|
11620
11787
|
const takeBuckets = (codeName) => {
|
|
11621
|
-
if (drainedCodeNames.has(codeName)) return [];
|
|
11788
|
+
if (drainedCodeNames.has(codeName)) return { buckets: [], classifications: null };
|
|
11622
11789
|
drainedCodeNames.add(codeName);
|
|
11623
|
-
const
|
|
11624
|
-
|
|
11625
|
-
return buckets;
|
|
11790
|
+
const nowMs = Date.now();
|
|
11791
|
+
const raw = sharedBusyBuckets.drainClosed(codeName, nowMs);
|
|
11792
|
+
if (raw.length === 0) return { buckets: [], classifications: null };
|
|
11793
|
+
let q;
|
|
11794
|
+
try {
|
|
11795
|
+
q = qualifyBuckets(raw, collectQualifyingTurns(codeName, nowMs), qualifierMode, nowMs);
|
|
11796
|
+
} catch (err) {
|
|
11797
|
+
log(
|
|
11798
|
+
`[occupancy-gate] qualification failed for '${codeName}' \u2014 reporting ${raw.length} bucket(s) ungated: ${err.message}`
|
|
11799
|
+
);
|
|
11800
|
+
q = { kept: raw, qualified: 0, unqualifiedDropped: 0, unreadable: raw.length };
|
|
11801
|
+
}
|
|
11802
|
+
if (q.kept.length > 0) drainedBuckets.set(codeName, q.kept);
|
|
11803
|
+
return {
|
|
11804
|
+
buckets: q.kept,
|
|
11805
|
+
classifications: occupancyQualificationClassifications(q)
|
|
11806
|
+
};
|
|
11626
11807
|
};
|
|
11627
11808
|
const probes = [...collectResponsivenessProbes(probeCodeNames), ...paneless].map((p) => {
|
|
11628
11809
|
const giveUps = takeWatchdogGiveUpCount(p.code_name);
|
|
11629
11810
|
if (giveUps > 0) drainedGiveUps.set(p.code_name, giveUps);
|
|
11630
|
-
const busyBuckets = takeBuckets(p.code_name);
|
|
11811
|
+
const { buckets: busyBuckets, classifications } = takeBuckets(p.code_name);
|
|
11631
11812
|
return {
|
|
11632
11813
|
...p,
|
|
11633
11814
|
input_stuck_give_ups: giveUps,
|
|
11634
|
-
...busyBuckets.length > 0 ? { busy_buckets: busyBuckets } : {}
|
|
11815
|
+
...busyBuckets.length > 0 ? { busy_buckets: busyBuckets } : {},
|
|
11816
|
+
...classifications ? { occupancy_qualification_classifications: classifications } : {}
|
|
11635
11817
|
};
|
|
11636
11818
|
});
|
|
11637
11819
|
for (const codeName of probeCodeNames) {
|
|
11638
|
-
const buckets = takeBuckets(codeName);
|
|
11639
|
-
if (buckets.length > 0) {
|
|
11640
|
-
probes.push({
|
|
11820
|
+
const { buckets, classifications } = takeBuckets(codeName);
|
|
11821
|
+
if (buckets.length > 0 || classifications) {
|
|
11822
|
+
probes.push({
|
|
11823
|
+
code_name: codeName,
|
|
11824
|
+
input_stuck_give_ups: 0,
|
|
11825
|
+
...buckets.length > 0 ? { busy_buckets: buckets } : {},
|
|
11826
|
+
...classifications ? { occupancy_qualification_classifications: classifications } : {}
|
|
11827
|
+
});
|
|
11641
11828
|
}
|
|
11642
11829
|
}
|
|
11643
11830
|
if (probes.length > 0) {
|
|
@@ -11666,7 +11853,7 @@ async function pollCycle() {
|
|
|
11666
11853
|
collectResponsivenessProbes,
|
|
11667
11854
|
livePendingInboundOldestAgeSeconds,
|
|
11668
11855
|
parkPendingInbound
|
|
11669
|
-
} = await import("../responsiveness-probe-
|
|
11856
|
+
} = await import("../responsiveness-probe-WYGR4B2F.js");
|
|
11670
11857
|
const { getProjectDir: wedgeProjectDir } = await import("../scheduler-engine-NDP36U7O.js");
|
|
11671
11858
|
const wedgeNow = /* @__PURE__ */ new Date();
|
|
11672
11859
|
const liveAgents = agentState.persistentSessionAgents;
|
|
@@ -11758,10 +11945,10 @@ async function pollCycle() {
|
|
|
11758
11945
|
const paneTail = readFileSync22(paneLogPath(codeName), "utf8").slice(-65536);
|
|
11759
11946
|
const transient = detectTransientApiErrorInLog(paneTail);
|
|
11760
11947
|
if (transient) {
|
|
11761
|
-
const wedgeHome =
|
|
11948
|
+
const wedgeHome = join29(homedir12(), ".augmented", codeName);
|
|
11762
11949
|
if (existsSync12(wedgeHome)) {
|
|
11763
11950
|
atomicWriteFileSync(
|
|
11764
|
-
|
|
11951
|
+
join29(wedgeHome, "watchdog-give-up.json"),
|
|
11765
11952
|
JSON.stringify({
|
|
11766
11953
|
gave_up_at: wedgeNow.toISOString(),
|
|
11767
11954
|
reason: "transient_overload"
|
|
@@ -12032,7 +12219,7 @@ async function pollCycle() {
|
|
|
12032
12219
|
const adapter = resolveAgentFramework(prev.codeName);
|
|
12033
12220
|
stopAgentRuntime2(prev.codeName, "removed-from-host");
|
|
12034
12221
|
killAgentChannelProcesses(prev.codeName, { log });
|
|
12035
|
-
const agentDir =
|
|
12222
|
+
const agentDir = join29(adapter.getAgentDir(prev.codeName), "provision");
|
|
12036
12223
|
await cleanupAgentFiles(prev.codeName, agentDir);
|
|
12037
12224
|
clearAgentCaches(prev.agentId, prev.codeName);
|
|
12038
12225
|
}
|
|
@@ -12119,10 +12306,10 @@ async function pollCycle() {
|
|
|
12119
12306
|
// pending-inbound marker. Best-effort: a write failure is logged by
|
|
12120
12307
|
// the watchdog, never fails the poll cycle.
|
|
12121
12308
|
signalGiveUp: (codeName) => {
|
|
12122
|
-
const dir =
|
|
12309
|
+
const dir = join29(homedir12(), ".augmented", codeName);
|
|
12123
12310
|
if (!existsSync12(dir)) return;
|
|
12124
12311
|
atomicWriteFileSync(
|
|
12125
|
-
|
|
12312
|
+
join29(dir, "watchdog-give-up.json"),
|
|
12126
12313
|
JSON.stringify({ gave_up_at: (/* @__PURE__ */ new Date()).toISOString() })
|
|
12127
12314
|
);
|
|
12128
12315
|
}
|
|
@@ -12207,7 +12394,12 @@ async function getOrCacheRegisteredAgents(adapter, profile) {
|
|
|
12207
12394
|
async function processAgent(agent, agentStates) {
|
|
12208
12395
|
if (!config) return;
|
|
12209
12396
|
const renderIntegrationsSection = shouldRenderIntegrationsSection();
|
|
12210
|
-
syncAccountEnforcementMarker(
|
|
12397
|
+
syncAccountEnforcementMarker(
|
|
12398
|
+
agent.code_name,
|
|
12399
|
+
agent.enforcement ?? null,
|
|
12400
|
+
log,
|
|
12401
|
+
agent.enforcement_text ?? null
|
|
12402
|
+
);
|
|
12211
12403
|
const previousKnownStatus = agentState.knownStatuses.get(agent.agent_id);
|
|
12212
12404
|
agentState.agentDisplayNames.set(agent.code_name, agent.display_name);
|
|
12213
12405
|
agentState.codeNameToAgentId.set(agent.code_name, agent.agent_id);
|
|
@@ -12264,7 +12456,7 @@ async function processAgent(agent, agentStates) {
|
|
|
12264
12456
|
}
|
|
12265
12457
|
const now = (/* @__PURE__ */ new Date()).toISOString();
|
|
12266
12458
|
const adapter = resolveAgentFramework(agent.code_name);
|
|
12267
|
-
let agentDir =
|
|
12459
|
+
let agentDir = join29(adapter.getAgentDir(agent.code_name), "provision");
|
|
12268
12460
|
if (agent.status === "draft" || agent.status === "paused") {
|
|
12269
12461
|
if (previousKnownStatus !== agent.status) {
|
|
12270
12462
|
log(`Agent '${agent.code_name}' is ${agent.status}, skipping provisioning`);
|
|
@@ -12438,7 +12630,7 @@ async function processAgent(agent, agentStates) {
|
|
|
12438
12630
|
const frameworkId = refreshData.agent.framework ?? DEFAULT_FRAMEWORK;
|
|
12439
12631
|
agentFrameworkCache.set(agent.code_name, frameworkId);
|
|
12440
12632
|
const frameworkAdapter = getFramework(frameworkId);
|
|
12441
|
-
agentDir =
|
|
12633
|
+
agentDir = join29(frameworkAdapter.getAgentDir(agent.code_name), "provision");
|
|
12442
12634
|
cacheAgentDeliveryMetadata(agent.code_name, refreshData);
|
|
12443
12635
|
agentRestartTimezoneInputs.set(agent.code_name, {
|
|
12444
12636
|
agentTimezone: typeof refreshData.agent.timezone === "string" ? refreshData.agent.timezone : null,
|
|
@@ -12487,7 +12679,7 @@ async function processAgent(agent, agentStates) {
|
|
|
12487
12679
|
const changedFiles = [];
|
|
12488
12680
|
mkdirSync10(agentDir, { recursive: true });
|
|
12489
12681
|
for (const artifact of artifacts) {
|
|
12490
|
-
const filePath =
|
|
12682
|
+
const filePath = join29(agentDir, artifact.relativePath);
|
|
12491
12683
|
let existingHash;
|
|
12492
12684
|
let newHash;
|
|
12493
12685
|
let writeContent = artifact.content;
|
|
@@ -12506,7 +12698,7 @@ async function processAgent(agent, agentStates) {
|
|
|
12506
12698
|
};
|
|
12507
12699
|
newHash = sha256(stripDynamicSections(artifact.content));
|
|
12508
12700
|
try {
|
|
12509
|
-
const projectClaudeMd =
|
|
12701
|
+
const projectClaudeMd = join29(config.configDir, agent.code_name, "project", "CLAUDE.md");
|
|
12510
12702
|
const existing = readFileSync22(projectClaudeMd, "utf-8");
|
|
12511
12703
|
existingHash = sha256(stripDynamicSections(existing));
|
|
12512
12704
|
} catch {
|
|
@@ -12557,12 +12749,12 @@ async function processAgent(agent, agentStates) {
|
|
|
12557
12749
|
}
|
|
12558
12750
|
}
|
|
12559
12751
|
if (changedFiles.length > 0) {
|
|
12560
|
-
const isFirst = !existsSync12(
|
|
12752
|
+
const isFirst = !existsSync12(join29(agentDir, "CHARTER.md"));
|
|
12561
12753
|
const verb = isFirst ? "Provisioning" : "Updating";
|
|
12562
12754
|
const fileNames = changedFiles.map((f) => f.relativePath).join(", ");
|
|
12563
12755
|
log(`${verb} '${agent.code_name}': ${fileNames}`);
|
|
12564
12756
|
for (const file of changedFiles) {
|
|
12565
|
-
const filePath =
|
|
12757
|
+
const filePath = join29(agentDir, file.relativePath);
|
|
12566
12758
|
mkdirSync10(dirname8(filePath), { recursive: true });
|
|
12567
12759
|
if (file.relativePath === ".mcp.json") {
|
|
12568
12760
|
safeWriteJsonAtomic(filePath, file.content, { mode: 384 });
|
|
@@ -12571,12 +12763,12 @@ async function processAgent(agent, agentStates) {
|
|
|
12571
12763
|
}
|
|
12572
12764
|
}
|
|
12573
12765
|
try {
|
|
12574
|
-
const provSkillsDir =
|
|
12766
|
+
const provSkillsDir = join29(agentDir, ".claude", "skills");
|
|
12575
12767
|
if (existsSync12(provSkillsDir)) {
|
|
12576
|
-
for (const folder of
|
|
12768
|
+
for (const folder of readdirSync8(provSkillsDir)) {
|
|
12577
12769
|
if (folder.startsWith("knowledge-")) {
|
|
12578
12770
|
try {
|
|
12579
|
-
rmSync5(
|
|
12771
|
+
rmSync5(join29(provSkillsDir, folder), { recursive: true });
|
|
12580
12772
|
} catch {
|
|
12581
12773
|
}
|
|
12582
12774
|
}
|
|
@@ -12589,7 +12781,7 @@ async function processAgent(agent, agentStates) {
|
|
|
12589
12781
|
const trackedFiles2 = frameworkAdapter.driftTrackedFiles();
|
|
12590
12782
|
const hashes = /* @__PURE__ */ new Map();
|
|
12591
12783
|
for (const file of trackedFiles2) {
|
|
12592
|
-
const h = hashFile(
|
|
12784
|
+
const h = hashFile(join29(agentDir, file));
|
|
12593
12785
|
if (h) hashes.set(file, h);
|
|
12594
12786
|
}
|
|
12595
12787
|
agentState.writtenHashes.set(agent.agent_id, hashes);
|
|
@@ -12607,14 +12799,14 @@ async function processAgent(agent, agentStates) {
|
|
|
12607
12799
|
}
|
|
12608
12800
|
if (Array.isArray(refreshData.workflows)) {
|
|
12609
12801
|
try {
|
|
12610
|
-
const provWorkflowsDir =
|
|
12802
|
+
const provWorkflowsDir = join29(agentDir, ".claude", "workflows");
|
|
12611
12803
|
if (existsSync12(provWorkflowsDir)) {
|
|
12612
12804
|
const expected = new Set(refreshData.workflows.map((w) => `${w.name}.js`));
|
|
12613
|
-
for (const file of
|
|
12805
|
+
for (const file of readdirSync8(provWorkflowsDir)) {
|
|
12614
12806
|
if (!file.endsWith(".js")) continue;
|
|
12615
12807
|
if (expected.has(file)) continue;
|
|
12616
12808
|
try {
|
|
12617
|
-
rmSync5(
|
|
12809
|
+
rmSync5(join29(provWorkflowsDir, file));
|
|
12618
12810
|
} catch {
|
|
12619
12811
|
}
|
|
12620
12812
|
}
|
|
@@ -12696,7 +12888,7 @@ async function processAgent(agent, agentStates) {
|
|
|
12696
12888
|
if (written && existsSync12(agentDir)) {
|
|
12697
12889
|
const driftedFiles = [];
|
|
12698
12890
|
for (const [file, expectedHash] of written) {
|
|
12699
|
-
const localHash = hashFile(
|
|
12891
|
+
const localHash = hashFile(join29(agentDir, file));
|
|
12700
12892
|
if (localHash && localHash !== expectedHash) {
|
|
12701
12893
|
driftedFiles.push(file);
|
|
12702
12894
|
}
|
|
@@ -12707,7 +12899,7 @@ async function processAgent(agent, agentStates) {
|
|
|
12707
12899
|
try {
|
|
12708
12900
|
const localHashes = {};
|
|
12709
12901
|
for (const file of driftedFiles) {
|
|
12710
|
-
localHashes[file] = hashFile(
|
|
12902
|
+
localHashes[file] = hashFile(join29(agentDir, file));
|
|
12711
12903
|
}
|
|
12712
12904
|
await api.post("/host/drift", {
|
|
12713
12905
|
agent_id: agent.agent_id,
|
|
@@ -12909,7 +13101,7 @@ async function processAgent(agent, agentStates) {
|
|
|
12909
13101
|
const addedChannels = [...restartDecision.added];
|
|
12910
13102
|
const writeDmNoticeMarkers = isChannelAddRestart ? () => {
|
|
12911
13103
|
try {
|
|
12912
|
-
const agentAugmentedDir =
|
|
13104
|
+
const agentAugmentedDir = join29(homedir12(), ".augmented", agent.code_name);
|
|
12913
13105
|
mkdirSync10(agentAugmentedDir, { recursive: true });
|
|
12914
13106
|
const markerJson = JSON.stringify({
|
|
12915
13107
|
version: 1,
|
|
@@ -12917,7 +13109,7 @@ async function processAgent(agent, agentStates) {
|
|
|
12917
13109
|
added: addedChannels
|
|
12918
13110
|
});
|
|
12919
13111
|
for (const file of ["slack-channel-add-restart.json", "telegram-channel-add-restart.json"]) {
|
|
12920
|
-
atomicWriteFileSync(
|
|
13112
|
+
atomicWriteFileSync(join29(agentAugmentedDir, file), markerJson);
|
|
12921
13113
|
}
|
|
12922
13114
|
} catch (err) {
|
|
12923
13115
|
log(`[hot-reload] channel-add DM-notice marker write failed for '${agent.code_name}' (non-fatal): ${err.message}`);
|
|
@@ -13106,18 +13298,18 @@ async function processAgent(agent, agentStates) {
|
|
|
13106
13298
|
if (agentSessionMode === "persistent" && (agentFrameworkCache.get(agent.code_name) ?? DEFAULT_FRAMEWORK) === "claude-code") {
|
|
13107
13299
|
try {
|
|
13108
13300
|
const agentProvisionDir = agentDir;
|
|
13109
|
-
const projectDir =
|
|
13301
|
+
const projectDir = join29(homedir12(), ".augmented", agent.code_name, "project");
|
|
13110
13302
|
mkdirSync10(agentProvisionDir, { recursive: true });
|
|
13111
13303
|
mkdirSync10(projectDir, { recursive: true });
|
|
13112
|
-
const provisionMcpPath =
|
|
13113
|
-
const projectMcpPath =
|
|
13304
|
+
const provisionMcpPath = join29(agentProvisionDir, ".mcp.json");
|
|
13305
|
+
const projectMcpPath = join29(projectDir, ".mcp.json");
|
|
13114
13306
|
let mcpConfig = { mcpServers: {} };
|
|
13115
13307
|
try {
|
|
13116
13308
|
mcpConfig = JSON.parse(readFileSync22(provisionMcpPath, "utf-8"));
|
|
13117
13309
|
if (!mcpConfig.mcpServers) mcpConfig.mcpServers = {};
|
|
13118
13310
|
} catch {
|
|
13119
13311
|
}
|
|
13120
|
-
const localDirectChatChannel =
|
|
13312
|
+
const localDirectChatChannel = join29(homedir12(), ".augmented", "_mcp", "direct-chat-channel.js");
|
|
13121
13313
|
const directChatTeamSettings = refreshData.team?.settings;
|
|
13122
13314
|
const directChatTz = (() => {
|
|
13123
13315
|
const tz = directChatTeamSettings?.["timezone"];
|
|
@@ -13143,7 +13335,7 @@ async function processAgent(agent, agentStates) {
|
|
|
13143
13335
|
// ~/.augmented/<codeName>/.current-turn-initiator.json. Note getAgentDir
|
|
13144
13336
|
// returns the agent root (NOT the /provision subdir `agentDir` points at),
|
|
13145
13337
|
// so it byte-matches the broker readers' path.
|
|
13146
|
-
AGT_TURN_INITIATOR_FILE:
|
|
13338
|
+
AGT_TURN_INITIATOR_FILE: join29(
|
|
13147
13339
|
frameworkAdapter.getAgentDir(agent.code_name),
|
|
13148
13340
|
".current-turn-initiator.json"
|
|
13149
13341
|
)
|
|
@@ -13163,7 +13355,7 @@ async function processAgent(agent, agentStates) {
|
|
|
13163
13355
|
log(`Channel credentials written for '${agent.code_name}/direct-chat'`);
|
|
13164
13356
|
}
|
|
13165
13357
|
}
|
|
13166
|
-
const staleChannelsPath =
|
|
13358
|
+
const staleChannelsPath = join29(projectDir, ".mcp-channels.json");
|
|
13167
13359
|
if (existsSync12(staleChannelsPath)) {
|
|
13168
13360
|
try {
|
|
13169
13361
|
rmSync5(staleChannelsPath, { force: true });
|
|
@@ -13253,7 +13445,7 @@ async function processAgent(agent, agentStates) {
|
|
|
13253
13445
|
}
|
|
13254
13446
|
if (hostFlagStore().getBoolean("connectivity-probe")) {
|
|
13255
13447
|
try {
|
|
13256
|
-
const probeProjectDir =
|
|
13448
|
+
const probeProjectDir = join29(homedir12(), ".augmented", agent.code_name, "project");
|
|
13257
13449
|
let probeSet = integrations;
|
|
13258
13450
|
try {
|
|
13259
13451
|
const quarantined = await api.post("/host/agent-integrations/quarantined", { agent_id: agent.agent_id });
|
|
@@ -13299,7 +13491,7 @@ async function processAgent(agent, agentStates) {
|
|
|
13299
13491
|
const forceDue = attemptsLeft > 0;
|
|
13300
13492
|
let probeRan = false;
|
|
13301
13493
|
try {
|
|
13302
|
-
const probeProjectDir =
|
|
13494
|
+
const probeProjectDir = join29(homedir12(), ".augmented", agent.code_name, "project");
|
|
13303
13495
|
probeRan = await runAgentSessionToolBindProbes(agent, integrations, probeProjectDir, { forceDue });
|
|
13304
13496
|
} catch (err) {
|
|
13305
13497
|
log(`Session-tool-bind probe failed for '${agent.code_name}': ${err.message}`);
|
|
@@ -13376,8 +13568,8 @@ async function processAgent(agent, agentStates) {
|
|
|
13376
13568
|
const intHash = computeIntegrationsHash(integrations);
|
|
13377
13569
|
const prevIntHash = agentState.knownIntegrationHashes.get(agent.agent_id);
|
|
13378
13570
|
if (intHash !== prevIntHash) {
|
|
13379
|
-
const projectDir =
|
|
13380
|
-
const envIntPath =
|
|
13571
|
+
const projectDir = join29(homedir12(), ".augmented", agent.code_name, "project");
|
|
13572
|
+
const envIntPath = join29(projectDir, ".env.integrations");
|
|
13381
13573
|
let preWriteEnv;
|
|
13382
13574
|
try {
|
|
13383
13575
|
preWriteEnv = readFileSync22(envIntPath, "utf-8");
|
|
@@ -13399,7 +13591,7 @@ async function processAgent(agent, agentStates) {
|
|
|
13399
13591
|
}
|
|
13400
13592
|
if (fw === "claude-code" && isSessionHealthy(agent.code_name)) {
|
|
13401
13593
|
try {
|
|
13402
|
-
const projectMcpPath =
|
|
13594
|
+
const projectMcpPath = join29(projectDir, ".mcp.json");
|
|
13403
13595
|
const postWriteEnv = readFileSync22(envIntPath, "utf-8");
|
|
13404
13596
|
const mcpContent = readFileSync22(projectMcpPath, "utf-8");
|
|
13405
13597
|
const changedVars = diffEnvIntegrations(preWriteEnv, postWriteEnv);
|
|
@@ -13664,23 +13856,23 @@ async function processAgent(agent, agentStates) {
|
|
|
13664
13856
|
}
|
|
13665
13857
|
}
|
|
13666
13858
|
try {
|
|
13667
|
-
const { readdirSync:
|
|
13859
|
+
const { readdirSync: readdirSync9, rmSync: rmSync6 } = await import("fs");
|
|
13668
13860
|
const { homedir: homedir13 } = await import("os");
|
|
13669
13861
|
const frameworkId2 = frameworkAdapter.id;
|
|
13670
13862
|
const candidateSkillDirs = [
|
|
13671
13863
|
// Claude Code — framework runtime tree
|
|
13672
|
-
|
|
13864
|
+
join29(homedir13(), ".augmented", agent.code_name, "skills"),
|
|
13673
13865
|
// Claude Code — project tree
|
|
13674
|
-
|
|
13866
|
+
join29(homedir13(), ".augmented", agent.code_name, "project", ".claude", "skills"),
|
|
13675
13867
|
// Defensive: legacy provision-side path, not currently an
|
|
13676
13868
|
// install target but cheap to sweep.
|
|
13677
|
-
|
|
13869
|
+
join29(agentDir, ".claude", "skills")
|
|
13678
13870
|
];
|
|
13679
13871
|
const existingDirs = candidateSkillDirs.filter((d) => existsSync12(d));
|
|
13680
13872
|
const discoveredEntries = /* @__PURE__ */ new Set();
|
|
13681
13873
|
for (const dir of existingDirs) {
|
|
13682
13874
|
try {
|
|
13683
|
-
for (const entry of
|
|
13875
|
+
for (const entry of readdirSync9(dir)) {
|
|
13684
13876
|
if (entry.startsWith("plugin-") || entry.startsWith("integration-")) {
|
|
13685
13877
|
discoveredEntries.add(entry);
|
|
13686
13878
|
}
|
|
@@ -13715,7 +13907,7 @@ async function processAgent(agent, agentStates) {
|
|
|
13715
13907
|
const sharedSkillsPayload = refreshAny.shared_skills;
|
|
13716
13908
|
const desiredResolved = globalSkillsPayload !== void 0 || sharedSkillsPayload !== void 0;
|
|
13717
13909
|
const manifestPath = managedSkillManifestPath(
|
|
13718
|
-
|
|
13910
|
+
join29(homedir12(), ".augmented", agent.code_name)
|
|
13719
13911
|
);
|
|
13720
13912
|
const prevIds = /* @__PURE__ */ new Set([
|
|
13721
13913
|
...agentState.knownGlobalSkillIds.get(agent.agent_id) ?? /* @__PURE__ */ new Set(),
|
|
@@ -13735,15 +13927,15 @@ async function processAgent(agent, agentStates) {
|
|
|
13735
13927
|
}
|
|
13736
13928
|
if (plan.removes.length) {
|
|
13737
13929
|
const globalSkillDirs = [
|
|
13738
|
-
|
|
13739
|
-
|
|
13740
|
-
|
|
13930
|
+
join29(homedir12(), ".augmented", agent.code_name, "skills"),
|
|
13931
|
+
join29(homedir12(), ".augmented", agent.code_name, "project", ".claude", "skills"),
|
|
13932
|
+
join29(agentDir, ".claude", "skills")
|
|
13741
13933
|
];
|
|
13742
13934
|
for (const id of plan.removes) {
|
|
13743
13935
|
let prunedAny = false;
|
|
13744
13936
|
for (const dir of globalSkillDirs) {
|
|
13745
|
-
const p =
|
|
13746
|
-
if (existsSync12(p) && existsSync12(
|
|
13937
|
+
const p = join29(dir, id);
|
|
13938
|
+
if (existsSync12(p) && existsSync12(join29(p, "SKILL.md"))) {
|
|
13747
13939
|
rmSync5(p, { recursive: true, force: true });
|
|
13748
13940
|
prunedAny = true;
|
|
13749
13941
|
}
|
|
@@ -13974,7 +14166,7 @@ async function processAgent(agent, agentStates) {
|
|
|
13974
14166
|
const sess = getSessionState(agent.code_name);
|
|
13975
14167
|
let mcpJsonParsed = null;
|
|
13976
14168
|
try {
|
|
13977
|
-
const mcpPath =
|
|
14169
|
+
const mcpPath = join29(getProjectDir(agent.code_name), ".mcp.json");
|
|
13978
14170
|
mcpJsonParsed = JSON.parse(readFileSync22(mcpPath, "utf-8"));
|
|
13979
14171
|
} catch {
|
|
13980
14172
|
}
|
|
@@ -14401,7 +14593,7 @@ Retried to the limit after repeated stalls \u2014 needs a look.`).catch(() => {
|
|
|
14401
14593
|
if (trackedFiles.length > 0 && existsSync12(agentDir)) {
|
|
14402
14594
|
const hashes = /* @__PURE__ */ new Map();
|
|
14403
14595
|
for (const file of trackedFiles) {
|
|
14404
|
-
const h = hashFile(
|
|
14596
|
+
const h = hashFile(join29(agentDir, file));
|
|
14405
14597
|
if (h) hashes.set(file, h);
|
|
14406
14598
|
}
|
|
14407
14599
|
agentState.writtenHashes.set(agent.agent_id, hashes);
|
|
@@ -14416,7 +14608,7 @@ Retried to the limit after repeated stalls \u2014 needs a look.`).catch(() => {
|
|
|
14416
14608
|
refreshData.agent.onboarding_state
|
|
14417
14609
|
);
|
|
14418
14610
|
const obStep = obState.step;
|
|
14419
|
-
const markerPath =
|
|
14611
|
+
const markerPath = join29(homedir12(), ".augmented", agent.code_name, "onboarding-drive.json");
|
|
14420
14612
|
const marker = readOnboardingDriveMarker(markerPath);
|
|
14421
14613
|
const decision = decideOnboardingDrive(obStep, marker, Date.now(), obState.generation ?? 0);
|
|
14422
14614
|
if (decision.clearMarker) {
|
|
@@ -14504,7 +14696,7 @@ async function ensureOpencodeRuntime(agent, refreshData, agentTimezone) {
|
|
|
14504
14696
|
}
|
|
14505
14697
|
stopOpencodeSlackIngest(codeName, log);
|
|
14506
14698
|
stopOpencodeTelegramIngest(codeName, log);
|
|
14507
|
-
const opencodeProjectDir =
|
|
14699
|
+
const opencodeProjectDir = join29(getFramework("opencode").getAgentDir(codeName), "provision");
|
|
14508
14700
|
const serveEnv = {
|
|
14509
14701
|
AGT_HOST: requireHost(),
|
|
14510
14702
|
AGT_API_KEY: getApiKey() ?? void 0,
|
|
@@ -14554,8 +14746,8 @@ async function ensurePersistentSession(agent, tasks, boardItems, refreshData) {
|
|
|
14554
14746
|
});
|
|
14555
14747
|
}
|
|
14556
14748
|
const projectDir = getProjectDir(codeName);
|
|
14557
|
-
const mcpConfigPath =
|
|
14558
|
-
const claudeMdPath =
|
|
14749
|
+
const mcpConfigPath = join29(projectDir, ".mcp.json");
|
|
14750
|
+
const claudeMdPath = join29(projectDir, "CLAUDE.md");
|
|
14559
14751
|
if (restartBreaker.isTripped(codeName)) {
|
|
14560
14752
|
const trip = restartBreaker.getTrip(codeName);
|
|
14561
14753
|
return {
|
|
@@ -15186,7 +15378,7 @@ async function handleRestartDoorbell(agentId, requestedAt, restartReason) {
|
|
|
15186
15378
|
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}`));
|
|
15187
15379
|
void (async () => {
|
|
15188
15380
|
try {
|
|
15189
|
-
const { collectDiagnostics } = await import("../persistent-session-
|
|
15381
|
+
const { collectDiagnostics } = await import("../persistent-session-T4IY7AJU.js");
|
|
15190
15382
|
await api.post("/host/heartbeat", {
|
|
15191
15383
|
host_id: hostId,
|
|
15192
15384
|
agent_diagnostics: collectDiagnostics([codeName], quarantineEntriesFor, claudeMdSizeFor)
|
|
@@ -15236,7 +15428,7 @@ async function respawnAgentAfterMcpStop(codeName, reason) {
|
|
|
15236
15428
|
}
|
|
15237
15429
|
try {
|
|
15238
15430
|
const hostId = await getHostId();
|
|
15239
|
-
const { collectDiagnostics } = await import("../persistent-session-
|
|
15431
|
+
const { collectDiagnostics } = await import("../persistent-session-T4IY7AJU.js");
|
|
15240
15432
|
await api.post("/host/heartbeat", {
|
|
15241
15433
|
host_id: hostId,
|
|
15242
15434
|
agent_diagnostics: collectDiagnostics([codeName], quarantineEntriesFor, claudeMdSizeFor)
|
|
@@ -15760,7 +15952,7 @@ async function processClaudePairSessions(agents) {
|
|
|
15760
15952
|
killPairSession,
|
|
15761
15953
|
pairTmuxSession,
|
|
15762
15954
|
finalizeClaudePairOnboarding
|
|
15763
|
-
} = await import("../claude-pair-runtime-
|
|
15955
|
+
} = await import("../claude-pair-runtime-TC2TTMIJ.js");
|
|
15764
15956
|
for (const pairId of pendingResp.cancelled_pair_ids ?? []) {
|
|
15765
15957
|
log(`[claude-pair] sweeping orphan tmux session for pair ${pairId.slice(0, 8)}`);
|
|
15766
15958
|
const killed = await killPairSession(pairTmuxSession(pairId));
|
|
@@ -16014,8 +16206,8 @@ function parseMemoryFile(raw, fallbackName) {
|
|
|
16014
16206
|
};
|
|
16015
16207
|
}
|
|
16016
16208
|
async function syncMemories(agent, configDir, log2) {
|
|
16017
|
-
const projectDir =
|
|
16018
|
-
const memoryDir =
|
|
16209
|
+
const projectDir = join29(configDir, agent.code_name, "project");
|
|
16210
|
+
const memoryDir = join29(projectDir, "memory");
|
|
16019
16211
|
const isFreshSync = pendingFreshMemorySync.has(agent.agent_id);
|
|
16020
16212
|
if (isFreshSync) {
|
|
16021
16213
|
log2(`[memory-sync] Fresh-sync requested for '${agent.code_name}' \u2014 pulling DB first`);
|
|
@@ -16030,10 +16222,10 @@ async function syncMemories(agent, configDir, log2) {
|
|
|
16030
16222
|
const prevHashes = memoryFileHashes.get(agent.agent_id) ?? /* @__PURE__ */ new Map();
|
|
16031
16223
|
const currentHashes = /* @__PURE__ */ new Map();
|
|
16032
16224
|
const changedMemories = [];
|
|
16033
|
-
for (const file of
|
|
16225
|
+
for (const file of readdirSync8(memoryDir)) {
|
|
16034
16226
|
if (!file.endsWith(".md")) continue;
|
|
16035
16227
|
try {
|
|
16036
|
-
const raw = readFileSync22(
|
|
16228
|
+
const raw = readFileSync22(join29(memoryDir, file), "utf-8");
|
|
16037
16229
|
const fileHash = createHash16("sha256").update(raw).digest("hex").slice(0, 16);
|
|
16038
16230
|
currentHashes.set(file, fileHash);
|
|
16039
16231
|
if (prevHashes.get(file) === fileHash) continue;
|
|
@@ -16058,7 +16250,7 @@ async function syncMemories(agent, configDir, log2) {
|
|
|
16058
16250
|
} catch (err) {
|
|
16059
16251
|
for (const mem of changedMemories) {
|
|
16060
16252
|
for (const [file] of currentHashes) {
|
|
16061
|
-
const parsed = parseMemoryFile(readFileSync22(
|
|
16253
|
+
const parsed = parseMemoryFile(readFileSync22(join29(memoryDir, file), "utf-8"), file.replace(/\.md$/, ""));
|
|
16062
16254
|
if (parsed?.name === mem.name) currentHashes.delete(file);
|
|
16063
16255
|
}
|
|
16064
16256
|
}
|
|
@@ -16071,7 +16263,7 @@ async function syncMemories(agent, configDir, log2) {
|
|
|
16071
16263
|
}
|
|
16072
16264
|
}
|
|
16073
16265
|
async function downloadMemories(agent, memoryDir, log2, { force }) {
|
|
16074
|
-
const localFiles = existsSync12(memoryDir) ?
|
|
16266
|
+
const localFiles = existsSync12(memoryDir) ? readdirSync8(memoryDir).filter((f) => f.endsWith(".md")).sort() : [];
|
|
16075
16267
|
const localListHash = createHash16("sha256").update(localFiles.join(",")).digest("hex").slice(0, 16);
|
|
16076
16268
|
const prevLocalHash = lastLocalFileHash.get(agent.agent_id);
|
|
16077
16269
|
const prevDownload = lastDownloadHash.get(agent.agent_id);
|
|
@@ -16093,7 +16285,7 @@ async function downloadMemories(agent, memoryDir, log2, { force }) {
|
|
|
16093
16285
|
const mem = dbMemories.memories[i];
|
|
16094
16286
|
const rawSlug = mem.name.toLowerCase().replace(/[^a-z0-9]+/g, "-").replace(/(^-|-$)/g, "").slice(0, 60);
|
|
16095
16287
|
const slug = rawSlug || `memory-${i}`;
|
|
16096
|
-
const filePath =
|
|
16288
|
+
const filePath = join29(memoryDir, `${slug}.md`);
|
|
16097
16289
|
const desired = `---
|
|
16098
16290
|
name: ${JSON.stringify(mem.name)}
|
|
16099
16291
|
type: ${mem.type}
|
|
@@ -16117,7 +16309,7 @@ ${mem.content}
|
|
|
16117
16309
|
}
|
|
16118
16310
|
}
|
|
16119
16311
|
if (written > 0 || overwritten > 0) {
|
|
16120
|
-
const updatedFiles =
|
|
16312
|
+
const updatedFiles = readdirSync8(memoryDir).filter((f) => f.endsWith(".md")).sort();
|
|
16121
16313
|
lastLocalFileHash.set(agent.agent_id, createHash16("sha256").update(updatedFiles.join(",")).digest("hex").slice(0, 16));
|
|
16122
16314
|
log2(`Memory download for '${agent.code_name}': wrote ${written} new, overwrote ${overwritten} stale`);
|
|
16123
16315
|
}
|
|
@@ -16396,7 +16588,7 @@ function startManager(opts) {
|
|
|
16396
16588
|
log(`[startup] state rehydration failed (continuing with empty state): ${err.message}`);
|
|
16397
16589
|
}
|
|
16398
16590
|
log(
|
|
16399
|
-
`[startup] worker pid=${process.pid} ppid=${process.ppid} node=${process.version} log=${
|
|
16591
|
+
`[startup] worker pid=${process.pid} ppid=${process.ppid} node=${process.version} log=${join29(homedir12(), ".augmented", "manager.log")}`
|
|
16400
16592
|
);
|
|
16401
16593
|
deployMcpAssets();
|
|
16402
16594
|
reapOrphanChannelMcps({ log });
|
|
@@ -16522,14 +16714,14 @@ function restartRunningChannelMcps(basenames) {
|
|
|
16522
16714
|
}
|
|
16523
16715
|
}
|
|
16524
16716
|
function deployMcpAssets() {
|
|
16525
|
-
const targetDir =
|
|
16717
|
+
const targetDir = join29(homedir12(), ".augmented", "_mcp");
|
|
16526
16718
|
mkdirSync10(targetDir, { recursive: true });
|
|
16527
16719
|
const moduleDir = dirname8(fileURLToPath(import.meta.url));
|
|
16528
16720
|
let mcpSourceDir = "";
|
|
16529
16721
|
let dir = moduleDir;
|
|
16530
16722
|
for (let i = 0; i < 6; i++) {
|
|
16531
|
-
const candidate =
|
|
16532
|
-
if (existsSync12(
|
|
16723
|
+
const candidate = join29(dir, "dist", "mcp");
|
|
16724
|
+
if (existsSync12(join29(candidate, "index.js"))) {
|
|
16533
16725
|
mcpSourceDir = candidate;
|
|
16534
16726
|
break;
|
|
16535
16727
|
}
|
|
@@ -16585,6 +16777,13 @@ function deployMcpAssets() {
|
|
|
16585
16777
|
// RESTARTABLE_CHANNEL_FILES; the reaper (re)starts it with the session and a
|
|
16586
16778
|
// bundle update applies on the next natural session restart.
|
|
16587
16779
|
"augmented-support.js",
|
|
16780
|
+
// ENG-8332: the help-knowledge-base broker, split out of augmented-support
|
|
16781
|
+
// so the docs can be granted without its ticket-filing and org-state
|
|
16782
|
+
// surface. Bundled with the CLI (never published to npm). Same treatment as
|
|
16783
|
+
// augmented-support - NOT a channel, so not in RESTARTABLE_CHANNEL_FILES;
|
|
16784
|
+
// the reaper (re)starts it with the session and a bundle update applies on
|
|
16785
|
+
// the next natural session restart.
|
|
16786
|
+
"augmented-help-kb.js",
|
|
16588
16787
|
// ENG-6859: the remote OAuth MCP proxy (brand-ninja, granola). NOT in
|
|
16589
16788
|
// RESTARTABLE_CHANNEL_FILES - it's not a channel; a bundle update applies on
|
|
16590
16789
|
// the next natural session restart. It re-reads the token from the secrets
|
|
@@ -16609,8 +16808,8 @@ function deployMcpAssets() {
|
|
|
16609
16808
|
// needs restarting to pick up a token rotation.
|
|
16610
16809
|
"xero.js"
|
|
16611
16810
|
]) {
|
|
16612
|
-
const src =
|
|
16613
|
-
const dst =
|
|
16811
|
+
const src = join29(mcpSourceDir, file);
|
|
16812
|
+
const dst = join29(targetDir, file);
|
|
16614
16813
|
if (!existsSync12(src)) continue;
|
|
16615
16814
|
const before = fileHash(dst);
|
|
16616
16815
|
try {
|
|
@@ -16628,14 +16827,14 @@ function deployMcpAssets() {
|
|
|
16628
16827
|
log(`[manager] Bundle(s) updated: ${changedBasenames.join(", ")} \u2014 signalling running instances to restart`);
|
|
16629
16828
|
restartRunningChannelMcps(changedBasenames);
|
|
16630
16829
|
}
|
|
16631
|
-
const localMcpPath =
|
|
16830
|
+
const localMcpPath = join29(targetDir, "index.js");
|
|
16632
16831
|
try {
|
|
16633
|
-
const agentsDir =
|
|
16832
|
+
const agentsDir = join29(homedir12(), ".augmented", "agents");
|
|
16634
16833
|
if (existsSync12(agentsDir)) {
|
|
16635
|
-
for (const entry of
|
|
16834
|
+
for (const entry of readdirSync8(agentsDir, { withFileTypes: true })) {
|
|
16636
16835
|
if (!entry.isDirectory()) continue;
|
|
16637
16836
|
for (const subdir of ["provision", "project"]) {
|
|
16638
|
-
const mcpJsonPath =
|
|
16837
|
+
const mcpJsonPath = join29(agentsDir, entry.name, subdir, ".mcp.json");
|
|
16639
16838
|
try {
|
|
16640
16839
|
const raw = readFileSync22(mcpJsonPath, "utf-8");
|
|
16641
16840
|
if (!raw.includes("@integrity-labs/augmented-mcp")) continue;
|