@pwrdrvr/agent-acp 0.13.1 → 0.14.0

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.d.ts CHANGED
@@ -700,6 +700,15 @@ type DiscoveredAcpAgentInstance = {
700
700
  /** Where this candidate came from (user override, `PATH`, or a fallback path). */
701
701
  source: AcpAgentInstanceSource;
702
702
  };
703
+ /** A detected executable that did not satisfy a strategy's discovery probe.
704
+ * It is diagnostic-only: hosts must never use it to launch an ACP session. */
705
+ type RejectedAcpAgentInstance = {
706
+ command: string;
707
+ /** Parsed from successful `--version` output when available. */
708
+ version?: string;
709
+ source: AcpAgentInstanceSource;
710
+ reason: "version-probe-failed" | "acp-probe-failed" | "acp-help-mismatch";
711
+ };
703
712
  /** Every installed instance of one agent found on this machine. */
704
713
  type DiscoveredAcpAgentGroup = {
705
714
  strategyId: string;
@@ -711,6 +720,9 @@ type DiscoveredAcpAgentGroup = {
711
720
  env: Record<string, string>;
712
721
  /** All instances that passed the probe, in candidate order (override → PATH → fallback). */
713
722
  instances: DiscoveredAcpAgentInstance[];
723
+ /** Detected candidates that failed the version or ACP-capability probe. Only
724
+ * populated when `includeRejectedCandidates` is enabled. */
725
+ rejectedInstances?: RejectedAcpAgentInstance[];
714
726
  discoveredAt: number;
715
727
  };
716
728
  type DiscoveredAcpAgent = {
@@ -740,11 +752,15 @@ type LocalAcpDiscoveryOptions = {
740
752
  env?: NodeJS.ProcessEnv;
741
753
  /** Injectable `PATH` executable lister (real-fs scan by default). */
742
754
  listExecutables?: AcpPathExecutableLister;
755
+ /** Include candidates known to exist but rejected by a discovery probe.
756
+ * Defaults false to preserve the legacy installed-only result. */
757
+ includeRejectedCandidates?: boolean;
743
758
  };
744
759
  /**
745
760
  * Discover every installed instance of each agent (all `PATH` matches +
746
761
  * fallbacks + override that pass the probe), grouped per strategy. Groups with
747
- * no passing instance are omitted.
762
+ * no passing instance are omitted unless `includeRejectedCandidates` is true
763
+ * and a detected candidate failed a probe.
748
764
  */
749
765
  declare function discoverLocalAcpAgentInstances(options?: LocalAcpDiscoveryOptions): Promise<DiscoveredAcpAgentGroup[]>;
750
766
  /**
@@ -874,4 +890,4 @@ declare class AcpRegistryService {
874
890
  declare function evaluateAcpDistributionPolicy(distribution: AcpRegistryDistribution, allowlist: AcpAllowlistDecision): AcpDistributionPolicy;
875
891
  declare function normalizeRegistry(raw: unknown): AcpRegistryAgent[];
876
892
 
877
- export { ACP_REGISTRY_URL, AcpAgentAllowlist, type AcpAgentAllowlistRule, AcpAgentClient, type AcpAgentClientFactory, type AcpAgentClientOptions, AcpAgentClientPool, type AcpAgentClientPoolOptions, type AcpAgentConnection, type AcpAgentConnectionHandle, type AcpAgentInstanceSource, type AcpAgentQuirks, type AcpAgentStrategy, type AcpAllowlistDecision, type AcpApplyContext, type AcpBinaryPlatformDistribution, AcpConnection, type AcpConnectionOptions, type AcpDiscoveryProbe, type AcpDistributionKind, type AcpDistributionPolicy, type AcpHttpMcpServerConfig, type AcpJsonRpcTransport, type AcpLoadThreadOptions, type AcpMcpKeyValue, type AcpMcpKeyValueCollection, type AcpMcpServerConfig, type AcpMcpServerWireConfig, type AcpNormalizeResult, type AcpNormalizerOptions, AcpOneShotClient, type AcpOneShotClientOptions, type AcpOneShotRequest, type AcpOneShotResponse, type AcpPackageDistribution, type AcpPathExecutableLister, type AcpPromptContentBlock, type AcpRegistryAgent, type AcpRegistryAgentWithPolicy, type AcpRegistryAuthDescriptor, type AcpRegistryAuthMethod, type AcpRegistryDistribution, type AcpRegistryFetch, AcpRegistryService, type AcpRegistryServiceOptions, type AcpRegistrySnapshot, type AcpRuntimeAgentCapabilities, type AcpRuntimeAgentInfo, type AcpRuntimeCapabilities, type AcpRuntimeCapabilitiesHandler, type AcpRuntimeCapabilitiesSource, type AcpRuntimeConfigOption, type AcpRuntimeConfigOptionValue, type AcpRuntimeMcpCapabilities, type AcpRuntimeMode, type AcpRuntimeModel, type AcpRuntimeModels, type AcpRuntimeModes, type AcpRuntimeOptionSource, AcpSessionNormalizer, type AcpSessionRuntimeState, type AcpSpawnSpec, type AcpSseMcpServerConfig, type AcpStartThreadOptions, type AcpStartTurnOptions, type AcpStdioMcpServerConfig, type AcpTitleHandler, type AcpVerificationStatus, BANNED_ACP_REGISTRY_IDS, BUILT_IN_ACP_STRATEGIES, DEFAULT_ACP_AGENT_ALLOWLIST, type DiscoveredAcpAgent, type DiscoveredAcpAgentGroup, type DiscoveredAcpAgentInstance, type LocalAcpAgentProbe, type LocalAcpDiscoveryOptions, type LocalAcpProbeResult, acpRuntimeSupportsHttpMcp, acpRuntimeSupportsSessionLoad, acpRuntimeSupportsSseMcp, acpSessionRuntimeStateFromCapabilities, acpSessionRuntimeStateFromUpdate, asRecord, buildAcpBackendId, buildStrategyTable, defaultAcpAgentAllowlist, defaultQuirks, discoverLocalAcpAgentInstances, discoverLocalAcpAgents, evaluateAcpDistributionPolicy, geminiStrategy, grokStrategy, isBannedAcpRegistryId, kimiStrategy, mergeAcpRuntimeState, modeLabelFor, modelConfigOption, modelIdFromCapabilities, modelsFromCapabilities, normalizeAcpMcpServerConfig, normalizeAcpMcpServerConfigs, normalizeAcpRuntimeCapabilities, normalizeRegistry, qwenStrategy, readAcpContentText, readBoolean, readContentText, readFirstLocationPath, readFirstString, readKind, readNonEmptyString, readNumber, readPromptText, readString, readToolCallId, readToolContentText, readToolOutput, readUpdateText, reasoningValueForThoughtLevel, strategyByBackendId, strategyById, toolCallFromUpdate, wellKnownAgentBinDirs };
893
+ export { ACP_REGISTRY_URL, AcpAgentAllowlist, type AcpAgentAllowlistRule, AcpAgentClient, type AcpAgentClientFactory, type AcpAgentClientOptions, AcpAgentClientPool, type AcpAgentClientPoolOptions, type AcpAgentConnection, type AcpAgentConnectionHandle, type AcpAgentInstanceSource, type AcpAgentQuirks, type AcpAgentStrategy, type AcpAllowlistDecision, type AcpApplyContext, type AcpBinaryPlatformDistribution, AcpConnection, type AcpConnectionOptions, type AcpDiscoveryProbe, type AcpDistributionKind, type AcpDistributionPolicy, type AcpHttpMcpServerConfig, type AcpJsonRpcTransport, type AcpLoadThreadOptions, type AcpMcpKeyValue, type AcpMcpKeyValueCollection, type AcpMcpServerConfig, type AcpMcpServerWireConfig, type AcpNormalizeResult, type AcpNormalizerOptions, AcpOneShotClient, type AcpOneShotClientOptions, type AcpOneShotRequest, type AcpOneShotResponse, type AcpPackageDistribution, type AcpPathExecutableLister, type AcpPromptContentBlock, type AcpRegistryAgent, type AcpRegistryAgentWithPolicy, type AcpRegistryAuthDescriptor, type AcpRegistryAuthMethod, type AcpRegistryDistribution, type AcpRegistryFetch, AcpRegistryService, type AcpRegistryServiceOptions, type AcpRegistrySnapshot, type AcpRuntimeAgentCapabilities, type AcpRuntimeAgentInfo, type AcpRuntimeCapabilities, type AcpRuntimeCapabilitiesHandler, type AcpRuntimeCapabilitiesSource, type AcpRuntimeConfigOption, type AcpRuntimeConfigOptionValue, type AcpRuntimeMcpCapabilities, type AcpRuntimeMode, type AcpRuntimeModel, type AcpRuntimeModels, type AcpRuntimeModes, type AcpRuntimeOptionSource, AcpSessionNormalizer, type AcpSessionRuntimeState, type AcpSpawnSpec, type AcpSseMcpServerConfig, type AcpStartThreadOptions, type AcpStartTurnOptions, type AcpStdioMcpServerConfig, type AcpTitleHandler, type AcpVerificationStatus, BANNED_ACP_REGISTRY_IDS, BUILT_IN_ACP_STRATEGIES, DEFAULT_ACP_AGENT_ALLOWLIST, type DiscoveredAcpAgent, type DiscoveredAcpAgentGroup, type DiscoveredAcpAgentInstance, type LocalAcpAgentProbe, type LocalAcpDiscoveryOptions, type LocalAcpProbeResult, type RejectedAcpAgentInstance, acpRuntimeSupportsHttpMcp, acpRuntimeSupportsSessionLoad, acpRuntimeSupportsSseMcp, acpSessionRuntimeStateFromCapabilities, acpSessionRuntimeStateFromUpdate, asRecord, buildAcpBackendId, buildStrategyTable, defaultAcpAgentAllowlist, defaultQuirks, discoverLocalAcpAgentInstances, discoverLocalAcpAgents, evaluateAcpDistributionPolicy, geminiStrategy, grokStrategy, isBannedAcpRegistryId, kimiStrategy, mergeAcpRuntimeState, modeLabelFor, modelConfigOption, modelIdFromCapabilities, modelsFromCapabilities, normalizeAcpMcpServerConfig, normalizeAcpMcpServerConfigs, normalizeAcpRuntimeCapabilities, normalizeRegistry, qwenStrategy, readAcpContentText, readBoolean, readContentText, readFirstLocationPath, readFirstString, readKind, readNonEmptyString, readNumber, readPromptText, readString, readToolCallId, readToolContentText, readToolOutput, readUpdateText, reasoningValueForThoughtLevel, strategyByBackendId, strategyById, toolCallFromUpdate, wellKnownAgentBinDirs };
package/dist/index.js CHANGED
@@ -2328,7 +2328,8 @@ async function discoverLocalAcpAgentInstances(options = {}) {
2328
2328
  now,
2329
2329
  env,
2330
2330
  listExecutables,
2331
- options.overrides?.[strategy.id]
2331
+ options.overrides?.[strategy.id],
2332
+ options.includeRejectedCandidates === true
2332
2333
  )
2333
2334
  )
2334
2335
  );
@@ -2352,21 +2353,40 @@ async function discoverLocalAcpAgents(options = {}) {
2352
2353
  return [agent];
2353
2354
  });
2354
2355
  }
2355
- async function discoverStrategyInstances(strategy, probe, now, env, listExecutables, override) {
2356
+ async function discoverStrategyInstances(strategy, probe, now, env, listExecutables, override, includeRejectedCandidates = false) {
2356
2357
  const candidates = candidateCommands(strategy, env, listExecutables, override);
2357
2358
  const instances = [];
2359
+ const rejectedInstances = [];
2358
2360
  for (const candidate of candidates) {
2359
2361
  const [versionResult, helpResult] = await Promise.all([
2360
2362
  runProbe(probe, candidate.command, strategy.discoveryProbe.versionArgs),
2361
2363
  runProbe(probe, candidate.command, strategy.discoveryProbe.helpArgs)
2362
2364
  ]);
2365
+ const version = versionResult ? parseCliVersion(resultText(versionResult)) : void 0;
2363
2366
  if (!versionResult || !helpResult) {
2367
+ if (includeRejectedCandidates && candidate.detected) {
2368
+ const rejected = {
2369
+ command: candidate.command,
2370
+ source: candidate.source,
2371
+ reason: versionResult ? "acp-probe-failed" : "version-probe-failed"
2372
+ };
2373
+ if (version !== void 0) rejected.version = version;
2374
+ rejectedInstances.push(rejected);
2375
+ }
2364
2376
  continue;
2365
2377
  }
2366
2378
  if (strategy.discoveryProbe.helpMatches !== void 0 && !strategy.discoveryProbe.helpMatches.test(resultText(helpResult))) {
2379
+ if (includeRejectedCandidates && candidate.detected) {
2380
+ const rejected = {
2381
+ command: candidate.command,
2382
+ source: candidate.source,
2383
+ reason: "acp-help-mismatch"
2384
+ };
2385
+ if (version !== void 0) rejected.version = version;
2386
+ rejectedInstances.push(rejected);
2387
+ }
2367
2388
  continue;
2368
2389
  }
2369
- const version = parseCliVersion(resultText(versionResult));
2370
2390
  const instance = {
2371
2391
  command: candidate.command,
2372
2392
  source: candidate.source
@@ -2374,7 +2394,7 @@ async function discoverStrategyInstances(strategy, probe, now, env, listExecutab
2374
2394
  if (version !== void 0) instance.version = version;
2375
2395
  instances.push(instance);
2376
2396
  }
2377
- if (instances.length === 0) {
2397
+ if (instances.length === 0 && rejectedInstances.length === 0) {
2378
2398
  return void 0;
2379
2399
  }
2380
2400
  return {
@@ -2384,34 +2404,43 @@ async function discoverStrategyInstances(strategy, probe, now, env, listExecutab
2384
2404
  args: ensureArgs(strategy.spawn.args, strategy.spawn.ensureArgs),
2385
2405
  env: strategy.spawn.env ?? {},
2386
2406
  instances,
2407
+ ...rejectedInstances.length > 0 ? { rejectedInstances } : {},
2387
2408
  discoveredAt: now()
2388
2409
  };
2389
2410
  }
2390
2411
  function candidateCommands(strategy, env, listExecutables, override) {
2391
2412
  const out = [];
2392
2413
  const seen = /* @__PURE__ */ new Set();
2393
- const push = (command, source) => {
2414
+ const push = (command, source, detected) => {
2394
2415
  const trimmed = command.trim();
2395
2416
  if (trimmed.length === 0) return;
2396
2417
  const key = canonicalize(trimmed);
2397
2418
  if (seen.has(key)) return;
2398
2419
  seen.add(key);
2399
- out.push({ command: trimmed, source });
2420
+ out.push({ command: trimmed, source, detected });
2400
2421
  };
2401
2422
  if (override && override.trim().length > 0) {
2402
- push(override, "override");
2423
+ push(override, "override", isExecutableFile(override));
2403
2424
  }
2404
2425
  const pathMatches = listExecutables(strategy.discoveryProbe.command, env);
2405
2426
  if (pathMatches.length > 0) {
2406
- for (const match of pathMatches) push(match, "path");
2427
+ for (const match of pathMatches) push(match, "path", true);
2407
2428
  } else {
2408
- push(strategy.discoveryProbe.command, "path");
2429
+ push(strategy.discoveryProbe.command, "path", false);
2409
2430
  }
2410
2431
  for (const fallback of strategy.discoveryProbe.fallbackCommands ?? []) {
2411
- push(fallback, "fallback");
2432
+ push(fallback, "fallback", isExecutableFile(fallback));
2412
2433
  }
2413
2434
  return out;
2414
2435
  }
2436
+ function isExecutableFile(command) {
2437
+ try {
2438
+ const stat = statSync(command);
2439
+ return stat.isFile() && (process.platform === "win32" || (stat.mode & 73) !== 0);
2440
+ } catch {
2441
+ return false;
2442
+ }
2443
+ }
2415
2444
  function canonicalize(command) {
2416
2445
  if (!path4.isAbsolute(command)) {
2417
2446
  return process.platform === "win32" ? command.toLowerCase() : command;