@integrity-labs/agt-cli 0.28.24 → 0.28.26

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-Z5GPBUID.js";
25
+ } from "../chunk-NDGLXWV7.js";
26
26
  import {
27
27
  getProjectDir as getProjectDir2,
28
28
  getReadyTasks,
@@ -105,10 +105,10 @@ import {
105
105
 
106
106
  // src/lib/manager-worker.ts
107
107
  import { createHash as createHash4 } from "crypto";
108
- 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
+ import { readFileSync as readFileSync12, writeFileSync as writeFileSync4, mkdirSync as mkdirSync4, existsSync as existsSync8, rmSync as rmSync3, readdirSync as readdirSync5, statSync as statSync4, unlinkSync, copyFileSync } from "fs";
109
109
  import https from "https";
110
110
  import { execFileSync as syncExecFile } from "child_process";
111
- import { join as join13, dirname as dirname3 } from "path";
111
+ import { join as join14, dirname as dirname3 } from "path";
112
112
  import { homedir as homedir7 } from "os";
113
113
  import { fileURLToPath } from "url";
114
114
 
@@ -3831,6 +3831,273 @@ async function applyClaudeAuthToEnv(childEnv, label) {
3831
3831
  }
3832
3832
  }
3833
3833
 
3834
+ // src/lib/manager/kanban/parsers.ts
3835
+ import { existsSync as existsSync6, readFileSync as readFileSync10 } from "fs";
3836
+ import { join as join12 } from "path";
3837
+ var STANDUP_TEMPLATES = /* @__PURE__ */ new Set(["daily-standup", "end-of-day-summary"]);
3838
+ var TASK_UPDATE_TEMPLATES = /* @__PURE__ */ new Set(["hourly-status", "task-update"]);
3839
+ var PLAN_TEMPLATES = /* @__PURE__ */ new Set(["morning-plan"]);
3840
+ var KANBAN_WORK_TEMPLATES = /* @__PURE__ */ new Set(["kanban-work"]);
3841
+ function isPlainScheduledTemplate(templateId) {
3842
+ return !STANDUP_TEMPLATES.has(templateId) && !TASK_UPDATE_TEMPLATES.has(templateId) && !PLAN_TEMPLATES.has(templateId) && !KANBAN_WORK_TEMPLATES.has(templateId);
3843
+ }
3844
+ function isKanbanHybridEnabled() {
3845
+ return true;
3846
+ }
3847
+ function isKanbanHybridDryRun() {
3848
+ const v = process.env["AGT_KANBAN_HYBRID_DRY_RUN"];
3849
+ return v === "1" || v?.toLowerCase() === "true";
3850
+ }
3851
+ var HYBRID_ACTIONABLE_STATUSES = /* @__PURE__ */ new Set(["todo", "in_progress"]);
3852
+ function isHybridActionable(item) {
3853
+ return HYBRID_ACTIONABLE_STATUSES.has(item.status) && item.source_type !== "scheduled_task";
3854
+ }
3855
+ function isSlashCommand(command) {
3856
+ return command.trimStart().startsWith("/");
3857
+ }
3858
+ var BOARD_INJECT_TEMPLATES = /* @__PURE__ */ new Set(["morning-plan", "task-update", "hourly-status", "end-of-day-summary"]);
3859
+ function parseStandupSummary(summary) {
3860
+ const lines = summary.split("\n");
3861
+ let yesterday = "";
3862
+ let today = "";
3863
+ let blockers = "";
3864
+ let currentSection = null;
3865
+ for (const line of lines) {
3866
+ const lower = line.toLowerCase();
3867
+ if (lower.includes("yesterday") || lower.includes("accomplished")) {
3868
+ currentSection = "yesterday";
3869
+ continue;
3870
+ } else if (lower.includes("today") || lower.includes("todo") || lower.includes("working on")) {
3871
+ currentSection = "todo";
3872
+ continue;
3873
+ } else if (lower.includes("blocker")) {
3874
+ currentSection = "blockers";
3875
+ continue;
3876
+ }
3877
+ const trimmed = line.replace(/^[-*•]\s*/, "").trim();
3878
+ if (!trimmed) continue;
3879
+ switch (currentSection) {
3880
+ case "yesterday":
3881
+ yesterday += (yesterday ? "\n" : "") + trimmed;
3882
+ break;
3883
+ case "todo":
3884
+ today += (today ? "\n" : "") + trimmed;
3885
+ break;
3886
+ case "blockers":
3887
+ blockers += (blockers ? "\n" : "") + trimmed;
3888
+ break;
3889
+ }
3890
+ }
3891
+ if (!yesterday && !today && !blockers) {
3892
+ today = summary;
3893
+ }
3894
+ return { yesterday, today, blockers };
3895
+ }
3896
+ function parsePlanItems(summary) {
3897
+ const items = [];
3898
+ const lines = summary.split("\n");
3899
+ let currentItem = null;
3900
+ for (const line of lines) {
3901
+ const trimmed = line.trim();
3902
+ const itemMatch = trimmed.match(/^(?:\d+[\.\)]\s*|[-*•]\s*)\[?(HIGH|MEDIUM|LOW|MED)\]?\s*(.+)/i);
3903
+ if (itemMatch) {
3904
+ if (currentItem) items.push(currentItem);
3905
+ const priorityStr = itemMatch[1].toUpperCase();
3906
+ const rest = itemMatch[2];
3907
+ let estimatedMinutes;
3908
+ const timeMatch = rest.match(/\(~?(\d+)\s*(min(?:utes?)?|hr?(?:ours?)?|h)\)/i);
3909
+ if (timeMatch) {
3910
+ const val = parseInt(timeMatch[1], 10);
3911
+ const unit = timeMatch[2].toLowerCase();
3912
+ estimatedMinutes = unit.startsWith("h") ? val * 60 : val;
3913
+ }
3914
+ const title = sanitizeKanbanString(
3915
+ rest.replace(/\(~?\d+\s*(?:min(?:utes?)?|hr?(?:ours?)?|h)\)/i, ""),
3916
+ MAX_KANBAN_TITLE_LENGTH
3917
+ );
3918
+ if (!title) continue;
3919
+ const priorityMap = { HIGH: 1, MEDIUM: 2, MED: 2, LOW: 3 };
3920
+ const priority = priorityMap[priorityStr] ?? 2;
3921
+ if (![1, 2, 3].includes(priority)) continue;
3922
+ currentItem = {
3923
+ title,
3924
+ priority,
3925
+ estimated_minutes: estimatedMinutes,
3926
+ status: "todo"
3927
+ };
3928
+ } else if (currentItem && trimmed && !trimmed.match(/^(?:PLAN|---)/i)) {
3929
+ const descLine = sanitizeKanbanString(trimmed, MAX_KANBAN_NOTES_LENGTH);
3930
+ currentItem.description = currentItem.description ? sanitizeKanbanString(currentItem.description + "\n" + descLine, MAX_KANBAN_NOTES_LENGTH) : descLine;
3931
+ }
3932
+ }
3933
+ if (currentItem) items.push(currentItem);
3934
+ return items;
3935
+ }
3936
+ var VALID_KANBAN_STATUSES = /* @__PURE__ */ new Set(["backlog", "todo", "in_progress", "done"]);
3937
+ var MAX_KANBAN_TITLE_LENGTH = 500;
3938
+ var MAX_KANBAN_NOTES_LENGTH = 2e3;
3939
+ function sanitizeKanbanString(value, maxLen) {
3940
+ if (!value) return "";
3941
+ return value.replace(/[\x00-\x08\x0B\x0C\x0E-\x1F\x7F]/g, "").replace(/\{\{.*?\}\}/g, "").replace(/^(System|Assistant|Human):\s*/gmi, "").replace(/#{2,}/g, "").replace(/\s+/g, " ").trim().slice(0, maxLen);
3942
+ }
3943
+ function sanitizeBoardItem(item) {
3944
+ return {
3945
+ ...item,
3946
+ title: sanitizeKanbanString(item.title, 200),
3947
+ status: sanitizeKanbanString(item.status, 50),
3948
+ ...item.deliverable ? { deliverable: sanitizeKanbanString(item.deliverable, 500) } : {}
3949
+ };
3950
+ }
3951
+ var builtInSkillCache = /* @__PURE__ */ new Map();
3952
+ function getBuiltInSkillContent(skillId) {
3953
+ if (builtInSkillCache.has(skillId)) return builtInSkillCache.get(skillId);
3954
+ try {
3955
+ const candidates = [
3956
+ join12(process.cwd(), "skills", skillId, "SKILL.md"),
3957
+ join12(new URL(".", import.meta.url).pathname, "..", "..", "..", "..", "..", "..", "skills", skillId, "SKILL.md")
3958
+ ];
3959
+ for (const candidate of candidates) {
3960
+ if (existsSync6(candidate)) {
3961
+ const content = readFileSync10(candidate, "utf-8");
3962
+ const files = [{ relativePath: "SKILL.md", content }];
3963
+ builtInSkillCache.set(skillId, files);
3964
+ return files;
3965
+ }
3966
+ }
3967
+ builtInSkillCache.set(skillId, null);
3968
+ return null;
3969
+ } catch {
3970
+ builtInSkillCache.set(skillId, null);
3971
+ return null;
3972
+ }
3973
+ }
3974
+ function parseKanbanUpdates(summary) {
3975
+ const updates = [];
3976
+ const markerMatch = /kanban update:/i.exec(summary);
3977
+ if (!markerMatch) return updates;
3978
+ const kanbanSection = summary.slice(markerMatch.index + markerMatch[0].length);
3979
+ const lines = kanbanSection.split("\n");
3980
+ for (const line of lines) {
3981
+ const trimmed = line.trim();
3982
+ const match = trimmed.match(/^[-*•]\s*"([^"]+)":\s*(backlog|todo|today|in_progress|done)(?:\s*\((.+)\))?/i);
3983
+ if (match) {
3984
+ const rawStatus = match[2].toLowerCase();
3985
+ const status = rawStatus === "today" ? "todo" : rawStatus;
3986
+ if (!VALID_KANBAN_STATUSES.has(status)) continue;
3987
+ const title = sanitizeKanbanString(match[1], MAX_KANBAN_TITLE_LENGTH);
3988
+ if (!title) continue;
3989
+ const parenthetical = match[3] ?? void 0;
3990
+ let notes;
3991
+ let result;
3992
+ if (parenthetical && status === "done") {
3993
+ const resultMatch = parenthetical.match(/^result:\s*(.+)/i);
3994
+ if (resultMatch) {
3995
+ result = sanitizeKanbanString(resultMatch[1], MAX_KANBAN_NOTES_LENGTH);
3996
+ } else {
3997
+ notes = sanitizeKanbanString(parenthetical, MAX_KANBAN_NOTES_LENGTH);
3998
+ }
3999
+ } else if (parenthetical) {
4000
+ notes = sanitizeKanbanString(parenthetical, MAX_KANBAN_NOTES_LENGTH);
4001
+ }
4002
+ updates.push({
4003
+ title,
4004
+ status,
4005
+ notes,
4006
+ result
4007
+ });
4008
+ }
4009
+ }
4010
+ return updates;
4011
+ }
4012
+ function formatBoardForPrompt(items, template) {
4013
+ if (items.length === 0) return "";
4014
+ const priorityLabel = (p) => p === 1 ? "HIGH" : p === 3 ? "LOW" : "MED";
4015
+ const timeLabel = (m) => m ? ` (~${m >= 60 ? `${Math.round(m / 60)}hr` : `${m}min`})` : "";
4016
+ const deliverableLine = (d) => d ? `
4017
+ Deliverable: ${d}` : "";
4018
+ const sourceLine = (channel, thread, url) => {
4019
+ const parts = [];
4020
+ if (channel && thread) parts.push(`${channel} thread ${thread}`);
4021
+ if (url) parts.push(url);
4022
+ return parts.length > 0 ? `
4023
+ source: ${parts.join(" \u2022 ")}` : "";
4024
+ };
4025
+ const grouped = {};
4026
+ for (const item of items) {
4027
+ const key = item.status;
4028
+ if (!grouped[key]) grouped[key] = [];
4029
+ grouped[key].push(item);
4030
+ }
4031
+ const hasSourceThread = items.some(
4032
+ (i) => (i.status === "todo" || i.status === "in_progress") && !!i.source_integration && !!i.source_external_id
4033
+ );
4034
+ const lines = [];
4035
+ if (template === "morning-plan") {
4036
+ lines.push("=== CURRENT BOARD ===");
4037
+ for (const [status, label] of [["backlog", "BACKLOG (carry-over)"], ["todo", "TO DO"], ["in_progress", "IN PROGRESS"]]) {
4038
+ const statusItems = grouped[status];
4039
+ if (statusItems && statusItems.length > 0) {
4040
+ lines.push(`${label}:`);
4041
+ statusItems.forEach((item, i) => {
4042
+ lines.push(` ${i + 1}. [${priorityLabel(item.priority)}] ${item.title}${timeLabel(item.estimated_minutes)}${deliverableLine(item.deliverable)}${sourceLine(item.source_integration, item.source_external_id, item.source_url)}`);
4043
+ });
4044
+ }
4045
+ }
4046
+ lines.push("=====================");
4047
+ lines.push("");
4048
+ lines.push("Create today's plan. You may:");
4049
+ lines.push('- Move backlog items to "todo"');
4050
+ lines.push("- Add new items you've identified");
4051
+ lines.push("- Reprioritise existing items");
4052
+ lines.push("");
4053
+ } else {
4054
+ lines.push("=== YOUR KANBAN BOARD ===");
4055
+ for (const [status, label] of [["todo", "TO DO"], ["in_progress", "IN PROGRESS"], ["backlog", "BACKLOG"]]) {
4056
+ const statusItems = grouped[status];
4057
+ if (statusItems && statusItems.length > 0) {
4058
+ lines.push(`${label}:`);
4059
+ statusItems.forEach((item, i) => {
4060
+ lines.push(` ${i + 1}. [${priorityLabel(item.priority)}] ${item.title}${timeLabel(item.estimated_minutes)}${deliverableLine(item.deliverable)}${sourceLine(item.source_integration, item.source_external_id, item.source_url)}`);
4061
+ });
4062
+ }
4063
+ }
4064
+ const doneItems = grouped["done"];
4065
+ if (doneItems && doneItems.length > 0) {
4066
+ lines.push("DONE TODAY:");
4067
+ doneItems.forEach((item, i) => {
4068
+ lines.push(` ${i + 1}. ${item.title}`);
4069
+ });
4070
+ }
4071
+ lines.push("=========================");
4072
+ lines.push("");
4073
+ lines.push("IMPORTANT: Use kanban MCP tools to update the board IN REAL TIME:");
4074
+ lines.push("1. FIRST call kanban_move to move your chosen item to in_progress BEFORE starting work");
4075
+ lines.push("2. Do the work");
4076
+ lines.push("3. Call kanban_done with a result summary when finished");
4077
+ lines.push("4. If blocked, call kanban_update with notes, then pick the next item");
4078
+ lines.push("");
4079
+ if (hasSourceThread) {
4080
+ lines.push("THREAD CONTINUITY: If a card shows a `source:` line, the request originated");
4081
+ lines.push("in that Slack/Telegram thread. When you deliver the result, reply in that");
4082
+ lines.push("thread (not the default channel) so the user sees the answer where they");
4083
+ lines.push("asked. The card's `source_channel` + `source_thread_id` are the thread");
4084
+ lines.push("coordinates to use.");
4085
+ lines.push("");
4086
+ }
4087
+ lines.push("SELF-MANAGEMENT: When you receive a request from a channel (Slack, Telegram)");
4088
+ lines.push("that takes more than a quick response, create a task first with kanban_add,");
4089
+ lines.push("move to in_progress, do the work, then kanban_done with a result summary.");
4090
+ lines.push("");
4091
+ lines.push("If MCP tools are unavailable, include a KANBAN UPDATE section in your output:");
4092
+ lines.push("KANBAN UPDATE:");
4093
+ lines.push('- "item title": new_status (optional notes)');
4094
+ lines.push('- "item title": done (result: <what you produced>)');
4095
+ lines.push("Statuses: backlog, today, in_progress, done");
4096
+ lines.push("");
4097
+ }
4098
+ return lines.join("\n");
4099
+ }
4100
+
3834
4101
  // src/lib/wedge-detection.ts
