@adhdev/daemon-standalone 0.9.76 → 0.9.77-rc.10
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 +902 -209
- package/dist/index.js.map +1 -1
- package/package.json +4 -4
- 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 +1354 -279
- package/vendor/mcp-server/index.js.map +1 -1
- package/vendor/session-host-daemon/index.js +0 -0
- package/vendor/session-host-daemon/index.mjs +0 -0
|
@@ -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
|
+
input: 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 : {};
|
|
@@ -33891,7 +34501,7 @@ function commandExists(command) {
|
|
|
33891
34501
|
const trimmed = command.trim();
|
|
33892
34502
|
if (!trimmed) return false;
|
|
33893
34503
|
if (isExplicitCommand(trimmed)) {
|
|
33894
|
-
return (0,
|
|
34504
|
+
return (0, import_fs12.existsSync)(expandExecutable(trimmed));
|
|
33895
34505
|
}
|
|
33896
34506
|
try {
|
|
33897
34507
|
(0, import_child_process7.execFileSync)(process.platform === "win32" ? "where" : "which", [trimmed], {
|
|
@@ -33912,10 +34522,10 @@ function hasCliArg(args, flag) {
|
|
|
33912
34522
|
}
|
|
33913
34523
|
function ensureEmptyDelegatedMcpConfig(workspace) {
|
|
33914
34524
|
const baseDir = path18.join(os13.tmpdir(), "adhdev-delegated-agent-empty-mcp");
|
|
33915
|
-
(0,
|
|
34525
|
+
(0, import_fs12.mkdirSync)(baseDir, { recursive: true });
|
|
33916
34526
|
const workspaceHash = crypto4.createHash("sha256").update(path18.resolve(workspace || os13.tmpdir())).digest("hex").slice(0, 16);
|
|
33917
34527
|
const filePath = path18.join(baseDir, `${workspaceHash}.json`);
|
|
33918
|
-
(0,
|
|
34528
|
+
(0, import_fs12.writeFileSync)(filePath, JSON.stringify({ mcpServers: {} }, null, 2), "utf-8");
|
|
33919
34529
|
return filePath;
|
|
33920
34530
|
}
|
|
33921
34531
|
function buildCoordinatorDelegatedCliLaunchOptions(input) {
|
|
@@ -34876,7 +35486,7 @@ function resolveHermesMeshCoordinatorSetup(options) {
|
|
|
34876
35486
|
reason: "Could not resolve the ADHDev MCP server entrypoint and a Node runtime with WebSocket support for daemon IPC mode"
|
|
34877
35487
|
};
|
|
34878
35488
|
}
|
|
34879
|
-
const configPath = (0,
|
|
35489
|
+
const configPath = (0, import_path6.join)(resolveHermesCoordinatorHome(options.meshId, options.workspace), "config.yaml");
|
|
34880
35490
|
if (!configPath.trim()) {
|
|
34881
35491
|
return createHermesManualMeshCoordinatorSetup(options.meshId, options.workspace);
|
|
34882
35492
|
}
|
|
@@ -34982,16 +35592,16 @@ function renderMeshCoordinatorTemplate(template, values) {
|
|
|
34982
35592
|
}
|
|
34983
35593
|
function resolveHermesCoordinatorHome(meshId, workspace) {
|
|
34984
35594
|
const key = `${meshId || "mesh"}
|
|
34985
|
-
${(0,
|
|
34986
|
-
const hash2 = (0,
|
|
34987
|
-
return (0,
|
|
35595
|
+
${(0, import_path6.resolve)(workspace || os17.tmpdir())}`;
|
|
35596
|
+
const hash2 = (0, import_crypto8.createHash)("sha256").update(key).digest("hex").slice(0, 16);
|
|
35597
|
+
return (0, import_path6.join)(os17.tmpdir(), `adhdev-hermes-mesh-coordinator-${hash2}`);
|
|
34988
35598
|
}
|
|
34989
35599
|
function resolveMcpConfigPath(configPath, workspace) {
|
|
34990
35600
|
const trimmed = configPath.trim();
|
|
34991
35601
|
if (trimmed === "~") return os17.homedir();
|
|
34992
|
-
if (trimmed.startsWith("~/")) return (0,
|
|
34993
|
-
if ((0,
|
|
34994
|
-
return (0,
|
|
35602
|
+
if (trimmed.startsWith("~/")) return (0, import_path6.join)(os17.homedir(), trimmed.slice(2));
|
|
35603
|
+
if ((0, import_path6.isAbsolute)(trimmed)) return trimmed;
|
|
35604
|
+
return (0, import_path6.join)(workspace, trimmed);
|
|
34995
35605
|
}
|
|
34996
35606
|
function resolveAdhdevMcpServerLaunch(options) {
|
|
34997
35607
|
const entryPath = resolveAdhdevMcpEntryPath(options.adhdevMcpEntryPath);
|
|
@@ -35031,15 +35641,15 @@ function addNodeCandidatesFromPath(pathValue, addCandidate) {
|
|
|
35031
35641
|
for (const entry of (pathValue || "").split(":")) {
|
|
35032
35642
|
const dir = entry.trim();
|
|
35033
35643
|
if (!dir) continue;
|
|
35034
|
-
addCandidate((0,
|
|
35644
|
+
addCandidate((0, import_path6.join)(dir, "node"));
|
|
35035
35645
|
}
|
|
35036
35646
|
}
|
|
35037
35647
|
function addNodeCandidatesFromNvm(homeDir, addCandidate) {
|
|
35038
|
-
const versionsDir = (0,
|
|
35648
|
+
const versionsDir = (0, import_path6.join)(homeDir, ".nvm", "versions", "node");
|
|
35039
35649
|
try {
|
|
35040
|
-
const versionDirs = (0,
|
|
35650
|
+
const versionDirs = (0, import_fs13.readdirSync)(versionsDir, { withFileTypes: true }).filter((entry) => entry.isDirectory()).map((entry) => entry.name).sort(compareNodeVersionNamesDescending);
|
|
35041
35651
|
for (const versionDir of versionDirs) {
|
|
35042
|
-
addCandidate((0,
|
|
35652
|
+
addCandidate((0, import_path6.join)(versionsDir, versionDir, "bin", "node"));
|
|
35043
35653
|
}
|
|
35044
35654
|
} catch {
|
|
35045
35655
|
}
|
|
@@ -35077,12 +35687,12 @@ function resolveAdhdevMcpEntryPath(explicitPath) {
|
|
|
35077
35687
|
const addPackagedCandidates = (baseFile) => {
|
|
35078
35688
|
if (!baseFile) return;
|
|
35079
35689
|
const realBase = normalizeExistingPath(baseFile) || baseFile;
|
|
35080
|
-
const dir = (0,
|
|
35081
|
-
addCandidate((0,
|
|
35082
|
-
addCandidate((0,
|
|
35083
|
-
addCandidate((0,
|
|
35084
|
-
addCandidate((0,
|
|
35085
|
-
addCandidate((0,
|
|
35690
|
+
const dir = (0, import_path6.dirname)(realBase);
|
|
35691
|
+
addCandidate((0, import_path6.resolve)(dir, "../vendor/mcp-server/index.js"));
|
|
35692
|
+
addCandidate((0, import_path6.resolve)(dir, "../../vendor/mcp-server/index.js"));
|
|
35693
|
+
addCandidate((0, import_path6.resolve)(dir, "../../../vendor/mcp-server/index.js"));
|
|
35694
|
+
addCandidate((0, import_path6.resolve)(dir, "../../mcp-server/dist/index.js"));
|
|
35695
|
+
addCandidate((0, import_path6.resolve)(dir, "../../../mcp-server/dist/index.js"));
|
|
35086
35696
|
};
|
|
35087
35697
|
addPackagedCandidates(process.argv[1]);
|
|
35088
35698
|
for (const candidate of candidates) {
|
|
@@ -35090,7 +35700,7 @@ function resolveAdhdevMcpEntryPath(explicitPath) {
|
|
|
35090
35700
|
if (normalized) return normalized;
|
|
35091
35701
|
}
|
|
35092
35702
|
try {
|
|
35093
|
-
const requireBase = process.argv[1] ? normalizeExistingPath(process.argv[1]) || process.argv[1] : (0,
|
|
35703
|
+
const requireBase = process.argv[1] ? normalizeExistingPath(process.argv[1]) || process.argv[1] : (0, import_path6.join)(process.cwd(), "adhdev-daemon.js");
|
|
35094
35704
|
const req = (0, import_module2.createRequire)(requireBase);
|
|
35095
35705
|
const resolvedModule = req.resolve("@adhdev/mcp-server");
|
|
35096
35706
|
return normalizeExistingPath(resolvedModule) || resolvedModule;
|
|
@@ -35100,129 +35710,12 @@ function resolveAdhdevMcpEntryPath(explicitPath) {
|
|
|
35100
35710
|
}
|
|
35101
35711
|
function normalizeExistingPath(filePath) {
|
|
35102
35712
|
try {
|
|
35103
|
-
if (!(0,
|
|
35104
|
-
return
|
|
35713
|
+
if (!(0, import_fs13.existsSync)(filePath)) return null;
|
|
35714
|
+
return import_fs13.realpathSync.native(filePath);
|
|
35105
35715
|
} catch {
|
|
35106
35716
|
return null;
|
|
35107
35717
|
}
|
|
35108
35718
|
}
|
|
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
35719
|
function buildRecentReadDebugSignature(snapshot) {
|
|
35227
35720
|
return [
|
|
35228
35721
|
snapshot.providerType,
|
|
@@ -35920,22 +36413,22 @@ function serializeMeshCoordinatorMcpConfig(config2, format) {
|
|
|
35920
36413
|
}
|
|
35921
36414
|
function resolveHermesUserHome() {
|
|
35922
36415
|
const explicitHome = process.env.HERMES_HOME?.trim();
|
|
35923
|
-
return explicitHome || (0,
|
|
36416
|
+
return explicitHome || (0, import_path7.join)((0, import_os4.homedir)(), ".hermes");
|
|
35924
36417
|
}
|
|
35925
36418
|
function loadHermesCoordinatorBaseConfig(targetConfigPath) {
|
|
35926
36419
|
const sourceHome = resolveHermesUserHome();
|
|
35927
|
-
const sourceConfigPath = (0,
|
|
36420
|
+
const sourceConfigPath = (0, import_path7.join)(sourceHome, "config.yaml");
|
|
35928
36421
|
if (!fs10.existsSync(sourceConfigPath)) return { config: {}, sourceHome, sourceConfigPath };
|
|
35929
|
-
if ((0,
|
|
36422
|
+
if ((0, import_path7.resolve)(sourceConfigPath) === (0, import_path7.resolve)(targetConfigPath)) return { config: {}, sourceHome, sourceConfigPath };
|
|
35930
36423
|
const parsed = parseMeshCoordinatorMcpConfig(fs10.readFileSync(sourceConfigPath, "utf-8"), "hermes_config_yaml");
|
|
35931
36424
|
const { mcp_servers: _mcpServers, ...baseConfig } = parsed;
|
|
35932
36425
|
return { config: baseConfig, sourceHome, sourceConfigPath };
|
|
35933
36426
|
}
|
|
35934
36427
|
function copyHermesCoordinatorCredentialFiles(sourceHome, targetHome) {
|
|
35935
|
-
if ((0,
|
|
36428
|
+
if ((0, import_path7.resolve)(sourceHome) === (0, import_path7.resolve)(targetHome)) return;
|
|
35936
36429
|
for (const fileName of [".env", "auth.json"]) {
|
|
35937
|
-
const sourcePath = (0,
|
|
35938
|
-
const targetPath = (0,
|
|
36430
|
+
const sourcePath = (0, import_path7.join)(sourceHome, fileName);
|
|
36431
|
+
const targetPath = (0, import_path7.join)(targetHome, fileName);
|
|
35939
36432
|
if (!fs10.existsSync(sourcePath)) continue;
|
|
35940
36433
|
try {
|
|
35941
36434
|
fs10.copyFileSync(sourcePath, targetPath);
|
|
@@ -40420,7 +40913,7 @@ async function shutdownDaemonComponents(components) {
|
|
|
40420
40913
|
}
|
|
40421
40914
|
cdpManagers.clear();
|
|
40422
40915
|
}
|
|
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,
|
|
40916
|
+
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
40917
|
var init_dist2 = __esm({
|
|
40425
40918
|
"../daemon-core/dist/index.mjs"() {
|
|
40426
40919
|
"use strict";
|
|
@@ -40436,9 +40929,16 @@ var init_dist2 = __esm({
|
|
|
40436
40929
|
import_fs5 = require("fs");
|
|
40437
40930
|
import_path2 = require("path");
|
|
40438
40931
|
import_crypto3 = require("crypto");
|
|
40932
|
+
import_fs6 = require("fs");
|
|
40933
|
+
import_path3 = require("path");
|
|
40934
|
+
import_crypto4 = require("crypto");
|
|
40935
|
+
import_events2 = require("events");
|
|
40936
|
+
import_fs7 = require("fs");
|
|
40937
|
+
import_path4 = require("path");
|
|
40938
|
+
import_crypto5 = require("crypto");
|
|
40439
40939
|
fs2 = __toESM(require("fs"), 1);
|
|
40440
|
-
|
|
40441
|
-
|
|
40940
|
+
path8 = __toESM(require("path"), 1);
|
|
40941
|
+
os22 = __toESM(require("os"), 1);
|
|
40442
40942
|
init_dist();
|
|
40443
40943
|
os8 = __toESM(require("os"), 1);
|
|
40444
40944
|
os9 = __toESM(require("os"), 1);
|
|
@@ -40449,7 +40949,7 @@ var init_dist2 = __esm({
|
|
|
40449
40949
|
init_dist();
|
|
40450
40950
|
os11 = __toESM(require("os"), 1);
|
|
40451
40951
|
import_child_process3 = require("child_process");
|
|
40452
|
-
|
|
40952
|
+
import_fs8 = require("fs");
|
|
40453
40953
|
import_promises5 = require("fs/promises");
|
|
40454
40954
|
path = __toESM(require("path"), 1);
|
|
40455
40955
|
import_util4 = require("util");
|
|
@@ -40457,40 +40957,40 @@ var init_dist2 = __esm({
|
|
|
40457
40957
|
path22 = __toESM(require("path"), 1);
|
|
40458
40958
|
path32 = __toESM(require("path"), 1);
|
|
40459
40959
|
fs = __toESM(require("fs"), 1);
|
|
40460
|
-
|
|
40960
|
+
os4 = __toESM(require("os"), 1);
|
|
40461
40961
|
path5 = __toESM(require("path"), 1);
|
|
40462
|
-
|
|
40962
|
+
import_crypto6 = require("crypto");
|
|
40463
40963
|
path6 = __toESM(require("path"), 1);
|
|
40464
40964
|
path7 = __toESM(require("path"), 1);
|
|
40465
|
-
|
|
40466
|
-
|
|
40965
|
+
import_fs9 = require("fs");
|
|
40966
|
+
import_path5 = require("path");
|
|
40467
40967
|
import_child_process4 = require("child_process");
|
|
40468
|
-
|
|
40968
|
+
import_fs10 = require("fs");
|
|
40469
40969
|
import_os3 = require("os");
|
|
40470
|
-
path8 = __toESM(require("path"), 1);
|
|
40471
|
-
import_child_process5 = require("child_process");
|
|
40472
|
-
os22 = __toESM(require("os"), 1);
|
|
40473
40970
|
path9 = __toESM(require("path"), 1);
|
|
40474
|
-
|
|
40971
|
+
import_child_process5 = require("child_process");
|
|
40475
40972
|
os32 = __toESM(require("os"), 1);
|
|
40973
|
+
path10 = __toESM(require("path"), 1);
|
|
40974
|
+
import_fs11 = require("fs");
|
|
40975
|
+
os42 = __toESM(require("os"), 1);
|
|
40476
40976
|
import_child_process6 = require("child_process");
|
|
40477
40977
|
init_wrapper();
|
|
40478
40978
|
http = __toESM(require("http"), 1);
|
|
40479
40979
|
crypto2 = __toESM(require("crypto"), 1);
|
|
40480
40980
|
fs3 = __toESM(require("fs"), 1);
|
|
40481
40981
|
path11 = __toESM(require("path"), 1);
|
|
40482
|
-
|
|
40982
|
+
os5 = __toESM(require("os"), 1);
|
|
40483
40983
|
fs4 = __toESM(require("fs"), 1);
|
|
40484
40984
|
os6 = __toESM(require("os"), 1);
|
|
40485
40985
|
path12 = __toESM(require("path"), 1);
|
|
40486
|
-
|
|
40986
|
+
import_crypto7 = require("crypto");
|
|
40487
40987
|
fs5 = __toESM(require("fs"), 1);
|
|
40488
40988
|
path13 = __toESM(require("path"), 1);
|
|
40489
40989
|
os7 = __toESM(require("os"), 1);
|
|
40490
40990
|
os13 = __toESM(require("os"), 1);
|
|
40491
40991
|
path18 = __toESM(require("path"), 1);
|
|
40492
40992
|
crypto4 = __toESM(require("crypto"), 1);
|
|
40493
|
-
|
|
40993
|
+
import_fs12 = require("fs");
|
|
40494
40994
|
import_child_process7 = require("child_process");
|
|
40495
40995
|
init_source();
|
|
40496
40996
|
os12 = __toESM(require("os"), 1);
|
|
@@ -40515,11 +41015,11 @@ var init_dist2 = __esm({
|
|
|
40515
41015
|
os16 = __toESM(require("os"), 1);
|
|
40516
41016
|
init_js_yaml();
|
|
40517
41017
|
import_child_process10 = require("child_process");
|
|
40518
|
-
|
|
40519
|
-
|
|
41018
|
+
import_crypto8 = require("crypto");
|
|
41019
|
+
import_fs13 = require("fs");
|
|
40520
41020
|
import_module2 = require("module");
|
|
40521
41021
|
os17 = __toESM(require("os"), 1);
|
|
40522
|
-
|
|
41022
|
+
import_path6 = require("path");
|
|
40523
41023
|
os18 = __toESM(require("os"), 1);
|
|
40524
41024
|
import_child_process11 = require("child_process");
|
|
40525
41025
|
import_child_process12 = require("child_process");
|
|
@@ -40527,7 +41027,7 @@ var init_dist2 = __esm({
|
|
|
40527
41027
|
os19 = __toESM(require("os"), 1);
|
|
40528
41028
|
path222 = __toESM(require("path"), 1);
|
|
40529
41029
|
import_os4 = require("os");
|
|
40530
|
-
|
|
41030
|
+
import_path7 = require("path");
|
|
40531
41031
|
fs10 = __toESM(require("fs"), 1);
|
|
40532
41032
|
fs11 = __toESM(require("fs"), 1);
|
|
40533
41033
|
path23 = __toESM(require("path"), 1);
|
|
@@ -40584,7 +41084,8 @@ var init_dist2 = __esm({
|
|
|
40584
41084
|
dirtyWorkspaceBehavior: "warn",
|
|
40585
41085
|
maxParallelTasks: 2,
|
|
40586
41086
|
spawnedSessionVisibility: "visible",
|
|
40587
|
-
sessionCleanupOnNodeRemove: "preserve"
|
|
41087
|
+
sessionCleanupOnNodeRemove: "preserve",
|
|
41088
|
+
maxTaskRetries: 1
|
|
40588
41089
|
};
|
|
40589
41090
|
}
|
|
40590
41091
|
});
|
|
@@ -40687,6 +41188,7 @@ var init_dist2 = __esm({
|
|
|
40687
41188
|
| \`mesh_launch_session\` | Start a new agent session on a node |
|
|
40688
41189
|
| \`mesh_send_task\` | Send a task (natural language) to a running agent |
|
|
40689
41190
|
| \`mesh_read_chat\` | Read an agent's recent messages to check progress |
|
|
41191
|
+
| \`mesh_task_history\` | Read the task ledger \u2014 dispatches, completions, failures. Use to understand what has been done before deciding next steps |
|
|
40690
41192
|
| \`mesh_git_status\` | Check git status on a specific node |
|
|
40691
41193
|
| \`mesh_checkpoint\` | Create a git checkpoint on a node |
|
|
40692
41194
|
| \`mesh_approve\` | Approve/reject a pending agent action |
|
|
@@ -40697,18 +41199,57 @@ var init_dist2 = __esm({
|
|
|
40697
41199
|
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
41200
|
WORKFLOW_SECTION = `## Orchestration Workflow
|
|
40699
41201
|
|
|
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
|
|
41202
|
+
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.
|
|
41203
|
+
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.
|
|
41204
|
+
3. **Queue / Delegate** \u2014 The Mesh uses an autonomous pull-based Work Queue:
|
|
41205
|
+
a. **General Tasks**: Enqueue tasks using \`mesh_enqueue_task\`. Idle node agents will automatically pull tasks from the queue and begin working.
|
|
41206
|
+
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.
|
|
41207
|
+
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.
|
|
41208
|
+
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.
|
|
41209
|
+
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
41210
|
5. **Verify** \u2014 When a task reports completion or git work is visible, call \`mesh_git_status\` to verify changes were made.
|
|
40709
41211
|
6. **Checkpoint** \u2014 Call \`mesh_checkpoint\` to save the work.
|
|
40710
41212
|
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
|
|
41213
|
+
8. **Report** \u2014 Summarize what was done, what changed, and any issues.
|
|
41214
|
+
|
|
41215
|
+
## Failure Recovery
|
|
41216
|
+
|
|
41217
|
+
When a node agent stops unexpectedly, the daemon automatically enriches the system message with **Recovery Context** that includes:
|
|
41218
|
+
- The number of consecutive failures on that node
|
|
41219
|
+
- The original task message (if recorded in the ledger)
|
|
41220
|
+
- A recommendation: **retry**, **reassign**, or **escalate**
|
|
41221
|
+
|
|
41222
|
+
Follow these recovery rules:
|
|
41223
|
+
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.
|
|
41224
|
+
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.
|
|
41225
|
+
3. **If no recovery context**: The stop may be intentional (normal completion). Use \`mesh_read_chat\` once to verify, then move on.
|
|
41226
|
+
4. **Always record what happened**: After handling a failure, briefly note the outcome in your report to the user.`;
|
|
41227
|
+
}
|
|
41228
|
+
});
|
|
41229
|
+
mesh_ledger_exports = {};
|
|
41230
|
+
__export2(mesh_ledger_exports, {
|
|
41231
|
+
appendLedgerEntry: () => appendLedgerEntry,
|
|
41232
|
+
appendRemoteLedgerEntries: () => appendRemoteLedgerEntries,
|
|
41233
|
+
getLedgerDir: () => getLedgerDir,
|
|
41234
|
+
getLedgerSummary: () => getLedgerSummary,
|
|
41235
|
+
getSessionRecoveryContext: () => getSessionRecoveryContext,
|
|
41236
|
+
meshLedgerEvents: () => meshLedgerEvents,
|
|
41237
|
+
readLedgerEntries: () => readLedgerEntries
|
|
41238
|
+
});
|
|
41239
|
+
init_mesh_ledger = __esm2({
|
|
41240
|
+
"src/mesh/mesh-ledger.ts"() {
|
|
41241
|
+
"use strict";
|
|
41242
|
+
init_config();
|
|
41243
|
+
LEDGER_DIR_NAME = "mesh-ledger";
|
|
41244
|
+
MAX_FILE_SIZE_BYTES = 10 * 1024 * 1024;
|
|
41245
|
+
RECENT_FAILURE_WINDOW_MS = 30 * 60 * 1e3;
|
|
41246
|
+
meshLedgerEvents = new import_events2.EventEmitter();
|
|
41247
|
+
}
|
|
41248
|
+
});
|
|
41249
|
+
init_mesh_work_queue = __esm2({
|
|
41250
|
+
"src/mesh/mesh-work-queue.ts"() {
|
|
41251
|
+
"use strict";
|
|
41252
|
+
init_mesh_ledger();
|
|
40712
41253
|
}
|
|
40713
41254
|
});
|
|
40714
41255
|
init_logger = __esm2({
|
|
@@ -40717,7 +41258,7 @@ Before doing any coordinator work, confirm that the actual callable tool list in
|
|
|
40717
41258
|
LEVEL_NUM = { debug: 0, info: 1, warn: 2, error: 3 };
|
|
40718
41259
|
LEVEL_LABEL = { debug: "DBG", info: "INF", warn: "WRN", error: "ERR" };
|
|
40719
41260
|
currentLevel = "info";
|
|
40720
|
-
LOG_DIR = process.platform === "win32" ?
|
|
41261
|
+
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
41262
|
MAX_LOG_SIZE = 5 * 1024 * 1024;
|
|
40722
41263
|
MAX_LOG_DAYS = 7;
|
|
40723
41264
|
try {
|
|
@@ -40725,16 +41266,16 @@ Before doing any coordinator work, confirm that the actual callable tool list in
|
|
|
40725
41266
|
} catch {
|
|
40726
41267
|
}
|
|
40727
41268
|
currentDate = getDateStr();
|
|
40728
|
-
currentLogFile =
|
|
41269
|
+
currentLogFile = path8.join(LOG_DIR, `daemon-${currentDate}.log`);
|
|
40729
41270
|
cleanOldLogs();
|
|
40730
41271
|
try {
|
|
40731
|
-
const oldLog =
|
|
41272
|
+
const oldLog = path8.join(LOG_DIR, "daemon.log");
|
|
40732
41273
|
if (fs2.existsSync(oldLog)) {
|
|
40733
41274
|
const stat22 = fs2.statSync(oldLog);
|
|
40734
41275
|
const oldDate = stat22.mtime.toISOString().slice(0, 10);
|
|
40735
|
-
fs2.renameSync(oldLog,
|
|
41276
|
+
fs2.renameSync(oldLog, path8.join(LOG_DIR, `daemon-${oldDate}.log`));
|
|
40736
41277
|
}
|
|
40737
|
-
const oldLogBackup =
|
|
41278
|
+
const oldLogBackup = path8.join(LOG_DIR, "daemon.log.old");
|
|
40738
41279
|
if (fs2.existsSync(oldLogBackup)) {
|
|
40739
41280
|
fs2.unlinkSync(oldLogBackup);
|
|
40740
41281
|
}
|
|
@@ -40766,7 +41307,38 @@ Before doing any coordinator work, confirm that the actual callable tool list in
|
|
|
40766
41307
|
}
|
|
40767
41308
|
};
|
|
40768
41309
|
interceptorInstalled = false;
|
|
40769
|
-
LOG_PATH =
|
|
41310
|
+
LOG_PATH = path8.join(LOG_DIR, `daemon-${getDateStr()}.log`);
|
|
41311
|
+
}
|
|
41312
|
+
});
|
|
41313
|
+
mesh_events_exports = {};
|
|
41314
|
+
__export2(mesh_events_exports, {
|
|
41315
|
+
drainPendingMeshCoordinatorEvents: () => drainPendingMeshCoordinatorEvents,
|
|
41316
|
+
handleMeshForwardEvent: () => handleMeshForwardEvent,
|
|
41317
|
+
setupMeshEventForwarding: () => setupMeshEventForwarding,
|
|
41318
|
+
triggerMeshQueue: () => triggerMeshQueue,
|
|
41319
|
+
tryAssignQueueTask: () => tryAssignQueueTask
|
|
41320
|
+
});
|
|
41321
|
+
init_mesh_events = __esm2({
|
|
41322
|
+
"src/mesh/mesh-events.ts"() {
|
|
41323
|
+
"use strict";
|
|
41324
|
+
init_mesh_config();
|
|
41325
|
+
init_logger();
|
|
41326
|
+
init_mesh_ledger();
|
|
41327
|
+
init_mesh_work_queue();
|
|
41328
|
+
MAX_PENDING_EVENTS = 50;
|
|
41329
|
+
pendingMeshCoordinatorEvents = [];
|
|
41330
|
+
MESH_COORDINATOR_EVENTS = /* @__PURE__ */ new Set([
|
|
41331
|
+
"agent:generating_completed",
|
|
41332
|
+
"agent:waiting_approval",
|
|
41333
|
+
"agent:stopped",
|
|
41334
|
+
"monitor:long_generating"
|
|
41335
|
+
]);
|
|
41336
|
+
EVENT_TO_LEDGER_KIND = {
|
|
41337
|
+
"agent:generating_completed": "task_completed",
|
|
41338
|
+
"agent:waiting_approval": "task_approval_needed",
|
|
41339
|
+
"agent:stopped": "task_failed",
|
|
41340
|
+
"monitor:long_generating": "task_stalled"
|
|
41341
|
+
};
|
|
40770
41342
|
}
|
|
40771
41343
|
});
|
|
40772
41344
|
init_debug_config = __esm2({
|
|
@@ -41293,6 +41865,8 @@ Before doing any coordinator work, confirm that the actual callable tool list in
|
|
|
41293
41865
|
statusHistory = [];
|
|
41294
41866
|
// ─── CLI Scripts (script-based parsing) ───
|
|
41295
41867
|
cliScripts;
|
|
41868
|
+
/** Per-session opaque state object created by cliScripts.createState(), reset on stop. */
|
|
41869
|
+
scriptState = null;
|
|
41296
41870
|
runtimeSettings = {};
|
|
41297
41871
|
/** Full accumulated rendered PTY transcript for parser/readback use */
|
|
41298
41872
|
accumulatedBuffer = "";
|
|
@@ -41474,6 +42048,7 @@ ${lastSnapshot}`;
|
|
|
41474
42048
|
this.cliScripts = scripts;
|
|
41475
42049
|
this.parsedStatusCache = null;
|
|
41476
42050
|
this.parseErrorMessage = null;
|
|
42051
|
+
this.scriptState = typeof scripts.createState === "function" ? scripts.createState() : null;
|
|
41477
42052
|
const scriptNames = listCliScriptNames(scripts);
|
|
41478
42053
|
LOG.info("CLI", `[${this.cliType}] CLI scripts injected: [${scriptNames.join(", ")}]`);
|
|
41479
42054
|
}
|
|
@@ -41591,6 +42166,7 @@ ${lastSnapshot}`;
|
|
|
41591
42166
|
this.ready = false;
|
|
41592
42167
|
this.startupParseGate = false;
|
|
41593
42168
|
this.spawnAt = 0;
|
|
42169
|
+
this.scriptState = null;
|
|
41594
42170
|
this.onStatusChange?.();
|
|
41595
42171
|
});
|
|
41596
42172
|
this.spawnAt = Date.now();
|
|
@@ -42364,7 +42940,7 @@ ${lastSnapshot}`;
|
|
|
42364
42940
|
scope: this.currentTurnScope,
|
|
42365
42941
|
runtimeSettings: this.runtimeSettings
|
|
42366
42942
|
});
|
|
42367
|
-
const session = this.cliScripts.parseSession({ ...input, tail, tailScreen: buildCliScreenSnapshot(tail) });
|
|
42943
|
+
const session = this.cliScripts.parseSession(this.scriptState, { ...input, tail, tailScreen: buildCliScreenSnapshot(tail) });
|
|
42368
42944
|
this.parseErrorMessage = null;
|
|
42369
42945
|
return session && typeof session === "object" ? session : null;
|
|
42370
42946
|
} catch (e) {
|
|
@@ -42378,7 +42954,7 @@ ${lastSnapshot}`;
|
|
|
42378
42954
|
if (!this.cliScripts?.detectStatus) return null;
|
|
42379
42955
|
try {
|
|
42380
42956
|
const screenText = this.terminalScreen.getText();
|
|
42381
|
-
const status = this.cliScripts.detectStatus({
|
|
42957
|
+
const status = this.cliScripts.detectStatus(this.scriptState, {
|
|
42382
42958
|
tail: text.slice(-500),
|
|
42383
42959
|
screenText,
|
|
42384
42960
|
rawBuffer: this.accumulatedRawBuffer,
|
|
@@ -42397,7 +42973,7 @@ ${lastSnapshot}`;
|
|
|
42397
42973
|
try {
|
|
42398
42974
|
const screenText = this.terminalScreen.getText();
|
|
42399
42975
|
const buffer = screenText || this.accumulatedBuffer;
|
|
42400
|
-
return this.cliScripts.parseApproval({
|
|
42976
|
+
return this.cliScripts.parseApproval(this.scriptState, {
|
|
42401
42977
|
buffer,
|
|
42402
42978
|
screenText,
|
|
42403
42979
|
rawBuffer: this.accumulatedRawBuffer,
|
|
@@ -42505,7 +43081,7 @@ ${lastSnapshot}`;
|
|
|
42505
43081
|
scope: this.currentTurnScope,
|
|
42506
43082
|
runtimeSettings: this.runtimeSettings
|
|
42507
43083
|
});
|
|
42508
|
-
return await Promise.resolve(fn({
|
|
43084
|
+
return await Promise.resolve(fn(this.scriptState, {
|
|
42509
43085
|
...input,
|
|
42510
43086
|
args: args && typeof args === "object" ? { ...args } : {}
|
|
42511
43087
|
}));
|
|
@@ -43497,6 +44073,9 @@ ${lastSnapshot}`;
|
|
|
43497
44073
|
init_mesh_config();
|
|
43498
44074
|
init_coordinator_prompt();
|
|
43499
44075
|
init_mesh_config();
|
|
44076
|
+
init_mesh_ledger();
|
|
44077
|
+
init_mesh_work_queue();
|
|
44078
|
+
init_mesh_events();
|
|
43500
44079
|
init_config();
|
|
43501
44080
|
DEFAULT_STATE = {
|
|
43502
44081
|
recentActivity: [],
|
|
@@ -44963,7 +45542,7 @@ ${lastSnapshot}`;
|
|
|
44963
45542
|
HIDDEN_AUDIENCES = /* @__PURE__ */ new Set(["debug", "trace", "internal"]);
|
|
44964
45543
|
ACTIVITY_SOURCE_SET = new Set(CHAT_MESSAGE_ACTIVITY_SOURCES);
|
|
44965
45544
|
INTERNAL_SOURCE_SET = new Set(CHAT_MESSAGE_INTERNAL_SOURCES);
|
|
44966
|
-
HISTORY_DIR = path11.join(
|
|
45545
|
+
HISTORY_DIR = path11.join(os5.homedir(), ".adhdev", "history");
|
|
44967
45546
|
RETAIN_DAYS = 30;
|
|
44968
45547
|
SAVED_HISTORY_INDEX_VERSION = 1;
|
|
44969
45548
|
SAVED_HISTORY_INDEX_FILE = ".saved-history-index.json";
|
|
@@ -46682,6 +47261,7 @@ ${effect.notification.body || ""}`.trim();
|
|
|
46682
47261
|
};
|
|
46683
47262
|
STATUS_MODAL_MESSAGE_LIMIT = 2 * 1024;
|
|
46684
47263
|
STATUS_MODAL_BUTTON_LIMIT = 120;
|
|
47264
|
+
init_mesh_work_queue();
|
|
46685
47265
|
VALID_INPUT_MEDIA_TYPES = /* @__PURE__ */ new Set(["text", "image", "audio", "video", "resource"]);
|
|
46686
47266
|
VALID_INPUT_STRATEGIES = /* @__PURE__ */ new Set(["native", "native_acp", "resource_link", "text_fallback", "paste", "upload"]);
|
|
46687
47267
|
TEXT_ONLY_MESSAGE_INPUT_SUPPORT = Object.freeze({
|
|
@@ -51540,16 +52120,7 @@ Run 'adhdev doctor' for detailed diagnostics.`
|
|
|
51540
52120
|
DEFAULT_ADHDEV_MCP_COMMAND = "adhdev-mcp";
|
|
51541
52121
|
HERMES_CLI_TYPE = "hermes-cli";
|
|
51542
52122
|
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
|
-
]);
|
|
52123
|
+
init_mesh_events();
|
|
51553
52124
|
init_config();
|
|
51554
52125
|
init_terminal_screen();
|
|
51555
52126
|
init_logger();
|
|
@@ -52432,6 +53003,21 @@ Run 'adhdev doctor' for detailed diagnostics.`
|
|
|
52432
53003
|
return { success: false, error: e.message };
|
|
52433
53004
|
}
|
|
52434
53005
|
}
|
|
53006
|
+
case "get_mesh_ledger": {
|
|
53007
|
+
const meshId = typeof args?.meshId === "string" ? args.meshId.trim() : "";
|
|
53008
|
+
if (!meshId) return { success: false, error: "meshId required" };
|
|
53009
|
+
try {
|
|
53010
|
+
const { readLedgerEntries: readLedgerEntries2, getLedgerSummary: getLedgerSummary2 } = await Promise.resolve().then(() => (init_mesh_ledger(), mesh_ledger_exports));
|
|
53011
|
+
const tail = typeof args?.tail === "number" ? args.tail : 20;
|
|
53012
|
+
const since = typeof args?.since === "string" ? args.since : void 0;
|
|
53013
|
+
const kind = Array.isArray(args?.kind) ? args.kind.filter((k) => typeof k === "string") : void 0;
|
|
53014
|
+
const entries = readLedgerEntries2(meshId, { tail, since, kind });
|
|
53015
|
+
const summary = getLedgerSummary2(meshId);
|
|
53016
|
+
return { success: true, entries, summary };
|
|
53017
|
+
} catch (e) {
|
|
53018
|
+
return { success: false, error: e.message };
|
|
53019
|
+
}
|
|
53020
|
+
}
|
|
52435
53021
|
case "add_mesh_node": {
|
|
52436
53022
|
const meshId = typeof args?.meshId === "string" ? args.meshId.trim() : "";
|
|
52437
53023
|
const workspace = typeof args?.workspace === "string" ? args.workspace.trim() : "";
|
|
@@ -52500,6 +53086,54 @@ Run 'adhdev doctor' for detailed diagnostics.`
|
|
|
52500
53086
|
return { success: false, error: e.message };
|
|
52501
53087
|
}
|
|
52502
53088
|
}
|
|
53089
|
+
case "refine_mesh_node": {
|
|
53090
|
+
const meshId = typeof args?.meshId === "string" ? args.meshId.trim() : "";
|
|
53091
|
+
const nodeId = typeof args?.nodeId === "string" ? args.nodeId.trim() : "";
|
|
53092
|
+
if (!meshId || !nodeId) return { success: false, error: "meshId and nodeId required" };
|
|
53093
|
+
try {
|
|
53094
|
+
const meshRecord = await this.getMeshForCommand(meshId, args?.inlineMesh);
|
|
53095
|
+
const mesh = meshRecord?.mesh;
|
|
53096
|
+
const node = mesh?.nodes?.find((n) => n.id === nodeId || n.nodeId === nodeId);
|
|
53097
|
+
if (!node) return { success: false, error: `Node '${nodeId}' not found in mesh` };
|
|
53098
|
+
if (!node.isLocalWorktree || !node.workspace) {
|
|
53099
|
+
return { success: false, error: `Refinery requires a local worktree node` };
|
|
53100
|
+
}
|
|
53101
|
+
const sourceNode = node.clonedFromNodeId ? mesh?.nodes.find((n) => n.id === node.clonedFromNodeId || n.nodeId === node.clonedFromNodeId) : mesh?.nodes.find((n) => !n.isLocalWorktree);
|
|
53102
|
+
const repoRoot = sourceNode?.repoRoot || sourceNode?.workspace;
|
|
53103
|
+
if (!repoRoot) return { success: false, error: "Source node repoRoot not found" };
|
|
53104
|
+
const { execFile: execFile3 } = await import("child_process");
|
|
53105
|
+
const { promisify: promisify3 } = await import("util");
|
|
53106
|
+
const execFileAsync3 = promisify3(execFile3);
|
|
53107
|
+
const { stdout: branchStdout } = await execFileAsync3("git", ["branch", "--show-current"], { cwd: node.workspace, encoding: "utf8" });
|
|
53108
|
+
const branch = branchStdout.trim();
|
|
53109
|
+
if (!branch) return { success: false, error: "Could not determine branch of the worktree node" };
|
|
53110
|
+
const { stdout: baseBranchStdout } = await execFileAsync3("git", ["branch", "--show-current"], { cwd: repoRoot, encoding: "utf8" });
|
|
53111
|
+
const baseBranch = baseBranchStdout.trim();
|
|
53112
|
+
try {
|
|
53113
|
+
await execFileAsync3("git", ["merge", "--no-ff", branch, "-m", `Auto-merge branch '${branch}' via Refinery`], { cwd: repoRoot, encoding: "utf8" });
|
|
53114
|
+
} catch (e) {
|
|
53115
|
+
return { success: false, error: `Merge failed (conflicts?): ${e.message}` };
|
|
53116
|
+
}
|
|
53117
|
+
const removeResult = await this.execute("remove_mesh_node", {
|
|
53118
|
+
meshId,
|
|
53119
|
+
nodeId,
|
|
53120
|
+
sessionCleanupMode: "kill",
|
|
53121
|
+
inlineMesh: args?.inlineMesh
|
|
53122
|
+
});
|
|
53123
|
+
try {
|
|
53124
|
+
const { appendLedgerEntry: appendLedgerEntry2 } = await Promise.resolve().then(() => (init_mesh_ledger(), mesh_ledger_exports));
|
|
53125
|
+
appendLedgerEntry2(meshId, {
|
|
53126
|
+
kind: "node_removed",
|
|
53127
|
+
nodeId,
|
|
53128
|
+
payload: { refined: true, mergedBranch: branch, into: baseBranch }
|
|
53129
|
+
});
|
|
53130
|
+
} catch {
|
|
53131
|
+
}
|
|
53132
|
+
return { success: true, merged: true, branch, into: baseBranch, removeResult };
|
|
53133
|
+
} catch (e) {
|
|
53134
|
+
return { success: false, error: e.message };
|
|
53135
|
+
}
|
|
53136
|
+
}
|
|
52503
53137
|
case "remove_mesh_node": {
|
|
52504
53138
|
const meshId = typeof args?.meshId === "string" ? args.meshId.trim() : "";
|
|
52505
53139
|
const nodeId = typeof args?.nodeId === "string" ? args.nodeId.trim() : "";
|
|
@@ -52535,6 +53169,17 @@ Run 'adhdev doctor' for detailed diagnostics.`
|
|
|
52535
53169
|
const { removeNode: removeNode3 } = await Promise.resolve().then(() => (init_mesh_config(), mesh_config_exports));
|
|
52536
53170
|
removed = removeNode3(meshId, nodeId);
|
|
52537
53171
|
}
|
|
53172
|
+
if (removed) {
|
|
53173
|
+
try {
|
|
53174
|
+
const { appendLedgerEntry: appendLedgerEntry2 } = await Promise.resolve().then(() => (init_mesh_ledger(), mesh_ledger_exports));
|
|
53175
|
+
appendLedgerEntry2(meshId, {
|
|
53176
|
+
kind: "node_removed",
|
|
53177
|
+
nodeId,
|
|
53178
|
+
payload: { worktree: !!node?.isLocalWorktree, sessionCleanupMode }
|
|
53179
|
+
});
|
|
53180
|
+
} catch {
|
|
53181
|
+
}
|
|
53182
|
+
}
|
|
52538
53183
|
return { success: true, removed, ...sessionCleanup ? { sessionCleanup } : {} };
|
|
52539
53184
|
} catch (e) {
|
|
52540
53185
|
return { success: false, error: e.message };
|
|
@@ -52564,9 +53209,9 @@ Run 'adhdev doctor' for detailed diagnostics.`
|
|
|
52564
53209
|
});
|
|
52565
53210
|
let node;
|
|
52566
53211
|
if (meshRecord.inline) {
|
|
52567
|
-
const { randomUUID:
|
|
53212
|
+
const { randomUUID: randomUUID10 } = await import("crypto");
|
|
52568
53213
|
node = {
|
|
52569
|
-
id: `node_${
|
|
53214
|
+
id: `node_${randomUUID10().replace(/-/g, "")}`,
|
|
52570
53215
|
workspace: result.worktreePath,
|
|
52571
53216
|
repoRoot: result.worktreePath,
|
|
52572
53217
|
daemonId: sourceNode.daemonId,
|
|
@@ -52591,6 +53236,15 @@ Run 'adhdev doctor' for detailed diagnostics.`
|
|
|
52591
53236
|
});
|
|
52592
53237
|
if (!node) return { success: false, error: "Failed to register worktree node" };
|
|
52593
53238
|
}
|
|
53239
|
+
try {
|
|
53240
|
+
const { appendLedgerEntry: appendLedgerEntry2 } = await Promise.resolve().then(() => (init_mesh_ledger(), mesh_ledger_exports));
|
|
53241
|
+
appendLedgerEntry2(meshId, {
|
|
53242
|
+
kind: "node_cloned",
|
|
53243
|
+
nodeId: node.id,
|
|
53244
|
+
payload: { sourceNodeId, branch: result.branch, worktreePath: result.worktreePath }
|
|
53245
|
+
});
|
|
53246
|
+
} catch {
|
|
53247
|
+
}
|
|
52594
53248
|
return {
|
|
52595
53249
|
success: true,
|
|
52596
53250
|
node,
|
|
@@ -52601,6 +53255,19 @@ Run 'adhdev doctor' for detailed diagnostics.`
|
|
|
52601
53255
|
return { success: false, error: e.message };
|
|
52602
53256
|
}
|
|
52603
53257
|
}
|
|
53258
|
+
case "trigger_mesh_queue": {
|
|
53259
|
+
const meshId = typeof args?.meshId === "string" ? args.meshId.trim() : "";
|
|
53260
|
+
if (!meshId) return { success: false, error: "meshId required" };
|
|
53261
|
+
try {
|
|
53262
|
+
const { triggerMeshQueue: triggerMeshQueue2 } = await Promise.resolve().then(() => (init_mesh_events(), mesh_events_exports));
|
|
53263
|
+
if (meshId) {
|
|
53264
|
+
triggerMeshQueue2(this.deps, meshId);
|
|
53265
|
+
}
|
|
53266
|
+
return { success: true };
|
|
53267
|
+
} catch (e) {
|
|
53268
|
+
return { success: false, error: e.message };
|
|
53269
|
+
}
|
|
53270
|
+
}
|
|
52604
53271
|
// ─── Mesh Coordinator Launch ───
|
|
52605
53272
|
case "launch_mesh_coordinator": {
|
|
52606
53273
|
const meshId = typeof args?.meshId === "string" ? args.meshId.trim() : "";
|
|
@@ -52705,7 +53372,7 @@ Run 'adhdev doctor' for detailed diagnostics.`
|
|
|
52705
53372
|
workspace
|
|
52706
53373
|
};
|
|
52707
53374
|
}
|
|
52708
|
-
const { existsSync:
|
|
53375
|
+
const { existsSync: existsSync25, readFileSync: readFileSync17, writeFileSync: writeFileSync15, copyFileSync: copyFileSync4, mkdirSync: mkdirSync17 } = await import("fs");
|
|
52709
53376
|
const { dirname: dirname92 } = await import("path");
|
|
52710
53377
|
const mcpConfigPath = coordinatorSetup.configPath;
|
|
52711
53378
|
const hermesManualFallback = cliType === "hermes-cli" && configFormat === "hermes_config_yaml" ? createHermesManualMeshCoordinatorSetup(meshId, workspace) : null;
|
|
@@ -52739,21 +53406,21 @@ Run 'adhdev doctor' for detailed diagnostics.`
|
|
|
52739
53406
|
};
|
|
52740
53407
|
}
|
|
52741
53408
|
try {
|
|
52742
|
-
|
|
53409
|
+
mkdirSync17(dirname92(mcpConfigPath), { recursive: true });
|
|
52743
53410
|
} catch (error48) {
|
|
52744
53411
|
const message = `Could not prepare MCP config path for automatic setup: ${error48?.message || error48}`;
|
|
52745
53412
|
LOG.error("MeshCoordinator", message);
|
|
52746
53413
|
if (hermesManualFallback) return returnManualFallback(message);
|
|
52747
53414
|
return { success: false, code: "mesh_coordinator_config_write_failed", error: message, meshId, cliType, workspace };
|
|
52748
53415
|
}
|
|
52749
|
-
const hadExistingMcpConfig =
|
|
53416
|
+
const hadExistingMcpConfig = existsSync25(mcpConfigPath);
|
|
52750
53417
|
let existingMcpConfig = hermesBaseConfig?.config || {};
|
|
52751
53418
|
if (hermesBaseConfig) {
|
|
52752
53419
|
copyHermesCoordinatorCredentialFiles(hermesBaseConfig.sourceHome, dirname92(mcpConfigPath));
|
|
52753
53420
|
}
|
|
52754
53421
|
if (hadExistingMcpConfig) {
|
|
52755
53422
|
try {
|
|
52756
|
-
const parsedExistingMcpConfig = parseMeshCoordinatorMcpConfig(
|
|
53423
|
+
const parsedExistingMcpConfig = parseMeshCoordinatorMcpConfig(readFileSync17(mcpConfigPath, "utf-8"), configFormat);
|
|
52757
53424
|
existingMcpConfig = { ...existingMcpConfig, ...parsedExistingMcpConfig };
|
|
52758
53425
|
copyFileSync4(mcpConfigPath, mcpConfigPath + ".backup");
|
|
52759
53426
|
} catch (error48) {
|
|
@@ -52775,7 +53442,7 @@ Run 'adhdev doctor' for detailed diagnostics.`
|
|
|
52775
53442
|
}
|
|
52776
53443
|
};
|
|
52777
53444
|
try {
|
|
52778
|
-
|
|
53445
|
+
writeFileSync15(mcpConfigPath, serializeMeshCoordinatorMcpConfig(mcpConfig, configFormat), "utf-8");
|
|
52779
53446
|
} catch (error48) {
|
|
52780
53447
|
const message = `Could not write MCP config for automatic setup: ${error48?.message || error48}`;
|
|
52781
53448
|
LOG.error("MeshCoordinator", message);
|
|
@@ -52812,6 +53479,16 @@ Run 'adhdev doctor' for detailed diagnostics.`
|
|
|
52812
53479
|
return { success: false, error: launchResult?.error || "Failed to launch CLI session" };
|
|
52813
53480
|
}
|
|
52814
53481
|
LOG.info("MeshCoordinator", `Launched ${cliType} coordinator for mesh ${meshId} in ${workspace}`);
|
|
53482
|
+
try {
|
|
53483
|
+
const { appendLedgerEntry: appendLedgerEntry2 } = await Promise.resolve().then(() => (init_mesh_ledger(), mesh_ledger_exports));
|
|
53484
|
+
appendLedgerEntry2(meshId, {
|
|
53485
|
+
kind: "coordinator_started",
|
|
53486
|
+
sessionId: launchResult.sessionId || launchResult.id,
|
|
53487
|
+
providerType: cliType,
|
|
53488
|
+
payload: { workspace }
|
|
53489
|
+
});
|
|
53490
|
+
} catch {
|
|
53491
|
+
}
|
|
52815
53492
|
return {
|
|
52816
53493
|
success: true,
|
|
52817
53494
|
meshId,
|
|
@@ -56359,6 +57036,7 @@ data: ${JSON.stringify(msg.data)}
|
|
|
56359
57036
|
};
|
|
56360
57037
|
init_logger();
|
|
56361
57038
|
init_config();
|
|
57039
|
+
init_mesh_events();
|
|
56362
57040
|
}
|
|
56363
57041
|
});
|
|
56364
57042
|
|
|
@@ -56564,6 +57242,7 @@ function annotateRapidReadChatAdvisory(payload, options) {
|
|
|
56564
57242
|
}
|
|
56565
57243
|
|
|
56566
57244
|
// src/tools/mesh-tools.ts
|
|
57245
|
+
init_dist2();
|
|
56567
57246
|
var meshSessionProviderMetadata = /* @__PURE__ */ new Map();
|
|
56568
57247
|
async function refreshMeshFromDaemon(ctx) {
|
|
56569
57248
|
if (!(ctx.transport instanceof IpcTransport)) return;
|
|
@@ -56744,9 +57423,34 @@ var MESH_LIST_NODES_TOOL = {
|
|
|
56744
57423
|
properties: {}
|
|
56745
57424
|
}
|
|
56746
57425
|
};
|
|
57426
|
+
var MESH_ENQUEUE_TASK_TOOL = {
|
|
57427
|
+
name: "mesh_enqueue_task",
|
|
57428
|
+
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.",
|
|
57429
|
+
inputSchema: {
|
|
57430
|
+
type: "object",
|
|
57431
|
+
properties: {
|
|
57432
|
+
message: { type: "string", description: "The task instruction for the agent." }
|
|
57433
|
+
},
|
|
57434
|
+
required: ["message"]
|
|
57435
|
+
}
|
|
57436
|
+
};
|
|
57437
|
+
var MESH_VIEW_QUEUE_TOOL = {
|
|
57438
|
+
name: "mesh_view_queue",
|
|
57439
|
+
description: "View the current status of the mesh work queue (pending, assigned, completed, failed tasks).",
|
|
57440
|
+
inputSchema: {
|
|
57441
|
+
type: "object",
|
|
57442
|
+
properties: {
|
|
57443
|
+
status: {
|
|
57444
|
+
type: "array",
|
|
57445
|
+
items: { type: "string" },
|
|
57446
|
+
description: "Filter by task status: pending, assigned, completed, failed. Returns all if omitted."
|
|
57447
|
+
}
|
|
57448
|
+
}
|
|
57449
|
+
}
|
|
57450
|
+
};
|
|
56747
57451
|
var MESH_SEND_TASK_TOOL = {
|
|
56748
57452
|
name: "mesh_send_task",
|
|
56749
|
-
description: "
|
|
57453
|
+
description: "Legacy push-based task assignment. Enqueues a task specifically targeted at a given node. The node will pull it immediately if idle.",
|
|
56750
57454
|
inputSchema: {
|
|
56751
57455
|
type: "object",
|
|
56752
57456
|
properties: {
|
|
@@ -56886,9 +57590,33 @@ var MESH_CLEANUP_SESSIONS_TOOL = {
|
|
|
56886
57590
|
required: ["node_id", "mode"]
|
|
56887
57591
|
}
|
|
56888
57592
|
};
|
|
57593
|
+
var MESH_TASK_HISTORY_TOOL = {
|
|
57594
|
+
name: "mesh_task_history",
|
|
57595
|
+
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.",
|
|
57596
|
+
inputSchema: {
|
|
57597
|
+
type: "object",
|
|
57598
|
+
properties: {
|
|
57599
|
+
tail: { type: "number", description: "Number of recent entries to return (default: 20)." },
|
|
57600
|
+
kind: { type: "string", description: "Filter by entry kind: task_dispatched, task_completed, task_failed, task_stalled, session_launched, checkpoint_created, node_cloned, node_removed." }
|
|
57601
|
+
}
|
|
57602
|
+
}
|
|
57603
|
+
};
|
|
57604
|
+
var MESH_REFINE_NODE_TOOL = {
|
|
57605
|
+
name: "mesh_refine_node",
|
|
57606
|
+
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.",
|
|
57607
|
+
inputSchema: {
|
|
57608
|
+
type: "object",
|
|
57609
|
+
properties: {
|
|
57610
|
+
node_id: { type: "string", description: "Node ID of the completed worktree node to refine and merge." }
|
|
57611
|
+
},
|
|
57612
|
+
required: ["node_id"]
|
|
57613
|
+
}
|
|
57614
|
+
};
|
|
56889
57615
|
var ALL_MESH_TOOLS = [
|
|
56890
57616
|
MESH_STATUS_TOOL,
|
|
56891
57617
|
MESH_LIST_NODES_TOOL,
|
|
57618
|
+
MESH_ENQUEUE_TASK_TOOL,
|
|
57619
|
+
MESH_VIEW_QUEUE_TOOL,
|
|
56892
57620
|
MESH_SEND_TASK_TOOL,
|
|
56893
57621
|
MESH_READ_CHAT_TOOL,
|
|
56894
57622
|
MESH_READ_DEBUG_TOOL,
|
|
@@ -56898,7 +57626,9 @@ var ALL_MESH_TOOLS = [
|
|
|
56898
57626
|
MESH_APPROVE_TOOL,
|
|
56899
57627
|
MESH_CLONE_NODE_TOOL,
|
|
56900
57628
|
MESH_REMOVE_NODE_TOOL,
|
|
56901
|
-
|
|
57629
|
+
MESH_REFINE_NODE_TOOL,
|
|
57630
|
+
MESH_CLEANUP_SESSIONS_TOOL,
|
|
57631
|
+
MESH_TASK_HISTORY_TOOL
|
|
56902
57632
|
];
|
|
56903
57633
|
async function meshStatus(ctx) {
|
|
56904
57634
|
await refreshMeshFromDaemon(ctx);
|
|
@@ -56949,6 +57679,10 @@ async function meshStatus(ctx) {
|
|
|
56949
57679
|
refreshedAt: (/* @__PURE__ */ new Date()).toISOString(),
|
|
56950
57680
|
nodes: results
|
|
56951
57681
|
};
|
|
57682
|
+
try {
|
|
57683
|
+
response.ledgerSummary = getLedgerSummary(mesh.id);
|
|
57684
|
+
} catch {
|
|
57685
|
+
}
|
|
56952
57686
|
if (ctx.transport instanceof IpcTransport) {
|
|
56953
57687
|
try {
|
|
56954
57688
|
const eventsResult = await ctx.transport.command("get_pending_mesh_events", {});
|
|
@@ -56961,6 +57695,14 @@ async function meshStatus(ctx) {
|
|
|
56961
57695
|
}
|
|
56962
57696
|
return JSON.stringify(response, null, 2);
|
|
56963
57697
|
}
|
|
57698
|
+
async function meshTaskHistory(ctx, args) {
|
|
57699
|
+
const { mesh } = ctx;
|
|
57700
|
+
const tail = typeof args.tail === "number" && args.tail > 0 ? args.tail : 20;
|
|
57701
|
+
const kind = typeof args.kind === "string" && args.kind.trim() ? [args.kind.trim()] : void 0;
|
|
57702
|
+
const entries = readLedgerEntries(mesh.id, { tail, kind });
|
|
57703
|
+
const summary = getLedgerSummary(mesh.id);
|
|
57704
|
+
return JSON.stringify({ meshId: mesh.id, entries, summary }, null, 2);
|
|
57705
|
+
}
|
|
56964
57706
|
async function meshListNodes(ctx) {
|
|
56965
57707
|
await refreshMeshFromDaemon(ctx);
|
|
56966
57708
|
const { mesh } = ctx;
|
|
@@ -56979,29 +57721,54 @@ async function meshListNodes(ctx) {
|
|
|
56979
57721
|
}))
|
|
56980
57722
|
}, null, 2);
|
|
56981
57723
|
}
|
|
57724
|
+
async function meshEnqueueTask(ctx, args) {
|
|
57725
|
+
try {
|
|
57726
|
+
const task = enqueueTask(ctx.mesh.id, args.message);
|
|
57727
|
+
if (ctx.transport instanceof IpcTransport && ctx.localDaemonId) {
|
|
57728
|
+
ctx.transport.meshCommand(ctx.localDaemonId, "trigger_mesh_queue", { meshId: ctx.mesh.id }).catch(() => {
|
|
57729
|
+
});
|
|
57730
|
+
} else if (isLocalTransport(ctx.transport)) {
|
|
57731
|
+
ctx.transport.command("trigger_mesh_queue", { meshId: ctx.mesh.id }).catch(() => {
|
|
57732
|
+
});
|
|
57733
|
+
}
|
|
57734
|
+
return JSON.stringify({ success: true, taskId: task.id, status: task.status });
|
|
57735
|
+
} catch (e) {
|
|
57736
|
+
return JSON.stringify({ success: false, error: e.message });
|
|
57737
|
+
}
|
|
57738
|
+
}
|
|
57739
|
+
async function meshViewQueue(ctx, args) {
|
|
57740
|
+
try {
|
|
57741
|
+
const queue = getQueue(ctx.mesh.id, { status: args.status });
|
|
57742
|
+
return JSON.stringify({ success: true, queue }, null, 2);
|
|
57743
|
+
} catch (e) {
|
|
57744
|
+
return JSON.stringify({ success: false, error: e.message });
|
|
57745
|
+
}
|
|
57746
|
+
}
|
|
56982
57747
|
async function meshSendTask(ctx, args) {
|
|
56983
57748
|
const node = await findNodeWithRefresh(ctx, args.node_id);
|
|
56984
57749
|
if (node.policy?.readOnly) {
|
|
56985
57750
|
return JSON.stringify({ error: `Node '${args.node_id}' is read-only` });
|
|
56986
57751
|
}
|
|
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"
|
|
57752
|
+
try {
|
|
57753
|
+
if (!isLocalTransport(ctx.transport) && node.daemonId) {
|
|
57754
|
+
const res = await ctx.transport.meshEnqueueTask(node.daemonId, {
|
|
57755
|
+
meshId: ctx.mesh.id,
|
|
57756
|
+
message: args.message,
|
|
57757
|
+
targetNodeId: args.node_id
|
|
57000
57758
|
});
|
|
57759
|
+
return JSON.stringify(res);
|
|
57001
57760
|
}
|
|
57002
|
-
|
|
57003
|
-
|
|
57004
|
-
|
|
57761
|
+
const task = enqueueTask(ctx.mesh.id, args.message, { targetNodeId: args.node_id });
|
|
57762
|
+
if (ctx.transport instanceof IpcTransport && node.daemonId && node.daemonId !== ctx.localDaemonId) {
|
|
57763
|
+
ctx.transport.meshCommand(node.daemonId, "trigger_mesh_queue", { meshId: ctx.mesh.id }).catch(() => {
|
|
57764
|
+
});
|
|
57765
|
+
} else if (isLocalTransport(ctx.transport)) {
|
|
57766
|
+
ctx.transport.command("trigger_mesh_queue", { meshId: ctx.mesh.id }).catch(() => {
|
|
57767
|
+
});
|
|
57768
|
+
}
|
|
57769
|
+
return JSON.stringify({ success: true, nodeId: args.node_id, taskId: task.id, status: task.status });
|
|
57770
|
+
} catch (e) {
|
|
57771
|
+
return JSON.stringify({ success: false, error: e.message });
|
|
57005
57772
|
}
|
|
57006
57773
|
}
|
|
57007
57774
|
async function meshReadChat(ctx, args) {
|
|
@@ -57035,8 +57802,19 @@ async function meshReadChat(ctx, args) {
|
|
|
57035
57802
|
);
|
|
57036
57803
|
}
|
|
57037
57804
|
return JSON.stringify(payload, null, 2);
|
|
57805
|
+
} else if (!isLocalTransport(ctx.transport) && node.daemonId) {
|
|
57806
|
+
try {
|
|
57807
|
+
const targetId = `${node.daemonId}:session:${args.session_id}`;
|
|
57808
|
+
const res = await ctx.transport.readChat(targetId, {
|
|
57809
|
+
limit: args.tail ?? 10,
|
|
57810
|
+
sessionId: args.session_id
|
|
57811
|
+
});
|
|
57812
|
+
return JSON.stringify(res, null, 2);
|
|
57813
|
+
} catch (e) {
|
|
57814
|
+
return JSON.stringify({ success: false, error: e.message });
|
|
57815
|
+
}
|
|
57038
57816
|
} else {
|
|
57039
|
-
return JSON.stringify({ error: "Cloud mesh read_chat
|
|
57817
|
+
return JSON.stringify({ error: "Cloud mesh read_chat requires node daemonId" });
|
|
57040
57818
|
}
|
|
57041
57819
|
}
|
|
57042
57820
|
async function meshReadDebug(ctx, args) {
|
|
@@ -57056,8 +57834,20 @@ async function meshReadDebug(ctx, args) {
|
|
|
57056
57834
|
});
|
|
57057
57835
|
const payload = unwrapCommandPayload(result);
|
|
57058
57836
|
return JSON.stringify(payload, null, 2);
|
|
57837
|
+
} else if (!isLocalTransport(ctx.transport) && node.daemonId) {
|
|
57838
|
+
try {
|
|
57839
|
+
const targetId = `${node.daemonId}:session:${args.session_id}`;
|
|
57840
|
+
const res = await ctx.transport.getChatDebugBundle(targetId, {
|
|
57841
|
+
sessionId: args.session_id,
|
|
57842
|
+
tailLimit: args.tail ?? 40,
|
|
57843
|
+
delivery: args.delivery
|
|
57844
|
+
});
|
|
57845
|
+
return JSON.stringify(res, null, 2);
|
|
57846
|
+
} catch (e) {
|
|
57847
|
+
return JSON.stringify({ success: false, error: e.message });
|
|
57848
|
+
}
|
|
57059
57849
|
}
|
|
57060
|
-
return JSON.stringify({ error: "Cloud mesh read_debug
|
|
57850
|
+
return JSON.stringify({ error: "Cloud mesh read_debug requires node daemonId" });
|
|
57061
57851
|
}
|
|
57062
57852
|
async function meshLaunchSession(ctx, args) {
|
|
57063
57853
|
const node = await findNodeWithRefresh(ctx, args.node_id);
|
|
@@ -57106,13 +57896,70 @@ async function meshLaunchSession(ctx, args) {
|
|
|
57106
57896
|
...providerSessionId ? { providerSessionId } : {}
|
|
57107
57897
|
});
|
|
57108
57898
|
}
|
|
57899
|
+
try {
|
|
57900
|
+
appendLedgerEntry(ctx.mesh.id, {
|
|
57901
|
+
kind: "session_launched",
|
|
57902
|
+
nodeId: args.node_id,
|
|
57903
|
+
sessionId: runtimeSessionId || void 0,
|
|
57904
|
+
providerType: resolvedProviderType,
|
|
57905
|
+
payload: { providerSessionId }
|
|
57906
|
+
});
|
|
57907
|
+
} catch {
|
|
57908
|
+
}
|
|
57909
|
+
if (ctx.transport instanceof IpcTransport && node.daemonId && node.daemonId !== ctx.localDaemonId) {
|
|
57910
|
+
ctx.transport.meshCommand(node.daemonId, "trigger_mesh_queue", { meshId: ctx.mesh.id }).catch(() => {
|
|
57911
|
+
});
|
|
57912
|
+
} else if (isLocalTransport(ctx.transport)) {
|
|
57913
|
+
ctx.transport.command("trigger_mesh_queue", { meshId: ctx.mesh.id }).catch(() => {
|
|
57914
|
+
});
|
|
57915
|
+
}
|
|
57109
57916
|
return JSON.stringify({
|
|
57110
57917
|
...launchPayload,
|
|
57111
57918
|
resolvedProviderType,
|
|
57112
57919
|
...providerSessionId ? { providerSessionId } : {}
|
|
57113
57920
|
}, null, 2);
|
|
57921
|
+
} else if (!isLocalTransport(ctx.transport) && node.daemonId) {
|
|
57922
|
+
let resolvedProviderType = typeof args.type === "string" && args.type.trim() ? args.type : "";
|
|
57923
|
+
if (!resolvedProviderType) {
|
|
57924
|
+
const providerPriority = readProviderPriority(node.policy);
|
|
57925
|
+
if (!providerPriority.length) {
|
|
57926
|
+
return JSON.stringify({ success: false, error: missingProviderPriorityMessage(args.node_id) });
|
|
57927
|
+
}
|
|
57928
|
+
resolvedProviderType = providerPriority[0];
|
|
57929
|
+
}
|
|
57930
|
+
const coordinatorNode = resolveCoordinatorNode(ctx);
|
|
57931
|
+
const coordinatorDaemonId = coordinatorNode?.daemonId || ctx.localDaemonId;
|
|
57932
|
+
const spawnedSessionVisibility = readSpawnedSessionVisibility(ctx.mesh.policy);
|
|
57933
|
+
try {
|
|
57934
|
+
const res = await ctx.transport.launch(node.daemonId, {
|
|
57935
|
+
type: resolvedProviderType,
|
|
57936
|
+
dir: node.workspace,
|
|
57937
|
+
settings: {
|
|
57938
|
+
meshNodeFor: ctx.mesh.id,
|
|
57939
|
+
meshNodeId: args.node_id,
|
|
57940
|
+
spawnedSessionVisibility,
|
|
57941
|
+
...coordinatorDaemonId ? { meshCoordinatorDaemonId: coordinatorDaemonId } : {},
|
|
57942
|
+
...coordinatorNode?.id ? { meshCoordinatorNodeId: coordinatorNode.id } : {},
|
|
57943
|
+
launchedByCoordinator: true
|
|
57944
|
+
}
|
|
57945
|
+
});
|
|
57946
|
+
const runtimeSessionId = typeof res?.sessionId === "string" ? res.sessionId : typeof res?.id === "string" ? res.id : "";
|
|
57947
|
+
try {
|
|
57948
|
+
appendLedgerEntry(ctx.mesh.id, {
|
|
57949
|
+
kind: "session_launched",
|
|
57950
|
+
nodeId: args.node_id,
|
|
57951
|
+
sessionId: runtimeSessionId || void 0,
|
|
57952
|
+
providerType: resolvedProviderType,
|
|
57953
|
+
payload: {}
|
|
57954
|
+
});
|
|
57955
|
+
} catch {
|
|
57956
|
+
}
|
|
57957
|
+
return JSON.stringify({ ...res, resolvedProviderType }, null, 2);
|
|
57958
|
+
} catch (e) {
|
|
57959
|
+
return JSON.stringify({ success: false, error: e.message });
|
|
57960
|
+
}
|
|
57114
57961
|
} else {
|
|
57115
|
-
return JSON.stringify({ error: "Cloud mesh launch_session
|
|
57962
|
+
return JSON.stringify({ error: "Cloud mesh launch_session requires node daemonId" });
|
|
57116
57963
|
}
|
|
57117
57964
|
}
|
|
57118
57965
|
async function meshGitStatus(ctx, args) {
|
|
@@ -57155,9 +58002,36 @@ async function meshCheckpoint(ctx, args) {
|
|
|
57155
58002
|
message: args.message,
|
|
57156
58003
|
includeUntracked: true
|
|
57157
58004
|
});
|
|
58005
|
+
try {
|
|
58006
|
+
appendLedgerEntry(ctx.mesh.id, {
|
|
58007
|
+
kind: "checkpoint_created",
|
|
58008
|
+
nodeId: args.node_id,
|
|
58009
|
+
payload: { message: args.message, commit: result?.checkpoint?.commit }
|
|
58010
|
+
});
|
|
58011
|
+
} catch {
|
|
58012
|
+
}
|
|
57158
58013
|
return JSON.stringify(result, null, 2);
|
|
58014
|
+
} else if (!isLocalTransport(ctx.transport) && node.daemonId) {
|
|
58015
|
+
try {
|
|
58016
|
+
const res = await ctx.transport.gitCheckpoint(node.daemonId, {
|
|
58017
|
+
workspace: node.workspace,
|
|
58018
|
+
message: args.message,
|
|
58019
|
+
includeUntracked: true
|
|
58020
|
+
});
|
|
58021
|
+
try {
|
|
58022
|
+
appendLedgerEntry(ctx.mesh.id, {
|
|
58023
|
+
kind: "checkpoint_created",
|
|
58024
|
+
nodeId: args.node_id,
|
|
58025
|
+
payload: { message: args.message, commit: res?.checkpoint?.commit }
|
|
58026
|
+
});
|
|
58027
|
+
} catch {
|
|
58028
|
+
}
|
|
58029
|
+
return JSON.stringify(res, null, 2);
|
|
58030
|
+
} catch (e) {
|
|
58031
|
+
return JSON.stringify({ success: false, error: e.message });
|
|
58032
|
+
}
|
|
57159
58033
|
} else {
|
|
57160
|
-
return JSON.stringify({ error: "Cloud mesh checkpoint
|
|
58034
|
+
return JSON.stringify({ error: "Cloud mesh checkpoint requires node daemonId" });
|
|
57161
58035
|
}
|
|
57162
58036
|
}
|
|
57163
58037
|
async function meshApprove(ctx, args) {
|
|
@@ -57174,8 +58048,16 @@ async function meshApprove(ctx, args) {
|
|
|
57174
58048
|
action: args.action === "reject" ? "reject" : "approve"
|
|
57175
58049
|
});
|
|
57176
58050
|
return JSON.stringify(result, null, 2);
|
|
58051
|
+
} else if (!isLocalTransport(ctx.transport) && node.daemonId) {
|
|
58052
|
+
try {
|
|
58053
|
+
const targetId = `${node.daemonId}:session:${args.session_id}`;
|
|
58054
|
+
const res = await ctx.transport.approve(targetId, args.action === "reject" ? "reject" : "approve");
|
|
58055
|
+
return JSON.stringify(res, null, 2);
|
|
58056
|
+
} catch (e) {
|
|
58057
|
+
return JSON.stringify({ success: false, error: e.message });
|
|
58058
|
+
}
|
|
57177
58059
|
} else {
|
|
57178
|
-
return JSON.stringify({ error: "Cloud mesh approve
|
|
58060
|
+
return JSON.stringify({ error: "Cloud mesh approve requires node daemonId" });
|
|
57179
58061
|
}
|
|
57180
58062
|
}
|
|
57181
58063
|
async function meshCloneNode(ctx, args) {
|
|
@@ -57196,8 +58078,28 @@ async function meshCloneNode(ctx, args) {
|
|
|
57196
58078
|
ctx.mesh.updatedAt = (/* @__PURE__ */ new Date()).toISOString();
|
|
57197
58079
|
}
|
|
57198
58080
|
return JSON.stringify(result, null, 2);
|
|
58081
|
+
} else if (!isLocalTransport(ctx.transport) && sourceNode.daemonId) {
|
|
58082
|
+
try {
|
|
58083
|
+
const res = await ctx.transport.meshCloneNode(sourceNode.daemonId, {
|
|
58084
|
+
meshId: ctx.mesh.id,
|
|
58085
|
+
sourceNodeId: args.source_node_id,
|
|
58086
|
+
branch: args.branch,
|
|
58087
|
+
baseBranch: args.base_branch,
|
|
58088
|
+
inlineMesh: ctx.mesh
|
|
58089
|
+
});
|
|
58090
|
+
const clonePayload = extractCloneNodePayload(res);
|
|
58091
|
+
if (clonePayload?.success && clonePayload.node?.id) {
|
|
58092
|
+
const existingIndex = ctx.mesh.nodes.findIndex((n) => n.id === clonePayload.node.id);
|
|
58093
|
+
if (existingIndex >= 0) ctx.mesh.nodes[existingIndex] = clonePayload.node;
|
|
58094
|
+
else ctx.mesh.nodes.push(clonePayload.node);
|
|
58095
|
+
ctx.mesh.updatedAt = (/* @__PURE__ */ new Date()).toISOString();
|
|
58096
|
+
}
|
|
58097
|
+
return JSON.stringify(res, null, 2);
|
|
58098
|
+
} catch (e) {
|
|
58099
|
+
return JSON.stringify({ success: false, error: e.message });
|
|
58100
|
+
}
|
|
57199
58101
|
} else {
|
|
57200
|
-
return JSON.stringify({ error: "Cloud mesh clone_node
|
|
58102
|
+
return JSON.stringify({ error: "Cloud mesh clone_node requires source node daemonId" });
|
|
57201
58103
|
}
|
|
57202
58104
|
}
|
|
57203
58105
|
async function meshCleanupSessions(ctx, args) {
|
|
@@ -57212,8 +58114,22 @@ async function meshCleanupSessions(ctx, args) {
|
|
|
57212
58114
|
inlineMesh: ctx.mesh
|
|
57213
58115
|
});
|
|
57214
58116
|
return JSON.stringify(result, null, 2);
|
|
58117
|
+
} else if (!isLocalTransport(ctx.transport) && node.daemonId) {
|
|
58118
|
+
try {
|
|
58119
|
+
const res = await ctx.transport.meshCleanupSessions(node.daemonId, {
|
|
58120
|
+
meshId: ctx.mesh.id,
|
|
58121
|
+
nodeId: args.node_id,
|
|
58122
|
+
mode: args.mode,
|
|
58123
|
+
sessionIds: args.session_ids,
|
|
58124
|
+
dryRun: args.dry_run === true,
|
|
58125
|
+
inlineMesh: ctx.mesh
|
|
58126
|
+
});
|
|
58127
|
+
return JSON.stringify(res, null, 2);
|
|
58128
|
+
} catch (e) {
|
|
58129
|
+
return JSON.stringify({ success: false, error: e.message });
|
|
58130
|
+
}
|
|
57215
58131
|
} else {
|
|
57216
|
-
return JSON.stringify({ error: "Cloud mesh cleanup_sessions
|
|
58132
|
+
return JSON.stringify({ error: "Cloud mesh cleanup_sessions requires node daemonId" });
|
|
57217
58133
|
}
|
|
57218
58134
|
}
|
|
57219
58135
|
async function meshRemoveNode(ctx, args) {
|
|
@@ -57233,8 +58149,65 @@ async function meshRemoveNode(ctx, args) {
|
|
|
57233
58149
|
}
|
|
57234
58150
|
}
|
|
57235
58151
|
return JSON.stringify(result, null, 2);
|
|
58152
|
+
} else if (!isLocalTransport(ctx.transport) && node.daemonId) {
|
|
58153
|
+
try {
|
|
58154
|
+
const res = await ctx.transport.meshRemoveNode(node.daemonId, {
|
|
58155
|
+
meshId: ctx.mesh.id,
|
|
58156
|
+
nodeId: args.node_id,
|
|
58157
|
+
...args.session_cleanup_mode ? { sessionCleanupMode: args.session_cleanup_mode } : {},
|
|
58158
|
+
inlineMesh: ctx.mesh
|
|
58159
|
+
});
|
|
58160
|
+
if (res?.success && res.removed !== false) {
|
|
58161
|
+
const idx = ctx.mesh.nodes.findIndex((n) => n.id === args.node_id);
|
|
58162
|
+
if (idx >= 0) {
|
|
58163
|
+
ctx.mesh.nodes.splice(idx, 1);
|
|
58164
|
+
ctx.mesh.updatedAt = (/* @__PURE__ */ new Date()).toISOString();
|
|
58165
|
+
}
|
|
58166
|
+
}
|
|
58167
|
+
return JSON.stringify(res, null, 2);
|
|
58168
|
+
} catch (e) {
|
|
58169
|
+
return JSON.stringify({ success: false, error: e.message });
|
|
58170
|
+
}
|
|
57236
58171
|
} else {
|
|
57237
|
-
return JSON.stringify({ error: "Cloud mesh remove_node
|
|
58172
|
+
return JSON.stringify({ error: "Cloud mesh remove_node requires node daemonId" });
|
|
58173
|
+
}
|
|
58174
|
+
}
|
|
58175
|
+
async function meshRefineNode(ctx, args) {
|
|
58176
|
+
const node = await findNodeWithRefresh(ctx, args.node_id);
|
|
58177
|
+
if (isLocalTransport(ctx.transport)) {
|
|
58178
|
+
const result = await commandForNode(ctx, node, "refine_mesh_node", {
|
|
58179
|
+
meshId: ctx.mesh.id,
|
|
58180
|
+
nodeId: args.node_id,
|
|
58181
|
+
inlineMesh: ctx.mesh
|
|
58182
|
+
});
|
|
58183
|
+
if (result?.success && result.removeResult?.removed !== false) {
|
|
58184
|
+
const idx = ctx.mesh.nodes.findIndex((n) => n.id === args.node_id);
|
|
58185
|
+
if (idx >= 0) {
|
|
58186
|
+
ctx.mesh.nodes.splice(idx, 1);
|
|
58187
|
+
ctx.mesh.updatedAt = (/* @__PURE__ */ new Date()).toISOString();
|
|
58188
|
+
}
|
|
58189
|
+
}
|
|
58190
|
+
return JSON.stringify(result, null, 2);
|
|
58191
|
+
} else if (!isLocalTransport(ctx.transport) && node.daemonId) {
|
|
58192
|
+
try {
|
|
58193
|
+
const res = await ctx.transport.meshRefineNode(node.daemonId, {
|
|
58194
|
+
meshId: ctx.mesh.id,
|
|
58195
|
+
nodeId: args.node_id,
|
|
58196
|
+
inlineMesh: ctx.mesh
|
|
58197
|
+
});
|
|
58198
|
+
if (res?.success && res.removeResult?.removed !== false) {
|
|
58199
|
+
const idx = ctx.mesh.nodes.findIndex((n) => n.id === args.node_id);
|
|
58200
|
+
if (idx >= 0) {
|
|
58201
|
+
ctx.mesh.nodes.splice(idx, 1);
|
|
58202
|
+
ctx.mesh.updatedAt = (/* @__PURE__ */ new Date()).toISOString();
|
|
58203
|
+
}
|
|
58204
|
+
}
|
|
58205
|
+
return JSON.stringify(res, null, 2);
|
|
58206
|
+
} catch (e) {
|
|
58207
|
+
return JSON.stringify({ success: false, error: e.message });
|
|
58208
|
+
}
|
|
58209
|
+
} else {
|
|
58210
|
+
return JSON.stringify({ error: "Cloud mesh refine_node requires node daemonId" });
|
|
57238
58211
|
}
|
|
57239
58212
|
}
|
|
57240
58213
|
|
|
@@ -57348,6 +58321,36 @@ var CloudTransport = class {
|
|
|
57348
58321
|
"Authorization": `Bearer ${this.apiKey}`
|
|
57349
58322
|
};
|
|
57350
58323
|
}
|
|
58324
|
+
async listRemoteMeshes() {
|
|
58325
|
+
const res = await fetch(`${this.baseUrl}/api/v1/repo-meshes`, { headers: this.headers() });
|
|
58326
|
+
if (!res.ok) throw new Error(`List remote meshes failed: ${res.status}`);
|
|
58327
|
+
return res.json();
|
|
58328
|
+
}
|
|
58329
|
+
async createRemoteMesh(data) {
|
|
58330
|
+
const res = await fetch(`${this.baseUrl}/api/v1/repo-meshes`, {
|
|
58331
|
+
method: "POST",
|
|
58332
|
+
headers: this.headers(),
|
|
58333
|
+
body: JSON.stringify(data)
|
|
58334
|
+
});
|
|
58335
|
+
if (!res.ok) throw new Error(`Create remote mesh failed: ${res.status}`);
|
|
58336
|
+
return res.json();
|
|
58337
|
+
}
|
|
58338
|
+
async deleteRemoteMesh(meshId) {
|
|
58339
|
+
const res = await fetch(`${this.baseUrl}/api/v1/repo-meshes/${encodeURIComponent(meshId)}`, {
|
|
58340
|
+
method: "DELETE",
|
|
58341
|
+
headers: this.headers()
|
|
58342
|
+
});
|
|
58343
|
+
if (!res.ok) throw new Error(`Delete remote mesh failed: ${res.status}`);
|
|
58344
|
+
}
|
|
58345
|
+
async syncMeshLedger(meshId, data) {
|
|
58346
|
+
const res = await fetch(`${this.baseUrl}/api/v1/repo-meshes/${encodeURIComponent(meshId)}/ledger/sync`, {
|
|
58347
|
+
method: "POST",
|
|
58348
|
+
headers: this.headers(),
|
|
58349
|
+
body: JSON.stringify(data)
|
|
58350
|
+
});
|
|
58351
|
+
if (!res.ok) throw new Error(`Sync mesh ledger failed: ${res.status}`);
|
|
58352
|
+
return res.json();
|
|
58353
|
+
}
|
|
57351
58354
|
async listDaemons() {
|
|
57352
58355
|
const res = await fetch(`${this.baseUrl}/api/v1/daemons`, { headers: this.headers() });
|
|
57353
58356
|
if (!res.ok) throw new Error(`List daemons failed: ${res.status}`);
|
|
@@ -57505,6 +58508,66 @@ var CloudTransport = class {
|
|
|
57505
58508
|
if (!res.ok) throw new Error(`Git checkpoint failed: ${res.status}`);
|
|
57506
58509
|
return res.json();
|
|
57507
58510
|
}
|
|
58511
|
+
async meshCloneNode(daemonId, payload) {
|
|
58512
|
+
const res = await fetch(
|
|
58513
|
+
`${this.baseUrl}/api/v1/shortcuts/${encodeURIComponent(daemonId)}/mesh/clone-node`,
|
|
58514
|
+
{
|
|
58515
|
+
method: "POST",
|
|
58516
|
+
headers: this.headers(),
|
|
58517
|
+
body: JSON.stringify(payload)
|
|
58518
|
+
}
|
|
58519
|
+
);
|
|
58520
|
+
if (!res.ok) throw new Error(`Mesh clone node failed: ${res.status}`);
|
|
58521
|
+
return res.json();
|
|
58522
|
+
}
|
|
58523
|
+
async meshRemoveNode(daemonId, payload) {
|
|
58524
|
+
const res = await fetch(
|
|
58525
|
+
`${this.baseUrl}/api/v1/shortcuts/${encodeURIComponent(daemonId)}/mesh/remove-node`,
|
|
58526
|
+
{
|
|
58527
|
+
method: "POST",
|
|
58528
|
+
headers: this.headers(),
|
|
58529
|
+
body: JSON.stringify(payload)
|
|
58530
|
+
}
|
|
58531
|
+
);
|
|
58532
|
+
if (!res.ok) throw new Error(`Mesh remove node failed: ${res.status}`);
|
|
58533
|
+
return res.json();
|
|
58534
|
+
}
|
|
58535
|
+
async meshCleanupSessions(daemonId, payload) {
|
|
58536
|
+
const res = await fetch(
|
|
58537
|
+
`${this.baseUrl}/api/v1/shortcuts/${encodeURIComponent(daemonId)}/mesh/cleanup-sessions`,
|
|
58538
|
+
{
|
|
58539
|
+
method: "POST",
|
|
58540
|
+
headers: this.headers(),
|
|
58541
|
+
body: JSON.stringify(payload)
|
|
58542
|
+
}
|
|
58543
|
+
);
|
|
58544
|
+
if (!res.ok) throw new Error(`Mesh cleanup sessions failed: ${res.status}`);
|
|
58545
|
+
return res.json();
|
|
58546
|
+
}
|
|
58547
|
+
async meshEnqueueTask(daemonId, payload) {
|
|
58548
|
+
const res = await fetch(
|
|
58549
|
+
`${this.baseUrl}/api/v1/shortcuts/${encodeURIComponent(daemonId)}/mesh/enqueue`,
|
|
58550
|
+
{
|
|
58551
|
+
method: "POST",
|
|
58552
|
+
headers: this.headers(),
|
|
58553
|
+
body: JSON.stringify(payload)
|
|
58554
|
+
}
|
|
58555
|
+
);
|
|
58556
|
+
if (!res.ok) throw new Error(`Mesh enqueue task failed: ${res.status}`);
|
|
58557
|
+
return res.json();
|
|
58558
|
+
}
|
|
58559
|
+
async meshRefineNode(daemonId, payload) {
|
|
58560
|
+
const res = await fetch(
|
|
58561
|
+
`${this.baseUrl}/api/v1/shortcuts/${encodeURIComponent(daemonId)}/mesh/refine-node`,
|
|
58562
|
+
{
|
|
58563
|
+
method: "POST",
|
|
58564
|
+
headers: this.headers(),
|
|
58565
|
+
body: JSON.stringify(payload)
|
|
58566
|
+
}
|
|
58567
|
+
);
|
|
58568
|
+
if (!res.ok) throw new Error(`Mesh refine node failed: ${res.status}`);
|
|
58569
|
+
return res.json();
|
|
58570
|
+
}
|
|
57508
58571
|
async ping() {
|
|
57509
58572
|
try {
|
|
57510
58573
|
await this.listDaemons();
|
|
@@ -58372,7 +59435,7 @@ var GIT_CHECKPOINT_TOOL = {
|
|
|
58372
59435
|
required: ["workspace", "message"]
|
|
58373
59436
|
}
|
|
58374
59437
|
};
|
|
58375
|
-
async function
|
|
59438
|
+
async function gitCheckpoint2(transport, args) {
|
|
58376
59439
|
const message = args.message?.trim();
|
|
58377
59440
|
if (!message) return "Error: message is required";
|
|
58378
59441
|
if (message.length > 200) return "Error: message must be 200 characters or fewer";
|
|
@@ -58432,7 +59495,7 @@ var GIT_PUSH_TOOL = {
|
|
|
58432
59495
|
required: ["workspace"]
|
|
58433
59496
|
}
|
|
58434
59497
|
};
|
|
58435
|
-
async function
|
|
59498
|
+
async function gitPush2(transport, args) {
|
|
58436
59499
|
let raw;
|
|
58437
59500
|
if (isLocalTransport(transport)) {
|
|
58438
59501
|
raw = await transport.command("git_push", {
|
|
@@ -58823,6 +59886,12 @@ async function startMcpServer(opts) {
|
|
|
58823
59886
|
case "mesh_list_nodes":
|
|
58824
59887
|
text = await meshListNodes(meshCtx);
|
|
58825
59888
|
break;
|
|
59889
|
+
case "mesh_enqueue_task":
|
|
59890
|
+
text = await meshEnqueueTask(meshCtx, a);
|
|
59891
|
+
break;
|
|
59892
|
+
case "mesh_view_queue":
|
|
59893
|
+
text = await meshViewQueue(meshCtx, a);
|
|
59894
|
+
break;
|
|
58826
59895
|
case "mesh_send_task":
|
|
58827
59896
|
text = await meshSendTask(meshCtx, a);
|
|
58828
59897
|
break;
|
|
@@ -58850,9 +59919,15 @@ async function startMcpServer(opts) {
|
|
|
58850
59919
|
case "mesh_remove_node":
|
|
58851
59920
|
text = await meshRemoveNode(meshCtx, a);
|
|
58852
59921
|
break;
|
|
59922
|
+
case "mesh_refine_node":
|
|
59923
|
+
text = await meshRefineNode(meshCtx, a);
|
|
59924
|
+
break;
|
|
58853
59925
|
case "mesh_cleanup_sessions":
|
|
58854
59926
|
text = await meshCleanupSessions(meshCtx, a);
|
|
58855
59927
|
break;
|
|
59928
|
+
case "mesh_task_history":
|
|
59929
|
+
text = await meshTaskHistory(meshCtx, a);
|
|
59930
|
+
break;
|
|
58856
59931
|
default:
|
|
58857
59932
|
return { content: [{ type: "text", text: `Unknown tool: ${name}` }], isError: true };
|
|
58858
59933
|
}
|
|
@@ -58941,11 +60016,11 @@ async function startMcpServer(opts) {
|
|
|
58941
60016
|
return { content: [{ type: "text", text }] };
|
|
58942
60017
|
}
|
|
58943
60018
|
case "git_checkpoint": {
|
|
58944
|
-
const text = await
|
|
60019
|
+
const text = await gitCheckpoint2(transport, { workspace: a.workspace, message: a.message, include_untracked: a.include_untracked, daemon_id: a.daemon_id });
|
|
58945
60020
|
return { content: [{ type: "text", text }] };
|
|
58946
60021
|
}
|
|
58947
60022
|
case "git_push": {
|
|
58948
|
-
const text = await
|
|
60023
|
+
const text = await gitPush2(transport, { workspace: a.workspace, remote: a.remote, branch: a.branch, daemon_id: a.daemon_id });
|
|
58949
60024
|
return { content: [{ type: "text", text }] };
|
|
58950
60025
|
}
|
|
58951
60026
|
case "launch_session": {
|