@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.
@@ -22,7 +22,7 @@ import {
22
22
  provisionStopHook,
23
23
  requireHost,
24
24
  safeWriteJsonAtomic
25
- } from "../chunk-BBTTZRCH.js";
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 createHash3 } from "crypto";
107
- import { readFileSync as readFileSync10, writeFileSync as writeFileSync4, appendFileSync, mkdirSync as mkdirSync3, chmodSync, existsSync as existsSync5, rmSync as rmSync2, readdirSync as readdirSync5, statSync as statSync4, unlinkSync, copyFileSync } from "fs";
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 join11, dirname as dirname2 } from "path";
111
- import { homedir as homedir5 } from "os";
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 existsSync4, mkdirSync as mkdirSync2, readdirSync as readdirSync4, readFileSync as readFileSync9, renameSync, rmSync, writeFileSync as writeFileSync3 } from "fs";
3817
- import { homedir as homedir4 } from "os";
3818
- import { join as join10 } from "path";
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 join10(homedir4(), ".augmented", "restart-flags");
4004
+ return join12(homedir6(), ".augmented", "restart-flags");
3822
4005
  }
3823
4006
  function flagPath(codeName) {
3824
- return join10(restartFlagsDir(), `${codeName}.flag`);
4007
+ return join12(restartFlagsDir(), `${codeName}.flag`);
3825
4008
  }
3826
4009
  function readRestartFlags() {
3827
4010
  const dir = restartFlagsDir();
3828
- if (!existsSync4(dir)) return [];
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 = readFileSync9(join10(dir, entry), "utf8");
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 (existsSync4(path)) {
3852
- rmSync(path, { force: true });
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 = join11(process.env["HOME"] ?? "/tmp", ".augmented");
4382
- var GATEWAY_PORTS_FILE = join11(AUGMENTED_DIR, "gateway-ports.json");
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 = readFileSync10(join11(projectDir, ".mcp.json"), "utf-8");
4758
- return createHash3("sha256").update(canonicalJson(JSON.parse(raw))).digest("hex");
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 = readFileSync10(join11(projectDir, ".mcp.json"), "utf-8");
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 = readFileSync10(join11(projectDir, ".mcp.json"), "utf-8");
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 = join11(projectDir, ".env.integrations");
4805
- if (existsSync5(envIntPath)) {
4806
- Object.assign(probeEnv, parseEnvIntegrations(readFileSync10(envIntPath, "utf-8")));
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
- readFileSync10(join11(projectDir, ".env.integrations"), "utf-8")
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.13-canary.18" : "dev";
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 (existsSync5(path)) return path;
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) => existsSync5(path))) return true;
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 = dirname2(brewPath);
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 (existsSync5(path)) {
5263
- const raw = readFileSync10(path, "utf-8").trim();
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
- mkdirSync3(dirname2(path), { recursive: true });
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 = dirname2(brewPath);
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 (existsSync5("/home/linuxbrew/.linuxbrew/bin/claude")) {
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 join11(homedir5(), ".augmented", ".last-claude-code-upgrade-check");
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(readFileSync10(claudeCodeUpgradeMarkerPath(), "utf-8").trim(), 10);
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 join11(homedir5(), ".augmented", ".last-self-update-applied");
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 = join11(homedir5(), ".augmented", ".last-update-check");
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 && existsSync5(evalEmptyMcpConfigPath)) return evalEmptyMcpConfigPath;
5707
- const dir = join11(homedir5(), ".augmented");
5863
+ if (evalEmptyMcpConfigPath && existsSync7(evalEmptyMcpConfigPath)) return evalEmptyMcpConfigPath;
5864
+ const dir = join13(homedir7(), ".augmented");
5708
5865
  try {
5709
- mkdirSync3(dir, { recursive: true });
5866
+ mkdirSync4(dir, { recursive: true });
5710
5867
  } catch {
5711
5868
  }
5712
- const p = join11(dir, ".eval-empty-mcp.json");
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: homedir5(),
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(readFileSync10(GATEWAY_PORTS_FILE, "utf-8"));
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
- mkdirSync3(AUGMENTED_DIR, { recursive: true });
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 join11(config?.configDir ?? join11(process.env["HOME"] ?? "/tmp", ".augmented"), "manager-state.json");
5974
+ return join13(config?.configDir ?? join13(process.env["HOME"] ?? "/tmp", ".augmented"), "manager-state.json");
5818
5975
  }
