openpencil/packages/harness
Danila Poyarkov 19d01f0835
fix(harness): start Pi sessions with MCP tools under Node (#897)
* fix(harness): start Pi sessions with MCP tools under Node

The desktop app always gives Pi OpenPencil's MCP server, and the
published companion failed every such session:

- @ai-sdk/harness-pi imports pi-mcp-adapter, which publishes only
  TypeScript sources, and Node refuses to strip types under
  node_modules. A module load hook now strips them for TypeScript
  dependencies only; Bun runs them as is. (vercel/ai#22040)
- pi-mcp-adapter imports @earendil-works/pi-tui but declares it as an
  optional peer, so npm leaves it out. The companion depends on it at
  the version pi-coding-agent uses, and a test keeps the two in step.
  (nicobailon/pi-mcp-adapter#805)
- Pi reports live-process resume, yet the service handed it state
  saved by an earlier session, and the just-bash sandbox cannot resume,
  so every later session with that ID failed. Live-process backends now
  start fresh and drop saved state.

Pi also installs the packages from a person's Pi settings with npm on
every session, writing npm's output to the companion's stdout. The
companion now keeps the real stdout for protocol messages, sends other
writes to stderr, and quiets npm on success. The app logs companion
stderr as diagnostics, since failures arrive as protocol errors.

* fix(harness): reject another backend's state before dropping it

loadResumeState removed saved state for a live-process backend before
createSession checked which backend owned it, so state saved by another
backend was lost instead of rejected. Ownership is checked first, and
only state that belongs to the live-process backend is dropped.
2026-10-05 17:21:50 +00:00
..
src fix(harness): start Pi sessions with MCP tools under Node (#897) 2026-10-05 17:21:50 +00:00
tests fix(harness): start Pi sessions with MCP tools under Node (#897) 2026-10-05 17:21:50 +00:00
AGENTS.md fix(harness): start Pi sessions with MCP tools under Node (#897) 2026-10-05 17:21:50 +00:00
package.json fix(harness): start Pi sessions with MCP tools under Node (#897) 2026-10-05 17:21:50 +00:00
README.md fix(harness): start Pi sessions with MCP tools under Node (#897) 2026-10-05 17:21:50 +00:00
tsconfig.json feat(ai): add HarnessAgent sidecar foundation (#560) 2026-08-19 17:41:10 +03:00
tsdown.config.ts feat(ai): add HarnessAgent sidecar foundation (#560) 2026-08-19 17:41:10 +03:00

@open-pencil/harness

Optional Node companion runtime for coding-agent harness sessions. It owns the backend-neutral session lifecycle, opaque resume-state persistence, and the JSONL sidecar protocol used by host applications.

The first backend uses AI SDK HarnessAgent, Pi, and local just-bash. Pi runs in the Node host process; just-bash provides an isolated in-memory workspace and shell without requiring cloud infrastructure.

Current scope

  • Backend-neutral, streaming session service.
  • Atomic, bounded persistence of opaque harness resume state.
  • JSONL stdio sidecar transport.
  • Pi + just-bash backend.

The package is installed as an optional companion CLI for the desktop application. It is not bundled into every Tauri build; install @open-pencil/harness globally to make the openpencil-harness command available. It runs on Node 22.15 or later, or Bun: Pi's MCP adapter publishes TypeScript sources, which the companion strips through Node's module hooks. Credentials are supplied to the companion process at runtime and are never written to resume-state storage.

Local sandbox limitation

just-bash is process-local and in-memory. Multi-turn sessions work while the sidecar remains alive, but its sandbox cannot be reattached after a process restart. A backend that reports sessionResume: 'live-process', as Pi does, therefore starts a stopped session fresh and drops its saved state. Durable restart recovery requires a persistent sandbox provider in a later integration.