
Security News
upm Launches as a Fast, Tiny Package Manager Written in TypeScript
upm uses Node.js to deliver fast npm installs in about 250 KB, with a JavaScript API and security defaults.
Minimalistic extendable server exposing a local pi AI agent to the internet over WebSocket.
Minimalistic, extendable server that exposes a local pi AI agent to the internet over WebSocket. The pi agent runs on the same machine in RPC mode; pi-ws bridges public WebSocket clients to it.
browser/client ──ws──▶ pi-ws ──rpc──▶ pi agent (rpc mode)
Default endpoint:
ws://0.0.0.0:8787/ws/pi
Clients send pi RPC JSON objects as text WebSocket frames. pi-ws validates
each frame as a JSON object and forwards it to pi as one JSONL command. pi RPC
events and responses are forwarded back as JSON text frames. Bridge lifecycle
events use pi_ws_* event types.
mise install # installs node + pnpm from .mise.toml
pnpm install
pnpm dev — watch-mode entrypoint (tsx)pnpm demo — run the server on 127.0.0.1:8787 with the chat examplepnpm build — type-check + emit to dist/pnpm start — run built entrypointpnpm demo:built — run the built server with the chat examplepnpm example:chat — build and run the guided chat example launcherpnpm build:docs — generate API report + markdown docs into docs/api/pnpm lint — types + eslint + auditpnpm test — lint + unit testsGenerated API reference:
Regenerate it with:
pnpm build:docs
pi-ws is library-first. Embed PiWs, add your routes, then listen:
import { PiWs } from 'pi-ws';
const pipe = new PiWs({
host: '127.0.0.1',
port: 8787,
});
pipe.handle('get', '/api/version', (res) => {
res
.writeHeader('content-type', 'application/json')
.end(JSON.stringify({ version: 'local-dev' }));
});
pipe.route('/ws/echo', {
message(ws, message, isBinary) {
ws.send(message, isBinary);
},
});
await pipe.listen();
The built-in Pi RPC route remains available at /ws/pi. Use handle() for
HTTP routes, route() for WebSocket routes, and use() for direct
uWebSockets.js access when needed.
For the full exported API surface, see docs/api/pi-ws.md.
From this repository:
mise install
pnpm install
pnpm build
node examples/embedded-server.mjs
Then open:
http://127.0.0.1:8787/examples/chat/
Or check the custom HTTP route:
curl http://127.0.0.1:8787/api/hello
When using pi-ws from another project:
pnpm add pi-ws
Create server.mjs:
import { PiWs } from 'pi-ws';
const pipe = new PiWs({
host: '127.0.0.1',
port: 8787,
});
pipe.handle('get', '/api/hello', (res) => {
res
.writeHeader('content-type', 'application/json')
.end(JSON.stringify({ hello: 'pi-ws' }));
});
await pipe.listen();
Run it:
node server.mjs
The pi-ws binary is a thin wrapper around the library:
const pipe = new PiWs();
await pipe.listen();
After installing the package, run:
pi-ws
From this repository, the equivalent binary-style commands are:
pnpm demo
or, after building:
pnpm build
pnpm demo:built
The repository includes a minimal browser chat UI at /examples/chat/.
See examples/README.md for detailed provider, API key,
model, proxy/base URL, and mise task instructions.
Normal launch:
pnpm demo
Then open:
http://127.0.0.1:8787/examples/chat/
The page connects to:
ws://127.0.0.1:8787/ws/pi
You do not need to launch Pi separately for this flow. pi-ws starts one
bundled Pi subprocess in RPC mode for each /ws/pi websocket connection:
pi --mode rpc --no-session
To use a specific configured LLM provider/model, pass Pi arguments through
PI_WS_PI_ARGS:
PI_WS_PI_ARGS='["--no-session","--provider","openai","--model","openai/gpt-4.1"]' pnpm demo
Or use your configured Pi defaults:
PI_WS_PI_ARGS='["--no-session"]' pnpm demo
Optional Pi-only sanity check:
pnpm exec pi --mode rpc --no-session
Type a JSON command such as {"type":"get_state"} and press Enter. Exit with
Ctrl+C.
PI_WS_HOST — bind host, default 0.0.0.0PI_WS_PORT — bind port, default 8787PI_WS_PREFIX — WebSocket prefix, default /wsPI_WS_MAX_PAYLOAD_BYTES — max inbound frame size, default 1048576PI_WS_PI_COMMAND — optional pi command override; bundled pi is used by
defaultPI_WS_PI_ARGS — extra pi args after --mode rpc; use whitespace
separated args or a JSON string arrayPI_WS_PI_CWD — optional pi subprocess working directorypi-ws keeps the server surface intentionally small:
/healthz/ws/pi/examples/chat/handle(), route(), and use()At runtime, each client connected to /ws/pi gets a dedicated local Pi
subprocess running in RPC mode. Incoming WebSocket text frames must be JSON
objects. pi-ws validates them, converts them to JSONL commands, and forwards
them to Pi over stdin. Pi stdout is read as UTF-8 JSONL, parsed back into JSON
objects, and sent to the client as WebSocket text frames. Pi stderr and bridge
lifecycle changes are exposed as pi_ws_* events.
Route registration order is:
handle()route()use()flowchart TD
Client[Browser or WS client]
UWS[uWebSockets.js websocket]
Bridge[Pi bridge]
Pi[Pi CLI in RPC mode]
Client -->|WS text JSON to /ws/pi| UWS
UWS -->|message event| Bridge
Bridge -->|stdin JSONL| Pi
Pi -->|stdout JSONL| Bridge
Pi -->|stderr and exit| Bridge
Bridge -->|ws.send JSON text| UWS
UWS -->|WS frames| Client
Example embedded usage:
import { PiWs } from 'pi-ws';
const pipe = new PiWs();
pipe.handle('get', '/api/version', (res) => {
res
.writeHeader('content-type', 'application/json')
.end(JSON.stringify({ version: '1.0.0' }));
});
pipe.route('/ws/echo', {
message(ws, message, isBinary) {
ws.send(message, isBinary);
},
});
pipe.use((app) => {
app.get('/internal/ping', (res) => {
res.end('pong');
});
});
await pipe.listen();
FAQs
Embeddable WebSocket bridge for running local Pi coding-agent RPC sessions from Node.js apps.
The npm package pi-ws receives a total of 4 weekly downloads. As such, pi-ws popularity was classified as not popular.
We found that pi-ws demonstrated a healthy version release cadence and project activity because the last version was released less than a year ago. It has 1 open source maintainer collaborating on the project.

Security News
upm uses Node.js to deliver fast npm installs in about 250 KB, with a JavaScript API and security defaults.

Company News
Socket is joining the OpenJS Security Stewardship Program to fund Node.js vulnerability research, maintainer remediation, and security releases.

Security News
Two compromised GitHub Actions were re-enabled with malicious tags intact, exposing thousands of downstream repositories to Mini Shai-Hulud.