diff --git a/.gitignore b/.gitignore index 37f3228..9f71d48 100644 --- a/.gitignore +++ b/.gitignore @@ -57,6 +57,11 @@ [Tt][Ee][Ss][Tt][Ii][Nn][Gg]/ .[Tt][Ee][Ss][Tt][Ii][Nn][Gg]/ +# ──────────────────── Planning Artifacts ─────────────────── +# Catalog files generated by pre-implementation analysis passes +opinionated_catalog.md +docs/superpowers + # ─────────────────── AI Sessions and Rules ────────────────── # Matches CLAUDE.md, .claud*, etc. [Cc][Ll][Aa][Uu][Dd][Ee].[Mm][Dd] diff --git a/docs/superpowers/plans/2026-06-07-first-run.md b/docs/superpowers/plans/2026-06-07-first-run.md deleted file mode 100644 index d04cb3a..0000000 --- a/docs/superpowers/plans/2026-06-07-first-run.md +++ /dev/null @@ -1,328 +0,0 @@ -# First-Run Initialization Routine — 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:** Create `conf.d/first_run.fish` that runs exactly once on the first interactive fish session — showing a welcome message, auto-installing Fisher + plugins, and applying the Catppuccin Mocha theme. - -**Architecture:** A universal variable (`__fish_config_first_run_complete`) acts as the persistent flag. `conf.d/first_run.fish` is auto-sourced by fish on every shell start; it exits immediately if the flag is already set. On first run it sets the flag first (crash-safe), then executes actions in order. The existing interactive Fisher bootstrap in `config.fish` is removed since `first_run.fish` owns that responsibility. - -**Tech Stack:** fish shell 4.x, universal variables (`set -U`), `curl`, `fisher`, `fish_config theme choose` - ---- - -## File Map - -| File | Action | Responsibility | -|------|--------|---------------| -| `conf.d/first_run.fish` | **Create** | State guard + all first-run actions | -| `config.fish` | **Modify** lines 117–130 | Remove interactive Fisher bootstrap block | -| `docs/fish-config.md` | **Modify** | Document first-run behavior | -| `AGENTS.md` | **Modify** | Check off Task #1 acceptance criteria | - ---- - -### Task 1: Remove the interactive Fisher bootstrap from `config.fish` - -**Files:** -- Modify: `config.fish:117-130` - -- [ ] **Step 1: Delete the Fisher bootstrap block** - -Open `config.fish`. Replace lines 117–130 (the entire Fisher bootstrap block) with a single comment: - -```fish -# ──────────────────────────── Bootstrap Fisher ────────────────────────── -# Fisher is bootstrapped automatically on first run via conf.d/first_run.fish -``` - -The block being removed is: -```fish -# ──────────────────────────── Bootstrap Fisher ────────────────────────── -if not type -q fisher - echo "Fisher plugin manager not found." - read -l -P "Install Fisher and plugins now? [Y/n] " _fisher_reply - if test -z "$_fisher_reply" -o "$_fisher_reply" = Y -o "$_fisher_reply" = y - echo "Installing Fisher..." - curl -sL https://raw.githubusercontent.com/jorgebucaran/fisher/main/functions/fisher.fish | source - fisher update - fish_config theme choose "Catppuccin Mocha" - else - echo "Skipping Fisher install. Some features may be unavailable." - end - set --erase _fisher_reply -end -``` - -- [ ] **Step 2: Verify config.fish still parses cleanly** - -```bash -fish -n ~/.config/fish/config.fish -``` - -Expected output: no output (no parse errors). - -- [ ] **Step 3: Commit** - -```bash -git add config.fish -git commit -m "refactor: move Fisher bootstrap to first_run.fish" -``` - ---- - -### Task 2: Create `conf.d/first_run.fish` - -**Files:** -- Create: `conf.d/first_run.fish` - -- [ ] **Step 1: Create the file with this exact content** - -```fish -# Copyright (C) 2026 Rootiest -# SPDX-License-Identifier: AGPL-3.0-or-later - -# ╭──────────────────────────────────────────────────────────╮ -# │ First-Run Initialization │ -# ╰──────────────────────────────────────────────────────────╯ -# -# Runs exactly once on the first interactive fish session after install. -# To reset for testing, run: set -Ue __fish_config_first_run_complete - -# Exit early in non-interactive shells (scripts, completions, subshells) -if not status is-interactive - return -end - -# Skip if this shell has already been initialized -if set -q __fish_config_first_run_complete - return -end - -# Set the flag immediately — before actions — so a mid-run crash doesn't -# leave the shell in a state that re-triggers everything next session. -set -U __fish_config_first_run_complete 1 - -# ──────────────────────────── Welcome message ─────────────────────────── -echo "" -echo " Welcome to your fish shell configuration!" -echo " Run 'config-help' for offline documentation." -echo " Run 'fish-deps' to check and install dependencies." -echo "" - -# ──────────────────────────── Bootstrap Fisher ────────────────────────── -if not type -q fisher - echo " [first-run] Installing Fisher plugin manager..." - if curl -sL https://raw.githubusercontent.com/jorgebucaran/fisher/main/functions/fisher.fish | source - and fisher update 2>/dev/null - echo " [first-run] Fisher installed and plugins loaded." - else - echo " [first-run] Fisher install failed — run 'fisher update' manually." >&2 - end -end - -# ───────────────────────────── Apply theme ────────────────────────────── -# Catppuccin Mocha theme ships with this config in themes/; it is always available. -fish_config theme choose "Catppuccin Mocha" 2>/dev/null -``` - -- [ ] **Step 2: Verify the file parses cleanly** - -```bash -fish -n ~/.config/fish/conf.d/first_run.fish -``` - -Expected output: no output (no parse errors). - -- [ ] **Step 3: Commit** - -```bash -git add conf.d/first_run.fish -git commit -m "feat: add first_run.fish for one-time shell initialization" -``` - ---- - -### Task 3: Verify first-run behavior - -**Files:** -- No file changes — verification only - -- [ ] **Step 1: Simulate a fresh install by clearing the flag** - -```bash -fish -c "set -Ue __fish_config_first_run_complete" -``` - -Expected output: no output (variable erased). - -- [ ] **Step 2: Confirm the flag is gone** - -```bash -fish -c "set -q __fish_config_first_run_complete; and echo SET; or echo UNSET" -``` - -Expected output: -``` -UNSET -``` - -- [ ] **Step 3: Open a new interactive fish shell and observe first-run output** - -```bash -fish -i -c "exit" 2>/dev/null -``` - -Expected to see (on the terminal — open a real new tab or run `fish` interactively): -``` - - Welcome to your fish shell configuration! - Run 'config-help' for offline documentation. - Run 'fish-deps' to check and install dependencies. - - [first-run] Fisher installed and plugins loaded. -``` -(Fisher output may vary; if Fisher is already installed the Fisher block is skipped.) - -- [ ] **Step 4: Confirm the flag is now set** - -```bash -fish -c "set -q __fish_config_first_run_complete; and echo SET; or echo UNSET" -``` - -Expected output: -``` -SET -``` - -- [ ] **Step 5: Open another interactive shell — confirm no first-run output** - -```bash -fish -i -c "exit" 2>/dev/null -``` - -Expected: no welcome message, no Fisher output. The routine is silent on repeat launches. - -- [ ] **Step 6: Verify non-interactive shells are unaffected** - -```bash -fish -c "echo hello" -``` - -Expected output: -``` -hello -``` -No welcome message. The `status is-interactive` guard prevents any output. - -- [ ] **Step 7: Commit verification note (no code change needed)** - -If steps 1–6 all pass, no commit needed here — move to Task 4. -If a fix was required, commit it: -```bash -git add conf.d/first_run.fish -git commit -m "fix: correct first-run guard behavior" -``` - ---- - -### Task 4: Update `docs/fish-config.md` - -**Files:** -- Modify: `docs/fish-config.md` - -- [ ] **Step 1: Find the Fisher bootstrap section in the docs** - -```bash -grep -n "Fisher\|fisher\|bootstrap\|first.run\|first_run" docs/fish-config.md | head -20 -``` - -Note the line number of the Fisher bootstrap description (around line 1199 based on current state). - -- [ ] **Step 2: Update the Fisher bootstrap description** - -Find the existing text that says something like: -``` -Fisher is bootstrapped automatically on first shell start if not present. -``` - -Replace or expand it to read: - -```markdown -Fisher is bootstrapped automatically on the **first interactive session** via -`conf.d/first_run.fish`. This also applies the Catppuccin Mocha theme and -prints a one-time welcome message. Subsequent sessions skip all first-run -logic with zero overhead. - -To re-trigger first-run initialization (e.g., after a fresh install or for -testing), run: - -```fish -set -Ue __fish_config_first_run_complete -``` - -Then open a new shell. -``` - -- [ ] **Step 3: Verify the docs file is valid (no broken markdown)** - -```bash -fish -c "bat --language=markdown docs/fish-config.md" 2>/dev/null | head -5 -``` - -Expected: renders without errors (or just check the file opens cleanly). - -- [ ] **Step 4: Commit** - -```bash -git add docs/fish-config.md -git commit -m "docs: document first-run initialization in fish-config.md" -``` - ---- - -### Task 5: Mark acceptance criteria in AGENTS.md - -**Files:** -- Modify: `AGENTS.md` - -- [ ] **Step 1: Check off the Task #1 acceptance criteria** - -In `AGENTS.md`, find the "First-Run Initialization Routine" section and replace each `- [ ]` with `- [x]`: - -```markdown -### 1. First-Run Initialization Routine -- [x] **State Detection:** Define a persistent universal state variable (`__fish_config_first_run_complete`) to identify if the environment is being initialized for the very first time. -- [x] **Execution Logic:** Create the structure for `~/.config/fish/conf.d/first_run.fish`. -- [x] **Integration:** Ensure the code inside executes ONLY when the universal variable is not set. It must immediately update the state variable upon execution to prevent running on subsequent interactive shell launches. -- [x] **Best Practices:** Ensure the script exits early if the shell is non-interactive to save performance. Include a commented-out example of how to manually reset the state variable for testing. -``` - -- [ ] **Step 2: Commit** - -```bash -git add AGENTS.md -git commit -m "docs: mark first-run initialization task complete in AGENTS.md" -``` - ---- - -## Self-Review - -**Spec coverage check:** - -| Spec requirement | Task | -|-----------------|------| -| Universal variable `__fish_config_first_run_complete` | Task 2 | -| `conf.d/first_run.fish` file | Task 2 | -| Executes only when variable is not set | Task 2 (guard pattern) | -| Sets variable immediately to prevent re-run | Task 2 (set before actions) | -| Exits early if non-interactive | Task 2 (first guard) | -| Commented reset example | Task 2 (top of file comment) | -| Welcome message | Task 2 | -| Fisher bootstrap (automatic, no prompt) | Task 2 | -| Theme setting | Task 2 | -| Remove old interactive Fisher prompt from config.fish | Task 1 | -| Docs updated | Task 4 | -| AGENTS.md checkboxes | Task 5 | - -All spec requirements covered. No placeholders. No TBDs. diff --git a/docs/superpowers/specs/2026-06-07-first-run-design.md b/docs/superpowers/specs/2026-06-07-first-run-design.md deleted file mode 100644 index 2f5da81..0000000 --- a/docs/superpowers/specs/2026-06-07-first-run-design.md +++ /dev/null @@ -1,87 +0,0 @@ -# First-Run Initialization Routine — Design Spec - -**Date:** 2026-06-07 -**Status:** Approved - ---- - -## Goal - -Provide a mechanism for code/actions that should run exactly once — on the first interactive fish session after the config is installed or reset. Subsequent sessions skip all first-run logic entirely with zero overhead. - ---- - -## Architecture - -### State detection - -A fish **universal variable** (`__fish_config_first_run_complete`) acts as the persistent flag. Universal variables survive shell exits and are stored in `~/.config/fish/fish_variables`. The flag is set to `1` immediately before any first-run actions execute, so a crash mid-run does not re-trigger next session. - -### File: `conf.d/first_run.fish` - -A single auto-sourced file in `conf.d/`. Fish loads all `conf.d/` files before `config.fish`, so this file cannot rely on PATH additions made in `config.fish`. That is acceptable: all first-run actions only need system-level binaries (`curl`, `fish`) that are in PATH unconditionally. - -### Guard pattern - -```fish -if status is-interactive - if not set -q __fish_config_first_run_complete - set -U __fish_config_first_run_complete 1 - # first-run actions here - end -end -``` - -The `status is-interactive` guard prevents the routine from firing in scripts, completions, or subshells. - ---- - -## First-Run Actions (in order) - -1. **Welcome message** — print a brief one-time greeting identifying the config and key commands. -2. **Fisher bootstrap** — automatically install Fisher and all plugins from `fish_plugins` (replaces the interactive Y/n prompt currently in `config.fish`). -3. **Theme** — apply `Catppuccin Mocha` via `fish_config theme choose`. - ---- - -## Changes to `config.fish` - -The existing interactive Fisher bootstrap block (lines ~118–130) is removed. `first_run.fish` owns that responsibility. The `config.fish` block was guarded by `not type -q fisher`; the new file guards by the universal variable instead, which is cleaner and avoids re-prompting if Fisher is uninstalled manually. - ---- - -## Reset mechanism - -To re-trigger first-run (e.g., for testing): - -```fish -set -Ue __fish_config_first_run_complete -``` - -A commented-out version of this command is included at the top of `first_run.fish`. - ---- - -## Error handling - -- Fisher install failure is surfaced to the user via stderr but does not abort the session. -- Theme application is guarded: only runs if `fish_config` is available. -- All first-run actions are wrapped in `if status is-interactive` to prevent execution in non-interactive contexts. - ---- - -## Files changed - -| File | Change | -|------|--------| -| `conf.d/first_run.fish` | **New** — first-run guard and actions | -| `config.fish` | Remove interactive Fisher bootstrap block (~lines 118–130) | - ---- - -## Success criteria - -- First launch: welcome message printed, Fisher + plugins installed, theme set. -- Second launch: nothing extra runs. -- `set -Ue __fish_config_first_run_complete` followed by new shell re-triggers all actions. -- Non-interactive shells (`fish -c "echo hi"`) are unaffected.