@agentproto/cli 0.5.0 → 0.7.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
@@ -1,4 +1,6 @@
1
1
  import { AgentCliMode, AgentCliHandle } from '@agentproto/driver-agent-cli';
2
+ import { AdapterCatalogEntry } from '@agentproto/provider-kit';
3
+ import { AcpAgentConfigEntry, AgentprotoConfig } from '@agentproto/runtime/config';
2
4
 
3
5
  /**
4
6
  * `agentproto install <slug>`
@@ -76,6 +78,26 @@ declare function runRun(args: readonly string[]): Promise<number>;
76
78
  */
77
79
  declare function runServe(args: readonly string[]): Promise<number>;
78
80
 
81
+ /**
82
+ * `agentproto acp <subcommand>`
83
+ *
84
+ * Manage generic ACP agents — any CLI that already speaks the Agent
85
+ * Client Protocol, connectable with zero adapter code (see
86
+ * ../registry/acp-generic.ts).
87
+ *
88
+ * Subcommands:
89
+ * ls curated catalog + config agents, with status
90
+ * add <slug> --bin <bin> [--args …] write a config.acpAgents entry
91
+ * [--name] [--desc] [--env]
92
+ * [--resumable]
93
+ * rm <slug> remove a config.acpAgents entry
94
+ *
95
+ * `ls` reflects both the built-in `ACP_CATALOG` and the user's
96
+ * `~/.agentproto/config.json` `acpAgents`; `add`/`rm` only ever touch the
97
+ * config file — the curated catalog is read-only.
98
+ */
99
+ declare function runAcp(args: readonly string[]): Promise<number>;
100
+
79
101
  /**
80
102
  * Resolve a slug like "claude-code" to a runnable `AgentCliHandle`.
81
103
  *
@@ -99,8 +121,15 @@ interface AgentCliCommand {
99
121
  interface ResolvedAdapter {
100
122
  readonly slug: string;
101
123
  readonly handle: AgentCliHandle;
102
- readonly source: "npm" | "file" | "bundled";
124
+ readonly source: "npm" | "file" | "bundled" | "acp-config" | "acp-catalog";
103
125
  readonly packageName?: string;
126
+ /** True when this resolution was served from the last-known-good cache
127
+ * because the current import attempt failed (see `importFresh`'s doc
128
+ * comment for why that happens mid-rebuild). Never present on an
129
+ * actually-fresh successful resolution — callers that only care about
130
+ * spawning don't need to check it, callers that surface status
131
+ * (`listAdaptersWithCatalog`) must not report it as plain "ready". */
132
+ readonly stale?: true;
104
133
  }
105
134
  /** Mode metadata surfaced in `adapter_list` — the UI-safe subset of an
106
135
  * AIP-45 `modes[]` entry. Omits the spawn internals (`bin_args_*`, `env`)
@@ -141,13 +170,36 @@ interface AdapterInfo {
141
170
  * adapter manifest's `models.allowed` field. Empty when the adapter
142
171
  * doesn't declare a model list (accepts whatever the underlying
143
172
  * binary accepts). Pass one of these as `model` in `agent_start`
144
- * to avoid trial-and-error validation errors. */
173
+ * to avoid trial-and-error validation errors. Flat id list — kept
174
+ * exactly as before so every existing consumer of this field keeps
175
+ * working untouched; see `modelDetails` for the provider/mode a
176
+ * structured entry additionally states. */
145
177
  models: string[];
146
178
  /** AIP-45 `modes[]` the adapter declares, projected to the UI-safe
147
179
  * subset (id + description + honest status). Empty when the adapter
148
180
  * declares no modes. `status` defaults to "active" when the manifest
149
181
  * omits it, so a declared mode is never silently statusless. */
150
182
  modes: AdapterMode[];
183
+ /** Same models as `models`, in the same order, each carrying the
184
+ * `provider`/`mode` a structured `models.allowed` entry states.
185
+ * `provider`/`mode` are undefined for a bare-string entry — an
186
+ * unstated provider is never guessed here (see AdapterModelInfo). */
187
+ modelDetails: AdapterModelInfo[];
188
+ }
189
+ /** One entry of an adapter's declared model menu, projected from a
190
+ * `models.allowed` item — bare string or {@link AgentCliModelEntry}.
191
+ * `provider`/`mode` stay undefined for a bare-string entry: an unstated
192
+ * provider must never be guessed downstream (a wrong-but-confident
193
+ * guess would bill the wrong account). See AGENTS.md / AIP-45 for the
194
+ * three-facts-in-one-string problem this splits apart. */
195
+ interface AdapterModelInfo {
196
+ id: string;
197
+ /** Who serves/bills this model (a ProviderPreset id, or a direct
198
+ * provider like "anthropic"). Undefined when unstated. */
199
+ provider?: string;
200
+ /** This adapter's mode id that routes to `provider`. Undefined when
201
+ * the adapter routes on its own or needs no mode switch. */
202
+ mode?: string;
151
203
  }
