Metadata-Version: 2.5
Name: simultex
Version: 0.1.2
Summary: A rich browser companion for Codex CLI and Claude Code
Project-URL: Homepage, https://github.com/acb3688/simultex
Project-URL: Repository, https://github.com/acb3688/simultex
Project-URL: Issues, https://github.com/acb3688/simultex/issues
Author: William Wang
License-Expression: MIT
License-File: LICENSE
Requires-Python: >=3.10
Requires-Dist: fastapi<1,>=0.115
Requires-Dist: httpx<1,>=0.27
Requires-Dist: pyte<0.9,>=0.8.2
Requires-Dist: uvicorn<1,>=0.30
Requires-Dist: websockets<16,>=14
Description-Content-Type: text/markdown

<p align="center">
  <img src="https://raw.githubusercontent.com/acb3688/simultex/main/assets/logo.svg" alt="SimulTeX" width="320">
</p>

# SimulTeX

**A rich browser companion for Codex CLI and Claude Code.**

https://github.com/user-attachments/assets/8ae681c9-8f20-49d3-8164-c508573ee057

<p align="center">Demo (Claude)</p>

SimulTeX preserves the native terminal UI while turning the conversation into a
readable, scrollable browser transcript. Prompts and responses render as rich
Markdown.

The browser is read-only. You continue working in the real Codex or Claude
terminal session while SimulTeX mirrors it on a private localhost URL.

## Quick start

SimulTeX requires Python 3.10 or newer. Install it with pipx (recommended for a
CLI application):

```sh
pipx install simultex
```

Or install it into your current Python environment:

```sh
python3 -m pip install simultex
```

You can also run the published release without installing SimulTeX
persistently:

```sh
pipx run simultex -- codex
pipx run simultex -- claude
```

SimulTeX rejects unsupported Python versions. If pipx selects an older
interpreter for a persistent install, choose one explicitly:

```sh
pipx install --python python3.11 simultex
```

Launch Codex or Claude Code through SimulTeX:

```sh
simultex -- codex
simultex -- claude
```

Copy or open the token-bearing URL printed by SimulTeX, then press Enter to
launch the child session. Keyboard input stays in the terminal; the browser
follows the session live.

If the browser transcript displays incorrectly, try reloading the page.

To let someone else follow the live, read-only view, click **Share** in the
browser companion's top-right corner. SimulTeX starts LocalTunnel (https://github.com/localtunnel/localtunnel) on demand and
shows the temporary public link in an in-page dialog, together with the
LocalTunnel access password when one is available.

