design-protocol 1.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (72) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +225 -0
  3. package/agents/dp-researcher.md +239 -0
  4. package/agents/dp-verifier.md +207 -0
  5. package/bin/install.js +464 -0
  6. package/commands/dp-back.md +221 -0
  7. package/commands/dp-discuss.md +257 -0
  8. package/commands/dp-execute.md +513 -0
  9. package/commands/dp-journey.md +85 -0
  10. package/commands/dp-progress.md +178 -0
  11. package/commands/dp-roadmap.md +83 -0
  12. package/commands/dp-skip.md +186 -0
  13. package/commands/dp-start.md +510 -0
  14. package/commands/dp-storytell.md +94 -0
  15. package/commands/dp-verify.md +207 -0
  16. package/package.json +59 -0
  17. package/skills/dp-color/SKILL.md +214 -0
  18. package/skills/dp-color/export_tokens.py +297 -0
  19. package/skills/dp-color/references/apca-contrast.md +87 -0
  20. package/skills/dp-color/references/hue-emotions.md +109 -0
  21. package/skills/dp-color/references/oklch-gamut.md +79 -0
  22. package/skills/dp-color/references/pitfalls.md +171 -0
  23. package/skills/dp-color/references/scale-patterns.md +206 -0
  24. package/skills/dp-color/references/tool-workflows.md +200 -0
  25. package/skills/dp-discovery/SKILL.md +480 -0
  26. package/skills/dp-eng_review/SKILL.md +471 -0
  27. package/skills/dp-eng_review/references/code-review-checklist.md +385 -0
  28. package/skills/dp-eng_review/references/react-patterns.md +512 -0
  29. package/skills/dp-eng_review/references/shadcn-patterns.md +510 -0
  30. package/skills/dp-eng_review/references/tailwind-conventions.md +351 -0
  31. package/skills/dp-journey/SKILL.md +682 -0
  32. package/skills/dp-journey/references/journey-types.md +97 -0
  33. package/skills/dp-journey/references/map-structures.md +177 -0
  34. package/skills/dp-journey/references/omnichannel-patterns.md +208 -0
  35. package/skills/dp-journey/references/research-methods.md +125 -0
  36. package/skills/dp-prd/SKILL.md +201 -0
  37. package/skills/dp-prd/references/claude-code-spec.md +107 -0
  38. package/skills/dp-prd/references/interview-questions.md +158 -0
  39. package/skills/dp-prd/references/section-templates.md +231 -0
  40. package/skills/dp-research/SKILL.md +540 -0
  41. package/skills/dp-research/references/facilitation-guide.md +291 -0
  42. package/skills/dp-research/references/interview-guide-template.md +190 -0
  43. package/skills/dp-research/references/method-selection.md +195 -0
  44. package/skills/dp-research/references/question-writing.md +244 -0
  45. package/skills/dp-research/references/research-report-template.md +363 -0
  46. package/skills/dp-research/references/synthesis-methods.md +289 -0
  47. package/skills/dp-research/references/usability-test-template.md +260 -0
  48. package/skills/dp-roadmap/SKILL.md +648 -0
  49. package/skills/dp-roadmap/references/prioritization-frameworks.md +312 -0
  50. package/skills/dp-roadmap/references/roadmap-structures.md +179 -0
  51. package/skills/dp-roadmap/references/roadmap-workshops.md +264 -0
  52. package/skills/dp-roadmap/references/theme-development.md +168 -0
  53. package/skills/dp-storytell/SKILL.md +645 -0
  54. package/skills/dp-storytell/references/audience-playbooks.md +260 -0
  55. package/skills/dp-storytell/references/content-type-templates.md +310 -0
  56. package/skills/dp-storytell/references/delivery-tactics.md +228 -0
  57. package/skills/dp-storytell/references/narrative-frameworks.md +259 -0
  58. package/skills/dp-ui/SKILL.md +503 -0
  59. package/skills/dp-ui/references/b2b-enterprise-patterns.md +319 -0
  60. package/skills/dp-ui/references/data-visualization.md +304 -0
  61. package/skills/dp-ui/references/visual-design-principles.md +237 -0
  62. package/skills/dp-ux/SKILL.md +414 -0
  63. package/skills/dp-ux/references/accessibility-checklist.md +128 -0
  64. package/skills/dp-ux/references/product-excellence.md +149 -0
  65. package/skills/dp-ux/references/usability-principles.md +140 -0
  66. package/skills/dp-ux/references/ux-patterns.md +221 -0
  67. package/templates/config.json +55 -0
  68. package/templates/context.md +96 -0
  69. package/templates/project.md +83 -0
  70. package/templates/requirements.md +137 -0
  71. package/templates/roadmap.md +168 -0
  72. package/templates/state.md +107 -0
package/bin/install.js ADDED
@@ -0,0 +1,464 @@
1
+ #!/usr/bin/env node
2
+
3
+ const fs = require('fs');
4
+ const path = require('path');
5
+ const readline = require('readline');
6
+ const { execSync } = require('child_process');
7
+
8
+ const VERSION = '1.0.0';
9
+ const PACKAGE_NAME = 'design-protocol';
10
+ const PACKAGE_DIR = path.join(__dirname, '..');
11
+ let VERBOSE = false;
12
+
13
+ // ANSI colors
14
+ const c = {
15
+ reset: '\x1b[0m',
16
+ bright: '\x1b[1m',
17
+ dim: '\x1b[2m',
18
+ green: '\x1b[32m',
19
+ yellow: '\x1b[33m',
20
+ blue: '\x1b[34m',
21
+ magenta: '\x1b[35m',
22
+ cyan: '\x1b[36m',
23
+ red: '\x1b[31m'
24
+ };
25
+
26
+ function log(msg, color = 'reset') {
27
+ console.log(`${c[color]}${msg}${c.reset}`);
28
+ }
29
+
30
+ function logStep(step, total, msg) {
31
+ console.log(`${c.cyan}[${step}/${total}]${c.reset} ${msg}`);
32
+ }
33
+
34
+ function logSuccess(msg) {
35
+ console.log(` ${c.green}✓${c.reset} ${msg}`);
36
+ }
37
+
38
+ function logSkip(msg) {
39
+ console.log(` ${c.yellow}○${c.reset} ${msg}`);
40
+ }
41
+
42
+ function logError(msg) {
43
+ console.log(` ${c.red}✗${c.reset} ${msg}`);
44
+ }
45
+
46
+ function logVerbose(msg) {
47
+ if (VERBOSE) console.log(` ${c.dim} → ${msg}${c.reset}`);
48
+ }
49
+
50
+ function printBanner() {
51
+ console.log(`\n${c.magenta}${c.bright} DP ${c.reset}${c.cyan}Design Protocol${c.reset} ${c.dim}v${VERSION}${c.reset}`);
52
+ console.log(`${c.dim} Complete design workflow for Claude Code${c.reset}\n`);
53
+ }
54
+
55
+ function getClaudeDir(location) {
56
+ if (location === 'global') {
57
+ const homeDir = process.env.HOME || process.env.USERPROFILE;
58
+ return process.env.CLAUDE_CONFIG_DIR || path.join(homeDir, '.claude');
59
+ }
60
+ return path.join(process.cwd(), '.claude');
61
+ }
62
+
63
+ function ensureDir(dir) {
64
+ if (!fs.existsSync(dir)) {
65
+ logVerbose(`mkdir ${dir}`);
66
+ try {
67
+ fs.mkdirSync(dir, { recursive: true });
68
+ } catch (err) {
69
+ if (err.code === 'EACCES') {
70
+ throw new Error(`Permission denied creating directory: ${dir}\n Try running with sudo or check folder permissions.`);
71
+ }
72
+ throw new Error(`Failed to create directory: ${dir}\n ${err.message}`);
73
+ }
74
+ }
75
+ }
76
+
77
+ const MAX_COPY_DEPTH = 10;
78
+ const SKIP_ENTRIES = new Set(['.git', '.DS_Store', '.env', 'node_modules', '.next']);
79
+
80
+ function copyRecursive(src, dest, depth = 0) {
81
+ if (!fs.existsSync(src)) return 0;
82
+ if (depth > MAX_COPY_DEPTH) {
83
+ logError(`Skipping deeply nested path (>${MAX_COPY_DEPTH} levels): ${src}`);
84
+ return 0;
85
+ }
86
+
87
+ // Skip symlinks — only copy real files
88
+ const lstats = fs.lstatSync(src);
89
+ if (lstats.isSymbolicLink()) return 0;
90
+
91
+ let count = 0;
92
+
93
+ if (lstats.isDirectory()) {
94
+ ensureDir(dest);
95
+ const files = fs.readdirSync(src);
96
+ for (const file of files) {
97
+ if (SKIP_ENTRIES.has(file)) continue;
98
+ count += copyRecursive(
99
+ path.join(src, file),
100
+ path.join(dest, file),
101
+ depth + 1
102
+ );
103
+ }
104
+ } else {
105
+ try {
106
+ fs.copyFileSync(src, dest);
107
+ logVerbose(`${path.basename(src)}`);
108
+ } catch (err) {
109
+ if (err.code === 'EACCES') {
110
+ throw new Error(`Permission denied writing file: ${dest}`);
111
+ }
112
+ throw new Error(`Failed to copy ${path.basename(src)} → ${dest}\n ${err.message}`);
113
+ }
114
+ count = 1;
115
+ }
116
+ return count;
117
+ }
118
+
119
+ function countFiles(dir) {
120
+ if (!fs.existsSync(dir)) return 0;
121
+ let count = 0;
122
+ const items = fs.readdirSync(dir);
123
+ for (const item of items) {
124
+ const itemPath = path.join(dir, item);
125
+ const stats = fs.statSync(itemPath);
126
+ if (stats.isDirectory()) {
127
+ count += countFiles(itemPath);
128
+ } else {
129
+ count++;
130
+ }
131
+ }
132
+ return count;
133
+ }
134
+
135
+ async function prompt(question) {
136
+ const rl = readline.createInterface({
137
+ input: process.stdin,
138
+ output: process.stdout
139
+ });
140
+ return new Promise((resolve) => {
141
+ rl.question(question, (answer) => {
142
+ rl.close();
143
+ resolve(answer.trim().toLowerCase());
144
+ });
145
+ });
146
+ }
147
+
148
+ function getLatestVersion() {
149
+ try {
150
+ const result = execSync(`npm view ${PACKAGE_NAME} version`, { encoding: 'utf8' });
151
+ return result.trim();
152
+ } catch (err) {
153
+ return null;
154
+ }
155
+ }
156
+
157
+ function compareVersions(v1, v2) {
158
+ const parts1 = v1.split('.').map(Number);
159
+ const parts2 = v2.split('.').map(Number);
160
+
161
+ for (let i = 0; i < Math.max(parts1.length, parts2.length); i++) {
162
+ const p1 = parts1[i] || 0;
163
+ const p2 = parts2[i] || 0;
164
+ if (p1 > p2) return 1;
165
+ if (p1 < p2) return -1;
166
+ }
167
+ return 0;
168
+ }
169
+
170
+ async function checkForUpdate() {
171
+ log('\nChecking for updates...', 'dim');
172
+
173
+ const latest = getLatestVersion();
174
+ if (!latest) {
175
+ logError('Could not check for updates. Are you online?');
176
+ return false;
177
+ }
178
+
179
+ const comparison = compareVersions(latest, VERSION);
180
+
181
+ if (comparison > 0) {
182
+ log(`\n${c.yellow}Update available!${c.reset} ${VERSION} → ${c.green}${latest}${c.reset}\n`);
183
+ return latest;
184
+ } else if (comparison === 0) {
185
+ log(`\n${c.green}✓${c.reset} You have the latest version (${VERSION})\n`);
186
+ return false;
187
+ } else {
188
+ log(`\n${c.green}✓${c.reset} You have a newer version (${VERSION}) than npm (${latest})\n`);
189
+ return false;
190
+ }
191
+ }
192
+
193
+ async function performUpdate(location) {
194
+ log(`\nUpdating DP...`, 'bright');
195
+
196
+ try {
197
+ // Run npx with latest version
198
+ log('Downloading latest version...', 'dim');
199
+ execSync(`npx ${PACKAGE_NAME}@latest --${location} --auto`, {
200
+ stdio: 'inherit',
201
+ encoding: 'utf8'
202
+ });
203
+ return true;
204
+ } catch (err) {
205
+ logError(`Update failed: ${err.message}`);
206
+ return false;
207
+ }
208
+ }
209
+
210
+ async function main() {
211
+ const args = process.argv.slice(2);
212
+
213
+ // Parse arguments
214
+ const isGlobal = args.includes('--global') || args.includes('-g');
215
+ const isLocal = args.includes('--local') || args.includes('-l');
216
+ const isAuto = args.includes('--auto');
217
+ const isUninstall = args.includes('--uninstall') || args.includes('-u');
218
+ const isUpdate = args.includes('--update') || args.includes('--upgrade');
219
+ const isCheckUpdate = args.includes('--check-update');
220
+ const isHelp = args.includes('--help') || args.includes('-h');
221
+ const showVersion = args.includes('--version') || args.includes('-v');
222
+ VERBOSE = args.includes('--verbose');
223
+
224
+ if (showVersion) {
225
+ console.log(`dp v${VERSION}`);
226
+ process.exit(0);
227
+ }
228
+
229
+ if (isHelp) {
230
+ console.log(`
231
+ ${c.bright}DP - Design Protocol v${VERSION}${c.reset}
232
+
233
+ Usage: npx design-protocol [options]
234
+
235
+ Options:
236
+ --global, -g Install to ~/.claude/ (all projects)
237
+ --local, -l Install to ./.claude/ (current project only)
238
+ --auto Non-interactive install (default: global)
239
+ --update Update to the latest version
240
+ --check-update Check if updates are available
241
+ --uninstall, -u Remove DP from specified location
242
+ --verbose Show detailed output for troubleshooting
243
+ --version, -v Show version number
244
+ --help, -h Show this help message
245
+
246
+ Examples:
247
+ npx design-protocol # Interactive installation
248
+ npx design-protocol --global # Install globally
249
+ npx design-protocol --local # Install to current project
250
+ npx design-protocol --update # Update to latest version
251
+ npx design-protocol -g -u # Uninstall from global
252
+
253
+ ${c.bright}What Gets Installed:${c.reset}
254
+ ~/.claude/skills/ 10 design skills (dp-discovery, dp-prd, dp-journey, dp-roadmap, dp-ux, dp-color, dp-ui, dp-eng_review, dp-research, dp-storytell)
255
+ ~/.claude/commands/ 7 workflow commands (dp:start, dp:execute, etc.)
256
+ ~/.claude/agents/ 2 specialized agents
257
+
258
+ ${c.bright}Workflow:${c.reset}
259
+ /dp:start → /dp:discovery → /dp:ux → /dp:execute → /dp:ui → /dp:execute → /dp:eng_review → /dp:verify
260
+ `);
261
+ process.exit(0);
262
+ }
263
+
264
+ // Check for updates only
265
+ if (isCheckUpdate) {
266
+ printBanner();
267
+ await checkForUpdate();
268
+ process.exit(0);
269
+ }
270
+
271
+ // Update mode
272
+ if (isUpdate) {
273
+ printBanner();
274
+ const latest = await checkForUpdate();
275
+ if (latest) {
276
+ const location = isLocal ? 'local' : 'global';
277
+ const answer = await prompt(`Update to v${latest}? [Y/n]: `);
278
+ if (answer !== 'n' && answer !== 'no') {
279
+ await performUpdate(location);
280
+ } else {
281
+ log('Update cancelled.', 'yellow');
282
+ }
283
+ }
284
+ process.exit(0);
285
+ }
286
+
287
+ printBanner();
288
+
289
+ // Determine installation location
290
+ let location;
291
+ if (isGlobal || isAuto) {
292
+ location = 'global';
293
+ } else if (isLocal) {
294
+ location = 'local';
295
+ } else {
296
+ log('\nWhere would you like to install DP?\n', 'bright');
297
+ console.log(' 1. Global (~/.claude/) - Available in all projects');
298
+ console.log(' 2. Local (./.claude/) - Current project only\n');
299
+ const answer = await prompt('Choose [1/2] (default: 1): ');
300
+ location = answer === '2' ? 'local' : 'global';
301
+ }
302
+
303
+ const claudeDir = getClaudeDir(location);
304
+ const skillsDir = path.join(claudeDir, 'skills');
305
+ const commandsDir = path.join(claudeDir, 'commands');
306
+ const agentsDir = path.join(claudeDir, 'agents');
307
+
308
+ if (VERBOSE) {
309
+ log('', 'dim');
310
+ log(' Resolved paths:', 'dim');
311
+ log(` PACKAGE_DIR: ${PACKAGE_DIR}`, 'dim');
312
+ log(` claudeDir: ${claudeDir}`, 'dim');
313
+ log(` CLAUDE_CONFIG_DIR: ${process.env.CLAUDE_CONFIG_DIR || '(not set)'}`, 'dim');
314
+ log(` HOME: ${process.env.HOME || process.env.USERPROFILE}`, 'dim');
315
+ log('', 'dim');
316
+ }
317
+
318
+ if (isUninstall) {
319
+ await runUninstall(location, { skillsDir, commandsDir, agentsDir, claudeDir });
320
+ } else {
321
+ await runInstall(location, { skillsDir, commandsDir, agentsDir, claudeDir }, isAuto);
322
+ }
323
+ }
324
+
325
+ // ─── Uninstall ────────────────────────────────────────────────────────────────
326
+
327
+ async function runUninstall(location, dirs) {
328
+ log(`\nUninstalling from ${location} location...`, 'yellow');
329
+ log(`Target: ${dirs.claudeDir}`, 'dim');
330
+
331
+ let removed = 0;
332
+
333
+ const skillNames = ['dp-discovery', 'dp-prd', 'dp-journey', 'dp-roadmap', 'dp-ux', 'dp-color', 'dp-ui', 'dp-eng_review', 'dp-research', 'dp-storytell'];
334
+ for (const name of skillNames) {
335
+ const skillPath = path.join(dirs.skillsDir, name);
336
+ if (fs.existsSync(skillPath)) {
337
+ fs.rmSync(skillPath, { recursive: true, force: true });
338
+ logSuccess(`Removed skill: ${name}`);
339
+ removed++;
340
+ }
341
+ }
342
+
343
+ const commandFiles = fs.readdirSync(path.join(PACKAGE_DIR, 'commands')).filter(f => f.endsWith('.md'));
344
+ for (const file of commandFiles) {
345
+ const cmdPath = path.join(dirs.commandsDir, file);
346
+ if (fs.existsSync(cmdPath)) {
347
+ fs.unlinkSync(cmdPath);
348
+ logSuccess(`Removed command: ${file}`);
349
+ removed++;
350
+ }
351
+ }
352
+
353
+ const agentFiles = fs.readdirSync(path.join(PACKAGE_DIR, 'agents')).filter(f => f.endsWith('.md'));
354
+ for (const file of agentFiles) {
355
+ const agentPath = path.join(dirs.agentsDir, file);
356
+ if (fs.existsSync(agentPath)) {
357
+ fs.unlinkSync(agentPath);
358
+ logSuccess(`Removed agent: ${file}`);
359
+ removed++;
360
+ }
361
+ }
362
+
363
+ if (removed > 0) {
364
+ log(`\n${c.green}DP uninstalled successfully!${c.reset}\n`);
365
+ } else {
366
+ log(`\n${c.yellow}No DP installation found at ${dirs.claudeDir}${c.reset}\n`);
367
+ }
368
+ }
369
+
370
+ // ─── Install ──────────────────────────────────────────────────────────────────
371
+
372
+ async function runInstall(location, dirs, isAuto) {
373
+ const totalSteps = 4;
374
+ log(`\nInstalling to ${location} location...`, 'bright');
375
+ log(`Target: ${dirs.claudeDir}\n`, 'dim');
376
+
377
+ // Step 1: Skills
378
+ logStep(1, totalSteps, 'Installing skills...');
379
+ const srcSkills = path.join(PACKAGE_DIR, 'skills');
380
+ const skillDirs = fs.readdirSync(srcSkills).filter(f =>
381
+ fs.statSync(path.join(srcSkills, f)).isDirectory()
382
+ );
383
+
384
+ for (const skill of skillDirs) {
385
+ const src = path.join(srcSkills, skill);
386
+ const dest = path.join(dirs.skillsDir, skill);
387
+
388
+ if (fs.existsSync(dest) && !isAuto) {
389
+ const answer = await prompt(` Overwrite ${skill}? [y/N]: `);
390
+ if (answer !== 'y' && answer !== 'yes') {
391
+ logSkip(skill);
392
+ continue;
393
+ }
394
+ fs.rmSync(dest, { recursive: true, force: true });
395
+ }
396
+
397
+ const count = copyRecursive(src, dest);
398
+ logSuccess(`${skill} (${count} files)`);
399
+ }
400
+
401
+ // Step 2: Commands
402
+ logStep(2, totalSteps, 'Installing commands...');
403
+ ensureDir(dirs.commandsDir);
404
+ const srcCommands = path.join(PACKAGE_DIR, 'commands');
405
+ const commandFiles = fs.readdirSync(srcCommands).filter(f => f.endsWith('.md'));
406
+
407
+ for (const file of commandFiles) {
408
+ fs.copyFileSync(path.join(srcCommands, file), path.join(dirs.commandsDir, file));
409
+ logSuccess(file.replace('.md', ''));
410
+ }
411
+
412
+ // Step 3: Agents
413
+ logStep(3, totalSteps, 'Installing agents...');
414
+ ensureDir(dirs.agentsDir);
415
+ const srcAgents = path.join(PACKAGE_DIR, 'agents');
416
+ const agentFiles = fs.readdirSync(srcAgents).filter(f => f.endsWith('.md'));
417
+
418
+ for (const file of agentFiles) {
419
+ fs.copyFileSync(path.join(srcAgents, file), path.join(dirs.agentsDir, file));
420
+ logSuccess(file.replace('.md', ''));
421
+ }
422
+
423
+ // Step 4: Summary
424
+ logStep(4, totalSteps, 'Installation complete!');
425
+ printSummary(
426
+ { skills: skillDirs.length, commands: commandFiles.length, agents: agentFiles.length },
427
+ dirs
428
+ );
429
+ }
430
+
431
+ // ─── Summary ──────────────────────────────────────────────────────────────────
432
+
433
+ function printSummary(counts, dirs) {
434
+ console.log(`
435
+ ${c.green}${c.bright}DP ${VERSION} installed successfully!${c.reset}
436
+
437
+ ${c.bright}Installed:${c.reset}
438
+ ${c.cyan}${counts.skills}${c.reset} skills → ${dirs.skillsDir}
439
+ ${c.cyan}${counts.commands}${c.reset} commands → ${dirs.commandsDir}
440
+ ${c.cyan}${counts.agents}${c.reset} agents → ${dirs.agentsDir}
441
+
442
+ ${c.bright}Quick Start:${c.reset}
443
+ ${c.cyan}/dp:start${c.reset} Start a new design workflow
444
+ ${c.cyan}/dp:progress${c.reset} Check workflow status
445
+ ${c.cyan}/dp:execute${c.reset} Generate implementation
446
+
447
+ ${c.bright}Design Skills:${c.reset}
448
+ ${c.cyan}/dp:discovery${c.reset} Discovery & requirements
449
+ ${c.cyan}/dp:ux${c.reset} UX principles & states
450
+ ${c.cyan}/dp:ui${c.reset} Visual design & tokens
451
+ ${c.cyan}/dp:eng_review${c.reset} Code review & a11y
452
+
453
+ ${c.bright}Workflow:${c.reset}
454
+ Discovery → UX → ${c.yellow}Execute(wireframe)${c.reset} → UI → ${c.yellow}Execute(polished)${c.reset} → Review
455
+
456
+ ${c.dim}Restart Claude Code to load DP.${c.reset}
457
+ `);
458
+ }
459
+
460
+ main().catch((err) => {
461
+ logError(`Installation failed: ${err.message}`);
462
+ console.error(err);
463
+ process.exit(1);
464
+ });
@@ -0,0 +1,221 @@
1
+ ---
2
+ name: dp-back
3
+ description: Go back to a previous DP workflow phase. Use to revisit decisions, update context, or re-run a phase with new information.
4
+ ---
5
+
6
+ # /dp:back — Return to Previous Phase
7
+
8
+ You are navigating back in the DP workflow. This allows revisiting earlier phases to update or refine design work.
9
+
10
+ ## When to Use
11
+
12
+ - New information invalidates earlier decisions
13
+ - Need to update discovery based on research findings
14
+ - Want to refine UX decisions after UI work revealed issues
15
+ - Stakeholder feedback requires earlier phase changes
16
+ - Review found issues that need design-level fixes
17
+
18
+ ## Workflow
19
+
20
+ ### Step 1: Check Workflow Exists
21
+
22
+ ```bash
23
+ ls .design/config.json 2>/dev/null
24
+ ```
25
+
26
+ ### Step 2: Get Current Position
27
+
28
+ Read `.design/STATE.md` and `.design/config.json` to determine:
29
+ - Current phase number
30
+ - Completed phases
31
+ - Available phases to return to
32
+
33
+ ### Step 3: Present Options
34
+
35
+ **If current phase > 1:**
36
+ ```
37
+ CURRENT POSITION: Phase [N] — [Phase Name]
38
+
39
+ Go back to:
40
+ 1. Discovery — Update problem/users/requirements
41
+ 2. UX — Revise user flows and states
42
+ [3. UI — Adjust visual specs]
43
+
44
+ Or enter phase number (1-[N-1])
45
+
46
+ Which phase? (1-[N-1] or cancel)
47
+ ```
48
+
49
+ **If on first phase:**
50
+ ```
51
+ You're on Phase 1 (Discovery) — can't go back further.
52
+
53
+ Options:
54
+ • Run /dp:discovery to start/redo discovery
55
+ • Run /dp:progress to see status
56
+ ```
57
+
58
+ ### Step 4: Handle Navigation
59
+
60
+ **When user selects a phase:**
61
+
62
+ 1. Confirm the action:
63
+ ```
64
+ Going back to: Phase [X] — [Phase Name]
65
+
66
+ This will:
67
+ ✓ Set Phase [X] as current
68
+ ✓ Keep existing [Phase X] output for reference
69
+ ○ Later phases remain but may need updates
70
+
71
+ Continue? (y/n)
72
+ ```
73
+
74
+ 2. Update `.design/STATE.md`:
75
+ - Set current phase to selected phase
76
+ - Add navigation to activity log
77
+ - Note any context about why going back
78
+
79
+ 3. Update `.design/config.json`:
80
+ - Set `current_phase` to selected phase number
81
+ - Don't remove later phases from `phases_completed` (they exist but may be stale)
82
+
83
+ 4. Rename existing phase file (if exists):
84
+ - `.design/phases/DISCOVERY.md` → `.design/phases/DISCOVERY.v1.md`
85
+ - Allows fresh start while preserving history
86
+
87
+ **Output:**
88
+ ```
89
+ ✓ Returned to: Phase [X] — [Phase Name]
90
+
91
+ Previous output preserved as: [PHASE_NAME].v1.md
92
+
93
+ Current Position:
94
+ Phase: [X] of 4 ([Phase Name])
95
+ Status: Ready
96
+ Progress: [██░░░░░░░░] [X]%
97
+
98
+ Note: Phases [X+1] through [N] may need updates after you modify this phase.
99
+
100
+ Next: Run /[skill] to redo this phase
101
+ Or /dp:discuss to capture new context first
102
+ ```
103
+
104
+ ### Step 5: Provide Context
105
+
106
+ When going back, remind user of relevant context:
107
+
108
+ **Going back to Discovery:**
109
+ ```
110
+ CONTEXT FOR DISCOVERY REDO
111
+ ────────────────────────────────────────────────────────────────────────────────
112
+ What triggered going back:
113
+ • [from user or inferred]
114
+
115
+ Existing outputs that may be affected:
116
+ • UX-DECISIONS.md — May need updates
117
+ • UI-SPEC.md — May need updates
118
+
119
+ Key questions to reconsider:
120
+ • Is the problem statement still accurate?
121
+ • Has our understanding of users changed?
122
+ • Do requirements need reprioritization?
123
+ ```
124
+
125
+ **Going back to UX:**
126
+ ```
127
+ CONTEXT FOR UX REDO
128
+ ────────────────────────────────────────────────────────────────────────────────
129
+ From Discovery (unchanged):
130
+ • Problem: [problem statement]
131
+ • User: [primary user]
132
+
133
+ What may need updating:
134
+ • User flows
135
+ • State definitions
136
+ • Accessibility requirements
137
+
138
+ Existing UI spec may need realignment after UX changes.
139
+ ```
140
+
141
+ ### Step 6: Edge Cases
142
+
143
+ **Going back with uncommitted changes:**
144
+ ```
145
+ Note: You have changes in progress for Phase [N].
146
+
147
+ Options:
148
+ 1. Go back anyway (current progress will be marked incomplete)
149
+ 2. Complete current phase first, then go back
150
+ 3. Cancel
151
+
152
+ Choice?
153
+ ```
154
+
155
+ **Going back to a skipped phase:**
156
+ ```
157
+ Phase [X] was previously skipped.
158
+
159
+ Going back will:
160
+ • Set Phase [X] as current
161
+ • Allow you to complete it properly
162
+
163
+ This is a good way to fill in a skipped phase.
164
+
165
+ Continue? (y/n)
166
+ ```
167
+
168
+ **Multiple iterations:**
169
+
170
+ Track version history in STATE.md:
171
+ ```markdown
172
+ ## Iteration History
173
+
174
+ | Phase | Version | Date | Reason |
175
+ |-------|---------|------|--------|
176
+ | Discovery | v1 | 2024-01-15 | Initial |
177
+ | Discovery | v2 | 2024-01-18 | Updated after research |
178
+ | UX | v1 | 2024-01-16 | Initial |
179
+ ```
180
+
181
+ ## Version Management
182
+
183
+ When going back, preserve history:
184
+
185
+ ```
186
+ .design/phases/
187
+ ├── DISCOVERY.md # Current version (v2)
188
+ ├── DISCOVERY.v1.md # Previous version
189
+ ├── UX-DECISIONS.md # Current (may be stale)
190
+ └── UI-SPEC.md # Current (may be stale)
191
+ ```
192
+
193
+ Maximum versions to keep: 3 (oldest auto-deleted)
194
+
195
+ ## State Updates
196
+
197
+ **STATE.md activity log:**
198
+ ```markdown
199
+ ### Last Activity
200
+ - **Date:** [TIMESTAMP]
201
+ - **Action:** Returned to Discovery phase (was on UI)
202
+ - **Reason:** Research findings changed user understanding
203
+ ```
204
+
205
+ ## Integration Notes
206
+
207
+ - Skills should check STATE.md to see if they're running as a redo
208
+ - If redoing, skill can offer to show diff from previous version
209
+ - Later phases should be flagged as "may need update" in progress view
210
+
211
+ ---
212
+
213
+ ## Workflow Navigation
214
+
215
+ | | |
216
+ |---|---|
217
+ | **This command** | `/dp:back` — Return to previous phase |
218
+ | **Use when** | New information invalidates earlier decisions |
219
+ | **Returns to** | The previous phase (or a specific phase if specified) |
220
+ | **Then run** | The phase skill for that phase to redo it |
221
+ | **Related** | `/dp:skip` — Skip forward if redo isn't needed after all |