provider-snapshot no longer returns null for uninstalled/disabled providers: it emits one entry per registered provider with a lifecycle status (loading|ready|unavailable|error), an enabled flag, and a two-tier probe. Tier-1 is a fast which-style check (command-availability.ts, execFile/no-shell); tier-2 (cold ACP probe) is skipped unless forced, last_probed_at is older than PROVIDER_PROBE_TTL_MS (24h), or DB models are empty — the snapshot-latency win. Cache miss returns status:'loading' synchronously while the build settles via the existing inflight promise. ProviderSnapshotStatus/Entry regain loading/unavailable + gain enabled/description?/fetchedAt? in both coder and web copies, guarded by a runtime parity test (provider-types-parity.test.ts; compile-time cross-project check was blocked by TS6307). Also tracks the data/coder-providers.json seed via a .gitignore exception, completing the Phase 1 config file. No dispatch/route/UI changes (Phase 3+); AgentComposerBar filtering unchanged. 13 snapshot tests (+6) + 6 parity tests. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
23 lines
865 B
TypeScript
23 lines
865 B
TypeScript
/**
|
|
* v2.3 phase 2: tier-1 fast availability check — is a binary on PATH?
|
|
*
|
|
* Uses execFile (NO shell) because the binary name can come from the provider
|
|
* config file (custom ACP entries) — mirrors the Phase 1 agent-probe hardening.
|
|
* Note: agent-probe's `whichBinary` returns the resolved path (it needs it for
|
|
* `install_path`); this returns a boolean. Kept separate rather than over-
|
|
* refactored into one helper — different return contracts, two short call sites.
|
|
*/
|
|
import { execFile as execFileCb } from 'node:child_process';
|
|
import { promisify } from 'node:util';
|
|
|
|
const execFile = promisify(execFileCb);
|
|
|
|
export async function isCommandAvailable(binary: string): Promise<boolean> {
|
|
try {
|
|
const { stdout } = await execFile('which', [binary], { timeout: 10_000 });
|
|
return stdout.trim().length > 0;
|
|
} catch {
|
|
return false;
|
|
}
|
|
}
|