Skip to content

Connect browser terminal and HTML views to native fx - #810

Draft
nandorojo wants to merge 5 commits into
mainfrom
codex/libfx-remote-ui-rfc
Draft

Connect browser terminal and HTML views to native fx#810
nandorojo wants to merge 5 commits into
mainfrom
codex/libfx-remote-ui-rfc

Conversation

@nandorojo

@nandorojo nandorojo commented Sep 11, 2026

Copy link
Copy Markdown

This lets a web app use libfx’s terminal or HTML UI while native fx runs in Vercel Sandbox. The browser connects through the app’s backend; fx keeps the conversation, calls models, and executes tools in the sandbox.

Browser

Use the existing terminal component:

import { createFxTerminal, xtermAdapter } from 'libfx/browser';

const terminal = await createFxTerminal({
  terminal: xtermAdapter(term),
  remote: connection,
});
await terminal.interactive;

Or use HTML with fx-owned commands, model choices, and permission controls:

import { createFxView } from 'libfx/browser';
import { createFxHtmlView } from 'libfx/html';

let client;
const view = createFxHtmlView({
  container: document.querySelector('#fx'),
  send: action => client.interact(action),
});
client = await createFxView({ remote: connection, onSnapshot: view.render });
await client.interactive;

Backend

Start once using the application’s existing sandbox, then retain the private connection for that session:

import { startVercelTerminal } from './sdk/examples/remote-terminal/vercel.mjs';
import { createTerminalRelay } from './sdk/examples/remote-terminal/relay.mjs';

const privateConnection = await startVercelTerminal({
  sandbox,
  cwd: '/vercel/sandbox/repo',
  fxPath: '/vercel/sandbox/.local/bin/fx',
  origin: 'https://your-app.example',
  sessionId,
  env: { AI_GATEWAY_API_KEY: process.env.AI_GATEWAY_API_KEY },
  existingPorts: [3000],
});

const relay = createTerminalRelay({
  origin: 'https://your-app.example',
  resolveSession,
});
server.on('upgrade', relay.upgrade);

resolveSession(request) is the app’s authentication hook: return the authenticated user’s stored private connection, or null. Give the browser {url: 'wss://your-app.example/api/fx', sessionId}. Sandbox URLs and credentials stay on the backend.

The example needs Node and Python in the sandbox, and Bun to bundle the broker. It reuses the native process across prompts and browser reconnects. abort() detaches the view; interrupt() cancels the native operation.

Limits

HTML currently supports conversation, command suggestions, model selection, and permission prompts; other native screens explicitly offer terminal handoff. Replay is bounded, expired terminal cursors fail explicitly, and one view can write at a time.

Validation

Native/WASM builds, focused SDK tests, and 13 real PTY/relay tests pass. Real Chrome exercised native model selection and streaming; a prompt through the app relay survived reload without another model request. The provider was a local mock, not a live model or paid Vercel Sandbox.

Draft pending exact-commit Full CI across Linux and macOS.

@nandorojo nandorojo added the type: docs Changes documentation only label Sep 11, 2026
@nandorojo nandorojo changed the title Propose shared libfx interaction support for remote clients RFC: Run libfx in the browser with tools in Vercel Sandbox Sep 11, 2026
@nandorojo nandorojo changed the title RFC: Run libfx in the browser with tools in Vercel Sandbox Connect browser terminal and HTML views to native fx Sep 11, 2026
@nandorojo nandorojo added type: feature Adds a new user-facing capability and removed type: docs Changes documentation only labels Sep 11, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

type: feature Adds a new user-facing capability

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant