pmp-gywd 3.3.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 (126) hide show
  1. package/LICENSE +27 -0
  2. package/README.md +567 -0
  3. package/bin/install.js +348 -0
  4. package/commands/gywd/add-phase.md +207 -0
  5. package/commands/gywd/anticipate.md +271 -0
  6. package/commands/gywd/bootstrap.md +336 -0
  7. package/commands/gywd/challenge.md +344 -0
  8. package/commands/gywd/check-drift.md +144 -0
  9. package/commands/gywd/complete-milestone.md +106 -0
  10. package/commands/gywd/consider-issues.md +202 -0
  11. package/commands/gywd/context.md +93 -0
  12. package/commands/gywd/create-roadmap.md +115 -0
  13. package/commands/gywd/deps.md +169 -0
  14. package/commands/gywd/digest.md +138 -0
  15. package/commands/gywd/discuss-milestone.md +47 -0
  16. package/commands/gywd/discuss-phase.md +60 -0
  17. package/commands/gywd/execute-plan.md +161 -0
  18. package/commands/gywd/extract-decisions.md +325 -0
  19. package/commands/gywd/health.md +150 -0
  20. package/commands/gywd/help.md +556 -0
  21. package/commands/gywd/history.md +278 -0
  22. package/commands/gywd/impact.md +317 -0
  23. package/commands/gywd/init.md +95 -0
  24. package/commands/gywd/insert-phase.md +227 -0
  25. package/commands/gywd/list-phase-assumptions.md +50 -0
  26. package/commands/gywd/map-codebase.md +84 -0
  27. package/commands/gywd/memory.md +159 -0
  28. package/commands/gywd/new-milestone.md +59 -0
  29. package/commands/gywd/new-project.md +315 -0
  30. package/commands/gywd/pause-work.md +123 -0
  31. package/commands/gywd/plan-fix.md +205 -0
  32. package/commands/gywd/plan-phase.md +93 -0
  33. package/commands/gywd/preview-plan.md +139 -0
  34. package/commands/gywd/profile.md +363 -0
  35. package/commands/gywd/progress.md +317 -0
  36. package/commands/gywd/remove-phase.md +338 -0
  37. package/commands/gywd/research-phase.md +91 -0
  38. package/commands/gywd/resume-work.md +40 -0
  39. package/commands/gywd/rollback.md +179 -0
  40. package/commands/gywd/status.md +42 -0
  41. package/commands/gywd/sync-github.md +234 -0
  42. package/commands/gywd/verify-work.md +71 -0
  43. package/commands/gywd/why.md +251 -0
  44. package/docs/COMMANDS.md +722 -0
  45. package/docs/CONTRIBUTING.md +342 -0
  46. package/docs/EXAMPLES.md +535 -0
  47. package/docs/GETTING-STARTED.md +262 -0
  48. package/docs/README.md +55 -0
  49. package/docs/RELEASING.md +159 -0
  50. package/get-your-work-done/core/agent-patterns.md +331 -0
  51. package/get-your-work-done/core/architecture.md +334 -0
  52. package/get-your-work-done/core/context-model-schema.json +154 -0
  53. package/get-your-work-done/core/decisions-schema.json +193 -0
  54. package/get-your-work-done/core/learning-state-schema.json +133 -0
  55. package/get-your-work-done/core/profile-schema.json +257 -0
  56. package/get-your-work-done/references/adaptive-decomposition.md +175 -0
  57. package/get-your-work-done/references/checkpoints.md +287 -0
  58. package/get-your-work-done/references/confidence-scoring.md +169 -0
  59. package/get-your-work-done/references/continuation-format.md +255 -0
  60. package/get-your-work-done/references/git-integration.md +254 -0
  61. package/get-your-work-done/references/plan-format.md +428 -0
  62. package/get-your-work-done/references/principles.md +157 -0
  63. package/get-your-work-done/references/questioning.md +162 -0
  64. package/get-your-work-done/references/research-pitfalls.md +215 -0
  65. package/get-your-work-done/references/scope-estimation.md +172 -0
  66. package/get-your-work-done/references/tdd.md +263 -0
  67. package/get-your-work-done/templates/codebase/architecture.md +255 -0
  68. package/get-your-work-done/templates/codebase/concerns.md +310 -0
  69. package/get-your-work-done/templates/codebase/conventions.md +307 -0
  70. package/get-your-work-done/templates/codebase/integrations.md +280 -0
  71. package/get-your-work-done/templates/codebase/stack.md +186 -0
  72. package/get-your-work-done/templates/codebase/structure.md +285 -0
  73. package/get-your-work-done/templates/codebase/testing.md +480 -0
  74. package/get-your-work-done/templates/config.json +18 -0
  75. package/get-your-work-done/templates/context.md +161 -0
  76. package/get-your-work-done/templates/continue-here.md +78 -0
  77. package/get-your-work-done/templates/discovery.md +146 -0
  78. package/get-your-work-done/templates/issues.md +32 -0
  79. package/get-your-work-done/templates/milestone-archive.md +123 -0
  80. package/get-your-work-done/templates/milestone-context.md +93 -0
  81. package/get-your-work-done/templates/milestone.md +115 -0
  82. package/get-your-work-done/templates/phase-prompt.md +303 -0
  83. package/get-your-work-done/templates/project.md +184 -0
  84. package/get-your-work-done/templates/research.md +529 -0
  85. package/get-your-work-done/templates/roadmap.md +196 -0
  86. package/get-your-work-done/templates/state.md +210 -0
  87. package/get-your-work-done/templates/summary.md +273 -0
  88. package/get-your-work-done/templates/uat-issues.md +143 -0
  89. package/get-your-work-done/workflows/complete-milestone.md +643 -0
  90. package/get-your-work-done/workflows/create-milestone.md +416 -0
  91. package/get-your-work-done/workflows/create-roadmap.md +481 -0
  92. package/get-your-work-done/workflows/discovery-phase.md +293 -0
  93. package/get-your-work-done/workflows/discuss-milestone.md +236 -0
  94. package/get-your-work-done/workflows/discuss-phase.md +247 -0
  95. package/get-your-work-done/workflows/execute-phase.md +1625 -0
  96. package/get-your-work-done/workflows/list-phase-assumptions.md +178 -0
  97. package/get-your-work-done/workflows/map-codebase.md +434 -0
  98. package/get-your-work-done/workflows/plan-phase.md +488 -0
  99. package/get-your-work-done/workflows/research-phase.md +436 -0
  100. package/get-your-work-done/workflows/resume-project.md +287 -0
  101. package/get-your-work-done/workflows/transition.md +580 -0
  102. package/get-your-work-done/workflows/verify-work.md +202 -0
  103. package/lib/automation/dependency-analyzer.js +635 -0
  104. package/lib/automation/doc-generator.js +643 -0
  105. package/lib/automation/index.js +42 -0
  106. package/lib/automation/test-generator.js +628 -0
  107. package/lib/context/context-analyzer.js +554 -0
  108. package/lib/context/context-cache.js +426 -0
  109. package/lib/context/context-predictor.js +622 -0
  110. package/lib/context/index.js +44 -0
  111. package/lib/memory/confidence-calibrator.js +484 -0
  112. package/lib/memory/feedback-collector.js +551 -0
  113. package/lib/memory/global-memory.js +465 -0
  114. package/lib/memory/index.js +75 -0
  115. package/lib/memory/pattern-aggregator.js +487 -0
  116. package/lib/memory/team-sync.js +501 -0
  117. package/lib/profile/index.js +24 -0
  118. package/lib/profile/pattern-learner.js +303 -0
  119. package/lib/profile/profile-manager.js +445 -0
  120. package/lib/questioning/index.js +49 -0
  121. package/lib/questioning/question-engine.js +311 -0
  122. package/lib/questioning/question-templates.js +315 -0
  123. package/lib/validators/command-validator.js +188 -0
  124. package/lib/validators/index.js +29 -0
  125. package/lib/validators/schema-validator.js +183 -0
  126. package/package.json +61 -0
