Skip to content

[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

@nicolehaugen

Problem Statement

Today specify preset info <id> and specify extension info <id> emit only text. speckit-wizard-canvas reads the raw preset.yml / extension.yml files with js-yaml and re-normalizes the shape itself in composition/collect.mjs::parseProvidesEntries and ::parseHookDeclarations — including strategy inference from shorthand keys (replaces vs. wraps vs. prepends vs. appends), hook-phase normalization (phase vs. trigger, command vs. targetCommand), and script-runtime inference by globbing scripts/{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 --json issue. The list variant operates on the collection of installed packs and returns a JSON array, one row per pack, where provides is just integer counts ({ commands: 4, templates: 2, scripts: 1, hooks: 3 }) — a summary/catalog view suitable for "here's every preset the project has". info operates on one pack, addressed by id, and returns a single JSON object where provides is 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 what speckit.git contributes to my project" needs the info detail; list's counts are not enough. Both surfaces are required; neither is a subset of the other.

Proposed Solution

Add --json to both info commands. 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:

  • Preset objects omit hooks.
  • Extension commands/templates/scripts entries omit strategy (they are always replace, per the replace-only rule enforced at extensions/__init__.py:622-626).
  • id values use the stable-id scheme from the companion "stable id / lookupId" issue; the id on a per-contribution entry is what the companion specify artifact info --json stack's lookupId points at.
  • artifact, optional, handoffs on commands come from the companion "artifact/optional/handoffs" issue.
  • runtimes on 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).
  • All shorthand-key normalization (replaces/wraps/prepends/appends → strategy: "replace"|"wrap"|"prepend"|"append") is done server-side.

Alternatives Considered

  • Fold everything into the companion specify artifact info --json command. Rejected — artifact info is per-artifact (walks one composition stack across all installed packs); info --json is per-source (walks one preset/extension across all its contributions). Both are needed and neither is a subset of the other.
  • Fold everything into the companion preset list --json / extension list --json. Rejected — that surface is per-collection with summary counts; info is per-pack with full expansion. Different shape, different call pattern, different use cases (see Problem Statement).
  • Emit YAML. Rejected — the whole point is to let the wizard drop js-yaml.
  • Leave hook-phase / strategy shorthand un-normalized. Rejected — every consumer would reproduce the client-side logic from composition/collect.mjs and drift over time.

Component

Specify CLI (initialization, commands)

AI Agent (if applicable)

Not applicable

Use Cases

  1. speckit-wizard-canvas deletes composition/collect.mjs::parseProvidesEntries and ::parseHookDeclarations, replacing them with JSON.parse(execFileSync("specify", ["preset", "info", "<id>", "--json"])) / specify extension info <id> --json. This is the change that removes the js-yaml dependency.
  2. An IDE plugin renders hover-cards on command names by looking up the commands[] entry (description, artifact, handoffs).
  3. A pre-commit check walks extension info --json's hooks[] to warn when two extensions register the same trigger at the same priority.

Acceptance Criteria

  • specify preset info <id> --json and specify extension info <id> --json emit a single JSON object with top-level fields matching the companion list --json issue (id, name, description, version, author, priority, enabled, source) plus fully-expanded commands, templates, scripts arrays (and hooks for extensions) — not integer counts.
  • Command entries include artifact, optional, handoffs (from the companion command-fields issue).
  • Script entries include runtimes for both presets and extensions.
  • Preset command/template/script entries include strategy; extension entries omit it (or set to "replace" for informational purposes).
  • Shorthand keys (replaces/wraps/prepends/appends) are normalized server-side into strategy.
  • Hook entries include trigger, targetCommand, sourcePath, optional, priority — phase/command shorthand normalized.
  • All id values follow the stable-id scheme and are stable across reinstalls, matching the lookupId values emitted by specify artifact info --json.
  • Unknown id → non-zero exit + stderr JSON error.
  • Tests: schema round-trip, strategy normalization (all four shorthand forms), hook shorthand normalization, extension replace-only enforcement, handoffs frontmatter-merge, and id cross-reference with specify artifact info --json output.
  • Docs: preset info / extension info sections in the CLI reference show the --json shape and normalization rules, plus a note contrasting info --json (per-pack, full expansion) with list --json (per-collection, count summary).

Additional Context

Direct replacement for plugins/spec-kit-copilot-wizard/extensions/speckit-wizard-canvas/composition/collect.mjs::parseProvidesEntries and ::parseHookDeclarations in github/spec-kit-copilot. Depends on the companion "artifact/optional/handoffs" and "stable id / lookupId" issues; benefits from the companion "structured source provenance" issue.

Activity

  1. github-actions commented on Aug 19, 2026

    @github-actions
    Contributor

    Feature assessment — info-json-full-expansion · Stage 1/5: Intake

    Idea Intake: Add --json to preset info and extension info

    Idea (as captured)

    Add --json to both specify preset info <id> and specify 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 (and hooks for 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/command vs trigger/targetCommand) is also normalized. Unknown id exits non-zero with a JSON error on stderr.

    Restated

    Today specify preset info and specify extension info emit only human-readable text; downstream consumers such as speckit-wizard-canvas reconstruct the structured shape by parsing raw YAML files directly. This feature adds --json to 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-canvas component in the github/spec-kit-copilot repository re-parses preset.yml/extension.yml with js-yaml and re-implements strategy-inference and hook-normalization logic (parseProvidesEntries, parseHookDeclarations in composition/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 id fields? 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 --json cross-reference IDs be validated in this PR or deferred to the companion issue?]
    • [NEEDS CLARIFICATION: Is speckit-wizard-canvas the 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 · ◷

  2. github-actions commented on Aug 19, 2026

    @github-actions
    Contributor

    Feature 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

    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: Is list --json already 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 info implementation (src/specify_cli/presets/_commands.py, line 461): outputs Rich-formatted text only; no --json flag exists. Confirmed by codebase inspection. — [source: codebase] (confidence: high, cited)
    • Current extension info implementation (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 strategy is already rejected (src/specify_cli/extensions/__init__.py, lines 622–626): extensions cannot author strategy — enforced at the Python layer. — [source: codebase] (confidence: high, cited)
    • runtimes field 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

    Data & Constraints

    Evidence Against the Idea

    • Companion dependency risk: artifact/optional/handoffs and stable id / lookupId are 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 --json to 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 --json covers 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.yml loader normalize replaces/wraps/prepends/appends shorthand keys, or does it only accept canonical longform?]
    • [NEEDS CLARIFICATION: Are there additional known consumers beyond speckit-wizard-canvas?]

    Sources

    Generated by 💡 Assess a Feature Request by Installing and Running Spec Kit for issue #4213 · 614.8 AIC · ⌖ 12.3 AIC · ⊞ 38K · ◷

  3. github-actions commented on Aug 19, 2026

    @github-actions
    Contributor

    Feature 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 info and specify extension info cannot 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.yml directly.
    • Stakeholders: Spec Kit CLI maintainers — any change to preset.yml/extension.yml schema silently breaks client-side parsers without the CLI ever raising an error; this creates hidden coupling.

    Goals

    • specify preset info <id> --json and specify extension info <id> --json emit 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 --json in this work.
    • Architectural redesign of the YAML data model is out of scope.

    Success Metrics

    • speckit-wizard-canvas can delete parseProvidesEntries and parseHookDeclarations from composition/collect.mjs and replace them with a single specify preset info --json / specify extension info --json call. (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-yaml dependency in speckit-wizard-canvas remains, 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? The id, artifact, optional, and handoffs fields on command entries are blocked on them.]
    • [NEEDS CLARIFICATION: Does preset.yml accept shorthand strategy keys (replaces, wraps, etc.) or only canonical longform?]
    • [NEEDS CLARIFICATION: Should runtimes be 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 · ◷

  4. github-actions commented on Aug 19, 2026

    @github-actions
    Contributor

    Feature 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 --json to 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 (id stable scheme, artifact, optional, handoffs) are included as null with 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 — eliminating js-yaml parsing and most of the collect.mjs logic — 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 see null fields 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_version field mitigates this.

    Option B — Wait for all companion issues before shipping

    • Sketch: Do not add --json until stable id / lookupId, artifact/optional/handoffs, and structured source provenance are 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-canvas keeps js-yaml and 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 --json but return only top-level metadata (id, name, description, version, author, priority, enabled, source); omit commands, templates, scripts, hooks arrays.
    • Appetite: small (days)
    • Trade-offs: Wins: trivially easy, low risk. Sacrifices: does not address the primary use case — speckit-wizard-canvas still needs the contribution arrays and still needs js-yaml. Almost no payoff.
    • Rabbit holes: None, but no value either.

    Recommendation

    Option A — phased delivery with null stubs for companion-dependent fields. The primary value (eliminating client-side YAML parsing and normalization re-implementation) is achievable now without the companions. A null stub 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 --json is additive. Shape instability is mitigated by documenting the contract and including a schema_version field.

    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, handoffs fields on command entries (stubs to null here; companion fills them)
    • Changes to preset.yml / extension.yml schema

    Assumptions to Validate

    • Canonical longform strategy values are already stored after YAML parsing and do not require additional shorthand normalization in the --json path.
    • The runtimes field 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-canvas is willing to handle null stubs 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 · ◷

  5. github-actions commented on Aug 19, 2026

    @github-actions
    Contributor

    Feature 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 go can be issued:

    1. Companion merge status: The JSON shape explicitly depends on companion issues (stable id / lookupId and artifact/optional/handoffs) for the id, artifact, optional, and handoffs fields 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 a null-stub period — or the team reconsiders in favor of Option B (wait for all companions).

    2. Shorthand normalization scope: The issue asserts that replaces/wraps/prepends/appends shorthand 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 (not weak) 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 a go verdict 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 / lookupId and artifact/optional/handoffs) already merged or open? If open, what is their expected timeline?]
      • [NEEDS CLARIFICATION: Does the current preset.yml loader accept shorthand strategy keys (replaces, wraps, prepends, appends), or only canonical longform (replace, wrap, prepend, append)?]
    • 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 · ◷

  6. nicolehaugen commented on Aug 19, 2026

    @nicolehaugen
    ContributorAuthor

    [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.

  7. added
    feature-assessRun the Spec Kit idea-assessment pipeline on this feature request
    and removed
    feature-assessRun the Spec Kit idea-assessment pipeline on this feature request
    on Aug 19, 2026
  8. added
    feature-assessRun the Spec Kit idea-assessment pipeline on this feature request
    and removed
    feature-assessRun the Spec Kit idea-assessment pipeline on this feature request
    on Aug 20, 2026
  9. github-actions commented on Aug 20, 2026

    @github-actions
    Contributor

    Feature assessment — info-json-full-expansion · Stage 1/5: Intake

    Idea Intake: Add --json to preset info and extension info

    Idea (as captured)

    Add --json to both specify preset info <id> and specify extension info <id> commands. The output should be a single JSON object with fully-expanded commands, templates, scripts, and hooks (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 omit strategy (always replace). Companion to the list --json issue but distinct: info is per-pack full expansion; list is 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 --json output to specify preset info and specify extension info so that structured, fully-normalized metadata can be consumed directly from the CLI without client-side reconstruction.

    Origin & Context

    • Raised by: @nicolehaugen
    • Trigger: speckit-wizard-canvas currently uses js-yaml + composition/collect.mjs::parseProvidesEntries and ::parseHookDeclarations to 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 runtimes field already exist in the manifest for preset script entries, or only for extensions?]
    • [NEEDS CLARIFICATION: What is the exact source object shape — is it the "structured source provenance" companion, or a simpler {layer, presetId} dict?]
    • [NEEDS CLARIFICATION: Is speckit-wizard-canvas in 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 · ◷

  10. github-actions commented on Aug 20, 2026

    @github-actions
    Contributor

    Feature 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 repo github/spec-kit-copilot) currently reconstructs CLI data client-side via composition/collect.mjs::parseProvidesEntries and ::parseHookDeclarations, pulling raw preset.yml/extension.yml with js-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

    • --json flag already exists in the codebase for specify workflow info and specify --features (src/specify_cli/workflows/_commands.py, src/specify_cli/__init__.py). The pattern is established. (confidence: high, cited: codebase)
    • specify extension info and specify preset info exist and currently output rich terminal text only — no --json flag. (confidence: high, cited: codebase lines _commands.py:1337 and _commands.py:461)
    • Neither list --json nor info --json exist 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-yaml dependency 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:
      1. "stable id / lookupId" — grep of entire src/specify_cli/ finds zero matches for stable_id, lookup_id, lookupId. (confidence: high, cited: codebase)
      2. "artifact / optional / handoffs" on commands — grep finds no handoffs in preset/extension command schemas anywhere in src/. (confidence: high, cited: codebase)
      3. "structured source provenance" — source object shape not implemented. (confidence: high, cited: codebase)
    • runtimes IS validated for extension scripts (extensions/__init__.py lines 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__.py lines 622–626), confirming strategy is 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 --json before 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 --json ship in a reduced form (omitting id, handoffs, artifact, optional) with companions added later, or must it be atomic?]
    • [NEEDS CLARIFICATION: Is speckit-wizard-canvas the only known downstream consumer?]

    Sources

    Generated by 💡 Assess a Feature Request by Installing and Running Spec Kit for issue #4213 · 623.2 AIC · ⌖ 13.8 AIC · ⊞ 36.5K · ◷

  11. github-actions commented on Aug 20, 2026

    @github-actions
    Contributor

    Feature 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 info and specify extension info only 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 specify CLI output (e.g., speckit-wizard-canvas maintainers, IDE plugin developers, CI script authors)
    • Stakeholders: Specify CLI maintainers (API surface, backward compatibility), speckit-wizard-canvas / spec-kit-copilot team (primary known consumer), future downstream integrators

    Goals

    • Add --json to specify preset info <id> and specify 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-canvas to drop its js-yaml dependency 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-canvas can delete composition/collect.mjs::parseProvidesEntries and ::parseHookDeclarations and replace them with specify preset info <id> --json / specify extension info <id> --json calls (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-yaml dependency persists in speckit-wizard-canvas with 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 (without id, handoffs, artifact, optional) ship first and be extended when companions land?]
    • [NEEDS CLARIFICATION: Is speckit-wizard-canvas the 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 · ◷

  12. github-actions commented on Aug 20, 2026

    @github-actions
    Contributor

    Feature 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 --json with fields the CLI already has (id using current pack id, name, description, version, author, priority, enabled, simple source dict) plus fully-normalized commands, templates, scripts (and hooks for extensions) using existing contribution data. Omit artifact, optional, handoffs until the companion "artifact/optional/handoffs" issue lands; update id to stable-id scheme when "stable id / lookupId" lands. Document deferred fields explicitly.
    • Appetite: medium (weeks)
    • Trade-offs: Wins: unblocks speckit-wizard-canvas strategy/hook normalization immediately; establishes the --json surface. Sacrifices: schema evolves across releases; id values may change when stable-id lands.
    • Rabbit holes: schema evolution requires clear versioning intent to avoid breaking consumers when handoffs/artifact/id land.

    Option C — Do nothing / document the YAML contract

    • Sketch: Formally document preset.yml/extension.yml schema 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-yaml dependency 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 --json with fully-normalized strategy/hook data — enough for speckit-wizard-canvas to drop YAML parsing. The id/handoffs/artifact/optional gap 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 id values (pending "stable id / lookupId" companion)
    • handoffs, artifact, optional fields on command entries (pending companion)
    • Full source provenance 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/ExtensionManager structures 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 · ◷

  13. github-actions commented on Aug 20, 2026

    @github-actions
    Contributor

    Feature 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-canvas has 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 --json is absent. Independent demand signal beyond the requester is thin (low-confidence for IDE/pre-commit use cases).
    Value vs. inaction strong Inaction leaves js-yaml dependency and growing drift between CLI internals and every consumer's normalization copy. Incremental option ships real value quickly without companion blocking.
    Feasibility / appetite strong --json pattern 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, optional are 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 adequate bar (codebase confirms the gap and the established --json pattern), 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 score adequate or better; the downgrade rule does not apply.

    Handoff to /speckit-specify

    • Problem: specify preset info and specify extension info output 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 --json to both commands, outputting a single JSON object with fully-normalized commands, templates, scripts, and hooks (extensions) arrays using currently-available fields. Defer id (stable-id scheme), handoffs, artifact, optional, and full source provenance to companion issues; document deferred fields.
    • In scope: --json on preset info and extension info; per-contribution arrays with normalized strategy shorthand and hook-phase fields; runtimes on 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-id id scheme, handoffs/artifact/optional fields, full source provenance object.
    • Success metrics: speckit-wizard-canvas can replace js-yaml/parseProvidesEntries/parseHookDeclarations with specify * 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 null in the initial shape (forward-compatibility) or absent entirely?]
      • [NEEDS CLARIFICATION: Is speckit-wizard-canvas willing to adopt the incremental shape, or does it require the full shape before switching?]

    Generated by 💡 Assess a Feature Request by Installing and Running Spec Kit for issue #4213 · 623.2 AIC · ⌖ 13.8 AIC · ⊞ 36.5K · ◷

  14. added
    feature-goFeature assessment verdict: go — ready to hand off to /speckit.specify
    on Aug 20, 2026
  15. assigned and unassigned on Aug 20, 2026
  16. nefayran commented on Oct 2, 2026

    @nefayran
    Contributor

    I'd like to work on this. Before writing code, here is the scope I have in mind for a first PR, checked against main at 838f118. Could a maintainer confirm it or say what to change?

    In scope:

    • specify preset info <id> --json and specify extension info <id> --json for installed packs. Top-level fields come from installed_list_item in _installed_list_json.py, so they match list --json (id, name, description, version, author, priority, enabled, source), with expanded arrays in place of the provides counts.
    • commands, templates and scripts entries with name, description, sourcePath and source. Preset entries carry strategy as the manifest validates it (default replace); extension entries leave it out, since extensions are replace-only. Extension scripts carry runtimes.
    • Extension hooks with trigger, targetCommand, optional and priority, using the defaults specify artifact already applies (priority 10, optional true).
    • Unknown id: exit 1 with the emit_json_error envelope on stderr.
    • Tests next to tests/test_installed_list_json.py, and the --json shape in the CLI reference for both commands.

    Left out, with questions:

    1. Per-entry id. The lookup-id helpers in artifacts/_identifiers.py are 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. Leave id out for now, or reuse derive_lookup_id so entries join with specify artifact output?
    2. artifact, optional and handoffs on 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.
    3. runtimes on preset scripts needs a preset manifest schema change. Separate PR?
    4. Shorthand keys. The CLI reads only strategy:. replaces: appears in presets/lean/preset.yml but nothing parses it, and wraps, prepends and appends are not used anywhere. Is reporting the validated strategy enough, or should replaces: and the others be mapped too?
    5. 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.

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

Metadata

Metadata

Assignees

No one assigned

    Labels

    enhancementfeature-assessRun the Spec Kit idea-assessment pipeline on this feature requestfeature-goFeature assessment verdict: go — ready to hand off to /speckit.specify

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions