Skip to content

fix(core): accept structured extension source in registry - #8

Open
PhanCongVuDuc wants to merge 1 commit into
tinesoft:developfrom
PhanCongVuDuc:fix/registry-structured-source
Open

PhanCongVuDuc wants to merge 1 commit into
tinesoft:developfrom
PhanCongVuDuc:fix/registry-structured-source

Conversation

@PhanCongVuDuc

Copy link
Copy Markdown

Problem

With spec-kit 1.0.12, spectatui fails to start in any project where an extension was installed or updated from a catalog:

Error: failed to discover project

Caused by:
    0: failed to parse extensions registry
    1: invalid type: map, expected a string at line 26 column 16

spec-kit now writes source in .specify/extensions/.registry as an object when the extension comes from a catalog (src/specify_cli/extensions/__init__.py, ExtensionManager registry update):

"assess": {
  "version": "1.0.1",
  "source": { "kind": "catalog", "catalog": "default" },
  ...
}

Entries installed locally still use the legacy string ("source": "local"), so a single registry can contain both shapes. ExtensionRegistryEntry.source was Option<String>, so the object makes the whole registry fail to parse and discovery aborts.

Reproduce: specify extension update (or specify extension add <id> from the default catalog) with spec-kit 1.0.12, then run spectatui.

Fix

  • ExtensionRegistryEntry.source is read as Option<serde_json::Value>.
  • A new extension_source() maps both shapes to ExtensionSource:
    • legacy string: unchanged behaviour ("local" → Local, http… → Url, anything else → Catalog)
    • object: {"kind": "catalog", "catalog": "<name>"} → Catalog(name); {"kind": "local"}, a blank catalog name or an unknown kind → Local — the same normalisation spec-kit applies in _installed_list_json._normalized_source
  • An unrecognised shape now falls back to Local instead of failing project discovery.

The presets registry has the same new object source, but PresetRegistryEntry does not declare the field, so serde already ignores it there — no change needed.

Tests

  • loads_extensions_with_legacy_and_structured_sources — writes a registry containing one legacy and one structured entry and runs load_extensions. Confirmed it fails on develop with the exact error above, and passes with the fix.
  • maps_every_extension_source_shape — covers each string and object variant, plus None.

Checked locally (Windows, stable-x86_64-pc-windows-gnu):

  • cargo fmt --all -- --check
  • cargo clippy --workspace -- -D warnings
  • cargo test --workspace (76 passed)
  • release build started against a real spec-kit 1.0.12 project: the v1.1.0 binary exits with the error above, the patched one starts normally.

🤖 Generated with Claude Code

spec-kit 1.0.12 writes `source` in `.specify/extensions/.registry` as an
object (`{"kind": "catalog", "catalog": "<name>"}`) when an extension is
installed or updated from a catalog. The registry parser only accepted a
string, so project discovery failed with "invalid type: map, expected a
string" and spectatui exited on startup.

Read `source` as raw JSON and map both the legacy string and the
structured object to ExtensionSource; any other shape falls back to Local
instead of failing discovery.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant