jettypod 4.4.45 → 4.4.47
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/jettypod.js +485 -117
- package/lib/database.js +33 -0
- package/lib/work-commands/index.js +73 -1
- package/lib/worktree-manager.js +6 -2
- package/package.json +1 -1
- package/skills-templates/chore-mode/SKILL.md +8 -0
- package/skills-templates/feature-planning/SKILL.md +242 -144
- package/skills-templates/speed-mode/SKILL.md +39 -13
- package/skills-templates/stable-mode/SKILL.md +8 -0
package/lib/database.js
CHANGED
|
@@ -203,6 +203,39 @@ function initSchema() {
|
|
|
203
203
|
}
|
|
204
204
|
});
|
|
205
205
|
|
|
206
|
+
db.run(`
|
|
207
|
+
CREATE TABLE IF NOT EXISTS skill_executions (
|
|
208
|
+
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
|
209
|
+
work_item_id INTEGER NOT NULL,
|
|
210
|
+
skill_name TEXT NOT NULL,
|
|
211
|
+
status TEXT DEFAULT 'in_progress',
|
|
212
|
+
step_reached INTEGER DEFAULT 1,
|
|
213
|
+
context_json TEXT,
|
|
214
|
+
started_at DATETIME DEFAULT CURRENT_TIMESTAMP,
|
|
215
|
+
completed_at DATETIME,
|
|
216
|
+
FOREIGN KEY (work_item_id) REFERENCES work_items(id)
|
|
217
|
+
)
|
|
218
|
+
`, (err) => {
|
|
219
|
+
if (err) {
|
|
220
|
+
throw new Error(`Failed to create skill_executions table: ${err.message}`);
|
|
221
|
+
}
|
|
222
|
+
});
|
|
223
|
+
|
|
224
|
+
db.run(`
|
|
225
|
+
CREATE TABLE IF NOT EXISTS workflow_gates (
|
|
226
|
+
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
|
227
|
+
work_item_id INTEGER NOT NULL,
|
|
228
|
+
gate_name TEXT NOT NULL,
|
|
229
|
+
passed_at DATETIME,
|
|
230
|
+
UNIQUE(work_item_id, gate_name),
|
|
231
|
+
FOREIGN KEY (work_item_id) REFERENCES work_items(id)
|
|
232
|
+
)
|
|
233
|
+
`, (err) => {
|
|
234
|
+
if (err) {
|
|
235
|
+
throw new Error(`Failed to create workflow_gates table: ${err.message}`);
|
|
236
|
+
}
|
|
237
|
+
});
|
|
238
|
+
|
|
206
239
|
// Migrations: Add columns if they don't exist (for databases created before these columns were in base schema)
|
|
207
240
|
const handleAlterError = (columnName) => (err) => {
|
|
208
241
|
if (err && !err.message.includes('duplicate column')) {
|
|
@@ -1629,10 +1629,82 @@ async function mergeWork(options = {}) {
|
|
|
1629
1629
|
}
|
|
1630
1630
|
}
|
|
1631
1631
|
|
|
1632
|
+
/**
|
|
1633
|
+
* Create a worktree for writing BDD tests for a feature
|
|
1634
|
+
* @param {number} featureId - Feature ID to create test worktree for
|
|
1635
|
+
* @returns {Promise<Object>} Worktree info with path and branch
|
|
1636
|
+
* @throws {Error} If feature not found or not in correct phase
|
|
1637
|
+
*/
|
|
1638
|
+
async function testsWork(featureId) {
|
|
1639
|
+
if (!featureId || isNaN(featureId) || featureId < 1) {
|
|
1640
|
+
return Promise.reject(new Error('Invalid feature ID'));
|
|
1641
|
+
}
|
|
1642
|
+
|
|
1643
|
+
const paths = getPaths();
|
|
1644
|
+
|
|
1645
|
+
if (!fs.existsSync(paths.jettypodDir)) {
|
|
1646
|
+
return Promise.reject(new Error('JettyPod not initialized. Run: jettypod init'));
|
|
1647
|
+
}
|
|
1648
|
+
|
|
1649
|
+
if (!fs.existsSync(paths.dbPath)) {
|
|
1650
|
+
return Promise.reject(new Error('Work database not found. Run: jettypod init'));
|
|
1651
|
+
}
|
|
1652
|
+
|
|
1653
|
+
const db = getDb();
|
|
1654
|
+
|
|
1655
|
+
return new Promise((resolve, reject) => {
|
|
1656
|
+
// Get feature work item
|
|
1657
|
+
db.get(
|
|
1658
|
+
`SELECT * FROM work_items WHERE id = ? AND type = 'feature'`,
|
|
1659
|
+
[featureId],
|
|
1660
|
+
async (err, feature) => {
|
|
1661
|
+
if (err) {
|
|
1662
|
+
return reject(new Error(`Database error: ${err.message}`));
|
|
1663
|
+
}
|
|
1664
|
+
|
|
1665
|
+
if (!feature) {
|
|
1666
|
+
return reject(new Error(`Feature #${featureId} not found`));
|
|
1667
|
+
}
|
|
1668
|
+
|
|
1669
|
+
// Create worktree with tests/ prefix
|
|
1670
|
+
try {
|
|
1671
|
+
const gitRoot = getGitRoot();
|
|
1672
|
+
const worktreeResult = await worktreeManager.createWorktree(feature, {
|
|
1673
|
+
repoPath: gitRoot,
|
|
1674
|
+
branchPrefix: 'tests/feature',
|
|
1675
|
+
pathPrefix: 'tests-'
|
|
1676
|
+
});
|
|
1677
|
+
|
|
1678
|
+
// Set as current work
|
|
1679
|
+
setCurrentWork({
|
|
1680
|
+
id: feature.id,
|
|
1681
|
+
type: feature.type,
|
|
1682
|
+
title: feature.title,
|
|
1683
|
+
status: feature.status || 'in_progress',
|
|
1684
|
+
worktreePath: worktreeResult.worktree_path,
|
|
1685
|
+
branchName: worktreeResult.branch_name
|
|
1686
|
+
});
|
|
1687
|
+
|
|
1688
|
+
console.log(`✅ Created test worktree: ${worktreeResult.worktree_path}`);
|
|
1689
|
+
console.log(`📁 IMPORTANT: Use absolute paths for file operations:`);
|
|
1690
|
+
console.log(` ${worktreeResult.worktree_path}/features/your-feature.feature (correct)`);
|
|
1691
|
+
console.log(` features/your-feature.feature (wrong - creates in main repo)`);
|
|
1692
|
+
console.log(`\nWorking on tests for: [#${feature.id}] ${feature.title}`);
|
|
1693
|
+
|
|
1694
|
+
resolve(worktreeResult);
|
|
1695
|
+
} catch (worktreeErr) {
|
|
1696
|
+
reject(new Error(`Failed to create test worktree: ${worktreeErr.message}`));
|
|
1697
|
+
}
|
|
1698
|
+
}
|
|
1699
|
+
);
|
|
1700
|
+
});
|
|
1701
|
+
}
|
|
1702
|
+
|
|
1632
1703
|
module.exports = {
|
|
1633
1704
|
startWork,
|
|
1634
1705
|
stopWork,
|
|
1635
1706
|
getCurrentWork,
|
|
1636
1707
|
cleanupWorktrees,
|
|
1637
|
-
mergeWork
|
|
1708
|
+
mergeWork,
|
|
1709
|
+
testsWork
|
|
1638
1710
|
};
|
package/lib/worktree-manager.js
CHANGED
|
@@ -29,6 +29,8 @@ const VALID_STATUSES = ['active', 'merging', 'cleanup_pending', 'corrupted'];
|
|
|
29
29
|
* @param {Object} options - Optional configuration
|
|
30
30
|
* @param {string} options.repoPath - Path to git repository (defaults to process.cwd())
|
|
31
31
|
* @param {Object} options.db - Database connection (defaults to global database)
|
|
32
|
+
* @param {string} options.branchPrefix - Branch prefix (defaults to 'feature/work')
|
|
33
|
+
* @param {string} options.pathPrefix - Worktree path prefix (defaults to '')
|
|
32
34
|
* @returns {Promise<Object>} Worktree record with id, work_item_id, branch_name, worktree_path, status
|
|
33
35
|
*/
|
|
34
36
|
async function createWorktree(workItem, options = {}) {
|
|
@@ -85,9 +87,11 @@ async function createWorktree(workItem, options = {}) {
|
|
|
85
87
|
|
|
86
88
|
// Generate branch name and worktree path
|
|
87
89
|
const titleSlug = slugify(workItem.title || 'item');
|
|
88
|
-
const
|
|
90
|
+
const branchPrefix = options.branchPrefix || 'feature/work';
|
|
91
|
+
const pathPrefix = options.pathPrefix || '';
|
|
92
|
+
const branchName = `${branchPrefix}-${workItem.id}-${titleSlug}`;
|
|
89
93
|
const worktreeBasePath = path.join(gitRoot, '.jettypod-work');
|
|
90
|
-
const worktreePath = path.join(worktreeBasePath, `${workItem.id}-${titleSlug}`);
|
|
94
|
+
const worktreePath = path.join(worktreeBasePath, `${pathPrefix}${workItem.id}-${titleSlug}`);
|
|
91
95
|
|
|
92
96
|
let worktreeId = null;
|
|
93
97
|
let branchCreated = false;
|
package/package.json
CHANGED
|
@@ -78,6 +78,14 @@ Implementation Plan:
|
|
|
78
78
|
|
|
79
79
|
**Your task:** Create an isolated worktree for this chore.
|
|
80
80
|
|
|
81
|
+
**🚫 FORBIDDEN: Manual Git Worktree Commands**
|
|
82
|
+
```
|
|
83
|
+
❌ git worktree add ...
|
|
84
|
+
❌ git checkout -b feature/...
|
|
85
|
+
❌ git branch feature/...
|
|
86
|
+
```
|
|
87
|
+
**ALWAYS use `jettypod work start`** - it handles branch naming, path conventions, database tracking, and cleanup. Manual git commands will create orphaned worktrees that break the merge workflow.
|
|
88
|
+
|
|
81
89
|
```bash
|
|
82
90
|
jettypod work start [chore-id]
|
|
83
91
|
```
|
|
@@ -13,20 +13,23 @@ When this skill is activated, you are helping discover the best approach for a f
|
|
|
13
13
|
|
|
14
14
|
## 🔑 Critical Command Distinction
|
|
15
15
|
|
|
16
|
-
**
|
|
16
|
+
**Four different commands, four different purposes:**
|
|
17
17
|
|
|
18
18
|
| Command | Used For | When | Phase |
|
|
19
19
|
|---------|----------|------|-------|
|
|
20
|
-
| `work implement <feature-id>` | Transition feature to implementation phase |
|
|
21
|
-
| `work start <
|
|
20
|
+
| `work implement <feature-id>` | Transition feature to implementation phase | After chores created (Step 8C) | Feature Planning |
|
|
21
|
+
| `work tests start <feature-id>` | Create worktree for test authoring | After transition (Step 8D) | Feature Planning |
|
|
22
|
+
| `work tests merge <feature-id>` | Merge tests to main, cleanup worktree | After tests validated (Step 8D) | Feature Planning |
|
|
23
|
+
| `work start <chore-id>` | Start implementing a specific chore | After tests merged (Step 8E) | Speed Mode |
|
|
22
24
|
|
|
23
|
-
**CRITICAL:**
|
|
24
|
-
- `work implement` = Ends feature planning,
|
|
25
|
-
- `work start` =
|
|
25
|
+
**CRITICAL:** All commands are run by **Claude**, not the user. The distinction is:
|
|
26
|
+
- `work implement` = Ends feature planning, transitions to implementation phase
|
|
27
|
+
- `work tests start/merge` = Write and land BDD tests in isolated worktree
|
|
28
|
+
- `work start` = Creates worktree/branch for chore implementation
|
|
26
29
|
|
|
27
|
-
**🛑 STOP GATE:** DO NOT run `work start` until Step
|
|
30
|
+
**🛑 STOP GATE:** DO NOT run `work start` until Step 8E. Tests must be merged to main first.
|
|
28
31
|
|
|
29
|
-
**🛑 HANDOFF REQUIREMENT:** After `work start`, you MUST invoke speed-mode using the Skill tool. See Step
|
|
32
|
+
**🛑 HANDOFF REQUIREMENT:** After `work start`, you MUST invoke speed-mode using the Skill tool. See Step 8E.
|
|
30
33
|
|
|
31
34
|
---
|
|
32
35
|
|
|
@@ -224,9 +227,9 @@ Example:
|
|
|
224
227
|
|
|
225
228
|
**WAIT for user to confirm or adjust the integration contract.**
|
|
226
229
|
|
|
227
|
-
#### Step 6B:
|
|
230
|
+
#### Step 6B: Propose BDD Scenarios (DO NOT WRITE YET)
|
|
228
231
|
|
|
229
|
-
**CRITICAL:**
|
|
232
|
+
**CRITICAL:** Do NOT write files yet. Display the proposed scenarios for user confirmation. Files will be written in Step 8D inside an isolated worktree.
|
|
230
233
|
|
|
231
234
|
**Feature slug:** Derive `FEATURE_SLUG` from the feature title:
|
|
232
235
|
- Lowercase
|
|
@@ -234,43 +237,79 @@ Example:
|
|
|
234
237
|
- Remove special characters
|
|
235
238
|
- Examples: "Email Password Login" → "email-password-login", "User's Profile (v2)" → "users-profile-v2"
|
|
236
239
|
|
|
237
|
-
Based on chosen approach,
|
|
240
|
+
Based on chosen approach, **display** the proposed scenarios to the user:
|
|
238
241
|
|
|
239
|
-
|
|
242
|
+
```
|
|
243
|
+
📋 Proposed BDD Scenarios
|
|
240
244
|
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
- All success paths - required functionality AND optional features
|
|
245
|
-
- Multiple valid workflows if the feature supports them
|
|
246
|
-
- Success variations (different outcomes that are all correct)
|
|
247
|
-
- NO error handling scenarios (added in stable mode)
|
|
248
|
-
- NO validation failures (added in stable mode)
|
|
249
|
-
- NO security/compliance scenarios (added in production mode)
|
|
245
|
+
**Feature file:** features/[feature-slug].feature
|
|
246
|
+
**Step definitions:** features/step_definitions/[feature-slug].steps.js
|
|
247
|
+
```
|
|
250
248
|
|
|
251
|
-
|
|
249
|
+
Then show the full Gherkin content:
|
|
252
250
|
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
4. **Include**:
|
|
257
|
-
- Test environment setup/cleanup
|
|
258
|
-
- All Given steps (setup state)
|
|
259
|
-
- All When steps (execute actions)
|
|
260
|
-
- All Then steps (verify outcomes)
|
|
251
|
+
```gherkin
|
|
252
|
+
Feature: [Feature Name]
|
|
253
|
+
[Brief description based on chosen UX approach]
|
|
261
254
|
|
|
262
|
-
|
|
255
|
+
Epic: [Epic name if applicable]
|
|
256
|
+
Approach: [Chosen approach name]
|
|
263
257
|
|
|
264
|
-
|
|
265
|
-
|
|
258
|
+
# Integration Contract:
|
|
259
|
+
# Entry Point: [from Step 6A]
|
|
260
|
+
# Caller Code: [from Step 6A]
|
|
261
|
+
|
|
262
|
+
# INTEGRATION SCENARIO (REQUIRED - proves feature is reachable)
|
|
263
|
+
Scenario: User can reach [feature] from [entry point]
|
|
264
|
+
Given I am on [existing entry point users can access]
|
|
265
|
+
When I [navigate/click/invoke to reach the feature]
|
|
266
|
+
Then I [see/access the feature]
|
|
267
|
+
|
|
268
|
+
# FEATURE SCENARIOS (required + optional functionality)
|
|
269
|
+
Scenario: [Core functionality - required workflow]
|
|
270
|
+
Given [initial state]
|
|
271
|
+
When [user takes main action]
|
|
272
|
+
Then [expected successful outcome]
|
|
273
|
+
And [observable UI/system state change]
|
|
274
|
+
|
|
275
|
+
Scenario: [Optional feature 1 - if applicable]
|
|
276
|
+
Given [initial state]
|
|
277
|
+
When [user uses optional feature]
|
|
278
|
+
Then [feature works correctly]
|
|
279
|
+
|
|
280
|
+
# SPEED MODE: All success scenarios above (integration + required + optional)
|
|
281
|
+
# STABLE MODE: Will add error handling, validation failures, edge cases
|
|
266
282
|
```
|
|
267
283
|
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
284
|
+
Then list the step definitions that will be created:
|
|
285
|
+
|
|
286
|
+
```
|
|
287
|
+
**Step definitions to implement:**
|
|
288
|
+
• Given I am on [entry point] - [brief implementation note]
|
|
289
|
+
• When I [action] - [brief implementation note]
|
|
290
|
+
• Then I [outcome] - [brief implementation note]
|
|
291
|
+
[etc.]
|
|
292
|
+
|
|
293
|
+
Does this capture the feature correctly? Any scenarios to add/change?
|
|
271
294
|
```
|
|
272
295
|
|
|
273
|
-
**
|
|
296
|
+
**Scenario content requirements:**
|
|
297
|
+
- **FIRST scenario MUST be the Integration Scenario** from Step 6A (proves reachability)
|
|
298
|
+
- **Include all "make it work" scenarios**:
|
|
299
|
+
- All success paths - required functionality AND optional features
|
|
300
|
+
- Multiple valid workflows if the feature supports them
|
|
301
|
+
- Success variations (different outcomes that are all correct)
|
|
302
|
+
- NO error handling scenarios (added in stable mode)
|
|
303
|
+
- NO validation failures (added in stable mode)
|
|
304
|
+
- NO security/compliance scenarios (added in production mode)
|
|
305
|
+
|
|
306
|
+
**WAIT for user confirmation.**
|
|
307
|
+
|
|
308
|
+
- If user confirms → Proceed to Step 7
|
|
309
|
+
- If user requests changes → Revise scenarios and display again
|
|
310
|
+
- **Store the confirmed scenarios in memory** - you'll write them in Step 8D
|
|
311
|
+
|
|
312
|
+
**Proceed to Step 7.**
|
|
274
313
|
|
|
275
314
|
**Template for speed mode (make it work):**
|
|
276
315
|
|
|
@@ -395,102 +434,9 @@ Scenario: Prevent unauthorized access
|
|
|
395
434
|
|
|
396
435
|
</details>
|
|
397
436
|
|
|
398
|
-
### Step 6.5: Validate BDD Infrastructure
|
|
399
|
-
|
|
400
|
-
**CRITICAL:** After creating both scenario and step definition files, validate them with cucumber dry-run to catch errors immediately.
|
|
401
|
-
|
|
402
|
-
**Run this command** (replace `${FEATURE_SLUG}` with actual slug):
|
|
403
|
-
|
|
404
|
-
```bash
|
|
405
|
-
npx cucumber-js --dry-run features/${FEATURE_SLUG}.feature
|
|
406
|
-
```
|
|
407
|
-
|
|
408
|
-
Example:
|
|
409
|
-
```bash
|
|
410
|
-
npx cucumber-js --dry-run features/email-password-login.feature
|
|
411
|
-
```
|
|
412
|
-
|
|
413
|
-
**What the output means:**
|
|
414
|
-
|
|
415
|
-
✅ **Success** - No errors, all steps have definitions:
|
|
416
|
-
```
|
|
417
|
-
0 scenarios
|
|
418
|
-
0 steps
|
|
419
|
-
```
|
|
420
|
-
(Dry-run doesn't execute, so 0 is correct)
|
|
421
|
-
|
|
422
|
-
❌ **Undefined steps** - Missing step definitions:
|
|
423
|
-
```
|
|
424
|
-
Undefined. Implement with the following snippet:
|
|
425
|
-
Given('I am on the login page', function () {
|
|
426
|
-
...
|
|
427
|
-
});
|
|
428
|
-
```
|
|
429
|
-
→ Add the missing step definition to your `.steps.js` file
|
|
430
|
-
|
|
431
|
-
❌ **Syntax error** - Invalid Gherkin:
|
|
432
|
-
```
|
|
433
|
-
Parse error in features/foo.feature
|
|
434
|
-
```
|
|
435
|
-
→ Fix the feature file syntax
|
|
436
|
-
|
|
437
|
-
❌ **Duplicate steps** - Multiple definitions match:
|
|
438
|
-
```
|
|
439
|
-
Multiple step definitions match
|
|
440
|
-
```
|
|
441
|
-
→ Remove or rename one of the duplicate step definitions
|
|
442
|
-
|
|
443
|
-
**If validation fails:**
|
|
444
|
-
1. Read the error message carefully
|
|
445
|
-
2. Fix the step definitions or scenario file
|
|
446
|
-
3. Re-run the dry-run command
|
|
447
|
-
4. **Loop until validation passes** - do NOT proceed to Step 7 until green
|
|
448
|
-
|
|
449
|
-
**If validation succeeds:**
|
|
450
|
-
Display: "✅ BDD infrastructure validated - all steps have definitions"
|
|
451
|
-
|
|
452
|
-
**Proceed to Step 6.6.**
|
|
453
|
-
|
|
454
|
-
**Note:** Unit tests are created during speed mode implementation, not during feature planning. Feature planning focuses on BDD scenarios (user experience); speed mode handles unit tests (implementation details).
|
|
455
|
-
|
|
456
|
-
### Step 6.6: Commit BDD Files to Main
|
|
457
|
-
|
|
458
|
-
**CRITICAL:** The BDD files must be committed to main BEFORE creating worktrees. If you skip this step, worktrees won't have the scenario files and speed-mode will fail.
|
|
459
|
-
|
|
460
|
-
**Commit the BDD files:**
|
|
461
|
-
|
|
462
|
-
```bash
|
|
463
|
-
git add features/${FEATURE_SLUG}.feature features/steps/${FEATURE_SLUG}.* features/step_definitions/${FEATURE_SLUG}.*
|
|
464
|
-
git commit -m "test: Add BDD scenarios for ${FEATURE_TITLE}
|
|
465
|
-
|
|
466
|
-
- Feature file: features/${FEATURE_SLUG}.feature
|
|
467
|
-
- Step definitions for speed mode scenarios"
|
|
468
|
-
|
|
469
|
-
git push
|
|
470
|
-
```
|
|
471
|
-
|
|
472
|
-
Replace `${FEATURE_SLUG}` and `${FEATURE_TITLE}` with actual values. Example:
|
|
473
|
-
```bash
|
|
474
|
-
git add features/email-password-login.feature features/steps/email-password-login.* features/step_definitions/email-password-login.*
|
|
475
|
-
git commit -m "test: Add BDD scenarios for Email Password Login
|
|
476
|
-
|
|
477
|
-
- Feature file: features/email-password-login.feature
|
|
478
|
-
- Step definitions for speed mode scenarios"
|
|
479
|
-
|
|
480
|
-
git push
|
|
481
|
-
```
|
|
482
|
-
|
|
483
|
-
**Why this matters:**
|
|
484
|
-
- Worktrees are created from the current branch (usually main)
|
|
485
|
-
- If BDD files aren't committed, they won't exist in the worktree
|
|
486
|
-
- Speed-mode will fail trying to run tests against non-existent files
|
|
487
|
-
- **Push is required** so other assistants/machines have the latest main
|
|
488
|
-
|
|
489
|
-
**Proceed to Step 7.**
|
|
490
|
-
|
|
491
437
|
### Step 7: Propose Speed Mode Chores
|
|
492
438
|
|
|
493
|
-
**CRITICAL:** After BDD
|
|
439
|
+
**CRITICAL:** After user confirms the BDD scenarios, analyze the codebase and propose technical implementation chores. **DO NOT CREATE CHORES YET** - the feature must transition to implementation mode first (Step 8).
|
|
494
440
|
|
|
495
441
|
**Your analysis should consider:**
|
|
496
442
|
- The BDD scenarios (integration + all success paths)
|
|
@@ -633,6 +579,147 @@ After successful transition, display:
|
|
|
633
579
|
✅ Feature transitioned to implementation phase
|
|
634
580
|
✅ Created X chores for speed mode
|
|
635
581
|
|
|
582
|
+
Now I'll write the BDD tests in an isolated worktree...
|
|
583
|
+
```
|
|
584
|
+
|
|
585
|
+
**Proceed to Step 8D.**
|
|
586
|
+
|
|
587
|
+
#### Step 8D: Write Tests in Isolated Worktree
|
|
588
|
+
|
|
589
|
+
**CRITICAL:** Tests are written in an isolated worktree, not directly on main. This ensures agent failures don't leave uncommitted garbage on main.
|
|
590
|
+
|
|
591
|
+
**🚫 FORBIDDEN: Manual Git Worktree Commands**
|
|
592
|
+
```
|
|
593
|
+
❌ git worktree add ...
|
|
594
|
+
❌ git checkout -b tests/...
|
|
595
|
+
❌ git branch tests/...
|
|
596
|
+
```
|
|
597
|
+
**ALWAYS use jettypod commands** - they handle branch naming, path conventions, database tracking, and cleanup. Manual git commands will create orphaned worktrees that break the merge workflow.
|
|
598
|
+
|
|
599
|
+
**Sub-step 1: Create test worktree**
|
|
600
|
+
|
|
601
|
+
```bash
|
|
602
|
+
jettypod work tests start ${FEATURE_ID}
|
|
603
|
+
```
|
|
604
|
+
|
|
605
|
+
This creates:
|
|
606
|
+
- Worktree at `.jettypod-work/tests-<id>-<slug>/`
|
|
607
|
+
- Branch `tests/feature-<id>-<slug>`
|
|
608
|
+
|
|
609
|
+
**Capture the worktree path from output** - you'll need it for file operations.
|
|
610
|
+
|
|
611
|
+
Example output:
|
|
612
|
+
```
|
|
613
|
+
✅ Created test worktree: /path/to/.jettypod-work/tests-42-email-login
|
|
614
|
+
Branch: tests/feature-42-email-login
|
|
615
|
+
|
|
616
|
+
Write your BDD files to:
|
|
617
|
+
<worktree>/features/email-login.feature
|
|
618
|
+
<worktree>/features/step_definitions/email-login.steps.js
|
|
619
|
+
|
|
620
|
+
When done, run: jettypod work tests merge 42
|
|
621
|
+
```
|
|
622
|
+
|
|
623
|
+
**🛑 STOP AND CHECK:** Verify worktree was created successfully. If you see an error, investigate before continuing.
|
|
624
|
+
|
|
625
|
+
**Sub-step 2: Write BDD files in the worktree**
|
|
626
|
+
|
|
627
|
+
Using the scenarios you confirmed in Step 6B, write the files using **absolute paths to the worktree**:
|
|
628
|
+
|
|
629
|
+
**A. Write scenario file** using Write tool:
|
|
630
|
+
```
|
|
631
|
+
<worktree_path>/features/${FEATURE_SLUG}.feature
|
|
632
|
+
```
|
|
633
|
+
|
|
634
|
+
**B. Write step definitions file** using Write tool:
|
|
635
|
+
```
|
|
636
|
+
<worktree_path>/features/step_definitions/${FEATURE_SLUG}.steps.js
|
|
637
|
+
```
|
|
638
|
+
|
|
639
|
+
**Step definition requirements:**
|
|
640
|
+
1. Implement all Given/When/Then steps from the scenarios
|
|
641
|
+
2. Follow existing patterns - check other `.steps.js` files for conventions
|
|
642
|
+
3. Include test environment setup/cleanup
|
|
643
|
+
4. All Given steps (setup state)
|
|
644
|
+
5. All When steps (execute actions)
|
|
645
|
+
6. All Then steps (verify outcomes)
|
|
646
|
+
|
|
647
|
+
**Sub-step 3: Validate BDD infrastructure**
|
|
648
|
+
|
|
649
|
+
Run cucumber dry-run **from within the worktree**:
|
|
650
|
+
|
|
651
|
+
```bash
|
|
652
|
+
cd <worktree_path> && npx cucumber-js --dry-run features/${FEATURE_SLUG}.feature
|
|
653
|
+
```
|
|
654
|
+
|
|
655
|
+
**What the output means:**
|
|
656
|
+
|
|
657
|
+
✅ **Success** - No errors, all steps have definitions:
|
|
658
|
+
```
|
|
659
|
+
0 scenarios
|
|
660
|
+
0 steps
|
|
661
|
+
```
|
|
662
|
+
(Dry-run doesn't execute, so 0 is correct)
|
|
663
|
+
|
|
664
|
+
❌ **Undefined steps** - Missing step definitions:
|
|
665
|
+
```
|
|
666
|
+
Undefined. Implement with the following snippet:
|
|
667
|
+
Given('I am on the login page', function () {
|
|
668
|
+
...
|
|
669
|
+
});
|
|
670
|
+
```
|
|
671
|
+
→ Add the missing step definition to your `.steps.js` file
|
|
672
|
+
|
|
673
|
+
❌ **Syntax error** - Invalid Gherkin:
|
|
674
|
+
```
|
|
675
|
+
Parse error in features/foo.feature
|
|
676
|
+
```
|
|
677
|
+
→ Fix the feature file syntax
|
|
678
|
+
|
|
679
|
+
❌ **Duplicate steps** - Multiple definitions match:
|
|
680
|
+
```
|
|
681
|
+
Multiple step definitions match
|
|
682
|
+
```
|
|
683
|
+
→ Remove or rename one of the duplicate step definitions
|
|
684
|
+
|
|
685
|
+
**If validation fails:**
|
|
686
|
+
1. Read the error message carefully
|
|
687
|
+
2. Fix the step definitions or scenario file **in the worktree**
|
|
688
|
+
3. Re-run the dry-run command
|
|
689
|
+
4. **Loop until validation passes** - do NOT proceed until green
|
|
690
|
+
|
|
691
|
+
**If validation succeeds:**
|
|
692
|
+
Display: "✅ BDD infrastructure validated - all steps have definitions"
|
|
693
|
+
|
|
694
|
+
**Sub-step 4: Update database with scenario file path**
|
|
695
|
+
|
|
696
|
+
```bash
|
|
697
|
+
sqlite3 .jettypod/work.db "UPDATE work_items SET scenario_file = 'features/${FEATURE_SLUG}.feature' WHERE id = ${FEATURE_ID}"
|
|
698
|
+
```
|
|
699
|
+
|
|
700
|
+
**Sub-step 5: Merge tests to main**
|
|
701
|
+
|
|
702
|
+
```bash
|
|
703
|
+
jettypod work tests merge ${FEATURE_ID}
|
|
704
|
+
```
|
|
705
|
+
|
|
706
|
+
This will:
|
|
707
|
+
- Commit changes in the worktree
|
|
708
|
+
- Merge to main
|
|
709
|
+
- Push to remote
|
|
710
|
+
- Clean up the worktree
|
|
711
|
+
|
|
712
|
+
**🛑 STOP AND CHECK:** Verify merge succeeded:
|
|
713
|
+
- ✅ "Tests merged to main" → Proceed to Step 8E
|
|
714
|
+
- ❌ Error → Investigate, worktree still exists for debugging
|
|
715
|
+
|
|
716
|
+
**After successful merge, display:**
|
|
717
|
+
|
|
718
|
+
```
|
|
719
|
+
✅ Feature transitioned to implementation phase
|
|
720
|
+
✅ Created X chores for speed mode
|
|
721
|
+
✅ BDD tests merged to main
|
|
722
|
+
|
|
636
723
|
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
|
|
637
724
|
🎯 Feature Planning Complete!
|
|
638
725
|
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
|
|
@@ -648,9 +735,11 @@ After successful transition, display:
|
|
|
648
735
|
Start this one? [yes / pick different / done for now]
|
|
649
736
|
```
|
|
650
737
|
|
|
651
|
-
|
|
738
|
+
**Proceed to Step 8E.**
|
|
739
|
+
|
|
740
|
+
#### Step 8E: Start First Chore
|
|
652
741
|
|
|
653
|
-
**Feature planning is now complete.** The feature has been transitioned to implementation phase and chores are ready.
|
|
742
|
+
**Feature planning is now complete.** The feature has been transitioned to implementation phase, tests are on main, and chores are ready.
|
|
654
743
|
|
|
655
744
|
The completion message above already includes your recommendation. Now:
|
|
656
745
|
|
|
@@ -675,6 +764,14 @@ End feature-planning skill without starting a chore. Do NOT invoke speed-mode.
|
|
|
675
764
|
|
|
676
765
|
**After user picks a chore, execute these steps IN ORDER:**
|
|
677
766
|
|
|
767
|
+
**🚫 FORBIDDEN: Manual Git Worktree Commands**
|
|
768
|
+
```
|
|
769
|
+
❌ git worktree add ...
|
|
770
|
+
❌ git checkout -b feature/...
|
|
771
|
+
❌ git branch feature/...
|
|
772
|
+
```
|
|
773
|
+
**ALWAYS use `jettypod work start`** - it handles branch naming, path conventions, database tracking, and cleanup. Manual git commands will create orphaned worktrees that break the merge workflow.
|
|
774
|
+
|
|
678
775
|
**Step 1: Start the chore (creates worktree and branch):**
|
|
679
776
|
```bash
|
|
680
777
|
jettypod work start [chore-id]
|
|
@@ -763,14 +860,15 @@ Before completing feature planning, ensure:
|
|
|
763
860
|
- [ ] Exactly 3 approaches suggested
|
|
764
861
|
- [ ] Winner chosen (with prototypes or without)
|
|
765
862
|
- [ ] **Integration Contract defined** (entry point, caller code, integration scenario)
|
|
766
|
-
- [ ] **Integration Scenario is FIRST scenario** in
|
|
767
|
-
- [ ] BDD scenarios
|
|
768
|
-
- [ ]
|
|
769
|
-
- [ ]
|
|
770
|
-
- [ ]
|
|
771
|
-
- [ ]
|
|
772
|
-
- [ ]
|
|
773
|
-
- [ ] **
|
|
774
|
-
- [ ]
|
|
775
|
-
- [ ]
|
|
776
|
-
- [ ]
|
|
863
|
+
- [ ] **Integration Scenario is FIRST scenario** in proposed scenarios
|
|
864
|
+
- [ ] BDD scenarios **proposed and confirmed** by user (Step 6B)
|
|
865
|
+
- [ ] **At least one Integration Chore proposed** (wires feature into app)
|
|
866
|
+
- [ ] Speed mode chores proposed and confirmed (Step 7)
|
|
867
|
+
- [ ] Chores created in database (Step 8B)
|
|
868
|
+
- [ ] Feature transitioned to implementation with `work implement` (Step 8C)
|
|
869
|
+
- [ ] **Test worktree created** with `work tests start` (Step 8D)
|
|
870
|
+
- [ ] **BDD files written** in worktree (Step 8D)
|
|
871
|
+
- [ ] **BDD infrastructure validated** with dry-run (Step 8D)
|
|
872
|
+
- [ ] **Tests merged to main** with `work tests merge` (Step 8D)
|
|
873
|
+
- [ ] First chore started with `work start [chore-id]` (Step 8E)
|
|
874
|
+
- [ ] **Speed-mode skill invoked using Skill tool** (Step 8E)
|