152
204
  declare function resolveAdapter(slug: string): Promise<ResolvedAdapter>;
153
205
  /**
@@ -174,5 +226,147 @@ declare function listInstalledAdapters(opts?: {
174
226
  * package's own location until we hit a `node_modules/@agentproto`. */
175
227
  searchRoot?: string;
176
228
  }): Promise<AdapterInfo[]>;
229
+ /**
230
+ * Enumerate adapters starting from a static catalog and enriching each entry
231
+ * with its runtime availability status:
232
+ *
233
+ * "supported" — known to agentproto, package not importable (not installed)
234
+ * "available" — package resolves; requiresSetup but no ledger yet
235
+ * "ready" — package resolves + setup complete (or no setup needed)
236
+ *
237
+ * Also appends any adapters discovered in node_modules that aren't in the
238
+ * catalog, so locally-installed custom adapters still appear.
239
+ *
240
+ * Status is derived via the kit's `computeStatus`: resolved × requiresSetup ×
241
+ * ledger-exists — never via `handle.check()` (per OQ-5).
242
+ *
243
+ * A fourth status, `"unresolvable"`, sits outside that kit-owned vocabulary:
244
+ * when `resolveAdapter` falls back to its last-known-good cache (see there),
245
+ * the kit sees a normally-resolved handle and would compute "ready" — which
246
+ * would silently hide the fact that the CURRENT import attempt just failed.
247
+ * `resolved.stale` (threaded through `wrapCliHandle` → `AgentCliInfo`) is
248
+ * checked below and overrides whatever the kit computed, so a rebuilding
249
+ * adapter reads as neither "ready" (a lie — a spawn against a half-written
250
+ * dist would still fail) nor "supported" (equally wrong — it tells the
251
+ * operator to reinstall something that's already there).
252
+ */
253
+ declare function listAdaptersWithCatalog(catalog: readonly AdapterCatalogEntry[]): Promise<(AdapterInfo & {
254
+ status: "supported" | "available" | "ready" | "unresolvable";
255
+ hint?: string;
256
+ })[]>;
257
+ /** A single row of the merged adapter listing — npm/native catalog
258
+ * entries and generic ACP entries share this shape (the latter also
259
+ * carry a `source`). */
260
+ type AdapterListing = AdapterInfo & {
261
+ status: "supported" | "available" | "ready" | "unresolvable";
262
+ hint?: string;
263
+ source?: "acp-config" | "acp-catalog";
264
+ };
265
+ /**
266
+ * The full adapter listing surfaced by `adapter_list` / `GET /adapters`:
267
+ * every npm/native catalog adapter PLUS the generic ACP agents (curated
268
+ * `ACP_CATALOG` + user `config.acpAgents`). Generic entries whose slug is
269
+ * already covered by a native adapter are dropped, so a slug never appears
270
+ * twice. Native adapters keep their richer status (`ready` after setup);
271
+ * generic entries are `available` (bin on PATH) or `supported` (not yet).
272
+ */
273
+ declare function listAdaptersWithAcp(catalog: readonly AdapterCatalogEntry[]): Promise<AdapterListing[]>;
274
+
275
+ /**
276
+ * Generic ACP agents — connect any ACP-speaking CLI with zero adapter code.
277
+ *
278
+ * Our ACP protocol arm (`createAcpProtocolArm`) is fully adapter-agnostic:
279
+ * it performs the standard `initialize` / `session/new` handshake over stdio
280
+ * JSON-RPC and streams turns, regardless of which binary is on the other end.
281
+ * So any CLI that already speaks the Agent Client Protocol doesn't need a
282
+ * bespoke `@agentproto/adapter-*` package — it just needs a spawn recipe.
283
+ *
284
+ * `acpHandleFromSpec` mints a runnable `AgentCliHandle` from a plain
285
+ * `AcpAgentSpec` (bin + args + env + a few flags). Two sources feed it:
286
+ * - `ACP_CATALOG` — a conservative, curated list of known ACP CLIs.
287
+ * - `config.acpAgents` — user-defined entries in `~/.agentproto/config.json`.
288
+ * User entries shadow the catalog on slug collision.
289
+ *
290
+ * `resolveAdapter` (see ./resolve.ts) tries npm first, then these; so a real
291
+ * adapter package always wins over a generic spec of the same slug.
292
+ */
293
+
294
+ /**
295
+ * A generic ACP agent's spawn recipe. The config-file form
296
+ * (`AcpAgentConfigEntry`, keyed by slug in `acpAgents`) plus the slug
297
+ * itself. Kept in sync with the runtime config type by extension so the
298
+ * two never drift.
299
+ */
300
+ interface AcpAgentSpec extends AcpAgentConfigEntry {
301
+ /** Adapter slug, e.g. "gemini-cli". Lower-kebab, ≥3 chars (AIP-45 id). */
302
+ slug: string;
303
+ }
304
+ /** Distinguishes where a resolved generic handle came from. */
305
+ type AcpSpecSource = "acp-config" | "acp-catalog";
306
+ /**
307
+ * Mint a runnable `AgentCliHandle` from a plain spec by routing every
308
+ * field through `defineAgentCli` with `protocol: "acp"`. The result is a
309
+ * fully-validated AIP-45 handle — schema-identical to a hand-authored
310
+ * native ACP adapter, just without the npm package.
311
+ *
312
+ * The AIP-45 schema requires `install` / `version_check` / `sandbox`
313
+ * even though a generic agent is bring-your-own-binary: we synthesize
314
+ * truthful, minimal values (a `vendored` install pointing at the bin so
315
+ * `agentproto install` correctly treats it as pre-provided, a
316
+ * conventional `<bin> --version` check, and the shared GENERIC.ACP.md as
317
+ * both the `acp` wire ref and the `sandbox` ref). This keeps the existing
318
+ * schema unchanged — no fighting it.
319
+ */
320
+ declare function acpHandleFromSpec(spec: AcpAgentSpec): AgentCliHandle;
321
+ /**
322
+ * Curated catalog of known, publicly-documented ACP-speaking CLIs that do
323
+ * NOT ship a native `@agentproto/adapter-*` package. Conservative on
324
+ * purpose: every entry's ACP invocation is drawn from the agent's own
325
+ * public docs — no invented flags. Agents that already have a native
326
+ * adapter in `CATALOG` (claude-code, opencode, codex, hermes, …) are
327
+ * excluded; a native adapter always wins in `resolveAdapter` anyway.
328
+ *
329
+ * The `--experimental-acp` flag family below is the well-documented ACP
330
+ * entry point popularised by Gemini CLI and reused verbatim by its
331
+ * public forks.
332
+ */
333
+ declare const ACP_CATALOG: readonly AcpAgentSpec[];
334
+ /**
335
+ * Resolve a slug to a generic ACP spec: user config first (shadowing),
336
+ * then the curated catalog. Returns the matched spec + its source, or
337
+ * `null` when neither has the slug. Pass `config` to avoid a disk read
338
+ * (e.g. when the caller already loaded it); otherwise it's read lazily.
339
+ */
340
+ declare function resolveAcpSpec(slug: string, config?: AgentprotoConfig): Promise<{
341
+ spec: AcpAgentSpec;
342
+ source: AcpSpecSource;
343
+ } | null>;
344
+ /**
345
+ * Is `bin` runnable — a path that exists+executable, or a bare name found
346
+ * on PATH? Used to classify generic ACP agents in the listing:
347
+ * `available` when present, `supported` (install_hint) when not.
348
+ */
349
+ declare function binOnPath(bin: string): Promise<boolean>;
350
+ /** A generic ACP entry as surfaced in the adapter listing — the same
351
+ * UI-safe shape as `listAdaptersWithCatalog` entries, plus provenance. */
352
+ type AcpGenericListEntry = AdapterInfo & {
353
+ status: "supported" | "available";
354
+ hint?: string;
355
+ source: AcpSpecSource;
356
+ };
357
+ /**
358
+ * List the generic ACP agents (curated catalog + user config, config
359
+ * shadowing catalog) with a runtime `status` derived from bin presence:
360
+ * `available` when the bin is on PATH, `supported` (not installed, shows
361
+ * `install_hint`) otherwise. Config-defined agents are always listed.
362
+ *
363
+ * `excludeSlugs` drops entries already covered by an npm adapter /
364
+ * native catalog entry, so a generic spec never double-appears next to a
365
+ * real adapter of the same slug in the merged `adapter_list`.
366
+ */
367
+ declare function listAcpGenericAdapters(opts?: {
368
+ config?: AgentprotoConfig;
369
+ excludeSlugs?: ReadonlySet<string>;
370
+ }): Promise<AcpGenericListEntry[]>;
177
371
 
178
- export { type AdapterInfo, type ResolvedAdapter, listInstalledAdapters, resolveAdapter, runInstall, runRun, runServe };
372
+ export { ACP_CATALOG, type AcpAgentSpec, type AcpGenericListEntry, type AcpSpecSource, type AdapterInfo, type AdapterListing, type ResolvedAdapter, acpHandleFromSpec, binOnPath, listAcpGenericAdapters, listAdaptersWithAcp, listAdaptersWithCatalog, listInstalledAdapters, resolveAcpSpec, resolveAdapter, runAcp, runInstall, runRun, runServe };