@adhdev/daemon-standalone 0.9.82-rc.231 → 0.9.82-rc.233

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.
@@ -224,11 +224,6 @@ var IpcTransport = class {
224
224
  }
225
225
  };
226
226
 
227
- // src/transports/mode.ts
228
- function isLocalTransport(transport) {
229
- return typeof transport.command === "function";
230
- }
231
-
232
227
  // src/tools/chat-compact.ts
233
228
  function messageContent(message) {
234
229
  const content = message?.content;
@@ -410,7 +405,6 @@ var OLD_HISTORICAL_QUEUE_RECORD_MS = 7 * 24 * 60 * 6e4;
410
405
  var ACTIVE_QUEUE_STATUSES = /* @__PURE__ */ new Set(["pending", "assigned"]);
411
406
  var HISTORICAL_QUEUE_STATUSES = /* @__PURE__ */ new Set(["completed", "failed", "cancelled"]);
412
407
  async function refreshMeshFromDaemon(ctx) {
413
- if (!isLocalTransport(ctx.transport)) return;
414
408
  try {
415
409
  const result = await ctx.transport.command("get_mesh", { meshId: ctx.mesh.id });
416
410
  if (!result?.success || !Array.isArray(result.mesh?.nodes)) return;
@@ -934,15 +928,12 @@ async function reconcileDirectDispatchesFromTranscriptEvidence(ctx, liveNodes, d
934
928
  return { attempted, reconciled, skipped };
935
929
  }
936
930
  async function triggerMeshQueueAndReport(ctx, node, opts) {
937
- if (!(isLocalTransport(ctx.transport) || ctx.transport instanceof IpcTransport)) return void 0;
938
931
  try {
939
932
  let raw;
940
933
  if (ctx.transport instanceof IpcTransport && node?.daemonId && opts?.localNode === false) {
941
934
  raw = await ctx.transport.meshCommand(node.daemonId, "trigger_mesh_queue", { meshId: ctx.mesh.id });
942
- } else if (isLocalTransport(ctx.transport)) {
943
- raw = await ctx.transport.command("trigger_mesh_queue", { meshId: ctx.mesh.id });
944
935
  } else {
945
- return void 0;
936
+ raw = await ctx.transport.command("trigger_mesh_queue", { meshId: ctx.mesh.id });
946
937
  }
947
938
  const payload = unwrapCommandPayload(raw);
948
939
  const trigger = payload?.trigger && typeof payload.trigger === "object" ? payload.trigger : payload;
@@ -1592,7 +1583,7 @@ async function collectRelatedRepoStatuses(ctx, node) {
1592
1583
  const results = [];
1593
1584
  for (const repo of relatedRepos) {
1594
1585
  try {
1595
- const statusResult = !isLocalTransport(ctx.transport) && node.daemonId ? await ctx.transport.gitStatus(node.daemonId, repo.workspace, false, true) : await commandForNode(ctx, node, "git_status", { workspace: repo.workspace, refreshUpstream: true });
1586
+ const statusResult = await commandForNode(ctx, node, "git_status", { workspace: repo.workspace, refreshUpstream: true });
1596
1587
  const status = extractGitStatus(statusResult);
1597
1588
  results.push(summarizeRelatedRepoStatus(repo, status));
1598
1589
  } catch (e) {
@@ -1811,11 +1802,7 @@ async function commandForNode(ctx, node, command, args = {}) {
1811
1802
  if (ctx.transport instanceof IpcTransport && node.daemonId && !isLocalNode) {
1812
1803
  return ctx.transport.meshCommand(node.daemonId, command, args);
1813
1804
  }
1814
- if (isLocalTransport(ctx.transport)) {
1815
- return ctx.transport.command(command, args);
1816
- }
1817
- const identity = buildNodeMachineIdentity(ctx, node);
1818
- throw new Error(`Command '${command}' requires daemon IPC/local transport for node '${node.id}' (hostname=${identity.hostname || "unknown"}, coordinatorHostname=${identity.coordinatorHostname || "unknown"}, sameMachine=${identity.sameMachine})`);
1805
+ return ctx.transport.command(command, args);
1819
1806
  }
1820
1807
  function normalizePendingMeshCoordinatorEvents(value) {
1821
1808
  const payload = unwrapCommandPayload(value);
@@ -1893,12 +1880,9 @@ async function drainCoordinatorPendingEvents(ctx, opts) {
1893
1880
  }
1894
1881
  return surfacedEvents;
1895
1882
  }
1896
- if (isLocalTransport(ctx.transport)) {
1897
- const events = (0, import_daemon_core.drainPendingMeshCoordinatorEvents)(ctx.mesh.id, ctx.localDaemonId).filter(matchesCurrentMesh);
1898
- events.forEach(rememberMeshSessionProviderMetadataFromEvent);
1899
- return events;
1900
- }
1901
- return [];
1883
+ const events = (0, import_daemon_core.drainPendingMeshCoordinatorEvents)(ctx.mesh.id, ctx.localDaemonId).filter(matchesCurrentMesh);
1884
+ events.forEach(rememberMeshSessionProviderMetadataFromEvent);
1885
+ return events;
1902
1886
  }
1903
1887
  function isP2pTransportUnavailableError(error) {
1904
1888
  return (0, import_daemon_core.isP2pRelayTransportFailure)(error);
@@ -2299,47 +2283,26 @@ async function meshStatus(ctx, args = {}) {
2299
2283
  ...getNodeLaunchReadiness(node)
2300
2284
  };
2301
2285
  try {
2302
- if (!isLocalTransport(transport) && node.daemonId) {
2303
- const result = await transport.gitStatus(node.daemonId, node.workspace, false, true);
2304
- const status = extractGitStatus(result);
2305
- const uncommittedChanges = countUncommittedChanges(status);
2306
- const dirty = isGitStatusDirty(status);
2307
- entry.health = status?.isGitRepo ? dirty ? "dirty" : "online" : "degraded";
2308
- assignFullGitSnapshot(entry, status);
2309
- entry.branch = status?.branch;
2310
- entry.isDirty = dirty;
2311
- entry.uncommittedChanges = uncommittedChanges;
2312
- entry.branchConvergence = buildBranchConvergence(mesh, node, status, dirty, uncommittedChanges);
2313
- const submodules = extractSubmodules(result, node.policy?.submoduleIgnorePaths || []);
2314
- if (submodules && submodules.some((s) => s?.outOfSync)) {
2315
- entry.submoduleWarning = "One or more submodules are out of sync with the parent repo. Run `git submodule update` or check deployment readiness.";
2316
- entry.outOfSyncSubmodules = submodules.filter((s) => s?.outOfSync).map((s) => s.path);
2317
- }
2318
- } else if (isLocalTransport(transport)) {
2319
- const autoDiscover = node.policy?.autoDiscoverSubmodules !== false;
2320
- const statusResult = await commandForNode(ctx, node, "git_status", {
2321
- workspace: node.workspace,
2322
- refreshUpstream: true,
2323
- includeSubmodules: autoDiscover,
2324
- submoduleIgnorePaths: node.policy?.submoduleIgnorePaths || void 0
2325
- });
2326
- const status = extractGitStatus(statusResult);
2327
- const uncommittedChanges = countUncommittedChanges(status);
2328
- const dirty = isGitStatusDirty(status);
2329
- entry.health = status?.isGitRepo ? dirty ? "dirty" : "online" : "degraded";
2330
- assignFullGitSnapshot(entry, status);
2331
- entry.branch = status?.branch;
2332
- entry.isDirty = dirty;
2333
- entry.uncommittedChanges = uncommittedChanges;
2334
- entry.branchConvergence = buildBranchConvergence(mesh, node, status, dirty, uncommittedChanges);
2335
- const submodules = extractSubmodules(statusResult, node.policy?.submoduleIgnorePaths || []);
2336
- if (submodules && submodules.some((s) => s?.outOfSync)) {
2337
- entry.submoduleWarning = "One or more submodules are out of sync with the parent repo. Run `git submodule update` or check deployment readiness.";
2338
- entry.outOfSyncSubmodules = submodules.filter((s) => s?.outOfSync).map((s) => s.path);
2339
- }
2340
- } else {
2341
- entry.health = "unknown";
2342
- entry.note = "No daemonId available for cloud status probe";
2286
+ const autoDiscover = node.policy?.autoDiscoverSubmodules !== false;
2287
+ const statusResult = await commandForNode(ctx, node, "git_status", {
2288
+ workspace: node.workspace,
2289
+ refreshUpstream: true,
2290
+ includeSubmodules: autoDiscover,
2291
+ submoduleIgnorePaths: node.policy?.submoduleIgnorePaths || void 0
2292
+ });
2293
+ const status = extractGitStatus(statusResult);
2294
+ const uncommittedChanges = countUncommittedChanges(status);
2295
+ const dirty = isGitStatusDirty(status);
2296
+ entry.health = status?.isGitRepo ? dirty ? "dirty" : "online" : "degraded";
2297
+ assignFullGitSnapshot(entry, status);
2298
+ entry.branch = status?.branch;
2299
+ entry.isDirty = dirty;
2300
+ entry.uncommittedChanges = uncommittedChanges;
2301
+ entry.branchConvergence = buildBranchConvergence(mesh, node, status, dirty, uncommittedChanges);
2302
+ const submodules = extractSubmodules(statusResult, node.policy?.submoduleIgnorePaths || []);
2303
+ if (submodules && submodules.some((s) => s?.outOfSync)) {
2304
+ entry.submoduleWarning = "One or more submodules are out of sync with the parent repo. Run `git submodule update` or check deployment readiness.";
2305
+ entry.outOfSyncSubmodules = submodules.filter((s) => s?.outOfSync).map((s) => s.path);
2343
2306
  }
2344
2307
  } catch (e) {
2345
2308
  const failure = buildCoordinatorP2pRelayFailure(e, {
@@ -2671,7 +2634,7 @@ async function meshEnqueueTask(ctx, args) {
2671
2634
  const missionId = readString(args.missionId) || readString(args.mission_id) || void 0;
2672
2635
  try {
2673
2636
  const task = (0, import_daemon_core.enqueueTask)(ctx.mesh.id, args.message, { taskMode, requiredTags, dependsOn, missionId });
2674
- if (isLocalTransport(ctx.transport) && !(ctx.transport instanceof IpcTransport)) {
2637
+ if (!(ctx.transport instanceof IpcTransport)) {
2675
2638
  const queueTrigger = await triggerMeshQueueAndReport(ctx);
2676
2639
  return JSON.stringify({
2677
2640
  success: true,
@@ -2684,7 +2647,7 @@ async function meshEnqueueTask(ctx, args) {
2684
2647
  ...buildQueueTriggerGuidance(queueTrigger)
2685
2648
  });
2686
2649
  }
2687
- if (ctx.transport instanceof IpcTransport) {
2650
+ {
2688
2651
  const queueTrigger = await triggerMeshQueueAndReport(ctx);
2689
2652
  const dispatchPromises = [];
2690
2653
  for (const node of ctx.mesh.nodes) {
@@ -2748,7 +2711,6 @@ async function meshEnqueueTask(ctx, args) {
2748
2711
  ...buildQueueTriggerGuidance(queueTrigger)
2749
2712
  });
2750
2713
  }
2751
- return JSON.stringify({ success: true, source: "queue", taskId: task.id, status: task.status, taskMode: task.taskMode, requiredTags: task.requiredTags });
2752
2714
  } catch (e) {
2753
2715
  const message = e?.message || String(e);
2754
2716
  if (message.includes("live_debug_readonly_guardrail_violation")) {
@@ -2864,10 +2826,8 @@ async function meshQueueCancel(ctx, args) {
2864
2826
  if (!taskId) return JSON.stringify({ success: false, error: "task_id required" });
2865
2827
  const task = (0, import_daemon_core.cancelTask)(ctx.mesh.id, taskId, { reason: args.reason });
2866
2828
  if (!task) return JSON.stringify({ success: false, error: `Queue task '${taskId}' not found` });
2867
- if (isLocalTransport(ctx.transport)) {
2868
- ctx.transport.command("trigger_mesh_queue", { meshId: ctx.mesh.id }).catch(() => {
2869
- });
2870
- }
2829
+ ctx.transport.command("trigger_mesh_queue", { meshId: ctx.mesh.id }).catch(() => {
2830
+ });
2871
2831
  return JSON.stringify({ success: true, task }, null, 2);
2872
2832
  } catch (e) {
2873
2833
  return JSON.stringify({ success: false, error: e.message });
@@ -2898,10 +2858,8 @@ async function meshQueueRequeue(ctx, args) {
2898
2858
  hint: "Use force=true to bypass the retry cap for explicit operator recovery."
2899
2859
  }, null, 2);
2900
2860
  }
2901
- if (isLocalTransport(ctx.transport)) {
2902
- ctx.transport.command("trigger_mesh_queue", { meshId: ctx.mesh.id }).catch(() => {
2903
- });
2904
- }
2861
+ ctx.transport.command("trigger_mesh_queue", { meshId: ctx.mesh.id }).catch(() => {
2862
+ });
2905
2863
  return JSON.stringify({ success: true, task }, null, 2);
2906
2864
  } catch (e) {
2907
2865
  return JSON.stringify({ success: false, error: e.message });
@@ -2926,7 +2884,7 @@ async function meshSendTask(ctx, args) {
2926
2884
  return JSON.stringify({ error: `Node '${args.node_id}' is read-only` });
2927
2885
  }
2928
2886
  let explicitTargetSession;
2929
- if (args.session_id && isWorkerTaskMode(taskMode) && (ctx.transport instanceof IpcTransport || isLocalTransport(ctx.transport))) {
2887
+ if (args.session_id && isWorkerTaskMode(taskMode)) {
2930
2888
  try {
2931
2889
  const statusResult = await commandForNode(ctx, node, "get_status_metadata", {});
2932
2890
  const sessions = extractStatusMetadataSessions(statusResult);
@@ -2981,15 +2939,6 @@ async function meshSendTask(ctx, args) {
2981
2939
  });
2982
2940
  }
2983
2941
  try {
2984
- if (!isLocalTransport(ctx.transport) && node.daemonId) {
2985
- const res = await ctx.transport.meshEnqueueTask(node.daemonId, {
2986
- meshId: ctx.mesh.id,
2987
- message: args.message,
2988
- targetNodeId: args.node_id,
2989
- ...taskMode ? { taskMode } : {}
2990
- });
2991
- return JSON.stringify(res);
2992
- }
2993
2942
  const isLocalNode = isLocalControlPlaneNode(ctx, node);
2994
2943
  if (ctx.transport instanceof IpcTransport && node.daemonId && !isLocalNode) {
2995
2944
  const cached = getSessionMetadata(meshSessionCacheKey(args.node_id, args.session_id || ""));
@@ -3047,7 +2996,7 @@ async function meshSendTask(ctx, args) {
3047
2996
  dispatched: result2.success === true
3048
2997
  });
3049
2998
  }
3050
- if (args.session_id && isLocalTransport(ctx.transport)) {
2999
+ if (args.session_id) {
3051
3000
  const cached = getSessionMetadata(meshSessionCacheKey(args.node_id, args.session_id));
3052
3001
  let resolvedProviderType = cached?.providerType || "";
3053
3002
  if (!resolvedProviderType) {
@@ -3244,8 +3193,8 @@ async function meshSendTask(ctx, args) {
3244
3193
  targetSessionId: args.session_id,
3245
3194
  taskMode
3246
3195
  });
3247
- const queueTrigger = isLocalTransport(ctx.transport) || ctx.transport instanceof IpcTransport ? await triggerMeshQueueAndReport(ctx) : void 0;
3248
- const pendingEvents = isLocalTransport(ctx.transport) ? (0, import_daemon_core.drainPendingMeshCoordinatorEvents)(ctx.mesh.id, ctx.localDaemonId) : [];
3196
+ const queueTrigger = await triggerMeshQueueAndReport(ctx);
3197
+ const pendingEvents = (0, import_daemon_core.drainPendingMeshCoordinatorEvents)(ctx.mesh.id, ctx.localDaemonId);
3249
3198
  const result = {
3250
3199
  success: true,
3251
3200
  source: "queue",
@@ -3275,91 +3224,59 @@ async function meshReadChat(ctx, args) {
3275
3224
  if (!node) {
3276
3225
  return JSON.stringify(buildMissingNodeReadChatRecovery(ctx, args), null, 2);
3277
3226
  }
3278
- if (ctx.transport instanceof IpcTransport || isLocalTransport(ctx.transport)) {
3279
- await drainCoordinatorPendingEvents(ctx, { nodeIds: [args.node_id] });
3280
- }
3281
- if (isLocalTransport(ctx.transport)) {
3282
- const cached = resolveMeshSessionProviderMetadata(ctx, args.node_id, args.session_id);
3283
- const providerSessionId = typeof args.provider_session_id === "string" && args.provider_session_id.trim() ? args.provider_session_id.trim() : cached?.providerSessionId;
3284
- const result = await commandForNode(ctx, node, "read_chat", {
3227
+ await drainCoordinatorPendingEvents(ctx, { nodeIds: [args.node_id] });
3228
+ const cached = resolveMeshSessionProviderMetadata(ctx, args.node_id, args.session_id);
3229
+ const providerSessionId = typeof args.provider_session_id === "string" && args.provider_session_id.trim() ? args.provider_session_id.trim() : cached?.providerSessionId;
3230
+ const result = await commandForNode(ctx, node, "read_chat", {
3231
+ sessionId: args.session_id,
3232
+ targetSessionId: args.session_id,
3233
+ workspace: node.workspace,
3234
+ ...cached?.providerType ? { agentType: cached.providerType, providerType: cached.providerType } : {},
3235
+ ...providerSessionId ? { providerSessionId } : {},
3236
+ tailLimit: args.tail ?? 10
3237
+ });
3238
+ const payload = annotateRapidReadChatAdvisory(unwrapCommandPayload(result), {
3239
+ key: `mesh:${args.node_id}:${args.session_id}`,
3240
+ toolName: "mesh_read_chat",
3241
+ completionCallbackExpected: true
3242
+ });
3243
+ const useCompact = args.compact !== false;
3244
+ if (useCompact) {
3245
+ const compactPayload = compactChatPayload(payload, {
3246
+ nodeId: args.node_id,
3285
3247
  sessionId: args.session_id,
3286
- targetSessionId: args.session_id,
3287
- workspace: node.workspace,
3288
- ...cached?.providerType ? { agentType: cached.providerType, providerType: cached.providerType } : {},
3289
- ...providerSessionId ? { providerSessionId } : {},
3290
- tailLimit: args.tail ?? 10
3291
- });
3292
- const payload = annotateRapidReadChatAdvisory(unwrapCommandPayload(result), {
3293
- key: `mesh:${args.node_id}:${args.session_id}`,
3294
- toolName: "mesh_read_chat",
3295
- completionCallbackExpected: true
3248
+ limit: args.tail ?? 10
3296
3249
  });
3297
- const useCompact = args.compact !== false;
3298
- if (useCompact) {
3299
- const compactPayload = compactChatPayload(payload, {
3300
- nodeId: args.node_id,
3301
- sessionId: args.session_id,
3302
- limit: args.tail ?? 10
3303
- });
3304
- return JSON.stringify(
3305
- payload.pollingAdvisory ? { ...compactPayload, pollingAdvisory: payload.pollingAdvisory } : compactPayload,
3306
- null,
3307
- 2
3308
- );
3309
- }
3310
- return JSON.stringify(payload, null, 2);
3311
- } else if (!isLocalTransport(ctx.transport) && node.daemonId) {
3312
- try {
3313
- const targetId = `${node.daemonId}:session:${args.session_id}`;
3314
- const res = await ctx.transport.readChat(targetId, {
3315
- limit: args.tail ?? 10,
3316
- sessionId: args.session_id
3317
- });
3318
- return JSON.stringify(res, null, 2);
3319
- } catch (e) {
3320
- return JSON.stringify({ success: false, error: e.message });
3321
- }
3322
- } else {
3323
- return JSON.stringify({ error: "Cloud mesh read_chat requires node daemonId" });
3250
+ return JSON.stringify(
3251
+ payload.pollingAdvisory ? { ...compactPayload, pollingAdvisory: payload.pollingAdvisory } : compactPayload,
3252
+ null,
3253
+ 2
3254
+ );
3324
3255
  }
3256
+ return JSON.stringify(payload, null, 2);
3325
3257
  }
3326
3258
  async function meshReadDebug(ctx, args) {
3327
3259
  const node = await findNodeWithRefresh(ctx, args.node_id);
3328
- if (isLocalTransport(ctx.transport)) {
3329
- const cached = resolveMeshSessionProviderMetadata(ctx, args.node_id, args.session_id);
3330
- const providerSessionId = typeof args.provider_session_id === "string" && args.provider_session_id.trim() ? args.provider_session_id.trim() : cached?.providerSessionId;
3331
- const delivery = args.delivery === "inline" ? void 0 : "daemon_file";
3332
- const result = await commandForNode(ctx, node, "get_chat_debug_bundle", {
3333
- sessionId: args.session_id,
3334
- targetSessionId: args.session_id,
3335
- workspace: node.workspace,
3336
- ...cached?.providerType ? { agentType: cached.providerType, providerType: cached.providerType } : {},
3337
- ...providerSessionId ? { providerSessionId } : {},
3338
- tailLimit: args.tail ?? 40,
3339
- ...delivery ? { delivery } : {}
3340
- });
3341
- const payload = unwrapCommandPayload(result);
3342
- return JSON.stringify(payload, null, 2);
3343
- } else if (!isLocalTransport(ctx.transport) && node.daemonId) {
3344
- try {
3345
- const targetId = `${node.daemonId}:session:${args.session_id}`;
3346
- const res = await ctx.transport.getChatDebugBundle(targetId, {
3347
- sessionId: args.session_id,
3348
- tailLimit: args.tail ?? 40,
3349
- delivery: args.delivery
3350
- });
3351
- return JSON.stringify(res, null, 2);
3352
- } catch (e) {
3353
- return JSON.stringify({ success: false, error: e.message });
3354
- }
3355
- }
3356
- return JSON.stringify({ error: "Cloud mesh read_debug requires node daemonId" });
3260
+ const cached = resolveMeshSessionProviderMetadata(ctx, args.node_id, args.session_id);
3261
+ const providerSessionId = typeof args.provider_session_id === "string" && args.provider_session_id.trim() ? args.provider_session_id.trim() : cached?.providerSessionId;
3262
+ const delivery = args.delivery === "inline" ? void 0 : "daemon_file";
3263
+ const result = await commandForNode(ctx, node, "get_chat_debug_bundle", {
3264
+ sessionId: args.session_id,
3265
+ targetSessionId: args.session_id,
3266
+ workspace: node.workspace,
3267
+ ...cached?.providerType ? { agentType: cached.providerType, providerType: cached.providerType } : {},
3268
+ ...providerSessionId ? { providerSessionId } : {},
3269
+ tailLimit: args.tail ?? 40,
3270
+ ...delivery ? { delivery } : {}
3271
+ });
3272
+ const payload = unwrapCommandPayload(result);
3273
+ return JSON.stringify(payload, null, 2);
3357
3274
  }
3358
3275
  async function meshLaunchSession(ctx, args) {
3359
3276
  const node = await findNodeWithRefresh(ctx, args.node_id);
3360
3277
  const bootstrapBlock = getWorktreeBootstrapLaunchBlock(node, ctx.mesh.policy);
3361
3278
  if (bootstrapBlock) return JSON.stringify(bootstrapBlock, null, 2);
3362
- if (isLocalTransport(ctx.transport)) {
3279
+ {
3363
3280
  let resolvedProviderType = typeof args.type === "string" && args.type.trim() ? args.type : "";
3364
3281
  if (!resolvedProviderType) {
3365
3282
  const providerPriority = readProviderPriority(node.policy);
@@ -3439,51 +3356,6 @@ async function meshLaunchSession(ctx, args) {
3439
3356
  queueTrigger,
3440
3357
  ...buildQueueTriggerGuidance(queueTrigger)
3441
3358
  }, null, 2);
3442
- } else if (!isLocalTransport(ctx.transport) && node.daemonId) {
3443
- let resolvedProviderType = typeof args.type === "string" && args.type.trim() ? args.type : "";
3444
- if (!resolvedProviderType) {
3445
- const providerPriority = readProviderPriority(node.policy);
3446
- if (!providerPriority.length) {
3447
- return JSON.stringify({ success: false, error: missingProviderPriorityMessage(args.node_id) });
3448
- }
3449
- resolvedProviderType = providerPriority[0];
3450
- }
3451
- const coordinatorNode = resolveCoordinatorNode(ctx);
3452
- const coordinatorDaemonId = coordinatorNode?.daemonId || ctx.localDaemonId;
3453
- const spawnedSessionVisibility = readSpawnedSessionVisibility(ctx.mesh.policy);
3454
- if (!coordinatorDaemonId) {
3455
- return JSON.stringify(buildMissingCoordinatorDaemonIdFailure(ctx, node, resolvedProviderType), null, 2);
3456
- }
3457
- try {
3458
- const res = await ctx.transport.launch(node.daemonId, {
3459
- type: resolvedProviderType,
3460
- dir: node.workspace,
3461
- settings: {
3462
- meshNodeFor: ctx.mesh.id,
3463
- meshNodeId: args.node_id,
3464
- spawnedSessionVisibility,
3465
- ...coordinatorDaemonId ? { meshCoordinatorDaemonId: coordinatorDaemonId } : {},
3466
- ...coordinatorNode?.id ? { meshCoordinatorNodeId: coordinatorNode.id } : {},
3467
- launchedByCoordinator: true
3468
- }
3469
- });
3470
- const runtimeSessionId = typeof res?.sessionId === "string" ? res.sessionId : typeof res?.id === "string" ? res.id : "";
3471
- try {
3472
- (0, import_daemon_core.appendLedgerEntry)(ctx.mesh.id, {
3473
- kind: "session_launched",
3474
- nodeId: args.node_id,
3475
- sessionId: runtimeSessionId || void 0,
3476
- providerType: resolvedProviderType,
3477
- payload: {}
3478
- });
3479
- } catch {
3480
- }
3481
- return JSON.stringify({ ...res, resolvedProviderType }, null, 2);
3482
- } catch (e) {
3483
- return JSON.stringify(recordRecoverableLaunchFailure(ctx, node, resolvedProviderType, e), null, 2);
3484
- }
3485
- } else {
3486
- return JSON.stringify({ error: "Cloud mesh launch_session requires node daemonId" });
3487
3359
  }
3488
3360
  }
3489
3361
  async function meshGitStatus(ctx, args) {
@@ -3491,37 +3363,23 @@ async function meshGitStatus(ctx, args) {
3491
3363
  const autoDiscoverSubmodules = node.policy?.autoDiscoverSubmodules !== false;
3492
3364
  const submoduleIgnorePaths = node.policy?.submoduleIgnorePaths || [];
3493
3365
  try {
3494
- if (!isLocalTransport(ctx.transport) && node.daemonId) {
3495
- const result = await ctx.transport.gitStatus(node.daemonId, node.workspace, true, true);
3496
- return JSON.stringify({
3497
- nodeId: args.node_id,
3498
- workspace: node.workspace,
3499
- status: extractGitStatus(result),
3500
- diff: extractGitDiff(result),
3501
- submodules: autoDiscoverSubmodules ? extractSubmodules(result, submoduleIgnorePaths) : void 0,
3502
- relatedRepos: await collectRelatedRepoStatuses(ctx, node)
3503
- }, null, 2);
3504
- } else if (isLocalTransport(ctx.transport)) {
3505
- const statusResult = await commandForNode(ctx, node, "git_status", {
3506
- workspace: node.workspace,
3507
- refreshUpstream: true,
3508
- includeSubmodules: autoDiscoverSubmodules,
3509
- submoduleIgnorePaths: submoduleIgnorePaths.length > 0 ? submoduleIgnorePaths : void 0
3510
- });
3511
- const diffResult = await commandForNode(ctx, node, "git_diff_summary", {
3512
- workspace: node.workspace
3513
- });
3514
- return JSON.stringify({
3515
- nodeId: args.node_id,
3516
- workspace: node.workspace,
3517
- status: extractGitStatus(statusResult),
3518
- diff: extractGitDiff(diffResult),
3519
- submodules: autoDiscoverSubmodules ? extractSubmodules(statusResult, submoduleIgnorePaths) : void 0,
3520
- relatedRepos: await collectRelatedRepoStatuses(ctx, node)
3521
- }, null, 2);
3522
- } else {
3523
- return JSON.stringify({ error: "No daemonId available for cloud git_status probe" });
3524
- }
3366
+ const statusResult = await commandForNode(ctx, node, "git_status", {
3367
+ workspace: node.workspace,
3368
+ refreshUpstream: true,
3369
+ includeSubmodules: autoDiscoverSubmodules,
3370
+ submoduleIgnorePaths: submoduleIgnorePaths.length > 0 ? submoduleIgnorePaths : void 0
3371
+ });
3372
+ const diffResult = await commandForNode(ctx, node, "git_diff_summary", {
3373
+ workspace: node.workspace
3374
+ });
3375
+ return JSON.stringify({
3376
+ nodeId: args.node_id,
3377
+ workspace: node.workspace,
3378
+ status: extractGitStatus(statusResult),
3379
+ diff: extractGitDiff(diffResult),
3380
+ submodules: autoDiscoverSubmodules ? extractSubmodules(statusResult, submoduleIgnorePaths) : void 0,
3381
+ relatedRepos: await collectRelatedRepoStatuses(ctx, node)
3382
+ }, null, 2);
3525
3383
  } catch (e) {
3526
3384
  const failure = buildCoordinatorP2pRelayFailure(e, {
3527
3385
  command: "git_status",
@@ -3584,211 +3442,104 @@ async function meshCheckpoint(ctx, args) {
3584
3442
  if (node.policy?.readOnly) {
3585
3443
  return JSON.stringify({ error: `Node '${args.node_id}' is read-only \u2014 cannot checkpoint` });
3586
3444
  }
3587
- if (isLocalTransport(ctx.transport)) {
3588
- const result = await commandForNode(ctx, node, "git_checkpoint", {
3589
- workspace: node.workspace,
3590
- message: args.message,
3591
- includeUntracked: true
3592
- });
3593
- try {
3594
- (0, import_daemon_core.appendLedgerEntry)(ctx.mesh.id, {
3595
- kind: "checkpoint_created",
3596
- nodeId: args.node_id,
3597
- payload: {
3598
- message: args.message,
3599
- commit: result?.checkpoint?.commit,
3600
- outcome: result?.checkpoint?.status || (result?.checkpoint?.noop ? "skipped" : void 0),
3601
- noop: result?.checkpoint?.noop === true,
3602
- reason: result?.checkpoint?.reason
3603
- }
3604
- });
3605
- } catch {
3606
- }
3607
- return JSON.stringify(result, null, 2);
3608
- } else if (!isLocalTransport(ctx.transport) && node.daemonId) {
3609
- try {
3610
- const res = await ctx.transport.gitCheckpoint(node.daemonId, {
3611
- workspace: node.workspace,
3445
+ const result = await commandForNode(ctx, node, "git_checkpoint", {
3446
+ workspace: node.workspace,
3447
+ message: args.message,
3448
+ includeUntracked: true
3449
+ });
3450
+ try {
3451
+ (0, import_daemon_core.appendLedgerEntry)(ctx.mesh.id, {
3452
+ kind: "checkpoint_created",
3453
+ nodeId: args.node_id,
3454
+ payload: {
3612
3455
  message: args.message,
3613
- includeUntracked: true
3614
- });
3615
- try {
3616
- (0, import_daemon_core.appendLedgerEntry)(ctx.mesh.id, {
3617
- kind: "checkpoint_created",
3618
- nodeId: args.node_id,
3619
- payload: {
3620
- message: args.message,
3621
- commit: res?.checkpoint?.commit,
3622
- outcome: res?.checkpoint?.status || (res?.checkpoint?.noop ? "skipped" : void 0),
3623
- noop: res?.checkpoint?.noop === true,
3624
- reason: res?.checkpoint?.reason
3625
- }
3626
- });
3627
- } catch {
3456
+ commit: result?.checkpoint?.commit,
3457
+ outcome: result?.checkpoint?.status || (result?.checkpoint?.noop ? "skipped" : void 0),
3458
+ noop: result?.checkpoint?.noop === true,
3459
+ reason: result?.checkpoint?.reason
3628
3460
  }
3629
- return JSON.stringify(res, null, 2);
3630
- } catch (e) {
3631
- return JSON.stringify({ success: false, error: e.message });
3632
- }
3633
- } else {
3634
- return JSON.stringify({ error: "Cloud mesh checkpoint requires node daemonId" });
3461
+ });
3462
+ } catch {
3635
3463
  }
3464
+ return JSON.stringify(result, null, 2);
3636
3465
  }
3637
3466
  async function meshApprove(ctx, args) {
3638
3467
  const node = await findNodeWithRefresh(ctx, args.node_id);
3639
- if (isLocalTransport(ctx.transport)) {
3640
- const cached = getSessionMetadata(meshSessionCacheKey(args.node_id, args.session_id));
3641
- const providerSessionId = cached?.providerSessionId;
3642
- const result = await commandForNode(ctx, node, "resolve_action", {
3643
- sessionId: args.session_id,
3644
- targetSessionId: args.session_id,
3645
- workspace: node.workspace,
3646
- ...cached?.providerType ? { agentType: cached.providerType, providerType: cached.providerType } : {},
3647
- ...providerSessionId ? { providerSessionId } : {},
3648
- action: args.action === "reject" ? "reject" : "approve"
3649
- });
3650
- return JSON.stringify(result, null, 2);
3651
- } else if (!isLocalTransport(ctx.transport) && node.daemonId) {
3652
- try {
3653
- const targetId = `${node.daemonId}:session:${args.session_id}`;
3654
- const res = await ctx.transport.approve(targetId, args.action === "reject" ? "reject" : "approve");
3655
- return JSON.stringify(res, null, 2);
3656
- } catch (e) {
3657
- return JSON.stringify({ success: false, error: e.message });
3658
- }
3659
- } else {
3660
- return JSON.stringify({ error: "Cloud mesh approve requires node daemonId" });
3661
- }
3468
+ const cached = getSessionMetadata(meshSessionCacheKey(args.node_id, args.session_id));
3469
+ const providerSessionId = cached?.providerSessionId;
3470
+ const result = await commandForNode(ctx, node, "resolve_action", {
3471
+ sessionId: args.session_id,
3472
+ targetSessionId: args.session_id,
3473
+ workspace: node.workspace,
3474
+ ...cached?.providerType ? { agentType: cached.providerType, providerType: cached.providerType } : {},
3475
+ ...providerSessionId ? { providerSessionId } : {},
3476
+ action: args.action === "reject" ? "reject" : "approve"
3477
+ });
3478
+ return JSON.stringify(result, null, 2);
3662
3479
  }
3663
3480
  async function meshCloneNode(ctx, args) {
3664
3481
  const sourceNode = await findNodeWithRefresh(ctx, args.source_node_id);
3665
- if (isLocalTransport(ctx.transport)) {
3666
- const result = await commandForNode(ctx, sourceNode, "clone_mesh_node", {
3667
- meshId: ctx.mesh.id,
3668
- sourceNodeId: args.source_node_id,
3669
- branch: args.branch,
3670
- baseBranch: args.base_branch,
3671
- inlineMesh: ctx.mesh
3672
- });
3673
- const clonePayload = extractCloneNodePayload(result);
3674
- if (clonePayload?.success && clonePayload.node?.id) {
3675
- const existingIndex = ctx.mesh.nodes.findIndex((n) => n.id === clonePayload.node.id);
3676
- if (existingIndex >= 0) ctx.mesh.nodes[existingIndex] = clonePayload.node;
3677
- else ctx.mesh.nodes.push(clonePayload.node);
3678
- ctx.mesh.updatedAt = (/* @__PURE__ */ new Date()).toISOString();
3679
- await syncCoordinatorDaemonMeshCache(ctx);
3680
- }
3681
- return JSON.stringify(result, null, 2);
3682
- } else if (!isLocalTransport(ctx.transport) && sourceNode.daemonId) {
3683
- try {
3684
- const res = await ctx.transport.meshCloneNode(sourceNode.daemonId, {
3685
- meshId: ctx.mesh.id,
3686
- sourceNodeId: args.source_node_id,
3687
- branch: args.branch,
3688
- baseBranch: args.base_branch,
3689
- inlineMesh: ctx.mesh
3690
- });
3691
- const clonePayload = extractCloneNodePayload(res);
3692
- if (clonePayload?.success && clonePayload.node?.id) {
3693
- const existingIndex = ctx.mesh.nodes.findIndex((n) => n.id === clonePayload.node.id);
3694
- if (existingIndex >= 0) ctx.mesh.nodes[existingIndex] = clonePayload.node;
3695
- else ctx.mesh.nodes.push(clonePayload.node);
3696
- ctx.mesh.updatedAt = (/* @__PURE__ */ new Date()).toISOString();
3697
- await syncCoordinatorDaemonMeshCache(ctx);
3698
- }
3699
- return JSON.stringify(res, null, 2);
3700
- } catch (e) {
3701
- return JSON.stringify({ success: false, error: e.message });
3702
- }
3703
- } else {
3704
- return JSON.stringify({ error: "Cloud mesh clone_node requires source node daemonId" });
3482
+ const result = await commandForNode(ctx, sourceNode, "clone_mesh_node", {
3483
+ meshId: ctx.mesh.id,
3484
+ sourceNodeId: args.source_node_id,
3485
+ branch: args.branch,
3486
+ baseBranch: args.base_branch,
3487
+ inlineMesh: ctx.mesh
3488
+ });
3489
+ const clonePayload = extractCloneNodePayload(result);
3490
+ if (clonePayload?.success && clonePayload.node?.id) {
3491
+ const existingIndex = ctx.mesh.nodes.findIndex((n) => n.id === clonePayload.node.id);
3492
+ if (existingIndex >= 0) ctx.mesh.nodes[existingIndex] = clonePayload.node;
3493
+ else ctx.mesh.nodes.push(clonePayload.node);
3494
+ ctx.mesh.updatedAt = (/* @__PURE__ */ new Date()).toISOString();
3495
+ await syncCoordinatorDaemonMeshCache(ctx);
3705
3496
  }
3497
+ return JSON.stringify(result, null, 2);
3706
3498
  }
3707
3499
  async function meshCleanupSessions(ctx, args) {
3708
3500
  const node = await findNodeWithRefresh(ctx, args.node_id);
3709
- if (isLocalTransport(ctx.transport)) {
3710
- const result = await commandForNode(ctx, node, "cleanup_mesh_sessions", {
3711
- meshId: ctx.mesh.id,
3712
- nodeId: args.node_id,
3713
- mode: args.mode,
3714
- sessionIds: args.session_ids,
3715
- dryRun: args.dry_run === true,
3716
- inlineMesh: ctx.mesh
3717
- });
3718
- return JSON.stringify(result, null, 2);
3719
- } else if (!isLocalTransport(ctx.transport) && node.daemonId) {
3720
- try {
3721
- const res = await ctx.transport.meshCleanupSessions(node.daemonId, {
3722
- meshId: ctx.mesh.id,
3723
- nodeId: args.node_id,
3724
- mode: args.mode,
3725
- sessionIds: args.session_ids,
3726
- dryRun: args.dry_run === true,
3727
- inlineMesh: ctx.mesh
3728
- });
3729
- return JSON.stringify(res, null, 2);
3730
- } catch (e) {
3731
- return JSON.stringify({ success: false, error: e.message });
3732
- }
3733
- } else {
3734
- return JSON.stringify({ error: "Cloud mesh cleanup_sessions requires node daemonId" });
3735
- }
3501
+ const result = await commandForNode(ctx, node, "cleanup_mesh_sessions", {
3502
+ meshId: ctx.mesh.id,
3503
+ nodeId: args.node_id,
3504
+ mode: args.mode,
3505
+ sessionIds: args.session_ids,
3506
+ dryRun: args.dry_run === true,
3507
+ inlineMesh: ctx.mesh
3508
+ });
3509
+ return JSON.stringify(result, null, 2);
3736
3510
  }
3737
3511
  async function meshRemoveNode(ctx, args) {
3738
3512
  const node = await findNodeWithRefresh(ctx, args.node_id);
3739
- if (isLocalTransport(ctx.transport)) {
3740
- const removeArgs = buildRemoveNodeArgs(ctx, args.node_id, args.session_cleanup_mode);
3741
- let result;
3742
- let transportFallback;
3743
- try {
3744
- result = await commandForNode(ctx, node, "remove_mesh_node", removeArgs);
3745
- } catch (e) {
3746
- if (ctx.transport instanceof IpcTransport && node.isLocalWorktree && isP2pTransportUnavailableError(e)) {
3747
- result = await ctx.transport.command("remove_mesh_node", removeArgs);
3748
- transportFallback = {
3749
- from: "p2p_mesh_relay",
3750
- to: "local_control_plane",
3751
- reason: e?.message || String(e)
3752
- };
3753
- } else {
3754
- return JSON.stringify({
3755
- success: false,
3756
- code: isP2pTransportUnavailableError(e) ? "p2p_unavailable" : "mesh_remove_node_failed",
3757
- error: e?.message || String(e),
3758
- recoveryHint: isP2pTransportUnavailableError(e) ? "If this is an ADHDev-managed local worktree, retry from a coordinator connected to the daemon that owns the worktree; dashboard command/data-plane traffic still requires P2P." : "Inspect mesh_status and retry after resolving the reported failure."
3759
- }, null, 2);
3760
- }
3761
- }
3762
- if (result?.success && result.removed !== false) {
3763
- const idx = ctx.mesh.nodes.findIndex((n) => n.id === args.node_id);
3764
- if (idx >= 0) {
3765
- ctx.mesh.nodes.splice(idx, 1);
3766
- ctx.mesh.updatedAt = (/* @__PURE__ */ new Date()).toISOString();
3767
- }
3513
+ const removeArgs = buildRemoveNodeArgs(ctx, args.node_id, args.session_cleanup_mode);
3514
+ let result;
3515
+ let transportFallback;
3516
+ try {
3517
+ result = await commandForNode(ctx, node, "remove_mesh_node", removeArgs);
3518
+ } catch (e) {
3519
+ if (ctx.transport instanceof IpcTransport && node.isLocalWorktree && isP2pTransportUnavailableError(e)) {
3520
+ result = await ctx.transport.command("remove_mesh_node", removeArgs);
3521
+ transportFallback = {
3522
+ from: "p2p_mesh_relay",
3523
+ to: "local_control_plane",
3524
+ reason: e?.message || String(e)
3525
+ };
3526
+ } else {
3527
+ return JSON.stringify({
3528
+ success: false,
3529
+ code: isP2pTransportUnavailableError(e) ? "p2p_unavailable" : "mesh_remove_node_failed",
3530
+ error: e?.message || String(e),
3531
+ recoveryHint: isP2pTransportUnavailableError(e) ? "If this is an ADHDev-managed local worktree, retry from a coordinator connected to the daemon that owns the worktree; dashboard command/data-plane traffic still requires P2P." : "Inspect mesh_status and retry after resolving the reported failure."
3532
+ }, null, 2);
3768
3533
  }
3769
- return JSON.stringify({ ...result || {}, ...transportFallback ? { transportFallback } : {} }, null, 2);
3770
- } else if (!isLocalTransport(ctx.transport) && node.daemonId) {
3771
- try {
3772
- const res = await ctx.transport.meshRemoveNode(node.daemonId, {
3773
- meshId: ctx.mesh.id,
3774
- nodeId: args.node_id,
3775
- ...args.session_cleanup_mode ? { sessionCleanupMode: args.session_cleanup_mode } : {},
3776
- inlineMesh: ctx.mesh
3777
- });
3778
- if (res?.success && res.removed !== false) {
3779
- const idx = ctx.mesh.nodes.findIndex((n) => n.id === args.node_id);
3780
- if (idx >= 0) {
3781
- ctx.mesh.nodes.splice(idx, 1);
3782
- ctx.mesh.updatedAt = (/* @__PURE__ */ new Date()).toISOString();
3783
- }
3784
- }
3785
- return JSON.stringify(res, null, 2);
3786
- } catch (e) {
3787
- return JSON.stringify({ success: false, error: e.message });
3534
+ }
3535
+ if (result?.success && result.removed !== false) {
3536
+ const idx = ctx.mesh.nodes.findIndex((n) => n.id === args.node_id);
3537
+ if (idx >= 0) {
3538
+ ctx.mesh.nodes.splice(idx, 1);
3539
+ ctx.mesh.updatedAt = (/* @__PURE__ */ new Date()).toISOString();
3788
3540
  }
3789
- } else {
3790
- return JSON.stringify({ error: "Cloud mesh remove_node requires node daemonId" });
3791
3541
  }
3542
+ return JSON.stringify({ ...result || {}, ...transportFallback ? { transportFallback } : {} }, null, 2);
3792
3543
  }
3793
3544
  function resolveRefineConfigNode(ctx, nodeId) {
3794
3545
  if (nodeId) return findNode(ctx.mesh, nodeId);
@@ -3829,46 +3580,21 @@ async function meshRefinePlan(ctx, args) {
3829
3580
  }
3830
3581
  async function meshRefineNode(ctx, args) {
3831
3582
  const node = await findNodeWithRefresh(ctx, args.node_id);
3832
- if (isLocalTransport(ctx.transport)) {
3833
- const result = await commandForNode(ctx, node, "refine_mesh_node", {
3834
- meshId: ctx.mesh.id,
3835
- nodeId: args.node_id,
3836
- inlineMesh: ctx.mesh
3837
- });
3838
- if (result?.success && result.async !== true && result.removeResult?.removed !== false) {
3839
- const idx = ctx.mesh.nodes.findIndex((n) => n.id === args.node_id);
3840
- if (idx >= 0) {
3841
- ctx.mesh.nodes.splice(idx, 1);
3842
- ctx.mesh.updatedAt = (/* @__PURE__ */ new Date()).toISOString();
3843
- }
3844
- }
3845
- return JSON.stringify(result, null, 2);
3846
- } else if (!isLocalTransport(ctx.transport) && node.daemonId) {
3847
- try {
3848
- const res = await ctx.transport.meshRefineNode(node.daemonId, {
3849
- meshId: ctx.mesh.id,
3850
- nodeId: args.node_id,
3851
- inlineMesh: ctx.mesh
3852
- });
3853
- if (res?.success && res.async !== true && res.removeResult?.removed !== false) {
3854
- const idx = ctx.mesh.nodes.findIndex((n) => n.id === args.node_id);
3855
- if (idx >= 0) {
3856
- ctx.mesh.nodes.splice(idx, 1);
3857
- ctx.mesh.updatedAt = (/* @__PURE__ */ new Date()).toISOString();
3858
- }
3859
- }
3860
- return JSON.stringify(res, null, 2);
3861
- } catch (e) {
3862
- return JSON.stringify({ success: false, error: e.message });
3583
+ const result = await commandForNode(ctx, node, "refine_mesh_node", {
3584
+ meshId: ctx.mesh.id,
3585
+ nodeId: args.node_id,
3586
+ inlineMesh: ctx.mesh
3587
+ });
3588
+ if (result?.success && result.async !== true && result.removeResult?.removed !== false) {
3589
+ const idx = ctx.mesh.nodes.findIndex((n) => n.id === args.node_id);
3590
+ if (idx >= 0) {
3591
+ ctx.mesh.nodes.splice(idx, 1);
3592
+ ctx.mesh.updatedAt = (/* @__PURE__ */ new Date()).toISOString();
3863
3593
  }
3864
- } else {
3865
- return JSON.stringify({ error: "Cloud mesh refine_node requires node daemonId" });
3866
3594
  }
3595
+ return JSON.stringify(result, null, 2);
3867
3596
  }
3868
3597
  async function meshReviewInbox(ctx, args = {}) {
3869
- if (!isLocalTransport(ctx.transport)) {
3870
- return JSON.stringify({ error: "mesh_review_inbox requires a local daemon transport (M4.0 scope: local nodes only)" });
3871
- }
3872
3598
  await refreshMeshFromDaemon(ctx);
3873
3599
  const meshId = (args.mesh_id ?? ctx.mesh.id).trim();
3874
3600
  const result = await commandForNode(ctx, ctx.mesh.nodes[0], "get_mesh_review_inbox", {
@@ -3903,24 +3629,20 @@ ADHDev MCP Server
3903
3629
 
3904
3630
  Usage:
3905
3631
  adhdev mcp Local mode (requires standalone daemon)
3906
- adhdev mcp --api-key <key> Cloud mode (ADHDev cloud API)
3907
3632
  adhdev mcp --mode ipc --repo-mesh <mesh_id> Cloud daemon IPC mesh mode
3908
3633
  adhdev-mcp --help Compatibility bin (same server, legacy package entrypoint)
3909
3634
 
3910
3635
  Options:
3911
- --mode <mode> Transport: local, cloud, or ipc
3636
+ --mode <mode> Transport: local or ipc
3912
3637
  --port <n> Standalone or IPC daemon port (defaults: local 3847, ipc 19222)
3913
3638
  --password <pass> Standalone daemon password (if set)
3914
- --api-key <key> ADHDev cloud API key (switches to cloud mode)
3915
- --base-url <url> Override cloud API base URL
3916
3639
  --repo-mesh <mesh_id> Enable mesh mode \u2014 exposes only mesh-scoped coordinator tools
3917
3640
  --help Show this help
3918
3641
 
3919
3642
  Environment variables:
3920
- ADHDEV_API_KEY API key (cloud mode)
3921
3643
  ADHDEV_PASSWORD Daemon password (local mode)
3922
3644
  ADHDEV_MESH_ID Mesh ID (mesh mode)
3923
- ADHDEV_MCP_TRANSPORT Transport: local, cloud, or ipc
3645
+ ADHDEV_MCP_TRANSPORT Transport: local or ipc
3924
3646
 
3925
3647
  Standard tools: ${STANDARD_TOOLS.join(", ")}
3926
3648
  Mesh tools: ${meshTools.join(", ")}
@@ -3974,269 +3696,6 @@ var LocalTransport = class {
3974
3696
  }
3975
3697
  };
3976
3698
 
3977
- // src/transports/cloud.ts
3978
- var DEFAULT_BASE_URL = "https://api.adhf.dev";
3979
- var CloudTransport = class {
3980
- baseUrl;
3981
- apiKey;
3982
- constructor(opts) {
3983
- this.apiKey = opts.apiKey;
3984
- this.baseUrl = opts.baseUrl ?? DEFAULT_BASE_URL;
3985
- }
3986
- headers() {
3987
- return {
3988
- "Content-Type": "application/json",
3989
- "Authorization": `Bearer ${this.apiKey}`
3990
- };
3991
- }
3992
- async listRemoteMeshes() {
3993
- const res = await fetch(`${this.baseUrl}/api/v1/repo-meshes`, { headers: this.headers() });
3994
- if (!res.ok) throw new Error(`List remote meshes failed: ${res.status}`);
3995
- return res.json();
3996
- }
3997
- async createRemoteMesh(data) {
3998
- const res = await fetch(`${this.baseUrl}/api/v1/repo-meshes`, {
3999
- method: "POST",
4000
- headers: this.headers(),
4001
- body: JSON.stringify(data)
4002
- });
4003
- if (!res.ok) throw new Error(`Create remote mesh failed: ${res.status}`);
4004
- return res.json();
4005
- }
4006
- async deleteRemoteMesh(meshId) {
4007
- const res = await fetch(`${this.baseUrl}/api/v1/repo-meshes/${encodeURIComponent(meshId)}`, {
4008
- method: "DELETE",
4009
- headers: this.headers()
4010
- });
4011
- if (!res.ok) throw new Error(`Delete remote mesh failed: ${res.status}`);
4012
- }
4013
- async listDaemons() {
4014
- const res = await fetch(`${this.baseUrl}/api/v1/daemons`, { headers: this.headers() });
4015
- if (!res.ok) throw new Error(`List daemons failed: ${res.status}`);
4016
- return res.json();
4017
- }
4018
- async getStatus(targetId) {
4019
- const res = await fetch(
4020
- `${this.baseUrl}/api/v1/shortcuts/${encodeURIComponent(targetId)}/status`,
4021
- { headers: this.headers() }
4022
- );
4023
- if (!res.ok) throw new Error(`Status failed: ${res.status}`);
4024
- return res.json();
4025
- }
4026
- /** Get all sessions for a daemon (returns CompactSessionEntry[]). */
4027
- async getDaemonStatus(daemonId) {
4028
- const res = await fetch(
4029
- `${this.baseUrl}/api/v1/daemons/${encodeURIComponent(daemonId)}/status`,
4030
- { headers: this.headers() }
4031
- );
4032
- if (!res.ok) throw new Error(`Daemon status failed: ${res.status}`);
4033
- return res.json();
4034
- }
4035
- async readChat(targetId, opts = {}) {
4036
- const params = new URLSearchParams();
4037
- if (opts.limit) params.set("limit", String(opts.limit));
4038
- if (opts.sessionId) params.set("sessionId", opts.sessionId);
4039
- const qs = params.toString() ? `?${params}` : "";
4040
- const res = await fetch(
4041
- `${this.baseUrl}/api/v1/shortcuts/${encodeURIComponent(targetId)}/chat${qs}`,
4042
- { headers: this.headers() }
4043
- );
4044
- if (!res.ok) throw new Error(`Read chat failed: ${res.status}`);
4045
- return res.json();
4046
- }
4047
- async getChatDebugBundle(targetId, opts = {}) {
4048
- const res = await fetch(
4049
- `${this.baseUrl}/api/v1/shortcuts/${encodeURIComponent(targetId)}/chat/debug`,
4050
- {
4051
- method: "POST",
4052
- headers: this.headers(),
4053
- body: JSON.stringify({
4054
- ...opts.agentType ? { agentType: opts.agentType } : {},
4055
- ...opts.sessionId ? { sessionId: opts.sessionId } : {},
4056
- ...opts.tailLimit ? { tailLimit: opts.tailLimit } : {},
4057
- ...opts.delivery ? { delivery: opts.delivery } : {}
4058
- })
4059
- }
4060
- );
4061
- if (!res.ok) throw new Error(`Chat debug bundle failed: ${res.status}`);
4062
- return res.json();
4063
- }
4064
- async sendChat(targetId, message, opts = {}) {
4065
- const res = await fetch(
4066
- `${this.baseUrl}/api/v1/shortcuts/${encodeURIComponent(targetId)}/chat`,
4067
- {
4068
- method: "POST",
4069
- headers: this.headers(),
4070
- body: JSON.stringify({ message, ...opts })
4071
- }
4072
- );
4073
- if (!res.ok) throw new Error(`Send chat failed: ${res.status}`);
4074
- return res.json();
4075
- }
4076
- async approve(targetId, action, agentType) {
4077
- const res = await fetch(
4078
- `${this.baseUrl}/api/v1/shortcuts/${encodeURIComponent(targetId)}/approve`,
4079
- {
4080
- method: "POST",
4081
- headers: this.headers(),
4082
- body: JSON.stringify({ action, ...agentType ? { agentType } : {} })
4083
- }
4084
- );
4085
- if (!res.ok) throw new Error(`Approve failed: ${res.status}`);
4086
- return res.json();
4087
- }
4088
- async gitStatus(daemonId, workspace, includeDiff = true, refreshUpstream = false) {
4089
- const params = new URLSearchParams({ workspace, includeDiff: String(includeDiff), refreshUpstream: String(refreshUpstream) });
4090
- const res = await fetch(
4091
- `${this.baseUrl}/api/v1/shortcuts/${encodeURIComponent(daemonId)}/git-status?${params}`,
4092
- { headers: this.headers() }
4093
- );
4094
- if (!res.ok) throw new Error(`Git status failed: ${res.status}`);
4095
- return res.json();
4096
- }
4097
- async stop(daemonId, opts) {
4098
- const res = await fetch(
4099
- `${this.baseUrl}/api/v1/shortcuts/${encodeURIComponent(daemonId)}/stop`,
4100
- {
4101
- method: "POST",
4102
- headers: this.headers(),
4103
- body: JSON.stringify(opts)
4104
- }
4105
- );
4106
- if (!res.ok) throw new Error(`Stop failed: ${res.status}`);
4107
- return res.json();
4108
- }
4109
- async launch(daemonId, opts) {
4110
- const res = await fetch(
4111
- `${this.baseUrl}/api/v1/shortcuts/${encodeURIComponent(daemonId)}/launch`,
4112
- {
4113
- method: "POST",
4114
- headers: this.headers(),
4115
- body: JSON.stringify(opts)
4116
- }
4117
- );
4118
- if (!res.ok) throw new Error(`Launch failed: ${res.status}`);
4119
- return res.json();
4120
- }
4121
- async gitLog(daemonId, workspace, opts = {}) {
4122
- const params = new URLSearchParams({ workspace });
4123
- if (opts.limit) params.set("limit", String(opts.limit));
4124
- if (opts.file) params.set("file", opts.file);
4125
- if (opts.since) params.set("since", opts.since);
4126
- if (opts.until) params.set("until", opts.until);
4127
- const res = await fetch(
4128
- `${this.baseUrl}/api/v1/shortcuts/${encodeURIComponent(daemonId)}/git-log?${params}`,
4129
- { headers: this.headers() }
4130
- );
4131
- if (!res.ok) throw new Error(`Git log failed: ${res.status}`);
4132
- return res.json();
4133
- }
4134
- async gitDiff(daemonId, workspace, opts = {}) {
4135
- const params = new URLSearchParams({ workspace });
4136
- if (opts.file) params.set("file", opts.file);
4137
- if (opts.maxLines) params.set("maxLines", String(opts.maxLines));
4138
- if (opts.staged) params.set("staged", "true");
4139
- const res = await fetch(
4140
- `${this.baseUrl}/api/v1/shortcuts/${encodeURIComponent(daemonId)}/git-diff?${params}`,
4141
- { headers: this.headers() }
4142
- );
4143
- if (!res.ok) throw new Error(`Git diff failed: ${res.status}`);
4144
- return res.json();
4145
- }
4146
- async gitPush(daemonId, opts) {
4147
- const res = await fetch(
4148
- `${this.baseUrl}/api/v1/shortcuts/${encodeURIComponent(daemonId)}/git-push`,
4149
- {
4150
- method: "POST",
4151
- headers: this.headers(),
4152
- body: JSON.stringify(opts)
4153
- }
4154
- );
4155
- if (!res.ok) throw new Error(`Git push failed: ${res.status}`);
4156
- return res.json();
4157
- }
4158
- async gitCheckpoint(daemonId, opts) {
4159
- const res = await fetch(
4160
- `${this.baseUrl}/api/v1/shortcuts/${encodeURIComponent(daemonId)}/git-checkpoint`,
4161
- {
4162
- method: "POST",
4163
- headers: this.headers(),
4164
- body: JSON.stringify(opts)
4165
- }
4166
- );
4167
- if (!res.ok) throw new Error(`Git checkpoint failed: ${res.status}`);
4168
- return res.json();
4169
- }
4170
- async meshCloneNode(daemonId, payload) {
4171
- const res = await fetch(
4172
- `${this.baseUrl}/api/v1/shortcuts/${encodeURIComponent(daemonId)}/mesh/clone-node`,
4173
- {
4174
- method: "POST",
4175
- headers: this.headers(),
4176
- body: JSON.stringify(payload)
4177
- }
4178
- );
4179
- if (!res.ok) throw new Error(`Mesh clone node failed: ${res.status}`);
4180
- return res.json();
4181
- }
4182
- async meshRemoveNode(daemonId, payload) {
4183
- const res = await fetch(
4184
- `${this.baseUrl}/api/v1/shortcuts/${encodeURIComponent(daemonId)}/mesh/remove-node`,
4185
- {
4186
- method: "POST",
4187
- headers: this.headers(),
4188
- body: JSON.stringify(payload)
4189
- }
4190
- );
4191
- if (!res.ok) throw new Error(`Mesh remove node failed: ${res.status}`);
4192
- return res.json();
4193
- }
4194
- async meshCleanupSessions(daemonId, payload) {
4195
- const res = await fetch(
4196
- `${this.baseUrl}/api/v1/shortcuts/${encodeURIComponent(daemonId)}/mesh/cleanup-sessions`,
4197
- {
4198
- method: "POST",
4199
- headers: this.headers(),
4200
- body: JSON.stringify(payload)
4201
- }
4202
- );
4203
- if (!res.ok) throw new Error(`Mesh cleanup sessions failed: ${res.status}`);
4204
- return res.json();
4205
- }
4206
- async meshEnqueueTask(daemonId, payload) {
4207
- const res = await fetch(
4208
- `${this.baseUrl}/api/v1/shortcuts/${encodeURIComponent(daemonId)}/mesh/enqueue`,
4209
- {
4210
- method: "POST",
4211
- headers: this.headers(),
4212
- body: JSON.stringify(payload)
4213
- }
4214
- );
4215
- if (!res.ok) throw new Error(`Mesh enqueue task failed: ${res.status}`);
4216
- return res.json();
4217
- }
4218
- async meshRefineNode(daemonId, payload) {
4219
- const res = await fetch(
4220
- `${this.baseUrl}/api/v1/shortcuts/${encodeURIComponent(daemonId)}/mesh/refine-node`,
4221
- {
4222
- method: "POST",
4223
- headers: this.headers(),
4224
- body: JSON.stringify(payload)
4225
- }
4226
- );
4227
- if (!res.ok) throw new Error(`Mesh refine node failed: ${res.status}`);
4228
- return res.json();
4229
- }
4230
- async ping() {
4231
- try {
4232
- await this.listDaemons();
4233
- return true;
4234
- } catch {
4235
- return false;
4236
- }
4237
- }
4238
- };
4239
-
4240
3699
  // src/tools/list-sessions.ts
4241
3700
  var FORMAT_PROP = {
4242
3701
  format: {
@@ -4247,14 +3706,10 @@ var FORMAT_PROP = {
4247
3706
  };
4248
3707
  var LIST_SESSIONS_TOOL = {
4249
3708
  name: "list_sessions",
4250
- description: "List all connected agent sessions. In cloud mode, fetches session state from each daemon (data is sourced from daemon WS status reports, up to 30s stale). Pass daemon_id to scope to a single daemon.",
3709
+ description: "List all connected agent sessions.",
4251
3710
  inputSchema: {
4252
3711
  type: "object",
4253
3712
  properties: {
4254
- daemon_id: {
4255
- type: "string",
4256
- description: "Daemon ID (cloud mode only). Omit to list sessions across all daemons."
4257
- },
4258
3713
  ...FORMAT_PROP
4259
3714
  },
4260
3715
  required: []
@@ -4262,87 +3717,35 @@ var LIST_SESSIONS_TOOL = {
4262
3717
  };
4263
3718
  async function listSessions(transport, args = {}) {
4264
3719
  const asJson = args.format === "json";
4265
- if (isLocalTransport(transport)) {
4266
- const status = await transport.getStatus();
4267
- const sessions = status?.sessions ?? [];
4268
- if (asJson) {
4269
- return JSON.stringify({
4270
- sessions: sessions.map((s) => ({
4271
- id: s.id,
4272
- type: s.providerType ?? s.type ?? "unknown",
4273
- label: s.label ?? null,
4274
- status: s.status ?? s.agentStatus ?? null,
4275
- workspace: s.workspace ?? null
4276
- }))
4277
- }, null, 2);
4278
- }
4279
- if (sessions.length === 0) return "No active sessions.";
4280
- const lines = sessions.map((s) => {
4281
- const parts = [`id: ${s.id}`, `type: ${s.providerType ?? s.type ?? "unknown"}`];
4282
- if (s.label) parts.push(`label: ${s.label}`);
4283
- if (s.status ?? s.agentStatus) parts.push(`status: ${s.status ?? s.agentStatus}`);
4284
- if (s.workspace) parts.push(`workspace: ${s.workspace}`);
4285
- return parts.join(", ");
4286
- });
4287
- return `Sessions (${sessions.length}):
4288
- ${lines.join("\n")}`;
4289
- }
4290
- return listSessionsCloud(transport, args.daemon_id, asJson);
4291
- }
4292
- async function listSessionsCloud(transport, daemonId, asJson) {
4293
- const collected = [];
4294
- if (daemonId) {
4295
- const daemonStatus = await transport.getDaemonStatus(daemonId);
4296
- for (const s of daemonStatus?.sessions ?? []) {
4297
- collected.push({ daemonId, session: s });
4298
- }
4299
- } else {
4300
- const data = await transport.listDaemons();
4301
- const daemons = data?.daemons ?? [];
4302
- for (let i = 0; i < daemons.length; i += 5) {
4303
- await Promise.allSettled(
4304
- daemons.slice(i, i + 5).map(async (d) => {
4305
- try {
4306
- const daemonStatus = await transport.getDaemonStatus(d.id);
4307
- for (const s of daemonStatus?.sessions ?? []) {
4308
- collected.push({ daemonId: d.id, session: s });
4309
- }
4310
- } catch {
4311
- }
4312
- })
4313
- );
4314
- }
4315
- }
3720
+ const status = await transport.getStatus();
3721
+ const sessions = status?.sessions ?? [];
4316
3722
  if (asJson) {
4317
3723
  return JSON.stringify({
4318
- sessions: collected.map(({ daemonId: dId, session: s }) => ({
4319
- daemon_id: dId,
3724
+ sessions: sessions.map((s) => ({
4320
3725
  id: s.id,
4321
- type: s.providerType ?? "unknown",
4322
- status: s.status ?? null,
3726
+ type: s.providerType ?? s.type ?? "unknown",
3727
+ label: s.label ?? null,
3728
+ status: s.status ?? s.agentStatus ?? null,
4323
3729
  workspace: s.workspace ?? null
4324
3730
  }))
4325
3731
  }, null, 2);
4326
3732
  }
4327
- if (collected.length === 0) return "No active sessions.";
4328
- const lines = collected.map(({ daemonId: dId, session: s }) => {
4329
- const parts = [
4330
- `daemon: ${dId}`,
4331
- `session: ${s.id}`,
4332
- `type: ${s.providerType ?? "unknown"}`
4333
- ];
4334
- if (s.status) parts.push(`status: ${s.status}`);
3733
+ if (sessions.length === 0) return "No active sessions.";
3734
+ const lines = sessions.map((s) => {
3735
+ const parts = [`id: ${s.id}`, `type: ${s.providerType ?? s.type ?? "unknown"}`];
3736
+ if (s.label) parts.push(`label: ${s.label}`);
3737
+ if (s.status ?? s.agentStatus) parts.push(`status: ${s.status ?? s.agentStatus}`);
4335
3738
  if (s.workspace) parts.push(`workspace: ${s.workspace}`);
4336
3739
  return parts.join(", ");
4337
3740
  });
4338
- return `Sessions (${collected.length}):
3741
+ return `Sessions (${sessions.length}):
4339
3742
  ${lines.join("\n")}`;
4340
3743
  }
4341
3744
 
4342
3745
  // src/tools/list-daemons.ts
4343
3746
  var LIST_DAEMONS_TOOL = {
4344
3747
  name: "list_daemons",
4345
- description: "List all connected daemons (machines running the ADHDev agent). Use this to discover daemon IDs before calling launch_session, git_status, or other tools that require daemon_id. In local mode returns the single standalone daemon info.",
3748
+ description: "List the connected daemon (machine running the ADHDev agent). Returns the daemon identity extracted from its status report.",
4346
3749
  inputSchema: {
4347
3750
  type: "object",
4348
3751
  properties: {
@@ -4353,46 +3756,17 @@ var LIST_DAEMONS_TOOL = {
4353
3756
  };
4354
3757
  async function listDaemons(transport, args = {}) {
4355
3758
  const asJson = args.format === "json";
4356
- if (isLocalTransport(transport)) {
4357
- const status = await transport.getStatus();
4358
- const daemon = {
4359
- id: status?.id ?? status?.instanceId ?? "standalone",
4360
- hostname: status?.hostname ?? status?.machine?.hostname ?? "localhost",
4361
- platform: status?.platform ?? status?.machine?.platform ?? "unknown",
4362
- version: status?.version ?? null,
4363
- sessions: (status?.sessions ?? []).length
4364
- };
4365
- if (asJson) return JSON.stringify({ daemons: [daemon] }, null, 2);
4366
- return `Daemons (1):
3759
+ const status = await transport.getStatus();
3760
+ const daemon = {
3761
+ id: status?.id ?? status?.instanceId ?? "standalone",
3762
+ hostname: status?.hostname ?? status?.machine?.hostname ?? "localhost",
3763
+ platform: status?.platform ?? status?.machine?.platform ?? "unknown",
3764
+ version: status?.version ?? null,
3765
+ sessions: (status?.sessions ?? []).length
3766
+ };
3767
+ if (asJson) return JSON.stringify({ daemons: [daemon] }, null, 2);
3768
+ return `Daemons (1):
4367
3769
  id: ${daemon.id}, hostname: ${daemon.hostname}, platform: ${daemon.platform}${daemon.version ? `, version: ${daemon.version}` : ""}, sessions: ${daemon.sessions}`;
4368
- }
4369
- const data = await transport.listDaemons();
4370
- const daemons = data?.daemons ?? [];
4371
- if (asJson) {
4372
- return JSON.stringify({
4373
- daemons: daemons.map((d) => ({
4374
- id: d.id,
4375
- hostname: d.hostname ?? null,
4376
- platform: d.platform ?? null,
4377
- nickname: d.nickname ?? null,
4378
- version: d.version ?? null,
4379
- p2p_available: d.p2p?.available ?? null,
4380
- cdp_connected: d.cdpConnected ?? null
4381
- }))
4382
- }, null, 2);
4383
- }
4384
- if (daemons.length === 0) return "No connected daemons.";
4385
- const lines = daemons.map((d) => {
4386
- const parts = [`id: ${d.id}`];
4387
- if (d.nickname) parts.push(`nickname: ${d.nickname}`);
4388
- if (d.hostname) parts.push(`hostname: ${d.hostname}`);
4389
- if (d.platform) parts.push(`platform: ${d.platform}`);
4390
- if (d.version) parts.push(`version: ${d.version}`);
4391
- if (d.p2p?.available != null) parts.push(`p2p: ${d.p2p.available ? "yes" : "no"}`);
4392
- return parts.join(", ");
4393
- });
4394
- return `Daemons (${daemons.length}):
4395
- ${lines.join("\n")}`;
4396
3770
  }
4397
3771
 
4398
3772
  // src/tools/read-chat.ts
@@ -4410,10 +3784,6 @@ var READ_CHAT_TOOL = {
4410
3784
  type: "number",
4411
3785
  description: "Max messages to return (default: 50)."
4412
3786
  },
4413
- daemon_id: {
4414
- type: "string",
4415
- description: "Daemon ID (cloud mode only). Omit for local mode."
4416
- },
4417
3787
  compact: {
4418
3788
  type: "boolean",
4419
3789
  description: "Opt-in compact mode: filters tool/terminal/system/internal/control/debug/status chatter and returns user-visible messages plus lightweight summary metadata."
@@ -4425,23 +3795,12 @@ var READ_CHAT_TOOL = {
4425
3795
  };
4426
3796
  async function readChat(transport, args) {
4427
3797
  const limit = args.limit ?? 50;
4428
- if (isLocalTransport(transport)) {
4429
- const result2 = await transport.command("read_chat", {
4430
- ...args.session_id ? { targetSessionId: args.session_id } : {},
4431
- tailLimit: limit
4432
- });
4433
- const annotated2 = annotateRapidReadChatAdvisory(result2, {
4434
- key: `local:${args.session_id ?? "__active__"}`,
4435
- toolName: "read_chat",
4436
- completionCallbackExpected: false
4437
- });
4438
- return formatChatResult(annotated2, args.session_id, args.format, limit, args.compact);
4439
- }
4440
- if (!args.daemon_id) throw new Error("daemon_id is required in cloud mode");
4441
- const targetId = args.session_id ? `${args.daemon_id}:session:${args.session_id}` : args.daemon_id;
4442
- const result = await transport.readChat(targetId, { limit, sessionId: args.session_id });
3798
+ const result = await transport.command("read_chat", {
3799
+ ...args.session_id ? { targetSessionId: args.session_id } : {},
3800
+ tailLimit: limit
3801
+ });
4443
3802
  const annotated = annotateRapidReadChatAdvisory(result, {
4444
- key: `cloud:${args.daemon_id}:${args.session_id ?? "__active__"}`,
3803
+ key: `local:${args.session_id ?? "__active__"}`,
4445
3804
  toolName: "read_chat",
4446
3805
  completionCallbackExpected: false
4447
3806
  });
@@ -4531,10 +3890,6 @@ var READ_CHAT_DEBUG_TOOL = {
4531
3890
  type: "string",
4532
3891
  description: "Target session ID (from list_sessions). Required for reliable routing."
4533
3892
  },
4534
- daemon_id: {
4535
- type: "string",
4536
- description: "Daemon ID (cloud mode only). Omit for local mode."
4537
- },
4538
3893
  agent_type: {
4539
3894
  type: "string",
4540
3895
  description: "Optional provider/agent type hint, e.g. hermes-cli, claude-cli, codex-cli."
@@ -4564,19 +3919,7 @@ async function readChatDebug(transport, args) {
4564
3919
  ...args.agent_type ? { agentType: args.agent_type, providerType: args.agent_type } : {},
4565
3920
  ...delivery === "daemon_file" ? { delivery: "daemon_file" } : {}
4566
3921
  };
4567
- let result;
4568
- if (isLocalTransport(transport)) {
4569
- result = await transport.command("get_chat_debug_bundle", commandArgs);
4570
- } else {
4571
- if (!args.daemon_id) throw new Error("daemon_id is required in cloud mode");
4572
- const targetId = `${args.daemon_id}:session:${sessionId}`;
4573
- result = await transport.getChatDebugBundle(targetId, {
4574
- sessionId,
4575
- agentType: args.agent_type,
4576
- tailLimit,
4577
- delivery
4578
- });
4579
- }
3922
+ const result = await transport.command("get_chat_debug_bundle", commandArgs);
4580
3923
  return formatChatDebugResult(result, { sessionId, delivery, format: args.format });
4581
3924
  }
4582
3925
  function formatChatDebugResult(result, options) {
@@ -4618,10 +3961,6 @@ var SPEC_DEBUG_TOOL = {
4618
3961
  type: "string",
4619
3962
  description: "Target session ID (from list_sessions)."
4620
3963
  },
4621
- daemon_id: {
4622
- type: "string",
4623
- description: "Daemon ID (cloud mode only). Omit for local mode."
4624
- },
4625
3964
  ...FORMAT_PROP
4626
3965
  },
4627
3966
  required: ["session_id"]
@@ -4630,14 +3969,7 @@ var SPEC_DEBUG_TOOL = {
4630
3969
  async function specDebug(transport, args) {
4631
3970
  const sessionId = typeof args.session_id === "string" ? args.session_id.trim() : "";
4632
3971
  if (!sessionId) throw new Error("session_id is required");
4633
- let result;
4634
- if (isLocalTransport(transport)) {
4635
- result = await transport.command("get_spec_debug", { targetSessionId: sessionId });
4636
- } else {
4637
- if (!args.daemon_id) throw new Error("daemon_id is required in cloud mode");
4638
- const targetId = `${args.daemon_id}:session:${sessionId}`;
4639
- result = await transport.sendCommand(targetId, "get_spec_debug", { targetSessionId: sessionId });
4640
- }
3972
+ const result = await transport.command("get_spec_debug", { targetSessionId: sessionId });
4641
3973
  return formatSpecDebugResult(result, { sessionId, format: args.format });
4642
3974
  }
4643
3975
  function formatSpecDebugResult(result, options) {
@@ -4705,10 +4037,6 @@ var SEND_CHAT_TOOL = {
4705
4037
  session_id: {
4706
4038
  type: "string",
4707
4039
  description: "Target session ID (from list_sessions). Omit to use the active session."
4708
- },
4709
- daemon_id: {
4710
- type: "string",
4711
- description: "Daemon ID (cloud mode only). Omit for local mode."
4712
4040
  }
4713
4041
  },
4714
4042
  required: ["message"]
@@ -4716,18 +4044,9 @@ var SEND_CHAT_TOOL = {
4716
4044
  };
4717
4045
  async function sendChat(transport, args) {
4718
4046
  if (!args.message?.trim()) throw new Error("message is required");
4719
- if (isLocalTransport(transport)) {
4720
- const result2 = await transport.command("send_chat", {
4721
- message: args.message,
4722
- ...args.session_id ? { targetSessionId: args.session_id } : {}
4723
- });
4724
- if (result2?.success === false) return `Error: ${result2.error ?? "send_chat failed"}`;
4725
- return "Message sent.";
4726
- }
4727
- if (!args.daemon_id) throw new Error("daemon_id is required in cloud mode");
4728
- const targetId = args.session_id ? `${args.daemon_id}:session:${args.session_id}` : args.daemon_id;
4729
- const result = await transport.sendChat(targetId, args.message, {
4730
- ...args.session_id ? { sessionId: args.session_id } : {}
4047
+ const result = await transport.command("send_chat", {
4048
+ message: args.message,
4049
+ ...args.session_id ? { targetSessionId: args.session_id } : {}
4731
4050
  });
4732
4051
  if (result?.success === false) return `Error: ${result.error ?? "send_chat failed"}`;
4733
4052
  return "Message sent.";
@@ -4748,10 +4067,6 @@ var APPROVE_TOOL = {
4748
4067
  session_id: {
4749
4068
  type: "string",
4750
4069
  description: "Target session ID. Omit to use the active session."
4751
- },
4752
- daemon_id: {
4753
- type: "string",
4754
- description: "Daemon ID (cloud mode only)."
4755
4070
  }
4756
4071
  },
4757
4072
  required: ["action"]
@@ -4759,25 +4074,18 @@ var APPROVE_TOOL = {
4759
4074
  };
4760
4075
  async function approve(transport, args) {
4761
4076
  const action = args.action === "reject" ? "reject" : "approve";
4762
- if (isLocalTransport(transport)) {
4763
- const result2 = await transport.command("resolve_action", {
4764
- action,
4765
- ...args.session_id ? { targetSessionId: args.session_id } : {}
4766
- });
4767
- if (result2?.success === false) return `Error: ${result2.error ?? "resolve_action failed"}`;
4768
- return `Action ${action}d.`;
4769
- }
4770
- if (!args.daemon_id) throw new Error("daemon_id is required in cloud mode");
4771
- const targetId = args.session_id ? `${args.daemon_id}:session:${args.session_id}` : args.daemon_id;
4772
- const result = await transport.approve(targetId, action);
4773
- if (result?.success === false) return `Error: ${result.error ?? "approve failed"}`;
4077
+ const result = await transport.command("resolve_action", {
4078
+ action,
4079
+ ...args.session_id ? { targetSessionId: args.session_id } : {}
4080
+ });
4081
+ if (result?.success === false) return `Error: ${result.error ?? "resolve_action failed"}`;
4774
4082
  return `Action ${action}d.`;
4775
4083
  }
4776
4084
 
4777
4085
  // src/tools/screenshot.ts
4778
4086
  var SCREENSHOT_TOOL = {
4779
4087
  name: "screenshot",
4780
- description: "Capture a screenshot of the current IDE window. Returns the image. Local mode only \u2014 screenshots require direct P2P access to the daemon and are not available in cloud mode.",
4088
+ description: "Capture a screenshot of the current IDE window. Returns the image.",
4781
4089
  inputSchema: {
4782
4090
  type: "object",
4783
4091
  properties: {
@@ -4790,14 +4098,9 @@ var SCREENSHOT_TOOL = {
4790
4098
  }
4791
4099
  };
4792
4100
  async function screenshot(transport, args) {
4793
- let result;
4794
- if (isLocalTransport(transport)) {
4795
- result = await transport.command("screenshot", {
4796
- ...args.session_id ? { targetSessionId: args.session_id } : {}
4797
- });
4798
- } else {
4799
- return { type: "text", text: "Screenshots are not available in cloud mode. Run adhdev mcp in local mode (requires standalone daemon)." };
4800
- }
4101
+ const result = await transport.command("screenshot", {
4102
+ ...args.session_id ? { targetSessionId: args.session_id } : {}
4103
+ });
4801
4104
  if (result?.success === false) {
4802
4105
  return { type: "text", text: `Error: ${result.error ?? "screenshot failed"}` };
4803
4106
  }
@@ -4824,42 +4127,22 @@ var GIT_STATUS_TOOL = {
4824
4127
  type: "boolean",
4825
4128
  description: "Include changed file list (default: true)."
4826
4129
  },
4827
- daemon_id: {
4828
- type: "string",
4829
- description: "Daemon ID (cloud mode only)."
4830
- },
4831
4130
  ...FORMAT_PROP
4832
4131
  },
4833
4132
  required: ["workspace"]
4834
4133
  }
4835
4134
  };
4836
4135
  async function gitStatus(transport, args) {
4837
- let status;
4838
4136
  let diffSummary;
4839
- if (isLocalTransport(transport)) {
4840
- const statusResult = await transport.command("git_status", {
4137
+ const statusResult = await transport.command("git_status", {
4138
+ workspace: args.workspace
4139
+ });
4140
+ const status = statusResult?.status ?? statusResult;
4141
+ if (args.include_diff !== false) {
4142
+ const diffResult = await transport.command("git_diff_summary", {
4841
4143
  workspace: args.workspace
4842
4144
  });
4843
- status = statusResult?.status ?? statusResult;
4844
- if (args.include_diff !== false) {
4845
- const diffResult = await transport.command("git_diff_summary", {
4846
- workspace: args.workspace
4847
- });
4848
- diffSummary = diffResult?.diffSummary ?? diffResult;
4849
- }
4850
- } else {
4851
- if (!args.daemon_id) throw new Error("daemon_id is required in cloud mode");
4852
- const result = await transport.gitStatus(
4853
- args.daemon_id,
4854
- args.workspace,
4855
- args.include_diff !== false
4856
- );
4857
- if (result?.error) {
4858
- if (args.format === "json") return JSON.stringify({ error: result.error }, null, 2);
4859
- return `Error: ${result.error}`;
4860
- }
4861
- status = result?.status;
4862
- diffSummary = result?.diff;
4145
+ diffSummary = diffResult?.diffSummary ?? diffResult;
4863
4146
  }
4864
4147
  if (status?.success === false || status?.reason) {
4865
4148
  const msg = status?.error ?? status?.reason ?? "unknown";
@@ -4951,10 +4234,6 @@ var GIT_LOG_TOOL = {
4951
4234
  type: "string",
4952
4235
  description: "Only commits before this date (ISO 8601 or git date string, optional)."
4953
4236
  },
4954
- daemon_id: {
4955
- type: "string",
4956
- description: "Daemon ID (cloud mode only, required)."
4957
- },
4958
4237
  ...FORMAT_PROP
4959
4238
  },
4960
4239
  required: ["workspace"]
@@ -4962,26 +4241,14 @@ var GIT_LOG_TOOL = {
4962
4241
  };
4963
4242
  async function gitLog(transport, args) {
4964
4243
  const limit = Math.max(1, Math.min(100, args.limit ?? 20));
4965
- let raw;
4966
- if (isLocalTransport(transport)) {
4967
- raw = await transport.command("git_log", {
4968
- workspace: args.workspace,
4969
- limit,
4970
- ...args.file ? { path: args.file } : {},
4971
- ...args.since ? { since: args.since } : {},
4972
- ...args.until ? { until: args.until } : {}
4973
- });
4974
- raw = raw?.log ?? raw;
4975
- } else {
4976
- if (!args.daemon_id) throw new Error("daemon_id is required in cloud mode");
4977
- const result = await transport.gitLog(args.daemon_id, args.workspace, {
4978
- limit,
4979
- file: args.file,
4980
- since: args.since,
4981
- until: args.until
4982
- });
4983
- raw = result?.log ?? result;
4984
- }
4244
+ let raw = await transport.command("git_log", {
4245
+ workspace: args.workspace,
4246
+ limit,
4247
+ ...args.file ? { path: args.file } : {},
4248
+ ...args.since ? { since: args.since } : {},
4249
+ ...args.until ? { until: args.until } : {}
4250
+ });
4251
+ raw = raw?.log ?? raw;
4985
4252
  if (raw?.success === false || raw?.reason) {
4986
4253
  const msg = raw?.error ?? raw?.reason ?? "unknown";
4987
4254
  if (args.format === "json") return JSON.stringify({ error: msg }, null, 2);
@@ -5044,10 +4311,6 @@ var GIT_DIFF_TOOL = {
5044
4311
  type: "boolean",
5045
4312
  description: "Show staged changes instead of unstaged (default: false)."
5046
4313
  },
5047
- daemon_id: {
5048
- type: "string",
5049
- description: "Daemon ID (cloud mode only, required)."
5050
- },
5051
4314
  ...FORMAT_PROP
5052
4315
  },
5053
4316
  required: ["workspace"]
@@ -5056,20 +4319,7 @@ var GIT_DIFF_TOOL = {
5056
4319
  async function gitDiff(transport, args) {
5057
4320
  const maxLines = Math.max(10, Math.min(2e3, args.max_lines ?? 300));
5058
4321
  const staged = args.staged ?? false;
5059
- if (isLocalTransport(transport)) {
5060
- return localGitDiff(transport, args.workspace, args.file, maxLines, staged, args.format);
5061
- }
5062
- if (!args.daemon_id) throw new Error("daemon_id is required in cloud mode");
5063
- const result = await transport.gitDiff(args.daemon_id, args.workspace, {
5064
- file: args.file,
5065
- maxLines,
5066
- staged
5067
- });
5068
- if (result?.error) {
5069
- if (args.format === "json") return JSON.stringify({ error: result.error }, null, 2);
5070
- return `Git diff error: ${result.error}`;
5071
- }
5072
- return formatDiffResult(result, args.format);
4322
+ return localGitDiff(transport, args.workspace, args.file, maxLines, staged, args.format);
5073
4323
  }
5074
4324
  async function localGitDiff(transport, workspace, file, maxLines, staged, format) {
5075
4325
  if (file) {
@@ -5191,10 +4441,6 @@ var GIT_CHECKPOINT_TOOL = {
5191
4441
  include_untracked: {
5192
4442
  type: "boolean",
5193
4443
  description: "Also stage and commit untracked files (default: false)."
5194
- },
5195
- daemon_id: {
5196
- type: "string",
5197
- description: "Daemon ID (cloud mode only, required)."
5198
4444
  }
5199
4445
  },
5200
4446
  required: ["workspace", "message"]
@@ -5204,23 +4450,12 @@ async function gitCheckpoint(transport, args) {
5204
4450
  const message = args.message?.trim();
5205
4451
  if (!message) return "Error: message is required";
5206
4452
  if (message.length > 200) return "Error: message must be 200 characters or fewer";
5207
- let raw;
5208
- if (isLocalTransport(transport)) {
5209
- raw = await transport.command("git_checkpoint", {
5210
- workspace: args.workspace,
5211
- message,
5212
- includeUntracked: args.include_untracked ?? false
5213
- });
5214
- raw = raw?.checkpoint ?? raw;
5215
- } else {
5216
- if (!args.daemon_id) throw new Error("daemon_id is required in cloud mode");
5217
- const result = await transport.gitCheckpoint(args.daemon_id, {
5218
- workspace: args.workspace,
5219
- message,
5220
- includeUntracked: args.include_untracked ?? false
5221
- });
5222
- raw = result?.checkpoint ?? result;
5223
- }
4453
+ let raw = await transport.command("git_checkpoint", {
4454
+ workspace: args.workspace,
4455
+ message,
4456
+ includeUntracked: args.include_untracked ?? false
4457
+ });
4458
+ raw = raw?.checkpoint ?? raw;
5224
4459
  if (raw?.success === false || raw?.reason) {
5225
4460
  const msg = raw?.error ?? raw?.reason ?? "unknown";
5226
4461
  if (msg.includes("Nothing to commit") || msg.includes("nothing to commit")) {
@@ -5251,33 +4486,18 @@ var GIT_PUSH_TOOL = {
5251
4486
  branch: {
5252
4487
  type: "string",
5253
4488
  description: "Branch to push (default: current branch)."
5254
- },
5255
- daemon_id: {
5256
- type: "string",
5257
- description: "Daemon ID (cloud mode only, required)."
5258
4489
  }
5259
4490
  },
5260
4491
  required: ["workspace"]
5261
4492
  }
5262
4493
  };
5263
4494
  async function gitPush(transport, args) {
5264
- let raw;
5265
- if (isLocalTransport(transport)) {
5266
- raw = await transport.command("git_push", {
5267
- workspace: args.workspace,
5268
- remote: args.remote ?? "origin",
5269
- ...args.branch ? { branch: args.branch } : {}
5270
- });
5271
- raw = raw?.push ?? raw;
5272
- } else {
5273
- if (!args.daemon_id) throw new Error("daemon_id is required in cloud mode");
5274
- const result = await transport.gitPush(args.daemon_id, {
5275
- workspace: args.workspace,
5276
- remote: args.remote,
5277
- branch: args.branch
5278
- });
5279
- raw = result?.push ?? result;
5280
- }
4495
+ let raw = await transport.command("git_push", {
4496
+ workspace: args.workspace,
4497
+ remote: args.remote ?? "origin",
4498
+ ...args.branch ? { branch: args.branch } : {}
4499
+ });
4500
+ raw = raw?.push ?? raw;
5281
4501
  if (raw?.success === false || raw?.reason) {
5282
4502
  const msg = raw?.error ?? raw?.reason ?? "unknown";
5283
4503
  return `Git push error: ${msg}`;
@@ -5308,32 +4528,17 @@ var LAUNCH_SESSION_TOOL = {
5308
4528
  model: {
5309
4529
  type: "string",
5310
4530
  description: "Model override for ACP agents (e.g. claude-opus-4-7)."
5311
- },
5312
- daemon_id: {
5313
- type: "string",
5314
- description: "Daemon ID (cloud mode only). Required in cloud mode."
5315
4531
  }
5316
4532
  },
5317
4533
  required: ["type"]
5318
4534
  }
5319
4535
  };
5320
4536
  async function launchSession(transport, args) {
5321
- if (isLocalTransport(transport)) {
5322
- const isCliOrAcp = args.type.includes("-cli") || args.type.includes("-acp") || args.type === "codex";
5323
- const commandType = isCliOrAcp ? "launch_cli" : "launch_ide";
5324
- const payload = isCliOrAcp ? { cliType: args.type, dir: args.workspace ?? "~", ...args.model ? { model: args.model } : {} } : { ideType: args.type, enableCdp: true };
5325
- const result2 = await transport.command(commandType, payload);
5326
- if (result2?.success === false) return `Error: ${result2.error ?? "launch failed"}`;
5327
- const id2 = result2?.id ?? result2?.sessionId;
5328
- return id2 ? `Session launched. id: ${id2}, type: ${args.type}` : `Launched: ${JSON.stringify(result2)}`;
5329
- }
5330
- if (!args.daemon_id) throw new Error("daemon_id is required in cloud mode");
5331
- const result = await transport.launch(args.daemon_id, {
5332
- type: args.type,
5333
- dir: args.workspace,
5334
- model: args.model
5335
- });
5336
- if (result?.success === false || result?.error) return `Error: ${result.error ?? "launch failed"}`;
4537
+ const isCliOrAcp = args.type.includes("-cli") || args.type.includes("-acp") || args.type === "codex";
4538
+ const commandType = isCliOrAcp ? "launch_cli" : "launch_ide";
4539
+ const payload = isCliOrAcp ? { cliType: args.type, dir: args.workspace ?? "~", ...args.model ? { model: args.model } : {} } : { ideType: args.type, enableCdp: true };
4540
+ const result = await transport.command(commandType, payload);
4541
+ if (result?.success === false) return `Error: ${result.error ?? "launch failed"}`;
5337
4542
  const id = result?.id ?? result?.sessionId;
5338
4543
  return id ? `Session launched. id: ${id}, type: ${args.type}` : `Launched: ${JSON.stringify(result)}`;
5339
4544
  }
@@ -5349,43 +4554,29 @@ var STOP_SESSION_TOOL = {
5349
4554
  type: "string",
5350
4555
  description: "Session ID to stop (from list_sessions)."
5351
4556
  },
5352
- daemon_id: {
5353
- type: "string",
5354
- description: "Daemon ID (cloud mode only, required)."
5355
- },
5356
4557
  type: {
5357
4558
  type: "string",
5358
- description: "Provider type (e.g. hermes-cli, claude-cli). Local mode auto-resolves from session_id if omitted; cloud mode forwards the session_id and omits type unless explicitly provided."
4559
+ description: "Provider type (e.g. hermes-cli, claude-cli). Auto-resolved from session_id if omitted."
5359
4560
  }
5360
4561
  },
5361
4562
  required: ["session_id"]
5362
4563
  }
5363
4564
  };
5364
4565
  async function stopSession(transport, args) {
5365
- if (isLocalTransport(transport)) {
5366
- const local = transport;
5367
- let resolvedType = args.type;
5368
- if (!resolvedType) {
5369
- const status = await local.getStatus();
5370
- const session = (status?.sessions ?? []).find((s) => s.id === args.session_id);
5371
- resolvedType = session?.providerType ?? session?.type;
5372
- }
5373
- if (!resolvedType) {
5374
- return `Error: could not resolve session type for ${args.session_id}. Pass type= explicitly.`;
5375
- }
5376
- const result2 = await local.command("stop_cli", {
5377
- targetSessionId: args.session_id,
5378
- cliType: resolvedType
5379
- });
5380
- if (result2?.success === false) return `Error: ${result2.error ?? "stop failed"}`;
5381
- return `Session ${args.session_id} stopped.`;
4566
+ let resolvedType = args.type;
4567
+ if (!resolvedType) {
4568
+ const status = await transport.getStatus();
4569
+ const session = (status?.sessions ?? []).find((s) => s.id === args.session_id);
4570
+ resolvedType = session?.providerType ?? session?.type;
4571
+ }
4572
+ if (!resolvedType) {
4573
+ return `Error: could not resolve session type for ${args.session_id}. Pass type= explicitly.`;
5382
4574
  }
5383
- if (!args.daemon_id) throw new Error("daemon_id is required in cloud mode");
5384
- const result = await transport.stop(args.daemon_id, {
5385
- id: args.session_id,
5386
- ...args.type ? { type: args.type } : {}
4575
+ const result = await transport.command("stop_cli", {
4576
+ targetSessionId: args.session_id,
4577
+ cliType: resolvedType
5387
4578
  });
5388
- if (result?.success === false || result?.error) return `Error: ${result.error ?? "stop failed"}`;
4579
+ if (result?.success === false) return `Error: ${result.error ?? "stop failed"}`;
5389
4580
  return `Session ${args.session_id} stopped.`;
5390
4581
  }
5391
4582
 
@@ -5396,28 +4587,18 @@ var CHECK_PENDING_TOOL = {
5396
4587
  inputSchema: {
5397
4588
  type: "object",
5398
4589
  properties: {
5399
- daemon_id: {
5400
- type: "string",
5401
- description: "Daemon ID to check (cloud mode). Omit to check all daemons."
5402
- },
5403
4590
  ...FORMAT_PROP
5404
4591
  },
5405
4592
  required: []
5406
4593
  }
5407
4594
  };
5408
4595
  async function checkPending(transport, args) {
5409
- if (isLocalTransport(transport)) {
5410
- return checkPendingLocal(transport, args.format);
5411
- }
5412
- return checkPendingCloud(transport, args.daemon_id, args.format);
5413
- }
5414
- async function checkPendingLocal(transport, format) {
5415
4596
  const status = await transport.getStatus();
5416
4597
  const sessions = status?.sessions ?? [];
5417
4598
  const pending = sessions.filter(
5418
4599
  (s) => s.status === "waiting_approval" || s.agentStatus === "waiting_approval"
5419
4600
  );
5420
- if (format === "json") {
4601
+ if (args.format === "json") {
5421
4602
  return JSON.stringify({
5422
4603
  pending: pending.map((s) => ({
5423
4604
  session_id: s.id,
@@ -5440,56 +4621,6 @@ async function checkPendingLocal(transport, format) {
5440
4621
  });
5441
4622
  return `Pending approvals (${pending.length}):
5442
4623
 
5443
- ${lines.join("\n\n")}`;
5444
- }
5445
- async function checkPendingCloud(transport, daemonId, format) {
5446
- const pending = [];
5447
- if (daemonId) {
5448
- const daemonStatus = await transport.getDaemonStatus(daemonId);
5449
- const sessions = daemonStatus?.sessions ?? [];
5450
- for (const s of sessions) {
5451
- if (s.status === "waiting_approval") pending.push({ daemonId, session: s });
5452
- }
5453
- } else {
5454
- const data = await transport.listDaemons();
5455
- const daemons = data?.daemons ?? [];
5456
- for (let i = 0; i < daemons.length; i += 5) {
5457
- await Promise.allSettled(
5458
- daemons.slice(i, i + 5).map(async (d) => {
5459
- try {
5460
- const daemonStatus = await transport.getDaemonStatus(d.id);
5461
- const sessions = daemonStatus?.sessions ?? [];
5462
- for (const s of sessions) {
5463
- if (s.status === "waiting_approval") pending.push({ daemonId: d.id, session: s });
5464
- }
5465
- } catch {
5466
- }
5467
- })
5468
- );
5469
- }
5470
- }
5471
- if (format === "json") {
5472
- return JSON.stringify({
5473
- pending: pending.map(({ daemonId: dId, session: s }) => ({
5474
- daemon_id: dId,
5475
- session_id: s.id,
5476
- workspace: s.workspace ?? null,
5477
- type: s.providerType ?? null,
5478
- modal_message: null,
5479
- buttons: []
5480
- }))
5481
- }, null, 2);
5482
- }
5483
- if (pending.length === 0) return "No sessions waiting for approval.";
5484
- const lines = pending.map(({ daemonId: dId, session: s }) => {
5485
- const parts = [`daemon_id: ${dId}`, `session_id: ${s.id}`];
5486
- if (s.workspace) parts.push(`workspace: ${s.workspace}`);
5487
- if (s.providerType) parts.push(`type: ${s.providerType}`);
5488
- parts.push("(use read_chat to see the approval prompt)");
5489
- return parts.join("\n ");
5490
- });
5491
- return `Pending approvals (${pending.length}):
5492
-
5493
4624
  ${lines.join("\n\n")}`;
5494
4625
  }
5495
4626
 
@@ -5503,10 +4634,10 @@ async function buildMeshModeCoordinatorPrompt(mesh) {
5503
4634
  }
5504
4635
  }
5505
4636
  async function startMcpServer(opts) {
5506
- const transport = opts.mode === "cloud" ? new CloudTransport({ apiKey: opts.apiKey, baseUrl: opts.baseUrl }) : opts.mode === "ipc" ? new IpcTransport({ port: opts.port }) : new LocalTransport({ port: opts.port, password: opts.password });
4637
+ const transport = opts.mode === "ipc" ? new IpcTransport({ port: opts.port }) : new LocalTransport({ port: opts.port, password: opts.password });
5507
4638
  const alive = await transport.ping();
5508
4639
  if (!alive) {
5509
- const hint = opts.mode === "local" ? `Make sure the standalone daemon is running (adhdev standalone or npx @adhdev/daemon-standalone).` : opts.mode === "ipc" ? `Make sure the cloud daemon is running with local IPC enabled (adhdev daemon).` : `Check your API key and network connectivity.`;
4640
+ const hint = opts.mode === "local" ? `Make sure the standalone daemon is running (adhdev standalone or npx @adhdev/daemon-standalone).` : `Make sure the cloud daemon is running with local IPC enabled (adhdev daemon).`;
5510
4641
  process.stderr.write(`[adhdev-mcp] Cannot reach ${opts.mode} daemon. ${hint}
5511
4642
  `);
5512
4643
  process.exit(1);
@@ -5521,64 +4652,6 @@ async function startMcpServer(opts) {
5521
4652
  `);
5522
4653
  } catch (e) {
5523
4654
  process.stderr.write(`[adhdev-mcp] Failed to parse ADHDEV_INLINE_MESH: ${e.message}
5524
- `);
5525
- }
5526
- }
5527
- if (!mesh && opts.mode === "cloud" && opts.apiKey) {
5528
- try {
5529
- const base = opts.baseUrl || "https://api.adhf.dev";
5530
- const res = await fetch(`${base}/api/v1/repo-meshes/${opts.meshId}`, {
5531
- headers: { "Authorization": `Bearer ${opts.apiKey}`, "Content-Type": "application/json" }
5532
- });
5533
- if (res.ok) {
5534
- const data = await res.json();
5535
- const rm = data.mesh;
5536
- const nodes = data.nodes || [];
5537
- let policy = {};
5538
- try {
5539
- policy = JSON.parse(rm.policy_json || rm.policy || "{}");
5540
- } catch {
5541
- }
5542
- let coordinator = {};
5543
- try {
5544
- coordinator = JSON.parse(rm.coordinator_json || rm.coordinator_config || "{}");
5545
- } catch {
5546
- }
5547
- mesh = {
5548
- id: rm.id,
5549
- name: rm.name,
5550
- repoIdentity: rm.repo_identity,
5551
- repoRemoteUrl: rm.repo_remote_url,
5552
- defaultBranch: rm.default_branch,
5553
- policy: {
5554
- requirePreTaskCheckpoint: false,
5555
- requirePostTaskCheckpoint: true,
5556
- requireApprovalForPush: true,
5557
- allowAutoPublishSubmoduleMainCommits: false,
5558
- requireApprovalForDestructiveGit: true,
5559
- dirtyWorkspaceBehavior: "warn",
5560
- maxParallelTasks: 2,
5561
- spawnedSessionVisibility: "visible",
5562
- ...policy
5563
- },
5564
- coordinator,
5565
- nodes: nodes.map((n) => ({
5566
- id: n.id,
5567
- workspace: n.workspace,
5568
- repoRoot: n.repo_root,
5569
- daemonId: n.daemon_id,
5570
- userOverrides: {},
5571
- policy: {},
5572
- isLocalWorktree: false
5573
- })),
5574
- createdAt: rm.created_at,
5575
- updatedAt: rm.updated_at
5576
- };
5577
- process.stderr.write(`[adhdev-mcp] Loaded mesh config from cloud API
5578
- `);
5579
- }
5580
- } catch (e) {
5581
- process.stderr.write(`[adhdev-mcp] Cloud mesh fetch failed, falling back to local: ${e.message}
5582
4655
  `);
5583
4656
  }
5584
4657
  }
@@ -5605,7 +4678,7 @@ async function startMcpServer(opts) {
5605
4678
  }
5606
4679
  }
5607
4680
  if (!mesh) {
5608
- process.stderr.write(`[adhdev-mcp] Mesh '${opts.meshId}' not found in ${opts.mode === "cloud" ? "cloud or local" : "local"} config. Use 'adhdev mesh list' to see available meshes.
4681
+ process.stderr.write(`[adhdev-mcp] Mesh '${opts.meshId}' not found in local config. Use 'adhdev mesh list' to see available meshes.
5609
4682
  `);
5610
4683
  process.exit(1);
5611
4684
  }
@@ -5784,7 +4857,7 @@ async function startMcpServer(opts) {
5784
4857
  return { content: [{ type: "text", text }] };
5785
4858
  }
5786
4859
  case "list_sessions": {
5787
- const text = await listSessions(transport, { format: a.format, daemon_id: a.daemon_id });
4860
+ const text = await listSessions(transport, { format: a.format });
5788
4861
  return { content: [{ type: "text", text }] };
5789
4862
  }
5790
4863
  case "read_chat": {
@@ -5800,12 +4873,12 @@ async function startMcpServer(opts) {
5800
4873
  return { content: [{ type: "text", text }] };
5801
4874
  }
5802
4875
  case "send_chat": {
5803
- const text = await sendChat(transport, { message: a.message, session_id: a.session_id, daemon_id: a.daemon_id });
4876
+ const text = await sendChat(transport, { message: a.message, session_id: a.session_id });
5804
4877
  return { content: [{ type: "text", text }] };
5805
4878
  }
5806
4879
  case "approve": {
5807
4880
  const action = a.action === "reject" ? "reject" : "approve";
5808
- const text = await approve(transport, { action, session_id: a.session_id, daemon_id: a.daemon_id });
4881
+ const text = await approve(transport, { action, session_id: a.session_id });
5809
4882
  return { content: [{ type: "text", text }] };
5810
4883
  }
5811
4884
  case "screenshot": {
@@ -5818,44 +4891,42 @@ async function startMcpServer(opts) {
5818
4891
  return { content: [{ type: "text", text: result.text }] };
5819
4892
  }
5820
4893
  case "git_status": {
5821
- const text = await gitStatus(transport, { workspace: a.workspace, include_diff: a.include_diff, daemon_id: a.daemon_id, format: a.format });
4894
+ const text = await gitStatus(transport, { workspace: a.workspace, include_diff: a.include_diff, format: a.format });
5822
4895
  return { content: [{ type: "text", text }] };
5823
4896
  }
5824
4897
  case "git_log": {
5825
- const text = await gitLog(transport, { workspace: a.workspace, limit: a.limit, file: a.file, since: a.since, until: a.until, daemon_id: a.daemon_id, format: a.format });
4898
+ const text = await gitLog(transport, { workspace: a.workspace, limit: a.limit, file: a.file, since: a.since, until: a.until, format: a.format });
5826
4899
  return { content: [{ type: "text", text }] };
5827
4900
  }
5828
4901
  case "git_diff": {
5829
- const text = await gitDiff(transport, { workspace: a.workspace, file: a.file, max_lines: a.max_lines, staged: a.staged, daemon_id: a.daemon_id, format: a.format });
4902
+ const text = await gitDiff(transport, { workspace: a.workspace, file: a.file, max_lines: a.max_lines, staged: a.staged, format: a.format });
5830
4903
  return { content: [{ type: "text", text }] };
5831
4904
  }
5832
4905
  case "git_checkpoint": {
5833
- const text = await gitCheckpoint(transport, { workspace: a.workspace, message: a.message, include_untracked: a.include_untracked, daemon_id: a.daemon_id });
4906
+ const text = await gitCheckpoint(transport, { workspace: a.workspace, message: a.message, include_untracked: a.include_untracked });
5834
4907
  return { content: [{ type: "text", text }] };
5835
4908
  }
5836
4909
  case "git_push": {
5837
- const text = await gitPush(transport, { workspace: a.workspace, remote: a.remote, branch: a.branch, daemon_id: a.daemon_id });
4910
+ const text = await gitPush(transport, { workspace: a.workspace, remote: a.remote, branch: a.branch });
5838
4911
  return { content: [{ type: "text", text }] };
5839
4912
  }
5840
4913
  case "launch_session": {
5841
4914
  const text = await launchSession(transport, {
5842
4915
  type: a.type,
5843
4916
  workspace: a.workspace,
5844
- model: a.model,
5845
- daemon_id: a.daemon_id
4917
+ model: a.model
5846
4918
  });
5847
4919
  return { content: [{ type: "text", text }] };
5848
4920
  }
5849
4921
  case "stop_session": {
5850
4922
  const text = await stopSession(transport, {
5851
4923
  session_id: a.session_id,
5852
- daemon_id: a.daemon_id,
5853
4924
  type: a.type
5854
4925
  });
5855
4926
  return { content: [{ type: "text", text }] };
5856
4927
  }
5857
4928
  case "check_pending": {
5858
- const text = await checkPending(transport, { daemon_id: a.daemon_id, format: a.format });
4929
+ const text = await checkPending(transport, { format: a.format });
5859
4930
  return { content: [{ type: "text", text }] };
5860
4931
  }
5861
4932
  default:
@@ -5877,26 +4948,18 @@ async function startMcpServer(opts) {
5877
4948
  // src/index.ts
5878
4949
  function parseArgs(argv, env = process.env) {
5879
4950
  const args = argv.slice(2);
5880
- let apiKey;
5881
- let baseUrl;
5882
4951
  let port;
5883
4952
  let password;
5884
4953
  let meshId;
5885
4954
  let explicitMode;
5886
4955
  for (let i = 0; i < args.length; i++) {
5887
4956
  const arg = args[i];
5888
- if ((arg === "--api-key" || arg === "-k") && args[i + 1]) {
5889
- apiKey = args[++i];
5890
- } else if (arg?.startsWith("--api-key=")) {
5891
- apiKey = arg.slice("--api-key=".length);
5892
- } else if (arg === "--base-url" && args[i + 1]) {
5893
- baseUrl = args[++i];
5894
- } else if (arg === "--mode" && args[i + 1]) {
4957
+ if (arg === "--mode" && args[i + 1]) {
5895
4958
  const value = String(args[++i]).trim();
5896
- if (value === "local" || value === "cloud" || value === "ipc") explicitMode = value;
4959
+ if (value === "local" || value === "ipc") explicitMode = value;
5897
4960
  } else if (arg?.startsWith("--mode=")) {
5898
4961
  const value = arg.slice("--mode=".length).trim();
5899
- if (value === "local" || value === "cloud" || value === "ipc") explicitMode = value;
4962
+ if (value === "local" || value === "ipc") explicitMode = value;
5900
4963
  } else if (arg === "--port" && args[i + 1]) {
5901
4964
  port = Number(args[++i]);
5902
4965
  } else if (arg?.startsWith("--port=")) {
@@ -5912,15 +4975,14 @@ function parseArgs(argv, env = process.env) {
5912
4975
  process.exit(0);
5913
4976
  }
5914
4977
  }
5915
- if (!apiKey && env.ADHDEV_API_KEY) apiKey = env.ADHDEV_API_KEY;
5916
4978
  if (!password && env.ADHDEV_PASSWORD) password = env.ADHDEV_PASSWORD;
5917
4979
  if (!meshId && env.ADHDEV_MESH_ID) meshId = env.ADHDEV_MESH_ID;
5918
4980
  if (!explicitMode && env.ADHDEV_MCP_TRANSPORT) {
5919
4981
  const value = env.ADHDEV_MCP_TRANSPORT.trim();
5920
- if (value === "local" || value === "cloud" || value === "ipc") explicitMode = value;
4982
+ if (value === "local" || value === "ipc") explicitMode = value;
5921
4983
  }
5922
- const mode = explicitMode || (apiKey ? "cloud" : meshId && env.ADHDEV_INLINE_MESH ? "ipc" : "local");
5923
- return { mode, port, password, apiKey, baseUrl, meshId };
4984
+ const mode = explicitMode || (meshId && env.ADHDEV_INLINE_MESH ? "ipc" : "local");
4985
+ return { mode, port, password, meshId };
5924
4986
  }
5925
4987
  function printHelp() {
5926
4988
  console.error(buildMcpHelpText());