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.
@@ -23,6 +23,7 @@ export function PlaceholderCard({ height, minHeight = DEFAULT_MIN_HEIGHT }: Plac
23
23
  borderRadius: 8,
24
24
  border: '2px dashed rgba(100, 116, 139, 0.4)',
25
25
  backgroundColor: 'rgba(100, 116, 139, 0.1)',
26
+ marginTop: 8,
26
27
  marginBottom: 8,
27
28
  }}
28
29
  />
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 Requires a Work Item
249
- **Claude CANNOT write code directly to main branch.**
250
- - All work requires: \`work create\` \`work start\` skill workflow \`work merge\`
251
- - If user asks to implement something without a work item, create one first and invoke the matching skill
252
- - Pre-commit hooks block direct commits to main
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
- - epic-planning: Guides architectural decisions
257
- - feature-planning: Guides UX discovery + BDD scenarios
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
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "jettypod",
3
- "version": "4.4.90",
3
+ "version": "4.4.92",
4
4
  "description": "AI-powered development workflow manager with TDD, BDD, and automatic test generation",
5
5
  "main": "jettypod.js",
6
6
  "bin": {
@@ -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
- | Describes user-facing behavior change | Higher complexity |
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 a simple, obvious change?
95
- (Copy, styling, config, minor behavior tweak, one clear approach)
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 user-facing behavior with UX decisions to make | UX exploration → BDD → speed → stable → production |
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** | Obvious change, no UX decisions, small scope | Direct implementation |
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
- *(One obvious implementation, no UX exploration needed, just do it)*
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** - just implement the obvious solution
183
- - A **feature** - explore a few UX approaches first
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
- Which feels right?
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.