@pavp/storywright 1.6.0 → 1.6.1

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.6.0",
3
+ "version": "1.6.1",
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",
@@ -0,0 +1,279 @@
1
+ ---
2
+ name: storywright-base
3
+ description: Shared base behavior for all storywright top-level skills. Hard rules, canonical output, terminal-only Q, context schema, mechanical deps, V audit, language detect.
4
+ trigger: "internal use by story-* skills"
5
+ intent: Component skill that holds the v2.2 baseline. Top-level skills (story-generate, story-refine, story-split, story-from-figma) compose this and add only their source-specific behavior on top.
6
+ version: 2.2.0
7
+ inputs:
8
+ - none
9
+ outputs:
10
+ - none
11
+ ---
12
+
13
+ ## Purpose
14
+
15
+ Every top-level storywright skill must behave identically except for three things:
16
+
17
+ 1. **Source** — what the input is (raw prompt / existing story / oversize story / Figma URL).
18
+ 2. **Prompt** — what the user is asking for.
19
+ 3. **Split behavior** — whether the skill produces 1 story, recommends a split, or produces N stories directly.
20
+
21
+ Everything else (how to ask questions, what shape the output takes, how to detect language, how to count outcomes, how to flag dependencies, how to persist context) lives here.
22
+
23
+ If you are reading this through a top-level skill, treat every rule below as non-negotiable for that skill too.
24
+
25
+ ## Hard rules (v2.2 — apply to all top-level storywright skills)
26
+
27
+ 1. **Terminal-only clarifications.** Never write any sidecar question file (no `clarifications.md`, no `questions.md`, nothing). All gap questions go through `AskUserQuestion`, batched ≤4 per call. Non-blocking gaps → mark `⚠️ Assumed: <text>` inline in the story body — do not ask.
28
+
29
+ 2. **Cohn + Gherkin canonical.** Every story (or child story) has:
30
+ - ONE Use Case block (`As a / I want to / so that`).
31
+ - ONE AC Scenario (one Given chain + one `When` + one `Then`).
32
+ If the input naturally needs >1 `When`/`Then`, the skill MUST stop the single-story path and route to `[[story-split]]`.
33
+
34
+ 3. **No mini-PRDs.** PROHIBITED sections in any story output:
35
+ - Non-Functional Requirements blocks (a11y/i18n/perf/tokens) — DoD only.
36
+ - Edge Cases enumerated as their own section — fold into AC failure paths.
37
+ - Dependencies as prose — Jira ticket links only.
38
+ - Per-claim visual specs (pixel measurements, hex inferences) inline — use single banner (rule 5).
39
+ - Logs >3 lines (>5 if SPLIT verdict).
40
+
41
+ 4. **Output language matches the user's chat language**, not the input's. Auto-detect first via rule 4a; only ask via `AskUserQuestion` if signals split.
42
+
43
+ 5. **Visual inference confidence — single banner only.** Do NOT tag every visual claim. ONE banner at the top of the Design Reference block declares source type; all claims under it inherit:
44
+ - Raster source (PNG/JPG) → `**Source: raster mockup → all visual specs are pixel-derived, not token-confirmed.**`
45
+ - Figma source → `**Source: Figma → values can be tokenized at implementation.**`
46
+ - Design-token source → `**Source: design tokens → values are authoritative.**`
47
+ Never assert hex / px / spacing from raster without the raster banner.
48
+
49
+ 6. **Sibling task IDs.** If the story references "next task / future task / another story / siblings" — check `<output-folder>/.storywright-context.json` first. If unresolved, ask via `AskUserQuestion`. If user has none yet, leave `TODO: link sibling` (unless rule F applies — invent slug per persisted naming pattern).
50
+
51
+ 7. **Mockup chrome detection — closed list.** Chrome = exactly:
52
+ - left nav rail / sidebar
53
+ - top bar (user menu, global breadcrumbs, global search)
54
+ - footer
55
+ - persistent toast/snackbar slot
56
+ - persistent modal scrim
57
+ - app-level tabs
58
+
59
+ If a companion image shows any of these AND the input does not mention them, ask via `AskUserQuestion` whether each is `in-scope`, `sibling-scope`, or `out-of-scope`. Anything not on this list (cards, section headers, in-flow buttons) is NOT chrome — do not surface as a chrome question.
60
+
61
+ 8. **Anti-PRD is part of INVEST `Small`, not a separate step.** See `[[invest-checklist]]` Small criterion — line-count ceiling (~60 lines) lives there. Single source of truth.
62
+
63
+ 9. **Cross-skill context persistence.** When any storywright skill resolves a clarification via `AskUserQuestion`, write the **answer** to `<output-folder>/.storywright-context.json`. Read only from the exact output folder of the current invocation; never search siblings or parents. Schema:
64
+
65
+ ```json
66
+ {
67
+ "version": 1,
68
+ "decided_at": "<ISO date>",
69
+ "decided_by_skill": "story-generate | story-refine | story-split | story-from-figma",
70
+ "language": "EN | ES | ...",
71
+ "chrome_scope": "in-scope | in-scope-placeholder | sibling | out-of-scope",
72
+ "siblings": "TODO | <list of IDs> | not-applicable",
73
+ "design_source": "raster | figma | tokens",
74
+ "naming_pattern": "kebab-feature-action | verb-noun | domain-action | jira-prefix",
75
+ "extra": {}
76
+ }
77
+ ```
78
+
79
+ Every skill MUST read this file BEFORE asking any question. Every skill MUST write this file when it resolves a question.
80
+
81
+ 10. **Children independence — mechanical detection (rule A).** When any skill produces multiple stories or children (story-split, story-from-figma multi-flow, story-refine recommending split):
82
+ - For each child Cj, parse its `Given:` and `and Given:` lines.
83
+ - If any Given text contains a surface noun owned by child Ci (Ci's title/scope owns "grid" and Cj's Given mentions "the grid") → mark `DEP(Cj → Ci)`.
84
+ - The dependency map IS the union of those text matches. **Do not add deps "you sense" without a Given citation.**
85
+ - Affected child's INVEST `Independent` becomes `PARTIAL · depends on <Ci>`.
86
+ - Parent epic / flow-summary file lists explicit build order (topological sort of the matrix).
87
+ - If a dep is real but no Given mentions it, rewrite the child's Given to make it explicit, then re-run the match. Intuition-based deps are forbidden.
88
+
89
+ 11. **Per-child V audit (rule C).** After any split-style output, for each candidate child run a one-line test:
90
+ "If only this child ships and no sibling exists, does a real user complete a real task?"
91
+ - If yes → V = PASS.
92
+ - If no, useless until `<other>` ships → V = `WEAK · merge-upstream-candidate`. Recommend merging into the parent surface instead of keeping standalone.
93
+ Do not let stylistic/UI-fragment children survive a split.
94
+
95
+ 12. **Passive-goal downstream prompt (rule G).** If the story's `I want to` verb is observational (`view, see, read, browse, look at, inspect, monitor`) AND the `so that` does not name a follow-up user action — ask once via `AskUserQuestion`: "What does the user do with this?". Strengthen the `so that` accordingly. Skip if `so that` already names a downstream action.
96
+
97
+ ### 4a. Language auto-detect — expanded signals (rule E)
98
+
99
+ Run cheap detection before asking. Multi-signal weighted decision:
100
+
101
+ | Signal | Where to look | Weight |
102
+ |---|---|---|
103
+ | Gherkin keywords in M ("Given/When/Then") | AC block | high |
104
+ | Persona phrasing in M ("As a user" vs "Como un usuario") | Use Case | high |
105
+ | Column / field names in M ("Phone - primary", "Teléfono - principal") | AC bullets | medium |
106
+ | Domain verbs in M ("clicking" vs "hacer clic") | AC bullets | medium |
107
+ | Figma frame names / layer text in M (when source = figma) | design source | medium |
108
+ | Title language | header | low |
109
+
110
+ **Decision:**
111
+ - All high+medium signals agree on language M → adopt M silently. Mark inline `⚠️ Assumed: output language = <M> (auto-detected from <signals>)`.
112
+ - Signals split → ask once via `AskUserQuestion`.
113
+ - User chat = L, story body = M, but high signals tie → prefer M (story body is contract).
114
+
115
+ Persist via rule 9.
116
+
117
+ ### Rule D. Surface vs styling (deterministic)
118
+
119
+ A "named UI surface" counts as a separate outcome (+1 in the pre-split counter) ONLY if it has its own user goal — a verb in the input where the user *does something with that surface* (clicks it, navigates with it, reads it, configures it).
120
+
121
+ If a noun is mentioned only in a styling context (color, padding, alignment, background) or as a sub-component of a parent surface (column inside a grid, label inside a button) → it is NOT a surface. It is styling. Count = 0.
122
+
123
+ Examples:
124
+ - "header row visually distinct (purple)" → styling of grid → 0
125
+ - "pagination control with page numbers" → surface with user goal (navigating) → +1
126
+ - "5 columns: Code, Name, Phone, ..." → sub-components of grid → 0 (grid still counts once)
127
+ - "results counter next to search button" → surface with user goal (reading count) → +1
128
+
129
+ ### Rule F. Naming pattern — ask once, persist
130
+
131
+ When any skill needs to invent a tentative ticket slug AND `.storywright-context.json` has no `naming_pattern` field, ask once via `AskUserQuestion`:
132
+
133
+ ```
134
+ Which naming pattern do you use for tickets?
135
+ - kebab-case feature-action → "customer-search-bar-wire"
136
+ - verb-noun → "wire-search-bar"
137
+ - domain-action → "search.customer.wire-input"
138
+ - Jira prefix + numeric → "CSB-001"
139
+ ```
140
+
141
+ Persist in `naming_pattern`. Use for all sibling slugs in this run AND future skills reading the same context file.
142
+
143
+ ### Deterministic pre-split test (used by all skills)
144
+
145
+ Mechanical counter. Apply the table — do NOT eyeball:
146
+
147
+ | Signal | Hit value |
148
+ |---|---|
149
+ | AC bullet starting with action verb at user level ("clicking", "submitting", "entering", "navigating") | +1 each |
150
+ | Distinct `When [event]` phrasing already implied in the story | +1 each |
151
+ | Distinct named UI surface mentioned at the AC level (rule D applies) | +1 each |
152
+
153
+ **Do NOT count:**
154
+ - sub-bullets describing the same flow
155
+ - styling of an existing surface
156
+ - preconditions or passive "rendered" statements
157
+
158
+ **Decision:**
159
+ - Count ≤1 → proceed with single-story path.
160
+ - Count ≥2 → STOP single-story path. Route to split behavior per the host skill (recommend `/story-split`, produce epic+children, or recurse).
161
+
162
+ ## Canonical output shape (this is the WHOLE story — no exceptions)
163
+
164
+ ```markdown
165
+ ### [Title]
166
+
167
+ #### Use Case
168
+ - **As a** [persona — never just "user"]
169
+ - **I want to** [action]
170
+ - **so that** [outcome with downstream action — rule G]
171
+
172
+ #### Preconditions (optional, only if user provided)
173
+ - ...
174
+
175
+ #### Out of Scope (optional, only if user provided)
176
+ - ...
177
+
178
+ #### Acceptance Criteria
179
+ - **Scenario:** [single-outcome scenario name]
180
+ - **Given:** [context — surface nouns here drive dep matrix per rule 10]
181
+ - **and Given:** [context]
182
+ - **When:** [single trigger]
183
+ - **Then:** [single observable outcome]
184
+
185
+ #### Design Reference (optional)
186
+ **Source: <raster | figma | tokens> → <banner from rule 5>**
187
+ - [link or path]
188
+ - visual notes: [...]
189
+
190
+ #### INVEST
191
+ - I — <PASS | PARTIAL · depends on <Ci>>
192
+ - N/V/E/S/T — one line each, evidence-based.
193
+ - **Verdict:** READY | READY (after <Ci> builds) | SPLIT RECOMMENDED | NEEDS REFINEMENT | NOT A STORY | WEAK·merge-upstream-candidate
194
+
195
+ #### <Generation | Refinement | Split> log (≤3 lines; ≤5 if SPLIT verdict)
196
+ - ...
197
+ ```
198
+
199
+ NOTHING else. No NFR block. No Edge Cases enumeration. No Dependencies prose. No Assumptions block (assumptions get `⚠️ Assumed` inline or are resolved via `AskUserQuestion`).
200
+
201
+ ## Application (step-by-step — every skill follows this skeleton)
202
+
203
+ 0. **Detect companion sources** (image, figma-link, accompanying text). Run conflict detection against the primary input. Run chrome detection using rule 7. Surface conflicts as BLOCKING `AskUserQuestion`.
204
+
205
+ 1. **Read prior context.** Load `<output-folder>/.storywright-context.json` if present (exact folder only). Apply resolved answers; skip the corresponding questions.
206
+
207
+ 2. **Language resolution** via rule 4 + 4a. Auto-detect using the expanded signal table; ask only if signals split. Persist via rule 9.
208
+
209
+ 3. **Persona sharpening.** If persona is "user" / "customer" / "person", ask via `AskUserQuestion` for a specific role. Generic personas hide motivation.
210
+
211
+ 4. **Passive-goal check (rule G).** If `I want to` is observational AND `so that` lacks downstream action → ask once.
212
+
213
+ 5. **Gap-check.** For each weak/missing section:
214
+ - **Blocking** (changes scope, AC outcome, or persona) → `AskUserQuestion` immediately (batched ≤4).
215
+ - **Non-blocking** (additive detail) → fill inline marked `⚠️ Assumed: <text>`. Do not ask.
216
+
217
+ 6. **Sibling reference check.** If unlinked references found → ask once. If user opts for tentative slugs, apply rule F. Persist via rule 9.
218
+
219
+ 7. **Deterministic pre-split test.** Apply the table above mechanically.
220
+ - Count ≤1 → continue to step 8 (single-story path).
221
+ - Count ≥2 → execute the **host skill's split behavior** (see Source-specific differential in each top-level skill).
222
+
223
+ 8. **Fill the canonical block** (Use Case + AC + Design Ref + INVEST). Preserve original wording where it was already good. NEVER invent NFR/edge-case/deps sections.
224
+
225
+ 9. **Run INVEST** via `[[invest-checklist]]`.
226
+ - `READY` → render.
227
+ - `SPLIT RECOMMENDED` → host-skill split behavior + rule 10 matrix + rule 11 V audit.
228
+ - `NEEDS REFINEMENT` → iterate failing dimension, max 1 cycle, then STOP.
229
+ - `NOT A STORY` → tell user it's a tech task and stop.
230
+
231
+ 10. **Render** via `[[jira-wiki-formatter]]`. Files: `story.standard.md` + `story.jira-wiki.md`. Plus `.storywright-context.json`. No other files.
232
+
233
+ 11. **Log** ≤3 bullets (≤5 if SPLIT) appended at story end. Log type label is host-specific (Generation / Refinement / Split).
234
+
235
+ ## What each top-level skill adds on top of this base
236
+
237
+ Only these three things vary:
238
+
239
+ | Skill | Source | Split behavior |
240
+ |---|---|---|
241
+ | `story-generate` | Raw prompt / ambiguous text + optional image/Figma | If pre-split count ≥2 → STOP, recommend `/story-split`. Otherwise draft 1 story. |
242
+ | `story-refine` | Existing story text + optional image/Figma | If pre-split count ≥2 → STOP, recommend `/story-split`. Otherwise fix in place. |
243
+ | `story-split` | Oversize story (any source) | Always produces epic + N children. Mechanical NxN matrix + per-child V audit MANDATORY. Recursive re-split per child if count ≥2. |
244
+ | `story-from-figma` | Figma file/page/frame URL (+ optional companion text) | One story per logical user-goal flow. Multi-flow output → mandatory `flow-summary.md` with mechanical matrix + V audit. Any flow with count ≥2 → hand off to `[[story-split]]`. |
245
+
246
+ Everything else is identical and lives in this base.
247
+
248
+ ## Common Pitfalls (all skills)
249
+
250
+ - Writing any sidecar question file (clarifications.md, questions.md, etc).
251
+ - Skipping rule 1 (terminal-only) "because the user is async".
252
+ - Eyeballing outcome counts instead of running the mechanical table.
253
+ - Renumbering ACs the team may already reference externally.
254
+ - Adding NFR/edge-cases sections "to be thorough".
255
+ - Tagging every visual claim instead of using the single Design Reference banner.
256
+ - Claiming children Independent without running the rule 10 matrix.
257
+ - Letting stylistic/UI-fragment children survive (rule 11 should have flagged them).
258
+ - Asking for a downstream action and then not strengthening the `so that`.
259
+ - Re-asking questions already answered in `.storywright-context.json`.
260
+ - Reading `.storywright-context.json` from a sibling or parent folder.
261
+
262
+ ## References
263
+
264
+ - [[invest-checklist]]
265
+ - [[acceptance-criteria]]
266
+ - [[clarification-questions]]
267
+ - [[jira-wiki-formatter]]
268
+ - [[story-generate]]
269
+ - [[story-refine]]
270
+ - [[story-split]]
271
+ - [[story-from-figma]]
272
+
273
+ <claude-specific>
274
+ - Treat every rule above as load-bearing across all top-level skills.
275
+ - Use extended thinking when applying rule 10 (parse Given lines) and rule 11 (V audit per child).
276
+ - Never call Write for any sidecar question file. Use `AskUserQuestion`.
277
+ - Read `.storywright-context.json` ONLY from the exact target output folder.
278
+ - When you find yourself about to add an NFR / edge-cases / dependencies prose section to a story body, STOP — rule 3 forbids it.
279
+ </claude-specific>
@@ -1,17 +1,18 @@
1
1
  ---
