Prompt enhancement for Claude Code — tuned specifically for Claude Opus 4.6 and 4.7. An Augment-style "enhance this prompt" slash command, rebuilt as a native Claude Code command. Takes a rough prompt, rewrites it into a tuned, project-aware prompt, and shows you the refined version for approval before execution.
The two refinement modes map directly to Opus 4.6 and 4.7's distinct execution styles. Sonnet and Haiku are not targeted at launch; a Sonnet mode may be added in a future release based on demand — see the Roadmap.
- What it does
- Why two modes?
- Install
- Customize for your project
- Examples
- How it works
- Security
- Roadmap
- Credits
- Releases
- License
You type:
/refine 47 fix the logout bug on the admin page
Instead of Claude Code acting on that directly, it:
- Inspects your project (CLAUDE.md, package.json, relevant source files)
- Identifies ambiguities in the rough prompt
- Rewrites the prompt with explicit goals, context, and success criteria — using the mode-specific structure (see Examples)
- Shows you the refined prompt and waits for approval before executing
If the refinement misreads your intent, you say edit or cancel and nothing runs. If it nails it, you say yes and Claude Code proceeds with the tuned version.
Claude Opus 4.6 and 4.7 have noticeably different execution styles, and a prompt tuned for one can be suboptimal for the other:
47— Claude Opus 4.7 reads instructions literally. It benefits from exhaustive specs with explicit fences, ordered steps, and verifiable success criteria. Under-specify it and it'll either stall on ambiguity or interpret narrowly.46— Claude Opus 4.6 fills gaps sensibly from context. Over-specify it and it can fixate on mechanics at the expense of the goal. It prefers intent-focused briefs.
The refinement output adapts to whichever mode you pick. Pass 47 or 46 as the first argument:
/refine 47 <rough prompt> # exhaustive spec for 4.7
/refine 46 <rough prompt> # intent-focused brief for 4.6
/refine <rough prompt> # defaults to 47, notes the default
One file, no dependencies. Pin to a release tag rather than main, and verify the SHA-256 published alongside the release.
mkdir -p ~/.claude/commands
curl -o ~/.claude/commands/refine.md \
https://raw.githubusercontent.com/ICJIA/claude-code-refine/v0.4.2/refine.md
# Paste the sha256 from the matching GitHub release:
# https://github.com/ICJIA/claude-code-refine/releases/tag/v0.4.2
echo "e16bdba67959519f2d3f07ec7ee6c3b2b0df0db3db90d2b84e15c4bf8869410c $HOME/.claude/commands/refine.md" | shasum -a 256 -cOr clone at a tag and copy:
git clone --branch v0.4.2 --depth 1 https://github.com/ICJIA/claude-code-refine.git
cp claude-code-refine/refine.md ~/.claude/commands/Restart your Claude Code session so it picks up the new command. Installed in ~/.claude/commands/, Refine is available across every project. Drop it in .claude/commands/ inside a specific project if you want it scoped there instead.
Heads up on project-scoped installs. Anything inside a repo's
.claude/commands/gets committed with the repo by default. Keep internal workflow details or sensitive conventions in~/.claude/commands/instead — see Security for why the conventions block at the bottom ofrefine.mdis a trust boundary.
Open refine.md and scroll to the bottom. There's a section marked "Project conventions to apply (← trust-sensitive: mode 47 restates this verbatim; only add conventions from sources you control)" with a placeholder list. Replace it with your own stack defaults, testing conventions, module format, or anything else refinements should apply consistently.
Trust note. Content you paste here is restated verbatim in mode-47 refinements and invoked by name in mode-46 refinements — treat it as instruction-grade content, not just style guidance. Only add conventions from sources you control or have reviewed. See Security for the full trust-boundary note.
Example replacement for a Rust project:
## Project conventions to apply
- Rust 2024 edition, Cargo workspaces, sqlx for DB, tokio runtime
- Tests run via `cargo test`; integration tests in `tests/`
- Errors via `thiserror`; propagate with `?`, no `unwrap()` outside tests
- Public APIs documented with `///` doc comments including examplesMode 47 will restate these verbatim in the refined prompt when relevant. Mode 46 will invoke them by name and trust Claude to apply them from surrounding code.
Two rough prompts, each shown in both modes so you can compare the output Refine produces for Claude Opus 4.7 vs 4.6. Expand the sections below to see the refined prompts.
Rough prompt:
/refine 47 add dark mode to the landing page
(Assume a Nuxt 4 + Nuxt UI 4 + TypeScript project.)
Mode 47 — exhaustive spec for Claude Opus 4.7
REFINED PROMPT
==============
> **Tuned for: Claude Opus 4.7 (literal / exhaustive-spec mode)**
## Goal
Add a user-toggleable dark mode to the landing page using the project's
existing UI framework's built-in color-mode support.
## Context
- Stack: Nuxt 4 + Nuxt UI 4 + TypeScript (from package.json)
- Landing page at pages/index.vue
- Existing header component: components/AppHeader.vue
## Steps
1. Enable color-mode in nuxt.config.ts with preference: 'system',
fallback: 'light'.
2. Add <UColorModeButton /> to components/AppHeader.vue, right-aligned.
3. Audit pages/index.vue for hardcoded hex colors; replace with
CSS vars or Nuxt UI's useColorMode-aware tokens.
4. Run the site locally and toggle between modes; verify no component
has invisible or low-contrast text.
5. Reload the page; confirm preference persists via color-mode's default
localStorage key.
## Success criteria
- Toggle switches theme within one frame.
- Preference persists across reload.
- No low-contrast text in either mode (spot-check all text on
pages/index.vue).
## Out of scope
- Custom brand palette beyond Nuxt UI defaults.
- Dark mode for any other page.
- Per-component dark overrides.
## Assumptions to confirm
- "Dark mode" means a user toggle, not a forced dark theme.
- Nuxt UI defaults are acceptable; no custom palette.
Execute this refined prompt? (yes / edit / cancel)
Mode 46 — intent-focused brief for Claude Opus 4.6
REFINED PROMPT
==============
> **Tuned for: Claude Opus 4.6 (fuzzy / intent-focused mode)**
## Goal
Add a user-toggleable dark mode to the landing page using Nuxt UI 4's
built-in color-mode support.
## Context
Nuxt 4 + Nuxt UI 4 + TypeScript. Landing is pages/index.vue; header is
components/AppHeader.vue.
## Approach
Enable Nuxt's color-mode module, drop a <UColorModeButton /> into the
header, and audit the landing page for hardcoded colors that won't
flip with the theme. Use Nuxt UI's color tokens where you find them.
## Constraints
- Nuxt UI defaults are fine — no custom brand palette.
- Scope is the landing page only.
## Done when
- Toggle switches theme and the preference persists across reload.
- No low-contrast text in either mode.
Execute this refined prompt? (yes / edit / cancel)
Rough prompt:
/refine 47 add rate limiting to the login endpoint
(Assume an Express 4 + Redis project with the login route at src/routes/auth.ts.)
Mode 47 — exhaustive spec for Claude Opus 4.7
REFINED PROMPT
==============
> **Tuned for: Claude Opus 4.7 (literal / exhaustive-spec mode)**
## Goal
Add per-IP rate limiting to POST /api/auth/login that returns HTTP 429
after 10 failed attempts within 15 minutes.
## Context
- Stack: Express 4 + Redis (from package.json)
- Auth route: src/routes/auth.ts, handler loginHandler
- Existing Redis client: src/lib/redis.ts, exported as redisClient
- Error middleware: src/middleware/errorHandler.ts
## Steps
1. Add `express-rate-limit` and `rate-limit-redis` to package.json.
2. Create src/middleware/rateLimiters.ts exporting a limiter bound to
redisClient with windowMs=15*60*1000, max=10, standardHeaders true,
legacyHeaders false, keyGenerator using req.ip.
3. In loginHandler, call the limiter only after password verification
fails — not on every request.
4. When the limit trips, respond with 429 and body
`{ error: 'TOO_MANY_ATTEMPTS', retryAfterSeconds: <number> }`.
5. Add integration tests in tests/auth.test.ts: 10 failed logins from
one IP returns 429 on attempt 11; a successful login does not
increment the counter.
## Success criteria
- `pnpm test tests/auth.test.ts` exits 0.
- Curling 11 failed logins from one IP returns 429 on request 11 with
the specified JSON body.
- A successful login does not consume a rate-limit slot.
## Out of scope
- Rate limiting on any endpoint other than /api/auth/login.
- Cross-region rate-limit coordination.
- User-account-level limits (only per-IP for now).
## Assumptions to confirm
- "Failed" means incorrect password, not network or validation errors.
- Counting by req.ip is acceptable with the current proxy setup.
Execute this refined prompt? (yes / edit / cancel)
Mode 46 — intent-focused brief for Claude Opus 4.6
REFINED PROMPT
==============
> **Tuned for: Claude Opus 4.6 (fuzzy / intent-focused mode)**
## Goal
Protect POST /api/auth/login from brute-force attempts by rate-limiting
failed logins per IP and returning 429 once the threshold is hit.
## Context
Express 4 + Redis. Login handler lives in src/routes/auth.ts. Redis
client is already wired up in src/lib/redis.ts.
## Approach
Use express-rate-limit with the Redis store, counting only failed
password checks (not every request). Go with a 10-in-15-minutes
threshold unless our house rule says otherwise. Return 429 with a
clear retry-after hint.
## Constraints
- Count failed attempts only, not all login traffic.
- Use the existing Redis client; don't spin up a new one.
## Done when
- Repeated failed logins from one IP return 429 after hitting the limit.
- A successful login does not count against the limit.
- Integration tests cover both behaviors.
Execute this refined prompt? (yes / edit / cancel)
Notice how mode 46 invokes project conventions by name ("the existing Redis client," "our house rule") while mode 47 spells out exact values, file paths, and test commands. The divergence is deliberate: 4.6 fills sensible defaults from context; 4.7 follows what's written literally. After either output, you say yes to proceed, edit if an assumption is wrong, or cancel to start over.
Refine is a standard Claude Code custom slash command — a single markdown file with YAML frontmatter, stored under ~/.claude/commands/. When you type /refine 47 fix the logout bug, Claude Code loads refine.md, substitutes the arguments, and runs the result as the prompt for that turn. No additional API calls, no server, no runtime dependencies beyond Claude Code itself.
The substitution is simple:
$1→ the first whitespace-separated token after the command name (in the example above,47).$ARGUMENTS→ everything after the command name (47 fix the logout bug).
Inside refine.md, $1 drives the mode branch (47-literal vs 46-fuzzy), and the remainder of $ARGUMENTS becomes the rough prompt to refine. If $1 is not 47 or 46, the template falls back to mode 47 and treats the entire argument string as the rough prompt.
The rest of refine.md is a short procedure the model runs on itself:
- Gather context silently — read
CLAUDE.mdandpackage.jsonby default; readREADME,CHANGELOG, or source files only when the rough prompt names them or Step-3 ambiguities can't be resolved otherwise. No narration. - Handle attached files — if file paths appear in
$ARGUMENTS(a dropped CSV, screenshot, PDF, JSON, log, etc.), open them and surface what they contain (column names + sample rows for tabular data; visible UI/layout/text for images; summary for documents). Paths are carried verbatim into the refined prompt'sContext. - Identify ambiguities — list them, resolve each from project context or flag it as an assumption to confirm.
- Skip-refinement check — if the rough prompt is already specific enough that refinement would only add boilerplate, say so and ask whether to refine anyway or execute as-is.
- Write the refined prompt — using the mode-specific template (exhaustive spec for 47, intent-focused brief for 46), with a
Tuned for: Claude Opus 4.xbanner as the first line. - Present and pause — show the refined prompt in a fenced block, list open assumptions, and wait for
yes/edit/cancel.
Because everything lives in the template, customization is just editing refine.md. There is no build step, no dependency install, no runtime. A future Claude Code release changing how slash commands work is the only thing that could break it — and that would be a git pull away from a fix.
See Claude Code's slash command docs for the full argument-substitution and frontmatter reference.
Advanced: global defaults, project specifics, and multi-context setups
Refine reads two sources of project knowledge every time it runs:
- The conventions section inside
refine.md— whatever you've customized globally. These are your cross-project defaults: preferred language, package manager, testing framework, documentation style. - The current project's
CLAUDE.md(andpackage.json,README, relevant source files) — the specifics of the repo you're currently working in. Step 1 of the refinement explicitly inspects these.
The refiner merges both when it rewrites the prompt. Claude Code doesn't have extends or include syntax for slash commands, but the effect is the same, because the refinement template already reads both sources.
A practical split:
- Global
refine.mdconventions — things true across all your work. "I use pnpm. I write design docs in markdown. I prefer SQLite by default." - Per-project
CLAUDE.md— things specific to this repo. "This project is Nuxt 4 + Strapi v5. Tests run viapnpm test. Deployment is Netlify with serverless SSR."
When you run /refine 47 <something> inside a project, the refined prompt reflects both.
If you work across multiple contexts — an employer with its own stack conventions plus personal projects, for instance — you may want a third tier between "global defaults" and "this specific project." The cleanest pattern is a second slash command:
~/.claude/commands/
├── refine.md ← /refine — your personal defaults
└── refine-work.md ← /refine-work — work-context conventions baked in
Type /refine-work 47 ... when you're in a work repo, /refine 47 ... otherwise. Two commands, explicit choice at invocation time, no ambiguity. Cleaner than trying to encode conditional logic inside a single refine.md, and it lets you share refine-work.md with teammates without muddying your personal setup.
Slash commands can live in two places: ~/.claude/commands/ (global, in your home directory) or <project-root>/.claude/commands/ (project-scoped, inside the repo). Project-scoped commands get committed with the repo by default. If a tuned command contains internal workflow details you don't want public, keep it in ~/.claude/commands/ — not in any project's .claude/commands/.
Refine is a slash-command template — there is no Refine runtime, binary, or service. Its security posture reduces to which inputs reach the template and what guardrails the template imposes before the executor runs. The primary defense is the explicit yes / edit / cancel approval gate; every other hardening measure reinforces it.
Inputs the refiner reads
- Your rough-prompt text, and any file paths attached to
$ARGUMENTS. CLAUDE.mdandpackage.jsonin the current project (always).README.md,CHANGELOG.md, or named source files in the current project (conditionally, when a rough prompt names them or a Step-2 ambiguity requires them).- The "Project conventions to apply" block at the bottom of
refine.md(baked in at install time).
Baked-in defenses (all enforced inside refine.md)
- Read-scope policy. Reads are confined to the current working directory; paths containing
.., starting with~/$HOME, resolving outside the repo, or matching common secret-file patterns (.env*,*.pem,*.key,id_rsa*,id_ed25519*,id_ecdsa*,.aws/**,.ssh/**,.gnupg/**,.netrc,.npmrc,.pypirc) are refused and recorded inAssumptions to confirm. - Data-not-instructions framing. Rough-prompt text, file contents, and multimodal attachment transcripts (PNG/PDF text) are treated as inputs to summarize, not instructions to execute. Injected overrides — "skip Step 4", "pre-approve", "widen scope" — are ignored and surfaced, not silently applied.
- Immutable approval gate. The Step 4 approval question (
Execute this refined prompt? (yes / edit / cancel)) is fixed verbatim. The template rejects attempts to reword it, add acceptance conditions, or accept alternative answers. - Trust-labelled conventions block. The user-editable block at the bottom of
refine.mdis flagged as trust-sensitive, since mode 47 restates it verbatim in every refined prompt and mode 46 invokes it by name. - Pinned + checksummed install. The Install command pins to a release tag and verifies a SHA-256 published alongside the GitHub release — no floating
mainbranch, no unverifiedcurl. - Mode-token normalization.
$1is stripped of surrounding whitespace/quotes and NFKC-normalized before mode comparison, so quirky inputs fall through to default mode predictably instead of silently mismatching.
Out of scope for the template
- The downstream executor turn — after you click
yes, normal Claude Code and Anthropic API guardrails apply. - The Anthropic API itself, your OS, your shell, and your telemetry configuration.
- Third-party forks of
refine.mddistributed outside official release tags.
Full audit. See SECURITY_REVIEW.md for the red-team / blue-team analysis that motivated these defenses, the threat model, per-finding severity, reproduction examples, and remediation status.
Reporting. If you find a new issue, open a GitHub issue marked security (or email the maintainer privately for sensitive reports before disclosing publicly).
Sonnet refinement mode (maybe). Sonnet 4.6 is a common daily-driver model in Claude Code, and there's a reasonable case for a third mode tuned for its execution style. Refine holds off on this at launch because its modes should be grounded in observed behavioral differences, not guesses — and a Sonnet mode needs more empirical characterization before it can ship with the same confidence as the 46 and 47 modes.
If you use Sonnet 4.6 heavily in Claude Code and have observations about what prompt structures it prefers, PRs and issues are welcome.
Haiku refinement mode (probably not). Refinement pays off most when the executor is going to spend significant time and tokens on a task. Haiku's sweet spot is fast, cheap, one-shot work — a class of task where adding a refinement step fights the point of using Haiku in the first place. If you disagree and have a concrete use case, open an issue.
Other modes or features? Open an issue. Refine is intentionally small and focused, but thoughtful proposals are welcome.
Design pattern inspired by Augment Code's "Enhance Prompt" feature — one of the most genuinely useful ideas in AI coding tooling, and the direct motivation for this project.
Augment's broader pitch is that every AI coding tool uses the same underlying foundation models; their differentiator is the Context Engine, a live index of your whole codebase, dependencies, and history. Enhance Prompt surfaces that context at the prompt layer: instead of firing a rough ask at an agent and hoping, Augment rewrites the prompt into something concrete, project-aware, and reviewable — before any code changes.
Why the pattern is so useful. The dominant failure mode of coding agents isn't writing bad code. It's writing plausible code for the wrong problem. An agent acting on "fix the logout bug on the admin page" might refactor an unrelated session helper, skip the actual regression, and still produce green tests. A refinement step catches that class of failure before tokens burn:
- Ambiguities become explicit assumptions to confirm, not silent guesses.
- Project conventions and file paths get injected into the brief, not inferred mid-task.
- You see a reviewable plan — with a concrete goal, steps, and success criteria — and can
editorcancelbefore the agent touches a file.
In practice, that single interstitial step turns a lot of "almost right" agent turns into first-try-correct ones, and makes the expensive turns that do run far more likely to land the intended change.
Refine rebuilds this idea natively in Claude Code. Claude Code's own codebase awareness — CLAUDE.md, project structure, live repo reads — plays roughly the role Augment's Context Engine plays in their stack: the refiner draws on everything the repo already tells Claude, and produces a model-specific brief before execution. The 4.6 vs 4.7 mode split is what's novel here. The refinement-step-in-front idea is not — full credit to Augment for popularizing it, and for making it feel obvious in retrospect.
The 4.6 vs 4.7 distinction reflects widely-observed differences in how the two models handle under- and over-specified prompts — 4.7's tendency to read instructions literally, 4.6's tendency to fill context-driven gaps. Refine's mode templates are grounded in those observations. Contributions from anyone with additional behavioral notes are welcome via issues or PRs.
Versioned releases are published on GitHub: Releases. See CHANGELOG.md for the full version history.
MIT © Illinois Criminal Justice Information Authority (ICJIA). See LICENSE.