Usage
facet system to talk to external tools, most often AI coding harnesses (OpenCode, Claude Code, Codex, etc.). Adapters define where assets and configuration live on disk.
Run with no specifier to choose from an interactive picker of the first-party adapters (TTY only) — in a non-interactive shell the no-argument form fails with a structured error and exit 1.
facet adapter install is a deprecated alias of add. It still installs exactly the same way and exits with the same code; it just prints a deprecation notice on stderr first. Prefer add, which mirrors the top-level split: facet add takes a specifier, facet install takes none.Built-in adapters
These names resolve to the first-party adapter packages:opencode— OpenCode adapter (@agent-facets/adapter-opencode)claude-code— Claude Code adapter (@agent-facets/adapter-claude-code)codex— Codex adapter (@agent-facets/adapter-codex)
A per-install
--target-dir flag is intentionally not supported: later invocations (such as facet build) would have no way to locate adapters placed in non-default locations.Exit codes
What it does
The flow stages and verifies a candidate before it ever touches the existing installation:- Download (or clone/copy) the source and bundle it into a self-contained
adapter.jsin temporary storage. - Verify the bundle: it must export a valid adapter that declares a supported adapter API. For npm sources the runtime declaration must also match the package metadata used for selection.
- Acquire a per-adapter replacement lock, copy the verified bundle into a new generation under
$FACET_DIR/adapters/<name>/generations/<generation-id>/, and verify it again at its final path. - Atomically activate the new generation by replacing the
installation.jsonreceipt — the record of the active generation, verified API, and source provenance (specifier, resolved npm package/version, integrity). - Remove the previous generation.
FACET_DIR layout.
Specifier formats
Adapter specifiers accept
git+ URLs even though facet sources for facet add reject them — adapters and facets follow different source rules.1.2.3, major wildcard 1.*, minor wildcard 1.2.*, *, or latest. npm range syntax (^1.2.3, ~1.2.3, comparators, hyphen/OR/x-ranges, prerelease tags) is rejected with an error listing the supported forms.
Compatible resolution
Every adapter declares the adapter API contract it was built against, and each CLI release supports an exact set of adapter APIs — currently just0.3 (the read-only planning contract, where the adapter decides what changes and the CLI performs every write). Adapters declaring 0.0, 0.1, or 0.2 wrote files themselves and are unsupported. An older CLI whose set excludes 0.3 keeps selecting the highest release it does support, so the lines advance independently. Membership is exact and unordered, and numeric proximity confers nothing.
For npm installs, the CLI reads the package’s version metadata (the facetAdapterApiVersion field each release publishes) and selects the highest stable release that both satisfies your version selector and declares a supported API:
- A bare name,
*, orlatestselects the highest compatible release — independent of npm’slatestdist-tag. - A wildcard selector (
1.*,1.2.*) selects the highest compatible release in the range. - An exact version considers only that release: if it is incompatible, the install fails rather than substituting another version.
- Releases with a missing or malformed declaration are never selected.
#ref still pins exactly what gets built (a tag, branch, or commit), and both Git and local sources are built as supplied and must pass the same runtime compatibility verification before installation.
Being installable is not the same as being able to configure MCP servers. An adapter with no MCP support installs and works normally — it only blocks a project that has active MCP server declarations. All three first-party adapters declare
0.3 with MCP support.See also
facet adapter list— list installed adapters.facet adapter remove— remove an installed adapter.- Environment variables —
FACET_DIRand the directory layout.