@adhdev/daemon-core 0.8.93 → 0.8.94

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.mjs CHANGED
@@ -2504,7 +2504,7 @@ var init_provider_cli_adapter = __esm({
2504
2504
  `[${this.cliType}] Waiting for interactive prompt: hasPrompt=${hasPrompt} stableMs=${stableMs} recentOutputMs=${recentlyOutput} status=${status} startup=${startupLikelyActive} screen=${JSON.stringify(summarizeCliTraceText(screenText, 220)).slice(0, 260)}`
2505
2505
  );
2506
2506
  }
2507
- await new Promise((resolve11) => setTimeout(resolve11, 50));
2507
+ await new Promise((resolve12) => setTimeout(resolve12, 50));
2508
2508
  }
2509
2509
  const finalScreenText = this.terminalScreen.getText() || "";
2510
2510
  LOG.warn(
@@ -3092,7 +3092,7 @@ var init_provider_cli_adapter = __esm({
3092
3092
  }
3093
3093
  projectEffectiveStatus(startupModal = null) {
3094
3094
  if (this.parseErrorMessage) return "error";
3095
- if (startupModal) return "waiting_approval";
3095
+ if (startupModal || this.activeModal) return "waiting_approval";
3096
3096
  if (this.isWaitingForResponse && this.currentTurnScope && this.currentStatus === "idle") return "generating";
3097
3097
  return this.currentStatus;
3098
3098
  }
@@ -3100,12 +3100,24 @@ var init_provider_cli_adapter = __esm({
3100
3100
  getStatus() {
3101
3101
  const screenText = this.terminalScreen.getText() || "";
3102
3102
  const startupModal = this.startupParseGate ? this.getStartupConfirmationModal(screenText) : null;
3103
- const effectiveStatus = this.projectEffectiveStatus(startupModal);
3103
+ let effectiveStatus = this.projectEffectiveStatus(startupModal);
3104
+ let effectiveModal = startupModal || this.activeModal;
3105
+ if (!startupModal && !effectiveModal && typeof this.cliScripts?.parseOutput === "function") {
3106
+ try {
3107
+ const parsed = this.getScriptParsedStatus();
3108
+ const parsedModal = parsed?.activeModal && Array.isArray(parsed.activeModal.buttons) && parsed.activeModal.buttons.some((button) => typeof button === "string" && button.trim()) ? parsed.activeModal : null;
3109
+ if (parsed?.status === "waiting_approval" && parsedModal) {
3110
+ effectiveStatus = "waiting_approval";
3111
+ effectiveModal = parsedModal;
3112
+ }
3113
+ } catch {
3114
+ }
3115
+ }
3104
3116
  return {
3105
3117
  status: effectiveStatus,
3106
3118
  messages: [...this.committedMessages],
3107
3119
  workingDir: this.workingDir,
3108
- activeModal: startupModal || this.activeModal,
3120
+ activeModal: effectiveModal,
3109
3121
  errorMessage: this.parseErrorMessage || void 0,
3110
3122
  errorReason: this.parseErrorMessage ? "parse_error" : void 0
3111
3123
  };
@@ -3141,6 +3153,15 @@ var init_provider_cli_adapter = __esm({
3141
3153
  this.currentTurnScope,
3142
3154
  screenText
3143
3155
  );
3156
+ const parsedModal = parsed?.activeModal && Array.isArray(parsed.activeModal.buttons) && parsed.activeModal.buttons.some((button) => typeof button === "string" && button.trim()) ? parsed.activeModal : null;
3157
+ if (parsedModal && parsed?.status === "waiting_approval") {
3158
+ this.activeModal = parsedModal;
3159
+ this.isWaitingForResponse = true;
3160
+ if (this.currentStatus !== "waiting_approval") {
3161
+ this.setStatus("waiting_approval", "parsed_waiting_approval");
3162
+ this.onStatusChange?.();
3163
+ }
3164
+ }
3144
3165
  if (this.maybeCommitVisibleIdleTranscript(parsed)) {
3145
3166
  return this.getScriptParsedStatus();
3146
3167
  }
@@ -3345,7 +3366,7 @@ ${data.message || ""}`.trim();
3345
3366
  const deadline = Date.now() + 1e4;
3346
3367
  while (this.startupParseGate && Date.now() < deadline) {
3347
3368
  this.resolveStartupState("send_wait");
3348
- await new Promise((resolve11) => setTimeout(resolve11, 50));
3369
+ await new Promise((resolve12) => setTimeout(resolve12, 50));
3349
3370
  }
3350
3371
  }
3351
3372
  if (!allowInterventionPrompt) {
@@ -3437,12 +3458,12 @@ ${data.message || ""}`.trim();
3437
3458
  if (this.isWaitingForResponse) this.finishResponse();
3438
3459
  }, this.timeouts.maxResponse);
3439
3460
  };
3440
- await new Promise((resolve11) => {
3461
+ await new Promise((resolve12) => {
3441
3462
  let resolved = false;
3442
3463
  const resolveOnce = () => {
3443
3464
  if (resolved) return;
3444
3465
  resolved = true;
3445
- resolve11();
3466
+ resolve12();
3446
3467
  };
3447
3468
  const submit = () => {
3448
3469
  if (!this.ptyProcess) {
@@ -3616,17 +3637,17 @@ ${data.message || ""}`.trim();
3616
3637
  }
3617
3638
  }
3618
3639
  waitForStopped(timeoutMs) {
3619
- return new Promise((resolve11) => {
3640
+ return new Promise((resolve12) => {
3620
3641
  const startedAt = Date.now();
3621
3642
  const timer = setInterval(() => {
3622
3643
  if (!this.ptyProcess || this.currentStatus === "stopped") {
3623
3644
  clearInterval(timer);
3624
- resolve11(true);
3645
+ resolve12(true);
3625
3646
  return;
3626
3647
  }
3627
3648
  if (Date.now() - startedAt >= timeoutMs) {
3628
3649
  clearInterval(timer);
3629
- resolve11(false);
3650
+ resolve12(false);
3630
3651
  }
3631
3652
  }, 100);
3632
3653
  });
@@ -3791,7 +3812,22 @@ ${data.message || ""}`.trim();
3791
3812
  }
3792
3813
  resolveModal(buttonIndex) {
3793
3814
  const screenText = this.terminalScreen.getText() || "";
3794
- const modal = this.activeModal || this.getStartupConfirmationModal(screenText);
3815
+ let modal = this.activeModal || this.getStartupConfirmationModal(screenText);
3816
+ if (!modal && typeof this.cliScripts?.parseOutput === "function") {
3817
+ try {
3818
+ const parsed = this.getScriptParsedStatus();
3819
+ const parsedModal = parsed?.activeModal && Array.isArray(parsed.activeModal.buttons) && parsed.activeModal.buttons.some((button) => typeof button === "string" && button.trim()) ? parsed.activeModal : null;
3820
+ if (parsed?.status === "waiting_approval" && parsedModal) {
3821
+ modal = parsedModal;
3822
+ this.activeModal = parsedModal;
3823
+ if (this.currentStatus !== "waiting_approval") {
3824
+ this.setStatus("waiting_approval", "resolve_modal_parse");
3825
+ this.onStatusChange?.();
3826
+ }
3827
+ }
3828
+ } catch {
3829
+ }
3830
+ }
3795
3831
  if (!this.ptyProcess || this.currentStatus !== "waiting_approval" && !modal) return;
3796
3832
  this.clearIdleFinishCandidate("resolve_modal");
3797
3833
  this.recordTrace("resolve_modal", {
@@ -4605,15 +4641,15 @@ function resolveCommandPath(command) {
4605
4641
  return null;
4606
4642
  }
4607
4643
  function execAsync(cmd, timeoutMs = 5e3) {
4608
- return new Promise((resolve11) => {
4644
+ return new Promise((resolve12) => {
4609
4645
  const child = exec(cmd, { encoding: "utf-8", timeout: timeoutMs }, (err, stdout) => {
4610
4646
  if (err || !stdout?.trim()) {
4611
- resolve11(null);
4647
+ resolve12(null);
4612
4648
  } else {
4613
- resolve11(stdout.trim());
4649
+ resolve12(stdout.trim());
4614
4650
  }
4615
4651
  });
4616
- child.on("error", () => resolve11(null));
4652
+ child.on("error", () => resolve12(null));
4617
4653
  });
4618
4654
  }
4619
4655
  async function detectCLIs(providerLoader, options) {
@@ -4973,7 +5009,7 @@ var DaemonCdpManager = class {
4973
5009
  * Returns multiple entries if multiple IDE windows are open on same port
4974
5010
  */
4975
5011
  static listAllTargets(port) {
4976
- return new Promise((resolve11) => {
5012
+ return new Promise((resolve12) => {
4977
5013
  const req = http.get(`http://127.0.0.1:${port}/json`, (res) => {
4978
5014
  let data = "";
4979
5015
  res.on("data", (chunk) => data += chunk.toString());
@@ -4989,16 +5025,16 @@ var DaemonCdpManager = class {
4989
5025
  (t) => !isNonMain(t.title || "") && t.url?.includes("workbench.html") && !t.url?.includes("agent")
4990
5026
  );
4991
5027
  const fallbackPages = pages.filter((t) => !isNonMain(t.title || ""));
4992
- resolve11(mainPages.length > 0 ? mainPages : fallbackPages);
5028
+ resolve12(mainPages.length > 0 ? mainPages : fallbackPages);
4993
5029
  } catch {
4994
- resolve11([]);
5030
+ resolve12([]);
4995
5031
  }
4996
5032
  });
4997
5033
  });
4998
- req.on("error", () => resolve11([]));
5034
+ req.on("error", () => resolve12([]));
4999
5035
  req.setTimeout(2e3, () => {
5000
5036
  req.destroy();
5001
- resolve11([]);
5037
+ resolve12([]);
5002
5038
  });
5003
5039
  });
5004
5040
  }
@@ -5038,7 +5074,7 @@ var DaemonCdpManager = class {
5038
5074
  }
5039
5075
  }
5040
5076
  findTargetOnPort(port) {
5041
- return new Promise((resolve11) => {
5077
+ return new Promise((resolve12) => {
5042
5078
  const req = http.get(`http://127.0.0.1:${port}/json`, (res) => {
5043
5079
  let data = "";
5044
5080
  res.on("data", (chunk) => data += chunk.toString());
@@ -5049,7 +5085,7 @@ var DaemonCdpManager = class {
5049
5085
  (t) => (t.type === "page" || t.type === "browser" || t.type === "Page") && t.webSocketDebuggerUrl
5050
5086
  );
5051
5087
  if (pages.length === 0) {
5052
- resolve11(targets.find((t) => t.webSocketDebuggerUrl) || null);
5088
+ resolve12(targets.find((t) => t.webSocketDebuggerUrl) || null);
5053
5089
  return;
5054
5090
  }
5055
5091
  const titleFilteredPages = pages.filter((t) => !this.isNonMainTitle(t.title || ""));
@@ -5068,25 +5104,25 @@ var DaemonCdpManager = class {
5068
5104
  this._targetId = selected.target.id;
5069
5105
  }
5070
5106
  this._pageTitle = selected.target.title || "";
5071
- resolve11(selected.target);
5107
+ resolve12(selected.target);
5072
5108
  return;
5073
5109
  }
5074
5110
  if (previousTargetId) {
5075
5111
  this.log(`[CDP] Target ${previousTargetId} not found in page list`);
5076
- resolve11(null);
5112
+ resolve12(null);
5077
5113
  return;
5078
5114
  }
5079
5115
  this._pageTitle = list[0]?.title || "";
5080
- resolve11(list[0]);
5116
+ resolve12(list[0]);
5081
5117
  } catch {
5082
- resolve11(null);
5118
+ resolve12(null);
5083
5119
  }
5084
5120
  });
5085
5121
  });
5086
- req.on("error", () => resolve11(null));
5122
+ req.on("error", () => resolve12(null));
5087
5123
  req.setTimeout(2e3, () => {
5088
5124
  req.destroy();
5089
- resolve11(null);
5125
+ resolve12(null);
5090
5126
  });
5091
5127
  });
5092
5128
  }
@@ -5097,7 +5133,7 @@ var DaemonCdpManager = class {
5097
5133
  this.extensionProviders = providers;
5098
5134
  }
5099
5135
  connectToTarget(wsUrl) {
5100
- return new Promise((resolve11) => {
5136
+ return new Promise((resolve12) => {
5101
5137
  this.ws = new WebSocket(wsUrl);
5102
5138
  this.ws.on("open", async () => {
5103
5139
  this._connected = true;
@@ -5107,17 +5143,17 @@ var DaemonCdpManager = class {
5107
5143
  }
5108
5144
  this.connectBrowserWs().catch(() => {
5109
5145
  });
5110
- resolve11(true);
5146
+ resolve12(true);
5111
5147
  });
5112
5148
  this.ws.on("message", (data) => {
5113
5149
  try {
5114
5150
  const msg = JSON.parse(data.toString());
5115
5151
  if (msg.id && this.pending.has(msg.id)) {
5116
- const { resolve: resolve12, reject } = this.pending.get(msg.id);
5152
+ const { resolve: resolve13, reject } = this.pending.get(msg.id);
5117
5153
  this.pending.delete(msg.id);
5118
5154
  this.failureCount = 0;
5119
5155
  if (msg.error) reject(new Error(msg.error.message));
5120
- else resolve12(msg.result);
5156
+ else resolve13(msg.result);
5121
5157
  } else if (msg.method === "Runtime.executionContextCreated") {
5122
5158
  this.contexts.add(msg.params.context.id);
5123
5159
  } else if (msg.method === "Runtime.executionContextDestroyed") {
@@ -5140,7 +5176,7 @@ var DaemonCdpManager = class {
5140
5176
  this.ws.on("error", (err) => {
5141
5177
  this.log(`[CDP] WebSocket error: ${err.message}`);
5142
5178
  this._connected = false;
5143
- resolve11(false);
5179
+ resolve12(false);
5144
5180
  });
5145
5181
  });
5146
5182
  }
@@ -5154,7 +5190,7 @@ var DaemonCdpManager = class {
5154
5190
  return;
5155
5191
  }
5156
5192
  this.log(`[CDP] Connecting browser WS for target discovery...`);
5157
- await new Promise((resolve11, reject) => {
5193
+ await new Promise((resolve12, reject) => {
5158
5194
  this.browserWs = new WebSocket(browserWsUrl);
5159
5195
  this.browserWs.on("open", async () => {
5160
5196
  this._browserConnected = true;
@@ -5164,16 +5200,16 @@ var DaemonCdpManager = class {
5164
5200
  } catch (e) {
5165
5201
  this.log(`[CDP] setDiscoverTargets failed: ${e.message}`);
5166
5202
  }
5167
- resolve11();
5203
+ resolve12();
5168
5204
  });
5169
5205
  this.browserWs.on("message", (data) => {
5170
5206
  try {
5171
5207
  const msg = JSON.parse(data.toString());
5172
5208
  if (msg.id && this.browserPending.has(msg.id)) {
5173
- const { resolve: resolve12, reject: reject2 } = this.browserPending.get(msg.id);
5209
+ const { resolve: resolve13, reject: reject2 } = this.browserPending.get(msg.id);
5174
5210
  this.browserPending.delete(msg.id);
5175
5211
  if (msg.error) reject2(new Error(msg.error.message));
5176
- else resolve12(msg.result);
5212
+ else resolve13(msg.result);
5177
5213
  }
5178
5214
  } catch {
5179
5215
  }
@@ -5193,31 +5229,31 @@ var DaemonCdpManager = class {
5193
5229
  }
5194
5230
  }
5195
5231
  getBrowserWsUrl() {
5196
- return new Promise((resolve11) => {
5232
+ return new Promise((resolve12) => {
5197
5233
  const req = http.get(`http://127.0.0.1:${this.port}/json/version`, (res) => {
5198
5234
  let data = "";
5199
5235
  res.on("data", (chunk) => data += chunk.toString());
5200
5236
  res.on("end", () => {
5201
5237
  try {
5202
5238
  const info = JSON.parse(data);
5203
- resolve11(info.webSocketDebuggerUrl || null);
5239
+ resolve12(info.webSocketDebuggerUrl || null);
5204
5240
  } catch {
5205
- resolve11(null);
5241
+ resolve12(null);
5206
5242
  }
5207
5243
  });
5208
5244
  });
5209
- req.on("error", () => resolve11(null));
5245
+ req.on("error", () => resolve12(null));
5210
5246
  req.setTimeout(3e3, () => {
5211
5247
  req.destroy();
5212
- resolve11(null);
5248
+ resolve12(null);
5213
5249
  });
5214
5250
  });
5215
5251
  }
5216
5252
  sendBrowser(method, params = {}, timeoutMs = 15e3) {
5217
- return new Promise((resolve11, reject) => {
5253
+ return new Promise((resolve12, reject) => {
5218
5254
  if (!this.browserWs || !this._browserConnected) return reject(new Error("Browser WS not connected"));
5219
5255
  const id = this.browserMsgId++;
5220
- this.browserPending.set(id, { resolve: resolve11, reject });
5256
+ this.browserPending.set(id, { resolve: resolve12, reject });
5221
5257
  this.browserWs.send(JSON.stringify({ id, method, params }));
5222
5258
  setTimeout(() => {
5223
5259
  if (this.browserPending.has(id)) {
@@ -5257,11 +5293,11 @@ var DaemonCdpManager = class {
5257
5293
  }
5258
5294
  // ─── CDP Protocol ────────────────────────────────────────
5259
5295
  sendInternal(method, params = {}, timeoutMs = 15e3) {
5260
- return new Promise((resolve11, reject) => {
5296
+ return new Promise((resolve12, reject) => {
5261
5297
  if (!this.ws || !this._connected) return reject(new Error("CDP not connected"));
5262
5298
  if (this.ws.readyState !== WebSocket.OPEN) return reject(new Error("WebSocket not open"));
5263
5299
  const id = this.msgId++;
5264
- this.pending.set(id, { resolve: resolve11, reject });
5300
+ this.pending.set(id, { resolve: resolve12, reject });
5265
5301
  this.ws.send(JSON.stringify({ id, method, params }));
5266
5302
  setTimeout(() => {
5267
5303
  if (this.pending.has(id)) {
@@ -5510,7 +5546,7 @@ var DaemonCdpManager = class {
5510
5546
  const browserWs = this.browserWs;
5511
5547
  let msgId = this.browserMsgId;
5512
5548
  const sendWs = (method, params = {}, sessionId) => {
5513
- return new Promise((resolve11, reject) => {
5549
+ return new Promise((resolve12, reject) => {
5514
5550
  const mid = msgId++;
5515
5551
  this.browserMsgId = msgId;
5516
5552
  const handler = (raw) => {
@@ -5519,7 +5555,7 @@ var DaemonCdpManager = class {
5519
5555
  if (msg.id === mid) {
5520
5556
  browserWs.removeListener("message", handler);
5521
5557
  if (msg.error) reject(new Error(msg.error.message || JSON.stringify(msg.error)));
5522
- else resolve11(msg.result);
5558
+ else resolve12(msg.result);
5523
5559
  }
5524
5560
  } catch {
5525
5561
  }
@@ -5720,14 +5756,14 @@ var DaemonCdpManager = class {
5720
5756
  if (!ws || ws.readyState !== WebSocket.OPEN) {
5721
5757
  throw new Error("CDP not connected");
5722
5758
  }
5723
- return new Promise((resolve11, reject) => {
5759
+ return new Promise((resolve12, reject) => {
5724
5760
  const id = getNextId();
5725
5761
  pendingMap.set(id, {
5726
5762
  resolve: (result) => {
5727
5763
  if (result?.result?.subtype === "error") {
5728
5764
  reject(new Error(result.result.description));
5729
5765
  } else {
5730
- resolve11(result?.result?.value);
5766
+ resolve12(result?.result?.value);
5731
5767
  }
5732
5768
  },
5733
5769
  reject
@@ -5759,10 +5795,10 @@ var DaemonCdpManager = class {
5759
5795
  throw new Error("CDP not connected");
5760
5796
  }
5761
5797
  const sendViaSession = (method, params = {}) => {
5762
- return new Promise((resolve11, reject) => {
5798
+ return new Promise((resolve12, reject) => {
5763
5799
  const pendingMap = this._browserConnected ? this.browserPending : this.pending;
5764
5800
  const id = this._browserConnected ? this.browserMsgId++ : this.msgId++;
5765
- pendingMap.set(id, { resolve: resolve11, reject });
5801
+ pendingMap.set(id, { resolve: resolve12, reject });
5766
5802
  ws.send(JSON.stringify({ id, sessionId, method, params }));
5767
5803
  setTimeout(() => {
5768
5804
  if (pendingMap.has(id)) {
@@ -9659,7 +9695,9 @@ function getTargetInstance(h, args) {
9659
9695
  const targetSessionId = typeof args?.targetSessionId === "string" ? args.targetSessionId.trim() : "";
9660
9696
  const sessionId = targetSessionId || h.currentSession?.sessionId || "";
9661
9697
  if (!sessionId) return null;
9662
- return h.ctx.instanceManager?.getInstance(sessionId) || null;
9698
+ const session = h.ctx.sessionRegistry?.get(sessionId);
9699
+ const instanceKey = session?.adapterKey || session?.instanceKey || sessionId;
9700
+ return h.ctx.instanceManager?.getInstance(instanceKey) || null;
9663
9701
  }
9664
9702
  function getTargetTransport(h, provider) {
9665
9703
  if (h.currentSession?.transport) return h.currentSession.transport;
@@ -9956,7 +9994,7 @@ function getStateLastSignature(state) {
9956
9994
  async function getStableExtensionBaseline(h) {
9957
9995
  const first = await readExtensionChatState(h);
9958
9996
  if (getStateMessageCount(first) > 0 || getStateLastSignature(first)) return first;
9959
- await new Promise((resolve11) => setTimeout(resolve11, 150));
9997
+ await new Promise((resolve12) => setTimeout(resolve12, 150));
9960
9998
  const second = await readExtensionChatState(h);
9961
9999
  return getStateMessageCount(second) >= getStateMessageCount(first) ? second : first;
9962
10000
  }
@@ -9964,7 +10002,7 @@ async function verifyExtensionSendObserved(h, before) {
9964
10002
  const beforeCount = getStateMessageCount(before);
9965
10003
  const beforeSignature = getStateLastSignature(before);
9966
10004
  for (let attempt = 0; attempt < 12; attempt += 1) {
9967
- await new Promise((resolve11) => setTimeout(resolve11, 250));
10005
+ await new Promise((resolve12) => setTimeout(resolve12, 250));
9968
10006
  const state = await readExtensionChatState(h);
9969
10007
  if (state?.status === "waiting_approval") return true;
9970
10008
  const afterCount = getStateMessageCount(state);
@@ -10728,10 +10766,17 @@ async function handleResolveAction(h, args) {
10728
10766
  }
10729
10767
  }
10730
10768
  const status = adapter.getStatus();
10731
- if (status?.status !== "waiting_approval") {
10769
+ const targetInstance = getTargetInstance(h, args);
10770
+ const targetState = targetInstance?.getState?.();
10771
+ const surfacedModal = targetState?.activeChat?.activeModal && Array.isArray(targetState.activeChat.activeModal.buttons) && targetState.activeChat.activeModal.buttons.some((candidate) => typeof candidate === "string" && candidate.trim()) ? targetState.activeChat.activeModal : null;
10772
+ const statusModal = status?.activeModal && Array.isArray(status.activeModal.buttons) && status.activeModal.buttons.some((candidate) => typeof candidate === "string" && candidate.trim()) ? status.activeModal : null;
10773
+ const effectiveModal = statusModal || surfacedModal;
10774
+ const effectiveStatus = status?.status === "waiting_approval" || targetState?.activeChat?.status === "waiting_approval" ? "waiting_approval" : status?.status;
10775
+ LOG.info("Command", `[resolveAction] CLI PTY gate target=${String(args?.targetSessionId || "")} rawStatus=${String(status?.status || "")} effectiveStatus=${String(effectiveStatus || "")} statusModal=${statusModal ? "yes" : "no"} surfacedModal=${surfacedModal ? "yes" : "no"} instance=${targetInstance ? "yes" : "no"}`);
10776
+ if (effectiveStatus !== "waiting_approval" && !effectiveModal) {
10732
10777
  return { success: false, error: "Not in approval state" };
10733
10778
  }
10734
- const buttons = status.activeModal?.buttons || ["Allow once", "Always allow", "Deny"];
10779
+ const buttons = effectiveModal?.buttons || ["Allow once", "Always allow", "Deny"];
10735
10780
  let buttonIndex = typeof args?.buttonIndex === "number" ? args.buttonIndex : -1;
10736
10781
  if (buttonIndex < 0) {
10737
10782
  const btnLower = button.toLowerCase();
@@ -12184,7 +12229,7 @@ var DaemonCommandHandler = class {
12184
12229
  try {
12185
12230
  const http3 = await import("http");
12186
12231
  const postData = JSON.stringify(body);
12187
- const result = await new Promise((resolve11, reject) => {
12232
+ const result = await new Promise((resolve12, reject) => {
12188
12233
  const req = http3.request({
12189
12234
  hostname: "127.0.0.1",
12190
12235
  port: 19280,
@@ -12196,9 +12241,9 @@ var DaemonCommandHandler = class {
12196
12241
  res.on("data", (chunk) => data += chunk);
12197
12242
  res.on("end", () => {
12198
12243
  try {
12199
- resolve11(JSON.parse(data));
12244
+ resolve12(JSON.parse(data));
12200
12245
  } catch {
12201
- resolve11({ raw: data });
12246
+ resolve12({ raw: data });
12202
12247
  }
12203
12248
  });
12204
12249
  });
@@ -12216,15 +12261,15 @@ var DaemonCommandHandler = class {
12216
12261
  if (!providerType) return { success: false, error: "providerType required" };
12217
12262
  try {
12218
12263
  const http3 = await import("http");
12219
- const result = await new Promise((resolve11, reject) => {
12264
+ const result = await new Promise((resolve12, reject) => {
12220
12265
  http3.get(`http://127.0.0.1:19280/api/providers/${providerType}/${endpoint}`, (res) => {
12221
12266
  let data = "";
12222
12267
  res.on("data", (chunk) => data += chunk);
12223
12268
  res.on("end", () => {
12224
12269
  try {
12225
- resolve11(JSON.parse(data));
12270
+ resolve12(JSON.parse(data));
12226
12271
  } catch {
12227
- resolve11({ raw: data });
12272
+ resolve12({ raw: data });
12228
12273
  }
12229
12274
  });
12230
12275
  }).on("error", reject);
@@ -12238,7 +12283,7 @@ var DaemonCommandHandler = class {
12238
12283
  try {
12239
12284
  const http3 = await import("http");
12240
12285
  const postData = JSON.stringify(args || {});
12241
- const result = await new Promise((resolve11, reject) => {
12286
+ const result = await new Promise((resolve12, reject) => {
12242
12287
  const req = http3.request({
12243
12288
  hostname: "127.0.0.1",
12244
12289
  port: 19280,
@@ -12250,9 +12295,9 @@ var DaemonCommandHandler = class {
12250
12295
  res.on("data", (chunk) => data += chunk);
12251
12296
  res.on("end", () => {
12252
12297
  try {
12253
- resolve11(JSON.parse(data));
12298
+ resolve12(JSON.parse(data));
12254
12299
  } catch {
12255
- resolve11({ raw: data });
12300
+ resolve12({ raw: data });
12256
12301
  }
12257
12302
  });
12258
12303
  });
@@ -12350,7 +12395,7 @@ async function waitForCliAdapterReady(adapter, options) {
12350
12395
  if (status === "stopped") {
12351
12396
  throw new Error("CLI runtime stopped before it became ready");
12352
12397
  }
12353
- await new Promise((resolve11) => setTimeout(resolve11, pollMs));
12398
+ await new Promise((resolve12) => setTimeout(resolve12, pollMs));
12354
12399
  }
12355
12400
  throw new Error(`CLI runtime did not become ready within ${timeoutMs}ms`);
12356
12401
  }
@@ -13659,13 +13704,13 @@ var AcpProviderInstance = class {
13659
13704
  }
13660
13705
  this.currentStatus = "waiting_approval";
13661
13706
  this.detectStatusTransition();
13662
- const approved = await new Promise((resolve11) => {
13663
- this.permissionResolvers.push(resolve11);
13707
+ const approved = await new Promise((resolve12) => {
13708
+ this.permissionResolvers.push(resolve12);
13664
13709
  setTimeout(() => {
13665
- const idx = this.permissionResolvers.indexOf(resolve11);
13710
+ const idx = this.permissionResolvers.indexOf(resolve12);
13666
13711
  if (idx >= 0) {
13667
13712
  this.permissionResolvers.splice(idx, 1);
13668
- resolve11(false);
13713
+ resolve12(false);
13669
13714
  }
13670
13715
  }, 3e5);
13671
13716
  });
@@ -15207,10 +15252,75 @@ var ProviderLoader = class _ProviderLoader {
15207
15252
  }
15208
15253
  static GITHUB_TARBALL_URL = "https://github.com/vilmire/adhdev-providers/archive/refs/heads/main.tar.gz";
15209
15254
  static META_FILE = ".meta.json";
15255
+ static REPO_PROVIDER_DIRNAME = "adhdev-providers";
15256
+ static SIBLING_MARKER_FILE = ".adhdev-provider-root";
15257
+ static SIBLING_ENV_VAR = "ADHDEV_USE_SIBLING_PROVIDERS";
15258
+ probeStarts = [];
15259
+ siblingLogged = false;
15260
+ userDirSource = "home-default";
15261
+ /** Process-level dedup for stderr sibling-adoption notices (shared across all ProviderLoader instances). */
15262
+ static siblingStderrLogged = /* @__PURE__ */ new Set();
15263
+ static looksLikeProviderRoot(candidate) {
15264
+ try {
15265
+ if (!fs6.existsSync(candidate) || !fs6.statSync(candidate).isDirectory()) return false;
15266
+ return ["ide", "extension", "cli", "acp"].some(
15267
+ (category) => fs6.existsSync(path13.join(candidate, category))
15268
+ );
15269
+ } catch {
15270
+ return false;
15271
+ }
15272
+ }
15273
+ static hasProviderRootMarker(candidate) {
15274
+ try {
15275
+ return fs6.existsSync(path13.join(candidate, _ProviderLoader.SIBLING_MARKER_FILE));
15276
+ } catch {
15277
+ return false;
15278
+ }
15279
+ }
15280
+ detectDefaultUserDir() {
15281
+ const fallback = path13.join(os13.homedir(), ".adhdev", "providers");
15282
+ const envOptIn = process.env[_ProviderLoader.SIBLING_ENV_VAR] === "1";
15283
+ const visited = /* @__PURE__ */ new Set();
15284
+ for (const start of this.probeStarts) {
15285
+ let current = path13.resolve(start);
15286
+ while (!visited.has(current)) {
15287
+ visited.add(current);
15288
+ const siblingCandidate = path13.join(path13.dirname(current), _ProviderLoader.REPO_PROVIDER_DIRNAME);
15289
+ if (_ProviderLoader.looksLikeProviderRoot(siblingCandidate)) {
15290
+ const hasMarker = _ProviderLoader.hasProviderRootMarker(siblingCandidate);
15291
+ if (envOptIn || hasMarker) {
15292
+ const source = hasMarker ? "sibling-marker" : "sibling-env";
15293
+ if (!this.siblingLogged) {
15294
+ this.log(`Using sibling provider checkout (${source}): ${siblingCandidate}`);
15295
+ this.siblingLogged = true;
15296
+ }
15297
+ if (!_ProviderLoader.siblingStderrLogged.has(siblingCandidate)) {
15298
+ _ProviderLoader.siblingStderrLogged.add(siblingCandidate);
15299
+ try {
15300
+ process.stderr.write(
15301
+ `[adhdev] Using sibling adhdev-providers checkout (${source}): ${siblingCandidate}
15302
+ `
15303
+ );
15304
+ } catch {
15305
+ }
15306
+ }
15307
+ return { path: siblingCandidate, source };
15308
+ }
15309
+ }
15310
+ const parent = path13.dirname(current);
15311
+ if (parent === current) break;
15312
+ current = parent;
15313
+ }
15314
+ }
15315
+ return { path: fallback, source: "home-default" };
15316
+ }
15210
15317
  constructor(options) {
15211
15318
  this.logFn = options?.logFn || LOG.forComponent("Provider").asLogFn();
15319
+ this.probeStarts = options?.probeStarts ?? [process.cwd(), __dirname];
15212
15320
  this.defaultProvidersDir = path13.join(os13.homedir(), ".adhdev", "providers");
15213
- this.userDir = this.defaultProvidersDir;
15321
+ const detected = this.detectDefaultUserDir();
15322
+ this.userDir = detected.path;
15323
+ this.userDirSource = detected.source;
15214
15324
  this.upstreamDir = path13.join(this.defaultProvidersDir, ".upstream");
15215
15325
  this.disableUpstream = false;
15216
15326
  this.applySourceConfig({
@@ -15248,6 +15358,7 @@ var ProviderLoader = class _ProviderLoader {
15248
15358
  disableUpstream: this.disableUpstream,
15249
15359
  explicitProviderDir: this.explicitProviderDir,
15250
15360
  userDir: this.userDir,
15361
+ userDirSource: this.userDirSource,
15251
15362
  upstreamDir: this.upstreamDir,
15252
15363
  providerRoots: this.getProviderRoots()
15253
15364
  };
@@ -15258,7 +15369,14 @@ var ProviderLoader = class _ProviderLoader {
15258
15369
  this.explicitProviderDir = options.userDir?.trim() ? options.userDir : null;
15259
15370
  }
15260
15371
  this.sourceMode = nextSourceMode;
15261
- this.userDir = this.explicitProviderDir || this.defaultProvidersDir;
15372
+ if (this.explicitProviderDir) {
15373
+ this.userDir = this.explicitProviderDir;
15374
+ this.userDirSource = "explicit";
15375
+ } else {
15376
+ const detected = this.detectDefaultUserDir();
15377
+ this.userDir = detected.path;
15378
+ this.userDirSource = detected.source;
15379
+ }
15262
15380
  this.upstreamDir = path13.join(this.defaultProvidersDir, ".upstream");
15263
15381
  this.disableUpstream = this.sourceMode === "no-upstream";
15264
15382
  if (this.explicitProviderDir) {
@@ -15852,7 +15970,7 @@ var ProviderLoader = class _ProviderLoader {
15852
15970
  return { updated: false };
15853
15971
  }
15854
15972
  try {
15855
- const etag = await new Promise((resolve11, reject) => {
15973
+ const etag = await new Promise((resolve12, reject) => {
15856
15974
  const options = {
15857
15975
  method: "HEAD",
15858
15976
  hostname: "github.com",
@@ -15870,7 +15988,7 @@ var ProviderLoader = class _ProviderLoader {
15870
15988
  headers: { "User-Agent": "adhdev-launcher" },
15871
15989
  timeout: 1e4
15872
15990
  }, (res2) => {
15873
- resolve11(res2.headers.etag || res2.headers["last-modified"] || "");
15991
+ resolve12(res2.headers.etag || res2.headers["last-modified"] || "");
15874
15992
  });
15875
15993
  req2.on("error", reject);
15876
15994
  req2.on("timeout", () => {
@@ -15879,7 +15997,7 @@ var ProviderLoader = class _ProviderLoader {
15879
15997
  });
15880
15998
  req2.end();
15881
15999
  } else {
15882
- resolve11(res.headers.etag || res.headers["last-modified"] || "");
16000
+ resolve12(res.headers.etag || res.headers["last-modified"] || "");
15883
16001
  }
15884
16002
  });
15885
16003
  req.on("error", reject);
@@ -15943,7 +16061,7 @@ var ProviderLoader = class _ProviderLoader {
15943
16061
  downloadFile(url, destPath) {
15944
16062
  const https = __require("https");
15945
16063
  const http3 = __require("http");
15946
- return new Promise((resolve11, reject) => {
16064
+ return new Promise((resolve12, reject) => {
15947
16065
  const doRequest = (reqUrl, redirectCount = 0) => {
15948
16066
  if (redirectCount > 5) {
15949
16067
  reject(new Error("Too many redirects"));
@@ -15963,7 +16081,7 @@ var ProviderLoader = class _ProviderLoader {
15963
16081
  res.pipe(ws);
15964
16082
  ws.on("finish", () => {
15965
16083
  ws.close();
15966
- resolve11();
16084
+ resolve12();
15967
16085
  });
15968
16086
  ws.on("error", reject);
15969
16087
  });
@@ -16438,17 +16556,17 @@ async function findFreePort(ports) {
16438
16556
  throw new Error("No free port found");
16439
16557
  }
16440
16558
  function checkPortFree(port) {
16441
- return new Promise((resolve11) => {
16559
+ return new Promise((resolve12) => {
16442
16560
  const server = net.createServer();
16443
16561
  server.unref();
16444
- server.on("error", () => resolve11(false));
16562
+ server.on("error", () => resolve12(false));
16445
16563
  server.listen(port, "127.0.0.1", () => {
16446
- server.close(() => resolve11(true));
16564
+ server.close(() => resolve12(true));
16447
16565
  });
16448
16566
  });
16449
16567
  }
16450
16568
  async function isCdpActive(port) {
16451
- return new Promise((resolve11) => {
16569
+ return new Promise((resolve12) => {
16452
16570
  const req = __require("http").get(`http://127.0.0.1:${port}/json/version`, {
16453
16571
  timeout: 2e3
16454
16572
  }, (res) => {
@@ -16457,16 +16575,16 @@ async function isCdpActive(port) {
16457
16575
  res.on("end", () => {
16458
16576
  try {
16459
16577
  const info = JSON.parse(data);
16460
- resolve11(!!info["WebKit-Version"] || !!info["Browser"]);
16578
+ resolve12(!!info["WebKit-Version"] || !!info["Browser"]);
16461
16579
  } catch {
16462
- resolve11(false);
16580
+ resolve12(false);
16463
16581
  }
16464
16582
  });
16465
16583
  });
16466
- req.on("error", () => resolve11(false));
16584
+ req.on("error", () => resolve12(false));
16467
16585
  req.on("timeout", () => {
16468
16586
  req.destroy();
16469
- resolve11(false);
16587
+ resolve12(false);
16470
16588
  });
16471
16589
  });
16472
16590
  }
@@ -17258,7 +17376,7 @@ async function waitForPidExit(pid, timeoutMs) {
17258
17376
  while (Date.now() - start < timeoutMs) {
17259
17377
  try {
17260
17378
  process.kill(pid, 0);
17261
- await new Promise((resolve11) => setTimeout(resolve11, 250));
17379
+ await new Promise((resolve12) => setTimeout(resolve12, 250));
17262
17380
  } catch {
17263
17381
  return;
17264
17382
  }
@@ -17373,7 +17491,7 @@ async function runDaemonUpgradeHelper(payload) {
17373
17491
  appendUpgradeLog(installOutput.trim());
17374
17492
  }
17375
17493
  if (process.platform === "win32") {
17376
- await new Promise((resolve11) => setTimeout(resolve11, 500));
17494
+ await new Promise((resolve12) => setTimeout(resolve12, 500));
17377
17495
  cleanupStaleGlobalInstallDirs(payload.packageName);
17378
17496
  appendUpgradeLog("Post-install staging cleanup complete");
17379
17497
  }
@@ -18715,7 +18833,7 @@ var ProviderStreamAdapter = class {
18715
18833
  const beforeCount = this.messageCount(before);
18716
18834
  const beforeSignature = this.lastMessageSignature(before);
18717
18835
  for (let attempt = 0; attempt < 12; attempt += 1) {
18718
- await new Promise((resolve11) => setTimeout(resolve11, 250));
18836
+ await new Promise((resolve12) => setTimeout(resolve12, 250));
18719
18837
  let state;
18720
18838
  try {
18721
18839
  state = await this.readChat(evaluate);
@@ -18737,7 +18855,7 @@ var ProviderStreamAdapter = class {
18737
18855
  if (this.messageCount(first) > 0 || this.lastMessageSignature(first)) {
18738
18856
  return first;
18739
18857
  }
18740
- await new Promise((resolve11) => setTimeout(resolve11, 150));
18858
+ await new Promise((resolve12) => setTimeout(resolve12, 150));
18741
18859
  const second = await this.readChat(evaluate);
18742
18860
  return this.messageCount(second) >= this.messageCount(first) ? second : first;
18743
18861
  }
@@ -18888,7 +19006,7 @@ var ProviderStreamAdapter = class {
18888
19006
  if (typeof data.error === "string" && data.error.trim()) return false;
18889
19007
  }
18890
19008
  for (let attempt = 0; attempt < 6; attempt += 1) {
18891
- await new Promise((resolve11) => setTimeout(resolve11, 250));
19009
+ await new Promise((resolve12) => setTimeout(resolve12, 250));
18892
19010
  const state = await this.readChat(evaluate);
18893
19011
  const title = this.getStateTitle(state);
18894
19012
  if (this.titlesMatch(title, sessionId)) return true;
@@ -21414,7 +21532,7 @@ function getCliTargetBundle(ctx, type, instanceId) {
21414
21532
  return { target, instance, adapter };
21415
21533
  }
21416
21534
  function sleep(ms) {
21417
- return new Promise((resolve11) => setTimeout(resolve11, ms));
21535
+ return new Promise((resolve12) => setTimeout(resolve12, ms));
21418
21536
  }
21419
21537
  async function waitForCliReady(ctx, type, instanceId, timeoutMs) {
21420
21538
  const startedAt = Date.now();
@@ -23672,15 +23790,15 @@ var DevServer = class _DevServer {
23672
23790
  this.json(res, 500, { error: e.message });
23673
23791
  }
23674
23792
  });
23675
- return new Promise((resolve11, reject) => {
23793
+ return new Promise((resolve12, reject) => {
23676
23794
  this.server.listen(port, "127.0.0.1", () => {
23677
23795
  this.log(`Dev server listening on http://127.0.0.1:${port}`);
23678
- resolve11();
23796
+ resolve12();
23679
23797
  });
23680
23798
  this.server.on("error", (e) => {
23681
23799
  if (e.code === "EADDRINUSE") {
23682
23800
  this.log(`Port ${port} in use, skipping dev server`);
23683
- resolve11();
23801
+ resolve12();
23684
23802
  } else {
23685
23803
  reject(e);
23686
23804
  }
@@ -23762,20 +23880,20 @@ var DevServer = class _DevServer {
23762
23880
  child.stderr?.on("data", (d) => {
23763
23881
  stderr += d.toString().slice(0, 2e3);
23764
23882
  });
23765
- await new Promise((resolve11) => {
23883
+ await new Promise((resolve12) => {
23766
23884
  const timer = setTimeout(() => {
23767
23885
  child.kill();
23768
- resolve11();
23886
+ resolve12();
23769
23887
  }, 3e3);
23770
23888
  child.on("exit", () => {
23771
23889
  clearTimeout(timer);
23772
- resolve11();
23890
+ resolve12();
23773
23891
  });
23774
23892
  child.stdout?.once("data", () => {
23775
23893
  setTimeout(() => {
23776
23894
  child.kill();
23777
23895
  clearTimeout(timer);
23778
- resolve11();
23896
+ resolve12();
23779
23897
  }, 500);
23780
23898
  });
23781
23899
  });
@@ -24291,14 +24409,14 @@ var DevServer = class _DevServer {
24291
24409
  child.stderr?.on("data", (d) => {
24292
24410
  stderr += d.toString();
24293
24411
  });
24294
- await new Promise((resolve11) => {
24412
+ await new Promise((resolve12) => {
24295
24413
  const timer = setTimeout(() => {
24296
24414
  child.kill();
24297
- resolve11();
24415
+ resolve12();
24298
24416
  }, timeout);
24299
24417
  child.on("exit", () => {
24300
24418
  clearTimeout(timer);
24301
- resolve11();
24419
+ resolve12();
24302
24420
  });
24303
24421
  });
24304
24422
  const elapsed = Date.now() - start;
@@ -24968,14 +25086,14 @@ data: ${JSON.stringify(msg.data)}
24968
25086
  res.end(JSON.stringify(data, null, 2));
24969
25087
  }
24970
25088
  async readBody(req) {
24971
- return new Promise((resolve11) => {
25089
+ return new Promise((resolve12) => {
24972
25090
  let body = "";
24973
25091
  req.on("data", (chunk) => body += chunk);
24974
25092
  req.on("end", () => {
24975
25093
  try {
24976
- resolve11(JSON.parse(body));
25094
+ resolve12(JSON.parse(body));
24977
25095
  } catch {
24978
- resolve11({});
25096
+ resolve12({});
24979
25097
  }
24980
25098
  });
24981
25099
  });
@@ -25488,7 +25606,7 @@ async function waitForReady(endpoint, timeoutMs = STARTUP_TIMEOUT_MS) {
25488
25606
  const deadline = Date.now() + timeoutMs;
25489
25607
  while (Date.now() < deadline) {
25490
25608
  if (await canConnect(endpoint)) return;
25491
- await new Promise((resolve11) => setTimeout(resolve11, STARTUP_POLL_MS));
25609
+ await new Promise((resolve12) => setTimeout(resolve12, STARTUP_POLL_MS));
25492
25610
  }
25493
25611
  throw new Error(`Session host did not become ready within ${timeoutMs}ms`);
25494
25612
  }
@@ -25666,10 +25784,10 @@ async function installExtension(ide, extension) {
25666
25784
  const buffer = Buffer.from(await res.arrayBuffer());
25667
25785
  const fs15 = await import("fs");
25668
25786
  fs15.writeFileSync(vsixPath, buffer);
25669
- return new Promise((resolve11) => {
25787
+ return new Promise((resolve12) => {
25670
25788
  const cmd = `"${ide.cliCommand}" --install-extension "${vsixPath}" --force`;
25671
25789
  exec2(cmd, { timeout: 6e4 }, (error, _stdout, stderr) => {
25672
- resolve11({
25790
+ resolve12({
25673
25791
  extensionId: extension.id,
25674
25792
  marketplaceId: extension.marketplaceId,
25675
25793
  success: !error,
@@ -25682,11 +25800,11 @@ async function installExtension(ide, extension) {
25682
25800
  } catch (e) {
25683
25801
  }
25684
25802
  }
25685
- return new Promise((resolve11) => {
25803
+ return new Promise((resolve12) => {
25686
25804
  const cmd = `"${ide.cliCommand}" --install-extension ${extension.marketplaceId} --force`;
25687
25805
  exec2(cmd, { timeout: 6e4 }, (error, stdout, stderr) => {
25688
25806
  if (error) {
25689
- resolve11({
25807
+ resolve12({
25690
25808
  extensionId: extension.id,
25691
25809
  marketplaceId: extension.marketplaceId,
25692
25810
  success: false,
@@ -25694,7 +25812,7 @@ async function installExtension(ide, extension) {
25694
25812
  error: stderr || error.message
25695
25813
  });
25696
25814
  } else {
25697
- resolve11({
25815
+ resolve12({
25698
25816
  extensionId: extension.id,
25699
25817
  marketplaceId: extension.marketplaceId,
25700
25818
  success: true,