From agentops
Executes safe, incremental refactors on files, functions, or projects with test verification at each step to prevent regressions. Supports target, sweep, and extract modes.
npx claudepluginhub boshu2/agentops --plugin agentopsThis skill uses the workspace's default tool permissions.
> **Quick Ref:** Safe, incremental refactoring with test verification at every step. One transformation, one test run, one commit. Never batch.
Creates isolated Git worktrees for feature branches with prioritized directory selection, gitignore safety checks, auto project setup for Node/Python/Rust/Go, and baseline verification.
Executes implementation plans in current session by dispatching fresh subagents per independent task, with two-stage reviews: spec compliance then code quality.
Dispatches parallel agents to independently tackle 2+ tasks like separate test failures or subsystems without shared state or dependencies.
Quick Ref: Safe, incremental refactoring with test verification at every step. One transformation, one test run, one commit. Never batch.
YOU MUST EXECUTE THIS WORKFLOW. Do not just describe it.
/refactor <file-or-function>
Refactor a specific file, function, or class. You identify what needs improving, plan the steps, and execute them one at a time with test verification.
/refactor --sweep <scope>
Find and fix complexity hotspots across a directory, package, or entire project. Runs /complexity first to identify targets, then works through them in priority order (highest complexity first).
<scope> can be:
cli/internal/)goals)all (entire project -- use with caution)/refactor --extract <pattern>
Extract method, class, or module from a target. The <pattern> describes what to extract:
method:<function-name> -- extract a section of a long function into a named helpermodule:<file> -- split a god file into focused modulesclass:<class-name> -- extract a class into its own fileEvery refactoring step must be verified by running tests before proceeding to the next step.
No batching. No "I'll run tests after all changes." Each transformation is atomic:
Transform -> Test -> Pass? -> Commit -> Next
|
No -> Revert -> Re-analyze
Run the full test suite for the target scope BEFORE making any changes.
Go projects:
cd cli && go test ./...
Python projects:
pytest
If tests fail: STOP. Do not refactor code with a broken test suite. Fix the failing tests first, or scope your refactoring to exclude the broken area.
Record the baseline:
Target mode: Read the target code. Identify:
Sweep mode: Run /complexity on the scope to get a ranked list of targets:
/complexity <scope>
Sort by complexity score descending. Work the worst offenders first.
Extract mode: Read the target and identify the extraction boundary:
For each target, produce a numbered list of specific transformations:
1. Extract lines 45-78 of processConfig() into validateConfig()
2. Replace nested if/else at line 92 with guard clause + early return
3. Rename `cfg` to `clusterConfig` for clarity
4. Inline single-use helper `tmpName()` at line 120
For each transformation, identify:
If no tests cover the target: write tests FIRST. Do not refactor untested code.
For EACH transformation in the plan:
Apply a single, focused change. Do not combine multiple transformations. Keep the diff minimal and reviewable.
# Go
cd cli && go test ./...
# Python
pytest
# Or the project-specific test command
Tests pass:
refactor(<scope>): <description>
Examples:
refactor(goals): extract validateConfig from processConfigrefactor(hooks): simplify conditional logic in pre-push gaterefactor(cli): reduce parameter count in NewCommandTests fail:
Repeat 3a-3c for each planned step. After completing all steps for a target, move to Step 4.
After all transformations are complete:
Run full test suite -- not just the targeted tests, the entire suite:
cd cli && go test ./...
Run complexity analysis on changed files:
/complexity <changed-files>
Compare before/after metrics:
| Metric | Before | After | Delta |
|---|---|---|---|
| Cyclomatic complexity | ? | ? | ? |
| Lines of code | ? | ? | ? |
| Function count | ? | ? | ? |
| Max nesting depth | ? | ? | ? |
| Test count | ? | ? | ? |
Verify no behavioral change -- the refactored code must do exactly what the old code did. If tests were added, they must pass against BOTH the old and new code.
Write a refactoring summary to .agents/refactor/:
mkdir -p .agents/refactor
File: .agents/refactor/YYYY-MM-DD-refactor-<scope>.md
Content:
# Refactor: <scope>
**Date:** YYYY-MM-DD
**Mode:** target | sweep | extract
**Files changed:** <count>
## Targets
- <file:function> -- <what was done>
## Metrics
| Metric | Before | After | Delta |
|--------|--------|-------|-------|
| Cyclomatic complexity | X | Y | -Z |
| Lines of code | X | Y | -Z |
| Max nesting depth | X | Y | -Z |
## Transformations Applied
1. <description> -- <commit hash>
2. <description> -- <commit hash>
## Tests
- Baseline: X passing, Y skipped
- Final: X passing, Y skipped
- New tests added: Z
## Learnings
- <anything worth noting for future refactors>
When: Function exceeds 30 lines, or a block of code has a clear single purpose.
Pattern:
Before: longFunction() { ... block A ... block B ... block C ... }
After: longFunction() { doA(); doB(); doC(); }
doA() { ... block A ... }
doB() { ... block B ... }
doC() { ... block C ... }
Safety: Low risk if inputs/outputs are clear. Watch for:
When: A file exceeds 500 lines, or contains multiple unrelated concerns.
Pattern:
Before: god_file.go (800 lines, 5 concerns)
After: config.go (validation, loading)
metrics.go (collection, reporting)
handlers.go (request handling)
Safety: Medium risk. Watch for:
When: A name is ambiguous, misleading, or uses abbreviations that obscure meaning.
Pattern:
Before: func proc(cfg *C) error
After: func processClusterConfig(config *ClusterConfig) error
Safety: Low risk with tooling. Always:
When: A function or variable adds indirection without adding clarity. Single-use helpers that obscure the flow.
Pattern:
Before: x := getName(item) // func getName(i Item) string { return i.Name }
After: x := item.Name
Safety: Low risk. Verify the inlined code does not have side effects you are hiding.
When: Nested if/else chains exceed 3 levels, or boolean expressions are complex.
Patterns:
Before:
if err != nil {
if isRetryable(err) {
if attempts < max {
retry()
} else {
fail()
}
} else {
fail()
}
} else {
succeed()
}
After:
if err == nil {
succeed()
return
}
if !isRetryable(err) || attempts >= max {
fail()
return
}
retry()
When: A function takes more than 4 parameters.
Pattern:
Before: func deploy(name, ns, image string, replicas int, labels map[string]string, timeout time.Duration) error
After: func deploy(opts DeployOptions) error
type DeployOptions struct {
Name string
NS string
Image string
Replicas int
Labels map[string]string
Timeout time.Duration
}
Safety: Medium risk -- all callers must be updated. Use the struct field convention from go.md: grep all call sites and update each one.
When: Functions, variables, constants, or types are defined but never referenced.
How to identify:
# Go: unused exports
go vet ./...
# Or use staticcheck, deadcode, or unparam tools
# Python: vulture or pylint unused-import
vulture <directory>
Safety: Low risk for truly dead code. But verify:
/complexity -- analyze code complexity metrics/standards -- language-specific conventions/vibe -- validate code quality post-refactor/bug-hunt -- if refactoring uncovers bugs/implement -- if refactoring requires new code