clique-panel 0.50.54__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 (80) hide show
  1. clique_panel-0.50.54/LICENSE +21 -0
  2. clique_panel-0.50.54/PKG-INFO +217 -0
  3. clique_panel-0.50.54/README.md +168 -0
  4. clique_panel-0.50.54/clique/__init__.py +40 -0
  5. clique_panel-0.50.54/clique/__main__.py +231 -0
  6. clique_panel-0.50.54/clique/app.py +1838 -0
  7. clique_panel-0.50.54/clique/artifacts.py +155 -0
  8. clique_panel-0.50.54/clique/attention.py +236 -0
  9. clique_panel-0.50.54/clique/auth.py +253 -0
  10. clique_panel-0.50.54/clique/changelog.py +127 -0
  11. clique_panel-0.50.54/clique/config/clis.toml +299 -0
  12. clique_panel-0.50.54/clique/files.py +132 -0
  13. clique_panel-0.50.54/clique/gitinfo.py +200 -0
  14. clique_panel-0.50.54/clique/history.py +567 -0
  15. clique_panel-0.50.54/clique/migrate.py +84 -0
  16. clique_panel-0.50.54/clique/notify.py +310 -0
  17. clique_panel-0.50.54/clique/registry.py +427 -0
  18. clique_panel-0.50.54/clique/services.py +204 -0
  19. clique_panel-0.50.54/clique/store.py +696 -0
  20. clique_panel-0.50.54/clique/stream.py +185 -0
  21. clique_panel-0.50.54/clique/sysinfo.py +249 -0
  22. clique_panel-0.50.54/clique/termstrip.py +126 -0
  23. clique_panel-0.50.54/clique/tmux.py +562 -0
  24. clique_panel-0.50.54/clique/tokens.py +172 -0
  25. clique_panel-0.50.54/clique/web/app.css +1500 -0
  26. clique_panel-0.50.54/clique/web/app.js +6439 -0
  27. clique_panel-0.50.54/clique/web/brand/SOURCE.md +51 -0
  28. clique_panel-0.50.54/clique/web/brand/apple-touch-icon.png +0 -0
  29. clique_panel-0.50.54/clique/web/brand/favicon.ico +0 -0
  30. clique_panel-0.50.54/clique/web/brand/icon-128.png +0 -0
  31. clique_panel-0.50.54/clique/web/brand/icon-16.png +0 -0
  32. clique_panel-0.50.54/clique/web/brand/icon-180.png +0 -0
  33. clique_panel-0.50.54/clique/web/brand/icon-192.png +0 -0
  34. clique_panel-0.50.54/clique/web/brand/icon-256.png +0 -0
  35. clique_panel-0.50.54/clique/web/brand/icon-32.png +0 -0
  36. clique_panel-0.50.54/clique/web/brand/icon-512.png +0 -0
  37. clique_panel-0.50.54/clique/web/brand/icon-64.png +0 -0
  38. clique_panel-0.50.54/clique/web/brand/icon-maskable-512.png +0 -0
  39. clique_panel-0.50.54/clique/web/brand/lockup.svg +17 -0
  40. clique_panel-0.50.54/clique/web/brand/logo.svg +11 -0
  41. clique_panel-0.50.54/clique/web/brand/mark-mono.svg +4 -0
  42. clique_panel-0.50.54/clique/web/brand/mark.svg +10 -0
  43. clique_panel-0.50.54/clique/web/brand/social-preview.png +0 -0
  44. clique_panel-0.50.54/clique/web/icons/README.md +55 -0
  45. clique_panel-0.50.54/clique/web/icons/antigravity.svg +1 -0
  46. clique_panel-0.50.54/clique/web/icons/claude.svg +1 -0
  47. clique_panel-0.50.54/clique/web/icons/cline.png +0 -0
  48. clique_panel-0.50.54/clique/web/icons/codex.svg +1 -0
  49. clique_panel-0.50.54/clique/web/icons/copilot.svg +1 -0
  50. clique_panel-0.50.54/clique/web/icons/cursor.svg +1 -0
  51. clique_panel-0.50.54/clique/web/icons/default.svg +4 -0
  52. clique_panel-0.50.54/clique/web/icons/droid.svg +6 -0
  53. clique_panel-0.50.54/clique/web/icons/gemini.svg +10 -0
  54. clique_panel-0.50.54/clique/web/icons/goose.svg +10 -0
  55. clique_panel-0.50.54/clique/web/icons/grok.svg +1 -0
  56. clique_panel-0.50.54/clique/web/icons/ollama.svg +1 -0
  57. clique_panel-0.50.54/clique/web/icons/opencode.svg +7 -0
  58. clique_panel-0.50.54/clique/web/icons/qwen.svg +1 -0
  59. clique_panel-0.50.54/clique/web/icons/shell.svg +1 -0
  60. clique_panel-0.50.54/clique/web/index.html +634 -0
  61. clique_panel-0.50.54/clique/web/manifest.webmanifest +21 -0
  62. clique_panel-0.50.54/clique/web/sw.js +18 -0
  63. clique_panel-0.50.54/clique/web/themes.js +157 -0
  64. clique_panel-0.50.54/clique/web/vendor/README.md +26 -0
  65. clique_panel-0.50.54/clique/web/vendor/addon-canvas.js +2 -0
  66. clique_panel-0.50.54/clique/web/vendor/addon-fit.js +2 -0
  67. clique_panel-0.50.54/clique/web/vendor/addon-unicode11.js +2 -0
  68. clique_panel-0.50.54/clique/web/vendor/xterm.LICENSE +21 -0
  69. clique_panel-0.50.54/clique/web/vendor/xterm.css +285 -0
  70. clique_panel-0.50.54/clique/web/vendor/xterm.js +2 -0
  71. clique_panel-0.50.54/clique/working.py +136 -0
  72. clique_panel-0.50.54/clique/workspace.py +205 -0
  73. clique_panel-0.50.54/clique/wsproto.py +230 -0
  74. clique_panel-0.50.54/clique_panel.egg-info/PKG-INFO +217 -0
  75. clique_panel-0.50.54/clique_panel.egg-info/SOURCES.txt +78 -0
  76. clique_panel-0.50.54/clique_panel.egg-info/dependency_links.txt +1 -0
  77. clique_panel-0.50.54/clique_panel.egg-info/entry_points.txt +2 -0
  78. clique_panel-0.50.54/clique_panel.egg-info/top_level.txt +1 -0
  79. clique_panel-0.50.54/pyproject.toml +88 -0
  80. clique_panel-0.50.54/setup.cfg +4 -0
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 Justin Willhite
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,217 @@
1
+ Metadata-Version: 2.4
2
+ Name: clique-panel
3
+ Version: 0.50.54
4
+ Summary: Your private clique of CLIs. Folder-organised, CLI-agnostic coding sessions in a browser, persisted in tmux
5
+ Author: Justin Willhite
6
+ License: MIT License
7
+
8
+ Copyright (c) 2026 Justin Willhite
9
+
10
+ Permission is hereby granted, free of charge, to any person obtaining a copy
11
+ of this software and associated documentation files (the "Software"), to deal
12
+ in the Software without restriction, including without limitation the rights
13
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
14
+ copies of the Software, and to permit persons to whom the Software is
15
+ furnished to do so, subject to the following conditions:
16
+
17
+ The above copyright notice and this permission notice shall be included in all
18
+ copies or substantial portions of the Software.
19
+
20
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
21
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
22
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
23
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
24
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
25
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
26
+ SOFTWARE.
27
+
28
+ Project-URL: Homepage, https://github.com/thejdubb02/clique
29
+ Project-URL: Changelog, https://github.com/thejdubb02/clique/blob/main/CHANGELOG.md
30
+ Project-URL: Issues, https://github.com/thejdubb02/clique/issues
31
+ Project-URL: API, https://github.com/thejdubb02/clique/blob/main/API.md
32
+ Keywords: tmux,terminal,session-manager,web-terminal,coding-agents,claude-code,self-hosted,multi-agent
33
+ Classifier: Development Status :: 4 - Beta
34
+ Classifier: Environment :: Console
35
+ Classifier: Environment :: Web Environment
36
+ Classifier: Intended Audience :: Developers
37
+ Classifier: License :: OSI Approved :: MIT License
38
+ Classifier: Operating System :: POSIX :: Linux
39
+ Classifier: Operating System :: MacOS
40
+ Classifier: Programming Language :: Python :: 3 :: Only
41
+ Classifier: Programming Language :: Python :: 3.11
42
+ Classifier: Topic :: Software Development
43
+ Classifier: Topic :: Terminals :: Terminal Emulators/X Terminals
44
+ Classifier: Topic :: Utilities
45
+ Requires-Python: >=3.11
46
+ Description-Content-Type: text/markdown
47
+ License-File: LICENSE
48
+ Dynamic: license-file
49
+
50
+ <p align="center">
51
+ <img src="clique/web/brand/social-preview.png" alt="CLIque: a folder for every CLI on the box" width="800">
52
+ </p>
53
+
54
+ <p align="center">
55
+ <strong>A folder for every CLI on the box. Coding sessions in the browser, kept alive in tmux.</strong><br>
56
+ Claude Code, Codex, Gemini, Grok, Antigravity, or anything you add in four lines of config.
57
+ </p>
58
+
59
+ <p align="center">
60
+ <a href="#quick-start"><img src="https://img.shields.io/badge/python-3.11%2B-3776AB?style=flat-square" alt="Python 3.11+"></a>
61
+ <a href="#why-it-is-stdlib-only"><img src="https://img.shields.io/badge/deps-none-22c55e?style=flat-square" alt="No dependencies"></a>
62
+ <a href="LICENSE"><img src="https://img.shields.io/badge/license-MIT-5FA8F5?style=flat-square" alt="MIT"></a>
63
+ <a href="https://github.com/thejdubb02/clique/actions/workflows/tests.yml"><img src="https://github.com/thejdubb02/clique/actions/workflows/tests.yml/badge.svg" alt="tests"></a>
64
+ <a href="CHANGELOG.md"><img src="https://img.shields.io/badge/version-0.50.54-A855F7?style=flat-square" alt="0.50.54"></a>
65
+ <a href="https://github.com/thejdubb02/clique/stargazers"><img src="https://img.shields.io/github/stars/thejdubb02/clique?style=flat-square" alt="GitHub stars"></a>
66
+ <a href="https://buymeacoffee.com/jdubb"><img src="https://img.shields.io/badge/Buy%20me%20a%20coffee-FFDD00?style=flat-square&logo=buymeacoffee&logoColor=black" alt="Buy me a coffee"></a>
67
+ <a href="#support-the-dev"><img src="https://img.shields.io/badge/Donate-BTC%20%7C%20SHIB%20%7C%20DOGE-5FA8F5?style=flat-square" alt="Donate"></a>
68
+ </p>
69
+
70
+ ---
71
+
72
+ CLIque is a **driver, not an IDE**. It does not parse a vendor's protocol, impersonate a model, or reimplement the tools you already have. It keeps a private tmux server, puts every CLI session in a folder you can actually find, and gives you a browser to jump between them.
73
+
74
+ If you run more than two coding agents at once, you already know the problem: terminals everywhere, no idea which one is waiting on you, a conversation you cannot get back to. CLIque is the panel for that.
75
+
76
+ **24 MB resident.** No framework, no `node_modules`, no build step. `tmux`, a PTY, and the Python standard library.
77
+
78
+ ## Who it's for
79
+
80
+ **Using one AI coding agent?** Claude Code, Codex, Cursor's CLI, Gemini, Grok, Antigravity — CLIque puts it in your browser. Kick off a task, close the laptop, and check on it from your phone on the couch. Nothing to babysit, nothing to install but Python and tmux.
81
+
82
+ **Running several at once?** You already know the problem: terminals everywhere, no idea which one is waiting on you, a conversation you cannot get back to. CLIque is the one screen in front of all of them — folders, a status ring on each, one click to jump, and a real phone notification when one wants you.
83
+
84
+ **Driving a fleet?** Run ten agents across ten repos, each in its own git worktree so they do not step on each other, reap the idle ones to reclaim memory and resume them later exactly where they left off, and script the whole thing over an HTTP API.
85
+
86
+ It is **not** an IDE, not another AI, and not a replacement for your CLIs — it is the control panel in front of the tools you already use. If you want the tool to *be* the agent, look elsewhere.
87
+
88
+ ## What it does
89
+
90
+ | | |
91
+ |---|---|
92
+ | **Command palette** | `Ctrl`/`Cmd`+`K`: fuzzy jump between sessions, most-recently-used first. `>` commands, `@` sessions, `~` past conversations. |
93
+ | **History** | Every conversation your CLIs have kept, filed by directory, resumable in one click. Repeated runs of the same scheduled agent fold into one row. |
94
+ | **Resume & reap** | An idle tab has its process stopped after a few hours — ~700 MB freed for an idle Claude — and its tab greys out. Click it and it resumes exactly where it was. Ten open tabs cost what two do. |
95
+ | **Worktrees** | Start a session in its own git worktree, so several agents work the same repo at once without touching each other's files. Delete the session and the worktree goes too — unless it has uncommitted work. |
96
+ | **Conversation view** | A CLI that draws full-screen keeps no scrollback; **View conversation** reads its transcript back — your turns and the assistant's prose, tools and thinking left out — in a clean sheet. |
97
+ | **Agent-drivable** | A one-word `state` per session, a `wait`-until-done call, and a skill, so an agent can drive CLIque itself: fan one task across many repos and collect the results. |
98
+ | **Filter** | One button in the sidebar hides every stopped session — and any folder left empty by it — so a list of two dozen collapses to what is actually running. |
99
+ | **Folders** | A tree. Drag to reorder folders and sessions, or drop a session on a folder to file it. Double-click rename, right-click, search, collapse to a rail (`Ctrl`/`Cmd`+`B`). Each row names the git branch it is on, and how many files have changed. |
100
+ | **Tabs** | Drag to reorder, `Alt`+`1`–`9` to jump. Names shrink first; what still will not fit lands in **N more**, wearing the same working / waiting ring. Closing a tab is not killing the session. |
101
+ | **Terminal** | Live output, full scrollback on reattach, resize, auto-reconnect, themed to the panel. Drag to copy, even when the CLI wants the mouse. `Ctrl`/`Cmd`+`C` copies a selection and interrupts when there isn't one; `Ctrl`/`Cmd`+`Shift`+`C` copies the screen. |
102
+ | **Links** | URLs in the pane are clickable: a new tab, or a new window with `Ctrl`/`Cmd`. `http(s)` only. A URL that wrapped onto the next line is still one link. A file path opens a read-only look — copy it, or drop it into the prompt. |
103
+ | **Scroll lock** | Scroll up and the view detaches from the stream. A badge says how far behind you are; the bottom, the lock, or `Ctrl`/`Cmd`+`Shift`+`L` catches you up. |
104
+ | **Paste a screenshot** | `Ctrl`/`Cmd`+`V` saves the image into the session's own directory and drops the path where you were typing. Nothing is sent until you press enter. |
105
+ | **See what it made** | An agent writes a screenshot into the session's directory and a count appears in the tab bar. Grid, full size, and the path back into your prompt in one click. |
106
+ | **Prompt drafts** | A half-typed instruction survives a tab switch, a reload, and a closed laptop. Per session, on the server, so it follows you to another device. |
107
+ | **Workspace** | Open tabs, their order, the one in front, and which groups are collapsed live on the server. A reload attaches the tab you are looking at, then warms the rest in the background without resizing the pane. Sign in somewhere else and the strip is where you left it. |
108
+ | **Status** | A ring around the CLI's own logo: an arc turning means working, a steady pulse means finished and waiting for you, idle draws nothing. The logo is never recoloured. |
109
+ | **The box** | CPU, memory, disk and **VIEWS** in the bottom bar. Views is live connections on the box, not open tabs — hover if the number looks high; extras are another window or a phone. |
110
+ | **Waiting on you** | Three tiers: tmux's clock, regexes you declare per CLI, and a `POST .../attention` a session fires from your own hook. Nothing here knows which vendor is talking. |
111
+ | **Unread** | A dot on anything that produced output while you were elsewhere, and a rule in the pane where you stopped reading. |
112
+ | **Which CLI** | The pane edge, the active tab and the prompt box carry the CLI's colour, so switching tabs tells you where you are typing. Colours editable per CLI. |
113
+ | **Themes** | Nine presets, light / dark / system, custom CSS in three slots, independent font sizes, a monospace picker that falls back on every OS. |
114
+ | **API** | Every action in the panel is an HTTP call, with bearer tokens and read-only ones. Full reference in [API.md](API.md), kept honest by a drift check in the test suite. |
115
+ | **Changelog** | Settings → Changelog: the last few releases, with a link to the rest on GitHub. After an upgrade, **What's new** sits on the bottom bar and goes straight there. |
116
+ | **Told, not checked** | One webhook URL, POSTed when a session wants you, errors, finishes or dies. ntfy, Gotify, Discord, Mattermost and Uptime Kuma push all speak it. Real phone notifications, no app of ours. |
117
+ | **Monitoring** | `GET /healthz` answers without a login. Point Uptime Kuma, Gatus or Healthchecks at it. Anonymously it says `{"ok": true}` and nothing else. |
118
+ | **Security** | Password login (scrypt), API tokens, CSRF, `Origin` and `Host` checks, CSP with per-response nonces. See [SECURITY.md](SECURITY.md). |
119
+ | **Touch** | Long press a session for the menu right-click gives, with tap targets sized for a finger. |
120
+ | **Phone & PWA** | Install it as its own app — no tabs, no URL bar, full screen from the bottom bar. Built for a phone browser too: a drawer sidebar, a full-width pane, an on-screen row for the keys a terminal needs (Esc, Tab, Ctrl+C, arrows), and a wheel that scrolls a full-screen CLI's own view. |
121
+
122
+ Not built, on purpose: subagent visualisation, a respawn controller, multi-host, a Ralph loop. Those need to know which vendor is talking. This product does not.
123
+
124
+ What is next, and why that order: [ROADMAP.md](ROADMAP.md). What shipped: [CHANGELOG.md](CHANGELOG.md).
125
+
126
+ ## Quick start
127
+
128
+ Needs **Python 3.11+** and **tmux**. Nothing else.
129
+
130
+ ```bash
131
+ git clone https://github.com/thejdubb02/clique.git
132
+ cd clique
133
+ python3 -m clique password # prompted; stored as an scrypt hash
134
+ python3 -m clique # http://127.0.0.1:3200
135
+ ```
136
+
137
+ State lives in `$CLIQUE_HOME`, default `~/.clique`. To edit the CLI catalogue,
138
+ `python3 -m clique config` drops one where your edits survive an upgrade.
139
+
140
+ Once it is on PyPI, `pip install clique-panel` gives you a `clique` command
141
+ (the package is `clique-panel` because `clique` there is an unrelated library).
142
+
143
+ It binds to loopback on purpose. Put a tunnel in front of it (Tailscale Serve, Caddy, nginx) if you want it from another machine. Do not bind it to the public internet. Anyone who reaches the panel has a terminal as the user that started it.
144
+
145
+ ```bash
146
+ # optional: behind Tailscale
147
+ tailscale serve --bg --set-path /clique http://127.0.0.1:3200
148
+ ```
149
+
150
+ A systemd user unit is in [`deploy/`](deploy/README.md).
151
+
152
+ `GET /healthz` answers without a login (`{"ok":true}` and nothing else), so Uptime Kuma, Gatus or Healthchecks can watch it.
153
+
154
+ ## Adding a CLI
155
+
156
+ A block in [`clique/config/clis.toml`](clique/config/clis.toml). Reload the page. No restart, no code:
157
+
158
+ ```toml
159
+ [cli.grok]
160
+ label = "Grok CLI"
161
+ command = "grok"
162
+ args = []
163
+ color = "#6f42c1"
164
+ ```
165
+
166
+ There is no per-CLI branch in the codebase. If adding one ever needs a code change, the design has failed.
167
+
168
+ Claude Code and Gemini CLI can also declare an **autonomy pill** (the mode above the prompt). That is four keys in the same block (`modes`, `mode_key`, `mode_label`), documented in the comments of `clis.toml`. Omit them and the pill stays hidden, which is the right default for a CLI whose approval is a launch flag.
169
+
170
+ ## Why it is stdlib-only
171
+
172
+ A coding-agent session already costs hundreds of megabytes. The manager's job is to disappear into that budget. Measured: **24 MB resident**.
173
+
174
+ That also means the real ceiling on concurrent sessions is the agents, not this. On a 16 GB box with ~9 GB free, roughly a dozen at once.
175
+
176
+ ## Design notes that are easy to get wrong
177
+
178
+ - **Own tmux server** (`tmux -L clique`). Isolated from everything else on the box.
179
+ - **A PTY exists only while a browser is attached.** An idle session costs this process nothing; cost scales with open tabs, not with session count.
180
+ - **Each viewer gets its own grouped tmux session.** Plain `attach` makes every client share one size, so tmux shrinks the pane to the smallest watcher.
181
+ - **Closing a tab is not killing a session.** Detach sends SIGHUP; tmux and the CLI carry on.
182
+ - **`kill()` refuses sessions that are not ours** unless forced.
183
+
184
+ ## Tests
185
+
186
+ Neither suite is mocked. The failure modes worth catching (tmux quoting, a PTY that never gets its first byte) only exist across a real socket. GitHub Actions runs all three on every push. They start their own panel and tmux server, so they cannot touch the one you are using.
187
+
188
+ ```bash
189
+ python3 tools/smoke.py # engine, against a real tmux server
190
+ python3 tools/smoke_http.py # server, over real HTTP + WebSocket
191
+ python3 tools/api_drift.py # API.md still covers every route and setting
192
+ ruff check .
193
+ ```
194
+
195
+ They will not catch a UI that renders wrong. Open the page for that.
196
+
197
+ ## Contributing
198
+
199
+ Patches welcome, with a short filter: [CONTRIBUTING.md](CONTRIBUTING.md). Feature ideas that need to know which vendor is talking get refused. That is the product, not a freeze.
200
+
201
+ ## Support the dev
202
+
203
+ Free, and staying that way. If it saved you an afternoon, this is the tip jar.
204
+
205
+ **[Buy me a coffee](https://buymeacoffee.com/jdubb)**
206
+
207
+ | | Network | Address |
208
+ |---|---|---|
209
+ | **BTC** | Bitcoin | `3A3nA8BQFmXdvyUQokHhPd8HAd99wRDYFQ` |
210
+ | **SHIB** | Ethereum | `0x6b5DEd92946692D50642dC3af169727225E32D3b` |
211
+ | **DOGE** | Dogecoin | `DNiJeUJUVaVTDuteLXCtP7JVgvdL2NqoYp` |
212
+
213
+ ## License
214
+
215
+ [MIT](LICENSE). Built by [Justin Willhite](https://github.com/thejdubb02).
216
+
217
+ A hole that reaches a terminal is a [private advisory](https://github.com/thejdubb02/clique/security/advisories/new), not a public issue. See [SECURITY.md](SECURITY.md).
@@ -0,0 +1,168 @@
1
+ <p align="center">
2
+ <img src="clique/web/brand/social-preview.png" alt="CLIque: a folder for every CLI on the box" width="800">
3
+ </p>
4
+
5
+ <p align="center">
6
+ <strong>A folder for every CLI on the box. Coding sessions in the browser, kept alive in tmux.</strong><br>
7
+ Claude Code, Codex, Gemini, Grok, Antigravity, or anything you add in four lines of config.
8
+ </p>
9
+
10
+ <p align="center">
11
+ <a href="#quick-start"><img src="https://img.shields.io/badge/python-3.11%2B-3776AB?style=flat-square" alt="Python 3.11+"></a>
12
+ <a href="#why-it-is-stdlib-only"><img src="https://img.shields.io/badge/deps-none-22c55e?style=flat-square" alt="No dependencies"></a>
13
+ <a href="LICENSE"><img src="https://img.shields.io/badge/license-MIT-5FA8F5?style=flat-square" alt="MIT"></a>
14
+ <a href="https://github.com/thejdubb02/clique/actions/workflows/tests.yml"><img src="https://github.com/thejdubb02/clique/actions/workflows/tests.yml/badge.svg" alt="tests"></a>
15
+ <a href="CHANGELOG.md"><img src="https://img.shields.io/badge/version-0.50.54-A855F7?style=flat-square" alt="0.50.54"></a>
16
+ <a href="https://github.com/thejdubb02/clique/stargazers"><img src="https://img.shields.io/github/stars/thejdubb02/clique?style=flat-square" alt="GitHub stars"></a>
17
+ <a href="https://buymeacoffee.com/jdubb"><img src="https://img.shields.io/badge/Buy%20me%20a%20coffee-FFDD00?style=flat-square&logo=buymeacoffee&logoColor=black" alt="Buy me a coffee"></a>
18
+ <a href="#support-the-dev"><img src="https://img.shields.io/badge/Donate-BTC%20%7C%20SHIB%20%7C%20DOGE-5FA8F5?style=flat-square" alt="Donate"></a>
19
+ </p>
20
+
21
+ ---
22
+
23
+ CLIque is a **driver, not an IDE**. It does not parse a vendor's protocol, impersonate a model, or reimplement the tools you already have. It keeps a private tmux server, puts every CLI session in a folder you can actually find, and gives you a browser to jump between them.
24
+
25
+ If you run more than two coding agents at once, you already know the problem: terminals everywhere, no idea which one is waiting on you, a conversation you cannot get back to. CLIque is the panel for that.
26
+
27
+ **24 MB resident.** No framework, no `node_modules`, no build step. `tmux`, a PTY, and the Python standard library.
28
+
29
+ ## Who it's for
30
+
31
+ **Using one AI coding agent?** Claude Code, Codex, Cursor's CLI, Gemini, Grok, Antigravity — CLIque puts it in your browser. Kick off a task, close the laptop, and check on it from your phone on the couch. Nothing to babysit, nothing to install but Python and tmux.
32
+
33
+ **Running several at once?** You already know the problem: terminals everywhere, no idea which one is waiting on you, a conversation you cannot get back to. CLIque is the one screen in front of all of them — folders, a status ring on each, one click to jump, and a real phone notification when one wants you.
34
+
35
+ **Driving a fleet?** Run ten agents across ten repos, each in its own git worktree so they do not step on each other, reap the idle ones to reclaim memory and resume them later exactly where they left off, and script the whole thing over an HTTP API.
36
+
37
+ It is **not** an IDE, not another AI, and not a replacement for your CLIs — it is the control panel in front of the tools you already use. If you want the tool to *be* the agent, look elsewhere.
38
+
39
+ ## What it does
40
+
41
+ | | |
42
+ |---|---|
43
+ | **Command palette** | `Ctrl`/`Cmd`+`K`: fuzzy jump between sessions, most-recently-used first. `>` commands, `@` sessions, `~` past conversations. |
44
+ | **History** | Every conversation your CLIs have kept, filed by directory, resumable in one click. Repeated runs of the same scheduled agent fold into one row. |
45
+ | **Resume & reap** | An idle tab has its process stopped after a few hours — ~700 MB freed for an idle Claude — and its tab greys out. Click it and it resumes exactly where it was. Ten open tabs cost what two do. |
46
+ | **Worktrees** | Start a session in its own git worktree, so several agents work the same repo at once without touching each other's files. Delete the session and the worktree goes too — unless it has uncommitted work. |
47
+ | **Conversation view** | A CLI that draws full-screen keeps no scrollback; **View conversation** reads its transcript back — your turns and the assistant's prose, tools and thinking left out — in a clean sheet. |
48
+ | **Agent-drivable** | A one-word `state` per session, a `wait`-until-done call, and a skill, so an agent can drive CLIque itself: fan one task across many repos and collect the results. |
49
+ | **Filter** | One button in the sidebar hides every stopped session — and any folder left empty by it — so a list of two dozen collapses to what is actually running. |
50
+ | **Folders** | A tree. Drag to reorder folders and sessions, or drop a session on a folder to file it. Double-click rename, right-click, search, collapse to a rail (`Ctrl`/`Cmd`+`B`). Each row names the git branch it is on, and how many files have changed. |
51
+ | **Tabs** | Drag to reorder, `Alt`+`1`–`9` to jump. Names shrink first; what still will not fit lands in **N more**, wearing the same working / waiting ring. Closing a tab is not killing the session. |
52
+ | **Terminal** | Live output, full scrollback on reattach, resize, auto-reconnect, themed to the panel. Drag to copy, even when the CLI wants the mouse. `Ctrl`/`Cmd`+`C` copies a selection and interrupts when there isn't one; `Ctrl`/`Cmd`+`Shift`+`C` copies the screen. |
53
+ | **Links** | URLs in the pane are clickable: a new tab, or a new window with `Ctrl`/`Cmd`. `http(s)` only. A URL that wrapped onto the next line is still one link. A file path opens a read-only look — copy it, or drop it into the prompt. |
54
+ | **Scroll lock** | Scroll up and the view detaches from the stream. A badge says how far behind you are; the bottom, the lock, or `Ctrl`/`Cmd`+`Shift`+`L` catches you up. |
55
+ | **Paste a screenshot** | `Ctrl`/`Cmd`+`V` saves the image into the session's own directory and drops the path where you were typing. Nothing is sent until you press enter. |
56
+ | **See what it made** | An agent writes a screenshot into the session's directory and a count appears in the tab bar. Grid, full size, and the path back into your prompt in one click. |
57
+ | **Prompt drafts** | A half-typed instruction survives a tab switch, a reload, and a closed laptop. Per session, on the server, so it follows you to another device. |
58
+ | **Workspace** | Open tabs, their order, the one in front, and which groups are collapsed live on the server. A reload attaches the tab you are looking at, then warms the rest in the background without resizing the pane. Sign in somewhere else and the strip is where you left it. |
59
+ | **Status** | A ring around the CLI's own logo: an arc turning means working, a steady pulse means finished and waiting for you, idle draws nothing. The logo is never recoloured. |
60
+ | **The box** | CPU, memory, disk and **VIEWS** in the bottom bar. Views is live connections on the box, not open tabs — hover if the number looks high; extras are another window or a phone. |
61
+ | **Waiting on you** | Three tiers: tmux's clock, regexes you declare per CLI, and a `POST .../attention` a session fires from your own hook. Nothing here knows which vendor is talking. |
62
+ | **Unread** | A dot on anything that produced output while you were elsewhere, and a rule in the pane where you stopped reading. |
63
+ | **Which CLI** | The pane edge, the active tab and the prompt box carry the CLI's colour, so switching tabs tells you where you are typing. Colours editable per CLI. |
64
+ | **Themes** | Nine presets, light / dark / system, custom CSS in three slots, independent font sizes, a monospace picker that falls back on every OS. |
65
+ | **API** | Every action in the panel is an HTTP call, with bearer tokens and read-only ones. Full reference in [API.md](API.md), kept honest by a drift check in the test suite. |
66
+ | **Changelog** | Settings → Changelog: the last few releases, with a link to the rest on GitHub. After an upgrade, **What's new** sits on the bottom bar and goes straight there. |
67
+ | **Told, not checked** | One webhook URL, POSTed when a session wants you, errors, finishes or dies. ntfy, Gotify, Discord, Mattermost and Uptime Kuma push all speak it. Real phone notifications, no app of ours. |
68
+ | **Monitoring** | `GET /healthz` answers without a login. Point Uptime Kuma, Gatus or Healthchecks at it. Anonymously it says `{"ok": true}` and nothing else. |
69
+ | **Security** | Password login (scrypt), API tokens, CSRF, `Origin` and `Host` checks, CSP with per-response nonces. See [SECURITY.md](SECURITY.md). |
70
+ | **Touch** | Long press a session for the menu right-click gives, with tap targets sized for a finger. |
71
+ | **Phone & PWA** | Install it as its own app — no tabs, no URL bar, full screen from the bottom bar. Built for a phone browser too: a drawer sidebar, a full-width pane, an on-screen row for the keys a terminal needs (Esc, Tab, Ctrl+C, arrows), and a wheel that scrolls a full-screen CLI's own view. |
72
+
73
+ Not built, on purpose: subagent visualisation, a respawn controller, multi-host, a Ralph loop. Those need to know which vendor is talking. This product does not.
74
+
75
+ What is next, and why that order: [ROADMAP.md](ROADMAP.md). What shipped: [CHANGELOG.md](CHANGELOG.md).
76
+
77
+ ## Quick start
78
+
79
+ Needs **Python 3.11+** and **tmux**. Nothing else.
80
+
81
+ ```bash
82
+ git clone https://github.com/thejdubb02/clique.git
83
+ cd clique
84
+ python3 -m clique password # prompted; stored as an scrypt hash
85
+ python3 -m clique # http://127.0.0.1:3200
86
+ ```
87
+
88
+ State lives in `$CLIQUE_HOME`, default `~/.clique`. To edit the CLI catalogue,
89
+ `python3 -m clique config` drops one where your edits survive an upgrade.
90
+
91
+ Once it is on PyPI, `pip install clique-panel` gives you a `clique` command
92
+ (the package is `clique-panel` because `clique` there is an unrelated library).
93
+
94
+ It binds to loopback on purpose. Put a tunnel in front of it (Tailscale Serve, Caddy, nginx) if you want it from another machine. Do not bind it to the public internet. Anyone who reaches the panel has a terminal as the user that started it.
95
+
96
+ ```bash
97
+ # optional: behind Tailscale
98
+ tailscale serve --bg --set-path /clique http://127.0.0.1:3200
99
+ ```
100
+
101
+ A systemd user unit is in [`deploy/`](deploy/README.md).
102
+
103
+ `GET /healthz` answers without a login (`{"ok":true}` and nothing else), so Uptime Kuma, Gatus or Healthchecks can watch it.
104
+
105
+ ## Adding a CLI
106
+
107
+ A block in [`clique/config/clis.toml`](clique/config/clis.toml). Reload the page. No restart, no code:
108
+
109
+ ```toml
110
+ [cli.grok]
111
+ label = "Grok CLI"
112
+ command = "grok"
113
+ args = []
114
+ color = "#6f42c1"
115
+ ```
116
+
117
+ There is no per-CLI branch in the codebase. If adding one ever needs a code change, the design has failed.
118
+
119
+ Claude Code and Gemini CLI can also declare an **autonomy pill** (the mode above the prompt). That is four keys in the same block (`modes`, `mode_key`, `mode_label`), documented in the comments of `clis.toml`. Omit them and the pill stays hidden, which is the right default for a CLI whose approval is a launch flag.
120
+
121
+ ## Why it is stdlib-only
122
+
123
+ A coding-agent session already costs hundreds of megabytes. The manager's job is to disappear into that budget. Measured: **24 MB resident**.
124
+
125
+ That also means the real ceiling on concurrent sessions is the agents, not this. On a 16 GB box with ~9 GB free, roughly a dozen at once.
126
+
127
+ ## Design notes that are easy to get wrong
128
+
129
+ - **Own tmux server** (`tmux -L clique`). Isolated from everything else on the box.
130
+ - **A PTY exists only while a browser is attached.** An idle session costs this process nothing; cost scales with open tabs, not with session count.
131
+ - **Each viewer gets its own grouped tmux session.** Plain `attach` makes every client share one size, so tmux shrinks the pane to the smallest watcher.
132
+ - **Closing a tab is not killing a session.** Detach sends SIGHUP; tmux and the CLI carry on.
133
+ - **`kill()` refuses sessions that are not ours** unless forced.
134
+
135
+ ## Tests
136
+
137
+ Neither suite is mocked. The failure modes worth catching (tmux quoting, a PTY that never gets its first byte) only exist across a real socket. GitHub Actions runs all three on every push. They start their own panel and tmux server, so they cannot touch the one you are using.
138
+
139
+ ```bash
140
+ python3 tools/smoke.py # engine, against a real tmux server
141
+ python3 tools/smoke_http.py # server, over real HTTP + WebSocket
142
+ python3 tools/api_drift.py # API.md still covers every route and setting
143
+ ruff check .
144
+ ```
145
+
146
+ They will not catch a UI that renders wrong. Open the page for that.
147
+
148
+ ## Contributing
149
+
150
+ Patches welcome, with a short filter: [CONTRIBUTING.md](CONTRIBUTING.md). Feature ideas that need to know which vendor is talking get refused. That is the product, not a freeze.
151
+
152
+ ## Support the dev
153
+
154
+ Free, and staying that way. If it saved you an afternoon, this is the tip jar.
155
+
156
+ **[Buy me a coffee](https://buymeacoffee.com/jdubb)**
157
+
158
+ | | Network | Address |
159
+ |---|---|---|
160
+ | **BTC** | Bitcoin | `3A3nA8BQFmXdvyUQokHhPd8HAd99wRDYFQ` |
161
+ | **SHIB** | Ethereum | `0x6b5DEd92946692D50642dC3af169727225E32D3b` |
162
+ | **DOGE** | Dogecoin | `DNiJeUJUVaVTDuteLXCtP7JVgvdL2NqoYp` |
163
+
164
+ ## License
165
+
166
+ [MIT](LICENSE). Built by [Justin Willhite](https://github.com/thejdubb02).
167
+
168
+ A hole that reaches a terminal is a [private advisory](https://github.com/thejdubb02/clique/security/advisories/new), not a public issue. See [SECURITY.md](SECURITY.md).
@@ -0,0 +1,40 @@
1
+ """CLIque — Your private clique of CLIs.
2
+
3
+ Folder-organised, CLI-agnostic terminal sessions in a browser, kept alive in tmux.
4
+ """
5
+
6
+ from __future__ import annotations
7
+
8
+ import subprocess
9
+ from functools import lru_cache
10
+ from pathlib import Path
11
+
12
+ #: Semver, bumped with every release-worthy change and shown in the sidebar.
13
+ #: Minor for features, patch for fixes. The version alone is not enough to
14
+ #: identify a build during active development, which is what build_id is for.
15
+ __version__ = "0.50.54"
16
+
17
+
18
+ @lru_cache(maxsize=1)
19
+ def build_id() -> str:
20
+ """Short commit of the working tree, or "" outside a checkout.
21
+
22
+ A bug report that says "0.2.0" during a week of daily commits names a
23
+ range, not a build. This makes it name a commit.
24
+ """
25
+ try:
26
+ result = subprocess.run(
27
+ ["git", "-C", str(Path(__file__).resolve().parents[1]),
28
+ "rev-parse", "--short", "HEAD"],
29
+ capture_output=True, text=True, timeout=5,
30
+ )
31
+ if result.returncode == 0:
32
+ return result.stdout.strip()
33
+ except (OSError, subprocess.SubprocessError):
34
+ pass
35
+ return ""
36
+
37
+
38
+ def version_string() -> str:
39
+ build = build_id()
40
+ return f"{__version__}+{build}" if build else __version__