dirge-agent 0.18.6

Minimalistic coding agent written in Rust, optimized for memory footprint and performance
# nREPL plugin hooks.
#
# on-init: tries to auto-connect by reading .nrepl-port from cwd.
# before-agent-start: injects skill instructions for nrepl_eval tool.

(defn on-init [ctx]
  (def cwd (harness/get-cwd))
  (def port-file (string cwd "/.nrepl-port"))
  (if-let [port-str (try (string/trim (slurp port-file)) ([_] nil))]
    (do
      (harness/log (string "nrepl: found .nrepl-port → " port-str))
      # Janet `try` takes ONE body form, so multi-step bodies must be
      # wrapped in `(do ...)`.
      (try
        (do
          (def status (nrepl-connect nrepl-host port-str))
          (harness/notify (string "[nrepl] " status) :info)
          (harness/log (string "nrepl: " status)))
        ([err]
         (harness/notify
           (string "[nrepl] auto-connect failed: " err) :warn))))
    (harness/log "nrepl: no .nrepl-port found, skipping auto-connect"))
  nil)

(def nrepl-skill-prompt
  (string
    "\n"
    "## nREPL Evaluation\n"
    "\n"
    "You have access to an nREPL-connected Clojure REPL via the `nrepl_eval` tool. "
    "The REPL session persists across evaluations — state, vars, and loaded namespaces "
    "survive as long as the nREPL server keeps running.\n"
    "\n"
    "### When to use nrepl_eval\n"
    "- Verify that edited Clojure files compile and load correctly\n"
    "- Test function behavior interactively\n"
    "- Check runtime state (vars, namespaces, system components)\n"
    "- Debug code by evaluating expressions\n"
    "- Require or reload namespaces after making changes\n"
    "- Run tests from the REPL\n"
    "\n"
    "### How to connect\n"
    "Use the `/nrepl-connect [host] [port]` slash command. "
    "If no port is given, reads from `.nrepl-port` in the project root. "
    "Check connection status with `/nrepl-status`.\n"
    "\n"
    "### Common patterns\n"
    "\n"
    "**Require a namespace (always use :reload to pick up changes):**\n"
    "```\n"
    "(require '[my.namespace :as ns] :reload)\n"
    "```\n"
    "\n"
    "**Test a function after requiring:**\n"
    "```\n"
    "(ns/my-function arg1 arg2)\n"
    "```\n"
    "\n"
    "**Check if a file compiles:**\n"
    "```\n"
    "(require 'my.namespace :reload)\n"
    "```\n"
    "\n"
    "**Run a test:**\n"
    "```\n"
    "(require '[clojure.test :refer [run-tests]])\n"
    "(run-tests 'my.namespace-test)\n"
    "```\n"
    "\n"
    "**Inspect runtime state:**\n"
    "```\n"
    "(keys (ns-publics 'my.namespace))\n"
    "(*print-length*)\n"
    "```\n"
    "\n"
    "**Multiple expressions in one call:**\n"
    "```\n"
    "(def x 10)\n"
    "(* x 2)\n"
    "(+ x 5)\n"
    "```\n"
    "\n"
    "### Important notes\n"
    "- **Automatic delimiter repair:** Unbalanced parentheses are auto-repaired before eval. "
    "If you see a repair notice, your code had mismatched delimiters.\n"
    "- **Session persists:** State survives across tool calls until the nREPL server restarts.\n"
    "- **Always :reload:** When requiring namespaces after editing, use `:reload` to pick up changes.\n"
    "- **Connection management:** Use `/nrepl-status` to check connectivity, "
    "`/nrepl-disconnect` to close, `/nrepl-connect` to reconnect.\n"))

(defn before-agent-start [ctx]
  (harness/append-system-prompt nrepl-skill-prompt)
  nil)