go-code
/go-code
Use when writing or fixing Go code (a behavior-preserving refactor routes to go-code-refactor), whether or not the task has one obvious topic — it loads the go-* skills the task needs and runs the closing gate. Also use when asked to implement a Go package, function, or handler whose declarations and documentation already exist — write the bodies, fill in a stub, replace panic("not implemented") — even if the request names only the package. Use it too when /go-code modifies another workflow (e.g. /opsx:apply /go-code); as a modifier it selects Go rules, not a change name or path.
- Author
- h0rn3t ↗
- Repository
- golang-skills ↗
- Licence
- Apache-2.0
- Last repository change
- 27.10.2026
Assessment and security
- Files in this package
- 3
- Scripts
- 0
- HTML comments
- 0
- URLs in SKILL.md
- 0
No signals detected. Repository changed on 27.10.2026, without references to retired models or APIs.
Apache-2.0, otwarta: można używać i zmieniać, z zachowaniem licencji i informacji o zmianach.
What it does and when to use it
Use when writing or fixing Go code (a behavior-preserving refactor routes to go-code-refactor), whether or not the task has one obvious topic — it loads the go-* skills the task needs and runs the closing gate. Also use when asked to implement a Go package, function, or handler whose declarations and documentation already exist — write the bodies, fill in a stub, replace panic("not implemented") — even if the request names only the package. Use it too when /go-code modifies another workflow (e.g. /opsx:apply /go-code); as a modifier it selects Go rules, not a change name or path.
Triggers from the description
Original author description
Use when writing or fixing Go code (a behavior-preserving refactor routes to go-code-refactor), whether or not the task has one obvious topic — it loads the go-* skills the task needs and runs the closing gate. Also use when asked to implement a Go package, function, or handler whose declarations and documentation already exist — write the bodies, fill in a stub, replace panic("not implemented") — even if the request names only the package. Use it too when /go-code modifies another workflow (e.g. /opsx:apply /go-code); as a modifier it selects Go rules, not a change name or path.
How it works
- Resource Routing
- Workflow
- Route Before The First Edit
- Writing New Code
- Close With The Gate
- Related Skills
SKILL.md preview
---
name: go-code
description: Use when writing or fixing Go code (a behavior-preserving refactor routes to go-code-refactor), whether or not the task has one obvious topic — it loads the go-* skills the task needs and runs the closing gate. Also use when asked to implement a Go package, function, or handler whose declarations and documentation already exist — write the bodies, fill in a stub, replace panic("not implemented") — even if the request names only the package. Use it too when /go-code modifies another workflow (e.g. /opsx:apply /go-code); as a modifier it selects Go rules, not a change name or path.
---
# Go Code Profile
Route Go work to the relevant owners, then close with their verification gate.
> Compatibility: Baseline Go 1.27 (see the plugin repository's COMPATIBILITY.md).
## Resource Routing
Sibling skills resolve relative to this installed directory; scripts run from the target project. A skill is loaded when
its `SKILL.md` is in context: the `Skill` tool where the host has one, else a read of `../<name>/SKILL.md`. Report missing resources.
- `../go-style-core/SKILL.md` — Load on every task (step 2); it carries the idiom card, and its references are read only for a decision the task requires.
- `../go-linting/SKILL.md` — With a shell, load alongside go-style-core at step 2; its gate and receipt verifier close step 6.
- `references/INTENSITY.md` — Read when the prompt carries `lite` or `ultra` (`/go-code ultra <task>`, `ultra mode`): what each level changes.
- `references/NEW-CODE-EXAMPLES.md` — Read when the shape of a Contract Table case, Plain Code body, or budgeted helper is in doubt.
- `../go-code-refactor/references/LADDER.md` — Read before the first edit on every task, unless the session-start hook already printed its ladder: step 5 climbs it for each added entity.
- `../go-code-refactor/references/OVER-ENGINEERING.md` — Read its replacement table only when seeking a simpler existing API.
## Workflow
1. **Resolve invocation.** `$go-code <task>` or `/go-code <task>` selects Go
work; a leading `lite`, `full`, or `ultra` sets the restraint level
([INTENSITY.md](references/INTENSITY.md)), not the task. An invocation inserts this file only; steps 2 and 3 load the
rest. As a modifier (`/opsx:apply add-auth /go-code`) it is never a change
name or path, and the host keeps workflow state, checkpoints, and
delegation policy.
2. **Load `go-style-core` and read the code.** With a shell, load `go-linting`
in the same initial Skill message. `go-style-core` carries the
idiom card. Then inspect repository instructions, `go.mod` (its `go`
directive sets the idiom), neighboring code and tests. Without a shell
tool, step 6 runs nothing and `go-linting` stays unread. A new function,
package, or stub body makes step 4 apply. A fix skips the table but adds
one case that fails on the code before it and passes after
([go-troubleshooting](../go-troubleshooting/SKILL.md#fix-and-regression-proof)),
so `go-testing` is loaded for it too; a restructuring skips both.
3. **Load the owners before the first edit.** Match the task against
[Route Before The First Edit](#route-before-the-first-edit) and load each
matched owner plus every `Also load` entry whose condition holds, all in
one message. When step 4 applies or the task is a fix, `go-testing` is one of them. Select by the decisions being changed: a routine local
variable or `if` triggers no owner. No edit before every selected skill is
in context; add owners when new evidence requires them. Wait for successful
Skill results before the edit message; do not dispatch loads and edits together.
4. **Write the Contract Table, for new code only.** Turn the documentation
and the request into the test file the [Contract Table](#contract-table)
describes before the first production edit: a case written after the body
checks only what the body already does. Its cases are what step 6 runs or
reads.
5. **Implement the authorized scope.** Every task — new code, a fix, a
restructuring — climbs the restraint ladder in
[LADDER.md](../go-code-refactor/references/LADDER.md#the-restraint-ladder)
before each helper, type, layer, interface, option, or import it adds,
once per entity, and a fix lands at the root cause the ladder names. New
code takes the [Plain Code](#plain-code) form, counts every package-level
declaration that survives the ladder in the
[Declaration Budget](#declaration-budget), and gets the
[Delete Pass](#delete-pass) and [Reader Pass](#reader-pass) once its cases
pass. Restructuring follows the
[delete-first priority](../go-code-refactor/SKILL.md#delete-before-you-restructure). Preserve
required behavior, validation, security controls, and meaningful tests. A
task that does not ask for a dependency adds none: `go.mod` stays as it
is, and a test compares with the standard library
([go-testing](../go-testing/SKILL.md#assertions-match-the-repository) owns
the assertion rule). Resolve routine choices without stopping; ask only
for missing information that changes correctness, scope, or authorization.
6. **Verify and report.** With a shell, **load the `go-linting` skill**
(`Skill` tool with the router's namespace, otherwise read its `SKILL.md`),
select the gate scope, then run the Contract Table file with that gate.
Hook receipts count only as [go-linting](../go-linting/SKILL.md#verification-gate)
verifies them. Without a shell, read each case against its code path.
Report as [go-style-core](../go-style-core/SKILL.md#how-much-to-say) says,
in this shape and order:
```text
<what the change does, in one sentence>
checks: gofmt pass · vet pass · test -race pass · lint pass
added package-level declarations: 1 — parseLimit: handleList, handleSearch
<one sentence per material gap, or nothing>
```
Name the test file and result, not each case.
## Route Before The First Edit
The third column adds owners only under its stated condition. Prefer the
narrower owner when topics overlap; a local or unexported identifier alone
does not require `go-naming` or `go-documentation`.
| Task touches | Skill | Also load |
|---|---|---|
| errors, wrapping, `errors.Is`/`errors.AsType` | [go-error-handling](../go-error-handling/SKILL.md) | — |
| goroutines, channels, mutexes, races, timers and tickers | [go-concurrency](../go-concurrency/SKILL.md) | [go-context](../go-context/SKILL.md) if anything is cancelled |
| `context.Context`, timeouts, cancellation | [go-context](../go-context/SKILL.md) | [go-concurrency](../go-concurrency/SKILL.md) if goroutines are started |
| tests, table-driven cases, `synctest` | [go-testing](../go-testing/SKILL.md) | — |
| API naming changes or a naming question | [go-naming](../go-naming/SKILL.md) | — |
| new or changed exported API, doc comments | [go-documentation](../go-documentation/SKILL.md) | [go-naming](../go-naming/SKILL.md) if API names change; [go-functions](../go-functions/SKILL.md#changing-an-exported-api) if an existing exported signature, interface, or struct changes |
| interfaces, embedding, test doubles, pointer vs value receivers | [go-interfaces](../go-interfaces/SKILL.md) | — |
| function API design, constructor configuration, ordering, signatures, `Printf` helpers | [go-functions](../go-functions/SKILL.md) | — |
| slices, maps, arrays, sets | [go-data-structures](../go-data-structures/SKILL.md) | — |
| declaration, enum, or initialization decisions | [go-style-core references](../go-style-core/SKILL.md#resource-routing) | — |
| loop/switch mechanics or statement scoping decisions | [go-style-core references](../go-style-core/SKILL.md#resource-routing) | — |
| type parameters, constraints, generic methods | [go-generics](../go-generics/SKILL.md) | — |
| `slog`, log levels, request-scoped fields, metrics and trace correlation | [go-logging](../go-logging/SKILL.md) | [go-security](../go-security/SKILL.md) if a secret or PII could reach a log line |
| panic/recover and `Must` helpers, a deferred closure or a written file's `Close`, boundary copies, mutable globals, nil/aliasing/overflow traps, `time.Time`/`Duration` values | [go-defensive](../go-defensive/SKILL.md) | — |
| a cache, hot paths, allocations, benchmarks | [go-performance](../go-performance/SKILL.md) | [go-troubleshooting](../go-troubleshooting/SKILL.md) if the cause of slowness is unknown |
| package layout, imports, dependencies | [go-packages](../go-packages/SKILL.md) | — |
| restructuring or deleting existing code | [go-code-refactor](../go-code-refactor/SKILL.md) | — |
| linter config, CI checks | [go-linting](../go-linting/SKILL.md) | — |
| HTTP handlers, routing, middleware, servers, clients; gRPC services and clients | [go-http](../go-http/SKILL.md) ([GRPC.md](../go-http/references/GRPC.md) for gRPC) | [go-security](../go-security/SKILL.md) if input reaches a file, shell, URL, or template |
| SQL queries, transactions, repositories, migrations | [go-database](../go-database/SKILL.md) | [go-security](../go-security/SKILL.md) if a request value picks a row by ID or names a column, table, or sort order |
| untrusted input, secrets, tokens, TLS, cookies | [go-security](../go-security/SKILL.md) | [go-defensive](../go-defensive/SKILL.md) |
| retries, idempotency, circuit breakers, overload, backpressure, fallback | [go-resilience](../go-resilience/SKILL.md) | the HTTP, SQL, context, or concurrency owner when its mechanics change |
| ticket, wrong result, environment regression, panic, hang, leak, flaky test; cause unknown | [go-troubleshooting](../go-troubleshooting/SKILL.md) | the owner of the mechanism once found |
| JSON and other wire formats, struct tags | [go-http](../go-http/SKILL.md) ([JSON-V2.md](../go-http/references/JSON-V2.md)) | [go-defensive](../go-defensive/SKILL.md) (tags) |
| CLI entry point, flags, `main`/`run` | [go-packages](../go-packages/SKILL.md) | — |
| a list of findings from a review or audit | the rows the findings name | per area, not per task |
## Writing New Code
Start at the required entry point and its callers. Implement the documented
success and failure paths within the existing API; design a new API only when
the task calls for one. A stub's `panic("not implemented")` is missing
behavior, not a refactor contract: replace it and satisfy the acceptance
tests.
### Contract Table
Before the first production edit, turn the documentation and the request into
a table-driven test in the package — a new `<pkg>_contract_test.go`, or cases
added to the existing test file — one case per observable clause of the
documentation, not per branch of the body
([go-testing](../go-testing/SKILL.md#what-earns-a-test) says which cases earn
a place): each request or input class, each method and status code,
ordering, the error a caller matches and any error text the documentation
promises, and the empty, nil, and invalid inputs; a clause that
says what the code must *not* do is a case too. The empty case is built from
nil — a nil slice, a nil map, a request with no body — not from an empty
literal: `[]T{}` already has the shape the case is meant to prove, and
`slices.Clone` of nil is nil. A case for a list that may come back empty
compares the body text with `[]` (`strings.TrimSpace(rec.Body.String())`),
never a decoded value:
`json.Unmarshal` decodes `null` to a nil slice and `[]` to an empty one, both
of length zero, and the case passes on the one body the contract forbids. A
clause written as a class — "any other method", "any other value" — takes its
case from the member a library default treats unlike the rest: for "any method
other than `GET`" that is one `HEAD` request per `GET` path, the health check
included, since a `GET` pattern answers `HEAD` with 200 on its own.
Where a case contradicts a standard-library default — a nil slice encoding as
`null`, a `GET` pattern answering `HEAD` with 200 — the contract wins, and the
default is overridden in code rather than explained in prose. A failing or
unrunnable case is reported as such, never deleted or weakened to pass; an
expectation that turns out wrong is corrected against the documentation, not
against the implementation. The file is plain code too: one case struct, one
table, one `t.Run` loop, and a failure message in the `Func(input) = got, want`
form; [go-testing](../go-testing/SKILL.md) owns the table-test form, and
[NEW-CODE-EXAMPLES.md](references/NEW-CODE-EXAMPLES.md) shows a worked table.
### Plain Code
The body reads as the documentation reads: reject invalid states early, then
do the main work in its natural order. Return directly when that makes the
result clear; do not introduce a result variable to enforce one final return.
This applies to the entry point, anything it calls, and the contract test.
- **Vocabulary from the specification.** The doc comment's nouns name the
variables.
- **Smallest scope that works.** A document built in one function is an
anonymous struct or a type declared inside that function; a step done once
is inline unless it sits at another level of abstraction
([Declaration Budget](#declaration-budget) rule 4); an error carrying
context is `fmt.Errorf("op %q: %w", key, err)`, matched by the caller with
`errors.Is`.
- **Names that explain, states that stay.** An intermediate value gets a name
when its expression nests deeper than one call or the name says what the
expression does not; otherwise it is written where it is used. A fact the
code tracks — what was already asked for, what was sent, what failed —
keeps its own variable even when another one almost holds it.
- **A comment states what the code cannot show**, never a narration of the
next line; [go-style-core](../go-style-core/SKILL.md#formatting) owns
comment style and [the early return](../go-style-core/SKILL.md#reduce-nesting).
- **Use a standard-library operation when it states the intent more clearly**
(the idiom card lists them); a loop that tracks several related facts may
read better as a loop. Check ordering, ownership, and nil-versus-empty
results. [Reach For What Go Ships](../go-code-refactor/references/OVER-ENGINEERING.md#reach-for-what-go-ships)
lists replacements; [go-data-structures](../go-data-structures/SKILL.md)
owns collection semantics.
- **New JSON is `encoding/json/v2`.** A package with no `encoding/json` import writes
`import json "encoding/json/v2"` (Go 1.27) and no `make([]T, 0, n)` for the wire; one on v1 keeps v1.
[JSON-V2.md](../go-http/references/JSON-V2.md#defaults-that-can-change-the-contract) owns what each writes for nil.
- **Neighbors set the register.** Where the package has code, match its
naming and comment density ([House Style](../go-style-core/SKILL.md#house-style-wins)).
Not its Go version: the current form at the module's `go` directive is
written even beside an older neighbor
([Write Current Go](../go-style-core/SKILL.md#write-current-go)).
[NEW-CODE-EXAMPLES.md](references/NEW-CODE-EXAMPLES.md) carries a whole
documented JSON document in this form.
### Business Rules
Code that carries multi-step business rules — intervals, history or snapshot
processing, reconciling against a set of properties, branching on mode or
role — is written as a chain, new or refactored; plain CRUD and glue code are
exempt.
- **The entry point is the chain.** Each step's result is a named value the
next step takes: `a := step1()`, `b := step2(a)`, `c := step3(a, b)`. The
whole algorithm and its key branches read in that function or one level
below it. A struct holding the call's dependencies (`ctx`, `tx`, the input)
may carry the steps as methods; a fluent chain that passes intermediate
results through struct fields hides the data flow and is not written.
- **Effects at the top, logic below.** Deep functions return data; writes and
external calls happen in the entry point or a step of its chain. Lifting an
effect keeps the order and count of writes
([BEHAVIOR-TRAPS.md](../go-code-refactor/references/BEHAVIOR-TRAPS.md#pre-commit-checklist)).
- **Untyped data is parsed once.** A map, a JSON document, or a database row
becomes a typed struct in one place, which returns the parse error; the
decisions and comparisons after it are pure functions with no `error`
result. Checking the value types and converting them is that one pass, not
a validation loop followed by a second `switch v.(type)` in the matcher:
the matcher takes the typed struct, never the `map[string]any`, and holds
no type switch or assertion.
- **A step earns its function** by the [Declaration Budget](#declaration-budget):
a step of the entry point's chain, or a pure step below it, is rule 4's
other level of abstraction even with one call site. Three steps are named
here because a body written behind one signature folds them in: the parse
of untyped data into its typed struct, the pure match or decision on that
struct, and the interval or set arithmetic. Each is a package-level
function, not a closure inside the entry point, which keeps the step names,
the branches, and the writes and stays within about 40 lines. Any other
wrapper around one expression or one error check is inlined. Its name says what the
step means in the domain, not the library call behind it: verb-like for an
action or a predicate (`subtract`, `matches`), noun-like for a value it
returns (`processingInterval`); `leftDifferences` names the mechanism and
`processReminder` names nothing
([go-naming](../go-naming/references/IDENTIFIERS.md#naming-conventions)
owns the conventions).
- **Leave complexity headroom.** Before a function grows or two merge, read the
service's complexity linters in its golangci config (`gocyclo`, `gocognit`,
`funlen`, `nestif`) and stay clear of their limits, not at them.
A fragment of an entry point in that shape; `b` holds only the dependencies,
`bindCombination` writes by snapshot and returns what it left uncovered, and
inside it `readSnapshot` parses each snapshot once so `matches` stays pure:
```go
interval, ok, err := b.processingInterval()
if err != nil || !ok {
return false, err
}
snapshots, err := b.loadSnapshots(interval)
if err != nil {
return false, err
}
remainders, err := b.bindCombination(interval, snapshots)
if err != nil {
return false, err
}
if !data.Bind {
return true, nil // unbind leaves values outside the combination alone
}
for _, r := range remainders {
if err := b.clear(r); err != nil {
return false, err
}
}
return true, nil
```
### Delete Pass
When the Contract Table passes, walk the diff once, top to bottom, and delete
what the test already proves or the code already shows. Each item below is a
line a reviewer sends back:
- A comment that narrates the next line or repeats what the code already
shows. A comment giving a reason the code cannot show stays.
- A name used once that explains nothing, and the variable it fills: the
value is written where it is used. A name that passes the Plain Code test
stays.
- A field, header, or option set to what the library uses when it is
absent: `MaxHeaderBytes: 1 << 20` is `http.DefaultMaxHeaderBytes`,
`Content-Type: text/plain; charset=utf-8` before `w.Write([]byte("ok"))` is
what the writer sniffs for a body the code fixes — a body that carries
input keeps its `Content-Type` ([go-security](../go-security/SKILL.md)) —
and `false`, `0`, `nil`, or `""` in a keyed literal is the zero value. The
line says nothing its absence does not.
- A `fmt.Errorf` wrap that only restates the call: `return json.Marshal(doc)`.
The failure branch stays, since `json.Marshal` fails on input (invalid
UTF-8 or a `time.Duration` under v2, NaN under v1) and a handler keeps its
500; a branch on a call documented never to fail — `(*bytes.Buffer).Write`,
`(*strings.Builder).WriteString`, `hash.Hash.Write` — goes. A write whose
error has nowhere to go is discarded in the open, `_, _ = w.Write(body)`
with its reason, never bare: `errcheck` in the gate reads a bare call as a
finding, and the reason on that line is not a comment to delete.
- A doc comment on an unexported helper beyond one line;
[go-documentation](../go-documentation/SKILL.md) owns the exported ones.
The pass runs behind the test, never ahead of it: a line a case needs stays,
and validation at a trust boundary, failure behavior, and security controls
are not deleted for a smaller diff. Rerun or reread the cases after it.
### Reader Pass
Read the changed path from its entry point to its result or side effect. Can a
reader find the main decision, error exits, and state the code tracks without
chasing wrappers that only rename an operation? Keep a one-use name when it
exposes a meaningful boundary or state; keep a helper when it hides details
that obscure the caller's decision. If either adds a jump without answering a
reader's question, inline it and run the cases again.
### Declaration Budget
The specification already declares what the task needs: a body behind an
existing signature adds no package-level declaration by default, and the count
of those it does add is what the report carries. Count every function, method,
type, interface, and variable added at package level in production code across
the whole diff; [go-testing](../go-testing/SKILL.md) owns test helpers. A
declaration is written when the code shows the need at the moment it is
written:
1. Two call sites exist in the diff, and the report names both.
2. A caller outside the function names it: it reads a field through
`errors.AsType`, satisfies an interface a consumer declares
([go-interfaces](../go-interfaces/SKILL.md) owns the shape), or owns a
resource whose lifetime outlives one call. A caller that *inspects* or
*matches* an error reads no field: it uses `errors.Is` on the wrapped
sentinel, and that needs no type.
3. It is a distinct algorithm — a parser, a scheduler — whose name at the
call site says more than its body would, and the body left behind reads
top to bottom without it.
4. It is a step at another level of abstraction than the rest of the
function — building SQL beside the domain rule — even with one call site;
the report names its caller and this rule. A helper whose name only
restates two or three lines of its body is not such a step: those lines
stay inline. In multi-step business rules the parse, the pure match, and
the interval arithmetic are such steps ([Business Rules](#business-rules)).
A function literal bound to a name that captures nothing from the function
around it counts under the same four rules: the count is a record, not a
score, and hiding a helper inside a function changes the number without
changing the code. A closure is for capturing state, and a handler registered
once is written at its registration; the values routes share are locals of
the constructor that the handler literals capture, not fields of a `server`
type with one method per route.
A representation is a value, not a reason: a wire document, a formatted error,
and a sorted view take the [Plain Code](#plain-code) form. A helper that names
a step at its caller's own level of abstraction meets none of the four; write
the step inline.
The named helpers in skill examples (`validate`, `writeJSON`, `writeError`)
show the order of an operation, not a list to reproduce.
The budget counts what survives the restraint ladder in
[LADDER.md](../go-code-refactor/references/LADDER.md#the-restraint-ladder),
climbed per declaration before the four rules are checked. Never trade input validation at a trust boundary,
failure behavior, or a security control for a smaller count.
The report carries one line — `added package-level declarations: N` — and,
for each, its name and the call sites or caller that need it. A declaration
whose line cannot name them is removed before the report is written, not
explained in it.
## Close With The Gate
Select checks with [go-linting](../go-linting/SKILL.md#verification-gate) for
the requested scope; a repository gate replaces the defaults rather than
joining them. Bundled scripts add evidence the gate lacks:
- Error handling: `bash <installed-skill-dir>/../go-error-handling/scripts/check-errors.sh ./...`.
- Exported API documentation: `bash <installed-skill-dir>/../go-documentation/scripts/check-docs.sh`.
- Before submitting: [go-code-review](../go-code-review/SKILL.md).
`<installed-skill-dir>` is the directory the host loaded this file from; each
command runs from the project with that path written out, through `bash`: an
install can drop the scripts' executable bit.
Run routine checks inline. The report carries only results observed for the
current diff and scope, each as `pass`, `fail`, `unavailable (reason)`, or
`skipped (reason)` per go-linting.
## Related Skills
- Every owner in [Route Before The First Edit](#route-before-the-first-edit).
- [go-style-core](../go-style-core/SKILL.md): house style, report length, and delegation.
- [go-linting](../go-linting/SKILL.md): the closing gate.
- [go-code-review](../go-code-review/SKILL.md): the checklist before submitting.
Files in this package (3)
- SKILL.md 25 KB
- references/INTENSITY.md 2 KB
- references/NEW-CODE-EXAMPLES.md 4 KB
Versions
The database has no other skills named go-code.
Database snapshot: 13.11.2026 · package version 57c98d198cd2 (SHA-256 digest of the entire package)
Downloads in the last 30 days: 0 · ranking
Report a problem with this skill: harmful content, incorrect descriptions or an author’s removal request.
Similar skills
- 100test-driven-development
Build features and fix bugs test-first with red-green-refactor: write one failing test, watch it fail for the right reason, write the least code that makes it pass, then refactor while green. Use this skill whenever you implement a feature, add a function or endpoint, change… - 100refactor
Refactor existing code with impact analysis first. Routes to tech-lead for blast-radius assessment, then engineers, with heavy emphasis on test coverage. Use when restructuring code with no intended behavior change. Trigger this when someone says: refactor this, clean up this… - 100refactor-code
Use this skill whenever the user wants to actually refactor, rewrite, modernize, or transform existing code. Triggers include: "refactor this", "rewrite this code", "convert to hooks", "modernize this", "extract utilities", "clean up this code", "apply the refactor plan",… - 84refactor-code
Refactor code with safety checks and pattern application. Use when user says "refactor this code", "clean up this function", "simplify this logic", "extract this into a separate function", "apply the strategy pattern here", "reduce the complexity of this module", or "reorganize this file structure". - 90dev-refactor-plan
Use when the user asks for a behavior-preserving refactor plan before implementation. Do not trigger when the user already requested a clear, scoped refactor to be implemented directly. - 100refactor
Safe refactoring with test guard — improve code quality without changing behavior. Use when: refactor, cleanup, restructure, simplify, extract function, improve code quality.