package/bin/install.js ADDED
@@ -0,0 +1,348 @@
1
+ #!/usr/bin/env node
2
+
3
+ const fs = require('fs');
4
+ const path = require('path');
5
+ const os = require('os');
6
+ const readline = require('readline');
7
+
8
+ // Colors
9
+ const cyan = '\x1b[36m';
10
+ const green = '\x1b[32m';
11
+ const yellow = '\x1b[33m';
12
+ const red = '\x1b[31m';
13
+ const dim = '\x1b[2m';
14
+ const reset = '\x1b[0m';
15
+
16
+ // Get version from package.json
17
+ const pkg = require('../package.json');
18
+
19
+ const banner = `
20
+ ${cyan} ██████╗ ██╗ ██╗██╗ ██╗██████╗
21
+ ██╔════╝ ╚██╗ ██╔╝██║ ██║██╔══██╗
22
+ ██║ ███╗ ╚████╔╝ ██║ █╗ ██║██║ ██║
23
+ ██║ ██║ ╚██╔╝ ██║███╗██║██║ ██║
24
+ ╚██████╔╝ ██║ ╚███╔███╔╝██████╔╝
25
+ ╚═════╝ ╚═╝ ╚══╝╚══╝ ╚═════╝${reset}
26
+
27
+ PMP - Get Your Work Done ${dim}v${pkg.version}${reset}
28
+ A meta-prompting, context engineering and spec-driven
29
+ development system for Claude Code by cyberbloke9.
30
+ `;
31
+
32
+ // Parse args
33
+ const args = process.argv.slice(2);
34
+ const hasGlobal = args.includes('--global') || args.includes('-g');
35
+ const hasLocal = args.includes('--local') || args.includes('-l');
36
+
37
+ // Parse --config-dir argument
38
+ function parseConfigDirArg() {
39
+ const configDirIndex = args.findIndex(arg => arg === '--config-dir' || arg === '-c');
40
+ if (configDirIndex !== -1) {
41
+ const nextArg = args[configDirIndex + 1];
42
+ if (!nextArg || nextArg.startsWith('-')) {
43
+ console.error(` ${yellow}--config-dir requires a path argument${reset}`);
44
+ process.exit(1);
45
+ }
46
+ return nextArg;
47
+ }
48
+ const configDirArg = args.find(arg => arg.startsWith('--config-dir=') || arg.startsWith('-c='));
49
+ if (configDirArg) {
50
+ return configDirArg.split('=')[1];
51
+ }
52
+ return null;
53
+ }
54
+ const explicitConfigDir = parseConfigDirArg();
55
+ const hasHelp = args.includes('--help') || args.includes('-h');
56
+
57
+ console.log(banner);
58
+
59
+ // Show help if requested
60
+ if (hasHelp) {
61
+ console.log(` ${yellow}Usage:${reset} npx pmp-gywd [options]
62
+
63
+ ${yellow}Options:${reset}
64
+ ${cyan}-g, --global${reset} Install globally (to Claude config directory)
65
+ ${cyan}-l, --local${reset} Install locally (to ./.claude in current directory)
66
+ ${cyan}-c, --config-dir <path>${reset} Specify custom Claude config directory
67
+ ${cyan}-h, --help${reset} Show this help message
68
+
69
+ ${yellow}Examples:${reset}
70
+ ${dim}# Install to default ~/.claude directory${reset}
71
+ npx pmp-gywd --global
72
+
73
+ ${dim}# Install to custom config directory${reset}
74
+ npx pmp-gywd --global --config-dir ~/.claude-bc
75
+
76
+ ${dim}# Install to current project only${reset}
77
+ npx pmp-gywd --local
78
+
79
+ ${yellow}Notes:${reset}
80
+ The --config-dir option is useful when you have multiple Claude Code
81
+ configurations. It takes priority over CLAUDE_CONFIG_DIR env variable.
82
+ `);
83
+ process.exit(0);
84
+ }
85
+
86
+ /**
87
+ * Print error message and exit
88
+ */
89
+ function exitWithError(message, details = null) {
90
+ console.error(`\n ${red}Error:${reset} ${message}`);
91
+ if (details) {
92
+ console.error(` ${dim}${details}${reset}`);
93
+ }
94
+ console.error(`\n ${dim}If this persists, please report at:${reset}`);
95
+ console.error(` ${cyan}https://github.com/cyberbloke9/pmp-gwyd/issues${reset}\n`);
96
+ process.exit(1);
97
+ }
98
+
99
+ /**
100
+ * Expand ~ to home directory
101
+ */
102
+ function expandTilde(filePath) {
103
+ if (!filePath) return filePath;
104
+ if (filePath === '~') return os.homedir();
105
+ if (filePath.startsWith('~/')) {
106
+ return path.join(os.homedir(), filePath.slice(2));
107
+ }
108
+ return filePath;
109
+ }
110
+
111
+ /**
112
+ * Validate path is safe (no path traversal)
113
+ */
114
+ function validatePath(targetPath) {
115
+ const resolved = path.resolve(targetPath);
116
+ // Check for null bytes (security)
117
+ if (targetPath.includes('\0')) {
118
+ return { valid: false, reason: 'Path contains invalid characters' };
119
+ }
120
+ return { valid: true, resolved };
121
+ }
122
+
123
+ /**
124
+ * Safely create directory
125
+ */
126
+ function safeCreateDir(dirPath) {
127
+ const validation = validatePath(dirPath);
128
+ if (!validation.valid) {
129
+ throw new Error(validation.reason);
130
+ }
131
+
132
+ try {
133
+ fs.mkdirSync(dirPath, { recursive: true });
134
+ } catch (err) {
135
+ if (err.code === 'EACCES') {
136
+ throw new Error(`Permission denied: Cannot create directory at ${dirPath}`);
137
+ } else if (err.code === 'ENOSPC') {
138
+ throw new Error('Disk is full. Please free up space and try again.');
139
+ } else if (err.code === 'EROFS') {
140
+ throw new Error('Cannot write to read-only filesystem.');
141
+ } else {
142
+ throw new Error(`Failed to create directory: ${err.message}`);
143
+ }
144
+ }
145
+ }
146
+
147
+ /**
148
+ * Safely read file
149
+ */
150
+ function safeReadFile(filePath) {
151
+ try {
152
+ return fs.readFileSync(filePath, 'utf8');
153
+ } catch (err) {
154
+ if (err.code === 'ENOENT') {
155
+ throw new Error(`File not found: ${filePath}`);
156
+ } else if (err.code === 'EACCES') {
157
+ throw new Error(`Permission denied: Cannot read ${filePath}`);
158
+ } else {
159
+ throw new Error(`Failed to read file: ${err.message}`);
160
+ }
161
+ }
162
+ }
163
+
164
+ /**
165
+ * Safely write file
166
+ */
167
+ function safeWriteFile(filePath, content) {
168
+ try {
169
+ fs.writeFileSync(filePath, content);
170
+ } catch (err) {
171
+ if (err.code === 'EACCES') {
172
+ throw new Error(`Permission denied: Cannot write to ${filePath}`);
173
+ } else if (err.code === 'ENOSPC') {
174
+ throw new Error('Disk is full. Please free up space and try again.');
175
+ } else if (err.code === 'EROFS') {
176
+ throw new Error('Cannot write to read-only filesystem.');
177
+ } else {
178
+ throw new Error(`Failed to write file: ${err.message}`);
179
+ }
180
+ }
181
+ }
182
+
183
+ /**
184
+ * Safely copy file
185
+ */
186
+ function safeCopyFile(src, dest) {
187
+ try {
188
+ fs.copyFileSync(src, dest);
189
+ } catch (err) {
190
+ if (err.code === 'ENOENT') {
191
+ throw new Error(`Source file not found: ${src}`);
192
+ } else if (err.code === 'EACCES') {
193
+ throw new Error(`Permission denied: Cannot copy to ${dest}`);
194
+ } else if (err.code === 'ENOSPC') {
195
+ throw new Error('Disk is full. Please free up space and try again.');
196
+ } else {
197
+ throw new Error(`Failed to copy file: ${err.message}`);
198
+ }
199
+ }
200
+ }
201
+
202
+ /**
203
+ * Safely read directory
204
+ */
205
+ function safeReadDir(dirPath) {
206
+ try {
207
+ return fs.readdirSync(dirPath, { withFileTypes: true });
208
+ } catch (err) {
209
+ if (err.code === 'ENOENT') {
210
+ throw new Error(`Directory not found: ${dirPath}`);
211
+ } else if (err.code === 'EACCES') {
212
+ throw new Error(`Permission denied: Cannot read directory ${dirPath}`);
213
+ } else {
214
+ throw new Error(`Failed to read directory: ${err.message}`);
215
+ }
216
+ }
217
+ }
218
+
219
+ /**
220
+ * Recursively copy directory with path replacement in .md files
221
+ */
222
+ function copyWithPathReplacement(srcDir, destDir, pathPrefix) {
223
+ safeCreateDir(destDir);
224
+ const entries = safeReadDir(srcDir);
225
+
226
+ for (const entry of entries) {
227
+ const srcPath = path.join(srcDir, entry.name);
228
+ const destPath = path.join(destDir, entry.name);
229
+
230
+ if (entry.isDirectory()) {
231
+ copyWithPathReplacement(srcPath, destPath, pathPrefix);
232
+ } else if (entry.name.endsWith('.md')) {
233
+ let content = safeReadFile(srcPath);
234
+ content = content.replace(/~\/\.claude\//g, pathPrefix);
235
+ safeWriteFile(destPath, content);
236
+ } else {
237
+ safeCopyFile(srcPath, destPath);
238
+ }
239
+ }
240
+ }
241
+
242
+ /**
243
+ * Install to the specified directory
244
+ */
245
+ function install(isGlobal) {
246
+ const src = path.join(__dirname, '..');
247
+
248
+ // Validate source directory exists
249
+ if (!fs.existsSync(src)) {
250
+ exitWithError('Installation source not found.', 'Package may be corrupted. Try reinstalling.');
251
+ }
252
+
253
+ const configDir = expandTilde(explicitConfigDir) || expandTilde(process.env.CLAUDE_CONFIG_DIR);
254
+ const defaultGlobalDir = configDir || path.join(os.homedir(), '.claude');
255
+ const claudeDir = isGlobal ? defaultGlobalDir : path.join(process.cwd(), '.claude');
256
+
257
+ // Validate destination path
258
+ const validation = validatePath(claudeDir);
259
+ if (!validation.valid) {
260
+ exitWithError(`Invalid installation path: ${claudeDir}`, validation.reason);
261
+ }
262
+
263
+ const locationLabel = isGlobal
264
+ ? claudeDir.replace(os.homedir(), '~')
265
+ : claudeDir.replace(process.cwd(), '.');
266
+
267
+ const pathPrefix = isGlobal
268
+ ? (configDir ? `${claudeDir}/` : '~/.claude/')
269
+ : './.claude/';
270
+
271
+ console.log(` Installing to ${cyan}${locationLabel}${reset}\n`);
272
+
273
+ try {
274
+ // Create commands directory
275
+ const commandsDir = path.join(claudeDir, 'commands');
276
+ safeCreateDir(commandsDir);
277
+
278
+ // Copy commands/gywd
279
+ const gywdSrc = path.join(src, 'commands', 'gywd');
280
+ const gywdDest = path.join(commandsDir, 'gywd');
281
+
282
+ if (!fs.existsSync(gywdSrc)) {
283
+ exitWithError('Commands source not found.', `Expected at: ${gywdSrc}`);
284
+ }
285
+
286
+ copyWithPathReplacement(gywdSrc, gywdDest, pathPrefix);
287
+ console.log(` ${green}✓${reset} Installed commands/gywd`);
288
+
289
+ // Copy get-your-work-done
290
+ const skillSrc = path.join(src, 'get-your-work-done');
291
+ const skillDest = path.join(claudeDir, 'get-your-work-done');
292
+
293
+ if (!fs.existsSync(skillSrc)) {
294
+ exitWithError('Skills source not found.', `Expected at: ${skillSrc}`);
295
+ }
296
+
297
+ copyWithPathReplacement(skillSrc, skillDest, pathPrefix);
298
+ console.log(` ${green}✓${reset} Installed get-your-work-done`);
299
+
300
+ console.log(`
301
+ ${green}Done!${reset} Run ${cyan}/gywd:help${reset} to get started.
302
+ `);
303
+ } catch (err) {
304
+ exitWithError('Installation failed.', err.message);
305
+ }
306
+ }
307
+
308
+ /**
309
+ * Prompt for install location
310
+ */
311
+ function promptLocation() {
312
+ const rl = readline.createInterface({
313
+ input: process.stdin,
314
+ output: process.stdout,
315
+ });
316
+
317
+ const configDir = expandTilde(explicitConfigDir) || expandTilde(process.env.CLAUDE_CONFIG_DIR);
318
+ const globalPath = configDir || path.join(os.homedir(), '.claude');
319
+ const globalLabel = globalPath.replace(os.homedir(), '~');
320
+
321
+ console.log(` ${yellow}Where would you like to install?${reset}
322
+
323
+ ${cyan}1${reset}) Global ${dim}(${globalLabel})${reset} - available in all projects
324
+ ${cyan}2${reset}) Local ${dim}(./.claude)${reset} - this project only
325
+ `);
326
+
327
+ rl.question(` Choice ${dim}[1]${reset}: `, (answer) => {
328
+ rl.close();
329
+ const choice = answer.trim() || '1';
330
+ const isGlobal = choice !== '2';
331
+ install(isGlobal);
332
+ });
333
+ }
334
+
335
+ // Main
336
+ if (hasGlobal && hasLocal) {
337
+ console.error(` ${yellow}Cannot specify both --global and --local${reset}`);
338
+ process.exit(1);
339
+ } else if (explicitConfigDir && hasLocal) {
340
+ console.error(` ${yellow}Cannot use --config-dir with --local${reset}`);
341
+ process.exit(1);
342
+ } else if (hasGlobal) {
343
+ install(true);
344
+ } else if (hasLocal) {
345
+ install(false);
346
+ } else {
347
+ promptLocation();
348
+ }
@@ -0,0 +1,207 @@
1
+ ---
2
+ name: GYWD:add-phase
3
+ description: Add phase to end of current milestone in roadmap
4
+ argument-hint: <description>
5
+ allowed-tools:
6
+ - Read
7
+ - Write
8
+ - Bash
9
+ ---
10
+
11
+ <objective>
12
+ Add a new integer phase to the end of the current milestone in the roadmap.
13
+
14
+ This command appends sequential phases to the current milestone's phase list, automatically calculating the next phase number based on existing phases.
15
+
16
+ Purpose: Add planned work discovered during execution that belongs at the end of current milestone.
17
+ </objective>
18
+
19
+ <execution_context>
20
+ @.planning/ROADMAP.md
21
+ @.planning/STATE.md
22
+ </execution_context>
23
+
24
+ <process>
25
+
26
+ <step name="parse_arguments">
27
+ Parse the command arguments:
28
+ - All arguments become the phase description
29
+ - Example: `/gywd:add-phase Add authentication` → description = "Add authentication"
30
+ - Example: `/gywd:add-phase Fix critical performance issues` → description = "Fix critical performance issues"
31
+
32
+ If no arguments provided:
33
+
34
+ ```
35
+ ERROR: Phase description required
36
+ Usage: /gywd:add-phase <description>
37
+ Example: /gywd:add-phase Add authentication system
38
+ ```
39
+
40
+ Exit.
41
+ </step>
42
+
43
+ <step name="load_roadmap">
44
+ Load the roadmap file:
45
+
46
+ ```bash
47
+ if [ -f .planning/ROADMAP.md ]; then
48
+ ROADMAP=".planning/ROADMAP.md"
49
+ else
50
+ echo "ERROR: No roadmap found (.planning/ROADMAP.md)"
51
+ exit 1
52
+ fi
53
+ ```
54
+
55
+ Read roadmap content for parsing.
56
+ </step>
57
+
58
+ <step name="find_current_milestone">
59
+ Parse the roadmap to find the current milestone section:
60
+
61
+ 1. Locate the "## Current Milestone:" heading
62
+ 2. Extract milestone name and version
63
+ 3. Identify all phases under this milestone (before next "---" separator or next milestone heading)
64
+ 4. Parse existing phase numbers (including decimals if present)
65
+
66
+ Example structure:
67
+
68
+ ```
69
+ ## Current Milestone: v1.0 Foundation
70
+
71
+ ### Phase 4: Focused Command System
72
+ ### Phase 5: Path Routing & Validation
73
+ ### Phase 6: Documentation & Distribution
74
+ ```
75
+
76
+ </step>
77
+
78
+ <step name="calculate_next_phase">
79
+ Find the highest integer phase number in the current milestone:
80
+
81
+ 1. Extract all phase numbers from phase headings (### Phase N:)
82
+ 2. Filter to integer phases only (ignore decimals like 4.1, 4.2)
83
+ 3. Find the maximum integer value
84
+ 4. Add 1 to get the next phase number
85
+
86
+ Example: If phases are 4, 5, 5.1, 6 → next is 7
87
+
88
+ Format as two-digit: `printf "%02d" $next_phase`
89
+ </step>
90
+
91
+ <step name="generate_slug">
92
+ Convert the phase description to a kebab-case slug:
93
+
94
+ ```bash
95
+ # Example transformation:
96
+ # "Add authentication" → "add-authentication"
97
+ # "Fix critical performance issues" → "fix-critical-performance-issues"
98
+
99
+ slug=$(echo "$description" | tr '[:upper:]' '[:lower:]' | sed 's/[^a-z0-9]/-/g' | sed 's/--*/-/g' | sed 's/^-//;s/-$//')
100
+ ```
101
+
102
+ Phase directory name: `{two-digit-phase}-{slug}`
103
+ Example: `07-add-authentication`
104
+ </step>
105
+
106
+ <step name="create_phase_directory">
107
+ Create the phase directory structure:
108
+
109
+ ```bash
110
+ phase_dir=".planning/phases/${phase_num}-${slug}"
111
+ mkdir -p "$phase_dir"
112
+ ```
113
+
114
+ Confirm: "Created directory: $phase_dir"
115
+ </step>
116
+
117
+ <step name="update_roadmap">
118
+ Add the new phase entry to the roadmap:
119
+
120
+ 1. Find the insertion point (after last phase in current milestone, before "---" separator)
121
+ 2. Insert new phase heading:
122
+
123
+ ```
124
+ ### Phase {N}: {Description}
125
+
126
+ **Goal:** [To be planned]
127
+ **Depends on:** Phase {N-1}
128
+ **Plans:** 0 plans
129
+
130
+ Plans:
131
+ - [ ] TBD (run /gywd:plan-phase {N} to break down)
132
+
133
+ **Details:**
134
+ [To be added during planning]
135
+ ```
136
+
137
+ 3. Write updated roadmap back to file
138
+
139
+ Preserve all other content exactly (formatting, spacing, other phases).
140
+ </step>
141
+
142
+ <step name="update_project_state">
143
+ Update STATE.md to reflect the new phase:
144
+
145
+ 1. Read `.planning/STATE.md`
146
+ 2. Under "## Current Position" → "**Next Phase:**" add reference to new phase
147
+ 3. Under "## Accumulated Context" → "### Roadmap Evolution" add entry:
148
+ ```
149
+ - Phase {N} added: {description}
150
+ ```
151
+
152
+ If "Roadmap Evolution" section doesn't exist, create it.
153
+ </step>
154
+
155
+ <step name="completion">
156
+ Present completion summary:
157
+
158
+ ```
159
+ Phase {N} added to current milestone:
160
+ - Description: {description}
161
+ - Directory: .planning/phases/{phase-num}-{slug}/
162
+ - Status: Not planned yet
163
+
164
+ Roadmap updated: {roadmap-path}
165
+ Project state updated: .planning/STATE.md
166
+
167
+ ---
168
+
169
+ ## ▶ Next Up
170
+
171
+ **Phase {N}: {description}**
172
+
173
+ `/gywd:plan-phase {N}`
174
+
175
+ <sub>`/clear` first → fresh context window</sub>
176
+
177
+ ---
178
+
179
+ **Also available:**
180
+ - `/gywd:add-phase <description>` — add another phase
181
+ - Review roadmap
182
+
183
+ ---
184
+ ```
185
+ </step>
186
+
187
+ </process>
188
+
189
+ <anti_patterns>
190
+
191
+ - Don't modify phases outside current milestone
192
+ - Don't renumber existing phases
193
+ - Don't use decimal numbering (that's /gywd:insert-phase)
194
+ - Don't create plans yet (that's /gywd:plan-phase)
195
+ - Don't commit changes (user decides when to commit)
196
+ </anti_patterns>
197
+
198
+ <success_criteria>
199
+ Phase addition is complete when:
200
+
201
+ - [ ] Phase directory created: `.planning/phases/{NN}-{slug}/`
202
+ - [ ] Roadmap updated with new phase entry
203
+ - [ ] STATE.md updated with roadmap evolution note
204
+ - [ ] New phase appears at end of current milestone
205
+ - [ ] Next phase number calculated correctly (ignoring decimals)
206
+ - [ ] User informed of next steps
207
+ </success_criteria>