{"_id":"@capyup/pi-warp","_rev":"3-7fbe742adb58c6c8395bcd052aedf5d5","name":"@capyup/pi-warp","dist-tags":{"latest":"0.1.2"},"versions":{"0.1.0":{"name":"@capyup/pi-warp","version":"0.1.0","keywords":["pi-package","pi","pi-extension","warp","terminal","cli-agent"],"author":{"name":"capyup"},"license":"MIT","_id":"@capyup/pi-warp@0.1.0","maintainers":[{"name":"capyup","email":"lucas@knowecon.com"}],"homepage":"https://github.com/lulucatdev/pi-warp#readme","bugs":{"url":"https://github.com/lulucatdev/pi-warp/issues"},"pi":{"extensions":["./extensions/warp-integration.ts"]},"dist":{"shasum":"1b087623ea9fb9ba83d88e95dd6b2669c209602c","tarball":"https://registry.npmjs.org/@capyup/pi-warp/-/pi-warp-0.1.0.tgz","fileCount":4,"integrity":"sha512-+7didCI2guAFu8Q0MMfLohreB98ZXtf0YMuXeX0LP5isKQKtsau8CdzIAZ9gDg5RdZUX4kUGWycbvfDIiam6Fw==","signatures":[{"sig":"MEQCIHcsqE6myjcb3N4F73Fr9i9RNHtTeV8xEs3w/cX8/RlGAiBqiK8stqTEwtXc3zHDg1RIk/ldcKVIwC0Py54T6PAmbQ==","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":18328},"type":"module","gitHead":"8c3579bd9ebcd8644f8c7a0e77a82369cd0e44f7","_npmUser":{"name":"capyup","email":"lucas@knowecon.com"},"repository":{"url":"git+https://github.com/lulucatdev/pi-warp.git","type":"git"},"_npmVersion":"11.12.1","description":"Warp terminal integration for Pi — tab status, spinner, and rich session notifications via the warp://cli-agent protocol.","directories":{},"_nodeVersion":"25.9.0","publishConfig":{"access":"public"},"_hasShrinkwrap":false,"devDependencies":{"vitest":"^4.1.5","typescript":"^5.8.0","@types/node":"^25.6.2"},"peerDependencies":{"@earendil-works/pi-coding-agent":"*"},"_npmOperationalInternal":{"tmp":"tmp/pi-warp_0.1.0_1778294475635_0.4800587543055581","host":"s3://npm-registry-packages-npm-production"}},"0.1.1":{"name":"@capyup/pi-warp","version":"0.1.1","keywords":["pi-package","pi","pi-extension","warp","terminal","cli-agent"],"author":{"name":"capyup"},"license":"MIT","_id":"@capyup/pi-warp@0.1.1","maintainers":[{"name":"capyup","email":"lucas@knowecon.com"}],"homepage":"https://github.com/capyup/pi-warp#readme","bugs":{"url":"https://github.com/capyup/pi-warp/issues"},"pi":{"extensions":["./extensions/warp-integration.ts"]},"dist":{"shasum":"e4904f20a4081dec5f185759599a32b5d558454b","tarball":"https://registry.npmjs.org/@capyup/pi-warp/-/pi-warp-0.1.1.tgz","fileCount":4,"integrity":"sha512-bdgAPzIGJlXpeFeiW4TdAQSliMVqb04vej3+hKAdEmK3wvEfUw6Li1iZQEzQtvyFSR42gqXALb6JXQXWP9zT2Q==","signatures":[{"sig":"MEUCIQC/TOXfCmpcQYP+PTHsZCymC4Uh8BkkEweabXUGUmxi9QIgPr2ugRbZddZOe/YWG7Zxdutaul/CtShNRly6ZZ+AyTA=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":18320},"type":"module","gitHead":"5c881d63e63a4c29b925e4fe9953b053ef387c23","_npmUser":{"name":"capyup","email":"lucas@knowecon.com"},"repository":{"url":"git+https://github.com/capyup/pi-warp.git","type":"git"},"_npmVersion":"11.12.1","description":"Warp terminal integration for Pi — tab status, spinner, and rich session notifications via the warp://cli-agent protocol.","directories":{},"_nodeVersion":"25.9.0","publishConfig":{"access":"public"},"_hasShrinkwrap":false,"devDependencies":{"vitest":"^4.1.5","typescript":"^5.8.0","@types/node":"^25.6.2"},"peerDependencies":{"@earendil-works/pi-coding-agent":"*"},"_npmOperationalInternal":{"tmp":"tmp/pi-warp_0.1.1_1778295480107_0.13168064387587797","host":"s3://npm-registry-packages-npm-production"}},"0.1.2":{"name":"@capyup/pi-warp","version":"0.1.2","description":"Warp terminal integration for Pi — tab status, spinner, and rich session notifications via the warp://cli-agent protocol.","repository":{"type":"git","url":"git+https://github.com/capyup/pi-warp.git"},"author":{"name":"capyup"},"license":"MIT","type":"module","keywords":["pi-package","pi","pi-extension","warp","terminal","cli-agent"],"publishConfig":{"access":"public"},"pi":{"extensions":["./extensions/warp-integration.ts"]},"peerDependencies":{"@earendil-works/pi-coding-agent":"*"},"devDependencies":{"@types/node":"^25.6.2","typescript":"^5.8.0","vitest":"^4.1.5"},"gitHead":"089f0055821d4061edf803b02e3f0a7cf095a616","_id":"@capyup/pi-warp@0.1.2","bugs":{"url":"https://github.com/capyup/pi-warp/issues"},"homepage":"https://github.com/capyup/pi-warp#readme","_nodeVersion":"25.9.0","_npmVersion":"11.12.1","dist":{"integrity":"sha512-DqNo7mKVZbl+c4I8Io9RO451jciLKEGboTWm4UG2MmoDF3i/b5zWq2aXw0Lb0XdIIDS1al47NwRnQwK+kxkAlQ==","shasum":"ec06b4b87a9389bf7355ab06ab6e9e9608ac5d7f","tarball":"https://registry.npmjs.org/@capyup/pi-warp/-/pi-warp-0.1.2.tgz","fileCount":4,"unpackedSize":22441,"signatures":[{"keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U","sig":"MEQCIAJjeQCgJo7J08oD/wkCitwTYrFp6mLfYkkk7bp+yjP/AiBH6IQLoPL0nR021m28rwwMQPaID0zwHp07TTRL9VZTQA=="}]},"_npmUser":{"name":"capyup","email":"lucas@knowecon.com"},"directories":{},"maintainers":[{"name":"capyup","email":"lucas@knowecon.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages-npm-production","tmp":"tmp/pi-warp_0.1.2_1778298617654_0.5118626849070045"},"_hasShrinkwrap":false}},"time":{"created":"2026-05-09T02:41:15.521Z","modified":"2026-05-09T03:50:17.925Z","0.1.0":"2026-05-09T02:41:15.788Z","0.1.1":"2026-05-09T02:58:00.280Z","0.1.2":"2026-05-09T03:50:17.812Z"},"bugs":{"url":"https://github.com/capyup/pi-warp/issues"},"author":{"name":"capyup"},"license":"MIT","homepage":"https://github.com/capyup/pi-warp#readme","keywords":["pi-package","pi","pi-extension","warp","terminal","cli-agent"],"repository":{"type":"git","url":"git+https://github.com/capyup/pi-warp.git"},"description":"Warp terminal integration for Pi — tab status, spinner, and rich session notifications via the warp://cli-agent protocol.","maintainers":[{"name":"capyup","email":"lucas@knowecon.com"}],"readme":"# pi-warp\n\n**Warp terminal integration for [Pi](https://pi.dev)** — real-time tab status, animated spinners, and rich session notifications.\n\nWhen you run Pi inside [Warp](https://www.warp.dev), this extension sends structured lifecycle events so Warp can display the agent's status directly in its sidebar tab:\n\n| Status | Tab indicator | Meaning |\n|---|---|---|\n| InProgress | ● spinner | Agent is thinking or executing tools |\n| Success | ✓ checkmark | Agent turn completed |\n| Blocked | ! exclamation | Agent needs user input (future) |\n\nIt also updates the terminal title with an animated braille spinner while the agent is working, matching the behavior of Codex CLI and Claude Code.\n\n## Install\n\n```bash\n# From npm (recommended)\npi install npm:@capyup/pi-warp\n\n# Or from git\npi install git:github.com/capyup/pi-warp\n```\n\nThat's it — the extension auto-activates when Pi detects a Warp terminal (`TERM_PROGRAM=WarpTerminal`). In non-Warp terminals it does nothing.\n\n## How It Works\n\n### Two-Layer Protocol\n\nModern terminals like Warp integrate with CLI agents through two complementary mechanisms:\n\n#### Layer 1: OSC 0 — Dynamic Terminal Title\n\nStandard escape sequence (`\\x1b]0;title\\x07`) that updates the window/tab title. Pi-warp sets:\n\n- **Working:** `⠋ π session — project` (animated braille spinner)\n- **Ready:** `π session — project` (static, no spinner)\n\nMost terminals display this in their tab bar as a basic activity indicator.\n\n#### Layer 2: OSC 777 — Structured JSON Events (`warp://cli-agent`)\n\nWarp defines a private protocol where CLI agents send structured notifications via OSC 777:\n\n```\nESC ] 777 ; notify ; warp://cli-agent ; {\"v\":1,\"agent\":\"pi\",\"event\":\"stop\",...} BEL\n```\n\nThis gives Warp fine-grained session state: who's running, what they're doing, when they're blocked, and when they're done.\n\n### Events Emitted\n\n| Pi lifecycle event | Warp event | Status transition |\n|---|---|---|\n| `session_start` | `session_start` | Initialize tracking |\n| `agent_start` | `session_start` + `prompt_submit` | Reattach listener, → InProgress |\n| `message_start` (user) | `prompt_submit` | Correct/update query, → InProgress |\n| active turn heartbeat (~15s) | `session_start` + `prompt_submit` | Recover dropped tab state |\n| `tool_result` | `tool_complete` | Tool context update |\n| `agent_end` | `stop` | → Success ✓ |\n| `agent_end` + 300ms | `idle_prompt` | (no change) |\n\n### Event Payload (v1 Schema)\n\n```jsonc\n{\n  \"v\": 1,                              // Protocol version\n  \"agent\": \"pi\",                       // CLIAgent identifier\n  \"event\": \"prompt_submit\",            // Event type\n  \"session_id\": \"a1b2c3d4-...\",        // Stable per-session UUID\n  \"cwd\": \"/Users/you/project\",         // Working directory\n  \"project\": \"project\",                // Project folder name\n  \"query\": \"fix the failing tests\",    // User's prompt (truncated)\n  \"response\": \"Done! All tests pass.\", // Agent's reply (truncated)\n  \"tool_name\": \"bash\",                 // Last tool used\n  \"tool_input\": {\"command\": \"npm test\"},// Tool arguments preview\n  \"plugin_version\": \"0.1.2\"            // Extension version\n}\n```\n\n## Research Background\n\n### How Does Warp Know What CLI Agents Are Doing?\n\nWe reverse-engineered Warp's open-source codebase ([warpdotdev/Warp](https://github.com/warpdotdev/Warp)) and cross-referenced it with Codex CLI ([openai/codex](https://github.com/openai/codex)) and Claude Code to understand the full integration story. Here's what we found.\n\n#### Warp's Architecture\n\nWarp maintains a `CLIAgentSessionsModel` — a per-tab state machine that tracks:\n\n```\nCLIAgentSessionStatus:\n  InProgress  →  the agent is working\n  Success     →  the agent's turn is done\n  Blocked     →  the agent needs user input\n```\n\nIt detects CLI agents by matching the command against known prefixes (`claude`, `codex`, `gemini`, `pi`, `amp`, etc.) and subscribes to their PTY output for event signals.\n\n#### How Codex CLI Integrates\n\nCodex uses **two mechanisms** (neither of which is the structured JSON protocol):\n\n1. **OSC 0 terminal title** — Rich dynamic titles like `⠋ codex - project | Working` that Warp reads as a fallback tab label\n2. **OSC 9 plain-text notifications** — Simple text like `\"Agent turn complete\"` that Warp's `CodexSessionHandler` parses into a Stop event\n\nCodex does *not* send OSC 777 JSON events. Its Warp integration is lower-fidelity — all OSC 9 notifications are treated as \"success/stop\" since there's no way to distinguish event types from plain text.\n\n#### How Claude Code Integrates\n\nClaude Code uses the **full OSC 777 `warp://cli-agent` protocol** with structured JSON events. This is the gold standard — Warp gets precise `prompt_submit`, `tool_complete`, `stop`, `permission_request`, etc. events with rich metadata.\n\nWarp uses `DefaultSessionListener` for Claude Code (and also for Pi, Gemini, OpenCode, Auggie), which expects structured JSON events via OSC 777.\n\n#### What Pi Was Missing\n\n| Capability | Codex | Claude Code | Pi (before) | Pi (with pi-warp) |\n|---|---|---|---|---|\n| OSC 0 dynamic title with spinner | ✅ rich | ✅ | ❌ static | ✅ |\n| OSC 777 `session_start` | ❌ | ✅ | ❌ | ✅ |\n| OSC 777 `prompt_submit` | ❌ | ✅ | ❌ | ✅ |\n| OSC 777 `tool_complete` | ❌ | ✅ | ❌ | ✅ |\n| OSC 777 `stop` (success) | ❌ | ✅ | ❌ | ✅ |\n| OSC 777 `idle_prompt` | ❌ | ✅ | ❌ | ✅ |\n| Warp tab status display | ⚠️ stop only | ✅ full | ❌ none | ✅ full |\n\nPi had `CLIAgent::Pi` registered in Warp's codebase (with a brand color and `DefaultSessionListener`), but since Pi never sent any events, the handler had nothing to process.\n\n#### Why an Extension Works\n\nPi's extension API provides all the necessary hooks:\n\n- `session_start` / `session_shutdown` → session lifecycle\n- `agent_start` / `agent_end` → turn lifecycle\n- `message_start` → capture user prompts\n- `tool_result` → tool completion events\n- `ctx.ui.setTitle()` → terminal title control\n- `process.stdout.write()` → raw escape sequence output\n\nThis makes it possible to implement the full `warp://cli-agent` protocol as a pure extension, without any changes to Pi's core.\n\n### Source References\n\n- **Warp event protocol:** [`app/src/terminal/cli_agent_sessions/event/`](https://github.com/warpdotdev/Warp/tree/main/app/src/terminal/cli_agent_sessions/event)\n- **Warp CLI agent enum:** [`app/src/terminal/cli_agent.rs`](https://github.com/warpdotdev/Warp/blob/main/app/src/terminal/cli_agent.rs)\n- **Warp session handler:** [`app/src/terminal/cli_agent_sessions/listener/mod.rs`](https://github.com/warpdotdev/Warp/blob/main/app/src/terminal/cli_agent_sessions/listener/mod.rs)\n- **Codex terminal title:** [`codex-rs/tui/src/terminal_title.rs`](https://github.com/openai/codex/blob/main/codex-rs/tui/src/terminal_title.rs)\n- **Codex status surfaces:** [`codex-rs/tui/src/chatwidget/status_surfaces.rs`](https://github.com/openai/codex/blob/main/codex-rs/tui/src/chatwidget/status_surfaces.rs)\n\n## Development\n\n```bash\n# Install dev dependencies\nnpm install\n\n# Run tests\nnpx vitest run\n\n# Test locally without installing\npi -e ./extensions/warp-integration.ts\n```\n\n## Future Work\n\n- **`permission_request` / `question_asked` events:** Pi's extension API doesn't currently expose a \"waiting for user approval\" hook. When Pi adds this, the extension can emit `permission_request` to show the Blocked status in Warp's tab.\n- **`WARP_CLI_AGENT_PROTOCOL_VERSION` negotiation:** Warp exports this env var on the PTY. Future versions could use it to negotiate payload format.\n\n## License\n\nMIT\n","readmeFilename":"README.md"}