adhdev 0.5.8 → 0.5.12

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.js CHANGED
@@ -16718,14 +16718,14 @@ var require_dist = __commonJS({
16718
16718
  LOG: () => LOG5,
16719
16719
  ProviderCliAdapter: () => ProviderCliAdapter,
16720
16720
  ProviderInstanceManager: () => ProviderInstanceManager,
16721
- ProviderLoader: () => ProviderLoader2,
16721
+ ProviderLoader: () => ProviderLoader,
16722
16722
  VersionArchive: () => VersionArchive2,
16723
16723
  addCliHistory: () => addCliHistory,
16724
16724
  connectCdpManager: () => connectCdpManager,
16725
16725
  detectAllVersions: () => detectAllVersions2,
16726
16726
  detectCLIs: () => detectCLIs,
16727
- detectIDEs: () => detectIDEs2,
16728
- getAIExtensions: () => getAIExtensions2,
16727
+ detectIDEs: () => detectIDEs,
16728
+ getAIExtensions: () => getAIExtensions,
16729
16729
  getAvailableIdeIds: () => getAvailableIdeIds,
16730
16730
  getHostMemorySnapshot: () => getHostMemorySnapshot,
16731
16731
  getLogLevel: () => getLogLevel,
@@ -16734,11 +16734,11 @@ var require_dist = __commonJS({
16734
16734
  getWorkspaceActivity: () => getWorkspaceActivity,
16735
16735
  getWorkspaceState: () => getWorkspaceState,
16736
16736
  initDaemonComponents: () => initDaemonComponents2,
16737
- installExtensions: () => installExtensions2,
16737
+ installExtensions: () => installExtensions,
16738
16738
  installGlobalInterceptor: () => installGlobalInterceptor,
16739
16739
  isExtensionInstalled: () => isExtensionInstalled,
16740
16740
  isSetupComplete: () => isSetupComplete2,
16741
- launchIDE: () => launchIDE2,
16741
+ launchIDE: () => launchIDE,
16742
16742
  launchWithCdp: () => launchWithCdp,
16743
16743
  loadConfig: () => loadConfig3,
16744
16744
  logCommand: () => logCommand2,
@@ -16850,7 +16850,7 @@ var require_dist = __commonJS({
16850
16850
  }
16851
16851
  return null;
16852
16852
  }
16853
- async function detectIDEs2() {
16853
+ async function detectIDEs() {
16854
16854
  const os15 = (0, import_os2.platform)();
16855
16855
  const results = [];
16856
16856
  for (const def of getMergedDefinitions()) {
@@ -18655,8 +18655,7 @@ var require_dist = __commonJS({
18655
18655
  // IDE meta
18656
18656
  ideVersion = "";
18657
18657
  instanceId;
18658
- workspaceFolders = [];
18659
- activeFile = null;
18658
+ workspace = "";
18660
18659
  // ─── Child Extension Instances ────────────────────
18661
18660
  extensions = /* @__PURE__ */ new Map();
18662
18661
  constructor(provider, instanceKey) {
@@ -18717,8 +18716,7 @@ var require_dist = __commonJS({
18717
18716
  activeModal: this.cachedChat.activeModal || null,
18718
18717
  inputContent: this.cachedChat.inputContent || ""
18719
18718
  } : null,
18720
- workspaceFolders: this.workspaceFolders,
18721
- activeFile: this.activeFile,
18719
+ workspace: this.workspace || null,
18722
18720
  extensions: extensionStates,
18723
18721
  cdpConnected: cdp?.isConnected || false,
18724
18722
  currentModel: this.cachedChat?.model || void 0,
@@ -18735,11 +18733,6 @@ var require_dist = __commonJS({
18735
18733
  } else if (event === "cdp_disconnected") {
18736
18734
  this.cachedChat = null;
18737
18735
  this.currentStatus = "idle";
18738
- } else if (event === "extension_data") {
18739
- if (data?.workspaceFolders) this.workspaceFolders = data.workspaceFolders;
18740
- if (data?.activeFile) this.activeFile = data.activeFile;
18741
- if (data?.ideVersion) this.ideVersion = data.ideVersion;
18742
- if (data?.instanceId) this.instanceId = data.instanceId;
18743
18736
  } else if (event === "stream_update") {
18744
18737
  const extType = data?.extensionType;
18745
18738
  if (extType && this.extensions.has(extType)) {
@@ -18795,6 +18788,10 @@ var require_dist = __commonJS({
18795
18788
  getExtensionInstances() {
18796
18789
  return [...this.extensions.values()];
18797
18790
  }
18791
+ /** Set workspace from daemon launch context */
18792
+ setWorkspace(workspace) {
18793
+ this.workspace = workspace;
18794
+ }
18798
18795
  // ─── CDP readChat ───────────────────────────────
18799
18796
  async readChat() {
18800
18797
  const { cdp } = this.context;
@@ -20874,7 +20871,7 @@ var require_dist = __commonJS({
20874
20871
  var fs5 = __toESM2(require("fs"));
20875
20872
  var path6 = __toESM2(require("path"));
20876
20873
  var os7 = __toESM2(require("os"));
20877
- var ProviderLoader2 = class _ProviderLoader {
20874
+ var ProviderLoader = class _ProviderLoader {
20878
20875
  providers = /* @__PURE__ */ new Map();
20879
20876
  builtinDirs;
20880
20877
  userDir;
@@ -21753,7 +21750,7 @@ var require_dist = __commonJS({
21753
21750
  var _providerLoader = null;
21754
21751
  function getProviderLoader() {
21755
21752
  if (!_providerLoader) {
21756
- _providerLoader = new ProviderLoader2({ logFn: () => {
21753
+ _providerLoader = new ProviderLoader({ logFn: () => {
21757
21754
  } });
21758
21755
  _providerLoader.loadAll();
21759
21756
  _providerLoader.registerToDetector();
@@ -21954,7 +21951,7 @@ var require_dist = __commonJS({
21954
21951
  async function launchWithCdp(options = {}) {
21955
21952
  const platform8 = os8.platform();
21956
21953
  let targetIde;
21957
- const ides = await detectIDEs2();
21954
+ const ides = await detectIDEs();
21958
21955
  if (options.ideId) {
21959
21956
  targetIde = ides.find((i) => i.id === options.ideId && i.installed);
21960
21957
  if (!targetIde) {
@@ -22384,7 +22381,7 @@ var require_dist = __commonJS({
22384
22381
  }
22385
22382
  // ─── IDE detection ───
22386
22383
  case "detect_ides": {
22387
- this.deps.detectedIdes.value = await detectIDEs2();
22384
+ this.deps.detectedIdes.value = await detectIDEs();
22388
22385
  return { success: true, ides: this.deps.detectedIdes.value };
22389
22386
  }
22390
22387
  // ─── Machine Settings ───
@@ -22516,7 +22513,7 @@ var require_dist = __commonJS({
22516
22513
  const acpStates = allStates.filter((s) => s.category === "acp");
22517
22514
  const ideSummary = ideStates.map((s) => {
22518
22515
  const msgs = s.activeChat?.messages?.length || 0;
22519
- const exts = (s.extensions || []).length;
22516
+ const exts = s.extensions.length;
22520
22517
  return `${s.type}(${s.status},${msgs}msg,${exts}ext${s.currentModel ? ",model=" + s.currentModel : ""})`;
22521
22518
  }).join(", ");
22522
22519
  const cliSummary = cliStates.map((s) => `${s.type}(${s.status})`).join(", ");
@@ -22536,13 +22533,12 @@ var require_dist = __commonJS({
22536
22533
  ideType: s.type,
22537
22534
  ideVersion: "",
22538
22535
  instanceId: s.instanceId,
22539
- workspaceFolders: s.workspaceFolders || [],
22540
- activeFile: s.activeFile || null,
22536
+ workspace: s.workspace || null,
22541
22537
  terminals: 0,
22542
22538
  aiAgents: [],
22543
22539
  activeChat: s.activeChat,
22544
22540
  chats: [],
22545
- agentStreams: (s.extensions || []).map((ext) => ({
22541
+ agentStreams: s.extensions.map((ext) => ({
22546
22542
  agentType: ext.type,
22547
22543
  agentName: ext.name,
22548
22544
  extensionId: ext.type,
@@ -22551,7 +22547,7 @@ var require_dist = __commonJS({
22551
22547
  inputContent: ext.activeChat?.inputContent || "",
22552
22548
  activeModal: ext.activeChat?.activeModal || null
22553
22549
  })),
22554
- cdpConnected: s.cdpConnected || false,
22550
+ cdpConnected: s.cdpConnected,
22555
22551
  currentModel: s.currentModel,
22556
22552
  currentPlan: s.currentPlan,
22557
22553
  currentAutoApprove: s.currentAutoApprove
@@ -22562,8 +22558,8 @@ var require_dist = __commonJS({
22562
22558
  cliType: s.type,
22563
22559
  cliName: s.name,
22564
22560
  status: s.status,
22565
- mode: s.mode || "terminal",
22566
- workingDir: s.workingDir || "",
22561
+ mode: s.mode,
22562
+ workspace: s.workspace || "",
22567
22563
  activeChat: s.activeChat
22568
22564
  }));
22569
22565
  const managedAcps = acpStates.map((s) => ({
@@ -22571,19 +22567,22 @@ var require_dist = __commonJS({
22571
22567
  acpType: s.type,
22572
22568
  acpName: s.name,
22573
22569
  status: s.status,
22574
- mode: "chat",
22575
- workingDir: s.workingDir || "",
22570
+ mode: s.mode,
22571
+ workspace: s.workspace || "",
22576
22572
  activeChat: s.activeChat,
22577
22573
  currentModel: s.currentModel,
22578
22574
  currentPlan: s.currentPlan,
22579
22575
  acpConfigOptions: s.acpConfigOptions,
22580
- acpModes: s.acpModes
22576
+ acpModes: s.acpModes,
22577
+ errorMessage: s.errorMessage,
22578
+ errorReason: s.errorReason
22581
22579
  }));
22582
22580
  const cfg = loadConfig3();
22583
22581
  const wsState = getWorkspaceState(cfg);
22584
22582
  const memSnap = getHostMemorySnapshot();
22585
22583
  const payload = {
22586
22584
  daemonMode: true,
22585
+ version: this.deps.daemonVersion || "unknown",
22587
22586
  machineNickname: cfg.machineNickname || null,
22588
22587
  workspaces: wsState.workspaces,
22589
22588
  defaultWorkspaceId: wsState.defaultWorkspaceId,
@@ -22786,12 +22785,14 @@ var require_dist = __commonJS({
22786
22785
  /Type your message/i,
22787
22786
  /^>\s*$/m,
22788
22787
  // '>' alone on its own line
22789
- /[›➤]\s*$/,
22790
- /for shortcuts/i,
22791
- /\?\s*for help/i,
22788
+ /[›❯]\s*[\r\n]/,
22789
+ // prompt char followed by line ending (ANSI-stripped may not have $ at end)
22790
+ /[›❯]\s*$/m,
22791
+ // prompt char at end of line (multiline)
22792
+ /for\s*shortcuts/i,
22793
+ // Claude Code prompt (ANSI strip may remove spaces → 'forshortcuts')
22794
+ /\?\s*for\s*help/i,
22792
22795
  /Press enter/i
22793
- // NOTE: removed /^[\s\u2500-\u257f]*>\s*$/m — the box-drawing char range is too wide and
22794
- // can match dialog-clearing ANSI output, causing false prompt detection in approval state.
22795
22796
  ];
22796
22797
  var FALLBACK_GENERATING = [
22797
22798
  /[\u2800-\u28ff]/,
@@ -22803,13 +22804,18 @@ var require_dist = __commonJS({
22803
22804
  // Specific Claude Code status
22804
22805
  ];
22805
22806
  var FALLBACK_APPROVAL = [
22806
- /Allow\s+once/i,
22807
- /Always\s+allow/i,
22807
+ /Allow\s*once/i,
22808
+ // ANSI strip may remove spaces
22809
+ /Always\s*allow/i,
22808
22810
  /\(y\/n\)/i,
22809
22811
  /\[Y\/n\]/i,
22810
- /Run\s+this\s+command/i
22811
- // NOTE: removed /Do you want to (?:run|execute|allow)/i — too broad, matches AI explanation
22812
- // text like "Do you want to allow this feature?" causing false approval notifications.
22812
+ /Run\s*this\s*command/i,
22813
+ /Allow\s*tool/i,
22814
+ // Claude Code v2 approval
22815
+ /Yes,?\s*don'?t\s*ask/i,
22816
+ // "Yes, don't ask again" (Claude Code)
22817
+ /Deny/i
22818
+ // Deny button presence = approval dialog
22813
22819
  ];
22814
22820
  function defaultCleanOutput(raw, _lastUserInput) {
22815
22821
  return stripAnsi(raw).trim();
@@ -22844,6 +22850,8 @@ var require_dist = __commonJS({
22844
22850
  maxResponse: t.maxResponse ?? 3e5,
22845
22851
  shutdownGrace: t.shutdownGrace ?? 1e3
22846
22852
  };
22853
+ const rawKeys = provider.approvalKeys;
22854
+ this.approvalKeys = rawKeys && typeof rawKeys === "object" ? rawKeys : {};
22847
22855
  }
22848
22856
  cliType;
22849
22857
  cliName;
@@ -22875,8 +22883,20 @@ var require_dist = __commonJS({
22875
22883
  approvalExitTimeout = null;
22876
22884
  // Resize redraw suppression
22877
22885
  resizeSuppressUntil = 0;
22886
+ // Debug: status transition history
22887
+ statusHistory = [];
22888
+ setStatus(status, trigger) {
22889
+ const prev = this.currentStatus;
22890
+ if (prev === status) return;
22891
+ this.currentStatus = status;
22892
+ this.statusHistory.push({ status, at: Date.now(), trigger });
22893
+ if (this.statusHistory.length > 50) this.statusHistory.shift();
22894
+ LOG5.info("CLI", `[${this.cliType}] status: ${prev} \u2192 ${status}${trigger ? ` (${trigger})` : ""}`);
22895
+ }
22878
22896
  // Resolved timeouts (provider defaults + overrides)
22879
22897
  timeouts;
22898
+ // Provider approval key mapping (e.g. { 0: '1', 1: '2', 2: '3' }) — loaded from provider.json
22899
+ approvalKeys;
22880
22900
  // ─── Lifecycle ─────────────────────────────────
22881
22901
  setServerConn(serverConn) {
22882
22902
  this.serverConn = serverConn;
@@ -22956,11 +22976,11 @@ var require_dist = __commonJS({
22956
22976
  this.ptyProcess.onExit(({ exitCode }) => {
22957
22977
  LOG5.info("CLI", `[${this.cliType}] Exit code ${exitCode}`);
22958
22978
  this.ptyProcess = null;
22959
- this.currentStatus = "stopped";
22979
+ this.setStatus("stopped", "pty_exit");
22960
22980
  this.ready = false;
22961
22981
  this.onStatusChange?.();
22962
22982
  });
22963
- this.currentStatus = "starting";
22983
+ this.setStatus("starting", "spawn");
22964
22984
  this.onStatusChange?.();
22965
22985
  }
22966
22986
  // ─── Output state machine ────────────────────────────
@@ -22978,9 +22998,13 @@ var require_dist = __commonJS({
22978
22998
  this.recentOutputBuffer = (this.recentOutputBuffer + cleanData).slice(-1e3);
22979
22999
  if (!this.ready) {
22980
23000
  this.startupBuffer += cleanData;
23001
+ LOG5.info("CLI", `[${this.cliType}] startup chunk (${cleanData.length} chars): ${cleanData.slice(0, 200).replace(/\n/g, "\\n")}`);
22981
23002
  const dialogPatterns = [
22982
23003
  /Do you want to connect/i,
22983
- /Do you trust the files/i
23004
+ /Do you trust the files/i,
23005
+ /Quick safety check/i,
23006
+ /Is this a project/i,
23007
+ /Enter to confirm/i
22984
23008
  ];
22985
23009
  if (dialogPatterns.some((p) => p.test(this.startupBuffer))) {
22986
23010
  setTimeout(() => this.ptyProcess?.write("\r"), this.timeouts.dialogAccept);
@@ -22989,7 +23013,7 @@ var require_dist = __commonJS({
22989
23013
  }
22990
23014
  if (patterns.prompt.some((p) => p.test(this.startupBuffer))) {
22991
23015
  this.ready = true;
22992
- this.currentStatus = "idle";
23016
+ this.setStatus("idle", "prompt_matched");
22993
23017
  LOG5.info("CLI", `[${this.cliType}] \u2713 Ready`);
22994
23018
  this.onStatusChange?.();
22995
23019
  }
@@ -23000,12 +23024,12 @@ var require_dist = __commonJS({
23000
23024
  if (this.lastApprovalResolvedAt && Date.now() - this.lastApprovalResolvedAt < this.timeouts.approvalCooldown) return;
23001
23025
  const ctxLines = this.recentOutputBuffer.split("\n").map((l) => l.trim()).filter((l) => l && !/^[─═╭╮╰╯│]+$/.test(l));
23002
23026
  this.isWaitingForResponse = true;
23003
- this.currentStatus = "waiting_approval";
23027
+ this.setStatus("waiting_approval", "approval_pattern");
23004
23028
  this.recentOutputBuffer = "";
23005
23029
  this.approvalTransitionBuffer = "";
23006
23030
  this.activeModal = {
23007
23031
  message: ctxLines.slice(-5).join(" ").slice(0, 200) || "Approval required",
23008
- buttons: ["Allow once", "Always allow", "Deny"]
23032
+ buttons: this.cliType === "claude-cli" ? ["Yes (y)", "Always allow (a)", "Deny (Esc)"] : ["Allow once", "Always allow", "Deny"]
23009
23033
  };
23010
23034
  if (this.idleTimeout) clearTimeout(this.idleTimeout);
23011
23035
  if (this.approvalExitTimeout) clearTimeout(this.approvalExitTimeout);
@@ -23017,7 +23041,7 @@ var require_dist = __commonJS({
23017
23041
  this.recentOutputBuffer = "";
23018
23042
  this.approvalTransitionBuffer = "";
23019
23043
  this.approvalExitTimeout = null;
23020
- this.currentStatus = this.isWaitingForResponse ? "generating" : "idle";
23044
+ this.setStatus(this.isWaitingForResponse ? "generating" : "idle", "approval_cleared");
23021
23045
  this.onStatusChange?.();
23022
23046
  }
23023
23047
  }, 6e4);
@@ -23033,7 +23057,7 @@ var require_dist = __commonJS({
23033
23057
  clearTimeout(this.approvalExitTimeout);
23034
23058
  this.approvalExitTimeout = null;
23035
23059
  }
23036
- this.currentStatus = "generating";
23060
+ this.setStatus("generating", "approval_gen_resume");
23037
23061
  this.activeModal = null;
23038
23062
  this.recentOutputBuffer = "";
23039
23063
  this.approvalTransitionBuffer = "";
@@ -23056,7 +23080,7 @@ var require_dist = __commonJS({
23056
23080
  if (patterns.generating.some((p) => p.test(cleanData))) {
23057
23081
  this.isWaitingForResponse = true;
23058
23082
  this.responseBuffer = "";
23059
- this.currentStatus = "generating";
23083
+ this.setStatus("generating", "autonomous_gen");
23060
23084
  this.onStatusChange?.();
23061
23085
  }
23062
23086
  }
@@ -23065,7 +23089,7 @@ var require_dist = __commonJS({
23065
23089
  if (this.idleTimeout) clearTimeout(this.idleTimeout);
23066
23090
  const stillGenerating = patterns.generating.some((p) => p.test(cleanData));
23067
23091
  if (stillGenerating) {
23068
- this.currentStatus = "generating";
23092
+ this.setStatus("generating", "still_generating");
23069
23093
  this.idleTimeout = setTimeout(() => {
23070
23094
  if (this.isWaitingForResponse) this.finishResponse();
23071
23095
  }, this.timeouts.generatingIdle);
@@ -23112,7 +23136,7 @@ var require_dist = __commonJS({
23112
23136
  this.responseBuffer = "";
23113
23137
  this.isWaitingForResponse = false;
23114
23138
  this.activeModal = null;
23115
- this.currentStatus = "idle";
23139
+ this.setStatus("idle", "response_finished");
23116
23140
  this.onStatusChange?.();
23117
23141
  }
23118
23142
  // ─── Public API (CliAdapter interface) ──────────
@@ -23131,7 +23155,7 @@ var require_dist = __commonJS({
23131
23155
  this.messages.push({ role: "user", content: text, timestamp: Date.now() });
23132
23156
  this.isWaitingForResponse = true;
23133
23157
  this.responseBuffer = "";
23134
- this.currentStatus = "generating";
23158
+ this.setStatus("generating", "sendMessage");
23135
23159
  this.onStatusChange?.();
23136
23160
  this.ptyProcess.write(text + "\r");
23137
23161
  this.responseTimeout = setTimeout(() => {
@@ -23159,7 +23183,7 @@ var require_dist = __commonJS({
23159
23183
  } catch {
23160
23184
  }
23161
23185
  this.ptyProcess = null;
23162
- this.currentStatus = "stopped";
23186
+ this.setStatus("stopped", "stop_cmd");
23163
23187
  this.ready = false;
23164
23188
  this.onStatusChange?.();
23165
23189
  }, this.timeouts.shutdownGrace);
@@ -23185,9 +23209,13 @@ var require_dist = __commonJS({
23185
23209
  */
23186
23210
  resolveModal(buttonIndex) {
23187
23211
  if (!this.ptyProcess || this.currentStatus !== "waiting_approval") return;
23188
- const DOWN = "\x1B[B";
23189
- const keys = DOWN.repeat(Math.max(0, buttonIndex)) + "\r";
23190
- this.ptyProcess.write(keys);
23212
+ if (buttonIndex in this.approvalKeys) {
23213
+ this.ptyProcess.write(this.approvalKeys[buttonIndex]);
23214
+ } else {
23215
+ const DOWN = "\x1B[B";
23216
+ const keys = DOWN.repeat(Math.max(0, buttonIndex)) + "\r";
23217
+ this.ptyProcess.write(keys);
23218
+ }
23191
23219
  }
23192
23220
  resize(cols, rows) {
23193
23221
  if (this.ptyProcess) {
@@ -23198,6 +23226,44 @@ var require_dist = __commonJS({
23198
23226
  }
23199
23227
  }
23200
23228
  }
23229
+ /**
23230
+ * Full debug state — exposes all internal buffers, status, and patterns for debugging.
23231
+ * Used by DevServer /api/cli/debug endpoint.
23232
+ */
23233
+ getDebugState() {
23234
+ return {
23235
+ type: this.cliType,
23236
+ name: this.cliName,
23237
+ status: this.currentStatus,
23238
+ ready: this.ready,
23239
+ workingDir: this.workingDir,
23240
+ messages: this.messages.slice(-20),
23241
+ messageCount: this.messages.length,
23242
+ // Buffers
23243
+ startupBuffer: this.startupBuffer.slice(-500),
23244
+ recentOutputBuffer: this.recentOutputBuffer.slice(-500),
23245
+ responseBuffer: this.responseBuffer.slice(-500),
23246
+ approvalTransitionBuffer: this.approvalTransitionBuffer.slice(-500),
23247
+ // State
23248
+ isWaitingForResponse: this.isWaitingForResponse,
23249
+ activeModal: this.activeModal,
23250
+ lastApprovalResolvedAt: this.lastApprovalResolvedAt,
23251
+ resizeSuppressUntil: this.resizeSuppressUntil,
23252
+ // Provider patterns (serialized)
23253
+ patterns: {
23254
+ prompt: this.provider.patterns.prompt.map((p) => p.toString()),
23255
+ generating: this.provider.patterns.generating.map((p) => p.toString()),
23256
+ approval: this.provider.patterns.approval.map((p) => p.toString()),
23257
+ ready: this.provider.patterns.ready.map((p) => p.toString())
23258
+ },
23259
+ // Status history
23260
+ statusHistory: this.statusHistory.slice(-30),
23261
+ // Timeouts config
23262
+ timeouts: this.timeouts,
23263
+ // PTY alive
23264
+ ptyAlive: !!this.ptyProcess
23265
+ };
23266
+ }
23201
23267
  };
23202
23268
  init_config();
23203
23269
  init_workspaces();
@@ -23222,6 +23288,8 @@ var require_dist = __commonJS({
23222
23288
  generatingStartedAt = 0;
23223
23289
  settings = {};
23224
23290
  monitor;
23291
+ generatingDebounceTimer = null;
23292
+ generatingDebouncePending = null;
23225
23293
  historyWriter;
23226
23294
  instanceId;
23227
23295
  // ─── Lifecycle ─────────────────────────────────
@@ -23288,7 +23356,7 @@ var require_dist = __commonJS({
23288
23356
  activeModal: adapterStatus.activeModal,
23289
23357
  inputContent: ""
23290
23358
  },
23291
- workingDir: this.workingDir,
23359
+ workspace: this.workingDir,
23292
23360
  instanceId: this.instanceId,
23293
23361
  lastUpdated: Date.now(),
23294
23362
  settings: this.settings,
@@ -23317,8 +23385,24 @@ var require_dist = __commonJS({
23317
23385
  LOG5.info("CLI", `[${this.type}] status: ${this.lastStatus} \u2192 ${newStatus}`);
23318
23386
  if (this.lastStatus === "idle" && newStatus === "generating") {
23319
23387
  this.generatingStartedAt = now;
23320
- this.pushEvent({ event: "agent:generating_started", chatTitle, timestamp: now });
23388
+ if (this.generatingDebounceTimer) clearTimeout(this.generatingDebounceTimer);
23389
+ this.generatingDebouncePending = { chatTitle, timestamp: now };
23390
+ this.generatingDebounceTimer = setTimeout(() => {
23391
+ if (this.generatingDebouncePending) {
23392
+ this.pushEvent({ event: "agent:generating_started", ...this.generatingDebouncePending });
23393
+ this.generatingDebouncePending = null;
23394
+ }
23395
+ this.generatingDebounceTimer = null;
23396
+ }, 1e3);
23321
23397
  } else if (newStatus === "waiting_approval") {
23398
+ if (this.generatingDebouncePending) {
23399
+ if (this.generatingDebounceTimer) {
23400
+ clearTimeout(this.generatingDebounceTimer);
23401
+ this.generatingDebounceTimer = null;
23402
+ }
23403
+ this.pushEvent({ event: "agent:generating_started", ...this.generatingDebouncePending });
23404
+ this.generatingDebouncePending = null;
23405
+ }
23322
23406
  if (!this.generatingStartedAt) this.generatingStartedAt = now;
23323
23407
  const modal = adapterStatus.activeModal;
23324
23408
  LOG5.info("CLI", `[${this.type}] approval modal: "${modal?.message?.slice(0, 80) ?? "none"}"`);
@@ -23331,10 +23415,24 @@ var require_dist = __commonJS({
23331
23415
  });
23332
23416
  } else if (newStatus === "idle" && (this.lastStatus === "generating" || this.lastStatus === "waiting_approval")) {
23333
23417
  const duration3 = this.generatingStartedAt ? Math.round((now - this.generatingStartedAt) / 1e3) : 0;
23334
- LOG5.info("CLI", `[${this.type}] completed in ${duration3}s`);
23335
- this.pushEvent({ event: "agent:generating_completed", chatTitle, duration: duration3, timestamp: now });
23418
+ if (this.generatingDebouncePending) {
23419
+ LOG5.info("CLI", `[${this.type}] suppressed short generating (${now - this.generatingStartedAt}ms)`);
23420
+ if (this.generatingDebounceTimer) {
23421
+ clearTimeout(this.generatingDebounceTimer);
23422
+ this.generatingDebounceTimer = null;
23423
+ }
23424
+ this.generatingDebouncePending = null;
23425
+ } else {
23426
+ LOG5.info("CLI", `[${this.type}] completed in ${duration3}s`);
23427
+ this.pushEvent({ event: "agent:generating_completed", chatTitle, duration: duration3, timestamp: now });
23428
+ }
23336
23429
  this.generatingStartedAt = 0;
23337
23430
  } else if (newStatus === "stopped") {
23431
+ if (this.generatingDebounceTimer) {
23432
+ clearTimeout(this.generatingDebounceTimer);
23433
+ this.generatingDebounceTimer = null;
23434
+ }
23435
+ this.generatingDebouncePending = null;
23338
23436
  this.pushEvent({ event: "agent:stopped", chatTitle, timestamp: now });
23339
23437
  }
23340
23438
  this.lastStatus = newStatus;
@@ -23479,7 +23577,7 @@ var require_dist = __commonJS({
23479
23577
  } : null,
23480
23578
  inputContent: ""
23481
23579
  },
23482
- workingDir: this.workingDir,
23580
+ workspace: this.workingDir,
23483
23581
  currentModel: this.currentModel,
23484
23582
  currentPlan: this.currentMode,
23485
23583
  instanceId: this.instanceId,
@@ -23490,8 +23588,8 @@ var require_dist = __commonJS({
23490
23588
  acpConfigOptions: this.configOptions,
23491
23589
  acpModes: this.availableModes,
23492
23590
  // Error details for dashboard display
23493
- errorMessage: this.errorMessage,
23494
- errorReason: this.errorReason
23591
+ errorMessage: this.errorMessage || void 0,
23592
+ errorReason: this.errorReason || void 0
23495
23593
  };
23496
23594
  }
23497
23595
  onEvent(event, data) {
@@ -23974,29 +24072,27 @@ var require_dist = __commonJS({
23974
24072
  handleSessionUpdate(params) {
23975
24073
  if (!params) return;
23976
24074
  const update = params.update;
23977
- this.log.debug(`[${this.type}] sessionUpdate: ${update.sessionUpdate} | keys=${Object.keys(update).join(",")}`);
24075
+ this.log.debug(`[${this.type}] sessionUpdate: ${update.sessionUpdate}`);
23978
24076
  switch (update.sessionUpdate) {
23979
24077
  case "agent_message_chunk": {
23980
24078
  const content = update.content;
23981
- if (content?.type === "text" && content.text) {
24079
+ if (content.type === "text") {
23982
24080
  this.partialContent += content.text;
23983
- } else if (content?.type === "image") {
24081
+ } else if (content.type === "image") {
23984
24082
  this.partialBlocks.push({
23985
24083
  type: "image",
23986
- data: content.data || "",
23987
- mimeType: content.mimeType || "image/png",
23988
- uri: content.uri
24084
+ data: content.data,
24085
+ mimeType: content.mimeType
23989
24086
  });
23990
- } else if (content?.type === "resource_link") {
24087
+ } else if (content.type === "resource_link") {
23991
24088
  this.partialBlocks.push({
23992
24089
  type: "resource_link",
23993
- uri: content.uri || "",
24090
+ uri: content.uri,
23994
24091
  name: content.name || "resource",
23995
- title: content.title,
23996
- mimeType: content.mimeType,
23997
- size: content.size
24092
+ title: content.title ?? void 0,
24093
+ mimeType: content.mimeType ?? void 0
23998
24094
  });
23999
- } else if (content?.type === "resource") {
24095
+ } else if (content.type === "resource") {
24000
24096
  this.partialBlocks.push({
24001
24097
  type: "resource",
24002
24098
  resource: content.resource
@@ -25709,6 +25805,8 @@ async (params) => {
25709
25805
  server = null;
25710
25806
  providerLoader;
25711
25807
  cdpManagers;
25808
+ instanceManager;
25809
+ cliManager;
25712
25810
  logFn;
25713
25811
  sseClients = [];
25714
25812
  watchScriptPath = null;
@@ -25718,9 +25816,13 @@ async (params) => {
25718
25816
  autoImplProcess = null;
25719
25817
  autoImplSSEClients = [];
25720
25818
  autoImplStatus = { running: false, type: null, progress: [] };
25819
+ // CLI debug SSE
25820
+ cliSSEClients = [];
25721
25821
  constructor(options) {
25722
25822
  this.providerLoader = options.providerLoader;
25723
25823
  this.cdpManagers = options.cdpManagers;
25824
+ this.instanceManager = options.instanceManager || null;
25825
+ this.cliManager = options.cliManager || null;
25724
25826
  this.logFn = options.logFn || LOG5.forComponent("DevServer").asLogFn();
25725
25827
  }
25726
25828
  log(msg) {
@@ -25747,6 +25849,15 @@ async (params) => {
25747
25849
  { method: "POST", pattern: "/api/watch/stop", handler: (q, s) => this.handleWatchStop(q, s) },
25748
25850
  { method: "GET", pattern: "/api/watch/events", handler: (q, s) => this.handleSSE(q, s) },
25749
25851
  { method: "POST", pattern: "/api/scaffold", handler: (q, s) => this.handleScaffold(q, s) },
25852
+ // CLI Debug routes
25853
+ { method: "GET", pattern: "/api/cli/status", handler: (q, s) => this.handleCliStatus(q, s) },
25854
+ { method: "POST", pattern: "/api/cli/launch", handler: (q, s) => this.handleCliLaunch(q, s) },
25855
+ { method: "POST", pattern: "/api/cli/send", handler: (q, s) => this.handleCliSend(q, s) },
25856
+ { method: "POST", pattern: "/api/cli/resolve", handler: (q, s) => this.handleCliResolve(q, s) },
25857
+ { method: "POST", pattern: "/api/cli/raw", handler: (q, s) => this.handleCliRaw(q, s) },
25858
+ { method: "POST", pattern: "/api/cli/stop", handler: (q, s) => this.handleCliStop(q, s) },
25859
+ { method: "GET", pattern: "/api/cli/events", handler: (q, s) => this.handleCliSSE(q, s) },
25860
+ { method: "GET", pattern: /^\/api\/cli\/debug\/([^/]+)$/, handler: (q, s, p) => this.handleCliDebug(p[0], q, s) },
25750
25861
  // Dynamic routes (provider :type param)
25751
25862
  { method: "POST", pattern: /^\/api\/providers\/([^/]+)\/script$/, handler: (q, s, p) => this.handleRunScript(p[0], q, s) },
25752
25863
  { method: "GET", pattern: /^\/api\/providers\/([^/]+)\/files$/, handler: (q, s, p) => this.handleListFiles(p[0], q, s) },
@@ -28013,6 +28124,251 @@ data: ${JSON.stringify(msg.data)}
28013
28124
  });
28014
28125
  });
28015
28126
  }
28127
+ // ─── CLI Debug Handlers ──────────────────────────────
28128
+ /** GET /api/cli/status — list all running CLI/ACP instances with state */
28129
+ async handleCliStatus(_req, res) {
28130
+ if (!this.instanceManager) {
28131
+ this.json(res, 503, { error: "InstanceManager not available (daemon not fully initialized)" });
28132
+ return;
28133
+ }
28134
+ const allStates = this.instanceManager.collectAllStates();
28135
+ const cliStates = allStates.filter((s) => s.category === "cli" || s.category === "acp");
28136
+ const result = cliStates.map((s) => ({
28137
+ instanceId: s.instanceId,
28138
+ type: s.type,
28139
+ name: s.name,
28140
+ category: s.category,
28141
+ status: s.status,
28142
+ mode: s.mode,
28143
+ workspace: s.workspace,
28144
+ messageCount: s.activeChat?.messages?.length || 0,
28145
+ lastMessage: s.activeChat?.messages?.slice(-1)[0] || null,
28146
+ activeModal: s.activeChat?.activeModal || null,
28147
+ pendingEvents: s.pendingEvents || [],
28148
+ currentModel: s.currentModel,
28149
+ settings: s.settings
28150
+ }));
28151
+ this.json(res, 200, { instances: result, count: result.length });
28152
+ }
28153
+ /** POST /api/cli/launch — launch a CLI agent { type, workingDir?, args? } */
28154
+ async handleCliLaunch(req, res) {
28155
+ if (!this.cliManager) {
28156
+ this.json(res, 503, { error: "CliManager not available" });
28157
+ return;
28158
+ }
28159
+ const body = await this.readBody(req);
28160
+ const { type, workingDir, args } = body;
28161
+ if (!type) {
28162
+ this.json(res, 400, { error: "type required (e.g. claude-cli, gemini-cli)" });
28163
+ return;
28164
+ }
28165
+ try {
28166
+ await this.cliManager.startSession(type, workingDir || process.cwd(), args || []);
28167
+ this.json(res, 200, { launched: true, type, workspace: workingDir || process.cwd() });
28168
+ } catch (e) {
28169
+ this.json(res, 500, { error: `Launch failed: ${e.message}` });
28170
+ }
28171
+ }
28172
+ /** POST /api/cli/send — send message to a running CLI { type, text } */
28173
+ async handleCliSend(req, res) {
28174
+ if (!this.instanceManager) {
28175
+ this.json(res, 503, { error: "InstanceManager not available" });
28176
+ return;
28177
+ }
28178
+ const body = await this.readBody(req);
28179
+ const { type, text, instanceId } = body;
28180
+ if (!text) {
28181
+ this.json(res, 400, { error: "text required" });
28182
+ return;
28183
+ }
28184
+ const allStates = this.instanceManager.collectAllStates();
28185
+ const target = allStates.find(
28186
+ (s) => (s.category === "cli" || s.category === "acp") && (instanceId ? s.instanceId === instanceId : s.type === type)
28187
+ );
28188
+ if (!target) {
28189
+ this.json(res, 404, { error: `No running instance found for: ${type || instanceId}` });
28190
+ return;
28191
+ }
28192
+ try {
28193
+ this.instanceManager.sendEvent(target.instanceId, "send_message", { text });
28194
+ this.json(res, 200, { sent: true, type: target.type, instanceId: target.instanceId });
28195
+ } catch (e) {
28196
+ this.json(res, 500, { error: `Send failed: ${e.message}` });
28197
+ }
28198
+ }
28199
+ /** POST /api/cli/stop — stop a running CLI { type } */
28200
+ async handleCliStop(req, res) {
28201
+ if (!this.instanceManager) {
28202
+ this.json(res, 503, { error: "InstanceManager not available" });
28203
+ return;
28204
+ }
28205
+ const body = await this.readBody(req);
28206
+ const { type, instanceId } = body;
28207
+ const allStates = this.instanceManager.collectAllStates();
28208
+ const target = allStates.find(
28209
+ (s) => (s.category === "cli" || s.category === "acp") && (instanceId ? s.instanceId === instanceId : s.type === type)
28210
+ );
28211
+ if (!target) {
28212
+ this.json(res, 404, { error: `No running instance found for: ${type || instanceId}` });
28213
+ return;
28214
+ }
28215
+ try {
28216
+ this.instanceManager.removeInstance(target.instanceId);
28217
+ this.json(res, 200, { stopped: true, type: target.type, instanceId: target.instanceId });
28218
+ } catch (e) {
28219
+ this.json(res, 500, { error: `Stop failed: ${e.message}` });
28220
+ }
28221
+ }
28222
+ /** GET /api/cli/events — SSE stream of CLI status events */
28223
+ handleCliSSE(_req, res) {
28224
+ res.writeHead(200, {
28225
+ "Content-Type": "text/event-stream",
28226
+ "Cache-Control": "no-cache",
28227
+ "Connection": "keep-alive",
28228
+ "Access-Control-Allow-Origin": "*"
28229
+ });
28230
+ res.write('data: {"type":"connected"}\n\n');
28231
+ this.cliSSEClients.push(res);
28232
+ if (this.cliSSEClients.length === 1 && this.instanceManager) {
28233
+ this.instanceManager.onEvent((event) => {
28234
+ this.sendCliSSE(event);
28235
+ });
28236
+ }
28237
+ if (this.instanceManager) {
28238
+ const allStates = this.instanceManager.collectAllStates();
28239
+ const cliStates = allStates.filter((s) => s.category === "cli" || s.category === "acp");
28240
+ for (const s of cliStates) {
28241
+ this.sendCliSSE({ event: "snapshot", providerType: s.type, status: s.status, instanceId: s.instanceId });
28242
+ }
28243
+ }
28244
+ _req.on("close", () => {
28245
+ this.cliSSEClients = this.cliSSEClients.filter((c) => c !== res);
28246
+ });
28247
+ }
28248
+ sendCliSSE(data) {
28249
+ const msg = `data: ${JSON.stringify({ ...data, timestamp: Date.now() })}
28250
+
28251
+ `;
28252
+ for (const client of this.cliSSEClients) {
28253
+ try {
28254
+ client.write(msg);
28255
+ } catch {
28256
+ }
28257
+ }
28258
+ }
28259
+ /** GET /api/cli/debug/:type — full internal debug state of a CLI adapter */
28260
+ async handleCliDebug(type, _req, res) {
28261
+ if (!this.instanceManager) {
28262
+ this.json(res, 503, { error: "InstanceManager not available" });
28263
+ return;
28264
+ }
28265
+ const allStates = this.instanceManager.collectAllStates();
28266
+ const target = allStates.find(
28267
+ (s) => (s.category === "cli" || s.category === "acp") && s.type === type
28268
+ );
28269
+ if (!target) {
28270
+ this.json(res, 404, { error: `No running instance for: ${type}`, available: allStates.filter((s) => s.category === "cli" || s.category === "acp").map((s) => s.type) });
28271
+ return;
28272
+ }
28273
+ const instance = this.instanceManager.getInstance(target.instanceId);
28274
+ if (!instance) {
28275
+ this.json(res, 404, { error: `Instance not found: ${target.instanceId}` });
28276
+ return;
28277
+ }
28278
+ try {
28279
+ const adapter = instance.getAdapter?.() || instance.adapter;
28280
+ if (adapter && typeof adapter.getDebugState === "function") {
28281
+ const debugState = adapter.getDebugState();
28282
+ this.json(res, 200, {
28283
+ instanceId: target.instanceId,
28284
+ providerState: {
28285
+ type: target.type,
28286
+ name: target.name,
28287
+ status: target.status,
28288
+ mode: "mode" in target ? target.mode : void 0
28289
+ },
28290
+ debug: debugState
28291
+ });
28292
+ } else {
28293
+ this.json(res, 200, {
28294
+ instanceId: target.instanceId,
28295
+ providerState: target,
28296
+ debug: null,
28297
+ message: "No debug state available (adapter.getDebugState not found)"
28298
+ });
28299
+ }
28300
+ } catch (e) {
28301
+ this.json(res, 500, { error: `Debug state failed: ${e.message}` });
28302
+ }
28303
+ }
28304
+ /** POST /api/cli/resolve — resolve an approval modal { type, buttonIndex } */
28305
+ async handleCliResolve(req, res) {
28306
+ const body = await this.readBody(req);
28307
+ const { type, buttonIndex, instanceId } = body;
28308
+ if (buttonIndex === void 0 || buttonIndex === null) {
28309
+ this.json(res, 400, { error: "buttonIndex required (0=Yes, 1=Always, 2=Deny)" });
28310
+ return;
28311
+ }
28312
+ if (!this.cliManager) {
28313
+ this.json(res, 503, { error: "CliManager not available" });
28314
+ return;
28315
+ }
28316
+ let adapter = null;
28317
+ for (const [, a] of this.cliManager.adapters) {
28318
+ if (type && a.cliType === type) {
28319
+ adapter = a;
28320
+ break;
28321
+ }
28322
+ }
28323
+ if (!adapter) {
28324
+ this.json(res, 404, { error: `No running adapter for: ${type || instanceId}` });
28325
+ return;
28326
+ }
28327
+ try {
28328
+ if (typeof adapter.resolveModal === "function") {
28329
+ adapter.resolveModal(buttonIndex);
28330
+ this.json(res, 200, { resolved: true, type, buttonIndex });
28331
+ } else {
28332
+ this.json(res, 400, { error: "resolveModal not available on this adapter" });
28333
+ }
28334
+ } catch (e) {
28335
+ this.json(res, 500, { error: `Resolve failed: ${e.message}` });
28336
+ }
28337
+ }
28338
+ /** POST /api/cli/raw — send raw keystrokes to PTY { type, keys } */
28339
+ async handleCliRaw(req, res) {
28340
+ const body = await this.readBody(req);
28341
+ const { type, keys, instanceId } = body;
28342
+ if (!keys) {
28343
+ this.json(res, 400, { error: "keys required (raw string to send to PTY)" });
28344
+ return;
28345
+ }
28346
+ if (!this.cliManager) {
28347
+ this.json(res, 503, { error: "CliManager not available" });
28348
+ return;
28349
+ }
28350
+ let adapter = null;
28351
+ for (const [, a] of this.cliManager.adapters) {
28352
+ if (type && a.cliType === type) {
28353
+ adapter = a;
28354
+ break;
28355
+ }
28356
+ }
28357
+ if (!adapter) {
28358
+ this.json(res, 404, { error: `No running adapter for: ${type || instanceId}` });
28359
+ return;
28360
+ }
28361
+ try {
28362
+ if (typeof adapter.writeRaw === "function") {
28363
+ adapter.writeRaw(keys);
28364
+ this.json(res, 200, { sent: true, type, keysLength: keys.length });
28365
+ } else {
28366
+ this.json(res, 400, { error: "writeRaw not available on this adapter" });
28367
+ }
28368
+ } catch (e) {
28369
+ this.json(res, 500, { error: `Raw send failed: ${e.message}` });
28370
+ }
28371
+ }
28016
28372
  };
28017
28373
  var import_child_process8 = require("child_process");
28018
28374
  var EXTENSION_CATALOG = [
@@ -28168,7 +28524,7 @@ data: ${JSON.stringify(msg.data)}
28168
28524
  });
28169
28525
  });
28170
28526
  }
28171
- async function installExtensions2(ide, extensions, onProgress) {
28527
+ async function installExtensions(ide, extensions, onProgress) {
28172
28528
  const results = [];
28173
28529
  for (let i = 0; i < extensions.length; i++) {
28174
28530
  const ext = extensions[i];
@@ -28178,10 +28534,10 @@ data: ${JSON.stringify(msg.data)}
28178
28534
  }
28179
28535
  return results;
28180
28536
  }
28181
- function getAIExtensions2() {
28537
+ function getAIExtensions() {
28182
28538
  return EXTENSION_CATALOG.filter((e) => e.category === "ai-agent");
28183
28539
  }
28184
- function launchIDE2(ide, workspacePath) {
28540
+ function launchIDE(ide, workspacePath) {
28185
28541
  if (!ide.cliCommand) return false;
28186
28542
  try {
28187
28543
  const args = workspacePath ? `"${workspacePath}"` : "";
@@ -28194,7 +28550,7 @@ data: ${JSON.stringify(msg.data)}
28194
28550
  init_config();
28195
28551
  async function initDaemonComponents2(config2) {
28196
28552
  installGlobalInterceptor();
28197
- const providerLoader = new ProviderLoader2({
28553
+ const providerLoader = new ProviderLoader({
28198
28554
  logFn: config2.providerLogFn
28199
28555
  });
28200
28556
  providerLoader.loadAll();
@@ -28208,7 +28564,7 @@ data: ${JSON.stringify(msg.data)}
28208
28564
  getInstanceManager: () => instanceManager
28209
28565
  }, providerLoader);
28210
28566
  LOG5.info("Init", "Detecting IDEs...");
28211
- detectedIdesRef.value = await detectIDEs2();
28567
+ detectedIdesRef.value = await detectIDEs();
28212
28568
  const installed = detectedIdesRef.value.filter((i) => i.installed);
28213
28569
  LOG5.info("Init", `Found ${installed.length} IDE(s): ${installed.map((i) => i.id).join(", ") || "none"}`);
28214
28570
  const cdpSetupContext = {
@@ -28357,7 +28713,8 @@ var init_server_connection = __esm({
28357
28713
  this.ws = new import_ws.default(fullUrl, {
28358
28714
  headers: {
28359
28715
  "X-ADHDev-Token": this.options.token,
28360
- "X-ADHDev-IDE": JSON.stringify(this.options.cliInfo)
28716
+ "X-ADHDev-IDE": JSON.stringify(this.options.cliInfo),
28717
+ "X-ADHDev-Version": this.options.daemonVersion || "unknown"
28361
28718
  }
28362
28719
  });
28363
28720
  this.ws.on("open", () => this.onOpen());
@@ -28455,6 +28812,19 @@ var init_server_connection = __esm({
28455
28812
  import_daemon_core.LOG.error("Server", `Auth failed: ${message.payload.reason}`);
28456
28813
  this.setState("error");
28457
28814
  return;
28815
+ } else if (message.type === "version_mismatch") {
28816
+ const p = message.payload;
28817
+ import_daemon_core.LOG.info("Server", `
28818
+ \u{1F504} Update available: v${p.current} \u2192 v${p.latest}`);
28819
+ import_daemon_core.LOG.info("Server", ` Run: adhdev daemon:upgrade
28820
+ `);
28821
+ } else if (message.type === "force_update_required") {
28822
+ const p = message.payload;
28823
+ import_daemon_core.LOG.error("Server", `
28824
+ \u26D4 Daemon v${this.options.daemonVersion} is no longer compatible.`);
28825
+ import_daemon_core.LOG.error("Server", ` Minimum required: v${p.minVersion}`);
28826
+ import_daemon_core.LOG.error("Server", ` Run: adhdev daemon:upgrade
28827
+ `);
28458
28828
  }
28459
28829
  const handlers = this.messageHandlers.get(message.type);
28460
28830
  if (handlers) {
@@ -29631,6 +30001,7 @@ var init_adhdev_daemon = __esm({
29631
30001
  this.serverConn = new ServerConnection({
29632
30002
  serverUrl: options.serverUrl || config2.serverUrl,
29633
30003
  token: config2.connectionToken,
30004
+ daemonVersion: pkgVersion,
29634
30005
  cliInfo: {
29635
30006
  type: "adhdev-daemon",
29636
30007
  version: pkgVersion,
@@ -29716,6 +30087,7 @@ var init_adhdev_daemon = __esm({
29716
30087
  adapters: this.components.cliManager.adapters,
29717
30088
  detectedIdes: this.components.detectedIdes.value,
29718
30089
  ideType: this.ideType,
30090
+ daemonVersion: pkgVersion,
29719
30091
  instanceManager: this.components.instanceManager
29720
30092
  });
29721
30093
  this.statusReporter.startReporting();
@@ -29726,7 +30098,12 @@ var init_adhdev_daemon = __esm({
29726
30098
  process.on("SIGINT", () => this.stop());
29727
30099
  process.on("SIGTERM", () => this.stop());
29728
30100
  if (options.dev) {
29729
- const devServer = new import_daemon_core4.DevServer({ providerLoader: this.components.providerLoader, cdpManagers: this.components.cdpManagers });
30101
+ const devServer = new import_daemon_core4.DevServer({
30102
+ providerLoader: this.components.providerLoader,
30103
+ cdpManagers: this.components.cdpManagers,
30104
+ instanceManager: this.components.instanceManager,
30105
+ cliManager: this.components.cliManager
30106
+ });
29730
30107
  await devServer.start();
29731
30108
  }
29732
30109
  this.printBanner(options, config2.serverUrl);
@@ -30008,18 +30385,11 @@ ${import_chalk2.default.cyan("\u255A\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u
30008
30385
  `;
30009
30386
  var DIVIDER = import_chalk2.default.gray("\u2500".repeat(44));
30010
30387
  async function runWizard(options = {}) {
30011
- const loader = new import_daemon_core5.ProviderLoader({ logFn: () => {
30012
- } });
30013
- loader.loadAll();
30014
- loader.registerToDetector();
30015
30388
  console.log(LOGO);
30016
30389
  if ((0, import_daemon_core5.isSetupComplete)() && !options.force) {
30017
30390
  const config2 = (0, import_daemon_core5.loadConfig)();
30018
30391
  console.log(import_chalk2.default.green("\u2713") + " ADHDev is already set up!");
30019
- const ides = config2.configuredIdes?.length ? config2.configuredIdes.join(", ") : config2.selectedIde || "none";
30020
- console.log(import_chalk2.default.gray(` IDEs: ${ides}`));
30021
30392
  console.log(import_chalk2.default.gray(` User: ${config2.userEmail || "not logged in"}`));
30022
- console.log(import_chalk2.default.gray(` Extensions: ${config2.installedExtensions.length} installed`));
30023
30393
  console.log();
30024
30394
  const { action } = await import_inquirer.default.prompt([
30025
30395
  {
@@ -30057,78 +30427,15 @@ async function runWizard(options = {}) {
30057
30427
  return;
30058
30428
  }
30059
30429
  }
30060
- const { mode } = await import_inquirer.default.prompt([
30061
- {
30062
- type: "list",
30063
- name: "mode",
30064
- message: "Setup mode:",
30065
- choices: [
30066
- { name: `\u{1F680} ${import_chalk2.default.bold("Quick Setup")} \u2014 Auto-detect IDEs, login ${import_chalk2.default.gray("(recommended)")}`, value: "quick" },
30067
- { name: `\u2699\uFE0F ${import_chalk2.default.bold("Custom Setup")} \u2014 Choose IDE, AI extensions, and more`, value: "custom" },
30068
- { name: `\u{1F527} ${import_chalk2.default.bold("CLI Only")} \u2014 Install adhdev command globally`, value: "cli-only" }
30069
- ]
30070
- }
30071
- ]);
30072
- if (mode === "quick") {
30073
- await quickSetup();
30074
- } else if (mode === "cli-only") {
30075
- await installCliOnly();
30076
- } else {
30077
- await customSetup();
30078
- }
30430
+ await quickSetup();
30079
30431
  }
30080
30432
  async function quickSetup() {
30081
30433
  console.log(import_chalk2.default.bold("\n\u{1F680} Quick Setup\n"));
30082
- const spinner = (0, import_ora.default)("Detecting installed IDEs...").start();
30083
- const ides = await (0, import_daemon_core5.detectIDEs)();
30084
- const installedIDEs = ides.filter((i) => i.installed && i.cliCommand);
30085
- spinner.stop();
30086
- if (installedIDEs.length === 0) {
30087
- console.log(import_chalk2.default.red("\u2717 No supported IDE with CLI found."));
30088
- console.log(import_chalk2.default.gray(" Supported: VS Code, Cursor, Antigravity, Windsurf, VSCodium"));
30089
- return;
30090
- }
30091
- console.log(import_chalk2.default.green(`Found ${installedIDEs.length} IDE(s):
30092
- `));
30093
- installedIDEs.forEach((ide) => {
30094
- const version2 = ide.version ? import_chalk2.default.gray(` v${ide.version}`) : "";
30095
- console.log(` ${import_chalk2.default.green("\u2713")} ${ide.icon} ${import_chalk2.default.bold(ide.displayName)}${version2}`);
30096
- });
30097
- console.log();
30098
- let selectedIDEs;
30099
- if (installedIDEs.length === 1) {
30100
- selectedIDEs = installedIDEs;
30101
- console.log(import_chalk2.default.gray(` Auto-selected: ${installedIDEs[0].displayName}
30102
- `));
30103
- } else {
30104
- const { selectedIdeIds } = await import_inquirer.default.prompt([
30105
- {
30106
- type: "checkbox",
30107
- name: "selectedIdeIds",
30108
- message: "Select IDEs to set up (Space to toggle, Enter to confirm):",
30109
- choices: installedIDEs.map((ide) => ({
30110
- name: `${ide.icon} ${ide.displayName}${ide.version ? import_chalk2.default.gray(` v${ide.version}`) : ""}`,
30111
- value: ide.id,
30112
- checked: true
30113
- // All selected by default
30114
- })),
30115
- validate: (input) => input.length > 0 ? true : "Select at least one IDE"
30116
- }
30117
- ]);
30118
- selectedIDEs = installedIDEs.filter((i) => selectedIdeIds.includes(i.id));
30119
- }
30120
- console.log(DIVIDER);
30121
30434
  const loginResult = await loginFlow();
30122
30435
  if (!loginResult) {
30123
30436
  console.log(import_chalk2.default.yellow("\u26A0 Setup completed without login. You can login later with `adhdev setup`."));
30124
30437
  }
30125
- if (loginResult?.connectionToken) {
30126
- for (const ide of selectedIDEs) {
30127
- await injectTokenToIDE(ide, loginResult.connectionToken);
30128
- }
30129
- }
30130
- const ideIds = selectedIDEs.map((i) => i.id);
30131
- (0, import_daemon_core5.markSetupComplete)(ideIds, ["adhdev"]);
30438
+ (0, import_daemon_core5.markSetupComplete)(["daemon"], ["adhdev"]);
30132
30439
  if (loginResult) {
30133
30440
  (0, import_daemon_core5.updateConfig)({
30134
30441
  connectionToken: loginResult.connectionToken,
@@ -30138,11 +30445,6 @@ async function quickSetup() {
30138
30445
  }
30139
30446
  console.log(DIVIDER);
30140
30447
  console.log(import_chalk2.default.bold("\n\u{1F389} Setup Complete!\n"));
30141
- if (selectedIDEs.length === 1) {
30142
- console.log(` ${import_chalk2.default.bold("IDE:")} ${selectedIDEs[0].icon} ${selectedIDEs[0].displayName}`);
30143
- } else {
30144
- console.log(` ${import_chalk2.default.bold("IDEs:")} ${selectedIDEs.map((i) => `${i.icon} ${i.displayName}`).join(", ")}`);
30145
- }
30146
30448
  console.log(` ${import_chalk2.default.bold("User:")} ${loginResult?.email || "not logged in"}`);
30147
30449
  console.log(` ${import_chalk2.default.bold("Status:")} ${import_chalk2.default.green("Ready to connect")}`);
30148
30450
  console.log();
@@ -30150,108 +30452,19 @@ async function quickSetup() {
30150
30452
  console.log(import_chalk2.default.gray(" adhdev daemon \u2014 Start the main daemon (required for all features)"));
30151
30453
  console.log(import_chalk2.default.gray(" adhdev launch <ide> \u2014 Launch an IDE with remote control (e.g. cursor)"));
30152
30454
  console.log(import_chalk2.default.gray(" adhdev launch <agent> \u2014 Start a CLI agent via daemon (e.g. gemini, claude)"));
30153
- console.log(import_chalk2.default.gray(" adhdev cdp \u2014 Interactive CDP debug console"));
30154
30455
  console.log(import_chalk2.default.gray(" adhdev status \u2014 Check setup status"));
30155
30456
  console.log(import_chalk2.default.gray(" adhdev setup \u2014 Reconfigure ADHDev"));
30156
30457
  console.log();
30157
30458
  await installCliOnly();
30158
30459
  await startDaemonFlow();
30159
30460
  }
30160
- async function customSetup() {
30161
- console.log(import_chalk2.default.bold("\n\u{1F4CD} Step 1/4 \u2014 Detecting installed IDEs...\n"));
30162
- const spinner = (0, import_ora.default)("Scanning your system...").start();
30163
- const ides = await (0, import_daemon_core5.detectIDEs)();
30164
- const installedIDEs = ides.filter((i) => i.installed);
30165
- spinner.stop();
30166
- if (installedIDEs.length === 0) {
30167
- console.log(import_chalk2.default.yellow("\u26A0 No supported IDEs found."));
30168
- return;
30169
- }
30170
- console.log(import_chalk2.default.green(`Found ${installedIDEs.length} IDE(s):
30171
- `));
30172
- installedIDEs.forEach((ide) => {
30173
- const version2 = ide.version ? import_chalk2.default.gray(` v${ide.version}`) : "";
30174
- const cli = ide.cliCommand ? import_chalk2.default.gray(` (CLI: \u2713)`) : import_chalk2.default.yellow(` (CLI: \u2717 manual install)`);
30175
- console.log(` ${ide.icon} ${import_chalk2.default.bold(ide.displayName)}${version2}${cli}`);
30176
- });
30177
- console.log();
30178
- console.log(DIVIDER);
30179
- console.log(import_chalk2.default.bold("\n\u{1F4CD} Step 2/4 \u2014 Select your primary IDE\n"));
30180
- const { selectedIdeId } = await import_inquirer.default.prompt([
30181
- {
30182
- type: "list",
30183
- name: "selectedIdeId",
30184
- message: "Which IDE?",
30185
- choices: installedIDEs.map((ide) => ({
30186
- name: `${ide.icon} ${ide.displayName}${ide.version ? import_chalk2.default.gray(` v${ide.version}`) : ""}`,
30187
- value: ide.id
30188
- }))
30189
- }
30190
- ]);
30191
- const selectedIDE = installedIDEs.find((i) => i.id === selectedIdeId);
30192
- console.log(DIVIDER);
30193
- console.log(import_chalk2.default.bold("\n\u{1F4CD} Step 3/4 \u2014 Choose AI extensions\n"));
30194
- const aiExtensions = (0, import_daemon_core5.getAIExtensions)();
30195
- const { selectedExtIds } = await import_inquirer.default.prompt([
30196
- {
30197
- type: "checkbox",
30198
- name: "selectedExtIds",
30199
- message: "Select AI extensions:",
30200
- choices: aiExtensions.map((ext) => ({
30201
- name: `${ext.icon} ${ext.displayName} \u2014 ${import_chalk2.default.gray(ext.description)}`,
30202
- value: ext.id,
30203
- checked: ext.recommended
30204
- }))
30205
- }
30206
- ]);
30207
- const selectedAIExts = aiExtensions.filter((e) => selectedExtIds.includes(e.id));
30208
- const allExtensions = selectedAIExts;
30209
- console.log(import_chalk2.default.bold("\n\u{1F4CD} Step 4/4 \u2014 Installing extensions\n"));
30210
- if (selectedIDE.cliCommand) {
30211
- await (0, import_daemon_core5.installExtensions)(
30212
- selectedIDE,
30213
- allExtensions,
30214
- (current, total, ext, result) => {
30215
- const status = result.alreadyInstalled ? import_chalk2.default.blue("already installed") : result.success ? import_chalk2.default.green("installed \u2713") : import_chalk2.default.red(`failed \u2717`);
30216
- console.log(` [${current}/${total}] ${ext.icon} ${ext.displayName} \u2014 ${status}`);
30217
- }
30218
- );
30219
- } else {
30220
- console.log(import_chalk2.default.yellow("\u26A0 No CLI \u2014 install manually:"));
30221
- allExtensions.forEach((ext) => {
30222
- console.log(import_chalk2.default.gray(` ${ext.icon} ${ext.displayName}: ${ext.marketplaceId}`));
30223
- });
30224
- }
30225
- console.log(DIVIDER);
30226
- const loginResult = await loginFlow();
30227
- if (loginResult?.connectionToken) {
30228
- await injectTokenToIDE(selectedIDE, loginResult.connectionToken);
30229
- }
30230
- (0, import_daemon_core5.markSetupComplete)(selectedIdeId, allExtensions.map((e) => e.id));
30231
- if (loginResult) {
30232
- (0, import_daemon_core5.updateConfig)({
30233
- connectionToken: loginResult.connectionToken,
30234
- userEmail: loginResult.email,
30235
- userName: loginResult.name
30236
- });
30237
- }
30238
- console.log(DIVIDER);
30239
- console.log(import_chalk2.default.bold("\n\u{1F389} Setup Complete!\n"));
30240
- console.log(` ${import_chalk2.default.bold("IDE:")} ${selectedIDE.icon} ${selectedIDE.displayName}`);
30241
- console.log(` ${import_chalk2.default.bold("Extensions:")} ${allExtensions.length} installed`);
30242
- console.log(` ${import_chalk2.default.bold("User:")} ${loginResult?.email || "not logged in"}`);
30243
- console.log(` ${import_chalk2.default.bold("Status:")} ${import_chalk2.default.green("Ready to connect")}`);
30244
- console.log();
30245
- await startDaemonFlow();
30246
- console.log(import_chalk2.default.gray("\nThank you for using ADHDev! \u{1F9A6}\n"));
30247
- }
30248
30461
  async function loginFlow() {
30249
30462
  console.log(import_chalk2.default.bold("\n\u{1F510} Login to ADHDev\n"));
30250
30463
  const { wantLogin } = await import_inquirer.default.prompt([
30251
30464
  {
30252
30465
  type: "confirm",
30253
30466
  name: "wantLogin",
30254
- message: "Sign in to connect IDE to your ADHDev account?",
30467
+ message: "Sign in to connect to your ADHDev account?",
30255
30468
  default: true
30256
30469
  }
30257
30470
  ]);
@@ -30318,49 +30531,6 @@ async function loginFlow() {
30318
30531
  pollSpinner.fail("Authentication timed out");
30319
30532
  return null;
30320
30533
  }
30321
- async function injectTokenToIDE(ide, connectionToken) {
30322
- if (!ide.cliCommand) return;
30323
- try {
30324
- const os3 = await import("os");
30325
- const fs3 = await import("fs");
30326
- const path3 = await import("path");
30327
- const platform2 = os3.platform();
30328
- const home = os3.homedir();
30329
- const getSettingsPath = (appName2) => {
30330
- if (platform2 === "darwin") {
30331
- return path3.join(home, "Library", "Application Support", appName2, "User", "settings.json");
30332
- } else if (platform2 === "win32") {
30333
- return path3.join(process.env.APPDATA || path3.join(home, "AppData", "Roaming"), appName2, "User", "settings.json");
30334
- } else {
30335
- return path3.join(home, ".config", appName2, "User", "settings.json");
30336
- }
30337
- };
30338
- const loader = new import_daemon_core5.ProviderLoader({ logFn: () => {
30339
- } });
30340
- loader.loadAll();
30341
- const appNameMap = loader.getMacAppIdentifiers();
30342
- const appName = appNameMap[ide.id];
30343
- if (!appName) return;
30344
- const settingsPath = getSettingsPath(appName);
30345
- let settings = {};
30346
- if (fs3.existsSync(settingsPath)) {
30347
- try {
30348
- settings = JSON.parse(fs3.readFileSync(settingsPath, "utf-8"));
30349
- } catch {
30350
- settings = {};
30351
- }
30352
- } else {
30353
- fs3.mkdirSync(path3.dirname(settingsPath), { recursive: true });
30354
- }
30355
- settings["adhdev.connectionToken"] = connectionToken;
30356
- settings["adhdev.autoConnect"] = true;
30357
- fs3.writeFileSync(settingsPath, JSON.stringify(settings, null, 4), "utf-8");
30358
- console.log(import_chalk2.default.green(" \u2713 Connection token saved to IDE settings"));
30359
- } catch (e) {
30360
- console.log(import_chalk2.default.yellow(` \u26A0 Could not inject token: ${e.message}`));
30361
- console.log(import_chalk2.default.gray(` You can set it manually: adhdev.connectionToken = ${connectionToken}`));
30362
- }
30363
- }
30364
30534
  async function startDaemonFlow() {
30365
30535
  const { isDaemonRunning: isDaemonRunning2 } = await Promise.resolve().then(() => (init_adhdev_daemon(), adhdev_daemon_exports));
30366
30536
  if (isDaemonRunning2()) {
@@ -30372,7 +30542,7 @@ async function startDaemonFlow() {
30372
30542
  {
30373
30543
  type: "confirm",
30374
30544
  name: "startDaemon",
30375
- message: "Start the ADHDev Daemon now? (Required for all agent/IDE routing features)",
30545
+ message: "Start the ADHDev Daemon now?",
30376
30546
  default: true
30377
30547
  }
30378
30548
  ]);
@@ -30388,11 +30558,20 @@ async function startDaemonFlow() {
30388
30558
  const os3 = await import("os");
30389
30559
  const path3 = await import("path");
30390
30560
  const logPath = path3.join(os3.homedir(), ".adhdev", "daemon.log");
30561
+ const platform2 = os3.platform();
30391
30562
  try {
30392
- execSync(`nohup adhdev daemon > "${logPath}" 2>&1 &`, {
30393
- timeout: 3e3,
30394
- stdio: "ignore"
30395
- });
30563
+ if (platform2 === "win32") {
30564
+ execSync(`start /B adhdev daemon > "${logPath}" 2>&1`, {
30565
+ timeout: 3e3,
30566
+ stdio: "ignore",
30567
+ shell: "cmd.exe"
30568
+ });
30569
+ } else {
30570
+ execSync(`nohup adhdev daemon > "${logPath}" 2>&1 &`, {
30571
+ timeout: 3e3,
30572
+ stdio: "ignore"
30573
+ });
30574
+ }
30396
30575
  } catch {
30397
30576
  daemon.start({ localPort: 19222, foreground: false }).catch(() => {
30398
30577
  });
@@ -30400,13 +30579,11 @@ async function startDaemonFlow() {
30400
30579
  await new Promise((r) => setTimeout(r, 2e3));
30401
30580
  if (isDaemonRunning2()) {
30402
30581
  daemonSpinner.succeed("Daemon started");
30403
- console.log(import_chalk2.default.gray(" Dashboard: https://adhf.dev/dashboard"));
30404
- console.log(import_chalk2.default.gray(` Logs: ${logPath}`));
30405
30582
  } else {
30406
30583
  daemonSpinner.succeed("Daemon starting in background");
30407
- console.log(import_chalk2.default.gray(" Dashboard: https://adhf.dev/dashboard"));
30408
- console.log(import_chalk2.default.gray(` Logs: ${logPath}`));
30409
30584
  }
30585
+ console.log(import_chalk2.default.gray(" Dashboard: https://adhf.dev/dashboard"));
30586
+ console.log(import_chalk2.default.gray(` Logs: ${logPath}`));
30410
30587
  console.log();
30411
30588
  } catch (e) {
30412
30589
  daemonSpinner.fail(`Daemon start failed: ${e?.message || "Unknown"}`);
@@ -30432,7 +30609,6 @@ async function installCliOnly() {
30432
30609
  console.log(import_chalk2.default.gray(" \u2022 Start the main daemon (adhdev daemon)"));
30433
30610
  console.log(import_chalk2.default.gray(" \u2022 Launch IDE with CDP (adhdev launch <ide>)"));
30434
30611
  console.log(import_chalk2.default.gray(" \u2022 Start CLI agents (adhdev launch <agent>)"));
30435
- console.log(import_chalk2.default.gray(" \u2022 CDP Debugging Console (adhdev cdp)"));
30436
30612
  console.log(import_chalk2.default.gray(" \u2022 Check setup status (adhdev status)"));
30437
30613
  console.log();
30438
30614
  if (currentVersion) {
@@ -30483,7 +30659,6 @@ async function installCliOnly() {
30483
30659
  }
30484
30660
  installSpinner.succeed(`adhdev CLI ${currentVersion ? "updated" : "installed"} \u2713 (v${newVersion})`);
30485
30661
  console.log(import_chalk2.default.gray(" Try: adhdev daemon"));
30486
- console.log(import_chalk2.default.gray(" adhdev status"));
30487
30662
  console.log();
30488
30663
  } catch (e) {
30489
30664
  installSpinner.fail("Install failed");