Skip to content

Commit aa83a94

Browse files
Bruce Haumanclaude
andcommitted
Fix test failures by adding dry_run parameter to pipeline calls
Updated three execute-tool methods in tool.clj and two test methods in pipeline_test.clj to pass the new dry_run parameter (as nil) to edit-form-pipeline, which now requires 7 arguments instead of 6. All 365 tests now pass. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
1 parent dfca0da commit aa83a94

File tree

7 files changed

+253
-3
lines changed

7 files changed

+253
-3
lines changed

dev/test_file_edit_dry_run.txt

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
Line 1
2+
Line 2
3+
Line 3 - Normal mode, file should be modified
4+
Line 4
5+
Line 5
Lines changed: 129 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,129 @@
1+
# Guide to Creating Custom Prompts in Clojure MCP
2+
3+
## Overview
4+
Custom prompts are saved in `.clojure-mcp/config.edn` under the `:prompts` key. Prompts use Mustache templating for dynamic content with parameters.
5+
6+
## Prompt Structure
7+
8+
Each prompt is defined as a map with the following keys:
9+
10+
### Required Keys:
11+
- **`:description`** (string) - Clear description shown to the LLM when listing prompts
12+
- **`:content`** (string) OR **`:file-path`** (string) - Choose one:
13+
- `:content` - Inline Mustache template content
14+
- `:file-path` - Path to a template file (relative to project root)
15+
16+
### Optional Keys:
17+
- **`:args`** (vector of maps) - Parameter definitions for the template
18+
- Each argument map has:
19+
- `:name` (required) - Parameter name used in Mustache template (e.g., `{{name}}`)
20+
- `:description` (required) - What this parameter is for
21+
- `:required?` (optional, defaults to false) - Whether parameter is required
22+
23+
## Mustache Template Syntax
24+
25+
- `{{variable}}` - Simple variable substitution
26+
- `{{#variable}}content{{/variable}}` - Conditional section (only shown if variable exists)
27+
- `{{^variable}}content{{/variable}}` - Inverted section (only shown if variable doesn't exist)
28+
29+
## Examples
30+
31+
### Simple Prompt (No Parameters)
32+
```edn
33+
"my-greeting" {:description "A simple greeting"
34+
:content "Hello! I'm ready to help you."}
35+
```
36+
37+
### Prompt with Required Parameters
38+
```edn
39+
"code-reviewer" {:description "Reviews code for best practices"
40+
:content "Please review this {{language}} code:\n\n```{{language}}\n{{code}}\n```\n\nProvide feedback on quality and improvements."
41+
:args [{:name "language"
42+
:description "Programming language"
43+
:required? true}
44+
{:name "code"
45+
:description "Code to review"
46+
:required? true}]}
47+
```
48+
49+
### Prompt with Optional Parameters
50+
```edn
51+
"explain-code" {:description "Explains code in detail"
52+
:content "Explain this {{language}} code:\n\n```\n{{code}}\n```\n\n{{#audience}}Target audience: {{audience}}{{/audience}}"
53+
:args [{:name "language"
54+
:description "Programming language"
55+
:required? true}
56+
{:name "code"
57+
:description "Code to explain"
58+
:required? true}
59+
{:name "audience"
60+
:description "Target audience level"
61+
:required? false}]}
62+
```
63+
64+
### Prompt Using File Template
65+
```edn
66+
"my-file-prompt" {:description "Loads content from a file"
67+
:file-path "prompts/my-template.md"
68+
:args [{:name "project_name"
69+
:description "Name of the project"
70+
:required? true}]}
71+
```
72+
73+
## Step-by-Step Guide
74+
75+
1. **Locate config file**: Open `.clojure-mcp/config.edn` in your project root
76+
- If it doesn't exist, create it
77+
78+
2. **Add `:prompts` key**: If not present, add `:prompts {}` to the config map
79+
80+
3. **Define your prompt**: Add an entry under `:prompts` with:
81+
- String key (prompt name) - e.g., `"my-custom-prompt"`
82+
- Map value with `:description` and either `:content` or `:file-path`
83+
84+
4. **Add parameters** (optional): If your prompt needs dynamic values:
85+
- Add `:args` vector with parameter definitions
86+
- Use parameter names in your template with Mustache syntax: `{{param_name}}`
87+
88+
5. **Save and test**: Save the config file
89+
- The MCP server will reload the configuration
90+
- Your prompt will appear in the prompts list
91+
92+
## Common Patterns
93+
94+
### Code Review/Analysis
95+
```edn
96+
:content "Analyze this {{language}} code for {{focus}}:\n\n```{{language}}\n{{code}}\n```"
97+
```
98+
99+
### Documentation Generation
100+
```edn
101+
:content "Generate documentation for this {{language}} {{type}}:\n\n{{code}}\n\nInclude: {{#sections}}{{.}}, {{/sections}}"
102+
```
103+
104+
### Test Generation
105+
```edn
106+
:content "Generate {{framework}} tests for:\n\nFunction: {{function_name}}\n```{{language}}\n{{code}}\n```"
107+
```
108+
109+
## Important Notes
110+
111+
- Prompt names MUST be strings (not keywords): `"my-prompt"` not `:my-prompt`
112+
- You cannot use both `:content` and `:file-path` - choose one
113+
- Parameter `:name` values must match the `{{variable}}` names in your template
114+
- Required parameters are enforced when the prompt is invoked
115+
- The config file must be valid EDN format
116+
117+
## Configuration Location
118+
119+
Full path: `<project-root>/.clojure-mcp/config.edn`
120+
121+
Example complete config:
122+
```edn
123+
{:prompts {"my-prompt" {:description "My custom prompt"
124+
:content "Content here with {{param}}"
125+
:args [{:name "param"
126+
:description "A parameter"
127+
:required? true}]}}
128+
:allowed-directories ["." "src" "test"]}
129+
```
Lines changed: 90 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,90 @@
1+
;; Example .clojure-mcp/config.edn with custom prompt configurations
2+
;;
3+
;; Prompts can use Mustache templating for dynamic content with parameters.
4+
;; Place this in .clojure-mcp/config.edn in your project root.
5+
6+
{;; Custom prompt definitions
7+
:prompts {;; Simple prompt with inline content (no parameters)
8+
"my-simple-prompt" {:description "A simple greeting prompt"
9+
:content "Hello! I'm ready to help you with {{task}}."}
10+
11+
;; Prompt with parameters/arguments
12+
"code-reviewer" {:description "Reviews code for best practices"
13+
:content "Please review this {{language}} code and provide feedback on:\n1. Code quality\n2. Best practices\n3. Potential improvements\n\nCode:\n```\n{{code}}\n```"
14+
:args [{:name "language"
15+
:description "Programming language of the code"
16+
:required? true}
17+
{:name "code"
18+
:description "The code to review"
19+
:required? true}]}
20+
21+
;; Prompt using a template file instead of inline content
22+
"my-file-prompt" {:description "Loads content from a file"
23+
:file-path "prompts/my-custom-prompt.md"
24+
:args [{:name "project_name"
25+
:description "Name of the project"
26+
:required? true}]}
27+
28+
;; Advanced example with multiple optional parameters
29+
"test-generator" {:description "Generates unit tests for a function"
30+
:content "Generate {{test_framework}} unit tests for the following {{language}} function:\n\nFunction: {{function_name}}\n{{#description}}Description: {{description}}{{/description}}\n\nCode:\n```{{language}}\n{{code}}\n```\n\n{{#edge_cases}}Focus on these edge cases: {{edge_cases}}{{/edge_cases}}"
31+
:args [{:name "language"
32+
:description "Programming language"
33+
:required? true}
34+
{:name "test_framework"
35+
:description "Testing framework to use"
36+
:required? true}
37+
{:name "function_name"
38+
:description "Name of the function"
39+
:required? true}
40+
{:name "code"
41+
:description "Function implementation"
42+
:required? true}
43+
{:name "description"
44+
:description "Optional function description"
45+
:required? false}
46+
{:name "edge_cases"
47+
:description "Optional edge cases to test"
48+
:required? false}]}
49+
50+
;; Example with code explanation
51+
"explain-code" {:description "Explains code in detail"
52+
:content "Explain this {{language}} code:\n\n```{{language}}\n{{code}}\n```\n\nProvide:\n1. High-level overview\n2. Step-by-step breakdown\n3. Key concepts used\n{{#audience}}Target audience: {{audience}}{{/audience}}"
53+
:args [{:name "language"
54+
:description "Programming language"
55+
:required? true}
56+
{:name "code"
57+
:description "Code to explain"
58+
:required? true}
59+
{:name "audience"
60+
:description "Target audience (e.g., beginner, intermediate)"
61+
:required? false}]}}
62+
63+
;; Other configuration options
64+
:allowed-directories ["." "src" "test" "resources"]
65+
:cljfmt true}
66+
67+
;; NOTES:
68+
;; ======
69+
;;
70+
;; Mustache Template Syntax:
71+
;; - {{variable}} - Simple variable substitution
72+
;; - {{#variable}}content{{/variable}} - Conditional section (only shown if variable exists)
73+
;; - {{^variable}}content{{/variable}} - Inverted section (only shown if variable doesn't exist)
74+
;;
75+
;; Prompt Structure:
76+
;; - :description (required) - Clear description shown to LLM when listing prompts
77+
;; - :content (required if :file-path not provided) - Inline Mustache template
78+
;; - :file-path (required if :content not provided) - Path to template file (relative to project root)
79+
;; - :args (optional) - Vector of parameter definitions
80+
;;
81+
;; Argument Structure:
82+
;; - :name (required) - Parameter name used in template
83+
;; - :description (required) - What this parameter is for
84+
;; - :required? (optional, defaults to false) - Whether parameter is required
85+
;;
86+
;; Key Points:
87+
;; - Prompt names must be strings (not keywords)
88+
;; - You can use either :content OR :file-path, but not both
89+
;; - Parameter names in :args must match the {{variable}} names in your template
90+
;; - Required parameters are enforced when the prompt is used

src/clojure_mcp/tools/form_edit/tool.clj

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -164,7 +164,7 @@ Note: For `defmethod` forms, be sure to include the dispatch value (`area :recta
164164

165165
(defmethod tool-system/execute-tool :clojure-edit-replace-form [{:keys [nrepl-client-atom] :as tool} inputs]
166166
(let [{:keys [file_path form_name form_type content]} inputs
167-
result (pipeline/edit-form-pipeline file_path form_name form_type content :replace tool)
167+
result (pipeline/edit-form-pipeline file_path form_name form_type content :replace nil tool)
168168
formatted-result (pipeline/format-result result)]
169169
formatted-result))
170170

@@ -256,7 +256,7 @@ Note: For `defmethod` forms, be sure to include the dispatch value (`area :recta
256256

257257
(defmethod tool-system/execute-tool :clojure-edit-insert-before-form [{:keys [nrepl-client-atom] :as tool} inputs]
258258
(let [{:keys [file_path form_name form_type content]} inputs
259-
result (pipeline/edit-form-pipeline file_path form_name form_type content :before tool)
259+
result (pipeline/edit-form-pipeline file_path form_name form_type content :before nil tool)
260260
formatted-result (pipeline/format-result result)]
261261
formatted-result))
262262

@@ -348,7 +348,7 @@ Note: For `defmethod` forms, be sure to include the dispatch value (`area :recta
348348

349349
(defmethod tool-system/execute-tool :clojure-edit-insert-after-form [{:keys [nrepl-client-atom] :as tool} inputs]
350350
(let [{:keys [file_path form_name form_type content]} inputs
351-
result (pipeline/edit-form-pipeline file_path form_name form_type content :after tool)
351+
result (pipeline/edit-form-pipeline file_path form_name form_type content :after nil tool)
352352
formatted-result (pipeline/format-result result)]
353353
formatted-result))
354354

test-listener-simple.sh

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
#!/bin/bash
2+
3+
echo "Testing prompt-cli with listener support..."
4+
echo "========================================="
5+
echo ""
6+
echo "This will show request/response messages via the pretty-print listener"
7+
echo ""
8+
9+
# Test with a simple evaluation that should work
10+
clojure -M:prompt-cli -p "What is 2 + 2?" --port 7888

test-listener.sh

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
#!/bin/bash
2+
3+
# Quick test of prompt-cli with listener
4+
echo "Testing prompt-cli with pretty-print listener..."
5+
echo "================================================"
6+
echo ""
7+
echo "This test will:"
8+
echo "1. Connect to nREPL on port 7888"
9+
echo "2. Show the request/response messages via the listener"
10+
echo "3. Execute a simple Clojure evaluation"
11+
echo ""
12+
13+
# Simple test that should work without API keys
14+
clojure -M:prompt-cli -p "Please evaluate the Clojure expression (+ 1 2) and tell me the result"

test/clojure_mcp/tools/form_edit/pipeline_test.clj

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -294,6 +294,7 @@
294294
"defn"
295295
"(defn example-fn [x y]\n (* x y))"
296296
:replace
297+
nil
297298
*nrepl-client-atom*)
298299
result (sut/format-result pipeline-result)
299300
file-content (slurp file-path)]
@@ -316,6 +317,7 @@
316317
"comment"
317318
"(comment some test comment)"
318319
:replace
320+
nil
319321
*nrepl-client-atom*)]
320322
(is (true? (::sut/error pipeline-result)))
321323
(is (string? (::sut/message pipeline-result)))

0 commit comments

Comments
 (0)