8.5 KiB
Allium → Pi.dev Port Plan
Goal
Port allium (https://github.com/juxt/allium) to pi.dev, keeping upstream files by reference where possible. Test with the turn-limit extension (https://gitea.apps.sustainabledelivery.com/QWAN/monotonic-pi-extensions).
Directory layout
pi-allium/ ← this repo
├── allium-main/ ← git clone of juxt/allium (submodule or checkout)
├── turn-limit/ ← checkout of monotonic-pi-extensions/packages/pi-turn-limit
├── .pi/
│ └── skills/
│ ├── allium/ ← root skill (entry point, routing table)
│ │ ├── SKILL.md ← adapted frontmatter + symlink or include of upstream content
│ │ └── references/ ← symlinks to allium-main/references/*
│ ├── elicit/
│ │ ├── SKILL.md
│ │ └── references/ ← symlinks to allium-main/skills/elicit/references/*
│ ├── distill/
│ │ ├── SKILL.md
│ │ └── references/ ← symlinks to allium-main/skills/distill/references/*
│ └── propagate/
│ ├── SKILL.md
│ └── references/ ← (upstream has none currently)
├── allium-port-plan.md ← this file
└── learning-goal.md ← goal card
Key differences: Claude Code plugin vs Pi skill
| Aspect | Claude Code | Pi.dev |
|---|---|---|
| Skill location | .claude-plugin/ + skills/ |
.pi/skills/{name}/SKILL.md |
| Frontmatter | name, description, version, auto_trigger |
name, description, disable-model-invocation, license, metadata |
| References dir | resources/ or references/ |
references/ |
| Agents | .claude/agents/{name}.md with model:, tools: |
No native agent support — needs extension or workaround |
| Hooks | .claude/settings.json → PostToolUse hooks |
Not directly supported — needs extension |
| Rules | .claude/rules/*.md with globs: |
No equivalent — content goes into SKILL.md or references |
| Auto-trigger | auto_trigger: file_patterns, keywords |
disable-model-invocation: true/false |
| Invocation | /allium, /allium:elicit |
/skill:allium, /skill:elicit |
Phases
Phase 1: Setup and smoke test
Goal: get the root /skill:allium working in pi with a local model.
- Clone allium upstream into
allium-main/cd ~/research/pi-allium git clone https://github.com/juxt/allium.git allium-main - Create
.pi/skills/allium/SKILL.mdwith pi-compatible frontmatter- Source:
allium-main/skills/allium/SKILL.md - Change: add
disable-model-invocation: true,license: MIT,metadatablock - Change: update routing table to use
/skill:elicit,/skill:distill,/skill:propagateinstead of Claude skill/agent references - Change: update reference paths from
../../references/toreferences/ - Keep: the full language reference body
- Source:
- Symlink references:
ln -s ../../../allium-main/references .pi/skills/allium/references - Smoke test:
pi -pin this directory, invoke/skill:allium, verify it loads and responds with the routing table - Verify references load: ask allium about language syntax, confirm it can read
references/language-reference.md
Phase 2: Port elicit, distill, propagate skills
Goal: all three sub-skills work via /skill:elicit etc.
- Create
.pi/skills/elicit/SKILL.md— adapt frontmatter fromallium-main/skills/elicit/SKILL.md - Symlink references: individual symlinks in
.pi/skills/elicit/references/(language-reference.md + library-spec-signals.md) - Smoke test
/skill:elicit— start a mini elicitation session, verify it follows the methodology - Create
.pi/skills/distill/SKILL.md— adapt frontmatter fromallium-main/skills/distill/SKILL.md - Symlink references: individual symlinks in
.pi/skills/distill/references/(language-reference.md + worked-examples.md) - Smoke test
/skill:distill - Create
.pi/skills/propagate/SKILL.md— adapt frontmatter fromallium-main/skills/propagate/SKILL.md - Smoke test
/skill:propagate
Phase 3: Test with turn-limit extension (TDD)
Goal: use distill → propagate on real code, verify allium produces useful output.
- Checkout turn-limit into this workspace
git clone https://gitea.apps.sustainabledelivery.com/QWAN/monotonic-pi-extensions.git turn-limit-repo ln -s turn-limit-repo/packages/pi-turn-limit turn-limit - Run
/skill:distillagainstturn-limit/— extract a.alliumspec from existing code - Review the generated spec: does it capture turn-limit constraints, enable/disable, UI separation?
- Run
/skill:propagateagainst the generated spec — generate test suggestions - Write at least one test based on propagate output (TDD red step)
- Implement to make the test pass (green step)
- Iterate: use allium to identify more test obligations, write them, make them pass
- Run
/skill:elicitto explore the "disable turn limit" feature requirement - Generate spec + tests for the new feature via propagate
Phase 4: Fold in allium rules content
Goal: pi agent knows allium syntax rules when editing .allium files.
- Merge content from
allium-main/.claude/rules/allium.mdintoSKILL.mdor a reference file- This contains syntax gotchas and anti-patterns that the model needs when writing .allium files
- In Claude Code this auto-triggers on
**/*.alliumglobs — in pi we need it in the skill context
- Test: create/edit a
.alliumfile via pi, verify the model follows naming conventions and avoids anti-patterns
Phase 5: Agent support (tend & weed)
Goal: find a way to support tend/weed agent functionality in pi.
Tend and weed are Claude Code agents with model: opus and specific tool permissions (Read, Glob, Grep, Edit, Write, Bash). Pi doesn't have native agent support.
Options to investigate:
- Option A: Skills as agents — port tend.md and weed.md as skills with
disable-model-invocation: true. The model won't have enforced tool restrictions but the skill prompt still guides behavior. Simplest path. - Option B: Pi extension (TypeScript) — write a TypeScript extension that registers
/tendand/weedcommands, controlling context injection. More control, more work. - Option C: npm agents package — check if pi.dev has an agents extension or if one exists on npm (
npx skillsecosystem). Check https://pi.dev/docs and https://github.com/nicepkg/agent-skills. - Decide on approach and implement
- Test: use tend to modify a
.alliumspec, verify it follows allium conventions - Test: use weed to check spec-code alignment on the turn-limit extension
Phase 6: Hook support (allium-check validation)
Goal: .allium files get validated on write.
The Claude Code version runs allium-check.mjs as a PostToolUse hook on Edit/Write.
- Investigate pi.dev hook/extension support for post-write validation
- If supported: configure the hook pointing to
allium-main/.claude/hooks/allium-check.mjs - If not: add validation instructions to the skill prompt ("after writing .allium files, run
node allium-check.mjs <file>") - Test: write a
.alliumfile with deliberate errors, verify validation catches them
Phase 7: Documentation and upstream
Goal: publishable result.
- Add README.md with attribution (MIT license from JUXT)
- Add LICENSE
- Document the symlink-based approach for staying in sync with upstream
- Document known limitations vs Claude Code version
- Write blog post draft (separate file)
- Share with allium team and pi.dev community
Key URLs
- Allium upstream: https://github.com/juxt/allium
- Allium docs: https://juxt.github.io/allium/
- Allium installation: https://juxt.github.io/allium/installation
- Turn-limit extension: https://gitea.apps.sustainabledelivery.com/QWAN/monotonic-pi-extensions
- Pi.dev: https://pi.dev
- Local allium cache (current):
~/.claude/plugins/cache/juxt-plugins/allium/f6fb08dd301f/
Notes for the agent on the other machine
- Pi is invoked with
pi -pto load project skills from.pi/skills/ - Default model:
qwen3.5:35b-a3bvia Ollama on192.168.0.1:11434 - Skills are invoked with
/skill:name(requiresenableSkillCommands: truein pi settings if not already set) - Symlinks must resolve on the target machine — clone allium-main in the same relative position
- The
.alliumlanguage version is 3 (checkallium-main/VERSION)