@devnazim/pi-cmux
cmux notifications and status integration for pi.
Package details
Install @devnazim/pi-cmux from npm and Pi will load the resources declared by the package manifest.
$ pi install npm:@devnazim/pi-cmux- Package
@devnazim/pi-cmux- Version
0.1.0- Published
- May 21, 2026
- Downloads
- not available
- Author
- devnazim
- License
- MIT
- Types
- extension
- Size
- 21.9 KB
- Dependencies
- 0 dependencies · 1 peer
Pi manifest JSON
{
"extensions": [
"./src/index.ts"
]
}Security note
Pi packages can execute code and influence agent behavior. Review the source before installing third-party packages.
README
pi-cmux
cmux notifications and status integration for pi.
pi-cmux is a standalone pi extension/package. It sends generic pi lifecycle updates to cmux and exposes an optional in-process notifier API that other pi extensions can use for semantic notifications.
Package name: @devnazim/pi-cmux.
Install
After publishing to npm:
pi install npm:@devnazim/pi-cmux
From a local checkout:
pi install /path/to/pi-cmux
Or try without installing:
pi -e /path/to/pi-cmux
What it does
| pi event | cmux action |
|---|---|
| Agent starts | mark the active cmux surface as running (surface.report_shell_state) |
| Agent ends with no queued messages | desktop notification (including session name when set) + mark surface as prompt/idle |
| Agent ends with queued messages | keep/report the active surface as running |
| Session shuts down/reloads | mark surface as prompt/idle |
| Optional extension notification | popup/status/log best-effort, controlled by the caller |
All cmux calls are best-effort. If cmux is unavailable or a command fails, pi continues normally.
cmux, SSH, and tmux behavior
pi-cmux detects cmux with:
CMUX_WORKSPACE_ID- any non-empty
CMUX_SOCKET_PATH(including remote relay values like127.0.0.1:<port>) /tmp/cmux.sockas a final fallback
It resolves the cmux CLI with CMUX_BUNDLED_CLI_PATH, falling back to cmux on PATH.
For SSH/tmux/surface-aware notifications, it targets the active cmux surface when either env var exists:
CMUX_SURFACE_IDCMUX_PANEL_ID
When a surface is available, notifications use:
cmux rpc notification.create_for_surface '{"surface_id":"...","title":"..."}'
Otherwise they fall back to:
cmux rpc notification.create '{"title":"..."}'
If TMUX_PANE is set, pi-cmux asks tmux for a readable pane label and prefixes notification bodies with it, e.g. [dev:1 %2] Ready for input. If tmux lookup fails, it falls back to the raw pane id.
This avoids terminal OSC notifications and works through SSH/tmux when the cmux shell integration exposes the needed env/socket/CLI access in the remote environment. Without that cmux environment, the extension silently no-ops.
Current cmux builds expose notifications and surface shell-state RPCs, but may not expose older set-status, clear-status, or log CLI commands. pi-cmux uses the shell-state RPC for surface activity, probes cmux --help before calling optional legacy status/log commands, and keeps legacy status calls off the critical agent lifecycle path.
Configuration
Create ~/.config/pi-cmux/config.json or set PI_CMUX_CONFIG to another path.
{
"notifications": {
"done": true,
"error": true,
"xplan": true
},
"status": true,
"logs": true
}
| Option | Default | Description |
|---|---|---|
notifications.done |
true |
Show generic “Pi done” notifications. |
notifications.error |
true |
Allow error-level popup notifications from optional callers. |
notifications.xplan |
true |
Allow popup notifications from source: "xplan". |
status |
true |
Report active cmux surface activity, or use supported legacy status commands when available. |
logs |
true |
Write cmux log entries when the installed cmux CLI exposes cmux log; otherwise no-op. |
Malformed or omitted values fall back to defaults.
Optional notifier API
Other extensions can request cmux notifications without importing or depending on pi-cmux:
const notify = (globalThis as any)[Symbol.for("pi.cmux.notify.v1")];
if (typeof notify === "function") {
await notify({
source: "xplan",
type: "step_ready",
title: "xplan step ready",
body: "S2 is ready for review",
level: "success",
status: { key: "xplan", text: "review", icon: "check", color: "#22c55e" },
});
}
If pi-cmux is not installed, the symbol is absent. Callers should treat notifications as optional and never require them for workflow state.
Supported payload fields:
title— required notification titlesubtitle,body— optional body parts, joined with—source— log/status source, e.g.xplantype— caller-defined event typelevel—info,success,warning,error, orwarnnotify: false— skip popup notificationlog: false— skip cmux log entrystatus— optional keyed status set/clear request; used only when the installed cmux CLI supports legacy status commands
Development
npm install
npm test
npm run check
The implementation no-ops outside cmux, targets notifications to the active surface when possible, adds tmux pane labels and pi session names for disambiguation, probes optional legacy commands before using them, keeps legacy status calls best-effort in the background, and executes commands without shell interpolation.