jettypod 3.0.1

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 (122) hide show
  1. package/.claude/PROTECT_SKILLS.md +28 -0
  2. package/.claude/settings.json +24 -0
  3. package/.claude/settings.local.json +16 -0
  4. package/.claude/skills/epic-discover/SKILL.md +262 -0
  5. package/.claude/skills/feature-discover/SKILL.md +393 -0
  6. package/.claude/skills/speed-mode/SKILL.md +364 -0
  7. package/.claude/skills/stable-mode/SKILL.md +591 -0
  8. package/.github/workflows/test-safety.yml +85 -0
  9. package/README.md +25 -0
  10. package/SPEED-STABLE-AUDIT.md +853 -0
  11. package/SYSTEM-BEHAVIOR.md +1241 -0
  12. package/TEST_SAFETY_AUDIT.md +314 -0
  13. package/TEST_SAFETY_IMPLEMENTATION.md +97 -0
  14. package/cucumber.js +8 -0
  15. package/docs/COMMAND_REFERENCE.md +903 -0
  16. package/docs/DECISIONS.md +68 -0
  17. package/docs/README.md +48 -0
  18. package/docs/STANDARDS-SYSTEM-DOCUMENTATION.md +374 -0
  19. package/docs/TEST-REWRITE-PLAN.md +261 -0
  20. package/docs/ai-test-writing-requirements.md +219 -0
  21. package/docs/claude-code-skills.md +607 -0
  22. package/docs/core-jettypod-methodology/comprehensive-jettypod-methodology.md +582 -0
  23. package/docs/core-jettypod-methodology/deprecated/jettypod-comprehensive-standards.md +1222 -0
  24. package/docs/core-jettypod-methodology/deprecated/jettypod-operating-guide.md +3399 -0
  25. package/docs/core-jettypod-methodology/deprecated/jettypod-technical-checklist.md +1325 -0
  26. package/docs/core-jettypod-methodology/deprecated/jettypod-vibe-coding-framework.md +1544 -0
  27. package/docs/core-jettypod-methodology/deprecated/prompt-engineering-guide.md +320 -0
  28. package/docs/core-jettypod-methodology/deprecated/vibe-coding-cheatsheet (1).md +516 -0
  29. package/docs/core-jettypod-methodology/deprecated/vibe-coding-framework.md +1544 -0
  30. package/docs/features/jettypod-standards-explained.md +543 -0
  31. package/docs/features/standards-inventory.md +257 -0
  32. package/docs/gap-analysis-current-vs-comprehensive-methodology.md +939 -0
  33. package/docs/jettypod-system-overview.md +409 -0
  34. package/features/auto-generate-production-chores.feature +14 -0
  35. package/features/claude-md-protection/steps.js +487 -0
  36. package/features/decisions/index.js +490 -0
  37. package/features/decisions/index.test.js +208 -0
  38. package/features/git-hooks/git-hooks.feature +30 -0
  39. package/features/git-hooks/index.js +93 -0
  40. package/features/git-hooks/index.test.js +137 -0
  41. package/features/git-hooks/post-commit +56 -0
  42. package/features/git-hooks/post-merge +47 -0
  43. package/features/git-hooks/pre-commit +28 -0
  44. package/features/git-hooks/simple-steps.js +53 -0
  45. package/features/git-hooks/simple-test.feature +10 -0
  46. package/features/git-hooks/steps.js +196 -0
  47. package/features/jettypod-update-command.feature +46 -0
  48. package/features/mode-prompts/index.js +95 -0
  49. package/features/mode-prompts/simple-steps.js +44 -0
  50. package/features/mode-prompts/simple-test.feature +9 -0
  51. package/features/mode-prompts/validation.test.js +120 -0
  52. package/features/refactor-mode/steps.js +217 -0
  53. package/features/refactor-mode.feature +49 -0
  54. package/features/skills-update/index.test.js +216 -0
  55. package/features/step_definitions/auto-generate-production-chores.steps.js +162 -0
  56. package/features/step_definitions/terminal-logo.steps.js +145 -0
  57. package/features/step_definitions/update-command.steps.js +183 -0
  58. package/features/terminal-logo/index.js +39 -0
  59. package/features/terminal-logo/terminal-logo.feature +30 -0
  60. package/features/update-command/index.js +181 -0
  61. package/features/update-command/index.test.js +225 -0
  62. package/features/work-commands/bug-workflow-display.feature +22 -0
  63. package/features/work-commands/index.js +311 -0
  64. package/features/work-commands/simple-steps.js +69 -0
  65. package/features/work-commands/stable-tests.feature +57 -0
  66. package/features/work-commands/steps.js +1120 -0
  67. package/features/work-commands/validation.test.js +88 -0
  68. package/features/work-commands/work-commands.feature +13 -0
  69. package/features/work-tracking/discovery-validation.test.js +228 -0
  70. package/features/work-tracking/index.js +1511 -0
  71. package/features/work-tracking/mode-required.feature +112 -0
  72. package/features/work-tracking/phase-tracking.test.js +482 -0
  73. package/features/work-tracking/prototype-tracking.test.js +485 -0
  74. package/features/work-tracking/tree-view.test.js +310 -0
  75. package/features/work-tracking/work-set-mode.feature +71 -0
  76. package/features/work-tracking/work-start-mode.feature +88 -0
  77. package/full-test.txt +0 -0
  78. package/install.sh +89 -0
  79. package/jettypod.js +1640 -0
  80. package/lib/bug-workflow.js +94 -0
  81. package/lib/bug-workflow.test.js +177 -0
  82. package/lib/claudemd.js +130 -0
  83. package/lib/claudemd.test.js +195 -0
  84. package/lib/comprehensive-standards-full.json +1778 -0
  85. package/lib/config.js +181 -0
  86. package/lib/config.test.js +511 -0
  87. package/lib/constants.js +107 -0
  88. package/lib/constants.test.js +164 -0
  89. package/lib/current-work.js +130 -0
  90. package/lib/current-work.test.js +146 -0
  91. package/lib/database-project-config.test.js +107 -0
  92. package/lib/database.js +256 -0
  93. package/lib/database.test.js +106 -0
  94. package/lib/decisions-generator.js +102 -0
  95. package/lib/decisions-generator.test.js +457 -0
  96. package/lib/decisions-helpers.js +119 -0
  97. package/lib/decisions-helpers.test.js +310 -0
  98. package/lib/discovery-checkpoint.js +83 -0
  99. package/lib/docs-generator.js +280 -0
  100. package/lib/external-checklist.js +177 -0
  101. package/lib/git.js +142 -0
  102. package/lib/git.test.js +145 -0
  103. package/lib/logo.js +3 -0
  104. package/lib/migrations/001-epic-to-parent.js +24 -0
  105. package/lib/migrations/002-default-work-item-modes.js +37 -0
  106. package/lib/migrations/002-default-work-item-modes.test.js +351 -0
  107. package/lib/migrations/003-epic-discovery-fields.js +52 -0
  108. package/lib/migrations/004-discovery-decisions-table.js +32 -0
  109. package/lib/migrations/005-migrate-decision-data.js +62 -0
  110. package/lib/migrations/006-feature-phase-field.js +61 -0
  111. package/lib/migrations/007-prototype-tracking.js +38 -0
  112. package/lib/migrations/008-scenario-file-field.js +24 -0
  113. package/lib/migrations/index.js +74 -0
  114. package/lib/production-helpers.js +69 -0
  115. package/lib/project-state.test.js +92 -0
  116. package/lib/test-helpers.js +184 -0
  117. package/lib/test-helpers.test.js +255 -0
  118. package/package.json +36 -0
  119. package/prototypes/test/index.html +1 -0
  120. package/setup-dist-repo.sh +68 -0
  121. package/test-safety-check.sh +80 -0
  122. package/work-item-tracking-plan.md +199 -0
