adhdev 0.9.28 → 0.9.30

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
@@ -70,6 +70,29 @@ function asOptionalString(value) {
70
70
  function asBoolean(value, fallback2) {
71
71
  return typeof value === "boolean" ? value : fallback2;
72
72
  }
73
+ function normalizeMachineProviders(value) {
74
+ if (!isPlainObject(value)) return {};
75
+ const result = {};
76
+ for (const [providerType, raw] of Object.entries(value)) {
77
+ if (!isPlainObject(raw)) continue;
78
+ const entry = {};
79
+ if (raw.enabled === true) entry.enabled = true;
80
+ if (typeof raw.executable === "string" && raw.executable.trim()) {
81
+ entry.executable = raw.executable.trim();
82
+ }
83
+ if (Array.isArray(raw.args)) {
84
+ entry.args = raw.args.filter((arg) => typeof arg === "string");
85
+ }
86
+ if (isPlainObject(raw.lastDetection)) {
87
+ entry.lastDetection = raw.lastDetection;
88
+ }
89
+ if (isPlainObject(raw.lastVerification)) {
90
+ entry.lastVerification = raw.lastVerification;
91
+ }
92
+ result[providerType] = entry;
93
+ }
94
+ return result;
95
+ }
73
96
  function normalizeConfig(raw) {
74
97
  const parsed = isPlainObject(raw) ? raw : {};
75
98
  return {
@@ -90,6 +113,7 @@ function normalizeConfig(raw) {
90
113
  machineSecret: parsed.machineSecret === null ? null : asOptionalString(parsed.machineSecret),
91
114
  registeredMachineId: asOptionalString(parsed.registeredMachineId),
92
115
  providerSettings: isPlainObject(parsed.providerSettings) ? parsed.providerSettings : {},
116
+ machineProviders: normalizeMachineProviders(parsed.machineProviders),
93
117
  ideSettings: isPlainObject(parsed.ideSettings) ? parsed.ideSettings : {},
94
118
  providerSourceMode: resolveProviderSourceMode(parsed.providerSourceMode, parsed.disableUpstream),
95
119
  providerDir: asOptionalString(parsed.providerDir),
@@ -239,6 +263,7 @@ var init_config = __esm({
239
263
  machineSecret: null,
240
264
  registeredMachineId: void 0,
241
265
  providerSettings: {},
266
+ machineProviders: {},
242
267
  ideSettings: {},
243
268
  providerSourceMode: "normal",
244
269
  terminalSizingMode: "measured"
@@ -32114,6 +32139,27 @@ var init_hosted_runtime_restore = __esm({
32114
32139
  });
32115
32140
 
32116
32141
  // ../../oss/packages/daemon-core/src/commands/cli-manager.ts
32142
+ function isExplicitCommand(command) {
32143
+ const trimmed = command.trim();
32144
+ return path12.isAbsolute(trimmed) || trimmed.includes("/") || trimmed.includes("\\") || trimmed.startsWith("~");
32145
+ }
32146
+ function expandExecutable(command) {
32147
+ const trimmed = command.trim();
32148
+ return trimmed.startsWith("~") ? path12.join(os14.homedir(), trimmed.slice(1)) : trimmed;
32149
+ }
32150
+ function commandExists(command) {
32151
+ const trimmed = command.trim();
32152
+ if (!trimmed) return false;
32153
+ if (isExplicitCommand(trimmed)) {
32154
+ return (0, import_fs5.existsSync)(expandExecutable(trimmed));
32155
+ }
32156
+ try {
32157
+ (0, import_child_process6.execFileSync)(process.platform === "win32" ? "where" : "which", [trimmed], { stdio: "ignore" });
32158
+ return true;
32159
+ } catch {
32160
+ return false;
32161
+ }
32162
+ }
32117
32163
  function colorize(color, text) {
32118
32164
  const fn = chalkApi?.[color];
32119
32165
  return typeof fn === "function" ? fn(text) : text;
@@ -32233,13 +32279,15 @@ function resolveCliSessionBinding(provider, normalizedType, cliArgs, requestedRe
32233
32279
  launchMode: "new"
32234
32280
  };
32235
32281
  }
32236
- var os14, path12, crypto4, chalkModule, chalkApi, DaemonCliManager;
32282
+ var os14, path12, crypto4, import_fs5, import_child_process6, chalkModule, chalkApi, DaemonCliManager;
32237
32283
  var init_cli_manager = __esm({
32238
32284
  "../../oss/packages/daemon-core/src/commands/cli-manager.ts"() {
32239
32285
  "use strict";
32240
32286
  os14 = __toESM(require("os"));
32241
32287
  path12 = __toESM(require("path"));
32242
32288
  crypto4 = __toESM(require("crypto"));
32289
+ import_fs5 = require("fs");
32290
+ import_child_process6 = require("child_process");
32243
32291
  init_source();
32244
32292
  init_provider_cli_adapter();
32245
32293
  init_cli_detector();
@@ -32401,29 +32449,33 @@ var init_cli_manager = __esm({
32401
32449
  if (!trimmed) throw new Error("working directory required");
32402
32450
  const resolvedDir = trimmed.startsWith("~") ? trimmed.replace(/^~/, os14.homedir()) : path12.resolve(trimmed);
32403
32451
  const normalizedType = this.providerLoader.resolveAlias(cliType);
32404
- const provider = this.providerLoader.getByAlias(cliType);
32452
+ const rawProvider = this.providerLoader.getByAlias(cliType);
32453
+ const provider = rawProvider ? this.providerLoader.resolve(normalizedType) || rawProvider : void 0;
32454
+ if (provider && (provider.category === "cli" || provider.category === "acp") && !this.providerLoader.isMachineProviderEnabled(normalizedType)) {
32455
+ const displayName = provider.displayName || provider.name || normalizedType;
32456
+ throw new Error(
32457
+ `${displayName} is disabled on this machine.
32458
+ Enable and detect this provider from the Machine Providers page before starting a runtime.`
32459
+ );
32460
+ }
32405
32461
  const key = crypto4.randomUUID();
32406
32462
  const sessionRegistry = this.deps.getSessionRegistry?.() || null;
32407
32463
  if (provider && provider.category === "acp") {
32408
32464
  const instanceManager2 = this.deps.getInstanceManager();
32409
32465
  if (!instanceManager2) throw new Error("InstanceManager not available");
32410
- const spawnCmd = provider.spawn?.command;
32411
- if (spawnCmd) {
32412
- try {
32413
- const { execSync: execSync7 } = require("child_process");
32414
- execSync7(`which ${spawnCmd}`, { stdio: "ignore" });
32415
- } catch {
32416
- const installInfo = provider.install || `Install: check ${provider.displayName || provider.name} documentation`;
32417
- throw new Error(
32418
- `${provider.displayName || provider.name} is not installed.
32419
- Command '${spawnCmd}' not found in PATH.
32466
+ const resolvedProvider = this.providerLoader.resolve(normalizedType) || provider;
32467
+ const spawnCmd = resolvedProvider.spawn?.command;
32468
+ if (spawnCmd && !commandExists(spawnCmd)) {
32469
+ const installInfo = provider.install || `Install: check ${provider.displayName || provider.name} documentation`;
32470
+ throw new Error(
32471
+ `${provider.displayName || provider.name} is not installed.
32472
+ Command '${spawnCmd}' not found.
32420
32473
 
32421
32474
  ${installInfo}`
32422
- );
32423
- }
32475
+ );
32424
32476
  }
32425
32477
  console.log(colorize("cyan", ` \u{1F50C} Starting ACP agent: ${provider.name} (${provider.type}) in ${resolvedDir}`));
32426
- const acpInstance = new AcpProviderInstance(provider, resolvedDir, cliArgs);
32478
+ const acpInstance = new AcpProviderInstance(resolvedProvider, resolvedDir, cliArgs);
32427
32479
  await instanceManager2.addInstance(key, acpInstance, {
32428
32480
  settings: this.providerLoader.getSettings(normalizedType)
32429
32481
  });
@@ -35120,15 +35172,18 @@ var init_provider_loader = __esm({
35120
35172
  getCliDetectionList() {
35121
35173
  const result = [];
35122
35174
  for (const p of this.providers.values()) {
35123
- if ((p.category === "cli" || p.category === "acp") && p.spawn?.command) {
35175
+ if ((p.category === "cli" || p.category === "acp") && p.spawn?.command && this.isMachineProviderEnabled(p.type)) {
35124
35176
  const versionCommand = this.getPlatformVersionCommand(p.versionCommand);
35125
35177
  const command = this.getSpawnCommand(p.type, p.spawn.command);
35178
+ const args = this.getSpawnArgs(p.type, p.spawn.args || []);
35126
35179
  result.push({
35127
35180
  id: p.type,
35128
35181
  displayName: p.displayName || p.name,
35129
35182
  icon: p.icon || "\u{1F527}",
35130
35183
  command,
35184
+ ...args.length > 0 ? { args } : {},
35131
35185
  category: p.category,
35186
+ enabled: true,
35132
35187
  ...typeof versionCommand === "string" && versionCommand.trim() ? { versionCommand: versionCommand.trim() } : {}
35133
35188
  });
35134
35189
  }
@@ -35257,9 +35312,10 @@ var init_provider_loader = __esm({
35257
35312
  return [...this.providers.values()].filter((p) => p.category === "ide" && p.cdpPorts).map((p) => p.type);
35258
35313
  }
35259
35314
  getSpawnCommand(type, fallback2) {
35260
- const override = this.getOptionalStringSetting(type, "executablePath");
35261
- if (override) return override;
35262
- return fallback2 || this.providers.get(type)?.spawn?.command || type;
35315
+ const providerType = this.resolveAlias(type);
35316
+ const machineConfig = this.getMachineProviderConfig(providerType);
35317
+ if (machineConfig.executable) return machineConfig.executable;
35318
+ return fallback2 || this.providers.get(providerType)?.spawn?.command || providerType;
35263
35319
  }
35264
35320
  getIdeCliCommand(type, fallback2) {
35265
35321
  const override = this.getOptionalStringSetting(type, "cliPathOverride");
@@ -35273,6 +35329,131 @@ var init_provider_loader = __esm({
35273
35329
  const osPaths = this.providers.get(type)?.paths?.[process.platform];
35274
35330
  return Array.isArray(osPaths) ? [...osPaths] : [];
35275
35331
  }
35332
+ isMachineProviderEnabled(type) {
35333
+ const providerType = this.resolveAlias(type);
35334
+ const config2 = this.readConfig();
35335
+ return config2?.machineProviders?.[providerType]?.enabled === true;
35336
+ }
35337
+ getMachineProviderConfig(type) {
35338
+ const providerType = this.resolveAlias(type);
35339
+ const raw = this.readConfig()?.machineProviders?.[providerType];
35340
+ if (!raw || typeof raw !== "object") return {};
35341
+ const executable = typeof raw.executable === "string" && raw.executable.trim() ? raw.executable.trim() : void 0;
35342
+ return {
35343
+ ...raw.enabled === true ? { enabled: true } : {},
35344
+ ...executable ? { executable } : {},
35345
+ ...Array.isArray(raw.args) ? { args: raw.args.filter((arg) => typeof arg === "string") } : {},
35346
+ ...raw.lastDetection && typeof raw.lastDetection === "object" ? { lastDetection: raw.lastDetection } : {},
35347
+ ...raw.lastVerification && typeof raw.lastVerification === "object" ? { lastVerification: raw.lastVerification } : {}
35348
+ };
35349
+ }
35350
+ setMachineProviderConfig(type, patch) {
35351
+ const providerType = this.resolveAlias(type);
35352
+ if (!this.providers.has(providerType)) return false;
35353
+ const config2 = this.readConfig();
35354
+ if (!config2) return false;
35355
+ try {
35356
+ if (!config2.machineProviders) config2.machineProviders = {};
35357
+ const current = config2.machineProviders[providerType] || {};
35358
+ const next = { ...current };
35359
+ const enabledChanged = "enabled" in patch && current.enabled !== (patch.enabled === true);
35360
+ const executableChanged = "executable" in patch;
35361
+ const argsChanged = "args" in patch;
35362
+ if ("enabled" in patch) next.enabled = patch.enabled === true;
35363
+ if ("executable" in patch) {
35364
+ const executable = typeof patch.executable === "string" ? patch.executable.trim() : "";
35365
+ if (executable) next.executable = executable;
35366
+ else delete next.executable;
35367
+ }
35368
+ if ("args" in patch) {
35369
+ if (Array.isArray(patch.args)) next.args = patch.args.filter((arg) => typeof arg === "string");
35370
+ else delete next.args;
35371
+ }
35372
+ if (enabledChanged || executableChanged || argsChanged) {
35373
+ delete next.lastDetection;
35374
+ delete next.lastVerification;
35375
+ }
35376
+ if ("lastDetection" in patch) {
35377
+ if (patch.lastDetection) next.lastDetection = patch.lastDetection;
35378
+ else delete next.lastDetection;
35379
+ }
35380
+ if ("lastVerification" in patch) {
35381
+ if (patch.lastVerification) next.lastVerification = patch.lastVerification;
35382
+ else delete next.lastVerification;
35383
+ }
35384
+ config2.machineProviders[providerType] = next;
35385
+ if (next.enabled !== true) {
35386
+ this.providerAvailability.set(providerType, { installed: false, detectedPath: null });
35387
+ }
35388
+ this.writeConfig(config2);
35389
+ this.log(`Machine provider config updated: ${providerType}`);
35390
+ return true;
35391
+ } catch (e) {
35392
+ this.log(`Failed to save machine provider config: ${e.message}`);
35393
+ return false;
35394
+ }
35395
+ }
35396
+ setMachineProviderEnabled(type, enabled) {
35397
+ return this.setMachineProviderConfig(type, { enabled });
35398
+ }
35399
+ getMachineProviderStatus(type) {
35400
+ const providerType = this.resolveAlias(type);
35401
+ if (!this.isMachineProviderEnabled(providerType)) return "disabled";
35402
+ const availability = this.providerAvailability.get(providerType);
35403
+ if (!availability) return "enabled_unchecked";
35404
+ return availability.installed ? "detected" : "not_detected";
35405
+ }
35406
+ getSpawnArgs(type, fallback2 = []) {
35407
+ const machineConfig = this.getMachineProviderConfig(type);
35408
+ if (machineConfig.args) return [...machineConfig.args];
35409
+ return [...fallback2];
35410
+ }
35411
+ parseArgsSetting(value) {
35412
+ const args = [];
35413
+ let current = "";
35414
+ let quote = null;
35415
+ let escaping = false;
35416
+ for (const ch of value.trim()) {
35417
+ if (escaping) {
35418
+ current += ch;
35419
+ escaping = false;
35420
+ continue;
35421
+ }
35422
+ if (ch === "\\") {
35423
+ escaping = true;
35424
+ continue;
35425
+ }
35426
+ if (quote === "single") {
35427
+ if (ch === "'") quote = null;
35428
+ else current += ch;
35429
+ continue;
35430
+ }
35431
+ if (quote === "double") {
35432
+ if (ch === '"') quote = null;
35433
+ else current += ch;
35434
+ continue;
35435
+ }
35436
+ if (ch === "'") {
35437
+ quote = "single";
35438
+ continue;
35439
+ }
35440
+ if (ch === '"') {
35441
+ quote = "double";
35442
+ continue;
35443
+ }
35444
+ if (/\s/.test(ch)) {
35445
+ if (current) {
35446
+ args.push(current);
35447
+ current = "";
35448
+ }
35449
+ continue;
35450
+ }
35451
+ current += ch;
35452
+ }
35453
+ if (escaping) current += "\\";
35454
+ if (current) args.push(current);
35455
+ return args;
35456
+ }
35276
35457
  setProviderAvailability(type, state) {
35277
35458
  this.providerAvailability.set(type, {
35278
35459
  installed: !!state.installed,
@@ -35280,18 +35461,53 @@ var init_provider_loader = __esm({
35280
35461
  });
35281
35462
  }
35282
35463
  setCliDetectionResults(results, replace = true) {
35464
+ const resultByType = /* @__PURE__ */ new Map();
35465
+ for (const result of results) {
35466
+ resultByType.set(this.resolveAlias(result.id), result);
35467
+ }
35283
35468
  if (replace) {
35284
35469
  for (const provider of this.providers.values()) {
35285
35470
  if (provider.category === "cli" || provider.category === "acp") {
35286
- this.providerAvailability.set(provider.type, { installed: false, detectedPath: null });
35471
+ const result = resultByType.get(provider.type);
35472
+ const installed = !!result?.installed;
35473
+ const detectedPath = result?.path || null;
35474
+ this.providerAvailability.set(provider.type, { installed, detectedPath });
35475
+ if (this.isMachineProviderEnabled(provider.type)) {
35476
+ this.setMachineProviderConfig(provider.type, {
35477
+ lastDetection: {
35478
+ ok: installed,
35479
+ stage: "detection",
35480
+ checkedAt: (/* @__PURE__ */ new Date()).toISOString(),
35481
+ command: this.getSpawnCommand(provider.type, provider.spawn?.command),
35482
+ path: detectedPath,
35483
+ message: installed ? "Provider command detected" : "Provider command was not detected"
35484
+ }
35485
+ });
35486
+ }
35287
35487
  }
35288
35488
  }
35489
+ return;
35289
35490
  }
35290
35491
  for (const result of results) {
35291
- this.setProviderAvailability(result.id, {
35492
+ const providerType = this.resolveAlias(result.id);
35493
+ const provider = this.providers.get(providerType);
35494
+ const detectedPath = result.path || null;
35495
+ this.setProviderAvailability(providerType, {
35292
35496
  installed: !!result.installed,
35293
- detectedPath: result.path || null
35497
+ detectedPath
35294
35498
  });
35499
+ if (provider && (provider.category === "cli" || provider.category === "acp") && this.isMachineProviderEnabled(providerType)) {
35500
+ this.setMachineProviderConfig(providerType, {
35501
+ lastDetection: {
35502
+ ok: !!result.installed,
35503
+ stage: "detection",
35504
+ checkedAt: (/* @__PURE__ */ new Date()).toISOString(),
35505
+ command: this.getSpawnCommand(providerType, provider.spawn?.command),
35506
+ path: detectedPath,
35507
+ message: result.installed ? "Provider command detected" : "Provider command was not detected"
35508
+ }
35509
+ });
35510
+ }
35295
35511
  }
35296
35512
  }
35297
35513
  setIdeDetectionResults(results, replace = true) {
@@ -35312,8 +35528,14 @@ var init_provider_loader = __esm({
35312
35528
  getAvailableProviderInfos() {
35313
35529
  return this.getAll().map((provider) => {
35314
35530
  const availability = this.providerAvailability.get(provider.type);
35531
+ const enabled = this.isMachineProviderEnabled(provider.type);
35532
+ const machineConfig = this.getMachineProviderConfig(provider.type);
35315
35533
  return {
35316
35534
  ...provider,
35535
+ enabled,
35536
+ machineStatus: this.getMachineProviderStatus(provider.type),
35537
+ ...machineConfig.lastDetection ? { lastDetection: machineConfig.lastDetection } : {},
35538
+ ...machineConfig.lastVerification ? { lastVerification: machineConfig.lastVerification } : {},
35317
35539
  ...availability ? {
35318
35540
  installed: availability.installed,
35319
35541
  detectedPath: availability.detectedPath
@@ -35460,6 +35682,13 @@ var init_provider_loader = __esm({
35460
35682
  }
35461
35683
  }
35462
35684
  }
35685
+ if ((resolved.category === "cli" || resolved.category === "acp") && resolved.spawn?.command) {
35686
+ resolved.spawn = {
35687
+ ...resolved.spawn,
35688
+ command: this.getSpawnCommand(type, resolved.spawn.command),
35689
+ args: this.getSpawnArgs(type, resolved.spawn.args || [])
35690
+ };
35691
+ }
35463
35692
  return resolved;
35464
35693
  }
35465
35694
  /**
@@ -35782,20 +36011,33 @@ var init_provider_loader = __esm({
35782
36011
  * Resolved setting value for a provider (default + user override)
35783
36012
  */
35784
36013
  getSettingValue(type, key) {
35785
- const schemaDef = this.getSettingsSchema(type)[key];
36014
+ const providerType = this.resolveAlias(type);
36015
+ const machineConfig = this.getMachineProviderConfig(providerType);
36016
+ if (key === "enabled") {
36017
+ return machineConfig.enabled === true;
36018
+ }
36019
+ if (key === "executablePath") {
36020
+ return machineConfig.executable || "";
36021
+ }
36022
+ if (key === "executableArgs") {
36023
+ const args = machineConfig.args;
36024
+ return args ? args.map((arg) => /\s/.test(arg) ? JSON.stringify(arg) : arg).join(" ") : "";
36025
+ }
36026
+ const schemaDef = this.getSettingsSchema(providerType)[key];
35786
36027
  const defaultVal = schemaDef ? key === "autoApprove" && schemaDef.type === "boolean" ? true : schemaDef.default : void 0;
35787
36028
  const config2 = this.readConfig();
35788
- const userVal = config2?.providerSettings?.[type]?.[key];
36029
+ const userVal = config2?.providerSettings?.[providerType]?.[key];
35789
36030
  return userVal !== void 0 ? userVal : defaultVal;
35790
36031
  }
35791
36032
  /**
35792
36033
  * All resolved settings for a provider (default + user override)
35793
36034
  */
35794
36035
  getSettings(type) {
35795
- const settings = this.getSettingsSchema(type);
36036
+ const providerType = this.resolveAlias(type);
36037
+ const settings = this.getSettingsSchema(providerType);
35796
36038
  const result = {};
35797
36039
  for (const [key] of Object.entries(settings)) {
35798
- result[key] = this.getSettingValue(type, key);
36040
+ result[key] = this.getSettingValue(providerType, key);
35799
36041
  }
35800
36042
  return result;
35801
36043
  }
@@ -35803,7 +36045,8 @@ var init_provider_loader = __esm({
35803
36045
  * Save provider setting value (writes to config.json)
35804
36046
  */
35805
36047
  setSetting(type, key, value) {
35806
- const schemaDef = this.getSettingsSchema(type)[key];
36048
+ const providerType = this.resolveAlias(type);
36049
+ const schemaDef = this.getSettingsSchema(providerType)[key];
35807
36050
  if (!schemaDef) return false;
35808
36051
  if (!schemaDef.public) return false;
35809
36052
  if (schemaDef.type === "boolean" && typeof value !== "boolean") return false;
@@ -35814,14 +36057,25 @@ var init_provider_loader = __esm({
35814
36057
  if (schemaDef.max !== void 0 && value > schemaDef.max) return false;
35815
36058
  }
35816
36059
  if (schemaDef.type === "select" && schemaDef.options && !schemaDef.options.includes(value)) return false;
36060
+ if (key === "enabled") {
36061
+ return this.setMachineProviderEnabled(providerType, value);
36062
+ }
36063
+ if (key === "executablePath") {
36064
+ return this.setMachineProviderConfig(providerType, { executable: value });
36065
+ }
36066
+ if (key === "executableArgs") {
36067
+ return this.setMachineProviderConfig(providerType, {
36068
+ args: value.trim() ? this.parseArgsSetting(value) : void 0
36069
+ });
36070
+ }
35817
36071
  const config2 = this.readConfig();
35818
36072
  if (!config2) return false;
35819
36073
  try {
35820
36074
  if (!config2.providerSettings) config2.providerSettings = {};
35821
- if (!config2.providerSettings[type]) config2.providerSettings[type] = {};
35822
- config2.providerSettings[type][key] = value;
36075
+ if (!config2.providerSettings[providerType]) config2.providerSettings[providerType] = {};
36076
+ config2.providerSettings[providerType][key] = value;
35823
36077
  this.writeConfig(config2);
35824
- this.log(`Setting updated: ${type}.${key} = ${JSON.stringify(value)}`);
36078
+ this.log(`Setting updated: ${providerType}.${key} = ${JSON.stringify(value)}`);
35825
36079
  return true;
35826
36080
  } catch (e) {
35827
36081
  this.log(`Failed to save setting: ${e.message}`);
@@ -35882,6 +36136,15 @@ var init_provider_loader = __esm({
35882
36136
  }
35883
36137
  getSyntheticSettings(type, provider) {
35884
36138
  const result = {};
36139
+ if (provider.category === "cli" || provider.category === "acp") {
36140
+ result.enabled = {
36141
+ type: "boolean",
36142
+ default: false,
36143
+ public: true,
36144
+ label: "Enabled on this machine",
36145
+ description: "Opt in before ADHDev detects, launches, or verifies this provider on this machine."
36146
+ };
36147
+ }
35885
36148
  if (!provider.settings?.autoApprove) {
35886
36149
  result.autoApprove = {
35887
36150
  type: "boolean",
@@ -35900,6 +36163,15 @@ var init_provider_loader = __esm({
35900
36163
  description: "Optional absolute path for this provider binary. Leave blank to use the default PATH lookup."
35901
36164
  };
35902
36165
  }
36166
+ if ((provider.category === "cli" || provider.category === "acp") && provider.spawn?.command && !provider.settings?.executableArgs) {
36167
+ result.executableArgs = {
36168
+ type: "string",
36169
+ default: "",
36170
+ public: true,
36171
+ label: "Executable arguments",
36172
+ description: "Optional replacement for provider default command arguments. Leave blank to use the provider default."
36173
+ };
36174
+ }
35903
36175
  if (provider.category === "ide") {
35904
36176
  if (provider.cli && !provider.settings?.cliPathOverride) {
35905
36177
  result.cliPathOverride = {
@@ -36219,32 +36491,32 @@ async function killIdeProcess(ideId) {
36219
36491
  try {
36220
36492
  if (plat === "darwin" && appName) {
36221
36493
  try {
36222
- (0, import_child_process6.execSync)(`osascript -e 'tell application "${escapeForAppleScript(appName)}" to quit' 2>/dev/null`, {
36494
+ (0, import_child_process7.execSync)(`osascript -e 'tell application "${escapeForAppleScript(appName)}" to quit' 2>/dev/null`, {
36223
36495
  timeout: 5e3
36224
36496
  });
36225
36497
  } catch {
36226
36498
  try {
36227
- (0, import_child_process6.execSync)(`pkill -x "${appName}" 2>/dev/null`, { timeout: 5e3 });
36499
+ (0, import_child_process7.execSync)(`pkill -x "${appName}" 2>/dev/null`, { timeout: 5e3 });
36228
36500
  } catch {
36229
36501
  }
36230
36502
  }
36231
36503
  } else if (plat === "win32" && winProcesses) {
36232
36504
  for (const proc of winProcesses) {
36233
36505
  try {
36234
- (0, import_child_process6.execSync)(`taskkill /IM "${proc}" /F 2>nul`, { timeout: 5e3 });
36506
+ (0, import_child_process7.execSync)(`taskkill /IM "${proc}" /F 2>nul`, { timeout: 5e3 });
36235
36507
  } catch {
36236
36508
  }
36237
36509
  }
36238
36510
  try {
36239
36511
  const exeName = winProcesses[0].replace(".exe", "");
36240
- (0, import_child_process6.execSync)(`powershell -Command "Get-Process -Name '${exeName}' -ErrorAction SilentlyContinue | Stop-Process -Force"`, {
36512
+ (0, import_child_process7.execSync)(`powershell -Command "Get-Process -Name '${exeName}' -ErrorAction SilentlyContinue | Stop-Process -Force"`, {
36241
36513
  timeout: 1e4
36242
36514
  });
36243
36515
  } catch {
36244
36516
  }
36245
36517
  } else {
36246
36518
  try {
36247
- (0, import_child_process6.execSync)(`pkill -f "${ideId}" 2>/dev/null`);
36519
+ (0, import_child_process7.execSync)(`pkill -f "${ideId}" 2>/dev/null`);
36248
36520
  } catch {
36249
36521
  }
36250
36522
  }
@@ -36254,13 +36526,13 @@ async function killIdeProcess(ideId) {
36254
36526
  }
36255
36527
  if (plat === "darwin" && appName) {
36256
36528
  try {
36257
- (0, import_child_process6.execSync)(`pkill -9 -x "${appName}" 2>/dev/null`, { timeout: 5e3 });
36529
+ (0, import_child_process7.execSync)(`pkill -9 -x "${appName}" 2>/dev/null`, { timeout: 5e3 });
36258
36530
  } catch {
36259
36531
  }
36260
36532
  } else if (plat === "win32" && winProcesses) {
36261
36533
  for (const proc of winProcesses) {
36262
36534
  try {
36263
- (0, import_child_process6.execSync)(`taskkill /IM "${proc}" /F 2>nul`);
36535
+ (0, import_child_process7.execSync)(`taskkill /IM "${proc}" /F 2>nul`);
36264
36536
  } catch {
36265
36537
  }
36266
36538
  }
@@ -36278,13 +36550,13 @@ function isIdeRunning(ideId) {
36278
36550
  const appName = getMacAppIdentifiers()[ideId];
36279
36551
  if (!appName) return false;
36280
36552
  try {
36281
- const result = (0, import_child_process6.execSync)(`pgrep -x "${appName}" 2>/dev/null`, {
36553
+ const result = (0, import_child_process7.execSync)(`pgrep -x "${appName}" 2>/dev/null`, {
36282
36554
  encoding: "utf-8",
36283
36555
  timeout: 3e3
36284
36556
  });
36285
36557
  return result.trim().length > 0;
36286
36558
  } catch {
36287
- const result = (0, import_child_process6.execSync)(
36559
+ const result = (0, import_child_process7.execSync)(
36288
36560
  `osascript -e 'tell application "System Events" to count (every process whose name is "${escapeForAppleScript(appName)}")'`,
36289
36561
  {
36290
36562
  encoding: "utf-8",
@@ -36299,14 +36571,14 @@ function isIdeRunning(ideId) {
36299
36571
  if (!winProcesses) return false;
36300
36572
  for (const proc of winProcesses) {
36301
36573
  try {
36302
- const result = (0, import_child_process6.execSync)(`tasklist /FI "IMAGENAME eq ${proc}" /NH 2>nul`, { encoding: "utf-8" });
36574
+ const result = (0, import_child_process7.execSync)(`tasklist /FI "IMAGENAME eq ${proc}" /NH 2>nul`, { encoding: "utf-8" });
36303
36575
  if (result.includes(proc)) return true;
36304
36576
  } catch {
36305
36577
  }
36306
36578
  }
36307
36579
  try {
36308
36580
  const exeName = winProcesses[0].replace(".exe", "");
36309
- const result = (0, import_child_process6.execSync)(
36581
+ const result = (0, import_child_process7.execSync)(
36310
36582
  `powershell -Command "(Get-Process -Name '${exeName}' -ErrorAction SilentlyContinue).Count"`,
36311
36583
  { encoding: "utf-8", timeout: 5e3 }
36312
36584
  );
@@ -36315,7 +36587,7 @@ function isIdeRunning(ideId) {
36315
36587
  }
36316
36588
  return false;
36317
36589
  } else {
36318
- const result = (0, import_child_process6.execSync)(`pgrep -f "${ideId}" 2>/dev/null`, { encoding: "utf-8" });
36590
+ const result = (0, import_child_process7.execSync)(`pgrep -f "${ideId}" 2>/dev/null`, { encoding: "utf-8" });
36319
36591
  return result.trim().length > 0;
36320
36592
  }
36321
36593
  } catch {
@@ -36328,7 +36600,7 @@ function detectCurrentWorkspace(ideId) {
36328
36600
  try {
36329
36601
  const appName = getMacAppIdentifiers()[ideId];
36330
36602
  if (!appName) return void 0;
36331
- const result = (0, import_child_process6.execSync)(
36603
+ const result = (0, import_child_process7.execSync)(
36332
36604
  `lsof -c "${appName}" 2>/dev/null | grep cwd | head -1 | awk '{print $NF}'`,
36333
36605
  { encoding: "utf-8", timeout: 3e3 }
36334
36606
  );
@@ -36480,10 +36752,10 @@ async function launchMacOS(ide, port, workspace, newWindow) {
36480
36752
  const canUseAppLauncher = !!appName;
36481
36753
  const useAppLauncher = preferredMethod === "app" ? canUseAppLauncher : preferredMethod === "cli" ? false : !canUseCli && canUseAppLauncher;
36482
36754
  if (!useAppLauncher && ide.cliCommand) {
36483
- (0, import_child_process6.spawn)(ide.cliCommand, args, { detached: true, stdio: "ignore" }).unref();
36755
+ (0, import_child_process7.spawn)(ide.cliCommand, args, { detached: true, stdio: "ignore" }).unref();
36484
36756
  } else if (appName) {
36485
36757
  const openArgs = ["-a", appName, "--args", ...args];
36486
- (0, import_child_process6.spawn)("open", openArgs, { detached: true, stdio: "ignore" }).unref();
36758
+ (0, import_child_process7.spawn)("open", openArgs, { detached: true, stdio: "ignore" }).unref();
36487
36759
  } else {
36488
36760
  throw new Error(`No app identifier or CLI for ${ide.displayName}`);
36489
36761
  }
@@ -36509,16 +36781,16 @@ async function launchLinux(ide, port, workspace, newWindow) {
36509
36781
  const args = ["--remote-debugging-port=" + port];
36510
36782
  if (newWindow) args.push("--new-window");
36511
36783
  if (workspace) args.push(workspace);
36512
- (0, import_child_process6.spawn)(cli, args, { detached: true, stdio: "ignore" }).unref();
36784
+ (0, import_child_process7.spawn)(cli, args, { detached: true, stdio: "ignore" }).unref();
36513
36785
  }
36514
36786
  function getAvailableIdeIds() {
36515
36787
  return getProviderLoader().getAvailableIdeTypes();
36516
36788
  }
36517
- var import_child_process6, net2, os16, path14, _providerLoader;
36789
+ var import_child_process7, net2, os16, path14, _providerLoader;
36518
36790
  var init_launch = __esm({
36519
36791
  "../../oss/packages/daemon-core/src/launch.ts"() {
36520
36792
  "use strict";
36521
- import_child_process6 = require("child_process");
36793
+ import_child_process7 = require("child_process");
36522
36794
  net2 = __toESM(require("net"));
36523
36795
  os16 = __toESM(require("os"));
36524
36796
  path14 = __toESM(require("path"));
@@ -36719,7 +36991,11 @@ function buildAvailableProviders(providerLoader) {
36719
36991
  icon: provider.icon || "\u{1F4BB}",
36720
36992
  category: provider.category,
36721
36993
  ...provider.installed !== void 0 ? { installed: provider.installed } : {},
36722
- ...provider.detectedPath !== void 0 ? { detectedPath: provider.detectedPath } : {}
36994
+ ...provider.detectedPath !== void 0 ? { detectedPath: provider.detectedPath } : {},
36995
+ ...provider.enabled !== void 0 ? { enabled: provider.enabled } : {},
36996
+ ...provider.machineStatus !== void 0 ? { machineStatus: provider.machineStatus } : {},
36997
+ ...provider.lastDetection !== void 0 ? { lastDetection: provider.lastDetection } : {},
36998
+ ...provider.lastVerification !== void 0 ? { lastVerification: provider.lastVerification } : {}
36723
36999
  }));
36724
37000
  }
36725
37001
  function buildMachineInfo(profile = "full") {
@@ -37090,7 +37366,7 @@ function getNpmExecOptions() {
37090
37366
  function killPid(pid) {
37091
37367
  try {
37092
37368
  if (process.platform === "win32") {
37093
- (0, import_child_process7.execFileSync)("taskkill", ["/PID", String(pid), "/T", "/F"], { stdio: "ignore" });
37369
+ (0, import_child_process8.execFileSync)("taskkill", ["/PID", String(pid), "/T", "/F"], { stdio: "ignore" });
37094
37370
  } else {
37095
37371
  process.kill(pid, "SIGTERM");
37096
37372
  }
@@ -37128,7 +37404,7 @@ function stopSessionHostProcesses(appName) {
37128
37404
  }
37129
37405
  if (process.platform !== "win32") {
37130
37406
  try {
37131
- const raw = (0, import_child_process7.execFileSync)("pgrep", ["-f", "session-host-daemon"], { encoding: "utf8" }).trim();
37407
+ const raw = (0, import_child_process8.execFileSync)("pgrep", ["-f", "session-host-daemon"], { encoding: "utf8" }).trim();
37132
37408
  for (const line of raw.split("\n")) {
37133
37409
  const pid = Number.parseInt(line.trim(), 10);
37134
37410
  if (Number.isFinite(pid)) {
@@ -37149,9 +37425,9 @@ function removeDaemonPidFile() {
37149
37425
  function cleanupStaleGlobalInstallDirs(pkgName, surface) {
37150
37426
  const npmExecOpts = getNpmExecOptions();
37151
37427
  const prefixArgs = surface.installPrefix ? ["--prefix", surface.installPrefix] : [];
37152
- const npmRoot = (0, import_child_process7.execFileSync)(surface.npmExecutable, ["root", "-g", ...prefixArgs], { encoding: "utf8", ...npmExecOpts }).trim();
37428
+ const npmRoot = (0, import_child_process8.execFileSync)(surface.npmExecutable, ["root", "-g", ...prefixArgs], { encoding: "utf8", ...npmExecOpts }).trim();
37153
37429
  if (!npmRoot) return;
37154
- const npmPrefix = surface.installPrefix || (0, import_child_process7.execFileSync)(surface.npmExecutable, ["prefix", "-g", ...prefixArgs], { encoding: "utf8", ...npmExecOpts }).trim();
37430
+ const npmPrefix = surface.installPrefix || (0, import_child_process8.execFileSync)(surface.npmExecutable, ["prefix", "-g", ...prefixArgs], { encoding: "utf8", ...npmExecOpts }).trim();
37155
37431
  const binDir = process.platform === "win32" ? npmPrefix : path16.join(npmPrefix, "bin");
37156
37432
  const packageBaseName = pkgName.startsWith("@") ? pkgName.split("/")[1] : pkgName;
37157
37433
  const binNames = /* @__PURE__ */ new Set([packageBaseName]);
@@ -37184,7 +37460,7 @@ function cleanupStaleGlobalInstallDirs(pkgName, surface) {
37184
37460
  }
37185
37461
  function spawnDetachedDaemonUpgradeHelper(payload) {
37186
37462
  const env3 = { ...process.env, [UPGRADE_HELPER_ENV]: JSON.stringify(payload) };
37187
- const child = (0, import_child_process8.spawn)(process.execPath, process.argv.slice(1), {
37463
+ const child = (0, import_child_process9.spawn)(process.execPath, process.argv.slice(1), {
37188
37464
  detached: true,
37189
37465
  stdio: "ignore",
37190
37466
  windowsHide: true,
@@ -37214,7 +37490,7 @@ async function runDaemonUpgradeHelper(payload) {
37214
37490
  cleanupStaleGlobalInstallDirs(payload.packageName, installCommand.surface);
37215
37491
  const spec = `${payload.packageName}@${payload.targetVersion || "latest"}`;
37216
37492
  appendUpgradeLog(`Installing ${spec}`);
37217
- const installOutput = (0, import_child_process7.execFileSync)(
37493
+ const installOutput = (0, import_child_process8.execFileSync)(
37218
37494
  installCommand.command,
37219
37495
  installCommand.args,
37220
37496
  {
@@ -37236,7 +37512,7 @@ async function runDaemonUpgradeHelper(payload) {
37236
37512
  const env3 = { ...process.env };
37237
37513
  delete env3[UPGRADE_HELPER_ENV];
37238
37514
  appendUpgradeLog(`Restarting daemon with args: ${restartArgv.join(" ")}`);
37239
- const child = (0, import_child_process8.spawn)(process.execPath, restartArgv, {
37515
+ const child = (0, import_child_process9.spawn)(process.execPath, restartArgv, {
37240
37516
  detached: true,
37241
37517
  stdio: "ignore",
37242
37518
  windowsHide: true,
@@ -37261,12 +37537,12 @@ async function maybeRunDaemonUpgradeHelperFromEnv() {
37261
37537
  process.exit(1);
37262
37538
  }
37263
37539
  }
37264
- var import_child_process7, import_child_process8, fs8, os19, path16, UPGRADE_HELPER_ENV;
37540
+ var import_child_process8, import_child_process9, fs8, os19, path16, UPGRADE_HELPER_ENV;
37265
37541
  var init_upgrade_helper = __esm({
37266
37542
  "../../oss/packages/daemon-core/src/commands/upgrade-helper.ts"() {
37267
37543
  "use strict";
37268
- import_child_process7 = require("child_process");
37269
37544
  import_child_process8 = require("child_process");
37545
+ import_child_process9 = require("child_process");
37270
37546
  fs8 = __toESM(require("fs"));
37271
37547
  os19 = __toESM(require("os"));
37272
37548
  path16 = __toESM(require("path"));
@@ -37371,6 +37647,7 @@ var init_router = __esm({
37371
37647
  init_saved_sessions();
37372
37648
  init_chat_history();
37373
37649
  init_ide_detector();
37650
+ init_cli_detector();
37374
37651
  init_logger();
37375
37652
  init_command_log();
37376
37653
  init_logger();
@@ -37807,6 +38084,33 @@ var init_router = __esm({
37807
38084
  }
37808
38085
  return { ...result };
37809
38086
  }
38087
+ // ─── Detect providers ───
38088
+ case "detect_provider": {
38089
+ const providerType = typeof args?.providerType === "string" ? args.providerType.trim() : "";
38090
+ if (!providerType) return { success: false, error: "providerType is required" };
38091
+ const normalizedType = this.deps.providerLoader.resolveAlias(providerType);
38092
+ const provider = this.deps.providerLoader.getByAlias(providerType);
38093
+ if (!provider) return { success: false, error: `Provider not found: ${providerType}` };
38094
+ if (provider.category !== "cli" && provider.category !== "acp") {
38095
+ return { success: false, error: `Provider detection is only supported for CLI/ACP providers: ${providerType}` };
38096
+ }
38097
+ if (!this.deps.providerLoader.isMachineProviderEnabled(normalizedType)) {
38098
+ return { success: false, error: `Provider is disabled on this machine: ${providerType}` };
38099
+ }
38100
+ const detected = await detectCLI(normalizedType, this.deps.providerLoader, { includeVersion: false });
38101
+ this.deps.providerLoader.setCliDetectionResults([{
38102
+ id: normalizedType,
38103
+ installed: !!detected,
38104
+ path: detected?.path
38105
+ }], false);
38106
+ this.deps.onStatusChange?.();
38107
+ return {
38108
+ success: true,
38109
+ providerType: normalizedType,
38110
+ detected: !!detected,
38111
+ path: detected?.path || null
38112
+ };
38113
+ }
37810
38114
  // ─── Detect IDEs ───
37811
38115
  case "detect_ides": {
37812
38116
  const results = await detectIDEs(this.deps.providerLoader);
@@ -37852,13 +38156,16 @@ var init_router = __esm({
37852
38156
  this.deps.cdpManagers
37853
38157
  );
37854
38158
  const targetSession = sessionEntries.find((entry) => entry.id === sessionId);
37855
- const completionMarker = targetSession ? getSessionCompletionMarker(targetSession) : "";
38159
+ const requestedCompletionMarker = typeof args?.completionMarker === "string" ? args.completionMarker.trim() : "";
38160
+ const completionMarker = requestedCompletionMarker || (targetSession ? getSessionCompletionMarker(targetSession) : "");
38161
+ const requestedProviderSessionId = typeof args?.providerSessionId === "string" ? args.providerSessionId.trim() : "";
38162
+ const providerSessionId = requestedProviderSessionId || targetSession?.providerSessionId;
37856
38163
  const next = markSessionSeen(
37857
38164
  currentState,
37858
38165
  sessionId,
37859
38166
  typeof args?.seenAt === "number" ? args.seenAt : Date.now(),
37860
38167
  completionMarker,
37861
- targetSession?.providerSessionId
38168
+ providerSessionId
37862
38169
  );
37863
38170
  if (READ_DEBUG_ENABLED2) {
37864
38171
  LOG.info("RecentRead", `mark_session_seen sessionId=${sessionId} seenAt=${String(args?.seenAt || "")} prevSeenAt=${String(prevSeenAt)} nextSeenAt=${String(next.sessionReads?.[sessionId] || 0)} marker=${completionMarker || "-"}`);
@@ -39651,7 +39958,7 @@ var init_provider_instance_manager = __esm({
39651
39958
  // ../../oss/packages/daemon-core/src/providers/version-archive.ts
39652
39959
  function runCommand(cmd, timeout = 1e4) {
39653
39960
  try {
39654
- return (0, import_child_process9.execSync)(cmd, {
39961
+ return (0, import_child_process10.execSync)(cmd, {
39655
39962
  encoding: "utf-8",
39656
39963
  timeout,
39657
39964
  stdio: ["pipe", "pipe", "pipe"]
@@ -39773,14 +40080,14 @@ async function detectAllVersions(loader, archive) {
39773
40080
  }
39774
40081
  return results;
39775
40082
  }
39776
- var fs10, path17, os20, import_child_process9, import_os3, ARCHIVE_PATH, MAX_ENTRIES_PER_PROVIDER, VersionArchive;
40083
+ var fs10, path17, os20, import_child_process10, import_os3, ARCHIVE_PATH, MAX_ENTRIES_PER_PROVIDER, VersionArchive;
39777
40084
  var init_version_archive = __esm({
39778
40085
  "../../oss/packages/daemon-core/src/providers/version-archive.ts"() {
39779
40086
  "use strict";
39780
40087
  fs10 = __toESM(require("fs"));
39781
40088
  path17 = __toESM(require("path"));
39782
40089
  os20 = __toESM(require("os"));
39783
- import_child_process9 = require("child_process");
40090
+ import_child_process10 = require("child_process");
39784
40091
  import_os3 = require("os");
39785
40092
  ARCHIVE_PATH = path17.join(os20.homedir(), ".adhdev", "version-history.json");
39786
40093
  MAX_ENTRIES_PER_PROVIDER = 20;
@@ -45560,7 +45867,7 @@ var init_startup_restore_policy = __esm({
45560
45867
  function isExtensionInstalled(ide, marketplaceId) {
45561
45868
  if (!ide.cliCommand) return false;
45562
45869
  try {
45563
- const result = (0, import_child_process10.execSync)(`"${ide.cliCommand}" --list-extensions`, {
45870
+ const result = (0, import_child_process11.execSync)(`"${ide.cliCommand}" --list-extensions`, {
45564
45871
  encoding: "utf-8",
45565
45872
  timeout: 15e3,
45566
45873
  stdio: ["pipe", "pipe", "pipe"]
@@ -45601,7 +45908,7 @@ async function installExtension(ide, extension) {
45601
45908
  fs24.writeFileSync(vsixPath, buffer);
45602
45909
  return new Promise((resolve16) => {
45603
45910
  const cmd = `"${ide.cliCommand}" --install-extension "${vsixPath}" --force`;
45604
- (0, import_child_process10.exec)(cmd, { timeout: 6e4 }, (error48, _stdout, stderr) => {
45911
+ (0, import_child_process11.exec)(cmd, { timeout: 6e4 }, (error48, _stdout, stderr) => {
45605
45912
  resolve16({
45606
45913
  extensionId: extension.id,
45607
45914
  marketplaceId: extension.marketplaceId,
@@ -45617,7 +45924,7 @@ async function installExtension(ide, extension) {
45617
45924
  }
45618
45925
  return new Promise((resolve16) => {
45619
45926
  const cmd = `"${ide.cliCommand}" --install-extension ${extension.marketplaceId} --force`;
45620
- (0, import_child_process10.exec)(cmd, { timeout: 6e4 }, (error48, stdout, stderr) => {
45927
+ (0, import_child_process11.exec)(cmd, { timeout: 6e4 }, (error48, stdout, stderr) => {
45621
45928
  if (error48) {
45622
45929
  resolve16({
45623
45930
  extensionId: extension.id,
@@ -45654,17 +45961,17 @@ function launchIDE(ide, workspacePath) {
45654
45961
  if (!ide.cliCommand) return false;
45655
45962
  try {
45656
45963
  const args = workspacePath ? `"${workspacePath}"` : "";
45657
- (0, import_child_process10.exec)(`"${ide.cliCommand}" ${args}`, { timeout: 1e4 });
45964
+ (0, import_child_process11.exec)(`"${ide.cliCommand}" ${args}`, { timeout: 1e4 });
45658
45965
  return true;
45659
45966
  } catch {
45660
45967
  return false;
45661
45968
  }
45662
45969
  }
45663
- var import_child_process10, EXTENSION_CATALOG;
45970
+ var import_child_process11, EXTENSION_CATALOG;
45664
45971
  var init_installer = __esm({
45665
45972
  "../../oss/packages/daemon-core/src/installer.ts"() {
45666
45973
  "use strict";
45667
- import_child_process10 = require("child_process");
45974
+ import_child_process11 = require("child_process");
45668
45975
  EXTENSION_CATALOG = [
45669
45976
  // AI Agent extensions
45670
45977
  {
@@ -45867,10 +46174,11 @@ async function initDaemonComponents(config2) {
45867
46174
  if (!providerType || targetCategory === "cli" || targetCategory === "acp") {
45868
46175
  if (providerType && targetProvider) {
45869
46176
  const detected = await detectCLI(targetProvider.type, providerLoader, { includeVersion: false });
45870
- providerLoader.setProviderAvailability(targetProvider.type, {
46177
+ providerLoader.setCliDetectionResults([{
46178
+ id: targetProvider.type,
45871
46179
  installed: !!detected,
45872
- detectedPath: detected?.path || null
45873
- });
46180
+ path: detected?.path
46181
+ }], false);
45874
46182
  } else {
45875
46183
  providerLoader.setCliDetectionResults(await detectCLIs(providerLoader, { includeVersion: false }), true);
45876
46184
  }
@@ -54689,7 +54997,7 @@ function getSessionHostPidFile() {
54689
54997
  function killPid2(pid) {
54690
54998
  try {
54691
54999
  if (process.platform === "win32") {
54692
- (0, import_child_process11.execFileSync)("taskkill", ["/PID", String(pid), "/T", "/F"], { stdio: "ignore", windowsHide: true });
55000
+ (0, import_child_process12.execFileSync)("taskkill", ["/PID", String(pid), "/T", "/F"], { stdio: "ignore", windowsHide: true });
54693
55001
  } else {
54694
55002
  process.kill(pid, "SIGTERM");
54695
55003
  }
@@ -54701,7 +55009,7 @@ function killPid2(pid) {
54701
55009
  function getWindowsProcessCommandLine(pid) {
54702
55010
  const pidFilter = `ProcessId=${pid}`;
54703
55011
  try {
54704
- const psOut = (0, import_child_process11.execFileSync)("powershell.exe", [
55012
+ const psOut = (0, import_child_process12.execFileSync)("powershell.exe", [
54705
55013
  "-NoProfile",
54706
55014
  "-NonInteractive",
54707
55015
  "-ExecutionPolicy",
@@ -54714,7 +55022,7 @@ function getWindowsProcessCommandLine(pid) {
54714
55022
  } catch {
54715
55023
  }
54716
55024
  try {
54717
- const wmicOut = (0, import_child_process11.execFileSync)("wmic", [
55025
+ const wmicOut = (0, import_child_process12.execFileSync)("wmic", [
54718
55026
  "process",
54719
55027
  "where",
54720
55028
  pidFilter,
@@ -54750,7 +55058,7 @@ function stopSessionHost() {
54750
55058
  let stopped = stopManagedSessionHostProcess();
54751
55059
  if (process.platform === "win32") {
54752
55060
  try {
54753
- const raw = (0, import_child_process11.execFileSync)("tasklist", ["/FO", "CSV", "/NH", "/FI", "IMAGENAME eq node.exe"], {
55061
+ const raw = (0, import_child_process12.execFileSync)("tasklist", ["/FO", "CSV", "/NH", "/FI", "IMAGENAME eq node.exe"], {
54754
55062
  encoding: "utf8",
54755
55063
  timeout: 5e3,
54756
55064
  stdio: ["ignore", "pipe", "ignore"],
@@ -54770,7 +55078,7 @@ function stopSessionHost() {
54770
55078
  }
54771
55079
  } else {
54772
55080
  try {
54773
- const raw = (0, import_child_process11.execFileSync)("pgrep", ["-f", "session-host-daemon"], { encoding: "utf8" }).trim();
55081
+ const raw = (0, import_child_process12.execFileSync)("pgrep", ["-f", "session-host-daemon"], { encoding: "utf8" }).trim();
54774
55082
  for (const line of raw.split("\n")) {
54775
55083
  const pid = Number.parseInt(line.trim(), 10);
54776
55084
  if (Number.isFinite(pid) && pid !== process.pid && pid !== process.ppid) {
@@ -54804,7 +55112,7 @@ async function ensureSessionHostReady2() {
54804
55112
  const logDir = path25.join(os24.homedir(), ".adhdev", "logs");
54805
55113
  fs17.mkdirSync(logDir, { recursive: true });
54806
55114
  const logFd = fs17.openSync(path25.join(logDir, "session-host.log"), "a");
54807
- const child = (0, import_child_process11.spawn)(process.execPath, [entry], {
55115
+ const child = (0, import_child_process12.spawn)(process.execPath, [entry], {
54808
55116
  detached: true,
54809
55117
  stdio: ["ignore", logFd, logFd],
54810
55118
  windowsHide: true,
@@ -54838,11 +55146,11 @@ async function ensureSessionHostReady2() {
54838
55146
  async function listHostedCliRuntimes2(endpoint) {
54839
55147
  return listHostedCliRuntimes(endpoint);
54840
55148
  }
54841
- var import_child_process11, fs17, os24, path25, SESSION_HOST_APP_NAME, SESSION_HOST_START_TIMEOUT_MS;
55149
+ var import_child_process12, fs17, os24, path25, SESSION_HOST_APP_NAME, SESSION_HOST_START_TIMEOUT_MS;
54842
55150
  var init_session_host = __esm({
54843
55151
  "src/session-host.ts"() {
54844
55152
  "use strict";
54845
- import_child_process11 = require("child_process");
55153
+ import_child_process12 = require("child_process");
54846
55154
  fs17 = __toESM(require("fs"));
54847
55155
  os24 = __toESM(require("os"));
54848
55156
  path25 = __toESM(require("path"));
@@ -55537,18 +55845,18 @@ function resolvePackageVersion(options) {
55537
55845
  ];
55538
55846
  for (const p of possiblePaths) {
55539
55847
  try {
55540
- const data = JSON.parse((0, import_fs5.readFileSync)(p, "utf-8"));
55848
+ const data = JSON.parse((0, import_fs6.readFileSync)(p, "utf-8"));
55541
55849
  if (data.version) return data.version;
55542
55850
  } catch {
55543
55851
  }
55544
55852
  }
55545
55853
  return injectedVersion;
55546
55854
  }
55547
- var import_fs5, import_path3;
55855
+ var import_fs6, import_path3;
55548
55856
  var init_version = __esm({
55549
55857
  "src/version.ts"() {
55550
55858
  "use strict";
55551
- import_fs5 = require("fs");
55859
+ import_fs6 = require("fs");
55552
55860
  import_path3 = require("path");
55553
55861
  }
55554
55862
  });
@@ -55587,7 +55895,7 @@ function removeDaemonPid(ref = {}) {
55587
55895
  function isDaemonRunning(ref = {}) {
55588
55896
  const port = resolveDaemonPort(ref);
55589
55897
  try {
55590
- const { execFileSync: execFileSync4 } = require("child_process");
55898
+ const { execFileSync: execFileSync5 } = require("child_process");
55591
55899
  const probe = `
55592
55900
  const http = require('http');
55593
55901
  const req = http.get('http://127.0.0.1:${port}/health', { timeout: 1500 }, (res) => {
@@ -55597,7 +55905,7 @@ function isDaemonRunning(ref = {}) {
55597
55905
  req.on('error', () => process.stdout.write('0'));
55598
55906
  req.on('timeout', () => { req.destroy(); process.stdout.write('0'); });
55599
55907
  `;
55600
- const result = execFileSync4(process.execPath, ["-e", probe], {
55908
+ const result = execFileSync5(process.execPath, ["-e", probe], {
55601
55909
  encoding: "utf-8",
55602
55910
  timeout: 3e3,
55603
55911
  stdio: ["ignore", "pipe", "ignore"]
@@ -55623,9 +55931,9 @@ function isDaemonRunning(ref = {}) {
55623
55931
  function isAdhdevProcess(pid) {
55624
55932
  try {
55625
55933
  if (process.platform === "win32") {
55626
- const { execFileSync: execFileSync4 } = require("child_process");
55934
+ const { execFileSync: execFileSync5 } = require("child_process");
55627
55935
  try {
55628
- const psOut = execFileSync4("powershell.exe", [
55936
+ const psOut = execFileSync5("powershell.exe", [
55629
55937
  "-NoProfile",
55630
55938
  "-NonInteractive",
55631
55939
  "-ExecutionPolicy",
@@ -55638,8 +55946,8 @@ function isAdhdevProcess(pid) {
55638
55946
  return true;
55639
55947
  }
55640
55948
  } else {
55641
- const { execFileSync: execFileSync4 } = require("child_process");
55642
- const cmdline = execFileSync4("ps", ["-o", "command=", "-p", String(pid)], {
55949
+ const { execFileSync: execFileSync5 } = require("child_process");
55950
+ const cmdline = execFileSync5("ps", ["-o", "command=", "-p", String(pid)], {
55643
55951
  encoding: "utf-8",
55644
55952
  timeout: 2e3,
55645
55953
  stdio: ["ignore", "pipe", "ignore"]
@@ -55653,7 +55961,7 @@ function isAdhdevProcess(pid) {
55653
55961
  function getDaemonHealthPid(ref = {}) {
55654
55962
  const port = resolveDaemonPort(ref);
55655
55963
  try {
55656
- const { execFileSync: execFileSync4 } = require("child_process");
55964
+ const { execFileSync: execFileSync5 } = require("child_process");
55657
55965
  const probe = `
55658
55966
  const http = require('http');
55659
55967
  const req = http.get('http://127.0.0.1:${port}/health', { timeout: 1500 }, (res) => {
@@ -55671,7 +55979,7 @@ function getDaemonHealthPid(ref = {}) {
55671
55979
  req.on('error', () => {});
55672
55980
  req.on('timeout', () => { req.destroy(); });
55673
55981
  `;
55674
- const result = execFileSync4(process.execPath, ["-e", probe], {
55982
+ const result = execFileSync5(process.execPath, ["-e", probe], {
55675
55983
  encoding: "utf-8",
55676
55984
  timeout: 3e3,
55677
55985
  stdio: ["ignore", "pipe", "ignore"]
@@ -55738,7 +56046,7 @@ var init_adhdev_daemon = __esm({
55738
56046
  init_version();
55739
56047
  init_src();
55740
56048
  init_runtime_defaults();
55741
- pkgVersion = resolvePackageVersion({ injectedVersion: "0.9.28" });
56049
+ pkgVersion = resolvePackageVersion({ injectedVersion: "0.9.30" });
55742
56050
  AdhdevDaemon = class _AdhdevDaemon {
55743
56051
  localHttpServer = null;
55744
56052
  localWss = null;
@@ -56537,12 +56845,13 @@ ${err?.stack || ""}`);
56537
56845
  return { success: false, error: "CLI session runtime unavailable", code: "CLI_RUNTIME_UNAVAILABLE", interactionId };
56538
56846
  }
56539
56847
  if (!this.sessionHostEndpoint) return { success: false, error: "Session host unavailable", interactionId };
56848
+ const sinceSeq = typeof normalizedData.sinceSeq === "number" ? normalizedData.sinceSeq : void 0;
56540
56849
  const client = new SessionHostClient({ endpoint: this.sessionHostEndpoint });
56541
56850
  try {
56542
56851
  await client.connect();
56543
56852
  const snapshot = await client.request({
56544
56853
  type: "get_snapshot",
56545
- payload: { sessionId }
56854
+ payload: { sessionId, sinceSeq }
56546
56855
  });
56547
56856
  if (!snapshot.success || !snapshot.result) {
56548
56857
  return { success: false, error: snapshot.error || "Runtime snapshot unavailable", interactionId };
@@ -71473,7 +71782,7 @@ var require_buffer_list = __commonJS({
71473
71782
  }
71474
71783
  }, {
71475
71784
  key: "join",
71476
- value: function join29(s) {
71785
+ value: function join30(s) {
71477
71786
  if (this.length === 0) return "";
71478
71787
  var p = this.head;
71479
71788
  var ret = "" + p.data;
@@ -85532,13 +85841,13 @@ function splitStringBySpace(str) {
85532
85841
  }
85533
85842
  return pieces;
85534
85843
  }
85535
- var import_chardet, import_child_process12, import_fs6, import_node_path2, import_node_os4, import_node_crypto, import_iconv_lite, ExternalEditor;
85844
+ var import_chardet, import_child_process13, import_fs7, import_node_path2, import_node_os4, import_node_crypto, import_iconv_lite, ExternalEditor;
85536
85845
  var init_esm2 = __esm({
85537
85846
  "../../node_modules/@inquirer/external-editor/dist/esm/index.js"() {
85538
85847
  "use strict";
85539
85848
  import_chardet = __toESM(require_lib2(), 1);
85540
- import_child_process12 = require("child_process");
85541
- import_fs6 = require("fs");
85849
+ import_child_process13 = require("child_process");
85850
+ import_fs7 = require("fs");
85542
85851
  import_node_path2 = __toESM(require("path"), 1);
85543
85852
  import_node_os4 = __toESM(require("os"), 1);
85544
85853
  import_node_crypto = require("crypto");
@@ -85614,14 +85923,14 @@ var init_esm2 = __esm({
85614
85923
  if (Object.prototype.hasOwnProperty.call(this.fileOptions, "mode")) {
85615
85924
  opt.mode = this.fileOptions.mode;
85616
85925
  }
85617
- (0, import_fs6.writeFileSync)(this.tempFile, this.text, opt);
85926
+ (0, import_fs7.writeFileSync)(this.tempFile, this.text, opt);
85618
85927
  } catch (createFileError) {
85619
85928
  throw new CreateFileError(createFileError);
85620
85929
  }
85621
85930
  }
85622
85931
  readTemporaryFile() {
85623
85932
  try {
85624
- const tempFileBuffer = (0, import_fs6.readFileSync)(this.tempFile);
85933
+ const tempFileBuffer = (0, import_fs7.readFileSync)(this.tempFile);
85625
85934
  if (tempFileBuffer.length === 0) {
85626
85935
  this.text = "";
85627
85936
  } else {
@@ -85637,14 +85946,14 @@ var init_esm2 = __esm({
85637
85946
  }
85638
85947
  removeTemporaryFile() {
85639
85948
  try {
85640
- (0, import_fs6.unlinkSync)(this.tempFile);
85949
+ (0, import_fs7.unlinkSync)(this.tempFile);
85641
85950
  } catch (removeFileError) {
85642
85951
  throw new RemoveFileError(removeFileError);
85643
85952
  }
85644
85953
  }
85645
85954
  launchEditor() {
85646
85955
  try {
85647
- const editorProcess = (0, import_child_process12.spawnSync)(this.editor.bin, this.editor.args.concat([this.tempFile]), { stdio: "inherit" });
85956
+ const editorProcess = (0, import_child_process13.spawnSync)(this.editor.bin, this.editor.args.concat([this.tempFile]), { stdio: "inherit" });
85648
85957
  this.lastExitStatus = editorProcess.status ?? 0;
85649
85958
  } catch (launchError) {
85650
85959
  throw new LaunchEditorError(launchError);
@@ -85652,7 +85961,7 @@ var init_esm2 = __esm({
85652
85961
  }
85653
85962
  launchEditorAsync(callback) {
85654
85963
  try {
85655
- const editorProcess = (0, import_child_process12.spawn)(this.editor.bin, this.editor.args.concat([this.tempFile]), { stdio: "inherit" });
85964
+ const editorProcess = (0, import_child_process13.spawn)(this.editor.bin, this.editor.args.concat([this.tempFile]), { stdio: "inherit" });
85656
85965
  editorProcess.on("exit", (code) => {
85657
85966
  this.lastExitStatus = code;
85658
85967
  setImmediate(callback);
@@ -87930,9 +88239,9 @@ async function runWizard(options = {}) {
87930
88239
  }
87931
88240
  async function checkForUpdate() {
87932
88241
  try {
87933
- const { execFileSync: execFileSync4 } = await import("child_process");
88242
+ const { execFileSync: execFileSync5 } = await import("child_process");
87934
88243
  const currentVersion = resolvePackageVersion();
87935
- const latestVersion = readLatestPublishedCliVersion(execFileSync4);
88244
+ const latestVersion = readLatestPublishedCliVersion(execFileSync5);
87936
88245
  if (!latestVersion) return;
87937
88246
  if (!currentVersion || !latestVersion || currentVersion === latestVersion) return;
87938
88247
  console.log(source_default2.yellow(` Update available: ${currentVersion} \u2192 ${latestVersion}`));
@@ -87949,7 +88258,7 @@ async function checkForUpdate() {
87949
88258
  const spinner = (await Promise.resolve().then(() => (init_ora(), ora_exports))).default("Updating adhdev CLI...").start();
87950
88259
  try {
87951
88260
  const installCommand = buildPinnedGlobalInstallCommand({ packageName: "adhdev", targetVersion: "latest" });
87952
- execFileSync4(installCommand.command, installCommand.args, {
88261
+ execFileSync5(installCommand.command, installCommand.args, {
87953
88262
  encoding: "utf-8",
87954
88263
  timeout: 6e4,
87955
88264
  stdio: ["pipe", "pipe", "pipe"]