@benjaminthomas/spec-driven-dev 0.0.0-stage → 1.4.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (29) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +483 -2
  3. package/bin/cli.mjs +357 -0
  4. package/package.json +12 -4
  5. package/skills/generative-seo/SKILL.md +255 -0
  6. package/skills/generative-seo/assets/citation-log-template.md +17 -0
  7. package/skills/generative-seo/assets/competitor-analysis-template.md +20 -0
  8. package/skills/generative-seo/assets/content-plan-template.md +15 -0
  9. package/skills/generative-seo/assets/geo-config-template.md +33 -0
  10. package/skills/generative-seo/assets/geo-playbook-template.md +22 -0
  11. package/skills/generative-seo/assets/social-queue-template.md +8 -0
  12. package/skills/generative-seo/references/geo-methodology.md +143 -0
  13. package/skills/spec-checkpoint/SKILL.md +106 -0
  14. package/skills/spec-create/SKILL.md +149 -0
  15. package/skills/spec-create/references/action-required-template.md +53 -0
  16. package/skills/spec-create/references/readme-template.md +53 -0
  17. package/skills/spec-create/references/requirements-template.md +54 -0
  18. package/skills/spec-create/references/task-template.md +86 -0
  19. package/skills/spec-implement/SKILL.md +236 -0
  20. package/skills/spec-implement/references/coder-prompt-template.md +48 -0
  21. package/skills/spec-implement/references/fix-prompt-template.md +38 -0
  22. package/skills/spec-implement/references/review-prompt-template.md +50 -0
  23. package/skills/spec-investigate/SKILL.md +323 -0
  24. package/skills/spec-investigate/references/report-template.md +53 -0
  25. package/skills/spec-setup/SKILL.md +99 -0
  26. package/skills/spec-setup/references/config-template.yml +45 -0
  27. package/skills/spec-ship/SKILL.md +218 -0
  28. package/skills/spec-verify/SKILL.md +153 -0
  29. package/skills/spec-verify/references/report-template.md +57 -0
