@adhdev/daemon-core 0.8.56 → 0.8.58

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.
Files changed (35) hide show
  1. package/dist/boot/daemon-lifecycle.d.ts +1 -0
  2. package/dist/commands/handler.d.ts +1 -0
  3. package/dist/commands/stream-commands.d.ts +2 -0
  4. package/dist/config/chat-history.d.ts +3 -0
  5. package/dist/config/config.d.ts +3 -0
  6. package/dist/config/provider-source-config.d.ts +23 -0
  7. package/dist/daemon/dev-server-types.d.ts +1 -0
  8. package/dist/daemon/dev-server.d.ts +4 -0
  9. package/dist/index.d.ts +2 -0
  10. package/dist/index.js +316 -155
  11. package/dist/index.js.map +1 -1
  12. package/dist/index.mjs +315 -155
  13. package/dist/index.mjs.map +1 -1
  14. package/dist/providers/cli-provider-instance.d.ts +9 -0
  15. package/dist/providers/contracts.d.ts +1 -0
  16. package/dist/providers/provider-loader.d.ts +14 -1
  17. package/node_modules/@adhdev/session-host-core/package.json +1 -1
  18. package/package.json +1 -1
  19. package/src/boot/daemon-lifecycle.ts +13 -3
  20. package/src/commands/handler.ts +3 -0
  21. package/src/commands/router.ts +5 -4
  22. package/src/commands/stream-commands.ts +41 -0
  23. package/src/config/chat-history.ts +39 -0
  24. package/src/config/config.d.ts +3 -0
  25. package/src/config/config.ts +19 -3
  26. package/src/config/provider-source-config.ts +42 -0
  27. package/src/daemon/dev-auto-implement.ts +0 -13
  28. package/src/daemon/dev-server-types.ts +1 -0
  29. package/src/daemon/dev-server.ts +45 -20
  30. package/src/index.ts +2 -0
  31. package/src/providers/cli-provider-instance.ts +25 -0
  32. package/src/providers/contracts.ts +1 -0
  33. package/src/providers/provider-loader.d.ts +4 -1
  34. package/src/providers/provider-loader.ts +61 -23
  35. package/src/providers/provider-schema.ts +3 -0
package/dist/index.js CHANGED
@@ -40,9 +40,16 @@ __export(config_exports, {
40
40
  loadConfig: () => loadConfig,
41
41
  markSetupComplete: () => markSetupComplete,
42
42
  resetConfig: () => resetConfig,
43
+ resolveProviderSourceMode: () => resolveProviderSourceMode,
43
44
  saveConfig: () => saveConfig,
44
45
  updateConfig: () => updateConfig
45
46
  });
47
+ function resolveProviderSourceMode(providerSourceMode, legacyDisableUpstream) {
48
+ if (providerSourceMode === "normal" || providerSourceMode === "no-upstream") {
49
+ return providerSourceMode;
50
+ }
51
+ return legacyDisableUpstream === true ? "no-upstream" : "normal";
52
+ }
46
53
  function isPlainObject(value) {
47
54
  return !!value && typeof value === "object" && !Array.isArray(value);
48
55
  }
@@ -80,7 +87,7 @@ function normalizeConfig(raw) {
80
87
  registeredMachineId: asOptionalString(parsed.registeredMachineId),
81
88
  providerSettings: isPlainObject(parsed.providerSettings) ? parsed.providerSettings : {},
82
89
  ideSettings: isPlainObject(parsed.ideSettings) ? parsed.ideSettings : {},
83
- disableUpstream: asBoolean(parsed.disableUpstream, DEFAULT_CONFIG.disableUpstream ?? false),
90
+ providerSourceMode: resolveProviderSourceMode(parsed.providerSourceMode, parsed.disableUpstream),
84
91
  providerDir: asOptionalString(parsed.providerDir),
85
92
  terminalSizingMode: parsed.terminalSizingMode === "fit" ? "fit" : "measured"
86
93
  };
@@ -229,7 +236,7 @@ var init_config = __esm({
229
236
  registeredMachineId: void 0,
230
237
  providerSettings: {},
231
238
  ideSettings: {},
232
- disableUpstream: false,
239
+ providerSourceMode: "normal",
233
240
  terminalSizingMode: "measured"
234
241
  };
235
242
  MACHINE_ID_PREFIX = "mach_";
@@ -1897,7 +1904,7 @@ var init_provider_cli_adapter = __esm({
1897
1904
  `[${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)}`
1898
1905
  );
1899
1906
  }
1900
- await new Promise((resolve12) => setTimeout(resolve12, 50));
1907
+ await new Promise((resolve11) => setTimeout(resolve11, 50));
1901
1908
  }
1902
1909
  const finalScreenText = this.terminalScreen.getText() || "";
1903
1910
  LOG.warn(
@@ -2470,7 +2477,7 @@ ${data.message || ""}`.trim();
2470
2477
  const deadline = Date.now() + 1e4;
2471
2478
  while (this.startupParseGate && Date.now() < deadline) {
2472
2479
  this.resolveStartupState("send_wait");
2473
- await new Promise((resolve12) => setTimeout(resolve12, 50));
2480
+ await new Promise((resolve11) => setTimeout(resolve11, 50));
2474
2481
  }
2475
2482
  }
2476
2483
  await this.waitForInteractivePrompt();
@@ -2540,12 +2547,12 @@ ${data.message || ""}`.trim();
2540
2547
  if (this.isWaitingForResponse) this.finishResponse();
2541
2548
  }, this.timeouts.maxResponse);
2542
2549
  };
2543
- await new Promise((resolve12) => {
2550
+ await new Promise((resolve11) => {
2544
2551
  let resolved = false;
2545
2552
  const resolveOnce = () => {
2546
2553
  if (resolved) return;
2547
2554
  resolved = true;
2548
- resolve12();
2555
+ resolve11();
2549
2556
  };
2550
2557
  const submit = () => {
2551
2558
  if (!this.ptyProcess) {
@@ -2719,17 +2726,17 @@ ${data.message || ""}`.trim();
2719
2726
  }
2720
2727
  }
2721
2728
  waitForStopped(timeoutMs) {
2722
- return new Promise((resolve12) => {
2729
+ return new Promise((resolve11) => {
2723
2730
  const startedAt = Date.now();
2724
2731
  const timer = setInterval(() => {
2725
2732
  if (!this.ptyProcess || this.currentStatus === "stopped") {
2726
2733
  clearInterval(timer);
2727
- resolve12(true);
2734
+ resolve11(true);
2728
2735
  return;
2729
2736
  }
2730
2737
  if (Date.now() - startedAt >= timeoutMs) {
2731
2738
  clearInterval(timer);
2732
- resolve12(false);
2739
+ resolve11(false);
2733
2740
  }
2734
2741
  }, 100);
2735
2742
  });
@@ -3084,6 +3091,7 @@ __export(index_exports, {
3084
3091
  normalizeInputEnvelope: () => normalizeInputEnvelope,
3085
3092
  normalizeManagedStatus: () => normalizeManagedStatus,
3086
3093
  normalizeMessageParts: () => normalizeMessageParts,
3094
+ parseProviderSourceConfigUpdate: () => parseProviderSourceConfigUpdate,
3087
3095
  partitionSessionHostDiagnosticsSessions: () => partitionSessionHostDiagnosticsSessions,
3088
3096
  partitionSessionHostRecords: () => partitionSessionHostRecords,
3089
3097
  probeCdpPort: () => probeCdpPort,
@@ -3576,15 +3584,15 @@ function resolveCommandPath(command) {
3576
3584
  return null;
3577
3585
  }
3578
3586
  function execAsync(cmd, timeoutMs = 5e3) {
3579
- return new Promise((resolve12) => {
3587
+ return new Promise((resolve11) => {
3580
3588
  const child = (0, import_child_process2.exec)(cmd, { encoding: "utf-8", timeout: timeoutMs }, (err, stdout) => {
3581
3589
  if (err || !stdout?.trim()) {
3582
- resolve12(null);
3590
+ resolve11(null);
3583
3591
  } else {
3584
- resolve12(stdout.trim());
3592
+ resolve11(stdout.trim());
3585
3593
  }
3586
3594
  });
3587
- child.on("error", () => resolve12(null));
3595
+ child.on("error", () => resolve11(null));
3588
3596
  });
3589
3597
  }
3590
3598
  async function detectCLIs(providerLoader, options) {
@@ -3795,7 +3803,7 @@ var DaemonCdpManager = class {
3795
3803
  * Returns multiple entries if multiple IDE windows are open on same port
3796
3804
  */
3797
3805
  static listAllTargets(port) {
3798
- return new Promise((resolve12) => {
3806
+ return new Promise((resolve11) => {
3799
3807
  const req = http.get(`http://127.0.0.1:${port}/json`, (res) => {
3800
3808
  let data = "";
3801
3809
  res.on("data", (chunk) => data += chunk.toString());
@@ -3811,16 +3819,16 @@ var DaemonCdpManager = class {
3811
3819
  (t) => !isNonMain(t.title || "") && t.url?.includes("workbench.html") && !t.url?.includes("agent")
3812
3820
  );
3813
3821
  const fallbackPages = pages.filter((t) => !isNonMain(t.title || ""));
3814
- resolve12(mainPages.length > 0 ? mainPages : fallbackPages);
3822
+ resolve11(mainPages.length > 0 ? mainPages : fallbackPages);
3815
3823
  } catch {
3816
- resolve12([]);
3824
+ resolve11([]);
3817
3825
  }
3818
3826
  });
3819
3827
  });
3820
- req.on("error", () => resolve12([]));
3828
+ req.on("error", () => resolve11([]));
3821
3829
  req.setTimeout(2e3, () => {
3822
3830
  req.destroy();
3823
- resolve12([]);
3831
+ resolve11([]);
3824
3832
  });
3825
3833
  });
