Skip to content

[Feature]: Spec Kit Package Manager — community CLI for extension/preset discovery, install, version pinning, and conflict detection #2566

Closed

Description

@Quratulain-bilal

Problem Statement

The April 2026 newsletter calls out as future work:

"Catalog discovery as package-manager experience for extensions/presets/integrations"

Today the ecosystem has 110+ community extensions and 12+ presets, but installation is still a manual flow: copy a
download URL from a catalog JSON, run specify extension add --from <url>, hope nothing collides with what's already
installed, and re-do it by hand for every update. There is no:

  • extensions.lock.json (no version pinning, no reproducible installs across machines / CI)
  • conflict detection (two extensions writing the same .specify/*.md artifact silently overwrite each other)
  • dependency resolution (e.g. "Canon" requires "Canon Core" preset — surfaced only in prose)
  • bulk update path (specify pm outdated, specify pm upgrade)
  • offline search / filter against the catalog (specify pm search drift --category process --license MIT)
  • preset+extension stack snapshot for new team members

This is the exact gap the maintainers named on the roadmap; nothing in extensions/catalog.community.json addresses it
today.

Proposed Solution

A community extension spec-kit-pm that prototypes a package-manager experience the maintainers can later promote into
core (mirroring the pattern of the existing specify self check / self upgrade stubs in v0.7.5):

/speckit.pm.search drift                 # search community catalog locally
/speckit.pm.install spec-kit-sync        # resolves deps, writes extensions.lock.json
/speckit.pm.outdated                     # compares installed vs catalog versions
/speckit.pm.upgrade                      # respects pins; --dry-run by default
/speckit.pm.conflicts                    # static analysis of artifact collisions
/speckit.pm.snapshot                     # export reproducible stack manifest
/speckit.pm.restore <manifest>           # rehydrate stack on new machine

Key design decisions:

- Reads the existing catalog.community.json — zero changes to upstream catalog format
- Writes .specify/extensions.lock.json parallel to existing .specify/integration.json so it integrates with the current
try_read_integration_json schema-guard pattern
- Conflict detection is static: parses each extension's extension.yml provides.commands / artifact-write paths declared
in the manifest
- Honors the existing requires.speckit_version and (proposed extension) requires.extensions fields —
backwards-compatible for extensions that don't declare them
- Pure read+write to project root and .specify/ — no network calls except an opt-in catalog refresh


### Alternatives Considered

- Wait for core support — newsletter lists this as roadmap work but no ETA; a community extension can prove the UX
faster and feed learnings back
- Per-extension installers — every author would reinvent the wheel; a single shared layer is cheaper and more consistent
- Pure shell aliases — doesn't solve conflict detection or lock files
- Fork existing JS/Python package managers — overkill; catalog is JSON, install surface is small, native fit is
.specify/* artifacts


### Component

Specify CLI (initialization, commands)

### AI Agent (if applicable)

All agents

### Use Cases

1. Reproducible installs in CI — specify pm restore stack.json on a clean checkout produces the exact same extension
set, no version drift between team members
2. Pre-merge conflict detection — before a maintainer accepts a new catalog PR, specify pm conflicts can flag if the new
 extension's artifact paths collide with popular existing ones
3. Upgrade hygiene — specify pm outdated --severity major surfaces upstream changes a team should review before
consuming
4. Stack discovery for newcomers — instead of reading 110 README files, specify pm search "spec drift" returns ranked
matches with description / author / stars from the catalog
5. Audit trail — extensions.lock.json becomes the durable record of "what shaped this project" — useful for the very
governance and onboarding tools the newsletter highlights (Memory Loader, Onboard, MemoryLint)


### Acceptance Criteria

- /speckit.pm.search <query> returns matching catalog entries with name / description / author / version / category /
license / stars
- /speckit.pm.install <id> downloads from catalog.community.json download_url, writes extensions.lock.json with resolved
 version + sha256
- /speckit.pm.outdated reports installed-vs-catalog diff
- /speckit.pm.upgrade defaults to --dry-run; only mutates with --apply
- /speckit.pm.conflicts statically detects two installed extensions writing the same path
- /speckit.pm.snapshot produces a portable manifest; /speckit.pm.restore rehydrates it
- Works with the existing .specify/integration.json schema-guard pattern (silent fallback on missing, loud error on
malformed)
- No network calls unless an explicit --refresh flag is passed
- Read-only by default for search, outdated, conflicts, snapshot; write only for install, upgrade --apply, restore
- README, LICENSE (MIT), CHANGELOG, GitHub release v1.0.0
- Tested against ≥10 randomly-chosen catalog entries


### Additional Context

- Newsletter quote (April 2026, roadmap section): "Catalog discovery as package-manager experience for
extensions/presets/integrations"
- Newsletter pain point: "instruction bloat, context rot" (Thoughtworks Radar v34) — a lock file + curated stack
manifest helps teams keep extension count intentional
- Newsletter pain point: "experienced reviewer is still essential" (XB Software field report) — pm conflicts reduces the
 review surface
- Pattern precedent: specify self check / self upgrade stubs already exist in v0.7.5, so a pm family fits the existing
CLI shape
- Wanted to align with the maintainers before building — happy to adjust scope, naming, command shape, or split into a
smaller v0.1 (e.g. just install + lock first) based on your steer.

Activity

  1. mnriem commented on May 14, 2026

    @mnriem
    Collaborator

    Package management here was meant in the context of creating bundles that an organization wants to maintain. So a curated and versioned set of catalog JSONs. Note the community catalog will stay read-only, but anyone can copy it and use it as the starting point of hosting their own internal catalogs

  2. Quratulain-bilal commented on May 14, 2026

    @Quratulain-bilal
    ContributorAuthor

    Ohh that's a much cleaner mental model than what I had in my head, thanks for spelling it out.

    So the unit isn't really "a project's installed extensions" (which is where I started), it's "a catalog that an org owns
    and distributes." The community catalog stays as the source-of-truth upstream, and downstream is just whoever forked it
    and curated. That's basically how Linux distros relate to upstream package maintainers, makes sense.

    A few things I want to sanity-check before I rewrite the proposal:

    1. Is the expected delivery format literally a published catalog.json (or a tagged repo containing one), or are you
      imagining something more structured like a manifest that wraps multiple catalogs + a version + signing metadata? I can
      see arguments either way.
    2. For the "curate" step, do you see value in pinning extension versions inside the bundle (e.g. org says "we ship
      spec-kit-sync at v0.3.2, not latest")? That's the one piece of my original lock-file idea I think still applies here,
      but at the catalog level not the project level.
    3. Is there appetite for a specify catalog CLI surface eventually (similar to the self check / self upgrade stubs), or
      do you want this to live entirely as a community extension that orgs adopt by choice?

    Happy to either edit this issue down to the bundle scope or close it and open a fresh one if you'd prefer a clean slate.
    Whichever's easier to track.

  3. mnriem commented on May 15, 2026

    @mnriem
    Collaborator

    I included a catalog.json with the presets and extensions I host myself. See https://github.com/mnriem/spec-kit-presets/blob/main/catalog.json for an example for presets catalog. And https://github.com/mnriem/spec-kit-extensions/blob/main/catalog.json

    That is how indeed an organization can host it themselves. And they can use a Git tags if so desired

    And the you can already do specify extension catalog and specify presets catalog

  4. Quratulain-bilal commented on May 15, 2026

    @Quratulain-bilal
    ContributorAuthor

    ahh I'd missed specify extension catalog and specify presets catalog entirely. Just looked at your two repos plus
    the implementation in src/specify_cli/extensions.py and catalogs.py and I see it now: SPECKIT_CATALOG_URL env var,
    multi-catalog CatalogEntry registry with priorities, schema_version + updated_at + catalog_url at the root. The "host
    your own catalog" plumbing is already there.

    That changes what's worth building. The tooling exists; the gap is the convention layer an org needs in order to
    actually adopt this pattern:

    1. A template repo (spec-kit-org-catalog-template) that ships with a starter catalog.json curated from upstream,
      a CI workflow that validates schema + checks every download_url is reachable + diffs vs upstream on every PR, and a
      RELEASE.md describing the git-tag-as-version convention you mentioned.

    2. A catalog diff command in the template make diff-upstream that pulls the community catalog and reports
      added/removed/version-changed entries since the last sync. Orgs need this to do periodic refreshes without manually
      scanning the upstream catalog.

    3. A short HOSTING.md in spec-kit docs (or a docs/community/hosting-your-own-catalog.md) that links to your two
      example repos and walks through: fork → curate → set SPECKIT_CATALOG_URL → tag releases. Right now that workflow is
      implicit; making it explicit unlocks the org-internal use case you described.

    None of that requires touching upstream code. It's purely playbook + tooling that lives alongside the existing CLI.

    Two questions before I do anything:

    • Would you prefer the template + diff tooling lives in a community extension I host, or as docs/templates contributed
      back into the spec-kit repo? Both work; first is faster, second has more reach.
    • Are you and other org-hosters already running anything like the upstream-diff check internally, or is that genuinely a
      gap? Don't want to reinvent something you already have.

    If neither of these is interesting, I'm equally happy to close this issue the underlying need was "make org-hosted
    catalogs more discoverable" and you've shown it's already largely solved.

  5. mnriem commented on May 18, 2026

    @mnriem
    Collaborator

    You do nor have to set the environment variable. You can use multiple catalogs at the same time. Is https://github.github.com/spec-kit/reference/extensions.html#catalog-management not sufficient?

  6. Quratulain-bilal commented on May 18, 2026

    @Quratulain-bilal
    ContributorAuthor

    I missed the multi-catalog section first time round specify extension catalog add with priorities is exactly the
    surface I was reaching for. Closing.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions