jettypod 4.1.4 → 4.1.6
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/cucumber.js +0 -1
- package/lib/current-work.js +104 -52
- package/lib/migrations/016-worktree-sessions-table.js +84 -0
- package/lib/worktree-manager.js +27 -2
- package/lib/worktree-sessions.js +186 -0
- package/package.json +1 -1
- package/skills-templates/feature-planning/SKILL.md +68 -180
- package/skills-templates/speed-mode/SKILL.md +224 -93
- package/skills-templates/stable-mode/SKILL.md +189 -158
|
@@ -5,6 +5,19 @@ description: Guide implementation of speed mode chores with autonomous code anal
|
|
|
5
5
|
|
|
6
6
|
# Speed Mode Skill
|
|
7
7
|
|
|
8
|
+
```
|
|
9
|
+
┌─────────────────────────────────────────────────────────────────────┐
|
|
10
|
+
│ Mode Progression Flow │
|
|
11
|
+
│ │
|
|
12
|
+
│ Feature Planning → [SPEED MODE] → Stable Mode → Production Mode │
|
|
13
|
+
│ ▲▲▲▲▲▲▲▲▲▲▲ │
|
|
14
|
+
│ YOU ARE HERE │
|
|
15
|
+
│ │
|
|
16
|
+
│ Next: After implementation, this skill generates stable mode │
|
|
17
|
+
│ chores and elevates the feature to stable mode. │
|
|
18
|
+
└─────────────────────────────────────────────────────────────────────┘
|
|
19
|
+
```
|
|
20
|
+
|
|
8
21
|
Guides Claude Code through speed mode implementation with autonomous analysis and execution. Users confirm approach but Claude Code writes the code.
|
|
9
22
|
|
|
10
23
|
## Instructions
|
|
@@ -20,13 +33,30 @@ When this skill is activated, you are helping implement a speed mode chore to ma
|
|
|
20
33
|
- **Assume happy path** - assume inputs are valid, files upload successfully, types are correct
|
|
21
34
|
- **No error handling** - no validation, no edge case handling, no error messages (that's for stable mode)
|
|
22
35
|
- **Fast iteration** - single file when possible, inline code over abstraction
|
|
23
|
-
- **
|
|
36
|
+
- **Use real infrastructure** - use the actual database/storage from your tech stack, not mocks
|
|
24
37
|
- **Autonomous execution** - Claude Code writes code, user confirms approach
|
|
25
38
|
|
|
26
39
|
**User Profile:** May not know how to code - Claude Code does the implementation autonomously.
|
|
27
40
|
|
|
28
41
|
---
|
|
29
42
|
|
|
43
|
+
## Quick Reference: Async Boundaries
|
|
44
|
+
|
|
45
|
+
**Where Claude Code MUST wait for user confirmation:**
|
|
46
|
+
|
|
47
|
+
| Phase | Location | Why |
|
|
48
|
+
|-------|----------|-----|
|
|
49
|
+
| Step 3 Phase 1 | Before implementing | User confirms implementation approach |
|
|
50
|
+
| Step 4 Phase 2 | Before creating chores | User confirms proposed stable mode chores |
|
|
51
|
+
|
|
52
|
+
**Where Claude Code executes autonomously:**
|
|
53
|
+
- Step 1: Scenario analysis
|
|
54
|
+
- Step 2: Codebase analysis
|
|
55
|
+
- Step 3 Phase 2: RED→GREEN→REFACTOR loop
|
|
56
|
+
- Step 4 Phases 3-4: Create chores and elevate
|
|
57
|
+
|
|
58
|
+
---
|
|
59
|
+
|
|
30
60
|
## ⚠️ CRITICAL: Speed Mode Workflow Requirements
|
|
31
61
|
|
|
32
62
|
**DO NOT mark features as complete after speed mode implementation.**
|
|
@@ -57,6 +87,11 @@ The validation will require you to:
|
|
|
57
87
|
|
|
58
88
|
## Implementation Steps
|
|
59
89
|
|
|
90
|
+
<!-- ═══════════════════════════════════════════════════════════════════════════
|
|
91
|
+
PHASE 1: AUTONOMOUS ANALYSIS
|
|
92
|
+
No user input required - Claude Code executes independently
|
|
93
|
+
═══════════════════════════════════════════════════════════════════════════ -->
|
|
94
|
+
|
|
60
95
|
### Step 1: Check for Breadcrumbs and Analyze Scenario
|
|
61
96
|
|
|
62
97
|
**CRITICAL:** Claude Code executes this autonomously - no user permission needed.
|
|
@@ -71,32 +106,42 @@ The validation will require you to:
|
|
|
71
106
|
**Code to check for breadcrumbs:**
|
|
72
107
|
|
|
73
108
|
```javascript
|
|
109
|
+
// --- Setup and imports ---
|
|
74
110
|
const { getCurrentWork } = require('../../lib/current-work');
|
|
75
111
|
const { getDb } = require('../../lib/database');
|
|
76
112
|
const fs = require('fs');
|
|
77
113
|
const path = require('path');
|
|
78
114
|
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
currentWork.description
|
|
84
|
-
|
|
85
|
-
|
|
115
|
+
(async () => {
|
|
116
|
+
const currentWork = await getCurrentWork();
|
|
117
|
+
|
|
118
|
+
// --- Check for breadcrumbs ---
|
|
119
|
+
const hasBreadcrumbs = currentWork.description &&
|
|
120
|
+
currentWork.description.includes('Scenario steps addressed:') &&
|
|
121
|
+
currentWork.description.includes('Implementation guidance:') &&
|
|
122
|
+
currentWork.description.includes('Verification:');
|
|
123
|
+
|
|
124
|
+
// --- Get parent feature from database ---
|
|
125
|
+
const db = getDb();
|
|
126
|
+
const feature = await new Promise((resolve, reject) => {
|
|
127
|
+
db.get('SELECT * FROM work_items WHERE id = ?', [currentWork.parent_id], (err, row) => {
|
|
128
|
+
if (err) reject(err);
|
|
129
|
+
else resolve(row);
|
|
130
|
+
});
|
|
131
|
+
});
|
|
86
132
|
|
|
87
|
-
//
|
|
88
|
-
const db = getDb();
|
|
89
|
-
db.get('SELECT * FROM work_items WHERE id = ?', [currentWork.parent_id], (err, feature) => {
|
|
133
|
+
// --- Validate scenario file exists ---
|
|
90
134
|
if (!feature.scenario_file) {
|
|
91
135
|
console.error('No scenario file found for this feature');
|
|
92
136
|
return;
|
|
93
137
|
}
|
|
94
138
|
|
|
139
|
+
// --- Read scenario content ---
|
|
95
140
|
const scenarioPath = path.join(process.cwd(), feature.scenario_file);
|
|
96
141
|
const scenarioContent = fs.readFileSync(scenarioPath, 'utf8');
|
|
97
142
|
|
|
98
143
|
// Parse and analyze...
|
|
99
|
-
});
|
|
144
|
+
})();
|
|
100
145
|
```
|
|
101
146
|
|
|
102
147
|
**Parse Gherkin:**
|
|
@@ -227,6 +272,11 @@ Now proposing implementation approach...
|
|
|
227
272
|
|
|
228
273
|
**Move to Step 3 automatically.**
|
|
229
274
|
|
|
275
|
+
<!-- ═══════════════════════════════════════════════════════════════════════════
|
|
276
|
+
PHASE 2: USER CONFIRMATION REQUIRED
|
|
277
|
+
⚡ ASYNC BOUNDARY - Must wait for user response before proceeding
|
|
278
|
+
═══════════════════════════════════════════════════════════════════════════ -->
|
|
279
|
+
|
|
230
280
|
### Step 3: Propose and Execute Implementation
|
|
231
281
|
|
|
232
282
|
**Two phases: Propose (get user confirmation) → Execute (autonomous)**
|
|
@@ -259,6 +309,11 @@ Sound good? I'll implement this autonomously once you confirm.
|
|
|
259
309
|
|
|
260
310
|
If user adjusts: revise proposal and confirm again.
|
|
261
311
|
|
|
312
|
+
<!-- ═══════════════════════════════════════════════════════════════════════════
|
|
313
|
+
PHASE 3: AUTONOMOUS EXECUTION
|
|
314
|
+
User has confirmed - Claude Code executes RED→GREEN loop independently
|
|
315
|
+
═══════════════════════════════════════════════════════════════════════════ -->
|
|
316
|
+
|
|
262
317
|
#### Phase 2: Autonomous Execution
|
|
263
318
|
|
|
264
319
|
**CRITICAL:** After user confirms, Claude Code executes autonomously - no permission needed for individual code changes.
|
|
@@ -268,15 +323,23 @@ If user adjusts: revise proposal and confirm again.
|
|
|
268
323
|
Before writing any implementation code, run tests to establish the RED state:
|
|
269
324
|
|
|
270
325
|
```javascript
|
|
271
|
-
|
|
326
|
+
// --- Imports ---
|
|
327
|
+
const { runBddScenarioWithTimeout, getFirstScenarioLine, parseTestProgress, extractErrors } = require('./.claude/skills/speed-mode/test-runner');
|
|
272
328
|
const { getCurrentWork } = require('./lib/current-work');
|
|
273
329
|
const { getDb } = require('./lib/database');
|
|
274
330
|
|
|
275
|
-
|
|
276
|
-
|
|
331
|
+
(async () => {
|
|
332
|
+
// --- Get current work and parent feature ---
|
|
333
|
+
const currentWork = await getCurrentWork();
|
|
334
|
+
const db = getDb();
|
|
335
|
+
|
|
336
|
+
const feature = await new Promise((resolve, reject) => {
|
|
337
|
+
db.get('SELECT * FROM work_items WHERE id = ?', [currentWork.parent_id], (err, row) => {
|
|
338
|
+
if (err) reject(err);
|
|
339
|
+
else resolve(row);
|
|
340
|
+
});
|
|
341
|
+
});
|
|
277
342
|
|
|
278
|
-
// Get parent feature and its scenario file
|
|
279
|
-
db.get('SELECT * FROM work_items WHERE id = ?', [currentWork.parent_id], async (err, feature) => {
|
|
280
343
|
if (!feature.scenario_file) {
|
|
281
344
|
console.error('No scenario file found for this feature');
|
|
282
345
|
return;
|
|
@@ -284,28 +347,31 @@ db.get('SELECT * FROM work_items WHERE id = ?', [currentWork.parent_id], async (
|
|
|
284
347
|
|
|
285
348
|
console.log('🔴 Establishing RED baseline...\n');
|
|
286
349
|
|
|
287
|
-
// Find happy path scenario
|
|
350
|
+
// --- Find happy path scenario ---
|
|
288
351
|
const happyPathLine = getFirstScenarioLine(feature.scenario_file);
|
|
289
352
|
if (!happyPathLine) {
|
|
290
353
|
console.error('No scenario found in feature file');
|
|
291
354
|
return;
|
|
292
355
|
}
|
|
293
356
|
|
|
294
|
-
// Run
|
|
357
|
+
// --- Run tests before implementation ---
|
|
295
358
|
const result = await runBddScenarioWithTimeout(feature.scenario_file, happyPathLine);
|
|
359
|
+
let progress = { passed: 0, total: 0, failedSteps: [] };
|
|
296
360
|
|
|
361
|
+
// --- Handle timeout ---
|
|
297
362
|
if (result.timedOut) {
|
|
298
363
|
console.log('⚠️ Test execution timed out - tests may be hanging');
|
|
299
364
|
console.log('Proceeding with implementation...\n');
|
|
300
365
|
} else {
|
|
301
|
-
// Parse
|
|
302
|
-
|
|
366
|
+
// --- Parse and display results ---
|
|
367
|
+
progress = parseTestProgress(result.stdout + result.stderr);
|
|
303
368
|
const errors = extractErrors(result.stdout + result.stderr);
|
|
304
369
|
|
|
305
370
|
console.log(`RED Baseline: ${progress.total - progress.passed} of ${progress.total} steps failing`);
|
|
306
371
|
console.log('\nFailing steps:');
|
|
307
372
|
progress.failedSteps.forEach(step => console.log(` ✖ ${step}`));
|
|
308
373
|
|
|
374
|
+
// --- Show first error ---
|
|
309
375
|
if (errors.errors.length > 0) {
|
|
310
376
|
console.log('\nFirst error:');
|
|
311
377
|
const firstError = errors.errors[0];
|
|
@@ -316,13 +382,13 @@ db.get('SELECT * FROM work_items WHERE id = ?', [currentWork.parent_id], async (
|
|
|
316
382
|
console.log('\n🎯 Goal: Make all steps pass\n');
|
|
317
383
|
}
|
|
318
384
|
|
|
319
|
-
// Store baseline for
|
|
385
|
+
// --- Store baseline for iteration loop ---
|
|
320
386
|
global.redBaseline = {
|
|
321
387
|
passed: progress.passed,
|
|
322
388
|
total: progress.total,
|
|
323
389
|
failedSteps: progress.failedSteps
|
|
324
390
|
};
|
|
325
|
-
});
|
|
391
|
+
})();
|
|
326
392
|
```
|
|
327
393
|
|
|
328
394
|
**Display RED baseline:**
|
|
@@ -351,39 +417,54 @@ Now implementing...
|
|
|
351
417
|
|
|
352
418
|
Iterate until all tests pass or MAX_ITERATIONS reached:
|
|
353
419
|
|
|
420
|
+
<!-- ┌─────────────────────────────────────────────────────────────────────────┐
|
|
421
|
+
│ 🔄 ITERATION LOOP: RED→GREEN │
|
|
422
|
+
│ │
|
|
423
|
+
│ Progress Tracking: │
|
|
424
|
+
│ • Display: "Iteration X/10" at start of each cycle │
|
|
425
|
+
│ • Track: steps passing vs total, newly passing steps │
|
|
426
|
+
│ • Goal: All steps pass (exit code 0) │
|
|
427
|
+
│ │
|
|
428
|
+
│ Return Points: │
|
|
429
|
+
│ • CHECKPOINT_ITERATION: Resume at specific iteration number │
|
|
430
|
+
│ • CHECKPOINT_PROGRESS: Resume with known passing step count │
|
|
431
|
+
│ • If session interrupted, can resume from last known iteration │
|
|
432
|
+
└─────────────────────────────────────────────────────────────────────────┘ -->
|
|
433
|
+
|
|
354
434
|
```javascript
|
|
435
|
+
// --- Imports and setup ---
|
|
355
436
|
const { runBddScenarioWithTimeout, parseTestProgress, findNewlyPassingSteps, extractErrors, MAX_ITERATIONS } = require('./.claude/skills/speed-mode/test-runner');
|
|
356
437
|
|
|
357
438
|
let previousResult = global.redBaseline; // From Step 1
|
|
358
439
|
let iteration = 0;
|
|
359
440
|
|
|
441
|
+
// --- Main iteration loop ---
|
|
442
|
+
// 📊 PROGRESS: Iteration {iteration}/{MAX_ITERATIONS} | Steps: {passed}/{total}
|
|
360
443
|
while (iteration < MAX_ITERATIONS) {
|
|
361
444
|
iteration++;
|
|
362
|
-
|
|
363
445
|
console.log(`\n━━━ Iteration ${iteration}/${MAX_ITERATIONS} ━━━`);
|
|
364
446
|
|
|
365
|
-
//
|
|
447
|
+
// --- Make code changes ---
|
|
366
448
|
console.log(`\n✍️ Making code changes...`);
|
|
367
449
|
// [Claude Code writes implementation code here using Write/Edit tools]
|
|
368
450
|
|
|
369
|
-
//
|
|
451
|
+
// --- Run tests ---
|
|
370
452
|
console.log(`\n🧪 Running tests...`);
|
|
371
453
|
const result = await runBddScenarioWithTimeout(feature.scenario_file, happyPathLine);
|
|
372
454
|
|
|
455
|
+
// --- Handle timeout ---
|
|
373
456
|
if (result.timedOut) {
|
|
374
457
|
console.log(`⚠️ Test execution timed out - tests may be hanging`);
|
|
375
458
|
console.log(`Stopping iteration loop`);
|
|
376
459
|
break;
|
|
377
460
|
}
|
|
378
461
|
|
|
379
|
-
//
|
|
462
|
+
// --- Parse results and track progress ---
|
|
380
463
|
const currentResult = parseTestProgress(result.stdout + result.stderr);
|
|
381
464
|
const errors = extractErrors(result.stdout + result.stderr);
|
|
382
|
-
|
|
383
|
-
// 4. Track progress
|
|
384
465
|
const newlyPassing = findNewlyPassingSteps(previousResult, currentResult);
|
|
385
466
|
|
|
386
|
-
//
|
|
467
|
+
// --- Display progress ---
|
|
387
468
|
console.log(`\n📊 Progress: ${currentResult.passed}/${currentResult.total} steps passing`);
|
|
388
469
|
|
|
389
470
|
if (newlyPassing.length > 0) {
|
|
@@ -391,20 +472,20 @@ while (iteration < MAX_ITERATIONS) {
|
|
|
391
472
|
newlyPassing.forEach(step => console.log(` • ${step}`));
|
|
392
473
|
}
|
|
393
474
|
|
|
394
|
-
//
|
|
475
|
+
// --- Check for GREEN state ---
|
|
395
476
|
if (currentResult.exitCode === 0 || currentResult.passed === currentResult.total) {
|
|
396
477
|
console.log(`\n🎉 GREEN: All tests passing!`);
|
|
397
478
|
break;
|
|
398
479
|
}
|
|
399
480
|
|
|
400
|
-
//
|
|
481
|
+
// --- Display next failure ---
|
|
401
482
|
if (errors.errors.length > 0) {
|
|
402
483
|
const nextError = errors.errors[0];
|
|
403
484
|
console.log(`\n🔧 Next failure to address:`);
|
|
404
485
|
console.log(` Step: ${nextError.step}`);
|
|
405
486
|
console.log(` Error: ${nextError.message}`);
|
|
406
487
|
if (nextError.stack) {
|
|
407
|
-
console.log(` Stack: ${nextError.stack.split('\n')[0]}`);
|
|
488
|
+
console.log(` Stack: ${nextError.stack.split('\n')[0]}`);
|
|
408
489
|
}
|
|
409
490
|
} else if (currentResult.failedSteps.length > 0) {
|
|
410
491
|
console.log(`\n🔧 Still failing:`);
|
|
@@ -414,11 +495,10 @@ while (iteration < MAX_ITERATIONS) {
|
|
|
414
495
|
}
|
|
415
496
|
}
|
|
416
497
|
|
|
417
|
-
// Store for next iteration comparison
|
|
418
498
|
previousResult = currentResult;
|
|
419
499
|
}
|
|
420
500
|
|
|
421
|
-
//
|
|
501
|
+
// --- Handle max iterations reached ---
|
|
422
502
|
if (iteration >= MAX_ITERATIONS) {
|
|
423
503
|
console.log(`\n⚠️ Maximum iterations (${MAX_ITERATIONS}) reached without achieving GREEN`);
|
|
424
504
|
console.log(`Final progress: ${previousResult.passed}/${previousResult.total} steps passing`);
|
|
@@ -489,13 +569,33 @@ Modified src/dashboard.js
|
|
|
489
569
|
- **Single file when possible** - keep it simple
|
|
490
570
|
- **NO error handling** - no try/catch, no validation, no edge cases
|
|
491
571
|
- **Assume everything works** - valid inputs, successful operations, correct types
|
|
492
|
-
- **
|
|
572
|
+
- **Use real infrastructure** - actual database/storage from your tech stack
|
|
493
573
|
- **Inline code over separate modules** - keep it simple
|
|
494
574
|
- **Focus: Make. All. Features. Work.** (on the happy path)
|
|
495
575
|
|
|
496
|
-
**Step 3:
|
|
576
|
+
**Step 3: REFACTOR**
|
|
577
|
+
|
|
578
|
+
After GREEN is achieved, do a quick refactor pass:
|
|
579
|
+
|
|
580
|
+
1. **Extract duplicated code** - DRY up any copy-pasted logic
|
|
581
|
+
2. **Rename unclear variables** - make intent obvious
|
|
582
|
+
3. **Simplify complex expressions** - break into readable steps
|
|
583
|
+
4. **Remove dead code** - delete unused variables/functions
|
|
584
|
+
|
|
585
|
+
**Keep it fast** - 5 minutes max. Major refactoring happens in stable mode.
|
|
497
586
|
|
|
498
|
-
|
|
587
|
+
**Re-run tests after refactoring** to ensure nothing broke:
|
|
588
|
+
|
|
589
|
+
```javascript
|
|
590
|
+
const result = await runBddScenarioWithTimeout(feature.scenario_file, scenarioLine);
|
|
591
|
+
if (result.exitCode !== 0) {
|
|
592
|
+
console.log('⚠️ Refactoring broke tests - revert and try again');
|
|
593
|
+
}
|
|
594
|
+
```
|
|
595
|
+
|
|
596
|
+
**Step 4: Final Verification and Completion**
|
|
597
|
+
|
|
598
|
+
After GREEN + REFACTOR, run full feature file once to verify no regressions:
|
|
499
599
|
|
|
500
600
|
```javascript
|
|
501
601
|
// After iteration loop succeeds (GREEN achieved)
|
|
@@ -504,8 +604,8 @@ if (currentResult.exitCode === 0 || currentResult.passed === currentResult.total
|
|
|
504
604
|
console.log(`\n🔍 Running full verification (all scenarios)...`);
|
|
505
605
|
|
|
506
606
|
// Run entire feature file once for regression detection
|
|
507
|
-
|
|
508
|
-
const fullResult = await
|
|
607
|
+
// Uses the already imported runBddScenarioWithTimeout with no line number to run all scenarios
|
|
608
|
+
const fullResult = await runBddScenarioWithTimeout(feature.scenario_file);
|
|
509
609
|
|
|
510
610
|
if (fullResult.timedOut) {
|
|
511
611
|
console.log(`⚠️ Full verification timed out`);
|
|
@@ -550,35 +650,34 @@ if (filesModified.length > 0) {
|
|
|
550
650
|
console.log();
|
|
551
651
|
}
|
|
552
652
|
|
|
553
|
-
//
|
|
554
|
-
|
|
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
|
-
}
|
|
653
|
+
// --- Create unit tests for new functions ---
|
|
654
|
+
// For each new function implemented, create a unit test file with happy path coverage
|
|
573
655
|
|
|
574
|
-
|
|
575
|
-
|
|
576
|
-
|
|
577
|
-
}
|
|
578
|
-
|
|
579
|
-
|
|
656
|
+
// Unit test template for new functions:
|
|
657
|
+
// test/[filename].test.js or __tests__/[filename].test.js
|
|
658
|
+
/*
|
|
659
|
+
const { functionName } = require('../src/path/to/module');
|
|
660
|
+
|
|
661
|
+
describe('functionName', () => {
|
|
662
|
+
it('should handle valid input successfully', () => {
|
|
663
|
+
// Arrange
|
|
664
|
+
const input = validTestData;
|
|
665
|
+
|
|
666
|
+
// Act
|
|
667
|
+
const result = functionName(input);
|
|
580
668
|
|
|
581
|
-
|
|
669
|
+
// Assert
|
|
670
|
+
expect(result).toEqual(expectedOutput);
|
|
671
|
+
});
|
|
672
|
+
});
|
|
673
|
+
*/
|
|
674
|
+
|
|
675
|
+
// Speed mode unit tests focus on:
|
|
676
|
+
// - Happy path with valid input
|
|
677
|
+
// - One successful operation per function
|
|
678
|
+
// - Basic return value verification
|
|
679
|
+
|
|
680
|
+
console.log(`Next step: Elevate to stable mode using 'jettypod work set-mode <feature-id> stable'\n`);
|
|
582
681
|
```
|
|
583
682
|
|
|
584
683
|
**Display:**
|
|
@@ -607,10 +706,12 @@ Next step: Elevate to stable mode using 'node jettypod.js work set-mode <feature
|
|
|
607
706
|
**On FAILURE (max iterations or timeout):**
|
|
608
707
|
|
|
609
708
|
```javascript
|
|
709
|
+
// --- Display failure header ---
|
|
610
710
|
console.log(`\n━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━`);
|
|
611
711
|
console.log(`⚠️ SPEED MODE INCOMPLETE - STILL IN RED STATE`);
|
|
612
712
|
console.log(`━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n`);
|
|
613
713
|
|
|
714
|
+
// --- Handle timeout case ---
|
|
614
715
|
if (result.timedOut) {
|
|
615
716
|
console.log(`❌ Test execution timed out`);
|
|
616
717
|
console.log(`\nPossible causes:`);
|
|
@@ -618,15 +719,18 @@ if (result.timedOut) {
|
|
|
618
719
|
console.log(` • Test is waiting for async operation that never completes`);
|
|
619
720
|
console.log(` • Step definition has blocking code`);
|
|
620
721
|
} else {
|
|
722
|
+
// --- Handle max iterations case ---
|
|
621
723
|
console.log(`❌ Maximum iterations (${MAX_ITERATIONS}) reached\n`);
|
|
622
724
|
console.log(`Final Progress: ${previousResult.passed}/${previousResult.total} steps passing\n`);
|
|
623
725
|
|
|
726
|
+
// --- Display failing steps ---
|
|
624
727
|
if (previousResult.failedSteps.length > 0) {
|
|
625
728
|
console.log(`Still failing:`);
|
|
626
729
|
previousResult.failedSteps.forEach(step => console.log(` ✖ ${step}`));
|
|
627
730
|
console.log();
|
|
628
731
|
}
|
|
629
732
|
|
|
733
|
+
// --- Display remaining errors ---
|
|
630
734
|
const errors = extractErrors(result.stdout + result.stderr);
|
|
631
735
|
if (errors.errors.length > 0) {
|
|
632
736
|
console.log(`Remaining errors:`);
|
|
@@ -637,6 +741,7 @@ if (result.timedOut) {
|
|
|
637
741
|
}
|
|
638
742
|
}
|
|
639
743
|
|
|
744
|
+
// --- Display next steps ---
|
|
640
745
|
console.log(`\nWhat to do:`);
|
|
641
746
|
console.log(` • Review implementation approach - is it the right strategy?`);
|
|
642
747
|
console.log(` • Check for incorrect assumptions about existing code`);
|
|
@@ -678,6 +783,11 @@ DO NOT proceed to generate stable mode chores until GREEN is achieved.
|
|
|
678
783
|
|
|
679
784
|
**Move to Step 4 only if GREEN achieved.**
|
|
680
785
|
|
|
786
|
+
<!-- ═══════════════════════════════════════════════════════════════════════════
|
|
787
|
+
PHASE 4: STABLE CHORE GENERATION
|
|
788
|
+
⚡ ASYNC BOUNDARY - Must wait for user to confirm proposed chores
|
|
789
|
+
═══════════════════════════════════════════════════════════════════════════ -->
|
|
790
|
+
|
|
681
791
|
### Step 4: Generate Stable Mode Chores
|
|
682
792
|
|
|
683
793
|
**Two phases: Analyze and propose → Get confirmation → Create autonomously**
|
|
@@ -741,6 +851,11 @@ Sound good? I'll create these chores once you confirm.
|
|
|
741
851
|
|
|
742
852
|
If user adjusts: revise chores and confirm again.
|
|
743
853
|
|
|
854
|
+
<!-- ═══════════════════════════════════════════════════════════════════════════
|
|
855
|
+
PHASE 5: AUTONOMOUS COMPLETION
|
|
856
|
+
User has confirmed chores - create them and finalize
|
|
857
|
+
═══════════════════════════════════════════════════════════════════════════ -->
|
|
858
|
+
|
|
744
859
|
#### Phase 3: Create Chores Autonomously
|
|
745
860
|
|
|
746
861
|
**CRITICAL:** After user confirms, create chores programmatically - no additional permission needed.
|
|
@@ -751,11 +866,13 @@ If user adjusts: revise chores and confirm again.
|
|
|
751
866
|
const { create } = require('./features/work-tracking');
|
|
752
867
|
const { getCurrentWork } = require('../../lib/current-work');
|
|
753
868
|
|
|
754
|
-
|
|
755
|
-
const
|
|
869
|
+
(async () => {
|
|
870
|
+
const currentWork = await getCurrentWork();
|
|
871
|
+
const featureId = currentWork.parent_id; // Parent feature
|
|
756
872
|
|
|
757
|
-
// For each confirmed chore:
|
|
758
|
-
await create('chore', 'Chore Title', 'Description', featureId, 'stable', false);
|
|
873
|
+
// For each confirmed chore:
|
|
874
|
+
await create('chore', 'Chore Title', 'Description', featureId, 'stable', false);
|
|
875
|
+
})();
|
|
759
876
|
```
|
|
760
877
|
|
|
761
878
|
**Display results:**
|
|
@@ -773,42 +890,56 @@ Chores created:
|
|
|
773
890
|
|
|
774
891
|
**CRITICAL: Check if ALL speed mode chores are complete. If yes, auto-elevate to stable mode.**
|
|
775
892
|
|
|
893
|
+
<!-- ┌─────────────────────────────────────────────────────────────────────────┐
|
|
894
|
+
│ 🔍 COMPLETION CHECK: Speed Chores │
|
|
895
|
+
│ │
|
|
896
|
+
│ Progress Tracking: │
|
|
897
|
+
│ • Query: Count incomplete speed chores for feature │
|
|
898
|
+
│ • Display: "X speed mode chores remaining" or "All complete" │
|
|
899
|
+
│ • Action: Auto-elevate if all complete │
|
|
900
|
+
│ │
|
|
901
|
+
│ Return Point: │
|
|
902
|
+
│ • CHECKPOINT_CHORE_COUNT: Known incomplete count from last check │
|
|
903
|
+
│ • If session interrupted, re-query to get current count │
|
|
904
|
+
└─────────────────────────────────────────────────────────────────────────┘ -->
|
|
905
|
+
|
|
776
906
|
```javascript
|
|
777
|
-
//
|
|
907
|
+
// --- Imports ---
|
|
778
908
|
const { getDb } = require('../../lib/database');
|
|
779
909
|
const { getCurrentWork } = require('../../lib/current-work');
|
|
780
910
|
|
|
781
|
-
|
|
782
|
-
|
|
783
|
-
|
|
784
|
-
const
|
|
785
|
-
db
|
|
786
|
-
|
|
787
|
-
|
|
788
|
-
|
|
789
|
-
|
|
790
|
-
|
|
791
|
-
|
|
792
|
-
|
|
793
|
-
|
|
794
|
-
|
|
795
|
-
|
|
796
|
-
|
|
797
|
-
|
|
911
|
+
(async () => {
|
|
912
|
+
// --- Get current work context ---
|
|
913
|
+
const currentWork = await getCurrentWork();
|
|
914
|
+
const featureId = currentWork.parent_id;
|
|
915
|
+
const db = getDb();
|
|
916
|
+
|
|
917
|
+
// --- Query for incomplete speed chores ---
|
|
918
|
+
const result = await new Promise((resolve, reject) => {
|
|
919
|
+
db.get(`
|
|
920
|
+
SELECT COUNT(*) as incomplete_count
|
|
921
|
+
FROM work_items
|
|
922
|
+
WHERE parent_id = ?
|
|
923
|
+
AND type = 'chore'
|
|
924
|
+
AND mode = 'speed'
|
|
925
|
+
AND status != 'done'
|
|
926
|
+
`, [featureId], (err, row) => {
|
|
927
|
+
if (err) reject(err);
|
|
928
|
+
else resolve(row);
|
|
929
|
+
});
|
|
930
|
+
});
|
|
798
931
|
|
|
932
|
+
// --- Handle completion or remaining chores ---
|
|
799
933
|
if (result.incomplete_count === 0) {
|
|
800
|
-
// All speed chores done - auto-elevate to stable
|
|
801
934
|
console.log('\n✅ All speed mode chores complete!');
|
|
802
935
|
console.log('Auto-elevating feature to stable mode...\n');
|
|
803
|
-
|
|
804
936
|
// Use Bash tool to execute elevation
|
|
805
|
-
// DO NOT display as text - EXECUTE IT
|
|
806
937
|
} else {
|
|
807
938
|
console.log(`\n📋 ${result.incomplete_count} speed mode chores remaining`);
|
|
808
939
|
}
|
|
809
940
|
|
|
810
941
|
db.close();
|
|
811
|
-
});
|
|
942
|
+
})();
|
|
812
943
|
```
|
|
813
944
|
|
|
814
945
|
**If all speed chores are done, use Bash tool to EXECUTE elevation:**
|