@c0x12c/spartan-ai-toolkit 1.10.0 → 1.11.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/.claude-plugin/marketplace.json +2 -2
- package/.claude-plugin/plugin.json +2 -2
- package/README.md +16 -0
- package/VERSION +1 -1
- package/claude-md/40-product.md +1 -0
- package/commands/spartan/build.md +6 -8
- package/commands/spartan/web-to-prd.md +544 -0
- package/package.json +1 -1
- package/packs/packs.compiled.json +5 -2
- package/packs/product.yaml +3 -1
- package/skills/web-to-prd/SKILL.md +436 -0
|
@@ -8,9 +8,9 @@
|
|
|
8
8
|
"plugins": [
|
|
9
9
|
{
|
|
10
10
|
"name": "spartan-ai-toolkit",
|
|
11
|
-
"description": "5 workflows,
|
|
11
|
+
"description": "5 workflows, 69 commands, 21 rules, 29 skills, 9 agents — organized in 12 packs with dependencies",
|
|
12
12
|
"source": "./toolkit",
|
|
13
|
-
"version": "1.
|
|
13
|
+
"version": "1.11.0"
|
|
14
14
|
}
|
|
15
15
|
]
|
|
16
16
|
}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "spartan-ai-toolkit",
|
|
3
|
-
"version": "1.
|
|
4
|
-
"description": "Engineering discipline layer for Claude Code — 5 workflows,
|
|
3
|
+
"version": "1.11.0",
|
|
4
|
+
"description": "Engineering discipline layer for Claude Code — 5 workflows, 69 commands, 21 rules, 29 skills, 9 agents organized in 12 packs",
|
|
5
5
|
"author": {
|
|
6
6
|
"name": "Khoa Tran",
|
|
7
7
|
"url": "https://github.com/spartan-stratos"
|
package/README.md
CHANGED
|
@@ -51,6 +51,20 @@ After install, open any project, run `claude`, then type `/spartan`.
|
|
|
51
51
|
|
|
52
52
|
---
|
|
53
53
|
|
|
54
|
+
## Demo: Web-to-PRD
|
|
55
|
+
|
|
56
|
+
Scan a live web app, extract every feature, generate a structured PRD with epics and stories, then export to Notion.
|
|
57
|
+
|
|
58
|
+
```
|
|
59
|
+
/spartan:web-to-prd "https://screensdesign.com"
|
|
60
|
+
```
|
|
61
|
+
|
|
62
|
+

|
|
63
|
+
|
|
64
|
+
Uses Playwright MCP (browser control) + Notion MCP (export). Auto-installs prerequisites, handles login, and asks for confirmation at each step.
|
|
65
|
+
|
|
66
|
+
---
|
|
67
|
+
|
|
54
68
|
## How to Use
|
|
55
69
|
|
|
56
70
|
### The core workflow
|
|
@@ -229,6 +243,7 @@ Type `/spartan` to get the smart router — it asks what you need and picks the
|
|
|
229
243
|
| `interview` | Mom Test interview questions |
|
|
230
244
|
| `lean-canvas` | Fill out a 9-block Lean Canvas |
|
|
231
245
|
| `brainstorm` | Generate and rank ideas |
|
|
246
|
+
| `web-to-prd "URL"` | Scan a live web app with Playwright, extract features, generate PRD with epics/stories, export to Notion |
|
|
232
247
|
|
|
233
248
|
### Infrastructure (infrastructure pack)
|
|
234
249
|
| Command | What it does |
|
|
@@ -293,6 +308,7 @@ Skills give Claude deeper knowledge in specific areas. They're loaded automatica
|
|
|
293
308
|
| `article-writing` | research | Long-form content creation |
|
|
294
309
|
| `content-engine` | research | Content strategy and production |
|
|
295
310
|
| `startup-pipeline` | research | Full startup research pipeline |
|
|
311
|
+
| `web-to-prd` | product | Scan web apps, extract features, generate PRD, export to Notion |
|
|
296
312
|
|
|
297
313
|
---
|
|
298
314
|
|
package/VERSION
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
1.
|
|
1
|
+
1.11.0
|
package/claude-md/40-product.md
CHANGED
|
@@ -36,3 +36,4 @@ You don't have to use all of them. Pick what fits your stage.
|
|
|
36
36
|
| `/spartan:interview "product"` | Generate Mom Test interview script (talk about their life, not your idea) |
|
|
37
37
|
| `/spartan:lean-canvas "product"` | Fill out 9-block Lean Canvas interactively |
|
|
38
38
|
| `/spartan:brainstorm "theme"` | Generate 8-15 ideas → filter → rank top 3 |
|
|
39
|
+
| `/spartan:web-to-prd "URL"` | Scan a live web app → extract features → generate PRD/epics/stories → export to Notion. Needs Playwright MCP + Notion MCP. |
|
|
@@ -64,21 +64,19 @@ _PROJECT=$(basename "$(git rev-parse --show-toplevel 2>/dev/null)" 2>/dev/null |
|
|
|
64
64
|
echo "SESSIONS: $_SESSIONS"
|
|
65
65
|
echo "BRANCH: $_BRANCH"
|
|
66
66
|
echo "PROJECT: $_PROJECT"
|
|
67
|
+
cat .spartan/build.yaml 2>/dev/null || true
|
|
68
|
+
cat .spartan/commands.yaml 2>/dev/null || true
|
|
67
69
|
```
|
|
68
70
|
|
|
69
71
|
**Read the output.** If `SESSIONS` >= 3, start EVERY response with: **[PROJECT / BRANCH]** Currently working on: [task]
|
|
70
72
|
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
## Load Build Config (silent — no questions)
|
|
73
|
+
If `.spartan/commands.yaml` has a `prompts.build` entry, apply those custom instructions alongside the built-in ones.
|
|
74
74
|
|
|
75
|
-
|
|
75
|
+
---
|
|
76
76
|
|
|
77
|
-
|
|
78
|
-
cat .spartan/build.yaml 2>/dev/null || cat .spartan/build.yml 2>/dev/null
|
|
79
|
-
```
|
|
77
|
+
## Build Config Fields
|
|
80
78
|
|
|
81
|
-
If `.spartan/build.yaml`
|
|
79
|
+
If the preamble output includes `.spartan/build.yaml` content, apply these overrides. All fields are optional.
|
|
82
80
|
|
|
83
81
|
| Field | Default | What it does |
|
|
84
82
|
|-------|---------|-------------|
|
|
@@ -0,0 +1,544 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: spartan:web-to-prd
|
|
3
|
+
description: Scan a live web app, extract all features, generate PRD with epics/stories/tasks, export to Notion
|
|
4
|
+
argument-hint: "[URL of the web app to scan]"
|
|
5
|
+
preamble-tier: 3
|
|
6
|
+
---
|
|
7
|
+
|
|
8
|
+
# Web-to-PRD: {{ args[0] | default: "https://example.com" }}
|
|
9
|
+
|
|
10
|
+
You are the **Web-to-PRD pipeline** — scan a live web app, extract every feature, create PM artifacts, and push to Notion.
|
|
11
|
+
|
|
12
|
+
**Target URL:** {{ args[0] | default: "https://example.com" }}
|
|
13
|
+
|
|
14
|
+
---
|
|
15
|
+
|
|
16
|
+
## Step 0: Prerequisite Check
|
|
17
|
+
|
|
18
|
+
**This step is mandatory. Do NOT skip it. Do NOT proceed until all checks pass.**
|
|
19
|
+
|
|
20
|
+
**You (Claude) handle the setup. Don't ask the user to run install commands — do it yourself.**
|
|
21
|
+
|
|
22
|
+
### Check 1: Playwright MCP
|
|
23
|
+
|
|
24
|
+
Two checks: (A) is it installed? (B) is it using the Chrome profile?
|
|
25
|
+
|
|
26
|
+
**Step A: Check if Playwright MCP is installed**
|
|
27
|
+
|
|
28
|
+
Try to use any Playwright MCP tool (like `browser_snapshot` or `browser_navigate`).
|
|
29
|
+
|
|
30
|
+
If tool not found → go to **Auto-Install** below.
|
|
31
|
+
If tool found → go to **Step B**.
|
|
32
|
+
|
|
33
|
+
**Step B: Check if it's configured properly**
|
|
34
|
+
|
|
35
|
+
Read the MCP config:
|
|
36
|
+
|
|
37
|
+
```bash
|
|
38
|
+
cat ~/.claude.json 2>/dev/null | grep -A5 playwright || \
|
|
39
|
+
cat .claude.json 2>/dev/null | grep -A5 playwright || \
|
|
40
|
+
echo "NO_CONFIG_FOUND"
|
|
41
|
+
```
|
|
42
|
+
|
|
43
|
+
| What you see in config | Status | Action |
|
|
44
|
+
|------------------------|--------|--------|
|
|
45
|
+
| `--user-data-dir` with `.playwright-profile` | Good (default) | Proceed |
|
|
46
|
+
| `--user-data-dir` pointing to real Chrome profile | Risky — extensions cause timeouts | Ask: "Your Playwright uses the real Chrome profile. Extensions can slow it down. Switch to a clean profile?" If yes → **Auto-Install** |
|
|
47
|
+
| No `--user-data-dir` (clean mode) | OK for public sites | If site needs login → ask: "Want me to set up a persistent profile so logins are saved?" |
|
|
48
|
+
| `--cdp-endpoint` | Advanced mode | OK — proceed |
|
|
49
|
+
|
|
50
|
+
**Auto-Install (handles both fresh install and reconfigure):**
|
|
51
|
+
|
|
52
|
+
```bash
|
|
53
|
+
# Remove old config
|
|
54
|
+
claude mcp remove playwright 2>/dev/null || true
|
|
55
|
+
|
|
56
|
+
# Add with persistent separate profile (no extensions, fast, Chrome stays open)
|
|
57
|
+
claude mcp add playwright -- npx @playwright/mcp@latest --user-data-dir="$HOME/.playwright-profile" --browser=chrome
|
|
58
|
+
```
|
|
59
|
+
|
|
60
|
+
After install, tell the user:
|
|
61
|
+
|
|
62
|
+
> "Playwright MCP is ready. It uses a separate lightweight profile (no extensions, fast).
|
|
63
|
+
>
|
|
64
|
+
> For public sites: ready to go.
|
|
65
|
+
> For login-protected sites: first run will open a browser — log in there. Your login is saved for next time."
|
|
66
|
+
|
|
67
|
+
**No need to close Chrome.** Separate profile = no conflict with your running Chrome.
|
|
68
|
+
|
|
69
|
+
**If the install command fails**, fall back to clean session:
|
|
70
|
+
```bash
|
|
71
|
+
claude mcp remove playwright 2>/dev/null || true
|
|
72
|
+
claude mcp add playwright -- npx @playwright/mcp@latest
|
|
73
|
+
```
|
|
74
|
+
Tell user: "Installed Playwright without persistent profile. Login-protected sites won't save logins between runs."
|
|
75
|
+
|
|
76
|
+
**Why NOT use the real Chrome profile:**
|
|
77
|
+
- Loads ALL extensions (AdBlock, LastPass, etc.) → timeouts, hangs
|
|
78
|
+
- Requires closing Chrome first (profile lock)
|
|
79
|
+
- Stale `SingletonLock` files cause infinite hangs after Chrome crash
|
|
80
|
+
- A lightweight separate profile is faster and more reliable
|
|
81
|
+
|
|
82
|
+
### Check 2: Notion MCP
|
|
83
|
+
|
|
84
|
+
Try to call `notion-search` with query "test".
|
|
85
|
+
|
|
86
|
+
**If tool not found:**
|
|
87
|
+
|
|
88
|
+
```
|
|
89
|
+
Notion MCP is not connected.
|
|
90
|
+
|
|
91
|
+
To connect:
|
|
92
|
+
1. Go to Claude Code settings (or Claude Desktop > Settings)
|
|
93
|
+
2. Find "Integrations" or "MCP Servers"
|
|
94
|
+
3. Enable "Notion" and authorize your workspace
|
|
95
|
+
|
|
96
|
+
Alternative: Install via CLI:
|
|
97
|
+
claude mcp add notion -- npx @anthropic-ai/mcp-notion
|
|
98
|
+
|
|
99
|
+
Then restart Claude Code and re-run:
|
|
100
|
+
|
|
101
|
+
/spartan:web-to-prd {{ args[0] | default: "URL" }}
|
|
102
|
+
```
|
|
103
|
+
|
|
104
|
+
**STOP here. Do not continue.**
|
|
105
|
+
|
|
106
|
+
**If auth error (needs re-authentication):**
|
|
107
|
+
|
|
108
|
+
```
|
|
109
|
+
Notion MCP needs re-authentication.
|
|
110
|
+
|
|
111
|
+
Open Claude Code settings and re-authorize Notion access to your workspace.
|
|
112
|
+
```
|
|
113
|
+
|
|
114
|
+
**STOP here.**
|
|
115
|
+
|
|
116
|
+
### Check 3: Confirm both are working
|
|
117
|
+
|
|
118
|
+
Show status:
|
|
119
|
+
|
|
120
|
+
```
|
|
121
|
+
Prerequisite Check:
|
|
122
|
+
Playwright MCP: [connected / not found]
|
|
123
|
+
Notion MCP: [connected / not found / needs auth]
|
|
124
|
+
|
|
125
|
+
[If both connected]: Ready to scan. Proceeding...
|
|
126
|
+
[If any missing]: Fix the issues above and re-run.
|
|
127
|
+
```
|
|
128
|
+
|
|
129
|
+
**Only proceed to Step 1 if BOTH are connected.**
|
|
130
|
+
|
|
131
|
+
---
|
|
132
|
+
|
|
133
|
+
## Step 1: Navigate and Handle Login
|
|
134
|
+
|
|
135
|
+
**This step ensures we're fully logged in before exploring anything.**
|
|
136
|
+
|
|
137
|
+
### 1-pre. Clean up stale browser processes (MANDATORY before first navigate)
|
|
138
|
+
|
|
139
|
+
Playwright MCP leaves orphan Chrome processes from previous runs. These cause "Opening in existing browser session" errors. **Always run this before the first `browser_navigate` call:**
|
|
140
|
+
|
|
141
|
+
```bash
|
|
142
|
+
# Remove stale lock files (safe — doesn't kill any processes)
|
|
143
|
+
rm -f "$HOME/.playwright-profile/SingletonLock" \
|
|
144
|
+
"$HOME/.playwright-profile/SingletonCookie" \
|
|
145
|
+
"$HOME/.playwright-profile/SingletonSocket" 2>/dev/null
|
|
146
|
+
|
|
147
|
+
echo "Browser cleanup done"
|
|
148
|
+
```
|
|
149
|
+
|
|
150
|
+
**WARNING:** Do NOT run `pkill -f "playwright-profile"` — it kills the Playwright MCP server process too, disconnecting the tools mid-session. Only remove lock files.
|
|
151
|
+
|
|
152
|
+
**If `browser_navigate` still fails with "Opening in existing browser session":**
|
|
153
|
+
1. Run the cleanup again
|
|
154
|
+
2. Wait 2 seconds
|
|
155
|
+
3. Retry once
|
|
156
|
+
4. If still fails → tell user to restart Claude Code (MCP server needs fresh start)
|
|
157
|
+
|
|
158
|
+
Now navigate to the target URL using Playwright. Take a snapshot.
|
|
159
|
+
|
|
160
|
+
### 1a. Check if login is needed
|
|
161
|
+
|
|
162
|
+
Look at the snapshot for login signals:
|
|
163
|
+
- Login/Sign-in form fields (email, password)
|
|
164
|
+
- "Sign in", "Log in", "Create account" text
|
|
165
|
+
- OAuth buttons (Google, GitHub, SSO)
|
|
166
|
+
- URL contains `/login`, `/signin`, `/auth`
|
|
167
|
+
- Redirect to a different domain (auth provider)
|
|
168
|
+
|
|
169
|
+
### 1b. If login page detected — STOP and handle login
|
|
170
|
+
|
|
171
|
+
Playwright opens a **visible browser window** (headed mode). The user can see and interact with it.
|
|
172
|
+
|
|
173
|
+
Tell the user:
|
|
174
|
+
|
|
175
|
+
> "This app needs login before I can see all the features.
|
|
176
|
+
> A Chrome window should be open on your screen.
|
|
177
|
+
>
|
|
178
|
+
> Please log in directly in that browser window.
|
|
179
|
+
> I won't see or store your credentials.
|
|
180
|
+
>
|
|
181
|
+
> Tell me when you're logged in."
|
|
182
|
+
|
|
183
|
+
**Wait for user confirmation.** Do NOT proceed until they say "done", "logged in", or similar.
|
|
184
|
+
|
|
185
|
+
After user confirms:
|
|
186
|
+
1. Take a snapshot of the current page
|
|
187
|
+
2. Check if still on login page → "Still seeing the login page. Try again?"
|
|
188
|
+
3. Check if on dashboard/home/main content → "Logged in. Proceeding."
|
|
189
|
+
4. If unclear → ask user: "I see [page title]. Is this the main page after login?"
|
|
190
|
+
|
|
191
|
+
**Repeat until login is confirmed.** Do NOT start crawling while on a login page.
|
|
192
|
+
|
|
193
|
+
**Login security rules:**
|
|
194
|
+
- Never use `browser_type` to enter passwords — user types directly in browser
|
|
195
|
+
- Never ask for credentials in chat
|
|
196
|
+
- Never screenshot login pages (could capture pre-filled credentials)
|
|
197
|
+
- SSO/OAuth popups work normally — wait for user to complete
|
|
198
|
+
|
|
199
|
+
### 1c. If NOT a login page — proceed directly
|
|
200
|
+
|
|
201
|
+
The site is public or already logged in (cookies from previous session).
|
|
202
|
+
|
|
203
|
+
### 1d. Verify access level
|
|
204
|
+
|
|
205
|
+
After login (or on public site), check what's visible:
|
|
206
|
+
|
|
207
|
+
> "I can see [dashboard/home page]. I see these navigation sections:
|
|
208
|
+
> 1. [Section name]
|
|
209
|
+
> 2. [Section name]
|
|
210
|
+
> ...
|
|
211
|
+
>
|
|
212
|
+
> Does this look like full access? Or are there sections I'm missing?
|
|
213
|
+
> (Some apps hide admin/settings pages behind roles)"
|
|
214
|
+
|
|
215
|
+
**Wait for user to confirm** before starting the full crawl. This prevents generating a PRD from a limited view.
|
|
216
|
+
|
|
217
|
+
### 1e. Show crawl plan
|
|
218
|
+
|
|
219
|
+
```
|
|
220
|
+
Crawl Plan: [App Name]
|
|
221
|
+
URL: [target URL]
|
|
222
|
+
Type: [SPA / Multi-page / Hybrid]
|
|
223
|
+
Auth: [Logged in / Public]
|
|
224
|
+
Estimated pages: ~[N]
|
|
225
|
+
Estimated time: [N] minutes
|
|
226
|
+
|
|
227
|
+
Sections to explore:
|
|
228
|
+
1. [Section name] — [N sub-items]
|
|
229
|
+
2. [Section name] — [N sub-items]
|
|
230
|
+
...
|
|
231
|
+
|
|
232
|
+
Proceed? [Y/n]
|
|
233
|
+
```
|
|
234
|
+
|
|
235
|
+
---
|
|
236
|
+
|
|
237
|
+
## Step 2: Crawl and Extract
|
|
238
|
+
|
|
239
|
+
**Only start this step after login is confirmed and crawl plan is approved.**
|
|
240
|
+
|
|
241
|
+
Navigate through each section systematically:
|
|
242
|
+
|
|
243
|
+
1. **Visit each page** from the navigation
|
|
244
|
+
2. **Take a snapshot** (accessibility tree) of each page
|
|
245
|
+
3. **Click into sub-pages** — tabs, accordions, detail views
|
|
246
|
+
4. **Note interactive elements** — forms, buttons, modals, filters
|
|
247
|
+
5. **Don't click destructive actions** — skip Delete, Remove, etc.
|
|
248
|
+
6. **Add 1-2 second delay** between navigations
|
|
249
|
+
7. **If session expires mid-crawl** (redirected to login) → STOP, tell user to re-login in the browser, wait, then continue
|
|
250
|
+
|
|
251
|
+
### Progress updates
|
|
252
|
+
|
|
253
|
+
After every 10 pages or every major section:
|
|
254
|
+
|
|
255
|
+
> "Progress: Scanned [N] pages. Found [N] feature areas so far.
|
|
256
|
+
> Latest section: [section name]
|
|
257
|
+
> Continue? [Y/n]"
|
|
258
|
+
|
|
259
|
+
### What to capture per page
|
|
260
|
+
|
|
261
|
+
For each page, record:
|
|
262
|
+
- URL and page title
|
|
263
|
+
- Page type (dashboard, list, detail, form, settings, etc.)
|
|
264
|
+
- Features visible on the page
|
|
265
|
+
- Form fields and their types
|
|
266
|
+
- Action buttons and what they do
|
|
267
|
+
- Data displayed (tables, charts, cards)
|
|
268
|
+
- Navigation elements (tabs, breadcrumbs, sidebar items)
|
|
269
|
+
|
|
270
|
+
### Build the feature map
|
|
271
|
+
|
|
272
|
+
As you crawl, build a structured feature map:
|
|
273
|
+
|
|
274
|
+
```yaml
|
|
275
|
+
app:
|
|
276
|
+
name: "[detected app name]"
|
|
277
|
+
url: "[target URL]"
|
|
278
|
+
sections:
|
|
279
|
+
- name: "[Section from nav]"
|
|
280
|
+
pages:
|
|
281
|
+
- url: "/path"
|
|
282
|
+
title: "Page Title"
|
|
283
|
+
type: "list"
|
|
284
|
+
features:
|
|
285
|
+
- name: "Feature name"
|
|
286
|
+
type: "data-display | form | action | filter | notification"
|
|
287
|
+
description: "What it does"
|
|
288
|
+
ui_elements: ["table", "search bar", "export button"]
|
|
289
|
+
```
|
|
290
|
+
|
|
291
|
+
---
|
|
292
|
+
|
|
293
|
+
## Step 3: Organize and Prioritize
|
|
294
|
+
|
|
295
|
+
After crawling is done, organize the raw features:
|
|
296
|
+
|
|
297
|
+
### 3a. Group into Epics
|
|
298
|
+
|
|
299
|
+
Group features by:
|
|
300
|
+
1. Navigation sections (natural grouping)
|
|
301
|
+
2. User goals (what the user is trying to do)
|
|
302
|
+
3. Data domain (features that touch the same data)
|
|
303
|
+
|
|
304
|
+
### 3b. Write User Stories
|
|
305
|
+
|
|
306
|
+
For each feature, write a story:
|
|
307
|
+
> As a [user type], I can [action] so that [benefit]
|
|
308
|
+
|
|
309
|
+
Add acceptance criteria (2-4 per story).
|
|
310
|
+
|
|
311
|
+
### 3c. Assign Priorities
|
|
312
|
+
|
|
313
|
+
| Priority | Rule |
|
|
314
|
+
|----------|------|
|
|
315
|
+
| P0 | Core flow — app is broken without it |
|
|
316
|
+
| P1 | Important — app is usable but limited without it |
|
|
317
|
+
| P2 | Nice to have — enhancement, polish |
|
|
318
|
+
| P3 | Future — advanced, not needed now |
|
|
319
|
+
|
|
320
|
+
### 3d. Map Dependencies
|
|
321
|
+
|
|
322
|
+
Figure out build order:
|
|
323
|
+
- Auth always comes first
|
|
324
|
+
- CRUD: Create → Read/List → Update → Delete
|
|
325
|
+
- Data display depends on data input
|
|
326
|
+
- Settings depend on the feature they configure
|
|
327
|
+
|
|
328
|
+
### 3e. Show summary and confirm
|
|
329
|
+
|
|
330
|
+
> "Here's what I found:
|
|
331
|
+
>
|
|
332
|
+
> **App:** [name]
|
|
333
|
+
> **Pages scanned:** [N]
|
|
334
|
+
> **Epics:** [N]
|
|
335
|
+
> **Stories:** [N]
|
|
336
|
+
> **Tasks:** [N]
|
|
337
|
+
>
|
|
338
|
+
> **Build order:**
|
|
339
|
+
> Phase 1: [Epic A, Epic B] — no dependencies
|
|
340
|
+
> Phase 2: [Epic C] — depends on Phase 1
|
|
341
|
+
> Phase 3: [Epic D, Epic E] — depends on Phase 2
|
|
342
|
+
>
|
|
343
|
+
> Anything look wrong or missing before I generate the PRD?"
|
|
344
|
+
|
|
345
|
+
---
|
|
346
|
+
|
|
347
|
+
## Step 4: Generate PRD
|
|
348
|
+
|
|
349
|
+
Generate a full PRD document with this structure:
|
|
350
|
+
|
|
351
|
+
```markdown
|
|
352
|
+
# PRD: [App Name]
|
|
353
|
+
|
|
354
|
+
## 1. TL;DR
|
|
355
|
+
|
|
356
|
+
[1-2 sentences: what this app does, who it's for, what problem it solves, what makes it different.]
|
|
357
|
+
|
|
358
|
+
## 2. Goals
|
|
359
|
+
|
|
360
|
+
### Business Goals
|
|
361
|
+
- [What this app is trying to achieve as a business]
|
|
362
|
+
- [Revenue model, growth metrics observed]
|
|
363
|
+
|
|
364
|
+
### User Goals
|
|
365
|
+
- [What users can do with this app]
|
|
366
|
+
- [What pain it solves]
|
|
367
|
+
|
|
368
|
+
### Non-Goals
|
|
369
|
+
- [Things this app intentionally doesn't do]
|
|
370
|
+
- [Adjacent features it could have but chose not to]
|
|
371
|
+
|
|
372
|
+
## 3. User Stories
|
|
373
|
+
|
|
374
|
+
[Grouped by persona/role detected in the app:]
|
|
375
|
+
|
|
376
|
+
- As a [user type], I want to [action], so that [benefit]
|
|
377
|
+
- As a [admin/manager], I want to [action], so that [benefit]
|
|
378
|
+
|
|
379
|
+
## 4. Functional Requirements
|
|
380
|
+
|
|
381
|
+
[Grouped by Epic, with priority. This is the main section.]
|
|
382
|
+
|
|
383
|
+
### Epic 1: [Name] — Priority: P0 — Phase: 1
|
|
384
|
+
**Dependencies:** none
|
|
385
|
+
**Pages:** [URLs in this area]
|
|
386
|
+
|
|
387
|
+
| # | Requirement | Priority | Story |
|
|
388
|
+
|---|-------------|----------|-------|
|
|
389
|
+
| 1.1 | [Specific feature/capability] | P0 | As a user, I can... |
|
|
390
|
+
| 1.2 | [Specific feature/capability] | P0 | As a user, I can... |
|
|
391
|
+
| 1.3 | [Specific feature/capability] | P1 | As a user, I can... |
|
|
392
|
+
|
|
393
|
+
**Acceptance Criteria:**
|
|
394
|
+
- [ ] [Testable criterion for 1.1]
|
|
395
|
+
- [ ] [Testable criterion for 1.2]
|
|
396
|
+
|
|
397
|
+
### Epic 2: [Name] — Priority: P1 — Phase: 2
|
|
398
|
+
**Dependencies:** Epic 1
|
|
399
|
+
...
|
|
400
|
+
|
|
401
|
+
[Repeat for all epics]
|
|
402
|
+
|
|
403
|
+
## 5. User Experience
|
|
404
|
+
|
|
405
|
+
### Entry Points
|
|
406
|
+
- [How users get into the app]
|
|
407
|
+
- [Main navigation structure]
|
|
408
|
+
|
|
409
|
+
### Key Flows
|
|
410
|
+
1. [Flow name]: [step-by-step from entry to completion]
|
|
411
|
+
2. [Flow name]: [step-by-step]
|
|
412
|
+
|
|
413
|
+
### Edge Cases
|
|
414
|
+
- [What happens when X fails]
|
|
415
|
+
- [Empty states observed]
|
|
416
|
+
|
|
417
|
+
### Design Notes
|
|
418
|
+
- [UI patterns used: sidebar, tabs, cards, etc.]
|
|
419
|
+
- [Responsive behavior observed]
|
|
420
|
+
|
|
421
|
+
## 6. Narrative
|
|
422
|
+
|
|
423
|
+
[200 words: a story from the user's point of view.
|
|
424
|
+
Walk through a typical session using the app.
|
|
425
|
+
Makes the PRD feel real, not abstract.]
|
|
426
|
+
|
|
427
|
+
## 7. Build Roadmap
|
|
428
|
+
|
|
429
|
+
[This is the actionable section. Shows exactly what to build first.]
|
|
430
|
+
|
|
431
|
+
### Phase 1: Foundation (no dependencies)
|
|
432
|
+
| Epic | Priority | Stories | Est. complexity |
|
|
433
|
+
|------|----------|---------|-----------------|
|
|
434
|
+
| [Epic A] | P0 | [N] | [Simple/Medium/Complex] |
|
|
435
|
+
| [Epic B] | P0 | [N] | [Simple/Medium/Complex] |
|
|
436
|
+
|
|
437
|
+
### Phase 2: Core Features (depends on Phase 1)
|
|
438
|
+
| Epic | Priority | Stories | Est. complexity |
|
|
439
|
+
|------|----------|---------|-----------------|
|
|
440
|
+
| [Epic C] | P0 | [N] | [Medium/Complex] |
|
|
441
|
+
|
|
442
|
+
### Phase 3: Enhancement (depends on Phase 2)
|
|
443
|
+
...
|
|
444
|
+
|
|
445
|
+
### Dependency Graph
|
|
446
|
+
[Text diagram showing which epics depend on which]
|
|
447
|
+
|
|
448
|
+
## 8. Open Questions
|
|
449
|
+
- [Things that couldn't be determined from the UI]
|
|
450
|
+
- [Decisions that need product input]
|
|
451
|
+
- [Areas where the app behavior was unclear]
|
|
452
|
+
```
|
|
453
|
+
|
|
454
|
+
**Save locally first:**
|
|
455
|
+
```
|
|
456
|
+
.planning/web-to-prd/
|
|
457
|
+
prd-[app-name].md
|
|
458
|
+
```
|
|
459
|
+
|
|
460
|
+
---
|
|
461
|
+
|
|
462
|
+
## Step 5: Export to Notion
|
|
463
|
+
|
|
464
|
+
Ask the user:
|
|
465
|
+
|
|
466
|
+
> "Where should I create the backlog in Notion?
|
|
467
|
+
>
|
|
468
|
+
> A) New page in workspace root
|
|
469
|
+
> B) Under an existing page (I'll search for it)
|
|
470
|
+
> C) Skip Notion — just keep the local PRD file"
|
|
471
|
+
|
|
472
|
+
### If A or B: Create Notion structure
|
|
473
|
+
|
|
474
|
+
1. **Create parent page** — "[App Name] — Product Backlog" with PRD content
|
|
475
|
+
2. **Create Epics database** with columns:
|
|
476
|
+
- Name (title)
|
|
477
|
+
- Priority (select: P0, P1, P2, P3)
|
|
478
|
+
- Status (select: Not Started, In Progress, Done)
|
|
479
|
+
- Phase (number)
|
|
480
|
+
- Description (rich text)
|
|
481
|
+
3. **Create Stories database** with columns:
|
|
482
|
+
- Name (title)
|
|
483
|
+
- Epic (relation to Epics)
|
|
484
|
+
- Priority (select: P0, P1, P2, P3)
|
|
485
|
+
- Status (select: Backlog, Ready, In Progress, Review, Done)
|
|
486
|
+
- User Story (rich text)
|
|
487
|
+
- Acceptance Criteria (rich text)
|
|
488
|
+
4. **Create Tasks database** with columns:
|
|
489
|
+
- Name (title)
|
|
490
|
+
- Story (relation to Stories)
|
|
491
|
+
- Status (select: To Do, In Progress, Done)
|
|
492
|
+
- Type (select: Frontend, Backend, Design, DevOps, QA)
|
|
493
|
+
5. **Populate all databases** with the extracted data
|
|
494
|
+
6. **Create views:**
|
|
495
|
+
- Kanban by Status (for Stories)
|
|
496
|
+
- Table grouped by Epic (for Stories)
|
|
497
|
+
|
|
498
|
+
### If C: Local only
|
|
499
|
+
|
|
500
|
+
Save to `.planning/web-to-prd/` and done.
|
|
501
|
+
|
|
502
|
+
---
|
|
503
|
+
|
|
504
|
+
## Step 6: Done
|
|
505
|
+
|
|
506
|
+
Show final summary:
|
|
507
|
+
|
|
508
|
+
```
|
|
509
|
+
Web-to-PRD Complete
|
|
510
|
+
|
|
511
|
+
App: [name]
|
|
512
|
+
URL: [url]
|
|
513
|
+
Scanned: [N] pages
|
|
514
|
+
|
|
515
|
+
Generated:
|
|
516
|
+
- [N] Epics
|
|
517
|
+
- [N] Stories
|
|
518
|
+
- [N] Tasks
|
|
519
|
+
- [N] Phases (build order)
|
|
520
|
+
|
|
521
|
+
Saved to:
|
|
522
|
+
- Local: .planning/web-to-prd/prd-[app-name].md
|
|
523
|
+
- Notion: [page URL if exported]
|
|
524
|
+
|
|
525
|
+
Next steps:
|
|
526
|
+
- Review the PRD and adjust priorities
|
|
527
|
+
- Use /spartan:spec to detail individual features
|
|
528
|
+
- Use /spartan:plan to plan implementation for each epic
|
|
529
|
+
```
|
|
530
|
+
|
|
531
|
+
---
|
|
532
|
+
|
|
533
|
+
## Rules
|
|
534
|
+
|
|
535
|
+
1. **Prerequisites are non-negotiable.** Always check Playwright and Notion MCP first. Don't try to work around missing tools.
|
|
536
|
+
2. **Don't guess features you can't see.** Only document what's visible in the UI.
|
|
537
|
+
3. **Don't click destructive buttons.** No Delete, Remove, Reset, or similar actions during crawl.
|
|
538
|
+
4. **Show progress.** Update the user every 10 pages or every section.
|
|
539
|
+
5. **Local save always happens.** Even if Notion export works, save the PRD locally too.
|
|
540
|
+
6. **Ask before login.** Never assume credentials. Let the user handle auth manually.
|
|
541
|
+
7. **One app per run.** Don't follow links to external domains.
|
|
542
|
+
8. **Delay between pages.** 1-2 seconds between navigations. Don't hammer the server.
|
|
543
|
+
9. **Mark assumptions.** If you're guessing what a feature does, say so.
|
|
544
|
+
10. **The PRD is a starting point.** Tell the user to review and adjust — it's not final.
|
package/package.json
CHANGED
|
@@ -281,10 +281,13 @@
|
|
|
281
281
|
"teardown",
|
|
282
282
|
"interview",
|
|
283
283
|
"lean-canvas",
|
|
284
|
-
"brainstorm"
|
|
284
|
+
"brainstorm",
|
|
285
|
+
"web-to-prd"
|
|
285
286
|
],
|
|
286
287
|
"rules": [],
|
|
287
|
-
"skills": [
|
|
288
|
+
"skills": [
|
|
289
|
+
"web-to-prd"
|
|
290
|
+
],
|
|
288
291
|
"agents": [],
|
|
289
292
|
"claudeSections": [
|
|
290
293
|
"40-product.md"
|
package/packs/product.yaml
CHANGED
|
@@ -0,0 +1,436 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: web-to-prd
|
|
3
|
+
description: "Scan a live web app with Playwright, extract all features, generate PRD/epics/stories with priorities and dependencies, export to Notion. Checks required MCP servers before starting."
|
|
4
|
+
allowed_tools:
|
|
5
|
+
- Read
|
|
6
|
+
- Write
|
|
7
|
+
- Bash
|
|
8
|
+
- Glob
|
|
9
|
+
- Grep
|
|
10
|
+
- WebSearch
|
|
11
|
+
---
|
|
12
|
+
|
|
13
|
+
# Web-to-PRD Skill
|
|
14
|
+
|
|
15
|
+
Scan a live web app. Extract every feature. Turn it into a structured PRD with epics, stories, and tasks. Push it all to Notion.
|
|
16
|
+
|
|
17
|
+
## When to Use
|
|
18
|
+
|
|
19
|
+
- Reverse-engineer a competitor's product
|
|
20
|
+
- Document an existing app you're taking over
|
|
21
|
+
- Create a PRD from a live product (yours or someone else's)
|
|
22
|
+
- Build a feature backlog from scratch by looking at what's already built
|
|
23
|
+
|
|
24
|
+
## What This Skill Does
|
|
25
|
+
|
|
26
|
+
1. **Checks prerequisites** — makes sure Playwright MCP and Notion MCP are connected
|
|
27
|
+
2. **Crawls the web app** — navigates page by page, reads UI elements
|
|
28
|
+
3. **Extracts features** — groups what it finds into feature areas
|
|
29
|
+
4. **Generates PM artifacts** — PRD, epics, stories, tasks with priorities and dependencies
|
|
30
|
+
5. **Exports to Notion** — creates linked databases, populates everything
|
|
31
|
+
|
|
32
|
+
## Prerequisites
|
|
33
|
+
|
|
34
|
+
This skill needs 2 MCP servers. The command checks both before starting.
|
|
35
|
+
|
|
36
|
+
### 1. Playwright MCP (browser control)
|
|
37
|
+
|
|
38
|
+
Claude uses Playwright to open a real browser, navigate pages, and read content.
|
|
39
|
+
|
|
40
|
+
#### Browser modes
|
|
41
|
+
|
|
42
|
+
| Mode | Install command | What it does |
|
|
43
|
+
|------|----------------|-------------|
|
|
44
|
+
| **Persistent profile (default)** | See setup below | Lightweight profile at `~/.playwright-profile`. Login once, remembered. Chrome stays open. No extensions bloat. |
|
|
45
|
+
| CDP (advanced) | `--cdp-endpoint='http://localhost:9222'` | Connects to running Chrome. Has your logins but also loads all extensions (can be slow). |
|
|
46
|
+
| Chrome profile (heavy) | `--user-data-dir="[Chrome path]" --browser=chrome` | Uses real Chrome profile. Has logins but loads ALL extensions — often causes timeouts. Not recommended. |
|
|
47
|
+
| Clean session | no extra flags | Fresh browser each time. No saved state. Public sites only. |
|
|
48
|
+
|
|
49
|
+
#### Default setup: Persistent profile (auto-installed by the command)
|
|
50
|
+
|
|
51
|
+
The `/spartan:web-to-prd` command handles installation itself. Uses a lightweight separate profile at `~/.playwright-profile` — no extensions, no bloat, fast startup.
|
|
52
|
+
|
|
53
|
+
**What the command does internally:**
|
|
54
|
+
```bash
|
|
55
|
+
claude mcp remove playwright 2>/dev/null || true
|
|
56
|
+
claude mcp add playwright -- npx @playwright/mcp@latest --user-data-dir="$HOME/.playwright-profile" --browser=chrome
|
|
57
|
+
```
|
|
58
|
+
|
|
59
|
+
**First run on a login-protected site:** Playwright opens Chrome with a clean profile. User logs in manually. Cookies are saved to `~/.playwright-profile`. Next runs are already logged in.
|
|
60
|
+
|
|
61
|
+
**Why not the real Chrome profile?** Real Chrome profiles load ALL extensions (AdBlock, LastPass, password managers, etc.). These add latency, block requests, and often cause Playwright to timeout or hang. A separate profile is faster and more reliable.
|
|
62
|
+
|
|
63
|
+
**Chrome can stay open.** Since we use a separate profile, there's no conflict.
|
|
64
|
+
|
|
65
|
+
#### Switching modes
|
|
66
|
+
|
|
67
|
+
To change mode, remove and re-add:
|
|
68
|
+
```bash
|
|
69
|
+
claude mcp remove playwright
|
|
70
|
+
claude mcp add playwright -- npx @playwright/mcp@latest [flags]
|
|
71
|
+
```
|
|
72
|
+
|
|
73
|
+
#### All Playwright MCP flags
|
|
74
|
+
|
|
75
|
+
| Flag | What it does |
|
|
76
|
+
|------|-------------|
|
|
77
|
+
| `--cdp-endpoint="http://localhost:9222"` | Connect to running Chrome via CDP |
|
|
78
|
+
| `--user-data-dir="/path"` | Persistent browser profile (keeps cookies) |
|
|
79
|
+
| `--storage-state="/path/to/state.json"` | Load saved cookies from file |
|
|
80
|
+
| `--isolated` | Fresh session, no persistent data |
|
|
81
|
+
| `--browser=chrome` | Use real Chrome instead of Chromium |
|
|
82
|
+
| `--headless` | No visible browser window |
|
|
83
|
+
|
|
84
|
+
All flags also work as env vars with `PLAYWRIGHT_MCP_` prefix (e.g., `PLAYWRIGHT_MCP_CDP_ENDPOINT`).
|
|
85
|
+
|
|
86
|
+
**How to verify Playwright MCP is installed:**
|
|
87
|
+
```bash
|
|
88
|
+
claude mcp list | grep -i playwright
|
|
89
|
+
```
|
|
90
|
+
|
|
91
|
+
**What it gives you:** `browser_navigate`, `browser_click`, `browser_snapshot`, `browser_type`, `browser_tab_list` and more.
|
|
92
|
+
|
|
93
|
+
### 2. Notion MCP (export destination)
|
|
94
|
+
|
|
95
|
+
Claude uses Notion MCP to create databases, pages, and views in your workspace.
|
|
96
|
+
|
|
97
|
+
**How to install:**
|
|
98
|
+
The Notion MCP is available as a Claude.ai integration. Enable it from:
|
|
99
|
+
- Claude Code settings > MCP servers
|
|
100
|
+
- Or Claude Desktop > Settings > Integrations > Notion
|
|
101
|
+
|
|
102
|
+
**How to verify:**
|
|
103
|
+
```bash
|
|
104
|
+
claude mcp list | grep -i notion
|
|
105
|
+
```
|
|
106
|
+
|
|
107
|
+
**What it gives you:** `notion-create-database`, `notion-create-pages`, `notion-create-view`, `notion-search`, `notion-update-page`.
|
|
108
|
+
|
|
109
|
+
### Optional: Firecrawl MCP (faster crawling)
|
|
110
|
+
|
|
111
|
+
If the user has Firecrawl, use it instead of Playwright for the initial crawl. It's faster but costs money.
|
|
112
|
+
|
|
113
|
+
```bash
|
|
114
|
+
claude mcp add firecrawl -- npx firecrawl-mcp
|
|
115
|
+
```
|
|
116
|
+
|
|
117
|
+
Firecrawl is optional. Playwright alone handles everything.
|
|
118
|
+
|
|
119
|
+
---
|
|
120
|
+
|
|
121
|
+
## Prerequisite Check Logic
|
|
122
|
+
|
|
123
|
+
Run this check at the start. **Claude handles installation — don't ask the user to run install commands.**
|
|
124
|
+
|
|
125
|
+
```
|
|
126
|
+
CHECK 1: Playwright MCP
|
|
127
|
+
A) Try calling any Playwright tool (e.g., browser_snapshot)
|
|
128
|
+
If not found → auto-install with Chrome profile (see below)
|
|
129
|
+
|
|
130
|
+
B) If found → check the config (grep .claude.json for playwright args)
|
|
131
|
+
If --user-data-dir points to ~/.playwright-profile → good, proceed
|
|
132
|
+
If --user-data-dir points to real Chrome profile → risky (extensions cause timeouts), ask to switch
|
|
133
|
+
If no --user-data-dir (clean mode) → ask: want persistent profile for saved logins?
|
|
134
|
+
If --cdp-endpoint → good, proceed
|
|
135
|
+
|
|
136
|
+
Auto-install: claude mcp remove + add with --user-data-dir="$HOME/.playwright-profile" --browser=chrome
|
|
137
|
+
|
|
138
|
+
CHECK 2: Notion MCP
|
|
139
|
+
Try calling notion-search with a simple query
|
|
140
|
+
If not found → show instructions (needs manual auth, can't auto-install)
|
|
141
|
+
If auth error → tell user to re-authenticate
|
|
142
|
+
If found → continue
|
|
143
|
+
|
|
144
|
+
BOTH OK → proceed to crawl (no need to close Chrome — separate profile has no conflict)
|
|
145
|
+
```
|
|
146
|
+
|
|
147
|
+
**Notion can't be auto-installed** because it needs the user to authorize their workspace. Show setup instructions and STOP.
|
|
148
|
+
|
|
149
|
+
---
|
|
150
|
+
|
|
151
|
+
## Crawl Strategy
|
|
152
|
+
|
|
153
|
+
### Step 0: Clean up stale browser processes (before every run)
|
|
154
|
+
|
|
155
|
+
Playwright MCP leaves orphan Chrome processes from previous runs. Always clean up before the first `browser_navigate`:
|
|
156
|
+
|
|
157
|
+
```bash
|
|
158
|
+
pkill -f "playwright-profile" 2>/dev/null || true
|
|
159
|
+
rm -f "$HOME/.playwright-profile/SingletonLock" "$HOME/.playwright-profile/SingletonCookie" "$HOME/.playwright-profile/SingletonSocket" 2>/dev/null
|
|
160
|
+
```
|
|
161
|
+
|
|
162
|
+
If navigate still fails with "Opening in existing browser session" → retry once after 2 seconds. If still fails → user needs to restart Claude Code.
|
|
163
|
+
|
|
164
|
+
### Step 1: Login FIRST (mandatory before crawling)
|
|
165
|
+
|
|
166
|
+
**Never start crawling without confirming access. Login is Step 1, not an afterthought.**
|
|
167
|
+
|
|
168
|
+
1. Navigate to the target URL
|
|
169
|
+
2. Take a snapshot — check for login signals (form fields, "Sign in" text, `/login` URL)
|
|
170
|
+
3. **If login page:**
|
|
171
|
+
- STOP. Tell user: "Login page detected. Please log in in the browser window. Tell me when done."
|
|
172
|
+
- Wait for user confirmation
|
|
173
|
+
- Take snapshot to verify — still login page? Ask again. See dashboard? Proceed.
|
|
174
|
+
- **Repeat until logged in.** Do NOT start crawling from a login page.
|
|
175
|
+
4. **If already logged in** (or public site):
|
|
176
|
+
- Show the user what sections are visible
|
|
177
|
+
- Ask: "Does this look like full access? Any sections I'm missing?"
|
|
178
|
+
- Wait for confirmation before crawling
|
|
179
|
+
|
|
180
|
+
**Session expiry during crawl:** If redirected to login mid-crawl → STOP, tell user to re-login in the browser, wait for confirmation, then continue where you left off.
|
|
181
|
+
|
|
182
|
+
**Security rules:**
|
|
183
|
+
- Never use `browser_type` to enter passwords — user types directly in the browser
|
|
184
|
+
- Never ask for credentials in chat
|
|
185
|
+
- Never screenshot login pages
|
|
186
|
+
- SSO/OAuth popups work normally — just wait for user to complete
|
|
187
|
+
|
|
188
|
+
**Cookies:** With persistent profile (`~/.playwright-profile`), logins are saved. Next run on the same site = already logged in.
|
|
189
|
+
|
|
190
|
+
### Step 2: Explore all sections
|
|
191
|
+
|
|
192
|
+
After login is confirmed:
|
|
193
|
+
|
|
194
|
+
1. Read all navigation links (navbar, sidebar, footer)
|
|
195
|
+
2. Visit each link, take snapshot
|
|
196
|
+
3. For each page, look for:
|
|
197
|
+
- Sub-navigation (tabs, accordions, dropdowns)
|
|
198
|
+
- Forms and their fields
|
|
199
|
+
- Data tables and their columns
|
|
200
|
+
- Action buttons (create, edit, delete, export)
|
|
201
|
+
- Modals/dialogs (click non-destructive buttons to discover them)
|
|
202
|
+
- Settings/config pages
|
|
203
|
+
- User/account pages
|
|
204
|
+
- Admin panels (if accessible)
|
|
205
|
+
4. Build a sitemap as you go
|
|
206
|
+
|
|
207
|
+
### For SPAs (single page apps)
|
|
208
|
+
|
|
209
|
+
SPAs don't have traditional page URLs. Use this approach:
|
|
210
|
+
1. Start at the root URL
|
|
211
|
+
2. Read the navigation/sidebar for all sections
|
|
212
|
+
3. Click each section, wait for content to load
|
|
213
|
+
4. Take snapshot after each navigation
|
|
214
|
+
5. Track visited states by URL hash or path changes
|
|
215
|
+
|
|
216
|
+
### Crawl depth limits
|
|
217
|
+
|
|
218
|
+
| App size | Max pages | Estimated time |
|
|
219
|
+
|----------|-----------|----------------|
|
|
220
|
+
| Small (< 10 pages) | All pages | 2-5 min |
|
|
221
|
+
| Medium (10-50 pages) | All pages | 5-15 min |
|
|
222
|
+
| Large (50+ pages) | Top 50, then ask user | 15+ min |
|
|
223
|
+
|
|
224
|
+
After every 10 pages, show progress:
|
|
225
|
+
> "Scanned 10/~25 pages. Found 3 feature areas so far. Continue?"
|
|
226
|
+
|
|
227
|
+
---
|
|
228
|
+
|
|
229
|
+
## Feature Extraction
|
|
230
|
+
|
|
231
|
+
### What to extract from each page
|
|
232
|
+
|
|
233
|
+
For every page visited, capture:
|
|
234
|
+
|
|
235
|
+
```yaml
|
|
236
|
+
page:
|
|
237
|
+
url: "/dashboard"
|
|
238
|
+
title: "Dashboard"
|
|
239
|
+
type: dashboard | list | detail | form | settings | landing | auth | empty
|
|
240
|
+
features:
|
|
241
|
+
- name: "Revenue Chart"
|
|
242
|
+
type: data-display | form | action | navigation | filter | notification
|
|
243
|
+
description: "Line chart showing monthly revenue with date range picker"
|
|
244
|
+
ui_elements:
|
|
245
|
+
- chart (line, with tooltips)
|
|
246
|
+
- date range picker
|
|
247
|
+
- export button
|
|
248
|
+
interactions:
|
|
249
|
+
- hover shows tooltip with exact value
|
|
250
|
+
- date range filters the data
|
|
251
|
+
- export downloads CSV
|
|
252
|
+
- name: "Quick Actions Bar"
|
|
253
|
+
type: action
|
|
254
|
+
description: "Row of shortcut buttons: New Invoice, New Client, Reports"
|
|
255
|
+
interactions:
|
|
256
|
+
- each button navigates to respective page
|
|
257
|
+
```
|
|
258
|
+
|
|
259
|
+
### Feature grouping rules
|
|
260
|
+
|
|
261
|
+
After crawling, group features into **feature areas** (these become Epics):
|
|
262
|
+
|
|
263
|
+
1. **By navigation section** — sidebar/navbar sections are natural groupings
|
|
264
|
+
2. **By user goal** — what is the user trying to do?
|
|
265
|
+
3. **By data domain** — features that touch the same data belong together
|
|
266
|
+
|
|
267
|
+
Example groupings:
|
|
268
|
+
```
|
|
269
|
+
Epic: User Management
|
|
270
|
+
- User list with search/filter
|
|
271
|
+
- User profile page
|
|
272
|
+
- User invite flow
|
|
273
|
+
- Role assignment
|
|
274
|
+
- User deactivation
|
|
275
|
+
|
|
276
|
+
Epic: Billing & Payments
|
|
277
|
+
- Invoice list
|
|
278
|
+
- Create invoice form
|
|
279
|
+
- Payment tracking
|
|
280
|
+
- Subscription management
|
|
281
|
+
- Billing settings
|
|
282
|
+
```
|
|
283
|
+
|
|
284
|
+
### Priority assignment
|
|
285
|
+
|
|
286
|
+
Assign priority based on visibility and complexity:
|
|
287
|
+
|
|
288
|
+
| Priority | Criteria |
|
|
289
|
+
|----------|----------|
|
|
290
|
+
| P0 - Must have | Core user flow, app doesn't work without it |
|
|
291
|
+
| P1 - Should have | Important but app is usable without it |
|
|
292
|
+
| P2 - Nice to have | Enhancement, polish, edge case handling |
|
|
293
|
+
| P3 - Future | Advanced feature, nice but not needed now |
|
|
294
|
+
|
|
295
|
+
**Heuristics:**
|
|
296
|
+
- Main navigation items → P0 or P1
|
|
297
|
+
- Settings/config pages → P1 or P2
|
|
298
|
+
- Empty states, onboarding → P2
|
|
299
|
+
- Social features, sharing → P2 or P3
|
|
300
|
+
|
|
301
|
+
### Dependency mapping
|
|
302
|
+
|
|
303
|
+
Map dependencies between features:
|
|
304
|
+
|
|
305
|
+
```
|
|
306
|
+
Epic: Authentication (must build first)
|
|
307
|
+
→ Epic: User Management (needs auth)
|
|
308
|
+
→ Epic: Team Management (needs users)
|
|
309
|
+
→ Epic: Permissions (needs teams)
|
|
310
|
+
|
|
311
|
+
Epic: Product Catalog (independent)
|
|
312
|
+
→ Epic: Shopping Cart (needs products)
|
|
313
|
+
→ Epic: Checkout (needs cart)
|
|
314
|
+
→ Epic: Order Management (needs checkout)
|
|
315
|
+
```
|
|
316
|
+
|
|
317
|
+
Rules for dependencies:
|
|
318
|
+
- CRUD operations: Create before Read/List before Update before Delete
|
|
319
|
+
- Auth is always first
|
|
320
|
+
- Data display depends on data input
|
|
321
|
+
- Settings depend on the feature they configure
|
|
322
|
+
|
|
323
|
+
---
|
|
324
|
+
|
|
325
|
+
## PRD Generation
|
|
326
|
+
|
|
327
|
+
### Structure
|
|
328
|
+
|
|
329
|
+
Generate a PRD with 8 sections. The format is designed to be actionable — when someone reads it, they know exactly what to build first, step by step.
|
|
330
|
+
|
|
331
|
+
```
|
|
332
|
+
1. TL;DR — 2 sentences, what this app does
|
|
333
|
+
2. Goals — Business goals, user goals, non-goals
|
|
334
|
+
3. User Stories — Grouped by persona/role
|
|
335
|
+
4. Functional Reqs — Grouped by Epic, with priority table + acceptance criteria
|
|
336
|
+
5. User Experience — Entry points, key flows, edge cases, design notes
|
|
337
|
+
6. Narrative — 200-word story from user's POV
|
|
338
|
+
7. Build Roadmap — Phased plan with dependency graph (the "what to do first" section)
|
|
339
|
+
8. Open Questions — Things that need human input
|
|
340
|
+
```
|
|
341
|
+
|
|
342
|
+
**Section 4 (Functional Requirements)** is the main section. Each Epic gets:
|
|
343
|
+
- A priority and phase number
|
|
344
|
+
- A requirements table: `# | Requirement | Priority | Story`
|
|
345
|
+
- Acceptance criteria as checkboxes
|
|
346
|
+
|
|
347
|
+
**Section 7 (Build Roadmap)** is the actionable section. Shows:
|
|
348
|
+
- Phases with parallel epics
|
|
349
|
+
- Dependency graph (text diagram)
|
|
350
|
+
- Complexity estimate per epic
|
|
351
|
+
|
|
352
|
+
See the command file (`web-to-prd.md`) for the full template.
|
|
353
|
+
|
|
354
|
+
---
|
|
355
|
+
|
|
356
|
+
## Notion Export
|
|
357
|
+
|
|
358
|
+
### Database Structure
|
|
359
|
+
|
|
360
|
+
Create 4 linked databases in Notion:
|
|
361
|
+
|
|
362
|
+
```
|
|
363
|
+
Parent page: "[App Name] — Product Backlog"
|
|
364
|
+
├── PRD page (full text PRD)
|
|
365
|
+
├── Epics database
|
|
366
|
+
│ ├── Name (title)
|
|
367
|
+
│ ├── Priority (select: P0, P1, P2, P3)
|
|
368
|
+
│ ├── Status (select: Not Started, In Progress, Done)
|
|
369
|
+
│ ├── Phase (number)
|
|
370
|
+
│ ├── Depends On (relation → Epics)
|
|
371
|
+
│ ├── Description (rich text)
|
|
372
|
+
│ └── Story Count (rollup from Stories)
|
|
373
|
+
├── Stories database
|
|
374
|
+
│ ├── Name (title)
|
|
375
|
+
│ ├── Epic (relation → Epics)
|
|
376
|
+
│ ├── Priority (select: P0, P1, P2, P3)
|
|
377
|
+
│ ├── Status (select: Backlog, Ready, In Progress, Review, Done)
|
|
378
|
+
│ ├── Points (number)
|
|
379
|
+
│ ├── User Story (rich text: As a..., I can..., so that...)
|
|
380
|
+
│ └── Acceptance Criteria (rich text: checklist)
|
|
381
|
+
└── Tasks database
|
|
382
|
+
├── Name (title)
|
|
383
|
+
├── Story (relation → Stories)
|
|
384
|
+
├── Status (select: To Do, In Progress, Done)
|
|
385
|
+
├── Type (select: Frontend, Backend, Design, DevOps, QA)
|
|
386
|
+
└── Description (rich text)
|
|
387
|
+
```
|
|
388
|
+
|
|
389
|
+
### Export steps
|
|
390
|
+
|
|
391
|
+
1. **Ask where to put it:**
|
|
392
|
+
> "Where should I create the backlog in Notion?
|
|
393
|
+
> A) Create a new page in your workspace root
|
|
394
|
+
> B) Add it under an existing page (I'll search for it)
|
|
395
|
+
> C) Just generate the PRD locally, don't push to Notion"
|
|
396
|
+
|
|
397
|
+
2. **Create parent page** with the PRD content
|
|
398
|
+
3. **Create Epics database** with all epics
|
|
399
|
+
4. **Create Stories database** linked to Epics
|
|
400
|
+
5. **Create Tasks database** linked to Stories
|
|
401
|
+
6. **Create views:**
|
|
402
|
+
- Kanban view (by Status) for Stories
|
|
403
|
+
- Timeline view (by Phase) for Epics
|
|
404
|
+
- Table view (default) for Tasks
|
|
405
|
+
|
|
406
|
+
### If Notion MCP is not available
|
|
407
|
+
|
|
408
|
+
Save everything locally:
|
|
409
|
+
```
|
|
410
|
+
.planning/web-to-prd/
|
|
411
|
+
├── prd.md # Full PRD document
|
|
412
|
+
├── epics.md # All epics with stories
|
|
413
|
+
├── dependency-graph.md # Visual dependency map
|
|
414
|
+
└── screenshots/ # Page screenshots (if taken)
|
|
415
|
+
```
|
|
416
|
+
|
|
417
|
+
User can import to Notion manually later.
|
|
418
|
+
|
|
419
|
+
---
|
|
420
|
+
|
|
421
|
+
## Rules
|
|
422
|
+
|
|
423
|
+
1. **Always check prerequisites first.** Don't start crawling without confirming both MCP servers.
|
|
424
|
+
2. **Login before crawling.** Never generate a PRD from a login page or public-only view. If the app has login, handle it first. Verify you see the full app before starting.
|
|
425
|
+
3. **Confirm access level.** After login, show the user what sections are visible and ask if anything is missing. A PRD from a limited view is useless.
|
|
426
|
+
4. **Handle session expiry.** If redirected to login mid-crawl, STOP and ask user to re-login. Don't crawl from a login page.
|
|
427
|
+
5. **Show progress during crawl.** Every 10 pages or every major section, update the user.
|
|
428
|
+
3. **Don't guess features you can't see.** Only document what's visible in the UI. Mark assumptions clearly.
|
|
429
|
+
4. **Ask before clicking destructive actions.** If you see "Delete" or "Remove" buttons, don't click them during crawl.
|
|
430
|
+
5. **Handle errors gracefully.** If a page fails to load, note it and move on. Don't stop the whole crawl.
|
|
431
|
+
6. **Respect rate limits.** Add 1-2 second delays between page navigations to avoid being blocked.
|
|
432
|
+
7. **Screenshots are optional.** Only take them if the user asks or if a page has complex layout.
|
|
433
|
+
8. **Login is the user's job.** Never store or ask for production credentials. Use headed mode for manual login.
|
|
434
|
+
9. **Local save is always available.** Even if Notion export fails, the PRD is saved locally.
|
|
435
|
+
10. **One app per run.** Don't crawl multiple domains in a single session.
|
|
436
|
+
11. **NEVER point `--user-data-dir` to the real Chrome profile directory** (e.g., `~/Library/Application Support/Google/Chrome` on Mac, `~/.config/google-chrome` on Linux). This can corrupt Chrome profiles, delete saved logins, and break the user's browser. Always use a separate directory like `~/.playwright-profile`.
|