jettypod 4.1.2 β 4.1.4
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/.nvmrc +1 -0
- package/docs/COMPLETE-TESTING-STRATEGY.md +970 -0
- package/docs/DECISIONS.md +10 -12
- package/docs/NODE_VERSION.md +83 -0
- package/docs/TDD-INFRASTRUCTURE-STRATEGY.md +1374 -0
- package/docs/TESTING-FOR-NON-ENGINEERS.md +1588 -0
- package/docs/TESTING-STRATEGY-AUDIT.md +698 -0
- package/hooks/post-checkout +17 -0
- package/hooks/post-merge +17 -0
- package/hooks/pre-commit +30 -0
- package/jettypod.js +259 -120
- package/lib/coverage-tracker.js +218 -0
- package/lib/database.js +2 -0
- package/lib/db-export.js +192 -0
- package/lib/db-import.js +193 -0
- package/lib/external-transition-handler.js +32 -0
- package/lib/git-hook-helpers.js +174 -0
- package/lib/git-root.js +90 -0
- package/lib/infrastructure-chore-generator.js +45 -0
- package/lib/install-hooks.js +52 -0
- package/lib/jettypod-backup.js +238 -0
- package/lib/merge-lock.js +193 -0
- package/lib/migrations/012-add-worktree-path.js +38 -0
- package/lib/migrations/013-worktrees-table.js +86 -0
- package/lib/migrations/014-migrate-worktree-data.js +161 -0
- package/lib/migrations/015-merge-locks-table.js +67 -0
- package/lib/pattern-finder.js +152 -0
- package/lib/process-manager.js +140 -0
- package/lib/production-standards-reader.js +13 -2
- package/lib/production-standards-writer.js +85 -0
- package/lib/skills/feature-planning/dry-run-validator.js +135 -0
- package/lib/skills/feature-planning/validation-formatter.js +160 -0
- package/lib/smart-conflict-detection.js +168 -0
- package/lib/smart-fetch-rebase.js +614 -0
- package/lib/step-definition-parser.js +76 -0
- package/lib/unit-test-generator.js +232 -0
- package/lib/verification-command-generator.js +66 -0
- package/lib/worktree-diagnostics.js +413 -0
- package/lib/worktree-facade.js +174 -0
- package/lib/worktree-manager.js +636 -0
- package/lib/worktree-reconciler.js +429 -0
- package/package.json +30 -3
- package/skills-templates/external-transition/SKILL.md +34 -3
- package/skills-templates/feature-planning/SKILL.md +190 -24
- package/skills-templates/production-mode/SKILL.md +127 -9
- package/skills-templates/speed-mode/SKILL.md +454 -51
- package/skills-templates/stable-mode/SKILL.md +285 -76
- package/.claude/PROTECT_SKILLS.md +0 -28
- package/.claude/settings.json +0 -24
- package/.claude/settings.local.json +0 -16
- package/.claude/skills/epic-planning/SKILL.md +0 -297
- package/.claude/skills/external-transition/SKILL.md +0 -384
- package/.claude/skills/feature-planning/SKILL.md +0 -464
- package/.claude/skills/production-mode/SKILL.md +0 -369
- package/.claude/skills/speed-mode/SKILL.md +0 -481
- package/.claude/skills/stable-mode/SKILL.md +0 -713
- package/.claude/skills.backup-2025-11-10T23-33-09-368Z/epic-planning/SKILL.md +0 -297
- package/.claude/skills.backup-2025-11-10T23-33-09-368Z/feature-planning/SKILL.md +0 -464
- package/.claude/skills.backup-2025-11-10T23-33-09-368Z/speed-mode/SKILL.md +0 -467
- package/.claude/skills.backup-2025-11-10T23-33-09-368Z/stable-mode/SKILL.md +0 -673
- package/.claude/skills.backup-2025-11-11T16-15-10-070Z/epic-discover/SKILL.md +0 -297
- package/.claude/skills.backup-2025-11-11T16-42-43-212Z/epic-planning/SKILL.md +0 -297
- package/.claude/skills.backup-2025-11-11T16-42-43-212Z/feature-planning/SKILL.md +0 -464
- package/.claude/skills.backup-2025-11-11T16-42-43-212Z/speed-mode/SKILL.md +0 -467
- package/.claude/skills.backup-2025-11-11T16-42-43-212Z/stable-mode/SKILL.md +0 -673
- package/.claude/skills.backup-2025-11-11T17-06-09-783Z/epic-planning/SKILL.md +0 -297
- package/.claude/skills.backup-2025-11-11T17-06-09-783Z/feature-planning/SKILL.md +0 -464
- package/.claude/skills.backup-2025-11-11T17-06-09-783Z/speed-mode/SKILL.md +0 -467
- package/.claude/skills.backup-2025-11-11T17-06-09-783Z/stable-mode/SKILL.md +0 -673
- package/.devpod/current-work.json +0 -10
- package/.devpod/work.db +0 -0
- package/.github/workflows/test-safety.yml +0 -85
- package/.jettypod/config.json +0 -5
- package/.jettypod/current-work.json +0 -10
- package/.jettypod/hooks/README.md +0 -77
- package/.jettypod/hooks/protect-claude-md.js +0 -338
- package/.jettypod/test-work.db +0 -0
- package/.jettypod/work.db +0 -0
- package/CLAUDE.md +0 -49
- package/SPEED-STABLE-AUDIT.md +0 -853
- package/SYSTEM-BEHAVIOR.md +0 -2199
- package/TEST_SAFETY_AUDIT.md +0 -314
- package/TEST_SAFETY_IMPLEMENTATION.md +0 -97
- package/cucumber-report.html +0 -45
- package/dist/devpod-linux +0 -0
- package/dist/devpod-macos +0 -0
- package/dist/devpod-win.exe +0 -0
- package/docs/features/jettypod-standards-explained.md +0 -543
- package/docs/features/standards-inventory.md +0 -257
- package/features/auto-generate-production-chores.feature +0 -13
- package/features/backlog-command.feature +0 -26
- package/features/backlog-filtering-production.feature +0 -10
- package/features/claude-md-protection/steps.js +0 -498
- package/features/decisions/index.js +0 -490
- package/features/decisions/index.test.js +0 -208
- package/features/fix-text-wrapping.feature +0 -42
- package/features/git-hooks/git-hooks.feature +0 -30
- package/features/git-hooks/index.js +0 -93
- package/features/git-hooks/index.test.js +0 -137
- package/features/git-hooks/post-commit +0 -56
- package/features/git-hooks/post-merge +0 -47
- package/features/git-hooks/pre-commit +0 -28
- package/features/git-hooks/simple-steps.js +0 -53
- package/features/git-hooks/simple-test.feature +0 -10
- package/features/git-hooks/steps.js +0 -196
- package/features/jettypod-update-command.feature +0 -46
- package/features/mode-prompts/index.js +0 -95
- package/features/mode-prompts/simple-steps.js +0 -44
- package/features/mode-prompts/simple-test.feature +0 -9
- package/features/mode-prompts/validation.test.js +0 -120
- package/features/multiple-claude-instances.feature +0 -121
- package/features/production-mode-skill.feature +0 -121
- package/features/refactor-mode/steps.js +0 -217
- package/features/refactor-mode.feature +0 -49
- package/features/simplify-external-transition.feature +0 -166
- package/features/skills-update/index.test.js +0 -216
- package/features/step_definitions/backlog-command.steps.js +0 -37
- package/features/step_definitions/fix-text-wrapping.steps.js +0 -271
- package/features/step_definitions/multiple-claude-instances.steps.js +0 -621
- package/features/step_definitions/production-mode-skill.steps.js +0 -862
- package/features/step_definitions/simplify-external-transition.steps.js +0 -370
- package/features/step_definitions/terminal-logo.steps.js +0 -145
- package/features/step_definitions/update-command.steps.js +0 -183
- package/features/support/hooks.js +0 -9
- package/features/terminal-logo/index.js +0 -39
- package/features/terminal-logo/terminal-logo.feature +0 -30
- package/features/update-command/index.js +0 -181
- package/features/update-command/index.test.js +0 -225
- package/features/work-commands/bug-workflow-display.feature +0 -22
- package/features/work-commands/index.js +0 -498
- package/features/work-commands/simple-steps.js +0 -69
- package/features/work-commands/stable-tests.feature +0 -57
- package/features/work-commands/steps.js +0 -1174
- package/features/work-commands/validation.test.js +0 -88
- package/features/work-commands/work-commands.feature +0 -13
- package/features/work-tracking/discovery-validation.test.js +0 -228
- package/features/work-tracking/index.js +0 -1921
- package/features/work-tracking/mode-required.feature +0 -112
- package/features/work-tracking/phase-tracking.test.js +0 -482
- package/features/work-tracking/prototype-tracking.test.js +0 -485
- package/features/work-tracking/tree-view.test.js +0 -310
- package/features/work-tracking/work-set-mode.feature +0 -71
- package/features/work-tracking/work-start-mode.feature +0 -88
- package/full-test.txt +0 -0
- package/lib/bug-workflow.test.js +0 -177
- package/lib/claudemd.test.js +0 -195
- package/lib/config.test.js +0 -511
- package/lib/constants.test.js +0 -164
- package/lib/current-work.test.js +0 -146
- package/lib/database-project-config.test.js +0 -111
- package/lib/database.test.js +0 -106
- package/lib/decisions-generator.test.js +0 -457
- package/lib/decisions-helpers.test.js +0 -310
- package/lib/git-coordinator.js +0 -167
- package/lib/git.test.js +0 -145
- package/lib/migrations/002-default-work-item-modes.test.js +0 -351
- package/lib/production-chore-generator.test.js +0 -432
- package/lib/production-context-detector.test.js +0 -277
- package/lib/production-scenario-appender.test.js +0 -235
- package/lib/production-scenario-validator.test.js +0 -246
- package/lib/production-standards-reader.test.js +0 -270
- package/lib/project-state.test.js +0 -92
- package/lib/push-queue.js +0 -417
- package/lib/queue-processor.js +0 -74
- package/lib/test-helpers.js +0 -202
- package/lib/test-helpers.test.js +0 -255
- package/prototypes/2025-01-11-production-mode-autonomous.js +0 -119
- package/prototypes/2025-01-11-production-mode-collaborative.js +0 -166
- package/prototypes/2025-01-11-production-mode-guided.js +0 -217
- package/prototypes/2025-01-11-production-mode-smart-context.js +0 -347
- package/prototypes/2025-01-11-production-standards-example.md +0 -204
- package/prototypes/2025-11-10-backlog-filtering-tree-aware.js +0 -242
- package/prototypes/test/index.html +0 -1
- package/setup-dist-repo.sh +0 -68
- package/test-production-standards-engine.js +0 -130
- package/test-results.json +0 -2195
- package/test-safety-check.sh +0 -80
- package/work-item-tracking-plan.md +0 -199
- /package/{.jettypod/devpod.db β jettypod.db} +0 -0
|
@@ -20,14 +20,21 @@ You'll receive context about:
|
|
|
20
20
|
|
|
21
21
|
### Step 2: Check Epic Architectural Decisions
|
|
22
22
|
|
|
23
|
-
**CRITICAL:** If this feature belongs to an epic, check for existing architectural decisions
|
|
23
|
+
**CRITICAL:** If this feature belongs to an epic, check for existing architectural decisions.
|
|
24
|
+
|
|
25
|
+
**β οΈ IMPORTANT - USE EXACT CODE BELOW:**
|
|
26
|
+
- Import from `./lib/decisions-helpers` (NOT `./features/decisions/index.js`)
|
|
27
|
+
- The function name is `getDecisionsForEpic` (matches the import)
|
|
28
|
+
- Use `await` because it returns a Promise
|
|
29
|
+
|
|
30
|
+
**Execute this EXACT code (copy/paste as-is):**
|
|
24
31
|
|
|
25
32
|
```javascript
|
|
26
|
-
const { getDecisionsForEpic } = require('
|
|
33
|
+
const { getDecisionsForEpic } = require('./lib/decisions-helpers');
|
|
27
34
|
|
|
28
35
|
if (parentEpicId) {
|
|
29
36
|
const epicDecisions = await getDecisionsForEpic(parentEpicId);
|
|
30
|
-
|
|
37
|
+
console.log('Epic decisions:', JSON.stringify(epicDecisions, null, 2));
|
|
31
38
|
}
|
|
32
39
|
```
|
|
33
40
|
|
|
@@ -77,6 +84,8 @@ Here are 3 different approaches for [feature name]:
|
|
|
77
84
|
- *[Alternative 1]*: [Brief] - Not selected because [reason]
|
|
78
85
|
- *[Alternative 2]*: [Brief] - Not selected because [reason]
|
|
79
86
|
|
|
87
|
+
**π‘ Recommendation:** [State which option you recommend and why - 2-3 sentences explaining the reasoning]
|
|
88
|
+
|
|
80
89
|
Would you like me to create working prototypes of these approaches?
|
|
81
90
|
```
|
|
82
91
|
|
|
@@ -184,9 +193,120 @@ Scenario: User successfully logs in with valid credentials
|
|
|
184
193
|
And I have an active session token
|
|
185
194
|
```
|
|
186
195
|
|
|
196
|
+
### Step 6.5: Validate BDD Infrastructure
|
|
197
|
+
|
|
198
|
+
**CRITICAL:** After creating both scenario and step definition files, automatically validate them with cucumber dry-run to catch errors immediately.
|
|
199
|
+
|
|
200
|
+
**Execute validation:**
|
|
201
|
+
|
|
202
|
+
```javascript
|
|
203
|
+
const { validateBddInfrastructure } = require('../../lib/skills/feature-planning/dry-run-validator');
|
|
204
|
+
const { formatValidationResult } = require('../../lib/skills/feature-planning/validation-formatter');
|
|
205
|
+
const path = require('path');
|
|
206
|
+
|
|
207
|
+
console.log('π§ͺ Validating BDD infrastructure...\n');
|
|
208
|
+
|
|
209
|
+
const featurePath = path.join(process.cwd(), 'features', '[feature-slug].feature');
|
|
210
|
+
const result = await validateBddInfrastructure(featurePath);
|
|
211
|
+
|
|
212
|
+
// Format and display results with colors and guidance
|
|
213
|
+
const formattedOutput = formatValidationResult(result, featurePath);
|
|
214
|
+
console.log(formattedOutput);
|
|
215
|
+
|
|
216
|
+
if (!result.success) {
|
|
217
|
+
console.log(''); // Extra line before halting
|
|
218
|
+
return; // Halt - do not generate chores yet
|
|
219
|
+
}
|
|
220
|
+
|
|
221
|
+
// Continue to Step 7
|
|
222
|
+
console.log(''); // Extra line before continuing
|
|
223
|
+
```
|
|
224
|
+
|
|
225
|
+
**Validation checks:**
|
|
226
|
+
- β
Feature file has valid Gherkin syntax
|
|
227
|
+
- β
All scenario steps have matching step definitions
|
|
228
|
+
- β
No duplicate step definitions
|
|
229
|
+
- β
Cucumber can parse the files
|
|
230
|
+
- β
Validation completes in < 5 seconds
|
|
231
|
+
|
|
232
|
+
**If validation fails:**
|
|
233
|
+
1. Show clear error messages with file locations
|
|
234
|
+
2. Provide actionable guidance on how to fix
|
|
235
|
+
3. DO NOT proceed to chore generation
|
|
236
|
+
4. Wait for user to fix issues
|
|
237
|
+
|
|
238
|
+
**If validation succeeds:**
|
|
239
|
+
1. Confirm success with checkmarks
|
|
240
|
+
2. Proceed immediately to Step 6.75
|
|
241
|
+
|
|
242
|
+
### Step 6.75: Scaffold Unit Test Files
|
|
243
|
+
|
|
244
|
+
**CRITICAL:** After BDD validation passes, scaffold empty unit test files for expected implementation files.
|
|
245
|
+
|
|
246
|
+
**Execute:**
|
|
247
|
+
|
|
248
|
+
```javascript
|
|
249
|
+
const { scaffoldUnitTestFile } = require('../../lib/unit-test-generator');
|
|
250
|
+
const path = require('path');
|
|
251
|
+
|
|
252
|
+
console.log('π Scaffolding unit test files...\n');
|
|
253
|
+
|
|
254
|
+
// Infer implementation files from chore breadcrumbs
|
|
255
|
+
// Parse "Files to create/modify" from each proposed chore
|
|
256
|
+
const implementationFiles = [];
|
|
257
|
+
|
|
258
|
+
// For each chore you're about to propose, extract file paths
|
|
259
|
+
// Example: if chore says "Files to create/modify: src/login.js, src/auth.js"
|
|
260
|
+
// Then implementationFiles = ['src/login.js', 'src/auth.js']
|
|
261
|
+
|
|
262
|
+
for (const chore of proposedChores) {
|
|
263
|
+
const filesMatch = chore.description.match(/Files to create\/modify:\s*([^\n]+)/);
|
|
264
|
+
if (filesMatch) {
|
|
265
|
+
const files = filesMatch[1].split(',').map(f => f.trim());
|
|
266
|
+
implementationFiles.push(...files);
|
|
267
|
+
}
|
|
268
|
+
}
|
|
269
|
+
|
|
270
|
+
// Remove duplicates
|
|
271
|
+
const uniqueFiles = [...new Set(implementationFiles)];
|
|
272
|
+
|
|
273
|
+
// Scaffold test files
|
|
274
|
+
const scaffoldedTests = [];
|
|
275
|
+
for (const filePath of uniqueFiles) {
|
|
276
|
+
if (filePath.endsWith('.js') && !filePath.includes('test')) {
|
|
277
|
+
try {
|
|
278
|
+
const testFile = scaffoldUnitTestFile(filePath);
|
|
279
|
+
scaffoldedTests.push(testFile);
|
|
280
|
+
console.log(` β
${testFile}`);
|
|
281
|
+
} catch (err) {
|
|
282
|
+
console.log(` β οΈ Could not scaffold ${filePath}: ${err.message}`);
|
|
283
|
+
}
|
|
284
|
+
}
|
|
285
|
+
}
|
|
286
|
+
|
|
287
|
+
if (scaffoldedTests.length > 0) {
|
|
288
|
+
console.log(`\nπ¦ Scaffolded ${scaffoldedTests.length} unit test files`);
|
|
289
|
+
console.log('These files have empty TODO placeholders - speed mode will fill them.\n');
|
|
290
|
+
} else {
|
|
291
|
+
console.log('No new test files to scaffold\n');
|
|
292
|
+
}
|
|
293
|
+
```
|
|
294
|
+
|
|
295
|
+
**Why scaffold now:**
|
|
296
|
+
- Creates test file structure before implementation
|
|
297
|
+
- Reminds developers tests are required
|
|
298
|
+
- Speed mode can update these TODO placeholders after GREEN
|
|
299
|
+
- Prevents "I'll add tests later" (they never do)
|
|
300
|
+
|
|
301
|
+
**What gets scaffolded:**
|
|
302
|
+
- Empty `test/[path]/[file].test.js` files
|
|
303
|
+
- Basic `describe()` blocks
|
|
304
|
+
- TODO placeholders for actual tests
|
|
305
|
+
- Won't overwrite existing test files
|
|
306
|
+
|
|
187
307
|
### Step 7: Propose Speed Mode Chores
|
|
188
308
|
|
|
189
|
-
**CRITICAL:** After
|
|
309
|
+
**CRITICAL:** After BDD validation passes, analyze the codebase and propose technical implementation chores with rich breadcrumbs for speed mode execution.
|
|
190
310
|
|
|
191
311
|
**Your analysis should consider:**
|
|
192
312
|
- The BDD scenarios (especially the happy path)
|
|
@@ -240,27 +360,66 @@ Sound good? Any adjustments?
|
|
|
240
360
|
**Then create the chores with rich descriptions:**
|
|
241
361
|
|
|
242
362
|
```javascript
|
|
243
|
-
//
|
|
363
|
+
// Import breadcrumb generators
|
|
364
|
+
const { parseStepDefinitions } = require('../../lib/step-definition-parser');
|
|
365
|
+
const { findSimilarPatterns } = require('../../lib/pattern-finder');
|
|
366
|
+
const { generateVerificationCommands } = require('../../lib/verification-command-generator');
|
|
244
367
|
const { create } = require('./features/work-tracking');
|
|
368
|
+
const path = require('path');
|
|
369
|
+
|
|
370
|
+
// Parse step definitions for verification breadcrumbs
|
|
371
|
+
const stepDefsPath = path.join(process.cwd(), 'features/step_definitions', `${featureSlug}.steps.js`);
|
|
372
|
+
const stepMap = parseStepDefinitions(stepDefsPath);
|
|
245
373
|
|
|
246
|
-
|
|
374
|
+
// For each confirmed chore:
|
|
375
|
+
for (const chore of confirmedChores) {
|
|
376
|
+
// Find similar patterns for implementation guidance
|
|
377
|
+
const patterns = findSimilarPatterns(chore.keywords || []);
|
|
378
|
+
|
|
379
|
+
// Build pattern references
|
|
380
|
+
const patternRefs = patterns.length > 0
|
|
381
|
+
? patterns.map(p => `${p.file} (${p.description})`).join('\n β’ ')
|
|
382
|
+
: 'No similar patterns found - create new implementation';
|
|
383
|
+
|
|
384
|
+
// Build step definition references with file:line
|
|
385
|
+
const stepRefs = chore.steps
|
|
386
|
+
.map(stepText => {
|
|
387
|
+
const stepInfo = stepMap.get(stepText);
|
|
388
|
+
if (stepInfo) {
|
|
389
|
+
return `${path.basename(stepInfo.file)}:${stepInfo.lineNumber} - "${stepText}"`;
|
|
390
|
+
}
|
|
391
|
+
return `"${stepText}" (not yet implemented)`;
|
|
392
|
+
})
|
|
393
|
+
.join('\n β’ ');
|
|
394
|
+
|
|
395
|
+
// Generate verification command for the chore's scenario
|
|
396
|
+
const verification = generateVerificationCommands(
|
|
397
|
+
`features/${featureSlug}.feature`,
|
|
398
|
+
chore.scenarioLine
|
|
399
|
+
);
|
|
400
|
+
|
|
401
|
+
const description = `${chore.technicalDescription}
|
|
247
402
|
|
|
248
403
|
Scenario steps addressed:
|
|
249
|
-
|
|
404
|
+
${chore.scenarioSteps.map(s => `β’ ${s}`).join('\n')}
|
|
250
405
|
|
|
251
406
|
Implementation guidance:
|
|
252
|
-
β’ Files to create/modify:
|
|
253
|
-
β’ Patterns to follow:
|
|
254
|
-
β’
|
|
407
|
+
β’ Files to create/modify: ${chore.files.join(', ')}
|
|
408
|
+
β’ Patterns to follow:
|
|
409
|
+
β’ ${patternRefs}
|
|
410
|
+
β’ Key functions/components needed: ${chore.components.join(', ')}
|
|
255
411
|
|
|
256
412
|
Verification:
|
|
257
|
-
β’ Step definitions that should pass:
|
|
413
|
+
β’ Step definitions that should pass:
|
|
414
|
+
β’ ${stepRefs}
|
|
415
|
+
β’ Test command: ${verification.command}
|
|
416
|
+
β’ Scenario: ${verification.scenarioName}`;
|
|
258
417
|
|
|
259
|
-
await create('chore',
|
|
260
|
-
|
|
418
|
+
await create('chore', chore.title, description, featureId, 'speed', false);
|
|
419
|
+
}
|
|
261
420
|
```
|
|
262
421
|
|
|
263
|
-
**Example chore description:**
|
|
422
|
+
**Example chore description (with breadcrumb generators):**
|
|
264
423
|
|
|
265
424
|
```
|
|
266
425
|
Build login form component with email/password fields
|
|
@@ -270,24 +429,30 @@ Scenario steps addressed:
|
|
|
270
429
|
β’ When I enter valid credentials and submit
|
|
271
430
|
|
|
272
431
|
Implementation guidance:
|
|
273
|
-
β’
|
|
274
|
-
β’
|
|
275
|
-
β’
|
|
276
|
-
β’
|
|
432
|
+
β’ Files to create/modify: src/components/LoginForm.jsx
|
|
433
|
+
β’ Patterns to follow:
|
|
434
|
+
β’ src/components/SignupForm.jsx (Functions: handleSubmit, validateEmail)
|
|
435
|
+
β’ lib/validation.js (Functions: validateEmailFormat, validatePassword)
|
|
436
|
+
β’ Key functions/components needed: EmailInput, PasswordInput, SubmitButton
|
|
277
437
|
|
|
278
438
|
Verification:
|
|
279
|
-
β’
|
|
280
|
-
β’
|
|
439
|
+
β’ Step definitions that should pass:
|
|
440
|
+
β’ login.steps.js:15 - "I am on the login page"
|
|
441
|
+
β’ login.steps.js:23 - "I enter valid credentials and submit"
|
|
442
|
+
β’ Test command: npm run test:bdd -- features/login.feature:8
|
|
443
|
+
β’ Scenario: User successfully logs in with valid credentials
|
|
281
444
|
```
|
|
282
445
|
|
|
283
446
|
**Report:**
|
|
284
447
|
```
|
|
285
448
|
β
Created X chores for speed mode
|
|
286
449
|
|
|
287
|
-
Each chore includes:
|
|
288
|
-
β’
|
|
289
|
-
β’
|
|
290
|
-
β’
|
|
450
|
+
Each chore includes automated breadcrumbs from:
|
|
451
|
+
β’ Step definition parser - Exact file:line references for verification
|
|
452
|
+
β’ Pattern finder - Similar code patterns to follow
|
|
453
|
+
β’ Verification command generator - Ready-to-run test commands
|
|
454
|
+
β’ Scenario steps addressed
|
|
455
|
+
β’ Implementation guidance with file paths
|
|
291
456
|
|
|
292
457
|
Ready to start implementation: jettypod work start [first-chore-id]
|
|
293
458
|
```
|
|
@@ -461,4 +626,5 @@ Before completing feature discovery, ensure:
|
|
|
461
626
|
- [ ] Step definitions written for ALL scenario steps
|
|
462
627
|
- [ ] Scenarios file exists at `features/[feature-slug].feature`
|
|
463
628
|
- [ ] Step definitions file exists at `features/step_definitions/[feature-slug].steps.js`
|
|
629
|
+
- [ ] BDD infrastructure validated with dry-run (Step 6.5)
|
|
464
630
|
- [ ] User knows next step .jettypod work start [feature-id])
|
|
@@ -294,11 +294,23 @@ try {
|
|
|
294
294
|
|
|
295
295
|
### Step 3: Implement Production Chore
|
|
296
296
|
|
|
297
|
-
**For all scenarios:** Implement the current production chore.
|
|
297
|
+
**For all scenarios:** Implement the current production chore with test-driven iteration.
|
|
298
298
|
|
|
299
299
|
```javascript
|
|
300
300
|
const { getCurrentWork } = require('../../lib/current-work');
|
|
301
|
+
const { getDb } = require('../../lib/database');
|
|
302
|
+
const {
|
|
303
|
+
MAX_ITERATIONS,
|
|
304
|
+
TEST_TIMEOUT,
|
|
305
|
+
runBddTestWithTimeout,
|
|
306
|
+
runBddScenarioWithTimeout,
|
|
307
|
+
getScenarioLineByName,
|
|
308
|
+
parseTestProgress,
|
|
309
|
+
extractErrors,
|
|
310
|
+
findNewlyPassingSteps
|
|
311
|
+
} = require('../../.claude/skills/speed-mode/test-runner');
|
|
301
312
|
const fs = require('fs');
|
|
313
|
+
const path = require('path');
|
|
302
314
|
|
|
303
315
|
try {
|
|
304
316
|
const currentWork = getCurrentWork();
|
|
@@ -306,16 +318,122 @@ try {
|
|
|
306
318
|
console.log(`\nπ Implementing: ${currentWork.title}`);
|
|
307
319
|
console.log(`Description: ${currentWork.description}`);
|
|
308
320
|
|
|
309
|
-
//
|
|
310
|
-
|
|
321
|
+
// Get parent feature and scenario file
|
|
322
|
+
const db = getDb();
|
|
323
|
+
const feature = await new Promise((resolve, reject) => {
|
|
324
|
+
db.get('SELECT * FROM work_items WHERE id = ?', [currentWork.parent_id], (err, row) => {
|
|
325
|
+
if (err) reject(err);
|
|
326
|
+
resolve(row);
|
|
327
|
+
});
|
|
328
|
+
});
|
|
329
|
+
|
|
330
|
+
if (!feature.scenario_file) {
|
|
331
|
+
console.error('β Feature has no scenario file.');
|
|
332
|
+
return;
|
|
333
|
+
}
|
|
334
|
+
|
|
335
|
+
// Identify which production scenario this chore addresses
|
|
336
|
+
// Parse from chore description (e.g., "Scenario: Rate limiting on login")
|
|
337
|
+
const scenarioMatch = currentWork.description.match(/Scenario:\s*(.+?)(?:\n|$)/i);
|
|
338
|
+
if (!scenarioMatch) {
|
|
339
|
+
console.error('β Cannot identify target scenario from chore description.');
|
|
340
|
+
console.log('Suggestion: Update chore description to reference specific scenario.');
|
|
341
|
+
return;
|
|
342
|
+
}
|
|
343
|
+
|
|
344
|
+
const targetScenarioName = scenarioMatch[1].trim();
|
|
345
|
+
const scenarioLine = getScenarioLineByName(feature.scenario_file, targetScenarioName);
|
|
346
|
+
|
|
347
|
+
if (!scenarioLine) {
|
|
348
|
+
console.error(`β Cannot find scenario "${targetScenarioName}" in ${feature.scenario_file}`);
|
|
349
|
+
return;
|
|
350
|
+
}
|
|
351
|
+
|
|
352
|
+
console.log(`\nπ Target scenario: ${targetScenarioName} (line ${scenarioLine})`);
|
|
353
|
+
|
|
354
|
+
// REDβGREEN iteration loop for production implementation
|
|
355
|
+
let iteration = 0;
|
|
356
|
+
let scenarioPasses = false;
|
|
357
|
+
let previousResult = null;
|
|
358
|
+
|
|
359
|
+
console.log('\nπ΄ Establishing RED baseline...\n');
|
|
360
|
+
const baselineResult = await runBddScenarioWithTimeout(feature.scenario_file, scenarioLine, TEST_TIMEOUT);
|
|
361
|
+
|
|
362
|
+
if (!baselineResult.timedOut) {
|
|
363
|
+
const baselineProgress = parseTestProgress(baselineResult.stdout + baselineResult.stderr);
|
|
364
|
+
console.log(`RED Baseline: ${baselineProgress.total - baselineProgress.passed} of ${baselineProgress.total} steps failing\n`);
|
|
365
|
+
}
|
|
366
|
+
|
|
367
|
+
while (!scenarioPasses && iteration < MAX_ITERATIONS) {
|
|
368
|
+
iteration++;
|
|
369
|
+
console.log(`\nβββ Iteration ${iteration}/${MAX_ITERATIONS} βββ`);
|
|
370
|
+
|
|
371
|
+
// 1. Implement production hardening based on standard
|
|
372
|
+
console.log('βοΈ Implementing production hardening...');
|
|
373
|
+
// [Claude Code uses Edit/Write tools to implement standard requirements]
|
|
374
|
+
|
|
375
|
+
// 2. Run target scenario only
|
|
376
|
+
console.log('π§ͺ Running target scenario...');
|
|
377
|
+
const result = await runBddScenarioWithTimeout(feature.scenario_file, scenarioLine, TEST_TIMEOUT);
|
|
378
|
+
|
|
379
|
+
if (result.timedOut) {
|
|
380
|
+
console.error('β Tests timed out');
|
|
381
|
+
break;
|
|
382
|
+
}
|
|
383
|
+
|
|
384
|
+
const currentResult = parseTestProgress(result.stdout + result.stderr);
|
|
385
|
+
const newlyPassing = previousResult ? findNewlyPassingSteps(previousResult, currentResult) : [];
|
|
386
|
+
|
|
387
|
+
console.log(`\nπ Progress: ${currentResult.passed}/${currentResult.total} steps passing`);
|
|
388
|
+
|
|
389
|
+
if (newlyPassing.length > 0) {
|
|
390
|
+
console.log(`\nβ
Newly passing:`);
|
|
391
|
+
newlyPassing.forEach(step => console.log(` β’ ${step}`));
|
|
392
|
+
}
|
|
393
|
+
|
|
394
|
+
// Check if target scenario passes
|
|
395
|
+
if (currentResult.passed === currentResult.total && currentResult.total > 0) {
|
|
396
|
+
console.log('\nβ
Target scenario passing!');
|
|
397
|
+
|
|
398
|
+
// Run full verification (all scenarios) once for regression detection
|
|
399
|
+
console.log('\nπ Running full verification (all scenarios)...');
|
|
400
|
+
const fullResult = await runBddTestWithTimeout(feature.scenario_file, TEST_TIMEOUT);
|
|
401
|
+
|
|
402
|
+
if (fullResult.timedOut) {
|
|
403
|
+
console.log('β οΈ Full verification timed out');
|
|
404
|
+
} else if (fullResult.exitCode !== 0) {
|
|
405
|
+
const fullProgress = parseTestProgress(fullResult.stdout + fullResult.stderr);
|
|
406
|
+
console.log(`β οΈ Full verification found regressions: ${fullProgress.total - fullProgress.passed} scenarios failing`);
|
|
407
|
+
console.log('Continuing iterations to fix regressions...');
|
|
408
|
+
scenarioPasses = false;
|
|
409
|
+
} else {
|
|
410
|
+
console.log('β
Full verification passed - all scenarios passing!');
|
|
411
|
+
scenarioPasses = true;
|
|
412
|
+
}
|
|
413
|
+
} else {
|
|
414
|
+
console.log(`\nβ ${currentResult.total - currentResult.passed} steps still failing`);
|
|
415
|
+
|
|
416
|
+
const errors = extractErrors(result.stdout + result.stderr);
|
|
417
|
+
if (errors.errors.length > 0) {
|
|
418
|
+
console.log('\nπ§ Next failure to address:');
|
|
419
|
+
const firstError = errors.errors[0];
|
|
420
|
+
console.log(` Step: ${firstError.step}`);
|
|
421
|
+
console.log(` Error: ${firstError.message}`);
|
|
422
|
+
}
|
|
423
|
+
}
|
|
424
|
+
|
|
425
|
+
previousResult = currentResult;
|
|
426
|
+
}
|
|
427
|
+
|
|
428
|
+
if (!scenarioPasses) {
|
|
429
|
+
console.error(`\nβ Maximum iterations (${MAX_ITERATIONS}) reached without passing scenario`);
|
|
430
|
+
console.log('Review implementation against production standard acceptance criteria.');
|
|
431
|
+
return;
|
|
432
|
+
}
|
|
311
433
|
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
// 2. Implement code that satisfies the criteria
|
|
315
|
-
// 3. Add tests based on scenario steps
|
|
434
|
+
console.log('\nβ
Production chore implementation complete');
|
|
435
|
+
console.log('All scenarios passing with production standards enforced.');
|
|
316
436
|
|
|
317
|
-
console.log('\nβ
Implementation complete');
|
|
318
|
-
console.log('Run: npx cucumber-js to verify scenarios pass');
|
|
319
437
|
} catch (err) {
|
|
320
438
|
console.error('β Implementation failed:', err.message);
|
|
321
439
|
return;
|