jettypod 4.4.98 → 4.4.99
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/claude/[workItemId]/route.ts +127 -0
- package/apps/dashboard/app/page.tsx +10 -0
- package/apps/dashboard/app/tests/page.tsx +73 -0
- package/apps/dashboard/components/CardMenu.tsx +19 -2
- package/apps/dashboard/components/ClaudePanel.tsx +271 -0
- package/apps/dashboard/components/KanbanBoard.tsx +11 -4
- package/apps/dashboard/components/RealTimeKanbanWrapper.tsx +62 -3
- package/apps/dashboard/components/TestTree.tsx +208 -0
- package/apps/dashboard/hooks/useClaudeSessions.ts +265 -0
- package/apps/dashboard/hooks/useClaudeStream.ts +205 -0
- package/apps/dashboard/lib/tests.ts +201 -0
- package/apps/dashboard/next-env.d.ts +1 -1
- package/cucumber-results.json +12970 -0
- package/lib/git-hooks/pre-commit +6 -0
- package/lib/work-commands/index.js +20 -10
- package/package.json +1 -1
- package/skills-templates/feature-planning/SKILL.md +6 -2
- package/skills-templates/simple-improvement/SKILL.md +30 -4
package/lib/git-hooks/pre-commit
CHANGED
|
@@ -59,6 +59,12 @@ if (!checkBranchRestriction()) {
|
|
|
59
59
|
|
|
60
60
|
// Export database snapshots (runs for all commits where .jettypod exists)
|
|
61
61
|
async function exportSnapshots() {
|
|
62
|
+
// Skip in worktrees - snapshots only matter for commits on main
|
|
63
|
+
// Worktrees can't git add files from main repo ("outside repository" error)
|
|
64
|
+
if (process.cwd().includes('.jettypod-work')) {
|
|
65
|
+
return;
|
|
66
|
+
}
|
|
67
|
+
|
|
62
68
|
const jettypodDir = path.join(process.cwd(), '.jettypod');
|
|
63
69
|
if (!fs.existsSync(jettypodDir)) {
|
|
64
70
|
return; // No JettyPod directory, skip export
|
|
@@ -1508,9 +1508,20 @@ async function mergeWork(options = {}) {
|
|
|
1508
1508
|
return Promise.reject(new Error(`Failed to check git status: ${err.message}`));
|
|
1509
1509
|
}
|
|
1510
1510
|
|
|
1511
|
+
// Validate work item type BEFORE git operations
|
|
1512
|
+
// Only chores, bugs, and test worktrees can be merged directly
|
|
1513
|
+
const isTestWorktree = currentBranch.startsWith('tests/');
|
|
1514
|
+
if (!isTestWorktree && !['chore', 'bug'].includes(currentWork.type)) {
|
|
1515
|
+
return Promise.reject(new Error(
|
|
1516
|
+
`Cannot merge ${currentWork.type} #${currentWork.id} directly.\n\n` +
|
|
1517
|
+
`Only chores and bugs can be merged. Features complete when all their chores are done.\n` +
|
|
1518
|
+
`Test worktrees (tests/* branches) merge BDD scenarios without completing the feature.`
|
|
1519
|
+
));
|
|
1520
|
+
}
|
|
1521
|
+
|
|
1511
1522
|
console.log(`Merging work item #${currentWork.id}: ${currentWork.title}`);
|
|
1512
1523
|
console.log(`Branch: ${currentBranch}`);
|
|
1513
|
-
|
|
1524
|
+
|
|
1514
1525
|
// Step 1: Push feature branch to remote
|
|
1515
1526
|
// NOTE: Use ['pipe', 'inherit', 'inherit'] instead of 'inherit' to avoid stealing stdin
|
|
1516
1527
|
// from Claude Code's shell. Using 'inherit' for stdin breaks the shell when run interactively.
|
|
@@ -1724,10 +1735,8 @@ async function mergeWork(options = {}) {
|
|
|
1724
1735
|
|
|
1725
1736
|
console.log(`✓ Successfully merged work item #${currentWork.id}`);
|
|
1726
1737
|
|
|
1727
|
-
// Check if this is a test worktree (tests/ prefix) - only set scenario_file, don't mark done
|
|
1728
|
-
const isTestWorktree = currentBranch.startsWith('tests/');
|
|
1729
|
-
|
|
1730
1738
|
// Get worktree info from database (needed for cleanup message)
|
|
1739
|
+
// Note: isTestWorktree was already set before git operations for early validation
|
|
1731
1740
|
const worktree = await new Promise((resolve, reject) => {
|
|
1732
1741
|
db.get(
|
|
1733
1742
|
`SELECT id, worktree_path, branch_name FROM worktrees WHERE work_item_id = ? AND status = 'active'`,
|
|
@@ -1775,16 +1784,17 @@ async function mergeWork(options = {}) {
|
|
|
1775
1784
|
|
|
1776
1785
|
console.log(`✅ BDD tests merged for feature #${currentWork.id}`);
|
|
1777
1786
|
console.log(' Feature remains in discovery phase - create chores to continue');
|
|
1778
|
-
} else if (currentWork.type
|
|
1779
|
-
// Non-test branch for a non-
|
|
1787
|
+
} else if (!['chore', 'bug'].includes(currentWork.type)) {
|
|
1788
|
+
// Non-test branch for a non-mergeable type - should have been caught by early validation
|
|
1789
|
+
// but kept as defensive check
|
|
1780
1790
|
return Promise.reject(new Error(
|
|
1781
1791
|
`Cannot merge ${currentWork.type} #${currentWork.id} directly.\n\n` +
|
|
1782
|
-
`Only chores can be merged. Features complete when all their chores are done.\n` +
|
|
1792
|
+
`Only chores and bugs can be merged. Features complete when all their chores are done.\n` +
|
|
1783
1793
|
`Test worktrees (tests/* branches) merge BDD scenarios without completing the feature.`
|
|
1784
1794
|
));
|
|
1785
1795
|
} else {
|
|
1786
|
-
// Chore worktree: mark as done
|
|
1787
|
-
console.log(
|
|
1796
|
+
// Chore or bug worktree: mark as done
|
|
1797
|
+
console.log(`Marking ${currentWork.type} as done...`);
|
|
1788
1798
|
const completedAt = new Date().toISOString();
|
|
1789
1799
|
await new Promise((resolve, reject) => {
|
|
1790
1800
|
db.run(
|
|
@@ -1796,7 +1806,7 @@ async function mergeWork(options = {}) {
|
|
|
1796
1806
|
}
|
|
1797
1807
|
);
|
|
1798
1808
|
});
|
|
1799
|
-
console.log(`✅
|
|
1809
|
+
console.log(`✅ ${currentWork.type.charAt(0).toUpperCase() + currentWork.type.slice(1)} #${currentWork.id} marked as done`);
|
|
1800
1810
|
}
|
|
1801
1811
|
|
|
1802
1812
|
// Mark worktree as merged but DON'T delete it yet
|
package/package.json
CHANGED
|
@@ -13,16 +13,20 @@ 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
|
+
**Six commands in workflow order:**
|
|
17
17
|
|
|
18
18
|
| Command | Used For | When | Phase |
|
|
19
19
|
|---------|----------|------|-------|
|
|
20
|
+
| `work prototype start <feature-id> [approach]` | Create worktree for UX prototyping | After UX approaches proposed (Step 4) | Feature Planning |
|
|
21
|
+
| `work prototype merge <feature-id>` | Merge prototype to main | After user tests prototype (Step 4) | Feature Planning |
|
|
20
22
|
| `work tests start <feature-id>` | Create worktree for test authoring | After Integration Contract (Step 7) | Feature Planning |
|
|
21
|
-
| `work tests merge` → `cd` → `work cleanup` | Merge tests to main, then cleanup worktree | After chores created (Step 12) | Feature Planning |
|
|
22
23
|
| `work implement <feature-id>` | Transition feature to implementation phase | After chores created (Step 11) | Feature Planning |
|
|
24
|
+
| `work tests merge` → `cd` → `work cleanup` | Merge tests to main, then cleanup worktree | After transition (Step 12) | Feature Planning |
|
|
23
25
|
| `work start <chore-id>` | Start implementing a specific chore | After tests merged (Step 13) | Speed Mode |
|
|
24
26
|
|
|
25
27
|
**CRITICAL:** All commands are run by **Claude**, not the user. The distinction is:
|
|
28
|
+
- `work prototype start` = Creates isolated worktree for UX prototyping (Step 4, optional)
|
|
29
|
+
- `work prototype merge` = Land prototype files on main (Step 4)
|
|
26
30
|
- `work tests start` = Creates isolated worktree for BDD test authoring (Step 7)
|
|
27
31
|
- `work implement` = Ends feature planning, transitions to implementation phase
|
|
28
32
|
- `work tests merge` = Land BDD tests on main
|
|
@@ -192,10 +192,34 @@ Do NOT proceed to Step 3 until chore is successfully created.
|
|
|
192
192
|
jettypod work start <chore-id>
|
|
193
193
|
```
|
|
194
194
|
|
|
195
|
+
**🛑 STOP AND CHECK:** Verify worktree was created successfully before proceeding.
|
|
196
|
+
|
|
197
|
+
```bash
|
|
198
|
+
sqlite3 .jettypod/work.db "SELECT worktree_path FROM worktrees WHERE work_item_id = <chore-id> AND status = 'active'"
|
|
199
|
+
```
|
|
200
|
+
|
|
201
|
+
**If empty or error:** Stop and investigate. Do NOT proceed without a valid worktree.
|
|
202
|
+
|
|
203
|
+
**Capture the worktree path:**
|
|
204
|
+
- `WORKTREE_PATH` - the absolute path from the query result (e.g., `/path/to/.jettypod-work/42-fix-button-text`)
|
|
205
|
+
|
|
206
|
+
**Display confirmation:**
|
|
207
|
+
|
|
208
|
+
```
|
|
209
|
+
📁 Worktree created: ${WORKTREE_PATH}
|
|
210
|
+
|
|
211
|
+
From this point forward, ALL file operations MUST use paths starting with:
|
|
212
|
+
${WORKTREE_PATH}/
|
|
213
|
+
```
|
|
214
|
+
|
|
215
|
+
**🔒 WORKTREE PATH LOCK:** Store `WORKTREE_PATH` - all file operations in this skill MUST use this path prefix.
|
|
216
|
+
|
|
217
|
+
---
|
|
218
|
+
|
|
195
219
|
**Then implement the change directly:**
|
|
196
220
|
|
|
197
|
-
1. Read the file(s) that need modification
|
|
198
|
-
2. Make the specific change requested
|
|
221
|
+
1. Read the file(s) that need modification (using `${WORKTREE_PATH}/...`)
|
|
222
|
+
2. Make the specific change requested (using `${WORKTREE_PATH}/...`)
|
|
199
223
|
3. Verify the change looks correct
|
|
200
224
|
|
|
201
225
|
**Display progress:**
|
|
@@ -203,7 +227,7 @@ jettypod work start <chore-id>
|
|
|
203
227
|
```
|
|
204
228
|
📝 Implementing change...
|
|
205
229
|
|
|
206
|
-
Modified: [
|
|
230
|
+
Modified: ${WORKTREE_PATH}/[relative path]
|
|
207
231
|
Change: [what was changed]
|
|
208
232
|
|
|
209
233
|
Verifying...
|
|
@@ -224,9 +248,11 @@ Verifying...
|
|
|
224
248
|
|
|
225
249
|
**If verification passes:**
|
|
226
250
|
|
|
251
|
+
**🔒 WORKTREE PATH REQUIRED:** Use the `WORKTREE_PATH` captured in Step 3.
|
|
252
|
+
|
|
227
253
|
```bash
|
|
228
254
|
# Commit the change
|
|
229
|
-
cd
|
|
255
|
+
cd ${WORKTREE_PATH}
|
|
230
256
|
git add .
|
|
231
257
|
git commit -m "fix: [brief description]
|
|
232
258
|
|