nightytidy 0.3.7 → 0.3.9
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.
- package/bin/nightytidy.js +1 -1
- package/package.json +1 -1
- package/src/agent/git-integration.js +4 -1
- package/src/claude.js +1 -1
- package/src/prompts/manifest.json +138 -138
- package/src/prompts/steps/02-test-coverage.md +181 -181
- package/src/prompts/steps/03-test-hardening.md +181 -181
- package/src/prompts/steps/04-test-architecture.md +130 -130
- package/src/prompts/steps/05-test-consolidation.md +165 -165
- package/src/prompts/steps/06-test-quality.md +211 -211
- package/src/prompts/steps/07-api-design.md +165 -165
- package/src/prompts/steps/08-security-sweep.md +207 -207
- package/src/prompts/steps/09-dependency-health.md +217 -217
- package/src/prompts/steps/10-codebase-cleanup.md +189 -189
- package/src/prompts/steps/11-crosscutting-concerns.md +196 -196
- package/src/prompts/steps/12-file-decomposition.md +263 -263
- package/src/prompts/steps/13-code-elegance.md +329 -329
- package/src/prompts/steps/14-architectural-complexity.md +297 -297
- package/src/prompts/steps/15-type-safety.md +192 -192
- package/src/prompts/steps/16-logging-error-message.md +173 -173
- package/src/prompts/steps/17-data-integrity.md +139 -139
- package/src/prompts/steps/18-performance.md +183 -183
- package/src/prompts/steps/19-cost-resource-optimization.md +136 -136
- package/src/prompts/steps/20-error-recovery.md +145 -145
- package/src/prompts/steps/21-race-condition-audit.md +178 -178
- package/src/prompts/steps/22-bug-hunt.md +229 -229
- package/src/prompts/steps/23-frontend-quality.md +210 -210
- package/src/prompts/steps/24-uiux-audit.md +284 -284
- package/src/prompts/steps/25-state-management.md +170 -170
- package/src/prompts/steps/26-perceived-performance.md +190 -190
- package/src/prompts/steps/27-devops.md +165 -165
- package/src/prompts/steps/28-scheduled-job-chron-jobs.md +141 -141
- package/src/prompts/steps/29-observability.md +152 -152
- package/src/prompts/steps/30-backup-check.md +155 -155
- package/src/prompts/steps/31-product-polish-ux-friction.md +122 -122
- package/src/prompts/steps/32-feature-discovery-opportunity.md +128 -128
- package/src/prompts/steps/33-strategic-opportunities.md +217 -217
|
@@ -1,263 +1,263 @@
|
|
|
1
|
-
# File Decomposition & Module Structure
|
|
2
|
-
|
|
3
|
-
You are running an overnight file decomposition and module structure improvement pass. Your job: find oversized files that are doing too much, and break them into smaller, focused modules that are easier to understand, test, and maintain. Target: no file should exceed 500 lines unless there's a clear structural reason.
|
|
4
|
-
|
|
5
|
-
This is one of the higher-risk overnight runs — every file split touches imports across the codebase. Move slowly, verify thoroughly, and when in doubt, document rather than split.
|
|
6
|
-
|
|
7
|
-
Work on branch `file-decomposition-[date]`.
|
|
8
|
-
|
|
9
|
-
---
|
|
10
|
-
|
|
11
|
-
## Global Rules
|
|
12
|
-
|
|
13
|
-
- **One file at a time.** Split a file, update ALL imports, run tests, commit. Only then move to the next file.
|
|
14
|
-
- Run the FULL test suite after every split — not just related test files. Import breakage can surface anywhere.
|
|
15
|
-
- Run the build/compile step after every split too (if applicable). Runtime import errors don't always show up in tests.
|
|
16
|
-
- DO NOT change any business logic, function signatures, or public APIs. Only move code between files and update references.
|
|
17
|
-
- DO NOT rename functions, variables, classes, or exports during this pass. Renaming + moving simultaneously makes failures harder to diagnose.
|
|
18
|
-
- If tests or build fail after a split, revert the ENTIRE split immediately. Do not attempt to debug — document what happened and move on.
|
|
19
|
-
- Commit format: `refactor: decompose [original-file] into [new-modules]`
|
|
20
|
-
- **Conservative threshold**: Only split files over **300 lines**. Files between 300-500 lines should only be split if they contain clearly distinct responsibilities. Files under 300 lines are almost never worth touching.
|
|
21
|
-
- You have all night — thoroughness and safety matter more than splitting every possible file.
|
|
22
|
-
|
|
23
|
-
---
|
|
24
|
-
|
|
25
|
-
## Phase 1: File Size Inventory & Prioritization
|
|
26
|
-
|
|
27
|
-
**Step 1: Measure every file**
|
|
28
|
-
Scan the entire source directory (excluding `node_modules`, `vendor`, `dist`, `build`, `.git`, test fixtures, generated files, and migration files). For each file, record:
|
|
29
|
-
- Path and filename
|
|
30
|
-
- Line count
|
|
31
|
-
- Primary responsibility (inferred from reading the file)
|
|
32
|
-
- Number of exports (functions, classes, constants, types)
|
|
33
|
-
- Number of files that import from it (import fan-out — high fan-out = higher risk to split)
|
|
34
|
-
|
|
35
|
-
**Step 2: Identify oversized files**
|
|
36
|
-
Flag every file exceeding 300 lines. Sort by line count descending.
|
|
37
|
-
|
|
38
|
-
**Step 3: Classify each oversized file**
|
|
39
|
-
|
|
40
|
-
- **Clear multi-responsibility** (SPLIT): File contains 2+ distinct logical groupings that don't heavily cross-reference each other. Example: a file with utility functions, API handlers, and type definitions mixed together.
|
|
41
|
-
- **Single responsibility, just long** (MAYBE SPLIT): File does one thing but it's large — a big React component with subcomponents inline, a long service class, a comprehensive validation module. May benefit from extracting helpers/subcomponents.
|
|
42
|
-
- **Inherently monolithic** (DO NOT SPLIT): Generated files, large config objects, migration files, single complex algorithms, test files with many cases for one unit. Splitting would hurt readability. Document why and skip.
|
|
43
|
-
- **High fan-out risk** (SPLIT WITH CAUTION): Many files import from this one. Splitting it means updating many import sites. Extra verification needed.
|
|
44
|
-
|
|
45
|
-
**Step 4: Create a split plan**
|
|
46
|
-
Produce a prioritized list:
|
|
47
|
-
1. Clear multi-responsibility files with LOW fan-out (safest, highest value)
|
|
48
|
-
2. Clear multi-responsibility files with HIGH fan-out (high value but riskier)
|
|
49
|
-
3. Single responsibility files that would benefit from helper extraction
|
|
50
|
-
4. Skip inherently monolithic files — document reasoning
|
|
51
|
-
|
|
52
|
-
For each file in the plan, outline the proposed split BEFORE making any changes:
|
|
53
|
-
- Original file path and line count
|
|
54
|
-
- Proposed new files with names and responsibilities
|
|
55
|
-
- Which exports move where
|
|
56
|
-
- Estimated import update count (how many other files reference this one)
|
|
57
|
-
- Risk assessment: low / medium / high
|
|
58
|
-
|
|
59
|
-
---
|
|
60
|
-
|
|
61
|
-
## Phase 2: Pre-Split Safety Checks
|
|
62
|
-
|
|
63
|
-
Before splitting ANY file, run these checks:
|
|
64
|
-
|
|
65
|
-
**Step 1: Map all references**
|
|
66
|
-
For the file you're about to split, find EVERY reference:
|
|
67
|
-
- Static imports/requires (`import { x } from './file'`, `const x = require('./file')`)
|
|
68
|
-
- Dynamic imports (`import('./file')`, `require.resolve('./file')`)
|
|
69
|
-
- Re-exports from barrel/index files (`export { x } from './file'`)
|
|
70
|
-
- Build tool references (webpack aliases, tsconfig paths, jest moduleNameMapper, babel module resolver)
|
|
71
|
-
- String-based references (route configs, lazy loading paths, test mocks with `jest.mock('./file')`)
|
|
72
|
-
- Documentation and comments referencing the file path
|
|
73
|
-
- CI/CD configs, Dockerfiles, or scripts referencing the file
|
|
74
|
-
- Package.json `main`, `exports`, or `bin` fields
|
|
75
|
-
|
|
76
|
-
**Step 2: Check for circular dependency risk**
|
|
77
|
-
Before splitting, trace the dependency graph for the target file:
|
|
78
|
-
- What does it import?
|
|
79
|
-
- What imports it?
|
|
80
|
-
- Would any proposed new module need to import from another proposed new module created from the same original file? If yes — reconsider the split boundaries.
|
|
81
|
-
|
|
82
|
-
**Step 3: Check for barrel file / index re-export patterns**
|
|
83
|
-
If the project uses barrel files (`index.ts` that re-exports from submodules):
|
|
84
|
-
- Plan to update the barrel file to re-export from the new locations
|
|
85
|
-
- This preserves backward compatibility for external consumers
|
|
86
|
-
- Internal imports should be updated to import directly from the new files (not through barrels) for clarity
|
|
87
|
-
|
|
88
|
-
---
|
|
89
|
-
|
|
90
|
-
## Phase 3: Execute Splits
|
|
91
|
-
|
|
92
|
-
For each file in the plan (one at a time, in priority order):
|
|
93
|
-
|
|
94
|
-
**Step 1: Create the new files**
|
|
95
|
-
- Name files by their responsibility: `user-validation.ts`, `order-utils.ts`, `payment-types.ts` — not `file2.ts` or `helpers.ts`
|
|
96
|
-
- Match existing project naming conventions (kebab-case, camelCase, PascalCase — whatever the codebase uses)
|
|
97
|
-
- Place new files in the same directory as the original, unless a subdirectory makes more structural sense AND the project already uses that pattern
|
|
98
|
-
- Move related code together: if a function and its helper are tightly coupled, they go in the same new file
|
|
99
|
-
- Keep the original file as a "home" for whatever doesn't have a better place — don't force everything out
|
|
100
|
-
|
|
101
|
-
**Step 2: Move exports to new files**
|
|
102
|
-
- Cut functions/classes/constants/types from the original file
|
|
103
|
-
- Paste into the appropriate new file
|
|
104
|
-
- Add necessary imports to the new file (dependencies the moved code needs)
|
|
105
|
-
- Update the original file to import from the new files if it still references the moved code
|
|
106
|
-
- If barrel files exist, update them to re-export from new locations
|
|
107
|
-
|
|
108
|
-
**Step 3: Update all import references**
|
|
109
|
-
- Update every file that imported the moved exports from the original file
|
|
110
|
-
- Verify: search the entire codebase for the original file's path to catch string-based references
|
|
111
|
-
- Check test files — especially `jest.mock()`, `vi.mock()`, or equivalent calls that reference file paths
|
|
112
|
-
- Check for `__mocks__` directories that mirror the original file structure
|
|
113
|
-
|
|
114
|
-
**Step 4: Verify**
|
|
115
|
-
- Run the full build/compile step
|
|
116
|
-
- Run the full test suite
|
|
117
|
-
- If ANYTHING fails: revert the entire split, document what went wrong, move to the next file
|
|
118
|
-
- If everything passes: commit with a clear message listing the original file and all new files created
|
|
119
|
-
|
|
120
|
-
**Step 5: Verify import cleanliness**
|
|
121
|
-
After a successful split, quickly check:
|
|
122
|
-
- No circular imports introduced (the build step usually catches this, but verify)
|
|
123
|
-
- No duplicate imports (importing the same thing from both the old and new location)
|
|
124
|
-
- The original file doesn't import from new files that import back from it
|
|
125
|
-
|
|
126
|
-
---
|
|
127
|
-
|
|
128
|
-
## Phase 4: Structural Improvements (Conservative)
|
|
129
|
-
|
|
130
|
-
After all planned splits are complete, look for broader structural improvements — but ONLY document these, do not implement:
|
|
131
|
-
|
|
132
|
-
**Directory structure opportunities**
|
|
133
|
-
- Are related files scattered across the project that should be co-located?
|
|
134
|
-
- Are there directories with 20+ files that would benefit from subdirectories?
|
|
135
|
-
- Does the project structure match the architectural pattern? (Feature-based vs. layer-based)
|
|
136
|
-
|
|
137
|
-
**Barrel file assessment**
|
|
138
|
-
- Are barrel files helping or hurting? (They help external consumers but can mask circular deps and hurt tree-shaking)
|
|
139
|
-
- Are there missing barrel files where they'd improve import ergonomics?
|
|
140
|
-
|
|
141
|
-
**Shared module opportunities**
|
|
142
|
-
- Did the splits reveal shared utilities that multiple new modules depend on? Would a `shared/` or `common/` module make sense?
|
|
143
|
-
|
|
144
|
-
---
|
|
145
|
-
|
|
146
|
-
## Phase 5: Post-Split Validation
|
|
147
|
-
|
|
148
|
-
After ALL splits are done:
|
|
149
|
-
|
|
150
|
-
**Step 1: Full verification**
|
|
151
|
-
- Run the complete test suite one final time
|
|
152
|
-
- Run the build one final time
|
|
153
|
-
- If the project has a linter, run it (new files may need lint fixes for import ordering, etc.)
|
|
154
|
-
|
|
155
|
-
**Step 2: Metrics**
|
|
156
|
-
- Count total files before and after
|
|
157
|
-
- Largest file before and after
|
|
158
|
-
- Average file size before and after
|
|
159
|
-
- Distribution: how many files are now in 0-100, 100-200, 200-300, 300-500, 500+ line buckets
|
|
160
|
-
|
|
161
|
-
**Step 3: Remaining oversized files**
|
|
162
|
-
For files that are still over 500 lines after this pass, document:
|
|
163
|
-
- Why they weren't split (inherently monolithic, too risky, failed and reverted)
|
|
164
|
-
- Whether a future pass with more context could address them
|
|
165
|
-
|
|
166
|
-
---
|
|
167
|
-
|
|
168
|
-
## Output
|
|
169
|
-
|
|
170
|
-
Create `audit-reports/` in project root if needed. Save as `audit-reports/12_FILE_DECOMPOSITION_REPORT_[run-number]_[date]_[time in user's local time].md`, incrementing run number based on existing reports.
|
|
171
|
-
|
|
172
|
-
### Report Structure
|
|
173
|
-
|
|
174
|
-
1. **Executive Summary** — Files analyzed, files split, files skipped (and why), total line reduction in largest files, all tests passing.
|
|
175
|
-
|
|
176
|
-
2. **File Size Inventory** — Before/after table for every file over 300 lines:
|
|
177
|
-
| File | Before (lines) | After (lines) | Action | New Files Created |
|
|
178
|
-
|
|
179
|
-
3. **Splits Executed** — For each split:
|
|
180
|
-
- Original file, line count, number of exports
|
|
181
|
-
- New files created with line counts and responsibilities
|
|
182
|
-
- Import references updated (count)
|
|
183
|
-
- Test/build status after split
|
|
184
|
-
- Commit hash
|
|
185
|
-
|
|
186
|
-
4. **Splits Attempted but Reverted** — For each failed split:
|
|
187
|
-
- What was attempted
|
|
188
|
-
- What broke (test failure, build failure, circular dep)
|
|
189
|
-
- Why it couldn't be resolved safely overnight
|
|
190
|
-
|
|
191
|
-
5. **Files Skipped** — For each oversized file not split:
|
|
192
|
-
- Why (inherently monolithic, too risky, time constraints)
|
|
193
|
-
- Whether it could be addressed in a future pass
|
|
194
|
-
|
|
195
|
-
6. **Structural Observations (Documentation Only)**
|
|
196
|
-
- Directory structure recommendations
|
|
197
|
-
- Barrel file assessment
|
|
198
|
-
- Shared module opportunities
|
|
199
|
-
|
|
200
|
-
7. **File Size Distribution** — Before/after histogram:
|
|
201
|
-
| Range | Before | After |
|
|
202
|
-
| 0-100 lines | X | Y |
|
|
203
|
-
| 100-200 | X | Y |
|
|
204
|
-
| 200-300 | X | Y |
|
|
205
|
-
| 300-500 | X | Y |
|
|
206
|
-
| 500+ | X | Y |
|
|
207
|
-
|
|
208
|
-
8. **Recommendations** — Priority-ordered next steps, files needing manual review for further decomposition, naming/structure conventions to adopt going forward.
|
|
209
|
-
|
|
210
|
-
## Rules
|
|
211
|
-
- Branch: `file-decomposition-[date]`
|
|
212
|
-
- ONE FILE AT A TIME. Split, update, test, commit. Then next file.
|
|
213
|
-
- Run FULL test suite AND build after every split. Not just related tests.
|
|
214
|
-
- If tests or build fail, revert the entire split immediately. Do not debug.
|
|
215
|
-
- DO NOT rename anything. Only move code between files and update import paths.
|
|
216
|
-
- DO NOT change function signatures, behavior, or exports.
|
|
217
|
-
- DO NOT split files under 300 lines.
|
|
218
|
-
- DO NOT split generated files, migration files, or config files.
|
|
219
|
-
- DO NOT split test files (they're supposed to be comprehensive for their unit).
|
|
220
|
-
- DO NOT create deeply nested directory structures that don't already exist in the project.
|
|
221
|
-
- DO NOT introduce new patterns (if the project doesn't use barrel files, don't add them).
|
|
222
|
-
- Preserve git blame where possible — move code in the commit, don't rewrite it.
|
|
223
|
-
- When in doubt about a split boundary, keep things together. Over-splitting is worse than under-splitting.
|
|
224
|
-
- Check for dynamic imports, string-based references, and build tool configs BEFORE splitting.
|
|
225
|
-
- You have all night. Prioritize safe, clean splits over quantity.
|
|
226
|
-
|
|
227
|
-
## Chat Output Requirement
|
|
228
|
-
|
|
229
|
-
In addition to writing the full report file, you MUST print a summary directly in the conversation when you finish. Do not make the user open the report to get the highlights. The chat summary should include:
|
|
230
|
-
|
|
231
|
-
### 1. Status Line
|
|
232
|
-
One sentence: what you did, how long it took, and whether all tests still pass.
|
|
233
|
-
|
|
234
|
-
### 2. Key Findings
|
|
235
|
-
The most important things discovered — bugs, risks, wins, or surprises. Each bullet should be specific and actionable, not vague. Lead with severity or impact.
|
|
236
|
-
|
|
237
|
-
**Good:** "CRITICAL: No backup configuration found for the primary Postgres database — total data loss risk."
|
|
238
|
-
**Bad:** "Found some issues with backups."
|
|
239
|
-
|
|
240
|
-
### 3. Changes Made (if applicable)
|
|
241
|
-
Bullet list of what was actually modified, added, or removed. Skip this section for read-only analysis runs.
|
|
242
|
-
|
|
243
|
-
### 4. Recommendations
|
|
244
|
-
|
|
245
|
-
If there are legitimately beneficial recommendations worth pursuing right now, present them in a table. Do **not** force recommendations — if the audit surfaced no actionable improvements, simply state that no recommendations are warranted at this time and move on.
|
|
246
|
-
|
|
247
|
-
When recommendations exist, use this table format:
|
|
248
|
-
|
|
249
|
-
| # | Recommendation | Impact | Risk if Ignored | Worth Doing? | Details |
|
|
250
|
-
|---|---|---|---|---|---|
|
|
251
|
-
| *Sequential number* | *Short description (≤10 words)* | *What improves if addressed* | *Low / Medium / High / Critical* | *Yes / Probably / Only if time allows* | *1–3 sentences explaining the reasoning, context, or implementation guidance* |
|
|
252
|
-
|
|
253
|
-
Order rows by risk descending (Critical → High → Medium → Low). Be honest in the "Worth Doing?" column — not everything flagged is worth the engineering time. If a recommendation is marginal, say so.
|
|
254
|
-
|
|
255
|
-
### 5. Report Location
|
|
256
|
-
State the full path to the detailed report file for deeper review.
|
|
257
|
-
|
|
258
|
-
---
|
|
259
|
-
|
|
260
|
-
**Formatting rules for chat output:**
|
|
261
|
-
- Use markdown headers, bold for severity labels, and bullet points for scannability.
|
|
262
|
-
- Do not duplicate the full report contents — just the highlights and recommendations.
|
|
263
|
-
- If you made zero findings in a phase, say so in one line rather than omitting it silently.
|
|
1
|
+
# File Decomposition & Module Structure
|
|
2
|
+
|
|
3
|
+
You are running an overnight file decomposition and module structure improvement pass. Your job: find oversized files that are doing too much, and break them into smaller, focused modules that are easier to understand, test, and maintain. Target: no file should exceed 500 lines unless there's a clear structural reason.
|
|
4
|
+
|
|
5
|
+
This is one of the higher-risk overnight runs — every file split touches imports across the codebase. Move slowly, verify thoroughly, and when in doubt, document rather than split.
|
|
6
|
+
|
|
7
|
+
Work on branch `file-decomposition-[date]`.
|
|
8
|
+
|
|
9
|
+
---
|
|
10
|
+
|
|
11
|
+
## Global Rules
|
|
12
|
+
|
|
13
|
+
- **One file at a time.** Split a file, update ALL imports, run tests, commit. Only then move to the next file.
|
|
14
|
+
- Run the FULL test suite after every split — not just related test files. Import breakage can surface anywhere.
|
|
15
|
+
- Run the build/compile step after every split too (if applicable). Runtime import errors don't always show up in tests.
|
|
16
|
+
- DO NOT change any business logic, function signatures, or public APIs. Only move code between files and update references.
|
|
17
|
+
- DO NOT rename functions, variables, classes, or exports during this pass. Renaming + moving simultaneously makes failures harder to diagnose.
|
|
18
|
+
- If tests or build fail after a split, revert the ENTIRE split immediately. Do not attempt to debug — document what happened and move on.
|
|
19
|
+
- Commit format: `refactor: decompose [original-file] into [new-modules]`
|
|
20
|
+
- **Conservative threshold**: Only split files over **300 lines**. Files between 300-500 lines should only be split if they contain clearly distinct responsibilities. Files under 300 lines are almost never worth touching.
|
|
21
|
+
- You have all night — thoroughness and safety matter more than splitting every possible file.
|
|
22
|
+
|
|
23
|
+
---
|
|
24
|
+
|
|
25
|
+
## Phase 1: File Size Inventory & Prioritization
|
|
26
|
+
|
|
27
|
+
**Step 1: Measure every file**
|
|
28
|
+
Scan the entire source directory (excluding `node_modules`, `vendor`, `dist`, `build`, `.git`, test fixtures, generated files, and migration files). For each file, record:
|
|
29
|
+
- Path and filename
|
|
30
|
+
- Line count
|
|
31
|
+
- Primary responsibility (inferred from reading the file)
|
|
32
|
+
- Number of exports (functions, classes, constants, types)
|
|
33
|
+
- Number of files that import from it (import fan-out — high fan-out = higher risk to split)
|
|
34
|
+
|
|
35
|
+
**Step 2: Identify oversized files**
|
|
36
|
+
Flag every file exceeding 300 lines. Sort by line count descending.
|
|
37
|
+
|
|
38
|
+
**Step 3: Classify each oversized file**
|
|
39
|
+
|
|
40
|
+
- **Clear multi-responsibility** (SPLIT): File contains 2+ distinct logical groupings that don't heavily cross-reference each other. Example: a file with utility functions, API handlers, and type definitions mixed together.
|
|
41
|
+
- **Single responsibility, just long** (MAYBE SPLIT): File does one thing but it's large — a big React component with subcomponents inline, a long service class, a comprehensive validation module. May benefit from extracting helpers/subcomponents.
|
|
42
|
+
- **Inherently monolithic** (DO NOT SPLIT): Generated files, large config objects, migration files, single complex algorithms, test files with many cases for one unit. Splitting would hurt readability. Document why and skip.
|
|
43
|
+
- **High fan-out risk** (SPLIT WITH CAUTION): Many files import from this one. Splitting it means updating many import sites. Extra verification needed.
|
|
44
|
+
|
|
45
|
+
**Step 4: Create a split plan**
|
|
46
|
+
Produce a prioritized list:
|
|
47
|
+
1. Clear multi-responsibility files with LOW fan-out (safest, highest value)
|
|
48
|
+
2. Clear multi-responsibility files with HIGH fan-out (high value but riskier)
|
|
49
|
+
3. Single responsibility files that would benefit from helper extraction
|
|
50
|
+
4. Skip inherently monolithic files — document reasoning
|
|
51
|
+
|
|
52
|
+
For each file in the plan, outline the proposed split BEFORE making any changes:
|
|
53
|
+
- Original file path and line count
|
|
54
|
+
- Proposed new files with names and responsibilities
|
|
55
|
+
- Which exports move where
|
|
56
|
+
- Estimated import update count (how many other files reference this one)
|
|
57
|
+
- Risk assessment: low / medium / high
|
|
58
|
+
|
|
59
|
+
---
|
|
60
|
+
|
|
61
|
+
## Phase 2: Pre-Split Safety Checks
|
|
62
|
+
|
|
63
|
+
Before splitting ANY file, run these checks:
|
|
64
|
+
|
|
65
|
+
**Step 1: Map all references**
|
|
66
|
+
For the file you're about to split, find EVERY reference:
|
|
67
|
+
- Static imports/requires (`import { x } from './file'`, `const x = require('./file')`)
|
|
68
|
+
- Dynamic imports (`import('./file')`, `require.resolve('./file')`)
|
|
69
|
+
- Re-exports from barrel/index files (`export { x } from './file'`)
|
|
70
|
+
- Build tool references (webpack aliases, tsconfig paths, jest moduleNameMapper, babel module resolver)
|
|
71
|
+
- String-based references (route configs, lazy loading paths, test mocks with `jest.mock('./file')`)
|
|
72
|
+
- Documentation and comments referencing the file path
|
|
73
|
+
- CI/CD configs, Dockerfiles, or scripts referencing the file
|
|
74
|
+
- Package.json `main`, `exports`, or `bin` fields
|
|
75
|
+
|
|
76
|
+
**Step 2: Check for circular dependency risk**
|
|
77
|
+
Before splitting, trace the dependency graph for the target file:
|
|
78
|
+
- What does it import?
|
|
79
|
+
- What imports it?
|
|
80
|
+
- Would any proposed new module need to import from another proposed new module created from the same original file? If yes — reconsider the split boundaries.
|
|
81
|
+
|
|
82
|
+
**Step 3: Check for barrel file / index re-export patterns**
|
|
83
|
+
If the project uses barrel files (`index.ts` that re-exports from submodules):
|
|
84
|
+
- Plan to update the barrel file to re-export from the new locations
|
|
85
|
+
- This preserves backward compatibility for external consumers
|
|
86
|
+
- Internal imports should be updated to import directly from the new files (not through barrels) for clarity
|
|
87
|
+
|
|
88
|
+
---
|
|
89
|
+
|
|
90
|
+
## Phase 3: Execute Splits
|
|
91
|
+
|
|
92
|
+
For each file in the plan (one at a time, in priority order):
|
|
93
|
+
|
|
94
|
+
**Step 1: Create the new files**
|
|
95
|
+
- Name files by their responsibility: `user-validation.ts`, `order-utils.ts`, `payment-types.ts` — not `file2.ts` or `helpers.ts`
|
|
96
|
+
- Match existing project naming conventions (kebab-case, camelCase, PascalCase — whatever the codebase uses)
|
|
97
|
+
- Place new files in the same directory as the original, unless a subdirectory makes more structural sense AND the project already uses that pattern
|
|
98
|
+
- Move related code together: if a function and its helper are tightly coupled, they go in the same new file
|
|
99
|
+
- Keep the original file as a "home" for whatever doesn't have a better place — don't force everything out
|
|
100
|
+
|
|
101
|
+
**Step 2: Move exports to new files**
|
|
102
|
+
- Cut functions/classes/constants/types from the original file
|
|
103
|
+
- Paste into the appropriate new file
|
|
104
|
+
- Add necessary imports to the new file (dependencies the moved code needs)
|
|
105
|
+
- Update the original file to import from the new files if it still references the moved code
|
|
106
|
+
- If barrel files exist, update them to re-export from new locations
|
|
107
|
+
|
|
108
|
+
**Step 3: Update all import references**
|
|
109
|
+
- Update every file that imported the moved exports from the original file
|
|
110
|
+
- Verify: search the entire codebase for the original file's path to catch string-based references
|
|
111
|
+
- Check test files — especially `jest.mock()`, `vi.mock()`, or equivalent calls that reference file paths
|
|
112
|
+
- Check for `__mocks__` directories that mirror the original file structure
|
|
113
|
+
|
|
114
|
+
**Step 4: Verify**
|
|
115
|
+
- Run the full build/compile step
|
|
116
|
+
- Run the full test suite
|
|
117
|
+
- If ANYTHING fails: revert the entire split, document what went wrong, move to the next file
|
|
118
|
+
- If everything passes: commit with a clear message listing the original file and all new files created
|
|
119
|
+
|
|
120
|
+
**Step 5: Verify import cleanliness**
|
|
121
|
+
After a successful split, quickly check:
|
|
122
|
+
- No circular imports introduced (the build step usually catches this, but verify)
|
|
123
|
+
- No duplicate imports (importing the same thing from both the old and new location)
|
|
124
|
+
- The original file doesn't import from new files that import back from it
|
|
125
|
+
|
|
126
|
+
---
|
|
127
|
+
|
|
128
|
+
## Phase 4: Structural Improvements (Conservative)
|
|
129
|
+
|
|
130
|
+
After all planned splits are complete, look for broader structural improvements — but ONLY document these, do not implement:
|
|
131
|
+
|
|
132
|
+
**Directory structure opportunities**
|
|
133
|
+
- Are related files scattered across the project that should be co-located?
|
|
134
|
+
- Are there directories with 20+ files that would benefit from subdirectories?
|
|
135
|
+
- Does the project structure match the architectural pattern? (Feature-based vs. layer-based)
|
|
136
|
+
|
|
137
|
+
**Barrel file assessment**
|
|
138
|
+
- Are barrel files helping or hurting? (They help external consumers but can mask circular deps and hurt tree-shaking)
|
|
139
|
+
- Are there missing barrel files where they'd improve import ergonomics?
|
|
140
|
+
|
|
141
|
+
**Shared module opportunities**
|
|
142
|
+
- Did the splits reveal shared utilities that multiple new modules depend on? Would a `shared/` or `common/` module make sense?
|
|
143
|
+
|
|
144
|
+
---
|
|
145
|
+
|
|
146
|
+
## Phase 5: Post-Split Validation
|
|
147
|
+
|
|
148
|
+
After ALL splits are done:
|
|
149
|
+
|
|
150
|
+
**Step 1: Full verification**
|
|
151
|
+
- Run the complete test suite one final time
|
|
152
|
+
- Run the build one final time
|
|
153
|
+
- If the project has a linter, run it (new files may need lint fixes for import ordering, etc.)
|
|
154
|
+
|
|
155
|
+
**Step 2: Metrics**
|
|
156
|
+
- Count total files before and after
|
|
157
|
+
- Largest file before and after
|
|
158
|
+
- Average file size before and after
|
|
159
|
+
- Distribution: how many files are now in 0-100, 100-200, 200-300, 300-500, 500+ line buckets
|
|
160
|
+
|
|
161
|
+
**Step 3: Remaining oversized files**
|
|
162
|
+
For files that are still over 500 lines after this pass, document:
|
|
163
|
+
- Why they weren't split (inherently monolithic, too risky, failed and reverted)
|
|
164
|
+
- Whether a future pass with more context could address them
|
|
165
|
+
|
|
166
|
+
---
|
|
167
|
+
|
|
168
|
+
## Output
|
|
169
|
+
|
|
170
|
+
Create `audit-reports/` in project root if needed. Save as `audit-reports/12_FILE_DECOMPOSITION_REPORT_[run-number]_[date]_[time in user's local time].md`, incrementing run number based on existing reports.
|
|
171
|
+
|
|
172
|
+
### Report Structure
|
|
173
|
+
|
|
174
|
+
1. **Executive Summary** — Files analyzed, files split, files skipped (and why), total line reduction in largest files, all tests passing.
|
|
175
|
+
|
|
176
|
+
2. **File Size Inventory** — Before/after table for every file over 300 lines:
|
|
177
|
+
| File | Before (lines) | After (lines) | Action | New Files Created |
|
|
178
|
+
|
|
179
|
+
3. **Splits Executed** — For each split:
|
|
180
|
+
- Original file, line count, number of exports
|
|
181
|
+
- New files created with line counts and responsibilities
|
|
182
|
+
- Import references updated (count)
|
|
183
|
+
- Test/build status after split
|
|
184
|
+
- Commit hash
|
|
185
|
+
|
|
186
|
+
4. **Splits Attempted but Reverted** — For each failed split:
|
|
187
|
+
- What was attempted
|
|
188
|
+
- What broke (test failure, build failure, circular dep)
|
|
189
|
+
- Why it couldn't be resolved safely overnight
|
|
190
|
+
|
|
191
|
+
5. **Files Skipped** — For each oversized file not split:
|
|
192
|
+
- Why (inherently monolithic, too risky, time constraints)
|
|
193
|
+
- Whether it could be addressed in a future pass
|
|
194
|
+
|
|
195
|
+
6. **Structural Observations (Documentation Only)**
|
|
196
|
+
- Directory structure recommendations
|
|
197
|
+
- Barrel file assessment
|
|
198
|
+
- Shared module opportunities
|
|
199
|
+
|
|
200
|
+
7. **File Size Distribution** — Before/after histogram:
|
|
201
|
+
| Range | Before | After |
|
|
202
|
+
| 0-100 lines | X | Y |
|
|
203
|
+
| 100-200 | X | Y |
|
|
204
|
+
| 200-300 | X | Y |
|
|
205
|
+
| 300-500 | X | Y |
|
|
206
|
+
| 500+ | X | Y |
|
|
207
|
+
|
|
208
|
+
8. **Recommendations** — Priority-ordered next steps, files needing manual review for further decomposition, naming/structure conventions to adopt going forward.
|
|
209
|
+
|
|
210
|
+
## Rules
|
|
211
|
+
- Branch: `file-decomposition-[date]`
|
|
212
|
+
- ONE FILE AT A TIME. Split, update, test, commit. Then next file.
|
|
213
|
+
- Run FULL test suite AND build after every split. Not just related tests.
|
|
214
|
+
- If tests or build fail, revert the entire split immediately. Do not debug.
|
|
215
|
+
- DO NOT rename anything. Only move code between files and update import paths.
|
|
216
|
+
- DO NOT change function signatures, behavior, or exports.
|
|
217
|
+
- DO NOT split files under 300 lines.
|
|
218
|
+
- DO NOT split generated files, migration files, or config files.
|
|
219
|
+
- DO NOT split test files (they're supposed to be comprehensive for their unit).
|
|
220
|
+
- DO NOT create deeply nested directory structures that don't already exist in the project.
|
|
221
|
+
- DO NOT introduce new patterns (if the project doesn't use barrel files, don't add them).
|
|
222
|
+
- Preserve git blame where possible — move code in the commit, don't rewrite it.
|
|
223
|
+
- When in doubt about a split boundary, keep things together. Over-splitting is worse than under-splitting.
|
|
224
|
+
- Check for dynamic imports, string-based references, and build tool configs BEFORE splitting.
|
|
225
|
+
- You have all night. Prioritize safe, clean splits over quantity.
|
|
226
|
+
|
|
227
|
+
## Chat Output Requirement
|
|
228
|
+
|
|
229
|
+
In addition to writing the full report file, you MUST print a summary directly in the conversation when you finish. Do not make the user open the report to get the highlights. The chat summary should include:
|
|
230
|
+
|
|
231
|
+
### 1. Status Line
|
|
232
|
+
One sentence: what you did, how long it took, and whether all tests still pass.
|
|
233
|
+
|
|
234
|
+
### 2. Key Findings
|
|
235
|
+
The most important things discovered — bugs, risks, wins, or surprises. Each bullet should be specific and actionable, not vague. Lead with severity or impact.
|
|
236
|
+
|
|
237
|
+
**Good:** "CRITICAL: No backup configuration found for the primary Postgres database — total data loss risk."
|
|
238
|
+
**Bad:** "Found some issues with backups."
|
|
239
|
+
|
|
240
|
+
### 3. Changes Made (if applicable)
|
|
241
|
+
Bullet list of what was actually modified, added, or removed. Skip this section for read-only analysis runs.
|
|
242
|
+
|
|
243
|
+
### 4. Recommendations
|
|
244
|
+
|
|
245
|
+
If there are legitimately beneficial recommendations worth pursuing right now, present them in a table. Do **not** force recommendations — if the audit surfaced no actionable improvements, simply state that no recommendations are warranted at this time and move on.
|
|
246
|
+
|
|
247
|
+
When recommendations exist, use this table format:
|
|
248
|
+
|
|
249
|
+
| # | Recommendation | Impact | Risk if Ignored | Worth Doing? | Details |
|
|
250
|
+
|---|---|---|---|---|---|
|
|
251
|
+
| *Sequential number* | *Short description (≤10 words)* | *What improves if addressed* | *Low / Medium / High / Critical* | *Yes / Probably / Only if time allows* | *1–3 sentences explaining the reasoning, context, or implementation guidance* |
|
|
252
|
+
|
|
253
|
+
Order rows by risk descending (Critical → High → Medium → Low). Be honest in the "Worth Doing?" column — not everything flagged is worth the engineering time. If a recommendation is marginal, say so.
|
|
254
|
+
|
|
255
|
+
### 5. Report Location
|
|
256
|
+
State the full path to the detailed report file for deeper review.
|
|
257
|
+
|
|
258
|
+
---
|
|
259
|
+
|
|
260
|
+
**Formatting rules for chat output:**
|
|
261
|
+
- Use markdown headers, bold for severity labels, and bullet points for scannability.
|
|
262
|
+
- Do not duplicate the full report contents — just the highlights and recommendations.
|
|
263
|
+
- If you made zero findings in a phase, say so in one line rather than omitting it silently.
|