Repository navigation
[Feature]: Add --json output to preset info and extension info with fully-expanded per-contribution detail (per-pack detail view; complements list --json summary counts) #4213
Description
Activity
- addedfeature-assessRun the Spec Kit idea-assessment pipeline on this feature requestRun the Spec Kit idea-assessment pipeline on this feature request
on Aug 19, 2026 github-actions commented
on Aug 19, 2026 on Aug 19, 2026 – with GitHub ActionsContributorMore actionsFeature assessment — info-json-full-expansion · Stage 1/5: Intake
Idea Intake: Add --json to preset info and extension info
- Slug: info-json-full-expansion
- Created: 2026-08-19
- Source: GitHub issue [Feature]: Add --json output to preset info and extension info with fully-expanded per-contribution detail (per-pack detail view; complements list --json summary counts) #4213, github/spec-kit, raised by @nicolehaugen
- Type: improvement
Idea (as captured)
Add
--jsonto bothspecify preset info <id>andspecify extension info <id>commands. The output should be a single JSON object with top-level metadata fields (id,name,description,version,author,priority,enabled,source) plus fully-expanded arrays:commands,templates,scripts(andhooksfor extensions) — each item enumerated with its full per-contribution schema (id,name,description,artifact,optional,handoffs,strategy,sourcePath,runtimes, etc.). Strategy shorthand keys (replaces/wraps/prepends/appends) are normalized server-side. Hook shorthand (phase/commandvstrigger/targetCommand) is also normalized. Unknown id exits non-zero with a JSON error on stderr.Restated
Today
specify preset infoandspecify extension infoemit only human-readable text; downstream consumers such asspeckit-wizard-canvasreconstruct the structured shape by parsing raw YAML files directly. This feature adds--jsonto both commands, returning a single, fully-normalized JSON object so clients can stop duplicating server-side normalization logic.Origin & Context
- Raised by: @nicolehaugen
- Trigger: The
speckit-wizard-canvascomponent in thegithub/spec-kit-copilotrepository re-parsespreset.yml/extension.ymlwithjs-yamland re-implements strategy-inference and hook-normalization logic (parseProvidesEntries,parseHookDeclarationsincomposition/collect.mjs). This creates a fragile client-side mirror of server-side logic that drifts over time.
First-Glance Unknowns
- [NEEDS CLARIFICATION: What is the exact stable-id scheme for per-contribution
idfields? The issue references a companion "stable id / lookupId" issue but does not link it.] - [NEEDS CLARIFICATION: What fields does the companion "artifact/optional/handoffs" issue define for command entries? Both are hard dependencies.]
- [NEEDS CLARIFICATION: Should
specify artifact info --jsoncross-reference IDs be validated in this PR or deferred to the companion issue?] - [NEEDS CLARIFICATION: Is
speckit-wizard-canvasthe only known consumer, or are there other downstream clients depending on this shape?]
Generated by 💡 Assess a Feature Request by Installing and Running Spec Kit for issue #4213 · 614.8 AIC · ⌖ 12.3 AIC · ⊞ 38K · ◷
github-actions commented
on Aug 19, 2026 on Aug 19, 2026 – with GitHub ActionsContributorMore actionsFeature assessment — info-json-full-expansion · Stage 2/5: Research
Idea Research: Add --json to preset info and extension info
- Slug: info-json-full-expansion
- Created: 2026-08-19
- Evidence confidence (overall): high
Users & Demand
speckit-wizard-canvas(github/spec-kit-copilot,composition/collect.mjs) explicitly re-parses rawpreset.yml/extension.ymlusingjs-yamland re-implementsparseProvidesEntriesandparseHookDeclarations, including strategy-shorthand inference and hook-phase normalization. This is the direct, stated motivation; the consumer is identified by name. — [source: issue [Feature]: Add --json output to preset info and extension info with fully-expanded per-contribution detail (per-pack detail view; complements list --json summary counts) #4213 body] (confidence: high, cited)- IDE plugin hover-cards and pre-commit hook-collision checks are listed as additional use cases in the issue. These are plausible but unnamed/unlinked. — [source: issue [Feature]: Add --json output to preset info and extension info with fully-expanded per-contribution detail (per-pack detail view; complements list --json summary counts) #4213 body] (confidence: low, assumption)
Prior Art
specify preset list --json/specify extension list --json: The issue references a companion list-JSON issue as existing or in-flight; this feature is explicitly scoped as complementary to it (per-pack detail vs. per-collection counts). No PR/issue number is linked. — [NEEDS CLARIFICATION: Islist --jsonalready shipped or also planned?] (confidence: medium, assumption)specify artifact info --json: A companion issue covers per-artifact lookup. Neither supersedes the other. — [source: issue [Feature]: Add --json output to preset info and extension info with fully-expanded per-contribution detail (per-pack detail view; complements list --json summary counts) #4213 body] (confidence: high, cited)- Current
preset infoimplementation (src/specify_cli/presets/_commands.py, line 461): outputs Rich-formatted text only; no--jsonflag exists. Confirmed by codebase inspection. — [source: codebase] (confidence: high, cited) - Current
extension infoimplementation (src/specify_cli/extensions/_commands.py, line 1337): text-only, no JSON path. — [source: codebase] (confidence: high, cited) - Strategy normalization already exists (
src/specify_cli/presets/__init__.py, line 258:VALID_PRESET_STRATEGIES = {"replace", "prepend", "append", "wrap"}; line 451: strategy defaults to"replace"and is validated). The canonical longform is already stored in the Python layer after YAML parsing. — [source: codebase] (confidence: high, cited) - Extension
strategyis already rejected (src/specify_cli/extensions/__init__.py, lines 622–626): extensions cannot authorstrategy— enforced at the Python layer. — [source: codebase] (confidence: high, cited) runtimesfield exists for extension scripts (src/specify_cli/extensions/__init__.py, lines 628–639): validated as a list of strings. — [source: codebase] (confidence: high, cited)
Market & Context
- CLI-first tools (e.g., Homebrew, npm,
gh) routinely expose--jsonon detail commands as a first-class contract for scripting and tooling. The pattern is well-established. — [source: general knowledge] (confidence: medium, assumption) - Without
--json, downstream consumers parsingpreset infotext output are brittle to Rich formatting changes. The wizard currently bypasses the CLI entirely by reading raw YAML, which can silently drift from the CLI's validated schema. — [source: issue [Feature]: Add --json output to preset info and extension info with fully-expanded per-contribution detail (per-pack detail view; complements list --json summary counts) #4213 body] (confidence: high, cited)
Data & Constraints
- The fully-expanded JSON shape depends on multiple companion issues for
id,artifact,optional,handoffs. These are hard dependencies; shipping before companions means either omitting fields or risking a breaking shape change later. — [source: issue [Feature]: Add --json output to preset info and extension info with fully-expanded per-contribution detail (per-pack detail view; complements list --json summary counts) #4213 body] (confidence: high, cited) - No JSON test coverage currently exists for
preset info/extension info. — [source: codebase] (confidence: medium, cited)
Evidence Against the Idea
- Companion dependency risk:
artifact/optional/handoffsandstable id / lookupIdare hard dependencies. If those ship after this issue, the JSON contract would be incomplete on first release, requiring a follow-up breaking change or stubs. - Surface area / maintenance: Adding
--jsonto two commands requires schema stability guarantees going forward. Any output shape change becomes a breaking change for consumers. - Duplication concern: The issue pre-empts the argument that
artifact info --jsoncovers this use case, but reviewers may still question whether both surfaces are necessary. The distinction (per-pack vs. per-artifact) is clear in the issue text but not self-evident to new readers.
Gaps & Open Questions
- [NEEDS CLARIFICATION: Are the companion issues (
stable id / lookupId,artifact/optional/handoffs) already merged or still open?] - [NEEDS CLARIFICATION: Does the current
preset.ymlloader normalizereplaces/wraps/prepends/appendsshorthand keys, or does it only accept canonical longform?] - [NEEDS CLARIFICATION: Are there additional known consumers beyond
speckit-wizard-canvas?]
Sources
- github.com/[Feature]: Add --json output to preset info and extension info with fully-expanded per-contribution detail (per-pack detail view; complements list --json summary counts) #4213 (host: github.com, policy: allowlisted)
- Codebase: src/specify_cli/presets/_commands.py, src/specify_cli/extensions/_commands.py, src/specify_cli/presets/init.py, src/specify_cli/extensions/init.py (local filesystem)
Generated by 💡 Assess a Feature Request by Installing and Running Spec Kit for issue #4213 · 614.8 AIC · ⌖ 12.3 AIC · ⊞ 38K · ◷
github-actions commented
on Aug 19, 2026 on Aug 19, 2026 – with GitHub ActionsContributorMore actionsFeature assessment — info-json-full-expansion · Stage 3/5: Problem
Problem Definition: Add --json to preset info and extension info
- Slug: info-json-full-expansion
- Created: 2026-08-19
- Inputs used: intake.md | research.md
Problem Statement
Downstream consumers of
specify preset infoandspecify extension infocannot programmatically obtain the fully-normalized, per-contribution detail for a pack (commands, templates, scripts, hooks with strategy, handoffs, runtimes, etc.) because both commands emit only human-readable text. As a result, clients must parse raw YAML files directly and re-implement server-side normalization logic — creating a fragile, drift-prone mirror of the CLI's own data model.Affected Users & Stakeholders
- Users: Tooling authors (wizard canvas, IDE plugins, pre-commit hooks) who need structured pack detail to render UI, enforce constraints, or feed downstream automation — they currently parse
preset.yml/extension.ymldirectly. - Stakeholders: Spec Kit CLI maintainers — any change to
preset.yml/extension.ymlschema silently breaks client-side parsers without the CLI ever raising an error; this creates hidden coupling.
Goals
specify preset info <id> --jsonandspecify extension info <id> --jsonemit a single, fully-normalized JSON object with all metadata and expanded per-contribution arrays.- Strategy shorthand normalization and hook-phase normalization are done server-side in the CLI, not re-implemented in clients.
- Unknown IDs exit non-zero with a JSON-formatted error on stderr.
- The output shape is stable and testable (schema round-trip, normalization tests).
Non-Goals
- Not a replacement for
specify artifact info --json(per-artifact cross-pack view vs. per-pack view). - Not a replacement for
specify preset list --json/specify extension list --json(collection summary vs. single-pack detail). - No other subcommands get
--jsonin this work. - Architectural redesign of the YAML data model is out of scope.
Success Metrics
speckit-wizard-canvascan deleteparseProvidesEntriesandparseHookDeclarationsfromcomposition/collect.mjsand replace them with a singlespecify preset info --json/specify extension info --jsoncall. (qualitative, binary)- Zero divergence between CLI-reported structure and raw YAML structure for a given pack, verified by round-trip tests. (measurable)
- All four strategy shorthand forms normalize correctly in output. (measurable, testable)
Cost of Inaction
Without this, every new downstream consumer must independently parse and normalize YAML — each accumulates its own version of the same drift risk. When the Spec Kit data model evolves, client-side parsers silently produce wrong data rather than surfacing an error. The
js-yamldependency inspeckit-wizard-canvasremains, and the normalization surface grows with each new consumer.Open Questions
- [NEEDS CLARIFICATION: Are the companion issues (
stable id / lookupId,artifact/optional/handoffs) already merged? Theid,artifact,optional, andhandoffsfields on command entries are blocked on them.] - [NEEDS CLARIFICATION: Does
preset.ymlaccept shorthand strategy keys (replaces,wraps, etc.) or only canonical longform?] - [NEEDS CLARIFICATION: Should
runtimesbe added to preset script entries for parity in this PR, or is it already supported?]
Generated by 💡 Assess a Feature Request by Installing and Running Spec Kit for issue #4213 · 614.8 AIC · ⌖ 12.3 AIC · ⊞ 38K · ◷
github-actions commented
on Aug 19, 2026 on Aug 19, 2026 – with GitHub ActionsContributorMore actionsFeature assessment — info-json-full-expansion · Stage 4/5: Concept
Concept: Add --json to preset info and extension info
- Slug: info-json-full-expansion
- Created: 2026-08-19
- Recommended option: Option A — Phased delivery: core JSON now, companion-dependent fields via stubs
Options
Option A — Phased delivery: core JSON now, companion-dependent fields via stubs
- Sketch: Add
--jsonto both commands immediately, emitting all fields that are currently available in the Python data model (metadata, commands with name/description/sourcePath/strategy, templates with strategy, scripts with runtimes, hooks with trigger/targetCommand/sourcePath/priority). Fields that depend on companion issues (idstable scheme,artifact,optional,handoffs) are included asnullwith a documented note that they are filled by the companion PRs. The JSON contract is versioned so consumers can check completeness. Shorthand normalization ships now (canonical form is already stored in the Python layer). This delivers the primary value — eliminatingjs-yamlparsing and most of thecollect.mjslogic — while unblocking the companions to fill in the remaining fields. - Appetite: medium (weeks)
- Trade-offs: Wins: immediate value for
speckit-wizard-canvas, unblocks companions, establishes the contract early. Sacrifices: consumers seenullfields until companions land; the schema has a "v1 incomplete" period. - Rabbit holes: Defining a stable-enough output shape that companions can fill without breaking the contract. A
schema_versionfield mitigates this.
Option B — Wait for all companion issues before shipping
- Sketch: Do not add
--jsonuntilstable id / lookupId,artifact/optional/handoffs, andstructured source provenanceare all merged. Ship the complete shape in one PR. - Appetite: large (months, depending on companions)
- Trade-offs: Wins: clean, complete contract from day one. Sacrifices:
speckit-wizard-canvaskeepsjs-yamland client-side normalization for months; other consumers cannot start adopting the output. - Rabbit holes: Companion timelines are unknown; this could slip indefinitely.
Option C — Minimal metadata-only JSON, no expanded contributions
- Sketch: Add
--jsonbut return only top-level metadata (id,name,description,version,author,priority,enabled,source); omitcommands,templates,scripts,hooksarrays. - Appetite: small (days)
- Trade-offs: Wins: trivially easy, low risk. Sacrifices: does not address the primary use case —
speckit-wizard-canvasstill needs the contribution arrays and still needsjs-yaml. Almost no payoff. - Rabbit holes: None, but no value either.
Recommendation
Option A — phased delivery with
nullstubs for companion-dependent fields. The primary value (eliminating client-side YAML parsing and normalization re-implementation) is achievable now without the companions. Anullstub is better than no field: it signals the contract shape and lets consumers code against it before real values arrive. The shorthand normalization logic is already encoded in the Python layer; exposing it via--jsonis additive. Shape instability is mitigated by documenting the contract and including aschema_versionfield.Out of Scope (for the recommended option)
specify artifact info --json(companion issue)specify preset list --json/specify extension list --json(companion issue)- Stable-id scheme implementation (companion issue)
artifact,optional,handoffsfields on command entries (stubs tonullhere; companion fills them)- Changes to
preset.yml/extension.ymlschema
Assumptions to Validate
- Canonical longform strategy values are already stored after YAML parsing and do not require additional shorthand normalization in the
--jsonpath. - The
runtimesfield can be populated for preset scripts at pack-read time (or is already stored). - Companion issues will merge within weeks, not quarters, justifying phased over Option B.
speckit-wizard-canvasis willing to handlenullstubs for companion-dependent fields during transition.
Generated by 💡 Assess a Feature Request by Installing and Running Spec Kit for issue #4213 · 614.8 AIC · ⌖ 12.3 AIC · ⊞ 38K · ◷
github-actions commented
on Aug 19, 2026 on Aug 19, 2026 – with GitHub ActionsContributorMore actionsFeature assessment — info-json-full-expansion · Stage 5/5: Decision — verdict needs-clarification
Decision: Add --json to preset info and extension info
- Slug: info-json-full-expansion
- Decided: 2026-08-19
- Verdict: needs-clarification
- Artifacts reviewed: intake.md | research.md | problem.md | concept.md
Scorecard
Criterion Rating Justification Problem validity strong Real, concrete downstream consumer ( speckit-wizard-canvas) is explicitly identified, with named files that must be replaced. The fragility risk is clear and well-argued.Evidence strength adequate The primary consumer is directly cited. Additional use cases (IDE plugins, pre-commit checks) are plausible but unlinked. Companion issue timelines and their merge status are unknown — this is the binding gap. Value vs. inaction strong Without this, every new consumer re-implements server-side normalization; the CLI never surfaces schema drift to clients. Value of building is high; cost of inaction compounds with each new consumer. Feasibility / appetite adequate The core JSON path (metadata + contribution arrays with currently-known fields) is implementable in medium appetite. Companion-dependent fields ( id,artifact,optional,handoffs) require a phased approach with stubs, which introduces shape-completeness risk.Strategic fit strong Aligns with the Spec Kit principle that the CLI is the single source of truth for pack metadata. Eliminating client-side YAML parsing is a direct expression of that principle. Risk posture adequate The main risks — companion timeline uncertainty and JSON schema stability — are identified and have credible mitigations (stubs + schema_version). The risk of a breaking shape change is real but manageable.Verdict & Rationale
needs-clarification — The problem is real, well-evidenced, and strategically aligned; the concept is credible. However, two blocking questions must be answered before a
gocan be issued:-
Companion merge status: The JSON shape explicitly depends on companion issues (
stable id / lookupIdandartifact/optional/handoffs) for theid,artifact,optional, andhandoffsfields on command entries. If those companions are already merged, Option A (phased delivery with stubs) is straightforwardly viable. If they are still open, the assessment needs explicit confirmation that the project is comfortable with anull-stub period — or the team reconsiders in favor of Option B (wait for all companions). -
Shorthand normalization scope: The issue asserts that
replaces/wraps/prepends/appendsshorthand keys must be normalized server-side. Codebase inspection confirms canonical longform is stored after parsing, but does not confirm whether shorthand is currently accepted as input. If shorthand is accepted today, normalization work is non-trivial; if not, this is simpler.
Evidence strength is
adequate(notweak) because the primary consumer is concretely identified and the codebase confirms both the problem and the feasibility of the core path. However, the companion dependency makes agoverdict premature without knowing whether the full shape can be delivered coherently or requires a staged rollout the team must explicitly accept.If needs-clarification
- Blocking questions:
- [NEEDS CLARIFICATION: Are the companion issues (
stable id / lookupIdandartifact/optional/handoffs) already merged or open? If open, what is their expected timeline?] - [NEEDS CLARIFICATION: Does the current
preset.ymlloader accept shorthand strategy keys (replaces,wraps,prepends,appends), or only canonical longform (replace,wrap,prepend,append)?]
- [NEEDS CLARIFICATION: Are the companion issues (
- Revisit stage: research (confirm companion status and shorthand scope) → decide
Generated by 💡 Assess a Feature Request by Installing and Running Spec Kit for issue #4213 · 614.8 AIC · ⌖ 12.3 AIC · ⊞ 38K · ◷
- addedfeature-needs-clarificationFeature assessment verdict: needs clarificationFeature assessment verdict: needs clarification
on Aug 19, 2026 [NEEDS CLARIFICATION: Are the companion issues (stable id / lookupId and artifact/optional/handoffs) already merged or open? If open, what is their expected timeline?] => this is the companion issue mentioned: #4210
[NEEDS CLARIFICATION: Does the current preset.yml loader accept shorthand strategy keys (replaces, wraps, prepends, appends), or only canonical longform (replace, wrap, prepend, append)?] => Short is fine.
- addedfeature-assessRun the Spec Kit idea-assessment pipeline on this feature requestRun the Spec Kit idea-assessment pipeline on this feature requestand removedfeature-assessRun the Spec Kit idea-assessment pipeline on this feature requestRun the Spec Kit idea-assessment pipeline on this feature requestfeature-needs-clarificationFeature assessment verdict: needs clarificationFeature assessment verdict: needs clarification
on Aug 19, 2026 - addedfeature-assessRun the Spec Kit idea-assessment pipeline on this feature requestRun the Spec Kit idea-assessment pipeline on this feature requestand removedfeature-assessRun the Spec Kit idea-assessment pipeline on this feature requestRun the Spec Kit idea-assessment pipeline on this feature request
on Aug 20, 2026 github-actions commented
on Aug 20, 2026 on Aug 20, 2026 – with GitHub ActionsContributorMore actionsFeature assessment — info-json-full-expansion · Stage 1/5: Intake
Idea Intake: Add --json to preset info and extension info
- Slug: info-json-full-expansion
- Created: 2026-08-20
- Source: GitHub issue [Feature]: Add --json output to preset info and extension info with fully-expanded per-contribution detail (per-pack detail view; complements list --json summary counts) #4213, github/spec-kit, raised by @nicolehaugen
- Type: improvement
Idea (as captured)
Add
--jsonto bothspecify preset info <id>andspecify extension info <id>commands. The output should be a single JSON object with fully-expandedcommands,templates,scripts, andhooks(extensions only) arrays — not integer counts. Each contribution entry includes full per-contribution schema (id,name,description,artifact,optional,handoffs,strategy,sourcePath,runtimes, etc.). All shorthand-key normalization (replaces/wraps/prepends/appends→strategy) is done server-side. Extension entries omitstrategy(alwaysreplace). Companion to thelist --jsonissue but distinct:infois per-pack full expansion;listis per-collection summary counts.Restated
Downstream consumers of the Specify CLI (notably
speckit-wizard-canvas) currently reconstruct structured pack metadata by parsing raw YAML files on the client side. This request adds--jsonoutput tospecify preset infoandspecify extension infoso that structured, fully-normalized metadata can be consumed directly from the CLI without client-side reconstruction.Origin & Context
- Raised by: @nicolehaugen
- Trigger:
speckit-wizard-canvascurrently usesjs-yaml+composition/collect.mjs::parseProvidesEntriesand::parseHookDeclarationsto reconstruct server-side data on the client. The request eliminates that duplication.
First-Glance Unknowns
- [NEEDS CLARIFICATION: Are the companion "stable id / lookupId" and "artifact/optional/handoffs" issues already merged or still open? The proposed JSON shape depends on both.]
- [NEEDS CLARIFICATION: Does
runtimesfield already exist in the manifest for preset script entries, or only for extensions?] - [NEEDS CLARIFICATION: What is the exact
sourceobject shape — is it the "structured source provenance" companion, or a simpler{layer, presetId}dict?] - [NEEDS CLARIFICATION: Is
speckit-wizard-canvasin an external repo or this one?]
Generated by 💡 Assess a Feature Request by Installing and Running Spec Kit for issue #4213 · 623.2 AIC · ⌖ 13.8 AIC · ⊞ 36.5K · ◷
github-actions commented
on Aug 20, 2026 on Aug 20, 2026 – with GitHub ActionsContributorMore actionsFeature assessment — info-json-full-expansion · Stage 2/5: Research
Idea Research: Add --json to preset info and extension info
- Slug: info-json-full-expansion
- Created: 2026-08-20
- Evidence confidence (overall): medium
Users & Demand
speckit-wizard-canvas(in a companion repogithub/spec-kit-copilot) currently reconstructs CLI data client-side viacomposition/collect.mjs::parseProvidesEntriesand::parseHookDeclarations, pulling rawpreset.yml/extension.ymlwithjs-yaml. The issue body is the primary source. (confidence: high, cited)- IDE plugins and pre-commit hooks are cited as additional consumers (use cases 2 and 3 in the issue). (confidence: low, assumption — no independent signal beyond the requester)
Prior Art
--jsonflag already exists in the codebase forspecify workflow infoandspecify --features(src/specify_cli/workflows/_commands.py,src/specify_cli/__init__.py). The pattern is established. (confidence: high, cited: codebase)specify extension infoandspecify preset infoexist and currently output rich terminal text only — no--jsonflag. (confidence: high, cited: codebase lines_commands.py:1337and_commands.py:461)- Neither
list --jsonnorinfo --jsonexist yet for presets/extensions — zero results from codebase grep. (confidence: high, cited: codebase)
Market & Context
- Alternative users rely on today: parsing raw YAML on the client with
js-yaml, requiring clients to re-implement strategy shorthand, hook-phase, and script-runtime inference that the server already knows. (confidence: high, cited: issue body) - Cost of inaction: continued client-side reconstruction logic that drifts as server-side normalization evolves;
js-yamldependency persists. (confidence: medium, assumption — maintenance burden is plausible but unquantified)
Data & Constraints
- Companion dependencies identified in the issue and not yet merged per codebase inspection:
- "stable id / lookupId" — grep of entire
src/specify_cli/finds zero matches forstable_id,lookup_id,lookupId. (confidence: high, cited: codebase) - "artifact / optional / handoffs" on commands — grep finds no
handoffsin preset/extension command schemas anywhere insrc/. (confidence: high, cited: codebase) - "structured source provenance" —
sourceobject shape not implemented. (confidence: high, cited: codebase)
- "stable id / lookupId" — grep of entire
runtimesIS validated for extension scripts (extensions/__init__.pylines 628–639, post-[Feature]: Allow extensions to declare templates and scripts in their manifest #4010). Parity for preset script entries unconfirmed. (confidence: medium, cited: codebase)- Extension replace-only enforcement IS in place (
extensions/__init__.pylines 622–626), confirmingstrategyis not authorable on extension contributions. (confidence: high, cited: codebase)
Evidence Against the Idea
- The full proposed JSON shape depends on at least two unimplemented companions ("stable id / lookupId", "artifact/optional/handoffs"). Building
info --jsonbefore those land either produces an incomplete shape or blocks until companions ship. - The serialization scope is non-trivial: four strategy shorthands + hook-phase normalization + per-contribution schemas across four contribution types.
Gaps & Open Questions
- [NEEDS CLARIFICATION: Status of companion issues — "stable id / lookupId" and "artifact/optional/handoffs" — are they merged, open, or planned?]
- [NEEDS CLARIFICATION: Can
info --jsonship in a reduced form (omittingid,handoffs,artifact,optional) with companions added later, or must it be atomic?] - [NEEDS CLARIFICATION: Is
speckit-wizard-canvasthe only known downstream consumer?]
Sources
- GitHub issue [Feature]: Add --json output to preset info and extension info with fully-expanded per-contribution detail (per-pack detail view; complements list --json summary counts) #4213, github/spec-kit (policy: allowlisted)
src/specify_cli/presets/_commands.py,src/specify_cli/extensions/_commands.py,src/specify_cli/extensions/__init__.py,src/specify_cli/__init__.py,src/specify_cli/workflows/_commands.py(codebase)
Generated by 💡 Assess a Feature Request by Installing and Running Spec Kit for issue #4213 · 623.2 AIC · ⌖ 13.8 AIC · ⊞ 36.5K · ◷
github-actions commented
on Aug 20, 2026 on Aug 20, 2026 – with GitHub ActionsContributorMore actionsFeature assessment — info-json-full-expansion · Stage 3/5: Problem
Problem Definition: Add --json to preset info and extension info
- Slug: info-json-full-expansion
- Created: 2026-08-20
- Inputs used: intake.md | research.md
Problem Statement
Downstream consumers of the Specify CLI (wizard UIs, IDE plugins, tooling scripts) cannot get structured, normalized pack metadata programmatically —
specify preset infoandspecify extension infoonly emit human-readable terminal text — forcing each consumer to redundantly parse raw YAML and re-implement server-side normalization logic (strategy shorthand, hook-phase mapping, script-runtime inference) that the CLI already knows.Affected Users & Stakeholders
- Users: tooling authors consuming
specifyCLI output (e.g.,speckit-wizard-canvasmaintainers, IDE plugin developers, CI script authors) - Stakeholders: Specify CLI maintainers (API surface, backward compatibility),
speckit-wizard-canvas/spec-kit-copilotteam (primary known consumer), future downstream integrators
Goals
- Add
--jsontospecify preset info <id>andspecify extension info <id>so structured, fully-normalized pack metadata is available without parsing YAML - Normalize all shorthand keys server-side (
replaces/wraps/prepends/appends→strategy;phase/command→trigger/targetCommand) - Expose full per-contribution detail (commands, templates, scripts, hooks) — not summary counts
- Enable
speckit-wizard-canvasto drop itsjs-yamldependency and client-side normalization code
Non-Goals
- This is not
specify preset list --json/specify extension list --json(per-collection summary counts — a companion issue) - This is not
specify artifact info --json(per-artifact composition stack — another companion) - Detailed API design, data model, or task breakdown (belongs in specification)
Success Metrics
speckit-wizard-canvascan deletecomposition/collect.mjs::parseProvidesEntriesand::parseHookDeclarationsand replace them withspecify preset info <id> --json/specify extension info <id> --jsoncalls (qualitative; baseline: not possible today)- Zero client-side shorthand normalization code needed by any consumer (qualitative)
- Non-zero exit + stderr JSON error on unknown id (measurable; baseline: exits non-zero but no JSON error format)
Cost of Inaction
Downstream consumers continue to maintain parallel YAML-parsing and normalization logic that must stay in sync with CLI internals. As the CLI evolves, each consumer diverges independently. The
js-yamldependency persists inspeckit-wizard-canvaswith no obvious removal path.Open Questions
- [NEEDS CLARIFICATION: Are the "stable id / lookupId" and "artifact/optional/handoffs" companion issues merged, in progress, or still planned?]
- [NEEDS CLARIFICATION: Can a reduced
info --json(withoutid,handoffs,artifact,optional) ship first and be extended when companions land?] - [NEEDS CLARIFICATION: Is
speckit-wizard-canvasthe only confirmed downstream consumer actively blocked on this?]
Generated by 💡 Assess a Feature Request by Installing and Running Spec Kit for issue #4213 · 623.2 AIC · ⌖ 13.8 AIC · ⊞ 36.5K · ◷
github-actions commented
on Aug 20, 2026 on Aug 20, 2026 – with GitHub ActionsContributorMore actionsFeature assessment — info-json-full-expansion · Stage 4/5: Concept
Concept: Add --json to preset info and extension info
- Slug: info-json-full-expansion
- Created: 2026-08-20
- Recommended option: B — Incremental (core fields now, companions when ready)
Options
Option A — Full atomic implementation
- Sketch: Implement the complete JSON shape as described in the issue — including
id(stable-id scheme),handoffs,artifact,optional,source(provenance object) — in a single release. Block on all companion issues landing first. - Appetite: large (months — gated by companion delivery)
- Trade-offs: Wins: complete, consistent API surface from day one. Sacrifices: delays unblocking
speckit-wizard-canvas; implementation coupled to three other tracks with unknown timelines. - Rabbit holes: companion issue timelines unknown; atomic coupling risks the whole feature stalling indefinitely.
Option B — Incremental: core fields first, companions extended later
- Sketch: Ship
--jsonwith fields the CLI already has (idusing current pack id,name,description,version,author,priority,enabled, simplesourcedict) plus fully-normalizedcommands,templates,scripts(andhooksfor extensions) using existing contribution data. Omitartifact,optional,handoffsuntil the companion "artifact/optional/handoffs" issue lands; updateidto stable-id scheme when "stable id / lookupId" lands. Document deferred fields explicitly. - Appetite: medium (weeks)
- Trade-offs: Wins: unblocks
speckit-wizard-canvasstrategy/hook normalization immediately; establishes the--jsonsurface. Sacrifices: schema evolves across releases;idvalues may change when stable-id lands. - Rabbit holes: schema evolution requires clear versioning intent to avoid breaking consumers when
handoffs/artifact/idland.
Option C — Do nothing / document the YAML contract
- Sketch: Formally document
preset.yml/extension.ymlschema as a stable contract; optionally publish a JSON schema. No CLI change. - Appetite: small (days)
- Trade-offs: Wins: no CLI change; low effort. Sacrifices: clients still duplicate normalization logic;
js-yamldependency persists; normalization bugs must be fixed in every consumer. - Rabbit holes: a "stable YAML contract" may conflict with the CLI's desire to evolve its internal schema.
Recommendation
Option B — Incremental. The core problem (no machine-readable output, client-side normalization duplication) is solvable now without blocking on companions. Option B ships
--jsonwith fully-normalized strategy/hook data — enough forspeckit-wizard-canvasto drop YAML parsing. Theid/handoffs/artifact/optionalgap is well-defined and low-risk to document as a deferred extension. Option C doesn't address the normalization problem. Option A is the right long-term state but inflates delay and coupling risk.Out of Scope (for the recommended option)
- Stable
idvalues (pending "stable id / lookupId" companion) handoffs,artifact,optionalfields on command entries (pending companion)- Full
sourceprovenance object (pending "structured source provenance" companion) specify preset list --json/specify extension list --json(separate companion)specify artifact info --json(separate companion)
Assumptions to Validate
- Existing
PresetManager/ExtensionManagerstructures expose enough normalized contribution data to build the arrays without companion fields - Consumers are willing to adopt a schema that grows additional fields when companions land
- Strategy shorthand normalization is already centralized in CLI internals
Generated by 💡 Assess a Feature Request by Installing and Running Spec Kit for issue #4213 · 623.2 AIC · ⌖ 13.8 AIC · ⊞ 36.5K · ◷
github-actions commented
on Aug 20, 2026 on Aug 20, 2026 – with GitHub ActionsContributorMore actionsFeature assessment — info-json-full-expansion · Stage 5/5: Decision — verdict go
Decision: Add --json to preset info and extension info
- Slug: info-json-full-expansion
- Decided: 2026-08-20
- Verdict: go
- Artifacts reviewed: intake.md | research.md | problem.md | concept.md
Scorecard
Criterion Rating Justification Problem validity strong Real, documented pain: speckit-wizard-canvashas concrete client-side normalization code (parseProvidesEntries,parseHookDeclarations) that duplicates server logic already in the CLI.Evidence strength adequate Primary consumer ( speckit-wizard-canvas) is named and specific. Codebase confirms both commands exist with text-only output and--jsonis absent. Independent demand signal beyond the requester is thin (low-confidence for IDE/pre-commit use cases).Value vs. inaction strong Inaction leaves js-yamldependency and growing drift between CLI internals and every consumer's normalization copy. Incremental option ships real value quickly without companion blocking.Feasibility / appetite strong --jsonpattern is already established (workflow info,specify --features). Option B is medium appetite, does not require companion issues, and normalization logic lives in the CLI.Strategic fit strong Aligns with CLI as authoritative source for pack metadata; reduces client-side coupling; supports the broader machine-readable metadata family. Risk posture adequate Main risk is schema evolution: id,handoffs,artifact,optionalare deferred to companions. This is acknowledged and scoped — a planned extension seam, not an unmitigated risk.Verdict & Rationale
Go. The problem is real, the use case is specific and named, evidence strength clears the
adequatebar (codebase confirms the gap and the established--jsonpattern), the incremental concept is feasible within weeks, and strategic fit is strong. The companion dependencies (stable id, handoffs/artifact/optional) introduce schema-evolution risk, but Option B explicitly scopes them out and documents the deferral — this is a planned extension seam, not a blocking unknown. All criteria scoreadequateor better; the downgrade rule does not apply.Handoff to
/speckit-specify- Problem:
specify preset infoandspecify extension infooutput human-readable text only; downstream consumers must parse raw YAML and re-implement server-side normalization, creating duplication and drift. - Chosen approach: Option B — Incremental. Add
--jsonto both commands, outputting a single JSON object with fully-normalizedcommands,templates,scripts, andhooks(extensions) arrays using currently-available fields. Deferid(stable-id scheme),handoffs,artifact,optional, and fullsourceprovenance to companion issues; document deferred fields. - In scope:
--jsononpreset infoandextension info; per-contribution arrays with normalized strategy shorthand and hook-phase fields;runtimeson script entries; non-zero exit + JSON error on unknown id; tests (schema round-trip, normalization, replace-only enforcement); docs update. - Out of scope:
list --json,artifact info --json, stable-ididscheme,handoffs/artifact/optionalfields, full source provenance object. - Success metrics:
speckit-wizard-canvascan replacejs-yaml/parseProvidesEntries/parseHookDeclarationswithspecify * info --json; zero client-side shorthand normalization needed. - Carried-forward open questions:
- [NEEDS CLARIFICATION: Does existing
PresetManager/pack data expose contribution arrays in normalized form, or must normalization be added to the serialization layer?] - [NEEDS CLARIFICATION: Should deferred fields be present as
nullin the initial shape (forward-compatibility) or absent entirely?] - [NEEDS CLARIFICATION: Is
speckit-wizard-canvaswilling to adopt the incremental shape, or does it require the full shape before switching?]
- [NEEDS CLARIFICATION: Does existing
Generated by 💡 Assess a Feature Request by Installing and Running Spec Kit for issue #4213 · 623.2 AIC · ⌖ 13.8 AIC · ⊞ 36.5K · ◷
- addedfeature-goFeature assessment verdict: go — ready to hand off to /speckit.specifyFeature assessment verdict: go — ready to hand off to /speckit.specify
on Aug 20, 2026 I'd like to work on this. Before writing code, here is the scope I have in mind for a first PR, checked against
mainat 838f118. Could a maintainer confirm it or say what to change?In scope:
specify preset info <id> --jsonandspecify extension info <id> --jsonfor installed packs. Top-level fields come frominstalled_list_itemin_installed_list_json.py, so they matchlist --json(id,name,description,version,author,priority,enabled,source), with expanded arrays in place of theprovidescounts.commands,templatesandscriptsentries withname,description,sourcePathandsource. Preset entries carrystrategyas the manifest validates it (defaultreplace); extension entries leave it out, since extensions are replace-only. Extension scripts carryruntimes.- Extension
hookswithtrigger,targetCommand,optionalandpriority, using the defaultsspecify artifactalready applies (priority 10, optional true). - Unknown id: exit 1 with the
emit_json_errorenvelope on stderr. - Tests next to
tests/test_installed_list_json.py, and the--jsonshape in the CLI reference for both commands.
Left out, with questions:
- Per-entry
id. The lookup-id helpers inartifacts/_identifiers.pyare private to the artifact surface, and exposing ids through preset/extension info is what [Feature]: Add deterministic contribution IDs and stack lookup IDs for resolved artifacts #4210 tracks. Leaveidout for now, or reusederive_lookup_idso entries join withspecify artifactoutput? artifact,optionalandhandoffson commands depend on [Feature]: Add artifact, optional, and handoffs to the command manifest schema #4209, which is still under discussion, so I'd leave them out.runtimeson preset scripts needs a preset manifest schema change. Separate PR?- Shorthand keys. The CLI reads only
strategy:.replaces:appears inpresets/lean/preset.ymlbut nothing parses it, andwraps,prependsandappendsare not used anywhere. Is reporting the validatedstrategyenough, or shouldreplaces:and the others be mapped too? - A pack that is in the catalog but not installed: a JSON error, or the catalog metadata without the arrays?
#4776 also changes
presets/command_info.py; I'll rebase on whichever lands first.AI disclosure: posted by @nefayran. Claude Code (Claude Opus 5.5, max reasoning effort, human-supervised) read the code and drafted this comment; I checked it before posting.
- added 2 commits that reference this issue
on Oct 6, 2026 - added a commit that references this issue
on Oct 7, 2026
Problem Statement
Today
specify preset info <id>andspecify extension info <id>emit only text.speckit-wizard-canvasreads the rawpreset.yml/extension.ymlfiles withjs-yamland re-normalizes the shape itself incomposition/collect.mjs::parseProvidesEntriesand::parseHookDeclarations— including strategy inference from shorthand keys (replacesvs.wrapsvs.prependsvs.appends), hook-phase normalization (phasevs.trigger,commandvs.targetCommand), and script-runtime inference by globbingscripts/{bash,powershell,python}/*.{sh,ps1,py}. All of this is server-side data being reconstructed on the client.Downstream consumers need the structured shape returned by the CLI itself so they can stop reconstructing it.
How this differs from the companion
preset list --json/extension list --jsonissue. Thelistvariant operates on the collection of installed packs and returns a JSON array, one row per pack, whereprovidesis just integer counts ({ commands: 4, templates: 2, scripts: 1, hooks: 3 }) — a summary/catalog view suitable for "here's every preset the project has".infooperates on one pack, addressed by id, and returns a single JSON object whereprovidesis fully expanded — every command, template, script, and hook enumerated with its full per-contribution schema (id,name,description,artifact,optional,handoffs,strategy,sourcePath,runtimes, etc.). A wizard rendering "here's whatspeckit.gitcontributes to my project" needs theinfodetail;list's counts are not enough. Both surfaces are required; neither is a subset of the other.Proposed Solution
Add
--jsonto bothinfocommands. Output shape:{ "id": "…", "name": "…", "description": "…", "version": "…", "author": "…", "priority": 100, "enabled": true, "source": { "…": "…" }, "commands": [ { "id": "…", "name": "speckit.plan", "description": "…", "artifact": "specs/{feature}/plan.md", "optional": false, "handoffs": [ { "to": "speckit.tasks", "when": "…", "message": "…" } ], "strategy": "wrap", "source": { "layer": "preset", "presetId": "…" }, "sourcePath": "commands/speckit.plan.md" } ], "templates": [ { "id": "…", "name": "…", "description": "…", "strategy": "replace", "source": { "…": "…" }, "sourcePath": "templates/…" } ], "scripts": [ { "id": "…", "name": "…", "description": "…", "strategy": "replace", "source": { "…": "…" }, "sourcePath": "scripts/bash/…", "runtimes": ["bash", "powershell", "python"] } ], "hooks": [ { "id": "…", "name": "…", "description": "…", "trigger": "before_speckit.plan", "targetCommand": "speckit.git.checklist", "sourcePath": "commands/speckit.git.checklist.md", "optional": false, "priority": 10 } ] }Notes:
hooks.commands/templates/scriptsentries omitstrategy(they are alwaysreplace, per the replace-only rule enforced atextensions/__init__.py:622-626).idvalues use the stable-id scheme from the companion "stable id / lookupId" issue; theidon a per-contribution entry is what the companionspecify artifact info --jsonstack'slookupIdpoints at.artifact,optional,handoffson commands come from the companion "artifact/optional/handoffs" issue.runtimeson scripts comes directly from the manifest (extensions post-[Feature]: Allow extensions to declare templates and scripts in their manifest #4010; add the same field to preset script entries for parity).replaces/wraps/prepends/appends→strategy: "replace"|"wrap"|"prepend"|"append") is done server-side.Alternatives Considered
specify artifact info --jsoncommand. Rejected —artifact infois per-artifact (walks one composition stack across all installed packs);info --jsonis per-source (walks one preset/extension across all its contributions). Both are needed and neither is a subset of the other.preset list --json/extension list --json. Rejected — that surface is per-collection with summary counts;infois per-pack with full expansion. Different shape, different call pattern, different use cases (see Problem Statement).js-yaml.composition/collect.mjsand drift over time.Component
Specify CLI (initialization, commands)
AI Agent (if applicable)
Not applicable
Use Cases
speckit-wizard-canvasdeletescomposition/collect.mjs::parseProvidesEntriesand::parseHookDeclarations, replacing them withJSON.parse(execFileSync("specify", ["preset", "info", "<id>", "--json"]))/specify extension info <id> --json. This is the change that removes thejs-yamldependency.commands[]entry (description,artifact,handoffs).extension info --json'shooks[]to warn when two extensions register the sametriggerat the samepriority.Acceptance Criteria
specify preset info <id> --jsonandspecify extension info <id> --jsonemit a single JSON object with top-level fields matching the companionlist --jsonissue (id,name,description,version,author,priority,enabled,source) plus fully-expandedcommands,templates,scriptsarrays (andhooksfor extensions) — not integer counts.artifact,optional,handoffs(from the companion command-fields issue).runtimesfor both presets and extensions.strategy; extension entries omit it (or set to"replace"for informational purposes).replaces/wraps/prepends/appends) are normalized server-side intostrategy.trigger,targetCommand,sourcePath,optional,priority—phase/commandshorthand normalized.idvalues follow the stable-id scheme and are stable across reinstalls, matching thelookupIdvalues emitted byspecify artifact info --json.idcross-reference withspecify artifact info --jsonoutput.preset info/extension infosections in the CLI reference show the--jsonshape and normalization rules, plus a note contrastinginfo --json(per-pack, full expansion) withlist --json(per-collection, count summary).Additional Context
Direct replacement for
plugins/spec-kit-copilot-wizard/extensions/speckit-wizard-canvas/composition/collect.mjs::parseProvidesEntriesand::parseHookDeclarationsingithub/spec-kit-copilot. Depends on the companion "artifact/optional/handoffs" and "stable id / lookupId" issues; benefits from the companion "structured source provenance" issue.