2
2
  name: story-from-figma
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.
3
+ description: Generate Cohn+Gherkin user stories from a Figma URL. One story per user-goal flow, not per frame. Inherits all hard rules from storywright-base.
4
4
  trigger: "/story-from-figma | story from figma | generate from figma | analizar figma | https://www.figma.com/"
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
5
+ intent: Multimodal entrypoint. Behavior 100% identical to siblings except for source (Figma URL via MCP, with PNG fallback) and split-behavior (one canonical story per logical user-goal flow; flows with count ≥2 routed to /story-split).
6
+ version: 2.3.0
7
7
  inputs:
8
8
  - figma-link
9
9
  outputs:
10
- - story-<N>.standard.md
11
- - story-<N>.jira-wiki.md
10
+ - story-1.standard.md
11
+ - story-1.jira-wiki.md
12
12
  - flow-summary.md
13
13
  - .storywright-context.json
14
14
  composes:
15
+ - _components/storywright-base
15
16
  - _components/clarification-questions
16
17
  - _components/acceptance-criteria
17
18
  - _components/invest-checklist
@@ -20,172 +21,77 @@ composes:
20
21
 
21
22
  ## Purpose
22
23
 
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
+ 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**.
24
25
 
25
- ## Hard rules (v2.2 parity with refine/generate/split)
26
+ **All hard rules, canonical output shape, language detection, terminal-only Q, mechanical NxN dep matrix, per-child V audit, context persistence, and INVEST handling live in `[[storywright-base]]`. Read that first. Anything in this file is a SOURCE-SPECIFIC or SPLIT-BEHAVIOR delta only.**
26
27
 
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
+ ## Source-specific differential
28
29
 
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
+ - **Source:** a Figma file/page/frame URL, accessed via MCP Figma server. Falls back to PNG screenshots if MCP is unavailable.
31
+ - **What changes vs base:**
32
+ - **Design Reference banner is always Figma** (`**Source: Figma → values can be tokenized at implementation.**`) when MCP is used. Switches to the raster banner if user falls back to PNGs.
33
+ - **Persona / Goal inferred from prototype flow + frame text** (rule 4a base signal table includes Figma frame names and layer text as medium-weight signals).
34
+ - **One story per logical user-goal flow**, not per frame. Group frames by prototype-link connectivity to identify flows.
35
+ - **Companion text overrides Figma** for `User Story / Scope / Business Goal` if both are present. Figma is canonical for `Components / States / Flow structure`.
30
36
 
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
+ ## Split behavior differential
37
38
 
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
+ This skill may produce **multiple stories in one invocation** (one per flow). When N>1:
40
+ - **MANDATORY: emit `flow-summary.md`** with:
41
+ - Per-story INVEST verdict
42
+ - Mechanical NxN dep matrix (base rule 10) parsed from each story's Given lines
43
+ - Per-story V audit (base rule 11) with merge-upstream flags
44
+ - Topological build order
45
+ - For any single flow whose deterministic pre-split count ≥2 → STOP that flow's draft, route to `[[story-split]]`. Mark the flow as SPLIT RECOMMENDED in `flow-summary.md`. Continue with the other flows.
39
46
 
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.
73
-
74
- ## When to use
75
-
76
- - User pastes a Figma link.
77
- - User says "generate stories from this design".
78
-
79
- ## Inputs & interpretation
80
-
81
- - **figma-link** — file URL, page URL, or specific frame URL. Detect the scope:
82
- - File URL → consider the whole file; ask which page or flow to focus on
83
- - Page URL → enumerate frames in that page
84
- - Frame URL → single-screen analysis (usually one story)
47
+ If N=1 (single frame URL)standard single-story output. No `flow-summary.md`.
85
48
 
