@adhdev/daemon-standalone 0.9.77-rc.1 → 0.9.77-rc.11

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.
@@ -2437,7 +2437,7 @@ var require_extension = __commonJS({
2437
2437
  var require_websocket = __commonJS({
2438
2438
  "../../node_modules/ws/lib/websocket.js"(exports2, module2) {
2439
2439
  "use strict";
2440
- var EventEmitter2 = require("events");
2440
+ var EventEmitter3 = require("events");
2441
2441
  var https = require("https");
2442
2442
  var http3 = require("http");
2443
2443
  var net3 = require("net");
@@ -2469,7 +2469,7 @@ var require_websocket = __commonJS({
2469
2469
  var protocolVersions = [8, 13];
2470
2470
  var readyStates = ["CONNECTING", "OPEN", "CLOSING", "CLOSED"];
2471
2471
  var subprotocolRegex = /^[!#$%&'*+\-.0-9A-Z^_`|a-z~]+$/;
2472
- var WebSocket2 = class _WebSocket extends EventEmitter2 {
2472
+ var WebSocket2 = class _WebSocket extends EventEmitter3 {
2473
2473
  /**
2474
2474
  * Create a new `WebSocket`.
2475
2475
  *
@@ -3466,7 +3466,7 @@ var require_subprotocol = __commonJS({
3466
3466
  var require_websocket_server = __commonJS({
3467
3467
  "../../node_modules/ws/lib/websocket-server.js"(exports2, module2) {
3468
3468
  "use strict";
3469
- var EventEmitter2 = require("events");
3469
+ var EventEmitter3 = require("events");
3470
3470
  var http3 = require("http");
3471
3471
  var { Duplex } = require("stream");
3472
3472
  var { createHash: createHash3 } = require("crypto");
@@ -3479,7 +3479,7 @@ var require_websocket_server = __commonJS({
3479
3479
  var RUNNING = 0;
3480
3480
  var CLOSING = 1;
3481
3481
  var CLOSED = 2;
3482
- var WebSocketServer2 = class extends EventEmitter2 {
3482
+ var WebSocketServer2 = class extends EventEmitter3 {
3483
3483
  /**
3484
3484
  * Create a `WebSocketServer` instance.
3485
3485
  *
@@ -25102,6 +25102,7 @@ __export(dist_exports, {
25102
25102
  TurnSnapshotTracker: () => TurnSnapshotTracker,
25103
25103
  VersionArchive: () => VersionArchive,
25104
25104
  addNode: () => addNode,
25105
+ appendLedgerEntry: () => appendLedgerEntry,
25105
25106
  appendRecentActivity: () => appendRecentActivity,
25106
25107
  buildAssistantChatMessage: () => buildAssistantChatMessage,
25107
25108
  buildChatMessage: () => buildChatMessage,
@@ -25119,6 +25120,7 @@ __export(dist_exports, {
25119
25120
  buildThoughtChatMessage: () => buildThoughtChatMessage,
25120
25121
  buildToolChatMessage: () => buildToolChatMessage,
25121
25122
  buildUserChatMessage: () => buildUserChatMessage,
25123
+ claimNextTask: () => claimNextTask,
25122
25124
  classifyChatMessageVisibility: () => classifyChatMessageVisibility,
25123
25125
  classifyHotChatSessionsForSubscriptionFlush: () => classifyHotChatSessionsForSubscriptionFlush,
25124
25126
  clearDebugTrace: () => clearDebugTrace,
@@ -25137,6 +25139,7 @@ __export(dist_exports, {
25137
25139
  detectAllVersions: () => detectAllVersions,
25138
25140
  detectCLIs: () => detectCLIs,
25139
25141
  detectIDEs: () => detectIDEs,
25142
+ enqueueTask: () => enqueueTask,
25140
25143
  ensureSessionHostReady: () => ensureSessionHostReady,
25141
25144
  execNpmCommandSync: () => execNpmCommandSync,
25142
25145
  filterActivityChatMessages: () => filterActivityChatMessages,
@@ -25155,10 +25158,13 @@ __export(dist_exports, {
25155
25158
  getGitFileDiff: () => getGitFileDiff,
25156
25159
  getGitRepoStatus: () => getGitRepoStatus,
25157
25160
  getHostMemorySnapshot: () => getHostMemorySnapshot,
25161
+ getLedgerDir: () => getLedgerDir,
25162
+ getLedgerSummary: () => getLedgerSummary,
25158
25163
  getLogLevel: () => getLogLevel,
25159
25164
  getMesh: () => getMesh,
25160
25165
  getMeshByRepo: () => getMeshByRepo,
25161
25166
  getNpmExecOptions: () => getNpmExecOptions,
25167
+ getQueue: () => getQueue,
25162
25168
  getRecentActivity: () => getRecentActivity,
25163
25169
  getRecentCommands: () => getRecentCommands,
25164
25170
  getRecentDebugTrace: () => getRecentDebugTrace,
@@ -25166,6 +25172,7 @@ __export(dist_exports, {
25166
25172
  getSavedProviderSessions: () => getSavedProviderSessions,
25167
25173
  getSessionHostRecoveryLabel: () => getSessionHostRecoveryLabel,
25168
25174
  getSessionHostSurfaceKind: () => getSessionHostSurfaceKind,
25175
+ getSessionRecoveryContext: () => getSessionRecoveryContext,
25169
25176
  getWorkspaceState: () => getWorkspaceState,
25170
25177
  handleGitCommand: () => handleGitCommand,
25171
25178
  hasCdpManager: () => hasCdpManager,
@@ -25219,6 +25226,7 @@ __export(dist_exports, {
25219
25226
  prepareSessionModalUpdate: () => prepareSessionModalUpdate,
25220
25227
  probeCdpPort: () => probeCdpPort,
25221
25228
  readChatHistory: () => readChatHistory,
25229
+ readLedgerEntries: () => readLedgerEntries,
25222
25230
  recordDebugTrace: () => recordDebugTrace,
25223
25231
  registerExtensionProviders: () => registerExtensionProviders,
25224
25232
  removeNode: () => removeNode,
@@ -25247,9 +25255,12 @@ __export(dist_exports, {
25247
25255
  startDaemonDevSupport: () => startDaemonDevSupport,
25248
25256
  summarizeGitStatus: () => summarizeGitStatus,
25249
25257
  syncMeshes: () => syncMeshes,
25258
+ triggerMeshQueue: () => triggerMeshQueue,
25250
25259
  updateConfig: () => updateConfig,
25251
25260
  updateMesh: () => updateMesh,
25252
25261
  updateNode: () => updateNode,
25262
+ updateSessionTaskStatus: () => updateSessionTaskStatus,
25263
+ updateTaskStatus: () => updateTaskStatus,
25253
25264
  upsertSavedProviderSession: () => upsertSavedProviderSession
25254
25265
  });
25255
25266
  function resolveWorktreePath(repoRoot, meshName, branch) {
@@ -25769,18 +25780,315 @@ function buildRulesSection(coordinatorCliType) {
25769
25780
  return `## Rules
25770
25781
 
25771
25782
  - **Minimize coordinator context.** The coordinator's job is routing, not implementing. Do not read source files, run commands, or analyze code directly \u2014 delegate all of that to node agents. Your context should stay lean.
25772
- - **Delegate analysis too.** If you need to understand a bug or explore the codebase, send that investigation as a task to a node. Do not do it yourself.
25783
+ - **Delegate analysis too.** If you need to understand a bug or explore the codebase, send that investigation as a task to the queue or a node. Do not do it yourself.
25773
25784
  - **Respect explicit provider requests.** If the user names an agent/provider, pass the matching provider type to \`mesh_launch_session\`: Hermes \u2192 \`hermes-cli\`, Claude Code/Claude \u2192 \`claude-cli\`, Codex \u2192 \`codex-cli\`, Gemini \u2192 \`gemini-cli\`. Never substitute \`claude-cli\` just because the coordinator itself is Claude Code.
25774
- - **Front-load the task message.** When calling \`mesh_send_task\`, include everything the agent needs: what files to touch, what the problem is, what the fix should look like. The agent won't ask follow-up questions.
25785
+ - **Front-load the task message.** When calling \`mesh_enqueue_task\` or \`mesh_send_task\`, include everything the agent needs: what files to touch, what the problem is, what the fix should look like. The agent won't ask follow-up questions.
25775
25786
  - **Don't inspect code.** Treat delegated agent summaries as self-reports, not verification. Verify side effects via \`mesh_git_status\` (including related repo freshness when configured), not by reading source files.
25776
25787
  - **Don't over-parallelize.** Start with 1-2 concurrent tasks. Scale up if they succeed. Never launch a duplicate session or second worker solely because \`mesh_read_chat\` has no final assistant message while the delegated session is still showing tool/terminal activity.
25777
- - **Handle failures gracefully.** If a task fails, read the chat to understand why, then retry or reassign.
25788
+ - **Handle failures with context.** If a task fails, check \`mesh_task_history\` first to see if this task was attempted before and how it failed. Read the chat to understand why, then decide: retry on the same node, reassign to a different node, or escalate to the user.
25789
+ - **Check history before starting.** At the beginning of a coordination session, call \`mesh_task_history\` to understand what was previously delegated and its outcomes. This prevents duplicate work and informs recovery decisions.
25778
25790
  - **Keep the user informed.** Report progress after each delegation round \u2014 one or two sentences, not a narration.
25779
25791
  - **Respect node capabilities.** Don't send build tasks to read-only nodes. Don't push from nodes that aren't allowed to.
25780
25792
  - **Never fabricate tool results.** Always call the actual tool; never pretend you did.
25781
25793
  - **Clean up worktree nodes.** After a worktree task completes and its changes are merged or checkpointed, call \`mesh_remove_node\` to free resources.
25782
25794
  - **Name worktree branches meaningfully.** Use descriptive names like \`feat/auth-refactor\` or \`fix/build-123\`.${coordinatorNote}`;
25783
25795
  }
25796
+ function getLedgerDir() {
25797
+ const dir = (0, import_path3.join)(getConfigDir(), LEDGER_DIR_NAME);
25798
+ if (!(0, import_fs6.existsSync)(dir)) {
25799
+ (0, import_fs6.mkdirSync)(dir, { recursive: true, mode: 448 });
25800
+ }
25801
+ return dir;
25802
+ }
25803
+ function getLedgerPath(meshId) {
25804
+ const safe = meshId.replace(/[^a-zA-Z0-9_-]/g, "_");
25805
+ return (0, import_path3.join)(getLedgerDir(), `${safe}.jsonl`);
25806
+ }
25807
+ function getRotatedPath(meshId, index) {
25808
+ const safe = meshId.replace(/[^a-zA-Z0-9_-]/g, "_");
25809
+ return (0, import_path3.join)(getLedgerDir(), `${safe}.${index}.jsonl`);
25810
+ }
25811
+ function appendLedgerEntry(meshId, partial2) {
25812
+ const entry = {
25813
+ id: (0, import_crypto4.randomUUID)(),
25814
+ meshId,
25815
+ timestamp: (/* @__PURE__ */ new Date()).toISOString(),
25816
+ ...partial2
25817
+ };
25818
+ const filePath = getLedgerPath(meshId);
25819
+ if ((0, import_fs6.existsSync)(filePath)) {
25820
+ try {
25821
+ const stat22 = (0, import_fs6.statSync)(filePath);
25822
+ if (stat22.size >= MAX_FILE_SIZE_BYTES) {
25823
+ rotateLedgerFile(meshId, filePath);
25824
+ }
25825
+ } catch {
25826
+ }
25827
+ }
25828
+ try {
25829
+ const line = JSON.stringify(entry) + "\n";
25830
+ (0, import_fs6.appendFileSync)(filePath, line, { encoding: "utf-8", mode: 384 });
25831
+ meshLedgerEvents.emit("append", meshId, entry);
25832
+ return entry;
25833
+ } catch (e) {
25834
+ throw new Error(`Failed to append to ledger for mesh ${meshId}: ${e.message}`);
25835
+ }
25836
+ }
25837
+ function appendRemoteLedgerEntries(meshId, entries) {
25838
+ if (entries.length === 0) return;
25839
+ const ledgerPath = getLedgerPath(meshId);
25840
+ const existing = new Set(readLedgerEntries(meshId).map((e) => e.id));
25841
+ const newEntries = entries.filter((e) => !existing.has(e.id));
25842
+ if (newEntries.length === 0) return;
25843
+ try {
25844
+ const lines = newEntries.map((e) => JSON.stringify(e)).join("\n") + "\n";
25845
+ (0, import_fs6.appendFileSync)(ledgerPath, lines, { encoding: "utf-8", mode: 384 });
25846
+ } catch (e) {
25847
+ throw new Error(`Failed to append remote ledger entries for mesh ${meshId}: ${e.message}`);
25848
+ }
25849
+ }
25850
+ function readLedgerEntries(meshId, opts) {
25851
+ const filePath = getLedgerPath(meshId);
25852
+ if (!(0, import_fs6.existsSync)(filePath)) return [];
25853
+ let content;
25854
+ try {
25855
+ content = (0, import_fs6.readFileSync)(filePath, "utf-8");
25856
+ } catch {
25857
+ return [];
25858
+ }
25859
+ const lines = content.split("\n").filter((line) => line.trim());
25860
+ let entries = [];
25861
+ for (const line of lines) {
25862
+ try {
25863
+ const entry = JSON.parse(line);
25864
+ if (!entry.id || !entry.kind) continue;
25865
+ entries.push(entry);
25866
+ } catch {
25867
+ }
25868
+ }
25869
+ if (opts?.since) {
25870
+ const sinceDate = new Date(opts.since).getTime();
25871
+ if (!isNaN(sinceDate)) {
25872
+ entries = entries.filter((e) => new Date(e.timestamp).getTime() >= sinceDate);
25873
+ }
25874
+ }
25875
+ if (opts?.kind?.length) {
25876
+ const kindSet = new Set(opts.kind);
25877
+ entries = entries.filter((e) => kindSet.has(e.kind));
25878
+ }
25879
+ if (opts?.tail && opts.tail > 0 && entries.length > opts.tail) {
25880
+ entries = entries.slice(-opts.tail);
25881
+ }
25882
+ return entries;
25883
+ }
25884
+ function getLedgerSummary(meshId) {
25885
+ const entries = readLedgerEntries(meshId);
25886
+ const now = Date.now();
25887
+ const recentFailureCutoff = now - RECENT_FAILURE_WINDOW_MS;
25888
+ const summary = {
25889
+ meshId,
25890
+ totalEntries: entries.length,
25891
+ taskDispatched: 0,
25892
+ taskCompleted: 0,
25893
+ taskFailed: 0,
25894
+ taskStalled: 0,
25895
+ sessionLaunched: 0,
25896
+ checkpointCreated: 0,
25897
+ lastActivityAt: null,
25898
+ recentFailures: 0
25899
+ };
25900
+ for (const entry of entries) {
25901
+ switch (entry.kind) {
25902
+ case "task_dispatched":
25903
+ summary.taskDispatched++;
25904
+ break;
25905
+ case "task_completed":
25906
+ summary.taskCompleted++;
25907
+ break;
25908
+ case "task_failed": {
25909
+ summary.taskFailed++;
25910
+ if (new Date(entry.timestamp).getTime() >= recentFailureCutoff) {
25911
+ summary.recentFailures++;
25912
+ }
25913
+ break;
25914
+ }
25915
+ case "task_stalled":
25916
+ summary.taskStalled++;
25917
+ break;
25918
+ case "session_launched":
25919
+ summary.sessionLaunched++;
25920
+ break;
25921
+ case "checkpoint_created":
25922
+ summary.checkpointCreated++;
25923
+ break;
25924
+ }
25925
+ }
25926
+ if (entries.length > 0) {
25927
+ summary.lastActivityAt = entries[entries.length - 1].timestamp;
25928
+ }
25929
+ return summary;
25930
+ }
25931
+ function getSessionRecoveryContext(meshId, opts) {
25932
+ const maxRetries = opts.maxRetries ?? 1;
25933
+ const entries = readLedgerEntries(meshId);
25934
+ let lastDispatch = null;
25935
+ for (let i = entries.length - 1; i >= 0; i--) {
25936
+ const e = entries[i];
25937
+ if (e.kind !== "task_dispatched") continue;
25938
+ if (opts.sessionId && e.sessionId === opts.sessionId) {
25939
+ lastDispatch = e;
25940
+ break;
25941
+ }
25942
+ if (opts.nodeId && e.nodeId === opts.nodeId) {
25943
+ lastDispatch = e;
25944
+ break;
25945
+ }
25946
+ }
25947
+ const lastTaskMessage = typeof lastDispatch?.payload?.message === "string" ? lastDispatch.payload.message : null;
25948
+ const now = Date.now();
25949
+ const recentWindow = now - RECENT_FAILURE_WINDOW_MS;
25950
+ let consecutiveNodeFailures = 0;
25951
+ for (let i = entries.length - 1; i >= 0; i--) {
25952
+ const e = entries[i];
25953
+ if (new Date(e.timestamp).getTime() < recentWindow) break;
25954
+ if (opts.nodeId && e.nodeId !== opts.nodeId) continue;
25955
+ if (e.kind === "task_failed") {
25956
+ consecutiveNodeFailures++;
25957
+ } else if (e.kind === "task_completed" || e.kind === "task_dispatched") {
25958
+ break;
25959
+ }
25960
+ }
25961
+ let taskAttemptCount = 0;
25962
+ if (lastTaskMessage) {
25963
+ const prefix = lastTaskMessage.slice(0, 200);
25964
+ for (const e of entries) {
25965
+ if (e.kind === "task_dispatched" && typeof e.payload?.message === "string") {
25966
+ if (e.payload.message.startsWith(prefix)) {
25967
+ taskAttemptCount++;
25968
+ }
25969
+ }
25970
+ }
25971
+ }
25972
+ const retryRecommended = consecutiveNodeFailures <= maxRetries;
25973
+ let advice;
25974
+ if (consecutiveNodeFailures === 0) {
25975
+ advice = "No recent failures detected. This may be a normal stop.";
25976
+ } else if (retryRecommended) {
25977
+ const remaining = maxRetries - consecutiveNodeFailures + 1;
25978
+ advice = `Retry recommended (${consecutiveNodeFailures}/${maxRetries + 1} attempts used, ${remaining} remaining). ` + (lastTaskMessage ? `Re-launch the session and resend the original task.` : `Re-launch the session. Original task message not found in ledger.`);
25979
+ } else {
25980
+ advice = `Max retries exceeded (${consecutiveNodeFailures} consecutive failures). Consider: (1) reassigning to a different node, (2) simplifying the task, or (3) escalating to the user.`;
25981
+ }
25982
+ return {
25983
+ lastTaskMessage,
25984
+ failedNodeId: opts.nodeId || null,
25985
+ failedSessionId: opts.sessionId || null,
25986
+ failedProviderType: null,
25987
+ // filled by caller if available
25988
+ consecutiveNodeFailures,
25989
+ taskAttemptCount,
25990
+ retryRecommended,
25991
+ advice
25992
+ };
25993
+ }
25994
+ function rotateLedgerFile(meshId, currentPath) {
25995
+ let index = 1;
25996
+ while ((0, import_fs6.existsSync)(getRotatedPath(meshId, index))) {
25997
+ index++;
25998
+ if (index > 10) break;
25999
+ }
26000
+ if (index > 10) index = 10;
26001
+ try {
26002
+ (0, import_fs6.renameSync)(currentPath, getRotatedPath(meshId, index));
26003
+ } catch {
26004
+ }
26005
+ }
26006
+ function getQueuePath(meshId) {
26007
+ const safe = meshId.replace(/[^a-zA-Z0-9_-]/g, "_");
26008
+ return (0, import_path4.join)(getLedgerDir(), `${safe}.queue.json`);
26009
+ }
26010
+ function readQueue(meshId) {
26011
+ const path28 = getQueuePath(meshId);
26012
+ if (!(0, import_fs7.existsSync)(path28)) return [];
26013
+ try {
26014
+ const content = (0, import_fs7.readFileSync)(path28, "utf-8");
26015
+ return JSON.parse(content);
26016
+ } catch {
26017
+ return [];
26018
+ }
26019
+ }
26020
+ function writeQueue(meshId, queue) {
26021
+ const path28 = getQueuePath(meshId);
26022
+ (0, import_fs7.writeFileSync)(path28, JSON.stringify(queue, null, 2), "utf-8");
26023
+ }
26024
+ function enqueueTask(meshId, message, opts) {
26025
+ const queue = readQueue(meshId);
26026
+ const entry = {
26027
+ id: (0, import_crypto5.randomUUID)(),
26028
+ meshId,
26029
+ message,
26030
+ status: "pending",
26031
+ targetNodeId: opts?.targetNodeId,
26032
+ createdAt: (/* @__PURE__ */ new Date()).toISOString(),
26033
+ updatedAt: (/* @__PURE__ */ new Date()).toISOString()
26034
+ };
26035
+ queue.push(entry);
26036
+ writeQueue(meshId, queue);
26037
+ return entry;
26038
+ }
26039
+ function getQueue(meshId, opts) {
26040
+ let queue = readQueue(meshId);
26041
+ if (opts?.status?.length) {
26042
+ const statuses = new Set(opts.status);
26043
+ queue = queue.filter((q) => statuses.has(q.status));
26044
+ }
26045
+ return queue;
26046
+ }
26047
+ function claimNextTask(meshId, nodeId, sessionId) {
26048
+ const queue = readQueue(meshId);
26049
+ let targetIdx = queue.findIndex((q) => q.status === "pending" && q.targetNodeId === nodeId);
26050
+ if (targetIdx === -1) {
26051
+ targetIdx = queue.findIndex((q) => q.status === "pending" && !q.targetNodeId);
26052
+ }
26053
+ if (targetIdx === -1) return null;
26054
+ const entry = queue[targetIdx];
26055
+ entry.status = "assigned";
26056
+ entry.assignedNodeId = nodeId;
26057
+ entry.assignedSessionId = sessionId;
26058
+ entry.updatedAt = (/* @__PURE__ */ new Date()).toISOString();
26059
+ writeQueue(meshId, queue);
26060
+ return entry;
26061
+ }
26062
+ function updateTaskStatus(meshId, taskId, status) {
26063
+ const queue = readQueue(meshId);
26064
+ const idx = queue.findIndex((q) => q.id === taskId);
26065
+ if (idx === -1) return null;
26066
+ queue[idx].status = status;
26067
+ queue[idx].updatedAt = (/* @__PURE__ */ new Date()).toISOString();
26068
+ writeQueue(meshId, queue);
26069
+ return queue[idx];
26070
+ }
26071
+ function updateSessionTaskStatus(meshId, sessionId, status) {
26072
+ const queue = readQueue(meshId);
26073
+ for (let i = queue.length - 1; i >= 0; i--) {
26074
+ if (queue[i].assignedSessionId === sessionId && queue[i].status === "assigned") {
26075
+ queue[i].status = status;
26076
+ queue[i].updatedAt = (/* @__PURE__ */ new Date()).toISOString();
26077
+ writeQueue(meshId, queue);
26078
+ return queue[i];
26079
+ }
26080
+ }
26081
+ return null;
26082
+ }
26083
+ function getMeshQueueStats(meshId) {
26084
+ const queue = readQueue(meshId);
26085
+ return {
26086
+ pending: queue.filter((q) => q.status === "pending").length,
26087
+ assigned: queue.filter((q) => q.status === "assigned").length,
26088
+ completed: queue.filter((q) => q.status === "completed").length,
26089
+ failed: queue.filter((q) => q.status === "failed").length
26090
+ };
26091
+ }
25784
26092
  function setLogLevel(level) {
25785
26093
  currentLevel = level;
25786
26094
  daemonLog("Logger", `Log level set to: ${level}`, "info");
@@ -25795,13 +26103,13 @@ function getDaemonLogDir() {
25795
26103
  return LOG_DIR;
25796
26104
  }
25797
26105
  function getCurrentDaemonLogPath(date5 = /* @__PURE__ */ new Date()) {
25798
- return path10.join(LOG_DIR, `daemon-${date5.toISOString().slice(0, 10)}.log`);
26106
+ return path8.join(LOG_DIR, `daemon-${date5.toISOString().slice(0, 10)}.log`);
25799
26107
  }
25800
26108
  function checkDateRotation() {
25801
26109
  const today = getDateStr();
25802
26110
  if (today !== currentDate) {
25803
26111
  currentDate = today;
25804
- currentLogFile = path10.join(LOG_DIR, `daemon-${currentDate}.log`);
26112
+ currentLogFile = path8.join(LOG_DIR, `daemon-${currentDate}.log`);
25805
26113
  cleanOldLogs();
25806
26114
  }
25807
26115
  }
@@ -25815,7 +26123,7 @@ function cleanOldLogs() {
25815
26123
  const dateMatch = file2.match(/daemon-(\d{4}-\d{2}-\d{2})/);
25816
26124
  if (dateMatch && dateMatch[1] < cutoffStr) {
25817
26125
  try {
25818
- fs2.unlinkSync(path10.join(LOG_DIR, file2));
26126
+ fs2.unlinkSync(path8.join(LOG_DIR, file2));
25819
26127
  } catch {
25820
26128
  }
25821
26129
  }
@@ -25931,6 +26239,278 @@ function installGlobalInterceptor() {
25931
26239
  writeToFile(`Log file: ${currentLogFile}`);
25932
26240
  writeToFile(`Log level: ${currentLevel}`);
25933
26241
  }
26242
+ function drainPendingMeshCoordinatorEvents() {
26243
+ return pendingMeshCoordinatorEvents.splice(0);
26244
+ }
26245
+ function readNonEmptyString(value) {
26246
+ return typeof value === "string" && value.trim() ? value.trim() : "";
26247
+ }
26248
+ function isMeshCoordinatorEvent(eventName) {
26249
+ return typeof eventName === "string" && MESH_COORDINATOR_EVENTS.has(eventName);
26250
+ }
26251
+ function formatCompletionMetadata(event) {
26252
+ const parts = [
26253
+ readNonEmptyString(event.targetSessionId) ? `session_id=${readNonEmptyString(event.targetSessionId)}` : "",
26254
+ readNonEmptyString(event.providerType) ? `provider=${readNonEmptyString(event.providerType)}` : "",
26255
+ readNonEmptyString(event.providerSessionId) ? `provider_session_id=${readNonEmptyString(event.providerSessionId)}` : ""
26256
+ ].filter(Boolean);
26257
+ return parts.length > 0 ? ` (${parts.join("; ")})` : "";
26258
+ }
26259
+ function tryAssignQueueTask(components, meshId, nodeId, sessionId, providerType) {
26260
+ const task = claimNextTask(meshId, nodeId, sessionId);
26261
+ if (!task) return false;
26262
+ LOG.info("MeshQueue", `Node ${nodeId} (${sessionId}) pulled task ${task.id}`);
26263
+ components.cliManager.handleCliCommand("agent_command", {
26264
+ targetSessionId: sessionId,
26265
+ cliType: providerType,
26266
+ action: "send_chat",
26267
+ message: task.message
26268
+ }).catch((e) => {
26269
+ LOG.error("MeshQueue", `Failed to dispatch task to node ${nodeId}: ${e?.message}`);
26270
+ });
26271
+ return true;
26272
+ }
26273
+ function triggerMeshQueue(components, meshId) {
26274
+ const mesh = getMesh(meshId);
26275
+ if (!mesh) return;
26276
+ const cliInstances = components.instanceManager.getByCategory("cli");
26277
+ for (const inst of cliInstances) {
26278
+ const state = inst.getState();
26279
+ const settings = state.settings || {};
26280
+ const instMeshId = readNonEmptyString(settings.meshNodeFor);
26281
+ if (instMeshId !== meshId && !settings.launchedByCoordinator) continue;
26282
+ const nodeId = readNonEmptyString(settings.meshNodeId) || readNonEmptyString(settings.nodeId);
26283
+ if (!nodeId) continue;
26284
+ if (state.status !== "idle" && state.status !== "stopped" && state.activeChat?.status !== "waiting_input") continue;
26285
+ const sessionId = state.instanceId;
26286
+ const providerType = state.type || readNonEmptyString(settings.providerType);
26287
+ if (providerType) {
26288
+ tryAssignQueueTask(components, meshId, nodeId, sessionId, providerType);
26289
+ }
26290
+ }
26291
+ }
26292
+ function buildMeshSystemMessage(args) {
26293
+ const metadata = formatCompletionMetadata(args.metadataEvent);
26294
+ if (args.event === "agent:generating_completed") {
26295
+ return `[System] ${args.nodeLabel} has completed its task and is now idle${metadata}. This completion came from the agent status event path; use mesh_read_chat once to review its final progress, but do not poll repeatedly.`;
26296
+ }
26297
+ if (args.event === "agent:waiting_approval") {
26298
+ return `[System] ${args.nodeLabel} is waiting for approval to proceed${metadata}. You may use mesh_read_chat and mesh_approve to handle it.`;
26299
+ }
26300
+ if (args.event === "agent:stopped") {
26301
+ const rc = args.recoveryContext;
26302
+ if (rc && rc.consecutiveNodeFailures > 0) {
26303
+ const parts = [
26304
+ `[System] ${args.nodeLabel} has stopped unexpectedly${metadata}.`,
26305
+ `
26306
+
26307
+ **Recovery Context:**`,
26308
+ `- Consecutive failures on this node: ${rc.consecutiveNodeFailures}`,
26309
+ rc.taskAttemptCount > 0 ? `- This task has been attempted ${rc.taskAttemptCount} time(s)` : "",
26310
+ `- Recommendation: ${rc.advice}`
26311
+ ];
26312
+ if (rc.retryRecommended && rc.lastTaskMessage) {
26313
+ parts.push(
26314
+ `
26315
+
26316
+ **Original task to retry:**`,
26317
+ `> ${rc.lastTaskMessage.length > 300 ? rc.lastTaskMessage.slice(0, 300) + "..." : rc.lastTaskMessage}`,
26318
+ `
26319
+ To retry: call \`mesh_launch_session\` for this node, then \`mesh_send_task\` with the original task.`
26320
+ );
26321
+ } else if (!rc.retryRecommended) {
26322
+ parts.push(
26323
+ `
26324
+ Do NOT retry on this node. Consider reassigning to a different node or asking the user for guidance.`
26325
+ );
26326
+ }
26327
+ return parts.filter(Boolean).join("\n");
26328
+ }
26329
+ return `[System] ${args.nodeLabel} has stopped${metadata}. Use mesh_read_chat once if you need to inspect its last output.`;
26330
+ }
26331
+ if (args.event === "monitor:long_generating") {
26332
+ return `[System] ${args.nodeLabel} has been generating for a long time${metadata}. Use mesh_read_chat once for a status check, but do not poll repeatedly.`;
26333
+ }
26334
+ return "";
26335
+ }
26336
+ function injectMeshSystemMessage(components, args) {
26337
+ if (args.event === "agent:generating_completed") {
26338
+ const sessionId = readNonEmptyString(args.metadataEvent.targetSessionId);
26339
+ const nodeId = readNonEmptyString(args.metadataEvent.nodeId) || readNonEmptyString(args.metadataEvent.meshNodeId);
26340
+ const providerType = readNonEmptyString(args.metadataEvent.providerType);
26341
+ if (sessionId) {
26342
+ updateSessionTaskStatus(args.meshId, sessionId, "completed");
26343
+ if (nodeId && providerType) {
26344
+ setTimeout(() => {
26345
+ tryAssignQueueTask(components, args.meshId, nodeId, sessionId, providerType);
26346
+ }, 500);
26347
+ }
26348
+ }
26349
+ } else if (args.event === "agent:stopped") {
26350
+ const sessionId = readNonEmptyString(args.metadataEvent.targetSessionId);
26351
+ if (sessionId) {
26352
+ updateSessionTaskStatus(args.meshId, sessionId, "failed");
26353
+ }
26354
+ }
26355
+ const ledgerKind = EVENT_TO_LEDGER_KIND[args.event];
26356
+ if (ledgerKind) {
26357
+ try {
26358
+ appendLedgerEntry(args.meshId, {
26359
+ kind: ledgerKind,
26360
+ nodeId: readNonEmptyString(args.metadataEvent.nodeId) || readNonEmptyString(args.metadataEvent.meshNodeId) || void 0,
26361
+ sessionId: readNonEmptyString(args.metadataEvent.targetSessionId) || void 0,
26362
+ providerType: readNonEmptyString(args.metadataEvent.providerType) || void 0,
26363
+ payload: {
26364
+ event: args.event,
26365
+ nodeLabel: args.nodeLabel,
26366
+ providerSessionId: readNonEmptyString(args.metadataEvent.providerSessionId) || void 0
26367
+ }
26368
+ });
26369
+ } catch (e) {
26370
+ LOG.warn("MeshLedger", `Failed to record ${ledgerKind}: ${e?.message || e}`);
26371
+ }
26372
+ }
26373
+ let recoveryContext = null;
26374
+ if (args.event === "agent:stopped") {
26375
+ try {
26376
+ const mesh = getMesh(args.meshId);
26377
+ const maxRetries = mesh?.policy?.maxTaskRetries ?? 1;
26378
+ recoveryContext = getSessionRecoveryContext(args.meshId, {
26379
+ sessionId: readNonEmptyString(args.metadataEvent.targetSessionId) || void 0,
26380
+ nodeId: readNonEmptyString(args.metadataEvent.nodeId) || readNonEmptyString(args.metadataEvent.meshNodeId) || void 0,
26381
+ maxRetries
26382
+ });
26383
+ recoveryContext.failedProviderType = readNonEmptyString(args.metadataEvent.providerType) || null;
26384
+ if (recoveryContext.retryRecommended && recoveryContext.consecutiveNodeFailures > 0) {
26385
+ appendLedgerEntry(args.meshId, {
26386
+ kind: "recovery_attempted",
26387
+ nodeId: recoveryContext.failedNodeId || void 0,
26388
+ sessionId: recoveryContext.failedSessionId || void 0,
26389
+ providerType: recoveryContext.failedProviderType || void 0,
26390
+ payload: {
26391
+ consecutiveFailures: recoveryContext.consecutiveNodeFailures,
26392
+ taskAttemptCount: recoveryContext.taskAttemptCount,
26393
+ retryRecommended: recoveryContext.retryRecommended,
26394
+ advice: recoveryContext.advice
26395
+ }
26396
+ });
26397
+ if (recoveryContext.lastTaskMessage && recoveryContext.failedNodeId && recoveryContext.failedProviderType) {
26398
+ const autoNodeId = recoveryContext.failedNodeId;
26399
+ try {
26400
+ const task = enqueueTask(args.meshId, recoveryContext.lastTaskMessage, {
26401
+ targetNodeId: autoNodeId
26402
+ });
26403
+ LOG.info("MeshRecovery", `Auto-requeued failed task: ${task.id} for node ${autoNodeId}`);
26404
+ const node = mesh?.nodes.find((n) => n.id === autoNodeId);
26405
+ if (node) {
26406
+ components.cliManager.handleCliCommand("launch_cli", {
26407
+ cliType: recoveryContext.failedProviderType,
26408
+ dir: node.workspace,
26409
+ settings: {
26410
+ meshNodeFor: args.meshId,
26411
+ meshNodeId: node.id,
26412
+ spawnedSessionVisibility: mesh?.policy?.spawnedSessionVisibility || "hidden",
26413
+ launchedByCoordinator: true
26414
+ }
26415
+ }).catch((e) => LOG.error("MeshRecovery", `Failed to auto-relaunch session for ${node.id}: ${e?.message}`));
26416
+ }
26417
+ } catch (e) {
26418
+ LOG.warn("MeshRecovery", `Failed to execute auto-recovery: ${e?.message}`);
26419
+ }
26420
+ }
26421
+ }
26422
+ LOG.info("MeshRecovery", `Recovery context for ${args.nodeLabel}: ${recoveryContext.advice}`);
26423
+ } catch (e) {
26424
+ LOG.warn("MeshRecovery", `Failed to build recovery context: ${e?.message || e}`);
26425
+ }
26426
+ }
26427
+ const coordinatorInstances = components.instanceManager.getByCategory("cli").filter((inst) => {
26428
+ const instState = inst.getState();
26429
+ if (instState.settings?.meshCoordinatorFor !== args.meshId) return false;
26430
+ if (args.sourceInstanceId && instState.instanceId === args.sourceInstanceId) return false;
26431
+ return true;
26432
+ });
26433
+ if (coordinatorInstances.length === 0) {
26434
+ if (pendingMeshCoordinatorEvents.length < MAX_PENDING_EVENTS) {
26435
+ pendingMeshCoordinatorEvents.push({
26436
+ event: args.event,
26437
+ meshId: args.meshId,
26438
+ nodeLabel: args.nodeLabel,
26439
+ metadataEvent: {
26440
+ ...args.metadataEvent,
26441
+ ...recoveryContext ? { recoveryContext } : {}
26442
+ },
26443
+ queuedAt: Date.now()
26444
+ });
26445
+ LOG.info("MeshEvents", `Queued ${args.event} for MCP coordinator (mesh ${args.meshId})`);
26446
+ }
26447
+ return { success: true, forwarded: 0 };
26448
+ }
26449
+ const messageText = buildMeshSystemMessage({
26450
+ event: args.event,
26451
+ nodeLabel: args.nodeLabel,
26452
+ metadataEvent: args.metadataEvent,
26453
+ recoveryContext
26454
+ });
26455
+ if (!messageText) return { success: false, error: "unsupported mesh event" };
26456
+ for (const coord of coordinatorInstances) {
26457
+ const coordState = coord.getState();
26458
+ LOG.info("MeshEvents", `Forwarding mesh event to coordinator ${coordState.instanceId}`);
26459
+ coord.onEvent("send_message", { input: { text: messageText, textFallback: messageText } });
26460
+ }
26461
+ return { success: true, forwarded: coordinatorInstances.length };
26462
+ }
26463
+ function handleMeshForwardEvent(components, payload) {
26464
+ const eventName = readNonEmptyString(payload.event);
26465
+ if (!isMeshCoordinatorEvent(eventName)) {
26466
+ return { success: false, error: "unsupported mesh event" };
26467
+ }
26468
+ const meshId = readNonEmptyString(payload.meshId);
26469
+ if (!meshId) return { success: false, error: "meshId required" };
26470
+ const nodeId = readNonEmptyString(payload.nodeId);
26471
+ const workspace = readNonEmptyString(payload.workspace);
26472
+ const nodeLabel = nodeId ? `Node '${nodeId}'` : workspace ? `Agent at ${workspace}` : "Remote agent";
26473
+ return injectMeshSystemMessage(components, {
26474
+ meshId,
26475
+ nodeLabel,
26476
+ event: eventName,
26477
+ metadataEvent: {
26478
+ targetSessionId: readNonEmptyString(payload.targetSessionId) || readNonEmptyString(payload.sessionId),
26479
+ providerType: readNonEmptyString(payload.providerType),
26480
+ providerSessionId: readNonEmptyString(payload.providerSessionId)
26481
+ }
26482
+ });
26483
+ }
26484
+ function setupMeshEventForwarding(components) {
26485
+ components.instanceManager.onEvent((event) => {
26486
+ if (!isMeshCoordinatorEvent(event.event)) return;
26487
+ const instanceId = readNonEmptyString(event.instanceId);
26488
+ if (!instanceId) return;
26489
+ const sourceInstance = components.instanceManager.getInstance(instanceId);
26490
+ if (!sourceInstance || sourceInstance.category !== "cli") return;
26491
+ const state = sourceInstance.getState();
26492
+ const workspace = readNonEmptyString(state.workspace);
26493
+ if (!workspace) return;
26494
+ const settings = state.settings && typeof state.settings === "object" ? state.settings : {};
26495
+ if (readNonEmptyString(settings.meshCoordinatorFor)) return;
26496
+ const meshIdFromRuntime = readNonEmptyString(settings.meshNodeFor);
26497
+ const isMeshDelegate = Boolean(meshIdFromRuntime || settings.launchedByCoordinator);
26498
+ if (!isMeshDelegate) return;
26499
+ const mesh = meshIdFromRuntime ? getMesh(meshIdFromRuntime) : getMeshByRepo(workspace);
26500
+ const meshId = meshIdFromRuntime || readNonEmptyString(mesh?.id);
26501
+ if (!meshId) return;
26502
+ const targetNode = mesh?.nodes?.find((n) => n.workspace === workspace);
26503
+ const runtimeNodeId = readNonEmptyString(settings.meshNodeId);
26504
+ const nodeLabel = targetNode ? `Node '${targetNode.id}'` : runtimeNodeId ? `Node '${runtimeNodeId}'` : `Agent at ${workspace}`;
26505
+ injectMeshSystemMessage(components, {
26506
+ meshId,
26507
+ sourceInstanceId: instanceId,
26508
+ nodeLabel,
26509
+ event: event.event,
26510
+ metadataEvent: event
26511
+ });
26512
+ });
26513
+ }
25934
26514
  function normalizeCategories(categories) {
25935
26515
  if (!Array.isArray(categories)) return [];
25936
26516
  return categories.map((category) => String(category || "").trim()).filter(Boolean);
@@ -26537,7 +27117,7 @@ async function validateWorkspace(workspace) {
26537
27117
  cwd: normalizedWorkspace
26538
27118
  });
26539
27119
  }
26540
- await (0, import_promises5.access)(normalizedWorkspace, import_fs6.constants.R_OK);
27120
+ await (0, import_promises5.access)(normalizedWorkspace, import_fs8.constants.R_OK);
26541
27121
  } catch (error48) {
26542
27122
  if (error48 instanceof GitCommandError) throw error48;
26543
27123
  throw new GitCommandError("invalid_args", "Workspace must be an existing directory", {
@@ -27150,12 +27730,12 @@ function createDefaultGitCommandServices() {
27150
27730
  }),
27151
27731
  compareSnapshots: ({ beforeSnapshotId, afterSnapshotId }) => defaultSnapshotStore.compare(beforeSnapshotId, afterSnapshotId),
27152
27732
  getLog: ({ workspace, limit, path: filePath, since, until }) => getGitLog(workspace, { limit, path: filePath, since, until }),
27153
- checkpoint: async ({ workspace, message, includeUntracked = false }) => gitCheckpoint2(workspace, message, includeUntracked),
27733
+ checkpoint: async ({ workspace, message, includeUntracked = false }) => gitCheckpoint(workspace, message, includeUntracked),
27154
27734
  stashPush: async ({ workspace, message, includeUntracked = false }) => gitStashPush(workspace, message, includeUntracked),
27155
27735
  stashPop: async ({ workspace, stashRef }) => gitStashPop(workspace, stashRef),
27156
27736
  checkoutFiles: async ({ workspace, paths }) => gitCheckoutFiles(workspace, paths),
27157
27737
  getRemoteUrl: async ({ workspace, remote = "origin" }) => gitGetRemoteUrl(workspace, remote),
27158
- push: async ({ workspace, remote = "origin", branch, setUpstream = false }) => gitPush2(workspace, remote, branch, setUpstream)
27738
+ push: async ({ workspace, remote = "origin", branch, setUpstream = false }) => gitPush(workspace, remote, branch, setUpstream)
27159
27739
  };
27160
27740
  }
27161
27741
  function validateWorkspace2(args) {
@@ -27350,7 +27930,7 @@ function validateMutatingMessage(value) {
27350
27930
  }
27351
27931
  return msg;
27352
27932
  }
27353
- async function gitCheckpoint2(workspace, message, includeUntracked) {
27933
+ async function gitCheckpoint(workspace, message, includeUntracked) {
27354
27934
  const repo = await resolveGitRepository(workspace);
27355
27935
  const repoRoot = repo.repoRoot;
27356
27936
  const statusResult = await getGitRepoStatus(workspace);
@@ -27441,7 +28021,7 @@ async function gitGetRemoteUrl(workspace, remote) {
27441
28021
  }
27442
28022
  return { remoteUrl, remote };
27443
28023
  }
27444
- async function gitPush2(workspace, remote, branch, setUpstream) {
28024
+ async function gitPush(workspace, remote, branch, setUpstream) {
27445
28025
  const lastCheckedAt = Date.now();
27446
28026
  const repo = await resolveGitRepository(workspace);
27447
28027
  const repoRoot = repo.repoRoot;
@@ -27544,7 +28124,7 @@ function validateGitLogPath(repoRoot, filePath) {
27544
28124
  function expandPath(p) {
27545
28125
  const t = (p || "").trim();
27546
28126
  if (!t) return "";
27547
- if (t.startsWith("~")) return path5.join(os5.homedir(), t.slice(1).replace(/^\//, ""));
28127
+ if (t.startsWith("~")) return path5.join(os4.homedir(), t.slice(1).replace(/^\//, ""));
27548
28128
  return path5.resolve(t);
27549
28129
  }
27550
28130
  function validateWorkspacePath(absPath) {
@@ -27617,7 +28197,7 @@ function resolveLaunchDirectory(args, config2) {
27617
28197
  };
27618
28198
  }
27619
28199
  if (a.useHome === true) {
27620
- return { ok: true, path: os5.homedir(), source: "home" };
28200
+ return { ok: true, path: os4.homedir(), source: "home" };
27621
28201
  }
27622
28202
  return {
27623
28203
  ok: false,
@@ -27675,7 +28255,7 @@ function addWorkspaceEntry(config2, rawPath, label, options) {
27675
28255
  return { error: `Maximum ${MAX_WORKSPACES} workspaces` };
27676
28256
  }
27677
28257
  const entry = {
27678
- id: (0, import_crypto4.randomUUID)(),
28258
+ id: (0, import_crypto6.randomUUID)(),
27679
28259
  path: abs,
27680
28260
  label: (label || "").trim() || defaultWorkspaceLabel(abs),
27681
28261
  addedAt: Date.now()
@@ -28030,13 +28610,31 @@ async function syncMeshes(transport) {
28030
28610
  }
28031
28611
  }
28032
28612
  }
28613
+ if (transport.syncMeshLedger) {
28614
+ for (const local of localMeshes) {
28615
+ try {
28616
+ await syncMeshLedger(local.id, transport);
28617
+ } catch (e) {
28618
+ result.errors.push(`Ledger sync failed for "${local.name}": ${e.message}`);
28619
+ }
28620
+ }
28621
+ }
28033
28622
  return result;
28034
28623
  }
28624
+ async function syncMeshLedger(meshId, transport) {
28625
+ if (!transport.syncMeshLedger) return;
28626
+ const { readLedgerEntries: readLedgerEntries2, appendRemoteLedgerEntries: appendRemoteLedgerEntries2 } = await Promise.resolve().then(() => (init_mesh_ledger(), mesh_ledger_exports));
28627
+ const localEntries = readLedgerEntries2(meshId);
28628
+ const res = await transport.syncMeshLedger(meshId, { newEntries: localEntries });
28629
+ if (res.missingEntries && res.missingEntries.length > 0) {
28630
+ appendRemoteLedgerEntries2(meshId, res.missingEntries);
28631
+ }
28632
+ }
28035
28633
  function isPlainObject22(value) {
28036
28634
  return !!value && typeof value === "object" && !Array.isArray(value);
28037
28635
  }
28038
28636
  function getStatePath() {
28039
- return (0, import_path3.join)(getConfigDir(), "state.json");
28637
+ return (0, import_path5.join)(getConfigDir(), "state.json");
28040
28638
  }
28041
28639
  function normalizeState(raw) {
28042
28640
  const parsed = isPlainObject22(raw) ? raw : {};
@@ -28072,11 +28670,11 @@ function normalizeState(raw) {
28072
28670
  }
28073
28671
  function loadState() {
28074
28672
  const statePath = getStatePath();
28075
- if (!(0, import_fs7.existsSync)(statePath)) {
28673
+ if (!(0, import_fs9.existsSync)(statePath)) {
28076
28674
  return { ...DEFAULT_STATE };
28077
28675
  }
28078
28676
  try {
28079
- const raw = (0, import_fs7.readFileSync)(statePath, "utf-8");
28677
+ const raw = (0, import_fs9.readFileSync)(statePath, "utf-8");
28080
28678
  return normalizeState(JSON.parse(raw));
28081
28679
  } catch {
28082
28680
  return { ...DEFAULT_STATE };
@@ -28085,7 +28683,7 @@ function loadState() {
28085
28683
  function saveState(state) {
28086
28684
  const statePath = getStatePath();
28087
28685
  const normalized = normalizeState(state);
28088
- (0, import_fs7.writeFileSync)(statePath, JSON.stringify(normalized, null, 2), { encoding: "utf-8", mode: 384 });
28686
+ (0, import_fs9.writeFileSync)(statePath, JSON.stringify(normalized, null, 2), { encoding: "utf-8", mode: 384 });
28089
28687
  }
28090
28688
  function resetState() {
28091
28689
  saveState({ ...DEFAULT_STATE });
@@ -28106,10 +28704,10 @@ function getMergedDefinitions() {
28106
28704
  function findCliCommand(command) {
28107
28705
  const trimmed = String(command || "").trim();
28108
28706
  if (!trimmed) return null;
28109
- if (path8.isAbsolute(trimmed) || trimmed.includes("/") || trimmed.includes("\\") || trimmed.startsWith("~")) {
28110
- const candidate = trimmed.startsWith("~") ? path8.join((0, import_os3.homedir)(), trimmed.slice(1)) : trimmed;
28111
- const resolved = path8.isAbsolute(candidate) ? candidate : path8.resolve(candidate);
28112
- return (0, import_fs8.existsSync)(resolved) ? resolved : null;
28707
+ if (path9.isAbsolute(trimmed) || trimmed.includes("/") || trimmed.includes("\\") || trimmed.startsWith("~")) {
28708
+ const candidate = trimmed.startsWith("~") ? path9.join((0, import_os3.homedir)(), trimmed.slice(1)) : trimmed;
28709
+ const resolved = path9.isAbsolute(candidate) ? candidate : path9.resolve(candidate);
28710
+ return (0, import_fs10.existsSync)(resolved) ? resolved : null;
28113
28711
  }
28114
28712
  try {
28115
28713
  const result = (0, import_child_process4.execSync)(
@@ -28136,13 +28734,13 @@ function getIdeVersion(cliCommand) {
28136
28734
  function checkPathExists(paths) {
28137
28735
  const home = (0, import_os3.homedir)();
28138
28736
  for (const p of paths) {
28139
- const normalized = p.startsWith("~") ? path8.join(home, p.slice(1)) : p;
28737
+ const normalized = p.startsWith("~") ? path9.join(home, p.slice(1)) : p;
28140
28738
  if (normalized.includes("*")) {
28141
28739
  const username = home.split(/[\\/]/).pop() || "";
28142
28740
  const resolved = normalized.replace("*", username);
28143
- if ((0, import_fs8.existsSync)(resolved)) return resolved;
28741
+ if ((0, import_fs10.existsSync)(resolved)) return resolved;
28144
28742
  } else {
28145
- if ((0, import_fs8.existsSync)(normalized)) return normalized;
28743
+ if ((0, import_fs10.existsSync)(normalized)) return normalized;
28146
28744
  }
28147
28745
  }
28148
28746
  return null;
@@ -28156,7 +28754,7 @@ async function detectIDEs(providerLoader) {
28156
28754
  let resolvedCli = cliPath;
28157
28755
  if (!resolvedCli && appPath && os222 === "darwin") {
28158
28756
  const bundledCli = `${appPath}/Contents/Resources/app/bin/${def.cli}`;
28159
- if ((0, import_fs8.existsSync)(bundledCli)) resolvedCli = bundledCli;
28757
+ if ((0, import_fs10.existsSync)(bundledCli)) resolvedCli = bundledCli;
28160
28758
  }
28161
28759
  if (!resolvedCli && appPath && os222 === "win32") {
28162
28760
  const { dirname: dirname92 } = await import("path");
@@ -28169,7 +28767,7 @@ async function detectIDEs(providerLoader) {
28169
28767
  `${appDir}\\\\resources\\\\app\\\\bin\\\\${def.cli}.cmd`
28170
28768
  ];
28171
28769
  for (const c of candidates) {
28172
- if ((0, import_fs8.existsSync)(c)) {
28770
+ if ((0, import_fs10.existsSync)(c)) {
28173
28771
  resolvedCli = c;
28174
28772
  break;
28175
28773
  }
@@ -28201,19 +28799,19 @@ function shellQuote(value) {
28201
28799
  function expandHome(value) {
28202
28800
  const trimmed = value.trim();
28203
28801
  if (!trimmed.startsWith("~")) return trimmed;
28204
- return path9.join(os22.homedir(), trimmed.slice(1));
28802
+ return path10.join(os32.homedir(), trimmed.slice(1));
28205
28803
  }
28206
28804
  function isExplicitCommandPath(command) {
28207
28805
  const trimmed = command.trim();
28208
- return path9.isAbsolute(trimmed) || trimmed.includes("/") || trimmed.includes("\\") || trimmed.startsWith("~");
28806
+ return path10.isAbsolute(trimmed) || trimmed.includes("/") || trimmed.includes("\\") || trimmed.startsWith("~");
28209
28807
  }
28210
28808
  function resolveCommandPath(command) {
28211
28809
  const trimmed = command.trim();
28212
28810
  if (!trimmed) return null;
28213
28811
  if (isExplicitCommandPath(trimmed)) {
28214
28812
  const expanded = expandHome(trimmed);
28215
- const candidate = path9.isAbsolute(expanded) ? expanded : path9.resolve(expanded);
28216
- return (0, import_fs9.existsSync)(candidate) ? candidate : null;
28813
+ const candidate = path10.isAbsolute(expanded) ? expanded : path10.resolve(expanded);
28814
+ return (0, import_fs11.existsSync)(candidate) ? candidate : null;
28217
28815
  }
28218
28816
  return null;
28219
28817
  }
@@ -28234,7 +28832,7 @@ function execAsync(cmd, timeoutMs = 5e3) {
28234
28832
  });
28235
28833
  }
28236
28834
  async function detectCLIs(providerLoader, options) {
28237
- const platform10 = os22.platform();
28835
+ const platform10 = os32.platform();
28238
28836
  const whichCmd = platform10 === "win32" ? "where" : "which";
28239
28837
  const includeVersion = options?.includeVersion !== false;
28240
28838
  const cliList = providerLoader ? providerLoader.getCliDetectionList() : [];
@@ -28278,7 +28876,7 @@ async function detectCLI(cliId, providerLoader, options) {
28278
28876
  const cliList = providerLoader.getCliDetectionList();
28279
28877
  const target = cliList.find((c) => c.id === resolvedId);
28280
28878
  if (target) {
28281
- const platform10 = os22.platform();
28879
+ const platform10 = os32.platform();
28282
28880
  const whichCmd = platform10 === "win32" ? "where" : "which";
28283
28881
  try {
28284
28882
  const explicitPath = resolveCommandPath(target.command);
@@ -28314,7 +28912,7 @@ async function detectCLI(cliId, providerLoader, options) {
28314
28912
  return all.find((c) => c.id === resolvedId && c.installed) || null;
28315
28913
  }
28316
28914
  function parseDarwinAvailableBytes(totalMem) {
28317
- if (os32.platform() !== "darwin") return null;
28915
+ if (os42.platform() !== "darwin") return null;
28318
28916
  try {
28319
28917
  const out = (0, import_child_process6.execSync)("vm_stat", {
28320
28918
  encoding: "utf-8",
@@ -28345,8 +28943,8 @@ function parseDarwinAvailableBytes(totalMem) {
28345
28943
  }
28346
28944
  }
28347
28945
  function getHostMemorySnapshot() {
28348
- const totalMem = os32.totalmem();
28349
- const freeMem = os32.freemem();
28946
+ const totalMem = os42.totalmem();
28947
+ const freeMem = os42.freemem();
28350
28948
  const darwinAvail = parseDarwinAvailableBytes(totalMem);
28351
28949
  const availableMem = darwinAvail != null ? darwinAvail : freeMem;
28352
28950
  return { totalMem, freeMem, availableMem };
@@ -30678,6 +31276,8 @@ function buildIdeWorkspaceSession(state, cdpManagers, options) {
30678
31276
  const workspace = state.workspace || null;
30679
31277
  const git = getGitSummaryForWorkspace(workspace, options);
30680
31278
  const title = activeChat?.title || state.name;
31279
+ const meshCoordinatorFor = state.settings?.meshCoordinatorFor;
31280
+ const meshQueueStats = meshCoordinatorFor ? getMeshQueueStats(meshCoordinatorFor) : void 0;
30681
31281
  return {
30682
31282
  id: state.instanceId || state.type,
30683
31283
  parentId: null,
@@ -30700,7 +31300,8 @@ function buildIdeWorkspaceSession(state, cdpManagers, options) {
30700
31300
  errorMessage: state.errorMessage,
30701
31301
  errorReason: state.errorReason,
30702
31302
  lastUpdated: state.lastUpdated,
30703
- settings: state.settings
31303
+ settings: state.settings,
31304
+ ...meshQueueStats && { meshQueueStats }
30704
31305
  };
30705
31306
  }
30706
31307
  function buildExtensionAgentSession(parent, ext, options) {
@@ -30712,6 +31313,8 @@ function buildExtensionAgentSession(parent, ext, options) {
30712
31313
  const includeSessionControls = shouldIncludeSessionControls(profile);
30713
31314
  const workspace = parent.workspace || null;
30714
31315
  const git = getGitSummaryForWorkspace(workspace, options);
31316
+ const meshCoordinatorFor = ext.settings?.meshCoordinatorFor;
31317
+ const meshQueueStats = meshCoordinatorFor ? getMeshQueueStats(meshCoordinatorFor) : void 0;
30715
31318
  return {
30716
31319
  id: ext.instanceId || `${parent.instanceId}:${ext.type}`,
30717
31320
  parentId: parent.instanceId || parent.type,
@@ -30734,7 +31337,8 @@ function buildExtensionAgentSession(parent, ext, options) {
30734
31337
  errorMessage: ext.errorMessage,
30735
31338
  errorReason: ext.errorReason,
30736
31339
  lastUpdated: ext.lastUpdated,
30737
- settings: ext.settings
31340
+ settings: ext.settings,
31341
+ ...meshQueueStats && { meshQueueStats }
30738
31342
  };
30739
31343
  }
30740
31344
  function shouldIncludeExtensionSession(ext) {
@@ -30762,6 +31366,8 @@ function buildCliSession(state, options) {
30762
31366
  const includeSessionControls = shouldIncludeSessionControls(profile);
30763
31367
  const workspace = state.workspace || null;
30764
31368
  const git = getGitSummaryForWorkspace(workspace, options);
31369
+ const meshCoordinatorFor = state.settings?.meshCoordinatorFor;
31370
+ const meshQueueStats = meshCoordinatorFor ? getMeshQueueStats(meshCoordinatorFor) : void 0;
30765
31371
  return {
30766
31372
  id: state.instanceId,
30767
31373
  parentId: null,
@@ -30800,7 +31406,8 @@ function buildCliSession(state, options) {
30800
31406
  errorMessage: state.errorMessage,
30801
31407
  errorReason: state.errorReason,
30802
31408
  lastUpdated: state.lastUpdated,
30803
- settings: state.settings
31409
+ settings: state.settings,
31410
+ ...meshQueueStats && { meshQueueStats }
30804
31411
  };
30805
31412
  }
30806
31413
  function buildAcpSession(state, options) {
@@ -30812,6 +31419,8 @@ function buildAcpSession(state, options) {
30812
31419
  const includeSessionControls = shouldIncludeSessionControls(profile);
30813
31420
  const workspace = state.workspace || null;
30814
31421
  const git = getGitSummaryForWorkspace(workspace, options);
31422
+ const meshCoordinatorFor = state.settings?.meshCoordinatorFor;
31423
+ const meshQueueStats = meshCoordinatorFor ? getMeshQueueStats(meshCoordinatorFor) : void 0;
30815
31424
  return {
30816
31425
  id: state.instanceId,
30817
31426
  parentId: null,
@@ -30833,7 +31442,8 @@ function buildAcpSession(state, options) {
30833
31442
  errorMessage: state.errorMessage,
30834
31443
  errorReason: state.errorReason,
30835
31444
  lastUpdated: state.lastUpdated,
30836
- settings: state.settings
31445
+ settings: state.settings,
31446
+ ...meshQueueStats && { meshQueueStats }
30837
31447
  };
30838
31448
  }
30839
31449
  function buildSessionEntries(allStates, cdpManagers, options = {}) {
@@ -31435,7 +32045,7 @@ function safeBundleIdSegment(value, fallback) {
31435
32045
  function createChatDebugBundleId(targetSessionId) {
31436
32046
  const timestamp2 = (/* @__PURE__ */ new Date()).toISOString().replace(/[-:.]/g, "").replace("T", "T").replace("Z", "Z");
31437
32047
  const sessionSegment = safeBundleIdSegment(targetSessionId, "unknown-session");
31438
- return `chat-debug-${timestamp2}-${sessionSegment}-${(0, import_crypto5.randomUUID)().slice(0, 8)}`;
32048
+ return `chat-debug-${timestamp2}-${sessionSegment}-${(0, import_crypto7.randomUUID)().slice(0, 8)}`;
31439
32049
  }
31440
32050
  function buildChatDebugBundleSummary(bundle) {
31441
32051
  const target = bundle.target && typeof bundle.target === "object" ? bundle.target : {};
@@ -33091,11 +33701,13 @@ async function handleOpenPanel(h, args) {
33091
33701
  async function handlePtyInput(h, args) {
33092
33702
  const { cliType, data, targetSessionId } = args || {};
33093
33703
  if (!data) return { success: false, error: "data required" };
33704
+ const cleanData = typeof data === "string" ? data.replace(/\x1b\[\?[0-9;]*c/g, "") : data;
33705
+ if (!cleanData) return { success: true };
33094
33706
  const adapter = h.getCliAdapter(targetSessionId || cliType);
33095
33707
  if (!adapter || typeof adapter.writeRaw !== "function") {
33096
33708
  return { success: false, error: `CLI adapter not found: ${targetSessionId || cliType || "unknown"}` };
33097
33709
  }
33098
- await adapter.writeRaw(data);
33710
+ await adapter.writeRaw(cleanData);
33099
33711
  return { success: true };
33100
33712
  }
33101
33713
  function handlePtyResize(_h, args) {
@@ -33891,7 +34503,7 @@ function commandExists(command) {
33891
34503
  const trimmed = command.trim();
33892
34504
  if (!trimmed) return false;
33893
34505
  if (isExplicitCommand(trimmed)) {
33894
- return (0, import_fs10.existsSync)(expandExecutable(trimmed));
34506
+ return (0, import_fs12.existsSync)(expandExecutable(trimmed));
33895
34507
  }
33896
34508
  try {
33897
34509
  (0, import_child_process7.execFileSync)(process.platform === "win32" ? "where" : "which", [trimmed], {
@@ -33912,10 +34524,10 @@ function hasCliArg(args, flag) {
33912
34524
  }
33913
34525
  function ensureEmptyDelegatedMcpConfig(workspace) {
33914
34526
  const baseDir = path18.join(os13.tmpdir(), "adhdev-delegated-agent-empty-mcp");
33915
- (0, import_fs10.mkdirSync)(baseDir, { recursive: true });
34527
+ (0, import_fs12.mkdirSync)(baseDir, { recursive: true });
33916
34528
  const workspaceHash = crypto4.createHash("sha256").update(path18.resolve(workspace || os13.tmpdir())).digest("hex").slice(0, 16);
33917
34529
  const filePath = path18.join(baseDir, `${workspaceHash}.json`);
33918
- (0, import_fs10.writeFileSync)(filePath, JSON.stringify({ mcpServers: {} }, null, 2), "utf-8");
34530
+ (0, import_fs12.writeFileSync)(filePath, JSON.stringify({ mcpServers: {} }, null, 2), "utf-8");
33919
34531
  return filePath;
33920
34532
  }
33921
34533
  function buildCoordinatorDelegatedCliLaunchOptions(input) {
@@ -34876,7 +35488,7 @@ function resolveHermesMeshCoordinatorSetup(options) {
34876
35488
  reason: "Could not resolve the ADHDev MCP server entrypoint and a Node runtime with WebSocket support for daemon IPC mode"
34877
35489
  };
34878
35490
  }
34879
- const configPath = (0, import_path4.join)(resolveHermesCoordinatorHome(options.meshId, options.workspace), "config.yaml");
35491
+ const configPath = (0, import_path6.join)(resolveHermesCoordinatorHome(options.meshId, options.workspace), "config.yaml");
34880
35492
  if (!configPath.trim()) {
34881
35493
  return createHermesManualMeshCoordinatorSetup(options.meshId, options.workspace);
34882
35494
  }
@@ -34957,6 +35569,22 @@ function resolveMeshCoordinatorSetup(options) {
34957
35569
  if (!instructions || !template?.trim()) {
34958
35570
  return { kind: "unsupported", reason: "Provider manual MCP setup is missing instructions or template" };
34959
35571
  }
35572
+ const renderedTemplate = renderMeshCoordinatorTemplate(template, {
35573
+ meshId,
35574
+ workspace,
35575
+ serverName,
35576
+ adhdevMcpCommand: options.adhdevMcpCommand || DEFAULT_ADHDEV_MCP_COMMAND
35577
+ });
35578
+ const isCliCommand = !renderedTemplate.trim().includes("\n") && !renderedTemplate.trim().startsWith("{");
35579
+ if (isCliCommand) {
35580
+ return {
35581
+ kind: "cli_command",
35582
+ serverName,
35583
+ command: renderedTemplate.trim(),
35584
+ requiresRestart: mcpConfig.requiresRestart === true,
35585
+ instructions
35586
+ };
35587
+ }
34960
35588
  return {
34961
35589
  kind: "manual",
34962
35590
  serverName,
@@ -34964,12 +35592,7 @@ function resolveMeshCoordinatorSetup(options) {
34964
35592
  configPathCommand: mcpConfig.configPathCommand,
34965
35593
  requiresRestart: mcpConfig.requiresRestart === true,
34966
35594
  instructions,
34967
- template: renderMeshCoordinatorTemplate(template, {
34968
- meshId,
34969
- workspace,
34970
- serverName,
34971
- adhdevMcpCommand: options.adhdevMcpCommand || DEFAULT_ADHDEV_MCP_COMMAND
34972
- })
35595
+ template: renderedTemplate
34973
35596
  };
34974
35597
  }
34975
35598
  return {
@@ -34982,16 +35605,16 @@ function renderMeshCoordinatorTemplate(template, values) {
34982
35605
  }
34983
35606
  function resolveHermesCoordinatorHome(meshId, workspace) {
34984
35607
  const key = `${meshId || "mesh"}
34985
- ${(0, import_path4.resolve)(workspace || os17.tmpdir())}`;
34986
- const hash2 = (0, import_crypto6.createHash)("sha256").update(key).digest("hex").slice(0, 16);
34987
- return (0, import_path4.join)(os17.tmpdir(), `adhdev-hermes-mesh-coordinator-${hash2}`);
35608
+ ${(0, import_path6.resolve)(workspace || os17.tmpdir())}`;
35609
+ const hash2 = (0, import_crypto8.createHash)("sha256").update(key).digest("hex").slice(0, 16);
35610
+ return (0, import_path6.join)(os17.tmpdir(), `adhdev-hermes-mesh-coordinator-${hash2}`);
34988
35611
  }
34989
35612
  function resolveMcpConfigPath(configPath, workspace) {
34990
35613
  const trimmed = configPath.trim();
34991
35614
  if (trimmed === "~") return os17.homedir();
34992
- if (trimmed.startsWith("~/")) return (0, import_path4.join)(os17.homedir(), trimmed.slice(2));
34993
- if ((0, import_path4.isAbsolute)(trimmed)) return trimmed;
34994
- return (0, import_path4.join)(workspace, trimmed);
35615
+ if (trimmed.startsWith("~/")) return (0, import_path6.join)(os17.homedir(), trimmed.slice(2));
35616
+ if ((0, import_path6.isAbsolute)(trimmed)) return trimmed;
35617
+ return (0, import_path6.join)(workspace, trimmed);
34995
35618
  }
34996
35619
  function resolveAdhdevMcpServerLaunch(options) {
34997
35620
  const entryPath = resolveAdhdevMcpEntryPath(options.adhdevMcpEntryPath);
@@ -35031,15 +35654,15 @@ function addNodeCandidatesFromPath(pathValue, addCandidate) {
35031
35654
  for (const entry of (pathValue || "").split(":")) {
35032
35655
  const dir = entry.trim();
35033
35656
  if (!dir) continue;
35034
- addCandidate((0, import_path4.join)(dir, "node"));
35657
+ addCandidate((0, import_path6.join)(dir, "node"));
35035
35658
  }
35036
35659
  }
35037
35660
  function addNodeCandidatesFromNvm(homeDir, addCandidate) {
35038
- const versionsDir = (0, import_path4.join)(homeDir, ".nvm", "versions", "node");
35661
+ const versionsDir = (0, import_path6.join)(homeDir, ".nvm", "versions", "node");
35039
35662
  try {
35040
- const versionDirs = (0, import_fs11.readdirSync)(versionsDir, { withFileTypes: true }).filter((entry) => entry.isDirectory()).map((entry) => entry.name).sort(compareNodeVersionNamesDescending);
35663
+ const versionDirs = (0, import_fs13.readdirSync)(versionsDir, { withFileTypes: true }).filter((entry) => entry.isDirectory()).map((entry) => entry.name).sort(compareNodeVersionNamesDescending);
35041
35664
  for (const versionDir of versionDirs) {
35042
- addCandidate((0, import_path4.join)(versionsDir, versionDir, "bin", "node"));
35665
+ addCandidate((0, import_path6.join)(versionsDir, versionDir, "bin", "node"));
35043
35666
  }
35044
35667
  } catch {
35045
35668
  }
@@ -35077,12 +35700,12 @@ function resolveAdhdevMcpEntryPath(explicitPath) {
35077
35700
  const addPackagedCandidates = (baseFile) => {
35078
35701
  if (!baseFile) return;
35079
35702
  const realBase = normalizeExistingPath(baseFile) || baseFile;
35080
- const dir = (0, import_path4.dirname)(realBase);
35081
- addCandidate((0, import_path4.resolve)(dir, "../vendor/mcp-server/index.js"));
35082
- addCandidate((0, import_path4.resolve)(dir, "../../vendor/mcp-server/index.js"));
35083
- addCandidate((0, import_path4.resolve)(dir, "../../../vendor/mcp-server/index.js"));
35084
- addCandidate((0, import_path4.resolve)(dir, "../../mcp-server/dist/index.js"));
35085
- addCandidate((0, import_path4.resolve)(dir, "../../../mcp-server/dist/index.js"));
35703
+ const dir = (0, import_path6.dirname)(realBase);
35704
+ addCandidate((0, import_path6.resolve)(dir, "../vendor/mcp-server/index.js"));
35705
+ addCandidate((0, import_path6.resolve)(dir, "../../vendor/mcp-server/index.js"));
35706
+ addCandidate((0, import_path6.resolve)(dir, "../../../vendor/mcp-server/index.js"));
35707
+ addCandidate((0, import_path6.resolve)(dir, "../../mcp-server/dist/index.js"));
35708
+ addCandidate((0, import_path6.resolve)(dir, "../../../mcp-server/dist/index.js"));
35086
35709
  };
35087
35710
  addPackagedCandidates(process.argv[1]);
35088
35711
  for (const candidate of candidates) {
@@ -35090,7 +35713,7 @@ function resolveAdhdevMcpEntryPath(explicitPath) {
35090
35713
  if (normalized) return normalized;
35091
35714
  }
35092
35715
  try {
35093
- const requireBase = process.argv[1] ? normalizeExistingPath(process.argv[1]) || process.argv[1] : (0, import_path4.join)(process.cwd(), "adhdev-daemon.js");
35716
+ const requireBase = process.argv[1] ? normalizeExistingPath(process.argv[1]) || process.argv[1] : (0, import_path6.join)(process.cwd(), "adhdev-daemon.js");
35094
35717
  const req = (0, import_module2.createRequire)(requireBase);
35095
35718
  const resolvedModule = req.resolve("@adhdev/mcp-server");
35096
35719
  return normalizeExistingPath(resolvedModule) || resolvedModule;
@@ -35100,129 +35723,12 @@ function resolveAdhdevMcpEntryPath(explicitPath) {
35100
35723
  }
35101
35724
  function normalizeExistingPath(filePath) {
35102
35725
  try {
35103
- if (!(0, import_fs11.existsSync)(filePath)) return null;
35104
- return import_fs11.realpathSync.native(filePath);
35726
+ if (!(0, import_fs13.existsSync)(filePath)) return null;
35727
+ return import_fs13.realpathSync.native(filePath);
35105
35728
  } catch {
35106
35729
  return null;
35107
35730
  }
35108
35731
  }
35109
- function drainPendingMeshCoordinatorEvents() {
35110
- return pendingMeshCoordinatorEvents.splice(0);
35111
- }
35112
- function readNonEmptyString(value) {
35113
- return typeof value === "string" && value.trim() ? value.trim() : "";
35114
- }
35115
- function isMeshCoordinatorEvent(eventName) {
35116
- return typeof eventName === "string" && MESH_COORDINATOR_EVENTS.has(eventName);
35117
- }
35118
- function formatCompletionMetadata(event) {
35119
- const parts = [
35120
- readNonEmptyString(event.targetSessionId) ? `session_id=${readNonEmptyString(event.targetSessionId)}` : "",
35121
- readNonEmptyString(event.providerType) ? `provider=${readNonEmptyString(event.providerType)}` : "",
35122
- readNonEmptyString(event.providerSessionId) ? `provider_session_id=${readNonEmptyString(event.providerSessionId)}` : ""
35123
- ].filter(Boolean);
35124
- return parts.length > 0 ? ` (${parts.join("; ")})` : "";
35125
- }
35126
- function buildMeshSystemMessage(args) {
35127
- const metadata = formatCompletionMetadata(args.metadataEvent);
35128
- if (args.event === "agent:generating_completed") {
35129
- return `[System] ${args.nodeLabel} has completed its task and is now idle${metadata}. This completion came from the agent status event path; use mesh_read_chat once to review its final progress, but do not poll repeatedly.`;
35130
- }
35131
- if (args.event === "agent:waiting_approval") {
35132
- return `[System] ${args.nodeLabel} is waiting for approval to proceed${metadata}. You may use mesh_read_chat and mesh_approve to handle it.`;
35133
- }
35134
- if (args.event === "agent:stopped") {
35135
- return `[System] ${args.nodeLabel} has stopped${metadata}. Use mesh_read_chat once if you need to inspect its last output.`;
35136
- }
35137
- if (args.event === "monitor:long_generating") {
35138
- return `[System] ${args.nodeLabel} has been generating for a long time${metadata}. Use mesh_read_chat once for a status check, but do not poll repeatedly.`;
35139
- }
35140
- return "";
35141
- }
35142
- function injectMeshSystemMessage(components, args) {
35143
- const coordinatorInstances = components.instanceManager.getByCategory("cli").filter((inst) => {
35144
- const instState = inst.getState();
35145
- if (instState.settings?.meshCoordinatorFor !== args.meshId) return false;
35146
- if (args.sourceInstanceId && instState.instanceId === args.sourceInstanceId) return false;
35147
- return true;
35148
- });
35149
- if (coordinatorInstances.length === 0) {
35150
- if (pendingMeshCoordinatorEvents.length < MAX_PENDING_EVENTS) {
35151
- pendingMeshCoordinatorEvents.push({
35152
- event: args.event,
35153
- meshId: args.meshId,
35154
- nodeLabel: args.nodeLabel,
35155
- metadataEvent: args.metadataEvent,
35156
- queuedAt: Date.now()
35157
- });
35158
- LOG.info("MeshEvents", `Queued ${args.event} for MCP coordinator (mesh ${args.meshId})`);
35159
- }
35160
- return { success: true, forwarded: 0 };
35161
- }
35162
- const messageText = buildMeshSystemMessage({
35163
- event: args.event,
35164
- nodeLabel: args.nodeLabel,
35165
- metadataEvent: args.metadataEvent
35166
- });
35167
- if (!messageText) return { success: false, error: "unsupported mesh event" };
35168
- for (const coord of coordinatorInstances) {
35169
- const coordState = coord.getState();
35170
- LOG.info("MeshEvents", `Forwarding mesh event to coordinator ${coordState.instanceId}`);
35171
- coord.onEvent("send_message", { input: { text: messageText, textFallback: messageText } });
35172
- }
35173
- return { success: true, forwarded: coordinatorInstances.length };
35174
- }
35175
- function handleMeshForwardEvent(components, payload) {
35176
- const eventName = readNonEmptyString(payload.event);
35177
- if (!isMeshCoordinatorEvent(eventName)) {
35178
- return { success: false, error: "unsupported mesh event" };
35179
- }
35180
- const meshId = readNonEmptyString(payload.meshId);
35181
- if (!meshId) return { success: false, error: "meshId required" };
35182
- const nodeId = readNonEmptyString(payload.nodeId);
35183
- const workspace = readNonEmptyString(payload.workspace);
35184
- const nodeLabel = nodeId ? `Node '${nodeId}'` : workspace ? `Agent at ${workspace}` : "Remote agent";
35185
- return injectMeshSystemMessage(components, {
35186
- meshId,
35187
- nodeLabel,
35188
- event: eventName,
35189
- metadataEvent: {
35190
- targetSessionId: readNonEmptyString(payload.targetSessionId) || readNonEmptyString(payload.sessionId),
35191
- providerType: readNonEmptyString(payload.providerType),
35192
- providerSessionId: readNonEmptyString(payload.providerSessionId)
35193
- }
35194
- });
35195
- }
35196
- function setupMeshEventForwarding(components) {
35197
- components.instanceManager.onEvent((event) => {
35198
- if (!isMeshCoordinatorEvent(event.event)) return;
35199
- const instanceId = readNonEmptyString(event.instanceId);
35200
- if (!instanceId) return;
35201
- const sourceInstance = components.instanceManager.getInstance(instanceId);
35202
- if (!sourceInstance || sourceInstance.category !== "cli") return;
35203
- const state = sourceInstance.getState();
35204
- const workspace = readNonEmptyString(state.workspace);
35205
- if (!workspace) return;
35206
- const settings = state.settings && typeof state.settings === "object" ? state.settings : {};
35207
- if (readNonEmptyString(settings.meshCoordinatorFor)) return;
35208
- const meshIdFromRuntime = readNonEmptyString(settings.meshNodeFor);
35209
- const isMeshDelegate = Boolean(meshIdFromRuntime || settings.launchedByCoordinator);
35210
- if (!isMeshDelegate) return;
35211
- const mesh = meshIdFromRuntime ? getMesh(meshIdFromRuntime) : getMeshByRepo(workspace);
35212
- const meshId = meshIdFromRuntime || readNonEmptyString(mesh?.id);
35213
- if (!meshId) return;
35214
- const targetNode = mesh?.nodes?.find((n) => n.workspace === workspace);
35215
- const runtimeNodeId = readNonEmptyString(settings.meshNodeId);
35216
- const nodeLabel = targetNode ? `Node '${targetNode.id}'` : runtimeNodeId ? `Node '${runtimeNodeId}'` : `Agent at ${workspace}`;
35217
- injectMeshSystemMessage(components, {
35218
- meshId,
35219
- sourceInstanceId: instanceId,
35220
- nodeLabel,
35221
- event: event.event,
35222
- metadataEvent: event
35223
- });
35224
- });
35225
- }
35226
35732
  function buildRecentReadDebugSignature(snapshot) {
35227
35733
  return [
35228
35734
  snapshot.providerType,
@@ -35920,22 +36426,22 @@ function serializeMeshCoordinatorMcpConfig(config2, format) {
35920
36426
  }
35921
36427
  function resolveHermesUserHome() {
35922
36428
  const explicitHome = process.env.HERMES_HOME?.trim();
35923
- return explicitHome || (0, import_path5.join)((0, import_os4.homedir)(), ".hermes");
36429
+ return explicitHome || (0, import_path7.join)((0, import_os4.homedir)(), ".hermes");
35924
36430
  }
35925
36431
  function loadHermesCoordinatorBaseConfig(targetConfigPath) {
35926
36432
  const sourceHome = resolveHermesUserHome();
35927
- const sourceConfigPath = (0, import_path5.join)(sourceHome, "config.yaml");
36433
+ const sourceConfigPath = (0, import_path7.join)(sourceHome, "config.yaml");
35928
36434
  if (!fs10.existsSync(sourceConfigPath)) return { config: {}, sourceHome, sourceConfigPath };
35929
- if ((0, import_path5.resolve)(sourceConfigPath) === (0, import_path5.resolve)(targetConfigPath)) return { config: {}, sourceHome, sourceConfigPath };
36435
+ if ((0, import_path7.resolve)(sourceConfigPath) === (0, import_path7.resolve)(targetConfigPath)) return { config: {}, sourceHome, sourceConfigPath };
35930
36436
  const parsed = parseMeshCoordinatorMcpConfig(fs10.readFileSync(sourceConfigPath, "utf-8"), "hermes_config_yaml");
35931
36437
  const { mcp_servers: _mcpServers, ...baseConfig } = parsed;
35932
36438
  return { config: baseConfig, sourceHome, sourceConfigPath };
35933
36439
  }
35934
36440
  function copyHermesCoordinatorCredentialFiles(sourceHome, targetHome) {
35935
- if ((0, import_path5.resolve)(sourceHome) === (0, import_path5.resolve)(targetHome)) return;
36441
+ if ((0, import_path7.resolve)(sourceHome) === (0, import_path7.resolve)(targetHome)) return;
35936
36442
  for (const fileName of [".env", "auth.json"]) {
35937
- const sourcePath = (0, import_path5.join)(sourceHome, fileName);
35938
- const targetPath = (0, import_path5.join)(targetHome, fileName);
36443
+ const sourcePath = (0, import_path7.join)(sourceHome, fileName);
36444
+ const targetPath = (0, import_path7.join)(targetHome, fileName);
35939
36445
  if (!fs10.existsSync(sourcePath)) continue;
35940
36446
  try {
35941
36447
  fs10.copyFileSync(sourcePath, targetPath);
@@ -40420,7 +40926,7 @@ async function shutdownDaemonComponents(components) {
40420
40926
  }
40421
40927
  cdpManagers.clear();
40422
40928
  }
40423
- var path4, import_promises4, import_fs3, import_child_process, import_util3, import_os2, import_path, import_fs4, import_crypto2, import_fs5, import_path2, import_crypto3, fs2, path10, os4, os8, os9, path14, import_child_process2, os10, path15, os11, import_child_process3, import_fs6, import_promises5, path, import_util4, import_promises6, path22, path32, fs, os5, path5, import_crypto4, path6, path7, import_fs7, import_path3, import_child_process4, import_fs8, import_os3, path8, import_child_process5, os22, path9, import_fs9, os32, import_child_process6, http, crypto2, fs3, path11, os52, fs4, os6, path12, import_crypto5, fs5, path13, os7, os13, path18, crypto4, import_fs10, import_child_process7, os12, path16, crypto3, fs6, import_module, path17, import_stream2, import_child_process8, import_child_process9, net2, os15, path20, fs7, path19, os14, fs8, path21, os16, import_child_process10, import_crypto6, import_fs11, import_module2, os17, import_path4, os18, import_child_process11, import_child_process12, fs9, os19, path222, import_os4, import_path5, fs10, fs11, path23, os20, import_child_process13, import_os5, http2, fs15, path27, fs12, path24, fs13, path25, fs14, path26, os21, import_child_process14, __defProp2, __getOwnPropDesc2, __getOwnPropNames2, __hasOwnProp2, __require2, __esm2, __export2, __copyProps2, __toCommonJS2, DEFAULT_MESH_POLICY, init_repo_mesh_types, git_worktree_exports, execFileAsync2, WORKTREE_DIR_NAME, GIT_TIMEOUT_MS, GIT_MAX_BUFFER, init_git_worktree, config_exports, DEFAULT_CONFIG, MACHINE_ID_PREFIX, init_config, mesh_config_exports, SESSION_CLEANUP_MODES, SPAWNED_SESSION_VISIBILITY_MODES, init_mesh_config, coordinator_prompt_exports, TOOLS_SECTION, TOOL_EXPOSURE_PREFLIGHT_SECTION, WORKFLOW_SECTION, init_coordinator_prompt, LEVEL_NUM, LEVEL_LABEL, currentLevel, LOG_DIR, MAX_LOG_SIZE, MAX_LOG_DAYS, currentDate, currentLogFile, writeCount, RING_BUFFER_SIZE, ringBuffer, origConsoleLog, origConsoleError, origConsoleWarn, LOG, interceptorInstalled, LOG_PATH, init_logger, NORMAL_TRACE_BUFFER_SIZE, DEV_TRACE_BUFFER_SIZE, DEFAULT_CONFIG2, currentConfig, init_debug_config, DEFAULT_BINDING_CANDIDATES, cachedBinding, cachedBindingError, GhosttyVtTerminalBackend, init_ghostty_vt_backend, TerminalCtor, XtermTerminalBackend, init_xterm_backend, DEFAULT_SCROLLBACK, loggedTerminalBackends, TerminalScreen, init_terminal_screen, init_spawn_env, cachedPty, NodePtyRuntimeTransport, NodePtyTransportFactory, init_pty_transport, TerminalTranscriptAccumulator, buildCliSpawnEnv, init_provider_cli_shared, init_provider_cli_parse, init_provider_cli_config, init_provider_cli_runtime, provider_cli_adapter_exports, ProviderCliAdapter, init_provider_cli_adapter, execFileAsync, DEFAULT_TIMEOUT_MS, DEFAULT_MAX_BUFFER, GitCommandError, DEFAULT_MAX_FILES, DEFAULT_MAX_BYTES, summarizeGitStatus, InMemoryGitSnapshotStore, DEFAULT_GIT_WORKSPACE_POLL_INTERVAL_MS, MIN_GIT_WORKSPACE_POLL_INTERVAL_MS, GitWorkspaceMonitor, GIT_COMMAND_NAMES, SNAPSHOT_REASONS, FAILURE_REASONS, defaultSnapshotStore, defaultGitCommandServices, BUSY_STATUSES, TERMINAL_STATUSES, TurnSnapshotTracker, MAX_WORKSPACES, MAX_ACTIVITY, MAX_SAVED_SESSIONS, DEFAULT_STATE, BUILTIN_IDE_DEFINITIONS, registeredIDEs, LIVE_LIFECYCLES, DEFAULT_ACTIVE_CHAT_POLL_STATUSES, DEFAULT_CHAT_TAIL_RECENT_MESSAGE_GRACE_MS, LIVE_RUNTIME_LIFECYCLES, DaemonCdpManager, CdpDomHandlers, DEFAULT_MONITOR_CONFIG, StatusMonitor, BUILTIN_CHAT_MESSAGE_KINDS, CHAT_MESSAGE_VISIBILITIES, CHAT_MESSAGE_TRANSCRIPT_VISIBILITIES, CHAT_MESSAGE_AUDIENCES, CHAT_MESSAGE_SOURCES, CHAT_MESSAGE_ACTIVITY_SOURCES, CHAT_MESSAGE_INTERNAL_SOURCES, KNOWN_CHAT_MESSAGE_KINDS, CHAT_MESSAGE_KIND_ALIASES, EXPLICIT_HIDDEN_VISIBILITIES, EXPLICIT_VISIBLE_VISIBILITIES, HIDDEN_AUDIENCES, ACTIVITY_SOURCE_SET, INTERNAL_SOURCE_SET, HISTORY_DIR, RETAIN_DAYS, SAVED_HISTORY_INDEX_VERSION, SAVED_HISTORY_INDEX_FILE, SAVED_HISTORY_INDEX_LOCK_SUFFIX, SAVED_HISTORY_INDEX_LOCK_WAIT_MS, SAVED_HISTORY_INDEX_LOCK_STALE_MS, SAVED_HISTORY_INDEX_LOCK_POLL_MS, SAVED_HISTORY_ROLLUP_THRESHOLD_BYTES, savedHistorySessionCache, savedHistoryFileSummaryCache, savedHistoryBackgroundRefresh, savedHistoryRollupInFlight, ChatHistoryWriter, IDE_PROVIDER_SESSION_CAPABILITIES_BASE, EXTENSION_PROVIDER_SESSION_CAPABILITIES_BASE, ExtensionProviderInstance, VALID_STATUSES, VALID_ROLES, VALID_BUBBLE_STATES, VALID_TURN_STATUSES, DEFAULT_APPROVAL_POSITIVE_HINTS, IdeProviderInstance, DEFAULT_CDP_SCAN_INTERVAL_MS, DEFAULT_CDP_DISCOVERY_INTERVAL_MS, DEFAULT_STATUS_INITIAL_REPORT_DELAY_MS, DEFAULT_STATUS_SERVER_REPORT_INTERVAL_MS, DEFAULT_STATUS_P2P_REPORT_INTERVAL_MS, MIN_MACHINE_RUNTIME_SUBSCRIPTION_INTERVAL_MS, DEFAULT_MACHINE_RUNTIME_SUBSCRIPTION_INTERVAL_MS, MIN_SESSION_HOST_DIAGNOSTICS_SUBSCRIPTION_INTERVAL_MS, DEFAULT_SESSION_HOST_DIAGNOSTICS_SUBSCRIPTION_INTERVAL_MS, DEFAULT_SESSION_HOST_READY_TIMEOUT_MS, STANDALONE_CDP_SCAN_INTERVAL_MS, DaemonCdpScanner, DaemonCdpInitializer, WORKING_STATUSES, FULL_STATUS_ACTIVE_CHAT_OPTIONS, LIVE_STATUS_ACTIVE_CHAT_OPTIONS, STATUS_MODAL_MESSAGE_LIMIT, STATUS_MODAL_BUTTON_LIMIT, VALID_INPUT_MEDIA_TYPES, VALID_INPUT_STRATEGIES, TEXT_ONLY_MESSAGE_INPUT_SUPPORT, IDE_SESSION_CAPABILITIES, EXTENSION_SESSION_CAPABILITIES, PTY_SESSION_CAPABILITIES, CLI_CHAT_SESSION_CAPABILITIES, ACP_SESSION_CAPABILITIES, globalStore, RECENT_SEND_WINDOW_MS, READ_CHAT_PROVIDER_EVAL_TIMEOUT_MS, HERMES_CLI_STARTING_SEND_SETTLE_MS, recentSendByTarget, DEFAULT_DEBUG_SANITIZE_OPTIONS, SECRET_KEY_PATTERN, KEY_TO_VK, COMMAND_DEBUG_LEVELS, DaemonCommandHandler, IMAGE_MIME_EXTENSIONS, MATERIALIZED_IMAGE_MAX_AGE_MS, MATERIALIZED_IMAGE_CLEANUP_INTERVAL_MS, lastMaterializedImageCleanupAt, CachedDatabaseSync, CliProviderInstance, AcpProviderInstance, chalkModule, chalkApi, COORDINATOR_DELEGATED_ENV_UNSETS, DaemonCliManager, VALID_CAPABILITY_MEDIA_TYPES, VALID_INPUT_STRATEGIES2, KNOWN_PROVIDER_FIELDS, VALUE_CONTROL_TYPES, ProviderLoader, _providerLoader, LOG_DIR2, MAX_FILE_SIZE, MAX_DAYS, SENSITIVE_KEYS, currentDate2, currentFile, writeCount2, SKIP_COMMANDS, DEFAULT_SERVER_NAME, DEFAULT_ADHDEV_MCP_COMMAND, HERMES_CLI_TYPE, HERMES_MCP_CONFIG_PATH, MAX_PENDING_EVENTS, pendingMeshCoordinatorEvents, MESH_COORDINATOR_EVENTS, READ_DEBUG_ENABLED, recentReadDebugSignatureBySession, UPGRADE_HELPER_ENV, CHANNEL_NPM_TAG, CHANNEL_SERVER_URL, CHAT_COMMANDS, READ_DEBUG_ENABLED2, DaemonCommandRouter, DaemonStatusReporter, DEFAULT_DAEMON_PORT, DAEMON_WS_PATH, ProviderStreamAdapter, DaemonAgentStreamManager, AgentStreamPoller, ProviderInstanceManager, ARCHIVE_PATH, MAX_ENTRIES_PER_PROVIDER, VersionArchive, DEV_SERVER_PORT, DevServer, SessionHostRuntimeTransport, SessionHostPtyTransportFactory, DEFAULT_SESSION_HOST_APP_NAME, DEFAULT_STANDALONE_SESSION_HOST_APP_NAME, STARTUP_TIMEOUT_MS, STARTUP_POLL_MS, SessionHostCompatibilityError, EXTENSION_CATALOG, SessionRegistry;
40929
+ var path4, import_promises4, import_fs3, import_child_process, import_util3, import_os2, import_path, import_fs4, import_crypto2, import_fs5, import_path2, import_crypto3, import_fs6, import_path3, import_crypto4, import_events2, import_fs7, import_path4, import_crypto5, fs2, path8, os22, os8, os9, path14, import_child_process2, os10, path15, os11, import_child_process3, import_fs8, import_promises5, path, import_util4, import_promises6, path22, path32, fs, os4, path5, import_crypto6, path6, path7, import_fs9, import_path5, import_child_process4, import_fs10, import_os3, path9, import_child_process5, os32, path10, import_fs11, os42, import_child_process6, http, crypto2, fs3, path11, os5, fs4, os6, path12, import_crypto7, fs5, path13, os7, os13, path18, crypto4, import_fs12, import_child_process7, os12, path16, crypto3, fs6, import_module, path17, import_stream2, import_child_process8, import_child_process9, net2, os15, path20, fs7, path19, os14, fs8, path21, os16, import_child_process10, import_crypto8, import_fs13, import_module2, os17, import_path6, os18, import_child_process11, import_child_process12, fs9, os19, path222, import_os4, import_path7, fs10, fs11, path23, os20, import_child_process13, import_os5, http2, fs15, path27, fs12, path24, fs13, path25, fs14, path26, os21, import_child_process14, __defProp2, __getOwnPropDesc2, __getOwnPropNames2, __hasOwnProp2, __require2, __esm2, __export2, __copyProps2, __toCommonJS2, DEFAULT_MESH_POLICY, init_repo_mesh_types, git_worktree_exports, execFileAsync2, WORKTREE_DIR_NAME, GIT_TIMEOUT_MS, GIT_MAX_BUFFER, init_git_worktree, config_exports, DEFAULT_CONFIG, MACHINE_ID_PREFIX, init_config, mesh_config_exports, SESSION_CLEANUP_MODES, SPAWNED_SESSION_VISIBILITY_MODES, init_mesh_config, coordinator_prompt_exports, TOOLS_SECTION, TOOL_EXPOSURE_PREFLIGHT_SECTION, WORKFLOW_SECTION, init_coordinator_prompt, mesh_ledger_exports, LEDGER_DIR_NAME, MAX_FILE_SIZE_BYTES, RECENT_FAILURE_WINDOW_MS, meshLedgerEvents, init_mesh_ledger, init_mesh_work_queue, LEVEL_NUM, LEVEL_LABEL, currentLevel, LOG_DIR, MAX_LOG_SIZE, MAX_LOG_DAYS, currentDate, currentLogFile, writeCount, RING_BUFFER_SIZE, ringBuffer, origConsoleLog, origConsoleError, origConsoleWarn, LOG, interceptorInstalled, LOG_PATH, init_logger, mesh_events_exports, MAX_PENDING_EVENTS, pendingMeshCoordinatorEvents, MESH_COORDINATOR_EVENTS, EVENT_TO_LEDGER_KIND, init_mesh_events, NORMAL_TRACE_BUFFER_SIZE, DEV_TRACE_BUFFER_SIZE, DEFAULT_CONFIG2, currentConfig, init_debug_config, DEFAULT_BINDING_CANDIDATES, cachedBinding, cachedBindingError, GhosttyVtTerminalBackend, init_ghostty_vt_backend, TerminalCtor, XtermTerminalBackend, init_xterm_backend, DEFAULT_SCROLLBACK, loggedTerminalBackends, TerminalScreen, init_terminal_screen, init_spawn_env, cachedPty, NodePtyRuntimeTransport, NodePtyTransportFactory, init_pty_transport, TerminalTranscriptAccumulator, buildCliSpawnEnv, init_provider_cli_shared, init_provider_cli_parse, init_provider_cli_config, init_provider_cli_runtime, provider_cli_adapter_exports, ProviderCliAdapter, init_provider_cli_adapter, execFileAsync, DEFAULT_TIMEOUT_MS, DEFAULT_MAX_BUFFER, GitCommandError, DEFAULT_MAX_FILES, DEFAULT_MAX_BYTES, summarizeGitStatus, InMemoryGitSnapshotStore, DEFAULT_GIT_WORKSPACE_POLL_INTERVAL_MS, MIN_GIT_WORKSPACE_POLL_INTERVAL_MS, GitWorkspaceMonitor, GIT_COMMAND_NAMES, SNAPSHOT_REASONS, FAILURE_REASONS, defaultSnapshotStore, defaultGitCommandServices, BUSY_STATUSES, TERMINAL_STATUSES, TurnSnapshotTracker, MAX_WORKSPACES, MAX_ACTIVITY, MAX_SAVED_SESSIONS, DEFAULT_STATE, BUILTIN_IDE_DEFINITIONS, registeredIDEs, LIVE_LIFECYCLES, DEFAULT_ACTIVE_CHAT_POLL_STATUSES, DEFAULT_CHAT_TAIL_RECENT_MESSAGE_GRACE_MS, LIVE_RUNTIME_LIFECYCLES, DaemonCdpManager, CdpDomHandlers, DEFAULT_MONITOR_CONFIG, StatusMonitor, BUILTIN_CHAT_MESSAGE_KINDS, CHAT_MESSAGE_VISIBILITIES, CHAT_MESSAGE_TRANSCRIPT_VISIBILITIES, CHAT_MESSAGE_AUDIENCES, CHAT_MESSAGE_SOURCES, CHAT_MESSAGE_ACTIVITY_SOURCES, CHAT_MESSAGE_INTERNAL_SOURCES, KNOWN_CHAT_MESSAGE_KINDS, CHAT_MESSAGE_KIND_ALIASES, EXPLICIT_HIDDEN_VISIBILITIES, EXPLICIT_VISIBLE_VISIBILITIES, HIDDEN_AUDIENCES, ACTIVITY_SOURCE_SET, INTERNAL_SOURCE_SET, HISTORY_DIR, RETAIN_DAYS, SAVED_HISTORY_INDEX_VERSION, SAVED_HISTORY_INDEX_FILE, SAVED_HISTORY_INDEX_LOCK_SUFFIX, SAVED_HISTORY_INDEX_LOCK_WAIT_MS, SAVED_HISTORY_INDEX_LOCK_STALE_MS, SAVED_HISTORY_INDEX_LOCK_POLL_MS, SAVED_HISTORY_ROLLUP_THRESHOLD_BYTES, savedHistorySessionCache, savedHistoryFileSummaryCache, savedHistoryBackgroundRefresh, savedHistoryRollupInFlight, ChatHistoryWriter, IDE_PROVIDER_SESSION_CAPABILITIES_BASE, EXTENSION_PROVIDER_SESSION_CAPABILITIES_BASE, ExtensionProviderInstance, VALID_STATUSES, VALID_ROLES, VALID_BUBBLE_STATES, VALID_TURN_STATUSES, DEFAULT_APPROVAL_POSITIVE_HINTS, IdeProviderInstance, DEFAULT_CDP_SCAN_INTERVAL_MS, DEFAULT_CDP_DISCOVERY_INTERVAL_MS, DEFAULT_STATUS_INITIAL_REPORT_DELAY_MS, DEFAULT_STATUS_SERVER_REPORT_INTERVAL_MS, DEFAULT_STATUS_P2P_REPORT_INTERVAL_MS, MIN_MACHINE_RUNTIME_SUBSCRIPTION_INTERVAL_MS, DEFAULT_MACHINE_RUNTIME_SUBSCRIPTION_INTERVAL_MS, MIN_SESSION_HOST_DIAGNOSTICS_SUBSCRIPTION_INTERVAL_MS, DEFAULT_SESSION_HOST_DIAGNOSTICS_SUBSCRIPTION_INTERVAL_MS, DEFAULT_SESSION_HOST_READY_TIMEOUT_MS, STANDALONE_CDP_SCAN_INTERVAL_MS, DaemonCdpScanner, DaemonCdpInitializer, WORKING_STATUSES, FULL_STATUS_ACTIVE_CHAT_OPTIONS, LIVE_STATUS_ACTIVE_CHAT_OPTIONS, STATUS_MODAL_MESSAGE_LIMIT, STATUS_MODAL_BUTTON_LIMIT, VALID_INPUT_MEDIA_TYPES, VALID_INPUT_STRATEGIES, TEXT_ONLY_MESSAGE_INPUT_SUPPORT, IDE_SESSION_CAPABILITIES, EXTENSION_SESSION_CAPABILITIES, PTY_SESSION_CAPABILITIES, CLI_CHAT_SESSION_CAPABILITIES, ACP_SESSION_CAPABILITIES, globalStore, RECENT_SEND_WINDOW_MS, READ_CHAT_PROVIDER_EVAL_TIMEOUT_MS, HERMES_CLI_STARTING_SEND_SETTLE_MS, recentSendByTarget, DEFAULT_DEBUG_SANITIZE_OPTIONS, SECRET_KEY_PATTERN, KEY_TO_VK, COMMAND_DEBUG_LEVELS, DaemonCommandHandler, IMAGE_MIME_EXTENSIONS, MATERIALIZED_IMAGE_MAX_AGE_MS, MATERIALIZED_IMAGE_CLEANUP_INTERVAL_MS, lastMaterializedImageCleanupAt, CachedDatabaseSync, CliProviderInstance, AcpProviderInstance, chalkModule, chalkApi, COORDINATOR_DELEGATED_ENV_UNSETS, DaemonCliManager, VALID_CAPABILITY_MEDIA_TYPES, VALID_INPUT_STRATEGIES2, KNOWN_PROVIDER_FIELDS, VALUE_CONTROL_TYPES, ProviderLoader, _providerLoader, LOG_DIR2, MAX_FILE_SIZE, MAX_DAYS, SENSITIVE_KEYS, currentDate2, currentFile, writeCount2, SKIP_COMMANDS, DEFAULT_SERVER_NAME, DEFAULT_ADHDEV_MCP_COMMAND, HERMES_CLI_TYPE, HERMES_MCP_CONFIG_PATH, READ_DEBUG_ENABLED, recentReadDebugSignatureBySession, UPGRADE_HELPER_ENV, CHANNEL_NPM_TAG, CHANNEL_SERVER_URL, CHAT_COMMANDS, READ_DEBUG_ENABLED2, DaemonCommandRouter, DaemonStatusReporter, DEFAULT_DAEMON_PORT, DAEMON_WS_PATH, ProviderStreamAdapter, DaemonAgentStreamManager, AgentStreamPoller, ProviderInstanceManager, ARCHIVE_PATH, MAX_ENTRIES_PER_PROVIDER, VersionArchive, DEV_SERVER_PORT, DevServer, SessionHostRuntimeTransport, SessionHostPtyTransportFactory, DEFAULT_SESSION_HOST_APP_NAME, DEFAULT_STANDALONE_SESSION_HOST_APP_NAME, STARTUP_TIMEOUT_MS, STARTUP_POLL_MS, SessionHostCompatibilityError, EXTENSION_CATALOG, SessionRegistry;
40424
40930
  var init_dist2 = __esm({
40425
40931
  "../daemon-core/dist/index.mjs"() {
40426
40932
  "use strict";
@@ -40436,9 +40942,16 @@ var init_dist2 = __esm({
40436
40942
  import_fs5 = require("fs");
40437
40943
  import_path2 = require("path");
40438
40944
  import_crypto3 = require("crypto");
40945
+ import_fs6 = require("fs");
40946
+ import_path3 = require("path");
40947
+ import_crypto4 = require("crypto");
40948
+ import_events2 = require("events");
40949
+ import_fs7 = require("fs");
40950
+ import_path4 = require("path");
40951
+ import_crypto5 = require("crypto");
40439
40952
  fs2 = __toESM(require("fs"), 1);
40440
- path10 = __toESM(require("path"), 1);
40441
- os4 = __toESM(require("os"), 1);
40953
+ path8 = __toESM(require("path"), 1);
40954
+ os22 = __toESM(require("os"), 1);
40442
40955
  init_dist();
40443
40956
  os8 = __toESM(require("os"), 1);
40444
40957
  os9 = __toESM(require("os"), 1);
@@ -40449,7 +40962,7 @@ var init_dist2 = __esm({
40449
40962
  init_dist();
40450
40963
  os11 = __toESM(require("os"), 1);
40451
40964
  import_child_process3 = require("child_process");
40452
- import_fs6 = require("fs");
40965
+ import_fs8 = require("fs");
40453
40966
  import_promises5 = require("fs/promises");
40454
40967
  path = __toESM(require("path"), 1);
40455
40968
  import_util4 = require("util");
@@ -40457,40 +40970,40 @@ var init_dist2 = __esm({
40457
40970
  path22 = __toESM(require("path"), 1);
40458
40971
  path32 = __toESM(require("path"), 1);
40459
40972
  fs = __toESM(require("fs"), 1);
40460
- os5 = __toESM(require("os"), 1);
40973
+ os4 = __toESM(require("os"), 1);
40461
40974
  path5 = __toESM(require("path"), 1);
40462
- import_crypto4 = require("crypto");
40975
+ import_crypto6 = require("crypto");
40463
40976
  path6 = __toESM(require("path"), 1);
40464
40977
  path7 = __toESM(require("path"), 1);
40465
- import_fs7 = require("fs");
40466
- import_path3 = require("path");
40978
+ import_fs9 = require("fs");
40979
+ import_path5 = require("path");
40467
40980
  import_child_process4 = require("child_process");
40468
- import_fs8 = require("fs");
40981
+ import_fs10 = require("fs");
40469
40982
  import_os3 = require("os");
40470
- path8 = __toESM(require("path"), 1);
40471
- import_child_process5 = require("child_process");
40472
- os22 = __toESM(require("os"), 1);
40473
40983
  path9 = __toESM(require("path"), 1);
40474
- import_fs9 = require("fs");
40984
+ import_child_process5 = require("child_process");
40475
40985
  os32 = __toESM(require("os"), 1);
40986
+ path10 = __toESM(require("path"), 1);
40987
+ import_fs11 = require("fs");
40988
+ os42 = __toESM(require("os"), 1);
40476
40989
  import_child_process6 = require("child_process");
40477
40990
  init_wrapper();
40478
40991
  http = __toESM(require("http"), 1);
40479
40992
  crypto2 = __toESM(require("crypto"), 1);
40480
40993
  fs3 = __toESM(require("fs"), 1);
40481
40994
  path11 = __toESM(require("path"), 1);
40482
- os52 = __toESM(require("os"), 1);
40995
+ os5 = __toESM(require("os"), 1);
40483
40996
  fs4 = __toESM(require("fs"), 1);
40484
40997
  os6 = __toESM(require("os"), 1);
40485
40998
  path12 = __toESM(require("path"), 1);
40486
- import_crypto5 = require("crypto");
40999
+ import_crypto7 = require("crypto");
40487
41000
  fs5 = __toESM(require("fs"), 1);
40488
41001
  path13 = __toESM(require("path"), 1);
40489
41002
  os7 = __toESM(require("os"), 1);
40490
41003
  os13 = __toESM(require("os"), 1);
40491
41004
  path18 = __toESM(require("path"), 1);
40492
41005
  crypto4 = __toESM(require("crypto"), 1);
40493
- import_fs10 = require("fs");
41006
+ import_fs12 = require("fs");
40494
41007
  import_child_process7 = require("child_process");
40495
41008
  init_source();
40496
41009
  os12 = __toESM(require("os"), 1);
@@ -40515,11 +41028,11 @@ var init_dist2 = __esm({
40515
41028
  os16 = __toESM(require("os"), 1);
40516
41029
  init_js_yaml();
40517
41030
  import_child_process10 = require("child_process");
40518
- import_crypto6 = require("crypto");
40519
- import_fs11 = require("fs");
41031
+ import_crypto8 = require("crypto");
41032
+ import_fs13 = require("fs");
40520
41033
  import_module2 = require("module");
40521
41034
  os17 = __toESM(require("os"), 1);
40522
- import_path4 = require("path");
41035
+ import_path6 = require("path");
40523
41036
  os18 = __toESM(require("os"), 1);
40524
41037
  import_child_process11 = require("child_process");
40525
41038
  import_child_process12 = require("child_process");
@@ -40527,7 +41040,7 @@ var init_dist2 = __esm({
40527
41040
  os19 = __toESM(require("os"), 1);
40528
41041
  path222 = __toESM(require("path"), 1);
40529
41042
  import_os4 = require("os");
40530
- import_path5 = require("path");
41043
+ import_path7 = require("path");
40531
41044
  fs10 = __toESM(require("fs"), 1);
40532
41045
  fs11 = __toESM(require("fs"), 1);
40533
41046
  path23 = __toESM(require("path"), 1);
@@ -40584,7 +41097,8 @@ var init_dist2 = __esm({
40584
41097
  dirtyWorkspaceBehavior: "warn",
40585
41098
  maxParallelTasks: 2,
40586
41099
  spawnedSessionVisibility: "visible",
40587
- sessionCleanupOnNodeRemove: "preserve"
41100
+ sessionCleanupOnNodeRemove: "preserve",
41101
+ maxTaskRetries: 1
40588
41102
  };
40589
41103
  }
40590
41104
  });
@@ -40687,6 +41201,7 @@ var init_dist2 = __esm({
40687
41201
  | \`mesh_launch_session\` | Start a new agent session on a node |
40688
41202
  | \`mesh_send_task\` | Send a task (natural language) to a running agent |
40689
41203
  | \`mesh_read_chat\` | Read an agent's recent messages to check progress |
41204
+ | \`mesh_task_history\` | Read the task ledger \u2014 dispatches, completions, failures. Use to understand what has been done before deciding next steps |
40690
41205
  | \`mesh_git_status\` | Check git status on a specific node |
40691
41206
  | \`mesh_checkpoint\` | Create a git checkpoint on a node |
40692
41207
  | \`mesh_approve\` | Approve/reject a pending agent action |
@@ -40697,18 +41212,57 @@ var init_dist2 = __esm({
40697
41212
  Before doing any coordinator work, confirm that the actual callable tool list includes \`mesh_status\` and the other \`mesh_*\` tools from the table above. If this Repo Mesh coordinator prompt is present but the callable \`mesh_*\` tools are missing, the MCP server/tool manifest is stale or not injected yet. Do not substitute terminal/file/git tools, do not inspect or edit the repository directly, and do not continue as a non-mesh local coding agent. Stop immediately and tell the user to run \`/reload-mcp\` or start a fresh coordinator session so ADHDev can reconnect \`adhdev-mesh\`.`;
40698
41213
  WORKFLOW_SECTION = `## Orchestration Workflow
40699
41214
 
40700
- 1. **Assess** \u2014 Call \`mesh_status\` to see which nodes are healthy and available.
40701
- 2. **Plan** \u2014 Decompose the user's request into independent tasks for parallel execution, or sequential tasks when dependencies exist.
40702
- 3. **Delegate** \u2014 For each task:
40703
- a. Pick the best node (consider: health, dirty state, current workload).
40704
- b. If you need branch isolation for parallel work, call \`mesh_clone_node\` to create a worktree node first.
40705
- c. If no session exists, call \`mesh_launch_session\` to start one.
40706
- d. Call \`mesh_send_task\` with a **complete, self-contained** instruction that includes all context the agent needs (file paths, line numbers, what to change, why). Do not send partial instructions expecting future follow-up.
40707
- 4. **Monitor** \u2014 Prefer event-driven completion/status notifications. Do **not** poll \`mesh_read_chat\` repeatedly just because the delegated session has not produced a final assistant message yet; tool/terminal activity means work may still be in progress. Do not call \`mesh_read_chat\` again within a few seconds for the same generating session; wait for the completion callback/status event instead unless you are debugging a real stall. Use at most one compact \`mesh_read_chat\` check after a completion/approval signal, an explicit user status request, or a real timeout/stall. Handle approvals via \`mesh_approve\`.
41215
+ 1. **Assess** \u2014 Call \`mesh_status\` to see which nodes are healthy and available. Check \`mesh_task_history\` to understand what has already been done in this mesh \u2014 previous delegations, completions, and failures.
41216
+ 2. **Plan** \u2014 Decompose the user's request into independent tasks for parallel execution, or sequential tasks when dependencies exist. If \`mesh_task_history\` shows a recent failure for a task, decide whether to retry or reassign.
41217
+ 3. **Queue / Delegate** \u2014 The Mesh uses an autonomous pull-based Work Queue:
41218
+ a. **General Tasks**: Enqueue tasks using \`mesh_enqueue_task\`. Idle node agents will automatically pull tasks from the queue and begin working.
41219
+ b. **Node Preparation**: Call \`mesh_launch_session\` to ensure enough agent sessions are active to handle the queue. If you need branch isolation for parallel work, call \`mesh_clone_node\` to create a worktree node first.
41220
+ c. **Targeted Tasks**: Use \`mesh_send_task\` only when you need to bypass the queue and force a specific node to execute a task immediately.
41221
+ d. Always provide a **complete, self-contained** instruction that includes all context the agent needs (file paths, line numbers, what to change, why). Do not send partial instructions expecting future follow-up.
41222
+ 4. **Monitor** \u2014 Prefer event-driven completion/status notifications. Do **not** poll \`mesh_read_chat\` repeatedly. Use \`mesh_view_queue\` to see the status of all pending, assigned, completed, and failed tasks. Do not call \`mesh_read_chat\` again within a few seconds for the same generating session. Use at most one compact \`mesh_read_chat\` check after a completion/approval signal. Handle approvals via \`mesh_approve\`.
40708
41223
  5. **Verify** \u2014 When a task reports completion or git work is visible, call \`mesh_git_status\` to verify changes were made.
40709
41224
  6. **Checkpoint** \u2014 Call \`mesh_checkpoint\` to save the work.
40710
41225
  7. **Clean up** \u2014 Remove worktree nodes via \`mesh_remove_node\` after their work is merged or no longer needed.
40711
- 8. **Report** \u2014 Summarize what was done, what changed, and any issues.`;
41226
+ 8. **Report** \u2014 Summarize what was done, what changed, and any issues.
41227
+
41228
+ ## Failure Recovery
41229
+
41230
+ When a node agent stops unexpectedly, the daemon automatically enriches the system message with **Recovery Context** that includes:
41231
+ - The number of consecutive failures on that node
41232
+ - The original task message (if recorded in the ledger)
41233
+ - A recommendation: **retry**, **reassign**, or **escalate**
41234
+
41235
+ Follow these recovery rules:
41236
+ 1. **If "Retry recommended"**: Re-launch the session on the same node (\`mesh_launch_session\`), then resend the original task (\`mesh_send_task\`). The system message includes the original task text.
41237
+ 2. **If "Max retries exceeded"**: Do NOT retry on the same node. Either reassign the task to a different node, or inform the user that the task requires manual intervention.
41238
+ 3. **If no recovery context**: The stop may be intentional (normal completion). Use \`mesh_read_chat\` once to verify, then move on.
41239
+ 4. **Always record what happened**: After handling a failure, briefly note the outcome in your report to the user.`;
41240
+ }
41241
+ });
41242
+ mesh_ledger_exports = {};
41243
+ __export2(mesh_ledger_exports, {
41244
+ appendLedgerEntry: () => appendLedgerEntry,
41245
+ appendRemoteLedgerEntries: () => appendRemoteLedgerEntries,
41246
+ getLedgerDir: () => getLedgerDir,
41247
+ getLedgerSummary: () => getLedgerSummary,
41248
+ getSessionRecoveryContext: () => getSessionRecoveryContext,
41249
+ meshLedgerEvents: () => meshLedgerEvents,
41250
+ readLedgerEntries: () => readLedgerEntries
41251
+ });
41252
+ init_mesh_ledger = __esm2({
41253
+ "src/mesh/mesh-ledger.ts"() {
41254
+ "use strict";
41255
+ init_config();
41256
+ LEDGER_DIR_NAME = "mesh-ledger";
41257
+ MAX_FILE_SIZE_BYTES = 10 * 1024 * 1024;
41258
+ RECENT_FAILURE_WINDOW_MS = 30 * 60 * 1e3;
41259
+ meshLedgerEvents = new import_events2.EventEmitter();
41260
+ }
41261
+ });
41262
+ init_mesh_work_queue = __esm2({
41263
+ "src/mesh/mesh-work-queue.ts"() {
41264
+ "use strict";
41265
+ init_mesh_ledger();
40712
41266
  }
40713
41267
  });
40714
41268
  init_logger = __esm2({
@@ -40717,7 +41271,7 @@ Before doing any coordinator work, confirm that the actual callable tool list in
40717
41271
  LEVEL_NUM = { debug: 0, info: 1, warn: 2, error: 3 };
40718
41272
  LEVEL_LABEL = { debug: "DBG", info: "INF", warn: "WRN", error: "ERR" };
40719
41273
  currentLevel = "info";
40720
- LOG_DIR = process.platform === "win32" ? path10.join(process.env.LOCALAPPDATA || process.env.APPDATA || path10.join(os4.homedir(), "AppData", "Local"), "adhdev", "logs") : process.platform === "darwin" ? path10.join(os4.homedir(), "Library", "Logs", "adhdev") : path10.join(os4.homedir(), ".local", "share", "adhdev", "logs");
41274
+ LOG_DIR = process.platform === "win32" ? path8.join(process.env.LOCALAPPDATA || process.env.APPDATA || path8.join(os22.homedir(), "AppData", "Local"), "adhdev", "logs") : process.platform === "darwin" ? path8.join(os22.homedir(), "Library", "Logs", "adhdev") : path8.join(os22.homedir(), ".local", "share", "adhdev", "logs");
40721
41275
  MAX_LOG_SIZE = 5 * 1024 * 1024;
40722
41276
  MAX_LOG_DAYS = 7;
40723
41277
  try {
@@ -40725,16 +41279,16 @@ Before doing any coordinator work, confirm that the actual callable tool list in
40725
41279
  } catch {
40726
41280
  }
40727
41281
  currentDate = getDateStr();
40728
- currentLogFile = path10.join(LOG_DIR, `daemon-${currentDate}.log`);
41282
+ currentLogFile = path8.join(LOG_DIR, `daemon-${currentDate}.log`);
40729
41283
  cleanOldLogs();
40730
41284
  try {
40731
- const oldLog = path10.join(LOG_DIR, "daemon.log");
41285
+ const oldLog = path8.join(LOG_DIR, "daemon.log");
40732
41286
  if (fs2.existsSync(oldLog)) {
40733
41287
  const stat22 = fs2.statSync(oldLog);
40734
41288
  const oldDate = stat22.mtime.toISOString().slice(0, 10);
40735
- fs2.renameSync(oldLog, path10.join(LOG_DIR, `daemon-${oldDate}.log`));
41289
+ fs2.renameSync(oldLog, path8.join(LOG_DIR, `daemon-${oldDate}.log`));
40736
41290
  }
40737
- const oldLogBackup = path10.join(LOG_DIR, "daemon.log.old");
41291
+ const oldLogBackup = path8.join(LOG_DIR, "daemon.log.old");
40738
41292
  if (fs2.existsSync(oldLogBackup)) {
40739
41293
  fs2.unlinkSync(oldLogBackup);
40740
41294
  }
@@ -40766,7 +41320,38 @@ Before doing any coordinator work, confirm that the actual callable tool list in
40766
41320
  }
40767
41321
  };
40768
41322
  interceptorInstalled = false;
40769
- LOG_PATH = path10.join(LOG_DIR, `daemon-${getDateStr()}.log`);
41323
+ LOG_PATH = path8.join(LOG_DIR, `daemon-${getDateStr()}.log`);
41324
+ }
41325
+ });
41326
+ mesh_events_exports = {};
41327
+ __export2(mesh_events_exports, {
41328
+ drainPendingMeshCoordinatorEvents: () => drainPendingMeshCoordinatorEvents,
41329
+ handleMeshForwardEvent: () => handleMeshForwardEvent,
41330
+ setupMeshEventForwarding: () => setupMeshEventForwarding,
41331
+ triggerMeshQueue: () => triggerMeshQueue,
41332
+ tryAssignQueueTask: () => tryAssignQueueTask
41333
+ });
41334
+ init_mesh_events = __esm2({
41335
+ "src/mesh/mesh-events.ts"() {
41336
+ "use strict";
41337
+ init_mesh_config();
41338
+ init_logger();
41339
+ init_mesh_ledger();
41340
+ init_mesh_work_queue();
41341
+ MAX_PENDING_EVENTS = 50;
41342
+ pendingMeshCoordinatorEvents = [];
41343
+ MESH_COORDINATOR_EVENTS = /* @__PURE__ */ new Set([
41344
+ "agent:generating_completed",
41345
+ "agent:waiting_approval",
41346
+ "agent:stopped",
41347
+ "monitor:long_generating"
41348
+ ]);
41349
+ EVENT_TO_LEDGER_KIND = {
41350
+ "agent:generating_completed": "task_completed",
41351
+ "agent:waiting_approval": "task_approval_needed",
41352
+ "agent:stopped": "task_failed",
41353
+ "monitor:long_generating": "task_stalled"
41354
+ };
40770
41355
  }
40771
41356
  });
40772
41357
  init_debug_config = __esm2({
@@ -41293,6 +41878,8 @@ Before doing any coordinator work, confirm that the actual callable tool list in
41293
41878
  statusHistory = [];
41294
41879
  // ─── CLI Scripts (script-based parsing) ───
41295
41880
  cliScripts;
41881
+ /** Per-session opaque state object created by cliScripts.createState(), reset on stop. */
41882
+ scriptState = null;
41296
41883
  runtimeSettings = {};
41297
41884
  /** Full accumulated rendered PTY transcript for parser/readback use */
41298
41885
  accumulatedBuffer = "";
@@ -41474,6 +42061,7 @@ ${lastSnapshot}`;
41474
42061
  this.cliScripts = scripts;
41475
42062
  this.parsedStatusCache = null;
41476
42063
  this.parseErrorMessage = null;
42064
+ this.scriptState = typeof scripts.createState === "function" ? scripts.createState() : null;
41477
42065
  const scriptNames = listCliScriptNames(scripts);
41478
42066
  LOG.info("CLI", `[${this.cliType}] CLI scripts injected: [${scriptNames.join(", ")}]`);
41479
42067
  }
@@ -41591,6 +42179,7 @@ ${lastSnapshot}`;
41591
42179
  this.ready = false;
41592
42180
  this.startupParseGate = false;
41593
42181
  this.spawnAt = 0;
42182
+ this.scriptState = null;
41594
42183
  this.onStatusChange?.();
41595
42184
  });
41596
42185
  this.spawnAt = Date.now();
@@ -42364,7 +42953,7 @@ ${lastSnapshot}`;
42364
42953
  scope: this.currentTurnScope,
42365
42954
  runtimeSettings: this.runtimeSettings
42366
42955
  });
42367
- const session = this.cliScripts.parseSession({ ...input, tail, tailScreen: buildCliScreenSnapshot(tail) });
42956
+ const session = this.cliScripts.parseSession(this.scriptState, { ...input, tail, tailScreen: buildCliScreenSnapshot(tail) });
42368
42957
  this.parseErrorMessage = null;
42369
42958
  return session && typeof session === "object" ? session : null;
42370
42959
  } catch (e) {
@@ -42378,7 +42967,7 @@ ${lastSnapshot}`;
42378
42967
  if (!this.cliScripts?.detectStatus) return null;
42379
42968
  try {
42380
42969
  const screenText = this.terminalScreen.getText();
42381
- const status = this.cliScripts.detectStatus({
42970
+ const status = this.cliScripts.detectStatus(this.scriptState, {
42382
42971
  tail: text.slice(-500),
42383
42972
  screenText,
42384
42973
  rawBuffer: this.accumulatedRawBuffer,
@@ -42397,7 +42986,7 @@ ${lastSnapshot}`;
42397
42986
  try {
42398
42987
  const screenText = this.terminalScreen.getText();
42399
42988
  const buffer = screenText || this.accumulatedBuffer;
42400
- return this.cliScripts.parseApproval({
42989
+ return this.cliScripts.parseApproval(this.scriptState, {
42401
42990
  buffer,
42402
42991
  screenText,
42403
42992
  rawBuffer: this.accumulatedRawBuffer,
@@ -42505,7 +43094,7 @@ ${lastSnapshot}`;
42505
43094
  scope: this.currentTurnScope,
42506
43095
  runtimeSettings: this.runtimeSettings
42507
43096
  });
42508
- return await Promise.resolve(fn({
43097
+ return await Promise.resolve(fn(this.scriptState, {
42509
43098
  ...input,
42510
43099
  args: args && typeof args === "object" ? { ...args } : {}
42511
43100
  }));
@@ -43497,6 +44086,9 @@ ${lastSnapshot}`;
43497
44086
  init_mesh_config();
43498
44087
  init_coordinator_prompt();
43499
44088
  init_mesh_config();
44089
+ init_mesh_ledger();
44090
+ init_mesh_work_queue();
44091
+ init_mesh_events();
43500
44092
  init_config();
43501
44093
  DEFAULT_STATE = {
43502
44094
  recentActivity: [],
@@ -44963,7 +45555,7 @@ ${lastSnapshot}`;
44963
45555
  HIDDEN_AUDIENCES = /* @__PURE__ */ new Set(["debug", "trace", "internal"]);
44964
45556
  ACTIVITY_SOURCE_SET = new Set(CHAT_MESSAGE_ACTIVITY_SOURCES);
44965
45557
  INTERNAL_SOURCE_SET = new Set(CHAT_MESSAGE_INTERNAL_SOURCES);
44966
- HISTORY_DIR = path11.join(os52.homedir(), ".adhdev", "history");
45558
+ HISTORY_DIR = path11.join(os5.homedir(), ".adhdev", "history");
44967
45559
  RETAIN_DAYS = 30;
44968
45560
  SAVED_HISTORY_INDEX_VERSION = 1;
44969
45561
  SAVED_HISTORY_INDEX_FILE = ".saved-history-index.json";
@@ -46682,6 +47274,7 @@ ${effect.notification.body || ""}`.trim();
46682
47274
  };
46683
47275
  STATUS_MODAL_MESSAGE_LIMIT = 2 * 1024;
46684
47276
  STATUS_MODAL_BUTTON_LIMIT = 120;
47277
+ init_mesh_work_queue();
46685
47278
  VALID_INPUT_MEDIA_TYPES = /* @__PURE__ */ new Set(["text", "image", "audio", "video", "resource"]);
46686
47279
  VALID_INPUT_STRATEGIES = /* @__PURE__ */ new Set(["native", "native_acp", "resource_link", "text_fallback", "paste", "upload"]);
46687
47280
  TEXT_ONLY_MESSAGE_INPUT_SUPPORT = Object.freeze({
@@ -51540,16 +52133,7 @@ Run 'adhdev doctor' for detailed diagnostics.`
51540
52133
  DEFAULT_ADHDEV_MCP_COMMAND = "adhdev-mcp";
51541
52134
  HERMES_CLI_TYPE = "hermes-cli";
51542
52135
  HERMES_MCP_CONFIG_PATH = "~/.hermes/config.yaml";
51543
- init_mesh_config();
51544
- init_logger();
51545
- MAX_PENDING_EVENTS = 50;
51546
- pendingMeshCoordinatorEvents = [];
51547
- MESH_COORDINATOR_EVENTS = /* @__PURE__ */ new Set([
51548
- "agent:generating_completed",
51549
- "agent:waiting_approval",
51550
- "agent:stopped",
51551
- "monitor:long_generating"
51552
- ]);
52136
+ init_mesh_events();
51553
52137
  init_config();
51554
52138
  init_terminal_screen();
51555
52139
  init_logger();
@@ -52432,6 +53016,21 @@ Run 'adhdev doctor' for detailed diagnostics.`
52432
53016
  return { success: false, error: e.message };
52433
53017
  }
52434
53018
  }
53019
+ case "get_mesh_ledger": {
53020
+ const meshId = typeof args?.meshId === "string" ? args.meshId.trim() : "";
53021
+ if (!meshId) return { success: false, error: "meshId required" };
53022
+ try {
53023
+ const { readLedgerEntries: readLedgerEntries2, getLedgerSummary: getLedgerSummary2 } = await Promise.resolve().then(() => (init_mesh_ledger(), mesh_ledger_exports));
53024
+ const tail = typeof args?.tail === "number" ? args.tail : 20;
53025
+ const since = typeof args?.since === "string" ? args.since : void 0;
53026
+ const kind = Array.isArray(args?.kind) ? args.kind.filter((k) => typeof k === "string") : void 0;
53027
+ const entries = readLedgerEntries2(meshId, { tail, since, kind });
53028
+ const summary = getLedgerSummary2(meshId);
53029
+ return { success: true, entries, summary };
53030
+ } catch (e) {
53031
+ return { success: false, error: e.message };
53032
+ }
53033
+ }
52435
53034
  case "add_mesh_node": {
52436
53035
  const meshId = typeof args?.meshId === "string" ? args.meshId.trim() : "";
52437
53036
  const workspace = typeof args?.workspace === "string" ? args.workspace.trim() : "";
@@ -52500,6 +53099,54 @@ Run 'adhdev doctor' for detailed diagnostics.`
52500
53099
  return { success: false, error: e.message };
52501
53100
  }
52502
53101
  }
53102
+ case "refine_mesh_node": {
53103
+ const meshId = typeof args?.meshId === "string" ? args.meshId.trim() : "";
53104
+ const nodeId = typeof args?.nodeId === "string" ? args.nodeId.trim() : "";
53105
+ if (!meshId || !nodeId) return { success: false, error: "meshId and nodeId required" };
53106
+ try {
53107
+ const meshRecord = await this.getMeshForCommand(meshId, args?.inlineMesh);
53108
+ const mesh = meshRecord?.mesh;
53109
+ const node = mesh?.nodes?.find((n) => n.id === nodeId || n.nodeId === nodeId);
53110
+ if (!node) return { success: false, error: `Node '${nodeId}' not found in mesh` };
53111
+ if (!node.isLocalWorktree || !node.workspace) {
53112
+ return { success: false, error: `Refinery requires a local worktree node` };
53113
+ }
53114
+ const sourceNode = node.clonedFromNodeId ? mesh?.nodes.find((n) => n.id === node.clonedFromNodeId || n.nodeId === node.clonedFromNodeId) : mesh?.nodes.find((n) => !n.isLocalWorktree);
53115
+ const repoRoot = sourceNode?.repoRoot || sourceNode?.workspace;
53116
+ if (!repoRoot) return { success: false, error: "Source node repoRoot not found" };
53117
+ const { execFile: execFile3 } = await import("child_process");
53118
+ const { promisify: promisify3 } = await import("util");
53119
+ const execFileAsync3 = promisify3(execFile3);
53120
+ const { stdout: branchStdout } = await execFileAsync3("git", ["branch", "--show-current"], { cwd: node.workspace, encoding: "utf8" });
53121
+ const branch = branchStdout.trim();
53122
+ if (!branch) return { success: false, error: "Could not determine branch of the worktree node" };
53123
+ const { stdout: baseBranchStdout } = await execFileAsync3("git", ["branch", "--show-current"], { cwd: repoRoot, encoding: "utf8" });
53124
+ const baseBranch = baseBranchStdout.trim();
53125
+ try {
53126
+ await execFileAsync3("git", ["merge", "--no-ff", branch, "-m", `Auto-merge branch '${branch}' via Refinery`], { cwd: repoRoot, encoding: "utf8" });
53127
+ } catch (e) {
53128
+ return { success: false, error: `Merge failed (conflicts?): ${e.message}` };
53129
+ }
53130
+ const removeResult = await this.execute("remove_mesh_node", {
53131
+ meshId,
53132
+ nodeId,
53133
+ sessionCleanupMode: "kill",
53134
+ inlineMesh: args?.inlineMesh
53135
+ });
53136
+ try {
53137
+ const { appendLedgerEntry: appendLedgerEntry2 } = await Promise.resolve().then(() => (init_mesh_ledger(), mesh_ledger_exports));
53138
+ appendLedgerEntry2(meshId, {
53139
+ kind: "node_removed",
53140
+ nodeId,
53141
+ payload: { refined: true, mergedBranch: branch, into: baseBranch }
53142
+ });
53143
+ } catch {
53144
+ }
53145
+ return { success: true, merged: true, branch, into: baseBranch, removeResult };
53146
+ } catch (e) {
53147
+ return { success: false, error: e.message };
53148
+ }
53149
+ }
52503
53150
  case "remove_mesh_node": {
52504
53151
  const meshId = typeof args?.meshId === "string" ? args.meshId.trim() : "";
52505
53152
  const nodeId = typeof args?.nodeId === "string" ? args.nodeId.trim() : "";
@@ -52535,6 +53182,17 @@ Run 'adhdev doctor' for detailed diagnostics.`
52535
53182
  const { removeNode: removeNode3 } = await Promise.resolve().then(() => (init_mesh_config(), mesh_config_exports));
52536
53183
  removed = removeNode3(meshId, nodeId);
52537
53184
  }
53185
+ if (removed) {
53186
+ try {
53187
+ const { appendLedgerEntry: appendLedgerEntry2 } = await Promise.resolve().then(() => (init_mesh_ledger(), mesh_ledger_exports));
53188
+ appendLedgerEntry2(meshId, {
53189
+ kind: "node_removed",
53190
+ nodeId,
53191
+ payload: { worktree: !!node?.isLocalWorktree, sessionCleanupMode }
53192
+ });
53193
+ } catch {
53194
+ }
53195
+ }
52538
53196
  return { success: true, removed, ...sessionCleanup ? { sessionCleanup } : {} };
52539
53197
  } catch (e) {
52540
53198
  return { success: false, error: e.message };
@@ -52564,9 +53222,9 @@ Run 'adhdev doctor' for detailed diagnostics.`
52564
53222
  });
52565
53223
  let node;
52566
53224
  if (meshRecord.inline) {
52567
- const { randomUUID: randomUUID8 } = await import("crypto");
53225
+ const { randomUUID: randomUUID10 } = await import("crypto");
52568
53226
  node = {
52569
- id: `node_${randomUUID8().replace(/-/g, "")}`,
53227
+ id: `node_${randomUUID10().replace(/-/g, "")}`,
52570
53228
  workspace: result.worktreePath,
52571
53229
  repoRoot: result.worktreePath,
52572
53230
  daemonId: sourceNode.daemonId,
@@ -52591,6 +53249,15 @@ Run 'adhdev doctor' for detailed diagnostics.`
52591
53249
  });
52592
53250
  if (!node) return { success: false, error: "Failed to register worktree node" };
52593
53251
  }
53252
+ try {
53253
+ const { appendLedgerEntry: appendLedgerEntry2 } = await Promise.resolve().then(() => (init_mesh_ledger(), mesh_ledger_exports));
53254
+ appendLedgerEntry2(meshId, {
53255
+ kind: "node_cloned",
53256
+ nodeId: node.id,
53257
+ payload: { sourceNodeId, branch: result.branch, worktreePath: result.worktreePath }
53258
+ });
53259
+ } catch {
53260
+ }
52594
53261
  return {
52595
53262
  success: true,
52596
53263
  node,
@@ -52601,6 +53268,19 @@ Run 'adhdev doctor' for detailed diagnostics.`
52601
53268
  return { success: false, error: e.message };
52602
53269
  }
52603
53270
  }
53271
+ case "trigger_mesh_queue": {
53272
+ const meshId = typeof args?.meshId === "string" ? args.meshId.trim() : "";
53273
+ if (!meshId) return { success: false, error: "meshId required" };
53274
+ try {
53275
+ const { triggerMeshQueue: triggerMeshQueue2 } = await Promise.resolve().then(() => (init_mesh_events(), mesh_events_exports));
53276
+ if (meshId) {
53277
+ triggerMeshQueue2(this.deps, meshId);
53278
+ }
53279
+ return { success: true };
53280
+ } catch (e) {
53281
+ return { success: false, error: e.message };
53282
+ }
53283
+ }
52604
53284
  // ─── Mesh Coordinator Launch ───
52605
53285
  case "launch_mesh_coordinator": {
52606
53286
  const meshId = typeof args?.meshId === "string" ? args.meshId.trim() : "";
@@ -52679,6 +53359,93 @@ Run 'adhdev doctor' for detailed diagnostics.`
52679
53359
  meshCoordinatorSetup: coordinatorSetup
52680
53360
  };
52681
53361
  }
53362
+ if (coordinatorSetup.kind === "cli_command") {
53363
+ let cliCmdSystemPrompt = "";
53364
+ try {
53365
+ cliCmdSystemPrompt = buildCoordinatorSystemPrompt2({ mesh, coordinatorCliType: cliType });
53366
+ } catch (error48) {
53367
+ const message = error48?.message || String(error48);
53368
+ LOG.error("MeshCoordinator", `Failed to build coordinator prompt: ${message}`);
53369
+ return {
53370
+ success: false,
53371
+ code: "mesh_coordinator_prompt_failed",
53372
+ error: `Failed to build Repo Mesh coordinator prompt: ${message}`,
53373
+ meshId,
53374
+ cliType,
53375
+ workspace
53376
+ };
53377
+ }
53378
+ try {
53379
+ const { execFileSync: execCmdSync } = await import("child_process");
53380
+ const cmdParts = coordinatorSetup.command.trim().split(/\s+/);
53381
+ const [regCmd, ...regArgs] = cmdParts;
53382
+ LOG.info("MeshCoordinator", `Running MCP registration: ${coordinatorSetup.command}`);
53383
+ execCmdSync(regCmd, regArgs, { stdio: "pipe", timeout: 15e3 });
53384
+ } catch (error48) {
53385
+ LOG.warn("MeshCoordinator", `MCP registration command failed (may be pre-registered): ${error48?.message || error48}`);
53386
+ }
53387
+ const cliCmdArgs = [];
53388
+ const cliCmdEnv = {};
53389
+ if (cliCmdSystemPrompt) {
53390
+ if (cliType === "codex-cli") {
53391
+ cliCmdArgs.push("-c", `developer_instructions=${JSON.stringify(cliCmdSystemPrompt)}`);
53392
+ } else if (cliType === "gemini-cli") {
53393
+ try {
53394
+ const { writeFileSync: wfs, existsSync: efs, readFileSync: rfs } = await import("fs");
53395
+ const geminiMdPath = `${workspace}/GEMINI.md`;
53396
+ const marker = "<!-- adhdev-mesh-coordinator-prompt -->";
53397
+ const markerEnd = "<!-- /adhdev-mesh-coordinator-prompt -->";
53398
+ const block = `${marker}
53399
+ ${cliCmdSystemPrompt}
53400
+ ${markerEnd}`;
53401
+ if (efs(geminiMdPath)) {
53402
+ const existing = rfs(geminiMdPath, "utf-8");
53403
+ const replaced = existing.replace(
53404
+ new RegExp(`${marker}[\\s\\S]*?${markerEnd}`, "g"),
53405
+ block
53406
+ );
53407
+ wfs(geminiMdPath, replaced.includes(marker) ? replaced : `${existing}
53408
+
53409
+ ${block}`);
53410
+ } else {
53411
+ wfs(geminiMdPath, block);
53412
+ }
53413
+ LOG.info("MeshCoordinator", `Wrote coordinator prompt to ${workspace}/GEMINI.md`);
53414
+ } catch (e) {
53415
+ LOG.warn("MeshCoordinator", `Could not write GEMINI.md: ${e?.message || e}`);
53416
+ }
53417
+ }
53418
+ }
53419
+ const cliCmdLaunch = await this.deps.cliManager.handleCliCommand("launch_cli", {
53420
+ cliType,
53421
+ dir: workspace,
53422
+ cliArgs: cliCmdArgs.length > 0 ? cliCmdArgs : void 0,
53423
+ env: Object.keys(cliCmdEnv).length > 0 ? cliCmdEnv : void 0,
53424
+ settings: { meshCoordinatorFor: meshId }
53425
+ });
53426
+ if (!cliCmdLaunch?.success) {
53427
+ return { success: false, error: cliCmdLaunch?.error || "Failed to launch CLI session" };
53428
+ }
53429
+ LOG.info("MeshCoordinator", `Launched ${cliType} coordinator (cli_command) for mesh ${meshId}`);
53430
+ try {
53431
+ const { appendLedgerEntry: appendLedgerEntry2 } = await Promise.resolve().then(() => (init_mesh_ledger(), mesh_ledger_exports));
53432
+ appendLedgerEntry2(meshId, {
53433
+ kind: "coordinator_started",
53434
+ sessionId: cliCmdLaunch.sessionId || cliCmdLaunch.id,
53435
+ providerType: cliType,
53436
+ payload: { workspace }
53437
+ });
53438
+ } catch {
53439
+ }
53440
+ return {
53441
+ success: true,
53442
+ meshId,
53443
+ cliType,
53444
+ workspace,
53445
+ sessionId: cliCmdLaunch.sessionId || cliCmdLaunch.id,
53446
+ mcpRegistered: true
53447
+ };
53448
+ }
52682
53449
  const configFormat = coordinatorSetup.configFormat;
52683
53450
  if (configFormat !== "claude_mcp_json" && configFormat !== "hermes_config_yaml") {
52684
53451
  return {
@@ -52705,7 +53472,7 @@ Run 'adhdev doctor' for detailed diagnostics.`
52705
53472
  workspace
52706
53473
  };
52707
53474
  }
52708
- const { existsSync: existsSync23, readFileSync: readFileSync15, writeFileSync: writeFileSync14, copyFileSync: copyFileSync4, mkdirSync: mkdirSync16 } = await import("fs");
53475
+ const { existsSync: existsSync25, readFileSync: readFileSync17, writeFileSync: writeFileSync15, copyFileSync: copyFileSync4, mkdirSync: mkdirSync17 } = await import("fs");
52709
53476
  const { dirname: dirname92 } = await import("path");
52710
53477
  const mcpConfigPath = coordinatorSetup.configPath;
52711
53478
  const hermesManualFallback = cliType === "hermes-cli" && configFormat === "hermes_config_yaml" ? createHermesManualMeshCoordinatorSetup(meshId, workspace) : null;
@@ -52739,21 +53506,21 @@ Run 'adhdev doctor' for detailed diagnostics.`
52739
53506
  };
52740
53507
  }
52741
53508
  try {
52742
- mkdirSync16(dirname92(mcpConfigPath), { recursive: true });
53509
+ mkdirSync17(dirname92(mcpConfigPath), { recursive: true });
52743
53510
  } catch (error48) {
52744
53511
  const message = `Could not prepare MCP config path for automatic setup: ${error48?.message || error48}`;
52745
53512
  LOG.error("MeshCoordinator", message);
52746
53513
  if (hermesManualFallback) return returnManualFallback(message);
52747
53514
  return { success: false, code: "mesh_coordinator_config_write_failed", error: message, meshId, cliType, workspace };
52748
53515
  }
52749
- const hadExistingMcpConfig = existsSync23(mcpConfigPath);
53516
+ const hadExistingMcpConfig = existsSync25(mcpConfigPath);
52750
53517
  let existingMcpConfig = hermesBaseConfig?.config || {};
52751
53518
  if (hermesBaseConfig) {
52752
53519
  copyHermesCoordinatorCredentialFiles(hermesBaseConfig.sourceHome, dirname92(mcpConfigPath));
52753
53520
  }
52754
53521
  if (hadExistingMcpConfig) {
52755
53522
  try {
52756
- const parsedExistingMcpConfig = parseMeshCoordinatorMcpConfig(readFileSync15(mcpConfigPath, "utf-8"), configFormat);
53523
+ const parsedExistingMcpConfig = parseMeshCoordinatorMcpConfig(readFileSync17(mcpConfigPath, "utf-8"), configFormat);
52757
53524
  existingMcpConfig = { ...existingMcpConfig, ...parsedExistingMcpConfig };
52758
53525
  copyFileSync4(mcpConfigPath, mcpConfigPath + ".backup");
52759
53526
  } catch (error48) {
@@ -52775,7 +53542,7 @@ Run 'adhdev doctor' for detailed diagnostics.`
52775
53542
  }
52776
53543
  };
52777
53544
  try {
52778
- writeFileSync14(mcpConfigPath, serializeMeshCoordinatorMcpConfig(mcpConfig, configFormat), "utf-8");
53545
+ writeFileSync15(mcpConfigPath, serializeMeshCoordinatorMcpConfig(mcpConfig, configFormat), "utf-8");
52779
53546
  } catch (error48) {
52780
53547
  const message = `Could not write MCP config for automatic setup: ${error48?.message || error48}`;
52781
53548
  LOG.error("MeshCoordinator", message);
@@ -52812,6 +53579,16 @@ Run 'adhdev doctor' for detailed diagnostics.`
52812
53579
  return { success: false, error: launchResult?.error || "Failed to launch CLI session" };
52813
53580
  }
52814
53581
  LOG.info("MeshCoordinator", `Launched ${cliType} coordinator for mesh ${meshId} in ${workspace}`);
53582
+ try {
53583
+ const { appendLedgerEntry: appendLedgerEntry2 } = await Promise.resolve().then(() => (init_mesh_ledger(), mesh_ledger_exports));
53584
+ appendLedgerEntry2(meshId, {
53585
+ kind: "coordinator_started",
53586
+ sessionId: launchResult.sessionId || launchResult.id,
53587
+ providerType: cliType,
53588
+ payload: { workspace }
53589
+ });
53590
+ } catch {
53591
+ }
52815
53592
  return {
52816
53593
  success: true,
52817
53594
  meshId,
@@ -56359,6 +57136,7 @@ data: ${JSON.stringify(msg.data)}
56359
57136
  };
56360
57137
  init_logger();
56361
57138
  init_config();
57139
+ init_mesh_events();
56362
57140
  }
56363
57141
  });
56364
57142
 
@@ -56564,6 +57342,7 @@ function annotateRapidReadChatAdvisory(payload, options) {
56564
57342
  }
56565
57343
 
56566
57344
  // src/tools/mesh-tools.ts
57345
+ init_dist2();
56567
57346
  var meshSessionProviderMetadata = /* @__PURE__ */ new Map();
56568
57347
  async function refreshMeshFromDaemon(ctx) {
56569
57348
  if (!(ctx.transport instanceof IpcTransport)) return;
@@ -56744,9 +57523,34 @@ var MESH_LIST_NODES_TOOL = {
56744
57523
  properties: {}
56745
57524
  }
56746
57525
  };
57526
+ var MESH_ENQUEUE_TASK_TOOL = {
57527
+ name: "mesh_enqueue_task",
57528
+ description: "Add a new task to the mesh work queue. Idle nodes will automatically pull and execute tasks from this queue. Use this instead of mesh_send_task when you do not need to target a specific node.",
57529
+ inputSchema: {
57530
+ type: "object",
57531
+ properties: {
57532
+ message: { type: "string", description: "The task instruction for the agent." }
57533
+ },
57534
+ required: ["message"]
57535
+ }
57536
+ };
57537
+ var MESH_VIEW_QUEUE_TOOL = {
57538
+ name: "mesh_view_queue",
57539
+ description: "View the current status of the mesh work queue (pending, assigned, completed, failed tasks).",
57540
+ inputSchema: {
57541
+ type: "object",
57542
+ properties: {
57543
+ status: {
57544
+ type: "array",
57545
+ items: { type: "string" },
57546
+ description: "Filter by task status: pending, assigned, completed, failed. Returns all if omitted."
57547
+ }
57548
+ }
57549
+ }
57550
+ };
56747
57551
  var MESH_SEND_TASK_TOOL = {
56748
57552
  name: "mesh_send_task",
56749
- description: "Send a natural-language task to an agent session on a mesh node. The agent will execute the task autonomously.",
57553
+ description: "Legacy push-based task assignment. Enqueues a task specifically targeted at a given node. The node will pull it immediately if idle.",
56750
57554
  inputSchema: {
56751
57555
  type: "object",
56752
57556
  properties: {
@@ -56886,9 +57690,33 @@ var MESH_CLEANUP_SESSIONS_TOOL = {
56886
57690
  required: ["node_id", "mode"]
56887
57691
  }
56888
57692
  };
57693
+ var MESH_TASK_HISTORY_TOOL = {
57694
+ name: "mesh_task_history",
57695
+ description: "Read the task ledger for this mesh \u2014 dispatched tasks, completions, failures, checkpoints, and node lifecycle events. Use to understand what has been done before deciding next steps, to detect repeated failures, and to inform recovery decisions.",
57696
+ inputSchema: {
57697
+ type: "object",
57698
+ properties: {
57699
+ tail: { type: "number", description: "Number of recent entries to return (default: 20)." },
57700
+ kind: { type: "string", description: "Filter by entry kind: task_dispatched, task_completed, task_failed, task_stalled, session_launched, checkpoint_created, node_cloned, node_removed." }
57701
+ }
57702
+ }
57703
+ };
57704
+ var MESH_REFINE_NODE_TOOL = {
57705
+ name: "mesh_refine_node",
57706
+ description: "The Refinery: Automatically validate and merge a completed worktree node back into its base branch. This tool automates the validation gate and merge queue step. It will merge the node's branch into its base branch and cleanly remove the worktree node and its sessions.",
57707
+ inputSchema: {
57708
+ type: "object",
57709
+ properties: {
57710
+ node_id: { type: "string", description: "Node ID of the completed worktree node to refine and merge." }
57711
+ },
57712
+ required: ["node_id"]
57713
+ }
57714
+ };
56889
57715
  var ALL_MESH_TOOLS = [
56890
57716
  MESH_STATUS_TOOL,
56891
57717
  MESH_LIST_NODES_TOOL,
57718
+ MESH_ENQUEUE_TASK_TOOL,
57719
+ MESH_VIEW_QUEUE_TOOL,
56892
57720
  MESH_SEND_TASK_TOOL,
56893
57721
  MESH_READ_CHAT_TOOL,
56894
57722
  MESH_READ_DEBUG_TOOL,
@@ -56898,7 +57726,9 @@ var ALL_MESH_TOOLS = [
56898
57726
  MESH_APPROVE_TOOL,
56899
57727
  MESH_CLONE_NODE_TOOL,
56900
57728
  MESH_REMOVE_NODE_TOOL,
56901
- MESH_CLEANUP_SESSIONS_TOOL
57729
+ MESH_REFINE_NODE_TOOL,
57730
+ MESH_CLEANUP_SESSIONS_TOOL,
57731
+ MESH_TASK_HISTORY_TOOL
56902
57732
  ];
56903
57733
  async function meshStatus(ctx) {
56904
57734
  await refreshMeshFromDaemon(ctx);
@@ -56949,6 +57779,10 @@ async function meshStatus(ctx) {
56949
57779
  refreshedAt: (/* @__PURE__ */ new Date()).toISOString(),
56950
57780
  nodes: results
56951
57781
  };
57782
+ try {
57783
+ response.ledgerSummary = getLedgerSummary(mesh.id);
57784
+ } catch {
57785
+ }
56952
57786
  if (ctx.transport instanceof IpcTransport) {
56953
57787
  try {
56954
57788
  const eventsResult = await ctx.transport.command("get_pending_mesh_events", {});
@@ -56961,6 +57795,14 @@ async function meshStatus(ctx) {
56961
57795
  }
56962
57796
  return JSON.stringify(response, null, 2);
56963
57797
  }
57798
+ async function meshTaskHistory(ctx, args) {
57799
+ const { mesh } = ctx;
57800
+ const tail = typeof args.tail === "number" && args.tail > 0 ? args.tail : 20;
57801
+ const kind = typeof args.kind === "string" && args.kind.trim() ? [args.kind.trim()] : void 0;
57802
+ const entries = readLedgerEntries(mesh.id, { tail, kind });
57803
+ const summary = getLedgerSummary(mesh.id);
57804
+ return JSON.stringify({ meshId: mesh.id, entries, summary }, null, 2);
57805
+ }
56964
57806
  async function meshListNodes(ctx) {
56965
57807
  await refreshMeshFromDaemon(ctx);
56966
57808
  const { mesh } = ctx;
@@ -56979,29 +57821,54 @@ async function meshListNodes(ctx) {
56979
57821
  }))
56980
57822
  }, null, 2);
56981
57823
  }
57824
+ async function meshEnqueueTask(ctx, args) {
57825
+ try {
57826
+ const task = enqueueTask(ctx.mesh.id, args.message);
57827
+ if (ctx.transport instanceof IpcTransport && ctx.localDaemonId) {
57828
+ ctx.transport.meshCommand(ctx.localDaemonId, "trigger_mesh_queue", { meshId: ctx.mesh.id }).catch(() => {
57829
+ });
57830
+ } else if (isLocalTransport(ctx.transport)) {
57831
+ ctx.transport.command("trigger_mesh_queue", { meshId: ctx.mesh.id }).catch(() => {
57832
+ });
57833
+ }
57834
+ return JSON.stringify({ success: true, taskId: task.id, status: task.status });
57835
+ } catch (e) {
57836
+ return JSON.stringify({ success: false, error: e.message });
57837
+ }
57838
+ }
57839
+ async function meshViewQueue(ctx, args) {
57840
+ try {
57841
+ const queue = getQueue(ctx.mesh.id, { status: args.status });
57842
+ return JSON.stringify({ success: true, queue }, null, 2);
57843
+ } catch (e) {
57844
+ return JSON.stringify({ success: false, error: e.message });
57845
+ }
57846
+ }
56982
57847
  async function meshSendTask(ctx, args) {
56983
57848
  const node = await findNodeWithRefresh(ctx, args.node_id);
56984
57849
  if (node.policy?.readOnly) {
56985
57850
  return JSON.stringify({ error: `Node '${args.node_id}' is read-only` });
56986
57851
  }
56987
- if (isLocalTransport(ctx.transport)) {
56988
- const result = await commandForNode(ctx, node, "send_chat", {
56989
- message: args.message,
56990
- sessionId: args.session_id,
56991
- targetSessionId: args.session_id
56992
- });
56993
- const payload = unwrapCommandPayload(result);
56994
- if (payload?.success === false) {
56995
- return JSON.stringify({
56996
- success: false,
56997
- nodeId: args.node_id,
56998
- sessionId: args.session_id,
56999
- error: payload.error || "send_chat failed"
57852
+ try {
57853
+ if (!isLocalTransport(ctx.transport) && node.daemonId) {
57854
+ const res = await ctx.transport.meshEnqueueTask(node.daemonId, {
57855
+ meshId: ctx.mesh.id,
57856
+ message: args.message,
57857
+ targetNodeId: args.node_id
57000
57858
  });
57859
+ return JSON.stringify(res);
57001
57860
  }
57002
- return JSON.stringify({ success: true, nodeId: args.node_id, sessionId: args.session_id });
57003
- } else {
57004
- return JSON.stringify({ error: "Cloud mesh send_task not yet implemented" });
57861
+ const task = enqueueTask(ctx.mesh.id, args.message, { targetNodeId: args.node_id });
57862
+ if (ctx.transport instanceof IpcTransport && node.daemonId && node.daemonId !== ctx.localDaemonId) {
57863
+ ctx.transport.meshCommand(node.daemonId, "trigger_mesh_queue", { meshId: ctx.mesh.id }).catch(() => {
57864
+ });
57865
+ } else if (isLocalTransport(ctx.transport)) {
57866
+ ctx.transport.command("trigger_mesh_queue", { meshId: ctx.mesh.id }).catch(() => {
57867
+ });
57868
+ }
57869
+ return JSON.stringify({ success: true, nodeId: args.node_id, taskId: task.id, status: task.status });
57870
+ } catch (e) {
57871
+ return JSON.stringify({ success: false, error: e.message });
57005
57872
  }
57006
57873
  }
57007
57874
  async function meshReadChat(ctx, args) {
@@ -57035,8 +57902,19 @@ async function meshReadChat(ctx, args) {
57035
57902
  );
57036
57903
  }
57037
57904
  return JSON.stringify(payload, null, 2);
57905
+ } else if (!isLocalTransport(ctx.transport) && node.daemonId) {
57906
+ try {
57907
+ const targetId = `${node.daemonId}:session:${args.session_id}`;
57908
+ const res = await ctx.transport.readChat(targetId, {
57909
+ limit: args.tail ?? 10,
57910
+ sessionId: args.session_id
57911
+ });
57912
+ return JSON.stringify(res, null, 2);
57913
+ } catch (e) {
57914
+ return JSON.stringify({ success: false, error: e.message });
57915
+ }
57038
57916
  } else {
57039
- return JSON.stringify({ error: "Cloud mesh read_chat not yet implemented" });
57917
+ return JSON.stringify({ error: "Cloud mesh read_chat requires node daemonId" });
57040
57918
  }
57041
57919
  }
57042
57920
  async function meshReadDebug(ctx, args) {
@@ -57056,8 +57934,20 @@ async function meshReadDebug(ctx, args) {
57056
57934
  });
57057
57935
  const payload = unwrapCommandPayload(result);
57058
57936
  return JSON.stringify(payload, null, 2);
57937
+ } else if (!isLocalTransport(ctx.transport) && node.daemonId) {
57938
+ try {
57939
+ const targetId = `${node.daemonId}:session:${args.session_id}`;
57940
+ const res = await ctx.transport.getChatDebugBundle(targetId, {
57941
+ sessionId: args.session_id,
57942
+ tailLimit: args.tail ?? 40,
57943
+ delivery: args.delivery
57944
+ });
57945
+ return JSON.stringify(res, null, 2);
57946
+ } catch (e) {
57947
+ return JSON.stringify({ success: false, error: e.message });
57948
+ }
57059
57949
  }
57060
- return JSON.stringify({ error: "Cloud mesh read_debug not yet implemented" });
57950
+ return JSON.stringify({ error: "Cloud mesh read_debug requires node daemonId" });
57061
57951
  }
57062
57952
  async function meshLaunchSession(ctx, args) {
57063
57953
  const node = await findNodeWithRefresh(ctx, args.node_id);
@@ -57106,13 +57996,70 @@ async function meshLaunchSession(ctx, args) {
57106
57996
  ...providerSessionId ? { providerSessionId } : {}
57107
57997
  });
57108
57998
  }
57999
+ try {
58000
+ appendLedgerEntry(ctx.mesh.id, {
58001
+ kind: "session_launched",
58002
+ nodeId: args.node_id,
58003
+ sessionId: runtimeSessionId || void 0,
58004
+ providerType: resolvedProviderType,
58005
+ payload: { providerSessionId }
58006
+ });
58007
+ } catch {
58008
+ }
58009
+ if (ctx.transport instanceof IpcTransport && node.daemonId && node.daemonId !== ctx.localDaemonId) {
58010
+ ctx.transport.meshCommand(node.daemonId, "trigger_mesh_queue", { meshId: ctx.mesh.id }).catch(() => {
58011
+ });
58012
+ } else if (isLocalTransport(ctx.transport)) {
58013
+ ctx.transport.command("trigger_mesh_queue", { meshId: ctx.mesh.id }).catch(() => {
58014
+ });
58015
+ }
57109
58016
  return JSON.stringify({
57110
58017
  ...launchPayload,
57111
58018
  resolvedProviderType,
57112
58019
  ...providerSessionId ? { providerSessionId } : {}
57113
58020
  }, null, 2);
58021
+ } else if (!isLocalTransport(ctx.transport) && node.daemonId) {
58022
+ let resolvedProviderType = typeof args.type === "string" && args.type.trim() ? args.type : "";
58023
+ if (!resolvedProviderType) {
58024
+ const providerPriority = readProviderPriority(node.policy);
58025
+ if (!providerPriority.length) {
58026
+ return JSON.stringify({ success: false, error: missingProviderPriorityMessage(args.node_id) });
58027
+ }
58028
+ resolvedProviderType = providerPriority[0];
58029
+ }
58030
+ const coordinatorNode = resolveCoordinatorNode(ctx);
58031
+ const coordinatorDaemonId = coordinatorNode?.daemonId || ctx.localDaemonId;
58032
+ const spawnedSessionVisibility = readSpawnedSessionVisibility(ctx.mesh.policy);
58033
+ try {
58034
+ const res = await ctx.transport.launch(node.daemonId, {
58035
+ type: resolvedProviderType,
58036
+ dir: node.workspace,
58037
+ settings: {
58038
+ meshNodeFor: ctx.mesh.id,
58039
+ meshNodeId: args.node_id,
58040
+ spawnedSessionVisibility,
58041
+ ...coordinatorDaemonId ? { meshCoordinatorDaemonId: coordinatorDaemonId } : {},
58042
+ ...coordinatorNode?.id ? { meshCoordinatorNodeId: coordinatorNode.id } : {},
58043
+ launchedByCoordinator: true
58044
+ }
58045
+ });
58046
+ const runtimeSessionId = typeof res?.sessionId === "string" ? res.sessionId : typeof res?.id === "string" ? res.id : "";
58047
+ try {
58048
+ appendLedgerEntry(ctx.mesh.id, {
58049
+ kind: "session_launched",
58050
+ nodeId: args.node_id,
58051
+ sessionId: runtimeSessionId || void 0,
58052
+ providerType: resolvedProviderType,
58053
+ payload: {}
58054
+ });
58055
+ } catch {
58056
+ }
58057
+ return JSON.stringify({ ...res, resolvedProviderType }, null, 2);
58058
+ } catch (e) {
58059
+ return JSON.stringify({ success: false, error: e.message });
58060
+ }
57114
58061
  } else {
57115
- return JSON.stringify({ error: "Cloud mesh launch_session not yet implemented" });
58062
+ return JSON.stringify({ error: "Cloud mesh launch_session requires node daemonId" });
57116
58063
  }
57117
58064
  }
57118
58065
  async function meshGitStatus(ctx, args) {
@@ -57155,9 +58102,36 @@ async function meshCheckpoint(ctx, args) {
57155
58102
  message: args.message,
57156
58103
  includeUntracked: true
57157
58104
  });
58105
+ try {
58106
+ appendLedgerEntry(ctx.mesh.id, {
58107
+ kind: "checkpoint_created",
58108
+ nodeId: args.node_id,
58109
+ payload: { message: args.message, commit: result?.checkpoint?.commit }
58110
+ });
58111
+ } catch {
58112
+ }
57158
58113
  return JSON.stringify(result, null, 2);
58114
+ } else if (!isLocalTransport(ctx.transport) && node.daemonId) {
58115
+ try {
58116
+ const res = await ctx.transport.gitCheckpoint(node.daemonId, {
58117
+ workspace: node.workspace,
58118
+ message: args.message,
58119
+ includeUntracked: true
58120
+ });
58121
+ try {
58122
+ appendLedgerEntry(ctx.mesh.id, {
58123
+ kind: "checkpoint_created",
58124
+ nodeId: args.node_id,
58125
+ payload: { message: args.message, commit: res?.checkpoint?.commit }
58126
+ });
58127
+ } catch {
58128
+ }
58129
+ return JSON.stringify(res, null, 2);
58130
+ } catch (e) {
58131
+ return JSON.stringify({ success: false, error: e.message });
58132
+ }
57159
58133
  } else {
57160
- return JSON.stringify({ error: "Cloud mesh checkpoint not yet implemented" });
58134
+ return JSON.stringify({ error: "Cloud mesh checkpoint requires node daemonId" });
57161
58135
  }
57162
58136
  }
57163
58137
  async function meshApprove(ctx, args) {
@@ -57174,8 +58148,16 @@ async function meshApprove(ctx, args) {
57174
58148
  action: args.action === "reject" ? "reject" : "approve"
57175
58149
  });
57176
58150
  return JSON.stringify(result, null, 2);
58151
+ } else if (!isLocalTransport(ctx.transport) && node.daemonId) {
58152
+ try {
58153
+ const targetId = `${node.daemonId}:session:${args.session_id}`;
58154
+ const res = await ctx.transport.approve(targetId, args.action === "reject" ? "reject" : "approve");
58155
+ return JSON.stringify(res, null, 2);
58156
+ } catch (e) {
58157
+ return JSON.stringify({ success: false, error: e.message });
58158
+ }
57177
58159
  } else {
57178
- return JSON.stringify({ error: "Cloud mesh approve not yet implemented" });
58160
+ return JSON.stringify({ error: "Cloud mesh approve requires node daemonId" });
57179
58161
  }
57180
58162
  }
57181
58163
  async function meshCloneNode(ctx, args) {
@@ -57196,8 +58178,28 @@ async function meshCloneNode(ctx, args) {
57196
58178
  ctx.mesh.updatedAt = (/* @__PURE__ */ new Date()).toISOString();
57197
58179
  }
57198
58180
  return JSON.stringify(result, null, 2);
58181
+ } else if (!isLocalTransport(ctx.transport) && sourceNode.daemonId) {
58182
+ try {
58183
+ const res = await ctx.transport.meshCloneNode(sourceNode.daemonId, {
58184
+ meshId: ctx.mesh.id,
58185
+ sourceNodeId: args.source_node_id,
58186
+ branch: args.branch,
58187
+ baseBranch: args.base_branch,
58188
+ inlineMesh: ctx.mesh
58189
+ });
58190
+ const clonePayload = extractCloneNodePayload(res);
58191
+ if (clonePayload?.success && clonePayload.node?.id) {
58192
+ const existingIndex = ctx.mesh.nodes.findIndex((n) => n.id === clonePayload.node.id);
58193
+ if (existingIndex >= 0) ctx.mesh.nodes[existingIndex] = clonePayload.node;
58194
+ else ctx.mesh.nodes.push(clonePayload.node);
58195
+ ctx.mesh.updatedAt = (/* @__PURE__ */ new Date()).toISOString();
58196
+ }
58197
+ return JSON.stringify(res, null, 2);
58198
+ } catch (e) {
58199
+ return JSON.stringify({ success: false, error: e.message });
58200
+ }
57199
58201
  } else {
57200
- return JSON.stringify({ error: "Cloud mesh clone_node not yet implemented" });
58202
+ return JSON.stringify({ error: "Cloud mesh clone_node requires source node daemonId" });
57201
58203
  }
57202
58204
  }
57203
58205
  async function meshCleanupSessions(ctx, args) {
@@ -57212,8 +58214,22 @@ async function meshCleanupSessions(ctx, args) {
57212
58214
  inlineMesh: ctx.mesh
57213
58215
  });
57214
58216
  return JSON.stringify(result, null, 2);
58217
+ } else if (!isLocalTransport(ctx.transport) && node.daemonId) {
58218
+ try {
58219
+ const res = await ctx.transport.meshCleanupSessions(node.daemonId, {
58220
+ meshId: ctx.mesh.id,
58221
+ nodeId: args.node_id,
58222
+ mode: args.mode,
58223
+ sessionIds: args.session_ids,
58224
+ dryRun: args.dry_run === true,
58225
+ inlineMesh: ctx.mesh
58226
+ });
58227
+ return JSON.stringify(res, null, 2);
58228
+ } catch (e) {
58229
+ return JSON.stringify({ success: false, error: e.message });
58230
+ }
57215
58231
  } else {
57216
- return JSON.stringify({ error: "Cloud mesh cleanup_sessions not yet implemented" });
58232
+ return JSON.stringify({ error: "Cloud mesh cleanup_sessions requires node daemonId" });
57217
58233
  }
57218
58234
  }
57219
58235
  async function meshRemoveNode(ctx, args) {
@@ -57233,8 +58249,65 @@ async function meshRemoveNode(ctx, args) {
57233
58249
  }
57234
58250
  }
57235
58251
  return JSON.stringify(result, null, 2);
58252
+ } else if (!isLocalTransport(ctx.transport) && node.daemonId) {
58253
+ try {
58254
+ const res = await ctx.transport.meshRemoveNode(node.daemonId, {
58255
+ meshId: ctx.mesh.id,
58256
+ nodeId: args.node_id,
58257
+ ...args.session_cleanup_mode ? { sessionCleanupMode: args.session_cleanup_mode } : {},
58258
+ inlineMesh: ctx.mesh
58259
+ });
58260
+ if (res?.success && res.removed !== false) {
58261
+ const idx = ctx.mesh.nodes.findIndex((n) => n.id === args.node_id);
58262
+ if (idx >= 0) {
58263
+ ctx.mesh.nodes.splice(idx, 1);
58264
+ ctx.mesh.updatedAt = (/* @__PURE__ */ new Date()).toISOString();
58265
+ }
58266
+ }
58267
+ return JSON.stringify(res, null, 2);
58268
+ } catch (e) {
58269
+ return JSON.stringify({ success: false, error: e.message });
58270
+ }
58271
+ } else {
58272
+ return JSON.stringify({ error: "Cloud mesh remove_node requires node daemonId" });
58273
+ }
58274
+ }
58275
+ async function meshRefineNode(ctx, args) {
58276
+ const node = await findNodeWithRefresh(ctx, args.node_id);
58277
+ if (isLocalTransport(ctx.transport)) {
58278
+ const result = await commandForNode(ctx, node, "refine_mesh_node", {
58279
+ meshId: ctx.mesh.id,
58280
+ nodeId: args.node_id,
58281
+ inlineMesh: ctx.mesh
58282
+ });
58283
+ if (result?.success && result.removeResult?.removed !== false) {
58284
+ const idx = ctx.mesh.nodes.findIndex((n) => n.id === args.node_id);
58285
+ if (idx >= 0) {
58286
+ ctx.mesh.nodes.splice(idx, 1);
58287
+ ctx.mesh.updatedAt = (/* @__PURE__ */ new Date()).toISOString();
58288
+ }
58289
+ }
58290
+ return JSON.stringify(result, null, 2);
58291
+ } else if (!isLocalTransport(ctx.transport) && node.daemonId) {
58292
+ try {
58293
+ const res = await ctx.transport.meshRefineNode(node.daemonId, {
58294
+ meshId: ctx.mesh.id,
58295
+ nodeId: args.node_id,
58296
+ inlineMesh: ctx.mesh
58297
+ });
58298
+ if (res?.success && res.removeResult?.removed !== false) {
58299
+ const idx = ctx.mesh.nodes.findIndex((n) => n.id === args.node_id);
58300
+ if (idx >= 0) {
58301
+ ctx.mesh.nodes.splice(idx, 1);
58302
+ ctx.mesh.updatedAt = (/* @__PURE__ */ new Date()).toISOString();
58303
+ }
58304
+ }
58305
+ return JSON.stringify(res, null, 2);
58306
+ } catch (e) {
58307
+ return JSON.stringify({ success: false, error: e.message });
58308
+ }
57236
58309
  } else {
57237
- return JSON.stringify({ error: "Cloud mesh remove_node not yet implemented" });
58310
+ return JSON.stringify({ error: "Cloud mesh refine_node requires node daemonId" });
57238
58311
  }
57239
58312
  }
57240
58313
 
@@ -57348,6 +58421,36 @@ var CloudTransport = class {
57348
58421
  "Authorization": `Bearer ${this.apiKey}`
57349
58422
  };
57350
58423
  }
58424
+ async listRemoteMeshes() {
58425
+ const res = await fetch(`${this.baseUrl}/api/v1/repo-meshes`, { headers: this.headers() });
58426
+ if (!res.ok) throw new Error(`List remote meshes failed: ${res.status}`);
58427
+ return res.json();
58428
+ }
58429
+ async createRemoteMesh(data) {
58430
+ const res = await fetch(`${this.baseUrl}/api/v1/repo-meshes`, {
58431
+ method: "POST",
58432
+ headers: this.headers(),
58433
+ body: JSON.stringify(data)
58434
+ });
58435
+ if (!res.ok) throw new Error(`Create remote mesh failed: ${res.status}`);
58436
+ return res.json();
58437
+ }
58438
+ async deleteRemoteMesh(meshId) {
58439
+ const res = await fetch(`${this.baseUrl}/api/v1/repo-meshes/${encodeURIComponent(meshId)}`, {
58440
+ method: "DELETE",
58441
+ headers: this.headers()
58442
+ });
58443
+ if (!res.ok) throw new Error(`Delete remote mesh failed: ${res.status}`);
58444
+ }
58445
+ async syncMeshLedger(meshId, data) {
58446
+ const res = await fetch(`${this.baseUrl}/api/v1/repo-meshes/${encodeURIComponent(meshId)}/ledger/sync`, {
58447
+ method: "POST",
58448
+ headers: this.headers(),
58449
+ body: JSON.stringify(data)
58450
+ });
58451
+ if (!res.ok) throw new Error(`Sync mesh ledger failed: ${res.status}`);
58452
+ return res.json();
58453
+ }
57351
58454
  async listDaemons() {
57352
58455
  const res = await fetch(`${this.baseUrl}/api/v1/daemons`, { headers: this.headers() });
57353
58456
  if (!res.ok) throw new Error(`List daemons failed: ${res.status}`);
@@ -57505,6 +58608,66 @@ var CloudTransport = class {
57505
58608
  if (!res.ok) throw new Error(`Git checkpoint failed: ${res.status}`);
57506
58609
  return res.json();
57507
58610
  }
58611
+ async meshCloneNode(daemonId, payload) {
58612
+ const res = await fetch(
58613
+ `${this.baseUrl}/api/v1/shortcuts/${encodeURIComponent(daemonId)}/mesh/clone-node`,
58614
+ {
58615
+ method: "POST",
58616
+ headers: this.headers(),
58617
+ body: JSON.stringify(payload)
58618
+ }
58619
+ );
58620
+ if (!res.ok) throw new Error(`Mesh clone node failed: ${res.status}`);
58621
+ return res.json();
58622
+ }
58623
+ async meshRemoveNode(daemonId, payload) {
58624
+ const res = await fetch(
58625
+ `${this.baseUrl}/api/v1/shortcuts/${encodeURIComponent(daemonId)}/mesh/remove-node`,
58626
+ {
58627
+ method: "POST",
58628
+ headers: this.headers(),
58629
+ body: JSON.stringify(payload)
58630
+ }
58631
+ );
58632
+ if (!res.ok) throw new Error(`Mesh remove node failed: ${res.status}`);
58633
+ return res.json();
58634
+ }
58635
+ async meshCleanupSessions(daemonId, payload) {
58636
+ const res = await fetch(
58637
+ `${this.baseUrl}/api/v1/shortcuts/${encodeURIComponent(daemonId)}/mesh/cleanup-sessions`,
58638
+ {
58639
+ method: "POST",
58640
+ headers: this.headers(),
58641
+ body: JSON.stringify(payload)
58642
+ }
58643
+ );
58644
+ if (!res.ok) throw new Error(`Mesh cleanup sessions failed: ${res.status}`);
58645
+ return res.json();
58646
+ }
58647
+ async meshEnqueueTask(daemonId, payload) {
58648
+ const res = await fetch(
58649
+ `${this.baseUrl}/api/v1/shortcuts/${encodeURIComponent(daemonId)}/mesh/enqueue`,
58650
+ {
58651
+ method: "POST",
58652
+ headers: this.headers(),
58653
+ body: JSON.stringify(payload)
58654
+ }
58655
+ );
58656
+ if (!res.ok) throw new Error(`Mesh enqueue task failed: ${res.status}`);
58657
+ return res.json();
58658
+ }
58659
+ async meshRefineNode(daemonId, payload) {
58660
+ const res = await fetch(
58661
+ `${this.baseUrl}/api/v1/shortcuts/${encodeURIComponent(daemonId)}/mesh/refine-node`,
58662
+ {
58663
+ method: "POST",
58664
+ headers: this.headers(),
58665
+ body: JSON.stringify(payload)
58666
+ }
58667
+ );
58668
+ if (!res.ok) throw new Error(`Mesh refine node failed: ${res.status}`);
58669
+ return res.json();
58670
+ }
57508
58671
  async ping() {
57509
58672
  try {
57510
58673
  await this.listDaemons();
@@ -58372,7 +59535,7 @@ var GIT_CHECKPOINT_TOOL = {
58372
59535
  required: ["workspace", "message"]
58373
59536
  }
58374
59537
  };
58375
- async function gitCheckpoint(transport, args) {
59538
+ async function gitCheckpoint2(transport, args) {
58376
59539
  const message = args.message?.trim();
58377
59540
  if (!message) return "Error: message is required";
58378
59541
  if (message.length > 200) return "Error: message must be 200 characters or fewer";
@@ -58432,7 +59595,7 @@ var GIT_PUSH_TOOL = {
58432
59595
  required: ["workspace"]
58433
59596
  }
58434
59597
  };
58435
- async function gitPush(transport, args) {
59598
+ async function gitPush2(transport, args) {
58436
59599
  let raw;
58437
59600
  if (isLocalTransport(transport)) {
58438
59601
  raw = await transport.command("git_push", {
@@ -58823,6 +59986,12 @@ async function startMcpServer(opts) {
58823
59986
  case "mesh_list_nodes":
58824
59987
  text = await meshListNodes(meshCtx);
58825
59988
  break;
59989
+ case "mesh_enqueue_task":
59990
+ text = await meshEnqueueTask(meshCtx, a);
59991
+ break;
59992
+ case "mesh_view_queue":
59993
+ text = await meshViewQueue(meshCtx, a);
59994
+ break;
58826
59995
  case "mesh_send_task":
58827
59996
  text = await meshSendTask(meshCtx, a);
58828
59997
  break;
@@ -58850,9 +60019,15 @@ async function startMcpServer(opts) {
58850
60019
  case "mesh_remove_node":
58851
60020
  text = await meshRemoveNode(meshCtx, a);
58852
60021
  break;
60022
+ case "mesh_refine_node":
60023
+ text = await meshRefineNode(meshCtx, a);
60024
+ break;
58853
60025
  case "mesh_cleanup_sessions":
58854
60026
  text = await meshCleanupSessions(meshCtx, a);
58855
60027
  break;
60028
+ case "mesh_task_history":
60029
+ text = await meshTaskHistory(meshCtx, a);
60030
+ break;
58856
60031
  default:
58857
60032
  return { content: [{ type: "text", text: `Unknown tool: ${name}` }], isError: true };
58858
60033
  }
@@ -58941,11 +60116,11 @@ async function startMcpServer(opts) {
58941
60116
  return { content: [{ type: "text", text }] };
58942
60117
  }
58943
60118
  case "git_checkpoint": {
58944
- const text = await gitCheckpoint(transport, { workspace: a.workspace, message: a.message, include_untracked: a.include_untracked, daemon_id: a.daemon_id });
60119
+ const text = await gitCheckpoint2(transport, { workspace: a.workspace, message: a.message, include_untracked: a.include_untracked, daemon_id: a.daemon_id });
58945
60120
  return { content: [{ type: "text", text }] };
58946
60121
  }
58947
60122
  case "git_push": {
58948
- const text = await gitPush(transport, { workspace: a.workspace, remote: a.remote, branch: a.branch, daemon_id: a.daemon_id });
60123
+ const text = await gitPush2(transport, { workspace: a.workspace, remote: a.remote, branch: a.branch, daemon_id: a.daemon_id });
58949
60124
  return { content: [{ type: "text", text }] };
58950
60125
  }
58951
60126
  case "launch_session": {