Larger feature planning for this project happens in an internal repo. If you have access to a local checkout at ~/Development/vibe-program/, read its AGENTS.md and follow the relevant roadmap/execution documents before designing new capabilities; do not redesign decisions made there. Without access, ask the user before planning new feature areas.
When releasing a new tagged version:
- Bump all package versions together and update
CHANGELOG.md.- Root
package.json,packages/extension/package.json, andpackages/bridge/mix.exsversions must match exactly.
- Root
- Run
pnpm run check.- This includes JS checks, BEAM
mix ci, integration tests, changelog release-note validation, Hex/npm package validation, an installed npm artifact smoke, and version alignment.
- This includes JS checks, BEAM
- Commit the bump, tag
vX.Y.Z, and push the commit and tag. - Confirm the Publish GitHub Actions workflow succeeds and publishes:
pi_bridgeand its documentation to Hex/HexDocs.pi-elixirto npm.- The GitHub Release with notes extracted from the matching
CHANGELOG.mdsection.
For local development, start pi with the checkout extension directly:
pnpm dogfoodThis bypasses package discovery and the last published npm package. Use it as the default way to develop pi-elixir with pi-elixir itself. Pass normal pi args directly after the script name, for example:
pnpm dogfood --model openai/gpt-5.5 --thinking high
pnpm dogfood --continue
pnpm dogfood "initial prompt"If you are already inside pi with a new-enough pi-elixir extension loaded, run:
/elixir:dogfood
That installs the current checkout with pi install . and reloads pi.
Optional helpers:
pnpm run dogfood:install # add this checkout to pi package settings
pnpm run dogfood:smoke # non-interactive version smoke; should print current pi_bridge versionIf BEAM status shows offline, call elixir_eval once and check for a version mismatch. A mismatch like “extension expects 0.5.x” means the current TUI is still running an old installed extension instance. If dogfood:smoke returns the current version but the TUI still says offline, investigate the status widget/startup path rather than the bridge itself.
From the repo root, the extension should resolve the nested Mix project at packages/bridge/mix.exs and start embedded stdio there. Manual bridge smoke:
cd packages/bridge
mix run -e 'Pi.Transport.Stdio.start()'pnpm run check is the normal release gate. JS unit tests intentionally exclude packages/extension/test/integration/** for speed; run the integration suite explicitly when touching embedded stdio, MCP HTTP routing, resolver behavior, or fixture-project startup:
pnpm --dir packages/extension run test:integrationNever parse structured source, configuration, metadata, or protocols with regular expressions. Use the canonical parser/decoder or a semantic API for Elixir AST, YAML frontmatter, JSON, versions, Mix project metadata, and wire events. If no parser exists, add a typed boundary or remove the heuristic rather than treating a regex capture as authoritative. Regular expressions remain appropriate for explicitly textual search/filter/render tasks.
When changing extension tool renderers, follow packages/extension/docs/rendering-style.md and compare against built-in tools. Prefer core tool colors (toolOutput, muted, accent, warning, error) over Markdown-only colors for metadata. Use bold mainly for call titles, keep labels muted, URLs/paths as accent, normal result text as tool output, and warnings/errors only for real warning/error states.
Feature flags are defaults-on escape hatches for noisy, sensitive, or experimental environments:
PI_ELIXIR_STATEFUL_EVAL=0— makeelixir_evalstateless.PI_ELIXIR_EVAL_SIDECAR=0— keep eval state in memory only; do not write sidecar snapshots.PI_ELIXIR_LLM=0— disable BEAM-initiatedPi.LLM/Pi.ReqLLMrequests.PI_ELIXIR_SESSIONS=0— disable BEAM session widgets/control affordances.PI_ELIXIR_PLUGINS=0— disable built-in/project-local plugins, hooks, UI events, and commands.PI_ELIXIR_MIRROR=0— disable the built-in QuackDB/DuckDB event mirror.PI_ELIXIR_SKILLS=0— disable executable Elixir skill discovery.PI_ELIXIR_COMPACT_EVAL_PREVIEW=1— force extra-short one-line eval previews.
When adding BEAM-side feature checks, prefer the call-site DSL:
require Pi.Features
Pi.Features.gate :llm do
# feature body
endWhen investigating interactive TUI artifacts, do not run pi as a long unattended foreground command. Use a monitored playground:
- Create a temporary Mix project and depend on the local bridge by path. Prefer a variable for the repository root, not a user-specific absolute path:
export PI_ELIXIR_REPO=$(git rev-parse --show-toplevel)
Or write the resolved path into the temp project's{:pi_bridge, path: System.fetch_env!("PI_ELIXIR_REPO") <> "/packages/bridge", only: :dev}
mix.exsfrom a script using$REPO/packages/bridge. - Run pi inside
tmuxwith an isolated session directory and asciinema recording:REPO=$(git rev-parse --show-toplevel) PI_OFFLINE=1 \ PI_ELIXIR_DEBUG=1 \ PI_CODING_AGENT_SESSION_DIR=/tmp/pi-elixir-smoke-sessions \ asciinema rec -q -c "pi --approve --no-context-files --extension '$REPO/packages/extension/src/index.ts' --tools elixir_eval \"$(cat prompt.txt)\"" /tmp/pi-elixir-smoke.cast
- Poll the tmux pane every few seconds while the scenario runs:
tmux capture-pane -t <session-name> -p -S -80
- After the run, inspect both artifacts:
- The
.castfile for frame-by-frame TUI rendering/ANSI artifacts. - The JSONL file under
PI_CODING_AGENT_SESSION_DIRfor persisted transcript entries.
- The
Expected BEAM session behavior:
- Live/running BEAM session snapshots should be widget-only.
- Completed root session trees should persist as a single
custom_messagewithcustomType: "elixir-sessions". - There should not be repeated live
type: "custom"entries forelixir-sessions. - Complex session trees should show compact status and usage summaries, e.g.
2 done · 1 failed · ↑2.0k ↓400 $0.005.
Useful playground scenarios:
- Parallel children completing at staggered times.
- Nested groups with mixed success/failure/cancelled children.
- Streaming children that emit
recentOutput. - Width-constrained panes to check truncation and branch guide alignment.