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

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions