summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPaul Buetow <paul@buetow.org>2026-06-09 22:25:07 +0300
committerPaul Buetow <paul@buetow.org>2026-06-09 22:25:07 +0300
commitfd5976e16281feab4c69588f3d13285e5b0ef175 (patch)
tree584b4033207f4a49ae5f4be59ebdc64c68a1bc5a
parent02eb0db90ccd4d21d31faa51a17abcb3d4e68e72 (diff)
rocky-vm-setup: add tmux default-terminal for 256-color helix support
-rw-r--r--prompts/skills/rocky-vm-setup/SKILL.md12
-rw-r--r--prompts/skills/rocky-vm-setup/references/git-remotes.md13
-rw-r--r--prompts/skills/rocky-vm-setup/references/notes.md5
-rw-r--r--prompts/skills/rocky-vm-setup/references/overview.md42
-rw-r--r--prompts/skills/rocky-vm-setup/references/privileges.md20
-rw-r--r--prompts/skills/rocky-vm-setup/references/rex.md22
-rw-r--r--prompts/skills/rocky-vm-setup/references/scripts.md20
-rw-r--r--prompts/skills/rocky-vm-setup/references/tmux.md62
-rw-r--r--prompts/skills/rocky-vm-setup/references/tools.md69
-rw-r--r--prompts/skills/rocky-vm-setup/references/zrepl.md12
10 files changed, 273 insertions, 4 deletions
diff --git a/prompts/skills/rocky-vm-setup/SKILL.md b/prompts/skills/rocky-vm-setup/SKILL.md
index 581fefe..cf287e8 100644
--- a/prompts/skills/rocky-vm-setup/SKILL.md
+++ b/prompts/skills/rocky-vm-setup/SKILL.md
@@ -76,10 +76,10 @@ Earth (outer tmux) uses the default **C-b** prefix. Rocky (inner tmux) uses **C-
**Visual distinction — you'll never confuse the two:**
-| Layer | Prefix | Active Border | Status Bar | Pane Indicators |
-|-------|--------|---------------|------------|-----------------|
-| **Earth (outer)** | `C-b` | **Magenta** | White-on-purple | Default blue |
-| **Rocky (inner)** | `C-g` | **Bright Red** | **Black-on-orange** with `[ROCKY]` label | **Red/orange** pane numbers, border labels |
+| Layer | Prefix | Active Border | Status Bar | Pane Indicators | TERM |
+|-------|--------|---------------|------------|-----------------|------|
+| **Earth (outer)** | `C-b` | **Magenta** | White-on-purple | Default blue | `tmux-256color` |
+| **Rocky (inner)** | `C-g` | **Bright Red** | **Black-on-orange** with `[ROCKY]` label | **Red/orange** pane numbers, border labels | `tmux-256color` |
**Workflow:**
| Key | Action |
@@ -110,6 +110,10 @@ set -g display-panes-active-colour brightred # active pane number
set -g pane-border-status top # show pane info on borders
set -g pane-border-format '#[fg=colour208] #{pane_index} #[fg=brightred]#{pane_title} '
set -g window-status-current-format ' #I*#[bg=brightred,fg=white] #W '
+
+# TERM inside tmux — must advertise 256 colors so helix/fzf/etc work
+set -g default-terminal 'tmux-256color'
+set -ga terminal-overrides ',xterm-256color:Tc,*-256color:Tc'
```
This is deployed by the `home_tmux_rocky` Rex task (runs only when `hostname =~ /rocky/`).
diff --git a/prompts/skills/rocky-vm-setup/references/git-remotes.md b/prompts/skills/rocky-vm-setup/references/git-remotes.md
new file mode 100644
index 0000000..bddc6c3
--- /dev/null
+++ b/prompts/skills/rocky-vm-setup/references/git-remotes.md
@@ -0,0 +1,13 @@
+# Git Remotes on Rocky
+
+All repos available on the local git server have `r0`, `r1`, `r2` remotes replacing any codeberg ones:
+
+```
+url = ssh://git@r0:30022/repos/REPO.git
+url = ssh://git@r1:30022/repos/REPO.git
+url = ssh://git@r2:30022/repos/REPO.git
+```
+
+Repos pushed: conf, dotfiles, gemtexter, gitsyncer, goprecords, gt, hexai, hypr, ior, photoalbum, rcm, snonux, tasksamurai, wireguardmeshgenerator
+
+The public keys of both `root` and `paul` on rocky are in the k3s `git-server-authorized-keys` secret (namespace `cicd`).
diff --git a/prompts/skills/rocky-vm-setup/references/notes.md b/prompts/skills/rocky-vm-setup/references/notes.md
new file mode 100644
index 0000000..124c345
--- /dev/null
+++ b/prompts/skills/rocky-vm-setup/references/notes.md
@@ -0,0 +1,5 @@
+# Notes
+
+- The `claude` wrapper must **not** be a shell script calling the JS wrapper — that caused a fork bomb because `cli-wrapper.cjs` tried to exec the `claude` binary but found the script instead. Use a direct symlink or the npm-installed binary.
+- Node.js is installed via `dnf module install nodejs:22/common` (pi 0.75.0+ requires Node >= 22.19.0).
+- `amp` panics in non-TTY environments — that's expected for a TUI editor.
diff --git a/prompts/skills/rocky-vm-setup/references/overview.md b/prompts/skills/rocky-vm-setup/references/overview.md
new file mode 100644
index 0000000..f4256d2
--- /dev/null
+++ b/prompts/skills/rocky-vm-setup/references/overview.md
@@ -0,0 +1,42 @@
+# Rocky VM Overview
+
+The `rocky` VM is a plain Rocky Linux 9 bhyve guest on **f3** (LAN IP `192.168.1.123`, WireGuard `192.168.2.123`). It is **not** part of the k3s cluster and serves as a general-purpose build / dev / git client VM.
+
+Parent infrastructure: see the [`f3s`](skills/f3s) skill (f3 host, zrepl, bhyve, git server).
+
+## SSH Keys
+
+| Key | Path | Purpose |
+|-----|------|---------|
+| Root VM key | `/root/.ssh/id_ed25519` | Git server SSH auth |
+| Paul VM key | `/home/paul/.ssh/id_ed25519` | Git server SSH auth, local remotes |
+
+The public keys are added to the k3s `git-server-authorized-keys` secret (namespace `cicd`) so both `root` and `paul` can push/pull via `git@r{N}:30022`.
+
+```sh
+# Regenerate if needed
+ssh-keygen -t ed25519 -N '' -f /root/.ssh/id_ed25519 -C 'root@rocky.f3s.lan.buetow.org'
+```
+
+## /etc/hosts
+
+Short LAN aliases for all f3s hosts (short, `.lan`, and `.lan.buetow.org` variants):
+
+```
+# f3s k3s node LAN aliases
+192.168.1.120 r0 r0.lan r0.lan.buetow.org
+192.168.1.121 r1 r1.lan r1.lan.buetow.org
+192.168.1.122 r2 r2.lan r2.lan.buetow.org
+
+# f3s FreeBSD host LAN aliases
+192.168.1.130 f0 f0.lan f0.lan.buetow.org
+192.168.1.131 f1 f1.lan f1.lan.buetow.org
+192.168.1.132 f2 f2.lan f2.lan.buetow.org
+192.168.1.133 f3 f3.lan f3.lan.buetow.org
+
+# f3s Raspberry Pi LAN aliases
+192.168.1.125 pi0 pi0.lan pi0.lan.buetow.org
+192.168.1.126 pi1 pi1.lan pi1.lan.buetow.org
+192.168.1.127 pi2 pi2.lan pi2.lan.buetow.org
+192.168.1.128 pi3 pi3.lan pi3.lan.buetow.org
+```
diff --git a/prompts/skills/rocky-vm-setup/references/privileges.md b/prompts/skills/rocky-vm-setup/references/privileges.md
new file mode 100644
index 0000000..d8f25ba
--- /dev/null
+++ b/prompts/skills/rocky-vm-setup/references/privileges.md
@@ -0,0 +1,20 @@
+# User and Privileges
+
+**`root`** — full root, used for package installs and Rex tasks.
+
+**`paul`**
+- **Removed from `wheel`** group. No general `sudo` access.
+- **Only** allowed to run without password:
+ ```
+ /home/paul/scripts/update-coding-agents
+ ```
+- Home: `/home/paul`
+- Git repos: `~/git/` (cloned via local `r0`/`r1`/`r2` remotes)
+
+## Sudoers config
+
+```
+paul ALL=(root) NOPASSWD: /home/paul/scripts/update-coding-agents
+```
+
+No other sudo privileges. The `wheel-nopasswd` file was removed and paul was removed from the `wheel` group.
diff --git a/prompts/skills/rocky-vm-setup/references/rex.md b/prompts/skills/rocky-vm-setup/references/rex.md
new file mode 100644
index 0000000..1eba83a
--- /dev/null
+++ b/prompts/skills/rocky-vm-setup/references/rex.md
@@ -0,0 +1,22 @@
+# Rex Usage
+
+The dotfiles repo (`~/git/dotfiles`) contains the main `Rexfile`.
+
+```sh
+# Install packages (as root)
+rex pkg_rocky
+
+# Deploy dotfiles (as paul)
+rex home
+```
+
+`pkg_rocky` uses Rex's `pkg` directive which requires root — no `sudo` wrappers.
+
+## Rocky-specific Rex tasks
+
+| Task | Runs when | What it does |
+|------|-----------|--------------|
+| `home_tmux_rocky` | `hostname =~ /rocky/` | Sources `tmux.rocky.conf` at the **end** of `tmux.conf` so red/orange colors win |
+| `pkg_rocky` | Manually (as root) | Installs packages: tmux, fish, helix, zoxide, fzf, golang, nodejs, etc. |
+
+The `home_tmux_rocky` task also cleans stale references from `tmux.local.conf` and strips the `extended-keys-format` line for tmux 3.2a compatibility.
diff --git a/prompts/skills/rocky-vm-setup/references/scripts.md b/prompts/skills/rocky-vm-setup/references/scripts.md
new file mode 100644
index 0000000..14fa7e0
--- /dev/null
+++ b/prompts/skills/rocky-vm-setup/references/scripts.md
@@ -0,0 +1,20 @@
+# Scripts
+
+## `/home/paul/scripts/update-coding-agents`
+
+```sh
+#!/bin/sh
+set -e
+if [ "$(id -u)" -ne 0 ]; then
+ exec sudo "$0" "$@"
+fi
+echo "Updating Claude Code..."
+npm update -g @anthropic-ai/claude-code @anthropic-ai/claude-code-linux-x64
+echo "Updating pi coding agent..."
+npm update -g @earendil-works/pi-coding-agent
+echo "All coding agents updated."
+```
+
+Run as paul: `$ /home/paul/scripts/update-coding-agents`
+
+Sudoers allows this specific script without a password. No other root access for paul.
diff --git a/prompts/skills/rocky-vm-setup/references/tmux.md b/prompts/skills/rocky-vm-setup/references/tmux.md
new file mode 100644
index 0000000..42ce58e
--- /dev/null
+++ b/prompts/skills/rocky-vm-setup/references/tmux.md
@@ -0,0 +1,62 @@
+# Nested tmux on Rocky
+
+Earth (outer tmux) uses the default **C-b** prefix. Rocky (inner tmux) uses **C-g** so you can control both layers.
+
+## Visual distinction
+
+| Layer | Prefix | Active Border | Status Bar | Pane Indicators |
+|-------|--------|---------------|------------|-----------------|
+| **Earth (outer)** | `C-b` | **Magenta** | White-on-purple | Default blue |
+| **Rocky (inner)** | `C-g` | **Bright Red** | **Black-on-orange** (`colour208`) with `[ROCKY]` label | **Red/orange** pane numbers, border labels |
+
+## Workflow
+
+| Key | Action |
+|-----|--------|
+| `C-b c` | Create window in outer tmux (earth) |
+| `C-g c` | Create window in inner tmux (rocky) |
+| `C-b b` | Send `C-b` through to inner tmux |
+| `C-g g` | Send `C-g` through to inner-inner tmux |
+
+## Config
+
+Rocky config is in `~/.config/tmux/tmux.rocky.conf` and sourced from `tmux.local.conf`:
+
+```sh
+# ~/.config/tmux/tmux.rocky.conf
+unbind C-b
+set -g prefix C-g
+bind C-g send-prefix
+
+# Drastic RED/ORANGE color scheme
+set -g pane-active-border-style 'fg=brightred,bold'
+set -g status-style 'bg=colour208,fg=black,bold'
+set -g status-left ' [ROCKY] #[bg=brightred,fg=white] #S '
+set -g window-status-current-style 'bg=brightred,fg=white,bold'
+set -g window-status-style 'bg=colour208,fg=black'
+
+# Active pane indicators
+set -g display-panes-colour colour208 # prefix+q pane numbers
+set -g display-panes-active-colour brightred # active pane number
+set -g pane-border-status top # show pane info on borders
+set -g pane-border-format '#[fg=colour208] #{pane_index} #[fg=brightred]#{pane_title} '
+set -g window-status-current-format ' #I*#[bg=brightred,fg=white] #W '
+```
+
+## Important: source ordering
+
+The rocky config must be sourced **at the end of** `~/.config/tmux/tmux.conf` so its color overrides win over the shared config. The `home_tmux_rocky` Rex task handles this by:
+
+1. Cleaning any stale reference from `tmux.local.conf`
+2. Appending `source-file ~/.config/tmux/tmux.rocky.conf` to the **end** of `tmux.conf`
+
+## Terminal / color support
+
+The inner tmux must advertise 256 colors (or helix/fzf/etc fall back to 16):
+
+```sh
+set -g default-terminal 'tmux-256color'
+set -ga terminal-overrides ',xterm-256color:Tc,*-256color:Tc'
+```
+
+Without this, tmux defaults to `TERM=screen` (8 colors) and helix themes break.
diff --git a/prompts/skills/rocky-vm-setup/references/tools.md b/prompts/skills/rocky-vm-setup/references/tools.md
new file mode 100644
index 0000000..c753414
--- /dev/null
+++ b/prompts/skills/rocky-vm-setup/references/tools.md
@@ -0,0 +1,69 @@
+# Installed Tools
+
+| Tool | Version | How Installed |
+|------|---------|---------------|
+| tmux | 3.2a | `dnf install -y tmux` |
+| tmux prefix | C-g | **Rocky override** — nested tmux (see [tmux.md](tmux.md)) |
+| fish | 3.7.1 | `dnf install -y fish` (EPEL) |
+| helix | 25.07.1 | `dnf install -y helix helix-themes` (EPEL) |
+| amp | 0.7.1 | Downloaded binary from GitHub releases |
+| claude-code | 2.1.169 | `npm install -g @anthropic-ai/claude-code` |
+| pi coding agent | 0.79.0 | `npm install -g @earendil-works/pi-coding-agent` |
+| taskwarrior | 2.6.2 | **Built from source** (see below) |
+| Rex | 1.16.1 | `cpanm Rex` (requires expat-devel, perl-LWP-Protocol-https) |
+| zoxide | 0.9.8 | `dnf install -y zoxide` (EPEL) |
+| fzf | 0.58.0 | `dnf install -y fzf` (EPEL) |
+| fzf fish plugin | — | **fisher install PatrickF1/fzf.fish** |
+| ask, hexai*, gt, gitsyncer, etc. | — | `go install codeberg.org/snonux/...` (see update::tools) |
+
+## Building taskwarrior from source
+
+Rocky 9 does not ship `task`/`taskwarrior`. v3.x requires Rust; v2.6.2 compiles cleanly.
+
+```sh
+# deps
+dnf install -y cmake gcc-c++ make libuuid-devel gnutls-devel libssh2-devel
+
+# build
+git clone --depth 1 --branch v2.6.2 \
+ https://github.com/GothenburgBitFactory/taskwarrior.git /tmp/tw-build
+cd /tmp/tw-build
+cmake -S . -B build -DCMAKE_BUILD_TYPE=Release
+cmake --build build -j$(nproc)
+cmake --install build
+
+# verify
+/usr/local/bin/task --version # 2.6.2
+```
+
+## First-run fish setup
+
+After the dotfiles `home` task deploys fish config, some plugins and binaries are expected but not yet present:
+
+```sh
+# 1. Install fisher (fish plugin manager)
+curl -sL https://raw.githubusercontent.com/jorgebucaran/fisher/main/functions/fisher.fish | source
+fisher install jorgebucaran/fisher
+
+# 2. Install the fzf.fish plugin (provides fzf_configure_bindings)
+fisher install PatrickF1/fzf.fish
+
+# 3. First-run taskwarrior creates ~/.taskrc
+yes | task >/dev/null 2>&1
+
+# 4. Install Go tooling binaries (run as paul)
+for prog in ask hexai hexai-lsp-server hexai-tmux-action hexai-tmux-edit hexai-mcp-server; do
+ go install codeberg.org/snonux/hexai/cmd/$prog@latest
+done
+for prog in tasksamurai timesamurai gt; do
+ go install codeberg.org/snonux/$prog/cmd/$prog@latest
+done
+for prog in gitsyncer gos snonux; do
+ go install codeberg.org/snonux/$prog/cmd/$prog@latest
+done
+# (foostore, loadbars, totalrecall, goprecords may need X11/GL deps for GUI — skip on headless)
+```
+
+## tmux 3.2a compatibility note
+
+The dotfiles `tmux.conf` includes `set -g extended-keys-format csi-u` (tmux 3.3+). On rocky this line is automatically stripped by the `home_tmux_rocky` Rex task. If you deploy manually, remove or comment out that line.
diff --git a/prompts/skills/rocky-vm-setup/references/zrepl.md b/prompts/skills/rocky-vm-setup/references/zrepl.md
new file mode 100644
index 0000000..4fafe64
--- /dev/null
+++ b/prompts/skills/rocky-vm-setup/references/zrepl.md
@@ -0,0 +1,12 @@
+# ZFS Snapshot / Replication
+
+The rocky VM dataset `zroot/bhyve/rocky` is managed by **zrepl** on the FreeBSD host f3. It is **not** included in local `zfs-periodic` snapshots.
+
+| Property | Value |
+|------------|-------|
+| Snapshots | Every 10 minutes via zrepl (`zrepl_` prefix) |
+| Replication | f3 → f2 (`zroot/sink/f3/zroot/bhyve/rocky`) |
+| Retention | 10 immediate + 24 hourly + 14 daily |
+| Local snap job | `zroot/bhyve/rocky` excluded from `local_zfs_snapshots` |
+
+See [`f3s` skill zrepl.md](skills/f3s/references/storage/zrepl.md) for full config.