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.
- simultex-0.1.0/.gitattributes +2 -0
- simultex-0.1.0/.gitignore +6 -0
- simultex-0.1.0/LICENSE +21 -0
- simultex-0.1.0/PKG-INFO +221 -0
- simultex-0.1.0/README.md +206 -0
- simultex-0.1.0/assets/logo.svg +24 -0
- simultex-0.1.0/assets/logo.tex +10 -0
- simultex-0.1.0/assets/simultex.ansi +6 -0
- simultex-0.1.0/browser-ui/package-lock.json +1711 -0
- simultex-0.1.0/browser-ui/package.json +19 -0
- simultex-0.1.0/browser-ui/src/api-transcript.js +397 -0
- simultex-0.1.0/browser-ui/src/code-highlighting.js +84 -0
- simultex-0.1.0/browser-ui/src/copy-source.js +116 -0
- simultex-0.1.0/browser-ui/src/html-export.js +191 -0
- simultex-0.1.0/browser-ui/src/image-source.js +9 -0
- simultex-0.1.0/browser-ui/src/latex-normalize.js +28 -0
- simultex-0.1.0/browser-ui/src/main.js +1014 -0
- simultex-0.1.0/browser-ui/src/mermaid-support.js +48 -0
- simultex-0.1.0/browser-ui/src/message-records.js +122 -0
- simultex-0.1.0/browser-ui/src/style.css +486 -0
- simultex-0.1.0/browser-ui/src/tui-chrome.js +108 -0
- simultex-0.1.0/browser-ui/test/api-transcript.test.js +342 -0
- simultex-0.1.0/browser-ui/test/code-highlighting.test.js +23 -0
- simultex-0.1.0/browser-ui/test/copy-source.test.js +55 -0
- simultex-0.1.0/browser-ui/test/html-export.test.js +73 -0
- simultex-0.1.0/browser-ui/test/image-source.test.js +35 -0
- simultex-0.1.0/browser-ui/test/latex-normalize.test.js +62 -0
- simultex-0.1.0/browser-ui/test/mermaid-support.test.js +81 -0
- simultex-0.1.0/browser-ui/test/message-records.test.js +204 -0
- simultex-0.1.0/browser-ui/test/tui-chrome.test.js +138 -0
- simultex-0.1.0/pyproject.toml +31 -0
- simultex-0.1.0/scripts/inspect_capture.py +42 -0
- simultex-0.1.0/scripts/replay_capture.py +58 -0
- simultex-0.1.0/src/simultex/__init__.py +3 -0
- simultex-0.1.0/src/simultex/browser.py +329 -0
- simultex-0.1.0/src/simultex/browser_assets/KaTeX_AMS-Regular-CYEKBG2K.woff +0 -0
- simultex-0.1.0/src/simultex/browser_assets/KaTeX_AMS-Regular-JKX5W2C4.ttf +0 -0
- simultex-0.1.0/src/simultex/browser_assets/KaTeX_AMS-Regular-U6PRYMIZ.woff2 +0 -0
- simultex-0.1.0/src/simultex/browser_assets/KaTeX_Caligraphic-Bold-5QL5CMTE.woff2 +0 -0
- simultex-0.1.0/src/simultex/browser_assets/KaTeX_Caligraphic-Bold-WZ3QSGD3.woff +0 -0
- simultex-0.1.0/src/simultex/browser_assets/KaTeX_Caligraphic-Bold-ZTS3R3HK.ttf +0 -0
- simultex-0.1.0/src/simultex/browser_assets/KaTeX_Caligraphic-Regular-3LKEU76G.woff +0 -0
- simultex-0.1.0/src/simultex/browser_assets/KaTeX_Caligraphic-Regular-A7XRTZ5Q.ttf +0 -0
- simultex-0.1.0/src/simultex/browser_assets/KaTeX_Caligraphic-Regular-KX5MEWCF.woff2 +0 -0
- simultex-0.1.0/src/simultex/browser_assets/KaTeX_Fraktur-Bold-2QVFK6NQ.woff2 +0 -0
- simultex-0.1.0/src/simultex/browser_assets/KaTeX_Fraktur-Bold-T4SWXBMT.woff +0 -0
- simultex-0.1.0/src/simultex/browser_assets/KaTeX_Fraktur-Bold-WGHVTYOR.ttf +0 -0
- simultex-0.1.0/src/simultex/browser_assets/KaTeX_Fraktur-Regular-2PEIFJSJ.woff2 +0 -0
- simultex-0.1.0/src/simultex/browser_assets/KaTeX_Fraktur-Regular-5U4OPH2X.ttf +0 -0
- simultex-0.1.0/src/simultex/browser_assets/KaTeX_Fraktur-Regular-PQMHCIK6.woff +0 -0
- simultex-0.1.0/src/simultex/browser_assets/KaTeX_Main-Bold-2GA4IZIN.woff +0 -0
- simultex-0.1.0/src/simultex/browser_assets/KaTeX_Main-Bold-W5FBVCZM.ttf +0 -0
- simultex-0.1.0/src/simultex/browser_assets/KaTeX_Main-Bold-YP5VVQRP.woff2 +0 -0
- simultex-0.1.0/src/simultex/browser_assets/KaTeX_Main-BoldItalic-4P4C7HJH.woff +0 -0
- simultex-0.1.0/src/simultex/browser_assets/KaTeX_Main-BoldItalic-N4V3DX7S.woff2 +0 -0
- simultex-0.1.0/src/simultex/browser_assets/KaTeX_Main-BoldItalic-ODMLBJJQ.ttf +0 -0
- simultex-0.1.0/src/simultex/browser_assets/KaTeX_Main-Italic-I43T2HSR.ttf +0 -0
- simultex-0.1.0/src/simultex/browser_assets/KaTeX_Main-Italic-RELBIK7M.woff2 +0 -0
- simultex-0.1.0/src/simultex/browser_assets/KaTeX_Main-Italic-SASNQFN2.woff +0 -0
- simultex-0.1.0/src/simultex/browser_assets/KaTeX_Main-Regular-ARRPAO67.woff2 +0 -0
- simultex-0.1.0/src/simultex/browser_assets/KaTeX_Main-Regular-P5I74A2A.woff +0 -0
- simultex-0.1.0/src/simultex/browser_assets/KaTeX_Main-Regular-W74P5G27.ttf +0 -0
- simultex-0.1.0/src/simultex/browser_assets/KaTeX_Math-BoldItalic-6EBV3DK5.woff +0 -0
- simultex-0.1.0/src/simultex/browser_assets/KaTeX_Math-BoldItalic-K4WTGH3J.woff2 +0 -0
- simultex-0.1.0/src/simultex/browser_assets/KaTeX_Math-BoldItalic-VB447A4D.ttf +0 -0
- simultex-0.1.0/src/simultex/browser_assets/KaTeX_Math-Italic-6KGCHLFN.woff2 +0 -0
- simultex-0.1.0/src/simultex/browser_assets/KaTeX_Math-Italic-KKK3USB2.woff +0 -0
- simultex-0.1.0/src/simultex/browser_assets/KaTeX_Math-Italic-SON4MRCA.ttf +0 -0
- simultex-0.1.0/src/simultex/browser_assets/KaTeX_SansSerif-Bold-RRNVJFFW.woff2 +0 -0
- simultex-0.1.0/src/simultex/browser_assets/KaTeX_SansSerif-Bold-STQ6RXC7.ttf +0 -0
- simultex-0.1.0/src/simultex/browser_assets/KaTeX_SansSerif-Bold-X5M5EMOD.woff +0 -0
- simultex-0.1.0/src/simultex/browser_assets/KaTeX_SansSerif-Italic-HMPFTM52.woff2 +0 -0
- simultex-0.1.0/src/simultex/browser_assets/KaTeX_SansSerif-Italic-PSN4QKYX.woff +0 -0
- simultex-0.1.0/src/simultex/browser_assets/KaTeX_SansSerif-Italic-WTBAZBGY.ttf +0 -0
- simultex-0.1.0/src/simultex/browser_assets/KaTeX_SansSerif-Regular-2TL3USAE.ttf +0 -0
- simultex-0.1.0/src/simultex/browser_assets/KaTeX_SansSerif-Regular-OQCII6EP.woff +0 -0
- simultex-0.1.0/src/simultex/browser_assets/KaTeX_SansSerif-Regular-XIQ62X4E.woff2 +0 -0
- simultex-0.1.0/src/simultex/browser_assets/KaTeX_Script-Regular-72OLXYNA.ttf +0 -0
- simultex-0.1.0/src/simultex/browser_assets/KaTeX_Script-Regular-A5IFOEBS.woff +0 -0
- simultex-0.1.0/src/simultex/browser_assets/KaTeX_Script-Regular-APUWIHLP.woff2 +0 -0
- simultex-0.1.0/src/simultex/browser_assets/KaTeX_Size1-Regular-4HRHTS65.woff +0 -0
- simultex-0.1.0/src/simultex/browser_assets/KaTeX_Size1-Regular-5LRUTBFT.woff2 +0 -0
- simultex-0.1.0/src/simultex/browser_assets/KaTeX_Size1-Regular-7K6AASVL.ttf +0 -0
- simultex-0.1.0/src/simultex/browser_assets/KaTeX_Size2-Regular-222HN3GT.ttf +0 -0
- simultex-0.1.0/src/simultex/browser_assets/KaTeX_Size2-Regular-K5ZHAIS6.woff +0 -0
- simultex-0.1.0/src/simultex/browser_assets/KaTeX_Size2-Regular-LELKET5D.woff2 +0 -0
- simultex-0.1.0/src/simultex/browser_assets/KaTeX_Size3-Regular-TLFPAHDE.woff +0 -0
- simultex-0.1.0/src/simultex/browser_assets/KaTeX_Size3-Regular-UFCO6WCA.ttf +0 -0
- simultex-0.1.0/src/simultex/browser_assets/KaTeX_Size3-Regular-WQRQ47UD.woff2 +0 -0
- simultex-0.1.0/src/simultex/browser_assets/KaTeX_Size4-Regular-7PGNVPQK.ttf +0 -0
- simultex-0.1.0/src/simultex/browser_assets/KaTeX_Size4-Regular-CDMV7U5C.woff2 +0 -0
- simultex-0.1.0/src/simultex/browser_assets/KaTeX_Size4-Regular-PKMWZHNC.woff +0 -0
- simultex-0.1.0/src/simultex/browser_assets/KaTeX_Typewriter-Regular-3F5K6SQ6.ttf +0 -0
- simultex-0.1.0/src/simultex/browser_assets/KaTeX_Typewriter-Regular-MJMFSK64.woff +0 -0
- simultex-0.1.0/src/simultex/browser_assets/KaTeX_Typewriter-Regular-VBYJ4NRC.woff2 +0 -0
- simultex-0.1.0/src/simultex/browser_assets/app.css +1 -0
- simultex-0.1.0/src/simultex/browser_assets/app.js +3683 -0
- simultex-0.1.0/src/simultex/browser_assets/index.html +22 -0
- simultex-0.1.0/src/simultex/cli.py +369 -0
- simultex-0.1.0/src/simultex/codex_history.py +330 -0
- simultex-0.1.0/src/simultex/model_proxy.py +961 -0
- simultex-0.1.0/src/simultex/protocol.py +218 -0
- simultex-0.1.0/src/simultex/pty_proxy.py +166 -0
- simultex-0.1.0/src/simultex/render.py +234 -0
- simultex-0.1.0/src/simultex/screen.py +333 -0
- simultex-0.1.0/src/simultex/stream.py +276 -0
- simultex-0.1.0/tests/test_browser.py +172 -0
- simultex-0.1.0/tests/test_codex_history.py +200 -0
- simultex-0.1.0/tests/test_model_proxy.py +793 -0
- simultex-0.1.0/tests/test_protocol.py +72 -0
- simultex-0.1.0/tests/test_render.py +90 -0
- simultex-0.1.0/tests/test_screen.py +150 -0
- simultex-0.1.0/tests/test_stream.py +121 -0
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.
|
simultex-0.1.0/PKG-INFO
ADDED
|
@@ -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
|
simultex-0.1.0/README.md
ADDED
|
@@ -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,6 @@
|
|
|
1
|
+
[38;2;0;255;65m [38;2;0;253;64m█[38;2;0;252;64m█[38;2;0;250;63m█[38;2;0;249;62m█[38;2;0;247;62m█[38;2;0;246;61m█[38;2;0;244;60m█[38;2;0;242;60m╗[38;2;0;241;59m [38;2;0;239;58m█[38;2;0;238;58m█[38;2;0;236;57m╗[38;2;0;234;56m [38;2;0;233;56m█[38;2;0;231;55m█[38;2;0;230;54m█[38;2;0;228;54m╗[38;2;0;227;53m [38;2;0;225;52m [38;2;0;223;51m [38;2;0;222;51m█[38;2;0;220;50m█[38;2;0;219;49m█[38;2;0;217;49m╗[38;2;0;216;48m [38;2;0;214;47m█[38;2;0;212;47m█[38;2;0;211;46m╗[38;2;0;209;45m [38;2;0;208;45m [38;2;0;206;44m [38;2;0;205;43m█[38;2;0;203;43m█[38;2;0;201;42m╗[38;2;0;200;41m [38;2;0;198;41m█[38;2;0;197;40m█[38;2;0;195;39m╗[38;2;0;193;39m [38;2;0;192;38m [38;2;0;190;37m [38;2;0;189;37m [38;2;0;187;36m [38;2;0;186;35m [38;2;0;184;35m█[38;2;0;182;34m█[38;2;0;181;33m█[38;2;0;179;33m█[38;2;0;178;32m█[38;2;0;176;31m█[38;2;0;175;31m█[38;2;0;173;30m█[38;2;0;171;29m╗[38;2;0;170;28m [38;2;0;168;28m█[38;2;0;167;27m█[38;2;0;165;26m█[38;2;0;164;26m█[38;2;0;162;25m█[38;2;0;160;24m█[38;2;0;159;24m█[38;2;0;157;23m╗[38;2;0;156;22m [38;2;0;154;22m█[38;2;0;152;21m█[38;2;0;151;20m╗[38;2;0;149;20m [38;2;0;148;19m [38;2;0;146;18m█[38;2;0;145;18m█[38;2;0;143;17m╗[39m
|
|
2
|
+
[38;2;0;255;65m [38;2;0;253;64m█[38;2;0;252;64m█[38;2;0;250;63m╔[38;2;0;249;62m═[38;2;0;247;62m═[38;2;0;246;61m═[38;2;0;244;60m═[38;2;0;242;60m╝[38;2;0;241;59m [38;2;0;239;58m█[38;2;0;238;58m█[38;2;0;236;57m║[38;2;0;234;56m [38;2;0;233;56m█[38;2;0;231;55m█[38;2;0;230;54m█[38;2;0;228;54m█[38;2;0;227;53m╗[38;2;0;225;52m [38;2;0;223;51m█[38;2;0;222;51m█[38;2;0;220;50m█[38;2;0;219;49m█[38;2;0;217;49m║[38;2;0;216;48m [38;2;0;214;47m█[38;2;0;212;47m█[38;2;0;211;46m║[38;2;0;209;45m [38;2;0;208;45m [38;2;0;206;44m [38;2;0;205;43m█[38;2;0;203;43m█[38;2;0;201;42m║[38;2;0;200;41m [38;2;0;198;41m█[38;2;0;197;40m█[38;2;0;195;39m║[38;2;0;193;39m [38;2;0;192;38m [38;2;0;190;37m [38;2;0;189;37m [38;2;0;187;36m [38;2;0;186;35m [38;2;0;184;35m╚[38;2;0;182;34m═[38;2;0;181;33m═[38;2;0;179;33m█[38;2;0;178;32m█[38;2;0;176;31m╔[38;2;0;175;31m═[38;2;0;173;30m═[38;2;0;171;29m╝[38;2;0;170;28m [38;2;0;168;28m█[38;2;0;167;27m█[38;2;0;165;26m╔[38;2;0;164;26m═[38;2;0;162;25m═[38;2;0;160;24m═[38;2;0;159;24m═[38;2;0;157;23m╝[38;2;0;156;22m [38;2;0;154;22m╚[38;2;0;152;21m█[38;2;0;151;20m█[38;2;0;149;20m╗[38;2;0;148;19m█[38;2;0;146;18m█[38;2;0;145;18m╔[38;2;0;143;17m╝[39m
|
|
3
|
+
[38;2;0;255;65m [38;2;0;253;64m█[38;2;0;252;64m█[38;2;0;250;63m█[38;2;0;249;62m█[38;2;0;247;62m█[38;2;0;246;61m█[38;2;0;244;60m█[38;2;0;242;60m╗[38;2;0;241;59m [38;2;0;239;58m█[38;2;0;238;58m█[38;2;0;236;57m║[38;2;0;234;56m [38;2;0;233;56m█[38;2;0;231;55m█[38;2;0;230;54m╔[38;2;0;228;54m█[38;2;0;227;53m█[38;2;0;225;52m█[38;2;0;223;51m█[38;2;0;222;51m╔[38;2;0;220;50m█[38;2;0;219;49m█[38;2;0;217;49m║[38;2;0;216;48m [38;2;0;214;47m█[38;2;0;212;47m█[38;2;0;211;46m║[38;2;0;209;45m [38;2;0;208;45m [38;2;0;206;44m [38;2;0;205;43m█[38;2;0;203;43m█[38;2;0;201;42m║[38;2;0;200;41m [38;2;0;198;41m█[38;2;0;197;40m█[38;2;0;195;39m║[38;2;0;193;39m [38;2;0;192;38m [38;2;0;190;37m [38;2;0;189;37m [38;2;0;187;36m [38;2;0;186;35m [38;2;0;184;35m [38;2;0;182;34m [38;2;0;181;33m [38;2;0;179;33m█[38;2;0;178;32m█[38;2;0;176;31m║[38;2;0;175;31m [38;2;0;173;30m [38;2;0;171;29m [38;2;0;170;28m [38;2;0;168;28m█[38;2;0;167;27m█[38;2;0;165;26m█[38;2;0;164;26m█[38;2;0;162;25m█[38;2;0;160;24m╗[38;2;0;159;24m [38;2;0;157;23m [38;2;0;156;22m [38;2;0;154;22m [38;2;0;152;21m╚[38;2;0;151;20m█[38;2;0;149;20m█[38;2;0;148;19m█[38;2;0;146;18m╔[38;2;0;145;18m╝[38;2;0;143;17m [39m
|
|
4
|
+
[38;2;0;255;65m [38;2;0;253;64m╚[38;2;0;252;64m═[38;2;0;250;63m═[38;2;0;249;62m═[38;2;0;247;62m═[38;2;0;246;61m█[38;2;0;244;60m█[38;2;0;242;60m║[38;2;0;241;59m [38;2;0;239;58m█[38;2;0;238;58m█[38;2;0;236;57m║[38;2;0;234;56m [38;2;0;233;56m█[38;2;0;231;55m█[38;2;0;230;54m║[38;2;0;228;54m╚[38;2;0;227;53m█[38;2;0;225;52m█[38;2;0;223;51m╔[38;2;0;222;51m╝[38;2;0;220;50m█[38;2;0;219;49m█[38;2;0;217;49m║[38;2;0;216;48m [38;2;0;214;47m█[38;2;0;212;47m█[38;2;0;211;46m║[38;2;0;209;45m [38;2;0;208;45m [38;2;0;206;44m [38;2;0;205;43m█[38;2;0;203;43m█[38;2;0;201;42m║[38;2;0;200;41m [38;2;0;198;41m█[38;2;0;197;40m█[38;2;0;195;39m║[38;2;0;193;39m [38;2;0;192;38m [38;2;0;190;37m [38;2;0;189;37m [38;2;0;187;36m [38;2;0;186;35m [38;2;0;184;35m [38;2;0;182;34m [38;2;0;181;33m [38;2;0;179;33m█[38;2;0;178;32m█[38;2;0;176;31m║[38;2;0;175;31m [38;2;0;173;30m [38;2;0;171;29m [38;2;0;170;28m [38;2;0;168;28m█[38;2;0;167;27m█[38;2;0;165;26m╔[38;2;0;164;26m═[38;2;0;162;25m═[38;2;0;160;24m╝[38;2;0;159;24m [38;2;0;157;23m [38;2;0;156;22m [38;2;0;154;22m [38;2;0;152;21m█[38;2;0;151;20m█[38;2;0;149;20m╔[38;2;0;148;19m█[38;2;0;146;18m█[38;2;0;145;18m╗[38;2;0;143;17m [39m
|
|
5
|
+
[38;2;0;255;65m [38;2;0;253;64m█[38;2;0;252;64m█[38;2;0;250;63m█[38;2;0;249;62m█[38;2;0;247;62m█[38;2;0;246;61m█[38;2;0;244;60m█[38;2;0;242;60m║[38;2;0;241;59m [38;2;0;239;58m█[38;2;0;238;58m█[38;2;0;236;57m║[38;2;0;234;56m [38;2;0;233;56m█[38;2;0;231;55m█[38;2;0;230;54m║[38;2;0;228;54m [38;2;0;227;53m╚[38;2;0;225;52m═[38;2;0;223;51m╝[38;2;0;222;51m [38;2;0;220;50m█[38;2;0;219;49m█[38;2;0;217;49m║[38;2;0;216;48m [38;2;0;214;47m╚[38;2;0;212;47m█[38;2;0;211;46m█[38;2;0;209;45m█[38;2;0;208;45m█[38;2;0;206;44m█[38;2;0;205;43m█[38;2;0;203;43m╔[38;2;0;201;42m╝[38;2;0;200;41m [38;2;0;198;41m█[38;2;0;197;40m█[38;2;0;195;39m█[38;2;0;193;39m█[38;2;0;192;38m█[38;2;0;190;37m█[38;2;0;189;37m█[38;2;0;187;36m╗[38;2;0;186;35m [38;2;0;184;35m [38;2;0;182;34m [38;2;0;181;33m [38;2;0;179;33m█[38;2;0;178;32m█[38;2;0;176;31m║[38;2;0;175;31m [38;2;0;173;30m [38;2;0;171;29m [38;2;0;170;28m [38;2;0;168;28m█[38;2;0;167;27m█[38;2;0;165;26m█[38;2;0;164;26m█[38;2;0;162;25m█[38;2;0;160;24m█[38;2;0;159;24m█[38;2;0;157;23m╗[38;2;0;156;22m [38;2;0;154;22m█[38;2;0;152;21m█[38;2;0;151;20m╔[38;2;0;149;20m╝[38;2;0;148;19m [38;2;0;146;18m█[38;2;0;145;18m█[38;2;0;143;17m╗[39m
|
|
6
|
+
[38;2;0;255;65m [38;2;0;253;64m╚[38;2;0;252;64m═[38;2;0;250;63m═[38;2;0;249;62m═[38;2;0;247;62m═[38;2;0;246;61m═[38;2;0;244;60m═[38;2;0;242;60m╝[38;2;0;241;59m [38;2;0;239;58m╚[38;2;0;238;58m═[38;2;0;236;57m╝[38;2;0;234;56m [38;2;0;233;56m╚[38;2;0;231;55m═[38;2;0;230;54m╝[38;2;0;228;54m [38;2;0;227;53m [38;2;0;225;52m [38;2;0;223;51m [38;2;0;222;51m [38;2;0;220;50m╚[38;2;0;219;49m═[38;2;0;217;49m╝[38;2;0;216;48m [38;2;0;214;47m [38;2;0;212;47m╚[38;2;0;211;46m═[38;2;0;209;45m═[38;2;0;208;45m═[38;2;0;206;44m═[38;2;0;205;43m═[38;2;0;203;43m╝[38;2;0;201;42m [38;2;0;200;41m [38;2;0;198;41m╚[38;2;0;197;40m═[38;2;0;195;39m═[38;2;0;193;39m═[38;2;0;192;38m═[38;2;0;190;37m═[38;2;0;189;37m═[38;2;0;187;36m╝[38;2;0;186;35m [38;2;0;184;35m [38;2;0;182;34m [38;2;0;181;33m [38;2;0;179;33m╚[38;2;0;178;32m═[38;2;0;176;31m╝[38;2;0;175;31m [38;2;0;173;30m [38;2;0;171;29m [38;2;0;170;28m [38;2;0;168;28m╚[38;2;0;167;27m═[38;2;0;165;26m═[38;2;0;164;26m═[38;2;0;162;25m═[38;2;0;160;24m═[38;2;0;159;24m═[38;2;0;157;23m╝[38;2;0;156;22m [38;2;0;154;22m╚[38;2;0;152;21m═[38;2;0;151;20m╝[38;2;0;149;20m [38;2;0;148;19m [38;2;0;146;18m╚[38;2;0;145;18m═[38;2;0;143;17m╝[39m[0m
|