diff --git a/configs/gptel-agents/README.md b/configs/gptel-agents/README.md index ff4f800..c6bf7da 100644 --- a/configs/gptel-agents/README.md +++ b/configs/gptel-agents/README.md @@ -18,8 +18,9 @@ Agentes y prompts internos para `gptel-agent`, portados de [opencode](https://op (el último dir gana) sobreescriba los agentes por defecto del paquete `gptel-agent`. - Los `{{AGENTS}}`/`{{SKILLS}}` del cuerpo se expanden automáticamente por `gptel-agent`. - Las tools LSP (`lsp_diagnostics` y `lsp_symbols`, basadas en eglot/flymake), - `apply_patch` (diff unificado vía `patch`) y `plan_write` (guarda planes en - `.gptel/plans/`) se definen en `configs/init-ai.el` y se referencian desde los + `apply_patch` (diff unificado vía `patch`) y `plan_write` (guarda planes + fuera del proyecto, en `kj-gptel-plans-dir` con nombre `----.md`) + se definen en `configs/init-ai.el` y se referencian desde los agentes correspondientes. - `confirm-tool-calls`: build y general usan `auto` (confirmación por tool); plan y explore usan `false` (solo lectura, sin confirmar cada lectura). diff --git a/configs/init-ai.el b/configs/init-ai.el index 0fbba01..a69754d 100644 --- a/configs/init-ai.el +++ b/configs/init-ai.el @@ -203,6 +203,15 @@ content do not break gptel-magit." nil uses the current session's model." :type '(choice (const :tag "Current session model" nil) string) :group 'gptel) + + (defcustom kj-gptel-plans-dir + (expand-file-name "gptel-plans" user-emacs-directory) + "Directory where gptel-agent plans are stored, outside the project. +Plans are named ----.md, where is a +truncated md5 of the project root, so plans never pollute the project +directory and can be mapped back to their project." + :type 'directory + :group 'gptel) (defun kj-gptel-load-agents-md () "Add AGENTS.md rules to the current gptel buffer context. Loads AGENTS.md from the project root and from `user-emacs-directory', @@ -406,11 +415,20 @@ Tries `patch -p1' first and falls back to `-p0'." (car r1) (cdr r1))))))) (defun kj-gptel-plan-write (filename content) - "Write CONTENT to `.gptel/plans/FILENAME' in the project. Return status." + "Write CONTENT to a plan file for the current project and return status. +Plans are stored in `kj-gptel-plans-dir' (outside the project), named +----.md so that each project keeps its own +plans without adding extra files to the project directory." (let* ((root (kj-gptel--project-root)) - (dir (expand-file-name ".gptel/plans" root)) - (file (expand-file-name (file-name-nondirectory filename) dir))) - (make-directory dir t) + (hash (substring (md5 root) 0 12)) + (project (replace-regexp-in-string + "[^A-Za-z0-9._-]" "-" + (file-name-nondirectory (directory-file-name root)))) + (name (file-name-nondirectory filename)) + (file (expand-file-name + (format "%s--%s--%s" hash project name) + kj-gptel-plans-dir))) + (make-directory kj-gptel-plans-dir t) (with-temp-file file (insert content)) (format "Plan saved to %s" file))) @@ -584,9 +602,9 @@ Takes a unified diff (git format or --- a/ / +++ b/). It is applied with the pat (gptel-make-tool :name "plan_write" :function #'kj-gptel-plan-write - :description "Save the current plan as a Markdown file in .gptel/plans/ of the project. + :description "Save the current plan as a Markdown file in the Emacs directory, outside the project. -Use it when you have drafted a plan, to persist it to disk and be able to resume it later. Saves the content to .gptel/plans/.md. Does not modify any other file." +Use it when you have drafted a plan, to persist it to disk and be able to resume it later. Plans are stored in `kj-gptel-plans-dir' (inside the Emacs directory) named ----.md, where is a truncated md5 of the project root, so each project keeps its own plans without adding files to the project directory. Does not modify any project file." :args '((:name "filename" :type string :description "Name of the plan file (e.g. refactor-auth.md).")