@integrity-labs/agt-cli 0.28.494 → 0.28.495
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-JHEJP3KC.js → chunk-4SQZDAWG.js} +63 -1
- package/dist/chunk-4SQZDAWG.js.map +1 -0
- package/dist/{chunk-DJNJWFKI.js → chunk-CAHE6QSE.js} +3 -3
- package/dist/{claude-pair-runtime-2RMAJGZH.js → claude-pair-runtime-LCQYCW67.js} +2 -2
- package/dist/lib/manager-worker.js +272 -212
- package/dist/lib/manager-worker.js.map +1 -1
- package/dist/mcp/direct-chat-channel.js +301 -46
- package/dist/mcp/origami.js +14 -0
- package/dist/mcp/slack-channel.js +14 -0
- package/dist/mcp/telegram-channel.js +14 -0
- package/dist/{persistent-session-JEN37LZS.js → persistent-session-TSPVNVQL.js} +2 -2
- package/dist/{responsiveness-probe-MSXL7NVR.js → responsiveness-probe-3LWQKHV2.js} +64 -2
- package/dist/responsiveness-probe-3LWQKHV2.js.map +1 -0
- package/package.json +1 -1
- package/dist/chunk-JHEJP3KC.js.map +0 -1
- package/dist/responsiveness-probe-MSXL7NVR.js.map +0 -1
- /package/dist/{chunk-DJNJWFKI.js.map → chunk-CAHE6QSE.js.map} +0 -0
- /package/dist/{claude-pair-runtime-2RMAJGZH.js.map → claude-pair-runtime-LCQYCW67.js.map} +0 -0
- /package/dist/{persistent-session-JEN37LZS.js.map → persistent-session-TSPVNVQL.js.map} +0 -0
|
@@ -45,7 +45,7 @@ import {
|
|
|
45
45
|
resolveEffectivePinRaw,
|
|
46
46
|
safeWriteJsonAtomic,
|
|
47
47
|
setConfigHash
|
|
48
|
-
} from "../chunk-
|
|
48
|
+
} from "../chunk-CAHE6QSE.js";
|
|
49
49
|
import {
|
|
50
50
|
getProjectDir as getProjectDir2,
|
|
51
51
|
getReadyTasks,
|
|
@@ -81,16 +81,19 @@ import {
|
|
|
81
81
|
buildScheduledTaskContextBlocks,
|
|
82
82
|
checkChannelInputs,
|
|
83
83
|
classifyActor,
|
|
84
|
+
classifyCursorAdvance,
|
|
84
85
|
classifyOutput,
|
|
85
86
|
classifyTranscriptRateLimit,
|
|
86
87
|
coerceOnboardingState,
|
|
87
88
|
creditWatchdogGiveUpCount,
|
|
89
|
+
cursorShortfallKey,
|
|
88
90
|
describeOnboardingChannel,
|
|
89
91
|
egressMode,
|
|
90
92
|
estimateActiveTasksTokens,
|
|
91
93
|
execFilePromiseLong,
|
|
92
94
|
extractFrontmatter,
|
|
93
95
|
formatActorId,
|
|
96
|
+
formatCursorAdvanceShortfall,
|
|
94
97
|
formatRunMarker,
|
|
95
98
|
getFramework,
|
|
96
99
|
getIntegration,
|
|
@@ -163,16 +166,16 @@ import {
|
|
|
163
166
|
toOpencodeModel,
|
|
164
167
|
transcriptActivityAgeSeconds,
|
|
165
168
|
writeEgressAllowlist
|
|
166
|
-
} from "../chunk-
|
|
169
|
+
} from "../chunk-4SQZDAWG.js";
|
|
167
170
|
import {
|
|
168
171
|
reapOrphanChannelMcps
|
|
169
172
|
} from "../chunk-XWVM4KPK.js";
|
|
170
173
|
|
|
171
174
|
// src/lib/manager-worker.ts
|
|
172
175
|
import { createHash as createHash16 } from "crypto";
|
|
173
|
-
import { readFileSync as
|
|
176
|
+
import { readFileSync as readFileSync22, writeFileSync as writeFileSync13, mkdirSync as mkdirSync10, existsSync as existsSync12, rmSync as rmSync5, readdirSync as readdirSync7, statSync as statSync6, copyFileSync } from "fs";
|
|
174
177
|
import { execFileSync as syncExecFile } from "child_process";
|
|
175
|
-
import { join as
|
|
178
|
+
import { join as join27, dirname as dirname8, delimiter as pathDelimiter } from "path";
|
|
176
179
|
import { homedir as homedir12 } from "os";
|
|
177
180
|
import { fileURLToPath } from "url";
|
|
178
181
|
|
|
@@ -2195,8 +2198,35 @@ function collectEnvGates(env) {
|
|
|
2195
2198
|
return out;
|
|
2196
2199
|
}
|
|
2197
2200
|
|
|
2198
|
-
//
|
|
2201
|
+
// ../../packages/core/dist/direct-chat/cursor-advance-telemetry.js
|
|
2202
|
+
import { readFileSync as readFileSync7, writeFileSync as writeFileSync4 } from "fs";
|
|
2199
2203
|
import { join as join6 } from "path";
|
|
2204
|
+
var CURSOR_SHORTFALL_COUNTER_SUFFIX = "-cursor-advance-classifications.json";
|
|
2205
|
+
function recordCursorAdvanceShortfall(agentDir, source, classification) {
|
|
2206
|
+
if (!agentDir)
|
|
2207
|
+
return;
|
|
2208
|
+
const path = join6(agentDir, `${source}${CURSOR_SHORTFALL_COUNTER_SUFFIX}`);
|
|
2209
|
+
const counts = {};
|
|
2210
|
+
try {
|
|
2211
|
+
const parsed = JSON.parse(readFileSync7(path, "utf-8"));
|
|
2212
|
+
if (parsed && typeof parsed === "object" && !Array.isArray(parsed)) {
|
|
2213
|
+
for (const [k, v] of Object.entries(parsed)) {
|
|
2214
|
+
if (typeof v === "number" && Number.isInteger(v) && v >= 0)
|
|
2215
|
+
counts[k] = v;
|
|
2216
|
+
}
|
|
2217
|
+
}
|
|
2218
|
+
} catch {
|
|
2219
|
+
}
|
|
2220
|
+
const key = cursorShortfallKey(classification.route, classification.reason, classification.partial);
|
|
2221
|
+
counts[key] = (counts[key] ?? 0) + 1;
|
|
2222
|
+
try {
|
|
2223
|
+
writeFileSync4(path, JSON.stringify(counts), { mode: 384 });
|
|
2224
|
+
} catch {
|
|
2225
|
+
}
|
|
2226
|
+
}
|
|
2227
|
+
|
|
2228
|
+
// src/lib/artifact-stream.ts
|
|
2229
|
+
import { join as join7 } from "path";
|
|
2200
2230
|
import { homedir as homedir3 } from "os";
|
|
2201
2231
|
import { readdir, stat, readFile } from "fs/promises";
|
|
2202
2232
|
var ARTEFACT_ENTRY_FILE = "index.html";
|
|
@@ -2282,7 +2312,7 @@ var ArtifactStreamScanner = class {
|
|
|
2282
2312
|
return;
|
|
2283
2313
|
}
|
|
2284
2314
|
for (const name of names) {
|
|
2285
|
-
const file =
|
|
2315
|
+
const file = join7(this.artifactsDir, name, ARTEFACT_ENTRY_FILE);
|
|
2286
2316
|
const mtime = await this.fsDeps.mtimeMs(file).catch(() => null);
|
|
2287
2317
|
if (mtime === null) continue;
|
|
2288
2318
|
if (this.seenMtime.get(name) === mtime) continue;
|
|
@@ -2313,7 +2343,7 @@ var ArtifactStreamScanner = class {
|
|
|
2313
2343
|
}
|
|
2314
2344
|
};
|
|
2315
2345
|
function artifactsDirFor(codeName) {
|
|
2316
|
-
return
|
|
2346
|
+
return join7(homedir3(), ".augmented", codeName, "artifacts");
|
|
2317
2347
|
}
|
|
2318
2348
|
var nodeArtifactFs = {
|
|
2319
2349
|
async listArtefactNames(artifactsDir) {
|
|
@@ -2403,12 +2433,12 @@ async function maybeReportUsageBanner(args) {
|
|
|
2403
2433
|
import { createHash as createHash6 } from "crypto";
|
|
2404
2434
|
import { readFile as readFile3, readdir as readdir3 } from "fs/promises";
|
|
2405
2435
|
import { homedir as homedir5, platform as platform2 } from "os";
|
|
2406
|
-
import { dirname as dirname4, join as
|
|
2436
|
+
import { dirname as dirname4, join as join9 } from "path";
|
|
2407
2437
|
|
|
2408
2438
|
// src/lib/claude-auth-detect.ts
|
|
2409
2439
|
import { readFile as readFile2, readdir as readdir2 } from "fs/promises";
|
|
2410
2440
|
import { homedir as homedir4, platform } from "os";
|
|
2411
|
-
import { join as
|
|
2441
|
+
import { join as join8 } from "path";
|
|
2412
2442
|
import { execFile } from "child_process";
|
|
2413
2443
|
import { promisify } from "util";
|
|
2414
2444
|
var execFileAsync = promisify(execFile);
|
|
@@ -2423,16 +2453,16 @@ async function detectClaudeAuth() {
|
|
|
2423
2453
|
}
|
|
2424
2454
|
async function findClaudeCredentialsPaths() {
|
|
2425
2455
|
const candidates = [
|
|
2426
|
-
|
|
2427
|
-
|
|
2456
|
+
join8(homedir4(), ".claude", ".credentials.json"),
|
|
2457
|
+
join8(homedir4(), ".claude", "credentials.json")
|
|
2428
2458
|
];
|
|
2429
2459
|
const isLinuxRoot = platform() === "linux" && typeof process.getuid === "function" && process.getuid() === 0;
|
|
2430
2460
|
if (isLinuxRoot) {
|
|
2431
2461
|
try {
|
|
2432
2462
|
const entries = await readdir2("/home", { withFileTypes: true });
|
|
2433
2463
|
for (const entry of entries.filter((entry2) => entry2.isDirectory()).sort((a, b) => a.name.localeCompare(b.name))) {
|
|
2434
|
-
candidates.push(
|
|
2435
|
-
candidates.push(
|
|
2464
|
+
candidates.push(join8("/home", entry.name, ".claude", ".credentials.json"));
|
|
2465
|
+
candidates.push(join8("/home", entry.name, ".claude", "credentials.json"));
|
|
2436
2466
|
}
|
|
2437
2467
|
} catch {
|
|
2438
2468
|
}
|
|
@@ -2516,7 +2546,7 @@ async function candidateHomes() {
|
|
|
2516
2546
|
try {
|
|
2517
2547
|
const entries = await readdir3("/home", { withFileTypes: true });
|
|
2518
2548
|
for (const entry of entries.filter((e) => e.isDirectory()).sort((a, b) => a.name.localeCompare(b.name))) {
|
|
2519
|
-
homes.push(
|
|
2549
|
+
homes.push(join9("/home", entry.name));
|
|
2520
2550
|
}
|
|
2521
2551
|
} catch {
|
|
2522
2552
|
}
|
|
@@ -2536,11 +2566,11 @@ async function homeOfActiveCredentials() {
|
|
|
2536
2566
|
async function claudeConfigCandidatePaths() {
|
|
2537
2567
|
const paths = [];
|
|
2538
2568
|
const configDir = process.env["CLAUDE_CONFIG_DIR"]?.trim();
|
|
2539
|
-
if (configDir) paths.push(
|
|
2569
|
+
if (configDir) paths.push(join9(configDir, ".claude.json"));
|
|
2540
2570
|
const activeHome = await homeOfActiveCredentials();
|
|
2541
|
-
if (activeHome) paths.push(
|
|
2571
|
+
if (activeHome) paths.push(join9(activeHome, ".claude.json"));
|
|
2542
2572
|
for (const home of await candidateHomes()) {
|
|
2543
|
-
const path =
|
|
2573
|
+
const path = join9(home, ".claude.json");
|
|
2544
2574
|
if (!paths.includes(path)) paths.push(path);
|
|
2545
2575
|
}
|
|
2546
2576
|
return paths;
|
|
@@ -2637,11 +2667,11 @@ function diffAuthTuples(recorded, current) {
|
|
|
2637
2667
|
}
|
|
2638
2668
|
|
|
2639
2669
|
// src/lib/account-enforcement-marker.ts
|
|
2640
|
-
import { mkdirSync as mkdirSync4, renameSync as renameSync2, rmSync as rmSync2, writeFileSync as
|
|
2670
|
+
import { mkdirSync as mkdirSync4, renameSync as renameSync2, rmSync as rmSync2, writeFileSync as writeFileSync5 } from "fs";
|
|
2641
2671
|
import { homedir as homedir6 } from "os";
|
|
2642
|
-
import { join as
|
|
2672
|
+
import { join as join10 } from "path";
|
|
2643
2673
|
function accountEnforcementMarkerPath(codeName) {
|
|
2644
|
-
return
|
|
2674
|
+
return join10(homedir6(), ".augmented", codeName, ACCOUNT_ENFORCEMENT_MARKER_FILENAME);
|
|
2645
2675
|
}
|
|
2646
2676
|
function syncAccountEnforcementMarker(codeName, level, log2 = (m) => process.stderr.write(`${m}
|
|
2647
2677
|
`)) {
|
|
@@ -2649,12 +2679,12 @@ function syncAccountEnforcementMarker(codeName, level, log2 = (m) => process.std
|
|
|
2649
2679
|
clearAccountEnforcementMarker(codeName, log2);
|
|
2650
2680
|
return;
|
|
2651
2681
|
}
|
|
2652
|
-
const dir =
|
|
2653
|
-
const path =
|
|
2682
|
+
const dir = join10(homedir6(), ".augmented", codeName);
|
|
2683
|
+
const path = join10(dir, ACCOUNT_ENFORCEMENT_MARKER_FILENAME);
|
|
2654
2684
|
const tempPath = `${path}.${process.pid}.tmp`;
|
|
2655
2685
|
try {
|
|
2656
2686
|
mkdirSync4(dir, { recursive: true });
|
|
2657
|
-
|
|
2687
|
+
writeFileSync5(tempPath, serializeAccountEnforcementMarker(level), "utf-8");
|
|
2658
2688
|
renameSync2(tempPath, path);
|
|
2659
2689
|
} catch (err) {
|
|
2660
2690
|
try {
|
|
@@ -2675,8 +2705,8 @@ function clearAccountEnforcementMarker(codeName, log2 = (m) => process.stderr.wr
|
|
|
2675
2705
|
}
|
|
2676
2706
|
|
|
2677
2707
|
// src/lib/token-usage-monitor.ts
|
|
2678
|
-
import { readdirSync, readFileSync as
|
|
2679
|
-
import { join as
|
|
2708
|
+
import { readdirSync, readFileSync as readFileSync8, statSync } from "fs";
|
|
2709
|
+
import { join as join11 } from "path";
|
|
2680
2710
|
var MIN_CHECK_INTERVAL_MS2 = 6e4;
|
|
2681
2711
|
var TRANSCRIPT_MTIME_WINDOW_MS = 2 * 24 * 60 * 60 * 1e3;
|
|
2682
2712
|
var MAX_ENTRIES_PER_POST = 200;
|
|
@@ -2705,7 +2735,7 @@ async function maybeReportTokenUsage(args) {
|
|
|
2705
2735
|
if (!name.endsWith(".jsonl")) continue;
|
|
2706
2736
|
const sessionId = name.slice(0, -".jsonl".length);
|
|
2707
2737
|
if (!sessionId) continue;
|
|
2708
|
-
const path =
|
|
2738
|
+
const path = join11(dir, name);
|
|
2709
2739
|
let st;
|
|
2710
2740
|
try {
|
|
2711
2741
|
st = statSync(path);
|
|
@@ -2721,7 +2751,7 @@ async function maybeReportTokenUsage(args) {
|
|
|
2721
2751
|
}
|
|
2722
2752
|
let content;
|
|
2723
2753
|
try {
|
|
2724
|
-
content =
|
|
2754
|
+
content = readFileSync8(path, "utf-8");
|
|
2725
2755
|
} catch (err) {
|
|
2726
2756
|
log2(`[token-usage] read failed for '${codeName}/${name}': ${err.message}`);
|
|
2727
2757
|
continue;
|
|
@@ -2802,8 +2832,8 @@ async function maybeReportTokenUsage(args) {
|
|
|
2802
2832
|
}
|
|
2803
2833
|
|
|
2804
2834
|
// src/lib/workflow-run-reconciler.ts
|
|
2805
|
-
import { readdirSync as readdirSync2, readFileSync as
|
|
2806
|
-
import { join as
|
|
2835
|
+
import { readdirSync as readdirSync2, readFileSync as readFileSync9, statSync as statSync2 } from "fs";
|
|
2836
|
+
import { join as join12 } from "path";
|
|
2807
2837
|
var MIN_CHECK_INTERVAL_MS3 = 5 * 6e4;
|
|
2808
2838
|
var SETTLE_MS = 3e4;
|
|
2809
2839
|
var TRANSCRIPT_MTIME_WINDOW_MS2 = 2 * 24 * 60 * 60 * 1e3;
|
|
@@ -2822,7 +2852,7 @@ function collectJsonlRecursive(dir, minMtimeMs, out, depth) {
|
|
|
2822
2852
|
return;
|
|
2823
2853
|
}
|
|
2824
2854
|
for (const name of entries) {
|
|
2825
|
-
const p =
|
|
2855
|
+
const p = join12(dir, name);
|
|
2826
2856
|
let st;
|
|
2827
2857
|
try {
|
|
2828
2858
|
st = statSync2(p);
|
|
@@ -2845,7 +2875,7 @@ function enumerateTranscriptFiles(transcriptDir, nowMs, minMtimeMs = nowMs - TRA
|
|
|
2845
2875
|
return out;
|
|
2846
2876
|
}
|
|
2847
2877
|
for (const name of entries) {
|
|
2848
|
-
const path =
|
|
2878
|
+
const path = join12(transcriptDir, name);
|
|
2849
2879
|
let st;
|
|
2850
2880
|
try {
|
|
2851
2881
|
st = statSync2(path);
|
|
@@ -2857,7 +2887,7 @@ function enumerateTranscriptFiles(transcriptDir, nowMs, minMtimeMs = nowMs - TRA
|
|
|
2857
2887
|
continue;
|
|
2858
2888
|
}
|
|
2859
2889
|
if (st.isDirectory()) {
|
|
2860
|
-
collectJsonlRecursive(
|
|
2890
|
+
collectJsonlRecursive(join12(path, "subagents"), minMtimeMs, out, 0);
|
|
2861
2891
|
}
|
|
2862
2892
|
}
|
|
2863
2893
|
return out;
|
|
@@ -2902,7 +2932,7 @@ async function maybeReconcileWorkflowRunTokens(args) {
|
|
|
2902
2932
|
const contents = [];
|
|
2903
2933
|
for (const path of files) {
|
|
2904
2934
|
try {
|
|
2905
|
-
contents.push(
|
|
2935
|
+
contents.push(readFileSync9(path, "utf-8"));
|
|
2906
2936
|
} catch {
|
|
2907
2937
|
}
|
|
2908
2938
|
}
|
|
@@ -2947,8 +2977,8 @@ async function maybeReconcileWorkflowRunTokens(args) {
|
|
|
2947
2977
|
}
|
|
2948
2978
|
|
|
2949
2979
|
// src/lib/conversation-evaluator.ts
|
|
2950
|
-
import { readdirSync as readdirSync3, readFileSync as
|
|
2951
|
-
import { join as
|
|
2980
|
+
import { readdirSync as readdirSync3, readFileSync as readFileSync10, statSync as statSync3 } from "fs";
|
|
2981
|
+
import { join as join13 } from "path";
|
|
2952
2982
|
var MIN_CHECK_INTERVAL_MS4 = 5 * 6e4;
|
|
2953
2983
|
var TRANSCRIPT_MTIME_WINDOW_MS3 = 7 * 24 * 60 * 60 * 1e3;
|
|
2954
2984
|
var WINDOW_PAD_MS = 5 * 6e4;
|
|
@@ -3384,7 +3414,7 @@ function readRecentTurns(dir, nowMs) {
|
|
|
3384
3414
|
return;
|
|
3385
3415
|
}
|
|
3386
3416
|
for (const ent of entries) {
|
|
3387
|
-
const full =
|
|
3417
|
+
const full = join13(d, ent.name);
|
|
3388
3418
|
if (ent.isDirectory()) {
|
|
3389
3419
|
visit(full);
|
|
3390
3420
|
continue;
|
|
@@ -3399,7 +3429,7 @@ function readRecentTurns(dir, nowMs) {
|
|
|
3399
3429
|
if (nowMs - mtimeMs > TRANSCRIPT_MTIME_WINDOW_MS3) continue;
|
|
3400
3430
|
let content;
|
|
3401
3431
|
try {
|
|
3402
|
-
content =
|
|
3432
|
+
content = readFileSync10(full, "utf8");
|
|
3403
3433
|
} catch {
|
|
3404
3434
|
continue;
|
|
3405
3435
|
}
|
|
@@ -3689,11 +3719,11 @@ async function reportSkip2(api2, agentId, conversationId, log2, codeName) {
|
|
|
3689
3719
|
}
|
|
3690
3720
|
|
|
3691
3721
|
// src/lib/activity-cache-monitor.ts
|
|
3692
|
-
import { existsSync as existsSync3, readFileSync as
|
|
3722
|
+
import { existsSync as existsSync3, readFileSync as readFileSync11 } from "fs";
|
|
3693
3723
|
import { homedir as homedir7 } from "os";
|
|
3694
|
-
import { join as
|
|
3724
|
+
import { join as join14 } from "path";
|
|
3695
3725
|
var MIN_CHECK_INTERVAL_MS6 = 6e4;
|
|
3696
|
-
var STATS_CACHE_PATH =
|
|
3726
|
+
var STATS_CACHE_PATH = join14(homedir7(), ".claude", "stats-cache.json");
|
|
3697
3727
|
var ISO_DATE_RE = /^\d{4}-\d{2}-\d{2}$/;
|
|
3698
3728
|
var state5 = { lastObservedDate: null, lastCheckedAt: 0 };
|
|
3699
3729
|
function selectNewDailyRows(raw, lastObservedDate) {
|
|
@@ -3741,7 +3771,7 @@ async function maybeReportActivityCache(args) {
|
|
|
3741
3771
|
}
|
|
3742
3772
|
let raw;
|
|
3743
3773
|
try {
|
|
3744
|
-
raw =
|
|
3774
|
+
raw = readFileSync11(STATS_CACHE_PATH, "utf-8");
|
|
3745
3775
|
} catch (err) {
|
|
3746
3776
|
log2(`[activity-cache] readFileSync failed: ${err.message}`);
|
|
3747
3777
|
return;
|
|
@@ -3945,18 +3975,18 @@ function computeChannelConfigHash(input) {
|
|
|
3945
3975
|
}
|
|
3946
3976
|
|
|
3947
3977
|
// src/lib/channel-hash-cache.ts
|
|
3948
|
-
import { existsSync as existsSync4, readFileSync as
|
|
3949
|
-
import { join as
|
|
3978
|
+
import { existsSync as existsSync4, readFileSync as readFileSync12, writeFileSync as writeFileSync6 } from "fs";
|
|
3979
|
+
import { join as join15 } from "path";
|
|
3950
3980
|
var CACHE_FILENAME = "channel-hash-cache.json";
|
|
3951
3981
|
function getChannelHashCacheFile(configDir) {
|
|
3952
|
-
return
|
|
3982
|
+
return join15(configDir, CACHE_FILENAME);
|
|
3953
3983
|
}
|
|
3954
3984
|
function loadChannelHashCache(target, configDir) {
|
|
3955
3985
|
const path = getChannelHashCacheFile(configDir);
|
|
3956
3986
|
if (!existsSync4(path)) return;
|
|
3957
3987
|
let parsed;
|
|
3958
3988
|
try {
|
|
3959
|
-
parsed = JSON.parse(
|
|
3989
|
+
parsed = JSON.parse(readFileSync12(path, "utf-8"));
|
|
3960
3990
|
} catch {
|
|
3961
3991
|
return;
|
|
3962
3992
|
}
|
|
@@ -3970,14 +4000,14 @@ function saveChannelHashCache(source, configDir) {
|
|
|
3970
4000
|
const obj = {};
|
|
3971
4001
|
for (const [key, value] of source) obj[key] = value;
|
|
3972
4002
|
try {
|
|
3973
|
-
|
|
4003
|
+
writeFileSync6(path, JSON.stringify(obj, null, 2));
|
|
3974
4004
|
} catch {
|
|
3975
4005
|
}
|
|
3976
4006
|
}
|
|
3977
4007
|
|
|
3978
4008
|
// src/lib/sender-policy-baseline.ts
|
|
3979
|
-
import { existsSync as existsSync5, readFileSync as
|
|
3980
|
-
import { join as
|
|
4009
|
+
import { existsSync as existsSync5, readFileSync as readFileSync13 } from "fs";
|
|
4010
|
+
import { join as join16 } from "path";
|
|
3981
4011
|
var BASELINE_FILENAME = "sender-policy-baseline.json";
|
|
3982
4012
|
var SENDER_POLICY_BASELINE_VERSION = 1;
|
|
3983
4013
|
var BASELINE_CONCERNS = ["senderPolicy", "slackBehaviour", "msteamsBehaviour"];
|
|
@@ -3989,14 +4019,14 @@ function createDeliveryBaselineMaps() {
|
|
|
3989
4019
|
};
|
|
3990
4020
|
}
|
|
3991
4021
|
function getSenderPolicyBaselineFile(configDir) {
|
|
3992
|
-
return
|
|
4022
|
+
return join16(configDir, BASELINE_FILENAME);
|
|
3993
4023
|
}
|
|
3994
4024
|
function loadSenderPolicyBaseline(target, configDir, log2) {
|
|
3995
4025
|
const path = getSenderPolicyBaselineFile(configDir);
|
|
3996
4026
|
if (!existsSync5(path)) return;
|
|
3997
4027
|
let parsed;
|
|
3998
4028
|
try {
|
|
3999
|
-
parsed = JSON.parse(
|
|
4029
|
+
parsed = JSON.parse(readFileSync13(path, "utf-8"));
|
|
4000
4030
|
} catch (err) {
|
|
4001
4031
|
log2?.(
|
|
4002
4032
|
`[sender-policy] discarding corrupt ${BASELINE_FILENAME} (${err.message}) - restrictive-policy agents will take one fail-closed restart`
|
|
@@ -4519,16 +4549,16 @@ function planGlobalSkillSync(globalSkills, prevIds, hashOf, knownHash, options)
|
|
|
4519
4549
|
}
|
|
4520
4550
|
|
|
4521
4551
|
// src/lib/manager/managed-skill-manifest.ts
|
|
4522
|
-
import { existsSync as existsSync6, mkdirSync as mkdirSync5, readFileSync as
|
|
4523
|
-
import { dirname as dirname5, join as
|
|
4552
|
+
import { existsSync as existsSync6, mkdirSync as mkdirSync5, readFileSync as readFileSync14, writeFileSync as writeFileSync7 } from "fs";
|
|
4553
|
+
import { dirname as dirname5, join as join17 } from "path";
|
|
4524
4554
|
var MANIFEST_VERSION = 1;
|
|
4525
4555
|
function managedSkillManifestPath(agentRootDir) {
|
|
4526
|
-
return
|
|
4556
|
+
return join17(agentRootDir, "managed-skills.json");
|
|
4527
4557
|
}
|
|
4528
4558
|
function readManagedSkillManifest(path) {
|
|
4529
4559
|
try {
|
|
4530
4560
|
if (!existsSync6(path)) return /* @__PURE__ */ new Set();
|
|
4531
|
-
const parsed = JSON.parse(
|
|
4561
|
+
const parsed = JSON.parse(readFileSync14(path, "utf-8"));
|
|
4532
4562
|
const ids = Array.isArray(parsed?.globalSkillIds) ? parsed.globalSkillIds : [];
|
|
4533
4563
|
return new Set(ids.filter((id) => typeof id === "string" && id.length > 0));
|
|
4534
4564
|
} catch {
|
|
@@ -4542,7 +4572,7 @@ function writeManagedSkillManifest(path, ids) {
|
|
|
4542
4572
|
version: MANIFEST_VERSION,
|
|
4543
4573
|
globalSkillIds: [...ids].sort()
|
|
4544
4574
|
};
|
|
4545
|
-
|
|
4575
|
+
writeFileSync7(path, JSON.stringify(body, null, 2));
|
|
4546
4576
|
} catch {
|
|
4547
4577
|
}
|
|
4548
4578
|
}
|
|
@@ -4641,7 +4671,7 @@ function resolveModelChain(refreshData) {
|
|
|
4641
4671
|
|
|
4642
4672
|
// src/lib/manager/claude-auth.ts
|
|
4643
4673
|
import { existsSync as existsSync7, rmSync as rmSync3 } from "fs";
|
|
4644
|
-
import { join as
|
|
4674
|
+
import { join as join18 } from "path";
|
|
4645
4675
|
import { homedir as homedir8 } from "os";
|
|
4646
4676
|
async function applyClaudeAuthToEnv(childEnv, label) {
|
|
4647
4677
|
const apiKey = getApiKey();
|
|
@@ -4654,9 +4684,9 @@ async function applyClaudeAuthToEnv(childEnv, label) {
|
|
|
4654
4684
|
throw new Error("claude_auth_mode=api_key but /host/exchange returned no decrypted key");
|
|
4655
4685
|
}
|
|
4656
4686
|
childEnv.ANTHROPIC_API_KEY = exchange.anthropicApiKey;
|
|
4657
|
-
const claudeDir =
|
|
4687
|
+
const claudeDir = join18(homedir8(), ".claude");
|
|
4658
4688
|
for (const filename of [".credentials.json", "credentials.json"]) {
|
|
4659
|
-
const p =
|
|
4689
|
+
const p = join18(claudeDir, filename);
|
|
4660
4690
|
if (existsSync7(p)) {
|
|
4661
4691
|
try {
|
|
4662
4692
|
rmSync3(p, { force: true });
|
|
@@ -4671,8 +4701,8 @@ async function applyClaudeAuthToEnv(childEnv, label) {
|
|
|
4671
4701
|
}
|
|
4672
4702
|
|
|
4673
4703
|
// src/lib/manager/kanban/parsers.ts
|
|
4674
|
-
import { existsSync as existsSync8, readFileSync as
|
|
4675
|
-
import { join as
|
|
4704
|
+
import { existsSync as existsSync8, readFileSync as readFileSync15 } from "fs";
|
|
4705
|
+
import { join as join19 } from "path";
|
|
4676
4706
|
var STANDUP_TEMPLATES = /* @__PURE__ */ new Set(["daily-standup", "end-of-day-summary"]);
|
|
4677
4707
|
var TASK_UPDATE_TEMPLATES = /* @__PURE__ */ new Set(["hourly-status", "task-update"]);
|
|
4678
4708
|
var PLAN_TEMPLATES = /* @__PURE__ */ new Set(["morning-plan"]);
|
|
@@ -4811,12 +4841,12 @@ function getBuiltInSkillContent(skillId) {
|
|
|
4811
4841
|
if (builtInSkillCache.has(skillId)) return builtInSkillCache.get(skillId);
|
|
4812
4842
|
try {
|
|
4813
4843
|
const candidates = [
|
|
4814
|
-
|
|
4815
|
-
|
|
4844
|
+
join19(process.cwd(), "skills", skillId, "SKILL.md"),
|
|
4845
|
+
join19(new URL(".", import.meta.url).pathname, "..", "..", "..", "..", "..", "..", "skills", skillId, "SKILL.md")
|
|
4816
4846
|
];
|
|
4817
4847
|
for (const candidate of candidates) {
|
|
4818
4848
|
if (existsSync8(candidate)) {
|
|
4819
|
-
const content =
|
|
4849
|
+
const content = readFileSync15(candidate, "utf-8");
|
|
4820
4850
|
const files = [{ relativePath: "SKILL.md", content }];
|
|
4821
4851
|
builtInSkillCache.set(skillId, files);
|
|
4822
4852
|
return files;
|
|
@@ -4957,19 +4987,19 @@ function formatBoardForPrompt(items, template) {
|
|
|
4957
4987
|
}
|
|
4958
4988
|
|
|
4959
4989
|
// src/lib/manager/kanban/nudge-state-cache.ts
|
|
4960
|
-
import { existsSync as existsSync9, readFileSync as
|
|
4961
|
-
import { join as
|
|
4990
|
+
import { existsSync as existsSync9, readFileSync as readFileSync16, writeFileSync as writeFileSync8 } from "fs";
|
|
4991
|
+
import { join as join20 } from "path";
|
|
4962
4992
|
var CACHE_FILENAME2 = "kanban-nudge-state.json";
|
|
4963
4993
|
var KANBAN_NUDGE_STATE_VERSION = 1;
|
|
4964
4994
|
function getKanbanNudgeStateFile(configDir) {
|
|
4965
|
-
return
|
|
4995
|
+
return join20(configDir, CACHE_FILENAME2);
|
|
4966
4996
|
}
|
|
4967
4997
|
function loadKanbanNudgeState(target, configDir) {
|
|
4968
4998
|
const path = getKanbanNudgeStateFile(configDir);
|
|
4969
4999
|
if (!existsSync9(path)) return;
|
|
4970
5000
|
let parsed;
|
|
4971
5001
|
try {
|
|
4972
|
-
parsed = JSON.parse(
|
|
5002
|
+
parsed = JSON.parse(readFileSync16(path, "utf-8"));
|
|
4973
5003
|
} catch {
|
|
4974
5004
|
return;
|
|
4975
5005
|
}
|
|
@@ -4994,7 +5024,7 @@ function saveKanbanNudgeState(source, configDir) {
|
|
|
4994
5024
|
const agents = {};
|
|
4995
5025
|
for (const [codeName, state7] of source) agents[codeName] = state7;
|
|
4996
5026
|
try {
|
|
4997
|
-
|
|
5027
|
+
writeFileSync8(path, JSON.stringify({ version: KANBAN_NUDGE_STATE_VERSION, agents }, null, 2));
|
|
4998
5028
|
} catch {
|
|
4999
5029
|
}
|
|
5000
5030
|
}
|
|
@@ -5569,9 +5599,9 @@ function closeScheduledRunsForCode(codeName, outcome, reason) {
|
|
|
5569
5599
|
|
|
5570
5600
|
// src/lib/manager/scheduler/kanban-route.ts
|
|
5571
5601
|
import { createHash as createHash11 } from "crypto";
|
|
5572
|
-
import { writeFileSync as
|
|
5602
|
+
import { writeFileSync as writeFileSync9, renameSync as renameSync3, mkdirSync as mkdirSync6, readFileSync as readFileSync17, unlinkSync } from "fs";
|
|
5573
5603
|
import { homedir as homedir9 } from "os";
|
|
5574
|
-
import { join as
|
|
5604
|
+
import { join as join21, dirname as dirname6 } from "path";
|
|
5575
5605
|
|
|
5576
5606
|
// src/lib/manager/scheduler/notify.ts
|
|
5577
5607
|
import { createHash as createHash10 } from "crypto";
|
|
@@ -5912,19 +5942,19 @@ function resolveScheduledSlackTarget(task) {
|
|
|
5912
5942
|
}
|
|
5913
5943
|
function stampScheduledTurnMarker(codeName, taskId, target) {
|
|
5914
5944
|
try {
|
|
5915
|
-
const file =
|
|
5945
|
+
const file = join21(homedir9(), ".augmented", codeName, SCHEDULED_TURN_MARKER_FILENAME);
|
|
5916
5946
|
const marker = { ts: Date.now(), task_id: taskId, ...target ? { target } : {} };
|
|
5917
5947
|
const tmp = `${file}.tmp`;
|
|
5918
|
-
|
|
5948
|
+
writeFileSync9(tmp, JSON.stringify(marker), "utf8");
|
|
5919
5949
|
renameSync3(tmp, file);
|
|
5920
5950
|
} catch (err) {
|
|
5921
5951
|
log(`[scheduled-kanban] scheduled-turn marker write failed for '${codeName}': ${err.message}`);
|
|
5922
5952
|
}
|
|
5923
5953
|
}
|
|
5924
5954
|
function clearScheduledTurnMarkerForTask(codeName, taskId) {
|
|
5925
|
-
const file =
|
|
5955
|
+
const file = join21(homedir9(), ".augmented", codeName, SCHEDULED_TURN_MARKER_FILENAME);
|
|
5926
5956
|
try {
|
|
5927
|
-
const raw = JSON.parse(
|
|
5957
|
+
const raw = JSON.parse(readFileSync17(file, "utf8"));
|
|
5928
5958
|
if (typeof raw?.task_id !== "string" || raw.task_id !== taskId) return;
|
|
5929
5959
|
unlinkSync(file);
|
|
5930
5960
|
log(`[scheduled-kanban] scheduled-turn marker cleared for '${codeName}' (task ${taskId} complete)`);
|
|
@@ -5986,7 +6016,7 @@ async function routeScheduledTaskViaKanban(codeName, agentId, task, prompt, dura
|
|
|
5986
6016
|
try {
|
|
5987
6017
|
const doorbell = directChatDoorbellPath(agentId, homedir9());
|
|
5988
6018
|
mkdirSync6(dirname6(doorbell), { recursive: true });
|
|
5989
|
-
|
|
6019
|
+
writeFileSync9(doorbell, String(Date.now()));
|
|
5990
6020
|
} catch (err) {
|
|
5991
6021
|
log(`[scheduled-kanban] doorbell ring failed for '${codeName}': ${err.message} (notice still queued)`);
|
|
5992
6022
|
}
|
|
@@ -6137,11 +6167,11 @@ async function processClaudeTaskResult(codeName, agentId, templateId, rawOutput,
|
|
|
6137
6167
|
// src/lib/manager/scheduler/execution.ts
|
|
6138
6168
|
import { createHash as createHash12 } from "crypto";
|
|
6139
6169
|
import { homedir as homedir10 } from "os";
|
|
6140
|
-
import { join as
|
|
6170
|
+
import { join as join23 } from "path";
|
|
6141
6171
|
|
|
6142
6172
|
// src/lib/agent-serving-probe.ts
|
|
6143
|
-
import { readFileSync as
|
|
6144
|
-
import { join as
|
|
6173
|
+
import { readFileSync as readFileSync18, readdirSync as readdirSync4, statSync as statSync4 } from "fs";
|
|
6174
|
+
import { join as join22 } from "path";
|
|
6145
6175
|
var RATE_LIMIT_WINDOW_MS = 6 * 60 * 60 * 1e3;
|
|
6146
6176
|
function probeRateLimit(args) {
|
|
6147
6177
|
const now = args.now ?? /* @__PURE__ */ new Date();
|
|
@@ -6157,7 +6187,7 @@ function probeRateLimit(args) {
|
|
|
6157
6187
|
let newest = UNKNOWN_RATE_LIMIT;
|
|
6158
6188
|
for (const name of entries) {
|
|
6159
6189
|
if (!name.endsWith(".jsonl")) continue;
|
|
6160
|
-
const path =
|
|
6190
|
+
const path = join22(dir, name);
|
|
6161
6191
|
try {
|
|
6162
6192
|
const st = statSync4(path);
|
|
6163
6193
|
if (!st.isFile() || st.mtimeMs < startMs) continue;
|
|
@@ -6166,7 +6196,7 @@ function probeRateLimit(args) {
|
|
|
6166
6196
|
}
|
|
6167
6197
|
let content;
|
|
6168
6198
|
try {
|
|
6169
|
-
content =
|
|
6199
|
+
content = readFileSync18(path, "utf-8");
|
|
6170
6200
|
} catch {
|
|
6171
6201
|
continue;
|
|
6172
6202
|
}
|
|
@@ -6228,7 +6258,7 @@ function shouldLogUsageCapDeferral(site, codeName, limitedUntil) {
|
|
|
6228
6258
|
|
|
6229
6259
|
// src/lib/manager/scheduler/execution.ts
|
|
6230
6260
|
function claudePidFilePath() {
|
|
6231
|
-
return
|
|
6261
|
+
return join23(homedir10(), ".augmented", "manager-claude-pids.json");
|
|
6232
6262
|
}
|
|
6233
6263
|
var inFlightClaudePids = /* @__PURE__ */ new Map();
|
|
6234
6264
|
function registerClaudeSpawn(record) {
|
|
@@ -7461,9 +7491,9 @@ async function fireOpencodeScheduledTask(agent, task) {
|
|
|
7461
7491
|
|
|
7462
7492
|
// src/lib/opencode-telegram-ingest.ts
|
|
7463
7493
|
import { createHash as createHash15 } from "crypto";
|
|
7464
|
-
import { existsSync as existsSync10, mkdirSync as mkdirSync7, readFileSync as
|
|
7494
|
+
import { existsSync as existsSync10, mkdirSync as mkdirSync7, readFileSync as readFileSync19, renameSync as renameSync4, unlinkSync as unlinkSync2, writeFileSync as writeFileSync10 } from "fs";
|
|
7465
7495
|
import { randomUUID } from "crypto";
|
|
7466
|
-
import { join as
|
|
7496
|
+
import { join as join24 } from "path";
|
|
7467
7497
|
|
|
7468
7498
|
// src/lib/telegram-ingest.ts
|
|
7469
7499
|
import https2 from "https";
|
|
@@ -8011,7 +8041,7 @@ function createFileOffsetStore(codeName, log2, currentBotId) {
|
|
|
8011
8041
|
let filePath;
|
|
8012
8042
|
try {
|
|
8013
8043
|
dir = getFramework("opencode").getAgentDir(codeName);
|
|
8014
|
-
filePath =
|
|
8044
|
+
filePath = join24(dir, "telegram-getupdates-offset-opencode.json");
|
|
8015
8045
|
} catch {
|
|
8016
8046
|
dir = null;
|
|
8017
8047
|
filePath = null;
|
|
@@ -8020,7 +8050,7 @@ function createFileOffsetStore(codeName, log2, currentBotId) {
|
|
|
8020
8050
|
load() {
|
|
8021
8051
|
if (!filePath) return 0;
|
|
8022
8052
|
try {
|
|
8023
|
-
const parsed = JSON.parse(
|
|
8053
|
+
const parsed = JSON.parse(readFileSync19(filePath, "utf-8"));
|
|
8024
8054
|
if (currentBotId != null && typeof parsed?.bot_id === "number" && parsed.bot_id !== currentBotId) {
|
|
8025
8055
|
log2(`[telegram-ingest:${codeName}] offset cursor belongs to a different bot; ignoring (bot swap)`);
|
|
8026
8056
|
return 0;
|
|
@@ -8039,7 +8069,7 @@ function createFileOffsetStore(codeName, log2, currentBotId) {
|
|
|
8039
8069
|
const tmpPath = `${filePath}.${process.pid}.${randomUUID()}.tmp`;
|
|
8040
8070
|
try {
|
|
8041
8071
|
mkdirSync7(dir, { recursive: true, mode: 448 });
|
|
8042
|
-
|
|
8072
|
+
writeFileSync10(
|
|
8043
8073
|
tmpPath,
|
|
8044
8074
|
JSON.stringify({
|
|
8045
8075
|
offset,
|
|
@@ -8290,15 +8320,15 @@ function partitionActionableByPoison(actionable, states, config2) {
|
|
|
8290
8320
|
}
|
|
8291
8321
|
|
|
8292
8322
|
// src/lib/restart-flags.ts
|
|
8293
|
-
import { existsSync as existsSync11, mkdirSync as mkdirSync8, readdirSync as readdirSync5, readFileSync as
|
|
8323
|
+
import { existsSync as existsSync11, mkdirSync as mkdirSync8, readdirSync as readdirSync5, readFileSync as readFileSync20, renameSync as renameSync5, rmSync as rmSync4, writeFileSync as writeFileSync11 } from "fs";
|
|
8294
8324
|
import { homedir as homedir11 } from "os";
|
|
8295
|
-
import { join as
|
|
8325
|
+
import { join as join25 } from "path";
|
|
8296
8326
|
import { randomUUID as randomUUID2 } from "crypto";
|
|
8297
8327
|
function restartFlagsDir() {
|
|
8298
|
-
return
|
|
8328
|
+
return join25(homedir11(), ".augmented", "restart-flags");
|
|
8299
8329
|
}
|
|
8300
8330
|
function flagPath(codeName) {
|
|
8301
|
-
return
|
|
8331
|
+
return join25(restartFlagsDir(), `${codeName}.flag`);
|
|
8302
8332
|
}
|
|
8303
8333
|
function readRestartFlags() {
|
|
8304
8334
|
const dir = restartFlagsDir();
|
|
@@ -8307,7 +8337,7 @@ function readRestartFlags() {
|
|
|
8307
8337
|
for (const entry of readdirSync5(dir)) {
|
|
8308
8338
|
if (!entry.endsWith(".flag")) continue;
|
|
8309
8339
|
try {
|
|
8310
|
-
const raw =
|
|
8340
|
+
const raw = readFileSync20(join25(dir, entry), "utf8");
|
|
8311
8341
|
const parsed = JSON.parse(raw);
|
|
8312
8342
|
if (typeof parsed.codeName !== "string" || parsed.codeName.length === 0) {
|
|
8313
8343
|
parsed.codeName = entry.replace(/\.flag$/, "");
|
|
@@ -8425,8 +8455,8 @@ async function sendError(flag, opts, text) {
|
|
|
8425
8455
|
}
|
|
8426
8456
|
|
|
8427
8457
|
// src/lib/restart-context.ts
|
|
8428
|
-
import { readdirSync as readdirSync6, readFileSync as
|
|
8429
|
-
import { dirname as dirname7, join as
|
|
8458
|
+
import { readdirSync as readdirSync6, readFileSync as readFileSync21, writeFileSync as writeFileSync12, mkdirSync as mkdirSync9, unlinkSync as unlinkSync3 } from "fs";
|
|
8459
|
+
import { dirname as dirname7, join as join26 } from "path";
|
|
8430
8460
|
var SLACK_PENDING_INBOUND_DIRNAME = "slack-pending-inbound";
|
|
8431
8461
|
var SLACK_RESTART_CONTEXT_DIRNAME = "slack-restart-context";
|
|
8432
8462
|
var MAX_TOPIC_CHARS = 140;
|
|
@@ -8438,10 +8468,10 @@ function augmentedAgentDir(codeName) {
|
|
|
8438
8468
|
return dirname7(getProjectDir(codeName));
|
|
8439
8469
|
}
|
|
8440
8470
|
function slackPendingInboundDir(codeName) {
|
|
8441
|
-
return
|
|
8471
|
+
return join26(augmentedAgentDir(codeName), SLACK_PENDING_INBOUND_DIRNAME);
|
|
8442
8472
|
}
|
|
8443
8473
|
function slackRestartContextDir(codeName) {
|
|
8444
|
-
return
|
|
8474
|
+
return join26(augmentedAgentDir(codeName), SLACK_RESTART_CONTEXT_DIRNAME);
|
|
8445
8475
|
}
|
|
8446
8476
|
function sanitizeTopic(raw) {
|
|
8447
8477
|
const cleaned = raw.replace(/\s+/g, " ").trim().replace(/[<>]/g, " ").replace(/\s+/g, " ").trim();
|
|
@@ -8483,7 +8513,7 @@ function safeReaddir(dir) {
|
|
|
8483
8513
|
}
|
|
8484
8514
|
function readStrandedMarker(path) {
|
|
8485
8515
|
try {
|
|
8486
|
-
const parsed = JSON.parse(
|
|
8516
|
+
const parsed = JSON.parse(readFileSync21(path, "utf-8"));
|
|
8487
8517
|
if (typeof parsed.channel === "string" && typeof parsed.thread_ts === "string") {
|
|
8488
8518
|
return { channel: parsed.channel, thread_ts: parsed.thread_ts };
|
|
8489
8519
|
}
|
|
@@ -8493,7 +8523,7 @@ function readStrandedMarker(path) {
|
|
|
8493
8523
|
}
|
|
8494
8524
|
function writeHintFile(path, dir, hint) {
|
|
8495
8525
|
mkdirSync9(dir, { recursive: true, mode: 448 });
|
|
8496
|
-
|
|
8526
|
+
writeFileSync12(path, JSON.stringify(hint), { mode: 384 });
|
|
8497
8527
|
}
|
|
8498
8528
|
function pruneHintsExcept(codeName, freshFilenames) {
|
|
8499
8529
|
const ctxDir = slackRestartContextDir(codeName);
|
|
@@ -8501,7 +8531,7 @@ function pruneHintsExcept(codeName, freshFilenames) {
|
|
|
8501
8531
|
if (!filename.endsWith(".json")) continue;
|
|
8502
8532
|
if (freshFilenames.has(filename)) continue;
|
|
8503
8533
|
try {
|
|
8504
|
-
unlinkSync3(
|
|
8534
|
+
unlinkSync3(join26(ctxDir, filename));
|
|
8505
8535
|
} catch {
|
|
8506
8536
|
}
|
|
8507
8537
|
}
|
|
@@ -8522,7 +8552,7 @@ function refreshSlackRestartContextHints(codeNames, opts = {}) {
|
|
|
8522
8552
|
}
|
|
8523
8553
|
const markers = [];
|
|
8524
8554
|
for (const filename of markerFilenames.slice(0, cap)) {
|
|
8525
|
-
const parsed = readStrandedMarker(
|
|
8555
|
+
const parsed = readStrandedMarker(join26(markerDir, filename));
|
|
8526
8556
|
if (parsed) markers.push({ filename, channel: parsed.channel, thread_ts: parsed.thread_ts });
|
|
8527
8557
|
}
|
|
8528
8558
|
if (markers.length === 0) {
|
|
@@ -8536,7 +8566,7 @@ function refreshSlackRestartContextHints(codeNames, opts = {}) {
|
|
|
8536
8566
|
const freshFilenames = /* @__PURE__ */ new Set();
|
|
8537
8567
|
for (const { filename, hint } of hints) {
|
|
8538
8568
|
try {
|
|
8539
|
-
writeHintFile(
|
|
8569
|
+
writeHintFile(join26(ctxDir, filename), ctxDir, hint);
|
|
8540
8570
|
freshFilenames.add(filename);
|
|
8541
8571
|
} catch (err) {
|
|
8542
8572
|
log2(`[restart-context] ${codeName}: hint write failed for ${filename}: ${err.message}`);
|
|
@@ -9846,7 +9876,7 @@ var runningChannelSecretHashes = /* @__PURE__ */ new Map();
|
|
|
9846
9876
|
var sessionLaunchManagedStructure = /* @__PURE__ */ new Map();
|
|
9847
9877
|
function projectMcpHash(_codeName, projectDir) {
|
|
9848
9878
|
try {
|
|
9849
|
-
const raw =
|
|
9879
|
+
const raw = readFileSync22(join27(projectDir, ".mcp.json"), "utf-8");
|
|
9850
9880
|
return createHash16("sha256").update(canonicalJson(JSON.parse(raw))).digest("hex");
|
|
9851
9881
|
} catch {
|
|
9852
9882
|
return null;
|
|
@@ -9854,7 +9884,7 @@ function projectMcpHash(_codeName, projectDir) {
|
|
|
9854
9884
|
}
|
|
9855
9885
|
function projectMcpKeys(_codeName, projectDir) {
|
|
9856
9886
|
try {
|
|
9857
|
-
const raw =
|
|
9887
|
+
const raw = readFileSync22(join27(projectDir, ".mcp.json"), "utf-8");
|
|
9858
9888
|
const parsed = JSON.parse(raw);
|
|
9859
9889
|
const servers = parsed.mcpServers;
|
|
9860
9890
|
if (!servers || typeof servers !== "object") return /* @__PURE__ */ new Set();
|
|
@@ -9872,7 +9902,7 @@ function seedSessionLaunchBaselines(codeName, projectDir) {
|
|
|
9872
9902
|
else runningMcpServerKeys.delete(codeName);
|
|
9873
9903
|
let launchStructure = null;
|
|
9874
9904
|
try {
|
|
9875
|
-
const raw =
|
|
9905
|
+
const raw = readFileSync22(join27(projectDir, ".mcp.json"), "utf-8");
|
|
9876
9906
|
launchStructure = managedMcpStructureHashFromFile(
|
|
9877
9907
|
JSON.parse(raw),
|
|
9878
9908
|
isManagedMcpServerKey
|
|
@@ -9976,7 +10006,7 @@ async function runAgentSessionToolBindProbes(agent, integrations, projectDir, op
|
|
|
9976
10006
|
if (result && result.rebindCandidates.length > 0 && hostFlagStore().getBoolean("session-tool-rebind")) {
|
|
9977
10007
|
let mcpJsonForRebind = null;
|
|
9978
10008
|
try {
|
|
9979
|
-
mcpJsonForRebind = JSON.parse(
|
|
10009
|
+
mcpJsonForRebind = JSON.parse(readFileSync22(join27(projectDir, ".mcp.json"), "utf-8"));
|
|
9980
10010
|
} catch {
|
|
9981
10011
|
mcpJsonForRebind = null;
|
|
9982
10012
|
}
|
|
@@ -10120,7 +10150,7 @@ function checkMcpConfigDriftAndScheduleRestart(codeName, projectDir) {
|
|
|
10120
10150
|
function projectChannelSecretHash(projectDir) {
|
|
10121
10151
|
try {
|
|
10122
10152
|
const entries = parseEnvIntegrations(
|
|
10123
|
-
|
|
10153
|
+
readFileSync22(join27(projectDir, ".env.integrations"), "utf-8")
|
|
10124
10154
|
);
|
|
10125
10155
|
return channelSecretValueHash(entries, CHANNEL_SECRET_ENV_KEYS);
|
|
10126
10156
|
} catch {
|
|
@@ -10216,7 +10246,7 @@ var agentRestartTimezoneInputs = /* @__PURE__ */ new Map();
|
|
|
10216
10246
|
var lastVersionCheckAt = 0;
|
|
10217
10247
|
var VERSION_CHECK_INTERVAL_MS = 5 * 60 * 1e3;
|
|
10218
10248
|
var lastResponsivenessProbeAt = 0;
|
|
10219
|
-
var agtCliVersion = true ? "0.28.
|
|
10249
|
+
var agtCliVersion = true ? "0.28.495" : "dev";
|
|
10220
10250
|
function resolveBrewPath(execFileSync2) {
|
|
10221
10251
|
try {
|
|
10222
10252
|
const out = execFileSync2("which", ["brew"], { timeout: 5e3 }).toString().trim();
|
|
@@ -10505,7 +10535,7 @@ function ensureClaudeManagedSettings(path = claudeManagedSettingsPath()) {
|
|
|
10505
10535
|
try {
|
|
10506
10536
|
let settings = {};
|
|
10507
10537
|
if (existsSync12(path)) {
|
|
10508
|
-
const raw =
|
|
10538
|
+
const raw = readFileSync22(path, "utf-8").trim();
|
|
10509
10539
|
if (raw) {
|
|
10510
10540
|
let parsed;
|
|
10511
10541
|
try {
|
|
@@ -10522,7 +10552,7 @@ function ensureClaudeManagedSettings(path = claudeManagedSettingsPath()) {
|
|
|
10522
10552
|
if (settings.channelsEnabled === true) return "ok";
|
|
10523
10553
|
settings.channelsEnabled = true;
|
|
10524
10554
|
mkdirSync10(dirname8(path), { recursive: true });
|
|
10525
|
-
|
|
10555
|
+
writeFileSync13(path, `${JSON.stringify(settings, null, 2)}
|
|
10526
10556
|
`);
|
|
10527
10557
|
log(`[managed-settings] set channelsEnabled:true in ${path} (ENG-5786 \u2014 unblocks Claude Code channels)`);
|
|
10528
10558
|
return "ok";
|
|
@@ -10560,7 +10590,7 @@ async function ensureOpencodeBinary() {
|
|
|
10560
10590
|
try {
|
|
10561
10591
|
const prefix = execFileSync2("npm", ["prefix", "-g"], { encoding: "utf-8", timeout: 1e4 }).trim();
|
|
10562
10592
|
if (prefix) {
|
|
10563
|
-
const npmBin =
|
|
10593
|
+
const npmBin = join27(prefix, "bin");
|
|
10564
10594
|
const current = (process.env.PATH ?? "").split(pathDelimiter);
|
|
10565
10595
|
if (!current.includes(npmBin)) {
|
|
10566
10596
|
process.env.PATH = [npmBin, ...current.filter(Boolean)].join(pathDelimiter);
|
|
@@ -10677,7 +10707,7 @@ ${r.stderr}`;
|
|
|
10677
10707
|
}
|
|
10678
10708
|
var UPDATE_CHECK_INTERVAL_MS = 5 * 60 * 1e3;
|
|
10679
10709
|
function selfUpdateAppliedMarkerPath() {
|
|
10680
|
-
return
|
|
10710
|
+
return join27(homedir12(), ".augmented", ".last-self-update-applied");
|
|
10681
10711
|
}
|
|
10682
10712
|
var selfUpdateUpToDateLogged = false;
|
|
10683
10713
|
var selfUpdatePinnedLogged = false;
|
|
@@ -10705,7 +10735,7 @@ async function checkAndUpdateCli(opts) {
|
|
|
10705
10735
|
const isNpmGlobal = !isBrewFormula && resolvedPath.includes("node_modules");
|
|
10706
10736
|
if (!isBrewFormula && !isNpmGlobal) return "noop";
|
|
10707
10737
|
const { readFileSync: readF, writeFileSync: writeF } = await import("fs");
|
|
10708
|
-
const markerPath =
|
|
10738
|
+
const markerPath = join27(homedir12(), ".augmented", ".last-update-check");
|
|
10709
10739
|
if (!force) {
|
|
10710
10740
|
try {
|
|
10711
10741
|
const lastCheck = parseInt(readF(markerPath, "utf-8").trim(), 10);
|
|
@@ -11065,13 +11095,13 @@ async function checkClaudeAuth() {
|
|
|
11065
11095
|
var evalEmptyMcpConfigPath = null;
|
|
11066
11096
|
function ensureEvalEmptyMcpConfig() {
|
|
11067
11097
|
if (evalEmptyMcpConfigPath && existsSync12(evalEmptyMcpConfigPath)) return evalEmptyMcpConfigPath;
|
|
11068
|
-
const dir =
|
|
11098
|
+
const dir = join27(homedir12(), ".augmented");
|
|
11069
11099
|
try {
|
|
11070
11100
|
mkdirSync10(dir, { recursive: true });
|
|
11071
11101
|
} catch {
|
|
11072
11102
|
}
|
|
11073
|
-
const p =
|
|
11074
|
-
|
|
11103
|
+
const p = join27(dir, ".eval-empty-mcp.json");
|
|
11104
|
+
writeFileSync13(p, JSON.stringify({ mcpServers: {} }));
|
|
11075
11105
|
evalEmptyMcpConfigPath = p;
|
|
11076
11106
|
return p;
|
|
11077
11107
|
}
|
|
@@ -11162,10 +11192,10 @@ function resolveConversationEvalBackend() {
|
|
|
11162
11192
|
return conversationEvalBackend;
|
|
11163
11193
|
}
|
|
11164
11194
|
function getStateFile() {
|
|
11165
|
-
return
|
|
11195
|
+
return join27(config?.configDir ?? join27(process.env["HOME"] ?? "/tmp", ".augmented"), "manager-state.json");
|
|
11166
11196
|
}
|
|
11167
11197
|
function channelHashCacheDir() {
|
|
11168
|
-
return config?.configDir ??
|
|
11198
|
+
return config?.configDir ?? join27(process.env["HOME"] ?? "/tmp", ".augmented");
|
|
11169
11199
|
}
|
|
11170
11200
|
function loadChannelHashCache2() {
|
|
11171
11201
|
loadChannelHashCache(agentState.knownChannelConfigHashes, channelHashCacheDir());
|
|
@@ -11219,7 +11249,7 @@ function removeDeliveryBaselineEntries(agentId) {
|
|
|
11219
11249
|
var _channelQuarantineStore = null;
|
|
11220
11250
|
function channelQuarantineStore() {
|
|
11221
11251
|
if (!_channelQuarantineStore) {
|
|
11222
|
-
const dir = config?.configDir ??
|
|
11252
|
+
const dir = config?.configDir ?? join27(process.env["HOME"] ?? "/tmp", ".augmented");
|
|
11223
11253
|
_channelQuarantineStore = new ChannelQuarantineStore(defaultQuarantinePath(dir));
|
|
11224
11254
|
}
|
|
11225
11255
|
return _channelQuarantineStore;
|
|
@@ -11236,7 +11266,7 @@ function claudeMdSizeFor(codeName) {
|
|
|
11236
11266
|
var _hostFlagStore = null;
|
|
11237
11267
|
function hostFlagStore() {
|
|
11238
11268
|
if (!_hostFlagStore) {
|
|
11239
|
-
const dir = config?.configDir ??
|
|
11269
|
+
const dir = config?.configDir ?? join27(process.env["HOME"] ?? "/tmp", ".augmented");
|
|
11240
11270
|
_hostFlagStore = new HostFlagStore({ cachePath: defaultFlagsCachePath(dir), log });
|
|
11241
11271
|
}
|
|
11242
11272
|
return _hostFlagStore;
|
|
@@ -11306,13 +11336,13 @@ function parseSkillFrontmatter(content) {
|
|
|
11306
11336
|
return out;
|
|
11307
11337
|
}
|
|
11308
11338
|
async function refreshSkillsIndexInClaudeMd(configDir, codeName, log2) {
|
|
11309
|
-
const { readdirSync: readdirSync8, readFileSync: rfs, existsSync: ex, writeFileSync:
|
|
11310
|
-
const skillsDir =
|
|
11311
|
-
const claudeMdPath =
|
|
11339
|
+
const { readdirSync: readdirSync8, readFileSync: rfs, existsSync: ex, writeFileSync: writeFileSync14 } = await import("fs");
|
|
11340
|
+
const skillsDir = join27(configDir, codeName, "project", ".claude", "skills");
|
|
11341
|
+
const claudeMdPath = join27(configDir, codeName, "project", "CLAUDE.md");
|
|
11312
11342
|
if (!ex(skillsDir) || !ex(claudeMdPath)) return;
|
|
11313
11343
|
const entries = [];
|
|
11314
11344
|
for (const dir of readdirSync8(skillsDir).sort()) {
|
|
11315
|
-
const skillFile =
|
|
11345
|
+
const skillFile = join27(skillsDir, dir, "SKILL.md");
|
|
11316
11346
|
if (!ex(skillFile)) continue;
|
|
11317
11347
|
try {
|
|
11318
11348
|
const { name, description } = parseSkillFrontmatter(rfs(skillFile, "utf-8"));
|
|
@@ -11356,7 +11386,7 @@ ${SKILLS_INDEX_END}`;
|
|
|
11356
11386
|
next = current.trimEnd() + "\n\n" + section + "\n";
|
|
11357
11387
|
}
|
|
11358
11388
|
if (next !== current) {
|
|
11359
|
-
|
|
11389
|
+
writeFileSync14(claudeMdPath, next, "utf-8");
|
|
11360
11390
|
log2(
|
|
11361
11391
|
injectSkillList ? `Refreshed skills index in CLAUDE.md for '${codeName}' (${entries.length} skills)` : `Refreshed CLAUDE.md managed block for '${codeName}' (skill list suppressed by claude-md-skills-index=false; ${entries.length} skills on disk)`
|
|
11362
11392
|
);
|
|
@@ -11379,7 +11409,7 @@ function flushRestartedAgentDiagnostics(hostId, codeNames) {
|
|
|
11379
11409
|
if (codeNames.length === 0) return;
|
|
11380
11410
|
void (async () => {
|
|
11381
11411
|
try {
|
|
11382
|
-
const { collectDiagnostics } = await import("../persistent-session-
|
|
11412
|
+
const { collectDiagnostics } = await import("../persistent-session-TSPVNVQL.js");
|
|
11383
11413
|
await api.post("/host/heartbeat", {
|
|
11384
11414
|
host_id: hostId,
|
|
11385
11415
|
agent_diagnostics: collectDiagnostics(codeNames, quarantineEntriesFor, claudeMdSizeFor)
|
|
@@ -11486,7 +11516,7 @@ async function pollCycle() {
|
|
|
11486
11516
|
}
|
|
11487
11517
|
try {
|
|
11488
11518
|
const { detectHostSecurity } = await import("../host-security-6PDFG7F5.js");
|
|
11489
|
-
const { collectDiagnostics } = await import("../persistent-session-
|
|
11519
|
+
const { collectDiagnostics } = await import("../persistent-session-TSPVNVQL.js");
|
|
11490
11520
|
const diagCodeNames = [...agentState.persistentSessionAgents];
|
|
11491
11521
|
const agentDiagnostics = diagCodeNames.length > 0 ? collectDiagnostics(diagCodeNames, quarantineEntriesFor, claudeMdSizeFor) : void 0;
|
|
11492
11522
|
let tailscaleHostname;
|
|
@@ -11601,7 +11631,7 @@ async function pollCycle() {
|
|
|
11601
11631
|
collectResponsivenessProbes,
|
|
11602
11632
|
collectPanelessActivityProbes,
|
|
11603
11633
|
getResponsivenessIntervalMs
|
|
11604
|
-
} = await import("../responsiveness-probe-
|
|
11634
|
+
} = await import("../responsiveness-probe-3LWQKHV2.js");
|
|
11605
11635
|
const probeIntervalMs = getResponsivenessIntervalMs();
|
|
11606
11636
|
if (now - lastResponsivenessProbeAt > probeIntervalMs) {
|
|
11607
11637
|
const probeCodeNames = [...agentState.persistentSessionAgents];
|
|
@@ -11665,7 +11695,7 @@ async function pollCycle() {
|
|
|
11665
11695
|
collectResponsivenessProbes,
|
|
11666
11696
|
livePendingInboundOldestAgeSeconds,
|
|
11667
11697
|
parkPendingInbound
|
|
11668
|
-
} = await import("../responsiveness-probe-
|
|
11698
|
+
} = await import("../responsiveness-probe-3LWQKHV2.js");
|
|
11669
11699
|
const { getProjectDir: wedgeProjectDir } = await import("../scheduler-engine-NDP36U7O.js");
|
|
11670
11700
|
const wedgeNow = /* @__PURE__ */ new Date();
|
|
11671
11701
|
const liveAgents = agentState.persistentSessionAgents;
|
|
@@ -11754,13 +11784,13 @@ async function pollCycle() {
|
|
|
11754
11784
|
);
|
|
11755
11785
|
if (hostFlagStore().getBoolean("wedge-transient-notice")) {
|
|
11756
11786
|
try {
|
|
11757
|
-
const paneTail =
|
|
11787
|
+
const paneTail = readFileSync22(paneLogPath(codeName), "utf8").slice(-65536);
|
|
11758
11788
|
const transient = detectTransientApiErrorInLog(paneTail);
|
|
11759
11789
|
if (transient) {
|
|
11760
|
-
const wedgeHome =
|
|
11790
|
+
const wedgeHome = join27(homedir12(), ".augmented", codeName);
|
|
11761
11791
|
if (existsSync12(wedgeHome)) {
|
|
11762
11792
|
atomicWriteFileSync(
|
|
11763
|
-
|
|
11793
|
+
join27(wedgeHome, "watchdog-give-up.json"),
|
|
11764
11794
|
JSON.stringify({
|
|
11765
11795
|
gave_up_at: wedgeNow.toISOString(),
|
|
11766
11796
|
reason: "transient_overload"
|
|
@@ -12031,7 +12061,7 @@ async function pollCycle() {
|
|
|
12031
12061
|
const adapter = resolveAgentFramework(prev.codeName);
|
|
12032
12062
|
stopAgentRuntime2(prev.codeName, "removed-from-host");
|
|
12033
12063
|
killAgentChannelProcesses(prev.codeName, { log });
|
|
12034
|
-
const agentDir =
|
|
12064
|
+
const agentDir = join27(adapter.getAgentDir(prev.codeName), "provision");
|
|
12035
12065
|
await cleanupAgentFiles(prev.codeName, agentDir);
|
|
12036
12066
|
clearAgentCaches(prev.agentId, prev.codeName);
|
|
12037
12067
|
}
|
|
@@ -12118,10 +12148,10 @@ async function pollCycle() {
|
|
|
12118
12148
|
// pending-inbound marker. Best-effort: a write failure is logged by
|
|
12119
12149
|
// the watchdog, never fails the poll cycle.
|
|
12120
12150
|
signalGiveUp: (codeName) => {
|
|
12121
|
-
const dir =
|
|
12151
|
+
const dir = join27(homedir12(), ".augmented", codeName);
|
|
12122
12152
|
if (!existsSync12(dir)) return;
|
|
12123
12153
|
atomicWriteFileSync(
|
|
12124
|
-
|
|
12154
|
+
join27(dir, "watchdog-give-up.json"),
|
|
12125
12155
|
JSON.stringify({ gave_up_at: (/* @__PURE__ */ new Date()).toISOString() })
|
|
12126
12156
|
);
|
|
12127
12157
|
}
|
|
@@ -12263,7 +12293,7 @@ async function processAgent(agent, agentStates) {
|
|
|
12263
12293
|
}
|
|
12264
12294
|
const now = (/* @__PURE__ */ new Date()).toISOString();
|
|
12265
12295
|
const adapter = resolveAgentFramework(agent.code_name);
|
|
12266
|
-
let agentDir =
|
|
12296
|
+
let agentDir = join27(adapter.getAgentDir(agent.code_name), "provision");
|
|
12267
12297
|
if (agent.status === "draft" || agent.status === "paused") {
|
|
12268
12298
|
if (previousKnownStatus !== agent.status) {
|
|
12269
12299
|
log(`Agent '${agent.code_name}' is ${agent.status}, skipping provisioning`);
|
|
@@ -12437,7 +12467,7 @@ async function processAgent(agent, agentStates) {
|
|
|
12437
12467
|
const frameworkId = refreshData.agent.framework ?? DEFAULT_FRAMEWORK;
|
|
12438
12468
|
agentFrameworkCache.set(agent.code_name, frameworkId);
|
|
12439
12469
|
const frameworkAdapter = getFramework(frameworkId);
|
|
12440
|
-
agentDir =
|
|
12470
|
+
agentDir = join27(frameworkAdapter.getAgentDir(agent.code_name), "provision");
|
|
12441
12471
|
cacheAgentDeliveryMetadata(agent.code_name, refreshData);
|
|
12442
12472
|
agentRestartTimezoneInputs.set(agent.code_name, {
|
|
12443
12473
|
agentTimezone: typeof refreshData.agent.timezone === "string" ? refreshData.agent.timezone : null,
|
|
@@ -12486,7 +12516,7 @@ async function processAgent(agent, agentStates) {
|
|
|
12486
12516
|
const changedFiles = [];
|
|
12487
12517
|
mkdirSync10(agentDir, { recursive: true });
|
|
12488
12518
|
for (const artifact of artifacts) {
|
|
12489
|
-
const filePath =
|
|
12519
|
+
const filePath = join27(agentDir, artifact.relativePath);
|
|
12490
12520
|
let existingHash;
|
|
12491
12521
|
let newHash;
|
|
12492
12522
|
let writeContent = artifact.content;
|
|
@@ -12505,8 +12535,8 @@ async function processAgent(agent, agentStates) {
|
|
|
12505
12535
|
};
|
|
12506
12536
|
newHash = sha256(stripDynamicSections(artifact.content));
|
|
12507
12537
|
try {
|
|
12508
|
-
const projectClaudeMd =
|
|
12509
|
-
const existing =
|
|
12538
|
+
const projectClaudeMd = join27(config.configDir, agent.code_name, "project", "CLAUDE.md");
|
|
12539
|
+
const existing = readFileSync22(projectClaudeMd, "utf-8");
|
|
12510
12540
|
existingHash = sha256(stripDynamicSections(existing));
|
|
12511
12541
|
} catch {
|
|
12512
12542
|
existingHash = null;
|
|
@@ -12524,7 +12554,7 @@ async function processAgent(agent, agentStates) {
|
|
|
12524
12554
|
const generatorKeys = Object.keys(generatorServers);
|
|
12525
12555
|
let existingRaw = "";
|
|
12526
12556
|
try {
|
|
12527
|
-
existingRaw =
|
|
12557
|
+
existingRaw = readFileSync22(filePath, "utf-8");
|
|
12528
12558
|
} catch {
|
|
12529
12559
|
}
|
|
12530
12560
|
const existingServers = parseMcp(existingRaw);
|
|
@@ -12540,7 +12570,7 @@ async function processAgent(agent, agentStates) {
|
|
|
12540
12570
|
} else if (artifact.relativePath === "opencode.json") {
|
|
12541
12571
|
let existingRaw = null;
|
|
12542
12572
|
try {
|
|
12543
|
-
existingRaw =
|
|
12573
|
+
existingRaw = readFileSync22(filePath, "utf-8");
|
|
12544
12574
|
} catch {
|
|
12545
12575
|
}
|
|
12546
12576
|
const mergeResult = mergeOpencodeConfigArtifact(artifact.content, existingRaw);
|
|
@@ -12556,26 +12586,26 @@ async function processAgent(agent, agentStates) {
|
|
|
12556
12586
|
}
|
|
12557
12587
|
}
|
|
12558
12588
|
if (changedFiles.length > 0) {
|
|
12559
|
-
const isFirst = !existsSync12(
|
|
12589
|
+
const isFirst = !existsSync12(join27(agentDir, "CHARTER.md"));
|
|
12560
12590
|
const verb = isFirst ? "Provisioning" : "Updating";
|
|
12561
12591
|
const fileNames = changedFiles.map((f) => f.relativePath).join(", ");
|
|
12562
12592
|
log(`${verb} '${agent.code_name}': ${fileNames}`);
|
|
12563
12593
|
for (const file of changedFiles) {
|
|
12564
|
-
const filePath =
|
|
12594
|
+
const filePath = join27(agentDir, file.relativePath);
|
|
12565
12595
|
mkdirSync10(dirname8(filePath), { recursive: true });
|
|
12566
12596
|
if (file.relativePath === ".mcp.json") {
|
|
12567
12597
|
safeWriteJsonAtomic(filePath, file.content, { mode: 384 });
|
|
12568
12598
|
} else {
|
|
12569
|
-
|
|
12599
|
+
writeFileSync13(filePath, file.content);
|
|
12570
12600
|
}
|
|
12571
12601
|
}
|
|
12572
12602
|
try {
|
|
12573
|
-
const provSkillsDir =
|
|
12603
|
+
const provSkillsDir = join27(agentDir, ".claude", "skills");
|
|
12574
12604
|
if (existsSync12(provSkillsDir)) {
|
|
12575
12605
|
for (const folder of readdirSync7(provSkillsDir)) {
|
|
12576
12606
|
if (folder.startsWith("knowledge-")) {
|
|
12577
12607
|
try {
|
|
12578
|
-
rmSync5(
|
|
12608
|
+
rmSync5(join27(provSkillsDir, folder), { recursive: true });
|
|
12579
12609
|
} catch {
|
|
12580
12610
|
}
|
|
12581
12611
|
}
|
|
@@ -12588,7 +12618,7 @@ async function processAgent(agent, agentStates) {
|
|
|
12588
12618
|
const trackedFiles2 = frameworkAdapter.driftTrackedFiles();
|
|
12589
12619
|
const hashes = /* @__PURE__ */ new Map();
|
|
12590
12620
|
for (const file of trackedFiles2) {
|
|
12591
|
-
const h = hashFile(
|
|
12621
|
+
const h = hashFile(join27(agentDir, file));
|
|
12592
12622
|
if (h) hashes.set(file, h);
|
|
12593
12623
|
}
|
|
12594
12624
|
agentState.writtenHashes.set(agent.agent_id, hashes);
|
|
@@ -12606,14 +12636,14 @@ async function processAgent(agent, agentStates) {
|
|
|
12606
12636
|
}
|
|
12607
12637
|
if (Array.isArray(refreshData.workflows)) {
|
|
12608
12638
|
try {
|
|
12609
|
-
const provWorkflowsDir =
|
|
12639
|
+
const provWorkflowsDir = join27(agentDir, ".claude", "workflows");
|
|
12610
12640
|
if (existsSync12(provWorkflowsDir)) {
|
|
12611
12641
|
const expected = new Set(refreshData.workflows.map((w) => `${w.name}.js`));
|
|
12612
12642
|
for (const file of readdirSync7(provWorkflowsDir)) {
|
|
12613
12643
|
if (!file.endsWith(".js")) continue;
|
|
12614
12644
|
if (expected.has(file)) continue;
|
|
12615
12645
|
try {
|
|
12616
|
-
rmSync5(
|
|
12646
|
+
rmSync5(join27(provWorkflowsDir, file));
|
|
12617
12647
|
} catch {
|
|
12618
12648
|
}
|
|
12619
12649
|
}
|
|
@@ -12695,7 +12725,7 @@ async function processAgent(agent, agentStates) {
|
|
|
12695
12725
|
if (written && existsSync12(agentDir)) {
|
|
12696
12726
|
const driftedFiles = [];
|
|
12697
12727
|
for (const [file, expectedHash] of written) {
|
|
12698
|
-
const localHash = hashFile(
|
|
12728
|
+
const localHash = hashFile(join27(agentDir, file));
|
|
12699
12729
|
if (localHash && localHash !== expectedHash) {
|
|
12700
12730
|
driftedFiles.push(file);
|
|
12701
12731
|
}
|
|
@@ -12706,7 +12736,7 @@ async function processAgent(agent, agentStates) {
|
|
|
12706
12736
|
try {
|
|
12707
12737
|
const localHashes = {};
|
|
12708
12738
|
for (const file of driftedFiles) {
|
|
12709
|
-
localHashes[file] = hashFile(
|
|
12739
|
+
localHashes[file] = hashFile(join27(agentDir, file));
|
|
12710
12740
|
}
|
|
12711
12741
|
await api.post("/host/drift", {
|
|
12712
12742
|
agent_id: agent.agent_id,
|
|
@@ -12908,7 +12938,7 @@ async function processAgent(agent, agentStates) {
|
|
|
12908
12938
|
const addedChannels = [...restartDecision.added];
|
|
12909
12939
|
const writeDmNoticeMarkers = isChannelAddRestart ? () => {
|
|
12910
12940
|
try {
|
|
12911
|
-
const agentAugmentedDir =
|
|
12941
|
+
const agentAugmentedDir = join27(homedir12(), ".augmented", agent.code_name);
|
|
12912
12942
|
mkdirSync10(agentAugmentedDir, { recursive: true });
|
|
12913
12943
|
const markerJson = JSON.stringify({
|
|
12914
12944
|
version: 1,
|
|
@@ -12916,7 +12946,7 @@ async function processAgent(agent, agentStates) {
|
|
|
12916
12946
|
added: addedChannels
|
|
12917
12947
|
});
|
|
12918
12948
|
for (const file of ["slack-channel-add-restart.json", "telegram-channel-add-restart.json"]) {
|
|
12919
|
-
atomicWriteFileSync(
|
|
12949
|
+
atomicWriteFileSync(join27(agentAugmentedDir, file), markerJson);
|
|
12920
12950
|
}
|
|
12921
12951
|
} catch (err) {
|
|
12922
12952
|
log(`[hot-reload] channel-add DM-notice marker write failed for '${agent.code_name}' (non-fatal): ${err.message}`);
|
|
@@ -13105,18 +13135,18 @@ async function processAgent(agent, agentStates) {
|
|
|
13105
13135
|
if (agentSessionMode === "persistent" && (agentFrameworkCache.get(agent.code_name) ?? DEFAULT_FRAMEWORK) === "claude-code") {
|
|
13106
13136
|
try {
|
|
13107
13137
|
const agentProvisionDir = agentDir;
|
|
13108
|
-
const projectDir =
|
|
13138
|
+
const projectDir = join27(homedir12(), ".augmented", agent.code_name, "project");
|
|
13109
13139
|
mkdirSync10(agentProvisionDir, { recursive: true });
|
|
13110
13140
|
mkdirSync10(projectDir, { recursive: true });
|
|
13111
|
-
const provisionMcpPath =
|
|
13112
|
-
const projectMcpPath =
|
|
13141
|
+
const provisionMcpPath = join27(agentProvisionDir, ".mcp.json");
|
|
13142
|
+
const projectMcpPath = join27(projectDir, ".mcp.json");
|
|
13113
13143
|
let mcpConfig = { mcpServers: {} };
|
|
13114
13144
|
try {
|
|
13115
|
-
mcpConfig = JSON.parse(
|
|
13145
|
+
mcpConfig = JSON.parse(readFileSync22(provisionMcpPath, "utf-8"));
|
|
13116
13146
|
if (!mcpConfig.mcpServers) mcpConfig.mcpServers = {};
|
|
13117
13147
|
} catch {
|
|
13118
13148
|
}
|
|
13119
|
-
const localDirectChatChannel =
|
|
13149
|
+
const localDirectChatChannel = join27(homedir12(), ".augmented", "_mcp", "direct-chat-channel.js");
|
|
13120
13150
|
const directChatTeamSettings = refreshData.team?.settings;
|
|
13121
13151
|
const directChatTz = (() => {
|
|
13122
13152
|
const tz = directChatTeamSettings?.["timezone"];
|
|
@@ -13142,7 +13172,7 @@ async function processAgent(agent, agentStates) {
|
|
|
13142
13172
|
// ~/.augmented/<codeName>/.current-turn-initiator.json. Note getAgentDir
|
|
13143
13173
|
// returns the agent root (NOT the /provision subdir `agentDir` points at),
|
|
13144
13174
|
// so it byte-matches the broker readers' path.
|
|
13145
|
-
AGT_TURN_INITIATOR_FILE:
|
|
13175
|
+
AGT_TURN_INITIATOR_FILE: join27(
|
|
13146
13176
|
frameworkAdapter.getAgentDir(agent.code_name),
|
|
13147
13177
|
".current-turn-initiator.json"
|
|
13148
13178
|
)
|
|
@@ -13162,7 +13192,7 @@ async function processAgent(agent, agentStates) {
|
|
|
13162
13192
|
log(`Channel credentials written for '${agent.code_name}/direct-chat'`);
|
|
13163
13193
|
}
|
|
13164
13194
|
}
|
|
13165
|
-
const staleChannelsPath =
|
|
13195
|
+
const staleChannelsPath = join27(projectDir, ".mcp-channels.json");
|
|
13166
13196
|
if (existsSync12(staleChannelsPath)) {
|
|
13167
13197
|
try {
|
|
13168
13198
|
rmSync5(staleChannelsPath, { force: true });
|
|
@@ -13252,7 +13282,7 @@ async function processAgent(agent, agentStates) {
|
|
|
13252
13282
|
}
|
|
13253
13283
|
if (hostFlagStore().getBoolean("connectivity-probe")) {
|
|
13254
13284
|
try {
|
|
13255
|
-
const probeProjectDir =
|
|
13285
|
+
const probeProjectDir = join27(homedir12(), ".augmented", agent.code_name, "project");
|
|
13256
13286
|
let probeSet = integrations;
|
|
13257
13287
|
try {
|
|
13258
13288
|
const quarantined = await api.post("/host/agent-integrations/quarantined", { agent_id: agent.agent_id });
|
|
@@ -13298,7 +13328,7 @@ async function processAgent(agent, agentStates) {
|
|
|
13298
13328
|
const forceDue = attemptsLeft > 0;
|
|
13299
13329
|
let probeRan = false;
|
|
13300
13330
|
try {
|
|
13301
|
-
const probeProjectDir =
|
|
13331
|
+
const probeProjectDir = join27(homedir12(), ".augmented", agent.code_name, "project");
|
|
13302
13332
|
probeRan = await runAgentSessionToolBindProbes(agent, integrations, probeProjectDir, { forceDue });
|
|
13303
13333
|
} catch (err) {
|
|
13304
13334
|
log(`Session-tool-bind probe failed for '${agent.code_name}': ${err.message}`);
|
|
@@ -13375,11 +13405,11 @@ async function processAgent(agent, agentStates) {
|
|
|
13375
13405
|
const intHash = computeIntegrationsHash(integrations);
|
|
13376
13406
|
const prevIntHash = agentState.knownIntegrationHashes.get(agent.agent_id);
|
|
13377
13407
|
if (intHash !== prevIntHash) {
|
|
13378
|
-
const projectDir =
|
|
13379
|
-
const envIntPath =
|
|
13408
|
+
const projectDir = join27(homedir12(), ".augmented", agent.code_name, "project");
|
|
13409
|
+
const envIntPath = join27(projectDir, ".env.integrations");
|
|
13380
13410
|
let preWriteEnv;
|
|
13381
13411
|
try {
|
|
13382
|
-
preWriteEnv =
|
|
13412
|
+
preWriteEnv = readFileSync22(envIntPath, "utf-8");
|
|
13383
13413
|
} catch {
|
|
13384
13414
|
preWriteEnv = void 0;
|
|
13385
13415
|
}
|
|
@@ -13398,9 +13428,9 @@ async function processAgent(agent, agentStates) {
|
|
|
13398
13428
|
}
|
|
13399
13429
|
if (fw === "claude-code" && isSessionHealthy(agent.code_name)) {
|
|
13400
13430
|
try {
|
|
13401
|
-
const projectMcpPath =
|
|
13402
|
-
const postWriteEnv =
|
|
13403
|
-
const mcpContent =
|
|
13431
|
+
const projectMcpPath = join27(projectDir, ".mcp.json");
|
|
13432
|
+
const postWriteEnv = readFileSync22(envIntPath, "utf-8");
|
|
13433
|
+
const mcpContent = readFileSync22(projectMcpPath, "utf-8");
|
|
13404
13434
|
const changedVars = diffEnvIntegrations(preWriteEnv, postWriteEnv);
|
|
13405
13435
|
const mcpJsonForReap = JSON.parse(mcpContent);
|
|
13406
13436
|
const affectedServerKeys = findMcpServersUsingVars(mcpJsonForReap, changedVars);
|
|
@@ -13657,12 +13687,12 @@ async function processAgent(agent, agentStates) {
|
|
|
13657
13687
|
const frameworkId2 = frameworkAdapter.id;
|
|
13658
13688
|
const candidateSkillDirs = [
|
|
13659
13689
|
// Claude Code — framework runtime tree
|
|
13660
|
-
|
|
13690
|
+
join27(homedir13(), ".augmented", agent.code_name, "skills"),
|
|
13661
13691
|
// Claude Code — project tree
|
|
13662
|
-
|
|
13692
|
+
join27(homedir13(), ".augmented", agent.code_name, "project", ".claude", "skills"),
|
|
13663
13693
|
// Defensive: legacy provision-side path, not currently an
|
|
13664
13694
|
// install target but cheap to sweep.
|
|
13665
|
-
|
|
13695
|
+
join27(agentDir, ".claude", "skills")
|
|
13666
13696
|
];
|
|
13667
13697
|
const existingDirs = candidateSkillDirs.filter((d) => existsSync12(d));
|
|
13668
13698
|
const discoveredEntries = /* @__PURE__ */ new Set();
|
|
@@ -13678,7 +13708,7 @@ async function processAgent(agent, agentStates) {
|
|
|
13678
13708
|
}
|
|
13679
13709
|
const removeSkillFolder = (entry, reason) => {
|
|
13680
13710
|
for (const dir of existingDirs) {
|
|
13681
|
-
const p =
|
|
13711
|
+
const p = join27(dir, entry);
|
|
13682
13712
|
if (existsSync12(p)) {
|
|
13683
13713
|
rmSync6(p, { recursive: true, force: true });
|
|
13684
13714
|
}
|
|
@@ -13698,7 +13728,7 @@ async function processAgent(agent, agentStates) {
|
|
|
13698
13728
|
const sharedSkillsPayload = refreshAny.shared_skills;
|
|
13699
13729
|
const desiredResolved = globalSkillsPayload !== void 0 || sharedSkillsPayload !== void 0;
|
|
13700
13730
|
const manifestPath = managedSkillManifestPath(
|
|
13701
|
-
|
|
13731
|
+
join27(homedir12(), ".augmented", agent.code_name)
|
|
13702
13732
|
);
|
|
13703
13733
|
const prevIds = /* @__PURE__ */ new Set([
|
|
13704
13734
|
...agentState.knownGlobalSkillIds.get(agent.agent_id) ?? /* @__PURE__ */ new Set(),
|
|
@@ -13718,15 +13748,15 @@ async function processAgent(agent, agentStates) {
|
|
|
13718
13748
|
}
|
|
13719
13749
|
if (plan.removes.length) {
|
|
13720
13750
|
const globalSkillDirs = [
|
|
13721
|
-
|
|
13722
|
-
|
|
13723
|
-
|
|
13751
|
+
join27(homedir12(), ".augmented", agent.code_name, "skills"),
|
|
13752
|
+
join27(homedir12(), ".augmented", agent.code_name, "project", ".claude", "skills"),
|
|
13753
|
+
join27(agentDir, ".claude", "skills")
|
|
13724
13754
|
];
|
|
13725
13755
|
for (const id of plan.removes) {
|
|
13726
13756
|
let prunedAny = false;
|
|
13727
13757
|
for (const dir of globalSkillDirs) {
|
|
13728
|
-
const p =
|
|
13729
|
-
if (existsSync12(p) && existsSync12(
|
|
13758
|
+
const p = join27(dir, id);
|
|
13759
|
+
if (existsSync12(p) && existsSync12(join27(p, "SKILL.md"))) {
|
|
13730
13760
|
rmSync5(p, { recursive: true, force: true });
|
|
13731
13761
|
prunedAny = true;
|
|
13732
13762
|
}
|
|
@@ -13957,8 +13987,8 @@ async function processAgent(agent, agentStates) {
|
|
|
13957
13987
|
const sess = getSessionState(agent.code_name);
|
|
13958
13988
|
let mcpJsonParsed = null;
|
|
13959
13989
|
try {
|
|
13960
|
-
const mcpPath =
|
|
13961
|
-
mcpJsonParsed = JSON.parse(
|
|
13990
|
+
const mcpPath = join27(getProjectDir(agent.code_name), ".mcp.json");
|
|
13991
|
+
mcpJsonParsed = JSON.parse(readFileSync22(mcpPath, "utf-8"));
|
|
13962
13992
|
} catch {
|
|
13963
13993
|
}
|
|
13964
13994
|
reapMissingMcpSessions({
|
|
@@ -14384,7 +14414,7 @@ Retried to the limit after repeated stalls \u2014 needs a look.`).catch(() => {
|
|
|
14384
14414
|
if (trackedFiles.length > 0 && existsSync12(agentDir)) {
|
|
14385
14415
|
const hashes = /* @__PURE__ */ new Map();
|
|
14386
14416
|
for (const file of trackedFiles) {
|
|
14387
|
-
const h = hashFile(
|
|
14417
|
+
const h = hashFile(join27(agentDir, file));
|
|
14388
14418
|
if (h) hashes.set(file, h);
|
|
14389
14419
|
}
|
|
14390
14420
|
agentState.writtenHashes.set(agent.agent_id, hashes);
|
|
@@ -14399,7 +14429,7 @@ Retried to the limit after repeated stalls \u2014 needs a look.`).catch(() => {
|
|
|
14399
14429
|
refreshData.agent.onboarding_state
|
|
14400
14430
|
);
|
|
14401
14431
|
const obStep = obState.step;
|
|
14402
|
-
const markerPath =
|
|
14432
|
+
const markerPath = join27(homedir12(), ".augmented", agent.code_name, "onboarding-drive.json");
|
|
14403
14433
|
const marker = readOnboardingDriveMarker(markerPath);
|
|
14404
14434
|
const decision = decideOnboardingDrive(obStep, marker, Date.now(), obState.generation ?? 0);
|
|
14405
14435
|
if (decision.clearMarker) {
|
|
@@ -14487,7 +14517,7 @@ async function ensureOpencodeRuntime(agent, refreshData, agentTimezone) {
|
|
|
14487
14517
|
}
|
|
14488
14518
|
stopOpencodeSlackIngest(codeName, log);
|
|
14489
14519
|
stopOpencodeTelegramIngest(codeName, log);
|
|
14490
|
-
const opencodeProjectDir =
|
|
14520
|
+
const opencodeProjectDir = join27(getFramework("opencode").getAgentDir(codeName), "provision");
|
|
14491
14521
|
const serveEnv = {
|
|
14492
14522
|
AGT_HOST: requireHost(),
|
|
14493
14523
|
AGT_API_KEY: getApiKey() ?? void 0,
|
|
@@ -14537,8 +14567,8 @@ async function ensurePersistentSession(agent, tasks, boardItems, refreshData) {
|
|
|
14537
14567
|
});
|
|
14538
14568
|
}
|
|
14539
14569
|
const projectDir = getProjectDir(codeName);
|
|
14540
|
-
const mcpConfigPath =
|
|
14541
|
-
const claudeMdPath =
|
|
14570
|
+
const mcpConfigPath = join27(projectDir, ".mcp.json");
|
|
14571
|
+
const claudeMdPath = join27(projectDir, "CLAUDE.md");
|
|
14542
14572
|
if (restartBreaker.isTripped(codeName)) {
|
|
14543
14573
|
const trip = restartBreaker.getTrip(codeName);
|
|
14544
14574
|
return {
|
|
@@ -15154,7 +15184,7 @@ async function handleRestartDoorbell(agentId, requestedAt, restartReason) {
|
|
|
15154
15184
|
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}`));
|
|
15155
15185
|
void (async () => {
|
|
15156
15186
|
try {
|
|
15157
|
-
const { collectDiagnostics } = await import("../persistent-session-
|
|
15187
|
+
const { collectDiagnostics } = await import("../persistent-session-TSPVNVQL.js");
|
|
15158
15188
|
await api.post("/host/heartbeat", {
|
|
15159
15189
|
host_id: hostId,
|
|
15160
15190
|
agent_diagnostics: collectDiagnostics([codeName], quarantineEntriesFor, claudeMdSizeFor)
|
|
@@ -15204,7 +15234,7 @@ async function respawnAgentAfterMcpStop(codeName, reason) {
|
|
|
15204
15234
|
}
|
|
15205
15235
|
try {
|
|
15206
15236
|
const hostId = await getHostId();
|
|
15207
|
-
const { collectDiagnostics } = await import("../persistent-session-
|
|
15237
|
+
const { collectDiagnostics } = await import("../persistent-session-TSPVNVQL.js");
|
|
15208
15238
|
await api.post("/host/heartbeat", {
|
|
15209
15239
|
host_id: hostId,
|
|
15210
15240
|
agent_diagnostics: collectDiagnostics([codeName], quarantineEntriesFor, claudeMdSizeFor)
|
|
@@ -15447,12 +15477,42 @@ async function processDirectChatMessageOpencode(agent, msg) {
|
|
|
15447
15477
|
}
|
|
15448
15478
|
if (result.status === "replied" && result.reply) {
|
|
15449
15479
|
try {
|
|
15450
|
-
await api.post("/host/direct-chat/reply", {
|
|
15480
|
+
const body = await api.post("/host/direct-chat/reply", {
|
|
15451
15481
|
agent_id: agent.agentId,
|
|
15452
15482
|
session_id: msg.session_id,
|
|
15453
15483
|
content: result.reply,
|
|
15454
15484
|
message_ids: [msg.id]
|
|
15455
15485
|
});
|
|
15486
|
+
const verdict = classifyCursorAdvance({
|
|
15487
|
+
messageIds: [msg.id],
|
|
15488
|
+
httpOk: true,
|
|
15489
|
+
body
|
|
15490
|
+
});
|
|
15491
|
+
if (verdict.outcome === "failed") {
|
|
15492
|
+
log(
|
|
15493
|
+
`[direct-chat] opencode reply REFUSED for '${agent.codeName}' (msg=${msg.id}): ${verdict.error} \u2014 leaving for redelivery`
|
|
15494
|
+
);
|
|
15495
|
+
return;
|
|
15496
|
+
}
|
|
15497
|
+
if (verdict.outcome === "shortfall") {
|
|
15498
|
+
log(
|
|
15499
|
+
formatCursorAdvanceShortfall(verdict, {
|
|
15500
|
+
route: "reply",
|
|
15501
|
+
site: "opencode-reply",
|
|
15502
|
+
sessionId: msg.session_id,
|
|
15503
|
+
// Nothing local to clear on this arm — the manager holds no claim
|
|
15504
|
+
// tracker and writes no pending marker for an opencode agent. The
|
|
15505
|
+
// field is still emitted (as `none`) so a fleet-wide grep for
|
|
15506
|
+
// `cleared_anyway=` does not silently skip this site.
|
|
15507
|
+
cleared: []
|
|
15508
|
+
})
|
|
15509
|
+
);
|
|
15510
|
+
recordCursorAdvanceShortfall(dirname8(paneLogPath(agent.codeName)), "direct-chat-manager", {
|
|
15511
|
+
route: "reply",
|
|
15512
|
+
reason: verdict.reason,
|
|
15513
|
+
partial: verdict.partial
|
|
15514
|
+
});
|
|
15515
|
+
}
|
|
15456
15516
|
log(`[direct-chat] opencode replied for '${agent.codeName}' (msg=${msg.id}, ${result.reply.length} chars)`);
|
|
15457
15517
|
} catch (err) {
|
|
15458
15518
|
log(`[direct-chat] opencode reply POST failed for '${agent.codeName}' (msg=${msg.id}): ${err.message} \u2014 leaving for redelivery`);
|
|
@@ -15496,7 +15556,7 @@ async function processDirectChatMessage(agent, msg) {
|
|
|
15496
15556
|
try {
|
|
15497
15557
|
const doorbell = directChatDoorbellPath(agent.agentId, homedir12());
|
|
15498
15558
|
mkdirSync10(dirname8(doorbell), { recursive: true });
|
|
15499
|
-
|
|
15559
|
+
writeFileSync13(doorbell, String(Date.now()));
|
|
15500
15560
|
log(`[direct-chat] Doorbell rung for '${agent.codeName}' (msg=${msg.id}) \u2014 in-session MCP will pull via the cursor`);
|
|
15501
15561
|
return;
|
|
15502
15562
|
} catch (err) {
|
|
@@ -15606,7 +15666,7 @@ ${formatRunMarker(run_id)}` : KANBAN_CHECK_COMMAND;
|
|
|
15606
15666
|
try {
|
|
15607
15667
|
const doorbell = directChatDoorbellPath(agentId, homedir12());
|
|
15608
15668
|
mkdirSync10(dirname8(doorbell), { recursive: true });
|
|
15609
|
-
|
|
15669
|
+
writeFileSync13(doorbell, String(Date.now()));
|
|
15610
15670
|
} catch (err) {
|
|
15611
15671
|
log(`[kanban] doorbell ring failed for '${codeName}': ${err.message} (notice still queued)`);
|
|
15612
15672
|
}
|
|
@@ -15662,7 +15722,7 @@ async function processClaudePairSessions(agents) {
|
|
|
15662
15722
|
killPairSession,
|
|
15663
15723
|
pairTmuxSession,
|
|
15664
15724
|
finalizeClaudePairOnboarding
|
|
15665
|
-
} = await import("../claude-pair-runtime-
|
|
15725
|
+
} = await import("../claude-pair-runtime-LCQYCW67.js");
|
|
15666
15726
|
for (const pairId of pendingResp.cancelled_pair_ids ?? []) {
|
|
15667
15727
|
log(`[claude-pair] sweeping orphan tmux session for pair ${pairId.slice(0, 8)}`);
|
|
15668
15728
|
const killed = await killPairSession(pairTmuxSession(pairId));
|
|
@@ -15916,8 +15976,8 @@ function parseMemoryFile(raw, fallbackName) {
|
|
|
15916
15976
|
};
|
|
15917
15977
|
}
|
|
15918
15978
|
async function syncMemories(agent, configDir, log2) {
|
|
15919
|
-
const projectDir =
|
|
15920
|
-
const memoryDir =
|
|
15979
|
+
const projectDir = join27(configDir, agent.code_name, "project");
|
|
15980
|
+
const memoryDir = join27(projectDir, "memory");
|
|
15921
15981
|
const isFreshSync = pendingFreshMemorySync.has(agent.agent_id);
|
|
15922
15982
|
if (isFreshSync) {
|
|
15923
15983
|
log2(`[memory-sync] Fresh-sync requested for '${agent.code_name}' \u2014 pulling DB first`);
|
|
@@ -15935,7 +15995,7 @@ async function syncMemories(agent, configDir, log2) {
|
|
|
15935
15995
|
for (const file of readdirSync7(memoryDir)) {
|
|
15936
15996
|
if (!file.endsWith(".md")) continue;
|
|
15937
15997
|
try {
|
|
15938
|
-
const raw =
|
|
15998
|
+
const raw = readFileSync22(join27(memoryDir, file), "utf-8");
|
|
15939
15999
|
const fileHash = createHash16("sha256").update(raw).digest("hex").slice(0, 16);
|
|
15940
16000
|
currentHashes.set(file, fileHash);
|
|
15941
16001
|
if (prevHashes.get(file) === fileHash) continue;
|
|
@@ -15960,7 +16020,7 @@ async function syncMemories(agent, configDir, log2) {
|
|
|
15960
16020
|
} catch (err) {
|
|
15961
16021
|
for (const mem of changedMemories) {
|
|
15962
16022
|
for (const [file] of currentHashes) {
|
|
15963
|
-
const parsed = parseMemoryFile(
|
|
16023
|
+
const parsed = parseMemoryFile(readFileSync22(join27(memoryDir, file), "utf-8"), file.replace(/\.md$/, ""));
|
|
15964
16024
|
if (parsed?.name === mem.name) currentHashes.delete(file);
|
|
15965
16025
|
}
|
|
15966
16026
|
}
|
|
@@ -15995,7 +16055,7 @@ async function downloadMemories(agent, memoryDir, log2, { force }) {
|
|
|
15995
16055
|
const mem = dbMemories.memories[i];
|
|
15996
16056
|
const rawSlug = mem.name.toLowerCase().replace(/[^a-z0-9]+/g, "-").replace(/(^-|-$)/g, "").slice(0, 60);
|
|
15997
16057
|
const slug = rawSlug || `memory-${i}`;
|
|
15998
|
-
const filePath =
|
|
16058
|
+
const filePath = join27(memoryDir, `${slug}.md`);
|
|
15999
16059
|
const desired = `---
|
|
16000
16060
|
name: ${JSON.stringify(mem.name)}
|
|
16001
16061
|
type: ${mem.type}
|
|
@@ -16007,14 +16067,14 @@ ${mem.content}
|
|
|
16007
16067
|
if (existsSync12(filePath)) {
|
|
16008
16068
|
let existing = "";
|
|
16009
16069
|
try {
|
|
16010
|
-
existing =
|
|
16070
|
+
existing = readFileSync22(filePath, "utf-8");
|
|
16011
16071
|
} catch {
|
|
16012
16072
|
}
|
|
16013
16073
|
if (existing === desired) continue;
|
|
16014
|
-
|
|
16074
|
+
writeFileSync13(filePath, desired);
|
|
16015
16075
|
overwritten++;
|
|
16016
16076
|
} else {
|
|
16017
|
-
|
|
16077
|
+
writeFileSync13(filePath, desired);
|
|
16018
16078
|
written++;
|
|
16019
16079
|
}
|
|
16020
16080
|
}
|
|
@@ -16271,7 +16331,7 @@ function startManager(opts) {
|
|
|
16271
16331
|
try {
|
|
16272
16332
|
const stateFile = getStateFile();
|
|
16273
16333
|
if (existsSync12(stateFile)) {
|
|
16274
|
-
const raw =
|
|
16334
|
+
const raw = readFileSync22(stateFile, "utf-8");
|
|
16275
16335
|
const parsed = JSON.parse(raw);
|
|
16276
16336
|
if (Array.isArray(parsed.agents)) {
|
|
16277
16337
|
state6.agents = parsed.agents;
|
|
@@ -16298,7 +16358,7 @@ function startManager(opts) {
|
|
|
16298
16358
|
log(`[startup] state rehydration failed (continuing with empty state): ${err.message}`);
|
|
16299
16359
|
}
|
|
16300
16360
|
log(
|
|
16301
|
-
`[startup] worker pid=${process.pid} ppid=${process.ppid} node=${process.version} log=${
|
|
16361
|
+
`[startup] worker pid=${process.pid} ppid=${process.ppid} node=${process.version} log=${join27(homedir12(), ".augmented", "manager.log")}`
|
|
16302
16362
|
);
|
|
16303
16363
|
deployMcpAssets();
|
|
16304
16364
|
reapOrphanChannelMcps({ log });
|
|
@@ -16327,7 +16387,7 @@ async function reapOrphanedClaudePids() {
|
|
|
16327
16387
|
const looksLikeClaude = (pid) => {
|
|
16328
16388
|
if (process.platform !== "linux") return true;
|
|
16329
16389
|
try {
|
|
16330
|
-
const comm =
|
|
16390
|
+
const comm = readFileSync22(`/proc/${pid}/comm`, "utf-8").trim().toLowerCase();
|
|
16331
16391
|
return comm.includes("claude");
|
|
16332
16392
|
} catch {
|
|
16333
16393
|
return false;
|
|
@@ -16424,14 +16484,14 @@ function restartRunningChannelMcps(basenames) {
|
|
|
16424
16484
|
}
|
|
16425
16485
|
}
|
|
16426
16486
|
function deployMcpAssets() {
|
|
16427
|
-
const targetDir =
|
|
16487
|
+
const targetDir = join27(homedir12(), ".augmented", "_mcp");
|
|
16428
16488
|
mkdirSync10(targetDir, { recursive: true });
|
|
16429
16489
|
const moduleDir = dirname8(fileURLToPath(import.meta.url));
|
|
16430
16490
|
let mcpSourceDir = "";
|
|
16431
16491
|
let dir = moduleDir;
|
|
16432
16492
|
for (let i = 0; i < 6; i++) {
|
|
16433
|
-
const candidate =
|
|
16434
|
-
if (existsSync12(
|
|
16493
|
+
const candidate = join27(dir, "dist", "mcp");
|
|
16494
|
+
if (existsSync12(join27(candidate, "index.js"))) {
|
|
16435
16495
|
mcpSourceDir = candidate;
|
|
16436
16496
|
break;
|
|
16437
16497
|
}
|
|
@@ -16447,7 +16507,7 @@ function deployMcpAssets() {
|
|
|
16447
16507
|
const fileHash = (p) => {
|
|
16448
16508
|
try {
|
|
16449
16509
|
if (!existsSync12(p)) return null;
|
|
16450
|
-
return createHash16("sha256").update(
|
|
16510
|
+
return createHash16("sha256").update(readFileSync22(p)).digest("hex");
|
|
16451
16511
|
} catch {
|
|
16452
16512
|
return null;
|
|
16453
16513
|
}
|
|
@@ -16511,8 +16571,8 @@ function deployMcpAssets() {
|
|
|
16511
16571
|
// needs restarting to pick up a token rotation.
|
|
16512
16572
|
"xero.js"
|
|
16513
16573
|
]) {
|
|
16514
|
-
const src =
|
|
16515
|
-
const dst =
|
|
16574
|
+
const src = join27(mcpSourceDir, file);
|
|
16575
|
+
const dst = join27(targetDir, file);
|
|
16516
16576
|
if (!existsSync12(src)) continue;
|
|
16517
16577
|
const before = fileHash(dst);
|
|
16518
16578
|
try {
|
|
@@ -16530,23 +16590,23 @@ function deployMcpAssets() {
|
|
|
16530
16590
|
log(`[manager] Bundle(s) updated: ${changedBasenames.join(", ")} \u2014 signalling running instances to restart`);
|
|
16531
16591
|
restartRunningChannelMcps(changedBasenames);
|
|
16532
16592
|
}
|
|
16533
|
-
const localMcpPath =
|
|
16593
|
+
const localMcpPath = join27(targetDir, "index.js");
|
|
16534
16594
|
try {
|
|
16535
|
-
const agentsDir =
|
|
16595
|
+
const agentsDir = join27(homedir12(), ".augmented", "agents");
|
|
16536
16596
|
if (existsSync12(agentsDir)) {
|
|
16537
16597
|
for (const entry of readdirSync7(agentsDir, { withFileTypes: true })) {
|
|
16538
16598
|
if (!entry.isDirectory()) continue;
|
|
16539
16599
|
for (const subdir of ["provision", "project"]) {
|
|
16540
|
-
const mcpJsonPath =
|
|
16600
|
+
const mcpJsonPath = join27(agentsDir, entry.name, subdir, ".mcp.json");
|
|
16541
16601
|
try {
|
|
16542
|
-
const raw =
|
|
16602
|
+
const raw = readFileSync22(mcpJsonPath, "utf-8");
|
|
16543
16603
|
if (!raw.includes("@integrity-labs/augmented-mcp")) continue;
|
|
16544
16604
|
const mcpConfig = JSON.parse(raw);
|
|
16545
16605
|
const augServer = mcpConfig.mcpServers?.["augmented"];
|
|
16546
16606
|
if (!augServer) continue;
|
|
16547
16607
|
augServer.command = "node";
|
|
16548
16608
|
augServer.args = [localMcpPath];
|
|
16549
|
-
|
|
16609
|
+
writeFileSync13(mcpJsonPath, JSON.stringify(mcpConfig, null, 2));
|
|
16550
16610
|
log(`[manager] Patched ${entry.name}/${subdir}/.mcp.json: npx \u2192 node`);
|
|
16551
16611
|
} catch {
|
|
16552
16612
|
}
|