Note that **sharing does not work without an installation of Node.js** (https://nodejs.org/en/download).
You can install it like this, if necessary: 

```sh
# macOS with Homebrew
brew install node

# Ubuntu or Debian
sudo apt update
sudo apt install nodejs npm
```

On first use, SimulTeX uses `npm` to install a private LocalTunnel runtime in
the user cache. Its bundled lockfile pins LocalTunnel 2.0.2 and overrides its
Axios dependency with version 0.33.0, so a separate global LocalTunnel
installation is not required. Later sessions reuse the cached runtime. The
public URL and its access token remain valid only while that SimulTeX session is
running.
LocalTunnel may first show a viewer its own anti-abuse consent page. Its
password is separate from the random SimulTeX token in the URL.

Resume an existing Codex or Claude conversation through its native CLI:

```sh
simultex -- codex resume
simultex -- codex resume SESSION_ID
simultex -- claude --resume SESSION_ID
```

When resuming a conversation, SimulTeX restores saved history when available
and otherwise falls back to terminal output.

## What you get

- KaTeX math, including inline and display equations
- Mermaid diagrams from fenced `mermaid` blocks
- Animated SVG illustrations from fenced `svg` blocks
- Syntax highlighting for explicitly labeled code fences
- Markdown tables, lists, blockquotes, and links
- Local and remote images in Markdown messages
- Click-to-copy regions for inline code, fenced code, `latex`/`tex` fences, and
  Mermaid source
- Static, self-contained HTML transcript downloads
- PTY-only fallback for other interactive terminal programs

## Why SimulTeX?

- **Works with Codex and Claude.** Use the same browser experience with
  Codex CLI or Claude Code while continuing to work in their native TUIs.
- **Rich rendering for user/assistant messages.** Both user messages and
  assistant responses support Markdown, LaTeX, images, Mermaid diagrams,
  highlighted code, tables, and more.
- **Search like a web page.** Search the entire conversation with
  <kbd>Ctrl</kbd>/<kbd>Cmd</kbd>+<kbd>F</kbd>, scroll freely, and select or copy
  content without fighting terminal history.
- **Share a live view.** Let trusted students or collaborators follow the
  conversation through a temporary, token-bearing LocalTunnel URL.
- **Let the agent focus on the answer.** The agent answers in Markdown;
  SimulTeX handles consistent rendering without asking it to author and style an
  HTML artifact.
- **Customize the presentation.** Because the companion is built with HTML and
  CSS, you can adapt its layout and styling without changing how the agent
  responds.
- **Export as HTML.** Download the current conversation as a
  self-contained HTML file directly from the companion page.
- **Keep control in the terminal.** The companion is read-only, so
  input, permissions, and interactive controls stay in the real terminal.

## How it works

```mermaid
flowchart LR
    TUI[Codex or Claude TUI] -->|PTY output| SimulTeX
    SimulTeX -->|unchanged terminal stream| Terminal
    SimulTeX -->|SSE on localhost| Browser[Local browser companion]
    TUI -->|model API traffic| Proxy[Local reverse proxy]
    Proxy -->|normalized transcript events| SimulTeX
    Proxy <-->|streaming request and response| Provider[Model provider]
    Remote[Remote browser<br/>Shared view] <-->|HTTPS, including the existing SSE stream| Relay[LocalTunnel service]
    Relay <-->|outbound tunnel| Client[LocalTunnel client]
    Client <-->|forwarded HTTP| SimulTeX

    classDef hub fill:#6d28d9,stroke:#c4b5fd,color:#ffffff,stroke-width:3px
    classDef backend fill:#1e3a5f,stroke:#60a5fa,color:#ffffff,stroke-width:2px
    classDef localFrontend fill:#14532d,stroke:#4ade80,color:#ffffff,stroke-width:2px
    classDef remoteFrontend fill:#78350f,stroke:#fbbf24,color:#ffffff,stroke-width:2px

    class SimulTeX hub
    class TUI,Proxy,Provider backend
    class Terminal,Browser localFrontend
    class Client,Relay,Remote remoteFrontend
```

SimulTeX launches the child in a genuine controlling pseudo-terminal and forwards
keystrokes, output, signals, exit status, and window size normally. The same PTY
output is mirrored into an in-memory VT screen so the browser can reconstruct
terminal UI without replacing or modifying the original TUI.

For direct `codex` and `claude` commands, SimulTeX also starts a temporary
loopback reverse proxy. Only the child receives the per-run API routing override.
The proxy forwards model traffic as it arrives and normalizes provider responses
into turn, call, user-message, and assistant-text events.

Those API events are authoritative for conversation content, preserving exact
Markdown and TeX without the loss caused by terminal wrapping. PTY reconstruction
supplies everything the API does not contain: startup chrome, composers, status
UI, tool activity, permission panels, and fallback messages.

If API content is unavailable or a call fails before producing text, the
PTY-derived block remains visible instead of disappearing.

After Claude requests tool permission, SimulTeX temporarily holds PTY-derived
updates until the next model call or a confirmed local cancellation, preventing
interactive permission choices from becoming transcript messages.

When **Share** is clicked, SimulTeX launches the LocalTunnel client. On first
use, SimulTeX automatically provisions the locked LocalTunnel runtime in a
dedicated SimulTeX cache. The client opens an outbound connection to
LocalTunnel's public relay, so no router configuration or inbound firewall rule
is needed. Requests for the public page and its `/events` connection are
forwarded to the existing loopback HTTP server. The browser still receives
SimulTeX events through SSE; LocalTunnel only transports that HTTP connection.

## Options

Use a fixed port when helpful for browser automation:

```sh
simultex --browser-port 8765 -- codex
```

Try the experimental PTY-only renderer without authoritative API capture:

```sh
simultex --no-api-proxy -- codex
```

Useful development and diagnostic options:

```sh
simultex --api-upstream URL -- codex
simultex --capture-raw codex.raw -- codex
simultex --capture-api requests.jsonl -- codex
simultex --no-dollar -- codex
```

Raw PTY and API captures can contain the complete conversation and metadata.
API captures contain request bodies, prompts, and tool results, but do not record
transport headers or the proxy authorization token. Treat both formats as sensitive.
SimulTeX refuses to overwrite an existing capture file.

## Exporting and sharing

Use **Share** to create a temporary public LocalTunnel link from an in-page
dialog. Use **Download HTML** to save a self-contained transcript with its
styles, fonts, rendered diagrams, and loaded local images. The export removes
the live connection, sharing controls, and access token.

Copyable code, LaTeX, and Mermaid regions preserve their original source in both
the live companion and downloaded HTML. Remote images are embedded when possible;
otherwise their original URLs remain in the file.

## Privacy and security

- **Local and private by default.** SimulTeX listens only on `127.0.0.1`, and the
  live transcript requires the random token in the printed URL.
- **Read-only companion.** The browser cannot control the child process, and API
  routing changes apply only to the launched command—not your global Codex or
  Claude configuration.
- **Session history access.** For supported Codex `resume` commands and
  `claude --resume SESSION_ID`, SimulTeX reads the matching saved local history
  to restore exact Markdown.
- **Live Claude history access.** During a direct Claude session, SimulTeX also
  tails only newly appended records from that exact active session to recognize
  locally rejected tool permissions. The history data remains local.
- **Sharing redirects HTTP traffic.** Clicking **Share** sends the companion's HTTP traffic
  through the third-party LocalTunnel service. Anyone with the complete public
  URL can read the live transcript and any transcript-referenced local images,
  so treat the URL as a temporary password and _share it only with people you
  trust_.

## Limitations

- SimulTeX is a readable transcript, not a pixel-perfect copy of the terminal.
- Tool-calls are not yet displayed in the live view and sub-agent chat rendering is not yet supported. These will be added in a future release.
- SVG animations support declarative CSS and SMIL only. Scripts, event handlers, links, embedded HTML, and external resources are blocked for security purposes.
- Animated SVG supports declarative SMIL and CSS only, not JavaScript.
- Sharing requires Node.js/npm and depends on the availability and
  behavior of the hosted LocalTunnel service.

## Development

```sh
python3 -m pip install -e .
PYTHONPATH=src python3 -m unittest discover -s tests -v
cd browser-ui && npm install && npm test && npm run build
PYTHONPATH=src python3 scripts/replay_capture.py /path/to/codex.raw
```

The Python suite covers the PTY proxy, browser server, LocalTunnel lifecycle,
API normalization, provider routing, terminal reconstruction, image security,
and optional terminal rendering. The browser suite covers message
reconciliation, composer state, Markdown features, copy behavior, exports,
Mermaid, syntax highlighting, and image source handling.

## License

MIT
