mirror of
https://github.com/fscotto/infra.git
synced 2026-05-30 23:49:56 +00:00
Add Gemini CLI agent support with robust session parsing
This commit is contained in:
@@ -1,4 +1,5 @@
|
|||||||
;;functions to support syncing .elfeed between machines
|
(require 'seq)
|
||||||
|
(require 'subr-x)
|
||||||
;;makes sure elfeed reads index from disk before launching
|
;;makes sure elfeed reads index from disk before launching
|
||||||
(defvar fscotto/elfeed-initial-update-done nil
|
(defvar fscotto/elfeed-initial-update-done nil
|
||||||
"Non-nil once Elfeed has triggered its first automatic update this session.")
|
"Non-nil once Elfeed has triggered its first automatic update this session.")
|
||||||
@@ -131,7 +132,7 @@ Each entry is a cons cell of display string and session id."
|
|||||||
(defun fscotto/project-agent-dwim ()
|
(defun fscotto/project-agent-dwim ()
|
||||||
"Choose an agent for the current project and launch it externally."
|
"Choose an agent for the current project and launch it externally."
|
||||||
(interactive)
|
(interactive)
|
||||||
(let ((agent (completing-read "Agent: " '("Codex" "OpenCode") nil t)))
|
(let ((agent (completing-read "Agent: " '("Codex" "Gemini" "OpenCode") nil t)))
|
||||||
(pcase agent
|
(pcase agent
|
||||||
("OpenCode"
|
("OpenCode"
|
||||||
(let ((session-id (fscotto/project-opencode-latest-session-id)))
|
(let ((session-id (fscotto/project-opencode-latest-session-id)))
|
||||||
@@ -140,7 +141,10 @@ Each entry is a cons cell of display string and session id."
|
|||||||
(fscotto/project-root))
|
(fscotto/project-root))
|
||||||
(fscotto/project-opencode))))
|
(fscotto/project-opencode))))
|
||||||
("Codex"
|
("Codex"
|
||||||
(fscotto/launch-external-terminal '("codex" "resume" "--last"))))))
|
(fscotto/launch-external-terminal '("codex" "resume" "--last")))
|
||||||
|
("Gemini"
|
||||||
|
(fscotto/launch-external-terminal '("gemini" "--resume" "latest")
|
||||||
|
(fscotto/project-root))))))
|
||||||
|
|
||||||
(defun fscotto/project-opencode-session ()
|
(defun fscotto/project-opencode-session ()
|
||||||
"Resume a saved OpenCode session for the current project."
|
"Resume a saved OpenCode session for the current project."
|
||||||
@@ -154,15 +158,75 @@ Each entry is a cons cell of display string and session id."
|
|||||||
(fscotto/launch-external-terminal (list "opencode" "--session" session-id)
|
(fscotto/launch-external-terminal (list "opencode" "--session" session-id)
|
||||||
project-directory))))
|
project-directory))))
|
||||||
|
|
||||||
|
(defun fscotto/gemini-session-candidates (directory)
|
||||||
|
"Return Gemini session candidates for DIRECTORY.
|
||||||
|
|
||||||
|
Each entry is a cons cell of display string and session index.
|
||||||
|
Tries JSON output first, falls back to text parsing if unavailable."
|
||||||
|
(let* ((default-directory (file-name-as-directory directory))
|
||||||
|
(json-output (shell-command-to-string
|
||||||
|
"gemini --list-sessions --output-format json 2>/dev/null")))
|
||||||
|
(cond
|
||||||
|
((string-match "^{" json-output)
|
||||||
|
(ignore-errors
|
||||||
|
(require 'json)
|
||||||
|
(let* ((parsed (json-parse-string json-output))
|
||||||
|
(sessions (gethash "sessions" parsed)))
|
||||||
|
(when (vectorp sessions)
|
||||||
|
(seq-map-indexed
|
||||||
|
(lambda (s idx)
|
||||||
|
(let* ((idx-str (number-to-string (1+ idx)))
|
||||||
|
(msg (if (hash-table-p s)
|
||||||
|
(or (gethash "firstUserMessage" s) "Session")
|
||||||
|
"Session"))
|
||||||
|
(ts (and (hash-table-p s)
|
||||||
|
(ignore-errors (gethash "lastUpdated" s))
|
||||||
|
(when (stringp it) (string-trim it))))
|
||||||
|
(label (if ts (format "%s [%s]" msg ts) msg)))
|
||||||
|
(cons label idx-str)))
|
||||||
|
sessions)))))
|
||||||
|
(t
|
||||||
|
(let* ((output (shell-command-to-string "gemini --list-sessions"))
|
||||||
|
(lines (seq-filter (lambda (s) (string-match "\\S-" s))
|
||||||
|
(split-string output "\n" t)))
|
||||||
|
(data-lines (seq-drop lines 1))
|
||||||
|
(candidates nil))
|
||||||
|
(dolist (line data-lines)
|
||||||
|
(let ((trimmed (string-trim line)))
|
||||||
|
(when (string-match
|
||||||
|
(rx (group (one-or-more digit))
|
||||||
|
(one-or-more whitespace)
|
||||||
|
(group (one-or-more nonl)))
|
||||||
|
trimmed)
|
||||||
|
(push (cons (match-string 2 trimmed)
|
||||||
|
(match-string 1 trimmed))
|
||||||
|
candidates))))
|
||||||
|
(nreverse candidates))))))
|
||||||
|
|
||||||
|
(defun fscotto/project-gemini-session ()
|
||||||
|
"Choose and resume a Gemini session for the current project."
|
||||||
|
(interactive)
|
||||||
|
(let* ((project-directory (fscotto/project-root))
|
||||||
|
(candidates (fscotto/gemini-session-candidates project-directory)))
|
||||||
|
(unless candidates
|
||||||
|
(user-error "No Gemini sessions found for %s" project-directory))
|
||||||
|
(let* ((selection (completing-read "Gemini session: " candidates nil t))
|
||||||
|
(session-idx (cdr (assoc selection candidates))))
|
||||||
|
(fscotto/launch-external-terminal
|
||||||
|
(list "gemini" "--resume" session-idx)
|
||||||
|
project-directory))))
|
||||||
|
|
||||||
(defun fscotto/project-agent-session ()
|
(defun fscotto/project-agent-session ()
|
||||||
"Choose an agent and resume a saved session for the current project."
|
"Choose an agent and resume a saved session for the current project."
|
||||||
(interactive)
|
(interactive)
|
||||||
(let ((agent (completing-read "Agent session: " '("Codex" "OpenCode") nil t)))
|
(let ((agent (completing-read "Agent session: " '("Codex" "Gemini" "OpenCode") nil t)))
|
||||||
(pcase agent
|
(pcase agent
|
||||||
("OpenCode"
|
("OpenCode"
|
||||||
(fscotto/project-opencode-session))
|
(fscotto/project-opencode-session))
|
||||||
("Codex"
|
("Codex"
|
||||||
(fscotto/launch-external-terminal '("codex" "resume"))))))
|
(fscotto/launch-external-terminal '("codex" "resume")))
|
||||||
|
("Gemini"
|
||||||
|
(fscotto/project-gemini-session)))))
|
||||||
|
|
||||||
(defun fscotto/project-external-terminal ()
|
(defun fscotto/project-external-terminal ()
|
||||||
"Open the external terminal in project root."
|
"Open the external terminal in project root."
|
||||||
|
|||||||
Reference in New Issue
Block a user