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
|
@@ -27,6 +27,34 @@ When this skill is activated, you are helping implement a speed mode chore to ma
|
|
|
27
27
|
|
|
28
28
|
---
|
|
29
29
|
|
|
30
|
+
## ⚠️ CRITICAL: Speed Mode Workflow Requirements
|
|
31
|
+
|
|
32
|
+
**DO NOT mark features as complete after speed mode implementation.**
|
|
33
|
+
|
|
34
|
+
Speed mode is ONLY a checkpoint to prove the happy path works. Features are INCOMPLETE without stable mode chores that add:
|
|
35
|
+
- Error handling and validation
|
|
36
|
+
- Edge case coverage
|
|
37
|
+
- Comprehensive testing
|
|
38
|
+
- User-friendly error messages
|
|
39
|
+
|
|
40
|
+
**Required workflow after speed mode implementation:**
|
|
41
|
+
|
|
42
|
+
1. ✅ **Complete ALL speed mode chores** - Implement happy path functionality
|
|
43
|
+
2. ✅ **Elevate to stable mode** - Use `node jettypod.js work set-mode <feature-id> stable` to auto-generate stable mode chores
|
|
44
|
+
3. ✅ **Implement stable mode chores** - Add error handling and edge cases
|
|
45
|
+
4. ❌ **NEVER mark feature complete in speed mode** - This bypasses critical quality gates
|
|
46
|
+
|
|
47
|
+
**If you attempt to mark a feature complete while in speed mode, the system will block you with an error.**
|
|
48
|
+
|
|
49
|
+
The validation will require you to:
|
|
50
|
+
- Elevate to stable mode: `node jettypod.js work set-mode <feature-id> stable`
|
|
51
|
+
- This will automatically analyze the implementation and generate appropriate stable mode chores
|
|
52
|
+
- Or explicitly skip (not recommended): `node jettypod.js work set-mode <feature-id> stable --force`
|
|
53
|
+
|
|
54
|
+
**Remember:** Speed mode proves it works on the happy path. Stable mode makes it production-ready.
|
|
55
|
+
|
|
56
|
+
---
|
|
57
|
+
|
|
30
58
|
## Implementation Steps
|
|
31
59
|
|
|
32
60
|
### Step 1: Check for Breadcrumbs and Analyze Scenario
|
|
@@ -129,13 +157,22 @@ Now analyzing codebase to propose implementation...
|
|
|
129
157
|
|
|
130
158
|
**Check for architectural decisions:**
|
|
131
159
|
|
|
160
|
+
**⚠️ IMPORTANT - USE EXACT CODE BELOW:**
|
|
161
|
+
- Import from `./lib/decisions-helpers` (NOT `../../lib/decisions-helpers` or `./features/decisions/index.js`)
|
|
162
|
+
- Function returns a Promise, must use `await`
|
|
163
|
+
|
|
164
|
+
**Execute this EXACT code (copy/paste as-is):**
|
|
165
|
+
|
|
132
166
|
```javascript
|
|
133
|
-
const { getDecisionsForEpic } = require('
|
|
167
|
+
const { getDecisionsForEpic } = require('./lib/decisions-helpers');
|
|
168
|
+
const { getDb } = require('./lib/database');
|
|
169
|
+
const db = getDb();
|
|
134
170
|
|
|
135
171
|
// Get epic from current work
|
|
136
172
|
db.get('SELECT epic_id FROM work_items WHERE id = ?', [currentWork.parent_id], async (err, feature) => {
|
|
137
|
-
if (feature.epic_id) {
|
|
173
|
+
if (feature && feature.epic_id) {
|
|
138
174
|
const decisions = await getDecisionsForEpic(feature.epic_id);
|
|
175
|
+
console.log('Epic decisions:', JSON.stringify(decisions, null, 2));
|
|
139
176
|
// Decisions constrain your implementation approach
|
|
140
177
|
}
|
|
141
178
|
});
|
|
@@ -226,42 +263,226 @@ If user adjusts: revise proposal and confirm again.
|
|
|
226
263
|
|
|
227
264
|
**CRITICAL:** After user confirms, Claude Code executes autonomously - no permission needed for individual code changes.
|
|
228
265
|
|
|
229
|
-
**
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
266
|
+
**Step 1: Establish RED Baseline**
|
|
267
|
+
|
|
268
|
+
Before writing any implementation code, run tests to establish the RED state:
|
|
269
|
+
|
|
270
|
+
```javascript
|
|
271
|
+
const { runBddTestWithTimeout, runBddScenarioWithTimeout, getFirstScenarioLine, parseTestProgress, extractErrors } = require('./.claude/skills/speed-mode/test-runner');
|
|
272
|
+
const { getCurrentWork } = require('./lib/current-work');
|
|
273
|
+
const { getDb } = require('./lib/database');
|
|
274
|
+
|
|
275
|
+
const currentWork = getCurrentWork();
|
|
276
|
+
const db = getDb();
|
|
277
|
+
|
|
278
|
+
// Get parent feature and its scenario file
|
|
279
|
+
db.get('SELECT * FROM work_items WHERE id = ?', [currentWork.parent_id], async (err, feature) => {
|
|
280
|
+
if (!feature.scenario_file) {
|
|
281
|
+
console.error('No scenario file found for this feature');
|
|
282
|
+
return;
|
|
283
|
+
}
|
|
284
|
+
|
|
285
|
+
console.log('🔴 Establishing RED baseline...\n');
|
|
286
|
+
|
|
287
|
+
// Find happy path scenario (first scenario in file)
|
|
288
|
+
const happyPathLine = getFirstScenarioLine(feature.scenario_file);
|
|
289
|
+
if (!happyPathLine) {
|
|
290
|
+
console.error('No scenario found in feature file');
|
|
291
|
+
return;
|
|
292
|
+
}
|
|
293
|
+
|
|
294
|
+
// Run only happy path scenario before any code is written
|
|
295
|
+
const result = await runBddScenarioWithTimeout(feature.scenario_file, happyPathLine);
|
|
296
|
+
|
|
297
|
+
if (result.timedOut) {
|
|
298
|
+
console.log('⚠️ Test execution timed out - tests may be hanging');
|
|
299
|
+
console.log('Proceeding with implementation...\n');
|
|
300
|
+
} else {
|
|
301
|
+
// Parse the test output
|
|
302
|
+
const progress = parseTestProgress(result.stdout + result.stderr);
|
|
303
|
+
const errors = extractErrors(result.stdout + result.stderr);
|
|
304
|
+
|
|
305
|
+
console.log(`RED Baseline: ${progress.total - progress.passed} of ${progress.total} steps failing`);
|
|
306
|
+
console.log('\nFailing steps:');
|
|
307
|
+
progress.failedSteps.forEach(step => console.log(` ✖ ${step}`));
|
|
308
|
+
|
|
309
|
+
if (errors.errors.length > 0) {
|
|
310
|
+
console.log('\nFirst error:');
|
|
311
|
+
const firstError = errors.errors[0];
|
|
312
|
+
console.log(` Step: ${firstError.step}`);
|
|
313
|
+
console.log(` Error: ${firstError.message}`);
|
|
314
|
+
}
|
|
315
|
+
|
|
316
|
+
console.log('\n🎯 Goal: Make all steps pass\n');
|
|
317
|
+
}
|
|
318
|
+
|
|
319
|
+
// Store baseline for comparison in iteration loop (chore #115)
|
|
320
|
+
global.redBaseline = {
|
|
321
|
+
passed: progress.passed,
|
|
322
|
+
total: progress.total,
|
|
323
|
+
failedSteps: progress.failedSteps
|
|
324
|
+
};
|
|
325
|
+
});
|
|
326
|
+
```
|
|
327
|
+
|
|
328
|
+
**Display RED baseline:**
|
|
329
|
+
```
|
|
330
|
+
🔴 Establishing RED baseline...
|
|
331
|
+
|
|
332
|
+
RED Baseline: 5 of 8 steps failing
|
|
333
|
+
|
|
334
|
+
Failing steps:
|
|
335
|
+
✖ Given a user is logged in
|
|
336
|
+
✖ When they click the dashboard button
|
|
337
|
+
✖ Then they should see their dashboard
|
|
338
|
+
✖ And the dashboard should show their username
|
|
339
|
+
✖ And the dashboard should show their recent activity
|
|
340
|
+
|
|
341
|
+
First error:
|
|
342
|
+
Step: Given a user is logged in
|
|
343
|
+
Error: Error: login function is not defined
|
|
344
|
+
|
|
345
|
+
🎯 Goal: Make all steps pass
|
|
346
|
+
|
|
347
|
+
Now implementing...
|
|
348
|
+
```
|
|
349
|
+
|
|
350
|
+
**Step 2: RED→GREEN Iteration Loop**
|
|
351
|
+
|
|
352
|
+
Iterate until all tests pass or MAX_ITERATIONS reached:
|
|
353
|
+
|
|
354
|
+
```javascript
|
|
355
|
+
const { runBddScenarioWithTimeout, parseTestProgress, findNewlyPassingSteps, extractErrors, MAX_ITERATIONS } = require('./.claude/skills/speed-mode/test-runner');
|
|
356
|
+
|
|
357
|
+
let previousResult = global.redBaseline; // From Step 1
|
|
358
|
+
let iteration = 0;
|
|
359
|
+
|
|
360
|
+
while (iteration < MAX_ITERATIONS) {
|
|
361
|
+
iteration++;
|
|
362
|
+
|
|
363
|
+
console.log(`\n━━━ Iteration ${iteration}/${MAX_ITERATIONS} ━━━`);
|
|
364
|
+
|
|
365
|
+
// 1. Make code changes based on current failure
|
|
366
|
+
console.log(`\n✍️ Making code changes...`);
|
|
367
|
+
// [Claude Code writes implementation code here using Write/Edit tools]
|
|
368
|
+
|
|
369
|
+
// 2. Run tests - only happy path scenario during iteration
|
|
370
|
+
console.log(`\n🧪 Running tests...`);
|
|
371
|
+
const result = await runBddScenarioWithTimeout(feature.scenario_file, happyPathLine);
|
|
372
|
+
|
|
373
|
+
if (result.timedOut) {
|
|
374
|
+
console.log(`⚠️ Test execution timed out - tests may be hanging`);
|
|
375
|
+
console.log(`Stopping iteration loop`);
|
|
376
|
+
break;
|
|
377
|
+
}
|
|
378
|
+
|
|
379
|
+
// 3. Parse results
|
|
380
|
+
const currentResult = parseTestProgress(result.stdout + result.stderr);
|
|
381
|
+
const errors = extractErrors(result.stdout + result.stderr);
|
|
382
|
+
|
|
383
|
+
// 4. Track progress
|
|
384
|
+
const newlyPassing = findNewlyPassingSteps(previousResult, currentResult);
|
|
385
|
+
|
|
386
|
+
// 5. Display progress
|
|
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
|
+
// 6. Check if all tests pass (GREEN state achieved)
|
|
395
|
+
if (currentResult.exitCode === 0 || currentResult.passed === currentResult.total) {
|
|
396
|
+
console.log(`\n🎉 GREEN: All tests passing!`);
|
|
397
|
+
break;
|
|
398
|
+
}
|
|
399
|
+
|
|
400
|
+
// 7. Display next failure to address
|
|
401
|
+
if (errors.errors.length > 0) {
|
|
402
|
+
const nextError = errors.errors[0];
|
|
403
|
+
console.log(`\n🔧 Next failure to address:`);
|
|
404
|
+
console.log(` Step: ${nextError.step}`);
|
|
405
|
+
console.log(` Error: ${nextError.message}`);
|
|
406
|
+
if (nextError.stack) {
|
|
407
|
+
console.log(` Stack: ${nextError.stack.split('\n')[0]}`); // First line only
|
|
408
|
+
}
|
|
409
|
+
} else if (currentResult.failedSteps.length > 0) {
|
|
410
|
+
console.log(`\n🔧 Still failing:`);
|
|
411
|
+
currentResult.failedSteps.slice(0, 3).forEach(step => console.log(` • ${step}`));
|
|
412
|
+
if (currentResult.failedSteps.length > 3) {
|
|
413
|
+
console.log(` ... and ${currentResult.failedSteps.length - 3} more`);
|
|
414
|
+
}
|
|
415
|
+
}
|
|
416
|
+
|
|
417
|
+
// Store for next iteration comparison
|
|
418
|
+
previousResult = currentResult;
|
|
419
|
+
}
|
|
420
|
+
|
|
421
|
+
// After loop ends
|
|
422
|
+
if (iteration >= MAX_ITERATIONS) {
|
|
423
|
+
console.log(`\n⚠️ Maximum iterations (${MAX_ITERATIONS}) reached without achieving GREEN`);
|
|
424
|
+
console.log(`Final progress: ${previousResult.passed}/${previousResult.total} steps passing`);
|
|
425
|
+
console.log(`\nConsider:`);
|
|
426
|
+
console.log(` • Breaking down the chore into smaller pieces`);
|
|
427
|
+
console.log(` • Reviewing the implementation approach`);
|
|
428
|
+
console.log(` • Checking for incorrect assumptions`);
|
|
429
|
+
}
|
|
430
|
+
```
|
|
431
|
+
|
|
432
|
+
**Display example:**
|
|
433
|
+
```
|
|
434
|
+
━━━ Iteration 1/10 ━━━
|
|
435
|
+
|
|
436
|
+
✍️ Making code changes...
|
|
437
|
+
Created src/login.js
|
|
438
|
+
Modified src/app.js
|
|
439
|
+
|
|
440
|
+
🧪 Running tests...
|
|
441
|
+
|
|
442
|
+
📊 Progress: 2/8 steps passing
|
|
443
|
+
|
|
444
|
+
✅ Newly passing:
|
|
445
|
+
• Given a user is logged in
|
|
446
|
+
• When they click the dashboard button
|
|
447
|
+
|
|
448
|
+
🔧 Next failure to address:
|
|
449
|
+
Step: Then they should see their dashboard
|
|
450
|
+
Error: Cannot read property 'innerText' of null
|
|
451
|
+
Stack: at Dashboard.render (src/dashboard.js:12:15)
|
|
452
|
+
|
|
453
|
+
━━━ Iteration 2/10 ━━━
|
|
454
|
+
|
|
455
|
+
✍️ Making code changes...
|
|
456
|
+
Created src/dashboard.js
|
|
457
|
+
Modified src/app.js
|
|
458
|
+
|
|
459
|
+
🧪 Running tests...
|
|
460
|
+
|
|
461
|
+
📊 Progress: 5/8 steps passing
|
|
462
|
+
|
|
463
|
+
✅ Newly passing:
|
|
464
|
+
• Then they should see their dashboard
|
|
465
|
+
• And the dashboard should show their username
|
|
466
|
+
• And the dashboard should show their recent activity
|
|
467
|
+
|
|
468
|
+
🔧 Next failure to address:
|
|
469
|
+
Step: And the activity should be sorted by date
|
|
470
|
+
Error: Expected ['Post 2', 'Post 1'] but got ['Post 1', 'Post 2']
|
|
471
|
+
|
|
472
|
+
━━━ Iteration 3/10 ━━━
|
|
473
|
+
|
|
474
|
+
✍️ Making code changes...
|
|
475
|
+
Modified src/dashboard.js
|
|
476
|
+
|
|
477
|
+
🧪 Running tests...
|
|
478
|
+
|
|
479
|
+
📊 Progress: 8/8 steps passing
|
|
480
|
+
|
|
481
|
+
✅ Newly passing:
|
|
482
|
+
• And the activity should be sorted by date
|
|
483
|
+
|
|
484
|
+
🎉 GREEN: All tests passing!
|
|
485
|
+
```
|
|
265
486
|
|
|
266
487
|
**Speed mode constraints:**
|
|
267
488
|
- **Implement ALL scoped functionality** - if the scenario requires file upload, implement it (just assume it works)
|
|
@@ -272,20 +493,190 @@ If user adjusts: revise proposal and confirm again.
|
|
|
272
493
|
- **Inline code over separate modules** - keep it simple
|
|
273
494
|
- **Focus: Make. All. Features. Work.** (on the happy path)
|
|
274
495
|
|
|
275
|
-
**
|
|
496
|
+
**Step 3: Final Verification and Completion**
|
|
497
|
+
|
|
498
|
+
After GREEN is achieved, run full feature file once to verify no regressions:
|
|
499
|
+
|
|
500
|
+
```javascript
|
|
501
|
+
// After iteration loop succeeds (GREEN achieved)
|
|
502
|
+
if (currentResult.exitCode === 0 || currentResult.passed === currentResult.total) {
|
|
503
|
+
console.log(`\n🎉 GREEN: Happy path scenario passing!`);
|
|
504
|
+
console.log(`\n🔍 Running full verification (all scenarios)...`);
|
|
505
|
+
|
|
506
|
+
// Run entire feature file once for regression detection
|
|
507
|
+
const { runBddTestWithTimeout } = require('./.claude/skills/speed-mode/test-runner');
|
|
508
|
+
const fullResult = await runBddTestWithTimeout(feature.scenario_file);
|
|
509
|
+
|
|
510
|
+
if (fullResult.timedOut) {
|
|
511
|
+
console.log(`⚠️ Full verification timed out`);
|
|
512
|
+
} else if (fullResult.exitCode !== 0) {
|
|
513
|
+
const fullProgress = parseTestProgress(fullResult.stdout + fullResult.stderr);
|
|
514
|
+
console.log(`⚠️ Full verification found regressions: ${fullProgress.total - fullProgress.passed} scenarios failing`);
|
|
515
|
+
console.log(`This is expected in speed mode - stable mode will address additional scenarios.`);
|
|
516
|
+
} else {
|
|
517
|
+
console.log(`✅ Full verification passed - all scenarios passing!`);
|
|
518
|
+
}
|
|
519
|
+
}
|
|
520
|
+
```
|
|
521
|
+
|
|
522
|
+
Display comprehensive results:
|
|
523
|
+
|
|
524
|
+
**On SUCCESS (GREEN achieved):**
|
|
525
|
+
|
|
526
|
+
```javascript
|
|
527
|
+
// Track what files were created/modified during implementation
|
|
528
|
+
const filesCreated = [/* list of created files */];
|
|
529
|
+
const filesModified = [/* list of modified files */];
|
|
530
|
+
|
|
531
|
+
console.log(`\n━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━`);
|
|
532
|
+
console.log(`✅ SPEED MODE COMPLETE - GREEN STATE ACHIEVED`);
|
|
533
|
+
console.log(`━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n`);
|
|
534
|
+
|
|
535
|
+
console.log(`🎉 Happy path scenario: ALL TESTS PASSING\n`);
|
|
536
|
+
|
|
537
|
+
console.log(`Implementation Summary:`);
|
|
538
|
+
console.log(` Iterations: ${iteration}/${MAX_ITERATIONS}`);
|
|
539
|
+
console.log(` Test steps: ${currentResult.passed}/${currentResult.total} passing\n`);
|
|
540
|
+
|
|
541
|
+
if (filesCreated.length > 0) {
|
|
542
|
+
console.log(`Files created:`);
|
|
543
|
+
filesCreated.forEach(file => console.log(` ✅ ${file}`));
|
|
544
|
+
console.log();
|
|
545
|
+
}
|
|
546
|
+
|
|
547
|
+
if (filesModified.length > 0) {
|
|
548
|
+
console.log(`Files modified:`);
|
|
549
|
+
filesModified.forEach(file => console.log(` ✏️ ${file}`));
|
|
550
|
+
console.log();
|
|
551
|
+
}
|
|
552
|
+
|
|
553
|
+
// Generate unit tests for new functions after GREEN
|
|
554
|
+
console.log(`📝 Generating unit tests for new functions...\n`);
|
|
555
|
+
const { generateTestsAfterGreen } = require('./lib/unit-test-generator');
|
|
556
|
+
|
|
557
|
+
const allFiles = [...filesCreated, ...filesModified];
|
|
558
|
+
const testsGenerated = [];
|
|
559
|
+
|
|
560
|
+
for (const file of allFiles) {
|
|
561
|
+
if (file.endsWith('.js') && !file.includes('test')) {
|
|
562
|
+
try {
|
|
563
|
+
const result = generateTestsAfterGreen(file);
|
|
564
|
+
if (result.created || result.functionsAdded > 0) {
|
|
565
|
+
testsGenerated.push({ file: result.testFile, functionsAdded: result.functionsAdded });
|
|
566
|
+
console.log(` ✅ ${result.testFile} (${result.functionsAdded} functions)`);
|
|
567
|
+
}
|
|
568
|
+
} catch (err) {
|
|
569
|
+
console.log(` ⚠️ Could not generate tests for ${file}: ${err.message}`);
|
|
570
|
+
}
|
|
571
|
+
}
|
|
572
|
+
}
|
|
573
|
+
|
|
574
|
+
if (testsGenerated.length > 0) {
|
|
575
|
+
console.log(`\n🧪 Generated tests for ${testsGenerated.length} files`);
|
|
576
|
+
console.log(` Tests have TODO placeholders - stable mode will add edge cases\n`);
|
|
577
|
+
} else {
|
|
578
|
+
console.log(`No unit tests generated (no functions found)\n`);
|
|
579
|
+
}
|
|
580
|
+
|
|
581
|
+
console.log(`Next step: Elevate to stable mode using 'node jettypod.js work set-mode <feature-id> stable'\n`);
|
|
582
|
+
```
|
|
276
583
|
|
|
584
|
+
**Display:**
|
|
277
585
|
```
|
|
278
|
-
|
|
586
|
+
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
|
|
587
|
+
✅ SPEED MODE COMPLETE - GREEN STATE ACHIEVED
|
|
588
|
+
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
|
|
589
|
+
|
|
590
|
+
🎉 Happy path scenario: ALL TESTS PASSING
|
|
279
591
|
|
|
280
|
-
Implementation
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
• Tests: ✅ Passing
|
|
592
|
+
Implementation Summary:
|
|
593
|
+
Iterations: 3/10
|
|
594
|
+
Test steps: 8/8 passing
|
|
284
595
|
|
|
285
|
-
|
|
596
|
+
Files created:
|
|
597
|
+
✅ src/login.js
|
|
598
|
+
✅ src/dashboard.js
|
|
599
|
+
|
|
600
|
+
Files modified:
|
|
601
|
+
✏️ src/app.js
|
|
602
|
+
✏️ src/index.html
|
|
603
|
+
|
|
604
|
+
Next step: Elevate to stable mode using 'node jettypod.js work set-mode <feature-id> stable'
|
|
286
605
|
```
|
|
287
606
|
|
|
288
|
-
**
|
|
607
|
+
**On FAILURE (max iterations or timeout):**
|
|
608
|
+
|
|
609
|
+
```javascript
|
|
610
|
+
console.log(`\n━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━`);
|
|
611
|
+
console.log(`⚠️ SPEED MODE INCOMPLETE - STILL IN RED STATE`);
|
|
612
|
+
console.log(`━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n`);
|
|
613
|
+
|
|
614
|
+
if (result.timedOut) {
|
|
615
|
+
console.log(`❌ Test execution timed out`);
|
|
616
|
+
console.log(`\nPossible causes:`);
|
|
617
|
+
console.log(` • Infinite loop in implementation code`);
|
|
618
|
+
console.log(` • Test is waiting for async operation that never completes`);
|
|
619
|
+
console.log(` • Step definition has blocking code`);
|
|
620
|
+
} else {
|
|
621
|
+
console.log(`❌ Maximum iterations (${MAX_ITERATIONS}) reached\n`);
|
|
622
|
+
console.log(`Final Progress: ${previousResult.passed}/${previousResult.total} steps passing\n`);
|
|
623
|
+
|
|
624
|
+
if (previousResult.failedSteps.length > 0) {
|
|
625
|
+
console.log(`Still failing:`);
|
|
626
|
+
previousResult.failedSteps.forEach(step => console.log(` ✖ ${step}`));
|
|
627
|
+
console.log();
|
|
628
|
+
}
|
|
629
|
+
|
|
630
|
+
const errors = extractErrors(result.stdout + result.stderr);
|
|
631
|
+
if (errors.errors.length > 0) {
|
|
632
|
+
console.log(`Remaining errors:`);
|
|
633
|
+
errors.errors.slice(0, 3).forEach(err => {
|
|
634
|
+
console.log(` Step: ${err.step}`);
|
|
635
|
+
console.log(` Error: ${err.message}\n`);
|
|
636
|
+
});
|
|
637
|
+
}
|
|
638
|
+
}
|
|
639
|
+
|
|
640
|
+
console.log(`\nWhat to do:`);
|
|
641
|
+
console.log(` • Review implementation approach - is it the right strategy?`);
|
|
642
|
+
console.log(` • Check for incorrect assumptions about existing code`);
|
|
643
|
+
console.log(` • Consider breaking this chore into smaller pieces`);
|
|
644
|
+
console.log(` • Verify step definitions match what implementation provides`);
|
|
645
|
+
console.log(`\nDO NOT proceed to generate stable mode chores until GREEN is achieved.`);
|
|
646
|
+
```
|
|
647
|
+
|
|
648
|
+
**Display (on failure):**
|
|
649
|
+
```
|
|
650
|
+
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
|
|
651
|
+
⚠️ SPEED MODE INCOMPLETE - STILL IN RED STATE
|
|
652
|
+
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
|
|
653
|
+
|
|
654
|
+
❌ Maximum iterations (10) reached
|
|
655
|
+
|
|
656
|
+
Final Progress: 5/8 steps passing
|
|
657
|
+
|
|
658
|
+
Still failing:
|
|
659
|
+
✖ Then they should see their dashboard
|
|
660
|
+
✖ And the dashboard should show their username
|
|
661
|
+
✖ And the dashboard should show their recent activity
|
|
662
|
+
|
|
663
|
+
Remaining errors:
|
|
664
|
+
Step: Then they should see their dashboard
|
|
665
|
+
Error: Cannot read property 'innerText' of null
|
|
666
|
+
|
|
667
|
+
Step: And the dashboard should show their username
|
|
668
|
+
Error: Expected 'John Doe' but got undefined
|
|
669
|
+
|
|
670
|
+
What to do:
|
|
671
|
+
• Review implementation approach - is it the right strategy?
|
|
672
|
+
• Check for incorrect assumptions about existing code
|
|
673
|
+
• Consider breaking this chore into smaller pieces
|
|
674
|
+
• Verify step definitions match what implementation provides
|
|
675
|
+
|
|
676
|
+
DO NOT proceed to generate stable mode chores until GREEN is achieved.
|
|
677
|
+
```
|
|
678
|
+
|
|
679
|
+
**Move to Step 4 only if GREEN achieved.**
|
|
289
680
|
|
|
290
681
|
### Step 4: Generate Stable Mode Chores
|
|
291
682
|
|
|
@@ -424,7 +815,7 @@ db.get(`
|
|
|
424
815
|
|
|
425
816
|
```javascript
|
|
426
817
|
// Use Bash tool to execute:
|
|
427
|
-
node jettypod.js work
|
|
818
|
+
node jettypod.js work set-mode [feature-id] stable
|
|
428
819
|
```
|
|
429
820
|
|
|
430
821
|
**DO NOT display this as example text. EXECUTE IT using the Bash tool.**
|
|
@@ -436,13 +827,25 @@ After execution, display:
|
|
|
436
827
|
🎯 Speed Mode Complete! Feature Elevated to Stable Mode
|
|
437
828
|
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
|
|
438
829
|
|
|
830
|
+
⚠️ CRITICAL: Speed mode is ONLY a checkpoint to prove functionality works.
|
|
831
|
+
The feature is INCOMPLETE without stable mode - error handling, validation,
|
|
832
|
+
edge cases, and comprehensive testing are ALL required.
|
|
833
|
+
|
|
439
834
|
What we accomplished:
|
|
440
835
|
✅ Happy path scenario passes
|
|
441
836
|
✅ All speed mode chores complete
|
|
442
837
|
✅ Feature elevated to stable mode
|
|
443
838
|
✅ Stable mode chores created and ready
|
|
444
839
|
|
|
445
|
-
|
|
840
|
+
🚀 NEVER leave a feature in speed mode - it's not production-ready.
|
|
841
|
+
Stable mode adds:
|
|
842
|
+
• Comprehensive error handling and user-friendly error messages
|
|
843
|
+
• Input validation (null checks, type checks, range validation)
|
|
844
|
+
• Edge case handling (empty arrays, boundary values, race conditions)
|
|
845
|
+
• State consistency and data integrity
|
|
846
|
+
• All BDD scenarios passing (happy path + error/edge cases)
|
|
847
|
+
|
|
848
|
+
**Next step:** IMMEDIATELY start the first stable mode chore
|
|
446
849
|
jettypod work start [first-stable-chore-id]
|
|
447
850
|
```
|
|
448
851
|
|
|
@@ -465,14 +868,14 @@ Remaining speed mode chores: [count]
|
|
|
465
868
|
|
|
466
869
|
**Mark current chore as done:**
|
|
467
870
|
|
|
468
|
-
Use Bash tool to commit
|
|
871
|
+
Use Bash tool to commit and push:
|
|
469
872
|
```bash
|
|
470
873
|
git add . && git commit -m "feat: [brief description of what was implemented]" && git push
|
|
471
874
|
```
|
|
472
875
|
|
|
473
|
-
Then merge to main (which auto-marks chore as done via
|
|
876
|
+
Then use the merge command to merge to main (which auto-marks chore as done via post-merge hook):
|
|
474
877
|
```bash
|
|
475
|
-
|
|
878
|
+
jettypod work merge
|
|
476
879
|
```
|
|
477
880
|
|
|
478
881
|
The post-merge hook will automatically mark the chore as done when merged to main.
|