The Zulip extension spawned a brand-new pi -p --mode json subprocess for every incoming Zulip DM. This required a full cold-start: loading extensions, initializing the provider, and connecting the LLM. This caused ETIMEDOUT and ENOBUFS errors.
Additionally, the zulip-js import used a named { createClient } import, but the library only exports a default function.
Solution
Replaced the subprocess architecture with direct session injection:
pi.sendUserMessage() injects Zulip DMs directly into the current pi session
agent_end event handler captures the assistant response and relays it back
Pending reply queue handles ordered delivery
Changes
Removed spawnSync subprocess entirely
Fixed zulip-js import (CJS default export, not named)
Added types.d.ts for zulip-js type declarations
Uses yaml package for config parsing (matching main branch conventions)
Removed all subprocess timeout/buffer error paths
## Problem
The Zulip extension spawned a brand-new `pi -p --mode json` subprocess for every incoming Zulip DM. This required a full cold-start: loading extensions, initializing the provider, and connecting the LLM. This caused ETIMEDOUT and ENOBUFS errors.
Additionally, the `zulip-js` import used a named `{ createClient }` import, but the library only exports a default function.
## Solution
Replaced the subprocess architecture with direct session injection:
1. `pi.sendUserMessage()` injects Zulip DMs directly into the current pi session
2. `agent_end` event handler captures the assistant response and relays it back
3. Pending reply queue handles ordered delivery
## Changes
- Removed spawnSync subprocess entirely
- Fixed zulip-js import (CJS default export, not named)
- Added types.d.ts for zulip-js type declarations
- Uses `yaml` package for config parsing (matching main branch conventions)
- Removed all subprocess timeout/buffer error paths
- Removed spawnSync subprocess (pi -p --mode json) for Zulip DM processing
- Messages now inject directly into the current pi session via
pi.sendUserMessage(), reusing the already-hot LLM — zero cold-start
- agent_end event handler captures assistant response and relays it to Zulip
- Added pending reply queue for ordered delivery of multiple Zulip messages
- Fixed zulip-js import (CJS default export, not named createClient)
- Added types.d.ts for zulip-js with default export declaration
- Updated package.json with yaml dependency, @earendil-works/pi-coding-agent
- Config supports both nested YAML and flat env-var formats
- Removed all subprocess timeout/buffer error paths (no longer needed)
jerome
merged commit 0079d11d94 into main2026-06-24 20:25:56 +00:00
Blocking a user prevents them from interacting with repositories, such as opening or commenting on pull requests or issues. Learn more about blocking a user.
Problem
The Zulip extension spawned a brand-new
pi -p --mode jsonsubprocess for every incoming Zulip DM. This required a full cold-start: loading extensions, initializing the provider, and connecting the LLM. This caused ETIMEDOUT and ENOBUFS errors.Additionally, the
zulip-jsimport used a named{ createClient }import, but the library only exports a default function.Solution
Replaced the subprocess architecture with direct session injection:
pi.sendUserMessage()injects Zulip DMs directly into the current pi sessionagent_endevent handler captures the assistant response and relays it backChanges
yamlpackage for config parsing (matching main branch conventions)