86
49
  ## Application (step-by-step)
87
50
 
51
+ Follow the **base Application** skeleton for the front-end behaviors (context load, language with Figma signal weighting, persona, passive-goal, gap-check, siblings). Figma-specific steps:
52
+
88
53
  ### Phase 0 — MCP availability + context load
89
54
 
90
55
  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.
95
-
96
- ### Phase 0.5 — Companion inputs + language
97
-
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`.
56
+ 2. Read prior context per base rule 9.
57
+ 3. If MCP unavailable, ask via `AskUserQuestion` for fallback: (a) install MCP, (b) export PNGs, (c) paste textual flow descriptions. If user picks PNG, set `design_source = raster` in context and use the raster banner.
101
58
 
102
59
  ### Phase 1 — Inventory (MCP)
103
60
 
104
61
  1. List pages in the file (if MCP allows).
105
- 2. For the target page, list frames with:
106
- - Frame name
107
- - Frame type (entry, modal, error state, empty state, success state, loading, etc.)
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.
62
+ 2. For the target page, list frames with: frame name, frame type (entry/modal/error/empty/success/loading), outgoing prototype links.
63
+ 3. Identify **flows** by grouping frames connected by prototype links. One flow = one candidate story (or epic if pre-split count ≥2).
64
+ 4. Apply base rule D: visual variants of the same flow do NOT count as new flows.
111
65
 
112
66
  ### Phase 2 — Per-flow inference
113
67
 
114
68
  For each flow:
69
+ 1. Identify the user goal, entry point, states (empty/loading/success/error/edge).
70
+ 2. Score confidence per inference (HIGH/MEDIUM/LOW). Below HIGH → `⚠️ Assumed` inline.
71
+ 3. Run base rule G (passive-goal check) on the inferred goal.
72
+ 4. Run base deterministic pre-split counter on the flow.
73
+ - Count ≤1 → draft the base canonical block for this flow.
74
+ - Count ≥2 → mark flow as SPLIT RECOMMENDED; skip drafting.
115
75
 
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]
133
-
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]
139
-
140
- #### Design Reference
141
- **Source: Figma → values can be tokenized at implementation.**
142
- - <frame URL or frame names>
143
-
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
- ```
76
+ ### Phase 3 Draft canonical block per flow (count ≤1 flows only)
151
77
 
