jettypod 4.1.2 → 4.1.4

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.
Files changed (179) hide show
  1. package/.nvmrc +1 -0
  2. package/docs/COMPLETE-TESTING-STRATEGY.md +970 -0
  3. package/docs/DECISIONS.md +10 -12
  4. package/docs/NODE_VERSION.md +83 -0
  5. package/docs/TDD-INFRASTRUCTURE-STRATEGY.md +1374 -0
  6. package/docs/TESTING-FOR-NON-ENGINEERS.md +1588 -0
  7. package/docs/TESTING-STRATEGY-AUDIT.md +698 -0
  8. package/hooks/post-checkout +17 -0
  9. package/hooks/post-merge +17 -0
  10. package/hooks/pre-commit +30 -0
  11. package/jettypod.js +259 -120
  12. package/lib/coverage-tracker.js +218 -0
  13. package/lib/database.js +2 -0
  14. package/lib/db-export.js +192 -0
  15. package/lib/db-import.js +193 -0
  16. package/lib/external-transition-handler.js +32 -0
  17. package/lib/git-hook-helpers.js +174 -0
  18. package/lib/git-root.js +90 -0
  19. package/lib/infrastructure-chore-generator.js +45 -0
  20. package/lib/install-hooks.js +52 -0
  21. package/lib/jettypod-backup.js +238 -0
  22. package/lib/merge-lock.js +193 -0
  23. package/lib/migrations/012-add-worktree-path.js +38 -0
  24. package/lib/migrations/013-worktrees-table.js +86 -0
  25. package/lib/migrations/014-migrate-worktree-data.js +161 -0
  26. package/lib/migrations/015-merge-locks-table.js +67 -0
  27. package/lib/pattern-finder.js +152 -0
  28. package/lib/process-manager.js +140 -0
  29. package/lib/production-standards-reader.js +13 -2
  30. package/lib/production-standards-writer.js +85 -0
  31. package/lib/skills/feature-planning/dry-run-validator.js +135 -0
  32. package/lib/skills/feature-planning/validation-formatter.js +160 -0
  33. package/lib/smart-conflict-detection.js +168 -0
  34. package/lib/smart-fetch-rebase.js +614 -0
  35. package/lib/step-definition-parser.js +76 -0
  36. package/lib/unit-test-generator.js +232 -0
  37. package/lib/verification-command-generator.js +66 -0
  38. package/lib/worktree-diagnostics.js +413 -0
  39. package/lib/worktree-facade.js +174 -0
  40. package/lib/worktree-manager.js +636 -0
  41. package/lib/worktree-reconciler.js +429 -0
  42. package/package.json +30 -3
  43. package/skills-templates/external-transition/SKILL.md +34 -3
  44. package/skills-templates/feature-planning/SKILL.md +190 -24
  45. package/skills-templates/production-mode/SKILL.md +127 -9
  46. package/skills-templates/speed-mode/SKILL.md +454 -51
  47. package/skills-templates/stable-mode/SKILL.md +285 -76
  48. package/.claude/PROTECT_SKILLS.md +0 -28
  49. package/.claude/settings.json +0 -24
  50. package/.claude/settings.local.json +0 -16
  51. package/.claude/skills/epic-planning/SKILL.md +0 -297
  52. package/.claude/skills/external-transition/SKILL.md +0 -384
  53. package/.claude/skills/feature-planning/SKILL.md +0 -464
  54. package/.claude/skills/production-mode/SKILL.md +0 -369
  55. package/.claude/skills/speed-mode/SKILL.md +0 -481
  56. package/.claude/skills/stable-mode/SKILL.md +0 -713
  57. package/.claude/skills.backup-2025-11-10T23-33-09-368Z/epic-planning/SKILL.md +0 -297
  58. package/.claude/skills.backup-2025-11-10T23-33-09-368Z/feature-planning/SKILL.md +0 -464
  59. package/.claude/skills.backup-2025-11-10T23-33-09-368Z/speed-mode/SKILL.md +0 -467
  60. package/.claude/skills.backup-2025-11-10T23-33-09-368Z/stable-mode/SKILL.md +0 -673
  61. package/.claude/skills.backup-2025-11-11T16-15-10-070Z/epic-discover/SKILL.md +0 -297
  62. package/.claude/skills.backup-2025-11-11T16-42-43-212Z/epic-planning/SKILL.md +0 -297
  63. package/.claude/skills.backup-2025-11-11T16-42-43-212Z/feature-planning/SKILL.md +0 -464
  64. package/.claude/skills.backup-2025-11-11T16-42-43-212Z/speed-mode/SKILL.md +0 -467
  65. package/.claude/skills.backup-2025-11-11T16-42-43-212Z/stable-mode/SKILL.md +0 -673
  66. package/.claude/skills.backup-2025-11-11T17-06-09-783Z/epic-planning/SKILL.md +0 -297
  67. package/.claude/skills.backup-2025-11-11T17-06-09-783Z/feature-planning/SKILL.md +0 -464
  68. package/.claude/skills.backup-2025-11-11T17-06-09-783Z/speed-mode/SKILL.md +0 -467
  69. package/.claude/skills.backup-2025-11-11T17-06-09-783Z/stable-mode/SKILL.md +0 -673
  70. package/.devpod/current-work.json +0 -10
  71. package/.devpod/work.db +0 -0
  72. package/.github/workflows/test-safety.yml +0 -85
  73. package/.jettypod/config.json +0 -5
  74. package/.jettypod/current-work.json +0 -10
  75. package/.jettypod/hooks/README.md +0 -77
  76. package/.jettypod/hooks/protect-claude-md.js +0 -338
  77. package/.jettypod/test-work.db +0 -0
  78. package/.jettypod/work.db +0 -0
  79. package/CLAUDE.md +0 -49
  80. package/SPEED-STABLE-AUDIT.md +0 -853
  81. package/SYSTEM-BEHAVIOR.md +0 -2199
  82. package/TEST_SAFETY_AUDIT.md +0 -314
  83. package/TEST_SAFETY_IMPLEMENTATION.md +0 -97
  84. package/cucumber-report.html +0 -45
  85. package/dist/devpod-linux +0 -0
  86. package/dist/devpod-macos +0 -0
  87. package/dist/devpod-win.exe +0 -0
  88. package/docs/features/jettypod-standards-explained.md +0 -543
  89. package/docs/features/standards-inventory.md +0 -257
  90. package/features/auto-generate-production-chores.feature +0 -13
  91. package/features/backlog-command.feature +0 -26
  92. package/features/backlog-filtering-production.feature +0 -10
  93. package/features/claude-md-protection/steps.js +0 -498
  94. package/features/decisions/index.js +0 -490
  95. package/features/decisions/index.test.js +0 -208
  96. package/features/fix-text-wrapping.feature +0 -42
  97. package/features/git-hooks/git-hooks.feature +0 -30
  98. package/features/git-hooks/index.js +0 -93
  99. package/features/git-hooks/index.test.js +0 -137
  100. package/features/git-hooks/post-commit +0 -56
  101. package/features/git-hooks/post-merge +0 -47
  102. package/features/git-hooks/pre-commit +0 -28
  103. package/features/git-hooks/simple-steps.js +0 -53
  104. package/features/git-hooks/simple-test.feature +0 -10
  105. package/features/git-hooks/steps.js +0 -196
  106. package/features/jettypod-update-command.feature +0 -46
  107. package/features/mode-prompts/index.js +0 -95
  108. package/features/mode-prompts/simple-steps.js +0 -44
  109. package/features/mode-prompts/simple-test.feature +0 -9
  110. package/features/mode-prompts/validation.test.js +0 -120
  111. package/features/multiple-claude-instances.feature +0 -121
  112. package/features/production-mode-skill.feature +0 -121
  113. package/features/refactor-mode/steps.js +0 -217
  114. package/features/refactor-mode.feature +0 -49
  115. package/features/simplify-external-transition.feature +0 -166
  116. package/features/skills-update/index.test.js +0 -216
  117. package/features/step_definitions/backlog-command.steps.js +0 -37
  118. package/features/step_definitions/fix-text-wrapping.steps.js +0 -271
  119. package/features/step_definitions/multiple-claude-instances.steps.js +0 -621
  120. package/features/step_definitions/production-mode-skill.steps.js +0 -862
  121. package/features/step_definitions/simplify-external-transition.steps.js +0 -370
  122. package/features/step_definitions/terminal-logo.steps.js +0 -145
  123. package/features/step_definitions/update-command.steps.js +0 -183
  124. package/features/support/hooks.js +0 -9
  125. package/features/terminal-logo/index.js +0 -39
  126. package/features/terminal-logo/terminal-logo.feature +0 -30
  127. package/features/update-command/index.js +0 -181
  128. package/features/update-command/index.test.js +0 -225
  129. package/features/work-commands/bug-workflow-display.feature +0 -22
  130. package/features/work-commands/index.js +0 -498
  131. package/features/work-commands/simple-steps.js +0 -69
  132. package/features/work-commands/stable-tests.feature +0 -57
  133. package/features/work-commands/steps.js +0 -1174
  134. package/features/work-commands/validation.test.js +0 -88
  135. package/features/work-commands/work-commands.feature +0 -13
  136. package/features/work-tracking/discovery-validation.test.js +0 -228
  137. package/features/work-tracking/index.js +0 -1921
  138. package/features/work-tracking/mode-required.feature +0 -112
  139. package/features/work-tracking/phase-tracking.test.js +0 -482
  140. package/features/work-tracking/prototype-tracking.test.js +0 -485
  141. package/features/work-tracking/tree-view.test.js +0 -310
  142. package/features/work-tracking/work-set-mode.feature +0 -71
  143. package/features/work-tracking/work-start-mode.feature +0 -88
  144. package/full-test.txt +0 -0
  145. package/lib/bug-workflow.test.js +0 -177
  146. package/lib/claudemd.test.js +0 -195
  147. package/lib/config.test.js +0 -511
  148. package/lib/constants.test.js +0 -164
  149. package/lib/current-work.test.js +0 -146
  150. package/lib/database-project-config.test.js +0 -111
  151. package/lib/database.test.js +0 -106
  152. package/lib/decisions-generator.test.js +0 -457
  153. package/lib/decisions-helpers.test.js +0 -310
  154. package/lib/git-coordinator.js +0 -167
  155. package/lib/git.test.js +0 -145
  156. package/lib/migrations/002-default-work-item-modes.test.js +0 -351
  157. package/lib/production-chore-generator.test.js +0 -432
  158. package/lib/production-context-detector.test.js +0 -277
  159. package/lib/production-scenario-appender.test.js +0 -235
  160. package/lib/production-scenario-validator.test.js +0 -246
  161. package/lib/production-standards-reader.test.js +0 -270
  162. package/lib/project-state.test.js +0 -92
  163. package/lib/push-queue.js +0 -417
  164. package/lib/queue-processor.js +0 -74
  165. package/lib/test-helpers.js +0 -202
  166. package/lib/test-helpers.test.js +0 -255
  167. package/prototypes/2025-01-11-production-mode-autonomous.js +0 -119
  168. package/prototypes/2025-01-11-production-mode-collaborative.js +0 -166
  169. package/prototypes/2025-01-11-production-mode-guided.js +0 -217
  170. package/prototypes/2025-01-11-production-mode-smart-context.js +0 -347
  171. package/prototypes/2025-01-11-production-standards-example.md +0 -204
  172. package/prototypes/2025-11-10-backlog-filtering-tree-aware.js +0 -242
  173. package/prototypes/test/index.html +0 -1
  174. package/setup-dist-repo.sh +0 -68
  175. package/test-production-standards-engine.js +0 -130
  176. package/test-results.json +0 -2195
  177. package/test-safety-check.sh +0 -80
  178. package/work-item-tracking-plan.md +0 -199
  179. /package/{.jettypod/devpod.db → jettypod.db} +0 -0
