一键导入
clj-debug
Use when debugging Clojure or Babashka code, especially before adding log statements or println - redirects to REPL-based inline inspection instead
用 Codex 或 Claude 帮你安装 复制这段 Prompt,粘贴到 Codex、Claude 或其他助手里,让它检查 Skill 页面并帮你完成安装。
菜单
Use when debugging Clojure or Babashka code, especially before adding log statements or println - redirects to REPL-based inline inspection instead
用 Codex 或 Claude 帮你安装 复制这段 Prompt,粘贴到 Codex、Claude 或其他助手里,让它检查 Skill 页面并帮你完成安装。
基于 SOC 职业分类
When writing Clojure code with unfamiliar Java interop or macros, use this skill to explore and gather context. For Java interop, search for Clojure wrapper libraries first (via WebSearch), then explore Java classes if needed. For macros, expand them to understand what code they generate. This prevents bugs from incorrect API usage. Use this skill when encountering Java classes or unclear macros.
Scan files for mechanism/policy separation opportunities
Use when replacing Clojure or Babashka code but str_replace fails due to formatting differences - compares S-expression structure instead
Evaluate Clojure skills through rigorous real-project testing with and without skills enabled. Use this skill whenever you need to assess whether a Clojure skill (like clj-discover, clj-debug, clj-replace) actually improves development outcomes. Compare behavior differences via context-logs, code quality, documentation depth, and test comprehensiveness. This prevents vague or hypothetical evaluation and forces concrete real-world testing.
| name | clj-debug |
| version | 1.0.0 |
| description | Use when debugging Clojure or Babashka code, especially before adding log statements or println - redirects to REPL-based inline inspection instead |
| compatibility | Requires /brepl skill access, works with Integrant-based systems |
Adding logs and re-running tests creates a slow feedback loop. Clojure's REPL lets you inspect values directly at the point of failure, test fixes instantly, and validate corrections before touching the source file. This is faster and safer than println or formal debuggers.
RED FLAG: You're about to add println, tap>, (log ...), or modify source code to debug.
Instead: Use inline def in nrepl. Evaluate modified code directly without changing files, capture values, inspect them, test your fix, then commit with confidence.
When a function fails, add a temporary (def variable-name variable-name) inside the function and evaluate the modified function in nrepl. This captures the value without changing the source file.
Your function fails:
(defn foo [& [{:keys [a b c] :as m}]]
(+ a b c))
(foo :a 1 :b 2 :c 3)
;; => java.lang.NullPointerException
In nrepl, write the function with an inline def to capture the argument:
;; Evaluate this in nrepl (don't modify the source file):
(defn foo [& [{:keys [a b c] :as m}]]
(def m m) ;; TODO: remove before commit
(+ a b c))
;; Now call it:
(foo :a 1 :b 2 :c 3)
;; => java.lang.NullPointerException
;; Inspect what was captured:
m
;; => :a
;; Aha! m is :a, not a map. The caller is passing wrong format.
Now you understand the bug: the function expects a map {:a 1 :b 2 :c 3}, not keyword arguments.
Once you understand the problem, test the corrected version in nrepl:
;; Test 1: Fix the calling convention
(foo {:a 1 :b 2 :c 3})
;; => 6 ✓ Works!
;; Test 2: Or fix the function to accept varargs correctly
(defn foo [& [{:keys [a b c] :as m}]]
;; No def here — we understand the bug now
(+ a b c))
(foo {:a 1 :b 2 :c 3})
;; => 6 ✓ Verified!
;; Or change the function signature:
(defn foo [& args]
(def args args) ;; Capture to verify varargs format
(let [{:keys [a b c]} (first args)]
(+ a b c)))
(foo {:a 1 :b 2 :c 3})
;; args => ({:a 1, :b 2, :c 3}) ✓ Correct format now
Once the fix works in nrepl, update the source file confidently. Remove any (def ...) lines before committing.
This is the complete cycle — use /brepl to evaluate each step:
digraph debugging_workflow {
rankdir=TB;
node [shape=box, style=rounded];
edge [fontsize=10];
"Test Fails or\nError Occurs" -> "Read Error\nMessage &\nStack Trace";
"Read Error\nMessage &\nStack Trace" -> "Identify Where\nto Inspect\n(Which function/\nwhich args?)";
"Identify Where\nto Inspect\n(Which function/\nwhich args?)" -> "Write Function\nwith inline def\nin nrepl\n(def var var)";
"Write Function\nwith inline def\nin nrepl\n(def var var)" -> "Evaluate Modified\nFunction in nrepl\n(defn foo ...)";
"Evaluate Modified\nFunction in nrepl\n(defn foo ...)" -> "Call Function\nwith Test Args\n(foo ...)";
"Call Function\nwith Test Args\n(foo ...)" -> "Inspect Captured\nValue at REPL\n(var / keys / type)";
"Inspect Captured\nValue at REPL\n(var / keys / type)" -> "Form Hypothesis\n(Why is this\nwrong?)";
"Form Hypothesis\n(Why is this\nwrong?)" -> "Test Corrected Code\nin nrepl\n(defn foo ...)";
"Test Corrected Code\nin nrepl\n(defn foo ...)" -> "Verify Fix Works\n(Call & verify\nresults)";
"Verify Fix Works\n(Call & verify\nresults)" -> "Update Source File\n(Remove inline def,\napply fix)";
"Update Source File\n(Remove inline def,\napply fix)" -> "Run Test Suite\n(Confirm fix\nsolves problem)";
}
If the code uses Integrant components, understand this: When you modify component code and evaluate it in nrepl, the running component may not pick up the change. You'll see the old behavior even though the new code is loaded.
Use this decision tree:
digraph integrant_decision {
rankdir=TB;
node [shape=diamond, style=rounded];
start [label="Modified code that\nthe component\nuses?", shape=diamond];
no_reset [label="No reset needed\n(Only inspecting\nwith def or\ntesting pure\nfunctions)", shape=box, style=rounded];
do_reset [label="Reset component\nto pick up\nchanges", shape=box, style=rounded];
start -> no_reset [label="No"];
start -> do_reset [label="Yes"];
}
How to reset:
;; After evaluating your code change in nrepl:
(require '[your.component :as comp] :reload)
;; Reset the component to pick up the new code:
(ig/halt! @system :component-key)
(alter-var-root #'@system (fn [s] (ig/init (:system/config @system) :component-key)))
;; Now test again — the component reflects your change
(def var var) in nrepl?def line before committing?