Files
Michael Ramos 89f0b6628e feat(pi): live local app annotation through a shared proxy core and Node transport (#1366)
Phase 2 of live app annotation: full parity on Pi over one shared
implementation instead of drifting copies.

- Extract every proxy decision into packages/shared/live-proxy-core.ts
  (HTML injector state machine, loopback/Host/Origin predicates,
  CSP/X-Frame-Options policy, redirect rewrite, WS origin gate, bridge
  assembly, liveAppDraftIdentity) and the CLI probe + live-mode messages
  into packages/shared/live-probe.ts. packages/server/live-proxy.ts is
  now a thin Bun transport over the core; its test suite passes
  unmodified.
- Add packages/shared/live-proxy-node.ts, the node:http transport the Pi
  extension runs: streaming request/response piping through the shared
  injector, and WebSocket (HMR) passthrough that replays the client's
  handshake upstream over raw TCP and pipes the sockets byte-for-byte.
  Transport tests run the proxy in a real node child process, because
  Bun's node:http shim drops writes to an upgrade event's socket.
- Wire Pi: /plannotator-annotate probes loopback URLs live-first with
  the shared probe (same 3s timeout, same <500 gate, same messages),
  recognizes --app/--static via parseAnnotateArgs's liveFlags opt-in
  (OpenCode deliberately does not opt in), and serves mode annotate-app
  from serverAnnotate.ts with the shared per-target draft identity,
  live sessions excluded from history/submissions, the remote hard-off
  throw, and guarded live-proxy shutdown.
- Vendor live-proxy-core/live-probe/live-proxy-node plus the
  dependency-free bridge-script constants to generated/.
- Docs: AGENTS.md phase-gate passages, marketing annotate page, Pi
  README.
2026-08-21 10:29:29 -07:00

33 lines
1.3 KiB
TypeScript

/**
* Test-only child entry for live-proxy-node.test.ts.
*
* Hosts the Node live proxy in a REAL node process: the transport's runtime
* is node:http under Pi (jiti on Node), and Bun's node:http shim differs in
* exactly the place that matters most here — writes to an 'upgrade' event's
* socket never reach the wire under the shim (verified against Bun 1.x),
* so an in-process proxy under `bun test` would fail WS passthrough that
* works in production and vice versa could mask real breakage. The suite
* builds this file with Bun.build, launches it under `node`, and drives the
* proxy over the wire.
*
* Env contract: LIVE_PROXY_TARGET (required upstream origin),
* LIVE_PROXY_EDITOR_ORIGINS (comma-separated), LIVE_PROXY_BRIDGE (bridge
* body). Prints one JSON line { port } once listening, then stays alive
* until killed.
*/
import { startLiveAppProxyNode } from "./live-proxy-node";
const targetUrl = process.env.LIVE_PROXY_TARGET;
if (!targetUrl) {
throw new Error("LIVE_PROXY_TARGET is required");
}
const proxy = await startLiveAppProxyNode({
targetUrl,
editorOrigins: (process.env.LIVE_PROXY_EDITOR_ORIGINS ?? "").split(",").filter(Boolean),
bridgeJs: process.env.LIVE_PROXY_BRIDGE ?? "// bridge",
});
process.stdout.write(JSON.stringify({ port: proxy.port }) + "\n");