adhdev 0.9.28 → 0.9.29

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/cli/index.js CHANGED
@@ -590,6 +590,29 @@ function asOptionalString(value) {
590
590
  function asBoolean(value, fallback2) {
591
591
  return typeof value === "boolean" ? value : fallback2;
592
592
  }
593
+ function normalizeMachineProviders(value) {
594
+ if (!isPlainObject(value)) return {};
595
+ const result = {};
596
+ for (const [providerType, raw] of Object.entries(value)) {
597
+ if (!isPlainObject(raw)) continue;
598
+ const entry = {};
599
+ if (raw.enabled === true) entry.enabled = true;
600
+ if (typeof raw.executable === "string" && raw.executable.trim()) {
601
+ entry.executable = raw.executable.trim();
602
+ }
603
+ if (Array.isArray(raw.args)) {
604
+ entry.args = raw.args.filter((arg) => typeof arg === "string");
605
+ }
606
+ if (isPlainObject(raw.lastDetection)) {
607
+ entry.lastDetection = raw.lastDetection;
608
+ }
609
+ if (isPlainObject(raw.lastVerification)) {
610
+ entry.lastVerification = raw.lastVerification;
611
+ }
612
+ result[providerType] = entry;
613
+ }
614
+ return result;
615
+ }
593
616
  function normalizeConfig(raw) {
594
617
  const parsed = isPlainObject(raw) ? raw : {};
595
618
  return {
@@ -610,6 +633,7 @@ function normalizeConfig(raw) {
610
633
  machineSecret: parsed.machineSecret === null ? null : asOptionalString(parsed.machineSecret),
611
634
  registeredMachineId: asOptionalString(parsed.registeredMachineId),
612
635
  providerSettings: isPlainObject(parsed.providerSettings) ? parsed.providerSettings : {},
636
+ machineProviders: normalizeMachineProviders(parsed.machineProviders),
613
637
  ideSettings: isPlainObject(parsed.ideSettings) ? parsed.ideSettings : {},
614
638
  providerSourceMode: resolveProviderSourceMode(parsed.providerSourceMode, parsed.disableUpstream),
615
639
  providerDir: asOptionalString(parsed.providerDir),
@@ -759,6 +783,7 @@ var init_config = __esm({
759
783
  machineSecret: null,
760
784
  registeredMachineId: void 0,
761
785
  providerSettings: {},
786
+ machineProviders: {},
762
787
  ideSettings: {},
763
788
  providerSourceMode: "normal",
764
789
  terminalSizingMode: "measured"
@@ -33070,6 +33095,27 @@ var init_hosted_runtime_restore = __esm({
33070
33095
  });
33071
33096
 
33072
33097
  // ../../oss/packages/daemon-core/src/commands/cli-manager.ts
33098
+ function isExplicitCommand(command) {
33099
+ const trimmed = command.trim();
33100
+ return path13.isAbsolute(trimmed) || trimmed.includes("/") || trimmed.includes("\\") || trimmed.startsWith("~");
33101
+ }
33102
+ function expandExecutable(command) {
33103
+ const trimmed = command.trim();
33104
+ return trimmed.startsWith("~") ? path13.join(os15.homedir(), trimmed.slice(1)) : trimmed;
33105
+ }
33106
+ function commandExists(command) {
33107
+ const trimmed = command.trim();
33108
+ if (!trimmed) return false;
33109
+ if (isExplicitCommand(trimmed)) {
33110
+ return (0, import_fs5.existsSync)(expandExecutable(trimmed));
33111
+ }
33112
+ try {
33113
+ (0, import_child_process6.execFileSync)(process.platform === "win32" ? "where" : "which", [trimmed], { stdio: "ignore" });
33114
+ return true;
33115
+ } catch {
33116
+ return false;
33117
+ }
33118
+ }
33073
33119
  function colorize(color, text) {
33074
33120
  const fn = chalkApi?.[color];
33075
33121
  return typeof fn === "function" ? fn(text) : text;
@@ -33189,13 +33235,15 @@ function resolveCliSessionBinding(provider, normalizedType, cliArgs, requestedRe
33189
33235
  launchMode: "new"
33190
33236
  };
33191
33237
  }
33192
- var os15, path13, crypto4, chalkModule, chalkApi, DaemonCliManager;
33238
+ var os15, path13, crypto4, import_fs5, import_child_process6, chalkModule, chalkApi, DaemonCliManager;
33193
33239
  var init_cli_manager = __esm({
33194
33240
  "../../oss/packages/daemon-core/src/commands/cli-manager.ts"() {
33195
33241
  "use strict";
33196
33242
  os15 = __toESM(require("os"));
33197
33243
  path13 = __toESM(require("path"));
33198
33244
  crypto4 = __toESM(require("crypto"));
33245
+ import_fs5 = require("fs");
33246
+ import_child_process6 = require("child_process");
33199
33247
  init_source2();
33200
33248
  init_provider_cli_adapter();
33201
33249
  init_cli_detector();
@@ -33357,29 +33405,33 @@ var init_cli_manager = __esm({
33357
33405
  if (!trimmed) throw new Error("working directory required");
33358
33406
  const resolvedDir = trimmed.startsWith("~") ? trimmed.replace(/^~/, os15.homedir()) : path13.resolve(trimmed);
33359
33407
  const normalizedType = this.providerLoader.resolveAlias(cliType);
33360
- const provider = this.providerLoader.getByAlias(cliType);
33408
+ const rawProvider = this.providerLoader.getByAlias(cliType);
33409
+ const provider = rawProvider ? this.providerLoader.resolve(normalizedType) || rawProvider : void 0;
33410
+ if (provider && (provider.category === "cli" || provider.category === "acp") && !this.providerLoader.isMachineProviderEnabled(normalizedType)) {
33411
+ const displayName = provider.displayName || provider.name || normalizedType;
33412
+ throw new Error(
33413
+ `${displayName} is disabled on this machine.
33414
+ Enable and detect this provider from the Machine Providers page before starting a runtime.`
33415
+ );
33416
+ }
33361
33417
  const key = crypto4.randomUUID();
33362
33418
  const sessionRegistry = this.deps.getSessionRegistry?.() || null;
33363
33419
  if (provider && provider.category === "acp") {
33364
33420
  const instanceManager2 = this.deps.getInstanceManager();
33365
33421
  if (!instanceManager2) throw new Error("InstanceManager not available");
33366
- const spawnCmd = provider.spawn?.command;
33367
- if (spawnCmd) {
33368
- try {
33369
- const { execSync: execSync8 } = require("child_process");
33370
- execSync8(`which ${spawnCmd}`, { stdio: "ignore" });
33371
- } catch {
33372
- const installInfo = provider.install || `Install: check ${provider.displayName || provider.name} documentation`;
33373
- throw new Error(
33374
- `${provider.displayName || provider.name} is not installed.
33375
- Command '${spawnCmd}' not found in PATH.
33422
+ const resolvedProvider = this.providerLoader.resolve(normalizedType) || provider;
33423
+ const spawnCmd = resolvedProvider.spawn?.command;
33424
+ if (spawnCmd && !commandExists(spawnCmd)) {
33425
+ const installInfo = provider.install || `Install: check ${provider.displayName || provider.name} documentation`;
33426
+ throw new Error(
33427
+ `${provider.displayName || provider.name} is not installed.
33428
+ Command '${spawnCmd}' not found.
33376
33429
 
33377
33430
  ${installInfo}`
33378
- );
33379
- }
33431
+ );
33380
33432
  }
33381
33433
  console.log(colorize("cyan", ` \u{1F50C} Starting ACP agent: ${provider.name} (${provider.type}) in ${resolvedDir}`));
33382
- const acpInstance = new AcpProviderInstance(provider, resolvedDir, cliArgs);
33434
+ const acpInstance = new AcpProviderInstance(resolvedProvider, resolvedDir, cliArgs);
33383
33435
  await instanceManager2.addInstance(key, acpInstance, {
33384
33436
  settings: this.providerLoader.getSettings(normalizedType)
33385
33437
  });
@@ -36076,15 +36128,18 @@ var init_provider_loader = __esm({
36076
36128
  getCliDetectionList() {
36077
36129
  const result = [];
36078
36130
  for (const p of this.providers.values()) {
36079
- if ((p.category === "cli" || p.category === "acp") && p.spawn?.command) {
36131
+ if ((p.category === "cli" || p.category === "acp") && p.spawn?.command && this.isMachineProviderEnabled(p.type)) {
36080
36132
  const versionCommand = this.getPlatformVersionCommand(p.versionCommand);
36081
36133
  const command = this.getSpawnCommand(p.type, p.spawn.command);
36134
+ const args = this.getSpawnArgs(p.type, p.spawn.args || []);
36082
36135
  result.push({
36083
36136
  id: p.type,
36084
36137
  displayName: p.displayName || p.name,
36085
36138
  icon: p.icon || "\u{1F527}",
36086
36139
  command,
36140
+ ...args.length > 0 ? { args } : {},
36087
36141
  category: p.category,
36142
+ enabled: true,
36088
36143
  ...typeof versionCommand === "string" && versionCommand.trim() ? { versionCommand: versionCommand.trim() } : {}
36089
36144
  });
36090
36145
  }
@@ -36213,9 +36268,10 @@ var init_provider_loader = __esm({
36213
36268
  return [...this.providers.values()].filter((p) => p.category === "ide" && p.cdpPorts).map((p) => p.type);
36214
36269
  }
36215
36270
  getSpawnCommand(type, fallback2) {
36216
- const override = this.getOptionalStringSetting(type, "executablePath");
36217
- if (override) return override;
36218
- return fallback2 || this.providers.get(type)?.spawn?.command || type;
36271
+ const providerType = this.resolveAlias(type);
36272
+ const machineConfig = this.getMachineProviderConfig(providerType);
36273
+ if (machineConfig.executable) return machineConfig.executable;
36274
+ return fallback2 || this.providers.get(providerType)?.spawn?.command || providerType;
36219
36275
  }
36220
36276
  getIdeCliCommand(type, fallback2) {
36221
36277
  const override = this.getOptionalStringSetting(type, "cliPathOverride");
@@ -36229,6 +36285,131 @@ var init_provider_loader = __esm({
36229
36285
  const osPaths = this.providers.get(type)?.paths?.[process.platform];
36230
36286
  return Array.isArray(osPaths) ? [...osPaths] : [];
36231
36287
  }
36288
+ isMachineProviderEnabled(type) {
36289
+ const providerType = this.resolveAlias(type);
36290
+ const config2 = this.readConfig();
36291
+ return config2?.machineProviders?.[providerType]?.enabled === true;
36292
+ }
36293
+ getMachineProviderConfig(type) {
36294
+ const providerType = this.resolveAlias(type);
36295
+ const raw = this.readConfig()?.machineProviders?.[providerType];
36296
+ if (!raw || typeof raw !== "object") return {};
36297
+ const executable = typeof raw.executable === "string" && raw.executable.trim() ? raw.executable.trim() : void 0;
36298
+ return {
36299
+ ...raw.enabled === true ? { enabled: true } : {},
36300
+ ...executable ? { executable } : {},
36301
+ ...Array.isArray(raw.args) ? { args: raw.args.filter((arg) => typeof arg === "string") } : {},
36302
+ ...raw.lastDetection && typeof raw.lastDetection === "object" ? { lastDetection: raw.lastDetection } : {},
36303
+ ...raw.lastVerification && typeof raw.lastVerification === "object" ? { lastVerification: raw.lastVerification } : {}
36304
+ };
36305
+ }
36306
+ setMachineProviderConfig(type, patch) {
36307
+ const providerType = this.resolveAlias(type);
36308
+ if (!this.providers.has(providerType)) return false;
36309
+ const config2 = this.readConfig();
36310
+ if (!config2) return false;
36311
+ try {
36312
+ if (!config2.machineProviders) config2.machineProviders = {};
36313
+ const current = config2.machineProviders[providerType] || {};
36314
+ const next = { ...current };
36315
+ const enabledChanged = "enabled" in patch && current.enabled !== (patch.enabled === true);
36316
+ const executableChanged = "executable" in patch;
36317
+ const argsChanged = "args" in patch;
36318
+ if ("enabled" in patch) next.enabled = patch.enabled === true;
36319
+ if ("executable" in patch) {
36320
+ const executable = typeof patch.executable === "string" ? patch.executable.trim() : "";
36321
+ if (executable) next.executable = executable;
36322
+ else delete next.executable;
36323
+ }
36324
+ if ("args" in patch) {
36325
+ if (Array.isArray(patch.args)) next.args = patch.args.filter((arg) => typeof arg === "string");
36326
+ else delete next.args;
36327
+ }
36328
+ if (enabledChanged || executableChanged || argsChanged) {
36329
+ delete next.lastDetection;
36330
+ delete next.lastVerification;
36331
+ }
36332
+ if ("lastDetection" in patch) {
36333
+ if (patch.lastDetection) next.lastDetection = patch.lastDetection;
36334
+ else delete next.lastDetection;
36335
+ }
36336
+ if ("lastVerification" in patch) {
36337
+ if (patch.lastVerification) next.lastVerification = patch.lastVerification;
36338
+ else delete next.lastVerification;
36339
+ }
36340
+ config2.machineProviders[providerType] = next;
36341
+ if (next.enabled !== true) {
36342
+ this.providerAvailability.set(providerType, { installed: false, detectedPath: null });
36343
+ }
36344
+ this.writeConfig(config2);
36345
+ this.log(`Machine provider config updated: ${providerType}`);
36346
+ return true;
36347
+ } catch (e) {
36348
+ this.log(`Failed to save machine provider config: ${e.message}`);
36349
+ return false;
36350
+ }
36351
+ }
36352
+ setMachineProviderEnabled(type, enabled) {
36353
+ return this.setMachineProviderConfig(type, { enabled });
36354
+ }
36355
+ getMachineProviderStatus(type) {
36356
+ const providerType = this.resolveAlias(type);
36357
+ if (!this.isMachineProviderEnabled(providerType)) return "disabled";
36358
+ const availability = this.providerAvailability.get(providerType);
36359
+ if (!availability) return "enabled_unchecked";
36360
+ return availability.installed ? "detected" : "not_detected";
36361
+ }
36362
+ getSpawnArgs(type, fallback2 = []) {
36363
+ const machineConfig = this.getMachineProviderConfig(type);
36364
+ if (machineConfig.args) return [...machineConfig.args];
36365
+ return [...fallback2];
36366
+ }
36367
+ parseArgsSetting(value) {
36368
+ const args = [];
36369
+ let current = "";
36370
+ let quote = null;
36371
+ let escaping = false;
36372
+ for (const ch of value.trim()) {
36373
+ if (escaping) {
36374
+ current += ch;
36375
+ escaping = false;
36376
+ continue;
36377
+ }
36378
+ if (ch === "\\") {
36379
+ escaping = true;
36380
+ continue;
36381
+ }
36382
+ if (quote === "single") {
36383
+ if (ch === "'") quote = null;
36384
+ else current += ch;
36385
+ continue;
36386
+ }
36387
+ if (quote === "double") {
36388
+ if (ch === '"') quote = null;
36389
+ else current += ch;
36390
+ continue;
36391
+ }
36392
+ if (ch === "'") {
36393
+ quote = "single";
36394
+ continue;
36395
+ }
36396
+ if (ch === '"') {
36397
+ quote = "double";
36398
+ continue;
36399
+ }
36400
+ if (/\s/.test(ch)) {
36401
+ if (current) {
36402
+ args.push(current);
36403
+ current = "";
36404
+ }
36405
+ continue;
36406
+ }
36407
+ current += ch;
36408
+ }
36409
+ if (escaping) current += "\\";
36410
+ if (current) args.push(current);
36411
+ return args;
36412
+ }
36232
36413
  setProviderAvailability(type, state) {
36233
36414
  this.providerAvailability.set(type, {
36234
36415
  installed: !!state.installed,
@@ -36236,18 +36417,53 @@ var init_provider_loader = __esm({
36236
36417
  });
36237
36418
  }
36238
36419
  setCliDetectionResults(results, replace = true) {
36420
+ const resultByType = /* @__PURE__ */ new Map();
36421
+ for (const result of results) {
36422
+ resultByType.set(this.resolveAlias(result.id), result);
36423
+ }
36239
36424
  if (replace) {
36240
36425
  for (const provider of this.providers.values()) {
36241
36426
  if (provider.category === "cli" || provider.category === "acp") {
36242
- this.providerAvailability.set(provider.type, { installed: false, detectedPath: null });
36427
+ const result = resultByType.get(provider.type);
36428
+ const installed = !!result?.installed;
36429
+ const detectedPath = result?.path || null;
36430
+ this.providerAvailability.set(provider.type, { installed, detectedPath });
36431
+ if (this.isMachineProviderEnabled(provider.type)) {
36432
+ this.setMachineProviderConfig(provider.type, {
36433
+ lastDetection: {
36434
+ ok: installed,
36435
+ stage: "detection",
36436
+ checkedAt: (/* @__PURE__ */ new Date()).toISOString(),
36437
+ command: this.getSpawnCommand(provider.type, provider.spawn?.command),
36438
+ path: detectedPath,
36439
+ message: installed ? "Provider command detected" : "Provider command was not detected"
36440
+ }
36441
+ });
36442
+ }
36243
36443
  }
36244
36444
  }
36445
+ return;
36245
36446
  }
36246
36447
  for (const result of results) {
36247
- this.setProviderAvailability(result.id, {
36448
+ const providerType = this.resolveAlias(result.id);
36449
+ const provider = this.providers.get(providerType);
36450
+ const detectedPath = result.path || null;
36451
+ this.setProviderAvailability(providerType, {
36248
36452
  installed: !!result.installed,
36249
- detectedPath: result.path || null
36453
+ detectedPath
36250
36454
  });
36455
+ if (provider && (provider.category === "cli" || provider.category === "acp") && this.isMachineProviderEnabled(providerType)) {
36456
+ this.setMachineProviderConfig(providerType, {
36457
+ lastDetection: {
36458
+ ok: !!result.installed,
36459
+ stage: "detection",
36460
+ checkedAt: (/* @__PURE__ */ new Date()).toISOString(),
36461
+ command: this.getSpawnCommand(providerType, provider.spawn?.command),
36462
+ path: detectedPath,
36463
+ message: result.installed ? "Provider command detected" : "Provider command was not detected"
36464
+ }
36465
+ });
36466
+ }
36251
36467
  }
36252
36468
  }
36253
36469
  setIdeDetectionResults(results, replace = true) {
@@ -36268,8 +36484,14 @@ var init_provider_loader = __esm({
36268
36484
  getAvailableProviderInfos() {
36269
36485
  return this.getAll().map((provider) => {
36270
36486
  const availability = this.providerAvailability.get(provider.type);
36487
+ const enabled = this.isMachineProviderEnabled(provider.type);
36488
+ const machineConfig = this.getMachineProviderConfig(provider.type);
36271
36489
  return {
36272
36490
  ...provider,
36491
+ enabled,
36492
+ machineStatus: this.getMachineProviderStatus(provider.type),
36493
+ ...machineConfig.lastDetection ? { lastDetection: machineConfig.lastDetection } : {},
36494
+ ...machineConfig.lastVerification ? { lastVerification: machineConfig.lastVerification } : {},
36273
36495
  ...availability ? {
36274
36496
  installed: availability.installed,
36275
36497
  detectedPath: availability.detectedPath
@@ -36416,6 +36638,13 @@ var init_provider_loader = __esm({
36416
36638
  }
36417
36639
  }
36418
36640
  }
36641
+ if ((resolved.category === "cli" || resolved.category === "acp") && resolved.spawn?.command) {
36642
+ resolved.spawn = {
36643
+ ...resolved.spawn,
36644
+ command: this.getSpawnCommand(type, resolved.spawn.command),
36645
+ args: this.getSpawnArgs(type, resolved.spawn.args || [])
36646
+ };
36647
+ }
36419
36648
  return resolved;
36420
36649
  }
36421
36650
  /**
@@ -36738,20 +36967,33 @@ var init_provider_loader = __esm({
36738
36967
  * Resolved setting value for a provider (default + user override)
36739
36968
  */
36740
36969
  getSettingValue(type, key) {
36741
- const schemaDef = this.getSettingsSchema(type)[key];
36970
+ const providerType = this.resolveAlias(type);
36971
+ const machineConfig = this.getMachineProviderConfig(providerType);
36972
+ if (key === "enabled") {
36973
+ return machineConfig.enabled === true;
36974
+ }
36975
+ if (key === "executablePath") {
36976
+ return machineConfig.executable || "";
36977
+ }
36978
+ if (key === "executableArgs") {
36979
+ const args = machineConfig.args;
36980
+ return args ? args.map((arg) => /\s/.test(arg) ? JSON.stringify(arg) : arg).join(" ") : "";
36981
+ }
36982
+ const schemaDef = this.getSettingsSchema(providerType)[key];
36742
36983
  const defaultVal = schemaDef ? key === "autoApprove" && schemaDef.type === "boolean" ? true : schemaDef.default : void 0;
36743
36984
  const config2 = this.readConfig();
36744
- const userVal = config2?.providerSettings?.[type]?.[key];
36985
+ const userVal = config2?.providerSettings?.[providerType]?.[key];
36745
36986
  return userVal !== void 0 ? userVal : defaultVal;
36746
36987
  }
36747
36988
  /**
36748
36989
  * All resolved settings for a provider (default + user override)
36749
36990
  */
36750
36991
  getSettings(type) {
36751
- const settings = this.getSettingsSchema(type);
36992
+ const providerType = this.resolveAlias(type);
36993
+ const settings = this.getSettingsSchema(providerType);
36752
36994
  const result = {};
36753
36995
  for (const [key] of Object.entries(settings)) {
36754
- result[key] = this.getSettingValue(type, key);
36996
+ result[key] = this.getSettingValue(providerType, key);
36755
36997
  }
36756
36998
  return result;
36757
36999
  }
@@ -36759,7 +37001,8 @@ var init_provider_loader = __esm({
36759
37001
  * Save provider setting value (writes to config.json)
36760
37002
  */
36761
37003
  setSetting(type, key, value) {
36762
- const schemaDef = this.getSettingsSchema(type)[key];
37004
+ const providerType = this.resolveAlias(type);
37005
+ const schemaDef = this.getSettingsSchema(providerType)[key];
36763
37006
  if (!schemaDef) return false;
36764
37007
  if (!schemaDef.public) return false;
36765
37008
  if (schemaDef.type === "boolean" && typeof value !== "boolean") return false;
@@ -36770,14 +37013,25 @@ var init_provider_loader = __esm({
36770
37013
  if (schemaDef.max !== void 0 && value > schemaDef.max) return false;
36771
37014
  }
36772
37015
  if (schemaDef.type === "select" && schemaDef.options && !schemaDef.options.includes(value)) return false;
37016
+ if (key === "enabled") {
37017
+ return this.setMachineProviderEnabled(providerType, value);
37018
+ }
37019
+ if (key === "executablePath") {
37020
+ return this.setMachineProviderConfig(providerType, { executable: value });
37021
+ }
37022
+ if (key === "executableArgs") {
37023
+ return this.setMachineProviderConfig(providerType, {
37024
+ args: value.trim() ? this.parseArgsSetting(value) : void 0
37025
+ });
37026
+ }
36773
37027
  const config2 = this.readConfig();
36774
37028
  if (!config2) return false;
36775
37029
  try {
36776
37030
  if (!config2.providerSettings) config2.providerSettings = {};
36777
- if (!config2.providerSettings[type]) config2.providerSettings[type] = {};
36778
- config2.providerSettings[type][key] = value;
37031
+ if (!config2.providerSettings[providerType]) config2.providerSettings[providerType] = {};
37032
+ config2.providerSettings[providerType][key] = value;
36779
37033
  this.writeConfig(config2);
36780
- this.log(`Setting updated: ${type}.${key} = ${JSON.stringify(value)}`);
37034
+ this.log(`Setting updated: ${providerType}.${key} = ${JSON.stringify(value)}`);
36781
37035
  return true;
36782
37036
  } catch (e) {
36783
37037
  this.log(`Failed to save setting: ${e.message}`);
@@ -36838,6 +37092,15 @@ var init_provider_loader = __esm({
36838
37092
  }
36839
37093
  getSyntheticSettings(type, provider) {
36840
37094
  const result = {};
37095
+ if (provider.category === "cli" || provider.category === "acp") {
37096
+ result.enabled = {
37097
+ type: "boolean",
37098
+ default: false,
37099
+ public: true,
37100
+ label: "Enabled on this machine",
37101
+ description: "Opt in before ADHDev detects, launches, or verifies this provider on this machine."
37102
+ };
37103
+ }
36841
37104
  if (!provider.settings?.autoApprove) {
36842
37105
  result.autoApprove = {
36843
37106
  type: "boolean",
@@ -36856,6 +37119,15 @@ var init_provider_loader = __esm({
36856
37119
  description: "Optional absolute path for this provider binary. Leave blank to use the default PATH lookup."
36857
37120
  };
36858
37121
  }
37122
+ if ((provider.category === "cli" || provider.category === "acp") && provider.spawn?.command && !provider.settings?.executableArgs) {
37123
+ result.executableArgs = {
37124
+ type: "string",
37125
+ default: "",
37126
+ public: true,
37127
+ label: "Executable arguments",
37128
+ description: "Optional replacement for provider default command arguments. Leave blank to use the provider default."
37129
+ };
37130
+ }
36859
37131
  if (provider.category === "ide") {
36860
37132
  if (provider.cli && !provider.settings?.cliPathOverride) {
36861
37133
  result.cliPathOverride = {
@@ -37175,32 +37447,32 @@ async function killIdeProcess(ideId) {
37175
37447
  try {
37176
37448
  if (plat === "darwin" && appName) {
37177
37449
  try {
37178
- (0, import_child_process6.execSync)(`osascript -e 'tell application "${escapeForAppleScript(appName)}" to quit' 2>/dev/null`, {
37450
+ (0, import_child_process7.execSync)(`osascript -e 'tell application "${escapeForAppleScript(appName)}" to quit' 2>/dev/null`, {
37179
37451
  timeout: 5e3
37180
37452
  });
37181
37453
  } catch {
37182
37454
  try {
37183
- (0, import_child_process6.execSync)(`pkill -x "${appName}" 2>/dev/null`, { timeout: 5e3 });
37455
+ (0, import_child_process7.execSync)(`pkill -x "${appName}" 2>/dev/null`, { timeout: 5e3 });
37184
37456
  } catch {
37185
37457
  }
37186
37458
  }
37187
37459
  } else if (plat === "win32" && winProcesses) {
37188
37460
  for (const proc of winProcesses) {
37189
37461
  try {
37190
- (0, import_child_process6.execSync)(`taskkill /IM "${proc}" /F 2>nul`, { timeout: 5e3 });
37462
+ (0, import_child_process7.execSync)(`taskkill /IM "${proc}" /F 2>nul`, { timeout: 5e3 });
37191
37463
  } catch {
37192
37464
  }
37193
37465
  }
37194
37466
  try {
37195
37467
  const exeName = winProcesses[0].replace(".exe", "");
37196
- (0, import_child_process6.execSync)(`powershell -Command "Get-Process -Name '${exeName}' -ErrorAction SilentlyContinue | Stop-Process -Force"`, {
37468
+ (0, import_child_process7.execSync)(`powershell -Command "Get-Process -Name '${exeName}' -ErrorAction SilentlyContinue | Stop-Process -Force"`, {
37197
37469
  timeout: 1e4
37198
37470
  });
37199
37471
  } catch {
37200
37472
  }
37201
37473
  } else {
37202
37474
  try {
37203
- (0, import_child_process6.execSync)(`pkill -f "${ideId}" 2>/dev/null`);
37475
+ (0, import_child_process7.execSync)(`pkill -f "${ideId}" 2>/dev/null`);
37204
37476
  } catch {
37205
37477
  }
37206
37478
  }
@@ -37210,13 +37482,13 @@ async function killIdeProcess(ideId) {
37210
37482
  }
37211
37483
  if (plat === "darwin" && appName) {
37212
37484
  try {
37213
- (0, import_child_process6.execSync)(`pkill -9 -x "${appName}" 2>/dev/null`, { timeout: 5e3 });
37485
+ (0, import_child_process7.execSync)(`pkill -9 -x "${appName}" 2>/dev/null`, { timeout: 5e3 });
37214
37486
  } catch {
37215
37487
  }
37216
37488
  } else if (plat === "win32" && winProcesses) {
37217
37489
  for (const proc of winProcesses) {
37218
37490
  try {
37219
- (0, import_child_process6.execSync)(`taskkill /IM "${proc}" /F 2>nul`);
37491
+ (0, import_child_process7.execSync)(`taskkill /IM "${proc}" /F 2>nul`);
37220
37492
  } catch {
37221
37493
  }
37222
37494
  }
@@ -37234,13 +37506,13 @@ function isIdeRunning(ideId) {
37234
37506
  const appName = getMacAppIdentifiers()[ideId];
37235
37507
  if (!appName) return false;
37236
37508
  try {
37237
- const result = (0, import_child_process6.execSync)(`pgrep -x "${appName}" 2>/dev/null`, {
37509
+ const result = (0, import_child_process7.execSync)(`pgrep -x "${appName}" 2>/dev/null`, {
37238
37510
  encoding: "utf-8",
37239
37511
  timeout: 3e3
37240
37512
  });
37241
37513
  return result.trim().length > 0;
37242
37514
  } catch {
37243
- const result = (0, import_child_process6.execSync)(
37515
+ const result = (0, import_child_process7.execSync)(
37244
37516
  `osascript -e 'tell application "System Events" to count (every process whose name is "${escapeForAppleScript(appName)}")'`,
37245
37517
  {
37246
37518
  encoding: "utf-8",
@@ -37255,14 +37527,14 @@ function isIdeRunning(ideId) {
37255
37527
  if (!winProcesses) return false;
37256
37528
  for (const proc of winProcesses) {
37257
37529
  try {
37258
- const result = (0, import_child_process6.execSync)(`tasklist /FI "IMAGENAME eq ${proc}" /NH 2>nul`, { encoding: "utf-8" });
37530
+ const result = (0, import_child_process7.execSync)(`tasklist /FI "IMAGENAME eq ${proc}" /NH 2>nul`, { encoding: "utf-8" });
37259
37531
  if (result.includes(proc)) return true;
37260
37532
  } catch {
37261
37533
  }
37262
37534
  }
37263
37535
  try {
37264
37536
  const exeName = winProcesses[0].replace(".exe", "");
37265
- const result = (0, import_child_process6.execSync)(
37537
+ const result = (0, import_child_process7.execSync)(
37266
37538
  `powershell -Command "(Get-Process -Name '${exeName}' -ErrorAction SilentlyContinue).Count"`,
37267
37539
  { encoding: "utf-8", timeout: 5e3 }
37268
37540
  );
@@ -37271,7 +37543,7 @@ function isIdeRunning(ideId) {
37271
37543
  }
37272
37544
  return false;
37273
37545
  } else {
37274
- const result = (0, import_child_process6.execSync)(`pgrep -f "${ideId}" 2>/dev/null`, { encoding: "utf-8" });
37546
+ const result = (0, import_child_process7.execSync)(`pgrep -f "${ideId}" 2>/dev/null`, { encoding: "utf-8" });
37275
37547
  return result.trim().length > 0;
37276
37548
  }
37277
37549
  } catch {
@@ -37284,7 +37556,7 @@ function detectCurrentWorkspace(ideId) {
37284
37556
  try {
37285
37557
  const appName = getMacAppIdentifiers()[ideId];
37286
37558
  if (!appName) return void 0;
37287
- const result = (0, import_child_process6.execSync)(
37559
+ const result = (0, import_child_process7.execSync)(
37288
37560
  `lsof -c "${appName}" 2>/dev/null | grep cwd | head -1 | awk '{print $NF}'`,
37289
37561
  { encoding: "utf-8", timeout: 3e3 }
37290
37562
  );
@@ -37436,10 +37708,10 @@ async function launchMacOS(ide, port, workspace, newWindow) {
37436
37708
  const canUseAppLauncher = !!appName;
37437
37709
  const useAppLauncher = preferredMethod === "app" ? canUseAppLauncher : preferredMethod === "cli" ? false : !canUseCli && canUseAppLauncher;
37438
37710
  if (!useAppLauncher && ide.cliCommand) {
37439
- (0, import_child_process6.spawn)(ide.cliCommand, args, { detached: true, stdio: "ignore" }).unref();
37711
+ (0, import_child_process7.spawn)(ide.cliCommand, args, { detached: true, stdio: "ignore" }).unref();
37440
37712
  } else if (appName) {
37441
37713
  const openArgs = ["-a", appName, "--args", ...args];
37442
- (0, import_child_process6.spawn)("open", openArgs, { detached: true, stdio: "ignore" }).unref();
37714
+ (0, import_child_process7.spawn)("open", openArgs, { detached: true, stdio: "ignore" }).unref();
37443
37715
  } else {
37444
37716
  throw new Error(`No app identifier or CLI for ${ide.displayName}`);
37445
37717
  }
@@ -37465,16 +37737,16 @@ async function launchLinux(ide, port, workspace, newWindow) {
37465
37737
  const args = ["--remote-debugging-port=" + port];
37466
37738
  if (newWindow) args.push("--new-window");
37467
37739
  if (workspace) args.push(workspace);
37468
- (0, import_child_process6.spawn)(cli, args, { detached: true, stdio: "ignore" }).unref();
37740
+ (0, import_child_process7.spawn)(cli, args, { detached: true, stdio: "ignore" }).unref();
37469
37741
  }
37470
37742
  function getAvailableIdeIds() {
37471
37743
  return getProviderLoader().getAvailableIdeTypes();
37472
37744
  }
37473
- var import_child_process6, net2, os17, path15, _providerLoader;
37745
+ var import_child_process7, net2, os17, path15, _providerLoader;
37474
37746
  var init_launch = __esm({
37475
37747
  "../../oss/packages/daemon-core/src/launch.ts"() {
37476
37748
  "use strict";
37477
- import_child_process6 = require("child_process");
37749
+ import_child_process7 = require("child_process");
37478
37750
  net2 = __toESM(require("net"));
37479
37751
  os17 = __toESM(require("os"));
37480
37752
  path15 = __toESM(require("path"));
@@ -38046,7 +38318,7 @@ function getNpmExecOptions() {
38046
38318
  function killPid(pid) {
38047
38319
  try {
38048
38320
  if (process.platform === "win32") {
38049
- (0, import_child_process7.execFileSync)("taskkill", ["/PID", String(pid), "/T", "/F"], { stdio: "ignore" });
38321
+ (0, import_child_process8.execFileSync)("taskkill", ["/PID", String(pid), "/T", "/F"], { stdio: "ignore" });
38050
38322
  } else {
38051
38323
  process.kill(pid, "SIGTERM");
38052
38324
  }
@@ -38084,7 +38356,7 @@ function stopSessionHostProcesses(appName) {
38084
38356
  }
38085
38357
  if (process.platform !== "win32") {
38086
38358
  try {
38087
- const raw = (0, import_child_process7.execFileSync)("pgrep", ["-f", "session-host-daemon"], { encoding: "utf8" }).trim();
38359
+ const raw = (0, import_child_process8.execFileSync)("pgrep", ["-f", "session-host-daemon"], { encoding: "utf8" }).trim();
38088
38360
  for (const line of raw.split("\n")) {
38089
38361
  const pid = Number.parseInt(line.trim(), 10);
38090
38362
  if (Number.isFinite(pid)) {
@@ -38105,9 +38377,9 @@ function removeDaemonPidFile() {
38105
38377
  function cleanupStaleGlobalInstallDirs(pkgName, surface) {
38106
38378
  const npmExecOpts = getNpmExecOptions();
38107
38379
  const prefixArgs = surface.installPrefix ? ["--prefix", surface.installPrefix] : [];
38108
- const npmRoot = (0, import_child_process7.execFileSync)(surface.npmExecutable, ["root", "-g", ...prefixArgs], { encoding: "utf8", ...npmExecOpts }).trim();
38380
+ const npmRoot = (0, import_child_process8.execFileSync)(surface.npmExecutable, ["root", "-g", ...prefixArgs], { encoding: "utf8", ...npmExecOpts }).trim();
38109
38381
  if (!npmRoot) return;
38110
- const npmPrefix = surface.installPrefix || (0, import_child_process7.execFileSync)(surface.npmExecutable, ["prefix", "-g", ...prefixArgs], { encoding: "utf8", ...npmExecOpts }).trim();
38382
+ const npmPrefix = surface.installPrefix || (0, import_child_process8.execFileSync)(surface.npmExecutable, ["prefix", "-g", ...prefixArgs], { encoding: "utf8", ...npmExecOpts }).trim();
38111
38383
  const binDir = process.platform === "win32" ? npmPrefix : path17.join(npmPrefix, "bin");
38112
38384
  const packageBaseName = pkgName.startsWith("@") ? pkgName.split("/")[1] : pkgName;
38113
38385
  const binNames = /* @__PURE__ */ new Set([packageBaseName]);
@@ -38140,7 +38412,7 @@ function cleanupStaleGlobalInstallDirs(pkgName, surface) {
38140
38412
  }
38141
38413
  function spawnDetachedDaemonUpgradeHelper(payload) {
38142
38414
  const env3 = { ...process.env, [UPGRADE_HELPER_ENV]: JSON.stringify(payload) };
38143
- const child = (0, import_child_process8.spawn)(process.execPath, process.argv.slice(1), {
38415
+ const child = (0, import_child_process9.spawn)(process.execPath, process.argv.slice(1), {
38144
38416
  detached: true,
38145
38417
  stdio: "ignore",
38146
38418
  windowsHide: true,
@@ -38170,7 +38442,7 @@ async function runDaemonUpgradeHelper(payload) {
38170
38442
  cleanupStaleGlobalInstallDirs(payload.packageName, installCommand.surface);
38171
38443
  const spec = `${payload.packageName}@${payload.targetVersion || "latest"}`;
38172
38444
  appendUpgradeLog(`Installing ${spec}`);
38173
- const installOutput = (0, import_child_process7.execFileSync)(
38445
+ const installOutput = (0, import_child_process8.execFileSync)(
38174
38446
  installCommand.command,
38175
38447
  installCommand.args,
38176
38448
  {
@@ -38192,7 +38464,7 @@ async function runDaemonUpgradeHelper(payload) {
38192
38464
  const env3 = { ...process.env };
38193
38465
  delete env3[UPGRADE_HELPER_ENV];
38194
38466
  appendUpgradeLog(`Restarting daemon with args: ${restartArgv.join(" ")}`);
38195
- const child = (0, import_child_process8.spawn)(process.execPath, restartArgv, {
38467
+ const child = (0, import_child_process9.spawn)(process.execPath, restartArgv, {
38196
38468
  detached: true,
38197
38469
  stdio: "ignore",
38198
38470
  windowsHide: true,
@@ -38217,12 +38489,12 @@ async function maybeRunDaemonUpgradeHelperFromEnv() {
38217
38489
  process.exit(1);
38218
38490
  }
38219
38491
  }
38220
- var import_child_process7, import_child_process8, fs8, os20, path17, UPGRADE_HELPER_ENV;
38492
+ var import_child_process8, import_child_process9, fs8, os20, path17, UPGRADE_HELPER_ENV;
38221
38493
  var init_upgrade_helper = __esm({
38222
38494
  "../../oss/packages/daemon-core/src/commands/upgrade-helper.ts"() {
38223
38495
  "use strict";
38224
- import_child_process7 = require("child_process");
38225
38496
  import_child_process8 = require("child_process");
38497
+ import_child_process9 = require("child_process");
38226
38498
  fs8 = __toESM(require("fs"));
38227
38499
  os20 = __toESM(require("os"));
38228
38500
  path17 = __toESM(require("path"));
@@ -38327,6 +38599,7 @@ var init_router = __esm({
38327
38599
  init_saved_sessions();
38328
38600
  init_chat_history();
38329
38601
  init_ide_detector();
38602
+ init_cli_detector();
38330
38603
  init_logger();
38331
38604
  init_command_log();
38332
38605
  init_logger();
@@ -38763,6 +39036,33 @@ var init_router = __esm({
38763
39036
  }
38764
39037
  return { ...result };
38765
39038
  }
39039
+ // ─── Detect providers ───
39040
+ case "detect_provider": {
39041
+ const providerType = typeof args?.providerType === "string" ? args.providerType.trim() : "";
39042
+ if (!providerType) return { success: false, error: "providerType is required" };
39043
+ const normalizedType = this.deps.providerLoader.resolveAlias(providerType);
39044
+ const provider = this.deps.providerLoader.getByAlias(providerType);
39045
+ if (!provider) return { success: false, error: `Provider not found: ${providerType}` };
39046
+ if (provider.category !== "cli" && provider.category !== "acp") {
39047
+ return { success: false, error: `Provider detection is only supported for CLI/ACP providers: ${providerType}` };
39048
+ }
39049
+ if (!this.deps.providerLoader.isMachineProviderEnabled(normalizedType)) {
39050
+ return { success: false, error: `Provider is disabled on this machine: ${providerType}` };
39051
+ }
39052
+ const detected = await detectCLI(normalizedType, this.deps.providerLoader, { includeVersion: false });
39053
+ this.deps.providerLoader.setCliDetectionResults([{
39054
+ id: normalizedType,
39055
+ installed: !!detected,
39056
+ path: detected?.path
39057
+ }], false);
39058
+ this.deps.onStatusChange?.();
39059
+ return {
39060
+ success: true,
39061
+ providerType: normalizedType,
39062
+ detected: !!detected,
39063
+ path: detected?.path || null
39064
+ };
39065
+ }
38766
39066
  // ─── Detect IDEs ───
38767
39067
  case "detect_ides": {
38768
39068
  const results = await detectIDEs(this.deps.providerLoader);
@@ -38808,13 +39108,16 @@ var init_router = __esm({
38808
39108
  this.deps.cdpManagers
38809
39109
  );
38810
39110
  const targetSession = sessionEntries.find((entry) => entry.id === sessionId);
38811
- const completionMarker = targetSession ? getSessionCompletionMarker(targetSession) : "";
39111
+ const requestedCompletionMarker = typeof args?.completionMarker === "string" ? args.completionMarker.trim() : "";
39112
+ const completionMarker = requestedCompletionMarker || (targetSession ? getSessionCompletionMarker(targetSession) : "");
39113
+ const requestedProviderSessionId = typeof args?.providerSessionId === "string" ? args.providerSessionId.trim() : "";
39114
+ const providerSessionId = requestedProviderSessionId || targetSession?.providerSessionId;
38812
39115
  const next = markSessionSeen(
38813
39116
  currentState,
38814
39117
  sessionId,
38815
39118
  typeof args?.seenAt === "number" ? args.seenAt : Date.now(),
38816
39119
  completionMarker,
38817
- targetSession?.providerSessionId
39120
+ providerSessionId
38818
39121
  );
38819
39122
  if (READ_DEBUG_ENABLED2) {
38820
39123
  LOG.info("RecentRead", `mark_session_seen sessionId=${sessionId} seenAt=${String(args?.seenAt || "")} prevSeenAt=${String(prevSeenAt)} nextSeenAt=${String(next.sessionReads?.[sessionId] || 0)} marker=${completionMarker || "-"}`);
@@ -40607,7 +40910,7 @@ var init_provider_instance_manager = __esm({
40607
40910
  // ../../oss/packages/daemon-core/src/providers/version-archive.ts
40608
40911
  function runCommand(cmd, timeout = 1e4) {
40609
40912
  try {
40610
- return (0, import_child_process9.execSync)(cmd, {
40913
+ return (0, import_child_process10.execSync)(cmd, {
40611
40914
  encoding: "utf-8",
40612
40915
  timeout,
40613
40916
  stdio: ["pipe", "pipe", "pipe"]
@@ -40729,14 +41032,14 @@ async function detectAllVersions(loader, archive) {
40729
41032
  }
40730
41033
  return results;
40731
41034
  }
40732
- var fs10, path18, os21, import_child_process9, import_os3, ARCHIVE_PATH, MAX_ENTRIES_PER_PROVIDER, VersionArchive;
41035
+ var fs10, path18, os21, import_child_process10, import_os3, ARCHIVE_PATH, MAX_ENTRIES_PER_PROVIDER, VersionArchive;
40733
41036
  var init_version_archive = __esm({
40734
41037
  "../../oss/packages/daemon-core/src/providers/version-archive.ts"() {
40735
41038
  "use strict";
40736
41039
  fs10 = __toESM(require("fs"));
40737
41040
  path18 = __toESM(require("path"));
40738
41041
  os21 = __toESM(require("os"));
40739
- import_child_process9 = require("child_process");
41042
+ import_child_process10 = require("child_process");
40740
41043
  import_os3 = require("os");
40741
41044
  ARCHIVE_PATH = path18.join(os21.homedir(), ".adhdev", "version-history.json");
40742
41045
  MAX_ENTRIES_PER_PROVIDER = 20;
@@ -46516,7 +46819,7 @@ var init_startup_restore_policy = __esm({
46516
46819
  function isExtensionInstalled(ide, marketplaceId) {
46517
46820
  if (!ide.cliCommand) return false;
46518
46821
  try {
46519
- const result = (0, import_child_process10.execSync)(`"${ide.cliCommand}" --list-extensions`, {
46822
+ const result = (0, import_child_process11.execSync)(`"${ide.cliCommand}" --list-extensions`, {
46520
46823
  encoding: "utf-8",
46521
46824
  timeout: 15e3,
46522
46825
  stdio: ["pipe", "pipe", "pipe"]
@@ -46557,7 +46860,7 @@ async function installExtension(ide, extension) {
46557
46860
  fs27.writeFileSync(vsixPath, buffer);
46558
46861
  return new Promise((resolve18) => {
46559
46862
  const cmd = `"${ide.cliCommand}" --install-extension "${vsixPath}" --force`;
46560
- (0, import_child_process10.exec)(cmd, { timeout: 6e4 }, (error48, _stdout, stderr) => {
46863
+ (0, import_child_process11.exec)(cmd, { timeout: 6e4 }, (error48, _stdout, stderr) => {
46561
46864
  resolve18({
46562
46865
  extensionId: extension.id,
46563
46866
  marketplaceId: extension.marketplaceId,
@@ -46573,7 +46876,7 @@ async function installExtension(ide, extension) {
46573
46876
  }
46574
46877
  return new Promise((resolve18) => {
46575
46878
  const cmd = `"${ide.cliCommand}" --install-extension ${extension.marketplaceId} --force`;
46576
- (0, import_child_process10.exec)(cmd, { timeout: 6e4 }, (error48, stdout, stderr) => {
46879
+ (0, import_child_process11.exec)(cmd, { timeout: 6e4 }, (error48, stdout, stderr) => {
46577
46880
  if (error48) {
46578
46881
  resolve18({
46579
46882
  extensionId: extension.id,
@@ -46610,17 +46913,17 @@ function launchIDE(ide, workspacePath) {
46610
46913
  if (!ide.cliCommand) return false;
46611
46914
  try {
46612
46915
  const args = workspacePath ? `"${workspacePath}"` : "";
46613
- (0, import_child_process10.exec)(`"${ide.cliCommand}" ${args}`, { timeout: 1e4 });
46916
+ (0, import_child_process11.exec)(`"${ide.cliCommand}" ${args}`, { timeout: 1e4 });
46614
46917
  return true;
46615
46918
  } catch {
46616
46919
  return false;
46617
46920
  }
46618
46921
  }
46619
- var import_child_process10, EXTENSION_CATALOG;
46922
+ var import_child_process11, EXTENSION_CATALOG;
46620
46923
  var init_installer = __esm({
46621
46924
  "../../oss/packages/daemon-core/src/installer.ts"() {
46622
46925
  "use strict";
46623
- import_child_process10 = require("child_process");
46926
+ import_child_process11 = require("child_process");
46624
46927
  EXTENSION_CATALOG = [
46625
46928
  // AI Agent extensions
46626
46929
  {
@@ -46823,10 +47126,11 @@ async function initDaemonComponents(config2) {
46823
47126
  if (!providerType || targetCategory === "cli" || targetCategory === "acp") {
46824
47127
  if (providerType && targetProvider) {
46825
47128
  const detected = await detectCLI(targetProvider.type, providerLoader, { includeVersion: false });
46826
- providerLoader.setProviderAvailability(targetProvider.type, {
47129
+ providerLoader.setCliDetectionResults([{
47130
+ id: targetProvider.type,
46827
47131
  installed: !!detected,
46828
- detectedPath: detected?.path || null
46829
- });
47132
+ path: detected?.path
47133
+ }], false);
46830
47134
  } else {
46831
47135
  providerLoader.setCliDetectionResults(await detectCLIs(providerLoader, { includeVersion: false }), true);
46832
47136
  }
@@ -62021,7 +62325,7 @@ var require_buffer_list = __commonJS({
62021
62325
  }
62022
62326
  }, {
62023
62327
  key: "join",
62024
- value: function join32(s) {
62328
+ value: function join33(s) {
62025
62329
  if (this.length === 0) return "";
62026
62330
  var p = this.head;
62027
62331
  var ret = "" + p.data;
@@ -76080,13 +76384,13 @@ function splitStringBySpace(str) {
76080
76384
  }
76081
76385
  return pieces;
76082
76386
  }
76083
- var import_chardet, import_child_process11, import_fs5, import_node_path2, import_node_os4, import_node_crypto, import_iconv_lite, ExternalEditor;
76387
+ var import_chardet, import_child_process12, import_fs6, import_node_path2, import_node_os4, import_node_crypto, import_iconv_lite, ExternalEditor;
76084
76388
  var init_esm2 = __esm({
76085
76389
  "../../node_modules/@inquirer/external-editor/dist/esm/index.js"() {
76086
76390
  "use strict";
76087
76391
  import_chardet = __toESM(require_lib(), 1);
76088
- import_child_process11 = require("child_process");
76089
- import_fs5 = require("fs");
76392
+ import_child_process12 = require("child_process");
76393
+ import_fs6 = require("fs");
76090
76394
  import_node_path2 = __toESM(require("path"), 1);
76091
76395
  import_node_os4 = __toESM(require("os"), 1);
76092
76396
  import_node_crypto = require("crypto");
@@ -76162,14 +76466,14 @@ var init_esm2 = __esm({
76162
76466
  if (Object.prototype.hasOwnProperty.call(this.fileOptions, "mode")) {
76163
76467
  opt.mode = this.fileOptions.mode;
76164
76468
  }
76165
- (0, import_fs5.writeFileSync)(this.tempFile, this.text, opt);
76469
+ (0, import_fs6.writeFileSync)(this.tempFile, this.text, opt);
76166
76470
  } catch (createFileError) {
76167
76471
  throw new CreateFileError(createFileError);
76168
76472
  }
76169
76473
  }
76170
76474
  readTemporaryFile() {
76171
76475
  try {
76172
- const tempFileBuffer = (0, import_fs5.readFileSync)(this.tempFile);
76476
+ const tempFileBuffer = (0, import_fs6.readFileSync)(this.tempFile);
76173
76477
  if (tempFileBuffer.length === 0) {
76174
76478
  this.text = "";
76175
76479
  } else {
@@ -76185,14 +76489,14 @@ var init_esm2 = __esm({
76185
76489
  }
76186
76490
  removeTemporaryFile() {
76187
76491
  try {
76188
- (0, import_fs5.unlinkSync)(this.tempFile);
76492
+ (0, import_fs6.unlinkSync)(this.tempFile);
76189
76493
  } catch (removeFileError) {
76190
76494
  throw new RemoveFileError(removeFileError);
76191
76495
  }
76192
76496
  }
76193
76497
  launchEditor() {
76194
76498
  try {
76195
- const editorProcess = (0, import_child_process11.spawnSync)(this.editor.bin, this.editor.args.concat([this.tempFile]), { stdio: "inherit" });
76499
+ const editorProcess = (0, import_child_process12.spawnSync)(this.editor.bin, this.editor.args.concat([this.tempFile]), { stdio: "inherit" });
76196
76500
  this.lastExitStatus = editorProcess.status ?? 0;
76197
76501
  } catch (launchError) {
76198
76502
  throw new LaunchEditorError(launchError);
@@ -76200,7 +76504,7 @@ var init_esm2 = __esm({
76200
76504
  }
76201
76505
  launchEditorAsync(callback) {
76202
76506
  try {
76203
- const editorProcess = (0, import_child_process11.spawn)(this.editor.bin, this.editor.args.concat([this.tempFile]), { stdio: "inherit" });
76507
+ const editorProcess = (0, import_child_process12.spawn)(this.editor.bin, this.editor.args.concat([this.tempFile]), { stdio: "inherit" });
76204
76508
  editorProcess.on("exit", (code) => {
76205
76509
  this.lastExitStatus = code;
76206
76510
  setImmediate(callback);
@@ -78472,18 +78776,18 @@ function resolvePackageVersion(options) {
78472
78776
  ];
78473
78777
  for (const p of possiblePaths) {
78474
78778
  try {
78475
- const data = JSON.parse((0, import_fs6.readFileSync)(p, "utf-8"));
78779
+ const data = JSON.parse((0, import_fs7.readFileSync)(p, "utf-8"));
78476
78780
  if (data.version) return data.version;
78477
78781
  } catch {
78478
78782
  }
78479
78783
  }
78480
78784
  return injectedVersion;
78481
78785
  }
78482
- var import_fs6, import_path3;
78786
+ var import_fs7, import_path3;
78483
78787
  var init_version = __esm({
78484
78788
  "src/version.ts"() {
78485
78789
  "use strict";
78486
- import_fs6 = require("fs");
78790
+ import_fs7 = require("fs");
78487
78791
  import_path3 = require("path");
78488
78792
  }
78489
78793
  });
@@ -86929,7 +87233,7 @@ function getSessionHostPid() {
86929
87233
  function killPid2(pid) {
86930
87234
  try {
86931
87235
  if (process.platform === "win32") {
86932
- (0, import_child_process12.execFileSync)("taskkill", ["/PID", String(pid), "/T", "/F"], { stdio: "ignore", windowsHide: true });
87236
+ (0, import_child_process13.execFileSync)("taskkill", ["/PID", String(pid), "/T", "/F"], { stdio: "ignore", windowsHide: true });
86933
87237
  } else {
86934
87238
  process.kill(pid, "SIGTERM");
86935
87239
  }
@@ -86941,7 +87245,7 @@ function killPid2(pid) {
86941
87245
  function getWindowsProcessCommandLine(pid) {
86942
87246
  const pidFilter = `ProcessId=${pid}`;
86943
87247
  try {
86944
- const psOut = (0, import_child_process12.execFileSync)("powershell.exe", [
87248
+ const psOut = (0, import_child_process13.execFileSync)("powershell.exe", [
86945
87249
  "-NoProfile",
86946
87250
  "-NonInteractive",
86947
87251
  "-ExecutionPolicy",
@@ -86954,7 +87258,7 @@ function getWindowsProcessCommandLine(pid) {
86954
87258
  } catch {
86955
87259
  }
86956
87260
  try {
86957
- const wmicOut = (0, import_child_process12.execFileSync)("wmic", [
87261
+ const wmicOut = (0, import_child_process13.execFileSync)("wmic", [
86958
87262
  "process",
86959
87263
  "where",
86960
87264
  pidFilter,
@@ -86990,7 +87294,7 @@ function stopSessionHost() {
86990
87294
  let stopped = stopManagedSessionHostProcess();
86991
87295
  if (process.platform === "win32") {
86992
87296
  try {
86993
- const raw = (0, import_child_process12.execFileSync)("tasklist", ["/FO", "CSV", "/NH", "/FI", "IMAGENAME eq node.exe"], {
87297
+ const raw = (0, import_child_process13.execFileSync)("tasklist", ["/FO", "CSV", "/NH", "/FI", "IMAGENAME eq node.exe"], {
86994
87298
  encoding: "utf8",
86995
87299
  timeout: 5e3,
86996
87300
  stdio: ["ignore", "pipe", "ignore"],
@@ -87010,7 +87314,7 @@ function stopSessionHost() {
87010
87314
  }
87011
87315
  } else {
87012
87316
  try {
87013
- const raw = (0, import_child_process12.execFileSync)("pgrep", ["-f", "session-host-daemon"], { encoding: "utf8" }).trim();
87317
+ const raw = (0, import_child_process13.execFileSync)("pgrep", ["-f", "session-host-daemon"], { encoding: "utf8" }).trim();
87014
87318
  for (const line of raw.split("\n")) {
87015
87319
  const pid = Number.parseInt(line.trim(), 10);
87016
87320
  if (Number.isFinite(pid) && pid !== process.pid && pid !== process.ppid) {
@@ -87044,7 +87348,7 @@ async function ensureSessionHostReady2() {
87044
87348
  const logDir = path28.join(os27.homedir(), ".adhdev", "logs");
87045
87349
  fs22.mkdirSync(logDir, { recursive: true });
87046
87350
  const logFd = fs22.openSync(path28.join(logDir, "session-host.log"), "a");
87047
- const child = (0, import_child_process12.spawn)(process.execPath, [entry], {
87351
+ const child = (0, import_child_process13.spawn)(process.execPath, [entry], {
87048
87352
  detached: true,
87049
87353
  stdio: ["ignore", logFd, logFd],
87050
87354
  windowsHide: true,
@@ -87105,11 +87409,11 @@ async function probeSessionHostStatus() {
87105
87409
  };
87106
87410
  }
87107
87411
  }
87108
- var import_child_process12, fs22, os27, path28, SESSION_HOST_APP_NAME, SESSION_HOST_START_TIMEOUT_MS;
87412
+ var import_child_process13, fs22, os27, path28, SESSION_HOST_APP_NAME, SESSION_HOST_START_TIMEOUT_MS;
87109
87413
  var init_session_host = __esm({
87110
87414
  "src/session-host.ts"() {
87111
87415
  "use strict";
87112
- import_child_process12 = require("child_process");
87416
+ import_child_process13 = require("child_process");
87113
87417
  fs22 = __toESM(require("fs"));
87114
87418
  os27 = __toESM(require("os"));
87115
87419
  path28 = __toESM(require("path"));
@@ -87307,7 +87611,7 @@ function removeDaemonPid(ref = {}) {
87307
87611
  function isDaemonRunning(ref = {}) {
87308
87612
  const port = resolveDaemonPort(ref);
87309
87613
  try {
87310
- const { execFileSync: execFileSync5 } = require("child_process");
87614
+ const { execFileSync: execFileSync6 } = require("child_process");
87311
87615
  const probe = `
87312
87616
  const http = require('http');
87313
87617
  const req = http.get('http://127.0.0.1:${port}/health', { timeout: 1500 }, (res) => {
@@ -87317,7 +87621,7 @@ function isDaemonRunning(ref = {}) {
87317
87621
  req.on('error', () => process.stdout.write('0'));
87318
87622
  req.on('timeout', () => { req.destroy(); process.stdout.write('0'); });
87319
87623
  `;
87320
- const result = execFileSync5(process.execPath, ["-e", probe], {
87624
+ const result = execFileSync6(process.execPath, ["-e", probe], {
87321
87625
  encoding: "utf-8",
87322
87626
  timeout: 3e3,
87323
87627
  stdio: ["ignore", "pipe", "ignore"]
@@ -87343,9 +87647,9 @@ function isDaemonRunning(ref = {}) {
87343
87647
  function isAdhdevProcess(pid) {
87344
87648
  try {
87345
87649
  if (process.platform === "win32") {
87346
- const { execFileSync: execFileSync5 } = require("child_process");
87650
+ const { execFileSync: execFileSync6 } = require("child_process");
87347
87651
  try {
87348
- const psOut = execFileSync5("powershell.exe", [
87652
+ const psOut = execFileSync6("powershell.exe", [
87349
87653
  "-NoProfile",
87350
87654
  "-NonInteractive",
87351
87655
  "-ExecutionPolicy",
@@ -87358,8 +87662,8 @@ function isAdhdevProcess(pid) {
87358
87662
  return true;
87359
87663
  }
87360
87664
  } else {
87361
- const { execFileSync: execFileSync5 } = require("child_process");
87362
- const cmdline = execFileSync5("ps", ["-o", "command=", "-p", String(pid)], {
87665
+ const { execFileSync: execFileSync6 } = require("child_process");
87666
+ const cmdline = execFileSync6("ps", ["-o", "command=", "-p", String(pid)], {
87363
87667
  encoding: "utf-8",
87364
87668
  timeout: 2e3,
87365
87669
  stdio: ["ignore", "pipe", "ignore"]
@@ -87373,7 +87677,7 @@ function isAdhdevProcess(pid) {
87373
87677
  function getDaemonHealthPid(ref = {}) {
87374
87678
  const port = resolveDaemonPort(ref);
87375
87679
  try {
87376
- const { execFileSync: execFileSync5 } = require("child_process");
87680
+ const { execFileSync: execFileSync6 } = require("child_process");
87377
87681
  const probe = `
87378
87682
  const http = require('http');
87379
87683
  const req = http.get('http://127.0.0.1:${port}/health', { timeout: 1500 }, (res) => {
@@ -87391,7 +87695,7 @@ function getDaemonHealthPid(ref = {}) {
87391
87695
  req.on('error', () => {});
87392
87696
  req.on('timeout', () => { req.destroy(); });
87393
87697
  `;
87394
- const result = execFileSync5(process.execPath, ["-e", probe], {
87698
+ const result = execFileSync6(process.execPath, ["-e", probe], {
87395
87699
  encoding: "utf-8",
87396
87700
  timeout: 3e3,
87397
87701
  stdio: ["ignore", "pipe", "ignore"]
@@ -87458,7 +87762,7 @@ var init_adhdev_daemon = __esm({
87458
87762
  init_version();
87459
87763
  init_src();
87460
87764
  init_runtime_defaults();
87461
- pkgVersion = resolvePackageVersion({ injectedVersion: "0.9.28" });
87765
+ pkgVersion = resolvePackageVersion({ injectedVersion: "0.9.29" });
87462
87766
  AdhdevDaemon = class _AdhdevDaemon {
87463
87767
  localHttpServer = null;
87464
87768
  localWss = null;
@@ -88257,12 +88561,13 @@ ${err?.stack || ""}`);
88257
88561
  return { success: false, error: "CLI session runtime unavailable", code: "CLI_RUNTIME_UNAVAILABLE", interactionId };
88258
88562
  }
88259
88563
  if (!this.sessionHostEndpoint) return { success: false, error: "Session host unavailable", interactionId };
88564
+ const sinceSeq = typeof normalizedData.sinceSeq === "number" ? normalizedData.sinceSeq : void 0;
88260
88565
  const client = new SessionHostClient({ endpoint: this.sessionHostEndpoint });
88261
88566
  try {
88262
88567
  await client.connect();
88263
88568
  const snapshot = await client.request({
88264
88569
  type: "get_snapshot",
88265
- payload: { sessionId }
88570
+ payload: { sessionId, sinceSeq }
88266
88571
  });
88267
88572
  if (!snapshot.success || !snapshot.result) {
88268
88573
  return { success: false, error: snapshot.error || "Runtime snapshot unavailable", interactionId };
@@ -88597,9 +88902,9 @@ async function runWizard(options = {}) {
88597
88902
  }
88598
88903
  async function checkForUpdate() {
88599
88904
  try {
88600
- const { execFileSync: execFileSync5 } = await import("child_process");
88905
+ const { execFileSync: execFileSync6 } = await import("child_process");
88601
88906
  const currentVersion = resolvePackageVersion();
88602
- const latestVersion = readLatestPublishedCliVersion(execFileSync5);
88907
+ const latestVersion = readLatestPublishedCliVersion(execFileSync6);
88603
88908
  if (!latestVersion) return;
88604
88909
  if (!currentVersion || !latestVersion || currentVersion === latestVersion) return;
88605
88910
  console.log(source_default.yellow(` Update available: ${currentVersion} \u2192 ${latestVersion}`));
@@ -88616,7 +88921,7 @@ async function checkForUpdate() {
88616
88921
  const spinner = (await Promise.resolve().then(() => (init_ora(), ora_exports))).default("Updating adhdev CLI...").start();
88617
88922
  try {
88618
88923
  const installCommand = buildPinnedGlobalInstallCommand({ packageName: "adhdev", targetVersion: "latest" });
88619
- execFileSync5(installCommand.command, installCommand.args, {
88924
+ execFileSync6(installCommand.command, installCommand.args, {
88620
88925
  encoding: "utf-8",
88621
88926
  timeout: 6e4,
88622
88927
  stdio: ["pipe", "pipe", "pipe"]
@@ -91911,7 +92216,7 @@ function registerDaemonCommands(program2, pkgVersion3) {
91911
92216
 
91912
92217
  // src/cli/doctor-commands.ts
91913
92218
  init_source();
91914
- var import_child_process13 = require("child_process");
92219
+ var import_child_process14 = require("child_process");
91915
92220
  var fs26 = __toESM(require("fs"));
91916
92221
  var os30 = __toESM(require("os"));
91917
92222
  var path33 = __toESM(require("path"));
@@ -92553,7 +92858,7 @@ function findCommandPaths(command) {
92553
92858
  try {
92554
92859
  const bin = process.platform === "win32" ? "where.exe" : "which";
92555
92860
  const args = process.platform === "win32" ? [command] : ["-a", command];
92556
- const output = (0, import_child_process13.execFileSync)(bin, args, {
92861
+ const output = (0, import_child_process14.execFileSync)(bin, args, {
92557
92862
  encoding: "utf-8",
92558
92863
  stdio: ["ignore", "pipe", "ignore"]
92559
92864
  });
@@ -92568,7 +92873,7 @@ function probeCliBinary(commandPath, currentVersion) {
92568
92873
  currentVersion
92569
92874
  };
92570
92875
  try {
92571
- probe.version = (0, import_child_process13.execFileSync)(commandPath, ["--version"], {
92876
+ probe.version = (0, import_child_process14.execFileSync)(commandPath, ["--version"], {
92572
92877
  encoding: "utf-8",
92573
92878
  stdio: ["ignore", "pipe", "pipe"]
92574
92879
  }).trim();
@@ -92576,7 +92881,7 @@ function probeCliBinary(commandPath, currentVersion) {
92576
92881
  probe.versionError = error48?.stderr?.toString?.().trim() || error48?.message || "version probe failed";
92577
92882
  }
92578
92883
  try {
92579
- probe.helpText = (0, import_child_process13.execFileSync)(commandPath, ["--help"], {
92884
+ probe.helpText = (0, import_child_process14.execFileSync)(commandPath, ["--help"], {
92580
92885
  encoding: "utf-8",
92581
92886
  stdio: ["ignore", "pipe", "pipe"]
92582
92887
  });