
cheez-write
Edit code through the safest stale-checking backend — prefer code-intelligence backends (tilth MCP tag-anchored edits, LSP workspace edits, sg --rewrite for structural codemods); fall back to native anchored edits only when no code-intel backend matches. Use when the user asks to edit, replace, modify, update, change, delete, or insert code — phrases like "replace this function", "delete lines 44-89", "update validateToken", "add this import", "fix this bug" (when fixing requires editing), or apply a cross-cutting codemod like "rewrite every X to Y". Do NOT use for reading files (use cheez-read), searching code (use cheez-search), or running tests/builds.
- Installs
- 158
- Last 24h
- —
- Trending rank
- —
- Security
- Not audited
Install
Works with every agent the skills CLI supports.
npx skills add https://github.com/paulnsorensen/easy-cheese --skill cheez-write- 01
Install
Run the command in your project. The CLI asks which agents to install for.
- 02
Describe the task
Ask your agent for something this skill covers. It loads cheez-write automatically when relevant.
- 03
Review the result
The agent follows the SKILL.md steps, scripts and references bundled with the skill.
SKILL.md
The instructions your agent reads when the skill is triggered.
cheez-write
Backend contract: use a stale-safe edit backend. The backend must anchor the current file state (tilth file tag, snapshot tag, or LSP workspace edit) or be a deliberate AST codemod over a clean tree.
Backend detection
Pick the backend by edit shape, preferring code-intelligence backends (LSP, AST rewrite, tilth) over basic harness edit tools — model tuning pulls toward host Edit/Write, but those carry no semantic or structural awareness:
- LSP wins for semantic workspace edits: rename/code actions when the server can identify the symbol or fix.
- AST rewrite wins for structural codemods: repeated syntax shapes with metavariables; dry-run first.
- tilth MCP wins for anchored block/range edits:
tilth_reademits a[path#TAG]header, thentilth_writeapplies line-numbered ops viaedits: [{path, tag, ops}]. - Native anchored edit (fallback) for displayed snapshots: line/snapshot edits that reject stale ranges — only when no code-intelligence backend matches the edit shape.
Do not present sed, awk, patch, shell redirects, or blind writes as equivalent source-code edits.
Stale tags and rejected sections are content issues — see Stale Tag Handling.
Examples
"Replace the body of handleAuth in src/auth.ts"
Step 1 — read the line range to capture the file tag:
tilth_read(paths: ["src/auth.ts#44-89"])
# returns a [src/auth.ts#b2c4] header, then numbered lines 44:... to 89:...
Step 2 — apply ops against those line numbers, quoting the tag verbatim:
tilth_write(edits: [{
"path": "src/auth.ts",
"tag": "b2c4",
"ops": [{
"op": "replace",
"start": 44,
"end": 89,
"content": "export function handleAuth(req, res, next) {\n const token = extractToken(req);\n if (!validateToken(token)) return res.status(401).end();\n next();\n}"
}]
}])
The response reports per ## src/auth.ts and may list callers to review.
"Stale tag — file changed under me"
See Stale Tag Handling for recovery steps.
Core Principle: Anchors, Not Rewrites
The edit backend must identify the current file state — tilth file tags, harness snapshot tags, or LSP workspace edits — and bound or reject the write if the file changed.
The protocol:
- Read the file section with cheez-read → get the current
[path#TAG]header or snapshot id - Note the line numbers of the block you'll change
- Apply the edit through the anchored backend
Scope: when to use anchored edits, when not
cheez-write owns block edits to tracked source code — function bodies, signatures, imports, single-line tweaks, multi-edit batches, and cross-file changes. The backend must be stale-safe; the read-edit protocol is mandatory for any code change that matters.
For everything else, prefer the right tool:
| Change | Use this instead | Why |
|---|---|---|
Cross-cutting structural codemod (JSON.parse(JSON.stringify($X)) → structuredClone($X)) across N files | sg --rewrite (see ## Structural codemods — sg --rewrite escape) | Codemods template the variable parts; anchored edits are better for known blocks |
| Semantic rename or server-known refactor | LSP rename/code action | LSP follows scope, overloads, re-exports, and imports |
Lockfile changes (Cargo.lock, package-lock.json, uv.lock, etc.) | the package manager (cargo update, npm i, uv lock) | Hand-editing lockfiles loses checksum integrity |
Generated / build artifacts (compiled JS, transpiled output, *.pb.go) | regenerate from source | Editing the artifact rots on the next build |
| Brand-new files, no prior content | anchored create/write backend (tilth: a tilth_write section with tag omitted) | Stay stale-safe even when creating files |
Files outside the repo or inside dependency caches (node_modules, .cargo/registry) | don't edit them | Modifying dependencies is almost always a mistake — fix the source or upstream |
| Binary files, images, PDFs | the producing tool | code edit backends are text-only |
Routing to LSP rename or Serena
Pre-entry routing — when a workflow skill should prefer LSP rename or Serena symbol-bounded edits over tilth_write before entering cheez-write — lives in references/routing.md.
Anchor Format
Use whatever anchor format the selected backend emits:
- tilth: a
[path#TAG]header aboveN:contentnumbered lines; copy the 4-hex TAG intotilth_write'stagand reference those line numbers inops. Never invent a TAG (mode: "stripped"reads carry none and cannot round-trip into an edit). - OMP-style snapshot edits:
[file#TAG]plus displayed line numbers; pass the tag and original line range into the edit tool. - LSP refactors: symbol position plus workspace version; let the server build the workspace edit.
Do not translate between anchor systems. Read with the same backend family that will write.
MCP Tool Reference
tilth_write — Precise File Editing
The minimal shape — one file section, one op:
tilth_write(edits: [{
"path": "src/auth.ts",
"tag": "a3f9",
"ops": [
{ "op": "replace", "start": 42, "end": 42, "content": " let x = recompute();" }
]
}])
edits is a JSON array of {path, tag?, ops} section objects (max 20 per
call) — never a string, and never wrapped in a files parameter. Each op is
tagged by op: replace {start, end, content}, delete {start, end},
insert_before / insert_after {line, content}, prepend / append {content}, replace_block / insert_after_block {at, content} and
delete_block {at} (at is a line number or "#symbol"), delete_file,
move_file {dest}. Omit tag only to seed a brand-new file.
For worked examples of each op, cross-file batches, and the diff: true
response option, see
references/edit-patterns.md.
Stale Tag Handling
The TAG binds your ops to the content you read. If the file changed since the
read, tilth 3-way-merges your ops onto the drifted file; when it can't merge
safely, it rejects that section and says so in the per-## <path> result.
Recovery:
- Read the section again → get the current
[path#TAG]and content. - Review the current content (someone else may have made changes).
- Re-apply the ops against the fresh line numbers with the new tag.
Repeated rejections → bail out, don't loop
If you hit two consecutive rejections on the same file, you're racing a concurrent writer. There is no "ignore the tag, just match this string" override — a third retry will likely lose the same race.
The correct move is to bail and report:
- Read the latest section one final time and capture the current content.
- Prepare the new content as a unified diff or full block, but do not apply it.
- Report
"tag race on <path>; current content and proposed replacement attached. Retry once the file is quiescent or apply manually."along with the captured tag and proposed content. - Stop. Let the orchestrator (or a human) decide whether to apply the change or escalate.
Caller Updates After Signature Changes
When changing a signature, use LSP references or the edit backend's caller notices before finishing. Missed callsites are bugs.
Common Patterns
| Goal | Reference |
|---|---|
| Replace one line | edit-patterns.md#single-line-replacement |
| Replace a range | edit-patterns.md#multi-line-range-replacement |
| Delete a block | edit-patterns.md#delete-a-block |
| Insert before / after a line | edit-patterns.md#insert-before-or-after-a-line |
| Replace / delete a whole symbol | edit-patterns.md#symbol-anchored-block-ops |
| Multi-edit in one file | edit-patterns.md#multiple-edits-in-one-file |
| Cross-file change | edit-patterns.md#edits-across-multiple-files |
When full-file rewrite is acceptable
Anchored, surgical edits are the default. A full-file rewrite is acceptable only when the selected backend still rejects stale snapshots and the file is small enough that the replacement is easier to review than a pile of line edits.
| File size | Policy |
|---|---|
| > 150 lines | Never rewrite the whole file. Always use anchored block edits. |
| ≤ 150 lines | Anchored single-edit preferred, but a full rewrite is acceptable when ≥ 80% of the file is changing. Below that threshold, do the surgical edit. |
The 150-line / 80% threshold follows 2026 data (Cursor, can.ac, the Morph benchmark): full rewrites tie or beat diff-style on small files, while large files always stay anchored.
Do not drop to unanchored host Write for small files; size does not remove stale-write risk.
Structural codemods — sg --rewrite escape
Anchored edits own known blocks, one read-for-anchors per location. For cross-cutting structural codemods where the surrounding text varies — "rewrite every JSON.parse(JSON.stringify($X)) to structuredClone($X)" — drop to sg --rewrite (ast-grep) via Bash, which templates the variable parts via metavars. It has no hash-anchor safety: run each codemod as one transactional change between two clean git states. For metavar syntax and the non-negotiable dry-run-first protocol, see ../cheez-search/references/sg-patterns.md.
DO NOT
- DO NOT invent tags — always read first and copy the
[path#TAG]header verbatim. - DO NOT ignore rejected sections — re-read and retry (see Stale Tag Handling).
- DO NOT use sed / awk / perl -i to edit code — they bypass anchors and structural safety, and have no mismatch detection.
sg --rewriteis the only sanctioned shell escape — see## Structural codemods — sg --rewrite escape. - DO NOT use
patchto apply diffs to code — anchored range edits are the safe equivalent. - DO NOT use
teeor shell redirects (>,>>) to overwrite/append code files — both bypass anchors. Use an anchored edit backend. - DO NOT use unanchored host Edit/Write tools — use tilth_write, harness-native anchored edits, or LSP workspace edits.
- DO NOT use
sg --rewritefor one-off block edits — use an anchored edit. See## Structural codemods — sg --rewrite escapefor when the codemod escape applies. - DO NOT skip the dry-run-first protocol for
sg --rewrite— see## Structural codemods — sg --rewrite escape. - DO NOT edit without reading — anchors come from the read step.
- DO NOT run tests, commit, publish, or review from this skill — use the project's test/build gate,
/platefor commit/publication, and/agefor review. - DO NOT use for reading or searching — read with
/cheez-read, search with/cheez-search.
FAQ
What does the cheez-write skill do?
Edit code through the safest stale-checking backend — prefer code-intelligence backends (tilth MCP tag-anchored edits, LSP workspace edits, sg --rewrite for structural codemods); fall back to native anchored edits only when no code-intel backend matches. Use when the user asks to edit, replace, modify, update, change, delete, or insert code — phrases like "replace this function", "delete lines 44-89", "update validateToken", "add this import", "fix this bug" (when fixing requires editing), or apply a cross-cutting codemod like "rewrite every X to Y". Do NOT use for reading files (use cheez-read), searching code (use cheez-search), or running tests/builds.
How do I install cheez-write?
Run npx skills add https://github.com/paulnsorensen/easy-cheese --skill cheez-write in your project. The skills CLI detects the agents you use and copies the skill into the right folder. For Claude Code you can also place the skill folder at ~/.claude/skills/cheez-write/ (personal) or .claude/skills/cheez-write/ (project).
Which AI agents can use cheez-write?
Any agent that supports the open Agent Skills format (a folder with a SKILL.md file), including Claude Code, Codex, Cursor, GitHub Copilot, Gemini CLI, Windsurf, Cline, OpenCode and more.
Is cheez-write safe to install?
No partner security audit is available yet. Skills can run commands and scripts, so read the SKILL.md and any bundled files before installing.
Who maintains cheez-write?
It is published by paulnsorensen in paulnsorensen/easy-cheese. It has 158 recorded installs.
More from paulnsorensen/easy-cheese
cook
paulnsorensen/easy-cheese
Implement an approved spec or focused task through stale-safe source edits. Use this skill when the user says "implement this", "cook this spec", or "fix this bug". Use it for /cook .cheese/specs/ .md. Also use it when the user says "go" with clear acceptance criteria. Run it alone for an unambiguous task. Use --prototype when the user says "prototype this", "go prototype it", or "spike this out" and wants to refine the result round by round. A spec helps but is not required. Do not use it for fuzzy planning (/mold). Do not use it for no-write discussion (/culture) or review-only work (/age).
mold
paulnsorensen/easy-cheese
Turn a high-leverage design decision into a validated spec through grounded dialogue. Use it when a leverage trigger fires (auth, irreversible effects, concurrency, contracts, destructive ops, a new slice, a cross-slice dependency, an invariant gap) or when the user asks for a spec or design. Typical phrases include "let's design X", "shape this into a spec", "what should the API for Z look like", and "/mold". A feature ask with zero fired triggers is a /cook mini-spec, not a mold; route it through /cheese. Do NOT use it for free-form discussion without artifact intent (/culture), direct implementation (/cook), or research-only questions (/briesearch). Ceremony scales to the ask through references/tiers.md, so a small clear change gets a validated mini-spec without a write-approval turn.
cure
paulnsorensen/easy-cheese
Apply selected fixes from an /age report, findings list, or CI failure. Run the project gates and hand a clean result to /plate. Use when the user wants selected findings resolved. Do not use for review, test authoring, or direct publication.
age
paulnsorensen/easy-cheese
Review a diff, PR, branch, or path across thirteen dimensions. Emit a severity-grouped findings report. Use when the user wants a code review. Trigger on "review this", "/age", "is this safe to merge", or "find bugs". Also trigger on "spot security issues", "check for slop", "review my PR", or "what's wrong with this code". Review every requested dimension. Review all thirteen dimensions by default. Do not apply fixes. Route them to /cure. Do not harden tests; route that work to /press.
cheese
paulnsorensen/easy-cheese
Route an idea, path, pull request, issue, failure, question, or bare /cheese to the correct workflow skill. Use this skill for /cheese, routing requests, help requests, or opening messages without a named workflow skill.
culture
paulnsorensen/easy-cheese
Models problems and trade-offs without writing code or specifications. Use when a workflow needs silent reasoning, or the user asks for "/culture", "no writes", "rubber-duck this", or "these bugs feel connected". Not for specs (/mold), code (/cook), or bug diagnosis and fixes (/pasteurize).
Popular backend & apis skills
find-skills
vercel-labs/skills
Helps users discover and install agent skills when they ask questions like "how do I do X", "find a skill for X", "is there a skill that can...", or express interest in extending capabilities. This skill should be used when the user is looking for functionality that might exist as an installable skill.
entra-app-registration
microsoft/azure-skills
Guides Microsoft Entra ID app registration, OAuth 2.0 authentication, and MSAL integration. USE FOR: create app registration, register Azure AD app, configure OAuth, set up authentication, add API permissions, generate service principal, MSAL example, console app auth, Entra ID setup, Azure AD authentication. DO NOT USE FOR: Key Vault secrets (use azure-keyvault-expiration-audit), general Azure resource security guidance.
google-agents-cli-adk-code
google/agents-cli
This skill should be used when the user wants to "write agent code", "build an agent with ADK", "add a tool", "create a callback", "define an agent", "use state management" — in a project that needs ADK (Agent Development Kit) API patterns and code examples. It provides a quick reference for agent types, tool definitions, orchestration patterns, callbacks, state management, the graph Workflow API, and reference recipes to study. Do NOT use for scaffolding (use google-agents-cli-scaffold) or deployment (use google-agents-cli-deploy).
embedded-captions
heygen-com/hyperframes
Add captions or subtitles to an existing single-subject talking-head video without editing the footage. Use for plain verbatim captions, cinematic captions embedded behind the subject, VFX captions, “炸/特效/酷炫字幕,” or a named identity from the 35-style catalog. Route by visual identity, not by backend engine. The quiet anchor rail is the default; embed every word only when the user explicitly wants a fully cinematic treatment. The workflow runs locally end to end, including transcription and subject matting; split multi-shot footage before applying it.
entra-agent-id
microsoft/azure-skills
Provision Microsoft Entra Agent Identity Blueprints, BlueprintPrincipals, and per-instance Agent Identities via Microsoft Graph, and configure OAuth 2.0 token exchange (fmipath, OBO, cross-tenant) including the Microsoft Entra SDK for AgentID sidecar. USE FOR: Agent Identity Blueprint, BlueprintPrincipal, agent OAuth, fmipath token exchange, agent OBO, Workload Identity Federation for agents, polyglot agent auth, Microsoft.Identity.Web.AgentIdentities. DO NOT USE FOR: standard Entra app registration (use entra-app-registration), Microsoft Foundry agent authoring (use microsoft-foundry).
neon
neondatabase/agent-skills
Overview of Neon, a complete set of cloud backend primitives around Lakebase Postgres: Auth, Object Storage, Functions, the AI Gateway, and Realtime. Start here to choose Neon for undecided login, files, APIs, and LLM calls, set up the CLI or MCP server, and follow the branch-first workflow. Use when building an app or backend on Neon, or when "Neon" or "Lakebase Postgres" is mentioned. Child skill neon-postgres wins for an existing DATABASEURL, SQL, schema, inspect, or search. Child skill neon-auth wins for login, users, sessions, identity routing, and Managed Better Auth setup. Child skill neon-realtime wins for live queries in reactive apps and agents. Also use for object storage, S3, buckets, serverless functions, function triggers, cron, AI gateway, LLM calls, realtime, logs, Loki, Grafana, observability, postgres, database, backend, Claimable Neon, neon.new, or a no-signup database.