927 lines
50 KiB
Markdown
927 lines
50 KiB
Markdown
---
|
||
created: 2026-05-16
|
||
modified: 2026-09-06
|
||
type: subject
|
||
status: active
|
||
tags:
|
||
- ai
|
||
- dev-ops
|
||
aliases: []
|
||
---
|
||
|
||
# Pi Agent Extensions & Skills
|
||
|
||
## Source Repositories
|
||
|
||
| Source | Location |
|
||
|---|---|
|
||
| Gitea (package) | `git:https://gitea.lab.audasmedia.com.au/sam/pi-config` |
|
||
| Local filesystem | `~/.agents/` |
|
||
| Project settings | `sys_config/.pi/settings.json`, `ai_setup/.pi/settings.json` |
|
||
|
||
---
|
||
|
||
## OmniRoute — LLM Provider Router
|
||
|
||
OmniRoute is the central LLM routing proxy running on .13 (port 20128/20129). All three machines route pi's LLM requests through it.
|
||
|
||
| Aspect | Detail |
|
||
|--------|--------|
|
||
| **What it is** | Docker-based LLM proxy with **combo routing** — you define a prioritized list of providers and it tries them in order until one succeeds |
|
||
| **Where** | `.13:20129` via Docker, exposed through Caddy on .35 for remote access |
|
||
| **Provider registered in pi as** | `omni` (not `omniroute`) — the `omniroute-pi-ext-integration` npm package registers the `omni` provider |
|
||
| **Pi default model** | `default-opencode-go-ds-flash` — a combo on OmniRoute that prioritises OpenCode-Go's DeepSeek V4 Flash ($5/month sub) before falling back to other providers |
|
||
| **Combo chain** | User-created combo `default-opencode-go-ds-flash` tries providers in order: OpenCode-Go → OpenRouter → DeepSeek direct → Google Gemini |
|
||
| **Sub-agent routing** | Sub-agents route through the same combo — individual model IDs like `opencode-go/deepseek-v4-flash` match the combo and fall through the same priority chain |
|
||
| **Models** | 484 models available via OmniRoute (synced with `/omni sync`), available in pi's Ctrl+P model picker |
|
||
| **How pi connects** | The `omniroute-pi-ext-integration` extension registers all models + the `omni` provider. URL + API key set once via `/omni setup`. Re-sync via `/omni sync`. |
|
||
|
||
### Files & Commands
|
||
|
||
| Item | Location / Command |
|
||
|------|-------------------|
|
||
| Docker compose | `/home/sam/Docker/Containers/omniroute/docker-compose.yml` on .13 |
|
||
| pi extension | `omniroute-pi-ext-integration` (npm package, installed via `pi install npm:omniroute-pi-ext-integration`) |
|
||
| Extension config | `~/.pi/agent/models.json` — stores URL + API key for `omni` provider, plus model list |
|
||
| Setup | `/omni setup` (one-time: URL + API key) |
|
||
| Sync | `/omni sync` (re-fetch model list) |
|
||
| Access (local) | `http://192.168.20.13:20129/v1` |
|
||
| Access (via Caddy) | `https://omniroute.lab.audasmedia.com.au/v1` |
|
||
| API key | `sk-fff5c0d55c0bc0bf-b58ed0-76da5716` (stored in `~/.config/environment.d/10-secrets.conf` on .27/.51; on .13 in `~/.pi/agent/settings.json` — `chmod 600`, outside any git repo). ⚠️ This key is also written in this doc — rotate/move to a vault secret if this file ever syncs outside the vault |
|
||
|
||
---
|
||
|
||
## Open WebUI — Chat Frontend
|
||
|
||
Open WebUI v0.11.0 runs on .13 as a native NixOS process (not Docker), managed via Home Manager. Provides a chat UI that can connect to any OpenAI-compatible API — including OmniRoute.
|
||
|
||
| Aspect | Detail |
|
||
|--------|--------|
|
||
| **URL** | `http://192.168.20.13:3000` |
|
||
| **Package** | `open-webui-0.11.0` (NixOS nixpkgs) |
|
||
| **How to connect OmniRoute** | Admin Panel ⚙️ → Settings → Connections → OpenAI API → URL: `http://192.168.20.13:20129/v1` (include `/v1`), Key: OmniRoute API key |
|
||
| **Also works with** | Any OpenAI-compatible API (TokenRouter, OpenRouter, DeepSeek) — add each as a separate connection |
|
||
| **Port note** | :3000 is Open WebUI's port. |
|
||
|
||
---
|
||
|
||
## Ollama — Local LLM Inference (REMOVED)
|
||
|
||
~~Runs on .13 with `qwen2.5-coder:7b` (Q4_K_M, 7.6B params).~~ **Removed August 2026.** Redundant — OmniRoute provides 485 models including superior `qwen/qwen3.5-9b`. The 4.7GB disk + RAM cost on a 15.5GB server wasn't justified.
|
||
|
||
### Pi default model selection model
|
||
|
||
Machines route through `omni` provider with `defaultModel: "default-opencode-go-ds-flash"`:
|
||
|
||
```
|
||
pi → omni provider → POST /v1/chat/completions { model: "default-opencode-go-ds-flash" }
|
||
→ OmniRoute matches combo "default-opencode-go-ds-flash"
|
||
→ Tries: OpenCode-Go → OpenRouter → DeepSeek direct → Google Gemini
|
||
→ Returns first successful response
|
||
```
|
||
|
||
### Per-machine setup state
|
||
|
||
pi is **Nix-managed on all three** — the nixpkgs **`pi-coding-agent`** package (v0.82.1) in `home.packages` (npx wrapper removed 2026-08-05). Version uniform on all machines (matches all three flake locks). Updates = nixpkgs flake bump + rebuild. Global settings also include **pi-tool-display** (see below).
|
||
|
||
| Machine | pi package | pi version | Provider config | `/omni setup` done | Models synced |
|
||
|---------|-----------|-----------|-----------------|-------------------|--------------|
|
||
| .27 | `pi-coding-agent` (home.nix) | 0.82.1 | ✅ `omni` | ✅ | ✅ |
|
||
| .13 | `pi-coding-agent` (home.nix) | 0.82.1 | ✅ `omni` | ✅ | ✅ |
|
||
| .51 | `pi-coding-agent` (home.nix) | 0.82.1 | ✅ `omni` | ✅ | ✅ |
|
||
|
||
---
|
||
|
||
## Extensions
|
||
|
||
| Extension | Source | Purpose |
|
||
|---|---|---|
|
||
| **pi-config** | `~/.agents` | `/config-add`, `/config-remove`, `/config-show`, `/config-setup` — manage which extensions/skills are active in a project |
|
||
| **tavily-search** | Gitea | `tavily_search` — web search via Tavily API (AI-optimized) |
|
||
| **web-fetch** | `~/.agents` | `web_fetch` — fetch any URL and return clean markdown (HTML, PDF, JS-rendered with Jina fallback) |
|
||
| **ask-user-question** | `~/.agents` | `ask_user_question` — LLM presents structured multiple-choice / text questions with keyboard UI |
|
||
| **video-extract** | `~/.agents` | `video_extract` — extract frames from YouTube/local video + full Gemini analysis (requires ffmpeg + yt-dlp + GEMINI_API_KEY) |
|
||
| **filechanges** | `~/.agents` | `/filechanges`, `/filechanges-accept`, `/filechanges-decline` — tracks every file LLM edits/writes, diff review, revert |
|
||
| **pi-prompt-template-model** | npm (global) | Model-switching prompt templates with frontmatter. See [[#Prompt Templates]] section below |
|
||
| **pi-mcp-adapter** | npm (global) | Single proxy tool (~200 tokens) replaces hundreds of MCP tool definitions. `/mcp` command for management. Lazy server connections |
|
||
| **pi-graphify** | `~/.agents` | Knowledge graph tools: build, query, path tracing, explain, watch, add, update |
|
||
| **plannotator** | `~/.agents` | Interactive plan review with browser UI, annotations, code review |
|
||
| **caveman** | `~/.agents` | Ultra-compressed communication mode |
|
||
| **markitdown** | `~/.agents` | Convert files (PDF, Word, Excel, PPTX, images, HTML, etc.) to Markdown. Image analysis via Qwen 2.5 VL 72B on OpenRouter. |
|
||
| **@tintinweb/pi-subagents** | npm (global) | 18 custom agent types, background agents, mid-run steering, session resume, worktree isolation, scheduling, cross-extension RPC. See [[Pi Subagent]] for full documentation |
|
||
| **@tintinweb/pi-tasks** | npm (global) | Task management with dependency tracking, auto-cascade, background process tracking, TaskExecute spawns subagents via RPC |
|
||
| **gentle-engram** | `~/.agents` | Memory service connecting to engram via ENGRAM_URL. Replaces memory-vault. Session capture, compaction recovery |
|
||
| **headroom-bridge** | `~/.agents` | `compress_for_agent` tool — compresses >20K chars via Headroom Docker on .13:8787. 60-95% token reduction |
|
||
| **pi-mermaid** | `~/.agents` (vendored from npm 0.3.0, commit `8e68df0`) | Renders ` ```mermaid ` blocks as ASCII in the TUI (beautiful-mermaid) + Mermaid parser syntax warnings/errors. `/pi-mermaid` re-renders last assistant message. Per project: `/config-add ext pi-mermaid` |
|
||
| **pi-tool-display** | `~/.agents` (vendored npm 0.5.0, commit `41cc33d`) | OpenCode-style compact tool rendering, adaptive edit/write diffs, pending-edit previews, thinking labels. **Global** — 0 tools / 0 token cost (added via home.nix settings). `/tool-display` presets: opencode / balanced / verbose |
|
||
| **pi-lsp-extension** | `~/.agents` (vendored npm 1.3.0, commit `41cc33d`) | LSP diagnostics, hover, definition, references, symbols, rename, completions, code_actions + tree-sitter `code_overview`/`ast_search`/`code_rewrite`. **Per-project** via `/config-add ext pi-lsp-extension` (10 tools — token-lean). Commands: `/lsp`, `/lsp-config`, `/lsp-restart`, `/lsp-lombok` |
|
||
| **pi-browser-harness** | `~/.agents` (vendored npm 0.11.0, commit `a34b41e`) | Direct browser control of the user's **real running Chrome** via CDP — 40+ `browser_*` tools (snapshot/AX-tree, click, fill, execute_js, screenshot, console, network, web_search, read_page). **Per-project** via `/config-add ext pi-browser-harness`. Commands: `/browser-setup`, `/browser-profile`. See [[#pi-browser-harness]] below for full docs + other-machine rollout |
|
||
|
||
|
||
### pi-tool-display
|
||
|
||
OpenCode-style tool rendering for pi (vendored from npm `pi-tool-display@0.5.0`, by MasuRii, commit `41cc33d`).
|
||
|
||
| Aspect | Detail |
|
||
|---|---|
|
||
| **What it does** | Compact built-in tool rendering (read/grep/find/ls/bash/edit/write), adaptive split/unified edit diffs, workspace-scoped pending edit/write previews while streaming, thinking labels, optional native user message box |
|
||
| **Placement** | **Global** — registers 0 tools (pure TUI renderer), so no token cost. Added to the Gitea package `extensions` list in home.nix global settings (`extensions/pi-tool-display/index.ts`) on all three machines |
|
||
| **Presets** | `/tool-display` → opencode / balanced / verbose |
|
||
| **Token note** | Compacts/truncates tool output = saves context. Does NOT remove blocks from the transcript (that's `pi-foldable-tools`, deliberately skipped — overlapping renderer, no persistent token gain) |
|
||
| **Compat** | peer range `^0.74–0.80` — verified working on pi 0.82.1 |
|
||
|
||
### pi-lsp-extension
|
||
|
||
LSP integration for pi (vendored from npm `pi-lsp-extension@1.3.0`, by samfoy, commit `41cc33d`).
|
||
|
||
| Aspect | Detail |
|
||
|---|---|
|
||
| **Tools (11)** | `lsp_diagnostics`, `lsp_hover`, `lsp_definition`, `lsp_references`, `lsp_symbols`, `lsp_rename`, `lsp_completions`, `lsp_code_actions`, `code_overview`, `ast_search`, `code_rewrite` |
|
||
| **Commands** | `/lsp` (server status), `/lsp-config <lang> <cmd> [args]`, `/lsp-restart <lang>`, `/lsp-lombok` |
|
||
| **Placement** | **Per-project** via `/config-add ext pi-lsp-extension` (10+ tool defs — token-lean). Same on all machines |
|
||
| **Language servers** | Installed via home.nix: `vtsls` (TS/JS/React — use `/lsp-config typescript vtsls stdio`), `pyright` (Python), `gopls` (Go), `clang-tools` (C/C++/Arduino), `yaml-language-server`, `bash-language-server`, `vscode-langservers-extracted` (JSON/HTML/CSS), `lua-language-server`, `emmet-ls`, `intelephense` (PHP — paid; free alt `phpactor`), `nixd` (Nix), `marksman` (Markdown), `lemminx` (XML). Rust later → `rust-analyzer` |
|
||
| **Auto-diagnostics** | After `edit`/`write`, appends compile errors for the changed file when a server is running (configurable via `.pi-lsp.json` in workspace root) |
|
||
| **⚠️ Vendoring pitfall** | The published package imports `vscode-languageserver-protocol/node.js` — the `.js` subpath was dropped from v3.18's `exports` map, which crashes the whole extension at load (no commands appear). Fixed in our vendor (commit `57c5cd2`): import `/node` instead. **Re-apply if re-vendoring from npm** |
|
||
|
||
### pi-browser-harness
|
||
|
||
Direct browser control of your real Chrome via CDP (vendored from npm `pi-browser-harness@0.11.0`, commit `a34b41e`, 2026-09-10). Drives the Chrome **you're already using** — profile, logins, cookies — no second browser, no MCP hop, no extra API keys.
|
||
|
||
| Aspect | Detail |
|
||
|---|---|
|
||
| **What it does** | 40+ `browser_*` tools over a single CDP connection: `browser_snapshot` (AX-tree, default), `browser_execute_js` (surgical reads), `browser_click`/`browser_fill`/`browser_type`/`browser_press_key` (interaction), `browser_screenshot` (visual only), `browser_console`/`browser_network_requests` (diagnostics), `browser_web_search`/`browser_read_page` (research, isolated tabs). Element handles are stable refs (`@(x,y)`) that re-resolve at action time |
|
||
| **Commands** | `/browser-setup` (start daemon + connect to Chrome), `/browser-profile` (choose which Chrome profile the harness uses; persists in `~/.pi/agent/`) |
|
||
| **Placement** | **Per-project** via `/config-add ext pi-browser-harness` (active in `pi-browser_testing`) |
|
||
| **Runtime deps** | `ws` only — **sharp dropped from optionalDeps** (libvips/libheif CVEs; screenshots work without auto-resize). `@mariozechner/pi-coding-agent` is dev-only (loader aliases to bundled runtime). vet scan: 0 critical/0 high/0 other on production tree; npm audit clean |
|
||
| **Security model** | Agent gets access to your real Chrome session — the most powerful & least sandboxed option. Prefer a throwaway profile for untrusted pages. Chrome needs **remote debugging enabled**: `chrome://inspect/#remote-debugging` → tick Allow (per-session toggle) **or** relaunch once with `google-chrome --remote-debugging-port=9222` (persistent, and required to let the harness open its own window) |
|
||
| **Prereqs** | Chrome installed & running. Finder: daemon reads `DevToolsActivePort` in profile dirs → probes port 9222 → `BU_CDP_WS`/`BU_CDP_PORTS` env overrides. Daemon socket: `/tmp/pi-browser-daemon.sock` |
|
||
| **Machine status** | `.27` ✅ installed + active (windowed Chrome, `chrome://inspect` toggle). `.51` ✅ Chrome + deps + extension pulled — **required `npm install` in the extension dir** (node_modules is gitignored) then `/browser-setup`. `.13` ✅ Chrome installed (home.nix `google-chrome`), **headless server mode** — see below |
|
||
| **Headless Chrome on .13** (no GUI session needed) | `pkill -f "headless=new"` then `google-chrome --headless=new --remote-debugging-port=9222 --user-data-dir=$HOME/.chrome-pi &` — **Chrome 136+ REFUSES remote-debugging on the default data dir**, so `.chrome-pi` (or any custom dir) is required. One-off only: dies on ctrl-c/reboot (wrap in a systemd user service for persistence; paseo can also ensure it, but dies with paseo). Verify: `ss -tlnp \| grep 9222` → LISTEN. Confirmed working 2026-09-14 |
|
||
| **Known quirks** | With the `chrome://inspect` *toggle* (not the launch flag), the harness cannot open its own window for the pinned profile — fix by relaunching Chrome with `--remote-debugging-port=9222`, or clear the profile selection to use whichever window exists. The daemon discovers Chrome via `DevToolsActivePort` files / port 9222 / `BU_CDP_WS` |
|
||
| **Obsidian research** | Assessment of this + 4 other browser options (incl. camofox): [[AI Tools to try]] · Outline collection `Pi Browser Harness` · AGENT.md in `pi-browser_testing` |
|
||
|
||
### pi-subagents (@tintinweb)
|
||
|
||
v0.10.2, installed globally. 18 custom agent types in `~/.pi/agent/agents/` → `~/.agents/agents/`. Tools: `Agent()`, `get_subagent_result()`, `steer_subagent()`. `/agents` command for interactive management. Features: background agents with concurrency (4 default), mid-run steering, session resume, worktree isolation, scheduling, persistent widget showing live agent status. Cross-extension RPC event bus. Patched: 24h agent survival (was 10min), clearDisabled on session start. See [[Pi Subagent]] for full documentation.
|
||
|
||
### pi-tasks (@tintinweb)
|
||
|
||
v0.7.0, installed globally. 7 task tools: `TaskCreate`, `TaskList`, `TaskGet`, `TaskUpdate`, `TaskOutput`, `TaskStop`, `TaskExecute`. `/tasks` command. Features: dependency tracking (blocks/blockedBy), auto-cascade, background process tracking, persistent widget. `TaskExecute` spawns subagents via RPC.
|
||
|
||
---
|
||
|
||
## Skills
|
||
|
||
| Skill | Purpose |
|
||
|---|---|
|
||
| **nixos-workflow** | STRICT workflow for managing Pi assets via Gitea on NixOS |
|
||
| **system-architect** | Multi-machine NixOS infrastructure (Snapcast, MQTT, Docker, Nvim) |
|
||
| **obsidian-cli** | Interact with Obsidian vault (notes, search, plugin dev, theme dev) |
|
||
| **graphify** | Full-pipeline knowledge graph orchestration |
|
||
| **caveman** | Caveman communication mode |
|
||
| **openspec-propose** | Propose new changes with design docs, specs, tasks |
|
||
| **openspec-apply-change** | Implement tasks from an OpenSpec change |
|
||
| **openspec-archive-change** | Archive completed changes |
|
||
| **openspec-explore** | Explore ideas and clarify requirements |
|
||
| **npm-security** | Scan packages with SafeDep Vet, check typosquatting with npq, wrap installs with Socket Firewall |
|
||
| **ste-writing** | Rewrite prose (docs, READMEs, PRs, errors) into ASD-STE100 Simplified Technical English. Removes AI slop. Two modes: strict (procedures) and STE-flavored (general prose). Includes heuristic anti-slop linter (ste-lint.py). |
|
||
| **project-diagramming-mermaid** | Outline codebase/project as Mermaid → `<project>/docs/<topic>.mmd` + render to `<project>/docs/diagrams/` via mmdc (nixpkgs mermaid-cli) → prompt for Archify follow-up. Per project: `/config-add skill project-diagramming-mermaid`. See [[Dev-Ops Tooling — Mermaid, Archify, Vikunja & Outline]] |
|
||
| **project-diagramming-archify** | Mermaid or plain language → Archify JSON IR → validate (showcase) → deliver interactive HTML to `<project>/docs/<topic>-map.html`. Vendor renderer: `~/.agents/skills/archify` (v2.14). Per project: `/config-add skill project-diagramming-archify`. See [[Dev-Ops Tooling — Mermaid, Archify, Vikunja & Outline]] |
|
||
| **project-docs** | Meta-skill to initiate or update multi-platform project documentation across Gitea (tech README), Obsidian (human/portfolio showcase), Mermaid/Archify (diagrams & map links), Vikunja (human tasks), and Outline (AI context index using `ste-writing`). Per project: `/config-add skill project-docs` |
|
||
| **project-ops** | Task/stage/progress via **Vikunja** API + documentation via **Outline** API (bearer tokens in `10-secrets.conf`). Create/update tasks, move buckets, percent-done, read/write docs. Per project: `/config-add skill project-ops`. See [[Dev-Ops Tooling — Mermaid, Archify, Vikunja & Outline]] |
|
||
| **design-build** | Generate production-ready HTML/Tailwind code from design specifications and DESIGN.md design tokens. |
|
||
| **design-explore** | Generate UI design mockups as images for exploration and ideation. Supports DESIGN.md for design-token-accurate mockups. |
|
||
| **markitdown** | Convert files (PDF, Word, Excel, PowerPoint, images, HTML, CSV, JSON, XML, ZIP, EPubs, YouTube) to Markdown for LLM consumption. Image analysis via Qwen 2.5 VL 72B on OpenRouter. |
|
||
|
||
---
|
||
|
||
## markitdown
|
||
|
||
Convert various file formats to Markdown. Useful for feeding documents and images into LLMs.
|
||
|
||
### What it converts
|
||
|
||
| Format | Input | Notes |
|
||
|--------|-------|-------|
|
||
| PDF | `.pdf` | Preserves structure (headings, lists, tables) |
|
||
| Word | `.docx` | mammoth + lxml |
|
||
| PowerPoint | `.pptx` | python-pptx |
|
||
| Excel | `.xlsx`, `.xls` | openpyxl + pandas |
|
||
| Images | `.jpg`, `.png`, etc. | EXIF metadata (free) + LLM vision description (via OpenRouter) |
|
||
| HTML | `.html` | beautifulsoup4 |
|
||
| CSV / JSON / XML | `.csv`, `.json`, `.xml` | Structured data → Markdown tables |
|
||
| ZIP | `.zip` | Iterates contents, converts each file |
|
||
| EPubs | `.epub` | |
|
||
| YouTube | URLs | Transcript extraction |
|
||
|
||
### CLI usage
|
||
|
||
```bash
|
||
# Convert file to Markdown (stdout)
|
||
markitdown document.pdf
|
||
|
||
# Write to file
|
||
markitdown document.pdf -o document.md
|
||
|
||
# Image with LLM vision description
|
||
markitdown-vision photo.jpg
|
||
```
|
||
|
||
### Image analysis
|
||
|
||
Two levels:
|
||
|
||
1. **EXIF metadata only** (free, no API key): `markitdown photo.jpg`
|
||
2. **LLM vision description** (via OpenRouter, requires API key): `markitdown-vision photo.jpg`
|
||
|
||
The `markitdown-vision` wrapper auto-sources `OPENROUTER_API_KEY` from `~/.config/environment.d/10-secrets.conf` and uses `qwen/qwen2.5-vl-72b-instruct`.
|
||
|
||
### Missing / can be added
|
||
|
||
| Feature | What's needed |
|
||
|---------|--------------|
|
||
| Audio transcription | `pip install markitdown[audio-transcription]` (pydub + speechrecognition) |
|
||
| Azure AI Document Intelligence | `pip install markitdown[az-doc-intel]` + Azure credentials |
|
||
| Azure Content Understanding | `pip install markitdown[az-content-understanding]` + Azure credentials |
|
||
| markitdown-ocr plugin | Installed but needs OpenRouter key enabled to activate |
|
||
|
||
---
|
||
|
||
## project-docs
|
||
|
||
Meta-skill for initiating and updating multi-platform project documentation across human and AI systems. Orchestrates other skills (`nixos-workflow`, `project-diagramming-mermaid`, `project-diagramming-archify`, `obsidian-cli`, `ste-writing`).
|
||
|
||
### Multi-Platform Roles
|
||
|
||
| Platform | Target | Purpose & Tone | Key Output |
|
||
| :--- | :--- | :--- | :--- |
|
||
| **Gitea** | Developers / Resume | Technical repo README. Standard concise markdown. Highlights tech stack, usage, and portfolio skills. | `README.md` (embedded Mermaid diagram, Archify map links) |
|
||
| **Obsidian** | Humans / Hiring Managers | **Human understanding**. Simple, layperson-friendly language. Highlights skills, tools, and employment concepts. | Vault note (`<ProjectName>.md`) |
|
||
| **Mermaid + Archify** | Visualization | High-level system architecture and flow diagrams. | `docs/<topic>.mmd`, SVG/PNG renderings, hyperlinked nodes to `maps.lab.audasmedia.com.au` |
|
||
| **Vikunja** | Humans | High-level task tracking for human team members. | Vikunja Project & Task Board |
|
||
| **Outline** | AI Agents | **Deep AI context & document index**. Itemizes what is in each document in the collection so AI agents can inject specific files directly without searching. **Must use `ste-writing` skill** for terse, plain, slop-free text. | Outline Overview & Collection docs |
|
||
|
||
### Workflow & Usage
|
||
|
||
```bash
|
||
# Enable per-project
|
||
/config-add skill project-docs
|
||
/reload
|
||
|
||
# Invoke initiate mode
|
||
"Initiate project documentation using project-docs"
|
||
|
||
# Invoke update mode
|
||
"Update project docs across Gitea, Obsidian, Vikunja, and Outline"
|
||
```
|
||
|
||
---
|
||
|
||
## falcode-zellij
|
||
|
||
Zellij plugin + agent extensions that track all active AI coding panes (pi, OpenCode, Claude Code) across Zellij sessions in a floating popup. Jump to any pane with one keystroke. Shows attention icons on Zellij tabs when an agent starts/stops working.
|
||
|
||
### Components
|
||
|
||
| Component | Location | Purpose |
|
||
|-----------|----------|---------|
|
||
| **Zellij WASM plugin** | `~/.config/zellij/plugins/falcode-zellij-sessions.wasm` | Floating popup UI showing all agent panes |
|
||
| **pi extension** | `~/.pi/agent/extensions/falcode.ts` | Reports pi pane status (working/idle) to the Zellij plugin |
|
||
| **attention WASM** | `~/.config/zellij/plugins/zellij-attention.wasm` | Shows ⏳/✅ icons on Zellij tabs when agent is active/done |
|
||
| **detection script** | `~/.local/state/falcode-zellij/` | Shared state directory for pane status snapshots |
|
||
|
||
### Keybindings
|
||
|
||
| Key | Action |
|
||
|-----|--------|
|
||
| `Alt a` | Launch/focus falcode floating popup (config.kdl `shared_except "locked"`) |
|
||
|
||
### pi integration
|
||
|
||
The `falcode.ts` extension auto-detects Zellij via `ZELLIJ_PANE_ID`/`ZELLIJ_SESSION_NAME` env vars. Outside Zellij it's a no-op.
|
||
|
||
- `agent_start` event → writes `"working"` status
|
||
- `agent_end` event → writes `"waiting_user_input"` status
|
||
- Heartbeat every 60s to keep pane alive
|
||
- `FALCODE_NOTIFY_SCRIPT=/bin/true` in home.nix (disables macOS notifications on Linux)
|
||
|
||
### Install on new machine
|
||
|
||
```bash
|
||
# pi extension
|
||
mkdir -p ~/.pi/agent/extensions
|
||
curl -L https://raw.githubusercontent.com/victor-falcon/falcode-zellij/main/pi-extension/falcode.ts \
|
||
-o ~/.pi/agent/extensions/falcode.ts
|
||
|
||
# WASM plugins
|
||
mkdir -p ~/.config/zellij/plugins
|
||
curl -L https://github.com/victor-falcon/falcode-zellij/releases/latest/download/falcode-zellij-sessions.wasm \
|
||
-o ~/.config/zellij/plugins/falcode-zellij-sessions.wasm
|
||
curl -L https://github.com/victor-falcon/falcode-zellij/releases/latest/download/zellij-attention.wasm \
|
||
-o ~/.config/zellij/plugins/zellij-attention.wasm
|
||
```
|
||
|
||
### Claude Code integration
|
||
|
||
Also has a hook at `~/.local/state/falcode-zellij/falcode-hook.sh` for Claude Code status reporting. See [README](https://github.com/victor-falcon/falcode-zellij#readme) for Claude config.
|
||
|
||
### Zellij config (`config.kdl`)
|
||
|
||
Already configured in Home Manager:
|
||
```kdl
|
||
plugins {
|
||
falcode location="file:/home/sam/.config/zellij/plugins/falcode-zellij-sessions.wasm" {
|
||
state_dir "/home/sam/.local/state/falcode-zellij"
|
||
}
|
||
attention location="file:/home/sam/.config/zellij/plugins/zellij-attention.wasm"
|
||
}
|
||
|
||
load_plugins {
|
||
"file:/home/sam/.config/zellij/plugins/zellij-attention.wasm" {
|
||
enabled "true"
|
||
waiting_icon "⏳"
|
||
completed_icon "✅"
|
||
}
|
||
}
|
||
|
||
keybinds {
|
||
shared_except "locked" {
|
||
bind "Alt a" {
|
||
LaunchOrFocusPlugin "falcode" {
|
||
floating true
|
||
move_to_focused_tab true
|
||
}
|
||
}
|
||
}
|
||
}
|
||
```
|
||
|
||
---
|
||
|
||
## Security Tools (npm Global)
|
||
|
||
Three tools installed globally at `~/.local/share/npm-global/bin/` to guard package installs.
|
||
|
||
### SafeDep Vet (`vet`)
|
||
|
||
Scans local directories for multi-language malware signatures. Catches obfuscated code, suspicious imports, base64 payloads.
|
||
|
||
```bash
|
||
# Scan a cloned repo before touching it
|
||
vet scan -D . --format json --filter "package.malware == true"
|
||
|
||
# Scan package metadata from npm registry
|
||
vet scan package <name> --format json
|
||
```
|
||
|
||
### Socket Firewall (`socket`)
|
||
|
||
Wraps npm/pip installs with real-time scanning. Blocks malicious packages at install time.
|
||
|
||
```bash
|
||
# Safe npm install
|
||
socket npm install <package>
|
||
|
||
# Safe pip install
|
||
socket pip install -r requirements.txt
|
||
```
|
||
|
||
### npq
|
||
|
||
Checks package names against typosquatting lists before install. Lightweight, local, no phoning home.
|
||
|
||
```bash
|
||
npq check <package> --json
|
||
```
|
||
|
||
### Workflow
|
||
|
||
```
|
||
1. vet scan → checks for malware in the code/package
|
||
2. npq check → checks the package name for typosquatting
|
||
3. socket install → wraps the actual install with runtime scanning
|
||
```
|
||
|
||
The **npm-security** skill instructs the Pi agent to follow this workflow before any install.
|
||
|
||
|
||
## Headroom
|
||
|
||
Headroom is a **context compression layer** that reduces prompt token usage by 60-95% for heavy analysis/code/devops workloads. It runs as a Docker container on the server (192.168.20.13) and is triggered by the headroom-bridge extension.
|
||
|
||
### How it works
|
||
|
||
1. headroom-bridge detects analysis/code/devops contexts
|
||
2. Tags `read`, `discuss`, `search` **never** trigger compression (these are fast paths)
|
||
3. For all other tags, if accumulated context exceeds ~5K tokens, headroom-bridge calls `compress()`
|
||
4. Messages are sent to the Headroom proxy at `192.168.20.13:8787`
|
||
5. Headroom compresses the context (using SmartCrusher for JSON, CodeCompressor for AST, Kompress-base ML for text)
|
||
6. Compressed messages are returned and forwarded to the LLM
|
||
7. If the proxy is down, messages pass through unchanged (graceful fallback)
|
||
|
||
### Architecture
|
||
|
||
```
|
||
Desktop (.27) Server (.13)
|
||
───────────── ────────────
|
||
headroom-bridge headroom proxy (Docker)
|
||
│ │
|
||
│ if compress needed: │
|
||
│ compress_for_agent(content) ──────►│
|
||
│ HTTP POST 192.168.20.13:8787 │
|
||
│ ◄────────── compressed content │
|
||
│ │
|
||
│ return to agent │
|
||
│ │
|
||
│ if proxy down: pass through │
|
||
```
|
||
|
||
### Compression thresholds
|
||
|
||
| Condition | Action |
|
||
|---|---|
|
||
| Tag is `read`/`discuss`/`search` | Skip — no compression |
|
||
| Context < 5K tokens | Skip — too small to benefit |
|
||
| Context ≥ 5K tokens + analysis/code/devops tag | Compress |
|
||
| Proxy unreachable | Pass through unchanged |
|
||
|
||
### headroom-bridge
|
||
|
||
Path: `~/.agents/extensions/headroom-bridge/index.ts`. Tool: `compress_for_agent({ content })` — compresses content >20K chars via Headroom Docker on .13:8787. 60-95% token reduction. See [[#Function Calls]] for signature.
|
||
|
||
### Management
|
||
|
||
```bash
|
||
# Check status
|
||
ssh 192.168.20.13 "docker ps --filter name=headroom"
|
||
|
||
# View logs
|
||
ssh 192.168.20.13 "docker logs --tail 20 headroom"
|
||
|
||
# Restart
|
||
ssh 192.168.20.13 "docker restart headroom"
|
||
|
||
# Update image
|
||
ssh 192.168.20.13 "cd /home/sam/Docker/Containers/headroom && docker compose pull && docker compose up -d"
|
||
```
|
||
|
||
### Files
|
||
|
||
| File | Purpose |
|
||
|------|---------|
|
||
| `~/.agents/extensions/headroom-bridge/index.ts` | `compress_for_agent` tool implementation |
|
||
| `/home/sam/Docker/Containers/headroom/docker-compose.yml` | Docker service definition (on .13) |
|
||
| `/home/sam/Docker/Containers/headroom/.env` | Environment file (on .13) |
|
||
|
||
|
||
## codebase-memory-mcp
|
||
|
||
Code intelligence MCP server by DeusData. Single static C binary (~13MB), zero dependencies, 158 languages. Indexes a codebase into a persistent knowledge graph — average repo in milliseconds. 15 MCP tools for structural queries. Runs locally, code never leaves your machine.
|
||
|
||
**Install:**
|
||
```bash
|
||
curl -fsSL https://raw.githubusercontent.com/DeusData/codebase-memory-mcp/main/install.sh | bash
|
||
```
|
||
Installed to `~/.local/bin/codebase-memory-mcp`.
|
||
|
||
**Index a project:**
|
||
```
|
||
mcp({ tool: "index_repository", args: '{"repo_path": ".", "mode": "fast"}' })
|
||
```
|
||
|
||
**15 Tools:**
|
||
|
||
| Tool | What it does |
|
||
|------|-------------|
|
||
| `index_repository` | Index a repo (full/moderate/fast/cross-repo-intelligence modes) |
|
||
| `search_graph` | BM25 full-text search + semantic vector search for code |
|
||
| `query_graph` | Cypher queries — multi-hop patterns, complexity analysis |
|
||
| `trace_path` | Follow call chains, data flow, or cross-service HTTP via Route nodes |
|
||
| `get_code_snippet` | Read source code for a function/class/symbol |
|
||
| `get_graph_schema` | Show available node labels and edge types |
|
||
| `get_architecture` | High-level architecture: packages, clusters, routes, entry points |
|
||
| `search_code` | Grep + graph enrichment, ranked by structural importance |
|
||
| `list_projects` | List all indexed projects |
|
||
| `delete_project` | Remove a project from the graph |
|
||
| `index_status` | Check index freshness and stats |
|
||
| `detect_changes` | Find files changed since last index |
|
||
| `manage_adr` | Architecture Decision Records |
|
||
| `ingest_traces` | Import OpenTelemetry traces into the graph |
|
||
|
||
**MCP config** (`~/.pi/agent/mcp.json`):
|
||
```json
|
||
{
|
||
"mcpServers": {
|
||
"codebase-memory": {
|
||
"command": "/home/sam/.local/bin/codebase-memory-mcp",
|
||
"lifecycle": "lazy"
|
||
}
|
||
}
|
||
}
|
||
```
|
||
|
||
**Deployed on all machines (.27, .13, .51):**
|
||
```bash
|
||
~/.local/bin/codebase-memory-mcp --version # v0.9.0
|
||
```
|
||
Path not in shell PATH on .13/.51 — MCP config uses absolute path `/home/sam/.local/bin/codebase-memory-mcp` so still works.
|
||
|
||
**Install command (if needed on new machine):**
|
||
```bash
|
||
curl -fsSL https://raw.githubusercontent.com/DeusData/codebase-memory-mcp/main/install.sh | bash
|
||
```
|
||
|
||
**UI mode** (graph visualization at `localhost:9749`):
|
||
```bash
|
||
curl -fsSL .../install.sh | bash -s -- --ui
|
||
codebase-memory-mcp --ui=true --port=9749
|
||
```
|
||
|
||
Paper: [arXiv:2603.27277](https://arxiv.org/abs/2603.27277)
|
||
|
||
---
|
||
|
||
## code-review-graph
|
||
|
||
Structural code intelligence MCP server by tirth8205. Parses source code with Tree-sitter AST into a knowledge graph (functions, classes, imports, calls, inheritance, tests). Stored in SQLite. 28+ MCP tools for token-efficient code review, blast-radius analysis, and architectural insights. **Per-project** — each repo gets its own `.code-review-graph/graph.db`.
|
||
|
||
**Install:**
|
||
```bash
|
||
uv tool install code-review-graph # or: pipx install code-review-graph
|
||
```
|
||
Installed to `~/.local/bin/code-review-graph` v2.3.7.
|
||
|
||
**Build a graph for a project:**
|
||
```bash
|
||
cd /etc/nixos
|
||
code-review-graph build # parses codebase → .code-review-graph/graph.db
|
||
```
|
||
|
||
**Key MCP tools:**
|
||
| Tool | What it does |
|
||
|------|-------------|
|
||
| `get_review_context` | Compact review context (callers, callees, tests, risks) |
|
||
| `get_impact_radius` | Blast radius — every caller/dependent/test affected by a change |
|
||
| `query_graph` | Direct graph queries (traverse call chains, dependency paths) |
|
||
| `semantic_search_nodes` | Semantic (embedding-based) code search |
|
||
| `detect_changes` | Diff analysis: what changed and what's affected |
|
||
| `traverse_graph` | Walk the graph in any direction (BFS/DFS from any node) |
|
||
| `get_architecture_overview` | High-level structure: packages, clusters, entry points |
|
||
| `get_affected_flows` | Execution paths impacted by a change |
|
||
|
||
**Complement to codebase-memory-mcp:** code-review-graph captures **what your code is** (structure, dependencies), codebase-memory-mcp captures **what agents learn** (decisions, patterns, runbooks). They solve different layers — install both.
|
||
|
||
**Installed on:** .27 (uv tool install), .51 (nix-shell -p uv → uv tool install)
|
||
|
||
**GitHub:** [tirth8205/code-review-graph](https://github.com/tirth8205/code-review-graph) (28K+ stars)
|
||
|
||
---
|
||
|
||
## Pi Dashboard
|
||
|
||
A multi-component system for live agent visibility across all machines. Every pi session on every machine (plus sub-agents) reports its state; the TUI shows them all in one table and can attach to them, review their diffs, or open their task boards.
|
||
|
||
### Architecture
|
||
|
||
```
|
||
pi session (any machine, any terminal: zellij / tmux / plain)
|
||
└─ dashboard.ts extension
|
||
├─ writes ~/.pi/agent/dashboard/<session>.json (heartbeat every 15s + on events)
|
||
├─ tracks tasks → <project>/todo.txt
|
||
└─ sends NTFY / Apprise / notify-send notifications
|
||
│ SSH pull (cat *.json)
|
||
pi-dashboard (Go TUI on .27) ◄───────────────────────┴── .13 + .51 state dirs
|
||
```
|
||
|
||
| Component | Type | Purpose |
|
||
|-----------|------|---------|
|
||
| **dashboard.ts** | pi extension (`~/.pi/agent/extensions/dashboard.ts`; source `~/.agents/extensions/dashboard.ts` → Gitea `pi-config`) | Per-session telemetry: heartbeat, cwd, started/closed times, agent status, tool count; task tools; notifications |
|
||
| **pi-dashboard** | Go binary (`~/.local/bin/pi-dashboard`) | Bubble Tea TUI over all machines' state files |
|
||
| **Tuxedo** | Rust binary (`tuxedo`, nix) | todo.txt task manager (vim keys, phone capture QR) — per-project boards |
|
||
| **Hunk** | Node CLI (`hunk`, nix / npm `hunkdiff`) | Review-first terminal diff viewer for agent-authored changes |
|
||
|
||
### Quick start
|
||
|
||
```bash
|
||
pi-dashboard # full TUI
|
||
pi-dashboard --list # plain-text snapshot of local sessions
|
||
pi-dashboard --help # keybindings + config reference
|
||
```
|
||
|
||
### Day-to-day usage (the mental model)
|
||
|
||
**The pi terminal is for talking; the dashboard TUI is for watching.** You never type tool names or run hunk/tuxedo inside the pi input.
|
||
|
||
| You want to… | What you do | What happens |
|
||
|---|---|---|
|
||
| Add / list / complete tasks | Tell pi: *"add a task: …"*, *"what tasks do I have?"*, *"mark … done"* | The agent calls `register_task` / `list_tasks` / `complete_task`, which write lines to `<project>/todo.txt` at the project root |
|
||
| See the task board | Press `Tab` in the dashboard TUI | Tuxedo opens the selected session's `todo.txt` (vim keys: `j/k`, `dd` complete, `u` undo, `s` phone QR) |
|
||
| Review what an agent changed | Press `d` on its row in the dashboard TUI | Hunk opens in the agent's folder: `cd <cwd> && hunk diff --watch` — shows **all uncommitted changes** in that repo (not a two-file compare) |
|
||
| Jump into a session | Press `Enter` on its row | `tmux attach` / `zellij attach` / `zellij action switch-session` |
|
||
|
||
Key points:
|
||
- `register_task`/`complete_task`/`list_tasks` are **agent tools** — you ask in English, the AI calls them. They feed todo.txt, which is what Tuxedo displays.
|
||
- **Hunk's "first/second file" mode** is `hunk diff <left> <right>` for comparing two concrete files. The dashboard `d` key uses `hunk diff --watch` (whole working tree) instead.
|
||
- Both task systems coexist: the **dashboard tools** → todo.txt → Tuxedo (vim board), while **@tintinweb/pi-tasks** (`TaskCreate`, `TaskExecute`, `/tasks`) is a separate dependency-tracked task engine that can spawn subagents.
|
||
|
||
### State model
|
||
|
||
Each session writes `~/.pi/agent/dashboard/<session>.json` (atomic write):
|
||
|
||
| Field | Meaning |
|
||
|-------|---------|
|
||
| `session` | pi session name |
|
||
| `cwd` | full working directory the session runs in (the **Folder** column) |
|
||
| `session_started_at` / `closed_at` | session start / graceful-close times |
|
||
| `last_seen_at` | heartbeat — refreshed every 15 s + on every event |
|
||
| `agent_status` | `idle` / `running` / `blocked` / `error` (the *agent turn*) |
|
||
| `session_state` | `open` / `closed` (the *process liveness*) |
|
||
| `terminal_type` | `tmux` / `zellij` / `tmux+zellij` / `direct` |
|
||
| `zellij_session` / `tmux_session` / `pid` | attach targets for Enter |
|
||
| `is_subagent` | true for rows named `<Agent>#<8hex>` (pi-subagents) |
|
||
|
||
**Closed detection** — a session counts as closed when:
|
||
- the extension wrote `session_state: "closed"` on graceful shutdown, **or**
|
||
- `last_seen_at` is older than `stale_after` (default 45 s) — the terminal was killed (pane closed, `kill -9`) without a shutdown event.
|
||
|
||
Status labels: `● running` · `○ idle` · `⚠ blocked` · `✕ error` · `✗ closed` (graceful) · `✗ lost` (died without shutdown).
|
||
|
||
### TUI keybindings
|
||
|
||
| Key | Action |
|
||
|-----|--------|
|
||
| `↑↓` | Select agent |
|
||
| `Enter` | Attach: `tmux attach -t <name>` / `zellij attach <name>` (dashboard outside zellij) / `zellij action switch-session <name>` (dashboard inside zellij) — local, or over SSH for remote rows |
|
||
| `d` | **Hunk** — review the selected agent's changes *in its own folder*: `cd <cwd> && hunk diff --watch` |
|
||
| `Tab` | **Tuxedo** — open the selected agent's **project** task board: `<cwd>/todo.txt` (created if missing; falls back to global board) |
|
||
| `s` | Cycle sort: **smart** (live first → running first → last activity) → activity → started → folder |
|
||
| `x` | Toggle hiding closed sessions (dead sessions sink to the bottom by default; `x` removes them from the view, press again to restore) |
|
||
| `z` | Toggle hiding sub-agent rows (marked `◇`) |
|
||
| `r` | Force refresh |
|
||
| `q` | Quit |
|
||
|
||
Selecting a row shows a detail pane: full folder path, started / closed / last-seen times, terminal + zellij/tmux session + pid, model, tool count, current task, blocked prompt.
|
||
|
||
### Session naming & rename
|
||
|
||
Name resolution order on start: pi session name → `PI_SESSION` env → tmux session name → **zellij session name** (only when it isn't zellij's auto-generated `word-word` animal name like `chatty-echidna`) → working-directory basename.
|
||
|
||
**Recommended workflow — one named zellij session per pi session, same name for both:**
|
||
|
||
```bash
|
||
zellij -s computer_software # create a named zellij session…
|
||
# …pi started inside it auto-inherits "computer_software" as its pi session name
|
||
```
|
||
|
||
**Rename mid-session (pi session + zellij session + dashboard row together):**
|
||
|
||
```text
|
||
/dash-name <name>
|
||
```
|
||
|
||
> pi's built-in `/name` only renames the pi session and cannot be hooked by extensions — `/dash-name` renames all three (pi, zellij, dashboard row). Use `/name` or `Ctrl+R` in `/tree` when you only want to rename the pi session.
|
||
|
||
### Long-running / background sessions (tmux survival layer)
|
||
|
||
To keep a pi session running after zellij (or the terminal) closes — e.g. a long agent job on a remote machine — run pi inside a tmux session **inside** the zellij pane:
|
||
|
||
```bash
|
||
tmux new -s deploy-job # inside the zellij pane
|
||
pi # start pi inside tmux
|
||
# detach with Ctrl-b d — tmux (and pi) keep running after zellij closes
|
||
tmux attach -t deploy-job # reattach whenever
|
||
```
|
||
|
||
The extension detects the `TMUX` env var: rows show `Ⓣ`, and `Enter` does `tmux attach` — the session survives zellij closing. Rows in bare zellij panes show `Ⓩ`; `tmux+zellij` shows `ⓉⓏ`; plain terminals show `·`.
|
||
|
||
### Tasks & Tuxedo
|
||
|
||
- Agents register tasks via the `register_task` / `complete_task` / `list_tasks` tools.
|
||
- Task files are **per project**: `<project>/todo.txt` at the project root (standard todo.txt format) — visible in `ls`, easy to open, and **tracked in git** when the project is a repo: task changes are versioned (progress history) and visible to collaborators who clone the repo. (No gitignore — it's a tiny file; the only caveat is that tasks in a public/shared repo are public, so keep secrets out of task titles.)
|
||
- In the dashboard, `Tab` opens Tuxedo on the **selected row's** project board; with nothing selected it falls back to `~/.pi/agent/dashboard/tasks/todo.txt`.
|
||
- Tuxedo: vim keys (`j/k`, `dd`, `gg/G`), `u` undo (50 levels), `s` QR phone capture → https://github.com/webstonehq/tuxedo
|
||
|
||
### Hunk
|
||
|
||
- `d` in the dashboard runs `hunk diff --watch` in the selected agent's folder (over SSH for remote rows) — review exactly what that agent changed.
|
||
- Standalone: `hunk diff --watch` (live review of the working tree), `hunk show` (last commit). Multi-file sidebar, inline AI annotations, split/stack/responsive layouts. → https://github.com/modem-dev/hunk
|
||
|
||
### Cross-machine config (`~/.config/pi-dashboard.yaml`)
|
||
|
||
```yaml
|
||
poll_interval: 2
|
||
stale_after: 45 # seconds without heartbeat ⇒ session considered closed
|
||
hide_closed: false # start with closed sessions hidden (toggle with x)
|
||
local:
|
||
path: /home/sam/.pi/agent/dashboard/
|
||
remote:
|
||
- host: 192.168.20.13
|
||
user: sam
|
||
path: /home/sam/.pi/agent/dashboard/
|
||
- host: 192.168.20.51
|
||
user: sam
|
||
path: /home/sam/.pi/agent/dashboard/
|
||
```
|
||
|
||
Remote polling is plain `ssh … "cat <path>/*.json"` (BatchMode, 5 s connect timeout); unreachable remotes are skipped silently.
|
||
|
||
### Deployment
|
||
|
||
- **Extension** — source of truth: `~/.agents/extensions/dashboard.ts` (Gitea `pi-config`). Edit there, commit + push, then copy to `~/.pi/agent/extensions/dashboard.ts` on each machine (`.27`, `.13`, `.51`).
|
||
- **Binary** — `cd ~/src/pi-dashboard && CGO_ENABLED=0 go build -o ~/.local/bin/pi-dashboard .`, then `scp` to `.13`/`.51`.
|
||
- After updating the extension on a machine, run `/reload` in running pi sessions (or restart) to activate it.
|
||
- Dead state files accumulate by design (they just show as closed); the `archive/` subfolder holds pruned files.
|
||
|
||
---
|
||
|
||
## engram + gentle-engram
|
||
|
||
engram v1.16.1 runs on nixos-desktop (.13) at `~/.local/bin/engram`. Systemd user service auto-starts. Binds `127.0.0.1:7437`, accessed via SSH tunnel: `ssh -fNL 7437:127.0.0.1:7437 192.168.20.13`.
|
||
|
||
**gentle-engram** connects via `ENGRAM_URL=http://127.0.0.1:7437`. Replaces memory-vault. Features: session capture, compaction recovery, private block redaction.
|
||
|
||
⚠️ **The SSH tunnel must be running for engram to work.** It does not auto-start. Re-establish with: `ssh -fNL 7437:127.0.0.1:7437 192.168.20.13`
|
||
|
||
---
|
||
|
||
## Paseo (orchestration layer — not a skill/extension)
|
||
|
||
Paseo is the **multi-agent orchestration GUI** that wraps pi — not a skill or extension itself, but it runs pi agents (via `pi --mode rpc`) and is part of the agent stack. Full docs: **[[Paseo Pi GUI Tool]]** (Obsidian) · Gitea `sam/paseo` · maps.lab `/paseo/docs/`.
|
||
|
||
| Aspect | Detail |
|
||
|---|---|
|
||
| **What** | Client-server orchestration: daemon spawns/manages pi agents, streams output to CLI/web/mobile |
|
||
| **Where** | `.13` Docker `paseo` (:6767, password auth, `restart: always`) — `/home/sam/Docker/Containers/paseo/` |
|
||
| **Image** | `ghcr.io/getpaseo/paseo:latest` + baked pi 0.82.1 + `omniroute-pi-ext-integration` (built as `USER root`, runs as user `paseo`) |
|
||
| **Config** | container `~/.pi/` on the paseo-home volume: settings.json (omni provider, default model `default-opencode-go-ds-flash`), models.json (key + 476 omni models) |
|
||
| **LLM** | pi → omni provider → OmniRoute `.13:20129` (LAN IP reachable from bridge net) |
|
||
| **Clients** | `@getpaseo/cli` 0.7.2 on .27/.51 (env `PASEO_HOST`+`PASEO_PASSWORD` in each machine's `10-secrets.conf`); web UI `http://192.168.20.13:6767` (LAN) / `http://100.114.62.46:6767` (Tailscale, incl. mobile) |
|
||
| **Workspace** | `.13` `/home/sam/Docker/Containers/paseo/workspace/` → mounted at `/workspace` in the container (agents only see mounted folders) |
|
||
| **Notes** | Container pi is minimal — host `~/.agents` skills/extensions NOT auto-included (selective per-folder config = follow-up); browsers via separate `pi-browser-harness`; alerts via Apprise/NTFY follow-up |
|
||
|
||
---
|
||
|
||
## MCP Servers
|
||
|
||
pi-mcp-adapter connects Pi to external services via the Model Context Protocol.
|
||
|
||
**Config files:** `~/.pi/agent/mcp.json` (pi global), `~/.config/mcp/mcp.json` (shared), `.mcp.json` (project)
|
||
|
||
```json
|
||
// ~/.pi/agent/mcp.json — pi MCP servers
|
||
{
|
||
"mcpServers": {
|
||
"codebase-memory": {
|
||
"command": "/home/sam/.local/bin/codebase-memory-mcp",
|
||
"lifecycle": "lazy"
|
||
},
|
||
"code-review-graph": {
|
||
"command": "/home/sam/.local/bin/code-review-graph",
|
||
"args": ["serve"],
|
||
"lifecycle": "lazy"
|
||
}
|
||
}
|
||
}
|
||
```
|
||
|
||
Shared config at `~/.config/mcp/mcp.json`:
|
||
```json
|
||
{
|
||
"mcpServers": {
|
||
"filesystem": {
|
||
"command": "npx",
|
||
"args": ["-y", "@modelcontextprotocol/server-filesystem", "/home/sam"]
|
||
}
|
||
}
|
||
}
|
||
```
|
||
|
||
**Find MCP servers at:**
|
||
- [github.com/modelcontextprotocol/servers](https://github.com/modelcontextprotocol/servers)
|
||
- [smithery.ai](https://smithery.ai) — community registry
|
||
|
||
**Usage:**
|
||
- `/mcp` — interactive panel to manage servers
|
||
- `mcp({ search: "..." })` — search available tools
|
||
- `mcp({ tool: "tool_name", args: '{}' })` — call a tool
|
||
- Servers are lazy (connect on first use, disconnect after 10 min idle)
|
||
|
||
---
|
||
|
||
## Configuration Files
|
||
|
||
### Global (`~/.pi/agent/settings.json`)
|
||
- Nix store symlink — managed via `/etc/nixos/home/sam/home.nix`
|
||
- Contains: providers (opencode-go, openrouter, google), packages (pi-memctx, pi-prompt-template-model, Gitea)
|
||
- **Read-only** — cannot be modified by `pi install` or `/config-add`
|
||
|
||
### Project (`<project-dir>/.pi/settings.json`)
|
||
- Overrides global settings (arrays replace, not merge)
|
||
- Contains: `~/.agents` package (extensions + skills), Gitea package (tavily-search)
|
||
- Modified via `/config-add` / `/config-remove` commands
|
||
|
||
### Per-folder Memory (via pi-memctx)
|
||
- Memory stored in `<chat-folder>/.pi/memory-vault/packs/`
|
||
- Workspace map at `~/.pi/agent/memory-vault/00-system/workspace-map.json`
|
||
- Each chat folder has isolated memory (prevents sibling directory contamination)
|
||
|
||
|
||
### models.json (Provider Routing)
|
||
|
||
Path: `~/.pi/agent/models.json` (symlinked from `~/.agents/models.json` for Gitea). Injects OpenRouter provider routing for KV cache sharing. DeepSeek cache discount: 91.7% ($0.145/M vs $1.74/M input). Configured: deepseek, qwen, minimax, moonshotai. Mechanism: pi-core reads `model.compat.openRouterRouting` → injects `provider: { order: [...] }`.
|
||
|
||
### subagents.json
|
||
|
||
Path: `~/.pi/agent/subagents.json`. Configuration for pi-subagents agent types, default models, and providers.
|
||
|
||
---
|
||
|
||
## Useful Commands
|
||
|
||
| Command | What it does |
|
||
|---|---|
|
||
| `/config-setup` | One-shot: creates `.pi/`, `settings.json`, memory vault in current folder |
|
||
| `/config-add ext <name>` | Activate an extension from `~/.agents` |
|
||
| `/config-add skill <name>` | Activate a skill from `~/.agents` |
|
||
| `/config-show` | Show active extensions and skills |
|
||
| `/agents` | Interactive agent management (pi-subagents) |
|
||
| `/tasks` | Interactive task management (pi-tasks) |
|
||
| `/memctx-init` | Scan folder, build initial memory pack |
|
||
| `/memctx-status` | Show memory status |
|
||
| `/memctx-refresh` | Re-scan and enrich memory |
|
||
| `/filechanges` | Review changed files, diffs, accept/decline |
|
||
| `/filechanges-accept` | Accept all changes |
|
||
| `/filechanges-decline` | Revert all changes |
|
||
| `markitdown <file>` | Convert file to Markdown (PDF, Word, Excel, PPTX, images, HTML, etc.) |
|
||
| `markitdown-vision <file>` | Describe image using Qwen 2.5 VL 72B via OpenRouter |
|
||
| `Agent()` | Spawn subagent (pi-subagents) |
|
||
| `get_subagent_result()` | Retrieve results from background agent |
|
||
| `steer_subagent()` | Send mid-run steering message |
|
||
| `compress_for_agent()` | Compress large content via Headroom |
|
||
|
||
|
||
## Agent Roster (18)
|
||
|
||
| Agent | Model | Provider |
|
||
|-------|-------|----------|
|
||
| chat-search | google/gemini-2.5-flash:free | openrouter |
|
||
| code-analysis | deepseek-r1-distill-qwen-32b | opencode-go |
|
||
| code-ingest | google/gemini-2.5-flash:free | openrouter |
|
||
| coder-basic | deepseek/deepseek-chat | openrouter |
|
||
| coder-pro | deepseek/deepseek-v4-pro | openrouter |
|
||
| database | deepseek-r1-distill-qwen-32b | opencode-go |
|
||
| devops-basic | deepseek/deepseek-chat | openrouter |
|
||
| devops-pro | deepseek/deepseek-v4-pro | openrouter |
|
||
| document-writer | deepseek-r1-distill-qwen-32b | opencode-go |
|
||
| file-ops | qwen-coder-32b-instruct | opencode-go |
|
||
| home-automation | deepseek-r1-distill-qwen-32b | opencode-go |
|
||
| image-maker | black-forest-labs/flux-1-schnell | openrouter |
|
||
| iot-coder | qwen-coder-32b-instruct | opencode-go |
|
||
| iot-hardware | moonshotai/kimi-k2.6 | openrouter |
|
||
| obsidian | deepseek-r1-distill-qwen-14b | opencode-go |
|
||
| research | google/gemini-2.5-flash:free | openrouter |
|
||
| video-analyze | qwen/qwen-2.5-vl | openrouter |
|
||
| vscode-setup | qwen/qwen-3-coder-next | openrouter |
|
||
|
||
## Function Calls
|
||
|
||
```
|
||
Agent({ subagent_type, prompt, description, model?, thinking?, max_turns?, run_in_background?, resume?, isolated?, isolation?, inherit_context? })
|
||
get_subagent_result({ agent_id, wait?, verbose? })
|
||
steer_subagent({ agent_id, message })
|
||
compress_for_agent({ content })
|
||
```
|
||
|
||
---
|
||
|
||
## Skipped / Bookmarked
|
||
|
||
| Extension/Skill | Reason |
|
||
|---|---|
|
||
| **web-search** (amosblomqvist) | ❌ Redundant — Tavily does this |
|
||
| **subagents** (amosblomqvist) | ❌ Redundant — pi-subagents already installed |
|
||
| **bash-guard** (amosblomqvist) | ❌ Too aggressive — would interrupt flow |
|
||
| **google-image-search** (amosblomqvist) | ❌ Would need Google Search API + CSE setup |
|
||
| **pdf-reader** (amosblomqvist) | ⏳ Bookmarked — Python + pymupdf setup needed |
|
||
| **notify** (mitsuhiko) | ⏳ Minor QoL — desktop notifications on task complete |
|
||
| **audio/voice** | ⏳ Not practical | Pi TUI has no mic access or audio playback — fundamental platform limitation |
|
||
|
||
---
|
||
|
||
## Tasks
|
||
|
||
- [x] Rebuild NixOS to activate new packages ✅ 2026-06-11
|
||
- [x] Migrate to @tintinweb/pi-subagents with 18 agent types ✅ 2026-06-14
|
||
- [x] Deploy models.json with OpenRouter provider pinning (only: provider) ✅ 2026-06-14
|
||
- [x] Deploy engram + gentle-engram memory service on .13 ✅ 2026-06-13
|
||
- [x] Install pi-tasks (@tintinweb/pi-tasks) v0.7.0 ✅ 2026-06-13
|
||
- [x] Patch pi-subagents: 24h cleanup, disable clearCompleted ✅ 2026-06-14
|
||
- [x] Add memory: project to all 18 agent frontmats ✅ 2026-06-14
|
||
- [x] Remove custom subagent-registry skill (built-in /agents menu is sufficient) ✅ 2026-06-14
|
||
- [x] Update Pi Subagent.md and Pi Agent Extensions & Skills.md documentation ✅ 2026-06-14
|
||
- [x] Update pi-subagents to v0.10.3 ✅ 2026-06-14
|
||
- [x] Update pi-tasks to v0.7.0 ✅ 2026-06-13
|
||
- [x] Pi Dashboard v2: heartbeat + cwd + started/closed columns, hide/sort, /dash-name (pi+zellij), hunk in agent folder, tuxedo project boards, zellij/tmux attach ✅ 2026-08-04
|
||
- [ ] Verify video-extract works with Gemini
|
||
- [ ] Clean up workspace-map.json entries for any stale memory packs
|