3826
3834
  }
@@ -3860,7 +3868,7 @@ var DaemonCdpManager = class {
3860
3868
  }
3861
3869
  }
3862
3870
  findTargetOnPort(port) {
3863
- return new Promise((resolve12) => {
3871
+ return new Promise((resolve11) => {
3864
3872
  const req = http.get(`http://127.0.0.1:${port}/json`, (res) => {
3865
3873
  let data = "";
3866
3874
  res.on("data", (chunk) => data += chunk.toString());
@@ -3871,7 +3879,7 @@ var DaemonCdpManager = class {
3871
3879
  (t) => (t.type === "page" || t.type === "browser" || t.type === "Page") && t.webSocketDebuggerUrl
3872
3880
  );
3873
3881
  if (pages.length === 0) {
3874
- resolve12(targets.find((t) => t.webSocketDebuggerUrl) || null);
3882
+ resolve11(targets.find((t) => t.webSocketDebuggerUrl) || null);
3875
3883
  return;
3876
3884
  }
3877
3885
  const mainPages = pages.filter((t) => !this.isNonMainTitle(t.title || ""));
@@ -3881,24 +3889,24 @@ var DaemonCdpManager = class {
3881
3889
  const specific = list.find((t) => t.id === this._targetId);
3882
3890
  if (specific) {
3883
3891
  this._pageTitle = specific.title || "";
3884
- resolve12(specific);
3892
+ resolve11(specific);
3885
3893
  } else {
3886
3894
  this.log(`[CDP] Target ${this._targetId} not found in page list`);
3887
- resolve12(null);
3895
+ resolve11(null);
3888
3896
  }
3889
3897
  return;
3890
3898
  }
3891
3899
  this._pageTitle = list[0]?.title || "";
3892
- resolve12(list[0]);
3900
+ resolve11(list[0]);
3893
3901
  } catch {
3894
- resolve12(null);
3902
+ resolve11(null);
3895
3903
  }
3896
3904
  });
3897
3905
  });
3898
- req.on("error", () => resolve12(null));
3906
+ req.on("error", () => resolve11(null));
3899
3907
  req.setTimeout(2e3, () => {
3900
3908
  req.destroy();
3901
- resolve12(null);
3909
+ resolve11(null);
3902
3910
  });
3903
3911
  });
3904
3912
  }
@@ -3909,7 +3917,7 @@ var DaemonCdpManager = class {
3909
3917
  this.extensionProviders = providers;
3910
3918
  }
