Skillquality 0.45

cheez-write

This skill should be used when the user asks to edit, replace, modify, update, change, delete, or insert code in a file — phrases like "replace this function", "delete lines 44-89", "update validateToken", "change the implementation", "add this import", "fix this bug" (when fixin

Price
free
Protocol
skill
Verified
no

What it does

cheez-write

Hard dependency: If mcp__tilth__tilth_edit is unavailable, stop immediately and report "tilth MCP server is not loaded — cannot proceed." Do NOT fall back to Edit, Write, or any host tool. Install via tilth install <host> --edit — the --edit flag is required to expose tilth_edit (see README "Installing tilth MCP").

Capability detection

Before the first call, verify tilth's edit tool is reachable:

  1. Check that mcp__tilth__tilth_edit is in your tool list. If only tilth_read and tilth_search are present, tilth was installed without --edit. Stop and report "tilth MCP server is loaded but edit mode is disabled — re-install with 'tilth install <host> --edit'."
  2. The first edit call is a probe by definition — if it returns a JSON-RPC transport error (not a hash mismatch), stop and report "tilth MCP server present but unhealthy: <error>".
  3. Hash mismatches, syntax errors in the new content, or anchor-not-found are content issues — recover via the protocol below, do not bail.

Hash-anchored file editing via tilth MCP (tilth_edit). Use hash anchors from tilth_read to make precise, surgical edits. Avoid rewriting whole files unless the size and change ratio justify it (see "When full-file rewrite is acceptable" below).


Examples

"Replace the body of handleAuth in src/auth.ts"

Step 1 — read with edit mode to get anchors:

tilth_read(path: "src/auth.ts", section: "44-89", edit: true)
# returns 44:b2c|... and 89:e1d|...

Step 2 — apply with the captured anchors:

tilth_edit({
  "path": "src/auth.ts",
  "edits": [{
    "start": "44:b2c",
    "end":   "89:e1d",
    "content": "export function handleAuth(req, res, next) {\n  const token = extractToken(req);\n  if (!validateToken(token)) return res.status(401).end();\n  next();\n}"
  }]
})

Response confirms Edit applied to src/auth.ts and may list callers to review.

"Add an import without nuking the existing one on line 13"

tilth_edit replaces — there is no native insert. Anchor on line 13 and put the original line back at the top of content:

tilth_edit({
  "path": "src/auth.ts",
  "edits": [{
    "start": "13:abc",
    "content": "import { existingThing } from './existing';\nimport { newHelper } from './helpers';"
  }]
})

"Hash mismatch — file changed under me"

Error: Hash mismatch at line 44
Expected: b2c
Found: f9a

Re-read the section, capture the new anchors, retry once. If it mismatches again, stop — see "Hash Mismatch Handling → Repeated mismatches" below (tilth_edit has no fuzzy / search-replace mode, so blind retries lose races, not win them).


Core Principle: Anchors, Not Rewrites

Traditional AI editing rewrites entire files, wasting tokens and risking data loss. tilth_edit uses hash anchors — unique identifiers for each line — to:

  • Make precise, surgical changes
  • Reject edits if the file changed (hash mismatch)
  • Show you exactly what changed

The protocol:

  1. Read the file section with tilth_read (cheez-read) → get hash anchors
  2. Note start/end anchors for the block you'll change
  3. Call tilth_edit with those anchors and new content

Scope: when tilth_edit, when not

tilth_edit owns block edits to tracked source code — function bodies, signatures, imports, single-line tweaks, multi-edit batches, and cross-file specific changes. Hash anchors give concurrency safety; the read-edit protocol is mandatory for any code change that matters.

For everything else, prefer the right tool:

ChangeUse this insteadWhy
Cross-cutting structural codemod (JSON.parse(JSON.stringify($X))structuredClone($X)) across N filessg --rewrite (dry-run-first protocol)tilth_edit needs N reads-for-anchors; codemods template the variable parts
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 sourceEditing the artifact rots on the next build
Brand-new files, no prior contenttilth_edit (anchor on line 1, end-anchor on the last line for a single-edit insert)Stay on one path; the anchor cost is negligible for new files
Files outside the repo or inside dependency caches (node_modules, .cargo/registry)don't edit themModifying dependencies is almost always a mistake — fix the source or upstream
Binary files, images, PDFsthe producing tooltilth_edit is text-only

If the question is "which tool for this specific source-code block edit?" → tilth_edit. If it's "rewrite this pattern everywhere" → sg --rewrite with the dry-run protocol.

When LSP rename beats tilth_edit (if your harness has one)

easy-cheese does not install LSP — it is whatever language servers your harness already exposes. There is one editing operation where an available LSP materially outperforms tilth_edit: type-aware rename of a symbol across the project.

EditUse this insteadWhy LSP wins
Rename a function / class / variable across all type-correct usages, including aliased re-exports and generic instantiationstextDocument/rename (or the harness's rename refactor)Returns a typechecker-validated WorkspaceEdit; covers aliased imports without textual collisions, and skips coincidental name matches in unrelated scopes. tilth_edit would need a separate read-edit cycle per call site, and sg --rewrite matches on syntax not type identity (overshoots on shadowed names, undershoots on aliased re-exports)

For everything else — block edits, signature changes, body rewrites, hand-written codemods — tilth_edit (one-off) and sg --rewrite (cross-cutting) remain the right tools. LSP rename is narrowly the best fit for identifier renames specifically; nothing else in LSP's edit surface improves on the cheez-write protocol.

If no LSP is installed, or the rename touches a symbol the typechecker can't resolve (broken code, generated bindings), fall back to sg --rewrite with the dry-run-first protocol — see "Structural codemods" below.


Hash Anchor Format

When you read a file with tilth_read in edit mode, lines have anchors:

42:a3f|  let x = compute();
43:f1b|  return x;

Format: <line>:<hash>|<content> (ASCII pipe, no space).

The hash is a short content fingerprint. If someone else edits the file, hashes change, and your edit is safely rejected.


MCP Tool Reference

tilth_edit — Precise File Editing

The minimal shape — single anchor, replacement content:

tilth_edit({
  "path": "src/auth.ts",
  "edits": [
    { "start": "42:a3f", "content": "  let x = recompute();" }
  ]
})

For range replacement, deletion, multi-edit, insert-after, cross-file batches, and the diff: true response option, see references/edit-patterns.md. That file is the JSON cookbook; this body sticks to the protocol.


The Read-Edit Protocol

Step 1: Read to Get Anchors

tilth_read(path: "src/auth.ts", section: "44-89")

Output:

44:b2c|export function handleAuth(req, res, next) {
45:c3d|  const token = req.headers.authorization?.split(' ')[1];
...
88:d4e|  next();
89:e1d|}

Step 2: Note Your Anchors

  • Start anchor: 44:b2c (first line of function)
  • End anchor: 89:e1d (closing brace)

Step 3: Edit with Anchors

tilth_edit({
  "path": "src/auth.ts",
  "edits": [{
    "start": "44:b2c",
    "end": "89:e1d",
    "content": "export function handleAuth(req, res, next) {\n  const token = extractToken(req);\n  if (!validateToken(token)) {\n    return res.status(401).json({ error: 'Invalid token' });\n  }\n  req.user = decodeToken(token);\n  next();\n}"
  }]
})

Replacing Entire Functions

This is the most common use case. The pattern:

  1. Read the function (outline first if file is large):

    tilth_read(path: "src/auth.ts")
    # See: [44-89]  export fn handleAuth(req, res, next)
    
    tilth_read(path: "src/auth.ts", section: "44-89")
    # Get hash anchors
    
  2. Note start/end anchors from the hashlined output.

  3. Replace the entire function body:

    tilth_edit({
      "path": "src/auth.ts",
      "edits": [{
        "start": "44:b2c",
        "end": "89:e1d",
        "content": "<your new function implementation>"
      }]
    })
    

Hash Mismatch Handling

If the file changed since you read it:

Error: Hash mismatch at line 44
Expected: b2c
Found: f9a

Current content:
44:f9a|export async function handleAuth(req, res, next) {
...

Recovery:

  1. Read the section again → get new anchors.
  2. Review the current content (someone else may have made changes).
  3. Edit with new anchors.

This is a safety feature, not a bug.

Repeated mismatches → bail out, don't loop

If you hit two consecutive mismatches on the same anchor, you're racing a concurrent writer. tilth_edit has no fuzzy / search-replace mode — there is no "ignore the hash, just match this string" option. A third retry will likely lose the same race.

The correct move is to bail and report:

  1. Read the latest section one final time and capture the current content.
  2. Prepare the new content as a unified diff or full block, but do not apply it.
  3. Report "hash-anchor race on <path>:<line>; current content and proposed replacement attached. Retry once the file is quiescent or apply manually." along with the captured anchors and proposed content.
  4. Stop. Let the orchestrator (or a human) decide whether to apply the change or escalate.

This trades automation for safety — losing a race twice means whatever's writing the file is faster than your read-edit cycle, and a third blind retry could overwrite real work.


Caller Updates After Signature Changes

When you edit a function signature, tilth_edit shows callers that may need updating:

Edit applied to src/auth.ts

── callers that may need updates ──
  src/routes/api.ts:34   router.use('/api/*', handleAuth)
  src/routes/admin.ts:12 app.use(handleAuth)
  src/middleware.ts:8    const wrapped = handleAuth(...)

Check these locations and update if needed.


Common Patterns

GoalPatternReference
Replace one linesingle anchor, new contentedit-patterns.md#single-line-replacement
Replace a rangestart + end anchorsedit-patterns.md#multi-line-range-replacement
Delete a blockrange with content: ""edit-patterns.md#delete-a-block
Insert after a lineanchor on that line, prepend its contentedit-patterns.md#insert-after-a-line
Multi-edit in one fileedits: [...] ordered bottom-upedit-patterns.md#multiple-edits-in-one-call
Cross-file changeone tilth_edit call per fileedit-patterns.md#edits-across-multiple-files

Large Files: Outline First

For large files, tilth_read shows an outline, not hashlined content:

# src/giant.ts (2400 lines, ~32k tokens) [outline]

[1-20]    imports
[22-89]   interface Config
[91-450]  class GiantHandler
  [100-180]  fn process
  [182-340]  fn validate

To edit, drill into the specific section:

tilth_read(path: "src/giant.ts", section: "100-180")
# Now you get hashlined content for fn process

Then edit with those anchors.


When full-file rewrite is acceptable

Hash-anchored, surgical edits are the default. There is one exception:

File sizePolicy
> 150 linesNever rewrite the whole file. Always hash-anchored.
≤ 150 linesAnchored single-edit preferred, but a full rewrite (delete-everything + insert) is acceptable when ≥ 80% of the file is changing. Below that threshold, do the surgical edit.

The 150-line / 80% threshold is informed by 2026 industry data (Cursor's published numbers, can.ac analysis, the Morph benchmark) showing full-file rewrites tie or beat diff-style on small files. The threshold keeps the spirit conservative — large files always stay anchored.

When you do rewrite a small file in full, still use tilth_edit (anchor on line 1, end-anchor on the last line). Do not drop to host Write — that bypasses tilth's hash-mismatch safety.


Structural codemods — sg --rewrite escape

tilth_edit excels at "replace this specific block in this specific file" with hash-anchor concurrency safety. It handles cross-cutting structural changes awkwardly: one file at a time, one read-for-anchors per location. For codemods — "rewrite every JSON.parse(JSON.stringify($X)) to structuredClone($X)", "convert every var $X = $Y to let $X = $Y" — drop to sg --rewrite (ast-grep) via Bash. This is the only sanctioned shell escape from cheez-write.

The two tools are complementary, not redundant:

ToolSafety propertyBest for
tilth_editHash-anchor (concurrency)Specific-block edits, signature changes
sg --rewriteStructural match (CST)Cross-cutting codemods over N files

When the change repeats across many locations and the surrounding text varies, sg --rewrite captures the variable parts via metavars and templates them back into the rewrite — tilth_edit cannot express that without N reads.

For invocation rules (--lang, --json, no --interactive), pitfalls (CST-not-AST, metavar binding, lenient-by-default), and the non-negotiable dry-run-first protocol (search → clean tree → -U → diff → revert if too loose), see ../cheez-search/references/sg-patterns.md — the "Structural codemods (sg --rewrite)" and "Pitfalls" sections in particular.

sg --rewrite does not have hash-anchor safety. Treat each codemod as a single transactional change between two clean git states; never layer additional edits on top until the codemod is committed or reverted.


DO NOT

  • DO NOT rewrite files > 150 lines — use hash anchors for surgical edits.
  • DO NOT rewrite small files when the change is < 80% — anchor the changed range only.
  • DO NOT guess hash values — always read first to get current anchors.
  • DO NOT ignore hash mismatches — re-read and retry (see Hash Mismatch Handling).
  • DO NOT use sed / awk / perl -i to edit code — they bypass hash anchors and structural safety, and have no mismatch detection. sg --rewrite is the only sanctioned shell escape, and only for structural codemods that follow the dry-run-first protocol.
  • DO NOT use patch to apply diffs to code — tilth_edit's anchored ranges are the safe equivalent.
  • DO NOT use tee or shell redirects (>, >>) to overwrite/append code files — both bypass anchors. Use tilth_edit.
  • DO NOT use the host Edit/Write tool — use tilth_edit (or sg --rewrite for structural codemods) exclusively for code.
  • DO NOT use sg --rewrite for one-off block edits — that's tilth_edit territory. The codemod escape is only for cross-cutting structural changes; using it on a single location wastes its strength and skips hash-anchor safety.
  • DO NOT skip the dry-run-first protocol for sg --rewrite — search-only first, clean working tree, then -U. Never combine search+rewrite blindly.
  • DO NOT edit without reading — you need the anchors.
  • DO NOT use for reading — use cheez-read.
  • DO NOT use for searching — use cheez-search.

What This Skill Doesn't Do

  • Read files — use cheez-read first to get anchors.
  • Search code — use cheez-search to find what to edit.
  • Run tests after editing — use test/build skills.
  • Commit changes — use git/gh skills.
  • Review your edits — use the /age skill.

Capabilities

skillsource-paulnsorensenskill-cheez-writetopic-agent-skillstopic-ai-codingtopic-claude-codetopic-code-reviewtopic-developer-tools

Install

Installnpx skills add paulnsorensen/easy-cheese
Transportskills-sh
Protocolskill

Quality

0.45/ 1.00

deterministic score 0.45 from registry signals: · indexed on github topic:agent-skills · 7 github stars · SKILL.md body (16,285 chars)

Provenance

Indexed fromgithub
Enriched2026-05-18 19:13:40Z · deterministic:skill-github:v1 · v1
First seen2026-05-18
Last seen2026-05-18

Agent access