152
- ### Phase 4 Multi-flow analysis (if N>1)
78
+ Use the base canonical output shape. Design Reference banner per source-specific differential above.
153
79
 
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`.
80
+ ### Phase 4 Multi-flow analysis (N>1)
155
81
 
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.
82
+ 1. **Mechanical NxN matrix (base rule 10).** Parse each story's Given lines.
83
+ 2. **Per-story V audit (base rule 11).** Flag merge-upstream candidates.
84
+ 3. **Coherence check.** Union of stories covers the journey shown in Figma.
159
85
 
160
86
  ### Phase 5 — Output
161
87
 
162
- For each story:
88
+ Per drafted flow:
163
89
  - `story-<N>.standard.md` + `story-<N>.jira-wiki.md`.
164
90
 
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 | | | — |
91
+ If N>1 OR any flow was routed to split:
92
+ - `flow-summary.md` with the matrix, V audit, build order, and SPLIT-RECOMMENDED markers.
182
93
 
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.
94
+ Plus `.storywright-context.json` updated (`extra.figma_url`, `extra.figma_scope`, `extra.mcp_available`).
189
95
 
190
96
  NO `clarifications.md`. NO Edge Cases sections. NO NFR blocks. NO per-claim visual tags.
191
97
 
@@ -194,51 +100,47 @@ NO `clarifications.md`. NO Edge Cases sections. NO NFR blocks. NO per-claim visu
194
100
  ### Good
195
101
  Input: Figma file URL with 3 flows on the "Auth" page (login, signup, password reset).
196
102
  Output:
197
- - 3 canonical stories.
103
+ - 3 canonical stories (one per flow).
198
104
  - `flow-summary.md` with mechanical matrix (#2 DEP #1; #3 independent).
199
105
  - V audit: all PASS.
200
- - Recovery flow has 12 frames → pre-split counter ≥2 → recommend `[[story-split]]` for #3 only.
106
+ - Recovery flow has 12 frames → pre-split counter ≥2 → marked SPLIT RECOMMENDED; not drafted.
201
107
 
202
108
  ### 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).
109
+ MCP unavailable. User exports 3 PNGs. Skill switches banner to raster, marks `design_source = raster`, generates 3 stories with single raster banner each.
204
110
 
205
111
  ### 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.
112
+ Flow goal inferred as "view dashboard". Base rule G fires. Ask: "What does the user do with the dashboard data?". User: "Spot anomalies and drill in." So-that strengthened.
207
113
 
208
114
  ### Bad
209
115
  One story per frame. Frames are screens; stories are user goals.
210
116
 
211
117
  ### Bad
212
- Emitting `clarifications.md`. Violates rule 1.
118
+ Emitting `clarifications.md` (violates base rule 1).
213
119
 
214
120
  ### Bad
215
121
  Skipping the mechanical matrix in `flow-summary.md` when N>1.
216
122
 
217
- ## Common Pitfalls
123
+ ## Common Pitfalls (figma-specific)
218
124
 
219
125
  - Treating each frame as a story.
220
126
  - 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.
127
+ - Ignoring empty/error/loading states. Fold into AC failure paths, not edge-case sections.
222
128
  - 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.
129
+ - Skipping per-story V audit when N>1 (figma flows over-split easily).
130
+ - All other pitfalls in `[[storywright-base]]` apply equally.
227
131
 
228
132
  ## References
229
133
 
134
+ - [[storywright-base]] — the rulebook
230
135
  - [[story-generate]]
231
- - [[story-split]]
232
136
  - [[story-refine]]
233
- - [[clarification-questions]]
137
+ - [[story-split]]
234
138
  - `./mcp-figma-notes.md` (MCP server setup)
235
139
 
236
140
  <claude-specific>
141
+ - Read `[[storywright-base]]` before applying. Do not duplicate its rules in your reasoning.
237
142
  - Use Claude vision when MCP is unavailable and the user drops PNGs.
238
143
  - Use extended thinking for flow grouping — prototype links can be ambiguous.
239
- - Cache the Phase 2 inference checklist across calls.
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`.
144
+ - When MCP is available, batch frame metadata fetches into one round trip.
145
+ - Build the multi-story dependency matrix from Given-text parsing (base rule 10), not intuition.
244
146
  </claude-specific>