@integrity-labs/agt-cli 0.28.13-canary.18 → 0.28.14
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 +3 -3
- package/dist/bin/agt.js.map +1 -1
- package/dist/{chunk-BBTTZRCH.js → chunk-REFMPKKL.js} +1 -1
- package/dist/lib/manager-worker.js +432 -420
- package/dist/lib/manager-worker.js.map +1 -1
- package/package.json +1 -1
- /package/dist/{chunk-BBTTZRCH.js.map → chunk-REFMPKKL.js.map} +0 -0
|
@@ -22,7 +22,7 @@ import {
|
|
|
22
22
|
provisionStopHook,
|
|
23
23
|
requireHost,
|
|
24
24
|
safeWriteJsonAtomic
|
|
25
|
-
} from "../chunk-
|
|
25
|
+
} from "../chunk-REFMPKKL.js";
|
|
26
26
|
import {
|
|
27
27
|
getProjectDir as getProjectDir2,
|
|
28
28
|
getReadyTasks,
|
|
@@ -103,12 +103,12 @@ import {
|
|
|
103
103
|
} from "../chunk-XWVM4KPK.js";
|
|
104
104
|
|
|
105
105
|
// src/lib/manager-worker.ts
|
|
106
|
-
import { createHash as
|
|
107
|
-
import { readFileSync as
|
|
106
|
+
import { createHash as createHash4 } from "crypto";
|
|
107
|
+
import { readFileSync as readFileSync11, writeFileSync as writeFileSync4, mkdirSync as mkdirSync4, existsSync as existsSync7, rmSync as rmSync3, readdirSync as readdirSync5, statSync as statSync4, unlinkSync, copyFileSync } from "fs";
|
|
108
108
|
import https from "https";
|
|
109
109
|
import { execFileSync as syncExecFile } from "child_process";
|
|
110
|
-
import { join as
|
|
111
|
-
import { homedir as
|
|
110
|
+
import { join as join13, dirname as dirname3 } from "path";
|
|
111
|
+
import { homedir as homedir7 } from "os";
|
|
112
112
|
import { fileURLToPath } from "url";
|
|
113
113
|
|
|
114
114
|
// src/lib/mcp-config-drift.ts
|
|
@@ -3674,6 +3674,189 @@ function planGlobalSkillSync(globalSkills, prevIds, hashOf, knownHash) {
|
|
|
3674
3674
|
return { installs, removes, currentIds };
|
|
3675
3675
|
}
|
|
3676
3676
|
|
|
3677
|
+
// src/lib/manager/runtime.ts
|
|
3678
|
+
import { createHash as createHash3 } from "crypto";
|
|
3679
|
+
import { readFileSync as readFileSync9, appendFileSync, mkdirSync as mkdirSync2, chmodSync, existsSync as existsSync4 } from "fs";
|
|
3680
|
+
import { join as join10, dirname as dirname2 } from "path";
|
|
3681
|
+
import { homedir as homedir4 } from "os";
|
|
3682
|
+
function redactForDiskLog(value) {
|
|
3683
|
+
try {
|
|
3684
|
+
return value.replace(/\b(Bearer\s+)[A-Za-z0-9._-]+\b/gi, "$1[REDACTED]").replace(/\bxox[baprs]-[A-Za-z0-9-]+\b/g, "[REDACTED-SLACK]").replace(/\btlk_[A-Za-z0-9._-]+\b/g, "[REDACTED-HOST]").replace(/\bsk-ant-[A-Za-z0-9_-]+\b/g, "[REDACTED-ANTHROPIC]").replace(/\b\d{8,12}:[A-Za-z0-9_-]{30,}\b/g, "[REDACTED-TELEGRAM]").replace(
|
|
3685
|
+
/\b([A-Z0-9_]*(?:TOKEN|SECRET|API[_-]?KEY|PASSWORD)[A-Z0-9_]*)=(?:"[^"\r\n]*"|'[^'\r\n]*'|[^\s\r\n]+)/gi,
|
|
3686
|
+
"$1=[REDACTED]"
|
|
3687
|
+
);
|
|
3688
|
+
} catch {
|
|
3689
|
+
return "[REDACTED]";
|
|
3690
|
+
}
|
|
3691
|
+
}
|
|
3692
|
+
var managerLogPath = null;
|
|
3693
|
+
var managerLogWritable = true;
|
|
3694
|
+
function log(msg) {
|
|
3695
|
+
const ts = (/* @__PURE__ */ new Date()).toISOString();
|
|
3696
|
+
const safeMsg = redactForDiskLog(msg);
|
|
3697
|
+
const line = `[manager-worker ${ts}] ${safeMsg}
|
|
3698
|
+
`;
|
|
3699
|
+
if (!managerLogPath) {
|
|
3700
|
+
try {
|
|
3701
|
+
managerLogPath = join10(homedir4(), ".augmented", "manager.log");
|
|
3702
|
+
mkdirSync2(dirname2(managerLogPath), { recursive: true });
|
|
3703
|
+
if (existsSync4(managerLogPath)) {
|
|
3704
|
+
chmodSync(managerLogPath, 384);
|
|
3705
|
+
}
|
|
3706
|
+
} catch {
|
|
3707
|
+
}
|
|
3708
|
+
}
|
|
3709
|
+
let appendedToFile = false;
|
|
3710
|
+
if (managerLogPath && managerLogWritable) {
|
|
3711
|
+
try {
|
|
3712
|
+
appendFileSync(managerLogPath, line, { encoding: "utf-8", mode: 384 });
|
|
3713
|
+
appendedToFile = true;
|
|
3714
|
+
} catch (err) {
|
|
3715
|
+
managerLogWritable = false;
|
|
3716
|
+
process.stderr.write(
|
|
3717
|
+
`[manager-worker ${ts}] [log] manager.log append failed; falling back to stderr-only: ${err.message}
|
|
3718
|
+
`
|
|
3719
|
+
);
|
|
3720
|
+
}
|
|
3721
|
+
}
|
|
3722
|
+
if (!appendedToFile || process.stderr.isTTY === true) {
|
|
3723
|
+
process.stderr.write(line);
|
|
3724
|
+
}
|
|
3725
|
+
}
|
|
3726
|
+
function sha256(content) {
|
|
3727
|
+
return createHash3("sha256").update(content, "utf8").digest("hex");
|
|
3728
|
+
}
|
|
3729
|
+
function hashFile(filePath) {
|
|
3730
|
+
try {
|
|
3731
|
+
const content = readFileSync9(filePath, "utf-8");
|
|
3732
|
+
return sha256(content);
|
|
3733
|
+
} catch {
|
|
3734
|
+
return null;
|
|
3735
|
+
}
|
|
3736
|
+
}
|
|
3737
|
+
async function execFilePromise(cmd, args) {
|
|
3738
|
+
const { execFile: ef } = await import("child_process");
|
|
3739
|
+
return new Promise((resolve, reject) => {
|
|
3740
|
+
ef(cmd, args, { timeout: 15e3 }, (err, stdout, stderr) => {
|
|
3741
|
+
if (err) reject(err);
|
|
3742
|
+
else resolve({ stdout, stderr });
|
|
3743
|
+
});
|
|
3744
|
+
});
|
|
3745
|
+
}
|
|
3746
|
+
var ChildProcessError = class extends Error {
|
|
3747
|
+
code;
|
|
3748
|
+
stdout;
|
|
3749
|
+
stderr;
|
|
3750
|
+
constructor(code, stdout, stderr) {
|
|
3751
|
+
const stderrSnippet = stderr.trim().slice(0, 500);
|
|
3752
|
+
const stdoutSnippet = stdout.trim().slice(0, 500);
|
|
3753
|
+
const detail = stderrSnippet || stdoutSnippet || "(no output)";
|
|
3754
|
+
super(`Exit code ${code}: ${detail}`);
|
|
3755
|
+
this.name = "ChildProcessError";
|
|
3756
|
+
this.code = code;
|
|
3757
|
+
this.stdout = stdout;
|
|
3758
|
+
this.stderr = stderr;
|
|
3759
|
+
}
|
|
3760
|
+
};
|
|
3761
|
+
async function execFilePromiseLong(cmd, args, opts) {
|
|
3762
|
+
const { spawn: sp } = await import("child_process");
|
|
3763
|
+
return new Promise((resolve, reject) => {
|
|
3764
|
+
const child = sp(cmd, args, {
|
|
3765
|
+
cwd: opts?.cwd,
|
|
3766
|
+
stdio: [opts?.stdin === "ignore" ? "ignore" : "pipe", "pipe", "pipe"],
|
|
3767
|
+
...opts?.env ? { env: opts.env } : {}
|
|
3768
|
+
});
|
|
3769
|
+
if (opts?.onSpawn && typeof child.pid === "number") {
|
|
3770
|
+
try {
|
|
3771
|
+
opts.onSpawn(child.pid);
|
|
3772
|
+
} catch {
|
|
3773
|
+
}
|
|
3774
|
+
}
|
|
3775
|
+
let stdout = "";
|
|
3776
|
+
let stderr = "";
|
|
3777
|
+
child.stdout?.on("data", (d) => {
|
|
3778
|
+
stdout += d.toString();
|
|
3779
|
+
});
|
|
3780
|
+
child.stderr?.on("data", (d) => {
|
|
3781
|
+
stderr += d.toString();
|
|
3782
|
+
});
|
|
3783
|
+
const timer = setTimeout(() => {
|
|
3784
|
+
child.kill();
|
|
3785
|
+
reject(new Error(`Timed out after ${opts?.timeout ?? 12e4}ms`));
|
|
3786
|
+
}, opts?.timeout ?? 12e4);
|
|
3787
|
+
child.on("close", (code) => {
|
|
3788
|
+
clearTimeout(timer);
|
|
3789
|
+
if (opts?.onExit && typeof child.pid === "number") {
|
|
3790
|
+
try {
|
|
3791
|
+
opts.onExit(child.pid);
|
|
3792
|
+
} catch {
|
|
3793
|
+
}
|
|
3794
|
+
}
|
|
3795
|
+
if (code !== 0) reject(new ChildProcessError(code, stdout, stderr));
|
|
3796
|
+
else resolve({ stdout, stderr });
|
|
3797
|
+
});
|
|
3798
|
+
child.on("error", (err) => {
|
|
3799
|
+
clearTimeout(timer);
|
|
3800
|
+
reject(err);
|
|
3801
|
+
});
|
|
3802
|
+
});
|
|
3803
|
+
}
|
|
3804
|
+
|
|
3805
|
+
// src/lib/manager/model.ts
|
|
3806
|
+
function resolveModelChain(refreshData) {
|
|
3807
|
+
const agent = refreshData.agent;
|
|
3808
|
+
const modelDefaults = refreshData.model_defaults;
|
|
3809
|
+
const platform2 = modelDefaults?.platform ?? {};
|
|
3810
|
+
const org = modelDefaults?.org ?? {};
|
|
3811
|
+
function resolve(tier) {
|
|
3812
|
+
const agentField = `${tier}_model`;
|
|
3813
|
+
const platformField = `default_${tier}_model`;
|
|
3814
|
+
const agentVal = agent?.[agentField];
|
|
3815
|
+
if (agentVal) return agentVal;
|
|
3816
|
+
const orgVal = org?.[platformField];
|
|
3817
|
+
if (orgVal) return orgVal;
|
|
3818
|
+
const platformVal = platform2?.[platformField];
|
|
3819
|
+
if (platformVal) return platformVal;
|
|
3820
|
+
return void 0;
|
|
3821
|
+
}
|
|
3822
|
+
return {
|
|
3823
|
+
primary: resolve("primary"),
|
|
3824
|
+
secondary: resolve("secondary"),
|
|
3825
|
+
tertiary: resolve("tertiary")
|
|
3826
|
+
};
|
|
3827
|
+
}
|
|
3828
|
+
|
|
3829
|
+
// src/lib/manager/claude-auth.ts
|
|
3830
|
+
import { existsSync as existsSync5, rmSync } from "fs";
|
|
3831
|
+
import { join as join11 } from "path";
|
|
3832
|
+
import { homedir as homedir5 } from "os";
|
|
3833
|
+
async function applyClaudeAuthToEnv(childEnv, label) {
|
|
3834
|
+
const apiKey = getApiKey();
|
|
3835
|
+
if (!apiKey) {
|
|
3836
|
+
throw new Error("AGT_API_KEY is not set");
|
|
3837
|
+
}
|
|
3838
|
+
const exchange = await exchangeApiKey(apiKey, false, { forceRefresh: true });
|
|
3839
|
+
if (exchange.claudeAuthMode === "api_key") {
|
|
3840
|
+
if (!exchange.anthropicApiKey) {
|
|
3841
|
+
throw new Error("claude_auth_mode=api_key but /host/exchange returned no decrypted key");
|
|
3842
|
+
}
|
|
3843
|
+
childEnv.ANTHROPIC_API_KEY = exchange.anthropicApiKey;
|
|
3844
|
+
const claudeDir = join11(homedir5(), ".claude");
|
|
3845
|
+
for (const filename of [".credentials.json", "credentials.json"]) {
|
|
3846
|
+
const p = join11(claudeDir, filename);
|
|
3847
|
+
if (existsSync5(p)) {
|
|
3848
|
+
try {
|
|
3849
|
+
rmSync(p, { force: true });
|
|
3850
|
+
log(`[${label}] Removed ${p} (api_key mode \u2014 preventing OAuth fallback)`);
|
|
3851
|
+
} catch {
|
|
3852
|
+
}
|
|
3853
|
+
}
|
|
3854
|
+
}
|
|
3855
|
+
} else {
|
|
3856
|
+
delete childEnv.ANTHROPIC_API_KEY;
|
|
3857
|
+
}
|
|
3858
|
+
}
|
|
3859
|
+
|
|
3677
3860
|
// src/lib/wedge-detection.ts
|
|
3678
3861
|
var DEFAULTS = {
|
|
3679
3862
|
inboundWaitSeconds: 120,
|
|
@@ -3813,24 +3996,24 @@ function partitionActionableByPoison(actionable, states, config2) {
|
|
|
3813
3996
|
}
|
|
3814
3997
|
|
|
3815
3998
|
// src/lib/restart-flags.ts
|
|
3816
|
-
import { existsSync as
|
|
3817
|
-
import { homedir as
|
|
3818
|
-
import { join as
|
|
3999
|
+
import { existsSync as existsSync6, mkdirSync as mkdirSync3, readdirSync as readdirSync4, readFileSync as readFileSync10, renameSync, rmSync as rmSync2, writeFileSync as writeFileSync3 } from "fs";
|
|
4000
|
+
import { homedir as homedir6 } from "os";
|
|
4001
|
+
import { join as join12 } from "path";
|
|
3819
4002
|
import { randomUUID } from "crypto";
|
|
3820
4003
|
function restartFlagsDir() {
|
|
3821
|
-
return
|
|
4004
|
+
return join12(homedir6(), ".augmented", "restart-flags");
|
|
3822
4005
|
}
|
|
3823
4006
|
function flagPath(codeName) {
|
|
3824
|
-
return
|
|
4007
|
+
return join12(restartFlagsDir(), `${codeName}.flag`);
|
|
3825
4008
|
}
|
|
3826
4009
|
function readRestartFlags() {
|
|
3827
4010
|
const dir = restartFlagsDir();
|
|
3828
|
-
if (!
|
|
4011
|
+
if (!existsSync6(dir)) return [];
|
|
3829
4012
|
const out = [];
|
|
3830
4013
|
for (const entry of readdirSync4(dir)) {
|
|
3831
4014
|
if (!entry.endsWith(".flag")) continue;
|
|
3832
4015
|
try {
|
|
3833
|
-
const raw =
|
|
4016
|
+
const raw = readFileSync10(join12(dir, entry), "utf8");
|
|
3834
4017
|
const parsed = JSON.parse(raw);
|
|
3835
4018
|
if (typeof parsed.codeName !== "string" || parsed.codeName.length === 0) {
|
|
3836
4019
|
parsed.codeName = entry.replace(/\.flag$/, "");
|
|
@@ -3848,8 +4031,8 @@ function readRestartFlags() {
|
|
|
3848
4031
|
}
|
|
3849
4032
|
function deleteRestartFlag(codeName) {
|
|
3850
4033
|
const path = flagPath(codeName);
|
|
3851
|
-
if (
|
|
3852
|
-
|
|
4034
|
+
if (existsSync6(path)) {
|
|
4035
|
+
rmSync2(path, { force: true });
|
|
3853
4036
|
}
|
|
3854
4037
|
}
|
|
3855
4038
|
|
|
@@ -4378,8 +4561,8 @@ function applyRestartAcks(args) {
|
|
|
4378
4561
|
var GATEWAY_PORT_BASE = 18800;
|
|
4379
4562
|
var GATEWAY_PORT_STEP = 10;
|
|
4380
4563
|
var GATEWAY_PORT_MAX = 18899;
|
|
4381
|
-
var AUGMENTED_DIR =
|
|
4382
|
-
var GATEWAY_PORTS_FILE =
|
|
4564
|
+
var AUGMENTED_DIR = join13(process.env["HOME"] ?? "/tmp", ".augmented");
|
|
4565
|
+
var GATEWAY_PORTS_FILE = join13(AUGMENTED_DIR, "gateway-ports.json");
|
|
4383
4566
|
var CHANNEL_SWEEP_INTERVAL_MS = (() => {
|
|
4384
4567
|
const raw = parseInt(process.env["AGT_CHANNEL_SWEEP_INTERVAL_MS"] ?? "", 10);
|
|
4385
4568
|
if (!Number.isFinite(raw)) return 5 * 60 * 1e3;
|
|
@@ -4754,15 +4937,15 @@ var runningMcpServerKeys = /* @__PURE__ */ new Map();
|
|
|
4754
4937
|
var runningChannelSecretHashes = /* @__PURE__ */ new Map();
|
|
4755
4938
|
function projectMcpHash(_codeName, projectDir) {
|
|
4756
4939
|
try {
|
|
4757
|
-
const raw =
|
|
4758
|
-
return
|
|
4940
|
+
const raw = readFileSync11(join13(projectDir, ".mcp.json"), "utf-8");
|
|
4941
|
+
return createHash4("sha256").update(canonicalJson(JSON.parse(raw))).digest("hex");
|
|
4759
4942
|
} catch {
|
|
4760
4943
|
return null;
|
|
4761
4944
|
}
|
|
4762
4945
|
}
|
|
4763
4946
|
function projectMcpKeys(_codeName, projectDir) {
|
|
4764
4947
|
try {
|
|
4765
|
-
const raw =
|
|
4948
|
+
const raw = readFileSync11(join13(projectDir, ".mcp.json"), "utf-8");
|
|
4766
4949
|
const parsed = JSON.parse(raw);
|
|
4767
4950
|
const servers = parsed.mcpServers;
|
|
4768
4951
|
if (!servers || typeof servers !== "object") return /* @__PURE__ */ new Set();
|
|
@@ -4773,7 +4956,7 @@ function projectMcpKeys(_codeName, projectDir) {
|
|
|
4773
4956
|
}
|
|
4774
4957
|
function readMcpHttpServerConfig(projectDir, serverKey, env) {
|
|
4775
4958
|
try {
|
|
4776
|
-
const raw =
|
|
4959
|
+
const raw = readFileSync11(join13(projectDir, ".mcp.json"), "utf-8");
|
|
4777
4960
|
const servers = JSON.parse(raw).mcpServers ?? {};
|
|
4778
4961
|
const entry = servers[serverKey];
|
|
4779
4962
|
if (entry && typeof entry.url === "string" && (entry.type === "http" || entry.type === void 0)) {
|
|
@@ -4801,9 +4984,9 @@ async function runAgentConnectivityProbes(agent, integrations, projectDir) {
|
|
|
4801
4984
|
if (integrations.length === 0) return;
|
|
4802
4985
|
const probeEnv = { ...process.env };
|
|
4803
4986
|
try {
|
|
4804
|
-
const envIntPath =
|
|
4805
|
-
if (
|
|
4806
|
-
Object.assign(probeEnv, parseEnvIntegrations(
|
|
4987
|
+
const envIntPath = join13(projectDir, ".env.integrations");
|
|
4988
|
+
if (existsSync7(envIntPath)) {
|
|
4989
|
+
Object.assign(probeEnv, parseEnvIntegrations(readFileSync11(envIntPath, "utf-8")));
|
|
4807
4990
|
}
|
|
4808
4991
|
} catch {
|
|
4809
4992
|
}
|
|
@@ -4991,7 +5174,7 @@ function checkMcpConfigDriftAndScheduleRestart(codeName, projectDir) {
|
|
|
4991
5174
|
function projectChannelSecretHash(projectDir) {
|
|
4992
5175
|
try {
|
|
4993
5176
|
const entries = parseEnvIntegrations(
|
|
4994
|
-
|
|
5177
|
+
readFileSync11(join13(projectDir, ".env.integrations"), "utf-8")
|
|
4995
5178
|
);
|
|
4996
5179
|
return channelSecretValueHash(entries, CHANNEL_SECRET_ENV_KEYS);
|
|
4997
5180
|
} catch {
|
|
@@ -5083,7 +5266,7 @@ var cachedMaintenanceWindow = null;
|
|
|
5083
5266
|
var lastVersionCheckAt = 0;
|
|
5084
5267
|
var VERSION_CHECK_INTERVAL_MS = 5 * 60 * 1e3;
|
|
5085
5268
|
var lastResponsivenessProbeAt = 0;
|
|
5086
|
-
var agtCliVersion = true ? "0.28.
|
|
5269
|
+
var agtCliVersion = true ? "0.28.14" : "dev";
|
|
5087
5270
|
function resolveBrewPath(execFileSync4) {
|
|
5088
5271
|
try {
|
|
5089
5272
|
const out = execFileSync4("which", ["brew"], { timeout: 5e3 }).toString().trim();
|
|
@@ -5096,7 +5279,7 @@ function resolveBrewPath(execFileSync4) {
|
|
|
5096
5279
|
"/usr/local/bin/brew"
|
|
5097
5280
|
];
|
|
5098
5281
|
for (const path of fallbacks) {
|
|
5099
|
-
if (
|
|
5282
|
+
if (existsSync7(path)) return path;
|
|
5100
5283
|
}
|
|
5101
5284
|
return null;
|
|
5102
5285
|
}
|
|
@@ -5106,7 +5289,7 @@ function claudeBinaryInstalled(execFileSync4) {
|
|
|
5106
5289
|
"/opt/homebrew/bin/claude",
|
|
5107
5290
|
"/usr/local/bin/claude"
|
|
5108
5291
|
];
|
|
5109
|
-
if (canonical.some((path) =>
|
|
5292
|
+
if (canonical.some((path) => existsSync7(path))) return true;
|
|
5110
5293
|
try {
|
|
5111
5294
|
execFileSync4("which", ["claude"], { timeout: 5e3 });
|
|
5112
5295
|
return true;
|
|
@@ -5178,7 +5361,7 @@ async function ensureToolkitCli(toolkitSlug) {
|
|
|
5178
5361
|
toolkitCliEnsured.add(toolkitSlug);
|
|
5179
5362
|
return;
|
|
5180
5363
|
}
|
|
5181
|
-
brewBinDir =
|
|
5364
|
+
brewBinDir = dirname3(brewPath);
|
|
5182
5365
|
const isRoot = typeof process.getuid === "function" && process.getuid() === 0;
|
|
5183
5366
|
log(`[toolkit-install] ${toolkitSlug}: installing via brew (${pkg})\u2026`);
|
|
5184
5367
|
if (isRoot) {
|
|
@@ -5259,8 +5442,8 @@ function claudeManagedSettingsPath() {
|
|
|
5259
5442
|
function ensureClaudeManagedSettings(path = claudeManagedSettingsPath()) {
|
|
5260
5443
|
try {
|
|
5261
5444
|
let settings = {};
|
|
5262
|
-
if (
|
|
5263
|
-
const raw =
|
|
5445
|
+
if (existsSync7(path)) {
|
|
5446
|
+
const raw = readFileSync11(path, "utf-8").trim();
|
|
5264
5447
|
if (raw) {
|
|
5265
5448
|
let parsed;
|
|
5266
5449
|
try {
|
|
@@ -5276,7 +5459,7 @@ function ensureClaudeManagedSettings(path = claudeManagedSettingsPath()) {
|
|
|
5276
5459
|
}
|
|
5277
5460
|
if (settings.channelsEnabled === true) return "ok";
|
|
5278
5461
|
settings.channelsEnabled = true;
|
|
5279
|
-
|
|
5462
|
+
mkdirSync4(dirname3(path), { recursive: true });
|
|
5280
5463
|
writeFileSync4(path, `${JSON.stringify(settings, null, 2)}
|
|
5281
5464
|
`);
|
|
5282
5465
|
log(`[managed-settings] set channelsEnabled:true in ${path} (ENG-5786 \u2014 unblocks Claude Code channels)`);
|
|
@@ -5318,11 +5501,11 @@ async function ensureFrameworkBinary(frameworkId) {
|
|
|
5318
5501
|
log(`Claude Code install failed: ${err.message}`);
|
|
5319
5502
|
return;
|
|
5320
5503
|
}
|
|
5321
|
-
const brewBinDir =
|
|
5504
|
+
const brewBinDir = dirname3(brewPath);
|
|
5322
5505
|
if (!process.env.PATH?.split(":").includes(brewBinDir)) {
|
|
5323
5506
|
process.env.PATH = `${brewBinDir}:${process.env.PATH ?? ""}`;
|
|
5324
5507
|
}
|
|
5325
|
-
if (
|
|
5508
|
+
if (existsSync7("/home/linuxbrew/.linuxbrew/bin/claude")) {
|
|
5326
5509
|
log("Claude Code installed successfully");
|
|
5327
5510
|
} else {
|
|
5328
5511
|
log("Claude Code install completed but binary not found at expected path \u2014 check brew logs");
|
|
@@ -5334,7 +5517,7 @@ async function ensureFrameworkBinary(frameworkId) {
|
|
|
5334
5517
|
var CLAUDE_CODE_UPGRADE_CHECK_INTERVAL_MS = 24 * 60 * 60 * 1e3;
|
|
5335
5518
|
var claudeCodeUpgradeInFlight = false;
|
|
5336
5519
|
function claudeCodeUpgradeMarkerPath() {
|
|
5337
|
-
return
|
|
5520
|
+
return join13(homedir7(), ".augmented", ".last-claude-code-upgrade-check");
|
|
5338
5521
|
}
|
|
5339
5522
|
function stampClaudeCodeUpgradeMarker() {
|
|
5340
5523
|
try {
|
|
@@ -5344,7 +5527,7 @@ function stampClaudeCodeUpgradeMarker() {
|
|
|
5344
5527
|
}
|
|
5345
5528
|
function claudeCodeUpgradeThrottled() {
|
|
5346
5529
|
try {
|
|
5347
|
-
const lastCheck = parseInt(
|
|
5530
|
+
const lastCheck = parseInt(readFileSync11(claudeCodeUpgradeMarkerPath(), "utf-8").trim(), 10);
|
|
5348
5531
|
if (!Number.isFinite(lastCheck)) return false;
|
|
5349
5532
|
return Date.now() - lastCheck < CLAUDE_CODE_UPGRADE_CHECK_INTERVAL_MS;
|
|
5350
5533
|
} catch {
|
|
@@ -5397,7 +5580,7 @@ ${r.stderr}`;
|
|
|
5397
5580
|
}
|
|
5398
5581
|
var UPDATE_CHECK_INTERVAL_MS = 5 * 60 * 1e3;
|
|
5399
5582
|
function selfUpdateAppliedMarkerPath() {
|
|
5400
|
-
return
|
|
5583
|
+
return join13(homedir7(), ".augmented", ".last-self-update-applied");
|
|
5401
5584
|
}
|
|
5402
5585
|
var selfUpdateUpToDateLogged = false;
|
|
5403
5586
|
var restartAfterUpgrade = false;
|
|
@@ -5420,7 +5603,7 @@ async function checkAndUpdateCli() {
|
|
|
5420
5603
|
const isNpmGlobal = !isBrewFormula && resolvedPath.includes("node_modules");
|
|
5421
5604
|
if (!isBrewFormula && !isNpmGlobal) return;
|
|
5422
5605
|
const { readFileSync: readF, writeFileSync: writeF } = await import("fs");
|
|
5423
|
-
const markerPath =
|
|
5606
|
+
const markerPath = join13(homedir7(), ".augmented", ".last-update-check");
|
|
5424
5607
|
try {
|
|
5425
5608
|
const lastCheck = parseInt(readF(markerPath, "utf-8").trim(), 10);
|
|
5426
5609
|
if (Date.now() - lastCheck < UPDATE_CHECK_INTERVAL_MS) return;
|
|
@@ -5675,41 +5858,15 @@ async function checkClaudeAuth() {
|
|
|
5675
5858
|
return false;
|
|
5676
5859
|
}
|
|
5677
5860
|
}
|
|
5678
|
-
async function applyClaudeAuthToEnv(childEnv, label) {
|
|
5679
|
-
const apiKey = getApiKey();
|
|
5680
|
-
if (!apiKey) {
|
|
5681
|
-
throw new Error("AGT_API_KEY is not set");
|
|
5682
|
-
}
|
|
5683
|
-
const exchange = await exchangeApiKey(apiKey, false, { forceRefresh: true });
|
|
5684
|
-
if (exchange.claudeAuthMode === "api_key") {
|
|
5685
|
-
if (!exchange.anthropicApiKey) {
|
|
5686
|
-
throw new Error("claude_auth_mode=api_key but /host/exchange returned no decrypted key");
|
|
5687
|
-
}
|
|
5688
|
-
childEnv.ANTHROPIC_API_KEY = exchange.anthropicApiKey;
|
|
5689
|
-
const claudeDir = join11(homedir5(), ".claude");
|
|
5690
|
-
for (const filename of [".credentials.json", "credentials.json"]) {
|
|
5691
|
-
const p = join11(claudeDir, filename);
|
|
5692
|
-
if (existsSync5(p)) {
|
|
5693
|
-
try {
|
|
5694
|
-
rmSync2(p, { force: true });
|
|
5695
|
-
log(`[${label}] Removed ${p} (api_key mode \u2014 preventing OAuth fallback)`);
|
|
5696
|
-
} catch {
|
|
5697
|
-
}
|
|
5698
|
-
}
|
|
5699
|
-
}
|
|
5700
|
-
} else {
|
|
5701
|
-
delete childEnv.ANTHROPIC_API_KEY;
|
|
5702
|
-
}
|
|
5703
|
-
}
|
|
5704
5861
|
var evalEmptyMcpConfigPath = null;
|
|
5705
5862
|
function ensureEvalEmptyMcpConfig() {
|
|
5706
|
-
if (evalEmptyMcpConfigPath &&
|
|
5707
|
-
const dir =
|
|
5863
|
+
if (evalEmptyMcpConfigPath && existsSync7(evalEmptyMcpConfigPath)) return evalEmptyMcpConfigPath;
|
|
5864
|
+
const dir = join13(homedir7(), ".augmented");
|
|
5708
5865
|
try {
|
|
5709
|
-
|
|
5866
|
+
mkdirSync4(dir, { recursive: true });
|
|
5710
5867
|
} catch {
|
|
5711
5868
|
}
|
|
5712
|
-
const p =
|
|
5869
|
+
const p = join13(dir, ".eval-empty-mcp.json");
|
|
5713
5870
|
writeFileSync4(p, JSON.stringify({ mcpServers: {} }));
|
|
5714
5871
|
evalEmptyMcpConfigPath = p;
|
|
5715
5872
|
return p;
|
|
@@ -5735,7 +5892,7 @@ async function runEvalClaude(prompt, model) {
|
|
|
5735
5892
|
""
|
|
5736
5893
|
];
|
|
5737
5894
|
const { stdout } = await execFilePromiseLong(resolveClaudeBinary(), args, {
|
|
5738
|
-
cwd:
|
|
5895
|
+
cwd: homedir7(),
|
|
5739
5896
|
timeout: 12e4,
|
|
5740
5897
|
stdin: "ignore",
|
|
5741
5898
|
env: childEnv,
|
|
@@ -5784,13 +5941,13 @@ function resolveConversationEvalBackend() {
|
|
|
5784
5941
|
}
|
|
5785
5942
|
function loadGatewayPorts() {
|
|
5786
5943
|
try {
|
|
5787
|
-
return JSON.parse(
|
|
5944
|
+
return JSON.parse(readFileSync11(GATEWAY_PORTS_FILE, "utf-8"));
|
|
5788
5945
|
} catch {
|
|
5789
5946
|
return {};
|
|
5790
5947
|
}
|
|
5791
5948
|
}
|
|
5792
5949
|
function saveGatewayPorts(ports) {
|
|
5793
|
-
|
|
5950
|
+
mkdirSync4(AUGMENTED_DIR, { recursive: true });
|
|
5794
5951
|
writeFileSync4(GATEWAY_PORTS_FILE, JSON.stringify(ports, null, 2));
|
|
5795
5952
|
}
|
|
5796
5953
|
function allocatePort(codeName) {
|
|
@@ -5814,10 +5971,10 @@ function freePort(codeName) {
|
|
|
5814
5971
|
}
|
|
5815
5972
|
}
|
|
5816
5973
|
function getStateFile() {
|
|
5817
|
-
return
|
|
5974
|
+
return join13(config?.configDir ?? join13(process.env["HOME"] ?? "/tmp", ".augmented"), "manager-state.json");
|
|
5818
5975
|
}
|
|
5819
5976
|
function channelHashCacheDir() {
|
|
5820
|
-
return config?.configDir ??
|
|
5977
|
+
return config?.configDir ?? join13(process.env["HOME"] ?? "/tmp", ".augmented");
|
|
5821
5978
|
}
|
|
5822
5979
|
function loadChannelHashCache2() {
|
|
5823
5980
|
loadChannelHashCache(agentState.knownChannelConfigHashes, channelHashCacheDir());
|
|
@@ -5828,7 +5985,7 @@ function saveChannelHashCache2() {
|
|
|
5828
5985
|
var _channelQuarantineStore = null;
|
|
5829
5986
|
function channelQuarantineStore() {
|
|
5830
5987
|
if (!_channelQuarantineStore) {
|
|
5831
|
-
const dir = config?.configDir ??
|
|
5988
|
+
const dir = config?.configDir ?? join13(process.env["HOME"] ?? "/tmp", ".augmented");
|
|
5832
5989
|
_channelQuarantineStore = new ChannelQuarantineStore(defaultQuarantinePath(dir));
|
|
5833
5990
|
}
|
|
5834
5991
|
return _channelQuarantineStore;
|
|
@@ -5836,7 +5993,7 @@ function channelQuarantineStore() {
|
|
|
5836
5993
|
var _hostFlagStore = null;
|
|
5837
5994
|
function hostFlagStore() {
|
|
5838
5995
|
if (!_hostFlagStore) {
|
|
5839
|
-
const dir = config?.configDir ??
|
|
5996
|
+
const dir = config?.configDir ?? join13(process.env["HOME"] ?? "/tmp", ".augmented");
|
|
5840
5997
|
_hostFlagStore = new HostFlagStore({ cachePath: defaultFlagsCachePath(dir), log });
|
|
5841
5998
|
}
|
|
5842
5999
|
return _hostFlagStore;
|
|
@@ -5869,61 +6026,6 @@ function send(msg) {
|
|
|
5869
6026
|
log(`Error: ${msg.message}`);
|
|
5870
6027
|
}
|
|
5871
6028
|
}
|
|
5872
|
-
var managerLogPath = null;
|
|
5873
|
-
var managerLogWritable = true;
|
|
5874
|
-
function redactForDiskLog(value) {
|
|
5875
|
-
try {
|
|
5876
|
-
return value.replace(/\b(Bearer\s+)[A-Za-z0-9._-]+\b/gi, "$1[REDACTED]").replace(/\bxox[baprs]-[A-Za-z0-9-]+\b/g, "[REDACTED-SLACK]").replace(/\btlk_[A-Za-z0-9._-]+\b/g, "[REDACTED-HOST]").replace(/\bsk-ant-[A-Za-z0-9_-]+\b/g, "[REDACTED-ANTHROPIC]").replace(/\b\d{8,12}:[A-Za-z0-9_-]{30,}\b/g, "[REDACTED-TELEGRAM]").replace(
|
|
5877
|
-
/\b([A-Z0-9_]*(?:TOKEN|SECRET|API[_-]?KEY|PASSWORD)[A-Z0-9_]*)=(?:"[^"\r\n]*"|'[^'\r\n]*'|[^\s\r\n]+)/gi,
|
|
5878
|
-
"$1=[REDACTED]"
|
|
5879
|
-
);
|
|
5880
|
-
} catch {
|
|
5881
|
-
return "[REDACTED]";
|
|
5882
|
-
}
|
|
5883
|
-
}
|
|
5884
|
-
function log(msg) {
|
|
5885
|
-
const ts = (/* @__PURE__ */ new Date()).toISOString();
|
|
5886
|
-
const safeMsg = redactForDiskLog(msg);
|
|
5887
|
-
const line = `[manager-worker ${ts}] ${safeMsg}
|
|
5888
|
-
`;
|
|
5889
|
-
if (!managerLogPath) {
|
|
5890
|
-
try {
|
|
5891
|
-
managerLogPath = join11(homedir5(), ".augmented", "manager.log");
|
|
5892
|
-
mkdirSync3(dirname2(managerLogPath), { recursive: true });
|
|
5893
|
-
if (existsSync5(managerLogPath)) {
|
|
5894
|
-
chmodSync(managerLogPath, 384);
|
|
5895
|
-
}
|
|
5896
|
-
} catch {
|
|
5897
|
-
}
|
|
5898
|
-
}
|
|
5899
|
-
let appendedToFile = false;
|
|
5900
|
-
if (managerLogPath && managerLogWritable) {
|
|
5901
|
-
try {
|
|
5902
|
-
appendFileSync(managerLogPath, line, { encoding: "utf-8", mode: 384 });
|
|
5903
|
-
appendedToFile = true;
|
|
5904
|
-
} catch (err) {
|
|
5905
|
-
managerLogWritable = false;
|
|
5906
|
-
process.stderr.write(
|
|
5907
|
-
`[manager-worker ${ts}] [log] manager.log append failed; falling back to stderr-only: ${err.message}
|
|
5908
|
-
`
|
|
5909
|
-
);
|
|
5910
|
-
}
|
|
5911
|
-
}
|
|
5912
|
-
if (!appendedToFile || process.stderr.isTTY === true) {
|
|
5913
|
-
process.stderr.write(line);
|
|
5914
|
-
}
|
|
5915
|
-
}
|
|
5916
|
-
function sha256(content) {
|
|
5917
|
-
return createHash3("sha256").update(content, "utf8").digest("hex");
|
|
5918
|
-
}
|
|
5919
|
-
function hashFile(filePath) {
|
|
5920
|
-
try {
|
|
5921
|
-
const content = readFileSync10(filePath, "utf-8");
|
|
5922
|
-
return sha256(content);
|
|
5923
|
-
} catch {
|
|
5924
|
-
return null;
|
|
5925
|
-
}
|
|
5926
|
-
}
|
|
5927
6029
|
var SKILLS_INDEX_START = "<!-- AGT:SKILLS_INDEX_START -->";
|
|
5928
6030
|
var SKILLS_INDEX_END = "<!-- AGT:SKILLS_INDEX_END -->";
|
|
5929
6031
|
function sanitizeSkillsIndexText(value) {
|
|
@@ -5943,12 +6045,12 @@ function parseSkillFrontmatter(content) {
|
|
|
5943
6045
|
}
|
|
5944
6046
|
async function refreshSkillsIndexInClaudeMd(configDir, codeName, log2) {
|
|
5945
6047
|
const { readdirSync: readdirSync6, readFileSync: rfs, existsSync: ex, writeFileSync: writeFileSync5 } = await import("fs");
|
|
5946
|
-
const skillsDir =
|
|
5947
|
-
const claudeMdPath =
|
|
6048
|
+
const skillsDir = join13(configDir, codeName, "project", ".claude", "skills");
|
|
6049
|
+
const claudeMdPath = join13(configDir, codeName, "project", "CLAUDE.md");
|
|
5948
6050
|
if (!ex(skillsDir) || !ex(claudeMdPath)) return;
|
|
5949
6051
|
const entries = [];
|
|
5950
6052
|
for (const dir of readdirSync6(skillsDir).sort()) {
|
|
5951
|
-
const skillFile =
|
|
6053
|
+
const skillFile = join13(skillsDir, dir, "SKILL.md");
|
|
5952
6054
|
if (!ex(skillFile)) continue;
|
|
5953
6055
|
try {
|
|
5954
6056
|
const { name, description } = parseSkillFrontmatter(rfs(skillFile, "utf-8"));
|
|
@@ -5996,10 +6098,10 @@ ${SKILLS_INDEX_END}`;
|
|
|
5996
6098
|
}
|
|
5997
6099
|
async function migrateToProfiles() {
|
|
5998
6100
|
const homeDir = process.env["HOME"] ?? "/tmp";
|
|
5999
|
-
const sharedConfigPath =
|
|
6101
|
+
const sharedConfigPath = join13(homeDir, ".openclaw", "openclaw.json");
|
|
6000
6102
|
let sharedConfig;
|
|
6001
6103
|
try {
|
|
6002
|
-
sharedConfig = JSON.parse(
|
|
6104
|
+
sharedConfig = JSON.parse(readFileSync11(sharedConfigPath, "utf-8"));
|
|
6003
6105
|
} catch {
|
|
6004
6106
|
return;
|
|
6005
6107
|
}
|
|
@@ -6012,19 +6114,19 @@ async function migrateToProfiles() {
|
|
|
6012
6114
|
const codeName = agentEntry["id"];
|
|
6013
6115
|
if (!codeName) continue;
|
|
6014
6116
|
if (codeName === "main") continue;
|
|
6015
|
-
const profileDir =
|
|
6016
|
-
if (
|
|
6117
|
+
const profileDir = join13(homeDir, `.openclaw-${codeName}`);
|
|
6118
|
+
if (existsSync7(join13(profileDir, "openclaw.json"))) continue;
|
|
6017
6119
|
log(`Migrating agent '${codeName}' to per-agent profile`);
|
|
6018
6120
|
if (adapter.seedProfileConfig) {
|
|
6019
6121
|
adapter.seedProfileConfig(codeName);
|
|
6020
6122
|
}
|
|
6021
|
-
const sharedAuthDir =
|
|
6022
|
-
const profileAuthDir =
|
|
6023
|
-
const authFile =
|
|
6024
|
-
if (
|
|
6025
|
-
|
|
6026
|
-
const authContent =
|
|
6027
|
-
writeFileSync4(
|
|
6123
|
+
const sharedAuthDir = join13(homeDir, ".openclaw", "agents", codeName, "agent");
|
|
6124
|
+
const profileAuthDir = join13(profileDir, "agents", codeName, "agent");
|
|
6125
|
+
const authFile = join13(sharedAuthDir, "auth-profiles.json");
|
|
6126
|
+
if (existsSync7(authFile)) {
|
|
6127
|
+
mkdirSync4(profileAuthDir, { recursive: true });
|
|
6128
|
+
const authContent = readFileSync11(authFile, "utf-8");
|
|
6129
|
+
writeFileSync4(join13(profileAuthDir, "auth-profiles.json"), authContent);
|
|
6028
6130
|
}
|
|
6029
6131
|
allocatePort(codeName);
|
|
6030
6132
|
migrated++;
|
|
@@ -6033,28 +6135,6 @@ async function migrateToProfiles() {
|
|
|
6033
6135
|
log(`Migration complete: ${migrated} agent(s) migrated to per-agent profiles`);
|
|
6034
6136
|
}
|
|
6035
6137
|
}
|
|
6036
|
-
function resolveModelChain(refreshData) {
|
|
6037
|
-
const agent = refreshData.agent;
|
|
6038
|
-
const modelDefaults = refreshData.model_defaults;
|
|
6039
|
-
const platform2 = modelDefaults?.platform ?? {};
|
|
6040
|
-
const org = modelDefaults?.org ?? {};
|
|
6041
|
-
function resolve(tier) {
|
|
6042
|
-
const agentField = `${tier}_model`;
|
|
6043
|
-
const platformField = `default_${tier}_model`;
|
|
6044
|
-
const agentVal = agent?.[agentField];
|
|
6045
|
-
if (agentVal) return agentVal;
|
|
6046
|
-
const orgVal = org?.[platformField];
|
|
6047
|
-
if (orgVal) return orgVal;
|
|
6048
|
-
const platformVal = platform2?.[platformField];
|
|
6049
|
-
if (platformVal) return platformVal;
|
|
6050
|
-
return void 0;
|
|
6051
|
-
}
|
|
6052
|
-
return {
|
|
6053
|
-
primary: resolve("primary"),
|
|
6054
|
-
secondary: resolve("secondary"),
|
|
6055
|
-
tertiary: resolve("tertiary")
|
|
6056
|
-
};
|
|
6057
|
-
}
|
|
6058
6138
|
function readGatewayToken(codeName) {
|
|
6059
6139
|
const adapter = resolveAgentFramework(codeName);
|
|
6060
6140
|
if (adapter.readGatewayToken) {
|
|
@@ -6062,7 +6142,7 @@ function readGatewayToken(codeName) {
|
|
|
6062
6142
|
}
|
|
6063
6143
|
const homeDir = process.env["HOME"] ?? "/tmp";
|
|
6064
6144
|
try {
|
|
6065
|
-
const cfg = JSON.parse(
|
|
6145
|
+
const cfg = JSON.parse(readFileSync11(join13(homeDir, `.openclaw-${codeName}`, "openclaw.json"), "utf-8"));
|
|
6066
6146
|
return cfg?.gateway?.auth?.token;
|
|
6067
6147
|
} catch {
|
|
6068
6148
|
return void 0;
|
|
@@ -6071,10 +6151,10 @@ function readGatewayToken(codeName) {
|
|
|
6071
6151
|
var GATEWAY_HUNG_TIMEOUT_MS = 5 * 6e4;
|
|
6072
6152
|
function isGatewayHung(codeName) {
|
|
6073
6153
|
const homeDir = process.env["HOME"] ?? "/tmp";
|
|
6074
|
-
const jobsPath =
|
|
6075
|
-
if (!
|
|
6154
|
+
const jobsPath = join13(homeDir, `.openclaw-${codeName}`, "cron", "jobs.json");
|
|
6155
|
+
if (!existsSync7(jobsPath)) return false;
|
|
6076
6156
|
try {
|
|
6077
|
-
const data = JSON.parse(
|
|
6157
|
+
const data = JSON.parse(readFileSync11(jobsPath, "utf-8"));
|
|
6078
6158
|
const jobs = data.jobs ?? data;
|
|
6079
6159
|
if (!Array.isArray(jobs)) return false;
|
|
6080
6160
|
const now = Date.now();
|
|
@@ -6107,15 +6187,15 @@ async function ensureGatewayRunning(codeName, adapter) {
|
|
|
6107
6187
|
}
|
|
6108
6188
|
await new Promise((r) => setTimeout(r, 2e3));
|
|
6109
6189
|
const homeDir = process.env["HOME"] ?? "/tmp";
|
|
6110
|
-
const cronJobsPath =
|
|
6190
|
+
const cronJobsPath = join13(homeDir, `.openclaw-${codeName}`, "cron", "jobs.json");
|
|
6111
6191
|
clearStaleCronRunState(cronJobsPath);
|
|
6112
6192
|
} else {
|
|
6113
6193
|
if (status.port) {
|
|
6114
6194
|
try {
|
|
6115
6195
|
const homeDir = process.env["HOME"] ?? "/tmp";
|
|
6116
|
-
const configPath =
|
|
6117
|
-
if (
|
|
6118
|
-
const cfg = JSON.parse(
|
|
6196
|
+
const configPath = join13(homeDir, `.openclaw-${codeName}`, "openclaw.json");
|
|
6197
|
+
if (existsSync7(configPath)) {
|
|
6198
|
+
const cfg = JSON.parse(readFileSync11(configPath, "utf-8"));
|
|
6119
6199
|
if (cfg.gateway?.port !== status.port) {
|
|
6120
6200
|
if (!cfg.gateway) cfg.gateway = {};
|
|
6121
6201
|
cfg.gateway.port = status.port;
|
|
@@ -6139,9 +6219,9 @@ async function ensureGatewayRunning(codeName, adapter) {
|
|
|
6139
6219
|
gatewaysStartedThisCycle.add(codeName);
|
|
6140
6220
|
try {
|
|
6141
6221
|
const homeDir = process.env["HOME"] ?? "/tmp";
|
|
6142
|
-
const configPath =
|
|
6143
|
-
if (
|
|
6144
|
-
const cfg = JSON.parse(
|
|
6222
|
+
const configPath = join13(homeDir, `.openclaw-${codeName}`, "openclaw.json");
|
|
6223
|
+
if (existsSync7(configPath)) {
|
|
6224
|
+
const cfg = JSON.parse(readFileSync11(configPath, "utf-8"));
|
|
6145
6225
|
if (!cfg.gateway) cfg.gateway = {};
|
|
6146
6226
|
cfg.gateway.port = port;
|
|
6147
6227
|
writeFileSync4(configPath, JSON.stringify(cfg, null, 2));
|
|
@@ -6325,7 +6405,7 @@ async function pollCycle() {
|
|
|
6325
6405
|
claudeAuth = await detectClaudeAuth();
|
|
6326
6406
|
} catch (err) {
|
|
6327
6407
|
const errText = err instanceof Error ? err.message : String(err);
|
|
6328
|
-
const errId =
|
|
6408
|
+
const errId = createHash4("sha256").update(errText).digest("hex").slice(0, 12);
|
|
6329
6409
|
log(`Claude auth detection failed (error_id=${errId})`);
|
|
6330
6410
|
}
|
|
6331
6411
|
const hostHasClaudeCode = state6.agents.some(
|
|
@@ -6678,7 +6758,7 @@ async function pollCycle() {
|
|
|
6678
6758
|
}
|
|
6679
6759
|
killAgentChannelProcesses(prev.codeName, { log });
|
|
6680
6760
|
freePort(prev.codeName);
|
|
6681
|
-
const agentDir =
|
|
6761
|
+
const agentDir = join13(adapter.getAgentDir(prev.codeName), "provision");
|
|
6682
6762
|
await cleanupAgentFiles(prev.codeName, agentDir);
|
|
6683
6763
|
clearAgentCaches(prev.agentId, prev.codeName);
|
|
6684
6764
|
}
|
|
@@ -6764,10 +6844,10 @@ async function pollCycle() {
|
|
|
6764
6844
|
// pending-inbound marker. Best-effort: a write failure is logged by
|
|
6765
6845
|
// the watchdog, never fails the poll cycle.
|
|
6766
6846
|
signalGiveUp: (codeName) => {
|
|
6767
|
-
const dir =
|
|
6768
|
-
if (!
|
|
6847
|
+
const dir = join13(homedir7(), ".augmented", codeName);
|
|
6848
|
+
if (!existsSync7(dir)) return;
|
|
6769
6849
|
atomicWriteFileSync(
|
|
6770
|
-
|
|
6850
|
+
join13(dir, "watchdog-give-up.json"),
|
|
6771
6851
|
JSON.stringify({ gave_up_at: (/* @__PURE__ */ new Date()).toISOString() })
|
|
6772
6852
|
);
|
|
6773
6853
|
}
|
|
@@ -6894,7 +6974,7 @@ async function processAgent(agent, agentStates) {
|
|
|
6894
6974
|
}
|
|
6895
6975
|
const now = (/* @__PURE__ */ new Date()).toISOString();
|
|
6896
6976
|
const adapter = resolveAgentFramework(agent.code_name);
|
|
6897
|
-
let agentDir =
|
|
6977
|
+
let agentDir = join13(adapter.getAgentDir(agent.code_name), "provision");
|
|
6898
6978
|
if (agent.status === "draft" || agent.status === "paused") {
|
|
6899
6979
|
if (previousKnownStatus !== agent.status) {
|
|
6900
6980
|
log(`Agent '${agent.code_name}' is ${agent.status}, skipping provisioning`);
|
|
@@ -6946,7 +7026,7 @@ async function processAgent(agent, agentStates) {
|
|
|
6946
7026
|
const residuals = {
|
|
6947
7027
|
gatewayRunning: gatewayLiveness.running,
|
|
6948
7028
|
portAllocated: Object.prototype.hasOwnProperty.call(ports, agent.code_name),
|
|
6949
|
-
provisionDirExists:
|
|
7029
|
+
provisionDirExists: existsSync7(agentDir)
|
|
6950
7030
|
};
|
|
6951
7031
|
if (!hasRevokedResiduals(residuals)) {
|
|
6952
7032
|
agentStates.push({
|
|
@@ -7098,7 +7178,7 @@ async function processAgent(agent, agentStates) {
|
|
|
7098
7178
|
const frameworkId = refreshData.agent.framework ?? "openclaw";
|
|
7099
7179
|
agentFrameworkCache.set(agent.code_name, frameworkId);
|
|
7100
7180
|
const frameworkAdapter = getFramework(frameworkId);
|
|
7101
|
-
agentDir =
|
|
7181
|
+
agentDir = join13(frameworkAdapter.getAgentDir(agent.code_name), "provision");
|
|
7102
7182
|
cacheAgentDeliveryMetadata(agent.code_name, refreshData);
|
|
7103
7183
|
if (frameworkAdapter.migrateSecretStorage && !migratedSecretStorage.has(agent.code_name)) {
|
|
7104
7184
|
try {
|
|
@@ -7139,9 +7219,9 @@ async function processAgent(agent, agentStates) {
|
|
|
7139
7219
|
try {
|
|
7140
7220
|
const artifacts = generateArtifacts(agent, refreshData, frameworkAdapter);
|
|
7141
7221
|
const changedFiles = [];
|
|
7142
|
-
|
|
7222
|
+
mkdirSync4(agentDir, { recursive: true });
|
|
7143
7223
|
for (const artifact of artifacts) {
|
|
7144
|
-
const filePath =
|
|
7224
|
+
const filePath = join13(agentDir, artifact.relativePath);
|
|
7145
7225
|
let existingHash;
|
|
7146
7226
|
let newHash;
|
|
7147
7227
|
let writeContent = artifact.content;
|
|
@@ -7160,8 +7240,8 @@ async function processAgent(agent, agentStates) {
|
|
|
7160
7240
|
};
|
|
7161
7241
|
newHash = sha256(stripDynamicSections(artifact.content));
|
|
7162
7242
|
try {
|
|
7163
|
-
const projectClaudeMd =
|
|
7164
|
-
const existing =
|
|
7243
|
+
const projectClaudeMd = join13(config.configDir, agent.code_name, "project", "CLAUDE.md");
|
|
7244
|
+
const existing = readFileSync11(projectClaudeMd, "utf-8");
|
|
7165
7245
|
existingHash = sha256(stripDynamicSections(existing));
|
|
7166
7246
|
} catch {
|
|
7167
7247
|
existingHash = null;
|
|
@@ -7179,7 +7259,7 @@ async function processAgent(agent, agentStates) {
|
|
|
7179
7259
|
const generatorKeys = Object.keys(generatorServers);
|
|
7180
7260
|
let existingRaw = "";
|
|
7181
7261
|
try {
|
|
7182
|
-
existingRaw =
|
|
7262
|
+
existingRaw = readFileSync11(filePath, "utf-8");
|
|
7183
7263
|
} catch {
|
|
7184
7264
|
}
|
|
7185
7265
|
const existingServers = parseMcp(existingRaw);
|
|
@@ -7201,13 +7281,13 @@ async function processAgent(agent, agentStates) {
|
|
|
7201
7281
|
}
|
|
7202
7282
|
}
|
|
7203
7283
|
if (changedFiles.length > 0) {
|
|
7204
|
-
const isFirst = !
|
|
7284
|
+
const isFirst = !existsSync7(join13(agentDir, "CHARTER.md"));
|
|
7205
7285
|
const verb = isFirst ? "Provisioning" : "Updating";
|
|
7206
7286
|
const fileNames = changedFiles.map((f) => f.relativePath).join(", ");
|
|
7207
7287
|
log(`${verb} '${agent.code_name}': ${fileNames}`);
|
|
7208
7288
|
for (const file of changedFiles) {
|
|
7209
|
-
const filePath =
|
|
7210
|
-
|
|
7289
|
+
const filePath = join13(agentDir, file.relativePath);
|
|
7290
|
+
mkdirSync4(dirname3(filePath), { recursive: true });
|
|
7211
7291
|
if (file.relativePath === ".mcp.json") {
|
|
7212
7292
|
safeWriteJsonAtomic(filePath, file.content, { mode: 384 });
|
|
7213
7293
|
} else {
|
|
@@ -7215,12 +7295,12 @@ async function processAgent(agent, agentStates) {
|
|
|
7215
7295
|
}
|
|
7216
7296
|
}
|
|
7217
7297
|
try {
|
|
7218
|
-
const provSkillsDir =
|
|
7219
|
-
if (
|
|
7298
|
+
const provSkillsDir = join13(agentDir, ".claude", "skills");
|
|
7299
|
+
if (existsSync7(provSkillsDir)) {
|
|
7220
7300
|
for (const folder of readdirSync5(provSkillsDir)) {
|
|
7221
7301
|
if (folder.startsWith("knowledge-")) {
|
|
7222
7302
|
try {
|
|
7223
|
-
|
|
7303
|
+
rmSync3(join13(provSkillsDir, folder), { recursive: true });
|
|
7224
7304
|
} catch {
|
|
7225
7305
|
}
|
|
7226
7306
|
}
|
|
@@ -7233,7 +7313,7 @@ async function processAgent(agent, agentStates) {
|
|
|
7233
7313
|
const trackedFiles2 = frameworkAdapter.driftTrackedFiles();
|
|
7234
7314
|
const hashes = /* @__PURE__ */ new Map();
|
|
7235
7315
|
for (const file of trackedFiles2) {
|
|
7236
|
-
const h = hashFile(
|
|
7316
|
+
const h = hashFile(join13(agentDir, file));
|
|
7237
7317
|
if (h) hashes.set(file, h);
|
|
7238
7318
|
}
|
|
7239
7319
|
agentState.writtenHashes.set(agent.agent_id, hashes);
|
|
@@ -7251,14 +7331,14 @@ async function processAgent(agent, agentStates) {
|
|
|
7251
7331
|
}
|
|
7252
7332
|
if (Array.isArray(refreshData.workflows)) {
|
|
7253
7333
|
try {
|
|
7254
|
-
const provWorkflowsDir =
|
|
7255
|
-
if (
|
|
7334
|
+
const provWorkflowsDir = join13(agentDir, ".claude", "workflows");
|
|
7335
|
+
if (existsSync7(provWorkflowsDir)) {
|
|
7256
7336
|
const expected = new Set(refreshData.workflows.map((w) => `${w.name}.js`));
|
|
7257
7337
|
for (const file of readdirSync5(provWorkflowsDir)) {
|
|
7258
7338
|
if (!file.endsWith(".js")) continue;
|
|
7259
7339
|
if (expected.has(file)) continue;
|
|
7260
7340
|
try {
|
|
7261
|
-
|
|
7341
|
+
rmSync3(join13(provWorkflowsDir, file));
|
|
7262
7342
|
} catch {
|
|
7263
7343
|
}
|
|
7264
7344
|
}
|
|
@@ -7315,10 +7395,10 @@ async function processAgent(agent, agentStates) {
|
|
|
7315
7395
|
}
|
|
7316
7396
|
let lastDriftCheckAt = now;
|
|
7317
7397
|
const written = agentState.writtenHashes.get(agent.agent_id);
|
|
7318
|
-
if (written &&
|
|
7398
|
+
if (written && existsSync7(agentDir)) {
|
|
7319
7399
|
const driftedFiles = [];
|
|
7320
7400
|
for (const [file, expectedHash] of written) {
|
|
7321
|
-
const localHash = hashFile(
|
|
7401
|
+
const localHash = hashFile(join13(agentDir, file));
|
|
7322
7402
|
if (localHash && localHash !== expectedHash) {
|
|
7323
7403
|
driftedFiles.push(file);
|
|
7324
7404
|
}
|
|
@@ -7329,7 +7409,7 @@ async function processAgent(agent, agentStates) {
|
|
|
7329
7409
|
try {
|
|
7330
7410
|
const localHashes = {};
|
|
7331
7411
|
for (const file of driftedFiles) {
|
|
7332
|
-
localHashes[file] = hashFile(
|
|
7412
|
+
localHashes[file] = hashFile(join13(agentDir, file));
|
|
7333
7413
|
}
|
|
7334
7414
|
await api.post("/host/drift", {
|
|
7335
7415
|
agent_id: agent.agent_id,
|
|
@@ -7403,7 +7483,7 @@ async function processAgent(agent, agentStates) {
|
|
|
7403
7483
|
const sessionModeForHash = refreshData.agent.session_mode;
|
|
7404
7484
|
const senderPolicyForHash = refreshData.sender_policy ?? null;
|
|
7405
7485
|
const CHANNEL_WRITE_VERSION = 9;
|
|
7406
|
-
const configHash =
|
|
7486
|
+
const configHash = createHash4("sha256").update(
|
|
7407
7487
|
canonicalJson({
|
|
7408
7488
|
writeVersion: CHANNEL_WRITE_VERSION,
|
|
7409
7489
|
config: entry.config,
|
|
@@ -7517,7 +7597,7 @@ async function processAgent(agent, agentStates) {
|
|
|
7517
7597
|
if (channelConfigConverged) {
|
|
7518
7598
|
const hasSenderPolicyChannel = currentChannelIds.has("slack") || currentChannelIds.has("msteams");
|
|
7519
7599
|
const senderPolicyForRestartHash = refreshData.sender_policy ?? null;
|
|
7520
|
-
const senderPolicyHash =
|
|
7600
|
+
const senderPolicyHash = createHash4("sha256").update(canonicalJson({ senderPolicy: senderPolicyForRestartHash })).digest("hex");
|
|
7521
7601
|
const prevSenderPolicyHash = agentState.knownSenderPolicyHashes.get(agent.agent_id);
|
|
7522
7602
|
const senderPolicyDecision = hasSenderPolicyChannel ? decideSenderPolicyRestart({
|
|
7523
7603
|
previousHash: prevSenderPolicyHash,
|
|
@@ -7559,7 +7639,7 @@ async function processAgent(agent, agentStates) {
|
|
|
7559
7639
|
const behaviourSubset = extractMsTeamsBehaviourSubset(
|
|
7560
7640
|
msteamsEntry?.config
|
|
7561
7641
|
);
|
|
7562
|
-
const behaviourHash =
|
|
7642
|
+
const behaviourHash = createHash4("sha256").update(canonicalJson(behaviourSubset)).digest("hex");
|
|
7563
7643
|
const prevBehaviourHash = agentState.knownMsTeamsBehaviourHashes.get(agent.agent_id);
|
|
7564
7644
|
const behaviourDecision = decideSenderPolicyRestart({
|
|
7565
7645
|
previousHash: prevBehaviourHash,
|
|
@@ -7606,7 +7686,7 @@ async function processAgent(agent, agentStates) {
|
|
|
7606
7686
|
const slackBehaviourSubset = extractSlackBehaviourSubset(
|
|
7607
7687
|
slackEntry?.config
|
|
7608
7688
|
);
|
|
7609
|
-
const slackBehaviourHash =
|
|
7689
|
+
const slackBehaviourHash = createHash4("sha256").update(canonicalJson(slackBehaviourSubset)).digest("hex");
|
|
7610
7690
|
const prevSlackBehaviourHash = agentState.knownSlackBehaviourHashes.get(agent.agent_id);
|
|
7611
7691
|
const slackBehaviourDecision = decideSenderPolicyRestart({
|
|
7612
7692
|
previousHash: prevSlackBehaviourHash,
|
|
@@ -7653,24 +7733,24 @@ async function processAgent(agent, agentStates) {
|
|
|
7653
7733
|
if (agentSessionMode === "persistent" && (agentFrameworkCache.get(agent.code_name) ?? "openclaw") === "claude-code") {
|
|
7654
7734
|
try {
|
|
7655
7735
|
const agentProvisionDir = agentDir;
|
|
7656
|
-
const projectDir =
|
|
7657
|
-
|
|
7658
|
-
|
|
7659
|
-
const provisionMcpPath =
|
|
7660
|
-
const projectMcpPath =
|
|
7736
|
+
const projectDir = join13(homedir7(), ".augmented", agent.code_name, "project");
|
|
7737
|
+
mkdirSync4(agentProvisionDir, { recursive: true });
|
|
7738
|
+
mkdirSync4(projectDir, { recursive: true });
|
|
7739
|
+
const provisionMcpPath = join13(agentProvisionDir, ".mcp.json");
|
|
7740
|
+
const projectMcpPath = join13(projectDir, ".mcp.json");
|
|
7661
7741
|
let mcpConfig = { mcpServers: {} };
|
|
7662
7742
|
try {
|
|
7663
|
-
mcpConfig = JSON.parse(
|
|
7743
|
+
mcpConfig = JSON.parse(readFileSync11(provisionMcpPath, "utf-8"));
|
|
7664
7744
|
if (!mcpConfig.mcpServers) mcpConfig.mcpServers = {};
|
|
7665
7745
|
} catch {
|
|
7666
7746
|
}
|
|
7667
|
-
const localDirectChatChannel =
|
|
7747
|
+
const localDirectChatChannel = join13(homedir7(), ".augmented", "_mcp", "direct-chat-channel.js");
|
|
7668
7748
|
const directChatTeamSettings = refreshData.team?.settings;
|
|
7669
7749
|
const directChatTz = (() => {
|
|
7670
7750
|
const tz = directChatTeamSettings?.["timezone"];
|
|
7671
7751
|
return typeof tz === "string" && tz.trim() !== "" ? tz.trim() : void 0;
|
|
7672
7752
|
})();
|
|
7673
|
-
if (
|
|
7753
|
+
if (existsSync7(localDirectChatChannel)) {
|
|
7674
7754
|
const directChatEnv = {
|
|
7675
7755
|
AGT_HOST: requireHost(),
|
|
7676
7756
|
// ENG-5901 Track D: templated — the manager exports the real
|
|
@@ -7694,10 +7774,10 @@ async function processAgent(agent, agentStates) {
|
|
|
7694
7774
|
log(`Channel credentials written for '${agent.code_name}/direct-chat'`);
|
|
7695
7775
|
}
|
|
7696
7776
|
}
|
|
7697
|
-
const staleChannelsPath =
|
|
7698
|
-
if (
|
|
7777
|
+
const staleChannelsPath = join13(projectDir, ".mcp-channels.json");
|
|
7778
|
+
if (existsSync7(staleChannelsPath)) {
|
|
7699
7779
|
try {
|
|
7700
|
-
|
|
7780
|
+
rmSync3(staleChannelsPath, { force: true });
|
|
7701
7781
|
} catch {
|
|
7702
7782
|
}
|
|
7703
7783
|
}
|
|
@@ -7759,7 +7839,7 @@ async function processAgent(agent, agentStates) {
|
|
|
7759
7839
|
}
|
|
7760
7840
|
if (process.env.AGT_CONNECTIVITY_PROBE_ENABLED === "true") {
|
|
7761
7841
|
try {
|
|
7762
|
-
const probeProjectDir =
|
|
7842
|
+
const probeProjectDir = join13(homedir7(), ".augmented", agent.code_name, "project");
|
|
7763
7843
|
await runAgentConnectivityProbes(agent, integrations, probeProjectDir);
|
|
7764
7844
|
} catch (err) {
|
|
7765
7845
|
log(`Connectivity probe failed for '${agent.code_name}': ${err.message}`);
|
|
@@ -7777,11 +7857,11 @@ async function processAgent(agent, agentStates) {
|
|
|
7777
7857
|
recordConfigChurnEvent(agent.agent_id, agent.code_name, FLAP_CHANNEL_INTEGRATIONS, intMembership);
|
|
7778
7858
|
}
|
|
7779
7859
|
if (intHash !== prevIntHash) {
|
|
7780
|
-
const projectDir =
|
|
7781
|
-
const envIntPath =
|
|
7860
|
+
const projectDir = join13(homedir7(), ".augmented", agent.code_name, "project");
|
|
7861
|
+
const envIntPath = join13(projectDir, ".env.integrations");
|
|
7782
7862
|
let preWriteEnv;
|
|
7783
7863
|
try {
|
|
7784
|
-
preWriteEnv =
|
|
7864
|
+
preWriteEnv = readFileSync11(envIntPath, "utf-8");
|
|
7785
7865
|
} catch {
|
|
7786
7866
|
preWriteEnv = void 0;
|
|
7787
7867
|
}
|
|
@@ -7793,9 +7873,9 @@ async function processAgent(agent, agentStates) {
|
|
|
7793
7873
|
let rotationHandled = true;
|
|
7794
7874
|
if (fw === "claude-code" && isSessionHealthy(agent.code_name)) {
|
|
7795
7875
|
try {
|
|
7796
|
-
const projectMcpPath =
|
|
7797
|
-
const postWriteEnv =
|
|
7798
|
-
const mcpContent =
|
|
7876
|
+
const projectMcpPath = join13(projectDir, ".mcp.json");
|
|
7877
|
+
const postWriteEnv = readFileSync11(envIntPath, "utf-8");
|
|
7878
|
+
const mcpContent = readFileSync11(projectMcpPath, "utf-8");
|
|
7799
7879
|
const changedVars = diffEnvIntegrations(preWriteEnv, postWriteEnv);
|
|
7800
7880
|
const mcpJsonForReap = JSON.parse(mcpContent);
|
|
7801
7881
|
const affectedServerKeys = findMcpServersUsingVars(mcpJsonForReap, changedVars);
|
|
@@ -7850,10 +7930,10 @@ async function processAgent(agent, agentStates) {
|
|
|
7850
7930
|
desiredEntries.push({ serverId, url, headers: mcpHeaders, name: tk.toolkit_name });
|
|
7851
7931
|
}
|
|
7852
7932
|
const hashBasis = desiredEntries.slice().sort((a, b) => a.serverId.localeCompare(b.serverId)).map((e) => {
|
|
7853
|
-
const headersHash =
|
|
7933
|
+
const headersHash = createHash4("sha256").update(canonicalJson(e.headers ?? {})).digest("hex").slice(0, 16);
|
|
7854
7934
|
return `${e.serverId}|${e.url}|${headersHash}`;
|
|
7855
7935
|
}).join("\n");
|
|
7856
|
-
const mcpHash =
|
|
7936
|
+
const mcpHash = createHash4("sha256").update(hashBasis).digest("hex").slice(0, 16);
|
|
7857
7937
|
const prevMcpHash = agentState.knownManagedMcpHashes.get(agent.agent_id);
|
|
7858
7938
|
const structureHash = managedMcpStructureHash(desiredEntries);
|
|
7859
7939
|
const prevStructureHash = agentState.knownManagedMcpStructure.get(agent.agent_id);
|
|
@@ -7868,15 +7948,15 @@ async function processAgent(agent, agentStates) {
|
|
|
7868
7948
|
if (mcpHash !== prevMcpHash) {
|
|
7869
7949
|
for (const e of desiredEntries) {
|
|
7870
7950
|
frameworkAdapter.writeMcpServer(agent.code_name, e.serverId, { url: e.url, headers: e.headers });
|
|
7871
|
-
const urlHash =
|
|
7951
|
+
const urlHash = createHash4("sha256").update(e.url).digest("hex").slice(0, 12);
|
|
7872
7952
|
log(`[managed-toolkit] ${agent.code_name}: wrote '${e.name}' (serverId=${e.serverId}, url_hash=${urlHash})`);
|
|
7873
7953
|
}
|
|
7874
7954
|
if (frameworkAdapter.removeMcpServer && frameworkAdapter.getMcpPath) {
|
|
7875
7955
|
const mcpPath = frameworkAdapter.getMcpPath(agent.code_name);
|
|
7876
7956
|
if (mcpPath) {
|
|
7877
7957
|
try {
|
|
7878
|
-
const { readFileSync:
|
|
7879
|
-
const mcpConfig = JSON.parse(
|
|
7958
|
+
const { readFileSync: readFileSync12 } = await import("fs");
|
|
7959
|
+
const mcpConfig = JSON.parse(readFileSync12(mcpPath, "utf-8"));
|
|
7880
7960
|
if (mcpConfig.mcpServers) {
|
|
7881
7961
|
const managedPrefixes = [
|
|
7882
7962
|
"composio_",
|
|
@@ -7977,8 +8057,8 @@ async function processAgent(agent, agentStates) {
|
|
|
7977
8057
|
if (agent.status === "active") {
|
|
7978
8058
|
if (frameworkAdapter.installPlugin) {
|
|
7979
8059
|
try {
|
|
7980
|
-
const pluginPath =
|
|
7981
|
-
if (
|
|
8060
|
+
const pluginPath = join13(process.cwd(), "packages", "openclaw-plugin-augmented", "src", "index.ts");
|
|
8061
|
+
if (existsSync7(pluginPath)) {
|
|
7982
8062
|
frameworkAdapter.installPlugin(agent.code_name, "augmented", pluginPath, {
|
|
7983
8063
|
agtHost: requireHost(),
|
|
7984
8064
|
agtApiKey: getApiKey() ?? void 0,
|
|
@@ -8002,7 +8082,7 @@ async function processAgent(agent, agentStates) {
|
|
|
8002
8082
|
if (frameworkAdapter.installSkillFiles) {
|
|
8003
8083
|
const currentIntegrationSkillIds = /* @__PURE__ */ new Set();
|
|
8004
8084
|
const installedIntegrationSkills = [];
|
|
8005
|
-
const { createHash:
|
|
8085
|
+
const { createHash: createHash5 } = await import("crypto");
|
|
8006
8086
|
const refreshAny = refreshData;
|
|
8007
8087
|
const contexts = refreshAny.integration_contexts ?? refreshAny.plugin_contexts ?? [];
|
|
8008
8088
|
const contextBySlug = /* @__PURE__ */ new Map();
|
|
@@ -8031,7 +8111,7 @@ async function processAgent(agent, agentStates) {
|
|
|
8031
8111
|
)
|
|
8032
8112
|
}));
|
|
8033
8113
|
const bundle = buildIntegrationBundle(renderedScopes);
|
|
8034
|
-
const contentHash =
|
|
8114
|
+
const contentHash = createHash5("sha256").update(bundleFingerprint(bundle.files)).digest("hex").slice(0, 12);
|
|
8035
8115
|
const hashKey = `plugin-skill:${agent.agent_id}:${integrationSkillId}`;
|
|
8036
8116
|
if (agentState.knownSkillHashes.get(hashKey) === contentHash) continue;
|
|
8037
8117
|
frameworkAdapter.installSkillFiles(agent.code_name, integrationSkillId, bundle.files);
|
|
@@ -8043,21 +8123,21 @@ async function processAgent(agent, agentStates) {
|
|
|
8043
8123
|
}
|
|
8044
8124
|
}
|
|
8045
8125
|
try {
|
|
8046
|
-
const { readdirSync: readdirSync6, rmSync:
|
|
8047
|
-
const { homedir:
|
|
8126
|
+
const { readdirSync: readdirSync6, rmSync: rmSync4 } = await import("fs");
|
|
8127
|
+
const { homedir: homedir8 } = await import("os");
|
|
8048
8128
|
const frameworkId2 = frameworkAdapter.id;
|
|
8049
8129
|
const candidateSkillDirs = [
|
|
8050
8130
|
// Claude Code — framework runtime tree
|
|
8051
|
-
|
|
8131
|
+
join13(homedir8(), ".augmented", agent.code_name, "skills"),
|
|
8052
8132
|
// Claude Code — project tree
|
|
8053
|
-
|
|
8133
|
+
join13(homedir8(), ".augmented", agent.code_name, "project", ".claude", "skills"),
|
|
8054
8134
|
// OpenClaw — framework runtime tree
|
|
8055
|
-
|
|
8135
|
+
join13(homedir8(), `.openclaw-${agent.code_name}`, "skills"),
|
|
8056
8136
|
// Defensive: legacy provision-side path, not currently an
|
|
8057
8137
|
// install target but cheap to sweep.
|
|
8058
|
-
|
|
8138
|
+
join13(agentDir, ".claude", "skills")
|
|
8059
8139
|
];
|
|
8060
|
-
const existingDirs = candidateSkillDirs.filter((d) =>
|
|
8140
|
+
const existingDirs = candidateSkillDirs.filter((d) => existsSync7(d));
|
|
8061
8141
|
const discoveredEntries = /* @__PURE__ */ new Set();
|
|
8062
8142
|
for (const dir of existingDirs) {
|
|
8063
8143
|
try {
|
|
@@ -8071,9 +8151,9 @@ async function processAgent(agent, agentStates) {
|
|
|
8071
8151
|
}
|
|
8072
8152
|
const removeSkillFolder = (entry, reason) => {
|
|
8073
8153
|
for (const dir of existingDirs) {
|
|
8074
|
-
const p =
|
|
8075
|
-
if (
|
|
8076
|
-
|
|
8154
|
+
const p = join13(dir, entry);
|
|
8155
|
+
if (existsSync7(p)) {
|
|
8156
|
+
rmSync4(p, { recursive: true, force: true });
|
|
8077
8157
|
}
|
|
8078
8158
|
}
|
|
8079
8159
|
log(`Removed ${reason} '${entry}' for '${agent.code_name}' (framework=${frameworkId2})`);
|
|
@@ -8090,7 +8170,7 @@ async function processAgent(agent, agentStates) {
|
|
|
8090
8170
|
const plan = planGlobalSkillSync(
|
|
8091
8171
|
refreshAny.global_skills ?? [],
|
|
8092
8172
|
agentState.knownGlobalSkillIds.get(agent.agent_id) ?? /* @__PURE__ */ new Set(),
|
|
8093
|
-
(content) =>
|
|
8173
|
+
(content) => createHash5("sha256").update(content).digest("hex").slice(0, 12),
|
|
8094
8174
|
(skillId) => agentState.knownSkillHashes.get(`global-skill:${agent.agent_id}:${skillId}`)
|
|
8095
8175
|
);
|
|
8096
8176
|
for (const { skillId, content, hash } of plan.installs) {
|
|
@@ -8099,18 +8179,18 @@ async function processAgent(agent, agentStates) {
|
|
|
8099
8179
|
log(`Installed global skill '${skillId}' for '${agent.code_name}'`);
|
|
8100
8180
|
}
|
|
8101
8181
|
if (plan.removes.length) {
|
|
8102
|
-
const { rmSync:
|
|
8103
|
-
const { homedir:
|
|
8182
|
+
const { rmSync: rmSync4 } = await import("fs");
|
|
8183
|
+
const { homedir: homedir8 } = await import("os");
|
|
8104
8184
|
const globalSkillDirs = [
|
|
8105
|
-
|
|
8106
|
-
|
|
8107
|
-
|
|
8108
|
-
|
|
8185
|
+
join13(homedir8(), ".augmented", agent.code_name, "skills"),
|
|
8186
|
+
join13(homedir8(), ".augmented", agent.code_name, "project", ".claude", "skills"),
|
|
8187
|
+
join13(homedir8(), `.openclaw-${agent.code_name}`, "skills"),
|
|
8188
|
+
join13(agentDir, ".claude", "skills")
|
|
8109
8189
|
];
|
|
8110
8190
|
for (const id of plan.removes) {
|
|
8111
8191
|
for (const dir of globalSkillDirs) {
|
|
8112
|
-
const p =
|
|
8113
|
-
if (
|
|
8192
|
+
const p = join13(dir, id);
|
|
8193
|
+
if (existsSync7(p)) rmSync4(p, { recursive: true, force: true });
|
|
8114
8194
|
}
|
|
8115
8195
|
agentState.knownSkillHashes.delete(`global-skill:${agent.agent_id}:${id}`);
|
|
8116
8196
|
log(`Removed unpublished global skill '${id}' for '${agent.code_name}'`);
|
|
@@ -8134,7 +8214,7 @@ async function processAgent(agent, agentStates) {
|
|
|
8134
8214
|
const slug = hook.integration_slug ?? hook.plugin_slug;
|
|
8135
8215
|
if (!slug) continue;
|
|
8136
8216
|
try {
|
|
8137
|
-
const scriptHash =
|
|
8217
|
+
const scriptHash = createHash5("sha256").update(hook.script).digest("hex").slice(0, 12);
|
|
8138
8218
|
const hookKey = `${agent.agent_id}:${frameworkAdapter.id}:plugin-hook:${slug}:on_install`;
|
|
8139
8219
|
if (agentState.knownSkillHashes.get(hookKey) === scriptHash) continue;
|
|
8140
8220
|
const result = await frameworkAdapter.executePluginHook({
|
|
@@ -8149,9 +8229,9 @@ async function processAgent(agent, agentStates) {
|
|
|
8149
8229
|
} else if (result.timedOut) {
|
|
8150
8230
|
log(`Integration hook on_install '${slug}' TIMED OUT for '${agent.code_name}' after ${result.durationMs}ms`);
|
|
8151
8231
|
} else {
|
|
8152
|
-
const stderrHash =
|
|
8232
|
+
const stderrHash = createHash5("sha256").update(result.stderr).digest("hex").slice(0, 12);
|
|
8153
8233
|
const missingCmd = result.exitCode === 127 ? extractCommandNotFound(result.stderr) : null;
|
|
8154
|
-
const missingCmdHash = missingCmd ?
|
|
8234
|
+
const missingCmdHash = missingCmd ? createHash5("sha256").update(missingCmd).digest("hex").slice(0, 8) : null;
|
|
8155
8235
|
log(
|
|
8156
8236
|
`Integration hook on_install '${slug}' exited ${result.exitCode} for '${agent.code_name}' ` + (missingCmdHash ? `[missing_command_hash=${missingCmdHash}] ` : "") + `[stderr_hash=${stderrHash} stderr_len=${result.stderr.length}]`
|
|
8157
8237
|
);
|
|
@@ -8285,8 +8365,8 @@ async function processAgent(agent, agentStates) {
|
|
|
8285
8365
|
const sess = getSessionState(agent.code_name);
|
|
8286
8366
|
let mcpJsonParsed = null;
|
|
8287
8367
|
try {
|
|
8288
|
-
const mcpPath =
|
|
8289
|
-
mcpJsonParsed = JSON.parse(
|
|
8368
|
+
const mcpPath = join13(getProjectDir(agent.code_name), ".mcp.json");
|
|
8369
|
+
mcpJsonParsed = JSON.parse(readFileSync11(mcpPath, "utf-8"));
|
|
8290
8370
|
} catch {
|
|
8291
8371
|
}
|
|
8292
8372
|
reapMissingMcpSessions({
|
|
@@ -8420,10 +8500,10 @@ async function processAgent(agent, agentStates) {
|
|
|
8420
8500
|
} else if (agentFw === "claude-code" && tasks.length > 0) {
|
|
8421
8501
|
await syncAndCheckClaudeScheduler(agent, tasks, boardItems, refreshData);
|
|
8422
8502
|
} else if (frameworkAdapter.syncScheduledTasks && gatewayRunning && gatewayPort) {
|
|
8423
|
-
const stableTasksHash =
|
|
8424
|
-
const boardHash = boardItems.length > 0 ?
|
|
8503
|
+
const stableTasksHash = createHash4("sha256").update(JSON.stringify(tasks)).digest("hex").slice(0, 16);
|
|
8504
|
+
const boardHash = boardItems.length > 0 ? createHash4("sha256").update(JSON.stringify(boardItems.map((b) => ({ id: b.id, title: b.title, status: b.status, priority: b.priority, deliverable: b.deliverable })))).digest("hex").slice(0, 16) : "empty";
|
|
8425
8505
|
const resolvedModels = resolveModelChain(refreshData);
|
|
8426
|
-
const modelsHash =
|
|
8506
|
+
const modelsHash = createHash4("sha256").update(JSON.stringify(resolvedModels)).digest("hex").slice(0, 16);
|
|
8427
8507
|
const combinedHash = `${stableTasksHash}:${boardHash}:${modelsHash}`;
|
|
8428
8508
|
const prevTasksHash = agentState.knownTasksHashes.get(agent.agent_id);
|
|
8429
8509
|
if (combinedHash !== prevTasksHash) {
|
|
@@ -8495,10 +8575,10 @@ async function processAgent(agent, agentStates) {
|
|
|
8495
8575
|
lastWorkTriggerAt.set(agent.code_name, triggerTs);
|
|
8496
8576
|
if (agentFw === "openclaw" && gatewayRunning && gatewayPort) {
|
|
8497
8577
|
const homeDir = process.env["HOME"] ?? "/tmp";
|
|
8498
|
-
const jobsPath =
|
|
8499
|
-
if (
|
|
8578
|
+
const jobsPath = join13(homeDir, `.openclaw-${agent.code_name}`, "cron", "jobs.json");
|
|
8579
|
+
if (existsSync7(jobsPath)) {
|
|
8500
8580
|
try {
|
|
8501
|
-
const jobsData = JSON.parse(
|
|
8581
|
+
const jobsData = JSON.parse(readFileSync11(jobsPath, "utf-8"));
|
|
8502
8582
|
const kanbanJob = (jobsData.jobs ?? []).find(
|
|
8503
8583
|
(j) => typeof j.name === "string" && j.name.includes("kanban-work")
|
|
8504
8584
|
);
|
|
@@ -8632,10 +8712,10 @@ In progress for ${age} minutes \u2014 auto-failed`).catch(() => {
|
|
|
8632
8712
|
}
|
|
8633
8713
|
}
|
|
8634
8714
|
const trackedFiles = frameworkAdapter.driftTrackedFiles();
|
|
8635
|
-
if (trackedFiles.length > 0 &&
|
|
8715
|
+
if (trackedFiles.length > 0 && existsSync7(agentDir)) {
|
|
8636
8716
|
const hashes = /* @__PURE__ */ new Map();
|
|
8637
8717
|
for (const file of trackedFiles) {
|
|
8638
|
-
const h = hashFile(
|
|
8718
|
+
const h = hashFile(join13(agentDir, file));
|
|
8639
8719
|
if (h) hashes.set(file, h);
|
|
8640
8720
|
}
|
|
8641
8721
|
agentState.writtenHashes.set(agent.agent_id, hashes);
|
|
@@ -8669,19 +8749,19 @@ function cleanupStaleSessions(codeName) {
|
|
|
8669
8749
|
lastCleanupAt.set(codeName, Date.now());
|
|
8670
8750
|
const homeDir = process.env["HOME"] ?? "/tmp";
|
|
8671
8751
|
for (const agentDir of ["main", codeName]) {
|
|
8672
|
-
const sessionsDir =
|
|
8752
|
+
const sessionsDir = join13(homeDir, `.openclaw-${codeName}`, "agents", agentDir, "sessions");
|
|
8673
8753
|
cleanupCronSessions(sessionsDir, CRON_SESSION_KEEP_COUNT);
|
|
8674
8754
|
}
|
|
8675
|
-
const cronRunsDir =
|
|
8755
|
+
const cronRunsDir = join13(homeDir, `.openclaw-${codeName}`, "cron", "runs");
|
|
8676
8756
|
cleanupOldFiles(cronRunsDir, CRON_RUN_RETENTION_DAYS, ".jsonl");
|
|
8677
|
-
const cronJobsPath =
|
|
8757
|
+
const cronJobsPath = join13(homeDir, `.openclaw-${codeName}`, "cron", "jobs.json");
|
|
8678
8758
|
clearStaleCronRunState(cronJobsPath);
|
|
8679
8759
|
}
|
|
8680
8760
|
function cleanupCronSessions(sessionsDir, keepCount) {
|
|
8681
|
-
const indexPath =
|
|
8682
|
-
if (!
|
|
8761
|
+
const indexPath = join13(sessionsDir, "sessions.json");
|
|
8762
|
+
if (!existsSync7(indexPath)) return;
|
|
8683
8763
|
try {
|
|
8684
|
-
const raw =
|
|
8764
|
+
const raw = readFileSync11(indexPath, "utf-8");
|
|
8685
8765
|
const index = JSON.parse(raw);
|
|
8686
8766
|
const cronRunKeys = Object.keys(index).filter((k) => k.includes(":cron:") && k.includes(":run:")).map((k) => ({
|
|
8687
8767
|
key: k,
|
|
@@ -8694,9 +8774,9 @@ function cleanupCronSessions(sessionsDir, keepCount) {
|
|
|
8694
8774
|
for (const entry of toDelete) {
|
|
8695
8775
|
delete index[entry.key];
|
|
8696
8776
|
if (entry.sessionId) {
|
|
8697
|
-
const sessionFile =
|
|
8777
|
+
const sessionFile = join13(sessionsDir, `${entry.sessionId}.jsonl`);
|
|
8698
8778
|
try {
|
|
8699
|
-
if (
|
|
8779
|
+
if (existsSync7(sessionFile)) {
|
|
8700
8780
|
unlinkSync(sessionFile);
|
|
8701
8781
|
deletedFiles++;
|
|
8702
8782
|
}
|
|
@@ -8716,8 +8796,8 @@ function cleanupCronSessions(sessionsDir, keepCount) {
|
|
|
8716
8796
|
delete index[parentKey];
|
|
8717
8797
|
if (parentSessionId) {
|
|
8718
8798
|
try {
|
|
8719
|
-
const f =
|
|
8720
|
-
if (
|
|
8799
|
+
const f = join13(sessionsDir, `${parentSessionId}.jsonl`);
|
|
8800
|
+
if (existsSync7(f)) {
|
|
8721
8801
|
unlinkSync(f);
|
|
8722
8802
|
deletedFiles++;
|
|
8723
8803
|
}
|
|
@@ -8735,9 +8815,9 @@ function cleanupCronSessions(sessionsDir, keepCount) {
|
|
|
8735
8815
|
}
|
|
8736
8816
|
var STALE_RUN_TIMEOUT_MS = 5 * 6e4;
|
|
8737
8817
|
function clearStaleCronRunState(jobsPath) {
|
|
8738
|
-
if (!
|
|
8818
|
+
if (!existsSync7(jobsPath)) return;
|
|
8739
8819
|
try {
|
|
8740
|
-
const raw =
|
|
8820
|
+
const raw = readFileSync11(jobsPath, "utf-8");
|
|
8741
8821
|
const data = JSON.parse(raw);
|
|
8742
8822
|
const jobs = data.jobs ?? data;
|
|
8743
8823
|
if (!Array.isArray(jobs)) return;
|
|
@@ -8768,13 +8848,13 @@ function clearStaleCronRunState(jobsPath) {
|
|
|
8768
8848
|
}
|
|
8769
8849
|
}
|
|
8770
8850
|
function cleanupOldFiles(dir, maxAgeDays, ext) {
|
|
8771
|
-
if (!
|
|
8851
|
+
if (!existsSync7(dir)) return;
|
|
8772
8852
|
const cutoff = Date.now() - maxAgeDays * 24 * 60 * 60 * 1e3;
|
|
8773
8853
|
let removed = 0;
|
|
8774
8854
|
try {
|
|
8775
8855
|
for (const f of readdirSync5(dir)) {
|
|
8776
8856
|
if (!f.endsWith(ext)) continue;
|
|
8777
|
-
const fullPath =
|
|
8857
|
+
const fullPath = join13(dir, f);
|
|
8778
8858
|
try {
|
|
8779
8859
|
const st = statSync4(fullPath);
|
|
8780
8860
|
if (st.mtimeMs < cutoff) {
|
|
@@ -8814,7 +8894,7 @@ var inFlightClaudeTasks = /* @__PURE__ */ new Set();
|
|
|
8814
8894
|
var claudeTaskConcurrency = /* @__PURE__ */ new Map();
|
|
8815
8895
|
var MAX_CLAUDE_CONCURRENCY = 2;
|
|
8816
8896
|
function claudePidFilePath() {
|
|
8817
|
-
return
|
|
8897
|
+
return join13(homedir7(), ".augmented", "manager-claude-pids.json");
|
|
8818
8898
|
}
|
|
8819
8899
|
var inFlightClaudePids = /* @__PURE__ */ new Map();
|
|
8820
8900
|
function registerClaudeSpawn(record) {
|
|
@@ -8835,10 +8915,10 @@ function unregisterClaudeSpawn(pid) {
|
|
|
8835
8915
|
var claudeSchedulerStates = /* @__PURE__ */ new Map();
|
|
8836
8916
|
async function syncAndCheckClaudeScheduler(agent, tasks, boardItems, refreshData) {
|
|
8837
8917
|
const codeName = agent.code_name;
|
|
8838
|
-
const stableTasksHash =
|
|
8839
|
-
const boardHash = boardItems.length > 0 ?
|
|
8918
|
+
const stableTasksHash = createHash4("sha256").update(JSON.stringify(tasks)).digest("hex").slice(0, 16);
|
|
8919
|
+
const boardHash = boardItems.length > 0 ? createHash4("sha256").update(JSON.stringify(boardItems.map((b) => ({ id: b.id, title: b.title, status: b.status, priority: b.priority, deliverable: b.deliverable })))).digest("hex").slice(0, 16) : "empty";
|
|
8840
8920
|
const resolvedModels = resolveModelChain(refreshData);
|
|
8841
|
-
const modelsHash =
|
|
8921
|
+
const modelsHash = createHash4("sha256").update(JSON.stringify(resolvedModels)).digest("hex").slice(0, 16);
|
|
8842
8922
|
const combinedHash = `${stableTasksHash}:${boardHash}:${modelsHash}`;
|
|
8843
8923
|
const prevHash = agentState.knownTasksHashes.get(agent.agent_id);
|
|
8844
8924
|
if (combinedHash !== prevHash) {
|
|
@@ -8904,7 +8984,7 @@ async function startRun(opts) {
|
|
|
8904
8984
|
return { run_id: res.run_id ?? null, kanban_item_id: res.kanban_item_id ?? null };
|
|
8905
8985
|
} catch (err) {
|
|
8906
8986
|
const errText = err instanceof Error ? err.message : String(err);
|
|
8907
|
-
const errId =
|
|
8987
|
+
const errId = createHash4("sha256").update(errText).digest("hex").slice(0, 12);
|
|
8908
8988
|
log(`[runs] start failed for agent_id=${opts.agent_id} source_type=${opts.source_type} error_id=${errId}`);
|
|
8909
8989
|
return { run_id: null, kanban_item_id: null };
|
|
8910
8990
|
}
|
|
@@ -8921,7 +9001,7 @@ async function finishRun(runId, outcome, options = {}) {
|
|
|
8921
9001
|
});
|
|
8922
9002
|
} catch (err) {
|
|
8923
9003
|
const errText = err instanceof Error ? err.message : String(err);
|
|
8924
|
-
const errId =
|
|
9004
|
+
const errId = createHash4("sha256").update(errText).digest("hex").slice(0, 12);
|
|
8925
9005
|
log(`[runs] finish failed for run_id=${runId} outcome=${outcome} error_id=${errId}`);
|
|
8926
9006
|
}
|
|
8927
9007
|
}
|
|
@@ -8938,7 +9018,7 @@ async function fetchPriorScheduledRuns(agentId, taskId) {
|
|
|
8938
9018
|
return rows.filter((r) => typeof r.output_text === "string" && r.output_text.length > 0).map((r) => ({ startedAt: r.started_at, output: r.output_text }));
|
|
8939
9019
|
} catch (err) {
|
|
8940
9020
|
const errText = err instanceof Error ? err.message : String(err);
|
|
8941
|
-
const errId =
|
|
9021
|
+
const errId = createHash4("sha256").update(errText).digest("hex").slice(0, 12);
|
|
8942
9022
|
log(`[runs] prior-runs lookup failed for task_id=${taskId} error_id=${errId}`);
|
|
8943
9023
|
return [];
|
|
8944
9024
|
}
|
|
@@ -9154,7 +9234,7 @@ async function fireScheduledTaskViaKanban(codeName, agentId, task, prompt) {
|
|
|
9154
9234
|
}
|
|
9155
9235
|
async function executeAndProcessClaudeTask(codeName, agentId, task, prompt) {
|
|
9156
9236
|
const projectDir = getProjectDir2(codeName);
|
|
9157
|
-
const mcpConfigPath =
|
|
9237
|
+
const mcpConfigPath = join13(projectDir, ".mcp.json");
|
|
9158
9238
|
let runId = null;
|
|
9159
9239
|
let kanbanItemId = null;
|
|
9160
9240
|
let taskResult;
|
|
@@ -9162,11 +9242,11 @@ async function executeAndProcessClaudeTask(codeName, agentId, task, prompt) {
|
|
|
9162
9242
|
const priorRuns = await fetchPriorScheduledRuns(agentId, task.taskId);
|
|
9163
9243
|
prompt = wrapScheduledTaskPrompt(prompt, { priorRuns });
|
|
9164
9244
|
try {
|
|
9165
|
-
const claudeMdPath =
|
|
9245
|
+
const claudeMdPath = join13(projectDir, "CLAUDE.md");
|
|
9166
9246
|
const serverNames = [];
|
|
9167
|
-
if (
|
|
9247
|
+
if (existsSync7(mcpConfigPath)) {
|
|
9168
9248
|
try {
|
|
9169
|
-
const d = JSON.parse(
|
|
9249
|
+
const d = JSON.parse(readFileSync11(mcpConfigPath, "utf-8"));
|
|
9170
9250
|
if (d.mcpServers) serverNames.push(...Object.keys(d.mcpServers));
|
|
9171
9251
|
} catch {
|
|
9172
9252
|
}
|
|
@@ -9185,14 +9265,14 @@ async function executeAndProcessClaudeTask(codeName, agentId, task, prompt) {
|
|
|
9185
9265
|
"--allowedTools",
|
|
9186
9266
|
allowedTools
|
|
9187
9267
|
];
|
|
9188
|
-
if (
|
|
9268
|
+
if (existsSync7(claudeMdPath)) {
|
|
9189
9269
|
claudeArgs.push("--system-prompt-file", claudeMdPath);
|
|
9190
9270
|
}
|
|
9191
9271
|
const childEnv = { ...process.env };
|
|
9192
|
-
const envIntPath =
|
|
9193
|
-
if (
|
|
9272
|
+
const envIntPath = join13(projectDir, ".env.integrations");
|
|
9273
|
+
if (existsSync7(envIntPath)) {
|
|
9194
9274
|
try {
|
|
9195
|
-
Object.assign(childEnv, parseEnvIntegrations(
|
|
9275
|
+
Object.assign(childEnv, parseEnvIntegrations(readFileSync11(envIntPath, "utf-8")));
|
|
9196
9276
|
} catch {
|
|
9197
9277
|
}
|
|
9198
9278
|
}
|
|
@@ -9294,10 +9374,10 @@ async function processClaudeTaskResult(codeName, agentId, templateId, rawOutput,
|
|
|
9294
9374
|
const classification = classifyOutput(rawOutput);
|
|
9295
9375
|
if (classification.action === "suppress") {
|
|
9296
9376
|
const trimmed = (rawOutput ?? "").trim();
|
|
9297
|
-
const outputHash = trimmed.length === 0 ? "empty" :
|
|
9377
|
+
const outputHash = trimmed.length === 0 ? "empty" : createHash4("sha256").update(trimmed).digest("hex").slice(0, 12);
|
|
9298
9378
|
log(`[claude-scheduler] Suppressing delivery for '${codeName}' (template=${templateId}, task=${delivery?.taskId ?? "n/a"}) \u2014 output_len=${trimmed.length} output_hash=${outputHash}`);
|
|
9299
9379
|
if (classification.suppressedNotes) {
|
|
9300
|
-
const notesHash =
|
|
9380
|
+
const notesHash = createHash4("sha256").update(classification.suppressedNotes).digest("hex").slice(0, 12);
|
|
9301
9381
|
log(`[claude-scheduler] Suppressed notes for '${codeName}' (task=${delivery?.taskId ?? "n/a"}) \u2014 notes_len=${classification.suppressedNotes.length} notes_hash=${notesHash}`);
|
|
9302
9382
|
}
|
|
9303
9383
|
if (delivery?.mode === "announce" && delivery.to) {
|
|
@@ -9364,8 +9444,8 @@ var claudeAuthTupleBySession = /* @__PURE__ */ new Map();
|
|
|
9364
9444
|
async function ensurePersistentSession(agent, tasks, boardItems, refreshData) {
|
|
9365
9445
|
const codeName = agent.code_name;
|
|
9366
9446
|
const projectDir = getProjectDir(codeName);
|
|
9367
|
-
const mcpConfigPath =
|
|
9368
|
-
const claudeMdPath =
|
|
9447
|
+
const mcpConfigPath = join13(projectDir, ".mcp.json");
|
|
9448
|
+
const claudeMdPath = join13(projectDir, "CLAUDE.md");
|
|
9369
9449
|
if (restartBreaker.isTripped(codeName)) {
|
|
9370
9450
|
const trip = restartBreaker.getTrip(codeName);
|
|
9371
9451
|
return {
|
|
@@ -9482,7 +9562,7 @@ async function ensurePersistentSession(agent, tasks, boardItems, refreshData) {
|
|
|
9482
9562
|
const ctx = getLastFailureContext(codeName);
|
|
9483
9563
|
const recovery = prepareForRespawn(codeName);
|
|
9484
9564
|
const tailSummary = !ctx.tail ? "" : KNOWN_SAFE_TAIL_SIGNATURES.has(ctx.signature) ? `; last pane output (${PANE_TAIL_PREVIEW_LINES} of ~20 lines):
|
|
9485
|
-
${truncateForLog(ctx.tail)}` : `; pane_tail_hash=sha256:${
|
|
9565
|
+
${truncateForLog(ctx.tail)}` : `; pane_tail_hash=sha256:${createHash4("sha256").update(ctx.tail).digest("hex").slice(0, 12)} (raw at ~/.augmented/${codeName}/pane.log)`;
|
|
9486
9566
|
const sigSummary = ctx.signature !== "unknown" ? `; signature=${ctx.signature}` : "";
|
|
9487
9567
|
const recoverySummary = recovery ? `; recovery=${recovery}` : "";
|
|
9488
9568
|
log(
|
|
@@ -9496,7 +9576,7 @@ ${truncateForLog(ctx.tail)}` : `; pane_tail_hash=sha256:${createHash3("sha256").
|
|
|
9496
9576
|
);
|
|
9497
9577
|
getHostId().then((hostId) => {
|
|
9498
9578
|
if (!hostId) return;
|
|
9499
|
-
const paneTailHash = zombie.paneTail ? `sha256:${
|
|
9579
|
+
const paneTailHash = zombie.paneTail ? `sha256:${createHash4("sha256").update(zombie.paneTail).digest("hex").slice(0, 12)}` : null;
|
|
9500
9580
|
return api.post("/host/events", {
|
|
9501
9581
|
host_id: hostId,
|
|
9502
9582
|
agent_code_name: codeName,
|
|
@@ -9575,7 +9655,7 @@ ${truncateForLog(ctx.tail)}` : `; pane_tail_hash=sha256:${createHash3("sha256").
|
|
|
9575
9655
|
if (!claudeAuthTupleBySession.has(codeName)) {
|
|
9576
9656
|
claudeAuthTupleBySession.set(codeName, currentAuthTuple);
|
|
9577
9657
|
}
|
|
9578
|
-
const stableTasksHash =
|
|
9658
|
+
const stableTasksHash = createHash4("sha256").update(JSON.stringify(tasks)).digest("hex").slice(0, 16);
|
|
9579
9659
|
const prevHash = agentState.knownTasksHashes.get(agent.agent_id);
|
|
9580
9660
|
if (stableTasksHash !== prevHash) {
|
|
9581
9661
|
const taskInputs = tasks.map((t) => buildSchedulerTaskInput(t));
|
|
@@ -9964,8 +10044,8 @@ async function processDirectChatMessage(agent, msg) {
|
|
|
9964
10044
|
if (isSessionHealthy(agent.codeName)) {
|
|
9965
10045
|
if (hostFlagStore().getBoolean("direct-chat-doorbell")) {
|
|
9966
10046
|
try {
|
|
9967
|
-
const doorbell = directChatDoorbellPath(agent.agentId,
|
|
9968
|
-
|
|
10047
|
+
const doorbell = directChatDoorbellPath(agent.agentId, homedir7());
|
|
10048
|
+
mkdirSync4(dirname3(doorbell), { recursive: true });
|
|
9969
10049
|
writeFileSync4(doorbell, String(Date.now()));
|
|
9970
10050
|
log(`[direct-chat] Doorbell rung for '${agent.codeName}' (msg=${msg.id}) \u2014 in-session MCP will pull via the cursor`);
|
|
9971
10051
|
return;
|
|
@@ -10010,11 +10090,11 @@ ${escapeXml(msg.content)}
|
|
|
10010
10090
|
log(`[direct-chat] One-shot spawn for '${agent.codeName}' (msg=${msg.id}; host in-flight=${directChatSpawnGate.hostInFlight}, queued=${directChatSpawnGate.queuedCount})`);
|
|
10011
10091
|
const { getProjectDir: ccProjectDir } = await import("../claude-scheduler-FATCLHDM.js");
|
|
10012
10092
|
const projDir = ccProjectDir(agent.codeName);
|
|
10013
|
-
const mcpConfigPath =
|
|
10093
|
+
const mcpConfigPath = join13(projDir, ".mcp.json");
|
|
10014
10094
|
const serverNames = [];
|
|
10015
|
-
if (
|
|
10095
|
+
if (existsSync7(mcpConfigPath)) {
|
|
10016
10096
|
try {
|
|
10017
|
-
const d = JSON.parse(
|
|
10097
|
+
const d = JSON.parse(readFileSync11(mcpConfigPath, "utf-8"));
|
|
10018
10098
|
if (d.mcpServers) serverNames.push(...Object.keys(d.mcpServers));
|
|
10019
10099
|
} catch {
|
|
10020
10100
|
}
|
|
@@ -10033,15 +10113,15 @@ ${escapeXml(msg.content)}
|
|
|
10033
10113
|
"--allowedTools",
|
|
10034
10114
|
allowedTools
|
|
10035
10115
|
];
|
|
10036
|
-
const chatClaudeMd =
|
|
10037
|
-
if (
|
|
10116
|
+
const chatClaudeMd = join13(projDir, "CLAUDE.md");
|
|
10117
|
+
if (existsSync7(chatClaudeMd)) {
|
|
10038
10118
|
chatArgs.push("--system-prompt-file", chatClaudeMd);
|
|
10039
10119
|
}
|
|
10040
|
-
const envIntPath =
|
|
10120
|
+
const envIntPath = join13(projDir, ".env.integrations");
|
|
10041
10121
|
const childEnv = { ...process.env };
|
|
10042
|
-
if (
|
|
10122
|
+
if (existsSync7(envIntPath)) {
|
|
10043
10123
|
try {
|
|
10044
|
-
Object.assign(childEnv, parseEnvIntegrations(
|
|
10124
|
+
Object.assign(childEnv, parseEnvIntegrations(readFileSync11(envIntPath, "utf-8")));
|
|
10045
10125
|
} catch {
|
|
10046
10126
|
}
|
|
10047
10127
|
}
|
|
@@ -10101,7 +10181,7 @@ ${escapeXml(msg.content)}
|
|
|
10101
10181
|
log(`[direct-chat] Reply sent for '${agent.codeName}'`);
|
|
10102
10182
|
} catch (err) {
|
|
10103
10183
|
const errMsg = err instanceof Error ? err.message : String(err);
|
|
10104
|
-
const errorId =
|
|
10184
|
+
const errorId = createHash4("sha256").update(errMsg).digest("hex").slice(0, 12);
|
|
10105
10185
|
log(`[direct-chat] Failed to process message for '${agent.codeName}': error_id=${errorId} error=${errMsg.slice(0, 500)}`);
|
|
10106
10186
|
try {
|
|
10107
10187
|
await api.post("/host/direct-chat/reply", {
|
|
@@ -10419,12 +10499,12 @@ function getBuiltInSkillContent(skillId) {
|
|
|
10419
10499
|
if (builtInSkillCache.has(skillId)) return builtInSkillCache.get(skillId);
|
|
10420
10500
|
try {
|
|
10421
10501
|
const candidates = [
|
|
10422
|
-
|
|
10423
|
-
|
|
10502
|
+
join13(process.cwd(), "skills", skillId, "SKILL.md"),
|
|
10503
|
+
join13(new URL(".", import.meta.url).pathname, "..", "..", "..", "..", "skills", skillId, "SKILL.md")
|
|
10424
10504
|
];
|
|
10425
10505
|
for (const candidate of candidates) {
|
|
10426
|
-
if (
|
|
10427
|
-
const content =
|
|
10506
|
+
if (existsSync7(candidate)) {
|
|
10507
|
+
const content = readFileSync11(candidate, "utf-8");
|
|
10428
10508
|
const files = [{ relativePath: "SKILL.md", content }];
|
|
10429
10509
|
builtInSkillCache.set(skillId, files);
|
|
10430
10510
|
return files;
|
|
@@ -10563,73 +10643,6 @@ function formatBoardForPrompt(items, template) {
|
|
|
10563
10643
|
}
|
|
10564
10644
|
return lines.join("\n");
|
|
10565
10645
|
}
|
|
10566
|
-
async function execFilePromise(cmd, args) {
|
|
10567
|
-
const { execFile: ef } = await import("child_process");
|
|
10568
|
-
return new Promise((resolve, reject) => {
|
|
10569
|
-
ef(cmd, args, { timeout: 15e3 }, (err, stdout, stderr) => {
|
|
10570
|
-
if (err) reject(err);
|
|
10571
|
-
else resolve({ stdout, stderr });
|
|
10572
|
-
});
|
|
10573
|
-
});
|
|
10574
|
-
}
|
|
10575
|
-
var ChildProcessError = class extends Error {
|
|
10576
|
-
code;
|
|
10577
|
-
stdout;
|
|
10578
|
-
stderr;
|
|
10579
|
-
constructor(code, stdout, stderr) {
|
|
10580
|
-
const stderrSnippet = stderr.trim().slice(0, 500);
|
|
10581
|
-
const stdoutSnippet = stdout.trim().slice(0, 500);
|
|
10582
|
-
const detail = stderrSnippet || stdoutSnippet || "(no output)";
|
|
10583
|
-
super(`Exit code ${code}: ${detail}`);
|
|
10584
|
-
this.name = "ChildProcessError";
|
|
10585
|
-
this.code = code;
|
|
10586
|
-
this.stdout = stdout;
|
|
10587
|
-
this.stderr = stderr;
|
|
10588
|
-
}
|
|
10589
|
-
};
|
|
10590
|
-
async function execFilePromiseLong(cmd, args, opts) {
|
|
10591
|
-
const { spawn: sp } = await import("child_process");
|
|
10592
|
-
return new Promise((resolve, reject) => {
|
|
10593
|
-
const child = sp(cmd, args, {
|
|
10594
|
-
cwd: opts?.cwd,
|
|
10595
|
-
stdio: [opts?.stdin === "ignore" ? "ignore" : "pipe", "pipe", "pipe"],
|
|
10596
|
-
...opts?.env ? { env: opts.env } : {}
|
|
10597
|
-
});
|
|
10598
|
-
if (opts?.onSpawn && typeof child.pid === "number") {
|
|
10599
|
-
try {
|
|
10600
|
-
opts.onSpawn(child.pid);
|
|
10601
|
-
} catch {
|
|
10602
|
-
}
|
|
10603
|
-
}
|
|
10604
|
-
let stdout = "";
|
|
10605
|
-
let stderr = "";
|
|
10606
|
-
child.stdout?.on("data", (d) => {
|
|
10607
|
-
stdout += d.toString();
|
|
10608
|
-
});
|
|
10609
|
-
child.stderr?.on("data", (d) => {
|
|
10610
|
-
stderr += d.toString();
|
|
10611
|
-
});
|
|
10612
|
-
const timer = setTimeout(() => {
|
|
10613
|
-
child.kill();
|
|
10614
|
-
reject(new Error(`Timed out after ${opts?.timeout ?? 12e4}ms`));
|
|
10615
|
-
}, opts?.timeout ?? 12e4);
|
|
10616
|
-
child.on("close", (code) => {
|
|
10617
|
-
clearTimeout(timer);
|
|
10618
|
-
if (opts?.onExit && typeof child.pid === "number") {
|
|
10619
|
-
try {
|
|
10620
|
-
opts.onExit(child.pid);
|
|
10621
|
-
} catch {
|
|
10622
|
-
}
|
|
10623
|
-
}
|
|
10624
|
-
if (code !== 0) reject(new ChildProcessError(code, stdout, stderr));
|
|
10625
|
-
else resolve({ stdout, stderr });
|
|
10626
|
-
});
|
|
10627
|
-
child.on("error", (err) => {
|
|
10628
|
-
clearTimeout(timer);
|
|
10629
|
-
reject(err);
|
|
10630
|
-
});
|
|
10631
|
-
});
|
|
10632
|
-
}
|
|
10633
10646
|
var LATE_THRESHOLD_MS = 5 * 60 * 1e3;
|
|
10634
10647
|
async function monitorCronHealth(agentStates) {
|
|
10635
10648
|
const alerts = [];
|
|
@@ -11393,8 +11406,8 @@ function parseMemoryFile(raw, fallbackName) {
|
|
|
11393
11406
|
};
|
|
11394
11407
|
}
|
|
11395
11408
|
async function syncMemories(agent, configDir, log2) {
|
|
11396
|
-
const projectDir =
|
|
11397
|
-
const memoryDir =
|
|
11409
|
+
const projectDir = join13(configDir, agent.code_name, "project");
|
|
11410
|
+
const memoryDir = join13(projectDir, "memory");
|
|
11398
11411
|
const isFreshSync = pendingFreshMemorySync.has(agent.agent_id);
|
|
11399
11412
|
if (isFreshSync) {
|
|
11400
11413
|
log2(`[memory-sync] Fresh-sync requested for '${agent.code_name}' \u2014 pulling DB first`);
|
|
@@ -11405,15 +11418,15 @@ async function syncMemories(agent, configDir, log2) {
|
|
|
11405
11418
|
}
|
|
11406
11419
|
pendingFreshMemorySync.delete(agent.agent_id);
|
|
11407
11420
|
}
|
|
11408
|
-
if (
|
|
11421
|
+
if (existsSync7(memoryDir)) {
|
|
11409
11422
|
const prevHashes = memoryFileHashes.get(agent.agent_id) ?? /* @__PURE__ */ new Map();
|
|
11410
11423
|
const currentHashes = /* @__PURE__ */ new Map();
|
|
11411
11424
|
const changedMemories = [];
|
|
11412
11425
|
for (const file of readdirSync5(memoryDir)) {
|
|
11413
11426
|
if (!file.endsWith(".md")) continue;
|
|
11414
11427
|
try {
|
|
11415
|
-
const raw =
|
|
11416
|
-
const fileHash =
|
|
11428
|
+
const raw = readFileSync11(join13(memoryDir, file), "utf-8");
|
|
11429
|
+
const fileHash = createHash4("sha256").update(raw).digest("hex").slice(0, 16);
|
|
11417
11430
|
currentHashes.set(file, fileHash);
|
|
11418
11431
|
if (prevHashes.get(file) === fileHash) continue;
|
|
11419
11432
|
const parsed = parseMemoryFile(raw, file.replace(/\.md$/, ""));
|
|
@@ -11437,7 +11450,7 @@ async function syncMemories(agent, configDir, log2) {
|
|
|
11437
11450
|
} catch (err) {
|
|
11438
11451
|
for (const mem of changedMemories) {
|
|
11439
11452
|
for (const [file] of currentHashes) {
|
|
11440
|
-
const parsed = parseMemoryFile(
|
|
11453
|
+
const parsed = parseMemoryFile(readFileSync11(join13(memoryDir, file), "utf-8"), file.replace(/\.md$/, ""));
|
|
11441
11454
|
if (parsed?.name === mem.name) currentHashes.delete(file);
|
|
11442
11455
|
}
|
|
11443
11456
|
}
|
|
@@ -11450,29 +11463,29 @@ async function syncMemories(agent, configDir, log2) {
|
|
|
11450
11463
|
}
|
|
11451
11464
|
}
|
|
11452
11465
|
async function downloadMemories(agent, memoryDir, log2, { force }) {
|
|
11453
|
-
const localFiles =
|
|
11454
|
-
const localListHash =
|
|
11466
|
+
const localFiles = existsSync7(memoryDir) ? readdirSync5(memoryDir).filter((f) => f.endsWith(".md")).sort() : [];
|
|
11467
|
+
const localListHash = createHash4("sha256").update(localFiles.join(",")).digest("hex").slice(0, 16);
|
|
11455
11468
|
const prevLocalHash = lastLocalFileHash.get(agent.agent_id);
|
|
11456
11469
|
const prevDownload = lastDownloadHash.get(agent.agent_id);
|
|
11457
11470
|
try {
|
|
11458
11471
|
const dbMemories = await api.post("/host/memories", {
|
|
11459
11472
|
agent_id: agent.agent_id
|
|
11460
11473
|
});
|
|
11461
|
-
const responseHash =
|
|
11474
|
+
const responseHash = createHash4("sha256").update(JSON.stringify(dbMemories.memories ?? [])).digest("hex").slice(0, 16);
|
|
11462
11475
|
if (!force && prevDownload && prevLocalHash === localListHash && lastDownloadHash.get(agent.agent_id) === responseHash) {
|
|
11463
11476
|
return true;
|
|
11464
11477
|
}
|
|
11465
11478
|
lastDownloadHash.set(agent.agent_id, responseHash);
|
|
11466
11479
|
lastLocalFileHash.set(agent.agent_id, localListHash);
|
|
11467
11480
|
if (dbMemories.memories?.length) {
|
|
11468
|
-
|
|
11481
|
+
mkdirSync4(memoryDir, { recursive: true });
|
|
11469
11482
|
let written = 0;
|
|
11470
11483
|
let overwritten = 0;
|
|
11471
11484
|
for (let i = 0; i < dbMemories.memories.length; i++) {
|
|
11472
11485
|
const mem = dbMemories.memories[i];
|
|
11473
11486
|
const rawSlug = mem.name.toLowerCase().replace(/[^a-z0-9]+/g, "-").replace(/(^-|-$)/g, "").slice(0, 60);
|
|
11474
11487
|
const slug = rawSlug || `memory-${i}`;
|
|
11475
|
-
const filePath =
|
|
11488
|
+
const filePath = join13(memoryDir, `${slug}.md`);
|
|
11476
11489
|
const desired = `---
|
|
11477
11490
|
name: ${JSON.stringify(mem.name)}
|
|
11478
11491
|
type: ${mem.type}
|
|
@@ -11481,10 +11494,10 @@ description: ${JSON.stringify(mem.content.slice(0, 200))}
|
|
|
11481
11494
|
|
|
11482
11495
|
${mem.content}
|
|
11483
11496
|
`;
|
|
11484
|
-
if (
|
|
11497
|
+
if (existsSync7(filePath)) {
|
|
11485
11498
|
let existing = "";
|
|
11486
11499
|
try {
|
|
11487
|
-
existing =
|
|
11500
|
+
existing = readFileSync11(filePath, "utf-8");
|
|
11488
11501
|
} catch {
|
|
11489
11502
|
}
|
|
11490
11503
|
if (existing === desired) continue;
|
|
@@ -11497,7 +11510,7 @@ ${mem.content}
|
|
|
11497
11510
|
}
|
|
11498
11511
|
if (written > 0 || overwritten > 0) {
|
|
11499
11512
|
const updatedFiles = readdirSync5(memoryDir).filter((f) => f.endsWith(".md")).sort();
|
|
11500
|
-
lastLocalFileHash.set(agent.agent_id,
|
|
11513
|
+
lastLocalFileHash.set(agent.agent_id, createHash4("sha256").update(updatedFiles.join(",")).digest("hex").slice(0, 16));
|
|
11501
11514
|
log2(`Memory download for '${agent.code_name}': wrote ${written} new, overwrote ${overwritten} stale`);
|
|
11502
11515
|
}
|
|
11503
11516
|
}
|
|
@@ -11508,9 +11521,9 @@ ${mem.content}
|
|
|
11508
11521
|
}
|
|
11509
11522
|
}
|
|
11510
11523
|
async function cleanupAgentFiles(codeName, agentDir) {
|
|
11511
|
-
if (
|
|
11524
|
+
if (existsSync7(agentDir)) {
|
|
11512
11525
|
try {
|
|
11513
|
-
|
|
11526
|
+
rmSync3(agentDir, { recursive: true, force: true });
|
|
11514
11527
|
log(`Removed provision directory for '${codeName}'`);
|
|
11515
11528
|
} catch (err) {
|
|
11516
11529
|
log(`Failed to remove provision dir for '${codeName}': ${err.message}`);
|
|
@@ -11738,8 +11751,8 @@ function startManager(opts) {
|
|
|
11738
11751
|
config = opts;
|
|
11739
11752
|
try {
|
|
11740
11753
|
const stateFile = getStateFile();
|
|
11741
|
-
if (
|
|
11742
|
-
const raw =
|
|
11754
|
+
if (existsSync7(stateFile)) {
|
|
11755
|
+
const raw = readFileSync11(stateFile, "utf-8");
|
|
11743
11756
|
const parsed = JSON.parse(raw);
|
|
11744
11757
|
if (Array.isArray(parsed.agents)) {
|
|
11745
11758
|
state6.agents = parsed.agents;
|
|
@@ -11760,7 +11773,7 @@ function startManager(opts) {
|
|
|
11760
11773
|
log(`[startup] state rehydration failed (continuing with empty state): ${err.message}`);
|
|
11761
11774
|
}
|
|
11762
11775
|
log(
|
|
11763
|
-
`[startup] worker pid=${process.pid} ppid=${process.ppid} node=${process.version} log=${
|
|
11776
|
+
`[startup] worker pid=${process.pid} ppid=${process.ppid} node=${process.version} log=${join13(homedir7(), ".augmented", "manager.log")}`
|
|
11764
11777
|
);
|
|
11765
11778
|
deployMcpAssets();
|
|
11766
11779
|
reapOrphanChannelMcps({ log });
|
|
@@ -11781,7 +11794,7 @@ async function reapOrphanedClaudePids() {
|
|
|
11781
11794
|
const looksLikeClaude = (pid) => {
|
|
11782
11795
|
if (process.platform !== "linux") return true;
|
|
11783
11796
|
try {
|
|
11784
|
-
const comm =
|
|
11797
|
+
const comm = readFileSync11(`/proc/${pid}/comm`, "utf-8").trim().toLowerCase();
|
|
11785
11798
|
return comm.includes("claude");
|
|
11786
11799
|
} catch {
|
|
11787
11800
|
return false;
|
|
@@ -11891,18 +11904,18 @@ function restartRunningChannelMcps(basenames) {
|
|
|
11891
11904
|
}
|
|
11892
11905
|
}
|
|
11893
11906
|
function deployMcpAssets() {
|
|
11894
|
-
const targetDir =
|
|
11895
|
-
|
|
11896
|
-
const moduleDir =
|
|
11907
|
+
const targetDir = join13(homedir7(), ".augmented", "_mcp");
|
|
11908
|
+
mkdirSync4(targetDir, { recursive: true });
|
|
11909
|
+
const moduleDir = dirname3(fileURLToPath(import.meta.url));
|
|
11897
11910
|
let mcpSourceDir = "";
|
|
11898
11911
|
let dir = moduleDir;
|
|
11899
11912
|
for (let i = 0; i < 6; i++) {
|
|
11900
|
-
const candidate =
|
|
11901
|
-
if (
|
|
11913
|
+
const candidate = join13(dir, "dist", "mcp");
|
|
11914
|
+
if (existsSync7(join13(candidate, "index.js"))) {
|
|
11902
11915
|
mcpSourceDir = candidate;
|
|
11903
11916
|
break;
|
|
11904
11917
|
}
|
|
11905
|
-
const parent =
|
|
11918
|
+
const parent = dirname3(dir);
|
|
11906
11919
|
if (parent === dir) break;
|
|
11907
11920
|
dir = parent;
|
|
11908
11921
|
}
|
|
@@ -11913,8 +11926,8 @@ function deployMcpAssets() {
|
|
|
11913
11926
|
const changedBasenames = [];
|
|
11914
11927
|
const fileHash = (p) => {
|
|
11915
11928
|
try {
|
|
11916
|
-
if (!
|
|
11917
|
-
return
|
|
11929
|
+
if (!existsSync7(p)) return null;
|
|
11930
|
+
return createHash4("sha256").update(readFileSync11(p)).digest("hex");
|
|
11918
11931
|
} catch {
|
|
11919
11932
|
return null;
|
|
11920
11933
|
}
|
|
@@ -11941,9 +11954,9 @@ function deployMcpAssets() {
|
|
|
11941
11954
|
// natural session restart.
|
|
11942
11955
|
"augmented-admin.js"
|
|
11943
11956
|
]) {
|
|
11944
|
-
const src =
|
|
11945
|
-
const dst =
|
|
11946
|
-
if (!
|
|
11957
|
+
const src = join13(mcpSourceDir, file);
|
|
11958
|
+
const dst = join13(targetDir, file);
|
|
11959
|
+
if (!existsSync7(src)) continue;
|
|
11947
11960
|
const before = fileHash(dst);
|
|
11948
11961
|
try {
|
|
11949
11962
|
copyFileSync(src, dst);
|
|
@@ -11960,16 +11973,16 @@ function deployMcpAssets() {
|
|
|
11960
11973
|
log(`[manager] Bundle(s) updated: ${changedBasenames.join(", ")} \u2014 signalling running instances to restart`);
|
|
11961
11974
|
restartRunningChannelMcps(changedBasenames);
|
|
11962
11975
|
}
|
|
11963
|
-
const localMcpPath =
|
|
11976
|
+
const localMcpPath = join13(targetDir, "index.js");
|
|
11964
11977
|
try {
|
|
11965
|
-
const agentsDir =
|
|
11966
|
-
if (
|
|
11978
|
+
const agentsDir = join13(homedir7(), ".augmented", "agents");
|
|
11979
|
+
if (existsSync7(agentsDir)) {
|
|
11967
11980
|
for (const entry of readdirSync5(agentsDir, { withFileTypes: true })) {
|
|
11968
11981
|
if (!entry.isDirectory()) continue;
|
|
11969
11982
|
for (const subdir of ["provision", "project"]) {
|
|
11970
|
-
const mcpJsonPath =
|
|
11983
|
+
const mcpJsonPath = join13(agentsDir, entry.name, subdir, ".mcp.json");
|
|
11971
11984
|
try {
|
|
11972
|
-
const raw =
|
|
11985
|
+
const raw = readFileSync11(mcpJsonPath, "utf-8");
|
|
11973
11986
|
if (!raw.includes("@integrity-labs/augmented-mcp")) continue;
|
|
11974
11987
|
const mcpConfig = JSON.parse(raw);
|
|
11975
11988
|
const augServer = mcpConfig.mcpServers?.["augmented"];
|
|
@@ -12012,7 +12025,6 @@ process.on("disconnect", () => {
|
|
|
12012
12025
|
});
|
|
12013
12026
|
export {
|
|
12014
12027
|
BACK_ONLINE_GREETING_GUIDANCE,
|
|
12015
|
-
ChildProcessError,
|
|
12016
12028
|
SCHEDULED_CARD_DELIVERY_CONTRACT,
|
|
12017
12029
|
__resetScheduledDeliveryDedupeForTest,
|
|
12018
12030
|
__setAgentChannelTokensForTest,
|