jettypod 4.4.19 → 4.4.22

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.
@@ -0,0 +1,111 @@
1
+ Feature: Work item mode handling
2
+ As a developer
3
+ I want features to support speed/stable/production modes
4
+ So I can work in the appropriate mode for each phase
5
+
6
+ # Epic scenarios - epics don't have mode
7
+ Scenario: Create epic without mode
8
+ Given jettypod is initialized
9
+ When I create an epic "Test Epic" without mode
10
+ Then the work item is created successfully
11
+ And the work item has NULL mode
12
+
13
+ Scenario: Create epic with mode (optional)
14
+ Given jettypod is initialized
15
+ When I create an epic "Test Epic" with mode "stable"
16
+ Then the work item is created successfully
17
+ And the work item has mode "stable"
18
+
19
+ # Feature scenarios - mode is optional
20
+ Scenario: Create feature with explicit mode
21
+ Given jettypod is initialized
22
+ When I create a feature "Test Feature" with mode "speed"
23
+ Then the work item is created successfully
24
+ And the work item has mode "speed"
25
+
26
+ Scenario: Create feature without mode has NULL mode
27
+ Given jettypod is initialized
28
+ When I create a feature "Test Feature" without mode
29
+ Then the work item is created successfully
30
+ And the work item has NULL mode
31
+
32
+ Scenario: Create feature with invalid mode
33
+ Given jettypod is initialized
34
+ When I try to create a feature "Test Feature" with mode "invalid"
35
+ Then I get an error "Invalid mode"
36
+ And no work item is created
37
+
38
+ # Bug scenarios - bugs don't have modes
39
+ Scenario: Create bug with mode fails
40
+ Given jettypod is initialized
41
+ When I try to create a bug "Test Bug" with mode "stable"
42
+ Then I get an error "Bugs cannot have modes"
43
+ And no work item is created
44
+
45
+ Scenario: Create bug without mode succeeds with NULL
46
+ Given jettypod is initialized
47
+ When I create a bug "Test Bug" without mode
48
+ Then the work item is created successfully
49
+ And the work item has no mode
50
+
51
+ # Chore scenarios - chores don't have modes
52
+ Scenario: Create chore with mode fails
53
+ Given jettypod is initialized
54
+ When I try to create a chore "Test Chore" with mode "production"
55
+ Then I get an error "Chores do not have modes"
56
+ And no work item is created
57
+
58
+ Scenario: Create chore without mode succeeds with NULL
59
+ Given jettypod is initialized
60
+ When I create a chore "Test Chore" without mode
61
+ Then the work item is created successfully
62
+ And the work item has NULL mode
63
+
64
+ # All valid modes
65
+ Scenario Outline: Create feature with all valid modes
66
+ Given jettypod is initialized
67
+ When I create a feature "Test Feature" with mode "<mode>"
68
+ Then the work item is created successfully
69
+ And the work item has mode "<mode>"
70
+
71
+ Examples:
72
+ | mode |
73
+ | speed |
74
+ | stable |
75
+ | production |
76
+
77
+ # Integration - hierarchical structure
78
+ Scenario: Epic with children in different modes
79
+ Given jettypod is initialized
80
+ And I create an epic "Test Epic" without mode
81
+ And I create a feature "Speed Feature" with mode "speed" and parent epic
82
+ And I create a bug "Test Bug" with parent epic
83
+ And I create a chore "Test Chore" without mode and parent epic
84
+ When I view the backlog
85
+ Then I see the epic without mode indicator
86
+ And I see the feature with mode "speed"
87
+ And I see the bug without mode indicator
88
+ And I see the chore without mode indicator
89
+
90
+ # Edge cases
91
+ Scenario: Create multiple items with same title but different modes
92
+ Given jettypod is initialized
93
+ When I create a feature "Duplicate" with mode "speed"
94
+ And I create a feature "Duplicate" with mode "stable"
95
+ Then both work items are created successfully
96
+ And they have different modes
97
+
98
+ Scenario: Mode is case-sensitive
99
+ Given jettypod is initialized
100
+ When I try to create a feature "Test" with mode "Speed"
101
+ Then I get an error "Invalid mode"
102
+
103
+ Scenario: Mode with whitespace is invalid
104
+ Given jettypod is initialized
105
+ When I try to create a feature "Test" with mode " speed "
106
+ Then I get an error "Invalid mode"
107
+
108
+ Scenario: Empty string mode is treated as NULL
109
+ Given jettypod is initialized
110
+ When I try to create a feature "Test" with mode ""
111
+ Then I get an error "Invalid mode"
@@ -0,0 +1,70 @@
1
+ Feature: Work set-mode updates CLAUDE.md if item is current
2
+ As a developer
3
+ I want to change a work item's mode with jettypod work set-mode
4
+ So I can adjust my approach without recreating the work item
5
+
6
+ Background:
7
+ Given jettypod is initialized
8
+ And CLAUDE.md exists
9
+
10
+ # Basic mode changes
11
+ Scenario: Set mode on current work item updates CLAUDE.md
12
+ Given I create a feature "Test Feature" with mode "speed"
13
+ And I start work on the feature
14
+ And CLAUDE.md mode is set to "speed"
15
+ When I set mode for current item to "stable"
16
+ Then the work item has mode "stable"
17
+ And CLAUDE.md mode is set to "stable"
18
+
19
+ Scenario: Set mode on non-current item does not update CLAUDE.md
20
+ Given I create a feature "Item 1" with mode "speed"
21
+ And I create a feature "Item 2" with mode "stable"
22
+ And I start work on the feature "Item 1"
23
+ And CLAUDE.md mode is set to "speed"
24
+ When I set mode for item "Item 2" to "production"
25
+ Then item "Item 2" has mode "production"
26
+ But CLAUDE.md mode is set to "speed"
27
+
28
+ # Mode validation
29
+ Scenario: Set invalid mode shows error
30
+ Given I create a feature "Test Feature" with mode "speed"
31
+ When I try to set mode to "invalid"
32
+ Then I get error "Invalid mode"
33
+ And the work item still has mode "speed"
34
+
35
+ Scenario: Set mode is case-sensitive
36
+ Given I create a feature "Test Feature" with mode "speed"
37
+ When I try to set mode to "Speed"
38
+ Then I get error "Invalid mode"
39
+
40
+ # All valid modes
41
+ Scenario Outline: Change to all valid modes
42
+ Given I create a feature "Test Feature" with mode "speed"
43
+ And I start work on the feature
44
+ When I set mode for current item to "<new_mode>"
45
+ Then the work item has mode "<new_mode>"
46
+ And CLAUDE.md mode is set to "<new_mode>"
47
+
48
+ Examples:
49
+ | new_mode |
50
+ | stable |
51
+ | production |
52
+
53
+ # Mode persistence
54
+ Scenario: Mode change persists across work start/stop
55
+ Given I create a feature "Test Feature" with mode "speed"
56
+ And I start work on the feature
57
+ When I set mode for current item to "production"
58
+ And I stop work
59
+ And I start work on the feature
60
+ Then CLAUDE.md mode is set to "production"
61
+
62
+ # Multiple mode changes
63
+ Scenario: Change mode multiple times
64
+ Given I create a feature "Test Feature" with mode "speed"
65
+ And I start work on the feature
66
+ When I set mode for current item to "stable"
67
+ And I set mode for current item to "production"
68
+ And I set mode for current item to "speed"
69
+ Then the work item has mode "speed"
70
+ And CLAUDE.md mode is set to "speed"
@@ -0,0 +1,83 @@
1
+ Feature: Work start sets CLAUDE.md mode from work item
2
+ As a developer
3
+ I want jettypod work start to set the CLAUDE.md mode from the work item's mode
4
+ So I automatically work in the correct mode for each work item
5
+
6
+ Background:
7
+ Given jettypod is initialized
8
+ And CLAUDE.md exists
9
+
10
+ # Basic mode inheritance
11
+ Scenario: Start work on feature in speed mode
12
+ Given I create a feature "Speed Feature" with mode "speed"
13
+ When I start work on the feature
14
+ Then CLAUDE.md mode is set to "speed"
15
+
16
+ Scenario: Start work on chore inherits parent feature mode
17
+ Given I create a feature "Speed Feature" with mode "speed"
18
+ And I create a chore "Child Chore" without mode and parent feature
19
+ When I start work on the chore
20
+ Then CLAUDE.md mode is set to "speed"
21
+
22
+ Scenario: Start work on feature in production mode
23
+ Given I create a feature "Production Feature" with mode "production"
24
+ When I start work on the feature
25
+ Then CLAUDE.md mode is set to "production"
26
+
27
+ # Mode switching between work items
28
+ Scenario: Switch from speed mode item to stable mode item
29
+ Given I create a feature "Speed Feature" with mode "speed"
30
+ And I create a feature "Stable Feature" with mode "stable"
31
+ And I start work on the feature "Speed Feature"
32
+ And CLAUDE.md mode is set to "speed"
33
+ When I stop work
34
+ And I start work on the feature "Stable Feature"
35
+ Then CLAUDE.md mode is set to "stable"
36
+
37
+ Scenario: Start work updates mode even if item already in progress
38
+ Given I create a feature "Test Feature" with mode "stable"
39
+ And the feature status is "in_progress"
40
+ And CLAUDE.md has mode "speed"
41
+ When I start work on the feature
42
+ Then CLAUDE.md mode is set to "stable"
43
+
44
+ # Epic handling - epics don't have modes
45
+ Scenario: Start work on epic (NULL mode)
46
+ Given I create an epic "Test Epic" without mode
47
+ When I start work on the epic
48
+ Then CLAUDE.md has no mode line
49
+ And the current work section exists
50
+
51
+ # NULL mode handling
52
+ Scenario: Start work on feature without mode (NULL)
53
+ Given I create a feature "Default Feature" without mode
54
+ And the work item has NULL mode
55
+ When I start work on the feature
56
+ Then CLAUDE.md has no mode line
57
+
58
+ # Hierarchical structure
59
+ Scenario: Start work on child features use their own mode, not parent's
60
+ Given I create an epic "Test Epic" without mode
61
+ And I create a feature "Speed Feature" with mode "speed" and parent epic
62
+ And I create a feature "Stable Feature" with mode "stable" and parent epic
63
+ When I start work on the speed feature
64
+ Then CLAUDE.md mode is set to "speed"
65
+ When I stop work
66
+ And I start work on the stable feature
67
+ Then CLAUDE.md mode is set to "stable"
68
+
69
+ # Mode persistence
70
+ Scenario: Work item mode persists in database after start
71
+ Given I create a feature "Test Feature" with mode "stable"
72
+ When I start work on the feature
73
+ And I stop work
74
+ Then the work item still has mode "stable"
75
+
76
+ # Edge cases
77
+ Scenario: Starting work multiple times preserves mode
78
+ Given I create a feature "Test Feature" with mode "production"
79
+ When I start work on the feature
80
+ And I stop work
81
+ And I start work on the feature
82
+ Then CLAUDE.md mode is set to "production"
83
+ And the work item still has mode "production"
@@ -231,28 +231,34 @@ async function createWorktree(workItem, options = {}) {
231
231
  throw new Error(`Failed to create .jettypod symlink: ${symlinkErr.message}`);
232
232
  }
