adhdev 0.9.56 → 0.9.57

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/cli/index.js CHANGED
@@ -35891,7 +35891,7 @@ Run 'adhdev doctor' for detailed diagnostics.`
35891
35891
  resolvedDir,
35892
35892
  resolvedCliArgs,
35893
35893
  resolvedProvider,
35894
- {},
35894
+ this.providerLoader.getSettings(normalizedType),
35895
35895
  false,
35896
35896
  {
35897
35897
  providerSessionId: sessionBinding.providerSessionId,
@@ -38041,9 +38041,9 @@ function validateProviderDefinition(raw) {
38041
38041
  const typedProvider = provider;
38042
38042
  const controls = Array.isArray(provider.controls) ? provider.controls : [];
38043
38043
  if (category === "cli" || category === "acp") {
38044
- const spawn6 = provider.spawn;
38045
- const command = spawn6 && typeof spawn6 === "object" ? spawn6.command : void 0;
38046
- if (!spawn6 || typeof spawn6 !== "object") {
38044
+ const spawn7 = provider.spawn;
38045
+ const command = spawn7 && typeof spawn7 === "object" ? spawn7.command : void 0;
38046
+ if (!spawn7 || typeof spawn7 !== "object") {
38047
38047
  errors.push(`${String(category).toUpperCase()}/CLI providers must have spawn config`);
38048
38048
  } else if (typeof command !== "string" || !command.trim()) {
38049
38049
  errors.push("spawn.command is required");
@@ -46267,8 +46267,8 @@ async function handleAutoImplement(ctx, type, req, res) {
46267
46267
  fs14.writeFileSync(promptFile, prompt2, "utf-8");
46268
46268
  ctx.log(`Auto-implement prompt written to ${promptFile} (${prompt2.length} chars)`);
46269
46269
  const agentProvider = ctx.providerLoader.resolve(agent) || ctx.providerLoader.getMeta(agent);
46270
- const spawn6 = agentProvider?.spawn;
46271
- if (!spawn6?.command) {
46270
+ const spawn7 = agentProvider?.spawn;
46271
+ if (!spawn7?.command) {
46272
46272
  try {
46273
46273
  fs14.unlinkSync(promptFile);
46274
46274
  } catch {
@@ -46278,22 +46278,22 @@ async function handleAutoImplement(ctx, type, req, res) {
46278
46278
  }
46279
46279
  const agentCategory = agentProvider?.category;
46280
46280
  if (agentCategory === "acp") {
46281
- sendAutoImplSSE(ctx, { event: "progress", data: { function: "_init", status: "spawning", message: `Spawning ACP agent: ${spawn6.command} ${(spawn6.args || []).join(" ")}` } });
46281
+ sendAutoImplSSE(ctx, { event: "progress", data: { function: "_init", status: "spawning", message: `Spawning ACP agent: ${spawn7.command} ${(spawn7.args || []).join(" ")}` } });
46282
46282
  ctx.autoImplStatus.running = true;
46283
46283
  ctx.autoImplStatus.type = type;
46284
46284
  const { ClientSideConnection: ClientSideConnection2, ndJsonStream: ndJsonStream2, PROTOCOL_VERSION: PROTOCOL_VERSION2 } = await Promise.resolve().then(() => (init_acp(), acp_exports));
46285
46285
  const { Readable: Readable3, Writable: Writable3 } = await import("stream");
46286
46286
  const { spawn: spawnFn2 } = await import("child_process");
46287
- const acpArgs = [...spawn6.args || []];
46287
+ const acpArgs = [...spawn7.args || []];
46288
46288
  if (model) {
46289
46289
  acpArgs.push("--model", model);
46290
46290
  ctx.log(`Auto-implement ACP using model: ${model}`);
46291
46291
  }
46292
- const child2 = spawnFn2(spawn6.command, acpArgs, {
46292
+ const child2 = spawnFn2(spawn7.command, acpArgs, {
46293
46293
  cwd: providerDir,
46294
46294
  stdio: ["pipe", "pipe", "pipe"],
46295
- shell: spawn6.shell ?? false,
46296
- env: { ...process.env, ...spawn6.env || {} }
46295
+ shell: spawn7.shell ?? false,
46296
+ env: { ...process.env, ...spawn7.env || {} }
46297
46297
  });
46298
46298
  ctx.autoImplProcess = child2;
46299
46299
  child2.stderr?.on("data", (d) => {
@@ -46403,7 +46403,7 @@ async function handleAutoImplement(ctx, type, req, res) {
46403
46403
  ctx.json(res, 202, {
46404
46404
  started: true,
46405
46405
  type,
46406
- agent: spawn6.command,
46406
+ agent: spawn7.command,
46407
46407
  functions,
46408
46408
  providerDir,
46409
46409
  message: "ACP Auto-implement started. Connect to SSE for progress.",
@@ -46411,10 +46411,10 @@ async function handleAutoImplement(ctx, type, req, res) {
46411
46411
  });
46412
46412
  return;
46413
46413
  }
46414
- const command = spawn6.command;
46415
- const autoImpl = spawn6.autoImpl;
46414
+ const command = spawn7.command;
46415
+ const autoImpl = spawn7.autoImpl;
46416
46416
  const interactiveFlags = ["--yolo", "--interactive", "-i"];
46417
- const baseArgs = [...spawn6.args || []].filter((a) => !interactiveFlags.includes(a));
46417
+ const baseArgs = [...spawn7.args || []].filter((a) => !interactiveFlags.includes(a));
46418
46418
  let shellCmd;
46419
46419
  const isWin = os24.platform() === "win32";
46420
46420
  const escapeArg = (a) => isWin ? `"${a.replace(/"/g, '""')}"` : `'${a.replace(/'/g, "'\\''")}'`;
@@ -46461,7 +46461,7 @@ async function handleAutoImplement(ctx, type, req, res) {
46461
46461
  cols: 120,
46462
46462
  rows: 40,
46463
46463
  cwd: providerDir,
46464
- env: { ...process.env, ...spawn6.env || {} }
46464
+ env: { ...process.env, ...spawn7.env || {} }
46465
46465
  });
46466
46466
  isPty = true;
46467
46467
  } catch (err) {
@@ -46473,7 +46473,7 @@ async function handleAutoImplement(ctx, type, req, res) {
46473
46473
  stdio: ["pipe", "pipe", "pipe"],
46474
46474
  env: {
46475
46475
  ...process.env,
46476
- ...spawn6.env || {}
46476
+ ...spawn7.env || {}
46477
46477
  }
46478
46478
  });
46479
46479
  child.on("error", (err2) => {
@@ -47645,16 +47645,16 @@ var init_dev_server = __esm({
47645
47645
  this.json(res, 404, { error: `Provider not found: ${type}` });
47646
47646
  return;
47647
47647
  }
47648
- const spawn6 = provider.spawn;
47649
- if (!spawn6) {
47648
+ const spawn7 = provider.spawn;
47649
+ if (!spawn7) {
47650
47650
  this.json(res, 400, { error: `Provider ${type} has no spawn config` });
47651
47651
  return;
47652
47652
  }
47653
47653
  const { spawn: spawnFn } = await import("child_process");
47654
47654
  const start = Date.now();
47655
47655
  try {
47656
- const child = spawnFn(spawn6.command, [...spawn6.args || []], {
47657
- shell: spawn6.shell ?? false,
47656
+ const child = spawnFn(spawn7.command, [...spawn7.args || []], {
47657
+ shell: spawn7.shell ?? false,
47658
47658
  timeout: 5e3,
47659
47659
  stdio: ["pipe", "pipe", "pipe"]
47660
47660
  });
@@ -47686,7 +47686,7 @@ var init_dev_server = __esm({
47686
47686
  const elapsed = Date.now() - start;
47687
47687
  this.json(res, 200, {
47688
47688
  success: true,
47689
- command: `${spawn6.command} ${(spawn6.args || []).join(" ")}`,
47689
+ command: `${spawn7.command} ${(spawn7.args || []).join(" ")}`,
47690
47690
  elapsed,
47691
47691
  stdout: stdout.trim(),
47692
47692
  stderr: stderr.trim(),
@@ -47696,7 +47696,7 @@ var init_dev_server = __esm({
47696
47696
  const elapsed = Date.now() - start;
47697
47697
  this.json(res, 200, {
47698
47698
  success: false,
47699
- command: `${spawn6.command} ${(spawn6.args || []).join(" ")}`,
47699
+ command: `${spawn7.command} ${(spawn7.args || []).join(" ")}`,
47700
47700
  elapsed,
47701
47701
  error: e.message
47702
47702
  });
@@ -48159,20 +48159,20 @@ var init_dev_server = __esm({
48159
48159
  this.json(res, 404, { error: `Provider not found: ${type}` });
48160
48160
  return;
48161
48161
  }
48162
- const spawn6 = provider.spawn;
48163
- if (!spawn6) {
48162
+ const spawn7 = provider.spawn;
48163
+ if (!spawn7) {
48164
48164
  this.json(res, 400, { error: `Provider ${type} has no spawn config` });
48165
48165
  return;
48166
48166
  }
48167
48167
  const { spawn: spawnFn } = await import("child_process");
48168
48168
  const start = Date.now();
48169
48169
  try {
48170
- const args = [...spawn6.args || [], message];
48171
- const child = spawnFn(spawn6.command, args, {
48172
- shell: spawn6.shell ?? false,
48170
+ const args = [...spawn7.args || [], message];
48171
+ const child = spawnFn(spawn7.command, args, {
48172
+ shell: spawn7.shell ?? false,
48173
48173
  timeout,
48174
48174
  stdio: ["pipe", "pipe", "pipe"],
48175
- env: { ...process.env, ...spawn6.env || {} }
48175
+ env: { ...process.env, ...spawn7.env || {} }
48176
48176
  });
48177
48177
  let stdout = "";
48178
48178
  let stderr = "";
@@ -80979,6 +80979,58 @@ var init_server_connection = __esm({
80979
80979
  onStateChange(callback) {
80980
80980
  this.stateChangeCallbacks.push(callback);
80981
80981
  }
80982
+ /**
80983
+ * Send a command to another daemon owned by the same user, via server relay.
80984
+ * The server validates ownership before forwarding to the target daemon.
80985
+ *
80986
+ * Returns the command result or throws on timeout / auth failure.
80987
+ */
80988
+ sendMeshCommand(targetDaemonId, command, args = {}, timeoutMs = 3e4) {
80989
+ return new Promise((resolve21, reject) => {
80990
+ const requestId = `mesh_${Date.now()}_${Math.random().toString(36).substring(2, 8)}`;
80991
+ const timer = setTimeout(() => {
80992
+ this.off("daemon_mesh_result", handler);
80993
+ reject(new Error(`Mesh command timed out after ${timeoutMs}ms`));
80994
+ }, timeoutMs);
80995
+ const handler = (msg) => {
80996
+ if (msg.payload?.requestId !== requestId) return;
80997
+ this.off("daemon_mesh_result", handler);
80998
+ clearTimeout(timer);
80999
+ if (msg.payload?.success === false) {
81000
+ reject(new Error(msg.payload?.error ?? "Mesh command failed"));
81001
+ } else {
81002
+ resolve21(msg.payload?.result);
81003
+ }
81004
+ };
81005
+ this.on("daemon_mesh_result", handler);
81006
+ const sent = this.ws?.readyState === 1 && (() => {
81007
+ try {
81008
+ this.ws.send(JSON.stringify({
81009
+ type: "daemon_mesh_command",
81010
+ requestId,
81011
+ targetDaemonId,
81012
+ command,
81013
+ args,
81014
+ timestamp: Date.now()
81015
+ }));
81016
+ return true;
81017
+ } catch {
81018
+ return false;
81019
+ }
81020
+ })();
81021
+ if (!sent) {
81022
+ clearTimeout(timer);
81023
+ this.off("daemon_mesh_result", handler);
81024
+ reject(new Error("Not connected to server"));
81025
+ }
81026
+ });
81027
+ }
81028
+ off(type, handler) {
81029
+ const handlers = this.messageHandlers.get(type);
81030
+ if (!handlers) return;
81031
+ const idx = handlers.indexOf(handler);
81032
+ if (idx !== -1) handlers.splice(idx, 1);
81033
+ }
80982
81034
  getState() {
80983
81035
  return this.state;
80984
81036
  }
@@ -89935,6 +89987,64 @@ var init_session_host_controller = __esm({
89935
89987
  }
89936
89988
  });
89937
89989
 
89990
+ // src/daemon-mesh-manager.ts
89991
+ var daemon_mesh_manager_exports = {};
89992
+ __export(daemon_mesh_manager_exports, {
89993
+ DaemonMeshManager: () => DaemonMeshManager
89994
+ });
89995
+ function interpolateArgs(args, context) {
89996
+ const result = {};
89997
+ for (const [k, v] of Object.entries(args)) {
89998
+ result[k] = typeof v === "string" ? interpolateString(v, context) : v;
89999
+ }
90000
+ return result;
90001
+ }
90002
+ function interpolateString(template, ctx) {
90003
+ return template.replace(/\{\{(\w+)\}\}/g, (_2, key) => {
90004
+ const val = ctx[key];
90005
+ return val !== void 0 ? String(val) : `{{${key}}}`;
90006
+ });
90007
+ }
90008
+ var DaemonMeshManager;
90009
+ var init_daemon_mesh_manager = __esm({
90010
+ "src/daemon-mesh-manager.ts"() {
90011
+ "use strict";
90012
+ init_src();
90013
+ DaemonMeshManager = class {
90014
+ rules = [];
90015
+ serverConn;
90016
+ constructor(serverConn) {
90017
+ this.serverConn = serverConn;
90018
+ }
90019
+ setRules(rules) {
90020
+ this.rules = rules;
90021
+ LOG.info("Mesh", `[Mesh] ${rules.length} rule(s) loaded`);
90022
+ }
90023
+ async emit(event) {
90024
+ const matching = this.rules.filter((r) => r.trigger === event.trigger);
90025
+ if (matching.length === 0) return;
90026
+ await Promise.allSettled(
90027
+ matching.map((rule) => this.executeRule(rule, event.context ?? {}))
90028
+ );
90029
+ }
90030
+ async executeRule(rule, context) {
90031
+ const args = interpolateArgs(rule.args ?? {}, context);
90032
+ try {
90033
+ LOG.info("Mesh", `[Mesh] Relaying '${rule.command}' \u2192 ${rule.targetDaemonId.slice(0, 12)}\u2026`);
90034
+ await this.serverConn.sendMeshCommand(rule.targetDaemonId, rule.command, args);
90035
+ LOG.info("Mesh", `[Mesh] Relay '${rule.command}' complete`);
90036
+ } catch (err) {
90037
+ LOG.warn("Mesh", `[Mesh] Relay '${rule.command}' failed: ${err?.message ?? err}`);
90038
+ }
90039
+ }
90040
+ /** Convenience: send a one-off mesh command without a rule. */
90041
+ async sendCommand(targetDaemonId, command, args = {}) {
90042
+ return this.serverConn.sendMeshCommand(targetDaemonId, command, args);
90043
+ }
90044
+ };
90045
+ }
90046
+ });
90047
+
89938
90048
  // src/adhdev-daemon.ts
89939
90049
  var adhdev_daemon_exports = {};
89940
90050
  __export(adhdev_daemon_exports, {
@@ -90179,13 +90289,14 @@ var init_adhdev_daemon = __esm({
90179
90289
  init_version();
90180
90290
  init_src();
90181
90291
  init_runtime_defaults();
90182
- pkgVersion = resolvePackageVersion({ injectedVersion: "0.9.56" });
90292
+ pkgVersion = resolvePackageVersion({ injectedVersion: "0.9.57" });
90183
90293
  AdhdevDaemon = class _AdhdevDaemon {
90184
90294
  localHttpServer = null;
90185
90295
  localWss = null;
90186
90296
  localClients = /* @__PURE__ */ new Set();
90187
90297
  serverConn = null;
90188
90298
  p2p = null;
90299
+ meshManager = null;
90189
90300
  screenshotController = null;
90190
90301
  statusReporter = null;
90191
90302
  topicSubscriptionTimer = null;
@@ -90769,6 +90880,12 @@ ${err?.stack || ""}`);
90769
90880
  }
