@integrity-labs/agt-cli 0.28.1005 → 0.28.1007
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 +6 -5
- package/dist/bin/agt.js.map +1 -1
- package/dist/chunk-EL5MWGGH.js +160 -0
- package/dist/chunk-EL5MWGGH.js.map +1 -0
- package/dist/{chunk-6U4NB3LJ.js → chunk-FLJNRC3D.js} +71 -9
- package/dist/chunk-FLJNRC3D.js.map +1 -0
- package/dist/{chunk-TGTUE7Y2.js → chunk-SQX4ZGD5.js} +73 -8
- package/dist/chunk-SQX4ZGD5.js.map +1 -0
- package/dist/{chunk-DVSYT4MU.js → chunk-XWMUQR65.js} +52 -1
- package/dist/{chunk-DVSYT4MU.js.map → chunk-XWMUQR65.js.map} +1 -1
- package/dist/{claude-code-updater-45MB2AXE.js → claude-code-updater-NEJCTT7S.js} +7 -3
- package/dist/claude-code-updater-NEJCTT7S.js.map +1 -0
- package/dist/{claude-pair-runtime-DDSYAHQW.js → claude-pair-runtime-X27QVAXL.js} +172 -18
- package/dist/claude-pair-runtime-X27QVAXL.js.map +1 -0
- package/dist/lib/manager-worker.js +547 -227
- package/dist/lib/manager-worker.js.map +1 -1
- package/dist/mcp/direct-chat-channel.js +57 -2
- package/dist/mcp/index.js +51 -0
- package/dist/mcp/origami.js +51 -0
- package/dist/mcp/slack-channel.js +57 -2
- package/dist/mcp/telegram-channel.js +57 -2
- package/dist/{persistent-session-4PP3ON7H.js → persistent-session-5KWYODZB.js} +6 -3
- package/dist/{responsiveness-probe-6NWZAXIZ.js → responsiveness-probe-J2DYGC7T.js} +4 -3
- package/dist/{responsiveness-probe-6NWZAXIZ.js.map → responsiveness-probe-J2DYGC7T.js.map} +1 -1
- package/dist/{session-auth-dead-2V2BOXAG.js → session-auth-dead-4SE5Q7MU.js} +2 -2
- package/package.json +1 -1
- package/dist/chunk-6U4NB3LJ.js.map +0 -1
- package/dist/chunk-TGTUE7Y2.js.map +0 -1
- package/dist/claude-code-updater-45MB2AXE.js.map +0 -1
- package/dist/claude-pair-runtime-DDSYAHQW.js.map +0 -1
- /package/dist/{persistent-session-4PP3ON7H.js.map → persistent-session-5KWYODZB.js.map} +0 -0
- /package/dist/{session-auth-dead-2V2BOXAG.js.map → session-auth-dead-4SE5Q7MU.js.map} +0 -0
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import {
|
|
2
2
|
ApiError,
|
|
3
3
|
COMPUTER_USE_MCP_KEY,
|
|
4
|
+
DEAD_CHANNEL_MS,
|
|
4
5
|
FIRST_CONNECT_WINDOW_MS,
|
|
5
6
|
HostFlagStore,
|
|
6
7
|
RestartBreaker,
|
|
@@ -63,7 +64,7 @@ import {
|
|
|
63
64
|
safeWriteJsonAtomic,
|
|
64
65
|
setConfigHash,
|
|
65
66
|
tripClass
|
|
66
|
-
} from "../chunk-
|
|
67
|
+
} from "../chunk-FLJNRC3D.js";
|
|
67
68
|
import {
|
|
68
69
|
getProjectDir as getProjectDir2,
|
|
69
70
|
getReadyTasks,
|
|
@@ -141,7 +142,7 @@ import {
|
|
|
141
142
|
takeZombieDetection,
|
|
142
143
|
toOpencodeModel,
|
|
143
144
|
writeEgressAllowlist
|
|
144
|
-
} from "../chunk-
|
|
145
|
+
} from "../chunk-SQX4ZGD5.js";
|
|
145
146
|
import {
|
|
146
147
|
ACCOUNT_ENFORCEMENT_MARKER_FILENAME,
|
|
147
148
|
AnchorSessionClient,
|
|
@@ -240,16 +241,23 @@ import {
|
|
|
240
241
|
subagentActivityAgeSeconds,
|
|
241
242
|
sumTranscriptUsageInWindow,
|
|
242
243
|
transcriptActivityAgeSeconds
|
|
243
|
-
} from "../chunk-
|
|
244
|
+
} from "../chunk-XWMUQR65.js";
|
|
244
245
|
import "../chunk-DHWNVVX4.js";
|
|
245
246
|
import {
|
|
246
247
|
reapOrphanChannelMcps
|
|
247
248
|
} from "../chunk-XWVM4KPK.js";
|
|
249
|
+
import {
|
|
250
|
+
CLAUDE_CONFIG_DIR_ENV,
|
|
251
|
+
claudeConfigDirFor,
|
|
252
|
+
claudeConfigDirIsReady,
|
|
253
|
+
effectiveClaudeJsonPath,
|
|
254
|
+
seedClaudeConfigFromLegacy
|
|
255
|
+
} from "../chunk-EL5MWGGH.js";
|
|
248
256
|
import "../chunk-DGUM43GV.js";
|
|
249
257
|
|
|
250
258
|
// src/lib/manager-worker.ts
|
|
251
259
|
import { createHash as createHash20 } from "crypto";
|
|
252
|
-
import { readFileSync as
|
|
260
|
+
import { readFileSync as readFileSync34, writeFileSync as writeFileSync18, mkdirSync as mkdirSync15, existsSync as existsSync19, rmSync as rmSync8, readdirSync as readdirSync12, statSync as statSync13, unlinkSync as unlinkSync6, renameSync as renameSync11, utimesSync as utimesSync4 } from "fs";
|
|
253
261
|
|
|
254
262
|
// src/lib/atomic-file-replace.ts
|
|
255
263
|
import { copyFileSync, renameSync, unlinkSync } from "fs";
|
|
@@ -276,7 +284,7 @@ function defaultUnique() {
|
|
|
276
284
|
// src/lib/manager-worker.ts
|
|
277
285
|
import { execFileSync as syncExecFile } from "child_process";
|
|
278
286
|
import { join as join42, dirname as dirname11, delimiter as pathDelimiter } from "path";
|
|
279
|
-
import { homedir as
|
|
287
|
+
import { homedir as homedir17 } from "os";
|
|
280
288
|
import { fileURLToPath as fileURLToPath2 } from "url";
|
|
281
289
|
|
|
282
290
|
// ../../packages/core/dist/provisioning/channel-policy-env.js
|
|
@@ -1053,9 +1061,157 @@ function clearOnboardingDriveMarker(path) {
|
|
|
1053
1061
|
}
|
|
1054
1062
|
}
|
|
1055
1063
|
|
|
1056
|
-
// src/lib/channel-
|
|
1064
|
+
// src/lib/channel-auto-resume.ts
|
|
1057
1065
|
import { readFileSync as readFileSync3 } from "fs";
|
|
1058
1066
|
import { join as join3 } from "path";
|
|
1067
|
+
var AUTO_RESUME_BASE_MS = 2 * 60 * 6e4;
|
|
1068
|
+
var AUTO_RESUME_MAX_MS = 24 * 60 * 6e4;
|
|
1069
|
+
var AUTO_RESUME_MAX_ATTEMPTS = 5;
|
|
1070
|
+
var QUARANTINE_DWELL_FLOOR_MS = 18e4;
|
|
1071
|
+
var AUTO_RESUME_SUCCESS_GRACE_MS = 2 * (DEAD_CHANNEL_MS + QUARANTINE_DWELL_FLOOR_MS);
|
|
1072
|
+
function defaultResumeHistoryPath(configDir) {
|
|
1073
|
+
return join3(configDir, "channel-quarantine-resumes.json");
|
|
1074
|
+
}
|
|
1075
|
+
function isResumeFile(value) {
|
|
1076
|
+
if (!value || typeof value !== "object" || Array.isArray(value)) return false;
|
|
1077
|
+
for (const forAgent of Object.values(value)) {
|
|
1078
|
+
if (!forAgent || typeof forAgent !== "object" || Array.isArray(forAgent)) return false;
|
|
1079
|
+
for (const entry of Object.values(forAgent)) {
|
|
1080
|
+
if (!entry || typeof entry !== "object") return false;
|
|
1081
|
+
const e = entry;
|
|
1082
|
+
if (e.gaveUpLogged !== void 0 && typeof e.gaveUpLogged !== "boolean") return false;
|
|
1083
|
+
const attempts = e.attempts;
|
|
1084
|
+
const lastAttemptAt = e.lastAttemptAt;
|
|
1085
|
+
if (typeof attempts !== "number" || !Number.isSafeInteger(attempts) || attempts < 0 || typeof lastAttemptAt !== "number" || !Number.isSafeInteger(lastAttemptAt) || lastAttemptAt < 0) {
|
|
1086
|
+
return false;
|
|
1087
|
+
}
|
|
1088
|
+
}
|
|
1089
|
+
}
|
|
1090
|
+
return true;
|
|
1091
|
+
}
|
|
1092
|
+
var ChannelResumeHistoryStore = class {
|
|
1093
|
+
path;
|
|
1094
|
+
cache = null;
|
|
1095
|
+
constructor(path) {
|
|
1096
|
+
this.path = path;
|
|
1097
|
+
}
|
|
1098
|
+
load() {
|
|
1099
|
+
if (this.cache) return this.cache;
|
|
1100
|
+
try {
|
|
1101
|
+
const parsed = JSON.parse(readFileSync3(this.path, "utf-8"));
|
|
1102
|
+
this.cache = isResumeFile(parsed) ? parsed : {};
|
|
1103
|
+
} catch {
|
|
1104
|
+
this.cache = {};
|
|
1105
|
+
}
|
|
1106
|
+
return this.cache;
|
|
1107
|
+
}
|
|
1108
|
+
persist() {
|
|
1109
|
+
atomicWriteFileSync(this.path, JSON.stringify(this.cache ?? {}, null, 2));
|
|
1110
|
+
}
|
|
1111
|
+
get(codeName, serverKey) {
|
|
1112
|
+
return this.load()[codeName]?.[serverKey];
|
|
1113
|
+
}
|
|
1114
|
+
/**
|
|
1115
|
+
* Every recorded key for one agent, as [storedKey, entry] pairs.
|
|
1116
|
+
*
|
|
1117
|
+
* Needed because the success sweep asks about channels that are NOT in the
|
|
1118
|
+
* quarantine store — a trial that worked leaves history behind and no marker,
|
|
1119
|
+
* so a loop over quarantine entries can never reach it. Returns the STORED
|
|
1120
|
+
* key (see `resumeHistoryKey`), not the channel key, because the caller is
|
|
1121
|
+
* the only thing that knows which namespace it is working in.
|
|
1122
|
+
*/
|
|
1123
|
+
entriesFor(codeName) {
|
|
1124
|
+
return Object.entries(this.load()[codeName] ?? {});
|
|
1125
|
+
}
|
|
1126
|
+
/** Record a trial. Returns the entry as written. */
|
|
1127
|
+
recordAttempt(codeName, serverKey, now) {
|
|
1128
|
+
const file = this.load();
|
|
1129
|
+
const forAgent = file[codeName] ??= {};
|
|
1130
|
+
const prior = forAgent[serverKey];
|
|
1131
|
+
const next = {
|
|
1132
|
+
attempts: (prior?.attempts ?? 0) + 1,
|
|
1133
|
+
lastAttemptAt: now,
|
|
1134
|
+
// Carried, not reset: a further trial inside the same episode must not
|
|
1135
|
+
// re-arm the give-up line. It clears with the entry itself on forget().
|
|
1136
|
+
...prior?.gaveUpLogged ? { gaveUpLogged: true } : {}
|
|
1137
|
+
};
|
|
1138
|
+
forAgent[serverKey] = next;
|
|
1139
|
+
this.persist();
|
|
1140
|
+
return next;
|
|
1141
|
+
}
|
|
1142
|
+
/**
|
|
1143
|
+
* Forget a key's history — called when an OPERATOR clears the quarantine.
|
|
1144
|
+
*
|
|
1145
|
+
* A human pressing Re-enable is a statement that the underlying fault was
|
|
1146
|
+
* addressed, so the next automatic trial should start from a clean two hours
|
|
1147
|
+
* rather than inheriting strikes from before the fix. Without this an
|
|
1148
|
+
* operator could fix a channel, watch it break again for an unrelated reason
|
|
1149
|
+
* weeks later, and find auto-resume already exhausted.
|
|
1150
|
+
*/
|
|
1151
|
+
forget(codeName, serverKey) {
|
|
1152
|
+
const file = this.load();
|
|
1153
|
+
const forAgent = file[codeName];
|
|
1154
|
+
if (!forAgent || !forAgent[serverKey]) return false;
|
|
1155
|
+
delete forAgent[serverKey];
|
|
1156
|
+
if (Object.keys(forAgent).length === 0) delete file[codeName];
|
|
1157
|
+
this.persist();
|
|
1158
|
+
return true;
|
|
1159
|
+
}
|
|
1160
|
+
/**
|
|
1161
|
+
* Latch the give-up line for this key. Returns whether it had ALREADY been
|
|
1162
|
+
* logged, so the caller logs only on the first call of an episode.
|
|
1163
|
+
*
|
|
1164
|
+
* Returns true (already logged) when there is no entry at all: with no
|
|
1165
|
+
* history there are no strikes, so there is nothing to have given up ON, and
|
|
1166
|
+
* announcing an abandonment would be false.
|
|
1167
|
+
*/
|
|
1168
|
+
noteGaveUpLogged(codeName, serverKey) {
|
|
1169
|
+
const file = this.load();
|
|
1170
|
+
const entry = file[codeName]?.[serverKey];
|
|
1171
|
+
if (!entry) return true;
|
|
1172
|
+
if (entry.gaveUpLogged) return true;
|
|
1173
|
+
entry.gaveUpLogged = true;
|
|
1174
|
+
this.persist();
|
|
1175
|
+
return false;
|
|
1176
|
+
}
|
|
1177
|
+
__invalidateCacheForTests() {
|
|
1178
|
+
this.cache = null;
|
|
1179
|
+
}
|
|
1180
|
+
};
|
|
1181
|
+
function resumeHistoryKey(mode, serverKey) {
|
|
1182
|
+
return mode === "shadow" ? `shadow:${serverKey}` : serverKey;
|
|
1183
|
+
}
|
|
1184
|
+
function backoffForAttempt(attemptsAlreadyMade) {
|
|
1185
|
+
const doubled = AUTO_RESUME_BASE_MS * 2 ** Math.max(0, attemptsAlreadyMade);
|
|
1186
|
+
return Math.min(doubled, AUTO_RESUME_MAX_MS);
|
|
1187
|
+
}
|
|
1188
|
+
function resolveAutoResumeEffectiveMode(autoResume, quarantine) {
|
|
1189
|
+
if (autoResume === "enforce" && quarantine !== "enforce") return "shadow";
|
|
1190
|
+
return autoResume;
|
|
1191
|
+
}
|
|
1192
|
+
function autoResumeSuccessGraceMs(configuredDwellMs) {
|
|
1193
|
+
const dwell = typeof configuredDwellMs === "number" && Number.isFinite(configuredDwellMs) && configuredDwellMs > QUARANTINE_DWELL_FLOOR_MS ? configuredDwellMs : QUARANTINE_DWELL_FLOOR_MS;
|
|
1194
|
+
return 2 * (DEAD_CHANNEL_MS + dwell);
|
|
1195
|
+
}
|
|
1196
|
+
function shouldForgetResumeHistory(input) {
|
|
1197
|
+
if (input.isQuarantined) return false;
|
|
1198
|
+
const history = input.history;
|
|
1199
|
+
if (!history || history.attempts === 0) return false;
|
|
1200
|
+
return input.now - history.lastAttemptAt >= autoResumeSuccessGraceMs(input.configuredDwellMs);
|
|
1201
|
+
}
|
|
1202
|
+
function decideChannelAutoResume(input) {
|
|
1203
|
+
const attempts = input.history?.attempts ?? 0;
|
|
1204
|
+
if (attempts >= AUTO_RESUME_MAX_ATTEMPTS) return { action: "give-up", attempts };
|
|
1205
|
+
const since = Math.max(input.quarantinedAt, input.history?.lastAttemptAt ?? 0);
|
|
1206
|
+
const waited = input.now - since;
|
|
1207
|
+
const need = backoffForAttempt(attempts);
|
|
1208
|
+
if (waited >= need) return { action: "resume", waitedMs: waited, attempt: attempts + 1 };
|
|
1209
|
+
return { action: "wait", dueInMs: need - waited, attempt: attempts + 1 };
|
|
1210
|
+
}
|
|
1211
|
+
|
|
1212
|
+
// src/lib/channel-quarantine.ts
|
|
1213
|
+
import { readFileSync as readFileSync4 } from "fs";
|
|
1214
|
+
import { join as join4 } from "path";
|
|
1059
1215
|
var ESSENTIAL_CHANNEL_KEYS = /* @__PURE__ */ new Set(["direct-chat", "augmented"]);
|
|
1060
1216
|
var OPTIONAL_CHANNEL_KEYS = /* @__PURE__ */ new Set([
|
|
1061
1217
|
"telegram",
|
|
@@ -1087,7 +1243,7 @@ function classifyChannelCriticality(serverKey, entry) {
|
|
|
1087
1243
|
return "essential";
|
|
1088
1244
|
}
|
|
1089
1245
|
function defaultQuarantinePath(configDir) {
|
|
1090
|
-
return
|
|
1246
|
+
return join4(configDir, "channel-quarantine.json");
|
|
1091
1247
|
}
|
|
1092
1248
|
var ChannelQuarantineStore = class {
|
|
1093
1249
|
path;
|
|
@@ -1098,7 +1254,7 @@ var ChannelQuarantineStore = class {
|
|
|
1098
1254
|
load() {
|
|
1099
1255
|
if (this.cache) return this.cache;
|
|
1100
1256
|
try {
|
|
1101
|
-
const raw =
|
|
1257
|
+
const raw = readFileSync4(this.path, "utf-8");
|
|
1102
1258
|
const parsed = JSON.parse(raw);
|
|
1103
1259
|
this.cache = isQuarantineFile(parsed) ? parsed : {};
|
|
1104
1260
|
} catch {
|
|
@@ -1186,13 +1342,13 @@ function isQuarantineFile(value) {
|
|
|
1186
1342
|
}
|
|
1187
1343
|
|
|
1188
1344
|
// src/lib/claude-md-size.ts
|
|
1189
|
-
import { readFileSync as
|
|
1190
|
-
import { join as
|
|
1345
|
+
import { readFileSync as readFileSync5 } from "fs";
|
|
1346
|
+
import { join as join5 } from "path";
|
|
1191
1347
|
function measureClaudeMd(configDir, codeName, ceiling = CLAUDE_MD_CONTEXT_ALARM_CHARS) {
|
|
1192
1348
|
let chars;
|
|
1193
1349
|
let bytes;
|
|
1194
1350
|
try {
|
|
1195
|
-
const buf =
|
|
1351
|
+
const buf = readFileSync5(join5(configDir, codeName, "project", "CLAUDE.md"));
|
|
1196
1352
|
chars = buf.toString("utf8").length;
|
|
1197
1353
|
bytes = buf.length;
|
|
1198
1354
|
} catch {
|
|
@@ -1212,8 +1368,8 @@ function measureClaudeMd(configDir, codeName, ceiling = CLAUDE_MD_CONTEXT_ALARM_
|
|
|
1212
1368
|
function measureCoreKnowledgeDescription(configDir, codeName) {
|
|
1213
1369
|
let text;
|
|
1214
1370
|
try {
|
|
1215
|
-
text =
|
|
1216
|
-
|
|
1371
|
+
text = readFileSync5(
|
|
1372
|
+
join5(configDir, codeName, "project", ".claude", "skills", "core-knowledge", "SKILL.md"),
|
|
1217
1373
|
"utf8"
|
|
1218
1374
|
);
|
|
1219
1375
|
} catch {
|
|
@@ -1247,16 +1403,16 @@ function logClaudeMdCeilingTransition(codeName, report, log2) {
|
|
|
1247
1403
|
}
|
|
1248
1404
|
|
|
1249
1405
|
// ../../packages/core/dist/integrations/forwarded-tools-report.js
|
|
1250
|
-
import { readFileSync as
|
|
1251
|
-
import { join as
|
|
1406
|
+
import { readFileSync as readFileSync6, writeFileSync as writeFileSync3 } from "fs";
|
|
1407
|
+
import { join as join6 } from "path";
|
|
1252
1408
|
var FORWARDED_TOOLS_REPORT_FILENAME = "forwarded-tools.json";
|
|
1253
1409
|
function forwardedToolsReportPath(agentDir) {
|
|
1254
|
-
return
|
|
1410
|
+
return join6(agentDir, FORWARDED_TOOLS_REPORT_FILENAME);
|
|
1255
1411
|
}
|
|
1256
1412
|
function readForwardedToolsReport(agentDir) {
|
|
1257
1413
|
let raw;
|
|
1258
1414
|
try {
|
|
1259
|
-
raw =
|
|
1415
|
+
raw = readFileSync6(forwardedToolsReportPath(agentDir), "utf-8");
|
|
1260
1416
|
} catch {
|
|
1261
1417
|
return null;
|
|
1262
1418
|
}
|
|
@@ -1873,9 +2029,9 @@ var DependencyRecoveryLedger = class {
|
|
|
1873
2029
|
// src/lib/mcp-assets-ready.ts
|
|
1874
2030
|
import { existsSync as nodeExistsSync, readFileSync as nodeReadFileSync } from "fs";
|
|
1875
2031
|
import { homedir as homedir2 } from "os";
|
|
1876
|
-
import { join as
|
|
2032
|
+
import { join as join7, resolve, sep } from "path";
|
|
1877
2033
|
function getSharedMcpDir(homeDir = homedir2()) {
|
|
1878
|
-
return
|
|
2034
|
+
return join7(homeDir, ".augmented", "_mcp");
|
|
1879
2035
|
}
|
|
1880
2036
|
function isPathInsideDir(candidate, dir) {
|
|
1881
2037
|
const resolvedDir = resolve(dir);
|
|
@@ -1885,11 +2041,11 @@ function isPathInsideDir(candidate, dir) {
|
|
|
1885
2041
|
}
|
|
1886
2042
|
function findMissingMcpBundles(mcpConfigPath, deps = {}) {
|
|
1887
2043
|
const existsSync20 = deps.existsSync ?? nodeExistsSync;
|
|
1888
|
-
const
|
|
2044
|
+
const readFileSync35 = deps.readFileSync ?? nodeReadFileSync;
|
|
1889
2045
|
const mcpDir = deps.mcpDir ?? getSharedMcpDir();
|
|
1890
2046
|
let parsed;
|
|
1891
2047
|
try {
|
|
1892
|
-
parsed = JSON.parse(
|
|
2048
|
+
parsed = JSON.parse(readFileSync35(mcpConfigPath, "utf-8"));
|
|
1893
2049
|
} catch {
|
|
1894
2050
|
return [];
|
|
1895
2051
|
}
|
|
@@ -1927,7 +2083,7 @@ function formatMissingMcpBundles(missing) {
|
|
|
1927
2083
|
}
|
|
1928
2084
|
|
|
1929
2085
|
// src/lib/self-update-coalesce.ts
|
|
1930
|
-
import { readFileSync as
|
|
2086
|
+
import { readFileSync as readFileSync7, writeFileSync as writeFileSync4, mkdirSync as mkdirSync3 } from "fs";
|
|
1931
2087
|
import { dirname as dirname4 } from "path";
|
|
1932
2088
|
var DEFAULT_SELF_UPDATE_COALESCE_MS = 30 * 60 * 1e3;
|
|
1933
2089
|
function resolveCoalesceWindowMs(env = process.env) {
|
|
@@ -1937,7 +2093,7 @@ function resolveCoalesceWindowMs(env = process.env) {
|
|
|
1937
2093
|
if (!Number.isFinite(parsed) || parsed < 0) return DEFAULT_SELF_UPDATE_COALESCE_MS;
|
|
1938
2094
|
return Math.trunc(parsed);
|
|
1939
2095
|
}
|
|
1940
|
-
function readLastSelfUpdateAppliedMs(markerPath, now = Date.now(), read = (p) =>
|
|
2096
|
+
function readLastSelfUpdateAppliedMs(markerPath, now = Date.now(), read = (p) => readFileSync7(p, "utf-8")) {
|
|
1941
2097
|
let raw;
|
|
1942
2098
|
try {
|
|
1943
2099
|
raw = read(markerPath);
|
|
@@ -2242,11 +2398,11 @@ async function reportModelApiError(opts) {
|
|
|
2242
2398
|
}
|
|
2243
2399
|
|
|
2244
2400
|
// src/lib/claude-pid-tracker.ts
|
|
2245
|
-
import { existsSync, readFileSync as
|
|
2401
|
+
import { existsSync, readFileSync as readFileSync8 } from "fs";
|
|
2246
2402
|
function readPidFile(path) {
|
|
2247
2403
|
if (!existsSync(path)) return { version: 1, spawns: [] };
|
|
2248
2404
|
try {
|
|
2249
|
-
const raw = JSON.parse(
|
|
2405
|
+
const raw = JSON.parse(readFileSync8(path, "utf-8"));
|
|
2250
2406
|
if (raw.version !== 1 || !Array.isArray(raw.spawns)) return { version: 1, spawns: [] };
|
|
2251
2407
|
const spawns = raw.spawns.filter(
|
|
2252
2408
|
(s) => !!s && typeof s.pid === "number" && Number.isFinite(s.pid) && s.pid > 0
|
|
@@ -2346,14 +2502,14 @@ async function killSessionsConcurrently(sessions, killOne) {
|
|
|
2346
2502
|
}
|
|
2347
2503
|
|
|
2348
2504
|
// src/lib/direct-chat-delivery.ts
|
|
2349
|
-
import { join as
|
|
2505
|
+
import { join as join8 } from "path";
|
|
2350
2506
|
var DEFAULT_DIRECT_CHAT_MAX_AGE_MS = 30 * 6e4;
|
|
2351
2507
|
function directChatMaxAgeMs() {
|
|
2352
2508
|
const raw = parseInt(process.env["AGT_DIRECT_CHAT_MAX_AGE_MS"] ?? "", 10);
|
|
2353
2509
|
return Number.isFinite(raw) && raw >= 0 ? raw : DEFAULT_DIRECT_CHAT_MAX_AGE_MS;
|
|
2354
2510
|
}
|
|
2355
2511
|
function directChatDoorbellPath(agentId, home) {
|
|
2356
|
-
return
|
|
2512
|
+
return join8(home, ".augmented", agentId, "direct-chat-doorbell");
|
|
2357
2513
|
}
|
|
2358
2514
|
function isDirectChatMessageExpired(createdAt, nowMs, maxAgeMs) {
|
|
2359
2515
|
if (!maxAgeMs || maxAgeMs <= 0) return false;
|
|
@@ -2364,8 +2520,8 @@ function isDirectChatMessageExpired(createdAt, nowMs, maxAgeMs) {
|
|
|
2364
2520
|
}
|
|
2365
2521
|
|
|
2366
2522
|
// src/lib/review-poster-asset.ts
|
|
2367
|
-
import { copyFileSync as copyFileSync2, chmodSync, existsSync as existsSync2, mkdirSync as mkdirSync4, readFileSync as
|
|
2368
|
-
import { dirname as dirname5, join as
|
|
2523
|
+
import { copyFileSync as copyFileSync2, chmodSync, existsSync as existsSync2, mkdirSync as mkdirSync4, readFileSync as readFileSync9 } from "fs";
|
|
2524
|
+
import { dirname as dirname5, join as join9 } from "path";
|
|
2369
2525
|
import { fileURLToPath } from "url";
|
|
2370
2526
|
var POSTER_FILENAME = "post-review-findings.mjs";
|
|
2371
2527
|
var AUTH_FILENAME = "obiwan-auth.mjs";
|
|
@@ -2378,14 +2534,14 @@ function resolveBundledReviewAssetDir() {
|
|
|
2378
2534
|
const moduleDir = dirname5(fileURLToPath(import.meta.url));
|
|
2379
2535
|
const candidates = [
|
|
2380
2536
|
// Built output: dist/<chunk>.js → dist/assets/review
|
|
2381
|
-
|
|
2537
|
+
join9(moduleDir, "assets", REVIEW_ASSET_DIRNAME),
|
|
2382
2538
|
// Built output sibling case: dist/<sub>/<chunk>.js → dist/assets/review
|
|
2383
|
-
|
|
2539
|
+
join9(moduleDir, "..", "assets", REVIEW_ASSET_DIRNAME),
|
|
2384
2540
|
// Dev source: src/lib/review-poster-asset.ts → ../../assets/review
|
|
2385
|
-
|
|
2541
|
+
join9(moduleDir, "..", "..", "assets", REVIEW_ASSET_DIRNAME)
|
|
2386
2542
|
];
|
|
2387
2543
|
for (const candidate of candidates) {
|
|
2388
|
-
if (existsSync2(
|
|
2544
|
+
if (existsSync2(join9(candidate, POSTER_FILENAME))) return candidate;
|
|
2389
2545
|
}
|
|
2390
2546
|
throw new Error(
|
|
2391
2547
|
`[review-poster] could not locate bundled assets; tried:
|
|
@@ -2393,18 +2549,18 @@ function resolveBundledReviewAssetDir() {
|
|
|
2393
2549
|
);
|
|
2394
2550
|
}
|
|
2395
2551
|
function reviewPosterDir(codeName) {
|
|
2396
|
-
return
|
|
2552
|
+
return join9(getFramework("claude-code").getAgentDir(codeName), REVIEW_ASSET_DIRNAME);
|
|
2397
2553
|
}
|
|
2398
2554
|
function provisionReviewPoster(codeName, sourceDir = resolveBundledReviewAssetDir()) {
|
|
2399
2555
|
const destDir = reviewPosterDir(codeName);
|
|
2400
2556
|
mkdirSync4(destDir, { recursive: true });
|
|
2401
2557
|
for (const [name, mode] of ASSET_FILES) {
|
|
2402
|
-
const src =
|
|
2403
|
-
const dest =
|
|
2558
|
+
const src = join9(sourceDir, name);
|
|
2559
|
+
const dest = join9(destDir, name);
|
|
2404
2560
|
if (!existsSync2(src)) {
|
|
2405
2561
|
throw new Error(`[review-poster] bundled asset missing: ${src}`);
|
|
2406
2562
|
}
|
|
2407
|
-
if (!existsSync2(dest) || !
|
|
2563
|
+
if (!existsSync2(dest) || !readFileSync9(src).equals(readFileSync9(dest))) {
|
|
2408
2564
|
copyFileSync2(src, dest);
|
|
2409
2565
|
}
|
|
2410
2566
|
chmodSync(dest, mode);
|
|
@@ -2413,7 +2569,7 @@ function provisionReviewPoster(codeName, sourceDir = resolveBundledReviewAssetDi
|
|
|
2413
2569
|
|
|
2414
2570
|
// src/lib/id-keyed-migration.ts
|
|
2415
2571
|
import { existsSync as existsSync3, lstatSync, readlinkSync, renameSync as renameSync2 } from "fs";
|
|
2416
|
-
import { join as
|
|
2572
|
+
import { join as join10 } from "path";
|
|
2417
2573
|
import { homedir as homedir3 } from "os";
|
|
2418
2574
|
var ID_KEYED_MIGRATION_FLAG = "id-keyed-layout-migration";
|
|
2419
2575
|
function agentHasActiveWhatsapp(channelConfigs, codeNameDir) {
|
|
@@ -2421,7 +2577,7 @@ function agentHasActiveWhatsapp(channelConfigs, codeNameDir) {
|
|
|
2421
2577
|
return true;
|
|
2422
2578
|
}
|
|
2423
2579
|
try {
|
|
2424
|
-
if (existsSync3(
|
|
2580
|
+
if (existsSync3(join10(codeNameDir, "whatsapp-pending-inbound"))) return true;
|
|
2425
2581
|
} catch {
|
|
2426
2582
|
}
|
|
2427
2583
|
return false;
|
|
@@ -2453,10 +2609,10 @@ function finishTranscriptMove(oldCwd, newCwd, codeName, log2) {
|
|
|
2453
2609
|
function maybeMigrateAgentToIdKeyedLayout(agent, deps) {
|
|
2454
2610
|
const home = deps.home ?? homedir3();
|
|
2455
2611
|
const { code_name: codeName, agent_id: agentId } = agent;
|
|
2456
|
-
const codeNamePath =
|
|
2457
|
-
const idPath =
|
|
2458
|
-
const oldCwd =
|
|
2459
|
-
const newCwd =
|
|
2612
|
+
const codeNamePath = join10(home, ".augmented", codeName);
|
|
2613
|
+
const idPath = join10(home, ".augmented", agentId);
|
|
2614
|
+
const oldCwd = join10(home, ".augmented", codeName, "project");
|
|
2615
|
+
const newCwd = join10(idPath, "project");
|
|
2460
2616
|
let codeNameKind;
|
|
2461
2617
|
try {
|
|
2462
2618
|
codeNameKind = lstatSync(codeNamePath).isSymbolicLink() ? "symlink" : "realdir";
|
|
@@ -2583,8 +2739,8 @@ function collectEnvGates(env) {
|
|
|
2583
2739
|
}
|
|
2584
2740
|
|
|
2585
2741
|
// ../../packages/core/dist/direct-chat/cursor-advance-telemetry.js
|
|
2586
|
-
import { readFileSync as
|
|
2587
|
-
import { join as
|
|
2742
|
+
import { readFileSync as readFileSync10, writeFileSync as writeFileSync5 } from "fs";
|
|
2743
|
+
import { join as join11 } from "path";
|
|
2588
2744
|
var CURSOR_SHORTFALL_COUNTER_SUFFIX = "-cursor-advance-classifications.json";
|
|
2589
2745
|
function recordCursorAdvanceOutcome(agentDir, source, route, verdict) {
|
|
2590
2746
|
if (!agentDir)
|
|
@@ -2592,10 +2748,10 @@ function recordCursorAdvanceOutcome(agentDir, source, route, verdict) {
|
|
|
2592
2748
|
const key = cursorAdvanceCounterKey(route, verdict);
|
|
2593
2749
|
if (key === null)
|
|
2594
2750
|
return;
|
|
2595
|
-
const path =
|
|
2751
|
+
const path = join11(agentDir, `${source}${CURSOR_SHORTFALL_COUNTER_SUFFIX}`);
|
|
2596
2752
|
const counts = {};
|
|
2597
2753
|
try {
|
|
2598
|
-
const parsed = JSON.parse(
|
|
2754
|
+
const parsed = JSON.parse(readFileSync10(path, "utf-8"));
|
|
2599
2755
|
if (parsed && typeof parsed === "object" && !Array.isArray(parsed)) {
|
|
2600
2756
|
for (const [k, v] of Object.entries(parsed)) {
|
|
2601
2757
|
if (typeof v === "number" && Number.isInteger(v) && v >= 0)
|
|
@@ -2612,7 +2768,7 @@ function recordCursorAdvanceOutcome(agentDir, source, route, verdict) {
|
|
|
2612
2768
|
}
|
|
2613
2769
|
|
|
2614
2770
|
// src/lib/artifact-stream.ts
|
|
2615
|
-
import { join as
|
|
2771
|
+
import { join as join12 } from "path";
|
|
2616
2772
|
import { homedir as homedir4 } from "os";
|
|
2617
2773
|
import { readdir, stat, readFile } from "fs/promises";
|
|
2618
2774
|
var ARTEFACT_ENTRY_FILE = "index.html";
|
|
@@ -2698,7 +2854,7 @@ var ArtifactStreamScanner = class {
|
|
|
2698
2854
|
return;
|
|
2699
2855
|
}
|
|
2700
2856
|
for (const name of names) {
|
|
2701
|
-
const file =
|
|
2857
|
+
const file = join12(this.artifactsDir, name, ARTEFACT_ENTRY_FILE);
|
|
2702
2858
|
const mtime = await this.fsDeps.mtimeMs(file).catch(() => null);
|
|
2703
2859
|
if (mtime === null) continue;
|
|
2704
2860
|
if (this.seenMtime.get(name) === mtime) continue;
|
|
@@ -2729,7 +2885,7 @@ var ArtifactStreamScanner = class {
|
|
|
2729
2885
|
}
|
|
2730
2886
|
};
|
|
2731
2887
|
function artifactsDirFor(codeName) {
|
|
2732
|
-
return
|
|
2888
|
+
return join12(homedir4(), ".augmented", codeName, "artifacts");
|
|
2733
2889
|
}
|
|
2734
2890
|
var nodeArtifactFs = {
|
|
2735
2891
|
async listArtefactNames(artifactsDir) {
|
|
@@ -3005,12 +3161,12 @@ async function maybePollHostUsage(deps) {
|
|
|
3005
3161
|
import { createHash as createHash6 } from "crypto";
|
|
3006
3162
|
import { readFile as readFile3, readdir as readdir3 } from "fs/promises";
|
|
3007
3163
|
import { homedir as homedir6, platform as platform2 } from "os";
|
|
3008
|
-
import { dirname as dirname6, join as
|
|
3164
|
+
import { dirname as dirname6, join as join14 } from "path";
|
|
3009
3165
|
|
|
3010
3166
|
// src/lib/claude-auth-detect.ts
|
|
3011
3167
|
import { readFile as readFile2, readdir as readdir2 } from "fs/promises";
|
|
3012
3168
|
import { homedir as homedir5, platform } from "os";
|
|
3013
|
-
import { join as
|
|
3169
|
+
import { join as join13 } from "path";
|
|
3014
3170
|
import { execFile } from "child_process";
|
|
3015
3171
|
import { promisify } from "util";
|
|
3016
3172
|
var execFileAsync = promisify(execFile);
|
|
@@ -3025,16 +3181,16 @@ async function detectClaudeAuth() {
|
|
|
3025
3181
|
}
|
|
3026
3182
|
async function findClaudeCredentialsPaths() {
|
|
3027
3183
|
const candidates = [
|
|
3028
|
-
|
|
3029
|
-
|
|
3184
|
+
join13(homedir5(), ".claude", ".credentials.json"),
|
|
3185
|
+
join13(homedir5(), ".claude", "credentials.json")
|
|
3030
3186
|
];
|
|
3031
3187
|
const isLinuxRoot = platform() === "linux" && typeof process.getuid === "function" && process.getuid() === 0;
|
|
3032
3188
|
if (isLinuxRoot) {
|
|
3033
3189
|
try {
|
|
3034
3190
|
const entries = await readdir2("/home", { withFileTypes: true });
|
|
3035
3191
|
for (const entry of entries.filter((entry2) => entry2.isDirectory()).sort((a, b) => a.name.localeCompare(b.name))) {
|
|
3036
|
-
candidates.push(
|
|
3037
|
-
candidates.push(
|
|
3192
|
+
candidates.push(join13("/home", entry.name, ".claude", ".credentials.json"));
|
|
3193
|
+
candidates.push(join13("/home", entry.name, ".claude", "credentials.json"));
|
|
3038
3194
|
}
|
|
3039
3195
|
} catch {
|
|
3040
3196
|
}
|
|
@@ -3118,7 +3274,7 @@ async function candidateHomes() {
|
|
|
3118
3274
|
try {
|
|
3119
3275
|
const entries = await readdir3("/home", { withFileTypes: true });
|
|
3120
3276
|
for (const entry of entries.filter((e) => e.isDirectory()).sort((a, b) => a.name.localeCompare(b.name))) {
|
|
3121
|
-
homes.push(
|
|
3277
|
+
homes.push(join14("/home", entry.name));
|
|
3122
3278
|
}
|
|
3123
3279
|
} catch {
|
|
3124
3280
|
}
|
|
@@ -3138,11 +3294,11 @@ async function homeOfActiveCredentials() {
|
|
|
3138
3294
|
async function claudeConfigCandidatePaths() {
|
|
3139
3295
|
const paths = [];
|
|
3140
3296
|
const configDir = process.env["CLAUDE_CONFIG_DIR"]?.trim();
|
|
3141
|
-
if (configDir) paths.push(
|
|
3297
|
+
if (configDir) paths.push(join14(configDir, ".claude.json"));
|
|
3142
3298
|
const activeHome = await homeOfActiveCredentials();
|
|
3143
|
-
if (activeHome) paths.push(
|
|
3299
|
+
if (activeHome) paths.push(join14(activeHome, ".claude.json"));
|
|
3144
3300
|
for (const home of await candidateHomes()) {
|
|
3145
|
-
const path =
|
|
3301
|
+
const path = join14(home, ".claude.json");
|
|
3146
3302
|
if (!paths.includes(path)) paths.push(path);
|
|
3147
3303
|
}
|
|
3148
3304
|
return paths;
|
|
@@ -3261,9 +3417,9 @@ function diffAuthTuples(recorded, current) {
|
|
|
3261
3417
|
// src/lib/account-enforcement-marker.ts
|
|
3262
3418
|
import { mkdirSync as mkdirSync5, renameSync as renameSync3, rmSync as rmSync2, writeFileSync as writeFileSync6 } from "fs";
|
|
3263
3419
|
import { homedir as homedir7 } from "os";
|
|
3264
|
-
import { join as
|
|
3420
|
+
import { join as join15 } from "path";
|
|
3265
3421
|
function accountEnforcementMarkerPath(codeName) {
|
|
3266
|
-
return
|
|
3422
|
+
return join15(homedir7(), ".augmented", codeName, ACCOUNT_ENFORCEMENT_MARKER_FILENAME);
|
|
3267
3423
|
}
|
|
3268
3424
|
function syncAccountEnforcementMarker(codeName, level, log2 = (m) => process.stderr.write(`${m}
|
|
3269
3425
|
`), text) {
|
|
@@ -3271,8 +3427,8 @@ function syncAccountEnforcementMarker(codeName, level, log2 = (m) => process.std
|
|
|
3271
3427
|
clearAccountEnforcementMarker(codeName, log2);
|
|
3272
3428
|
return;
|
|
3273
3429
|
}
|
|
3274
|
-
const dir =
|
|
3275
|
-
const path =
|
|
3430
|
+
const dir = join15(homedir7(), ".augmented", codeName);
|
|
3431
|
+
const path = join15(dir, ACCOUNT_ENFORCEMENT_MARKER_FILENAME);
|
|
3276
3432
|
const tempPath = `${path}.${process.pid}.tmp`;
|
|
3277
3433
|
try {
|
|
3278
3434
|
mkdirSync5(dir, { recursive: true });
|
|
@@ -3297,8 +3453,8 @@ function clearAccountEnforcementMarker(codeName, log2 = (m) => process.stderr.wr
|
|
|
3297
3453
|
}
|
|
3298
3454
|
|
|
3299
3455
|
// src/lib/token-usage-monitor.ts
|
|
3300
|
-
import { readdirSync, readFileSync as
|
|
3301
|
-
import { join as
|
|
3456
|
+
import { readdirSync, readFileSync as readFileSync11, statSync } from "fs";
|
|
3457
|
+
import { join as join16 } from "path";
|
|
3302
3458
|
var MIN_CHECK_INTERVAL_MS2 = 6e4;
|
|
3303
3459
|
var TRANSCRIPT_MTIME_WINDOW_MS = 2 * 24 * 60 * 60 * 1e3;
|
|
3304
3460
|
var MAX_ENTRIES_PER_POST = 200;
|
|
@@ -3327,7 +3483,7 @@ async function maybeReportTokenUsage(args) {
|
|
|
3327
3483
|
if (!name.endsWith(".jsonl")) continue;
|
|
3328
3484
|
const sessionId = name.slice(0, -".jsonl".length);
|
|
3329
3485
|
if (!sessionId) continue;
|
|
3330
|
-
const path =
|
|
3486
|
+
const path = join16(dir, name);
|
|
3331
3487
|
let st;
|
|
3332
3488
|
try {
|
|
3333
3489
|
st = statSync(path);
|
|
@@ -3343,7 +3499,7 @@ async function maybeReportTokenUsage(args) {
|
|
|
3343
3499
|
}
|
|
3344
3500
|
let content;
|
|
3345
3501
|
try {
|
|
3346
|
-
content =
|
|
3502
|
+
content = readFileSync11(path, "utf-8");
|
|
3347
3503
|
} catch (err) {
|
|
3348
3504
|
log2(`[token-usage] read failed for '${codeName}/${name}': ${err.message}`);
|
|
3349
3505
|
continue;
|
|
@@ -3424,8 +3580,8 @@ async function maybeReportTokenUsage(args) {
|
|
|
3424
3580
|
}
|
|
3425
3581
|
|
|
3426
3582
|
// src/lib/workflow-run-reconciler.ts
|
|
3427
|
-
import { readdirSync as readdirSync2, readFileSync as
|
|
3428
|
-
import { join as
|
|
3583
|
+
import { readdirSync as readdirSync2, readFileSync as readFileSync12, statSync as statSync2 } from "fs";
|
|
3584
|
+
import { join as join17 } from "path";
|
|
3429
3585
|
var MIN_CHECK_INTERVAL_MS3 = 5 * 6e4;
|
|
3430
3586
|
var SETTLE_MS = 3e4;
|
|
3431
3587
|
var TRANSCRIPT_MTIME_WINDOW_MS2 = 2 * 24 * 60 * 60 * 1e3;
|
|
@@ -3444,7 +3600,7 @@ function collectJsonlRecursive(dir, minMtimeMs, out, depth) {
|
|
|
3444
3600
|
return;
|
|
3445
3601
|
}
|
|
3446
3602
|
for (const name of entries) {
|
|
3447
|
-
const p =
|
|
3603
|
+
const p = join17(dir, name);
|
|
3448
3604
|
let st;
|
|
3449
3605
|
try {
|
|
3450
3606
|
st = statSync2(p);
|
|
@@ -3467,7 +3623,7 @@ function enumerateTranscriptFiles(transcriptDir, nowMs, minMtimeMs = nowMs - TRA
|
|
|
3467
3623
|
return out;
|
|
3468
3624
|
}
|
|
3469
3625
|
for (const name of entries) {
|
|
3470
|
-
const path =
|
|
3626
|
+
const path = join17(transcriptDir, name);
|
|
3471
3627
|
let st;
|
|
3472
3628
|
try {
|
|
3473
3629
|
st = statSync2(path);
|
|
@@ -3479,7 +3635,7 @@ function enumerateTranscriptFiles(transcriptDir, nowMs, minMtimeMs = nowMs - TRA
|
|
|
3479
3635
|
continue;
|
|
3480
3636
|
}
|
|
3481
3637
|
if (st.isDirectory()) {
|
|
3482
|
-
collectJsonlRecursive(
|
|
3638
|
+
collectJsonlRecursive(join17(path, "subagents"), minMtimeMs, out, 0);
|
|
3483
3639
|
}
|
|
3484
3640
|
}
|
|
3485
3641
|
return out;
|
|
@@ -3524,7 +3680,7 @@ async function maybeReconcileWorkflowRunTokens(args) {
|
|
|
3524
3680
|
const contents = [];
|
|
3525
3681
|
for (const path of files) {
|
|
3526
3682
|
try {
|
|
3527
|
-
contents.push(
|
|
3683
|
+
contents.push(readFileSync12(path, "utf-8"));
|
|
3528
3684
|
} catch {
|
|
3529
3685
|
}
|
|
3530
3686
|
}
|
|
@@ -3569,8 +3725,8 @@ async function maybeReconcileWorkflowRunTokens(args) {
|
|
|
3569
3725
|
}
|
|
3570
3726
|
|
|
3571
3727
|
// src/lib/conversation-evaluator.ts
|
|
3572
|
-
import { readdirSync as readdirSync3, readFileSync as
|
|
3573
|
-
import { join as
|
|
3728
|
+
import { readdirSync as readdirSync3, readFileSync as readFileSync13, statSync as statSync3 } from "fs";
|
|
3729
|
+
import { join as join18 } from "path";
|
|
3574
3730
|
|
|
3575
3731
|
// src/lib/detect-meta-egress.ts
|
|
3576
3732
|
var REPOST_PREAMBLE_WINDOW = 200;
|
|
@@ -4055,7 +4211,7 @@ function readRecentTurns(dir, nowMs) {
|
|
|
4055
4211
|
return;
|
|
4056
4212
|
}
|
|
4057
4213
|
for (const ent of entries) {
|
|
4058
|
-
const full =
|
|
4214
|
+
const full = join18(d, ent.name);
|
|
4059
4215
|
if (ent.isDirectory()) {
|
|
4060
4216
|
visit(full);
|
|
4061
4217
|
continue;
|
|
@@ -4070,7 +4226,7 @@ function readRecentTurns(dir, nowMs) {
|
|
|
4070
4226
|
if (nowMs - mtimeMs > TRANSCRIPT_MTIME_WINDOW_MS3) continue;
|
|
4071
4227
|
let content;
|
|
4072
4228
|
try {
|
|
4073
|
-
content =
|
|
4229
|
+
content = readFileSync13(full, "utf8");
|
|
4074
4230
|
} catch {
|
|
4075
4231
|
continue;
|
|
4076
4232
|
}
|
|
@@ -4443,22 +4599,22 @@ async function reportSkip2(api2, agentId, conversationId, log2, codeName) {
|
|
|
4443
4599
|
|
|
4444
4600
|
// src/lib/tool-call-audit.ts
|
|
4445
4601
|
import { homedir as homedir11 } from "os";
|
|
4446
|
-
import { join as
|
|
4602
|
+
import { join as join23 } from "path";
|
|
4447
4603
|
|
|
4448
4604
|
// src/lib/agent-logging-mode.ts
|
|
4449
|
-
import { readFileSync as
|
|
4605
|
+
import { readFileSync as readFileSync14 } from "fs";
|
|
4450
4606
|
import { homedir as homedir8 } from "os";
|
|
4451
|
-
import { join as
|
|
4607
|
+
import { join as join19 } from "path";
|
|
4452
4608
|
var LOGGING_MODES = ["hash-only", "redacted", "full-local"];
|
|
4453
4609
|
function charterPath(codeName, homeDir) {
|
|
4454
4610
|
const home = homeDir ?? (process.env["HOME"]?.trim() || homedir8());
|
|
4455
4611
|
const key = agentRuntimeKey(codeName, homeDir);
|
|
4456
|
-
return
|
|
4612
|
+
return join19(home, ".augmented", key, "provision", "CHARTER.md");
|
|
4457
4613
|
}
|
|
4458
4614
|
function readAgentLoggingMode(codeName, homeDir) {
|
|
4459
4615
|
let raw;
|
|
4460
4616
|
try {
|
|
4461
|
-
raw =
|
|
4617
|
+
raw = readFileSync14(charterPath(codeName, homeDir), "utf-8");
|
|
4462
4618
|
} catch {
|
|
4463
4619
|
return { mode: null, reason: "no-charter" };
|
|
4464
4620
|
}
|
|
@@ -4482,15 +4638,15 @@ function loggingModeWithholdsTargets(reading) {
|
|
|
4482
4638
|
|
|
4483
4639
|
// src/lib/tool-call-path-salt.ts
|
|
4484
4640
|
import { randomBytes } from "crypto";
|
|
4485
|
-
import { existsSync as existsSync4, mkdirSync as mkdirSync6, readFileSync as
|
|
4641
|
+
import { existsSync as existsSync4, mkdirSync as mkdirSync6, readFileSync as readFileSync15, renameSync as renameSync4, unlinkSync as unlinkSync2, writeFileSync as writeFileSync7 } from "fs";
|
|
4486
4642
|
import { homedir as homedir9 } from "os";
|
|
4487
|
-
import { dirname as dirname7, join as
|
|
4643
|
+
import { dirname as dirname7, join as join20 } from "path";
|
|
4488
4644
|
var SALT_BYTES = 32;
|
|
4489
4645
|
var SALT_RE = /^[0-9a-f]{64}$/;
|
|
4490
4646
|
function pathSaltPath(codeName, homeDir) {
|
|
4491
4647
|
const home = homeDir ?? (process.env["HOME"]?.trim() || homedir9());
|
|
4492
4648
|
const key = agentRuntimeKey(codeName, homeDir);
|
|
4493
|
-
return
|
|
4649
|
+
return join20(home, ".augmented", key, "tool-call-path-salt");
|
|
4494
4650
|
}
|
|
4495
4651
|
function readToolCallPathSalt(codeName, homeDir) {
|
|
4496
4652
|
let file;
|
|
@@ -4501,7 +4657,7 @@ function readToolCallPathSalt(codeName, homeDir) {
|
|
|
4501
4657
|
}
|
|
4502
4658
|
try {
|
|
4503
4659
|
if (existsSync4(file)) {
|
|
4504
|
-
const existing =
|
|
4660
|
+
const existing = readFileSync15(file, "utf-8").trim();
|
|
4505
4661
|
if (SALT_RE.test(existing)) return existing;
|
|
4506
4662
|
}
|
|
4507
4663
|
} catch {
|
|
@@ -4527,8 +4683,8 @@ function readToolCallPathSalt(codeName, homeDir) {
|
|
|
4527
4683
|
import { statSync as statSync4 } from "fs";
|
|
4528
4684
|
|
|
4529
4685
|
// src/lib/tool-call-extractor.ts
|
|
4530
|
-
import { closeSync, fstatSync, openSync, readFileSync as
|
|
4531
|
-
import { basename as basename2, join as
|
|
4686
|
+
import { closeSync, fstatSync, openSync, readFileSync as readFileSync16, readSync, readdirSync as readdirSync4 } from "fs";
|
|
4687
|
+
import { basename as basename2, join as join21, relative } from "path";
|
|
4532
4688
|
import { StringDecoder } from "string_decoder";
|
|
4533
4689
|
|
|
4534
4690
|
// src/lib/tool-call-redaction.ts
|
|
@@ -4657,7 +4813,7 @@ function redactToolTargetInner(toolName, input, ctx) {
|
|
|
4657
4813
|
var EXTRACTOR_VERSION = "e1";
|
|
4658
4814
|
function enumerateSessionTranscripts(transcriptDir, sessionId, projectsRoot) {
|
|
4659
4815
|
const files = [];
|
|
4660
|
-
const mainAbs =
|
|
4816
|
+
const mainAbs = join21(transcriptDir, `${sessionId}.jsonl`);
|
|
4661
4817
|
files.push({
|
|
4662
4818
|
absPath: mainAbs,
|
|
4663
4819
|
relPath: relative(projectsRoot, mainAbs),
|
|
@@ -4665,7 +4821,7 @@ function enumerateSessionTranscripts(transcriptDir, sessionId, projectsRoot) {
|
|
|
4665
4821
|
isSubagent: false,
|
|
4666
4822
|
subagentId: null
|
|
4667
4823
|
});
|
|
4668
|
-
const subDir =
|
|
4824
|
+
const subDir = join21(transcriptDir, sessionId, "subagents");
|
|
4669
4825
|
let entries;
|
|
4670
4826
|
try {
|
|
4671
4827
|
entries = readdirSync4(subDir);
|
|
@@ -4674,7 +4830,7 @@ function enumerateSessionTranscripts(transcriptDir, sessionId, projectsRoot) {
|
|
|
4674
4830
|
}
|
|
4675
4831
|
for (const name of entries) {
|
|
4676
4832
|
if (!name.endsWith(".jsonl")) continue;
|
|
4677
|
-
const abs =
|
|
4833
|
+
const abs = join21(subDir, name);
|
|
4678
4834
|
const stem = basename2(name, ".jsonl");
|
|
4679
4835
|
files.push({
|
|
4680
4836
|
absPath: abs,
|
|
@@ -4872,9 +5028,9 @@ function extractTranscriptWindow(file, opts, from) {
|
|
|
4872
5028
|
}
|
|
4873
5029
|
|
|
4874
5030
|
// src/lib/tool-call-cursor.ts
|
|
4875
|
-
import { existsSync as existsSync5, readFileSync as
|
|
5031
|
+
import { existsSync as existsSync5, readFileSync as readFileSync17 } from "fs";
|
|
4876
5032
|
import { homedir as homedir10 } from "os";
|
|
4877
|
-
import { join as
|
|
5033
|
+
import { join as join22 } from "path";
|
|
4878
5034
|
var COVERAGE_DISPOSITIONS = [
|
|
4879
5035
|
"ok",
|
|
4880
5036
|
"not_entitled",
|
|
@@ -4929,13 +5085,13 @@ function parseCursorKey(key) {
|
|
|
4929
5085
|
function cursorStatePath(codeName, homeDir) {
|
|
4930
5086
|
const home = homeDir ?? (process.env["HOME"]?.trim() || homedir10());
|
|
4931
5087
|
const key = agentRuntimeKey(codeName, homeDir);
|
|
4932
|
-
return
|
|
5088
|
+
return join22(home, ".augmented", key, "tool-call-cursors.json");
|
|
4933
5089
|
}
|
|
4934
5090
|
function loadCursors(path) {
|
|
4935
5091
|
const out = /* @__PURE__ */ new Map();
|
|
4936
5092
|
if (!existsSync5(path)) return out;
|
|
4937
5093
|
try {
|
|
4938
|
-
const parsed = JSON.parse(
|
|
5094
|
+
const parsed = JSON.parse(readFileSync17(path, "utf-8"));
|
|
4939
5095
|
if (!parsed || parsed.version !== 1 || typeof parsed.files !== "object") return out;
|
|
4940
5096
|
for (const [k, v] of Object.entries(parsed.files)) {
|
|
4941
5097
|
if (!v || typeof v !== "object") continue;
|
|
@@ -5342,7 +5498,7 @@ async function maybeScanToolCalls(args) {
|
|
|
5342
5498
|
log2(`[tool-call-audit] ${codeName}: no path-hash salt available \u2014 file targets withheld`);
|
|
5343
5499
|
}
|
|
5344
5500
|
const home = args.homeDir ?? (process.env["HOME"]?.trim() || homedir11());
|
|
5345
|
-
const projectsRoot = args.projectsRoot ??
|
|
5501
|
+
const projectsRoot = args.projectsRoot ?? join23(home, ".claude", "projects");
|
|
5346
5502
|
const transcriptDir = args.transcriptDir ?? sessionTranscriptDir(getProjectDir(codeName));
|
|
5347
5503
|
const current = peekCurrentSession(codeName);
|
|
5348
5504
|
const sessionIds = current ? [current.sessionId] : [];
|
|
@@ -5371,11 +5527,11 @@ async function maybeScanToolCalls(args) {
|
|
|
5371
5527
|
}
|
|
5372
5528
|
|
|
5373
5529
|
// src/lib/activity-cache-monitor.ts
|
|
5374
|
-
import { existsSync as existsSync6, readFileSync as
|
|
5530
|
+
import { existsSync as existsSync6, readFileSync as readFileSync18 } from "fs";
|
|
5375
5531
|
import { homedir as homedir12 } from "os";
|
|
5376
|
-
import { join as
|
|
5532
|
+
import { join as join24 } from "path";
|
|
5377
5533
|
var MIN_CHECK_INTERVAL_MS7 = 6e4;
|
|
5378
|
-
var STATS_CACHE_PATH =
|
|
5534
|
+
var STATS_CACHE_PATH = join24(homedir12(), ".claude", "stats-cache.json");
|
|
5379
5535
|
var ISO_DATE_RE = /^\d{4}-\d{2}-\d{2}$/;
|
|
5380
5536
|
var state7 = { lastObservedDate: null, lastCheckedAt: 0 };
|
|
5381
5537
|
function selectNewDailyRows(raw, lastObservedDate) {
|
|
@@ -5423,7 +5579,7 @@ async function maybeReportActivityCache(args) {
|
|
|
5423
5579
|
}
|
|
5424
5580
|
let raw;
|
|
5425
5581
|
try {
|
|
5426
|
-
raw =
|
|
5582
|
+
raw = readFileSync18(STATS_CACHE_PATH, "utf-8");
|
|
5427
5583
|
} catch (err) {
|
|
5428
5584
|
log2(`[activity-cache] readFileSync failed: ${err.message}`);
|
|
5429
5585
|
return;
|
|
@@ -5726,7 +5882,7 @@ import { createHash as createHash9 } from "crypto";
|
|
|
5726
5882
|
import {
|
|
5727
5883
|
existsSync as existsSync7,
|
|
5728
5884
|
mkdirSync as mkdirSync7,
|
|
5729
|
-
readFileSync as
|
|
5885
|
+
readFileSync as readFileSync19,
|
|
5730
5886
|
readdirSync as readdirSync5,
|
|
5731
5887
|
renameSync as renameSync5,
|
|
5732
5888
|
rmSync as rmSync3,
|
|
@@ -5734,7 +5890,7 @@ import {
|
|
|
5734
5890
|
utimesSync,
|
|
5735
5891
|
writeFileSync as writeFileSync8
|
|
5736
5892
|
} from "fs";
|
|
5737
|
-
import { join as
|
|
5893
|
+
import { join as join25 } from "path";
|
|
5738
5894
|
var KNOWLEDGE_FETCH_CHUNK = 100;
|
|
5739
5895
|
var CACHE_TTL_MS = 30 * 24 * 60 * 60 * 1e3;
|
|
5740
5896
|
var SWEEP_INTERVAL_MS = 24 * 60 * 60 * 1e3;
|
|
@@ -5743,12 +5899,12 @@ function knowledgeHash(content) {
|
|
|
5743
5899
|
return createHash9("sha256").update(content, "utf8").digest("hex");
|
|
5744
5900
|
}
|
|
5745
5901
|
function cachePath(cacheDir, hash) {
|
|
5746
|
-
return
|
|
5902
|
+
return join25(cacheDir, hash);
|
|
5747
5903
|
}
|
|
5748
5904
|
function readCachedKnowledge(cacheDir, hash) {
|
|
5749
5905
|
const path = cachePath(cacheDir, hash);
|
|
5750
5906
|
try {
|
|
5751
|
-
const content =
|
|
5907
|
+
const content = readFileSync19(path, "utf-8");
|
|
5752
5908
|
try {
|
|
5753
5909
|
const now = /* @__PURE__ */ new Date();
|
|
5754
5910
|
utimesSync(path, now, now);
|
|
@@ -5777,7 +5933,7 @@ function sweepKnowledgeCache(cacheDir, now = Date.now()) {
|
|
|
5777
5933
|
try {
|
|
5778
5934
|
if (!existsSync7(cacheDir)) return;
|
|
5779
5935
|
for (const name of readdirSync5(cacheDir)) {
|
|
5780
|
-
const path =
|
|
5936
|
+
const path = join25(cacheDir, name);
|
|
5781
5937
|
try {
|
|
5782
5938
|
if (now - statSync6(path).mtimeMs > CACHE_TTL_MS) rmSync3(path, { force: true });
|
|
5783
5939
|
} catch {
|
|
@@ -5829,7 +5985,7 @@ import { createHash as createHash10 } from "crypto";
|
|
|
5829
5985
|
import {
|
|
5830
5986
|
existsSync as existsSync8,
|
|
5831
5987
|
mkdirSync as mkdirSync8,
|
|
5832
|
-
readFileSync as
|
|
5988
|
+
readFileSync as readFileSync20,
|
|
5833
5989
|
readdirSync as readdirSync6,
|
|
5834
5990
|
renameSync as renameSync6,
|
|
5835
5991
|
rmSync as rmSync4,
|
|
@@ -5837,7 +5993,7 @@ import {
|
|
|
5837
5993
|
utimesSync as utimesSync2,
|
|
5838
5994
|
writeFileSync as writeFileSync9
|
|
5839
5995
|
} from "fs";
|
|
5840
|
-
import { join as
|
|
5996
|
+
import { join as join26 } from "path";
|
|
5841
5997
|
var MEMORY_FETCH_CHUNK = 100;
|
|
5842
5998
|
var CACHE_TTL_MS2 = 30 * 24 * 60 * 60 * 1e3;
|
|
5843
5999
|
var SWEEP_INTERVAL_MS2 = 24 * 60 * 60 * 1e3;
|
|
@@ -5846,12 +6002,12 @@ function memoryHash(content) {
|
|
|
5846
6002
|
return createHash10("sha256").update(content, "utf8").digest("hex");
|
|
5847
6003
|
}
|
|
5848
6004
|
function cachePath2(cacheDir, hash) {
|
|
5849
|
-
return
|
|
6005
|
+
return join26(cacheDir, hash);
|
|
5850
6006
|
}
|
|
5851
6007
|
function readCachedMemory(cacheDir, hash) {
|
|
5852
6008
|
const path = cachePath2(cacheDir, hash);
|
|
5853
6009
|
try {
|
|
5854
|
-
const content =
|
|
6010
|
+
const content = readFileSync20(path, "utf-8");
|
|
5855
6011
|
try {
|
|
5856
6012
|
const now = /* @__PURE__ */ new Date();
|
|
5857
6013
|
utimesSync2(path, now, now);
|
|
@@ -5880,7 +6036,7 @@ function sweepMemoryCache(cacheDir, now = Date.now()) {
|
|
|
5880
6036
|
try {
|
|
5881
6037
|
if (!existsSync8(cacheDir)) return;
|
|
5882
6038
|
for (const name of readdirSync6(cacheDir)) {
|
|
5883
|
-
const path =
|
|
6039
|
+
const path = join26(cacheDir, name);
|
|
5884
6040
|
try {
|
|
5885
6041
|
if (now - statSync7(path).mtimeMs > CACHE_TTL_MS2) rmSync4(path, { force: true });
|
|
5886
6042
|
} catch {
|
|
@@ -5938,7 +6094,7 @@ import { createHash as createHash11 } from "crypto";
|
|
|
5938
6094
|
import {
|
|
5939
6095
|
existsSync as existsSync9,
|
|
5940
6096
|
mkdirSync as mkdirSync9,
|
|
5941
|
-
readFileSync as
|
|
6097
|
+
readFileSync as readFileSync21,
|
|
5942
6098
|
readdirSync as readdirSync7,
|
|
5943
6099
|
renameSync as renameSync7,
|
|
5944
6100
|
rmSync as rmSync5,
|
|
@@ -5946,7 +6102,7 @@ import {
|
|
|
5946
6102
|
utimesSync as utimesSync3,
|
|
5947
6103
|
writeFileSync as writeFileSync10
|
|
5948
6104
|
} from "fs";
|
|
5949
|
-
import { join as
|
|
6105
|
+
import { join as join27 } from "path";
|
|
5950
6106
|
var SKILL_FETCH_CHUNK = 100;
|
|
5951
6107
|
var CACHE_TTL_MS3 = 30 * 24 * 60 * 60 * 1e3;
|
|
5952
6108
|
var SWEEP_INTERVAL_MS3 = 24 * 60 * 60 * 1e3;
|
|
@@ -5955,12 +6111,12 @@ function skillHash(content) {
|
|
|
5955
6111
|
return createHash11("sha256").update(content, "utf8").digest("hex");
|
|
5956
6112
|
}
|
|
5957
6113
|
function cachePath3(cacheDir, hash) {
|
|
5958
|
-
return
|
|
6114
|
+
return join27(cacheDir, hash);
|
|
5959
6115
|
}
|
|
5960
6116
|
function readCachedSkill(cacheDir, hash) {
|
|
5961
6117
|
const path = cachePath3(cacheDir, hash);
|
|
5962
6118
|
try {
|
|
5963
|
-
const content =
|
|
6119
|
+
const content = readFileSync21(path, "utf-8");
|
|
5964
6120
|
try {
|
|
5965
6121
|
const now = /* @__PURE__ */ new Date();
|
|
5966
6122
|
utimesSync3(path, now, now);
|
|
@@ -5989,7 +6145,7 @@ function sweepSkillCache(cacheDir, now = Date.now()) {
|
|
|
5989
6145
|
try {
|
|
5990
6146
|
if (!existsSync9(cacheDir)) return;
|
|
5991
6147
|
for (const name of readdirSync7(cacheDir)) {
|
|
5992
|
-
const path =
|
|
6148
|
+
const path = join27(cacheDir, name);
|
|
5993
6149
|
try {
|
|
5994
6150
|
if (now - statSync8(path).mtimeMs > CACHE_TTL_MS3) rmSync5(path, { force: true });
|
|
5995
6151
|
} catch {
|
|
@@ -6276,18 +6432,18 @@ function resolveConditionalResponse(wire, hasCachedBody) {
|
|
|
6276
6432
|
}
|
|
6277
6433
|
|
|
6278
6434
|
// src/lib/channel-hash-cache.ts
|
|
6279
|
-
import { existsSync as existsSync10, readFileSync as
|
|
6280
|
-
import { join as
|
|
6435
|
+
import { existsSync as existsSync10, readFileSync as readFileSync22, writeFileSync as writeFileSync11 } from "fs";
|
|
6436
|
+
import { join as join28 } from "path";
|
|
6281
6437
|
var CACHE_FILENAME = "channel-hash-cache.json";
|
|
6282
6438
|
function getChannelHashCacheFile(configDir) {
|
|
6283
|
-
return
|
|
6439
|
+
return join28(configDir, CACHE_FILENAME);
|
|
6284
6440
|
}
|
|
6285
6441
|
function loadChannelHashCache(target, configDir) {
|
|
6286
6442
|
const path = getChannelHashCacheFile(configDir);
|
|
6287
6443
|
if (!existsSync10(path)) return;
|
|
6288
6444
|
let parsed;
|
|
6289
6445
|
try {
|
|
6290
|
-
parsed = JSON.parse(
|
|
6446
|
+
parsed = JSON.parse(readFileSync22(path, "utf-8"));
|
|
6291
6447
|
} catch {
|
|
6292
6448
|
return;
|
|
6293
6449
|
}
|
|
@@ -6307,8 +6463,8 @@ function saveChannelHashCache(source, configDir) {
|
|
|
6307
6463
|
}
|
|
6308
6464
|
|
|
6309
6465
|
// src/lib/sender-policy-baseline.ts
|
|
6310
|
-
import { existsSync as existsSync11, readFileSync as
|
|
6311
|
-
import { join as
|
|
6466
|
+
import { existsSync as existsSync11, readFileSync as readFileSync23 } from "fs";
|
|
6467
|
+
import { join as join29 } from "path";
|
|
6312
6468
|
var BASELINE_FILENAME = "sender-policy-baseline.json";
|
|
6313
6469
|
var SENDER_POLICY_BASELINE_VERSION = 1;
|
|
6314
6470
|
var BASELINE_CONCERNS = [
|
|
@@ -6346,14 +6502,14 @@ function createDeliveryBaselineMaps() {
|
|
|
6346
6502
|
};
|
|
6347
6503
|
}
|
|
6348
6504
|
function getSenderPolicyBaselineFile(configDir) {
|
|
6349
|
-
return
|
|
6505
|
+
return join29(configDir, BASELINE_FILENAME);
|
|
6350
6506
|
}
|
|
6351
6507
|
function loadSenderPolicyBaseline(target, configDir, log2) {
|
|
6352
6508
|
const path = getSenderPolicyBaselineFile(configDir);
|
|
6353
6509
|
if (!existsSync11(path)) return;
|
|
6354
6510
|
let parsed;
|
|
6355
6511
|
try {
|
|
6356
|
-
parsed = JSON.parse(
|
|
6512
|
+
parsed = JSON.parse(readFileSync23(path, "utf-8"));
|
|
6357
6513
|
} catch (err) {
|
|
6358
6514
|
log2?.(
|
|
6359
6515
|
`[sender-policy] discarding corrupt ${BASELINE_FILENAME} (${err.message}) - restrictive-policy agents will take one fail-closed restart`
|
|
@@ -6402,8 +6558,8 @@ function saveSenderPolicyBaseline(source, configDir, log2) {
|
|
|
6402
6558
|
}
|
|
6403
6559
|
|
|
6404
6560
|
// src/lib/stuck-streak-store.ts
|
|
6405
|
-
import { existsSync as existsSync12, readFileSync as
|
|
6406
|
-
import { join as
|
|
6561
|
+
import { existsSync as existsSync12, readFileSync as readFileSync24 } from "fs";
|
|
6562
|
+
import { join as join30 } from "path";
|
|
6407
6563
|
var STORE_FILENAME = "stuck-streaks.json";
|
|
6408
6564
|
var STUCK_STREAK_STORE_VERSION = 1;
|
|
6409
6565
|
var STUCK_STREAK_CONCERNS = ["channelSync", "realtimeRebind"];
|
|
@@ -6411,7 +6567,7 @@ function createStuckStreakMaps() {
|
|
|
6411
6567
|
return { channelSync: /* @__PURE__ */ new Map(), realtimeRebind: /* @__PURE__ */ new Map() };
|
|
6412
6568
|
}
|
|
6413
6569
|
function getStuckStreakStoreFile(configDir) {
|
|
6414
|
-
return
|
|
6570
|
+
return join30(configDir, STORE_FILENAME);
|
|
6415
6571
|
}
|
|
6416
6572
|
function isValidPersistedStreak(value) {
|
|
6417
6573
|
if (!value || typeof value !== "object" || Array.isArray(value)) return false;
|
|
@@ -6453,7 +6609,7 @@ function loadStuckStreaks(target, configDir, log2) {
|
|
|
6453
6609
|
if (!existsSync12(path)) return;
|
|
6454
6610
|
let parsed;
|
|
6455
6611
|
try {
|
|
6456
|
-
parsed = JSON.parse(
|
|
6612
|
+
parsed = JSON.parse(readFileSync24(path, "utf-8"));
|
|
6457
6613
|
} catch (err) {
|
|
6458
6614
|
log2?.(
|
|
6459
6615
|
`[stuck-streaks] discarding corrupt ${STORE_FILENAME} (${err.message}) \u2014 stuck-streak ages restart from zero and one spurious "recovered" close may follow`
|
|
@@ -6496,11 +6652,9 @@ function pruneStuckStreaksToAgents(maps, activeAgentIds) {
|
|
|
6496
6652
|
}
|
|
6497
6653
|
|
|
6498
6654
|
// src/lib/claude-device-state.ts
|
|
6499
|
-
import { readFileSync as
|
|
6500
|
-
import { homedir as homedir13 } from "os";
|
|
6501
|
-
import { join as join30 } from "path";
|
|
6655
|
+
import { readFileSync as readFileSync25, statSync as statSync9 } from "fs";
|
|
6502
6656
|
function claudeDeviceStatePath(env = process.env) {
|
|
6503
|
-
return
|
|
6657
|
+
return effectiveClaudeJsonPath(void 0, env);
|
|
6504
6658
|
}
|
|
6505
6659
|
function probeClaudeDeviceStatePresence(path = claudeDeviceStatePath()) {
|
|
6506
6660
|
try {
|
|
@@ -6523,7 +6677,7 @@ function checkClaudeDeviceState(path = claudeDeviceStatePath()) {
|
|
|
6523
6677
|
}
|
|
6524
6678
|
let raw;
|
|
6525
6679
|
try {
|
|
6526
|
-
raw =
|
|
6680
|
+
raw = readFileSync25(path, "utf-8");
|
|
6527
6681
|
} catch {
|
|
6528
6682
|
return { usable: false, reason: "unreadable" };
|
|
6529
6683
|
}
|
|
@@ -7222,7 +7376,7 @@ function removeIntegrationSkillFolder(opts) {
|
|
|
7222
7376
|
}
|
|
7223
7377
|
|
|
7224
7378
|
// src/lib/manager/managed-skill-manifest.ts
|
|
7225
|
-
import { existsSync as existsSync13, mkdirSync as mkdirSync10, readFileSync as
|
|
7379
|
+
import { existsSync as existsSync13, mkdirSync as mkdirSync10, readFileSync as readFileSync26, writeFileSync as writeFileSync12 } from "fs";
|
|
7226
7380
|
import { dirname as dirname8, join as join32 } from "path";
|
|
7227
7381
|
var MANIFEST_VERSION = 1;
|
|
7228
7382
|
function managedSkillManifestPath(agentRootDir) {
|
|
@@ -7231,7 +7385,7 @@ function managedSkillManifestPath(agentRootDir) {
|
|
|
7231
7385
|
function readManagedSkillManifest(path) {
|
|
7232
7386
|
try {
|
|
7233
7387
|
if (!existsSync13(path)) return /* @__PURE__ */ new Set();
|
|
7234
|
-
const parsed = JSON.parse(
|
|
7388
|
+
const parsed = JSON.parse(readFileSync26(path, "utf-8"));
|
|
7235
7389
|
const ids = Array.isArray(parsed?.globalSkillIds) ? parsed.globalSkillIds : [];
|
|
7236
7390
|
return new Set(ids.filter((id) => typeof id === "string" && id.length > 0));
|
|
7237
7391
|
} catch {
|
|
@@ -7362,7 +7516,7 @@ function resolveModelChain(refreshData) {
|
|
|
7362
7516
|
// src/lib/manager/claude-auth.ts
|
|
7363
7517
|
import { existsSync as existsSync14, rmSync as rmSync6 } from "fs";
|
|
7364
7518
|
import { join as join33 } from "path";
|
|
7365
|
-
import { homedir as
|
|
7519
|
+
import { homedir as homedir13 } from "os";
|
|
7366
7520
|
async function applyClaudeAuthToEnv(childEnv, label) {
|
|
7367
7521
|
const apiKey = getApiKey();
|
|
7368
7522
|
if (!apiKey) {
|
|
@@ -7374,7 +7528,7 @@ async function applyClaudeAuthToEnv(childEnv, label) {
|
|
|
7374
7528
|
throw new Error("claude_auth_mode=api_key but /host/exchange returned no decrypted key");
|
|
7375
7529
|
}
|
|
7376
7530
|
childEnv.ANTHROPIC_API_KEY = exchange.anthropicApiKey;
|
|
7377
|
-
const claudeDir = join33(
|
|
7531
|
+
const claudeDir = join33(homedir13(), ".claude");
|
|
7378
7532
|
for (const filename of [".credentials.json", "credentials.json"]) {
|
|
7379
7533
|
const p = join33(claudeDir, filename);
|
|
7380
7534
|
if (existsSync14(p)) {
|
|
@@ -7732,7 +7886,7 @@ function formatBoardForPrompt(items, template) {
|
|
|
7732
7886
|
}
|
|
7733
7887
|
|
|
7734
7888
|
// src/lib/manager/kanban/nudge-state-cache.ts
|
|
7735
|
-
import { existsSync as existsSync15, readFileSync as
|
|
7889
|
+
import { existsSync as existsSync15, readFileSync as readFileSync27, writeFileSync as writeFileSync13 } from "fs";
|
|
7736
7890
|
import { join as join34 } from "path";
|
|
7737
7891
|
var CACHE_FILENAME2 = "kanban-nudge-state.json";
|
|
7738
7892
|
var KANBAN_NUDGE_STATE_VERSION = 1;
|
|
@@ -7744,7 +7898,7 @@ function loadKanbanNudgeState(target, configDir) {
|
|
|
7744
7898
|
if (!existsSync15(path)) return;
|
|
7745
7899
|
let parsed;
|
|
7746
7900
|
try {
|
|
7747
|
-
parsed = JSON.parse(
|
|
7901
|
+
parsed = JSON.parse(readFileSync27(path, "utf-8"));
|
|
7748
7902
|
} catch {
|
|
7749
7903
|
return;
|
|
7750
7904
|
}
|
|
@@ -8362,8 +8516,8 @@ function closeSessionRunForCode(codeName, outcome, reason) {
|
|
|
8362
8516
|
|
|
8363
8517
|
// src/lib/manager/scheduler/kanban-route.ts
|
|
8364
8518
|
import { createHash as createHash15 } from "crypto";
|
|
8365
|
-
import { writeFileSync as writeFileSync14, renameSync as renameSync8, mkdirSync as mkdirSync11, readFileSync as
|
|
8366
|
-
import { homedir as
|
|
8519
|
+
import { writeFileSync as writeFileSync14, renameSync as renameSync8, mkdirSync as mkdirSync11, readFileSync as readFileSync28, unlinkSync as unlinkSync3 } from "fs";
|
|
8520
|
+
import { homedir as homedir14 } from "os";
|
|
8367
8521
|
import { join as join35, dirname as dirname9 } from "path";
|
|
8368
8522
|
|
|
8369
8523
|
// src/lib/manager/scheduler/notify.ts
|
|
@@ -8723,7 +8877,7 @@ function resolveScheduledSlackTarget(task) {
|
|
|
8723
8877
|
}
|
|
8724
8878
|
function stampScheduledTurnMarker(codeName, taskId, target) {
|
|
8725
8879
|
try {
|
|
8726
|
-
const file = join35(
|
|
8880
|
+
const file = join35(homedir14(), ".augmented", codeName, SCHEDULED_TURN_MARKER_FILENAME);
|
|
8727
8881
|
const marker = { ts: Date.now(), task_id: taskId, ...target ? { target } : {} };
|
|
8728
8882
|
const tmp = `${file}.tmp`;
|
|
8729
8883
|
writeFileSync14(tmp, JSON.stringify(marker), "utf8");
|
|
@@ -8733,9 +8887,9 @@ function stampScheduledTurnMarker(codeName, taskId, target) {
|
|
|
8733
8887
|
}
|
|
8734
8888
|
}
|
|
8735
8889
|
function clearScheduledTurnMarkerForTask(codeName, taskId) {
|
|
8736
|
-
const file = join35(
|
|
8890
|
+
const file = join35(homedir14(), ".augmented", codeName, SCHEDULED_TURN_MARKER_FILENAME);
|
|
8737
8891
|
try {
|
|
8738
|
-
const raw = JSON.parse(
|
|
8892
|
+
const raw = JSON.parse(readFileSync28(file, "utf8"));
|
|
8739
8893
|
if (typeof raw?.task_id !== "string" || raw.task_id !== taskId) return;
|
|
8740
8894
|
unlinkSync3(file);
|
|
8741
8895
|
log(`[scheduled-kanban] scheduled-turn marker cleared for '${codeName}' (task ${taskId} complete)`);
|
|
@@ -8795,7 +8949,7 @@ async function routeScheduledTaskViaKanban(codeName, agentId, task, prompt, dura
|
|
|
8795
8949
|
return false;
|
|
8796
8950
|
}
|
|
8797
8951
|
try {
|
|
8798
|
-
const doorbell = directChatDoorbellPath(agentId,
|
|
8952
|
+
const doorbell = directChatDoorbellPath(agentId, homedir14());
|
|
8799
8953
|
mkdirSync11(dirname9(doorbell), { recursive: true });
|
|
8800
8954
|
writeFileSync14(doorbell, String(Date.now()));
|
|
8801
8955
|
} catch (err) {
|
|
@@ -8950,11 +9104,11 @@ async function processClaudeTaskResult(codeName, agentId, templateId, rawOutput,
|
|
|
8950
9104
|
|
|
8951
9105
|
// src/lib/manager/scheduler/execution.ts
|
|
8952
9106
|
import { createHash as createHash16 } from "crypto";
|
|
8953
|
-
import { homedir as
|
|
9107
|
+
import { homedir as homedir15 } from "os";
|
|
8954
9108
|
import { join as join37 } from "path";
|
|
8955
9109
|
|
|
8956
9110
|
// src/lib/agent-serving-probe.ts
|
|
8957
|
-
import { readFileSync as
|
|
9111
|
+
import { readFileSync as readFileSync29, readdirSync as readdirSync8, statSync as statSync10 } from "fs";
|
|
8958
9112
|
import { join as join36 } from "path";
|
|
8959
9113
|
var RATE_LIMIT_WINDOW_MS = 6 * 60 * 60 * 1e3;
|
|
8960
9114
|
function probeRateLimit(args) {
|
|
@@ -8980,7 +9134,7 @@ function probeRateLimit(args) {
|
|
|
8980
9134
|
}
|
|
8981
9135
|
let content;
|
|
8982
9136
|
try {
|
|
8983
|
-
content =
|
|
9137
|
+
content = readFileSync29(path, "utf-8");
|
|
8984
9138
|
} catch {
|
|
8985
9139
|
continue;
|
|
8986
9140
|
}
|
|
@@ -9042,7 +9196,7 @@ function shouldLogUsageCapDeferral(site, codeName, limitedUntil) {
|
|
|
9042
9196
|
|
|
9043
9197
|
// src/lib/manager/scheduler/execution.ts
|
|
9044
9198
|
function claudePidFilePath() {
|
|
9045
|
-
return join37(
|
|
9199
|
+
return join37(homedir15(), ".augmented", "manager-claude-pids.json");
|
|
9046
9200
|
}
|
|
9047
9201
|
var inFlightClaudePids = /* @__PURE__ */ new Map();
|
|
9048
9202
|
function registerClaudeSpawn(record) {
|
|
@@ -9442,7 +9596,7 @@ function stopPaneOccupancySampler() {
|
|
|
9442
9596
|
}
|
|
9443
9597
|
|
|
9444
9598
|
// src/lib/pid-pressure-sampler.ts
|
|
9445
|
-
import { existsSync as existsSync16, readFileSync as
|
|
9599
|
+
import { existsSync as existsSync16, readFileSync as readFileSync30 } from "fs";
|
|
9446
9600
|
var SAMPLE_INTERVAL_MS2 = 3e4;
|
|
9447
9601
|
function warnFraction() {
|
|
9448
9602
|
const raw = Number(process.env.AGT_PID_PRESSURE_WARN_FRACTION);
|
|
@@ -9470,7 +9624,7 @@ function parseMemoryEvents(text) {
|
|
|
9470
9624
|
}
|
|
9471
9625
|
function readTextReal(path) {
|
|
9472
9626
|
try {
|
|
9473
|
-
return
|
|
9627
|
+
return readFileSync30(path, "utf-8");
|
|
9474
9628
|
} catch {
|
|
9475
9629
|
return null;
|
|
9476
9630
|
}
|
|
@@ -10753,7 +10907,7 @@ async function fireOpencodeScheduledTask(agent, task) {
|
|
|
10753
10907
|
|
|
10754
10908
|
// src/lib/opencode-telegram-ingest.ts
|
|
10755
10909
|
import { createHash as createHash19 } from "crypto";
|
|
10756
|
-
import { existsSync as existsSync17, mkdirSync as mkdirSync12, readFileSync as
|
|
10910
|
+
import { existsSync as existsSync17, mkdirSync as mkdirSync12, readFileSync as readFileSync31, renameSync as renameSync9, unlinkSync as unlinkSync4, writeFileSync as writeFileSync15 } from "fs";
|
|
10757
10911
|
import { randomUUID } from "crypto";
|
|
10758
10912
|
import { join as join39 } from "path";
|
|
10759
10913
|
|
|
@@ -11321,7 +11475,7 @@ function createFileOffsetStore(codeName, log2, currentBotId) {
|
|
|
11321
11475
|
load() {
|
|
11322
11476
|
if (!filePath) return 0;
|
|
11323
11477
|
try {
|
|
11324
|
-
const parsed = JSON.parse(
|
|
11478
|
+
const parsed = JSON.parse(readFileSync31(filePath, "utf-8"));
|
|
11325
11479
|
if (currentBotId != null && typeof parsed?.bot_id === "number" && parsed.bot_id !== currentBotId) {
|
|
11326
11480
|
log2(`[telegram-ingest:${codeName}] offset cursor belongs to a different bot; ignoring (bot swap)`);
|
|
11327
11481
|
return 0;
|
|
@@ -11595,12 +11749,12 @@ function partitionActionableByPoison(actionable, states, config2) {
|
|
|
11595
11749
|
}
|
|
11596
11750
|
|
|
11597
11751
|
// src/lib/restart-flags.ts
|
|
11598
|
-
import { existsSync as existsSync18, mkdirSync as mkdirSync13, readdirSync as readdirSync10, readFileSync as
|
|
11599
|
-
import { homedir as
|
|
11752
|
+
import { existsSync as existsSync18, mkdirSync as mkdirSync13, readdirSync as readdirSync10, readFileSync as readFileSync32, renameSync as renameSync10, rmSync as rmSync7, writeFileSync as writeFileSync16 } from "fs";
|
|
11753
|
+
import { homedir as homedir16 } from "os";
|
|
11600
11754
|
import { join as join40 } from "path";
|
|
11601
11755
|
import { randomUUID as randomUUID2 } from "crypto";
|
|
11602
11756
|
function restartFlagsDir() {
|
|
11603
|
-
return join40(
|
|
11757
|
+
return join40(homedir16(), ".augmented", "restart-flags");
|
|
11604
11758
|
}
|
|
11605
11759
|
function flagPath(codeName) {
|
|
11606
11760
|
return join40(restartFlagsDir(), `${codeName}.flag`);
|
|
@@ -11612,7 +11766,7 @@ function readRestartFlags() {
|
|
|
11612
11766
|
for (const entry of readdirSync10(dir)) {
|
|
11613
11767
|
if (!entry.endsWith(".flag")) continue;
|
|
11614
11768
|
try {
|
|
11615
|
-
const raw =
|
|
11769
|
+
const raw = readFileSync32(join40(dir, entry), "utf8");
|
|
11616
11770
|
const parsed = JSON.parse(raw);
|
|
11617
11771
|
if (typeof parsed.codeName !== "string" || parsed.codeName.length === 0) {
|
|
11618
11772
|
parsed.codeName = entry.replace(/\.flag$/, "");
|
|
@@ -11730,7 +11884,7 @@ async function sendError(flag, opts, text) {
|
|
|
11730
11884
|
}
|
|
11731
11885
|
|
|
11732
11886
|
// src/lib/restart-context.ts
|
|
11733
|
-
import { readdirSync as readdirSync11, readFileSync as
|
|
11887
|
+
import { readdirSync as readdirSync11, readFileSync as readFileSync33, writeFileSync as writeFileSync17, mkdirSync as mkdirSync14, unlinkSync as unlinkSync5 } from "fs";
|
|
11734
11888
|
import { dirname as dirname10, join as join41 } from "path";
|
|
11735
11889
|
var SLACK_PENDING_INBOUND_DIRNAME = "slack-pending-inbound";
|
|
11736
11890
|
var SLACK_RESTART_CONTEXT_DIRNAME = "slack-restart-context";
|
|
@@ -11788,7 +11942,7 @@ function safeReaddir(dir) {
|
|
|
11788
11942
|
}
|
|
11789
11943
|
function readStrandedMarker(path) {
|
|
11790
11944
|
try {
|
|
11791
|
-
const parsed = JSON.parse(
|
|
11945
|
+
const parsed = JSON.parse(readFileSync33(path, "utf-8"));
|
|
11792
11946
|
if (typeof parsed.channel === "string" && typeof parsed.thread_ts === "string") {
|
|
11793
11947
|
return { channel: parsed.channel, thread_ts: parsed.thread_ts };
|
|
11794
11948
|
}
|
|
@@ -13311,7 +13465,7 @@ var pendingDayRolloverReset = /* @__PURE__ */ new Set();
|
|
|
13311
13465
|
var dayRolloverInboundHold = /* @__PURE__ */ new Map();
|
|
13312
13466
|
var INBOUND_HOLD_EPISODE_GAP_MS = 12e4;
|
|
13313
13467
|
async function channelInboundActivityAgeSecondsFor(codeName) {
|
|
13314
|
-
const { newestPendingInboundActivityMtimeMs } = await import("../responsiveness-probe-
|
|
13468
|
+
const { newestPendingInboundActivityMtimeMs } = await import("../responsiveness-probe-J2DYGC7T.js");
|
|
13315
13469
|
const newest = newestPendingInboundActivityMtimeMs(dirname11(paneLogPath(codeName)));
|
|
13316
13470
|
if (newest === null) return null;
|
|
13317
13471
|
return Math.max(0, Math.floor((Date.now() - newest) / 1e3));
|
|
@@ -13636,7 +13790,7 @@ var runningChannelSecretHashes = /* @__PURE__ */ new Map();
|
|
|
13636
13790
|
var sessionLaunchManagedStructure = /* @__PURE__ */ new Map();
|
|
13637
13791
|
function projectMcpHash(_codeName, projectDir) {
|
|
13638
13792
|
try {
|
|
13639
|
-
const raw =
|
|
13793
|
+
const raw = readFileSync34(join42(projectDir, ".mcp.json"), "utf-8");
|
|
13640
13794
|
return createHash20("sha256").update(canonicalJson(JSON.parse(raw))).digest("hex");
|
|
13641
13795
|
} catch {
|
|
13642
13796
|
return null;
|
|
@@ -13644,7 +13798,7 @@ function projectMcpHash(_codeName, projectDir) {
|
|
|
13644
13798
|
}
|
|
13645
13799
|
function projectMcpKeys(_codeName, projectDir) {
|
|
13646
13800
|
try {
|
|
13647
|
-
const raw =
|
|
13801
|
+
const raw = readFileSync34(join42(projectDir, ".mcp.json"), "utf-8");
|
|
13648
13802
|
const parsed = JSON.parse(raw);
|
|
13649
13803
|
const servers = parsed.mcpServers;
|
|
13650
13804
|
if (!servers || typeof servers !== "object") return /* @__PURE__ */ new Set();
|
|
@@ -13662,7 +13816,7 @@ function seedSessionLaunchBaselines(codeName, projectDir) {
|
|
|
13662
13816
|
else runningMcpServerKeys.delete(codeName);
|
|
13663
13817
|
let launchStructure = null;
|
|
13664
13818
|
try {
|
|
13665
|
-
const raw =
|
|
13819
|
+
const raw = readFileSync34(join42(projectDir, ".mcp.json"), "utf-8");
|
|
13666
13820
|
launchStructure = managedMcpStructureHashFromFile(
|
|
13667
13821
|
JSON.parse(raw),
|
|
13668
13822
|
isManagedMcpServerKey
|
|
@@ -13797,7 +13951,7 @@ async function runAgentSessionToolBindProbes(agent, integrations, projectDir, op
|
|
|
13797
13951
|
if (result && result.rebindCandidates.length > 0 && hostFlagStore().getBoolean("session-tool-rebind")) {
|
|
13798
13952
|
let mcpJsonForRebind = null;
|
|
13799
13953
|
try {
|
|
13800
|
-
mcpJsonForRebind = JSON.parse(
|
|
13954
|
+
mcpJsonForRebind = JSON.parse(readFileSync34(join42(projectDir, ".mcp.json"), "utf-8"));
|
|
13801
13955
|
} catch {
|
|
13802
13956
|
mcpJsonForRebind = null;
|
|
13803
13957
|
}
|
|
@@ -13945,7 +14099,7 @@ function shouldInjectChannelSecrets(agentId) {
|
|
|
13945
14099
|
function projectChannelSecretHash(projectDir) {
|
|
13946
14100
|
try {
|
|
13947
14101
|
const entries = parseEnvIntegrations(
|
|
13948
|
-
|
|
14102
|
+
readFileSync34(join42(projectDir, ".env.integrations"), "utf-8")
|
|
13949
14103
|
);
|
|
13950
14104
|
return channelSecretValueHash(entries, CHANNEL_SECRET_ENV_KEYS);
|
|
13951
14105
|
} catch {
|
|
@@ -14054,7 +14208,7 @@ var agentRestartTimezoneInputs = /* @__PURE__ */ new Map();
|
|
|
14054
14208
|
var lastVersionCheckAt = 0;
|
|
14055
14209
|
var VERSION_CHECK_INTERVAL_MS = 5 * 60 * 1e3;
|
|
14056
14210
|
var lastResponsivenessProbeAt = 0;
|
|
14057
|
-
var agtCliVersion = true ? "0.28.
|
|
14211
|
+
var agtCliVersion = true ? "0.28.1007" : "dev";
|
|
14058
14212
|
function resolveBrewPath(execFileSync2) {
|
|
14059
14213
|
try {
|
|
14060
14214
|
const out = execFileSync2("which", ["brew"], { timeout: 5e3 }).toString().trim();
|
|
@@ -14389,7 +14543,7 @@ function ensureClaudeManagedSettings(path = claudeManagedSettingsPath()) {
|
|
|
14389
14543
|
try {
|
|
14390
14544
|
let settings = {};
|
|
14391
14545
|
if (existsSync19(path)) {
|
|
14392
|
-
const raw =
|
|
14546
|
+
const raw = readFileSync34(path, "utf-8").trim();
|
|
14393
14547
|
if (raw) {
|
|
14394
14548
|
let parsed;
|
|
14395
14549
|
try {
|
|
@@ -14596,7 +14750,7 @@ async function maybeUpgradeClaudeCode() {
|
|
|
14596
14750
|
}
|
|
14597
14751
|
var UPDATE_CHECK_INTERVAL_MS = 5 * 60 * 1e3;
|
|
14598
14752
|
function selfUpdateAppliedMarkerPath() {
|
|
14599
|
-
return join42(
|
|
14753
|
+
return join42(homedir17(), ".augmented", ".last-self-update-applied");
|
|
14600
14754
|
}
|
|
14601
14755
|
var selfUpdateUpToDateLogged = false;
|
|
14602
14756
|
var selfUpdatePinnedLogged = false;
|
|
@@ -14647,7 +14801,7 @@ async function checkAndUpdateCli(opts) {
|
|
|
14647
14801
|
const isNpmGlobal = !isBrewFormula && resolvedPath.includes("node_modules");
|
|
14648
14802
|
if (!isBrewFormula && !isNpmGlobal) return "noop";
|
|
14649
14803
|
const { readFileSync: readF, writeFileSync: writeF } = await import("fs");
|
|
14650
|
-
const markerPath = join42(
|
|
14804
|
+
const markerPath = join42(homedir17(), ".augmented", ".last-update-check");
|
|
14651
14805
|
if (!force) {
|
|
14652
14806
|
try {
|
|
14653
14807
|
const lastCheck = parseInt(readF(markerPath, "utf-8").trim(), 10);
|
|
@@ -15058,7 +15212,7 @@ async function runClaudeRuntimeAuthProbe() {
|
|
|
15058
15212
|
];
|
|
15059
15213
|
try {
|
|
15060
15214
|
const { stdout, stderr } = await execFilePromiseLong(resolveClaudeBinary(), args, {
|
|
15061
|
-
cwd:
|
|
15215
|
+
cwd: homedir17(),
|
|
15062
15216
|
timeout: RUNTIME_AUTH_PROBE_TIMEOUT_MS,
|
|
15063
15217
|
stdin: "ignore",
|
|
15064
15218
|
env: childEnv,
|
|
@@ -15098,7 +15252,7 @@ async function runHostUsageCommand() {
|
|
|
15098
15252
|
""
|
|
15099
15253
|
];
|
|
15100
15254
|
const { stdout } = await execFilePromiseLong(resolveClaudeBinary(), args, {
|
|
15101
|
-
cwd:
|
|
15255
|
+
cwd: homedir17(),
|
|
15102
15256
|
timeout: HOST_USAGE_POLL_TIMEOUT_MS,
|
|
15103
15257
|
stdin: "ignore",
|
|
15104
15258
|
env: childEnv,
|
|
@@ -15145,7 +15299,7 @@ async function checkClaudeAuth() {
|
|
|
15145
15299
|
var evalEmptyMcpConfigPath = null;
|
|
15146
15300
|
function ensureEvalEmptyMcpConfig() {
|
|
15147
15301
|
if (evalEmptyMcpConfigPath && existsSync19(evalEmptyMcpConfigPath)) return evalEmptyMcpConfigPath;
|
|
15148
|
-
const dir = join42(
|
|
15302
|
+
const dir = join42(homedir17(), ".augmented");
|
|
15149
15303
|
try {
|
|
15150
15304
|
mkdirSync15(dir, { recursive: true });
|
|
15151
15305
|
} catch {
|
|
@@ -15176,7 +15330,7 @@ async function runEvalClaude(prompt, model) {
|
|
|
15176
15330
|
""
|
|
15177
15331
|
];
|
|
15178
15332
|
const { stdout } = await execFilePromiseLong(resolveClaudeBinary(), args, {
|
|
15179
|
-
cwd:
|
|
15333
|
+
cwd: homedir17(),
|
|
15180
15334
|
timeout: 12e4,
|
|
15181
15335
|
stdin: "ignore",
|
|
15182
15336
|
env: childEnv,
|
|
@@ -15466,6 +15620,24 @@ function channelQuarantineStore() {
|
|
|
15466
15620
|
}
|
|
15467
15621
|
return _channelQuarantineStore;
|
|
15468
15622
|
}
|
|
15623
|
+
var _channelResumeHistoryStore = null;
|
|
15624
|
+
function channelResumeHistoryStore() {
|
|
15625
|
+
if (!_channelResumeHistoryStore) {
|
|
15626
|
+
const dir = config?.configDir ?? join42(process.env["HOME"] ?? "/tmp", ".augmented");
|
|
15627
|
+
_channelResumeHistoryStore = new ChannelResumeHistoryStore(defaultResumeHistoryPath(dir));
|
|
15628
|
+
}
|
|
15629
|
+
return _channelResumeHistoryStore;
|
|
15630
|
+
}
|
|
15631
|
+
var autoResumeDowngradeLogged = /* @__PURE__ */ new Set();
|
|
15632
|
+
function shouldLogAutoResumeModeDowngrade(autoResume, quarantine) {
|
|
15633
|
+
const key = `${autoResume}->${quarantine}`;
|
|
15634
|
+
if (autoResumeDowngradeLogged.has(key)) return false;
|
|
15635
|
+
autoResumeDowngradeLogged.add(key);
|
|
15636
|
+
return true;
|
|
15637
|
+
}
|
|
15638
|
+
function channelQuarantineAutoResumeMode() {
|
|
15639
|
+
return hostFlagStore().getString("channel-quarantine-auto-resume");
|
|
15640
|
+
}
|
|
15469
15641
|
function quarantineEntriesFor(codeName) {
|
|
15470
15642
|
return channelQuarantineStore().getQuarantineEntries(codeName);
|
|
15471
15643
|
}
|
|
@@ -15670,7 +15842,7 @@ function flushRestartedAgentDiagnostics(hostId, codeNames) {
|
|
|
15670
15842
|
if (codeNames.length === 0) return;
|
|
15671
15843
|
void (async () => {
|
|
15672
15844
|
try {
|
|
15673
|
-
const { collectDiagnostics } = await import("../persistent-session-
|
|
15845
|
+
const { collectDiagnostics } = await import("../persistent-session-5KWYODZB.js");
|
|
15674
15846
|
await api.post("/host/heartbeat", {
|
|
15675
15847
|
host_id: hostId,
|
|
15676
15848
|
agent_diagnostics: collectDiagnostics(codeNames, quarantineEntriesFor, claudeMdSizeFor, spawnOutcomeForDiagnostics, pidPressureFor, forwardedToolsFor)
|
|
@@ -15812,7 +15984,7 @@ async function pollCycleInner() {
|
|
|
15812
15984
|
}
|
|
15813
15985
|
try {
|
|
15814
15986
|
const { detectHostSecurity } = await import("../host-security-KQYYZZVW.js");
|
|
15815
|
-
const { collectDiagnostics } = await import("../persistent-session-
|
|
15987
|
+
const { collectDiagnostics } = await import("../persistent-session-5KWYODZB.js");
|
|
15816
15988
|
const diagCodeNames = [...agentState.persistentSessionAgents];
|
|
15817
15989
|
const agentDiagnostics = diagCodeNames.length > 0 ? collectDiagnostics(diagCodeNames, quarantineEntriesFor, claudeMdSizeFor, spawnOutcomeForDiagnostics, pidPressureFor, forwardedToolsFor) : void 0;
|
|
15818
15990
|
let tailscaleHostname;
|
|
@@ -15968,7 +16140,7 @@ async function pollCycleInner() {
|
|
|
15968
16140
|
try {
|
|
15969
16141
|
const desiredClaudeCodeVersion = hbResp?.desired_claude_code_version?.trim();
|
|
15970
16142
|
if (desiredClaudeCodeVersion && decideMaintenanceWindowGate({ window: cachedMaintenanceWindow, now: /* @__PURE__ */ new Date() }) === "proceed") {
|
|
15971
|
-
const { maybeUpdateClaudeCode } = await import("../claude-code-updater-
|
|
16143
|
+
const { maybeUpdateClaudeCode } = await import("../claude-code-updater-NEJCTT7S.js");
|
|
15972
16144
|
await maybeUpdateClaudeCode({
|
|
15973
16145
|
desiredVersion: desiredClaudeCodeVersion,
|
|
15974
16146
|
currentVersion: cachedFrameworkVersion,
|
|
@@ -15988,7 +16160,7 @@ async function pollCycleInner() {
|
|
|
15988
16160
|
collectPanelessActivityProbes,
|
|
15989
16161
|
getResponsivenessIntervalMs,
|
|
15990
16162
|
occupancyQualificationClassifications
|
|
15991
|
-
} = await import("../responsiveness-probe-
|
|
16163
|
+
} = await import("../responsiveness-probe-J2DYGC7T.js");
|
|
15992
16164
|
const probeIntervalMs = getResponsivenessIntervalMs();
|
|
15993
16165
|
if (now - lastResponsivenessProbeAt > probeIntervalMs) {
|
|
15994
16166
|
const probeCodeNames = [...agentState.persistentSessionAgents];
|
|
@@ -16105,7 +16277,7 @@ async function pollCycleInner() {
|
|
|
16105
16277
|
collectResponsivenessProbes,
|
|
16106
16278
|
livePendingInboundOldestAgeSeconds,
|
|
16107
16279
|
parkPendingInbound
|
|
16108
|
-
} = await import("../responsiveness-probe-
|
|
16280
|
+
} = await import("../responsiveness-probe-J2DYGC7T.js");
|
|
16109
16281
|
const { getProjectDir: wedgeProjectDir } = await import("../scheduler-engine-M6AFZWNU.js");
|
|
16110
16282
|
const wedgeNow = /* @__PURE__ */ new Date();
|
|
16111
16283
|
const liveAgents = agentState.persistentSessionAgents;
|
|
@@ -16194,10 +16366,10 @@ async function pollCycleInner() {
|
|
|
16194
16366
|
);
|
|
16195
16367
|
if (hostFlagStore().getBoolean("wedge-transient-notice")) {
|
|
16196
16368
|
try {
|
|
16197
|
-
const paneTail =
|
|
16369
|
+
const paneTail = readFileSync34(paneLogPath(codeName), "utf8").slice(-65536);
|
|
16198
16370
|
const transient = detectTransientApiErrorInLog(paneTail);
|
|
16199
16371
|
if (transient) {
|
|
16200
|
-
const wedgeHome = join42(
|
|
16372
|
+
const wedgeHome = join42(homedir17(), ".augmented", codeName);
|
|
16201
16373
|
if (existsSync19(wedgeHome)) {
|
|
16202
16374
|
atomicWriteFileSync(
|
|
16203
16375
|
join42(wedgeHome, "watchdog-give-up.json"),
|
|
@@ -16261,7 +16433,7 @@ async function pollCycleInner() {
|
|
|
16261
16433
|
}
|
|
16262
16434
|
try {
|
|
16263
16435
|
const { scrapeMcpFailedBannerCount } = await import("../pane-mcp-banner-scraper-VR5QGP3J.js");
|
|
16264
|
-
const { probeSessionAuth } = await import("../session-auth-dead-
|
|
16436
|
+
const { probeSessionAuth } = await import("../session-auth-dead-4SE5Q7MU.js");
|
|
16265
16437
|
const observations = [];
|
|
16266
16438
|
const pendingCacheCommits = [];
|
|
16267
16439
|
const modelApiErrorReportingOn = hostFlagStore().getBoolean("model-api-error-reporting");
|
|
@@ -16417,6 +16589,12 @@ async function pollCycleInner() {
|
|
|
16417
16589
|
agent.code_name,
|
|
16418
16590
|
clear.channel_id
|
|
16419
16591
|
);
|
|
16592
|
+
for (const mode of ["enforce", "shadow"]) {
|
|
16593
|
+
channelResumeHistoryStore().forget(
|
|
16594
|
+
agent.code_name,
|
|
16595
|
+
resumeHistoryKey(mode, clear.channel_id)
|
|
16596
|
+
);
|
|
16597
|
+
}
|
|
16420
16598
|
log(
|
|
16421
16599
|
`[channel-reenable] ${removed ? "cleared" : "no marker for"} '${clear.channel_id}' on '${agent.code_name}' (operator re-enable)`
|
|
16422
16600
|
);
|
|
@@ -16431,6 +16609,92 @@ async function pollCycleInner() {
|
|
|
16431
16609
|
);
|
|
16432
16610
|
}
|
|
16433
16611
|
}
|
|
16612
|
+
const autoResumeMode = channelQuarantineAutoResumeMode();
|
|
16613
|
+
const quarantineMode = channelQuarantineMode();
|
|
16614
|
+
const autoResumeEffective = resolveAutoResumeEffectiveMode(autoResumeMode, quarantineMode);
|
|
16615
|
+
if (autoResumeMode === "enforce" && autoResumeEffective === "shadow") {
|
|
16616
|
+
if (shouldLogAutoResumeModeDowngrade(autoResumeMode, quarantineMode)) {
|
|
16617
|
+
log(
|
|
16618
|
+
`[channel-auto-resume] channel-quarantine-auto-resume is 'enforce' but channel-quarantine-mode is '${quarantineMode}', so the reaper writes no quarantine marker and a failed trial could never be observed - every trial would score a success and permanently un-quarantine a dead channel. Running in SHADOW instead (bookkeeping only, nothing cleared). Set channel-quarantine-mode to 'enforce' first.`
|
|
16619
|
+
);
|
|
16620
|
+
}
|
|
16621
|
+
}
|
|
16622
|
+
if (autoResumeEffective !== "off") {
|
|
16623
|
+
const nowMs = Date.now();
|
|
16624
|
+
for (const agent of agents) {
|
|
16625
|
+
if (agent.status !== "active") continue;
|
|
16626
|
+
try {
|
|
16627
|
+
const quarantineEntries = channelQuarantineStore().getQuarantineEntries(agent.code_name);
|
|
16628
|
+
const quarantinedKeys = new Set(quarantineEntries.map((e) => e.serverKey));
|
|
16629
|
+
for (const [storedKey, history] of channelResumeHistoryStore().entriesFor(agent.code_name)) {
|
|
16630
|
+
const isShadowKey = storedKey.startsWith("shadow:");
|
|
16631
|
+
if (isShadowKey !== (autoResumeEffective === "shadow")) continue;
|
|
16632
|
+
const serverKey = isShadowKey ? storedKey.slice("shadow:".length) : storedKey;
|
|
16633
|
+
if (!shouldForgetResumeHistory({
|
|
16634
|
+
isQuarantined: quarantinedKeys.has(serverKey),
|
|
16635
|
+
history,
|
|
16636
|
+
now: nowMs,
|
|
16637
|
+
// THE CONFIGURED DWELL, NOT THE FLOOR (obi-wan `7414dbf3d758`).
|
|
16638
|
+
// A host that raised AGT_CHANNEL_QUARANTINE_DWELL_MS pushes
|
|
16639
|
+
// re-quarantine PAST the floor-derived grace, so a failed trial
|
|
16640
|
+
// read as a success and wiped the strikes - restarting the
|
|
16641
|
+
// five-attempt budget every episode, forever.
|
|
16642
|
+
configuredDwellMs: channelQuarantineDwellMs()
|
|
16643
|
+
})) {
|
|
16644
|
+
continue;
|
|
16645
|
+
}
|
|
16646
|
+
channelResumeHistoryStore().forget(agent.code_name, storedKey);
|
|
16647
|
+
log(
|
|
16648
|
+
`[channel-auto-resume] trial SUCCEEDED for '${serverKey}' on '${agent.code_name}' \u2014 un-quarantined for ${Math.round((nowMs - history.lastAttemptAt) / 6e4)}m, clearing ${history.attempts} strike(s) so the next episode starts from a full budget` + (autoResumeEffective === "shadow" ? " (shadow bookkeeping)" : "")
|
|
16649
|
+
);
|
|
16650
|
+
}
|
|
16651
|
+
for (const entry of quarantineEntries) {
|
|
16652
|
+
const historyKeyFor = (key) => resumeHistoryKey(autoResumeEffective, key);
|
|
16653
|
+
const historyKey = historyKeyFor(entry.serverKey);
|
|
16654
|
+
const history = channelResumeHistoryStore().get(agent.code_name, historyKey);
|
|
16655
|
+
const decision = decideChannelAutoResume({
|
|
16656
|
+
quarantinedAt: entry.quarantinedAt,
|
|
16657
|
+
history,
|
|
16658
|
+
now: nowMs
|
|
16659
|
+
});
|
|
16660
|
+
if (decision.action === "wait") continue;
|
|
16661
|
+
if (decision.action === "give-up") {
|
|
16662
|
+
if (!channelResumeHistoryStore().noteGaveUpLogged(agent.code_name, historyKeyFor(entry.serverKey))) {
|
|
16663
|
+
log(
|
|
16664
|
+
autoResumeEffective === "shadow" ? `[channel-auto-resume] WOULD HAVE GIVEN UP on '${entry.serverKey}' for '${agent.code_name}' \u2014 ${decision.attempts} shadow trials recorded, which is the cap. No trial ran and nothing is abandoned: the strikes are in the shadow namespace, so enforcing would start this key at attempt 1 (shadow bookkeeping)` : `[channel-auto-resume] GIVING UP on '${entry.serverKey}' for '${agent.code_name}' \u2014 ${decision.attempts} trials over ~2 days all ended in re-quarantine, so it will NOT be retried automatically again. It stays quarantined until a human presses Re-enable, which also clears the strike count.`
|
|
16665
|
+
);
|
|
16666
|
+
}
|
|
16667
|
+
continue;
|
|
16668
|
+
}
|
|
16669
|
+
const quarantineAgeMin = Math.round((nowMs - entry.quarantinedAt) / 6e4);
|
|
16670
|
+
const waitedMin = Math.round(decision.waitedMs / 6e4);
|
|
16671
|
+
const recorded = channelResumeHistoryStore().recordAttempt(
|
|
16672
|
+
agent.code_name,
|
|
16673
|
+
historyKey,
|
|
16674
|
+
nowMs
|
|
16675
|
+
);
|
|
16676
|
+
if (autoResumeEffective === "shadow") {
|
|
16677
|
+
log(
|
|
16678
|
+
`[channel-auto-resume] WOULD resume '${entry.serverKey}' on '${agent.code_name}' (attempt ${recorded.attempts}/${AUTO_RESUME_MAX_ATTEMPTS}, quarantined ${quarantineAgeMin}m ago, waited ${waitedMin}m since the last trial) \u2014 shadow mode, not acting`
|
|
16679
|
+
);
|
|
16680
|
+
continue;
|
|
16681
|
+
}
|
|
16682
|
+
const cleared = channelQuarantineStore().clearQuarantine(
|
|
16683
|
+
agent.code_name,
|
|
16684
|
+
entry.serverKey
|
|
16685
|
+
);
|
|
16686
|
+
log(
|
|
16687
|
+
`[channel-auto-resume] ${cleared ? "resumed" : "no marker for"} '${entry.serverKey}' on '${agent.code_name}' for a TRIAL run (attempt ${recorded.attempts}/${AUTO_RESUME_MAX_ATTEMPTS}, quarantined ${quarantineAgeMin}m ago, waited ${waitedMin}m since the last trial). The reaper will re-quarantine it if it is still dead.`
|
|
16688
|
+
);
|
|
16689
|
+
}
|
|
16690
|
+
} catch (err) {
|
|
16691
|
+
log(
|
|
16692
|
+
`[channel-auto-resume] a write FAILED partway through '${agent.code_name}' \u2014 ${err instanceof Error ? err.message : String(err)}. Skipping the REST of auto-resume for this agent this cycle; every other agent still gets its poll. State is PARTIAL, not untouched: entries processed before the throw have already been written (channel-resume-history.json, channel-quarantine.json). Every strike is recorded before its marker is cleared, so the failure direction is a wasted strike rather than a trial nobody paid for - but do not read this as "nothing happened".`
|
|
16693
|
+
);
|
|
16694
|
+
continue;
|
|
16695
|
+
}
|
|
16696
|
+
}
|
|
16697
|
+
}
|
|
16434
16698
|
const frameworksThisCycle = new Set(agents.map((a) => a.framework).filter(Boolean));
|
|
16435
16699
|
for (const fw of frameworksThisCycle) {
|
|
16436
16700
|
await ensureFrameworkBinary(fw);
|
|
@@ -16637,7 +16901,7 @@ async function pollCycleInner() {
|
|
|
16637
16901
|
// pending-inbound marker. Best-effort: a write failure is logged by
|
|
16638
16902
|
// the watchdog, never fails the poll cycle.
|
|
16639
16903
|
signalGiveUp: (codeName) => {
|
|
16640
|
-
const dir = join42(
|
|
16904
|
+
const dir = join42(homedir17(), ".augmented", codeName);
|
|
16641
16905
|
if (!existsSync19(dir)) return;
|
|
16642
16906
|
atomicWriteFileSync(
|
|
16643
16907
|
join42(dir, "watchdog-give-up.json"),
|
|
@@ -17249,7 +17513,7 @@ async function processAgent(agent, agentStates, managedToolkits) {
|
|
|
17249
17513
|
newHash = sha256(stripDynamicSections(artifact.content));
|
|
17250
17514
|
try {
|
|
17251
17515
|
const projectClaudeMd = join42(config.configDir, agent.code_name, "project", "CLAUDE.md");
|
|
17252
|
-
const existing =
|
|
17516
|
+
const existing = readFileSync34(projectClaudeMd, "utf-8");
|
|
17253
17517
|
existingHash = sha256(stripDynamicSections(existing));
|
|
17254
17518
|
} catch {
|
|
17255
17519
|
existingHash = null;
|
|
@@ -17267,7 +17531,7 @@ async function processAgent(agent, agentStates, managedToolkits) {
|
|
|
17267
17531
|
const generatorKeys = Object.keys(generatorServers);
|
|
17268
17532
|
let existingRaw = "";
|
|
17269
17533
|
try {
|
|
17270
|
-
existingRaw =
|
|
17534
|
+
existingRaw = readFileSync34(filePath, "utf-8");
|
|
17271
17535
|
} catch {
|
|
17272
17536
|
}
|
|
17273
17537
|
const existingServers = parseMcp(existingRaw);
|
|
@@ -17283,7 +17547,7 @@ async function processAgent(agent, agentStates, managedToolkits) {
|
|
|
17283
17547
|
} else if (artifact.relativePath === "opencode.json") {
|
|
17284
17548
|
let existingRaw = null;
|
|
17285
17549
|
try {
|
|
17286
|
-
existingRaw =
|
|
17550
|
+
existingRaw = readFileSync34(filePath, "utf-8");
|
|
17287
17551
|
} catch {
|
|
17288
17552
|
}
|
|
17289
17553
|
const mergeResult = mergeOpencodeConfigArtifact(artifact.content, existingRaw);
|
|
@@ -17727,7 +17991,7 @@ async function processAgent(agent, agentStates, managedToolkits) {
|
|
|
17727
17991
|
const addedChannels = [...restartDecision.added];
|
|
17728
17992
|
const writeDmNoticeMarkers = isChannelAddRestart ? () => {
|
|
17729
17993
|
try {
|
|
17730
|
-
const agentAugmentedDir = join42(
|
|
17994
|
+
const agentAugmentedDir = join42(homedir17(), ".augmented", agent.code_name);
|
|
17731
17995
|
mkdirSync15(agentAugmentedDir, { recursive: true });
|
|
17732
17996
|
const markerJson = JSON.stringify({
|
|
17733
17997
|
version: 1,
|
|
@@ -18034,18 +18298,18 @@ async function processAgent(agent, agentStates, managedToolkits) {
|
|
|
18034
18298
|
if (agentSessionMode === "persistent" && (agentFrameworkCache.get(agent.code_name) ?? DEFAULT_FRAMEWORK) === "claude-code") {
|
|
18035
18299
|
try {
|
|
18036
18300
|
const agentProvisionDir = agentDir;
|
|
18037
|
-
const projectDir = join42(
|
|
18301
|
+
const projectDir = join42(homedir17(), ".augmented", agent.code_name, "project");
|
|
18038
18302
|
mkdirSync15(agentProvisionDir, { recursive: true });
|
|
18039
18303
|
mkdirSync15(projectDir, { recursive: true });
|
|
18040
18304
|
const provisionMcpPath = join42(agentProvisionDir, ".mcp.json");
|
|
18041
18305
|
const projectMcpPath = join42(projectDir, ".mcp.json");
|
|
18042
18306
|
let mcpConfig = { mcpServers: {} };
|
|
18043
18307
|
try {
|
|
18044
|
-
mcpConfig = JSON.parse(
|
|
18308
|
+
mcpConfig = JSON.parse(readFileSync34(provisionMcpPath, "utf-8"));
|
|
18045
18309
|
if (!mcpConfig.mcpServers) mcpConfig.mcpServers = {};
|
|
18046
18310
|
} catch {
|
|
18047
18311
|
}
|
|
18048
|
-
const localDirectChatChannel = join42(
|
|
18312
|
+
const localDirectChatChannel = join42(homedir17(), ".augmented", "_mcp", "direct-chat-channel.js");
|
|
18049
18313
|
const directChatTeamSettings = refreshData.team?.settings;
|
|
18050
18314
|
const directChatTz = (() => {
|
|
18051
18315
|
const tz = directChatTeamSettings?.["timezone"];
|
|
@@ -18204,7 +18468,7 @@ async function processAgent(agent, agentStates, managedToolkits) {
|
|
|
18204
18468
|
}
|
|
18205
18469
|
if (hostFlagStore().getBoolean("connectivity-probe")) {
|
|
18206
18470
|
try {
|
|
18207
|
-
const probeProjectDir = join42(
|
|
18471
|
+
const probeProjectDir = join42(homedir17(), ".augmented", agent.code_name, "project");
|
|
18208
18472
|
let probeSet = integrations;
|
|
18209
18473
|
const fetchQuarantined = async () => {
|
|
18210
18474
|
const quarantined = await api.post("/host/agent-integrations/quarantined", { agent_id: agent.agent_id });
|
|
@@ -18264,7 +18528,7 @@ async function processAgent(agent, agentStates, managedToolkits) {
|
|
|
18264
18528
|
const forceDue = attemptsLeft > 0;
|
|
18265
18529
|
let probeRan = false;
|
|
18266
18530
|
try {
|
|
18267
|
-
const probeProjectDir = join42(
|
|
18531
|
+
const probeProjectDir = join42(homedir17(), ".augmented", agent.code_name, "project");
|
|
18268
18532
|
probeRan = await runAgentSessionToolBindProbes(agent, integrations, probeProjectDir, { forceDue });
|
|
18269
18533
|
} catch (err) {
|
|
18270
18534
|
log(`Session-tool-bind probe failed for '${agent.code_name}': ${err.message}`);
|
|
@@ -18341,11 +18605,11 @@ async function processAgent(agent, agentStates, managedToolkits) {
|
|
|
18341
18605
|
const intHash = computeIntegrationsHash(integrations);
|
|
18342
18606
|
const prevIntHash = agentState.knownIntegrationHashes.get(agent.agent_id);
|
|
18343
18607
|
if (intHash !== prevIntHash) {
|
|
18344
|
-
const projectDir = join42(
|
|
18608
|
+
const projectDir = join42(homedir17(), ".augmented", agent.code_name, "project");
|
|
18345
18609
|
const envIntPath = join42(projectDir, ".env.integrations");
|
|
18346
18610
|
let preWriteEnv;
|
|
18347
18611
|
try {
|
|
18348
|
-
preWriteEnv =
|
|
18612
|
+
preWriteEnv = readFileSync34(envIntPath, "utf-8");
|
|
18349
18613
|
} catch {
|
|
18350
18614
|
preWriteEnv = void 0;
|
|
18351
18615
|
}
|
|
@@ -18365,8 +18629,8 @@ async function processAgent(agent, agentStates, managedToolkits) {
|
|
|
18365
18629
|
if (fw === "claude-code" && isSessionHealthy(agent.code_name)) {
|
|
18366
18630
|
try {
|
|
18367
18631
|
const projectMcpPath = join42(projectDir, ".mcp.json");
|
|
18368
|
-
const postWriteEnv =
|
|
18369
|
-
const mcpContent =
|
|
18632
|
+
const postWriteEnv = readFileSync34(envIntPath, "utf-8");
|
|
18633
|
+
const mcpContent = readFileSync34(projectMcpPath, "utf-8");
|
|
18370
18634
|
const changedVars = diffEnvIntegrations(preWriteEnv, postWriteEnv);
|
|
18371
18635
|
const mcpJsonForReap = JSON.parse(mcpContent);
|
|
18372
18636
|
const affectedServerKeys = findMcpServersUsingVars(mcpJsonForReap, changedVars);
|
|
@@ -18665,13 +18929,13 @@ async function processAgent(agent, agentStates, managedToolkits) {
|
|
|
18665
18929
|
}
|
|
18666
18930
|
try {
|
|
18667
18931
|
const { readdirSync: readdirSync13, rmSync: rmSync9 } = await import("fs");
|
|
18668
|
-
const { homedir:
|
|
18932
|
+
const { homedir: homedir18 } = await import("os");
|
|
18669
18933
|
const frameworkId2 = frameworkAdapter.id;
|
|
18670
18934
|
const candidateSkillDirs = [
|
|
18671
18935
|
// Claude Code — framework runtime tree
|
|
18672
|
-
join42(
|
|
18936
|
+
join42(homedir18(), ".augmented", agent.code_name, "skills"),
|
|
18673
18937
|
// Claude Code — project tree
|
|
18674
|
-
join42(
|
|
18938
|
+
join42(homedir18(), ".augmented", agent.code_name, "project", ".claude", "skills"),
|
|
18675
18939
|
// Defensive: legacy provision-side path, not currently an
|
|
18676
18940
|
// install target but cheap to sweep.
|
|
18677
18941
|
join42(agentDir, ".claude", "skills")
|
|
@@ -18717,7 +18981,7 @@ async function processAgent(agent, agentStates, managedToolkits) {
|
|
|
18717
18981
|
const sharedSkillsPayload = refreshAny.shared_skills;
|
|
18718
18982
|
const desiredResolved = globalSkillsPayload !== void 0 || sharedSkillsPayload !== void 0;
|
|
18719
18983
|
const manifestPath = managedSkillManifestPath(
|
|
18720
|
-
join42(
|
|
18984
|
+
join42(homedir17(), ".augmented", agent.code_name)
|
|
18721
18985
|
);
|
|
18722
18986
|
const prevIds = /* @__PURE__ */ new Set([
|
|
18723
18987
|
...agentState.knownGlobalSkillIds.get(agent.agent_id) ?? /* @__PURE__ */ new Set(),
|
|
@@ -18737,8 +19001,8 @@ async function processAgent(agent, agentStates, managedToolkits) {
|
|
|
18737
19001
|
}
|
|
18738
19002
|
if (plan.removes.length) {
|
|
18739
19003
|
const globalSkillDirs = [
|
|
18740
|
-
join42(
|
|
18741
|
-
join42(
|
|
19004
|
+
join42(homedir17(), ".augmented", agent.code_name, "skills"),
|
|
19005
|
+
join42(homedir17(), ".augmented", agent.code_name, "project", ".claude", "skills"),
|
|
18742
19006
|
join42(agentDir, ".claude", "skills")
|
|
18743
19007
|
];
|
|
18744
19008
|
for (const id of plan.removes) {
|
|
@@ -19002,7 +19266,7 @@ async function processAgent(agent, agentStates, managedToolkits) {
|
|
|
19002
19266
|
let mcpJsonParsed = null;
|
|
19003
19267
|
try {
|
|
19004
19268
|
const mcpPath = join42(getProjectDir(agent.code_name), ".mcp.json");
|
|
19005
|
-
mcpJsonParsed = JSON.parse(
|
|
19269
|
+
mcpJsonParsed = JSON.parse(readFileSync34(mcpPath, "utf-8"));
|
|
19006
19270
|
} catch {
|
|
19007
19271
|
}
|
|
19008
19272
|
const computerUseIsolated = isolationMode(agent.code_name) === "docker";
|
|
@@ -19509,7 +19773,7 @@ Retried to the limit after repeated stalls \u2014 needs a look.`).catch(() => {
|
|
|
19509
19773
|
refreshData.agent.onboarding_state
|
|
19510
19774
|
);
|
|
19511
19775
|
const obStep = obState.step;
|
|
19512
|
-
const markerPath = join42(
|
|
19776
|
+
const markerPath = join42(homedir17(), ".augmented", agent.code_name, "onboarding-drive.json");
|
|
19513
19777
|
const marker = readOnboardingDriveMarker(markerPath);
|
|
19514
19778
|
const obContactRaw = refreshData.agent.manager_last_contacted_at;
|
|
19515
19779
|
const obContact = typeof obContactRaw === "string" && obContactRaw ? obContactRaw : null;
|
|
@@ -20549,7 +20813,7 @@ async function handleRestartDoorbell(agentId, requestedAt, restartReason) {
|
|
|
20549
20813
|
try {
|
|
20550
20814
|
const freshId = rotateSessionForWedge(codeName);
|
|
20551
20815
|
consecutiveWedgeCycles.delete(codeName);
|
|
20552
|
-
const { parkPendingInbound: parkForRestart } = await import("../responsiveness-probe-
|
|
20816
|
+
const { parkPendingInbound: parkForRestart } = await import("../responsiveness-probe-J2DYGC7T.js");
|
|
20553
20817
|
const { parked, deadLettered } = parkForRestart(codeName, /* @__PURE__ */ new Date());
|
|
20554
20818
|
const parkNote = parked > 0 ? `, ${parked} inbound parked` : "";
|
|
20555
20819
|
const deadNote = deadLettered > 0 ? `, ${deadLettered} undeliverable dead-lettered` : "";
|
|
@@ -20592,7 +20856,7 @@ async function handleRestartDoorbell(agentId, requestedAt, restartReason) {
|
|
|
20592
20856
|
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}`));
|
|
20593
20857
|
void (async () => {
|
|
20594
20858
|
try {
|
|
20595
|
-
const { collectDiagnostics } = await import("../persistent-session-
|
|
20859
|
+
const { collectDiagnostics } = await import("../persistent-session-5KWYODZB.js");
|
|
20596
20860
|
await api.post("/host/heartbeat", {
|
|
20597
20861
|
host_id: hostId,
|
|
20598
20862
|
agent_diagnostics: collectDiagnostics([codeName], quarantineEntriesFor, claudeMdSizeFor, spawnOutcomeForDiagnostics, pidPressureFor, forwardedToolsFor)
|
|
@@ -20643,7 +20907,7 @@ async function respawnAgentAfterMcpStop(codeName, reason) {
|
|
|
20643
20907
|
}
|
|
20644
20908
|
try {
|
|
20645
20909
|
const hostId = await getHostId();
|
|
20646
|
-
const { collectDiagnostics } = await import("../persistent-session-
|
|
20910
|
+
const { collectDiagnostics } = await import("../persistent-session-5KWYODZB.js");
|
|
20647
20911
|
await api.post("/host/heartbeat", {
|
|
20648
20912
|
host_id: hostId,
|
|
20649
20913
|
agent_diagnostics: collectDiagnostics([codeName], quarantineEntriesFor, claudeMdSizeFor, spawnOutcomeForDiagnostics, pidPressureFor, forwardedToolsFor)
|
|
@@ -21067,7 +21331,7 @@ async function processDirectChatMessage(agent, msg) {
|
|
|
21067
21331
|
const useDoorbell = hostFlagStore().getBoolean("direct-chat-doorbell") || isolationMode(agent.codeName) === "docker";
|
|
21068
21332
|
if (useDoorbell) {
|
|
21069
21333
|
try {
|
|
21070
|
-
const doorbell = directChatDoorbellPath(agent.agentId,
|
|
21334
|
+
const doorbell = directChatDoorbellPath(agent.agentId, homedir17());
|
|
21071
21335
|
mkdirSync15(dirname11(doorbell), { recursive: true });
|
|
21072
21336
|
writeFileSync18(doorbell, String(Date.now()));
|
|
21073
21337
|
log(`[direct-chat] Doorbell rung for '${agent.codeName}' (msg=${msg.id}) \u2014 in-session MCP will pull via the cursor`);
|
|
@@ -21196,7 +21460,7 @@ ${formatRunMarker(run_id)}` : KANBAN_CHECK_COMMAND;
|
|
|
21196
21460
|
}
|
|
21197
21461
|
if (run_id) openInjectedRunByCode.set(codeName, run_id);
|
|
21198
21462
|
try {
|
|
21199
|
-
const doorbell = directChatDoorbellPath(agentId,
|
|
21463
|
+
const doorbell = directChatDoorbellPath(agentId, homedir17());
|
|
21200
21464
|
mkdirSync15(dirname11(doorbell), { recursive: true });
|
|
21201
21465
|
writeFileSync18(doorbell, String(Date.now()));
|
|
21202
21466
|
} catch (err) {
|
|
@@ -21302,8 +21566,19 @@ async function processClaudePairSessions(agents) {
|
|
|
21302
21566
|
spawnPairSession,
|
|
21303
21567
|
killPairSession,
|
|
21304
21568
|
pairTmuxSession,
|
|
21305
|
-
finalizeClaudePairOnboarding
|
|
21306
|
-
|
|
21569
|
+
finalizeClaudePairOnboarding,
|
|
21570
|
+
// ENG-10862: the failure vocabulary lives beside the loop that produces it,
|
|
21571
|
+
// so the code the console stores and the message the operator reads cannot
|
|
21572
|
+
// drift from the reason finalize actually returned.
|
|
21573
|
+
PAIR_FINALIZE_ERROR_CODES,
|
|
21574
|
+
describePairFinalizeFailure,
|
|
21575
|
+
// ENG-10862: the last-chance re-read before a failure is reported.
|
|
21576
|
+
confirmPairFailure,
|
|
21577
|
+
// ENG-10862: the pre-submit mtime baseline. Taken here because finalize
|
|
21578
|
+
// cannot take it for itself — by the time it runs, the write it is looking
|
|
21579
|
+
// for may already have happened.
|
|
21580
|
+
snapshotPairConfig
|
|
21581
|
+
} = await import("../claude-pair-runtime-X27QVAXL.js");
|
|
21307
21582
|
for (const pairId of pendingResp.cancelled_pair_ids ?? []) {
|
|
21308
21583
|
log(`[claude-pair] sweeping orphan tmux session for pair ${pairId.slice(0, 8)}`);
|
|
21309
21584
|
const killed = await killPairSession(pairTmuxSession(pairId));
|
|
@@ -21323,7 +21598,8 @@ async function processClaudePairSessions(agents) {
|
|
|
21323
21598
|
async function reportAndCleanup(pairId, body) {
|
|
21324
21599
|
await api.post("/host/claude-pair/result", { pair_id: pairId, ...body });
|
|
21325
21600
|
if (typeof body.status === "string" && TERMINAL.has(body.status)) {
|
|
21326
|
-
|
|
21601
|
+
const isOnboardingFailure = typeof body.error_code === "string" && body.error_code.startsWith("onboarding_");
|
|
21602
|
+
if (body.status === "success" || isOnboardingFailure) {
|
|
21327
21603
|
await new Promise((r) => setTimeout(r, 3e3));
|
|
21328
21604
|
}
|
|
21329
21605
|
const killed = await killPairSession(pairTmuxSession(pairId));
|
|
@@ -21375,16 +21651,50 @@ async function processClaudePairSessions(agents) {
|
|
|
21375
21651
|
}
|
|
21376
21652
|
} else if (session.status === "code_submitted" && session.code) {
|
|
21377
21653
|
log(`[claude-pair] submitting code (pair ${session.pair_id.slice(0, 8)})`);
|
|
21654
|
+
const configBaseline = snapshotPairConfig();
|
|
21378
21655
|
const result = await submitClaudePairCode({
|
|
21379
21656
|
session: pairSession,
|
|
21380
21657
|
code: session.code
|
|
21381
21658
|
});
|
|
21382
21659
|
if (result.kind === "success") {
|
|
21383
|
-
const finalize = await finalizeClaudePairOnboarding(pairSession, log
|
|
21384
|
-
|
|
21385
|
-
|
|
21660
|
+
const finalize = await finalizeClaudePairOnboarding(pairSession, log, {
|
|
21661
|
+
baseline: configBaseline
|
|
21662
|
+
});
|
|
21663
|
+
const pairShort = session.pair_id.slice(0, 8);
|
|
21664
|
+
const confirmed = finalize.finalized ? "landed-after-all" : await confirmPairFailure({
|
|
21665
|
+
configPath: finalize.configPath,
|
|
21666
|
+
sinceMtimeMs: configBaseline.mtimeMs,
|
|
21667
|
+
log
|
|
21668
|
+
});
|
|
21669
|
+
if (!finalize.finalized && confirmed === "confirmed") {
|
|
21670
|
+
const reason = finalize.reason ?? "not-flushed";
|
|
21671
|
+
const errorCode = PAIR_FINALIZE_ERROR_CODES[reason];
|
|
21672
|
+
log(
|
|
21673
|
+
`[claude-pair] onboarding did NOT persist (pair ${pairShort}) reason=${reason} code=${errorCode} iterations=${finalize.iterations} graceWaits=${finalize.graceWaits} consumerTerms=${finalize.counts.consumerTerms} dialogEnter=${finalize.counts.dialogEnter} noMatch=${finalize.counts.noMatch} \u2014 reporting the pairing as FAILED`
|
|
21674
|
+
);
|
|
21675
|
+
await reportAndCleanup(session.pair_id, {
|
|
21676
|
+
status: "failure",
|
|
21677
|
+
error_code: errorCode,
|
|
21678
|
+
// The path finalize actually watched, returned by it rather than
|
|
21679
|
+
// recomputed here — two copies of that rule is how the operator
|
|
21680
|
+
// ends up reading about a file the flow never looked at.
|
|
21681
|
+
error_message: describePairFinalizeFailure(reason, finalize.configPath),
|
|
21682
|
+
// AC5: the loop's own accounting, so "do real pairings need more
|
|
21683
|
+
// than 10 dismissals?" stops being unanswerable. Counts only —
|
|
21684
|
+
// never pane text, which carries `Logged in as <email>`. These
|
|
21685
|
+
// are NOT stored on the pair row (no column, by decision); the
|
|
21686
|
+
// route forwards them into the alert payload, which is jsonb.
|
|
21687
|
+
finalize_iterations: finalize.iterations,
|
|
21688
|
+
finalize_grace_waits: finalize.graceWaits,
|
|
21689
|
+
finalize_dialog_counts: finalize.counts
|
|
21690
|
+
});
|
|
21691
|
+
} else {
|
|
21692
|
+
const lateness = finalize.finalized ? "" : ` (late: finalize said ${finalize.reason}, config landed during the confirm window)`;
|
|
21693
|
+
log(
|
|
21694
|
+
`[claude-pair] onboarding persisted (pair ${pairShort}) iterations=${finalize.iterations} graceWaits=${finalize.graceWaits} consumerTerms=${finalize.counts.consumerTerms} dialogEnter=${finalize.counts.dialogEnter} noMatch=${finalize.counts.noMatch}${lateness}`
|
|
21695
|
+
);
|
|
21696
|
+
await reportAndCleanup(session.pair_id, { status: "success" });
|
|
21386
21697
|
}
|
|
21387
|
-
await reportAndCleanup(session.pair_id, { status: "success" });
|
|
21388
21698
|
} else if (result.kind === "failure") {
|
|
21389
21699
|
await reportAndCleanup(session.pair_id, {
|
|
21390
21700
|
status: "failure",
|
|
@@ -21545,7 +21855,7 @@ function loadMemoryManifest(agentId, configDir, codeName) {
|
|
|
21545
21855
|
if (cached) return cached;
|
|
21546
21856
|
let manifest = {};
|
|
21547
21857
|
try {
|
|
21548
|
-
const raw =
|
|
21858
|
+
const raw = readFileSync34(memoryManifestPath(configDir, codeName), "utf-8");
|
|
21549
21859
|
const parsed = JSON.parse(raw);
|
|
21550
21860
|
if (parsed && typeof parsed === "object" && !Array.isArray(parsed)) {
|
|
21551
21861
|
for (const [name, entry] of Object.entries(parsed)) {
|
|
@@ -21660,7 +21970,7 @@ function applyMemoryTombstones(opts) {
|
|
|
21660
21970
|
continue;
|
|
21661
21971
|
}
|
|
21662
21972
|
try {
|
|
21663
|
-
const actual = createHash20("sha256").update(
|
|
21973
|
+
const actual = createHash20("sha256").update(readFileSync34(filePath)).digest("hex");
|
|
21664
21974
|
if (actual !== entry.sha) {
|
|
21665
21975
|
outcomes.kept_modified++;
|
|
21666
21976
|
outcomes.unapplied.push({ name: tomb.name, reason: "kept_modified" });
|
|
@@ -21760,7 +22070,7 @@ async function syncMemories(agent, configDir, log2) {
|
|
|
21760
22070
|
for (const file of readdirSync12(memoryDir)) {
|
|
21761
22071
|
if (!file.endsWith(".md")) continue;
|
|
21762
22072
|
try {
|
|
21763
|
-
const raw =
|
|
22073
|
+
const raw = readFileSync34(join42(memoryDir, file), "utf-8");
|
|
21764
22074
|
const fileHash = createHash20("sha256").update(raw).digest("hex").slice(0, 16);
|
|
21765
22075
|
currentHashes.set(file, fileHash);
|
|
21766
22076
|
if (prevHashes.get(file) === fileHash) continue;
|
|
@@ -21785,7 +22095,7 @@ async function syncMemories(agent, configDir, log2) {
|
|
|
21785
22095
|
} catch (err) {
|
|
21786
22096
|
for (const mem of changedMemories) {
|
|
21787
22097
|
for (const [file] of currentHashes) {
|
|
21788
|
-
const parsed = parseMemoryFile(
|
|
22098
|
+
const parsed = parseMemoryFile(readFileSync34(join42(memoryDir, file), "utf-8"), file.replace(/\.md$/, ""));
|
|
21789
22099
|
if (parsed?.name === mem.name) currentHashes.delete(file);
|
|
21790
22100
|
}
|
|
21791
22101
|
}
|
|
@@ -21924,7 +22234,7 @@ ${mem.content}
|
|
|
21924
22234
|
if (existsSync19(filePath)) {
|
|
21925
22235
|
let existing = "";
|
|
21926
22236
|
try {
|
|
21927
|
-
existing =
|
|
22237
|
+
existing = readFileSync34(filePath, "utf-8");
|
|
21928
22238
|
} catch {
|
|
21929
22239
|
}
|
|
21930
22240
|
if (existing === desired) {
|
|
@@ -22089,6 +22399,16 @@ function startPolling() {
|
|
|
22089
22399
|
livenessTimer.unref();
|
|
22090
22400
|
startPaneOccupancySampler(() => agentState.persistentSessionAgents);
|
|
22091
22401
|
startPidPressureSampler(() => agentState.persistentSessionAgents);
|
|
22402
|
+
{
|
|
22403
|
+
const seedOutcome = seedClaudeConfigFromLegacy({ log });
|
|
22404
|
+
const configDirUsable = claudeConfigDirIsReady();
|
|
22405
|
+
if (configDirUsable && !process.env[CLAUDE_CONFIG_DIR_ENV]?.trim()) {
|
|
22406
|
+
process.env[CLAUDE_CONFIG_DIR_ENV] = claudeConfigDirFor();
|
|
22407
|
+
}
|
|
22408
|
+
log(
|
|
22409
|
+
`[claude-config] ${CLAUDE_CONFIG_DIR_ENV}=${process.env[CLAUDE_CONFIG_DIR_ENV] ?? "<not adopted>"} configDirUsable=${configDirUsable} seed=${seedOutcome}`
|
|
22410
|
+
);
|
|
22411
|
+
}
|
|
22092
22412
|
void startCaffeinate();
|
|
22093
22413
|
loadChannelHashCache2();
|
|
22094
22414
|
loadSenderPolicyBaseline2();
|
|
@@ -22304,7 +22624,7 @@ function startManager(opts) {
|
|
|
22304
22624
|
try {
|
|
22305
22625
|
const stateFile = getStateFile();
|
|
22306
22626
|
if (existsSync19(stateFile)) {
|
|
22307
|
-
const raw =
|
|
22627
|
+
const raw = readFileSync34(stateFile, "utf-8");
|
|
22308
22628
|
const parsed = JSON.parse(raw);
|
|
22309
22629
|
if (Array.isArray(parsed.agents)) {
|
|
22310
22630
|
state8.agents = parsed.agents;
|
|
@@ -22331,7 +22651,7 @@ function startManager(opts) {
|
|
|
22331
22651
|
log(`[startup] state rehydration failed (continuing with empty state): ${err.message}`);
|
|
22332
22652
|
}
|
|
22333
22653
|
log(
|
|
22334
|
-
`[startup] worker pid=${process.pid} ppid=${process.ppid} node=${process.version} log=${join42(
|
|
22654
|
+
`[startup] worker pid=${process.pid} ppid=${process.ppid} node=${process.version} log=${join42(homedir17(), ".augmented", "manager.log")}`
|
|
22335
22655
|
);
|
|
22336
22656
|
deployMcpAssets();
|
|
22337
22657
|
reapOrphanChannelMcps({ log });
|
|
@@ -22360,7 +22680,7 @@ async function reapOrphanedClaudePids() {
|
|
|
22360
22680
|
const looksLikeClaude = (pid) => {
|
|
22361
22681
|
if (process.platform !== "linux") return true;
|
|
22362
22682
|
try {
|
|
22363
|
-
const comm =
|
|
22683
|
+
const comm = readFileSync34(`/proc/${pid}/comm`, "utf-8").trim().toLowerCase();
|
|
22364
22684
|
return comm.includes("claude");
|
|
22365
22685
|
} catch {
|
|
22366
22686
|
return false;
|
|
@@ -22457,7 +22777,7 @@ function restartRunningChannelMcps(basenames) {
|
|
|
22457
22777
|
}
|
|
22458
22778
|
}
|
|
22459
22779
|
function deployMcpAssets() {
|
|
22460
|
-
const targetDir = join42(
|
|
22780
|
+
const targetDir = join42(homedir17(), ".augmented", "_mcp");
|
|
22461
22781
|
mkdirSync15(targetDir, { recursive: true });
|
|
22462
22782
|
const moduleDir = dirname11(fileURLToPath2(import.meta.url));
|
|
22463
22783
|
let mcpSourceDir = "";
|
|
@@ -22482,7 +22802,7 @@ function deployMcpAssets() {
|
|
|
22482
22802
|
const fileHash = (p) => {
|
|
22483
22803
|
try {
|
|
22484
22804
|
if (!existsSync19(p)) return null;
|
|
22485
|
-
return createHash20("sha256").update(
|
|
22805
|
+
return createHash20("sha256").update(readFileSync34(p)).digest("hex");
|
|
22486
22806
|
} catch {
|
|
22487
22807
|
return null;
|
|
22488
22808
|
}
|
|
@@ -22593,14 +22913,14 @@ function deployMcpAssets() {
|
|
|
22593
22913
|
}
|
|
22594
22914
|
const localMcpPath = join42(targetDir, "index.js");
|
|
22595
22915
|
try {
|
|
22596
|
-
const agentsDir = join42(
|
|
22916
|
+
const agentsDir = join42(homedir17(), ".augmented", "agents");
|
|
22597
22917
|
if (existsSync19(agentsDir)) {
|
|
22598
22918
|
for (const entry of readdirSync12(agentsDir, { withFileTypes: true })) {
|
|
22599
22919
|
if (!entry.isDirectory()) continue;
|
|
22600
22920
|
for (const subdir of ["provision", "project"]) {
|
|
22601
22921
|
const mcpJsonPath = join42(agentsDir, entry.name, subdir, ".mcp.json");
|
|
22602
22922
|
try {
|
|
22603
|
-
const raw =
|
|
22923
|
+
const raw = readFileSync34(mcpJsonPath, "utf-8");
|
|
22604
22924
|
if (!raw.includes("@integrity-labs/augmented-mcp")) continue;
|
|
22605
22925
|
const mcpConfig = JSON.parse(raw);
|
|
22606
22926
|
const augServer = mcpConfig.mcpServers?.["augmented"];
|