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
|
@@ -1,713 +0,0 @@
|
|
|
1
|
-
---
|
|
2
|
-
name: stable-mode
|
|
3
|
-
description: Guide implementation of stable mode chores with comprehensive testing and error handling. Use when user starts work on a stable mode chore. Analyzes BDD scenarios, reviews speed mode implementation, and adds proper error handling, validation, and edge case coverage.
|
|
4
|
-
---
|
|
5
|
-
|
|
6
|
-
# Stable Mode Skill
|
|
7
|
-
|
|
8
|
-
Guides Claude Code through stable mode implementation with comprehensive testing focus. Users confirm approach but Claude Code writes the code.
|
|
9
|
-
|
|
10
|
-
## Instructions
|
|
11
|
-
|
|
12
|
-
When this skill is activated, you are helping implement a stable mode chore to add comprehensive testing and error handling. Follow this structured approach:
|
|
13
|
-
|
|
14
|
-
### Overview
|
|
15
|
-
|
|
16
|
-
**Stable Mode Goal:** Add error handling, validation, and edge case coverage to the speed mode implementation.
|
|
17
|
-
|
|
18
|
-
**CRITICAL DISTINCTION:**
|
|
19
|
-
- **Speed mode implemented ALL functionality** - every feature/function is already working on the happy path
|
|
20
|
-
- **Stable mode adds robustness** - error handling, validation, edge cases, error messages
|
|
21
|
-
|
|
22
|
-
**Key Principles:**
|
|
23
|
-
- **Build on speed implementation** - do not re-implement features, ADD to them
|
|
24
|
-
- **Comprehensive error handling** - catch all failure modes, show clear error messages
|
|
25
|
-
- **Input validation** - validate all inputs, handle edge cases (empty, null, max values, wrong types)
|
|
26
|
-
- **Edge case coverage** - handle boundary conditions, race conditions, state consistency
|
|
27
|
-
- **All BDD scenarios pass** - happy path AND error/edge case scenarios
|
|
28
|
-
- **Autonomous execution** - Claude Code writes code, user confirms approach
|
|
29
|
-
|
|
30
|
-
**User Profile:** May not know how to code - Claude Code does the implementation autonomously.
|
|
31
|
-
|
|
32
|
-
---
|
|
33
|
-
|
|
34
|
-
## Implementation Steps
|
|
35
|
-
|
|
36
|
-
### Step 0: Create Additional Scenarios (If First Stable Chore)
|
|
37
|
-
|
|
38
|
-
**CRITICAL:** If this is the FIRST stable mode chore for this feature, you must ADD edge case scenarios and step definitions.
|
|
39
|
-
|
|
40
|
-
**Check if scenarios exist beyond happy path:**
|
|
41
|
-
1. Read the feature's `.feature` file
|
|
42
|
-
2. Count scenarios - if only 1 (happy path), ADD edge case scenarios
|
|
43
|
-
3. Update step definitions to include new scenarios
|
|
44
|
-
|
|
45
|
-
**Add to `.feature` file:**
|
|
46
|
-
```gherkin
|
|
47
|
-
# Error handling scenario
|
|
48
|
-
Scenario: [Error case title]
|
|
49
|
-
Given [setup for error condition]
|
|
50
|
-
When [action that triggers error]
|
|
51
|
-
Then [expected error handling]
|
|
52
|
-
And [system remains stable]
|
|
53
|
-
|
|
54
|
-
# Edge case scenario
|
|
55
|
-
Scenario: [Edge case title]
|
|
56
|
-
Given [edge condition setup]
|
|
57
|
-
When [action at boundary]
|
|
58
|
-
Then [expected edge case behavior]
|
|
59
|
-
```
|
|
60
|
-
|
|
61
|
-
**Add to `features/step_definitions/[feature-slug].steps.js`:**
|
|
62
|
-
- Implement Given/When/Then steps for new scenarios
|
|
63
|
-
- Follow existing patterns from happy path steps
|
|
64
|
-
- Include proper error assertions
|
|
65
|
-
|
|
66
|
-
**IMPORTANT:** Only do this ONCE per feature (first stable chore). Subsequent stable chores implement existing scenarios.
|
|
67
|
-
|
|
68
|
-
### Step 1: Analyze Scenario to Implement
|
|
69
|
-
|
|
70
|
-
**CRITICAL:** Claude Code executes this autonomously - no user permission needed.
|
|
71
|
-
|
|
72
|
-
**Your task:**
|
|
73
|
-
1. Get current work item and parent feature's scenario file
|
|
74
|
-
2. Read the full scenario file (should now have happy path + edge cases)
|
|
75
|
-
3. Identify which scenario this chore addresses
|
|
76
|
-
4. Extract requirements from the scenario's Given/When/Then steps
|
|
77
|
-
|
|
78
|
-
**Code to get scenario (with error handling):**
|
|
79
|
-
|
|
80
|
-
```javascript
|
|
81
|
-
const { getCurrentWork } = require('../../lib/current-work');
|
|
82
|
-
const { getDb } = require('../../lib/database');
|
|
83
|
-
const fs = require('fs');
|
|
84
|
-
const path = require('path');
|
|
85
|
-
|
|
86
|
-
try {
|
|
87
|
-
const currentWork = getCurrentWork();
|
|
88
|
-
|
|
89
|
-
// Error handling: Check if current work exists
|
|
90
|
-
if (!currentWork) {
|
|
91
|
-
console.error('ā No current work found. Run: jettypod work start <chore-id>');
|
|
92
|
-
return;
|
|
93
|
-
}
|
|
94
|
-
|
|
95
|
-
// Error handling: Check if parent exists
|
|
96
|
-
if (!currentWork.parent_id) {
|
|
97
|
-
console.error('ā Current work has no parent feature. This chore must be part of a feature.');
|
|
98
|
-
return;
|
|
99
|
-
}
|
|
100
|
-
|
|
101
|
-
const db = getDb();
|
|
102
|
-
db.get('SELECT * FROM work_items WHERE id = ?', [currentWork.parent_id], (err, feature) => {
|
|
103
|
-
// Error handling: Database errors
|
|
104
|
-
if (err) {
|
|
105
|
-
console.error('ā Database error:', err.message);
|
|
106
|
-
db.close();
|
|
107
|
-
return;
|
|
108
|
-
}
|
|
109
|
-
|
|
110
|
-
// Error handling: Feature not found
|
|
111
|
-
if (!feature) {
|
|
112
|
-
console.error('ā Parent feature not found in database.');
|
|
113
|
-
db.close();
|
|
114
|
-
return;
|
|
115
|
-
}
|
|
116
|
-
|
|
117
|
-
// Error handling: No scenario file
|
|
118
|
-
if (!feature.scenario_file) {
|
|
119
|
-
console.error('ā Feature has no scenario_file. Cannot determine what to implement.');
|
|
120
|
-
console.log('Suggestion: Create a scenario file and update the feature.');
|
|
121
|
-
db.close();
|
|
122
|
-
return;
|
|
123
|
-
}
|
|
124
|
-
|
|
125
|
-
const scenarioPath = path.join(process.cwd(), feature.scenario_file);
|
|
126
|
-
|
|
127
|
-
// Error handling: Scenario file doesn't exist
|
|
128
|
-
if (!fs.existsSync(scenarioPath)) {
|
|
129
|
-
console.error(`ā Scenario file not found: ${scenarioPath}`);
|
|
130
|
-
console.log('Suggestion: Create the scenario file or update the feature.scenario_file path.');
|
|
131
|
-
db.close();
|
|
132
|
-
return;
|
|
133
|
-
}
|
|
134
|
-
|
|
135
|
-
// Error handling: File read errors
|
|
136
|
-
let scenarioContent;
|
|
137
|
-
try {
|
|
138
|
-
scenarioContent = fs.readFileSync(scenarioPath, 'utf8');
|
|
139
|
-
} catch (readErr) {
|
|
140
|
-
console.error(`ā Cannot read scenario file: ${readErr.message}`);
|
|
141
|
-
db.close();
|
|
142
|
-
return;
|
|
143
|
-
}
|
|
144
|
-
|
|
145
|
-
// Error handling: Empty scenario file
|
|
146
|
-
if (!scenarioContent || scenarioContent.trim().length === 0) {
|
|
147
|
-
console.error('ā Scenario file is empty.');
|
|
148
|
-
db.close();
|
|
149
|
-
return;
|
|
150
|
-
}
|
|
151
|
-
|
|
152
|
-
// Parse all scenarios...
|
|
153
|
-
db.close();
|
|
154
|
-
});
|
|
155
|
-
} catch (err) {
|
|
156
|
-
console.error('ā Unexpected error in Step 1:', err.message);
|
|
157
|
-
return;
|
|
158
|
-
}
|
|
159
|
-
```
|
|
160
|
-
|
|
161
|
-
**Identify target scenario (with error handling):**
|
|
162
|
-
|
|
163
|
-
```javascript
|
|
164
|
-
// Parse scenarios from Gherkin content
|
|
165
|
-
const scenarios = [];
|
|
166
|
-
const scenarioBlocks = scenarioContent.split(/\nScenario:/);
|
|
167
|
-
|
|
168
|
-
// Error handling: No scenarios found
|
|
169
|
-
if (scenarioBlocks.length < 2) {
|
|
170
|
-
console.error('ā No scenarios found in scenario file.');
|
|
171
|
-
console.log('Suggestion: Add Gherkin scenarios to the feature file.');
|
|
172
|
-
return;
|
|
173
|
-
}
|
|
174
|
-
|
|
175
|
-
// Parse each scenario
|
|
176
|
-
for (let i = 1; i < scenarioBlocks.length; i++) {
|
|
177
|
-
const block = 'Scenario:' + scenarioBlocks[i];
|
|
178
|
-
const titleMatch = block.match(/Scenario:\s*(.+)/);
|
|
179
|
-
const title = titleMatch ? titleMatch[1].trim() : 'Unknown';
|
|
180
|
-
scenarios.push({ title, content: block });
|
|
181
|
-
}
|
|
182
|
-
|
|
183
|
-
// Match scenario to chore
|
|
184
|
-
const choreDesc = currentWork.description.toLowerCase();
|
|
185
|
-
let targetScenario = null;
|
|
186
|
-
|
|
187
|
-
// Try to match by scenario number in chore description
|
|
188
|
-
const scenarioNumMatch = choreDesc.match(/scenario\s+(\d+)/);
|
|
189
|
-
if (scenarioNumMatch) {
|
|
190
|
-
const num = parseInt(scenarioNumMatch[1]);
|
|
191
|
-
if (num > 0 && num <= scenarios.length) {
|
|
192
|
-
targetScenario = scenarios[num - 1];
|
|
193
|
-
}
|
|
194
|
-
}
|
|
195
|
-
|
|
196
|
-
// Try to match by keywords if no number match
|
|
197
|
-
if (!targetScenario) {
|
|
198
|
-
for (const scenario of scenarios) {
|
|
199
|
-
const scenarioLower = scenario.title.toLowerCase();
|
|
200
|
-
// Skip happy path (usually first scenario)
|
|
201
|
-
if (scenarios.indexOf(scenario) === 0) continue;
|
|
202
|
-
|
|
203
|
-
// Match keywords from chore description
|
|
204
|
-
const keywords = choreDesc.split(/\s+/).filter(w => w.length > 3);
|
|
205
|
-
const matches = keywords.filter(k => scenarioLower.includes(k));
|
|
206
|
-
|
|
207
|
-
if (matches.length > 0) {
|
|
208
|
-
targetScenario = scenario;
|
|
209
|
-
break;
|
|
210
|
-
}
|
|
211
|
-
}
|
|
212
|
-
}
|
|
213
|
-
|
|
214
|
-
// Error handling: No matching scenario
|
|
215
|
-
if (!targetScenario) {
|
|
216
|
-
console.error('ā Cannot match chore to any scenario in feature file.');
|
|
217
|
-
console.log('Available scenarios:');
|
|
218
|
-
scenarios.forEach((s, i) => console.log(` ${i + 1}. ${s.title}`));
|
|
219
|
-
console.log('\nSuggestion: Update chore description to reference a specific scenario.');
|
|
220
|
-
return;
|
|
221
|
-
}
|
|
222
|
-
```
|
|
223
|
-
|
|
224
|
-
**Display to user:**
|
|
225
|
-
|
|
226
|
-
```
|
|
227
|
-
š§Ŗ Stable Mode: [Feature Name]
|
|
228
|
-
|
|
229
|
-
Target Scenario:
|
|
230
|
-
[Scenario title]
|
|
231
|
-
|
|
232
|
-
What needs to happen:
|
|
233
|
-
⢠[Given] Initial state: [requirement]
|
|
234
|
-
⢠[When] Action/condition: [requirement]
|
|
235
|
-
⢠[Then] Expected behavior: [requirement]
|
|
236
|
-
|
|
237
|
-
Now reviewing speed mode implementation...
|
|
238
|
-
```
|
|
239
|
-
|
|
240
|
-
**Move to Step 2 automatically.**
|
|
241
|
-
|
|
242
|
-
### Step 2: Review Speed Mode Implementation
|
|
243
|
-
|
|
244
|
-
**CRITICAL:** Claude Code executes this autonomously - no user permission needed.
|
|
245
|
-
|
|
246
|
-
**Your task:**
|
|
247
|
-
1. Find files created/modified in speed mode
|
|
248
|
-
2. Read the existing implementation
|
|
249
|
-
3. Identify what's missing for this scenario
|
|
250
|
-
4. Understand current code structure
|
|
251
|
-
|
|
252
|
-
**Find speed mode files (with error handling):**
|
|
253
|
-
|
|
254
|
-
```javascript
|
|
255
|
-
const { exec } = require('child_process');
|
|
256
|
-
const util = require('util');
|
|
257
|
-
const execPromise = util.promisify(exec);
|
|
258
|
-
|
|
259
|
-
// Try to find files from git history
|
|
260
|
-
let speedModeFiles = [];
|
|
261
|
-
|
|
262
|
-
try {
|
|
263
|
-
// Get commits for this feature
|
|
264
|
-
const featureName = feature.title.toLowerCase().replace(/\s+/g, '-');
|
|
265
|
-
const { stdout: gitLog } = await execPromise(
|
|
266
|
-
`git log --oneline --all --grep="${featureName}" -10`
|
|
267
|
-
);
|
|
268
|
-
|
|
269
|
-
// Error handling: No commits found
|
|
270
|
-
if (!gitLog || gitLog.trim().length === 0) {
|
|
271
|
-
console.log('ā ļø No git commits found for this feature.');
|
|
272
|
-
console.log('Asking user for files created in speed mode...');
|
|
273
|
-
|
|
274
|
-
// Ask user which files were created
|
|
275
|
-
console.log('\nš Which files did speed mode create/modify for this feature?');
|
|
276
|
-
console.log('(List file paths, one per line, or type "none" if no files exist)\n');
|
|
277
|
-
|
|
278
|
-
// Wait for user response...
|
|
279
|
-
// If user says "none", handle gracefully
|
|
280
|
-
return;
|
|
281
|
-
}
|
|
282
|
-
|
|
283
|
-
// Get files changed in those commits
|
|
284
|
-
const commits = gitLog.trim().split('\n').map(line => line.split(' ')[0]);
|
|
285
|
-
|
|
286
|
-
for (const commit of commits) {
|
|
287
|
-
try {
|
|
288
|
-
const { stdout: files } = await execPromise(`git diff-tree --no-commit-id --name-only -r ${commit}`);
|
|
289
|
-
const fileList = files.trim().split('\n').filter(f => f.length > 0);
|
|
290
|
-
speedModeFiles.push(...fileList);
|
|
291
|
-
} catch (diffErr) {
|
|
292
|
-
// Ignore errors for individual commits
|
|
293
|
-
continue;
|
|
294
|
-
}
|
|
295
|
-
}
|
|
296
|
-
|
|
297
|
-
// Remove duplicates
|
|
298
|
-
speedModeFiles = [...new Set(speedModeFiles)];
|
|
299
|
-
|
|
300
|
-
// Error handling: No files found
|
|
301
|
-
if (speedModeFiles.length === 0) {
|
|
302
|
-
console.error('ā No files found in git history for this feature.');
|
|
303
|
-
console.log('Suggestion: Either:');
|
|
304
|
-
console.log(' 1. Specify files manually');
|
|
305
|
-
console.log(' 2. Check if speed mode committed changes');
|
|
306
|
-
console.log(' 3. Start fresh if speed mode was not completed\n');
|
|
307
|
-
|
|
308
|
-
// Ask user for files
|
|
309
|
-
console.log('š Which files should be reviewed? (or type "start-fresh" to begin from scratch)');
|
|
310
|
-
return;
|
|
311
|
-
}
|
|
312
|
-
|
|
313
|
-
console.log(`ā
Found ${speedModeFiles.length} files from speed mode`);
|
|
314
|
-
|
|
315
|
-
} catch (gitErr) {
|
|
316
|
-
console.error('ā ļø Git error:', gitErr.message);
|
|
317
|
-
console.log('Falling back to manual file specification...\n');
|
|
318
|
-
|
|
319
|
-
console.log('š Which files did speed mode create/modify?');
|
|
320
|
-
return;
|
|
321
|
-
}
|
|
322
|
-
|
|
323
|
-
// Validate files are readable
|
|
324
|
-
const readableFiles = [];
|
|
325
|
-
const unreadableFiles = [];
|
|
326
|
-
|
|
327
|
-
for (const filePath of speedModeFiles) {
|
|
328
|
-
const fullPath = path.join(process.cwd(), filePath);
|
|
329
|
-
|
|
330
|
-
// Error handling: File doesn't exist
|
|
331
|
-
if (!fs.existsSync(fullPath)) {
|
|
332
|
-
console.log(`ā ļø File no longer exists: ${filePath}`);
|
|
333
|
-
continue;
|
|
334
|
-
}
|
|
335
|
-
|
|
336
|
-
// Error handling: File not readable
|
|
337
|
-
try {
|
|
338
|
-
fs.accessSync(fullPath, fs.constants.R_OK);
|
|
339
|
-
readableFiles.push(filePath);
|
|
340
|
-
} catch (accessErr) {
|
|
341
|
-
unreadableFiles.push(filePath);
|
|
342
|
-
console.error(`ā Cannot read file: ${filePath}`);
|
|
343
|
-
}
|
|
344
|
-
}
|
|
345
|
-
|
|
346
|
-
// Error handling: No readable files
|
|
347
|
-
if (readableFiles.length === 0) {
|
|
348
|
-
console.error('ā No readable speed mode files found.');
|
|
349
|
-
console.log('Cannot proceed without existing implementation to review.');
|
|
350
|
-
console.log('\nSuggestion: Verify that speed mode was completed or start implementation from scratch.');
|
|
351
|
-
return;
|
|
352
|
-
}
|
|
353
|
-
|
|
354
|
-
if (unreadableFiles.length > 0) {
|
|
355
|
-
console.log(`ā ļø ${unreadableFiles.length} files cannot be read - skipping them`);
|
|
356
|
-
}
|
|
357
|
-
|
|
358
|
-
speedModeFiles = readableFiles;
|
|
359
|
-
```
|
|
360
|
-
|
|
361
|
-
**Identify gaps:**
|
|
362
|
-
- What error handling is missing?
|
|
363
|
-
- What validation is not performed?
|
|
364
|
-
- What edge cases are not covered?
|
|
365
|
-
- What needs to change to pass this scenario?
|
|
366
|
-
|
|
367
|
-
**Display analysis:**
|
|
368
|
-
|
|
369
|
-
```
|
|
370
|
-
š Code Analysis Complete
|
|
371
|
-
|
|
372
|
-
Current Implementation:
|
|
373
|
-
⢠Files: [list]
|
|
374
|
-
⢠Happy path: ā
Working
|
|
375
|
-
⢠Error handling: ā Missing [specific gaps]
|
|
376
|
-
⢠Validation: ā Missing [specific gaps]
|
|
377
|
-
⢠Edge cases: ā Not handled [specific gaps]
|
|
378
|
-
|
|
379
|
-
To pass the target scenario, I need to:
|
|
380
|
-
1. [Specific change]
|
|
381
|
-
2. [Specific change]
|
|
382
|
-
3. [Specific change]
|
|
383
|
-
|
|
384
|
-
Now proposing comprehensive implementation...
|
|
385
|
-
```
|
|
386
|
-
|
|
387
|
-
**Move to Step 3 automatically.**
|
|
388
|
-
|
|
389
|
-
### Step 3: Propose and Execute Comprehensive Implementation
|
|
390
|
-
|
|
391
|
-
**Two phases: Propose (get user confirmation) ā Execute (autonomous)**
|
|
392
|
-
|
|
393
|
-
#### Phase 1: Propose Comprehensive Implementation
|
|
394
|
-
|
|
395
|
-
**Present your analysis and proposal:**
|
|
396
|
-
|
|
397
|
-
```
|
|
398
|
-
š” Comprehensive Implementation Proposal
|
|
399
|
-
|
|
400
|
-
Based on scenario and code analysis, here's how I'll add proper error handling and make the scenario pass:
|
|
401
|
-
|
|
402
|
-
**Changes needed:**
|
|
403
|
-
1. [File]: Add [specific error handling/validation]
|
|
404
|
-
2. [File]: Add [specific edge case handling]
|
|
405
|
-
3. [File]: Add [specific tests]
|
|
406
|
-
|
|
407
|
-
**Error handling approach:**
|
|
408
|
-
⢠[Specific errors to catch and how to handle them]
|
|
409
|
-
⢠[User-friendly error messages]
|
|
410
|
-
⢠[Graceful failure behavior]
|
|
411
|
-
|
|
412
|
-
**Validation approach:**
|
|
413
|
-
⢠[Input validation checks]
|
|
414
|
-
⢠[Boundary condition handling]
|
|
415
|
-
⢠[State validation]
|
|
416
|
-
|
|
417
|
-
**Why this approach:**
|
|
418
|
-
[Brief explanation of how this satisfies the scenario with proper quality]
|
|
419
|
-
|
|
420
|
-
Sound good? I'll implement this autonomously once you confirm.
|
|
421
|
-
```
|
|
422
|
-
|
|
423
|
-
**WAIT for user confirmation or adjustments.**
|
|
424
|
-
|
|
425
|
-
If user adjusts: revise proposal and confirm again.
|
|
426
|
-
|
|
427
|
-
#### Phase 2: Autonomous Execution
|
|
428
|
-
|
|
429
|
-
**CRITICAL:** After user confirms, Claude Code executes autonomously - no permission needed for individual code changes.
|
|
430
|
-
|
|
431
|
-
**Execution loop (with iteration limits and error handling):**
|
|
432
|
-
|
|
433
|
-
```javascript
|
|
434
|
-
const MAX_ITERATIONS = 10; // Prevent infinite loops
|
|
435
|
-
const TEST_TIMEOUT = 60000; // 60 second timeout per test run
|
|
436
|
-
|
|
437
|
-
let iteration = 0;
|
|
438
|
-
let scenarioPasses = false;
|
|
439
|
-
|
|
440
|
-
while (!scenarioPasses && iteration < MAX_ITERATIONS) {
|
|
441
|
-
iteration++;
|
|
442
|
-
console.log(`\nš Iteration ${iteration}/${MAX_ITERATIONS}`);
|
|
443
|
-
|
|
444
|
-
// 1. Modify existing files using Edit tool
|
|
445
|
-
try {
|
|
446
|
-
// Add error handling, validation, error messages, etc.
|
|
447
|
-
console.log('āļø Adding error handling to [file]...');
|
|
448
|
-
// ... use Edit tool ...
|
|
449
|
-
console.log('ā
Updated [file]');
|
|
450
|
-
} catch (editErr) {
|
|
451
|
-
console.error('ā Error modifying files:', editErr.message);
|
|
452
|
-
console.log('Retrying with adjusted approach...');
|
|
453
|
-
continue;
|
|
454
|
-
}
|
|
455
|
-
|
|
456
|
-
// 2. Run tests with timeout
|
|
457
|
-
console.log('š§Ŗ Running tests...');
|
|
458
|
-
|
|
459
|
-
let testsPassed = false;
|
|
460
|
-
try {
|
|
461
|
-
const { exec } = require('child_process');
|
|
462
|
-
const util = require('util');
|
|
463
|
-
const execPromise = util.promisify(exec);
|
|
464
|
-
|
|
465
|
-
const { stdout, stderr } = await execPromise('npm run test:bdd -- features/[feature-slug].feature', {
|
|
466
|
-
timeout: TEST_TIMEOUT,
|
|
467
|
-
killSignal: 'SIGTERM'
|
|
468
|
-
});
|
|
469
|
-
|
|
470
|
-
// Parse BDD test output to check if target scenario passes
|
|
471
|
-
// Step definitions (created during feature discovery) execute your code
|
|
472
|
-
const targetScenarioPassed = stdout.includes('[scenario-title]') && stdout.includes('ā');
|
|
473
|
-
|
|
474
|
-
if (targetScenarioPassed) {
|
|
475
|
-
console.log('ā
Target scenario passes!');
|
|
476
|
-
|
|
477
|
-
// Check if ALL scenarios still pass
|
|
478
|
-
const allPass = !stdout.includes('ā') && !stdout.includes('failing');
|
|
479
|
-
|
|
480
|
-
if (allPass) {
|
|
481
|
-
console.log('ā
All scenarios still passing!');
|
|
482
|
-
scenarioPasses = true;
|
|
483
|
-
} else {
|
|
484
|
-
console.log('ā ļø Target scenario passes but other scenarios broke.');
|
|
485
|
-
console.log('Adjusting to fix regressions...');
|
|
486
|
-
}
|
|
487
|
-
} else {
|
|
488
|
-
console.log('ā Target scenario still failing');
|
|
489
|
-
|
|
490
|
-
// Extract failure reason from test output
|
|
491
|
-
const failureMatch = stdout.match(/AssertionError: (.+)/);
|
|
492
|
-
const failureReason = failureMatch ? failureMatch[1] : 'Unknown failure';
|
|
493
|
-
|
|
494
|
-
console.log(`Reason: ${failureReason}`);
|
|
495
|
-
console.log('Analyzing and adjusting...');
|
|
496
|
-
}
|
|
497
|
-
|
|
498
|
-
} catch (testErr) {
|
|
499
|
-
// Error handling: Test timeout
|
|
500
|
-
if (testErr.killed && testErr.signal === 'SIGTERM') {
|
|
501
|
-
console.error('ā Tests timed out after 60 seconds');
|
|
502
|
-
console.log('This might indicate an infinite loop or hung process.');
|
|
503
|
-
console.log('Suggestion: Check for blocking operations or missing async/await');
|
|
504
|
-
|
|
505
|
-
// Ask user if they want to continue
|
|
506
|
-
console.log('\nā ļø Test timeout - continue trying? (yes/no)');
|
|
507
|
-
// If no, break
|
|
508
|
-
break;
|
|
509
|
-
}
|
|
510
|
-
|
|
511
|
-
// Error handling: Test execution errors
|
|
512
|
-
console.error('ā Test execution error:', testErr.message);
|
|
513
|
-
|
|
514
|
-
// Check if it's a missing test file
|
|
515
|
-
if (testErr.message.includes('No tests found') || testErr.message.includes('Cannot find module')) {
|
|
516
|
-
console.error('Test file might not exist or is misconfigured.');
|
|
517
|
-
console.log('Suggestion: Create the test file or check test configuration');
|
|
518
|
-
break;
|
|
519
|
-
}
|
|
520
|
-
|
|
521
|
-
console.log('Retrying...');
|
|
522
|
-
}
|
|
523
|
-
}
|
|
524
|
-
|
|
525
|
-
// Error handling: Max iterations reached
|
|
526
|
-
if (!scenarioPasses && iteration >= MAX_ITERATIONS) {
|
|
527
|
-
console.error('\nā Maximum iterations reached without passing scenario');
|
|
528
|
-
console.log('\nāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāā');
|
|
529
|
-
console.log('š Unable to make scenario pass automatically');
|
|
530
|
-
console.log('āāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāā');
|
|
531
|
-
console.log('\nPossible reasons:');
|
|
532
|
-
console.log('⢠Scenario requirements may need clarification');
|
|
533
|
-
console.log('⢠Implementation approach may need rethinking');
|
|
534
|
-
console.log('⢠External dependencies may be missing');
|
|
535
|
-
console.log('⢠Test assertions may be incorrect');
|
|
536
|
-
console.log('\nSuggestions:');
|
|
537
|
-
console.log('1. Review the scenario and verify it\'s achievable');
|
|
538
|
-
console.log('2. Check test output for specific failure patterns');
|
|
539
|
-
console.log('3. Try a different implementation approach');
|
|
540
|
-
console.log('4. Ask for help if stuck\n');
|
|
541
|
-
|
|
542
|
-
// Ask user how to proceed
|
|
543
|
-
console.log('How would you like to proceed?');
|
|
544
|
-
console.log(' 1. Review changes made so far');
|
|
545
|
-
console.log(' 2. Try a different approach');
|
|
546
|
-
console.log(' 3. Debug manually');
|
|
547
|
-
return;
|
|
548
|
-
}
|
|
549
|
-
```
|
|
550
|
-
|
|
551
|
-
**Display progress:**
|
|
552
|
-
```
|
|
553
|
-
š Iteration 1/10
|
|
554
|
-
|
|
555
|
-
āļø Adding error handling to [file]...
|
|
556
|
-
ā
Updated [file]
|
|
557
|
-
|
|
558
|
-
š§Ŗ Running tests...
|
|
559
|
-
ā
Target scenario passes!
|
|
560
|
-
ā
All scenarios still passing!
|
|
561
|
-
```
|
|
562
|
-
|
|
563
|
-
**Stable mode focus:**
|
|
564
|
-
- **Add to existing implementation** - speed mode already implemented all features
|
|
565
|
-
- **Comprehensive error handling** - wrap existing code with try/catch, handle failures gracefully
|
|
566
|
-
- **Input validation** - add checks before existing logic (null checks, type checks, range validation)
|
|
567
|
-
- **Edge case handling** - handle empty arrays, missing properties, boundary values, concurrent access
|
|
568
|
-
- **Clear error messages** - user-friendly, actionable feedback for all failure modes
|
|
569
|
-
- **All BDD scenarios pass** - happy path (already passing from speed) AND error/edge scenarios
|
|
570
|
-
|
|
571
|
-
**When all scenarios pass:**
|
|
572
|
-
|
|
573
|
-
```
|
|
574
|
-
š Stable mode scenario passes!
|
|
575
|
-
|
|
576
|
-
Implementation complete:
|
|
577
|
-
⢠Modified: [list files]
|
|
578
|
-
⢠Error handling: ā
Comprehensive
|
|
579
|
-
⢠Validation: ā
Complete
|
|
580
|
-
⢠All scenarios: ā
Passing
|
|
581
|
-
```
|
|
582
|
-
|
|
583
|
-
### Step 4: Check for Production Mode (When All Stable Chores Complete)
|
|
584
|
-
|
|
585
|
-
**CRITICAL: This step ONLY happens when ALL stable chores for the feature are complete. Otherwise skip to marking chore as done.**
|
|
586
|
-
|
|
587
|
-
**Check completion status and project state:**
|
|
588
|
-
```javascript
|
|
589
|
-
const { getDb } = require('../../lib/database');
|
|
590
|
-
const { getCurrentWork } = require('../../lib/current-work');
|
|
591
|
-
|
|
592
|
-
const currentWork = getCurrentWork();
|
|
593
|
-
const featureId = currentWork.parent_id;
|
|
594
|
-
|
|
595
|
-
const db = getDb();
|
|
596
|
-
db.get(`
|
|
597
|
-
SELECT COUNT(*) as incomplete_count
|
|
598
|
-
FROM work_items
|
|
599
|
-
WHERE parent_id = ?
|
|
600
|
-
AND type = 'chore'
|
|
601
|
-
AND status NOT IN ('done', 'cancelled')
|
|
602
|
-
`, [featureId], (err, result) => {
|
|
603
|
-
if (result.incomplete_count === 0) {
|
|
604
|
-
// All stable chores done - check project state
|
|
605
|
-
db.get('SELECT project_state FROM project_config WHERE id = 1', (err, config) => {
|
|
606
|
-
const projectState = config?.project_state || 'internal';
|
|
607
|
-
|
|
608
|
-
if (projectState === 'internal') {
|
|
609
|
-
// Internal project - stable mode is complete
|
|
610
|
-
console.log('Internal project - no production mode needed');
|
|
611
|
-
} else {
|
|
612
|
-
// External project - invoke production-mode skill
|
|
613
|
-
console.log('External project - auto-generating production chores from standards');
|
|
614
|
-
}
|
|
615
|
-
});
|
|
616
|
-
} else {
|
|
617
|
-
// More chores remain - just mark this one done
|
|
618
|
-
console.log(`\nš ${result.incomplete_count} stable mode chores remaining`);
|
|
619
|
-
}
|
|
620
|
-
db.close();
|
|
621
|
-
});
|
|
622
|
-
```
|
|
623
|
-
|
|
624
|
-
**If all stable chores are done AND project is INTERNAL:**
|
|
625
|
-
|
|
626
|
-
```
|
|
627
|
-
āāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāā
|
|
628
|
-
ā
FEATURE COMPLETE!
|
|
629
|
-
āāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāā
|
|
630
|
-
|
|
631
|
-
What we accomplished:
|
|
632
|
-
ā
All BDD scenarios passing (happy path + error handling + edge cases)
|
|
633
|
-
ā
Comprehensive error handling and validation
|
|
634
|
-
ā
Feature stable and ready to use
|
|
635
|
-
|
|
636
|
-
This is an internal project - no production hardening needed.
|
|
637
|
-
|
|
638
|
-
If you later transition to external state, production chores will be
|
|
639
|
-
automatically generated from production standards.
|
|
640
|
-
```
|
|
641
|
-
|
|
642
|
-
**If all stable chores are done AND project is EXTERNAL:**
|
|
643
|
-
|
|
644
|
-
Use the Skill tool to invoke the production-mode skill:
|
|
645
|
-
|
|
646
|
-
```javascript
|
|
647
|
-
// Use Skill tool to invoke: production-mode
|
|
648
|
-
// The production-mode skill will:
|
|
649
|
-
// 1. Detect feature context (Scenario A/B/C)
|
|
650
|
-
// 2. Generate production scenarios from standards
|
|
651
|
-
// 3. Append scenarios to feature file
|
|
652
|
-
// 4. Create production chores
|
|
653
|
-
```
|
|
654
|
-
|
|
655
|
-
Display to user:
|
|
656
|
-
|
|
657
|
-
```
|
|
658
|
-
āāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāā
|
|
659
|
-
ā
ALL STABLE MODE CHORES COMPLETE!
|
|
660
|
-
āāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāā
|
|
661
|
-
|
|
662
|
-
What we accomplished:
|
|
663
|
-
ā
All BDD scenarios passing (happy path + error handling + edge cases)
|
|
664
|
-
ā
Comprehensive error handling and validation
|
|
665
|
-
ā
Feature stable and ready for production hardening
|
|
666
|
-
|
|
667
|
-
āāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāā
|
|
668
|
-
š AUTO-GENERATING PRODUCTION CHORES
|
|
669
|
-
āāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāā
|
|
670
|
-
|
|
671
|
-
This project is external - invoking production-mode skill to:
|
|
672
|
-
⢠Detect feature context (authentication/data/general)
|
|
673
|
-
⢠Generate production scenarios from standards
|
|
674
|
-
⢠Create production chores with proper scope
|
|
675
|
-
|
|
676
|
-
[Invoke production-mode skill - it handles the rest autonomously]
|
|
677
|
-
```
|
|
678
|
-
|
|
679
|
-
**If stable chores remain:**
|
|
680
|
-
|
|
681
|
-
```
|
|
682
|
-
āāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāā
|
|
683
|
-
šÆ Stable Mode Chore Complete!
|
|
684
|
-
āāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāā
|
|
685
|
-
|
|
686
|
-
What we accomplished:
|
|
687
|
-
ā
Scenario passes with proper error handling
|
|
688
|
-
ā
Input validation added
|
|
689
|
-
ā
Edge cases handled
|
|
690
|
-
|
|
691
|
-
Remaining stable mode chores: [count]
|
|
692
|
-
|
|
693
|
-
**Next step:** Continue with next stable mode chore
|
|
694
|
-
jettypod work start [next-stable-chore-id]
|
|
695
|
-
```
|
|
696
|
-
|
|
697
|
-
**Mark current chore as done:**
|
|
698
|
-
|
|
699
|
-
Use Bash tool to commit, push, and merge to main:
|
|
700
|
-
```bash
|
|
701
|
-
git add . && git commit -m "feat: [brief description of what was implemented]" && git push
|
|
702
|
-
```
|
|
703
|
-
|
|
704
|
-
Then merge to main (which auto-marks chore as done via git hooks):
|
|
705
|
-
```bash
|
|
706
|
-
git checkout main && git pull && git merge [branch-name] && git push
|
|
707
|
-
```
|
|
708
|
-
|
|
709
|
-
The post-merge hook will automatically mark the chore as done when merged to main.
|
|
710
|
-
|
|
711
|
-
**End skill.**
|
|
712
|
-
|
|
713
|
-
|