5819
5976
  function channelHashCacheDir() {
5820
- return config?.configDir ?? join11(process.env["HOME"] ?? "/tmp", ".augmented");
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 ?? join11(process.env["HOME"] ?? "/tmp", ".augmented");
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 ?? join11(process.env["HOME"] ?? "/tmp", ".augmented");
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 = join11(configDir, codeName, "project", ".claude", "skills");
5947
- const claudeMdPath = join11(configDir, codeName, "project", "CLAUDE.md");
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 = join11(skillsDir, dir, "SKILL.md");
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 = join11(homeDir, ".openclaw", "openclaw.json");
6101
+ const sharedConfigPath = join13(homeDir, ".openclaw", "openclaw.json");
6000
6102
  let sharedConfig;
6001
6103
  try {
6002
- sharedConfig = JSON.parse(readFileSync10(sharedConfigPath, "utf-8"));
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 = join11(homeDir, `.openclaw-${codeName}`);
6016
- if (existsSync5(join11(profileDir, "openclaw.json"))) continue;
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 = join11(homeDir, ".openclaw", "agents", codeName, "agent");
6022
- const profileAuthDir = join11(profileDir, "agents", codeName, "agent");
6023
- const authFile = join11(sharedAuthDir, "auth-profiles.json");
6024
- if (existsSync5(authFile)) {
6025
- mkdirSync3(profileAuthDir, { recursive: true });
6026
- const authContent = readFileSync10(authFile, "utf-8");
6027
- writeFileSync4(join11(profileAuthDir, "auth-profiles.json"), authContent);
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(readFileSync10(join11(homeDir, `.openclaw-${codeName}`, "openclaw.json"), "utf-8"));
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 = join11(homeDir, `.openclaw-${codeName}`, "cron", "jobs.json");
6075
- if (!existsSync5(jobsPath)) return false;
6154
+ const jobsPath = join13(homeDir, `.openclaw-${codeName}`, "cron", "jobs.json");
6155
+ if (!existsSync7(jobsPath)) return false;
6076
6156
  try {
6077
- const data = JSON.parse(readFileSync10(jobsPath, "utf-8"));
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 = join11(homeDir, `.openclaw-${codeName}`, "cron", "jobs.json");
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 = join11(homeDir, `.openclaw-${codeName}`, "openclaw.json");
6117
- if (existsSync5(configPath)) {
6118
- const cfg = JSON.parse(readFileSync10(configPath, "utf-8"));
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 = join11(homeDir, `.openclaw-${codeName}`, "openclaw.json");
6143
- if (existsSync5(configPath)) {
6144
- const cfg = JSON.parse(readFileSync10(configPath, "utf-8"));
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 = createHash3("sha256").update(errText).digest("hex").slice(0, 12);
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 = join11(adapter.getAgentDir(prev.codeName), "provision");
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 = join11(homedir5(), ".augmented", codeName);
6768
- if (!existsSync5(dir)) return;
6847
+ const dir = join13(homedir7(), ".augmented", codeName);
6848
+ if (!existsSync7(dir)) return;
6769
6849
  atomicWriteFileSync(
6770
- join11(dir, "watchdog-give-up.json"),
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 = join11(adapter.getAgentDir(agent.code_name), "provision");
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: existsSync5(agentDir)
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 = join11(frameworkAdapter.getAgentDir(agent.code_name), "provision");
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
- mkdirSync3(agentDir, { recursive: true });
7222
+ mkdirSync4(agentDir, { recursive: true });
7143
7223
  for (const artifact of artifacts) {
7144
- const filePath = join11(agentDir, artifact.relativePath);
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 = join11(config.configDir, agent.code_name, "project", "CLAUDE.md");
7164
- const existing = readFileSync10(projectClaudeMd, "utf-8");
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 = readFileSync10(filePath, "utf-8");
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 = !existsSync5(join11(agentDir, "CHARTER.md"));
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 = join11(agentDir, file.relativePath);
7210
- mkdirSync3(dirname2(filePath), { recursive: true });
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 = join11(agentDir, ".claude", "skills");
7219
- if (existsSync5(provSkillsDir)) {
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
- rmSync2(join11(provSkillsDir, folder), { recursive: true });
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(join11(agentDir, file));
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 = join11(agentDir, ".claude", "workflows");
7255
- if (existsSync5(provWorkflowsDir)) {
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
- rmSync2(join11(provWorkflowsDir, file));
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 && existsSync5(agentDir)) {
7398
+ if (written && existsSync7(agentDir)) {
7319
7399
  const driftedFiles = [];
7320
7400
  for (const [file, expectedHash] of written) {
7321
- const localHash = hashFile(join11(agentDir, file));
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(join11(agentDir, file));
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 = createHash3("sha256").update(
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 = createHash3("sha256").update(canonicalJson({ senderPolicy: senderPolicyForRestartHash })).digest("hex");
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 = createHash3("sha256").update(canonicalJson(behaviourSubset)).digest("hex");
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 = createHash3("sha256").update(canonicalJson(slackBehaviourSubset)).digest("hex");
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 = join11(homedir5(), ".augmented", agent.code_name, "project");
7657
- mkdirSync3(agentProvisionDir, { recursive: true });
7658
- mkdirSync3(projectDir, { recursive: true });
7659
- const provisionMcpPath = join11(agentProvisionDir, ".mcp.json");
7660
- const projectMcpPath = join11(projectDir, ".mcp.json");
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(readFileSync10(provisionMcpPath, "utf-8"));
7743
+ mcpConfig = JSON.parse(readFileSync11(provisionMcpPath, "utf-8"));
7664
7744
  if (!mcpConfig.mcpServers) mcpConfig.mcpServers = {};
7665
7745
  } catch {
7666
7746
  }
7667
- const localDirectChatChannel = join11(homedir5(), ".augmented", "_mcp", "direct-chat-channel.js");
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 (existsSync5(localDirectChatChannel)) {
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 = join11(projectDir, ".mcp-channels.json");
7698
- if (existsSync5(staleChannelsPath)) {
7777
+ const staleChannelsPath = join13(projectDir, ".mcp-channels.json");
7778
+ if (existsSync7(staleChannelsPath)) {
7699
7779
  try {
7700
- rmSync2(staleChannelsPath, { force: true });
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 = join11(homedir5(), ".augmented", agent.code_name, "project");
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 = join11(homedir5(), ".augmented", agent.code_name, "project");
7781
- const envIntPath = join11(projectDir, ".env.integrations");
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 = readFileSync10(envIntPath, "utf-8");
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 = join11(projectDir, ".mcp.json");
7797
- const postWriteEnv = readFileSync10(envIntPath, "utf-8");
7798
- const mcpContent = readFileSync10(projectMcpPath, "utf-8");
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 = createHash3("sha256").update(canonicalJson(e.headers ?? {})).digest("hex").slice(0, 16);
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 = createHash3("sha256").update(hashBasis).digest("hex").slice(0, 16);
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 = createHash3("sha256").update(e.url).digest("hex").slice(0, 12);
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: readFileSync11 } = await import("fs");
7879
- const mcpConfig = JSON.parse(readFileSync11(mcpPath, "utf-8"));
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 = join11(process.cwd(), "packages", "openclaw-plugin-augmented", "src", "index.ts");
7981
- if (existsSync5(pluginPath)) {
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: createHash4 } = await import("crypto");
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 = createHash4("sha256").update(bundleFingerprint(bundle.files)).digest("hex").slice(0, 12);
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: rmSync3 } = await import("fs");
8047
- const { homedir: homedir6 } = await import("os");
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
- join11(homedir6(), ".augmented", agent.code_name, "skills"),
8131
+ join13(homedir8(), ".augmented", agent.code_name, "skills"),
8052
8132
  // Claude Code — project tree
8053
- join11(homedir6(), ".augmented", agent.code_name, "project", ".claude", "skills"),
8133
+ join13(homedir8(), ".augmented", agent.code_name, "project", ".claude", "skills"),
8054
8134
  // OpenClaw — framework runtime tree
8055
- join11(homedir6(), `.openclaw-${agent.code_name}`, "skills"),
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
- join11(agentDir, ".claude", "skills")
8138
+ join13(agentDir, ".claude", "skills")
8059
8139
  ];
8060
- const existingDirs = candidateSkillDirs.filter((d) => existsSync5(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 = join11(dir, entry);
8075
- if (existsSync5(p)) {
8076
- rmSync3(p, { recursive: true, force: true });
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) => createHash4("sha256").update(content).digest("hex").slice(0, 12),
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: rmSync3 } = await import("fs");
8103
- const { homedir: homedir6 } = await import("os");
8182
+ const { rmSync: rmSync4 } = await import("fs");
8183
+ const { homedir: homedir8 } = await import("os");
8104
8184
  const globalSkillDirs = [
8105
- join11(homedir6(), ".augmented", agent.code_name, "skills"),
8106
- join11(homedir6(), ".augmented", agent.code_name, "project", ".claude", "skills"),
8107
- join11(homedir6(), `.openclaw-${agent.code_name}`, "skills"),
8108
- join11(agentDir, ".claude", "skills")
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 = join11(dir, id);
8113
- if (existsSync5(p)) rmSync3(p, { recursive: true, force: true });
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 = createHash4("sha256").update(hook.script).digest("hex").slice(0, 12);
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 = createHash4("sha256").update(result.stderr).digest("hex").slice(0, 12);
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 ? createHash4("sha256").update(missingCmd).digest("hex").slice(0, 8) : null;
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 = join11(getProjectDir(agent.code_name), ".mcp.json");
8289
- mcpJsonParsed = JSON.parse(readFileSync10(mcpPath, "utf-8"));
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 = createHash3("sha256").update(JSON.stringify(tasks)).digest("hex").slice(0, 16);
8424
- const boardHash = boardItems.length > 0 ? createHash3("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";
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 = createHash3("sha256").update(JSON.stringify(resolvedModels)).digest("hex").slice(0, 16);
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 = join11(homeDir, `.openclaw-${agent.code_name}`, "cron", "jobs.json");
8499
- if (existsSync5(jobsPath)) {
8578
+ const jobsPath = join13(homeDir, `.openclaw-${agent.code_name}`, "cron", "jobs.json");
8579
+ if (existsSync7(jobsPath)) {
8500
8580
  try {
8501
- const jobsData = JSON.parse(readFileSync10(jobsPath, "utf-8"));
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 && existsSync5(agentDir)) {
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(join11(agentDir, file));
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 = join11(homeDir, `.openclaw-${codeName}`, "agents", agentDir, "sessions");
8752
+ const sessionsDir = join13(homeDir, `.openclaw-${codeName}`, "agents", agentDir, "sessions");
8673
8753
  cleanupCronSessions(sessionsDir, CRON_SESSION_KEEP_COUNT);
8674
8754
  }
8675
- const cronRunsDir = join11(homeDir, `.openclaw-${codeName}`, "cron", "runs");
8755
+ const cronRunsDir = join13(homeDir, `.openclaw-${codeName}`, "cron", "runs");
8676
8756
  cleanupOldFiles(cronRunsDir, CRON_RUN_RETENTION_DAYS, ".jsonl");
8677
- const cronJobsPath = join11(homeDir, `.openclaw-${codeName}`, "cron", "jobs.json");
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 = join11(sessionsDir, "sessions.json");
8682
- if (!existsSync5(indexPath)) return;
8761
+ const indexPath = join13(sessionsDir, "sessions.json");
8762
+ if (!existsSync7(indexPath)) return;
8683
8763
  try {
8684
- const raw = readFileSync10(indexPath, "utf-8");
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 = join11(sessionsDir, `${entry.sessionId}.jsonl`);
8777
+ const sessionFile = join13(sessionsDir, `${entry.sessionId}.jsonl`);
8698
8778
  try {
8699
- if (existsSync5(sessionFile)) {
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 = join11(sessionsDir, `${parentSessionId}.jsonl`);
8720
- if (existsSync5(f)) {
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 (!existsSync5(jobsPath)) return;
8818
+ if (!existsSync7(jobsPath)) return;
8739
8819
  try {
8740
- const raw = readFileSync10(jobsPath, "utf-8");
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 (!existsSync5(dir)) return;
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 = join11(dir, f);
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 join11(homedir5(), ".augmented", "manager-claude-pids.json");
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 = createHash3("sha256").update(JSON.stringify(tasks)).digest("hex").slice(0, 16);
8839
- const boardHash = boardItems.length > 0 ? createHash3("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";
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 = createHash3("sha256").update(JSON.stringify(resolvedModels)).digest("hex").slice(0, 16);
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 = createHash3("sha256").update(errText).digest("hex").slice(0, 12);
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 = createHash3("sha256").update(errText).digest("hex").slice(0, 12);
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 = createHash3("sha256").update(errText).digest("hex").slice(0, 12);
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 = join11(projectDir, ".mcp.json");
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 = join11(projectDir, "CLAUDE.md");
9245
+ const claudeMdPath = join13(projectDir, "CLAUDE.md");
9166
9246
  const serverNames = [];
9167
- if (existsSync5(mcpConfigPath)) {
9247
+ if (existsSync7(mcpConfigPath)) {
9168
9248
  try {
9169
- const d = JSON.parse(readFileSync10(mcpConfigPath, "utf-8"));
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 (existsSync5(claudeMdPath)) {
9268
+ if (existsSync7(claudeMdPath)) {
9189
9269
  claudeArgs.push("--system-prompt-file", claudeMdPath);
9190
9270
  }
9191
9271
  const childEnv = { ...process.env };
9192
- const envIntPath = join11(projectDir, ".env.integrations");
9193
- if (existsSync5(envIntPath)) {
9272
+ const envIntPath = join13(projectDir, ".env.integrations");
9273
+ if (existsSync7(envIntPath)) {
9194
9274
  try {
9195
- Object.assign(childEnv, parseEnvIntegrations(readFileSync10(envIntPath, "utf-8")));
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" : createHash3("sha256").update(trimmed).digest("hex").slice(0, 12);
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 = createHash3("sha256").update(classification.suppressedNotes).digest("hex").slice(0, 12);
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 = join11(projectDir, ".mcp.json");
9368
- const claudeMdPath = join11(projectDir, "CLAUDE.md");
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:${createHash3("sha256").update(ctx.tail).digest("hex").slice(0, 12)} (raw at ~/.augmented/${codeName}/pane.log)`;
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:${createHash3("sha256").update(zombie.paneTail).digest("hex").slice(0, 12)}` : null;
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 = createHash3("sha256").update(JSON.stringify(tasks)).digest("hex").slice(0, 16);
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, homedir5());
9968
- mkdirSync3(dirname2(doorbell), { recursive: true });
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 = join11(projDir, ".mcp.json");
10093
+ const mcpConfigPath = join13(projDir, ".mcp.json");
10014
10094
  const serverNames = [];
10015
- if (existsSync5(mcpConfigPath)) {
10095
+ if (existsSync7(mcpConfigPath)) {
10016
10096
  try {
10017
- const d = JSON.parse(readFileSync10(mcpConfigPath, "utf-8"));
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 = join11(projDir, "CLAUDE.md");
10037
- if (existsSync5(chatClaudeMd)) {
10116
+ const chatClaudeMd = join13(projDir, "CLAUDE.md");
10117
+ if (existsSync7(chatClaudeMd)) {
10038
10118
  chatArgs.push("--system-prompt-file", chatClaudeMd);
10039
10119
  }
10040
- const envIntPath = join11(projDir, ".env.integrations");
10120
+ const envIntPath = join13(projDir, ".env.integrations");
10041
10121
  const childEnv = { ...process.env };
10042
- if (existsSync5(envIntPath)) {
10122
+ if (existsSync7(envIntPath)) {
10043
10123
  try {
10044
- Object.assign(childEnv, parseEnvIntegrations(readFileSync10(envIntPath, "utf-8")));
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 = createHash3("sha256").update(errMsg).digest("hex").slice(0, 12);
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
- join11(process.cwd(), "skills", skillId, "SKILL.md"),
10423
- join11(new URL(".", import.meta.url).pathname, "..", "..", "..", "..", "skills", skillId, "SKILL.md")
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 (existsSync5(candidate)) {
10427
- const content = readFileSync10(candidate, "utf-8");
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 = join11(configDir, agent.code_name, "project");
11397
- const memoryDir = join11(projectDir, "memory");
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 (existsSync5(memoryDir)) {
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 = readFileSync10(join11(memoryDir, file), "utf-8");
11416
- const fileHash = createHash3("sha256").update(raw).digest("hex").slice(0, 16);
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(readFileSync10(join11(memoryDir, file), "utf-8"), file.replace(/\.md$/, ""));
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 = existsSync5(memoryDir) ? readdirSync5(memoryDir).filter((f) => f.endsWith(".md")).sort() : [];
11454
- const localListHash = createHash3("sha256").update(localFiles.join(",")).digest("hex").slice(0, 16);
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 = createHash3("sha256").update(JSON.stringify(dbMemories.memories ?? [])).digest("hex").slice(0, 16);
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
- mkdirSync3(memoryDir, { recursive: true });
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 = join11(memoryDir, `${slug}.md`);
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 (existsSync5(filePath)) {
11497
+ if (existsSync7(filePath)) {
11485
11498
  let existing = "";
11486
11499
  try {
11487
- existing = readFileSync10(filePath, "utf-8");
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, createHash3("sha256").update(updatedFiles.join(",")).digest("hex").slice(0, 16));
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 (existsSync5(agentDir)) {
11524
+ if (existsSync7(agentDir)) {
11512
11525
  try {
11513
- rmSync2(agentDir, { recursive: true, force: true });
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 (existsSync5(stateFile)) {
11742
- const raw = readFileSync10(stateFile, "utf-8");
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=${join11(homedir5(), ".augmented", "manager.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 = readFileSync10(`/proc/${pid}/comm`, "utf-8").trim().toLowerCase();
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 = join11(homedir5(), ".augmented", "_mcp");
11895
- mkdirSync3(targetDir, { recursive: true });
11896
- const moduleDir = dirname2(fileURLToPath(import.meta.url));
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 = join11(dir, "dist", "mcp");
11901
- if (existsSync5(join11(candidate, "index.js"))) {
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 = dirname2(dir);
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 (!existsSync5(p)) return null;
11917
- return createHash3("sha256").update(readFileSync10(p)).digest("hex");
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 = join11(mcpSourceDir, file);
11945
- const dst = join11(targetDir, file);
11946
- if (!existsSync5(src)) continue;
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 = join11(targetDir, "index.js");
11976
+ const localMcpPath = join13(targetDir, "index.js");
11964
11977
  try {
11965
- const agentsDir = join11(homedir5(), ".augmented", "agents");
11966
- if (existsSync5(agentsDir)) {
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 = join11(agentsDir, entry.name, subdir, ".mcp.json");
11983
+ const mcpJsonPath = join13(agentsDir, entry.name, subdir, ".mcp.json");
11971
11984
  try {
11972
- const raw = readFileSync10(mcpJsonPath, "utf-8");
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,