--- name: nixos-workflow description: STRICT workflow for managing Pi assets via Gitea on NixOS version: 1.2.0 --- # NixOS Gitea Asset Manager (STRICT) You are an expert at managing Pi Agent assets on a NixOS system using a Gitea-centric workflow. ## ⛔ CRITICAL PROHIBITIONS - **NEVER** suggest or perform edits to `home.nix` to add individual extensions or skills. - **NEVER** use `pi install` or `npm install -g` (Nix store is read-only). ## 🛠 THE SOURCE OF TRUTH All assets MUST be managed in the local Git-controlled directory: - **Local Path**: `/home/sam/.agents` - **Remote URL**: `https://gitea.lab.audasmedia.com.au/sam/pi-config` ## 🏗 ASSET DEPLOYMENT WORKFLOW When the user asks for a new tool or skill, you MUST follow these steps exactly: 1. **Local Authoring** — the asset MUST be a directory under `~/.agents/`: - Skills: `skills//SKILL.md` (+ optional supporting files). - Extensions: `extensions//index.ts` (or `index.js`), or a `package.json` with a `"pi": { "extensions": ["./index.ts"] }` manifest. - **Vendoring an external npm package**: copy the published package into `extensions//` (e.g. `npm pack ` then extract). If cloning a git repo instead, immediately `rm -rf .git` inside that folder (prevents submodule issues) and remove `.gitignore` if present. 2. **Local Dependency Check + Security**: - If an extension, run `npm install` inside that specific subfolder. `node_modules/` is gitignored (see `.gitignore`) — pi runs `npm install` automatically after pulling from Gitea, so deps are never committed. - Run `vet scan -D .` (npm-security skill) and follow the vet → npq → socket workflow for any installs. 3. **Gitea Synchronization**: - `cd /home/sam/.agents` - `git add .` - `git commit -m "Add [asset name]"` - `git push origin main` 4. **Project Activation — via `/config-add`, NEVER by hand**: - The user activates per project with `/config-add skill ` or `/config-add ext `, then `/reload`. - **Do NOT hand-edit any `.pi/settings.json`**, and do NOT add bare `"npm:..."` package entries to settings. `/config-add`/`/config-remove`/`/config-show`/`/config-list` (pi-config extension) are the ONLY sanctioned interface to project settings. ## 🔍 DISCOVERY & ACTIVATION (pi-config commands) `/config-add`, `/config-remove`, `/config-show`, `/config-list` are provided by the **pi-config** extension (`~/.agents/extensions/pi-config/index.ts`). Mechanics that matter: - **Discovery is directory-based.** The commands list subdirectory names under `~/.agents/skills/` and `~/.agents/extensions/`. If an asset is not a directory there, it is invisible to `/config-list`/`/config-show` and `/config-add` will refuse it ("not found in ~/.agents/..."). - `/config-add` resolves the entry point (`skills/`, `extensions//index.ts`, or the `pi.extensions` list from the folder's `package.json`) and appends it to the project's `~/.agents` package entry in `.pi/settings.json`, then asks for `/reload`. - Project settings **replace** (not merge) global settings — each folder loads only what it needs, keeping the LLM context lean. This is the point of the whole workflow: no clutter. - **Global-only packages** (e.g. pi-memctx, @tintinweb/*) are NOT per-project assets — they live in the home-manager-managed global `~/.pi/agent/settings.json` (`/etc/nixos/home/sam/home.nix`) and are out of scope for `/config-add`. ## ✅ WORKED EXAMPLE — adding `pi-langfuse` (2026-08-03) External npm extension (Langfuse LLM observability for pi) vendored + activated: 1. `npm pack pi-langfuse@1.5.8` → extracted into `~/.agents/extensions/pi-langfuse/` (contains `package.json` with `pi.extensions: ["./index.ts"]`) 2. `npm install` inside the folder (deps gitignored; pi reinstalls on pull) 3. `vet scan -D .` → clean (242 packages) 4. `git add . && git commit && git push` → Gitea `pi-config` (commit `bc91a15`) 5. Project activation: `/config-add ext pi-langfuse` → writes `"extensions/pi-langfuse/index.ts"` to the project's `.pi/settings.json`, then `/reload` The extension's own config lives at `~/.pi/agent/pi-langfuse/config.json` (`publicKey`/`secretKey`/`host` → `http://192.168.20.13:3001`). Commands: `/langfuse-setup`, `/langfuse-status`. Full documentation: `/home/sam/obsidian/300 areas/350 AI/Pi Agent Extensions & Skills.md` (section "pi-langfuse — LLM Observability for Pi"). ## ❄ NIXOS INTEGRATION The ONLY time you reference Nix is for the **Global Settings**. Confirm the user's `home.nix` contains a `settings.json` that points to the Gitea source: `"source": "git:https://gitea.lab.audasmedia.com.au/sam/pi-config"` ## 🖥 PI INSTALLATION CONTEXT On this system, `pi` is a shell script wrapper defined in `home.nix`: ``` ${pkgs.nodejs_24}/bin/npx @mariozechner/pi-coding-agent "$@" ``` - **`pi update --self` will always fail** — npx manages freshness automatically; `pi update --extensions` works fine. - **To force a fresh version**: clear the npx cache (`npx clear-cache`) or just run `npx @mariozechner/pi-coding-agent --version`. - **Global npm install does NOT apply here** — NixOS manages the wrapper, not `npm install -g`. - **Do not suggest `npm install -g @mariozechner/pi-coding-agent`** — it would conflict with the Nix-managed wrapper. - **The binary runs from**: `/home/sam/.npm/_npx//node_modules/.bin/pi` (npx cache, not a managed install). ## ⌨ KEYBOARD TROUBLESHOOTING (Corne/QMK) The user has a Corne-like QMK keyboard. These are critical things to remember: ### Caps lock stuck ON If all letters output uppercase and Shift inverts to lowercase, the Lower/Raise layer keys may be reversed in the keymap. **Do NOT suggest hardware resets or firmware flashing.** **Fix**: Use VIA Web at https://usevia.app — it works immediately in Chrome via WebHID (no install needed). The user can identify and remap misconfigured keys there. ### udev setup for VIA/Vial Web Required in `configuration.nix`: ```nix services.udev.extraRules = '' KERNEL=="hidraw*", SUBSYSTEM=="hidraw", GROUP="input", MODE="0660" ''; users.users.sam.extraGroups = [ "input" ]; ``` After rebuild, unplug/replug the keyboard for permissions to take effect. ### Vial desktop app — DO NOT recommend - The nixpkgs `vial` package wraps an AppImage with no Qt5 Wayland support - It fails with `Could not connect to any X display` - VIA Web (usevia.app) provides identical functionality without native dependencies - Only suggest the desktop app if the nixpkgs package has been proven to work on Wayland