@integrity-labs/agt-cli 0.28.1005 → 0.28.1006
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 +5 -5
- package/dist/{chunk-TGTUE7Y2.js → chunk-O6R6HS2Z.js} +2 -2
- package/dist/{chunk-DVSYT4MU.js → chunk-XWMUQR65.js} +52 -1
- package/dist/{chunk-DVSYT4MU.js.map → chunk-XWMUQR65.js.map} +1 -1
- package/dist/{chunk-6U4NB3LJ.js → chunk-Z5UDL4AB.js} +35 -5
- package/dist/{chunk-6U4NB3LJ.js.map → chunk-Z5UDL4AB.js.map} +1 -1
- package/dist/{claude-pair-runtime-DDSYAHQW.js → claude-pair-runtime-AW4N6NEE.js} +157 -18
- package/dist/claude-pair-runtime-AW4N6NEE.js.map +1 -0
- package/dist/lib/manager-worker.js +609 -304
- 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-K4DLZ7KF.js} +3 -3
- package/dist/{responsiveness-probe-6NWZAXIZ.js → responsiveness-probe-DXPEIUH6.js} +3 -3
- package/dist/{session-auth-dead-2V2BOXAG.js → session-auth-dead-4SE5Q7MU.js} +2 -2
- package/package.json +1 -1
- package/dist/claude-pair-runtime-DDSYAHQW.js.map +0 -1
- /package/dist/{chunk-TGTUE7Y2.js.map → chunk-O6R6HS2Z.js.map} +0 -0
- /package/dist/{persistent-session-4PP3ON7H.js.map → persistent-session-K4DLZ7KF.js.map} +0 -0
- /package/dist/{responsiveness-probe-6NWZAXIZ.js.map → responsiveness-probe-DXPEIUH6.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-Z5UDL4AB.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-O6R6HS2Z.js";
|
|
145
146
|
import {
|
|
146
147
|
ACCOUNT_ENFORCEMENT_MARKER_FILENAME,
|
|
147
148
|
AnchorSessionClient,
|
|
@@ -240,7 +241,7 @@ 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
|
|
@@ -249,7 +250,7 @@ import "../chunk-DGUM43GV.js";
|
|
|
249
250
|
|
|
250
251
|
// src/lib/manager-worker.ts
|
|
251
252
|
import { createHash as createHash20 } from "crypto";
|
|
252
|
-
import { readFileSync as
|
|
253
|
+
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
254
|
|
|
254
255
|
// src/lib/atomic-file-replace.ts
|
|
255
256
|
import { copyFileSync, renameSync, unlinkSync } from "fs";
|
|
@@ -275,7 +276,7 @@ function defaultUnique() {
|
|
|
275
276
|
|
|
276
277
|
// src/lib/manager-worker.ts
|
|
277
278
|
import { execFileSync as syncExecFile } from "child_process";
|
|
278
|
-
import { join as
|
|
279
|
+
import { join as join43, dirname as dirname11, delimiter as pathDelimiter } from "path";
|
|
279
280
|
import { homedir as homedir18 } from "os";
|
|
280
281
|
import { fileURLToPath as fileURLToPath2 } from "url";
|
|
281
282
|
|
|
@@ -1053,9 +1054,157 @@ function clearOnboardingDriveMarker(path) {
|
|
|
1053
1054
|
}
|
|
1054
1055
|
}
|
|
1055
1056
|
|
|
1056
|
-
// src/lib/channel-
|
|
1057
|
+
// src/lib/channel-auto-resume.ts
|
|
1057
1058
|
import { readFileSync as readFileSync3 } from "fs";
|
|
1058
1059
|
import { join as join3 } from "path";
|
|
1060
|
+
var AUTO_RESUME_BASE_MS = 2 * 60 * 6e4;
|
|
1061
|
+
var AUTO_RESUME_MAX_MS = 24 * 60 * 6e4;
|
|
1062
|
+
var AUTO_RESUME_MAX_ATTEMPTS = 5;
|
|
1063
|
+
var QUARANTINE_DWELL_FLOOR_MS = 18e4;
|
|
1064
|
+
var AUTO_RESUME_SUCCESS_GRACE_MS = 2 * (DEAD_CHANNEL_MS + QUARANTINE_DWELL_FLOOR_MS);
|
|
1065
|
+
function defaultResumeHistoryPath(configDir) {
|
|
1066
|
+
return join3(configDir, "channel-quarantine-resumes.json");
|
|
1067
|
+
}
|
|
1068
|
+
function isResumeFile(value) {
|
|
1069
|
+
if (!value || typeof value !== "object" || Array.isArray(value)) return false;
|
|
1070
|
+
for (const forAgent of Object.values(value)) {
|
|
1071
|
+
if (!forAgent || typeof forAgent !== "object" || Array.isArray(forAgent)) return false;
|
|
1072
|
+
for (const entry of Object.values(forAgent)) {
|
|
1073
|
+
if (!entry || typeof entry !== "object") return false;
|
|
1074
|
+
const e = entry;
|
|
1075
|
+
if (e.gaveUpLogged !== void 0 && typeof e.gaveUpLogged !== "boolean") return false;
|
|
1076
|
+
const attempts = e.attempts;
|
|
1077
|
+
const lastAttemptAt = e.lastAttemptAt;
|
|
1078
|
+
if (typeof attempts !== "number" || !Number.isSafeInteger(attempts) || attempts < 0 || typeof lastAttemptAt !== "number" || !Number.isSafeInteger(lastAttemptAt) || lastAttemptAt < 0) {
|
|
1079
|
+
return false;
|
|
1080
|
+
}
|
|
1081
|
+
}
|
|
1082
|
+
}
|
|
1083
|
+
return true;
|
|
1084
|
+
}
|
|
1085
|
+
var ChannelResumeHistoryStore = class {
|
|
1086
|
+
path;
|
|
1087
|
+
cache = null;
|
|
1088
|
+
constructor(path) {
|
|
1089
|
+
this.path = path;
|
|
1090
|
+
}
|
|
1091
|
+
load() {
|
|
1092
|
+
if (this.cache) return this.cache;
|
|
1093
|
+
try {
|
|
1094
|
+
const parsed = JSON.parse(readFileSync3(this.path, "utf-8"));
|
|
1095
|
+
this.cache = isResumeFile(parsed) ? parsed : {};
|
|
1096
|
+
} catch {
|
|
1097
|
+
this.cache = {};
|
|
1098
|
+
}
|
|
1099
|
+
return this.cache;
|
|
1100
|
+
}
|
|
1101
|
+
persist() {
|
|
1102
|
+
atomicWriteFileSync(this.path, JSON.stringify(this.cache ?? {}, null, 2));
|
|
1103
|
+
}
|
|
1104
|
+
get(codeName, serverKey) {
|
|
1105
|
+
return this.load()[codeName]?.[serverKey];
|
|
1106
|
+
}
|
|
1107
|
+
/**
|
|
1108
|
+
* Every recorded key for one agent, as [storedKey, entry] pairs.
|
|
1109
|
+
*
|
|
1110
|
+
* Needed because the success sweep asks about channels that are NOT in the
|
|
1111
|
+
* quarantine store — a trial that worked leaves history behind and no marker,
|
|
1112
|
+
* so a loop over quarantine entries can never reach it. Returns the STORED
|
|
1113
|
+
* key (see `resumeHistoryKey`), not the channel key, because the caller is
|
|
1114
|
+
* the only thing that knows which namespace it is working in.
|
|
1115
|
+
*/
|
|
1116
|
+
entriesFor(codeName) {
|
|
1117
|
+
return Object.entries(this.load()[codeName] ?? {});
|
|
1118
|
+
}
|
|
1119
|
+
/** Record a trial. Returns the entry as written. */
|
|
1120
|
+
recordAttempt(codeName, serverKey, now) {
|
|
1121
|
+
const file = this.load();
|
|
1122
|
+
const forAgent = file[codeName] ??= {};
|
|
1123
|
+
const prior = forAgent[serverKey];
|
|
1124
|
+
const next = {
|
|
1125
|
+
attempts: (prior?.attempts ?? 0) + 1,
|
|
1126
|
+
lastAttemptAt: now,
|
|
1127
|
+
// Carried, not reset: a further trial inside the same episode must not
|
|
1128
|
+
// re-arm the give-up line. It clears with the entry itself on forget().
|
|
1129
|
+
...prior?.gaveUpLogged ? { gaveUpLogged: true } : {}
|
|
1130
|
+
};
|
|
1131
|
+
forAgent[serverKey] = next;
|
|
1132
|
+
this.persist();
|
|
1133
|
+
return next;
|
|
1134
|
+
}
|
|
1135
|
+
/**
|
|
1136
|
+
* Forget a key's history — called when an OPERATOR clears the quarantine.
|
|
1137
|
+
*
|
|
1138
|
+
* A human pressing Re-enable is a statement that the underlying fault was
|
|
1139
|
+
* addressed, so the next automatic trial should start from a clean two hours
|
|
1140
|
+
* rather than inheriting strikes from before the fix. Without this an
|
|
1141
|
+
* operator could fix a channel, watch it break again for an unrelated reason
|
|
1142
|
+
* weeks later, and find auto-resume already exhausted.
|
|
1143
|
+
*/
|
|
1144
|
+
forget(codeName, serverKey) {
|
|
1145
|
+
const file = this.load();
|
|
1146
|
+
const forAgent = file[codeName];
|
|
1147
|
+
if (!forAgent || !forAgent[serverKey]) return false;
|
|
1148
|
+
delete forAgent[serverKey];
|
|
1149
|
+
if (Object.keys(forAgent).length === 0) delete file[codeName];
|
|
1150
|
+
this.persist();
|
|
1151
|
+
return true;
|
|
1152
|
+
}
|
|
1153
|
+
/**
|
|
1154
|
+
* Latch the give-up line for this key. Returns whether it had ALREADY been
|
|
1155
|
+
* logged, so the caller logs only on the first call of an episode.
|
|
1156
|
+
*
|
|
1157
|
+
* Returns true (already logged) when there is no entry at all: with no
|
|
1158
|
+
* history there are no strikes, so there is nothing to have given up ON, and
|
|
1159
|
+
* announcing an abandonment would be false.
|
|
1160
|
+
*/
|
|
1161
|
+
noteGaveUpLogged(codeName, serverKey) {
|
|
1162
|
+
const file = this.load();
|
|
1163
|
+
const entry = file[codeName]?.[serverKey];
|
|
1164
|
+
if (!entry) return true;
|
|
1165
|
+
if (entry.gaveUpLogged) return true;
|
|
1166
|
+
entry.gaveUpLogged = true;
|
|
1167
|
+
this.persist();
|
|
1168
|
+
return false;
|
|
1169
|
+
}
|
|
1170
|
+
__invalidateCacheForTests() {
|
|
1171
|
+
this.cache = null;
|
|
1172
|
+
}
|
|
1173
|
+
};
|
|
1174
|
+
function resumeHistoryKey(mode, serverKey) {
|
|
1175
|
+
return mode === "shadow" ? `shadow:${serverKey}` : serverKey;
|
|
1176
|
+
}
|
|
1177
|
+
function backoffForAttempt(attemptsAlreadyMade) {
|
|
1178
|
+
const doubled = AUTO_RESUME_BASE_MS * 2 ** Math.max(0, attemptsAlreadyMade);
|
|
1179
|
+
return Math.min(doubled, AUTO_RESUME_MAX_MS);
|
|
1180
|
+
}
|
|
1181
|
+
function resolveAutoResumeEffectiveMode(autoResume, quarantine) {
|
|
1182
|
+
if (autoResume === "enforce" && quarantine !== "enforce") return "shadow";
|
|
1183
|
+
return autoResume;
|
|
1184
|
+
}
|
|
1185
|
+
function autoResumeSuccessGraceMs(configuredDwellMs) {
|
|
1186
|
+
const dwell = typeof configuredDwellMs === "number" && Number.isFinite(configuredDwellMs) && configuredDwellMs > QUARANTINE_DWELL_FLOOR_MS ? configuredDwellMs : QUARANTINE_DWELL_FLOOR_MS;
|
|
1187
|
+
return 2 * (DEAD_CHANNEL_MS + dwell);
|
|
1188
|
+
}
|
|
1189
|
+
function shouldForgetResumeHistory(input) {
|
|
1190
|
+
if (input.isQuarantined) return false;
|
|
1191
|
+
const history = input.history;
|
|
1192
|
+
if (!history || history.attempts === 0) return false;
|
|
1193
|
+
return input.now - history.lastAttemptAt >= autoResumeSuccessGraceMs(input.configuredDwellMs);
|
|
1194
|
+
}
|
|
1195
|
+
function decideChannelAutoResume(input) {
|
|
1196
|
+
const attempts = input.history?.attempts ?? 0;
|
|
1197
|
+
if (attempts >= AUTO_RESUME_MAX_ATTEMPTS) return { action: "give-up", attempts };
|
|
1198
|
+
const since = Math.max(input.quarantinedAt, input.history?.lastAttemptAt ?? 0);
|
|
1199
|
+
const waited = input.now - since;
|
|
1200
|
+
const need = backoffForAttempt(attempts);
|
|
1201
|
+
if (waited >= need) return { action: "resume", waitedMs: waited, attempt: attempts + 1 };
|
|
1202
|
+
return { action: "wait", dueInMs: need - waited, attempt: attempts + 1 };
|
|
1203
|
+
}
|
|
1204
|
+
|
|
1205
|
+
// src/lib/channel-quarantine.ts
|
|
1206
|
+
import { readFileSync as readFileSync4 } from "fs";
|
|
1207
|
+
import { join as join4 } from "path";
|
|
1059
1208
|
var ESSENTIAL_CHANNEL_KEYS = /* @__PURE__ */ new Set(["direct-chat", "augmented"]);
|
|
1060
1209
|
var OPTIONAL_CHANNEL_KEYS = /* @__PURE__ */ new Set([
|
|
1061
1210
|
"telegram",
|
|
@@ -1087,7 +1236,7 @@ function classifyChannelCriticality(serverKey, entry) {
|
|
|
1087
1236
|
return "essential";
|
|
1088
1237
|
}
|
|
1089
1238
|
function defaultQuarantinePath(configDir) {
|
|
1090
|
-
return
|
|
1239
|
+
return join4(configDir, "channel-quarantine.json");
|
|
1091
1240
|
}
|
|
1092
1241
|
var ChannelQuarantineStore = class {
|
|
1093
1242
|
path;
|
|
@@ -1098,7 +1247,7 @@ var ChannelQuarantineStore = class {
|
|
|
1098
1247
|
load() {
|
|
1099
1248
|
if (this.cache) return this.cache;
|
|
1100
1249
|
try {
|
|
1101
|
-
const raw =
|
|
1250
|
+
const raw = readFileSync4(this.path, "utf-8");
|
|
1102
1251
|
const parsed = JSON.parse(raw);
|
|
1103
1252
|
this.cache = isQuarantineFile(parsed) ? parsed : {};
|
|
1104
1253
|
} catch {
|
|
@@ -1186,13 +1335,13 @@ function isQuarantineFile(value) {
|
|
|
1186
1335
|
}
|
|
1187
1336
|
|
|
1188
1337
|
// src/lib/claude-md-size.ts
|
|
1189
|
-
import { readFileSync as
|
|
1190
|
-
import { join as
|
|
1338
|
+
import { readFileSync as readFileSync5 } from "fs";
|
|
1339
|
+
import { join as join5 } from "path";
|
|
1191
1340
|
function measureClaudeMd(configDir, codeName, ceiling = CLAUDE_MD_CONTEXT_ALARM_CHARS) {
|
|
1192
1341
|
let chars;
|
|
1193
1342
|
let bytes;
|
|
1194
1343
|
try {
|
|
1195
|
-
const buf =
|
|
1344
|
+
const buf = readFileSync5(join5(configDir, codeName, "project", "CLAUDE.md"));
|
|
1196
1345
|
chars = buf.toString("utf8").length;
|
|
1197
1346
|
bytes = buf.length;
|
|
1198
1347
|
} catch {
|
|
@@ -1212,8 +1361,8 @@ function measureClaudeMd(configDir, codeName, ceiling = CLAUDE_MD_CONTEXT_ALARM_
|
|
|
1212
1361
|
function measureCoreKnowledgeDescription(configDir, codeName) {
|
|
1213
1362
|
let text;
|
|
1214
1363
|
try {
|
|
1215
|
-
text =
|
|
1216
|
-
|
|
1364
|
+
text = readFileSync5(
|
|
1365
|
+
join5(configDir, codeName, "project", ".claude", "skills", "core-knowledge", "SKILL.md"),
|
|
1217
1366
|
"utf8"
|
|
1218
1367
|
);
|
|
1219
1368
|
} catch {
|
|
@@ -1247,16 +1396,16 @@ function logClaudeMdCeilingTransition(codeName, report, log2) {
|
|
|
1247
1396
|
}
|
|
1248
1397
|
|
|
1249
1398
|
// ../../packages/core/dist/integrations/forwarded-tools-report.js
|
|
1250
|
-
import { readFileSync as
|
|
1251
|
-
import { join as
|
|
1399
|
+
import { readFileSync as readFileSync6, writeFileSync as writeFileSync3 } from "fs";
|
|
1400
|
+
import { join as join6 } from "path";
|
|
1252
1401
|
var FORWARDED_TOOLS_REPORT_FILENAME = "forwarded-tools.json";
|
|
1253
1402
|
function forwardedToolsReportPath(agentDir) {
|
|
1254
|
-
return
|
|
1403
|
+
return join6(agentDir, FORWARDED_TOOLS_REPORT_FILENAME);
|
|
1255
1404
|
}
|
|
1256
1405
|
function readForwardedToolsReport(agentDir) {
|
|
1257
1406
|
let raw;
|
|
1258
1407
|
try {
|
|
1259
|
-
raw =
|
|
1408
|
+
raw = readFileSync6(forwardedToolsReportPath(agentDir), "utf-8");
|
|
1260
1409
|
} catch {
|
|
1261
1410
|
return null;
|
|
1262
1411
|
}
|
|
@@ -1873,9 +2022,9 @@ var DependencyRecoveryLedger = class {
|
|
|
1873
2022
|
// src/lib/mcp-assets-ready.ts
|
|
1874
2023
|
import { existsSync as nodeExistsSync, readFileSync as nodeReadFileSync } from "fs";
|
|
1875
2024
|
import { homedir as homedir2 } from "os";
|
|
1876
|
-
import { join as
|
|
2025
|
+
import { join as join7, resolve, sep } from "path";
|
|
1877
2026
|
function getSharedMcpDir(homeDir = homedir2()) {
|
|
1878
|
-
return
|
|
2027
|
+
return join7(homeDir, ".augmented", "_mcp");
|
|
1879
2028
|
}
|
|
1880
2029
|
function isPathInsideDir(candidate, dir) {
|
|
1881
2030
|
const resolvedDir = resolve(dir);
|
|
@@ -1885,11 +2034,11 @@ function isPathInsideDir(candidate, dir) {
|
|
|
1885
2034
|
}
|
|
1886
2035
|
function findMissingMcpBundles(mcpConfigPath, deps = {}) {
|
|
1887
2036
|
const existsSync20 = deps.existsSync ?? nodeExistsSync;
|
|
1888
|
-
const
|
|
2037
|
+
const readFileSync35 = deps.readFileSync ?? nodeReadFileSync;
|
|
1889
2038
|
const mcpDir = deps.mcpDir ?? getSharedMcpDir();
|
|
1890
2039
|
let parsed;
|
|
1891
2040
|
try {
|
|
1892
|
-
parsed = JSON.parse(
|
|
2041
|
+
parsed = JSON.parse(readFileSync35(mcpConfigPath, "utf-8"));
|
|
1893
2042
|
} catch {
|
|
1894
2043
|
return [];
|
|
1895
2044
|
}
|
|
@@ -1927,7 +2076,7 @@ function formatMissingMcpBundles(missing) {
|
|
|
1927
2076
|
}
|
|
1928
2077
|
|
|
1929
2078
|
// src/lib/self-update-coalesce.ts
|
|
1930
|
-
import { readFileSync as
|
|
2079
|
+
import { readFileSync as readFileSync7, writeFileSync as writeFileSync4, mkdirSync as mkdirSync3 } from "fs";
|
|
1931
2080
|
import { dirname as dirname4 } from "path";
|
|
1932
2081
|
var DEFAULT_SELF_UPDATE_COALESCE_MS = 30 * 60 * 1e3;
|
|
1933
2082
|
function resolveCoalesceWindowMs(env = process.env) {
|
|
@@ -1937,7 +2086,7 @@ function resolveCoalesceWindowMs(env = process.env) {
|
|
|
1937
2086
|
if (!Number.isFinite(parsed) || parsed < 0) return DEFAULT_SELF_UPDATE_COALESCE_MS;
|
|
1938
2087
|
return Math.trunc(parsed);
|
|
1939
2088
|
}
|
|
1940
|
-
function readLastSelfUpdateAppliedMs(markerPath, now = Date.now(), read = (p) =>
|
|
2089
|
+
function readLastSelfUpdateAppliedMs(markerPath, now = Date.now(), read = (p) => readFileSync7(p, "utf-8")) {
|
|
1941
2090
|
let raw;
|
|
1942
2091
|
try {
|
|
1943
2092
|
raw = read(markerPath);
|
|
@@ -2242,11 +2391,11 @@ async function reportModelApiError(opts) {
|
|
|
2242
2391
|
}
|
|
2243
2392
|
|
|
2244
2393
|
// src/lib/claude-pid-tracker.ts
|
|
2245
|
-
import { existsSync, readFileSync as
|
|
2394
|
+
import { existsSync, readFileSync as readFileSync8 } from "fs";
|
|
2246
2395
|
function readPidFile(path) {
|
|
2247
2396
|
if (!existsSync(path)) return { version: 1, spawns: [] };
|
|
2248
2397
|
try {
|
|
2249
|
-
const raw = JSON.parse(
|
|
2398
|
+
const raw = JSON.parse(readFileSync8(path, "utf-8"));
|
|
2250
2399
|
if (raw.version !== 1 || !Array.isArray(raw.spawns)) return { version: 1, spawns: [] };
|
|
2251
2400
|
const spawns = raw.spawns.filter(
|
|
2252
2401
|
(s) => !!s && typeof s.pid === "number" && Number.isFinite(s.pid) && s.pid > 0
|
|
@@ -2346,14 +2495,14 @@ async function killSessionsConcurrently(sessions, killOne) {
|
|
|
2346
2495
|
}
|
|
2347
2496
|
|
|
2348
2497
|
// src/lib/direct-chat-delivery.ts
|
|
2349
|
-
import { join as
|
|
2498
|
+
import { join as join8 } from "path";
|
|
2350
2499
|
var DEFAULT_DIRECT_CHAT_MAX_AGE_MS = 30 * 6e4;
|
|
2351
2500
|
function directChatMaxAgeMs() {
|
|
2352
2501
|
const raw = parseInt(process.env["AGT_DIRECT_CHAT_MAX_AGE_MS"] ?? "", 10);
|
|
2353
2502
|
return Number.isFinite(raw) && raw >= 0 ? raw : DEFAULT_DIRECT_CHAT_MAX_AGE_MS;
|
|
2354
2503
|
}
|
|
2355
2504
|
function directChatDoorbellPath(agentId, home) {
|
|
2356
|
-
return
|
|
2505
|
+
return join8(home, ".augmented", agentId, "direct-chat-doorbell");
|
|
2357
2506
|
}
|
|
2358
2507
|
function isDirectChatMessageExpired(createdAt, nowMs, maxAgeMs) {
|
|
2359
2508
|
if (!maxAgeMs || maxAgeMs <= 0) return false;
|
|
@@ -2364,8 +2513,8 @@ function isDirectChatMessageExpired(createdAt, nowMs, maxAgeMs) {
|
|
|
2364
2513
|
}
|
|
2365
2514
|
|
|
2366
2515
|
// 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
|
|
2516
|
+
import { copyFileSync as copyFileSync2, chmodSync, existsSync as existsSync2, mkdirSync as mkdirSync4, readFileSync as readFileSync9 } from "fs";
|
|
2517
|
+
import { dirname as dirname5, join as join9 } from "path";
|
|
2369
2518
|
import { fileURLToPath } from "url";
|
|
2370
2519
|
var POSTER_FILENAME = "post-review-findings.mjs";
|
|
2371
2520
|
var AUTH_FILENAME = "obiwan-auth.mjs";
|
|
@@ -2378,14 +2527,14 @@ function resolveBundledReviewAssetDir() {
|
|
|
2378
2527
|
const moduleDir = dirname5(fileURLToPath(import.meta.url));
|
|
2379
2528
|
const candidates = [
|
|
2380
2529
|
// Built output: dist/<chunk>.js → dist/assets/review
|
|
2381
|
-
|
|
2530
|
+
join9(moduleDir, "assets", REVIEW_ASSET_DIRNAME),
|
|
2382
2531
|
// Built output sibling case: dist/<sub>/<chunk>.js → dist/assets/review
|
|
2383
|
-
|
|
2532
|
+
join9(moduleDir, "..", "assets", REVIEW_ASSET_DIRNAME),
|
|
2384
2533
|
// Dev source: src/lib/review-poster-asset.ts → ../../assets/review
|
|
2385
|
-
|
|
2534
|
+
join9(moduleDir, "..", "..", "assets", REVIEW_ASSET_DIRNAME)
|
|
2386
2535
|
];
|
|
2387
2536
|
for (const candidate of candidates) {
|
|
2388
|
-
if (existsSync2(
|
|
2537
|
+
if (existsSync2(join9(candidate, POSTER_FILENAME))) return candidate;
|
|
2389
2538
|
}
|
|
2390
2539
|
throw new Error(
|
|
2391
2540
|
`[review-poster] could not locate bundled assets; tried:
|
|
@@ -2393,18 +2542,18 @@ function resolveBundledReviewAssetDir() {
|
|
|
2393
2542
|
);
|
|
2394
2543
|
}
|
|
2395
2544
|
function reviewPosterDir(codeName) {
|
|
2396
|
-
return
|
|
2545
|
+
return join9(getFramework("claude-code").getAgentDir(codeName), REVIEW_ASSET_DIRNAME);
|
|
2397
2546
|
}
|
|
2398
2547
|
function provisionReviewPoster(codeName, sourceDir = resolveBundledReviewAssetDir()) {
|
|
2399
2548
|
const destDir = reviewPosterDir(codeName);
|
|
2400
2549
|
mkdirSync4(destDir, { recursive: true });
|
|
2401
2550
|
for (const [name, mode] of ASSET_FILES) {
|
|
2402
|
-
const src =
|
|
2403
|
-
const dest =
|
|
2551
|
+
const src = join9(sourceDir, name);
|
|
2552
|
+
const dest = join9(destDir, name);
|
|
2404
2553
|
if (!existsSync2(src)) {
|
|
2405
2554
|
throw new Error(`[review-poster] bundled asset missing: ${src}`);
|
|
2406
2555
|
}
|
|
2407
|
-
if (!existsSync2(dest) || !
|
|
2556
|
+
if (!existsSync2(dest) || !readFileSync9(src).equals(readFileSync9(dest))) {
|
|
2408
2557
|
copyFileSync2(src, dest);
|
|
2409
2558
|
}
|
|
2410
2559
|
chmodSync(dest, mode);
|
|
@@ -2413,7 +2562,7 @@ function provisionReviewPoster(codeName, sourceDir = resolveBundledReviewAssetDi
|
|
|
2413
2562
|
|
|
2414
2563
|
// src/lib/id-keyed-migration.ts
|
|
2415
2564
|
import { existsSync as existsSync3, lstatSync, readlinkSync, renameSync as renameSync2 } from "fs";
|
|
2416
|
-
import { join as
|
|
2565
|
+
import { join as join10 } from "path";
|
|
2417
2566
|
import { homedir as homedir3 } from "os";
|
|
2418
2567
|
var ID_KEYED_MIGRATION_FLAG = "id-keyed-layout-migration";
|
|
2419
2568
|
function agentHasActiveWhatsapp(channelConfigs, codeNameDir) {
|
|
@@ -2421,7 +2570,7 @@ function agentHasActiveWhatsapp(channelConfigs, codeNameDir) {
|
|
|
2421
2570
|
return true;
|
|
2422
2571
|
}
|
|
2423
2572
|
try {
|
|
2424
|
-
if (existsSync3(
|
|
2573
|
+
if (existsSync3(join10(codeNameDir, "whatsapp-pending-inbound"))) return true;
|
|
2425
2574
|
} catch {
|
|
2426
2575
|
}
|
|
2427
2576
|
return false;
|
|
@@ -2453,10 +2602,10 @@ function finishTranscriptMove(oldCwd, newCwd, codeName, log2) {
|
|
|
2453
2602
|
function maybeMigrateAgentToIdKeyedLayout(agent, deps) {
|
|
2454
2603
|
const home = deps.home ?? homedir3();
|
|
2455
2604
|
const { code_name: codeName, agent_id: agentId } = agent;
|
|
2456
|
-
const codeNamePath =
|
|
2457
|
-
const idPath =
|
|
2458
|
-
const oldCwd =
|
|
2459
|
-
const newCwd =
|
|
2605
|
+
const codeNamePath = join10(home, ".augmented", codeName);
|
|
2606
|
+
const idPath = join10(home, ".augmented", agentId);
|
|
2607
|
+
const oldCwd = join10(home, ".augmented", codeName, "project");
|
|
2608
|
+
const newCwd = join10(idPath, "project");
|
|
2460
2609
|
let codeNameKind;
|
|
2461
2610
|
try {
|
|
2462
2611
|
codeNameKind = lstatSync(codeNamePath).isSymbolicLink() ? "symlink" : "realdir";
|
|
@@ -2583,8 +2732,8 @@ function collectEnvGates(env) {
|
|
|
2583
2732
|
}
|
|
2584
2733
|
|
|
2585
2734
|
// ../../packages/core/dist/direct-chat/cursor-advance-telemetry.js
|
|
2586
|
-
import { readFileSync as
|
|
2587
|
-
import { join as
|
|
2735
|
+
import { readFileSync as readFileSync10, writeFileSync as writeFileSync5 } from "fs";
|
|
2736
|
+
import { join as join11 } from "path";
|
|
2588
2737
|
var CURSOR_SHORTFALL_COUNTER_SUFFIX = "-cursor-advance-classifications.json";
|
|
2589
2738
|
function recordCursorAdvanceOutcome(agentDir, source, route, verdict) {
|
|
2590
2739
|
if (!agentDir)
|
|
@@ -2592,10 +2741,10 @@ function recordCursorAdvanceOutcome(agentDir, source, route, verdict) {
|
|
|
2592
2741
|
const key = cursorAdvanceCounterKey(route, verdict);
|
|
2593
2742
|
if (key === null)
|
|
2594
2743
|
return;
|
|
2595
|
-
const path =
|
|
2744
|
+
const path = join11(agentDir, `${source}${CURSOR_SHORTFALL_COUNTER_SUFFIX}`);
|
|
2596
2745
|
const counts = {};
|
|
2597
2746
|
try {
|
|
2598
|
-
const parsed = JSON.parse(
|
|
2747
|
+
const parsed = JSON.parse(readFileSync10(path, "utf-8"));
|
|
2599
2748
|
if (parsed && typeof parsed === "object" && !Array.isArray(parsed)) {
|
|
2600
2749
|
for (const [k, v] of Object.entries(parsed)) {
|
|
2601
2750
|
if (typeof v === "number" && Number.isInteger(v) && v >= 0)
|
|
@@ -2612,7 +2761,7 @@ function recordCursorAdvanceOutcome(agentDir, source, route, verdict) {
|
|
|
2612
2761
|
}
|
|
2613
2762
|
|
|
2614
2763
|
// src/lib/artifact-stream.ts
|
|
2615
|
-
import { join as
|
|
2764
|
+
import { join as join12 } from "path";
|
|
2616
2765
|
import { homedir as homedir4 } from "os";
|
|
2617
2766
|
import { readdir, stat, readFile } from "fs/promises";
|
|
2618
2767
|
var ARTEFACT_ENTRY_FILE = "index.html";
|
|
@@ -2698,7 +2847,7 @@ var ArtifactStreamScanner = class {
|
|
|
2698
2847
|
return;
|
|
2699
2848
|
}
|
|
2700
2849
|
for (const name of names) {
|
|
2701
|
-
const file =
|
|
2850
|
+
const file = join12(this.artifactsDir, name, ARTEFACT_ENTRY_FILE);
|
|
2702
2851
|
const mtime = await this.fsDeps.mtimeMs(file).catch(() => null);
|
|
2703
2852
|
if (mtime === null) continue;
|
|
2704
2853
|
if (this.seenMtime.get(name) === mtime) continue;
|
|
@@ -2729,7 +2878,7 @@ var ArtifactStreamScanner = class {
|
|
|
2729
2878
|
}
|
|
2730
2879
|
};
|
|
2731
2880
|
function artifactsDirFor(codeName) {
|
|
2732
|
-
return
|
|
2881
|
+
return join12(homedir4(), ".augmented", codeName, "artifacts");
|
|
2733
2882
|
}
|
|
2734
2883
|
var nodeArtifactFs = {
|
|
2735
2884
|
async listArtefactNames(artifactsDir) {
|
|
@@ -3005,12 +3154,12 @@ async function maybePollHostUsage(deps) {
|
|
|
3005
3154
|
import { createHash as createHash6 } from "crypto";
|
|
3006
3155
|
import { readFile as readFile3, readdir as readdir3 } from "fs/promises";
|
|
3007
3156
|
import { homedir as homedir6, platform as platform2 } from "os";
|
|
3008
|
-
import { dirname as dirname6, join as
|
|
3157
|
+
import { dirname as dirname6, join as join14 } from "path";
|
|
3009
3158
|
|
|
3010
3159
|
// src/lib/claude-auth-detect.ts
|
|
3011
3160
|
import { readFile as readFile2, readdir as readdir2 } from "fs/promises";
|
|
3012
3161
|
import { homedir as homedir5, platform } from "os";
|
|
3013
|
-
import { join as
|
|
3162
|
+
import { join as join13 } from "path";
|
|
3014
3163
|
import { execFile } from "child_process";
|
|
3015
3164
|
import { promisify } from "util";
|
|
3016
3165
|
var execFileAsync = promisify(execFile);
|
|
@@ -3025,16 +3174,16 @@ async function detectClaudeAuth() {
|
|
|
3025
3174
|
}
|
|
3026
3175
|
async function findClaudeCredentialsPaths() {
|
|
3027
3176
|
const candidates = [
|
|
3028
|
-
|
|
3029
|
-
|
|
3177
|
+
join13(homedir5(), ".claude", ".credentials.json"),
|
|
3178
|
+
join13(homedir5(), ".claude", "credentials.json")
|
|
3030
3179
|
];
|
|
3031
3180
|
const isLinuxRoot = platform() === "linux" && typeof process.getuid === "function" && process.getuid() === 0;
|
|
3032
3181
|
if (isLinuxRoot) {
|
|
3033
3182
|
try {
|
|
3034
3183
|
const entries = await readdir2("/home", { withFileTypes: true });
|
|
3035
3184
|
for (const entry of entries.filter((entry2) => entry2.isDirectory()).sort((a, b) => a.name.localeCompare(b.name))) {
|
|
3036
|
-
candidates.push(
|
|
3037
|
-
candidates.push(
|
|
3185
|
+
candidates.push(join13("/home", entry.name, ".claude", ".credentials.json"));
|
|
3186
|
+
candidates.push(join13("/home", entry.name, ".claude", "credentials.json"));
|
|
3038
3187
|
}
|
|
3039
3188
|
} catch {
|
|
3040
3189
|
}
|
|
@@ -3118,7 +3267,7 @@ async function candidateHomes() {
|
|
|
3118
3267
|
try {
|
|
3119
3268
|
const entries = await readdir3("/home", { withFileTypes: true });
|
|
3120
3269
|
for (const entry of entries.filter((e) => e.isDirectory()).sort((a, b) => a.name.localeCompare(b.name))) {
|
|
3121
|
-
homes.push(
|
|
3270
|
+
homes.push(join14("/home", entry.name));
|
|
3122
3271
|
}
|
|
3123
3272
|
} catch {
|
|
3124
3273
|
}
|
|
@@ -3138,11 +3287,11 @@ async function homeOfActiveCredentials() {
|
|
|
3138
3287
|
async function claudeConfigCandidatePaths() {
|
|
3139
3288
|
const paths = [];
|
|
3140
3289
|
const configDir = process.env["CLAUDE_CONFIG_DIR"]?.trim();
|
|
3141
|
-
if (configDir) paths.push(
|
|
3290
|
+
if (configDir) paths.push(join14(configDir, ".claude.json"));
|
|
3142
3291
|
const activeHome = await homeOfActiveCredentials();
|
|
3143
|
-
if (activeHome) paths.push(
|
|
3292
|
+
if (activeHome) paths.push(join14(activeHome, ".claude.json"));
|
|
3144
3293
|
for (const home of await candidateHomes()) {
|
|
3145
|
-
const path =
|
|
3294
|
+
const path = join14(home, ".claude.json");
|
|
3146
3295
|
if (!paths.includes(path)) paths.push(path);
|
|
3147
3296
|
}
|
|
3148
3297
|
return paths;
|
|
@@ -3261,9 +3410,9 @@ function diffAuthTuples(recorded, current) {
|
|
|
3261
3410
|
// src/lib/account-enforcement-marker.ts
|
|
3262
3411
|
import { mkdirSync as mkdirSync5, renameSync as renameSync3, rmSync as rmSync2, writeFileSync as writeFileSync6 } from "fs";
|
|
3263
3412
|
import { homedir as homedir7 } from "os";
|
|
3264
|
-
import { join as
|
|
3413
|
+
import { join as join15 } from "path";
|
|
3265
3414
|
function accountEnforcementMarkerPath(codeName) {
|
|
3266
|
-
return
|
|
3415
|
+
return join15(homedir7(), ".augmented", codeName, ACCOUNT_ENFORCEMENT_MARKER_FILENAME);
|
|
3267
3416
|
}
|
|
3268
3417
|
function syncAccountEnforcementMarker(codeName, level, log2 = (m) => process.stderr.write(`${m}
|
|
3269
3418
|
`), text) {
|
|
@@ -3271,8 +3420,8 @@ function syncAccountEnforcementMarker(codeName, level, log2 = (m) => process.std
|
|
|
3271
3420
|
clearAccountEnforcementMarker(codeName, log2);
|
|
3272
3421
|
return;
|
|
3273
3422
|
}
|
|
3274
|
-
const dir =
|
|
3275
|
-
const path =
|
|
3423
|
+
const dir = join15(homedir7(), ".augmented", codeName);
|
|
3424
|
+
const path = join15(dir, ACCOUNT_ENFORCEMENT_MARKER_FILENAME);
|
|
3276
3425
|
const tempPath = `${path}.${process.pid}.tmp`;
|
|
3277
3426
|
try {
|
|
3278
3427
|
mkdirSync5(dir, { recursive: true });
|
|
@@ -3297,8 +3446,8 @@ function clearAccountEnforcementMarker(codeName, log2 = (m) => process.stderr.wr
|
|
|
3297
3446
|
}
|
|
3298
3447
|
|
|
3299
3448
|
// src/lib/token-usage-monitor.ts
|
|
3300
|
-
import { readdirSync, readFileSync as
|
|
3301
|
-
import { join as
|
|
3449
|
+
import { readdirSync, readFileSync as readFileSync11, statSync } from "fs";
|
|
3450
|
+
import { join as join16 } from "path";
|
|
3302
3451
|
var MIN_CHECK_INTERVAL_MS2 = 6e4;
|
|
3303
3452
|
var TRANSCRIPT_MTIME_WINDOW_MS = 2 * 24 * 60 * 60 * 1e3;
|
|
3304
3453
|
var MAX_ENTRIES_PER_POST = 200;
|
|
@@ -3327,7 +3476,7 @@ async function maybeReportTokenUsage(args) {
|
|
|
3327
3476
|
if (!name.endsWith(".jsonl")) continue;
|
|
3328
3477
|
const sessionId = name.slice(0, -".jsonl".length);
|
|
3329
3478
|
if (!sessionId) continue;
|
|
3330
|
-
const path =
|
|
3479
|
+
const path = join16(dir, name);
|
|
3331
3480
|
let st;
|
|
3332
3481
|
try {
|
|
3333
3482
|
st = statSync(path);
|
|
@@ -3343,7 +3492,7 @@ async function maybeReportTokenUsage(args) {
|
|
|
3343
3492
|
}
|
|
3344
3493
|
let content;
|
|
3345
3494
|
try {
|
|
3346
|
-
content =
|
|
3495
|
+
content = readFileSync11(path, "utf-8");
|
|
3347
3496
|
} catch (err) {
|
|
3348
3497
|
log2(`[token-usage] read failed for '${codeName}/${name}': ${err.message}`);
|
|
3349
3498
|
continue;
|
|
@@ -3424,8 +3573,8 @@ async function maybeReportTokenUsage(args) {
|
|
|
3424
3573
|
}
|
|
3425
3574
|
|
|
3426
3575
|
// src/lib/workflow-run-reconciler.ts
|
|
3427
|
-
import { readdirSync as readdirSync2, readFileSync as
|
|
3428
|
-
import { join as
|
|
3576
|
+
import { readdirSync as readdirSync2, readFileSync as readFileSync12, statSync as statSync2 } from "fs";
|
|
3577
|
+
import { join as join17 } from "path";
|
|
3429
3578
|
var MIN_CHECK_INTERVAL_MS3 = 5 * 6e4;
|
|
3430
3579
|
var SETTLE_MS = 3e4;
|
|
3431
3580
|
var TRANSCRIPT_MTIME_WINDOW_MS2 = 2 * 24 * 60 * 60 * 1e3;
|
|
@@ -3444,7 +3593,7 @@ function collectJsonlRecursive(dir, minMtimeMs, out, depth) {
|
|
|
3444
3593
|
return;
|
|
3445
3594
|
}
|
|
3446
3595
|
for (const name of entries) {
|
|
3447
|
-
const p =
|
|
3596
|
+
const p = join17(dir, name);
|
|
3448
3597
|
let st;
|
|
3449
3598
|
try {
|
|
3450
3599
|
st = statSync2(p);
|
|
@@ -3467,7 +3616,7 @@ function enumerateTranscriptFiles(transcriptDir, nowMs, minMtimeMs = nowMs - TRA
|
|
|
3467
3616
|
return out;
|
|
3468
3617
|
}
|
|
3469
3618
|
for (const name of entries) {
|
|
3470
|
-
const path =
|
|
3619
|
+
const path = join17(transcriptDir, name);
|
|
3471
3620
|
let st;
|
|
3472
3621
|
try {
|
|
3473
3622
|
st = statSync2(path);
|
|
@@ -3479,7 +3628,7 @@ function enumerateTranscriptFiles(transcriptDir, nowMs, minMtimeMs = nowMs - TRA
|
|
|
3479
3628
|
continue;
|
|
3480
3629
|
}
|
|
3481
3630
|
if (st.isDirectory()) {
|
|
3482
|
-
collectJsonlRecursive(
|
|
3631
|
+
collectJsonlRecursive(join17(path, "subagents"), minMtimeMs, out, 0);
|
|
3483
3632
|
}
|
|
3484
3633
|
}
|
|
3485
3634
|
return out;
|
|
@@ -3524,7 +3673,7 @@ async function maybeReconcileWorkflowRunTokens(args) {
|
|
|
3524
3673
|
const contents = [];
|
|
3525
3674
|
for (const path of files) {
|
|
3526
3675
|
try {
|
|
3527
|
-
contents.push(
|
|
3676
|
+
contents.push(readFileSync12(path, "utf-8"));
|
|
3528
3677
|
} catch {
|
|
3529
3678
|
}
|
|
3530
3679
|
}
|
|
@@ -3569,8 +3718,8 @@ async function maybeReconcileWorkflowRunTokens(args) {
|
|
|
3569
3718
|
}
|
|
3570
3719
|
|
|
3571
3720
|
// src/lib/conversation-evaluator.ts
|
|
3572
|
-
import { readdirSync as readdirSync3, readFileSync as
|
|
3573
|
-
import { join as
|
|
3721
|
+
import { readdirSync as readdirSync3, readFileSync as readFileSync13, statSync as statSync3 } from "fs";
|
|
3722
|
+
import { join as join18 } from "path";
|
|
3574
3723
|
|
|
3575
3724
|
// src/lib/detect-meta-egress.ts
|
|
3576
3725
|
var REPOST_PREAMBLE_WINDOW = 200;
|
|
@@ -4055,7 +4204,7 @@ function readRecentTurns(dir, nowMs) {
|
|
|
4055
4204
|
return;
|
|
4056
4205
|
}
|
|
4057
4206
|
for (const ent of entries) {
|
|
4058
|
-
const full =
|
|
4207
|
+
const full = join18(d, ent.name);
|
|
4059
4208
|
if (ent.isDirectory()) {
|
|
4060
4209
|
visit(full);
|
|
4061
4210
|
continue;
|
|
@@ -4070,7 +4219,7 @@ function readRecentTurns(dir, nowMs) {
|
|
|
4070
4219
|
if (nowMs - mtimeMs > TRANSCRIPT_MTIME_WINDOW_MS3) continue;
|
|
4071
4220
|
let content;
|
|
4072
4221
|
try {
|
|
4073
|
-
content =
|
|
4222
|
+
content = readFileSync13(full, "utf8");
|
|
4074
4223
|
} catch {
|
|
4075
4224
|
continue;
|
|
4076
4225
|
}
|
|
@@ -4443,22 +4592,22 @@ async function reportSkip2(api2, agentId, conversationId, log2, codeName) {
|
|
|
4443
4592
|
|
|
4444
4593
|
// src/lib/tool-call-audit.ts
|
|
4445
4594
|
import { homedir as homedir11 } from "os";
|
|
4446
|
-
import { join as
|
|
4595
|
+
import { join as join23 } from "path";
|
|
4447
4596
|
|
|
4448
4597
|
// src/lib/agent-logging-mode.ts
|
|
4449
|
-
import { readFileSync as
|
|
4598
|
+
import { readFileSync as readFileSync14 } from "fs";
|
|
4450
4599
|
import { homedir as homedir8 } from "os";
|
|
4451
|
-
import { join as
|
|
4600
|
+
import { join as join19 } from "path";
|
|
4452
4601
|
var LOGGING_MODES = ["hash-only", "redacted", "full-local"];
|
|
4453
4602
|
function charterPath(codeName, homeDir) {
|
|
4454
4603
|
const home = homeDir ?? (process.env["HOME"]?.trim() || homedir8());
|
|
4455
4604
|
const key = agentRuntimeKey(codeName, homeDir);
|
|
4456
|
-
return
|
|
4605
|
+
return join19(home, ".augmented", key, "provision", "CHARTER.md");
|
|
4457
4606
|
}
|
|
4458
4607
|
function readAgentLoggingMode(codeName, homeDir) {
|
|
4459
4608
|
let raw;
|
|
4460
4609
|
try {
|
|
4461
|
-
raw =
|
|
4610
|
+
raw = readFileSync14(charterPath(codeName, homeDir), "utf-8");
|
|
4462
4611
|
} catch {
|
|
4463
4612
|
return { mode: null, reason: "no-charter" };
|
|
4464
4613
|
}
|
|
@@ -4482,15 +4631,15 @@ function loggingModeWithholdsTargets(reading) {
|
|
|
4482
4631
|
|
|
4483
4632
|
// src/lib/tool-call-path-salt.ts
|
|
4484
4633
|
import { randomBytes } from "crypto";
|
|
4485
|
-
import { existsSync as existsSync4, mkdirSync as mkdirSync6, readFileSync as
|
|
4634
|
+
import { existsSync as existsSync4, mkdirSync as mkdirSync6, readFileSync as readFileSync15, renameSync as renameSync4, unlinkSync as unlinkSync2, writeFileSync as writeFileSync7 } from "fs";
|
|
4486
4635
|
import { homedir as homedir9 } from "os";
|
|
4487
|
-
import { dirname as dirname7, join as
|
|
4636
|
+
import { dirname as dirname7, join as join20 } from "path";
|
|
4488
4637
|
var SALT_BYTES = 32;
|
|
4489
4638
|
var SALT_RE = /^[0-9a-f]{64}$/;
|
|
4490
4639
|
function pathSaltPath(codeName, homeDir) {
|
|
4491
4640
|
const home = homeDir ?? (process.env["HOME"]?.trim() || homedir9());
|
|
4492
4641
|
const key = agentRuntimeKey(codeName, homeDir);
|
|
4493
|
-
return
|
|
4642
|
+
return join20(home, ".augmented", key, "tool-call-path-salt");
|
|
4494
4643
|
}
|
|
4495
4644
|
function readToolCallPathSalt(codeName, homeDir) {
|
|
4496
4645
|
let file;
|
|
@@ -4501,7 +4650,7 @@ function readToolCallPathSalt(codeName, homeDir) {
|
|
|
4501
4650
|
}
|
|
4502
4651
|
try {
|
|
4503
4652
|
if (existsSync4(file)) {
|
|
4504
|
-
const existing =
|
|
4653
|
+
const existing = readFileSync15(file, "utf-8").trim();
|
|
4505
4654
|
if (SALT_RE.test(existing)) return existing;
|
|
4506
4655
|
}
|
|
4507
4656
|
} catch {
|
|
@@ -4527,8 +4676,8 @@ function readToolCallPathSalt(codeName, homeDir) {
|
|
|
4527
4676
|
import { statSync as statSync4 } from "fs";
|
|
4528
4677
|
|
|
4529
4678
|
// src/lib/tool-call-extractor.ts
|
|
4530
|
-
import { closeSync, fstatSync, openSync, readFileSync as
|
|
4531
|
-
import { basename as basename2, join as
|
|
4679
|
+
import { closeSync, fstatSync, openSync, readFileSync as readFileSync16, readSync, readdirSync as readdirSync4 } from "fs";
|
|
4680
|
+
import { basename as basename2, join as join21, relative } from "path";
|
|
4532
4681
|
import { StringDecoder } from "string_decoder";
|
|
4533
4682
|
|
|
4534
4683
|
// src/lib/tool-call-redaction.ts
|
|
@@ -4657,7 +4806,7 @@ function redactToolTargetInner(toolName, input, ctx) {
|
|
|
4657
4806
|
var EXTRACTOR_VERSION = "e1";
|
|
4658
4807
|
function enumerateSessionTranscripts(transcriptDir, sessionId, projectsRoot) {
|
|
4659
4808
|
const files = [];
|
|
4660
|
-
const mainAbs =
|
|
4809
|
+
const mainAbs = join21(transcriptDir, `${sessionId}.jsonl`);
|
|
4661
4810
|
files.push({
|
|
4662
4811
|
absPath: mainAbs,
|
|
4663
4812
|
relPath: relative(projectsRoot, mainAbs),
|
|
@@ -4665,7 +4814,7 @@ function enumerateSessionTranscripts(transcriptDir, sessionId, projectsRoot) {
|
|
|
4665
4814
|
isSubagent: false,
|
|
4666
4815
|
subagentId: null
|
|
4667
4816
|
});
|
|
4668
|
-
const subDir =
|
|
4817
|
+
const subDir = join21(transcriptDir, sessionId, "subagents");
|
|
4669
4818
|
let entries;
|
|
4670
4819
|
try {
|
|
4671
4820
|
entries = readdirSync4(subDir);
|
|
@@ -4674,7 +4823,7 @@ function enumerateSessionTranscripts(transcriptDir, sessionId, projectsRoot) {
|
|
|
4674
4823
|
}
|
|
4675
4824
|
for (const name of entries) {
|
|
4676
4825
|
if (!name.endsWith(".jsonl")) continue;
|
|
4677
|
-
const abs =
|
|
4826
|
+
const abs = join21(subDir, name);
|
|
4678
4827
|
const stem = basename2(name, ".jsonl");
|
|
4679
4828
|
files.push({
|
|
4680
4829
|
absPath: abs,
|
|
@@ -4872,9 +5021,9 @@ function extractTranscriptWindow(file, opts, from) {
|
|
|
4872
5021
|
}
|
|
4873
5022
|
|
|
4874
5023
|
// src/lib/tool-call-cursor.ts
|
|
4875
|
-
import { existsSync as existsSync5, readFileSync as
|
|
5024
|
+
import { existsSync as existsSync5, readFileSync as readFileSync17 } from "fs";
|
|
4876
5025
|
import { homedir as homedir10 } from "os";
|
|
4877
|
-
import { join as
|
|
5026
|
+
import { join as join22 } from "path";
|
|
4878
5027
|
var COVERAGE_DISPOSITIONS = [
|
|
4879
5028
|
"ok",
|
|
4880
5029
|
"not_entitled",
|
|
@@ -4929,13 +5078,13 @@ function parseCursorKey(key) {
|
|
|
4929
5078
|
function cursorStatePath(codeName, homeDir) {
|
|
4930
5079
|
const home = homeDir ?? (process.env["HOME"]?.trim() || homedir10());
|
|
4931
5080
|
const key = agentRuntimeKey(codeName, homeDir);
|
|
4932
|
-
return
|
|
5081
|
+
return join22(home, ".augmented", key, "tool-call-cursors.json");
|
|
4933
5082
|
}
|
|
4934
5083
|
function loadCursors(path) {
|
|
4935
5084
|
const out = /* @__PURE__ */ new Map();
|
|
4936
5085
|
if (!existsSync5(path)) return out;
|
|
4937
5086
|
try {
|
|
4938
|
-
const parsed = JSON.parse(
|
|
5087
|
+
const parsed = JSON.parse(readFileSync17(path, "utf-8"));
|
|
4939
5088
|
if (!parsed || parsed.version !== 1 || typeof parsed.files !== "object") return out;
|
|
4940
5089
|
for (const [k, v] of Object.entries(parsed.files)) {
|
|
4941
5090
|
if (!v || typeof v !== "object") continue;
|
|
@@ -5342,7 +5491,7 @@ async function maybeScanToolCalls(args) {
|
|
|
5342
5491
|
log2(`[tool-call-audit] ${codeName}: no path-hash salt available \u2014 file targets withheld`);
|
|
5343
5492
|
}
|
|
5344
5493
|
const home = args.homeDir ?? (process.env["HOME"]?.trim() || homedir11());
|
|
5345
|
-
const projectsRoot = args.projectsRoot ??
|
|
5494
|
+
const projectsRoot = args.projectsRoot ?? join23(home, ".claude", "projects");
|
|
5346
5495
|
const transcriptDir = args.transcriptDir ?? sessionTranscriptDir(getProjectDir(codeName));
|
|
5347
5496
|
const current = peekCurrentSession(codeName);
|
|
5348
5497
|
const sessionIds = current ? [current.sessionId] : [];
|
|
@@ -5371,11 +5520,11 @@ async function maybeScanToolCalls(args) {
|
|
|
5371
5520
|
}
|
|
5372
5521
|
|
|
5373
5522
|
// src/lib/activity-cache-monitor.ts
|
|
5374
|
-
import { existsSync as existsSync6, readFileSync as
|
|
5523
|
+
import { existsSync as existsSync6, readFileSync as readFileSync18 } from "fs";
|
|
5375
5524
|
import { homedir as homedir12 } from "os";
|
|
5376
|
-
import { join as
|
|
5525
|
+
import { join as join24 } from "path";
|
|
5377
5526
|
var MIN_CHECK_INTERVAL_MS7 = 6e4;
|
|
5378
|
-
var STATS_CACHE_PATH =
|
|
5527
|
+
var STATS_CACHE_PATH = join24(homedir12(), ".claude", "stats-cache.json");
|
|
5379
5528
|
var ISO_DATE_RE = /^\d{4}-\d{2}-\d{2}$/;
|
|
5380
5529
|
var state7 = { lastObservedDate: null, lastCheckedAt: 0 };
|
|
5381
5530
|
function selectNewDailyRows(raw, lastObservedDate) {
|
|
@@ -5423,7 +5572,7 @@ async function maybeReportActivityCache(args) {
|
|
|
5423
5572
|
}
|
|
5424
5573
|
let raw;
|
|
5425
5574
|
try {
|
|
5426
|
-
raw =
|
|
5575
|
+
raw = readFileSync18(STATS_CACHE_PATH, "utf-8");
|
|
5427
5576
|
} catch (err) {
|
|
5428
5577
|
log2(`[activity-cache] readFileSync failed: ${err.message}`);
|
|
5429
5578
|
return;
|
|
@@ -5726,7 +5875,7 @@ import { createHash as createHash9 } from "crypto";
|
|
|
5726
5875
|
import {
|
|
5727
5876
|
existsSync as existsSync7,
|
|
5728
5877
|
mkdirSync as mkdirSync7,
|
|
5729
|
-
readFileSync as
|
|
5878
|
+
readFileSync as readFileSync19,
|
|
5730
5879
|
readdirSync as readdirSync5,
|
|
5731
5880
|
renameSync as renameSync5,
|
|
5732
5881
|
rmSync as rmSync3,
|
|
@@ -5734,7 +5883,7 @@ import {
|
|
|
5734
5883
|
utimesSync,
|
|
5735
5884
|
writeFileSync as writeFileSync8
|
|
5736
5885
|
} from "fs";
|
|
5737
|
-
import { join as
|
|
5886
|
+
import { join as join25 } from "path";
|
|
5738
5887
|
var KNOWLEDGE_FETCH_CHUNK = 100;
|
|
5739
5888
|
var CACHE_TTL_MS = 30 * 24 * 60 * 60 * 1e3;
|
|
5740
5889
|
var SWEEP_INTERVAL_MS = 24 * 60 * 60 * 1e3;
|
|
@@ -5743,12 +5892,12 @@ function knowledgeHash(content) {
|
|
|
5743
5892
|
return createHash9("sha256").update(content, "utf8").digest("hex");
|
|
5744
5893
|
}
|
|
5745
5894
|
function cachePath(cacheDir, hash) {
|
|
5746
|
-
return
|
|
5895
|
+
return join25(cacheDir, hash);
|
|
5747
5896
|
}
|
|
5748
5897
|
function readCachedKnowledge(cacheDir, hash) {
|
|
5749
5898
|
const path = cachePath(cacheDir, hash);
|
|
5750
5899
|
try {
|
|
5751
|
-
const content =
|
|
5900
|
+
const content = readFileSync19(path, "utf-8");
|
|
5752
5901
|
try {
|
|
5753
5902
|
const now = /* @__PURE__ */ new Date();
|
|
5754
5903
|
utimesSync(path, now, now);
|
|
@@ -5777,7 +5926,7 @@ function sweepKnowledgeCache(cacheDir, now = Date.now()) {
|
|
|
5777
5926
|
try {
|
|
5778
5927
|
if (!existsSync7(cacheDir)) return;
|
|
5779
5928
|
for (const name of readdirSync5(cacheDir)) {
|
|
5780
|
-
const path =
|
|
5929
|
+
const path = join25(cacheDir, name);
|
|
5781
5930
|
try {
|
|
5782
5931
|
if (now - statSync6(path).mtimeMs > CACHE_TTL_MS) rmSync3(path, { force: true });
|
|
5783
5932
|
} catch {
|
|
@@ -5829,7 +5978,7 @@ import { createHash as createHash10 } from "crypto";
|
|
|
5829
5978
|
import {
|
|
5830
5979
|
existsSync as existsSync8,
|
|
5831
5980
|
mkdirSync as mkdirSync8,
|
|
5832
|
-
readFileSync as
|
|
5981
|
+
readFileSync as readFileSync20,
|
|
5833
5982
|
readdirSync as readdirSync6,
|
|
5834
5983
|
renameSync as renameSync6,
|
|
5835
5984
|
rmSync as rmSync4,
|
|
@@ -5837,7 +5986,7 @@ import {
|
|
|
5837
5986
|
utimesSync as utimesSync2,
|
|
5838
5987
|
writeFileSync as writeFileSync9
|
|
5839
5988
|
} from "fs";
|
|
5840
|
-
import { join as
|
|
5989
|
+
import { join as join26 } from "path";
|
|
5841
5990
|
var MEMORY_FETCH_CHUNK = 100;
|
|
5842
5991
|
var CACHE_TTL_MS2 = 30 * 24 * 60 * 60 * 1e3;
|
|
5843
5992
|
var SWEEP_INTERVAL_MS2 = 24 * 60 * 60 * 1e3;
|
|
@@ -5846,12 +5995,12 @@ function memoryHash(content) {
|
|
|
5846
5995
|
return createHash10("sha256").update(content, "utf8").digest("hex");
|
|
5847
5996
|
}
|
|
5848
5997
|
function cachePath2(cacheDir, hash) {
|
|
5849
|
-
return
|
|
5998
|
+
return join26(cacheDir, hash);
|
|
5850
5999
|
}
|
|
5851
6000
|
function readCachedMemory(cacheDir, hash) {
|
|
5852
6001
|
const path = cachePath2(cacheDir, hash);
|
|
5853
6002
|
try {
|
|
5854
|
-
const content =
|
|
6003
|
+
const content = readFileSync20(path, "utf-8");
|
|
5855
6004
|
try {
|
|
5856
6005
|
const now = /* @__PURE__ */ new Date();
|
|
5857
6006
|
utimesSync2(path, now, now);
|
|
@@ -5880,7 +6029,7 @@ function sweepMemoryCache(cacheDir, now = Date.now()) {
|
|
|
5880
6029
|
try {
|
|
5881
6030
|
if (!existsSync8(cacheDir)) return;
|
|
5882
6031
|
for (const name of readdirSync6(cacheDir)) {
|
|
5883
|
-
const path =
|
|
6032
|
+
const path = join26(cacheDir, name);
|
|
5884
6033
|
try {
|
|
5885
6034
|
if (now - statSync7(path).mtimeMs > CACHE_TTL_MS2) rmSync4(path, { force: true });
|
|
5886
6035
|
} catch {
|
|
@@ -5938,7 +6087,7 @@ import { createHash as createHash11 } from "crypto";
|
|
|
5938
6087
|
import {
|
|
5939
6088
|
existsSync as existsSync9,
|
|
5940
6089
|
mkdirSync as mkdirSync9,
|
|
5941
|
-
readFileSync as
|
|
6090
|
+
readFileSync as readFileSync21,
|
|
5942
6091
|
readdirSync as readdirSync7,
|
|
5943
6092
|
renameSync as renameSync7,
|
|
5944
6093
|
rmSync as rmSync5,
|
|
@@ -5946,7 +6095,7 @@ import {
|
|
|
5946
6095
|
utimesSync as utimesSync3,
|
|
5947
6096
|
writeFileSync as writeFileSync10
|
|
5948
6097
|
} from "fs";
|
|
5949
|
-
import { join as
|
|
6098
|
+
import { join as join27 } from "path";
|
|
5950
6099
|
var SKILL_FETCH_CHUNK = 100;
|
|
5951
6100
|
var CACHE_TTL_MS3 = 30 * 24 * 60 * 60 * 1e3;
|
|
5952
6101
|
var SWEEP_INTERVAL_MS3 = 24 * 60 * 60 * 1e3;
|
|
@@ -5955,12 +6104,12 @@ function skillHash(content) {
|
|
|
5955
6104
|
return createHash11("sha256").update(content, "utf8").digest("hex");
|
|
5956
6105
|
}
|
|
5957
6106
|
function cachePath3(cacheDir, hash) {
|
|
5958
|
-
return
|
|
6107
|
+
return join27(cacheDir, hash);
|
|
5959
6108
|
}
|
|
5960
6109
|
function readCachedSkill(cacheDir, hash) {
|
|
5961
6110
|
const path = cachePath3(cacheDir, hash);
|
|
5962
6111
|
try {
|
|
5963
|
-
const content =
|
|
6112
|
+
const content = readFileSync21(path, "utf-8");
|
|
5964
6113
|
try {
|
|
5965
6114
|
const now = /* @__PURE__ */ new Date();
|
|
5966
6115
|
utimesSync3(path, now, now);
|
|
@@ -5989,7 +6138,7 @@ function sweepSkillCache(cacheDir, now = Date.now()) {
|
|
|
5989
6138
|
try {
|
|
5990
6139
|
if (!existsSync9(cacheDir)) return;
|
|
5991
6140
|
for (const name of readdirSync7(cacheDir)) {
|
|
5992
|
-
const path =
|
|
6141
|
+
const path = join27(cacheDir, name);
|
|
5993
6142
|
try {
|
|
5994
6143
|
if (now - statSync8(path).mtimeMs > CACHE_TTL_MS3) rmSync5(path, { force: true });
|
|
5995
6144
|
} catch {
|
|
@@ -6276,18 +6425,18 @@ function resolveConditionalResponse(wire, hasCachedBody) {
|
|
|
6276
6425
|
}
|
|
6277
6426
|
|
|
6278
6427
|
// src/lib/channel-hash-cache.ts
|
|
6279
|
-
import { existsSync as existsSync10, readFileSync as
|
|
6280
|
-
import { join as
|
|
6428
|
+
import { existsSync as existsSync10, readFileSync as readFileSync22, writeFileSync as writeFileSync11 } from "fs";
|
|
6429
|
+
import { join as join28 } from "path";
|
|
6281
6430
|
var CACHE_FILENAME = "channel-hash-cache.json";
|
|
6282
6431
|
function getChannelHashCacheFile(configDir) {
|
|
6283
|
-
return
|
|
6432
|
+
return join28(configDir, CACHE_FILENAME);
|
|
6284
6433
|
}
|
|
6285
6434
|
function loadChannelHashCache(target, configDir) {
|
|
6286
6435
|
const path = getChannelHashCacheFile(configDir);
|
|
6287
6436
|
if (!existsSync10(path)) return;
|
|
6288
6437
|
let parsed;
|
|
6289
6438
|
try {
|
|
6290
|
-
parsed = JSON.parse(
|
|
6439
|
+
parsed = JSON.parse(readFileSync22(path, "utf-8"));
|
|
6291
6440
|
} catch {
|
|
6292
6441
|
return;
|
|
6293
6442
|
}
|
|
@@ -6307,8 +6456,8 @@ function saveChannelHashCache(source, configDir) {
|
|
|
6307
6456
|
}
|
|
6308
6457
|
|
|
6309
6458
|
// src/lib/sender-policy-baseline.ts
|
|
6310
|
-
import { existsSync as existsSync11, readFileSync as
|
|
6311
|
-
import { join as
|
|
6459
|
+
import { existsSync as existsSync11, readFileSync as readFileSync23 } from "fs";
|
|
6460
|
+
import { join as join29 } from "path";
|
|
6312
6461
|
var BASELINE_FILENAME = "sender-policy-baseline.json";
|
|
6313
6462
|
var SENDER_POLICY_BASELINE_VERSION = 1;
|
|
6314
6463
|
var BASELINE_CONCERNS = [
|
|
@@ -6346,14 +6495,14 @@ function createDeliveryBaselineMaps() {
|
|
|
6346
6495
|
};
|
|
6347
6496
|
}
|
|
6348
6497
|
function getSenderPolicyBaselineFile(configDir) {
|
|
6349
|
-
return
|
|
6498
|
+
return join29(configDir, BASELINE_FILENAME);
|
|
6350
6499
|
}
|
|
6351
6500
|
function loadSenderPolicyBaseline(target, configDir, log2) {
|
|
6352
6501
|
const path = getSenderPolicyBaselineFile(configDir);
|
|
6353
6502
|
if (!existsSync11(path)) return;
|
|
6354
6503
|
let parsed;
|
|
6355
6504
|
try {
|
|
6356
|
-
parsed = JSON.parse(
|
|
6505
|
+
parsed = JSON.parse(readFileSync23(path, "utf-8"));
|
|
6357
6506
|
} catch (err) {
|
|
6358
6507
|
log2?.(
|
|
6359
6508
|
`[sender-policy] discarding corrupt ${BASELINE_FILENAME} (${err.message}) - restrictive-policy agents will take one fail-closed restart`
|
|
@@ -6402,8 +6551,8 @@ function saveSenderPolicyBaseline(source, configDir, log2) {
|
|
|
6402
6551
|
}
|
|
6403
6552
|
|
|
6404
6553
|
// src/lib/stuck-streak-store.ts
|
|
6405
|
-
import { existsSync as existsSync12, readFileSync as
|
|
6406
|
-
import { join as
|
|
6554
|
+
import { existsSync as existsSync12, readFileSync as readFileSync24 } from "fs";
|
|
6555
|
+
import { join as join30 } from "path";
|
|
6407
6556
|
var STORE_FILENAME = "stuck-streaks.json";
|
|
6408
6557
|
var STUCK_STREAK_STORE_VERSION = 1;
|
|
6409
6558
|
var STUCK_STREAK_CONCERNS = ["channelSync", "realtimeRebind"];
|
|
@@ -6411,7 +6560,7 @@ function createStuckStreakMaps() {
|
|
|
6411
6560
|
return { channelSync: /* @__PURE__ */ new Map(), realtimeRebind: /* @__PURE__ */ new Map() };
|
|
6412
6561
|
}
|
|
6413
6562
|
function getStuckStreakStoreFile(configDir) {
|
|
6414
|
-
return
|
|
6563
|
+
return join30(configDir, STORE_FILENAME);
|
|
6415
6564
|
}
|
|
6416
6565
|
function isValidPersistedStreak(value) {
|
|
6417
6566
|
if (!value || typeof value !== "object" || Array.isArray(value)) return false;
|
|
@@ -6453,7 +6602,7 @@ function loadStuckStreaks(target, configDir, log2) {
|
|
|
6453
6602
|
if (!existsSync12(path)) return;
|
|
6454
6603
|
let parsed;
|
|
6455
6604
|
try {
|
|
6456
|
-
parsed = JSON.parse(
|
|
6605
|
+
parsed = JSON.parse(readFileSync24(path, "utf-8"));
|
|
6457
6606
|
} catch (err) {
|
|
6458
6607
|
log2?.(
|
|
6459
6608
|
`[stuck-streaks] discarding corrupt ${STORE_FILENAME} (${err.message}) \u2014 stuck-streak ages restart from zero and one spurious "recovered" close may follow`
|
|
@@ -6496,11 +6645,11 @@ function pruneStuckStreaksToAgents(maps, activeAgentIds) {
|
|
|
6496
6645
|
}
|
|
6497
6646
|
|
|
6498
6647
|
// src/lib/claude-device-state.ts
|
|
6499
|
-
import { readFileSync as
|
|
6648
|
+
import { readFileSync as readFileSync25, statSync as statSync9 } from "fs";
|
|
6500
6649
|
import { homedir as homedir13 } from "os";
|
|
6501
|
-
import { join as
|
|
6650
|
+
import { join as join31 } from "path";
|
|
6502
6651
|
function claudeDeviceStatePath(env = process.env) {
|
|
6503
|
-
return
|
|
6652
|
+
return join31(env.HOME?.trim() || homedir13(), ".claude.json");
|
|
6504
6653
|
}
|
|
6505
6654
|
function probeClaudeDeviceStatePresence(path = claudeDeviceStatePath()) {
|
|
6506
6655
|
try {
|
|
@@ -6523,7 +6672,7 @@ function checkClaudeDeviceState(path = claudeDeviceStatePath()) {
|
|
|
6523
6672
|
}
|
|
6524
6673
|
let raw;
|
|
6525
6674
|
try {
|
|
6526
|
-
raw =
|
|
6675
|
+
raw = readFileSync25(path, "utf-8");
|
|
6527
6676
|
} catch {
|
|
6528
6677
|
return { usable: false, reason: "unreadable" };
|
|
6529
6678
|
}
|
|
@@ -7201,7 +7350,7 @@ function planGlobalSkillSync(globalSkills, prevIds, hashOf, knownHash, options)
|
|
|
7201
7350
|
}
|
|
7202
7351
|
|
|
7203
7352
|
// src/lib/manager/integration-skill-cache.ts
|
|
7204
|
-
import { join as
|
|
7353
|
+
import { join as join32 } from "path";
|
|
7205
7354
|
function integrationSkillHashKey(agentId, skillId) {
|
|
7206
7355
|
return `plugin-skill:${agentId}:${skillId}`;
|
|
7207
7356
|
}
|
|
@@ -7217,21 +7366,21 @@ function forgetIntegrationSkill(cache2, agentId, skillId) {
|
|
|
7217
7366
|
function removeIntegrationSkillFolder(opts) {
|
|
7218
7367
|
forgetIntegrationSkill(opts.cache, opts.agentId, opts.entry);
|
|
7219
7368
|
for (const dir of opts.dirs) {
|
|
7220
|
-
opts.removeDir(
|
|
7369
|
+
opts.removeDir(join32(dir, opts.entry));
|
|
7221
7370
|
}
|
|
7222
7371
|
}
|
|
7223
7372
|
|
|
7224
7373
|
// src/lib/manager/managed-skill-manifest.ts
|
|
7225
|
-
import { existsSync as existsSync13, mkdirSync as mkdirSync10, readFileSync as
|
|
7226
|
-
import { dirname as dirname8, join as
|
|
7374
|
+
import { existsSync as existsSync13, mkdirSync as mkdirSync10, readFileSync as readFileSync26, writeFileSync as writeFileSync12 } from "fs";
|
|
7375
|
+
import { dirname as dirname8, join as join33 } from "path";
|
|
7227
7376
|
var MANIFEST_VERSION = 1;
|
|
7228
7377
|
function managedSkillManifestPath(agentRootDir) {
|
|
7229
|
-
return
|
|
7378
|
+
return join33(agentRootDir, "managed-skills.json");
|
|
7230
7379
|
}
|
|
7231
7380
|
function readManagedSkillManifest(path) {
|
|
7232
7381
|
try {
|
|
7233
7382
|
if (!existsSync13(path)) return /* @__PURE__ */ new Set();
|
|
7234
|
-
const parsed = JSON.parse(
|
|
7383
|
+
const parsed = JSON.parse(readFileSync26(path, "utf-8"));
|
|
7235
7384
|
const ids = Array.isArray(parsed?.globalSkillIds) ? parsed.globalSkillIds : [];
|
|
7236
7385
|
return new Set(ids.filter((id) => typeof id === "string" && id.length > 0));
|
|
7237
7386
|
} catch {
|
|
@@ -7361,7 +7510,7 @@ function resolveModelChain(refreshData) {
|
|
|
7361
7510
|
|
|
7362
7511
|
// src/lib/manager/claude-auth.ts
|
|
7363
7512
|
import { existsSync as existsSync14, rmSync as rmSync6 } from "fs";
|
|
7364
|
-
import { join as
|
|
7513
|
+
import { join as join34 } from "path";
|
|
7365
7514
|
import { homedir as homedir14 } from "os";
|
|
7366
7515
|
async function applyClaudeAuthToEnv(childEnv, label) {
|
|
7367
7516
|
const apiKey = getApiKey();
|
|
@@ -7374,9 +7523,9 @@ async function applyClaudeAuthToEnv(childEnv, label) {
|
|
|
7374
7523
|
throw new Error("claude_auth_mode=api_key but /host/exchange returned no decrypted key");
|
|
7375
7524
|
}
|
|
7376
7525
|
childEnv.ANTHROPIC_API_KEY = exchange.anthropicApiKey;
|
|
7377
|
-
const claudeDir =
|
|
7526
|
+
const claudeDir = join34(homedir14(), ".claude");
|
|
7378
7527
|
for (const filename of [".credentials.json", "credentials.json"]) {
|
|
7379
|
-
const p =
|
|
7528
|
+
const p = join34(claudeDir, filename);
|
|
7380
7529
|
if (existsSync14(p)) {
|
|
7381
7530
|
try {
|
|
7382
7531
|
rmSync6(p, { force: true });
|
|
@@ -7732,19 +7881,19 @@ function formatBoardForPrompt(items, template) {
|
|
|
7732
7881
|
}
|
|
7733
7882
|
|
|
7734
7883
|
// src/lib/manager/kanban/nudge-state-cache.ts
|
|
7735
|
-
import { existsSync as existsSync15, readFileSync as
|
|
7736
|
-
import { join as
|
|
7884
|
+
import { existsSync as existsSync15, readFileSync as readFileSync27, writeFileSync as writeFileSync13 } from "fs";
|
|
7885
|
+
import { join as join35 } from "path";
|
|
7737
7886
|
var CACHE_FILENAME2 = "kanban-nudge-state.json";
|
|
7738
7887
|
var KANBAN_NUDGE_STATE_VERSION = 1;
|
|
7739
7888
|
function getKanbanNudgeStateFile(configDir) {
|
|
7740
|
-
return
|
|
7889
|
+
return join35(configDir, CACHE_FILENAME2);
|
|
7741
7890
|
}
|
|
7742
7891
|
function loadKanbanNudgeState(target, configDir) {
|
|
7743
7892
|
const path = getKanbanNudgeStateFile(configDir);
|
|
7744
7893
|
if (!existsSync15(path)) return;
|
|
7745
7894
|
let parsed;
|
|
7746
7895
|
try {
|
|
7747
|
-
parsed = JSON.parse(
|
|
7896
|
+
parsed = JSON.parse(readFileSync27(path, "utf-8"));
|
|
7748
7897
|
} catch {
|
|
7749
7898
|
return;
|
|
7750
7899
|
}
|
|
@@ -8362,9 +8511,9 @@ function closeSessionRunForCode(codeName, outcome, reason) {
|
|
|
8362
8511
|
|
|
8363
8512
|
// src/lib/manager/scheduler/kanban-route.ts
|
|
8364
8513
|
import { createHash as createHash15 } from "crypto";
|
|
8365
|
-
import { writeFileSync as writeFileSync14, renameSync as renameSync8, mkdirSync as mkdirSync11, readFileSync as
|
|
8514
|
+
import { writeFileSync as writeFileSync14, renameSync as renameSync8, mkdirSync as mkdirSync11, readFileSync as readFileSync28, unlinkSync as unlinkSync3 } from "fs";
|
|
8366
8515
|
import { homedir as homedir15 } from "os";
|
|
8367
|
-
import { join as
|
|
8516
|
+
import { join as join36, dirname as dirname9 } from "path";
|
|
8368
8517
|
|
|
8369
8518
|
// src/lib/manager/scheduler/notify.ts
|
|
8370
8519
|
import { createHash as createHash14 } from "crypto";
|
|
@@ -8723,7 +8872,7 @@ function resolveScheduledSlackTarget(task) {
|
|
|
8723
8872
|
}
|
|
8724
8873
|
function stampScheduledTurnMarker(codeName, taskId, target) {
|
|
8725
8874
|
try {
|
|
8726
|
-
const file =
|
|
8875
|
+
const file = join36(homedir15(), ".augmented", codeName, SCHEDULED_TURN_MARKER_FILENAME);
|
|
8727
8876
|
const marker = { ts: Date.now(), task_id: taskId, ...target ? { target } : {} };
|
|
8728
8877
|
const tmp = `${file}.tmp`;
|
|
8729
8878
|
writeFileSync14(tmp, JSON.stringify(marker), "utf8");
|
|
@@ -8733,9 +8882,9 @@ function stampScheduledTurnMarker(codeName, taskId, target) {
|
|
|
8733
8882
|
}
|
|
8734
8883
|
}
|
|
8735
8884
|
function clearScheduledTurnMarkerForTask(codeName, taskId) {
|
|
8736
|
-
const file =
|
|
8885
|
+
const file = join36(homedir15(), ".augmented", codeName, SCHEDULED_TURN_MARKER_FILENAME);
|
|
8737
8886
|
try {
|
|
8738
|
-
const raw = JSON.parse(
|
|
8887
|
+
const raw = JSON.parse(readFileSync28(file, "utf8"));
|
|
8739
8888
|
if (typeof raw?.task_id !== "string" || raw.task_id !== taskId) return;
|
|
8740
8889
|
unlinkSync3(file);
|
|
8741
8890
|
log(`[scheduled-kanban] scheduled-turn marker cleared for '${codeName}' (task ${taskId} complete)`);
|
|
@@ -8951,11 +9100,11 @@ async function processClaudeTaskResult(codeName, agentId, templateId, rawOutput,
|
|
|
8951
9100
|
// src/lib/manager/scheduler/execution.ts
|
|
8952
9101
|
import { createHash as createHash16 } from "crypto";
|
|
8953
9102
|
import { homedir as homedir16 } from "os";
|
|
8954
|
-
import { join as
|
|
9103
|
+
import { join as join38 } from "path";
|
|
8955
9104
|
|
|
8956
9105
|
// src/lib/agent-serving-probe.ts
|
|
8957
|
-
import { readFileSync as
|
|
8958
|
-
import { join as
|
|
9106
|
+
import { readFileSync as readFileSync29, readdirSync as readdirSync8, statSync as statSync10 } from "fs";
|
|
9107
|
+
import { join as join37 } from "path";
|
|
8959
9108
|
var RATE_LIMIT_WINDOW_MS = 6 * 60 * 60 * 1e3;
|
|
8960
9109
|
function probeRateLimit(args) {
|
|
8961
9110
|
const now = args.now ?? /* @__PURE__ */ new Date();
|
|
@@ -8971,7 +9120,7 @@ function probeRateLimit(args) {
|
|
|
8971
9120
|
let newest = UNKNOWN_RATE_LIMIT;
|
|
8972
9121
|
for (const name of entries) {
|
|
8973
9122
|
if (!name.endsWith(".jsonl")) continue;
|
|
8974
|
-
const path =
|
|
9123
|
+
const path = join37(dir, name);
|
|
8975
9124
|
try {
|
|
8976
9125
|
const st = statSync10(path);
|
|
8977
9126
|
if (!st.isFile() || st.mtimeMs < startMs) continue;
|
|
@@ -8980,7 +9129,7 @@ function probeRateLimit(args) {
|
|
|
8980
9129
|
}
|
|
8981
9130
|
let content;
|
|
8982
9131
|
try {
|
|
8983
|
-
content =
|
|
9132
|
+
content = readFileSync29(path, "utf-8");
|
|
8984
9133
|
} catch {
|
|
8985
9134
|
continue;
|
|
8986
9135
|
}
|
|
@@ -9042,7 +9191,7 @@ function shouldLogUsageCapDeferral(site, codeName, limitedUntil) {
|
|
|
9042
9191
|
|
|
9043
9192
|
// src/lib/manager/scheduler/execution.ts
|
|
9044
9193
|
function claudePidFilePath() {
|
|
9045
|
-
return
|
|
9194
|
+
return join38(homedir16(), ".augmented", "manager-claude-pids.json");
|
|
9046
9195
|
}
|
|
9047
9196
|
var inFlightClaudePids = /* @__PURE__ */ new Map();
|
|
9048
9197
|
function registerClaudeSpawn(record) {
|
|
@@ -9113,7 +9262,7 @@ async function syncAndCheckClaudeScheduler(agent, tasks, boardItems, refreshData
|
|
|
9113
9262
|
|
|
9114
9263
|
// src/lib/occupancy-gate.ts
|
|
9115
9264
|
import { closeSync as closeSync2, openSync as openSync2, readdirSync as readdirSync9, readSync as readSync2, statSync as statSync11 } from "fs";
|
|
9116
|
-
import { join as
|
|
9265
|
+
import { join as join39 } from "path";
|
|
9117
9266
|
function rostersMeasuredZero(mode, attested, runtimeRunning) {
|
|
9118
9267
|
return mode === "enforce" && attested && runtimeRunning;
|
|
9119
9268
|
}
|
|
@@ -9204,10 +9353,10 @@ function candidateTranscriptPaths(dir) {
|
|
|
9204
9353
|
let complete = true;
|
|
9205
9354
|
for (const name of top) {
|
|
9206
9355
|
if (name.endsWith(".jsonl")) {
|
|
9207
|
-
paths.push(
|
|
9356
|
+
paths.push(join39(dir, name));
|
|
9208
9357
|
continue;
|
|
9209
9358
|
}
|
|
9210
|
-
const subDir =
|
|
9359
|
+
const subDir = join39(dir, name, "subagents");
|
|
9211
9360
|
let subs;
|
|
9212
9361
|
try {
|
|
9213
9362
|
subs = readdirSync9(subDir);
|
|
@@ -9216,7 +9365,7 @@ function candidateTranscriptPaths(dir) {
|
|
|
9216
9365
|
continue;
|
|
9217
9366
|
}
|
|
9218
9367
|
for (const sub of subs) {
|
|
9219
|
-
if (sub.endsWith(".jsonl")) paths.push(
|
|
9368
|
+
if (sub.endsWith(".jsonl")) paths.push(join39(subDir, sub));
|
|
9220
9369
|
}
|
|
9221
9370
|
}
|
|
9222
9371
|
return { paths, complete };
|
|
@@ -9442,7 +9591,7 @@ function stopPaneOccupancySampler() {
|
|
|
9442
9591
|
}
|
|
9443
9592
|
|
|
9444
9593
|
// src/lib/pid-pressure-sampler.ts
|
|
9445
|
-
import { existsSync as existsSync16, readFileSync as
|
|
9594
|
+
import { existsSync as existsSync16, readFileSync as readFileSync30 } from "fs";
|
|
9446
9595
|
var SAMPLE_INTERVAL_MS2 = 3e4;
|
|
9447
9596
|
function warnFraction() {
|
|
9448
9597
|
const raw = Number(process.env.AGT_PID_PRESSURE_WARN_FRACTION);
|
|
@@ -9470,7 +9619,7 @@ function parseMemoryEvents(text) {
|
|
|
9470
9619
|
}
|
|
9471
9620
|
function readTextReal(path) {
|
|
9472
9621
|
try {
|
|
9473
|
-
return
|
|
9622
|
+
return readFileSync30(path, "utf-8");
|
|
9474
9623
|
} catch {
|
|
9475
9624
|
return null;
|
|
9476
9625
|
}
|
|
@@ -10753,9 +10902,9 @@ async function fireOpencodeScheduledTask(agent, task) {
|
|
|
10753
10902
|
|
|
10754
10903
|
// src/lib/opencode-telegram-ingest.ts
|
|
10755
10904
|
import { createHash as createHash19 } from "crypto";
|
|
10756
|
-
import { existsSync as existsSync17, mkdirSync as mkdirSync12, readFileSync as
|
|
10905
|
+
import { existsSync as existsSync17, mkdirSync as mkdirSync12, readFileSync as readFileSync31, renameSync as renameSync9, unlinkSync as unlinkSync4, writeFileSync as writeFileSync15 } from "fs";
|
|
10757
10906
|
import { randomUUID } from "crypto";
|
|
10758
|
-
import { join as
|
|
10907
|
+
import { join as join40 } from "path";
|
|
10759
10908
|
|
|
10760
10909
|
// src/lib/telegram-ingest.ts
|
|
10761
10910
|
import https2 from "https";
|
|
@@ -11312,7 +11461,7 @@ function createFileOffsetStore(codeName, log2, currentBotId) {
|
|
|
11312
11461
|
let filePath;
|
|
11313
11462
|
try {
|
|
11314
11463
|
dir = getFramework("opencode").getAgentDir(codeName);
|
|
11315
|
-
filePath =
|
|
11464
|
+
filePath = join40(dir, "telegram-getupdates-offset-opencode.json");
|
|
11316
11465
|
} catch {
|
|
11317
11466
|
dir = null;
|
|
11318
11467
|
filePath = null;
|
|
@@ -11321,7 +11470,7 @@ function createFileOffsetStore(codeName, log2, currentBotId) {
|
|
|
11321
11470
|
load() {
|
|
11322
11471
|
if (!filePath) return 0;
|
|
11323
11472
|
try {
|
|
11324
|
-
const parsed = JSON.parse(
|
|
11473
|
+
const parsed = JSON.parse(readFileSync31(filePath, "utf-8"));
|
|
11325
11474
|
if (currentBotId != null && typeof parsed?.bot_id === "number" && parsed.bot_id !== currentBotId) {
|
|
11326
11475
|
log2(`[telegram-ingest:${codeName}] offset cursor belongs to a different bot; ignoring (bot swap)`);
|
|
11327
11476
|
return 0;
|
|
@@ -11595,15 +11744,15 @@ function partitionActionableByPoison(actionable, states, config2) {
|
|
|
11595
11744
|
}
|
|
11596
11745
|
|
|
11597
11746
|
// src/lib/restart-flags.ts
|
|
11598
|
-
import { existsSync as existsSync18, mkdirSync as mkdirSync13, readdirSync as readdirSync10, readFileSync as
|
|
11747
|
+
import { existsSync as existsSync18, mkdirSync as mkdirSync13, readdirSync as readdirSync10, readFileSync as readFileSync32, renameSync as renameSync10, rmSync as rmSync7, writeFileSync as writeFileSync16 } from "fs";
|
|
11599
11748
|
import { homedir as homedir17 } from "os";
|
|
11600
|
-
import { join as
|
|
11749
|
+
import { join as join41 } from "path";
|
|
11601
11750
|
import { randomUUID as randomUUID2 } from "crypto";
|
|
11602
11751
|
function restartFlagsDir() {
|
|
11603
|
-
return
|
|
11752
|
+
return join41(homedir17(), ".augmented", "restart-flags");
|
|
11604
11753
|
}
|
|
11605
11754
|
function flagPath(codeName) {
|
|
11606
|
-
return
|
|
11755
|
+
return join41(restartFlagsDir(), `${codeName}.flag`);
|
|
11607
11756
|
}
|
|
11608
11757
|
function readRestartFlags() {
|
|
11609
11758
|
const dir = restartFlagsDir();
|
|
@@ -11612,7 +11761,7 @@ function readRestartFlags() {
|
|
|
11612
11761
|
for (const entry of readdirSync10(dir)) {
|
|
11613
11762
|
if (!entry.endsWith(".flag")) continue;
|
|
11614
11763
|
try {
|
|
11615
|
-
const raw =
|
|
11764
|
+
const raw = readFileSync32(join41(dir, entry), "utf8");
|
|
11616
11765
|
const parsed = JSON.parse(raw);
|
|
11617
11766
|
if (typeof parsed.codeName !== "string" || parsed.codeName.length === 0) {
|
|
11618
11767
|
parsed.codeName = entry.replace(/\.flag$/, "");
|
|
@@ -11730,8 +11879,8 @@ async function sendError(flag, opts, text) {
|
|
|
11730
11879
|
}
|
|
11731
11880
|
|
|
11732
11881
|
// src/lib/restart-context.ts
|
|
11733
|
-
import { readdirSync as readdirSync11, readFileSync as
|
|
11734
|
-
import { dirname as dirname10, join as
|
|
11882
|
+
import { readdirSync as readdirSync11, readFileSync as readFileSync33, writeFileSync as writeFileSync17, mkdirSync as mkdirSync14, unlinkSync as unlinkSync5 } from "fs";
|
|
11883
|
+
import { dirname as dirname10, join as join42 } from "path";
|
|
11735
11884
|
var SLACK_PENDING_INBOUND_DIRNAME = "slack-pending-inbound";
|
|
11736
11885
|
var SLACK_RESTART_CONTEXT_DIRNAME = "slack-restart-context";
|
|
11737
11886
|
var MAX_TOPIC_CHARS = 140;
|
|
@@ -11743,10 +11892,10 @@ function augmentedAgentDir(codeName) {
|
|
|
11743
11892
|
return dirname10(getProjectDir(codeName));
|
|
11744
11893
|
}
|
|
11745
11894
|
function slackPendingInboundDir(codeName) {
|
|
11746
|
-
return
|
|
11895
|
+
return join42(augmentedAgentDir(codeName), SLACK_PENDING_INBOUND_DIRNAME);
|
|
11747
11896
|
}
|
|
11748
11897
|
function slackRestartContextDir(codeName) {
|
|
11749
|
-
return
|
|
11898
|
+
return join42(augmentedAgentDir(codeName), SLACK_RESTART_CONTEXT_DIRNAME);
|
|
11750
11899
|
}
|
|
11751
11900
|
function sanitizeTopic(raw) {
|
|
11752
11901
|
const cleaned = raw.replace(/\s+/g, " ").trim().replace(/[<>]/g, " ").replace(/\s+/g, " ").trim();
|
|
@@ -11788,7 +11937,7 @@ function safeReaddir(dir) {
|
|
|
11788
11937
|
}
|
|
11789
11938
|
function readStrandedMarker(path) {
|
|
11790
11939
|
try {
|
|
11791
|
-
const parsed = JSON.parse(
|
|
11940
|
+
const parsed = JSON.parse(readFileSync33(path, "utf-8"));
|
|
11792
11941
|
if (typeof parsed.channel === "string" && typeof parsed.thread_ts === "string") {
|
|
11793
11942
|
return { channel: parsed.channel, thread_ts: parsed.thread_ts };
|
|
11794
11943
|
}
|
|
@@ -11806,7 +11955,7 @@ function pruneHintsExcept(codeName, freshFilenames) {
|
|
|
11806
11955
|
if (!filename.endsWith(".json")) continue;
|
|
11807
11956
|
if (freshFilenames.has(filename)) continue;
|
|
11808
11957
|
try {
|
|
11809
|
-
unlinkSync5(
|
|
11958
|
+
unlinkSync5(join42(ctxDir, filename));
|
|
11810
11959
|
} catch {
|
|
11811
11960
|
}
|
|
11812
11961
|
}
|
|
@@ -11827,7 +11976,7 @@ function refreshSlackRestartContextHints(codeNames, opts = {}) {
|
|
|
11827
11976
|
}
|
|
11828
11977
|
const markers = [];
|
|
11829
11978
|
for (const filename of markerFilenames.slice(0, cap)) {
|
|
11830
|
-
const parsed = readStrandedMarker(
|
|
11979
|
+
const parsed = readStrandedMarker(join42(markerDir, filename));
|
|
11831
11980
|
if (parsed) markers.push({ filename, channel: parsed.channel, thread_ts: parsed.thread_ts });
|
|
11832
11981
|
}
|
|
11833
11982
|
if (markers.length === 0) {
|
|
@@ -11841,7 +11990,7 @@ function refreshSlackRestartContextHints(codeNames, opts = {}) {
|
|
|
11841
11990
|
const freshFilenames = /* @__PURE__ */ new Set();
|
|
11842
11991
|
for (const { filename, hint } of hints) {
|
|
11843
11992
|
try {
|
|
11844
|
-
writeHintFile(
|
|
11993
|
+
writeHintFile(join42(ctxDir, filename), ctxDir, hint);
|
|
11845
11994
|
freshFilenames.add(filename);
|
|
11846
11995
|
} catch (err) {
|
|
11847
11996
|
log2(`[restart-context] ${codeName}: hint write failed for ${filename}: ${err.message}`);
|
|
@@ -13311,7 +13460,7 @@ var pendingDayRolloverReset = /* @__PURE__ */ new Set();
|
|
|
13311
13460
|
var dayRolloverInboundHold = /* @__PURE__ */ new Map();
|
|
13312
13461
|
var INBOUND_HOLD_EPISODE_GAP_MS = 12e4;
|
|
13313
13462
|
async function channelInboundActivityAgeSecondsFor(codeName) {
|
|
13314
|
-
const { newestPendingInboundActivityMtimeMs } = await import("../responsiveness-probe-
|
|
13463
|
+
const { newestPendingInboundActivityMtimeMs } = await import("../responsiveness-probe-DXPEIUH6.js");
|
|
13315
13464
|
const newest = newestPendingInboundActivityMtimeMs(dirname11(paneLogPath(codeName)));
|
|
13316
13465
|
if (newest === null) return null;
|
|
13317
13466
|
return Math.max(0, Math.floor((Date.now() - newest) / 1e3));
|
|
@@ -13636,7 +13785,7 @@ var runningChannelSecretHashes = /* @__PURE__ */ new Map();
|
|
|
13636
13785
|
var sessionLaunchManagedStructure = /* @__PURE__ */ new Map();
|
|
13637
13786
|
function projectMcpHash(_codeName, projectDir) {
|
|
13638
13787
|
try {
|
|
13639
|
-
const raw =
|
|
13788
|
+
const raw = readFileSync34(join43(projectDir, ".mcp.json"), "utf-8");
|
|
13640
13789
|
return createHash20("sha256").update(canonicalJson(JSON.parse(raw))).digest("hex");
|
|
13641
13790
|
} catch {
|
|
13642
13791
|
return null;
|
|
@@ -13644,7 +13793,7 @@ function projectMcpHash(_codeName, projectDir) {
|
|
|
13644
13793
|
}
|
|
13645
13794
|
function projectMcpKeys(_codeName, projectDir) {
|
|
13646
13795
|
try {
|
|
13647
|
-
const raw =
|
|
13796
|
+
const raw = readFileSync34(join43(projectDir, ".mcp.json"), "utf-8");
|
|
13648
13797
|
const parsed = JSON.parse(raw);
|
|
13649
13798
|
const servers = parsed.mcpServers;
|
|
13650
13799
|
if (!servers || typeof servers !== "object") return /* @__PURE__ */ new Set();
|
|
@@ -13662,7 +13811,7 @@ function seedSessionLaunchBaselines(codeName, projectDir) {
|
|
|
13662
13811
|
else runningMcpServerKeys.delete(codeName);
|
|
13663
13812
|
let launchStructure = null;
|
|
13664
13813
|
try {
|
|
13665
|
-
const raw =
|
|
13814
|
+
const raw = readFileSync34(join43(projectDir, ".mcp.json"), "utf-8");
|
|
13666
13815
|
launchStructure = managedMcpStructureHashFromFile(
|
|
13667
13816
|
JSON.parse(raw),
|
|
13668
13817
|
isManagedMcpServerKey
|
|
@@ -13797,7 +13946,7 @@ async function runAgentSessionToolBindProbes(agent, integrations, projectDir, op
|
|
|
13797
13946
|
if (result && result.rebindCandidates.length > 0 && hostFlagStore().getBoolean("session-tool-rebind")) {
|
|
13798
13947
|
let mcpJsonForRebind = null;
|
|
13799
13948
|
try {
|
|
13800
|
-
mcpJsonForRebind = JSON.parse(
|
|
13949
|
+
mcpJsonForRebind = JSON.parse(readFileSync34(join43(projectDir, ".mcp.json"), "utf-8"));
|
|
13801
13950
|
} catch {
|
|
13802
13951
|
mcpJsonForRebind = null;
|
|
13803
13952
|
}
|
|
@@ -13945,7 +14094,7 @@ function shouldInjectChannelSecrets(agentId) {
|
|
|
13945
14094
|
function projectChannelSecretHash(projectDir) {
|
|
13946
14095
|
try {
|
|
13947
14096
|
const entries = parseEnvIntegrations(
|
|
13948
|
-
|
|
14097
|
+
readFileSync34(join43(projectDir, ".env.integrations"), "utf-8")
|
|
13949
14098
|
);
|
|
13950
14099
|
return channelSecretValueHash(entries, CHANNEL_SECRET_ENV_KEYS);
|
|
13951
14100
|
} catch {
|
|
@@ -14054,7 +14203,7 @@ var agentRestartTimezoneInputs = /* @__PURE__ */ new Map();
|
|
|
14054
14203
|
var lastVersionCheckAt = 0;
|
|
14055
14204
|
var VERSION_CHECK_INTERVAL_MS = 5 * 60 * 1e3;
|
|
14056
14205
|
var lastResponsivenessProbeAt = 0;
|
|
14057
|
-
var agtCliVersion = true ? "0.28.
|
|
14206
|
+
var agtCliVersion = true ? "0.28.1006" : "dev";
|
|
14058
14207
|
function resolveBrewPath(execFileSync2) {
|
|
14059
14208
|
try {
|
|
14060
14209
|
const out = execFileSync2("which", ["brew"], { timeout: 5e3 }).toString().trim();
|
|
@@ -14381,7 +14530,7 @@ function runAsync(cmd, args, opts) {
|
|
|
14381
14530
|
});
|
|
14382
14531
|
}
|
|
14383
14532
|
function claudeManagedSettingsPath() {
|
|
14384
|
-
return
|
|
14533
|
+
return join43(CLAUDE_MANAGED_SETTINGS_DIR, "managed-settings.json");
|
|
14385
14534
|
}
|
|
14386
14535
|
var MANAGED_SETTINGS_KEYS = ["channelsEnabled", "enableAllProjectMcpServers"];
|
|
14387
14536
|
var MANAGED_SETTINGS_ENV = { DISABLE_AUTOUPDATER: "1" };
|
|
@@ -14389,7 +14538,7 @@ function ensureClaudeManagedSettings(path = claudeManagedSettingsPath()) {
|
|
|
14389
14538
|
try {
|
|
14390
14539
|
let settings = {};
|
|
14391
14540
|
if (existsSync19(path)) {
|
|
14392
|
-
const raw =
|
|
14541
|
+
const raw = readFileSync34(path, "utf-8").trim();
|
|
14393
14542
|
if (raw) {
|
|
14394
14543
|
let parsed;
|
|
14395
14544
|
try {
|
|
@@ -14456,7 +14605,7 @@ async function ensureOpencodeBinary() {
|
|
|
14456
14605
|
try {
|
|
14457
14606
|
const prefix = execFileSync2("npm", ["prefix", "-g"], { encoding: "utf-8", timeout: 1e4 }).trim();
|
|
14458
14607
|
if (prefix) {
|
|
14459
|
-
const npmBin =
|
|
14608
|
+
const npmBin = join43(prefix, "bin");
|
|
14460
14609
|
const current = (process.env.PATH ?? "").split(pathDelimiter);
|
|
14461
14610
|
if (!current.includes(npmBin)) {
|
|
14462
14611
|
process.env.PATH = [npmBin, ...current.filter(Boolean)].join(pathDelimiter);
|
|
@@ -14596,7 +14745,7 @@ async function maybeUpgradeClaudeCode() {
|
|
|
14596
14745
|
}
|
|
14597
14746
|
var UPDATE_CHECK_INTERVAL_MS = 5 * 60 * 1e3;
|
|
14598
14747
|
function selfUpdateAppliedMarkerPath() {
|
|
14599
|
-
return
|
|
14748
|
+
return join43(homedir18(), ".augmented", ".last-self-update-applied");
|
|
14600
14749
|
}
|
|
14601
14750
|
var selfUpdateUpToDateLogged = false;
|
|
14602
14751
|
var selfUpdatePinnedLogged = false;
|
|
@@ -14647,7 +14796,7 @@ async function checkAndUpdateCli(opts) {
|
|
|
14647
14796
|
const isNpmGlobal = !isBrewFormula && resolvedPath.includes("node_modules");
|
|
14648
14797
|
if (!isBrewFormula && !isNpmGlobal) return "noop";
|
|
14649
14798
|
const { readFileSync: readF, writeFileSync: writeF } = await import("fs");
|
|
14650
|
-
const markerPath =
|
|
14799
|
+
const markerPath = join43(homedir18(), ".augmented", ".last-update-check");
|
|
14651
14800
|
if (!force) {
|
|
14652
14801
|
try {
|
|
14653
14802
|
const lastCheck = parseInt(readF(markerPath, "utf-8").trim(), 10);
|
|
@@ -15145,12 +15294,12 @@ async function checkClaudeAuth() {
|
|
|
15145
15294
|
var evalEmptyMcpConfigPath = null;
|
|
15146
15295
|
function ensureEvalEmptyMcpConfig() {
|
|
15147
15296
|
if (evalEmptyMcpConfigPath && existsSync19(evalEmptyMcpConfigPath)) return evalEmptyMcpConfigPath;
|
|
15148
|
-
const dir =
|
|
15297
|
+
const dir = join43(homedir18(), ".augmented");
|
|
15149
15298
|
try {
|
|
15150
15299
|
mkdirSync15(dir, { recursive: true });
|
|
15151
15300
|
} catch {
|
|
15152
15301
|
}
|
|
15153
|
-
const p =
|
|
15302
|
+
const p = join43(dir, ".eval-empty-mcp.json");
|
|
15154
15303
|
writeFileSync18(p, JSON.stringify({ mcpServers: {} }));
|
|
15155
15304
|
evalEmptyMcpConfigPath = p;
|
|
15156
15305
|
return p;
|
|
@@ -15245,10 +15394,10 @@ function resolveConversationEvalBackend() {
|
|
|
15245
15394
|
return conversationEvalBackend;
|
|
15246
15395
|
}
|
|
15247
15396
|
function getStateFile() {
|
|
15248
|
-
return
|
|
15397
|
+
return join43(config?.configDir ?? join43(process.env["HOME"] ?? "/tmp", ".augmented"), "manager-state.json");
|
|
15249
15398
|
}
|
|
15250
15399
|
function channelHashCacheDir() {
|
|
15251
|
-
return config?.configDir ??
|
|
15400
|
+
return config?.configDir ?? join43(process.env["HOME"] ?? "/tmp", ".augmented");
|
|
15252
15401
|
}
|
|
15253
15402
|
function loadChannelHashCache2() {
|
|
15254
15403
|
loadChannelHashCache(agentState.knownChannelConfigHashes, channelHashCacheDir());
|
|
@@ -15461,11 +15610,29 @@ function removeDeliveryBaselineEntries(agentId) {
|
|
|
15461
15610
|
var _channelQuarantineStore = null;
|
|
15462
15611
|
function channelQuarantineStore() {
|
|
15463
15612
|
if (!_channelQuarantineStore) {
|
|
15464
|
-
const dir = config?.configDir ??
|
|
15613
|
+
const dir = config?.configDir ?? join43(process.env["HOME"] ?? "/tmp", ".augmented");
|
|
15465
15614
|
_channelQuarantineStore = new ChannelQuarantineStore(defaultQuarantinePath(dir));
|
|
15466
15615
|
}
|
|
15467
15616
|
return _channelQuarantineStore;
|
|
15468
15617
|
}
|
|
15618
|
+
var _channelResumeHistoryStore = null;
|
|
15619
|
+
function channelResumeHistoryStore() {
|
|
15620
|
+
if (!_channelResumeHistoryStore) {
|
|
15621
|
+
const dir = config?.configDir ?? join43(process.env["HOME"] ?? "/tmp", ".augmented");
|
|
15622
|
+
_channelResumeHistoryStore = new ChannelResumeHistoryStore(defaultResumeHistoryPath(dir));
|
|
15623
|
+
}
|
|
15624
|
+
return _channelResumeHistoryStore;
|
|
15625
|
+
}
|
|
15626
|
+
var autoResumeDowngradeLogged = /* @__PURE__ */ new Set();
|
|
15627
|
+
function shouldLogAutoResumeModeDowngrade(autoResume, quarantine) {
|
|
15628
|
+
const key = `${autoResume}->${quarantine}`;
|
|
15629
|
+
if (autoResumeDowngradeLogged.has(key)) return false;
|
|
15630
|
+
autoResumeDowngradeLogged.add(key);
|
|
15631
|
+
return true;
|
|
15632
|
+
}
|
|
15633
|
+
function channelQuarantineAutoResumeMode() {
|
|
15634
|
+
return hostFlagStore().getString("channel-quarantine-auto-resume");
|
|
15635
|
+
}
|
|
15469
15636
|
function quarantineEntriesFor(codeName) {
|
|
15470
15637
|
return channelQuarantineStore().getQuarantineEntries(codeName);
|
|
15471
15638
|
}
|
|
@@ -15477,12 +15644,12 @@ function claudeMdSizeFor(codeName) {
|
|
|
15477
15644
|
}
|
|
15478
15645
|
function forwardedToolsFor(codeName) {
|
|
15479
15646
|
if (!config?.configDir) return null;
|
|
15480
|
-
return readForwardedToolsReport(
|
|
15647
|
+
return readForwardedToolsReport(join43(config.configDir, codeName));
|
|
15481
15648
|
}
|
|
15482
15649
|
var _hostFlagStore = null;
|
|
15483
15650
|
function hostFlagStore() {
|
|
15484
15651
|
if (!_hostFlagStore) {
|
|
15485
|
-
const dir = config?.configDir ??
|
|
15652
|
+
const dir = config?.configDir ?? join43(process.env["HOME"] ?? "/tmp", ".augmented");
|
|
15486
15653
|
_hostFlagStore = new HostFlagStore({ cachePath: defaultFlagsCachePath(dir), log });
|
|
15487
15654
|
}
|
|
15488
15655
|
return _hostFlagStore;
|
|
@@ -15556,12 +15723,12 @@ function parseSkillFrontmatter(content) {
|
|
|
15556
15723
|
}
|
|
15557
15724
|
async function refreshSkillsIndexInClaudeMd(configDir, codeName, log2) {
|
|
15558
15725
|
const { readdirSync: readdirSync13, readFileSync: rfs, existsSync: ex, writeFileSync: writeFileSync19 } = await import("fs");
|
|
15559
|
-
const skillsDir =
|
|
15560
|
-
const claudeMdPath =
|
|
15726
|
+
const skillsDir = join43(configDir, codeName, "project", ".claude", "skills");
|
|
15727
|
+
const claudeMdPath = join43(configDir, codeName, "project", "CLAUDE.md");
|
|
15561
15728
|
if (!ex(skillsDir) || !ex(claudeMdPath)) return;
|
|
15562
15729
|
const entries = [];
|
|
15563
15730
|
for (const dir of readdirSync13(skillsDir).sort()) {
|
|
15564
|
-
const skillFile =
|
|
15731
|
+
const skillFile = join43(skillsDir, dir, "SKILL.md");
|
|
15565
15732
|
if (!ex(skillFile)) continue;
|
|
15566
15733
|
try {
|
|
15567
15734
|
const { name, description } = parseSkillFrontmatter(rfs(skillFile, "utf-8"));
|
|
@@ -15670,7 +15837,7 @@ function flushRestartedAgentDiagnostics(hostId, codeNames) {
|
|
|
15670
15837
|
if (codeNames.length === 0) return;
|
|
15671
15838
|
void (async () => {
|
|
15672
15839
|
try {
|
|
15673
|
-
const { collectDiagnostics } = await import("../persistent-session-
|
|
15840
|
+
const { collectDiagnostics } = await import("../persistent-session-K4DLZ7KF.js");
|
|
15674
15841
|
await api.post("/host/heartbeat", {
|
|
15675
15842
|
host_id: hostId,
|
|
15676
15843
|
agent_diagnostics: collectDiagnostics(codeNames, quarantineEntriesFor, claudeMdSizeFor, spawnOutcomeForDiagnostics, pidPressureFor, forwardedToolsFor)
|
|
@@ -15812,7 +15979,7 @@ async function pollCycleInner() {
|
|
|
15812
15979
|
}
|
|
15813
15980
|
try {
|
|
15814
15981
|
const { detectHostSecurity } = await import("../host-security-KQYYZZVW.js");
|
|
15815
|
-
const { collectDiagnostics } = await import("../persistent-session-
|
|
15982
|
+
const { collectDiagnostics } = await import("../persistent-session-K4DLZ7KF.js");
|
|
15816
15983
|
const diagCodeNames = [...agentState.persistentSessionAgents];
|
|
15817
15984
|
const agentDiagnostics = diagCodeNames.length > 0 ? collectDiagnostics(diagCodeNames, quarantineEntriesFor, claudeMdSizeFor, spawnOutcomeForDiagnostics, pidPressureFor, forwardedToolsFor) : void 0;
|
|
15818
15985
|
let tailscaleHostname;
|
|
@@ -15988,7 +16155,7 @@ async function pollCycleInner() {
|
|
|
15988
16155
|
collectPanelessActivityProbes,
|
|
15989
16156
|
getResponsivenessIntervalMs,
|
|
15990
16157
|
occupancyQualificationClassifications
|
|
15991
|
-
} = await import("../responsiveness-probe-
|
|
16158
|
+
} = await import("../responsiveness-probe-DXPEIUH6.js");
|
|
15992
16159
|
const probeIntervalMs = getResponsivenessIntervalMs();
|
|
15993
16160
|
if (now - lastResponsivenessProbeAt > probeIntervalMs) {
|
|
15994
16161
|
const probeCodeNames = [...agentState.persistentSessionAgents];
|
|
@@ -16105,7 +16272,7 @@ async function pollCycleInner() {
|
|
|
16105
16272
|
collectResponsivenessProbes,
|
|
16106
16273
|
livePendingInboundOldestAgeSeconds,
|
|
16107
16274
|
parkPendingInbound
|
|
16108
|
-
} = await import("../responsiveness-probe-
|
|
16275
|
+
} = await import("../responsiveness-probe-DXPEIUH6.js");
|
|
16109
16276
|
const { getProjectDir: wedgeProjectDir } = await import("../scheduler-engine-M6AFZWNU.js");
|
|
16110
16277
|
const wedgeNow = /* @__PURE__ */ new Date();
|
|
16111
16278
|
const liveAgents = agentState.persistentSessionAgents;
|
|
@@ -16194,13 +16361,13 @@ async function pollCycleInner() {
|
|
|
16194
16361
|
);
|
|
16195
16362
|
if (hostFlagStore().getBoolean("wedge-transient-notice")) {
|
|
16196
16363
|
try {
|
|
16197
|
-
const paneTail =
|
|
16364
|
+
const paneTail = readFileSync34(paneLogPath(codeName), "utf8").slice(-65536);
|
|
16198
16365
|
const transient = detectTransientApiErrorInLog(paneTail);
|
|
16199
16366
|
if (transient) {
|
|
16200
|
-
const wedgeHome =
|
|
16367
|
+
const wedgeHome = join43(homedir18(), ".augmented", codeName);
|
|
16201
16368
|
if (existsSync19(wedgeHome)) {
|
|
16202
16369
|
atomicWriteFileSync(
|
|
16203
|
-
|
|
16370
|
+
join43(wedgeHome, "watchdog-give-up.json"),
|
|
16204
16371
|
JSON.stringify({
|
|
16205
16372
|
gave_up_at: wedgeNow.toISOString(),
|
|
16206
16373
|
reason: "transient_overload"
|
|
@@ -16261,7 +16428,7 @@ async function pollCycleInner() {
|
|
|
16261
16428
|
}
|
|
16262
16429
|
try {
|
|
16263
16430
|
const { scrapeMcpFailedBannerCount } = await import("../pane-mcp-banner-scraper-VR5QGP3J.js");
|
|
16264
|
-
const { probeSessionAuth } = await import("../session-auth-dead-
|
|
16431
|
+
const { probeSessionAuth } = await import("../session-auth-dead-4SE5Q7MU.js");
|
|
16265
16432
|
const observations = [];
|
|
16266
16433
|
const pendingCacheCommits = [];
|
|
16267
16434
|
const modelApiErrorReportingOn = hostFlagStore().getBoolean("model-api-error-reporting");
|
|
@@ -16417,6 +16584,12 @@ async function pollCycleInner() {
|
|
|
16417
16584
|
agent.code_name,
|
|
16418
16585
|
clear.channel_id
|
|
16419
16586
|
);
|
|
16587
|
+
for (const mode of ["enforce", "shadow"]) {
|
|
16588
|
+
channelResumeHistoryStore().forget(
|
|
16589
|
+
agent.code_name,
|
|
16590
|
+
resumeHistoryKey(mode, clear.channel_id)
|
|
16591
|
+
);
|
|
16592
|
+
}
|
|
16420
16593
|
log(
|
|
16421
16594
|
`[channel-reenable] ${removed ? "cleared" : "no marker for"} '${clear.channel_id}' on '${agent.code_name}' (operator re-enable)`
|
|
16422
16595
|
);
|
|
@@ -16431,6 +16604,92 @@ async function pollCycleInner() {
|
|
|
16431
16604
|
);
|
|
16432
16605
|
}
|
|
16433
16606
|
}
|
|
16607
|
+
const autoResumeMode = channelQuarantineAutoResumeMode();
|
|
16608
|
+
const quarantineMode = channelQuarantineMode();
|
|
16609
|
+
const autoResumeEffective = resolveAutoResumeEffectiveMode(autoResumeMode, quarantineMode);
|
|
16610
|
+
if (autoResumeMode === "enforce" && autoResumeEffective === "shadow") {
|
|
16611
|
+
if (shouldLogAutoResumeModeDowngrade(autoResumeMode, quarantineMode)) {
|
|
16612
|
+
log(
|
|
16613
|
+
`[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.`
|
|
16614
|
+
);
|
|
16615
|
+
}
|
|
16616
|
+
}
|
|
16617
|
+
if (autoResumeEffective !== "off") {
|
|
16618
|
+
const nowMs = Date.now();
|
|
16619
|
+
for (const agent of agents) {
|
|
16620
|
+
if (agent.status !== "active") continue;
|
|
16621
|
+
try {
|
|
16622
|
+
const quarantineEntries = channelQuarantineStore().getQuarantineEntries(agent.code_name);
|
|
16623
|
+
const quarantinedKeys = new Set(quarantineEntries.map((e) => e.serverKey));
|
|
16624
|
+
for (const [storedKey, history] of channelResumeHistoryStore().entriesFor(agent.code_name)) {
|
|
16625
|
+
const isShadowKey = storedKey.startsWith("shadow:");
|
|
16626
|
+
if (isShadowKey !== (autoResumeEffective === "shadow")) continue;
|
|
16627
|
+
const serverKey = isShadowKey ? storedKey.slice("shadow:".length) : storedKey;
|
|
16628
|
+
if (!shouldForgetResumeHistory({
|
|
16629
|
+
isQuarantined: quarantinedKeys.has(serverKey),
|
|
16630
|
+
history,
|
|
16631
|
+
now: nowMs,
|
|
16632
|
+
// THE CONFIGURED DWELL, NOT THE FLOOR (obi-wan `7414dbf3d758`).
|
|
16633
|
+
// A host that raised AGT_CHANNEL_QUARANTINE_DWELL_MS pushes
|
|
16634
|
+
// re-quarantine PAST the floor-derived grace, so a failed trial
|
|
16635
|
+
// read as a success and wiped the strikes - restarting the
|
|
16636
|
+
// five-attempt budget every episode, forever.
|
|
16637
|
+
configuredDwellMs: channelQuarantineDwellMs()
|
|
16638
|
+
})) {
|
|
16639
|
+
continue;
|
|
16640
|
+
}
|
|
16641
|
+
channelResumeHistoryStore().forget(agent.code_name, storedKey);
|
|
16642
|
+
log(
|
|
16643
|
+
`[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)" : "")
|
|
16644
|
+
);
|
|
16645
|
+
}
|
|
16646
|
+
for (const entry of quarantineEntries) {
|
|
16647
|
+
const historyKeyFor = (key) => resumeHistoryKey(autoResumeEffective, key);
|
|
16648
|
+
const historyKey = historyKeyFor(entry.serverKey);
|
|
16649
|
+
const history = channelResumeHistoryStore().get(agent.code_name, historyKey);
|
|
16650
|
+
const decision = decideChannelAutoResume({
|
|
16651
|
+
quarantinedAt: entry.quarantinedAt,
|
|
16652
|
+
history,
|
|
16653
|
+
now: nowMs
|
|
16654
|
+
});
|
|
16655
|
+
if (decision.action === "wait") continue;
|
|
16656
|
+
if (decision.action === "give-up") {
|
|
16657
|
+
if (!channelResumeHistoryStore().noteGaveUpLogged(agent.code_name, historyKeyFor(entry.serverKey))) {
|
|
16658
|
+
log(
|
|
16659
|
+
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.`
|
|
16660
|
+
);
|
|
16661
|
+
}
|
|
16662
|
+
continue;
|
|
16663
|
+
}
|
|
16664
|
+
const quarantineAgeMin = Math.round((nowMs - entry.quarantinedAt) / 6e4);
|
|
16665
|
+
const waitedMin = Math.round(decision.waitedMs / 6e4);
|
|
16666
|
+
const recorded = channelResumeHistoryStore().recordAttempt(
|
|
16667
|
+
agent.code_name,
|
|
16668
|
+
historyKey,
|
|
16669
|
+
nowMs
|
|
16670
|
+
);
|
|
16671
|
+
if (autoResumeEffective === "shadow") {
|
|
16672
|
+
log(
|
|
16673
|
+
`[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`
|
|
16674
|
+
);
|
|
16675
|
+
continue;
|
|
16676
|
+
}
|
|
16677
|
+
const cleared = channelQuarantineStore().clearQuarantine(
|
|
16678
|
+
agent.code_name,
|
|
16679
|
+
entry.serverKey
|
|
16680
|
+
);
|
|
16681
|
+
log(
|
|
16682
|
+
`[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.`
|
|
16683
|
+
);
|
|
16684
|
+
}
|
|
16685
|
+
} catch (err) {
|
|
16686
|
+
log(
|
|
16687
|
+
`[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".`
|
|
16688
|
+
);
|
|
16689
|
+
continue;
|
|
16690
|
+
}
|
|
16691
|
+
}
|
|
16692
|
+
}
|
|
16434
16693
|
const frameworksThisCycle = new Set(agents.map((a) => a.framework).filter(Boolean));
|
|
16435
16694
|
for (const fw of frameworksThisCycle) {
|
|
16436
16695
|
await ensureFrameworkBinary(fw);
|
|
@@ -16550,7 +16809,7 @@ async function pollCycleInner() {
|
|
|
16550
16809
|
`[drain-flush] FAILED for '${prev.codeName}': ${err.message} \u2014 proceeding to teardown; this session was NOT shipped (ENG-9491)`
|
|
16551
16810
|
);
|
|
16552
16811
|
}
|
|
16553
|
-
const agentDir =
|
|
16812
|
+
const agentDir = join43(adapter.getAgentDir(prev.codeName), "provision");
|
|
16554
16813
|
await cleanupAgentFiles(prev.codeName, agentDir);
|
|
16555
16814
|
clearAgentCaches(prev.agentId, prev.codeName);
|
|
16556
16815
|
}
|
|
@@ -16637,10 +16896,10 @@ async function pollCycleInner() {
|
|
|
16637
16896
|
// pending-inbound marker. Best-effort: a write failure is logged by
|
|
16638
16897
|
// the watchdog, never fails the poll cycle.
|
|
16639
16898
|
signalGiveUp: (codeName) => {
|
|
16640
|
-
const dir =
|
|
16899
|
+
const dir = join43(homedir18(), ".augmented", codeName);
|
|
16641
16900
|
if (!existsSync19(dir)) return;
|
|
16642
16901
|
atomicWriteFileSync(
|
|
16643
|
-
|
|
16902
|
+
join43(dir, "watchdog-give-up.json"),
|
|
16644
16903
|
JSON.stringify({ gave_up_at: (/* @__PURE__ */ new Date()).toISOString() })
|
|
16645
16904
|
);
|
|
16646
16905
|
},
|
|
@@ -16661,7 +16920,7 @@ async function pollCycleInner() {
|
|
|
16661
16920
|
const dir = getFramework("claude-code").getAgentDir(codeName);
|
|
16662
16921
|
if (!existsSync19(dir)) return;
|
|
16663
16922
|
atomicWriteFileSync(
|
|
16664
|
-
|
|
16923
|
+
join43(dir, "watchdog-give-up.json"),
|
|
16665
16924
|
JSON.stringify({
|
|
16666
16925
|
gave_up_at: (/* @__PURE__ */ new Date()).toISOString(),
|
|
16667
16926
|
reason: "usage_limit",
|
|
@@ -16926,7 +17185,7 @@ async function processAgent(agent, agentStates, managedToolkits) {
|
|
|
16926
17185
|
}
|
|
16927
17186
|
const now = (/* @__PURE__ */ new Date()).toISOString();
|
|
16928
17187
|
const adapter = resolveAgentFramework(agent.code_name);
|
|
16929
|
-
let agentDir =
|
|
17188
|
+
let agentDir = join43(adapter.getAgentDir(agent.code_name), "provision");
|
|
16930
17189
|
if (agent.status === "draft" || agent.status === "paused") {
|
|
16931
17190
|
forgetChannelSyncState(agent.agent_id);
|
|
16932
17191
|
if (previousKnownStatus !== agent.status) {
|
|
@@ -17073,7 +17332,7 @@ async function processAgent(agent, agentStates, managedToolkits) {
|
|
|
17073
17332
|
if (refreshData.knowledge_manifest) {
|
|
17074
17333
|
const resolved = await resolveKnowledgeFromManifest({
|
|
17075
17334
|
manifest: refreshData.knowledge_manifest,
|
|
17076
|
-
cacheDir:
|
|
17335
|
+
cacheDir: join43(config.configDir, "_knowledge"),
|
|
17077
17336
|
delivery: refreshData.agent?.knowledge_delivery ?? "both",
|
|
17078
17337
|
fetchContents: async (hashes) => {
|
|
17079
17338
|
const res = await api.post(
|
|
@@ -17090,7 +17349,7 @@ async function processAgent(agent, agentStates, managedToolkits) {
|
|
|
17090
17349
|
const resolvedSkills = await resolveSkillsFromManifest({
|
|
17091
17350
|
globals: refreshData.global_skills_manifest ?? [],
|
|
17092
17351
|
shared: refreshData.shared_skills_manifest ?? [],
|
|
17093
|
-
cacheDir:
|
|
17352
|
+
cacheDir: join43(config.configDir, "_skills"),
|
|
17094
17353
|
fetchContents: async (hashes) => {
|
|
17095
17354
|
const res = await api.post(
|
|
17096
17355
|
"/host/skills/contents",
|
|
@@ -17108,7 +17367,7 @@ async function processAgent(agent, agentStates, managedToolkits) {
|
|
|
17108
17367
|
if (refreshData.integration_skills_manifest) {
|
|
17109
17368
|
const resolvedIntegrationSkills = await resolveIntegrationSkillsFromManifest({
|
|
17110
17369
|
manifest: refreshData.integration_skills_manifest,
|
|
17111
|
-
cacheDir:
|
|
17370
|
+
cacheDir: join43(config.configDir, "_skills"),
|
|
17112
17371
|
fetchContents: async (hashes) => {
|
|
17113
17372
|
const res = await api.post(
|
|
17114
17373
|
"/host/skills/contents",
|
|
@@ -17170,7 +17429,7 @@ async function processAgent(agent, agentStates, managedToolkits) {
|
|
|
17170
17429
|
const frameworkId = refreshData.agent.framework ?? DEFAULT_FRAMEWORK;
|
|
17171
17430
|
agentFrameworkCache.set(agent.code_name, frameworkId);
|
|
17172
17431
|
const frameworkAdapter = getFramework(frameworkId);
|
|
17173
|
-
agentDir =
|
|
17432
|
+
agentDir = join43(frameworkAdapter.getAgentDir(agent.code_name), "provision");
|
|
17174
17433
|
cacheAgentDeliveryMetadata(agent.code_name, refreshData);
|
|
17175
17434
|
agentRestartTimezoneInputs.set(agent.code_name, {
|
|
17176
17435
|
agentTimezone: typeof refreshData.agent.timezone === "string" ? refreshData.agent.timezone : null,
|
|
@@ -17229,7 +17488,7 @@ async function processAgent(agent, agentStates, managedToolkits) {
|
|
|
17229
17488
|
const changedFiles = [];
|
|
17230
17489
|
mkdirSync15(agentDir, { recursive: true });
|
|
17231
17490
|
for (const artifact of artifacts) {
|
|
17232
|
-
const filePath =
|
|
17491
|
+
const filePath = join43(agentDir, artifact.relativePath);
|
|
17233
17492
|
let existingHash;
|
|
17234
17493
|
let newHash;
|
|
17235
17494
|
let writeContent = artifact.content;
|
|
@@ -17248,8 +17507,8 @@ async function processAgent(agent, agentStates, managedToolkits) {
|
|
|
17248
17507
|
};
|
|
17249
17508
|
newHash = sha256(stripDynamicSections(artifact.content));
|
|
17250
17509
|
try {
|
|
17251
|
-
const projectClaudeMd =
|
|
17252
|
-
const existing =
|
|
17510
|
+
const projectClaudeMd = join43(config.configDir, agent.code_name, "project", "CLAUDE.md");
|
|
17511
|
+
const existing = readFileSync34(projectClaudeMd, "utf-8");
|
|
17253
17512
|
existingHash = sha256(stripDynamicSections(existing));
|
|
17254
17513
|
} catch {
|
|
17255
17514
|
existingHash = null;
|
|
@@ -17267,7 +17526,7 @@ async function processAgent(agent, agentStates, managedToolkits) {
|
|
|
17267
17526
|
const generatorKeys = Object.keys(generatorServers);
|
|
17268
17527
|
let existingRaw = "";
|
|
17269
17528
|
try {
|
|
17270
|
-
existingRaw =
|
|
17529
|
+
existingRaw = readFileSync34(filePath, "utf-8");
|
|
17271
17530
|
} catch {
|
|
17272
17531
|
}
|
|
17273
17532
|
const existingServers = parseMcp(existingRaw);
|
|
@@ -17283,7 +17542,7 @@ async function processAgent(agent, agentStates, managedToolkits) {
|
|
|
17283
17542
|
} else if (artifact.relativePath === "opencode.json") {
|
|
17284
17543
|
let existingRaw = null;
|
|
17285
17544
|
try {
|
|
17286
|
-
existingRaw =
|
|
17545
|
+
existingRaw = readFileSync34(filePath, "utf-8");
|
|
17287
17546
|
} catch {
|
|
17288
17547
|
}
|
|
17289
17548
|
const mergeResult = mergeOpencodeConfigArtifact(artifact.content, existingRaw);
|
|
@@ -17299,12 +17558,12 @@ async function processAgent(agent, agentStates, managedToolkits) {
|
|
|
17299
17558
|
}
|
|
17300
17559
|
}
|
|
17301
17560
|
if (changedFiles.length > 0) {
|
|
17302
|
-
const isFirst = !existsSync19(
|
|
17561
|
+
const isFirst = !existsSync19(join43(agentDir, "CHARTER.md"));
|
|
17303
17562
|
const verb = isFirst ? "Provisioning" : "Updating";
|
|
17304
17563
|
const fileNames = changedFiles.map((f) => f.relativePath).join(", ");
|
|
17305
17564
|
log(`${verb} '${agent.code_name}': ${fileNames}`);
|
|
17306
17565
|
for (const file of changedFiles) {
|
|
17307
|
-
const filePath =
|
|
17566
|
+
const filePath = join43(agentDir, file.relativePath);
|
|
17308
17567
|
mkdirSync15(dirname11(filePath), { recursive: true });
|
|
17309
17568
|
if (file.relativePath === ".mcp.json") {
|
|
17310
17569
|
safeWriteJsonAtomic(filePath, file.content, { mode: 384 });
|
|
@@ -17313,12 +17572,12 @@ async function processAgent(agent, agentStates, managedToolkits) {
|
|
|
17313
17572
|
}
|
|
17314
17573
|
}
|
|
17315
17574
|
try {
|
|
17316
|
-
const provSkillsDir =
|
|
17575
|
+
const provSkillsDir = join43(agentDir, ".claude", "skills");
|
|
17317
17576
|
if (existsSync19(provSkillsDir)) {
|
|
17318
17577
|
for (const folder of readdirSync12(provSkillsDir)) {
|
|
17319
17578
|
if (folder.startsWith("knowledge-")) {
|
|
17320
17579
|
try {
|
|
17321
|
-
rmSync8(
|
|
17580
|
+
rmSync8(join43(provSkillsDir, folder), { recursive: true });
|
|
17322
17581
|
} catch {
|
|
17323
17582
|
}
|
|
17324
17583
|
}
|
|
@@ -17331,7 +17590,7 @@ async function processAgent(agent, agentStates, managedToolkits) {
|
|
|
17331
17590
|
const trackedFiles2 = frameworkAdapter.driftTrackedFiles();
|
|
17332
17591
|
const hashes = /* @__PURE__ */ new Map();
|
|
17333
17592
|
for (const file of trackedFiles2) {
|
|
17334
|
-
const h = hashFile(
|
|
17593
|
+
const h = hashFile(join43(agentDir, file));
|
|
17335
17594
|
if (h) hashes.set(file, h);
|
|
17336
17595
|
}
|
|
17337
17596
|
agentState.writtenHashes.set(agent.agent_id, hashes);
|
|
@@ -17349,14 +17608,14 @@ async function processAgent(agent, agentStates, managedToolkits) {
|
|
|
17349
17608
|
}
|
|
17350
17609
|
if (Array.isArray(refreshData.workflows)) {
|
|
17351
17610
|
try {
|
|
17352
|
-
const provWorkflowsDir =
|
|
17611
|
+
const provWorkflowsDir = join43(agentDir, ".claude", "workflows");
|
|
17353
17612
|
if (existsSync19(provWorkflowsDir)) {
|
|
17354
17613
|
const expected = new Set(refreshData.workflows.map((w) => `${w.name}.js`));
|
|
17355
17614
|
for (const file of readdirSync12(provWorkflowsDir)) {
|
|
17356
17615
|
if (!file.endsWith(".js")) continue;
|
|
17357
17616
|
if (expected.has(file)) continue;
|
|
17358
17617
|
try {
|
|
17359
|
-
rmSync8(
|
|
17618
|
+
rmSync8(join43(provWorkflowsDir, file));
|
|
17360
17619
|
} catch {
|
|
17361
17620
|
}
|
|
17362
17621
|
}
|
|
@@ -17438,7 +17697,7 @@ async function processAgent(agent, agentStates, managedToolkits) {
|
|
|
17438
17697
|
if (written && existsSync19(agentDir)) {
|
|
17439
17698
|
const driftedFiles = [];
|
|
17440
17699
|
for (const [file, expectedHash] of written) {
|
|
17441
|
-
const localHash = hashFile(
|
|
17700
|
+
const localHash = hashFile(join43(agentDir, file));
|
|
17442
17701
|
if (localHash && localHash !== expectedHash) {
|
|
17443
17702
|
driftedFiles.push(file);
|
|
17444
17703
|
}
|
|
@@ -17449,7 +17708,7 @@ async function processAgent(agent, agentStates, managedToolkits) {
|
|
|
17449
17708
|
try {
|
|
17450
17709
|
const localHashes = {};
|
|
17451
17710
|
for (const file of driftedFiles) {
|
|
17452
|
-
localHashes[file] = hashFile(
|
|
17711
|
+
localHashes[file] = hashFile(join43(agentDir, file));
|
|
17453
17712
|
}
|
|
17454
17713
|
await api.post("/host/drift", {
|
|
17455
17714
|
agent_id: agent.agent_id,
|
|
@@ -17727,7 +17986,7 @@ async function processAgent(agent, agentStates, managedToolkits) {
|
|
|
17727
17986
|
const addedChannels = [...restartDecision.added];
|
|
17728
17987
|
const writeDmNoticeMarkers = isChannelAddRestart ? () => {
|
|
17729
17988
|
try {
|
|
17730
|
-
const agentAugmentedDir =
|
|
17989
|
+
const agentAugmentedDir = join43(homedir18(), ".augmented", agent.code_name);
|
|
17731
17990
|
mkdirSync15(agentAugmentedDir, { recursive: true });
|
|
17732
17991
|
const markerJson = JSON.stringify({
|
|
17733
17992
|
version: 1,
|
|
@@ -17735,7 +17994,7 @@ async function processAgent(agent, agentStates, managedToolkits) {
|
|
|
17735
17994
|
added: addedChannels
|
|
17736
17995
|
});
|
|
17737
17996
|
for (const file of ["slack-channel-add-restart.json", "telegram-channel-add-restart.json"]) {
|
|
17738
|
-
atomicWriteFileSync(
|
|
17997
|
+
atomicWriteFileSync(join43(agentAugmentedDir, file), markerJson);
|
|
17739
17998
|
}
|
|
17740
17999
|
} catch (err) {
|
|
17741
18000
|
log(`[hot-reload] channel-add DM-notice marker write failed for '${agent.code_name}' (non-fatal): ${err.message}`);
|
|
@@ -18034,18 +18293,18 @@ async function processAgent(agent, agentStates, managedToolkits) {
|
|
|
18034
18293
|
if (agentSessionMode === "persistent" && (agentFrameworkCache.get(agent.code_name) ?? DEFAULT_FRAMEWORK) === "claude-code") {
|
|
18035
18294
|
try {
|
|
18036
18295
|
const agentProvisionDir = agentDir;
|
|
18037
|
-
const projectDir =
|
|
18296
|
+
const projectDir = join43(homedir18(), ".augmented", agent.code_name, "project");
|
|
18038
18297
|
mkdirSync15(agentProvisionDir, { recursive: true });
|
|
18039
18298
|
mkdirSync15(projectDir, { recursive: true });
|
|
18040
|
-
const provisionMcpPath =
|
|
18041
|
-
const projectMcpPath =
|
|
18299
|
+
const provisionMcpPath = join43(agentProvisionDir, ".mcp.json");
|
|
18300
|
+
const projectMcpPath = join43(projectDir, ".mcp.json");
|
|
18042
18301
|
let mcpConfig = { mcpServers: {} };
|
|
18043
18302
|
try {
|
|
18044
|
-
mcpConfig = JSON.parse(
|
|
18303
|
+
mcpConfig = JSON.parse(readFileSync34(provisionMcpPath, "utf-8"));
|
|
18045
18304
|
if (!mcpConfig.mcpServers) mcpConfig.mcpServers = {};
|
|
18046
18305
|
} catch {
|
|
18047
18306
|
}
|
|
18048
|
-
const localDirectChatChannel =
|
|
18307
|
+
const localDirectChatChannel = join43(homedir18(), ".augmented", "_mcp", "direct-chat-channel.js");
|
|
18049
18308
|
const directChatTeamSettings = refreshData.team?.settings;
|
|
18050
18309
|
const directChatTz = (() => {
|
|
18051
18310
|
const tz = directChatTeamSettings?.["timezone"];
|
|
@@ -18071,7 +18330,7 @@ async function processAgent(agent, agentStates, managedToolkits) {
|
|
|
18071
18330
|
// ~/.augmented/<codeName>/.current-turn-initiator.json. Note getAgentDir
|
|
18072
18331
|
// returns the agent root (NOT the /provision subdir `agentDir` points at),
|
|
18073
18332
|
// so it byte-matches the broker readers' path.
|
|
18074
|
-
AGT_TURN_INITIATOR_FILE:
|
|
18333
|
+
AGT_TURN_INITIATOR_FILE: join43(
|
|
18075
18334
|
frameworkAdapter.getAgentDir(agent.code_name),
|
|
18076
18335
|
".current-turn-initiator.json"
|
|
18077
18336
|
)
|
|
@@ -18091,7 +18350,7 @@ async function processAgent(agent, agentStates, managedToolkits) {
|
|
|
18091
18350
|
log(`Channel credentials written for '${agent.code_name}/direct-chat'`);
|
|
18092
18351
|
}
|
|
18093
18352
|
}
|
|
18094
|
-
const staleChannelsPath =
|
|
18353
|
+
const staleChannelsPath = join43(projectDir, ".mcp-channels.json");
|
|
18095
18354
|
if (existsSync19(staleChannelsPath)) {
|
|
18096
18355
|
try {
|
|
18097
18356
|
rmSync8(staleChannelsPath, { force: true });
|
|
@@ -18204,7 +18463,7 @@ async function processAgent(agent, agentStates, managedToolkits) {
|
|
|
18204
18463
|
}
|
|
18205
18464
|
if (hostFlagStore().getBoolean("connectivity-probe")) {
|
|
18206
18465
|
try {
|
|
18207
|
-
const probeProjectDir =
|
|
18466
|
+
const probeProjectDir = join43(homedir18(), ".augmented", agent.code_name, "project");
|
|
18208
18467
|
let probeSet = integrations;
|
|
18209
18468
|
const fetchQuarantined = async () => {
|
|
18210
18469
|
const quarantined = await api.post("/host/agent-integrations/quarantined", { agent_id: agent.agent_id });
|
|
@@ -18264,7 +18523,7 @@ async function processAgent(agent, agentStates, managedToolkits) {
|
|
|
18264
18523
|
const forceDue = attemptsLeft > 0;
|
|
18265
18524
|
let probeRan = false;
|
|
18266
18525
|
try {
|
|
18267
|
-
const probeProjectDir =
|
|
18526
|
+
const probeProjectDir = join43(homedir18(), ".augmented", agent.code_name, "project");
|
|
18268
18527
|
probeRan = await runAgentSessionToolBindProbes(agent, integrations, probeProjectDir, { forceDue });
|
|
18269
18528
|
} catch (err) {
|
|
18270
18529
|
log(`Session-tool-bind probe failed for '${agent.code_name}': ${err.message}`);
|
|
@@ -18341,11 +18600,11 @@ async function processAgent(agent, agentStates, managedToolkits) {
|
|
|
18341
18600
|
const intHash = computeIntegrationsHash(integrations);
|
|
18342
18601
|
const prevIntHash = agentState.knownIntegrationHashes.get(agent.agent_id);
|
|
18343
18602
|
if (intHash !== prevIntHash) {
|
|
18344
|
-
const projectDir =
|
|
18345
|
-
const envIntPath =
|
|
18603
|
+
const projectDir = join43(homedir18(), ".augmented", agent.code_name, "project");
|
|
18604
|
+
const envIntPath = join43(projectDir, ".env.integrations");
|
|
18346
18605
|
let preWriteEnv;
|
|
18347
18606
|
try {
|
|
18348
|
-
preWriteEnv =
|
|
18607
|
+
preWriteEnv = readFileSync34(envIntPath, "utf-8");
|
|
18349
18608
|
} catch {
|
|
18350
18609
|
preWriteEnv = void 0;
|
|
18351
18610
|
}
|
|
@@ -18364,9 +18623,9 @@ async function processAgent(agent, agentStates, managedToolkits) {
|
|
|
18364
18623
|
}
|
|
18365
18624
|
if (fw === "claude-code" && isSessionHealthy(agent.code_name)) {
|
|
18366
18625
|
try {
|
|
18367
|
-
const projectMcpPath =
|
|
18368
|
-
const postWriteEnv =
|
|
18369
|
-
const mcpContent =
|
|
18626
|
+
const projectMcpPath = join43(projectDir, ".mcp.json");
|
|
18627
|
+
const postWriteEnv = readFileSync34(envIntPath, "utf-8");
|
|
18628
|
+
const mcpContent = readFileSync34(projectMcpPath, "utf-8");
|
|
18370
18629
|
const changedVars = diffEnvIntegrations(preWriteEnv, postWriteEnv);
|
|
18371
18630
|
const mcpJsonForReap = JSON.parse(mcpContent);
|
|
18372
18631
|
const affectedServerKeys = findMcpServersUsingVars(mcpJsonForReap, changedVars);
|
|
@@ -18669,12 +18928,12 @@ async function processAgent(agent, agentStates, managedToolkits) {
|
|
|
18669
18928
|
const frameworkId2 = frameworkAdapter.id;
|
|
18670
18929
|
const candidateSkillDirs = [
|
|
18671
18930
|
// Claude Code — framework runtime tree
|
|
18672
|
-
|
|
18931
|
+
join43(homedir19(), ".augmented", agent.code_name, "skills"),
|
|
18673
18932
|
// Claude Code — project tree
|
|
18674
|
-
|
|
18933
|
+
join43(homedir19(), ".augmented", agent.code_name, "project", ".claude", "skills"),
|
|
18675
18934
|
// Defensive: legacy provision-side path, not currently an
|
|
18676
18935
|
// install target but cheap to sweep.
|
|
18677
|
-
|
|
18936
|
+
join43(agentDir, ".claude", "skills")
|
|
18678
18937
|
];
|
|
18679
18938
|
const existingDirs = candidateSkillDirs.filter((d) => existsSync19(d));
|
|
18680
18939
|
const discoveredEntries = /* @__PURE__ */ new Set();
|
|
@@ -18717,7 +18976,7 @@ async function processAgent(agent, agentStates, managedToolkits) {
|
|
|
18717
18976
|
const sharedSkillsPayload = refreshAny.shared_skills;
|
|
18718
18977
|
const desiredResolved = globalSkillsPayload !== void 0 || sharedSkillsPayload !== void 0;
|
|
18719
18978
|
const manifestPath = managedSkillManifestPath(
|
|
18720
|
-
|
|
18979
|
+
join43(homedir18(), ".augmented", agent.code_name)
|
|
18721
18980
|
);
|
|
18722
18981
|
const prevIds = /* @__PURE__ */ new Set([
|
|
18723
18982
|
...agentState.knownGlobalSkillIds.get(agent.agent_id) ?? /* @__PURE__ */ new Set(),
|
|
@@ -18737,15 +18996,15 @@ async function processAgent(agent, agentStates, managedToolkits) {
|
|
|
18737
18996
|
}
|
|
18738
18997
|
if (plan.removes.length) {
|
|
18739
18998
|
const globalSkillDirs = [
|
|
18740
|
-
|
|
18741
|
-
|
|
18742
|
-
|
|
18999
|
+
join43(homedir18(), ".augmented", agent.code_name, "skills"),
|
|
19000
|
+
join43(homedir18(), ".augmented", agent.code_name, "project", ".claude", "skills"),
|
|
19001
|
+
join43(agentDir, ".claude", "skills")
|
|
18743
19002
|
];
|
|
18744
19003
|
for (const id of plan.removes) {
|
|
18745
19004
|
let prunedAny = false;
|
|
18746
19005
|
for (const dir of globalSkillDirs) {
|
|
18747
|
-
const p =
|
|
18748
|
-
if (existsSync19(p) && existsSync19(
|
|
19006
|
+
const p = join43(dir, id);
|
|
19007
|
+
if (existsSync19(p) && existsSync19(join43(p, "SKILL.md"))) {
|
|
18749
19008
|
rmSync8(p, { recursive: true, force: true });
|
|
18750
19009
|
prunedAny = true;
|
|
18751
19010
|
}
|
|
@@ -19001,8 +19260,8 @@ async function processAgent(agent, agentStates, managedToolkits) {
|
|
|
19001
19260
|
const sess = getSessionState(agent.code_name);
|
|
19002
19261
|
let mcpJsonParsed = null;
|
|
19003
19262
|
try {
|
|
19004
|
-
const mcpPath =
|
|
19005
|
-
mcpJsonParsed = JSON.parse(
|
|
19263
|
+
const mcpPath = join43(getProjectDir(agent.code_name), ".mcp.json");
|
|
19264
|
+
mcpJsonParsed = JSON.parse(readFileSync34(mcpPath, "utf-8"));
|
|
19006
19265
|
} catch {
|
|
19007
19266
|
}
|
|
19008
19267
|
const computerUseIsolated = isolationMode(agent.code_name) === "docker";
|
|
@@ -19494,7 +19753,7 @@ Retried to the limit after repeated stalls \u2014 needs a look.`).catch(() => {
|
|
|
19494
19753
|
if (trackedFiles.length > 0 && existsSync19(agentDir)) {
|
|
19495
19754
|
const hashes = /* @__PURE__ */ new Map();
|
|
19496
19755
|
for (const file of trackedFiles) {
|
|
19497
|
-
const h = hashFile(
|
|
19756
|
+
const h = hashFile(join43(agentDir, file));
|
|
19498
19757
|
if (h) hashes.set(file, h);
|
|
19499
19758
|
}
|
|
19500
19759
|
agentState.writtenHashes.set(agent.agent_id, hashes);
|
|
@@ -19509,7 +19768,7 @@ Retried to the limit after repeated stalls \u2014 needs a look.`).catch(() => {
|
|
|
19509
19768
|
refreshData.agent.onboarding_state
|
|
19510
19769
|
);
|
|
19511
19770
|
const obStep = obState.step;
|
|
19512
|
-
const markerPath =
|
|
19771
|
+
const markerPath = join43(homedir18(), ".augmented", agent.code_name, "onboarding-drive.json");
|
|
19513
19772
|
const marker = readOnboardingDriveMarker(markerPath);
|
|
19514
19773
|
const obContactRaw = refreshData.agent.manager_last_contacted_at;
|
|
19515
19774
|
const obContact = typeof obContactRaw === "string" && obContactRaw ? obContactRaw : null;
|
|
@@ -19624,7 +19883,7 @@ async function ensureOpencodeRuntime(agent, refreshData, agentTimezone) {
|
|
|
19624
19883
|
}
|
|
19625
19884
|
stopOpencodeSlackIngest(codeName, log);
|
|
19626
19885
|
stopOpencodeTelegramIngest(codeName, log);
|
|
19627
|
-
const opencodeProjectDir =
|
|
19886
|
+
const opencodeProjectDir = join43(getFramework("opencode").getAgentDir(codeName), "provision");
|
|
19628
19887
|
const serveEnv = {
|
|
19629
19888
|
AGT_HOST: requireHost(),
|
|
19630
19889
|
AGT_API_KEY: getApiKey() ?? void 0,
|
|
@@ -19684,8 +19943,8 @@ async function ensurePersistentSessionUnchecked(agent, tasks, boardItems, refres
|
|
|
19684
19943
|
});
|
|
19685
19944
|
}
|
|
19686
19945
|
const projectDir = getProjectDir(codeName);
|
|
19687
|
-
const mcpConfigPath =
|
|
19688
|
-
const claudeMdPath =
|
|
19946
|
+
const mcpConfigPath = join43(projectDir, ".mcp.json");
|
|
19947
|
+
const claudeMdPath = join43(projectDir, "CLAUDE.md");
|
|
19689
19948
|
if (restartBreaker.isTripped(codeName)) {
|
|
19690
19949
|
const trip = restartBreaker.getTrip(codeName);
|
|
19691
19950
|
return {
|
|
@@ -20549,7 +20808,7 @@ async function handleRestartDoorbell(agentId, requestedAt, restartReason) {
|
|
|
20549
20808
|
try {
|
|
20550
20809
|
const freshId = rotateSessionForWedge(codeName);
|
|
20551
20810
|
consecutiveWedgeCycles.delete(codeName);
|
|
20552
|
-
const { parkPendingInbound: parkForRestart } = await import("../responsiveness-probe-
|
|
20811
|
+
const { parkPendingInbound: parkForRestart } = await import("../responsiveness-probe-DXPEIUH6.js");
|
|
20553
20812
|
const { parked, deadLettered } = parkForRestart(codeName, /* @__PURE__ */ new Date());
|
|
20554
20813
|
const parkNote = parked > 0 ? `, ${parked} inbound parked` : "";
|
|
20555
20814
|
const deadNote = deadLettered > 0 ? `, ${deadLettered} undeliverable dead-lettered` : "";
|
|
@@ -20592,7 +20851,7 @@ async function handleRestartDoorbell(agentId, requestedAt, restartReason) {
|
|
|
20592
20851
|
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
20852
|
void (async () => {
|
|
20594
20853
|
try {
|
|
20595
|
-
const { collectDiagnostics } = await import("../persistent-session-
|
|
20854
|
+
const { collectDiagnostics } = await import("../persistent-session-K4DLZ7KF.js");
|
|
20596
20855
|
await api.post("/host/heartbeat", {
|
|
20597
20856
|
host_id: hostId,
|
|
20598
20857
|
agent_diagnostics: collectDiagnostics([codeName], quarantineEntriesFor, claudeMdSizeFor, spawnOutcomeForDiagnostics, pidPressureFor, forwardedToolsFor)
|
|
@@ -20643,7 +20902,7 @@ async function respawnAgentAfterMcpStop(codeName, reason) {
|
|
|
20643
20902
|
}
|
|
20644
20903
|
try {
|
|
20645
20904
|
const hostId = await getHostId();
|
|
20646
|
-
const { collectDiagnostics } = await import("../persistent-session-
|
|
20905
|
+
const { collectDiagnostics } = await import("../persistent-session-K4DLZ7KF.js");
|
|
20647
20906
|
await api.post("/host/heartbeat", {
|
|
20648
20907
|
host_id: hostId,
|
|
20649
20908
|
agent_diagnostics: collectDiagnostics([codeName], quarantineEntriesFor, claudeMdSizeFor, spawnOutcomeForDiagnostics, pidPressureFor, forwardedToolsFor)
|
|
@@ -21302,8 +21561,19 @@ async function processClaudePairSessions(agents) {
|
|
|
21302
21561
|
spawnPairSession,
|
|
21303
21562
|
killPairSession,
|
|
21304
21563
|
pairTmuxSession,
|
|
21305
|
-
finalizeClaudePairOnboarding
|
|
21306
|
-
|
|
21564
|
+
finalizeClaudePairOnboarding,
|
|
21565
|
+
// ENG-10862: the failure vocabulary lives beside the loop that produces it,
|
|
21566
|
+
// so the code the console stores and the message the operator reads cannot
|
|
21567
|
+
// drift from the reason finalize actually returned.
|
|
21568
|
+
PAIR_FINALIZE_ERROR_CODES,
|
|
21569
|
+
describePairFinalizeFailure,
|
|
21570
|
+
// ENG-10862: the last-chance re-read before a failure is reported.
|
|
21571
|
+
confirmPairFailure,
|
|
21572
|
+
// ENG-10862: the pre-submit mtime baseline. Taken here because finalize
|
|
21573
|
+
// cannot take it for itself — by the time it runs, the write it is looking
|
|
21574
|
+
// for may already have happened.
|
|
21575
|
+
snapshotPairConfig
|
|
21576
|
+
} = await import("../claude-pair-runtime-AW4N6NEE.js");
|
|
21307
21577
|
for (const pairId of pendingResp.cancelled_pair_ids ?? []) {
|
|
21308
21578
|
log(`[claude-pair] sweeping orphan tmux session for pair ${pairId.slice(0, 8)}`);
|
|
21309
21579
|
const killed = await killPairSession(pairTmuxSession(pairId));
|
|
@@ -21323,7 +21593,8 @@ async function processClaudePairSessions(agents) {
|
|
|
21323
21593
|
async function reportAndCleanup(pairId, body) {
|
|
21324
21594
|
await api.post("/host/claude-pair/result", { pair_id: pairId, ...body });
|
|
21325
21595
|
if (typeof body.status === "string" && TERMINAL.has(body.status)) {
|
|
21326
|
-
|
|
21596
|
+
const isOnboardingFailure = typeof body.error_code === "string" && body.error_code.startsWith("onboarding_");
|
|
21597
|
+
if (body.status === "success" || isOnboardingFailure) {
|
|
21327
21598
|
await new Promise((r) => setTimeout(r, 3e3));
|
|
21328
21599
|
}
|
|
21329
21600
|
const killed = await killPairSession(pairTmuxSession(pairId));
|
|
@@ -21375,16 +21646,50 @@ async function processClaudePairSessions(agents) {
|
|
|
21375
21646
|
}
|
|
21376
21647
|
} else if (session.status === "code_submitted" && session.code) {
|
|
21377
21648
|
log(`[claude-pair] submitting code (pair ${session.pair_id.slice(0, 8)})`);
|
|
21649
|
+
const configBaseline = snapshotPairConfig();
|
|
21378
21650
|
const result = await submitClaudePairCode({
|
|
21379
21651
|
session: pairSession,
|
|
21380
21652
|
code: session.code
|
|
21381
21653
|
});
|
|
21382
21654
|
if (result.kind === "success") {
|
|
21383
|
-
const finalize = await finalizeClaudePairOnboarding(pairSession, log
|
|
21384
|
-
|
|
21385
|
-
|
|
21655
|
+
const finalize = await finalizeClaudePairOnboarding(pairSession, log, {
|
|
21656
|
+
baseline: configBaseline
|
|
21657
|
+
});
|
|
21658
|
+
const pairShort = session.pair_id.slice(0, 8);
|
|
21659
|
+
const confirmed = finalize.finalized ? "landed-after-all" : await confirmPairFailure({
|
|
21660
|
+
configPath: finalize.configPath,
|
|
21661
|
+
sinceMtimeMs: configBaseline.mtimeMs,
|
|
21662
|
+
log
|
|
21663
|
+
});
|
|
21664
|
+
if (!finalize.finalized && confirmed === "confirmed") {
|
|
21665
|
+
const reason = finalize.reason ?? "not-flushed";
|
|
21666
|
+
const errorCode = PAIR_FINALIZE_ERROR_CODES[reason];
|
|
21667
|
+
log(
|
|
21668
|
+
`[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`
|
|
21669
|
+
);
|
|
21670
|
+
await reportAndCleanup(session.pair_id, {
|
|
21671
|
+
status: "failure",
|
|
21672
|
+
error_code: errorCode,
|
|
21673
|
+
// The path finalize actually watched, returned by it rather than
|
|
21674
|
+
// recomputed here — two copies of that rule is how the operator
|
|
21675
|
+
// ends up reading about a file the flow never looked at.
|
|
21676
|
+
error_message: describePairFinalizeFailure(reason, finalize.configPath),
|
|
21677
|
+
// AC5: the loop's own accounting, so "do real pairings need more
|
|
21678
|
+
// than 10 dismissals?" stops being unanswerable. Counts only —
|
|
21679
|
+
// never pane text, which carries `Logged in as <email>`. These
|
|
21680
|
+
// are NOT stored on the pair row (no column, by decision); the
|
|
21681
|
+
// route forwards them into the alert payload, which is jsonb.
|
|
21682
|
+
finalize_iterations: finalize.iterations,
|
|
21683
|
+
finalize_grace_waits: finalize.graceWaits,
|
|
21684
|
+
finalize_dialog_counts: finalize.counts
|
|
21685
|
+
});
|
|
21686
|
+
} else {
|
|
21687
|
+
const lateness = finalize.finalized ? "" : ` (late: finalize said ${finalize.reason}, config landed during the confirm window)`;
|
|
21688
|
+
log(
|
|
21689
|
+
`[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}`
|
|
21690
|
+
);
|
|
21691
|
+
await reportAndCleanup(session.pair_id, { status: "success" });
|
|
21386
21692
|
}
|
|
21387
|
-
await reportAndCleanup(session.pair_id, { status: "success" });
|
|
21388
21693
|
} else if (result.kind === "failure") {
|
|
21389
21694
|
await reportAndCleanup(session.pair_id, {
|
|
21390
21695
|
status: "failure",
|
|
@@ -21535,17 +21840,17 @@ var lastLocalFileHash = /* @__PURE__ */ new Map();
|
|
|
21535
21840
|
var lastMemoriesBody = /* @__PURE__ */ new Map();
|
|
21536
21841
|
var memoryManifests = /* @__PURE__ */ new Map();
|
|
21537
21842
|
function memoryRetirementDir(configDir, codeName) {
|
|
21538
|
-
return
|
|
21843
|
+
return join43(configDir, "_memory-retirement", codeName);
|
|
21539
21844
|
}
|
|
21540
21845
|
function memoryManifestPath(configDir, codeName) {
|
|
21541
|
-
return
|
|
21846
|
+
return join43(memoryRetirementDir(configDir, codeName), "manifest.json");
|
|
21542
21847
|
}
|
|
21543
21848
|
function loadMemoryManifest(agentId, configDir, codeName) {
|
|
21544
21849
|
const cached = memoryManifests.get(agentId);
|
|
21545
21850
|
if (cached) return cached;
|
|
21546
21851
|
let manifest = {};
|
|
21547
21852
|
try {
|
|
21548
|
-
const raw =
|
|
21853
|
+
const raw = readFileSync34(memoryManifestPath(configDir, codeName), "utf-8");
|
|
21549
21854
|
const parsed = JSON.parse(raw);
|
|
21550
21855
|
if (parsed && typeof parsed === "object" && !Array.isArray(parsed)) {
|
|
21551
21856
|
for (const [name, entry] of Object.entries(parsed)) {
|
|
@@ -21573,7 +21878,7 @@ function saveMemoryManifest(agentId, configDir, codeName) {
|
|
|
21573
21878
|
}
|
|
21574
21879
|
}
|
|
21575
21880
|
function retiredMemoryDir(configDir, codeName) {
|
|
21576
|
-
return
|
|
21881
|
+
return join43(memoryRetirementDir(configDir, codeName), "retired");
|
|
21577
21882
|
}
|
|
21578
21883
|
var RETIRED_MEMORY_TTL_MS = 30 * 24 * 60 * 60 * 1e3;
|
|
21579
21884
|
var lastRetirementReport = /* @__PURE__ */ new Map();
|
|
@@ -21652,7 +21957,7 @@ function applyMemoryTombstones(opts) {
|
|
|
21652
21957
|
log2(`[memory-retire] ${agent.code_name}: KEPT '${tomb.name}' \u2014 no write record, not ours to remove`);
|
|
21653
21958
|
continue;
|
|
21654
21959
|
}
|
|
21655
|
-
const filePath =
|
|
21960
|
+
const filePath = join43(memoryDir, entry.file);
|
|
21656
21961
|
if (!existsSync19(filePath)) {
|
|
21657
21962
|
outcomes.already_gone++;
|
|
21658
21963
|
delete manifest[tomb.name];
|
|
@@ -21660,7 +21965,7 @@ function applyMemoryTombstones(opts) {
|
|
|
21660
21965
|
continue;
|
|
21661
21966
|
}
|
|
21662
21967
|
try {
|
|
21663
|
-
const actual = createHash20("sha256").update(
|
|
21968
|
+
const actual = createHash20("sha256").update(readFileSync34(filePath)).digest("hex");
|
|
21664
21969
|
if (actual !== entry.sha) {
|
|
21665
21970
|
outcomes.kept_modified++;
|
|
21666
21971
|
outcomes.unapplied.push({ name: tomb.name, reason: "kept_modified" });
|
|
@@ -21672,9 +21977,9 @@ function applyMemoryTombstones(opts) {
|
|
|
21672
21977
|
const destDir = retiredMemoryDir(configDir, agent.code_name);
|
|
21673
21978
|
mkdirSync15(destDir, { recursive: true });
|
|
21674
21979
|
const stamp = Date.now();
|
|
21675
|
-
let dest =
|
|
21980
|
+
let dest = join43(destDir, `${entry.file}.${stamp}.retired`);
|
|
21676
21981
|
for (let n = 1; existsSync19(dest); n++) {
|
|
21677
|
-
dest =
|
|
21982
|
+
dest = join43(destDir, `${entry.file}.${stamp}-${n}.retired`);
|
|
21678
21983
|
}
|
|
21679
21984
|
renameSync11(filePath, dest);
|
|
21680
21985
|
try {
|
|
@@ -21713,7 +22018,7 @@ function reapRetiredMemories(configDir, codeName, log2) {
|
|
|
21713
22018
|
try {
|
|
21714
22019
|
for (const file of readdirSync12(dir)) {
|
|
21715
22020
|
if (!file.endsWith(".retired")) continue;
|
|
21716
|
-
const path =
|
|
22021
|
+
const path = join43(dir, file);
|
|
21717
22022
|
try {
|
|
21718
22023
|
if (statSync13(path).mtimeMs < cutoff) {
|
|
21719
22024
|
unlinkSync6(path);
|
|
@@ -21728,8 +22033,8 @@ function reapRetiredMemories(configDir, codeName, log2) {
|
|
|
21728
22033
|
if (reaped > 0) log2(`[memory-retire] ${codeName}: reaped ${reaped} retired memory file(s) past TTL`);
|
|
21729
22034
|
}
|
|
21730
22035
|
async function syncMemories(agent, configDir, log2) {
|
|
21731
|
-
const projectDir =
|
|
21732
|
-
const memoryDir =
|
|
22036
|
+
const projectDir = join43(configDir, agent.code_name, "project");
|
|
22037
|
+
const memoryDir = join43(projectDir, "memory");
|
|
21733
22038
|
const isFreshSync = pendingFreshMemorySync.has(agent.agent_id);
|
|
21734
22039
|
if (isFreshSync) {
|
|
21735
22040
|
log2(`[memory-sync] Fresh-sync requested for '${agent.code_name}' \u2014 pulling DB first`);
|
|
@@ -21760,7 +22065,7 @@ async function syncMemories(agent, configDir, log2) {
|
|
|
21760
22065
|
for (const file of readdirSync12(memoryDir)) {
|
|
21761
22066
|
if (!file.endsWith(".md")) continue;
|
|
21762
22067
|
try {
|
|
21763
|
-
const raw =
|
|
22068
|
+
const raw = readFileSync34(join43(memoryDir, file), "utf-8");
|
|
21764
22069
|
const fileHash = createHash20("sha256").update(raw).digest("hex").slice(0, 16);
|
|
21765
22070
|
currentHashes.set(file, fileHash);
|
|
21766
22071
|
if (prevHashes.get(file) === fileHash) continue;
|
|
@@ -21785,7 +22090,7 @@ async function syncMemories(agent, configDir, log2) {
|
|
|
21785
22090
|
} catch (err) {
|
|
21786
22091
|
for (const mem of changedMemories) {
|
|
21787
22092
|
for (const [file] of currentHashes) {
|
|
21788
|
-
const parsed = parseMemoryFile(
|
|
22093
|
+
const parsed = parseMemoryFile(readFileSync34(join43(memoryDir, file), "utf-8"), file.replace(/\.md$/, ""));
|
|
21789
22094
|
if (parsed?.name === mem.name) currentHashes.delete(file);
|
|
21790
22095
|
}
|
|
21791
22096
|
}
|
|
@@ -21866,7 +22171,7 @@ async function downloadMemories(agent, memoryDir, log2, { force, configDir }) {
|
|
|
21866
22171
|
// Per-agent, not host-wide: memories are agent-private, so a shared
|
|
21867
22172
|
// store would buy almost no dedupe while exposing one agent's content
|
|
21868
22173
|
// to every other agent on the host. See memory-cache.ts's header.
|
|
21869
|
-
cacheDir:
|
|
22174
|
+
cacheDir: join43(configDir, agent.code_name, "_memory_bodies"),
|
|
21870
22175
|
fetchContents: async (hashes) => {
|
|
21871
22176
|
const res = await api.post(
|
|
21872
22177
|
"/host/memories/contents",
|
|
@@ -21904,7 +22209,7 @@ async function downloadMemories(agent, memoryDir, log2, { force, configDir }) {
|
|
|
21904
22209
|
const rawSlug = mem.name.toLowerCase().replace(/[^a-z0-9]+/g, "-").replace(/(^-|-$)/g, "").slice(0, 60);
|
|
21905
22210
|
const slug = rawSlug || `memory-${i}`;
|
|
21906
22211
|
const fileName = `${slug}.md`;
|
|
21907
|
-
const filePath =
|
|
22212
|
+
const filePath = join43(memoryDir, fileName);
|
|
21908
22213
|
const desired = `---
|
|
21909
22214
|
name: ${JSON.stringify(mem.name)}
|
|
21910
22215
|
type: ${mem.type}
|
|
@@ -21924,7 +22229,7 @@ ${mem.content}
|
|
|
21924
22229
|
if (existsSync19(filePath)) {
|
|
21925
22230
|
let existing = "";
|
|
21926
22231
|
try {
|
|
21927
|
-
existing =
|
|
22232
|
+
existing = readFileSync34(filePath, "utf-8");
|
|
21928
22233
|
} catch {
|
|
21929
22234
|
}
|
|
21930
22235
|
if (existing === desired) {
|
|
@@ -22304,7 +22609,7 @@ function startManager(opts) {
|
|
|
22304
22609
|
try {
|
|
22305
22610
|
const stateFile = getStateFile();
|
|
22306
22611
|
if (existsSync19(stateFile)) {
|
|
22307
|
-
const raw =
|
|
22612
|
+
const raw = readFileSync34(stateFile, "utf-8");
|
|
22308
22613
|
const parsed = JSON.parse(raw);
|
|
22309
22614
|
if (Array.isArray(parsed.agents)) {
|
|
22310
22615
|
state8.agents = parsed.agents;
|
|
@@ -22331,7 +22636,7 @@ function startManager(opts) {
|
|
|
22331
22636
|
log(`[startup] state rehydration failed (continuing with empty state): ${err.message}`);
|
|
22332
22637
|
}
|
|
22333
22638
|
log(
|
|
22334
|
-
`[startup] worker pid=${process.pid} ppid=${process.ppid} node=${process.version} log=${
|
|
22639
|
+
`[startup] worker pid=${process.pid} ppid=${process.ppid} node=${process.version} log=${join43(homedir18(), ".augmented", "manager.log")}`
|
|
22335
22640
|
);
|
|
22336
22641
|
deployMcpAssets();
|
|
22337
22642
|
reapOrphanChannelMcps({ log });
|
|
@@ -22360,7 +22665,7 @@ async function reapOrphanedClaudePids() {
|
|
|
22360
22665
|
const looksLikeClaude = (pid) => {
|
|
22361
22666
|
if (process.platform !== "linux") return true;
|
|
22362
22667
|
try {
|
|
22363
|
-
const comm =
|
|
22668
|
+
const comm = readFileSync34(`/proc/${pid}/comm`, "utf-8").trim().toLowerCase();
|
|
22364
22669
|
return comm.includes("claude");
|
|
22365
22670
|
} catch {
|
|
22366
22671
|
return false;
|
|
@@ -22457,14 +22762,14 @@ function restartRunningChannelMcps(basenames) {
|
|
|
22457
22762
|
}
|
|
22458
22763
|
}
|
|
22459
22764
|
function deployMcpAssets() {
|
|
22460
|
-
const targetDir =
|
|
22765
|
+
const targetDir = join43(homedir18(), ".augmented", "_mcp");
|
|
22461
22766
|
mkdirSync15(targetDir, { recursive: true });
|
|
22462
22767
|
const moduleDir = dirname11(fileURLToPath2(import.meta.url));
|
|
22463
22768
|
let mcpSourceDir = "";
|
|
22464
22769
|
let dir = moduleDir;
|
|
22465
22770
|
for (let i = 0; i < 6; i++) {
|
|
22466
|
-
const candidate =
|
|
22467
|
-
if (existsSync19(
|
|
22771
|
+
const candidate = join43(dir, "dist", "mcp");
|
|
22772
|
+
if (existsSync19(join43(candidate, "index.js"))) {
|
|
22468
22773
|
mcpSourceDir = candidate;
|
|
22469
22774
|
break;
|
|
22470
22775
|
}
|
|
@@ -22482,7 +22787,7 @@ function deployMcpAssets() {
|
|
|
22482
22787
|
const fileHash = (p) => {
|
|
22483
22788
|
try {
|
|
22484
22789
|
if (!existsSync19(p)) return null;
|
|
22485
|
-
return createHash20("sha256").update(
|
|
22790
|
+
return createHash20("sha256").update(readFileSync34(p)).digest("hex");
|
|
22486
22791
|
} catch {
|
|
22487
22792
|
return null;
|
|
22488
22793
|
}
|
|
@@ -22564,8 +22869,8 @@ function deployMcpAssets() {
|
|
|
22564
22869
|
// natural session restart.
|
|
22565
22870
|
"computer-use-proxy.js"
|
|
22566
22871
|
]) {
|
|
22567
|
-
const src =
|
|
22568
|
-
const dst =
|
|
22872
|
+
const src = join43(mcpSourceDir, file);
|
|
22873
|
+
const dst = join43(targetDir, file);
|
|
22569
22874
|
if (!existsSync19(src)) continue;
|
|
22570
22875
|
attemptedFiles.push(file);
|
|
22571
22876
|
const before = fileHash(dst);
|
|
@@ -22591,16 +22896,16 @@ function deployMcpAssets() {
|
|
|
22591
22896
|
log(`[manager] Bundle(s) updated: ${changedBasenames.join(", ")} \u2014 signalling running instances to restart`);
|
|
22592
22897
|
restartRunningChannelMcps(changedBasenames);
|
|
22593
22898
|
}
|
|
22594
|
-
const localMcpPath =
|
|
22899
|
+
const localMcpPath = join43(targetDir, "index.js");
|
|
22595
22900
|
try {
|
|
22596
|
-
const agentsDir =
|
|
22901
|
+
const agentsDir = join43(homedir18(), ".augmented", "agents");
|
|
22597
22902
|
if (existsSync19(agentsDir)) {
|
|
22598
22903
|
for (const entry of readdirSync12(agentsDir, { withFileTypes: true })) {
|
|
22599
22904
|
if (!entry.isDirectory()) continue;
|
|
22600
22905
|
for (const subdir of ["provision", "project"]) {
|
|
22601
|
-
const mcpJsonPath =
|
|
22906
|
+
const mcpJsonPath = join43(agentsDir, entry.name, subdir, ".mcp.json");
|
|
22602
22907
|
try {
|
|
22603
|
-
const raw =
|
|
22908
|
+
const raw = readFileSync34(mcpJsonPath, "utf-8");
|
|
22604
22909
|
if (!raw.includes("@integrity-labs/augmented-mcp")) continue;
|
|
22605
22910
|
const mcpConfig = JSON.parse(raw);
|
|
22606
22911
|
const augServer = mcpConfig.mcpServers?.["augmented"];
|