npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

pi-app-server

v2.0.0

Published

Session multiplexer for pi-coding-agent

Readme

pi-server

Session multiplexer for pi-coding-agent. Exposes N independent AgentSession instances through WebSocket and stdio transports.

CI npm

Note: This is a standalone pi server package, not an extension/skills/themes bundle.

Features

  • Dual transport: WebSocket (port 3141) + stdio (JSON lines)
  • Session lifecycle: Create, delete, list, switch sessions
  • Command execution: Deterministic lane serialization per session
  • Idempotent replay: Atomic outcome storage with free replay lookups
  • Optimistic concurrency: Session versioning for conflict detection
  • Extension UI: Full round-trip support for select, confirm, input, editor, interview
  • Resource governance: Rate limiting, session limits, message size limits
  • Graceful shutdown: Drain in-flight commands, notify clients
  • Protocol versioning: serverVersion + protocolVersion for compatibility checks

Installation

npm install pi-app-server

Quick Start

WebSocket

# Start server
npx pi-server

# Connect with wscat
wscat -c ws://localhost:3141
// Create and use a session
ws> {"type":"create_session","sessionId":"my-session"}
ws> {"type":"switch_session","sessionId":"my-session"}
ws> {"id":"cmd-1","type":"prompt","sessionId":"my-session","message":"Hello!"}

stdio

echo '{"type":"create_session","sessionId":"test"}
{"type":"switch_session","sessionId":"test"}
{"id":"cmd-1","type":"prompt","sessionId":"test","message":"Hello!"}' | npx pi-server

Architecture

src/
├── server.ts               # transports, connection lifecycle, routing glue
├── session-manager.ts      # orchestration: coordinates stores, engines, sessions
├── command-router.ts       # session command handlers, routing
├── command-classification.ts  # pure command classification (timeout, mutation)
├── command-replay-store.ts    # idempotency, duplicate detection, outcome history
├── session-version-store.ts   # monotonic version counters per session
├── command-execution-engine.ts # lane serialization, dependency waits, timeouts
├── resource-governor.ts    # limits, rate controls, health/metrics
├── extension-ui.ts         # pending UI request tracking
├── server-ui-context.ts    # ExtensionUIContext for remote clients
├── validation.ts           # command validation
└── types.ts                # wire protocol types + SessionResolver interface

Core invariants

  • For each admitted command, there is exactly one terminal response.
  • For each session ID, there is at most one live AgentSession.
  • Subscriber session sets are always a subset of active sessions.
  • Session version is monotonic and mutation-sensitive.
  • Fingerprint excludes retry identity (id, idempotencyKey) for semantic equivalence.

Key abstractions

  • SessionResolver — Interface for session access (enables test doubles, future clustering)
  • CommandReplayStore — Idempotency and duplicate detection
  • SessionVersionStore — Optimistic concurrency via version counters
  • CommandExecutionEngine — Deterministic lane serialization and timeout management

Protocol

See PROTOCOL.md for the normative wire contract.

Command → Response

Every command receives exactly one response:

{"id": "cmd-1", "type": "prompt", "sessionId": "s1", "message": "hello"}
{"id": "cmd-1", "type": "response", "command": "prompt", "success": true}

Event Broadcast

Events flow session → subscribers:

{"type": "event", "sessionId": "s1", "event": {"type": "agent_start", ...}}

Extension UI Round-Trip

  1. Extension calls ui.select() → server creates pending request
  2. Server broadcasts extension_ui_request event with requestId
  3. Client sends extension_ui_response command with same requestId
  4. Server resolves pending promise → extension continues

Idempotency & Replay

// First request with idempotency key
{"id": "cmd-1", "type": "list_sessions", "idempotencyKey": "key-1"}
{"id": "cmd-1", "type": "response", "command": "list_sessions", "success": true, ...}

// Retry with same key → replayed (free, no rate limit charge)
{"id": "cmd-2", "type": "list_sessions", "idempotencyKey": "key-1"}
{"id": "cmd-2", "type": "response", "command": "list_sessions", "success": true, "replayed": true, ...}

Timeout semantics (ADR-0001)

  • Timeout is a terminal stored outcome (timedOut: true), not an indeterminate placeholder.
  • Replay of the same command identity returns the same timeout response.
  • Late underlying completion does not overwrite the stored timeout outcome.

Development

# Install dependencies
npm install

# Build
npm run build

# Run tests
npm test                    # Unit tests (83)
npm run test:integration    # Integration tests (26)
npm run test:fuzz           # Fuzz tests (17)

# Module tests (141)
node --experimental-vm-modules dist/test-command-classification.js
node --experimental-vm-modules dist/test-session-version-store.js
node --experimental-vm-modules dist/test-command-replay-store.js
node --experimental-vm-modules dist/test-command-execution-engine.js

# Type check + lint
npm run check

# Full CI
npm run ci

Release Process

This project uses release-please for automated versioning.

Automated Flow

  1. Push to main → release-please creates/updates a release PR
  2. Merge the release PR → Creates GitHub release + git tag
  3. Release published → GitHub Action publishes to npm with provenance

Manual Release Check

npm run release:check

This validates:

  • package.json has required fields
  • dist/ exists with compiled files
  • Entry point has correct shebang
  • npm pack produces expected files
  • Full CI passes

Documentation

| Document | Purpose | |----------|---------| | AGENTS.md | Crystallized learnings, patterns, anti-patterns | | PROTOCOL.md | Normative wire contract | | ADR-0001 | Atomic outcome storage (timeout semantics) | | ADR-0007 | Session persistence | | ADR-0009 | Connection authentication (planned) | | ADR-0010 | Circuit breaker for LLM calls | | ROADMAP.md | Phase tracking and milestones |

License

MIT