pi-extmgr0.4.1
Enhanced UX for managing local Pi extensions and community packages
Untested on omp
This is a pi package. No one has reported whether it works on omp yet. If you try it, add your result below.
Reports 0
No reports yet.
Readme
pi-extmgr

A better way to manage Pi extensions. Browse, install, enable/disable, and remove extensions from one place. Built on top of Pi's native package install, update, and config flows, so extmgr stays aligned with current upstream behavior.
Install
pi install npm:pi-extmgr
Or install straight from GitHub:
pi install git:github.com/ayagmar/pi-extmgr
If Pi is already running, use /reload.
Requires Pi >=1.0.1 and Node.js >=22.19.0. Use pi-extmgr 0.3.x with older Pi releases.
Update it with pi update npm:pi-extmgr or pi update --extensions (a bare pi update only updates Pi itself).
Project-scoped installs (pi install npm:pi-extmgr -l) need the project to be trusted.
Where packages live
Pi installs global npm packages into its own managed root, ~/.pi/agent/npm (or $PI_CODING_AGENT_DIR/npm),
and project packages into .pi/npm. No global npm prefix is involved, so an unwritable npm_config_prefix
no longer matters. extmgr reads the same locations. If npm needs a specific Node version or you want a
different package manager, set Pi's npmCommand setting.
npmCommand examples for ~/.pi/agent/settings.json:
{
// mise: run npm through Node 22
// "npmCommand": ["mise", "exec", "node@22", "--", "npm"]
// bun: use Bun as Pi's package-manager command
// "npmCommand": ["bun"]
// nvm: start Pi from an nvm-enabled shell and use npm on PATH
// "npmCommand": ["npm"]
}
Features
- Unified manager UI
- Local extensions (
~/.pi/agent/extensions, plus.pi/extensionsin trusted projects) and installed packages in one list - Grouped sections for local extensions vs installed packages
- Responsive master/detail layout on wide terminals, with a compact stacked fallback on narrow terminals
- Focused primary filters and contextual one-line controls; secondary actions remain available through the command palette and help
- Built-in search and filter shortcuts for large extension sets
- Scope indicators (global/project), status indicators, update badges, and package sizes when known
- Local extensions (
- Package extension configuration panel
- Configure individual extension entrypoints inside an installed package (
con package row) - Works with manifest-declared entrypoints and conventional
extensions/package layouts - Persists to package filters in
settings.json(no manual JSON editing)
- Configure individual extension entrypoints inside an installed package (
- Safe staged local extension toggles
- Toggle with
Space, apply withS - Unsaved-change guard when leaving (save/discard/stay)
- Toggle with
- Package management
- Install, update, remove from UI and command line
- Quick actions (
A,u,X) and coordinated bulk package actions (B)
- Remote discovery and install
- npm search/browse with server-side pagination, inline browse search, keyboard page navigation, and rate-limit-aware retries
- Weekly npm downloads in browse rows/details plus popularity sorting (
ocycles sort modes) - Path- and git-like queries are handled explicitly instead of surfacing unrelated npm results
- Install by source (
npm:,git:,https://,ssh://,git@..., local path) - Supports direct GitHub
.tsinstalls and standalone local install for self-contained packages - Search results render immediately; weekly download metrics hydrate in the background and update the visible rows
- Long-running discovery/detail screens now show dedicated loading UI, and cancellable reads can be aborted with
Esc
- Scheduled update checks
- Interactive wizard (
tin manager, or/extensions auto-update) - Persistent schedule restored on startup and session switch
- Background checks + status bar updates for installed npm + git packages
- Interactive wizard (
- Task-oriented workspaces
- Installed: local extensions, packages, updates, and staged changes
- Discover: community npm search, package inspection, downloads, and popularity sorting
- Profiles: inline current-vs-target diffs (scope, version, ref, filters, checksum); applying always passes through the review screen
- Health: runtime conflicts, compatibility, reload state, recoverable trash, conflict remediation, and a conservative “fix all safe issues” action (never removes packages)
- Operational visibility
- Session history (
/extensions history) - Cache controls (
/extensions clear-cacheclears persistent + runtime extmgr caches) - Status line summary (
pkg count • scheduled update checks • known updates) - History now records local extension deletions and scheduled update checks configuration changes
- Session history (
- Overlay-first output
- Help, item details, bulk summaries, doctor, history, trash lists, and profile check/import reports open in a floating scrollable panel instead of the chat transcript
- Reference peeks (help, details) float beside the list; standalone reports (doctor, history, summaries) center on screen
- Package updates show progress in a corner overlay while the session stays visible
- A one-line attention widget above the editor appears when updates are known or a reload is pending, and clears once handled
- The terminal title reflects the active workspace while the manager is open
- Interactive + non-interactive support
- Works in TUI and non-UI modes
- Non-UI modes receive the same report content as plain notifications
- Non-interactive commands for list/install/remove/update/scheduled update checks (checks discover updates; package updates remain explicit)
Usage
Open the manager:
/extensions
Or press Ctrl+Alt+E from anywhere in the pi TUI.
In the manager
| Key | Action |
|---|---|
Tab / Shift+Tab |
Next / previous workspace: Installed / Discover / Profiles / Health |
↑↓ |
Navigate |
PageUp/Down |
Jump through longer lists |
Home/End |
Jump to top or bottom |
Space |
Toggle selected local extension on/off |
S |
Save local extension changes |
Enter / A |
Actions on selected item |
/ / Ctrl+F |
Search visible items |
1-7 |
Filter: All / Local / Packages / Updates / Disabled / Favorites / Recent |
c |
Configure selected package extensions |
u |
Update selected package directly |
V |
View full details for selected item |
X |
Remove selected item (package/local extension) |
i |
Quick install by source |
f |
Remote package search |
B |
Bulk actions for selected packages |
W / L / D |
Save / load / delete manager views |
* |
Toggle favorite for selected item |
U |
Update all packages |
t |
Scheduled update checks wizard |
P / M |
Workspace screens and actions |
R |
Browse remote packages |
? / H |
Help |
Esc |
Clear search or exit |
In Pi's default fullscreen TUI, PageUp/PageDown/Home/End scroll the transcript before the manager
sees them. Use ↑↓, start Pi with --tui-mode regular, or rebind tui.altScreen.pageUp,
tui.altScreen.pageDown, tui.altScreen.top and tui.altScreen.bottom in keybindings.json.
Report panels (help, details, doctor, history) are overlays and keep these keys.
Commands
/extensions # Open interactive manager (default)
/extensions local # Alias: open interactive manager
/extensions list # List local extensions
/extensions remote # Open remote package browser
/extensions packages # Alias: remote browser
/extensions installed # Installed packages view (legacy alias to unified flow)
/extensions search <query> # Search npm packages
/extensions install <source> [--project|--global] # Install package
/extensions remove [source] # Remove package
/extensions uninstall [source] # Alias: remove
/extensions update [source] # Update one package (or all when omitted)
/extensions auto-update [every] # No arg opens wizard in UI; accepts 1d, 1w, 1mo, daily, weekly, monthly, never, etc.
/extensions doctor # Inspect ownership and package compatibility
/extensions profile list # List named profiles
/extensions profile save <name> [--force] # Save the current package profile
/extensions profile export <path> # Export; refuses to overwrite an existing file
/extensions profile apply <name|path> # Safely apply a profile
/extensions profile rename <from> <to> # Rename a named profile
/extensions profile duplicate <from> <to> # Duplicate a named profile
/extensions profile delete <name> # Delete a named profile
/extensions trash <list|restore|purge> # Manage local extension trash
/extensions history [options] # View change history (supports filters)
/extensions clear-cache # Clear persistent + runtime extmgr caches
Non-interactive mode
When Pi is running without UI, extmgr still supports command-driven workflows:
/extensions list/extensions installed/extensions install <source> [--project|--global]/extensions remove <source>/extensions update [source]/extensions history [options]/extensions auto-update <duration>- Use
1mofor monthly schedules (/extensions history --since <duration>also accepts1mo;30m/24hare just lookback examples)
- Use
Remote browsing/search menus require the full interactive TUI.
RPC / limited-UI mode
In RPC mode, dialog-based commands still work, but the custom TUI panels do not:
/extensionsfalls back to read-only local/package lists/extensions installedlists packages directly- remote browsing/search panels require the full interactive TUI
- package extension configuration requires the full interactive TUI
History options (works in non-interactive mode too):
--limit <n>--action <extension_toggle|extension_delete|package_install|package_update|package_remove|cache_clear|auto_update_config>--success/--failed--package <query>--since <duration>(e.g.30m,24h,7d,1mo;1mois supported for monthly lookbacks)--global(non-interactive mode only; reads all persisted sessions under~/.pi/agent/sessions)
Examples:
/extensions history --failed --limit 50/extensions history --action package_update --since 7d/extensions history --global --package extmgr --since 1mo
Install sources
/extensions install npm:package-name
/extensions install @scope/package
/extensions install git:https://github.com/user/repo.git
/extensions install git:git@github.com:user/repo.git
/extensions install ssh://git@github.com/user/repo.git
/extensions install https://github.com/user/repo/blob/main/extension.ts
/extensions install /path/to/extension.ts
/extensions install ./local-folder/
Whole-package enable/disable
Select a package and choose Disable package (or use B for bulk actions) to disable its extensions, skills, prompts, and themes together, without uninstalling it. Enable package restores the previous filters, including intentional exclusions. Configure package extensions remains extension-only; enable the package before editing.
Disabled packages show as package disabled in the Installed list and under the Disabled filter.
Changes apply to the selected scope. A project entry replaces a global entry for the same
package, except a project entry with autoload: false, which adds its explicit patterns on
top of the global one: disabling the global entry does not switch those resources off.
Reload and start a fresh session to avoid previously read skill instructions remaining
in context. Independently loaded copies and already-applied side effects are unaffected.
The prior configuration is saved in piExtmgrDisabled on the package settings entry.
Invalid snapshots are rejected rather than overwritten. If the package's filters were edited
after it was disabled, the single-package Enable/Disable action offers to discard the saved
configuration and keep the current filters.
Packages whose extensions were all disabled by an earlier extmgr version have no saved
configuration; Enable package re-enables their extensions as before. Other existing
extension-only exclusions (including Superpowers exclusions) are preserved, not migrated.
Tips
- Staged local changes: Toggle local extensions on/off, then press
Sto apply all at once. - Package extension config: Select a package and press
c(or Enter/A → Configure) to enable/disable individual extension entrypoints only; skills, prompts, and themes are unchanged.- After saving package extension config, run /reload to apply changes.
- Two install modes:
- Managed (npm/git): installed by Pi's package manager into
~/.pi/agent/npm/~/.pi/agent/git(project scope:.pi/npm/.pi/git), updated from extmgr or withpi update --extensions, supports Pi package manifest/convention loading - Local (standalone): Copies to
~/.pi/agent/extensions/{package}/, so it only accepts runnable standalone layouts (manifest-declared/root entrypoints), requirestaronPATH, and rejects packages whose runtimedependenciesare not already bundled with the package contents
- Managed (npm/git): installed by Pi's package manager into
- Scheduled update-check schedule is persistent:
/extensions auto-update 1dstays active across future Pi sessions and is restored when switching sessions. - Scheduled update-check badges cover npm + git packages: extmgr now uses pi's package manager APIs for structured update detection instead of parsing
pi listoutput. - Settings/cache writes are hardened: extmgr serializes writes and uses safe file replacement to reduce JSON corruption issues.
- Invalid JSON is handled safely: malformed
auto-update.json/ metadata cache files are backed up and reset; invalid.pi/settings.jsonis not overwritten during package-extension toggles. - Reload is built-in: When extmgr asks to reload, it calls
ctx.reload()directly. Successful mutations persist a versioned reload-required marker; cancellation and failure do not. The marker survives reopening the manager and clears after a successful reload. - Saved manager state: Views, favorites, recent items, and bulk selections are stored atomically in
~/.pi/agent/.extmgr-cache/views-<project>.json. Named profiles are stored inprofiles.json; project policies load from.pi/extmgr-policy.json. - Trash lifecycle: Local removals move to
~/.pi/agent/.extmgr-trash/with persistent records. Undo refuses to overwrite a replacement file, and expired or missing records are cleaned up. - Metadata safety: Missing compatibility, provenance, checksum, or target-version metadata is reported as
unknown, neversafe. Target-version previews, exact target badges, and update-policy/maintenance-window enforcement are intentionally deferred because Pi does not expose structured target metadata.
Releasing
Releases are cut from GitHub Actions — never from a laptop.
- Merge Conventional Commits (
feat:,fix:,feat!:…) intomaster. - Run Actions → Release → Run workflow (or
gh workflow run release.yml -f increment=auto).autoderives the bump from the commits; pickpatch/minor/majorto override. Tickdry_runto preview. - The workflow runs
pnpm run check, then release-it bumpspackage.json, updatesCHANGELOG.md, tagsvX.Y.Z, pushes and creates the GitHub release, and finallynpm publishpublishes with provenance through npm trusted publishing (OIDC — no npm token stored in the repo).
Preview locally with pnpm release:dry.
Before the first release from this workflow, configure trusted publishing on npmjs.com for
pi-extmgr (GitHub Actions · ayagmar/pi-extmgr · workflow release.yml); the package already
exists on npm, so no bootstrap run is needed. If a run already tagged and created the GitHub
release but failed at npm publish, re-run it with publish_only: true instead of cutting a new
version.
License
MIT