233
233
 
234
- // Step 4.5: Add .jettypod to worktree's .gitignore
235
- // NOTE: git's info/exclude does NOT work for worktrees - only .gitignore works
234
+ // Step 4.5: Add .jettypod to MAIN repo's .git/info/exclude
235
+ // NOTE: Worktree-specific info/exclude does NOT work - must use main repo's exclude
236
236
  // This prevents the symlink from being committed when merging the worktree branch
237
237
  try {
238
- const gitignorePath = path.join(worktreePath, '.gitignore');
238
+ const excludePath = path.join(gitRoot, '.git', 'info', 'exclude');
239
239
 
240
- // Read existing .gitignore or create empty
241
- let gitignoreContent = '';
242
- if (fs.existsSync(gitignorePath)) {
243
- gitignoreContent = fs.readFileSync(gitignorePath, 'utf8');
240
+ // Ensure the info directory exists
241
+ const infoDir = path.dirname(excludePath);
242
+ if (!fs.existsSync(infoDir)) {
243
+ fs.mkdirSync(infoDir, { recursive: true });
244
244
  }
245
245
 
246
- // Add .jettypod if not already in .gitignore
247
- if (!gitignoreContent.includes('.jettypod')) {
248
- const newEntry = gitignoreContent.endsWith('\n') || gitignoreContent === ''
246
+ // Read existing exclude or create empty
247
+ let excludeContent = '';
248
+ if (fs.existsSync(excludePath)) {
249
+ excludeContent = fs.readFileSync(excludePath, 'utf8');
250
+ }
251
+
252
+ // Add .jettypod if not already excluded
253
+ if (!excludeContent.includes('.jettypod')) {
254
+ const newEntry = excludeContent.endsWith('\n') || excludeContent === ''
249
255
  ? '.jettypod\n'
250
256
  : '\n.jettypod\n';
251
- fs.writeFileSync(gitignorePath, gitignoreContent + newEntry);
257
+ fs.writeFileSync(excludePath, excludeContent + newEntry);
252
258
  }
253
- } catch (gitignoreErr) {
259
+ } catch (excludeErr) {
254
260
  // Non-fatal - log warning but continue
255
- console.warn(`Warning: Could not add .jettypod to .gitignore: ${gitignoreErr.message}`);
261
+ console.warn(`Warning: Could not add .jettypod to .git/info/exclude: ${excludeErr.message}`);
256
262
  }
257
263
 
258
264
  // Step 5: Symlink .env files from main repo
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "jettypod",
3
- "version": "4.4.19",
3
+ "version": "4.4.22",
4
4
  "description": "AI-powered development workflow manager with TDD, BDD, and automatic test generation",
5
5
  "main": "jettypod.js",
6
6
  "bin": {