@pwrdrvr/agent-acp 0.16.0 → 0.17.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/chunk-64RRSPSB.js +51 -0
- package/dist/chunk-64RRSPSB.js.map +1 -0
- package/dist/chunk-GCWY5T5H.js +675 -0
- package/dist/chunk-GCWY5T5H.js.map +1 -0
- package/dist/chunk-OFMIS7W6.js +163 -0
- package/dist/chunk-OFMIS7W6.js.map +1 -0
- package/dist/discovery.d.ts +223 -0
- package/dist/discovery.js +32 -0
- package/dist/discovery.js.map +1 -0
- package/dist/index.d.ts +28 -360
- package/dist/index.js +140 -881
- package/dist/index.js.map +1 -1
- package/dist/mcp-server-config.d.ts +40 -0
- package/dist/mcp-server-config.js +9 -0
- package/dist/mcp-server-config.js.map +1 -0
- package/dist/strategies.d.ts +20 -0
- package/dist/strategies.js +25 -0
- package/dist/strategies.js.map +1 -0
- package/dist/strategy-types-C7yw6yQL.d.ts +82 -0
- package/package.json +14 -2
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/discovery/acp-local-discovery.ts","../src/discovery/acp-agent-allowlist.ts","../src/discovery/acp-registry-types.ts","../src/discovery/acp-registry-service.ts"],"sourcesContent":["// Probe which ACP CLIs are installed locally. STRATEGY-DRIVEN: iterates the\n// strategy table and runs each strategy's `discoveryProbe`. Adding a 5th agent\n// (a new strategy entry) surfaces it through discovery with ZERO changes here.\n//\n// Two granularities:\n// • `discoverLocalAcpAgentInstances` — returns EVERY installed instance of\n// each agent (each executable on `PATH` + the strategy's fallback paths +\n// an optional override that passes the probe), with its parsed version and\n// where it was found. A host UI can list them all and let the user pick.\n// Hosts that opt in can also receive detected candidates rejected by the\n// probe, so they can explain why a known CLI cannot be used.\n// • `discoverLocalAcpAgents` — the original first-match-per-agent view, kept\n// for back-compat. Implemented on top of the instance view.\n//\n// Ported from PwrAgnt acp-local-discovery.ts, generalized so the per-agent probe\n// details live in the strategy, not inline branches.\n\nimport { execFile as execFileCallback } from \"node:child_process\";\nimport { readdirSync, realpathSync, statSync } from \"node:fs\";\nimport { homedir } from \"node:os\";\nimport path from \"node:path\";\nimport { promisify } from \"node:util\";\nimport {\n createCommandInvocation,\n prependCommandDirToPath\n} from \"@pwrdrvr/agent-transport\";\nimport { BUILT_IN_ACP_STRATEGIES } from \"../strategies/index\";\nimport type {\n AcpAgentStrategy,\n AcpAgentStrategy as Strategy,\n LocalAcpAgentProbe,\n LocalAcpProbeOptions,\n LocalAcpProbeResult\n} from \"../strategies/strategy-types\";\n\nconst execFile = promisify(execFileCallback);\n\nexport type {\n LocalAcpAgentProbe,\n LocalAcpProbeOptions,\n LocalAcpProbeResult\n} from \"../strategies/strategy-types\";\n\n/** How a discovered instance's executable path was located. */\nexport type AcpAgentInstanceSource = \"override\" | \"path\" | \"fallback\";\n\n/** One installed executable of an agent that passed the probe. */\nexport type DiscoveredAcpAgentInstance = {\n /** Resolved command/path that passed the probe. */\n command: string;\n /** Parsed CLI version, when the version probe yielded one. */\n version?: string;\n /** Where this candidate came from (user override, `PATH`, or a fallback path). */\n source: AcpAgentInstanceSource;\n};\n\n/** A detected executable that did not satisfy a strategy's discovery probe.\n * It is diagnostic-only: hosts must never use it to launch an ACP session. */\nexport type RejectedAcpAgentInstance = {\n command: string;\n /** Parsed from successful `--version` output when available. */\n version?: string;\n source: AcpAgentInstanceSource;\n /** `probe-timed-out` means the CLI did not answer within the probe budget —\n * UNLIKE the other reasons it is not a verdict on the CLI, and a host may\n * re-probe on a larger `probeTimeoutMs` instead of reporting it unusable. */\n reason:\n | \"version-probe-failed\"\n | \"acp-probe-failed\"\n | \"acp-help-mismatch\"\n | \"probe-timed-out\";\n};\n\n/** Every installed instance of one agent found on this machine. */\nexport type DiscoveredAcpAgentGroup = {\n strategyId: string;\n backendId: string;\n name: string;\n /** Spawn args that put it into ACP stdio mode (same for every instance). */\n args: string[];\n /** Extra env to set at launch (same for every instance). */\n env: Record<string, string>;\n /** All instances that passed the probe, in candidate order (override → PATH → fallback). */\n instances: DiscoveredAcpAgentInstance[];\n /** Detected candidates that failed the version or ACP-capability probe. Only\n * populated when `includeRejectedCandidates` is enabled. */\n rejectedInstances?: RejectedAcpAgentInstance[];\n discoveredAt: number;\n};\n\nexport type DiscoveredAcpAgent = {\n strategyId: string;\n backendId: string;\n name: string;\n version?: string;\n /** Resolved command that passed the probe (may be a fallback path). */\n command: string;\n /** Spawn args that put it into ACP stdio mode. */\n args: string[];\n /** Extra env to set at launch. */\n env: Record<string, string>;\n discoveredAt: number;\n};\n\n/** Lists every executable named `command` across the dirs in `env.PATH`,\n * in `PATH` order (the `which -a` view). */\nexport type AcpPathExecutableLister = (\n command: string,\n env: NodeJS.ProcessEnv\n) => string[];\n\nexport type LocalAcpDiscoveryOptions = {\n probe?: LocalAcpAgentProbe;\n now?: () => number;\n /** Strategy table to probe (built-ins by default). */\n strategies?: readonly AcpAgentStrategy[];\n /** Per-strategy command override (tried before the strategy's own candidates). */\n overrides?: Record<string, string>;\n /** Env used both for PATH enumeration and (by the default probe) for spawns. */\n env?: NodeJS.ProcessEnv;\n /** Injectable `PATH` executable lister (real-fs scan by default). */\n listExecutables?: AcpPathExecutableLister;\n /** Include candidates known to exist but rejected by a discovery probe.\n * Defaults false to preserve the legacy installed-only result. */\n includeRejectedCandidates?: boolean;\n /** Budget for ONE probe spawn (the default probe only — an injected `probe`\n * owns its own timing). Defaults to `DEFAULT_ACP_PROBE_TIMEOUT_MS`. */\n probeTimeoutMs?: number;\n /** Abandon discovery in flight (re-triggered discovery, app quitting).\n * Already-probed groups are still returned. */\n signal?: AbortSignal;\n};\n\n/**\n * Budget for one ACP discovery probe spawn, in ms.\n *\n * Unchanged from the value this module has always used. Kept lower than\n * codex-discovery's version-probe budget on purpose: `discoverStrategyInstances`\n * walks its candidates SERIALLY, so the worst case here is (candidates x\n * budget) rather than a single budget. Hosts that scan machines with many\n * installed copies can raise it knowingly via `probeTimeoutMs`.\n */\nexport const DEFAULT_ACP_PROBE_TIMEOUT_MS = 5_000;\n\n/**\n * Discover every installed instance of each agent (all `PATH` matches +\n * fallbacks + override that pass the probe), grouped per strategy. Groups with\n * no passing instance are omitted unless `includeRejectedCandidates` is true\n * and a detected candidate failed a probe.\n */\nexport async function discoverLocalAcpAgentInstances(\n options: LocalAcpDiscoveryOptions = {}\n): Promise<DiscoveredAcpAgentGroup[]> {\n const strategies = options.strategies ?? BUILT_IN_ACP_STRATEGIES;\n const env = options.env ?? process.env;\n const probe = options.probe ?? makeDefaultProbe(env);\n const listExecutables = options.listExecutables ?? defaultListExecutables;\n const now = options.now ?? Date.now;\n const probeOptions: LocalAcpProbeOptions = {\n timeoutMs: options.probeTimeoutMs ?? DEFAULT_ACP_PROBE_TIMEOUT_MS,\n signal: options.signal\n };\n const groups = await Promise.all(\n strategies.map((strategy) =>\n discoverStrategyInstances(\n strategy,\n probe,\n now,\n env,\n listExecutables,\n options.overrides?.[strategy.id],\n options.includeRejectedCandidates === true,\n probeOptions\n )\n )\n );\n return groups.filter((group): group is DiscoveredAcpAgentGroup => group !== undefined);\n}\n\n/**\n * First-match-per-agent discovery (legacy view). Returns at most one record per\n * agent — the first instance that passed the probe in candidate order.\n */\nexport async function discoverLocalAcpAgents(\n options: LocalAcpDiscoveryOptions = {}\n): Promise<DiscoveredAcpAgent[]> {\n const groups = await discoverLocalAcpAgentInstances(options);\n return groups.flatMap((group) => {\n const first = group.instances[0];\n if (first === undefined) return [];\n const agent: DiscoveredAcpAgent = {\n strategyId: group.strategyId,\n backendId: group.backendId,\n name: group.name,\n command: first.command,\n args: group.args,\n env: group.env,\n discoveredAt: group.discoveredAt\n };\n if (first.version !== undefined) agent.version = first.version;\n return [agent];\n });\n}\n\nasync function discoverStrategyInstances(\n strategy: Strategy,\n probe: LocalAcpAgentProbe,\n now: () => number,\n env: NodeJS.ProcessEnv,\n listExecutables: AcpPathExecutableLister,\n override?: string,\n includeRejectedCandidates = false,\n probeOptions: LocalAcpProbeOptions = {}\n): Promise<DiscoveredAcpAgentGroup | undefined> {\n const candidates = candidateCommands(strategy, env, listExecutables, override);\n const instances: DiscoveredAcpAgentInstance[] = [];\n const rejectedInstances: RejectedAcpAgentInstance[] = [];\n for (const candidate of candidates) {\n if (probeOptions.signal?.aborted) break;\n const [versionAttempt, helpAttempt] = await Promise.all([\n runProbe(probe, candidate.command, strategy.discoveryProbe.versionArgs, probeOptions),\n runProbe(probe, candidate.command, strategy.discoveryProbe.helpArgs, probeOptions)\n ]);\n // An abort landed while these were in flight: whatever they returned is an\n // abandoned measurement, not a verdict on this candidate. Record nothing.\n if (probeOptions.signal?.aborted) break;\n const versionResult = versionAttempt.ok ? versionAttempt.result : undefined;\n const helpResult = helpAttempt.ok ? helpAttempt.result : undefined;\n const version = versionResult ? parseCliVersion(resultText(versionResult)) : undefined;\n if (!versionResult || !helpResult) {\n // A probe that ran out of budget is not a verdict on the CLI — it is an\n // unfinished measurement. Record it even when the caller did not opt into\n // diagnostics, because dropping it is exactly what makes a slow machine\n // look like a machine with nothing installed. (Genuine probe FAILURES\n // stay behind `includeRejectedCandidates` — those are verdicts, and the\n // legacy default is installed-only.)\n const timedOut =\n (!versionAttempt.ok && versionAttempt.timedOut) ||\n (!helpAttempt.ok && helpAttempt.timedOut);\n if (candidate.detected && (timedOut || includeRejectedCandidates)) {\n const rejected: RejectedAcpAgentInstance = {\n command: candidate.command,\n source: candidate.source,\n reason: timedOut\n ? \"probe-timed-out\"\n : versionResult\n ? \"acp-probe-failed\"\n : \"version-probe-failed\"\n };\n if (version !== undefined) rejected.version = version;\n rejectedInstances.push(rejected);\n }\n continue;\n }\n // A strategy with no `helpMatches` relies on the EXIT CODE: the help probe\n // succeeding (enforced just above — a non-zero exit makes `runProbe` return\n // undefined) is itself the ACP-capability signal. Only when a regex is set\n // do we additionally parse the (drift-prone) help text.\n if (\n strategy.discoveryProbe.helpMatches !== undefined &&\n !strategy.discoveryProbe.helpMatches.test(resultText(helpResult))\n ) {\n if (includeRejectedCandidates && candidate.detected) {\n const rejected: RejectedAcpAgentInstance = {\n command: candidate.command,\n source: candidate.source,\n reason: \"acp-help-mismatch\"\n };\n if (version !== undefined) rejected.version = version;\n rejectedInstances.push(rejected);\n }\n continue;\n }\n const instance: DiscoveredAcpAgentInstance = {\n command: candidate.command,\n source: candidate.source\n };\n if (version !== undefined) instance.version = version;\n instances.push(instance);\n }\n if (instances.length === 0 && rejectedInstances.length === 0) {\n return undefined;\n }\n return {\n strategyId: strategy.id,\n backendId: strategy.backendId,\n name: strategy.displayName,\n args: ensureArgs(strategy.spawn.args, strategy.spawn.ensureArgs),\n env: strategy.spawn.env ?? {},\n instances,\n ...(rejectedInstances.length > 0 ? { rejectedInstances } : {}),\n discoveredAt: now()\n };\n}\n\ntype Candidate = {\n command: string;\n source: AcpAgentInstanceSource;\n /** True only when command enumeration found a concrete executable path. */\n detected: boolean;\n};\n\n/** Build the de-duplicated candidate list for a strategy: override first, then\n * every `PATH` match of the bare command (or the bare command itself when the\n * lister finds none, so `execFile`'s own `PATH` resolution still gets a shot),\n * then the strategy's fallback paths. Duplicates (by resolved real path) are\n * collapsed so the same physical binary isn't listed twice. */\nfunction candidateCommands(\n strategy: Strategy,\n env: NodeJS.ProcessEnv,\n listExecutables: AcpPathExecutableLister,\n override?: string\n): Candidate[] {\n const out: Candidate[] = [];\n const seen = new Set<string>();\n const push = (\n command: string,\n source: AcpAgentInstanceSource,\n detected: boolean\n ): void => {\n const trimmed = command.trim();\n if (trimmed.length === 0) return;\n const key = canonicalize(trimmed);\n if (seen.has(key)) return;\n seen.add(key);\n out.push({ command: trimmed, source, detected });\n };\n\n if (override && override.trim().length > 0) {\n push(override, \"override\", isExecutableFile(override));\n }\n const pathMatches = listExecutables(strategy.discoveryProbe.command, env);\n if (pathMatches.length > 0) {\n for (const match of pathMatches) push(match, \"path\", true);\n } else {\n // No PATH hit (or an injected no-op lister): keep the bare command so\n // `execFile` resolves it via its own PATH and scripted-probe tests match.\n push(strategy.discoveryProbe.command, \"path\", false);\n }\n for (const fallback of strategy.discoveryProbe.fallbackCommands ?? []) {\n push(fallback, \"fallback\", isExecutableFile(fallback));\n }\n return out;\n}\n\nfunction isExecutableFile(command: string): boolean {\n try {\n const stat = statSync(command);\n return stat.isFile() && (process.platform === \"win32\" || (stat.mode & 0o111) !== 0);\n } catch {\n return false;\n }\n}\n\n/** Resolve symlinks so the same binary reached via two PATH entries dedupes. */\nfunction canonicalize(command: string): string {\n if (!path.isAbsolute(command)) {\n return process.platform === \"win32\" ? command.toLowerCase() : command;\n }\n try {\n const canonical = realpathSync(command);\n return process.platform === \"win32\" ? canonical.toLowerCase() : canonical;\n } catch {\n return process.platform === \"win32\" ? command.toLowerCase() : command;\n }\n}\n\n/** Default executable lister: scan `env.PATH` AND well-known version-manager /\n * install dirs for an executable file named `command`. On Windows, expand\n * each PATH entry using PATHEXT and return the actual .COM/.EXE/.BAT/.CMD\n * candidates rather than a bare command that `execFile` cannot launch.\n *\n * Scanning beyond `PATH` is deliberate: a desktop app launched from Finder /\n * Dock inherits launchd's minimal `PATH`, and login-shell hydration can't\n * reliably recover a version-manager `PATH` (nvm is often lazy-loaded and\n * pins a different node version than the one the agent CLI is installed\n * under). So an `npm i -g qwen` under nvm would be invisible. We find it by\n * scanning the version-manager bin dirs directly. */\nfunction defaultListExecutables(command: string, env: NodeJS.ProcessEnv): string[] {\n // A bare command name only — never enumerate when a path was passed.\n if (command.includes(\"/\") || command.includes(\"\\\\\")) return [];\n const found: string[] = [];\n const seenDir = new Set<string>();\n for (const dir of discoveryDirs(env)) {\n const normalizedDir = normalizePathEntry(dir);\n const dirKey = process.platform === \"win32\" ? normalizedDir.toLowerCase() : normalizedDir;\n if (normalizedDir.length === 0 || seenDir.has(dirKey)) continue;\n seenDir.add(dirKey);\n for (const commandName of executableCommandNames(command, env)) {\n const candidate = path.join(normalizedDir, commandName);\n try {\n const stat = statSync(candidate);\n if (stat.isFile() && (process.platform === \"win32\" || (stat.mode & 0o111) !== 0)) {\n found.push(candidate);\n }\n } catch {\n // Not in this dir; keep scanning.\n }\n }\n }\n return found;\n}\n\nfunction executableCommandNames(command: string, env: NodeJS.ProcessEnv): string[] {\n if (process.platform !== \"win32\") return [command];\n const extensions = (readWindowsEnv(env, \"PATHEXT\")?.trim() || \".COM;.EXE;.BAT;.CMD\")\n .split(\";\")\n .map((extension) => extension.trim())\n .filter(Boolean)\n .map((extension) => extension.startsWith(\".\") ? extension : `.${extension}`);\n const commandExtension = path.win32.extname(command);\n if (\n commandExtension.length > 0 &&\n extensions.some((extension) => extension.toLowerCase() === commandExtension.toLowerCase())\n ) {\n return [command];\n }\n return extensions.map((extension) => `${command}${extension}`);\n}\n\nfunction readWindowsEnv(env: NodeJS.ProcessEnv, name: string): string | undefined {\n const key = Object.keys(env).find((candidate) => candidate.toLowerCase() === name.toLowerCase());\n return key ? env[key] : undefined;\n}\n\nfunction normalizePathEntry(entry: string): string {\n const trimmed = entry.trim();\n const quoted = trimmed.match(/^\"(.*)\"$/);\n return quoted?.[1] ?? trimmed;\n}\n\n/** Dirs to scan for agent executables: every `env.PATH` entry first, then the\n * well-known version-manager / package-manager bin dirs a GUI app's `PATH`\n * usually omits. */\nfunction discoveryDirs(env: NodeJS.ProcessEnv): string[] {\n const pathValue = process.platform === \"win32\"\n ? readWindowsEnv(env, \"PATH\") ?? \"\"\n : env.PATH ?? \"\";\n const pathDirs = pathValue.split(path.delimiter);\n return process.platform === \"win32\"\n ? pathDirs\n : [...pathDirs, ...wellKnownAgentBinDirs(homedir())];\n}\n\n/** Well-known bin dirs where a CLI installed via a node/JS version manager or\n * a per-user package manager lives — even when it isn't on a GUI app's `PATH`.\n * Exported for testing; `home` defaults to the user's home dir. */\nexport function wellKnownAgentBinDirs(home: string = homedir()): string[] {\n return [\n // Every installed nvm node version's bin (the agent may be under any one).\n ...nvmNodeBinDirs(home),\n // Other version / package managers.\n path.join(home, \".volta\", \"bin\"),\n path.join(home, \".bun\", \"bin\"),\n path.join(home, \".asdf\", \"shims\"),\n path.join(home, \".deno\", \"bin\"),\n path.join(home, \".local\", \"bin\"),\n path.join(home, \".npm-global\", \"bin\"),\n // Common system install prefixes.\n \"/opt/homebrew/bin\",\n \"/usr/local/bin\"\n ];\n}\n\n/** Every `~/.nvm/versions/node/<v>/bin` dir, newest-first so the most recent\n * node version's install is tried before older ones. Empty when nvm absent. */\nfunction nvmNodeBinDirs(home: string): string[] {\n const base = path.join(home, \".nvm\", \"versions\", \"node\");\n try {\n return readdirSync(base)\n .sort()\n .reverse()\n .map((version) => path.join(base, version, \"bin\"));\n } catch {\n return [];\n }\n}\n\nfunction ensureArgs(args: string[], ensure: string[] | undefined): string[] {\n if (!ensure || ensure.length === 0) {\n return args;\n }\n const result = [...args];\n for (const arg of ensure) {\n if (!result.includes(arg)) result.push(arg);\n }\n return result;\n}\n\n/** Thrown by the default probe when its budget elapses. Distinguishable from\n * a probe that ran and failed, which is a verdict on the CLI. */\nclass AcpProbeTimeoutError extends Error {\n constructor(command: string, timeoutMs: number) {\n super(`acp probe did not answer within ${timeoutMs}ms: ${command}`);\n this.name = \"AcpProbeTimeoutError\";\n }\n}\n\nfunction isProbeTimeout(error: unknown): boolean {\n if (error instanceof AcpProbeTimeoutError) return true;\n // Covers an injected probe that leans on `execFile`'s own `timeout` (which\n // sets `killed`) or on an AbortSignal.\n const name = (error as { name?: unknown } | undefined)?.name;\n return (\n (error as { killed?: unknown } | undefined)?.killed === true ||\n name === \"AbortError\" ||\n name === \"TimeoutError\"\n );\n}\n\n/**\n * Clamp a caller-supplied probe budget.\n *\n * The `Number.isFinite` guard is load-bearing: `Infinity` is the natural way to\n * ask for \"no budget\", and `execFile` rejects a non-finite `timeout` with a\n * synchronous `ERR_OUT_OF_RANGE` — which `runProbe` would then classify as a\n * failed probe and report as \"not installed\" for every agent on the machine.\n */\nfunction normalizeProbeTimeoutMs(timeoutMs: number | undefined): number {\n if (timeoutMs === undefined || !Number.isFinite(timeoutMs)) {\n return DEFAULT_ACP_PROBE_TIMEOUT_MS;\n }\n return Math.max(1, Math.floor(timeoutMs));\n}\n\nfunction makeDefaultProbe(env: NodeJS.ProcessEnv): LocalAcpAgentProbe {\n return async (\n command: string,\n args: string[],\n options: LocalAcpProbeOptions = {}\n ): Promise<LocalAcpProbeResult> => {\n const timeoutMs = normalizeProbeTimeoutMs(options.timeoutMs);\n const launchEnv = prependCommandDirToPath(command, env);\n const invocation = createCommandInvocation({ command, args, env: launchEnv });\n const controller = new AbortController();\n let timedOut = false;\n const onAbort = (): void => controller.abort();\n options.signal?.addEventListener(\"abort\", onAbort, { once: true });\n const timer = setTimeout(() => {\n timedOut = true;\n controller.abort();\n }, timeoutMs);\n // Race the spawn against the budget rather than trusting `execFile`'s own\n // `timeout` alone: these CLIs are frequently Windows `.cmd` shims, and\n // killing the `cmd.exe` wrapper can leave a `node` grandchild holding the\n // pipes open so `execFile` never calls back at all.\n const expired = new Promise<\"expired\">((resolve) => {\n controller.signal.addEventListener(\"abort\", () => resolve(\"expired\"), {\n once: true\n });\n });\n try {\n const execution = execFile(invocation.command, invocation.args, {\n timeout: timeoutMs,\n signal: controller.signal,\n maxBuffer: 1024 * 1024,\n // A Windows `.cmd` shim runs through `cmd.exe`; without this every\n // discovery pass flashes console windows over the host app.\n windowsHide: true,\n // Prepend the candidate's own dir so a node-script CLI (e.g. an nvm-\n // installed `qwen`) finds its sibling `node` during the probe.\n env: launchEnv,\n windowsVerbatimArguments: invocation.windowsVerbatimArguments\n }).then(\n (result) => ({ ok: true as const, result }),\n (error: unknown) => ({ ok: false as const, error })\n );\n const settled = await Promise.race([execution, expired]);\n if (settled === \"expired\") {\n if (timedOut) throw new AcpProbeTimeoutError(command, timeoutMs);\n throw new Error(`acp probe aborted: ${command}`);\n }\n if (!settled.ok) {\n if (timedOut) throw new AcpProbeTimeoutError(command, timeoutMs);\n throw settled.error;\n }\n return settled.result;\n } finally {\n clearTimeout(timer);\n options.signal?.removeEventListener(\"abort\", onAbort);\n }\n };\n}\n\ntype ProbeAttempt =\n | { ok: true; result: LocalAcpProbeResult }\n | { ok: false; timedOut: boolean };\n\nasync function runProbe(\n probe: LocalAcpAgentProbe,\n command: string,\n args: string[],\n options: LocalAcpProbeOptions\n): Promise<ProbeAttempt> {\n try {\n return { ok: true, result: await probe(command, args, options) };\n } catch (error) {\n return { ok: false, timedOut: isProbeTimeout(error) };\n }\n}\n\nfunction resultText(result: LocalAcpProbeResult): string {\n return [result.stdout, result.stderr]\n .flatMap((value) => (value === undefined ? [] : [value]))\n .map((value) => (Buffer.isBuffer(value) ? value.toString(\"utf8\") : value))\n .join(\"\\n\");\n}\n\nfunction parseCliVersion(output: string): string | undefined {\n const trimmed = output.trim();\n if (!trimmed) {\n return undefined;\n }\n return trimmed.match(/\\d+\\.\\d+\\.\\d+(?:[-+][\\w.-]+)?/)?.[0] ?? trimmed;\n}\n","// Gate registry-sourced ACP agents. Rejects the GPL family, unpinned npx/uvx\n// packages, and unpinned binary archive hosts; `BANNED_ACP_REGISTRY_IDS` keeps\n// `codex-acp` out (PwrDrvr talks to Codex through the first-class Codex adapter,\n// not as an ACP duplicate).\n//\n// Ported from PwrAgnt acp-agent-allowlist.ts, with @pwragent/shared types\n// inlined.\n\nimport type {\n AcpAllowlistDecision,\n AcpDistributionKind,\n AcpRegistryAgent,\n AcpRegistryDistribution\n} from \"./acp-registry-types\";\n\nexport type AcpAgentAllowlistRule = {\n id: string;\n registryId: string;\n versions?: string[];\n distributionKinds?: AcpDistributionKind[];\n allowedPackageNames?: string[];\n allowedArchiveHosts?: string[];\n allowUnverifiedBinary?: boolean;\n allowGplFamilyLicense?: boolean;\n};\n\nexport const BANNED_ACP_REGISTRY_IDS = new Set([\"codex-acp\"]);\n\nexport const DEFAULT_ACP_AGENT_ALLOWLIST: AcpAgentAllowlistRule[] = [\n { id: \"local-grok-cli\", registryId: \"grok\", distributionKinds: [\"local\"] },\n { id: \"local-qwen-code-cli\", registryId: \"qwen\", distributionKinds: [\"local\"] }\n];\n\nexport class AcpAgentAllowlist {\n constructor(private readonly rules: AcpAgentAllowlistRule[]) {}\n\n evaluate(agent: AcpRegistryAgent): AcpAllowlistDecision {\n if (isBannedAcpRegistryId(agent.id)) {\n return { allowed: false, reason: \"banned\" };\n }\n const matchingRules = this.rules.filter((rule) => rule.registryId === agent.id);\n if (matchingRules.length === 0) {\n return { allowed: false, reason: \"not-allowlisted\" };\n }\n for (const rule of matchingRules) {\n const denial = evaluateRule(rule, agent);\n if (!denial) {\n return {\n allowed: true,\n ruleId: rule.id,\n unverifiedBinaryAllowed: rule.allowUnverifiedBinary === true\n };\n }\n }\n return { allowed: false, reason: \"allowlist-rule-mismatch\" };\n }\n\n evaluateDistribution(\n agent: AcpRegistryAgent,\n distribution: AcpRegistryDistribution\n ): AcpAllowlistDecision {\n if (isBannedAcpRegistryId(agent.id)) {\n return { allowed: false, reason: \"banned\" };\n }\n const matchingRules = this.rules.filter((rule) => rule.registryId === agent.id);\n if (matchingRules.length === 0) {\n return { allowed: false, reason: \"not-allowlisted\" };\n }\n for (const rule of matchingRules) {\n const denial = evaluateDistributionRule(rule, agent, distribution);\n if (!denial) {\n return {\n allowed: true,\n ruleId: rule.id,\n unverifiedBinaryAllowed: rule.allowUnverifiedBinary === true\n };\n }\n }\n return { allowed: false, reason: \"allowlist-rule-mismatch\" };\n }\n}\n\nexport const defaultAcpAgentAllowlist = new AcpAgentAllowlist(\n DEFAULT_ACP_AGENT_ALLOWLIST\n);\n\nexport function isBannedAcpRegistryId(registryId: string): boolean {\n return BANNED_ACP_REGISTRY_IDS.has(registryId);\n}\n\nfunction evaluateRule(\n rule: AcpAgentAllowlistRule,\n agent: AcpRegistryAgent\n): string | undefined {\n if (rule.versions && (!agent.version || !rule.versions.includes(agent.version))) {\n return \"version-not-allowed\";\n }\n if (isGplFamilyLicense(agent.license) && !rule.allowGplFamilyLicense) {\n return \"license-not-allowed\";\n }\n let distributionDeniedBySource = false;\n for (const distribution of agent.distributions) {\n const denial = evaluateDistributionRule(rule, agent, distribution, {\n skipAgentChecks: true\n });\n if (!denial) {\n return undefined;\n }\n if (denial === \"distribution-source-not-allowed\") {\n distributionDeniedBySource = true;\n }\n }\n return distributionDeniedBySource\n ? \"distribution-source-not-allowed\"\n : \"distribution-not-allowed\";\n}\n\nfunction evaluateDistributionRule(\n rule: AcpAgentAllowlistRule,\n agent: AcpRegistryAgent,\n distribution: AcpRegistryDistribution,\n options: { skipAgentChecks?: boolean } = {}\n): string | undefined {\n if (\n !options.skipAgentChecks &&\n rule.versions &&\n (!agent.version || !rule.versions.includes(agent.version))\n ) {\n return \"version-not-allowed\";\n }\n if (\n !options.skipAgentChecks &&\n isGplFamilyLicense(agent.license) &&\n !rule.allowGplFamilyLicense\n ) {\n return \"license-not-allowed\";\n }\n if (!distributionAllowedByKind(rule, distribution)) {\n return \"distribution-not-allowed\";\n }\n if (!distributionSourceAllowed(rule, distribution)) {\n return \"distribution-source-not-allowed\";\n }\n return undefined;\n}\n\nfunction distributionAllowedByKind(\n rule: AcpAgentAllowlistRule,\n distribution: AcpRegistryDistribution\n): boolean {\n return !rule.distributionKinds || rule.distributionKinds.includes(distribution.kind);\n}\n\nfunction distributionSourceAllowed(\n rule: AcpAgentAllowlistRule,\n distribution: AcpRegistryDistribution\n): boolean {\n if (distribution.kind === \"npx\" || distribution.kind === \"uvx\") {\n return (\n !rule.allowedPackageNames ||\n rule.allowedPackageNames.includes(distribution.packageName)\n );\n }\n if (distribution.kind !== \"binary\") {\n return false;\n }\n if (!rule.allowedArchiveHosts) {\n return true;\n }\n try {\n return rule.allowedArchiveHosts.includes(new URL(distribution.archiveUrl).host);\n } catch {\n return false;\n }\n}\n\nfunction isGplFamilyLicense(license: string | undefined): boolean {\n return /\\b(?:GPL|AGPL|LGPL)\\b/i.test(license ?? \"\");\n}\n","// Registry types for the ACP extension path. The four built-in strategies do\n// NOT require the registry; this is how a host adds more ACP agents from the\n// public Agent Client Protocol registry, gated by the allowlist.\n//\n// Ported from PwrAgnt acp-registry-types.ts, with @pwragent/shared types\n// inlined as neutral local types.\n\nimport { buildAcpBackendId } from \"../strategies/strategy-types\";\n\nexport const ACP_REGISTRY_URL =\n \"https://cdn.agentclientprotocol.com/registry/v1/latest/registry.json\";\n\nexport type AcpDistributionKind = \"npx\" | \"uvx\" | \"binary\" | \"local\";\n\nexport type AcpRegistryDistributionEnv = Record<string, string>;\n\nexport type AcpPackageDistribution = {\n kind: \"npx\" | \"uvx\";\n packageName: string;\n args: string[];\n env: AcpRegistryDistributionEnv;\n};\n\nexport type AcpBinaryPlatformDistribution = {\n kind: \"binary\";\n platform: string;\n archiveUrl: string;\n command: string;\n args: string[];\n env: AcpRegistryDistributionEnv;\n checksum?: string;\n signatureUrl?: string;\n};\n\nexport type AcpRegistryDistribution =\n | AcpPackageDistribution\n | AcpBinaryPlatformDistribution;\n\nexport type AcpRegistryAuthMethod = \"agent-managed\" | \"terminal\" | \"unknown\";\n\nexport type AcpRegistryAuthDescriptor = {\n required: boolean;\n methods: AcpRegistryAuthMethod[];\n raw?: unknown;\n};\n\nexport type AcpRegistryAgent = {\n id: string;\n backendId: string;\n name: string;\n version?: string;\n description?: string;\n authors: string[];\n license?: string;\n repositoryUrl?: string;\n websiteUrl?: string;\n iconUrl?: string;\n distributions: AcpRegistryDistribution[];\n distributionKinds: AcpDistributionKind[];\n auth: AcpRegistryAuthDescriptor;\n raw: unknown;\n};\n\nexport type AcpVerificationStatus =\n | \"verified\"\n | \"unverified-allowed\"\n | \"unverified-blocked\"\n | \"not-applicable\";\n\nexport type AcpAllowlistDecision =\n | { allowed: true; ruleId: string; unverifiedBinaryAllowed: boolean }\n | { allowed: false; reason: string };\n\nexport type AcpRegistryAgentWithPolicy = AcpRegistryAgent & {\n allowlist: AcpAllowlistDecision;\n installable: boolean;\n unavailableReason?: string;\n verificationStatus: AcpVerificationStatus;\n};\n\nexport type AcpRegistrySnapshot = {\n fetchedAt: number;\n agents: AcpRegistryAgent[];\n raw: unknown;\n};\n\nexport { buildAcpBackendId };\n","// Fetch + normalize the public ACP registry and apply the allowlist policy.\n// The EXTENSION path for adding ACP agents beyond the four built-in strategies.\n//\n// Ported from PwrAgnt acp-registry-service.ts, with @pwragent/shared dropped.\n\nimport {\n ACP_REGISTRY_URL,\n buildAcpBackendId,\n type AcpAllowlistDecision,\n type AcpBinaryPlatformDistribution,\n type AcpPackageDistribution,\n type AcpRegistryAgent,\n type AcpRegistryAgentWithPolicy,\n type AcpRegistryAuthDescriptor,\n type AcpRegistryDistribution,\n type AcpRegistrySnapshot,\n type AcpVerificationStatus\n} from \"./acp-registry-types\";\nimport {\n AcpAgentAllowlist,\n defaultAcpAgentAllowlist\n} from \"./acp-agent-allowlist\";\n\nexport type AcpRegistryFetch = (\n input: string,\n init?: { headers?: Record<string, string> }\n) => Promise<{\n ok: boolean;\n status: number;\n statusText: string;\n json(): Promise<unknown>;\n}>;\n\nexport type AcpRegistryServiceOptions = {\n allowlist?: AcpAgentAllowlist;\n fetch?: AcpRegistryFetch;\n now?: () => number;\n registryUrl?: string;\n};\n\nexport type AcpDistributionPolicy = {\n allowlist: AcpAllowlistDecision;\n installable: boolean;\n verificationStatus: AcpVerificationStatus;\n unavailableReason?: string;\n};\n\nexport class AcpRegistryService {\n private readonly allowlist: AcpAgentAllowlist;\n private readonly fetcher: AcpRegistryFetch;\n private readonly now: () => number;\n private readonly registryUrl: string;\n\n constructor(options: AcpRegistryServiceOptions = {}) {\n this.allowlist = options.allowlist ?? defaultAcpAgentAllowlist;\n this.fetcher =\n options.fetch ??\n (async (input, init) => {\n const response = await globalThis.fetch(input, init);\n return {\n ok: response.ok,\n status: response.status,\n statusText: response.statusText,\n json: () => response.json() as Promise<unknown>\n };\n });\n this.now = options.now ?? Date.now;\n this.registryUrl = options.registryUrl ?? ACP_REGISTRY_URL;\n }\n\n async fetchRegistry(): Promise<AcpRegistrySnapshot> {\n const response = await this.fetcher(this.registryUrl, {\n headers: { accept: \"application/json\" }\n });\n if (!response.ok) {\n throw new Error(\n `ACP registry request failed: ${response.status} ${response.statusText}`\n );\n }\n const raw = await response.json();\n return { fetchedAt: this.now(), agents: normalizeRegistry(raw), raw };\n }\n\n applyAllowlist(snapshot: AcpRegistrySnapshot): AcpRegistryAgentWithPolicy[] {\n return snapshot.agents.map((agent) => {\n const allowlist = this.allowlist.evaluate(agent);\n const distributionPolicies = agent.distributions.map((distribution) =>\n this.evaluateDistribution(agent, distribution)\n );\n const installablePolicy = distributionPolicies.find((policy) => policy.installable);\n const firstBlockedAllowedPolicy = distributionPolicies.find(\n (policy) => policy.allowlist.allowed\n );\n const installable = Boolean(installablePolicy);\n const result: AcpRegistryAgentWithPolicy = {\n ...agent,\n allowlist,\n installable,\n verificationStatus:\n installablePolicy?.verificationStatus ??\n firstBlockedAllowedPolicy?.verificationStatus ??\n \"not-applicable\"\n };\n const unavailableReason = installable\n ? undefined\n : (firstBlockedAllowedPolicy?.unavailableReason ??\n (allowlist.allowed ? \"distribution-not-installable\" : allowlist.reason));\n if (unavailableReason !== undefined) result.unavailableReason = unavailableReason;\n return result;\n });\n }\n\n evaluateDistribution(\n agent: AcpRegistryAgent,\n distribution: AcpRegistryDistribution\n ): AcpDistributionPolicy {\n const allowlist = this.allowlist.evaluateDistribution(agent, distribution);\n return evaluateAcpDistributionPolicy(distribution, allowlist);\n }\n}\n\nexport function evaluateAcpDistributionPolicy(\n distribution: AcpRegistryDistribution,\n allowlist: AcpAllowlistDecision\n): AcpDistributionPolicy {\n if (!allowlist.allowed) {\n return {\n allowlist,\n installable: false,\n verificationStatus: \"not-applicable\",\n unavailableReason: allowlist.reason\n };\n }\n if (distribution.kind !== \"binary\") {\n return { allowlist, installable: true, verificationStatus: \"not-applicable\" };\n }\n if (distribution.checksum) {\n return { allowlist, installable: true, verificationStatus: \"verified\" };\n }\n return {\n allowlist,\n installable: allowlist.unverifiedBinaryAllowed,\n verificationStatus: allowlist.unverifiedBinaryAllowed\n ? \"unverified-allowed\"\n : \"unverified-blocked\",\n ...(allowlist.unverifiedBinaryAllowed\n ? {}\n : { unavailableReason: \"binary-integrity-metadata-missing\" })\n };\n}\n\nexport function normalizeRegistry(raw: unknown): AcpRegistryAgent[] {\n const record = asRecord(raw);\n const rawAgents = Array.isArray(record?.agents) ? record.agents : [];\n return rawAgents.flatMap((item) => {\n const agent = normalizeAgent(item);\n return agent ? [agent] : [];\n });\n}\n\nfunction normalizeAgent(raw: unknown): AcpRegistryAgent | undefined {\n const record = asRecord(raw);\n if (!record || typeof record.id !== \"string\" || typeof record.name !== \"string\") {\n return undefined;\n }\n const distributions = normalizeDistributions(record.distribution);\n if (distributions.length === 0) {\n return undefined;\n }\n const agent: AcpRegistryAgent = {\n id: record.id,\n backendId: buildAcpBackendId(record.id),\n name: record.name,\n authors: Array.isArray(record.authors)\n ? record.authors.filter((author): author is string => typeof author === \"string\")\n : [],\n distributions,\n distributionKinds: [...new Set(distributions.map((d) => d.kind))],\n auth: normalizeAuth(record.auth),\n raw\n };\n const version = stringValue(record.version);\n if (version !== undefined) agent.version = version;\n const description = stringValue(record.description);\n if (description !== undefined) agent.description = description;\n const license = stringValue(record.license);\n if (license !== undefined) agent.license = license;\n const repositoryUrl = stringValue(record.repository);\n if (repositoryUrl !== undefined) agent.repositoryUrl = repositoryUrl;\n const websiteUrl = stringValue(record.website);\n if (websiteUrl !== undefined) agent.websiteUrl = websiteUrl;\n const iconUrl = stringValue(record.icon);\n if (iconUrl !== undefined) agent.iconUrl = iconUrl;\n return agent;\n}\n\nfunction normalizeDistributions(raw: unknown): AcpRegistryDistribution[] {\n const record = asRecord(raw);\n if (!record) {\n return [];\n }\n const distributions: AcpRegistryDistribution[] = [];\n const npx = normalizePackageDistribution(\"npx\", record.npx);\n if (npx) distributions.push(npx);\n const uvx = normalizePackageDistribution(\"uvx\", record.uvx);\n if (uvx) distributions.push(uvx);\n const binaryRecord = asRecord(record.binary);\n if (binaryRecord) {\n for (const [platform, value] of Object.entries(binaryRecord)) {\n const binary = normalizeBinaryDistribution(platform, value);\n if (binary) distributions.push(binary);\n }\n }\n return distributions;\n}\n\nfunction normalizePackageDistribution(\n kind: \"npx\" | \"uvx\",\n raw: unknown\n): AcpPackageDistribution | undefined {\n const record = asRecord(raw);\n if (!record || typeof record.package !== \"string\") {\n return undefined;\n }\n return {\n kind,\n packageName: record.package,\n args: stringArray(record.args),\n env: stringRecord(record.env)\n };\n}\n\nfunction normalizeBinaryDistribution(\n platform: string,\n raw: unknown\n): AcpBinaryPlatformDistribution | undefined {\n const record = asRecord(raw);\n if (!record || typeof record.archive !== \"string\" || typeof record.cmd !== \"string\") {\n return undefined;\n }\n const distribution: AcpBinaryPlatformDistribution = {\n kind: \"binary\",\n platform,\n archiveUrl: record.archive,\n command: record.cmd,\n args: stringArray(record.args),\n env: stringRecord(record.env)\n };\n const checksum = stringValue(record.checksum) ?? stringValue(record.sha256);\n if (checksum !== undefined) distribution.checksum = checksum;\n const signatureUrl = stringValue(record.signature) ?? stringValue(record.signatureUrl);\n if (signatureUrl !== undefined) distribution.signatureUrl = signatureUrl;\n return distribution;\n}\n\nfunction normalizeAuth(raw: unknown): AcpRegistryAuthDescriptor {\n if (!raw) {\n return { required: false, methods: [] };\n }\n const record = asRecord(raw);\n if (!record) {\n return { required: true, methods: [\"unknown\"], raw };\n }\n const methods = stringArray(record.methods).map((method) =>\n method === \"agent-managed\" || method === \"terminal\" ? method : \"unknown\"\n );\n return {\n required: record.required === false ? false : true,\n methods: methods.length > 0 ? [...new Set(methods)] : [\"unknown\"],\n raw\n };\n}\n\nfunction asRecord(value: unknown): Record<string, unknown> | undefined {\n return value && typeof value === \"object\" && !Array.isArray(value)\n ? (value as Record<string, unknown>)\n : undefined;\n}\n\nfunction stringValue(value: unknown): string | undefined {\n return typeof value === \"string\" && value.trim() ? value : undefined;\n}\n\nfunction stringArray(value: unknown): string[] {\n return Array.isArray(value)\n ? value.filter((item): item is string => typeof item === \"string\")\n : [];\n}\n\nfunction stringRecord(value: unknown): Record<string, string> {\n const record = asRecord(value);\n if (!record) {\n return {};\n }\n return Object.fromEntries(\n Object.entries(record).filter(\n (entry): entry is [string, string] => typeof entry[1] === \"string\"\n )\n );\n}\n"],"mappings":"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","names":[]}
|
|
@@ -0,0 +1,163 @@
|
|
|
1
|
+
// src/strategies/strategy-types.ts
|
|
2
|
+
function buildAcpBackendId(registryId) {
|
|
3
|
+
return `acp:${registryId}`;
|
|
4
|
+
}
|
|
5
|
+
var DEFAULT_QUIRKS = {
|
|
6
|
+
surfaceThoughts: true,
|
|
7
|
+
titleFrom: "topic-update"
|
|
8
|
+
};
|
|
9
|
+
function defaultQuirks(overrides = {}) {
|
|
10
|
+
return { ...DEFAULT_QUIRKS, ...overrides };
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
// src/strategies/gemini.ts
|
|
14
|
+
var geminiStrategy = {
|
|
15
|
+
id: "gemini",
|
|
16
|
+
backendId: buildAcpBackendId("gemini"),
|
|
17
|
+
displayName: "Gemini CLI",
|
|
18
|
+
authors: ["Google"],
|
|
19
|
+
discoveryProbe: {
|
|
20
|
+
command: "gemini",
|
|
21
|
+
versionArgs: ["--version"],
|
|
22
|
+
helpArgs: ["--help"],
|
|
23
|
+
helpMatches: /(^|\s)--acp(\s|,|$)/
|
|
24
|
+
},
|
|
25
|
+
spawn: {
|
|
26
|
+
command: "gemini",
|
|
27
|
+
args: ["--acp"],
|
|
28
|
+
// Gemini refuses to operate without workspace trust; matching PwrAgnt's
|
|
29
|
+
// launch-descriptor normalization, append --skip-trust + set the env flag.
|
|
30
|
+
ensureArgs: ["--skip-trust"],
|
|
31
|
+
env: { GEMINI_CLI_TRUST_WORKSPACE: "true" }
|
|
32
|
+
},
|
|
33
|
+
quirks: defaultQuirks({ surfaceThoughts: true, titleFrom: "topic-update" })
|
|
34
|
+
};
|
|
35
|
+
|
|
36
|
+
// src/strategies/grok.ts
|
|
37
|
+
import { homedir } from "os";
|
|
38
|
+
import path from "path";
|
|
39
|
+
var grokStrategy = {
|
|
40
|
+
id: "grok",
|
|
41
|
+
backendId: buildAcpBackendId("grok"),
|
|
42
|
+
displayName: "Grok",
|
|
43
|
+
authors: ["xAI"],
|
|
44
|
+
discoveryProbe: {
|
|
45
|
+
command: "grok",
|
|
46
|
+
versionArgs: ["--version"],
|
|
47
|
+
helpArgs: ["agent", "stdio", "--help"],
|
|
48
|
+
helpMatches: /Run the agent over stdio/i,
|
|
49
|
+
fallbackCommands: [
|
|
50
|
+
path.join(homedir(), ".grok", "bin", "grok"),
|
|
51
|
+
"/opt/homebrew/bin/grok",
|
|
52
|
+
"/usr/local/bin/grok"
|
|
53
|
+
]
|
|
54
|
+
},
|
|
55
|
+
spawn: {
|
|
56
|
+
command: "grok",
|
|
57
|
+
args: ["agent", "stdio"]
|
|
58
|
+
},
|
|
59
|
+
// Grok auto-generates the thread title via its vendor notification
|
|
60
|
+
// `_x.ai/session_notification` carrying `session_summary_generated`.
|
|
61
|
+
quirks: defaultQuirks({
|
|
62
|
+
surfaceThoughts: true,
|
|
63
|
+
titleFrom: "session-summary",
|
|
64
|
+
vendorNotificationMethods: ["_x.ai/session_notification"]
|
|
65
|
+
})
|
|
66
|
+
};
|
|
67
|
+
|
|
68
|
+
// src/strategies/kimi.ts
|
|
69
|
+
import { homedir as homedir2 } from "os";
|
|
70
|
+
import path2 from "path";
|
|
71
|
+
var kimiStrategy = {
|
|
72
|
+
id: "kimi",
|
|
73
|
+
backendId: buildAcpBackendId("kimi"),
|
|
74
|
+
displayName: "Kimi Code CLI",
|
|
75
|
+
authors: ["Moonshot AI"],
|
|
76
|
+
discoveryProbe: {
|
|
77
|
+
command: "kimi",
|
|
78
|
+
versionArgs: ["--version"],
|
|
79
|
+
// Capability signal is the EXIT CODE of `kimi acp --help`, NOT its prose.
|
|
80
|
+
// kimi's commander CLI exits non-zero for an unknown subcommand, so a
|
|
81
|
+
// zero-exit proves the `acp` subcommand exists. No `helpMatches`: the help
|
|
82
|
+
// wording has already drifted across kimi versions (0.11.0 prints "Agent
|
|
83
|
+
// Client Protocol (ACP) server over stdio"), so matching it is fragile.
|
|
84
|
+
helpArgs: ["acp", "--help"],
|
|
85
|
+
// The official Kimi Code installer drops a standalone binary at
|
|
86
|
+
// ~/.kimi-code/bin/kimi and does NOT add it to PATH — so a Finder-launched
|
|
87
|
+
// app misses it without this fallback (mirrors grok/qwen).
|
|
88
|
+
fallbackCommands: [
|
|
89
|
+
path2.join(homedir2(), ".kimi-code", "bin", "kimi"),
|
|
90
|
+
"/opt/homebrew/bin/kimi",
|
|
91
|
+
"/usr/local/bin/kimi"
|
|
92
|
+
]
|
|
93
|
+
},
|
|
94
|
+
spawn: {
|
|
95
|
+
command: "kimi",
|
|
96
|
+
args: ["acp"]
|
|
97
|
+
},
|
|
98
|
+
quirks: defaultQuirks({ surfaceThoughts: true, titleFrom: "topic-update" })
|
|
99
|
+
};
|
|
100
|
+
|
|
101
|
+
// src/strategies/qwen.ts
|
|
102
|
+
import { homedir as homedir3 } from "os";
|
|
103
|
+
import path3 from "path";
|
|
104
|
+
var qwenStrategy = {
|
|
105
|
+
id: "qwen",
|
|
106
|
+
backendId: buildAcpBackendId("qwen"),
|
|
107
|
+
displayName: "Qwen Code",
|
|
108
|
+
authors: ["Qwen Team"],
|
|
109
|
+
license: "Apache-2.0",
|
|
110
|
+
repositoryUrl: "https://github.com/QwenLM/qwen-code",
|
|
111
|
+
discoveryProbe: {
|
|
112
|
+
command: "qwen",
|
|
113
|
+
versionArgs: ["--version"],
|
|
114
|
+
helpArgs: ["--help"],
|
|
115
|
+
helpMatches: /(^|\s)--acp(\s|,|$)/,
|
|
116
|
+
fallbackCommands: [
|
|
117
|
+
path3.join(homedir3(), ".qwen", "bin", "qwen"),
|
|
118
|
+
"/opt/homebrew/bin/qwen",
|
|
119
|
+
"/usr/local/bin/qwen"
|
|
120
|
+
]
|
|
121
|
+
},
|
|
122
|
+
spawn: {
|
|
123
|
+
command: "qwen",
|
|
124
|
+
args: ["--acp"]
|
|
125
|
+
},
|
|
126
|
+
// Qwen's thought chunks are noisy internal scaffolding — suppress them.
|
|
127
|
+
quirks: defaultQuirks({ surfaceThoughts: false, titleFrom: "topic-update" })
|
|
128
|
+
};
|
|
129
|
+
|
|
130
|
+
// src/strategies/index.ts
|
|
131
|
+
var BUILT_IN_ACP_STRATEGIES = [
|
|
132
|
+
geminiStrategy,
|
|
133
|
+
kimiStrategy,
|
|
134
|
+
grokStrategy,
|
|
135
|
+
qwenStrategy
|
|
136
|
+
];
|
|
137
|
+
function buildStrategyTable(strategies = BUILT_IN_ACP_STRATEGIES) {
|
|
138
|
+
const table = /* @__PURE__ */ new Map();
|
|
139
|
+
for (const strategy of strategies) {
|
|
140
|
+
table.set(strategy.id, strategy);
|
|
141
|
+
}
|
|
142
|
+
return table;
|
|
143
|
+
}
|
|
144
|
+
function strategyById(id, table = buildStrategyTable()) {
|
|
145
|
+
return table.get(id);
|
|
146
|
+
}
|
|
147
|
+
function strategyByBackendId(backendId, strategies = BUILT_IN_ACP_STRATEGIES) {
|
|
148
|
+
return strategies.find((strategy) => strategy.backendId === backendId);
|
|
149
|
+
}
|
|
150
|
+
|
|
151
|
+
export {
|
|
152
|
+
buildAcpBackendId,
|
|
153
|
+
defaultQuirks,
|
|
154
|
+
geminiStrategy,
|
|
155
|
+
grokStrategy,
|
|
156
|
+
kimiStrategy,
|
|
157
|
+
qwenStrategy,
|
|
158
|
+
BUILT_IN_ACP_STRATEGIES,
|
|
159
|
+
buildStrategyTable,
|
|
160
|
+
strategyById,
|
|
161
|
+
strategyByBackendId
|
|
162
|
+
};
|
|
163
|
+
//# sourceMappingURL=chunk-OFMIS7W6.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/strategies/strategy-types.ts","../src/strategies/gemini.ts","../src/strategies/grok.ts","../src/strategies/kimi.ts","../src/strategies/qwen.ts","../src/strategies/index.ts"],"sourcesContent":["// Per-agent quirks live in a registered strategy table, never as inline\n// `if (agentId === ...)` branches in the normalizer or client (KTD-A2). Adding a\n// 5th ACP agent is a new table entry — zero normalizer edits.\n//\n// A strategy carries three things:\n// • discovery — how to probe whether the CLI is installed + ACP-capable;\n// • spawn — the command + args that launch it in ACP stdio mode;\n// • quirks — normalization behavior toggles the normalizer READS\n// (e.g. whether agent \"thought\" chunks surface as messages,\n// where the thread title comes from).\n\nexport type LocalAcpProbeResult = {\n stdout?: string | Buffer;\n stderr?: string | Buffer;\n};\n\nexport type LocalAcpProbeOptions = {\n /** Budget for this probe spawn. An injected probe should honor it so a slow\n * CLI is reported as \"did not answer in time\", not as \"not installed\". */\n timeoutMs?: number | undefined;\n /** Fires when discovery is abandoned mid-probe. */\n signal?: AbortSignal | undefined;\n};\n\nexport type LocalAcpAgentProbe = (\n command: string,\n args: string[],\n options?: LocalAcpProbeOptions\n) => Promise<LocalAcpProbeResult>;\n\n/** How a strategy decides it is installed + ACP-capable on this machine. */\nexport type AcpDiscoveryProbe = {\n /** Args that print a version (probed first; failure = not installed). */\n versionArgs: string[];\n /** Args probed to confirm ACP support. When `helpMatches` is set the OUTPUT\n * must match it; when omitted, a SUCCESSFUL probe (exit 0) is itself the\n * signal — for args that are an ACP subcommand whose mere existence proves\n * capability (e.g. `kimi acp --help`). */\n helpArgs: string[];\n /** Regex the help/usage output must match for the agent to count as\n * ACP-capable. OMIT to rely on the help probe's EXIT CODE instead — more\n * robust than parsing help prose, which drifts across CLI versions. */\n helpMatches?: RegExp;\n /** Bare command name tried first. */\n command: string;\n /** Additional candidate command paths (Homebrew prefixes, `~/.<agent>/bin`, …). */\n fallbackCommands?: string[];\n};\n\n/** Launch invocation: how to spawn the CLI in ACP stdio server mode. */\nexport type AcpSpawnSpec = {\n /** Command to run (resolved against the discovered candidate at spawn time). */\n command: string;\n /** Args that put the CLI into ACP stdio server mode (e.g. `[\"--acp\"]`). */\n args: string[];\n /** Extra env to set when launching (e.g. Gemini workspace-trust). */\n env?: Record<string, string>;\n /** Extra args appended only when missing (e.g. Gemini `--skip-trust`). */\n ensureArgs?: string[];\n};\n\n/**\n * Normalization quirks the normalizer reads. NO agent-id literal ever appears\n * in the normalizer — it reads these fields off the strategy it was constructed\n * with. A synthetic strategy with different quirk values flows through the\n * normalizer with zero normalizer changes (asserted in tests).\n */\nexport type AcpAgentQuirks = {\n /**\n * Whether agent \"thought\"/reasoning chunks surface as assistant messages.\n * Qwen sets this false (its thoughts are noisy scaffolding); others true.\n */\n surfaceThoughts: boolean;\n /**\n * Where the auto-generated thread title comes from:\n * • \"topic-update\" — a `tool_call` titled `Update topic to: \"…\"` (Gemini/Kimi/Qwen);\n * • \"session-summary\" — a vendor `session_summary_generated` update (Grok);\n * • \"both\" — recognize either.\n */\n titleFrom: \"topic-update\" | \"session-summary\" | \"both\";\n /** Vendor notification methods routed through the same session/update path. */\n vendorNotificationMethods?: string[];\n};\n\nexport type AcpAgentStrategy = {\n /** Strategy id, also the registry id (`gemini`, `grok`, `kimi`, `qwen`, …). */\n id: string;\n /** Neutral backend id (`acp:<id>`) used as the thread/session correlation key. */\n backendId: string;\n displayName: string;\n authors: string[];\n license?: string;\n repositoryUrl?: string;\n discoveryProbe: AcpDiscoveryProbe;\n spawn: AcpSpawnSpec;\n quirks: AcpAgentQuirks;\n};\n\n/** Build the neutral backend id for a registry id. */\nexport function buildAcpBackendId(registryId: string): string {\n return `acp:${registryId}`;\n}\n\nconst DEFAULT_QUIRKS: AcpAgentQuirks = {\n surfaceThoughts: true,\n titleFrom: \"topic-update\"\n};\n\n/** Quirks for an unknown/synthetic strategy default to the common case. */\nexport function defaultQuirks(overrides: Partial<AcpAgentQuirks> = {}): AcpAgentQuirks {\n return { ...DEFAULT_QUIRKS, ...overrides };\n}\n","import { buildAcpBackendId, defaultQuirks, type AcpAgentStrategy } from \"./strategy-types\";\n\nexport const geminiStrategy: AcpAgentStrategy = {\n id: \"gemini\",\n backendId: buildAcpBackendId(\"gemini\"),\n displayName: \"Gemini CLI\",\n authors: [\"Google\"],\n discoveryProbe: {\n command: \"gemini\",\n versionArgs: [\"--version\"],\n helpArgs: [\"--help\"],\n helpMatches: /(^|\\s)--acp(\\s|,|$)/\n },\n spawn: {\n command: \"gemini\",\n args: [\"--acp\"],\n // Gemini refuses to operate without workspace trust; matching PwrAgnt's\n // launch-descriptor normalization, append --skip-trust + set the env flag.\n ensureArgs: [\"--skip-trust\"],\n env: { GEMINI_CLI_TRUST_WORKSPACE: \"true\" }\n },\n quirks: defaultQuirks({ surfaceThoughts: true, titleFrom: \"topic-update\" })\n};\n","import { homedir } from \"node:os\";\nimport path from \"node:path\";\nimport { buildAcpBackendId, defaultQuirks, type AcpAgentStrategy } from \"./strategy-types\";\n\nexport const grokStrategy: AcpAgentStrategy = {\n id: \"grok\",\n backendId: buildAcpBackendId(\"grok\"),\n displayName: \"Grok\",\n authors: [\"xAI\"],\n discoveryProbe: {\n command: \"grok\",\n versionArgs: [\"--version\"],\n helpArgs: [\"agent\", \"stdio\", \"--help\"],\n helpMatches: /Run the agent over stdio/i,\n fallbackCommands: [\n path.join(homedir(), \".grok\", \"bin\", \"grok\"),\n \"/opt/homebrew/bin/grok\",\n \"/usr/local/bin/grok\"\n ]\n },\n spawn: {\n command: \"grok\",\n args: [\"agent\", \"stdio\"]\n },\n // Grok auto-generates the thread title via its vendor notification\n // `_x.ai/session_notification` carrying `session_summary_generated`.\n quirks: defaultQuirks({\n surfaceThoughts: true,\n titleFrom: \"session-summary\",\n vendorNotificationMethods: [\"_x.ai/session_notification\"]\n })\n};\n","import { homedir } from \"node:os\";\nimport path from \"node:path\";\nimport { buildAcpBackendId, defaultQuirks, type AcpAgentStrategy } from \"./strategy-types\";\n\nexport const kimiStrategy: AcpAgentStrategy = {\n id: \"kimi\",\n backendId: buildAcpBackendId(\"kimi\"),\n displayName: \"Kimi Code CLI\",\n authors: [\"Moonshot AI\"],\n discoveryProbe: {\n command: \"kimi\",\n versionArgs: [\"--version\"],\n // Capability signal is the EXIT CODE of `kimi acp --help`, NOT its prose.\n // kimi's commander CLI exits non-zero for an unknown subcommand, so a\n // zero-exit proves the `acp` subcommand exists. No `helpMatches`: the help\n // wording has already drifted across kimi versions (0.11.0 prints \"Agent\n // Client Protocol (ACP) server over stdio\"), so matching it is fragile.\n helpArgs: [\"acp\", \"--help\"],\n // The official Kimi Code installer drops a standalone binary at\n // ~/.kimi-code/bin/kimi and does NOT add it to PATH — so a Finder-launched\n // app misses it without this fallback (mirrors grok/qwen).\n fallbackCommands: [\n path.join(homedir(), \".kimi-code\", \"bin\", \"kimi\"),\n \"/opt/homebrew/bin/kimi\",\n \"/usr/local/bin/kimi\"\n ]\n },\n spawn: {\n command: \"kimi\",\n args: [\"acp\"]\n },\n quirks: defaultQuirks({ surfaceThoughts: true, titleFrom: \"topic-update\" })\n};\n","import { homedir } from \"node:os\";\nimport path from \"node:path\";\nimport { buildAcpBackendId, defaultQuirks, type AcpAgentStrategy } from \"./strategy-types\";\n\nexport const qwenStrategy: AcpAgentStrategy = {\n id: \"qwen\",\n backendId: buildAcpBackendId(\"qwen\"),\n displayName: \"Qwen Code\",\n authors: [\"Qwen Team\"],\n license: \"Apache-2.0\",\n repositoryUrl: \"https://github.com/QwenLM/qwen-code\",\n discoveryProbe: {\n command: \"qwen\",\n versionArgs: [\"--version\"],\n helpArgs: [\"--help\"],\n helpMatches: /(^|\\s)--acp(\\s|,|$)/,\n fallbackCommands: [\n path.join(homedir(), \".qwen\", \"bin\", \"qwen\"),\n \"/opt/homebrew/bin/qwen\",\n \"/usr/local/bin/qwen\"\n ]\n },\n spawn: {\n command: \"qwen\",\n args: [\"--acp\"]\n },\n // Qwen's thought chunks are noisy internal scaffolding — suppress them.\n quirks: defaultQuirks({ surfaceThoughts: false, titleFrom: \"topic-update\" })\n};\n","// The strategy table. The four built-ins do not require the registry — the\n// registry (discovery/acp-registry.ts) is the EXTENSION path. Adding a 5th\n// agent is a new entry here, with zero normalizer/client edits.\n\nimport type { AcpAgentStrategy } from \"./strategy-types\";\nimport { geminiStrategy } from \"./gemini\";\nimport { grokStrategy } from \"./grok\";\nimport { kimiStrategy } from \"./kimi\";\nimport { qwenStrategy } from \"./qwen\";\n\nexport { geminiStrategy } from \"./gemini\";\nexport { grokStrategy } from \"./grok\";\nexport { kimiStrategy } from \"./kimi\";\nexport { qwenStrategy } from \"./qwen\";\n\nexport const BUILT_IN_ACP_STRATEGIES: readonly AcpAgentStrategy[] = [\n geminiStrategy,\n kimiStrategy,\n grokStrategy,\n qwenStrategy\n];\n\n/** Index a list of strategies by id (built-ins by default). */\nexport function buildStrategyTable(\n strategies: readonly AcpAgentStrategy[] = BUILT_IN_ACP_STRATEGIES\n): Map<string, AcpAgentStrategy> {\n const table = new Map<string, AcpAgentStrategy>();\n for (const strategy of strategies) {\n table.set(strategy.id, strategy);\n }\n return table;\n}\n\n/** Look up a strategy by its registry id, falling back to the built-in table. */\nexport function strategyById(\n id: string,\n table: Map<string, AcpAgentStrategy> = buildStrategyTable()\n): AcpAgentStrategy | undefined {\n return table.get(id);\n}\n\n/** Look up a strategy by its neutral backend id (`acp:<id>`). */\nexport function strategyByBackendId(\n backendId: string,\n strategies: readonly AcpAgentStrategy[] = BUILT_IN_ACP_STRATEGIES\n): AcpAgentStrategy | undefined {\n return strategies.find((strategy) => strategy.backendId === backendId);\n}\n"],"mappings":";AAmGO,SAAS,kBAAkB,YAA4B;AAC5D,SAAO,OAAO,UAAU;AAC1B;AAEA,IAAM,iBAAiC;AAAA,EACrC,iBAAiB;AAAA,EACjB,WAAW;AACb;AAGO,SAAS,cAAc,YAAqC,CAAC,GAAmB;AACrF,SAAO,EAAE,GAAG,gBAAgB,GAAG,UAAU;AAC3C;;;AC7GO,IAAM,iBAAmC;AAAA,EAC9C,IAAI;AAAA,EACJ,WAAW,kBAAkB,QAAQ;AAAA,EACrC,aAAa;AAAA,EACb,SAAS,CAAC,QAAQ;AAAA,EAClB,gBAAgB;AAAA,IACd,SAAS;AAAA,IACT,aAAa,CAAC,WAAW;AAAA,IACzB,UAAU,CAAC,QAAQ;AAAA,IACnB,aAAa;AAAA,EACf;AAAA,EACA,OAAO;AAAA,IACL,SAAS;AAAA,IACT,MAAM,CAAC,OAAO;AAAA;AAAA;AAAA,IAGd,YAAY,CAAC,cAAc;AAAA,IAC3B,KAAK,EAAE,4BAA4B,OAAO;AAAA,EAC5C;AAAA,EACA,QAAQ,cAAc,EAAE,iBAAiB,MAAM,WAAW,eAAe,CAAC;AAC5E;;;ACtBA,SAAS,eAAe;AACxB,OAAO,UAAU;AAGV,IAAM,eAAiC;AAAA,EAC5C,IAAI;AAAA,EACJ,WAAW,kBAAkB,MAAM;AAAA,EACnC,aAAa;AAAA,EACb,SAAS,CAAC,KAAK;AAAA,EACf,gBAAgB;AAAA,IACd,SAAS;AAAA,IACT,aAAa,CAAC,WAAW;AAAA,IACzB,UAAU,CAAC,SAAS,SAAS,QAAQ;AAAA,IACrC,aAAa;AAAA,IACb,kBAAkB;AAAA,MAChB,KAAK,KAAK,QAAQ,GAAG,SAAS,OAAO,MAAM;AAAA,MAC3C;AAAA,MACA;AAAA,IACF;AAAA,EACF;AAAA,EACA,OAAO;AAAA,IACL,SAAS;AAAA,IACT,MAAM,CAAC,SAAS,OAAO;AAAA,EACzB;AAAA;AAAA;AAAA,EAGA,QAAQ,cAAc;AAAA,IACpB,iBAAiB;AAAA,IACjB,WAAW;AAAA,IACX,2BAA2B,CAAC,4BAA4B;AAAA,EAC1D,CAAC;AACH;;;AC/BA,SAAS,WAAAA,gBAAe;AACxB,OAAOC,WAAU;AAGV,IAAM,eAAiC;AAAA,EAC5C,IAAI;AAAA,EACJ,WAAW,kBAAkB,MAAM;AAAA,EACnC,aAAa;AAAA,EACb,SAAS,CAAC,aAAa;AAAA,EACvB,gBAAgB;AAAA,IACd,SAAS;AAAA,IACT,aAAa,CAAC,WAAW;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,IAMzB,UAAU,CAAC,OAAO,QAAQ;AAAA;AAAA;AAAA;AAAA,IAI1B,kBAAkB;AAAA,MAChBC,MAAK,KAAKC,SAAQ,GAAG,cAAc,OAAO,MAAM;AAAA,MAChD;AAAA,MACA;AAAA,IACF;AAAA,EACF;AAAA,EACA,OAAO;AAAA,IACL,SAAS;AAAA,IACT,MAAM,CAAC,KAAK;AAAA,EACd;AAAA,EACA,QAAQ,cAAc,EAAE,iBAAiB,MAAM,WAAW,eAAe,CAAC;AAC5E;;;AChCA,SAAS,WAAAC,gBAAe;AACxB,OAAOC,WAAU;AAGV,IAAM,eAAiC;AAAA,EAC5C,IAAI;AAAA,EACJ,WAAW,kBAAkB,MAAM;AAAA,EACnC,aAAa;AAAA,EACb,SAAS,CAAC,WAAW;AAAA,EACrB,SAAS;AAAA,EACT,eAAe;AAAA,EACf,gBAAgB;AAAA,IACd,SAAS;AAAA,IACT,aAAa,CAAC,WAAW;AAAA,IACzB,UAAU,CAAC,QAAQ;AAAA,IACnB,aAAa;AAAA,IACb,kBAAkB;AAAA,MAChBC,MAAK,KAAKC,SAAQ,GAAG,SAAS,OAAO,MAAM;AAAA,MAC3C;AAAA,MACA;AAAA,IACF;AAAA,EACF;AAAA,EACA,OAAO;AAAA,IACL,SAAS;AAAA,IACT,MAAM,CAAC,OAAO;AAAA,EAChB;AAAA;AAAA,EAEA,QAAQ,cAAc,EAAE,iBAAiB,OAAO,WAAW,eAAe,CAAC;AAC7E;;;ACbO,IAAM,0BAAuD;AAAA,EAClE;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF;AAGO,SAAS,mBACd,aAA0C,yBACX;AAC/B,QAAM,QAAQ,oBAAI,IAA8B;AAChD,aAAW,YAAY,YAAY;AACjC,UAAM,IAAI,SAAS,IAAI,QAAQ;AAAA,EACjC;AACA,SAAO;AACT;AAGO,SAAS,aACd,IACA,QAAuC,mBAAmB,GAC5B;AAC9B,SAAO,MAAM,IAAI,EAAE;AACrB;AAGO,SAAS,oBACd,WACA,aAA0C,yBACZ;AAC9B,SAAO,WAAW,KAAK,CAAC,aAAa,SAAS,cAAc,SAAS;AACvE;","names":["homedir","path","path","homedir","homedir","path","path","homedir"]}
|
|
@@ -0,0 +1,223 @@
|
|
|
1
|
+
import { L as LocalAcpAgentProbe, a as AcpAgentStrategy } from './strategy-types-C7yw6yQL.js';
|
|
2
|
+
|
|
3
|
+
/** How a discovered instance's executable path was located. */
|
|
4
|
+
type AcpAgentInstanceSource = "override" | "path" | "fallback";
|
|
5
|
+
/** One installed executable of an agent that passed the probe. */
|
|
6
|
+
type DiscoveredAcpAgentInstance = {
|
|
7
|
+
/** Resolved command/path that passed the probe. */
|
|
8
|
+
command: string;
|
|
9
|
+
/** Parsed CLI version, when the version probe yielded one. */
|
|
10
|
+
version?: string;
|
|
11
|
+
/** Where this candidate came from (user override, `PATH`, or a fallback path). */
|
|
12
|
+
source: AcpAgentInstanceSource;
|
|
13
|
+
};
|
|
14
|
+
/** A detected executable that did not satisfy a strategy's discovery probe.
|
|
15
|
+
* It is diagnostic-only: hosts must never use it to launch an ACP session. */
|
|
16
|
+
type RejectedAcpAgentInstance = {
|
|
17
|
+
command: string;
|
|
18
|
+
/** Parsed from successful `--version` output when available. */
|
|
19
|
+
version?: string;
|
|
20
|
+
source: AcpAgentInstanceSource;
|
|
21
|
+
/** `probe-timed-out` means the CLI did not answer within the probe budget —
|
|
22
|
+
* UNLIKE the other reasons it is not a verdict on the CLI, and a host may
|
|
23
|
+
* re-probe on a larger `probeTimeoutMs` instead of reporting it unusable. */
|
|
24
|
+
reason: "version-probe-failed" | "acp-probe-failed" | "acp-help-mismatch" | "probe-timed-out";
|
|
25
|
+
};
|
|
26
|
+
/** Every installed instance of one agent found on this machine. */
|
|
27
|
+
type DiscoveredAcpAgentGroup = {
|
|
28
|
+
strategyId: string;
|
|
29
|
+
backendId: string;
|
|
30
|
+
name: string;
|
|
31
|
+
/** Spawn args that put it into ACP stdio mode (same for every instance). */
|
|
32
|
+
args: string[];
|
|
33
|
+
/** Extra env to set at launch (same for every instance). */
|
|
34
|
+
env: Record<string, string>;
|
|
35
|
+
/** All instances that passed the probe, in candidate order (override → PATH → fallback). */
|
|
36
|
+
instances: DiscoveredAcpAgentInstance[];
|
|
37
|
+
/** Detected candidates that failed the version or ACP-capability probe. Only
|
|
38
|
+
* populated when `includeRejectedCandidates` is enabled. */
|
|
39
|
+
rejectedInstances?: RejectedAcpAgentInstance[];
|
|
40
|
+
discoveredAt: number;
|
|
41
|
+
};
|
|
42
|
+
type DiscoveredAcpAgent = {
|
|
43
|
+
strategyId: string;
|
|
44
|
+
backendId: string;
|
|
45
|
+
name: string;
|
|
46
|
+
version?: string;
|
|
47
|
+
/** Resolved command that passed the probe (may be a fallback path). */
|
|
48
|
+
command: string;
|
|
49
|
+
/** Spawn args that put it into ACP stdio mode. */
|
|
50
|
+
args: string[];
|
|
51
|
+
/** Extra env to set at launch. */
|
|
52
|
+
env: Record<string, string>;
|
|
53
|
+
discoveredAt: number;
|
|
54
|
+
};
|
|
55
|
+
/** Lists every executable named `command` across the dirs in `env.PATH`,
|
|
56
|
+
* in `PATH` order (the `which -a` view). */
|
|
57
|
+
type AcpPathExecutableLister = (command: string, env: NodeJS.ProcessEnv) => string[];
|
|
58
|
+
type LocalAcpDiscoveryOptions = {
|
|
59
|
+
probe?: LocalAcpAgentProbe;
|
|
60
|
+
now?: () => number;
|
|
61
|
+
/** Strategy table to probe (built-ins by default). */
|
|
62
|
+
strategies?: readonly AcpAgentStrategy[];
|
|
63
|
+
/** Per-strategy command override (tried before the strategy's own candidates). */
|
|
64
|
+
overrides?: Record<string, string>;
|
|
65
|
+
/** Env used both for PATH enumeration and (by the default probe) for spawns. */
|
|
66
|
+
env?: NodeJS.ProcessEnv;
|
|
67
|
+
/** Injectable `PATH` executable lister (real-fs scan by default). */
|
|
68
|
+
listExecutables?: AcpPathExecutableLister;
|
|
69
|
+
/** Include candidates known to exist but rejected by a discovery probe.
|
|
70
|
+
* Defaults false to preserve the legacy installed-only result. */
|
|
71
|
+
includeRejectedCandidates?: boolean;
|
|
72
|
+
/** Budget for ONE probe spawn (the default probe only — an injected `probe`
|
|
73
|
+
* owns its own timing). Defaults to `DEFAULT_ACP_PROBE_TIMEOUT_MS`. */
|
|
74
|
+
probeTimeoutMs?: number;
|
|
75
|
+
/** Abandon discovery in flight (re-triggered discovery, app quitting).
|
|
76
|
+
* Already-probed groups are still returned. */
|
|
77
|
+
signal?: AbortSignal;
|
|
78
|
+
};
|
|
79
|
+
/**
|
|
80
|
+
* Budget for one ACP discovery probe spawn, in ms.
|
|
81
|
+
*
|
|
82
|
+
* Unchanged from the value this module has always used. Kept lower than
|
|
83
|
+
* codex-discovery's version-probe budget on purpose: `discoverStrategyInstances`
|
|
84
|
+
* walks its candidates SERIALLY, so the worst case here is (candidates x
|
|
85
|
+
* budget) rather than a single budget. Hosts that scan machines with many
|
|
86
|
+
* installed copies can raise it knowingly via `probeTimeoutMs`.
|
|
87
|
+
*/
|
|
88
|
+
declare const DEFAULT_ACP_PROBE_TIMEOUT_MS = 5000;
|
|
89
|
+
/**
|
|
90
|
+
* Discover every installed instance of each agent (all `PATH` matches +
|
|
91
|
+
* fallbacks + override that pass the probe), grouped per strategy. Groups with
|
|
92
|
+
* no passing instance are omitted unless `includeRejectedCandidates` is true
|
|
93
|
+
* and a detected candidate failed a probe.
|
|
94
|
+
*/
|
|
95
|
+
declare function discoverLocalAcpAgentInstances(options?: LocalAcpDiscoveryOptions): Promise<DiscoveredAcpAgentGroup[]>;
|
|
96
|
+
/**
|
|
97
|
+
* First-match-per-agent discovery (legacy view). Returns at most one record per
|
|
98
|
+
* agent — the first instance that passed the probe in candidate order.
|
|
99
|
+
*/
|
|
100
|
+
declare function discoverLocalAcpAgents(options?: LocalAcpDiscoveryOptions): Promise<DiscoveredAcpAgent[]>;
|
|
101
|
+
/** Well-known bin dirs where a CLI installed via a node/JS version manager or
|
|
102
|
+
* a per-user package manager lives — even when it isn't on a GUI app's `PATH`.
|
|
103
|
+
* Exported for testing; `home` defaults to the user's home dir. */
|
|
104
|
+
declare function wellKnownAgentBinDirs(home?: string): string[];
|
|
105
|
+
|
|
106
|
+
declare const ACP_REGISTRY_URL = "https://cdn.agentclientprotocol.com/registry/v1/latest/registry.json";
|
|
107
|
+
type AcpDistributionKind = "npx" | "uvx" | "binary" | "local";
|
|
108
|
+
type AcpRegistryDistributionEnv = Record<string, string>;
|
|
109
|
+
type AcpPackageDistribution = {
|
|
110
|
+
kind: "npx" | "uvx";
|
|
111
|
+
packageName: string;
|
|
112
|
+
args: string[];
|
|
113
|
+
env: AcpRegistryDistributionEnv;
|
|
114
|
+
};
|
|
115
|
+
type AcpBinaryPlatformDistribution = {
|
|
116
|
+
kind: "binary";
|
|
117
|
+
platform: string;
|
|
118
|
+
archiveUrl: string;
|
|
119
|
+
command: string;
|
|
120
|
+
args: string[];
|
|
121
|
+
env: AcpRegistryDistributionEnv;
|
|
122
|
+
checksum?: string;
|
|
123
|
+
signatureUrl?: string;
|
|
124
|
+
};
|
|
125
|
+
type AcpRegistryDistribution = AcpPackageDistribution | AcpBinaryPlatformDistribution;
|
|
126
|
+
type AcpRegistryAuthMethod = "agent-managed" | "terminal" | "unknown";
|
|
127
|
+
type AcpRegistryAuthDescriptor = {
|
|
128
|
+
required: boolean;
|
|
129
|
+
methods: AcpRegistryAuthMethod[];
|
|
130
|
+
raw?: unknown;
|
|
131
|
+
};
|
|
132
|
+
type AcpRegistryAgent = {
|
|
133
|
+
id: string;
|
|
134
|
+
backendId: string;
|
|
135
|
+
name: string;
|
|
136
|
+
version?: string;
|
|
137
|
+
description?: string;
|
|
138
|
+
authors: string[];
|
|
139
|
+
license?: string;
|
|
140
|
+
repositoryUrl?: string;
|
|
141
|
+
websiteUrl?: string;
|
|
142
|
+
iconUrl?: string;
|
|
143
|
+
distributions: AcpRegistryDistribution[];
|
|
144
|
+
distributionKinds: AcpDistributionKind[];
|
|
145
|
+
auth: AcpRegistryAuthDescriptor;
|
|
146
|
+
raw: unknown;
|
|
147
|
+
};
|
|
148
|
+
type AcpVerificationStatus = "verified" | "unverified-allowed" | "unverified-blocked" | "not-applicable";
|
|
149
|
+
type AcpAllowlistDecision = {
|
|
150
|
+
allowed: true;
|
|
151
|
+
ruleId: string;
|
|
152
|
+
unverifiedBinaryAllowed: boolean;
|
|
153
|
+
} | {
|
|
154
|
+
allowed: false;
|
|
155
|
+
reason: string;
|
|
156
|
+
};
|
|
157
|
+
type AcpRegistryAgentWithPolicy = AcpRegistryAgent & {
|
|
158
|
+
allowlist: AcpAllowlistDecision;
|
|
159
|
+
installable: boolean;
|
|
160
|
+
unavailableReason?: string;
|
|
161
|
+
verificationStatus: AcpVerificationStatus;
|
|
162
|
+
};
|
|
163
|
+
type AcpRegistrySnapshot = {
|
|
164
|
+
fetchedAt: number;
|
|
165
|
+
agents: AcpRegistryAgent[];
|
|
166
|
+
raw: unknown;
|
|
167
|
+
};
|
|
168
|
+
|
|
169
|
+
type AcpAgentAllowlistRule = {
|
|
170
|
+
id: string;
|
|
171
|
+
registryId: string;
|
|
172
|
+
versions?: string[];
|
|
173
|
+
distributionKinds?: AcpDistributionKind[];
|
|
174
|
+
allowedPackageNames?: string[];
|
|
175
|
+
allowedArchiveHosts?: string[];
|
|
176
|
+
allowUnverifiedBinary?: boolean;
|
|
177
|
+
allowGplFamilyLicense?: boolean;
|
|
178
|
+
};
|
|
179
|
+
declare const BANNED_ACP_REGISTRY_IDS: Set<string>;
|
|
180
|
+
declare const DEFAULT_ACP_AGENT_ALLOWLIST: AcpAgentAllowlistRule[];
|
|
181
|
+
declare class AcpAgentAllowlist {
|
|
182
|
+
private readonly rules;
|
|
183
|
+
constructor(rules: AcpAgentAllowlistRule[]);
|
|
184
|
+
evaluate(agent: AcpRegistryAgent): AcpAllowlistDecision;
|
|
185
|
+
evaluateDistribution(agent: AcpRegistryAgent, distribution: AcpRegistryDistribution): AcpAllowlistDecision;
|
|
186
|
+
}
|
|
187
|
+
declare const defaultAcpAgentAllowlist: AcpAgentAllowlist;
|
|
188
|
+
declare function isBannedAcpRegistryId(registryId: string): boolean;
|
|
189
|
+
|
|
190
|
+
type AcpRegistryFetch = (input: string, init?: {
|
|
191
|
+
headers?: Record<string, string>;
|
|
192
|
+
}) => Promise<{
|
|
193
|
+
ok: boolean;
|
|
194
|
+
status: number;
|
|
195
|
+
statusText: string;
|
|
196
|
+
json(): Promise<unknown>;
|
|
197
|
+
}>;
|
|
198
|
+
type AcpRegistryServiceOptions = {
|
|
199
|
+
allowlist?: AcpAgentAllowlist;
|
|
200
|
+
fetch?: AcpRegistryFetch;
|
|
201
|
+
now?: () => number;
|
|
202
|
+
registryUrl?: string;
|
|
203
|
+
};
|
|
204
|
+
type AcpDistributionPolicy = {
|
|
205
|
+
allowlist: AcpAllowlistDecision;
|
|
206
|
+
installable: boolean;
|
|
207
|
+
verificationStatus: AcpVerificationStatus;
|
|
208
|
+
unavailableReason?: string;
|
|
209
|
+
};
|
|
210
|
+
declare class AcpRegistryService {
|
|
211
|
+
private readonly allowlist;
|
|
212
|
+
private readonly fetcher;
|
|
213
|
+
private readonly now;
|
|
214
|
+
private readonly registryUrl;
|
|
215
|
+
constructor(options?: AcpRegistryServiceOptions);
|
|
216
|
+
fetchRegistry(): Promise<AcpRegistrySnapshot>;
|
|
217
|
+
applyAllowlist(snapshot: AcpRegistrySnapshot): AcpRegistryAgentWithPolicy[];
|
|
218
|
+
evaluateDistribution(agent: AcpRegistryAgent, distribution: AcpRegistryDistribution): AcpDistributionPolicy;
|
|
219
|
+
}
|
|
220
|
+
declare function evaluateAcpDistributionPolicy(distribution: AcpRegistryDistribution, allowlist: AcpAllowlistDecision): AcpDistributionPolicy;
|
|
221
|
+
declare function normalizeRegistry(raw: unknown): AcpRegistryAgent[];
|
|
222
|
+
|
|
223
|
+
export { ACP_REGISTRY_URL, AcpAgentAllowlist, type AcpAgentAllowlistRule, type AcpAgentInstanceSource, type AcpAllowlistDecision, type AcpBinaryPlatformDistribution, type AcpDistributionKind, type AcpDistributionPolicy, type AcpPackageDistribution, type AcpPathExecutableLister, type AcpRegistryAgent, type AcpRegistryAgentWithPolicy, type AcpRegistryAuthDescriptor, type AcpRegistryAuthMethod, type AcpRegistryDistribution, type AcpRegistryFetch, AcpRegistryService, type AcpRegistryServiceOptions, type AcpRegistrySnapshot, type AcpVerificationStatus, BANNED_ACP_REGISTRY_IDS, DEFAULT_ACP_AGENT_ALLOWLIST, DEFAULT_ACP_PROBE_TIMEOUT_MS, type DiscoveredAcpAgent, type DiscoveredAcpAgentGroup, type DiscoveredAcpAgentInstance, type LocalAcpDiscoveryOptions, type RejectedAcpAgentInstance, defaultAcpAgentAllowlist, discoverLocalAcpAgentInstances, discoverLocalAcpAgents, evaluateAcpDistributionPolicy, isBannedAcpRegistryId, normalizeRegistry, wellKnownAgentBinDirs };
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
import {
|
|
2
|
+
ACP_REGISTRY_URL,
|
|
3
|
+
AcpAgentAllowlist,
|
|
4
|
+
AcpRegistryService,
|
|
5
|
+
BANNED_ACP_REGISTRY_IDS,
|
|
6
|
+
DEFAULT_ACP_AGENT_ALLOWLIST,
|
|
7
|
+
DEFAULT_ACP_PROBE_TIMEOUT_MS,
|
|
8
|
+
defaultAcpAgentAllowlist,
|
|
9
|
+
discoverLocalAcpAgentInstances,
|
|
10
|
+
discoverLocalAcpAgents,
|
|
11
|
+
evaluateAcpDistributionPolicy,
|
|
12
|
+
isBannedAcpRegistryId,
|
|
13
|
+
normalizeRegistry,
|
|
14
|
+
wellKnownAgentBinDirs
|
|
15
|
+
} from "./chunk-GCWY5T5H.js";
|
|
16
|
+
import "./chunk-OFMIS7W6.js";
|
|
17
|
+
export {
|
|
18
|
+
ACP_REGISTRY_URL,
|
|
19
|
+
AcpAgentAllowlist,
|
|
20
|
+
AcpRegistryService,
|
|
21
|
+
BANNED_ACP_REGISTRY_IDS,
|
|
22
|
+
DEFAULT_ACP_AGENT_ALLOWLIST,
|
|
23
|
+
DEFAULT_ACP_PROBE_TIMEOUT_MS,
|
|
24
|
+
defaultAcpAgentAllowlist,
|
|
25
|
+
discoverLocalAcpAgentInstances,
|
|
26
|
+
discoverLocalAcpAgents,
|
|
27
|
+
evaluateAcpDistributionPolicy,
|
|
28
|
+
isBannedAcpRegistryId,
|
|
29
|
+
normalizeRegistry,
|
|
30
|
+
wellKnownAgentBinDirs
|
|
31
|
+
};
|
|
32
|
+
//# sourceMappingURL=discovery.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":[],"sourcesContent":[],"mappings":"","names":[]}
|