@@ -0,0 +1,261 @@
1
+ # JettyPod Test Rewrite Plan
2
+
3
+ ## Current State
4
+ - **32 total scenarios**: 6 passing, 8 failing, 18 undefined
5
+ - Tests written for legacy dual-standards system
6
+ - Many step definitions missing or outdated
7
+ - No unit tests (only BDD with Cucumber)
8
+
9
+ ## Goal
10
+ Rewrite tests to match the new comprehensive standards engine that uses violation-based progressive disclosure.
11
+
12
+ ---
13
+
14
+ ## Phase 1: Remove Legacy Test Scenarios
15
+ **Priority: High | Estimated: 30 minutes**
16
+
17
+ ### Tasks:
18
+ - [ ] Remove/update scenarios that test for `.jettypod/standards.json` creation
19
+ - [ ] Remove tests checking for "Legacy Standards" section in CLAUDE.md
20
+ - [ ] Remove tests for old standards filtering (by stage/priority/bundle)
21
+ - [ ] Remove tests expecting mode-specific formatting (speed/discovery/production)
22
+
23
+ ### Files to Update:
24
+ - `.gherkin/features/01-initialization.feature`
25
+ - `.gherkin/features/05-standards-filtering.feature`
26
+ - `.gherkin/features/06-claude-generation.feature`
27
+
28
+ ---
29
+
30
+ ## Phase 2: Add New Standards Engine Tests
31
+ **Priority: Critical | Estimated: 1 hour**
32
+
33
+ ### New Test Scenarios Needed:
34
+
35
+ #### 2.1 Violation Tracking Tests
36
+ ```gherkin
37
+ Feature: Violation-Based Standards
38
+ Scenario: Standards appear after threshold
39
+ Given JettyPod is initialized
40
+ When I record 2 violations for "file.naming.constants"
41
+ Then CLAUDE.md should not contain "SCREAMING_SNAKE"
42
+ When I record 1 more violation for "file.naming.constants"
43
+ Then CLAUDE.md should contain "SCREAMING_SNAKE for constants (3 violations)"
44
+ ```
45
+
46
+ #### 2.2 Critical Standards Tests
47
+ ```gherkin
48
+ Feature: Critical Standards Always Show
49
+ Scenario: Critical standards appear immediately
50
+ Given JettyPod is initialized in "starting" stage
51
+ And bundles are ["core"]
52
+ When I run "jettypod generate"
53
+ Then CLAUDE.md should contain all critical standards for core bundle
54
+ And CLAUDE.md should not contain non-critical standards without violations
55
+ ```
56
+
57
+ #### 2.3 Bundle Detection Tests
58
+ ```gherkin
59
+ Feature: Automatic Bundle Detection
60
+ Scenario: React standards auto-include when React detected
61
+ Given package.json contains React dependency
62
+ When I run "jettypod generate"
63
+ Then CLAUDE.md should contain React critical standards
64
+ ```
65
+
66
+ #### 2.4 Mode Filtering Tests
67
+ ```gherkin
68
+ Feature: Mode-Based Filtering
69
+ Scenario: Speed mode filters by priority
70
+ Given JettyPod is in speed mode
71
+ And "test.medium.standard" has 5 violations (medium priority)
72
+ When I run "jettypod generate"
73
+ Then CLAUDE.md should not contain "test.medium.standard"
74
+
75
+ Scenario: Discovery mode shows all violated standards
76
+ Given JettyPod is in discovery mode
77
+ And "test.medium.standard" has 3 violations
78
+ When I run "jettypod generate"
79
+ Then CLAUDE.md should contain "test.medium.standard"
80
+ ```
81
+
82
+ ---
83
+
84
+ ## Phase 3: Fix Existing Step Definitions
85
+ **Priority: High | Estimated: 45 minutes**
86
+
87
+ ### Step Definitions to Add/Fix:
88
+
89
+ ```javascript
90
+ // Violation simulation
91
+ Given('{string} has {int} violations', function(standardId, count) {
92
+ // Clear existing violations for this standard
93
+ const violationsPath = '.jettypod/violations.json';
94
+ let violations = {};
95
+ if (fs.existsSync(violationsPath)) {
96
+ violations = JSON.parse(fs.readFileSync(violationsPath));
97
+ }
98
+ violations[standardId] = {
99
+ count: count,
100
+ lastSeen: new Date().toISOString()
101
+ };
102
+ fs.writeFileSync(violationsPath, JSON.stringify(violations, null, 2));
103
+ });
104
+
105
+ // Check for specific standards sections
106
+ Then('CLAUDE.md should contain all critical standards for {word} bundle', function(bundle) {
107
+ const claude = readClaude();
108
+ const library = JSON.parse(fs.readFileSync('lib/comprehensive-standards-full.json'));
109
+ const criticalStandards = Object.values(library.standards)
110
+ .filter(s => s.bundle === bundle && s.priority === 'critical');
111
+
112
+ criticalStandards.forEach(standard => {
113
+ expect(claude).to.include(standard.shortRule);
114
+ });
115
+ });
116
+
117
+ // Verify violation counts
118
+ Then('CLAUDE.md should contain {string} with {int} violations', function(text, count) {
119
+ const claude = readClaude();
120
+ expect(claude).to.include(`${text} (${count} violations)`);
121
+ });
122
+
123
+ // Check standards NOT present
124
+ Then('CLAUDE.md should not contain non-critical standards without violations', function() {
125
+ const claude = readClaude();
126
+ const standardsSection = claude.match(/<standards>([\s\S]*?)<\/standards>/);
127
+ if (standardsSection) {
128
+ // Should only have CRITICAL RULES section, no WATCH section if no violations
129
+ expect(standardsSection[1]).to.not.include('WATCH:');
130
+ }
131
+ });
132
+ ```
133
+
134
+ ---
135
+
136
+ ## Phase 4: Create Unit Tests
137
+ **Priority: Medium | Estimated: 1 hour**
138
+
139
+ ### New Unit Test Files:
140
+ - `tests/standards-engine.test.js`
141
+ - `tests/violation-tracking.test.js`
142
+
143
+ ### Test Coverage Needed:
144
+ ```javascript
145
+ // tests/standards-engine.test.js
146
+ describe('StandardsEngine', () => {
147
+ describe('prescribe()', () => {
148
+ it('should include critical standards for active bundles')
149
+ it('should include React criticals when React detected')
150
+ it('should add standards that exceed violation threshold')
151
+ it('should filter by mode (speed vs discovery)')
152
+ it('should respect stage filtering')
153
+ });
154
+
155
+ describe('recordViolation()', () => {
156
+ it('should create violation record if none exists')
157
+ it('should increment violation count')
158
+ it('should update lastSeen timestamp')
159
+ it('should not modify comprehensive standards file')
160
+ });
161
+
162
+ describe('formatForClaude()', () => {
163
+ it('should separate critical and violated standards')
164
+ it('should show violation counts in WATCH section')
165
+ it('should not include non-violated standards in WATCH')
166
+ });
167
+ });
168
+ ```
169
+
170
+ ---
171
+
172
+ ## Phase 5: Clean Up Test Structure
173
+ **Priority: Low | Estimated: 30 minutes**
174
+
175
+ ### Improvements:
176
+ - [ ] Consolidate duplicate step definitions
177
+ - [ ] Add helper functions for common operations
178
+ - [ ] Improve test data setup/teardown
179
+ - [ ] Add test utilities file for shared functions
180
+
181
+ ### Helper Functions Needed:
182
+ ```javascript
183
+ // test-helpers.js
184
+ function resetJettyPod() {
185
+ // Clean .jettypod directory
186
+ // Reset violations
187
+ // Set default config
188
+ }
189
+
190
+ function setViolations(violations) {
191
+ // Set specific violation state for testing
192
+ }
193
+
194
+ function assertStandardPresent(standardId) {
195
+ // Check if standard appears in CLAUDE.md
196
+ }
197
+
198
+ function assertStandardAbsent(standardId) {
199
+ // Verify standard does NOT appear
200
+ }
201
+ ```
202
+
203
+ ---
204
+
205
+ ## Phase 6: Documentation
206
+ **Priority: Low | Estimated: 15 minutes**
207
+
208
+ ### Documentation Updates:
209
+ - [ ] Update README with test running instructions
210
+ - [ ] Document test structure and patterns
211
+ - [ ] Add troubleshooting guide for common test failures
212
+ - [ ] Document how to add new test scenarios
213
+
214
+ ---
215
+
216
+ ## Implementation Order
217
+
218
+ 1. **Immediate (Fix Breaking Tests)**
219
+ - Add missing step definitions
220
+ - Fix regex patterns for Cucumber expressions
221
+ - Update paths and file references
222
+
223
+ 2. **Next (Remove Legacy)**
224
+ - Clean out old standards.json checks
225
+ - Remove legacy formatting tests
226
+ - Update CLAUDE.md content assertions
227
+
228
+ 3. **Then (Add New Coverage)**
229
+ - Implement violation threshold tests
230
+ - Add bundle detection tests
231
+ - Create mode filtering tests
232
+
233
+ 4. **Finally (Nice to Have)**
234
+ - Add unit tests for standards engine
235
+ - Improve test organization
236
+ - Add documentation
237
+
238
+ ---
239
+
240
+ ## Success Criteria
241
+
242
+ - [ ] All 32 scenarios have proper step definitions (no undefined)
243
+ - [ ] Tests accurately reflect new standards engine behavior
244
+ - [ ] Violation tracking is properly tested
245
+ - [ ] Critical standards always-show behavior is verified
246
+ - [ ] Mode filtering (speed vs others) is tested
247
+ - [ ] Stage cumulative filtering is tested
248
+ - [ ] Bundle detection (React) is tested
249
+ - [ ] Test run completes in under 10 seconds
250
+ - [ ] No false positives or flaky tests
251
+
252
+ ---
253
+
254
+ ## Notes
255
+
256
+ - Focus on integration tests over unit tests initially
257
+ - Prioritize testing the user-facing behavior
258
+ - Keep tests simple and readable
259
+ - Avoid testing implementation details
260
+ - Each test should have a clear purpose
261
+ - Use descriptive test names that explain the behavior
@@ -0,0 +1,219 @@
1
+ # AI Test Writing Requirements
2
+
3
+ ## Overview
4
+ This document provides guidelines for AI assistants when writing tests for this codebase. These requirements balance safety with practicality.
5
+
6
+ ## Core Principles
7
+
8
+ ### 1. Track Everything You Create
9
+ - Maintain lists of all files and directories created during tests
10
+ - Ensure cleanup even if tests fail
11
+ - Use try/catch blocks around cleanup operations
12
+
13
+ ### 2. Snapshot and Restore Critical Files
14
+ - Take snapshots of critical files (package.json, config files) before tests
15
+ - Restore them in After hooks unconditionally
16
+ - Verify restoration was successful
17
+
18
+ ### 3. Clean Up Test Artifacts
19
+ - Remove all test-created files (temp_*, test_*, etc.)
20
+ - Clean up test directories you explicitly created
21
+ - Never delete production directories (lib/, src/, node_modules/)
22
+
23
+ ## Required Test Structure
24
+
25
+ ```javascript
26
+ const { Before, After } = require('@cucumber/cucumber');
27
+ const fs = require('fs');
28
+ const path = require('path');
29
+
30
+ // Initialize tracking
31
+ function initializeTracking(context) {
32
+ context.createdFiles = [];
33
+ context.createdDirs = [];
34
+ context.modifiedFiles = new Map();
35
+ }
36
+
37
+ Before(function() {
38
+ // Initialize tracking
39
+ initializeTracking(this);
40
+
41
+ // Snapshot critical files
42
+ this.originalSnapshot = {
43
+ packageJson: fs.existsSync('package.json')
44
+ ? fs.readFileSync('package.json', 'utf-8')
45
+ : null,
46
+ config: fs.existsSync('.jettypod/config.json')
47
+ ? fs.readFileSync('.jettypod/config.json', 'utf-8')
48
+ : null
49
+ };
50
+ });
51
+
52
+ After(function() {
53
+ // Restore critical files FIRST
54
+ if (this.originalSnapshot?.packageJson) {
55
+ fs.writeFileSync('package.json', this.originalSnapshot.packageJson);
56
+ }
57
+
58
+ // Clean up created files
59
+ if (this.createdFiles) {
60
+ this.createdFiles.forEach(file => {
61
+ if (fs.existsSync(file)) {
62
+ try { fs.unlinkSync(file); } catch (e) {}
63
+ }
64
+ });
65
+ }
66
+
67
+ // Clean up created directories (in reverse order)
68
+ if (this.createdDirs) {
69
+ [...this.createdDirs].reverse().forEach(dir => {
70
+ if (fs.existsSync(dir)) {
71
+ try { fs.rmSync(dir, { recursive: true }); } catch (e) {}
72
+ }
73
+ });
74
+ }
75
+ });
76
+ ```
77
+
78
+ ## Safe Patterns
79
+
80
+ ### Creating Test Files
81
+ ```javascript
82
+ //  GOOD - Track what you create
83
+ Given('I create a test file', function() {
84
+ const filename = 'test_file.js';
85
+ fs.writeFileSync(filename, '// test content');
86
+ this.createdFiles.push(filename);
87
+ });
88
+ ```
89
+
90
+ ### Modifying Existing Files
91
+ ```javascript
92
+ //  GOOD - Snapshot before modifying
93
+ Given('package.json contains React', function() {
94
+ if (!this.packageBackup) {
95
+ this.packageBackup = fs.readFileSync('package.json', 'utf-8');
96
+ }
97
+ const pkg = JSON.parse(fs.readFileSync('package.json', 'utf-8'));
98
+ pkg.dependencies = pkg.dependencies || {};
99
+ pkg.dependencies.react = '^18.0.0';
100
+ fs.writeFileSync('package.json', JSON.stringify(pkg, null, 2));
101
+ });
102
+ ```
103
+
104
+ ### Creating Directories
105
+ ```javascript
106
+ //  GOOD - Track all levels
107
+ Given('I create nested directories', function() {
108
+ const dir = 'test/nested/dir';
109
+ fs.mkdirSync(dir, { recursive: true });
110
+
111
+ // Track all levels for cleanup
112
+ const parts = dir.split('/');
113
+ let currentPath = '';
114
+ parts.forEach(part => {
115
+ currentPath = currentPath ? `${currentPath}/${part}` : part;
116
+ if (!this.createdDirs.includes(currentPath)) {
117
+ this.createdDirs.push(currentPath);
118
+ }
119
+ });
120
+ });
121
+ ```
122
+
123
+ ## Dangerous Patterns to Avoid
124
+
125
+ ### L NEVER Do These:
126
+
127
+ 1. **Direct package.json modification without backup**
128
+ ```javascript
129
+ // L WRONG - No backup
130
+ fs.writeFileSync('package.json', modifiedContent);
131
+ ```
132
+
133
+ 2. **Cleanup with dangerous patterns**
134
+ ```javascript
135
+ // L WRONG - Could delete production directories
136
+ const dirsToDelete = ['lib', 'src', 'node_modules'];
137
+ dirsToDelete.forEach(dir => fs.rmSync(dir, { recursive: true }));
138
+ ```
139
+
140
+ 3. **Untracked file creation**
141
+ ```javascript
142
+ // L WRONG - Not tracked for cleanup
143
+ fs.writeFileSync('test.js', 'content');
144
+ // No this.createdFiles.push('test.js');
145
+ ```
146
+
147
+ 4. **Assuming cleanup will run**
148
+ ```javascript
149
+ // L WRONG - Cleanup might not run if test crashes
150
+ After(function() {
151
+ // Critical cleanup here might never execute
152
+ });
153
+ ```
154
+
155
+ ## Simplified Approach (Recommended)
156
+
157
+ For most tests, use a simplified approach that:
158
+ 1. Runs in the current directory (not isolated)
159
+ 2. Tracks all created files/directories
160
+ 3. Takes snapshots of critical files
161
+ 4. Restores everything in After hooks
162
+
163
+ This approach is simpler than full isolation but still safe because:
164
+ - All changes are tracked and reversed
165
+ - Critical files are protected by snapshots
166
+ - Cleanup is guaranteed even on failure
167
+
168
+ ## Testing Checklist
169
+
170
+ When writing tests, ensure:
171
+ - [ ] All created files are tracked in `this.createdFiles`
172
+ - [ ] All created directories are tracked in `this.createdDirs`
173
+ - [ ] package.json is snapshotted before any modification
174
+ - [ ] Config files are snapshotted before changes
175
+ - [ ] After hook restores all snapshots
176
+ - [ ] After hook removes all tracked items
177
+ - [ ] No production directories in cleanup lists
178
+ - [ ] Cleanup uses try/catch to continue on errors
179
+ - [ ] Test artifacts use clear naming (test_*, temp_*)
180
+
181
+ ## Advanced: Full Isolation (Optional)
182
+
183
+ For complete safety, tests can run in isolated temp directories:
184
+
185
+ ```javascript
186
+ const os = require('os');
187
+ const fs = require('fs');
188
+ const path = require('path');
189
+
190
+ Before(function() {
191
+ // Create isolated test directory
192
+ this.testDir = fs.mkdtempSync(path.join(os.tmpdir(), 'test-'));
193
+
194
+ // Copy only necessary files
195
+ [.jettypod.js', 'package.json', 'lib'].forEach(item => {
196
+ // Copy to test directory
197
+ });
198
+
199
+ process.chdir(this.testDir);
200
+ });
201
+
202
+ After(function() {
203
+ process.chdir(this.originalCwd);
204
+ fs.rmSync(this.testDir, { recursive: true, force: true });
205
+ });
206
+ ```
207
+
208
+ However, this approach has complications with module loading and is often overkill for most test scenarios.
209
+
210
+ ## Summary
211
+
212
+ The key to safe test writing is:
213
+ 1. **Track everything** you create or modify
214
+ 2. **Snapshot** critical files before changes
215
+ 3. **Restore** everything in After hooks
216
+ 4. **Never** assume cleanup will run
217
+ 5. **Never** delete production directories
218
+
219
+ Following these guidelines ensures tests can't corrupt the production codebase while keeping the test implementation simple and maintainable.