@integrity-labs/agt-cli 0.28.675 → 0.28.677
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-7Y54PSMR.js → chunk-F6CUSDJ6.js} +2 -2
- package/dist/{chunk-AJNES24H.js → chunk-GYYEUNTD.js} +26 -1
- package/dist/chunk-GYYEUNTD.js.map +1 -0
- package/dist/{chunk-ZKP6UYPJ.js → chunk-HTLUHAKN.js} +4 -4
- package/dist/{claude-pair-runtime-VAU7UXE4.js → claude-pair-runtime-MY5LMJVT.js} +2 -2
- package/dist/lib/manager-worker.js +382 -210
- package/dist/lib/manager-worker.js.map +1 -1
- package/dist/mcp/augmented-admin.js +34 -1
- package/dist/mcp/direct-chat-channel.js +25 -0
- package/dist/mcp/index.js +25 -0
- package/dist/mcp/origami.js +25 -0
- package/dist/mcp/slack-channel.js +25 -0
- package/dist/mcp/telegram-channel.js +25 -0
- package/dist/{persistent-session-F7JEOWHQ.js → persistent-session-TMOTEVV6.js} +3 -3
- package/dist/{responsiveness-probe-7465YNMN.js → responsiveness-probe-ZHE7S6G4.js} +3 -3
- package/dist/{session-auth-dead-GBC5QPH3.js → session-auth-dead-JCKENEY5.js} +2 -2
- package/package.json +1 -1
- package/dist/chunk-AJNES24H.js.map +0 -1
- /package/dist/{chunk-7Y54PSMR.js.map → chunk-F6CUSDJ6.js.map} +0 -0
- /package/dist/{chunk-ZKP6UYPJ.js.map → chunk-HTLUHAKN.js.map} +0 -0
- /package/dist/{claude-pair-runtime-VAU7UXE4.js.map → claude-pair-runtime-MY5LMJVT.js.map} +0 -0
- /package/dist/{persistent-session-F7JEOWHQ.js.map → persistent-session-TMOTEVV6.js.map} +0 -0
- /package/dist/{responsiveness-probe-7465YNMN.js.map → responsiveness-probe-ZHE7S6G4.js.map} +0 -0
- /package/dist/{session-auth-dead-GBC5QPH3.js.map → session-auth-dead-JCKENEY5.js.map} +0 -0
|
@@ -54,7 +54,7 @@ import {
|
|
|
54
54
|
safeWriteJsonAtomic,
|
|
55
55
|
setConfigHash,
|
|
56
56
|
tripClass
|
|
57
|
-
} from "../chunk-
|
|
57
|
+
} from "../chunk-HTLUHAKN.js";
|
|
58
58
|
import {
|
|
59
59
|
getProjectDir as getProjectDir2,
|
|
60
60
|
getReadyTasks,
|
|
@@ -112,7 +112,7 @@ import {
|
|
|
112
112
|
takeZombieDetection,
|
|
113
113
|
toOpencodeModel,
|
|
114
114
|
writeEgressAllowlist
|
|
115
|
-
} from "../chunk-
|
|
115
|
+
} from "../chunk-F6CUSDJ6.js";
|
|
116
116
|
import {
|
|
117
117
|
ACCOUNT_ENFORCEMENT_MARKER_FILENAME,
|
|
118
118
|
AnchorSessionClient,
|
|
@@ -193,14 +193,14 @@ import {
|
|
|
193
193
|
subagentActivityAgeSeconds,
|
|
194
194
|
sumTranscriptUsageInWindow,
|
|
195
195
|
transcriptActivityAgeSeconds
|
|
196
|
-
} from "../chunk-
|
|
196
|
+
} from "../chunk-GYYEUNTD.js";
|
|
197
197
|
import {
|
|
198
198
|
reapOrphanChannelMcps
|
|
199
199
|
} from "../chunk-XWVM4KPK.js";
|
|
200
200
|
|
|
201
201
|
// src/lib/manager-worker.ts
|
|
202
202
|
import { createHash as createHash17 } from "crypto";
|
|
203
|
-
import { readFileSync as
|
|
203
|
+
import { readFileSync as readFileSync29, writeFileSync as writeFileSync14, mkdirSync as mkdirSync11, existsSync as existsSync16, rmSync as rmSync5, readdirSync as readdirSync9, statSync as statSync8, unlinkSync as unlinkSync6, renameSync as renameSync8, utimesSync } from "fs";
|
|
204
204
|
|
|
205
205
|
// src/lib/atomic-file-replace.ts
|
|
206
206
|
import { copyFileSync, renameSync, unlinkSync } from "fs";
|
|
@@ -226,7 +226,7 @@ function defaultUnique() {
|
|
|
226
226
|
|
|
227
227
|
// src/lib/manager-worker.ts
|
|
228
228
|
import { execFileSync as syncExecFile } from "child_process";
|
|
229
|
-
import { join as
|
|
229
|
+
import { join as join37, dirname as dirname10, delimiter as pathDelimiter } from "path";
|
|
230
230
|
import { homedir as homedir17 } from "os";
|
|
231
231
|
import { fileURLToPath } from "url";
|
|
232
232
|
|
|
@@ -1608,12 +1608,12 @@ function isPathInsideDir(candidate, dir) {
|
|
|
1608
1608
|
return resolvedCandidate.startsWith(resolvedDir.endsWith(sep) ? resolvedDir : resolvedDir + sep);
|
|
1609
1609
|
}
|
|
1610
1610
|
function findMissingMcpBundles(mcpConfigPath, deps = {}) {
|
|
1611
|
-
const
|
|
1612
|
-
const
|
|
1611
|
+
const existsSync17 = deps.existsSync ?? nodeExistsSync;
|
|
1612
|
+
const readFileSync30 = deps.readFileSync ?? nodeReadFileSync;
|
|
1613
1613
|
const mcpDir = deps.mcpDir ?? getSharedMcpDir();
|
|
1614
1614
|
let parsed;
|
|
1615
1615
|
try {
|
|
1616
|
-
parsed = JSON.parse(
|
|
1616
|
+
parsed = JSON.parse(readFileSync30(mcpConfigPath, "utf-8"));
|
|
1617
1617
|
} catch {
|
|
1618
1618
|
return [];
|
|
1619
1619
|
}
|
|
@@ -1633,7 +1633,7 @@ function findMissingMcpBundles(mcpConfigPath, deps = {}) {
|
|
|
1633
1633
|
if (seenPaths.has(resolvedBundlePath)) continue;
|
|
1634
1634
|
let present;
|
|
1635
1635
|
try {
|
|
1636
|
-
present =
|
|
1636
|
+
present = existsSync17(bundlePath);
|
|
1637
1637
|
} catch {
|
|
1638
1638
|
continue;
|
|
1639
1639
|
}
|
|
@@ -5107,6 +5107,100 @@ function saveSenderPolicyBaseline(source, configDir, log2) {
|
|
|
5107
5107
|
}
|
|
5108
5108
|
}
|
|
5109
5109
|
|
|
5110
|
+
// src/lib/stuck-streak-store.ts
|
|
5111
|
+
import { existsSync as existsSync8, readFileSync as readFileSync19 } from "fs";
|
|
5112
|
+
import { join as join24 } from "path";
|
|
5113
|
+
var STORE_FILENAME = "stuck-streaks.json";
|
|
5114
|
+
var STUCK_STREAK_STORE_VERSION = 1;
|
|
5115
|
+
var STUCK_STREAK_CONCERNS = ["channelSync", "realtimeRebind"];
|
|
5116
|
+
function createStuckStreakMaps() {
|
|
5117
|
+
return { channelSync: /* @__PURE__ */ new Map(), realtimeRebind: /* @__PURE__ */ new Map() };
|
|
5118
|
+
}
|
|
5119
|
+
function getStuckStreakStoreFile(configDir) {
|
|
5120
|
+
return join24(configDir, STORE_FILENAME);
|
|
5121
|
+
}
|
|
5122
|
+
function isValidPersistedStreak(value) {
|
|
5123
|
+
if (!value || typeof value !== "object" || Array.isArray(value)) return false;
|
|
5124
|
+
const v = value;
|
|
5125
|
+
if (typeof v.attempts !== "number" || !Number.isFinite(v.attempts) || v.attempts < 1) return false;
|
|
5126
|
+
if (typeof v.since !== "number" || !Number.isFinite(v.since) || v.since <= 0) return false;
|
|
5127
|
+
if (typeof v.nextAttemptAt !== "number" || !Number.isFinite(v.nextAttemptAt)) return false;
|
|
5128
|
+
if (typeof v.loggedAtAttempt !== "number" || !Number.isFinite(v.loggedAtAttempt) || v.loggedAtAttempt < 0) return false;
|
|
5129
|
+
if (typeof v.detail !== "string") return false;
|
|
5130
|
+
return true;
|
|
5131
|
+
}
|
|
5132
|
+
function parseStuckStreakPayload(parsed) {
|
|
5133
|
+
if (!parsed || typeof parsed !== "object" || Array.isArray(parsed)) return null;
|
|
5134
|
+
const obj = parsed;
|
|
5135
|
+
if (obj.version !== STUCK_STREAK_STORE_VERSION) return null;
|
|
5136
|
+
const maps = createStuckStreakMaps();
|
|
5137
|
+
for (const concern of STUCK_STREAK_CONCERNS) {
|
|
5138
|
+
const entries = obj[concern];
|
|
5139
|
+
if (!entries || typeof entries !== "object" || Array.isArray(entries)) continue;
|
|
5140
|
+
for (const [agentId, entry] of Object.entries(entries)) {
|
|
5141
|
+
if (!agentId) continue;
|
|
5142
|
+
if (!isValidPersistedStreak(entry)) continue;
|
|
5143
|
+
maps[concern].set(agentId, entry);
|
|
5144
|
+
}
|
|
5145
|
+
}
|
|
5146
|
+
return maps;
|
|
5147
|
+
}
|
|
5148
|
+
function buildStuckStreakPayload(source) {
|
|
5149
|
+
const payload = { version: STUCK_STREAK_STORE_VERSION };
|
|
5150
|
+
for (const concern of STUCK_STREAK_CONCERNS) {
|
|
5151
|
+
const entries = {};
|
|
5152
|
+
for (const [agentId, streak] of source[concern]) entries[agentId] = streak;
|
|
5153
|
+
payload[concern] = entries;
|
|
5154
|
+
}
|
|
5155
|
+
return payload;
|
|
5156
|
+
}
|
|
5157
|
+
function loadStuckStreaks(target, configDir, log2) {
|
|
5158
|
+
const path = getStuckStreakStoreFile(configDir);
|
|
5159
|
+
if (!existsSync8(path)) return;
|
|
5160
|
+
let parsed;
|
|
5161
|
+
try {
|
|
5162
|
+
parsed = JSON.parse(readFileSync19(path, "utf-8"));
|
|
5163
|
+
} catch (err) {
|
|
5164
|
+
log2?.(
|
|
5165
|
+
`[stuck-streaks] discarding corrupt ${STORE_FILENAME} (${err.message}) \u2014 stuck-streak ages restart from zero and one spurious "recovered" close may follow`
|
|
5166
|
+
);
|
|
5167
|
+
return;
|
|
5168
|
+
}
|
|
5169
|
+
const maps = parseStuckStreakPayload(parsed);
|
|
5170
|
+
if (!maps) {
|
|
5171
|
+
log2?.(
|
|
5172
|
+
`[stuck-streaks] discarding unusable ${STORE_FILENAME} (bad shape or version, expected ${STUCK_STREAK_STORE_VERSION}) \u2014 stuck-streak ages restart from zero and one spurious "recovered" close may follow`
|
|
5173
|
+
);
|
|
5174
|
+
return;
|
|
5175
|
+
}
|
|
5176
|
+
for (const concern of STUCK_STREAK_CONCERNS) {
|
|
5177
|
+
for (const [agentId, streak] of maps[concern]) target[concern].set(agentId, streak);
|
|
5178
|
+
}
|
|
5179
|
+
}
|
|
5180
|
+
function saveStuckStreaks(source, configDir, log2) {
|
|
5181
|
+
const path = getStuckStreakStoreFile(configDir);
|
|
5182
|
+
try {
|
|
5183
|
+
atomicWriteFileSync(path, JSON.stringify(buildStuckStreakPayload(source), null, 2));
|
|
5184
|
+
return true;
|
|
5185
|
+
} catch (err) {
|
|
5186
|
+
log2?.(
|
|
5187
|
+
`[stuck-streaks] failed to persist ${STORE_FILENAME} (non-fatal): ${err.message}`
|
|
5188
|
+
);
|
|
5189
|
+
return false;
|
|
5190
|
+
}
|
|
5191
|
+
}
|
|
5192
|
+
function pruneStuckStreaksToAgents(maps, activeAgentIds) {
|
|
5193
|
+
const dropped = [];
|
|
5194
|
+
for (const concern of STUCK_STREAK_CONCERNS) {
|
|
5195
|
+
for (const agentId of [...maps[concern].keys()]) {
|
|
5196
|
+
if (activeAgentIds.has(agentId)) continue;
|
|
5197
|
+
maps[concern].delete(agentId);
|
|
5198
|
+
if (!dropped.includes(agentId)) dropped.push(agentId);
|
|
5199
|
+
}
|
|
5200
|
+
}
|
|
5201
|
+
return dropped;
|
|
5202
|
+
}
|
|
5203
|
+
|
|
5110
5204
|
// src/lib/channel-sweep.ts
|
|
5111
5205
|
import { execFileSync } from "child_process";
|
|
5112
5206
|
var CHANNEL_BASENAMES = [
|
|
@@ -5582,7 +5676,7 @@ function planGlobalSkillSync(globalSkills, prevIds, hashOf, knownHash, options)
|
|
|
5582
5676
|
}
|
|
5583
5677
|
|
|
5584
5678
|
// src/lib/manager/integration-skill-cache.ts
|
|
5585
|
-
import { join as
|
|
5679
|
+
import { join as join25 } from "path";
|
|
5586
5680
|
function integrationSkillHashKey(agentId, skillId) {
|
|
5587
5681
|
return `plugin-skill:${agentId}:${skillId}`;
|
|
5588
5682
|
}
|
|
@@ -5598,21 +5692,21 @@ function forgetIntegrationSkill(cache3, agentId, skillId) {
|
|
|
5598
5692
|
function removeIntegrationSkillFolder(opts) {
|
|
5599
5693
|
forgetIntegrationSkill(opts.cache, opts.agentId, opts.entry);
|
|
5600
5694
|
for (const dir of opts.dirs) {
|
|
5601
|
-
opts.removeDir(
|
|
5695
|
+
opts.removeDir(join25(dir, opts.entry));
|
|
5602
5696
|
}
|
|
5603
5697
|
}
|
|
5604
5698
|
|
|
5605
5699
|
// src/lib/manager/managed-skill-manifest.ts
|
|
5606
|
-
import { existsSync as
|
|
5607
|
-
import { dirname as dirname7, join as
|
|
5700
|
+
import { existsSync as existsSync9, mkdirSync as mkdirSync6, readFileSync as readFileSync20, writeFileSync as writeFileSync8 } from "fs";
|
|
5701
|
+
import { dirname as dirname7, join as join26 } from "path";
|
|
5608
5702
|
var MANIFEST_VERSION = 1;
|
|
5609
5703
|
function managedSkillManifestPath(agentRootDir) {
|
|
5610
|
-
return
|
|
5704
|
+
return join26(agentRootDir, "managed-skills.json");
|
|
5611
5705
|
}
|
|
5612
5706
|
function readManagedSkillManifest(path) {
|
|
5613
5707
|
try {
|
|
5614
|
-
if (!
|
|
5615
|
-
const parsed = JSON.parse(
|
|
5708
|
+
if (!existsSync9(path)) return /* @__PURE__ */ new Set();
|
|
5709
|
+
const parsed = JSON.parse(readFileSync20(path, "utf-8"));
|
|
5616
5710
|
const ids = Array.isArray(parsed?.globalSkillIds) ? parsed.globalSkillIds : [];
|
|
5617
5711
|
return new Set(ids.filter((id) => typeof id === "string" && id.length > 0));
|
|
5618
5712
|
} catch {
|
|
@@ -5738,8 +5832,8 @@ function resolveModelChain(refreshData) {
|
|
|
5738
5832
|
}
|
|
5739
5833
|
|
|
5740
5834
|
// src/lib/manager/claude-auth.ts
|
|
5741
|
-
import { existsSync as
|
|
5742
|
-
import { join as
|
|
5835
|
+
import { existsSync as existsSync10, rmSync as rmSync3 } from "fs";
|
|
5836
|
+
import { join as join27 } from "path";
|
|
5743
5837
|
import { homedir as homedir13 } from "os";
|
|
5744
5838
|
async function applyClaudeAuthToEnv(childEnv, label) {
|
|
5745
5839
|
const apiKey = getApiKey();
|
|
@@ -5752,10 +5846,10 @@ async function applyClaudeAuthToEnv(childEnv, label) {
|
|
|
5752
5846
|
throw new Error("claude_auth_mode=api_key but /host/exchange returned no decrypted key");
|
|
5753
5847
|
}
|
|
5754
5848
|
childEnv.ANTHROPIC_API_KEY = exchange.anthropicApiKey;
|
|
5755
|
-
const claudeDir =
|
|
5849
|
+
const claudeDir = join27(homedir13(), ".claude");
|
|
5756
5850
|
for (const filename of [".credentials.json", "credentials.json"]) {
|
|
5757
|
-
const p =
|
|
5758
|
-
if (
|
|
5851
|
+
const p = join27(claudeDir, filename);
|
|
5852
|
+
if (existsSync10(p)) {
|
|
5759
5853
|
try {
|
|
5760
5854
|
rmSync3(p, { force: true });
|
|
5761
5855
|
log(`[${label}] Removed ${p} (api_key mode \u2014 preventing OAuth fallback)`);
|
|
@@ -5836,8 +5930,8 @@ function heartbeatRuntimeAuthFields(probeVerdict) {
|
|
|
5836
5930
|
}
|
|
5837
5931
|
|
|
5838
5932
|
// src/lib/manager/kanban/parsers.ts
|
|
5839
|
-
import { existsSync as
|
|
5840
|
-
import { join as
|
|
5933
|
+
import { existsSync as existsSync11, readFileSync as readFileSync21 } from "fs";
|
|
5934
|
+
import { join as join28 } from "path";
|
|
5841
5935
|
var STANDUP_TEMPLATES = /* @__PURE__ */ new Set(["daily-standup", "end-of-day-summary"]);
|
|
5842
5936
|
var TASK_UPDATE_TEMPLATES = /* @__PURE__ */ new Set(["hourly-status", "task-update"]);
|
|
5843
5937
|
var PLAN_TEMPLATES = /* @__PURE__ */ new Set(["morning-plan"]);
|
|
@@ -5989,12 +6083,12 @@ function getBuiltInSkillContent(skillId) {
|
|
|
5989
6083
|
if (builtInSkillCache.has(skillId)) return builtInSkillCache.get(skillId);
|
|
5990
6084
|
try {
|
|
5991
6085
|
const candidates = [
|
|
5992
|
-
|
|
5993
|
-
|
|
6086
|
+
join28(process.cwd(), "skills", skillId, "SKILL.md"),
|
|
6087
|
+
join28(new URL(".", import.meta.url).pathname, "..", "..", "..", "..", "..", "..", "skills", skillId, "SKILL.md")
|
|
5994
6088
|
];
|
|
5995
6089
|
for (const candidate of candidates) {
|
|
5996
|
-
if (
|
|
5997
|
-
const content =
|
|
6090
|
+
if (existsSync11(candidate)) {
|
|
6091
|
+
const content = readFileSync21(candidate, "utf-8");
|
|
5998
6092
|
const files = [{ relativePath: "SKILL.md", content }];
|
|
5999
6093
|
builtInSkillCache.set(skillId, files);
|
|
6000
6094
|
return files;
|
|
@@ -6135,19 +6229,19 @@ function formatBoardForPrompt(items, template) {
|
|
|
6135
6229
|
}
|
|
6136
6230
|
|
|
6137
6231
|
// src/lib/manager/kanban/nudge-state-cache.ts
|
|
6138
|
-
import { existsSync as
|
|
6139
|
-
import { join as
|
|
6232
|
+
import { existsSync as existsSync12, readFileSync as readFileSync22, writeFileSync as writeFileSync9 } from "fs";
|
|
6233
|
+
import { join as join29 } from "path";
|
|
6140
6234
|
var CACHE_FILENAME2 = "kanban-nudge-state.json";
|
|
6141
6235
|
var KANBAN_NUDGE_STATE_VERSION = 1;
|
|
6142
6236
|
function getKanbanNudgeStateFile(configDir) {
|
|
6143
|
-
return
|
|
6237
|
+
return join29(configDir, CACHE_FILENAME2);
|
|
6144
6238
|
}
|
|
6145
6239
|
function loadKanbanNudgeState(target, configDir) {
|
|
6146
6240
|
const path = getKanbanNudgeStateFile(configDir);
|
|
6147
|
-
if (!
|
|
6241
|
+
if (!existsSync12(path)) return;
|
|
6148
6242
|
let parsed;
|
|
6149
6243
|
try {
|
|
6150
|
-
parsed = JSON.parse(
|
|
6244
|
+
parsed = JSON.parse(readFileSync22(path, "utf-8"));
|
|
6151
6245
|
} catch {
|
|
6152
6246
|
return;
|
|
6153
6247
|
}
|
|
@@ -6765,9 +6859,9 @@ function closeSessionRunForCode(codeName, outcome, reason) {
|
|
|
6765
6859
|
|
|
6766
6860
|
// src/lib/manager/scheduler/kanban-route.ts
|
|
6767
6861
|
import { createHash as createHash12 } from "crypto";
|
|
6768
|
-
import { writeFileSync as writeFileSync10, renameSync as renameSync5, mkdirSync as mkdirSync7, readFileSync as
|
|
6862
|
+
import { writeFileSync as writeFileSync10, renameSync as renameSync5, mkdirSync as mkdirSync7, readFileSync as readFileSync23, unlinkSync as unlinkSync3 } from "fs";
|
|
6769
6863
|
import { homedir as homedir14 } from "os";
|
|
6770
|
-
import { join as
|
|
6864
|
+
import { join as join30, dirname as dirname8 } from "path";
|
|
6771
6865
|
|
|
6772
6866
|
// src/lib/manager/scheduler/notify.ts
|
|
6773
6867
|
import { createHash as createHash11 } from "crypto";
|
|
@@ -7126,7 +7220,7 @@ function resolveScheduledSlackTarget(task) {
|
|
|
7126
7220
|
}
|
|
7127
7221
|
function stampScheduledTurnMarker(codeName, taskId, target) {
|
|
7128
7222
|
try {
|
|
7129
|
-
const file =
|
|
7223
|
+
const file = join30(homedir14(), ".augmented", codeName, SCHEDULED_TURN_MARKER_FILENAME);
|
|
7130
7224
|
const marker = { ts: Date.now(), task_id: taskId, ...target ? { target } : {} };
|
|
7131
7225
|
const tmp = `${file}.tmp`;
|
|
7132
7226
|
writeFileSync10(tmp, JSON.stringify(marker), "utf8");
|
|
@@ -7136,9 +7230,9 @@ function stampScheduledTurnMarker(codeName, taskId, target) {
|
|
|
7136
7230
|
}
|
|
7137
7231
|
}
|
|
7138
7232
|
function clearScheduledTurnMarkerForTask(codeName, taskId) {
|
|
7139
|
-
const file =
|
|
7233
|
+
const file = join30(homedir14(), ".augmented", codeName, SCHEDULED_TURN_MARKER_FILENAME);
|
|
7140
7234
|
try {
|
|
7141
|
-
const raw = JSON.parse(
|
|
7235
|
+
const raw = JSON.parse(readFileSync23(file, "utf8"));
|
|
7142
7236
|
if (typeof raw?.task_id !== "string" || raw.task_id !== taskId) return;
|
|
7143
7237
|
unlinkSync3(file);
|
|
7144
7238
|
log(`[scheduled-kanban] scheduled-turn marker cleared for '${codeName}' (task ${taskId} complete)`);
|
|
@@ -7351,11 +7445,11 @@ async function processClaudeTaskResult(codeName, agentId, templateId, rawOutput,
|
|
|
7351
7445
|
// src/lib/manager/scheduler/execution.ts
|
|
7352
7446
|
import { createHash as createHash13 } from "crypto";
|
|
7353
7447
|
import { homedir as homedir15 } from "os";
|
|
7354
|
-
import { join as
|
|
7448
|
+
import { join as join32 } from "path";
|
|
7355
7449
|
|
|
7356
7450
|
// src/lib/agent-serving-probe.ts
|
|
7357
|
-
import { readFileSync as
|
|
7358
|
-
import { join as
|
|
7451
|
+
import { readFileSync as readFileSync24, readdirSync as readdirSync5, statSync as statSync5 } from "fs";
|
|
7452
|
+
import { join as join31 } from "path";
|
|
7359
7453
|
var RATE_LIMIT_WINDOW_MS = 6 * 60 * 60 * 1e3;
|
|
7360
7454
|
function probeRateLimit(args) {
|
|
7361
7455
|
const now = args.now ?? /* @__PURE__ */ new Date();
|
|
@@ -7371,7 +7465,7 @@ function probeRateLimit(args) {
|
|
|
7371
7465
|
let newest = UNKNOWN_RATE_LIMIT;
|
|
7372
7466
|
for (const name of entries) {
|
|
7373
7467
|
if (!name.endsWith(".jsonl")) continue;
|
|
7374
|
-
const path =
|
|
7468
|
+
const path = join31(dir, name);
|
|
7375
7469
|
try {
|
|
7376
7470
|
const st = statSync5(path);
|
|
7377
7471
|
if (!st.isFile() || st.mtimeMs < startMs) continue;
|
|
@@ -7380,7 +7474,7 @@ function probeRateLimit(args) {
|
|
|
7380
7474
|
}
|
|
7381
7475
|
let content;
|
|
7382
7476
|
try {
|
|
7383
|
-
content =
|
|
7477
|
+
content = readFileSync24(path, "utf-8");
|
|
7384
7478
|
} catch {
|
|
7385
7479
|
continue;
|
|
7386
7480
|
}
|
|
@@ -7442,7 +7536,7 @@ function shouldLogUsageCapDeferral(site, codeName, limitedUntil) {
|
|
|
7442
7536
|
|
|
7443
7537
|
// src/lib/manager/scheduler/execution.ts
|
|
7444
7538
|
function claudePidFilePath() {
|
|
7445
|
-
return
|
|
7539
|
+
return join32(homedir15(), ".augmented", "manager-claude-pids.json");
|
|
7446
7540
|
}
|
|
7447
7541
|
var inFlightClaudePids = /* @__PURE__ */ new Map();
|
|
7448
7542
|
function registerClaudeSpawn(record) {
|
|
@@ -7513,7 +7607,7 @@ async function syncAndCheckClaudeScheduler(agent, tasks, boardItems, refreshData
|
|
|
7513
7607
|
|
|
7514
7608
|
// src/lib/occupancy-gate.ts
|
|
7515
7609
|
import { closeSync as closeSync2, openSync as openSync2, readdirSync as readdirSync6, readSync as readSync2, statSync as statSync6 } from "fs";
|
|
7516
|
-
import { join as
|
|
7610
|
+
import { join as join33 } from "path";
|
|
7517
7611
|
function rostersMeasuredZero(mode, attested, runtimeRunning) {
|
|
7518
7612
|
return mode === "enforce" && attested && runtimeRunning;
|
|
7519
7613
|
}
|
|
@@ -7604,10 +7698,10 @@ function candidateTranscriptPaths(dir) {
|
|
|
7604
7698
|
let complete = true;
|
|
7605
7699
|
for (const name of top) {
|
|
7606
7700
|
if (name.endsWith(".jsonl")) {
|
|
7607
|
-
paths.push(
|
|
7701
|
+
paths.push(join33(dir, name));
|
|
7608
7702
|
continue;
|
|
7609
7703
|
}
|
|
7610
|
-
const subDir =
|
|
7704
|
+
const subDir = join33(dir, name, "subagents");
|
|
7611
7705
|
let subs;
|
|
7612
7706
|
try {
|
|
7613
7707
|
subs = readdirSync6(subDir);
|
|
@@ -7616,7 +7710,7 @@ function candidateTranscriptPaths(dir) {
|
|
|
7616
7710
|
continue;
|
|
7617
7711
|
}
|
|
7618
7712
|
for (const sub of subs) {
|
|
7619
|
-
if (sub.endsWith(".jsonl")) paths.push(
|
|
7713
|
+
if (sub.endsWith(".jsonl")) paths.push(join33(subDir, sub));
|
|
7620
7714
|
}
|
|
7621
7715
|
}
|
|
7622
7716
|
return { paths, complete };
|
|
@@ -7843,7 +7937,7 @@ function stopPaneOccupancySampler() {
|
|
|
7843
7937
|
|
|
7844
7938
|
// src/lib/pid-pressure-sampler.ts
|
|
7845
7939
|
import { execFileSync as execFileSync2 } from "child_process";
|
|
7846
|
-
import { existsSync as
|
|
7940
|
+
import { existsSync as existsSync13, readFileSync as readFileSync25 } from "fs";
|
|
7847
7941
|
var SAMPLE_INTERVAL_MS2 = 3e4;
|
|
7848
7942
|
function warnFraction() {
|
|
7849
7943
|
const raw = Number(process.env.AGT_PID_PRESSURE_WARN_FRACTION);
|
|
@@ -7856,7 +7950,7 @@ function configuredCeiling() {
|
|
|
7856
7950
|
}
|
|
7857
7951
|
function readTextReal(path) {
|
|
7858
7952
|
try {
|
|
7859
|
-
return
|
|
7953
|
+
return readFileSync25(path, "utf-8");
|
|
7860
7954
|
} catch {
|
|
7861
7955
|
return null;
|
|
7862
7956
|
}
|
|
@@ -7865,7 +7959,7 @@ var cgroupDirCache = /* @__PURE__ */ new Map();
|
|
|
7865
7959
|
var resolveRetryAfter = /* @__PURE__ */ new Map();
|
|
7866
7960
|
var RESOLVE_RETRY_BACKOFF_MS = 5 * 6e4;
|
|
7867
7961
|
function resolveCgroupDirReal(codeName, deps = {}) {
|
|
7868
|
-
const exists = deps.exists ??
|
|
7962
|
+
const exists = deps.exists ?? existsSync13;
|
|
7869
7963
|
const inspectId = deps.inspectId ?? inspectContainerId;
|
|
7870
7964
|
const now = deps.now ?? Date.now;
|
|
7871
7965
|
const cached = cgroupDirCache.get(codeName);
|
|
@@ -9164,9 +9258,9 @@ async function fireOpencodeScheduledTask(agent, task) {
|
|
|
9164
9258
|
|
|
9165
9259
|
// src/lib/opencode-telegram-ingest.ts
|
|
9166
9260
|
import { createHash as createHash16 } from "crypto";
|
|
9167
|
-
import { existsSync as
|
|
9261
|
+
import { existsSync as existsSync14, mkdirSync as mkdirSync8, readFileSync as readFileSync26, renameSync as renameSync6, unlinkSync as unlinkSync4, writeFileSync as writeFileSync11 } from "fs";
|
|
9168
9262
|
import { randomUUID } from "crypto";
|
|
9169
|
-
import { join as
|
|
9263
|
+
import { join as join34 } from "path";
|
|
9170
9264
|
|
|
9171
9265
|
// src/lib/telegram-ingest.ts
|
|
9172
9266
|
import https2 from "https";
|
|
@@ -9714,7 +9808,7 @@ function createFileOffsetStore(codeName, log2, currentBotId) {
|
|
|
9714
9808
|
let filePath;
|
|
9715
9809
|
try {
|
|
9716
9810
|
dir = getFramework("opencode").getAgentDir(codeName);
|
|
9717
|
-
filePath =
|
|
9811
|
+
filePath = join34(dir, "telegram-getupdates-offset-opencode.json");
|
|
9718
9812
|
} catch {
|
|
9719
9813
|
dir = null;
|
|
9720
9814
|
filePath = null;
|
|
@@ -9723,7 +9817,7 @@ function createFileOffsetStore(codeName, log2, currentBotId) {
|
|
|
9723
9817
|
load() {
|
|
9724
9818
|
if (!filePath) return 0;
|
|
9725
9819
|
try {
|
|
9726
|
-
const parsed = JSON.parse(
|
|
9820
|
+
const parsed = JSON.parse(readFileSync26(filePath, "utf-8"));
|
|
9727
9821
|
if (currentBotId != null && typeof parsed?.bot_id === "number" && parsed.bot_id !== currentBotId) {
|
|
9728
9822
|
log2(`[telegram-ingest:${codeName}] offset cursor belongs to a different bot; ignoring (bot swap)`);
|
|
9729
9823
|
return 0;
|
|
@@ -9756,7 +9850,7 @@ function createFileOffsetStore(codeName, log2, currentBotId) {
|
|
|
9756
9850
|
} catch (err) {
|
|
9757
9851
|
log2(`[telegram-ingest:${codeName}] offset persist failed: ${err instanceof Error ? err.message : String(err)}`);
|
|
9758
9852
|
try {
|
|
9759
|
-
if (
|
|
9853
|
+
if (existsSync14(tmpPath)) unlinkSync4(tmpPath);
|
|
9760
9854
|
} catch {
|
|
9761
9855
|
}
|
|
9762
9856
|
}
|
|
@@ -9993,24 +10087,24 @@ function partitionActionableByPoison(actionable, states, config2) {
|
|
|
9993
10087
|
}
|
|
9994
10088
|
|
|
9995
10089
|
// src/lib/restart-flags.ts
|
|
9996
|
-
import { existsSync as
|
|
10090
|
+
import { existsSync as existsSync15, mkdirSync as mkdirSync9, readdirSync as readdirSync7, readFileSync as readFileSync27, renameSync as renameSync7, rmSync as rmSync4, writeFileSync as writeFileSync12 } from "fs";
|
|
9997
10091
|
import { homedir as homedir16 } from "os";
|
|
9998
|
-
import { join as
|
|
10092
|
+
import { join as join35 } from "path";
|
|
9999
10093
|
import { randomUUID as randomUUID2 } from "crypto";
|
|
10000
10094
|
function restartFlagsDir() {
|
|
10001
|
-
return
|
|
10095
|
+
return join35(homedir16(), ".augmented", "restart-flags");
|
|
10002
10096
|
}
|
|
10003
10097
|
function flagPath(codeName) {
|
|
10004
|
-
return
|
|
10098
|
+
return join35(restartFlagsDir(), `${codeName}.flag`);
|
|
10005
10099
|
}
|
|
10006
10100
|
function readRestartFlags() {
|
|
10007
10101
|
const dir = restartFlagsDir();
|
|
10008
|
-
if (!
|
|
10102
|
+
if (!existsSync15(dir)) return [];
|
|
10009
10103
|
const out = [];
|
|
10010
10104
|
for (const entry of readdirSync7(dir)) {
|
|
10011
10105
|
if (!entry.endsWith(".flag")) continue;
|
|
10012
10106
|
try {
|
|
10013
|
-
const raw =
|
|
10107
|
+
const raw = readFileSync27(join35(dir, entry), "utf8");
|
|
10014
10108
|
const parsed = JSON.parse(raw);
|
|
10015
10109
|
if (typeof parsed.codeName !== "string" || parsed.codeName.length === 0) {
|
|
10016
10110
|
parsed.codeName = entry.replace(/\.flag$/, "");
|
|
@@ -10028,7 +10122,7 @@ function readRestartFlags() {
|
|
|
10028
10122
|
}
|
|
10029
10123
|
function deleteRestartFlag(codeName) {
|
|
10030
10124
|
const path = flagPath(codeName);
|
|
10031
|
-
if (
|
|
10125
|
+
if (existsSync15(path)) {
|
|
10032
10126
|
rmSync4(path, { force: true });
|
|
10033
10127
|
}
|
|
10034
10128
|
}
|
|
@@ -10128,8 +10222,8 @@ async function sendError(flag, opts, text) {
|
|
|
10128
10222
|
}
|
|
10129
10223
|
|
|
10130
10224
|
// src/lib/restart-context.ts
|
|
10131
|
-
import { readdirSync as readdirSync8, readFileSync as
|
|
10132
|
-
import { dirname as dirname9, join as
|
|
10225
|
+
import { readdirSync as readdirSync8, readFileSync as readFileSync28, writeFileSync as writeFileSync13, mkdirSync as mkdirSync10, unlinkSync as unlinkSync5 } from "fs";
|
|
10226
|
+
import { dirname as dirname9, join as join36 } from "path";
|
|
10133
10227
|
var SLACK_PENDING_INBOUND_DIRNAME = "slack-pending-inbound";
|
|
10134
10228
|
var SLACK_RESTART_CONTEXT_DIRNAME = "slack-restart-context";
|
|
10135
10229
|
var MAX_TOPIC_CHARS = 140;
|
|
@@ -10141,10 +10235,10 @@ function augmentedAgentDir(codeName) {
|
|
|
10141
10235
|
return dirname9(getProjectDir(codeName));
|
|
10142
10236
|
}
|
|
10143
10237
|
function slackPendingInboundDir(codeName) {
|
|
10144
|
-
return
|
|
10238
|
+
return join36(augmentedAgentDir(codeName), SLACK_PENDING_INBOUND_DIRNAME);
|
|
10145
10239
|
}
|
|
10146
10240
|
function slackRestartContextDir(codeName) {
|
|
10147
|
-
return
|
|
10241
|
+
return join36(augmentedAgentDir(codeName), SLACK_RESTART_CONTEXT_DIRNAME);
|
|
10148
10242
|
}
|
|
10149
10243
|
function sanitizeTopic(raw) {
|
|
10150
10244
|
const cleaned = raw.replace(/\s+/g, " ").trim().replace(/[<>]/g, " ").replace(/\s+/g, " ").trim();
|
|
@@ -10186,7 +10280,7 @@ function safeReaddir(dir) {
|
|
|
10186
10280
|
}
|
|
10187
10281
|
function readStrandedMarker(path) {
|
|
10188
10282
|
try {
|
|
10189
|
-
const parsed = JSON.parse(
|
|
10283
|
+
const parsed = JSON.parse(readFileSync28(path, "utf-8"));
|
|
10190
10284
|
if (typeof parsed.channel === "string" && typeof parsed.thread_ts === "string") {
|
|
10191
10285
|
return { channel: parsed.channel, thread_ts: parsed.thread_ts };
|
|
10192
10286
|
}
|
|
@@ -10204,7 +10298,7 @@ function pruneHintsExcept(codeName, freshFilenames) {
|
|
|
10204
10298
|
if (!filename.endsWith(".json")) continue;
|
|
10205
10299
|
if (freshFilenames.has(filename)) continue;
|
|
10206
10300
|
try {
|
|
10207
|
-
unlinkSync5(
|
|
10301
|
+
unlinkSync5(join36(ctxDir, filename));
|
|
10208
10302
|
} catch {
|
|
10209
10303
|
}
|
|
10210
10304
|
}
|
|
@@ -10225,7 +10319,7 @@ function refreshSlackRestartContextHints(codeNames, opts = {}) {
|
|
|
10225
10319
|
}
|
|
10226
10320
|
const markers = [];
|
|
10227
10321
|
for (const filename of markerFilenames.slice(0, cap)) {
|
|
10228
|
-
const parsed = readStrandedMarker(
|
|
10322
|
+
const parsed = readStrandedMarker(join36(markerDir, filename));
|
|
10229
10323
|
if (parsed) markers.push({ filename, channel: parsed.channel, thread_ts: parsed.thread_ts });
|
|
10230
10324
|
}
|
|
10231
10325
|
if (markers.length === 0) {
|
|
@@ -10239,7 +10333,7 @@ function refreshSlackRestartContextHints(codeNames, opts = {}) {
|
|
|
10239
10333
|
const freshFilenames = /* @__PURE__ */ new Set();
|
|
10240
10334
|
for (const { filename, hint } of hints) {
|
|
10241
10335
|
try {
|
|
10242
|
-
writeHintFile(
|
|
10336
|
+
writeHintFile(join36(ctxDir, filename), ctxDir, hint);
|
|
10243
10337
|
freshFilenames.add(filename);
|
|
10244
10338
|
} catch (err) {
|
|
10245
10339
|
log2(`[restart-context] ${codeName}: hint write failed for ${filename}: ${err.message}`);
|
|
@@ -11617,7 +11711,7 @@ var pendingDayRolloverReset = /* @__PURE__ */ new Set();
|
|
|
11617
11711
|
var dayRolloverInboundHold = /* @__PURE__ */ new Map();
|
|
11618
11712
|
var INBOUND_HOLD_EPISODE_GAP_MS = 12e4;
|
|
11619
11713
|
async function channelInboundActivityAgeSecondsFor(codeName) {
|
|
11620
|
-
const { newestPendingInboundActivityMtimeMs } = await import("../responsiveness-probe-
|
|
11714
|
+
const { newestPendingInboundActivityMtimeMs } = await import("../responsiveness-probe-ZHE7S6G4.js");
|
|
11621
11715
|
const newest = newestPendingInboundActivityMtimeMs(dirname10(paneLogPath(codeName)));
|
|
11622
11716
|
if (newest === null) return null;
|
|
11623
11717
|
return Math.max(0, Math.floor((Date.now() - newest) / 1e3));
|
|
@@ -11867,7 +11961,7 @@ var runningChannelSecretHashes = /* @__PURE__ */ new Map();
|
|
|
11867
11961
|
var sessionLaunchManagedStructure = /* @__PURE__ */ new Map();
|
|
11868
11962
|
function projectMcpHash(_codeName, projectDir) {
|
|
11869
11963
|
try {
|
|
11870
|
-
const raw =
|
|
11964
|
+
const raw = readFileSync29(join37(projectDir, ".mcp.json"), "utf-8");
|
|
11871
11965
|
return createHash17("sha256").update(canonicalJson(JSON.parse(raw))).digest("hex");
|
|
11872
11966
|
} catch {
|
|
11873
11967
|
return null;
|
|
@@ -11875,7 +11969,7 @@ function projectMcpHash(_codeName, projectDir) {
|
|
|
11875
11969
|
}
|
|
11876
11970
|
function projectMcpKeys(_codeName, projectDir) {
|
|
11877
11971
|
try {
|
|
11878
|
-
const raw =
|
|
11972
|
+
const raw = readFileSync29(join37(projectDir, ".mcp.json"), "utf-8");
|
|
11879
11973
|
const parsed = JSON.parse(raw);
|
|
11880
11974
|
const servers = parsed.mcpServers;
|
|
11881
11975
|
if (!servers || typeof servers !== "object") return /* @__PURE__ */ new Set();
|
|
@@ -11893,7 +11987,7 @@ function seedSessionLaunchBaselines(codeName, projectDir) {
|
|
|
11893
11987
|
else runningMcpServerKeys.delete(codeName);
|
|
11894
11988
|
let launchStructure = null;
|
|
11895
11989
|
try {
|
|
11896
|
-
const raw =
|
|
11990
|
+
const raw = readFileSync29(join37(projectDir, ".mcp.json"), "utf-8");
|
|
11897
11991
|
launchStructure = managedMcpStructureHashFromFile(
|
|
11898
11992
|
JSON.parse(raw),
|
|
11899
11993
|
isManagedMcpServerKey
|
|
@@ -12019,7 +12113,7 @@ async function runAgentSessionToolBindProbes(agent, integrations, projectDir, op
|
|
|
12019
12113
|
if (result && result.rebindCandidates.length > 0 && hostFlagStore().getBoolean("session-tool-rebind")) {
|
|
12020
12114
|
let mcpJsonForRebind = null;
|
|
12021
12115
|
try {
|
|
12022
|
-
mcpJsonForRebind = JSON.parse(
|
|
12116
|
+
mcpJsonForRebind = JSON.parse(readFileSync29(join37(projectDir, ".mcp.json"), "utf-8"));
|
|
12023
12117
|
} catch {
|
|
12024
12118
|
mcpJsonForRebind = null;
|
|
12025
12119
|
}
|
|
@@ -12167,7 +12261,7 @@ function shouldInjectChannelSecrets(agentId) {
|
|
|
12167
12261
|
function projectChannelSecretHash(projectDir) {
|
|
12168
12262
|
try {
|
|
12169
12263
|
const entries = parseEnvIntegrations(
|
|
12170
|
-
|
|
12264
|
+
readFileSync29(join37(projectDir, ".env.integrations"), "utf-8")
|
|
12171
12265
|
);
|
|
12172
12266
|
return channelSecretValueHash(entries, CHANNEL_SECRET_ENV_KEYS);
|
|
12173
12267
|
} catch {
|
|
@@ -12265,7 +12359,7 @@ var agentRestartTimezoneInputs = /* @__PURE__ */ new Map();
|
|
|
12265
12359
|
var lastVersionCheckAt = 0;
|
|
12266
12360
|
var VERSION_CHECK_INTERVAL_MS = 5 * 60 * 1e3;
|
|
12267
12361
|
var lastResponsivenessProbeAt = 0;
|
|
12268
|
-
var agtCliVersion = true ? "0.28.
|
|
12362
|
+
var agtCliVersion = true ? "0.28.677" : "dev";
|
|
12269
12363
|
function resolveBrewPath(execFileSync3) {
|
|
12270
12364
|
try {
|
|
12271
12365
|
const out = execFileSync3("which", ["brew"], { timeout: 5e3 }).toString().trim();
|
|
@@ -12278,7 +12372,7 @@ function resolveBrewPath(execFileSync3) {
|
|
|
12278
12372
|
"/usr/local/bin/brew"
|
|
12279
12373
|
];
|
|
12280
12374
|
for (const path of fallbacks) {
|
|
12281
|
-
if (
|
|
12375
|
+
if (existsSync16(path)) return path;
|
|
12282
12376
|
}
|
|
12283
12377
|
return null;
|
|
12284
12378
|
}
|
|
@@ -12288,7 +12382,7 @@ function claudeBinaryInstalled(execFileSync3) {
|
|
|
12288
12382
|
"/opt/homebrew/bin/claude",
|
|
12289
12383
|
"/usr/local/bin/claude"
|
|
12290
12384
|
];
|
|
12291
|
-
if (canonical.some((path) =>
|
|
12385
|
+
if (canonical.some((path) => existsSync16(path))) return true;
|
|
12292
12386
|
try {
|
|
12293
12387
|
execFileSync3("which", ["claude"], { timeout: 5e3 });
|
|
12294
12388
|
return true;
|
|
@@ -12598,8 +12692,8 @@ var MANAGED_SETTINGS_KEYS = ["channelsEnabled", "enableAllProjectMcpServers"];
|
|
|
12598
12692
|
function ensureClaudeManagedSettings(path = claudeManagedSettingsPath()) {
|
|
12599
12693
|
try {
|
|
12600
12694
|
let settings = {};
|
|
12601
|
-
if (
|
|
12602
|
-
const raw =
|
|
12695
|
+
if (existsSync16(path)) {
|
|
12696
|
+
const raw = readFileSync29(path, "utf-8").trim();
|
|
12603
12697
|
if (raw) {
|
|
12604
12698
|
let parsed;
|
|
12605
12699
|
try {
|
|
@@ -12655,7 +12749,7 @@ async function ensureOpencodeBinary() {
|
|
|
12655
12749
|
try {
|
|
12656
12750
|
const prefix = execFileSync3("npm", ["prefix", "-g"], { encoding: "utf-8", timeout: 1e4 }).trim();
|
|
12657
12751
|
if (prefix) {
|
|
12658
|
-
const npmBin =
|
|
12752
|
+
const npmBin = join37(prefix, "bin");
|
|
12659
12753
|
const current = (process.env.PATH ?? "").split(pathDelimiter);
|
|
12660
12754
|
if (!current.includes(npmBin)) {
|
|
12661
12755
|
process.env.PATH = [npmBin, ...current.filter(Boolean)].join(pathDelimiter);
|
|
@@ -12716,7 +12810,7 @@ async function ensureFrameworkBinary(frameworkId) {
|
|
|
12716
12810
|
if (!process.env.PATH?.split(":").includes(brewBinDir)) {
|
|
12717
12811
|
process.env.PATH = `${brewBinDir}:${process.env.PATH ?? ""}`;
|
|
12718
12812
|
}
|
|
12719
|
-
if (
|
|
12813
|
+
if (existsSync16("/home/linuxbrew/.linuxbrew/bin/claude")) {
|
|
12720
12814
|
log("Claude Code installed successfully");
|
|
12721
12815
|
} else {
|
|
12722
12816
|
log("Claude Code install completed but binary not found at expected path \u2014 check brew logs");
|
|
@@ -12772,7 +12866,7 @@ ${r.stderr}`;
|
|
|
12772
12866
|
}
|
|
12773
12867
|
var UPDATE_CHECK_INTERVAL_MS = 5 * 60 * 1e3;
|
|
12774
12868
|
function selfUpdateAppliedMarkerPath() {
|
|
12775
|
-
return
|
|
12869
|
+
return join37(homedir17(), ".augmented", ".last-self-update-applied");
|
|
12776
12870
|
}
|
|
12777
12871
|
var selfUpdateUpToDateLogged = false;
|
|
12778
12872
|
var selfUpdatePinnedLogged = false;
|
|
@@ -12823,7 +12917,7 @@ async function checkAndUpdateCli(opts) {
|
|
|
12823
12917
|
const isNpmGlobal = !isBrewFormula && resolvedPath.includes("node_modules");
|
|
12824
12918
|
if (!isBrewFormula && !isNpmGlobal) return "noop";
|
|
12825
12919
|
const { readFileSync: readF, writeFileSync: writeF } = await import("fs");
|
|
12826
|
-
const markerPath =
|
|
12920
|
+
const markerPath = join37(homedir17(), ".augmented", ".last-update-check");
|
|
12827
12921
|
if (!force) {
|
|
12828
12922
|
try {
|
|
12829
12923
|
const lastCheck = parseInt(readF(markerPath, "utf-8").trim(), 10);
|
|
@@ -13276,13 +13370,13 @@ async function checkClaudeAuth() {
|
|
|
13276
13370
|
}
|
|
13277
13371
|
var evalEmptyMcpConfigPath = null;
|
|
13278
13372
|
function ensureEvalEmptyMcpConfig() {
|
|
13279
|
-
if (evalEmptyMcpConfigPath &&
|
|
13280
|
-
const dir =
|
|
13373
|
+
if (evalEmptyMcpConfigPath && existsSync16(evalEmptyMcpConfigPath)) return evalEmptyMcpConfigPath;
|
|
13374
|
+
const dir = join37(homedir17(), ".augmented");
|
|
13281
13375
|
try {
|
|
13282
13376
|
mkdirSync11(dir, { recursive: true });
|
|
13283
13377
|
} catch {
|
|
13284
13378
|
}
|
|
13285
|
-
const p =
|
|
13379
|
+
const p = join37(dir, ".eval-empty-mcp.json");
|
|
13286
13380
|
writeFileSync14(p, JSON.stringify({ mcpServers: {} }));
|
|
13287
13381
|
evalEmptyMcpConfigPath = p;
|
|
13288
13382
|
return p;
|
|
@@ -13377,10 +13471,10 @@ function resolveConversationEvalBackend() {
|
|
|
13377
13471
|
return conversationEvalBackend;
|
|
13378
13472
|
}
|
|
13379
13473
|
function getStateFile() {
|
|
13380
|
-
return
|
|
13474
|
+
return join37(config?.configDir ?? join37(process.env["HOME"] ?? "/tmp", ".augmented"), "manager-state.json");
|
|
13381
13475
|
}
|
|
13382
13476
|
function channelHashCacheDir() {
|
|
13383
|
-
return config?.configDir ??
|
|
13477
|
+
return config?.configDir ?? join37(process.env["HOME"] ?? "/tmp", ".augmented");
|
|
13384
13478
|
}
|
|
13385
13479
|
function loadChannelHashCache2() {
|
|
13386
13480
|
loadChannelHashCache(agentState.knownChannelConfigHashes, channelHashCacheDir());
|
|
@@ -13468,6 +13562,81 @@ function saveDeliveryBaseline() {
|
|
|
13468
13562
|
function flushDeliveryBaselineIfDirty() {
|
|
13469
13563
|
if (deliveryBaselineDirty) saveDeliveryBaseline();
|
|
13470
13564
|
}
|
|
13565
|
+
var stuckStreakSidecarDirty = false;
|
|
13566
|
+
var lastStuckStreakSignature = "";
|
|
13567
|
+
function snapshotStuckStreaks() {
|
|
13568
|
+
const maps = createStuckStreakMaps();
|
|
13569
|
+
for (const [agentId, s] of channelSyncFailures) {
|
|
13570
|
+
maps.channelSync.set(agentId, {
|
|
13571
|
+
attempts: s.attempts,
|
|
13572
|
+
since: s.since,
|
|
13573
|
+
nextAttemptAt: s.nextAttemptAt,
|
|
13574
|
+
loggedAtAttempt: s.loggedAtAttempt,
|
|
13575
|
+
detail: s.lastReason
|
|
13576
|
+
});
|
|
13577
|
+
}
|
|
13578
|
+
for (const [agentId, s] of realtimeRebindFailures) {
|
|
13579
|
+
maps.realtimeRebind.set(agentId, {
|
|
13580
|
+
attempts: s.attempts,
|
|
13581
|
+
since: s.since,
|
|
13582
|
+
nextAttemptAt: s.nextAttemptAt,
|
|
13583
|
+
loggedAtAttempt: s.loggedAtAttempt,
|
|
13584
|
+
detail: s.lastStatus
|
|
13585
|
+
});
|
|
13586
|
+
}
|
|
13587
|
+
return maps;
|
|
13588
|
+
}
|
|
13589
|
+
function flushStuckStreaksIfChanged() {
|
|
13590
|
+
const maps = snapshotStuckStreaks();
|
|
13591
|
+
const signature = JSON.stringify([
|
|
13592
|
+
[...maps.channelSync].map(([id, s]) => [id, s.since, s.attempts, s.detail]),
|
|
13593
|
+
[...maps.realtimeRebind].map(([id, s]) => [id, s.since, s.attempts, s.detail])
|
|
13594
|
+
]);
|
|
13595
|
+
if (signature === lastStuckStreakSignature && !stuckStreakSidecarDirty) return;
|
|
13596
|
+
const wrote = saveStuckStreaks(maps, channelHashCacheDir(), log);
|
|
13597
|
+
stuckStreakSidecarDirty = !wrote;
|
|
13598
|
+
if (wrote) lastStuckStreakSignature = signature;
|
|
13599
|
+
}
|
|
13600
|
+
function loadStuckStreaks2() {
|
|
13601
|
+
const maps = createStuckStreakMaps();
|
|
13602
|
+
loadStuckStreaks(maps, channelHashCacheDir(), log);
|
|
13603
|
+
for (const [agentId, s] of maps.channelSync) {
|
|
13604
|
+
channelSyncFailures.set(agentId, {
|
|
13605
|
+
attempts: s.attempts,
|
|
13606
|
+
since: s.since,
|
|
13607
|
+
lastReason: s.detail,
|
|
13608
|
+
loggedAtAttempt: s.loggedAtAttempt,
|
|
13609
|
+
nextAttemptAt: s.nextAttemptAt
|
|
13610
|
+
});
|
|
13611
|
+
}
|
|
13612
|
+
for (const [agentId, s] of maps.realtimeRebind) {
|
|
13613
|
+
realtimeRebindFailures.set(agentId, {
|
|
13614
|
+
attempts: s.attempts,
|
|
13615
|
+
since: s.since,
|
|
13616
|
+
lastStatus: s.detail,
|
|
13617
|
+
loggedAtAttempt: s.loggedAtAttempt,
|
|
13618
|
+
nextAttemptAt: s.nextAttemptAt
|
|
13619
|
+
});
|
|
13620
|
+
}
|
|
13621
|
+
const restored = channelSyncFailures.size + realtimeRebindFailures.size;
|
|
13622
|
+
if (restored > 0) {
|
|
13623
|
+
log(
|
|
13624
|
+
`[stuck-streaks] restored ${channelSyncFailures.size} channel-sync and ${realtimeRebindFailures.size} rebind streak(s) across the manager restart \u2014 their ages continue rather than restarting (ENG-9346)`
|
|
13625
|
+
);
|
|
13626
|
+
}
|
|
13627
|
+
}
|
|
13628
|
+
function pruneStuckStreaksToActiveAgents(activeAgentIds) {
|
|
13629
|
+
if (activeAgentIds.length === 0) return;
|
|
13630
|
+
const dropped = pruneStuckStreaksToAgents(snapshotStuckStreaks(), new Set(activeAgentIds));
|
|
13631
|
+
if (dropped.length === 0) return;
|
|
13632
|
+
for (const agentId of dropped) {
|
|
13633
|
+
channelSyncFailures.delete(agentId);
|
|
13634
|
+
realtimeRebindFailures.delete(agentId);
|
|
13635
|
+
}
|
|
13636
|
+
log(
|
|
13637
|
+
`[stuck-streaks] dropped ${dropped.length} persisted streak(s) for agent(s) no longer on this host (ENG-9346)`
|
|
13638
|
+
);
|
|
13639
|
+
}
|
|
13471
13640
|
function persistDeliveryBaselineEntry(concern, agentId, hash) {
|
|
13472
13641
|
if (hash === void 0) return;
|
|
13473
13642
|
if (persistedDeliveryBaseline[concern].get(agentId) === hash && !deliveryBaselineDirty) return;
|
|
@@ -13488,7 +13657,7 @@ function removeDeliveryBaselineEntries(agentId) {
|
|
|
13488
13657
|
var _channelQuarantineStore = null;
|
|
13489
13658
|
function channelQuarantineStore() {
|
|
13490
13659
|
if (!_channelQuarantineStore) {
|
|
13491
|
-
const dir = config?.configDir ??
|
|
13660
|
+
const dir = config?.configDir ?? join37(process.env["HOME"] ?? "/tmp", ".augmented");
|
|
13492
13661
|
_channelQuarantineStore = new ChannelQuarantineStore(defaultQuarantinePath(dir));
|
|
13493
13662
|
}
|
|
13494
13663
|
return _channelQuarantineStore;
|
|
@@ -13505,7 +13674,7 @@ function claudeMdSizeFor(codeName) {
|
|
|
13505
13674
|
var _hostFlagStore = null;
|
|
13506
13675
|
function hostFlagStore() {
|
|
13507
13676
|
if (!_hostFlagStore) {
|
|
13508
|
-
const dir = config?.configDir ??
|
|
13677
|
+
const dir = config?.configDir ?? join37(process.env["HOME"] ?? "/tmp", ".augmented");
|
|
13509
13678
|
_hostFlagStore = new HostFlagStore({ cachePath: defaultFlagsCachePath(dir), log });
|
|
13510
13679
|
}
|
|
13511
13680
|
return _hostFlagStore;
|
|
@@ -13579,12 +13748,12 @@ function parseSkillFrontmatter(content) {
|
|
|
13579
13748
|
}
|
|
13580
13749
|
async function refreshSkillsIndexInClaudeMd(configDir, codeName, log2) {
|
|
13581
13750
|
const { readdirSync: readdirSync10, readFileSync: rfs, existsSync: ex, writeFileSync: writeFileSync15 } = await import("fs");
|
|
13582
|
-
const skillsDir =
|
|
13583
|
-
const claudeMdPath =
|
|
13751
|
+
const skillsDir = join37(configDir, codeName, "project", ".claude", "skills");
|
|
13752
|
+
const claudeMdPath = join37(configDir, codeName, "project", "CLAUDE.md");
|
|
13584
13753
|
if (!ex(skillsDir) || !ex(claudeMdPath)) return;
|
|
13585
13754
|
const entries = [];
|
|
13586
13755
|
for (const dir of readdirSync10(skillsDir).sort()) {
|
|
13587
|
-
const skillFile =
|
|
13756
|
+
const skillFile = join37(skillsDir, dir, "SKILL.md");
|
|
13588
13757
|
if (!ex(skillFile)) continue;
|
|
13589
13758
|
try {
|
|
13590
13759
|
const { name, description } = parseSkillFrontmatter(rfs(skillFile, "utf-8"));
|
|
@@ -13651,7 +13820,7 @@ function flushRestartedAgentDiagnostics(hostId, codeNames) {
|
|
|
13651
13820
|
if (codeNames.length === 0) return;
|
|
13652
13821
|
void (async () => {
|
|
13653
13822
|
try {
|
|
13654
|
-
const { collectDiagnostics } = await import("../persistent-session-
|
|
13823
|
+
const { collectDiagnostics } = await import("../persistent-session-TMOTEVV6.js");
|
|
13655
13824
|
await api.post("/host/heartbeat", {
|
|
13656
13825
|
host_id: hostId,
|
|
13657
13826
|
agent_diagnostics: collectDiagnostics(codeNames, quarantineEntriesFor, claudeMdSizeFor, spawnOutcomeForDiagnostics, pidPressureFor)
|
|
@@ -13673,6 +13842,7 @@ async function pollCycleInner() {
|
|
|
13673
13842
|
if (!config) return;
|
|
13674
13843
|
if (restartAfterUpgrade) return;
|
|
13675
13844
|
flushDeliveryBaselineIfDirty();
|
|
13845
|
+
flushStuckStreaksIfChanged();
|
|
13676
13846
|
try {
|
|
13677
13847
|
await processRestartFlags({
|
|
13678
13848
|
log,
|
|
@@ -13767,7 +13937,7 @@ async function pollCycleInner() {
|
|
|
13767
13937
|
}
|
|
13768
13938
|
try {
|
|
13769
13939
|
const { detectHostSecurity } = await import("../host-security-6PDFG7F5.js");
|
|
13770
|
-
const { collectDiagnostics } = await import("../persistent-session-
|
|
13940
|
+
const { collectDiagnostics } = await import("../persistent-session-TMOTEVV6.js");
|
|
13771
13941
|
const diagCodeNames = [...agentState.persistentSessionAgents];
|
|
13772
13942
|
const agentDiagnostics = diagCodeNames.length > 0 ? collectDiagnostics(diagCodeNames, quarantineEntriesFor, claudeMdSizeFor, spawnOutcomeForDiagnostics, pidPressureFor) : void 0;
|
|
13773
13943
|
let tailscaleHostname;
|
|
@@ -13919,7 +14089,7 @@ async function pollCycleInner() {
|
|
|
13919
14089
|
collectPanelessActivityProbes,
|
|
13920
14090
|
getResponsivenessIntervalMs,
|
|
13921
14091
|
occupancyQualificationClassifications
|
|
13922
|
-
} = await import("../responsiveness-probe-
|
|
14092
|
+
} = await import("../responsiveness-probe-ZHE7S6G4.js");
|
|
13923
14093
|
const probeIntervalMs = getResponsivenessIntervalMs();
|
|
13924
14094
|
if (now - lastResponsivenessProbeAt > probeIntervalMs) {
|
|
13925
14095
|
const probeCodeNames = [...agentState.persistentSessionAgents];
|
|
@@ -14029,7 +14199,7 @@ async function pollCycleInner() {
|
|
|
14029
14199
|
collectResponsivenessProbes,
|
|
14030
14200
|
livePendingInboundOldestAgeSeconds,
|
|
14031
14201
|
parkPendingInbound
|
|
14032
|
-
} = await import("../responsiveness-probe-
|
|
14202
|
+
} = await import("../responsiveness-probe-ZHE7S6G4.js");
|
|
14033
14203
|
const { getProjectDir: wedgeProjectDir } = await import("../scheduler-engine-NDP36U7O.js");
|
|
14034
14204
|
const wedgeNow = /* @__PURE__ */ new Date();
|
|
14035
14205
|
const liveAgents = agentState.persistentSessionAgents;
|
|
@@ -14118,13 +14288,13 @@ async function pollCycleInner() {
|
|
|
14118
14288
|
);
|
|
14119
14289
|
if (hostFlagStore().getBoolean("wedge-transient-notice")) {
|
|
14120
14290
|
try {
|
|
14121
|
-
const paneTail =
|
|
14291
|
+
const paneTail = readFileSync29(paneLogPath(codeName), "utf8").slice(-65536);
|
|
14122
14292
|
const transient = detectTransientApiErrorInLog(paneTail);
|
|
14123
14293
|
if (transient) {
|
|
14124
|
-
const wedgeHome =
|
|
14125
|
-
if (
|
|
14294
|
+
const wedgeHome = join37(homedir17(), ".augmented", codeName);
|
|
14295
|
+
if (existsSync16(wedgeHome)) {
|
|
14126
14296
|
atomicWriteFileSync(
|
|
14127
|
-
|
|
14297
|
+
join37(wedgeHome, "watchdog-give-up.json"),
|
|
14128
14298
|
JSON.stringify({
|
|
14129
14299
|
gave_up_at: wedgeNow.toISOString(),
|
|
14130
14300
|
reason: "transient_overload"
|
|
@@ -14185,7 +14355,7 @@ async function pollCycleInner() {
|
|
|
14185
14355
|
}
|
|
14186
14356
|
try {
|
|
14187
14357
|
const { scrapeMcpFailedBannerCount } = await import("../pane-mcp-banner-scraper-JA437JIB.js");
|
|
14188
|
-
const { probeSessionAuth } = await import("../session-auth-dead-
|
|
14358
|
+
const { probeSessionAuth } = await import("../session-auth-dead-JCKENEY5.js");
|
|
14189
14359
|
const observations = [];
|
|
14190
14360
|
const pendingCacheCommits = [];
|
|
14191
14361
|
const modelApiErrorReportingOn = hostFlagStore().getBoolean("model-api-error-reporting");
|
|
@@ -14421,7 +14591,7 @@ async function pollCycleInner() {
|
|
|
14421
14591
|
const adapter = resolveAgentFramework(prev.codeName);
|
|
14422
14592
|
stopAgentRuntime2(prev.codeName, "removed-from-host");
|
|
14423
14593
|
killAgentChannelProcesses(prev.codeName, { log });
|
|
14424
|
-
const agentDir =
|
|
14594
|
+
const agentDir = join37(adapter.getAgentDir(prev.codeName), "provision");
|
|
14425
14595
|
await cleanupAgentFiles(prev.codeName, agentDir);
|
|
14426
14596
|
clearAgentCaches(prev.agentId, prev.codeName);
|
|
14427
14597
|
}
|
|
@@ -14508,10 +14678,10 @@ async function pollCycleInner() {
|
|
|
14508
14678
|
// pending-inbound marker. Best-effort: a write failure is logged by
|
|
14509
14679
|
// the watchdog, never fails the poll cycle.
|
|
14510
14680
|
signalGiveUp: (codeName) => {
|
|
14511
|
-
const dir =
|
|
14512
|
-
if (!
|
|
14681
|
+
const dir = join37(homedir17(), ".augmented", codeName);
|
|
14682
|
+
if (!existsSync16(dir)) return;
|
|
14513
14683
|
atomicWriteFileSync(
|
|
14514
|
-
|
|
14684
|
+
join37(dir, "watchdog-give-up.json"),
|
|
14515
14685
|
JSON.stringify({ gave_up_at: (/* @__PURE__ */ new Date()).toISOString() })
|
|
14516
14686
|
);
|
|
14517
14687
|
},
|
|
@@ -14530,9 +14700,9 @@ async function pollCycleInner() {
|
|
|
14530
14700
|
// parser elsewhere can only reconstruct an hour (ENG-8901).
|
|
14531
14701
|
signalUsageLimit: (codeName, resetsHint) => {
|
|
14532
14702
|
const dir = getFramework("claude-code").getAgentDir(codeName);
|
|
14533
|
-
if (!
|
|
14703
|
+
if (!existsSync16(dir)) return;
|
|
14534
14704
|
atomicWriteFileSync(
|
|
14535
|
-
|
|
14705
|
+
join37(dir, "watchdog-give-up.json"),
|
|
14536
14706
|
JSON.stringify({
|
|
14537
14707
|
gave_up_at: (/* @__PURE__ */ new Date()).toISOString(),
|
|
14538
14708
|
reason: "usage_limit",
|
|
@@ -14794,7 +14964,7 @@ async function processAgent(agent, agentStates, managedToolkits) {
|
|
|
14794
14964
|
}
|
|
14795
14965
|
const now = (/* @__PURE__ */ new Date()).toISOString();
|
|
14796
14966
|
const adapter = resolveAgentFramework(agent.code_name);
|
|
14797
|
-
let agentDir =
|
|
14967
|
+
let agentDir = join37(adapter.getAgentDir(agent.code_name), "provision");
|
|
14798
14968
|
if (agent.status === "draft" || agent.status === "paused") {
|
|
14799
14969
|
forgetChannelSyncState(agent.agent_id);
|
|
14800
14970
|
if (previousKnownStatus !== agent.status) {
|
|
@@ -14835,7 +15005,7 @@ async function processAgent(agent, agentStates, managedToolkits) {
|
|
|
14835
15005
|
const residuals = {
|
|
14836
15006
|
gatewayRunning: false,
|
|
14837
15007
|
portAllocated: false,
|
|
14838
|
-
provisionDirExists:
|
|
15008
|
+
provisionDirExists: existsSync16(agentDir)
|
|
14839
15009
|
};
|
|
14840
15010
|
if (!hasRevokedResiduals(residuals)) {
|
|
14841
15011
|
agentStates.push({
|
|
@@ -14969,7 +15139,7 @@ async function processAgent(agent, agentStates, managedToolkits) {
|
|
|
14969
15139
|
const frameworkId = refreshData.agent.framework ?? DEFAULT_FRAMEWORK;
|
|
14970
15140
|
agentFrameworkCache.set(agent.code_name, frameworkId);
|
|
14971
15141
|
const frameworkAdapter = getFramework(frameworkId);
|
|
14972
|
-
agentDir =
|
|
15142
|
+
agentDir = join37(frameworkAdapter.getAgentDir(agent.code_name), "provision");
|
|
14973
15143
|
cacheAgentDeliveryMetadata(agent.code_name, refreshData);
|
|
14974
15144
|
agentRestartTimezoneInputs.set(agent.code_name, {
|
|
14975
15145
|
agentTimezone: typeof refreshData.agent.timezone === "string" ? refreshData.agent.timezone : null,
|
|
@@ -15027,7 +15197,7 @@ async function processAgent(agent, agentStates, managedToolkits) {
|
|
|
15027
15197
|
const changedFiles = [];
|
|
15028
15198
|
mkdirSync11(agentDir, { recursive: true });
|
|
15029
15199
|
for (const artifact of artifacts) {
|
|
15030
|
-
const filePath =
|
|
15200
|
+
const filePath = join37(agentDir, artifact.relativePath);
|
|
15031
15201
|
let existingHash;
|
|
15032
15202
|
let newHash;
|
|
15033
15203
|
let writeContent = artifact.content;
|
|
@@ -15046,8 +15216,8 @@ async function processAgent(agent, agentStates, managedToolkits) {
|
|
|
15046
15216
|
};
|
|
15047
15217
|
newHash = sha256(stripDynamicSections(artifact.content));
|
|
15048
15218
|
try {
|
|
15049
|
-
const projectClaudeMd =
|
|
15050
|
-
const existing =
|
|
15219
|
+
const projectClaudeMd = join37(config.configDir, agent.code_name, "project", "CLAUDE.md");
|
|
15220
|
+
const existing = readFileSync29(projectClaudeMd, "utf-8");
|
|
15051
15221
|
existingHash = sha256(stripDynamicSections(existing));
|
|
15052
15222
|
} catch {
|
|
15053
15223
|
existingHash = null;
|
|
@@ -15065,7 +15235,7 @@ async function processAgent(agent, agentStates, managedToolkits) {
|
|
|
15065
15235
|
const generatorKeys = Object.keys(generatorServers);
|
|
15066
15236
|
let existingRaw = "";
|
|
15067
15237
|
try {
|
|
15068
|
-
existingRaw =
|
|
15238
|
+
existingRaw = readFileSync29(filePath, "utf-8");
|
|
15069
15239
|
} catch {
|
|
15070
15240
|
}
|
|
15071
15241
|
const existingServers = parseMcp(existingRaw);
|
|
@@ -15081,7 +15251,7 @@ async function processAgent(agent, agentStates, managedToolkits) {
|
|
|
15081
15251
|
} else if (artifact.relativePath === "opencode.json") {
|
|
15082
15252
|
let existingRaw = null;
|
|
15083
15253
|
try {
|
|
15084
|
-
existingRaw =
|
|
15254
|
+
existingRaw = readFileSync29(filePath, "utf-8");
|
|
15085
15255
|
} catch {
|
|
15086
15256
|
}
|
|
15087
15257
|
const mergeResult = mergeOpencodeConfigArtifact(artifact.content, existingRaw);
|
|
@@ -15097,12 +15267,12 @@ async function processAgent(agent, agentStates, managedToolkits) {
|
|
|
15097
15267
|
}
|
|
15098
15268
|
}
|
|
15099
15269
|
if (changedFiles.length > 0) {
|
|
15100
|
-
const isFirst = !
|
|
15270
|
+
const isFirst = !existsSync16(join37(agentDir, "CHARTER.md"));
|
|
15101
15271
|
const verb = isFirst ? "Provisioning" : "Updating";
|
|
15102
15272
|
const fileNames = changedFiles.map((f) => f.relativePath).join(", ");
|
|
15103
15273
|
log(`${verb} '${agent.code_name}': ${fileNames}`);
|
|
15104
15274
|
for (const file of changedFiles) {
|
|
15105
|
-
const filePath =
|
|
15275
|
+
const filePath = join37(agentDir, file.relativePath);
|
|
15106
15276
|
mkdirSync11(dirname10(filePath), { recursive: true });
|
|
15107
15277
|
if (file.relativePath === ".mcp.json") {
|
|
15108
15278
|
safeWriteJsonAtomic(filePath, file.content, { mode: 384 });
|
|
@@ -15111,12 +15281,12 @@ async function processAgent(agent, agentStates, managedToolkits) {
|
|
|
15111
15281
|
}
|
|
15112
15282
|
}
|
|
15113
15283
|
try {
|
|
15114
|
-
const provSkillsDir =
|
|
15115
|
-
if (
|
|
15284
|
+
const provSkillsDir = join37(agentDir, ".claude", "skills");
|
|
15285
|
+
if (existsSync16(provSkillsDir)) {
|
|
15116
15286
|
for (const folder of readdirSync9(provSkillsDir)) {
|
|
15117
15287
|
if (folder.startsWith("knowledge-")) {
|
|
15118
15288
|
try {
|
|
15119
|
-
rmSync5(
|
|
15289
|
+
rmSync5(join37(provSkillsDir, folder), { recursive: true });
|
|
15120
15290
|
} catch {
|
|
15121
15291
|
}
|
|
15122
15292
|
}
|
|
@@ -15129,7 +15299,7 @@ async function processAgent(agent, agentStates, managedToolkits) {
|
|
|
15129
15299
|
const trackedFiles2 = frameworkAdapter.driftTrackedFiles();
|
|
15130
15300
|
const hashes = /* @__PURE__ */ new Map();
|
|
15131
15301
|
for (const file of trackedFiles2) {
|
|
15132
|
-
const h = hashFile(
|
|
15302
|
+
const h = hashFile(join37(agentDir, file));
|
|
15133
15303
|
if (h) hashes.set(file, h);
|
|
15134
15304
|
}
|
|
15135
15305
|
agentState.writtenHashes.set(agent.agent_id, hashes);
|
|
@@ -15147,14 +15317,14 @@ async function processAgent(agent, agentStates, managedToolkits) {
|
|
|
15147
15317
|
}
|
|
15148
15318
|
if (Array.isArray(refreshData.workflows)) {
|
|
15149
15319
|
try {
|
|
15150
|
-
const provWorkflowsDir =
|
|
15151
|
-
if (
|
|
15320
|
+
const provWorkflowsDir = join37(agentDir, ".claude", "workflows");
|
|
15321
|
+
if (existsSync16(provWorkflowsDir)) {
|
|
15152
15322
|
const expected = new Set(refreshData.workflows.map((w) => `${w.name}.js`));
|
|
15153
15323
|
for (const file of readdirSync9(provWorkflowsDir)) {
|
|
15154
15324
|
if (!file.endsWith(".js")) continue;
|
|
15155
15325
|
if (expected.has(file)) continue;
|
|
15156
15326
|
try {
|
|
15157
|
-
rmSync5(
|
|
15327
|
+
rmSync5(join37(provWorkflowsDir, file));
|
|
15158
15328
|
} catch {
|
|
15159
15329
|
}
|
|
15160
15330
|
}
|
|
@@ -15233,10 +15403,10 @@ async function processAgent(agent, agentStates, managedToolkits) {
|
|
|
15233
15403
|
}
|
|
15234
15404
|
let lastDriftCheckAt = now;
|
|
15235
15405
|
const written = agentState.writtenHashes.get(agent.agent_id);
|
|
15236
|
-
if (written &&
|
|
15406
|
+
if (written && existsSync16(agentDir)) {
|
|
15237
15407
|
const driftedFiles = [];
|
|
15238
15408
|
for (const [file, expectedHash] of written) {
|
|
15239
|
-
const localHash = hashFile(
|
|
15409
|
+
const localHash = hashFile(join37(agentDir, file));
|
|
15240
15410
|
if (localHash && localHash !== expectedHash) {
|
|
15241
15411
|
driftedFiles.push(file);
|
|
15242
15412
|
}
|
|
@@ -15247,7 +15417,7 @@ async function processAgent(agent, agentStates, managedToolkits) {
|
|
|
15247
15417
|
try {
|
|
15248
15418
|
const localHashes = {};
|
|
15249
15419
|
for (const file of driftedFiles) {
|
|
15250
|
-
localHashes[file] = hashFile(
|
|
15420
|
+
localHashes[file] = hashFile(join37(agentDir, file));
|
|
15251
15421
|
}
|
|
15252
15422
|
await api.post("/host/drift", {
|
|
15253
15423
|
agent_id: agent.agent_id,
|
|
@@ -15492,7 +15662,7 @@ async function processAgent(agent, agentStates, managedToolkits) {
|
|
|
15492
15662
|
const addedChannels = [...restartDecision.added];
|
|
15493
15663
|
const writeDmNoticeMarkers = isChannelAddRestart ? () => {
|
|
15494
15664
|
try {
|
|
15495
|
-
const agentAugmentedDir =
|
|
15665
|
+
const agentAugmentedDir = join37(homedir17(), ".augmented", agent.code_name);
|
|
15496
15666
|
mkdirSync11(agentAugmentedDir, { recursive: true });
|
|
15497
15667
|
const markerJson = JSON.stringify({
|
|
15498
15668
|
version: 1,
|
|
@@ -15500,7 +15670,7 @@ async function processAgent(agent, agentStates, managedToolkits) {
|
|
|
15500
15670
|
added: addedChannels
|
|
15501
15671
|
});
|
|
15502
15672
|
for (const file of ["slack-channel-add-restart.json", "telegram-channel-add-restart.json"]) {
|
|
15503
|
-
atomicWriteFileSync(
|
|
15673
|
+
atomicWriteFileSync(join37(agentAugmentedDir, file), markerJson);
|
|
15504
15674
|
}
|
|
15505
15675
|
} catch (err) {
|
|
15506
15676
|
log(`[hot-reload] channel-add DM-notice marker write failed for '${agent.code_name}' (non-fatal): ${err.message}`);
|
|
@@ -15689,24 +15859,24 @@ async function processAgent(agent, agentStates, managedToolkits) {
|
|
|
15689
15859
|
if (agentSessionMode === "persistent" && (agentFrameworkCache.get(agent.code_name) ?? DEFAULT_FRAMEWORK) === "claude-code") {
|
|
15690
15860
|
try {
|
|
15691
15861
|
const agentProvisionDir = agentDir;
|
|
15692
|
-
const projectDir =
|
|
15862
|
+
const projectDir = join37(homedir17(), ".augmented", agent.code_name, "project");
|
|
15693
15863
|
mkdirSync11(agentProvisionDir, { recursive: true });
|
|
15694
15864
|
mkdirSync11(projectDir, { recursive: true });
|
|
15695
|
-
const provisionMcpPath =
|
|
15696
|
-
const projectMcpPath =
|
|
15865
|
+
const provisionMcpPath = join37(agentProvisionDir, ".mcp.json");
|
|
15866
|
+
const projectMcpPath = join37(projectDir, ".mcp.json");
|
|
15697
15867
|
let mcpConfig = { mcpServers: {} };
|
|
15698
15868
|
try {
|
|
15699
|
-
mcpConfig = JSON.parse(
|
|
15869
|
+
mcpConfig = JSON.parse(readFileSync29(provisionMcpPath, "utf-8"));
|
|
15700
15870
|
if (!mcpConfig.mcpServers) mcpConfig.mcpServers = {};
|
|
15701
15871
|
} catch {
|
|
15702
15872
|
}
|
|
15703
|
-
const localDirectChatChannel =
|
|
15873
|
+
const localDirectChatChannel = join37(homedir17(), ".augmented", "_mcp", "direct-chat-channel.js");
|
|
15704
15874
|
const directChatTeamSettings = refreshData.team?.settings;
|
|
15705
15875
|
const directChatTz = (() => {
|
|
15706
15876
|
const tz = directChatTeamSettings?.["timezone"];
|
|
15707
15877
|
return typeof tz === "string" && tz.trim() !== "" ? tz.trim() : void 0;
|
|
15708
15878
|
})();
|
|
15709
|
-
if (
|
|
15879
|
+
if (existsSync16(localDirectChatChannel)) {
|
|
15710
15880
|
const directChatEnv = {
|
|
15711
15881
|
AGT_HOST: requireHost(),
|
|
15712
15882
|
// ENG-5901 Track D: templated — the manager exports the real
|
|
@@ -15726,7 +15896,7 @@ async function processAgent(agent, agentStates, managedToolkits) {
|
|
|
15726
15896
|
// ~/.augmented/<codeName>/.current-turn-initiator.json. Note getAgentDir
|
|
15727
15897
|
// returns the agent root (NOT the /provision subdir `agentDir` points at),
|
|
15728
15898
|
// so it byte-matches the broker readers' path.
|
|
15729
|
-
AGT_TURN_INITIATOR_FILE:
|
|
15899
|
+
AGT_TURN_INITIATOR_FILE: join37(
|
|
15730
15900
|
frameworkAdapter.getAgentDir(agent.code_name),
|
|
15731
15901
|
".current-turn-initiator.json"
|
|
15732
15902
|
)
|
|
@@ -15746,8 +15916,8 @@ async function processAgent(agent, agentStates, managedToolkits) {
|
|
|
15746
15916
|
log(`Channel credentials written for '${agent.code_name}/direct-chat'`);
|
|
15747
15917
|
}
|
|
15748
15918
|
}
|
|
15749
|
-
const staleChannelsPath =
|
|
15750
|
-
if (
|
|
15919
|
+
const staleChannelsPath = join37(projectDir, ".mcp-channels.json");
|
|
15920
|
+
if (existsSync16(staleChannelsPath)) {
|
|
15751
15921
|
try {
|
|
15752
15922
|
rmSync5(staleChannelsPath, { force: true });
|
|
15753
15923
|
} catch {
|
|
@@ -15836,7 +16006,7 @@ async function processAgent(agent, agentStates, managedToolkits) {
|
|
|
15836
16006
|
}
|
|
15837
16007
|
if (hostFlagStore().getBoolean("connectivity-probe")) {
|
|
15838
16008
|
try {
|
|
15839
|
-
const probeProjectDir =
|
|
16009
|
+
const probeProjectDir = join37(homedir17(), ".augmented", agent.code_name, "project");
|
|
15840
16010
|
let probeSet = integrations;
|
|
15841
16011
|
try {
|
|
15842
16012
|
const quarantined = await api.post("/host/agent-integrations/quarantined", { agent_id: agent.agent_id });
|
|
@@ -15882,7 +16052,7 @@ async function processAgent(agent, agentStates, managedToolkits) {
|
|
|
15882
16052
|
const forceDue = attemptsLeft > 0;
|
|
15883
16053
|
let probeRan = false;
|
|
15884
16054
|
try {
|
|
15885
|
-
const probeProjectDir =
|
|
16055
|
+
const probeProjectDir = join37(homedir17(), ".augmented", agent.code_name, "project");
|
|
15886
16056
|
probeRan = await runAgentSessionToolBindProbes(agent, integrations, probeProjectDir, { forceDue });
|
|
15887
16057
|
} catch (err) {
|
|
15888
16058
|
log(`Session-tool-bind probe failed for '${agent.code_name}': ${err.message}`);
|
|
@@ -15959,11 +16129,11 @@ async function processAgent(agent, agentStates, managedToolkits) {
|
|
|
15959
16129
|
const intHash = computeIntegrationsHash(integrations);
|
|
15960
16130
|
const prevIntHash = agentState.knownIntegrationHashes.get(agent.agent_id);
|
|
15961
16131
|
if (intHash !== prevIntHash) {
|
|
15962
|
-
const projectDir =
|
|
15963
|
-
const envIntPath =
|
|
16132
|
+
const projectDir = join37(homedir17(), ".augmented", agent.code_name, "project");
|
|
16133
|
+
const envIntPath = join37(projectDir, ".env.integrations");
|
|
15964
16134
|
let preWriteEnv;
|
|
15965
16135
|
try {
|
|
15966
|
-
preWriteEnv =
|
|
16136
|
+
preWriteEnv = readFileSync29(envIntPath, "utf-8");
|
|
15967
16137
|
} catch {
|
|
15968
16138
|
preWriteEnv = void 0;
|
|
15969
16139
|
}
|
|
@@ -15982,9 +16152,9 @@ async function processAgent(agent, agentStates, managedToolkits) {
|
|
|
15982
16152
|
}
|
|
15983
16153
|
if (fw === "claude-code" && isSessionHealthy(agent.code_name)) {
|
|
15984
16154
|
try {
|
|
15985
|
-
const projectMcpPath =
|
|
15986
|
-
const postWriteEnv =
|
|
15987
|
-
const mcpContent =
|
|
16155
|
+
const projectMcpPath = join37(projectDir, ".mcp.json");
|
|
16156
|
+
const postWriteEnv = readFileSync29(envIntPath, "utf-8");
|
|
16157
|
+
const mcpContent = readFileSync29(projectMcpPath, "utf-8");
|
|
15988
16158
|
const changedVars = diffEnvIntegrations(preWriteEnv, postWriteEnv);
|
|
15989
16159
|
const mcpJsonForReap = JSON.parse(mcpContent);
|
|
15990
16160
|
const affectedServerKeys = findMcpServersUsingVars(mcpJsonForReap, changedVars);
|
|
@@ -16252,14 +16422,14 @@ async function processAgent(agent, agentStates, managedToolkits) {
|
|
|
16252
16422
|
const frameworkId2 = frameworkAdapter.id;
|
|
16253
16423
|
const candidateSkillDirs = [
|
|
16254
16424
|
// Claude Code — framework runtime tree
|
|
16255
|
-
|
|
16425
|
+
join37(homedir18(), ".augmented", agent.code_name, "skills"),
|
|
16256
16426
|
// Claude Code — project tree
|
|
16257
|
-
|
|
16427
|
+
join37(homedir18(), ".augmented", agent.code_name, "project", ".claude", "skills"),
|
|
16258
16428
|
// Defensive: legacy provision-side path, not currently an
|
|
16259
16429
|
// install target but cheap to sweep.
|
|
16260
|
-
|
|
16430
|
+
join37(agentDir, ".claude", "skills")
|
|
16261
16431
|
];
|
|
16262
|
-
const existingDirs = candidateSkillDirs.filter((d) =>
|
|
16432
|
+
const existingDirs = candidateSkillDirs.filter((d) => existsSync16(d));
|
|
16263
16433
|
const discoveredEntries = /* @__PURE__ */ new Set();
|
|
16264
16434
|
for (const dir of existingDirs) {
|
|
16265
16435
|
try {
|
|
@@ -16278,7 +16448,7 @@ async function processAgent(agent, agentStates, managedToolkits) {
|
|
|
16278
16448
|
entry,
|
|
16279
16449
|
dirs: existingDirs,
|
|
16280
16450
|
removeDir: (p) => {
|
|
16281
|
-
if (
|
|
16451
|
+
if (existsSync16(p)) {
|
|
16282
16452
|
rmSync6(p, { recursive: true, force: true });
|
|
16283
16453
|
}
|
|
16284
16454
|
}
|
|
@@ -16298,7 +16468,7 @@ async function processAgent(agent, agentStates, managedToolkits) {
|
|
|
16298
16468
|
const sharedSkillsPayload = refreshAny.shared_skills;
|
|
16299
16469
|
const desiredResolved = globalSkillsPayload !== void 0 || sharedSkillsPayload !== void 0;
|
|
16300
16470
|
const manifestPath = managedSkillManifestPath(
|
|
16301
|
-
|
|
16471
|
+
join37(homedir17(), ".augmented", agent.code_name)
|
|
16302
16472
|
);
|
|
16303
16473
|
const prevIds = /* @__PURE__ */ new Set([
|
|
16304
16474
|
...agentState.knownGlobalSkillIds.get(agent.agent_id) ?? /* @__PURE__ */ new Set(),
|
|
@@ -16318,15 +16488,15 @@ async function processAgent(agent, agentStates, managedToolkits) {
|
|
|
16318
16488
|
}
|
|
16319
16489
|
if (plan.removes.length) {
|
|
16320
16490
|
const globalSkillDirs = [
|
|
16321
|
-
|
|
16322
|
-
|
|
16323
|
-
|
|
16491
|
+
join37(homedir17(), ".augmented", agent.code_name, "skills"),
|
|
16492
|
+
join37(homedir17(), ".augmented", agent.code_name, "project", ".claude", "skills"),
|
|
16493
|
+
join37(agentDir, ".claude", "skills")
|
|
16324
16494
|
];
|
|
16325
16495
|
for (const id of plan.removes) {
|
|
16326
16496
|
let prunedAny = false;
|
|
16327
16497
|
for (const dir of globalSkillDirs) {
|
|
16328
|
-
const p =
|
|
16329
|
-
if (
|
|
16498
|
+
const p = join37(dir, id);
|
|
16499
|
+
if (existsSync16(p) && existsSync16(join37(p, "SKILL.md"))) {
|
|
16330
16500
|
rmSync5(p, { recursive: true, force: true });
|
|
16331
16501
|
prunedAny = true;
|
|
16332
16502
|
}
|
|
@@ -16562,8 +16732,8 @@ async function processAgent(agent, agentStates, managedToolkits) {
|
|
|
16562
16732
|
const sess = getSessionState(agent.code_name);
|
|
16563
16733
|
let mcpJsonParsed = null;
|
|
16564
16734
|
try {
|
|
16565
|
-
const mcpPath =
|
|
16566
|
-
mcpJsonParsed = JSON.parse(
|
|
16735
|
+
const mcpPath = join37(getProjectDir(agent.code_name), ".mcp.json");
|
|
16736
|
+
mcpJsonParsed = JSON.parse(readFileSync29(mcpPath, "utf-8"));
|
|
16567
16737
|
} catch {
|
|
16568
16738
|
}
|
|
16569
16739
|
reapMissingMcpSessions({
|
|
@@ -16994,10 +17164,10 @@ Retried to the limit after repeated stalls \u2014 needs a look.`).catch(() => {
|
|
|
16994
17164
|
}
|
|
16995
17165
|
}
|
|
16996
17166
|
const trackedFiles = frameworkAdapter.driftTrackedFiles();
|
|
16997
|
-
if (trackedFiles.length > 0 &&
|
|
17167
|
+
if (trackedFiles.length > 0 && existsSync16(agentDir)) {
|
|
16998
17168
|
const hashes = /* @__PURE__ */ new Map();
|
|
16999
17169
|
for (const file of trackedFiles) {
|
|
17000
|
-
const h = hashFile(
|
|
17170
|
+
const h = hashFile(join37(agentDir, file));
|
|
17001
17171
|
if (h) hashes.set(file, h);
|
|
17002
17172
|
}
|
|
17003
17173
|
agentState.writtenHashes.set(agent.agent_id, hashes);
|
|
@@ -17012,7 +17182,7 @@ Retried to the limit after repeated stalls \u2014 needs a look.`).catch(() => {
|
|
|
17012
17182
|
refreshData.agent.onboarding_state
|
|
17013
17183
|
);
|
|
17014
17184
|
const obStep = obState.step;
|
|
17015
|
-
const markerPath =
|
|
17185
|
+
const markerPath = join37(homedir17(), ".augmented", agent.code_name, "onboarding-drive.json");
|
|
17016
17186
|
const marker = readOnboardingDriveMarker(markerPath);
|
|
17017
17187
|
const obContactRaw = refreshData.agent.manager_last_contacted_at;
|
|
17018
17188
|
const obContact = typeof obContactRaw === "string" && obContactRaw ? obContactRaw : null;
|
|
@@ -17114,7 +17284,7 @@ async function ensureOpencodeRuntime(agent, refreshData, agentTimezone) {
|
|
|
17114
17284
|
}
|
|
17115
17285
|
stopOpencodeSlackIngest(codeName, log);
|
|
17116
17286
|
stopOpencodeTelegramIngest(codeName, log);
|
|
17117
|
-
const opencodeProjectDir =
|
|
17287
|
+
const opencodeProjectDir = join37(getFramework("opencode").getAgentDir(codeName), "provision");
|
|
17118
17288
|
const serveEnv = {
|
|
17119
17289
|
AGT_HOST: requireHost(),
|
|
17120
17290
|
AGT_API_KEY: getApiKey() ?? void 0,
|
|
@@ -17169,8 +17339,8 @@ async function ensurePersistentSession(agent, tasks, boardItems, refreshData) {
|
|
|
17169
17339
|
});
|
|
17170
17340
|
}
|
|
17171
17341
|
const projectDir = getProjectDir(codeName);
|
|
17172
|
-
const mcpConfigPath =
|
|
17173
|
-
const claudeMdPath =
|
|
17342
|
+
const mcpConfigPath = join37(projectDir, ".mcp.json");
|
|
17343
|
+
const claudeMdPath = join37(projectDir, "CLAUDE.md");
|
|
17174
17344
|
if (restartBreaker.isTripped(codeName)) {
|
|
17175
17345
|
const trip = restartBreaker.getTrip(codeName);
|
|
17176
17346
|
return {
|
|
@@ -17945,7 +18115,7 @@ async function handleRestartDoorbell(agentId, requestedAt, restartReason) {
|
|
|
17945
18115
|
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}`));
|
|
17946
18116
|
void (async () => {
|
|
17947
18117
|
try {
|
|
17948
|
-
const { collectDiagnostics } = await import("../persistent-session-
|
|
18118
|
+
const { collectDiagnostics } = await import("../persistent-session-TMOTEVV6.js");
|
|
17949
18119
|
await api.post("/host/heartbeat", {
|
|
17950
18120
|
host_id: hostId,
|
|
17951
18121
|
agent_diagnostics: collectDiagnostics([codeName], quarantineEntriesFor, claudeMdSizeFor, spawnOutcomeForDiagnostics, pidPressureFor)
|
|
@@ -17996,7 +18166,7 @@ async function respawnAgentAfterMcpStop(codeName, reason) {
|
|
|
17996
18166
|
}
|
|
17997
18167
|
try {
|
|
17998
18168
|
const hostId = await getHostId();
|
|
17999
|
-
const { collectDiagnostics } = await import("../persistent-session-
|
|
18169
|
+
const { collectDiagnostics } = await import("../persistent-session-TMOTEVV6.js");
|
|
18000
18170
|
await api.post("/host/heartbeat", {
|
|
18001
18171
|
host_id: hostId,
|
|
18002
18172
|
agent_diagnostics: collectDiagnostics([codeName], quarantineEntriesFor, claudeMdSizeFor, spawnOutcomeForDiagnostics, pidPressureFor)
|
|
@@ -18147,6 +18317,7 @@ function ensureRealtimeIntegrationContextStarted(agentStates) {
|
|
|
18147
18317
|
log(`[realtime] Dropped ${dropped} token-rotation rebind streak(s) for no-longer-active agent(s) (ENG-9265)`);
|
|
18148
18318
|
}
|
|
18149
18319
|
}
|
|
18320
|
+
pruneStuckStreaksToActiveAgents(activeAgentIds);
|
|
18150
18321
|
if (activeAgentIds.length === 0) {
|
|
18151
18322
|
if (subscribedIntegrationContextAgentIds.size > 0) {
|
|
18152
18323
|
stopRealtimeIntegrationContext();
|
|
@@ -18627,7 +18798,7 @@ async function processClaudePairSessions(agents) {
|
|
|
18627
18798
|
killPairSession,
|
|
18628
18799
|
pairTmuxSession,
|
|
18629
18800
|
finalizeClaudePairOnboarding
|
|
18630
|
-
} = await import("../claude-pair-runtime-
|
|
18801
|
+
} = await import("../claude-pair-runtime-MY5LMJVT.js");
|
|
18631
18802
|
for (const pairId of pendingResp.cancelled_pair_ids ?? []) {
|
|
18632
18803
|
log(`[claude-pair] sweeping orphan tmux session for pair ${pairId.slice(0, 8)}`);
|
|
18633
18804
|
const killed = await killPairSession(pairTmuxSession(pairId));
|
|
@@ -18852,17 +19023,17 @@ var lastDownloadHash = /* @__PURE__ */ new Map();
|
|
|
18852
19023
|
var lastLocalFileHash = /* @__PURE__ */ new Map();
|
|
18853
19024
|
var memoryManifests = /* @__PURE__ */ new Map();
|
|
18854
19025
|
function memoryRetirementDir(configDir, codeName) {
|
|
18855
|
-
return
|
|
19026
|
+
return join37(configDir, "_memory-retirement", codeName);
|
|
18856
19027
|
}
|
|
18857
19028
|
function memoryManifestPath(configDir, codeName) {
|
|
18858
|
-
return
|
|
19029
|
+
return join37(memoryRetirementDir(configDir, codeName), "manifest.json");
|
|
18859
19030
|
}
|
|
18860
19031
|
function loadMemoryManifest(agentId, configDir, codeName) {
|
|
18861
19032
|
const cached = memoryManifests.get(agentId);
|
|
18862
19033
|
if (cached) return cached;
|
|
18863
19034
|
let manifest = {};
|
|
18864
19035
|
try {
|
|
18865
|
-
const raw =
|
|
19036
|
+
const raw = readFileSync29(memoryManifestPath(configDir, codeName), "utf-8");
|
|
18866
19037
|
const parsed = JSON.parse(raw);
|
|
18867
19038
|
if (parsed && typeof parsed === "object" && !Array.isArray(parsed)) {
|
|
18868
19039
|
for (const [name, entry] of Object.entries(parsed)) {
|
|
@@ -18890,7 +19061,7 @@ function saveMemoryManifest(agentId, configDir, codeName) {
|
|
|
18890
19061
|
}
|
|
18891
19062
|
}
|
|
18892
19063
|
function retiredMemoryDir(configDir, codeName) {
|
|
18893
|
-
return
|
|
19064
|
+
return join37(memoryRetirementDir(configDir, codeName), "retired");
|
|
18894
19065
|
}
|
|
18895
19066
|
var RETIRED_MEMORY_TTL_MS = 30 * 24 * 60 * 60 * 1e3;
|
|
18896
19067
|
var lastRetirementReport = /* @__PURE__ */ new Map();
|
|
@@ -18968,15 +19139,15 @@ function applyMemoryTombstones(opts) {
|
|
|
18968
19139
|
log2(`[memory-retire] ${agent.code_name}: KEPT '${tomb.name}' \u2014 no write record, not ours to remove`);
|
|
18969
19140
|
continue;
|
|
18970
19141
|
}
|
|
18971
|
-
const filePath =
|
|
18972
|
-
if (!
|
|
19142
|
+
const filePath = join37(memoryDir, entry.file);
|
|
19143
|
+
if (!existsSync16(filePath)) {
|
|
18973
19144
|
outcomes.already_gone++;
|
|
18974
19145
|
delete manifest[tomb.name];
|
|
18975
19146
|
manifestDirty = true;
|
|
18976
19147
|
continue;
|
|
18977
19148
|
}
|
|
18978
19149
|
try {
|
|
18979
|
-
const actual = createHash17("sha256").update(
|
|
19150
|
+
const actual = createHash17("sha256").update(readFileSync29(filePath)).digest("hex");
|
|
18980
19151
|
if (actual !== entry.sha) {
|
|
18981
19152
|
outcomes.kept_modified++;
|
|
18982
19153
|
outcomes.unapplied.push({ name: tomb.name, reason: "kept_modified" });
|
|
@@ -18988,9 +19159,9 @@ function applyMemoryTombstones(opts) {
|
|
|
18988
19159
|
const destDir = retiredMemoryDir(configDir, agent.code_name);
|
|
18989
19160
|
mkdirSync11(destDir, { recursive: true });
|
|
18990
19161
|
const stamp = Date.now();
|
|
18991
|
-
let dest =
|
|
18992
|
-
for (let n = 1;
|
|
18993
|
-
dest =
|
|
19162
|
+
let dest = join37(destDir, `${entry.file}.${stamp}.retired`);
|
|
19163
|
+
for (let n = 1; existsSync16(dest); n++) {
|
|
19164
|
+
dest = join37(destDir, `${entry.file}.${stamp}-${n}.retired`);
|
|
18994
19165
|
}
|
|
18995
19166
|
renameSync8(filePath, dest);
|
|
18996
19167
|
try {
|
|
@@ -19023,13 +19194,13 @@ function applyMemoryTombstones(opts) {
|
|
|
19023
19194
|
}
|
|
19024
19195
|
function reapRetiredMemories(configDir, codeName, log2) {
|
|
19025
19196
|
const dir = retiredMemoryDir(configDir, codeName);
|
|
19026
|
-
if (!
|
|
19197
|
+
if (!existsSync16(dir)) return;
|
|
19027
19198
|
const cutoff = Date.now() - RETIRED_MEMORY_TTL_MS;
|
|
19028
19199
|
let reaped = 0;
|
|
19029
19200
|
try {
|
|
19030
19201
|
for (const file of readdirSync9(dir)) {
|
|
19031
19202
|
if (!file.endsWith(".retired")) continue;
|
|
19032
|
-
const path =
|
|
19203
|
+
const path = join37(dir, file);
|
|
19033
19204
|
try {
|
|
19034
19205
|
if (statSync8(path).mtimeMs < cutoff) {
|
|
19035
19206
|
unlinkSync6(path);
|
|
@@ -19044,8 +19215,8 @@ function reapRetiredMemories(configDir, codeName, log2) {
|
|
|
19044
19215
|
if (reaped > 0) log2(`[memory-retire] ${codeName}: reaped ${reaped} retired memory file(s) past TTL`);
|
|
19045
19216
|
}
|
|
19046
19217
|
async function syncMemories(agent, configDir, log2) {
|
|
19047
|
-
const projectDir =
|
|
19048
|
-
const memoryDir =
|
|
19218
|
+
const projectDir = join37(configDir, agent.code_name, "project");
|
|
19219
|
+
const memoryDir = join37(projectDir, "memory");
|
|
19049
19220
|
const isFreshSync = pendingFreshMemorySync.has(agent.agent_id);
|
|
19050
19221
|
if (isFreshSync) {
|
|
19051
19222
|
log2(`[memory-sync] Fresh-sync requested for '${agent.code_name}' \u2014 pulling DB first`);
|
|
@@ -19069,14 +19240,14 @@ async function syncMemories(agent, configDir, log2) {
|
|
|
19069
19240
|
}
|
|
19070
19241
|
pendingFreshMemorySync.delete(agent.agent_id);
|
|
19071
19242
|
}
|
|
19072
|
-
if (
|
|
19243
|
+
if (existsSync16(memoryDir)) {
|
|
19073
19244
|
const prevHashes = memoryFileHashes.get(agent.agent_id) ?? /* @__PURE__ */ new Map();
|
|
19074
19245
|
const currentHashes = /* @__PURE__ */ new Map();
|
|
19075
19246
|
const changedMemories = [];
|
|
19076
19247
|
for (const file of readdirSync9(memoryDir)) {
|
|
19077
19248
|
if (!file.endsWith(".md")) continue;
|
|
19078
19249
|
try {
|
|
19079
|
-
const raw =
|
|
19250
|
+
const raw = readFileSync29(join37(memoryDir, file), "utf-8");
|
|
19080
19251
|
const fileHash = createHash17("sha256").update(raw).digest("hex").slice(0, 16);
|
|
19081
19252
|
currentHashes.set(file, fileHash);
|
|
19082
19253
|
if (prevHashes.get(file) === fileHash) continue;
|
|
@@ -19101,7 +19272,7 @@ async function syncMemories(agent, configDir, log2) {
|
|
|
19101
19272
|
} catch (err) {
|
|
19102
19273
|
for (const mem of changedMemories) {
|
|
19103
19274
|
for (const [file] of currentHashes) {
|
|
19104
|
-
const parsed = parseMemoryFile(
|
|
19275
|
+
const parsed = parseMemoryFile(readFileSync29(join37(memoryDir, file), "utf-8"), file.replace(/\.md$/, ""));
|
|
19105
19276
|
if (parsed?.name === mem.name) currentHashes.delete(file);
|
|
19106
19277
|
}
|
|
19107
19278
|
}
|
|
@@ -19127,7 +19298,7 @@ async function syncMemories(agent, configDir, log2) {
|
|
|
19127
19298
|
}
|
|
19128
19299
|
}
|
|
19129
19300
|
async function downloadMemories(agent, memoryDir, log2, { force, configDir }) {
|
|
19130
|
-
const localFiles =
|
|
19301
|
+
const localFiles = existsSync16(memoryDir) ? readdirSync9(memoryDir).filter((f) => f.endsWith(".md")).sort() : [];
|
|
19131
19302
|
const localListHash = createHash17("sha256").update(localFiles.join(",")).digest("hex").slice(0, 16);
|
|
19132
19303
|
const prevLocalHash = lastLocalFileHash.get(agent.agent_id);
|
|
19133
19304
|
const prevDownload = lastDownloadHash.get(agent.agent_id);
|
|
@@ -19152,7 +19323,7 @@ async function downloadMemories(agent, memoryDir, log2, { force, configDir }) {
|
|
|
19152
19323
|
const rawSlug = mem.name.toLowerCase().replace(/[^a-z0-9]+/g, "-").replace(/(^-|-$)/g, "").slice(0, 60);
|
|
19153
19324
|
const slug = rawSlug || `memory-${i}`;
|
|
19154
19325
|
const fileName = `${slug}.md`;
|
|
19155
|
-
const filePath =
|
|
19326
|
+
const filePath = join37(memoryDir, fileName);
|
|
19156
19327
|
const desired = `---
|
|
19157
19328
|
name: ${JSON.stringify(mem.name)}
|
|
19158
19329
|
type: ${mem.type}
|
|
@@ -19169,10 +19340,10 @@ ${mem.content}
|
|
|
19169
19340
|
return true;
|
|
19170
19341
|
};
|
|
19171
19342
|
let manifestDirty = false;
|
|
19172
|
-
if (
|
|
19343
|
+
if (existsSync16(filePath)) {
|
|
19173
19344
|
let existing = "";
|
|
19174
19345
|
try {
|
|
19175
|
-
existing =
|
|
19346
|
+
existing = readFileSync29(filePath, "utf-8");
|
|
19176
19347
|
} catch {
|
|
19177
19348
|
}
|
|
19178
19349
|
if (existing === desired) {
|
|
@@ -19202,7 +19373,7 @@ ${mem.content}
|
|
|
19202
19373
|
}
|
|
19203
19374
|
}
|
|
19204
19375
|
async function cleanupAgentFiles(codeName, agentDir) {
|
|
19205
|
-
if (
|
|
19376
|
+
if (existsSync16(agentDir)) {
|
|
19206
19377
|
try {
|
|
19207
19378
|
rmSync5(agentDir, { recursive: true, force: true });
|
|
19208
19379
|
log(`Removed provision directory for '${codeName}'`);
|
|
@@ -19325,6 +19496,7 @@ function startPolling() {
|
|
|
19325
19496
|
void startCaffeinate();
|
|
19326
19497
|
loadChannelHashCache2();
|
|
19327
19498
|
loadSenderPolicyBaseline2();
|
|
19499
|
+
loadStuckStreaks2();
|
|
19328
19500
|
loadKanbanNudgeStateFromDisk();
|
|
19329
19501
|
hostFlagStore().init();
|
|
19330
19502
|
log(`Starting poll loop (interval=${config.intervalMs}ms, configDir=${config.configDir})`);
|
|
@@ -19470,8 +19642,8 @@ function startManager(opts) {
|
|
|
19470
19642
|
config = opts;
|
|
19471
19643
|
try {
|
|
19472
19644
|
const stateFile = getStateFile();
|
|
19473
|
-
if (
|
|
19474
|
-
const raw =
|
|
19645
|
+
if (existsSync16(stateFile)) {
|
|
19646
|
+
const raw = readFileSync29(stateFile, "utf-8");
|
|
19475
19647
|
const parsed = JSON.parse(raw);
|
|
19476
19648
|
if (Array.isArray(parsed.agents)) {
|
|
19477
19649
|
state7.agents = parsed.agents;
|
|
@@ -19498,7 +19670,7 @@ function startManager(opts) {
|
|
|
19498
19670
|
log(`[startup] state rehydration failed (continuing with empty state): ${err.message}`);
|
|
19499
19671
|
}
|
|
19500
19672
|
log(
|
|
19501
|
-
`[startup] worker pid=${process.pid} ppid=${process.ppid} node=${process.version} log=${
|
|
19673
|
+
`[startup] worker pid=${process.pid} ppid=${process.ppid} node=${process.version} log=${join37(homedir17(), ".augmented", "manager.log")}`
|
|
19502
19674
|
);
|
|
19503
19675
|
deployMcpAssets();
|
|
19504
19676
|
reapOrphanChannelMcps({ log });
|
|
@@ -19527,7 +19699,7 @@ async function reapOrphanedClaudePids() {
|
|
|
19527
19699
|
const looksLikeClaude = (pid) => {
|
|
19528
19700
|
if (process.platform !== "linux") return true;
|
|
19529
19701
|
try {
|
|
19530
|
-
const comm =
|
|
19702
|
+
const comm = readFileSync29(`/proc/${pid}/comm`, "utf-8").trim().toLowerCase();
|
|
19531
19703
|
return comm.includes("claude");
|
|
19532
19704
|
} catch {
|
|
19533
19705
|
return false;
|
|
@@ -19624,14 +19796,14 @@ function restartRunningChannelMcps(basenames) {
|
|
|
19624
19796
|
}
|
|
19625
19797
|
}
|
|
19626
19798
|
function deployMcpAssets() {
|
|
19627
|
-
const targetDir =
|
|
19799
|
+
const targetDir = join37(homedir17(), ".augmented", "_mcp");
|
|
19628
19800
|
mkdirSync11(targetDir, { recursive: true });
|
|
19629
19801
|
const moduleDir = dirname10(fileURLToPath(import.meta.url));
|
|
19630
19802
|
let mcpSourceDir = "";
|
|
19631
19803
|
let dir = moduleDir;
|
|
19632
19804
|
for (let i = 0; i < 6; i++) {
|
|
19633
|
-
const candidate =
|
|
19634
|
-
if (
|
|
19805
|
+
const candidate = join37(dir, "dist", "mcp");
|
|
19806
|
+
if (existsSync16(join37(candidate, "index.js"))) {
|
|
19635
19807
|
mcpSourceDir = candidate;
|
|
19636
19808
|
break;
|
|
19637
19809
|
}
|
|
@@ -19648,8 +19820,8 @@ function deployMcpAssets() {
|
|
|
19648
19820
|
const failedFiles = [];
|
|
19649
19821
|
const fileHash = (p) => {
|
|
19650
19822
|
try {
|
|
19651
|
-
if (!
|
|
19652
|
-
return createHash17("sha256").update(
|
|
19823
|
+
if (!existsSync16(p)) return null;
|
|
19824
|
+
return createHash17("sha256").update(readFileSync29(p)).digest("hex");
|
|
19653
19825
|
} catch {
|
|
19654
19826
|
return null;
|
|
19655
19827
|
}
|
|
@@ -19720,9 +19892,9 @@ function deployMcpAssets() {
|
|
|
19720
19892
|
// needs restarting to pick up a token rotation.
|
|
19721
19893
|
"xero.js"
|
|
19722
19894
|
]) {
|
|
19723
|
-
const src =
|
|
19724
|
-
const dst =
|
|
19725
|
-
if (!
|
|
19895
|
+
const src = join37(mcpSourceDir, file);
|
|
19896
|
+
const dst = join37(targetDir, file);
|
|
19897
|
+
if (!existsSync16(src)) continue;
|
|
19726
19898
|
attemptedFiles.push(file);
|
|
19727
19899
|
const before = fileHash(dst);
|
|
19728
19900
|
try {
|
|
@@ -19747,16 +19919,16 @@ function deployMcpAssets() {
|
|
|
19747
19919
|
log(`[manager] Bundle(s) updated: ${changedBasenames.join(", ")} \u2014 signalling running instances to restart`);
|
|
19748
19920
|
restartRunningChannelMcps(changedBasenames);
|
|
19749
19921
|
}
|
|
19750
|
-
const localMcpPath =
|
|
19922
|
+
const localMcpPath = join37(targetDir, "index.js");
|
|
19751
19923
|
try {
|
|
19752
|
-
const agentsDir =
|
|
19753
|
-
if (
|
|
19924
|
+
const agentsDir = join37(homedir17(), ".augmented", "agents");
|
|
19925
|
+
if (existsSync16(agentsDir)) {
|
|
19754
19926
|
for (const entry of readdirSync9(agentsDir, { withFileTypes: true })) {
|
|
19755
19927
|
if (!entry.isDirectory()) continue;
|
|
19756
19928
|
for (const subdir of ["provision", "project"]) {
|
|
19757
|
-
const mcpJsonPath =
|
|
19929
|
+
const mcpJsonPath = join37(agentsDir, entry.name, subdir, ".mcp.json");
|
|
19758
19930
|
try {
|
|
19759
|
-
const raw =
|
|
19931
|
+
const raw = readFileSync29(mcpJsonPath, "utf-8");
|
|
19760
19932
|
if (!raw.includes("@integrity-labs/augmented-mcp")) continue;
|
|
19761
19933
|
const mcpConfig = JSON.parse(raw);
|
|
19762
19934
|
const augServer = mcpConfig.mcpServers?.["augmented"];
|