@adhdev/daemon-core 0.9.82-rc.363 → 0.9.82-rc.365

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 CHANGED
@@ -316,10 +316,10 @@ function readInjected(value) {
316
316
  }
317
317
  function getDaemonBuildInfo() {
318
318
  if (cached) return cached;
319
- const commit = readInjected(true ? "4c5b30b1b0527ec5234c037893ba4fc24b88a8a0" : void 0) ?? "unknown";
320
- const commitShort = readInjected(true ? "4c5b30b1" : void 0) ?? (commit !== "unknown" ? commit.slice(0, 7) : "unknown");
321
- const version = readInjected(true ? "0.9.82-rc.363" : void 0) ?? readInjected(typeof process !== "undefined" ? process.env?.ADHDEV_PKG_VERSION : void 0) ?? "unknown";
322
- const builtAt = readInjected(true ? "2026-06-23T16:13:33.075Z" : void 0);
319
+ const commit = readInjected(true ? "fe24f3fb158efc949e806b79bca2479b1c29d753" : void 0) ?? "unknown";
320
+ const commitShort = readInjected(true ? "fe24f3fb" : void 0) ?? (commit !== "unknown" ? commit.slice(0, 7) : "unknown");
321
+ const version = readInjected(true ? "0.9.82-rc.365" : void 0) ?? readInjected(typeof process !== "undefined" ? process.env?.ADHDEV_PKG_VERSION : void 0) ?? "unknown";
322
+ const builtAt = readInjected(true ? "2026-06-24T00:47:57.092Z" : void 0);
323
323
  cached = builtAt ? { commit, commitShort, version, builtAt } : { commit, commitShort, version };
324
324
  return cached;
325
325
  }
@@ -2193,6 +2193,21 @@ var init_recent_activity = __esm({
2193
2193
  }
2194
2194
  });
2195
2195
 
2196
+ // src/system/hash.ts
2197
+ function sha256Hex(input) {
2198
+ return (0, import_node_crypto.createHash)("sha256").update(input).digest("hex");
2199
+ }
2200
+ function shortHash(input, length = 16) {
2201
+ return sha256Hex(input).slice(0, length);
2202
+ }
2203
+ var import_node_crypto;
2204
+ var init_hash = __esm({
2205
+ "src/system/hash.ts"() {
2206
+ "use strict";
2207
+ import_node_crypto = require("crypto");
2208
+ }
2209
+ });
2210
+
2196
2211
  // src/mesh/mesh-host-ownership.ts
