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,9 +0,0 @@
1
- const { After, AfterAll, setDefaultTimeout } = require('@cucumber/cucumber');
2
-
3
- // Set default timeout to 10 seconds for all steps
4
- setDefaultTimeout(10000);
5
-
6
- // Note: We don't close the database in AfterAll because SQLite3 has issues
7
- // with active prepared statements during cleanup. Node.js will handle cleanup
8
- // on process exit. Attempting to close the database here causes FATAL errors
9
- // in SQLite's native code during Statement::~Statement() destructor.
@@ -1,39 +0,0 @@
1
- // Terminal Logo - Unicode Box Drawing + Gradients
2
- // Zero dependencies, pure ANSI escape codes
3
-
4
- const colors = {
5
- cyan1: '\x1b[38;5;51m', // Bright cyan
6
- cyan2: '\x1b[38;5;45m', // Medium cyan
7
- cyan3: '\x1b[38;5;39m', // Darker cyan
8
- green1: '\x1b[38;5;48m', // Bright green
9
- green2: '\x1b[38;5;42m', // Medium green
10
- green3: '\x1b[38;5;36m', // Darker green
11
- gray: '\x1b[38;5;244m', // Gray for subtitle
12
- reset: '\x1b[0m', // Reset color
13
- bold: '\x1b[1m' // Bold text
14
- };
15
-
16
- function showLogo() {
17
- console.log(`
18
- ${colors.cyan1} ██╗${colors.cyan2}███████╗${colors.cyan3}████████╗${colors.green1}████████╗${colors.green2}██╗ ██╗${colors.reset}
19
- ${colors.cyan1} ██║${colors.cyan2}██╔════╝${colors.cyan3}╚══██╔══╝${colors.green1}╚══██╔══╝${colors.green2}╚██╗ ██╔╝${colors.reset}
20
- ${colors.cyan1} ██║${colors.cyan2}█████╗ ${colors.cyan3} ██║ ${colors.green1} ██║ ${colors.green2} ╚████╔╝ ${colors.reset}
21
- ${colors.cyan1}██ ██║${colors.cyan2}██╔══╝ ${colors.cyan3} ██║ ${colors.green1} ██║ ${colors.green2} ╚██╔╝ ${colors.reset}
22
- ${colors.cyan1}╚█████╔╝${colors.cyan2}███████╗${colors.cyan3} ██║ ${colors.green1} ██║ ${colors.green2} ██║ ${colors.reset}
23
- ${colors.cyan1} ╚════╝ ${colors.cyan2}╚══════╝${colors.cyan3} ╚═╝ ${colors.green1} ╚═╝ ${colors.green2} ╚═╝ ${colors.reset}
24
-
25
- ${colors.green1}██████╗ ${colors.green2}██████╗ ${colors.green3}██████╗ ${colors.reset}
26
- ${colors.green1}██╔══██╗${colors.green2}██╔═══██╗${colors.green3}██╔══██╗${colors.reset}
27
- ${colors.green1}██████╔╝${colors.green2}██║ ██║${colors.green3}██║ ██║${colors.reset}
28
- ${colors.green1}██╔═══╝ ${colors.green2}██║ ██║${colors.green3}██║ ██║${colors.reset}
29
- ${colors.green1}██║ ${colors.green2}╚██████╔╝${colors.green3}██████╔╝${colors.reset}
30
- ${colors.green1}╚═╝ ${colors.green2} ╚═════╝ ${colors.green3}╚═════╝ ${colors.reset}
31
- `);
32
-
33
- const pkg = require('../../package.json');
34
- const version = pkg.version || '3.0.0';
35
- console.log(colors.gray + ' AI Development Context Manager ' + colors.bold + 'v' + version + colors.reset);
36
- console.log();
37
- }
38
-
39
- module.exports = { showLogo };
@@ -1,30 +0,0 @@
1
- Feature: Terminal Logo Display
2
- As a JettyPod user
3
- I want to see a welcoming logo when I run jettypod init
4
- So that the tool feels approachable and modern
5
-
6
- Scenario: jettypod init displays unicode gradient logo
7
- Given a new empty directory
8
- When I run jettypod init
9
- Then the output contains the unicode gradient logo
10
- And the logo includes "DEV" and "POD" text
11
- And the logo uses ANSI color codes
12
-
13
- Scenario: Logo module exports showLogo function
14
- Given the logo module exists
15
- When I import it
16
- Then it exports a "showLogo" function
17
-
18
- Scenario: Logo output is properly formatted
19
- When I call the showLogo function
20
- Then it outputs 6 lines of logo art
21
- And it includes the version subtitle
22
-
23
- # Integration test
24
- Scenario: jettypod init integrates with existing features
25
- Given a new empty directory
26
- When I run jettypod init
27
- Then I see the unicode logo
28
- And the .jettypod directory is created
29
- And CLAUDE.md is created
30
- And git hooks are installed
@@ -1,181 +0,0 @@
1
- const { execSync } = require('child_process');
2
- const https = require('https');
3
- const packageJson = require('../../package.json');
4
-
5
- /**
6
- * Get current jettypod version from package.json
7
- * @returns {string} Current version
8
- */
9
- function getCurrentVersion() {
10
- return packageJson.version;
11
- }
12
-
13
- /**
14
- * Check npm registry for latest version
15
- * @returns {Promise<string>} Latest version from npm
16
- */
17
- function getLatestVersion() {
18
- return new Promise((resolve, reject) => {
19
- const packageName = packageJson.name;
20
- const url = `https://registry.npmjs.org/${packageName}/latest`;
21
-
22
- const request = https.get(url, (res) => {
23
- let data = '';
24
-
25
- if (res.statusCode !== 200) {
26
- reject(new Error(`HTTP ${res.statusCode}`));
27
- return;
28
- }
29
-
30
- res.on('data', (chunk) => {
31
- data += chunk;
32
- });
33
-
34
- res.on('end', () => {
35
- try {
36
- const json = JSON.parse(data);
37
- if (!json.version) {
38
- reject(new Error('No version found in npm response'));
39
- return;
40
- }
41
- resolve(json.version);
42
- } catch (err) {
43
- reject(new Error(`Invalid JSON response: ${err.message}`));
44
- }
45
- });
46
- });
47
-
48
- // Set timeout for network request (30 seconds)
49
- request.setTimeout(30000, () => {
50
- request.destroy();
51
- reject(new Error('Request timeout - network too slow'));
52
- });
53
-
54
- request.on('error', (err) => {
55
- // Provide specific error messages for common network errors
56
- if (err.code === 'ENOTFOUND') {
57
- reject(new Error('network error - DNS lookup failed (check internet connection)'));
58
- } else if (err.code === 'ETIMEDOUT' || err.code === 'ESOCKETTIMEDOUT') {
59
- reject(new Error('network error - connection timeout'));
60
- } else if (err.code === 'ECONNREFUSED') {
61
- reject(new Error('network error - connection refused'));
62
- } else if (err.code === 'ECONNRESET') {
63
- reject(new Error('network error - connection reset'));
64
- } else {
65
- reject(err);
66
- }
67
- });
68
- });
69
- }
70
-
71
- /**
72
- * Update jettypod to latest version using npm
73
- * @param {string} version - Version to update to (default: latest)
74
- * @returns {boolean} True if update succeeded
75
- */
76
- function updateJettyPod(version = 'latest') {
77
- try {
78
- console.log(`📦 Installing jettypod@${version}...`);
79
-
80
- // Use npm to update globally
81
- const packageName = packageJson.name;
82
- execSync(`npm install -g ${packageName}@${version}`, {
83
- stdio: 'inherit'
84
- });
85
-
86
- return true;
87
- } catch (err) {
88
- console.log('');
89
- console.error(`❌ Update failed`);
90
- console.log('');
91
-
92
- // Provide specific error messages for common failures
93
- const errorOutput = err.stderr ? err.stderr.toString() : '';
94
-
95
- if (err.message.includes('EACCES') || err.message.includes('EPERM') ||
96
- errorOutput.includes('EACCES') || errorOutput.includes('EPERM')) {
97
- console.error('Permission denied - try running with sudo:');
98
- console.log(` sudo npm install -g ${packageName}@${version}`);
99
- console.log('');
100
- console.error('Or configure npm to use a different directory:');
101
- console.log(' mkdir ~/.npm-global');
102
- console.log(' npm config set prefix ~/.npm-global');
103
- console.log(' export PATH=~/.npm-global/bin:$PATH');
104
- } else if (errorOutput.includes('ENOSPC')) {
105
- console.error('Not enough disk space to install update');
106
- console.log('Free up disk space and try again');
107
- } else if (errorOutput.includes('404') || errorOutput.includes('E404')) {
108
- console.error(`Version ${version} not found in npm registry`);
109
- } else if (errorOutput.includes('network') || errorOutput.includes('ETIMEDOUT') ||
110
- errorOutput.includes('ENOTFOUND')) {
111
- console.error('Network error during npm install');
112
- console.log('Check your internet connection and try again');
113
- } else {
114
- console.error(`Error details: ${err.message}`);
115
- }
116
-
117
- console.log('');
118
- console.error('Manual update:');
119
- console.log(` npm install -g ${packageName}@${version}`);
120
-
121
- return false;
122
- }
123
- }
124
-
125
- /**
126
- * Run the update command
127
- * @param {Object} options - Optional dependencies for testing
128
- * @param {Function} options.getCurrentVersion - Function to get current version
129
- * @param {Function} options.getLatestVersion - Function to get latest version
130
- * @param {Function} options.updateJettyPod - Function to update jettypod
131
- */
132
- async function runUpdate(options = {}) {
133
- const _getCurrentVersion = options.getCurrentVersion || getCurrentVersion;
134
- const _getLatestVersion = options.getLatestVersion || getLatestVersion;
135
- const _updateJettyPod = options.updateJettyPod || updateJettyPod;
136
-
137
- console.log('🔍 Checking for updates...');
138
-
139
- const currentVersion = _getCurrentVersion();
140
- console.log(`Current version: ${currentVersion}`);
141
-
142
- let latestVersion;
143
- try {
144
- latestVersion = await _getLatestVersion();
145
- } catch (err) {
146
- console.log(`Cannot check for updates: ${err.message}`);
147
- console.log('');
148
- console.log('You can still manually update with:');
149
- console.log(` npm install -g ${packageJson.name}@latest`);
150
- return false;
151
- }
152
-
153
- console.log(`Latest version: ${latestVersion}`);
154
- console.log('');
155
-
156
- if (currentVersion === latestVersion) {
157
- console.log(`Already on latest version: ${latestVersion}`);
158
- return true;
159
- }
160
-
161
- console.log(`New version available: ${latestVersion} (current: ${currentVersion})`);
162
- console.log('');
163
-
164
- const success = _updateJettyPod(latestVersion);
165
-
166
- if (success) {
167
- console.log('');
168
- console.log(`✅ JettyPod updated to ${latestVersion}`);
169
- console.log('');
170
- return true;
171
- }
172
-
173
- return false;
174
- }
175
-
176
- module.exports = {
177
- runUpdate,
178
- getCurrentVersion,
179
- getLatestVersion,
180
- updateJettyPod
181
- };
@@ -1,225 +0,0 @@
1
- const updateCommand = require('./index');
2
- const packageJson = require('../../package.json');
3
-
4
- /**
5
- * End-to-end tests for update command functionality
6
- * Tests the BDD scenarios from features/jettypod-update-command.feature
7
- */
8
- describe('Update Command', () => {
9
- describe('getCurrentVersion()', () => {
10
- test('should return version from package.json', () => {
11
- const version = updateCommand.getCurrentVersion();
12
- expect(version).toBe(packageJson.version);
13
- expect(typeof version).toBe('string');
14
- expect(version).toMatch(/^\d+\.\d+\.\d+/);
15
- });
16
- });
17
-
18
- describe('getLatestVersion()', () => {
19
- test('should fetch latest version from npm registry (integration test - may fail if not published)', async () => {
20
- try {
21
- const version = await updateCommand.getLatestVersion();
22
-
23
- expect(typeof version).toBe('string');
24
- expect(version).toMatch(/^\d+\.\d+\.\d+/);
25
- } catch (err) {
26
- // Package may not be published to npm - skip this test
27
- if (err.message.includes('HTTP 404')) {
28
- console.log('Skipping: Package not published to npm registry');
29
- return;
30
- }
31
- throw err;
32
- }
33
- }, 30000); // 30 second timeout for network request
34
-
35
- test('should handle network errors gracefully', async () => {
36
- // Mock https module to simulate network error
37
- const https = require('https');
38
- const originalGet = https.get;
39
-
40
- https.get = jest.fn((url, callback) => {
41
- const mockRequest = {
42
- on: jest.fn((event, handler) => {
43
- if (event === 'error') {
44
- handler({ code: 'ENOTFOUND' });
45
- }
46
- return mockRequest;
47
- }),
48
- setTimeout: jest.fn(),
49
- destroy: jest.fn()
50
- };
51
- return mockRequest;
52
- });
53
-
54
- await expect(updateCommand.getLatestVersion()).rejects.toThrow('network error');
55
-
56
- // Restore original
57
- https.get = originalGet;
58
- });
59
-
60
- test('should handle timeout errors', async () => {
61
- const https = require('https');
62
- const originalGet = https.get;
63
-
64
- https.get = jest.fn((url, callback) => {
65
- const mockRequest = {
66
- on: jest.fn((event, handler) => mockRequest),
67
- setTimeout: jest.fn((timeout, handler) => {
68
- // Immediately trigger timeout
69
- handler();
70
- return mockRequest;
71
- }),
72
- destroy: jest.fn()
73
- };
74
- return mockRequest;
75
- });
76
-
77
- await expect(updateCommand.getLatestVersion()).rejects.toThrow('timeout');
78
-
79
- https.get = originalGet;
80
- });
81
-
82
- test('should handle invalid JSON response', async () => {
83
- const https = require('https');
84
- const originalGet = https.get;
85
-
86
- https.get = jest.fn((url, callback) => {
87
- const mockResponse = {
88
- statusCode: 200,
89
- on: jest.fn((event, handler) => {
90
- if (event === 'data') {
91
- handler('invalid json');
92
- } else if (event === 'end') {
93
- handler();
94
- }
95
- return mockResponse;
96
- })
97
- };
98
-
99
- callback(mockResponse);
100
-
101
- return {
102
- on: jest.fn((event, handler) => ({
103
- on: jest.fn(),
104
- setTimeout: jest.fn(),
105
- destroy: jest.fn()
106
- })),
107
- setTimeout: jest.fn(),
108
- destroy: jest.fn()
109
- };
110
- });
111
-
112
- await expect(updateCommand.getLatestVersion()).rejects.toThrow('Invalid JSON');
113
-
114
- https.get = originalGet;
115
- });
116
-
117
- test('should handle HTTP error codes', async () => {
118
- const https = require('https');
119
- const originalGet = https.get;
120
-
121
- https.get = jest.fn((url, callback) => {
122
- const mockResponse = {
123
- statusCode: 404,
124
- on: jest.fn()
125
- };
126
-
127
- callback(mockResponse);
128
-
129
- return {
130
- on: jest.fn((event, handler) => ({
131
- on: jest.fn(),
132
- setTimeout: jest.fn(),
133
- destroy: jest.fn()
134
- })),
135
- setTimeout: jest.fn(),
136
- destroy: jest.fn()
137
- };
138
- });
139
-
140
- await expect(updateCommand.getLatestVersion()).rejects.toThrow('HTTP 404');
141
-
142
- https.get = originalGet;
143
- });
144
- });
145
-
146
- describe('updateJettyPod()', () => {
147
- // Note: We can't easily test the actual npm install without side effects
148
- // These tests verify the function structure and error handling
149
-
150
- test('should be a function', () => {
151
- expect(typeof updateCommand.updateJettyPod).toBe('function');
152
- });
153
-
154
- test('should handle version parameter', () => {
155
- // This test just verifies the function accepts parameters
156
- // Actual npm install testing requires integration tests
157
- expect(() => {
158
- updateCommand.updateJettyPod;
159
- }).not.toThrow();
160
- });
161
- });
162
-
163
- describe('runUpdate()', () => {
164
- test('should be an async function', () => {
165
- expect(updateCommand.runUpdate.constructor.name).toBe('AsyncFunction');
166
- });
167
-
168
- // Integration test would require network access and npm permissions
169
- // Covered by manual testing and BDD scenarios
170
- });
171
-
172
- describe('Error message clarity', () => {
173
- test('network errors should include "network error" in message', async () => {
174
- const https = require('https');
175
- const originalGet = https.get;
176
-
177
- https.get = jest.fn((url, callback) => {
178
- const mockRequest = {
179
- on: jest.fn((event, handler) => {
180
- if (event === 'error') {
181
- handler({ code: 'ENOTFOUND' });
182
- }
183
- return mockRequest;
184
- }),
185
- setTimeout: jest.fn(),
186
- destroy: jest.fn()
187
- };
188
- return mockRequest;
189
- });
190
-
191
- try {
192
- await updateCommand.getLatestVersion();
193
- } catch (err) {
194
- expect(err.message).toContain('network error');
195
- }
196
-
197
- https.get = originalGet;
198
- });
199
-
200
- test('timeout errors should mention timeout', async () => {
201
- const https = require('https');
202
- const originalGet = https.get;
203
-
204
- https.get = jest.fn((url, callback) => {
205
- const mockRequest = {
206
- on: jest.fn((event, handler) => mockRequest),
207
- setTimeout: jest.fn((timeout, handler) => {
208
- handler();
209
- return mockRequest;
210
- }),
211
- destroy: jest.fn()
212
- };
213
- return mockRequest;
214
- });
215
-
216
- try {
217
- await updateCommand.getLatestVersion();
218
- } catch (err) {
219
- expect(err.message.toLowerCase()).toContain('timeout');
220
- }
221
-
222
- https.get = originalGet;
223
- });
224
- });
225
- });
@@ -1,22 +0,0 @@
1
- Feature: Bug Workflow Display
2
- As a developer
3
- I want to see bug-specific workflow guidance when starting a bug
4
- So that I have systematic steps to follow for fixing bugs
5
-
6
- Scenario: Starting work on a bug displays workflow guidance
7
- Given jettypod is initialized
8
- And I create a bug "Install script fails"
9
- When I start work on the bug
10
- Then the output contains "BUG FIXING WORKFLOW"
11
- And the output contains "1. REPRODUCE"
12
- And the output contains "2. INVESTIGATE"
13
- And the output contains "3. ISOLATE"
14
- And the output contains "4. FIX"
15
- And the output contains "5. VERIFY"
16
- And the output contains "6. COMMIT"
17
-
18
- Scenario: Starting work on a feature does not display bug workflow
19
- Given jettypod is initialized
20
- And I create a feature "Add new feature"
21
- When I start work on the feature
22
- Then the output does not contain "BUG FIXING WORKFLOW"