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,351 +0,0 @@
1
- const sqlite3 = require('sqlite3').verbose();
2
- const migration = require('./002-default-work-item-modes');
3
-
4
- describe('Migration: 002-default-work-item-modes', () => {
5
- let db;
6
-
7
- beforeEach((done) => {
8
- // Create in-memory database for each test
9
- db = new sqlite3.Database(':memory:', (err) => {
10
- if (err) return done(err);
11
-
12
- // Create work_items table with schema
13
- db.run(`
14
- CREATE TABLE work_items (
15
- id INTEGER PRIMARY KEY AUTOINCREMENT,
16
- type TEXT NOT NULL,
17
- title TEXT NOT NULL,
18
- description TEXT,
19
- status TEXT DEFAULT 'backlog',
20
- parent_id INTEGER,
21
- epic_id INTEGER,
22
- branch_name TEXT,
23
- file_paths TEXT,
24
- commit_sha TEXT,
25
- mode TEXT,
26
- current INTEGER DEFAULT 0,
27
- created_at DATETIME DEFAULT CURRENT_TIMESTAMP
28
- )
29
- `, done);
30
- });
31
- });
32
-
33
- afterEach((done) => {
34
- db.close(done);
35
- });
36
-
37
- describe('metadata', () => {
38
- it('has correct migration id', () => {
39
- expect(migration.id).toBe('002-default-work-item-modes');
40
- });
41
-
42
- it('has description', () => {
43
- expect(migration.description).toBeDefined();
44
- expect(typeof migration.description).toBe('string');
45
- expect(migration.description.length).toBeGreaterThan(0);
46
- expect(migration.description).toContain('epics');
47
- });
48
-
49
- it('has up function', () => {
50
- expect(typeof migration.up).toBe('function');
51
- });
52
- });
53
-
54
- describe('up()', () => {
55
- it('sets mode to stable for features/bugs/chores with NULL mode', async () => {
56
- // Insert work items without mode
57
- await new Promise((resolve, reject) => {
58
- db.run(
59
- `INSERT INTO work_items (type, title, mode) VALUES
60
- ('feature', 'Test Feature', NULL),
61
- ('bug', 'Test Bug', NULL),
62
- ('chore', 'Test Chore', NULL)`,
63
- (err) => err ? reject(err) : resolve()
64
- );
65
- });
66
-
67
- // Run migration
68
- await migration.up(db);
69
-
70
- // Verify all items have mode set
71
- const items = await new Promise((resolve, reject) => {
72
- db.all('SELECT id, type, title, mode FROM work_items ORDER BY id', [], (err, rows) => {
73
- err ? reject(err) : resolve(rows);
74
- });
75
- });
76
-
77
- expect(items).toHaveLength(3);
78
- expect(items[0].mode).toBe('stable');
79
- expect(items[1].mode).toBe('stable');
80
- expect(items[2].mode).toBe('stable');
81
- });
82
-
83
- it('sets epic modes to NULL', async () => {
84
- // Insert epics with and without modes
85
- await new Promise((resolve, reject) => {
86
- db.run(
87
- `INSERT INTO work_items (type, title, mode) VALUES
88
- ('epic', 'Epic with mode', 'speed'),
89
- ('epic', 'Epic without mode', NULL)`,
90
- (err) => err ? reject(err) : resolve()
91
- );
92
- });
93
-
94
- // Run migration
95
- await migration.up(db);
96
-
97
- // Verify all epics have NULL mode
98
- const items = await new Promise((resolve, reject) => {
99
- db.all('SELECT id, title, mode FROM work_items WHERE type = "epic"', [], (err, rows) => {
100
- err ? reject(err) : resolve(rows);
101
- });
102
- });
103
-
104
- expect(items).toHaveLength(2);
105
- expect(items[0].mode).toBe(null);
106
- expect(items[1].mode).toBe(null);
107
- });
108
-
109
- it('does not change existing mode values for non-epics', async () => {
110
- // Insert work items with various modes
111
- await new Promise((resolve, reject) => {
112
- db.run(
113
- `INSERT INTO work_items (type, title, mode) VALUES
114
- ('feature', 'Speed Feature', 'speed'),
115
- ('bug', 'Discovery Bug', 'discovery'),
116
- ('chore', 'Production Chore', 'production'),
117
- ('feature', 'Stable Feature', 'stable')`,
118
- (err) => err ? reject(err) : resolve()
119
- );
120
- });
121
-
122
- // Run migration
123
- await migration.up(db);
124
-
125
- // Verify modes unchanged
126
- const items = await new Promise((resolve, reject) => {
127
- db.all('SELECT id, type, title, mode FROM work_items ORDER BY id', [], (err, rows) => {
128
- err ? reject(err) : resolve(rows);
129
- });
130
- });
131
-
132
- expect(items).toHaveLength(4);
133
- expect(items[0].mode).toBe('speed');
134
- expect(items[1].mode).toBe('discovery');
135
- expect(items[2].mode).toBe('production');
136
- expect(items[3].mode).toBe('stable');
137
- });
138
-
139
- it('handles mixed NULL and non-NULL modes', async () => {
140
- // Insert mix of items
141
- await new Promise((resolve, reject) => {
142
- db.run(
143
- `INSERT INTO work_items (type, title, mode) VALUES
144
- ('feature', 'Has Speed', 'speed'),
145
- ('feature', 'No Mode', NULL),
146
- ('feature', 'Has Discovery', 'discovery'),
147
- ('feature', 'Also No Mode', NULL)`,
148
- (err) => err ? reject(err) : resolve()
149
- );
150
- });
151
-
152
- // Run migration
153
- await migration.up(db);
154
-
155
- // Verify selective update
156
- const items = await new Promise((resolve, reject) => {
157
- db.all('SELECT id, title, mode FROM work_items ORDER BY id', [], (err, rows) => {
158
- err ? reject(err) : resolve(rows);
159
- });
160
- });
161
-
162
- expect(items).toHaveLength(4);
163
- expect(items[0].mode).toBe('speed'); // Unchanged
164
- expect(items[1].mode).toBe('stable'); // Changed from NULL
165
- expect(items[2].mode).toBe('discovery'); // Unchanged
166
- expect(items[3].mode).toBe('stable'); // Changed from NULL
167
- });
168
-
169
- it('is idempotent - can run multiple times safely', async () => {
170
- // Insert items without mode
171
- await new Promise((resolve, reject) => {
172
- db.run(
173
- `INSERT INTO work_items (type, title, mode) VALUES
174
- ('feature', 'Test', NULL)`,
175
- (err) => err ? reject(err) : resolve()
176
- );
177
- });
178
-
179
- // Run migration first time
180
- await migration.up(db);
181
-
182
- const firstRun = await new Promise((resolve, reject) => {
183
- db.all('SELECT mode FROM work_items', [], (err, rows) => {
184
- err ? reject(err) : resolve(rows);
185
- });
186
- });
187
-
188
- expect(firstRun[0].mode).toBe('stable');
189
-
190
- // Run migration second time
191
- await migration.up(db);
192
-
193
- const secondRun = await new Promise((resolve, reject) => {
194
- db.all('SELECT mode FROM work_items', [], (err, rows) => {
195
- err ? reject(err) : resolve(rows);
196
- });
197
- });
198
-
199
- expect(secondRun[0].mode).toBe('stable');
200
- expect(firstRun).toEqual(secondRun);
201
- });
202
-
203
- it('handles empty work_items table', async () => {
204
- // Don't insert any items
205
-
206
- // Run migration - should not fail
207
- await expect(migration.up(db)).resolves.not.toThrow();
208
-
209
- // Verify table still empty
210
- const items = await new Promise((resolve, reject) => {
211
- db.all('SELECT * FROM work_items', [], (err, rows) => {
212
- err ? reject(err) : resolve(rows);
213
- });
214
- });
215
-
216
- expect(items).toHaveLength(0);
217
- });
218
-
219
- it('handles all item types (epic, feature, bug, chore) correctly', async () => {
220
- // Insert one of each type without mode
221
- await new Promise((resolve, reject) => {
222
- db.run(
223
- `INSERT INTO work_items (type, title, mode) VALUES
224
- ('epic', 'Test Epic', NULL),
225
- ('feature', 'Test Feature', NULL),
226
- ('bug', 'Test Bug', NULL),
227
- ('chore', 'Test Chore', NULL)`,
228
- (err) => err ? reject(err) : resolve()
229
- );
230
- });
231
-
232
- // Run migration
233
- await migration.up(db);
234
-
235
- // Verify correct modes
236
- const items = await new Promise((resolve, reject) => {
237
- db.all('SELECT type, mode FROM work_items ORDER BY id', [], (err, rows) => {
238
- err ? reject(err) : resolve(rows);
239
- });
240
- });
241
-
242
- expect(items).toHaveLength(4);
243
- expect(items[0].mode).toBe(null); // epic
244
- expect(items[1].mode).toBe('stable'); // feature
245
- expect(items[2].mode).toBe('stable'); // bug
246
- expect(items[3].mode).toBe('stable'); // chore
247
- });
248
-
249
- it('preserves other column values during update', async () => {
250
- // Insert item with various fields populated
251
- await new Promise((resolve, reject) => {
252
- db.run(
253
- `INSERT INTO work_items
254
- (type, title, description, status, parent_id, branch_name, current, mode)
255
- VALUES
256
- ('feature', 'Rich Item', 'A detailed description', 'in_progress', 5, 'feature/test', 1, NULL)`,
257
- (err) => err ? reject(err) : resolve()
258
- );
259
- });
260
-
261
- // Run migration
262
- await migration.up(db);
263
-
264
- // Verify only mode changed
265
- const item = await new Promise((resolve, reject) => {
266
- db.get('SELECT * FROM work_items WHERE id = 1', [], (err, row) => {
267
- err ? reject(err) : resolve(row);
268
- });
269
- });
270
-
271
- expect(item.type).toBe('feature');
272
- expect(item.title).toBe('Rich Item');
273
- expect(item.description).toBe('A detailed description');
274
- expect(item.status).toBe('in_progress');
275
- expect(item.parent_id).toBe(5);
276
- expect(item.branch_name).toBe('feature/test');
277
- expect(item.current).toBe(1);
278
- expect(item.mode).toBe('stable'); // Only this changed
279
- });
280
-
281
- it('returns a Promise', () => {
282
- const result = migration.up(db);
283
- expect(result).toBeInstanceOf(Promise);
284
- });
285
-
286
- it('resolves Promise on success', async () => {
287
- await new Promise((resolve, reject) => {
288
- db.run(
289
- `INSERT INTO work_items (type, title, mode) VALUES ('feature', 'Test', NULL)`,
290
- (err) => err ? reject(err) : resolve()
291
- );
292
- });
293
-
294
- await expect(migration.up(db)).resolves.toBeUndefined();
295
- });
296
- });
297
-
298
- describe('edge cases', () => {
299
- it('handles work items created at exactly the same time', async () => {
300
- const timestamp = '2024-10-18 12:00:00';
301
-
302
- await new Promise((resolve, reject) => {
303
- db.run(
304
- `INSERT INTO work_items (type, title, mode, created_at) VALUES
305
- ('feature', 'Item 1', NULL, ?),
306
- ('feature', 'Item 2', NULL, ?)`,
307
- [timestamp, timestamp],
308
- (err) => err ? reject(err) : resolve()
309
- );
310
- });
311
-
312
- await migration.up(db);
313
-
314
- const items = await new Promise((resolve, reject) => {
315
- db.all('SELECT mode FROM work_items', [], (err, rows) => {
316
- err ? reject(err) : resolve(rows);
317
- });
318
- });
319
-
320
- expect(items).toHaveLength(2);
321
- expect(items[0].mode).toBe('stable');
322
- expect(items[1].mode).toBe('stable');
323
- });
324
-
325
- it('handles work items with parent_id hierarchy', async () => {
326
- // Epic with children, none have mode
327
- await new Promise((resolve, reject) => {
328
- db.run(
329
- `INSERT INTO work_items (id, type, title, parent_id, mode) VALUES
330
- (1, 'epic', 'Epic', NULL, NULL),
331
- (2, 'feature', 'Child 1', 1, NULL),
332
- (3, 'bug', 'Child 2', 1, NULL)`,
333
- (err) => err ? reject(err) : resolve()
334
- );
335
- });
336
-
337
- await migration.up(db);
338
-
339
- const items = await new Promise((resolve, reject) => {
340
- db.all('SELECT id, type, title, mode FROM work_items ORDER BY id', [], (err, rows) => {
341
- err ? reject(err) : resolve(rows);
342
- });
343
- });
344
-
345
- expect(items).toHaveLength(3);
346
- expect(items[0].mode).toBe(null); // Epic (container, no mode)
347
- expect(items[1].mode).toBe('stable'); // Child feature
348
- expect(items[2].mode).toBe('stable'); // Child bug
349
- });
350
- });
351
- });