simultex 0.1.0__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (113) hide show
  1. simultex-0.1.0/.gitattributes +2 -0
  2. simultex-0.1.0/.gitignore +6 -0
  3. simultex-0.1.0/LICENSE +21 -0
  4. simultex-0.1.0/PKG-INFO +221 -0
  5. simultex-0.1.0/README.md +206 -0
  6. simultex-0.1.0/assets/logo.svg +24 -0
  7. simultex-0.1.0/assets/logo.tex +10 -0
  8. simultex-0.1.0/assets/simultex.ansi +6 -0
  9. simultex-0.1.0/browser-ui/package-lock.json +1711 -0
  10. simultex-0.1.0/browser-ui/package.json +19 -0
  11. simultex-0.1.0/browser-ui/src/api-transcript.js +397 -0
  12. simultex-0.1.0/browser-ui/src/code-highlighting.js +84 -0
  13. simultex-0.1.0/browser-ui/src/copy-source.js +116 -0
  14. simultex-0.1.0/browser-ui/src/html-export.js +191 -0
  15. simultex-0.1.0/browser-ui/src/image-source.js +9 -0
  16. simultex-0.1.0/browser-ui/src/latex-normalize.js +28 -0
  17. simultex-0.1.0/browser-ui/src/main.js +1014 -0
  18. simultex-0.1.0/browser-ui/src/mermaid-support.js +48 -0
  19. simultex-0.1.0/browser-ui/src/message-records.js +122 -0
  20. simultex-0.1.0/browser-ui/src/style.css +486 -0
  21. simultex-0.1.0/browser-ui/src/tui-chrome.js +108 -0
  22. simultex-0.1.0/browser-ui/test/api-transcript.test.js +342 -0
  23. simultex-0.1.0/browser-ui/test/code-highlighting.test.js +23 -0
  24. simultex-0.1.0/browser-ui/test/copy-source.test.js +55 -0
  25. simultex-0.1.0/browser-ui/test/html-export.test.js +73 -0
  26. simultex-0.1.0/browser-ui/test/image-source.test.js +35 -0
  27. simultex-0.1.0/browser-ui/test/latex-normalize.test.js +62 -0
  28. simultex-0.1.0/browser-ui/test/mermaid-support.test.js +81 -0
  29. simultex-0.1.0/browser-ui/test/message-records.test.js +204 -0
  30. simultex-0.1.0/browser-ui/test/tui-chrome.test.js +138 -0
  31. simultex-0.1.0/pyproject.toml +31 -0
  32. simultex-0.1.0/scripts/inspect_capture.py +42 -0
  33. simultex-0.1.0/scripts/replay_capture.py +58 -0
  34. simultex-0.1.0/src/simultex/__init__.py +3 -0
  35. simultex-0.1.0/src/simultex/browser.py +329 -0
  36. simultex-0.1.0/src/simultex/browser_assets/KaTeX_AMS-Regular-CYEKBG2K.woff +0 -0
  37. simultex-0.1.0/src/simultex/browser_assets/KaTeX_AMS-Regular-JKX5W2C4.ttf +0 -0
  38. simultex-0.1.0/src/simultex/browser_assets/KaTeX_AMS-Regular-U6PRYMIZ.woff2 +0 -0
  39. simultex-0.1.0/src/simultex/browser_assets/KaTeX_Caligraphic-Bold-5QL5CMTE.woff2 +0 -0
  40. simultex-0.1.0/src/simultex/browser_assets/KaTeX_Caligraphic-Bold-WZ3QSGD3.woff +0 -0
  41. simultex-0.1.0/src/simultex/browser_assets/KaTeX_Caligraphic-Bold-ZTS3R3HK.ttf +0 -0
  42. simultex-0.1.0/src/simultex/browser_assets/KaTeX_Caligraphic-Regular-3LKEU76G.woff +0 -0
  43. simultex-0.1.0/src/simultex/browser_assets/KaTeX_Caligraphic-Regular-A7XRTZ5Q.ttf +0 -0
  44. simultex-0.1.0/src/simultex/browser_assets/KaTeX_Caligraphic-Regular-KX5MEWCF.woff2 +0 -0
  45. simultex-0.1.0/src/simultex/browser_assets/KaTeX_Fraktur-Bold-2QVFK6NQ.woff2 +0 -0
  46. simultex-0.1.0/src/simultex/browser_assets/KaTeX_Fraktur-Bold-T4SWXBMT.woff +0 -0
  47. simultex-0.1.0/src/simultex/browser_assets/KaTeX_Fraktur-Bold-WGHVTYOR.ttf +0 -0
  48. simultex-0.1.0/src/simultex/browser_assets/KaTeX_Fraktur-Regular-2PEIFJSJ.woff2 +0 -0
  49. simultex-0.1.0/src/simultex/browser_assets/KaTeX_Fraktur-Regular-5U4OPH2X.ttf +0 -0
  50. simultex-0.1.0/src/simultex/browser_assets/KaTeX_Fraktur-Regular-PQMHCIK6.woff +0 -0
  51. simultex-0.1.0/src/simultex/browser_assets/KaTeX_Main-Bold-2GA4IZIN.woff +0 -0
  52. simultex-0.1.0/src/simultex/browser_assets/KaTeX_Main-Bold-W5FBVCZM.ttf +0 -0
  53. simultex-0.1.0/src/simultex/browser_assets/KaTeX_Main-Bold-YP5VVQRP.woff2 +0 -0
  54. simultex-0.1.0/src/simultex/browser_assets/KaTeX_Main-BoldItalic-4P4C7HJH.woff +0 -0
  55. simultex-0.1.0/src/simultex/browser_assets/KaTeX_Main-BoldItalic-N4V3DX7S.woff2 +0 -0
  56. simultex-0.1.0/src/simultex/browser_assets/KaTeX_Main-BoldItalic-ODMLBJJQ.ttf +0 -0
  57. simultex-0.1.0/src/simultex/browser_assets/KaTeX_Main-Italic-I43T2HSR.ttf +0 -0
  58. simultex-0.1.0/src/simultex/browser_assets/KaTeX_Main-Italic-RELBIK7M.woff2 +0 -0
  59. simultex-0.1.0/src/simultex/browser_assets/KaTeX_Main-Italic-SASNQFN2.woff +0 -0
  60. simultex-0.1.0/src/simultex/browser_assets/KaTeX_Main-Regular-ARRPAO67.woff2 +0 -0
  61. simultex-0.1.0/src/simultex/browser_assets/KaTeX_Main-Regular-P5I74A2A.woff +0 -0
  62. simultex-0.1.0/src/simultex/browser_assets/KaTeX_Main-Regular-W74P5G27.ttf +0 -0
  63. simultex-0.1.0/src/simultex/browser_assets/KaTeX_Math-BoldItalic-6EBV3DK5.woff +0 -0
  64. simultex-0.1.0/src/simultex/browser_assets/KaTeX_Math-BoldItalic-K4WTGH3J.woff2 +0 -0
  65. simultex-0.1.0/src/simultex/browser_assets/KaTeX_Math-BoldItalic-VB447A4D.ttf +0 -0
  66. simultex-0.1.0/src/simultex/browser_assets/KaTeX_Math-Italic-6KGCHLFN.woff2 +0 -0
  67. simultex-0.1.0/src/simultex/browser_assets/KaTeX_Math-Italic-KKK3USB2.woff +0 -0
  68. simultex-0.1.0/src/simultex/browser_assets/KaTeX_Math-Italic-SON4MRCA.ttf +0 -0
  69. simultex-0.1.0/src/simultex/browser_assets/KaTeX_SansSerif-Bold-RRNVJFFW.woff2 +0 -0
  70. simultex-0.1.0/src/simultex/browser_assets/KaTeX_SansSerif-Bold-STQ6RXC7.ttf +0 -0
  71. simultex-0.1.0/src/simultex/browser_assets/KaTeX_SansSerif-Bold-X5M5EMOD.woff +0 -0
  72. simultex-0.1.0/src/simultex/browser_assets/KaTeX_SansSerif-Italic-HMPFTM52.woff2 +0 -0
  73. simultex-0.1.0/src/simultex/browser_assets/KaTeX_SansSerif-Italic-PSN4QKYX.woff +0 -0
  74. simultex-0.1.0/src/simultex/browser_assets/KaTeX_SansSerif-Italic-WTBAZBGY.ttf +0 -0
  75. simultex-0.1.0/src/simultex/browser_assets/KaTeX_SansSerif-Regular-2TL3USAE.ttf +0 -0
  76. simultex-0.1.0/src/simultex/browser_assets/KaTeX_SansSerif-Regular-OQCII6EP.woff +0 -0
  77. simultex-0.1.0/src/simultex/browser_assets/KaTeX_SansSerif-Regular-XIQ62X4E.woff2 +0 -0
  78. simultex-0.1.0/src/simultex/browser_assets/KaTeX_Script-Regular-72OLXYNA.ttf +0 -0
  79. simultex-0.1.0/src/simultex/browser_assets/KaTeX_Script-Regular-A5IFOEBS.woff +0 -0
  80. simultex-0.1.0/src/simultex/browser_assets/KaTeX_Script-Regular-APUWIHLP.woff2 +0 -0
  81. simultex-0.1.0/src/simultex/browser_assets/KaTeX_Size1-Regular-4HRHTS65.woff +0 -0
  82. simultex-0.1.0/src/simultex/browser_assets/KaTeX_Size1-Regular-5LRUTBFT.woff2 +0 -0
  83. simultex-0.1.0/src/simultex/browser_assets/KaTeX_Size1-Regular-7K6AASVL.ttf +0 -0
  84. simultex-0.1.0/src/simultex/browser_assets/KaTeX_Size2-Regular-222HN3GT.ttf +0 -0
  85. simultex-0.1.0/src/simultex/browser_assets/KaTeX_Size2-Regular-K5ZHAIS6.woff +0 -0
  86. simultex-0.1.0/src/simultex/browser_assets/KaTeX_Size2-Regular-LELKET5D.woff2 +0 -0
  87. simultex-0.1.0/src/simultex/browser_assets/KaTeX_Size3-Regular-TLFPAHDE.woff +0 -0
  88. simultex-0.1.0/src/simultex/browser_assets/KaTeX_Size3-Regular-UFCO6WCA.ttf +0 -0
  89. simultex-0.1.0/src/simultex/browser_assets/KaTeX_Size3-Regular-WQRQ47UD.woff2 +0 -0
  90. simultex-0.1.0/src/simultex/browser_assets/KaTeX_Size4-Regular-7PGNVPQK.ttf +0 -0
  91. simultex-0.1.0/src/simultex/browser_assets/KaTeX_Size4-Regular-CDMV7U5C.woff2 +0 -0
  92. simultex-0.1.0/src/simultex/browser_assets/KaTeX_Size4-Regular-PKMWZHNC.woff +0 -0
  93. simultex-0.1.0/src/simultex/browser_assets/KaTeX_Typewriter-Regular-3F5K6SQ6.ttf +0 -0
  94. simultex-0.1.0/src/simultex/browser_assets/KaTeX_Typewriter-Regular-MJMFSK64.woff +0 -0
  95. simultex-0.1.0/src/simultex/browser_assets/KaTeX_Typewriter-Regular-VBYJ4NRC.woff2 +0 -0
  96. simultex-0.1.0/src/simultex/browser_assets/app.css +1 -0
  97. simultex-0.1.0/src/simultex/browser_assets/app.js +3683 -0
  98. simultex-0.1.0/src/simultex/browser_assets/index.html +22 -0
  99. simultex-0.1.0/src/simultex/cli.py +369 -0
  100. simultex-0.1.0/src/simultex/codex_history.py +330 -0
  101. simultex-0.1.0/src/simultex/model_proxy.py +961 -0
  102. simultex-0.1.0/src/simultex/protocol.py +218 -0
  103. simultex-0.1.0/src/simultex/pty_proxy.py +166 -0
  104. simultex-0.1.0/src/simultex/render.py +234 -0
  105. simultex-0.1.0/src/simultex/screen.py +333 -0
  106. simultex-0.1.0/src/simultex/stream.py +276 -0
  107. simultex-0.1.0/tests/test_browser.py +172 -0
  108. simultex-0.1.0/tests/test_codex_history.py +200 -0
  109. simultex-0.1.0/tests/test_model_proxy.py +793 -0
  110. simultex-0.1.0/tests/test_protocol.py +72 -0
  111. simultex-0.1.0/tests/test_render.py +90 -0
  112. simultex-0.1.0/tests/test_screen.py +150 -0
  113. simultex-0.1.0/tests/test_stream.py +121 -0
