diff --git a/README.md b/README.md index fe9d9f0..8b060e8 100644 --- a/README.md +++ b/README.md @@ -89,7 +89,7 @@ When claude-code.el starts a new session it will start and associate a Monet ses ### Session Management -Sessions are automatically cleaned up (killed) when you exit the associated Claude session. When you exit Emacs all sessions are cleaned up. You can stop a session manually via `monet-stop-server` (`C-c q`). +Sessions are automatically cleaned up (killed) when you exit the associated Claude session. Set `monet-persist-sessions` to `t` to keep sessions alive after Claude disconnects. When you exit Emacs all sessions are cleaned up. You can stop a session manually via `monet-stop-server` (`C-c q`). ### Example @@ -155,6 +155,9 @@ You can start multiple sessions per project, or have multiple ;; Change ediff window split direction (setq monet-ediff-split-window-direction 'vertical) ; Default: 'horizontal + +;; Keep sessions alive after Claude Code disconnects +(setq monet-persist-sessions t) ; Default: nil ``` #### Customizing MCP Tools diff --git a/monet.el b/monet.el index 6486399..a3e75f0 100644 --- a/monet.el +++ b/monet.el @@ -116,6 +116,13 @@ the diff buffer will not be displayed (though it remains accessible in the Claud :type 'boolean :group 'monet-tool) +(defcustom monet-persist-sessions nil + "When non-nil, keep sessions alive after Claude Code disconnects. +Sessions will persist until manually stopped with `monet-stop-server' or Emacs exits. +This allows reconnecting to the same server with a new Claude Code session." + :type 'boolean + :group 'monet) + (defcustom monet-get-current-selection-tool 'monet-default-get-current-selection-tool "Function to use for getting the current text selection. The function should have the signature: @@ -567,21 +574,26 @@ claude later." (defun monet--on-close-server (session _ws) "Handle WebSocket WS close for SESSION. -Remove SESSION from `monet--sessions'." - (let ((key (monet--session-key session)) - (port (monet--session-port session))) - ;; Remove lockfile - (monet--remove-lockfile port) - ;; Remove session - (remhash key monet--sessions) - ;; Remove hooks if no more sessions - (when (= 0 (hash-table-count monet--sessions)) - (remove-hook 'post-command-hook #'monet--track-selection-change) - (remove-hook 'post-command-hook #'monet--track-diff-visibility) - ;; Cancel visibility timer if active - (when monet--diff-visibility-timer - (cancel-timer monet--diff-visibility-timer) - (setq monet--diff-visibility-timer nil))))) +When `monet-persist-sessions' is nil, remove SESSION from `monet--sessions'. +When non-nil, keep the session alive to allow reconnection." + (if monet-persist-sessions + ;; Keep session alive, just clear the client + (setf (monet--session-client session) nil) + ;; Default behavior: full cleanup + (let ((key (monet--session-key session)) + (port (monet--session-port session))) + ;; Remove lockfile + (monet--remove-lockfile port) + ;; Remove session + (remhash key monet--sessions) + ;; Remove hooks if no more sessions + (when (= 0 (hash-table-count monet--sessions)) + (remove-hook 'post-command-hook #'monet--track-selection-change) + (remove-hook 'post-command-hook #'monet--track-diff-visibility) + ;; Cancel visibility timer if active + (when monet--diff-visibility-timer + (cancel-timer monet--diff-visibility-timer) + (setq monet--diff-visibility-timer nil)))))) (defun monet--on-error-server (session _ws action error) "Handle WebSocket error for SESSION with WS during ACTION with ERROR."