@@ -0,0 +1,218 @@
1
+ ---
2
+ name: spec-ship
3
+ description: >
4
+ Push the current branch to GitHub and create a pull request. Use this skill when the user says
5
+ "ship it", "ship this", "push to github", "create a pr", "open a pull request", "send for review",
6
+ "get this reviewed", or wants to push their work and open a PR. Also use when the user says
7
+ "/spec-ship" (or their host's equivalent invocation syntax). This skill handles prerequisites,
8
+ branching, pushing, and PR creation — it does not commit or run quality checks (use
9
+ spec-checkpoint for that first).
10
+ license: MIT
11
+ ---
12
+
13
+ # Ship It
14
+
15
+ Push your work to GitHub and open a pull request — handling prerequisites, branch creation, pushing, and PR generation automatically.
16
+
17
+ This skill complements `spec-checkpoint`. Use `spec-checkpoint` to commit locally (with quality gates), then `spec-ship` to get the code to GitHub for review.
18
+
19
+ ## Project config (read first)
20
+
21
+ Load `.spec-driven.yml`: walk up from the current directory to the home folder, and the first one
22
+ found wins (a `multi-repo` config only applies inside the repos it lists). Its values beat anything
23
+ you would detect or assume. This skill uses `git.remote`, `git.pr_target`, `git.branch_name`, `tracker` (to link the ticket in the PR), and `layout`/`repos`.
24
+
25
+ **Multi-repo:** push and open one PR per repo that has unpushed commits, and list the sibling PRs in each PR's body so reviewers see the whole change.
26
+
27
+ **No config?** If the `spec-setup` skill is available, run it first, then continue here. If it
28
+ isn't, detect what this skill needs from the repo, ask about anything ambiguous, and offer to save
29
+ the answers to `.spec-driven.yml` (keys: `layout`, `repos`, `tracker`, `git`, `commands`,
30
+ `specs_dir`).
31
+
32
+ ## Instructions
33
+
34
+ ### Step 0: Prerequisites
35
+
36
+ Verify tooling before doing anything else.
37
+
38
+ 1. **GitHub CLI installed?**
39
+ ```bash
40
+ gh --version
41
+ ```
42
+ If the command fails (not found):
43
+ - Detect the platform and attempt to install:
44
+ - **Windows:** `winget install --id GitHub.cli`
45
+ - **macOS:** `brew install gh`
46
+ - **Linux (Debian/Ubuntu):** follow the official apt instructions
47
+ - If auto-install fails, tell the user what to install and stop.
48
+
49
+ 2. **GitHub CLI authenticated?**
50
+ ```bash
51
+ gh auth status
52
+ ```
53
+ If not authenticated, tell the user:
54
+ ```
55
+ GitHub CLI is not logged in. Please run this in the prompt:
56
+ ! gh auth login
57
+ Then re-run /spec-ship.
58
+ ```
59
+ Stop here — do not proceed until auth is confirmed.
60
+
61
+ 3. **Git remote exists?**
62
+ ```bash
63
+ git remote -v
64
+ ```
65
+ If no remote named `origin` exists, stop and tell the user:
66
+ ```
67
+ No git remote found. Add one with:
68
+ git remote add origin https://github.com/{user}/{repo}.git
69
+ ```
70
+
71
+ ### Step 1: Detect the Environment
72
+
73
+ Run these commands to understand the current state:
74
+
75
+ 1. `git branch --show-current` — get the current branch name
76
+ 2. Detect the default branch:
77
+ ```bash
78
+ gh repo view --json defaultBranchRef --jq '.defaultBranchRef.name'
79
+ ```
80
+ 3. `git status --porcelain` — check for uncommitted changes
81
+
82
+ If there are uncommitted changes, stop and tell the user:
83
+ ```
84
+ You have uncommitted changes. Run /spec-checkpoint first to commit them, then /spec-ship to push.
85
+ ```
86
+
87
+ Store the default branch name for use throughout the remaining steps. If `.spec-driven.yml` sets
88
+ `git.pr_target` (anything other than `default`), use that as `{default_branch}` everywhere below,
89
+ including as the PR's `--base`. Use `git.remote` instead of `origin` if it's set.
90
+
91
+ ### Step 2: Check for Unpushed Commits
92
+
93
+ Determine if there are commits that haven't been pushed yet.
94
+
95
+ **If on a feature branch with a remote tracking branch:**
96
+ ```bash
97
+ git log @{upstream}..HEAD --oneline
98
+ ```
99
+
100
+ **If on a feature branch with no remote tracking branch, or on the default branch:**
101
+ ```bash
102
+ git log origin/{default_branch}..HEAD --oneline
103
+ ```
104
+
105
+ If there are **no unpushed commits**, stop and tell the user:
106
+ ```
107
+ Nothing to ship — all commits are already pushed.
108
+ ```
109
+
110
+ Save the list of unpushed commit messages for use in later steps.
111
+
112
+ ### Step 3: Handle Branching
113
+
114
+ **If already on a feature branch** (not the default branch):
115
+ - Stay on it. No branching needed.
116
+ - Skip to Step 4.
117
+
118
+ **If on the default branch:**
119
+ - If the config sets `git.branch_name`, fill in its placeholders (`{ticket}` from the commits or
120
+ investigation, `{slug}` and `{type}` as below) and skip the derivation that follows.
121
+ - Otherwise, generate a branch name from the unpushed commit messages:
122
+ - Read the commit subjects
123
+ - Derive a kebab-case branch name with a conventional prefix: `feat/`, `fix/`, `refactor/`, `chore/`, `docs/` based on the commit content
124
+ - Keep it short (3-5 words max after the prefix), e.g., `feat/add-user-auth`, `fix/login-redirect-loop`
125
+ - Strip special characters, lowercase everything
126
+ - Create and switch to the new branch:
127
+ ```bash
128
+ git checkout -b {branch_name}
129
+ ```
130
+ - Tell the user: `Created branch {branch_name}`
131
+
132
+ ### Step 4: Confirm Before Pushing
133
+
134
+ Pushing and opening a PR are visible to others and not easily undone — confirm with the user
135
+ before proceeding, even if your host would otherwise run this skill non-interactively without
136
+ prompting. Show:
137
+
138
+ ```
139
+ About to push and open a PR:
140
+ Branch: {branch_name}
141
+ Remote: origin
142
+ Commits:
143
+ {list of unpushed commit subjects, from Step 2}
144
+
145
+ Proceed? (yes/no)
146
+ ```
147
+
148
+ Wait for an explicit yes. If the user declines or doesn't respond affirmatively, stop here —
149
+ do not push.
150
+
151
+ ### Step 5: Push to Origin
152
+
153
+ ```bash
154
+ git push -u origin {branch_name}
155
+ ```
156
+
157
+ If the branch already has a remote tracking branch, a regular `git push` is fine.
158
+
159
+ ### Step 6: Check for Existing PR
160
+
161
+ Before creating a new PR, check if one already exists for this branch:
162
+
163
+ ```bash
164
+ gh pr view --json number,url,title,state 2>/dev/null
165
+ ```
166
+
167
+ If a PR already exists and is **open**:
168
+ - Do NOT create a new one
169
+ - Skip to Step 8 and report the existing PR with a note that new commits were pushed.
170
+
171
+ If no PR exists (or it is closed/merged), proceed to Step 7.
172
+
173
+ ### Step 7: Create the Pull Request
174
+
175
+ Generate the PR title and body from the unpushed commits:
176
+
177
+ - **Title**: concise summary under 70 chars. If single commit, use its subject. If multiple, synthesize a short summary. Imperative mood.
178
+ - **Body**: TL;DR of the changes in 2-4 bullet points max, plus a footer naming whichever
179
+ agent/model actually generated the PR — never hardcode a specific vendor or model name, since
180
+ this skill runs under many different hosts. Omit the footer entirely if your host has no clean
181
+ way to identify itself.
182
+
183
+ ```bash
184
+ gh pr create --base {default_branch} --head {branch_name} --title "{title}" --body "$(cat <<'EOF'
185
+ ## Summary
186
+ {2-4 bullet points}
187
+
188
+ ---
189
+ Generated by {agent name}
190
+ EOF
191
+ )"
192
+ ```
193
+
194
+ ### Step 8: Report
195
+
196
+ Display the result clearly:
197
+
198
+ ```
199
+ Shipped to GitHub:
200
+ Branch: {branch_name}
201
+ PR: #{number} — {title}
202
+ URL: {url}
203
+ ```
204
+
205
+ ## Important
206
+
207
+ - Do NOT run lint, type-check, or build — that is spec-checkpoint's job
208
+ - Do NOT commit anything — only push existing commits and create a PR
209
+ - If the user has uncommitted changes, tell them to run /spec-checkpoint first
210
+ - Keep the PR body short — a TL;DR, not an essay
211
+ - Always check for an existing open PR before creating a new one to avoid duplicates
212
+ - Detect the default branch dynamically — do not hardcode `main` or `master`
213
+ - When creating a branch from the default branch, use conventional prefixes (`feat/`, `fix/`, etc.) with kebab-case names
214
+ - Never run destructive git operations (no `--force`, no `reset --hard`)
215
+ - If `gh` is not installed or authenticated, help the user get set up before proceeding
216
+ - Always get explicit user confirmation before pushing or opening a PR (Step 4) — do this even
217
+ if your host would otherwise let the skill run non-interactively, since pushing and opening a
218
+ PR are visible to others and not easily undone
@@ -0,0 +1,153 @@
1
+ ---
2
+ name: spec-verify
3
+ description: >
4
+ Verify a completed feature spec by driving the real running app — not just lint/typecheck/build
5
+ — and checking off every acceptance criterion from its specs/{feature}/ folder one by one. Use
6
+ this after /spec-implement finishes a spec, when the user says "test this end to end",
7
+ "verify this feature actually works", "did we actually build this right", or "/spec-verify",
8
+ and before /spec-ship or opening a PR. This is the spec-aware sibling of the generic /verify and
9
+ /run skills — /verify checks an arbitrary diff's runtime behavior and /run just launches the
10
+ app, but this skill specifically reads a spec's requirements.md and task files, builds a master
11
+ checklist of acceptance criteria, and reports pass/fail per criterion with real evidence
12
+ (screenshots, API responses, DB state) instead of a vague "looks good." Always invoke this when
13
+ a specs/{feature}/ folder exists and its implementation just finished, even if the user only
14
+ says "does this work" or "test it."
15
+ license: MIT
16
+ ---
17
+
18
+ # Verify Feature
19
+
20
+ Close the loop that `spec-create` → `spec-implement` leaves open: passing lint, typecheck, and
21
+ build proves the code compiles, not that the feature does what the spec says it does. This skill
22
+ reads a spec's acceptance criteria and checks each one against the actual running application —
23
+ clicking through the UI, calling the real API routes, or inspecting real database state produced
24
+ by the real code path. It produces a report the user can trust before shipping.
25
+
26
+ ## Project config (read first)
27
+
28
+ Load `.spec-driven.yml`: walk up from the current directory to the home folder, and the first one
29
+ found wins (a `multi-repo` config only applies inside the repos it lists). Its values beat anything
30
+ you would detect or assume. This skill uses `commands.dev`, `commands.dev_url`, and `layout`/`repos`.
31
+
32
+ **Monorepo / multi-repo:** start every app or service the criteria need (e.g. the API and the frontend), each with its own `dev` command.
33
+
34
+ **No config?** If the `spec-setup` skill is available, run it first, then continue here. If it
35
+ isn't, detect what this skill needs from the repo, ask about anything ambiguous, and offer to save
36
+ the answers to `.spec-driven.yml` (keys: `layout`, `repos`, `tracker`, `git`, `commands`,
37
+ `specs_dir`).
38
+
39
+ ## When there's no spec folder
40
+
41
+ If the user asks to verify a feature that wasn't built through `spec-create`, don't refuse —
42
+ interview them briefly for what was built and what "working" means (the golden path, the edge
43
+ cases they care about), then skip to [Step 3](#step-3-prepare-the-environment) treating their
44
+ answers as the criteria list. The spec-driven path below is the common case, not the only one.
45
+
46
+ ## Step 1: Locate the spec
47
+
48
+ 1. If the user named a feature, use `specs/{feature}/`.
49
+ 2. Otherwise look for a `specs/*/README.md` whose Task Status section is fully checked (all
50
+ tasks `- [x]`) but has no `verification-report.md` sibling yet — that's the most recently
51
+ completed, not-yet-verified feature.
52
+ 3. If `spec-implement` hasn't finished all batches yet (some tasks still `- [ ]`), tell the user
53
+ and ask whether to verify what's done so far or wait for the rest — verifying half a feature
54
+ can produce confusing false failures for criteria that depend on an unbuilt task.
55
+
56
+ ## Step 2: Build the master criteria checklist
57
+
58
+ Read `requirements.md`'s **Acceptance Criteria** section (feature-level, the whole thing working
59
+ end-to-end) and every `tasks/task-*.md`'s own **Acceptance Criteria** section (task-level). Merge
60
+ them into one ordered list, each item tagged with its source (`requirements` or the task
61
+ filename).
62
+
63
+ Split the merged list into two kinds, because they're verified completely differently:
64
+
65
+ - **Static criteria** — things like "lint passes" or "the production build succeeds."
66
+ `spec-implement`'s review gate already ran these during the build. Re-run them once quickly
67
+ to confirm nothing regressed since (uncommitted fix-ups, a rebase, etc.), but don't treat this
68
+ as the interesting part of verification.
69
+ - **Behavioral criteria** — anything that describes what a user, an API caller, or a scheduled
70
+ job actually observes ("a FREE user sees a Renew button," "the cron doesn't double-send,"
71
+ "removing a member revokes their access on next request"). These are why this skill exists —
72
+ they require driving the real app, not reading the diff.
73
+
74
+ ## Step 3: Prepare the environment
75
+
76
+ Check whether the app is already running (`curl -sf {commands.dev_url}`, or the port the
77
+ project's dev script uses) before starting a new one, since a stray second instance just causes
78
+ confusing port conflicts. If nothing responds, start `commands.dev` from the config (or the
79
+ project's own dev script) in the background and poll until it's ready.
80
+
81
+ Look at what the behavioral criteria actually need before reaching for tools:
82
+
83
+ - **UI-observable** (a button appears, a page shows a value, a flow completes) → browser
84
+ automation. Use whatever browser-automation capability your host provides — a browser MCP
85
+ server (Playwright, Puppeteer, etc.), a built-in browser tool, or a browser extension — and
86
+ enable/load it per your host's own convention if it isn't active by default. Take a screenshot
87
+ as evidence for each criterion you check this way.
88
+ - **API-only** (no UI surface, e.g. a webhook or a cron route) → call the real route. For
89
+ session-gated routes, log in through the actual UI once (or reuse a session cookie from a
90
+ browser step) rather than fabricating auth state. For routes gated by a bearer secret (like a
91
+ cron's `CRON_SECRET`), call them directly with `curl`.
92
+ Note: if your browser tool can read console/network logs, that's useful when a criterion is
93
+ best confirmed by watching what the frontend actually sent/received rather than clicking
94
+ through screenshots.
95
+ - **DB-state-only** (a column got stamped correctly, a row was scoped the way it should be) →
96
+ drive the real write path first (through the UI or API — never insert the expected state
97
+ directly, that verifies nothing), then read the resulting row back with the project's own DB client or CLI to
98
+ confirm it. This mirrors how you'd sanity-check a migration: trust the app's own code path to
99
+ produce the state, and only use direct DB reads for the *assertion*, never the *setup*.
100
+ - **Timing-dependent** (a reminder email fires N days before expiry, idempotency across cron
101
+ runs) → don't wait real days. Insert or edit the relevant date field in the test data so it
102
+ already sits at the boundary the criterion describes, then invoke the real code path (call the
103
+ cron route, run the actual query) and observe what happens. You're still exercising the real
104
+ logic — you're just moving the clock via input data instead of a `sleep`.
105
+
106
+ Create whatever throwaway test data (a second test user, a lapsed subscription row, etc.) each
107
+ criterion needs. Note everything you create — you'll remove it in Step 5.
108
+
109
+ ## Step 4: Verify each criterion
110
+
111
+ Work through the checklist in order. For each one, record:
112
+
113
+ - **Verdict**: PASS, FAIL, or SKIPPED (with a reason — e.g. "requires a live payment gateway
114
+ webhook, not reproducible locally").
115
+ - **Evidence**: a screenshot path, the exact `curl` command and response, or the DB query and
116
+ the row it returned. Evidence is what makes the report trustworthy instead of another
117
+ unverified claim — write down enough that someone who wasn't watching could confirm it.
118
+ - **For a FAIL**: the concrete scenario that breaks it (exact input/state → actual vs expected
119
+ output), not just "doesn't work." This is what turns a failure into something fixable.
120
+
121
+ Don't stop at the first failure — finish the checklist so the report reflects the feature's real
122
+ state, not just the first thing that went wrong.
123
+
124
+ ## Step 5: Clean up
125
+
126
+ Remove every test user, record, or row you created in Step 3/4 so the dev database is left the
127
+ way you found it. Never delete data that predates this run — if you're not certain something is
128
+ yours, leave it. If you started the dev server yourself in Step 3, it's fine to leave it running
129
+ (the user likely wants it for their own follow-up testing) — just say so in the report.
130
+
131
+ ## Step 6: Report
132
+
133
+ Write `specs/{feature}/verification-report.md` — see `references/report-template.md` for the
134
+ exact structure (a summary line, then a table of criterion → source → verdict → evidence, then a
135
+ "Failures" section with full repro detail for anything that didn't pass).
136
+
137
+ Update `specs/{feature}/README.md` with a short **Verification** section linking to the report
138
+ and stating the overall status (all pass / N of M pass).
139
+
140
+ Then tell the user directly:
141
+
142
+ ```
143
+ Verified {feature}: {X}/{Y} criteria passed.
144
+
145
+ {If all pass:} Ready to ship.
146
+ {If failures:} {N} failing — see specs/{feature}/verification-report.md for exact repro steps.
147
+ Options: loop back to /spec-implement to fix, or fix manually.
148
+ ```
149
+
150
+ This skill only verifies and reports — it does not fix failures itself. Mixing "test" and "fix"
151
+ in one pass makes it too easy to quietly patch a failure without recording that it happened;
152
+ keeping them separate means the report is always an honest snapshot of what was actually true
153
+ when you ran it.
@@ -0,0 +1,57 @@
1
+ # Verification Report Template
2
+
3
+ Use this structure for `specs/{feature}/verification-report.md`.
4
+
5
+ ## Template
6
+
7
+ ```markdown
8
+ # Verification Report: {Feature Name}
9
+
10
+ Verified: {date} · {X}/{Y} criteria passed
11
+
12
+ ## Summary
13
+
14
+ {One or two sentences: overall status, and anything a reviewer should know before reading
15
+ further — e.g. "All criteria pass; the Renew button was tested against all three checkout
16
+ providers by swapping ACTIVE_PAYMENT_PROVIDER." or "2 failures, both in the reminder-email
17
+ idempotency path — see Failures below."}
18
+
19
+ ## Environment
20
+
21
+ - Dev server: {already running / started fresh, left running or stopped}
22
+ - Test data created: {brief list — removed in cleanup unless noted otherwise}
23
+ - Tools used: {browser automation / curl / psql/Prisma / combination}
24
+
25
+ ## Criteria
26
+
27
+ | # | Criterion | Source | Verdict | Evidence |
28
+ |---|-----------|--------|---------|----------|
29
+ | 1 | {criterion text} | requirements.md | PASS | {screenshot path / curl command+response / query+result} |
30
+ | 2 | {criterion text} | task-01-{name}.md | PASS | ... |
31
+ | 3 | {criterion text} | task-02-{name}.md | FAIL | see Failures below |
32
+
33
+ ## Failures
34
+
35
+ {Omit this section entirely if everything passed.}
36
+
37
+ ### {Criterion text}
38
+
39
+ **Scenario:** {exact input/state that triggers it}
40
+ **Expected:** {what the criterion says should happen}
41
+ **Actual:** {what actually happened}
42
+ **Evidence:** {screenshot, response body, query result}
43
+
44
+ ## Notes
45
+
46
+ {Anything verified as SKIPPED and why (e.g. requires a live third-party webhook), or edge cases
47
+ noticed but not in the original criteria list that are worth flagging back to the spec.}
48
+ ```
49
+
50
+ ## Key Points
51
+
52
+ - The **Criteria** table is the core deliverable — it should let someone who wasn't in the room
53
+ trust that "PASS" actually means what it says, because the evidence column backs it up.
54
+ - Keep evidence concise (a path, a one-line command + result) — this file is a report, not a
55
+ transcript. Full detail belongs in the Failures section, only for things that need it.
56
+ - If a criterion is SKIPPED, say why in the Notes section rather than silently omitting it — a
57
+ missing row is indistinguishable from forgetting to check it.