Skip to content

[Feature]: Record install source (URL / ref / commit) for extensions, presets, and workflows installed via --from, and support them in update #3533

Description

@seiya-koji

Problem Statement

I use extensions, presets, and workflows in real projects, installing them by passing GitHub archive URLs to --from, and they evolve daily alongside the projects themselves. However, the current update process has friction:

  • Update detection relies solely on semver comparison of the manifest version field, so new commits are undetectable unless the version is bumped every time
  • Install-source records are inconsistent — extensions and presets store only source: "local" in the registry (the URL is lost), while workflows record the download URL but keep no ref / commit, and workflow update skips anything not installed from a catalog
  • Update procedures differ per component — extensions: add --force; presets: no update command at all, requiring removeadd; workflows: re-running add

As a result, the only way to update is to keep hand-assembling archive URLs (.../archive/<ref>.zip) and reinstalling. I would like commit-level version management and a simpler update flow.

Proposed Solution

Generalize the check → confirm → install → verify pipeline already established by specify self upgrade / self check to updates of all three components.

  1. Record the source on --from installs (extend workflows' existing source record with ref / commit; add the record to extensions and presets):
source:
  type: git-archive        # distinct from existing local / catalog
  url: https://github.com/<owner>/<repo>
  ref: main                # branch / tag / SHA
  commit: <resolved SHA>   # commit at install time

Since branch archive ZIPs don't include the SHA in their top-level directory name, resolve the ref at install time via GET /repos/{owner}/{repo}/commits/{ref} and record it — the same authentication pattern as resolve_github_release_asset_api_url(), which also covers GHES.

  1. Extend update: catalog-sourced items keep the current semver comparison; git-sourced items are checked by comparing the recorded SHA against the remote ref head (one API request, no download). SHA-pinned items are reported as "pinned" and skipped. Add --check for detection without applying. Add an update command to presets to unify the experience across all three components. Applying updates keeps the same confirmation prompt as catalog updates today — no silent auto-update, since extensions execute hooks.

Alternatives Considered

No response

Component

Specify CLI (initialization, commands)

AI Agent (if applicable)

Not applicable

Use Cases

  1. Trying out an extension under development from a fork / feature branch and tracking upstream before a release is cut
  2. Distributing extensions from internal private repositories (including GHES) without imposing a release workflow
  3. Checking with a single command whether community extensions not listed in any catalog have updates

Acceptance Criteria

  • --from installs record the source (url / ref / commit SHA) for all three components
  • update detects updates for git-sourced items via SHA comparison and applies them after confirmation (with a new update command for presets)
  • SHA-pinned items are excluded from updates and reported as "pinned"
  • Failed updates are restored via the existing backup mechanism
  • Works with private repositories (GITHUB_TOKEN / auth.json) and GHES

Additional Context

  • specify self upgrade already implements the same pipeline shape (detect via the release API → install from git+...@tag → verify the new binary → offer rollback); this proposal generalizes that philosophy

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Fields

    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions