@pavp/storywright 1.11.1 → 1.12.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/.claude-plugin/plugin.json +2 -1
- package/README.md +2 -1
- package/commands/story-generate.md +6 -1
- package/commands/story-refine.md +6 -1
- package/package.json +1 -1
- package/scripts/install-skills.mjs +7 -1
- package/scripts/validate-skills.mjs +17 -0
- package/scripts/zip-skill.mjs +26 -8
- package/skills/_components/analytics-events/SKILL.md +4 -4
- package/skills/_components/business-rules/SKILL.md +2 -2
- package/skills/_components/definition-of-done/SKILL.md +2 -2
- package/skills/_components/edge-cases/SKILL.md +4 -4
- package/skills/_components/jira-wiki-formatter/SKILL.md +41 -26
- package/skills/_components/risks-and-dependencies/SKILL.md +4 -4
- package/skills/_components/storywright-base/SKILL.md +19 -6
- package/skills/story-from-figma/SKILL.md +10 -4
- package/skills/story-generate/SKILL.md +6 -0
- package/skills/story-generate/templates/story.dev.md +27 -0
- package/skills/story-generate/templates/story.jira-wiki.md +4 -18
- package/skills/story-generate/templates/story.standard.md +6 -22
- package/skills/story-refine/SKILL.md +6 -0
- package/skills/story-split/SKILL.md +14 -5
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "storywright",
|
|
3
|
-
"version": "
|
|
3
|
+
"version": "1.12.0",
|
|
4
4
|
"description": "PM skills for Claude Code — turn ambiguous inputs (prompts, screenshots, Figma links) into Jira-ready user stories.",
|
|
5
5
|
"author": "pavp",
|
|
6
6
|
"license": "MIT",
|
|
@@ -11,6 +11,7 @@
|
|
|
11
11
|
"skills/story-refine",
|
|
12
12
|
"skills/story-split",
|
|
13
13
|
"skills/story-from-figma",
|
|
14
|
+
"skills/_components/storywright-base",
|
|
14
15
|
"skills/_components/clarification-questions",
|
|
15
16
|
"skills/_components/acceptance-criteria",
|
|
16
17
|
"skills/_components/invest-checklist",
|
package/README.md
CHANGED
|
@@ -26,7 +26,8 @@ Alternatives:
|
|
|
26
26
|
- **Git clone + symlink** for contributors:
|
|
27
27
|
```bash
|
|
28
28
|
git clone git@github.com:pavp/storywright.git
|
|
29
|
-
|
|
29
|
+
cd storywright
|
|
30
|
+
ln -s "$(pwd)/skills" ~/.claude/skills/storywright
|
|
30
31
|
```
|
|
31
32
|
- **ZIP upload to claude.ai**:
|
|
32
33
|
```bash
|
|
@@ -15,7 +15,12 @@ Follow the skill's full procedure:
|
|
|
15
15
|
4. Fill the CORE sections (Title, Summary, User Story, Acceptance Criteria, Definition of Done).
|
|
16
16
|
5. Fill optional sections only if they have real content (drop empty ones).
|
|
17
17
|
6. Run INVEST pre-split test. If count ≥2, show candidate children + ask via `AskUserQuestion` with options: "Yes, split" / "Continue without split" / "No, keep as-is". Never auto-split silently. For other verdicts (NOT A STORY / NEEDS REFINEMENT / RUN A SPIKE) — STOP and hand off accordingly.
|
|
18
|
-
7. Render
|
|
18
|
+
7. Render three outputs via `jira-wiki-formatter` to `docs/storywright/YYYY-MM-DD-HHmm-<title-slug>/` (current local time, title kebab-case max 5 words). Use the `Write` tool for all files — never ask:
|
|
19
|
+
- `story.standard.md` — PM-facing CommonMark: observable behavior only, no file paths/imports/component names/CLI commands
|
|
20
|
+
- `story.jira-wiki.md` — PM-facing Jira wiki markup: same content as standard
|
|
21
|
+
- `story.dev.md` — dev-facing CommonMark: full technical detail (file paths, imports, Technical Considerations, technical edge cases, DoD with `npm run` commands)
|
|
22
|
+
- `.storywright-context.json` — resolved session answers: `{"language":"...","persona":"...","naming_pattern":null,"output_folder":"...","resolved_questions":[],"sibling_refs":[]}`
|
|
23
|
+
Emit `story.standard.md` and `story.jira-wiki.md` as fenced code blocks in chat. Do NOT emit `story.dev.md` in chat.
|
|
19
24
|
8. Non-blocking assumptions remain? Mark inline with `⚠️ Assumed:`. Do NOT emit clarifications.md.
|
|
20
25
|
|
|
21
26
|
Output in the input language (preserve es/en).
|
package/commands/story-refine.md
CHANGED
|
@@ -16,5 +16,10 @@ Follow the skill's procedure:
|
|
|
16
16
|
4. Fill missing/weak sections via component skills. Preserve original wording where good.
|
|
17
17
|
5. Append a "Refinement log" at the end listing what changed.
|
|
18
18
|
6. Run INVEST pre-split test. If count ≥2, show candidate children + ask via `AskUserQuestion` with options: "Yes, split" / "Continue without split" / "No, keep as-is". Never auto-split silently.
|
|
19
|
-
7. Render
|
|
19
|
+
7. Render three outputs via `jira-wiki-formatter` to `docs/storywright/YYYY-MM-DD-HHmm-<title-slug>/` (current local time, title kebab-case max 5 words). Use the `Write` tool for all files — never ask:
|
|
20
|
+
- `story.standard.md` — PM-facing CommonMark: observable behavior only, no file paths/imports/component names/CLI commands
|
|
21
|
+
- `story.jira-wiki.md` — PM-facing Jira wiki markup: same content as standard
|
|
22
|
+
- `story.dev.md` — dev-facing CommonMark: full technical detail (file paths, imports, Technical Considerations, technical edge cases, DoD with `npm run` commands)
|
|
23
|
+
- `.storywright-context.json` — resolved session answers: `{"language":"...","persona":"...","naming_pattern":null,"output_folder":"...","resolved_questions":[],"sibling_refs":[]}`
|
|
24
|
+
Emit `story.standard.md` and `story.jira-wiki.md` as fenced code blocks in chat. Do NOT emit `story.dev.md` in chat.
|
|
20
25
|
8. Non-blocking assumptions remain? Mark inline with `⚠️ Assumed:`. Do NOT emit clarifications.md.
|
package/package.json
CHANGED
|
@@ -17,6 +17,10 @@ async function installSkills() {
|
|
|
17
17
|
}
|
|
18
18
|
await mkdir(skillsTarget, { recursive: true });
|
|
19
19
|
await cp(SKILLS_DIR, skillsTarget, { recursive: true });
|
|
20
|
+
// Verify the copy landed — cp can silently no-op on permission quirks.
|
|
21
|
+
if (!(await pathExists(join(skillsTarget, "_components")))) {
|
|
22
|
+
throw new Error(`copy verification failed: ${skillsTarget}/_components missing after install`);
|
|
23
|
+
}
|
|
20
24
|
console.log(`✓ Installed skills to ${skillsTarget}`);
|
|
21
25
|
}
|
|
22
26
|
|
|
@@ -49,7 +53,9 @@ async function ensureGlobalGitignore() {
|
|
|
49
53
|
globalIgnorePath = join(homedir(), ".gitignore_global");
|
|
50
54
|
execSync(`git config --global core.excludesFile "${globalIgnorePath}"`);
|
|
51
55
|
}
|
|
52
|
-
if (globalIgnorePath
|
|
56
|
+
if (globalIgnorePath === "~") {
|
|
57
|
+
globalIgnorePath = homedir();
|
|
58
|
+
} else if (globalIgnorePath.startsWith("~/")) {
|
|
53
59
|
globalIgnorePath = join(homedir(), globalIgnorePath.slice(2));
|
|
54
60
|
}
|
|
55
61
|
|
|
@@ -57,14 +57,31 @@ async function main() {
|
|
|
57
57
|
}
|
|
58
58
|
}
|
|
59
59
|
|
|
60
|
+
const referencedComponents = new Set();
|
|
60
61
|
for (const f of files) {
|
|
61
62
|
const skill = await loadSkill(f);
|
|
62
63
|
const composes = Array.isArray(skill.frontmatter.composes) ? skill.frontmatter.composes : [];
|
|
63
64
|
for (const dep of composes) {
|
|
64
65
|
if (!componentPaths.has(dep)) {
|
|
65
66
|
errors.push(`${skill.relPath}: composes references missing component '${dep}'`);
|
|
67
|
+
} else {
|
|
68
|
+
referencedComponents.add(dep);
|
|
66
69
|
}
|
|
67
70
|
}
|
|
71
|
+
// Body [[name]] links also count as a reference, so a component used only via
|
|
72
|
+
// prose cross-link (not composed) is not flagged as orphaned.
|
|
73
|
+
for (const m of skill.body.matchAll(/\[\[([a-z0-9-]+)\]\]/g)) {
|
|
74
|
+
referencedComponents.add(`_components/${m[1]}`);
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
// Orphan check: every component must be referenced by at least one skill
|
|
79
|
+
// (via composes or a body [[link]]). Catches dead/stale components that
|
|
80
|
+
// pass the existence check but are wired to nothing.
|
|
81
|
+
for (const comp of componentPaths) {
|
|
82
|
+
if (!referencedComponents.has(comp)) {
|
|
83
|
+
errors.push(`${comp}: orphaned component — referenced by no skill (composes or [[link]])`);
|
|
84
|
+
}
|
|
68
85
|
}
|
|
69
86
|
|
|
70
87
|
if (errors.length) {
|
package/scripts/zip-skill.mjs
CHANGED
|
@@ -11,16 +11,34 @@ if (!skillName) {
|
|
|
11
11
|
process.exit(1);
|
|
12
12
|
}
|
|
13
13
|
|
|
14
|
+
function hasZip() {
|
|
15
|
+
const probe = spawnSync("zip", ["-v"], { stdio: "ignore" });
|
|
16
|
+
return !probe.error;
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
async function resolveSourceDir() {
|
|
20
|
+
const topDir = join(SKILLS_DIR, skillName);
|
|
21
|
+
if (await pathExists(topDir)) return topDir;
|
|
22
|
+
const compDir = join(SKILLS_DIR, "_components", skillName);
|
|
23
|
+
if (await pathExists(compDir)) return compDir;
|
|
24
|
+
return null;
|
|
25
|
+
}
|
|
26
|
+
|
|
14
27
|
async function main() {
|
|
15
|
-
const
|
|
16
|
-
if (!
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
console.error(`✗ Skill not found: ${skillName}`);
|
|
20
|
-
process.exit(1);
|
|
21
|
-
}
|
|
28
|
+
const sourceDir = await resolveSourceDir();
|
|
29
|
+
if (!sourceDir) {
|
|
30
|
+
console.error(`✗ Skill not found: ${skillName}`);
|
|
31
|
+
process.exit(1);
|
|
22
32
|
}
|
|
23
|
-
|
|
33
|
+
if (!(await pathExists(join(sourceDir, "SKILL.md")))) {
|
|
34
|
+
console.error(`✗ ${skillName} has no SKILL.md — refusing to zip an invalid skill`);
|
|
35
|
+
process.exit(1);
|
|
36
|
+
}
|
|
37
|
+
if (!hasZip()) {
|
|
38
|
+
console.error("✗ `zip` not found on PATH. Install it (e.g. `brew install zip` / `apt-get install zip`) and retry.");
|
|
39
|
+
process.exit(127);
|
|
40
|
+
}
|
|
41
|
+
|
|
24
42
|
const outDir = join(REPO_ROOT, "dist");
|
|
25
43
|
if (!existsSync(outDir)) mkdirSync(outDir, { recursive: true });
|
|
26
44
|
|
|
@@ -3,12 +3,12 @@ name: analytics-events
|
|
|
3
3
|
description: Propose analytics/event tracking for a story. Names events, payloads, and trigger points. Returns only the analytics block, ready for ProductOps to map.
|
|
4
4
|
trigger: "internal use by story-* skills"
|
|
5
5
|
intent: Component skill that drafts a small, opinionated set of analytics events using a consistent naming convention.
|
|
6
|
-
version:
|
|
6
|
+
version: 2.0.0
|
|
7
7
|
inputs:
|
|
8
8
|
- story-context
|
|
9
9
|
- acceptance-criteria
|
|
10
10
|
outputs:
|
|
11
|
-
- analytics-events-block
|
|
11
|
+
- analytics-events-block (dev.md only)
|
|
12
12
|
---
|
|
13
13
|
|
|
14
14
|
## Purpose
|
|
@@ -17,7 +17,7 @@ Stories without analytics are stories without feedback. Propose the minimum set
|
|
|
17
17
|
|
|
18
18
|
## When to use
|
|
19
19
|
|
|
20
|
-
|
|
20
|
+
**Dev-file only.** Invoked while rendering `story.dev.md`, after acceptance criteria are drafted; events align to observable AC outcomes. Event names, payloads, and PII boundaries are technical detail — they belong in `story.dev.md`, never the PM-facing files (`[[storywright-base]]` rule 3).
|
|
21
21
|
|
|
22
22
|
## Inputs & interpretation
|
|
23
23
|
|
|
@@ -42,7 +42,7 @@ After acceptance criteria are drafted; events should align to observable AC outc
|
|
|
42
42
|
- `🔧 ops` — feeds error monitoring
|
|
43
43
|
- `💰 revenue` — feeds growth metrics
|
|
44
44
|
5. Note retention/PII boundaries explicitly when sensitive (e.g., emails hashed).
|
|
45
|
-
6. Emit under `### Analytics / Eventos
|
|
45
|
+
6. Emit under `### Analytics / Eventos` **inside `story.dev.md`**.
|
|
46
46
|
|
|
47
47
|
Example block:
|
|
48
48
|
|
|
@@ -3,7 +3,7 @@ name: business-rules
|
|
|
3
3
|
description: Extract and articulate business rules a story must honor. Distinguish rules (always true) from acceptance criteria (testable on this story). Returns only the rules block.
|
|
4
4
|
trigger: "internal use by story-* skills"
|
|
5
5
|
intent: Component skill that surfaces invariants, policies, and constraints that bound a story without being acceptance criteria themselves.
|
|
6
|
-
version:
|
|
6
|
+
version: 2.0.0
|
|
7
7
|
inputs:
|
|
8
8
|
- story-context
|
|
9
9
|
- domain-hints
|
|
@@ -17,7 +17,7 @@ Business rules are **policy invariants** the story must respect. They survive ac
|
|
|
17
17
|
|
|
18
18
|
## When to use
|
|
19
19
|
|
|
20
|
-
After the story body is drafted, before ACs are finalized — so ACs can reference relevant rules.
|
|
20
|
+
After the story body is drafted, before ACs are finalized — so ACs can reference relevant rules. Business Rules are an **optional PM section** (see `[[jira-wiki-formatter]]` — emit in `story.standard.md` / `story.jira-wiki.md` only when non-empty) AND are mirrored in `story.dev.md`. They are policy invariants, not technical detail, so unlike edge-cases they are not dev-only.
|
|
21
21
|
|
|
22
22
|
## Inputs & interpretation
|
|
23
23
|
|
|
@@ -3,7 +3,7 @@ name: definition-of-done
|
|
|
3
3
|
description: Produce a Definition of Done block for a user story. Covers code, tests, analytics, docs, accessibility, and release gates. Returns only the DoD block.
|
|
4
4
|
trigger: "internal use by story-* skills"
|
|
5
5
|
intent: Component skill that emits a baseline DoD aligned to common product/eng standards. Customizable via project-level overrides documented in the story.
|
|
6
|
-
version:
|
|
6
|
+
version: 2.0.0
|
|
7
7
|
inputs:
|
|
8
8
|
- story-context
|
|
9
9
|
- technical-considerations
|
|
@@ -17,7 +17,7 @@ A Definition of Done is the contract for "shippable". It must be **checkable, ob
|
|
|
17
17
|
|
|
18
18
|
## When to use
|
|
19
19
|
|
|
20
|
-
Invoked
|
|
20
|
+
Invoked after acceptance criteria and technical considerations are drafted. DoD is **dual-rendered** (see `[[jira-wiki-formatter]]`): the PM-facing files (`story.standard.md` / `story.jira-wiki.md`) carry the **acceptance-only** DoD (no CLI commands, no file-level criteria); `story.dev.md` carries the **full** DoD including CLI commands (`npm run test`) and file-level lines. Produce both projections from the baseline below: PM projection = drop command/file lines; dev projection = keep everything.
|
|
21
21
|
|
|
22
22
|
## Inputs & interpretation
|
|
23
23
|
|
|
@@ -3,11 +3,11 @@ name: edge-cases
|
|
|
3
3
|
description: Enumerate edge cases for a story. Covers boundary, concurrency, network, data, permission, and UX-state failures. Returns only the edge-cases block.
|
|
4
4
|
trigger: "internal use by story-* skills"
|
|
5
5
|
intent: Component skill that systematically generates edge cases across known failure axes so acceptance criteria can cover them.
|
|
6
|
-
version:
|
|
6
|
+
version: 2.0.0
|
|
7
7
|
inputs:
|
|
8
8
|
- story-context
|
|
9
9
|
outputs:
|
|
10
|
-
- edge-cases-block
|
|
10
|
+
- edge-cases-block (dev.md only)
|
|
11
11
|
---
|
|
12
12
|
|
|
13
13
|
## Purpose
|
|
@@ -16,7 +16,7 @@ Edge cases are how engineers find latent risk. Generate them **before** acceptan
|
|
|
16
16
|
|
|
17
17
|
## When to use
|
|
18
18
|
|
|
19
|
-
Invoked
|
|
19
|
+
**Dev-file only.** Invoked while rendering `story.dev.md` (the dev-facing file), never the PM-facing `story.standard.md` / `story.jira-wiki.md`. `[[storywright-base]]` rule 3 forbids an Edge Cases section in the PM story body — this output lands exclusively in `story.dev.md`. It still informs AC failure paths (`[[acceptance-criteria]]`): the AC covers the observable behavior in the PM files; the enumerated technical edge detail lives in dev.md.
|
|
20
20
|
|
|
21
21
|
## Inputs & interpretation
|
|
22
22
|
|
|
@@ -37,7 +37,7 @@ Walk these axes and pick the ones that apply:
|
|
|
37
37
|
|
|
38
38
|
For each applicable axis, write 1–2 concrete cases. Keep each ≤1 sentence.
|
|
39
39
|
|
|
40
|
-
Emit under `### Edge Cases
|
|
40
|
+
Emit under `### Edge Cases` **inside `story.dev.md`** (never the PM files):
|
|
41
41
|
|
|
42
42
|
```
|
|
43
43
|
### Edge Cases
|
|
@@ -1,14 +1,15 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: jira-wiki-formatter
|
|
3
|
-
description: Render a story into
|
|
3
|
+
description: Render a story into three files: story.standard.md and story.jira-wiki.md (PM-facing, no technical detail) plus story.dev.md (dev-facing, full technical detail).
|
|
4
4
|
trigger: "internal use by story-* skills"
|
|
5
|
-
intent: Component skill that takes a structured story
|
|
6
|
-
version:
|
|
5
|
+
intent: Component skill that takes a structured story and produces three output files following the templates in story-generate/templates.
|
|
6
|
+
version: 2.0.0
|
|
7
7
|
inputs:
|
|
8
8
|
- structured-story
|
|
9
9
|
outputs:
|
|
10
|
-
- story.jira-wiki.md
|
|
11
10
|
- story.standard.md
|
|
11
|
+
- story.jira-wiki.md
|
|
12
|
+
- story.dev.md
|
|
12
13
|
---
|
|
13
14
|
|
|
14
15
|
## Purpose
|
|
@@ -25,7 +26,21 @@ Final step in `story-generate` and `story-refine`. Always last.
|
|
|
25
26
|
|
|
26
27
|
## Application (step-by-step)
|
|
27
28
|
|
|
28
|
-
|
|
29
|
+
## Audience separation — THREE files
|
|
30
|
+
|
|
31
|
+
| File | Audience | Technical detail |
|
|
32
|
+
|---|---|---|
|
|
33
|
+
| `story.standard.md` | PM, stakeholders | ❌ None — no file paths, no imports, no component names, no `npm run X` in DoD |
|
|
34
|
+
| `story.jira-wiki.md` | PM → Jira paste | ❌ None — same content as standard, Jira markup |
|
|
35
|
+
| `story.dev.md` | Developer | ✅ Full — file paths, imports, Technical Considerations, technical edge cases, full DoD with commands |
|
|
36
|
+
|
|
37
|
+
**What is "technical":** file paths, import statements, component/hook names, API method names, CLI commands (`npm run test`), null/undefined checks, browser API constraints (HTTPS, permissions), specific library flags.
|
|
38
|
+
|
|
39
|
+
**ACs in PM files must describe observable behavior only.** "A copy icon appears next to the email field and clicking it copies the value" — not "ContentCopyOutlinedIcon is rendered next to the email Typography block and calls navigator.clipboard.writeText()".
|
|
40
|
+
|
|
41
|
+
---
|
|
42
|
+
|
|
43
|
+
1. Render `story.jira-wiki.md` (PM-facing) using Jira's wiki markup:
|
|
29
44
|
- Headings: `h1. `, `h2. `, `h3. `
|
|
30
45
|
- Bold: `*text*`
|
|
31
46
|
- Italic: `_text_`
|
|
@@ -33,7 +48,8 @@ Final step in `story-generate` and `story-refine`. Always last.
|
|
|
33
48
|
- Lists: `* item`, `# item` (numbered)
|
|
34
49
|
- Tables: `||header||header||` then `|cell|cell|`
|
|
35
50
|
- Panels for callouts: `{panel:title=⚠️ Assumed}…{panel}`
|
|
36
|
-
|
|
51
|
+
- Strip all technical detail (see audience table above)
|
|
52
|
+
2. Render `story.standard.md` (PM-facing) using CommonMark:
|
|
37
53
|
- Headings: `##`, `###`
|
|
38
54
|
- Bold: `**text**`
|
|
39
55
|
- Italic: `*text*`
|
|
@@ -41,29 +57,28 @@ Final step in `story-generate` and `story-refine`. Always last.
|
|
|
41
57
|
- Lists: `- item`, `1. item`
|
|
42
58
|
- Tables: standard pipe tables
|
|
43
59
|
- Callouts: `> ⚠️ **Assumed:** …`
|
|
44
|
-
|
|
60
|
+
- Strip all technical detail (see audience table above)
|
|
61
|
+
3. Render `story.dev.md` (dev-facing) using CommonMark:
|
|
62
|
+
- Same structure as `story.standard.md` PLUS:
|
|
63
|
+
- Technical Considerations section (file paths, imports, API calls)
|
|
64
|
+
- Edge Cases section (null checks, error states, browser constraints)
|
|
65
|
+
- DoD includes CLI commands and file-level criteria
|
|
66
|
+
- Refinement log includes technical changes
|
|
67
|
+
4. Section model for PM files = **core + optional (non-technical)**.
|
|
45
68
|
|
|
46
69
|
**Core (always emit, in this order):**
|
|
47
70
|
1. Title
|
|
48
|
-
2.
|
|
49
|
-
3.
|
|
50
|
-
4.
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
6.
|
|
55
|
-
7. Business
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
11. Technical Considerations
|
|
60
|
-
12. Dependencies
|
|
61
|
-
13. Risks
|
|
62
|
-
14. Analytics
|
|
63
|
-
15. Edge Cases
|
|
64
|
-
|
|
65
|
-
4. **Drop any section with no real content.** An empty heading is noise. A story with only the 5 core sections is a valid output.
|
|
66
|
-
5. Emit both as fenced code blocks in the chat so the user can copy them. File persistence is handled by the calling skill via the `Write` tool.
|
|
71
|
+
2. User Story (As a / I want to / so that)
|
|
72
|
+
3. Acceptance Criteria (observable behavior only)
|
|
73
|
+
4. Definition of Done (acceptance criteria only, no commands)
|
|
74
|
+
|
|
75
|
+
**Optional PM sections (emit only if non-empty):**
|
|
76
|
+
5. Business Goal
|
|
77
|
+
6. Scope / Out of Scope
|
|
78
|
+
7. Business Rules
|
|
79
|
+
|
|
80
|
+
5. **Drop any section with no real content.** An empty heading is noise.
|
|
81
|
+
6. Emit `story.standard.md` and `story.jira-wiki.md` as fenced code blocks in chat (PM-facing). Do NOT emit `story.dev.md` in chat — write to disk only. File persistence is handled by the calling skill via the `Write` tool.
|
|
67
82
|
|
|
68
83
|
## Examples
|
|
69
84
|
|
|
@@ -3,13 +3,13 @@ name: risks-and-dependencies
|
|
|
3
3
|
description: Surface technical, product, and organizational risks plus blocking dependencies for a story. Each item has owner, likelihood, mitigation. Returns only the risks+deps block.
|
|
4
4
|
trigger: "internal use by story-* skills"
|
|
5
5
|
intent: Component skill that turns hidden assumptions into tracked risks and dependencies so PMs and tech leads can act on them.
|
|
6
|
-
version:
|
|
6
|
+
version: 2.0.0
|
|
7
7
|
inputs:
|
|
8
8
|
- story-context
|
|
9
9
|
- business-rules
|
|
10
10
|
- technical-considerations
|
|
11
11
|
outputs:
|
|
12
|
-
- risks-and-dependencies-block
|
|
12
|
+
- risks-and-dependencies-block (dev.md only)
|
|
13
13
|
---
|
|
14
14
|
|
|
15
15
|
## Purpose
|
|
@@ -18,7 +18,7 @@ Risks and dependencies that aren't written down end up as outages or missed laun
|
|
|
18
18
|
|
|
19
19
|
## When to use
|
|
20
20
|
|
|
21
|
-
|
|
21
|
+
**Dev-file only.** Invoked while rendering `story.dev.md`, after business rules and technical considerations are drafted — those inform what's risky. Risks and dependencies reference infra, SDKs, env vars, and ownership — technical/delivery detail that belongs in `story.dev.md`, not the PM-facing files (`[[storywright-base]]` rule 3 bans Dependencies-as-prose in the PM body; PM files link Jira tickets only).
|
|
22
22
|
|
|
23
23
|
## Inputs & interpretation
|
|
24
24
|
|
|
@@ -41,7 +41,7 @@ Late in `story-generate`, after business rules and technical considerations are
|
|
|
41
41
|
- **Operational** (oncall toil, monitoring gap)
|
|
42
42
|
4. For each risk: `<risk> · likelihood (L/M/H) · impact (L/M/H) · mitigation`
|
|
43
43
|
5. If a risk is high-impact AND high-likelihood, flag it `🚨` so it gets attention in review.
|
|
44
|
-
6. Emit under two subheadings: `### Dependencias` and `### Riesgos` (or English).
|
|
44
|
+
6. Emit under two subheadings: `### Dependencias` and `### Riesgos` (or English) **inside `story.dev.md`**.
|
|
45
45
|
|
|
46
46
|
Example:
|
|
47
47
|
|
|
@@ -3,7 +3,7 @@ name: storywright-base
|
|
|
3
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
4
|
trigger: "internal use by story-* skills"
|
|
5
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.
|
|
6
|
+
version: 2.3.0
|
|
7
7
|
inputs:
|
|
8
8
|
- none
|
|
9
9
|
outputs:
|
|
@@ -31,13 +31,15 @@ If you are reading this through a top-level skill, treat every rule below as non
|
|
|
31
31
|
- ONE AC Scenario (one Given chain + one `When` + one `Then`).
|
|
32
32
|
If the input naturally needs >1 `When`/`Then`, the skill MUST stop the single-story path and route to `[[story-split]]`.
|
|
33
33
|
|
|
34
|
-
3. **No mini-PRDs.** PROHIBITED
|
|
34
|
+
3. **No mini-PRDs in the PM story body.** PROHIBITED in `story.standard.md` / `story.jira-wiki.md`:
|
|
35
35
|
- Non-Functional Requirements blocks (a11y/i18n/perf/tokens) — DoD only.
|
|
36
36
|
- Edge Cases enumerated as their own section — fold into AC failure paths.
|
|
37
37
|
- Dependencies as prose — Jira ticket links only.
|
|
38
38
|
- Per-claim visual specs (pixel measurements, hex inferences) inline — use single banner (rule 5).
|
|
39
39
|
- Logs >3 lines (>5 if SPLIT verdict).
|
|
40
40
|
|
|
41
|
+
3a. **Technical detail lives in `story.dev.md`.** The content rule 3 bans from the PM body is NOT discarded — it is rendered in the dev-facing file. Edge cases, analytics events, risks/dependencies, technical considerations, and the command-level DoD belong in `story.dev.md`, populated by the enrichment components (Application step 8b). The PM↔dev split is the home for this content; rule 3 governs the PM files, `story.dev.md` carries the technical detail. See `[[jira-wiki-formatter]]` for the audience table.
|
|
42
|
+
|
|
41
43
|
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
44
|
|
|
43
45
|
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:
|
|
@@ -218,7 +220,15 @@ NOTHING else. No NFR block. No Edge Cases enumeration. No Dependencies prose. No
|
|
|
218
220
|
- Count ≤1 → continue to step 8 (single-story path).
|
|
219
221
|
- Count ≥2 → execute the **host skill's split behavior** (see Source-specific differential in each top-level skill).
|
|
220
222
|
|
|
221
|
-
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.
|
|
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 **in the PM story body** — rule 3 still holds for `story.standard.md` / `story.jira-wiki.md`.
|
|
224
|
+
|
|
225
|
+
8b. **Gather dev-file enrichment** (feeds `story.dev.md` only — see rule 3a). Invoke the enrichment components to populate the technical sections of the dev file:
|
|
226
|
+
- `[[edge-cases]]` → `### Edge Cases` (technical failure axes)
|
|
227
|
+
- `[[risks-and-dependencies]]` → `### Dependencias` + `### Riesgos`
|
|
228
|
+
- `[[analytics-events]]` → `### Analytics / Eventos`
|
|
229
|
+
- `[[definition-of-done]]` → full DoD with CLI commands (PM files get the acceptance-only projection)
|
|
230
|
+
- `[[business-rules]]` → policy invariants (also an *optional* PM section per `[[jira-wiki-formatter]]` when non-empty)
|
|
231
|
+
None of these may appear in the PM story body except the optional Business Rules section. Skip any component whose output is empty (drop empty sections — rule 3 / jira-wiki-formatter).
|
|
222
232
|
|
|
223
233
|
9. **Run INVEST** via `[[invest-checklist]]`.
|
|
224
234
|
- `READY` → render.
|
|
@@ -228,10 +238,13 @@ NOTHING else. No NFR block. No Edge Cases enumeration. No Dependencies prose. No
|
|
|
228
238
|
|
|
229
239
|
10. **Render** via `[[jira-wiki-formatter]]`.
|
|
230
240
|
- Derive the output folder: `docs/storywright/YYYY-MM-DD-HHmm-<title-slug>/` where `YYYY-MM-DD-HHmm` is the current local date+time and `<title-slug>` is the story title in kebab-case (max 5 words, drop articles/prepositions).
|
|
231
|
-
- Use the `Write` tool to persist
|
|
232
|
-
|
|
241
|
+
- Use the `Write` tool to persist three files to that folder (create it if it does not exist):
|
|
242
|
+
- `story.standard.md` — PM-facing CommonMark, no technical detail
|
|
243
|
+
- `story.jira-wiki.md` — PM-facing Jira wiki markup, no technical detail
|
|
244
|
+
- `story.dev.md` — dev-facing CommonMark, full technical detail (file paths, imports, technical edge cases, full DoD with commands)
|
|
245
|
+
- Emit `story.standard.md` and `story.jira-wiki.md` as fenced code blocks in chat. Do NOT emit `story.dev.md` in chat.
|
|
233
246
|
- Write `.storywright-context.json` to the same folder.
|
|
234
|
-
-
|
|
247
|
+
- Never ask whether to save — always write all four files.
|
|
235
248
|
|
|
236
249
|
11. **Log** ≤3 bullets (≤5 if SPLIT) appended at story end. Log type label is host-specific (Generation / Refinement / Split).
|
|
237
250
|
|
|
@@ -9,12 +9,18 @@ inputs:
|
|
|
9
9
|
outputs:
|
|
10
10
|
- story-1.standard.md
|
|
11
11
|
- story-1.jira-wiki.md
|
|
12
|
+
- story-1.dev.md
|
|
12
13
|
- flow-summary.md
|
|
13
14
|
- .storywright-context.json
|
|
14
15
|
composes:
|
|
15
16
|
- _components/storywright-base
|
|
16
17
|
- _components/clarification-questions
|
|
18
|
+
- _components/business-rules
|
|
17
19
|
- _components/acceptance-criteria
|
|
20
|
+
- _components/edge-cases
|
|
21
|
+
- _components/analytics-events
|
|
22
|
+
- _components/risks-and-dependencies
|
|
23
|
+
- _components/definition-of-done
|
|
18
24
|
- _components/invest-checklist
|
|
19
25
|
- _components/jira-wiki-formatter
|
|
20
26
|
---
|
|
@@ -85,15 +91,15 @@ Use the base canonical output shape. Design Reference banner per source-specific
|
|
|
85
91
|
|
|
86
92
|
### Phase 5 — Output
|
|
87
93
|
|
|
88
|
-
Per drafted flow:
|
|
89
|
-
- `story-<N>.standard.md` + `story-<N>.jira-wiki.md
|
|
94
|
+
Per drafted flow, render the full trio via `[[jira-wiki-formatter]]` (same 3-file contract as `story-generate` / `story-refine`):
|
|
95
|
+
- `story-<N>.standard.md` + `story-<N>.jira-wiki.md` (PM-facing) + `story-<N>.dev.md` (dev-facing).
|
|
90
96
|
|
|
91
97
|
If N>1 OR any flow was routed to split:
|
|
92
98
|
- `flow-summary.md` with the matrix, V audit, build order, and SPLIT-RECOMMENDED markers.
|
|
93
99
|
|
|
94
100
|
Plus `.storywright-context.json` updated (`extra.figma_url`, `extra.figma_scope`, `extra.mcp_available`).
|
|
95
101
|
|
|
96
|
-
NO `clarifications.md`. NO Edge Cases sections.
|
|
102
|
+
NO `clarifications.md`. NO Edge Cases / NFR sections **in the PM files** (they live in `story-<N>.dev.md` per base rule 3a). NO per-claim visual tags.
|
|
97
103
|
|
|
98
104
|
## Examples
|
|
99
105
|
|
|
@@ -124,7 +130,7 @@ Skipping the mechanical matrix in `flow-summary.md` when N>1.
|
|
|
124
130
|
|
|
125
131
|
- Treating each frame as a story.
|
|
126
132
|
- Skipping prototype-link analysis — without flow structure, user goals are guesses.
|
|
127
|
-
- Ignoring empty/error/loading states.
|
|
133
|
+
- Ignoring empty/error/loading states. In the PM files fold them into AC failure paths (no edge-case section); the technical detail goes to `story-<N>.dev.md`.
|
|
128
134
|
- Trusting MEDIUM/LOW inferences silently — mark `⚠️ Assumed`.
|
|
129
135
|
- Skipping per-story V audit when N>1 (figma flows over-split easily).
|
|
130
136
|
- All other pitfalls in `[[storywright-base]]` apply equally.
|
|
@@ -11,11 +11,17 @@ inputs:
|
|
|
11
11
|
outputs:
|
|
12
12
|
- story.standard.md
|
|
13
13
|
- story.jira-wiki.md
|
|
14
|
+
- story.dev.md
|
|
14
15
|
- .storywright-context.json
|
|
15
16
|
composes:
|
|
16
17
|
- _components/storywright-base
|
|
17
18
|
- _components/clarification-questions
|
|
19
|
+
- _components/business-rules
|
|
18
20
|
- _components/acceptance-criteria
|
|
21
|
+
- _components/edge-cases
|
|
22
|
+
- _components/analytics-events
|
|
23
|
+
- _components/risks-and-dependencies
|
|
24
|
+
- _components/definition-of-done
|
|
19
25
|
- _components/invest-checklist
|
|
20
26
|
- _components/jira-wiki-formatter
|
|
21
27
|
---
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
# {{Title}} — Dev Notes
|
|
2
|
+
|
|
3
|
+
> This file is the developer supplement to `story.standard.md`.
|
|
4
|
+
> It contains all technical detail stripped from the PM-facing outputs.
|
|
5
|
+
|
|
6
|
+
## Technical Considerations
|
|
7
|
+
|
|
8
|
+
- {{file path or component name}} — {{what changes}}
|
|
9
|
+
- {{import to add/remove}}
|
|
10
|
+
- {{API call / SDK / feature flag / data model note}}
|
|
11
|
+
|
|
12
|
+
## Edge Cases & Error States
|
|
13
|
+
|
|
14
|
+
- **{{axis}}:** {{technical behavior — null checks, error states, race conditions, HTTPS requirements}}
|
|
15
|
+
|
|
16
|
+
## Definition of Done
|
|
17
|
+
|
|
18
|
+
- [ ] {{business criterion}}
|
|
19
|
+
- [ ] {{test command: npm run test / npm run lint}}
|
|
20
|
+
- [ ] {{file-level criterion: file X updated, import Y removed}}
|
|
21
|
+
|
|
22
|
+
---
|
|
23
|
+
|
|
24
|
+
<!-- Refinement Log — full version including technical changes -->
|
|
25
|
+
|
|
26
|
+
*Refinement log*
|
|
27
|
+
- {{change}} — {{reason}}
|
|
@@ -20,6 +20,10 @@ h3. Definition of Done
|
|
|
20
20
|
|
|
21
21
|
----
|
|
22
22
|
|
|
23
|
+
{panel:title=PM-facing — no technical detail}
|
|
24
|
+
Technical Considerations, Edge Cases, Analytics, Risks & Dependencies live in story.dev.md (rule 3). Optional sections below — keep only those with content.
|
|
25
|
+
{panel}
|
|
26
|
+
|
|
23
27
|
h3. Contexto
|
|
24
28
|
{{trigger: feedback / OKR / incident / competitor}}
|
|
25
29
|
|
|
@@ -34,21 +38,3 @@ h3. Out of Scope
|
|
|
34
38
|
|
|
35
39
|
h3. Business Rules
|
|
36
40
|
# {{rule 1}}
|
|
37
|
-
|
|
38
|
-
h3. Technical Considerations
|
|
39
|
-
* {{api / sdk / flag / data model}}
|
|
40
|
-
|
|
41
|
-
h3. Dependencies
|
|
42
|
-
||What||Owner||Status||Blocks?||
|
|
43
|
-
|{{dep}}|{{owner}}|{{READY/IN-PROGRESS}}|{{Yes/No}}|
|
|
44
|
-
|
|
45
|
-
h3. Risks
|
|
46
|
-
||Risk||L||I||Mitigation||
|
|
47
|
-
|{{risk}}|{{L/M/H}}|{{L/M/H}}|{{action}}|
|
|
48
|
-
|
|
49
|
-
h3. Analytics
|
|
50
|
-
||Event||Trigger||Payload||
|
|
51
|
-
|{{event_name}}|{{when}}|{{fields}}|
|
|
52
|
-
|
|
53
|
-
h3. Edge Cases
|
|
54
|
-
* *{{axis}}:* {{behavior}}
|
|
@@ -20,7 +20,12 @@
|
|
|
20
20
|
|
|
21
21
|
---
|
|
22
22
|
|
|
23
|
-
<!--
|
|
23
|
+
<!--
|
|
24
|
+
PM-facing file. NO technical detail (rule 3): no file paths, imports, commands,
|
|
25
|
+
edge-case sections, NFR blocks, or dependency prose. Technical Considerations,
|
|
26
|
+
Edge Cases, Analytics, Risks & Dependencies live in story.dev.md.
|
|
27
|
+
Optional sections below — keep only those with content. Delete the rest.
|
|
28
|
+
-->
|
|
24
29
|
|
|
25
30
|
## Contexto
|
|
26
31
|
{{trigger: feedback / OKR / incident / competitor}}
|
|
@@ -36,24 +41,3 @@
|
|
|
36
41
|
|
|
37
42
|
## Business Rules
|
|
38
43
|
1. {{rule 1}}
|
|
39
|
-
|
|
40
|
-
## Technical Considerations
|
|
41
|
-
- {{api / sdk / flag / data model}}
|
|
42
|
-
|
|
43
|
-
## Dependencies
|
|
44
|
-
| What | Owner | Status | Blocks? |
|
|
45
|
-
|---|---|---|---|
|
|
46
|
-
| {{dep}} | {{owner}} | {{READY/IN-PROGRESS}} | {{Yes/No}} |
|
|
47
|
-
|
|
48
|
-
## Risks
|
|
49
|
-
| Risk | L | I | Mitigation |
|
|
50
|
-
|---|---|---|---|
|
|
51
|
-
| {{risk}} | {{L/M/H}} | {{L/M/H}} | {{action}} |
|
|
52
|
-
|
|
53
|
-
## Analytics
|
|
54
|
-
| Event | Trigger | Payload |
|
|
55
|
-
|---|---|---|
|
|
56
|
-
| `{{event_name}}` | {{when}} | {{fields}} |
|
|
57
|
-
|
|
58
|
-
## Edge Cases
|
|
59
|
-
- **{{axis}}:** {{behavior}}
|
|
@@ -11,11 +11,17 @@ inputs:
|
|
|
11
11
|
outputs:
|
|
12
12
|
- story.standard.md
|
|
13
13
|
- story.jira-wiki.md
|
|
14
|
+
- story.dev.md
|
|
14
15
|
- .storywright-context.json
|
|
15
16
|
composes:
|
|
16
17
|
- _components/storywright-base
|
|
17
18
|
- _components/clarification-questions
|
|
19
|
+
- _components/business-rules
|
|
18
20
|
- _components/acceptance-criteria
|
|
21
|
+
- _components/edge-cases
|
|
22
|
+
- _components/analytics-events
|
|
23
|
+
- _components/risks-and-dependencies
|
|
24
|
+
- _components/definition-of-done
|
|
19
25
|
- _components/invest-checklist
|
|
20
26
|
- _components/jira-wiki-formatter
|
|
21
27
|
---
|
|
@@ -10,14 +10,23 @@ inputs:
|
|
|
10
10
|
- figma-link
|
|
11
11
|
outputs:
|
|
12
12
|
- epic.md
|
|
13
|
-
- story-1.md
|
|
14
|
-
- story-
|
|
13
|
+
- story-1.standard.md
|
|
14
|
+
- story-1.jira-wiki.md
|
|
15
|
+
- story-1.dev.md
|
|
16
|
+
- story-2.standard.md
|
|
17
|
+
- story-2.jira-wiki.md
|
|
18
|
+
- story-2.dev.md
|
|
15
19
|
- .storywright-context.json
|
|
16
20
|
composes:
|
|
17
21
|
- _components/storywright-base
|
|
18
22
|
- _components/invest-checklist
|
|
19
23
|
- _components/clarification-questions
|
|
24
|
+
- _components/business-rules
|
|
20
25
|
- _components/acceptance-criteria
|
|
26
|
+
- _components/edge-cases
|
|
27
|
+
- _components/analytics-events
|
|
28
|
+
- _components/risks-and-dependencies
|
|
29
|
+
- _components/definition-of-done
|
|
21
30
|
- _components/jira-wiki-formatter
|
|
22
31
|
---
|
|
23
32
|
|
|
@@ -35,8 +44,8 @@ When a story is an epic in disguise, splitting badly is worse than not splitting
|
|
|
35
44
|
## Split behavior differential
|
|
36
45
|
|
|
37
46
|
This skill IS the split behavior. It always emits multiple files:
|
|
38
|
-
- `epic.md` — title, why-split, INVEST failure reasons, mechanical NxN matrix, build order, V audit per child, list of children.
|
|
39
|
-
- `story
|
|
47
|
+
- `epic.md` — title, why-split, INVEST failure reasons, mechanical NxN matrix, build order, V audit per child, list of children. Single file (epic metadata, not a user story).
|
|
48
|
+
- Per child: the full 3-file trio `story-<N>.standard.md` + `story-<N>.jira-wiki.md` + `story-<N>.dev.md`, rendered via `[[jira-wiki-formatter]]` — same contract as every other story-producing skill. Each child is a canonical user story (per base shape).
|
|
40
49
|
- `.storywright-context.json` — persisted answers.
|
|
41
50
|
|
|
42
51
|
NO `split-plan.md`. The plan lives inside `epic.md`.
|
|
@@ -107,7 +116,7 @@ Follow the **base Application** skeleton for the front-end behaviors (context lo
|
|
|
107
116
|
|
|
108
117
|
5. **STOP and ask the user to approve via `AskUserQuestion`.**
|
|
109
118
|
|
|
110
|
-
6. **For each approved child, write the base canonical block
|
|
119
|
+
6. **For each approved child, write the base canonical block, then render via `[[jira-wiki-formatter]]` to the 3-file trio** (`story-<N>.standard.md` + `story-<N>.jira-wiki.md` + `story-<N>.dev.md`). The child's enrichment (edge cases, risks, analytics) populates its `story-<N>.dev.md` per base step 8b.
|
|
111
120
|
|
|
112
121
|
7. **Build dependency matrix mechanically (base rule 10).** Render in `epic.md`.
|
|
113
122
|
|