diff --git a/home/gabriel/features/pi/default.nix b/home/gabriel/features/pi/default.nix index d75bf306..1387e904 100644 --- a/home/gabriel/features/pi/default.nix +++ b/home/gabriel/features/pi/default.nix @@ -1,21 +1,27 @@ -{pkgs, ...}: { +{ + pkgs, + osConfig, + lib, + ... +}: let + customExtensions = pkgs.buildPiPackage { + pname = "extensions"; + version = "unstable"; + src = ./extensions; + npmDeps = pkgs.importNpmLock {npmRoot = ./extensions;}; + npmConfigHook = pkgs.importNpmLock.npmConfigHook; + }; +in { imports = [ ./theme.nix - ./extensions - ./prompts - ./skills - ./packages/pi-claude-bridge.nix - ./packages/pi-codex-image-gen.nix - ./packages/pi-llama-cpp.nix + ./packages ]; programs.pi-coding-agent = { enable = true; - # Used by the web-fetch skill to extract fetched HTML as Markdown. - extraPackages = [pkgs.python3Packages.trafilatura]; + extraPackages = [pkgs.python3Packages.trafilatura]; # Used by the web-fetch skill context = ./context.md; settings = { - llamaServerUrl = "http://llm.m7.rs"; compaction = { enabled = true; keepRecentTokens = 20000; @@ -28,6 +34,32 @@ "qwen3.6" "gemma-4" ]; + + skills = [./skills]; + prompts = [./prompts]; + extensions = [customExtensions]; + + webSearch = { + braveApiKeyFile = osConfig.sops.secrets.brave_api_key.path; + kagiSessionTokenFile = osConfig.sops.secrets.kagi_session_token.path; + }; + + gondolin = { + qemuPath = lib.getExe pkgs.qemu; + httpProxy = { + allowedHosts = ["api.github.com" "firefly.m7.rs"]; + secrets = { + GITHUB_TOKEN = { + hosts = ["api.github.com"]; + cmd = "gh auth token"; + }; + FIREFLY_TOKEN = { + hosts = ["firefly.m7.rs"]; + cmd = "pass firefly.m7.rs/pi-pat"; + }; + }; + }; + }; }; keybindings = { "app.editor.external" = ["alt+e"]; diff --git a/home/gabriel/features/pi/extensions/gabs-extensions/cd.ts b/home/gabriel/features/pi/extensions/cd.ts similarity index 100% rename from home/gabriel/features/pi/extensions/gabs-extensions/cd.ts rename to home/gabriel/features/pi/extensions/cd.ts diff --git a/home/gabriel/features/pi/extensions/gabs-extensions/codex-usage.ts b/home/gabriel/features/pi/extensions/codex-usage.ts similarity index 100% rename from home/gabriel/features/pi/extensions/gabs-extensions/codex-usage.ts rename to home/gabriel/features/pi/extensions/codex-usage.ts diff --git a/home/gabriel/features/pi/extensions/gabs-extensions/cwd-tools.ts b/home/gabriel/features/pi/extensions/cwd-tools.ts similarity index 100% rename from home/gabriel/features/pi/extensions/gabs-extensions/cwd-tools.ts rename to home/gabriel/features/pi/extensions/cwd-tools.ts diff --git a/home/gabriel/features/pi/extensions/default.nix b/home/gabriel/features/pi/extensions/default.nix deleted file mode 100644 index 71848863..00000000 --- a/home/gabriel/features/pi/extensions/default.nix +++ /dev/null @@ -1,42 +0,0 @@ -{ - pkgs, - lib, - osConfig, - ... -}: let - gabsExtensions = pkgs.buildPiExtension { - pname = "pi-extensions"; - version = "unstable"; - src = ./gabs-extensions; - npmDeps = pkgs.importNpmLock {npmRoot = ./gabs-extensions;}; - npmConfigHook = pkgs.importNpmLock.npmConfigHook; - }; -in { - programs.pi-coding-agent = { - settings = { - extensions = [ - gabsExtensions - ]; - webSearch = { - braveApiKeyFile = osConfig.sops.secrets.brave_api_key.path; - kagiSessionTokenFile = osConfig.sops.secrets.kagi_session_token.path; - }; - gondolin = { - qemuPath = lib.getExe pkgs.qemu; - httpProxy = { - allowedHosts = ["api.github.com" "firefly.m7.rs"]; - secrets = { - GITHUB_TOKEN = { - hosts = ["api.github.com"]; - cmd = "gh auth token"; - }; - FIREFLY_TOKEN = { - hosts = ["firefly.m7.rs"]; - cmd = "pass firefly.m7.rs/pi-pat"; - }; - }; - }; - }; - }; - }; -} diff --git a/home/gabriel/features/pi/extensions/gabs-extensions/inline-bash.ts b/home/gabriel/features/pi/extensions/inline-bash.ts similarity index 100% rename from home/gabriel/features/pi/extensions/gabs-extensions/inline-bash.ts rename to home/gabriel/features/pi/extensions/inline-bash.ts diff --git a/home/gabriel/features/pi/extensions/gabs-extensions/jj-workspace.ts b/home/gabriel/features/pi/extensions/jj-workspace.ts similarity index 100% rename from home/gabriel/features/pi/extensions/gabs-extensions/jj-workspace.ts rename to home/gabriel/features/pi/extensions/jj-workspace.ts diff --git a/home/gabriel/features/pi/extensions/gabs-extensions/lib/cwd.ts b/home/gabriel/features/pi/extensions/lib/cwd.ts similarity index 100% rename from home/gabriel/features/pi/extensions/gabs-extensions/lib/cwd.ts rename to home/gabriel/features/pi/extensions/lib/cwd.ts diff --git a/home/gabriel/features/pi/extensions/gabs-extensions/model-context.ts b/home/gabriel/features/pi/extensions/model-context.ts similarity index 100% rename from home/gabriel/features/pi/extensions/gabs-extensions/model-context.ts rename to home/gabriel/features/pi/extensions/model-context.ts diff --git a/home/gabriel/features/pi/extensions/gabs-extensions/package-lock.json b/home/gabriel/features/pi/extensions/package-lock.json similarity index 100% rename from home/gabriel/features/pi/extensions/gabs-extensions/package-lock.json rename to home/gabriel/features/pi/extensions/package-lock.json diff --git a/home/gabriel/features/pi/extensions/gabs-extensions/package.json b/home/gabriel/features/pi/extensions/package.json similarity index 100% rename from home/gabriel/features/pi/extensions/gabs-extensions/package.json rename to home/gabriel/features/pi/extensions/package.json diff --git a/home/gabriel/features/pi/extensions/gabs-extensions/pi-gondolin.ts b/home/gabriel/features/pi/extensions/pi-gondolin.ts similarity index 100% rename from home/gabriel/features/pi/extensions/gabs-extensions/pi-gondolin.ts rename to home/gabriel/features/pi/extensions/pi-gondolin.ts diff --git a/home/gabriel/features/pi/extensions/gabs-extensions/suggest-edit.ts b/home/gabriel/features/pi/extensions/suggest-edit.ts similarity index 100% rename from home/gabriel/features/pi/extensions/gabs-extensions/suggest-edit.ts rename to home/gabriel/features/pi/extensions/suggest-edit.ts diff --git a/home/gabriel/features/pi/extensions/gabs-extensions/tsconfig.json b/home/gabriel/features/pi/extensions/tsconfig.json similarity index 100% rename from home/gabriel/features/pi/extensions/gabs-extensions/tsconfig.json rename to home/gabriel/features/pi/extensions/tsconfig.json diff --git a/home/gabriel/features/pi/extensions/gabs-extensions/web.ts b/home/gabriel/features/pi/extensions/web.ts similarity index 100% rename from home/gabriel/features/pi/extensions/gabs-extensions/web.ts rename to home/gabriel/features/pi/extensions/web.ts diff --git a/home/gabriel/features/pi/packages/default.nix b/home/gabriel/features/pi/packages/default.nix new file mode 100644 index 00000000..1898fcc2 --- /dev/null +++ b/home/gabriel/features/pi/packages/default.nix @@ -0,0 +1,7 @@ +{ + imports = [ + ./pi-claude-bridge.nix + ./pi-codex-image-gen.nix + ./pi-llama-cpp.nix + ]; +} diff --git a/home/gabriel/features/pi/packages/pi-claude-bridge.nix b/home/gabriel/features/pi/packages/pi-claude-bridge.nix index 54b2d38b..a180cdd7 100644 --- a/home/gabriel/features/pi/packages/pi-claude-bridge.nix +++ b/home/gabriel/features/pi/packages/pi-claude-bridge.nix @@ -1,4 +1,4 @@ -{pkgs, ...}: let +{pkgs, lib, ...}: let piClaudeBridge = pkgs.buildPiPackage { pname = "pi-claude-bridge"; version = "unstable"; diff --git a/home/gabriel/features/pi/packages/pi-llama-cpp.nix b/home/gabriel/features/pi/packages/pi-llama-cpp.nix index 471e0f16..79fd9ded 100644 --- a/home/gabriel/features/pi/packages/pi-llama-cpp.nix +++ b/home/gabriel/features/pi/packages/pi-llama-cpp.nix @@ -11,5 +11,8 @@ dontNpmInstall = true; }; in { - programs.pi-coding-agent.settings.packages = [piLlamaCpp]; + programs.pi-coding-agent.settings = { + llamaServerUrl = "http://llm.m7.rs"; + packages = [piLlamaCpp]; + }; } diff --git a/home/gabriel/features/pi/prompts/default.nix b/home/gabriel/features/pi/prompts/default.nix deleted file mode 100644 index 80cdd421..00000000 --- a/home/gabriel/features/pi/prompts/default.nix +++ /dev/null @@ -1,5 +0,0 @@ -{ - programs.pi-coding-agent.settings.prompts = [ - ./. - ]; -} diff --git a/home/gabriel/features/pi/skills/default.nix b/home/gabriel/features/pi/skills/default.nix deleted file mode 100644 index a1836b90..00000000 --- a/home/gabriel/features/pi/skills/default.nix +++ /dev/null @@ -1,5 +0,0 @@ -{ - programs.pi-coding-agent.settings.skills = [ - ./. - ]; -} diff --git a/home/gabriel/features/pi/skills/pi-extension-authoring/SKILL.md b/home/gabriel/features/pi/skills/pi-extension-authoring/SKILL.md index a02a3208..a77647ab 100644 --- a/home/gabriel/features/pi/skills/pi-extension-authoring/SKILL.md +++ b/home/gabriel/features/pi/skills/pi-extension-authoring/SKILL.md @@ -1,83 +1,62 @@ --- name: pi-extension-authoring -description: Workflow for creating or wiring Pi extensions and skills. Use when adding, changing, packaging, or persisting global Pi extensions/skills for Gabs; not for per-project extensions/skills. Always load this when you consider writing/editing `~/.pi/agent` in any way. +description: Workflow guidelines for durable Pi package, extension, skill, prompt, and theme changes in Gabs's Nix-managed Pi config. Use before editing ~/.pi/agent or home/gabriel/features/pi. --- -# Pi Extending for Gabs's NixConfig +# Pi Authoring for Gabs's NixConfig -This skill is the local persistence map and workflow, not a replacement for Pi docs. If API details are needed, read the relevant Pi docs/examples first, then apply the repo-specific rules here. +This is a workflow guardrail, not a duplicate map of the code. Inspect the existing Nix files and follow their current shape. -The config usually lives at `~/Projects/NixConfig` and at `https://github.com/misterio77/nix-config`. +## First principles -This only applies to "global" (i.e. `~/.pi/agent`) pi configs. +- Read the current Pi docs before relying on API/package behavior: packages, extensions, skills, themes, and TUI docs as relevant. +- Do not edit `~/.pi/agent/*` for durable changes. It is Home Manager output. Temporary experiments are fine, but upstream working changes into Nix before calling them done. +- Prefer Pi packages for third-party/external resources. If a package provides metadata or conventional resource directories, wire it as a package and let Pi discover what it contains. +- Do not split a single external package into separate extension/skill paths unless package discovery genuinely cannot represent it. +- Use `pkgs.buildPiPackage` for package wiring. -## Persistence model +## Local vs external -Do not edit `~/.pi/agent/*` directly for durable changes. It is Home Manager output. +- Gabs-owned code belongs in the local Pi resource areas already wired by the module. +- Third-party code belongs under the external package module pattern already present in the repo. +- When unsure, copy the nearest existing example and adjust minimally. The repo is the source of truth; this skill is just the goblin with a clipboard. -Durable Pi config lives under: +## Change process -- `home/gabriel/features/pi/default.nix` — core Pi settings, context, keybindings -- `home/gabriel/features/pi/extensions/default.nix` — extension packages and `settings.extensions` -- `home/gabriel/features/pi/extensions/gabs-extensions/` — Gabs's packaged TypeScript extensions -- `home/gabriel/features/pi/skills/default.nix` — skill list exported to Pi settings -- `home/gabriel/features/pi/skills/*/SKILL.md` — repo-managed skills +1. Inspect current files before editing. +2. For external packages, review the source first. Pi packages can execute code; skills can instruct the agent to do anything. +3. Keep package derivations single-source: if one package contains both extension and skill resources, build/fetch it once. +4. Update package imports/aggregation in the same style as the existing modules. +5. Format touched Nix files only. +6. Evaluate the relevant `programs.pi-coding-agent.settings` values to confirm paths/types are what Pi will receive. +7. If package discovery matters, inspect the built output for `package.json` / conventional resource directories. -## Configuring Pi +## Local extension process -Edit the relevant `.nix` files. +When changing Gabs-owned TypeScript extensions: -## Tweaking global context +1. Keep runtime dependencies in `package.json`; update the lockfile when dependencies change. +2. Run the package's typecheck and formatter/check scripts from the extension package directory. +3. Then format touched Nix files and evaluate the Pi settings/package output. -Edit the `context.md` file. +## Skill content guidelines -## Adding or changing a local extension - -Use `home/gabriel/features/pi/extensions/gabs-extensions/` for Gabs-owned extensions. - -Checklist: - -1. Add or edit a `*.ts` file there. -2. Keep dependencies in `package.json`; update `package-lock.json` if dependencies change. -3. Run from that directory: - - `npm run typecheck` - - `npm run format` if TypeScript files changed -4. From repo root, format touched Nix files with `nix fmt `. -5. Build/evaluate enough to catch packaging mistakes. For this repo, the extension package is wired by `pkgs.buildPiExtension` in `home/gabriel/features/pi/extensions/default.nix`. - -Avoid one-off extension paths in `~/.pi/agent/settings.json`; use the Nix module so the store path is regenerated by Home Manager. - -## Adding or changing a skill - -Use `home/gabriel/features/pi/skills//SKILL.md`, then add the directory to `home/gabriel/features/pi/skills/default.nix`. - -Skill content should be Gabs/repo-specific. Do not paste generic Pi docs into skills; instead point the model to read Pi docs when API specifics matter. +Skills in this repo should stay Gabs/repo-specific. Do not paste generic Pi docs into skills; point the agent to read the docs when API details matter. Good skill material: -- local file paths and ownership -- build/test commands for this repo -- Pi-authoring-specific workflow ordering -- gotchas discovered while dogfooding this Nix-managed Pi setup +- workflow ordering +- local gotchas +- repo-specific verification commands +- decisions that are not obvious from copying nearby Nix Bad skill material: -- copied ExtensionAPI reference -- copied TUI component docs -- generic TypeScript tutorials +- copied API reference +- copied TUI docs +- generic TypeScript/Nix tutorials +- directory maps that duplicate what the Nix files already show -## Avoid duplicating global rules +## Reloading -Do not restate rules from `home/gabriel/features/pi/context.md` or other skills here. For VCS work, load `jujutsu`; for harness identity, commit trailers, and push policy, follow the context file. - -This skill should only carry Pi-authoring-specific local knowledge: where persistent files live, how Gabs packages extensions, and what to verify before calling the wiring done. - -## Rebuilding - -See repo's `AGENTS.md` for testing/building/deployment info. - -## Reloading and testing - -After NixOS/home-manager applies the config, Pi sees extension and skill paths from generated settings. During active Pi sessions, use `/reload` to reload extensions, skills, prompts, and themes after the underlying files are available. - -For quick local API experiments, writing to `~/.pi/agent` is fine, but convert successful experiments into the Nix-managed `gabs-extensions` package before calling them done. +After Home Manager applies config, active Pi sessions may need `/reload` to pick up changed extensions, skills, prompts, or themes. diff --git a/overlays/default.nix b/overlays/default.nix index 14862271..7751a2f2 100644 --- a/overlays/default.nix +++ b/overlays/default.nix @@ -118,8 +118,6 @@ in { }); }); - buildPiExtension = final.buildPiPackage; - buildPiPackage = let inherit (final) lib buildNpmPackage jq stdenvNoCC; fakeSha512 = lib.convertHash {