github / github/spec-kit

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

Đang mở
#4,213 11 bình luận 0 reaction 0 người được giao Xem trên GitHub
enhancement feature-assess feature-go
Ngôn ngữ chính
Python
Star
137k
Fork
12.3k
Merge trung bình
2 ngày 12 giờ
Pull request đã merge (30 ngày)
159

Mô tả

### Problem Statement

Today `specify preset info ` and `specify extension info ` 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:

```json
{
"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-#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", "", "--json"]))` / `specify extension info --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 --json` and `specify extension info --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.

Hướng dẫn đóng góp

Mở hướng dẫn đóng góp

Hướng nghiên cứu

Start with the `preset info --json` and `extension info --json` CLI entry points, then trace the existing normalization in `composition/collect.mjs::parseProvidesEntries` and `::parseHookDeclarations`; review `extensions/__init__.py:622-626` for replace-only behavior. Compare the output with the companion `list --json` and `artifact info --json` contracts. Done means the specified expanded schemas, stable IDs, normalization, errors, tests, and CLI reference documentation are complete.

Do mô hình lập chỉ mục viết ra từ nội dung của issue.

Đánh giá

Công nghệ
javascript, python
Lĩnh vực
cli, documentation, testing
Loại issue
Tính năng
Độ khó
5/5
Thời gian dự kiến
Hơn một tuần
Mức độ hoạt động
Sôi nổi
Độ rõ ràng
Khá rõ ràng
Mức phù hợp với người mới
45/100

Nhận issue mới trong hộp thư của bạn

Bản tóm tắt ngắn những issue GitHub phù hợp với người mới.