terminalboard 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.
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 dongfangyixi
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,249 @@
1
+ Metadata-Version: 2.4
2
+ Name: terminalboard
3
+ Version: 0.1.0
4
+ Summary: A pure-SSH terminal TensorBoard scalar viewer — live scalar curves in iTerm2, no browser, no X11, no port forwarding.
5
+ Author: dongfangyixi
6
+ License: MIT
7
+ Project-URL: Repository, https://github.com/dongfangyixi/terminalboard
8
+ Keywords: tensorboard,terminal,iterm2,plotext,ssh,ml
9
+ Requires-Python: >=3.9
10
+ Description-Content-Type: text/markdown
11
+ License-File: LICENSE
12
+ Requires-Dist: plotext>=5.2
13
+ Provides-Extra: tb
14
+ Requires-Dist: tensorboard>=2.9; extra == "tb"
15
+ Provides-Extra: hq
16
+ Requires-Dist: matplotlib>=3.5; extra == "hq"
17
+ Provides-Extra: full
18
+ Requires-Dist: tensorboard>=2.9; extra == "full"
19
+ Requires-Dist: matplotlib>=3.5; extra == "full"
20
+ Dynamic: license-file
21
+
22
+ # terminalboard
23
+
24
+ A **pure-SSH terminal TensorBoard scalar viewer**.
25
+
26
+ Train on a remote box, SSH in, and watch your **live-updating scalar curves
27
+ right inside the terminal** — crisp Unicode/braille text by default, or real
28
+ iTerm2 inline images with `--hq`. No browser, no X11, no port forwarding.
29
+
30
+ ```
31
+ ssh remote
32
+ terminalboard path/to/tb_logs
33
+ ```
34
+
35
+ ---
36
+
37
+ ## Why this exists
38
+
39
+ The usual TensorBoard workflow over SSH is painful: you either forward a port
40
+ (`ssh -L 6006:...`) and open a browser, or you give up and `grep` the logs. On a
41
+ headless training box you often can't do either cleanly. terminalboard reads the
42
+ event files directly and draws the curves in the terminal, so a plain SSH session
43
+ is all you need.
44
+
45
+ ## How it works
46
+
47
+ 1. **Read** the TensorBoard event files (`events.out.tfevents.*`) from a log
48
+ directory (scanned recursively for multiple runs) and collect the scalar series.
49
+ 2. **Render** the selected curves — by default as Unicode/braille **text** (works
50
+ in any terminal), or with `--hq` as a matplotlib PNG.
51
+ 3. **Display** them: braille text is printed directly; the `--hq` PNG is streamed
52
+ via the [iTerm2 inline-image protocol](https://iterm2.com/documentation-images.html)
53
+ (built in-memory, no temp file).
54
+ 4. **Watch** the log directory and re-render whenever new data lands, giving a
55
+ live dashboard. Repaints are **flicker-free**: the alternate screen buffer is
56
+ redrawn in place under synchronized output (DEC mode 2026), and an idle
57
+ dashboard isn't repainted at all (only changed data/views trigger a redraw).
58
+
59
+ ## Language: Python
60
+
61
+ The viewer is written in **Python**, chosen after weighing it against a
62
+ Next.js/TypeScript implementation:
63
+
64
+ | Factor | Python ✅ | Next.js / TypeScript |
65
+ |---|---|---|
66
+ | Reading TB event logs | First-class. The format is TFRecord-framed protobuf; `tensorboard`/`tbparse` parse it natively, or a small self-contained parser does. | No mature TFRecord/TB-protobuf reader — you'd reimplement framing + protobuf decoding by hand. |
67
+ | High-quality curves | matplotlib → PNG → iTerm2 inline image. | No native terminal-plotting story. |
68
+ | Live tailing | `watchdog` / offset polling. | Doable, no advantage. |
69
+ | Fit for purpose | It's a terminal CLI, and Python is the lingua franca of the ML/TensorBoard ecosystem. | Next.js is a web/SSR framework; its core value (React, routing, browser) is unused here. |
70
+ | This machine | Python 3.12 already present. | Node isn't installed. |
71
+
72
+ The decisive factor: TensorBoard logs are a TF-specific protobuf format with
73
+ first-class Python tooling, and the target terminal (iTerm2) supports an
74
+ inline-image protocol — so we can render genuine matplotlib-quality curves rather
75
+ than ASCII art.
76
+
77
+ ## Two rendering backends
78
+
79
+ - **Default — text/braille** (`plotext`): curves drawn directly as Unicode/braille
80
+ characters. No image is generated, so it works over **any** SSH session, tmux, or
81
+ plain terminal, and redraws instantly. *(See the example below.)*
82
+ - **`--hq` — iTerm2 image**: matplotlib rendered to an **in-memory** PNG (no temp
83
+ file) and streamed via the iTerm2 inline-image protocol. Pixel-perfect, but only
84
+ in iTerm2/WezTerm-class terminals.
85
+ - **`--auto`**: use the image renderer in iTerm2-class terminals, else fall back to
86
+ text automatically.
87
+
88
+ ## Two parsing backends
89
+
90
+ - **Default** (no flag): parse with the official `tensorboard` library
91
+ (`EventAccumulator`) — most robust, handles exotic summary encodings. If
92
+ `tensorboard` isn't installed, terminalboard falls back to `--light` automatically.
93
+ - **`--light`**: a self-contained pure-Python TFRecord + protobuf-wire parser with
94
+ no heavy dependencies — tiny install, fast startup, ideal for a thin remote box.
95
+
96
+ The two axes are independent: pick any parser with any renderer.
97
+
98
+ ## Install
99
+
100
+ > ⚠️ **Not published to PyPI yet**, so `pip install terminalboard` won't work
101
+ > until it is. Install from source for now.
102
+
103
+ **From a clone** (recommended for development):
104
+
105
+ ```bash
106
+ git clone https://github.com/dongfangyixi/terminalboard.git
107
+ cd terminalboard
108
+ pip install -e '.[full]' # editable; full = tensorboard + matplotlib
109
+ ```
110
+
111
+ **Directly from GitHub:**
112
+
113
+ ```bash
114
+ pip install "git+https://github.com/dongfangyixi/terminalboard.git"
115
+ # with extras (default parser + --hq image renderer):
116
+ pip install "terminalboard[full] @ git+https://github.com/dongfangyixi/terminalboard.git"
117
+ ```
118
+
119
+ The base install pulls only `plotext` — enough for the text renderer and the
120
+ dependency-free `--light` parser. Extras add the heavy bits:
121
+
122
+ | Extra | Adds | Enables |
123
+ |---|---|---|
124
+ | `[tb]` | `tensorboard` | the default (robust) parser |
125
+ | `[hq]` | `matplotlib` | the `--hq` iTerm2 image renderer |
126
+ | `[full]` | both | everything |
127
+
128
+ <details>
129
+ <summary>Once it's on PyPI</summary>
130
+
131
+ ```bash
132
+ pip install terminalboard # text renderer + pure-Python --light parser
133
+ pip install 'terminalboard[tb]' # + tensorboard (default parser)
134
+ pip install 'terminalboard[hq]' # + matplotlib (--hq image renderer)
135
+ pip install 'terminalboard[full]' # everything
136
+ ```
137
+
138
+ Publishing checklist: `pip install build twine` → `python -m build` →
139
+ `twine upload dist/*` (needs a PyPI account + the name `terminalboard` being free).
140
+ </details>
141
+
142
+ ## Usage
143
+
144
+ ```
145
+ terminalboard LOGDIR [options]
146
+
147
+ LOGDIR / --logdir directory of TensorBoard event files (scanned recursively)
148
+ --light use the dependency-free pure-Python parser
149
+ --hq / --text/--auto image / text (default) / auto-detect renderer
150
+ --tags GLOB filter tags, e.g. 'train/*loss*,val/*' (live-editable: t)
151
+ --experiments GLOB filter experiments/runs (live-editable: f)
152
+ --smooth ALPHA EMA smoothing weight in [0,1) (default: 0.6; 0 disables)
153
+ --grid RxC panels per page (default: 2x3)
154
+ --interval SECONDS live refresh interval (default: 2.0)
155
+ --once render a single frame and exit
156
+ --list list all scalar tags and exit
157
+ ```
158
+
159
+ ```bash
160
+ terminalboard ../tb_logs # live text dashboard
161
+ terminalboard ../tb_logs --tags 'train/*loss*' # filter to loss curves
162
+ terminalboard ../tb_logs --hq --grid 2x2 # high-quality iTerm2 images
163
+ terminalboard ../tb_logs --light --once # one frame, no deps, no loop
164
+ ```
165
+
166
+ ### Interactive controls (live mode)
167
+
168
+ | Key | Action |
169
+ |---|---|
170
+ | `q` | quit |
171
+ | `n` / `space`, `p` | next / previous page of tags |
172
+ | `t` | edit the **tag** filter live (Enter apply · Esc cancel · ^U clear) |
173
+ | `f` | edit the **experiment/run** filter live |
174
+ | `r` | refresh now |
175
+ | `+` / `-` | more / less smoothing |
176
+ | `0` | disable smoothing |
177
+ | `z` / `Z` | zoom out / in — panels per page: `1·2·4·6·9·12·16·24·36` |
178
+
179
+ Filters match per comma-separated token: a plain word is a case-insensitive
180
+ **substring** (`loss` → `train/loss`, `val/loss`), while `* ? [` make it a glob
181
+ (`train/*loss*`). The plots re-filter as you type. Tag and experiment filters
182
+ combine — a tag only shows if a currently-visible experiment has it.
183
+
184
+ ### Multiple experiments
185
+
186
+ When a logdir holds several runs, their curves are **overlaid in each panel**,
187
+ each experiment in its own color, with a legend above the grid. Colors are
188
+ **stable** — an experiment keeps its color no matter which others you filter in
189
+ or out — so you can always tell which curve is which. Use `f` (or
190
+ `--experiments`) to focus on a subset.
191
+
192
+ In the filter prompt: **←/→** move the cursor, **↑/↓** recall previous patterns,
193
+ **Home/End** (or `^A`/`^E`) jump, `^U` clears. If a pattern matches nothing the
194
+ current plots are **kept** (no jarring re-layout) and a red warning is shown
195
+ until you fix or cancel it.
196
+
197
+ ### Example (text renderer)
198
+
199
+ ```
200
+ train/text_token_accuracy
201
+ ┌──────────────────────────────────────────────────────────────────────────┐
202
+ 0.97┤ ⡠⣄⣀⣀⡠⠖⠦⠤⠤⠖⠒⠒⠒⠒⠉⠙⠒⠒⠉⠉⠉⠉⠉│
203
+ │ ⣠⠒⠒⠒⠞ │
204
+ │ ⡤⠲⠴⠤⠇ │
205
+ 0.82┤ ⢰⠁ │
206
+ │ ⢠⠒⠲⠤⠎ │
207
+ 0.67┤ ⣀⣀⣀⣠⠃ │
208
+ │ ⢀⠔⠒⠒⠲⠇ │
209
+ 0.52┤ ⣀⣀⣀⣀⣀⣀⣀⣀⡠⠤⠤⠤⠤⠞⠉⠉⠉⠛ │
210
+ │ ⡴⠲⠒⠉⠉⠉⠉⠉⠁ │
211
+ └┬─────────────────┬──────────────────┬─────────────────┬─────────────────┬┘
212
+ 10 1510 3010 4510 6010
213
+ ```
214
+
215
+ ## Roadmap
216
+
217
+ - [x] **Reader — `--light`**: pure-Python TFRecord + protobuf-wire parser
218
+ (Event → Summary → Value; both `simple_value` and tensor-encoded scalars).
219
+ - [x] **Reader — default**: `tensorboard` `EventAccumulator` backend with a shared
220
+ `ScalarSeries` data model and recursive multi-run logdir scan.
221
+ - [x] **Render — text**: `plotext` braille grid, the default (no image).
222
+ - [x] **Render — `--hq`**: matplotlib grid → in-memory PNG → iTerm2 inline image.
223
+ - [x] **Live loop + CLI**: flicker-free repaints, keyboard navigation; argparse front end.
224
+ - [x] **Zoom** (`z`/`Z`): 1·2·4·6·9·12·16·24·36 panels per page.
225
+ - [x] **Interactive filters** (`t`/`f`): live tag & experiment filtering with a
226
+ line editor (cursor, history, no-match warning).
227
+ - [x] **Multi-experiment overlay** with stable per-run colors and a legend.
228
+ - [ ] Publish to PyPI.
229
+ - [ ] Sixel fallback for non-iTerm2 terminals; config file; per-tag y-axis options.
230
+
231
+ ## Status
232
+
233
+ Working. The default text dashboard, `--hq` iTerm2 images, the `--light` parser,
234
+ multi-experiment overlay, zoom, and live interactive tag/experiment filtering are
235
+ all functional. Test event logs are kept in the **parent working folder** (e.g.
236
+ `../tb_logs/`), deliberately outside this repository — they're real training data
237
+ and don't belong in a public repo.
238
+
239
+ ## Development
240
+
241
+ ```bash
242
+ python3 -m venv .venv
243
+ .venv/bin/pip install -e '.[full]'
244
+ .venv/bin/terminalboard ../tb_logs --once
245
+ ```
246
+
247
+ ## License
248
+
249
+ [MIT](LICENSE).
@@ -0,0 +1,228 @@
1
+ # terminalboard
2
+
3
+ A **pure-SSH terminal TensorBoard scalar viewer**.
4
+
5
+ Train on a remote box, SSH in, and watch your **live-updating scalar curves
6
+ right inside the terminal** — crisp Unicode/braille text by default, or real
7
+ iTerm2 inline images with `--hq`. No browser, no X11, no port forwarding.
8
+
9
+ ```
10
+ ssh remote
11
+ terminalboard path/to/tb_logs
12
+ ```
13
+
14
+ ---
15
+
16
+ ## Why this exists
17
+
18
+ The usual TensorBoard workflow over SSH is painful: you either forward a port
19
+ (`ssh -L 6006:...`) and open a browser, or you give up and `grep` the logs. On a
20
+ headless training box you often can't do either cleanly. terminalboard reads the
21
+ event files directly and draws the curves in the terminal, so a plain SSH session
22
+ is all you need.
23
+
24
+ ## How it works
25
+
26
+ 1. **Read** the TensorBoard event files (`events.out.tfevents.*`) from a log
27
+ directory (scanned recursively for multiple runs) and collect the scalar series.
28
+ 2. **Render** the selected curves — by default as Unicode/braille **text** (works
29
+ in any terminal), or with `--hq` as a matplotlib PNG.
30
+ 3. **Display** them: braille text is printed directly; the `--hq` PNG is streamed
31
+ via the [iTerm2 inline-image protocol](https://iterm2.com/documentation-images.html)
32
+ (built in-memory, no temp file).
33
+ 4. **Watch** the log directory and re-render whenever new data lands, giving a
34
+ live dashboard. Repaints are **flicker-free**: the alternate screen buffer is
35
+ redrawn in place under synchronized output (DEC mode 2026), and an idle
36
+ dashboard isn't repainted at all (only changed data/views trigger a redraw).
37
+
38
+ ## Language: Python
39
+
40
+ The viewer is written in **Python**, chosen after weighing it against a
41
+ Next.js/TypeScript implementation:
42
+
43
+ | Factor | Python ✅ | Next.js / TypeScript |
44
+ |---|---|---|
45
+ | Reading TB event logs | First-class. The format is TFRecord-framed protobuf; `tensorboard`/`tbparse` parse it natively, or a small self-contained parser does. | No mature TFRecord/TB-protobuf reader — you'd reimplement framing + protobuf decoding by hand. |
46
+ | High-quality curves | matplotlib → PNG → iTerm2 inline image. | No native terminal-plotting story. |
47
+ | Live tailing | `watchdog` / offset polling. | Doable, no advantage. |
48
+ | Fit for purpose | It's a terminal CLI, and Python is the lingua franca of the ML/TensorBoard ecosystem. | Next.js is a web/SSR framework; its core value (React, routing, browser) is unused here. |
49
+ | This machine | Python 3.12 already present. | Node isn't installed. |
50
+
51
+ The decisive factor: TensorBoard logs are a TF-specific protobuf format with
52
+ first-class Python tooling, and the target terminal (iTerm2) supports an
53
+ inline-image protocol — so we can render genuine matplotlib-quality curves rather
54
+ than ASCII art.
55
+
56
+ ## Two rendering backends
57
+
58
+ - **Default — text/braille** (`plotext`): curves drawn directly as Unicode/braille
59
+ characters. No image is generated, so it works over **any** SSH session, tmux, or
60
+ plain terminal, and redraws instantly. *(See the example below.)*
61
+ - **`--hq` — iTerm2 image**: matplotlib rendered to an **in-memory** PNG (no temp
62
+ file) and streamed via the iTerm2 inline-image protocol. Pixel-perfect, but only
63
+ in iTerm2/WezTerm-class terminals.
64
+ - **`--auto`**: use the image renderer in iTerm2-class terminals, else fall back to
65
+ text automatically.
66
+
67
+ ## Two parsing backends
68
+
69
+ - **Default** (no flag): parse with the official `tensorboard` library
70
+ (`EventAccumulator`) — most robust, handles exotic summary encodings. If
71
+ `tensorboard` isn't installed, terminalboard falls back to `--light` automatically.
72
+ - **`--light`**: a self-contained pure-Python TFRecord + protobuf-wire parser with
73
+ no heavy dependencies — tiny install, fast startup, ideal for a thin remote box.
74
+
75
+ The two axes are independent: pick any parser with any renderer.
76
+
77
+ ## Install
78
+
79
+ > ⚠️ **Not published to PyPI yet**, so `pip install terminalboard` won't work
80
+ > until it is. Install from source for now.
81
+
82
+ **From a clone** (recommended for development):
83
+
84
+ ```bash
85
+ git clone https://github.com/dongfangyixi/terminalboard.git
86
+ cd terminalboard
87
+ pip install -e '.[full]' # editable; full = tensorboard + matplotlib
88
+ ```
89
+
90
+ **Directly from GitHub:**
91
+
92
+ ```bash
93
+ pip install "git+https://github.com/dongfangyixi/terminalboard.git"
94
+ # with extras (default parser + --hq image renderer):
95
+ pip install "terminalboard[full] @ git+https://github.com/dongfangyixi/terminalboard.git"
96
+ ```
97
+
98
+ The base install pulls only `plotext` — enough for the text renderer and the
99
+ dependency-free `--light` parser. Extras add the heavy bits:
100
+
101
+ | Extra | Adds | Enables |
102
+ |---|---|---|
103
+ | `[tb]` | `tensorboard` | the default (robust) parser |
104
+ | `[hq]` | `matplotlib` | the `--hq` iTerm2 image renderer |
105
+ | `[full]` | both | everything |
106
+
107
+ <details>
108
+ <summary>Once it's on PyPI</summary>
109
+
110
+ ```bash
111
+ pip install terminalboard # text renderer + pure-Python --light parser
112
+ pip install 'terminalboard[tb]' # + tensorboard (default parser)
113
+ pip install 'terminalboard[hq]' # + matplotlib (--hq image renderer)
114
+ pip install 'terminalboard[full]' # everything
115
+ ```
116
+
117
+ Publishing checklist: `pip install build twine` → `python -m build` →
118
+ `twine upload dist/*` (needs a PyPI account + the name `terminalboard` being free).
119
+ </details>
120
+
121
+ ## Usage
122
+
123
+ ```
124
+ terminalboard LOGDIR [options]
125
+
126
+ LOGDIR / --logdir directory of TensorBoard event files (scanned recursively)
127
+ --light use the dependency-free pure-Python parser
128
+ --hq / --text/--auto image / text (default) / auto-detect renderer
129
+ --tags GLOB filter tags, e.g. 'train/*loss*,val/*' (live-editable: t)
130
+ --experiments GLOB filter experiments/runs (live-editable: f)
131
+ --smooth ALPHA EMA smoothing weight in [0,1) (default: 0.6; 0 disables)
132
+ --grid RxC panels per page (default: 2x3)
133
+ --interval SECONDS live refresh interval (default: 2.0)
134
+ --once render a single frame and exit
135
+ --list list all scalar tags and exit
136
+ ```
137
+
138
+ ```bash
139
+ terminalboard ../tb_logs # live text dashboard
140
+ terminalboard ../tb_logs --tags 'train/*loss*' # filter to loss curves
141
+ terminalboard ../tb_logs --hq --grid 2x2 # high-quality iTerm2 images
142
+ terminalboard ../tb_logs --light --once # one frame, no deps, no loop
143
+ ```
144
+
145
+ ### Interactive controls (live mode)
146
+
147
+ | Key | Action |
148
+ |---|---|
149
+ | `q` | quit |
150
+ | `n` / `space`, `p` | next / previous page of tags |
151
+ | `t` | edit the **tag** filter live (Enter apply · Esc cancel · ^U clear) |
152
+ | `f` | edit the **experiment/run** filter live |
153
+ | `r` | refresh now |
154
+ | `+` / `-` | more / less smoothing |
155
+ | `0` | disable smoothing |
156
+ | `z` / `Z` | zoom out / in — panels per page: `1·2·4·6·9·12·16·24·36` |
157
+
158
+ Filters match per comma-separated token: a plain word is a case-insensitive
159
+ **substring** (`loss` → `train/loss`, `val/loss`), while `* ? [` make it a glob
160
+ (`train/*loss*`). The plots re-filter as you type. Tag and experiment filters
161
+ combine — a tag only shows if a currently-visible experiment has it.
162
+
163
+ ### Multiple experiments
164
+
165
+ When a logdir holds several runs, their curves are **overlaid in each panel**,
166
+ each experiment in its own color, with a legend above the grid. Colors are
167
+ **stable** — an experiment keeps its color no matter which others you filter in
168
+ or out — so you can always tell which curve is which. Use `f` (or
169
+ `--experiments`) to focus on a subset.
170
+
171
+ In the filter prompt: **←/→** move the cursor, **↑/↓** recall previous patterns,
172
+ **Home/End** (or `^A`/`^E`) jump, `^U` clears. If a pattern matches nothing the
173
+ current plots are **kept** (no jarring re-layout) and a red warning is shown
174
+ until you fix or cancel it.
175
+
176
+ ### Example (text renderer)
177
+
178
+ ```
179
+ train/text_token_accuracy
180
+ ┌──────────────────────────────────────────────────────────────────────────┐
181
+ 0.97┤ ⡠⣄⣀⣀⡠⠖⠦⠤⠤⠖⠒⠒⠒⠒⠉⠙⠒⠒⠉⠉⠉⠉⠉│
182
+ │ ⣠⠒⠒⠒⠞ │
183
+ │ ⡤⠲⠴⠤⠇ │
184
+ 0.82┤ ⢰⠁ │
185
+ │ ⢠⠒⠲⠤⠎ │
186
+ 0.67┤ ⣀⣀⣀⣠⠃ │
187
+ │ ⢀⠔⠒⠒⠲⠇ │
188
+ 0.52┤ ⣀⣀⣀⣀⣀⣀⣀⣀⡠⠤⠤⠤⠤⠞⠉⠉⠉⠛ │
189
+ │ ⡴⠲⠒⠉⠉⠉⠉⠉⠁ │
190
+ └┬─────────────────┬──────────────────┬─────────────────┬─────────────────┬┘
191
+ 10 1510 3010 4510 6010
192
+ ```
193
+
194
+ ## Roadmap
195
+
196
+ - [x] **Reader — `--light`**: pure-Python TFRecord + protobuf-wire parser
197
+ (Event → Summary → Value; both `simple_value` and tensor-encoded scalars).
198
+ - [x] **Reader — default**: `tensorboard` `EventAccumulator` backend with a shared
199
+ `ScalarSeries` data model and recursive multi-run logdir scan.
200
+ - [x] **Render — text**: `plotext` braille grid, the default (no image).
201
+ - [x] **Render — `--hq`**: matplotlib grid → in-memory PNG → iTerm2 inline image.
202
+ - [x] **Live loop + CLI**: flicker-free repaints, keyboard navigation; argparse front end.
203
+ - [x] **Zoom** (`z`/`Z`): 1·2·4·6·9·12·16·24·36 panels per page.
204
+ - [x] **Interactive filters** (`t`/`f`): live tag & experiment filtering with a
205
+ line editor (cursor, history, no-match warning).
206
+ - [x] **Multi-experiment overlay** with stable per-run colors and a legend.
207
+ - [ ] Publish to PyPI.
208
+ - [ ] Sixel fallback for non-iTerm2 terminals; config file; per-tag y-axis options.
209
+
210
+ ## Status
211
+
212
+ Working. The default text dashboard, `--hq` iTerm2 images, the `--light` parser,
213
+ multi-experiment overlay, zoom, and live interactive tag/experiment filtering are
214
+ all functional. Test event logs are kept in the **parent working folder** (e.g.
215
+ `../tb_logs/`), deliberately outside this repository — they're real training data
216
+ and don't belong in a public repo.
217
+
218
+ ## Development
219
+
220
+ ```bash
221
+ python3 -m venv .venv
222
+ .venv/bin/pip install -e '.[full]'
223
+ .venv/bin/terminalboard ../tb_logs --once
224
+ ```
225
+
226
+ ## License
227
+
228
+ [MIT](LICENSE).
@@ -0,0 +1,37 @@
1
+ [build-system]
2
+ requires = ["setuptools>=61"]
3
+ build-backend = "setuptools.build_meta"
4
+
5
+ [project]
6
+ name = "terminalboard"
7
+ version = "0.1.0"
8
+ description = "A pure-SSH terminal TensorBoard scalar viewer — live scalar curves in iTerm2, no browser, no X11, no port forwarding."
9
+ readme = "README.md"
10
+ requires-python = ">=3.9"
11
+ license = { text = "MIT" }
12
+ authors = [{ name = "dongfangyixi" }]
13
+ keywords = ["tensorboard", "terminal", "iterm2", "plotext", "ssh", "ml"]
14
+
15
+ # Base install is intentionally light: the text renderer (plotext) and the
16
+ # pure-Python --light parser work with just this.
17
+ dependencies = [
18
+ "plotext>=5.2",
19
+ ]
20
+
21
+ [project.optional-dependencies]
22
+ # Default parser backend (EventAccumulator).
23
+ tb = ["tensorboard>=2.9"]
24
+ # High-quality --hq image renderer (matplotlib -> iTerm2 inline image).
25
+ hq = ["matplotlib>=3.5"]
26
+ # Everything.
27
+ full = ["tensorboard>=2.9", "matplotlib>=3.5"]
28
+
29
+ [project.scripts]
30
+ terminalboard = "terminalboard.cli:main"
31
+
32
+ [project.urls]
33
+ Repository = "https://github.com/dongfangyixi/terminalboard"
34
+
35
+ [tool.setuptools.packages.find]
36
+ where = ["."]
37
+ include = ["terminalboard*"]
@@ -0,0 +1,4 @@
1
+ [egg_info]
2
+ tag_build =
3
+ tag_date = 0
4
+
@@ -0,0 +1,9 @@
1
+ """terminalboard — a pure-SSH terminal TensorBoard scalar viewer.
2
+
3
+ Reads TensorBoard event logs and renders live-updated scalar curves directly
4
+ inside the terminal — by default as Unicode/braille text (works over any SSH
5
+ session), or as high-quality matplotlib images via the iTerm2 inline-image
6
+ protocol with ``--hq``. No browser, no X11, no port forwarding.
7
+ """
8
+
9
+ __version__ = "0.1.0"
@@ -0,0 +1,4 @@
1
+ from .cli import main
2
+
3
+ if __name__ == "__main__":
4
+ raise SystemExit(main())