@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.
- package/dist/index.js +1009 -216
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
- package/public/assets/{index-B_uT3-ej.js → index-6WEc6L46.js} +19 -19
- package/public/index.html +1 -1
- package/vendor/mcp-server/index.js +1461 -286
- package/vendor/mcp-server/index.js.map +1 -1
|
@@ -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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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 =
|
|
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(
|
|
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,
|
|
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 }) =>
|
|
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 }) =>
|
|
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
|
|
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
|
|
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(
|
|
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:
|
|
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,
|
|
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,
|
|
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,
|
|
28673
|
+
if (!(0, import_fs9.existsSync)(statePath)) {
|
|
28076
28674
|
return { ...DEFAULT_STATE };
|
|
28077
28675
|
}
|
|
28078
28676
|
try {
|
|
28079
|
-
const raw = (0,
|
|
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,
|
|
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 (
|
|
28110
|
-
const candidate = trimmed.startsWith("~") ?
|
|
28111
|
-
const resolved =
|
|
28112
|
-
return (0,
|
|
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("~") ?
|
|
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,
|
|
28741
|
+
if ((0, import_fs10.existsSync)(resolved)) return resolved;
|
|
28144
28742
|
} else {
|
|
28145
|
-
if ((0,
|
|
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,
|
|
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,
|
|
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
|
|
28802
|
+
return path10.join(os32.homedir(), trimmed.slice(1));
|
|
28205
28803
|
}
|
|
28206
28804
|
function isExplicitCommandPath(command) {
|
|
28207
28805
|
const trimmed = command.trim();
|
|
28208
|
-
return
|
|
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 =
|
|
28216
|
-
return (0,
|
|
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 =
|
|
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 =
|
|
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 (
|
|
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 =
|
|
28349
|
-
const 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,
|
|
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(
|
|
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,
|
|
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,
|
|
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,
|
|
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,
|
|
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:
|
|
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,
|
|
34986
|
-
const hash2 = (0,
|
|
34987
|
-
return (0,
|
|
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,
|
|
34993
|
-
if ((0,
|
|
34994
|
-
return (0,
|
|
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,
|
|
35657
|
+
addCandidate((0, import_path6.join)(dir, "node"));
|
|
35035
35658
|
}
|
|
35036
35659
|
}
|
|
35037
35660
|
function addNodeCandidatesFromNvm(homeDir, addCandidate) {
|
|
35038
|
-
const versionsDir = (0,
|
|
35661
|
+
const versionsDir = (0, import_path6.join)(homeDir, ".nvm", "versions", "node");
|
|
35039
35662
|
try {
|
|
35040
|
-
const versionDirs = (0,
|
|
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,
|
|
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,
|
|
35081
|
-
addCandidate((0,
|
|
35082
|
-
addCandidate((0,
|
|
35083
|
-
addCandidate((0,
|
|
35084
|
-
addCandidate((0,
|
|
35085
|
-
addCandidate((0,
|
|
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,
|
|
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,
|
|
35104
|
-
return
|
|
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,
|
|
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,
|
|
36433
|
+
const sourceConfigPath = (0, import_path7.join)(sourceHome, "config.yaml");
|
|
35928
36434
|
if (!fs10.existsSync(sourceConfigPath)) return { config: {}, sourceHome, sourceConfigPath };
|
|
35929
|
-
if ((0,
|
|
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,
|
|
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,
|
|
35938
|
-
const targetPath = (0,
|
|
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,
|
|
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
|
-
|
|
40441
|
-
|
|
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
|
-
|
|
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
|
-
|
|
40973
|
+
os4 = __toESM(require("os"), 1);
|
|
40461
40974
|
path5 = __toESM(require("path"), 1);
|
|
40462
|
-
|
|
40975
|
+
import_crypto6 = require("crypto");
|
|
40463
40976
|
path6 = __toESM(require("path"), 1);
|
|
40464
40977
|
path7 = __toESM(require("path"), 1);
|
|
40465
|
-
|
|
40466
|
-
|
|
40978
|
+
import_fs9 = require("fs");
|
|
40979
|
+
import_path5 = require("path");
|
|
40467
40980
|
import_child_process4 = require("child_process");
|
|
40468
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
40519
|
-
|
|
41031
|
+
import_crypto8 = require("crypto");
|
|
41032
|
+
import_fs13 = require("fs");
|
|
40520
41033
|
import_module2 = require("module");
|
|
40521
41034
|
os17 = __toESM(require("os"), 1);
|
|
40522
|
-
|
|
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
|
-
|
|
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
|
|
40703
|
-
a.
|
|
40704
|
-
b. If you need branch isolation for parallel work, call \`mesh_clone_node\` to create a worktree node first.
|
|
40705
|
-
c.
|
|
40706
|
-
d.
|
|
40707
|
-
4. **Monitor** \u2014 Prefer event-driven completion/status notifications. Do **not** poll \`mesh_read_chat\` repeatedly
|
|
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" ?
|
|
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 =
|
|
41282
|
+
currentLogFile = path8.join(LOG_DIR, `daemon-${currentDate}.log`);
|
|
40729
41283
|
cleanOldLogs();
|
|
40730
41284
|
try {
|
|
40731
|
-
const oldLog =
|
|
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,
|
|
41289
|
+
fs2.renameSync(oldLog, path8.join(LOG_DIR, `daemon-${oldDate}.log`));
|
|
40736
41290
|
}
|
|
40737
|
-
const oldLogBackup =
|
|
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 =
|
|
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(
|
|
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
|
-
|
|
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:
|
|
53225
|
+
const { randomUUID: randomUUID10 } = await import("crypto");
|
|
52568
53226
|
node = {
|
|
52569
|
-
id: `node_${
|
|
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:
|
|
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
|
-
|
|
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 =
|
|
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(
|
|
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
|
-
|
|
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: "
|
|
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
|
-
|
|
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
|
-
|
|
56988
|
-
|
|
56989
|
-
|
|
56990
|
-
|
|
56991
|
-
|
|
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
|
-
|
|
57003
|
-
|
|
57004
|
-
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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": {
|