Files
pi-config/skills/nixos-workflow/SKILL.md

8.2 KiB

name, description, version
name description version
nixos-workflow STRICT workflow for managing Pi assets via Gitea on NixOS 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).

🗄 PER-MACHINE REPOS

Each machine has its OWN ~/.agents git repo — its own clone of the shared Gitea pi-config repo (Gitea itself runs as Docker on .35, web .35:3001, SSH .35:2222). A push from .27 does NOT auto-update .13/.51 — update each machine's clone individually (git -C ~/.agents pull). /config-add discovery reads the local ~/.agents/extensions|skills dirs, so a machine must pull before a new asset can be activated there. (.51 had no repo until 2026-08-05 — cloned then.)

🛠 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/<name>/SKILL.md (+ optional supporting files).
    • Extensions: extensions/<name>/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/<name>/ (e.g. npm pack <pkg> 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 <name> or /config-add ext <name>, 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/<name>, extensions/<name>/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/hosthttp://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").

⚠️ VENDORING PITFALL — vscode-languageserver-protocol subpath

pi-lsp-extension (and possibly other extensions) imports vscode-languageserver-protocol/node.js. npm resolves ^3.17.5 to 3.18.x whose exports map exposes ./node but not ./node.js — the import throws at load and the ENTIRE extension silently fails (no /lsp commands appear, while other extensions still load — confusing). Fix: change the import to vscode-languageserver-protocol/node (no .js); re-apply whenever re-vendoring from npm (our fix = commit 57c5cd2).

Load-verify any vendored extension by bundling it the way pi's loader does:

npx esbuild src/index.ts --bundle --platform=node --format=esm \
  --external:@earendil-works/* --external:vscode-languageserver-protocol \
  --external:web-tree-sitter --external:tree-sitter-wasms --outfile=/tmp/x.mjs
# then import /tmp/x.mjs with a stub ExtensionAPI (registerTool/registerCommand/on/events)

❄ 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 all three machines (.27/.13/.51) pi is Nix-managed — the nixpkgs package pi-coding-agent (v0.82.1) in home.packages. There is NO npx wrapper and NO npm-global install anymore (both removed 2026-08-05).

  • pi update --self / pi update --extensions: not applicable — the binary is Nix. Updating pi = bump the nixpkgs flake input (nix flake update nixpkgs) + sudo nixos-rebuild switch --flake .#<host>.
  • Never npm install -g @earendil-works/pi-coding-agent — npm-global/bin precedes /etc/profiles/per-user/sam/bin in PATH, so it shadows the Nix pi (caused a real bug once).
  • After a Nix pi switch: fully CLOSE running pi sessions. A /reload in a session started from the old binary fails — the loader re-resolves every extension import against the old runtime dir, which no longer exists. Fresh sessions only.
  • Vendored extensions (pi-tool-display global, pi-lsp-extension per-project) live in ~/.agents; see the Obsidian doc 350 AI → Pi Agent Extensions & Skills.md.

⌨ 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:

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