humorless/clj-native-agent

clj-replace

Use when replacing Clojure or Babashka code but str_replace fails due to formatting differences - compares S-expression structure instead

First seen May 13, 2026

Installation

$ npx skills add humorless/clj-native-agent --skill clj-replace

Similar popular skills

Related neighbors and high-traction skills in the same topics — useful to compare before installing.

Also in this package

Other skills from humorless/clj-native-agent.

npx skills add humorless/clj-native-agent

Browse all from humorless/clj-native-agent

More details

Agent compatibility

Declared targets from SKILL.md / docs. Unmarked agents are not listed — the skill may still install via the CLI.

Claude Code Declared
Cursor Not declared
Codex Not declared
GitHub Copilot Not declared
Windsurf Not declared
Gemini CLI Not declared
Cline Not declared
OpenCode Not declared

Repository health

Stars 34
Default branch main
Open issues 0
Status Active

Skill metadata

Parsed from SKILL.md frontmatter.

Version1.0.0
Declared agents claude-code

Package contents

Files included with this skill beyond the listing page.

  • skill md SKILL.md 3,583 B
  • docs SUMMARY.md 156 B

History

  1. First seen on skills.sh
  2. First recorded snapshot · 48 installs

SKILL.md

clj-replace: Structural Clojure Code Replacement

A Clojure-aware code replacement tool that improves on Claude Code's built-in str_replace by comparing code structure (S-expressions) rather than literal text.

When to Use

Use /clj-replace when:

  • Claude Code's strreplace fails because formatting (whitespace, indentation, line breaks) differs between the oldstring and target code
  • You need to replace code but the exact whitespace/formatting doesn't match the source
  • You want replacements to preserve the original file's formatting and style

Example: If strreplace fails with "oldstring not found" but the code structure looks identical, switch to clj-replace.

How It Works

Instead of comparing text character-by-character, clj-replace uses structural comparison:

  1. Parses both the old-string and file contents into S-expression trees (zippers)
  2. Walks the file and compares each node's structure (= on sexpr) with the target
  3. Formatting differences (spaces, indentation, newlines) are ignored during comparison
  4. When a match is found, replaces the node while preserving the original file's formatting

This means these are all equivalent:

(foo bar)          ≡ (foo  bar)        ≡ (foo
                                           bar)

Parameters

Positional Arguments:

  1. filename — Path to the Clojure source file to modify
  2. old-string — Code snippet to find (as a string)
  3. new-string — Code snippet to replace it with (as a string)

Usage

/clj-replace path/to/file.clj "old code here" "new code here"

Examples

Example 1: Whitespace Variation

File content:

(defn update-user
  [db id attrs]
  (merge-user db id attrs))

Command:

/clj-replace src/app.clj "(merge-user db id attrs)" "(update-user-in-db db id attrs)"

Works even though file has different indentation. Replaces the exact form while preserving file's style.

Example 2: Multi-line Form

File content:

(some-function
  arg1
  arg2
  arg3)

Command:

/clj-replace src/app.clj "(some-function arg1 arg2 arg3)" "(other-function arg1 arg2 arg3)"

Matches regardless of how the original is formatted across lines.

Exit Codes

  • 0 — Success: one or more nodes replaced
  • 1 — Error: file doesn't exist, or old-string/new-string are invalid Clojure
  • 2 — Error: no matching S-expression found in the file
  • 3 — Error: multiple matching S-expressions found (ambiguous); user must provide more specific old-string

Output

On success:

✓ Replaced 1 node(s) in path/to/file.clj
  Location: line 42, column 5
  Old: (merge-user db id attrs)
  New: (update-user-in-db db id attrs)

If multiple matches:

✗ Found 3 matching S-expressions in path/to/file.clj (ambiguous)
  1. line 42, column 5: (foo bar)
  2. line 85, column 10: (foo bar)
  3. line 120, column 1: (foo bar)
Please provide a more specific old-string (e.g., include surrounding context)

Implementation Details

Uses rewrite-clj library for:

  • Format-preserving parsing and modification
  • Structural comparison of S-expressions
  • Safe node replacement that maintains whitespace and style

The tool respects Clojure's semantics: two expressions are equivalent if they parse to the same structure, regardless of superficial formatting.