Aiwg decompose-file
Analyze large source files and produce decomposition plans, optionally executing refactoring with import updates and test verification
git clone https://github.com/jmagly/aiwg
T=$(mktemp -d) && git clone --depth=1 https://github.com/jmagly/aiwg "$T" && mkdir -p ~/.claude/skills && cp -r "$T/agentic/code/frameworks/sdlc-complete/skills/decompose-file" ~/.claude/skills/jmagly-aiwg-decompose-file-26cf9b && rm -rf "$T"
agentic/code/frameworks/sdlc-complete/skills/decompose-file/SKILL.mddecompose-file
Analyze a large source file and produce a concrete decomposition plan, optionally executing the refactoring with import updates and test verification.
Triggers
Alternate expressions and non-obvious activations (primary phrases are matched automatically from the skill description):
- "this file is too large" → file decomposition trigger
- "split into modules" → modular decomposition
Purpose
When
/codebase-health identifies files exceeding agent-friendly thresholds (300 LOC warning, 500 LOC error), this skill provides guided decomposition. It analyzes file structure, identifies logical groupings, maps internal dependencies, proposes a split plan, and optionally executes the refactoring.
The doc-splitter skill handles documentation splitting. This skill handles source code splitting — a fundamentally different problem requiring dependency analysis, import rewiring, and test verification.
Behavior
When triggered, this skill:
-
Analyze file structure:
- Parse the file to identify logical sections (classes, function groups, export clusters)
- Measure each section's size in LOC
- Identify the file's primary language and applicable parsing strategy
- Report current file size vs. agent-friendly thresholds
-
Map internal dependencies:
- Trace references between identified sections
- Identify shared state (module-level variables, constants)
- Detect circular dependency risks in proposed splits
- Catalog all exports and their consumers
-
Propose split plan:
- Assign each section to a proposed output file
- Name output files descriptively (no generic names)
- Ensure each output file is under the warning threshold (300 LOC)
- Include shared dependencies in the most logical location
- Add a purpose statement for each proposed file
-
Show dependency graph:
- Visualize which proposed modules depend on which
- Verify no circular dependencies exist
- Show import direction between new modules
-
Execute refactoring (if
or user approves):--execute- Create new files with proper imports
- Update the original file to re-export if needed for backward compatibility
- Find and update all import statements across the codebase
- Add module-level purpose statements to each new file
- Run tests to verify no breakage
Analysis Strategies
Language-Specific Parsing
| Language | Strategy | Boundaries |
|---|---|---|
| TypeScript/JavaScript | AST via function/class/export declarations | , , , |
| Python | AST via module | , , top-level assignments |
| Go | Package-level function/type declarations | , , blocks |
| Rust | , , , blocks | Module and impl boundaries |
| Java | Class and method declarations | , , |
Heuristic Fallback
For unsupported languages or when AST parsing is unavailable:
- Blank line groups — consecutive blank lines often separate logical sections
- Comment blocks — section header comments (
)// --- Section Name --- - Indentation changes — top-level declarations at zero indentation
- Export clusters — groups of exports at file end
Decomposition Plan Format
Decomposition Plan for src/extensions/registry.ts (847 lines) Current Structure: 1. Imports and type definitions (lines 1-45) 2. ExtensionRegistry class (lines 47-320) 2a. Constructor and initialization (lines 47-85) 2b. register() — registers an extension (lines 87-145) 2c. lookup() — finds extension by name (lines 147-210) 2d. listByType() — returns extensions of a type (lines 212-260) 2e. unregister() — removes an extension (lines 262-320) 3. Validation functions (lines 322-480) 3a. validateExtension() (lines 322-390) 3b. validateManifest() (lines 392-440) 3c. checkDependencies() (lines 442-480) 4. Discovery helpers (lines 482-620) 5. Deployment logic (lines 622-847) Proposed Split: 1. src/extensions/registry.ts (185 lines) — ExtensionRegistry class (core registration, lookup, list, unregister) — Imports from: validation, discovery, deployment 2. src/extensions/extension-validator.ts (160 lines) — validateExtension(), validateManifest(), checkDependencies() — No internal dependencies 3. src/extensions/extension-discovery.ts (140 lines) — discoverExtensions(), globForType(), resolveExtensionPath() — Imports from: extension-validator 4. src/extensions/extension-deployer.ts (227 lines) — deployToProvider(), buildProviderConfig(), writeDeploymentFiles() — Imports from: registry, extension-validator Dependency Graph: registry → extension-validator registry → extension-discovery registry → extension-deployer extension-discovery → extension-validator extension-deployer → registry, extension-validator Circular Dependencies: NONE ✓ All proposed files under 300 LOC warning threshold ✓
Arguments
| Argument | Required | Default | Description |
|---|---|---|---|
| Yes | — | File to decompose |
| No | 300 | Target max lines per output file |
| No | true | Show plan without executing |
| No | false | Execute the plan automatically |
| No | auto-detect | Override language detection |
| No | auto | , , or |
| No | true | Maintain backward-compatible re-exports |
Execution Workflow
When
--execute is used:
┌─────────────────────────────────────────────┐ │ 1. ANALYZE │ │ • Parse file structure │ │ • Identify logical sections │ │ • Map dependencies │ └──────────────┬──────────────────────────────┘ ▼ ┌─────────────────────────────────────────────┐ │ 2. PLAN │ │ • Propose split into N files │ │ • Verify no circular dependencies │ │ • Show plan to user │ └──────────────┬──────────────────────────────┘ ▼ ┌─────────────────────────────────────────────┐ │ 3. EXECUTE │ │ • Create new files with content │ │ • Add purpose statements │ │ • Update original file (re-exports) │ └──────────────┬──────────────────────────────┘ ▼ ┌─────────────────────────────────────────────┐ │ 4. REWIRE │ │ • Find all imports of original file │ │ • Update to point to new modules │ │ • Handle re-exports for compat │ └──────────────┬──────────────────────────────┘ ▼ ┌─────────────────────────────────────────────┐ │ 5. VERIFY │ │ • Run tests │ │ • Check for import errors │ │ • Report pass/fail │ └─────────────────────────────────────────────┘
Usage Examples
Dry Run (Default)
User: "decompose src/extensions/registry.ts" Skill analyzes the file and produces: - Current structure map with line ranges - Proposed split into 4 files - Dependency graph - Verification: no circular dependencies Output shows the plan without making changes.
Execute with Verification
User: "/decompose-file src/extensions/registry.ts --execute" Skill: 1. Analyzes and shows plan 2. Creates 4 new files 3. Updates registry.ts to re-export for compatibility 4. Finds 23 files importing from registry.ts 5. Updates imports to point to specific modules 6. Runs test suite: 247 passed, 0 failed ✓ Output: "Decomposition complete. 1 file (847 lines) → 4 files (avg 178 lines). All tests passing. 23 import statements updated."
Custom Strategy
User: "/decompose-file src/services/user-service.ts --strategy class --max-lines 200" Skill splits by class boundaries, targeting 200 lines per output file.
Error Handling
File Too Small
File src/utils/helper.ts is 85 lines — below the warning threshold (300). No decomposition needed. Use --max-lines to override if desired.
Circular Dependencies Detected
⚠ Proposed split would create circular dependency: module-a → module-b → module-a Suggestions: 1. Extract shared code into a common module 2. Merge module-a and module-b sections 3. Use dependency injection to break the cycle Adjusted plan: [shows revised plan]
Tests Fail After Split
🚫 Tests failed after decomposition. Failures: test/unit/registry.test.ts:42 — Cannot find module './registry' Root cause: Import path not updated in test file. Fix: Updating test imports... Re-running tests: 247 passed, 0 failed ✓
Integration
This skill uses:
rule: Target thresholds for output file sizesagent-friendly-code
rule: Prevents creating new large files during splitagent-generation-guardrails
rule: Runs tests after execution to verify no breakageexecutable-feedback
rule: Does not skip the split because it is complexanti-laziness
command: Identifies candidates for decomposition/codebase-health
Output Locations
- Decomposition plan:
.aiwg/working/decompose-{filename}-{date}.md - New source files: Same directory as original file (or user-specified)
References
- @$AIWG_ROOT/agentic/code/frameworks/sdlc-complete/rules/agent-friendly-code.md — Threshold definitions
- @$AIWG_ROOT/agentic/code/frameworks/sdlc-complete/rules/agent-generation-guardrails.md — Runtime guardrails
- @$AIWG_ROOT/agentic/code/frameworks/sdlc-complete/rules/executable-feedback.md — Test after changes
- @$AIWG_ROOT/agentic/code/frameworks/sdlc-complete/commands/codebase-health.md — Identifies candidates
- @$AIWG_ROOT/agentic/code/frameworks/sdlc-complete/skills/code-chunker/SKILL.md — Navigate large files before splitting