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.
@@ -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
- - **Pragmatic** - localStorage for data, simple implementations
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
- const currentWork = getCurrentWork();
80
-
81
- // Check if description has breadcrumbs from feature-planning
82
- const hasBreadcrumbs = currentWork.description &&
83
- currentWork.description.includes('Scenario steps addressed:') &&
84
- currentWork.description.includes('Implementation guidance:') &&
85
- currentWork.description.includes('Verification:');
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
- // Get parent feature
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
- const { runBddTestWithTimeout, runBddScenarioWithTimeout, getFirstScenarioLine, parseTestProgress, extractErrors } = require('./.claude/skills/speed-mode/test-runner');
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
- const currentWork = getCurrentWork();
276
- const db = getDb();
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 (first scenario in file)
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 only happy path scenario before any code is written
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 the test output
302
- const progress = parseTestProgress(result.stdout + result.stderr);
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 comparison in iteration loop (chore #115)
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
- // 1. Make code changes based on current failure
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
- // 2. Run tests - only happy path scenario during iteration
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
- // 3. Parse results
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
- // 5. Display progress
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
- // 6. Check if all tests pass (GREEN state achieved)
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
- // 7. Display next failure to address
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]}`); // First line only
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
- // After loop ends
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
- - **localStorage/memory for data** - no full database setup
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: Final Verification and Completion**
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
- After GREEN is achieved, run full feature file once to verify no regressions:
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
- const { runBddTestWithTimeout } = require('./.claude/skills/speed-mode/test-runner');
508
- const fullResult = await runBddTestWithTimeout(feature.scenario_file);
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
- // 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
- }
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
- 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
- }
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
- console.log(`Next step: Elevate to stable mode using 'node jettypod.js work set-mode <feature-id> stable'\n`);
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
- const currentWork = getCurrentWork();
755
- const featureId = currentWork.parent_id; // Parent feature
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
- // Check if all speed chores for this feature are done
907
+ // --- Imports ---
778
908
  const { getDb } = require('../../lib/database');
779
909
  const { getCurrentWork } = require('../../lib/current-work');
780
910
 
781
- const currentWork = getCurrentWork();
782
- const featureId = currentWork.parent_id;
783
-
784
- const db = getDb();
785
- db.get(`
786
- SELECT COUNT(*) as incomplete_count
787
- FROM work_items
788
- WHERE parent_id = ?
789
- AND type = 'chore'
790
- AND mode = 'speed'
791
- AND status != 'done'
792
- `, [featureId], async (err, result) => {
793
- if (err) {
794
- console.error('Error checking speed chores:', err.message);
795
- db.close();
796
- return;
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:**