mirror of
https://github.com/fscotto/infra.git
synced 2026-05-30 15:39:58 +00:00
Compare commits
27 Commits
feature/no
...
cd8c775630
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
cd8c775630 | ||
|
|
dab66bda47 | ||
|
|
e0fe207771 | ||
|
|
eaf1a7f182 | ||
|
|
4b5879a67e | ||
|
|
46b6bcd62c | ||
|
|
d48d2db0ba | ||
|
|
18ea0a02ad | ||
|
|
fa6b082381 | ||
|
|
e2a66c623f | ||
|
|
164b11bb73 | ||
|
|
10b0a6225b | ||
|
|
bcd8635d9e | ||
|
|
aa0f787d00 | ||
|
|
949ae2c47f | ||
|
|
16850eba53 | ||
|
|
e0869e72d6 | ||
|
|
e9af0bd1af | ||
|
|
763bbd8b9f | ||
|
|
950cbff85c | ||
|
|
003679f499 | ||
|
|
ab294f4cb7 | ||
|
|
325a405012 | ||
|
|
c9fa536bb5 | ||
|
|
a108957ba4 | ||
|
|
0eba6aa9c8 | ||
|
|
d036eee00a |
14
AGENTS.md
14
AGENTS.md
@@ -6,7 +6,9 @@ Ansible-driven personal infrastructure repo for Void desktops, Linux workstation
|
||||
- Main orchestration: `ansible/site.yml`
|
||||
- Inventory and layering inputs: `ansible/inventory/hosts.yml`, `ansible/inventory/group_vars/*.yml`, `ansible/inventory/host_vars/*.yml`
|
||||
- Dotfiles live under `dotfiles/`
|
||||
- OpenCode loads global instructions from `dotfiles/desktop/.config/opencode/opencode.json`
|
||||
- AI agent instructions (bootstrap, rules, knowledge) are centralized in `dotfiles/common/.config/ai/` and shared between OpenCode, Codex, and Gemini CLI.
|
||||
- OpenCode loads its entrypoint configuration from `dotfiles/common/.config/opencode/opencode.json`.
|
||||
- Codex config is rendered from `dotfiles/common/.codex/config.toml.j2` so `model_instructions_file` points to the deployed `~/.config/ai/bootstrap.md`.
|
||||
|
||||
## Topology
|
||||
- Void desktops: `ikaros`, `nymph`
|
||||
@@ -38,7 +40,7 @@ Ansible-driven personal infrastructure repo for Void desktops, Linux workstation
|
||||
- WSL dev: `ansible-playbook ansible/site.yml --limit deadalus-wsl --check --diff`
|
||||
- Server: `ansible-playbook ansible/site.yml --limit prometheus --check --diff`
|
||||
- Focused checks:
|
||||
- Emacs dotfiles only: `ansible-playbook ansible/site.yml --limit ikaros --tags emacs --check --diff` or `--limit nymph --tags emacs --check --diff`
|
||||
- Emacs dotfiles only: `ansible-playbook ansible/site.yml --limit ikaros --tags emacs --check --diff` or `--limit nymph --tags emacs --check --diff`
|
||||
- Sway/Noctalia bootstrap on nymph: `ansible-playbook ansible/site.yml --limit nymph --tags packages,dotfiles:desktop,sway --check --diff`
|
||||
- Mail bootstrap: `sh -n scripts/bootstrap_mail.sh` and `shellcheck scripts/bootstrap_mail.sh`
|
||||
- Windows bootstrap parse: `pwsh -NoProfile -Command "[void][System.Management.Automation.Language.Parser]::ParseFile('scripts/bootstrap_windows_workstation.ps1', [ref]$null, [ref]$null)"`
|
||||
@@ -55,6 +57,7 @@ Ansible-driven personal infrastructure repo for Void desktops, Linux workstation
|
||||
## Desktop Void Notes
|
||||
- `profile_desktop_common` owns the shared desktop bootstrap.
|
||||
- `.emacs.d` is deployed by a dedicated `profile_desktop_common` task tagged `emacs`.
|
||||
- NTFS filesystem support is provided by `ntfs-3g` in `ansible/inventory/group_vars/void.yml`.
|
||||
- User services are managed by `turnstile` and live under `dotfiles/desktop/.config/service/`.
|
||||
- `ssh-agent` runs under `turnstile` with stable socket `~/.local/state/ssh-agent/socket`.
|
||||
- Critical session entrypoints:
|
||||
@@ -73,6 +76,13 @@ Ansible-driven personal infrastructure repo for Void desktops, Linux workstation
|
||||
- `workstation_host_windows` runs with `gather_facts: false` and validates PSRP settings plus `windows_package_backend` before role execution.
|
||||
- Windows taskbar pins are driven by `windows_taskbar_pins` in `ansible/inventory/group_vars/workstation_host_windows.yml`; validate identifiers from a real Windows session before changing them.
|
||||
|
||||
## Coding Agent Notes
|
||||
- Shared agent packages live in `ai_agents_npm_packages` in `ansible/inventory/group_vars/all.yml`.
|
||||
- Shared agent dotfiles live in `ai_agents_dotfiles`; rendered configs live in `ai_agents_templates`.
|
||||
- Desktop, native workstation, and WSL profiles consume the shared agent package list; do not duplicate package entries in profile-specific vars.
|
||||
- `dotfiles_common` copies common dotfiles plus `ai_agents_dotfiles`, then renders `ai_agents_templates`.
|
||||
- Keep `.config/ai/` as the common instruction source; update agent-specific entrypoints to reference it rather than duplicating instruction text.
|
||||
|
||||
## Tooling Notes
|
||||
- Install local tooling with:
|
||||
- `python3 -m pip install ansible ansible-lint yamllint shellcheck-py`
|
||||
|
||||
@@ -50,6 +50,42 @@ common_dotfiles:
|
||||
dest: .vimrc
|
||||
mode: "0644"
|
||||
- name: bat config
|
||||
src: .config/bat/.config/bat/
|
||||
src: .config/bat/
|
||||
dest: .config/bat/
|
||||
mode: preserve
|
||||
|
||||
ai_agents_npm_packages:
|
||||
- name: "opencode-ai"
|
||||
state: latest
|
||||
- name: "@anthropic-ai/claude-code"
|
||||
state: latest
|
||||
- name: "@openai/codex"
|
||||
state: latest
|
||||
- name: "@google/gemini-cli"
|
||||
state: latest
|
||||
|
||||
ai_agents_enabled: true
|
||||
|
||||
ai_agents_dotfiles:
|
||||
- name: AI common config
|
||||
src: .config/ai/
|
||||
dest: .config/ai/
|
||||
mode: preserve
|
||||
- name: Gemini CLI config
|
||||
src: .gemini/
|
||||
dest: .gemini/
|
||||
mode: preserve
|
||||
- name: OpenCode config
|
||||
src: .config/opencode/
|
||||
dest: .config/opencode/
|
||||
mode: preserve
|
||||
- name: Claude Code memory
|
||||
src: .claude/
|
||||
dest: .claude/
|
||||
mode: preserve
|
||||
|
||||
ai_agents_templates:
|
||||
- name: Codex config
|
||||
src: .codex/config.toml.j2
|
||||
dest: .codex/config.toml
|
||||
mode: "0644"
|
||||
|
||||
@@ -146,9 +146,7 @@ desktop_source_tools:
|
||||
|
||||
desktop_binary_tools: []
|
||||
|
||||
desktop_npm_packages:
|
||||
- name: "opencode-ai"
|
||||
state: latest
|
||||
desktop_npm_packages: "{{ ai_agents_npm_packages + [] }}"
|
||||
|
||||
desktop_common_dotfiles:
|
||||
- name: XDG autostart entries
|
||||
@@ -183,10 +181,6 @@ desktop_common_dotfiles:
|
||||
src: .config/yt-dlp/
|
||||
dest: .config/yt-dlp/
|
||||
mode: preserve
|
||||
- name: OpenCode config
|
||||
src: .config/opencode/
|
||||
dest: .config/opencode/
|
||||
mode: preserve
|
||||
- name: MPV config
|
||||
src: .config/mpv/
|
||||
dest: .config/mpv/
|
||||
|
||||
@@ -6,6 +6,7 @@ effective_username: "{{ server_username }}"
|
||||
effective_user_group: "{{ server_user_group }}"
|
||||
effective_user_home: "{{ server_user_home }}"
|
||||
server_container_stack_dir: /opt/docker/server
|
||||
ai_agents_enabled: false
|
||||
|
||||
profile_packages:
|
||||
- avahi-daemon
|
||||
@@ -92,6 +93,14 @@ server_directories:
|
||||
owner: "1000"
|
||||
group: "1000"
|
||||
mode: "0755"
|
||||
- path: /srv/nextcloud
|
||||
owner: root
|
||||
group: root
|
||||
mode: "0755"
|
||||
- path: /srv/nextcloud/data
|
||||
owner: root
|
||||
group: root
|
||||
mode: "0755"
|
||||
|
||||
server_ufw_rules:
|
||||
- rule: allow
|
||||
|
||||
@@ -18,18 +18,23 @@ void_packages_base:
|
||||
- fuse3
|
||||
- gcc
|
||||
- gdb
|
||||
- gist
|
||||
- github-cli
|
||||
- gnome-keyring
|
||||
- go
|
||||
- gvfs
|
||||
- hugo
|
||||
- ImageMagick
|
||||
- isync
|
||||
- libsecret
|
||||
- libtool
|
||||
- linux-mainline
|
||||
- lm_sensors
|
||||
- msmtp
|
||||
- mu4e
|
||||
- network-manager-applet
|
||||
- nodejs
|
||||
- ntfs-3g
|
||||
- pavucontrol
|
||||
- pipewire
|
||||
- pkg-config
|
||||
@@ -42,6 +47,7 @@ void_packages_base:
|
||||
- simple-scan
|
||||
- socklog
|
||||
- socklog-void
|
||||
- speech-dispatcher
|
||||
- syncthing
|
||||
- system-config-printer
|
||||
- tmux
|
||||
|
||||
@@ -1,6 +1,4 @@
|
||||
---
|
||||
workstation_manage_opencode: true
|
||||
|
||||
workstation_npm_packages:
|
||||
- name: "opencode-ai"
|
||||
state: latest
|
||||
workstation_npm_packages: "{{ ai_agents_npm_packages + [] }}"
|
||||
|
||||
@@ -2,10 +2,10 @@
|
||||
hostname: nymph
|
||||
|
||||
desktop_sessions_enabled:
|
||||
- sway
|
||||
- i3
|
||||
|
||||
desktop_default_session: sway
|
||||
desktop_default_session_env: wayland
|
||||
desktop_default_session: i3
|
||||
desktop_default_session_env: xorg
|
||||
desktop_emptty_session_error_logging: rotate
|
||||
|
||||
host_xbps_repositories:
|
||||
@@ -16,6 +16,7 @@ host_packages:
|
||||
- cliphist
|
||||
- grimshot
|
||||
- nvidia
|
||||
- linux-mainline-headers
|
||||
- noctalia-shell
|
||||
- power-profiles-daemon
|
||||
- mesa-dri
|
||||
|
||||
@@ -16,6 +16,15 @@
|
||||
loop: "{{ xdg_user_directories | default([]) }}"
|
||||
when: "'void' in group_names"
|
||||
|
||||
- name: Extract templates kit to Templates directory
|
||||
tags: [dotfiles, dotfiles:common]
|
||||
ansible.builtin.unarchive:
|
||||
src: "{{ playbook_dir }}/../dotfiles/common/templates_kit.zip"
|
||||
dest: "{{ effective_user_home }}/Templates"
|
||||
owner: "{{ effective_username }}"
|
||||
group: "{{ effective_user_group }}"
|
||||
when: "'void' in group_names"
|
||||
|
||||
- name: Ensure SSH socket directory exists
|
||||
tags: [dotfiles, dotfiles:common]
|
||||
ansible.builtin.file:
|
||||
@@ -33,10 +42,41 @@
|
||||
owner: "{{ effective_username }}"
|
||||
group: "{{ effective_user_group }}"
|
||||
mode: "{{ item.mode }}"
|
||||
loop: "{{ common_dotfiles | default([]) }}"
|
||||
loop: >-
|
||||
{{
|
||||
(common_dotfiles | default([]))
|
||||
+ ((ai_agents_dotfiles | default([])) if (ai_agents_enabled | default(false)) else [])
|
||||
}}
|
||||
loop_control:
|
||||
label: "{{ item.dest }}"
|
||||
|
||||
- name: Ensure AI config directories exist
|
||||
tags: [dotfiles, dotfiles:common]
|
||||
ansible.builtin.file:
|
||||
path: "{{ effective_user_home }}/{{ item }}"
|
||||
state: directory
|
||||
owner: "{{ effective_username }}"
|
||||
group: "{{ effective_user_group }}"
|
||||
mode: "0755"
|
||||
loop:
|
||||
- .codex
|
||||
when:
|
||||
- ai_agents_enabled | default(false)
|
||||
- (ai_agents_templates | default([])) | length > 0
|
||||
|
||||
- name: Render AI agent templates
|
||||
tags: [dotfiles, dotfiles:common]
|
||||
ansible.builtin.template:
|
||||
src: "{{ playbook_dir }}/../dotfiles/common/{{ item.src }}"
|
||||
dest: "{{ effective_user_home }}/{{ item.dest }}"
|
||||
owner: "{{ effective_username }}"
|
||||
group: "{{ effective_user_group }}"
|
||||
mode: "{{ item.mode }}"
|
||||
loop: "{{ ai_agents_templates | default([]) }}"
|
||||
loop_control:
|
||||
label: "{{ item.dest }}"
|
||||
when: ai_agents_enabled | default(false)
|
||||
|
||||
- name: Refresh bat cache
|
||||
tags: [dotfiles, dotfiles:common]
|
||||
ansible.builtin.command:
|
||||
|
||||
@@ -36,6 +36,25 @@ services:
|
||||
- web
|
||||
- gitea
|
||||
|
||||
# Disabled: prometheus does not have enough resources to run Nextcloud AIO.
|
||||
# nextcloud-aio-mastercontainer:
|
||||
# image: ghcr.io/nextcloud-releases/all-in-one:latest
|
||||
# container_name: nextcloud-aio-mastercontainer
|
||||
# init: true
|
||||
# restart: always
|
||||
# ports:
|
||||
# - "127.0.0.1:8080:8080"
|
||||
# environment:
|
||||
# APACHE_PORT: "11000"
|
||||
# APACHE_IP_BINDING: "0.0.0.0"
|
||||
# APACHE_ADDITIONAL_NETWORK: "server_web"
|
||||
# NEXTCLOUD_DATADIR: "/srv/nextcloud/data"
|
||||
# volumes:
|
||||
# - "nextcloud_aio_mastercontainer:/mnt/docker-aio-config"
|
||||
# - "/var/run/docker.sock:/var/run/docker.sock:ro"
|
||||
# networks:
|
||||
# - web
|
||||
|
||||
navidromedb:
|
||||
image: postgres:13
|
||||
container_name: navidromedb
|
||||
@@ -87,6 +106,11 @@ services:
|
||||
|
||||
networks:
|
||||
web:
|
||||
name: server_web
|
||||
external: false
|
||||
gitea:
|
||||
external: false
|
||||
|
||||
# volumes:
|
||||
# nextcloud_aio_mastercontainer:
|
||||
# name: nextcloud_aio_mastercontainer
|
||||
|
||||
5
dotfiles/common/.claude/CLAUDE.md
Normal file
5
dotfiles/common/.claude/CLAUDE.md
Normal file
@@ -0,0 +1,5 @@
|
||||
# Claude Code Global Context
|
||||
|
||||
Import the shared coding agent bootstrap context:
|
||||
|
||||
@~/.config/ai/bootstrap.md
|
||||
16
dotfiles/common/.codex/config.toml.j2
Normal file
16
dotfiles/common/.codex/config.toml.j2
Normal file
@@ -0,0 +1,16 @@
|
||||
model = "gpt-5.5"
|
||||
model_reasoning_effort = "medium"
|
||||
|
||||
model_instructions_file = "{{ effective_user_home }}/.config/ai/bootstrap.md"
|
||||
|
||||
[projects."/home/fscotto/AnsiblePlaybook"]
|
||||
trust_level = "trusted"
|
||||
|
||||
[tui]
|
||||
theme = "coldark-dark"
|
||||
|
||||
[tui.model_availability_nux]
|
||||
"gpt-5.5" = 3
|
||||
|
||||
[features]
|
||||
memories = true
|
||||
7
dotfiles/common/.config/opencode/opencode.json
Normal file
7
dotfiles/common/.config/opencode/opencode.json
Normal file
@@ -0,0 +1,7 @@
|
||||
{
|
||||
"$schema": "https://opencode.ai/config.json",
|
||||
"instructions": [
|
||||
"~/.config/ai/bootstrap.md",
|
||||
"~/.config/ai/rules/safety.md"
|
||||
]
|
||||
}
|
||||
14
dotfiles/common/.gemini/settings.json
Normal file
14
dotfiles/common/.gemini/settings.json
Normal file
@@ -0,0 +1,14 @@
|
||||
{
|
||||
"security": {
|
||||
"auth": {
|
||||
"selectedType": "oauth-personal"
|
||||
}
|
||||
},
|
||||
"context": {
|
||||
"fileName": [
|
||||
"~/.config/ai/bootstrap.md",
|
||||
"~/.config/ai/rules/safety.md",
|
||||
"~/.config/ai/AGENTS.md"
|
||||
]
|
||||
}
|
||||
}
|
||||
BIN
dotfiles/common/templates_kit.zip
Normal file
BIN
dotfiles/common/templates_kit.zip
Normal file
Binary file not shown.
Binary file not shown.
@@ -12,7 +12,7 @@ ap() {
|
||||
cmd+=(--tag "$1")
|
||||
fi
|
||||
|
||||
printf '+ %s\n' "${cmd[*]}"
|
||||
printf '\033[0;36m+ %s\033[0m\n' "${cmd[*]}"
|
||||
"${cmd[@]}"
|
||||
)
|
||||
}
|
||||
|
||||
@@ -40,5 +40,6 @@ white = "#ffffff"
|
||||
[keyboard]
|
||||
bindings = [
|
||||
{ key = "V", mods = "Control|Shift", action = "Paste" },
|
||||
{ key = "C", mods = "Control|Shift", action = "Copy" }
|
||||
{ key = "C", mods = "Control|Shift", action = "Copy" },
|
||||
{ key = "Return", mods = "Shift", chars = "\u001B\r" }
|
||||
]
|
||||
|
||||
@@ -9,7 +9,7 @@ font pango:Liberation Mono 10
|
||||
exec --no-startup-id dex --autostart --environment i3
|
||||
exec --no-startup-id gnome-keyring-daemon --start --components=secrets
|
||||
exec_always --no-startup-id setxkbmap -layout us -variant intl
|
||||
exec_always --no-startup-id feh --bg-fill ~/.config/i3/wallpapers/void-minimalist2.png
|
||||
exec_always --no-startup-id feh --bg-center ~/.config/i3/wallpapers/wallpaper-161664.jpg
|
||||
exec_always --no-startup-id ~/.config/i3/scripts/setup-gtk-theme.sh
|
||||
exec --no-startup-id /usr/libexec/xdg-desktop-portal
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
#!/bin/sh
|
||||
|
||||
wallpaper="$HOME/.config/i3/wallpapers/void-minimalist.png"
|
||||
wallpaper="$HOME/.config/i3/wallpapers/maxresdefault.jpg"
|
||||
cached="$HOME/.cache/i3lock/wallpaper.png"
|
||||
dims_cache="$HOME/.cache/i3lock/dims.txt"
|
||||
dims=$(xdotool getdisplaygeometry | tr ' ' 'x')
|
||||
|
||||
BIN
dotfiles/desktop/.config/i3/wallpapers/785318-darth-vader.jpg
Executable file
BIN
dotfiles/desktop/.config/i3/wallpapers/785318-darth-vader.jpg
Executable file
Binary file not shown.
|
After Width: | Height: | Size: 82 KiB |
BIN
dotfiles/desktop/.config/i3/wallpapers/maxresdefault.jpg
Executable file
BIN
dotfiles/desktop/.config/i3/wallpapers/maxresdefault.jpg
Executable file
Binary file not shown.
|
After Width: | Height: | Size: 116 KiB |
BIN
dotfiles/desktop/.config/i3/wallpapers/wallpaper-161664.jpg
Executable file
BIN
dotfiles/desktop/.config/i3/wallpapers/wallpaper-161664.jpg
Executable file
Binary file not shown.
|
After Width: | Height: | Size: 118 KiB |
@@ -1,7 +0,0 @@
|
||||
{
|
||||
"$schema": "https://opencode.ai/config.json",
|
||||
"instructions": [
|
||||
"~/.config/opencode/bootstrap.md",
|
||||
"~/.config/opencode/rules/safety.md"
|
||||
]
|
||||
}
|
||||
@@ -105,8 +105,8 @@
|
||||
(define-key projectile-command-map (kbd "v") #'fscotto/project-multi-vterm)
|
||||
(define-key projectile-command-map (kbd "V") nil)
|
||||
(define-key projectile-command-map (kbd "x") #'fscotto/project-external-terminal)
|
||||
(define-key projectile-command-map (kbd "a") #'fscotto/project-opencode-dwim)
|
||||
(define-key projectile-command-map (kbd "A") #'fscotto/project-opencode-session)
|
||||
(define-key projectile-command-map (kbd "a") #'fscotto/project-agent-dwim)
|
||||
(define-key projectile-command-map (kbd "A") #'fscotto/project-agent-session)
|
||||
(define-key projectile-command-map (kbd "g") #'fscotto/project-magit-status))
|
||||
|
||||
;;;; LSP
|
||||
|
||||
@@ -2,9 +2,9 @@
|
||||
|
||||
;; Load default theme
|
||||
(use-package nordic-night-theme
|
||||
:ensure t)
|
||||
|
||||
(load-theme 'nordic-night t)
|
||||
:ensure t
|
||||
:config
|
||||
(load-theme 'nordic-night t))
|
||||
|
||||
;; Setting default font
|
||||
(set-frame-font "Liberation Mono 14" nil t)
|
||||
|
||||
@@ -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
|
||||
(defvar fscotto/elfeed-initial-update-done nil
|
||||
"Non-nil once Elfeed has triggered its first automatic update this session.")
|
||||
@@ -128,16 +129,24 @@ Each entry is a cons cell of display string and session id."
|
||||
"Return the latest saved OpenCode session id for the current project."
|
||||
(cdr (car (fscotto/opencode-session-candidates (fscotto/project-root)))))
|
||||
|
||||
(defun fscotto/project-opencode-dwim ()
|
||||
"Open the most useful OpenCode session for the current project.
|
||||
|
||||
Resume the latest saved session when available, otherwise create a new one."
|
||||
(defun fscotto/project-agent-dwim ()
|
||||
"Choose an agent for the current project and launch it externally."
|
||||
(interactive)
|
||||
(let ((session-id (fscotto/project-opencode-latest-session-id)))
|
||||
(if session-id
|
||||
(fscotto/launch-external-terminal (list "opencode" "--session" session-id)
|
||||
(fscotto/project-root))
|
||||
(fscotto/project-opencode))))
|
||||
(let ((agent (completing-read "Agent: " '("Claude" "Codex" "Gemini" "OpenCode") nil t)))
|
||||
(pcase agent
|
||||
("Claude"
|
||||
(fscotto/launch-external-terminal '("claude" "--continue")))
|
||||
("OpenCode"
|
||||
(let ((session-id (fscotto/project-opencode-latest-session-id)))
|
||||
(if session-id
|
||||
(fscotto/launch-external-terminal (list "opencode" "--session" session-id)
|
||||
(fscotto/project-root))
|
||||
(fscotto/project-opencode))))
|
||||
("Codex"
|
||||
(fscotto/launch-external-terminal '("codex" "resume" "--last")))
|
||||
("Gemini"
|
||||
(fscotto/launch-external-terminal '("gemini" "--resume" "latest")
|
||||
(fscotto/project-root))))))
|
||||
|
||||
(defun fscotto/project-opencode-session ()
|
||||
"Resume a saved OpenCode session for the current project."
|
||||
@@ -151,6 +160,78 @@ Resume the latest saved session when available, otherwise create a new one."
|
||||
(fscotto/launch-external-terminal (list "opencode" "--session" session-id)
|
||||
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 ()
|
||||
"Choose an agent and resume a saved session for the current project."
|
||||
(interactive)
|
||||
(let ((agent (completing-read "Agent session: " '("Claude" "Codex" "Gemini" "OpenCode") nil t)))
|
||||
(pcase agent
|
||||
("Claude"
|
||||
(fscotto/launch-external-terminal '("claude" "--resume")))
|
||||
("OpenCode"
|
||||
(fscotto/project-opencode-session))
|
||||
("Codex"
|
||||
(fscotto/launch-external-terminal '("codex" "resume")))
|
||||
("Gemini"
|
||||
(fscotto/project-gemini-session)))))
|
||||
|
||||
(defun fscotto/project-external-terminal ()
|
||||
"Open the external terminal in project root."
|
||||
(interactive)
|
||||
|
||||
@@ -145,8 +145,8 @@
|
||||
"C-c p t" "Test"
|
||||
"C-c p v" "Open multi-vterm in project"
|
||||
"C-c p x" "Open external term"
|
||||
"C-c p a" "OpenCode (dwim)"
|
||||
"C-c p A" "Choose OpenCode session"
|
||||
"C-c p a" "Choose agent"
|
||||
"C-c p A" "Choose agent session"
|
||||
"C-c p e" "Edit project config"
|
||||
"C-c p g" "Project Git status"
|
||||
"C-c p 4" "Other Window"
|
||||
|
||||
@@ -1,4 +1,8 @@
|
||||
Host vps
|
||||
IdentityFile ~/.ssh/id_rsa_vps
|
||||
|
||||
Host *
|
||||
IdentityFile ~/.ssh/id_ed25519
|
||||
ControlMaster auto
|
||||
ControlPath ~/.local/state/ssh/sockets/%r@%h-%p
|
||||
ControlPersist 600
|
||||
|
||||
73
scripts/cleanup_nymph_sway.sh
Executable file
73
scripts/cleanup_nymph_sway.sh
Executable file
@@ -0,0 +1,73 @@
|
||||
#!/usr/bin/env sh
|
||||
|
||||
set -eu
|
||||
|
||||
PACKAGES="
|
||||
swayfx
|
||||
kanshi
|
||||
grim
|
||||
grimshot
|
||||
slurp
|
||||
wl-clipboard
|
||||
xdg-desktop-portal-wlr
|
||||
cliphist
|
||||
noctalia-shell
|
||||
"
|
||||
|
||||
USER_PATHS="
|
||||
$HOME/.config/sway
|
||||
$HOME/.config/kanshi
|
||||
$HOME/.config/noctalia
|
||||
$HOME/.local/share/noctalia-plugins
|
||||
$HOME/.local/bin/start-sway-session
|
||||
"
|
||||
|
||||
SYSTEM_FILES="
|
||||
/etc/emptty/wayland-sessions/Sway.desktop
|
||||
/etc/xbps.d/noctalia.conf
|
||||
"
|
||||
|
||||
check_host() {
|
||||
if [ "$(hostname)" != "nymph" ]; then
|
||||
printf 'Error: questo script è destinato solo a nymph (hostname attuale: %s)\n' "$(hostname)" >&2
|
||||
exit 1
|
||||
fi
|
||||
}
|
||||
|
||||
remove_packages() {
|
||||
printf 'Rimozione pacchetti swayfx+noctalia...\n'
|
||||
# shellcheck disable=SC2086
|
||||
sudo xbps-remove -Ry $PACKAGES
|
||||
printf 'Rimozione dipendenze orfane...\n'
|
||||
sudo xbps-remove -o
|
||||
}
|
||||
|
||||
remove_user_configs() {
|
||||
printf 'Rimozione configurazioni utente...\n'
|
||||
for path in $USER_PATHS; do
|
||||
if [ -e "$path" ]; then
|
||||
rm -rf "$path"
|
||||
printf ' rimosso: %s\n' "$path"
|
||||
fi
|
||||
done
|
||||
}
|
||||
|
||||
remove_system_files() {
|
||||
printf 'Rimozione file di sistema...\n'
|
||||
for file in $SYSTEM_FILES; do
|
||||
if [ -e "$file" ]; then
|
||||
sudo rm -f "$file"
|
||||
printf ' rimosso: %s\n' "$file"
|
||||
fi
|
||||
done
|
||||
}
|
||||
|
||||
main() {
|
||||
check_host
|
||||
remove_packages
|
||||
remove_user_configs
|
||||
remove_system_files
|
||||
printf 'Cleanup completato.\n'
|
||||
}
|
||||
|
||||
main "$@"
|
||||
Reference in New Issue
Block a user