Extension CLI Reference
Complete reference for managing extensions with specify extension.
All extension commands require a project already initialized with specify init.
Search Available Extensions
specify extension search [query]
| Option | Description |
|---|---|
--tag |
Filter by tag |
--author |
Filter by author |
--verified |
Show only verified extensions |
Searches all active catalogs for extensions matching the query. Without a query, lists all available extensions.
Install an Extension
specify extension add <name>
specify extension add --from <url>
specify extension add --dev <path>
| Option | Description |
|---|---|
--dev |
Install from a local directory (for development) |
--from <url> |
Install from a custom URL instead of the catalog |
--version <v> |
Install an exact version advertised by a catalog |
--force |
Overwrite if the extension is already installed |
--priority <N> |
Resolution priority (default: 10; lower = higher precedence) |
Installs an extension from the catalog, a URL, or a local directory. Extension commands are registered with the active AI coding agent integration. For generic, invocations use the configured --commands-dir: flat command files by default, or speckit-<name>/SKILL.md with --skills.
The positional name is required for catalog installs, and --dev requires a
local path. With --from, the positional name can be omitted; the downloaded
manifest supplies the installed extension ID.
If a generic integration refresh cannot produce every extension invocation (for example, because a command or skill is user-modified or its source is missing), it warns and restores that extension's prior registered artifacts. Other extensions can still refresh.
An unqualified catalog install still selects the advertised current version.
--version uses only the winning catalog source for that extension ID; it does
not fall back to a lower-priority source when the requested version is absent.
Discovery-only catalogs remain non-installable. --version cannot be combined
with --dev or the direct-URL --from option. For --version catalog installs,
the downloaded archive's extension ID and version are compared with the
requested catalog ID and version before installation. Unqualified catalog
installs and direct --from installs validate the manifest but do not compare
its ID or version with expected catalog values.
Remove an Extension
specify extension remove <name>
| Option | Description |
|---|---|
--keep-config |
Preserve configuration files during removal |
--force |
Skip confirmation prompt |
Removes an installed extension. Configuration files are backed up by default; use --keep-config to leave them in place or --force to skip the confirmation.
List Installed Extensions
specify extension list
specify extension list --json
| Option | Description |
|---|---|
--available |
Show installed extensions and an installation hint; does not query catalogs |
--all |
Same current behavior as --available |
--json |
Write installed extensions as JSON |
Lists installed extensions with their status, version, and command counts.
Although help describes --available and --all as including catalog entries,
the current handler does not fetch or list uninstalled extensions. Use
specify extension search to discover available extensions.
--json writes a JSON array to stdout. Every item has the keys id, name,
description, version, author, priority, enabled, source, and
provides. author is null when absent; source is {"kind":"local"}
for local, legacy, or malformed provenance, or
{"kind":"catalog","catalog":"<catalog-name>"} for a valid catalog source.
Extension provides contains commands, templates, scripts, and hooks
counts. --available and --all do not broaden JSON output beyond installed
extensions. On success, --json writes exactly one array to stdout and exits
0. A runtime failure after option parsing writes exactly one
{"error":"..."} object to stderr and exits 1. If parsing raises a usage
error and the raw --json token is present, it writes that JSON error object
to stderr and preserves the usage exit code (normally 2). Without --json,
including for help, the existing human-readable behavior is unchanged.
Extension Info
specify extension info <name>
specify extension info <name> --versions
specify extension info <name> --json
Shows detailed information about an installed or available extension, including its description, version, commands, and configuration.
--versions lists the current and historical versions advertised by the
winning catalog source; it labels discovery-only sources as non-installable.
Equivalent PEP 440 version spellings (for example, v1.0 and 1.0) select
the same release; the catalog's advertised spelling remains visible.
See Historical releases for the catalog format used to advertise older versions and bundle-pin behavior.
--json describes one installed extension and writes a single JSON object to
stdout. <name> is matched as without --json: the extension ID first, then a
unique display name, ignoring case. The object has the same id, name,
description, version, author, priority, enabled, and source keys as
the matching specify extension list --json item. In place of the provides
counts it has commands, templates, scripts, and hooks arrays. Command,
template, and script entries have name, description ("" when absent),
source ({"layer": "extension", "extensionId": "<id>"}, the extension that
provides it; the top-level source is where it was installed from), and
sourcePath (the manifest file,
relative to the extension directory); script entries also have runtimes when
the manifest declares them. Extension entries carry no strategy, because
extension-provided files always replace. Each hook entry has trigger (the
hook event, such as after_tasks), targetCommand, optional (default
true), and priority (default 10). When an event declares the same command
more than once, the last declaration wins, as it does when hooks are
registered. --json cannot be combined with --versions (usage error, exit 2).
An extension that is not installed, an ambiguous name, or a missing project
writes one {"error":"..."} object to stderr and exits 1; usage errors keep
their exit code (normally 2), as with list --json.
Update Extensions
specify extension update [<name>]
Updates a specific extension, or all installed extensions if no name is given.
Bundled extensions (such as agent-context and git) have no download URL; their updates install from the copy shipped with the running spec-kit release. When the catalog advertises a newer version than your spec-kit release ships, the update is reported as requiring a spec-kit upgrade first.
For generic, a failed update restores hash-owned invocations from previously configured --commands-dir locations as well as the current location, even if another integration is now active.
Enable / Disable an Extension
specify extension enable <name>
specify extension disable <name>
Disable an extension without removing it. Disabled extensions are excluded from
registry-driven artifact resolution and future integration registration, and
their declarative hooks are marked disabled in .specify/extensions.yml.
Native runtime-event configuration is refreshed on a best-effort basis after
these state changes. If a refresh fails, the command warns, but a stale native
hook may remain active and still execute. Retry the affected integration's
refresh with specify integration upgrade <key>.
Non-generic integrations can retain generated command or skill files that
remain invocable until an integration
switch, uninstall, or reconciliation removes them. Disabling is not a universal
execution block. Hook-only extensions can be installed, enabled, and disabled
even if generic command-output settings are missing or invalid; extensions with
commands still require valid settings. Re-enable with enable.
For generic, disabling removes hash-owned invocations even after the output directory moves, but preserves unrelated same-named files in the new directory.
Set Extension Priority
specify extension set-priority <name> <priority>
Changes the artifact resolution priority of an extension. Lower numbers take precedence for contributed artifacts such as templates and scripts; ties are ordered by extension ID. Installation rejects exact command-name or alias collisions with installed extensions, and normalized output-name collisions with core commands. Priority does not permit duplicate command names to be installed.
Catalog Management
Extension catalogs control where search and add look for extensions. Catalogs are checked in priority order (lower number = higher precedence).
Discovery-only catalogs can be searched but cannot be installed from. Only enable installation for a source you own and vet. See the catalog trust model before installing third-party extensions.
List Catalogs
specify extension catalog list
Shows all active catalogs in the stack with their priorities and install permissions.
Add a Catalog
specify extension catalog add <url>
| Option | Description |
|---|---|
--name <name> |
Required. Unique name for the catalog |
--priority <N> |
Priority (default: 10; lower = higher precedence) |
--install-allowed / --no-install-allowed |
Mark the catalog as a trusted install source. Only enable for a catalog you own and vet; leave off (the default) for discovery-only sources. Never enable it for an unvetted public catalog. |
--description <text> |
Optional description |
Adds a catalog to the project's .specify/extension-catalogs.yml.
Re-adding the same named catalog with identical settings succeeds without changing the configuration; different settings are rejected.
Remove a Catalog
specify extension catalog remove <name>
Removes a catalog from the project configuration.