3911
3919
  connectToTarget(wsUrl) {
3912
- return new Promise((resolve12) => {
3920
+ return new Promise((resolve11) => {
3913
3921
  this.ws = new import_ws.default(wsUrl);
3914
3922
  this.ws.on("open", async () => {
3915
3923
  this._connected = true;
@@ -3919,17 +3927,17 @@ var DaemonCdpManager = class {
3919
3927
  }
3920
3928
  this.connectBrowserWs().catch(() => {
3921
3929
  });
3922
- resolve12(true);
3930
+ resolve11(true);
3923
3931
  });
3924
3932
  this.ws.on("message", (data) => {
3925
3933
  try {
3926
3934
  const msg = JSON.parse(data.toString());
3927
3935
  if (msg.id && this.pending.has(msg.id)) {
3928
- const { resolve: resolve13, reject } = this.pending.get(msg.id);
3936
+ const { resolve: resolve12, reject } = this.pending.get(msg.id);
3929
3937
  this.pending.delete(msg.id);
3930
3938
  this.failureCount = 0;
3931
3939
  if (msg.error) reject(new Error(msg.error.message));
3932
- else resolve13(msg.result);
3940
+ else resolve12(msg.result);
3933
3941
  } else if (msg.method === "Runtime.executionContextCreated") {
3934
3942
  this.contexts.add(msg.params.context.id);
3935
3943
  } else if (msg.method === "Runtime.executionContextDestroyed") {
@@ -3952,7 +3960,7 @@ var DaemonCdpManager = class {
3952
3960
  this.ws.on("error", (err) => {
3953
3961
  this.log(`[CDP] WebSocket error: ${err.message}`);
3954
3962
  this._connected = false;
3955
- resolve12(false);
3963
+ resolve11(false);
3956
3964
  });
3957
3965
  });
3958
3966
  }
@@ -3966,7 +3974,7 @@ var DaemonCdpManager = class {
3966
3974
  return;
3967
3975
  }
3968
3976
  this.log(`[CDP] Connecting browser WS for target discovery...`);
3969
- await new Promise((resolve12, reject) => {
3977
+ await new Promise((resolve11, reject) => {
3970
3978
  this.browserWs = new import_ws.default(browserWsUrl);
3971
3979
  this.browserWs.on("open", async () => {
3972
3980
  this._browserConnected = true;
@@ -3976,16 +3984,16 @@ var DaemonCdpManager = class {
3976
3984
  } catch (e) {
3977
3985
  this.log(`[CDP] setDiscoverTargets failed: ${e.message}`);
3978
3986
  }
3979
- resolve12();
3987
+ resolve11();
3980
3988
  });
3981
3989
  this.browserWs.on("message", (data) => {
3982
3990
  try {
3983
3991
  const msg = JSON.parse(data.toString());
3984
3992
  if (msg.id && this.browserPending.has(msg.id)) {
3985
- const { resolve: resolve13, reject: reject2 } = this.browserPending.get(msg.id);
3993
+ const { resolve: resolve12, reject: reject2 } = this.browserPending.get(msg.id);
3986
3994
  this.browserPending.delete(msg.id);
3987
3995
  if (msg.error) reject2(new Error(msg.error.message));
3988
- else resolve13(msg.result);
3996
+ else resolve12(msg.result);
3989
3997
  }
3990
3998
  } catch {
3991
3999
  }
@@ -4005,31 +4013,31 @@ var DaemonCdpManager = class {
4005
4013
  }
4006
4014
  }
4007
4015
  getBrowserWsUrl() {
4008
- return new Promise((resolve12) => {
4016
+ return new Promise((resolve11) => {
4009
4017
  const req = http.get(`http://127.0.0.1:${this.port}/json/version`, (res) => {
4010
4018
  let data = "";
4011
4019
  res.on("data", (chunk) => data += chunk.toString());
4012
4020
  res.on("end", () => {
4013
4021
  try {
4014
4022
  const info = JSON.parse(data);
4015
- resolve12(info.webSocketDebuggerUrl || null);
4023
+ resolve11(info.webSocketDebuggerUrl || null);
4016
4024
  } catch {
4017
- resolve12(null);
4025
+ resolve11(null);
4018
4026
  }
4019
4027
  });
4020
4028
  });
4021
- req.on("error", () => resolve12(null));
4029
+ req.on("error", () => resolve11(null));
4022
4030
  req.setTimeout(3e3, () => {
4023
4031
  req.destroy();
4024
- resolve12(null);
4032
+ resolve11(null);
4025
4033
  });
4026
4034
  });
4027
4035
  }
4028
4036
  sendBrowser(method, params = {}, timeoutMs = 15e3) {
4029
- return new Promise((resolve12, reject) => {
4037
+ return new Promise((resolve11, reject) => {
4030
4038
  if (!this.browserWs || !this._browserConnected) return reject(new Error("Browser WS not connected"));
4031
4039
  const id = this.browserMsgId++;
4032
- this.browserPending.set(id, { resolve: resolve12, reject });
4040
+ this.browserPending.set(id, { resolve: resolve11, reject });
4033
4041
  this.browserWs.send(JSON.stringify({ id, method, params }));
4034
4042
  setTimeout(() => {
4035
4043
  if (this.browserPending.has(id)) {
@@ -4069,11 +4077,11 @@ var DaemonCdpManager = class {
4069
4077
  }
4070
4078
  // ─── CDP Protocol ────────────────────────────────────────
4071
4079
  sendInternal(method, params = {}, timeoutMs = 15e3) {
4072
- return new Promise((resolve12, reject) => {
4080
+ return new Promise((resolve11, reject) => {
4073
4081
  if (!this.ws || !this._connected) return reject(new Error("CDP not connected"));
4074
4082
  if (this.ws.readyState !== import_ws.default.OPEN) return reject(new Error("WebSocket not open"));
4075
4083
  const id = this.msgId++;
4076
- this.pending.set(id, { resolve: resolve12, reject });
4084
+ this.pending.set(id, { resolve: resolve11, reject });
4077
4085
  this.ws.send(JSON.stringify({ id, method, params }));
4078
4086
  setTimeout(() => {
4079
4087
  if (this.pending.has(id)) {
@@ -4322,7 +4330,7 @@ var DaemonCdpManager = class {
4322
4330
  const browserWs = this.browserWs;
4323
4331
  let msgId = this.browserMsgId;
4324
4332
  const sendWs = (method, params = {}, sessionId) => {
4325
- return new Promise((resolve12, reject) => {
4333
+ return new Promise((resolve11, reject) => {
4326
4334
  const mid = msgId++;
4327
4335
  this.browserMsgId = msgId;
4328
4336
  const handler = (raw) => {
@@ -4331,7 +4339,7 @@ var DaemonCdpManager = class {
4331
4339
  if (msg.id === mid) {
4332
4340
  browserWs.removeListener("message", handler);
4333
4341
  if (msg.error) reject(new Error(msg.error.message || JSON.stringify(msg.error)));
4334
- else resolve12(msg.result);
4342
+ else resolve11(msg.result);
4335
4343
  }
4336
4344
  } catch {
4337
4345
  }
@@ -4532,14 +4540,14 @@ var DaemonCdpManager = class {
4532
4540
  if (!ws || ws.readyState !== import_ws.default.OPEN) {
4533
4541
  throw new Error("CDP not connected");
4534
4542
  }
4535
- return new Promise((resolve12, reject) => {
4543
+ return new Promise((resolve11, reject) => {
4536
4544
  const id = getNextId();
4537
4545
  pendingMap.set(id, {
4538
4546
  resolve: (result) => {
4539
4547
  if (result?.result?.subtype === "error") {
4540
4548
  reject(new Error(result.result.description));
4541
4549
  } else {
4542
- resolve12(result?.result?.value);
4550
+ resolve11(result?.result?.value);
4543
4551
  }
4544
4552
  },
4545
4553
  reject
@@ -4571,10 +4579,10 @@ var DaemonCdpManager = class {
4571
4579
  throw new Error("CDP not connected");
4572
4580
  }
4573
4581
  const sendViaSession = (method, params = {}) => {
4574
- return new Promise((resolve12, reject) => {
4582
+ return new Promise((resolve11, reject) => {
4575
4583
  const pendingMap = this._browserConnected ? this.browserPending : this.pending;
4576
4584
  const id = this._browserConnected ? this.browserMsgId++ : this.msgId++;
4577
- pendingMap.set(id, { resolve: resolve12, reject });
4585
+ pendingMap.set(id, { resolve: resolve11, reject });
4578
4586
  ws.send(JSON.stringify({ id, sessionId, method, params }));
4579
4587
  setTimeout(() => {
4580
4588
  if (pendingMap.has(id)) {
@@ -5484,6 +5492,30 @@ var ChatHistoryWriter = class {
5484
5492
  options.historySessionId
5485
5493
  );
5486
5494
  }
5495
+ writeSessionStart(agentType, historySessionId, workspace, instanceId) {
5496
+ const id = String(historySessionId || "").trim();
5497
+ const ws = String(workspace || "").trim();
5498
+ if (!id || !ws) return;
5499
+ try {
5500
+ const dir = path7.join(HISTORY_DIR, this.sanitize(agentType));
5501
+ fs3.mkdirSync(dir, { recursive: true });
5502
+ const date = (/* @__PURE__ */ new Date()).toISOString().slice(0, 10);
5503
+ const filePath = path7.join(dir, `${this.sanitize(id)}_${date}.jsonl`);
5504
+ const record = {
5505
+ ts: (/* @__PURE__ */ new Date()).toISOString(),
5506
+ receivedAt: Date.now(),
5507
+ role: "system",
5508
+ kind: "session_start",
5509
+ content: ws,
5510
+ agent: agentType,
5511
+ instanceId,
5512
+ historySessionId: id,
5513
+ workspace: ws
5514
+ };
5515
+ fs3.appendFileSync(filePath, JSON.stringify(record) + "\n", "utf-8");
5516
+ } catch {
5517
+ }
5518
+ }
5487
5519
  promoteHistorySession(agentType, previousHistorySessionId, nextHistorySessionId) {
5488
5520
  const fromId = String(previousHistorySessionId || "").trim();
5489
5521
  const toId = String(nextHistorySessionId || "").trim();
@@ -5703,6 +5735,7 @@ function listSavedHistorySessions(agentType, options = {}) {
5703
5735
  let lastMessageAt = 0;
5704
5736
  let sessionTitle = "";
5705
5737
  let preview = "";
5738
+ let workspace = "";
5706
5739
  for (const file of files.sort()) {
5707
5740
  const filePath = path7.join(dir, file);
5708
5741
  const content = fs3.readFileSync(filePath, "utf-8");
@@ -5715,6 +5748,10 @@ function listSavedHistorySessions(agentType, options = {}) {
5715
5748
  parsed = null;
5716
5749
  }
5717
5750
  if (!parsed || parsed.historySessionId !== historySessionId) continue;
5751
+ if (parsed.kind === "session_start") {
5752
+ if (!workspace && parsed.workspace) workspace = parsed.workspace;
5753
+ continue;
5754
+ }
5718
5755
  messageCount += 1;
5719
5756
  if (!firstMessageAt || parsed.receivedAt < firstMessageAt) firstMessageAt = parsed.receivedAt;
5720
5757
  if (!lastMessageAt || parsed.receivedAt > lastMessageAt) lastMessageAt = parsed.receivedAt;
@@ -5729,7 +5766,8 @@ function listSavedHistorySessions(agentType, options = {}) {
5729
5766
  messageCount,
5730
5767
  firstMessageAt,
5731
5768
  lastMessageAt,
5732
- preview: preview || void 0
5769
+ preview: preview || void 0,
5770
+ workspace: workspace || void 0
5733
5771
  });
5734
5772
  }
5735
5773
  summaries.sort((a, b) => b.lastMessageAt - a.lastMessageAt);
@@ -8104,7 +8142,7 @@ function getStateLastSignature(state) {
8104
8142
  async function getStableExtensionBaseline(h) {
8105
8143
  const first = await readExtensionChatState(h);
8106
8144
  if (getStateMessageCount(first) > 0 || getStateLastSignature(first)) return first;
8107
- await new Promise((resolve12) => setTimeout(resolve12, 150));
8145
+ await new Promise((resolve11) => setTimeout(resolve11, 150));
8108
8146
  const second = await readExtensionChatState(h);
8109
8147
  return getStateMessageCount(second) >= getStateMessageCount(first) ? second : first;
8110
8148
  }
@@ -8112,7 +8150,7 @@ async function verifyExtensionSendObserved(h, before) {
8112
8150
  const beforeCount = getStateMessageCount(before);
8113
8151
  const beforeSignature = getStateLastSignature(before);
8114
8152
  for (let attempt = 0; attempt < 12; attempt += 1) {
8115
- await new Promise((resolve12) => setTimeout(resolve12, 250));
8153
+ await new Promise((resolve11) => setTimeout(resolve11, 250));
8116
8154
  const state = await readExtensionChatState(h);
8117
8155
  if (state?.status === "waiting_approval") return true;
8118
8156
  const afterCount = getStateMessageCount(state);
@@ -9304,6 +9342,30 @@ async function handleFileListBrowse(h, args) {
9304
9342
  }
9305
9343
  }
9306
9344
 
9345
+ // src/commands/stream-commands.ts
9346
+ init_config();
9347
+
9348
+ // src/config/provider-source-config.ts
9349
+ function normalizeProviderDir(value) {
9350
+ if (typeof value !== "string") return void 0;
9351
+ const trimmed = value.trim();
9352
+ return trimmed ? trimmed : void 0;
9353
+ }
9354
+ function parseProviderSourceConfigUpdate(input) {
9355
+ const updates = {};
9356
+ if (Object.prototype.hasOwnProperty.call(input, "providerSourceMode")) {
9357
+ const { providerSourceMode } = input;
9358
+ if (providerSourceMode !== "normal" && providerSourceMode !== "no-upstream") {
9359
+ return { ok: false, error: "providerSourceMode must be 'normal' or 'no-upstream'" };
9360
+ }
9361
+ updates.providerSourceMode = providerSourceMode;
9362
+ }
9363
+ if (Object.prototype.hasOwnProperty.call(input, "providerDir")) {
9364
+ updates.providerDir = normalizeProviderDir(input.providerDir);
9365
+ }
9366
+ return { ok: true, updates };
9367
+ }
9368
+
9307
9369
  // src/providers/cli-script-results.ts
9308
9370
  function parseCliScriptResult(result) {
9309
9371
  if (typeof result === "string") {
@@ -9416,6 +9478,38 @@ async function handleSetProviderSetting(h, args) {
9416
9478
  }
9417
9479
  return { success: false, error: `Failed to set ${providerType}.${key} \u2014 invalid key, value, or not a public setting` };
9418
9480
  }
9481
+ function handleGetProviderSourceConfig(h, _args) {
9482
+ const loader = h.ctx.providerLoader;
9483
+ if (!loader) return { success: false, error: "providerLoader not available" };
9484
+ return { success: true, ...loader.getSourceConfig() };
9485
+ }
9486
+ async function handleSetProviderSourceConfig(h, args) {
9487
+ const loader = h.ctx.providerLoader;
9488
+ if (!loader) return { success: false, error: "providerLoader not available" };
9489
+ const parsed = parseProviderSourceConfigUpdate(args || {});
9490
+ if ("error" in parsed) {
9491
+ return { success: false, error: parsed.error };
9492
+ }
9493
+ const currentConfig2 = loadConfig();
9494
+ const nextConfig = {
9495
+ ...currentConfig2,
9496
+ ...parsed.updates.providerSourceMode ? { providerSourceMode: parsed.updates.providerSourceMode } : {},
9497
+ ...Object.prototype.hasOwnProperty.call(parsed.updates, "providerDir") ? { providerDir: parsed.updates.providerDir } : {}
9498
+ };
9499
+ saveConfig(nextConfig);
9500
+ const sourceConfig = loader.applySourceConfig({
9501
+ sourceMode: nextConfig.providerSourceMode,
9502
+ userDir: Object.prototype.hasOwnProperty.call(parsed.updates, "providerDir") ? parsed.updates.providerDir : loader.getSourceConfig().explicitProviderDir || void 0
9503
+ });
9504
+ loader.reload();
9505
+ loader.registerToDetector();
9506
+ await h.ctx.onProviderSourceConfigChanged?.();
9507
+ LOG.info(
9508
+ "Command",
9509
+ `[set_provider_source_config] mode=${sourceConfig.sourceMode} explicitProviderDir=${sourceConfig.explicitProviderDir || "-"} userDir=${sourceConfig.userDir}`
9510
+ );
9511
+ return { success: true, reloaded: true, ...sourceConfig };
9512
+ }
9419
9513
  function normalizeProviderScriptArgs(args) {
9420
9514
  const normalizedArgs = { ...args || {} };
9421
9515
  for (const key of ["mode", "model", "message", "action", "button", "text", "sessionId", "value"]) {
@@ -10109,6 +10203,10 @@ var DaemonCommandHandler = class {
10109
10203
  return handleGetProviderSettings(this, args);
10110
10204
  case "set_provider_setting":
10111
10205
  return handleSetProviderSetting(this, args);
10206
+ case "get_provider_source_config":
10207
+ return handleGetProviderSourceConfig(this, args);
10208
+ case "set_provider_source_config":
10209
+ return handleSetProviderSourceConfig(this, args);
10112
10210
  // ─── IDE Extension Settings (stream-commands.ts) ──────────
10113
10211
  case "get_ide_extensions":
10114
10212
  return handleGetIdeExtensions(this, args);
@@ -10148,7 +10246,7 @@ var DaemonCommandHandler = class {
10148
10246
  try {
10149
10247
  const http3 = await import("http");
10150
10248
  const postData = JSON.stringify(body);
10151
- const result = await new Promise((resolve12, reject) => {
10249
+ const result = await new Promise((resolve11, reject) => {
10152
10250
  const req = http3.request({
10153
10251
  hostname: "127.0.0.1",
10154
10252
  port: 19280,
@@ -10160,9 +10258,9 @@ var DaemonCommandHandler = class {
10160
10258
  res.on("data", (chunk) => data += chunk);
10161
10259
  res.on("end", () => {
10162
10260
  try {
10163
- resolve12(JSON.parse(data));
10261
+ resolve11(JSON.parse(data));
10164
10262
  } catch {
10165
- resolve12({ raw: data });
10263
+ resolve11({ raw: data });
10166
10264
  }
10167
10265
  });
10168
10266
  });
@@ -10180,15 +10278,15 @@ var DaemonCommandHandler = class {
10180
10278
  if (!providerType) return { success: false, error: "providerType required" };
10181
10279
  try {
10182
10280
  const http3 = await import("http");
10183
- const result = await new Promise((resolve12, reject) => {
10281
+ const result = await new Promise((resolve11, reject) => {
10184
10282
  http3.get(`http://127.0.0.1:19280/api/providers/${providerType}/${endpoint}`, (res) => {
10185
10283
  let data = "";
10186
10284
  res.on("data", (chunk) => data += chunk);
10187
10285
  res.on("end", () => {
10188
10286
  try {
10189
- resolve12(JSON.parse(data));
10287
+ resolve11(JSON.parse(data));
10190
10288
  } catch {
10191
- resolve12({ raw: data });
10289
+ resolve11({ raw: data });
10192
10290
  }
10193
10291
  });
10194
10292
  }).on("error", reject);
@@ -10202,7 +10300,7 @@ var DaemonCommandHandler = class {
10202
10300
  try {
10203
10301
  const http3 = await import("http");
10204
10302
  const postData = JSON.stringify(args || {});
10205
- const result = await new Promise((resolve12, reject) => {
10303
+ const result = await new Promise((resolve11, reject) => {
10206
10304
  const req = http3.request({
10207
10305
  hostname: "127.0.0.1",
10208
10306
  port: 19280,
@@ -10214,9 +10312,9 @@ var DaemonCommandHandler = class {
10214
10312
  res.on("data", (chunk) => data += chunk);
10215
10313
  res.on("end", () => {
10216
10314
  try {
10217
- resolve12(JSON.parse(data));
10315
+ resolve11(JSON.parse(data));
10218
10316
  } catch {
10219
- resolve12({ raw: data });
10317
+ resolve11({ raw: data });
10220
10318
  }
10221
10319
  });
10222
10320
  });
@@ -10266,6 +10364,9 @@ function getForcedNewSessionScriptName(provider, launchMode) {
10266
10364
  const controls = Array.isArray(provider.controls) ? provider.controls : [];
10267
10365
  for (const control of controls) {
10268
10366
  if (control?.type !== "action") continue;
10367
+ if (typeof control?.confirmTitle === "string" && control.confirmTitle.trim()) continue;
10368
+ if (typeof control?.confirmMessage === "string" && control.confirmMessage.trim()) continue;
10369
+ if (typeof control?.confirmLabel === "string" && control.confirmLabel.trim()) continue;
10269
10370
  const invokeScript = typeof control?.invokeScript === "string" ? control.invokeScript.trim() : "";
10270
10371
  if (!invokeScript) continue;
10271
10372
  const controlId = typeof control?.id === "string" ? control.id.trim() : "";
@@ -10275,6 +10376,20 @@ function getForcedNewSessionScriptName(provider, launchMode) {
10275
10376
  }
10276
10377
  return null;
10277
10378
  }
10379
+ async function waitForCliAdapterReady(adapter, options) {
10380
+ const timeoutMs = Math.max(100, options?.timeoutMs ?? 15e3);
10381
+ const pollMs = Math.max(10, options?.pollMs ?? 50);
10382
+ const deadline = Date.now() + timeoutMs;
10383
+ while (Date.now() < deadline) {
10384
+ if (adapter?.isReady?.()) return;
10385
+ const status = adapter?.getStatus?.()?.status;
10386
+ if (status === "stopped") {
10387
+ throw new Error("CLI runtime stopped before it became ready");
10388
+ }
10389
+ await new Promise((resolve11) => setTimeout(resolve11, pollMs));
10390
+ }
10391
+ throw new Error(`CLI runtime did not become ready within ${timeoutMs}ms`);
10392
+ }
10278
10393
  var CliProviderInstance = class {
10279
10394
  constructor(provider, workingDir, cliArgs = [], instanceId, transportFactory, options) {
10280
10395
  this.provider = provider;
@@ -10553,6 +10668,7 @@ var CliProviderInstance = class {
10553
10668
  const scriptName = getForcedNewSessionScriptName(this.provider, this.launchMode);
10554
10669
  if (!scriptName) return;
10555
10670
  LOG.info("CLI", `[${this.type}] forcing fresh session launch via script: ${scriptName}`);
10671
+ await waitForCliAdapterReady(this.adapter);
10556
10672
  const raw = await this.adapter.invokeScript(scriptName, {});
10557
10673
  const parsed = parseCliScriptResult(raw);
10558
10674
  if (!parsed.success) {
@@ -10902,6 +11018,7 @@ ${effect.notification.body || ""}`.trim();
10902
11018
  const previousProviderSessionId = this.providerSessionId;
10903
11019
  this.providerSessionId = nextSessionId;
10904
11020
  this.historyWriter.promoteHistorySession(this.type, previousHistorySessionId, nextSessionId);
11021
+ this.historyWriter.writeSessionStart(this.type, nextSessionId, this.workingDir, this.instanceId);
10905
11022
  this.adapter.updateRuntimeMeta({ providerSessionId: nextSessionId });
10906
11023
  this.onProviderSessionResolved?.({
10907
11024
  instanceId: this.instanceId,
@@ -11483,13 +11600,13 @@ var AcpProviderInstance = class {
11483
11600
  }
11484
11601
  this.currentStatus = "waiting_approval";
11485
11602
  this.detectStatusTransition();
11486
- const approved = await new Promise((resolve12) => {
11487
- this.permissionResolvers.push(resolve12);
11603
+ const approved = await new Promise((resolve11) => {
11604
+ this.permissionResolvers.push(resolve11);
11488
11605
  setTimeout(() => {
11489
- const idx = this.permissionResolvers.indexOf(resolve12);
11606
+ const idx = this.permissionResolvers.indexOf(resolve11);
11490
11607
  if (idx >= 0) {
11491
11608
  this.permissionResolvers.splice(idx, 1);
11492
- resolve12(false);
11609
+ resolve11(false);
11493
11610
  }
11494
11611
  }, 3e5);
11495
11612
  });
@@ -12805,6 +12922,9 @@ function validateProviderDefinition(raw) {
12805
12922
  warnings.push(`Unknown provider field: ${key}`);
12806
12923
  }
12807
12924
  }
12925
+ if (provider.disableUpstream !== void 0) {
12926
+ warnings.push("disableUpstream is deprecated in provider definitions; use machine-level provider source policy instead");
12927
+ }
12808
12928
  const category = provider.category;
12809
12929
  if (category === "cli" || category === "acp") {
12810
12930
  const spawn4 = provider.spawn;
@@ -12864,8 +12984,11 @@ function validateControl(control, errors) {
12864
12984
  var ProviderLoader = class _ProviderLoader {
12865
12985
  providers = /* @__PURE__ */ new Map();
12866
12986
  providerAvailability = /* @__PURE__ */ new Map();
12987
+ defaultProvidersDir;
12988
+ explicitProviderDir = null;
12867
12989
  userDir;
12868
12990
  upstreamDir;
12991
+ sourceMode = "normal";
12869
12992
  disableUpstream;
12870
12993
  watchers = [];
12871
12994
  logFn;
@@ -12879,22 +13002,15 @@ var ProviderLoader = class _ProviderLoader {
12879
13002
  static META_FILE = ".meta.json";
12880
13003
  constructor(options) {
12881
13004
  this.logFn = options?.logFn || LOG.forComponent("Provider").asLogFn();
12882
- const defaultProvidersDir = path14.join(os13.homedir(), ".adhdev", "providers");
12883
- if (options?.userDir) {
12884
- this.userDir = options.userDir;
12885
- this.log(`Config 'providerDir' applied: ${this.userDir}`);
12886
- } else {
12887
- const localRepoPath = path14.resolve(__dirname, "../../../../../adhdev-providers");
12888
- if (fs6.existsSync(localRepoPath)) {
12889
- this.userDir = localRepoPath;
12890
- this.log(`Auto-detected local public repository: ${this.userDir} (Dev workspace speedup)`);
12891
- } else {
12892
- this.userDir = defaultProvidersDir;
12893
- this.log(`Using default user providers directory: ${this.userDir}`);
12894
- }
12895
- }
12896
- this.upstreamDir = path14.join(defaultProvidersDir, ".upstream");
12897
- this.disableUpstream = options?.disableUpstream ?? false;
13005
+ this.defaultProvidersDir = path14.join(os13.homedir(), ".adhdev", "providers");
13006
+ this.userDir = this.defaultProvidersDir;
13007
+ this.upstreamDir = path14.join(this.defaultProvidersDir, ".upstream");
13008
+ this.disableUpstream = false;
13009
+ this.applySourceConfig({
13010
+ userDir: options?.userDir,
13011
+ sourceMode: options?.sourceMode,
13012
+ disableUpstream: options?.disableUpstream
13013
+ });
12898
13014
  }
12899
13015
  log(msg) {
12900
13016
  this.logFn(`[ProviderLoader] ${msg}`);
@@ -12919,6 +13035,33 @@ var ProviderLoader = class _ProviderLoader {
12919
13035
  getProviderRoots() {
12920
13036
  return [this.userDir, this.upstreamDir];
12921
13037
  }
13038
+ getSourceConfig() {
13039
+ return {
13040
+ sourceMode: this.sourceMode,
13041
+ disableUpstream: this.disableUpstream,
13042
+ explicitProviderDir: this.explicitProviderDir,
13043
+ userDir: this.userDir,
13044
+ upstreamDir: this.upstreamDir,
13045
+ providerRoots: this.getProviderRoots()
13046
+ };
13047
+ }
13048
+ applySourceConfig(options) {
13049
+ const nextSourceMode = options?.sourceMode === "no-upstream" ? "no-upstream" : options?.sourceMode === "normal" ? "normal" : options?.disableUpstream ? "no-upstream" : this.sourceMode || "normal";
13050
+ if (options && Object.prototype.hasOwnProperty.call(options, "userDir")) {
13051
+ this.explicitProviderDir = options.userDir?.trim() ? options.userDir : null;
13052
+ }
13053
+ this.sourceMode = nextSourceMode;
13054
+ this.userDir = this.explicitProviderDir || this.defaultProvidersDir;
13055
+ this.upstreamDir = path14.join(this.defaultProvidersDir, ".upstream");
13056
+ this.disableUpstream = this.sourceMode === "no-upstream";
13057
+ if (this.explicitProviderDir) {
13058
+ this.log(`Config 'providerDir' applied: ${this.userDir}`);
13059
+ } else {
13060
+ this.log(`Using default user providers directory: ${this.userDir}`);
13061
+ }
13062
+ this.log(`Provider source config: mode=${this.sourceMode} explicitProviderDir=${this.explicitProviderDir || "-"} userDir=${this.userDir} upstreamDir=${this.upstreamDir}`);
13063
+ return this.getSourceConfig();
13064
+ }
12922
13065
  /**
12923
13066
  * Canonical provider directory shape for a given root.
12924
13067
  */
@@ -12969,7 +13112,7 @@ var ProviderLoader = class _ProviderLoader {
12969
13112
  this.log(`Loaded ${upstreamCount} upstream providers (auto-updated)`);
12970
13113
  }
12971
13114
  } else if (this.disableUpstream) {
12972
- this.log("Upstream loading disabled (disableUpstream=true)");
13115
+ this.log("Upstream loading disabled (sourceMode=no-upstream)");
12973
13116
  }
12974
13117
  if (fs6.existsSync(this.userDir)) {
12975
13118
  const userCount = this.loadDir(this.userDir, [".upstream"]);
@@ -13480,7 +13623,7 @@ var ProviderLoader = class _ProviderLoader {
13480
13623
  */
13481
13624
  async fetchLatest() {
13482
13625
  if (this.disableUpstream) {
13483
- this.log("Upstream fetch skipped (disableUpstream=true)");
13626
+ this.log("Upstream fetch skipped (sourceMode=no-upstream)");
13484
13627
  return { updated: false };
13485
13628
  }
13486
13629
  const https = require("https");
@@ -13502,7 +13645,7 @@ var ProviderLoader = class _ProviderLoader {
13502
13645
  return { updated: false };
13503
13646
  }
13504
13647
  try {
13505
- const etag = await new Promise((resolve12, reject) => {
13648
+ const etag = await new Promise((resolve11, reject) => {
13506
13649
  const options = {
13507
13650
  method: "HEAD",
13508
13651
  hostname: "github.com",
@@ -13520,7 +13663,7 @@ var ProviderLoader = class _ProviderLoader {
13520
13663
  headers: { "User-Agent": "adhdev-launcher" },
13521
13664
  timeout: 1e4
13522
13665
  }, (res2) => {
13523
- resolve12(res2.headers.etag || res2.headers["last-modified"] || "");
13666
+ resolve11(res2.headers.etag || res2.headers["last-modified"] || "");
13524
13667
  });
13525
13668
  req2.on("error", reject);
13526
13669
  req2.on("timeout", () => {
@@ -13529,7 +13672,7 @@ var ProviderLoader = class _ProviderLoader {
13529
13672
  });
13530
13673
  req2.end();
13531
13674
  } else {
13532
- resolve12(res.headers.etag || res.headers["last-modified"] || "");
13675
+ resolve11(res.headers.etag || res.headers["last-modified"] || "");
13533
13676
  }
13534
13677
  });
13535
13678
  req.on("error", reject);
@@ -13593,7 +13736,7 @@ var ProviderLoader = class _ProviderLoader {
13593
13736
  downloadFile(url, destPath) {
13594
13737
  const https = require("https");
13595
13738
  const http3 = require("http");
13596
- return new Promise((resolve12, reject) => {
13739
+ return new Promise((resolve11, reject) => {
13597
13740
  const doRequest = (reqUrl, redirectCount = 0) => {
13598
13741
  if (redirectCount > 5) {
13599
13742
  reject(new Error("Too many redirects"));
@@ -13613,7 +13756,7 @@ var ProviderLoader = class _ProviderLoader {
13613
13756
  res.pipe(ws);
13614
13757
  ws.on("finish", () => {
13615
13758
  ws.close();
13616
- resolve12();
13759
+ resolve11();
13617
13760
  });
13618
13761
  ws.on("error", reject);
13619
13762
  });
@@ -14088,17 +14231,17 @@ async function findFreePort(ports) {
14088
14231
  throw new Error("No free port found");
14089
14232
  }
14090
14233
  function checkPortFree(port) {
14091
- return new Promise((resolve12) => {
14234
+ return new Promise((resolve11) => {
14092
14235
  const server = net.createServer();
14093
14236
  server.unref();
14094
- server.on("error", () => resolve12(false));
14237
+ server.on("error", () => resolve11(false));
14095
14238
  server.listen(port, "127.0.0.1", () => {
14096
- server.close(() => resolve12(true));
14239
+ server.close(() => resolve11(true));
14097
14240
  });
14098
14241
  });
14099
14242
  }
14100
14243
  async function isCdpActive(port) {
14101
- return new Promise((resolve12) => {
14244
+ return new Promise((resolve11) => {
14102
14245
  const req = require("http").get(`http://127.0.0.1:${port}/json/version`, {
14103
14246
  timeout: 2e3
14104
14247
  }, (res) => {
@@ -14107,16 +14250,16 @@ async function isCdpActive(port) {
14107
14250
  res.on("end", () => {
14108
14251
  try {
14109
14252
  const info = JSON.parse(data);
14110
- resolve12(!!info["WebKit-Version"] || !!info["Browser"]);
14253
+ resolve11(!!info["WebKit-Version"] || !!info["Browser"]);
14111
14254
  } catch {
14112
- resolve12(false);
14255
+ resolve11(false);
14113
14256
  }
14114
14257
  });
14115
14258
  });
14116
- req.on("error", () => resolve12(false));
14259
+ req.on("error", () => resolve11(false));
14117
14260
  req.on("timeout", () => {
14118
14261
  req.destroy();
14119
- resolve12(false);
14262
+ resolve11(false);
14120
14263
  });
14121
14264
  });
14122
14265
  }
@@ -14845,7 +14988,7 @@ async function waitForPidExit(pid, timeoutMs) {
14845
14988
  while (Date.now() - start < timeoutMs) {
14846
14989
  try {
14847
14990
  process.kill(pid, 0);
14848
- await new Promise((resolve12) => setTimeout(resolve12, 250));
14991
+ await new Promise((resolve11) => setTimeout(resolve11, 250));
14849
14992
  } catch {
14850
14993
  return;
14851
14994
  }
@@ -14960,7 +15103,7 @@ async function runDaemonUpgradeHelper(payload) {
14960
15103
  appendUpgradeLog(installOutput.trim());
14961
15104
  }
14962
15105
  if (process.platform === "win32") {
14963
- await new Promise((resolve12) => setTimeout(resolve12, 500));
15106
+ await new Promise((resolve11) => setTimeout(resolve11, 500));
14964
15107
  cleanupStaleGlobalInstallDirs(payload.packageName);
14965
15108
  appendUpgradeLog("Post-install staging cleanup complete");
14966
15109
  }
@@ -15253,8 +15396,9 @@ var DaemonCommandRouter = class {
15253
15396
  if (!providerType) {
15254
15397
  return { success: false, error: "providerType required" };
15255
15398
  }
15256
- const offset = Math.max(0, Number(args?.offset) || 0);
15257
- const limit = Math.max(1, Math.min(100, Number(args?.limit) || 30));
15399
+ const wantsAll = args?.all === true;
15400
+ const offset = wantsAll ? 0 : Math.max(0, Number(args?.offset) || 0);
15401
+ const limit = wantsAll ? Number.MAX_SAFE_INTEGER : Math.max(1, Math.min(100, Number(args?.limit) || 30));
15258
15402
  const { sessions: historySessions, hasMore } = listSavedHistorySessions(providerType, { offset, limit });
15259
15403
  const state = loadState();
15260
15404
  const savedSessions = getSavedProviderSessions(state, { providerType, kind });
@@ -15275,13 +15419,13 @@ var DaemonCommandRouter = class {
15275
15419
  providerName: saved?.providerName || recent?.providerName || providerType,
15276
15420
  kind: saved?.kind || recent?.kind || kind,
15277
15421
  title: saved?.title || recent?.title || session.sessionTitle || session.preview || providerType,
15278
- workspace: saved?.workspace || recent?.workspace,
15422
+ workspace: saved?.workspace || recent?.workspace || session.workspace,
15279
15423
  currentModel: saved?.currentModel || recent?.currentModel,
15280
15424
  preview: session.preview,
15281
15425
  messageCount: session.messageCount,
15282
15426
  firstMessageAt: session.firstMessageAt,
15283
15427
  lastMessageAt: session.lastMessageAt,
15284
- canResume: !!(saved?.workspace || recent?.workspace) && canResumeById
15428
+ canResume: !!(saved?.workspace || recent?.workspace || session.workspace) && canResumeById
15285
15429
  };
15286
15430
  }),
15287
15431
  hasMore
@@ -15898,7 +16042,7 @@ var ProviderStreamAdapter = class {
15898
16042
  const beforeCount = this.messageCount(before);
15899
16043
  const beforeSignature = this.lastMessageSignature(before);
15900
16044
  for (let attempt = 0; attempt < 12; attempt += 1) {
15901
- await new Promise((resolve12) => setTimeout(resolve12, 250));
16045
+ await new Promise((resolve11) => setTimeout(resolve11, 250));
15902
16046
  let state;
15903
16047
  try {
15904
16048
  state = await this.readChat(evaluate);
@@ -15920,7 +16064,7 @@ var ProviderStreamAdapter = class {
15920
16064
  if (this.messageCount(first) > 0 || this.lastMessageSignature(first)) {
15921
16065
  return first;
15922
16066
  }
15923
- await new Promise((resolve12) => setTimeout(resolve12, 150));
16067
+ await new Promise((resolve11) => setTimeout(resolve11, 150));
15924
16068
  const second = await this.readChat(evaluate);
15925
16069
  return this.messageCount(second) >= this.messageCount(first) ? second : first;
15926
16070
  }
@@ -16060,7 +16204,7 @@ var ProviderStreamAdapter = class {
16060
16204
  if (typeof data.error === "string" && data.error.trim()) return false;
16061
16205
  }
16062
16206
  for (let attempt = 0; attempt < 6; attempt += 1) {
16063
- await new Promise((resolve12) => setTimeout(resolve12, 250));
16207
+ await new Promise((resolve11) => setTimeout(resolve11, 250));
16064
16208
  const state = await this.readChat(evaluate);
16065
16209
  const title = this.getStateTitle(state);
16066
16210
  if (this.titlesMatch(title, sessionId)) return true;
@@ -16982,6 +17126,7 @@ async function detectAllVersions(loader, archive) {
16982
17126
  var http2 = __toESM(require("http"));
16983
17127
  var fs14 = __toESM(require("fs"));
16984
17128
  var path22 = __toESM(require("path"));
17129
+ init_config();
16985
17130
 
16986
17131
  // src/daemon/scaffold-template.ts
16987
17132
  function generateFiles(type, name, category, opts = {}) {
@@ -18518,7 +18663,7 @@ function getCliTargetBundle(ctx, type, instanceId) {
18518
18663
  return { target, instance, adapter };
18519
18664
  }
18520
18665
  function sleep(ms) {
18521
- return new Promise((resolve12) => setTimeout(resolve12, ms));
18666
+ return new Promise((resolve11) => setTimeout(resolve11, ms));
18522
18667
  }
18523
18668
  async function waitForCliReady(ctx, type, instanceId, timeoutMs) {
18524
18669
  const startedAt = Date.now();
@@ -19365,18 +19510,6 @@ function resolveAutoImplWritableProviderDir(ctx, category, type, requestedDir) {
19365
19510
  if (!fs13.existsSync(providerJson)) {
19366
19511
  return { dir: null, reason: `provider.json not found in writable provider directory: ${desiredDir}` };
19367
19512
  }
19368
- try {
19369
- const providerData = JSON.parse(fs13.readFileSync(providerJson, "utf-8"));
19370
- if (providerData.disableUpstream !== true) {
19371
- providerData.disableUpstream = true;
19372
- fs13.writeFileSync(providerJson, JSON.stringify(providerData, null, 2));
19373
- }
19374
- } catch (error) {
19375
- return {
19376
- dir: null,
19377
- reason: `Failed to update provider.json in writable provider directory: ${error.message}`
19378
- };
19379
- }
19380
19513
  return { dir: desiredDir };
19381
19514
  }
19382
19515
  function loadAutoImplReferenceScripts(ctx, referenceType) {
@@ -20663,6 +20796,7 @@ var DevServer = class _DevServer {
20663
20796
  cdpManagers;
20664
20797
  instanceManager;
20665
20798
  cliManager;
20799
+ onProviderSourceConfigChanged;
20666
20800
  logFn;
20667
20801
  sseClients = [];
20668
20802
  watchScriptPath = null;
@@ -20679,6 +20813,7 @@ var DevServer = class _DevServer {
20679
20813
  this.cdpManagers = options.cdpManagers;
20680
20814
  this.instanceManager = options.instanceManager || null;
20681
20815
  this.cliManager = options.cliManager || null;
20816
+ this.onProviderSourceConfigChanged = options.onProviderSourceConfigChanged || null;
20682
20817
  this.logFn = options.logFn || LOG.forComponent("DevServer").asLogFn();
20683
20818
  }
20684
20819
  log(msg) {
@@ -20688,6 +20823,8 @@ var DevServer = class _DevServer {
20688
20823
  routes = [
20689
20824
  // Static routes
20690
20825
  { method: "GET", pattern: "/api/providers", handler: (q, s) => this.handleListProviders(q, s) },
20826
+ { method: "GET", pattern: "/api/providers/source-config", handler: (q, s) => this.handleGetProviderSourceConfig(q, s) },
20827
+ { method: "POST", pattern: "/api/providers/source-config", handler: (q, s) => this.handleSetProviderSourceConfig(q, s) },
20691
20828
  { method: "GET", pattern: "/api/providers/versions", handler: (q, s) => this.handleDetectVersions(q, s) },
20692
20829
  { method: "POST", pattern: "/api/providers/reload", handler: (q, s) => this.handleReload(q, s) },
20693
20830
  { method: "POST", pattern: "/api/cdp/evaluate", handler: (q, s) => this.handleCdpEvaluate(q, s) },
@@ -20785,15 +20922,15 @@ var DevServer = class _DevServer {
20785
20922
  this.json(res, 500, { error: e.message });
20786
20923
  }
20787
20924
  });
20788
- return new Promise((resolve12, reject) => {
20925
+ return new Promise((resolve11, reject) => {
20789
20926
  this.server.listen(port, "127.0.0.1", () => {
20790
20927
  this.log(`Dev server listening on http://127.0.0.1:${port}`);
20791
- resolve12();
20928
+ resolve11();
20792
20929
  });
20793
20930
  this.server.on("error", (e) => {
20794
20931
  if (e.code === "EADDRINUSE") {
20795
20932
  this.log(`Port ${port} in use, skipping dev server`);
20796
- resolve12();
20933
+ resolve11();
20797
20934
  } else {
20798
20935
  reject(e);
20799
20936
  }
@@ -20807,7 +20944,33 @@ var DevServer = class _DevServer {
20807
20944
  // ─── Handlers ───
20808
20945
  async handleListProviders(_req, res) {
20809
20946
  const providers = this.providerLoader.getAll().map(toProviderListEntry);
20810
- this.json(res, 200, { providers, count: providers.length });
20947
+ this.json(res, 200, { providers, count: providers.length, sourceConfig: this.providerLoader.getSourceConfig() });
20948
+ }
20949
+ async handleGetProviderSourceConfig(_req, res) {
20950
+ this.json(res, 200, { success: true, sourceConfig: this.providerLoader.getSourceConfig() });
20951
+ }
20952
+ async handleSetProviderSourceConfig(req, res) {
20953
+ const body = await this.readBody(req);
20954
+ const parsed = parseProviderSourceConfigUpdate(body || {});
20955
+ if (!parsed.ok) {
20956
+ this.json(res, 400, { success: false, error: parsed.error });
20957
+ return;
20958
+ }
20959
+ const currentConfig2 = loadConfig();
20960
+ const nextConfig = {
20961
+ ...currentConfig2,
20962
+ ...parsed.updates.providerSourceMode ? { providerSourceMode: parsed.updates.providerSourceMode } : {},
20963
+ ...Object.prototype.hasOwnProperty.call(parsed.updates, "providerDir") ? { providerDir: parsed.updates.providerDir } : {}
20964
+ };
20965
+ saveConfig(nextConfig);
20966
+ const sourceConfig = this.providerLoader.applySourceConfig({
20967
+ sourceMode: nextConfig.providerSourceMode,
20968
+ userDir: Object.prototype.hasOwnProperty.call(parsed.updates, "providerDir") ? parsed.updates.providerDir : this.providerLoader.getSourceConfig().explicitProviderDir || void 0
20969
+ });
20970
+ this.providerLoader.reload();
20971
+ this.providerLoader.registerToDetector();
20972
+ await this.onProviderSourceConfigChanged?.();
20973
+ this.json(res, 200, { success: true, reloaded: true, sourceConfig });
20811
20974
  }
20812
20975
  async handleProviderConfig(type, _req, res) {
20813
20976
  const provider = this.providerLoader.resolve(type);
@@ -20849,20 +21012,20 @@ var DevServer = class _DevServer {
20849
21012
  child.stderr?.on("data", (d) => {
20850
21013
  stderr += d.toString().slice(0, 2e3);
20851
21014
  });
20852
- await new Promise((resolve12) => {
21015
+ await new Promise((resolve11) => {
20853
21016
  const timer = setTimeout(() => {
20854
21017
  child.kill();
20855
- resolve12();
21018
+ resolve11();
20856
21019
  }, 3e3);
20857
21020
  child.on("exit", () => {
20858
21021
  clearTimeout(timer);
20859
- resolve12();
21022
+ resolve11();
20860
21023
  });
20861
21024
  child.stdout?.once("data", () => {
20862
21025
  setTimeout(() => {
20863
21026
  child.kill();
20864
21027
  clearTimeout(timer);
20865
- resolve12();
21028
+ resolve11();
20866
21029
  }, 500);
20867
21030
  });
20868
21031
  });
@@ -21358,14 +21521,14 @@ var DevServer = class _DevServer {
21358
21521
  child.stderr?.on("data", (d) => {
21359
21522
  stderr += d.toString();
21360
21523
  });
21361
- await new Promise((resolve12) => {
21524
+ await new Promise((resolve11) => {
21362
21525
  const timer = setTimeout(() => {
21363
21526
  child.kill();
21364
- resolve12();
21527
+ resolve11();
21365
21528
  }, timeout);
21366
21529
  child.on("exit", () => {
21367
21530
  clearTimeout(timer);
21368
- resolve12();
21531
+ resolve11();
21369
21532
  });
21370
21533
  });
21371
21534
  const elapsed = Date.now() - start;
@@ -21510,18 +21673,6 @@ var DevServer = class _DevServer {
21510
21673
  if (!fs14.existsSync(providerJson)) {
21511
21674
  return { dir: null, reason: `provider.json not found in writable provider directory: ${desiredDir}` };
21512
21675
  }
21513
- try {
21514
- const providerData = JSON.parse(fs14.readFileSync(providerJson, "utf-8"));
21515
- if (providerData.disableUpstream !== true) {
21516
- providerData.disableUpstream = true;
21517
- fs14.writeFileSync(providerJson, JSON.stringify(providerData, null, 2));
21518
- }
21519
- } catch (error) {
21520
- return {
21521
- dir: null,
21522
- reason: `Failed to update provider.json in writable provider directory: ${error.message}`
21523
- };
21524
- }
21525
21676
  return { dir: desiredDir };
21526
21677
  }
21527
21678
  async handleAutoImplement(type, req, res) {
@@ -22047,14 +22198,14 @@ data: ${JSON.stringify(msg.data)}
22047
22198
  res.end(JSON.stringify(data, null, 2));
22048
22199
  }
22049
22200
  async readBody(req) {
22050
- return new Promise((resolve12) => {
22201
+ return new Promise((resolve11) => {
22051
22202
  let body = "";
22052
22203
  req.on("data", (chunk) => body += chunk);
22053
22204
  req.on("end", () => {
22054
22205
  try {
22055
- resolve12(JSON.parse(body));
22206
+ resolve11(JSON.parse(body));
22056
22207
  } catch {
22057
- resolve12({});
22208
+ resolve11({});
22058
22209
  }
22059
22210
  });
22060
22211
  });
@@ -22532,7 +22683,7 @@ async function waitForReady(endpoint, timeoutMs = STARTUP_TIMEOUT_MS) {
22532
22683
  const deadline = Date.now() + timeoutMs;
22533
22684
  while (Date.now() < deadline) {
22534
22685
  if (await canConnect(endpoint)) return;
22535
- await new Promise((resolve12) => setTimeout(resolve12, STARTUP_POLL_MS));
22686
+ await new Promise((resolve11) => setTimeout(resolve11, STARTUP_POLL_MS));
22536
22687
  }
22537
22688
  throw new Error(`Session host did not become ready within ${timeoutMs}ms`);
22538
22689
  }
@@ -22763,10 +22914,10 @@ async function installExtension(ide, extension) {
22763
22914
  const buffer = Buffer.from(await res.arrayBuffer());
22764
22915
  const fs15 = await import("fs");
22765
22916
  fs15.writeFileSync(vsixPath, buffer);
22766
- return new Promise((resolve12) => {
22917
+ return new Promise((resolve11) => {
22767
22918
  const cmd = `"${ide.cliCommand}" --install-extension "${vsixPath}" --force`;
22768
22919
  (0, import_child_process10.exec)(cmd, { timeout: 6e4 }, (error, _stdout, stderr) => {
22769
- resolve12({
22920
+ resolve11({
22770
22921
  extensionId: extension.id,
22771
22922
  marketplaceId: extension.marketplaceId,
22772
22923
  success: !error,
@@ -22779,11 +22930,11 @@ async function installExtension(ide, extension) {
22779
22930
  } catch (e) {
22780
22931
  }
22781
22932
  }
22782
- return new Promise((resolve12) => {
22933
+ return new Promise((resolve11) => {
22783
22934
  const cmd = `"${ide.cliCommand}" --install-extension ${extension.marketplaceId} --force`;
22784
22935
  (0, import_child_process10.exec)(cmd, { timeout: 6e4 }, (error, stdout, stderr) => {
22785
22936
  if (error) {
22786
- resolve12({
22937
+ resolve11({
22787
22938
  extensionId: extension.id,
22788
22939
  marketplaceId: extension.marketplaceId,
22789
22940
  success: false,
@@ -22791,7 +22942,7 @@ async function installExtension(ide, extension) {
22791
22942
  error: stderr || error.message
22792
22943
  });
22793
22944
  } else {
22794
- resolve12({
22945
+ resolve11({
22795
22946
  extensionId: extension.id,
22796
22947
  marketplaceId: extension.marketplaceId,
22797
22948
  success: true,
@@ -22888,10 +23039,11 @@ init_config();
22888
23039
  async function initDaemonComponents(config) {
22889
23040
  installGlobalInterceptor();
22890
23041
  const appConfig = loadConfig();
22891
- const disableUpstream = appConfig.disableUpstream ?? false;
23042
+ const providerSourceMode = appConfig.providerSourceMode || "normal";
23043
+ const disableUpstream = providerSourceMode === "no-upstream";
22892
23044
  const providerLoader = new ProviderLoader({
22893
23045
  logFn: config.providerLogFn,
22894
- disableUpstream,
23046
+ sourceMode: providerSourceMode,
22895
23047
  userDir: appConfig.providerDir
22896
23048
  });
22897
23049
  if (!disableUpstream && !providerLoader.hasUpstream()) {
@@ -22996,6 +23148,10 @@ async function initDaemonComponents(config) {
22996
23148
  onProviderSettingChanged: async (providerType) => {
22997
23149
  await refreshProviderAvailability(providerType);
22998
23150
  config.onStatusChange?.();
23151
+ },
23152
+ onProviderSourceConfigChanged: async () => {
23153
+ await refreshProviderAvailability();
23154
+ config.onStatusChange?.();
22999
23155
  }
23000
23156
  });
23001
23157
  agentStreamManager = new DaemonAgentStreamManager(
@@ -23045,7 +23201,8 @@ async function initDaemonComponents(config) {
23045
23201
  cdpInitializer,
23046
23202
  cdpManagers,
23047
23203
  sessionRegistry,
23048
- detectedIdes: detectedIdesRef
23204
+ detectedIdes: detectedIdesRef,
23205
+ refreshProviderAvailability
23049
23206
  };
23050
23207
  }
23051
23208
  async function startDaemonDevSupport(options) {
@@ -23054,7 +23211,10 @@ async function startDaemonDevSupport(options) {
23054
23211
  cdpManagers: options.components.cdpManagers,
23055
23212
  instanceManager: options.components.instanceManager,
23056
23213
  cliManager: options.components.cliManager,
23057
- logFn: options.logFn
23214
+ logFn: options.logFn,
23215
+ onProviderSourceConfigChanged: async () => {
23216
+ await options.components.refreshProviderAvailability();
23217
+ }
23058
23218
  });
23059
23219
  await devServer.start();
23060
23220
  options.components.providerLoader.watch();
@@ -23181,6 +23341,7 @@ async function shutdownDaemonComponents(components) {
23181
23341
  normalizeInputEnvelope,
23182
23342
  normalizeManagedStatus,
23183
23343
  normalizeMessageParts,
23344
+ parseProviderSourceConfigUpdate,
23184
23345
  partitionSessionHostDiagnosticsSessions,
23185
23346
  partitionSessionHostRecords,
23186
23347
  probeCdpPort,