@adhdev/daemon-core 0.6.72 → 0.6.73

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.js CHANGED
@@ -912,6 +912,8 @@ var init_provider_cli_adapter = __esm({
912
912
  spawnAt = 0;
913
913
  // PTY I/O
914
914
  onPtyDataCallback = null;
915
+ pendingOutputParseBuffer = "";
916
+ pendingOutputParseTimer = null;
915
917
  ptyOutputBuffer = "";
916
918
  ptyOutputFlushTimer = null;
917
919
  // Server log forwarding
@@ -1007,6 +1009,16 @@ var init_provider_cli_adapter = __esm({
1007
1009
  setOnPtyData(callback) {
1008
1010
  this.onPtyDataCallback = callback;
1009
1011
  }
1012
+ flushPendingOutputParse() {
1013
+ if (this.pendingOutputParseTimer) {
1014
+ clearTimeout(this.pendingOutputParseTimer);
1015
+ this.pendingOutputParseTimer = null;
1016
+ }
1017
+ if (!this.pendingOutputParseBuffer) return;
1018
+ const rawData = this.pendingOutputParseBuffer;
1019
+ this.pendingOutputParseBuffer = "";
1020
+ this.handleOutput(rawData);
1021
+ }
1010
1022
  async spawn() {
1011
1023
  if (this.ptyProcess) return;
1012
1024
  if (!pty) throw new Error("node-pty is not installed");
@@ -1055,7 +1067,17 @@ var init_provider_cli_adapter = __esm({
1055
1067
  }
1056
1068
  }
1057
1069
  this.ptyProcess.onData((data) => {
1058
- this.handleOutput(data);
1070
+ if (Date.now() < this.resizeSuppressUntil) return;
1071
+ if (data.includes("\x1B[6n") || data.includes("\x1B[?6n")) {
1072
+ this.ptyProcess?.write("\x1B[1;1R");
1073
+ }
1074
+ this.pendingOutputParseBuffer += data;
1075
+ if (!this.pendingOutputParseTimer) {
1076
+ this.pendingOutputParseTimer = setTimeout(() => {
1077
+ this.pendingOutputParseTimer = null;
1078
+ this.flushPendingOutputParse();
1079
+ }, this.timeouts.ptyFlush);
1080
+ }
1059
1081
  if (this.onPtyDataCallback) {
1060
1082
  this.ptyOutputBuffer += data;
1061
1083
  if (!this.ptyOutputFlushTimer) {
@@ -1071,6 +1093,7 @@ var init_provider_cli_adapter = __esm({
1071
1093
  });
1072
1094
  this.ptyProcess.onExit(({ exitCode }) => {
1073
1095
  LOG.info("CLI", `[${this.cliType}] Exit code ${exitCode}`);
1096
+ this.flushPendingOutputParse();
1074
1097
  this.ptyProcess = null;
1075
1098
  this.setStatus("stopped", "pty_exit");
1076
1099
  this.ready = false;
@@ -1090,10 +1113,6 @@ var init_provider_cli_adapter = __esm({
1090
1113
  }
1091
1114
  // ─── Output Handling ────────────────────────────
1092
1115
  handleOutput(rawData) {
1093
- if (Date.now() < this.resizeSuppressUntil) return;
1094
- if (rawData.includes("\x1B[6n") || rawData.includes("\x1B[?6n")) {
1095
- this.ptyProcess?.write("\x1B[1;1R");
1096
- }
1097
1116
  this.terminalScreen.write(rawData);
1098
1117
  this.terminalHistory = mergeTerminalHistory(this.terminalHistory, this.terminalScreen.getText());
1099
1118
  const cleanData = stripAnsi(rawData);
@@ -1444,7 +1463,7 @@ ${data.message || ""}`.trim();
1444
1463
  if (this.startupParseGate) {
1445
1464
  const deadline = Date.now() + 1e4;
1446
1465
  while (this.startupParseGate && Date.now() < deadline) {
1447
- await new Promise((resolve7) => setTimeout(resolve7, 50));
1466
+ await new Promise((resolve8) => setTimeout(resolve8, 50));
1448
1467
  }
1449
1468
  }
1450
1469
  if (!this.ready) throw new Error(`${this.cliName} not ready (status: ${this.currentStatus})`);
@@ -1581,6 +1600,16 @@ ${data.message || ""}`.trim();
1581
1600
  clearTimeout(this.submitRetryTimer);
1582
1601
  this.submitRetryTimer = null;
1583
1602
  }
1603
+ if (this.pendingOutputParseTimer) {
1604
+ clearTimeout(this.pendingOutputParseTimer);
1605
+ this.pendingOutputParseTimer = null;
1606
+ }
1607
+ this.pendingOutputParseBuffer = "";
1608
+ if (this.ptyOutputFlushTimer) {
1609
+ clearTimeout(this.ptyOutputFlushTimer);
1610
+ this.ptyOutputFlushTimer = null;
1611
+ }
1612
+ this.ptyOutputBuffer = "";
1584
1613
  if (this.ptyProcess) {
1585
1614
  this.ptyProcess.write("");
1586
1615
  setTimeout(() => {
@@ -1606,6 +1635,16 @@ ${data.message || ""}`.trim();
1606
1635
  this.currentTurnScope = null;
1607
1636
  this.submitRetryUsed = false;
1608
1637
  this.submitRetryPromptSnippet = "";
1638
+ if (this.pendingOutputParseTimer) {
1639
+ clearTimeout(this.pendingOutputParseTimer);
1640
+ this.pendingOutputParseTimer = null;
1641
+ }
1642
+ this.pendingOutputParseBuffer = "";
1643
+ if (this.ptyOutputFlushTimer) {
1644
+ clearTimeout(this.ptyOutputFlushTimer);
1645
+ this.ptyOutputFlushTimer = null;
1646
+ }
1647
+ this.ptyOutputBuffer = "";
1609
1648
  this.terminalScreen.reset();
1610
1649
  this.onStatusChange?.();
1611
1650
  }
@@ -1683,6 +1722,8 @@ ${data.message || ""}`.trim();
1683
1722
  scriptNames: Object.keys(this.cliScripts).filter((k) => typeof this.cliScripts[k] === "function"),
1684
1723
  statusHistory: this.statusHistory.slice(-30),
1685
1724
  timeouts: this.timeouts,
1725
+ pendingOutputParseBufferLength: this.pendingOutputParseBuffer.length,
1726
+ pendingOutputParseScheduled: !!this.pendingOutputParseTimer,
1686
1727
  ptyAlive: !!this.ptyProcess
1687
1728
  };
1688
1729
  }
@@ -1756,6 +1797,7 @@ __export(index_exports, {
1756
1797
  setLogLevel: () => setLogLevel,
1757
1798
  setupIdeInstance: () => setupIdeInstance,
1758
1799
  shutdownDaemonComponents: () => shutdownDaemonComponents,
1800
+ startDaemonDevSupport: () => startDaemonDevSupport,
1759
1801
  updateConfig: () => updateConfig
1760
1802
  });
1761
1803
  module.exports = __toCommonJS(index_exports);
@@ -1905,15 +1947,15 @@ async function detectIDEs() {
1905
1947
  var import_child_process2 = require("child_process");
1906
1948
  var os2 = __toESM(require("os"));
1907
1949
  function execAsync(cmd, timeoutMs = 5e3) {
1908
- return new Promise((resolve7) => {
1950
+ return new Promise((resolve8) => {
1909
1951
  const child = (0, import_child_process2.exec)(cmd, { encoding: "utf-8", timeout: timeoutMs }, (err, stdout) => {
1910
1952
  if (err || !stdout?.trim()) {
1911
- resolve7(null);
1953
+ resolve8(null);
1912
1954
  } else {
1913
- resolve7(stdout.trim());
1955
+ resolve8(stdout.trim());
1914
1956
  }
1915
1957
  });
1916
- child.on("error", () => resolve7(null));
1958
+ child.on("error", () => resolve8(null));
1917
1959
  });
1918
1960
  }
1919
1961
  async function detectCLIs(providerLoader) {
@@ -2072,7 +2114,7 @@ var DaemonCdpManager = class {
2072
2114
  * Returns multiple entries if multiple IDE windows are open on same port
2073
2115
  */
2074
2116
  static listAllTargets(port) {
2075
- return new Promise((resolve7) => {
2117
+ return new Promise((resolve8) => {
2076
2118
  const req = http.get(`http://127.0.0.1:${port}/json`, (res) => {
2077
2119
  let data = "";
2078
2120
  res.on("data", (chunk) => data += chunk.toString());
@@ -2088,16 +2130,16 @@ var DaemonCdpManager = class {
2088
2130
  (t) => !isNonMain(t.title || "") && t.url?.includes("workbench.html") && !t.url?.includes("agent")
2089
2131
  );
2090
2132
  const fallbackPages = pages.filter((t) => !isNonMain(t.title || ""));
2091
- resolve7(mainPages.length > 0 ? mainPages : fallbackPages);
2133
+ resolve8(mainPages.length > 0 ? mainPages : fallbackPages);
2092
2134
  } catch {
2093
- resolve7([]);
2135
+ resolve8([]);
2094
2136
  }
2095
2137
  });
2096
2138
  });
2097
- req.on("error", () => resolve7([]));
2139
+ req.on("error", () => resolve8([]));
2098
2140
  req.setTimeout(2e3, () => {
2099
2141
  req.destroy();
2100
- resolve7([]);
2142
+ resolve8([]);
2101
2143
  });
2102
2144
  });
2103
2145
  }
@@ -2137,7 +2179,7 @@ var DaemonCdpManager = class {
2137
2179
  }
2138
2180
  }
2139
2181
  findTargetOnPort(port) {
2140
- return new Promise((resolve7) => {
2182
+ return new Promise((resolve8) => {
2141
2183
  const req = http.get(`http://127.0.0.1:${port}/json`, (res) => {
2142
2184
  let data = "";
2143
2185
  res.on("data", (chunk) => data += chunk.toString());
@@ -2148,7 +2190,7 @@ var DaemonCdpManager = class {
2148
2190
  (t) => (t.type === "page" || t.type === "browser" || t.type === "Page") && t.webSocketDebuggerUrl
2149
2191
  );
2150
2192
  if (pages.length === 0) {
2151
- resolve7(targets.find((t) => t.webSocketDebuggerUrl) || null);
2193
+ resolve8(targets.find((t) => t.webSocketDebuggerUrl) || null);
2152
2194
  return;
2153
2195
  }
2154
2196
  const mainPages = pages.filter((t) => !this.isNonMainTitle(t.title || ""));
@@ -2158,24 +2200,24 @@ var DaemonCdpManager = class {
2158
2200
  const specific = list.find((t) => t.id === this._targetId);
2159
2201
  if (specific) {
2160
2202
  this._pageTitle = specific.title || "";
2161
- resolve7(specific);
2203
+ resolve8(specific);
2162
2204
  } else {
2163
2205
  this.log(`[CDP] Target ${this._targetId} not found in page list`);
2164
- resolve7(null);
2206
+ resolve8(null);
2165
2207
  }
2166
2208
  return;
2167
2209
  }
2168
2210
  this._pageTitle = list[0]?.title || "";
2169
- resolve7(list[0]);
2211
+ resolve8(list[0]);
2170
2212
  } catch {
2171
- resolve7(null);
2213
+ resolve8(null);
2172
2214
  }
2173
2215
  });
2174
2216
  });
2175
- req.on("error", () => resolve7(null));
2217
+ req.on("error", () => resolve8(null));
2176
2218
  req.setTimeout(2e3, () => {
2177
2219
  req.destroy();
2178
- resolve7(null);
2220
+ resolve8(null);
2179
2221
  });
2180
2222
  });
2181
2223
  }
@@ -2186,7 +2228,7 @@ var DaemonCdpManager = class {
2186
2228
  this.extensionProviders = providers;
2187
2229
  }
2188
2230
  connectToTarget(wsUrl) {
2189
- return new Promise((resolve7) => {
2231
+ return new Promise((resolve8) => {
2190
2232
  this.ws = new import_ws.default(wsUrl);
2191
2233
  this.ws.on("open", async () => {
2192
2234
  this._connected = true;
@@ -2196,17 +2238,17 @@ var DaemonCdpManager = class {
2196
2238
  }
2197
2239
  this.connectBrowserWs().catch(() => {
2198
2240
  });
2199
- resolve7(true);
2241
+ resolve8(true);
2200
2242
  });
2201
2243
  this.ws.on("message", (data) => {
2202
2244
  try {
2203
2245
  const msg = JSON.parse(data.toString());
2204
2246
  if (msg.id && this.pending.has(msg.id)) {
2205
- const { resolve: resolve8, reject } = this.pending.get(msg.id);
2247
+ const { resolve: resolve9, reject } = this.pending.get(msg.id);
2206
2248
  this.pending.delete(msg.id);
2207
2249
  this.failureCount = 0;
2208
2250
  if (msg.error) reject(new Error(msg.error.message));
2209
- else resolve8(msg.result);
2251
+ else resolve9(msg.result);
2210
2252
  } else if (msg.method === "Runtime.executionContextCreated") {
2211
2253
  this.contexts.add(msg.params.context.id);
2212
2254
  } else if (msg.method === "Runtime.executionContextDestroyed") {
@@ -2229,7 +2271,7 @@ var DaemonCdpManager = class {
2229
2271
  this.ws.on("error", (err) => {
2230
2272
  this.log(`[CDP] WebSocket error: ${err.message}`);
2231
2273
  this._connected = false;
2232
- resolve7(false);
2274
+ resolve8(false);
2233
2275
  });
2234
2276
  });
2235
2277
  }
@@ -2243,7 +2285,7 @@ var DaemonCdpManager = class {
2243
2285
  return;
2244
2286
  }
2245
2287
  this.log(`[CDP] Connecting browser WS for target discovery...`);
2246
- await new Promise((resolve7, reject) => {
2288
+ await new Promise((resolve8, reject) => {
2247
2289
  this.browserWs = new import_ws.default(browserWsUrl);
2248
2290
  this.browserWs.on("open", async () => {
2249
2291
  this._browserConnected = true;
@@ -2253,16 +2295,16 @@ var DaemonCdpManager = class {
2253
2295
  } catch (e) {
2254
2296
  this.log(`[CDP] setDiscoverTargets failed: ${e.message}`);
2255
2297
  }
2256
- resolve7();
2298
+ resolve8();
2257
2299
  });
2258
2300
  this.browserWs.on("message", (data) => {
2259
2301
  try {
2260
2302
  const msg = JSON.parse(data.toString());
2261
2303
  if (msg.id && this.browserPending.has(msg.id)) {
2262
- const { resolve: resolve8, reject: reject2 } = this.browserPending.get(msg.id);
2304
+ const { resolve: resolve9, reject: reject2 } = this.browserPending.get(msg.id);
2263
2305
  this.browserPending.delete(msg.id);
2264
2306
  if (msg.error) reject2(new Error(msg.error.message));
2265
- else resolve8(msg.result);
2307
+ else resolve9(msg.result);
2266
2308
  }
2267
2309
  } catch {
2268
2310
  }
@@ -2282,31 +2324,31 @@ var DaemonCdpManager = class {
2282
2324
  }
2283
2325
  }
2284
2326
  getBrowserWsUrl() {
2285
- return new Promise((resolve7) => {
2327
+ return new Promise((resolve8) => {
2286
2328
  const req = http.get(`http://127.0.0.1:${this.port}/json/version`, (res) => {
2287
2329
  let data = "";
2288
2330
  res.on("data", (chunk) => data += chunk.toString());
2289
2331
  res.on("end", () => {
2290
2332
  try {
2291
2333
  const info = JSON.parse(data);
2292
- resolve7(info.webSocketDebuggerUrl || null);
2334
+ resolve8(info.webSocketDebuggerUrl || null);
2293
2335
  } catch {
2294
- resolve7(null);
2336
+ resolve8(null);
2295
2337
  }
2296
2338
  });
2297
2339
  });
2298
- req.on("error", () => resolve7(null));
2340
+ req.on("error", () => resolve8(null));
2299
2341
  req.setTimeout(3e3, () => {
2300
2342
  req.destroy();
2301
- resolve7(null);
2343
+ resolve8(null);
2302
2344
  });
2303
2345
  });
2304
2346
  }
2305
2347
  sendBrowser(method, params = {}, timeoutMs = 15e3) {
2306
- return new Promise((resolve7, reject) => {
2348
+ return new Promise((resolve8, reject) => {
2307
2349
  if (!this.browserWs || !this._browserConnected) return reject(new Error("Browser WS not connected"));
2308
2350
  const id = this.browserMsgId++;
2309
- this.browserPending.set(id, { resolve: resolve7, reject });
2351
+ this.browserPending.set(id, { resolve: resolve8, reject });
2310
2352
  this.browserWs.send(JSON.stringify({ id, method, params }));
2311
2353
  setTimeout(() => {
2312
2354
  if (this.browserPending.has(id)) {
@@ -2346,11 +2388,11 @@ var DaemonCdpManager = class {
2346
2388
  }
2347
2389
  // ─── CDP Protocol ────────────────────────────────────────
2348
2390
  sendInternal(method, params = {}, timeoutMs = 15e3) {
2349
- return new Promise((resolve7, reject) => {
2391
+ return new Promise((resolve8, reject) => {
2350
2392
  if (!this.ws || !this._connected) return reject(new Error("CDP not connected"));
2351
2393
  if (this.ws.readyState !== import_ws.default.OPEN) return reject(new Error("WebSocket not open"));
2352
2394
  const id = this.msgId++;
2353
- this.pending.set(id, { resolve: resolve7, reject });
2395
+ this.pending.set(id, { resolve: resolve8, reject });
2354
2396
  this.ws.send(JSON.stringify({ id, method, params }));
2355
2397
  setTimeout(() => {
2356
2398
  if (this.pending.has(id)) {
@@ -2599,7 +2641,7 @@ var DaemonCdpManager = class {
2599
2641
  const browserWs = this.browserWs;
2600
2642
  let msgId = this.browserMsgId;
2601
2643
  const sendWs = (method, params = {}, sessionId) => {
2602
- return new Promise((resolve7, reject) => {
2644
+ return new Promise((resolve8, reject) => {
2603
2645
  const mid = msgId++;
2604
2646
  this.browserMsgId = msgId;
2605
2647
  const handler = (raw) => {
@@ -2608,7 +2650,7 @@ var DaemonCdpManager = class {
2608
2650
  if (msg.id === mid) {
2609
2651
  browserWs.removeListener("message", handler);
2610
2652
  if (msg.error) reject(new Error(msg.error.message || JSON.stringify(msg.error)));
2611
- else resolve7(msg.result);
2653
+ else resolve8(msg.result);
2612
2654
  }
2613
2655
  } catch {
2614
2656
  }
@@ -2790,14 +2832,14 @@ var DaemonCdpManager = class {
2790
2832
  if (!ws || ws.readyState !== import_ws.default.OPEN) {
2791
2833
  throw new Error("CDP not connected");
2792
2834
  }
2793
- return new Promise((resolve7, reject) => {
2835
+ return new Promise((resolve8, reject) => {
2794
2836
  const id = getNextId();
2795
2837
  pendingMap.set(id, {
2796
2838
  resolve: (result) => {
2797
2839
  if (result?.result?.subtype === "error") {
2798
2840
  reject(new Error(result.result.description));
2799
2841
  } else {
2800
- resolve7(result?.result?.value);
2842
+ resolve8(result?.result?.value);
2801
2843
  }
2802
2844
  },
2803
2845
  reject
@@ -2829,10 +2871,10 @@ var DaemonCdpManager = class {
2829
2871
  throw new Error("CDP not connected");
2830
2872
  }
2831
2873
  const sendViaSession = (method, params = {}) => {
2832
- return new Promise((resolve7, reject) => {
2874
+ return new Promise((resolve8, reject) => {
2833
2875
  const pendingMap = this._browserConnected ? this.browserPending : this.pending;
2834
2876
  const id = this._browserConnected ? this.browserMsgId++ : this.msgId++;
2835
- pendingMap.set(id, { resolve: resolve7, reject });
2877
+ pendingMap.set(id, { resolve: resolve8, reject });
2836
2878
  ws.send(JSON.stringify({ id, sessionId, method, params }));
2837
2879
  setTimeout(() => {
2838
2880
  if (pendingMap.has(id)) {
@@ -6237,7 +6279,7 @@ var DaemonCommandHandler = class {
6237
6279
  try {
6238
6280
  const http3 = await import("http");
6239
6281
  const postData = JSON.stringify(body);
6240
- const result = await new Promise((resolve7, reject) => {
6282
+ const result = await new Promise((resolve8, reject) => {
6241
6283
  const req = http3.request({
6242
6284
  hostname: "127.0.0.1",
6243
6285
  port: 19280,
@@ -6249,9 +6291,9 @@ var DaemonCommandHandler = class {
6249
6291
  res.on("data", (chunk) => data += chunk);
6250
6292
  res.on("end", () => {
6251
6293
  try {
6252
- resolve7(JSON.parse(data));
6294
+ resolve8(JSON.parse(data));
6253
6295
  } catch {
6254
- resolve7({ raw: data });
6296
+ resolve8({ raw: data });
6255
6297
  }
6256
6298
  });
6257
6299
  });
@@ -6269,15 +6311,15 @@ var DaemonCommandHandler = class {
6269
6311
  if (!providerType) return { success: false, error: "providerType required" };
6270
6312
  try {
6271
6313
  const http3 = await import("http");
6272
- const result = await new Promise((resolve7, reject) => {
6314
+ const result = await new Promise((resolve8, reject) => {
6273
6315
  http3.get(`http://127.0.0.1:19280/api/providers/${providerType}/${endpoint}`, (res) => {
6274
6316
  let data = "";
6275
6317
  res.on("data", (chunk) => data += chunk);
6276
6318
  res.on("end", () => {
6277
6319
  try {
6278
- resolve7(JSON.parse(data));
6320
+ resolve8(JSON.parse(data));
6279
6321
  } catch {
6280
- resolve7({ raw: data });
6322
+ resolve8({ raw: data });
6281
6323
  }
6282
6324
  });
6283
6325
  }).on("error", reject);
@@ -6291,7 +6333,7 @@ var DaemonCommandHandler = class {
6291
6333
  try {
6292
6334
  const http3 = await import("http");
6293
6335
  const postData = JSON.stringify(args || {});
6294
- const result = await new Promise((resolve7, reject) => {
6336
+ const result = await new Promise((resolve8, reject) => {
6295
6337
  const req = http3.request({
6296
6338
  hostname: "127.0.0.1",
6297
6339
  port: 19280,
@@ -6303,9 +6345,9 @@ var DaemonCommandHandler = class {
6303
6345
  res.on("data", (chunk) => data += chunk);
6304
6346
  res.on("end", () => {
6305
6347
  try {
6306
- resolve7(JSON.parse(data));
6348
+ resolve8(JSON.parse(data));
6307
6349
  } catch {
6308
- resolve7({ raw: data });
6350
+ resolve8({ raw: data });
6309
6351
  }
6310
6352
  });
6311
6353
  });
@@ -6330,10 +6372,10 @@ var path7 = __toESM(require("path"));
6330
6372
  var fs5 = __toESM(require("fs"));
6331
6373
  var path6 = __toESM(require("path"));
6332
6374
  var os7 = __toESM(require("os"));
6375
+ var chokidar = __toESM(require("chokidar"));
6333
6376
  init_logger();
6334
6377
  var ProviderLoader = class _ProviderLoader {
6335
6378
  providers = /* @__PURE__ */ new Map();
6336
- builtinDirs;
6337
6379
  userDir;
6338
6380
  upstreamDir;
6339
6381
  disableUpstream;
@@ -6348,36 +6390,31 @@ var ProviderLoader = class _ProviderLoader {
6348
6390
  static GITHUB_TARBALL_URL = "https://github.com/vilmire/adhdev-providers/archive/refs/heads/main.tar.gz";
6349
6391
  static META_FILE = ".meta.json";
6350
6392
  constructor(options) {
6351
- if (options?.builtinDir) {
6352
- this.builtinDirs = Array.isArray(options.builtinDir) ? options.builtinDir : [options.builtinDir];
6393
+ this.logFn = options?.logFn || LOG.forComponent("Provider").asLogFn();
6394
+ const defaultProvidersDir = path6.join(os7.homedir(), ".adhdev", "providers");
6395
+ if (options?.userDir) {
6396
+ this.userDir = options.userDir;
6397
+ this.log(`Config 'providerDir' applied: ${this.userDir}`);
6353
6398
  } else {
6354
- this.builtinDirs = [];
6399
+ const localRepoPath = path6.resolve(__dirname, "../../../../../adhdev-providers");
6400
+ if (fs5.existsSync(localRepoPath)) {
6401
+ this.userDir = localRepoPath;
6402
+ this.log(`Auto-detected local public repository: ${this.userDir} (Dev workspace speedup)`);
6403
+ } else {
6404
+ this.userDir = defaultProvidersDir;
6405
+ this.log(`Using default user providers directory: ${this.userDir}`);
6406
+ }
6355
6407
  }
6356
- const defaultProvidersDir = path6.join(os7.homedir(), ".adhdev", "providers");
6357
- this.userDir = options?.userDir || defaultProvidersDir;
6358
6408
  this.upstreamDir = path6.join(defaultProvidersDir, ".upstream");
6359
6409
  this.disableUpstream = options?.disableUpstream ?? false;
6360
- this.logFn = options?.logFn || LOG.forComponent("Provider").asLogFn();
6361
6410
  }
6362
6411
  log(msg) {
6363
6412
  this.logFn(`[ProviderLoader] ${msg}`);
6364
6413
  }
6365
6414
  // ─── Public API ────────────────────────────────
6366
6415
  /**
6367
- * Ordered builtin roots used for local fallback/reference data.
6368
- */
6369
- getBuiltinDirs() {
6370
- return [...this.builtinDirs];
6371
- }
6372
- /**
6373
- * Primary builtin root used for local scaffolding/reference flows.
6374
- */
6375
- getPrimaryBuiltinDir() {
6376
- return this.builtinDirs[0];
6377
- }
6378
- /**
6379
- * User override root (~/.adhdev/providers by default).
6380
- */
6416
+ * User override root (~/.adhdev/providers by default).
6417
+ */
6381
6418
  getUserDir() {
6382
6419
  return this.userDir;
6383
6420
  }
@@ -6388,11 +6425,11 @@ var ProviderLoader = class _ProviderLoader {
6388
6425
  return this.upstreamDir;
6389
6426
  }
6390
6427
  /**
6391
- * Provider search order for on-disk lookups.
6392
- * Highest-priority editable overrides come first.
6393
- */
6428
+ * Provider search order for on-disk lookups.
6429
+ * Highest-priority editable overrides come first.
6430
+ */
6394
6431
  getProviderRoots() {
6395
- return [this.userDir, this.upstreamDir, ...this.builtinDirs];
6432
+ return [this.userDir, this.upstreamDir];
6396
6433
  }
6397
6434
  /**
6398
6435
  * Canonical provider directory shape for a given root.
@@ -6413,16 +6450,9 @@ var ProviderLoader = class _ProviderLoader {
6413
6450
  return this.getProviderDir(this.upstreamDir, category, type);
6414
6451
  }
6415
6452
  /**
6416
- * Canonical builtin directory for a provider.
6453
+ * Find the on-disk directory for a provider by type.
6454
+ * Search order: user override → upstream.
6417
6455
  */
6418
- getBuiltinProviderDir(category, type) {
6419
- const builtinRoot = this.getPrimaryBuiltinDir();
6420
- return builtinRoot ? this.getProviderDir(builtinRoot, category, type) : "";
6421
- }
6422
- /**
6423
- * Find the on-disk directory for a provider by type.
6424
- * Search order: user override → upstream → builtin fallback.
6425
- */
6426
6456
  findProviderDir(type) {
6427
6457
  return this.findProviderDirInternal(type);
6428
6458
  }
@@ -6787,13 +6817,12 @@ var ProviderLoader = class _ProviderLoader {
6787
6817
  }
6788
6818
  }
6789
6819
  const result = this.buildScriptWrappersFromDir(dir);
6790
- this.log(` [loadScriptsFromDir] ${type}: built wrappers from ${dir} (${Object.keys(result).length} scripts)`);
6791
6820
  this.scriptsCache.set(dir, result);
6792
6821
  return result;
6793
6822
  }
6794
6823
  /**
6795
- * Hot-reload: start watching for file changes
6796
- */
6824
+ * Hot-reload: start watching for file changes
6825
+ */
6797
6826
  watch() {
6798
6827
  this.stopWatch();
6799
6828
  const watchDir = (dir) => {
@@ -6805,18 +6834,27 @@ var ProviderLoader = class _ProviderLoader {
6805
6834
  }
6806
6835
  }
6807
6836
  try {
6808
- const watcher = fs5.watch(dir, { recursive: true }, (event, filename) => {
6809
- if (filename?.endsWith(".js") || filename?.endsWith(".json")) {
6810
- this.log(`File changed: ${filename}, reloading...`);
6811
- this.loadAll();
6812
- }
6837
+ const watcher = chokidar.watch(dir, {
6838
+ ignored: /(^|[\/\\])\.\./,
6839
+ // ignore dotfiles
6840
+ persistent: true,
6841
+ ignoreInitial: true,
6842
+ awaitWriteFinish: { stabilityThreshold: 200, pollInterval: 50 }
6813
6843
  });
6844
+ const handleChange = (filePath) => {
6845
+ if (filePath.endsWith(".js") || filePath.endsWith(".json")) {
6846
+ this.log(`File changed: ${path6.basename(filePath)}, reloading...`);
6847
+ this.reload();
6848
+ }
6849
+ };
6850
+ watcher.on("add", handleChange).on("change", handleChange).on("unlink", handleChange);
6851
+ watcher.on("error", (err) => this.log(`Watch error: ${err.message}`));
6814
6852
  this.watchers.push(watcher);
6853
+ this.log(`Hot-reload watcher active: ${dir}`);
6815
6854
  } catch (e) {
6816
6855
  this.log(`Watch failed for ${dir}: ${e.message}`);
6817
6856
  }
6818
6857
  };
6819
- this.builtinDirs.forEach((dir) => watchDir(dir));
6820
6858
  watchDir(this.userDir);
6821
6859
  }
6822
6860
  /**
@@ -6877,7 +6915,7 @@ var ProviderLoader = class _ProviderLoader {
6877
6915
  return { updated: false };
6878
6916
  }
6879
6917
  try {
6880
- const etag = await new Promise((resolve7, reject) => {
6918
+ const etag = await new Promise((resolve8, reject) => {
6881
6919
  const options = {
6882
6920
  method: "HEAD",
6883
6921
  hostname: "github.com",
@@ -6895,7 +6933,7 @@ var ProviderLoader = class _ProviderLoader {
6895
6933
  headers: { "User-Agent": "adhdev-launcher" },
6896
6934
  timeout: 1e4
6897
6935
  }, (res2) => {
6898
- resolve7(res2.headers.etag || res2.headers["last-modified"] || "");
6936
+ resolve8(res2.headers.etag || res2.headers["last-modified"] || "");
6899
6937
  });
6900
6938
  req2.on("error", reject);
6901
6939
  req2.on("timeout", () => {
@@ -6904,7 +6942,7 @@ var ProviderLoader = class _ProviderLoader {
6904
6942
  });
6905
6943
  req2.end();
6906
6944
  } else {
6907
- resolve7(res.headers.etag || res.headers["last-modified"] || "");
6945
+ resolve8(res.headers.etag || res.headers["last-modified"] || "");
6908
6946
  }
6909
6947
  });
6910
6948
  req.on("error", reject);
@@ -6968,7 +7006,7 @@ var ProviderLoader = class _ProviderLoader {
6968
7006
  downloadFile(url, destPath) {
6969
7007
  const https = require("https");
6970
7008
  const http3 = require("http");
6971
- return new Promise((resolve7, reject) => {
7009
+ return new Promise((resolve8, reject) => {
6972
7010
  const doRequest = (reqUrl, redirectCount = 0) => {
6973
7011
  if (redirectCount > 5) {
6974
7012
  reject(new Error("Too many redirects"));
@@ -6988,7 +7026,7 @@ var ProviderLoader = class _ProviderLoader {
6988
7026
  res.pipe(ws);
6989
7027
  ws.on("finish", () => {
6990
7028
  ws.close();
6991
- resolve7();
7029
+ resolve8();
6992
7030
  });
6993
7031
  ws.on("error", reject);
6994
7032
  });
@@ -7260,8 +7298,8 @@ var ProviderLoader = class _ProviderLoader {
7260
7298
  const existed = this.providers.has(mod.type);
7261
7299
  this.providers.set(mod.type, mod);
7262
7300
  count++;
7263
- const source = d.startsWith(this.userDir) && !d.includes(".upstream") ? "user" : d.startsWith(this.upstreamDir) ? "upstream" : "builtin";
7264
- const overrideWarning = existed && source === "user" ? " \u26A0 OVERRIDES builtin/upstream" : "";
7301
+ const source = d.startsWith(this.userDir) && !d.includes(".upstream") ? "user" : "upstream";
7302
+ const overrideWarning = existed && source === "user" ? " \u26A0 OVERRIDES upstream" : "";
7265
7303
  this.log(` ${existed ? "\u{1F504}" : "\u2705"} ${mod.type} (${mod.category}) \u2014 ${mod.name} [${source}]${overrideWarning}`);
7266
7304
  }
7267
7305
  } catch (e) {
@@ -7353,17 +7391,17 @@ async function findFreePort(ports) {
7353
7391
  throw new Error("No free port found");
7354
7392
  }
7355
7393
  function checkPortFree(port) {
7356
- return new Promise((resolve7) => {
7394
+ return new Promise((resolve8) => {
7357
7395
  const server = net.createServer();
7358
7396
  server.unref();
7359
- server.on("error", () => resolve7(false));
7397
+ server.on("error", () => resolve8(false));
7360
7398
  server.listen(port, "127.0.0.1", () => {
7361
- server.close(() => resolve7(true));
7399
+ server.close(() => resolve8(true));
7362
7400
  });
7363
7401
  });
7364
7402
  }
7365
7403
  async function isCdpActive(port) {
7366
- return new Promise((resolve7) => {
7404
+ return new Promise((resolve8) => {
7367
7405
  const req = require("http").get(`http://127.0.0.1:${port}/json/version`, {
7368
7406
  timeout: 2e3
7369
7407
  }, (res) => {
@@ -7372,16 +7410,16 @@ async function isCdpActive(port) {
7372
7410
  res.on("end", () => {
7373
7411
  try {
7374
7412
  const info = JSON.parse(data);
7375
- resolve7(!!info["WebKit-Version"] || !!info["Browser"]);
7413
+ resolve8(!!info["WebKit-Version"] || !!info["Browser"]);
7376
7414
  } catch {
7377
- resolve7(false);
7415
+ resolve8(false);
7378
7416
  }
7379
7417
  });
7380
7418
  });
7381
- req.on("error", () => resolve7(false));
7419
+ req.on("error", () => resolve8(false));
7382
7420
  req.on("timeout", () => {
7383
7421
  req.destroy();
7384
- resolve7(false);
7422
+ resolve8(false);
7385
7423
  });
7386
7424
  });
7387
7425
  }
@@ -9042,13 +9080,13 @@ var AcpProviderInstance = class {
9042
9080
  }
9043
9081
  this.currentStatus = "waiting_approval";
9044
9082
  this.detectStatusTransition();
9045
- const approved = await new Promise((resolve7) => {
9046
- this.permissionResolvers.push(resolve7);
9083
+ const approved = await new Promise((resolve8) => {
9084
+ this.permissionResolvers.push(resolve8);
9047
9085
  setTimeout(() => {
9048
- const idx = this.permissionResolvers.indexOf(resolve7);
9086
+ const idx = this.permissionResolvers.indexOf(resolve8);
9049
9087
  if (idx >= 0) {
9050
9088
  this.permissionResolvers.splice(idx, 1);
9051
- resolve7(false);
9089
+ resolve8(false);
9052
9090
  }
9053
9091
  }, 3e5);
9054
9092
  });
@@ -11152,15 +11190,15 @@ var DevServer = class _DevServer {
11152
11190
  this.json(res, 500, { error: e.message });
11153
11191
  }
11154
11192
  });
11155
- return new Promise((resolve7, reject) => {
11193
+ return new Promise((resolve8, reject) => {
11156
11194
  this.server.listen(port, "127.0.0.1", () => {
11157
11195
  this.log(`Dev server listening on http://127.0.0.1:${port}`);
11158
- resolve7();
11196
+ resolve8();
11159
11197
  });
11160
11198
  this.server.on("error", (e) => {
11161
11199
  if (e.code === "EADDRINUSE") {
11162
11200
  this.log(`Port ${port} in use, skipping dev server`);
11163
- resolve7();
11201
+ resolve8();
11164
11202
  } else {
11165
11203
  reject(e);
11166
11204
  }
@@ -11243,20 +11281,20 @@ var DevServer = class _DevServer {
11243
11281
  child.stderr?.on("data", (d) => {
11244
11282
  stderr += d.toString().slice(0, 2e3);
11245
11283
  });
11246
- await new Promise((resolve7) => {
11284
+ await new Promise((resolve8) => {
11247
11285
  const timer = setTimeout(() => {
11248
11286
  child.kill();
11249
- resolve7();
11287
+ resolve8();
11250
11288
  }, 3e3);
11251
11289
  child.on("exit", () => {
11252
11290
  clearTimeout(timer);
11253
- resolve7();
11291
+ resolve8();
11254
11292
  });
11255
11293
  child.stdout?.once("data", () => {
11256
11294
  setTimeout(() => {
11257
11295
  child.kill();
11258
11296
  clearTimeout(timer);
11259
- resolve7();
11297
+ resolve8();
11260
11298
  }, 500);
11261
11299
  });
11262
11300
  });
@@ -12000,14 +12038,14 @@ var DevServer = class _DevServer {
12000
12038
  child.stderr?.on("data", (d) => {
12001
12039
  stderr += d.toString();
12002
12040
  });
12003
- await new Promise((resolve7) => {
12041
+ await new Promise((resolve8) => {
12004
12042
  const timer = setTimeout(() => {
12005
12043
  child.kill();
12006
- resolve7();
12044
+ resolve8();
12007
12045
  }, timeout);
12008
12046
  child.on("exit", () => {
12009
12047
  clearTimeout(timer);
12010
- resolve7();
12048
+ resolve8();
12011
12049
  });
12012
12050
  });
12013
12051
  const elapsed = Date.now() - start;
@@ -12851,25 +12889,63 @@ var DevServer = class _DevServer {
12851
12889
  const ref = this.providerLoader.resolve(desired) || this.providerLoader.getMeta(desired);
12852
12890
  if (ref?.category === category) return desired;
12853
12891
  const all = this.providerLoader.getAll();
12854
- const fallback = all.find((p) => p.category === category && p.type !== targetType);
12892
+ const fallback = all.filter((p) => p.category === category && p.type !== targetType).sort((a, b) => String(a.type || "").localeCompare(String(b.type || ""), void 0, { numeric: true, sensitivity: "base" }))[0];
12855
12893
  return fallback?.type || null;
12856
12894
  }
12857
- loadAutoImplReferenceScripts(category, referenceType) {
12858
- if (!referenceType) return {};
12859
- const refDir = this.providerLoader.getUpstreamProviderDir(category, referenceType);
12860
- if (!fs9.existsSync(refDir)) return {};
12861
- const referenceScripts = {};
12862
- const scriptsDir = path12.join(refDir, "scripts");
12863
- if (!fs9.existsSync(scriptsDir)) return referenceScripts;
12895
+ getLatestScriptVersionDir(scriptsDir) {
12896
+ if (!fs9.existsSync(scriptsDir)) return null;
12864
12897
  const versions = fs9.readdirSync(scriptsDir).filter((d) => {
12865
12898
  try {
12866
12899
  return fs9.statSync(path12.join(scriptsDir, d)).isDirectory();
12867
12900
  } catch {
12868
12901
  return false;
12869
12902
  }
12870
- }).sort().reverse();
12871
- if (versions.length === 0) return referenceScripts;
12872
- const latestDir = path12.join(scriptsDir, versions[0]);
12903
+ }).sort((a, b) => b.localeCompare(a, void 0, { numeric: true, sensitivity: "base" }));
12904
+ if (versions.length === 0) return null;
12905
+ return path12.join(scriptsDir, versions[0]);
12906
+ }
12907
+ resolveAutoImplWritableProviderDir(category, type, requestedDir) {
12908
+ const canonicalUserDir = path12.resolve(this.providerLoader.getUserProviderDir(category, type));
12909
+ const desiredDir = requestedDir ? path12.resolve(requestedDir) : canonicalUserDir;
12910
+ if (desiredDir !== canonicalUserDir) {
12911
+ return null;
12912
+ }
12913
+ const userRoot = path12.resolve(this.providerLoader.getUserDir());
12914
+ if (desiredDir !== userRoot && !desiredDir.startsWith(`${userRoot}${path12.sep}`)) {
12915
+ return null;
12916
+ }
12917
+ const sourceDir = this.findProviderDir(type);
12918
+ if (!sourceDir) {
12919
+ return null;
12920
+ }
12921
+ if (!fs9.existsSync(desiredDir)) {
12922
+ fs9.mkdirSync(path12.dirname(desiredDir), { recursive: true });
12923
+ fs9.cpSync(sourceDir, desiredDir, { recursive: true });
12924
+ this.log(`Auto-implement writable copy created: ${desiredDir}`);
12925
+ }
12926
+ const providerJson = path12.join(desiredDir, "provider.json");
12927
+ if (!fs9.existsSync(providerJson)) {
12928
+ return null;
12929
+ }
12930
+ try {
12931
+ const providerData = JSON.parse(fs9.readFileSync(providerJson, "utf-8"));
12932
+ if (providerData.disableUpstream !== true) {
12933
+ providerData.disableUpstream = true;
12934
+ fs9.writeFileSync(providerJson, JSON.stringify(providerData, null, 2));
12935
+ }
12936
+ } catch {
12937
+ return null;
12938
+ }
12939
+ return desiredDir;
12940
+ }
12941
+ loadAutoImplReferenceScripts(referenceType) {
12942
+ if (!referenceType) return {};
12943
+ const refDir = this.findProviderDir(referenceType);
12944
+ if (!refDir || !fs9.existsSync(refDir)) return {};
12945
+ const referenceScripts = {};
12946
+ const scriptsDir = path12.join(refDir, "scripts");
12947
+ const latestDir = this.getLatestScriptVersionDir(scriptsDir);
12948
+ if (!latestDir) return referenceScripts;
12873
12949
  for (const file of fs9.readdirSync(latestDir)) {
12874
12950
  if (!file.endsWith(".js")) continue;
12875
12951
  try {
@@ -12881,7 +12957,7 @@ var DevServer = class _DevServer {
12881
12957
  }
12882
12958
  async handleAutoImplement(type, req, res) {
12883
12959
  const body = await this.readBody(req);
12884
- const { agent = "claude-cli", functions, reference = "antigravity", model, comment } = body;
12960
+ const { agent = "claude-cli", functions, reference, model, comment, providerDir: requestedProviderDir } = body;
12885
12961
  if (!functions || !Array.isArray(functions) || functions.length === 0) {
12886
12962
  this.json(res, 400, { error: 'functions[] is required (e.g. ["readChat", "sendMessage"])' });
12887
12963
  return;
@@ -12895,9 +12971,11 @@ var DevServer = class _DevServer {
12895
12971
  this.json(res, 404, { error: `Provider not found: ${type}` });
12896
12972
  return;
12897
12973
  }
12898
- const providerDir = this.findProviderDir(type);
12974
+ const providerDir = this.resolveAutoImplWritableProviderDir(provider.category, type, requestedProviderDir);
12899
12975
  if (!providerDir) {
12900
- this.json(res, 404, { error: `Provider directory not found: ${type}` });
12976
+ this.json(res, 409, {
12977
+ error: `Auto-implement only writes to the canonical user provider directory for '${type}'.`
12978
+ });
12901
12979
  return;
12902
12980
  }
12903
12981
  try {
@@ -12919,7 +12997,7 @@ var DevServer = class _DevServer {
12919
12997
  message: `Loading reference script (${resolvedReference || "none"})...`
12920
12998
  }
12921
12999
  });
12922
- const referenceScripts = this.loadAutoImplReferenceScripts(provider.category, resolvedReference);
13000
+ const referenceScripts = this.loadAutoImplReferenceScripts(resolvedReference);
12923
13001
  const prompt = this.buildAutoImplPrompt(type, provider, providerDir, functions, domContext, referenceScripts, comment, resolvedReference);
12924
13002
  const tmpDir = path12.join(os14.tmpdir(), "adhdev-autoimpl");
12925
13003
  if (!fs9.existsSync(tmpDir)) fs9.mkdirSync(tmpDir, { recursive: true });
@@ -13275,29 +13353,20 @@ var DevServer = class _DevServer {
13275
13353
  lines.push("These are the files you need to EDIT. They contain TODO stubs \u2014 replace them with working implementations.");
13276
13354
  lines.push("");
13277
13355
  const scriptsDir = path12.join(providerDir, "scripts");
13278
- if (fs9.existsSync(scriptsDir)) {
13279
- const versions = fs9.readdirSync(scriptsDir).filter((d) => {
13280
- try {
13281
- return fs9.statSync(path12.join(scriptsDir, d)).isDirectory();
13282
- } catch {
13283
- return false;
13284
- }
13285
- }).sort().reverse();
13286
- if (versions.length > 0) {
13287
- const vDir = path12.join(scriptsDir, versions[0]);
13288
- lines.push(`Scripts version directory: \`${vDir}\``);
13289
- lines.push("");
13290
- for (const file of fs9.readdirSync(vDir)) {
13291
- if (file.endsWith(".js")) {
13292
- try {
13293
- const content = fs9.readFileSync(path12.join(vDir, file), "utf-8");
13294
- lines.push(`### \`${file}\``);
13295
- lines.push("```javascript");
13296
- lines.push(content);
13297
- lines.push("```");
13298
- lines.push("");
13299
- } catch {
13300
- }
13356
+ const latestScriptsDir = this.getLatestScriptVersionDir(scriptsDir);
13357
+ if (latestScriptsDir) {
13358
+ lines.push(`Scripts version directory: \`${latestScriptsDir}\``);
13359
+ lines.push("");
13360
+ for (const file of fs9.readdirSync(latestScriptsDir)) {
13361
+ if (file.endsWith(".js")) {
13362
+ try {
13363
+ const content = fs9.readFileSync(path12.join(latestScriptsDir, file), "utf-8");
13364
+ lines.push(`### \`${file}\``);
13365
+ lines.push("```javascript");
13366
+ lines.push(content);
13367
+ lines.push("```");
13368
+ lines.push("");
13369
+ } catch {
13301
13370
  }
13302
13371
  }
13303
13372
  }
@@ -13378,7 +13447,7 @@ var DevServer = class _DevServer {
13378
13447
  lines.push("## Rules");
13379
13448
  lines.push("1. **Scripts WITHOUT params** \u2192 IIFE: `(() => { ... })()`");
13380
13449
  lines.push("2. **Scripts WITH params** \u2192 arrow: `(params) => { ... }` \u2014 router calls `(${script})(${JSON.stringify(params)})`");
13381
- lines.push("3. Use CSS selectors from the DOM analysis above");
13450
+ lines.push("3. If live DOM analysis is included above, use it. Otherwise, discover selectors yourself via CDP before coding.");
13382
13451
  lines.push("4. Always wrap in try-catch, return `JSON.stringify(result)`");
13383
13452
  lines.push("5. Do NOT modify `scripts.js` router \u2014 only edit individual `*.js` files");
13384
13453
  lines.push("6. All scripts run in the browser (CDP evaluate) \u2014 use DOM APIs only");
@@ -13427,8 +13496,12 @@ var DevServer = class _DevServer {
13427
13496
  lines.push(" - `listSessions`: If sessions are unmounted when the panel is closed, try to explicitly interact with the UI to open the history/sessions view (e.g., clicking a history icon usually found near the chat header) BEFORE scraping.");
13428
13497
  lines.push(" - `switchSession`: Prove your switch was successful by subsequently calling `readChat` and explicitly checking that the chat context has actually changed.");
13429
13498
  lines.push("");
13430
- lines.push("## YOU MUST EXPLORE THE DOM YOURSELF!");
13431
- lines.push("I have NOT provided you with the DOM snapshot. You MUST use your command-line tools to discover the IDE structure dynamically!");
13499
+ lines.push("## DOM Exploration");
13500
+ if (domContext) {
13501
+ lines.push("A lightweight DOM snapshot is included above, but you MUST still verify selectors yourself before finalizing the scripts.");
13502
+ } else {
13503
+ lines.push("No DOM snapshot is included here. You MUST use your command-line tools to discover the IDE structure dynamically.");
13504
+ }
13432
13505
  lines.push("");
13433
13506
  lines.push("### 1. Evaluate JS to explore IDE DOM");
13434
13507
  lines.push("Use cURL to run JavaScript inside the IDE:");
@@ -13515,29 +13588,20 @@ var DevServer = class _DevServer {
13515
13588
  lines.push("These are the files you need to edit. Replace TODO or heuristic-only logic with working PTY-aware implementations.");
13516
13589
  lines.push("");
13517
13590
  const scriptsDir = path12.join(providerDir, "scripts");
13518
- if (fs9.existsSync(scriptsDir)) {
13519
- const versions = fs9.readdirSync(scriptsDir).filter((d) => {
13591
+ const latestScriptsDir = this.getLatestScriptVersionDir(scriptsDir);
13592
+ if (latestScriptsDir) {
13593
+ lines.push(`Scripts version directory: \`${latestScriptsDir}\``);
13594
+ lines.push("");
13595
+ for (const file of fs9.readdirSync(latestScriptsDir)) {
13596
+ if (!file.endsWith(".js")) continue;
13520
13597
  try {
13521
- return fs9.statSync(path12.join(scriptsDir, d)).isDirectory();
13598
+ const content = fs9.readFileSync(path12.join(latestScriptsDir, file), "utf-8");
13599
+ lines.push(`### \`${file}\``);
13600
+ lines.push("```javascript");
13601
+ lines.push(content);
13602
+ lines.push("```");
13603
+ lines.push("");
13522
13604
  } catch {
13523
- return false;
13524
- }
13525
- }).sort().reverse();
13526
- if (versions.length > 0) {
13527
- const vDir = path12.join(scriptsDir, versions[0]);
13528
- lines.push(`Scripts version directory: \`${vDir}\``);
13529
- lines.push("");
13530
- for (const file of fs9.readdirSync(vDir)) {
13531
- if (!file.endsWith(".js")) continue;
13532
- try {
13533
- const content = fs9.readFileSync(path12.join(vDir, file), "utf-8");
13534
- lines.push(`### \`${file}\``);
13535
- lines.push("```javascript");
13536
- lines.push(content);
13537
- lines.push("```");
13538
- lines.push("");
13539
- } catch {
13540
- }
13541
13605
  }
13542
13606
  }
13543
13607
  }
@@ -13751,14 +13815,14 @@ data: ${JSON.stringify(msg.data)}
13751
13815
  res.end(JSON.stringify(data, null, 2));
13752
13816
  }
13753
13817
  async readBody(req) {
13754
- return new Promise((resolve7) => {
13818
+ return new Promise((resolve8) => {
13755
13819
  let body = "";
13756
13820
  req.on("data", (chunk) => body += chunk);
13757
13821
  req.on("end", () => {
13758
13822
  try {
13759
- resolve7(JSON.parse(body));
13823
+ resolve8(JSON.parse(body));
13760
13824
  } catch {
13761
- resolve7({});
13825
+ resolve8({});
13762
13826
  }
13763
13827
  });
13764
13828
  });
@@ -14138,10 +14202,10 @@ async function installExtension(ide, extension) {
14138
14202
  const buffer = Buffer.from(await res.arrayBuffer());
14139
14203
  const fs10 = await import("fs");
14140
14204
  fs10.writeFileSync(vsixPath, buffer);
14141
- return new Promise((resolve7) => {
14205
+ return new Promise((resolve8) => {
14142
14206
  const cmd = `"${ide.cliCommand}" --install-extension "${vsixPath}" --force`;
14143
14207
  (0, import_child_process8.exec)(cmd, { timeout: 6e4 }, (error, _stdout, stderr) => {
14144
- resolve7({
14208
+ resolve8({
14145
14209
  extensionId: extension.id,
14146
14210
  marketplaceId: extension.marketplaceId,
14147
14211
  success: !error,
@@ -14154,11 +14218,11 @@ async function installExtension(ide, extension) {
14154
14218
  } catch (e) {
14155
14219
  }
14156
14220
  }
14157
- return new Promise((resolve7) => {
14221
+ return new Promise((resolve8) => {
14158
14222
  const cmd = `"${ide.cliCommand}" --install-extension ${extension.marketplaceId} --force`;
14159
14223
  (0, import_child_process8.exec)(cmd, { timeout: 6e4 }, (error, stdout, stderr) => {
14160
14224
  if (error) {
14161
- resolve7({
14225
+ resolve8({
14162
14226
  extensionId: extension.id,
14163
14227
  marketplaceId: extension.marketplaceId,
14164
14228
  success: false,
@@ -14166,7 +14230,7 @@ async function installExtension(ide, extension) {
14166
14230
  error: stderr || error.message
14167
14231
  });
14168
14232
  } else {
14169
- resolve7({
14233
+ resolve8({
14170
14234
  extensionId: extension.id,
14171
14235
  marketplaceId: extension.marketplaceId,
14172
14236
  success: true,
@@ -14321,6 +14385,18 @@ async function initDaemonComponents(config) {
14321
14385
  detectedIdes: detectedIdesRef
14322
14386
  };
14323
14387
  }
14388
+ async function startDaemonDevSupport(options) {
14389
+ const devServer = new DevServer({
14390
+ providerLoader: options.components.providerLoader,
14391
+ cdpManagers: options.components.cdpManagers,
14392
+ instanceManager: options.components.instanceManager,
14393
+ cliManager: options.components.cliManager,
14394
+ logFn: options.logFn
14395
+ });
14396
+ await devServer.start();
14397
+ options.components.providerLoader.watch();
14398
+ return devServer;
14399
+ }
14324
14400
  async function shutdownDaemonComponents(components) {
14325
14401
  const {
14326
14402
  poller,
@@ -14421,6 +14497,7 @@ async function shutdownDaemonComponents(components) {
14421
14497
  setLogLevel,
14422
14498
  setupIdeInstance,
14423
14499
  shutdownDaemonComponents,
14500
+ startDaemonDevSupport,
14424
14501
  updateConfig
14425
14502
  });
14426
14503
  //# sourceMappingURL=index.js.map