Files
dotfiles/docs/superpowers/plans/2026-05-02-flameshot-screenshot.md
funman300 7a5a276efd docs: track implementation plans for fan-profile auto and flameshot
Both plans were generated during their respective implementation
runs but never committed.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-05 23:18:31 -07:00

341 lines
12 KiB
Markdown

# Flameshot Screenshot Swap Implementation Plan
> **For agentic workers:** REQUIRED SUB-SKILL: Use superpowers:subagent-driven-development (recommended) or superpowers:executing-plans to implement this plan task-by-task. Steps use checkbox (`- [ ]`) syntax for tracking.
**Goal:** Replace the bespoke `scripts/screenshot.sh` pipeline with Flameshot, bound to `Mod+Print`.
**Architecture:** Pure tool swap. Install Flameshot from `extra`, generate a small `~/.config/flameshot/flameshot.ini` from `install.sh` (mirrors the existing `mako/config` generator pattern), point `Mod+Print` at `flameshot gui`, then delete the old script + symlink + install.sh entry. Tasks ordered so `Mod+Print` keeps working at every commit boundary.
**Tech Stack:** flameshot (Qt6, official Arch `extra`), niri, bash for `install.sh`.
**Spec:** `docs/superpowers/specs/2026-05-02-flameshot-screenshot-design.md`
**Verification model:** Bash + system commands. Each task ends with shell verification commands and a one-line user check (e.g. "press `Mod+Print`, confirm Flameshot toolbar appears"). The controller has a display; subagents do not — defer visual checks to the controller.
---
## File Structure
| File | Change |
|---|---|
| `packages.txt` | add `flameshot` |
| `install.sh` | remove the `ln -sf ".../screenshot.sh" ...` line; add a flameshot.ini generator block (idempotent: only writes if file doesn't exist) |
| `niri/config.kdl` | change `Mod+Print { spawn "screenshot"; }` to `Mod+Print { spawn "flameshot" "gui"; }` |
| `scripts/screenshot.sh` | deleted |
| `~/.local/bin/screenshot` | symlink removed (filesystem only, not git-tracked) |
| `~/.config/flameshot/flameshot.ini` | created on disk by the install.sh block (filesystem only, not git-tracked) |
---
## Task 1: Install Flameshot and add to packages.txt
After this task, the `flameshot` binary is on PATH and `packages.txt` declares it as a dependency. The old screenshot script and keybind are still wired up — nothing functional has changed yet.
**Files:**
- Modify: `packages.txt` (add one line)
- [ ] **Step 1: Install flameshot via the AUR helper**
```bash
yay -S --needed --noconfirm flameshot
```
Expected: package installs (or "is up to date" if already present). If `yay` is unavailable, substitute `paru` or `sudo pacman -S --needed --noconfirm flameshot`.
- [ ] **Step 2: Verify the binary is on PATH**
```bash
flameshot --version
```
Expected: a version string like `Flameshot v13.3.0 (compiled with Qt 6.x)`. If "command not found", the install failed — escalate.
- [ ] **Step 3: Add `flameshot` to `packages.txt`**
Open `packages.txt` and insert `flameshot` in alphabetical-ish order. The existing list is roughly grouped by topic, not strictly sorted. Insert after `fw-fanctrl` (line 39) so it sits with the small one-off utilities cluster:
```
fw-fanctrl
satty
starship
flameshot
```
(Final order doesn't matter as long as `flameshot` appears once and on its own line. Don't reorder unrelated lines.)
- [ ] **Step 4: Verify packages.txt is well-formed**
```bash
grep -c "^flameshot$" packages.txt
```
Expected: `1` (exactly one occurrence).
- [ ] **Step 5: Commit**
```bash
git add packages.txt
git commit -m "packages: add flameshot"
```
---
## Task 2: Add flameshot config generator to install.sh and run it
After this task, `~/.config/flameshot/flameshot.ini` exists with the spec's defaults. Re-running `install.sh` will not clobber the file (the generator has an `[ ! -f ]` guard so user-saved preferences like `savePath` are preserved on subsequent runs). The screenshot keybind still points at the old script.
**Files:**
- Modify: `install.sh` (insert generator block after the existing mako python block, around line 42)
- [ ] **Step 1: Insert the flameshot config generator into `install.sh`**
Find the existing mako block in `install.sh`. It looks like:
```bash
python3 - <<'PYEOF'
import json, os
c = json.load(open("theme/colors.json"))
config = f"""background-color={c['background']}
text-color={c['foreground']}
border-size=2
border-color={c['blue']}
default-timeout=4000
"""
open(os.path.expanduser("~/.config/mako/config"), "w").write(config)
PYEOF
```
Immediately *after* the `PYEOF` line that closes the mako block, insert:
```bash
mkdir -p ~/.config/flameshot
if [ ! -f ~/.config/flameshot/flameshot.ini ]; then
cat > ~/.config/flameshot/flameshot.ini <<'INI'
[General]
disabledTrayIcon=true
showStartupLaunchMessage=false
showHelp=false
copyAndCloseAfterUpload=true
uiColor=#81a2be
contrastUiColor=#1d1f21
contrastOpacity=190
INI
fi
```
The `[ ! -f ]` guard is required: Flameshot writes runtime state (savePath, last folder) back to this file, so re-running `install.sh` must not overwrite user preferences.
- [ ] **Step 2: Sanity-check `install.sh` parses as bash**
```bash
bash -n install.sh
```
Expected: no output, exit 0. (`-n` is dry-run syntax check.)
- [ ] **Step 3: Run the new block manually to create the live config**
You can either run install.sh in full, or extract just the new block. Cleanest is to run the block standalone:
```bash
mkdir -p ~/.config/flameshot
if [ ! -f ~/.config/flameshot/flameshot.ini ]; then
cat > ~/.config/flameshot/flameshot.ini <<'INI'
[General]
disabledTrayIcon=true
showStartupLaunchMessage=false
showHelp=false
copyAndCloseAfterUpload=true
uiColor=#81a2be
contrastUiColor=#1d1f21
contrastOpacity=190
INI
fi
```
- [ ] **Step 4: Verify the file was written with the right contents**
```bash
cat ~/.config/flameshot/flameshot.ini
```
Expected output:
```
[General]
disabledTrayIcon=true
showStartupLaunchMessage=false
showHelp=false
copyAndCloseAfterUpload=true
uiColor=#81a2be
contrastUiColor=#1d1f21
contrastOpacity=190
```
- [ ] **Step 5: Verify the guard works (re-run is a no-op)**
```bash
# Mutate the file slightly
echo "savePath=/home/alex/Pictures" >> ~/.config/flameshot/flameshot.ini
# Re-run the generator block (paste from Step 3)
mkdir -p ~/.config/flameshot
if [ ! -f ~/.config/flameshot/flameshot.ini ]; then
cat > ~/.config/flameshot/flameshot.ini <<'INI'
[General]
disabledTrayIcon=true
showStartupLaunchMessage=false
showHelp=false
copyAndCloseAfterUpload=true
uiColor=#81a2be
contrastUiColor=#1d1f21
contrastOpacity=190
INI
fi
# Confirm the savePath line is still present (file was not regenerated)
grep "^savePath=" ~/.config/flameshot/flameshot.ini
```
Expected: `savePath=/home/alex/Pictures` (proves the `[ ! -f ]` guard prevented overwrite).
Clean up the test mutation (so the file matches the spec's defaults again):
```bash
sed -i '/^savePath=/d' ~/.config/flameshot/flameshot.ini
```
- [ ] **Step 6: Commit**
```bash
git add install.sh
git commit -m "install: generate flameshot.ini with idempotent guard"
```
---
## Task 3: Repoint `Mod+Print` to Flameshot
After this task, pressing `Mod+Print` opens Flameshot's GUI (region selector + on-canvas annotation toolbar). The old `scripts/screenshot.sh` is no longer reachable via keybind, but the script and its symlink still exist on disk — Task 4 deletes them.
**Files:**
- Modify: `niri/config.kdl` (line 87)
- [ ] **Step 1: Replace the keybind**
In `niri/config.kdl`, find line 87:
```kdl
Mod+Print { spawn "screenshot"; }
```
Replace with:
```kdl
Mod+Print { spawn "flameshot" "gui"; }
```
Note the two-string form for `spawn` — niri's `spawn` action takes the program and each argument as separate quoted strings. `spawn "flameshot gui"` (single string) would not work; niri would try to exec a binary literally named `flameshot gui`.
- [ ] **Step 2: Validate the niri config**
```bash
niri validate
```
Expected: exit 0 and a final line `INFO niri: config is valid`. Any "ERROR" or non-zero exit means a syntax issue — fix before continuing.
- [ ] **Step 3: User-side visual verification (controller only — subagent skip)**
Niri picks up `config.kdl` changes live; no reload needed. Press `Mod+Print`. Expected: Flameshot's region-selector overlay appears, with a floating toolbar showing drawing tools and Save/Copy/Discard buttons. Cancel out (Esc) without taking a real screenshot.
If a portal permission prompt appears the first time, allow it — Flameshot uses `xdg-desktop-portal-wlr` to capture under Wayland.
If `Mod+Print` does nothing or you see "command not found" in `journalctl --user`, the binary isn't on PATH for niri — re-run Task 1, Step 1.
- [ ] **Step 4: Commit**
```bash
git add niri/config.kdl
git commit -m "niri: bind Mod+Print to flameshot gui"
```
---
## Task 4: Delete the old screenshot script, symlink, and install.sh entry
After this task, all traces of `scripts/screenshot.sh` are gone — script file deleted, `~/.local/bin/screenshot` symlink removed, and the corresponding line in `install.sh` removed so re-running it doesn't recreate the dead symlink. `Mod+Print` continues to work via Flameshot.
**Files:**
- Delete: `scripts/screenshot.sh`
- Modify: `install.sh` (remove one line)
- Filesystem: `~/.local/bin/screenshot` (remove symlink)
- [ ] **Step 1: Remove the symlink line from `install.sh`**
In `install.sh`, find this line (it's inside the `==> Installing scripts` section, around line 61):
```bash
ln -sf "$(pwd)/scripts/screenshot.sh" ~/.local/bin/screenshot
```
Delete the entire line. The surrounding lines (other `ln -sf` calls for the remaining scripts) stay intact.
- [ ] **Step 2: Sanity-check install.sh still parses**
```bash
bash -n install.sh
```
Expected: no output, exit 0.
- [ ] **Step 3: Delete the live symlink**
```bash
rm ~/.local/bin/screenshot
```
Expected: silent success. Verify it's gone:
```bash
ls -la ~/.local/bin/screenshot 2>&1
```
Expected: `cannot access ... No such file or directory`.
- [ ] **Step 4: Delete the script file from the repo**
```bash
git rm scripts/screenshot.sh
```
Expected: `rm 'scripts/screenshot.sh'`.
- [ ] **Step 5: Verify nothing else in the repo references the deleted script**
```bash
grep -rn "screenshot" --include="*.kdl" --include="*.sh" --include="*.jsonc" --include="*.toml" --include="*.fish" --exclude-dir=docs /home/alex/Documents/dotfiles
```
Expected: zero hits, or only matches inside markdown/spec files (which the include-glob excludes anyway). If the keybind from Task 3 still says `spawn "screenshot"`, Task 3 didn't land — go back and check.
- [ ] **Step 6: Confirm `Mod+Print` still works (controller only — subagent skip)**
Press `Mod+Print`. Flameshot's GUI should still appear (this isn't a regression test — it's just a sanity check that nothing in the cleanup broke the live keybind).
- [ ] **Step 7: Commit**
```bash
git add install.sh scripts/screenshot.sh
git commit -m "screenshot: remove old grim/slurp/wofi pipeline (replaced by flameshot)"
```
(`git rm` from Step 4 already staged the deletion; this commit picks up both the staged deletion and the install.sh edit.)
---
## Final verification
- [ ] **Pressing `Mod+Print` opens Flameshot.** Region selector + on-canvas toolbar with drawing tools and Save/Copy/Discard buttons.
- [ ] **`flameshot gui` produces a usable capture.** Pick a region, click Copy → confirm clipboard has the image (`wl-paste --list-types | grep image/png` should show `image/png`). Click Save → file lands wherever Flameshot prompts (first-time prompt expected; pick `~/Pictures`).
- [ ] **No leftover references.** `grep -rn "screenshot\.sh\|/local/bin/screenshot" /home/alex/Documents/dotfiles --exclude-dir=.git --exclude-dir=docs` → no hits.
- [ ] **install.sh is re-runnable without breakage.** Optional: rerun `bash install.sh` and confirm flameshot.ini is preserved (the `[ ! -f ]` guard) and no `~/.local/bin/screenshot` symlink reappears (because the line was removed).
- [ ] **Toolbar colors match the theme.** The Flameshot floating toolbar should show the Tomorrow Night blue accent (`#81a2be`) on the dark background (`#1d1f21`).