jettypod 4.4.90 → 4.4.92
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
CHANGED
|
@@ -245,16 +245,32 @@ Status: ${currentWork.status}
|
|
|
245
245
|
<jettypod_essentials>
|
|
246
246
|
JettyPod: Structured workflow system with skills that guide complex workflows.
|
|
247
247
|
|
|
248
|
-
## ⚠️ CRITICAL: All Work
|
|
249
|
-
|
|
250
|
-
-
|
|
251
|
-
|
|
252
|
-
|
|
248
|
+
## ⚠️ CRITICAL: All Work Starts with request-routing
|
|
249
|
+
|
|
250
|
+
**WHY:** request-routing creates a safe workspace (worktree) where your changes can actually be committed. Without it, you'll edit files on main, then discover the pre-commit hook blocks you—leaving uncommitted changes that can't be saved.
|
|
251
|
+
|
|
252
|
+
**FIRST RESPONSE RULE:** If user describes ANY code change, your FIRST action must be invoking request-routing. Not after reading files. Not after understanding the problem. FIRST.
|
|
253
|
+
|
|
254
|
+
**Trigger phrases → invoke request-routing immediately:**
|
|
255
|
+
- "we should...", "let's...", "can you..." (implementation requests)
|
|
256
|
+
- "fix", "broken", "not working", "bug" (bug reports)
|
|
257
|
+
- "add", "build", "create", "implement" (feature requests)
|
|
258
|
+
- "refactor", "migrate", "upgrade" (technical work)
|
|
259
|
+
- "I noticed...", "I'm thinking..." (when followed by desired change)
|
|
260
|
+
|
|
261
|
+
**⚠️ ANTI-PATTERN: Do NOT edit files before invoking request-routing.**
|
|
262
|
+
Wrong: See problem → edit files → realize you're on main → ask about workflow
|
|
263
|
+
Wrong: Read files → understand problem → try to fix → get blocked → create work item
|
|
264
|
+
Right: User describes work → invoke request-routing → skill creates worktree → then edit
|
|
253
265
|
|
|
254
266
|
## ⚠️ CRITICAL: Skills are MANDATORY for workflows
|
|
255
267
|
Skills auto-activate and MUST complete their full workflow:
|
|
256
|
-
-
|
|
257
|
-
-
|
|
268
|
+
- **request-routing**: ⚡ ENTRY POINT - routes ALL work requests to correct skill
|
|
269
|
+
- epic-planning: Guides architectural decisions (invoked by request-routing)
|
|
270
|
+
- feature-planning: Guides UX discovery + BDD scenarios (invoked by request-routing)
|
|
271
|
+
- chore-planning: Guides technical work planning (invoked by request-routing)
|
|
272
|
+
- bug-planning: Guides bug investigation (invoked by request-routing)
|
|
273
|
+
- simple-improvement: Direct implementation for obvious changes (invoked by request-routing)
|
|
258
274
|
- speed-mode: Implements happy path, THEN auto-invokes stable-mode
|
|
259
275
|
- stable-mode: Adds error handling to speed implementation
|
|
260
276
|
- external-transition: Guides launch preparation
|
|
@@ -1367,14 +1367,17 @@ async function mergeWork(options = {}) {
|
|
|
1367
1367
|
try {
|
|
1368
1368
|
// Get feature branch - either passed explicitly, from worktree DB, or from current CWD
|
|
1369
1369
|
let currentBranch;
|
|
1370
|
+
// Track worktree path for uncommitted changes check
|
|
1371
|
+
let worktreePath = null;
|
|
1372
|
+
|
|
1370
1373
|
if (featureBranch) {
|
|
1371
1374
|
// Branch passed from caller (e.g., status transition with worktree)
|
|
1372
1375
|
currentBranch = featureBranch;
|
|
1373
1376
|
} else if (workItemId) {
|
|
1374
|
-
// Explicit work item ID - look up branch from worktrees table
|
|
1377
|
+
// Explicit work item ID - look up branch AND worktree_path from worktrees table
|
|
1375
1378
|
const worktreeRecord = await new Promise((resolve, reject) => {
|
|
1376
1379
|
db.get(
|
|
1377
|
-
`SELECT branch_name FROM worktrees WHERE work_item_id = ? AND status = 'active'`,
|
|
1380
|
+
`SELECT branch_name, worktree_path FROM worktrees WHERE work_item_id = ? AND status = 'active'`,
|
|
1378
1381
|
[workItemId],
|
|
1379
1382
|
(err, row) => {
|
|
1380
1383
|
if (err) return reject(err);
|
|
@@ -1389,6 +1392,7 @@ async function mergeWork(options = {}) {
|
|
|
1389
1392
|
));
|
|
1390
1393
|
}
|
|
1391
1394
|
currentBranch = worktreeRecord.branch_name;
|
|
1395
|
+
worktreePath = worktreeRecord.worktree_path;
|
|
1392
1396
|
} else {
|
|
1393
1397
|
// Detect from current branch in CWD
|
|
1394
1398
|
try {
|
|
@@ -1408,6 +1412,61 @@ async function mergeWork(options = {}) {
|
|
|
1408
1412
|
if (currentBranch === 'main' || currentBranch === 'master') {
|
|
1409
1413
|
return Promise.reject(new Error('Already on main branch. Cannot merge from main to main.'));
|
|
1410
1414
|
}
|
|
1415
|
+
|
|
1416
|
+
// If we were running from inside a worktree, capture that path
|
|
1417
|
+
if (cwd.includes('.jettypod-work')) {
|
|
1418
|
+
worktreePath = cwd;
|
|
1419
|
+
}
|
|
1420
|
+
}
|
|
1421
|
+
|
|
1422
|
+
// CRITICAL SAFETY CHECK: Verify worktree has no uncommitted changes
|
|
1423
|
+
// This prevents silent data loss when user forgets to commit their work
|
|
1424
|
+
if (worktreePath) {
|
|
1425
|
+
const fs = require('fs');
|
|
1426
|
+
if (fs.existsSync(worktreePath)) {
|
|
1427
|
+
try {
|
|
1428
|
+
const worktreeStatus = execSync('git status --porcelain', {
|
|
1429
|
+
cwd: worktreePath,
|
|
1430
|
+
encoding: 'utf8',
|
|
1431
|
+
stdio: 'pipe'
|
|
1432
|
+
}).trim();
|
|
1433
|
+
|
|
1434
|
+
if (worktreeStatus) {
|
|
1435
|
+
const lines = worktreeStatus.split('\n');
|
|
1436
|
+
const staged = lines.filter(line => /^[MADRC]/.test(line));
|
|
1437
|
+
const unstaged = lines.filter(line => /^.[MD]/.test(line));
|
|
1438
|
+
const untracked = lines.filter(line => /^\?\?/.test(line));
|
|
1439
|
+
|
|
1440
|
+
// Block on any changes (staged, unstaged, or untracked)
|
|
1441
|
+
if (staged.length > 0 || unstaged.length > 0 || untracked.length > 0) {
|
|
1442
|
+
let errorDetails = `\n❌ UNCOMMITTED CHANGES IN WORKTREE - MERGE BLOCKED\n\n`;
|
|
1443
|
+
errorDetails += `Worktree: ${worktreePath}\n`;
|
|
1444
|
+
|
|
1445
|
+
if (staged.length > 0) {
|
|
1446
|
+
errorDetails += `\nStaged files (${staged.length}):\n${staged.map(l => ' ' + l).join('\n')}`;
|
|
1447
|
+
}
|
|
1448
|
+
if (unstaged.length > 0) {
|
|
1449
|
+
errorDetails += `\n\nUnstaged changes (${unstaged.length}):\n${unstaged.map(l => ' ' + l).join('\n')}`;
|
|
1450
|
+
}
|
|
1451
|
+
if (untracked.length > 0) {
|
|
1452
|
+
errorDetails += `\n\nUntracked files (${untracked.length}):\n${untracked.map(l => ' ' + l).join('\n')}`;
|
|
1453
|
+
}
|
|
1454
|
+
|
|
1455
|
+
errorDetails += `\n\n⚠️ YOUR WORK WILL BE LOST if you merge without committing!\n\n`;
|
|
1456
|
+
errorDetails += `To save your work, run:\n`;
|
|
1457
|
+
errorDetails += ` cd "${worktreePath}"\n`;
|
|
1458
|
+
errorDetails += ` git add -A && git commit -m "your message"\n\n`;
|
|
1459
|
+
errorDetails += `Then retry:\n`;
|
|
1460
|
+
errorDetails += ` jettypod work merge ${currentWork.id}`;
|
|
1461
|
+
|
|
1462
|
+
return Promise.reject(new Error(errorDetails));
|
|
1463
|
+
}
|
|
1464
|
+
}
|
|
1465
|
+
} catch (statusErr) {
|
|
1466
|
+
// If we can't check status, warn but continue (worktree may be corrupted)
|
|
1467
|
+
console.warn(`⚠️ Warning: Could not check worktree status: ${statusErr.message}`);
|
|
1468
|
+
}
|
|
1469
|
+
}
|
|
1411
1470
|
}
|
|
1412
1471
|
|
|
1413
1472
|
// Check for uncommitted changes
|
package/package.json
CHANGED
|
@@ -42,7 +42,9 @@ From the user's request, identify work type and complexity signals:
|
|
|
42
42
|
| "quick", "small", "just", "simple", "tweak" | Lower complexity |
|
|
43
43
|
| "feature", "workflow", "experience", "redesign" | Higher complexity |
|
|
44
44
|
| References specific file/function | Lower complexity |
|
|
45
|
-
|
|
|
45
|
+
| Has edge cases to consider (validation, failures, states) | Higher complexity |
|
|
46
|
+
| Could fail in interesting ways | Higher complexity |
|
|
47
|
+
| Needs error handling design | Higher complexity |
|
|
46
48
|
|
|
47
49
|
### Step 2: Gather Context (Silent - No Questions)
|
|
48
50
|
|
|
@@ -86,13 +88,19 @@ Does this need UX exploration?
|
|
|
86
88
|
├─► Yes → feature-planning
|
|
87
89
|
│
|
|
88
90
|
▼
|
|
91
|
+
Are there edge cases to consider?
|
|
92
|
+
(Validation? Error states? Things that could fail? Multiple outcomes?)
|
|
93
|
+
├─► Yes → feature-planning
|
|
94
|
+
│ (The speed→stable split helps: make it work, then handle edge cases)
|
|
95
|
+
│
|
|
96
|
+
▼
|
|
89
97
|
Is this substantial technical work?
|
|
90
98
|
(Refactoring, infrastructure, migrations, multi-file changes)
|
|
91
99
|
├─► Yes → chore-planning
|
|
92
100
|
│
|
|
93
101
|
▼
|
|
94
|
-
Is this
|
|
95
|
-
(
|
|
102
|
+
Is this truly atomic?
|
|
103
|
+
(No edge cases. Happy path IS the complete implementation.)
|
|
96
104
|
└─► Yes → simple-improvement
|
|
97
105
|
```
|
|
98
106
|
|
|
@@ -102,9 +110,9 @@ Is this a simple, obvious change?
|
|
|
102
110
|
|-------|-------------|-------------|
|
|
103
111
|
| **bug-planning** | Something is broken/not working as expected | Investigation → fix |
|
|
104
112
|
| **epic-planning** | Large initiative spanning multiple features | Break down → plan features |
|
|
105
|
-
| **feature-planning** | New
|
|
113
|
+
| **feature-planning** | New behavior needing UX exploration OR has edge cases worth sequencing | UX exploration → BDD → speed → stable → production |
|
|
106
114
|
| **chore-planning** | Substantial technical work, clear implementation | speed → stable → production |
|
|
107
|
-
| **simple-improvement** |
|
|
115
|
+
| **simple-improvement** | Atomic change where happy path IS the complete implementation | Direct implementation |
|
|
108
116
|
|
|
109
117
|
## Routing Examples
|
|
110
118
|
|
|
@@ -125,6 +133,14 @@ Is this a simple, obvious change?
|
|
|
125
133
|
|
|
126
134
|
*(Multiple valid UX approaches exist)*
|
|
127
135
|
|
|
136
|
+
**→ feature-planning (small but has edge cases)**
|
|
137
|
+
- "Add form validation to the signup form"
|
|
138
|
+
- "Add retry logic when the API fails"
|
|
139
|
+
- "Add confirmation before deleting items"
|
|
140
|
+
- "Add input validation for the settings"
|
|
141
|
+
|
|
142
|
+
*(Looks small, but has edge cases: what errors? what states? what feedback? Speed→stable split helps.)*
|
|
143
|
+
|
|
128
144
|
**→ chore-planning**
|
|
129
145
|
- "Refactor the auth module to use the new pattern"
|
|
130
146
|
- "Migrate from Moment.js to date-fns"
|
|
@@ -140,7 +156,7 @@ Is this a simple, obvious change?
|
|
|
140
156
|
- "Change the header color to blue"
|
|
141
157
|
- "Add a tooltip to the settings icon"
|
|
142
158
|
|
|
143
|
-
*(
|
|
159
|
+
*(Truly atomic: no edge cases, no error states to design, happy path IS the complete implementation)*
|
|
144
160
|
|
|
145
161
|
## Stating Your Routing Decision
|
|
146
162
|
|
|
@@ -156,12 +172,18 @@ This is a larger initiative with multiple features. Let's break it down.
|
|
|
156
172
|
```
|
|
157
173
|
Then invoke epic-planning skill.
|
|
158
174
|
|
|
159
|
-
**Feature:**
|
|
175
|
+
**Feature (UX exploration):**
|
|
160
176
|
```
|
|
161
177
|
This adds new user-facing behavior with some design choices to explore. Let me suggest a few approaches.
|
|
162
178
|
```
|
|
163
179
|
Then invoke feature-planning skill.
|
|
164
180
|
|
|
181
|
+
**Feature (edge cases):**
|
|
182
|
+
```
|
|
183
|
+
This has edge cases worth handling separately - let's make it work first, then handle the error states.
|
|
184
|
+
```
|
|
185
|
+
Then invoke feature-planning skill.
|
|
186
|
+
|
|
165
187
|
**Chore:**
|
|
166
188
|
```
|
|
167
189
|
This is technical work with a clear implementation path. Let me help you plan it out.
|
|
@@ -179,10 +201,10 @@ Then invoke simple-improvement skill.
|
|
|
179
201
|
**If genuinely ambiguous (rare - should be <20% of cases):**
|
|
180
202
|
```
|
|
181
203
|
I could approach "[brief description]" as:
|
|
182
|
-
- A **simple improvement** -
|
|
183
|
-
- A **feature** -
|
|
204
|
+
- A **simple improvement** - implement it directly (no edge cases to worry about)
|
|
205
|
+
- A **feature** - sequence it (make it work first, then handle edge cases)
|
|
184
206
|
|
|
185
|
-
|
|
207
|
+
Are there edge cases worth handling separately, or is this truly atomic?
|
|
186
208
|
```
|
|
187
209
|
|
|
188
210
|
Only ask when you truly cannot decide based on signals and context.
|