Aiwg decompose-file

Analyze large source files and produce decomposition plans, optionally executing refactoring with import updates and test verification

install
source · Clone the upstream repo
git clone https://github.com/jmagly/aiwg
Claude Code · Install into ~/.claude/skills/
T=$(mktemp -d) && git clone --depth=1 https://github.com/jmagly/aiwg "$T" && mkdir -p ~/.claude/skills && cp -r "$T/.agents/skills/decompose-file" ~/.claude/skills/jmagly-aiwg-decompose-file && rm -rf "$T"
manifest: .agents/skills/decompose-file/SKILL.md
source content

decompose-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:

  1. 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
  2. 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
  3. 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
  4. Show dependency graph:

    • Visualize which proposed modules depend on which
    • Verify no circular dependencies exist
    • Show import direction between new modules
  5. Execute refactoring (if

    --execute
    or user approves):

    • 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

LanguageStrategyBoundaries
TypeScript/JavaScriptAST via function/class/export declarations
export
,
class
,
function
,
const
PythonAST via
ast
module
class
,
def
, top-level assignments
GoPackage-level function/type declarations
func
,
type
,
var
blocks
Rust
mod
,
fn
,
struct
,
impl
blocks
Module and impl boundaries
JavaClass and method declarations
class
,
interface
,
enum

Heuristic Fallback

For unsupported languages or when AST parsing is unavailable:

  1. Blank line groups — consecutive blank lines often separate logical sections
  2. Comment blocks — section header comments (
    // --- Section Name ---
    )
  3. Indentation changes — top-level declarations at zero indentation
  4. 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

ArgumentRequiredDefaultDescription
<file-path>
YesFile to decompose
--max-lines <n>
No300Target max lines per output file
--dry-run
NotrueShow plan without executing
--execute
NofalseExecute the plan automatically
--language <lang>
Noauto-detectOverride language detection
--strategy <type>
Noauto
function
,
class
, or
responsibility
--preserve-exports
NotrueMaintain 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:

  • agent-friendly-code
    rule: Target thresholds for output file sizes
  • agent-generation-guardrails
    rule: Prevents creating new large files during split
  • executable-feedback
    rule: Runs tests after execution to verify no breakage
  • anti-laziness
    rule: Does not skip the split because it is complex
  • /codebase-health
    command: Identifies candidates for decomposition

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