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/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"));
@@ -37090,7 +37362,7 @@ function getNpmExecOptions() {
37090
37362
  function killPid(pid) {
37091
37363
  try {
37092
37364
  if (process.platform === "win32") {
37093
- (0, import_child_process7.execFileSync)("taskkill", ["/PID", String(pid), "/T", "/F"], { stdio: "ignore" });
37365
+ (0, import_child_process8.execFileSync)("taskkill", ["/PID", String(pid), "/T", "/F"], { stdio: "ignore" });
37094
37366
  } else {
37095
37367
  process.kill(pid, "SIGTERM");
37096
37368
  }
@@ -37128,7 +37400,7 @@ function stopSessionHostProcesses(appName) {
37128
37400
  }
37129
37401
  if (process.platform !== "win32") {
37130
37402
  try {
37131
- const raw = (0, import_child_process7.execFileSync)("pgrep", ["-f", "session-host-daemon"], { encoding: "utf8" }).trim();
37403
+ const raw = (0, import_child_process8.execFileSync)("pgrep", ["-f", "session-host-daemon"], { encoding: "utf8" }).trim();
37132
37404
  for (const line of raw.split("\n")) {
37133
37405
  const pid = Number.parseInt(line.trim(), 10);
37134
37406
  if (Number.isFinite(pid)) {
@@ -37149,9 +37421,9 @@ function removeDaemonPidFile() {
37149
37421
  function cleanupStaleGlobalInstallDirs(pkgName, surface) {
37150
37422
  const npmExecOpts = getNpmExecOptions();
37151
37423
  const prefixArgs = surface.installPrefix ? ["--prefix", surface.installPrefix] : [];
37152
- const npmRoot = (0, import_child_process7.execFileSync)(surface.npmExecutable, ["root", "-g", ...prefixArgs], { encoding: "utf8", ...npmExecOpts }).trim();
37424
+ const npmRoot = (0, import_child_process8.execFileSync)(surface.npmExecutable, ["root", "-g", ...prefixArgs], { encoding: "utf8", ...npmExecOpts }).trim();
37153
37425
  if (!npmRoot) return;
37154
- const npmPrefix = surface.installPrefix || (0, import_child_process7.execFileSync)(surface.npmExecutable, ["prefix", "-g", ...prefixArgs], { encoding: "utf8", ...npmExecOpts }).trim();
37426
+ const npmPrefix = surface.installPrefix || (0, import_child_process8.execFileSync)(surface.npmExecutable, ["prefix", "-g", ...prefixArgs], { encoding: "utf8", ...npmExecOpts }).trim();
37155
37427
  const binDir = process.platform === "win32" ? npmPrefix : path16.join(npmPrefix, "bin");
37156
37428
  const packageBaseName = pkgName.startsWith("@") ? pkgName.split("/")[1] : pkgName;
37157
37429
  const binNames = /* @__PURE__ */ new Set([packageBaseName]);
@@ -37184,7 +37456,7 @@ function cleanupStaleGlobalInstallDirs(pkgName, surface) {
37184
37456
  }
37185
37457
  function spawnDetachedDaemonUpgradeHelper(payload) {
37186
37458
  const env3 = { ...process.env, [UPGRADE_HELPER_ENV]: JSON.stringify(payload) };
37187
- const child = (0, import_child_process8.spawn)(process.execPath, process.argv.slice(1), {
37459
+ const child = (0, import_child_process9.spawn)(process.execPath, process.argv.slice(1), {
37188
37460
  detached: true,
37189
37461
  stdio: "ignore",
37190
37462
  windowsHide: true,
@@ -37214,7 +37486,7 @@ async function runDaemonUpgradeHelper(payload) {
37214
37486
  cleanupStaleGlobalInstallDirs(payload.packageName, installCommand.surface);
37215
37487
  const spec = `${payload.packageName}@${payload.targetVersion || "latest"}`;
37216
37488
  appendUpgradeLog(`Installing ${spec}`);
37217
- const installOutput = (0, import_child_process7.execFileSync)(
37489
+ const installOutput = (0, import_child_process8.execFileSync)(
37218
37490
  installCommand.command,
37219
37491
  installCommand.args,
37220
37492
  {
@@ -37236,7 +37508,7 @@ async function runDaemonUpgradeHelper(payload) {
37236
37508
  const env3 = { ...process.env };
37237
37509
  delete env3[UPGRADE_HELPER_ENV];
37238
37510
  appendUpgradeLog(`Restarting daemon with args: ${restartArgv.join(" ")}`);
37239
- const child = (0, import_child_process8.spawn)(process.execPath, restartArgv, {
37511
+ const child = (0, import_child_process9.spawn)(process.execPath, restartArgv, {
37240
37512
  detached: true,
37241
37513
  stdio: "ignore",
37242
37514
  windowsHide: true,
@@ -37261,12 +37533,12 @@ async function maybeRunDaemonUpgradeHelperFromEnv() {
37261
37533
  process.exit(1);
37262
37534
  }
37263
37535
  }
37264
- var import_child_process7, import_child_process8, fs8, os19, path16, UPGRADE_HELPER_ENV;
37536
+ var import_child_process8, import_child_process9, fs8, os19, path16, UPGRADE_HELPER_ENV;
37265
37537
  var init_upgrade_helper = __esm({
37266
37538
  "../../oss/packages/daemon-core/src/commands/upgrade-helper.ts"() {
37267
37539
  "use strict";
37268
- import_child_process7 = require("child_process");
37269
37540
  import_child_process8 = require("child_process");
37541
+ import_child_process9 = require("child_process");
37270
37542
  fs8 = __toESM(require("fs"));
37271
37543
  os19 = __toESM(require("os"));
37272
37544
  path16 = __toESM(require("path"));
@@ -37371,6 +37643,7 @@ var init_router = __esm({
37371
37643
  init_saved_sessions();
37372
37644
  init_chat_history();
37373
37645
  init_ide_detector();
37646
+ init_cli_detector();
37374
37647
  init_logger();
37375
37648
  init_command_log();
37376
37649
  init_logger();
@@ -37807,6 +38080,33 @@ var init_router = __esm({
37807
38080
  }
37808
38081
  return { ...result };
37809
38082
  }
38083
+ // ─── Detect providers ───
38084
+ case "detect_provider": {
38085
+ const providerType = typeof args?.providerType === "string" ? args.providerType.trim() : "";
38086
+ if (!providerType) return { success: false, error: "providerType is required" };
38087
+ const normalizedType = this.deps.providerLoader.resolveAlias(providerType);
38088
+ const provider = this.deps.providerLoader.getByAlias(providerType);
38089
+ if (!provider) return { success: false, error: `Provider not found: ${providerType}` };
38090
+ if (provider.category !== "cli" && provider.category !== "acp") {
38091
+ return { success: false, error: `Provider detection is only supported for CLI/ACP providers: ${providerType}` };
38092
+ }
38093
+ if (!this.deps.providerLoader.isMachineProviderEnabled(normalizedType)) {
38094
+ return { success: false, error: `Provider is disabled on this machine: ${providerType}` };
38095
+ }
38096
+ const detected = await detectCLI(normalizedType, this.deps.providerLoader, { includeVersion: false });
38097
+ this.deps.providerLoader.setCliDetectionResults([{
38098
+ id: normalizedType,
38099
+ installed: !!detected,
38100
+ path: detected?.path
38101
+ }], false);
38102
+ this.deps.onStatusChange?.();
38103
+ return {
38104
+ success: true,
38105
+ providerType: normalizedType,
38106
+ detected: !!detected,
38107
+ path: detected?.path || null
38108
+ };
38109
+ }
37810
38110
  // ─── Detect IDEs ───
37811
38111
  case "detect_ides": {
37812
38112
  const results = await detectIDEs(this.deps.providerLoader);
@@ -37852,13 +38152,16 @@ var init_router = __esm({
37852
38152
  this.deps.cdpManagers
37853
38153
  );
37854
38154
  const targetSession = sessionEntries.find((entry) => entry.id === sessionId);
37855
- const completionMarker = targetSession ? getSessionCompletionMarker(targetSession) : "";
38155
+ const requestedCompletionMarker = typeof args?.completionMarker === "string" ? args.completionMarker.trim() : "";
38156
+ const completionMarker = requestedCompletionMarker || (targetSession ? getSessionCompletionMarker(targetSession) : "");
38157
+ const requestedProviderSessionId = typeof args?.providerSessionId === "string" ? args.providerSessionId.trim() : "";
38158
+ const providerSessionId = requestedProviderSessionId || targetSession?.providerSessionId;
37856
38159
  const next = markSessionSeen(
37857
38160
  currentState,
37858
38161
  sessionId,
37859
38162
  typeof args?.seenAt === "number" ? args.seenAt : Date.now(),
37860
38163
  completionMarker,
37861
- targetSession?.providerSessionId
38164
+ providerSessionId
37862
38165
  );
37863
38166
  if (READ_DEBUG_ENABLED2) {
37864
38167
  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 +39954,7 @@ var init_provider_instance_manager = __esm({
39651
39954
  // ../../oss/packages/daemon-core/src/providers/version-archive.ts
39652
39955
  function runCommand(cmd, timeout = 1e4) {
39653
39956
  try {
39654
- return (0, import_child_process9.execSync)(cmd, {
39957
+ return (0, import_child_process10.execSync)(cmd, {
39655
39958
  encoding: "utf-8",
39656
39959
  timeout,
39657
39960
  stdio: ["pipe", "pipe", "pipe"]
@@ -39773,14 +40076,14 @@ async function detectAllVersions(loader, archive) {
39773
40076
  }
39774
40077
  return results;
39775
40078
  }
39776
- var fs10, path17, os20, import_child_process9, import_os3, ARCHIVE_PATH, MAX_ENTRIES_PER_PROVIDER, VersionArchive;
40079
+ var fs10, path17, os20, import_child_process10, import_os3, ARCHIVE_PATH, MAX_ENTRIES_PER_PROVIDER, VersionArchive;
39777
40080
  var init_version_archive = __esm({
39778
40081
  "../../oss/packages/daemon-core/src/providers/version-archive.ts"() {
39779
40082
  "use strict";
39780
40083
  fs10 = __toESM(require("fs"));
39781
40084
  path17 = __toESM(require("path"));
39782
40085
  os20 = __toESM(require("os"));
39783
- import_child_process9 = require("child_process");
40086
+ import_child_process10 = require("child_process");
39784
40087
  import_os3 = require("os");
39785
40088
  ARCHIVE_PATH = path17.join(os20.homedir(), ".adhdev", "version-history.json");
39786
40089
  MAX_ENTRIES_PER_PROVIDER = 20;
@@ -45560,7 +45863,7 @@ var init_startup_restore_policy = __esm({
45560
45863
  function isExtensionInstalled(ide, marketplaceId) {
45561
45864
  if (!ide.cliCommand) return false;
45562
45865
  try {
45563
- const result = (0, import_child_process10.execSync)(`"${ide.cliCommand}" --list-extensions`, {
45866
+ const result = (0, import_child_process11.execSync)(`"${ide.cliCommand}" --list-extensions`, {
45564
45867
  encoding: "utf-8",
45565
45868
  timeout: 15e3,
45566
45869
  stdio: ["pipe", "pipe", "pipe"]
@@ -45601,7 +45904,7 @@ async function installExtension(ide, extension) {
45601
45904
  fs24.writeFileSync(vsixPath, buffer);
45602
45905
  return new Promise((resolve16) => {
45603
45906
  const cmd = `"${ide.cliCommand}" --install-extension "${vsixPath}" --force`;
45604
- (0, import_child_process10.exec)(cmd, { timeout: 6e4 }, (error48, _stdout, stderr) => {
45907
+ (0, import_child_process11.exec)(cmd, { timeout: 6e4 }, (error48, _stdout, stderr) => {
45605
45908
  resolve16({
45606
45909
  extensionId: extension.id,
45607
45910
  marketplaceId: extension.marketplaceId,
@@ -45617,7 +45920,7 @@ async function installExtension(ide, extension) {
45617
45920
  }
45618
45921
  return new Promise((resolve16) => {
45619
45922
  const cmd = `"${ide.cliCommand}" --install-extension ${extension.marketplaceId} --force`;
45620
- (0, import_child_process10.exec)(cmd, { timeout: 6e4 }, (error48, stdout, stderr) => {
45923
+ (0, import_child_process11.exec)(cmd, { timeout: 6e4 }, (error48, stdout, stderr) => {
45621
45924
  if (error48) {
45622
45925
  resolve16({
45623
45926
  extensionId: extension.id,
@@ -45654,17 +45957,17 @@ function launchIDE(ide, workspacePath) {
45654
45957
  if (!ide.cliCommand) return false;
45655
45958
  try {
45656
45959
  const args = workspacePath ? `"${workspacePath}"` : "";
45657
- (0, import_child_process10.exec)(`"${ide.cliCommand}" ${args}`, { timeout: 1e4 });
45960
+ (0, import_child_process11.exec)(`"${ide.cliCommand}" ${args}`, { timeout: 1e4 });
45658
45961
  return true;
45659
45962
  } catch {
45660
45963
  return false;
45661
45964
  }
45662
45965
  }
45663
- var import_child_process10, EXTENSION_CATALOG;
45966
+ var import_child_process11, EXTENSION_CATALOG;
45664
45967
  var init_installer = __esm({
45665
45968
  "../../oss/packages/daemon-core/src/installer.ts"() {
45666
45969
  "use strict";
45667
- import_child_process10 = require("child_process");
45970
+ import_child_process11 = require("child_process");
45668
45971
  EXTENSION_CATALOG = [
45669
45972
  // AI Agent extensions
45670
45973
  {
@@ -45867,10 +46170,11 @@ async function initDaemonComponents(config2) {
45867
46170
  if (!providerType || targetCategory === "cli" || targetCategory === "acp") {
45868
46171
  if (providerType && targetProvider) {
45869
46172
  const detected = await detectCLI(targetProvider.type, providerLoader, { includeVersion: false });
45870
- providerLoader.setProviderAvailability(targetProvider.type, {
46173
+ providerLoader.setCliDetectionResults([{
46174
+ id: targetProvider.type,
45871
46175
  installed: !!detected,
45872
- detectedPath: detected?.path || null
45873
- });
46176
+ path: detected?.path
46177
+ }], false);
45874
46178
  } else {
45875
46179
  providerLoader.setCliDetectionResults(await detectCLIs(providerLoader, { includeVersion: false }), true);
45876
46180
  }
@@ -54689,7 +54993,7 @@ function getSessionHostPidFile() {
54689
54993
  function killPid2(pid) {
54690
54994
  try {
54691
54995
  if (process.platform === "win32") {
54692
- (0, import_child_process11.execFileSync)("taskkill", ["/PID", String(pid), "/T", "/F"], { stdio: "ignore", windowsHide: true });
54996
+ (0, import_child_process12.execFileSync)("taskkill", ["/PID", String(pid), "/T", "/F"], { stdio: "ignore", windowsHide: true });
54693
54997
  } else {
54694
54998
  process.kill(pid, "SIGTERM");
54695
54999
  }
@@ -54701,7 +55005,7 @@ function killPid2(pid) {
54701
55005
  function getWindowsProcessCommandLine(pid) {
54702
55006
  const pidFilter = `ProcessId=${pid}`;
54703
55007
  try {
54704
- const psOut = (0, import_child_process11.execFileSync)("powershell.exe", [
55008
+ const psOut = (0, import_child_process12.execFileSync)("powershell.exe", [
54705
55009
  "-NoProfile",
54706
55010
  "-NonInteractive",
54707
55011
  "-ExecutionPolicy",
@@ -54714,7 +55018,7 @@ function getWindowsProcessCommandLine(pid) {
54714
55018
  } catch {
54715
55019
  }
54716
55020
  try {
54717
- const wmicOut = (0, import_child_process11.execFileSync)("wmic", [
55021
+ const wmicOut = (0, import_child_process12.execFileSync)("wmic", [
54718
55022
  "process",
54719
55023
  "where",
54720
55024
  pidFilter,
@@ -54750,7 +55054,7 @@ function stopSessionHost() {
54750
55054
  let stopped = stopManagedSessionHostProcess();
54751
55055
  if (process.platform === "win32") {
54752
55056
  try {
54753
- const raw = (0, import_child_process11.execFileSync)("tasklist", ["/FO", "CSV", "/NH", "/FI", "IMAGENAME eq node.exe"], {
55057
+ const raw = (0, import_child_process12.execFileSync)("tasklist", ["/FO", "CSV", "/NH", "/FI", "IMAGENAME eq node.exe"], {
54754
55058
  encoding: "utf8",
54755
55059
  timeout: 5e3,
54756
55060
  stdio: ["ignore", "pipe", "ignore"],
@@ -54770,7 +55074,7 @@ function stopSessionHost() {
54770
55074
  }
54771
55075
  } else {
54772
55076
  try {
54773
- const raw = (0, import_child_process11.execFileSync)("pgrep", ["-f", "session-host-daemon"], { encoding: "utf8" }).trim();
55077
+ const raw = (0, import_child_process12.execFileSync)("pgrep", ["-f", "session-host-daemon"], { encoding: "utf8" }).trim();
54774
55078
  for (const line of raw.split("\n")) {
54775
55079
  const pid = Number.parseInt(line.trim(), 10);
54776
55080
  if (Number.isFinite(pid) && pid !== process.pid && pid !== process.ppid) {
@@ -54804,7 +55108,7 @@ async function ensureSessionHostReady2() {
54804
55108
  const logDir = path25.join(os24.homedir(), ".adhdev", "logs");
54805
55109
  fs17.mkdirSync(logDir, { recursive: true });
54806
55110
  const logFd = fs17.openSync(path25.join(logDir, "session-host.log"), "a");
54807
- const child = (0, import_child_process11.spawn)(process.execPath, [entry], {
55111
+ const child = (0, import_child_process12.spawn)(process.execPath, [entry], {
54808
55112
  detached: true,
54809
55113
  stdio: ["ignore", logFd, logFd],
54810
55114
  windowsHide: true,
@@ -54838,11 +55142,11 @@ async function ensureSessionHostReady2() {
54838
55142
  async function listHostedCliRuntimes2(endpoint) {
54839
55143
  return listHostedCliRuntimes(endpoint);
54840
55144
  }
54841
- var import_child_process11, fs17, os24, path25, SESSION_HOST_APP_NAME, SESSION_HOST_START_TIMEOUT_MS;
55145
+ var import_child_process12, fs17, os24, path25, SESSION_HOST_APP_NAME, SESSION_HOST_START_TIMEOUT_MS;
54842
55146
  var init_session_host = __esm({
54843
55147
  "src/session-host.ts"() {
54844
55148
  "use strict";
54845
- import_child_process11 = require("child_process");
55149
+ import_child_process12 = require("child_process");
54846
55150
  fs17 = __toESM(require("fs"));
54847
55151
  os24 = __toESM(require("os"));
54848
55152
  path25 = __toESM(require("path"));
@@ -55537,18 +55841,18 @@ function resolvePackageVersion(options) {
55537
55841
  ];
55538
55842
  for (const p of possiblePaths) {
55539
55843
  try {
55540
- const data = JSON.parse((0, import_fs5.readFileSync)(p, "utf-8"));
55844
+ const data = JSON.parse((0, import_fs6.readFileSync)(p, "utf-8"));
55541
55845
  if (data.version) return data.version;
55542
55846
  } catch {
55543
55847
  }
55544
55848
  }
55545
55849
  return injectedVersion;
55546
55850
  }
55547
- var import_fs5, import_path3;
55851
+ var import_fs6, import_path3;
55548
55852
  var init_version = __esm({
55549
55853
  "src/version.ts"() {
55550
55854
  "use strict";
55551
- import_fs5 = require("fs");
55855
+ import_fs6 = require("fs");
55552
55856
  import_path3 = require("path");
55553
55857
  }
55554
55858
  });
@@ -55587,7 +55891,7 @@ function removeDaemonPid(ref = {}) {
55587
55891
  function isDaemonRunning(ref = {}) {
55588
55892
  const port = resolveDaemonPort(ref);
55589
55893
  try {
55590
- const { execFileSync: execFileSync4 } = require("child_process");
55894
+ const { execFileSync: execFileSync5 } = require("child_process");
55591
55895
  const probe = `
55592
55896
  const http = require('http');
55593
55897
  const req = http.get('http://127.0.0.1:${port}/health', { timeout: 1500 }, (res) => {
@@ -55597,7 +55901,7 @@ function isDaemonRunning(ref = {}) {
55597
55901
  req.on('error', () => process.stdout.write('0'));
55598
55902
  req.on('timeout', () => { req.destroy(); process.stdout.write('0'); });
55599
55903
  `;
55600
- const result = execFileSync4(process.execPath, ["-e", probe], {
55904
+ const result = execFileSync5(process.execPath, ["-e", probe], {
55601
55905
  encoding: "utf-8",
55602
55906
  timeout: 3e3,
55603
55907
  stdio: ["ignore", "pipe", "ignore"]
@@ -55623,9 +55927,9 @@ function isDaemonRunning(ref = {}) {
55623
55927
  function isAdhdevProcess(pid) {
55624
55928
  try {
55625
55929
  if (process.platform === "win32") {
55626
- const { execFileSync: execFileSync4 } = require("child_process");
55930
+ const { execFileSync: execFileSync5 } = require("child_process");
55627
55931
  try {
55628
- const psOut = execFileSync4("powershell.exe", [
55932
+ const psOut = execFileSync5("powershell.exe", [
55629
55933
  "-NoProfile",
55630
55934
  "-NonInteractive",
55631
55935
  "-ExecutionPolicy",
@@ -55638,8 +55942,8 @@ function isAdhdevProcess(pid) {
55638
55942
  return true;
55639
55943
  }
55640
55944
  } else {
55641
- const { execFileSync: execFileSync4 } = require("child_process");
55642
- const cmdline = execFileSync4("ps", ["-o", "command=", "-p", String(pid)], {
55945
+ const { execFileSync: execFileSync5 } = require("child_process");
55946
+ const cmdline = execFileSync5("ps", ["-o", "command=", "-p", String(pid)], {
55643
55947
  encoding: "utf-8",
55644
55948
  timeout: 2e3,
55645
55949
  stdio: ["ignore", "pipe", "ignore"]
@@ -55653,7 +55957,7 @@ function isAdhdevProcess(pid) {
55653
55957
  function getDaemonHealthPid(ref = {}) {
55654
55958
  const port = resolveDaemonPort(ref);
55655
55959
  try {
55656
- const { execFileSync: execFileSync4 } = require("child_process");
55960
+ const { execFileSync: execFileSync5 } = require("child_process");
55657
55961
  const probe = `
55658
55962
  const http = require('http');
55659
55963
  const req = http.get('http://127.0.0.1:${port}/health', { timeout: 1500 }, (res) => {
@@ -55671,7 +55975,7 @@ function getDaemonHealthPid(ref = {}) {
55671
55975
  req.on('error', () => {});
55672
55976
  req.on('timeout', () => { req.destroy(); });
55673
55977
  `;
55674
- const result = execFileSync4(process.execPath, ["-e", probe], {
55978
+ const result = execFileSync5(process.execPath, ["-e", probe], {
55675
55979
  encoding: "utf-8",
55676
55980
  timeout: 3e3,
55677
55981
  stdio: ["ignore", "pipe", "ignore"]
@@ -55738,7 +56042,7 @@ var init_adhdev_daemon = __esm({
55738
56042
  init_version();
55739
56043
  init_src();
55740
56044
  init_runtime_defaults();
55741
- pkgVersion = resolvePackageVersion({ injectedVersion: "0.9.28" });
56045
+ pkgVersion = resolvePackageVersion({ injectedVersion: "0.9.29" });
55742
56046
  AdhdevDaemon = class _AdhdevDaemon {
55743
56047
  localHttpServer = null;
55744
56048
  localWss = null;
@@ -56537,12 +56841,13 @@ ${err?.stack || ""}`);
56537
56841
  return { success: false, error: "CLI session runtime unavailable", code: "CLI_RUNTIME_UNAVAILABLE", interactionId };
56538
56842
  }
56539
56843
  if (!this.sessionHostEndpoint) return { success: false, error: "Session host unavailable", interactionId };
56844
+ const sinceSeq = typeof normalizedData.sinceSeq === "number" ? normalizedData.sinceSeq : void 0;
56540
56845
  const client = new SessionHostClient({ endpoint: this.sessionHostEndpoint });
56541
56846
  try {
56542
56847
  await client.connect();
56543
56848
  const snapshot = await client.request({
56544
56849
  type: "get_snapshot",
56545
- payload: { sessionId }
56850
+ payload: { sessionId, sinceSeq }
56546
56851
  });
56547
56852
  if (!snapshot.success || !snapshot.result) {
56548
56853
  return { success: false, error: snapshot.error || "Runtime snapshot unavailable", interactionId };
@@ -71473,7 +71778,7 @@ var require_buffer_list = __commonJS({
71473
71778
  }
71474
71779
  }, {
71475
71780
  key: "join",
71476
- value: function join29(s) {
71781
+ value: function join30(s) {
71477
71782
  if (this.length === 0) return "";
71478
71783
  var p = this.head;
71479
71784
  var ret = "" + p.data;
@@ -85532,13 +85837,13 @@ function splitStringBySpace(str) {
85532
85837
  }
85533
85838
  return pieces;
85534
85839
  }
85535
- var import_chardet, import_child_process12, import_fs6, import_node_path2, import_node_os4, import_node_crypto, import_iconv_lite, ExternalEditor;
85840
+ var import_chardet, import_child_process13, import_fs7, import_node_path2, import_node_os4, import_node_crypto, import_iconv_lite, ExternalEditor;
85536
85841
  var init_esm2 = __esm({
85537
85842
  "../../node_modules/@inquirer/external-editor/dist/esm/index.js"() {
85538
85843
  "use strict";
85539
85844
  import_chardet = __toESM(require_lib2(), 1);
85540
- import_child_process12 = require("child_process");
85541
- import_fs6 = require("fs");
85845
+ import_child_process13 = require("child_process");
85846
+ import_fs7 = require("fs");
85542
85847
  import_node_path2 = __toESM(require("path"), 1);
85543
85848
  import_node_os4 = __toESM(require("os"), 1);
85544
85849
  import_node_crypto = require("crypto");
@@ -85614,14 +85919,14 @@ var init_esm2 = __esm({
85614
85919
  if (Object.prototype.hasOwnProperty.call(this.fileOptions, "mode")) {
85615
85920
  opt.mode = this.fileOptions.mode;
85616
85921
  }
85617
- (0, import_fs6.writeFileSync)(this.tempFile, this.text, opt);
85922
+ (0, import_fs7.writeFileSync)(this.tempFile, this.text, opt);
85618
85923
  } catch (createFileError) {
85619
85924
  throw new CreateFileError(createFileError);
85620
85925
  }
85621
85926
  }
85622
85927
  readTemporaryFile() {
85623
85928
  try {
85624
- const tempFileBuffer = (0, import_fs6.readFileSync)(this.tempFile);
85929
+ const tempFileBuffer = (0, import_fs7.readFileSync)(this.tempFile);
85625
85930
  if (tempFileBuffer.length === 0) {
85626
85931
  this.text = "";
85627
85932
  } else {
@@ -85637,14 +85942,14 @@ var init_esm2 = __esm({
85637
85942
  }
85638
85943
  removeTemporaryFile() {
85639
85944
  try {
85640
- (0, import_fs6.unlinkSync)(this.tempFile);
85945
+ (0, import_fs7.unlinkSync)(this.tempFile);
85641
85946
  } catch (removeFileError) {
85642
85947
  throw new RemoveFileError(removeFileError);
85643
85948
  }
85644
85949
  }
85645
85950
  launchEditor() {
85646
85951
  try {
85647
- const editorProcess = (0, import_child_process12.spawnSync)(this.editor.bin, this.editor.args.concat([this.tempFile]), { stdio: "inherit" });
85952
+ const editorProcess = (0, import_child_process13.spawnSync)(this.editor.bin, this.editor.args.concat([this.tempFile]), { stdio: "inherit" });
85648
85953
  this.lastExitStatus = editorProcess.status ?? 0;
85649
85954
  } catch (launchError) {
85650
85955
  throw new LaunchEditorError(launchError);
@@ -85652,7 +85957,7 @@ var init_esm2 = __esm({
85652
85957
  }
85653
85958
  launchEditorAsync(callback) {
85654
85959
  try {
85655
- const editorProcess = (0, import_child_process12.spawn)(this.editor.bin, this.editor.args.concat([this.tempFile]), { stdio: "inherit" });
85960
+ const editorProcess = (0, import_child_process13.spawn)(this.editor.bin, this.editor.args.concat([this.tempFile]), { stdio: "inherit" });
85656
85961
  editorProcess.on("exit", (code) => {
85657
85962
  this.lastExitStatus = code;
85658
85963
  setImmediate(callback);
@@ -87930,9 +88235,9 @@ async function runWizard(options = {}) {
87930
88235
  }
87931
88236
  async function checkForUpdate() {
87932
88237
  try {
87933
- const { execFileSync: execFileSync4 } = await import("child_process");
88238
+ const { execFileSync: execFileSync5 } = await import("child_process");
87934
88239
  const currentVersion = resolvePackageVersion();
87935
- const latestVersion = readLatestPublishedCliVersion(execFileSync4);
88240
+ const latestVersion = readLatestPublishedCliVersion(execFileSync5);
87936
88241
  if (!latestVersion) return;
87937
88242
  if (!currentVersion || !latestVersion || currentVersion === latestVersion) return;
87938
88243
  console.log(source_default2.yellow(` Update available: ${currentVersion} \u2192 ${latestVersion}`));
@@ -87949,7 +88254,7 @@ async function checkForUpdate() {
87949
88254
  const spinner = (await Promise.resolve().then(() => (init_ora(), ora_exports))).default("Updating adhdev CLI...").start();
87950
88255
  try {
87951
88256
  const installCommand = buildPinnedGlobalInstallCommand({ packageName: "adhdev", targetVersion: "latest" });
87952
- execFileSync4(installCommand.command, installCommand.args, {
88257
+ execFileSync5(installCommand.command, installCommand.args, {
87953
88258
  encoding: "utf-8",
87954
88259
  timeout: 6e4,
87955
88260
  stdio: ["pipe", "pipe", "pipe"]