iterm-dash 0.1.1__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 (50) hide show
  1. iterm_dash-0.1.1/.gitignore +9 -0
  2. iterm_dash-0.1.1/CHANGELOG.md +46 -0
  3. iterm_dash-0.1.1/CONTRIBUTING.md +73 -0
  4. iterm_dash-0.1.1/LICENSE +21 -0
  5. iterm_dash-0.1.1/PKG-INFO +270 -0
  6. iterm_dash-0.1.1/README.md +242 -0
  7. iterm_dash-0.1.1/SECURITY.md +30 -0
  8. iterm_dash-0.1.1/docs/architecture.md +192 -0
  9. iterm_dash-0.1.1/package.json +1 -0
  10. iterm_dash-0.1.1/pyproject.toml +61 -0
  11. iterm_dash-0.1.1/src/iterm_dash/__init__.py +0 -0
  12. iterm_dash-0.1.1/src/iterm_dash/backend.py +395 -0
  13. iterm_dash-0.1.1/src/iterm_dash/cli.py +313 -0
  14. iterm_dash-0.1.1/src/iterm_dash/demo.py +554 -0
  15. iterm_dash-0.1.1/src/iterm_dash/hub.py +239 -0
  16. iterm_dash-0.1.1/src/iterm_dash/palette.py +77 -0
  17. iterm_dash-0.1.1/src/iterm_dash/pump.py +45 -0
  18. iterm_dash-0.1.1/src/iterm_dash/registry.py +79 -0
  19. iterm_dash-0.1.1/src/iterm_dash/render.py +86 -0
  20. iterm_dash-0.1.1/src/iterm_dash/server.py +176 -0
  21. iterm_dash-0.1.1/src/iterm_dash/smoke.py +72 -0
  22. iterm_dash-0.1.1/src/iterm_dash/state.py +94 -0
  23. iterm_dash-0.1.1/src/iterm_dash/status.py +74 -0
  24. iterm_dash-0.1.1/src/iterm_dash/surface.py +116 -0
  25. iterm_dash-0.1.1/src/iterm_dash/web/app.js +760 -0
  26. iterm_dash-0.1.1/src/iterm_dash/web/clicks.js +26 -0
  27. iterm_dash-0.1.1/src/iterm_dash/web/format.js +7 -0
  28. iterm_dash-0.1.1/src/iterm_dash/web/index.html +74 -0
  29. iterm_dash-0.1.1/src/iterm_dash/web/layout.js +14 -0
  30. iterm_dash-0.1.1/src/iterm_dash/web/nav.js +36 -0
  31. iterm_dash-0.1.1/src/iterm_dash/web/rows.js +23 -0
  32. iterm_dash-0.1.1/src/iterm_dash/web/style.css +172 -0
  33. iterm_dash-0.1.1/src/iterm_dash/web.py +65 -0
  34. iterm_dash-0.1.1/tests/screens.py +24 -0
  35. iterm_dash-0.1.1/tests/test_backend.py +749 -0
  36. iterm_dash-0.1.1/tests/test_cli.py +803 -0
  37. iterm_dash-0.1.1/tests/test_demo_server.py +127 -0
  38. iterm_dash-0.1.1/tests/test_hub_web.py +371 -0
  39. iterm_dash-0.1.1/tests/test_palette.py +60 -0
  40. iterm_dash-0.1.1/tests/test_pump.py +127 -0
  41. iterm_dash-0.1.1/tests/test_registry.py +71 -0
  42. iterm_dash-0.1.1/tests/test_render.py +96 -0
  43. iterm_dash-0.1.1/tests/test_state.py +77 -0
  44. iterm_dash-0.1.1/tests/test_status.py +45 -0
  45. iterm_dash-0.1.1/tests/web/clicks.test.js +38 -0
  46. iterm_dash-0.1.1/tests/web/format.test.js +9 -0
  47. iterm_dash-0.1.1/tests/web/layout.test.js +22 -0
  48. iterm_dash-0.1.1/tests/web/nav.test.js +39 -0
  49. iterm_dash-0.1.1/tests/web/rows.test.js +28 -0
  50. iterm_dash-0.1.1/uv.lock +899 -0