90770
90881
  });
90771
90882
  this.p2p = new DaemonP2PSender(this.serverConn);
90883
+ const { DaemonMeshManager: DaemonMeshManager2 } = await Promise.resolve().then(() => (init_daemon_mesh_manager(), daemon_mesh_manager_exports));
90884
+ this.meshManager = new DaemonMeshManager2(this.serverConn);
90885
+ const meshRules = config2.meshRules;
90886
+ if (Array.isArray(meshRules) && meshRules.length > 0) {
90887
+ this.meshManager.setRules(meshRules);
90888
+ }
90772
90889
  if (this.p2p.isAvailable) {
90773
90890
  console.log(source_default.green(" \u{1F517} P2P available (node-datachannel)"));
90774
90891
  this.p2p.onInput(async (event) => {
@@ -91107,6 +91224,16 @@ ${err?.stack || ""}`);
91107
91224
  if (cmdType.startsWith("git_")) {
91108
91225
  void this.flushP2PWorkspaceGitSubscriptions();
91109
91226
  }
91227
+ if (cmdType === "git_checkpoint" && routed.success && this.meshManager) {
91228
+ void this.meshManager.emit({
91229
+ trigger: "git_checkpoint_complete",
91230
+ context: {
91231
+ workspace: String(normalizedData.workspace ?? ""),
91232
+ checkpoint_message: routed.checkpoint?.message ?? String(normalizedData.message ?? ""),
91233
+ commit: routed.checkpoint?.commit ?? ""
91234
+ }
91235
+ });
91236
+ }
91110
91237
  return { ...routed, interactionId };
91111
91238
  } catch (e) {
91112
91239
  logCommand({ ts: (/* @__PURE__ */ new Date()).toISOString(), cmd: cmdType, source: "p2p", interactionId, success: false, error: e.message, durationMs: Date.now() - cmdStart });
@@ -93817,9 +93944,9 @@ async function requestSessionHostDirect(request) {
93817
93944
  }
93818
93945
  }
93819
93946
  async function runRuntimeLaunchSpec(spec) {
93820
- const { spawn: spawn6 } = await import("child_process");
93947
+ const { spawn: spawn7 } = await import("child_process");
93821
93948
  return await new Promise((resolve21, reject) => {
93822
- const child = spawn6(spec.command, spec.args, {
93949
+ const child = spawn7(spec.command, spec.args, {
93823
93950
  stdio: "inherit",
93824
93951
  env: spec.env,
93825
93952
  shell: process.platform === "win32" && spec.command !== process.execPath
@@ -94088,7 +94215,7 @@ async function handleTraceCommand(options) {
94088
94215
  async function runDaemonUpgrade(options, pkgVersion3) {
94089
94216
  const { isDaemonRunning: isDaemonRunning2, stopDaemon: stopDaemon2 } = await Promise.resolve().then(() => (init_adhdev_daemon(), adhdev_daemon_exports));
94090
94217
  const { stopManagedSessionHostProcess: stopManagedSessionHostProcess2 } = await Promise.resolve().then(() => (init_session_host(), session_host_exports));
94091
- const { execSync: execSync8, spawn: spawn6 } = await import("child_process");
94218
+ const { execSync: execSync8, spawn: spawn7 } = await import("child_process");
94092
94219
  const fsMod = await import("fs");
94093
94220
  const pathMod = await import("path");
94094
94221
  console.log(source_default.bold("\n \u{1F504} ADHDev Upgrade\n"));
@@ -94172,7 +94299,7 @@ async function runDaemonUpgrade(options, pkgVersion3) {
94172
94299
  await new Promise((r) => setTimeout(r, 2e3));
94173
94300
  stopManagedSessionHostProcess2();
94174
94301
  await new Promise((r) => setTimeout(r, 500));
94175
- const child = spawn6(process.execPath, [process.argv[1], "daemon", "-p", DEFAULT_DAEMON_PORT_TEXT], {
94302
+ const child = spawn7(process.execPath, [process.argv[1], "daemon", "-p", DEFAULT_DAEMON_PORT_TEXT], {
94176
94303
  detached: true,
94177
94304
  stdio: "ignore",
94178
94305
  windowsHide: true,
@@ -94219,7 +94346,7 @@ function registerDaemonCommands(program2, pkgVersion3) {
94219
94346
  }
94220
94347
  });
94221
94348
  program2.command("standalone").description("\u{1F5A5}\uFE0F Start ADHDev Standalone Server (Local Dashboard & Embedded Daemon)").option("-p, --port <port>", "Local HTTP/WS server port", "3847").option("--host <host>", "Bind to specific host (use 0.0.0.0 for LAN access)").option("--no-open", "Prevent opening browser automatically").option("--token <token>", "Require token authentication").option("--dev", "Enable Dev Mode").action(async (options) => {
94222
- const { spawn: spawn6, execSync: execSync8 } = await import("child_process");
94349
+ const { spawn: spawn7, execSync: execSync8 } = await import("child_process");
94223
94350
  const { DEFAULT_STANDALONE_SESSION_HOST_APP_NAME: DEFAULT_STANDALONE_SESSION_HOST_APP_NAME2, resolveSessionHostAppNameResolution: resolveSessionHostAppNameResolution2 } = await Promise.resolve().then(() => (init_src(), src_exports));
94224
94351
  console.log(source_default.cyan("\n Starting ADHDev Standalone Server..."));
94225
94352
  const args = [];
@@ -94248,7 +94375,7 @@ function registerDaemonCommands(program2, pkgVersion3) {
94248
94375
  }
94249
94376
  console.log(source_default.gray(` Session host namespace: ${sessionHostName}${sessionHostResolution.source === "default" ? " (default isolated standalone namespace)" : sessionHostResolution.source === "explicit" ? " (from ADHDEV_SESSION_HOST_NAME)" : " (auto-corrected for standalone isolation)"}`));
94250
94377
  const spawnArgs = bin === "npx" ? npxArgs : args;
94251
- const child = spawn6(bin, spawnArgs, {
94378
+ const child = spawn7(bin, spawnArgs, {
94252
94379
  stdio: "inherit",
94253
94380
  shell: process.platform === "win32",
94254
94381
  env: standaloneEnv
@@ -94722,7 +94849,7 @@ function registerDaemonCommands(program2, pkgVersion3) {
94722
94849
  hideCommand(program2.command("daemon:restart").description("Restart ADHDev Daemon (stop \u2192 start)").option("-p, --port <port>", "Local WS server port", DEFAULT_DAEMON_PORT_TEXT).option("--server <url>", "Override server URL").option("--dev", "Enable Dev Mode").action(async (options) => {
94723
94850
  const { stopDaemon: stopDaemon2, isDaemonRunning: isDaemonRunning2 } = await Promise.resolve().then(() => (init_adhdev_daemon(), adhdev_daemon_exports));
94724
94851
  const { stopManagedSessionHostProcess: stopManagedSessionHostProcess2 } = await Promise.resolve().then(() => (init_session_host(), session_host_exports));
94725
- const { spawn: spawn6 } = await import("child_process");
94852
+ const { spawn: spawn7 } = await import("child_process");
94726
94853
  if (isDaemonRunning2({ port: parseInt(options.port, 10) || DEFAULT_DAEMON_PORT })) {
94727
94854
  console.log(source_default.yellow("\n Stopping existing daemon..."));
94728
94855
  stopDaemon2({ port: parseInt(options.port, 10) || DEFAULT_DAEMON_PORT });
@@ -94734,7 +94861,7 @@ function registerDaemonCommands(program2, pkgVersion3) {
94734
94861
  const args = ["daemon", "-p", options.port || DEFAULT_DAEMON_PORT_TEXT];
94735
94862
  if (options.server) args.push("--server", options.server);
94736
94863
  if (options.dev) args.push("--dev");
94737
- const child = spawn6(process.execPath, [process.argv[1], ...args], {
94864
+ const child = spawn7(process.execPath, [process.argv[1], ...args], {
94738
94865
  detached: true,
94739
94866
  stdio: "ignore",
94740
94867
  windowsHide: true,
@@ -96738,6 +96865,64 @@ function registerCdpCommands(program2) {
96738
96865
  });
96739
96866
  }
96740
96867
 
96868
+ // src/cli/mcp-commands.ts
96869
+ var import_node_child_process3 = require("child_process");
96870
+ var import_node_module3 = require("module");
96871
+ init_source();
96872
+ function registerMcpCommands(program2) {
96873
+ program2.command("mcp").description("Start an MCP server to expose IDE agents as tools (for Claude Desktop, etc.)").option("--api-key <key>", "ADHDev cloud API key (switches to cloud mode)").option("--port <n>", "Standalone daemon port (default: 3847)", "3847").option("--password <pass>", "Standalone daemon password (if set)").option("--base-url <url>", "Override cloud API base URL").addHelpText("after", `
96874
+ Examples:
96875
+ adhdev mcp Local mode (requires: adhdev standalone)
96876
+ adhdev mcp --api-key adk_xxx Cloud mode (no local daemon needed)
96877
+
96878
+ Claude Desktop config (~/.claude_desktop_config.json):
96879
+ {
96880
+ "mcpServers": {
96881
+ "adhdev": {
96882
+ "command": "adhdev",
96883
+ "args": ["mcp"]
96884
+ }
96885
+ }
96886
+ }
96887
+
96888
+ Tools available (local): list_sessions, read_chat, send_chat, approve, screenshot, git_status
96889
+ Tools available (cloud): list_sessions, read_chat, send_chat, approve
96890
+ `).action(async (opts) => {
96891
+ const mcpBin = resolveMcpBin();
96892
+ if (!mcpBin) {
96893
+ console.error(source_default.red("\u2717 @adhdev/mcp-server not found. Run: npm install -g @adhdev/mcp-server"));
96894
+ process.exit(1);
96895
+ }
96896
+ const args = [];
96897
+ if (opts.apiKey) args.push("--api-key", opts.apiKey);
96898
+ if (opts.port && opts.port !== "3847") args.push("--port", opts.port);
96899
+ if (opts.password) args.push("--password", opts.password);
96900
+ if (opts.baseUrl) args.push("--base-url", opts.baseUrl);
96901
+ const env3 = { ...process.env };
96902
+ if (opts.apiKey) env3.ADHDEV_API_KEY = opts.apiKey;
96903
+ if (opts.password) env3.ADHDEV_PASSWORD = opts.password;
96904
+ const child = (0, import_node_child_process3.spawn)(process.execPath, [mcpBin, ...args], {
96905
+ stdio: "inherit",
96906
+ env: env3
96907
+ });
96908
+ child.on("error", (err) => {
96909
+ console.error(source_default.red(`\u2717 MCP server error: ${err.message}`));
96910
+ process.exit(1);
96911
+ });
96912
+ child.on("exit", (code) => {
96913
+ process.exit(code ?? 0);
96914
+ });
96915
+ });
96916
+ }
96917
+ function resolveMcpBin() {
96918
+ try {
96919
+ const req = (0, import_node_module3.createRequire)(__filename);
96920
+ return req.resolve("@adhdev/mcp-server");
96921
+ } catch {
96922
+ return null;
96923
+ }
96924
+ }
96925
+
96741
96926
  // src/cli/index.ts
96742
96927
  init_version();
96743
96928
  var pkgVersion2 = resolvePackageVersion();
@@ -96757,6 +96942,7 @@ registerDoctorCommands(program, pkgVersion2);
96757
96942
  registerProviderCommands(program);
96758
96943
  registerCdpCommands(program);
96759
96944
  registerServiceCommands(program);
96945
+ registerMcpCommands(program);
96760
96946
  void (async () => {
96761
96947
  const helperMode = await maybeRunDaemonUpgradeHelperFromEnv();
96762
96948
  if (helperMode) {
@@ -96783,6 +96969,7 @@ void (async () => {
96783
96969
  console.log(source_default.gray(" Advanced tools:"));
96784
96970
  console.log(source_default.gray(" adhdev trace --category session_host \u2014 Inspect structured daemon trace"));
96785
96971
  console.log(source_default.gray(" adhdev service \u2014 Manage OS background auto-start service"));
96972
+ console.log(source_default.gray(" adhdev mcp \u2014 Start MCP server (expose agents to Claude Desktop, etc.)"));
96786
96973
  console.log(source_default.gray(" adhdev provider ... \u2014 Provider development commands"));
96787
96974
  console.log(source_default.gray(" adhdev cdp ... \u2014 CDP debugging tools"));
96788
96975
  console.log();