@pavp/storywright 1.4.0 → 1.6.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.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@pavp/storywright",
3
- "version": "1.4.0",
3
+ "version": "1.6.0",
4
4
  "description": "PM Skills pack for Claude Code — turn ambiguous inputs (prompts, screenshots, Figma links) into Jira-ready user stories.",
5
5
  "keywords": [
6
6
  "claude",
@@ -44,13 +44,16 @@ For each dimension, mark PASS / FAIL and write one sentence of evidence.
44
44
  FAIL if unknowns dominate (spike-shaped) or the surface is too broad.
45
45
 
46
46
  5. **S — Small**
47
- PASS if it fits one sprint and one developer-week is plausible.
48
- FAIL if it visibly mixes ≥2 distinct flows or touches ≥3 unrelated surfaces.
47
+ PASS if it fits one sprint AND has exactly one Gherkin `When`/`Then` pair AND touches ≤2 related surfaces.
48
+ FAIL if it visibly mixes ≥2 distinct flows, OR has >1 `When`/`Then` pair (multi-outcome = scope creep, Cohn anti-pattern), OR touches ≥3 unrelated surfaces.
49
49
 
50
50
  6. **T — Testable**
51
51
  PASS if every AC has an observable outcome.
52
52
  FAIL if ACs hand-wave behavior or rely on subjective judgment.
53
53
 
54
+ 7. **Anti-PRD sanity (storywright-specific)**
55
+ If the rendered story body exceeds ~60 lines excluding user-supplied Preconditions/Out-of-Scope blocks, treat as a spec, not a story. FAIL `Small`. Force `SPLIT RECOMMENDED`.
56
+
54
57
  7. Emit the report block:
55
58
  ```
56
59
  ### INVEST Check
@@ -1,30 +1,75 @@
1
1
  ---
2
2
  name: story-from-figma
3
- description: Generate user stories from a Figma file or frame URL. Uses an MCP Figma server to enumerate frames, components, navigation, and states; falls back to asking for screenshots if MCP is unavailable.
3
+ description: Generate Cohn+Gherkin user stories from a Figma URL. Maps prototype flows to stories (one per user goal, not per frame). Asks ONLY in terminal.
4
4
  trigger: "/story-from-figma | story from figma | generate from figma | analizar figma | https://www.figma.com/"
5
- intent: Multimodal entrypoint skill. Inspects a Figma design, infers user flows and screens, and produces one or more stories via story-generate.
6
- version: 1.0.0
5
+ intent: Multimodal entrypoint. Inspects a Figma design, infers flows and screens, and emits one canonical story per logical user goal. Honors v2.2 hard rules (terminal-only Q, no mini-PRD, mechanical deps for split, V audit per child).
6
+ version: 2.2.0
7
7
  inputs:
8
8
  - figma-link
9
9
  outputs:
10
- - story.jira-wiki.md (per generated story)
11
- - story.standard.md (per generated story)
12
- - clarifications.md
10
+ - story-<N>.standard.md
11
+ - story-<N>.jira-wiki.md
12
+ - flow-summary.md
13
+ - .storywright-context.json
13
14
  composes:
14
15
  - _components/clarification-questions
15
16
  - _components/acceptance-criteria
16
17
  - _components/invest-checklist
17
- - _components/definition-of-done
18
- - _components/business-rules
19
- - _components/edge-cases
20
- - _components/analytics-events
21
- - _components/risks-and-dependencies
22
18
  - _components/jira-wiki-formatter
23
19
  ---
24
20
 
25
21
  ## Purpose
26
22
 
27
- A Figma file usually represents N screens / N flows. This skill maps that visual structure into stories — one story per logical user goal, not one per frame.
23
+ A Figma file usually represents N screens / N flows. This skill maps that visual structure into Cohn+Gherkin stories — **one story per logical user goal, not one per frame**. Splits aggressively if any flow has multiple outcomes.
24
+
25
+ ## Hard rules (v2.2 parity with refine/generate/split)
26
+
27
+ 1. **Terminal-only clarifications.** Never write any sidecar question file (no `clarifications.md`). All gap questions through `AskUserQuestion`, batched ≤4. Non-blocking gaps → `⚠️ Assumed` inline.
28
+
29
+ 2. **Cohn + Gherkin canonical per story.** Each generated story has ONE Use Case + ONE AC scenario (one Given chain + one `When` + one `Then`). If a flow naturally has >1 `When`/`Then` → STOP and hand off to `[[story-split]]`.
30
+
31
+ 3. **No mini-PRDs.** Prohibited in each generated story:
32
+ - NFR blocks — DoD only
33
+ - Edge Cases enumerations as a section — fold into AC failure paths
34
+ - Dependencies as prose — Jira links only
35
+ - Per-claim visual specs — single banner (rule 5)
36
+ - Generation logs >3 lines (>5 if SPLIT recommended)
37
+
38
+ 4. **Output language matches the user's chat language**, not the Figma file's. Auto-detect via rule 4a; ask only if signals split. Persist via rule 9.
39
+
40
+ 5. **Visual inference confidence — single banner only.** Since the source IS Figma, the banner is always `**Source: Figma → values can be tokenized at implementation.**`. If MCP Figma is unavailable and the user falls back to PNG exports, switch the banner to raster (`pixel-derived, not token-confirmed`).
41
+
42
+ 6. **Sibling task IDs.** When the inventory phase produces multiple flows, ticket slugs follow rule F (naming pattern). Do NOT invent slugs without consulting `.storywright-context.json`.
43
+
44
+ 7. **Mockup chrome detection — closed list** (nav rail, top bar, footer, toast slot, modal scrim, app tabs). If a frame shows chrome that's NOT explicitly part of a flow, ask via `AskUserQuestion` whether it's a separate story, shared shell, or out-of-scope.
45
+
46
+ 8. **Anti-PRD is part of each story's INVEST `Small` criterion** — see `[[invest-checklist]]` Small.
47
+
48
+ 9. **Cross-skill context persistence.** Read `<output-folder>/.storywright-context.json` first (exact folder only). Write resolved answers back. Schema same as other v2.2 skills, plus:
49
+ ```json
50
+ {
51
+ "extra": {
52
+ "figma_url": "<url>",
53
+ "figma_scope": "file | page | frame",
54
+ "mcp_available": true | false
55
+ }
56
+ }
57
+ ```
58
+
59
+ 10. **Mechanical NxN dep matrix when emitting multiple stories (rule A).** If N>1 flows produce N stories, parse each story's `Given` lines for surface nouns owned by sibling flows. Mark `DEP(Sj → Si)` per match. Render the matrix in `flow-summary.md`. No intuition.
60
+
61
+ 11. **Per-story V audit (rule C).** For each candidate story, one-line test: "If only this story ships and no sibling flow exists, does a real user complete a real task?". If no → `WEAK · merge-upstream-candidate`. Recommend merging in `flow-summary.md`.
62
+
63
+ 12. **Passive-goal downstream prompt (rule G).** If a story's `I want to` verb is observational AND `so that` lacks downstream action → ask once via `AskUserQuestion`.
64
+
65
+ ### 4a. Language auto-detect — expanded signals (E)
66
+ Same weighted table as refine/generate/split (Gherkin keywords, persona phrasing, column names, domain verbs, title). Plus Figma-specific signal: **frame names** and **layer text** in M = medium weight.
67
+
68
+ ### Rule F. Naming pattern — ask once, persist
69
+ Same options. Persist in `naming_pattern` inside `.storywright-context.json`. Used for all story slugs in this run.
70
+
71
+ ### Rule D. Surface vs styling
72
+ Same deterministic rule. A frame counts as a separate flow ONLY if it has its own user goal (verb where the user *does something*). A purely visual variant (color theme, light/dark) is NOT a new flow.
28
73
 
29
74
  ## When to use
30
75
 
@@ -40,86 +85,160 @@ A Figma file usually represents N screens / N flows. This skill maps that visual
40
85
 
41
86
  ## Application (step-by-step)
42
87
 
43
- ### Phase 0 — MCP availability check
44
-
45
- 1. Verify an MCP Figma server is connected to Claude Code. See `mcp-figma-notes.md` in this skill folder for setup options.
46
- 2. If MCP is unavailable:
47
- - Ask the user to either (a) install an MCP Figma server, (b) export the relevant frames as PNGs and drop them in chat, or (c) paste a textual description of the flows.
48
- - Continue under the chosen fallback. The rest of the skill works with screenshots via Claude vision.
88
+ ### Phase 0 — MCP availability + context load
49
89
 
50
- ### Phase 0.5 Detect companion inputs
90
+ 1. Verify MCP Figma server is connected. See `mcp-figma-notes.md`.
91
+ 2. **Read prior context.** If `<output-folder>/.storywright-context.json` exists (exact folder only), load it.
92
+ 3. If MCP unavailable:
93
+ - Ask via `AskUserQuestion`: install MCP / export PNGs / paste textual flow descriptions.
94
+ - If user falls back to PNG, set `design_source = raster` in context file and use the raster banner per rule 5.
51
95
 
52
- Before extracting from Figma, check whether the user attached:
53
- - **Accompanying text** (goal, story draft, constraints) — treat as canonical for `User Story / Scope / Business Goal`. Figma is canonical for `Components / States / Flows`.
54
- - **Reference screenshots** — usually redundant when Figma is available; use only if Figma frames are missing states the screenshots show.
96
+ ### Phase 0.5 Companion inputs + language
55
97
 
56
- If text + Figma both describe the same flow but disagree (e.g., text says "single page form", Figma shows multi-step wizard), **surface the conflict** in clarifications and ask before drafting. Do NOT silently pick a winner. See `[[story-generate]]` "Mixed inputs" section for source priority.
98
+ 1. Detect companion text or PNGs.
99
+ 2. Run language auto-detect (rule 4a). Adopt silently if signals agree; ask if split.
100
+ 3. Persona sharpening: if persona ambiguous, ask via `AskUserQuestion`.
57
101
 
58
- ### Phase 1 — Inventory
102
+ ### Phase 1 — Inventory (MCP)
59
103
 
60
104
  1. List pages in the file (if MCP allows).
61
105
  2. For the target page, list frames with:
62
106
  - Frame name
63
107
  - Frame type (entry, modal, error state, empty state, success state, loading, etc.)
64
- - Outgoing prototype links (which other frame each interactive element points to)
65
- 3. Identify the **flows** by grouping frames connected by prototype links. One flow = one candidate story (or epic if large).
108
+ - Outgoing prototype links
109
+ 3. Identify **flows** by grouping frames connected by prototype links. One flow = one candidate story (or epic if large).
110
+ 4. Apply rule D: visual variants of the same flow do NOT count as new flows.
66
111
 
67
112
  ### Phase 2 — Per-flow inference
68
113
 
69
114
  For each flow:
70
115
 
71
- 1. Identify the **goal** (what user outcome does this flow achieve?).
72
- 2. Identify the **entry point** (where does the user start?).
73
- 3. Enumerate **states**: empty, loading, success, error, edge.
74
- 4. Identify **components** (forms, lists, modals) and their **inputs/outputs**.
75
- 5. Score confidence per inference: HIGH (visible in design), MEDIUM (implied), LOW (assumed). Anything below HIGH gets `> ⚠️ Assumed:` in the output.
76
- 6. Pass the structured inference to `[[story-generate]]` to produce the full story.
116
+ 1. Identify the **goal** (what user outcome).
117
+ 2. Identify the **entry point**.
118
+ 3. Enumerate **states**: empty / loading / success / error / edge. Fold into AC failure paths (rule 3); do NOT emit an Edge Cases section.
119
+ 4. Identify **components** and their **inputs/outputs**.
120
+ 5. Score confidence per inference: HIGH / MEDIUM / LOW. Below HIGH `⚠️ Assumed` inline.
121
+ 6. Run passive-goal check (rule G).
122
+ 7. Run pre-split deterministic counter (rule D) on the flow. If count ≥2 → recommend `[[story-split]]` for THAT flow before drafting.
123
+
124
+ ### Phase 3 — Draft canonical block per flow
125
+
126
+ ```markdown
127
+ ### [Flow Title]
128
+
129
+ #### Use Case
130
+ - **As a** [persona]
131
+ - **I want to** [action]
132
+ - **so that** [outcome with downstream action — rule G]
77
133
 
78
- ### Phase 3 — Splitting check
134
+ #### Acceptance Criteria
135
+ - **Scenario:** [single-outcome scenario name]
136
+ - **Given:** [context — surface nouns drive flow-summary dep matrix]
137
+ - **When:** [single trigger]
138
+ - **Then:** [single observable outcome]
79
139
 
80
- If a single flow has too many states or branches, run `[[invest-checklist]]` first. If it returns `SPLIT RECOMMENDED`, hand off to `[[story-split]]` before generating.
140
+ #### Design Reference
141
+ **Source: Figma → values can be tokenized at implementation.**
142
+ - <frame URL or frame names>
81
143
 
82
- ### Phase 4 — Output
144
+ #### INVEST
145
+ - I/N/V/E/S/T — one line each.
146
+ - **Verdict:** READY | SPLIT RECOMMENDED | NEEDS REFINEMENT | NOT A STORY
147
+
148
+ #### Generation log (≤3 lines)
149
+ - Mapped from frames: <FRAME-IDs>; pattern: <if any>.
150
+ ```
151
+
152
+ ### Phase 4 — Multi-flow analysis (if N>1)
153
+
154
+ 1. **Mechanical NxN dep matrix (rule 10).** Parse each story's Given lines for surface nouns owned by sibling flows. Emit in `flow-summary.md`.
155
+
156
+ 2. **Per-story V audit (rule 11).** Flag merge-upstream candidates loudly.
157
+
158
+ 3. **Coherence check** — verify the union of stories covers the user journey shown in Figma. Flag gaps.
159
+
160
+ ### Phase 5 — Output
83
161
 
84
162
  For each story:
85
- - Emit `story.jira-wiki.md` + `story.standard.md` per the formatter.
86
- - Emit a single `flow-summary.md` listing all stories produced and the frames they map to, so reviewers can audit traceability.
163
+ - `story-<N>.standard.md` + `story-<N>.jira-wiki.md`.
164
+
165
+ Plus single `flow-summary.md`:
166
+ ```markdown
167
+ ### Flow Summary — <Figma file/page>
168
+
169
+ | # | Story | Frames | INVEST verdict | V audit |
170
+ |---|---|---|---|---|
171
+ | 1 | login-google-web | AUTH-001, AUTH-002 | READY | PASS |
172
+ | 2 | login-google-mobile | AUTH-101 | READY (after #1) | PASS |
173
+ | 3 | recovery-flow | AUTH-201..AUTH-212 | SPLIT RECOMMENDED | — |
174
+
175
+ **Dependency matrix (rule 10):**
176
+
177
+ | | #1 | #2 | #3 |
178
+ |-----|----|----|----|
179
+ | #1 | — | | |
180
+ | #2 |DEP | — | |
181
+ | #3 | | | — |
87
182
 
88
- If any inference is LOW confidence, add to `clarifications.md`.
183
+ **Build order:** #1 #2 (parallel: #3 after its own split).
184
+
185
+ **Design source:** Figma (or raster, if PNG fallback).
186
+ ```
187
+
188
+ Plus `.storywright-context.json` updated.
189
+
190
+ NO `clarifications.md`. NO Edge Cases sections. NO NFR blocks. NO per-claim visual tags.
89
191
 
90
192
  ## Examples
91
193
 
92
194
  ### Good
93
-
94
195
  Input: Figma file URL with 3 flows on the "Auth" page (login, signup, password reset).
95
-
96
196
  Output:
97
- - 3 stories (one per flow).
98
- - Each story references the frames it derived from: `Maps to frames: AUTH-001, AUTH-002, AUTH-003`.
99
- - Account-recovery flow flagged for `[[story-split]]` because it had 12 frames covering multiple recovery methods.
197
+ - 3 canonical stories.
198
+ - `flow-summary.md` with mechanical matrix (#2 DEP #1; #3 independent).
199
+ - V audit: all PASS.
200
+ - Recovery flow has 12 frames → pre-split counter ≥2 → recommend `[[story-split]]` for #3 only.
201
+
202
+ ### Good — PNG fallback
203
+ MCP unavailable. User exports 3 PNGs. Skill switches banner to raster, marks `design_source = raster`, generates 3 stories with `[mockup-pixel-derived]`-style inheritance (single banner per Design Reference).
204
+
205
+ ### Good — passive goal fires
206
+ Flow goal inferred as "view dashboard". Skill detects passive verb → asks: "What does the user do with the dashboard data?". User: "Spot anomalies and drill into them." So-that strengthened.
100
207
 
101
208
  ### Bad
209
+ One story per frame. Frames are screens; stories are user goals.
102
210
 
103
- One story per frame. Frames are screens; stories are user goals. A single goal may span 5 frames.
211
+ ### Bad
212
+ Emitting `clarifications.md`. Violates rule 1.
213
+
214
+ ### Bad
215
+ Skipping the mechanical matrix in `flow-summary.md` when N>1.
104
216
 
105
217
  ## Common Pitfalls
106
218
 
107
219
  - Treating each frame as a story.
108
- - Skipping prototype-link analysis — without flow structure, inferred user goals are guesses.
109
- - Ignoring empty/error/loading states. Designers usually include them; PMs often miss them.
110
- - Trusting MEDIUM/LOW inferences silently. Always surface them.
111
- - Generating stories without verifying that the design covers all error paths (often the design only shows the happy path).
220
+ - Skipping prototype-link analysis — without flow structure, user goals are guesses.
221
+ - Ignoring empty/error/loading states. Designers usually include them; fold into AC failure paths.
222
+ - Trusting MEDIUM/LOW inferences silently mark `⚠️ Assumed`.
223
+ - Generating stories without verifying coverage of all error paths.
224
+ - Skipping per-story V audit (rule 11) — figma flows are easy to over-split.
225
+ - Re-asking questions already in `.storywright-context.json`.
226
+ - Tagging every visual claim instead of using the single Figma banner.
112
227
 
113
228
  ## References
114
229
 
115
230
  - [[story-generate]]
116
231
  - [[story-split]]
232
+ - [[story-refine]]
117
233
  - [[clarification-questions]]
118
- - `./mcp-figma-notes.md` (setup of MCP server)
234
+ - `./mcp-figma-notes.md` (MCP server setup)
119
235
 
120
236
  <claude-specific>
121
- - Use Claude's native vision when MCP is unavailable and the user drops PNGs.
237
+ - Use Claude vision when MCP is unavailable and the user drops PNGs.
122
238
  - Use extended thinking for flow grouping — prototype links can be ambiguous.
123
239
  - Cache the Phase 2 inference checklist across calls.
124
- - When MCP Figma is available, batch frame metadata fetches into one round trip to minimize tool round-trips.
240
+ - When MCP Figma is available, batch frame metadata fetches into one round trip.
241
+ - Read `.storywright-context.json` ONLY from the exact target output folder.
242
+ - Build the multi-story dependency matrix from Given-text parsing (rule 10), not intuition.
243
+ - Never call Write for any sidecar question file. Use `AskUserQuestion`.
125
244
  </claude-specific>