If the user did not give you a concrete task in their first message, read README.md, then ask which module(s) to work on. Based on the answer, read the relevant README.md files in parallel.
- packages/ai/README.md
- packages/tui/README.md
- packages/agent/README.md
- packages/coding-agent/README.md
- packages/mom/README.md
- packages/pods/README.md
- packages/web-ui/README.md
- No
anytypes unless absolutely necessary - Check node_modules for external API type definitions instead of guessing
- NEVER use inline imports - no
await import("./foo.js"), noimport("pkg").Typein type positions, no dynamic imports for types. Always use standard top-level imports. - NEVER remove or downgrade code to fix type errors from outdated dependencies; upgrade the dependency instead
- Always ask before removing functionality or code that appears to be intentional
- Never hardcode key checks with, eg.
matchesKey(keyData, "ctrl+x"). All keybindings must be configurable. Add default to matching object (DEFAULT_EDITOR_KEYBINDINGSorDEFAULT_APP_KEYBINDINGS)
- After code changes (not documentation changes):
npm run check(get full output, no tail). Fix all errors, warnings, and infos before committing. - Note:
npm run checkdoes not run tests. - NEVER run:
npm run dev,npm run build,npm test - Only run specific tests if user instructs:
npx tsx ../../node_modules/vitest/dist/cli.js --run test/specific.test.ts - Run tests from the package root, not the repo root.
- When writing tests, run them, identify issues in either the test or implementation, and iterate until fixed.
- NEVER commit unless user asks
When reading issues:
- Always read all comments on the issue
- Use this command to get everything in one call:
gh issue view <number> --json title,body,comments,labels,state
When creating issues:
- Add
pkg:*labels to indicate which package(s) the issue affects- Available labels:
pkg:agent,pkg:ai,pkg:coding-agent,pkg:mom,pkg:pods,pkg:tui,pkg:web-ui
- Available labels:
- If an issue spans multiple packages, add all relevant labels
When closing issues via commit:
- Include
fixes #<number>orcloses #<number>in the commit message - This automatically closes the issue when the commit is merged
- Analyze PRs without pulling locally first
- If the user approves: create a feature branch, pull PR, rebase on main, apply adjustments, commit, merge into main, push, close PR, and leave a comment in the user's tone
- You never open PRs yourself. We work in feature branches until everything is according to the user's requirements, then merge into main, and push.
- GitHub CLI for issues/PRs
- Add package labels to issues/PRs: pkg:agent, pkg:ai, pkg:coding-agent, pkg:mom, pkg:pods, pkg:tui, pkg:web-ui
To test pi's TUI in a controlled terminal environment:
# Create tmux session with specific dimensions
tmux new-session -d -s pi-test -x 80 -y 24
# Start pi from source
tmux send-keys -t pi-test "cd /Users/badlogic/workspaces/pi-mono && ./pi-test.sh" Enter
# Wait for startup, then capture output
sleep 3 && tmux capture-pane -t pi-test -p
# Send input
tmux send-keys -t pi-test "your prompt here" Enter
# Send special keys
tmux send-keys -t pi-test Escape
tmux send-keys -t pi-test C-o # ctrl+o
# Cleanup
tmux kill-session -t pi-test- Keep answers short and concise
- No emojis in commits, issues, PR comments, or code
- No fluff or cheerful filler text
- Technical prose only, be kind but direct (e.g., "Thanks @user" not "Thanks so much @user!")
Location: packages/*/CHANGELOG.md (each package has its own)
Use these sections under ## [Unreleased]:
### Breaking Changes- API changes requiring migration### Added- New features### Changed- Changes to existing functionality### Fixed- Bug fixes### Removed- Removed features
- Before adding entries, read the full
[Unreleased]section to see which subsections already exist - New entries ALWAYS go under
## [Unreleased]section - Append to existing subsections (e.g.,
### Fixed), do not create duplicates - NEVER modify already-released version sections (e.g.,
## [0.12.2]) - Each version section is immutable once released
- Internal changes (from issues):
Fixed foo bar ([#123](https://github.com/badlogic/pi-mono/issues/123)) - External contributions:
Added feature X ([#456](https://github.com/badlogic/pi-mono/pull/456) by [@username](https://github.com/username))
Adding a new provider requires changes across multiple files:
- Add API identifier to
Apitype union (e.g.,"bedrock-converse-stream") - Create options interface extending
StreamOptions - Add mapping to
ApiOptionsMap - Add provider name to
KnownProvidertype union
Create provider file exporting:
stream<Provider>()function returningAssistantMessageEventStream- Message/tool conversion functions
- Response parsing emitting standardized events (
text,tool_call,thinking,usage,stop)
- Import provider's stream function and options type
- Add credential detection in
getEnvApiKey() - Add case in
mapOptionsForApi()forSimpleStreamOptionsmapping - Add provider to
streamFunctionsmap
- Add logic to fetch/parse models from provider source
- Map to standardized
Modelinterface
Add provider to: stream.test.ts, tokens.test.ts, abort.test.ts, empty.test.ts, context-overflow.test.ts, image-limits.test.ts, unicode-surrogate.test.ts, tool-call-without-result.test.ts, image-tool-result.test.ts, total-tokens.test.ts, cross-provider-handoff.test.ts.
For cross-provider-handoff.test.ts, add at least one provider/model pair. If the provider exposes multiple model families (for example GPT and Claude), add at least one pair per family.
For non-standard auth, create utility (e.g., bedrock-utils.ts) with credential detection.
src/core/model-resolver.ts: Add default model ID toDEFAULT_MODELSsrc/cli/args.ts: Add env var documentationREADME.md: Add provider setup instructions
packages/ai/README.md: Add to providers table, document options/auth, add env varspackages/ai/CHANGELOG.md: Add entry under## [Unreleased]
Lockstep versioning: All packages always share the same version number. Every release updates all packages together.
Version semantics (no major releases):
patch: Bug fixes and new featuresminor: API breaking changes
-
Update CHANGELOGs: Ensure all changes since last release are documented in the
[Unreleased]section of each affected package's CHANGELOG.md -
Run release script:
npm run release:patch # Fixes and additions npm run release:minor # API breaking changes
The script handles: version bump, CHANGELOG finalization, commit, tag, publish, and adding new [Unreleased] sections.
- NEVER use sed/cat to read a file or a range of a file. Always use the read tool (use offset + limit for ranged reads).
- You MUST read every file you modify in full before editing.
Multiple agents may work on different files in the same worktree simultaneously. You MUST follow these rules:
- ONLY commit files YOU changed in THIS session
- ALWAYS include
fixes #<number>orcloses #<number>in the commit message when there is a related issue or PR - NEVER use
git add -Aorgit add .- these sweep up changes from other agents - ALWAYS use
git add <specific-file-paths>listing only files you modified - Before committing, run
git statusand verify you are only staging YOUR files - Track which files you created/modified/deleted during the session
These commands can destroy other agents' work:
git reset --hard- destroys uncommitted changesgit checkout .- destroys uncommitted changesgit clean -fd- deletes untracked filesgit stash- stashes ALL changes including other agents' workgit add -A/git add .- stages other agents' uncommitted workgit commit --no-verify- bypasses required checks and is never allowed
# 1. Check status first
git status
# 2. Add ONLY your specific files
git add packages/ai/src/providers/transform-messages.ts
git add packages/ai/CHANGELOG.md
# 3. Commit
git commit -m "fix(ai): description"
# 4. Push (pull --rebase if needed, but NEVER reset/checkout)
git pull --rebase && git push- Resolve conflicts in YOUR files only
- If conflict is in a file you didn't modify, abort and ask the user
- NEVER force push