@integrity-labs/agt-cli 0.27.150-test.16 → 0.27.150-test.17
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 +13 -6
- package/dist/bin/agt.js.map +1 -1
- package/dist/{chunk-WOOYOAPG.js → chunk-FZTGR2AQ.js} +153 -20
- package/dist/chunk-FZTGR2AQ.js.map +1 -0
- package/dist/{chunk-7GKJZBTB.js → chunk-HXMLMIR4.js} +230 -53
- package/dist/chunk-HXMLMIR4.js.map +1 -0
- package/dist/{chunk-QHEAAPEG.js → chunk-L2JA4OHU.js} +108 -2
- package/dist/chunk-L2JA4OHU.js.map +1 -0
- package/dist/{claude-pair-runtime-GIUCD7IG.js → claude-pair-runtime-QYJUJUYY.js} +2 -2
- package/dist/lib/manager-worker.js +422 -165
- package/dist/lib/manager-worker.js.map +1 -1
- package/dist/mcp/augmented-admin.js +42 -4
- package/dist/{persistent-session-35PWSTLO.js → persistent-session-IKQLTZZ6.js} +3 -4
- package/dist/{responsiveness-probe-MA4M2QM4.js → responsiveness-probe-2K4QHOWW.js} +3 -4
- package/dist/{responsiveness-probe-MA4M2QM4.js.map → responsiveness-probe-2K4QHOWW.js.map} +1 -1
- package/package.json +1 -1
- package/dist/chunk-354FAVQR.js +0 -173
- package/dist/chunk-354FAVQR.js.map +0 -1
- package/dist/chunk-7GKJZBTB.js.map +0 -1
- package/dist/chunk-QHEAAPEG.js.map +0 -1
- package/dist/chunk-WOOYOAPG.js.map +0 -1
- package/dist/daily-session-PNQX5URX.js +0 -27
- package/dist/persistent-session-35PWSTLO.js.map +0 -1
- /package/dist/{claude-pair-runtime-GIUCD7IG.js.map → claude-pair-runtime-QYJUJUYY.js.map} +0 -0
- /package/dist/{daily-session-PNQX5URX.js.map → persistent-session-IKQLTZZ6.js.map} +0 -0
|
@@ -15,10 +15,11 @@ import {
|
|
|
15
15
|
provisionAutoKanbanProgressHook,
|
|
16
16
|
provisionIsolationHook,
|
|
17
17
|
provisionOrientHook,
|
|
18
|
+
provisionSessionStateHook,
|
|
18
19
|
provisionStopHook,
|
|
19
20
|
requireHost,
|
|
20
21
|
safeWriteJsonAtomic
|
|
21
|
-
} from "../chunk-
|
|
22
|
+
} from "../chunk-L2JA4OHU.js";
|
|
22
23
|
import {
|
|
23
24
|
getProjectDir as getProjectDir2,
|
|
24
25
|
getReadyTasks,
|
|
@@ -37,10 +38,13 @@ import {
|
|
|
37
38
|
getSessionState,
|
|
38
39
|
injectMessage,
|
|
39
40
|
injectMessageWithStatus,
|
|
41
|
+
isAgentIdle,
|
|
40
42
|
isAgentPromptReady,
|
|
41
43
|
isSessionHealthy,
|
|
44
|
+
isStaleForToday,
|
|
42
45
|
paneLogPath,
|
|
43
46
|
parseEnvIntegrations,
|
|
47
|
+
peekCurrentSession,
|
|
44
48
|
prepareForRespawn,
|
|
45
49
|
probeMcpEnvSubstitution,
|
|
46
50
|
readPaneLogTail,
|
|
@@ -49,16 +53,20 @@ import {
|
|
|
49
53
|
rotateSessionForWedge,
|
|
50
54
|
sanitizeMcpJson,
|
|
51
55
|
sendToAgent,
|
|
56
|
+
sessionTranscriptDir,
|
|
52
57
|
startPersistentSession,
|
|
53
58
|
stopAllSessionsAndWait,
|
|
54
59
|
stopPersistentSession,
|
|
60
|
+
subagentActivityAgeSeconds,
|
|
55
61
|
takeWatchdogGiveUpCount,
|
|
56
|
-
takeZombieDetection
|
|
57
|
-
|
|
62
|
+
takeZombieDetection,
|
|
63
|
+
transcriptActivityAgeSeconds
|
|
64
|
+
} from "../chunk-HXMLMIR4.js";
|
|
58
65
|
import {
|
|
59
66
|
KANBAN_CHECK_COMMAND,
|
|
60
67
|
MAX_AVATAR_ENV_URL_BYTES,
|
|
61
68
|
SUPPRESS_SENTINEL,
|
|
69
|
+
StreamEncoder,
|
|
62
70
|
appendDmFooter,
|
|
63
71
|
attributeTranscriptUsageByRun,
|
|
64
72
|
classifyActor,
|
|
@@ -83,13 +91,7 @@ import {
|
|
|
83
91
|
resolveDmTarget,
|
|
84
92
|
worseConnectivityOutcome,
|
|
85
93
|
wrapScheduledTaskPrompt
|
|
86
|
-
} from "../chunk-
|
|
87
|
-
import {
|
|
88
|
-
isAgentIdle,
|
|
89
|
-
isStaleForToday,
|
|
90
|
-
peekCurrentSession,
|
|
91
|
-
sessionTranscriptDir
|
|
92
|
-
} from "../chunk-354FAVQR.js";
|
|
94
|
+
} from "../chunk-FZTGR2AQ.js";
|
|
93
95
|
import {
|
|
94
96
|
parsePsRows,
|
|
95
97
|
reapOrphanChannelMcps
|
|
@@ -100,8 +102,8 @@ import { createHash as createHash3 } from "crypto";
|
|
|
100
102
|
import { readFileSync as readFileSync9, writeFileSync as writeFileSync4, appendFileSync, mkdirSync as mkdirSync4, chmodSync, existsSync as existsSync5, rmSync as rmSync2, readdirSync as readdirSync4, statSync as statSync3, unlinkSync, copyFileSync } from "fs";
|
|
101
103
|
import https from "https";
|
|
102
104
|
import { execFileSync as syncExecFile } from "child_process";
|
|
103
|
-
import { join as
|
|
104
|
-
import { homedir as
|
|
105
|
+
import { join as join9, dirname as dirname3 } from "path";
|
|
106
|
+
import { homedir as homedir5 } from "os";
|
|
105
107
|
import { fileURLToPath } from "url";
|
|
106
108
|
|
|
107
109
|
// src/lib/mcp-config-drift.ts
|
|
@@ -1515,6 +1517,7 @@ function isUrgentUpgrade(opts) {
|
|
|
1515
1517
|
}
|
|
1516
1518
|
var RESTART_IDLE_THRESHOLD_SECONDS = 120;
|
|
1517
1519
|
var RESTART_INBOUND_QUIET_SECONDS = 300;
|
|
1520
|
+
var RESTART_TRANSCRIPT_STALE_SECONDS = 60;
|
|
1518
1521
|
var GATEABLE_RESTART_REASONS = /* @__PURE__ */ new Set([
|
|
1519
1522
|
"model-change",
|
|
1520
1523
|
"channel-set-change",
|
|
@@ -1533,9 +1536,11 @@ function decideRestartGate(opts) {
|
|
|
1533
1536
|
}
|
|
1534
1537
|
const paneThreshold = opts.idleThresholdSeconds ?? RESTART_IDLE_THRESHOLD_SECONDS;
|
|
1535
1538
|
const inboundThreshold = opts.inboundQuietSeconds ?? RESTART_INBOUND_QUIET_SECONDS;
|
|
1536
|
-
const
|
|
1539
|
+
const transcriptThreshold = opts.transcriptStaleSeconds ?? RESTART_TRANSCRIPT_STALE_SECONDS;
|
|
1540
|
+
const transcriptAge = opts.transcriptAgeSeconds ?? null;
|
|
1541
|
+
const progressBusy = transcriptAge !== null ? transcriptAge < transcriptThreshold : opts.paneLogAgeSeconds !== null && opts.paneLogAgeSeconds < paneThreshold;
|
|
1537
1542
|
const inboundBusy = opts.inboundAgeSeconds !== null && opts.inboundAgeSeconds < inboundThreshold;
|
|
1538
|
-
if (
|
|
1543
|
+
if (progressBusy || inboundBusy) return "defer-idle";
|
|
1539
1544
|
return "proceed";
|
|
1540
1545
|
}
|
|
1541
1546
|
|
|
@@ -1682,9 +1687,146 @@ var DirectChatSpawnGate = class {
|
|
|
1682
1687
|
}
|
|
1683
1688
|
};
|
|
1684
1689
|
|
|
1690
|
+
// src/lib/artifact-stream.ts
|
|
1691
|
+
import { join as join2 } from "path";
|
|
1692
|
+
import { homedir } from "os";
|
|
1693
|
+
import { readdir, stat, readFile } from "fs/promises";
|
|
1694
|
+
var ARTEFACT_ENTRY_FILE = "index.html";
|
|
1695
|
+
function errMessage(err) {
|
|
1696
|
+
return err instanceof Error ? err.message : String(err);
|
|
1697
|
+
}
|
|
1698
|
+
var ArtifactStreamSession = class {
|
|
1699
|
+
constructor(agentId, clientToken, deps, meta = {}) {
|
|
1700
|
+
this.agentId = agentId;
|
|
1701
|
+
this.clientToken = clientToken;
|
|
1702
|
+
this.deps = deps;
|
|
1703
|
+
this.meta = meta;
|
|
1704
|
+
this.encoder = new StreamEncoder(deps.now ? { now: deps.now } : {});
|
|
1705
|
+
}
|
|
1706
|
+
encoder;
|
|
1707
|
+
draftId = null;
|
|
1708
|
+
creating = null;
|
|
1709
|
+
/** The draft id once created, else null. */
|
|
1710
|
+
get id() {
|
|
1711
|
+
return this.draftId;
|
|
1712
|
+
}
|
|
1713
|
+
/**
|
|
1714
|
+
* Create the draft on first use (idempotent via client_token — a manager
|
|
1715
|
+
* restart returns the same draft). Concurrent callers share one in-flight
|
|
1716
|
+
* request. Returns null on failure (best-effort; the next snapshot retries).
|
|
1717
|
+
*/
|
|
1718
|
+
async ensureDraft() {
|
|
1719
|
+
if (this.draftId) return this.draftId;
|
|
1720
|
+
if (!this.creating) {
|
|
1721
|
+
this.creating = this.deps.api.post("/host/artifacts/draft", {
|
|
1722
|
+
agent_id: this.agentId,
|
|
1723
|
+
client_token: this.clientToken,
|
|
1724
|
+
kind: this.meta.kind ?? "other",
|
|
1725
|
+
...this.meta.title ? { title: this.meta.title } : {}
|
|
1726
|
+
}).then((res) => {
|
|
1727
|
+
this.draftId = res?.id ?? null;
|
|
1728
|
+
return this.draftId;
|
|
1729
|
+
}).catch((err) => {
|
|
1730
|
+
this.deps.log?.(`[artifact-stream] draft create failed (${this.clientToken}): ${errMessage(err)}`);
|
|
1731
|
+
return null;
|
|
1732
|
+
}).finally(() => {
|
|
1733
|
+
this.creating = null;
|
|
1734
|
+
});
|
|
1735
|
+
}
|
|
1736
|
+
return this.creating;
|
|
1737
|
+
}
|
|
1738
|
+
/** Encode one snapshot and relay its frame(s). Best-effort, never throws. */
|
|
1739
|
+
async pushSnapshot(content) {
|
|
1740
|
+
const id = await this.ensureDraft();
|
|
1741
|
+
if (!id) return;
|
|
1742
|
+
const frames = this.encoder.encode(content);
|
|
1743
|
+
for (const frame of frames) {
|
|
1744
|
+
try {
|
|
1745
|
+
await this.deps.api.post(`/host/artifacts/${encodeURIComponent(id)}/stream`, {
|
|
1746
|
+
agent_id: this.agentId,
|
|
1747
|
+
frame
|
|
1748
|
+
});
|
|
1749
|
+
} catch (err) {
|
|
1750
|
+
this.deps.log?.(`[artifact-stream] frame ${frame.seq} failed (${id}): ${errMessage(err)}`);
|
|
1751
|
+
}
|
|
1752
|
+
}
|
|
1753
|
+
}
|
|
1754
|
+
};
|
|
1755
|
+
var ArtifactStreamScanner = class {
|
|
1756
|
+
constructor(agentId, artifactsDir, fsDeps, deps) {
|
|
1757
|
+
this.agentId = agentId;
|
|
1758
|
+
this.artifactsDir = artifactsDir;
|
|
1759
|
+
this.fsDeps = fsDeps;
|
|
1760
|
+
this.deps = deps;
|
|
1761
|
+
}
|
|
1762
|
+
sessions = /* @__PURE__ */ new Map();
|
|
1763
|
+
seenMtime = /* @__PURE__ */ new Map();
|
|
1764
|
+
scanning = false;
|
|
1765
|
+
/** One scan pass. Reads + streams every changed artefact. Never throws. */
|
|
1766
|
+
async scanOnce() {
|
|
1767
|
+
if (this.scanning) return;
|
|
1768
|
+
this.scanning = true;
|
|
1769
|
+
try {
|
|
1770
|
+
let names;
|
|
1771
|
+
try {
|
|
1772
|
+
names = await this.fsDeps.listArtefactNames(this.artifactsDir);
|
|
1773
|
+
} catch {
|
|
1774
|
+
return;
|
|
1775
|
+
}
|
|
1776
|
+
for (const name of names) {
|
|
1777
|
+
const file = join2(this.artifactsDir, name, ARTEFACT_ENTRY_FILE);
|
|
1778
|
+
const mtime = await this.fsDeps.mtimeMs(file).catch(() => null);
|
|
1779
|
+
if (mtime === null) continue;
|
|
1780
|
+
if (this.seenMtime.get(name) === mtime) continue;
|
|
1781
|
+
let content;
|
|
1782
|
+
try {
|
|
1783
|
+
content = await this.fsDeps.readFile(file);
|
|
1784
|
+
} catch (err) {
|
|
1785
|
+
this.deps.log?.(`[artifact-stream] read failed (${name}): ${errMessage(err)}`);
|
|
1786
|
+
continue;
|
|
1787
|
+
}
|
|
1788
|
+
this.seenMtime.set(name, mtime);
|
|
1789
|
+
await this.sessionFor(name).pushSnapshot(content);
|
|
1790
|
+
}
|
|
1791
|
+
const live = new Set(names);
|
|
1792
|
+
for (const key of this.seenMtime.keys()) if (!live.has(key)) this.seenMtime.delete(key);
|
|
1793
|
+
for (const key of this.sessions.keys()) if (!live.has(key)) this.sessions.delete(key);
|
|
1794
|
+
} finally {
|
|
1795
|
+
this.scanning = false;
|
|
1796
|
+
}
|
|
1797
|
+
}
|
|
1798
|
+
sessionFor(name) {
|
|
1799
|
+
let session = this.sessions.get(name);
|
|
1800
|
+
if (!session) {
|
|
1801
|
+
session = new ArtifactStreamSession(this.agentId, name, this.deps, { title: name });
|
|
1802
|
+
this.sessions.set(name, session);
|
|
1803
|
+
}
|
|
1804
|
+
return session;
|
|
1805
|
+
}
|
|
1806
|
+
};
|
|
1807
|
+
function artifactsDirFor(codeName) {
|
|
1808
|
+
return join2(homedir(), ".augmented", codeName, "artifacts");
|
|
1809
|
+
}
|
|
1810
|
+
var nodeArtifactFs = {
|
|
1811
|
+
async listArtefactNames(artifactsDir) {
|
|
1812
|
+
const entries = await readdir(artifactsDir, { withFileTypes: true });
|
|
1813
|
+
return entries.filter((e) => e.isDirectory() && !e.name.startsWith(".")).map((e) => e.name);
|
|
1814
|
+
},
|
|
1815
|
+
async mtimeMs(filePath) {
|
|
1816
|
+
try {
|
|
1817
|
+
return (await stat(filePath)).mtimeMs;
|
|
1818
|
+
} catch {
|
|
1819
|
+
return null;
|
|
1820
|
+
}
|
|
1821
|
+
},
|
|
1822
|
+
readFile(filePath) {
|
|
1823
|
+
return readFile(filePath, "utf8");
|
|
1824
|
+
}
|
|
1825
|
+
};
|
|
1826
|
+
|
|
1685
1827
|
// src/lib/usage-banner-monitor.ts
|
|
1686
1828
|
var MIN_CHECK_INTERVAL_MS = 6e4;
|
|
1687
|
-
var PANE_TAIL_LINES_FOR_BANNER =
|
|
1829
|
+
var PANE_TAIL_LINES_FOR_BANNER = 5e3;
|
|
1688
1830
|
var state = /* @__PURE__ */ new Map();
|
|
1689
1831
|
async function maybeReportUsageBanner(args) {
|
|
1690
1832
|
const { api: api2, codeName, agentId, log: log2 } = args;
|
|
@@ -1739,7 +1881,7 @@ async function maybeReportUsageBanner(args) {
|
|
|
1739
1881
|
|
|
1740
1882
|
// src/lib/token-usage-monitor.ts
|
|
1741
1883
|
import { readdirSync, readFileSync as readFileSync4, statSync } from "fs";
|
|
1742
|
-
import { join as
|
|
1884
|
+
import { join as join3 } from "path";
|
|
1743
1885
|
var MIN_CHECK_INTERVAL_MS2 = 6e4;
|
|
1744
1886
|
var TRANSCRIPT_MTIME_WINDOW_MS = 2 * 24 * 60 * 60 * 1e3;
|
|
1745
1887
|
var MAX_ENTRIES_PER_POST = 200;
|
|
@@ -1768,7 +1910,7 @@ async function maybeReportTokenUsage(args) {
|
|
|
1768
1910
|
if (!name.endsWith(".jsonl")) continue;
|
|
1769
1911
|
const sessionId = name.slice(0, -".jsonl".length);
|
|
1770
1912
|
if (!sessionId) continue;
|
|
1771
|
-
const path =
|
|
1913
|
+
const path = join3(dir, name);
|
|
1772
1914
|
let st;
|
|
1773
1915
|
try {
|
|
1774
1916
|
st = statSync(path);
|
|
@@ -1866,7 +2008,7 @@ async function maybeReportTokenUsage(args) {
|
|
|
1866
2008
|
|
|
1867
2009
|
// src/lib/conversation-evaluator.ts
|
|
1868
2010
|
import { readdirSync as readdirSync2, readFileSync as readFileSync5, statSync as statSync2 } from "fs";
|
|
1869
|
-
import { join as
|
|
2011
|
+
import { join as join4 } from "path";
|
|
1870
2012
|
var MIN_CHECK_INTERVAL_MS3 = 5 * 6e4;
|
|
1871
2013
|
var TRANSCRIPT_MTIME_WINDOW_MS2 = 3 * 24 * 60 * 60 * 1e3;
|
|
1872
2014
|
var WINDOW_PAD_MS = 5 * 6e4;
|
|
@@ -2103,7 +2245,7 @@ function readRecentTurns(dir, nowMs) {
|
|
|
2103
2245
|
const turns = [];
|
|
2104
2246
|
for (const name of entries) {
|
|
2105
2247
|
if (!name.endsWith(".jsonl")) continue;
|
|
2106
|
-
const full =
|
|
2248
|
+
const full = join4(dir, name);
|
|
2107
2249
|
let mtimeMs;
|
|
2108
2250
|
try {
|
|
2109
2251
|
mtimeMs = statSync2(full).mtimeMs;
|
|
@@ -2283,10 +2425,10 @@ async function reportSkip2(api2, agentId, conversationId, log2, codeName) {
|
|
|
2283
2425
|
|
|
2284
2426
|
// src/lib/activity-cache-monitor.ts
|
|
2285
2427
|
import { existsSync as existsSync2, readFileSync as readFileSync6 } from "fs";
|
|
2286
|
-
import { homedir } from "os";
|
|
2287
|
-
import { join as
|
|
2428
|
+
import { homedir as homedir2 } from "os";
|
|
2429
|
+
import { join as join5 } from "path";
|
|
2288
2430
|
var MIN_CHECK_INTERVAL_MS5 = 6e4;
|
|
2289
|
-
var STATS_CACHE_PATH =
|
|
2431
|
+
var STATS_CACHE_PATH = join5(homedir2(), ".claude", "stats-cache.json");
|
|
2290
2432
|
var ISO_DATE_RE = /^\d{4}-\d{2}-\d{2}$/;
|
|
2291
2433
|
var state5 = { lastObservedDate: null, lastCheckedAt: 0 };
|
|
2292
2434
|
function selectNewDailyRows(raw, lastObservedDate) {
|
|
@@ -2782,9 +2924,9 @@ var GatewayClientPool = class extends EventEmitter {
|
|
|
2782
2924
|
};
|
|
2783
2925
|
|
|
2784
2926
|
// src/lib/claude-auth-detect.ts
|
|
2785
|
-
import { readFile, readdir } from "fs/promises";
|
|
2786
|
-
import { homedir as
|
|
2787
|
-
import { join as
|
|
2927
|
+
import { readFile as readFile2, readdir as readdir2 } from "fs/promises";
|
|
2928
|
+
import { homedir as homedir3, platform } from "os";
|
|
2929
|
+
import { join as join6 } from "path";
|
|
2788
2930
|
import { execFile as execFile2 } from "child_process";
|
|
2789
2931
|
import { promisify } from "util";
|
|
2790
2932
|
var execFileAsync = promisify(execFile2);
|
|
@@ -2799,17 +2941,17 @@ async function detectClaudeAuth() {
|
|
|
2799
2941
|
}
|
|
2800
2942
|
async function findClaudeCredentialsPaths() {
|
|
2801
2943
|
const candidates = [
|
|
2802
|
-
|
|
2803
|
-
|
|
2944
|
+
join6(homedir3(), ".claude", ".credentials.json"),
|
|
2945
|
+
join6(homedir3(), ".claude", "credentials.json")
|
|
2804
2946
|
];
|
|
2805
2947
|
const isLinuxRoot = platform() === "linux" && typeof process.getuid === "function" && process.getuid() === 0;
|
|
2806
2948
|
if (isLinuxRoot) {
|
|
2807
2949
|
try {
|
|
2808
|
-
const entries = await
|
|
2950
|
+
const entries = await readdir2("/home", { withFileTypes: true });
|
|
2809
2951
|
for (const entry of entries) {
|
|
2810
2952
|
if (!entry.isDirectory()) continue;
|
|
2811
|
-
candidates.push(
|
|
2812
|
-
candidates.push(
|
|
2953
|
+
candidates.push(join6("/home", entry.name, ".claude", ".credentials.json"));
|
|
2954
|
+
candidates.push(join6("/home", entry.name, ".claude", "credentials.json"));
|
|
2813
2955
|
}
|
|
2814
2956
|
} catch {
|
|
2815
2957
|
}
|
|
@@ -2845,7 +2987,7 @@ async function readMacKeychain() {
|
|
|
2845
2987
|
}
|
|
2846
2988
|
async function readJsonSilently(path) {
|
|
2847
2989
|
try {
|
|
2848
|
-
const raw = await
|
|
2990
|
+
const raw = await readFile2(path, "utf-8");
|
|
2849
2991
|
return JSON.parse(raw);
|
|
2850
2992
|
} catch {
|
|
2851
2993
|
return null;
|
|
@@ -2902,10 +3044,10 @@ function normalize(value) {
|
|
|
2902
3044
|
|
|
2903
3045
|
// src/lib/channel-hash-cache.ts
|
|
2904
3046
|
import { existsSync as existsSync3, readFileSync as readFileSync7, writeFileSync as writeFileSync2 } from "fs";
|
|
2905
|
-
import { join as
|
|
3047
|
+
import { join as join7 } from "path";
|
|
2906
3048
|
var CACHE_FILENAME = "channel-hash-cache.json";
|
|
2907
3049
|
function getChannelHashCacheFile(configDir) {
|
|
2908
|
-
return
|
|
3050
|
+
return join7(configDir, CACHE_FILENAME);
|
|
2909
3051
|
}
|
|
2910
3052
|
function loadChannelHashCache(target, configDir) {
|
|
2911
3053
|
const path = getChannelHashCacheFile(configDir);
|
|
@@ -3377,13 +3519,18 @@ function clearAgentState(agentId, codeName) {
|
|
|
3377
3519
|
// src/lib/wedge-detection.ts
|
|
3378
3520
|
var DEFAULTS = {
|
|
3379
3521
|
inboundWaitSeconds: 120,
|
|
3380
|
-
// ENG-
|
|
3381
|
-
//
|
|
3382
|
-
//
|
|
3383
|
-
//
|
|
3384
|
-
//
|
|
3385
|
-
//
|
|
3386
|
-
|
|
3522
|
+
// ENG-6264: DISABLED by default (0). A session that's actively producing
|
|
3523
|
+
// tokens is never force-respawned — a working agent must not be killed just
|
|
3524
|
+
// because a message has been queued behind its turn, no matter how long.
|
|
3525
|
+
// ENG-6238 made this an absolute backstop (1200s) to still catch a
|
|
3526
|
+
// producing-but-never-draining runaway loop, but that re-introduced the exact
|
|
3527
|
+
// failure we set out to kill: cutting off real work on a long turn. Runaway
|
|
3528
|
+
// token burn is owned by the cost guardrail (ENG-5556); a producing-but-silent
|
|
3529
|
+
// loop still trips the synthetic-probe alarm. So the backstop is now opt-in:
|
|
3530
|
+
// set AGT_WEDGE_INBOUND_HARD_WAIT_SECONDS to a positive value to re-enable it
|
|
3531
|
+
// (floored at inboundWaitSeconds). 0 = the frozen/hung wedge (transcript
|
|
3532
|
+
// static) is still caught by the soft path; only the *producing* path is spared.
|
|
3533
|
+
inboundHardWaitSeconds: 0,
|
|
3387
3534
|
paneStaleSeconds: 120,
|
|
3388
3535
|
transcriptStaleSeconds: 60,
|
|
3389
3536
|
minCycles: 3
|
|
@@ -3402,10 +3549,12 @@ function resolveWedgeConfig(env = process.env) {
|
|
|
3402
3549
|
DEFAULTS.inboundWaitSeconds,
|
|
3403
3550
|
30
|
|
3404
3551
|
);
|
|
3405
|
-
const
|
|
3406
|
-
|
|
3407
|
-
|
|
3552
|
+
const inboundHardWaitRaw = parsePositiveInt(
|
|
3553
|
+
env.AGT_WEDGE_INBOUND_HARD_WAIT_SECONDS,
|
|
3554
|
+
DEFAULTS.inboundHardWaitSeconds,
|
|
3555
|
+
0
|
|
3408
3556
|
);
|
|
3557
|
+
const inboundHardWaitSeconds = inboundHardWaitRaw <= 0 ? 0 : Math.max(inboundWaitSeconds, inboundHardWaitRaw);
|
|
3409
3558
|
return {
|
|
3410
3559
|
mode: parseMode(env.AGT_WEDGE_RESTART_MODE),
|
|
3411
3560
|
inboundWaitSeconds,
|
|
@@ -3420,16 +3569,25 @@ function resolveWedgeConfig(env = process.env) {
|
|
|
3420
3569
|
};
|
|
3421
3570
|
}
|
|
3422
3571
|
function isSessionProducing(signals, config2) {
|
|
3572
|
+
const subagentAge = signals.subagentActivityAgeSeconds;
|
|
3573
|
+
if (subagentAge !== null && subagentAge < config2.transcriptStaleSeconds) return true;
|
|
3423
3574
|
const transcriptAge = signals.transcriptActivityAgeSeconds;
|
|
3424
3575
|
if (transcriptAge !== null) return transcriptAge < config2.transcriptStaleSeconds;
|
|
3425
3576
|
const paneAge = signals.paneActivityAgeSeconds;
|
|
3426
3577
|
return paneAge !== null && paneAge < config2.paneStaleSeconds;
|
|
3427
3578
|
}
|
|
3579
|
+
function wedgeExemptionReason(signals, config2) {
|
|
3580
|
+
if (signals.subagentActivityAgeSeconds === null) return null;
|
|
3581
|
+
if (isWedgeCandidateCycle(signals, config2)) return null;
|
|
3582
|
+
const withoutSubagent = { ...signals, subagentActivityAgeSeconds: null };
|
|
3583
|
+
return isWedgeCandidateCycle(withoutSubagent, config2) ? "background-task-in-flight" : null;
|
|
3584
|
+
}
|
|
3428
3585
|
function isWedgeCandidateCycle(signals, config2) {
|
|
3429
3586
|
const inboundAge = signals.pendingInboundOldestAgeSeconds;
|
|
3430
3587
|
if (inboundAge === null) return false;
|
|
3431
3588
|
if (inboundAge < config2.inboundWaitSeconds) return false;
|
|
3432
3589
|
if (isSessionProducing(signals, config2)) {
|
|
3590
|
+
if (config2.inboundHardWaitSeconds <= 0) return false;
|
|
3433
3591
|
return inboundAge >= config2.inboundHardWaitSeconds;
|
|
3434
3592
|
}
|
|
3435
3593
|
return true;
|
|
@@ -3498,14 +3656,14 @@ function partitionActionableByPoison(actionable, states, config2) {
|
|
|
3498
3656
|
|
|
3499
3657
|
// src/lib/restart-flags.ts
|
|
3500
3658
|
import { existsSync as existsSync4, mkdirSync as mkdirSync3, readdirSync as readdirSync3, readFileSync as readFileSync8, renameSync as renameSync2, rmSync, writeFileSync as writeFileSync3 } from "fs";
|
|
3501
|
-
import { homedir as
|
|
3502
|
-
import { join as
|
|
3659
|
+
import { homedir as homedir4 } from "os";
|
|
3660
|
+
import { join as join8 } from "path";
|
|
3503
3661
|
import { randomUUID } from "crypto";
|
|
3504
3662
|
function restartFlagsDir() {
|
|
3505
|
-
return
|
|
3663
|
+
return join8(homedir4(), ".augmented", "restart-flags");
|
|
3506
3664
|
}
|
|
3507
3665
|
function flagPath(codeName) {
|
|
3508
|
-
return
|
|
3666
|
+
return join8(restartFlagsDir(), `${codeName}.flag`);
|
|
3509
3667
|
}
|
|
3510
3668
|
function readRestartFlags() {
|
|
3511
3669
|
const dir = restartFlagsDir();
|
|
@@ -3514,7 +3672,7 @@ function readRestartFlags() {
|
|
|
3514
3672
|
for (const entry of readdirSync3(dir)) {
|
|
3515
3673
|
if (!entry.endsWith(".flag")) continue;
|
|
3516
3674
|
try {
|
|
3517
|
-
const raw = readFileSync8(
|
|
3675
|
+
const raw = readFileSync8(join8(dir, entry), "utf8");
|
|
3518
3676
|
const parsed = JSON.parse(raw);
|
|
3519
3677
|
if (typeof parsed.codeName !== "string" || parsed.codeName.length === 0) {
|
|
3520
3678
|
parsed.codeName = entry.replace(/\.flag$/, "");
|
|
@@ -4062,8 +4220,8 @@ function applyRestartAcks(args) {
|
|
|
4062
4220
|
var GATEWAY_PORT_BASE = 18800;
|
|
4063
4221
|
var GATEWAY_PORT_STEP = 10;
|
|
4064
4222
|
var GATEWAY_PORT_MAX = 18899;
|
|
4065
|
-
var AUGMENTED_DIR =
|
|
4066
|
-
var GATEWAY_PORTS_FILE =
|
|
4223
|
+
var AUGMENTED_DIR = join9(process.env["HOME"] ?? "/tmp", ".augmented");
|
|
4224
|
+
var GATEWAY_PORTS_FILE = join9(AUGMENTED_DIR, "gateway-ports.json");
|
|
4067
4225
|
var CHANNEL_SWEEP_INTERVAL_MS = (() => {
|
|
4068
4226
|
const raw = parseInt(process.env["AGT_CHANNEL_SWEEP_INTERVAL_MS"] ?? "", 10);
|
|
4069
4227
|
if (!Number.isFinite(raw)) return 5 * 60 * 1e3;
|
|
@@ -4399,6 +4557,7 @@ var DEFER_LOG_THROTTLE_MS = 6e5;
|
|
|
4399
4557
|
var deferLogThrottle = /* @__PURE__ */ new Map();
|
|
4400
4558
|
var lastInboundMs = /* @__PURE__ */ new Map();
|
|
4401
4559
|
var consecutiveWedgeCycles = /* @__PURE__ */ new Map();
|
|
4560
|
+
var wedgeExemptionLogged = /* @__PURE__ */ new Set();
|
|
4402
4561
|
var wedgeRestartsByCard = /* @__PURE__ */ new Map();
|
|
4403
4562
|
function noteInbound(codeName) {
|
|
4404
4563
|
lastInboundMs.set(codeName, Date.now());
|
|
@@ -4417,11 +4576,16 @@ function paneLogAgeSecondsFor(codeName) {
|
|
|
4417
4576
|
return 0;
|
|
4418
4577
|
}
|
|
4419
4578
|
}
|
|
4420
|
-
function
|
|
4421
|
-
|
|
4579
|
+
function transcriptAgeSecondsFor(codeName) {
|
|
4580
|
+
const sessionId = getSessionState(codeName)?.currentSessionId ?? null;
|
|
4581
|
+
return transcriptActivityAgeSeconds(getProjectDir2(codeName), sessionId, /* @__PURE__ */ new Date());
|
|
4582
|
+
}
|
|
4583
|
+
function restartGateFor(codeName, reason) {
|
|
4584
|
+
if (!isGateableRestartReason(reason)) return "bypass";
|
|
4422
4585
|
return decideRestartGate({
|
|
4423
4586
|
window: cachedMaintenanceWindow,
|
|
4424
4587
|
paneLogAgeSeconds: paneLogAgeSecondsFor(codeName),
|
|
4588
|
+
transcriptAgeSeconds: transcriptAgeSecondsFor(codeName),
|
|
4425
4589
|
inboundAgeSeconds: inboundAgeSecondsFor(codeName),
|
|
4426
4590
|
now: /* @__PURE__ */ new Date()
|
|
4427
4591
|
});
|
|
@@ -4431,7 +4595,7 @@ var runningMcpServerKeys = /* @__PURE__ */ new Map();
|
|
|
4431
4595
|
var runningChannelSecretHashes = /* @__PURE__ */ new Map();
|
|
4432
4596
|
function projectMcpHash(_codeName, projectDir) {
|
|
4433
4597
|
try {
|
|
4434
|
-
const raw = readFileSync9(
|
|
4598
|
+
const raw = readFileSync9(join9(projectDir, ".mcp.json"), "utf-8");
|
|
4435
4599
|
return createHash3("sha256").update(canonicalJson(JSON.parse(raw))).digest("hex");
|
|
4436
4600
|
} catch {
|
|
4437
4601
|
return null;
|
|
@@ -4439,7 +4603,7 @@ function projectMcpHash(_codeName, projectDir) {
|
|
|
4439
4603
|
}
|
|
4440
4604
|
function projectMcpKeys(_codeName, projectDir) {
|
|
4441
4605
|
try {
|
|
4442
|
-
const raw = readFileSync9(
|
|
4606
|
+
const raw = readFileSync9(join9(projectDir, ".mcp.json"), "utf-8");
|
|
4443
4607
|
const parsed = JSON.parse(raw);
|
|
4444
4608
|
const servers = parsed.mcpServers;
|
|
4445
4609
|
if (!servers || typeof servers !== "object") return /* @__PURE__ */ new Set();
|
|
@@ -4450,7 +4614,7 @@ function projectMcpKeys(_codeName, projectDir) {
|
|
|
4450
4614
|
}
|
|
4451
4615
|
function readMcpHttpServerConfig(projectDir, serverKey, env) {
|
|
4452
4616
|
try {
|
|
4453
|
-
const raw = readFileSync9(
|
|
4617
|
+
const raw = readFileSync9(join9(projectDir, ".mcp.json"), "utf-8");
|
|
4454
4618
|
const servers = JSON.parse(raw).mcpServers ?? {};
|
|
4455
4619
|
const entry = servers[serverKey];
|
|
4456
4620
|
if (entry && typeof entry.url === "string" && (entry.type === "http" || entry.type === void 0)) {
|
|
@@ -4478,7 +4642,7 @@ async function runAgentConnectivityProbes(agent, integrations, projectDir) {
|
|
|
4478
4642
|
if (integrations.length === 0) return;
|
|
4479
4643
|
const probeEnv = { ...process.env };
|
|
4480
4644
|
try {
|
|
4481
|
-
const envIntPath =
|
|
4645
|
+
const envIntPath = join9(projectDir, ".env.integrations");
|
|
4482
4646
|
if (existsSync5(envIntPath)) {
|
|
4483
4647
|
Object.assign(probeEnv, parseEnvIntegrations(readFileSync9(envIntPath, "utf-8")));
|
|
4484
4648
|
}
|
|
@@ -4580,10 +4744,10 @@ async function runAgentConnectivityProbes(agent, integrations, projectDir) {
|
|
|
4580
4744
|
);
|
|
4581
4745
|
}
|
|
4582
4746
|
}
|
|
4583
|
-
function stopPersistentSessionAndForgetMcpBaseline(codeName, breakerReason) {
|
|
4584
|
-
const gate = restartGateFor(codeName,
|
|
4747
|
+
function stopPersistentSessionAndForgetMcpBaseline(codeName, breakerReason, gateReason = breakerReason) {
|
|
4748
|
+
const gate = restartGateFor(codeName, gateReason);
|
|
4585
4749
|
if (gate !== "bypass" && gate !== "proceed") {
|
|
4586
|
-
log(`[maintenance-window] Deferring '${
|
|
4750
|
+
log(`[maintenance-window] Deferring '${gateReason}' restart for '${codeName}' (${gate})`);
|
|
4587
4751
|
return;
|
|
4588
4752
|
}
|
|
4589
4753
|
cancelPendingSessionRestart(codeName);
|
|
@@ -4668,7 +4832,7 @@ function checkMcpConfigDriftAndScheduleRestart(codeName, projectDir) {
|
|
|
4668
4832
|
function projectChannelSecretHash(projectDir) {
|
|
4669
4833
|
try {
|
|
4670
4834
|
const entries = parseEnvIntegrations(
|
|
4671
|
-
readFileSync9(
|
|
4835
|
+
readFileSync9(join9(projectDir, ".env.integrations"), "utf-8")
|
|
4672
4836
|
);
|
|
4673
4837
|
return channelSecretValueHash(entries, CHANNEL_SECRET_ENV_KEYS);
|
|
4674
4838
|
} catch {
|
|
@@ -4760,7 +4924,7 @@ var cachedMaintenanceWindow = null;
|
|
|
4760
4924
|
var lastVersionCheckAt = 0;
|
|
4761
4925
|
var VERSION_CHECK_INTERVAL_MS = 5 * 60 * 1e3;
|
|
4762
4926
|
var lastResponsivenessProbeAt = 0;
|
|
4763
|
-
var agtCliVersion = true ? "0.27.150-test.
|
|
4927
|
+
var agtCliVersion = true ? "0.27.150-test.17" : "dev";
|
|
4764
4928
|
function resolveBrewPath(execFileSync4) {
|
|
4765
4929
|
try {
|
|
4766
4930
|
const out = execFileSync4("which", ["brew"], { timeout: 5e3 }).toString().trim();
|
|
@@ -5011,7 +5175,7 @@ async function ensureFrameworkBinary(frameworkId) {
|
|
|
5011
5175
|
var CLAUDE_CODE_UPGRADE_CHECK_INTERVAL_MS = 24 * 60 * 60 * 1e3;
|
|
5012
5176
|
var claudeCodeUpgradeInFlight = false;
|
|
5013
5177
|
function claudeCodeUpgradeMarkerPath() {
|
|
5014
|
-
return
|
|
5178
|
+
return join9(homedir5(), ".augmented", ".last-claude-code-upgrade-check");
|
|
5015
5179
|
}
|
|
5016
5180
|
function stampClaudeCodeUpgradeMarker() {
|
|
5017
5181
|
try {
|
|
@@ -5074,7 +5238,7 @@ ${r.stderr}`;
|
|
|
5074
5238
|
}
|
|
5075
5239
|
var UPDATE_CHECK_INTERVAL_MS = 5 * 60 * 1e3;
|
|
5076
5240
|
function selfUpdateAppliedMarkerPath() {
|
|
5077
|
-
return
|
|
5241
|
+
return join9(homedir5(), ".augmented", ".last-self-update-applied");
|
|
5078
5242
|
}
|
|
5079
5243
|
var selfUpdateUpToDateLogged = false;
|
|
5080
5244
|
var restartAfterUpgrade = false;
|
|
@@ -5097,7 +5261,7 @@ async function checkAndUpdateCli() {
|
|
|
5097
5261
|
const isNpmGlobal = !isBrewFormula && resolvedPath.includes("node_modules");
|
|
5098
5262
|
if (!isBrewFormula && !isNpmGlobal) return;
|
|
5099
5263
|
const { readFileSync: readF, writeFileSync: writeF } = await import("fs");
|
|
5100
|
-
const markerPath =
|
|
5264
|
+
const markerPath = join9(homedir5(), ".augmented", ".last-update-check");
|
|
5101
5265
|
try {
|
|
5102
5266
|
const lastCheck = parseInt(readF(markerPath, "utf-8").trim(), 10);
|
|
5103
5267
|
if (Date.now() - lastCheck < UPDATE_CHECK_INTERVAL_MS) return;
|
|
@@ -5354,9 +5518,9 @@ async function applyClaudeAuthToEnv(childEnv, label) {
|
|
|
5354
5518
|
throw new Error("claude_auth_mode=api_key but /host/exchange returned no decrypted key");
|
|
5355
5519
|
}
|
|
5356
5520
|
childEnv.ANTHROPIC_API_KEY = exchange.anthropicApiKey;
|
|
5357
|
-
const claudeDir =
|
|
5521
|
+
const claudeDir = join9(homedir5(), ".claude");
|
|
5358
5522
|
for (const filename of [".credentials.json", "credentials.json"]) {
|
|
5359
|
-
const p =
|
|
5523
|
+
const p = join9(claudeDir, filename);
|
|
5360
5524
|
if (existsSync5(p)) {
|
|
5361
5525
|
try {
|
|
5362
5526
|
rmSync2(p, { force: true });
|
|
@@ -5372,12 +5536,12 @@ async function applyClaudeAuthToEnv(childEnv, label) {
|
|
|
5372
5536
|
var evalEmptyMcpConfigPath = null;
|
|
5373
5537
|
function ensureEvalEmptyMcpConfig() {
|
|
5374
5538
|
if (evalEmptyMcpConfigPath && existsSync5(evalEmptyMcpConfigPath)) return evalEmptyMcpConfigPath;
|
|
5375
|
-
const dir =
|
|
5539
|
+
const dir = join9(homedir5(), ".augmented");
|
|
5376
5540
|
try {
|
|
5377
5541
|
mkdirSync4(dir, { recursive: true });
|
|
5378
5542
|
} catch {
|
|
5379
5543
|
}
|
|
5380
|
-
const p =
|
|
5544
|
+
const p = join9(dir, ".eval-empty-mcp.json");
|
|
5381
5545
|
writeFileSync4(p, JSON.stringify({ mcpServers: {} }));
|
|
5382
5546
|
evalEmptyMcpConfigPath = p;
|
|
5383
5547
|
return p;
|
|
@@ -5403,7 +5567,7 @@ async function runEvalClaude(prompt, model) {
|
|
|
5403
5567
|
""
|
|
5404
5568
|
];
|
|
5405
5569
|
const { stdout } = await execFilePromiseLong(resolveClaudeBinary(), args, {
|
|
5406
|
-
cwd:
|
|
5570
|
+
cwd: homedir5(),
|
|
5407
5571
|
timeout: 12e4,
|
|
5408
5572
|
stdin: "ignore",
|
|
5409
5573
|
env: childEnv,
|
|
@@ -5482,10 +5646,10 @@ function freePort(codeName) {
|
|
|
5482
5646
|
}
|
|
5483
5647
|
}
|
|
5484
5648
|
function getStateFile() {
|
|
5485
|
-
return
|
|
5649
|
+
return join9(config?.configDir ?? join9(process.env["HOME"] ?? "/tmp", ".augmented"), "manager-state.json");
|
|
5486
5650
|
}
|
|
5487
5651
|
function channelHashCacheDir() {
|
|
5488
|
-
return config?.configDir ??
|
|
5652
|
+
return config?.configDir ?? join9(process.env["HOME"] ?? "/tmp", ".augmented");
|
|
5489
5653
|
}
|
|
5490
5654
|
function loadChannelHashCache2() {
|
|
5491
5655
|
loadChannelHashCache(agentState.knownChannelConfigHashes, channelHashCacheDir());
|
|
@@ -5496,7 +5660,7 @@ function saveChannelHashCache2() {
|
|
|
5496
5660
|
var _channelQuarantineStore = null;
|
|
5497
5661
|
function channelQuarantineStore() {
|
|
5498
5662
|
if (!_channelQuarantineStore) {
|
|
5499
|
-
const dir = config?.configDir ??
|
|
5663
|
+
const dir = config?.configDir ?? join9(process.env["HOME"] ?? "/tmp", ".augmented");
|
|
5500
5664
|
_channelQuarantineStore = new ChannelQuarantineStore(defaultQuarantinePath(dir));
|
|
5501
5665
|
}
|
|
5502
5666
|
return _channelQuarantineStore;
|
|
@@ -5551,7 +5715,7 @@ function log(msg) {
|
|
|
5551
5715
|
`;
|
|
5552
5716
|
if (!managerLogPath) {
|
|
5553
5717
|
try {
|
|
5554
|
-
managerLogPath =
|
|
5718
|
+
managerLogPath = join9(homedir5(), ".augmented", "manager.log");
|
|
5555
5719
|
mkdirSync4(dirname3(managerLogPath), { recursive: true });
|
|
5556
5720
|
if (existsSync5(managerLogPath)) {
|
|
5557
5721
|
chmodSync(managerLogPath, 384);
|
|
@@ -5606,12 +5770,12 @@ function parseSkillFrontmatter(content) {
|
|
|
5606
5770
|
}
|
|
5607
5771
|
async function refreshSkillsIndexInClaudeMd(configDir, codeName, log2) {
|
|
5608
5772
|
const { readdirSync: readdirSync5, readFileSync: rfs, existsSync: ex, writeFileSync: writeFileSync5 } = await import("fs");
|
|
5609
|
-
const skillsDir =
|
|
5610
|
-
const claudeMdPath =
|
|
5773
|
+
const skillsDir = join9(configDir, codeName, "project", ".claude", "skills");
|
|
5774
|
+
const claudeMdPath = join9(configDir, codeName, "project", "CLAUDE.md");
|
|
5611
5775
|
if (!ex(skillsDir) || !ex(claudeMdPath)) return;
|
|
5612
5776
|
const entries = [];
|
|
5613
5777
|
for (const dir of readdirSync5(skillsDir).sort()) {
|
|
5614
|
-
const skillFile =
|
|
5778
|
+
const skillFile = join9(skillsDir, dir, "SKILL.md");
|
|
5615
5779
|
if (!ex(skillFile)) continue;
|
|
5616
5780
|
try {
|
|
5617
5781
|
const { name, description } = parseSkillFrontmatter(rfs(skillFile, "utf-8"));
|
|
@@ -5659,7 +5823,7 @@ ${SKILLS_INDEX_END}`;
|
|
|
5659
5823
|
}
|
|
5660
5824
|
async function migrateToProfiles() {
|
|
5661
5825
|
const homeDir = process.env["HOME"] ?? "/tmp";
|
|
5662
|
-
const sharedConfigPath =
|
|
5826
|
+
const sharedConfigPath = join9(homeDir, ".openclaw", "openclaw.json");
|
|
5663
5827
|
let sharedConfig;
|
|
5664
5828
|
try {
|
|
5665
5829
|
sharedConfig = JSON.parse(readFileSync9(sharedConfigPath, "utf-8"));
|
|
@@ -5675,19 +5839,19 @@ async function migrateToProfiles() {
|
|
|
5675
5839
|
const codeName = agentEntry["id"];
|
|
5676
5840
|
if (!codeName) continue;
|
|
5677
5841
|
if (codeName === "main") continue;
|
|
5678
|
-
const profileDir =
|
|
5679
|
-
if (existsSync5(
|
|
5842
|
+
const profileDir = join9(homeDir, `.openclaw-${codeName}`);
|
|
5843
|
+
if (existsSync5(join9(profileDir, "openclaw.json"))) continue;
|
|
5680
5844
|
log(`Migrating agent '${codeName}' to per-agent profile`);
|
|
5681
5845
|
if (adapter.seedProfileConfig) {
|
|
5682
5846
|
adapter.seedProfileConfig(codeName);
|
|
5683
5847
|
}
|
|
5684
|
-
const sharedAuthDir =
|
|
5685
|
-
const profileAuthDir =
|
|
5686
|
-
const authFile =
|
|
5848
|
+
const sharedAuthDir = join9(homeDir, ".openclaw", "agents", codeName, "agent");
|
|
5849
|
+
const profileAuthDir = join9(profileDir, "agents", codeName, "agent");
|
|
5850
|
+
const authFile = join9(sharedAuthDir, "auth-profiles.json");
|
|
5687
5851
|
if (existsSync5(authFile)) {
|
|
5688
5852
|
mkdirSync4(profileAuthDir, { recursive: true });
|
|
5689
5853
|
const authContent = readFileSync9(authFile, "utf-8");
|
|
5690
|
-
writeFileSync4(
|
|
5854
|
+
writeFileSync4(join9(profileAuthDir, "auth-profiles.json"), authContent);
|
|
5691
5855
|
}
|
|
5692
5856
|
allocatePort(codeName);
|
|
5693
5857
|
migrated++;
|
|
@@ -5725,7 +5889,7 @@ function readGatewayToken(codeName) {
|
|
|
5725
5889
|
}
|
|
5726
5890
|
const homeDir = process.env["HOME"] ?? "/tmp";
|
|
5727
5891
|
try {
|
|
5728
|
-
const cfg = JSON.parse(readFileSync9(
|
|
5892
|
+
const cfg = JSON.parse(readFileSync9(join9(homeDir, `.openclaw-${codeName}`, "openclaw.json"), "utf-8"));
|
|
5729
5893
|
return cfg?.gateway?.auth?.token;
|
|
5730
5894
|
} catch {
|
|
5731
5895
|
return void 0;
|
|
@@ -5734,7 +5898,7 @@ function readGatewayToken(codeName) {
|
|
|
5734
5898
|
var GATEWAY_HUNG_TIMEOUT_MS = 5 * 6e4;
|
|
5735
5899
|
function isGatewayHung(codeName) {
|
|
5736
5900
|
const homeDir = process.env["HOME"] ?? "/tmp";
|
|
5737
|
-
const jobsPath =
|
|
5901
|
+
const jobsPath = join9(homeDir, `.openclaw-${codeName}`, "cron", "jobs.json");
|
|
5738
5902
|
if (!existsSync5(jobsPath)) return false;
|
|
5739
5903
|
try {
|
|
5740
5904
|
const data = JSON.parse(readFileSync9(jobsPath, "utf-8"));
|
|
@@ -5770,13 +5934,13 @@ async function ensureGatewayRunning(codeName, adapter) {
|
|
|
5770
5934
|
}
|
|
5771
5935
|
await new Promise((r) => setTimeout(r, 2e3));
|
|
5772
5936
|
const homeDir = process.env["HOME"] ?? "/tmp";
|
|
5773
|
-
const cronJobsPath =
|
|
5937
|
+
const cronJobsPath = join9(homeDir, `.openclaw-${codeName}`, "cron", "jobs.json");
|
|
5774
5938
|
clearStaleCronRunState(cronJobsPath);
|
|
5775
5939
|
} else {
|
|
5776
5940
|
if (status.port) {
|
|
5777
5941
|
try {
|
|
5778
5942
|
const homeDir = process.env["HOME"] ?? "/tmp";
|
|
5779
|
-
const configPath =
|
|
5943
|
+
const configPath = join9(homeDir, `.openclaw-${codeName}`, "openclaw.json");
|
|
5780
5944
|
if (existsSync5(configPath)) {
|
|
5781
5945
|
const cfg = JSON.parse(readFileSync9(configPath, "utf-8"));
|
|
5782
5946
|
if (cfg.gateway?.port !== status.port) {
|
|
@@ -5802,7 +5966,7 @@ async function ensureGatewayRunning(codeName, adapter) {
|
|
|
5802
5966
|
gatewaysStartedThisCycle.add(codeName);
|
|
5803
5967
|
try {
|
|
5804
5968
|
const homeDir = process.env["HOME"] ?? "/tmp";
|
|
5805
|
-
const configPath =
|
|
5969
|
+
const configPath = join9(homeDir, `.openclaw-${codeName}`, "openclaw.json");
|
|
5806
5970
|
if (existsSync5(configPath)) {
|
|
5807
5971
|
const cfg = JSON.parse(readFileSync9(configPath, "utf-8"));
|
|
5808
5972
|
if (!cfg.gateway) cfg.gateway = {};
|
|
@@ -5958,7 +6122,7 @@ async function pollCycle() {
|
|
|
5958
6122
|
}
|
|
5959
6123
|
try {
|
|
5960
6124
|
const { detectHostSecurity } = await import("../host-security-6PDFG7F5.js");
|
|
5961
|
-
const { collectDiagnostics } = await import("../persistent-session-
|
|
6125
|
+
const { collectDiagnostics } = await import("../persistent-session-IKQLTZZ6.js");
|
|
5962
6126
|
const diagCodeNames = [...agentState.persistentSessionAgents];
|
|
5963
6127
|
const agentDiagnostics = diagCodeNames.length > 0 ? collectDiagnostics(diagCodeNames) : void 0;
|
|
5964
6128
|
let tailscaleHostname;
|
|
@@ -6045,12 +6209,12 @@ async function pollCycle() {
|
|
|
6045
6209
|
const {
|
|
6046
6210
|
collectResponsivenessProbes,
|
|
6047
6211
|
getResponsivenessIntervalMs
|
|
6048
|
-
} = await import("../responsiveness-probe-
|
|
6212
|
+
} = await import("../responsiveness-probe-2K4QHOWW.js");
|
|
6049
6213
|
const probeIntervalMs = getResponsivenessIntervalMs();
|
|
6050
6214
|
if (now - lastResponsivenessProbeAt > probeIntervalMs) {
|
|
6051
6215
|
const probeCodeNames = [...agentState.persistentSessionAgents];
|
|
6052
6216
|
if (probeCodeNames.length > 0) {
|
|
6053
|
-
const { takeAcpxExecFailureCount, creditAcpxExecFailureCount } = await import("../persistent-session-
|
|
6217
|
+
const { takeAcpxExecFailureCount, creditAcpxExecFailureCount } = await import("../persistent-session-IKQLTZZ6.js");
|
|
6054
6218
|
const drainedGiveUps = /* @__PURE__ */ new Map();
|
|
6055
6219
|
const drainedAcpxFailures = /* @__PURE__ */ new Map();
|
|
6056
6220
|
const probes = collectResponsivenessProbes(probeCodeNames).map((p) => {
|
|
@@ -6084,14 +6248,16 @@ async function pollCycle() {
|
|
|
6084
6248
|
collectResponsivenessProbes,
|
|
6085
6249
|
livePendingInboundOldestAgeSeconds,
|
|
6086
6250
|
deadLetterPendingInbound
|
|
6087
|
-
} = await import("../responsiveness-probe-
|
|
6088
|
-
const { transcriptActivityAgeSeconds } = await import("../daily-session-PNQX5URX.js");
|
|
6251
|
+
} = await import("../responsiveness-probe-2K4QHOWW.js");
|
|
6089
6252
|
const { getProjectDir: wedgeProjectDir } = await import("../claude-scheduler-FATCLHDM.js");
|
|
6090
6253
|
const wedgeNow = /* @__PURE__ */ new Date();
|
|
6091
6254
|
const liveAgents = agentState.persistentSessionAgents;
|
|
6092
6255
|
for (const tracked of consecutiveWedgeCycles.keys()) {
|
|
6093
6256
|
if (!liveAgents.has(tracked)) consecutiveWedgeCycles.delete(tracked);
|
|
6094
6257
|
}
|
|
6258
|
+
for (const tracked of wedgeExemptionLogged) {
|
|
6259
|
+
if (!liveAgents.has(tracked)) wedgeExemptionLogged.delete(tracked);
|
|
6260
|
+
}
|
|
6095
6261
|
for (const tracked of wedgeRestartsByCard.keys()) {
|
|
6096
6262
|
if (!liveAgents.has(tracked)) wedgeRestartsByCard.delete(tracked);
|
|
6097
6263
|
}
|
|
@@ -6100,6 +6266,7 @@ async function pollCycle() {
|
|
|
6100
6266
|
const codeName = probe.code_name;
|
|
6101
6267
|
if (!isSessionHealthy(codeName)) {
|
|
6102
6268
|
consecutiveWedgeCycles.delete(codeName);
|
|
6269
|
+
wedgeExemptionLogged.delete(codeName);
|
|
6103
6270
|
continue;
|
|
6104
6271
|
}
|
|
6105
6272
|
const wedgeSession = getSessionState(codeName);
|
|
@@ -6109,9 +6276,15 @@ async function pollCycle() {
|
|
|
6109
6276
|
wedgeSession?.currentSessionId ?? null,
|
|
6110
6277
|
wedgeNow
|
|
6111
6278
|
);
|
|
6279
|
+
const subagentAge = subagentActivityAgeSeconds(
|
|
6280
|
+
wedgeProjectDir(codeName),
|
|
6281
|
+
wedgeSession?.currentSessionId ?? null,
|
|
6282
|
+
wedgeNow
|
|
6283
|
+
);
|
|
6112
6284
|
const signals = {
|
|
6113
6285
|
paneActivityAgeSeconds: probe.pane_activity_age_seconds,
|
|
6114
6286
|
transcriptActivityAgeSeconds: transcriptAge,
|
|
6287
|
+
subagentActivityAgeSeconds: subagentAge,
|
|
6115
6288
|
pendingInboundOldestAgeSeconds: livePendingInboundOldestAgeSeconds(
|
|
6116
6289
|
codeName,
|
|
6117
6290
|
sessionStartMs,
|
|
@@ -6120,8 +6293,20 @@ async function pollCycle() {
|
|
|
6120
6293
|
};
|
|
6121
6294
|
if (!isWedgeCandidateCycle(signals, wedgeConfig)) {
|
|
6122
6295
|
consecutiveWedgeCycles.delete(codeName);
|
|
6296
|
+
const exemption = wedgeExemptionReason(signals, wedgeConfig);
|
|
6297
|
+
if (exemption !== null) {
|
|
6298
|
+
if (!wedgeExemptionLogged.has(codeName)) {
|
|
6299
|
+
wedgeExemptionLogged.add(codeName);
|
|
6300
|
+
log(
|
|
6301
|
+
`[wedge] exempt agent=${codeName} reason=${exemption} subagentAge=${subagentAge}s inboundAge=${signals.pendingInboundOldestAgeSeconds}s transcriptAge=${transcriptAge === null ? "n/a" : `${transcriptAge}s`}`
|
|
6302
|
+
);
|
|
6303
|
+
}
|
|
6304
|
+
} else {
|
|
6305
|
+
wedgeExemptionLogged.delete(codeName);
|
|
6306
|
+
}
|
|
6123
6307
|
continue;
|
|
6124
6308
|
}
|
|
6309
|
+
wedgeExemptionLogged.delete(codeName);
|
|
6125
6310
|
const streak = (consecutiveWedgeCycles.get(codeName) ?? 0) + 1;
|
|
6126
6311
|
consecutiveWedgeCycles.set(codeName, streak);
|
|
6127
6312
|
if (decideWedgeRestart({ ...signals, consecutiveWedgeCycles: streak }, wedgeConfig) !== "wedged") {
|
|
@@ -6149,6 +6334,21 @@ async function pollCycle() {
|
|
|
6149
6334
|
log(
|
|
6150
6335
|
`[wedge] forced fresh respawn ${detail} \u2192 new session ${newId} (transcript preserved${deadNote})`
|
|
6151
6336
|
);
|
|
6337
|
+
const wedgeAgentId = agentState.codeNameToAgentId.get(codeName);
|
|
6338
|
+
if (wedgeAgentId) {
|
|
6339
|
+
api.post("/host/wedge-respawn", {
|
|
6340
|
+
agent_id: wedgeAgentId,
|
|
6341
|
+
code_name: codeName,
|
|
6342
|
+
dead_lettered_count: deadLettered,
|
|
6343
|
+
pane_age_seconds: signals.paneActivityAgeSeconds,
|
|
6344
|
+
inbound_age_seconds: signals.pendingInboundOldestAgeSeconds,
|
|
6345
|
+
transcript_age_seconds: transcriptAge
|
|
6346
|
+
}).catch((err) => {
|
|
6347
|
+
log(
|
|
6348
|
+
`[wedge] failed to record respawn event for '${codeName}' (ENG-6265): ${err.message} \u2014 respawn proceeded; CloudWatch metric will under-count this event`
|
|
6349
|
+
);
|
|
6350
|
+
});
|
|
6351
|
+
}
|
|
6152
6352
|
const inProgressCardIds = (kanbanBoardCache.get(codeName) ?? []).filter((item) => item.status === "in_progress" && isHybridActionable(item)).map((item) => item.id);
|
|
6153
6353
|
const cardStates = wedgeRestartsByCard.get(codeName) ?? /* @__PURE__ */ new Map();
|
|
6154
6354
|
const { next, newlyPoisoned } = recordWedgeForCards(
|
|
@@ -6299,7 +6499,7 @@ async function pollCycle() {
|
|
|
6299
6499
|
}
|
|
6300
6500
|
killAgentChannelProcesses(prev.codeName, { log });
|
|
6301
6501
|
freePort(prev.codeName);
|
|
6302
|
-
const agentDir =
|
|
6502
|
+
const agentDir = join9(adapter.getAgentDir(prev.codeName), "provision");
|
|
6303
6503
|
await cleanupAgentFiles(prev.codeName, agentDir);
|
|
6304
6504
|
clearAgentCaches(prev.agentId, prev.codeName);
|
|
6305
6505
|
}
|
|
@@ -6385,10 +6585,10 @@ async function pollCycle() {
|
|
|
6385
6585
|
// pending-inbound marker. Best-effort: a write failure is logged by
|
|
6386
6586
|
// the watchdog, never fails the poll cycle.
|
|
6387
6587
|
signalGiveUp: (codeName) => {
|
|
6388
|
-
const dir =
|
|
6588
|
+
const dir = join9(homedir5(), ".augmented", codeName);
|
|
6389
6589
|
if (!existsSync5(dir)) return;
|
|
6390
6590
|
atomicWriteFileSync(
|
|
6391
|
-
|
|
6591
|
+
join9(dir, "watchdog-give-up.json"),
|
|
6392
6592
|
JSON.stringify({ gave_up_at: (/* @__PURE__ */ new Date()).toISOString() })
|
|
6393
6593
|
);
|
|
6394
6594
|
}
|
|
@@ -6509,7 +6709,7 @@ async function processAgent(agent, agentStates) {
|
|
|
6509
6709
|
}
|
|
6510
6710
|
const now = (/* @__PURE__ */ new Date()).toISOString();
|
|
6511
6711
|
const adapter = resolveAgentFramework(agent.code_name);
|
|
6512
|
-
let agentDir =
|
|
6712
|
+
let agentDir = join9(adapter.getAgentDir(agent.code_name), "provision");
|
|
6513
6713
|
if (agent.status === "draft" || agent.status === "paused") {
|
|
6514
6714
|
if (previousKnownStatus !== agent.status) {
|
|
6515
6715
|
log(`Agent '${agent.code_name}' is ${agent.status}, skipping provisioning`);
|
|
@@ -6713,7 +6913,7 @@ async function processAgent(agent, agentStates) {
|
|
|
6713
6913
|
const frameworkId = refreshData.agent.framework ?? "openclaw";
|
|
6714
6914
|
agentFrameworkCache.set(agent.code_name, frameworkId);
|
|
6715
6915
|
const frameworkAdapter = getFramework(frameworkId);
|
|
6716
|
-
agentDir =
|
|
6916
|
+
agentDir = join9(frameworkAdapter.getAgentDir(agent.code_name), "provision");
|
|
6717
6917
|
cacheAgentDeliveryMetadata(agent.code_name, refreshData);
|
|
6718
6918
|
if (frameworkAdapter.migrateSecretStorage && !migratedSecretStorage.has(agent.code_name)) {
|
|
6719
6919
|
try {
|
|
@@ -6756,7 +6956,7 @@ async function processAgent(agent, agentStates) {
|
|
|
6756
6956
|
const changedFiles = [];
|
|
6757
6957
|
mkdirSync4(agentDir, { recursive: true });
|
|
6758
6958
|
for (const artifact of artifacts) {
|
|
6759
|
-
const filePath =
|
|
6959
|
+
const filePath = join9(agentDir, artifact.relativePath);
|
|
6760
6960
|
let existingHash;
|
|
6761
6961
|
let newHash;
|
|
6762
6962
|
let writeContent = artifact.content;
|
|
@@ -6775,7 +6975,7 @@ async function processAgent(agent, agentStates) {
|
|
|
6775
6975
|
};
|
|
6776
6976
|
newHash = sha256(stripDynamicSections(artifact.content));
|
|
6777
6977
|
try {
|
|
6778
|
-
const projectClaudeMd =
|
|
6978
|
+
const projectClaudeMd = join9(config.configDir, agent.code_name, "project", "CLAUDE.md");
|
|
6779
6979
|
const existing = readFileSync9(projectClaudeMd, "utf-8");
|
|
6780
6980
|
existingHash = sha256(stripDynamicSections(existing));
|
|
6781
6981
|
} catch {
|
|
@@ -6816,12 +7016,12 @@ async function processAgent(agent, agentStates) {
|
|
|
6816
7016
|
}
|
|
6817
7017
|
}
|
|
6818
7018
|
if (changedFiles.length > 0) {
|
|
6819
|
-
const isFirst = !existsSync5(
|
|
7019
|
+
const isFirst = !existsSync5(join9(agentDir, "CHARTER.md"));
|
|
6820
7020
|
const verb = isFirst ? "Provisioning" : "Updating";
|
|
6821
7021
|
const fileNames = changedFiles.map((f) => f.relativePath).join(", ");
|
|
6822
7022
|
log(`${verb} '${agent.code_name}': ${fileNames}`);
|
|
6823
7023
|
for (const file of changedFiles) {
|
|
6824
|
-
const filePath =
|
|
7024
|
+
const filePath = join9(agentDir, file.relativePath);
|
|
6825
7025
|
mkdirSync4(dirname3(filePath), { recursive: true });
|
|
6826
7026
|
if (file.relativePath === ".mcp.json") {
|
|
6827
7027
|
safeWriteJsonAtomic(filePath, file.content, { mode: 384 });
|
|
@@ -6830,12 +7030,12 @@ async function processAgent(agent, agentStates) {
|
|
|
6830
7030
|
}
|
|
6831
7031
|
}
|
|
6832
7032
|
try {
|
|
6833
|
-
const provSkillsDir =
|
|
7033
|
+
const provSkillsDir = join9(agentDir, ".claude", "skills");
|
|
6834
7034
|
if (existsSync5(provSkillsDir)) {
|
|
6835
7035
|
for (const folder of readdirSync4(provSkillsDir)) {
|
|
6836
7036
|
if (folder.startsWith("knowledge-")) {
|
|
6837
7037
|
try {
|
|
6838
|
-
rmSync2(
|
|
7038
|
+
rmSync2(join9(provSkillsDir, folder), { recursive: true });
|
|
6839
7039
|
} catch {
|
|
6840
7040
|
}
|
|
6841
7041
|
}
|
|
@@ -6848,7 +7048,7 @@ async function processAgent(agent, agentStates) {
|
|
|
6848
7048
|
const trackedFiles2 = frameworkAdapter.driftTrackedFiles();
|
|
6849
7049
|
const hashes = /* @__PURE__ */ new Map();
|
|
6850
7050
|
for (const file of trackedFiles2) {
|
|
6851
|
-
const h = hashFile(
|
|
7051
|
+
const h = hashFile(join9(agentDir, file));
|
|
6852
7052
|
if (h) hashes.set(file, h);
|
|
6853
7053
|
}
|
|
6854
7054
|
agentState.writtenHashes.set(agent.agent_id, hashes);
|
|
@@ -6916,7 +7116,7 @@ async function processAgent(agent, agentStates) {
|
|
|
6916
7116
|
if (written && existsSync5(agentDir)) {
|
|
6917
7117
|
const driftedFiles = [];
|
|
6918
7118
|
for (const [file, expectedHash] of written) {
|
|
6919
|
-
const localHash = hashFile(
|
|
7119
|
+
const localHash = hashFile(join9(agentDir, file));
|
|
6920
7120
|
if (localHash && localHash !== expectedHash) {
|
|
6921
7121
|
driftedFiles.push(file);
|
|
6922
7122
|
}
|
|
@@ -6927,7 +7127,7 @@ async function processAgent(agent, agentStates) {
|
|
|
6927
7127
|
try {
|
|
6928
7128
|
const localHashes = {};
|
|
6929
7129
|
for (const file of driftedFiles) {
|
|
6930
|
-
localHashes[file] = hashFile(
|
|
7130
|
+
localHashes[file] = hashFile(join9(agentDir, file));
|
|
6931
7131
|
}
|
|
6932
7132
|
await api.post("/host/drift", {
|
|
6933
7133
|
agent_id: agent.agent_id,
|
|
@@ -7251,18 +7451,18 @@ async function processAgent(agent, agentStates) {
|
|
|
7251
7451
|
if (agentSessionMode === "persistent" && (agentFrameworkCache.get(agent.code_name) ?? "openclaw") === "claude-code") {
|
|
7252
7452
|
try {
|
|
7253
7453
|
const agentProvisionDir = agentDir;
|
|
7254
|
-
const projectDir =
|
|
7454
|
+
const projectDir = join9(homedir5(), ".augmented", agent.code_name, "project");
|
|
7255
7455
|
mkdirSync4(agentProvisionDir, { recursive: true });
|
|
7256
7456
|
mkdirSync4(projectDir, { recursive: true });
|
|
7257
|
-
const provisionMcpPath =
|
|
7258
|
-
const projectMcpPath =
|
|
7457
|
+
const provisionMcpPath = join9(agentProvisionDir, ".mcp.json");
|
|
7458
|
+
const projectMcpPath = join9(projectDir, ".mcp.json");
|
|
7259
7459
|
let mcpConfig = { mcpServers: {} };
|
|
7260
7460
|
try {
|
|
7261
7461
|
mcpConfig = JSON.parse(readFileSync9(provisionMcpPath, "utf-8"));
|
|
7262
7462
|
if (!mcpConfig.mcpServers) mcpConfig.mcpServers = {};
|
|
7263
7463
|
} catch {
|
|
7264
7464
|
}
|
|
7265
|
-
const localDirectChatChannel =
|
|
7465
|
+
const localDirectChatChannel = join9(homedir5(), ".augmented", "_mcp", "direct-chat-channel.js");
|
|
7266
7466
|
const directChatTeamSettings = refreshData.team?.settings;
|
|
7267
7467
|
const directChatTz = (() => {
|
|
7268
7468
|
const tz = directChatTeamSettings?.["timezone"];
|
|
@@ -7292,7 +7492,7 @@ async function processAgent(agent, agentStates) {
|
|
|
7292
7492
|
log(`Channel credentials written for '${agent.code_name}/direct-chat'`);
|
|
7293
7493
|
}
|
|
7294
7494
|
}
|
|
7295
|
-
const staleChannelsPath =
|
|
7495
|
+
const staleChannelsPath = join9(projectDir, ".mcp-channels.json");
|
|
7296
7496
|
if (existsSync5(staleChannelsPath)) {
|
|
7297
7497
|
try {
|
|
7298
7498
|
rmSync2(staleChannelsPath, { force: true });
|
|
@@ -7357,7 +7557,7 @@ async function processAgent(agent, agentStates) {
|
|
|
7357
7557
|
}
|
|
7358
7558
|
if (process.env.AGT_CONNECTIVITY_PROBE_ENABLED === "true") {
|
|
7359
7559
|
try {
|
|
7360
|
-
const probeProjectDir =
|
|
7560
|
+
const probeProjectDir = join9(homedir5(), ".augmented", agent.code_name, "project");
|
|
7361
7561
|
await runAgentConnectivityProbes(agent, integrations, probeProjectDir);
|
|
7362
7562
|
} catch (err) {
|
|
7363
7563
|
log(`Connectivity probe failed for '${agent.code_name}': ${err.message}`);
|
|
@@ -7375,8 +7575,8 @@ async function processAgent(agent, agentStates) {
|
|
|
7375
7575
|
recordConfigChurnEvent(agent.agent_id, agent.code_name, FLAP_CHANNEL_INTEGRATIONS, intMembership);
|
|
7376
7576
|
}
|
|
7377
7577
|
if (intHash !== prevIntHash) {
|
|
7378
|
-
const projectDir =
|
|
7379
|
-
const envIntPath =
|
|
7578
|
+
const projectDir = join9(homedir5(), ".augmented", agent.code_name, "project");
|
|
7579
|
+
const envIntPath = join9(projectDir, ".env.integrations");
|
|
7380
7580
|
let preWriteEnv;
|
|
7381
7581
|
try {
|
|
7382
7582
|
preWriteEnv = readFileSync9(envIntPath, "utf-8");
|
|
@@ -7391,7 +7591,7 @@ async function processAgent(agent, agentStates) {
|
|
|
7391
7591
|
let rotationHandled = true;
|
|
7392
7592
|
if (fw === "claude-code" && isSessionHealthy(agent.code_name)) {
|
|
7393
7593
|
try {
|
|
7394
|
-
const projectMcpPath =
|
|
7594
|
+
const projectMcpPath = join9(projectDir, ".mcp.json");
|
|
7395
7595
|
const postWriteEnv = readFileSync9(envIntPath, "utf-8");
|
|
7396
7596
|
const mcpContent = readFileSync9(projectMcpPath, "utf-8");
|
|
7397
7597
|
const changedVars = diffEnvIntegrations(preWriteEnv, postWriteEnv);
|
|
@@ -7575,7 +7775,7 @@ async function processAgent(agent, agentStates) {
|
|
|
7575
7775
|
if (agent.status === "active") {
|
|
7576
7776
|
if (frameworkAdapter.installPlugin) {
|
|
7577
7777
|
try {
|
|
7578
|
-
const pluginPath =
|
|
7778
|
+
const pluginPath = join9(process.cwd(), "packages", "openclaw-plugin-augmented", "src", "index.ts");
|
|
7579
7779
|
if (existsSync5(pluginPath)) {
|
|
7580
7780
|
frameworkAdapter.installPlugin(agent.code_name, "augmented", pluginPath, {
|
|
7581
7781
|
agtHost: requireHost(),
|
|
@@ -7642,18 +7842,18 @@ async function processAgent(agent, agentStates) {
|
|
|
7642
7842
|
}
|
|
7643
7843
|
try {
|
|
7644
7844
|
const { readdirSync: readdirSync5, rmSync: rmSync3 } = await import("fs");
|
|
7645
|
-
const { homedir:
|
|
7845
|
+
const { homedir: homedir6 } = await import("os");
|
|
7646
7846
|
const frameworkId2 = frameworkAdapter.id;
|
|
7647
7847
|
const candidateSkillDirs = [
|
|
7648
7848
|
// Claude Code — framework runtime tree
|
|
7649
|
-
|
|
7849
|
+
join9(homedir6(), ".augmented", agent.code_name, "skills"),
|
|
7650
7850
|
// Claude Code — project tree
|
|
7651
|
-
|
|
7851
|
+
join9(homedir6(), ".augmented", agent.code_name, "project", ".claude", "skills"),
|
|
7652
7852
|
// OpenClaw — framework runtime tree
|
|
7653
|
-
|
|
7853
|
+
join9(homedir6(), `.openclaw-${agent.code_name}`, "skills"),
|
|
7654
7854
|
// Defensive: legacy provision-side path, not currently an
|
|
7655
7855
|
// install target but cheap to sweep.
|
|
7656
|
-
|
|
7856
|
+
join9(agentDir, ".claude", "skills")
|
|
7657
7857
|
];
|
|
7658
7858
|
const existingDirs = candidateSkillDirs.filter((d) => existsSync5(d));
|
|
7659
7859
|
const discoveredEntries = /* @__PURE__ */ new Set();
|
|
@@ -7669,7 +7869,7 @@ async function processAgent(agent, agentStates) {
|
|
|
7669
7869
|
}
|
|
7670
7870
|
const removeSkillFolder = (entry, reason) => {
|
|
7671
7871
|
for (const dir of existingDirs) {
|
|
7672
|
-
const p =
|
|
7872
|
+
const p = join9(dir, entry);
|
|
7673
7873
|
if (existsSync5(p)) {
|
|
7674
7874
|
rmSync3(p, { recursive: true, force: true });
|
|
7675
7875
|
}
|
|
@@ -7849,7 +8049,7 @@ async function processAgent(agent, agentStates) {
|
|
|
7849
8049
|
const sess = getSessionState(agent.code_name);
|
|
7850
8050
|
let mcpJsonParsed = null;
|
|
7851
8051
|
try {
|
|
7852
|
-
const mcpPath =
|
|
8052
|
+
const mcpPath = join9(getProjectDir(agent.code_name), ".mcp.json");
|
|
7853
8053
|
mcpJsonParsed = JSON.parse(readFileSync9(mcpPath, "utf-8"));
|
|
7854
8054
|
} catch {
|
|
7855
8055
|
}
|
|
@@ -7868,7 +8068,19 @@ async function processAgent(agent, agentStates) {
|
|
|
7868
8068
|
// isolated and the agent keeps running degraded instead of being
|
|
7869
8069
|
// paused wholesale. reaperRestartBreakerReason() encodes that
|
|
7870
8070
|
// single-vs-multi decision; undefined means "restart, don't count".
|
|
7871
|
-
|
|
8071
|
+
//
|
|
8072
|
+
// ENG-6264: the breaker-count reason (above, undefined for a single dead
|
|
8073
|
+
// MCP) is decoupled from the GATE reason. Pre-6264 an undefined breaker
|
|
8074
|
+
// reason also made the restart non-gateable → 'bypass' → the session was
|
|
8075
|
+
// torn down mid-turn (the common single-MCP case interrupted busy
|
|
8076
|
+
// agents). Always pass 'mcp-presence-reaper' as the gate reason so the
|
|
8077
|
+
// restart defers-until-idle, while breakerReason still governs whether it
|
|
8078
|
+
// counts against the breaker.
|
|
8079
|
+
stopSession: (codeName, ctx) => stopPersistentSessionAndForgetMcpBaseline(
|
|
8080
|
+
codeName,
|
|
8081
|
+
reaperRestartBreakerReason(ctx.activeKeys),
|
|
8082
|
+
"mcp-presence-reaper"
|
|
8083
|
+
),
|
|
7872
8084
|
// ENG-5292: when the reaper gives up on a managed MCP (cap from
|
|
7873
8085
|
// ENG-5279 + state-preservation from ENG-5285 both said "this
|
|
7874
8086
|
// MCP keeps failing after 3 restart cycles"), mark the matching
|
|
@@ -8047,7 +8259,7 @@ async function processAgent(agent, agentStates) {
|
|
|
8047
8259
|
lastWorkTriggerAt.set(agent.code_name, triggerTs);
|
|
8048
8260
|
if (agentFw === "openclaw" && gatewayRunning && gatewayPort) {
|
|
8049
8261
|
const homeDir = process.env["HOME"] ?? "/tmp";
|
|
8050
|
-
const jobsPath =
|
|
8262
|
+
const jobsPath = join9(homeDir, `.openclaw-${agent.code_name}`, "cron", "jobs.json");
|
|
8051
8263
|
if (existsSync5(jobsPath)) {
|
|
8052
8264
|
try {
|
|
8053
8265
|
const jobsData = JSON.parse(readFileSync9(jobsPath, "utf-8"));
|
|
@@ -8187,7 +8399,7 @@ In progress for ${age} minutes \u2014 auto-failed`).catch(() => {
|
|
|
8187
8399
|
if (trackedFiles.length > 0 && existsSync5(agentDir)) {
|
|
8188
8400
|
const hashes = /* @__PURE__ */ new Map();
|
|
8189
8401
|
for (const file of trackedFiles) {
|
|
8190
|
-
const h = hashFile(
|
|
8402
|
+
const h = hashFile(join9(agentDir, file));
|
|
8191
8403
|
if (h) hashes.set(file, h);
|
|
8192
8404
|
}
|
|
8193
8405
|
agentState.writtenHashes.set(agent.agent_id, hashes);
|
|
@@ -8221,16 +8433,16 @@ function cleanupStaleSessions(codeName) {
|
|
|
8221
8433
|
lastCleanupAt.set(codeName, Date.now());
|
|
8222
8434
|
const homeDir = process.env["HOME"] ?? "/tmp";
|
|
8223
8435
|
for (const agentDir of ["main", codeName]) {
|
|
8224
|
-
const sessionsDir =
|
|
8436
|
+
const sessionsDir = join9(homeDir, `.openclaw-${codeName}`, "agents", agentDir, "sessions");
|
|
8225
8437
|
cleanupCronSessions(sessionsDir, CRON_SESSION_KEEP_COUNT);
|
|
8226
8438
|
}
|
|
8227
|
-
const cronRunsDir =
|
|
8439
|
+
const cronRunsDir = join9(homeDir, `.openclaw-${codeName}`, "cron", "runs");
|
|
8228
8440
|
cleanupOldFiles(cronRunsDir, CRON_RUN_RETENTION_DAYS, ".jsonl");
|
|
8229
|
-
const cronJobsPath =
|
|
8441
|
+
const cronJobsPath = join9(homeDir, `.openclaw-${codeName}`, "cron", "jobs.json");
|
|
8230
8442
|
clearStaleCronRunState(cronJobsPath);
|
|
8231
8443
|
}
|
|
8232
8444
|
function cleanupCronSessions(sessionsDir, keepCount) {
|
|
8233
|
-
const indexPath =
|
|
8445
|
+
const indexPath = join9(sessionsDir, "sessions.json");
|
|
8234
8446
|
if (!existsSync5(indexPath)) return;
|
|
8235
8447
|
try {
|
|
8236
8448
|
const raw = readFileSync9(indexPath, "utf-8");
|
|
@@ -8246,7 +8458,7 @@ function cleanupCronSessions(sessionsDir, keepCount) {
|
|
|
8246
8458
|
for (const entry of toDelete) {
|
|
8247
8459
|
delete index[entry.key];
|
|
8248
8460
|
if (entry.sessionId) {
|
|
8249
|
-
const sessionFile =
|
|
8461
|
+
const sessionFile = join9(sessionsDir, `${entry.sessionId}.jsonl`);
|
|
8250
8462
|
try {
|
|
8251
8463
|
if (existsSync5(sessionFile)) {
|
|
8252
8464
|
unlinkSync(sessionFile);
|
|
@@ -8268,7 +8480,7 @@ function cleanupCronSessions(sessionsDir, keepCount) {
|
|
|
8268
8480
|
delete index[parentKey];
|
|
8269
8481
|
if (parentSessionId) {
|
|
8270
8482
|
try {
|
|
8271
|
-
const f =
|
|
8483
|
+
const f = join9(sessionsDir, `${parentSessionId}.jsonl`);
|
|
8272
8484
|
if (existsSync5(f)) {
|
|
8273
8485
|
unlinkSync(f);
|
|
8274
8486
|
deletedFiles++;
|
|
@@ -8326,7 +8538,7 @@ function cleanupOldFiles(dir, maxAgeDays, ext) {
|
|
|
8326
8538
|
try {
|
|
8327
8539
|
for (const f of readdirSync4(dir)) {
|
|
8328
8540
|
if (!f.endsWith(ext)) continue;
|
|
8329
|
-
const fullPath =
|
|
8541
|
+
const fullPath = join9(dir, f);
|
|
8330
8542
|
try {
|
|
8331
8543
|
const st = statSync3(fullPath);
|
|
8332
8544
|
if (st.mtimeMs < cutoff) {
|
|
@@ -8366,7 +8578,7 @@ var inFlightClaudeTasks = /* @__PURE__ */ new Set();
|
|
|
8366
8578
|
var claudeTaskConcurrency = /* @__PURE__ */ new Map();
|
|
8367
8579
|
var MAX_CLAUDE_CONCURRENCY = 2;
|
|
8368
8580
|
function claudePidFilePath() {
|
|
8369
|
-
return
|
|
8581
|
+
return join9(homedir5(), ".augmented", "manager-claude-pids.json");
|
|
8370
8582
|
}
|
|
8371
8583
|
var inFlightClaudePids = /* @__PURE__ */ new Map();
|
|
8372
8584
|
function registerClaudeSpawn(record) {
|
|
@@ -8706,7 +8918,7 @@ async function fireScheduledTaskViaKanban(codeName, agentId, task, prompt) {
|
|
|
8706
8918
|
}
|
|
8707
8919
|
async function executeAndProcessClaudeTask(codeName, agentId, task, prompt) {
|
|
8708
8920
|
const projectDir = getProjectDir2(codeName);
|
|
8709
|
-
const mcpConfigPath =
|
|
8921
|
+
const mcpConfigPath = join9(projectDir, ".mcp.json");
|
|
8710
8922
|
let runId = null;
|
|
8711
8923
|
let kanbanItemId = null;
|
|
8712
8924
|
let taskResult;
|
|
@@ -8714,7 +8926,7 @@ async function executeAndProcessClaudeTask(codeName, agentId, task, prompt) {
|
|
|
8714
8926
|
const priorRuns = await fetchPriorScheduledRuns(agentId, task.taskId);
|
|
8715
8927
|
prompt = wrapScheduledTaskPrompt(prompt, { priorRuns });
|
|
8716
8928
|
try {
|
|
8717
|
-
const claudeMdPath =
|
|
8929
|
+
const claudeMdPath = join9(projectDir, "CLAUDE.md");
|
|
8718
8930
|
const serverNames = [];
|
|
8719
8931
|
if (existsSync5(mcpConfigPath)) {
|
|
8720
8932
|
try {
|
|
@@ -8741,7 +8953,7 @@ async function executeAndProcessClaudeTask(codeName, agentId, task, prompt) {
|
|
|
8741
8953
|
claudeArgs.push("--system-prompt-file", claudeMdPath);
|
|
8742
8954
|
}
|
|
8743
8955
|
const childEnv = { ...process.env };
|
|
8744
|
-
const envIntPath =
|
|
8956
|
+
const envIntPath = join9(projectDir, ".env.integrations");
|
|
8745
8957
|
if (existsSync5(envIntPath)) {
|
|
8746
8958
|
try {
|
|
8747
8959
|
Object.assign(childEnv, parseEnvIntegrations(readFileSync9(envIntPath, "utf-8")));
|
|
@@ -8916,8 +9128,8 @@ var claudeAuthTupleBySession = /* @__PURE__ */ new Map();
|
|
|
8916
9128
|
async function ensurePersistentSession(agent, tasks, boardItems, refreshData) {
|
|
8917
9129
|
const codeName = agent.code_name;
|
|
8918
9130
|
const projectDir = getProjectDir(codeName);
|
|
8919
|
-
const mcpConfigPath =
|
|
8920
|
-
const claudeMdPath =
|
|
9131
|
+
const mcpConfigPath = join9(projectDir, ".mcp.json");
|
|
9132
|
+
const claudeMdPath = join9(projectDir, "CLAUDE.md");
|
|
8921
9133
|
if (restartBreaker.isTripped(codeName)) {
|
|
8922
9134
|
const trip = restartBreaker.getTrip(codeName);
|
|
8923
9135
|
return {
|
|
@@ -9087,6 +9299,11 @@ ${truncateForLog(ctx.tail)}` : `; pane_tail_hash=sha256:${createHash3("sha256").
|
|
|
9087
9299
|
} catch (err) {
|
|
9088
9300
|
log(`[persistent-session] Failed to provision auto-progress hook for '${codeName}': ${err.message}`);
|
|
9089
9301
|
}
|
|
9302
|
+
try {
|
|
9303
|
+
provisionSessionStateHook(codeName);
|
|
9304
|
+
} catch (err) {
|
|
9305
|
+
log(`[persistent-session] Failed to provision session-state hook for '${codeName}': ${err.message}`);
|
|
9306
|
+
}
|
|
9090
9307
|
const sessionRunResult = await startRun({
|
|
9091
9308
|
agent_id: agent.agent_id,
|
|
9092
9309
|
source_type: "system",
|
|
@@ -9546,7 +9763,7 @@ ${escapeXml(msg.content)}
|
|
|
9546
9763
|
log(`[direct-chat] One-shot spawn for '${agent.codeName}' (msg=${msg.id}; host in-flight=${directChatSpawnGate.hostInFlight}, queued=${directChatSpawnGate.queuedCount})`);
|
|
9547
9764
|
const { getProjectDir: ccProjectDir } = await import("../claude-scheduler-FATCLHDM.js");
|
|
9548
9765
|
const projDir = ccProjectDir(agent.codeName);
|
|
9549
|
-
const mcpConfigPath =
|
|
9766
|
+
const mcpConfigPath = join9(projDir, ".mcp.json");
|
|
9550
9767
|
const serverNames = [];
|
|
9551
9768
|
if (existsSync5(mcpConfigPath)) {
|
|
9552
9769
|
try {
|
|
@@ -9569,11 +9786,11 @@ ${escapeXml(msg.content)}
|
|
|
9569
9786
|
"--allowedTools",
|
|
9570
9787
|
allowedTools
|
|
9571
9788
|
];
|
|
9572
|
-
const chatClaudeMd =
|
|
9789
|
+
const chatClaudeMd = join9(projDir, "CLAUDE.md");
|
|
9573
9790
|
if (existsSync5(chatClaudeMd)) {
|
|
9574
9791
|
chatArgs.push("--system-prompt-file", chatClaudeMd);
|
|
9575
9792
|
}
|
|
9576
|
-
const envIntPath =
|
|
9793
|
+
const envIntPath = join9(projDir, ".env.integrations");
|
|
9577
9794
|
const childEnv = { ...process.env };
|
|
9578
9795
|
if (existsSync5(envIntPath)) {
|
|
9579
9796
|
try {
|
|
@@ -9955,8 +10172,8 @@ function getBuiltInSkillContent(skillId) {
|
|
|
9955
10172
|
if (builtInSkillCache.has(skillId)) return builtInSkillCache.get(skillId);
|
|
9956
10173
|
try {
|
|
9957
10174
|
const candidates = [
|
|
9958
|
-
|
|
9959
|
-
|
|
10175
|
+
join9(process.cwd(), "skills", skillId, "SKILL.md"),
|
|
10176
|
+
join9(new URL(".", import.meta.url).pathname, "..", "..", "..", "..", "skills", skillId, "SKILL.md")
|
|
9960
10177
|
];
|
|
9961
10178
|
for (const candidate of candidates) {
|
|
9962
10179
|
if (existsSync5(candidate)) {
|
|
@@ -10615,7 +10832,7 @@ async function processClaudePairSessions(agents) {
|
|
|
10615
10832
|
killPairSession,
|
|
10616
10833
|
pairTmuxSession,
|
|
10617
10834
|
finalizeClaudePairOnboarding
|
|
10618
|
-
} = await import("../claude-pair-runtime-
|
|
10835
|
+
} = await import("../claude-pair-runtime-QYJUJUYY.js");
|
|
10619
10836
|
for (const pairId of pendingResp.cancelled_pair_ids ?? []) {
|
|
10620
10837
|
log(`[claude-pair] sweeping orphan tmux session for pair ${pairId.slice(0, 8)}`);
|
|
10621
10838
|
const killed = await killPairSession(pairTmuxSession(pairId));
|
|
@@ -10676,11 +10893,11 @@ async function processClaudePairSessions(agents) {
|
|
|
10676
10893
|
});
|
|
10677
10894
|
} else {
|
|
10678
10895
|
const errKind = result.error.kind;
|
|
10679
|
-
const
|
|
10896
|
+
const errMessage2 = "message" in result.error ? result.error.message : void 0;
|
|
10680
10897
|
await reportAndCleanup(session.pair_id, {
|
|
10681
10898
|
status: errKind === "no-session" ? "session_missing" : "failure",
|
|
10682
10899
|
error_code: errKind,
|
|
10683
|
-
error_message:
|
|
10900
|
+
error_message: errMessage2
|
|
10684
10901
|
});
|
|
10685
10902
|
}
|
|
10686
10903
|
} else if (session.status === "code_submitted" && session.code) {
|
|
@@ -10709,11 +10926,11 @@ async function processClaudePairSessions(agents) {
|
|
|
10709
10926
|
});
|
|
10710
10927
|
} else {
|
|
10711
10928
|
const errKind = result.error.kind;
|
|
10712
|
-
const
|
|
10929
|
+
const errMessage2 = "message" in result.error ? result.error.message : void 0;
|
|
10713
10930
|
await reportAndCleanup(session.pair_id, {
|
|
10714
10931
|
status: errKind === "no-session" ? "session_missing" : "failure",
|
|
10715
10932
|
error_code: errKind,
|
|
10716
|
-
error_message:
|
|
10933
|
+
error_message: errMessage2
|
|
10717
10934
|
});
|
|
10718
10935
|
}
|
|
10719
10936
|
}
|
|
@@ -10925,8 +11142,8 @@ function parseMemoryFile(raw, fallbackName) {
|
|
|
10925
11142
|
};
|
|
10926
11143
|
}
|
|
10927
11144
|
async function syncMemories(agent, configDir, log2) {
|
|
10928
|
-
const projectDir =
|
|
10929
|
-
const memoryDir =
|
|
11145
|
+
const projectDir = join9(configDir, agent.code_name, "project");
|
|
11146
|
+
const memoryDir = join9(projectDir, "memory");
|
|
10930
11147
|
const isFreshSync = pendingFreshMemorySync.has(agent.agent_id);
|
|
10931
11148
|
if (isFreshSync) {
|
|
10932
11149
|
log2(`[memory-sync] Fresh-sync requested for '${agent.code_name}' \u2014 pulling DB first`);
|
|
@@ -10944,7 +11161,7 @@ async function syncMemories(agent, configDir, log2) {
|
|
|
10944
11161
|
for (const file of readdirSync4(memoryDir)) {
|
|
10945
11162
|
if (!file.endsWith(".md")) continue;
|
|
10946
11163
|
try {
|
|
10947
|
-
const raw = readFileSync9(
|
|
11164
|
+
const raw = readFileSync9(join9(memoryDir, file), "utf-8");
|
|
10948
11165
|
const fileHash = createHash3("sha256").update(raw).digest("hex").slice(0, 16);
|
|
10949
11166
|
currentHashes.set(file, fileHash);
|
|
10950
11167
|
if (prevHashes.get(file) === fileHash) continue;
|
|
@@ -10969,7 +11186,7 @@ async function syncMemories(agent, configDir, log2) {
|
|
|
10969
11186
|
} catch (err) {
|
|
10970
11187
|
for (const mem of changedMemories) {
|
|
10971
11188
|
for (const [file] of currentHashes) {
|
|
10972
|
-
const parsed = parseMemoryFile(readFileSync9(
|
|
11189
|
+
const parsed = parseMemoryFile(readFileSync9(join9(memoryDir, file), "utf-8"), file.replace(/\.md$/, ""));
|
|
10973
11190
|
if (parsed?.name === mem.name) currentHashes.delete(file);
|
|
10974
11191
|
}
|
|
10975
11192
|
}
|
|
@@ -11004,7 +11221,7 @@ async function downloadMemories(agent, memoryDir, log2, { force }) {
|
|
|
11004
11221
|
const mem = dbMemories.memories[i];
|
|
11005
11222
|
const rawSlug = mem.name.toLowerCase().replace(/[^a-z0-9]+/g, "-").replace(/(^-|-$)/g, "").slice(0, 60);
|
|
11006
11223
|
const slug = rawSlug || `memory-${i}`;
|
|
11007
|
-
const filePath =
|
|
11224
|
+
const filePath = join9(memoryDir, `${slug}.md`);
|
|
11008
11225
|
const desired = `---
|
|
11009
11226
|
name: ${JSON.stringify(mem.name)}
|
|
11010
11227
|
type: ${mem.type}
|
|
@@ -11125,6 +11342,42 @@ function stopCaffeinate() {
|
|
|
11125
11342
|
log("caffeinate stopped");
|
|
11126
11343
|
}
|
|
11127
11344
|
}
|
|
11345
|
+
var artifactScanners = /* @__PURE__ */ new Map();
|
|
11346
|
+
var artifactStreamingInFlight = false;
|
|
11347
|
+
async function driveArtifactStreaming() {
|
|
11348
|
+
if (artifactStreamingInFlight) return;
|
|
11349
|
+
artifactStreamingInFlight = true;
|
|
11350
|
+
try {
|
|
11351
|
+
await driveArtifactStreamingInner();
|
|
11352
|
+
} finally {
|
|
11353
|
+
artifactStreamingInFlight = false;
|
|
11354
|
+
}
|
|
11355
|
+
}
|
|
11356
|
+
async function driveArtifactStreamingInner() {
|
|
11357
|
+
const liveIds = /* @__PURE__ */ new Set();
|
|
11358
|
+
for (const agent of state6.agents) {
|
|
11359
|
+
if (!agent.agentId || !agent.codeName || agent.status !== "active") continue;
|
|
11360
|
+
liveIds.add(agent.agentId);
|
|
11361
|
+
let scanner = artifactScanners.get(agent.agentId);
|
|
11362
|
+
if (!scanner) {
|
|
11363
|
+
scanner = new ArtifactStreamScanner(
|
|
11364
|
+
agent.agentId,
|
|
11365
|
+
artifactsDirFor(agent.codeName),
|
|
11366
|
+
nodeArtifactFs,
|
|
11367
|
+
{ api, log }
|
|
11368
|
+
);
|
|
11369
|
+
artifactScanners.set(agent.agentId, scanner);
|
|
11370
|
+
}
|
|
11371
|
+
try {
|
|
11372
|
+
await scanner.scanOnce();
|
|
11373
|
+
} catch (err) {
|
|
11374
|
+
log(`[artifact-stream] scan failed for ${agent.codeName}: ${err.message}`);
|
|
11375
|
+
}
|
|
11376
|
+
}
|
|
11377
|
+
for (const id of artifactScanners.keys()) {
|
|
11378
|
+
if (!liveIds.has(id)) artifactScanners.delete(id);
|
|
11379
|
+
}
|
|
11380
|
+
}
|
|
11128
11381
|
function startPolling() {
|
|
11129
11382
|
if (!config || running) return;
|
|
11130
11383
|
running = true;
|
|
@@ -11136,6 +11389,7 @@ function startPolling() {
|
|
|
11136
11389
|
startGatewayPool();
|
|
11137
11390
|
return pollCycle();
|
|
11138
11391
|
}).then(() => {
|
|
11392
|
+
void driveArtifactStreaming();
|
|
11139
11393
|
scheduleNext();
|
|
11140
11394
|
});
|
|
11141
11395
|
}
|
|
@@ -11158,7 +11412,10 @@ function scheduleNext() {
|
|
|
11158
11412
|
restartNow();
|
|
11159
11413
|
return;
|
|
11160
11414
|
}
|
|
11161
|
-
void pollCycle().then(
|
|
11415
|
+
void pollCycle().then(() => {
|
|
11416
|
+
void driveArtifactStreaming();
|
|
11417
|
+
scheduleNext();
|
|
11418
|
+
});
|
|
11162
11419
|
}, delayMs);
|
|
11163
11420
|
}
|
|
11164
11421
|
async function killAllAgtTmuxSessions() {
|
|
@@ -11251,7 +11508,7 @@ function startManager(opts) {
|
|
|
11251
11508
|
log(`[startup] state rehydration failed (continuing with empty state): ${err.message}`);
|
|
11252
11509
|
}
|
|
11253
11510
|
log(
|
|
11254
|
-
`[startup] worker pid=${process.pid} ppid=${process.ppid} node=${process.version} log=${
|
|
11511
|
+
`[startup] worker pid=${process.pid} ppid=${process.ppid} node=${process.version} log=${join9(homedir5(), ".augmented", "manager.log")}`
|
|
11255
11512
|
);
|
|
11256
11513
|
deployMcpAssets();
|
|
11257
11514
|
reapOrphanChannelMcps({ log });
|
|
@@ -11382,14 +11639,14 @@ function restartRunningChannelMcps(basenames) {
|
|
|
11382
11639
|
}
|
|
11383
11640
|
}
|
|
11384
11641
|
function deployMcpAssets() {
|
|
11385
|
-
const targetDir =
|
|
11642
|
+
const targetDir = join9(homedir5(), ".augmented", "_mcp");
|
|
11386
11643
|
mkdirSync4(targetDir, { recursive: true });
|
|
11387
11644
|
const moduleDir = dirname3(fileURLToPath(import.meta.url));
|
|
11388
11645
|
let mcpSourceDir = "";
|
|
11389
11646
|
let dir = moduleDir;
|
|
11390
11647
|
for (let i = 0; i < 6; i++) {
|
|
11391
|
-
const candidate =
|
|
11392
|
-
if (existsSync5(
|
|
11648
|
+
const candidate = join9(dir, "dist", "mcp");
|
|
11649
|
+
if (existsSync5(join9(candidate, "index.js"))) {
|
|
11393
11650
|
mcpSourceDir = candidate;
|
|
11394
11651
|
break;
|
|
11395
11652
|
}
|
|
@@ -11432,8 +11689,8 @@ function deployMcpAssets() {
|
|
|
11432
11689
|
// natural session restart.
|
|
11433
11690
|
"augmented-admin.js"
|
|
11434
11691
|
]) {
|
|
11435
|
-
const src =
|
|
11436
|
-
const dst =
|
|
11692
|
+
const src = join9(mcpSourceDir, file);
|
|
11693
|
+
const dst = join9(targetDir, file);
|
|
11437
11694
|
if (!existsSync5(src)) continue;
|
|
11438
11695
|
const before = fileHash(dst);
|
|
11439
11696
|
try {
|
|
@@ -11451,14 +11708,14 @@ function deployMcpAssets() {
|
|
|
11451
11708
|
log(`[manager] Bundle(s) updated: ${changedBasenames.join(", ")} \u2014 signalling running instances to restart`);
|
|
11452
11709
|
restartRunningChannelMcps(changedBasenames);
|
|
11453
11710
|
}
|
|
11454
|
-
const localMcpPath =
|
|
11711
|
+
const localMcpPath = join9(targetDir, "index.js");
|
|
11455
11712
|
try {
|
|
11456
|
-
const agentsDir =
|
|
11713
|
+
const agentsDir = join9(homedir5(), ".augmented", "agents");
|
|
11457
11714
|
if (existsSync5(agentsDir)) {
|
|
11458
11715
|
for (const entry of readdirSync4(agentsDir, { withFileTypes: true })) {
|
|
11459
11716
|
if (!entry.isDirectory()) continue;
|
|
11460
11717
|
for (const subdir of ["provision", "project"]) {
|
|
11461
|
-
const mcpJsonPath =
|
|
11718
|
+
const mcpJsonPath = join9(agentsDir, entry.name, subdir, ".mcp.json");
|
|
11462
11719
|
try {
|
|
11463
11720
|
const raw = readFileSync9(mcpJsonPath, "utf-8");
|
|
11464
11721
|
if (!raw.includes("@integrity-labs/augmented-mcp")) continue;
|