@integrity-labs/agt-cli 0.28.492 → 0.28.493
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/bin/agt.js +4 -4
- package/dist/{chunk-KB5KVAWJ.js → chunk-3XLUSG32.js} +129 -6
- package/dist/chunk-3XLUSG32.js.map +1 -0
- package/dist/{chunk-34E3FHOS.js → chunk-SRO2IQ4R.js} +13 -1
- package/dist/{chunk-34E3FHOS.js.map → chunk-SRO2IQ4R.js.map} +1 -1
- package/dist/{claude-pair-runtime-GJF64TMZ.js → claude-pair-runtime-7TSEIWGA.js} +2 -2
- package/dist/lib/manager-worker.js +332 -214
- package/dist/lib/manager-worker.js.map +1 -1
- package/dist/mcp/direct-chat-channel.js +12 -0
- package/dist/mcp/origami.js +12 -0
- package/dist/mcp/slack-channel.js +12 -0
- package/dist/mcp/telegram-channel.js +12 -0
- package/dist/{persistent-session-Y3WIXJPW.js → persistent-session-MVAEGE6J.js} +2 -2
- package/dist/{responsiveness-probe-AEFEFKOQ.js → responsiveness-probe-6YXN4G6V.js} +2 -2
- package/package.json +1 -1
- package/dist/chunk-KB5KVAWJ.js.map +0 -1
- /package/dist/{claude-pair-runtime-GJF64TMZ.js.map → claude-pair-runtime-7TSEIWGA.js.map} +0 -0
- /package/dist/{persistent-session-Y3WIXJPW.js.map → persistent-session-MVAEGE6J.js.map} +0 -0
- /package/dist/{responsiveness-probe-AEFEFKOQ.js.map → responsiveness-probe-6YXN4G6V.js.map} +0 -0
|
@@ -28,6 +28,7 @@ import {
|
|
|
28
28
|
isTransientAuthFailure,
|
|
29
29
|
liveProxyExtraHeaderVars,
|
|
30
30
|
liveProxyTokenVars,
|
|
31
|
+
migrateAgentDirToIdKeyed,
|
|
31
32
|
pinAllowsUrgent,
|
|
32
33
|
provision,
|
|
33
34
|
provisionAutoKanbanProgressHook,
|
|
@@ -44,7 +45,7 @@ import {
|
|
|
44
45
|
resolveEffectivePinRaw,
|
|
45
46
|
safeWriteJsonAtomic,
|
|
46
47
|
setConfigHash
|
|
47
|
-
} from "../chunk-
|
|
48
|
+
} from "../chunk-3XLUSG32.js";
|
|
48
49
|
import {
|
|
49
50
|
getProjectDir as getProjectDir2,
|
|
50
51
|
getReadyTasks,
|
|
@@ -162,17 +163,17 @@ import {
|
|
|
162
163
|
toOpencodeModel,
|
|
163
164
|
transcriptActivityAgeSeconds,
|
|
164
165
|
writeEgressAllowlist
|
|
165
|
-
} from "../chunk-
|
|
166
|
+
} from "../chunk-SRO2IQ4R.js";
|
|
166
167
|
import {
|
|
167
168
|
reapOrphanChannelMcps
|
|
168
169
|
} from "../chunk-XWVM4KPK.js";
|
|
169
170
|
|
|
170
171
|
// src/lib/manager-worker.ts
|
|
171
172
|
import { createHash as createHash16 } from "crypto";
|
|
172
|
-
import { readFileSync as readFileSync21, writeFileSync as writeFileSync12, mkdirSync as mkdirSync10, existsSync as
|
|
173
|
+
import { readFileSync as readFileSync21, writeFileSync as writeFileSync12, mkdirSync as mkdirSync10, existsSync as existsSync12, rmSync as rmSync5, readdirSync as readdirSync7, statSync as statSync6, copyFileSync } from "fs";
|
|
173
174
|
import { execFileSync as syncExecFile } from "child_process";
|
|
174
|
-
import { join as
|
|
175
|
-
import { homedir as
|
|
175
|
+
import { join as join26, dirname as dirname8, delimiter as pathDelimiter } from "path";
|
|
176
|
+
import { homedir as homedir12 } from "os";
|
|
176
177
|
import { fileURLToPath } from "url";
|
|
177
178
|
|
|
178
179
|
// src/lib/claude-code-upgrade-throttle.ts
|
|
@@ -2035,6 +2036,115 @@ function isDirectChatMessageExpired(createdAt, nowMs, maxAgeMs) {
|
|
|
2035
2036
|
return nowMs - created > maxAgeMs;
|
|
2036
2037
|
}
|
|
2037
2038
|
|
|
2039
|
+
// src/lib/id-keyed-migration.ts
|
|
2040
|
+
import { existsSync as existsSync2, lstatSync, readlinkSync, renameSync } from "fs";
|
|
2041
|
+
import { join as join5 } from "path";
|
|
2042
|
+
import { homedir as homedir2 } from "os";
|
|
2043
|
+
var ID_KEYED_MIGRATION_FLAG = "id-keyed-layout-migration";
|
|
2044
|
+
function agentHasActiveWhatsapp(channelConfigs, codeNameDir) {
|
|
2045
|
+
if (channelConfigs && Object.prototype.hasOwnProperty.call(channelConfigs, "whatsapp")) {
|
|
2046
|
+
return true;
|
|
2047
|
+
}
|
|
2048
|
+
try {
|
|
2049
|
+
if (existsSync2(join5(codeNameDir, "whatsapp-pending-inbound"))) return true;
|
|
2050
|
+
} catch {
|
|
2051
|
+
}
|
|
2052
|
+
return false;
|
|
2053
|
+
}
|
|
2054
|
+
function finishTranscriptMove(oldCwd, newCwd, codeName, log2) {
|
|
2055
|
+
const from = sessionTranscriptDir(oldCwd);
|
|
2056
|
+
const to = sessionTranscriptDir(newCwd);
|
|
2057
|
+
if (from === to) return;
|
|
2058
|
+
let fromExists = false;
|
|
2059
|
+
let toExists = false;
|
|
2060
|
+
try {
|
|
2061
|
+
fromExists = existsSync2(from);
|
|
2062
|
+
} catch {
|
|
2063
|
+
}
|
|
2064
|
+
if (!fromExists) return;
|
|
2065
|
+
try {
|
|
2066
|
+
toExists = existsSync2(to);
|
|
2067
|
+
} catch {
|
|
2068
|
+
}
|
|
2069
|
+
if (toExists) {
|
|
2070
|
+
log2(
|
|
2071
|
+
`[id-keyed-migration] transcript store for '${codeName}' already present at the id-keyed key; leaving the legacy dir in place for an operator to reconcile`
|
|
2072
|
+
);
|
|
2073
|
+
return;
|
|
2074
|
+
}
|
|
2075
|
+
renameSync(from, to);
|
|
2076
|
+
log2(`[id-keyed-migration] moved transcript store for '${codeName}' to the id-keyed key`);
|
|
2077
|
+
}
|
|
2078
|
+
function maybeMigrateAgentToIdKeyedLayout(agent, deps) {
|
|
2079
|
+
const home = deps.home ?? homedir2();
|
|
2080
|
+
const { code_name: codeName, agent_id: agentId } = agent;
|
|
2081
|
+
const codeNamePath = join5(home, ".augmented", codeName);
|
|
2082
|
+
const idPath = join5(home, ".augmented", agentId);
|
|
2083
|
+
const oldCwd = join5(home, ".augmented", codeName, "project");
|
|
2084
|
+
const newCwd = join5(idPath, "project");
|
|
2085
|
+
let codeNameKind;
|
|
2086
|
+
try {
|
|
2087
|
+
codeNameKind = lstatSync(codeNamePath).isSymbolicLink() ? "symlink" : "realdir";
|
|
2088
|
+
} catch {
|
|
2089
|
+
codeNameKind = "absent";
|
|
2090
|
+
}
|
|
2091
|
+
const idExists = existsSync2(idPath);
|
|
2092
|
+
try {
|
|
2093
|
+
if (codeNameKind === "symlink") {
|
|
2094
|
+
const target = readlinkSync(codeNamePath);
|
|
2095
|
+
if (target !== agentId) {
|
|
2096
|
+
deps.log(
|
|
2097
|
+
`[id-keyed-migration] CONFLICT for '${codeName}': codename symlink points at "${target}", expected "${agentId}"; refusing to touch the transcript store (operator reconciliation required)`
|
|
2098
|
+
);
|
|
2099
|
+
return "conflict";
|
|
2100
|
+
}
|
|
2101
|
+
finishTranscriptMove(oldCwd, newCwd, codeName, deps.log);
|
|
2102
|
+
return "already-id-keyed";
|
|
2103
|
+
}
|
|
2104
|
+
if (codeNameKind === "absent" && idExists) {
|
|
2105
|
+
migrateAgentDirToIdKeyed(codeName, agentId, { home });
|
|
2106
|
+
finishTranscriptMove(oldCwd, newCwd, codeName, deps.log);
|
|
2107
|
+
deps.log(
|
|
2108
|
+
`[id-keyed-migration] recovered an interrupted migration for '${codeName}' -> ${agentId}`
|
|
2109
|
+
);
|
|
2110
|
+
return "recovered";
|
|
2111
|
+
}
|
|
2112
|
+
if (codeNameKind === "absent") return "no-agent";
|
|
2113
|
+
if (!deps.flagStore.getBooleanForAgent(ID_KEYED_MIGRATION_FLAG, agentId)) {
|
|
2114
|
+
return "skipped-flag-off";
|
|
2115
|
+
}
|
|
2116
|
+
if (idExists) {
|
|
2117
|
+
deps.log(
|
|
2118
|
+
`[id-keyed-migration] CONFLICT for '${codeName}': a real codename dir AND a real ${agentId} dir both exist; refusing to migrate (operator reconciliation required)`
|
|
2119
|
+
);
|
|
2120
|
+
return "conflict";
|
|
2121
|
+
}
|
|
2122
|
+
if (agentHasActiveWhatsapp(deps.channelConfigs, codeNamePath)) {
|
|
2123
|
+
deps.log(
|
|
2124
|
+
`[id-keyed-migration] deferred '${codeName}': active WhatsApp channel \u2014 the host-resident inbound writer cannot be quiesced from the manager; use the manual rename runbook`
|
|
2125
|
+
);
|
|
2126
|
+
return "skipped-external-writer";
|
|
2127
|
+
}
|
|
2128
|
+
const status = migrateAgentDirToIdKeyed(codeName, agentId, { home });
|
|
2129
|
+
if (status === "conflict") {
|
|
2130
|
+
deps.log(
|
|
2131
|
+
`[id-keyed-migration] CONFLICT for '${codeName}': ${agentId} dir appeared mid-migration; refusing to migrate (operator reconciliation required)`
|
|
2132
|
+
);
|
|
2133
|
+
return "conflict";
|
|
2134
|
+
}
|
|
2135
|
+
finishTranscriptMove(oldCwd, newCwd, codeName, deps.log);
|
|
2136
|
+
deps.log(
|
|
2137
|
+
`[id-keyed-migration] migrated '${codeName}' to the id-keyed layout (~/.augmented/${agentId}); codename is now a compatibility symlink`
|
|
2138
|
+
);
|
|
2139
|
+
return "migrated";
|
|
2140
|
+
} catch (err) {
|
|
2141
|
+
deps.log(
|
|
2142
|
+
`[id-keyed-migration] FAILED for '${codeName}': ${err.message}; leaving the current layout in place, will retry next tick`
|
|
2143
|
+
);
|
|
2144
|
+
return "failed";
|
|
2145
|
+
}
|
|
2146
|
+
}
|
|
2147
|
+
|
|
2038
2148
|
// src/lib/manager/auth-resolve-decision.ts
|
|
2039
2149
|
function decideAuthResolveFailureAction(args) {
|
|
2040
2150
|
const transient = isTransientAuthFailure(args.error);
|
|
@@ -2086,8 +2196,8 @@ function collectEnvGates(env) {
|
|
|
2086
2196
|
}
|
|
2087
2197
|
|
|
2088
2198
|
// src/lib/artifact-stream.ts
|
|
2089
|
-
import { join as
|
|
2090
|
-
import { homedir as
|
|
2199
|
+
import { join as join6 } from "path";
|
|
2200
|
+
import { homedir as homedir3 } from "os";
|
|
2091
2201
|
import { readdir, stat, readFile } from "fs/promises";
|
|
2092
2202
|
var ARTEFACT_ENTRY_FILE = "index.html";
|
|
2093
2203
|
function errMessage(err) {
|
|
@@ -2172,7 +2282,7 @@ var ArtifactStreamScanner = class {
|
|
|
2172
2282
|
return;
|
|
2173
2283
|
}
|
|
2174
2284
|
for (const name of names) {
|
|
2175
|
-
const file =
|
|
2285
|
+
const file = join6(this.artifactsDir, name, ARTEFACT_ENTRY_FILE);
|
|
2176
2286
|
const mtime = await this.fsDeps.mtimeMs(file).catch(() => null);
|
|
2177
2287
|
if (mtime === null) continue;
|
|
2178
2288
|
if (this.seenMtime.get(name) === mtime) continue;
|
|
@@ -2203,7 +2313,7 @@ var ArtifactStreamScanner = class {
|
|
|
2203
2313
|
}
|
|
2204
2314
|
};
|
|
2205
2315
|
function artifactsDirFor(codeName) {
|
|
2206
|
-
return
|
|
2316
|
+
return join6(homedir3(), ".augmented", codeName, "artifacts");
|
|
2207
2317
|
}
|
|
2208
2318
|
var nodeArtifactFs = {
|
|
2209
2319
|
async listArtefactNames(artifactsDir) {
|
|
@@ -2292,13 +2402,13 @@ async function maybeReportUsageBanner(args) {
|
|
|
2292
2402
|
// src/lib/claude-account-fingerprint.ts
|
|
2293
2403
|
import { createHash as createHash6 } from "crypto";
|
|
2294
2404
|
import { readFile as readFile3, readdir as readdir3 } from "fs/promises";
|
|
2295
|
-
import { homedir as
|
|
2296
|
-
import { dirname as dirname4, join as
|
|
2405
|
+
import { homedir as homedir5, platform as platform2 } from "os";
|
|
2406
|
+
import { dirname as dirname4, join as join8 } from "path";
|
|
2297
2407
|
|
|
2298
2408
|
// src/lib/claude-auth-detect.ts
|
|
2299
2409
|
import { readFile as readFile2, readdir as readdir2 } from "fs/promises";
|
|
2300
|
-
import { homedir as
|
|
2301
|
-
import { join as
|
|
2410
|
+
import { homedir as homedir4, platform } from "os";
|
|
2411
|
+
import { join as join7 } from "path";
|
|
2302
2412
|
import { execFile } from "child_process";
|
|
2303
2413
|
import { promisify } from "util";
|
|
2304
2414
|
var execFileAsync = promisify(execFile);
|
|
@@ -2313,16 +2423,16 @@ async function detectClaudeAuth() {
|
|
|
2313
2423
|
}
|
|
2314
2424
|
async function findClaudeCredentialsPaths() {
|
|
2315
2425
|
const candidates = [
|
|
2316
|
-
|
|
2317
|
-
|
|
2426
|
+
join7(homedir4(), ".claude", ".credentials.json"),
|
|
2427
|
+
join7(homedir4(), ".claude", "credentials.json")
|
|
2318
2428
|
];
|
|
2319
2429
|
const isLinuxRoot = platform() === "linux" && typeof process.getuid === "function" && process.getuid() === 0;
|
|
2320
2430
|
if (isLinuxRoot) {
|
|
2321
2431
|
try {
|
|
2322
2432
|
const entries = await readdir2("/home", { withFileTypes: true });
|
|
2323
2433
|
for (const entry of entries.filter((entry2) => entry2.isDirectory()).sort((a, b) => a.name.localeCompare(b.name))) {
|
|
2324
|
-
candidates.push(
|
|
2325
|
-
candidates.push(
|
|
2434
|
+
candidates.push(join7("/home", entry.name, ".claude", ".credentials.json"));
|
|
2435
|
+
candidates.push(join7("/home", entry.name, ".claude", "credentials.json"));
|
|
2326
2436
|
}
|
|
2327
2437
|
} catch {
|
|
2328
2438
|
}
|
|
@@ -2400,13 +2510,13 @@ function parseExpiresAt(raw) {
|
|
|
2400
2510
|
|
|
2401
2511
|
// src/lib/claude-account-fingerprint.ts
|
|
2402
2512
|
async function candidateHomes() {
|
|
2403
|
-
const homes = [
|
|
2513
|
+
const homes = [homedir5()];
|
|
2404
2514
|
const isLinuxRoot = platform2() === "linux" && typeof process.getuid === "function" && process.getuid() === 0;
|
|
2405
2515
|
if (isLinuxRoot) {
|
|
2406
2516
|
try {
|
|
2407
2517
|
const entries = await readdir3("/home", { withFileTypes: true });
|
|
2408
2518
|
for (const entry of entries.filter((e) => e.isDirectory()).sort((a, b) => a.name.localeCompare(b.name))) {
|
|
2409
|
-
homes.push(
|
|
2519
|
+
homes.push(join8("/home", entry.name));
|
|
2410
2520
|
}
|
|
2411
2521
|
} catch {
|
|
2412
2522
|
}
|
|
@@ -2426,11 +2536,11 @@ async function homeOfActiveCredentials() {
|
|
|
2426
2536
|
async function claudeConfigCandidatePaths() {
|
|
2427
2537
|
const paths = [];
|
|
2428
2538
|
const configDir = process.env["CLAUDE_CONFIG_DIR"]?.trim();
|
|
2429
|
-
if (configDir) paths.push(
|
|
2539
|
+
if (configDir) paths.push(join8(configDir, ".claude.json"));
|
|
2430
2540
|
const activeHome = await homeOfActiveCredentials();
|
|
2431
|
-
if (activeHome) paths.push(
|
|
2541
|
+
if (activeHome) paths.push(join8(activeHome, ".claude.json"));
|
|
2432
2542
|
for (const home of await candidateHomes()) {
|
|
2433
|
-
const path =
|
|
2543
|
+
const path = join8(home, ".claude.json");
|
|
2434
2544
|
if (!paths.includes(path)) paths.push(path);
|
|
2435
2545
|
}
|
|
2436
2546
|
return paths;
|
|
@@ -2527,11 +2637,11 @@ function diffAuthTuples(recorded, current) {
|
|
|
2527
2637
|
}
|
|
2528
2638
|
|
|
2529
2639
|
// src/lib/account-enforcement-marker.ts
|
|
2530
|
-
import { mkdirSync as mkdirSync4, renameSync, rmSync as rmSync2, writeFileSync as writeFileSync4 } from "fs";
|
|
2531
|
-
import { homedir as
|
|
2532
|
-
import { join as
|
|
2640
|
+
import { mkdirSync as mkdirSync4, renameSync as renameSync2, rmSync as rmSync2, writeFileSync as writeFileSync4 } from "fs";
|
|
2641
|
+
import { homedir as homedir6 } from "os";
|
|
2642
|
+
import { join as join9 } from "path";
|
|
2533
2643
|
function accountEnforcementMarkerPath(codeName) {
|
|
2534
|
-
return
|
|
2644
|
+
return join9(homedir6(), ".augmented", codeName, ACCOUNT_ENFORCEMENT_MARKER_FILENAME);
|
|
2535
2645
|
}
|
|
2536
2646
|
function syncAccountEnforcementMarker(codeName, level, log2 = (m) => process.stderr.write(`${m}
|
|
2537
2647
|
`)) {
|
|
@@ -2539,13 +2649,13 @@ function syncAccountEnforcementMarker(codeName, level, log2 = (m) => process.std
|
|
|
2539
2649
|
clearAccountEnforcementMarker(codeName, log2);
|
|
2540
2650
|
return;
|
|
2541
2651
|
}
|
|
2542
|
-
const dir =
|
|
2543
|
-
const path =
|
|
2652
|
+
const dir = join9(homedir6(), ".augmented", codeName);
|
|
2653
|
+
const path = join9(dir, ACCOUNT_ENFORCEMENT_MARKER_FILENAME);
|
|
2544
2654
|
const tempPath = `${path}.${process.pid}.tmp`;
|
|
2545
2655
|
try {
|
|
2546
2656
|
mkdirSync4(dir, { recursive: true });
|
|
2547
2657
|
writeFileSync4(tempPath, serializeAccountEnforcementMarker(level), "utf-8");
|
|
2548
|
-
|
|
2658
|
+
renameSync2(tempPath, path);
|
|
2549
2659
|
} catch (err) {
|
|
2550
2660
|
try {
|
|
2551
2661
|
rmSync2(tempPath, { force: true });
|
|
@@ -2566,7 +2676,7 @@ function clearAccountEnforcementMarker(codeName, log2 = (m) => process.stderr.wr
|
|
|
2566
2676
|
|
|
2567
2677
|
// src/lib/token-usage-monitor.ts
|
|
2568
2678
|
import { readdirSync, readFileSync as readFileSync7, statSync } from "fs";
|
|
2569
|
-
import { join as
|
|
2679
|
+
import { join as join10 } from "path";
|
|
2570
2680
|
var MIN_CHECK_INTERVAL_MS2 = 6e4;
|
|
2571
2681
|
var TRANSCRIPT_MTIME_WINDOW_MS = 2 * 24 * 60 * 60 * 1e3;
|
|
2572
2682
|
var MAX_ENTRIES_PER_POST = 200;
|
|
@@ -2595,7 +2705,7 @@ async function maybeReportTokenUsage(args) {
|
|
|
2595
2705
|
if (!name.endsWith(".jsonl")) continue;
|
|
2596
2706
|
const sessionId = name.slice(0, -".jsonl".length);
|
|
2597
2707
|
if (!sessionId) continue;
|
|
2598
|
-
const path =
|
|
2708
|
+
const path = join10(dir, name);
|
|
2599
2709
|
let st;
|
|
2600
2710
|
try {
|
|
2601
2711
|
st = statSync(path);
|
|
@@ -2693,7 +2803,7 @@ async function maybeReportTokenUsage(args) {
|
|
|
2693
2803
|
|
|
2694
2804
|
// src/lib/workflow-run-reconciler.ts
|
|
2695
2805
|
import { readdirSync as readdirSync2, readFileSync as readFileSync8, statSync as statSync2 } from "fs";
|
|
2696
|
-
import { join as
|
|
2806
|
+
import { join as join11 } from "path";
|
|
2697
2807
|
var MIN_CHECK_INTERVAL_MS3 = 5 * 6e4;
|
|
2698
2808
|
var SETTLE_MS = 3e4;
|
|
2699
2809
|
var TRANSCRIPT_MTIME_WINDOW_MS2 = 2 * 24 * 60 * 60 * 1e3;
|
|
@@ -2712,7 +2822,7 @@ function collectJsonlRecursive(dir, minMtimeMs, out, depth) {
|
|
|
2712
2822
|
return;
|
|
2713
2823
|
}
|
|
2714
2824
|
for (const name of entries) {
|
|
2715
|
-
const p =
|
|
2825
|
+
const p = join11(dir, name);
|
|
2716
2826
|
let st;
|
|
2717
2827
|
try {
|
|
2718
2828
|
st = statSync2(p);
|
|
@@ -2735,7 +2845,7 @@ function enumerateTranscriptFiles(transcriptDir, nowMs, minMtimeMs = nowMs - TRA
|
|
|
2735
2845
|
return out;
|
|
2736
2846
|
}
|
|
2737
2847
|
for (const name of entries) {
|
|
2738
|
-
const path =
|
|
2848
|
+
const path = join11(transcriptDir, name);
|
|
2739
2849
|
let st;
|
|
2740
2850
|
try {
|
|
2741
2851
|
st = statSync2(path);
|
|
@@ -2747,7 +2857,7 @@ function enumerateTranscriptFiles(transcriptDir, nowMs, minMtimeMs = nowMs - TRA
|
|
|
2747
2857
|
continue;
|
|
2748
2858
|
}
|
|
2749
2859
|
if (st.isDirectory()) {
|
|
2750
|
-
collectJsonlRecursive(
|
|
2860
|
+
collectJsonlRecursive(join11(path, "subagents"), minMtimeMs, out, 0);
|
|
2751
2861
|
}
|
|
2752
2862
|
}
|
|
2753
2863
|
return out;
|
|
@@ -2838,7 +2948,7 @@ async function maybeReconcileWorkflowRunTokens(args) {
|
|
|
2838
2948
|
|
|
2839
2949
|
// src/lib/conversation-evaluator.ts
|
|
2840
2950
|
import { readdirSync as readdirSync3, readFileSync as readFileSync9, statSync as statSync3 } from "fs";
|
|
2841
|
-
import { join as
|
|
2951
|
+
import { join as join12 } from "path";
|
|
2842
2952
|
var MIN_CHECK_INTERVAL_MS4 = 5 * 6e4;
|
|
2843
2953
|
var TRANSCRIPT_MTIME_WINDOW_MS3 = 7 * 24 * 60 * 60 * 1e3;
|
|
2844
2954
|
var WINDOW_PAD_MS = 5 * 6e4;
|
|
@@ -3274,7 +3384,7 @@ function readRecentTurns(dir, nowMs) {
|
|
|
3274
3384
|
return;
|
|
3275
3385
|
}
|
|
3276
3386
|
for (const ent of entries) {
|
|
3277
|
-
const full =
|
|
3387
|
+
const full = join12(d, ent.name);
|
|
3278
3388
|
if (ent.isDirectory()) {
|
|
3279
3389
|
visit(full);
|
|
3280
3390
|
continue;
|
|
@@ -3579,11 +3689,11 @@ async function reportSkip2(api2, agentId, conversationId, log2, codeName) {
|
|
|
3579
3689
|
}
|
|
3580
3690
|
|
|
3581
3691
|
// src/lib/activity-cache-monitor.ts
|
|
3582
|
-
import { existsSync as
|
|
3583
|
-
import { homedir as
|
|
3584
|
-
import { join as
|
|
3692
|
+
import { existsSync as existsSync3, readFileSync as readFileSync10 } from "fs";
|
|
3693
|
+
import { homedir as homedir7 } from "os";
|
|
3694
|
+
import { join as join13 } from "path";
|
|
3585
3695
|
var MIN_CHECK_INTERVAL_MS6 = 6e4;
|
|
3586
|
-
var STATS_CACHE_PATH =
|
|
3696
|
+
var STATS_CACHE_PATH = join13(homedir7(), ".claude", "stats-cache.json");
|
|
3587
3697
|
var ISO_DATE_RE = /^\d{4}-\d{2}-\d{2}$/;
|
|
3588
3698
|
var state5 = { lastObservedDate: null, lastCheckedAt: 0 };
|
|
3589
3699
|
function selectNewDailyRows(raw, lastObservedDate) {
|
|
@@ -3626,7 +3736,7 @@ async function maybeReportActivityCache(args) {
|
|
|
3626
3736
|
const nowMs = now.getTime();
|
|
3627
3737
|
if (nowMs - state5.lastCheckedAt < MIN_CHECK_INTERVAL_MS6) return;
|
|
3628
3738
|
state5.lastCheckedAt = nowMs;
|
|
3629
|
-
if (!
|
|
3739
|
+
if (!existsSync3(STATS_CACHE_PATH)) {
|
|
3630
3740
|
return;
|
|
3631
3741
|
}
|
|
3632
3742
|
let raw;
|
|
@@ -3835,15 +3945,15 @@ function computeChannelConfigHash(input) {
|
|
|
3835
3945
|
}
|
|
3836
3946
|
|
|
3837
3947
|
// src/lib/channel-hash-cache.ts
|
|
3838
|
-
import { existsSync as
|
|
3839
|
-
import { join as
|
|
3948
|
+
import { existsSync as existsSync4, readFileSync as readFileSync11, writeFileSync as writeFileSync5 } from "fs";
|
|
3949
|
+
import { join as join14 } from "path";
|
|
3840
3950
|
var CACHE_FILENAME = "channel-hash-cache.json";
|
|
3841
3951
|
function getChannelHashCacheFile(configDir) {
|
|
3842
|
-
return
|
|
3952
|
+
return join14(configDir, CACHE_FILENAME);
|
|
3843
3953
|
}
|
|
3844
3954
|
function loadChannelHashCache(target, configDir) {
|
|
3845
3955
|
const path = getChannelHashCacheFile(configDir);
|
|
3846
|
-
if (!
|
|
3956
|
+
if (!existsSync4(path)) return;
|
|
3847
3957
|
let parsed;
|
|
3848
3958
|
try {
|
|
3849
3959
|
parsed = JSON.parse(readFileSync11(path, "utf-8"));
|
|
@@ -3866,8 +3976,8 @@ function saveChannelHashCache(source, configDir) {
|
|
|
3866
3976
|
}
|
|
3867
3977
|
|
|
3868
3978
|
// src/lib/sender-policy-baseline.ts
|
|
3869
|
-
import { existsSync as
|
|
3870
|
-
import { join as
|
|
3979
|
+
import { existsSync as existsSync5, readFileSync as readFileSync12 } from "fs";
|
|
3980
|
+
import { join as join15 } from "path";
|
|
3871
3981
|
var BASELINE_FILENAME = "sender-policy-baseline.json";
|
|
3872
3982
|
var SENDER_POLICY_BASELINE_VERSION = 1;
|
|
3873
3983
|
var BASELINE_CONCERNS = ["senderPolicy", "slackBehaviour", "msteamsBehaviour"];
|
|
@@ -3879,11 +3989,11 @@ function createDeliveryBaselineMaps() {
|
|
|
3879
3989
|
};
|
|
3880
3990
|
}
|
|
3881
3991
|
function getSenderPolicyBaselineFile(configDir) {
|
|
3882
|
-
return
|
|
3992
|
+
return join15(configDir, BASELINE_FILENAME);
|
|
3883
3993
|
}
|
|
3884
3994
|
function loadSenderPolicyBaseline(target, configDir, log2) {
|
|
3885
3995
|
const path = getSenderPolicyBaselineFile(configDir);
|
|
3886
|
-
if (!
|
|
3996
|
+
if (!existsSync5(path)) return;
|
|
3887
3997
|
let parsed;
|
|
3888
3998
|
try {
|
|
3889
3999
|
parsed = JSON.parse(readFileSync12(path, "utf-8"));
|
|
@@ -4409,15 +4519,15 @@ function planGlobalSkillSync(globalSkills, prevIds, hashOf, knownHash, options)
|
|
|
4409
4519
|
}
|
|
4410
4520
|
|
|
4411
4521
|
// src/lib/manager/managed-skill-manifest.ts
|
|
4412
|
-
import { existsSync as
|
|
4413
|
-
import { dirname as dirname5, join as
|
|
4522
|
+
import { existsSync as existsSync6, mkdirSync as mkdirSync5, readFileSync as readFileSync13, writeFileSync as writeFileSync6 } from "fs";
|
|
4523
|
+
import { dirname as dirname5, join as join16 } from "path";
|
|
4414
4524
|
var MANIFEST_VERSION = 1;
|
|
4415
4525
|
function managedSkillManifestPath(agentRootDir) {
|
|
4416
|
-
return
|
|
4526
|
+
return join16(agentRootDir, "managed-skills.json");
|
|
4417
4527
|
}
|
|
4418
4528
|
function readManagedSkillManifest(path) {
|
|
4419
4529
|
try {
|
|
4420
|
-
if (!
|
|
4530
|
+
if (!existsSync6(path)) return /* @__PURE__ */ new Set();
|
|
4421
4531
|
const parsed = JSON.parse(readFileSync13(path, "utf-8"));
|
|
4422
4532
|
const ids = Array.isArray(parsed?.globalSkillIds) ? parsed.globalSkillIds : [];
|
|
4423
4533
|
return new Set(ids.filter((id) => typeof id === "string" && id.length > 0));
|
|
@@ -4530,9 +4640,9 @@ function resolveModelChain(refreshData) {
|
|
|
4530
4640
|
}
|
|
4531
4641
|
|
|
4532
4642
|
// src/lib/manager/claude-auth.ts
|
|
4533
|
-
import { existsSync as
|
|
4534
|
-
import { join as
|
|
4535
|
-
import { homedir as
|
|
4643
|
+
import { existsSync as existsSync7, rmSync as rmSync3 } from "fs";
|
|
4644
|
+
import { join as join17 } from "path";
|
|
4645
|
+
import { homedir as homedir8 } from "os";
|
|
4536
4646
|
async function applyClaudeAuthToEnv(childEnv, label) {
|
|
4537
4647
|
const apiKey = getApiKey();
|
|
4538
4648
|
if (!apiKey) {
|
|
@@ -4544,10 +4654,10 @@ async function applyClaudeAuthToEnv(childEnv, label) {
|
|
|
4544
4654
|
throw new Error("claude_auth_mode=api_key but /host/exchange returned no decrypted key");
|
|
4545
4655
|
}
|
|
4546
4656
|
childEnv.ANTHROPIC_API_KEY = exchange.anthropicApiKey;
|
|
4547
|
-
const claudeDir =
|
|
4657
|
+
const claudeDir = join17(homedir8(), ".claude");
|
|
4548
4658
|
for (const filename of [".credentials.json", "credentials.json"]) {
|
|
4549
|
-
const p =
|
|
4550
|
-
if (
|
|
4659
|
+
const p = join17(claudeDir, filename);
|
|
4660
|
+
if (existsSync7(p)) {
|
|
4551
4661
|
try {
|
|
4552
4662
|
rmSync3(p, { force: true });
|
|
4553
4663
|
log(`[${label}] Removed ${p} (api_key mode \u2014 preventing OAuth fallback)`);
|
|
@@ -4561,8 +4671,8 @@ async function applyClaudeAuthToEnv(childEnv, label) {
|
|
|
4561
4671
|
}
|
|
4562
4672
|
|
|
4563
4673
|
// src/lib/manager/kanban/parsers.ts
|
|
4564
|
-
import { existsSync as
|
|
4565
|
-
import { join as
|
|
4674
|
+
import { existsSync as existsSync8, readFileSync as readFileSync14 } from "fs";
|
|
4675
|
+
import { join as join18 } from "path";
|
|
4566
4676
|
var STANDUP_TEMPLATES = /* @__PURE__ */ new Set(["daily-standup", "end-of-day-summary"]);
|
|
4567
4677
|
var TASK_UPDATE_TEMPLATES = /* @__PURE__ */ new Set(["hourly-status", "task-update"]);
|
|
4568
4678
|
var PLAN_TEMPLATES = /* @__PURE__ */ new Set(["morning-plan"]);
|
|
@@ -4701,11 +4811,11 @@ function getBuiltInSkillContent(skillId) {
|
|
|
4701
4811
|
if (builtInSkillCache.has(skillId)) return builtInSkillCache.get(skillId);
|
|
4702
4812
|
try {
|
|
4703
4813
|
const candidates = [
|
|
4704
|
-
|
|
4705
|
-
|
|
4814
|
+
join18(process.cwd(), "skills", skillId, "SKILL.md"),
|
|
4815
|
+
join18(new URL(".", import.meta.url).pathname, "..", "..", "..", "..", "..", "..", "skills", skillId, "SKILL.md")
|
|
4706
4816
|
];
|
|
4707
4817
|
for (const candidate of candidates) {
|
|
4708
|
-
if (
|
|
4818
|
+
if (existsSync8(candidate)) {
|
|
4709
4819
|
const content = readFileSync14(candidate, "utf-8");
|
|
4710
4820
|
const files = [{ relativePath: "SKILL.md", content }];
|
|
4711
4821
|
builtInSkillCache.set(skillId, files);
|
|
@@ -4847,16 +4957,16 @@ function formatBoardForPrompt(items, template) {
|
|
|
4847
4957
|
}
|
|
4848
4958
|
|
|
4849
4959
|
// src/lib/manager/kanban/nudge-state-cache.ts
|
|
4850
|
-
import { existsSync as
|
|
4851
|
-
import { join as
|
|
4960
|
+
import { existsSync as existsSync9, readFileSync as readFileSync15, writeFileSync as writeFileSync7 } from "fs";
|
|
4961
|
+
import { join as join19 } from "path";
|
|
4852
4962
|
var CACHE_FILENAME2 = "kanban-nudge-state.json";
|
|
4853
4963
|
var KANBAN_NUDGE_STATE_VERSION = 1;
|
|
4854
4964
|
function getKanbanNudgeStateFile(configDir) {
|
|
4855
|
-
return
|
|
4965
|
+
return join19(configDir, CACHE_FILENAME2);
|
|
4856
4966
|
}
|
|
4857
4967
|
function loadKanbanNudgeState(target, configDir) {
|
|
4858
4968
|
const path = getKanbanNudgeStateFile(configDir);
|
|
4859
|
-
if (!
|
|
4969
|
+
if (!existsSync9(path)) return;
|
|
4860
4970
|
let parsed;
|
|
4861
4971
|
try {
|
|
4862
4972
|
parsed = JSON.parse(readFileSync15(path, "utf-8"));
|
|
@@ -5459,9 +5569,9 @@ function closeScheduledRunsForCode(codeName, outcome, reason) {
|
|
|
5459
5569
|
|
|
5460
5570
|
// src/lib/manager/scheduler/kanban-route.ts
|
|
5461
5571
|
import { createHash as createHash11 } from "crypto";
|
|
5462
|
-
import { writeFileSync as writeFileSync8, renameSync as
|
|
5463
|
-
import { homedir as
|
|
5464
|
-
import { join as
|
|
5572
|
+
import { writeFileSync as writeFileSync8, renameSync as renameSync3, mkdirSync as mkdirSync6, readFileSync as readFileSync16, unlinkSync } from "fs";
|
|
5573
|
+
import { homedir as homedir9 } from "os";
|
|
5574
|
+
import { join as join20, dirname as dirname6 } from "path";
|
|
5465
5575
|
|
|
5466
5576
|
// src/lib/manager/scheduler/notify.ts
|
|
5467
5577
|
import { createHash as createHash10 } from "crypto";
|
|
@@ -5802,17 +5912,17 @@ function resolveScheduledSlackTarget(task) {
|
|
|
5802
5912
|
}
|
|
5803
5913
|
function stampScheduledTurnMarker(codeName, taskId, target) {
|
|
5804
5914
|
try {
|
|
5805
|
-
const file =
|
|
5915
|
+
const file = join20(homedir9(), ".augmented", codeName, SCHEDULED_TURN_MARKER_FILENAME);
|
|
5806
5916
|
const marker = { ts: Date.now(), task_id: taskId, ...target ? { target } : {} };
|
|
5807
5917
|
const tmp = `${file}.tmp`;
|
|
5808
5918
|
writeFileSync8(tmp, JSON.stringify(marker), "utf8");
|
|
5809
|
-
|
|
5919
|
+
renameSync3(tmp, file);
|
|
5810
5920
|
} catch (err) {
|
|
5811
5921
|
log(`[scheduled-kanban] scheduled-turn marker write failed for '${codeName}': ${err.message}`);
|
|
5812
5922
|
}
|
|
5813
5923
|
}
|
|
5814
5924
|
function clearScheduledTurnMarkerForTask(codeName, taskId) {
|
|
5815
|
-
const file =
|
|
5925
|
+
const file = join20(homedir9(), ".augmented", codeName, SCHEDULED_TURN_MARKER_FILENAME);
|
|
5816
5926
|
try {
|
|
5817
5927
|
const raw = JSON.parse(readFileSync16(file, "utf8"));
|
|
5818
5928
|
if (typeof raw?.task_id !== "string" || raw.task_id !== taskId) return;
|
|
@@ -5874,7 +5984,7 @@ async function routeScheduledTaskViaKanban(codeName, agentId, task, prompt, dura
|
|
|
5874
5984
|
return false;
|
|
5875
5985
|
}
|
|
5876
5986
|
try {
|
|
5877
|
-
const doorbell = directChatDoorbellPath(agentId,
|
|
5987
|
+
const doorbell = directChatDoorbellPath(agentId, homedir9());
|
|
5878
5988
|
mkdirSync6(dirname6(doorbell), { recursive: true });
|
|
5879
5989
|
writeFileSync8(doorbell, String(Date.now()));
|
|
5880
5990
|
} catch (err) {
|
|
@@ -6026,12 +6136,12 @@ async function processClaudeTaskResult(codeName, agentId, templateId, rawOutput,
|
|
|
6026
6136
|
|
|
6027
6137
|
// src/lib/manager/scheduler/execution.ts
|
|
6028
6138
|
import { createHash as createHash12 } from "crypto";
|
|
6029
|
-
import { homedir as
|
|
6030
|
-
import { join as
|
|
6139
|
+
import { homedir as homedir10 } from "os";
|
|
6140
|
+
import { join as join22 } from "path";
|
|
6031
6141
|
|
|
6032
6142
|
// src/lib/agent-serving-probe.ts
|
|
6033
6143
|
import { readFileSync as readFileSync17, readdirSync as readdirSync4, statSync as statSync4 } from "fs";
|
|
6034
|
-
import { join as
|
|
6144
|
+
import { join as join21 } from "path";
|
|
6035
6145
|
var RATE_LIMIT_WINDOW_MS = 6 * 60 * 60 * 1e3;
|
|
6036
6146
|
function probeRateLimit(args) {
|
|
6037
6147
|
const now = args.now ?? /* @__PURE__ */ new Date();
|
|
@@ -6047,7 +6157,7 @@ function probeRateLimit(args) {
|
|
|
6047
6157
|
let newest = UNKNOWN_RATE_LIMIT;
|
|
6048
6158
|
for (const name of entries) {
|
|
6049
6159
|
if (!name.endsWith(".jsonl")) continue;
|
|
6050
|
-
const path =
|
|
6160
|
+
const path = join21(dir, name);
|
|
6051
6161
|
try {
|
|
6052
6162
|
const st = statSync4(path);
|
|
6053
6163
|
if (!st.isFile() || st.mtimeMs < startMs) continue;
|
|
@@ -6118,7 +6228,7 @@ function shouldLogUsageCapDeferral(site, codeName, limitedUntil) {
|
|
|
6118
6228
|
|
|
6119
6229
|
// src/lib/manager/scheduler/execution.ts
|
|
6120
6230
|
function claudePidFilePath() {
|
|
6121
|
-
return
|
|
6231
|
+
return join22(homedir10(), ".augmented", "manager-claude-pids.json");
|
|
6122
6232
|
}
|
|
6123
6233
|
var inFlightClaudePids = /* @__PURE__ */ new Map();
|
|
6124
6234
|
function registerClaudeSpawn(record) {
|
|
@@ -7351,9 +7461,9 @@ async function fireOpencodeScheduledTask(agent, task) {
|
|
|
7351
7461
|
|
|
7352
7462
|
// src/lib/opencode-telegram-ingest.ts
|
|
7353
7463
|
import { createHash as createHash15 } from "crypto";
|
|
7354
|
-
import { existsSync as
|
|
7464
|
+
import { existsSync as existsSync10, mkdirSync as mkdirSync7, readFileSync as readFileSync18, renameSync as renameSync4, unlinkSync as unlinkSync2, writeFileSync as writeFileSync9 } from "fs";
|
|
7355
7465
|
import { randomUUID } from "crypto";
|
|
7356
|
-
import { join as
|
|
7466
|
+
import { join as join23 } from "path";
|
|
7357
7467
|
|
|
7358
7468
|
// src/lib/telegram-ingest.ts
|
|
7359
7469
|
import https2 from "https";
|
|
@@ -7901,7 +8011,7 @@ function createFileOffsetStore(codeName, log2, currentBotId) {
|
|
|
7901
8011
|
let filePath;
|
|
7902
8012
|
try {
|
|
7903
8013
|
dir = getFramework("opencode").getAgentDir(codeName);
|
|
7904
|
-
filePath =
|
|
8014
|
+
filePath = join23(dir, "telegram-getupdates-offset-opencode.json");
|
|
7905
8015
|
} catch {
|
|
7906
8016
|
dir = null;
|
|
7907
8017
|
filePath = null;
|
|
@@ -7939,11 +8049,11 @@ function createFileOffsetStore(codeName, log2, currentBotId) {
|
|
|
7939
8049
|
}),
|
|
7940
8050
|
{ mode: 384 }
|
|
7941
8051
|
);
|
|
7942
|
-
|
|
8052
|
+
renameSync4(tmpPath, filePath);
|
|
7943
8053
|
} catch (err) {
|
|
7944
8054
|
log2(`[telegram-ingest:${codeName}] offset persist failed: ${err instanceof Error ? err.message : String(err)}`);
|
|
7945
8055
|
try {
|
|
7946
|
-
if (
|
|
8056
|
+
if (existsSync10(tmpPath)) unlinkSync2(tmpPath);
|
|
7947
8057
|
} catch {
|
|
7948
8058
|
}
|
|
7949
8059
|
}
|
|
@@ -8180,24 +8290,24 @@ function partitionActionableByPoison(actionable, states, config2) {
|
|
|
8180
8290
|
}
|
|
8181
8291
|
|
|
8182
8292
|
// src/lib/restart-flags.ts
|
|
8183
|
-
import { existsSync as
|
|
8184
|
-
import { homedir as
|
|
8185
|
-
import { join as
|
|
8293
|
+
import { existsSync as existsSync11, mkdirSync as mkdirSync8, readdirSync as readdirSync5, readFileSync as readFileSync19, renameSync as renameSync5, rmSync as rmSync4, writeFileSync as writeFileSync10 } from "fs";
|
|
8294
|
+
import { homedir as homedir11 } from "os";
|
|
8295
|
+
import { join as join24 } from "path";
|
|
8186
8296
|
import { randomUUID as randomUUID2 } from "crypto";
|
|
8187
8297
|
function restartFlagsDir() {
|
|
8188
|
-
return
|
|
8298
|
+
return join24(homedir11(), ".augmented", "restart-flags");
|
|
8189
8299
|
}
|
|
8190
8300
|
function flagPath(codeName) {
|
|
8191
|
-
return
|
|
8301
|
+
return join24(restartFlagsDir(), `${codeName}.flag`);
|
|
8192
8302
|
}
|
|
8193
8303
|
function readRestartFlags() {
|
|
8194
8304
|
const dir = restartFlagsDir();
|
|
8195
|
-
if (!
|
|
8305
|
+
if (!existsSync11(dir)) return [];
|
|
8196
8306
|
const out = [];
|
|
8197
8307
|
for (const entry of readdirSync5(dir)) {
|
|
8198
8308
|
if (!entry.endsWith(".flag")) continue;
|
|
8199
8309
|
try {
|
|
8200
|
-
const raw = readFileSync19(
|
|
8310
|
+
const raw = readFileSync19(join24(dir, entry), "utf8");
|
|
8201
8311
|
const parsed = JSON.parse(raw);
|
|
8202
8312
|
if (typeof parsed.codeName !== "string" || parsed.codeName.length === 0) {
|
|
8203
8313
|
parsed.codeName = entry.replace(/\.flag$/, "");
|
|
@@ -8215,7 +8325,7 @@ function readRestartFlags() {
|
|
|
8215
8325
|
}
|
|
8216
8326
|
function deleteRestartFlag(codeName) {
|
|
8217
8327
|
const path = flagPath(codeName);
|
|
8218
|
-
if (
|
|
8328
|
+
if (existsSync11(path)) {
|
|
8219
8329
|
rmSync4(path, { force: true });
|
|
8220
8330
|
}
|
|
8221
8331
|
}
|
|
@@ -8316,7 +8426,7 @@ async function sendError(flag, opts, text) {
|
|
|
8316
8426
|
|
|
8317
8427
|
// src/lib/restart-context.ts
|
|
8318
8428
|
import { readdirSync as readdirSync6, readFileSync as readFileSync20, writeFileSync as writeFileSync11, mkdirSync as mkdirSync9, unlinkSync as unlinkSync3 } from "fs";
|
|
8319
|
-
import { dirname as dirname7, join as
|
|
8429
|
+
import { dirname as dirname7, join as join25 } from "path";
|
|
8320
8430
|
var SLACK_PENDING_INBOUND_DIRNAME = "slack-pending-inbound";
|
|
8321
8431
|
var SLACK_RESTART_CONTEXT_DIRNAME = "slack-restart-context";
|
|
8322
8432
|
var MAX_TOPIC_CHARS = 140;
|
|
@@ -8328,10 +8438,10 @@ function augmentedAgentDir(codeName) {
|
|
|
8328
8438
|
return dirname7(getProjectDir(codeName));
|
|
8329
8439
|
}
|
|
8330
8440
|
function slackPendingInboundDir(codeName) {
|
|
8331
|
-
return
|
|
8441
|
+
return join25(augmentedAgentDir(codeName), SLACK_PENDING_INBOUND_DIRNAME);
|
|
8332
8442
|
}
|
|
8333
8443
|
function slackRestartContextDir(codeName) {
|
|
8334
|
-
return
|
|
8444
|
+
return join25(augmentedAgentDir(codeName), SLACK_RESTART_CONTEXT_DIRNAME);
|
|
8335
8445
|
}
|
|
8336
8446
|
function sanitizeTopic(raw) {
|
|
8337
8447
|
const cleaned = raw.replace(/\s+/g, " ").trim().replace(/[<>]/g, " ").replace(/\s+/g, " ").trim();
|
|
@@ -8391,7 +8501,7 @@ function pruneHintsExcept(codeName, freshFilenames) {
|
|
|
8391
8501
|
if (!filename.endsWith(".json")) continue;
|
|
8392
8502
|
if (freshFilenames.has(filename)) continue;
|
|
8393
8503
|
try {
|
|
8394
|
-
unlinkSync3(
|
|
8504
|
+
unlinkSync3(join25(ctxDir, filename));
|
|
8395
8505
|
} catch {
|
|
8396
8506
|
}
|
|
8397
8507
|
}
|
|
@@ -8412,7 +8522,7 @@ function refreshSlackRestartContextHints(codeNames, opts = {}) {
|
|
|
8412
8522
|
}
|
|
8413
8523
|
const markers = [];
|
|
8414
8524
|
for (const filename of markerFilenames.slice(0, cap)) {
|
|
8415
|
-
const parsed = readStrandedMarker(
|
|
8525
|
+
const parsed = readStrandedMarker(join25(markerDir, filename));
|
|
8416
8526
|
if (parsed) markers.push({ filename, channel: parsed.channel, thread_ts: parsed.thread_ts });
|
|
8417
8527
|
}
|
|
8418
8528
|
if (markers.length === 0) {
|
|
@@ -8426,7 +8536,7 @@ function refreshSlackRestartContextHints(codeNames, opts = {}) {
|
|
|
8426
8536
|
const freshFilenames = /* @__PURE__ */ new Set();
|
|
8427
8537
|
for (const { filename, hint } of hints) {
|
|
8428
8538
|
try {
|
|
8429
|
-
writeHintFile(
|
|
8539
|
+
writeHintFile(join25(ctxDir, filename), ctxDir, hint);
|
|
8430
8540
|
freshFilenames.add(filename);
|
|
8431
8541
|
} catch (err) {
|
|
8432
8542
|
log2(`[restart-context] ${codeName}: hint write failed for ${filename}: ${err.message}`);
|
|
@@ -9736,7 +9846,7 @@ var runningChannelSecretHashes = /* @__PURE__ */ new Map();
|
|
|
9736
9846
|
var sessionLaunchManagedStructure = /* @__PURE__ */ new Map();
|
|
9737
9847
|
function projectMcpHash(_codeName, projectDir) {
|
|
9738
9848
|
try {
|
|
9739
|
-
const raw = readFileSync21(
|
|
9849
|
+
const raw = readFileSync21(join26(projectDir, ".mcp.json"), "utf-8");
|
|
9740
9850
|
return createHash16("sha256").update(canonicalJson(JSON.parse(raw))).digest("hex");
|
|
9741
9851
|
} catch {
|
|
9742
9852
|
return null;
|
|
@@ -9744,7 +9854,7 @@ function projectMcpHash(_codeName, projectDir) {
|
|
|
9744
9854
|
}
|
|
9745
9855
|
function projectMcpKeys(_codeName, projectDir) {
|
|
9746
9856
|
try {
|
|
9747
|
-
const raw = readFileSync21(
|
|
9857
|
+
const raw = readFileSync21(join26(projectDir, ".mcp.json"), "utf-8");
|
|
9748
9858
|
const parsed = JSON.parse(raw);
|
|
9749
9859
|
const servers = parsed.mcpServers;
|
|
9750
9860
|
if (!servers || typeof servers !== "object") return /* @__PURE__ */ new Set();
|
|
@@ -9762,7 +9872,7 @@ function seedSessionLaunchBaselines(codeName, projectDir) {
|
|
|
9762
9872
|
else runningMcpServerKeys.delete(codeName);
|
|
9763
9873
|
let launchStructure = null;
|
|
9764
9874
|
try {
|
|
9765
|
-
const raw = readFileSync21(
|
|
9875
|
+
const raw = readFileSync21(join26(projectDir, ".mcp.json"), "utf-8");
|
|
9766
9876
|
launchStructure = managedMcpStructureHashFromFile(
|
|
9767
9877
|
JSON.parse(raw),
|
|
9768
9878
|
isManagedMcpServerKey
|
|
@@ -9866,7 +9976,7 @@ async function runAgentSessionToolBindProbes(agent, integrations, projectDir, op
|
|
|
9866
9976
|
if (result && result.rebindCandidates.length > 0 && hostFlagStore().getBoolean("session-tool-rebind")) {
|
|
9867
9977
|
let mcpJsonForRebind = null;
|
|
9868
9978
|
try {
|
|
9869
|
-
mcpJsonForRebind = JSON.parse(readFileSync21(
|
|
9979
|
+
mcpJsonForRebind = JSON.parse(readFileSync21(join26(projectDir, ".mcp.json"), "utf-8"));
|
|
9870
9980
|
} catch {
|
|
9871
9981
|
mcpJsonForRebind = null;
|
|
9872
9982
|
}
|
|
@@ -10010,7 +10120,7 @@ function checkMcpConfigDriftAndScheduleRestart(codeName, projectDir) {
|
|
|
10010
10120
|
function projectChannelSecretHash(projectDir) {
|
|
10011
10121
|
try {
|
|
10012
10122
|
const entries = parseEnvIntegrations(
|
|
10013
|
-
readFileSync21(
|
|
10123
|
+
readFileSync21(join26(projectDir, ".env.integrations"), "utf-8")
|
|
10014
10124
|
);
|
|
10015
10125
|
return channelSecretValueHash(entries, CHANNEL_SECRET_ENV_KEYS);
|
|
10016
10126
|
} catch {
|
|
@@ -10106,7 +10216,7 @@ var agentRestartTimezoneInputs = /* @__PURE__ */ new Map();
|
|
|
10106
10216
|
var lastVersionCheckAt = 0;
|
|
10107
10217
|
var VERSION_CHECK_INTERVAL_MS = 5 * 60 * 1e3;
|
|
10108
10218
|
var lastResponsivenessProbeAt = 0;
|
|
10109
|
-
var agtCliVersion = true ? "0.28.
|
|
10219
|
+
var agtCliVersion = true ? "0.28.493" : "dev";
|
|
10110
10220
|
function resolveBrewPath(execFileSync2) {
|
|
10111
10221
|
try {
|
|
10112
10222
|
const out = execFileSync2("which", ["brew"], { timeout: 5e3 }).toString().trim();
|
|
@@ -10119,7 +10229,7 @@ function resolveBrewPath(execFileSync2) {
|
|
|
10119
10229
|
"/usr/local/bin/brew"
|
|
10120
10230
|
];
|
|
10121
10231
|
for (const path of fallbacks) {
|
|
10122
|
-
if (
|
|
10232
|
+
if (existsSync12(path)) return path;
|
|
10123
10233
|
}
|
|
10124
10234
|
return null;
|
|
10125
10235
|
}
|
|
@@ -10129,7 +10239,7 @@ function claudeBinaryInstalled(execFileSync2) {
|
|
|
10129
10239
|
"/opt/homebrew/bin/claude",
|
|
10130
10240
|
"/usr/local/bin/claude"
|
|
10131
10241
|
];
|
|
10132
|
-
if (canonical.some((path) =>
|
|
10242
|
+
if (canonical.some((path) => existsSync12(path))) return true;
|
|
10133
10243
|
try {
|
|
10134
10244
|
execFileSync2("which", ["claude"], { timeout: 5e3 });
|
|
10135
10245
|
return true;
|
|
@@ -10394,7 +10504,7 @@ function claudeManagedSettingsPath() {
|
|
|
10394
10504
|
function ensureClaudeManagedSettings(path = claudeManagedSettingsPath()) {
|
|
10395
10505
|
try {
|
|
10396
10506
|
let settings = {};
|
|
10397
|
-
if (
|
|
10507
|
+
if (existsSync12(path)) {
|
|
10398
10508
|
const raw = readFileSync21(path, "utf-8").trim();
|
|
10399
10509
|
if (raw) {
|
|
10400
10510
|
let parsed;
|
|
@@ -10450,7 +10560,7 @@ async function ensureOpencodeBinary() {
|
|
|
10450
10560
|
try {
|
|
10451
10561
|
const prefix = execFileSync2("npm", ["prefix", "-g"], { encoding: "utf-8", timeout: 1e4 }).trim();
|
|
10452
10562
|
if (prefix) {
|
|
10453
|
-
const npmBin =
|
|
10563
|
+
const npmBin = join26(prefix, "bin");
|
|
10454
10564
|
const current = (process.env.PATH ?? "").split(pathDelimiter);
|
|
10455
10565
|
if (!current.includes(npmBin)) {
|
|
10456
10566
|
process.env.PATH = [npmBin, ...current.filter(Boolean)].join(pathDelimiter);
|
|
@@ -10511,7 +10621,7 @@ async function ensureFrameworkBinary(frameworkId) {
|
|
|
10511
10621
|
if (!process.env.PATH?.split(":").includes(brewBinDir)) {
|
|
10512
10622
|
process.env.PATH = `${brewBinDir}:${process.env.PATH ?? ""}`;
|
|
10513
10623
|
}
|
|
10514
|
-
if (
|
|
10624
|
+
if (existsSync12("/home/linuxbrew/.linuxbrew/bin/claude")) {
|
|
10515
10625
|
log("Claude Code installed successfully");
|
|
10516
10626
|
} else {
|
|
10517
10627
|
log("Claude Code install completed but binary not found at expected path \u2014 check brew logs");
|
|
@@ -10567,7 +10677,7 @@ ${r.stderr}`;
|
|
|
10567
10677
|
}
|
|
10568
10678
|
var UPDATE_CHECK_INTERVAL_MS = 5 * 60 * 1e3;
|
|
10569
10679
|
function selfUpdateAppliedMarkerPath() {
|
|
10570
|
-
return
|
|
10680
|
+
return join26(homedir12(), ".augmented", ".last-self-update-applied");
|
|
10571
10681
|
}
|
|
10572
10682
|
var selfUpdateUpToDateLogged = false;
|
|
10573
10683
|
var selfUpdatePinnedLogged = false;
|
|
@@ -10595,7 +10705,7 @@ async function checkAndUpdateCli(opts) {
|
|
|
10595
10705
|
const isNpmGlobal = !isBrewFormula && resolvedPath.includes("node_modules");
|
|
10596
10706
|
if (!isBrewFormula && !isNpmGlobal) return "noop";
|
|
10597
10707
|
const { readFileSync: readF, writeFileSync: writeF } = await import("fs");
|
|
10598
|
-
const markerPath =
|
|
10708
|
+
const markerPath = join26(homedir12(), ".augmented", ".last-update-check");
|
|
10599
10709
|
if (!force) {
|
|
10600
10710
|
try {
|
|
10601
10711
|
const lastCheck = parseInt(readF(markerPath, "utf-8").trim(), 10);
|
|
@@ -10954,13 +11064,13 @@ async function checkClaudeAuth() {
|
|
|
10954
11064
|
}
|
|
10955
11065
|
var evalEmptyMcpConfigPath = null;
|
|
10956
11066
|
function ensureEvalEmptyMcpConfig() {
|
|
10957
|
-
if (evalEmptyMcpConfigPath &&
|
|
10958
|
-
const dir =
|
|
11067
|
+
if (evalEmptyMcpConfigPath && existsSync12(evalEmptyMcpConfigPath)) return evalEmptyMcpConfigPath;
|
|
11068
|
+
const dir = join26(homedir12(), ".augmented");
|
|
10959
11069
|
try {
|
|
10960
11070
|
mkdirSync10(dir, { recursive: true });
|
|
10961
11071
|
} catch {
|
|
10962
11072
|
}
|
|
10963
|
-
const p =
|
|
11073
|
+
const p = join26(dir, ".eval-empty-mcp.json");
|
|
10964
11074
|
writeFileSync12(p, JSON.stringify({ mcpServers: {} }));
|
|
10965
11075
|
evalEmptyMcpConfigPath = p;
|
|
10966
11076
|
return p;
|
|
@@ -10986,7 +11096,7 @@ async function runEvalClaude(prompt, model) {
|
|
|
10986
11096
|
""
|
|
10987
11097
|
];
|
|
10988
11098
|
const { stdout } = await execFilePromiseLong(resolveClaudeBinary(), args, {
|
|
10989
|
-
cwd:
|
|
11099
|
+
cwd: homedir12(),
|
|
10990
11100
|
timeout: 12e4,
|
|
10991
11101
|
stdin: "ignore",
|
|
10992
11102
|
env: childEnv,
|
|
@@ -11052,10 +11162,10 @@ function resolveConversationEvalBackend() {
|
|
|
11052
11162
|
return conversationEvalBackend;
|
|
11053
11163
|
}
|
|
11054
11164
|
function getStateFile() {
|
|
11055
|
-
return
|
|
11165
|
+
return join26(config?.configDir ?? join26(process.env["HOME"] ?? "/tmp", ".augmented"), "manager-state.json");
|
|
11056
11166
|
}
|
|
11057
11167
|
function channelHashCacheDir() {
|
|
11058
|
-
return config?.configDir ??
|
|
11168
|
+
return config?.configDir ?? join26(process.env["HOME"] ?? "/tmp", ".augmented");
|
|
11059
11169
|
}
|
|
11060
11170
|
function loadChannelHashCache2() {
|
|
11061
11171
|
loadChannelHashCache(agentState.knownChannelConfigHashes, channelHashCacheDir());
|
|
@@ -11109,7 +11219,7 @@ function removeDeliveryBaselineEntries(agentId) {
|
|
|
11109
11219
|
var _channelQuarantineStore = null;
|
|
11110
11220
|
function channelQuarantineStore() {
|
|
11111
11221
|
if (!_channelQuarantineStore) {
|
|
11112
|
-
const dir = config?.configDir ??
|
|
11222
|
+
const dir = config?.configDir ?? join26(process.env["HOME"] ?? "/tmp", ".augmented");
|
|
11113
11223
|
_channelQuarantineStore = new ChannelQuarantineStore(defaultQuarantinePath(dir));
|
|
11114
11224
|
}
|
|
11115
11225
|
return _channelQuarantineStore;
|
|
@@ -11126,7 +11236,7 @@ function claudeMdSizeFor(codeName) {
|
|
|
11126
11236
|
var _hostFlagStore = null;
|
|
11127
11237
|
function hostFlagStore() {
|
|
11128
11238
|
if (!_hostFlagStore) {
|
|
11129
|
-
const dir = config?.configDir ??
|
|
11239
|
+
const dir = config?.configDir ?? join26(process.env["HOME"] ?? "/tmp", ".augmented");
|
|
11130
11240
|
_hostFlagStore = new HostFlagStore({ cachePath: defaultFlagsCachePath(dir), log });
|
|
11131
11241
|
}
|
|
11132
11242
|
return _hostFlagStore;
|
|
@@ -11197,12 +11307,12 @@ function parseSkillFrontmatter(content) {
|
|
|
11197
11307
|
}
|
|
11198
11308
|
async function refreshSkillsIndexInClaudeMd(configDir, codeName, log2) {
|
|
11199
11309
|
const { readdirSync: readdirSync8, readFileSync: rfs, existsSync: ex, writeFileSync: writeFileSync13 } = await import("fs");
|
|
11200
|
-
const skillsDir =
|
|
11201
|
-
const claudeMdPath =
|
|
11310
|
+
const skillsDir = join26(configDir, codeName, "project", ".claude", "skills");
|
|
11311
|
+
const claudeMdPath = join26(configDir, codeName, "project", "CLAUDE.md");
|
|
11202
11312
|
if (!ex(skillsDir) || !ex(claudeMdPath)) return;
|
|
11203
11313
|
const entries = [];
|
|
11204
11314
|
for (const dir of readdirSync8(skillsDir).sort()) {
|
|
11205
|
-
const skillFile =
|
|
11315
|
+
const skillFile = join26(skillsDir, dir, "SKILL.md");
|
|
11206
11316
|
if (!ex(skillFile)) continue;
|
|
11207
11317
|
try {
|
|
11208
11318
|
const { name, description } = parseSkillFrontmatter(rfs(skillFile, "utf-8"));
|
|
@@ -11269,7 +11379,7 @@ function flushRestartedAgentDiagnostics(hostId, codeNames) {
|
|
|
11269
11379
|
if (codeNames.length === 0) return;
|
|
11270
11380
|
void (async () => {
|
|
11271
11381
|
try {
|
|
11272
|
-
const { collectDiagnostics } = await import("../persistent-session-
|
|
11382
|
+
const { collectDiagnostics } = await import("../persistent-session-MVAEGE6J.js");
|
|
11273
11383
|
await api.post("/host/heartbeat", {
|
|
11274
11384
|
host_id: hostId,
|
|
11275
11385
|
agent_diagnostics: collectDiagnostics(codeNames, quarantineEntriesFor, claudeMdSizeFor)
|
|
@@ -11376,7 +11486,7 @@ async function pollCycle() {
|
|
|
11376
11486
|
}
|
|
11377
11487
|
try {
|
|
11378
11488
|
const { detectHostSecurity } = await import("../host-security-6PDFG7F5.js");
|
|
11379
|
-
const { collectDiagnostics } = await import("../persistent-session-
|
|
11489
|
+
const { collectDiagnostics } = await import("../persistent-session-MVAEGE6J.js");
|
|
11380
11490
|
const diagCodeNames = [...agentState.persistentSessionAgents];
|
|
11381
11491
|
const agentDiagnostics = diagCodeNames.length > 0 ? collectDiagnostics(diagCodeNames, quarantineEntriesFor, claudeMdSizeFor) : void 0;
|
|
11382
11492
|
let tailscaleHostname;
|
|
@@ -11468,6 +11578,7 @@ async function pollCycle() {
|
|
|
11468
11578
|
hostFlagStore().applyHeartbeat(hbResp.feature_flags, hbResp.flags_schema_version);
|
|
11469
11579
|
}
|
|
11470
11580
|
hostFlagStore().applyNotifyDispatchByAgent(hbResp?.notify_dispatch_by_agent);
|
|
11581
|
+
hostFlagStore().applyBooleanFlagsByAgent(hbResp?.feature_flags_by_agent);
|
|
11471
11582
|
setConfigHash(hbResp?.config_hash ?? null);
|
|
11472
11583
|
try {
|
|
11473
11584
|
if (decideMaintenanceWindowGate({ window: cachedMaintenanceWindow, now: /* @__PURE__ */ new Date() }) === "proceed") {
|
|
@@ -11490,7 +11601,7 @@ async function pollCycle() {
|
|
|
11490
11601
|
collectResponsivenessProbes,
|
|
11491
11602
|
collectPanelessActivityProbes,
|
|
11492
11603
|
getResponsivenessIntervalMs
|
|
11493
|
-
} = await import("../responsiveness-probe-
|
|
11604
|
+
} = await import("../responsiveness-probe-6YXN4G6V.js");
|
|
11494
11605
|
const probeIntervalMs = getResponsivenessIntervalMs();
|
|
11495
11606
|
if (now - lastResponsivenessProbeAt > probeIntervalMs) {
|
|
11496
11607
|
const probeCodeNames = [...agentState.persistentSessionAgents];
|
|
@@ -11554,7 +11665,7 @@ async function pollCycle() {
|
|
|
11554
11665
|
collectResponsivenessProbes,
|
|
11555
11666
|
livePendingInboundOldestAgeSeconds,
|
|
11556
11667
|
parkPendingInbound
|
|
11557
|
-
} = await import("../responsiveness-probe-
|
|
11668
|
+
} = await import("../responsiveness-probe-6YXN4G6V.js");
|
|
11558
11669
|
const { getProjectDir: wedgeProjectDir } = await import("../scheduler-engine-NDP36U7O.js");
|
|
11559
11670
|
const wedgeNow = /* @__PURE__ */ new Date();
|
|
11560
11671
|
const liveAgents = agentState.persistentSessionAgents;
|
|
@@ -11646,10 +11757,10 @@ async function pollCycle() {
|
|
|
11646
11757
|
const paneTail = readFileSync21(paneLogPath(codeName), "utf8").slice(-65536);
|
|
11647
11758
|
const transient = detectTransientApiErrorInLog(paneTail);
|
|
11648
11759
|
if (transient) {
|
|
11649
|
-
const wedgeHome =
|
|
11650
|
-
if (
|
|
11760
|
+
const wedgeHome = join26(homedir12(), ".augmented", codeName);
|
|
11761
|
+
if (existsSync12(wedgeHome)) {
|
|
11651
11762
|
atomicWriteFileSync(
|
|
11652
|
-
|
|
11763
|
+
join26(wedgeHome, "watchdog-give-up.json"),
|
|
11653
11764
|
JSON.stringify({
|
|
11654
11765
|
gave_up_at: wedgeNow.toISOString(),
|
|
11655
11766
|
reason: "transient_overload"
|
|
@@ -11920,7 +12031,7 @@ async function pollCycle() {
|
|
|
11920
12031
|
const adapter = resolveAgentFramework(prev.codeName);
|
|
11921
12032
|
stopAgentRuntime2(prev.codeName, "removed-from-host");
|
|
11922
12033
|
killAgentChannelProcesses(prev.codeName, { log });
|
|
11923
|
-
const agentDir =
|
|
12034
|
+
const agentDir = join26(adapter.getAgentDir(prev.codeName), "provision");
|
|
11924
12035
|
await cleanupAgentFiles(prev.codeName, agentDir);
|
|
11925
12036
|
clearAgentCaches(prev.agentId, prev.codeName);
|
|
11926
12037
|
}
|
|
@@ -12007,10 +12118,10 @@ async function pollCycle() {
|
|
|
12007
12118
|
// pending-inbound marker. Best-effort: a write failure is logged by
|
|
12008
12119
|
// the watchdog, never fails the poll cycle.
|
|
12009
12120
|
signalGiveUp: (codeName) => {
|
|
12010
|
-
const dir =
|
|
12011
|
-
if (!
|
|
12121
|
+
const dir = join26(homedir12(), ".augmented", codeName);
|
|
12122
|
+
if (!existsSync12(dir)) return;
|
|
12012
12123
|
atomicWriteFileSync(
|
|
12013
|
-
|
|
12124
|
+
join26(dir, "watchdog-give-up.json"),
|
|
12014
12125
|
JSON.stringify({ gave_up_at: (/* @__PURE__ */ new Date()).toISOString() })
|
|
12015
12126
|
);
|
|
12016
12127
|
}
|
|
@@ -12152,7 +12263,7 @@ async function processAgent(agent, agentStates) {
|
|
|
12152
12263
|
}
|
|
12153
12264
|
const now = (/* @__PURE__ */ new Date()).toISOString();
|
|
12154
12265
|
const adapter = resolveAgentFramework(agent.code_name);
|
|
12155
|
-
let agentDir =
|
|
12266
|
+
let agentDir = join26(adapter.getAgentDir(agent.code_name), "provision");
|
|
12156
12267
|
if (agent.status === "draft" || agent.status === "paused") {
|
|
12157
12268
|
if (previousKnownStatus !== agent.status) {
|
|
12158
12269
|
log(`Agent '${agent.code_name}' is ${agent.status}, skipping provisioning`);
|
|
@@ -12192,7 +12303,7 @@ async function processAgent(agent, agentStates) {
|
|
|
12192
12303
|
const residuals = {
|
|
12193
12304
|
gatewayRunning: false,
|
|
12194
12305
|
portAllocated: false,
|
|
12195
|
-
provisionDirExists:
|
|
12306
|
+
provisionDirExists: existsSync12(agentDir)
|
|
12196
12307
|
};
|
|
12197
12308
|
if (!hasRevokedResiduals(residuals)) {
|
|
12198
12309
|
agentStates.push({
|
|
@@ -12326,7 +12437,7 @@ async function processAgent(agent, agentStates) {
|
|
|
12326
12437
|
const frameworkId = refreshData.agent.framework ?? DEFAULT_FRAMEWORK;
|
|
12327
12438
|
agentFrameworkCache.set(agent.code_name, frameworkId);
|
|
12328
12439
|
const frameworkAdapter = getFramework(frameworkId);
|
|
12329
|
-
agentDir =
|
|
12440
|
+
agentDir = join26(frameworkAdapter.getAgentDir(agent.code_name), "provision");
|
|
12330
12441
|
cacheAgentDeliveryMetadata(agent.code_name, refreshData);
|
|
12331
12442
|
agentRestartTimezoneInputs.set(agent.code_name, {
|
|
12332
12443
|
agentTimezone: typeof refreshData.agent.timezone === "string" ? refreshData.agent.timezone : null,
|
|
@@ -12375,7 +12486,7 @@ async function processAgent(agent, agentStates) {
|
|
|
12375
12486
|
const changedFiles = [];
|
|
12376
12487
|
mkdirSync10(agentDir, { recursive: true });
|
|
12377
12488
|
for (const artifact of artifacts) {
|
|
12378
|
-
const filePath =
|
|
12489
|
+
const filePath = join26(agentDir, artifact.relativePath);
|
|
12379
12490
|
let existingHash;
|
|
12380
12491
|
let newHash;
|
|
12381
12492
|
let writeContent = artifact.content;
|
|
@@ -12394,7 +12505,7 @@ async function processAgent(agent, agentStates) {
|
|
|
12394
12505
|
};
|
|
12395
12506
|
newHash = sha256(stripDynamicSections(artifact.content));
|
|
12396
12507
|
try {
|
|
12397
|
-
const projectClaudeMd =
|
|
12508
|
+
const projectClaudeMd = join26(config.configDir, agent.code_name, "project", "CLAUDE.md");
|
|
12398
12509
|
const existing = readFileSync21(projectClaudeMd, "utf-8");
|
|
12399
12510
|
existingHash = sha256(stripDynamicSections(existing));
|
|
12400
12511
|
} catch {
|
|
@@ -12445,12 +12556,12 @@ async function processAgent(agent, agentStates) {
|
|
|
12445
12556
|
}
|
|
12446
12557
|
}
|
|
12447
12558
|
if (changedFiles.length > 0) {
|
|
12448
|
-
const isFirst = !
|
|
12559
|
+
const isFirst = !existsSync12(join26(agentDir, "CHARTER.md"));
|
|
12449
12560
|
const verb = isFirst ? "Provisioning" : "Updating";
|
|
12450
12561
|
const fileNames = changedFiles.map((f) => f.relativePath).join(", ");
|
|
12451
12562
|
log(`${verb} '${agent.code_name}': ${fileNames}`);
|
|
12452
12563
|
for (const file of changedFiles) {
|
|
12453
|
-
const filePath =
|
|
12564
|
+
const filePath = join26(agentDir, file.relativePath);
|
|
12454
12565
|
mkdirSync10(dirname8(filePath), { recursive: true });
|
|
12455
12566
|
if (file.relativePath === ".mcp.json") {
|
|
12456
12567
|
safeWriteJsonAtomic(filePath, file.content, { mode: 384 });
|
|
@@ -12459,12 +12570,12 @@ async function processAgent(agent, agentStates) {
|
|
|
12459
12570
|
}
|
|
12460
12571
|
}
|
|
12461
12572
|
try {
|
|
12462
|
-
const provSkillsDir =
|
|
12463
|
-
if (
|
|
12573
|
+
const provSkillsDir = join26(agentDir, ".claude", "skills");
|
|
12574
|
+
if (existsSync12(provSkillsDir)) {
|
|
12464
12575
|
for (const folder of readdirSync7(provSkillsDir)) {
|
|
12465
12576
|
if (folder.startsWith("knowledge-")) {
|
|
12466
12577
|
try {
|
|
12467
|
-
rmSync5(
|
|
12578
|
+
rmSync5(join26(provSkillsDir, folder), { recursive: true });
|
|
12468
12579
|
} catch {
|
|
12469
12580
|
}
|
|
12470
12581
|
}
|
|
@@ -12477,7 +12588,7 @@ async function processAgent(agent, agentStates) {
|
|
|
12477
12588
|
const trackedFiles2 = frameworkAdapter.driftTrackedFiles();
|
|
12478
12589
|
const hashes = /* @__PURE__ */ new Map();
|
|
12479
12590
|
for (const file of trackedFiles2) {
|
|
12480
|
-
const h = hashFile(
|
|
12591
|
+
const h = hashFile(join26(agentDir, file));
|
|
12481
12592
|
if (h) hashes.set(file, h);
|
|
12482
12593
|
}
|
|
12483
12594
|
agentState.writtenHashes.set(agent.agent_id, hashes);
|
|
@@ -12495,14 +12606,14 @@ async function processAgent(agent, agentStates) {
|
|
|
12495
12606
|
}
|
|
12496
12607
|
if (Array.isArray(refreshData.workflows)) {
|
|
12497
12608
|
try {
|
|
12498
|
-
const provWorkflowsDir =
|
|
12499
|
-
if (
|
|
12609
|
+
const provWorkflowsDir = join26(agentDir, ".claude", "workflows");
|
|
12610
|
+
if (existsSync12(provWorkflowsDir)) {
|
|
12500
12611
|
const expected = new Set(refreshData.workflows.map((w) => `${w.name}.js`));
|
|
12501
12612
|
for (const file of readdirSync7(provWorkflowsDir)) {
|
|
12502
12613
|
if (!file.endsWith(".js")) continue;
|
|
12503
12614
|
if (expected.has(file)) continue;
|
|
12504
12615
|
try {
|
|
12505
|
-
rmSync5(
|
|
12616
|
+
rmSync5(join26(provWorkflowsDir, file));
|
|
12506
12617
|
} catch {
|
|
12507
12618
|
}
|
|
12508
12619
|
}
|
|
@@ -12581,10 +12692,10 @@ async function processAgent(agent, agentStates) {
|
|
|
12581
12692
|
}
|
|
12582
12693
|
let lastDriftCheckAt = now;
|
|
12583
12694
|
const written = agentState.writtenHashes.get(agent.agent_id);
|
|
12584
|
-
if (written &&
|
|
12695
|
+
if (written && existsSync12(agentDir)) {
|
|
12585
12696
|
const driftedFiles = [];
|
|
12586
12697
|
for (const [file, expectedHash] of written) {
|
|
12587
|
-
const localHash = hashFile(
|
|
12698
|
+
const localHash = hashFile(join26(agentDir, file));
|
|
12588
12699
|
if (localHash && localHash !== expectedHash) {
|
|
12589
12700
|
driftedFiles.push(file);
|
|
12590
12701
|
}
|
|
@@ -12595,7 +12706,7 @@ async function processAgent(agent, agentStates) {
|
|
|
12595
12706
|
try {
|
|
12596
12707
|
const localHashes = {};
|
|
12597
12708
|
for (const file of driftedFiles) {
|
|
12598
|
-
localHashes[file] = hashFile(
|
|
12709
|
+
localHashes[file] = hashFile(join26(agentDir, file));
|
|
12599
12710
|
}
|
|
12600
12711
|
await api.post("/host/drift", {
|
|
12601
12712
|
agent_id: agent.agent_id,
|
|
@@ -12797,7 +12908,7 @@ async function processAgent(agent, agentStates) {
|
|
|
12797
12908
|
const addedChannels = [...restartDecision.added];
|
|
12798
12909
|
const writeDmNoticeMarkers = isChannelAddRestart ? () => {
|
|
12799
12910
|
try {
|
|
12800
|
-
const agentAugmentedDir =
|
|
12911
|
+
const agentAugmentedDir = join26(homedir12(), ".augmented", agent.code_name);
|
|
12801
12912
|
mkdirSync10(agentAugmentedDir, { recursive: true });
|
|
12802
12913
|
const markerJson = JSON.stringify({
|
|
12803
12914
|
version: 1,
|
|
@@ -12805,7 +12916,7 @@ async function processAgent(agent, agentStates) {
|
|
|
12805
12916
|
added: addedChannels
|
|
12806
12917
|
});
|
|
12807
12918
|
for (const file of ["slack-channel-add-restart.json", "telegram-channel-add-restart.json"]) {
|
|
12808
|
-
atomicWriteFileSync(
|
|
12919
|
+
atomicWriteFileSync(join26(agentAugmentedDir, file), markerJson);
|
|
12809
12920
|
}
|
|
12810
12921
|
} catch (err) {
|
|
12811
12922
|
log(`[hot-reload] channel-add DM-notice marker write failed for '${agent.code_name}' (non-fatal): ${err.message}`);
|
|
@@ -12994,24 +13105,24 @@ async function processAgent(agent, agentStates) {
|
|
|
12994
13105
|
if (agentSessionMode === "persistent" && (agentFrameworkCache.get(agent.code_name) ?? DEFAULT_FRAMEWORK) === "claude-code") {
|
|
12995
13106
|
try {
|
|
12996
13107
|
const agentProvisionDir = agentDir;
|
|
12997
|
-
const projectDir =
|
|
13108
|
+
const projectDir = join26(homedir12(), ".augmented", agent.code_name, "project");
|
|
12998
13109
|
mkdirSync10(agentProvisionDir, { recursive: true });
|
|
12999
13110
|
mkdirSync10(projectDir, { recursive: true });
|
|
13000
|
-
const provisionMcpPath =
|
|
13001
|
-
const projectMcpPath =
|
|
13111
|
+
const provisionMcpPath = join26(agentProvisionDir, ".mcp.json");
|
|
13112
|
+
const projectMcpPath = join26(projectDir, ".mcp.json");
|
|
13002
13113
|
let mcpConfig = { mcpServers: {} };
|
|
13003
13114
|
try {
|
|
13004
13115
|
mcpConfig = JSON.parse(readFileSync21(provisionMcpPath, "utf-8"));
|
|
13005
13116
|
if (!mcpConfig.mcpServers) mcpConfig.mcpServers = {};
|
|
13006
13117
|
} catch {
|
|
13007
13118
|
}
|
|
13008
|
-
const localDirectChatChannel =
|
|
13119
|
+
const localDirectChatChannel = join26(homedir12(), ".augmented", "_mcp", "direct-chat-channel.js");
|
|
13009
13120
|
const directChatTeamSettings = refreshData.team?.settings;
|
|
13010
13121
|
const directChatTz = (() => {
|
|
13011
13122
|
const tz = directChatTeamSettings?.["timezone"];
|
|
13012
13123
|
return typeof tz === "string" && tz.trim() !== "" ? tz.trim() : void 0;
|
|
13013
13124
|
})();
|
|
13014
|
-
if (
|
|
13125
|
+
if (existsSync12(localDirectChatChannel)) {
|
|
13015
13126
|
const directChatEnv = {
|
|
13016
13127
|
AGT_HOST: requireHost(),
|
|
13017
13128
|
// ENG-5901 Track D: templated — the manager exports the real
|
|
@@ -13031,7 +13142,7 @@ async function processAgent(agent, agentStates) {
|
|
|
13031
13142
|
// ~/.augmented/<codeName>/.current-turn-initiator.json. Note getAgentDir
|
|
13032
13143
|
// returns the agent root (NOT the /provision subdir `agentDir` points at),
|
|
13033
13144
|
// so it byte-matches the broker readers' path.
|
|
13034
|
-
AGT_TURN_INITIATOR_FILE:
|
|
13145
|
+
AGT_TURN_INITIATOR_FILE: join26(
|
|
13035
13146
|
frameworkAdapter.getAgentDir(agent.code_name),
|
|
13036
13147
|
".current-turn-initiator.json"
|
|
13037
13148
|
)
|
|
@@ -13051,8 +13162,8 @@ async function processAgent(agent, agentStates) {
|
|
|
13051
13162
|
log(`Channel credentials written for '${agent.code_name}/direct-chat'`);
|
|
13052
13163
|
}
|
|
13053
13164
|
}
|
|
13054
|
-
const staleChannelsPath =
|
|
13055
|
-
if (
|
|
13165
|
+
const staleChannelsPath = join26(projectDir, ".mcp-channels.json");
|
|
13166
|
+
if (existsSync12(staleChannelsPath)) {
|
|
13056
13167
|
try {
|
|
13057
13168
|
rmSync5(staleChannelsPath, { force: true });
|
|
13058
13169
|
} catch {
|
|
@@ -13141,7 +13252,7 @@ async function processAgent(agent, agentStates) {
|
|
|
13141
13252
|
}
|
|
13142
13253
|
if (hostFlagStore().getBoolean("connectivity-probe")) {
|
|
13143
13254
|
try {
|
|
13144
|
-
const probeProjectDir =
|
|
13255
|
+
const probeProjectDir = join26(homedir12(), ".augmented", agent.code_name, "project");
|
|
13145
13256
|
let probeSet = integrations;
|
|
13146
13257
|
try {
|
|
13147
13258
|
const quarantined = await api.post("/host/agent-integrations/quarantined", { agent_id: agent.agent_id });
|
|
@@ -13187,7 +13298,7 @@ async function processAgent(agent, agentStates) {
|
|
|
13187
13298
|
const forceDue = attemptsLeft > 0;
|
|
13188
13299
|
let probeRan = false;
|
|
13189
13300
|
try {
|
|
13190
|
-
const probeProjectDir =
|
|
13301
|
+
const probeProjectDir = join26(homedir12(), ".augmented", agent.code_name, "project");
|
|
13191
13302
|
probeRan = await runAgentSessionToolBindProbes(agent, integrations, probeProjectDir, { forceDue });
|
|
13192
13303
|
} catch (err) {
|
|
13193
13304
|
log(`Session-tool-bind probe failed for '${agent.code_name}': ${err.message}`);
|
|
@@ -13264,8 +13375,8 @@ async function processAgent(agent, agentStates) {
|
|
|
13264
13375
|
const intHash = computeIntegrationsHash(integrations);
|
|
13265
13376
|
const prevIntHash = agentState.knownIntegrationHashes.get(agent.agent_id);
|
|
13266
13377
|
if (intHash !== prevIntHash) {
|
|
13267
|
-
const projectDir =
|
|
13268
|
-
const envIntPath =
|
|
13378
|
+
const projectDir = join26(homedir12(), ".augmented", agent.code_name, "project");
|
|
13379
|
+
const envIntPath = join26(projectDir, ".env.integrations");
|
|
13269
13380
|
let preWriteEnv;
|
|
13270
13381
|
try {
|
|
13271
13382
|
preWriteEnv = readFileSync21(envIntPath, "utf-8");
|
|
@@ -13287,7 +13398,7 @@ async function processAgent(agent, agentStates) {
|
|
|
13287
13398
|
}
|
|
13288
13399
|
if (fw === "claude-code" && isSessionHealthy(agent.code_name)) {
|
|
13289
13400
|
try {
|
|
13290
|
-
const projectMcpPath =
|
|
13401
|
+
const projectMcpPath = join26(projectDir, ".mcp.json");
|
|
13291
13402
|
const postWriteEnv = readFileSync21(envIntPath, "utf-8");
|
|
13292
13403
|
const mcpContent = readFileSync21(projectMcpPath, "utf-8");
|
|
13293
13404
|
const changedVars = diffEnvIntegrations(preWriteEnv, postWriteEnv);
|
|
@@ -13542,18 +13653,18 @@ async function processAgent(agent, agentStates) {
|
|
|
13542
13653
|
}
|
|
13543
13654
|
try {
|
|
13544
13655
|
const { readdirSync: readdirSync8, rmSync: rmSync6 } = await import("fs");
|
|
13545
|
-
const { homedir:
|
|
13656
|
+
const { homedir: homedir13 } = await import("os");
|
|
13546
13657
|
const frameworkId2 = frameworkAdapter.id;
|
|
13547
13658
|
const candidateSkillDirs = [
|
|
13548
13659
|
// Claude Code — framework runtime tree
|
|
13549
|
-
|
|
13660
|
+
join26(homedir13(), ".augmented", agent.code_name, "skills"),
|
|
13550
13661
|
// Claude Code — project tree
|
|
13551
|
-
|
|
13662
|
+
join26(homedir13(), ".augmented", agent.code_name, "project", ".claude", "skills"),
|
|
13552
13663
|
// Defensive: legacy provision-side path, not currently an
|
|
13553
13664
|
// install target but cheap to sweep.
|
|
13554
|
-
|
|
13665
|
+
join26(agentDir, ".claude", "skills")
|
|
13555
13666
|
];
|
|
13556
|
-
const existingDirs = candidateSkillDirs.filter((d) =>
|
|
13667
|
+
const existingDirs = candidateSkillDirs.filter((d) => existsSync12(d));
|
|
13557
13668
|
const discoveredEntries = /* @__PURE__ */ new Set();
|
|
13558
13669
|
for (const dir of existingDirs) {
|
|
13559
13670
|
try {
|
|
@@ -13567,8 +13678,8 @@ async function processAgent(agent, agentStates) {
|
|
|
13567
13678
|
}
|
|
13568
13679
|
const removeSkillFolder = (entry, reason) => {
|
|
13569
13680
|
for (const dir of existingDirs) {
|
|
13570
|
-
const p =
|
|
13571
|
-
if (
|
|
13681
|
+
const p = join26(dir, entry);
|
|
13682
|
+
if (existsSync12(p)) {
|
|
13572
13683
|
rmSync6(p, { recursive: true, force: true });
|
|
13573
13684
|
}
|
|
13574
13685
|
}
|
|
@@ -13587,7 +13698,7 @@ async function processAgent(agent, agentStates) {
|
|
|
13587
13698
|
const sharedSkillsPayload = refreshAny.shared_skills;
|
|
13588
13699
|
const desiredResolved = globalSkillsPayload !== void 0 || sharedSkillsPayload !== void 0;
|
|
13589
13700
|
const manifestPath = managedSkillManifestPath(
|
|
13590
|
-
|
|
13701
|
+
join26(homedir12(), ".augmented", agent.code_name)
|
|
13591
13702
|
);
|
|
13592
13703
|
const prevIds = /* @__PURE__ */ new Set([
|
|
13593
13704
|
...agentState.knownGlobalSkillIds.get(agent.agent_id) ?? /* @__PURE__ */ new Set(),
|
|
@@ -13607,15 +13718,15 @@ async function processAgent(agent, agentStates) {
|
|
|
13607
13718
|
}
|
|
13608
13719
|
if (plan.removes.length) {
|
|
13609
13720
|
const globalSkillDirs = [
|
|
13610
|
-
|
|
13611
|
-
|
|
13612
|
-
|
|
13721
|
+
join26(homedir12(), ".augmented", agent.code_name, "skills"),
|
|
13722
|
+
join26(homedir12(), ".augmented", agent.code_name, "project", ".claude", "skills"),
|
|
13723
|
+
join26(agentDir, ".claude", "skills")
|
|
13613
13724
|
];
|
|
13614
13725
|
for (const id of plan.removes) {
|
|
13615
13726
|
let prunedAny = false;
|
|
13616
13727
|
for (const dir of globalSkillDirs) {
|
|
13617
|
-
const p =
|
|
13618
|
-
if (
|
|
13728
|
+
const p = join26(dir, id);
|
|
13729
|
+
if (existsSync12(p) && existsSync12(join26(p, "SKILL.md"))) {
|
|
13619
13730
|
rmSync5(p, { recursive: true, force: true });
|
|
13620
13731
|
prunedAny = true;
|
|
13621
13732
|
}
|
|
@@ -13846,7 +13957,7 @@ async function processAgent(agent, agentStates) {
|
|
|
13846
13957
|
const sess = getSessionState(agent.code_name);
|
|
13847
13958
|
let mcpJsonParsed = null;
|
|
13848
13959
|
try {
|
|
13849
|
-
const mcpPath =
|
|
13960
|
+
const mcpPath = join26(getProjectDir(agent.code_name), ".mcp.json");
|
|
13850
13961
|
mcpJsonParsed = JSON.parse(readFileSync21(mcpPath, "utf-8"));
|
|
13851
13962
|
} catch {
|
|
13852
13963
|
}
|
|
@@ -14270,10 +14381,10 @@ Retried to the limit after repeated stalls \u2014 needs a look.`).catch(() => {
|
|
|
14270
14381
|
}
|
|
14271
14382
|
}
|
|
14272
14383
|
const trackedFiles = frameworkAdapter.driftTrackedFiles();
|
|
14273
|
-
if (trackedFiles.length > 0 &&
|
|
14384
|
+
if (trackedFiles.length > 0 && existsSync12(agentDir)) {
|
|
14274
14385
|
const hashes = /* @__PURE__ */ new Map();
|
|
14275
14386
|
for (const file of trackedFiles) {
|
|
14276
|
-
const h = hashFile(
|
|
14387
|
+
const h = hashFile(join26(agentDir, file));
|
|
14277
14388
|
if (h) hashes.set(file, h);
|
|
14278
14389
|
}
|
|
14279
14390
|
agentState.writtenHashes.set(agent.agent_id, hashes);
|
|
@@ -14288,7 +14399,7 @@ Retried to the limit after repeated stalls \u2014 needs a look.`).catch(() => {
|
|
|
14288
14399
|
refreshData.agent.onboarding_state
|
|
14289
14400
|
);
|
|
14290
14401
|
const obStep = obState.step;
|
|
14291
|
-
const markerPath =
|
|
14402
|
+
const markerPath = join26(homedir12(), ".augmented", agent.code_name, "onboarding-drive.json");
|
|
14292
14403
|
const marker = readOnboardingDriveMarker(markerPath);
|
|
14293
14404
|
const decision = decideOnboardingDrive(obStep, marker, Date.now(), obState.generation ?? 0);
|
|
14294
14405
|
if (decision.clearMarker) {
|
|
@@ -14376,7 +14487,7 @@ async function ensureOpencodeRuntime(agent, refreshData, agentTimezone) {
|
|
|
14376
14487
|
}
|
|
14377
14488
|
stopOpencodeSlackIngest(codeName, log);
|
|
14378
14489
|
stopOpencodeTelegramIngest(codeName, log);
|
|
14379
|
-
const opencodeProjectDir =
|
|
14490
|
+
const opencodeProjectDir = join26(getFramework("opencode").getAgentDir(codeName), "provision");
|
|
14380
14491
|
const serveEnv = {
|
|
14381
14492
|
AGT_HOST: requireHost(),
|
|
14382
14493
|
AGT_API_KEY: getApiKey() ?? void 0,
|
|
@@ -14418,9 +14529,16 @@ async function ensureOpencodeRuntime(agent, refreshData, agentTimezone) {
|
|
|
14418
14529
|
}
|
|
14419
14530
|
async function ensurePersistentSession(agent, tasks, boardItems, refreshData) {
|
|
14420
14531
|
const codeName = agent.code_name;
|
|
14532
|
+
if ((agentFrameworkCache.get(codeName) ?? DEFAULT_FRAMEWORK) === "claude-code" && !isSessionHealthy(codeName)) {
|
|
14533
|
+
maybeMigrateAgentToIdKeyedLayout(agent, {
|
|
14534
|
+
flagStore: hostFlagStore(),
|
|
14535
|
+
channelConfigs: refreshData["channel_configs"] ?? null,
|
|
14536
|
+
log
|
|
14537
|
+
});
|
|
14538
|
+
}
|
|
14421
14539
|
const projectDir = getProjectDir(codeName);
|
|
14422
|
-
const mcpConfigPath =
|
|
14423
|
-
const claudeMdPath =
|
|
14540
|
+
const mcpConfigPath = join26(projectDir, ".mcp.json");
|
|
14541
|
+
const claudeMdPath = join26(projectDir, "CLAUDE.md");
|
|
14424
14542
|
if (restartBreaker.isTripped(codeName)) {
|
|
14425
14543
|
const trip = restartBreaker.getTrip(codeName);
|
|
14426
14544
|
return {
|
|
@@ -15036,7 +15154,7 @@ async function handleRestartDoorbell(agentId, requestedAt, restartReason) {
|
|
|
15036
15154
|
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}`));
|
|
15037
15155
|
void (async () => {
|
|
15038
15156
|
try {
|
|
15039
|
-
const { collectDiagnostics } = await import("../persistent-session-
|
|
15157
|
+
const { collectDiagnostics } = await import("../persistent-session-MVAEGE6J.js");
|
|
15040
15158
|
await api.post("/host/heartbeat", {
|
|
15041
15159
|
host_id: hostId,
|
|
15042
15160
|
agent_diagnostics: collectDiagnostics([codeName], quarantineEntriesFor, claudeMdSizeFor)
|
|
@@ -15086,7 +15204,7 @@ async function respawnAgentAfterMcpStop(codeName, reason) {
|
|
|
15086
15204
|
}
|
|
15087
15205
|
try {
|
|
15088
15206
|
const hostId = await getHostId();
|
|
15089
|
-
const { collectDiagnostics } = await import("../persistent-session-
|
|
15207
|
+
const { collectDiagnostics } = await import("../persistent-session-MVAEGE6J.js");
|
|
15090
15208
|
await api.post("/host/heartbeat", {
|
|
15091
15209
|
host_id: hostId,
|
|
15092
15210
|
agent_diagnostics: collectDiagnostics([codeName], quarantineEntriesFor, claudeMdSizeFor)
|
|
@@ -15376,7 +15494,7 @@ async function processDirectChatMessage(agent, msg) {
|
|
|
15376
15494
|
const useDoorbell = hostFlagStore().getBoolean("direct-chat-doorbell") || isolationMode(agent.codeName) === "docker";
|
|
15377
15495
|
if (useDoorbell) {
|
|
15378
15496
|
try {
|
|
15379
|
-
const doorbell = directChatDoorbellPath(agent.agentId,
|
|
15497
|
+
const doorbell = directChatDoorbellPath(agent.agentId, homedir12());
|
|
15380
15498
|
mkdirSync10(dirname8(doorbell), { recursive: true });
|
|
15381
15499
|
writeFileSync12(doorbell, String(Date.now()));
|
|
15382
15500
|
log(`[direct-chat] Doorbell rung for '${agent.codeName}' (msg=${msg.id}) \u2014 in-session MCP will pull via the cursor`);
|
|
@@ -15486,7 +15604,7 @@ ${formatRunMarker(run_id)}` : KANBAN_CHECK_COMMAND;
|
|
|
15486
15604
|
}
|
|
15487
15605
|
if (run_id) openInjectedRunByCode.set(codeName, run_id);
|
|
15488
15606
|
try {
|
|
15489
|
-
const doorbell = directChatDoorbellPath(agentId,
|
|
15607
|
+
const doorbell = directChatDoorbellPath(agentId, homedir12());
|
|
15490
15608
|
mkdirSync10(dirname8(doorbell), { recursive: true });
|
|
15491
15609
|
writeFileSync12(doorbell, String(Date.now()));
|
|
15492
15610
|
} catch (err) {
|
|
@@ -15544,7 +15662,7 @@ async function processClaudePairSessions(agents) {
|
|
|
15544
15662
|
killPairSession,
|
|
15545
15663
|
pairTmuxSession,
|
|
15546
15664
|
finalizeClaudePairOnboarding
|
|
15547
|
-
} = await import("../claude-pair-runtime-
|
|
15665
|
+
} = await import("../claude-pair-runtime-7TSEIWGA.js");
|
|
15548
15666
|
for (const pairId of pendingResp.cancelled_pair_ids ?? []) {
|
|
15549
15667
|
log(`[claude-pair] sweeping orphan tmux session for pair ${pairId.slice(0, 8)}`);
|
|
15550
15668
|
const killed = await killPairSession(pairTmuxSession(pairId));
|
|
@@ -15798,8 +15916,8 @@ function parseMemoryFile(raw, fallbackName) {
|
|
|
15798
15916
|
};
|
|
15799
15917
|
}
|
|
15800
15918
|
async function syncMemories(agent, configDir, log2) {
|
|
15801
|
-
const projectDir =
|
|
15802
|
-
const memoryDir =
|
|
15919
|
+
const projectDir = join26(configDir, agent.code_name, "project");
|
|
15920
|
+
const memoryDir = join26(projectDir, "memory");
|
|
15803
15921
|
const isFreshSync = pendingFreshMemorySync.has(agent.agent_id);
|
|
15804
15922
|
if (isFreshSync) {
|
|
15805
15923
|
log2(`[memory-sync] Fresh-sync requested for '${agent.code_name}' \u2014 pulling DB first`);
|
|
@@ -15810,14 +15928,14 @@ async function syncMemories(agent, configDir, log2) {
|
|
|
15810
15928
|
}
|
|
15811
15929
|
pendingFreshMemorySync.delete(agent.agent_id);
|
|
15812
15930
|
}
|
|
15813
|
-
if (
|
|
15931
|
+
if (existsSync12(memoryDir)) {
|
|
15814
15932
|
const prevHashes = memoryFileHashes.get(agent.agent_id) ?? /* @__PURE__ */ new Map();
|
|
15815
15933
|
const currentHashes = /* @__PURE__ */ new Map();
|
|
15816
15934
|
const changedMemories = [];
|
|
15817
15935
|
for (const file of readdirSync7(memoryDir)) {
|
|
15818
15936
|
if (!file.endsWith(".md")) continue;
|
|
15819
15937
|
try {
|
|
15820
|
-
const raw = readFileSync21(
|
|
15938
|
+
const raw = readFileSync21(join26(memoryDir, file), "utf-8");
|
|
15821
15939
|
const fileHash = createHash16("sha256").update(raw).digest("hex").slice(0, 16);
|
|
15822
15940
|
currentHashes.set(file, fileHash);
|
|
15823
15941
|
if (prevHashes.get(file) === fileHash) continue;
|
|
@@ -15842,7 +15960,7 @@ async function syncMemories(agent, configDir, log2) {
|
|
|
15842
15960
|
} catch (err) {
|
|
15843
15961
|
for (const mem of changedMemories) {
|
|
15844
15962
|
for (const [file] of currentHashes) {
|
|
15845
|
-
const parsed = parseMemoryFile(readFileSync21(
|
|
15963
|
+
const parsed = parseMemoryFile(readFileSync21(join26(memoryDir, file), "utf-8"), file.replace(/\.md$/, ""));
|
|
15846
15964
|
if (parsed?.name === mem.name) currentHashes.delete(file);
|
|
15847
15965
|
}
|
|
15848
15966
|
}
|
|
@@ -15855,7 +15973,7 @@ async function syncMemories(agent, configDir, log2) {
|
|
|
15855
15973
|
}
|
|
15856
15974
|
}
|
|
15857
15975
|
async function downloadMemories(agent, memoryDir, log2, { force }) {
|
|
15858
|
-
const localFiles =
|
|
15976
|
+
const localFiles = existsSync12(memoryDir) ? readdirSync7(memoryDir).filter((f) => f.endsWith(".md")).sort() : [];
|
|
15859
15977
|
const localListHash = createHash16("sha256").update(localFiles.join(",")).digest("hex").slice(0, 16);
|
|
15860
15978
|
const prevLocalHash = lastLocalFileHash.get(agent.agent_id);
|
|
15861
15979
|
const prevDownload = lastDownloadHash.get(agent.agent_id);
|
|
@@ -15877,7 +15995,7 @@ async function downloadMemories(agent, memoryDir, log2, { force }) {
|
|
|
15877
15995
|
const mem = dbMemories.memories[i];
|
|
15878
15996
|
const rawSlug = mem.name.toLowerCase().replace(/[^a-z0-9]+/g, "-").replace(/(^-|-$)/g, "").slice(0, 60);
|
|
15879
15997
|
const slug = rawSlug || `memory-${i}`;
|
|
15880
|
-
const filePath =
|
|
15998
|
+
const filePath = join26(memoryDir, `${slug}.md`);
|
|
15881
15999
|
const desired = `---
|
|
15882
16000
|
name: ${JSON.stringify(mem.name)}
|
|
15883
16001
|
type: ${mem.type}
|
|
@@ -15886,7 +16004,7 @@ description: ${JSON.stringify(mem.content.slice(0, 200))}
|
|
|
15886
16004
|
|
|
15887
16005
|
${mem.content}
|
|
15888
16006
|
`;
|
|
15889
|
-
if (
|
|
16007
|
+
if (existsSync12(filePath)) {
|
|
15890
16008
|
let existing = "";
|
|
15891
16009
|
try {
|
|
15892
16010
|
existing = readFileSync21(filePath, "utf-8");
|
|
@@ -15913,7 +16031,7 @@ ${mem.content}
|
|
|
15913
16031
|
}
|
|
15914
16032
|
}
|
|
15915
16033
|
async function cleanupAgentFiles(codeName, agentDir) {
|
|
15916
|
-
if (
|
|
16034
|
+
if (existsSync12(agentDir)) {
|
|
15917
16035
|
try {
|
|
15918
16036
|
rmSync5(agentDir, { recursive: true, force: true });
|
|
15919
16037
|
log(`Removed provision directory for '${codeName}'`);
|
|
@@ -16152,7 +16270,7 @@ function startManager(opts) {
|
|
|
16152
16270
|
config = opts;
|
|
16153
16271
|
try {
|
|
16154
16272
|
const stateFile = getStateFile();
|
|
16155
|
-
if (
|
|
16273
|
+
if (existsSync12(stateFile)) {
|
|
16156
16274
|
const raw = readFileSync21(stateFile, "utf-8");
|
|
16157
16275
|
const parsed = JSON.parse(raw);
|
|
16158
16276
|
if (Array.isArray(parsed.agents)) {
|
|
@@ -16180,7 +16298,7 @@ function startManager(opts) {
|
|
|
16180
16298
|
log(`[startup] state rehydration failed (continuing with empty state): ${err.message}`);
|
|
16181
16299
|
}
|
|
16182
16300
|
log(
|
|
16183
|
-
`[startup] worker pid=${process.pid} ppid=${process.ppid} node=${process.version} log=${
|
|
16301
|
+
`[startup] worker pid=${process.pid} ppid=${process.ppid} node=${process.version} log=${join26(homedir12(), ".augmented", "manager.log")}`
|
|
16184
16302
|
);
|
|
16185
16303
|
deployMcpAssets();
|
|
16186
16304
|
reapOrphanChannelMcps({ log });
|
|
@@ -16306,14 +16424,14 @@ function restartRunningChannelMcps(basenames) {
|
|
|
16306
16424
|
}
|
|
16307
16425
|
}
|
|
16308
16426
|
function deployMcpAssets() {
|
|
16309
|
-
const targetDir =
|
|
16427
|
+
const targetDir = join26(homedir12(), ".augmented", "_mcp");
|
|
16310
16428
|
mkdirSync10(targetDir, { recursive: true });
|
|
16311
16429
|
const moduleDir = dirname8(fileURLToPath(import.meta.url));
|
|
16312
16430
|
let mcpSourceDir = "";
|
|
16313
16431
|
let dir = moduleDir;
|
|
16314
16432
|
for (let i = 0; i < 6; i++) {
|
|
16315
|
-
const candidate =
|
|
16316
|
-
if (
|
|
16433
|
+
const candidate = join26(dir, "dist", "mcp");
|
|
16434
|
+
if (existsSync12(join26(candidate, "index.js"))) {
|
|
16317
16435
|
mcpSourceDir = candidate;
|
|
16318
16436
|
break;
|
|
16319
16437
|
}
|
|
@@ -16328,7 +16446,7 @@ function deployMcpAssets() {
|
|
|
16328
16446
|
const changedBasenames = [];
|
|
16329
16447
|
const fileHash = (p) => {
|
|
16330
16448
|
try {
|
|
16331
|
-
if (!
|
|
16449
|
+
if (!existsSync12(p)) return null;
|
|
16332
16450
|
return createHash16("sha256").update(readFileSync21(p)).digest("hex");
|
|
16333
16451
|
} catch {
|
|
16334
16452
|
return null;
|
|
@@ -16393,9 +16511,9 @@ function deployMcpAssets() {
|
|
|
16393
16511
|
// needs restarting to pick up a token rotation.
|
|
16394
16512
|
"xero.js"
|
|
16395
16513
|
]) {
|
|
16396
|
-
const src =
|
|
16397
|
-
const dst =
|
|
16398
|
-
if (!
|
|
16514
|
+
const src = join26(mcpSourceDir, file);
|
|
16515
|
+
const dst = join26(targetDir, file);
|
|
16516
|
+
if (!existsSync12(src)) continue;
|
|
16399
16517
|
const before = fileHash(dst);
|
|
16400
16518
|
try {
|
|
16401
16519
|
copyFileSync(src, dst);
|
|
@@ -16412,14 +16530,14 @@ function deployMcpAssets() {
|
|
|
16412
16530
|
log(`[manager] Bundle(s) updated: ${changedBasenames.join(", ")} \u2014 signalling running instances to restart`);
|
|
16413
16531
|
restartRunningChannelMcps(changedBasenames);
|
|
16414
16532
|
}
|
|
16415
|
-
const localMcpPath =
|
|
16533
|
+
const localMcpPath = join26(targetDir, "index.js");
|
|
16416
16534
|
try {
|
|
16417
|
-
const agentsDir =
|
|
16418
|
-
if (
|
|
16535
|
+
const agentsDir = join26(homedir12(), ".augmented", "agents");
|
|
16536
|
+
if (existsSync12(agentsDir)) {
|
|
16419
16537
|
for (const entry of readdirSync7(agentsDir, { withFileTypes: true })) {
|
|
16420
16538
|
if (!entry.isDirectory()) continue;
|
|
16421
16539
|
for (const subdir of ["provision", "project"]) {
|
|
16422
|
-
const mcpJsonPath =
|
|
16540
|
+
const mcpJsonPath = join26(agentsDir, entry.name, subdir, ".mcp.json");
|
|
16423
16541
|
try {
|
|
16424
16542
|
const raw = readFileSync21(mcpJsonPath, "utf-8");
|
|
16425
16543
|
if (!raw.includes("@integrity-labs/augmented-mcp")) continue;
|