Pi ↔ Nix syntax conversions (this repo)
SkillDev toolsMaps Pi packages, extensions, and skills to this repository's Nix ownership. Use when converting between Pi setup instructions and declarative dotfiles.
Available today. Use it from your connected AI after setup.
No other account needed.
Connect ahel once, and every AI you use reads what you have installed.
Then ask your AI: use the Pi ↔ Nix syntax conversions (this repo) skill
What this skill tells your AI
The instructions your AI receives, as published by edmundmiller/dotfiles in .agents/skills/pi-nix-syntax/SKILL.md and read by ahel’s review.
This repo intentionally splits responsibilities:
- Pi packages + extensions live in:
config/pi/settings.jsonc(rendered to~/.pi/agent/settings.json). - Local Pi extensions live in:
config/pi/extensions/*.tsand are linked into~/.pi/agent/extensions/by Nix. - Shared skills are not loaded via Pi
packages[].skills; they are installed via agent-skills-nix (child flakeskills/). Package-native skills remain an explicit exception.
If you see skills collisions, it usually means skills were enabled both ways.
Canonical mapping
1) Pi settings.jsonc packages → stays Pi syntax (no Nix rewrite)
If the thing you’re converting is a Pi packages entry like:
{
"source": "git:github.com/tmustier/pi-extensions",
"extensions": ["tab-status/tab-status.ts"],
"skills": [],
}
…then in this repo it should generally remain a config/pi/settings.jsonc entry.
Nix only ensures the file gets placed at ~/.pi/agent/settings.json.
2) Local extension file → Nix home.file symlink
Pi-style: “I want this TS file to be a Pi extension.”
Nix-style (this repo):
- Put code in:
config/pi/extensions/<name>.ts
- Link it into Pi extensions dir via:
modules/agents/pi/default.nix→home-manager.users.<user>.home.file.".pi/agent/extensions/<name>.ts".source = "${configDir}/pi/extensions/<name>.ts";
Rule: anything under ~/.pi/agent/extensions/*.ts must default-export a factory.
3) Pi skills → agent-skills-nix catalog
Do not use config/pi/settings.jsonc packages[].skills for shared skills that
agent-skills-nix manages. Preserve intentionally package-native resources, such
as pi-amplike's bundled session-query skill, unless they collide with a
catalog-managed copy.
Instead:
- Shared/global skills: add
skills/catalog/<skill-name>/SKILL.md.- auto-enabled in
skills/flake.nixwithskills.enableAll = [ "catalog" ]; - installed into the harness-neutral
~/.agents/skills/target.
- auto-enabled in
- Dotfiles-only project skills: add
.agents/skills/<skill-name>/SKILL.md.- discovered only while working in this repository; never deploy them into the global catalog.
- Remote/pinned skills: add to
skills/flake.nix:- declare
inputs.<src> = { url = "..."; flake = false; }; programs.agent-skills.sources.<src> = { path = inputs.<src>.outPath; ... }programs.agent-skills.skills.explicit.<skillId> = { from = "<src>"; path = "..."; }- for a Pi-only skill, use
programs.dotfiles-agent-skills.targetedExplicit.<skillId>withmeta.targets = [ "pi" ];
- declare
After changing a remote input, update the child lock and then synchronize the parent lock through the guarded repository command:
cd skills && nix flake lock --update-input <src>
cd .. && hey skills-sync
Rule: avoid nested-symlink collisions by flattening nested IDs (example: skill-creator instead of extending-pi/skill-creator).
Conversions
Pi → Nix (how to implement in this repo)
Given a Pi-ish request, classify it:
- Remote extension package (git:, npm:, https:):
- Put/keep it in
config/pi/settings.jsoncunderpackages.
- Local extension (your own
.ts):
- Create
config/pi/extensions/<name>.ts. - Add a
home.filelink inmodules/agents/pi/default.nix.
- Skill (SKILL.md):
- If it should be shared across projects: create
skills/catalog/<name>/SKILL.md. - If it is specific to this dotfiles repository: create
.agents/skills/<name>/SKILL.md. - If remote: pin via
skills/flake.nix(child flake) and select viaskills.explicit. - Do not add catalog-managed shared skills to Pi package arrays. Preserve deliberate package-native skills when they have no catalog-managed copy.
Nix → Pi (how to express the effective Pi result)
- If Nix is linking a file into
~/.pi/agent/extensions/<x>.ts, then the Pi-side view is simply:
- “There exists an extension at
~/.pi/agent/extensions/<x>.ts.” - No
settings.jsonchange required.
- If Nix is generating
~/.pi/agent/settings.jsonfromconfig/pi/settings.jsonc, then the Pi-side view is:
- “My Pi packages list includes …” (copy the JSONC stanza).
- If Nix installs skills via agent-skills-nix, then the Pi-side view is:
- “Shared skills exist on disk in
~/.agents/skills/<name>/SKILL.md.” - “Pi-targeted skills exist on disk in
~/.pi/agent/skills/<name>/SKILL.md.” - They are not sourced from Pi
packages[].skills.
Quick templates
Add a new shared skill
- Path:
skills/catalog/<name>/SKILL.md - Frontmatter must match directory name.
Add a dotfiles-only project skill
- Path:
.agents/skills/<name>/SKILL.md - Frontmatter must match directory name.
Add a new local extension
- Path:
config/pi/extensions/<name>.ts - Must:
export default function (pi: ExtensionAPI) { ... } - Link in
modules/agents/pi/default.nixunderhome.file.
Signals
- GitHub stars
- 80
- Forks
- 6
- Last commit
- Sep 2026
Advanced
- Catalog kind
- skill
- Gateway key
pi-nix-syntax- Source
- github.com/edmundmiller/dotfiles