2197
2212
  function readObject(value) {
2198
2213
  return value && typeof value === "object" && !Array.isArray(value) ? value : null;
@@ -2470,7 +2485,7 @@ function normalizeManualHostAddress(hostAddress) {
2470
2485
  return normalized;
2471
2486
  }
2472
2487
  function tokenIdForManualPairing(token) {
2473
- return `tok_${(0, import_crypto3.createHash)("sha256").update(token).digest("hex").slice(0, 16)}`;
2488
+ return `tok_${shortHash(token)}`;
2474
2489
  }
2475
2490
  function normalizeTokenExpiry(value) {
2476
2491
  if (typeof value !== "string" || !value.trim()) return void 0;
@@ -2705,6 +2720,7 @@ var init_mesh_config = __esm({
2705
2720
  import_fs3 = require("fs");
2706
2721
  import_path3 = require("path");
2707
2722
  import_crypto3 = require("crypto");
2723
+ init_hash();
2708
2724
  init_config();
2709
2725
  init_repo_mesh_types();
2710
2726
  init_mesh_host_ownership();
@@ -7087,7 +7103,7 @@ function replaceLegacyCliCommandMcpArgs(command, args) {
7087
7103
  function resolveHermesCoordinatorHome(meshId, workspace) {
7088
7104
  const key = `${meshId || "mesh"}
7089
7105
  ${(0, import_node_path.resolve)(workspace || os4.tmpdir())}`;
7090
- const hash = (0, import_node_crypto.createHash)("sha256").update(key).digest("hex").slice(0, 16);
7106
+ const hash = shortHash(key);
7091
7107
  return (0, import_node_path.join)(os4.tmpdir(), `adhdev-hermes-mesh-coordinator-${hash}`);
7092
7108
  }
7093
7109
  function resolveMcpConfigPath(configPath, workspace) {
@@ -7296,16 +7312,16 @@ async function execUnderPty(command, args, options = {}) {
7296
7312
  });
7297
7313
  });
7298
7314
  }
7299
- var import_node_crypto, import_node_fs3, os4, import_session_host_core, import_node_path, DEFAULT_SERVER_NAME, DEFAULT_ADHDEV_MCP_COMMAND, HERMES_CLI_TYPE, HERMES_MCP_CONFIG_PATH;
7315
+ var import_node_fs3, os4, import_session_host_core, import_node_path, DEFAULT_SERVER_NAME, DEFAULT_ADHDEV_MCP_COMMAND, HERMES_CLI_TYPE, HERMES_MCP_CONFIG_PATH;
7300
7316
  var init_mesh_coordinator = __esm({
7301
7317
  "src/commands/mesh-coordinator.ts"() {
7302
7318
  "use strict";
7303
- import_node_crypto = require("crypto");
7304
7319
  import_node_fs3 = require("fs");
7305
7320
  os4 = __toESM(require("os"));
7306
7321
  import_session_host_core = require("@adhdev/session-host-core");
7307
7322
  import_node_path = require("path");
7308
7323
  init_logger();
7324
+ init_hash();
7309
7325
  DEFAULT_SERVER_NAME = "adhdev-mesh";
7310
7326
  DEFAULT_ADHDEV_MCP_COMMAND = "adhdev";
7311
7327
  HERMES_CLI_TYPE = "hermes-cli";
@@ -8174,6 +8190,46 @@ function classifyDirectDispatch(params) {
8174
8190
  const isFreshUnacknowledged = Boolean(ledgerOnlyStaleReason && !liveStaleReason);
8175
8191
  return { ledgerOnlyStaleReason, isFreshUnacknowledged };
8176
8192
  }
8193
+ function buildLedgerDirectDispatchRecord(dispatch, ctx) {
8194
+ const taskId = directDispatchTaskId(dispatch);
8195
+ const terminal = ctx.terminals.filter((entry) => new Date(entry.timestamp).getTime() >= new Date(dispatch.timestamp).getTime()).find((entry) => terminalMatchesDispatch(entry, dispatch, taskId));
8196
+ const terminalStatus = terminal ? statusFromTerminal(terminal) : void 0;
8197
+ const live = sessionStatusFromNodes(ctx.nodes, dispatch.nodeId, dispatch.sessionId);
8198
+ const status = terminalStatus || live.status || "assigned";
8199
+ const terminalRow = Boolean(terminal && terminal.kind !== "task_approval_needed");
8200
+ const { ledgerOnlyStaleReason, isFreshUnacknowledged } = classifyDirectDispatch({
8201
+ status,
8202
+ isTerminalRow: terminalRow,
8203
+ hasTerminalStatus: Boolean(terminalStatus),
8204
+ liveStatus: live.status,
8205
+ liveStaleReason: live.staleReason,
8206
+ dispatchedToIdleSession: dispatch.payload?.dispatchedToIdleSession === true
8207
+ });
8208
+ const message = readString6(dispatch.payload?.message) || readString6(dispatch.payload?.summary) || "";
8209
+ const { title, summary } = summarizeMessage(message);
8210
+ const record = {
8211
+ taskId,
8212
+ source: "direct",
8213
+ status,
8214
+ nodeId: dispatch.nodeId,
8215
+ sessionId: dispatch.sessionId,
8216
+ providerType: dispatch.providerType || readString6(dispatch.payload?.providerType),
8217
+ taskTitle: readString6(dispatch.payload?.taskTitle) || title,
8218
+ taskSummary: readString6(dispatch.payload?.taskSummary) || summary,
8219
+ message,
8220
+ taskMode: readString6(dispatch.payload?.taskMode),
8221
+ createdAt: dispatch.timestamp,
8222
+ updatedAt: terminal?.timestamp || dispatch.timestamp,
8223
+ dispatchedAt: dispatch.timestamp,
8224
+ elapsedMs: elapsedSince(dispatch.timestamp, ctx.now),
8225
+ terminal: terminalRow,
8226
+ terminalKind: terminal?.kind,
8227
+ terminalAt: terminal?.timestamp,
8228
+ staleReason: live.staleReason || ledgerOnlyStaleReason,
8229
+ ...isFreshUnacknowledged ? { staleDispatchUnacknowledged: true } : {}
8230
+ };
8231
+ return { record, terminalRow };
8232
+ }
8177
8233
  function buildMeshActiveWorkSummary(activeWork) {
8178
8234
  const statusCounts = {
8179
8235
  pending: 0,
@@ -8279,49 +8335,13 @@ function buildMeshActiveWork(opts) {
8279
8335
  const ledgerEntries = (opts.ledgerEntries || []).slice().sort((a, b) => new Date(a.timestamp).getTime() - new Date(b.timestamp).getTime());
8280
8336
  const terminals = ledgerEntries.filter((entry) => TERMINAL_LEDGER_KINDS.has(entry.kind) || entry.kind === "task_approval_needed");
8281
8337
  for (const dispatch of ledgerEntries.filter(isDirectDispatch)) {
8282
- const taskId = directDispatchTaskId(dispatch);
8283
- if (dbTaskIds.has(taskId)) continue;
8284
- const terminal = terminals.filter((entry) => new Date(entry.timestamp).getTime() >= new Date(dispatch.timestamp).getTime()).find((entry) => terminalMatchesDispatch(entry, dispatch, taskId));
8285
- const terminalStatus = terminal ? statusFromTerminal(terminal) : void 0;
8286
- const live = sessionStatusFromNodes(opts.nodes, dispatch.nodeId, dispatch.sessionId);
8287
- const status = terminalStatus || live.status || "assigned";
8288
- const terminalRow = Boolean(terminal && terminal.kind !== "task_approval_needed");
8289
- const { ledgerOnlyStaleReason, isFreshUnacknowledged } = classifyDirectDispatch({
8290
- status,
8291
- isTerminalRow: terminalRow,
8292
- hasTerminalStatus: Boolean(terminalStatus),
8293
- liveStatus: live.status,
8294
- liveStaleReason: live.staleReason,
8295
- dispatchedToIdleSession: dispatch.payload?.dispatchedToIdleSession === true
8296
- });
8297
- const message = readString6(dispatch.payload?.message) || readString6(dispatch.payload?.summary) || "";
8298
- const { title, summary: summary2 } = summarizeMessage(message);
8299
- const record = {
8300
- taskId,
8301
- source: "direct",
8302
- status,
8303
- nodeId: dispatch.nodeId,
8304
- sessionId: dispatch.sessionId,
8305
- providerType: dispatch.providerType || readString6(dispatch.payload?.providerType),
8306
- taskTitle: readString6(dispatch.payload?.taskTitle) || title,
8307
- taskSummary: readString6(dispatch.payload?.taskSummary) || summary2,
8308
- message,
8309
- taskMode: readString6(dispatch.payload?.taskMode),
8310
- createdAt: dispatch.timestamp,
8311
- updatedAt: terminal?.timestamp || dispatch.timestamp,
8312
- dispatchedAt: dispatch.timestamp,
8313
- elapsedMs: elapsedSince(dispatch.timestamp, now),
8314
- terminal: terminalRow,
8315
- terminalKind: terminal?.kind,
8316
- terminalAt: terminal?.timestamp,
8317
- staleReason: live.staleReason || ledgerOnlyStaleReason,
8318
- ...isFreshUnacknowledged ? { staleDispatchUnacknowledged: true } : {}
8319
- };
8338
+ if (dbTaskIds.has(directDispatchTaskId(dispatch))) continue;
8339
+ const { record, terminalRow } = buildLedgerDirectDispatchRecord(dispatch, { terminals, nodes: opts.nodes, now });
8320
8340
  if (terminalRow) {
8321
8341
  terminalDirectWork.push(record);
8322
8342
  if (opts.includeTerminalDirect !== true) continue;
8323
8343
  }
8324
- if ((live.staleReason || ledgerOnlyStaleReason) && !terminalRow) {
8344
+ if (record.staleReason && !terminalRow) {
8325
8345
  staleDirectWork.push(record);
8326
8346
  continue;
8327
8347
  }
@@ -8331,48 +8351,12 @@ function buildMeshActiveWork(opts) {
8331
8351
  const ledgerEntries = (opts.ledgerEntries || []).slice().sort((a, b) => new Date(a.timestamp).getTime() - new Date(b.timestamp).getTime());
8332
8352
  const terminals = ledgerEntries.filter((entry) => TERMINAL_LEDGER_KINDS.has(entry.kind) || entry.kind === "task_approval_needed");
8333
8353
  for (const dispatch of ledgerEntries.filter(isDirectDispatch)) {
8334
- const taskId = directDispatchTaskId(dispatch);
8335
- const terminal = terminals.filter((entry) => new Date(entry.timestamp).getTime() >= new Date(dispatch.timestamp).getTime()).find((entry) => terminalMatchesDispatch(entry, dispatch, taskId));
8336
- const terminalStatus = terminal ? statusFromTerminal(terminal) : void 0;
8337
- const live = sessionStatusFromNodes(opts.nodes, dispatch.nodeId, dispatch.sessionId);
8338
- const status = terminalStatus || live.status || "assigned";
8339
- const terminalRow = Boolean(terminal && terminal.kind !== "task_approval_needed");
8340
- const { ledgerOnlyStaleReason, isFreshUnacknowledged } = classifyDirectDispatch({
8341
- status,
8342
- isTerminalRow: terminalRow,
8343
- hasTerminalStatus: Boolean(terminalStatus),
8344
- liveStatus: live.status,
8345
- liveStaleReason: live.staleReason,
8346
- dispatchedToIdleSession: dispatch.payload?.dispatchedToIdleSession === true
8347
- });
8348
- const message = readString6(dispatch.payload?.message) || readString6(dispatch.payload?.summary) || "";
8349
- const { title, summary: summary2 } = summarizeMessage(message);
8350
- const record = {
8351
- taskId,
8352
- source: "direct",
8353
- status,
8354
- nodeId: dispatch.nodeId,
8355
- sessionId: dispatch.sessionId,
8356
- providerType: dispatch.providerType || readString6(dispatch.payload?.providerType),
8357
- taskTitle: readString6(dispatch.payload?.taskTitle) || title,
8358
- taskSummary: readString6(dispatch.payload?.taskSummary) || summary2,
8359
- message,
8360
- taskMode: readString6(dispatch.payload?.taskMode),
8361
- createdAt: dispatch.timestamp,
8362
- updatedAt: terminal?.timestamp || dispatch.timestamp,
8363
- dispatchedAt: dispatch.timestamp,
8364
- elapsedMs: elapsedSince(dispatch.timestamp, now),
8365
- terminal: terminalRow,
8366
- terminalKind: terminal?.kind,
8367
- terminalAt: terminal?.timestamp,
8368
- staleReason: live.staleReason || ledgerOnlyStaleReason,
8369
- ...isFreshUnacknowledged ? { staleDispatchUnacknowledged: true } : {}
8370
- };
8354
+ const { record, terminalRow } = buildLedgerDirectDispatchRecord(dispatch, { terminals, nodes: opts.nodes, now });
8371
8355
  if (terminalRow) {
8372
8356
  terminalDirectWork.push(record);
8373
8357
  if (opts.includeTerminalDirect !== true) continue;
8374
8358
  }
8375
- if ((live.staleReason || ledgerOnlyStaleReason) && !terminalRow) {
8359
+ if (record.staleReason && !terminalRow) {
8376
8360
  staleDirectWork.push(record);
8377
8361
  continue;
8378
8362
  }
@@ -34739,6 +34723,9 @@ var lowFamilyRegistry = new Map(
34739
34723
  })
34740
34724
  );
34741
34725
 
34726
+ // src/commands/med-family/cli-agent.ts
34727
+ init_dist();
34728
+
34742
34729
  // src/commands/cli-manager.ts
34743
34730
  var os21 = __toESM(require("os"));
34744
34731
  var path27 = __toESM(require("path"));
@@ -34752,6 +34739,7 @@ init_config();
34752
34739
  init_state_store();
34753
34740
  init_workspaces();
34754
34741
  init_recent_activity();
34742
+ init_hash();
34755
34743
  init_coordinator_registry();
34756
34744
  init_summary_metadata();
34757
34745
 
@@ -35091,6 +35079,11 @@ var FsmDriver = class {
35091
35079
  lastWin32WriteAt = 0;
35092
35080
  /** Pending paced chunk-write timer for a large win32 body (see writeWin32Body). */
35093
35081
  win32WriteTimer = null;
35082
+ /** Timer driving the win32 verification-based modal-confirm CR resend loop (see
35083
+ * scheduleWin32ModalConfirm). A lone CR that confirms an approval/picker choice
35084
+ * is absorbed by ConPTY the same way a send_message submit CR is, so the confirm
35085
+ * must be resent until the modal actually resolves (status leaves 'approval'). */
35086
+ win32ModalConfirmTimer = null;
35094
35087
  currentEval = null;
35095
35088
  stateHistory = [];
35096
35089
  prevStateAt = 0;
@@ -35215,6 +35208,10 @@ var FsmDriver = class {
35215
35208
  clearTimeout(this.win32WriteTimer);
35216
35209
  this.win32WriteTimer = null;
35217
35210
  }
35211
+ if (this.win32ModalConfirmTimer) {
35212
+ clearTimeout(this.win32ModalConfirmTimer);
35213
+ this.win32ModalConfirmTimer = null;
35214
+ }
35218
35215
  this.specWatcher?.close();
35219
35216
  this.adapter.kill();
35220
35217
  }
@@ -35810,10 +35807,61 @@ var FsmDriver = class {
35810
35807
  const nav = step.repeat(Math.abs(delta));
35811
35808
  const confirm = (rule.key_for_index || "\r").replace(/\{index\}/g, "") || "\r";
35812
35809
  if (nav) this.adapter.send_keys(nav);
35813
- this.adapter.send_keys(confirm);
35810
+ this.submitModalConfirm(confirm);
35811
+ return;
35812
+ }
35813
+ this.submitModalConfirm(btn.key);
35814
+ }
35815
+ /**
35816
+ * Submit a modal-confirm key sequence (the choice key + its trailing CR).
35817
+ *
35818
+ * On win32 the trailing CR is the SAME lone-CR-swallow case as a send_message
35819
+ * submit: ConPTY can absorb a single CR as a literal newline instead of a
35820
+ * confirm, so the approval/picker modal never resolves and the FSM flaps
35821
+ * approval↔busy while auto-approve keeps firing into the void (APPROVESTUCK).
35822
+ * So we split any non-CR prefix (e.g. the "1" of "1\r") off, write it once, and
35823
+ * resend the CR on a fixed cadence until the modal actually resolves (status
35824
+ * leaves 'approval'). Non-win32 keeps the single direct write — its CR submits
35825
+ * on the first try.
35826
+ */
35827
+ submitModalConfirm(keys) {
35828
+ if (process.platform !== "win32") {
35829
+ this.adapter.send_keys(keys);
35814
35830
  return;
35815
35831
  }
35816
- this.adapter.send_keys(btn.key);
35832
+ const m = /^([\s\S]*?)([\r\n]+)$/.exec(keys);
35833
+ const prefix = m ? m[1] : keys;
35834
+ const cr = m ? m[2] : "";
35835
+ if (prefix) this.adapter.send_keys(prefix);
35836
+ if (!cr) return;
35837
+ this.scheduleWin32ModalConfirm(cr);
35838
+ }
35839
+ /**
35840
+ * win32 modal-confirm CR resend loop. Mirrors scheduleWin32Submit's phase-2
35841
+ * verified resend, but gated on still being IN a modal (status 'approval')
35842
+ * rather than still idle: the first CR fires immediately, then resends every
35843
+ * WIN32_SUBMIT_RESEND_GAP_MS while the FSM is still showing the modal, up to
35844
+ * WIN32_SUBMIT_MAX_RESENDS. The instant the modal resolves (status flips to
35845
+ * generating/idle) we stop, so no stray CR leaks into the next turn's composer.
35846
+ */
35847
+ scheduleWin32ModalConfirm(submitKey) {
35848
+ if (this.win32ModalConfirmTimer) {
35849
+ clearTimeout(this.win32ModalConfirmTimer);
35850
+ this.win32ModalConfirmTimer = null;
35851
+ }
35852
+ const fire = (attempt) => {
35853
+ this.win32ModalConfirmTimer = null;
35854
+ this.adapter.send_keys(submitKey);
35855
+ if (attempt + 1 >= WIN32_SUBMIT_MAX_RESENDS) return;
35856
+ this.win32ModalConfirmTimer = setTimeout(() => {
35857
+ if (this.currentStatus() !== "approval") {
35858
+ this.win32ModalConfirmTimer = null;
35859
+ return;
35860
+ }
35861
+ fire(attempt + 1);
35862
+ }, WIN32_SUBMIT_RESEND_GAP_MS);
35863
+ };
35864
+ fire(0);
35817
35865
  }
35818
35866
  handleAttachImage(blob, mime) {
35819
35867
  const ctl = (this.spec.control_bar ?? []).find((c) => c.action.type === "attach_image");
@@ -41085,7 +41133,7 @@ function hasConfigOverride(args, key) {
41085
41133
  function ensureEmptyDelegatedMcpConfig(workspace) {
41086
41134
  const baseDir = path27.join(os21.tmpdir(), "adhdev-delegated-agent-empty-mcp");
41087
41135
  (0, import_fs15.mkdirSync)(baseDir, { recursive: true });
41088
- const workspaceHash = crypto5.createHash("sha256").update(path27.resolve(workspace || os21.tmpdir())).digest("hex").slice(0, 16);
41136
+ const workspaceHash = shortHash(path27.resolve(workspace || os21.tmpdir()));
41089
41137
  const filePath = path27.join(baseDir, `${workspaceHash}.json`);
41090
41138
  (0, import_fs15.writeFileSync)(filePath, JSON.stringify({ mcpServers: {} }, null, 2), "utf-8");
41091
41139
  return filePath;
@@ -42053,6 +42101,156 @@ Run 'adhdev doctor' for detailed diagnostics.`
42053
42101
  }
42054
42102
  };
42055
42103
 
42104
+ // src/commands/med-family/cli-agent.ts
42105
+ init_state_store();
42106
+ init_recent_activity();
42107
+ init_mesh_events_utils();
42108
+ var cliAgentHandlers = {
42109
+ launch_cli: async (ctx, args) => {
42110
+ const launchResult = await ctx.deps.cliManager.handleCliCommand("launch_cli", args);
42111
+ const meshNodeId = readStringValue(args?.settings?.meshNodeId);
42112
+ const meshId = readStringValue(args?.settings?.meshNodeFor);
42113
+ if (meshNodeId && meshId && launchResult?.success !== false) {
42114
+ try {
42115
+ const { getMesh: getMesh2 } = await Promise.resolve().then(() => (init_mesh_config(), mesh_config_exports));
42116
+ const meshObj = getMesh2(meshId) ?? ctx.getCachedInlineMesh(meshId);
42117
+ const nodeObj = Array.isArray(meshObj?.nodes) ? meshObj.nodes.find((n) => meshNodeIdMatches(n, meshNodeId)) : void 0;
42118
+ const bootstrapStatus = readStringValue(nodeObj?.worktreeBootstrap?.status);
42119
+ if (bootstrapStatus === "running") {
42120
+ return { success: true, ...launchResult, bootstrapPending: true };
42121
+ }
42122
+ } catch {
42123
+ }
42124
+ }
42125
+ return launchResult;
42126
+ },
42127
+ stop_cli: async (ctx, args) => {
42128
+ return ctx.deps.cliManager.handleCliCommand("stop_cli", args);
42129
+ },
42130
+ set_cli_view_mode: async (ctx, args) => {
42131
+ return ctx.deps.cliManager.handleCliCommand("set_cli_view_mode", args);
42132
+ },
42133
+ record_provider_pty: async (ctx, args) => {
42134
+ return ctx.deps.cliManager.handleCliCommand("record_provider_pty", args);
42135
+ },
42136
+ agent_command: async (ctx, args) => {
42137
+ {
42138
+ const dispatchSessionId = readStringValue(args?.targetSessionId, args?.sessionId, args?.instanceId);
42139
+ const dispatchMeshContext = args?.meshContext;
42140
+ if (dispatchSessionId && dispatchMeshContext) {
42141
+ try {
42142
+ const inst = ctx.deps.instanceManager.getInstance(dispatchSessionId);
42143
+ if (inst && typeof inst.updateSettings === "function") {
42144
+ const stamp = buildMeshWorkerRelayStamp(
42145
+ inst.getState?.()?.settings,
42146
+ {
42147
+ meshId: dispatchMeshContext.meshId,
42148
+ nodeId: dispatchMeshContext.nodeId,
42149
+ coordinatorDaemonId: dispatchMeshContext.coordinatorDaemonId,
42150
+ // Session-level anchor: preserved across the P2P dispatch to a
42151
+ // remote worker so its completion echoes back to the right session.
42152
+ coordinatorSessionId: dispatchMeshContext.coordinatorSessionId
42153
+ }
42154
+ );
42155
+ if (stamp) inst.updateSettings(stamp);
42156
+ }
42157
+ } catch {
42158
+ }
42159
+ }
42160
+ }
42161
+ const agentResult = await ctx.deps.cliManager.handleCliCommand("agent_command", args);
42162
+ const meshCtx = args?.meshContext;
42163
+ const dispatchNodeId = readStringValue(meshCtx?.nodeId);
42164
+ const dispatchMeshId = readStringValue(meshCtx?.meshId);
42165
+ if (dispatchNodeId && dispatchMeshId && agentResult?.success !== false) {
42166
+ try {
42167
+ const { getMesh: getMesh2 } = await Promise.resolve().then(() => (init_mesh_config(), mesh_config_exports));
42168
+ const meshObj = getMesh2(dispatchMeshId) ?? ctx.getCachedInlineMesh(dispatchMeshId);
42169
+ const nodeObj = Array.isArray(meshObj?.nodes) ? meshObj.nodes.find((n) => meshNodeIdMatches(n, dispatchNodeId)) : void 0;
42170
+ const bootstrapStatus = readStringValue(nodeObj?.worktreeBootstrap?.status);
42171
+ if (bootstrapStatus === "running") {
42172
+ return {
42173
+ success: true,
42174
+ ...agentResult,
42175
+ dispatchAcknowledgementRisk: true,
42176
+ dispatchAcknowledgementRiskReason: "bootstrap_still_running",
42177
+ nextAction: "Wait for worktree_bootstrap_complete event before dispatching work to this node."
42178
+ };
42179
+ }
42180
+ } catch {
42181
+ }
42182
+ }
42183
+ return agentResult;
42184
+ },
42185
+ // ─── Logs ───
42186
+ list_saved_sessions: async (ctx, args) => {
42187
+ const providerType = typeof args?.providerType === "string" ? args.providerType.trim() : typeof args?.agentType === "string" ? args.agentType.trim() : "";
42188
+ const kind = args?.kind === "acp" ? "acp" : "cli";
42189
+ if (!providerType) {
42190
+ return { success: false, error: "providerType required" };
42191
+ }
42192
+ const wantsAll = args?.all === true;
42193
+ const offset = wantsAll ? 0 : Math.max(0, Number(args?.offset) || 0);
42194
+ const limit = wantsAll ? Number.MAX_SAFE_INTEGER : Math.max(1, Math.min(100, Number(args?.limit) || 30));
42195
+ const requestedWorkspace = typeof args?.workspace === "string" ? args.workspace.trim() : "";
42196
+ const requestedProviderSessionId = typeof args?.providerSessionId === "string" ? args.providerSessionId.trim() : typeof args?.activeProviderSessionId === "string" ? args.activeProviderSessionId.trim() : "";
42197
+ const providerMeta = ctx.deps.providerLoader.resolve?.(providerType) || ctx.deps.providerLoader.getMeta(providerType);
42198
+ const { sessions: historySessions, hasMore, source } = listProviderHistorySessions(providerType, {
42199
+ canonicalHistory: providerMeta?.nativeHistory,
42200
+ offset,
42201
+ limit,
42202
+ historyBehavior: providerMeta?.historyBehavior,
42203
+ scripts: providerMeta?.scripts
42204
+ });
42205
+ const state = loadState();
42206
+ const savedSessions = getSavedProviderSessions(state, { providerType, kind });
42207
+ const recentSessions = getRecentActivity(state, 200).filter((entry) => entry.providerType === providerType && entry.kind === kind && entry.providerSessionId);
42208
+ const savedSessionById = new Map(savedSessions.map((entry) => [entry.providerSessionId, entry]));
42209
+ const recentSessionById = new Map(recentSessions.map((entry) => [entry.providerSessionId, entry]));
42210
+ const canResumeById = supportsExplicitSessionResume(providerMeta?.resume);
42211
+ return {
42212
+ success: true,
42213
+ sessions: historySessions.map((session) => {
42214
+ const saved = savedSessionById.get(session.historySessionId);
42215
+ const recent = recentSessionById.get(session.historySessionId);
42216
+ const workspace = saved?.workspace || recent?.workspace || session.workspace || (requestedWorkspace && requestedProviderSessionId === session.historySessionId ? requestedWorkspace : void 0);
42217
+ return {
42218
+ id: session.historySessionId,
42219
+ providerSessionId: session.historySessionId,
42220
+ providerType,
42221
+ providerName: saved?.providerName || recent?.providerName || providerType,
42222
+ kind: saved?.kind || recent?.kind || kind,
42223
+ title: saved?.title || recent?.title || session.sessionTitle || session.preview || providerType,
42224
+ workspace,
42225
+ summaryMetadata: saved?.summaryMetadata || recent?.summaryMetadata,
42226
+ preview: session.preview,
42227
+ messageCount: session.messageCount,
42228
+ firstMessageAt: session.firstMessageAt,
42229
+ lastMessageAt: session.lastMessageAt,
42230
+ canResume: !!workspace && canResumeById,
42231
+ historySource: session.source,
42232
+ sourcePath: session.sourcePath,
42233
+ sourceMtimeMs: session.sourceMtimeMs
42234
+ };
42235
+ }),
42236
+ hasMore,
42237
+ source
42238
+ };
42239
+ },
42240
+ // ─── restart_session: IDE / CLI / ACP unified ───
42241
+ restart_session: async (ctx, args) => {
42242
+ const targetType = args?.cliType || args?.agentType || args?.ideType;
42243
+ if (!targetType) throw new Error("cliType or ideType required");
42244
+ const isIde = ctx.deps.cdpManagers.has(targetType) || ctx.deps.providerLoader.getMeta(targetType)?.category === "ide";
42245
+ if (isIde) {
42246
+ await ctx.stopIde(targetType, true);
42247
+ const launchResult = await ctx.launchIde({ ideType: targetType, enableCdp: true, workspace: args?.workspace });
42248
+ return { success: true, restarted: true, ideType: targetType, launch: launchResult };
42249
+ }
42250
+ return ctx.deps.cliManager.handleCliCommand("restart_session", args);
42251
+ }
42252
+ };
42253
+
42056
42254
  // src/launch.ts
42057
42255
  var import_child_process9 = require("child_process");
42058
42256
  var net = __toESM(require("net"));
@@ -45878,12 +46076,1342 @@ function getAvailableIdeIds() {
45878
46076
  return getProviderLoader().getAvailableIdeTypes();
45879
46077
  }
45880
46078
 
45881
- // src/commands/router.ts
46079
+ // src/commands/med-family/ide.ts
45882
46080
  init_config();
45883
46081
  init_state_store();
45884
46082
  init_workspaces();
45885
46083
  init_recent_activity();
45886
46084
  init_cli_detector();
46085
+ init_logger();
46086
+ async function launchIde(ctx, args) {
46087
+ const ideKey = args?.ideId || args?.ideType;
46088
+ const resolvedWorkspace = resolveIdeLaunchWorkspace(
46089
+ {
46090
+ workspace: args?.workspace,
46091
+ workspaceId: args?.workspaceId,
46092
+ useDefaultWorkspace: args?.useDefaultWorkspace
46093
+ },
46094
+ loadConfig()
46095
+ );
46096
+ const launchArgs = {
46097
+ ideId: ideKey,
46098
+ workspace: resolvedWorkspace,
46099
+ newWindow: args?.newWindow
46100
+ };
46101
+ LOG.info("LaunchIDE", `target=${ideKey || "auto"}`);
46102
+ const result = await launchWithCdp(launchArgs);
46103
+ if (result.success && result.port && result.ideId && !ctx.deps.cdpManagers.has(result.ideId)) {
46104
+ const logFn = ctx.deps.getCdpLogFn ? ctx.deps.getCdpLogFn(result.ideId) : LOG.forComponent(`CDP:${result.ideId}`).asLogFn();
46105
+ const provider = ctx.deps.providerLoader.getMeta(result.ideId);
46106
+ const manager = new DaemonCdpManager(result.port, logFn, void 0, provider?.targetFilter);
46107
+ const connected = await manager.connect();
46108
+ if (connected) {
46109
+ registerExtensionProviders(ctx.deps.providerLoader, manager, result.ideId);
46110
+ ctx.deps.cdpManagers.set(result.ideId, manager);
46111
+ LOG.info("CDP", `Connected: ${result.ideId} (port ${result.port})`);
46112
+ LOG.info("CDP", `${ctx.deps.cdpManagers.size} IDE(s) connected`);
46113
+ ctx.deps.onCdpManagerCreated?.(result.ideId, manager);
46114
+ }
46115
+ }
46116
+ ctx.deps.onIdeConnected?.();
46117
+ try {
46118
+ const results = await detectIDEs(ctx.deps.providerLoader);
46119
+ ctx.deps.detectedIdes.value = results;
46120
+ ctx.deps.providerLoader.setIdeDetectionResults(results, true);
46121
+ } catch {
46122
+ }
46123
+ if (result.success && resolvedWorkspace) {
46124
+ try {
46125
+ const next = appendRecentActivity(loadState(), {
46126
+ kind: "ide",
46127
+ providerType: result.ideId || ideKey,
46128
+ providerName: result.ideId || ideKey,
46129
+ workspace: resolvedWorkspace,
46130
+ title: result.ideId || ideKey
46131
+ });
46132
+ saveState(next);
46133
+ } catch {
46134
+ }
46135
+ } else if (result.success && (result.ideId || ideKey)) {
46136
+ try {
46137
+ saveState(appendRecentActivity(loadState(), {
46138
+ kind: "ide",
46139
+ providerType: result.ideId || ideKey,
46140
+ providerName: result.ideId || ideKey,
46141
+ title: result.ideId || ideKey
46142
+ }));
46143
+ } catch {
46144
+ }
46145
+ }
46146
+ return { ...result };
46147
+ }
46148
+ var ideHandlers = {
46149
+ // ─── IDE stop ───
46150
+ stop_ide: async (ctx, args) => {
46151
+ const ideType = args?.ideType;
46152
+ if (!ideType) throw new Error("ideType required");
46153
+ const killProcess = args?.killProcess !== false;
46154
+ await ctx.stopIde(ideType, killProcess);
46155
+ try {
46156
+ const results = await detectIDEs(ctx.deps.providerLoader);
46157
+ ctx.deps.detectedIdes.value = results;
46158
+ ctx.deps.providerLoader.setIdeDetectionResults(results, true);
46159
+ } catch {
46160
+ }
46161
+ return { success: true, ideType, stopped: true, processKilled: killProcess };
46162
+ },
46163
+ // ─── IDE restart ───
46164
+ restart_ide: async (ctx, args) => {
46165
+ const ideType = args?.ideType;
46166
+ if (!ideType) throw new Error("ideType required");
46167
+ await ctx.stopIde(ideType, true);
46168
+ const launchResult = await ctx.launchIde({ ideType, enableCdp: true, workspace: args?.workspace });
46169
+ return { success: true, ideType, restarted: true, launch: launchResult };
46170
+ },
46171
+ // ─── IDE launch + CDP connect ───
46172
+ launch_ide: async (ctx, args) => {
46173
+ return launchIde(ctx, args);
46174
+ },
46175
+ // ─── Detect providers ───
46176
+ detect_provider: async (ctx, args) => {
46177
+ const providerType = typeof args?.providerType === "string" ? args.providerType.trim() : "";
46178
+ if (!providerType) return { success: false, error: "providerType is required" };
46179
+ const normalizedType = ctx.deps.providerLoader.resolveAlias(providerType);
46180
+ const provider = ctx.deps.providerLoader.getByAlias(providerType);
46181
+ if (!provider) return { success: false, error: `Provider not found: ${providerType}` };
46182
+ if (provider.category !== "cli" && provider.category !== "acp") {
46183
+ return { success: false, error: `Provider detection is only supported for CLI/ACP providers: ${providerType}` };
46184
+ }
46185
+ if (!ctx.deps.providerLoader.isMachineProviderEnabled(normalizedType)) {
46186
+ return { success: false, error: `Provider is disabled on this machine: ${providerType}` };
46187
+ }
46188
+ const detected = await detectCLI(normalizedType, ctx.deps.providerLoader, { includeVersion: false });
46189
+ ctx.deps.providerLoader.setCliDetectionResults([{
46190
+ id: normalizedType,
46191
+ installed: !!detected,
46192
+ path: detected?.path
46193
+ }], false);
46194
+ ctx.deps.onStatusChange?.();
46195
+ return {
46196
+ success: true,
46197
+ providerType: normalizedType,
46198
+ detected: !!detected,
46199
+ path: detected?.path || null
46200
+ };
46201
+ },
46202
+ // ─── Detect IDEs ───
46203
+ detect_ides: async (ctx, _args) => {
46204
+ const results = await detectIDEs(ctx.deps.providerLoader);
46205
+ ctx.deps.detectedIdes.value = results;
46206
+ ctx.deps.providerLoader.setIdeDetectionResults(results, true);
46207
+ return { success: true, detectedInfo: results };
46208
+ }
46209
+ };
46210
+
46211
+ // src/commands/med-family/mesh-crud.ts
46212
+ init_dist();
46213
+ init_mesh_host_ownership();
46214
+ init_mesh_events();
46215
+ init_config();
46216
+ var meshCrudHandlers = {
46217
+ list_meshes: async (_ctx, _args) => {
46218
+ try {
46219
+ const { listMeshes: listMeshes2 } = await Promise.resolve().then(() => (init_mesh_config(), mesh_config_exports));
46220
+ return { success: true, meshes: listMeshes2() };
46221
+ } catch (e) {
46222
+ return { success: false, error: e.message };
46223
+ }
46224
+ },
46225
+ get_mesh: async (ctx, args) => {
46226
+ const meshId = typeof args?.meshId === "string" ? args.meshId.trim() : "";
46227
+ if (!meshId) return { success: false, error: "meshId required" };
46228
+ const meshRecord = await ctx.getMeshForCommand(meshId, args?.inlineMesh, { preferInline: true });
46229
+ if (!meshRecord?.mesh) return { success: false, error: "Mesh not found" };
46230
+ const requireDirectPeerTruth = args?.requireDirectPeerTruth === true;
46231
+ const probeRemotePeers = args?.refresh === true || args?.forceRefresh === true;
46232
+ const directTruth = await hydrateInlineMeshDirectTruth({
46233
+ mesh: meshRecord.mesh,
46234
+ meshSource: meshRecord.source,
46235
+ dispatchMeshCommand: ctx.deps.dispatchMeshCommand,
46236
+ getMeshPeerConnectionStatus: ctx.deps.getMeshPeerConnectionStatus,
46237
+ statusInstanceId: ctx.deps.statusInstanceId,
46238
+ localMachineId: loadConfig().machineId || "",
46239
+ probeRemotePeers,
46240
+ probeCache: ctx.meshGitProbeCache
46241
+ });
46242
+ const directTruthSatisfied = meshRecord.source !== "inline_bootstrap" || directTruth.directEvidenceCount > 0;
46243
+ const sourceOfTruth = {
46244
+ membership: meshRecord.source === "inline_cache" ? "coordinator_inline_mesh_cache" : meshRecord.source === "local_config" ? "local_mesh_config" : "inline_bootstrap_snapshot",
46245
+ coordinatorOwnsLiveTruth: directTruthSatisfied,
46246
+ directPeerTruth: {
46247
+ required: requireDirectPeerTruth,
46248
+ satisfied: directTruthSatisfied,
46249
+ directEvidenceCount: directTruth.directEvidenceCount,
46250
+ localConfirmedCount: directTruth.localConfirmedCount,
46251
+ peerAttemptedCount: directTruth.peerAttemptedCount,
46252
+ peerConfirmedCount: directTruth.peerConfirmedCount,
46253
+ unavailableNodeIds: directTruth.unavailableNodeIds
46254
+ }
46255
+ };
46256
+ if (requireDirectPeerTruth && !directTruthSatisfied) {
46257
+ return {
46258
+ success: false,
46259
+ code: "mesh_direct_peer_truth_unavailable",
46260
+ error: "Selected coordinator could not confirm direct mesh truth yet. Bootstrap inventory stays unavailable until direct get_mesh probes succeed.",
46261
+ sourceOfTruth
46262
+ };
46263
+ }
46264
+ return { success: true, mesh: meshRecord.mesh, sourceOfTruth };
46265
+ },
46266
+ create_mesh: async (_ctx, args) => {
46267
+ const name = typeof args?.name === "string" ? args.name.trim() : "";
46268
+ const repoIdentity = typeof args?.repoIdentity === "string" ? args.repoIdentity.trim() : "";
46269
+ const repoRemoteUrl = typeof args?.repoRemoteUrl === "string" ? args.repoRemoteUrl.trim() : void 0;
46270
+ const defaultBranch = typeof args?.defaultBranch === "string" ? args.defaultBranch.trim() : void 0;
46271
+ if (!name) return { success: false, error: "name required" };
46272
+ try {
46273
+ const { createMesh: createMesh2 } = await Promise.resolve().then(() => (init_mesh_config(), mesh_config_exports));
46274
+ const meshHost = args?.meshHost && typeof args.meshHost === "object" && !Array.isArray(args.meshHost) ? args.meshHost : void 0;
46275
+ const mesh = createMesh2({ name, repoIdentity, repoRemoteUrl, defaultBranch, policy: args?.policy, meshHost });
46276
+ return { success: true, mesh };
46277
+ } catch (e) {
46278
+ return { success: false, error: e.message };
46279
+ }
46280
+ },
46281
+ update_mesh: async (ctx, args) => {
46282
+ const meshId = typeof args?.meshId === "string" ? args.meshId.trim() : "";
46283
+ if (!meshId) return { success: false, error: "meshId required" };
46284
+ try {
46285
+ const { updateMesh: updateMesh2 } = await Promise.resolve().then(() => (init_mesh_config(), mesh_config_exports));
46286
+ const patch = {};
46287
+ if (typeof args?.name === "string") patch.name = args.name;
46288
+ if (typeof args?.defaultBranch === "string") patch.defaultBranch = args.defaultBranch;
46289
+ if (args?.policy && typeof args.policy === "object" && !Array.isArray(args.policy)) patch.policy = args.policy;
46290
+ if (args?.coordinator && typeof args.coordinator === "object" && !Array.isArray(args.coordinator)) patch.coordinator = args.coordinator;
46291
+ if (args?.meshHost && typeof args.meshHost === "object" && !Array.isArray(args.meshHost)) patch.meshHost = args.meshHost;
46292
+ if (!Object.keys(patch).length) return { success: false, error: "No updates provided" };
46293
+ const mesh = updateMesh2(meshId, patch);
46294
+ if (!mesh) return { success: false, error: "Mesh not found" };
46295
+ ctx.inlineMeshCache.set(meshId, mesh);
46296
+ ctx.invalidateAggregateMeshStatus(meshId);
46297
+ return { success: true, mesh };
46298
+ } catch (e) {
46299
+ return { success: false, error: e.message };
46300
+ }
46301
+ },
46302
+ delete_mesh: async (_ctx, args) => {
46303
+ const meshId = typeof args?.meshId === "string" ? args.meshId.trim() : "";
46304
+ if (!meshId) return { success: false, error: "meshId required" };
46305
+ try {
46306
+ const { deleteMesh: deleteMesh2 } = await Promise.resolve().then(() => (init_mesh_config(), mesh_config_exports));
46307
+ const deleted = deleteMesh2(meshId);
46308
+ return { success: true, deleted };
46309
+ } catch (e) {
46310
+ return { success: false, error: e.message };
46311
+ }
46312
+ },
46313
+ add_mesh_node: async (ctx, args) => {
46314
+ const meshId = typeof args?.meshId === "string" ? args.meshId.trim() : "";
46315
+ const workspace = typeof args?.workspace === "string" ? args.workspace.trim() : "";
46316
+ if (!meshId) return { success: false, error: "meshId required" };
46317
+ if (!workspace) return { success: false, error: "workspace required" };
46318
+ const ownerFailure = await ctx.requireMeshHostMutationOwner(meshId, args?.inlineMesh, "node addition");
46319
+ if (ownerFailure) return ownerFailure;
46320
+ try {
46321
+ const { addNode: addNode2 } = await Promise.resolve().then(() => (init_mesh_config(), mesh_config_exports));
46322
+ const providerPriority = Array.isArray(args?.providerPriority) ? args.providerPriority.map((type) => typeof type === "string" ? type.trim() : "").filter(Boolean) : [];
46323
+ const readOnly = args?.readOnly === true;
46324
+ const providerRoles = normalizeProviderRoles(args?.providerRoles);
46325
+ const policy = {
46326
+ ...readOnly ? { readOnly: true } : {},
46327
+ ...providerPriority.length ? { providerPriority } : {},
46328
+ ...providerRoles.length ? { providerRoles } : {}
46329
+ };
46330
+ const role = normalizeMeshDaemonRole(args?.role);
46331
+ const daemonId = typeof args?.daemonId === "string" && args.daemonId.trim() ? args.daemonId.trim() : void 0;
46332
+ const machineId = typeof args?.machineId === "string" && args.machineId.trim() ? args.machineId.trim() : void 0;
46333
+ const repoRoot = typeof args?.repoRoot === "string" && args.repoRoot.trim() ? args.repoRoot.trim() : void 0;
46334
+ const node = addNode2(meshId, {
46335
+ workspace,
46336
+ ...repoRoot ? { repoRoot } : {},
46337
+ ...daemonId ? { daemonId } : {},
46338
+ ...machineId ? { machineId } : {},
46339
+ ...policy ? { policy } : {},
46340
+ ...role ? { role } : {}
46341
+ });
46342
+ if (!node) return { success: false, error: "Mesh not found" };
46343
+ ctx.invalidateAggregateMeshStatus(meshId);
46344
+ return { success: true, node };
46345
+ } catch (e) {
46346
+ return { success: false, error: e.message };
46347
+ }
46348
+ },
46349
+ update_mesh_node: async (ctx, args) => {
46350
+ const meshId = typeof args?.meshId === "string" ? args.meshId.trim() : "";
46351
+ const nodeId = typeof args?.nodeId === "string" ? args.nodeId.trim() : "";
46352
+ if (!meshId || !nodeId) return { success: false, error: "meshId and nodeId required" };
46353
+ const ownerFailure = await ctx.requireMeshHostMutationOwner(meshId, args?.inlineMesh, "node update");
46354
+ if (ownerFailure) return ownerFailure;
46355
+ try {
46356
+ const { updateNode: updateNode2 } = await Promise.resolve().then(() => (init_mesh_config(), mesh_config_exports));
46357
+ const policy = args?.policy && typeof args.policy === "object" && !Array.isArray(args.policy) ? { ...args.policy } : {};
46358
+ if (Array.isArray(args?.providerPriority)) {
46359
+ const providerPriority = args.providerPriority.map((type) => typeof type === "string" ? type.trim() : "").filter(Boolean);
46360
+ delete policy.provider_priority;
46361
+ if (providerPriority.length) {
46362
+ policy.providerPriority = providerPriority;
46363
+ } else {
46364
+ delete policy.providerPriority;
46365
+ }
46366
+ }
46367
+ if (Array.isArray(args?.providerRoles)) {
46368
+ const providerRoles = normalizeProviderRoles(args.providerRoles);
46369
+ if (providerRoles.length) {
46370
+ policy.providerRoles = providerRoles;
46371
+ } else {
46372
+ delete policy.providerRoles;
46373
+ }
46374
+ }
46375
+ const patch = { policy };
46376
+ if (typeof args?.systemPrompt === "string") {
46377
+ const trimmed = args.systemPrompt.trim();
46378
+ patch.systemPrompt = trimmed || void 0;
46379
+ } else if (args?.systemPrompt === null) {
46380
+ patch.systemPrompt = void 0;
46381
+ }
46382
+ const node = updateNode2(meshId, nodeId, patch);
46383
+ if (!node) return { success: false, error: "Mesh node not found" };
46384
+ ctx.invalidateAggregateMeshStatus(meshId);
46385
+ return { success: true, node };
46386
+ } catch (e) {
46387
+ return { success: false, error: e.message };
46388
+ }
46389
+ },
46390
+ cleanup_mesh_sessions: async (ctx, args) => {
46391
+ const meshId = typeof args?.meshId === "string" ? args.meshId.trim() : "";
46392
+ const nodeId = typeof args?.nodeId === "string" ? args.nodeId.trim() : "";
46393
+ if (!meshId || !nodeId) return { success: false, error: "meshId and nodeId required" };
46394
+ const ownerFailure = await ctx.requireMeshHostMutationOwner(meshId, args?.inlineMesh, "node removal");
46395
+ if (ownerFailure) return ownerFailure;
46396
+ try {
46397
+ const meshRecord = await ctx.getMeshForCommand(meshId, args?.inlineMesh, { preferInline: true });
46398
+ const mesh = meshRecord?.mesh;
46399
+ if (!mesh) return { success: false, error: "Mesh not found" };
46400
+ const node = mesh?.nodes?.find((n) => meshNodeIdMatches(n, nodeId));
46401
+ if (!node) return { success: false, error: `Node '${nodeId}' not found in mesh` };
46402
+ const mode = ctx.normalizeMeshSessionCleanupMode(args?.mode ?? mesh?.policy?.sessionCleanupOnNodeRemove);
46403
+ const sessionIds = Array.isArray(args?.sessionIds) ? args.sessionIds.map((id) => typeof id === "string" ? id.trim() : "").filter(Boolean) : void 0;
46404
+ const result = await ctx.cleanupMeshSessions({
46405
+ meshId,
46406
+ nodeId,
46407
+ node,
46408
+ mode,
46409
+ sessionIds,
46410
+ dryRun: args?.dryRun === true,
46411
+ source: "mesh_cleanup_sessions"
46412
+ });
46413
+ return result;
46414
+ } catch (e) {
46415
+ return { success: false, error: e.message };
46416
+ }
46417
+ },
46418
+ remove_mesh_node: async (ctx, args) => {
46419
+ const meshId = typeof args?.meshId === "string" ? args.meshId.trim() : "";
46420
+ const nodeId = typeof args?.nodeId === "string" ? args.nodeId.trim() : "";
46421
+ if (!meshId || !nodeId) return { success: false, error: "meshId and nodeId required" };
46422
+ try {
46423
+ const meshRecord = await ctx.getMeshForCommand(meshId, args?.inlineMesh, { preferInline: true });
46424
+ const mesh = meshRecord?.mesh;
46425
+ const node = mesh?.nodes?.find((n) => meshNodeIdMatches(n, nodeId));
46426
+ if (node && !args?._meshDirectDispatch && node.isLocalWorktree !== true && args?.force !== true) {
46427
+ const nodeDaemonId = typeof node.daemonId === "string" ? node.daemonId.trim() : "";
46428
+ const nodeMachineId = readMeshNodeMachineId(node) || "";
46429
+ const selfDaemonId = ctx.deps.statusInstanceId || "";
46430
+ const selfMachineId = (() => {
46431
+ try {
46432
+ return loadConfig().machineId || "";
46433
+ } catch {
46434
+ return "";
46435
+ }
46436
+ })();
46437
+ const isCoordinatorBaseNode = !!selfDaemonId && (nodeDaemonId === selfDaemonId || nodeMachineId === selfDaemonId) || !!selfMachineId && (nodeDaemonId === selfMachineId || nodeMachineId === selfMachineId);
46438
+ if (isCoordinatorBaseNode) {
46439
+ return {
46440
+ success: false,
46441
+ removed: false,
46442
+ code: "mesh_remove_coordinator_base_node_protected",
46443
+ error: `Refusing to remove the coordinator's own base node '${typeof node.workspace === "string" ? node.workspace : nodeId}'. It is the local non-worktree node bound to this coordinator daemon; removing it breaks live mesh membership and forces a restart.`,
46444
+ recoveryHint: "Remove worktree clone nodes instead, or pass force:true only if you are intentionally tearing down this mesh and accept that the coordinator must be re-registered/restarted."
46445
+ };
46446
+ }
46447
+ }
46448
+ const sessionCleanupMode = ctx.normalizeMeshSessionCleanupMode(
46449
+ args?.sessionCleanupMode ?? args?.session_cleanup_mode ?? mesh?.policy?.sessionCleanupOnNodeRemove
46450
+ );
46451
+ const explicitSessionIds = Array.isArray(args?.sessionIds) ? args.sessionIds.filter((v) => typeof v === "string" && v.trim().length > 0).map((v) => v.trim()) : void 0;
46452
+ let sessionCleanup;
46453
+ if (node && sessionCleanupMode !== "preserve") {
46454
+ sessionCleanup = await ctx.cleanupMeshSessions({
46455
+ meshId,
46456
+ nodeId,
46457
+ node,
46458
+ mode: sessionCleanupMode,
46459
+ ...explicitSessionIds && explicitSessionIds.length > 0 ? { sessionIds: explicitSessionIds } : {},
46460
+ source: "mesh_remove_node"
46461
+ });
46462
+ if (sessionCleanup.success === false) return { success: false, removed: false, sessionCleanup };
46463
+ }
46464
+ let worktreeCleanup;
46465
+ if (node?.isLocalWorktree) {
46466
+ const nodeDaemonId = typeof node.daemonId === "string" ? node.daemonId.trim() : void 0;
46467
+ const isRemoteWorktree = nodeDaemonId && !daemonIdsEquivalent(nodeDaemonId, ctx.deps.statusInstanceId) && ctx.deps.dispatchMeshCommand && !args?._meshDirectDispatch;
46468
+ if (isRemoteWorktree) {
46469
+ const forwarded = await ctx.deps.dispatchMeshCommand(nodeDaemonId, "remove_mesh_node", {
46470
+ ...typeof args === "object" && args !== null ? args : {},
46471
+ _meshDirectDispatch: true
46472
+ });
46473
+ return forwarded ?? { success: false, error: "no response from remote node" };
46474
+ }
46475
+ const cleanupResult = await ctx.cleanupLocalWorktreeNode({ mesh, node, nodeId, force: args?.force === true });
46476
+ if (cleanupResult.success === false) {
46477
+ return {
46478
+ success: false,
46479
+ removed: false,
46480
+ code: cleanupResult.code,
46481
+ error: cleanupResult.error,
46482
+ recoveryHint: cleanupResult.recoveryHint,
46483
+ ...sessionCleanup ? { sessionCleanup } : {},
46484
+ worktreeCleanup: cleanupResult
46485
+ };
46486
+ }
46487
+ worktreeCleanup = cleanupResult;
46488
+ }
46489
+ let removed = false;
46490
+ if (meshRecord?.inline) {
46491
+ removed = ctx.removeInlineMeshNode(meshId, mesh, nodeId);
46492
+ if (removed) ctx.invalidateAggregateMeshStatus(meshId);
46493
+ if (!removed && !node) removed = true;
46494
+ } else {
46495
+ const { removeNode: removeNode2 } = await Promise.resolve().then(() => (init_mesh_config(), mesh_config_exports));
46496
+ removed = removeNode2(meshId, nodeId);
46497
+ if (!removed && !node) removed = true;
46498
+ if (removed) ctx.invalidateAggregateMeshStatus(meshId);
46499
+ }
46500
+ if (removed) {
46501
+ try {
46502
+ const { appendLedgerEntry: appendLedgerEntry2 } = await Promise.resolve().then(() => (init_mesh_ledger(), mesh_ledger_exports));
46503
+ appendLedgerEntry2(meshId, {
46504
+ kind: "node_removed",
46505
+ nodeId,
46506
+ payload: {
46507
+ worktree: !!node?.isLocalWorktree,
46508
+ sessionCleanupMode,
46509
+ workspace: typeof node?.workspace === "string" ? node.workspace : void 0,
46510
+ daemonId: typeof node?.daemonId === "string" ? node.daemonId : void 0,
46511
+ worktreeBranch: typeof node?.worktreeBranch === "string" ? node.worktreeBranch : void 0,
46512
+ worktreeCleanupFallback: typeof worktreeCleanup?.fallback === "string" ? worktreeCleanup.fallback : void 0,
46513
+ forced: worktreeCleanup?.forced === true ? true : void 0,
46514
+ forceFallbackReason: typeof worktreeCleanup?.reason === "string" ? worktreeCleanup.reason : void 0
46515
+ }
46516
+ });
46517
+ } catch {
46518
+ }
46519
+ }
46520
+ const residueWarning = worktreeCleanup?.residue === true && typeof worktreeCleanup?.residueWarning === "string" ? worktreeCleanup.residueWarning : void 0;
46521
+ return {
46522
+ success: true,
46523
+ removed,
46524
+ ...residueWarning ? { residueWarning } : {},
46525
+ ...sessionCleanup ? { sessionCleanup } : {},
46526
+ ...worktreeCleanup ? { worktreeCleanup } : {}
46527
+ };
46528
+ } catch (e) {
46529
+ return { success: false, error: e.message };
46530
+ }
46531
+ },
46532
+ clone_mesh_node: async (ctx, args) => {
46533
+ const meshId = typeof args?.meshId === "string" ? args.meshId.trim() : "";
46534
+ const sourceNodeId = typeof args?.sourceNodeId === "string" ? args.sourceNodeId.trim() : "";
46535
+ const branch = typeof args?.branch === "string" ? args.branch.trim() : "";
46536
+ const baseBranch = typeof args?.baseBranch === "string" ? args.baseBranch.trim() : void 0;
46537
+ if (!meshId) return { success: false, error: "meshId required" };
46538
+ if (!sourceNodeId) return { success: false, error: "sourceNodeId required" };
46539
+ if (!branch) return { success: false, error: "branch required" };
46540
+ const ownerFailure = await ctx.requireMeshHostMutationOwner(meshId, args?.inlineMesh, "worktree clone");
46541
+ if (ownerFailure) return ownerFailure;
46542
+ try {
46543
+ const meshRecord = await ctx.getMeshForCommand(meshId, args?.inlineMesh, { preferInline: true });
46544
+ const mesh = meshRecord?.mesh;
46545
+ if (!mesh) return { success: false, error: "Mesh not found" };
46546
+ const sourceNode = mesh.nodes?.find((n) => meshNodeIdMatches(n, sourceNodeId));
46547
+ if (!sourceNode) return { success: false, error: `Source node '${sourceNodeId}' not found in mesh` };
46548
+ const sourceDaemonId = typeof sourceNode.daemonId === "string" ? sourceNode.daemonId.trim() : void 0;
46549
+ if (sourceDaemonId && !daemonIdsEquivalent(sourceDaemonId, ctx.deps.statusInstanceId) && ctx.deps.dispatchMeshCommand && !args?._meshDirectDispatch) {
46550
+ const forwarded = await ctx.deps.dispatchMeshCommand(sourceDaemonId, "clone_mesh_node", {
46551
+ ...typeof args === "object" && args !== null ? args : {},
46552
+ _meshDirectDispatch: true
46553
+ });
46554
+ return forwarded ?? { success: false, error: "no response from remote node" };
46555
+ }
46556
+ const repoRoot = sourceNode.repoRoot || sourceNode.workspace;
46557
+ const { createWorktree: createWorktree2 } = await Promise.resolve().then(() => (init_git_worktree(), git_worktree_exports));
46558
+ const result = await createWorktree2({
46559
+ repoRoot,
46560
+ branch,
46561
+ baseBranch,
46562
+ meshName: mesh.name
46563
+ });
46564
+ let node;
46565
+ if (meshRecord.inline) {
46566
+ const { randomUUID: randomUUID15 } = await import("crypto");
46567
+ node = {
46568
+ id: `node_${randomUUID15().replace(/-/g, "")}`,
46569
+ workspace: result.worktreePath,
46570
+ repoRoot: result.worktreePath,
46571
+ daemonId: sourceNode.daemonId,
46572
+ machineId: sourceNode.machineId ?? sourceNode.machine_id,
46573
+ userOverrides: { ...sourceNode.userOverrides || {} },
46574
+ policy: { ...sourceNode.policy || {} },
46575
+ isLocalWorktree: true,
46576
+ worktreeBranch: result.branch,
46577
+ clonedFromNodeId: sourceNodeId
46578
+ };
46579
+ ctx.updateInlineMeshNode(meshId, mesh, node);
46580
+ } else {
46581
+ const { addNode: addNode2 } = await Promise.resolve().then(() => (init_mesh_config(), mesh_config_exports));
46582
+ node = addNode2(meshId, {
46583
+ workspace: result.worktreePath,
46584
+ repoRoot: result.worktreePath,
46585
+ daemonId: sourceNode.daemonId,
46586
+ machineId: sourceNode.machineId ?? sourceNode.machine_id,
46587
+ userOverrides: { ...sourceNode.userOverrides || {} },
46588
+ isLocalWorktree: true,
46589
+ worktreeBranch: result.branch,
46590
+ clonedFromNodeId: sourceNodeId,
46591
+ policy: { ...sourceNode.policy || {} }
46592
+ });
46593
+ if (!node) return { success: false, error: "Failed to register worktree node" };
46594
+ const inlineForReconcile = ctx.getCachedInlineMesh(meshId);
46595
+ if (inlineForReconcile) ctx.updateInlineMeshNode(meshId, inlineForReconcile, node);
46596
+ ctx.invalidateAggregateMeshStatus(meshId);
46597
+ }
46598
+ const persistWorktreeSetupState = async (bootstrapState2) => {
46599
+ node.worktreeBootstrap = bootstrapState2;
46600
+ if (meshRecord.inline) {
46601
+ ctx.updateInlineMeshNode(meshId, mesh, node);
46602
+ return;
46603
+ }
46604
+ try {
46605
+ const { updateNode: updateNode2 } = await Promise.resolve().then(() => (init_mesh_config(), mesh_config_exports));
46606
+ updateNode2(meshId, node.id, { worktreeBootstrap: bootstrapState2 });
46607
+ ctx.invalidateAggregateMeshStatus(meshId);
46608
+ } catch {
46609
+ }
46610
+ };
46611
+ const appendCloneLedger = async (initSubmodules2, bootstrapState2) => {
46612
+ try {
46613
+ const { appendLedgerEntry: appendLedgerEntry2 } = await Promise.resolve().then(() => (init_mesh_ledger(), mesh_ledger_exports));
46614
+ appendLedgerEntry2(meshId, {
46615
+ kind: "node_cloned",
46616
+ nodeId: node.id,
46617
+ payload: {
46618
+ sourceNodeId,
46619
+ branch: result.branch,
46620
+ worktreePath: result.worktreePath,
46621
+ submodulesInitialized: initSubmodules2,
46622
+ worktreeBootstrap: {
46623
+ status: bootstrapState2.status,
46624
+ required: bootstrapState2.required,
46625
+ configSource: bootstrapState2.configSource,
46626
+ configSourceType: bootstrapState2.configSourceType,
46627
+ lastCommand: bootstrapState2.lastCommand,
46628
+ exitCode: bootstrapState2.exitCode
46629
+ }
46630
+ }
46631
+ });
46632
+ } catch {
46633
+ }
46634
+ };
46635
+ const initSubmodules = sourceNode.policy?.initSubmodulesOnClone !== false;
46636
+ const loadedBootstrap = loadMeshWorktreeBootstrapConfig(mesh, result.worktreePath);
46637
+ const runningBootstrapState = {
46638
+ status: "running",
46639
+ required: loadedBootstrap.config?.required !== false,
46640
+ configSource: loadedBootstrap.path || loadedBootstrap.source,
46641
+ configSourceType: loadedBootstrap.sourceType,
46642
+ startedAt: (/* @__PURE__ */ new Date()).toISOString()
46643
+ };
46644
+ await persistWorktreeSetupState(runningBootstrapState);
46645
+ const finishWorktreeSetup = async () => {
46646
+ let submodulesInitialized2 = false;
46647
+ if (initSubmodules) {
46648
+ try {
46649
+ const { runGit: runGit3 } = await Promise.resolve().then(() => (init_git_executor(), git_executor_exports));
46650
+ await runGit3(
46651
+ { workspace: result.worktreePath, repoRoot: result.worktreePath, isGitRepo: true },
46652
+ ["submodule", "update", "--init", "--recursive"],
46653
+ { timeoutMs: 12e4 }
46654
+ );
46655
+ submodulesInitialized2 = true;
46656
+ const sourceWorkspace = sourceNode.repoRoot || sourceNode.workspace;
46657
+ if (sourceWorkspace) {
46658
+ try {
46659
+ const { runGit: rg } = await Promise.resolve().then(() => (init_git_executor(), git_executor_exports));
46660
+ const sourceCtx = { workspace: sourceWorkspace, repoRoot: sourceWorkspace, isGitRepo: true };
46661
+ const worktreeCtx = { workspace: result.worktreePath, repoRoot: result.worktreePath, isGitRepo: true };
46662
+ const sourceStatusOut = await rg(sourceCtx, ["submodule", "status", "oss"], { timeoutMs: 1e4 });
46663
+ const sourceStatusLine = (typeof sourceStatusOut === "string" ? sourceStatusOut : sourceStatusOut?.stdout ?? "").trim();
46664
+ const sourceShaMatch = sourceStatusLine.match(/^[+\- ]?([0-9a-f]{40})/);
46665
+ const sourceSha = sourceShaMatch?.[1];
46666
+ if (sourceSha) {
46667
+ const ossCtx = { workspace: `${result.worktreePath}/oss`, repoRoot: `${result.worktreePath}/oss`, isGitRepo: true };
46668
+ const worktreeOssHeadOut = await rg(ossCtx, ["rev-parse", "HEAD"], { timeoutMs: 1e4 });
46669
+ const worktreeOssSha = (typeof worktreeOssHeadOut === "string" ? worktreeOssHeadOut : worktreeOssHeadOut?.stdout ?? "").trim();
46670
+ if (worktreeOssSha !== sourceSha) {
46671
+ await rg(ossCtx, ["fetch", `${sourceWorkspace}/oss`, "HEAD"], { timeoutMs: 6e4 });
46672
+ await rg(ossCtx, ["checkout", sourceSha], { timeoutMs: 1e4 });
46673
+ await rg(worktreeCtx, ["add", "oss"], { timeoutMs: 1e4 });
46674
+ await rg(worktreeCtx, ["commit", "-m", "chore: sync oss to source node HEAD on clone"], { timeoutMs: 1e4 });
46675
+ console.log(`[mesh] Synced oss submodule to source HEAD ${sourceSha.slice(0, 8)} in worktree`);
46676
+ }
46677
+ }
46678
+ } catch (ossErr) {
46679
+ console.warn("[mesh] oss submodule sync to source HEAD failed (best-effort):", ossErr.message);
46680
+ }
46681
+ }
46682
+ } catch (subErr) {
46683
+ console.warn("[mesh] Submodule init failed for worktree:", subErr.message);
46684
+ }
46685
+ }
46686
+ const bootstrapState2 = await runMeshWorktreeBootstrap(mesh, result.worktreePath);
46687
+ await persistWorktreeSetupState(bootstrapState2);
46688
+ await appendCloneLedger(submodulesInitialized2, bootstrapState2);
46689
+ return { submodulesInitialized: submodulesInitialized2, bootstrapState: bootstrapState2 };
46690
+ };
46691
+ const requestedSetupWaitMs = Number(args?.setupWaitMs ?? args?.bootstrapWaitMs ?? 8e3);
46692
+ const setupWaitMs = Number.isFinite(requestedSetupWaitMs) ? Math.min(Math.max(requestedSetupWaitMs, 0), 14e3) : 8e3;
46693
+ const setupPromise = finishWorktreeSetup();
46694
+ const setupResult = await Promise.race([
46695
+ setupPromise.then((value) => ({ completed: true, value })),
46696
+ new Promise((resolve24) => setTimeout(() => resolve24({ completed: false }), setupWaitMs))
46697
+ ]);
46698
+ const emitBootstrapEvent = (eventStatus2, bootstrapState2, startedAtMs, extraPayload) => {
46699
+ try {
46700
+ const durationMs = Date.now() - startedAtMs;
46701
+ const event = `worktree_${eventStatus2}`;
46702
+ const metadataEvent = {
46703
+ source: "clone_mesh_node_bootstrap",
46704
+ nodeId: node.id,
46705
+ status: eventStatus2,
46706
+ worktreePath: result.worktreePath,
46707
+ durationMs,
46708
+ bootstrapStatus: bootstrapState2.status,
46709
+ ...bootstrapState2.error ? { error: bootstrapState2.error } : {},
46710
+ ...bootstrapState2.exitCode !== void 0 ? { exitCode: bootstrapState2.exitCode } : {},
46711
+ ...extraPayload || {}
46712
+ };
46713
+ if (typeof ctx.deps.instanceManager?.getByCategory === "function") {
46714
+ const forwarded = handleMeshForwardEvent(
46715
+ { instanceManager: ctx.deps.instanceManager },
46716
+ { event, meshId, nodeId: node.id, workspace: result.worktreePath, metadataEvent }
46717
+ );
46718
+ if (forwarded?.success === true) return;
46719
+ }
46720
+ queuePendingMeshCoordinatorEvent({
46721
+ event,
46722
+ meshId,
46723
+ nodeLabel: node.id,
46724
+ nodeId: node.id,
46725
+ workspace: result.worktreePath,
46726
+ metadataEvent,
46727
+ queuedAt: Date.now()
46728
+ });
46729
+ } catch {
46730
+ }
46731
+ };
46732
+ const bootstrapStartedMs = Date.now();
46733
+ if (!setupResult.completed) {
46734
+ setupPromise.then(({ bootstrapState: bootstrapState2 }) => {
46735
+ emitBootstrapEvent("bootstrap_complete", bootstrapState2, bootstrapStartedMs);
46736
+ }).catch((error) => {
46737
+ const failedState = {
46738
+ ...runningBootstrapState,
46739
+ status: "failed",
46740
+ completedAt: (/* @__PURE__ */ new Date()).toISOString(),
46741
+ error: error?.message || String(error)
46742
+ };
46743
+ void persistWorktreeSetupState(failedState);
46744
+ void appendCloneLedger(false, failedState);
46745
+ emitBootstrapEvent("bootstrap_failed", failedState, bootstrapStartedMs, { error: error?.message || String(error) });
46746
+ });
46747
+ return {
46748
+ success: true,
46749
+ async: true,
46750
+ status: "accepted",
46751
+ node,
46752
+ worktreePath: result.worktreePath,
46753
+ branch: result.branch,
46754
+ worktreeBootstrap: runningBootstrapState,
46755
+ worktreeSetup: {
46756
+ status: "running",
46757
+ setupWaitMs,
46758
+ message: "Worktree node is registered; submodule/bootstrap setup is continuing in the background."
46759
+ }
46760
+ };
46761
+ }
46762
+ const { submodulesInitialized, bootstrapState } = setupResult.value;
46763
+ emitBootstrapEvent("bootstrap_complete", bootstrapState, bootstrapStartedMs);
46764
+ return {
46765
+ success: true,
46766
+ node,
46767
+ worktreePath: result.worktreePath,
46768
+ branch: result.branch,
46769
+ submodulesInitialized,
46770
+ worktreeBootstrap: bootstrapState
46771
+ };
46772
+ } catch (e) {
46773
+ return { success: false, error: e.message };
46774
+ }
46775
+ },
46776
+ retry_mesh_node_bootstrap: async (ctx, args) => {
46777
+ const meshId = typeof args?.meshId === "string" ? args.meshId.trim() : "";
46778
+ const nodeId = typeof args?.nodeId === "string" ? args.nodeId.trim() : "";
46779
+ if (!meshId) return { success: false, error: "meshId required" };
46780
+ if (!nodeId) return { success: false, error: "nodeId required" };
46781
+ const ownerFailure = await ctx.requireMeshHostMutationOwner(meshId, args?.inlineMesh, "bootstrap retry");
46782
+ if (ownerFailure) return ownerFailure;
46783
+ try {
46784
+ const meshRecord = await ctx.getMeshForCommand(meshId, args?.inlineMesh, { preferInline: true });
46785
+ const mesh = meshRecord?.mesh;
46786
+ if (!mesh) return { success: false, error: "Mesh not found" };
46787
+ const node = mesh.nodes?.find((n) => meshNodeIdMatches(n, nodeId));
46788
+ if (!node) return { success: false, error: `Node '${nodeId}' not found in mesh` };
46789
+ if (!node.isLocalWorktree) return { success: false, error: "Node is not a local worktree node" };
46790
+ const nodeDaemonId = typeof node.daemonId === "string" ? node.daemonId.trim() : void 0;
46791
+ if (nodeDaemonId && !daemonIdsEquivalent(nodeDaemonId, ctx.deps.statusInstanceId) && ctx.deps.dispatchMeshCommand && !args?._meshDirectDispatch) {
46792
+ const forwarded = await ctx.deps.dispatchMeshCommand(nodeDaemonId, "retry_mesh_node_bootstrap", {
46793
+ ...typeof args === "object" && args !== null ? args : {},
46794
+ _meshDirectDispatch: true
46795
+ });
46796
+ return forwarded ?? { success: false, error: "no response from remote node" };
46797
+ }
46798
+ const currentBootstrap = node.worktreeBootstrap;
46799
+ if (currentBootstrap?.status === "running") {
46800
+ return { success: false, error: "Bootstrap is already running for this node" };
46801
+ }
46802
+ const worktreePath = node.workspace || node.repoRoot;
46803
+ if (!worktreePath) return { success: false, error: "Node has no workspace path" };
46804
+ const loadedBootstrap = loadMeshWorktreeBootstrapConfig(mesh, worktreePath);
46805
+ const runningState = {
46806
+ status: "running",
46807
+ required: loadedBootstrap.config?.required !== false,
46808
+ configSource: loadedBootstrap.path || loadedBootstrap.source,
46809
+ configSourceType: loadedBootstrap.sourceType,
46810
+ startedAt: (/* @__PURE__ */ new Date()).toISOString()
46811
+ };
46812
+ const persistState = async (bootstrapState2) => {
46813
+ node.worktreeBootstrap = bootstrapState2;
46814
+ if (meshRecord.inline) {
46815
+ ctx.updateInlineMeshNode(meshId, mesh, node);
46816
+ return;
46817
+ }
46818
+ try {
46819
+ const { updateNode: updateNode2 } = await Promise.resolve().then(() => (init_mesh_config(), mesh_config_exports));
46820
+ updateNode2(meshId, node.id, { worktreeBootstrap: bootstrapState2 });
46821
+ ctx.invalidateAggregateMeshStatus(meshId);
46822
+ } catch {
46823
+ }
46824
+ };
46825
+ await persistState(runningState);
46826
+ const bootstrapState = await runMeshWorktreeBootstrap(mesh, worktreePath);
46827
+ await persistState(bootstrapState);
46828
+ return { success: true, bootstrapState };
46829
+ } catch (e) {
46830
+ return { success: false, error: e.message };
46831
+ }
46832
+ }
46833
+ };
46834
+
46835
+ // src/commands/med-family/mesh-host-pairing.ts
46836
+ init_mesh_host_ownership();
46837
+ var meshHostPairingHandlers = {
46838
+ get_mesh_host_pairing: async (ctx, args) => {
46839
+ const meshId = typeof args?.meshId === "string" ? args.meshId.trim() : "";
46840
+ if (!meshId) return { success: false, error: "meshId required" };
46841
+ const meshRecord = await ctx.getMeshForCommand(meshId, args?.inlineMesh, { preferInline: true });
46842
+ const mesh = meshRecord?.mesh;
46843
+ if (!mesh) return { success: false, error: "Mesh not found" };
46844
+ const meshHost = resolveMeshHostStatus(mesh);
46845
+ const pairingStatus = meshHost.pairing?.status || "not_configured";
46846
+ return {
46847
+ success: true,
46848
+ code: pairingStatus === "not_configured" ? "mesh_host_pairing_not_configured" : "mesh_host_pairing_pending",
46849
+ meshId,
46850
+ hostAddress: meshHost.hostAddress,
46851
+ meshHost,
46852
+ manualPairing: {
46853
+ status: pairingStatus,
46854
+ joinImplemented: true,
46855
+ protocol: "standalone_command_direct_v1",
46856
+ description: "Standalone manual pairing can save address/token metadata, apply a host join over direct standalone command HTTP or injected mesh command dispatch, and check persisted status. P2P signaling remains outside this slice."
46857
+ }
46858
+ };
46859
+ },
46860
+ configure_mesh_host_pairing: async (ctx, args) => {
46861
+ const meshId = typeof args?.meshId === "string" ? args.meshId.trim() : "";
46862
+ const hostAddress = typeof args?.hostAddress === "string" ? args.hostAddress.trim() : "";
46863
+ const token = typeof args?.token === "string" ? args.token.trim() : "";
46864
+ if (!meshId) return { success: false, error: "meshId required" };
46865
+ if (!hostAddress || !token) return { success: false, error: "hostAddress and token required" };
46866
+ try {
46867
+ const { configureMeshHostPairing: configureMeshHostPairing2 } = await Promise.resolve().then(() => (init_mesh_config(), mesh_config_exports));
46868
+ const configured = configureMeshHostPairing2(meshId, { hostAddress, token });
46869
+ if (!configured) return { success: false, error: "Mesh not found" };
46870
+ ctx.inlineMeshCache.set(meshId, configured.mesh);
46871
+ const meshHost = resolveMeshHostStatus(configured.mesh);
46872
+ return {
46873
+ success: true,
46874
+ code: "mesh_host_pairing_pending",
46875
+ meshId,
46876
+ hostAddress: configured.hostAddress,
46877
+ meshHost,
46878
+ manualPairing: {
46879
+ status: meshHost.pairing?.status || "pairing",
46880
+ joinImplemented: true,
46881
+ protocol: "standalone_command_direct_v1",
46882
+ description: "Manual Mesh Host pairing config was saved locally. Use join_mesh_host_pairing to apply it to the host. Raw token was not persisted."
46883
+ }
46884
+ };
46885
+ } catch (e) {
46886
+ return { success: false, code: "mesh_host_pairing_invalid", meshId, hostAddress, error: e.message };
46887
+ }
46888
+ },
46889
+ create_mesh_host_pairing_token: async (ctx, args) => {
46890
+ const meshId = typeof args?.meshId === "string" ? args.meshId.trim() : "";
46891
+ if (!meshId) return { success: false, error: "meshId required" };
46892
+ try {
46893
+ const { createMeshHostPairingToken: createMeshHostPairingToken2 } = await Promise.resolve().then(() => (init_mesh_config(), mesh_config_exports));
46894
+ const created = createMeshHostPairingToken2(meshId, {
46895
+ token: typeof args?.token === "string" ? args.token : void 0,
46896
+ expiresAt: typeof args?.expiresAt === "string" ? args.expiresAt : void 0
46897
+ });
46898
+ if (!created) return { success: false, error: "Mesh not found" };
46899
+ ctx.inlineMeshCache.set(meshId, created.mesh);
46900
+ ctx.invalidateAggregateMeshStatus(meshId);
46901
+ return {
46902
+ success: true,
46903
+ code: "mesh_host_pairing_token_created",
46904
+ meshId,
46905
+ token: created.token,
46906
+ tokenId: created.tokenId,
46907
+ expiresAt: created.expiresAt,
46908
+ meshHost: resolveMeshHostStatus(created.mesh),
46909
+ warning: "Raw token is returned once and is not persisted; share it with member daemons over a trusted channel."
46910
+ };
46911
+ } catch (e) {
46912
+ return { success: false, code: "mesh_host_pairing_token_invalid", meshId, error: e.message };
46913
+ }
46914
+ },
46915
+ apply_mesh_host_join: async (ctx, args) => {
46916
+ const meshId = typeof args?.meshId === "string" ? args.meshId.trim() : "";
46917
+ const token = typeof args?.token === "string" ? args.token.trim() : "";
46918
+ const memberNode = args?.memberNode && typeof args.memberNode === "object" && !Array.isArray(args.memberNode) ? args.memberNode : null;
46919
+ if (!meshId) return { success: false, error: "meshId required" };
46920
+ if (!token || !memberNode) return { success: false, error: "token and memberNode required" };
46921
+ try {
46922
+ const { applyMeshHostJoinRequest: applyMeshHostJoinRequest2 } = await Promise.resolve().then(() => (init_mesh_config(), mesh_config_exports));
46923
+ const applied = applyMeshHostJoinRequest2(meshId, {
46924
+ token,
46925
+ memberNode,
46926
+ memberMeshId: typeof args?.memberMeshId === "string" ? args.memberMeshId : void 0
46927
+ });
46928
+ if (!applied) return { success: false, error: "Mesh not found" };
46929
+ if (!applied.accepted) {
46930
+ return {
46931
+ success: false,
46932
+ code: "mesh_host_join_rejected",
46933
+ meshId,
46934
+ tokenId: applied.tokenId,
46935
+ meshHost: applied.meshHost ? resolveMeshHostStatus({ meshHost: applied.meshHost }) : void 0,
46936
+ error: applied.reason
46937
+ };
46938
+ }
46939
+ ctx.inlineMeshCache.set(meshId, applied.mesh);
46940
+ ctx.invalidateAggregateMeshStatus(meshId);
46941
+ try {
46942
+ const { appendLedgerEntry: appendLedgerEntry2 } = await Promise.resolve().then(() => (init_mesh_ledger(), mesh_ledger_exports));
46943
+ appendLedgerEntry2(meshId, {
46944
+ kind: "node_joined",
46945
+ nodeId: applied.node.id,
46946
+ payload: { role: "member", tokenId: applied.tokenId, workspace: applied.node.workspace }
46947
+ });
46948
+ } catch {
46949
+ }
46950
+ return {
46951
+ success: true,
46952
+ code: "mesh_host_join_accepted",
46953
+ meshId,
46954
+ node: applied.node,
46955
+ tokenId: applied.tokenId,
46956
+ meshHost: resolveMeshHostStatus(applied.mesh)
46957
+ };
46958
+ } catch (e) {
46959
+ return { success: false, code: "mesh_host_join_failed", meshId, error: e.message };
46960
+ }
46961
+ },
46962
+ join_mesh_host_pairing: async (ctx, args) => {
46963
+ const meshId = typeof args?.meshId === "string" ? args.meshId.trim() : "";
46964
+ const token = typeof args?.token === "string" ? args.token.trim() : "";
46965
+ if (!meshId) return { success: false, error: "meshId required" };
46966
+ if (!token) return { success: false, error: "token required because raw pairing tokens are not persisted" };
46967
+ const meshRecord = await ctx.getMeshForCommand(meshId, args?.inlineMesh, { preferInline: true });
46968
+ const mesh = meshRecord?.mesh;
46969
+ if (!mesh) return { success: false, error: "Mesh not found" };
46970
+ const meshHost = resolveMeshHostStatus(mesh);
46971
+ if (meshHost.role !== "member") {
46972
+ return { success: false, code: "mesh_host_join_not_member", meshId, meshHost, error: "join_mesh_host_pairing must run from a member daemon configured with a Mesh Host address/token." };
46973
+ }
46974
+ try {
46975
+ const { tokenIdForManualPairing: tokenIdForManualPairing2, markMeshHostPairingJoined: markMeshHostPairingJoined2 } = await Promise.resolve().then(() => (init_mesh_config(), mesh_config_exports));
46976
+ const tokenId = tokenIdForManualPairing2(token);
46977
+ if (meshHost.pairing?.tokenId && meshHost.pairing.tokenId !== tokenId) {
46978
+ return { success: false, code: "mesh_host_join_rejected", meshId, tokenId, meshHost, error: "invalid pairing token" };
46979
+ }
46980
+ const memberNode = buildMemberJoinNode(mesh, args, ctx.deps.statusInstanceId);
46981
+ if (!memberNode) return { success: false, error: "member node metadata unavailable" };
46982
+ const hostMeshId = typeof args?.hostMeshId === "string" && args.hostMeshId.trim() ? args.hostMeshId.trim() : meshId;
46983
+ const hostDaemonId = typeof args?.hostDaemonId === "string" && args.hostDaemonId.trim() ? args.hostDaemonId.trim() : meshHost.hostDaemonId;
46984
+ let hostResult;
46985
+ let transport;
46986
+ if (hostDaemonId && ctx.deps.dispatchMeshCommand) {
46987
+ transport = "mesh_command_dispatch";
46988
+ hostResult = await ctx.deps.dispatchMeshCommand(hostDaemonId, "apply_mesh_host_join", {
46989
+ meshId: hostMeshId,
46990
+ token,
46991
+ memberMeshId: meshId,
46992
+ memberNode
46993
+ });
46994
+ } else if (meshHost.hostAddress) {
46995
+ transport = "standalone_http_command";
46996
+ const commandUrl = normalizeStandaloneHostCommandUrl(meshHost.hostAddress);
46997
+ const response = await fetch(commandUrl, {
46998
+ method: "POST",
46999
+ headers: { "Content-Type": "application/json" },
47000
+ body: JSON.stringify({ type: "apply_mesh_host_join", payload: { meshId: hostMeshId, token, memberMeshId: meshId, memberNode } })
47001
+ });
47002
+ hostResult = await response.json().catch(() => ({ success: false, error: `Host returned HTTP ${response.status}` }));
47003
+ if (!response.ok && hostResult?.success !== false) hostResult = { success: false, error: `Host returned HTTP ${response.status}` };
47004
+ } else {
47005
+ return {
47006
+ success: false,
47007
+ code: "mesh_host_join_transport_unavailable",
47008
+ meshId,
47009
+ meshHost,
47010
+ error: "No hostDaemonId dispatch path or hostAddress HTTP command path is available. P2P signaling join is not implemented in this slice."
47011
+ };
47012
+ }
47013
+ if (!hostResult?.success) {
47014
+ return { success: false, code: hostResult?.code || "mesh_host_join_rejected", meshId, meshHost, transport, error: hostResult?.error || "Mesh Host rejected join request", hostResult };
47015
+ }
47016
+ const joined = meshRecord.inline ? null : markMeshHostPairingJoined2(meshId, {
47017
+ tokenId: hostResult.tokenId || tokenId,
47018
+ hostDaemonId: hostResult.meshHost?.hostDaemonId || hostDaemonId,
47019
+ hostNodeId: hostResult.meshHost?.hostNodeId,
47020
+ joinedAt: hostResult.meshHost?.pairing?.joinedAt
47021
+ });
47022
+ if (joined) {
47023
+ ctx.inlineMeshCache.set(meshId, joined.mesh);
47024
+ ctx.invalidateAggregateMeshStatus(meshId);
47025
+ }
47026
+ return {
47027
+ success: true,
47028
+ code: "mesh_host_join_applied",
47029
+ meshId,
47030
+ hostMeshId,
47031
+ transport,
47032
+ node: hostResult.node,
47033
+ tokenId: hostResult.tokenId || tokenId,
47034
+ meshHost: joined ? resolveMeshHostStatus(joined.mesh) : { ...meshHost, pairing: { ...meshHost.pairing || {}, status: "paired", tokenId: hostResult.tokenId || tokenId } },
47035
+ hostResult,
47036
+ manualPairing: {
47037
+ status: "paired",
47038
+ joinImplemented: true,
47039
+ protocol: "standalone_command_direct_v1",
47040
+ description: "Mesh Host accepted the join and local member pairing status was marked paired. P2P runtime signaling remains outside this slice."
47041
+ }
47042
+ };
47043
+ } catch (e) {
47044
+ return { success: false, code: "mesh_host_join_failed", meshId, meshHost, error: e.message };
47045
+ }
47046
+ }
47047
+ };
47048
+
47049
+ // src/commands/med-family/mesh-queue.ts
47050
+ var meshQueueHandlers = {
47051
+ get_mesh_queue: async (_ctx, args) => {
47052
+ const meshId = typeof args?.meshId === "string" ? args.meshId.trim() : "";
47053
+ if (!meshId) return { success: false, error: "meshId required" };
47054
+ try {
47055
+ const { getMeshQueueStats: getMeshQueueStats2, getQueue: getQueue2, describeTaskDependencyState: describeTaskDependencyState2 } = await Promise.resolve().then(() => (init_mesh_work_queue(), mesh_work_queue_exports));
47056
+ const status = Array.isArray(args?.status) ? args.status.map((s2) => typeof s2 === "string" ? s2.trim() : "").filter(Boolean) : void 0;
47057
+ const rawQueue = getQueue2(meshId, { status });
47058
+ const statusById = new Map(getQueue2(meshId).map((task) => [task.id, task.status]));
47059
+ const queue = rawQueue.map((task) => Array.isArray(task.dependsOn) && task.dependsOn.length > 0 ? { ...task, ...describeTaskDependencyState2(task, statusById) } : task);
47060
+ const summary = getMeshQueueStats2(meshId);
47061
+ return {
47062
+ success: true,
47063
+ queue,
47064
+ summary,
47065
+ sourceOfTruth: {
47066
+ kind: "mesh_work_queue_file",
47067
+ activeStatuses: ["pending", "assigned"],
47068
+ historicalStatuses: ["completed", "failed", "cancelled"],
47069
+ notes: "pending/assigned are active work; completed/failed/cancelled are historical records."
47070
+ }
47071
+ };
47072
+ } catch (e) {
47073
+ return { success: false, error: e.message };
47074
+ }
47075
+ },
47076
+ cancel_mesh_queue_task: async (ctx, args) => {
47077
+ const meshId = typeof args?.meshId === "string" ? args.meshId.trim() : "";
47078
+ const taskId = typeof args?.taskId === "string" ? args.taskId.trim() : "";
47079
+ if (!meshId || !taskId) return { success: false, error: "meshId and taskId required" };
47080
+ const ownerFailure = await ctx.requireMeshHostMutationOwner(meshId, args?.inlineMesh, "queue cancellation");
47081
+ if (ownerFailure) return ownerFailure;
47082
+ try {
47083
+ const { cancelTask: cancelTask2 } = await Promise.resolve().then(() => (init_mesh_work_queue(), mesh_work_queue_exports));
47084
+ const reason = typeof args?.reason === "string" ? args.reason : void 0;
47085
+ const task = cancelTask2(meshId, taskId, { reason });
47086
+ if (!task) return { success: false, error: `Queue task '${taskId}' not found` };
47087
+ return { success: true, task };
47088
+ } catch (e) {
47089
+ return { success: false, error: e.message };
47090
+ }
47091
+ },
47092
+ requeue_mesh_queue_task: async (ctx, args) => {
47093
+ const meshId = typeof args?.meshId === "string" ? args.meshId.trim() : "";
47094
+ const taskId = typeof args?.taskId === "string" ? args.taskId.trim() : "";
47095
+ if (!meshId || !taskId) return { success: false, error: "meshId and taskId required" };
47096
+ const ownerFailure = await ctx.requireMeshHostMutationOwner(meshId, args?.inlineMesh, "queue requeue");
47097
+ if (ownerFailure) return ownerFailure;
47098
+ try {
47099
+ const { requeueTask: requeueTask2 } = await Promise.resolve().then(() => (init_mesh_work_queue(), mesh_work_queue_exports));
47100
+ const task = requeueTask2(meshId, taskId, {
47101
+ reason: typeof args?.reason === "string" ? args.reason : void 0,
47102
+ targetNodeId: typeof args?.targetNodeId === "string" ? args.targetNodeId.trim() : void 0,
47103
+ targetSessionId: typeof args?.targetSessionId === "string" ? args.targetSessionId.trim() : void 0,
47104
+ clearTargetNode: args?.clearTargetNode === true,
47105
+ clearTargetSession: args?.clearTargetSession !== false
47106
+ });
47107
+ if (!task) return { success: false, error: `Queue task '${taskId}' not found` };
47108
+ return { success: true, task };
47109
+ } catch (e) {
47110
+ return { success: false, error: e.message };
47111
+ }
47112
+ },
47113
+ trigger_mesh_queue: async (ctx, args) => {
47114
+ const meshId = typeof args?.meshId === "string" ? args.meshId.trim() : "";
47115
+ if (!meshId) return { success: false, error: "meshId required" };
47116
+ const ownerFailure = await ctx.requireMeshHostMutationOwner(meshId, args?.inlineMesh, "queue trigger");
47117
+ if (ownerFailure) return ownerFailure;
47118
+ try {
47119
+ const { triggerMeshQueue: triggerMeshQueue2, tryAssignQueueTask: tryAssignQueueTask2 } = await Promise.resolve().then(() => (init_mesh_events(), mesh_events_exports));
47120
+ const preferredNodeId = typeof args?.preferredNodeId === "string" ? args.preferredNodeId.trim() : "";
47121
+ if (preferredNodeId) {
47122
+ const cliInstances = ctx.deps.instanceManager.getByCategory("cli");
47123
+ const sorted = [...cliInstances].sort((a, b) => {
47124
+ const aSettings = a.getState().settings || {};
47125
+ const bSettings = b.getState().settings || {};
47126
+ const aNode = readStringValue(aSettings.meshNodeId, aSettings.nodeId);
47127
+ const bNode = readStringValue(bSettings.meshNodeId, bSettings.nodeId);
47128
+ return (aNode === preferredNodeId ? -1 : 0) - (bNode === preferredNodeId ? -1 : 0);
47129
+ });
47130
+ for (const inst of sorted) {
47131
+ const state = inst.getState();
47132
+ const settings = state.settings || {};
47133
+ const nodeId = readStringValue(settings.meshNodeId, settings.nodeId);
47134
+ if (!nodeId || nodeId !== preferredNodeId) continue;
47135
+ const meshNodeFor = readStringValue(settings.meshNodeFor);
47136
+ if (meshNodeFor !== meshId) continue;
47137
+ const status = (readStringValue(state.status) || "").toLowerCase();
47138
+ if (status !== "idle") continue;
47139
+ const sessionId = typeof state.instanceId === "string" ? state.instanceId : "";
47140
+ const providerType = readStringValue(state.type, settings.providerType) || "";
47141
+ if (sessionId && providerType) {
47142
+ tryAssignQueueTask2(ctx.deps, meshId, nodeId, sessionId, providerType);
47143
+ break;
47144
+ }
47145
+ }
47146
+ }
47147
+ const trigger = await triggerMeshQueue2(ctx.deps, meshId);
47148
+ return { success: true, trigger };
47149
+ } catch (e) {
47150
+ return { success: false, error: e.message };
47151
+ }
47152
+ }
47153
+ };
47154
+
47155
+ // src/commands/med-family/fast-forward.ts
47156
+ init_dist();
47157
+ init_mesh_fast_forward();
47158
+
47159
+ // src/mesh/mesh-init.ts
47160
+ var import_fs16 = require("fs");
47161
+ var import_path11 = require("path");
47162
+ var MESH_INIT_REFINE_CONFIG_PATH = MESH_REFINE_CONFIG_LOCATIONS[0];
47163
+ var MESH_INIT_WORKTREE_BOOTSTRAP_CONFIG_PATH = MESH_WORKTREE_BOOTSTRAP_CONFIG_LOCATIONS[0];
47164
+ var CANDIDATE_STALE_INPUTS = [
47165
+ "package-lock.json",
47166
+ "pnpm-lock.yaml",
47167
+ "yarn.lock",
47168
+ "bun.lockb",
47169
+ "Cargo.lock",
47170
+ "go.sum",
47171
+ "poetry.lock",
47172
+ "requirements.txt"
47173
+ ];
47174
+ function writeConfigFile(workspace, relativePath, config) {
47175
+ const target = (0, import_path11.join)(workspace, relativePath);
47176
+ (0, import_fs16.mkdirSync)((0, import_path11.dirname)(target), { recursive: true });
47177
+ (0, import_fs16.writeFileSync)(target, `${JSON.stringify(config, null, 2)}
47178
+ `, "utf-8");
47179
+ return target;
47180
+ }
47181
+ function suggestMeshWorktreeBootstrapConfig(workspace) {
47182
+ const commands = [];
47183
+ const hasPackageJson = (0, import_fs16.existsSync)((0, import_path11.join)(workspace, "package.json"));
47184
+ const hasNpmLock = (0, import_fs16.existsSync)((0, import_path11.join)(workspace, "package-lock.json"));
47185
+ if (hasPackageJson) {
47186
+ commands.push(
47187
+ hasNpmLock ? { command: "npm", args: ["ci"] } : { command: "npm", args: ["install"] }
47188
+ );
47189
+ }
47190
+ const staleInputs = CANDIDATE_STALE_INPUTS.filter((relative5) => (0, import_fs16.existsSync)((0, import_path11.join)(workspace, relative5)));
47191
+ if (!commands.length) {
47192
+ return { commands, staleInputs };
47193
+ }
47194
+ return {
47195
+ commands,
47196
+ staleInputs,
47197
+ suggestedConfig: {
47198
+ version: 1,
47199
+ enabled: true,
47200
+ runOnClone: true,
47201
+ required: false,
47202
+ commands,
47203
+ ...staleInputs.length ? { staleInputs } : {}
47204
+ }
47205
+ };
47206
+ }
47207
+ var PROVIDER_PRIORITY_PREFERENCE = ["claude-cli", "codex-cli", "gemini-cli"];
47208
+ function suggestNodeProviderPriority(detected) {
47209
+ const installed = detected.filter((cli) => cli.installed);
47210
+ const installedIds = installed.map((cli) => cli.id);
47211
+ const preferred = PROVIDER_PRIORITY_PREFERENCE.filter((id) => installedIds.includes(id));
47212
+ const rest = installedIds.filter((id) => !preferred.includes(id));
47213
+ const providerPriority = [...preferred, ...rest];
47214
+ return {
47215
+ providerPriority,
47216
+ installedProviders: installed.map((cli) => ({
47217
+ id: cli.id,
47218
+ displayName: cli.displayName,
47219
+ ...cli.version ? { version: cli.version } : {}
47220
+ }))
47221
+ };
47222
+ }
47223
+ function runMeshInit(mesh, workspace, detected, options = {}) {
47224
+ const write = options.write === true;
47225
+ const overwrite = options.overwrite === true;
47226
+ const refine = applyConfigSuggestion({
47227
+ workspace,
47228
+ relativePath: MESH_INIT_REFINE_CONFIG_PATH,
47229
+ existing: loadMeshRefineConfig(mesh, workspace).config,
47230
+ suggestedConfig: suggestMeshRefineConfig(mesh, workspace).suggestedConfig,
47231
+ validate: (config) => validateMeshRefineConfig(config, MESH_INIT_REFINE_CONFIG_PATH).valid,
47232
+ write,
47233
+ overwrite
47234
+ });
47235
+ const bootstrapSuggestion = suggestMeshWorktreeBootstrapConfig(workspace);
47236
+ const worktreeBootstrap = applyConfigSuggestion({
47237
+ workspace,
47238
+ relativePath: MESH_INIT_WORKTREE_BOOTSTRAP_CONFIG_PATH,
47239
+ existing: loadMeshWorktreeBootstrapConfig(mesh, workspace).config,
47240
+ suggestedConfig: bootstrapSuggestion.suggestedConfig,
47241
+ validate: (config) => validateMeshWorktreeBootstrapConfig(config, MESH_INIT_WORKTREE_BOOTSTRAP_CONFIG_PATH).valid,
47242
+ write,
47243
+ overwrite
47244
+ });
47245
+ const providers = suggestNodeProviderPriority(detected);
47246
+ return {
47247
+ success: true,
47248
+ workspace,
47249
+ dryRun: !write,
47250
+ refine,
47251
+ worktreeBootstrap,
47252
+ providers,
47253
+ note: write ? "Configs written to disk are the execution source of truth; suggestions are scaffold and only take effect once saved. providerPriority is a recommendation \u2014 apply it to node policy via clone/policy update." : "Dry-run: no files written. Re-run with write=true to persist the suggested configs. Heuristic suggestions never execute until saved as repo config."
47254
+ };
47255
+ }
47256
+ function applyConfigSuggestion(input) {
47257
+ const { workspace, relativePath, existing, suggestedConfig, validate, write, overwrite } = input;
47258
+ const absolute = (0, import_path11.join)(workspace, relativePath);
47259
+ if (existing !== void 0 && !overwrite) {
47260
+ return { path: absolute, relativePath, written: false, skippedReason: "already_exists", config: existing };
47261
+ }
47262
+ if (!suggestedConfig || !validate(suggestedConfig)) {
47263
+ return { path: absolute, relativePath, written: false, skippedReason: "no_suggestion" };
47264
+ }
47265
+ if (!write) {
47266
+ return { path: absolute, relativePath, written: false, config: suggestedConfig };
47267
+ }
47268
+ const writtenPath = writeConfigFile(workspace, relativePath, suggestedConfig);
47269
+ return { path: writtenPath, relativePath, written: true, config: suggestedConfig };
47270
+ }
47271
+
47272
+ // src/commands/med-family/fast-forward.ts
47273
+ init_cli_detector();
47274
+ var fastForwardHandlers = {
47275
+ mesh_init: async (ctx, args) => {
47276
+ const workspace = typeof args?.workspace === "string" && args.workspace.trim() ? args.workspace.trim() : process.cwd();
47277
+ const mesh = args?.inlineMesh || {};
47278
+ try {
47279
+ const detected = await detectCLIs(ctx.deps.providerLoader, { includeVersion: true });
47280
+ return { ...runMeshInit(mesh, workspace, detected, {
47281
+ write: args?.write === true,
47282
+ overwrite: args?.overwrite === true
47283
+ }) };
47284
+ } catch (e) {
47285
+ return { success: false, error: e?.message || String(e) };
47286
+ }
47287
+ },
47288
+ plan_mesh_refine_node: async (ctx, args) => {
47289
+ const meshId = typeof args?.meshId === "string" ? args.meshId.trim() : "";
47290
+ const nodeId = typeof args?.nodeId === "string" ? args.nodeId.trim() : "";
47291
+ if (!meshId || !nodeId) return { success: false, error: "meshId and nodeId required" };
47292
+ const meshRecord = await ctx.getMeshForCommand(meshId, args?.inlineMesh, { preferInline: true });
47293
+ const mesh = meshRecord?.mesh;
47294
+ const node = mesh?.nodes?.find((n) => meshNodeIdMatches(n, nodeId));
47295
+ if (!node?.workspace) return { success: false, error: `Node '${nodeId}' workspace not found` };
47296
+ return {
47297
+ success: true,
47298
+ dryRun: true,
47299
+ nodeId,
47300
+ workspace: node.workspace,
47301
+ validationPlan: buildMeshRefineValidationPlan(mesh, node.workspace),
47302
+ mergeWillRun: false,
47303
+ cleanupWillRun: false
47304
+ };
47305
+ },
47306
+ fast_forward_mesh_node: async (ctx, args) => {
47307
+ const meshId = typeof args?.meshId === "string" ? args.meshId.trim() : "";
47308
+ const nodeId = typeof args?.nodeId === "string" ? args.nodeId.trim() : "";
47309
+ let workspace = typeof args?.workspace === "string" ? args.workspace.trim() : "";
47310
+ let submoduleIgnorePaths = Array.isArray(args?.submoduleIgnorePaths) ? args.submoduleIgnorePaths.filter((value) => typeof value === "string") : void 0;
47311
+ let nodeDaemonId;
47312
+ let allowAutoPublishSubmoduleMainCommits = false;
47313
+ if (meshId && nodeId) {
47314
+ const meshRecord = await ctx.getMeshForCommand(meshId, args?.inlineMesh, { preferInline: true });
47315
+ const mesh = meshRecord?.mesh;
47316
+ const node = mesh?.nodes?.find((n) => meshNodeIdMatches(n, nodeId));
47317
+ if (!workspace) {
47318
+ workspace = typeof node?.workspace === "string" ? node.workspace.trim() : "";
47319
+ }
47320
+ if (!submoduleIgnorePaths && Array.isArray(node?.policy?.submoduleIgnorePaths)) {
47321
+ submoduleIgnorePaths = node.policy.submoduleIgnorePaths.filter((value) => typeof value === "string");
47322
+ }
47323
+ allowAutoPublishSubmoduleMainCommits = mesh?.policy?.allowAutoPublishSubmoduleMainCommits === true;
47324
+ nodeDaemonId = typeof node?.daemonId === "string" ? node.daemonId.trim() : void 0;
47325
+ }
47326
+ const selfDaemonId = ctx.deps.statusInstanceId;
47327
+ const isRemote = nodeDaemonId && selfDaemonId && !daemonIdsEquivalent(nodeDaemonId, selfDaemonId);
47328
+ if (isRemote && ctx.deps.dispatchMeshCommand && !args?._meshDirectDispatch) {
47329
+ const forwarded = await ctx.deps.dispatchMeshCommand(nodeDaemonId, "fast_forward_mesh_node", {
47330
+ ...typeof args === "object" && args !== null ? args : {},
47331
+ workspace,
47332
+ _meshDirectDispatch: true
47333
+ });
47334
+ return forwarded ?? { success: false, error: "no response from remote node" };
47335
+ }
47336
+ const result = await fastForwardMeshNode({
47337
+ meshId: meshId || void 0,
47338
+ nodeId: nodeId || void 0,
47339
+ workspace,
47340
+ branch: typeof args?.branch === "string" ? args.branch : void 0,
47341
+ execute: args?.execute === true,
47342
+ dryRun: args?.dryRun === true,
47343
+ updateSubmodules: args?.updateSubmodules === true,
47344
+ submoduleIgnorePaths,
47345
+ mode: args?.mode === "push" ? "push" : "merge",
47346
+ pushSubmodules: args?.pushSubmodules === true,
47347
+ allowAutoPublishSubmoduleMainCommits
47348
+ });
47349
+ return result;
47350
+ },
47351
+ refine_mesh_node: async (ctx, args) => {
47352
+ const meshId = typeof args?.meshId === "string" ? args.meshId.trim() : "";
47353
+ const nodeId = typeof args?.nodeId === "string" ? args.nodeId.trim() : "";
47354
+ if (!meshId || !nodeId) return { success: false, error: "meshId and nodeId required" };
47355
+ {
47356
+ const meshRecordForForward = await ctx.getMeshForCommand(meshId, args?.inlineMesh, { preferInline: true });
47357
+ const forwardNode = meshRecordForForward?.mesh?.nodes?.find((n) => meshNodeIdMatches(n, nodeId));
47358
+ const nodeDaemonId = typeof forwardNode?.daemonId === "string" ? forwardNode.daemonId.trim() : void 0;
47359
+ const selfDaemonId = ctx.deps.statusInstanceId;
47360
+ const isRemote = nodeDaemonId && selfDaemonId && !daemonIdsEquivalent(nodeDaemonId, selfDaemonId);
47361
+ if (isRemote && ctx.deps.dispatchMeshCommand && !args?._meshDirectDispatch) {
47362
+ const callerCoordinatorDaemonId = typeof args?.coordinatorDaemonId === "string" && args.coordinatorDaemonId.trim() ? args.coordinatorDaemonId.trim() : void 0;
47363
+ const forwarded = await ctx.deps.dispatchMeshCommand(nodeDaemonId, "refine_mesh_node", {
47364
+ ...typeof args === "object" && args !== null ? args : {},
47365
+ coordinatorDaemonId: callerCoordinatorDaemonId || selfDaemonId,
47366
+ _meshDirectDispatch: true
47367
+ });
47368
+ return forwarded ?? { success: false, error: "no response from remote node" };
47369
+ }
47370
+ }
47371
+ const isDryRun = args?.dryRun !== false && args?.execute !== true;
47372
+ if (isDryRun) {
47373
+ const meshRecord = await ctx.getMeshForCommand(meshId, args?.inlineMesh, { preferInline: true });
47374
+ const mesh = meshRecord?.mesh;
47375
+ const node = mesh?.nodes?.find((n) => meshNodeIdMatches(n, nodeId));
47376
+ if (!node?.workspace) return { success: false, error: `Node '${nodeId}' workspace not found` };
47377
+ return {
47378
+ success: true,
47379
+ dryRun: true,
47380
+ nodeId,
47381
+ workspace: node.workspace,
47382
+ validationPlan: buildMeshRefineValidationPlan(mesh, node.workspace),
47383
+ mergeWillRun: false,
47384
+ cleanupWillRun: false,
47385
+ hint: "Dry-run only \u2014 no merge/push/cleanup performed. Re-invoke with execute:true to converge this node."
47386
+ };
47387
+ }
47388
+ return ctx.startMeshRefineJob(meshId, nodeId, args);
47389
+ },
47390
+ batch_refine_mesh_nodes: async (ctx, args) => {
47391
+ const meshId = typeof args?.meshId === "string" ? args.meshId.trim() : "";
47392
+ if (!meshId) return { success: false, error: "meshId required" };
47393
+ const requestedNodeIds = Array.isArray(args?.nodeIds) ? args.nodeIds.filter((v) => typeof v === "string" && v.trim().length > 0).map((v) => v.trim()) : void 0;
47394
+ const isDryRun = args?.dryRun !== false && args?.execute !== true;
47395
+ if (isDryRun) return ctx.batchRefineMeshNodes(meshId, requestedNodeIds, args);
47396
+ return ctx.startMeshRefineBatchJob(meshId, requestedNodeIds, args);
47397
+ }
47398
+ };
47399
+
47400
+ // src/commands/med-family/index.ts
47401
+ var medFamilyRegistry = new Map(
47402
+ Object.entries({
47403
+ ...cliAgentHandlers,
47404
+ ...ideHandlers,
47405
+ ...meshCrudHandlers,
47406
+ ...meshHostPairingHandlers,
47407
+ ...meshQueueHandlers,
47408
+ ...fastForwardHandlers
47409
+ })
47410
+ );
47411
+
47412
+ // src/commands/router.ts
47413
+ init_config();
47414
+ init_cli_detector();
45887
47415
  init_git_status();
45888
47416
  init_dist();
45889
47417
  init_logger();
@@ -46039,9 +47567,7 @@ init_mesh_coordinator();
46039
47567
  init_coordinator_registry();
46040
47568
  init_mesh_events();
46041
47569
  init_mesh_routing();
46042
- init_mesh_events_utils();
46043
47570
  init_mesh_host_ownership();
46044
- init_mesh_fast_forward();
46045
47571
 
46046
47572
  // src/mesh/mesh-refine-batch.ts
46047
47573
  var import_node_child_process4 = require("child_process");
@@ -46214,121 +47740,6 @@ function buildPreviewFreshness(repoRoot) {
46214
47740
 
46215
47741
  // src/commands/router.ts
46216
47742
  init_mesh_refine_status();
46217
-
46218
- // src/mesh/mesh-init.ts
46219
- var import_fs16 = require("fs");
46220
- var import_path11 = require("path");
46221
- var MESH_INIT_REFINE_CONFIG_PATH = MESH_REFINE_CONFIG_LOCATIONS[0];
46222
- var MESH_INIT_WORKTREE_BOOTSTRAP_CONFIG_PATH = MESH_WORKTREE_BOOTSTRAP_CONFIG_LOCATIONS[0];
46223
- var CANDIDATE_STALE_INPUTS = [
46224
- "package-lock.json",
46225
- "pnpm-lock.yaml",
46226
- "yarn.lock",
46227
- "bun.lockb",
46228
- "Cargo.lock",
46229
- "go.sum",
46230
- "poetry.lock",
46231
- "requirements.txt"
46232
- ];
46233
- function writeConfigFile(workspace, relativePath, config) {
46234
- const target = (0, import_path11.join)(workspace, relativePath);
46235
- (0, import_fs16.mkdirSync)((0, import_path11.dirname)(target), { recursive: true });
46236
- (0, import_fs16.writeFileSync)(target, `${JSON.stringify(config, null, 2)}
46237
- `, "utf-8");
46238
- return target;
46239
- }
46240
- function suggestMeshWorktreeBootstrapConfig(workspace) {
46241
- const commands = [];
46242
- const hasPackageJson = (0, import_fs16.existsSync)((0, import_path11.join)(workspace, "package.json"));
46243
- const hasNpmLock = (0, import_fs16.existsSync)((0, import_path11.join)(workspace, "package-lock.json"));
46244
- if (hasPackageJson) {
46245
- commands.push(
46246
- hasNpmLock ? { command: "npm", args: ["ci"] } : { command: "npm", args: ["install"] }
46247
- );
46248
- }
46249
- const staleInputs = CANDIDATE_STALE_INPUTS.filter((relative5) => (0, import_fs16.existsSync)((0, import_path11.join)(workspace, relative5)));
46250
- if (!commands.length) {
46251
- return { commands, staleInputs };
46252
- }
46253
- return {
46254
- commands,
46255
- staleInputs,
46256
- suggestedConfig: {
46257
- version: 1,
46258
- enabled: true,
46259
- runOnClone: true,
46260
- required: false,
46261
- commands,
46262
- ...staleInputs.length ? { staleInputs } : {}
46263
- }
46264
- };
46265
- }
46266
- var PROVIDER_PRIORITY_PREFERENCE = ["claude-cli", "codex-cli", "gemini-cli"];
46267
- function suggestNodeProviderPriority(detected) {
46268
- const installed = detected.filter((cli) => cli.installed);
46269
- const installedIds = installed.map((cli) => cli.id);
46270
- const preferred = PROVIDER_PRIORITY_PREFERENCE.filter((id) => installedIds.includes(id));
46271
- const rest = installedIds.filter((id) => !preferred.includes(id));
46272
- const providerPriority = [...preferred, ...rest];
46273
- return {
46274
- providerPriority,
46275
- installedProviders: installed.map((cli) => ({
46276
- id: cli.id,
46277
- displayName: cli.displayName,
46278
- ...cli.version ? { version: cli.version } : {}
46279
- }))
46280
- };
46281
- }
46282
- function runMeshInit(mesh, workspace, detected, options = {}) {
46283
- const write = options.write === true;
46284
- const overwrite = options.overwrite === true;
46285
- const refine = applyConfigSuggestion({
46286
- workspace,
46287
- relativePath: MESH_INIT_REFINE_CONFIG_PATH,
46288
- existing: loadMeshRefineConfig(mesh, workspace).config,
46289
- suggestedConfig: suggestMeshRefineConfig(mesh, workspace).suggestedConfig,
46290
- validate: (config) => validateMeshRefineConfig(config, MESH_INIT_REFINE_CONFIG_PATH).valid,
46291
- write,
46292
- overwrite
46293
- });
46294
- const bootstrapSuggestion = suggestMeshWorktreeBootstrapConfig(workspace);
46295
- const worktreeBootstrap = applyConfigSuggestion({
46296
- workspace,
46297
- relativePath: MESH_INIT_WORKTREE_BOOTSTRAP_CONFIG_PATH,
46298
- existing: loadMeshWorktreeBootstrapConfig(mesh, workspace).config,
46299
- suggestedConfig: bootstrapSuggestion.suggestedConfig,
46300
- validate: (config) => validateMeshWorktreeBootstrapConfig(config, MESH_INIT_WORKTREE_BOOTSTRAP_CONFIG_PATH).valid,
46301
- write,
46302
- overwrite
46303
- });
46304
- const providers = suggestNodeProviderPriority(detected);
46305
- return {
46306
- success: true,
46307
- workspace,
46308
- dryRun: !write,
46309
- refine,
46310
- worktreeBootstrap,
46311
- providers,
46312
- note: write ? "Configs written to disk are the execution source of truth; suggestions are scaffold and only take effect once saved. providerPriority is a recommendation \u2014 apply it to node policy via clone/policy update." : "Dry-run: no files written. Re-run with write=true to persist the suggested configs. Heuristic suggestions never execute until saved as repo config."
46313
- };
46314
- }
46315
- function applyConfigSuggestion(input) {
46316
- const { workspace, relativePath, existing, suggestedConfig, validate, write, overwrite } = input;
46317
- const absolute = (0, import_path11.join)(workspace, relativePath);
46318
- if (existing !== void 0 && !overwrite) {
46319
- return { path: absolute, relativePath, written: false, skippedReason: "already_exists", config: existing };
46320
- }
46321
- if (!suggestedConfig || !validate(suggestedConfig)) {
46322
- return { path: absolute, relativePath, written: false, skippedReason: "no_suggestion" };
46323
- }
46324
- if (!write) {
46325
- return { path: absolute, relativePath, written: false, config: suggestedConfig };
46326
- }
46327
- const writtenPath = writeConfigFile(workspace, relativePath, suggestedConfig);
46328
- return { path: writtenPath, relativePath, written: true, config: suggestedConfig };
46329
- }
46330
-
46331
- // src/commands/router.ts
46332
47743
  init_mesh_work_queue();
46333
47744
  init_repo_mesh_types();
46334
47745
  var import_os3 = require("os");
@@ -48880,6 +50291,37 @@ var DaemonCommandRouter = class {
48880
50291
  this.aggregateMeshStatusCache.delete(meshId);
48881
50292
  this.deps.onMeshStateChange?.(meshId);
48882
50293
  }
50294
+ /**
50295
+ * Build the MedFamilyContext handed to RF-ROUTER MED family handlers. Binds the
50296
+ * router-private collaborators those handlers need (mesh resolution, owner
50297
+ * gating, inline-cache mutation, worktree / session cleanup, refine job
50298
+ * starters, IDE stop/launch) plus the inline-mesh and git-probe caches. The
50299
+ * `launchIde` field closes over the freshly-built context so restart_session /
50300
+ * restart_ide invoke the IDE launch directly instead of recursing through
50301
+ * executeDaemonCommand('launch_ide').
50302
+ */
50303
+ buildMedFamilyContext() {
50304
+ const ctx = {
50305
+ deps: this.deps,
50306
+ getMeshForCommand: this.getMeshForCommand.bind(this),
50307
+ getCachedInlineMesh: this.getCachedInlineMesh.bind(this),
50308
+ requireMeshHostMutationOwner: this.requireMeshHostMutationOwner.bind(this),
50309
+ invalidateAggregateMeshStatus: this.invalidateAggregateMeshStatus.bind(this),
50310
+ updateInlineMeshNode: this.updateInlineMeshNode.bind(this),
50311
+ removeInlineMeshNode: this.removeInlineMeshNode.bind(this),
50312
+ normalizeMeshSessionCleanupMode: this.normalizeMeshSessionCleanupMode.bind(this),
50313
+ cleanupMeshSessions: this.cleanupMeshSessions.bind(this),
50314
+ cleanupLocalWorktreeNode: this.cleanupLocalWorktreeNode.bind(this),
50315
+ startMeshRefineJob: this.startMeshRefineJob.bind(this),
50316
+ batchRefineMeshNodes: this.batchRefineMeshNodes.bind(this),
50317
+ startMeshRefineBatchJob: this.startMeshRefineBatchJob.bind(this),
50318
+ stopIde: this.stopIde.bind(this),
50319
+ launchIde: (args) => launchIde(ctx, args),
50320
+ inlineMeshCache: this.inlineMeshCache,
50321
+ meshGitProbeCache: this.meshGitProbeCache
50322
+ };
50323
+ return ctx;
50324
+ }
48883
50325
  async requireMeshHostMutationOwner(meshId, inlineMesh, operation) {
48884
50326
  const meshRecord = await this.getMeshForCommand(meshId, inlineMesh, { preferInline: true });
48885
50327
  const mesh = meshRecord?.mesh;
@@ -50795,6 +52237,10 @@ ${hintLines.join("\n")}` : "",
50795
52237
  getMeshForCommand: this.getMeshForCommand.bind(this)
50796
52238
  }, args);
50797
52239
  }
52240
+ const medFamilyHandler = medFamilyRegistry.get(cmd);
52241
+ if (medFamilyHandler) {
52242
+ return await medFamilyHandler(this.buildMedFamilyContext(), args);
52243
+ }
50798
52244
  switch (cmd) {
50799
52245
  // ─── CLI / ACP commands ───
50800
52246
  case "mesh_forward_event": {
@@ -50815,1315 +52261,6 @@ ${hintLines.join("\n")}` : "",
50815
52261
  this.deps.instanceManager.sendEvent(sessionId, "interactive_prompt_response", response);
50816
52262
  return { success: true };
50817
52263
  }
50818
- case "launch_cli": {
50819
- const launchResult = await this.deps.cliManager.handleCliCommand(cmd, args);
50820
- const meshNodeId = readStringValue(args?.settings?.meshNodeId);
50821
- const meshId = readStringValue(args?.settings?.meshNodeFor);
50822
- if (meshNodeId && meshId && launchResult?.success !== false) {
50823
- try {
50824
- const { getMesh: getMesh2 } = await Promise.resolve().then(() => (init_mesh_config(), mesh_config_exports));
50825
- const meshObj = getMesh2(meshId) ?? this.getCachedInlineMesh(meshId);
50826
- const nodeObj = Array.isArray(meshObj?.nodes) ? meshObj.nodes.find((n) => meshNodeIdMatches(n, meshNodeId)) : void 0;
50827
- const bootstrapStatus = readStringValue(nodeObj?.worktreeBootstrap?.status);
50828
- if (bootstrapStatus === "running") {
50829
- return { success: true, ...launchResult, bootstrapPending: true };
50830
- }
50831
- } catch {
50832
- }
50833
- }
50834
- return launchResult;
50835
- }
50836
- case "stop_cli":
50837
- case "set_cli_view_mode":
50838
- case "record_provider_pty": {
50839
- return this.deps.cliManager.handleCliCommand(cmd, args);
50840
- }
50841
- case "agent_command": {
50842
- {
50843
- const dispatchSessionId = readStringValue(args?.targetSessionId, args?.sessionId, args?.instanceId);
50844
- const dispatchMeshContext = args?.meshContext;
50845
- if (dispatchSessionId && dispatchMeshContext) {
50846
- try {
50847
- const inst = this.deps.instanceManager.getInstance(dispatchSessionId);
50848
- if (inst && typeof inst.updateSettings === "function") {
50849
- const stamp = buildMeshWorkerRelayStamp(
50850
- inst.getState?.()?.settings,
50851
- {
50852
- meshId: dispatchMeshContext.meshId,
50853
- nodeId: dispatchMeshContext.nodeId,
50854
- coordinatorDaemonId: dispatchMeshContext.coordinatorDaemonId,
50855
- // Session-level anchor: preserved across the P2P dispatch to a
50856
- // remote worker so its completion echoes back to the right session.
50857
- coordinatorSessionId: dispatchMeshContext.coordinatorSessionId
50858
- }
50859
- );
50860
- if (stamp) inst.updateSettings(stamp);
50861
- }
50862
- } catch {
50863
- }
50864
- }
50865
- }
50866
- const agentResult = await this.deps.cliManager.handleCliCommand(cmd, args);
50867
- const meshCtx = args?.meshContext;
50868
- const dispatchNodeId = readStringValue(meshCtx?.nodeId);
50869
- const dispatchMeshId = readStringValue(meshCtx?.meshId);
50870
- if (dispatchNodeId && dispatchMeshId && agentResult?.success !== false) {
50871
- try {
50872
- const { getMesh: getMesh2 } = await Promise.resolve().then(() => (init_mesh_config(), mesh_config_exports));
50873
- const meshObj = getMesh2(dispatchMeshId) ?? this.getCachedInlineMesh(dispatchMeshId);
50874
- const nodeObj = Array.isArray(meshObj?.nodes) ? meshObj.nodes.find((n) => meshNodeIdMatches(n, dispatchNodeId)) : void 0;
50875
- const bootstrapStatus = readStringValue(nodeObj?.worktreeBootstrap?.status);
50876
- if (bootstrapStatus === "running") {
50877
- return {
50878
- success: true,
50879
- ...agentResult,
50880
- dispatchAcknowledgementRisk: true,
50881
- dispatchAcknowledgementRiskReason: "bootstrap_still_running",
50882
- nextAction: "Wait for worktree_bootstrap_complete event before dispatching work to this node."
50883
- };
50884
- }
50885
- } catch {
50886
- }
50887
- }
50888
- return agentResult;
50889
- }
50890
- // ─── Logs ───
50891
- case "list_saved_sessions": {
50892
- const providerType = typeof args?.providerType === "string" ? args.providerType.trim() : typeof args?.agentType === "string" ? args.agentType.trim() : "";
50893
- const kind = args?.kind === "acp" ? "acp" : "cli";
50894
- if (!providerType) {
50895
- return { success: false, error: "providerType required" };
50896
- }
50897
- const wantsAll = args?.all === true;
50898
- const offset = wantsAll ? 0 : Math.max(0, Number(args?.offset) || 0);
50899
- const limit = wantsAll ? Number.MAX_SAFE_INTEGER : Math.max(1, Math.min(100, Number(args?.limit) || 30));
50900
- const requestedWorkspace = typeof args?.workspace === "string" ? args.workspace.trim() : "";
50901
- const requestedProviderSessionId = typeof args?.providerSessionId === "string" ? args.providerSessionId.trim() : typeof args?.activeProviderSessionId === "string" ? args.activeProviderSessionId.trim() : "";
50902
- const providerMeta = this.deps.providerLoader.resolve?.(providerType) || this.deps.providerLoader.getMeta(providerType);
50903
- const { sessions: historySessions, hasMore, source } = listProviderHistorySessions(providerType, {
50904
- canonicalHistory: providerMeta?.nativeHistory,
50905
- offset,
50906
- limit,
50907
- historyBehavior: providerMeta?.historyBehavior,
50908
- scripts: providerMeta?.scripts
50909
- });
50910
- const state = loadState();
50911
- const savedSessions = getSavedProviderSessions(state, { providerType, kind });
50912
- const recentSessions = getRecentActivity(state, 200).filter((entry) => entry.providerType === providerType && entry.kind === kind && entry.providerSessionId);
50913
- const savedSessionById = new Map(savedSessions.map((entry) => [entry.providerSessionId, entry]));
50914
- const recentSessionById = new Map(recentSessions.map((entry) => [entry.providerSessionId, entry]));
50915
- const canResumeById = supportsExplicitSessionResume(providerMeta?.resume);
50916
- return {
50917
- success: true,
50918
- sessions: historySessions.map((session) => {
50919
- const saved = savedSessionById.get(session.historySessionId);
50920
- const recent = recentSessionById.get(session.historySessionId);
50921
- const workspace = saved?.workspace || recent?.workspace || session.workspace || (requestedWorkspace && requestedProviderSessionId === session.historySessionId ? requestedWorkspace : void 0);
50922
- return {
50923
- id: session.historySessionId,
50924
- providerSessionId: session.historySessionId,
50925
- providerType,
50926
- providerName: saved?.providerName || recent?.providerName || providerType,
50927
- kind: saved?.kind || recent?.kind || kind,
50928
- title: saved?.title || recent?.title || session.sessionTitle || session.preview || providerType,
50929
- workspace,
50930
- summaryMetadata: saved?.summaryMetadata || recent?.summaryMetadata,
50931
- preview: session.preview,
50932
- messageCount: session.messageCount,
50933
- firstMessageAt: session.firstMessageAt,
50934
- lastMessageAt: session.lastMessageAt,
50935
- canResume: !!workspace && canResumeById,
50936
- historySource: session.source,
50937
- sourcePath: session.sourcePath,
50938
- sourceMtimeMs: session.sourceMtimeMs
50939
- };
50940
- }),
50941
- hasMore,
50942
- source
50943
- };
50944
- }
50945
- // ─── restart_session: IDE / CLI / ACP unified ───
50946
- case "restart_session": {
50947
- const targetType = args?.cliType || args?.agentType || args?.ideType;
50948
- if (!targetType) throw new Error("cliType or ideType required");
50949
- const isIde = this.deps.cdpManagers.has(targetType) || this.deps.providerLoader.getMeta(targetType)?.category === "ide";
50950
- if (isIde) {
50951
- await this.stopIde(targetType, true);
50952
- const launchResult = await this.executeDaemonCommand("launch_ide", { ideType: targetType, enableCdp: true, workspace: args?.workspace });
50953
- return { success: true, restarted: true, ideType: targetType, launch: launchResult };
50954
- }
50955
- return this.deps.cliManager.handleCliCommand(cmd, args);
50956
- }
50957
- // ─── IDE stop ───
50958
- case "stop_ide": {
50959
- const ideType = args?.ideType;
50960
- if (!ideType) throw new Error("ideType required");
50961
- const killProcess = args?.killProcess !== false;
50962
- await this.stopIde(ideType, killProcess);
50963
- try {
50964
- const results = await detectIDEs(this.deps.providerLoader);
50965
- this.deps.detectedIdes.value = results;
50966
- this.deps.providerLoader.setIdeDetectionResults(results, true);
50967
- } catch {
50968
- }
50969
- return { success: true, ideType, stopped: true, processKilled: killProcess };
50970
- }
50971
- // ─── IDE restart ───
50972
- case "restart_ide": {
50973
- const ideType = args?.ideType;
50974
- if (!ideType) throw new Error("ideType required");
50975
- await this.stopIde(ideType, true);
50976
- const launchResult = await this.executeDaemonCommand("launch_ide", { ideType, enableCdp: true, workspace: args?.workspace });
50977
- return { success: true, ideType, restarted: true, launch: launchResult };
50978
- }
50979
- // ─── IDE launch + CDP connect ───
50980
- case "launch_ide": {
50981
- const ideKey = args?.ideId || args?.ideType;
50982
- const resolvedWorkspace = resolveIdeLaunchWorkspace(
50983
- {
50984
- workspace: args?.workspace,
50985
- workspaceId: args?.workspaceId,
50986
- useDefaultWorkspace: args?.useDefaultWorkspace
50987
- },
50988
- loadConfig()
50989
- );
50990
- const launchArgs = {
50991
- ideId: ideKey,
50992
- workspace: resolvedWorkspace,
50993
- newWindow: args?.newWindow
50994
- };
50995
- LOG.info("LaunchIDE", `target=${ideKey || "auto"}`);
50996
- const result = await launchWithCdp(launchArgs);
50997
- if (result.success && result.port && result.ideId && !this.deps.cdpManagers.has(result.ideId)) {
50998
- const logFn = this.deps.getCdpLogFn ? this.deps.getCdpLogFn(result.ideId) : LOG.forComponent(`CDP:${result.ideId}`).asLogFn();
50999
- const provider = this.deps.providerLoader.getMeta(result.ideId);
51000
- const manager = new DaemonCdpManager(result.port, logFn, void 0, provider?.targetFilter);
51001
- const connected = await manager.connect();
51002
- if (connected) {
51003
- registerExtensionProviders(this.deps.providerLoader, manager, result.ideId);
51004
- this.deps.cdpManagers.set(result.ideId, manager);
51005
- LOG.info("CDP", `Connected: ${result.ideId} (port ${result.port})`);
51006
- LOG.info("CDP", `${this.deps.cdpManagers.size} IDE(s) connected`);
51007
- this.deps.onCdpManagerCreated?.(result.ideId, manager);
51008
- }
51009
- }
51010
- this.deps.onIdeConnected?.();
51011
- try {
51012
- const results = await detectIDEs(this.deps.providerLoader);
51013
- this.deps.detectedIdes.value = results;
51014
- this.deps.providerLoader.setIdeDetectionResults(results, true);
51015
- } catch {
51016
- }
51017
- if (result.success && resolvedWorkspace) {
51018
- try {
51019
- const next = appendRecentActivity(loadState(), {
51020
- kind: "ide",
51021
- providerType: result.ideId || ideKey,
51022
- providerName: result.ideId || ideKey,
51023
- workspace: resolvedWorkspace,
51024
- title: result.ideId || ideKey
51025
- });
51026
- saveState(next);
51027
- } catch {
51028
- }
51029
- } else if (result.success && (result.ideId || ideKey)) {
51030
- try {
51031
- saveState(appendRecentActivity(loadState(), {
51032
- kind: "ide",
51033
- providerType: result.ideId || ideKey,
51034
- providerName: result.ideId || ideKey,
51035
- title: result.ideId || ideKey
51036
- }));
51037
- } catch {
51038
- }
51039
- }
51040
- return { ...result };
51041
- }
51042
- // ─── Detect providers ───
51043
- case "detect_provider": {
51044
- const providerType = typeof args?.providerType === "string" ? args.providerType.trim() : "";
51045
- if (!providerType) return { success: false, error: "providerType is required" };
51046
- const normalizedType = this.deps.providerLoader.resolveAlias(providerType);
51047
- const provider = this.deps.providerLoader.getByAlias(providerType);
51048
- if (!provider) return { success: false, error: `Provider not found: ${providerType}` };
51049
- if (provider.category !== "cli" && provider.category !== "acp") {
51050
- return { success: false, error: `Provider detection is only supported for CLI/ACP providers: ${providerType}` };
51051
- }
51052
- if (!this.deps.providerLoader.isMachineProviderEnabled(normalizedType)) {
51053
- return { success: false, error: `Provider is disabled on this machine: ${providerType}` };
51054
- }
51055
- const detected = await detectCLI(normalizedType, this.deps.providerLoader, { includeVersion: false });
51056
- this.deps.providerLoader.setCliDetectionResults([{
51057
- id: normalizedType,
51058
- installed: !!detected,
51059
- path: detected?.path
51060
- }], false);
51061
- this.deps.onStatusChange?.();
51062
- return {
51063
- success: true,
51064
- providerType: normalizedType,
51065
- detected: !!detected,
51066
- path: detected?.path || null
51067
- };
51068
- }
51069
- // ─── Detect IDEs ───
51070
- case "detect_ides": {
51071
- const results = await detectIDEs(this.deps.providerLoader);
51072
- this.deps.detectedIdes.value = results;
51073
- this.deps.providerLoader.setIdeDetectionResults(results, true);
51074
- return { success: true, detectedInfo: results };
51075
- }
51076
- // ─── Mesh CRUD (local meshes.json) ───
51077
- case "list_meshes": {
51078
- try {
51079
- const { listMeshes: listMeshes2 } = await Promise.resolve().then(() => (init_mesh_config(), mesh_config_exports));
51080
- return { success: true, meshes: listMeshes2() };
51081
- } catch (e) {
51082
- return { success: false, error: e.message };
51083
- }
51084
- }
51085
- case "get_mesh": {
51086
- const meshId = typeof args?.meshId === "string" ? args.meshId.trim() : "";
51087
- if (!meshId) return { success: false, error: "meshId required" };
51088
- const meshRecord = await this.getMeshForCommand(meshId, args?.inlineMesh, { preferInline: true });
51089
- if (!meshRecord?.mesh) return { success: false, error: "Mesh not found" };
51090
- const requireDirectPeerTruth = args?.requireDirectPeerTruth === true;
51091
- const probeRemotePeers = args?.refresh === true || args?.forceRefresh === true;
51092
- const directTruth = await hydrateInlineMeshDirectTruth({
51093
- mesh: meshRecord.mesh,
51094
- meshSource: meshRecord.source,
51095
- dispatchMeshCommand: this.deps.dispatchMeshCommand,
51096
- getMeshPeerConnectionStatus: this.deps.getMeshPeerConnectionStatus,
51097
- statusInstanceId: this.deps.statusInstanceId,
51098
- localMachineId: loadConfig().machineId || "",
51099
- probeRemotePeers,
51100
- probeCache: this.meshGitProbeCache
51101
- });
51102
- const directTruthSatisfied = meshRecord.source !== "inline_bootstrap" || directTruth.directEvidenceCount > 0;
51103
- const sourceOfTruth = {
51104
- membership: meshRecord.source === "inline_cache" ? "coordinator_inline_mesh_cache" : meshRecord.source === "local_config" ? "local_mesh_config" : "inline_bootstrap_snapshot",
51105
- coordinatorOwnsLiveTruth: directTruthSatisfied,
51106
- directPeerTruth: {
51107
- required: requireDirectPeerTruth,
51108
- satisfied: directTruthSatisfied,
51109
- directEvidenceCount: directTruth.directEvidenceCount,
51110
- localConfirmedCount: directTruth.localConfirmedCount,
51111
- peerAttemptedCount: directTruth.peerAttemptedCount,
51112
- peerConfirmedCount: directTruth.peerConfirmedCount,
51113
- unavailableNodeIds: directTruth.unavailableNodeIds
51114
- }
51115
- };
51116
- if (requireDirectPeerTruth && !directTruthSatisfied) {
51117
- return {
51118
- success: false,
51119
- code: "mesh_direct_peer_truth_unavailable",
51120
- error: "Selected coordinator could not confirm direct mesh truth yet. Bootstrap inventory stays unavailable until direct get_mesh probes succeed.",
51121
- sourceOfTruth
51122
- };
51123
- }
51124
- return { success: true, mesh: meshRecord.mesh, sourceOfTruth };
51125
- }
51126
- case "create_mesh": {
51127
- const name = typeof args?.name === "string" ? args.name.trim() : "";
51128
- const repoIdentity = typeof args?.repoIdentity === "string" ? args.repoIdentity.trim() : "";
51129
- const repoRemoteUrl = typeof args?.repoRemoteUrl === "string" ? args.repoRemoteUrl.trim() : void 0;
51130
- const defaultBranch = typeof args?.defaultBranch === "string" ? args.defaultBranch.trim() : void 0;
51131
- if (!name) return { success: false, error: "name required" };
51132
- try {
51133
- const { createMesh: createMesh2 } = await Promise.resolve().then(() => (init_mesh_config(), mesh_config_exports));
51134
- const meshHost = args?.meshHost && typeof args.meshHost === "object" && !Array.isArray(args.meshHost) ? args.meshHost : void 0;
51135
- const mesh = createMesh2({ name, repoIdentity, repoRemoteUrl, defaultBranch, policy: args?.policy, meshHost });
51136
- return { success: true, mesh };
51137
- } catch (e) {
51138
- return { success: false, error: e.message };
51139
- }
51140
- }
51141
- case "update_mesh": {
51142
- const meshId = typeof args?.meshId === "string" ? args.meshId.trim() : "";
51143
- if (!meshId) return { success: false, error: "meshId required" };
51144
- try {
51145
- const { updateMesh: updateMesh2 } = await Promise.resolve().then(() => (init_mesh_config(), mesh_config_exports));
51146
- const patch = {};
51147
- if (typeof args?.name === "string") patch.name = args.name;
51148
- if (typeof args?.defaultBranch === "string") patch.defaultBranch = args.defaultBranch;
51149
- if (args?.policy && typeof args.policy === "object" && !Array.isArray(args.policy)) patch.policy = args.policy;
51150
- if (args?.coordinator && typeof args.coordinator === "object" && !Array.isArray(args.coordinator)) patch.coordinator = args.coordinator;
51151
- if (args?.meshHost && typeof args.meshHost === "object" && !Array.isArray(args.meshHost)) patch.meshHost = args.meshHost;
51152
- if (!Object.keys(patch).length) return { success: false, error: "No updates provided" };
51153
- const mesh = updateMesh2(meshId, patch);
51154
- if (!mesh) return { success: false, error: "Mesh not found" };
51155
- this.inlineMeshCache.set(meshId, mesh);
51156
- this.invalidateAggregateMeshStatus(meshId);
51157
- return { success: true, mesh };
51158
- } catch (e) {
51159
- return { success: false, error: e.message };
51160
- }
51161
- }
51162
- case "get_mesh_host_pairing": {
51163
- const meshId = typeof args?.meshId === "string" ? args.meshId.trim() : "";
51164
- if (!meshId) return { success: false, error: "meshId required" };
51165
- const meshRecord = await this.getMeshForCommand(meshId, args?.inlineMesh, { preferInline: true });
51166
- const mesh = meshRecord?.mesh;
51167
- if (!mesh) return { success: false, error: "Mesh not found" };
51168
- const meshHost = resolveMeshHostStatus(mesh);
51169
- const pairingStatus = meshHost.pairing?.status || "not_configured";
51170
- return {
51171
- success: true,
51172
- code: pairingStatus === "not_configured" ? "mesh_host_pairing_not_configured" : "mesh_host_pairing_pending",
51173
- meshId,
51174
- hostAddress: meshHost.hostAddress,
51175
- meshHost,
51176
- manualPairing: {
51177
- status: pairingStatus,
51178
- joinImplemented: true,
51179
- protocol: "standalone_command_direct_v1",
51180
- description: "Standalone manual pairing can save address/token metadata, apply a host join over direct standalone command HTTP or injected mesh command dispatch, and check persisted status. P2P signaling remains outside this slice."
51181
- }
51182
- };
51183
- }
51184
- case "configure_mesh_host_pairing": {
51185
- const meshId = typeof args?.meshId === "string" ? args.meshId.trim() : "";
51186
- const hostAddress = typeof args?.hostAddress === "string" ? args.hostAddress.trim() : "";
51187
- const token = typeof args?.token === "string" ? args.token.trim() : "";
51188
- if (!meshId) return { success: false, error: "meshId required" };
51189
- if (!hostAddress || !token) return { success: false, error: "hostAddress and token required" };
51190
- try {
51191
- const { configureMeshHostPairing: configureMeshHostPairing2 } = await Promise.resolve().then(() => (init_mesh_config(), mesh_config_exports));
51192
- const configured = configureMeshHostPairing2(meshId, { hostAddress, token });
51193
- if (!configured) return { success: false, error: "Mesh not found" };
51194
- this.inlineMeshCache.set(meshId, configured.mesh);
51195
- const meshHost = resolveMeshHostStatus(configured.mesh);
51196
- return {
51197
- success: true,
51198
- code: "mesh_host_pairing_pending",
51199
- meshId,
51200
- hostAddress: configured.hostAddress,
51201
- meshHost,
51202
- manualPairing: {
51203
- status: meshHost.pairing?.status || "pairing",
51204
- joinImplemented: true,
51205
- protocol: "standalone_command_direct_v1",
51206
- description: "Manual Mesh Host pairing config was saved locally. Use join_mesh_host_pairing to apply it to the host. Raw token was not persisted."
51207
- }
51208
- };
51209
- } catch (e) {
51210
- return { success: false, code: "mesh_host_pairing_invalid", meshId, hostAddress, error: e.message };
51211
- }
51212
- }
51213
- case "create_mesh_host_pairing_token": {
51214
- const meshId = typeof args?.meshId === "string" ? args.meshId.trim() : "";
51215
- if (!meshId) return { success: false, error: "meshId required" };
51216
- try {
51217
- const { createMeshHostPairingToken: createMeshHostPairingToken2 } = await Promise.resolve().then(() => (init_mesh_config(), mesh_config_exports));
51218
- const created = createMeshHostPairingToken2(meshId, {
51219
- token: typeof args?.token === "string" ? args.token : void 0,
51220
- expiresAt: typeof args?.expiresAt === "string" ? args.expiresAt : void 0
51221
- });
51222
- if (!created) return { success: false, error: "Mesh not found" };
51223
- this.inlineMeshCache.set(meshId, created.mesh);
51224
- this.invalidateAggregateMeshStatus(meshId);
51225
- return {
51226
- success: true,
51227
- code: "mesh_host_pairing_token_created",
51228
- meshId,
51229
- token: created.token,
51230
- tokenId: created.tokenId,
51231
- expiresAt: created.expiresAt,
51232
- meshHost: resolveMeshHostStatus(created.mesh),
51233
- warning: "Raw token is returned once and is not persisted; share it with member daemons over a trusted channel."
51234
- };
51235
- } catch (e) {
51236
- return { success: false, code: "mesh_host_pairing_token_invalid", meshId, error: e.message };
51237
- }
51238
- }
51239
- case "apply_mesh_host_join": {
51240
- const meshId = typeof args?.meshId === "string" ? args.meshId.trim() : "";
51241
- const token = typeof args?.token === "string" ? args.token.trim() : "";
51242
- const memberNode = args?.memberNode && typeof args.memberNode === "object" && !Array.isArray(args.memberNode) ? args.memberNode : null;
51243
- if (!meshId) return { success: false, error: "meshId required" };
51244
- if (!token || !memberNode) return { success: false, error: "token and memberNode required" };
51245
- try {
51246
- const { applyMeshHostJoinRequest: applyMeshHostJoinRequest2 } = await Promise.resolve().then(() => (init_mesh_config(), mesh_config_exports));
51247
- const applied = applyMeshHostJoinRequest2(meshId, {
51248
- token,
51249
- memberNode,
51250
- memberMeshId: typeof args?.memberMeshId === "string" ? args.memberMeshId : void 0
51251
- });
51252
- if (!applied) return { success: false, error: "Mesh not found" };
51253
- if (!applied.accepted) {
51254
- return {
51255
- success: false,
51256
- code: "mesh_host_join_rejected",
51257
- meshId,
51258
- tokenId: applied.tokenId,
51259
- meshHost: applied.meshHost ? resolveMeshHostStatus({ meshHost: applied.meshHost }) : void 0,
51260
- error: applied.reason
51261
- };
51262
- }
51263
- this.inlineMeshCache.set(meshId, applied.mesh);
51264
- this.invalidateAggregateMeshStatus(meshId);
51265
- try {
51266
- const { appendLedgerEntry: appendLedgerEntry2 } = await Promise.resolve().then(() => (init_mesh_ledger(), mesh_ledger_exports));
51267
- appendLedgerEntry2(meshId, {
51268
- kind: "node_joined",
51269
- nodeId: applied.node.id,
51270
- payload: { role: "member", tokenId: applied.tokenId, workspace: applied.node.workspace }
51271
- });
51272
- } catch {
51273
- }
51274
- return {
51275
- success: true,
51276
- code: "mesh_host_join_accepted",
51277
- meshId,
51278
- node: applied.node,
51279
- tokenId: applied.tokenId,
51280
- meshHost: resolveMeshHostStatus(applied.mesh)
51281
- };
51282
- } catch (e) {
51283
- return { success: false, code: "mesh_host_join_failed", meshId, error: e.message };
51284
- }
51285
- }
51286
- case "join_mesh_host_pairing": {
51287
- const meshId = typeof args?.meshId === "string" ? args.meshId.trim() : "";
51288
- const token = typeof args?.token === "string" ? args.token.trim() : "";
51289
- if (!meshId) return { success: false, error: "meshId required" };
51290
- if (!token) return { success: false, error: "token required because raw pairing tokens are not persisted" };
51291
- const meshRecord = await this.getMeshForCommand(meshId, args?.inlineMesh, { preferInline: true });
51292
- const mesh = meshRecord?.mesh;
51293
- if (!mesh) return { success: false, error: "Mesh not found" };
51294
- const meshHost = resolveMeshHostStatus(mesh);
51295
- if (meshHost.role !== "member") {
51296
- return { success: false, code: "mesh_host_join_not_member", meshId, meshHost, error: "join_mesh_host_pairing must run from a member daemon configured with a Mesh Host address/token." };
51297
- }
51298
- try {
51299
- const { tokenIdForManualPairing: tokenIdForManualPairing2, markMeshHostPairingJoined: markMeshHostPairingJoined2 } = await Promise.resolve().then(() => (init_mesh_config(), mesh_config_exports));
51300
- const tokenId = tokenIdForManualPairing2(token);
51301
- if (meshHost.pairing?.tokenId && meshHost.pairing.tokenId !== tokenId) {
51302
- return { success: false, code: "mesh_host_join_rejected", meshId, tokenId, meshHost, error: "invalid pairing token" };
51303
- }
51304
- const memberNode = buildMemberJoinNode(mesh, args, this.deps.statusInstanceId);
51305
- if (!memberNode) return { success: false, error: "member node metadata unavailable" };
51306
- const hostMeshId = typeof args?.hostMeshId === "string" && args.hostMeshId.trim() ? args.hostMeshId.trim() : meshId;
51307
- const hostDaemonId = typeof args?.hostDaemonId === "string" && args.hostDaemonId.trim() ? args.hostDaemonId.trim() : meshHost.hostDaemonId;
51308
- let hostResult;
51309
- let transport;
51310
- if (hostDaemonId && this.deps.dispatchMeshCommand) {
51311
- transport = "mesh_command_dispatch";
51312
- hostResult = await this.deps.dispatchMeshCommand(hostDaemonId, "apply_mesh_host_join", {
51313
- meshId: hostMeshId,
51314
- token,
51315
- memberMeshId: meshId,
51316
- memberNode
51317
- });
51318
- } else if (meshHost.hostAddress) {
51319
- transport = "standalone_http_command";
51320
- const commandUrl = normalizeStandaloneHostCommandUrl(meshHost.hostAddress);
51321
- const response = await fetch(commandUrl, {
51322
- method: "POST",
51323
- headers: { "Content-Type": "application/json" },
51324
- body: JSON.stringify({ type: "apply_mesh_host_join", payload: { meshId: hostMeshId, token, memberMeshId: meshId, memberNode } })
51325
- });
51326
- hostResult = await response.json().catch(() => ({ success: false, error: `Host returned HTTP ${response.status}` }));
51327
- if (!response.ok && hostResult?.success !== false) hostResult = { success: false, error: `Host returned HTTP ${response.status}` };
51328
- } else {
51329
- return {
51330
- success: false,
51331
- code: "mesh_host_join_transport_unavailable",
51332
- meshId,
51333
- meshHost,
51334
- error: "No hostDaemonId dispatch path or hostAddress HTTP command path is available. P2P signaling join is not implemented in this slice."
51335
- };
51336
- }
51337
- if (!hostResult?.success) {
51338
- return { success: false, code: hostResult?.code || "mesh_host_join_rejected", meshId, meshHost, transport, error: hostResult?.error || "Mesh Host rejected join request", hostResult };
51339
- }
51340
- const joined = meshRecord.inline ? null : markMeshHostPairingJoined2(meshId, {
51341
- tokenId: hostResult.tokenId || tokenId,
51342
- hostDaemonId: hostResult.meshHost?.hostDaemonId || hostDaemonId,
51343
- hostNodeId: hostResult.meshHost?.hostNodeId,
51344
- joinedAt: hostResult.meshHost?.pairing?.joinedAt
51345
- });
51346
- if (joined) {
51347
- this.inlineMeshCache.set(meshId, joined.mesh);
51348
- this.invalidateAggregateMeshStatus(meshId);
51349
- }
51350
- return {
51351
- success: true,
51352
- code: "mesh_host_join_applied",
51353
- meshId,
51354
- hostMeshId,
51355
- transport,
51356
- node: hostResult.node,
51357
- tokenId: hostResult.tokenId || tokenId,
51358
- meshHost: joined ? resolveMeshHostStatus(joined.mesh) : { ...meshHost, pairing: { ...meshHost.pairing || {}, status: "paired", tokenId: hostResult.tokenId || tokenId } },
51359
- hostResult,
51360
- manualPairing: {
51361
- status: "paired",
51362
- joinImplemented: true,
51363
- protocol: "standalone_command_direct_v1",
51364
- description: "Mesh Host accepted the join and local member pairing status was marked paired. P2P runtime signaling remains outside this slice."
51365
- }
51366
- };
51367
- } catch (e) {
51368
- return { success: false, code: "mesh_host_join_failed", meshId, meshHost, error: e.message };
51369
- }
51370
- }
51371
- case "delete_mesh": {
51372
- const meshId = typeof args?.meshId === "string" ? args.meshId.trim() : "";
51373
- if (!meshId) return { success: false, error: "meshId required" };
51374
- try {
51375
- const { deleteMesh: deleteMesh2 } = await Promise.resolve().then(() => (init_mesh_config(), mesh_config_exports));
51376
- const deleted = deleteMesh2(meshId);
51377
- return { success: true, deleted };
51378
- } catch (e) {
51379
- return { success: false, error: e.message };
51380
- }
51381
- }
51382
- case "get_mesh_queue": {
51383
- const meshId = typeof args?.meshId === "string" ? args.meshId.trim() : "";
51384
- if (!meshId) return { success: false, error: "meshId required" };
51385
- try {
51386
- const { getMeshQueueStats: getMeshQueueStats2, getQueue: getQueue2, describeTaskDependencyState: describeTaskDependencyState2 } = await Promise.resolve().then(() => (init_mesh_work_queue(), mesh_work_queue_exports));
51387
- const status = Array.isArray(args?.status) ? args.status.map((s2) => typeof s2 === "string" ? s2.trim() : "").filter(Boolean) : void 0;
51388
- const rawQueue = getQueue2(meshId, { status });
51389
- const statusById = new Map(getQueue2(meshId).map((task) => [task.id, task.status]));
51390
- const queue = rawQueue.map((task) => Array.isArray(task.dependsOn) && task.dependsOn.length > 0 ? { ...task, ...describeTaskDependencyState2(task, statusById) } : task);
51391
- const summary = getMeshQueueStats2(meshId);
51392
- return {
51393
- success: true,
51394
- queue,
51395
- summary,
51396
- sourceOfTruth: {
51397
- kind: "mesh_work_queue_file",
51398
- activeStatuses: ["pending", "assigned"],
51399
- historicalStatuses: ["completed", "failed", "cancelled"],
51400
- notes: "pending/assigned are active work; completed/failed/cancelled are historical records."
51401
- }
51402
- };
51403
- } catch (e) {
51404
- return { success: false, error: e.message };
51405
- }
51406
- }
51407
- case "cancel_mesh_queue_task": {
51408
- const meshId = typeof args?.meshId === "string" ? args.meshId.trim() : "";
51409
- const taskId = typeof args?.taskId === "string" ? args.taskId.trim() : "";
51410
- if (!meshId || !taskId) return { success: false, error: "meshId and taskId required" };
51411
- const ownerFailure = await this.requireMeshHostMutationOwner(meshId, args?.inlineMesh, "queue cancellation");
51412
- if (ownerFailure) return ownerFailure;
51413
- try {
51414
- const { cancelTask: cancelTask2 } = await Promise.resolve().then(() => (init_mesh_work_queue(), mesh_work_queue_exports));
51415
- const reason = typeof args?.reason === "string" ? args.reason : void 0;
51416
- const task = cancelTask2(meshId, taskId, { reason });
51417
- if (!task) return { success: false, error: `Queue task '${taskId}' not found` };
51418
- return { success: true, task };
51419
- } catch (e) {
51420
- return { success: false, error: e.message };
51421
- }
51422
- }
51423
- case "requeue_mesh_queue_task": {
51424
- const meshId = typeof args?.meshId === "string" ? args.meshId.trim() : "";
51425
- const taskId = typeof args?.taskId === "string" ? args.taskId.trim() : "";
51426
- if (!meshId || !taskId) return { success: false, error: "meshId and taskId required" };
51427
- const ownerFailure = await this.requireMeshHostMutationOwner(meshId, args?.inlineMesh, "queue requeue");
51428
- if (ownerFailure) return ownerFailure;
51429
- try {
51430
- const { requeueTask: requeueTask2 } = await Promise.resolve().then(() => (init_mesh_work_queue(), mesh_work_queue_exports));
51431
- const task = requeueTask2(meshId, taskId, {
51432
- reason: typeof args?.reason === "string" ? args.reason : void 0,
51433
- targetNodeId: typeof args?.targetNodeId === "string" ? args.targetNodeId.trim() : void 0,
51434
- targetSessionId: typeof args?.targetSessionId === "string" ? args.targetSessionId.trim() : void 0,
51435
- clearTargetNode: args?.clearTargetNode === true,
51436
- clearTargetSession: args?.clearTargetSession !== false
51437
- });
51438
- if (!task) return { success: false, error: `Queue task '${taskId}' not found` };
51439
- return { success: true, task };
51440
- } catch (e) {
51441
- return { success: false, error: e.message };
51442
- }
51443
- }
51444
- case "add_mesh_node": {
51445
- const meshId = typeof args?.meshId === "string" ? args.meshId.trim() : "";
51446
- const workspace = typeof args?.workspace === "string" ? args.workspace.trim() : "";
51447
- if (!meshId) return { success: false, error: "meshId required" };
51448
- if (!workspace) return { success: false, error: "workspace required" };
51449
- const ownerFailure = await this.requireMeshHostMutationOwner(meshId, args?.inlineMesh, "node addition");
51450
- if (ownerFailure) return ownerFailure;
51451
- try {
51452
- const { addNode: addNode2 } = await Promise.resolve().then(() => (init_mesh_config(), mesh_config_exports));
51453
- const providerPriority = Array.isArray(args?.providerPriority) ? args.providerPriority.map((type) => typeof type === "string" ? type.trim() : "").filter(Boolean) : [];
51454
- const readOnly = args?.readOnly === true;
51455
- const providerRoles = normalizeProviderRoles(args?.providerRoles);
51456
- const policy = {
51457
- ...readOnly ? { readOnly: true } : {},
51458
- ...providerPriority.length ? { providerPriority } : {},
51459
- ...providerRoles.length ? { providerRoles } : {}
51460
- };
51461
- const role = normalizeMeshDaemonRole(args?.role);
51462
- const daemonId = typeof args?.daemonId === "string" && args.daemonId.trim() ? args.daemonId.trim() : void 0;
51463
- const machineId = typeof args?.machineId === "string" && args.machineId.trim() ? args.machineId.trim() : void 0;
51464
- const repoRoot = typeof args?.repoRoot === "string" && args.repoRoot.trim() ? args.repoRoot.trim() : void 0;
51465
- const node = addNode2(meshId, {
51466
- workspace,
51467
- ...repoRoot ? { repoRoot } : {},
51468
- ...daemonId ? { daemonId } : {},
51469
- ...machineId ? { machineId } : {},
51470
- ...policy ? { policy } : {},
51471
- ...role ? { role } : {}
51472
- });
51473
- if (!node) return { success: false, error: "Mesh not found" };
51474
- this.invalidateAggregateMeshStatus(meshId);
51475
- return { success: true, node };
51476
- } catch (e) {
51477
- return { success: false, error: e.message };
51478
- }
51479
- }
51480
- case "update_mesh_node": {
51481
- const meshId = typeof args?.meshId === "string" ? args.meshId.trim() : "";
51482
- const nodeId = typeof args?.nodeId === "string" ? args.nodeId.trim() : "";
51483
- if (!meshId || !nodeId) return { success: false, error: "meshId and nodeId required" };
51484
- const ownerFailure = await this.requireMeshHostMutationOwner(meshId, args?.inlineMesh, "node update");
51485
- if (ownerFailure) return ownerFailure;
51486
- try {
51487
- const { updateNode: updateNode2 } = await Promise.resolve().then(() => (init_mesh_config(), mesh_config_exports));
51488
- const policy = args?.policy && typeof args.policy === "object" && !Array.isArray(args.policy) ? { ...args.policy } : {};
51489
- if (Array.isArray(args?.providerPriority)) {
51490
- const providerPriority = args.providerPriority.map((type) => typeof type === "string" ? type.trim() : "").filter(Boolean);
51491
- delete policy.provider_priority;
51492
- if (providerPriority.length) {
51493
- policy.providerPriority = providerPriority;
51494
- } else {
51495
- delete policy.providerPriority;
51496
- }
51497
- }
51498
- if (Array.isArray(args?.providerRoles)) {
51499
- const providerRoles = normalizeProviderRoles(args.providerRoles);
51500
- if (providerRoles.length) {
51501
- policy.providerRoles = providerRoles;
51502
- } else {
51503
- delete policy.providerRoles;
51504
- }
51505
- }
51506
- const patch = { policy };
51507
- if (typeof args?.systemPrompt === "string") {
51508
- const trimmed = args.systemPrompt.trim();
51509
- patch.systemPrompt = trimmed || void 0;
51510
- } else if (args?.systemPrompt === null) {
51511
- patch.systemPrompt = void 0;
51512
- }
51513
- const node = updateNode2(meshId, nodeId, patch);
51514
- if (!node) return { success: false, error: "Mesh node not found" };
51515
- this.invalidateAggregateMeshStatus(meshId);
51516
- return { success: true, node };
51517
- } catch (e) {
51518
- return { success: false, error: e.message };
51519
- }
51520
- }
51521
- case "cleanup_mesh_sessions": {
51522
- const meshId = typeof args?.meshId === "string" ? args.meshId.trim() : "";
51523
- const nodeId = typeof args?.nodeId === "string" ? args.nodeId.trim() : "";
51524
- if (!meshId || !nodeId) return { success: false, error: "meshId and nodeId required" };
51525
- const ownerFailure = await this.requireMeshHostMutationOwner(meshId, args?.inlineMesh, "node removal");
51526
- if (ownerFailure) return ownerFailure;
51527
- try {
51528
- const meshRecord = await this.getMeshForCommand(meshId, args?.inlineMesh, { preferInline: true });
51529
- const mesh = meshRecord?.mesh;
51530
- if (!mesh) return { success: false, error: "Mesh not found" };
51531
- const node = mesh?.nodes?.find((n) => meshNodeIdMatches(n, nodeId));
51532
- if (!node) return { success: false, error: `Node '${nodeId}' not found in mesh` };
51533
- const mode = this.normalizeMeshSessionCleanupMode(args?.mode ?? mesh?.policy?.sessionCleanupOnNodeRemove);
51534
- const sessionIds = Array.isArray(args?.sessionIds) ? args.sessionIds.map((id) => typeof id === "string" ? id.trim() : "").filter(Boolean) : void 0;
51535
- const result = await this.cleanupMeshSessions({
51536
- meshId,
51537
- nodeId,
51538
- node,
51539
- mode,
51540
- sessionIds,
51541
- dryRun: args?.dryRun === true,
51542
- source: "mesh_cleanup_sessions"
51543
- });
51544
- return result;
51545
- } catch (e) {
51546
- return { success: false, error: e.message };
51547
- }
51548
- }
51549
- case "mesh_init": {
51550
- const workspace = typeof args?.workspace === "string" && args.workspace.trim() ? args.workspace.trim() : process.cwd();
51551
- const mesh = args?.inlineMesh || {};
51552
- try {
51553
- const detected = await detectCLIs(this.deps.providerLoader, { includeVersion: true });
51554
- return { ...runMeshInit(mesh, workspace, detected, {
51555
- write: args?.write === true,
51556
- overwrite: args?.overwrite === true
51557
- }) };
51558
- } catch (e) {
51559
- return { success: false, error: e?.message || String(e) };
51560
- }
51561
- }
51562
- case "plan_mesh_refine_node": {
51563
- const meshId = typeof args?.meshId === "string" ? args.meshId.trim() : "";
51564
- const nodeId = typeof args?.nodeId === "string" ? args.nodeId.trim() : "";
51565
- if (!meshId || !nodeId) return { success: false, error: "meshId and nodeId required" };
51566
- const meshRecord = await this.getMeshForCommand(meshId, args?.inlineMesh, { preferInline: true });
51567
- const mesh = meshRecord?.mesh;
51568
- const node = mesh?.nodes?.find((n) => meshNodeIdMatches(n, nodeId));
51569
- if (!node?.workspace) return { success: false, error: `Node '${nodeId}' workspace not found` };
51570
- return {
51571
- success: true,
51572
- dryRun: true,
51573
- nodeId,
51574
- workspace: node.workspace,
51575
- validationPlan: buildMeshRefineValidationPlan(mesh, node.workspace),
51576
- mergeWillRun: false,
51577
- cleanupWillRun: false
51578
- };
51579
- }
51580
- case "fast_forward_mesh_node": {
51581
- const meshId = typeof args?.meshId === "string" ? args.meshId.trim() : "";
51582
- const nodeId = typeof args?.nodeId === "string" ? args.nodeId.trim() : "";
51583
- let workspace = typeof args?.workspace === "string" ? args.workspace.trim() : "";
51584
- let submoduleIgnorePaths = Array.isArray(args?.submoduleIgnorePaths) ? args.submoduleIgnorePaths.filter((value) => typeof value === "string") : void 0;
51585
- let nodeDaemonId;
51586
- let allowAutoPublishSubmoduleMainCommits = false;
51587
- if (meshId && nodeId) {
51588
- const meshRecord = await this.getMeshForCommand(meshId, args?.inlineMesh, { preferInline: true });
51589
- const mesh = meshRecord?.mesh;
51590
- const node = mesh?.nodes?.find((n) => meshNodeIdMatches(n, nodeId));
51591
- if (!workspace) {
51592
- workspace = typeof node?.workspace === "string" ? node.workspace.trim() : "";
51593
- }
51594
- if (!submoduleIgnorePaths && Array.isArray(node?.policy?.submoduleIgnorePaths)) {
51595
- submoduleIgnorePaths = node.policy.submoduleIgnorePaths.filter((value) => typeof value === "string");
51596
- }
51597
- allowAutoPublishSubmoduleMainCommits = mesh?.policy?.allowAutoPublishSubmoduleMainCommits === true;
51598
- nodeDaemonId = typeof node?.daemonId === "string" ? node.daemonId.trim() : void 0;
51599
- }
51600
- const selfDaemonId = this.deps.statusInstanceId;
51601
- const isRemote = nodeDaemonId && selfDaemonId && !daemonIdsEquivalent(nodeDaemonId, selfDaemonId);
51602
- if (isRemote && this.deps.dispatchMeshCommand && !args?._meshDirectDispatch) {
51603
- const forwarded = await this.deps.dispatchMeshCommand(nodeDaemonId, "fast_forward_mesh_node", {
51604
- ...typeof args === "object" && args !== null ? args : {},
51605
- workspace,
51606
- _meshDirectDispatch: true
51607
- });
51608
- return forwarded ?? { success: false, error: "no response from remote node" };
51609
- }
51610
- const result = await fastForwardMeshNode({
51611
- meshId: meshId || void 0,
51612
- nodeId: nodeId || void 0,
51613
- workspace,
51614
- branch: typeof args?.branch === "string" ? args.branch : void 0,
51615
- execute: args?.execute === true,
51616
- dryRun: args?.dryRun === true,
51617
- updateSubmodules: args?.updateSubmodules === true,
51618
- submoduleIgnorePaths,
51619
- mode: args?.mode === "push" ? "push" : "merge",
51620
- pushSubmodules: args?.pushSubmodules === true,
51621
- allowAutoPublishSubmoduleMainCommits
51622
- });
51623
- return result;
51624
- }
51625
- case "refine_mesh_node": {
51626
- const meshId = typeof args?.meshId === "string" ? args.meshId.trim() : "";
51627
- const nodeId = typeof args?.nodeId === "string" ? args.nodeId.trim() : "";
51628
- if (!meshId || !nodeId) return { success: false, error: "meshId and nodeId required" };
51629
- {
51630
- const meshRecordForForward = await this.getMeshForCommand(meshId, args?.inlineMesh, { preferInline: true });
51631
- const forwardNode = meshRecordForForward?.mesh?.nodes?.find((n) => meshNodeIdMatches(n, nodeId));
51632
- const nodeDaemonId = typeof forwardNode?.daemonId === "string" ? forwardNode.daemonId.trim() : void 0;
51633
- const selfDaemonId = this.deps.statusInstanceId;
51634
- const isRemote = nodeDaemonId && selfDaemonId && !daemonIdsEquivalent(nodeDaemonId, selfDaemonId);
51635
- if (isRemote && this.deps.dispatchMeshCommand && !args?._meshDirectDispatch) {
51636
- const callerCoordinatorDaemonId = typeof args?.coordinatorDaemonId === "string" && args.coordinatorDaemonId.trim() ? args.coordinatorDaemonId.trim() : void 0;
51637
- const forwarded = await this.deps.dispatchMeshCommand(nodeDaemonId, "refine_mesh_node", {
51638
- ...typeof args === "object" && args !== null ? args : {},
51639
- coordinatorDaemonId: callerCoordinatorDaemonId || selfDaemonId,
51640
- _meshDirectDispatch: true
51641
- });
51642
- return forwarded ?? { success: false, error: "no response from remote node" };
51643
- }
51644
- }
51645
- const isDryRun = args?.dryRun !== false && args?.execute !== true;
51646
- if (isDryRun) {
51647
- const meshRecord = await this.getMeshForCommand(meshId, args?.inlineMesh, { preferInline: true });
51648
- const mesh = meshRecord?.mesh;
51649
- const node = mesh?.nodes?.find((n) => meshNodeIdMatches(n, nodeId));
51650
- if (!node?.workspace) return { success: false, error: `Node '${nodeId}' workspace not found` };
51651
- return {
51652
- success: true,
51653
- dryRun: true,
51654
- nodeId,
51655
- workspace: node.workspace,
51656
- validationPlan: buildMeshRefineValidationPlan(mesh, node.workspace),
51657
- mergeWillRun: false,
51658
- cleanupWillRun: false,
51659
- hint: "Dry-run only \u2014 no merge/push/cleanup performed. Re-invoke with execute:true to converge this node."
51660
- };
51661
- }
51662
- return this.startMeshRefineJob(meshId, nodeId, args);
51663
- }
51664
- case "batch_refine_mesh_nodes": {
51665
- const meshId = typeof args?.meshId === "string" ? args.meshId.trim() : "";
51666
- if (!meshId) return { success: false, error: "meshId required" };
51667
- const requestedNodeIds = Array.isArray(args?.nodeIds) ? args.nodeIds.filter((v) => typeof v === "string" && v.trim().length > 0).map((v) => v.trim()) : void 0;
51668
- const isDryRun = args?.dryRun !== false && args?.execute !== true;
51669
- if (isDryRun) return this.batchRefineMeshNodes(meshId, requestedNodeIds, args);
51670
- return this.startMeshRefineBatchJob(meshId, requestedNodeIds, args);
51671
- }
51672
- case "remove_mesh_node": {
51673
- const meshId = typeof args?.meshId === "string" ? args.meshId.trim() : "";
51674
- const nodeId = typeof args?.nodeId === "string" ? args.nodeId.trim() : "";
51675
- if (!meshId || !nodeId) return { success: false, error: "meshId and nodeId required" };
51676
- try {
51677
- const meshRecord = await this.getMeshForCommand(meshId, args?.inlineMesh, { preferInline: true });
51678
- const mesh = meshRecord?.mesh;
51679
- const node = mesh?.nodes?.find((n) => meshNodeIdMatches(n, nodeId));
51680
- if (node && !args?._meshDirectDispatch && node.isLocalWorktree !== true && args?.force !== true) {
51681
- const nodeDaemonId = typeof node.daemonId === "string" ? node.daemonId.trim() : "";
51682
- const nodeMachineId = readMeshNodeMachineId(node) || "";
51683
- const selfDaemonId = this.deps.statusInstanceId || "";
51684
- const selfMachineId = (() => {
51685
- try {
51686
- return loadConfig().machineId || "";
51687
- } catch {
51688
- return "";
51689
- }
51690
- })();
51691
- const isCoordinatorBaseNode = !!selfDaemonId && (nodeDaemonId === selfDaemonId || nodeMachineId === selfDaemonId) || !!selfMachineId && (nodeDaemonId === selfMachineId || nodeMachineId === selfMachineId);
51692
- if (isCoordinatorBaseNode) {
51693
- return {
51694
- success: false,
51695
- removed: false,
51696
- code: "mesh_remove_coordinator_base_node_protected",
51697
- error: `Refusing to remove the coordinator's own base node '${typeof node.workspace === "string" ? node.workspace : nodeId}'. It is the local non-worktree node bound to this coordinator daemon; removing it breaks live mesh membership and forces a restart.`,
51698
- recoveryHint: "Remove worktree clone nodes instead, or pass force:true only if you are intentionally tearing down this mesh and accept that the coordinator must be re-registered/restarted."
51699
- };
51700
- }
51701
- }
51702
- const sessionCleanupMode = this.normalizeMeshSessionCleanupMode(
51703
- args?.sessionCleanupMode ?? args?.session_cleanup_mode ?? mesh?.policy?.sessionCleanupOnNodeRemove
51704
- );
51705
- const explicitSessionIds = Array.isArray(args?.sessionIds) ? args.sessionIds.filter((v) => typeof v === "string" && v.trim().length > 0).map((v) => v.trim()) : void 0;
51706
- let sessionCleanup;
51707
- if (node && sessionCleanupMode !== "preserve") {
51708
- sessionCleanup = await this.cleanupMeshSessions({
51709
- meshId,
51710
- nodeId,
51711
- node,
51712
- mode: sessionCleanupMode,
51713
- ...explicitSessionIds && explicitSessionIds.length > 0 ? { sessionIds: explicitSessionIds } : {},
51714
- source: "mesh_remove_node"
51715
- });
51716
- if (sessionCleanup.success === false) return { success: false, removed: false, sessionCleanup };
51717
- }
51718
- let worktreeCleanup;
51719
- if (node?.isLocalWorktree) {
51720
- const nodeDaemonId = typeof node.daemonId === "string" ? node.daemonId.trim() : void 0;
51721
- const isRemoteWorktree = nodeDaemonId && !daemonIdsEquivalent(nodeDaemonId, this.deps.statusInstanceId) && this.deps.dispatchMeshCommand && !args?._meshDirectDispatch;
51722
- if (isRemoteWorktree) {
51723
- const forwarded = await this.deps.dispatchMeshCommand(nodeDaemonId, "remove_mesh_node", {
51724
- ...typeof args === "object" && args !== null ? args : {},
51725
- _meshDirectDispatch: true
51726
- });
51727
- return forwarded ?? { success: false, error: "no response from remote node" };
51728
- }
51729
- const cleanupResult = await this.cleanupLocalWorktreeNode({ mesh, node, nodeId, force: args?.force === true });
51730
- if (cleanupResult.success === false) {
51731
- return {
51732
- success: false,
51733
- removed: false,
51734
- code: cleanupResult.code,
51735
- error: cleanupResult.error,
51736
- recoveryHint: cleanupResult.recoveryHint,
51737
- ...sessionCleanup ? { sessionCleanup } : {},
51738
- worktreeCleanup: cleanupResult
51739
- };
51740
- }
51741
- worktreeCleanup = cleanupResult;
51742
- }
51743
- let removed = false;
51744
- if (meshRecord?.inline) {
51745
- removed = this.removeInlineMeshNode(meshId, mesh, nodeId);
51746
- if (removed) this.invalidateAggregateMeshStatus(meshId);
51747
- if (!removed && !node) removed = true;
51748
- } else {
51749
- const { removeNode: removeNode2 } = await Promise.resolve().then(() => (init_mesh_config(), mesh_config_exports));
51750
- removed = removeNode2(meshId, nodeId);
51751
- if (!removed && !node) removed = true;
51752
- if (removed) this.invalidateAggregateMeshStatus(meshId);
51753
- }
51754
- if (removed) {
51755
- try {
51756
- const { appendLedgerEntry: appendLedgerEntry2 } = await Promise.resolve().then(() => (init_mesh_ledger(), mesh_ledger_exports));
51757
- appendLedgerEntry2(meshId, {
51758
- kind: "node_removed",
51759
- nodeId,
51760
- payload: {
51761
- worktree: !!node?.isLocalWorktree,
51762
- sessionCleanupMode,
51763
- workspace: typeof node?.workspace === "string" ? node.workspace : void 0,
51764
- daemonId: typeof node?.daemonId === "string" ? node.daemonId : void 0,
51765
- worktreeBranch: typeof node?.worktreeBranch === "string" ? node.worktreeBranch : void 0,
51766
- worktreeCleanupFallback: typeof worktreeCleanup?.fallback === "string" ? worktreeCleanup.fallback : void 0,
51767
- forced: worktreeCleanup?.forced === true ? true : void 0,
51768
- forceFallbackReason: typeof worktreeCleanup?.reason === "string" ? worktreeCleanup.reason : void 0
51769
- }
51770
- });
51771
- } catch {
51772
- }
51773
- }
51774
- const residueWarning = worktreeCleanup?.residue === true && typeof worktreeCleanup?.residueWarning === "string" ? worktreeCleanup.residueWarning : void 0;
51775
- return {
51776
- success: true,
51777
- removed,
51778
- ...residueWarning ? { residueWarning } : {},
51779
- ...sessionCleanup ? { sessionCleanup } : {},
51780
- ...worktreeCleanup ? { worktreeCleanup } : {}
51781
- };
51782
- } catch (e) {
51783
- return { success: false, error: e.message };
51784
- }
51785
- }
51786
- case "clone_mesh_node": {
51787
- const meshId = typeof args?.meshId === "string" ? args.meshId.trim() : "";
51788
- const sourceNodeId = typeof args?.sourceNodeId === "string" ? args.sourceNodeId.trim() : "";
51789
- const branch = typeof args?.branch === "string" ? args.branch.trim() : "";
51790
- const baseBranch = typeof args?.baseBranch === "string" ? args.baseBranch.trim() : void 0;
51791
- if (!meshId) return { success: false, error: "meshId required" };
51792
- if (!sourceNodeId) return { success: false, error: "sourceNodeId required" };
51793
- if (!branch) return { success: false, error: "branch required" };
51794
- const ownerFailure = await this.requireMeshHostMutationOwner(meshId, args?.inlineMesh, "worktree clone");
51795
- if (ownerFailure) return ownerFailure;
51796
- try {
51797
- const meshRecord = await this.getMeshForCommand(meshId, args?.inlineMesh, { preferInline: true });
51798
- const mesh = meshRecord?.mesh;
51799
- if (!mesh) return { success: false, error: "Mesh not found" };
51800
- const sourceNode = mesh.nodes?.find((n) => meshNodeIdMatches(n, sourceNodeId));
51801
- if (!sourceNode) return { success: false, error: `Source node '${sourceNodeId}' not found in mesh` };
51802
- const sourceDaemonId = typeof sourceNode.daemonId === "string" ? sourceNode.daemonId.trim() : void 0;
51803
- if (sourceDaemonId && !daemonIdsEquivalent(sourceDaemonId, this.deps.statusInstanceId) && this.deps.dispatchMeshCommand && !args?._meshDirectDispatch) {
51804
- const forwarded = await this.deps.dispatchMeshCommand(sourceDaemonId, "clone_mesh_node", {
51805
- ...typeof args === "object" && args !== null ? args : {},
51806
- _meshDirectDispatch: true
51807
- });
51808
- return forwarded ?? { success: false, error: "no response from remote node" };
51809
- }
51810
- const repoRoot = sourceNode.repoRoot || sourceNode.workspace;
51811
- const { createWorktree: createWorktree2 } = await Promise.resolve().then(() => (init_git_worktree(), git_worktree_exports));
51812
- const result = await createWorktree2({
51813
- repoRoot,
51814
- branch,
51815
- baseBranch,
51816
- meshName: mesh.name
51817
- });
51818
- let node;
51819
- if (meshRecord.inline) {
51820
- const { randomUUID: randomUUID15 } = await import("crypto");
51821
- node = {
51822
- id: `node_${randomUUID15().replace(/-/g, "")}`,
51823
- workspace: result.worktreePath,
51824
- repoRoot: result.worktreePath,
51825
- daemonId: sourceNode.daemonId,
51826
- machineId: sourceNode.machineId ?? sourceNode.machine_id,
51827
- userOverrides: { ...sourceNode.userOverrides || {} },
51828
- policy: { ...sourceNode.policy || {} },
51829
- isLocalWorktree: true,
51830
- worktreeBranch: result.branch,
51831
- clonedFromNodeId: sourceNodeId
51832
- };
51833
- this.updateInlineMeshNode(meshId, mesh, node);
51834
- } else {
51835
- const { addNode: addNode2 } = await Promise.resolve().then(() => (init_mesh_config(), mesh_config_exports));
51836
- node = addNode2(meshId, {
51837
- workspace: result.worktreePath,
51838
- repoRoot: result.worktreePath,
51839
- daemonId: sourceNode.daemonId,
51840
- machineId: sourceNode.machineId ?? sourceNode.machine_id,
51841
- userOverrides: { ...sourceNode.userOverrides || {} },
51842
- isLocalWorktree: true,
51843
- worktreeBranch: result.branch,
51844
- clonedFromNodeId: sourceNodeId,
51845
- policy: { ...sourceNode.policy || {} }
51846
- });
51847
- if (!node) return { success: false, error: "Failed to register worktree node" };
51848
- const inlineForReconcile = this.getCachedInlineMesh(meshId);
51849
- if (inlineForReconcile) this.updateInlineMeshNode(meshId, inlineForReconcile, node);
51850
- this.invalidateAggregateMeshStatus(meshId);
51851
- }
51852
- const persistWorktreeSetupState = async (bootstrapState2) => {
51853
- node.worktreeBootstrap = bootstrapState2;
51854
- if (meshRecord.inline) {
51855
- this.updateInlineMeshNode(meshId, mesh, node);
51856
- return;
51857
- }
51858
- try {
51859
- const { updateNode: updateNode2 } = await Promise.resolve().then(() => (init_mesh_config(), mesh_config_exports));
51860
- updateNode2(meshId, node.id, { worktreeBootstrap: bootstrapState2 });
51861
- this.invalidateAggregateMeshStatus(meshId);
51862
- } catch {
51863
- }
51864
- };
51865
- const appendCloneLedger = async (initSubmodules2, bootstrapState2) => {
51866
- try {
51867
- const { appendLedgerEntry: appendLedgerEntry2 } = await Promise.resolve().then(() => (init_mesh_ledger(), mesh_ledger_exports));
51868
- appendLedgerEntry2(meshId, {
51869
- kind: "node_cloned",
51870
- nodeId: node.id,
51871
- payload: {
51872
- sourceNodeId,
51873
- branch: result.branch,
51874
- worktreePath: result.worktreePath,
51875
- submodulesInitialized: initSubmodules2,
51876
- worktreeBootstrap: {
51877
- status: bootstrapState2.status,
51878
- required: bootstrapState2.required,
51879
- configSource: bootstrapState2.configSource,
51880
- configSourceType: bootstrapState2.configSourceType,
51881
- lastCommand: bootstrapState2.lastCommand,
51882
- exitCode: bootstrapState2.exitCode
51883
- }
51884
- }
51885
- });
51886
- } catch {
51887
- }
51888
- };
51889
- const initSubmodules = sourceNode.policy?.initSubmodulesOnClone !== false;
51890
- const loadedBootstrap = loadMeshWorktreeBootstrapConfig(mesh, result.worktreePath);
51891
- const runningBootstrapState = {
51892
- status: "running",
51893
- required: loadedBootstrap.config?.required !== false,
51894
- configSource: loadedBootstrap.path || loadedBootstrap.source,
51895
- configSourceType: loadedBootstrap.sourceType,
51896
- startedAt: (/* @__PURE__ */ new Date()).toISOString()
51897
- };
51898
- await persistWorktreeSetupState(runningBootstrapState);
51899
- const finishWorktreeSetup = async () => {
51900
- let submodulesInitialized2 = false;
51901
- if (initSubmodules) {
51902
- try {
51903
- const { runGit: runGit3 } = await Promise.resolve().then(() => (init_git_executor(), git_executor_exports));
51904
- await runGit3(
51905
- { workspace: result.worktreePath, repoRoot: result.worktreePath, isGitRepo: true },
51906
- ["submodule", "update", "--init", "--recursive"],
51907
- { timeoutMs: 12e4 }
51908
- );
51909
- submodulesInitialized2 = true;
51910
- const sourceWorkspace = sourceNode.repoRoot || sourceNode.workspace;
51911
- if (sourceWorkspace) {
51912
- try {
51913
- const { runGit: rg } = await Promise.resolve().then(() => (init_git_executor(), git_executor_exports));
51914
- const sourceCtx = { workspace: sourceWorkspace, repoRoot: sourceWorkspace, isGitRepo: true };
51915
- const worktreeCtx = { workspace: result.worktreePath, repoRoot: result.worktreePath, isGitRepo: true };
51916
- const sourceStatusOut = await rg(sourceCtx, ["submodule", "status", "oss"], { timeoutMs: 1e4 });
51917
- const sourceStatusLine = (typeof sourceStatusOut === "string" ? sourceStatusOut : sourceStatusOut?.stdout ?? "").trim();
51918
- const sourceShaMatch = sourceStatusLine.match(/^[+\- ]?([0-9a-f]{40})/);
51919
- const sourceSha = sourceShaMatch?.[1];
51920
- if (sourceSha) {
51921
- const ossCtx = { workspace: `${result.worktreePath}/oss`, repoRoot: `${result.worktreePath}/oss`, isGitRepo: true };
51922
- const worktreeOssHeadOut = await rg(ossCtx, ["rev-parse", "HEAD"], { timeoutMs: 1e4 });
51923
- const worktreeOssSha = (typeof worktreeOssHeadOut === "string" ? worktreeOssHeadOut : worktreeOssHeadOut?.stdout ?? "").trim();
51924
- if (worktreeOssSha !== sourceSha) {
51925
- await rg(ossCtx, ["fetch", `${sourceWorkspace}/oss`, "HEAD"], { timeoutMs: 6e4 });
51926
- await rg(ossCtx, ["checkout", sourceSha], { timeoutMs: 1e4 });
51927
- await rg(worktreeCtx, ["add", "oss"], { timeoutMs: 1e4 });
51928
- await rg(worktreeCtx, ["commit", "-m", "chore: sync oss to source node HEAD on clone"], { timeoutMs: 1e4 });
51929
- console.log(`[mesh] Synced oss submodule to source HEAD ${sourceSha.slice(0, 8)} in worktree`);
51930
- }
51931
- }
51932
- } catch (ossErr) {
51933
- console.warn("[mesh] oss submodule sync to source HEAD failed (best-effort):", ossErr.message);
51934
- }
51935
- }
51936
- } catch (subErr) {
51937
- console.warn("[mesh] Submodule init failed for worktree:", subErr.message);
51938
- }
51939
- }
51940
- const bootstrapState2 = await runMeshWorktreeBootstrap(mesh, result.worktreePath);
51941
- await persistWorktreeSetupState(bootstrapState2);
51942
- await appendCloneLedger(submodulesInitialized2, bootstrapState2);
51943
- return { submodulesInitialized: submodulesInitialized2, bootstrapState: bootstrapState2 };
51944
- };
51945
- const requestedSetupWaitMs = Number(args?.setupWaitMs ?? args?.bootstrapWaitMs ?? 8e3);
51946
- const setupWaitMs = Number.isFinite(requestedSetupWaitMs) ? Math.min(Math.max(requestedSetupWaitMs, 0), 14e3) : 8e3;
51947
- const setupPromise = finishWorktreeSetup();
51948
- const setupResult = await Promise.race([
51949
- setupPromise.then((value) => ({ completed: true, value })),
51950
- new Promise((resolve24) => setTimeout(() => resolve24({ completed: false }), setupWaitMs))
51951
- ]);
51952
- const emitBootstrapEvent = (eventStatus2, bootstrapState2, startedAtMs, extraPayload) => {
51953
- try {
51954
- const durationMs = Date.now() - startedAtMs;
51955
- const event = `worktree_${eventStatus2}`;
51956
- const metadataEvent = {
51957
- source: "clone_mesh_node_bootstrap",
51958
- nodeId: node.id,
51959
- status: eventStatus2,
51960
- worktreePath: result.worktreePath,
51961
- durationMs,
51962
- bootstrapStatus: bootstrapState2.status,
51963
- ...bootstrapState2.error ? { error: bootstrapState2.error } : {},
51964
- ...bootstrapState2.exitCode !== void 0 ? { exitCode: bootstrapState2.exitCode } : {},
51965
- ...extraPayload || {}
51966
- };
51967
- if (typeof this.deps.instanceManager?.getByCategory === "function") {
51968
- const forwarded = handleMeshForwardEvent(
51969
- { instanceManager: this.deps.instanceManager },
51970
- { event, meshId, nodeId: node.id, workspace: result.worktreePath, metadataEvent }
51971
- );
51972
- if (forwarded?.success === true) return;
51973
- }
51974
- queuePendingMeshCoordinatorEvent({
51975
- event,
51976
- meshId,
51977
- nodeLabel: node.id,
51978
- nodeId: node.id,
51979
- workspace: result.worktreePath,
51980
- metadataEvent,
51981
- queuedAt: Date.now()
51982
- });
51983
- } catch {
51984
- }
51985
- };
51986
- const bootstrapStartedMs = Date.now();
51987
- if (!setupResult.completed) {
51988
- setupPromise.then(({ bootstrapState: bootstrapState2 }) => {
51989
- emitBootstrapEvent("bootstrap_complete", bootstrapState2, bootstrapStartedMs);
51990
- }).catch((error) => {
51991
- const failedState = {
51992
- ...runningBootstrapState,
51993
- status: "failed",
51994
- completedAt: (/* @__PURE__ */ new Date()).toISOString(),
51995
- error: error?.message || String(error)
51996
- };
51997
- void persistWorktreeSetupState(failedState);
51998
- void appendCloneLedger(false, failedState);
51999
- emitBootstrapEvent("bootstrap_failed", failedState, bootstrapStartedMs, { error: error?.message || String(error) });
52000
- });
52001
- return {
52002
- success: true,
52003
- async: true,
52004
- status: "accepted",
52005
- node,
52006
- worktreePath: result.worktreePath,
52007
- branch: result.branch,
52008
- worktreeBootstrap: runningBootstrapState,
52009
- worktreeSetup: {
52010
- status: "running",
52011
- setupWaitMs,
52012
- message: "Worktree node is registered; submodule/bootstrap setup is continuing in the background."
52013
- }
52014
- };
52015
- }
52016
- const { submodulesInitialized, bootstrapState } = setupResult.value;
52017
- emitBootstrapEvent("bootstrap_complete", bootstrapState, bootstrapStartedMs);
52018
- return {
52019
- success: true,
52020
- node,
52021
- worktreePath: result.worktreePath,
52022
- branch: result.branch,
52023
- submodulesInitialized,
52024
- worktreeBootstrap: bootstrapState
52025
- };
52026
- } catch (e) {
52027
- return { success: false, error: e.message };
52028
- }
52029
- }
52030
- case "retry_mesh_node_bootstrap": {
52031
- const meshId = typeof args?.meshId === "string" ? args.meshId.trim() : "";
52032
- const nodeId = typeof args?.nodeId === "string" ? args.nodeId.trim() : "";
52033
- if (!meshId) return { success: false, error: "meshId required" };
52034
- if (!nodeId) return { success: false, error: "nodeId required" };
52035
- const ownerFailure = await this.requireMeshHostMutationOwner(meshId, args?.inlineMesh, "bootstrap retry");
52036
- if (ownerFailure) return ownerFailure;
52037
- try {
52038
- const meshRecord = await this.getMeshForCommand(meshId, args?.inlineMesh, { preferInline: true });
52039
- const mesh = meshRecord?.mesh;
52040
- if (!mesh) return { success: false, error: "Mesh not found" };
52041
- const node = mesh.nodes?.find((n) => meshNodeIdMatches(n, nodeId));
52042
- if (!node) return { success: false, error: `Node '${nodeId}' not found in mesh` };
52043
- if (!node.isLocalWorktree) return { success: false, error: "Node is not a local worktree node" };
52044
- const nodeDaemonId = typeof node.daemonId === "string" ? node.daemonId.trim() : void 0;
52045
- if (nodeDaemonId && !daemonIdsEquivalent(nodeDaemonId, this.deps.statusInstanceId) && this.deps.dispatchMeshCommand && !args?._meshDirectDispatch) {
52046
- const forwarded = await this.deps.dispatchMeshCommand(nodeDaemonId, "retry_mesh_node_bootstrap", {
52047
- ...typeof args === "object" && args !== null ? args : {},
52048
- _meshDirectDispatch: true
52049
- });
52050
- return forwarded ?? { success: false, error: "no response from remote node" };
52051
- }
52052
- const currentBootstrap = node.worktreeBootstrap;
52053
- if (currentBootstrap?.status === "running") {
52054
- return { success: false, error: "Bootstrap is already running for this node" };
52055
- }
52056
- const worktreePath = node.workspace || node.repoRoot;
52057
- if (!worktreePath) return { success: false, error: "Node has no workspace path" };
52058
- const loadedBootstrap = loadMeshWorktreeBootstrapConfig(mesh, worktreePath);
52059
- const runningState = {
52060
- status: "running",
52061
- required: loadedBootstrap.config?.required !== false,
52062
- configSource: loadedBootstrap.path || loadedBootstrap.source,
52063
- configSourceType: loadedBootstrap.sourceType,
52064
- startedAt: (/* @__PURE__ */ new Date()).toISOString()
52065
- };
52066
- const persistState = async (bootstrapState2) => {
52067
- node.worktreeBootstrap = bootstrapState2;
52068
- if (meshRecord.inline) {
52069
- this.updateInlineMeshNode(meshId, mesh, node);
52070
- return;
52071
- }
52072
- try {
52073
- const { updateNode: updateNode2 } = await Promise.resolve().then(() => (init_mesh_config(), mesh_config_exports));
52074
- updateNode2(meshId, node.id, { worktreeBootstrap: bootstrapState2 });
52075
- this.invalidateAggregateMeshStatus(meshId);
52076
- } catch {
52077
- }
52078
- };
52079
- await persistState(runningState);
52080
- const bootstrapState = await runMeshWorktreeBootstrap(mesh, worktreePath);
52081
- await persistState(bootstrapState);
52082
- return { success: true, bootstrapState };
52083
- } catch (e) {
52084
- return { success: false, error: e.message };
52085
- }
52086
- }
52087
- case "trigger_mesh_queue": {
52088
- const meshId = typeof args?.meshId === "string" ? args.meshId.trim() : "";
52089
- if (!meshId) return { success: false, error: "meshId required" };
52090
- const ownerFailure = await this.requireMeshHostMutationOwner(meshId, args?.inlineMesh, "queue trigger");
52091
- if (ownerFailure) return ownerFailure;
52092
- try {
52093
- const { triggerMeshQueue: triggerMeshQueue2, tryAssignQueueTask: tryAssignQueueTask2 } = await Promise.resolve().then(() => (init_mesh_events(), mesh_events_exports));
52094
- const preferredNodeId = typeof args?.preferredNodeId === "string" ? args.preferredNodeId.trim() : "";
52095
- if (preferredNodeId) {
52096
- const cliInstances = this.deps.instanceManager.getByCategory("cli");
52097
- const sorted = [...cliInstances].sort((a, b) => {
52098
- const aSettings = a.getState().settings || {};
52099
- const bSettings = b.getState().settings || {};
52100
- const aNode = readStringValue(aSettings.meshNodeId, aSettings.nodeId);
52101
- const bNode = readStringValue(bSettings.meshNodeId, bSettings.nodeId);
52102
- return (aNode === preferredNodeId ? -1 : 0) - (bNode === preferredNodeId ? -1 : 0);
52103
- });
52104
- for (const inst of sorted) {
52105
- const state = inst.getState();
52106
- const settings = state.settings || {};
52107
- const nodeId = readStringValue(settings.meshNodeId, settings.nodeId);
52108
- if (!nodeId || nodeId !== preferredNodeId) continue;
52109
- const meshNodeFor = readStringValue(settings.meshNodeFor);
52110
- if (meshNodeFor !== meshId) continue;
52111
- const status = (readStringValue(state.status) || "").toLowerCase();
52112
- if (status !== "idle") continue;
52113
- const sessionId = typeof state.instanceId === "string" ? state.instanceId : "";
52114
- const providerType = readStringValue(state.type, settings.providerType) || "";
52115
- if (sessionId && providerType) {
52116
- tryAssignQueueTask2(this.deps, meshId, nodeId, sessionId, providerType);
52117
- break;
52118
- }
52119
- }
52120
- }
52121
- const trigger = await triggerMeshQueue2(this.deps, meshId);
52122
- return { success: true, trigger };
52123
- } catch (e) {
52124
- return { success: false, error: e.message };
52125
- }
52126
- }
52127
52264
  // ─── Mesh Coordinator Launch ───
52128
52265
  case "launch_mesh_coordinator": {
52129
52266
  const meshId = typeof args?.meshId === "string" ? args.meshId.trim() : "";