@@ -0,0 +1,9 @@
1
+ .venv/
2
+ __pycache__/
3
+ *.egg-info/
4
+ .pytest_cache/
5
+ .ruff_cache/
6
+ dist/
7
+ build/
8
+ node_modules/
9
+ .DS_Store
@@ -0,0 +1,46 @@
1
+ # Changelog
2
+
3
+ All notable changes to this project are documented here. The format follows [Keep a Changelog](https://keepachangelog.com/en/1.1.0/), and the project uses [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
4
+
5
+ ## [Unreleased]
6
+
7
+ ## [0.1.1] - 2026-10-28
8
+
9
+ ### Changed
10
+
11
+ - iterm-dash is on PyPI: install it with `uv tool install iterm-dash` or `pipx install iterm-dash`, and update with `uv tool upgrade iterm-dash`.
12
+ - The README opens with a recording of the dashboard in a real iTerm2 window, including `n` and `2` switching tabs.
13
+ - README images and links are absolute, so they also show on PyPI.
14
+
15
+ ### Added
16
+
17
+ - A release workflow publishes version tags to PyPI through Trusted Publishing, with PEP 740 attestations.
18
+
19
+ ## [0.1.0] - 2026-10-27
20
+
21
+ First release.
22
+
23
+ ### Added
24
+
25
+ - A live grid of your iTerm2 sessions in an iTerm2 browser tab. Each cell shows the session's full-width screen, scaled to fit, in the session's own colours, and keeps the latest output and input box in view.
26
+ - Claude Code status for every cell, read from iTerm2's Claude Code integration: "Needs your input" (the loudest), "Error", "Done · your turn" and "Working", plus the status detail, such as the question Claude is asking.
27
+ - Time since each session's status last changed (counted from when the dashboard saw the change), so a stale or stuck session stands out.
28
+ - The page title counts the visible sessions that need you, for example `(3) iterm-dash`.
29
+ - Keyboard navigation:
30
+ - <kbd>n</kbd> jumps to the next session that needs you: waiting first, then errors, then finished turns.
31
+ - <kbd>1</kbd>–<kbd>9</kbd> jump straight to that cell's tab.
32
+ - Arrow keys move the focus ring; <kbd>Enter</kbd> jumps to the focused cell's tab.
33
+ - <kbd>Space</kbd> enlarges the focused cell; <kbd>Space</kbd> or <kbd>Esc</kbd> closes it.
34
+ - <kbd>h</kbd> hides the focused cell and <kbd>H</kbd> opens the "Hidden by you" menu to bring one back.
35
+ - <kbd>a</kbd> toggles between Claude sessions only and all sessions.
36
+ - <kbd>-</kbd> and <kbd>+</kbd> change the minimum text size.
37
+ - <kbd>?</kbd> shows the shortcut list.
38
+ - Mouse support: click a cell to enlarge it, double-click to jump to its tab.
39
+ - Cells keep their order; new sessions are added at the end.
40
+ - The `iterm-dash` command starts the background server if needed and opens the dashboard tab, or brings the open one forward.
41
+ - `iterm-dash stop` stops the server, `iterm-dash smoke` prints a metadata-only check of your sessions, and `iterm-dash demo` serves a dashboard of made-up sessions.
42
+ - The server binds to `127.0.0.1`, requires a per-run token, and never changes your sessions; focusing a tab is its only action.
43
+
44
+ [Unreleased]: https://github.com/ritikrishu/iterm-dash/compare/v0.1.1...HEAD
45
+ [0.1.1]: https://github.com/ritikrishu/iterm-dash/compare/v0.1.0...v0.1.1
46
+ [0.1.0]: https://github.com/ritikrishu/iterm-dash/releases/tag/v0.1.0
@@ -0,0 +1,73 @@
1
+ # Contributing
2
+
3
+ Thanks for taking a look. Bug reports, small fixes and ideas are all welcome. For anything larger than a small fix, please open an issue first so we can agree on the approach before you spend time on it.
4
+
5
+ ## Setup
6
+
7
+ You need macOS, iTerm2 3.7 or later, Python 3.12+, [uv](https://docs.astral.sh/uv/) and Node.js (for the page's tests).
8
+
9
+ ```sh
10
+ uv sync # install dependencies into .venv
11
+ uv tool install --editable . # optional: put your checkout on PATH as `iterm-dash`
12
+ ```
13
+
14
+ ## Running the tests
15
+
16
+ ```sh
17
+ uv run pytest # Python tests
18
+ npm test # page module tests (node --test tests/web/*.test.js)
19
+ ```
20
+
21
+ One test at a time:
22
+
23
+ ```sh
24
+ uv run pytest tests/test_render.py::test_wide_char_is_its_own_run_and_continuation_skipped -v
25
+ ```
26
+
27
+ The tests don't need iTerm2. The backend tests run against fake sessions, and the page's logic lives in pure modules (`layout.js`, `nav.js`, `clicks.js`, `format.js`, `rows.js`) that run under `node --test`.
28
+
29
+ ## Working on the page without iTerm2
30
+
31
+ ```sh
32
+ uv run iterm-dash demo
33
+ ```
34
+
35
+ This starts a demo server with made-up sessions in the background and prints its URL. Open it in any browser to work on the grid, the enlarged view and the shortcuts. The demo server keeps its state in a separate `demo/` folder and never talks to iTerm2. `iterm-dash stop` stops it.
36
+
37
+ ## Checking against real sessions
38
+
39
+ ```sh
40
+ uv run iterm-dash smoke
41
+ ```
42
+
43
+ The smoke check connects to iTerm2 and prints one line of metadata per session (id, title, size, status, fetch time, row count). It changes nothing and never prints screen text.
44
+
45
+ ## State and logs
46
+
47
+ The server keeps `server.json`, `settings.json`, `dashboard.json` and `server.log` in `~/Library/Application Support/iterm-dash/`. Set `ITERM_DASH_STATE_DIR` to use another folder. `iterm-dash stop` stops a running server.
48
+
49
+ ## Project rules
50
+
51
+ These keep the tool safe to leave running next to real work:
52
+
53
+ - **Read-only toward sessions.** The only thing iterm-dash may do to another session is focus it (`async_activate`). Don't call `async_set_grid_size`, `async_send_text` or `async_inject` on a watched session.
54
+ - **Metadata only in logs and debug output.** Print ids, sizes, counts and timings, never screen text or status detail. Log exceptions by type name, because their messages can contain screen text.
55
+ - **Test changes on a throwaway session.** If you're experimenting with anything that changes a session, open a scratch tab for it rather than pointing it at your real work.
56
+ - **No network beyond 127.0.0.1.** The page loads nothing from the internet, and the server listens on localhost only.
57
+
58
+ ## Commits and pull requests
59
+
60
+ Commit messages follow [Conventional Commits](https://www.conventionalcommits.org/), as in the existing history:
61
+
62
+ ```
63
+ feat: show the session's detail line under its title
64
+ fix: keep the focus ring on the same cell after a session closes
65
+ docs: explain the line cache
66
+ chore: bump aiohttp
67
+ ```
68
+
69
+ Keep pull requests focused on one change, add or update tests with it, and make sure `uv run pytest` and `npm test` pass.
70
+
71
+ ## How it works
72
+
73
+ [docs/architecture.md](docs/architecture.md) walks through the modules, the preview pipeline, status, the security model and the iTerm2 behaviour the code depends on. It's worth reading before a change to `backend.py` or `render.py`.
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 ritikrishu
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,270 @@
1
+ Metadata-Version: 2.5
2
+ Name: iterm-dash
3
+ Version: 0.1.1
4
+ Summary: Live previews of every Claude Code session in iTerm2, in one keyboard-driven tab.
5
+ Project-URL: Homepage, https://github.com/ritikrishu/iterm-dash
6
+ Project-URL: Source, https://github.com/ritikrishu/iterm-dash
7
+ Project-URL: Issues, https://github.com/ritikrishu/iterm-dash/issues
8
+ Project-URL: Changelog, https://github.com/ritikrishu/iterm-dash/blob/main/CHANGELOG.md
9
+ Author: ritikrishu
10
+ License-Expression: MIT
11
+ License-File: LICENSE
12
+ Keywords: claude-code,dashboard,developer-tools,iterm2,macos,terminal
13
+ Classifier: Development Status :: 4 - Beta
14
+ Classifier: Environment :: MacOS X
15
+ Classifier: Intended Audience :: Developers
16
+ Classifier: Operating System :: MacOS
17
+ Classifier: Programming Language :: Python :: 3
18
+ Classifier: Programming Language :: Python :: 3.12
19
+ Classifier: Programming Language :: Python :: 3.13
20
+ Classifier: Topic :: Software Development
21
+ Classifier: Topic :: Terminals
22
+ Requires-Python: >=3.12
23
+ Requires-Dist: aiohttp>=3.9
24
+ Requires-Dist: iterm2>=2.30
25
+ Requires-Dist: protobuf<8
26
+ Requires-Dist: websockets<18
27
+ Description-Content-Type: text/markdown
28
+
29
+ <div align="center">
30
+
31
+ <h1>iterm-dash</h1>
32
+
33
+ <p><b>Never leave a Claude waiting.</b></p>
34
+
35
+ <p>A live, keyboard-driven grid of every Claude Code session you already have open in iTerm2.<br>
36
+ Press <kbd>n</kbd> to land in the next one that needs you.</p>
37
+
38
+ <p>
39
+ <a href="https://github.com/ritikrishu/iterm-dash/actions/workflows/ci.yml"><img alt="CI" src="https://github.com/ritikrishu/iterm-dash/actions/workflows/ci.yml/badge.svg"></a>
40
+ <a href="https://github.com/ritikrishu/iterm-dash/blob/main/LICENSE"><img alt="MIT license" src="https://img.shields.io/badge/license-MIT-blue.svg"></a>
41
+ <img alt="macOS and iTerm2" src="https://img.shields.io/badge/macOS-iTerm2%203.7%2B-black.svg">
42
+ </p>
43
+
44
+ <p><a href="#install">Install</a> · <a href="#how-it-works">How it works</a> · <a href="#faq">FAQ</a> · <a href="https://github.com/ritikrishu/iterm-dash/blob/main/docs/architecture.md">Architecture</a></p>
45
+
46
+ <img src="https://raw.githubusercontent.com/ritikrishu/iterm-dash/main/docs/assets/hero.gif" width="900" alt="iterm-dash running in a real iTerm2 window, showing six Claude Code sessions live. One cell turns blue with 'Needs your input'. Space opens it full size, n switches iTerm2 to that session's tab, Command-1 returns to the dashboard, and 2 jumps straight to another session's tab.">
47
+
48
+ <sub>Recorded in a real iTerm2 window. The six sessions are scripted stand-ins, so no private work is on screen; the dashboard, their status and the tab switches are real.</sub>
49
+
50
+ </div>
51
+
52
+ ## Why
53
+
54
+ I run eight or nine Claude Code sessions at once, each in its own iTerm2 tab, and two things kept going wrong.
55
+
56
+ A session would finish, or stop to ask me something, and then sit there until I happened to click past its tab. That's Claude Code time I wasn't using. And every so often I'd cycle through every tab just to glance at each one and check it was still on track, which is tedious with nine of them.
57
+
58
+ iterm-dash is one more iTerm2 tab that shows all the others live. The sessions that need you light up, and a single key takes you to them.
59
+
60
+ ## What you get
61
+
62
+ ### See who needs you
63
+
64
+ A session waiting on a question turns blue with **Needs your input** and shows the question under its title. A finished one turns green with **Done · your turn**. Every cell shows how long ago its status changed, so a session that has been waiting a while stands out. The header counts them, and the page title does too, for example `(2) iterm-dash`.
65
+
66
+ <img src="https://raw.githubusercontent.com/ritikrishu/iterm-dash/main/docs/assets/needs-you.png" width="900" alt="The header reads '1 needs input · 1 done · 4 working'. Below it, a blue 'Needs your input' cell shows Claude's question, next to a green 'Done · your turn' cell finished 4 minutes ago.">
67
+
68
+ ### The real screen, not a summary
69
+
70
+ Each cell is the session's actual terminal screen at full width, colours and all, scaled to fit and updated as it changes. You can tell a session that's making progress from one that's going in circles without opening it.
71
+
72
+ ### Keyboard first
73
+
74
+ | Key | Action |
75
+ | --- | --- |
76
+ | <kbd>n</kbd> | Jump to the next session that needs you: waiting first, then errors, then done |
77
+ | <kbd>1</kbd> – <kbd>9</kbd> | Jump to that cell's tab |
78
+ | <kbd>←</kbd> <kbd>↑</kbd> <kbd>→</kbd> <kbd>↓</kbd> | Move the focus ring |
79
+ | <kbd>Space</kbd> | Peek: enlarge the focused cell (<kbd>Space</kbd> or <kbd>Esc</kbd> closes it) |
80
+ | <kbd>Enter</kbd> | Jump to the focused or enlarged cell's tab |
81
+ | <kbd>h</kbd> / <kbd>H</kbd> | Hide the focused cell / bring a hidden one back |
82
+ | <kbd>a</kbd> | Show every session, not just Claude Code |
83
+ | <kbd>-</kbd> <kbd>+</kbd> | Smaller or larger minimum text size |
84
+ | <kbd>?</kbd> | Show all shortcuts |
85
+
86
+ The mouse works too: click a cell to peek, double-click to jump.
87
+
88
+ ### Peek before you jump
89
+
90
+ <kbd>Space</kbd> opens the focused session full size, so you can read the question or the diff and decide whether it needs you now.
91
+
92
+ <img src="https://raw.githubusercontent.com/ritikrishu/iterm-dash/main/docs/assets/peek.png" width="900" alt="An enlarged session showing Claude's question about how a database backfill should treat existing keys, with numbered options.">
93
+
94
+ ### Works with the tabs you already have
95
+
96
+ There's no tmux, no wrapper command and nothing to relaunch. Start Claude Code however you like, in any window or tab. iterm-dash finds sessions as they open and close and keeps them in the order it first saw them.
97
+
98
+ ### Read-only by design
99
+
100
+ iterm-dash never types into, resizes or rearranges your sessions. Apart from managing its own dashboard tab, the only thing it does in iTerm2 is bring a session's tab to the front when you ask.
101
+
102
+ ## Install
103
+
104
+ **You need** macOS, [iTerm2](https://iterm2.com) 3.7 or later, and [uv](https://docs.astral.sh/uv/). uv installs Python 3.12+ for you if you don't have it.
105
+
106
+ 1. **Turn on iTerm2's Claude Code integration:** choose **iTerm2 › Install Claude Code Integration** and complete at least **Enable Python API** and **Install Hook**. The hook is how each session reports whether it's working, waiting or done.
107
+ 2. **Install iTerm2's browser plugin,** which lets iTerm2 open a web page as a tab: download [iTermBrowserPlugin-1.0.zip](https://iterm2.com/downloads/browser-plugin/iTermBrowserPlugin-1.0.zip), unzip it and move `iTermBrowserPlugin.app` to `/Applications`. If it's missing, `iterm-dash` tells you so and prints these steps.
108
+ 3. **Install and run iterm-dash** from any iTerm2 tab:
109
+
110
+ ```sh
111
+ uv tool install iterm-dash
112
+ iterm-dash
113
+ ```
114
+
115
+ The dashboard opens as a new iTerm2 tab. Run `iterm-dash` again at any time to bring it back to the front. The first run takes a few seconds longer while Python compiles, and iTerm2 may ask you to allow the API connection.
116
+
117
+ <details>
118
+ <summary>Other ways to install, and how to uninstall</summary>
119
+
120
+ With pipx (needs Python 3.12 or later):
121
+
122
+ ```sh
123
+ pipx install iterm-dash
124
+ ```
125
+
126
+ The latest commit on `main`:
127
+
128
+ ```sh
129
+ uv tool install git+https://github.com/ritikrishu/iterm-dash
130
+ ```
131
+
132
+ From a clone:
133
+
134
+ ```sh
135
+ git clone https://github.com/ritikrishu/iterm-dash && cd iterm-dash
136
+ uv tool install --editable .
137
+ ```
138
+
139
+ To update, stop the server and upgrade:
140
+
141
+ ```sh
142
+ iterm-dash stop
143
+ uv tool upgrade iterm-dash
144
+ ```
145
+
146
+ To uninstall, stop the server and remove the tool. Settings and logs live in `~/Library/Application Support/iterm-dash/`.
147
+
148
+ ```sh
149
+ iterm-dash stop
150
+ uv tool uninstall iterm-dash
151
+ ```
152
+
153
+ </details>
154
+
155
+ ## Usage
156
+
157
+ | Command | What it does |
158
+ | --- | --- |
159
+ | `iterm-dash` | Starts the background server if needed, then opens the dashboard tab or brings it forward |
160
+ | `iterm-dash stop` | Stops the background server (and the demo server, if one is running) |
161
+ | `iterm-dash smoke` | Read-only check against iTerm2: prints one line of metadata per session (id, title, size, status, fetch time), never screen text |
162
+ | `iterm-dash demo` | Starts a demo server with made-up sessions and prints its URL, so you can try the UI without iTerm2 |
163
+
164
+ The server keeps running until iTerm2 quits or you run `iterm-dash stop`.
165
+
166
+ ## How it works
167
+
168
+ 1. **One background Python process** holds a single connection to [iTerm2's Python API](https://iterm2.com/python-api/).
169
+ 2. **Screens:** it treats each session's screen stream only as a "something changed" signal, then fetches the raw screen buffer at a throttled rate. Lines are cached by their content, so a changed or scrolled frame only re-renders the lines that are new. Fetching a 214×57 screen takes about 1 ms, and re-rendering a changed frame about 0.5 ms (measured on iTerm2 3.7.6 with Claude Code 2.1.310).
170
+ 3. **Status** comes from iTerm2's Claude Code integration (`iterm2.get_session_status`), the same source as iTerm2's Session Status tool.
171
+ 4. **The page** is served on `127.0.0.1` with a per-run token and opened as an iTerm2 browser tab. A WebSocket sends it only the rows that changed, and it renders each screen at full width and scales it to fit the cell. Claude Code ends every row with a hard line break, so text can't be re-flowed into a narrower cell without breaking it.
172
+
173
+ In the same setup, with several sessions working, the server used about 1% CPU. The full design, including the edge cases that shaped it, is in [docs/architecture.md](https://github.com/ritikrishu/iterm-dash/blob/main/docs/architecture.md).
174
+
175
+ ## Privacy and safety
176
+
177
+ Your terminals hold private work, so iterm-dash is built to keep it on your machine:
178
+
179
+ - The server only listens on `127.0.0.1`. The page, its WebSocket and its control API all require a random token that changes on every start. Only the page's own JavaScript and CSS are served without it, and they contain no terminal data.
180
+ - The dashboard opens as an iTerm2 browser tab, never in your default browser, so that browser's extensions and sync never see your terminal contents or the token URL.
181
+ - It makes no outbound network requests and has no telemetry.
182
+ - Logs and `iterm-dash smoke` record metadata only (ids, titles, sizes, timings), never screen text.
183
+ - It never sends keystrokes to, resizes or closes your sessions.
184
+
185
+ See [SECURITY.md](https://github.com/ritikrishu/iterm-dash/blob/main/SECURITY.md) to report a vulnerability.
186
+
187
+ ## How it compares
188
+
189
+ - **iTerm2's Session Status tool** (View › Toolbelt › Session Status) lists the same statuses and jumps to a session when you click it. If a status list is enough for you, you don't need iterm-dash. What iterm-dash adds is the live screen, so you can see whether a busy session is on track.
190
+ - **Claude Code's agent view** (`claude agents`) manages background sessions and shows a summary per session. Sessions open in other terminals only appear once you background them. iterm-dash shows the sessions you already have, as they are, without changing how you run them.
191
+ - **Session managers** such as [claude-squad](https://github.com/smtg-ai/claude-squad), [agent-deck](https://github.com/asheshgoplani/agent-deck) and [ccmanager](https://github.com/kbwo/ccmanager) start and manage agent sessions for you and let you drive them from one place. Choose one of those if you want orchestration. iterm-dash doesn't start, stop or type into anything.
192
+
193
+ ## FAQ
194
+
195
+ <details>
196
+ <summary><b>Does it work with Ghostty, Terminal.app, Warp or tmux?</b></summary>
197
+
198
+ No. It's built on iTerm2's Python API and browser tabs, so it's iTerm2 only. tmux running inside an iTerm2 tab shows up like any other session, but tmux's `-CC` integration mode isn't supported.
199
+ </details>
200
+
201
+ <details>
202
+ <summary><b>Do I need Claude Code?</b></summary>
203
+
204
+ The live previews work for any iTerm2 session: press <kbd>a</kbd> to show them all. The "needs you" highlighting relies on the status that Claude Code reports through iTerm2's integration, so other tools show up as plain previews.
205
+ </details>
206
+
207
+ <details>
208
+ <summary><b>Why not resize sessions to fit the grid?</b></summary>
209
+
210
+ Resizing a session in iTerm2 resizes its real window. Tabs share one window size, and it fails on full-screen windows. iterm-dash renders each screen at its own width and scales it down instead, so your windows stay exactly as you left them.
211
+ </details>
212
+
213
+ <details>
214
+ <summary><b>A session says "Done" but Claude crashed. Why?</b></summary>
215
+
216
+ Status is reported by Claude Code's hook. If Claude exits uncleanly, the last status can go stale. That's why every cell shows how long ago its status changed. The clock starts when iterm-dash sees the change, so after the server restarts, it counts from the restart.
217
+ </details>
218
+
219
+ <details>
220
+ <summary><b>Something isn't working. Where do I start?</b></summary>
221
+
222
+ - **Every cell says "Status unknown" or nothing ever lights up:** iTerm2's Claude Code hook isn't installed or was dropped. Choose **iTerm2 › Install Claude Code Integration** (or **Reinstall Claude Code Integration**), then restart the Claude Code sessions that were already running.
223
+ - **`iterm-dash` can't connect to iTerm2:** turn on the Python API in **Settings › General › Magic**, and run `iterm-dash` from an iTerm2 tab.
224
+ - **You closed the dashboard tab:** run `iterm-dash` again. It reopens the tab or brings it forward.
225
+ - **Something else:** `iterm-dash smoke` shows what iterm-dash can see, and `server.log` records what it did. Both contain metadata only, so they're safe to paste into an issue.
226
+ </details>
227
+
228
+ <details>
229
+ <summary><b>Where are the logs and settings?</b></summary>
230
+
231
+ In `~/Library/Application Support/iterm-dash/`: `server.log`, `settings.json` (text size and the show-all toggle), `server.json` and `dashboard.json`. Set `ITERM_DASH_STATE_DIR` to use a different folder.
232
+ </details>
233
+
234
+ <details>
235
+ <summary><b>Can it answer prompts or send text to a session?</b></summary>
236
+
237
+ Not in this version, and not by accident. Version 1 is deliberately read-only. Its only action is focusing a tab.
238
+ </details>
239
+
240
+ ## Development
241
+
242
+ ```sh
243
+ git clone https://github.com/ritikrishu/iterm-dash && cd iterm-dash
244
+ uv sync
245
+ uv run pytest # Python tests (no iTerm2 needed)
246
+ npm test # page module tests
247
+ uv run iterm-dash demo
248
+ ```
249
+
250
+ `iterm-dash demo` serves the real UI fed by scripted sessions, which is how the still screenshots above were made. It's the quickest way to work on the page. The tests run against fake sessions, so neither needs iTerm2.
251
+
252
+ How the code fits together:
253
+
254
+ | Module | Job |
255
+ | --- | --- |
256
+ | `backend.py` | iTerm2 API: discovery, screen watchers, status, focus, and the content-keyed line cache |
257
+ | `pump.py` | Throttled, latest-only screen fetches |
258
+ | `render.py` | Screen lines → styled row runs, plus row diffs |
259
+ | `hub.py` | Cached state, and broadcasts changes to open pages |
260
+ | `web.py` | Token-guarded routes and the WebSocket |
261
+ | `web/app.js` | The grid UI, built on pure modules (`layout.js`, `nav.js`, `clicks.js`, `format.js`, `rows.js`) |
262
+ | `server.py`, `cli.py` | Process entry point and the `iterm-dash` command |
263
+ | `surface.py` | Opens the iTerm2 browser tab |
264
+ | `demo.py` | Scripted sessions for UI work |
265
+
266
+ Read [CONTRIBUTING.md](https://github.com/ritikrishu/iterm-dash/blob/main/CONTRIBUTING.md) before opening a pull request, and [docs/architecture.md](https://github.com/ritikrishu/iterm-dash/blob/main/docs/architecture.md) for the design and the iTerm2 behaviour it depends on. There's one hard rule: anything that changes a session gets tested only on a throwaway session, and debug output never prints screen text.
267
+
268
+ ## License
269
+
270
+ [MIT](https://github.com/ritikrishu/iterm-dash/blob/main/LICENSE). iterm-dash is an independent project, not affiliated with Anthropic or iTerm2. Claude and Claude Code are trademarks of Anthropic.