jettypod 4.4.70 → 4.4.71
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/apps/dashboard/app/api/work/[id]/status/route.ts +21 -0
- package/apps/dashboard/app/api/work/[id]/title/route.ts +21 -0
- package/apps/dashboard/components/CardMenu.tsx +120 -0
- package/apps/dashboard/components/EditableTitle.tsx +102 -0
- package/apps/dashboard/components/KanbanBoard.tsx +97 -38
- package/apps/dashboard/components/RealTimeKanbanWrapper.tsx +51 -0
- package/apps/dashboard/lib/db.ts +30 -0
- package/claude-hooks/global-guardrails.js +29 -1
- package/docs/jetty-development-guide/shapeup.md +0 -0
- package/jettypod.js +14 -7
- package/lib/work-commands/index.js +62 -15
- package/lib/work-tracking/index.js +17 -0
- package/package.json +1 -1
- package/skills-templates/bug-mode/SKILL.md +392 -0
- package/skills-templates/bug-planning/SKILL.md +387 -0
- package/skills-templates/speed-mode/SKILL.md +29 -2
- package/skills-templates/stable-mode/SKILL.md +25 -2
package/jettypod.js
CHANGED
|
@@ -2135,15 +2135,22 @@ switch (command) {
|
|
|
2135
2135
|
}
|
|
2136
2136
|
}
|
|
2137
2137
|
|
|
2138
|
-
// Start WebSocket server for real-time updates
|
|
2138
|
+
// Start WebSocket server as background process for real-time updates
|
|
2139
2139
|
const WS_PORT = 8080;
|
|
2140
2140
|
const { getDbPath } = require('./lib/database');
|
|
2141
|
-
|
|
2142
|
-
|
|
2143
|
-
|
|
2144
|
-
|
|
2145
|
-
|
|
2146
|
-
|
|
2141
|
+
const wsServerScript = `
|
|
2142
|
+
const wsServer = require('./lib/ws-server');
|
|
2143
|
+
const { getDbPath } = require('./lib/database');
|
|
2144
|
+
wsServer.start(${WS_PORT}, { dbPath: getDbPath() })
|
|
2145
|
+
.catch(() => process.exit(1));
|
|
2146
|
+
`;
|
|
2147
|
+
const wsProcess = spawn('node', ['-e', wsServerScript], {
|
|
2148
|
+
cwd: __dirname,
|
|
2149
|
+
detached: true,
|
|
2150
|
+
stdio: 'ignore',
|
|
2151
|
+
env: { ...process.env, JETTYPOD_PROJECT_PATH: process.cwd() }
|
|
2152
|
+
});
|
|
2153
|
+
wsProcess.unref();
|
|
2147
2154
|
|
|
2148
2155
|
// Start dashboard in background with project path
|
|
2149
2156
|
console.log('🚀 Starting dashboard...');
|
|
@@ -1665,20 +1665,10 @@ async function mergeWork(options = {}) {
|
|
|
1665
1665
|
|
|
1666
1666
|
console.log(`✓ Successfully merged work item #${currentWork.id}`);
|
|
1667
1667
|
|
|
1668
|
-
//
|
|
1669
|
-
|
|
1670
|
-
await new Promise((resolve, reject) => {
|
|
1671
|
-
db.run(
|
|
1672
|
-
`UPDATE work_items SET status = 'done', completed_at = datetime('now') WHERE id = ?`,
|
|
1673
|
-
[currentWork.id],
|
|
1674
|
-
(err) => {
|
|
1675
|
-
if (err) return reject(err);
|
|
1676
|
-
resolve();
|
|
1677
|
-
}
|
|
1678
|
-
);
|
|
1679
|
-
});
|
|
1668
|
+
// Check if this is a test worktree (tests/ prefix) - only set scenario_file, don't mark done
|
|
1669
|
+
const isTestWorktree = currentBranch.startsWith('tests/');
|
|
1680
1670
|
|
|
1681
|
-
// Get worktree info from database
|
|
1671
|
+
// Get worktree info from database (needed for cleanup message)
|
|
1682
1672
|
const worktree = await new Promise((resolve, reject) => {
|
|
1683
1673
|
db.get(
|
|
1684
1674
|
`SELECT id, worktree_path, branch_name FROM worktrees WHERE work_item_id = ? AND status = 'active'`,
|
|
@@ -1690,6 +1680,65 @@ async function mergeWork(options = {}) {
|
|
|
1690
1680
|
);
|
|
1691
1681
|
});
|
|
1692
1682
|
|
|
1683
|
+
if (isTestWorktree) {
|
|
1684
|
+
// Test worktree: set scenario_file but don't mark feature as done
|
|
1685
|
+
console.log('📝 Test worktree detected - setting scenario_file only');
|
|
1686
|
+
|
|
1687
|
+
// Find and set scenario_file on the feature
|
|
1688
|
+
try {
|
|
1689
|
+
const addedFiles = execSync(`git diff --name-only --diff-filter=A HEAD~1 HEAD`, {
|
|
1690
|
+
cwd: gitRoot,
|
|
1691
|
+
encoding: 'utf8',
|
|
1692
|
+
stdio: 'pipe'
|
|
1693
|
+
}).trim();
|
|
1694
|
+
|
|
1695
|
+
const featureFiles = addedFiles
|
|
1696
|
+
.split('\n')
|
|
1697
|
+
.filter(f => f.endsWith('.feature') && f.startsWith('features/'));
|
|
1698
|
+
|
|
1699
|
+
if (featureFiles.length > 0) {
|
|
1700
|
+
const scenarioFile = featureFiles[0];
|
|
1701
|
+
await new Promise((resolve, reject) => {
|
|
1702
|
+
db.run(
|
|
1703
|
+
`UPDATE work_items SET scenario_file = ? WHERE id = ?`,
|
|
1704
|
+
[scenarioFile, currentWork.id],
|
|
1705
|
+
(err) => {
|
|
1706
|
+
if (err) return reject(err);
|
|
1707
|
+
resolve();
|
|
1708
|
+
}
|
|
1709
|
+
);
|
|
1710
|
+
});
|
|
1711
|
+
console.log(`✅ Set scenario_file: ${scenarioFile}`);
|
|
1712
|
+
}
|
|
1713
|
+
} catch (err) {
|
|
1714
|
+
console.log('⚠️ Could not auto-detect scenario file:', err.message);
|
|
1715
|
+
}
|
|
1716
|
+
|
|
1717
|
+
console.log(`✅ BDD tests merged for feature #${currentWork.id}`);
|
|
1718
|
+
console.log(' Feature remains in discovery phase - create chores to continue');
|
|
1719
|
+
} else if (currentWork.type !== 'chore') {
|
|
1720
|
+
// Non-test branch for a non-chore - this shouldn't happen
|
|
1721
|
+
return Promise.reject(new Error(
|
|
1722
|
+
`Cannot merge ${currentWork.type} #${currentWork.id} directly.\n\n` +
|
|
1723
|
+
`Only chores can be merged. Features complete when all their chores are done.\n` +
|
|
1724
|
+
`Test worktrees (tests/* branches) merge BDD scenarios without completing the feature.`
|
|
1725
|
+
));
|
|
1726
|
+
} else {
|
|
1727
|
+
// Chore worktree: mark as done (existing behavior)
|
|
1728
|
+
console.log('Marking chore as done...');
|
|
1729
|
+
await new Promise((resolve, reject) => {
|
|
1730
|
+
db.run(
|
|
1731
|
+
`UPDATE work_items SET status = 'done', completed_at = datetime('now') WHERE id = ?`,
|
|
1732
|
+
[currentWork.id],
|
|
1733
|
+
(err) => {
|
|
1734
|
+
if (err) return reject(err);
|
|
1735
|
+
resolve();
|
|
1736
|
+
}
|
|
1737
|
+
);
|
|
1738
|
+
});
|
|
1739
|
+
console.log(`✅ Chore #${currentWork.id} marked as done`);
|
|
1740
|
+
}
|
|
1741
|
+
|
|
1693
1742
|
// Mark worktree as merged but DON'T delete it yet
|
|
1694
1743
|
// This prevents shell CWD corruption when merge is run from inside the worktree
|
|
1695
1744
|
// User must run `jettypod work cleanup` separately after cd'ing to main repo
|
|
@@ -1706,8 +1755,6 @@ async function mergeWork(options = {}) {
|
|
|
1706
1755
|
});
|
|
1707
1756
|
}
|
|
1708
1757
|
|
|
1709
|
-
console.log(`✅ Work item #${currentWork.id} marked as done`);
|
|
1710
|
-
|
|
1711
1758
|
// Instruct user to cleanup worktree separately - be aggressive so AI doesn't forget
|
|
1712
1759
|
if (worktree && worktree.worktree_path && fs.existsSync(worktree.worktree_path)) {
|
|
1713
1760
|
console.log('');
|
|
@@ -764,6 +764,13 @@ function setBranch(id, branch) {
|
|
|
764
764
|
});
|
|
765
765
|
}
|
|
766
766
|
|
|
767
|
+
// Set scenario file
|
|
768
|
+
function setScenario(id, scenarioFile) {
|
|
769
|
+
db.run(`UPDATE work_items SET scenario_file = ? WHERE id = ?`, [scenarioFile, id], () => {
|
|
770
|
+
console.log(`Set #${id} scenario_file to ${scenarioFile}`);
|
|
771
|
+
});
|
|
772
|
+
}
|
|
773
|
+
|
|
767
774
|
// Set mode
|
|
768
775
|
function setMode(id, mode) {
|
|
769
776
|
return new Promise((resolve, reject) => {
|
|
@@ -1584,6 +1591,13 @@ async function main() {
|
|
|
1584
1591
|
break;
|
|
1585
1592
|
}
|
|
1586
1593
|
|
|
1594
|
+
case 'set-scenario': {
|
|
1595
|
+
const id = parseInt(args[0]);
|
|
1596
|
+
const file = args[1];
|
|
1597
|
+
setScenario(id, file);
|
|
1598
|
+
break;
|
|
1599
|
+
}
|
|
1600
|
+
|
|
1587
1601
|
case 'current': {
|
|
1588
1602
|
if (!args[0]) {
|
|
1589
1603
|
// No ID provided - show current work
|
|
@@ -2426,6 +2440,9 @@ Commands:
|
|
|
2426
2440
|
jettypod work set-mode <id> <mode>
|
|
2427
2441
|
Set mode (speed/discovery/stable/production)
|
|
2428
2442
|
|
|
2443
|
+
jettypod work set-scenario <id> <file>
|
|
2444
|
+
Set scenario_file for a feature (e.g., features/my-feature.feature)
|
|
2445
|
+
|
|
2429
2446
|
jettypod work current <id>
|
|
2430
2447
|
Set as current work item
|
|
2431
2448
|
|
package/package.json
CHANGED
|
@@ -0,0 +1,392 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: bug-mode
|
|
3
|
+
description: Guide implementation of standalone chores with type-appropriate guidance, verification steps, and test handling. Receives enriched context from chore-planning and executes with iteration until verification passes.
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# Bug Mode Skill
|
|
7
|
+
|
|
8
|
+
```
|
|
9
|
+
┌─────────────────────────────────────────────────────────────────────┐
|
|
10
|
+
│ Bug Fix Flow │
|
|
11
|
+
│ │
|
|
12
|
+
│ Bug Planning → [BUG MODE] → Done │
|
|
13
|
+
│ ▲▲▲▲▲▲▲▲▲▲ │
|
|
14
|
+
│ YOU ARE HERE │
|
|
15
|
+
│ │
|
|
16
|
+
│ Single pass: Covers speed through stable (internal) or │
|
|
17
|
+
│ through production (external) comprehensively. │
|
|
18
|
+
└─────────────────────────────────────────────────────────────────────┘
|
|
19
|
+
```
|
|
20
|
+
|
|
21
|
+
## Key Difference from Feature Modes
|
|
22
|
+
|
|
23
|
+
**Bug fixes do NOT follow speed → stable → production progression.**
|
|
24
|
+
|
|
25
|
+
- **Features:** Iterative refinement (speed makes it work, stable makes it robust, production makes it scalable)
|
|
26
|
+
- **Bugs:** Single comprehensive fix (fix the root cause properly the first time)
|
|
27
|
+
|
|
28
|
+
Why? A bug fix should:
|
|
29
|
+
1. Fix the root cause completely
|
|
30
|
+
2. Include proper error handling from the start
|
|
31
|
+
3. Pass the regression test
|
|
32
|
+
4. Be production-ready immediately
|
|
33
|
+
|
|
34
|
+
---
|
|
35
|
+
|
|
36
|
+
Guides Claude Code through comprehensive bug fix implementation. Receives context from bug-planning skill (root cause, breadcrumbs, regression test).
|
|
37
|
+
|
|
38
|
+
## Instructions
|
|
39
|
+
|
|
40
|
+
When this skill is activated, you are implementing a bug fix chore. The bug-planning skill has already:
|
|
41
|
+
- Identified root cause
|
|
42
|
+
- Created the bug work item and fix chore
|
|
43
|
+
- Written a regression test (currently failing)
|
|
44
|
+
- Started the worktree with `work start`
|
|
45
|
+
|
|
46
|
+
Your job: Make the regression test pass with a comprehensive fix.
|
|
47
|
+
|
|
48
|
+
## 🔑 Critical Context
|
|
49
|
+
|
|
50
|
+
**You are working in an isolated git worktree:**
|
|
51
|
+
- `work start [chore-id]` already created a dedicated worktree
|
|
52
|
+
- All file operations must use **absolute paths** from the worktree
|
|
53
|
+
- The worktree has its own branch - changes are isolated from main
|
|
54
|
+
|
|
55
|
+
**Worktree path is available in Step 0 output** - use it for all file operations.
|
|
56
|
+
|
|
57
|
+
---
|
|
58
|
+
|
|
59
|
+
## 🚨 SHELL CWD RECOVERY
|
|
60
|
+
|
|
61
|
+
**If ALL bash commands start failing with "Error: Exit code 1" and no output:**
|
|
62
|
+
|
|
63
|
+
Your shell's working directory was likely inside a worktree that was deleted. The CWD no longer exists.
|
|
64
|
+
|
|
65
|
+
**Recovery steps:**
|
|
66
|
+
1. Get the main repo path from your session context
|
|
67
|
+
2. Run: `cd <main-repo-path>`
|
|
68
|
+
3. Verify: `pwd && ls .jettypod`
|
|
69
|
+
4. Resume your work
|
|
70
|
+
|
|
71
|
+
---
|
|
72
|
+
|
|
73
|
+
## 🛑 PRE-FLIGHT VALIDATION (REQUIRED)
|
|
74
|
+
|
|
75
|
+
**Before proceeding, validate the worktree exists.**
|
|
76
|
+
|
|
77
|
+
```bash
|
|
78
|
+
sqlite3 .jettypod/work.db "SELECT wi.id, wi.title, wi.status, wt.worktree_path, wt.branch_name FROM work_items wi LEFT JOIN worktrees wt ON wi.id = wt.work_item_id WHERE wi.status = 'in_progress' AND wi.type = 'chore'"
|
|
79
|
+
```
|
|
80
|
+
|
|
81
|
+
**Check the result:**
|
|
82
|
+
|
|
83
|
+
| worktree_path | What it means | Action |
|
|
84
|
+
|---------------|---------------|--------|
|
|
85
|
+
| **Has a path** | ✅ Worktree exists, ready to proceed | Continue to Step 0 |
|
|
86
|
+
| **NULL or empty** | ❌ `work start` was not called | **STOP - run `jettypod work start [chore-id]` first** |
|
|
87
|
+
| **No rows returned** | ❌ No chore is in progress | **STOP - verify the chore exists and run `work start`** |
|
|
88
|
+
|
|
89
|
+
---
|
|
90
|
+
|
|
91
|
+
## Implementation Steps
|
|
92
|
+
|
|
93
|
+
### Step 0: Initialize Bug Mode Context
|
|
94
|
+
|
|
95
|
+
**Get the current work context:**
|
|
96
|
+
|
|
97
|
+
```bash
|
|
98
|
+
sqlite3 .jettypod/work.db "SELECT wi.id, wi.title, wi.description, wi.parent_id, parent.title as parent_title, parent.type as parent_type, wt.worktree_path, wt.branch_name FROM work_items wi LEFT JOIN work_items parent ON wi.parent_id = parent.id LEFT JOIN worktrees wt ON wi.id = wt.work_item_id WHERE wi.status = 'in_progress' AND wi.type = 'chore'"
|
|
99
|
+
```
|
|
100
|
+
|
|
101
|
+
**Verify parent is a bug:**
|
|
102
|
+
- `parent_type` should be `bug`
|
|
103
|
+
- If not, this skill may not be appropriate
|
|
104
|
+
|
|
105
|
+
**Extract breadcrumbs from chore description:**
|
|
106
|
+
The bug-planning skill embedded implementation guidance:
|
|
107
|
+
- Root cause location (file:line)
|
|
108
|
+
- Fix approach (steps)
|
|
109
|
+
- Files to modify
|
|
110
|
+
- Verification criteria
|
|
111
|
+
|
|
112
|
+
**Display to user:**
|
|
113
|
+
|
|
114
|
+
```
|
|
115
|
+
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
|
|
116
|
+
🐛 BUG MODE: Fixing #[bug-id]
|
|
117
|
+
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
|
|
118
|
+
|
|
119
|
+
Chore: [title]
|
|
120
|
+
Bug: #[parent-id] [parent-title]
|
|
121
|
+
Worktree: [worktree_path]
|
|
122
|
+
Branch: [branch_name]
|
|
123
|
+
|
|
124
|
+
Root Cause:
|
|
125
|
+
[From breadcrumbs - what's broken and where]
|
|
126
|
+
|
|
127
|
+
Fix Approach:
|
|
128
|
+
[From breadcrumbs - steps to fix]
|
|
129
|
+
|
|
130
|
+
Establishing RED baseline...
|
|
131
|
+
```
|
|
132
|
+
|
|
133
|
+
**Proceed to Step 1.**
|
|
134
|
+
|
|
135
|
+
---
|
|
136
|
+
|
|
137
|
+
### Step 1: Establish RED Baseline
|
|
138
|
+
|
|
139
|
+
**Run the regression test to confirm it fails:**
|
|
140
|
+
|
|
141
|
+
```bash
|
|
142
|
+
# Find the regression test file
|
|
143
|
+
sqlite3 .jettypod/work.db "SELECT id FROM work_items WHERE id = <bug-id>"
|
|
144
|
+
# Look for features/*<bug-id>*.feature or features/*<bug-slug>*.feature
|
|
145
|
+
```
|
|
146
|
+
|
|
147
|
+
```bash
|
|
148
|
+
# Run the regression test
|
|
149
|
+
npx cucumber-js features/<bug-slug>.feature --format progress
|
|
150
|
+
```
|
|
151
|
+
|
|
152
|
+
**Confirm RED state:**
|
|
153
|
+
- The regression test should FAIL
|
|
154
|
+
- This proves the bug exists and the test catches it
|
|
155
|
+
|
|
156
|
+
**Display RED baseline:**
|
|
157
|
+
|
|
158
|
+
```
|
|
159
|
+
🔴 RED Baseline Confirmed
|
|
160
|
+
|
|
161
|
+
Regression test: features/<bug-slug>.feature
|
|
162
|
+
Status: FAILING (as expected)
|
|
163
|
+
|
|
164
|
+
Error:
|
|
165
|
+
[Error message from test]
|
|
166
|
+
|
|
167
|
+
🎯 Goal: Make the regression test pass with a comprehensive fix
|
|
168
|
+
|
|
169
|
+
Now implementing fix...
|
|
170
|
+
```
|
|
171
|
+
|
|
172
|
+
**Proceed to Step 2.**
|
|
173
|
+
|
|
174
|
+
---
|
|
175
|
+
|
|
176
|
+
### Step 2: Implement Comprehensive Fix
|
|
177
|
+
|
|
178
|
+
**CRITICAL:** Bug fixes must be comprehensive from the start.
|
|
179
|
+
|
|
180
|
+
**Use breadcrumbs to guide implementation:**
|
|
181
|
+
1. Navigate to the root cause location
|
|
182
|
+
2. Understand the surrounding code
|
|
183
|
+
3. Implement the fix following the approach from bug-planning
|
|
184
|
+
4. Add proper error handling (don't just fix the happy path)
|
|
185
|
+
5. Consider edge cases related to the bug
|
|
186
|
+
|
|
187
|
+
**What "comprehensive" means:**
|
|
188
|
+
|
|
189
|
+
**INTERNAL projects (project_state = 'internal'):**
|
|
190
|
+
- Fix the root cause
|
|
191
|
+
- Add validation to prevent the bug condition
|
|
192
|
+
- Handle the error gracefully if it somehow occurs
|
|
193
|
+
- Ensure related edge cases are covered
|
|
194
|
+
|
|
195
|
+
**EXTERNAL projects (project_state = 'external'):**
|
|
196
|
+
- Everything for internal, PLUS:
|
|
197
|
+
- Consider security implications
|
|
198
|
+
- Add logging for debugging
|
|
199
|
+
- Ensure graceful degradation
|
|
200
|
+
- Consider concurrent access if relevant
|
|
201
|
+
|
|
202
|
+
**Check project state:**
|
|
203
|
+
|
|
204
|
+
```bash
|
|
205
|
+
sqlite3 .jettypod/work.db "SELECT project_state FROM project_config WHERE id = 1"
|
|
206
|
+
```
|
|
207
|
+
|
|
208
|
+
**Implement iteratively:**
|
|
209
|
+
|
|
210
|
+
```
|
|
211
|
+
━━━ Iteration 1 ━━━
|
|
212
|
+
📂 Reading: [file:line from breadcrumbs]
|
|
213
|
+
🔧 Change: [what you're fixing]
|
|
214
|
+
```
|
|
215
|
+
|
|
216
|
+
**After each change, run the regression test:**
|
|
217
|
+
|
|
218
|
+
```bash
|
|
219
|
+
npx cucumber-js features/<bug-slug>.feature --format progress
|
|
220
|
+
```
|
|
221
|
+
|
|
222
|
+
**Track progress:**
|
|
223
|
+
|
|
224
|
+
```
|
|
225
|
+
━━━ Iteration 2 ━━━
|
|
226
|
+
🧪 Running regression test...
|
|
227
|
+
📊 Status: Still failing
|
|
228
|
+
🔧 Next: [what else needs to change]
|
|
229
|
+
```
|
|
230
|
+
|
|
231
|
+
**Continue until GREEN:**
|
|
232
|
+
|
|
233
|
+
```
|
|
234
|
+
🎉 GREEN: Regression test passing!
|
|
235
|
+
|
|
236
|
+
Fix implemented:
|
|
237
|
+
- [Change 1]
|
|
238
|
+
- [Change 2]
|
|
239
|
+
- [Error handling added]
|
|
240
|
+
|
|
241
|
+
Now verifying no regressions...
|
|
242
|
+
```
|
|
243
|
+
|
|
244
|
+
**Proceed to Step 3.**
|
|
245
|
+
|
|
246
|
+
---
|
|
247
|
+
|
|
248
|
+
### Step 3: Verify No Regressions
|
|
249
|
+
|
|
250
|
+
**Run the full test suite to ensure the fix didn't break anything:**
|
|
251
|
+
|
|
252
|
+
```bash
|
|
253
|
+
# Run all BDD tests
|
|
254
|
+
npx cucumber-js --format progress
|
|
255
|
+
|
|
256
|
+
# Run unit tests if they exist
|
|
257
|
+
npm test 2>/dev/null || echo "No unit tests configured"
|
|
258
|
+
```
|
|
259
|
+
|
|
260
|
+
**If regressions found:**
|
|
261
|
+
|
|
262
|
+
```
|
|
263
|
+
⚠️ Regression Detected
|
|
264
|
+
|
|
265
|
+
Failing test: [test name]
|
|
266
|
+
Error: [error message]
|
|
267
|
+
|
|
268
|
+
Investigating...
|
|
269
|
+
```
|
|
270
|
+
|
|
271
|
+
Fix the regression and re-run tests. Iterate until all tests pass.
|
|
272
|
+
|
|
273
|
+
**When all tests pass:**
|
|
274
|
+
|
|
275
|
+
```
|
|
276
|
+
✅ All Tests Passing
|
|
277
|
+
|
|
278
|
+
- Regression test: ✅ PASS
|
|
279
|
+
- Other BDD tests: ✅ [X] scenarios passing
|
|
280
|
+
- Unit tests: ✅ [Y] tests passing (if applicable)
|
|
281
|
+
|
|
282
|
+
Ready to commit and merge.
|
|
283
|
+
```
|
|
284
|
+
|
|
285
|
+
**Proceed to Step 4.**
|
|
286
|
+
|
|
287
|
+
---
|
|
288
|
+
|
|
289
|
+
### Step 4: Commit and Merge
|
|
290
|
+
|
|
291
|
+
**Commit the fix:**
|
|
292
|
+
|
|
293
|
+
```bash
|
|
294
|
+
git add . && git commit -m "fix: [Brief description of the bug fix]
|
|
295
|
+
|
|
296
|
+
Root cause: [What was broken]
|
|
297
|
+
Fix: [What was changed]
|
|
298
|
+
|
|
299
|
+
Closes #<bug-id>
|
|
300
|
+
|
|
301
|
+
🤖 Generated with [Claude Code](https://claude.com/claude-code)
|
|
302
|
+
|
|
303
|
+
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>"
|
|
304
|
+
```
|
|
305
|
+
|
|
306
|
+
**Merge (3 steps):**
|
|
307
|
+
|
|
308
|
+
```bash
|
|
309
|
+
# Step 1: Merge (can run from worktree - it won't delete it)
|
|
310
|
+
jettypod work merge
|
|
311
|
+
```
|
|
312
|
+
|
|
313
|
+
```bash
|
|
314
|
+
# Step 2: cd to main repo
|
|
315
|
+
cd <main-repo-path>
|
|
316
|
+
pwd && ls .jettypod # verify
|
|
317
|
+
```
|
|
318
|
+
|
|
319
|
+
```bash
|
|
320
|
+
# Step 3: Clean up the worktree
|
|
321
|
+
jettypod work cleanup <chore-id>
|
|
322
|
+
```
|
|
323
|
+
|
|
324
|
+
**Proceed to Step 5.**
|
|
325
|
+
|
|
326
|
+
---
|
|
327
|
+
|
|
328
|
+
### Step 5: Mark Bug as Done
|
|
329
|
+
|
|
330
|
+
**After the fix chore is merged, mark the parent bug as done:**
|
|
331
|
+
|
|
332
|
+
```bash
|
|
333
|
+
jettypod work status <bug-id> done
|
|
334
|
+
```
|
|
335
|
+
|
|
336
|
+
**Display completion:**
|
|
337
|
+
|
|
338
|
+
```
|
|
339
|
+
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
|
|
340
|
+
✅ Bug Fix Complete
|
|
341
|
+
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
|
|
342
|
+
|
|
343
|
+
🐛 Bug: #[bug-id] [title]
|
|
344
|
+
🔧 Fix: #[chore-id] [title]
|
|
345
|
+
🧪 Regression test: ✅ Passing
|
|
346
|
+
|
|
347
|
+
What was fixed:
|
|
348
|
+
- Root cause: [brief description]
|
|
349
|
+
- Fix: [what changed]
|
|
350
|
+
- Prevention: [validation/error handling added]
|
|
351
|
+
|
|
352
|
+
The bug is now fixed and protected by a regression test.
|
|
353
|
+
```
|
|
354
|
+
|
|
355
|
+
**End bug-mode skill.**
|
|
356
|
+
|
|
357
|
+
---
|
|
358
|
+
|
|
359
|
+
## Validation Checklist
|
|
360
|
+
|
|
361
|
+
Before ending bug-mode skill, ensure:
|
|
362
|
+
- [ ] Regression test was failing (RED baseline confirmed)
|
|
363
|
+
- [ ] Fix implemented comprehensively (not just happy path)
|
|
364
|
+
- [ ] Regression test now passes (GREEN)
|
|
365
|
+
- [ ] No other tests broken (no regressions)
|
|
366
|
+
- [ ] Fix committed with descriptive message
|
|
367
|
+
- [ ] Chore merged to main
|
|
368
|
+
- [ ] Worktree cleaned up
|
|
369
|
+
- [ ] Bug marked as done
|
|
370
|
+
|
|
371
|
+
---
|
|
372
|
+
|
|
373
|
+
## Command Reference
|
|
374
|
+
|
|
375
|
+
**Merge fix (CRITICAL: cd to main repo separately):**
|
|
376
|
+
```bash
|
|
377
|
+
jettypod work merge # Merge current chore
|
|
378
|
+
```
|
|
379
|
+
|
|
380
|
+
```bash
|
|
381
|
+
cd <main-repo> # Change to main repo
|
|
382
|
+
jettypod work cleanup <id> # Clean up worktree
|
|
383
|
+
```
|
|
384
|
+
|
|
385
|
+
**Mark bug complete:**
|
|
386
|
+
```bash
|
|
387
|
+
jettypod work status <bug-id> done
|
|
388
|
+
```
|
|
389
|
+
|
|
390
|
+
**❌ DO NOT use these to complete chores:**
|
|
391
|
+
- `jettypod work status <chore-id> done`
|
|
392
|
+
- `jettypod work complete <id>`
|