@@ -1,310 +0,0 @@
1
- // Tests for tree view validation and error handling
2
- // These tests focus on the printTree and getTree functions' error handling
3
- // rather than full integration tests
4
-
5
- describe('Tree View - Error Handling', () => {
6
- describe('printTree validation', () => {
7
- const originalConsoleLog = console.log;
8
- let logOutput = [];
9
-
10
- beforeEach(() => {
11
- logOutput = [];
12
- console.log = jest.fn((...args) => {
13
- logOutput.push(args.join(' '));
14
- });
15
- });
16
-
17
- afterEach(() => {
18
- console.log = originalConsoleLog;
19
- });
20
-
21
- function printTree(items, prefix = '') {
22
- if (!Array.isArray(items)) {
23
- throw new Error('Items must be an array');
24
- }
25
-
26
- items.forEach((item, index) => {
27
- if (!item || typeof item !== 'object') {
28
- return; // Skip invalid items
29
- }
30
-
31
- // Print item (simplified for tests)
32
- console.log(`${prefix}${item.title}`);
33
-
34
- // Print description if present
35
- if (item.description) {
36
- console.log(`${prefix} "${item.description}"`);
37
- }
38
-
39
- if (item.children && item.children.length > 0) {
40
- const newPrefix = prefix + ' ';
41
- printTree(item.children, newPrefix);
42
- }
43
- });
44
- }
45
-
46
- test('should throw error for null input', () => {
47
- expect(() => printTree(null)).toThrow('Items must be an array');
48
- });
49
-
50
- test('should throw error for string input', () => {
51
- expect(() => printTree('not-an-array')).toThrow('Items must be an array');
52
- });
53
-
54
- test('should throw error for object input', () => {
55
- expect(() => printTree({})).toThrow('Items must be an array');
56
- });
57
-
58
- test('should not throw for empty array', () => {
59
- expect(() => printTree([])).not.toThrow();
60
- });
61
-
62
- test('should handle single valid item', () => {
63
- const items = [{
64
- id: 1,
65
- title: 'Test',
66
- type: 'feature',
67
- status: 'backlog',
68
- children: []
69
- }];
70
- expect(() => printTree(items)).not.toThrow();
71
- });
72
-
73
- test('should handle nested items', () => {
74
- const items = [{
75
- id: 1,
76
- title: 'Epic',
77
- type: 'epic',
78
- status: 'backlog',
79
- children: [{
80
- id: 2,
81
- title: 'Feature',
82
- type: 'feature',
83
- status: 'backlog',
84
- children: []
85
- }]
86
- }];
87
- expect(() => printTree(items)).not.toThrow();
88
- });
89
-
90
- test('should skip null items in array', () => {
91
- const items = [
92
- null,
93
- {
94
- id: 1,
95
- title: 'Valid',
96
- type: 'feature',
97
- status: 'backlog',
98
- children: []
99
- }
100
- ];
101
- expect(() => printTree(items)).not.toThrow();
102
- });
103
-
104
- test('should skip undefined items in array', () => {
105
- const items = [
106
- undefined,
107
- {
108
- id: 1,
109
- title: 'Valid',
110
- type: 'feature',
111
- status: 'backlog',
112
- children: []
113
- }
114
- ];
115
- expect(() => printTree(items)).not.toThrow();
116
- });
117
-
118
- test('should handle items without children property', () => {
119
- const items = [{
120
- id: 1,
121
- title: 'Test',
122
- type: 'feature',
123
- status: 'backlog'
124
- // no children property
125
- }];
126
- expect(() => printTree(items)).not.toThrow();
127
- });
128
-
129
- test('should handle deeply nested structures', () => {
130
- const items = [{
131
- id: 1,
132
- title: 'Level 1',
133
- children: [{
134
- id: 2,
135
- title: 'Level 2',
136
- children: [{
137
- id: 3,
138
- title: 'Level 3',
139
- children: []
140
- }]
141
- }]
142
- }];
143
- expect(() => printTree(items)).not.toThrow();
144
- });
145
-
146
- test('should display description when present', () => {
147
- const items = [{
148
- id: 1,
149
- title: 'Test Item',
150
- type: 'feature',
151
- status: 'backlog',
152
- description: 'Test description',
153
- children: []
154
- }];
155
- printTree(items);
156
- expect(logOutput).toContain('Test Item');
157
- expect(logOutput).toContain(' "Test description"');
158
- });
159
-
160
- test('should not break when description is missing', () => {
161
- const items = [{
162
- id: 1,
163
- title: 'No Description',
164
- type: 'feature',
165
- status: 'backlog',
166
- children: []
167
- }];
168
- expect(() => printTree(items)).not.toThrow();
169
- expect(logOutput).toContain('No Description');
170
- expect(logOutput).not.toContain('""');
171
- });
172
-
173
- test('should handle empty string description', () => {
174
- const items = [{
175
- id: 1,
176
- title: 'Empty Description',
177
- type: 'feature',
178
- status: 'backlog',
179
- description: '',
180
- children: []
181
- }];
182
- expect(() => printTree(items)).not.toThrow();
183
- expect(logOutput).toContain('Empty Description');
184
- // Empty string is falsy, so description should not display
185
- expect(logOutput).not.toContain('""');
186
- });
187
-
188
- test('should display descriptions for nested items', () => {
189
- const items = [{
190
- id: 1,
191
- title: 'Parent',
192
- description: 'Parent description',
193
- children: [{
194
- id: 2,
195
- title: 'Child',
196
- description: 'Child description',
197
- children: []
198
- }]
199
- }];
200
- printTree(items);
201
- expect(logOutput).toContain('Parent');
202
- expect(logOutput).toContain(' "Parent description"');
203
- expect(logOutput).toContain(' Child');
204
- expect(logOutput).toContain(' "Child description"');
205
- });
206
- });
207
-
208
- describe('getTree error handling', () => {
209
- test('should build tree from flat structure', () => {
210
- const rows = [
211
- { id: 1, title: 'Epic', type: 'epic', status: 'backlog', parent_id: null, epic_id: 1 },
212
- { id: 2, title: 'Feature', type: 'feature', status: 'backlog', parent_id: 1, epic_id: 1 }
213
- ];
214
-
215
- const itemsById = {};
216
- const rootItems = [];
217
-
218
- // Build lookup
219
- rows.forEach(item => {
220
- itemsById[item.id] = item;
221
- item.children = [];
222
- });
223
-
224
- // Build tree
225
- rows.forEach(item => {
226
- if (item.parent_id && itemsById[item.parent_id]) {
227
- itemsById[item.parent_id].children.push(item);
228
- } else if (!item.parent_id) {
229
- rootItems.push(item);
230
- }
231
- });
232
-
233
- expect(rootItems).toHaveLength(1);
234
- expect(rootItems[0].id).toBe(1);
235
- expect(rootItems[0].children).toHaveLength(1);
236
- expect(rootItems[0].children[0].id).toBe(2);
237
- });
238
-
239
- test('should handle empty rows array', () => {
240
- const rows = [];
241
- const itemsById = {};
242
- const rootItems = [];
243
-
244
- rows.forEach(item => {
245
- itemsById[item.id] = item;
246
- item.children = [];
247
- });
248
-
249
- rows.forEach(item => {
250
- if (item.parent_id && itemsById[item.parent_id]) {
251
- itemsById[item.parent_id].children.push(item);
252
- } else if (!item.parent_id) {
253
- rootItems.push(item);
254
- }
255
- });
256
-
257
- expect(rootItems).toEqual([]);
258
- });
259
-
260
- test('should handle orphaned items (missing parent)', () => {
261
- const rows = [
262
- { id: 1, title: 'Orphan', type: 'feature', status: 'backlog', parent_id: 999, epic_id: null }
263
- ];
264
-
265
- const itemsById = {};
266
- const rootItems = [];
267
-
268
- rows.forEach(item => {
269
- itemsById[item.id] = item;
270
- item.children = [];
271
- });
272
-
273
- rows.forEach(item => {
274
- if (item.parent_id && itemsById[item.parent_id]) {
275
- itemsById[item.parent_id].children.push(item);
276
- } else if (!item.parent_id) {
277
- rootItems.push(item);
278
- }
279
- });
280
-
281
- // Orphaned item (has parent_id but parent doesn't exist) is not added to rootItems
282
- expect(rootItems).toHaveLength(0);
283
- });
284
-
285
- test('should handle multiple root items', () => {
286
- const rows = [
287
- { id: 1, title: 'Epic 1', type: 'epic', status: 'backlog', parent_id: null, epic_id: 1 },
288
- { id: 2, title: 'Epic 2', type: 'epic', status: 'backlog', parent_id: null, epic_id: 2 }
289
- ];
290
-
291
- const itemsById = {};
292
- const rootItems = [];
293
-
294
- rows.forEach(item => {
295
- itemsById[item.id] = item;
296
- item.children = [];
297
- });
298
-
299
- rows.forEach(item => {
300
- if (item.parent_id && itemsById[item.parent_id]) {
301
- itemsById[item.parent_id].children.push(item);
302
- } else if (!item.parent_id) {
303
- rootItems.push(item);
304
- }
305
- });
306
-
307
- expect(rootItems).toHaveLength(2);
308
- });
309
- });
310
- });
@@ -1,71 +0,0 @@
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 "discovery"
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 "stable"
25
- Then item "Item 2" has mode "stable"
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
- | discovery |
51
- | stable |
52
- | production |
53
-
54
- # Mode persistence
55
- Scenario: Mode change persists across work start/stop
56
- Given I create a feature "Test Feature" with mode "speed"
57
- And I start work on the feature
58
- When I set mode for current item to "production"
59
- And I stop work
60
- And I start work on the feature
61
- Then CLAUDE.md mode is set to "production"
62
-
63
- # Multiple mode changes
64
- Scenario: Change mode multiple times
65
- Given I create a feature "Test Feature" with mode "speed"
66
- And I start work on the feature
67
- When I set mode for current item to "discovery"
68
- And I set mode for current item to "stable"
69
- And I set mode for current item to "production"
70
- Then the work item has mode "production"
71
- And CLAUDE.md mode is set to "production"
@@ -1,88 +0,0 @@
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 bug in stable mode
17
- Given I create a bug "Stable Bug" with mode "stable"
18
- When I start work on the bug
19
- Then CLAUDE.md mode is set to "stable"
20
-
21
- Scenario: Start work on chore inherits parent feature mode
22
- Given I create a feature "Discovery Feature" with mode "discovery"
23
- And I create a chore "Child Chore" without mode and parent feature
24
- When I start work on the chore
25
- Then CLAUDE.md mode is set to "discovery"
26
-
27
- Scenario: Start work on feature in production mode
28
- Given I create a feature "Production Feature" with mode "production"
29
- When I start work on the feature
30
- Then CLAUDE.md mode is set to "production"
31
-
32
- # Mode switching between work items
33
- Scenario: Switch from speed mode item to stable mode item
34
- Given I create a feature "Speed Feature" with mode "speed"
35
- And I create a bug "Stable Bug" with mode "stable"
36
- And I start work on the feature
37
- And CLAUDE.md mode is set to "speed"
38
- When I stop work
39
- And I start work on the bug
40
- Then CLAUDE.md mode is set to "stable"
41
-
42
- Scenario: Start work updates mode even if item already in progress
43
- Given I create a feature "Test Feature" with mode "discovery"
44
- And the feature status is "in_progress"
45
- And CLAUDE.md has mode "speed"
46
- When I start work on the feature
47
- Then CLAUDE.md mode is set to "discovery"
48
-
49
- # Epic handling - epics don't have modes
50
- Scenario: Start work on epic (NULL mode)
51
- Given I create an epic "Test Epic" without mode
52
- When I start work on the epic
53
- Then CLAUDE.md has no mode line
54
- And the current work section exists
55
-
56
- # Default mode from work item creation
57
- Scenario: Start work on feature with default discovery mode
58
- Given I create a feature "Default Feature" without mode
59
- And the work item has mode "discovery"
60
- When I start work on the feature
61
- Then CLAUDE.md mode is set to "discovery"
62
-
63
- # Hierarchical structure
64
- Scenario: Start work on child features use their own mode, not parent's
65
- Given I create an epic "Test Epic" without mode
66
- And I create a feature "Speed Feature" with mode "speed" and parent epic
67
- And I create a feature "Stable Feature" with mode "stable" and parent epic
68
- When I start work on the speed feature
69
- Then CLAUDE.md mode is set to "speed"
70
- When I stop work
71
- And I start work on the stable feature
72
- Then CLAUDE.md mode is set to "stable"
73
-
74
- # Mode persistence
75
- Scenario: Work item mode persists in database after start
76
- Given I create a feature "Test Feature" with mode "stable"
77
- When I start work on the feature
78
- And I stop work
79
- Then the work item still has mode "stable"
80
-
81
- # Edge cases
82
- Scenario: Starting work multiple times preserves mode
83
- Given I create a feature "Test Feature" with mode "production"
84
- When I start work on the feature
85
- And I stop work
86
- And I start work on the feature
87
- Then CLAUDE.md mode is set to "production"
88
- And the work item still has mode "production"
package/full-test.txt DELETED
File without changes
@@ -1,177 +0,0 @@
1
- const {
2
- BUG_WORKFLOW_STEPS,
3
- BUG_WORKFLOW_TECHNIQUES,
4
- BUG_WORKFLOW_RED_FLAGS,
5
- getBugWorkflowForClaudeMd,
6
- getBugWorkflowForTerminal
7
- } = require('./bug-workflow');
8
-
9
- describe('Bug Workflow Module', () => {
10
- describe('Constants', () => {
11
- test('BUG_WORKFLOW_STEPS contains all 6 steps', () => {
12
- expect(BUG_WORKFLOW_STEPS).toContain('1. REPRODUCE');
13
- expect(BUG_WORKFLOW_STEPS).toContain('2. INVESTIGATE');
14
- expect(BUG_WORKFLOW_STEPS).toContain('3. ISOLATE');
15
- expect(BUG_WORKFLOW_STEPS).toContain('4. FIX');
16
- expect(BUG_WORKFLOW_STEPS).toContain('5. VERIFY');
17
- expect(BUG_WORKFLOW_STEPS).toContain('6. COMMIT');
18
- });
19
-
20
- test('BUG_WORKFLOW_STEPS contains critical checklist items', () => {
21
- // REPRODUCE checklist
22
- expect(BUG_WORKFLOW_STEPS).toContain('Create minimal reproduction case');
23
- expect(BUG_WORKFLOW_STEPS).toContain('Write down exact steps to trigger');
24
-
25
- // INVESTIGATE checklist
26
- expect(BUG_WORKFLOW_STEPS).toContain('Read error messages/stack traces completely');
27
- expect(BUG_WORKFLOW_STEPS).toContain('Look for recent changes (git log/blame)');
28
-
29
- // ISOLATE checklist
30
- expect(BUG_WORKFLOW_STEPS).toContain('Identify root cause, not just symptoms');
31
- expect(BUG_WORKFLOW_STEPS).toContain('Understand why the bug occurs');
32
-
33
- // FIX checklist
34
- expect(BUG_WORKFLOW_STEPS).toContain('Make the minimal change that fixes root cause');
35
- expect(BUG_WORKFLOW_STEPS).toContain('Avoid "while I\'m here" refactoring');
36
-
37
- // VERIFY checklist
38
- expect(BUG_WORKFLOW_STEPS).toContain('Add regression test for this specific bug');
39
- expect(BUG_WORKFLOW_STEPS).toContain('Run existing tests - ensure nothing broke');
40
-
41
- // COMMIT checklist
42
- expect(BUG_WORKFLOW_STEPS).toContain('Clear commit message: "fix: [brief description]"');
43
- expect(BUG_WORKFLOW_STEPS).toContain('Reference issue number if applicable');
44
- });
45
-
46
- test('BUG_WORKFLOW_TECHNIQUES contains debugging tips', () => {
47
- expect(BUG_WORKFLOW_TECHNIQUES).toContain('DEBUGGING TECHNIQUES:');
48
- expect(BUG_WORKFLOW_TECHNIQUES).toContain('git bisect');
49
- expect(BUG_WORKFLOW_TECHNIQUES).toContain('Rubber duck');
50
- expect(BUG_WORKFLOW_TECHNIQUES).toContain('Take breaks');
51
- });
52
-
53
- test('BUG_WORKFLOW_RED_FLAGS contains anti-patterns', () => {
54
- expect(BUG_WORKFLOW_RED_FLAGS).toContain('RED FLAGS:');
55
- expect(BUG_WORKFLOW_RED_FLAGS).toContain('"It works on my machine"');
56
- expect(BUG_WORKFLOW_RED_FLAGS).toContain('Fixing symptoms without understanding cause');
57
- expect(BUG_WORKFLOW_RED_FLAGS).toContain('Adding try/catch to hide errors');
58
- expect(BUG_WORKFLOW_RED_FLAGS).toContain('Skipping reproduction');
59
- });
60
- });
61
-
62
- describe('getBugWorkflowForClaudeMd()', () => {
63
- test('returns string with all workflow sections', () => {
64
- const result = getBugWorkflowForClaudeMd();
65
-
66
- expect(typeof result).toBe('string');
67
- expect(result).toContain('SYSTEMATIC BUG FIXING WORKFLOW:');
68
- expect(result).toContain(BUG_WORKFLOW_STEPS);
69
- expect(result).toContain(BUG_WORKFLOW_TECHNIQUES);
70
- expect(result).toContain(BUG_WORKFLOW_RED_FLAGS);
71
- });
72
-
73
- test('does not contain terminal formatting characters', () => {
74
- const result = getBugWorkflowForClaudeMd();
75
-
76
- // Should not have Unicode box-drawing characters
77
- expect(result).not.toContain('━');
78
- // Should not have emojis
79
- expect(result).not.toContain('🐛');
80
- });
81
-
82
- test('has plain text header for markdown compatibility', () => {
83
- const result = getBugWorkflowForClaudeMd();
84
-
85
- expect(result).toContain('SYSTEMATIC BUG FIXING WORKFLOW:');
86
- });
87
- });
88
-
89
- describe('getBugWorkflowForTerminal()', () => {
90
- test('returns string with all workflow sections', () => {
91
- const result = getBugWorkflowForTerminal();
92
-
93
- expect(typeof result).toBe('string');
94
- expect(result).toContain(BUG_WORKFLOW_STEPS);
95
- expect(result).toContain(BUG_WORKFLOW_TECHNIQUES);
96
- expect(result).toContain(BUG_WORKFLOW_RED_FLAGS);
97
- });
98
-
99
- test('contains terminal formatting characters', () => {
100
- const result = getBugWorkflowForTerminal();
101
-
102
- // Should have Unicode box-drawing characters for borders
103
- expect(result).toContain('━');
104
- // Should have bug emoji
105
- expect(result).toContain('🐛');
106
- });
107
-
108
- test('has formatted header with emoji', () => {
109
- const result = getBugWorkflowForTerminal();
110
-
111
- expect(result).toContain('🐛 BUG FIXING WORKFLOW');
112
- });
113
-
114
- test('has top and bottom borders', () => {
115
- const result = getBugWorkflowForTerminal();
116
-
117
- // Count border lines
118
- const borderCount = (result.match(/━━━━━━━/g) || []).length;
119
- expect(borderCount).toBeGreaterThanOrEqual(2); // Top and bottom borders
120
- });
121
- });
122
-
123
- describe('Content Consistency', () => {
124
- test('both formats contain the same workflow steps', () => {
125
- const claudeMd = getBugWorkflowForClaudeMd();
126
- const terminal = getBugWorkflowForTerminal();
127
-
128
- // Both should contain the exact same steps content
129
- expect(claudeMd).toContain(BUG_WORKFLOW_STEPS);
130
- expect(terminal).toContain(BUG_WORKFLOW_STEPS);
131
- });
132
-
133
- test('both formats contain the same techniques', () => {
134
- const claudeMd = getBugWorkflowForClaudeMd();
135
- const terminal = getBugWorkflowForTerminal();
136
-
137
- expect(claudeMd).toContain(BUG_WORKFLOW_TECHNIQUES);
138
- expect(terminal).toContain(BUG_WORKFLOW_TECHNIQUES);
139
- });
140
-
141
- test('both formats contain the same red flags', () => {
142
- const claudeMd = getBugWorkflowForClaudeMd();
143
- const terminal = getBugWorkflowForTerminal();
144
-
145
- expect(claudeMd).toContain(BUG_WORKFLOW_RED_FLAGS);
146
- expect(terminal).toContain(BUG_WORKFLOW_RED_FLAGS);
147
- });
148
- });
149
-
150
- describe('Edge Cases', () => {
151
- test('functions return non-empty strings', () => {
152
- expect(getBugWorkflowForClaudeMd().length).toBeGreaterThan(0);
153
- expect(getBugWorkflowForTerminal().length).toBeGreaterThan(0);
154
- });
155
-
156
- test('functions are deterministic (same output on multiple calls)', () => {
157
- const claudeMd1 = getBugWorkflowForClaudeMd();
158
- const claudeMd2 = getBugWorkflowForClaudeMd();
159
- expect(claudeMd1).toBe(claudeMd2);
160
-
161
- const terminal1 = getBugWorkflowForTerminal();
162
- const terminal2 = getBugWorkflowForTerminal();
163
- expect(terminal1).toBe(terminal2);
164
- });
165
-
166
- test('constants are immutable strings', () => {
167
- expect(typeof BUG_WORKFLOW_STEPS).toBe('string');
168
- expect(typeof BUG_WORKFLOW_TECHNIQUES).toBe('string');
169
- expect(typeof BUG_WORKFLOW_RED_FLAGS).toBe('string');
170
-
171
- // Verify they're not empty
172
- expect(BUG_WORKFLOW_STEPS.length).toBeGreaterThan(0);
173
- expect(BUG_WORKFLOW_TECHNIQUES.length).toBeGreaterThan(0);
174
- expect(BUG_WORKFLOW_RED_FLAGS.length).toBeGreaterThan(0);
175
- });
176
- });
177
- });