@@ -0,0 +1,2 @@
1
+ # Minified third-party bundles can contain whitespace inside string literals.
2
+ src/simultex/browser_assets/app.js -whitespace
@@ -0,0 +1,6 @@
1
+ .venv/
2
+ **/__pycache__/
3
+ browser-ui/node_modules/
4
+ .playwright-mcp/
5
+ dist/
6
+ .DS_Store
simultex-0.1.0/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 William Wang
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
@@ -0,0 +1,221 @@
1
+ Metadata-Version: 2.4
2
+ Name: simultex
3
+ Version: 0.1.0
4
+ Summary: A PTY proxy that renders LaTeX as transparent terminal images
5
+ Author: William Wang
6
+ License: MIT
7
+ License-File: LICENSE
8
+ Requires-Python: >=3.10
9
+ Requires-Dist: fastapi<1,>=0.115
10
+ Requires-Dist: httpx<1,>=0.27
11
+ Requires-Dist: pyte<0.9,>=0.8.2
12
+ Requires-Dist: uvicorn<1,>=0.30
13
+ Requires-Dist: websockets<16,>=14
14
+ Description-Content-Type: text/markdown
15
+
16
+ <p align="center">
17
+ <img src="assets/logo.svg" alt="SimulTeX" width="320">
18
+ </p>
19
+
20
+ # SimulTeX
21
+
22
+ **A rich browser companion for Codex and Claude Code CLI.**
23
+
24
+ https://github.com/user-attachments/assets/afec92f0-c074-44c8-b4f1-846d523018f0
25
+
26
+ <p align="center">Demo (Codex)</p>
27
+
28
+ SimulTeX preserves the native terminal UI while turning the conversation into a
29
+ readable, scrollable browser transcript. Prompts and responses render as rich
30
+ Markdown.
31
+
32
+ The browser is read-only. You continue working in the real Codex or Claude
33
+ terminal session while SimulTeX mirrors it on a private localhost URL.
34
+
35
+ ## Quick start
36
+
37
+ SimulTeX requires Python 3.10 or newer. Install it with pipx (recommended for a
38
+ CLI application):
39
+
40
+ ```sh
41
+ pipx install simultex
42
+ ```
43
+
44
+ Or install it into your current Python environment:
45
+
46
+ ```sh
47
+ python3 -m pip install simultex
48
+ ```
49
+
50
+ Both methods reject unsupported Python versions. If pipx selects an older
51
+ interpreter, choose one explicitly:
52
+
53
+ ```sh
54
+ pipx install --python python3.11 simultex
55
+ ```
56
+
57
+ Launch Codex or Claude Code through SimulTeX:
58
+
59
+ ```sh
60
+ simultex -- codex
61
+ simultex -- claude
62
+ ```
63
+
64
+ Copy or open the token-bearing URL printed by SimulTeX, then press Enter to
65
+ launch the child session. Keyboard input stays in the terminal; the browser
66
+ follows the session live.
67
+
68
+ Resume an existing Codex or Claude conversation with its exact saved Markdown:
69
+
70
+ ```sh
71
+ simultex -- codex resume SESSION_ID
72
+ simultex -- claude --resume SESSION_ID
73
+ ```
74
+
75
+ SimulTeX reads the matching local Codex rollout when an explicit UUID or
76
+ `--last` selects the session. If that saved history is unavailable or uses an
77
+ unknown format, startup continues with the PTY-derived transcript.
78
+
79
+ ## What you get
80
+
81
+ - The original Codex or Claude TUI, unchanged in your terminal
82
+ - Exact user Markdown and assistant output for direct Codex and Claude sessions
83
+ - Terminal composers, startup UI, tool/status output, and permission prompts
84
+ - KaTeX math, including inline and display equations
85
+ - Mermaid diagrams from fenced `mermaid` blocks
86
+ - Syntax highlighting for explicitly labeled code fences
87
+ - Markdown tables, lists, blockquotes, links, and images
88
+ - Click-to-copy regions for inline code, fenced code, `latex`/`tex` fences, and
89
+ Mermaid source
90
+ - Static, self-contained HTML transcript downloads
91
+ - PTY-only fallback for other interactive terminal programs
92
+
93
+ ## Why SimulTeX?
94
+
95
+ - **Works with Codex and Claude.** Use the same browser experience with
96
+ Codex CLI or Claude Code while continuing to work in their native TUIs.
97
+ - **Rich rendering for user/assistant messages.** Both user messages and assistant responses
98
+ support Markdown, LaTeX, images, Mermaid diagrams, highlighted code, tables,
99
+ and more.
100
+ - **Search like a web page.** Search the entire conversation with
101
+ <kbd>Ctrl</kbd>/<kbd>Cmd</kbd>+<kbd>F</kbd>, scroll freely, and select or copy
102
+ content without fighting terminal history.
103
+ - **Share a live view.** Let students or collaborators follow the conversation
104
+ as it happens through screen sharing or a secure localhost tunnel.
105
+ - **Let the agent focus on the answer.** The agent answers in Markdown;
106
+ SimulTeX handles consistent rendering without asking it to author and style an
107
+ HTML artifact.
108
+ - **Customize the presentation.** Because the companion is built with HTML and
109
+ CSS, you can adapt its layout and styling without changing how the agent
110
+ responds.
111
+ - **Export as HTML.** Download the current conversation as a
112
+ self-contained HTML file directly from the companion page.
113
+ - **Keep control in the terminal.** The companion is read-only, so
114
+ input, permissions, and interactive controls stay in the real terminal.
115
+
116
+ ## How it works
117
+
118
+ ```mermaid
119
+ flowchart LR
120
+ TUI[Codex or Claude TUI] -->|PTY output| SimulTeX
121
+ SimulTeX -->|unchanged terminal stream| Terminal
122
+ SimulTeX -->|VT reconstruction| Browser[Browser companion]
123
+ TUI -->|model API traffic| Proxy[Local reverse proxy]
124
+ Proxy -->|normalized transcript events| Browser
125
+ Proxy <-->|streaming request and response| Provider[Model provider]
126
+ ```
127
+
128
+ SimulTeX launches the child in a genuine controlling pseudo-terminal and forwards
129
+ keystrokes, output, signals, exit status, and window size normally. The same PTY
130
+ output is mirrored into an in-memory VT screen so the browser can reconstruct
131
+ terminal UI without replacing or modifying the original TUI.
132
+
133
+ For direct `codex` and `claude` commands, SimulTeX also starts a temporary
134
+ loopback reverse proxy. Only the child receives the per-run API routing override.
135
+ The proxy forwards model traffic as it arrives and normalizes provider responses
136
+ into turn, call, user-message, and assistant-text events.
137
+
138
+ Those API events are authoritative for conversation content, preserving exact
139
+ Markdown and TeX without the loss caused by terminal wrapping. PTY reconstruction
140
+ supplies everything the API does not contain: startup chrome, composers, status
141
+ UI, tool activity, permission panels, and fallback messages.
142
+
143
+ If API content is unavailable or a call fails before producing text, the
144
+ PTY-derived block remains visible instead of disappearing.
145
+
146
+ ## Options
147
+
148
+ Use a fixed port when helpful for browser automation:
149
+
150
+ ```sh
151
+ simultex --browser-port 8765 -- codex
152
+ ```
153
+
154
+ Disable authoritative API capture to test PTY reconstruction by itself:
155
+
156
+ ```sh
157
+ simultex --no-api-proxy -- codex
158
+ ```
159
+
160
+ Useful development and diagnostic options:
161
+
162
+ ```sh
163
+ simultex --api-upstream URL -- codex
164
+ simultex --capture-raw codex.raw -- codex
165
+ simultex --no-dollar -- codex
166
+ ```
167
+
168
+ Raw captures can contain the complete terminal conversation and metadata.
169
+ SimulTeX refuses to overwrite an existing capture file.
170
+
171
+ ## Exporting and sharing
172
+
173
+ Use **Download HTML** to save a self-contained transcript with its styles, fonts,
174
+ rendered diagrams, and loaded local images. The export removes the live connection
175
+ and access token.
176
+
177
+ Copyable code, LaTeX, and Mermaid regions preserve their original source in both
178
+ the live companion and downloaded HTML. Remote images are embedded when possible;
179
+ otherwise their original URLs remain in the file.
180
+
181
+ ## Privacy and security
182
+
183
+ - **Local and private by default.** SimulTeX listens only on `127.0.0.1`, and the
184
+ live transcript requires the random token in the printed URL. Share it only
185
+ with people you trust and only through a secure tunnel.
186
+ - **Read-only companion.** The browser cannot control the child process, and API
187
+ routing changes apply only to the launched command—not your global Codex or
188
+ Claude configuration.
189
+ - **Local history access.** When resuming Codex, SimulTeX may read its saved local
190
+ history to restore exact Markdown; that data remains on the local companion.
191
+ - **Review before sharing.** Remote images contact their original servers, and
192
+ downloaded transcripts may include conversation text, metadata, and local
193
+ images.
194
+
195
+ ## Limitations
196
+
197
+ - SimulTeX is a readable transcript, not a pixel-perfect copy of the terminal.
198
+ Messages render as Markdown, while terminal UI stays fixed-width; the composer
199
+ may briefly flicker during redraws.
200
+ - Direct Codex and Claude sessions provide the most accurate Markdown. Other
201
+ commands rely on terminal reconstruction, so content erased before it appears
202
+ cannot always be recovered.
203
+
204
+ ## Development
205
+
206
+ ```sh
207
+ python3 -m pip install -e .
208
+ PYTHONPATH=src python3 -m unittest discover -s tests -v
209
+ cd browser-ui && npm install && npm test && npm run build
210
+ PYTHONPATH=src python3 scripts/replay_capture.py /path/to/codex.raw
211
+ ```
212
+
213
+ The Python suite covers the PTY proxy, browser server, API normalization,
214
+ provider routing, terminal reconstruction, image security, and optional terminal
215
+ rendering. The browser suite covers message reconciliation, composer state,
216
+ Markdown features, copy behavior, exports, Mermaid, syntax highlighting, and
217
+ image source handling.
218
+
219
+ ## License
220
+
221
+ MIT
@@ -0,0 +1,206 @@
1
+ <p align="center">
2
+ <img src="assets/logo.svg" alt="SimulTeX" width="320">
3
+ </p>
4
+
5
+ # SimulTeX
6
+
7
+ **A rich browser companion for Codex and Claude Code CLI.**
8
+
9
+ https://github.com/user-attachments/assets/afec92f0-c074-44c8-b4f1-846d523018f0
10
+
11
+ <p align="center">Demo (Codex)</p>
12
+
13
+ SimulTeX preserves the native terminal UI while turning the conversation into a
14
+ readable, scrollable browser transcript. Prompts and responses render as rich
15
+ Markdown.
16
+
17
+ The browser is read-only. You continue working in the real Codex or Claude
18
+ terminal session while SimulTeX mirrors it on a private localhost URL.
19
+
20
+ ## Quick start
21
+
22
+ SimulTeX requires Python 3.10 or newer. Install it with pipx (recommended for a
23
+ CLI application):
24
+
25
+ ```sh
26
+ pipx install simultex
27
+ ```
28
+
29
+ Or install it into your current Python environment:
30
+
31
+ ```sh
32
+ python3 -m pip install simultex
33
+ ```
34
+
35
+ Both methods reject unsupported Python versions. If pipx selects an older
36
+ interpreter, choose one explicitly:
37
+
38
+ ```sh
39
+ pipx install --python python3.11 simultex
40
+ ```
41
+
42
+ Launch Codex or Claude Code through SimulTeX:
43
+
44
+ ```sh
45
+ simultex -- codex
46
+ simultex -- claude
47
+ ```
48
+
49
+ Copy or open the token-bearing URL printed by SimulTeX, then press Enter to
50
+ launch the child session. Keyboard input stays in the terminal; the browser
51
+ follows the session live.
52
+
53
+ Resume an existing Codex or Claude conversation with its exact saved Markdown:
54
+
55
+ ```sh
56
+ simultex -- codex resume SESSION_ID
57
+ simultex -- claude --resume SESSION_ID
58
+ ```
59
+
60
+ SimulTeX reads the matching local Codex rollout when an explicit UUID or
61
+ `--last` selects the session. If that saved history is unavailable or uses an
62
+ unknown format, startup continues with the PTY-derived transcript.
63
+
64
+ ## What you get
65
+
66
+ - The original Codex or Claude TUI, unchanged in your terminal
67
+ - Exact user Markdown and assistant output for direct Codex and Claude sessions
68
+ - Terminal composers, startup UI, tool/status output, and permission prompts
69
+ - KaTeX math, including inline and display equations
70
+ - Mermaid diagrams from fenced `mermaid` blocks
71
+ - Syntax highlighting for explicitly labeled code fences
72
+ - Markdown tables, lists, blockquotes, links, and images
73
+ - Click-to-copy regions for inline code, fenced code, `latex`/`tex` fences, and
74
+ Mermaid source
75
+ - Static, self-contained HTML transcript downloads
76
+ - PTY-only fallback for other interactive terminal programs
77
+
78
+ ## Why SimulTeX?
79
+
80
+ - **Works with Codex and Claude.** Use the same browser experience with
81
+ Codex CLI or Claude Code while continuing to work in their native TUIs.
82
+ - **Rich rendering for user/assistant messages.** Both user messages and assistant responses
83
+ support Markdown, LaTeX, images, Mermaid diagrams, highlighted code, tables,
84
+ and more.
85
+ - **Search like a web page.** Search the entire conversation with
86
+ <kbd>Ctrl</kbd>/<kbd>Cmd</kbd>+<kbd>F</kbd>, scroll freely, and select or copy
87
+ content without fighting terminal history.
88
+ - **Share a live view.** Let students or collaborators follow the conversation
89
+ as it happens through screen sharing or a secure localhost tunnel.
90
+ - **Let the agent focus on the answer.** The agent answers in Markdown;
91
+ SimulTeX handles consistent rendering without asking it to author and style an
92
+ HTML artifact.
93
+ - **Customize the presentation.** Because the companion is built with HTML and
94
+ CSS, you can adapt its layout and styling without changing how the agent
95
+ responds.
96
+ - **Export as HTML.** Download the current conversation as a
97
+ self-contained HTML file directly from the companion page.
98
+ - **Keep control in the terminal.** The companion is read-only, so
99
+ input, permissions, and interactive controls stay in the real terminal.
100
+
101
+ ## How it works
102
+
103
+ ```mermaid
104
+ flowchart LR
105
+ TUI[Codex or Claude TUI] -->|PTY output| SimulTeX
106
+ SimulTeX -->|unchanged terminal stream| Terminal
107
+ SimulTeX -->|VT reconstruction| Browser[Browser companion]
108
+ TUI -->|model API traffic| Proxy[Local reverse proxy]
109
+ Proxy -->|normalized transcript events| Browser
110
+ Proxy <-->|streaming request and response| Provider[Model provider]
111
+ ```
112
+
113
+ SimulTeX launches the child in a genuine controlling pseudo-terminal and forwards
114
+ keystrokes, output, signals, exit status, and window size normally. The same PTY
115
+ output is mirrored into an in-memory VT screen so the browser can reconstruct
116
+ terminal UI without replacing or modifying the original TUI.
117
+
118
+ For direct `codex` and `claude` commands, SimulTeX also starts a temporary
119
+ loopback reverse proxy. Only the child receives the per-run API routing override.
120
+ The proxy forwards model traffic as it arrives and normalizes provider responses
121
+ into turn, call, user-message, and assistant-text events.
122
+
123
+ Those API events are authoritative for conversation content, preserving exact
124
+ Markdown and TeX without the loss caused by terminal wrapping. PTY reconstruction
125
+ supplies everything the API does not contain: startup chrome, composers, status
126
+ UI, tool activity, permission panels, and fallback messages.
127
+
128
+ If API content is unavailable or a call fails before producing text, the
129
+ PTY-derived block remains visible instead of disappearing.
130
+
131
+ ## Options
132
+
133
+ Use a fixed port when helpful for browser automation:
134
+
135
+ ```sh
136
+ simultex --browser-port 8765 -- codex
137
+ ```
138
+
139
+ Disable authoritative API capture to test PTY reconstruction by itself:
140
+
141
+ ```sh
142
+ simultex --no-api-proxy -- codex
143
+ ```
144
+
145
+ Useful development and diagnostic options:
146
+
147
+ ```sh
148
+ simultex --api-upstream URL -- codex
149
+ simultex --capture-raw codex.raw -- codex
150
+ simultex --no-dollar -- codex
151
+ ```
152
+
153
+ Raw captures can contain the complete terminal conversation and metadata.
154
+ SimulTeX refuses to overwrite an existing capture file.
155
+
156
+ ## Exporting and sharing
157
+
158
+ Use **Download HTML** to save a self-contained transcript with its styles, fonts,
159
+ rendered diagrams, and loaded local images. The export removes the live connection
160
+ and access token.
161
+
162
+ Copyable code, LaTeX, and Mermaid regions preserve their original source in both
163
+ the live companion and downloaded HTML. Remote images are embedded when possible;
164
+ otherwise their original URLs remain in the file.
165
+
166
+ ## Privacy and security
167
+
168
+ - **Local and private by default.** SimulTeX listens only on `127.0.0.1`, and the
169
+ live transcript requires the random token in the printed URL. Share it only
170
+ with people you trust and only through a secure tunnel.
171
+ - **Read-only companion.** The browser cannot control the child process, and API
172
+ routing changes apply only to the launched command—not your global Codex or
173
+ Claude configuration.
174
+ - **Local history access.** When resuming Codex, SimulTeX may read its saved local
175
+ history to restore exact Markdown; that data remains on the local companion.
176
+ - **Review before sharing.** Remote images contact their original servers, and
177
+ downloaded transcripts may include conversation text, metadata, and local
178
+ images.
179
+
180
+ ## Limitations
181
+
182
+ - SimulTeX is a readable transcript, not a pixel-perfect copy of the terminal.
183
+ Messages render as Markdown, while terminal UI stays fixed-width; the composer
184
+ may briefly flicker during redraws.
185
+ - Direct Codex and Claude sessions provide the most accurate Markdown. Other
186
+ commands rely on terminal reconstruction, so content erased before it appears
187
+ cannot always be recovered.
188
+
189
+ ## Development
190
+
191
+ ```sh
192
+ python3 -m pip install -e .
193
+ PYTHONPATH=src python3 -m unittest discover -s tests -v
194
+ cd browser-ui && npm install && npm test && npm run build
195
+ PYTHONPATH=src python3 scripts/replay_capture.py /path/to/codex.raw
196
+ ```
197
+
198
+ The Python suite covers the PTY proxy, browser server, API normalization,
199
+ provider routing, terminal reconstruction, image security, and optional terminal
200
+ rendering. The browser suite covers message reconciliation, composer state,
201
+ Markdown features, copy behavior, exports, Mermaid, syntax highlighting, and
202
+ image source handling.
203
+
204
+ ## License
205
+
206
+ MIT
@@ -0,0 +1,24 @@
1
+ <?xml version='1.0' encoding='UTF-8'?>
2
+ <!-- This file was generated by dvisvgm 3.6 -->
3
+ <svg version='1.1' xmlns='http://www.w3.org/2000/svg' xmlns:xlink='http://www.w3.org/1999/xlink' width='111.681793pt' height='26.533798pt' viewBox='-72 -72 111.681793 26.533798'>
4
+ <defs>
5
+ <path id='g0-83' d='M13.608092-4.957411C13.608092-7.733561 11.550767-9.815673 9.072062-10.385775L6.692504-10.931091C6.147189-11.055026 4.610392-11.625128 4.610392-13.03799C4.610392-15.14489 6.717291-15.194464 7.560051-15.194464C8.948126-15.194464 10.187479-14.872232 11.402045-13.682453C11.798637-13.310648 11.823424-13.285861 11.922573-13.285861C12.071295-13.285861 12.19523-13.360222 12.269591-13.732028L12.641397-15.888501C12.690971-16.086798 12.690971-16.136372 12.690971-16.210733C12.690971-16.409029 12.666184-16.433816 12.046508-16.756048C10.286627-17.623595 8.824191-17.74753 7.560051-17.74753C5.354004-17.74753 1.51201-17.227002 1.51201-12.591823C1.51201-10.831942 2.429131-9.691738 2.900085-9.195997C4.164225-7.90707 5.329216-7.6592 7.262607-7.213033C8.650682-6.890801 9.195997-6.766866 9.741312-6.271125C9.989183-6.023254 10.509711-5.502726 10.509711-4.560818C10.509711-2.230835 8.378024-2.156474 7.560051-2.156474C5.477939-2.156474 3.668484-2.999233 2.429131-4.114651C2.131687-4.412096 2.082112-4.412096 1.982964-4.412096C1.834242-4.412096 1.710307-4.337734 1.635946-3.965929L1.26414-1.809455C1.214566-1.611158 1.214566-1.561584 1.214566-1.487223C1.214566-.966695 3.792419-.074361 3.916354-.024787C5.577087 .495741 6.915588 .545315 7.560051 .545315C11.278109 .545315 13.608092-1.115417 13.608092-4.957411Z'/>
6
+ <path id='g0-105' d='M4.808688-1.189779V-10.162692C4.808688-10.955878 4.635179-11.35247 3.61891-11.35247H2.701789C1.809455-11.35247 1.51201-11.079813 1.51201-10.162692V-1.189779C1.51201-.297445 1.784668 0 2.701789 0H3.61891C4.560818 0 4.808688-.322232 4.808688-1.189779ZM4.982198-15.020954V-15.491908C4.982198-16.285094 4.808688-16.681687 3.792419-16.681687H2.528279C1.586371-16.681687 1.338501-16.359455 1.338501-15.491908V-15.020954C1.338501-14.30213 1.462436-13.831176 2.528279-13.831176H3.792419C4.833475-13.831176 4.982198-14.277343 4.982198-15.020954Z'/>
7
+ <path id='g0-108' d='M4.808688-1.189779V-16.012437C4.808688-16.805622 4.635179-17.202215 3.61891-17.202215H2.701789C1.809455-17.202215 1.51201-16.929557 1.51201-16.012437V-1.189779C1.51201-.297445 1.784668 0 2.701789 0H3.61891C4.560818 0 4.808688-.322232 4.808688-1.189779Z'/>
8
+ <path id='g0-109' d='M19.978365-1.189779V-8.055792C19.978365-10.608859 18.887735-11.625128 16.359455-11.625128C14.599574-11.625128 13.236287-10.807155 12.343953-9.17121C11.94736-11.550767 9.84046-11.625128 8.799404-11.625128C8.32845-11.625128 7.287394-11.625128 6.171976-10.807155C5.403578-10.237053 4.907837-9.443867 4.734327-9.072062H4.70954V-10.311414C4.70954-11.1046 4.536031-11.501193 3.519762-11.501193H2.677002C1.784668-11.501193 1.487223-11.228535 1.487223-10.311414V-1.189779C1.487223-.297445 1.759881 0 2.677002 0H3.668484C4.610392 0 4.858262-.322232 4.858262-1.189779V-6.667717C4.858262-8.898552 6.370273-9.84046 7.584838-9.84046C8.774617-9.84046 9.047275-9.319932 9.047275-8.006218V-1.189779C9.047275-.297445 9.319932 0 10.237053 0H11.228535C12.170443 0 12.418314-.322232 12.418314-1.189779V-6.667717C12.418314-8.898552 13.930324-9.84046 15.14489-9.84046C16.334668-9.84046 16.607326-9.319932 16.607326-8.006218V-1.189779C16.607326-.297445 16.879983 0 17.797104 0H18.788587C19.730495 0 19.978365-.322232 19.978365-1.189779Z'/>
9
+ <path id='g0-117' d='M12.393527-1.189779V-10.162692C12.393527-10.955878 12.220017-11.35247 11.203748-11.35247H10.212266C9.270358-11.35247 9.022487-11.030239 9.022487-10.162692V-4.28816C9.022487-2.652215 8.154941-1.239353 6.39506-1.239353C5.006985-1.239353 4.858262-1.586371 4.858262-2.900085V-10.162692C4.858262-10.955878 4.684753-11.35247 3.668484-11.35247H2.677002C1.784668-11.35247 1.487223-11.079813 1.487223-10.162692V-3.123169C1.487223-.470954 2.924872 .272658 5.502726 .272658C6.171976 .272658 7.931857 .272658 9.096849-1.834242V-1.189779C9.096849-.396593 9.270358 0 10.286627 0H11.203748C12.145656 0 12.393527-.322232 12.393527-1.189779Z'/>
10
+ <path id='g1-69' d='M15.045741-6.271125H14.599574C14.054259-2.627428 13.732028-.644463 9.369506-.644463H5.924106C4.932624-.644463 4.88305-.768399 4.88305-1.611158V-8.452385H7.213033C9.543016-8.452385 9.766099-7.609625 9.766099-5.5523H10.212266V-11.996934H9.766099C9.766099-9.939608 9.543016-9.096849 7.213033-9.096849H4.88305V-15.268825C4.88305-16.111585 4.932624-16.23552 5.924106-16.23552H9.319932C13.161925-16.23552 13.608092-14.698723 13.955111-11.402045H14.401278L13.806389-16.879983H1.26414V-16.23552C2.974446-16.23552 3.247104-16.23552 3.247104-15.120103V-1.759881C3.247104-.644463 2.974446-.644463 1.26414-.644463V0H14.153408L15.045741-6.271125Z'/>
11
+ <path id='g1-84' d='M15.838927-11.377258L15.417547-16.855196H1.115417L.694037-11.377258H1.140204C1.462436-15.491908 1.809455-16.210733 5.626661-16.210733C6.072828-16.210733 6.791653-16.210733 6.989949-16.185946C7.460903-16.111585 7.460903-15.81414 7.460903-15.244038V-1.809455C7.460903-.917121 7.386542-.644463 5.329216-.644463H4.635179V0L8.278876-.049574L11.922573 0V-.644463H11.228535C9.17121-.644463 9.096849-.917121 9.096849-1.809455V-15.244038C9.096849-15.789353 9.096849-16.086798 9.543016-16.185946C9.741312-16.210733 10.460137-16.210733 10.906304-16.210733C14.698723-16.210733 15.070528-15.491908 15.39276-11.377258H15.838927Z'/>
12
+ <path id='g1-88' d='M16.830409 0V-.644463C15.244038-.644463 14.996167-.768399 14.500426-1.462436L9.047275-9.394293L12.715758-14.673936C13.087564-15.194464 13.831176-16.260307 15.863714-16.285094V-16.929557C15.293612-16.879983 14.351704-16.879983 13.756815-16.879983C12.938842-16.879983 11.922573-16.879983 11.302896-16.929557V-16.285094C12.096082-16.210733 12.294379-15.714992 12.294379-15.318399C12.294379-15.020954 12.170443-14.822658 11.996934-14.574787L8.725043-9.84046L5.056559-15.194464C4.88305-15.467121 4.858262-15.541483 4.858262-15.615844C4.858262-15.838927 5.13092-16.260307 5.948893-16.285094V-16.929557C5.155707-16.879983 3.941141-16.879983 3.123169-16.879983C2.478705-16.879983 1.239353-16.879983 .644463-16.929557V-16.285094C2.007751-16.285094 2.453918-16.23552 2.999233-15.467121L7.783135-8.477172L3.470187-2.206048C2.404344-.66925 .793186-.644463 .322232-.644463V0C.892334-.049574 1.834242-.049574 2.429131-.049574C3.098382-.049574 4.263373-.049574 4.88305 0V-.644463C4.114651-.718825 3.891567-1.214566 3.891567-1.611158C3.891567-1.93339 4.015503-2.1069 4.139438-2.280409L8.105366-8.031005L12.418314-1.735094C12.61661-1.462436 12.61661-1.388075 12.61661-1.313714C12.61661-1.115417 12.393527-.694037 11.52598-.644463V0C12.319166-.049574 13.533731-.049574 14.351704-.049574C14.996167-.049574 16.23552-.049574 16.830409 0Z'/>
13
+ </defs>
14
+ <g id='page1'>
15
+ <use x='-70.007476' y='-52.794103' xlink:href='#g0-83'/>
16
+ <use x='-54.860127' y='-52.794103' xlink:href='#g0-105'/>
17
+ <use x='-48.525809' y='-52.794103' xlink:href='#g0-109'/>
18
+ <use x='-27.042842' y='-52.794103' xlink:href='#g0-117'/>
19
+ <use x='-13.13485' y='-52.794103' xlink:href='#g0-108'/>
20
+ <use x='-4.981654' y='-52.794103' xlink:href='#g1-84'/>
21
+ <use x='7.775923' y='-47.458733' xlink:href='#g1-69'/>
22
+ <use x='20.50477' y='-52.794103' xlink:href='#g1-88'/>
23
+ </g>
24
+ </svg>
@@ -0,0 +1,10 @@
1
+ \documentclass[border=2pt]{standalone}
2
+ \usepackage{lmodern}
3
+
4
+ \begin{document}
5
+ {\Huge
6
+ {\sffamily\bfseries Simul}%
7
+ \kern0.08em
8
+ {\rmfamily\mdseries\TeX}%
9
+ }
10
+ \end{document}
@@ -0,0 +1,6 @@
1
+  ███████╗ ██╗ ███╗   ███╗ ██╗   ██╗ ██╗      ████████╗ ███████╗ ██╗  ██╗
2
+  ██╔════╝ ██║ ████╗ ████║ ██║   ██║ ██║      ╚══██╔══╝ ██╔════╝ ╚██╗██╔╝
3
+  ███████╗ ██║ ██╔████╔██║ ██║   ██║ ██║         ██║    █████╗    ╚███╔╝ 
4
+  ╚════██║ ██║ ██║╚██╔╝██║ ██║   ██║ ██║         ██║    ██╔══╝    ██╔██╗ 
5
+  ███████║ ██║ ██║ ╚═╝ ██║ ╚██████╔╝ ███████╗    ██║    ███████╗ ██╔╝ ██╗
6
+  ╚══════╝ ╚═╝ ╚═╝     ╚═╝  ╚═════╝  ╚══════╝    ╚═╝    ╚══════╝ ╚═╝  ╚═╝