3835
4102
  var DEFAULTS = {
3836
4103
  inboundWaitSeconds: 120,
@@ -3970,24 +4237,24 @@ function partitionActionableByPoison(actionable, states, config2) {
3970
4237
  }
3971
4238
 
3972
4239
  // src/lib/restart-flags.ts
3973
- import { existsSync as existsSync6, mkdirSync as mkdirSync3, readdirSync as readdirSync4, readFileSync as readFileSync10, renameSync, rmSync as rmSync2, writeFileSync as writeFileSync3 } from "fs";
4240
+ import { existsSync as existsSync7, mkdirSync as mkdirSync3, readdirSync as readdirSync4, readFileSync as readFileSync11, renameSync, rmSync as rmSync2, writeFileSync as writeFileSync3 } from "fs";
3974
4241
  import { homedir as homedir6 } from "os";
3975
- import { join as join12 } from "path";
4242
+ import { join as join13 } from "path";
3976
4243
  import { randomUUID } from "crypto";
3977
4244
  function restartFlagsDir() {
3978
- return join12(homedir6(), ".augmented", "restart-flags");
4245
+ return join13(homedir6(), ".augmented", "restart-flags");
3979
4246
  }
3980
4247
  function flagPath(codeName) {
3981
- return join12(restartFlagsDir(), `${codeName}.flag`);
4248
+ return join13(restartFlagsDir(), `${codeName}.flag`);
3982
4249
  }
3983
4250
  function readRestartFlags() {
3984
4251
  const dir = restartFlagsDir();
3985
- if (!existsSync6(dir)) return [];
4252
+ if (!existsSync7(dir)) return [];
3986
4253
  const out = [];
3987
4254
  for (const entry of readdirSync4(dir)) {
3988
4255
  if (!entry.endsWith(".flag")) continue;
3989
4256
  try {
3990
- const raw = readFileSync10(join12(dir, entry), "utf8");
4257
+ const raw = readFileSync11(join13(dir, entry), "utf8");
3991
4258
  const parsed = JSON.parse(raw);
3992
4259
  if (typeof parsed.codeName !== "string" || parsed.codeName.length === 0) {
3993
4260
  parsed.codeName = entry.replace(/\.flag$/, "");
@@ -4005,7 +4272,7 @@ function readRestartFlags() {
4005
4272
  }
4006
4273
  function deleteRestartFlag(codeName) {
4007
4274
  const path = flagPath(codeName);
4008
- if (existsSync6(path)) {
4275
+ if (existsSync7(path)) {
4009
4276
  rmSync2(path, { force: true });
4010
4277
  }
4011
4278
  }
@@ -4540,8 +4807,8 @@ function applyRestartAcks(args) {
4540
4807
  var GATEWAY_PORT_BASE = 18800;
4541
4808
  var GATEWAY_PORT_STEP = 10;
4542
4809
  var GATEWAY_PORT_MAX = 18899;
4543
- var AUGMENTED_DIR = join13(process.env["HOME"] ?? "/tmp", ".augmented");
4544
- var GATEWAY_PORTS_FILE = join13(AUGMENTED_DIR, "gateway-ports.json");
4810
+ var AUGMENTED_DIR = join14(process.env["HOME"] ?? "/tmp", ".augmented");
4811
+ var GATEWAY_PORTS_FILE = join14(AUGMENTED_DIR, "gateway-ports.json");
4545
4812
  var CHANNEL_SWEEP_INTERVAL_MS = (() => {
4546
4813
  const raw = parseInt(process.env["AGT_CHANNEL_SWEEP_INTERVAL_MS"] ?? "", 10);
4547
4814
  if (!Number.isFinite(raw)) return 5 * 60 * 1e3;
@@ -5006,7 +5273,7 @@ var runningMcpServerKeys = /* @__PURE__ */ new Map();
5006
5273
  var runningChannelSecretHashes = /* @__PURE__ */ new Map();
5007
5274
  function projectMcpHash(_codeName, projectDir) {
5008
5275
  try {
5009
- const raw = readFileSync11(join13(projectDir, ".mcp.json"), "utf-8");
5276
+ const raw = readFileSync12(join14(projectDir, ".mcp.json"), "utf-8");
5010
5277
  return createHash4("sha256").update(canonicalJson(JSON.parse(raw))).digest("hex");
5011
5278
  } catch {
5012
5279
  return null;
@@ -5014,7 +5281,7 @@ function projectMcpHash(_codeName, projectDir) {
5014
5281
  }
5015
5282
  function projectMcpKeys(_codeName, projectDir) {
5016
5283
  try {
5017
- const raw = readFileSync11(join13(projectDir, ".mcp.json"), "utf-8");
5284
+ const raw = readFileSync12(join14(projectDir, ".mcp.json"), "utf-8");
5018
5285
  const parsed = JSON.parse(raw);
5019
5286
  const servers = parsed.mcpServers;
5020
5287
  if (!servers || typeof servers !== "object") return /* @__PURE__ */ new Set();
@@ -5025,7 +5292,7 @@ function projectMcpKeys(_codeName, projectDir) {
5025
5292
  }
5026
5293
  function readMcpHttpServerConfig(projectDir, serverKey, env) {
5027
5294
  try {
5028
- const raw = readFileSync11(join13(projectDir, ".mcp.json"), "utf-8");
5295
+ const raw = readFileSync12(join14(projectDir, ".mcp.json"), "utf-8");
5029
5296
  const servers = JSON.parse(raw).mcpServers ?? {};
5030
5297
  const entry = servers[serverKey];
5031
5298
  if (entry && typeof entry.url === "string" && (entry.type === "http" || entry.type === void 0)) {
@@ -5063,9 +5330,9 @@ async function runAgentConnectivityProbes(agent, integrations, projectDir) {
5063
5330
  if (integrations.length === 0) return;
5064
5331
  const probeEnv = { ...process.env };
5065
5332
  try {
5066
- const envIntPath = join13(projectDir, ".env.integrations");
5067
- if (existsSync7(envIntPath)) {
5068
- Object.assign(probeEnv, parseEnvIntegrations(readFileSync11(envIntPath, "utf-8")));
5333
+ const envIntPath = join14(projectDir, ".env.integrations");
5334
+ if (existsSync8(envIntPath)) {
5335
+ Object.assign(probeEnv, parseEnvIntegrations(readFileSync12(envIntPath, "utf-8")));
5069
5336
  }
5070
5337
  } catch {
5071
5338
  }
@@ -5270,7 +5537,7 @@ function checkMcpConfigDriftAndScheduleRestart(codeName, projectDir) {
5270
5537
  function projectChannelSecretHash(projectDir) {
5271
5538
  try {
5272
5539
  const entries = parseEnvIntegrations(
5273
- readFileSync11(join13(projectDir, ".env.integrations"), "utf-8")
5540
+ readFileSync12(join14(projectDir, ".env.integrations"), "utf-8")
5274
5541
  );
5275
5542
  return channelSecretValueHash(entries, CHANNEL_SECRET_ENV_KEYS);
5276
5543
  } catch {
@@ -5362,7 +5629,7 @@ var cachedMaintenanceWindow = null;
5362
5629
  var lastVersionCheckAt = 0;
5363
5630
  var VERSION_CHECK_INTERVAL_MS = 5 * 60 * 1e3;
5364
5631
  var lastResponsivenessProbeAt = 0;
5365
- var agtCliVersion = true ? "0.28.24" : "dev";
5632
+ var agtCliVersion = true ? "0.28.26" : "dev";
5366
5633
  function resolveBrewPath(execFileSync4) {
5367
5634
  try {
5368
5635
  const out = execFileSync4("which", ["brew"], { timeout: 5e3 }).toString().trim();
@@ -5375,7 +5642,7 @@ function resolveBrewPath(execFileSync4) {
5375
5642
  "/usr/local/bin/brew"
5376
5643
  ];
5377
5644
  for (const path of fallbacks) {
5378
- if (existsSync7(path)) return path;
5645
+ if (existsSync8(path)) return path;
5379
5646
  }
5380
5647
  return null;
5381
5648
  }
@@ -5385,7 +5652,7 @@ function claudeBinaryInstalled(execFileSync4) {
5385
5652
  "/opt/homebrew/bin/claude",
5386
5653
  "/usr/local/bin/claude"
5387
5654
  ];
5388
- if (canonical.some((path) => existsSync7(path))) return true;
5655
+ if (canonical.some((path) => existsSync8(path))) return true;
5389
5656
  try {
5390
5657
  execFileSync4("which", ["claude"], { timeout: 5e3 });
5391
5658
  return true;
@@ -5538,8 +5805,8 @@ function claudeManagedSettingsPath() {
5538
5805
  function ensureClaudeManagedSettings(path = claudeManagedSettingsPath()) {
5539
5806
  try {
5540
5807
  let settings = {};
5541
- if (existsSync7(path)) {
5542
- const raw = readFileSync11(path, "utf-8").trim();
5808
+ if (existsSync8(path)) {
5809
+ const raw = readFileSync12(path, "utf-8").trim();
5543
5810
  if (raw) {
5544
5811
  let parsed;
5545
5812
  try {
@@ -5601,7 +5868,7 @@ async function ensureFrameworkBinary(frameworkId) {
5601
5868
  if (!process.env.PATH?.split(":").includes(brewBinDir)) {
5602
5869
  process.env.PATH = `${brewBinDir}:${process.env.PATH ?? ""}`;
5603
5870
  }
5604
- if (existsSync7("/home/linuxbrew/.linuxbrew/bin/claude")) {
5871
+ if (existsSync8("/home/linuxbrew/.linuxbrew/bin/claude")) {
5605
5872
  log("Claude Code installed successfully");
5606
5873
  } else {
5607
5874
  log("Claude Code install completed but binary not found at expected path \u2014 check brew logs");
@@ -5613,7 +5880,7 @@ async function ensureFrameworkBinary(frameworkId) {
5613
5880
  var CLAUDE_CODE_UPGRADE_CHECK_INTERVAL_MS = 24 * 60 * 60 * 1e3;
5614
5881
  var claudeCodeUpgradeInFlight = false;
5615
5882
  function claudeCodeUpgradeMarkerPath() {
5616
- return join13(homedir7(), ".augmented", ".last-claude-code-upgrade-check");
5883
+ return join14(homedir7(), ".augmented", ".last-claude-code-upgrade-check");
5617
5884
  }
5618
5885
  function stampClaudeCodeUpgradeMarker() {
5619
5886
  try {
@@ -5623,7 +5890,7 @@ function stampClaudeCodeUpgradeMarker() {
5623
5890
  }
5624
5891
  function claudeCodeUpgradeThrottled() {
5625
5892
  try {
5626
- const lastCheck = parseInt(readFileSync11(claudeCodeUpgradeMarkerPath(), "utf-8").trim(), 10);
5893
+ const lastCheck = parseInt(readFileSync12(claudeCodeUpgradeMarkerPath(), "utf-8").trim(), 10);
5627
5894
  if (!Number.isFinite(lastCheck)) return false;
5628
5895
  return Date.now() - lastCheck < CLAUDE_CODE_UPGRADE_CHECK_INTERVAL_MS;
5629
5896
  } catch {
@@ -5676,7 +5943,7 @@ ${r.stderr}`;
5676
5943
  }
5677
5944
  var UPDATE_CHECK_INTERVAL_MS = 5 * 60 * 1e3;
5678
5945
  function selfUpdateAppliedMarkerPath() {
5679
- return join13(homedir7(), ".augmented", ".last-self-update-applied");
5946
+ return join14(homedir7(), ".augmented", ".last-self-update-applied");
5680
5947
  }
5681
5948
  var selfUpdateUpToDateLogged = false;
5682
5949
  var restartAfterUpgrade = false;
@@ -5699,7 +5966,7 @@ async function checkAndUpdateCli() {
5699
5966
  const isNpmGlobal = !isBrewFormula && resolvedPath.includes("node_modules");
5700
5967
  if (!isBrewFormula && !isNpmGlobal) return;
5701
5968
  const { readFileSync: readF, writeFileSync: writeF } = await import("fs");
5702
- const markerPath = join13(homedir7(), ".augmented", ".last-update-check");
5969
+ const markerPath = join14(homedir7(), ".augmented", ".last-update-check");
5703
5970
  try {
5704
5971
  const lastCheck = parseInt(readF(markerPath, "utf-8").trim(), 10);
5705
5972
  if (Date.now() - lastCheck < UPDATE_CHECK_INTERVAL_MS) return;
@@ -5956,13 +6223,13 @@ async function checkClaudeAuth() {
5956
6223
  }
5957
6224
  var evalEmptyMcpConfigPath = null;
5958
6225
  function ensureEvalEmptyMcpConfig() {
5959
- if (evalEmptyMcpConfigPath && existsSync7(evalEmptyMcpConfigPath)) return evalEmptyMcpConfigPath;
5960
- const dir = join13(homedir7(), ".augmented");
6226
+ if (evalEmptyMcpConfigPath && existsSync8(evalEmptyMcpConfigPath)) return evalEmptyMcpConfigPath;
6227
+ const dir = join14(homedir7(), ".augmented");
5961
6228
  try {
5962
6229
  mkdirSync4(dir, { recursive: true });
5963
6230
  } catch {
5964
6231
  }
5965
- const p = join13(dir, ".eval-empty-mcp.json");
6232
+ const p = join14(dir, ".eval-empty-mcp.json");
5966
6233
  writeFileSync4(p, JSON.stringify({ mcpServers: {} }));
5967
6234
  evalEmptyMcpConfigPath = p;
5968
6235
  return p;
@@ -6037,7 +6304,7 @@ function resolveConversationEvalBackend() {
6037
6304
  }
6038
6305
  function loadGatewayPorts() {
6039
6306
  try {
6040
- return JSON.parse(readFileSync11(GATEWAY_PORTS_FILE, "utf-8"));
6307
+ return JSON.parse(readFileSync12(GATEWAY_PORTS_FILE, "utf-8"));
6041
6308
  } catch {
6042
6309
  return {};
6043
6310
  }
@@ -6067,10 +6334,10 @@ function freePort(codeName) {
6067
6334
  }
6068
6335
  }
6069
6336
  function getStateFile() {
6070
- return join13(config?.configDir ?? join13(process.env["HOME"] ?? "/tmp", ".augmented"), "manager-state.json");
6337
+ return join14(config?.configDir ?? join14(process.env["HOME"] ?? "/tmp", ".augmented"), "manager-state.json");
6071
6338
  }
6072
6339
  function channelHashCacheDir() {
6073
- return config?.configDir ?? join13(process.env["HOME"] ?? "/tmp", ".augmented");
6340
+ return config?.configDir ?? join14(process.env["HOME"] ?? "/tmp", ".augmented");
6074
6341
  }
6075
6342
  function loadChannelHashCache2() {
6076
6343
  loadChannelHashCache(agentState.knownChannelConfigHashes, channelHashCacheDir());
@@ -6081,7 +6348,7 @@ function saveChannelHashCache2() {
6081
6348
  var _channelQuarantineStore = null;
6082
6349
  function channelQuarantineStore() {
6083
6350
  if (!_channelQuarantineStore) {
6084
- const dir = config?.configDir ?? join13(process.env["HOME"] ?? "/tmp", ".augmented");
6351
+ const dir = config?.configDir ?? join14(process.env["HOME"] ?? "/tmp", ".augmented");
6085
6352
  _channelQuarantineStore = new ChannelQuarantineStore(defaultQuarantinePath(dir));
6086
6353
  }
6087
6354
  return _channelQuarantineStore;
@@ -6089,7 +6356,7 @@ function channelQuarantineStore() {
6089
6356
  var _hostFlagStore = null;
6090
6357
  function hostFlagStore() {
6091
6358
  if (!_hostFlagStore) {
6092
- const dir = config?.configDir ?? join13(process.env["HOME"] ?? "/tmp", ".augmented");
6359
+ const dir = config?.configDir ?? join14(process.env["HOME"] ?? "/tmp", ".augmented");
6093
6360
  _hostFlagStore = new HostFlagStore({ cachePath: defaultFlagsCachePath(dir), log });
6094
6361
  }
6095
6362
  return _hostFlagStore;
@@ -6141,12 +6408,12 @@ function parseSkillFrontmatter(content) {
6141
6408
  }
6142
6409
  async function refreshSkillsIndexInClaudeMd(configDir, codeName, log2) {
6143
6410
  const { readdirSync: readdirSync6, readFileSync: rfs, existsSync: ex, writeFileSync: writeFileSync5 } = await import("fs");
6144
- const skillsDir = join13(configDir, codeName, "project", ".claude", "skills");
6145
- const claudeMdPath = join13(configDir, codeName, "project", "CLAUDE.md");
6411
+ const skillsDir = join14(configDir, codeName, "project", ".claude", "skills");
6412
+ const claudeMdPath = join14(configDir, codeName, "project", "CLAUDE.md");
6146
6413
  if (!ex(skillsDir) || !ex(claudeMdPath)) return;
6147
6414
  const entries = [];
6148
6415
  for (const dir of readdirSync6(skillsDir).sort()) {
6149
- const skillFile = join13(skillsDir, dir, "SKILL.md");
6416
+ const skillFile = join14(skillsDir, dir, "SKILL.md");
6150
6417
  if (!ex(skillFile)) continue;
6151
6418
  try {
6152
6419
  const { name, description } = parseSkillFrontmatter(rfs(skillFile, "utf-8"));
@@ -6194,10 +6461,10 @@ ${SKILLS_INDEX_END}`;
6194
6461
  }
6195
6462
  async function migrateToProfiles() {
6196
6463
  const homeDir = process.env["HOME"] ?? "/tmp";
6197
- const sharedConfigPath = join13(homeDir, ".openclaw", "openclaw.json");
6464
+ const sharedConfigPath = join14(homeDir, ".openclaw", "openclaw.json");
6198
6465
  let sharedConfig;
6199
6466
  try {
6200
- sharedConfig = JSON.parse(readFileSync11(sharedConfigPath, "utf-8"));
6467
+ sharedConfig = JSON.parse(readFileSync12(sharedConfigPath, "utf-8"));
6201
6468
  } catch {
6202
6469
  return;
6203
6470
  }
@@ -6210,19 +6477,19 @@ async function migrateToProfiles() {
6210
6477
  const codeName = agentEntry["id"];
6211
6478
  if (!codeName) continue;
6212
6479
  if (codeName === "main") continue;
6213
- const profileDir = join13(homeDir, `.openclaw-${codeName}`);
6214
- if (existsSync7(join13(profileDir, "openclaw.json"))) continue;
6480
+ const profileDir = join14(homeDir, `.openclaw-${codeName}`);
6481
+ if (existsSync8(join14(profileDir, "openclaw.json"))) continue;
6215
6482
  log(`Migrating agent '${codeName}' to per-agent profile`);
6216
6483
  if (adapter.seedProfileConfig) {
6217
6484
  adapter.seedProfileConfig(codeName);
6218
6485
  }
6219
- const sharedAuthDir = join13(homeDir, ".openclaw", "agents", codeName, "agent");
6220
- const profileAuthDir = join13(profileDir, "agents", codeName, "agent");
6221
- const authFile = join13(sharedAuthDir, "auth-profiles.json");
6222
- if (existsSync7(authFile)) {
6486
+ const sharedAuthDir = join14(homeDir, ".openclaw", "agents", codeName, "agent");
6487
+ const profileAuthDir = join14(profileDir, "agents", codeName, "agent");
6488
+ const authFile = join14(sharedAuthDir, "auth-profiles.json");
6489
+ if (existsSync8(authFile)) {
6223
6490
  mkdirSync4(profileAuthDir, { recursive: true });
6224
- const authContent = readFileSync11(authFile, "utf-8");
6225
- writeFileSync4(join13(profileAuthDir, "auth-profiles.json"), authContent);
6491
+ const authContent = readFileSync12(authFile, "utf-8");
6492
+ writeFileSync4(join14(profileAuthDir, "auth-profiles.json"), authContent);
6226
6493
  }
6227
6494
  allocatePort(codeName);
6228
6495
  migrated++;
@@ -6238,7 +6505,7 @@ function readGatewayToken(codeName) {
6238
6505
  }
6239
6506
  const homeDir = process.env["HOME"] ?? "/tmp";
6240
6507
  try {
6241
- const cfg = JSON.parse(readFileSync11(join13(homeDir, `.openclaw-${codeName}`, "openclaw.json"), "utf-8"));
6508
+ const cfg = JSON.parse(readFileSync12(join14(homeDir, `.openclaw-${codeName}`, "openclaw.json"), "utf-8"));
6242
6509
  return cfg?.gateway?.auth?.token;
6243
6510
  } catch {
6244
6511
  return void 0;
@@ -6247,10 +6514,10 @@ function readGatewayToken(codeName) {
6247
6514
  var GATEWAY_HUNG_TIMEOUT_MS = 5 * 6e4;
6248
6515
  function isGatewayHung(codeName) {
6249
6516
  const homeDir = process.env["HOME"] ?? "/tmp";
6250
- const jobsPath = join13(homeDir, `.openclaw-${codeName}`, "cron", "jobs.json");
6251
- if (!existsSync7(jobsPath)) return false;
6517
+ const jobsPath = join14(homeDir, `.openclaw-${codeName}`, "cron", "jobs.json");
6518
+ if (!existsSync8(jobsPath)) return false;
6252
6519
  try {
6253
- const data = JSON.parse(readFileSync11(jobsPath, "utf-8"));
6520
+ const data = JSON.parse(readFileSync12(jobsPath, "utf-8"));
6254
6521
  const jobs = data.jobs ?? data;
6255
6522
  if (!Array.isArray(jobs)) return false;
6256
6523
  const now = Date.now();
@@ -6283,15 +6550,15 @@ async function ensureGatewayRunning(codeName, adapter) {
6283
6550
  }
6284
6551
  await new Promise((r) => setTimeout(r, 2e3));
6285
6552
  const homeDir = process.env["HOME"] ?? "/tmp";
6286
- const cronJobsPath = join13(homeDir, `.openclaw-${codeName}`, "cron", "jobs.json");
6553
+ const cronJobsPath = join14(homeDir, `.openclaw-${codeName}`, "cron", "jobs.json");
6287
6554
  clearStaleCronRunState(cronJobsPath);
6288
6555
  } else {
6289
6556
  if (status.port) {
6290
6557
  try {
6291
6558
  const homeDir = process.env["HOME"] ?? "/tmp";
6292
- const configPath = join13(homeDir, `.openclaw-${codeName}`, "openclaw.json");
6293
- if (existsSync7(configPath)) {
6294
- const cfg = JSON.parse(readFileSync11(configPath, "utf-8"));
6559
+ const configPath = join14(homeDir, `.openclaw-${codeName}`, "openclaw.json");
6560
+ if (existsSync8(configPath)) {
6561
+ const cfg = JSON.parse(readFileSync12(configPath, "utf-8"));
6295
6562
  if (cfg.gateway?.port !== status.port) {
6296
6563
  if (!cfg.gateway) cfg.gateway = {};
6297
6564
  cfg.gateway.port = status.port;
@@ -6315,9 +6582,9 @@ async function ensureGatewayRunning(codeName, adapter) {
6315
6582
  gatewaysStartedThisCycle.add(codeName);
6316
6583
  try {
6317
6584
  const homeDir = process.env["HOME"] ?? "/tmp";
6318
- const configPath = join13(homeDir, `.openclaw-${codeName}`, "openclaw.json");
6319
- if (existsSync7(configPath)) {
6320
- const cfg = JSON.parse(readFileSync11(configPath, "utf-8"));
6585
+ const configPath = join14(homeDir, `.openclaw-${codeName}`, "openclaw.json");
6586
+ if (existsSync8(configPath)) {
6587
+ const cfg = JSON.parse(readFileSync12(configPath, "utf-8"));
6321
6588
  if (!cfg.gateway) cfg.gateway = {};
6322
6589
  cfg.gateway.port = port;
6323
6590
  writeFileSync4(configPath, JSON.stringify(cfg, null, 2));
@@ -6873,7 +7140,7 @@ async function pollCycle() {
6873
7140
  }
6874
7141
  killAgentChannelProcesses(prev.codeName, { log });
6875
7142
  freePort(prev.codeName);
6876
- const agentDir = join13(adapter.getAgentDir(prev.codeName), "provision");
7143
+ const agentDir = join14(adapter.getAgentDir(prev.codeName), "provision");
6877
7144
  await cleanupAgentFiles(prev.codeName, agentDir);
6878
7145
  clearAgentCaches(prev.agentId, prev.codeName);
6879
7146
  }
@@ -6959,10 +7226,10 @@ async function pollCycle() {
6959
7226
  // pending-inbound marker. Best-effort: a write failure is logged by
6960
7227
  // the watchdog, never fails the poll cycle.
6961
7228
  signalGiveUp: (codeName) => {
6962
- const dir = join13(homedir7(), ".augmented", codeName);
6963
- if (!existsSync7(dir)) return;
7229
+ const dir = join14(homedir7(), ".augmented", codeName);
7230
+ if (!existsSync8(dir)) return;
6964
7231
  atomicWriteFileSync(
6965
- join13(dir, "watchdog-give-up.json"),
7232
+ join14(dir, "watchdog-give-up.json"),
6966
7233
  JSON.stringify({ gave_up_at: (/* @__PURE__ */ new Date()).toISOString() })
6967
7234
  );
6968
7235
  }
@@ -7089,7 +7356,7 @@ async function processAgent(agent, agentStates) {
7089
7356
  }
7090
7357
  const now = (/* @__PURE__ */ new Date()).toISOString();
7091
7358
  const adapter = resolveAgentFramework(agent.code_name);
7092
- let agentDir = join13(adapter.getAgentDir(agent.code_name), "provision");
7359
+ let agentDir = join14(adapter.getAgentDir(agent.code_name), "provision");
7093
7360
  if (agent.status === "draft" || agent.status === "paused") {
7094
7361
  if (previousKnownStatus !== agent.status) {
7095
7362
  log(`Agent '${agent.code_name}' is ${agent.status}, skipping provisioning`);
@@ -7141,7 +7408,7 @@ async function processAgent(agent, agentStates) {
7141
7408
  const residuals = {
7142
7409
  gatewayRunning: gatewayLiveness.running,
7143
7410
  portAllocated: Object.prototype.hasOwnProperty.call(ports, agent.code_name),
7144
- provisionDirExists: existsSync7(agentDir)
7411
+ provisionDirExists: existsSync8(agentDir)
7145
7412
  };
7146
7413
  if (!hasRevokedResiduals(residuals)) {
7147
7414
  agentStates.push({
@@ -7293,7 +7560,7 @@ async function processAgent(agent, agentStates) {
7293
7560
  const frameworkId = refreshData.agent.framework ?? "openclaw";
7294
7561
  agentFrameworkCache.set(agent.code_name, frameworkId);
7295
7562
  const frameworkAdapter = getFramework(frameworkId);
7296
- agentDir = join13(frameworkAdapter.getAgentDir(agent.code_name), "provision");
7563
+ agentDir = join14(frameworkAdapter.getAgentDir(agent.code_name), "provision");
7297
7564
  cacheAgentDeliveryMetadata(agent.code_name, refreshData);
7298
7565
  if (frameworkAdapter.migrateSecretStorage && !migratedSecretStorage.has(agent.code_name)) {
7299
7566
  try {
@@ -7336,7 +7603,7 @@ async function processAgent(agent, agentStates) {
7336
7603
  const changedFiles = [];
7337
7604
  mkdirSync4(agentDir, { recursive: true });
7338
7605
  for (const artifact of artifacts) {
7339
- const filePath = join13(agentDir, artifact.relativePath);
7606
+ const filePath = join14(agentDir, artifact.relativePath);
7340
7607
  let existingHash;
7341
7608
  let newHash;
7342
7609
  let writeContent = artifact.content;
@@ -7355,8 +7622,8 @@ async function processAgent(agent, agentStates) {
7355
7622
  };
7356
7623
  newHash = sha256(stripDynamicSections(artifact.content));
7357
7624
  try {
7358
- const projectClaudeMd = join13(config.configDir, agent.code_name, "project", "CLAUDE.md");
7359
- const existing = readFileSync11(projectClaudeMd, "utf-8");
7625
+ const projectClaudeMd = join14(config.configDir, agent.code_name, "project", "CLAUDE.md");
7626
+ const existing = readFileSync12(projectClaudeMd, "utf-8");
7360
7627
  existingHash = sha256(stripDynamicSections(existing));
7361
7628
  } catch {
7362
7629
  existingHash = null;
@@ -7374,7 +7641,7 @@ async function processAgent(agent, agentStates) {
7374
7641
  const generatorKeys = Object.keys(generatorServers);
7375
7642
  let existingRaw = "";
7376
7643
  try {
7377
- existingRaw = readFileSync11(filePath, "utf-8");
7644
+ existingRaw = readFileSync12(filePath, "utf-8");
7378
7645
  } catch {
7379
7646
  }
7380
7647
  const existingServers = parseMcp(existingRaw);
@@ -7396,12 +7663,12 @@ async function processAgent(agent, agentStates) {
7396
7663
  }
7397
7664
  }
7398
7665
  if (changedFiles.length > 0) {
7399
- const isFirst = !existsSync7(join13(agentDir, "CHARTER.md"));
7666
+ const isFirst = !existsSync8(join14(agentDir, "CHARTER.md"));
7400
7667
  const verb = isFirst ? "Provisioning" : "Updating";
7401
7668
  const fileNames = changedFiles.map((f) => f.relativePath).join(", ");
7402
7669
  log(`${verb} '${agent.code_name}': ${fileNames}`);
7403
7670
  for (const file of changedFiles) {
7404
- const filePath = join13(agentDir, file.relativePath);
7671
+ const filePath = join14(agentDir, file.relativePath);
7405
7672
  mkdirSync4(dirname3(filePath), { recursive: true });
7406
7673
  if (file.relativePath === ".mcp.json") {
7407
7674
  safeWriteJsonAtomic(filePath, file.content, { mode: 384 });
@@ -7410,12 +7677,12 @@ async function processAgent(agent, agentStates) {
7410
7677
  }
7411
7678
  }
7412
7679
  try {
7413
- const provSkillsDir = join13(agentDir, ".claude", "skills");
7414
- if (existsSync7(provSkillsDir)) {
7680
+ const provSkillsDir = join14(agentDir, ".claude", "skills");
7681
+ if (existsSync8(provSkillsDir)) {
7415
7682
  for (const folder of readdirSync5(provSkillsDir)) {
7416
7683
  if (folder.startsWith("knowledge-")) {
7417
7684
  try {
7418
- rmSync3(join13(provSkillsDir, folder), { recursive: true });
7685
+ rmSync3(join14(provSkillsDir, folder), { recursive: true });
7419
7686
  } catch {
7420
7687
  }
7421
7688
  }
@@ -7428,7 +7695,7 @@ async function processAgent(agent, agentStates) {
7428
7695
  const trackedFiles2 = frameworkAdapter.driftTrackedFiles();
7429
7696
  const hashes = /* @__PURE__ */ new Map();
7430
7697
  for (const file of trackedFiles2) {
7431
- const h = hashFile(join13(agentDir, file));
7698
+ const h = hashFile(join14(agentDir, file));
7432
7699
  if (h) hashes.set(file, h);
7433
7700
  }
7434
7701
  agentState.writtenHashes.set(agent.agent_id, hashes);
@@ -7446,14 +7713,14 @@ async function processAgent(agent, agentStates) {
7446
7713
  }
7447
7714
  if (Array.isArray(refreshData.workflows)) {
7448
7715
  try {
7449
- const provWorkflowsDir = join13(agentDir, ".claude", "workflows");
7450
- if (existsSync7(provWorkflowsDir)) {
7716
+ const provWorkflowsDir = join14(agentDir, ".claude", "workflows");
7717
+ if (existsSync8(provWorkflowsDir)) {
7451
7718
  const expected = new Set(refreshData.workflows.map((w) => `${w.name}.js`));
7452
7719
  for (const file of readdirSync5(provWorkflowsDir)) {
7453
7720
  if (!file.endsWith(".js")) continue;
7454
7721
  if (expected.has(file)) continue;
7455
7722
  try {
7456
- rmSync3(join13(provWorkflowsDir, file));
7723
+ rmSync3(join14(provWorkflowsDir, file));
7457
7724
  } catch {
7458
7725
  }
7459
7726
  }
@@ -7510,10 +7777,10 @@ async function processAgent(agent, agentStates) {
7510
7777
  }
7511
7778
  let lastDriftCheckAt = now;
7512
7779
  const written = agentState.writtenHashes.get(agent.agent_id);
7513
- if (written && existsSync7(agentDir)) {
7780
+ if (written && existsSync8(agentDir)) {
7514
7781
  const driftedFiles = [];
7515
7782
  for (const [file, expectedHash] of written) {
7516
- const localHash = hashFile(join13(agentDir, file));
7783
+ const localHash = hashFile(join14(agentDir, file));
7517
7784
  if (localHash && localHash !== expectedHash) {
7518
7785
  driftedFiles.push(file);
7519
7786
  }
@@ -7524,7 +7791,7 @@ async function processAgent(agent, agentStates) {
7524
7791
  try {
7525
7792
  const localHashes = {};
7526
7793
  for (const file of driftedFiles) {
7527
- localHashes[file] = hashFile(join13(agentDir, file));
7794
+ localHashes[file] = hashFile(join14(agentDir, file));
7528
7795
  }
7529
7796
  await api.post("/host/drift", {
7530
7797
  agent_id: agent.agent_id,
@@ -7848,24 +8115,24 @@ async function processAgent(agent, agentStates) {
7848
8115
  if (agentSessionMode === "persistent" && (agentFrameworkCache.get(agent.code_name) ?? "openclaw") === "claude-code") {
7849
8116
  try {
7850
8117
  const agentProvisionDir = agentDir;
7851
- const projectDir = join13(homedir7(), ".augmented", agent.code_name, "project");
8118
+ const projectDir = join14(homedir7(), ".augmented", agent.code_name, "project");
7852
8119
  mkdirSync4(agentProvisionDir, { recursive: true });
7853
8120
  mkdirSync4(projectDir, { recursive: true });
7854
- const provisionMcpPath = join13(agentProvisionDir, ".mcp.json");
7855
- const projectMcpPath = join13(projectDir, ".mcp.json");
8121
+ const provisionMcpPath = join14(agentProvisionDir, ".mcp.json");
8122
+ const projectMcpPath = join14(projectDir, ".mcp.json");
7856
8123
  let mcpConfig = { mcpServers: {} };
7857
8124
  try {
7858
- mcpConfig = JSON.parse(readFileSync11(provisionMcpPath, "utf-8"));
8125
+ mcpConfig = JSON.parse(readFileSync12(provisionMcpPath, "utf-8"));
7859
8126
  if (!mcpConfig.mcpServers) mcpConfig.mcpServers = {};
7860
8127
  } catch {
7861
8128
  }
7862
- const localDirectChatChannel = join13(homedir7(), ".augmented", "_mcp", "direct-chat-channel.js");
8129
+ const localDirectChatChannel = join14(homedir7(), ".augmented", "_mcp", "direct-chat-channel.js");
7863
8130
  const directChatTeamSettings = refreshData.team?.settings;
7864
8131
  const directChatTz = (() => {
7865
8132
  const tz = directChatTeamSettings?.["timezone"];
7866
8133
  return typeof tz === "string" && tz.trim() !== "" ? tz.trim() : void 0;
7867
8134
  })();
7868
- if (existsSync7(localDirectChatChannel)) {
8135
+ if (existsSync8(localDirectChatChannel)) {
7869
8136
  const directChatEnv = {
7870
8137
  AGT_HOST: requireHost(),
7871
8138
  // ENG-5901 Track D: templated — the manager exports the real
@@ -7889,8 +8156,8 @@ async function processAgent(agent, agentStates) {
7889
8156
  log(`Channel credentials written for '${agent.code_name}/direct-chat'`);
7890
8157
  }
7891
8158
  }
7892
- const staleChannelsPath = join13(projectDir, ".mcp-channels.json");
7893
- if (existsSync7(staleChannelsPath)) {
8159
+ const staleChannelsPath = join14(projectDir, ".mcp-channels.json");
8160
+ if (existsSync8(staleChannelsPath)) {
7894
8161
  try {
7895
8162
  rmSync3(staleChannelsPath, { force: true });
7896
8163
  } catch {
@@ -7954,7 +8221,7 @@ async function processAgent(agent, agentStates) {
7954
8221
  }
7955
8222
  if (process.env.AGT_CONNECTIVITY_PROBE_ENABLED === "true") {
7956
8223
  try {
7957
- const probeProjectDir = join13(homedir7(), ".augmented", agent.code_name, "project");
8224
+ const probeProjectDir = join14(homedir7(), ".augmented", agent.code_name, "project");
7958
8225
  await runAgentConnectivityProbes(agent, integrations, probeProjectDir);
7959
8226
  } catch (err) {
7960
8227
  log(`Connectivity probe failed for '${agent.code_name}': ${err.message}`);
@@ -7972,11 +8239,11 @@ async function processAgent(agent, agentStates) {
7972
8239
  recordConfigChurnEvent(agent.agent_id, agent.code_name, FLAP_CHANNEL_INTEGRATIONS, intMembership);
7973
8240
  }
7974
8241
  if (intHash !== prevIntHash) {
7975
- const projectDir = join13(homedir7(), ".augmented", agent.code_name, "project");
7976
- const envIntPath = join13(projectDir, ".env.integrations");
8242
+ const projectDir = join14(homedir7(), ".augmented", agent.code_name, "project");
8243
+ const envIntPath = join14(projectDir, ".env.integrations");
7977
8244
  let preWriteEnv;
7978
8245
  try {
7979
- preWriteEnv = readFileSync11(envIntPath, "utf-8");
8246
+ preWriteEnv = readFileSync12(envIntPath, "utf-8");
7980
8247
  } catch {
7981
8248
  preWriteEnv = void 0;
7982
8249
  }
@@ -7988,9 +8255,9 @@ async function processAgent(agent, agentStates) {
7988
8255
  let rotationHandled = true;
7989
8256
  if (fw === "claude-code" && isSessionHealthy(agent.code_name)) {
7990
8257
  try {
7991
- const projectMcpPath = join13(projectDir, ".mcp.json");
7992
- const postWriteEnv = readFileSync11(envIntPath, "utf-8");
7993
- const mcpContent = readFileSync11(projectMcpPath, "utf-8");
8258
+ const projectMcpPath = join14(projectDir, ".mcp.json");
8259
+ const postWriteEnv = readFileSync12(envIntPath, "utf-8");
8260
+ const mcpContent = readFileSync12(projectMcpPath, "utf-8");
7994
8261
  const changedVars = diffEnvIntegrations(preWriteEnv, postWriteEnv);
7995
8262
  const mcpJsonForReap = JSON.parse(mcpContent);
7996
8263
  const affectedServerKeys = findMcpServersUsingVars(mcpJsonForReap, changedVars);
@@ -8070,8 +8337,8 @@ async function processAgent(agent, agentStates) {
8070
8337
  const mcpPath = frameworkAdapter.getMcpPath(agent.code_name);
8071
8338
  if (mcpPath) {
8072
8339
  try {
8073
- const { readFileSync: readFileSync12 } = await import("fs");
8074
- const mcpConfig = JSON.parse(readFileSync12(mcpPath, "utf-8"));
8340
+ const { readFileSync: readFileSync13 } = await import("fs");
8341
+ const mcpConfig = JSON.parse(readFileSync13(mcpPath, "utf-8"));
8075
8342
  if (mcpConfig.mcpServers) {
8076
8343
  const managedPrefixes = [
8077
8344
  "composio_",
@@ -8172,8 +8439,8 @@ async function processAgent(agent, agentStates) {
8172
8439
  if (agent.status === "active") {
8173
8440
  if (frameworkAdapter.installPlugin) {
8174
8441
  try {
8175
- const pluginPath = join13(process.cwd(), "packages", "openclaw-plugin-augmented", "src", "index.ts");
8176
- if (existsSync7(pluginPath)) {
8442
+ const pluginPath = join14(process.cwd(), "packages", "openclaw-plugin-augmented", "src", "index.ts");
8443
+ if (existsSync8(pluginPath)) {
8177
8444
  frameworkAdapter.installPlugin(agent.code_name, "augmented", pluginPath, {
8178
8445
  agtHost: requireHost(),
8179
8446
  agtApiKey: getApiKey() ?? void 0,
@@ -8243,16 +8510,16 @@ async function processAgent(agent, agentStates) {
8243
8510
  const frameworkId2 = frameworkAdapter.id;
8244
8511
  const candidateSkillDirs = [
8245
8512
  // Claude Code — framework runtime tree
8246
- join13(homedir8(), ".augmented", agent.code_name, "skills"),
8513
+ join14(homedir8(), ".augmented", agent.code_name, "skills"),
8247
8514
  // Claude Code — project tree
8248
- join13(homedir8(), ".augmented", agent.code_name, "project", ".claude", "skills"),
8515
+ join14(homedir8(), ".augmented", agent.code_name, "project", ".claude", "skills"),
8249
8516
  // OpenClaw — framework runtime tree
8250
- join13(homedir8(), `.openclaw-${agent.code_name}`, "skills"),
8517
+ join14(homedir8(), `.openclaw-${agent.code_name}`, "skills"),
8251
8518
  // Defensive: legacy provision-side path, not currently an
8252
8519
  // install target but cheap to sweep.
8253
- join13(agentDir, ".claude", "skills")
8520
+ join14(agentDir, ".claude", "skills")
8254
8521
  ];
8255
- const existingDirs = candidateSkillDirs.filter((d) => existsSync7(d));
8522
+ const existingDirs = candidateSkillDirs.filter((d) => existsSync8(d));
8256
8523
  const discoveredEntries = /* @__PURE__ */ new Set();
8257
8524
  for (const dir of existingDirs) {
8258
8525
  try {
@@ -8266,8 +8533,8 @@ async function processAgent(agent, agentStates) {
8266
8533
  }
8267
8534
  const removeSkillFolder = (entry, reason) => {
8268
8535
  for (const dir of existingDirs) {
8269
- const p = join13(dir, entry);
8270
- if (existsSync7(p)) {
8536
+ const p = join14(dir, entry);
8537
+ if (existsSync8(p)) {
8271
8538
  rmSync4(p, { recursive: true, force: true });
8272
8539
  }
8273
8540
  }
@@ -8297,15 +8564,15 @@ async function processAgent(agent, agentStates) {
8297
8564
  const { rmSync: rmSync4 } = await import("fs");
8298
8565
  const { homedir: homedir8 } = await import("os");
8299
8566
  const globalSkillDirs = [
8300
- join13(homedir8(), ".augmented", agent.code_name, "skills"),
8301
- join13(homedir8(), ".augmented", agent.code_name, "project", ".claude", "skills"),
8302
- join13(homedir8(), `.openclaw-${agent.code_name}`, "skills"),
8303
- join13(agentDir, ".claude", "skills")
8567
+ join14(homedir8(), ".augmented", agent.code_name, "skills"),
8568
+ join14(homedir8(), ".augmented", agent.code_name, "project", ".claude", "skills"),
8569
+ join14(homedir8(), `.openclaw-${agent.code_name}`, "skills"),
8570
+ join14(agentDir, ".claude", "skills")
8304
8571
  ];
8305
8572
  for (const id of plan.removes) {
8306
8573
  for (const dir of globalSkillDirs) {
8307
- const p = join13(dir, id);
8308
- if (existsSync7(p)) rmSync4(p, { recursive: true, force: true });
8574
+ const p = join14(dir, id);
8575
+ if (existsSync8(p)) rmSync4(p, { recursive: true, force: true });
8309
8576
  }
8310
8577
  agentState.knownSkillHashes.delete(`global-skill:${agent.agent_id}:${id}`);
8311
8578
  log(`Removed unpublished global skill '${id}' for '${agent.code_name}'`);
@@ -8480,8 +8747,8 @@ async function processAgent(agent, agentStates) {
8480
8747
  const sess = getSessionState(agent.code_name);
8481
8748
  let mcpJsonParsed = null;
8482
8749
  try {
8483
- const mcpPath = join13(getProjectDir(agent.code_name), ".mcp.json");
8484
- mcpJsonParsed = JSON.parse(readFileSync11(mcpPath, "utf-8"));
8750
+ const mcpPath = join14(getProjectDir(agent.code_name), ".mcp.json");
8751
+ mcpJsonParsed = JSON.parse(readFileSync12(mcpPath, "utf-8"));
8485
8752
  } catch {
8486
8753
  }
8487
8754
  reapMissingMcpSessions({
@@ -8690,10 +8957,10 @@ async function processAgent(agent, agentStates) {
8690
8957
  lastWorkTriggerAt.set(agent.code_name, triggerTs);
8691
8958
  if (agentFw === "openclaw" && gatewayRunning && gatewayPort) {
8692
8959
  const homeDir = process.env["HOME"] ?? "/tmp";
8693
- const jobsPath = join13(homeDir, `.openclaw-${agent.code_name}`, "cron", "jobs.json");
8694
- if (existsSync7(jobsPath)) {
8960
+ const jobsPath = join14(homeDir, `.openclaw-${agent.code_name}`, "cron", "jobs.json");
8961
+ if (existsSync8(jobsPath)) {
8695
8962
  try {
8696
- const jobsData = JSON.parse(readFileSync11(jobsPath, "utf-8"));
8963
+ const jobsData = JSON.parse(readFileSync12(jobsPath, "utf-8"));
8697
8964
  const kanbanJob = (jobsData.jobs ?? []).find(
8698
8965
  (j) => typeof j.name === "string" && j.name.includes("kanban-work")
8699
8966
  );
@@ -8827,10 +9094,10 @@ In progress for ${age} minutes \u2014 auto-failed`).catch(() => {
8827
9094
  }
8828
9095
  }
8829
9096
  const trackedFiles = frameworkAdapter.driftTrackedFiles();
8830
- if (trackedFiles.length > 0 && existsSync7(agentDir)) {
9097
+ if (trackedFiles.length > 0 && existsSync8(agentDir)) {
8831
9098
  const hashes = /* @__PURE__ */ new Map();
8832
9099
  for (const file of trackedFiles) {
8833
- const h = hashFile(join13(agentDir, file));
9100
+ const h = hashFile(join14(agentDir, file));
8834
9101
  if (h) hashes.set(file, h);
8835
9102
  }
8836
9103
  agentState.writtenHashes.set(agent.agent_id, hashes);
@@ -8864,19 +9131,19 @@ function cleanupStaleSessions(codeName) {
8864
9131
  lastCleanupAt.set(codeName, Date.now());
8865
9132
  const homeDir = process.env["HOME"] ?? "/tmp";
8866
9133
  for (const agentDir of ["main", codeName]) {
8867
- const sessionsDir = join13(homeDir, `.openclaw-${codeName}`, "agents", agentDir, "sessions");
9134
+ const sessionsDir = join14(homeDir, `.openclaw-${codeName}`, "agents", agentDir, "sessions");
8868
9135
  cleanupCronSessions(sessionsDir, CRON_SESSION_KEEP_COUNT);
8869
9136
  }
8870
- const cronRunsDir = join13(homeDir, `.openclaw-${codeName}`, "cron", "runs");
9137
+ const cronRunsDir = join14(homeDir, `.openclaw-${codeName}`, "cron", "runs");
8871
9138
  cleanupOldFiles(cronRunsDir, CRON_RUN_RETENTION_DAYS, ".jsonl");
8872
- const cronJobsPath = join13(homeDir, `.openclaw-${codeName}`, "cron", "jobs.json");
9139
+ const cronJobsPath = join14(homeDir, `.openclaw-${codeName}`, "cron", "jobs.json");
8873
9140
  clearStaleCronRunState(cronJobsPath);
8874
9141
  }
8875
9142
  function cleanupCronSessions(sessionsDir, keepCount) {
8876
- const indexPath = join13(sessionsDir, "sessions.json");
8877
- if (!existsSync7(indexPath)) return;
9143
+ const indexPath = join14(sessionsDir, "sessions.json");
9144
+ if (!existsSync8(indexPath)) return;
8878
9145
  try {
8879
- const raw = readFileSync11(indexPath, "utf-8");
9146
+ const raw = readFileSync12(indexPath, "utf-8");
8880
9147
  const index = JSON.parse(raw);
8881
9148
  const cronRunKeys = Object.keys(index).filter((k) => k.includes(":cron:") && k.includes(":run:")).map((k) => ({
8882
9149
  key: k,
@@ -8889,9 +9156,9 @@ function cleanupCronSessions(sessionsDir, keepCount) {
8889
9156
  for (const entry of toDelete) {
8890
9157
  delete index[entry.key];
8891
9158
  if (entry.sessionId) {
8892
- const sessionFile = join13(sessionsDir, `${entry.sessionId}.jsonl`);
9159
+ const sessionFile = join14(sessionsDir, `${entry.sessionId}.jsonl`);
8893
9160
  try {
8894
- if (existsSync7(sessionFile)) {
9161
+ if (existsSync8(sessionFile)) {
8895
9162
  unlinkSync(sessionFile);
8896
9163
  deletedFiles++;
8897
9164
  }
@@ -8911,8 +9178,8 @@ function cleanupCronSessions(sessionsDir, keepCount) {
8911
9178
  delete index[parentKey];
8912
9179
  if (parentSessionId) {
8913
9180
  try {
8914
- const f = join13(sessionsDir, `${parentSessionId}.jsonl`);
8915
- if (existsSync7(f)) {
9181
+ const f = join14(sessionsDir, `${parentSessionId}.jsonl`);
9182
+ if (existsSync8(f)) {
8916
9183
  unlinkSync(f);
8917
9184
  deletedFiles++;
8918
9185
  }
@@ -8930,9 +9197,9 @@ function cleanupCronSessions(sessionsDir, keepCount) {
8930
9197
  }
8931
9198
  var STALE_RUN_TIMEOUT_MS = 5 * 6e4;
8932
9199
  function clearStaleCronRunState(jobsPath) {
8933
- if (!existsSync7(jobsPath)) return;
9200
+ if (!existsSync8(jobsPath)) return;
8934
9201
  try {
8935
- const raw = readFileSync11(jobsPath, "utf-8");
9202
+ const raw = readFileSync12(jobsPath, "utf-8");
8936
9203
  const data = JSON.parse(raw);
8937
9204
  const jobs = data.jobs ?? data;
8938
9205
  if (!Array.isArray(jobs)) return;
@@ -8963,13 +9230,13 @@ function clearStaleCronRunState(jobsPath) {
8963
9230
  }
8964
9231
  }
8965
9232
  function cleanupOldFiles(dir, maxAgeDays, ext) {
8966
- if (!existsSync7(dir)) return;
9233
+ if (!existsSync8(dir)) return;
8967
9234
  const cutoff = Date.now() - maxAgeDays * 24 * 60 * 60 * 1e3;
8968
9235
  let removed = 0;
8969
9236
  try {
8970
9237
  for (const f of readdirSync5(dir)) {
8971
9238
  if (!f.endsWith(ext)) continue;
8972
- const fullPath = join13(dir, f);
9239
+ const fullPath = join14(dir, f);
8973
9240
  try {
8974
9241
  const st = statSync4(fullPath);
8975
9242
  if (st.mtimeMs < cutoff) {
@@ -9009,7 +9276,7 @@ var inFlightClaudeTasks = /* @__PURE__ */ new Set();
9009
9276
  var claudeTaskConcurrency = /* @__PURE__ */ new Map();
9010
9277
  var MAX_CLAUDE_CONCURRENCY = 2;
9011
9278
  function claudePidFilePath() {
9012
- return join13(homedir7(), ".augmented", "manager-claude-pids.json");
9279
+ return join14(homedir7(), ".augmented", "manager-claude-pids.json");
9013
9280
  }
9014
9281
  var inFlightClaudePids = /* @__PURE__ */ new Map();
9015
9282
  function registerClaudeSpawn(record) {
@@ -9349,7 +9616,7 @@ async function fireScheduledTaskViaKanban(codeName, agentId, task, prompt) {
9349
9616
  }
9350
9617
  async function executeAndProcessClaudeTask(codeName, agentId, task, prompt) {
9351
9618
  const projectDir = getProjectDir2(codeName);
9352
- const mcpConfigPath = join13(projectDir, ".mcp.json");
9619
+ const mcpConfigPath = join14(projectDir, ".mcp.json");
9353
9620
  let runId = null;
9354
9621
  let kanbanItemId = null;
9355
9622
  let taskResult;
@@ -9357,11 +9624,11 @@ async function executeAndProcessClaudeTask(codeName, agentId, task, prompt) {
9357
9624
  const priorRuns = await fetchPriorScheduledRuns(agentId, task.taskId);
9358
9625
  prompt = wrapScheduledTaskPrompt(prompt, { priorRuns });
9359
9626
  try {
9360
- const claudeMdPath = join13(projectDir, "CLAUDE.md");
9627
+ const claudeMdPath = join14(projectDir, "CLAUDE.md");
9361
9628
  const serverNames = [];
9362
- if (existsSync7(mcpConfigPath)) {
9629
+ if (existsSync8(mcpConfigPath)) {
9363
9630
  try {
9364
- const d = JSON.parse(readFileSync11(mcpConfigPath, "utf-8"));
9631
+ const d = JSON.parse(readFileSync12(mcpConfigPath, "utf-8"));
9365
9632
  if (d.mcpServers) serverNames.push(...Object.keys(d.mcpServers));
9366
9633
  } catch {
9367
9634
  }
@@ -9380,14 +9647,14 @@ async function executeAndProcessClaudeTask(codeName, agentId, task, prompt) {
9380
9647
  "--allowedTools",
9381
9648
  allowedTools
9382
9649
  ];
9383
- if (existsSync7(claudeMdPath)) {
9650
+ if (existsSync8(claudeMdPath)) {
9384
9651
  claudeArgs.push("--system-prompt-file", claudeMdPath);
9385
9652
  }
9386
9653
  const childEnv = { ...process.env };
9387
- const envIntPath = join13(projectDir, ".env.integrations");
9388
- if (existsSync7(envIntPath)) {
9654
+ const envIntPath = join14(projectDir, ".env.integrations");
9655
+ if (existsSync8(envIntPath)) {
9389
9656
  try {
9390
- Object.assign(childEnv, parseEnvIntegrations(readFileSync11(envIntPath, "utf-8")));
9657
+ Object.assign(childEnv, parseEnvIntegrations(readFileSync12(envIntPath, "utf-8")));
9391
9658
  } catch {
9392
9659
  }
9393
9660
  }
@@ -9559,8 +9826,8 @@ var claudeAuthTupleBySession = /* @__PURE__ */ new Map();
9559
9826
  async function ensurePersistentSession(agent, tasks, boardItems, refreshData) {
9560
9827
  const codeName = agent.code_name;
9561
9828
  const projectDir = getProjectDir(codeName);
9562
- const mcpConfigPath = join13(projectDir, ".mcp.json");
9563
- const claudeMdPath = join13(projectDir, "CLAUDE.md");
9829
+ const mcpConfigPath = join14(projectDir, ".mcp.json");
9830
+ const claudeMdPath = join14(projectDir, "CLAUDE.md");
9564
9831
  if (restartBreaker.isTripped(codeName)) {
9565
9832
  const trip = restartBreaker.getTrip(codeName);
9566
9833
  return {
@@ -10205,11 +10472,11 @@ ${escapeXml(msg.content)}
10205
10472
  log(`[direct-chat] One-shot spawn for '${agent.codeName}' (msg=${msg.id}; host in-flight=${directChatSpawnGate.hostInFlight}, queued=${directChatSpawnGate.queuedCount})`);
10206
10473
  const { getProjectDir: ccProjectDir } = await import("../claude-scheduler-FATCLHDM.js");
10207
10474
  const projDir = ccProjectDir(agent.codeName);
10208
- const mcpConfigPath = join13(projDir, ".mcp.json");
10475
+ const mcpConfigPath = join14(projDir, ".mcp.json");
10209
10476
  const serverNames = [];
10210
- if (existsSync7(mcpConfigPath)) {
10477
+ if (existsSync8(mcpConfigPath)) {
10211
10478
  try {
10212
- const d = JSON.parse(readFileSync11(mcpConfigPath, "utf-8"));
10479
+ const d = JSON.parse(readFileSync12(mcpConfigPath, "utf-8"));
10213
10480
  if (d.mcpServers) serverNames.push(...Object.keys(d.mcpServers));
10214
10481
  } catch {
10215
10482
  }
@@ -10228,15 +10495,15 @@ ${escapeXml(msg.content)}
10228
10495
  "--allowedTools",
10229
10496
  allowedTools
10230
10497
  ];
10231
- const chatClaudeMd = join13(projDir, "CLAUDE.md");
10232
- if (existsSync7(chatClaudeMd)) {
10498
+ const chatClaudeMd = join14(projDir, "CLAUDE.md");
10499
+ if (existsSync8(chatClaudeMd)) {
10233
10500
  chatArgs.push("--system-prompt-file", chatClaudeMd);
10234
10501
  }
10235
- const envIntPath = join13(projDir, ".env.integrations");
10502
+ const envIntPath = join14(projDir, ".env.integrations");
10236
10503
  const childEnv = { ...process.env };
10237
- if (existsSync7(envIntPath)) {
10504
+ if (existsSync8(envIntPath)) {
10238
10505
  try {
10239
- Object.assign(childEnv, parseEnvIntegrations(readFileSync11(envIntPath, "utf-8")));
10506
+ Object.assign(childEnv, parseEnvIntegrations(readFileSync12(envIntPath, "utf-8")));
10240
10507
  } catch {
10241
10508
  }
10242
10509
  }
@@ -10291,51 +10558,27 @@ ${escapeXml(msg.content)}
10291
10558
  await api.post("/host/direct-chat/reply", {
10292
10559
  agent_id: agent.agentId,
10293
10560
  session_id: msg.session_id,
10294
- content: reply
10295
- });
10296
- log(`[direct-chat] Reply sent for '${agent.codeName}'`);
10297
- } catch (err) {
10298
- const errMsg = err instanceof Error ? err.message : String(err);
10299
- const errorId = createHash4("sha256").update(errMsg).digest("hex").slice(0, 12);
10300
- log(`[direct-chat] Failed to process message for '${agent.codeName}': error_id=${errorId} error=${errMsg.slice(0, 500)}`);
10301
- try {
10302
- await api.post("/host/direct-chat/reply", {
10303
- agent_id: agent.agentId,
10304
- session_id: msg.session_id,
10305
- content: `[Error] Failed to process message (ref: ${errorId}). Please retry.`
10306
- });
10307
- } catch {
10308
- }
10309
- } finally {
10310
- releaseSpawnSlot?.();
10311
- }
10312
- }
10313
- var STANDUP_TEMPLATES = /* @__PURE__ */ new Set(["daily-standup", "end-of-day-summary"]);
10314
- var TASK_UPDATE_TEMPLATES = /* @__PURE__ */ new Set(["hourly-status", "task-update"]);
10315
- var PLAN_TEMPLATES = /* @__PURE__ */ new Set(["morning-plan"]);
10316
- var KANBAN_WORK_TEMPLATES = /* @__PURE__ */ new Set(["kanban-work"]);
10317
- function isPlainScheduledTemplate(templateId) {
10318
- return !STANDUP_TEMPLATES.has(templateId) && !TASK_UPDATE_TEMPLATES.has(templateId) && !PLAN_TEMPLATES.has(templateId) && !KANBAN_WORK_TEMPLATES.has(templateId);
10319
- }
10320
- function isKanbanHybridEnabled() {
10321
- return true;
10322
- }
10323
- function isKanbanHybridDryRun() {
10324
- const v = process.env["AGT_KANBAN_HYBRID_DRY_RUN"];
10325
- return v === "1" || v?.toLowerCase() === "true";
10326
- }
10327
- var HYBRID_ACTIONABLE_STATUSES = /* @__PURE__ */ new Set(["todo", "in_progress"]);
10328
- function isHybridActionable(item) {
10329
- return HYBRID_ACTIONABLE_STATUSES.has(item.status) && item.source_type !== "scheduled_task";
10330
- }
10331
- function hasHybridActionableItems(items) {
10332
- return items.some(isHybridActionable);
10561
+ content: reply
10562
+ });
10563
+ log(`[direct-chat] Reply sent for '${agent.codeName}'`);
10564
+ } catch (err) {
10565
+ const errMsg = err instanceof Error ? err.message : String(err);
10566
+ const errorId = createHash4("sha256").update(errMsg).digest("hex").slice(0, 12);
10567
+ log(`[direct-chat] Failed to process message for '${agent.codeName}': error_id=${errorId} error=${errMsg.slice(0, 500)}`);
10568
+ try {
10569
+ await api.post("/host/direct-chat/reply", {
10570
+ agent_id: agent.agentId,
10571
+ session_id: msg.session_id,
10572
+ content: `[Error] Failed to process message (ref: ${errorId}). Please retry.`
10573
+ });
10574
+ } catch {
10575
+ }
10576
+ } finally {
10577
+ releaseSpawnSlot?.();
10578
+ }
10333
10579
  }
10334
10580
  var lastKanbanInjectAt = /* @__PURE__ */ new Map();
10335
10581
  var openInjectedRunByCode = /* @__PURE__ */ new Map();
10336
- function isSlashCommand(command) {
10337
- return command.trimStart().startsWith("/");
10338
- }
10339
10582
  function closeInjectedRunIfOpen(codeName, outcome, outcomeMessage) {
10340
10583
  const runId = openInjectedRunByCode.get(codeName);
10341
10584
  if (!runId) return;
@@ -10393,11 +10636,6 @@ ${formatRunMarker(run_id)}` : KANBAN_CHECK_COMMAND;
10393
10636
  log(`[manager-worker] kanban inject failed for '${codeName}'`);
10394
10637
  }
10395
10638
  }
10396
- var BOARD_INJECT_TEMPLATES = /* @__PURE__ */ new Set(["morning-plan", "task-update", "hourly-status", "end-of-day-summary"]);
10397
- var ACTIONABLE_STATUSES = /* @__PURE__ */ new Set(["todo", "in_progress"]);
10398
- function hasActionableItems(items) {
10399
- return items.some((item) => ACTIONABLE_STATUSES.has(item.status));
10400
- }
10401
10639
  var lastHarvestAt = /* @__PURE__ */ new Map();
10402
10640
  var HARVEST_INTERVAL_MS = 3 * 60 * 1e3;
10403
10641
  var kanbanBoardCache = /* @__PURE__ */ new Map();
@@ -10517,247 +10755,6 @@ async function harvestCronResults(codeName, tasks, gatewayPort) {
10517
10755
  }
10518
10756
  }
10519
10757
  }
10520
- function parseStandupSummary(summary) {
10521
- const lines = summary.split("\n");
10522
- let yesterday = "";
10523
- let today = "";
10524
- let blockers = "";
10525
- let currentSection = null;
10526
- for (const line of lines) {
10527
- const lower = line.toLowerCase();
10528
- if (lower.includes("yesterday") || lower.includes("accomplished")) {
10529
- currentSection = "yesterday";
10530
- continue;
10531
- } else if (lower.includes("todo") || lower.includes("working on")) {
10532
- currentSection = "todo";
10533
- continue;
10534
- } else if (lower.includes("blocker")) {
10535
- currentSection = "blockers";
10536
- continue;
10537
- }
10538
- const trimmed = line.replace(/^[-*•]\s*/, "").trim();
10539
- if (!trimmed) continue;
10540
- switch (currentSection) {
10541
- case "yesterday":
10542
- yesterday += (yesterday ? "\n" : "") + trimmed;
10543
- break;
10544
- case "todo":
10545
- today += (today ? "\n" : "") + trimmed;
10546
- break;
10547
- case "blockers":
10548
- blockers += (blockers ? "\n" : "") + trimmed;
10549
- break;
10550
- }
10551
- }
10552
- if (!yesterday && !today && !blockers) {
10553
- today = summary;
10554
- }
10555
- return { yesterday, today, blockers };
10556
- }
10557
- function parsePlanItems(summary) {
10558
- const items = [];
10559
- const lines = summary.split("\n");
10560
- let currentItem = null;
10561
- for (const line of lines) {
10562
- const trimmed = line.trim();
10563
- const itemMatch = trimmed.match(/^(?:\d+[\.\)]\s*|[-*•]\s*)\[?(HIGH|MEDIUM|LOW|MED)\]?\s*(.+)/i);
10564
- if (itemMatch) {
10565
- if (currentItem) items.push(currentItem);
10566
- const priorityStr = itemMatch[1].toUpperCase();
10567
- const rest = itemMatch[2];
10568
- let estimatedMinutes;
10569
- const timeMatch = rest.match(/\(~?(\d+)\s*(min(?:utes?)?|hr?(?:ours?)?|h)\)/i);
10570
- if (timeMatch) {
10571
- const val = parseInt(timeMatch[1], 10);
10572
- const unit = timeMatch[2].toLowerCase();
10573
- estimatedMinutes = unit.startsWith("h") ? val * 60 : val;
10574
- }
10575
- const title = sanitizeKanbanString(
10576
- rest.replace(/\(~?\d+\s*(?:min(?:utes?)?|hr?(?:ours?)?|h)\)/i, ""),
10577
- MAX_KANBAN_TITLE_LENGTH
10578
- );
10579
- if (!title) continue;
10580
- const priorityMap = { HIGH: 1, MEDIUM: 2, MED: 2, LOW: 3 };
10581
- const priority = priorityMap[priorityStr] ?? 2;
10582
- if (![1, 2, 3].includes(priority)) continue;
10583
- currentItem = {
10584
- title,
10585
- priority,
10586
- estimated_minutes: estimatedMinutes,
10587
- status: "todo"
10588
- };
10589
- } else if (currentItem && trimmed && !trimmed.match(/^(?:PLAN|---)/i)) {
10590
- const descLine = sanitizeKanbanString(trimmed, MAX_KANBAN_NOTES_LENGTH);
10591
- currentItem.description = currentItem.description ? sanitizeKanbanString(currentItem.description + "\n" + descLine, MAX_KANBAN_NOTES_LENGTH) : descLine;
10592
- }
10593
- }
10594
- if (currentItem) items.push(currentItem);
10595
- return items;
10596
- }
10597
- var VALID_KANBAN_STATUSES = /* @__PURE__ */ new Set(["backlog", "todo", "in_progress", "done"]);
10598
- var MAX_KANBAN_TITLE_LENGTH = 500;
10599
- var MAX_KANBAN_NOTES_LENGTH = 2e3;
10600
- function sanitizeKanbanString(value, maxLen) {
10601
- if (!value) return "";
10602
- return value.replace(/[\x00-\x08\x0B\x0C\x0E-\x1F\x7F]/g, "").replace(/\{\{.*?\}\}/g, "").replace(/^(System|Assistant|Human):\s*/gmi, "").replace(/#{2,}/g, "").replace(/\s+/g, " ").trim().slice(0, maxLen);
10603
- }
10604
- function sanitizeBoardItem(item) {
10605
- return {
10606
- ...item,
10607
- title: sanitizeKanbanString(item.title, 200),
10608
- status: sanitizeKanbanString(item.status, 50),
10609
- ...item.deliverable ? { deliverable: sanitizeKanbanString(item.deliverable, 500) } : {}
10610
- };
10611
- }
10612
- var builtInSkillCache = /* @__PURE__ */ new Map();
10613
- function getBuiltInSkillContent(skillId) {
10614
- if (builtInSkillCache.has(skillId)) return builtInSkillCache.get(skillId);
10615
- try {
10616
- const candidates = [
10617
- join13(process.cwd(), "skills", skillId, "SKILL.md"),
10618
- join13(new URL(".", import.meta.url).pathname, "..", "..", "..", "..", "skills", skillId, "SKILL.md")
10619
- ];
10620
- for (const candidate of candidates) {
10621
- if (existsSync7(candidate)) {
10622
- const content = readFileSync11(candidate, "utf-8");
10623
- const files = [{ relativePath: "SKILL.md", content }];
10624
- builtInSkillCache.set(skillId, files);
10625
- return files;
10626
- }
10627
- }
10628
- builtInSkillCache.set(skillId, null);
10629
- return null;
10630
- } catch {
10631
- builtInSkillCache.set(skillId, null);
10632
- return null;
10633
- }
10634
- }
10635
- function parseKanbanUpdates(summary) {
10636
- const updates = [];
10637
- const kanbanIdx = summary.indexOf("KANBAN UPDATE:");
10638
- if (kanbanIdx === -1) return updates;
10639
- const kanbanSection = summary.slice(kanbanIdx + "KANBAN UPDATE:".length);
10640
- const lines = kanbanSection.split("\n");
10641
- for (const line of lines) {
10642
- const trimmed = line.trim();
10643
- const match = trimmed.match(/^[-*•]\s*"([^"]+)":\s*(backlog|todo|today|in_progress|done)(?:\s*\((.+)\))?/i);
10644
- if (match) {
10645
- const rawStatus = match[2].toLowerCase();
10646
- const status = rawStatus === "today" ? "todo" : rawStatus;
10647
- if (!VALID_KANBAN_STATUSES.has(status)) continue;
10648
- const title = sanitizeKanbanString(match[1], MAX_KANBAN_TITLE_LENGTH);
10649
- if (!title) continue;
10650
- const parenthetical = match[3] ?? void 0;
10651
- let notes;
10652
- let result;
10653
- if (parenthetical && status === "done") {
10654
- const resultMatch = parenthetical.match(/^result:\s*(.+)/i);
10655
- if (resultMatch) {
10656
- result = sanitizeKanbanString(resultMatch[1], MAX_KANBAN_NOTES_LENGTH);
10657
- } else {
10658
- notes = sanitizeKanbanString(parenthetical, MAX_KANBAN_NOTES_LENGTH);
10659
- }
10660
- } else if (parenthetical) {
10661
- notes = sanitizeKanbanString(parenthetical, MAX_KANBAN_NOTES_LENGTH);
10662
- }
10663
- updates.push({
10664
- title,
10665
- status,
10666
- notes,
10667
- result
10668
- });
10669
- }
10670
- }
10671
- return updates;
10672
- }
10673
- function formatBoardForPrompt(items, template) {
10674
- if (items.length === 0) return "";
10675
- const priorityLabel = (p) => p === 1 ? "HIGH" : p === 3 ? "LOW" : "MED";
10676
- const timeLabel = (m) => m ? ` (~${m >= 60 ? `${Math.round(m / 60)}hr` : `${m}min`})` : "";
10677
- const deliverableLine = (d) => d ? `
10678
- Deliverable: ${d}` : "";
10679
- const sourceLine = (channel, thread, url) => {
10680
- const parts = [];
10681
- if (channel && thread) parts.push(`${channel} thread ${thread}`);
10682
- if (url) parts.push(url);
10683
- return parts.length > 0 ? `
10684
- source: ${parts.join(" \u2022 ")}` : "";
10685
- };
10686
- const grouped = {};
10687
- for (const item of items) {
10688
- const key = item.status;
10689
- if (!grouped[key]) grouped[key] = [];
10690
- grouped[key].push(item);
10691
- }
10692
- const hasSourceThread = items.some(
10693
- (i) => (i.status === "todo" || i.status === "in_progress") && !!i.source_integration && !!i.source_external_id
10694
- );
10695
- const lines = [];
10696
- if (template === "morning-plan") {
10697
- lines.push("=== CURRENT BOARD ===");
10698
- for (const [status, label] of [["backlog", "BACKLOG (carry-over)"], ["todo", "TO DO"], ["in_progress", "IN PROGRESS"]]) {
10699
- const statusItems = grouped[status];
10700
- if (statusItems && statusItems.length > 0) {
10701
- lines.push(`${label}:`);
10702
- statusItems.forEach((item, i) => {
10703
- lines.push(` ${i + 1}. [${priorityLabel(item.priority)}] ${item.title}${timeLabel(item.estimated_minutes)}${deliverableLine(item.deliverable)}${sourceLine(item.source_integration, item.source_external_id, item.source_url)}`);
10704
- });
10705
- }
10706
- }
10707
- lines.push("=====================");
10708
- lines.push("");
10709
- lines.push("Create today's plan. You may:");
10710
- lines.push('- Move backlog items to "todo"');
10711
- lines.push("- Add new items you've identified");
10712
- lines.push("- Reprioritise existing items");
10713
- lines.push("");
10714
- } else {
10715
- lines.push("=== YOUR KANBAN BOARD ===");
10716
- for (const [status, label] of [["todo", "TO DO"], ["in_progress", "IN PROGRESS"], ["backlog", "BACKLOG"]]) {
10717
- const statusItems = grouped[status];
10718
- if (statusItems && statusItems.length > 0) {
10719
- lines.push(`${label}:`);
10720
- statusItems.forEach((item, i) => {
10721
- lines.push(` ${i + 1}. [${priorityLabel(item.priority)}] ${item.title}${timeLabel(item.estimated_minutes)}${deliverableLine(item.deliverable)}${sourceLine(item.source_integration, item.source_external_id, item.source_url)}`);
10722
- });
10723
- }
10724
- }
10725
- const doneItems = grouped["done"];
10726
- if (doneItems && doneItems.length > 0) {
10727
- lines.push("DONE TODAY:");
10728
- doneItems.forEach((item, i) => {
10729
- lines.push(` ${i + 1}. ${item.title}`);
10730
- });
10731
- }
10732
- lines.push("=========================");
10733
- lines.push("");
10734
- lines.push("IMPORTANT: Use kanban MCP tools to update the board IN REAL TIME:");
10735
- lines.push("1. FIRST call kanban_move to move your chosen item to in_progress BEFORE starting work");
10736
- lines.push("2. Do the work");
10737
- lines.push("3. Call kanban_done with a result summary when finished");
10738
- lines.push("4. If blocked, call kanban_update with notes, then pick the next item");
10739
- lines.push("");
10740
- if (hasSourceThread) {
10741
- lines.push("THREAD CONTINUITY: If a card shows a `source:` line, the request originated");
10742
- lines.push("in that Slack/Telegram thread. When you deliver the result, reply in that");
10743
- lines.push("thread (not the default channel) so the user sees the answer where they");
10744
- lines.push("asked. The card's `source_channel` + `source_thread_id` are the thread");
10745
- lines.push("coordinates to use.");
10746
- lines.push("");
10747
- }
10748
- lines.push("SELF-MANAGEMENT: When you receive a request from a channel (Slack, Telegram)");
10749
- lines.push("that takes more than a quick response, create a task first with kanban_add,");
10750
- lines.push("move to in_progress, do the work, then kanban_done with a result summary.");
10751
- lines.push("");
10752
- lines.push("If MCP tools are unavailable, include a KANBAN UPDATE section in your output:");
10753
- lines.push("KANBAN UPDATE:");
10754
- lines.push('- "item title": new_status (optional notes)');
10755
- lines.push('- "item title": done (result: <what you produced>)');
10756
- lines.push("Statuses: backlog, today, in_progress, done");
10757
- lines.push("");
10758
- }
10759
- return lines.join("\n");
10760
- }
10761
10758
  var LATE_THRESHOLD_MS = 5 * 60 * 1e3;
10762
10759
  async function monitorCronHealth(agentStates) {
10763
10760
  const alerts = [];
@@ -11521,8 +11518,8 @@ function parseMemoryFile(raw, fallbackName) {
11521
11518
  };
11522
11519
  }
11523
11520
  async function syncMemories(agent, configDir, log2) {
11524
- const projectDir = join13(configDir, agent.code_name, "project");
11525
- const memoryDir = join13(projectDir, "memory");
11521
+ const projectDir = join14(configDir, agent.code_name, "project");
11522
+ const memoryDir = join14(projectDir, "memory");
11526
11523
  const isFreshSync = pendingFreshMemorySync.has(agent.agent_id);
11527
11524
  if (isFreshSync) {
11528
11525
  log2(`[memory-sync] Fresh-sync requested for '${agent.code_name}' \u2014 pulling DB first`);
@@ -11533,14 +11530,14 @@ async function syncMemories(agent, configDir, log2) {
11533
11530
  }
11534
11531
  pendingFreshMemorySync.delete(agent.agent_id);
11535
11532
  }
11536
- if (existsSync7(memoryDir)) {
11533
+ if (existsSync8(memoryDir)) {
11537
11534
  const prevHashes = memoryFileHashes.get(agent.agent_id) ?? /* @__PURE__ */ new Map();
11538
11535
  const currentHashes = /* @__PURE__ */ new Map();
11539
11536
  const changedMemories = [];
11540
11537
  for (const file of readdirSync5(memoryDir)) {
11541
11538
  if (!file.endsWith(".md")) continue;
11542
11539
  try {
11543
- const raw = readFileSync11(join13(memoryDir, file), "utf-8");
11540
+ const raw = readFileSync12(join14(memoryDir, file), "utf-8");
11544
11541
  const fileHash = createHash4("sha256").update(raw).digest("hex").slice(0, 16);
11545
11542
  currentHashes.set(file, fileHash);
11546
11543
  if (prevHashes.get(file) === fileHash) continue;
@@ -11565,7 +11562,7 @@ async function syncMemories(agent, configDir, log2) {
11565
11562
  } catch (err) {
11566
11563
  for (const mem of changedMemories) {
11567
11564
  for (const [file] of currentHashes) {
11568
- const parsed = parseMemoryFile(readFileSync11(join13(memoryDir, file), "utf-8"), file.replace(/\.md$/, ""));
11565
+ const parsed = parseMemoryFile(readFileSync12(join14(memoryDir, file), "utf-8"), file.replace(/\.md$/, ""));
11569
11566
  if (parsed?.name === mem.name) currentHashes.delete(file);
11570
11567
  }
11571
11568
  }
@@ -11578,7 +11575,7 @@ async function syncMemories(agent, configDir, log2) {
11578
11575
  }
11579
11576
  }
11580
11577
  async function downloadMemories(agent, memoryDir, log2, { force }) {
11581
- const localFiles = existsSync7(memoryDir) ? readdirSync5(memoryDir).filter((f) => f.endsWith(".md")).sort() : [];
11578
+ const localFiles = existsSync8(memoryDir) ? readdirSync5(memoryDir).filter((f) => f.endsWith(".md")).sort() : [];
11582
11579
  const localListHash = createHash4("sha256").update(localFiles.join(",")).digest("hex").slice(0, 16);
11583
11580
  const prevLocalHash = lastLocalFileHash.get(agent.agent_id);
11584
11581
  const prevDownload = lastDownloadHash.get(agent.agent_id);
@@ -11600,7 +11597,7 @@ async function downloadMemories(agent, memoryDir, log2, { force }) {
11600
11597
  const mem = dbMemories.memories[i];
11601
11598
  const rawSlug = mem.name.toLowerCase().replace(/[^a-z0-9]+/g, "-").replace(/(^-|-$)/g, "").slice(0, 60);
11602
11599
  const slug = rawSlug || `memory-${i}`;
11603
- const filePath = join13(memoryDir, `${slug}.md`);
11600
+ const filePath = join14(memoryDir, `${slug}.md`);
11604
11601
  const desired = `---
11605
11602
  name: ${JSON.stringify(mem.name)}
11606
11603
  type: ${mem.type}
@@ -11609,10 +11606,10 @@ description: ${JSON.stringify(mem.content.slice(0, 200))}
11609
11606
 
11610
11607
  ${mem.content}
11611
11608
  `;
11612
- if (existsSync7(filePath)) {
11609
+ if (existsSync8(filePath)) {
11613
11610
  let existing = "";
11614
11611
  try {
11615
- existing = readFileSync11(filePath, "utf-8");
11612
+ existing = readFileSync12(filePath, "utf-8");
11616
11613
  } catch {
11617
11614
  }
11618
11615
  if (existing === desired) continue;
@@ -11636,7 +11633,7 @@ ${mem.content}
11636
11633
  }
11637
11634
  }
11638
11635
  async function cleanupAgentFiles(codeName, agentDir) {
11639
- if (existsSync7(agentDir)) {
11636
+ if (existsSync8(agentDir)) {
11640
11637
  try {
11641
11638
  rmSync3(agentDir, { recursive: true, force: true });
11642
11639
  log(`Removed provision directory for '${codeName}'`);
@@ -11886,8 +11883,8 @@ function startManager(opts) {
11886
11883
  config = opts;
11887
11884
  try {
11888
11885
  const stateFile = getStateFile();
11889
- if (existsSync7(stateFile)) {
11890
- const raw = readFileSync11(stateFile, "utf-8");
11886
+ if (existsSync8(stateFile)) {
11887
+ const raw = readFileSync12(stateFile, "utf-8");
11891
11888
  const parsed = JSON.parse(raw);
11892
11889
  if (Array.isArray(parsed.agents)) {
11893
11890
  state6.agents = parsed.agents;
@@ -11908,7 +11905,7 @@ function startManager(opts) {
11908
11905
  log(`[startup] state rehydration failed (continuing with empty state): ${err.message}`);
11909
11906
  }
11910
11907
  log(
11911
- `[startup] worker pid=${process.pid} ppid=${process.ppid} node=${process.version} log=${join13(homedir7(), ".augmented", "manager.log")}`
11908
+ `[startup] worker pid=${process.pid} ppid=${process.ppid} node=${process.version} log=${join14(homedir7(), ".augmented", "manager.log")}`
11912
11909
  );
11913
11910
  deployMcpAssets();
11914
11911
  reapOrphanChannelMcps({ log });
@@ -11929,7 +11926,7 @@ async function reapOrphanedClaudePids() {
11929
11926
  const looksLikeClaude = (pid) => {
11930
11927
  if (process.platform !== "linux") return true;
11931
11928
  try {
11932
- const comm = readFileSync11(`/proc/${pid}/comm`, "utf-8").trim().toLowerCase();
11929
+ const comm = readFileSync12(`/proc/${pid}/comm`, "utf-8").trim().toLowerCase();
11933
11930
  return comm.includes("claude");
11934
11931
  } catch {
11935
11932
  return false;
@@ -12039,14 +12036,14 @@ function restartRunningChannelMcps(basenames) {
12039
12036
  }
12040
12037
  }
12041
12038
  function deployMcpAssets() {
12042
- const targetDir = join13(homedir7(), ".augmented", "_mcp");
12039
+ const targetDir = join14(homedir7(), ".augmented", "_mcp");
12043
12040
  mkdirSync4(targetDir, { recursive: true });
12044
12041
  const moduleDir = dirname3(fileURLToPath(import.meta.url));
12045
12042
  let mcpSourceDir = "";
12046
12043
  let dir = moduleDir;
12047
12044
  for (let i = 0; i < 6; i++) {
12048
- const candidate = join13(dir, "dist", "mcp");
12049
- if (existsSync7(join13(candidate, "index.js"))) {
12045
+ const candidate = join14(dir, "dist", "mcp");
12046
+ if (existsSync8(join14(candidate, "index.js"))) {
12050
12047
  mcpSourceDir = candidate;
12051
12048
  break;
12052
12049
  }
@@ -12061,8 +12058,8 @@ function deployMcpAssets() {
12061
12058
  const changedBasenames = [];
12062
12059
  const fileHash = (p) => {
12063
12060
  try {
12064
- if (!existsSync7(p)) return null;
12065
- return createHash4("sha256").update(readFileSync11(p)).digest("hex");
12061
+ if (!existsSync8(p)) return null;
12062
+ return createHash4("sha256").update(readFileSync12(p)).digest("hex");
12066
12063
  } catch {
12067
12064
  return null;
12068
12065
  }
@@ -12089,9 +12086,9 @@ function deployMcpAssets() {
12089
12086
  // natural session restart.
12090
12087
  "augmented-admin.js"
12091
12088
  ]) {
12092
- const src = join13(mcpSourceDir, file);
12093
- const dst = join13(targetDir, file);
12094
- if (!existsSync7(src)) continue;
12089
+ const src = join14(mcpSourceDir, file);
12090
+ const dst = join14(targetDir, file);
12091
+ if (!existsSync8(src)) continue;
12095
12092
  const before = fileHash(dst);
12096
12093
  try {
12097
12094
  copyFileSync(src, dst);
@@ -12108,16 +12105,16 @@ function deployMcpAssets() {
12108
12105
  log(`[manager] Bundle(s) updated: ${changedBasenames.join(", ")} \u2014 signalling running instances to restart`);
12109
12106
  restartRunningChannelMcps(changedBasenames);
12110
12107
  }
12111
- const localMcpPath = join13(targetDir, "index.js");
12108
+ const localMcpPath = join14(targetDir, "index.js");
12112
12109
  try {
12113
- const agentsDir = join13(homedir7(), ".augmented", "agents");
12114
- if (existsSync7(agentsDir)) {
12110
+ const agentsDir = join14(homedir7(), ".augmented", "agents");
12111
+ if (existsSync8(agentsDir)) {
12115
12112
  for (const entry of readdirSync5(agentsDir, { withFileTypes: true })) {
12116
12113
  if (!entry.isDirectory()) continue;
12117
12114
  for (const subdir of ["provision", "project"]) {
12118
- const mcpJsonPath = join13(agentsDir, entry.name, subdir, ".mcp.json");
12115
+ const mcpJsonPath = join14(agentsDir, entry.name, subdir, ".mcp.json");
12119
12116
  try {
12120
- const raw = readFileSync11(mcpJsonPath, "utf-8");
12117
+ const raw = readFileSync12(mcpJsonPath, "utf-8");
12121
12118
  if (!raw.includes("@integrity-labs/augmented-mcp")) continue;
12122
12119
  const mcpConfig = JSON.parse(raw);
12123
12120
  const augServer = mcpConfig.mcpServers?.["augmented"];
@@ -12177,15 +12174,8 @@ export {
12177
12174
  extractCharterSlackPeers,
12178
12175
  extractCharterTelegramPeers,
12179
12176
  fireScheduledTaskViaKanban,
12180
- formatBoardForPrompt,
12181
- hasActionableItems,
12182
- hasHybridActionableItems,
12183
12177
  hasRevokedResiduals,
12184
- isHybridActionable,
12185
- isKanbanHybridDryRun,
12186
- isKanbanHybridEnabled,
12187
12178
  isOlderSemverTuple,
12188
- isPlainScheduledTemplate,
12189
12179
  isPrereleaseVersion,
12190
12180
  isScheduledCardTracked,
12191
12181
  isScheduledViaKanbanEnabled,