Skip to content

Commit dfca0da

Browse files
Bruce Haumanclaude
andcommitted
Add dry_run parameter support to clojure_edit_replace_sexp tool
- Add dry_run parameter to sexp-edit-pipeline - Extract and pass dry_run through validate-inputs and execute-tool - Update format-results to handle new-source output - Skip file write operations when dry_run is set 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
1 parent 77656fa commit dfca0da

File tree

2 files changed

+17
-20
lines changed

2 files changed

+17
-20
lines changed

src/clojure_mcp/tools/form_edit/pipeline.clj

Lines changed: 10 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -786,17 +786,19 @@
786786
- operation: The operation to perform (:replace, :insert-before, :insert-after)
787787
- replace-all: Whether to apply the operation to all occurrences
788788
- whitespace-sensitive: Whether to match forms exactly as written
789+
- dry_run: Optional string, either \"diff\" or \"new-source\" to skip actual file write
789790
- config: Optional tool configuration map with nrepl-client-atom
790791
791792
Returns:
792793
- A context map with the result of the operation"
793-
[file-path match-form new-form operation replace-all whitespace-sensitive {:keys [nrepl-client-atom] :as config}]
794+
[file-path match-form new-form operation replace-all whitespace-sensitive dry_run {:keys [nrepl-client-atom] :as config}]
794795
(let [ctx {::file-path file-path
795796
::match-form match-form
796797
::new-form new-form
797798
::operation operation
798799
::replace-all replace-all
799800
::whitespace-sensitive whitespace-sensitive
801+
::dry-run dry_run
800802
::nrepl-client-atom nrepl-client-atom
801803
::config config}]
802804
(thread-ctx
@@ -814,9 +816,13 @@
814816
format-source
815817
determine-file-type
816818
generate-diff
817-
save-file
818-
update-file-timestamp
819-
highlight-form)))
819+
(fn [ctx]
820+
(if (::dry-run ctx)
821+
ctx
822+
(-> ctx
823+
save-file
824+
update-file-timestamp
825+
highlight-form))))))
820826

821827
(comment
822828
;; Example usage of the pipelines

src/clojure_mcp/tools/form_edit/tool.clj

Lines changed: 7 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -545,7 +545,7 @@ For reliable results, use a unique substring that appears in only one comment bl
545545
(defmethod tool-system/validate-inputs :clojure-update-sexp
546546
[{:keys [nrepl-client-atom multi-op]} inputs]
547547
(let [file-path (validate-file-path inputs nrepl-client-atom)
548-
{:keys [match_form new_form operation replace_all whitespace_sensitive]} inputs]
548+
{:keys [match_form new_form operation replace_all whitespace_sensitive dry_run]} inputs]
549549
(when-not match_form
550550
(throw (ex-info "Missing required parameter: match_form"
551551
{:inputs inputs})))
@@ -567,16 +567,9 @@ For reliable results, use a unique substring that appears in only one comment bl
567567
(throw (ex-info "Bad parameter: match-form can not be a blank string."
568568
{:inputs inputs})))
569569

570-
;; TODO we can get more sophisticated here... we are handling
571-
;; code repairs deeper inside the actually tools evaluation and
572-
;; this prevents it. Also I think we can actually do comment
573-
;; replacement now but we might need special handling for that.
574-
575-
;; Special handling for empty string
576570
(when-not (str/blank? match_form)
577571
(try
578572
(let [parsed (p/parse-string-all match_form)]
579-
;; Check if there's at least one non-whitespace, non-comment node
580573
(when (zero? (count (n/child-sexprs parsed)))
581574
(throw (ex-info "match_form must contain at least one S-expression (not just comments or whitespace)"
582575
{:inputs inputs}))))
@@ -587,41 +580,39 @@ For reliable results, use a unique substring that appears in only one comment bl
587580
{:inputs inputs}))))))
588581

589582
(when-not (str/blank? new_form)
590-
;; Validate that new_form is valid Clojure code
591583
(try
592584
(p/parse-string-all new_form)
593585
(catch Exception e
594586
(throw (ex-info (str "Invalid Clojure code in new_form: " (.getMessage e))
595587
{:inputs inputs})))))
596-
;; Return validated inputs
597588
{:file_path file-path
598589
:match_form match_form
599590
:new_form new_form
600591
:operation operation
601592
:replace_all (boolean (if (#{"insert_before" "insert_after"} operation)
602593
false
603594
(or replace_all false)))
604-
:whitespace_sensitive (boolean (or whitespace_sensitive false))}))
595+
:whitespace_sensitive (boolean (or whitespace_sensitive false))
596+
:dry_run dry_run}))
605597

606598
(defmethod tool-system/execute-tool :clojure-update-sexp [{:keys [multi-op nrepl-client-atom] :as tool} inputs]
607-
(let [{:keys [file_path match_form new_form operation replace_all whitespace_sensitive]} inputs
608-
;; Convert operation string to keyword for the pipeline
599+
(let [{:keys [file_path match_form new_form operation replace_all whitespace_sensitive dry_run]} inputs
609600
operation-kw (if-not multi-op
610601
:replace
611602
(condp = operation
612603
"replace" :replace
613604
"insert_before" :insert-before
614605
"insert_after" :insert-after))
615606
result (pipeline/sexp-edit-pipeline
616-
file_path match_form new_form operation-kw replace_all whitespace_sensitive tool)
607+
file_path match_form new_form operation-kw replace_all whitespace_sensitive dry_run tool)
617608
formatted-result (pipeline/format-result result)]
618609
formatted-result))
619610

620-
(defmethod tool-system/format-results :clojure-update-sexp [_ {:keys [error message diff]}]
611+
(defmethod tool-system/format-results :clojure-update-sexp [_ {:keys [error message diff new-source]}]
621612
(if error
622613
{:result [message]
623614
:error true}
624-
{:result [diff]
615+
{:result [(or new-source diff)]
625616
:error false}))
626617

627618
;; Function to register the tool

0 commit comments

Comments
 (0)