@bakapiano/ccsm 0.22.6 → 0.22.8

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 (61) hide show
  1. package/CLAUDE.md +521 -540
  2. package/README.md +186 -189
  3. package/bin/ccsm.js +235 -235
  4. package/lib/cliActivity.js +36 -139
  5. package/lib/codexSeed.js +126 -183
  6. package/lib/config.js +277 -274
  7. package/lib/devices.js +229 -229
  8. package/lib/folders.js +124 -124
  9. package/lib/persistedSessions.js +179 -139
  10. package/lib/tunnel.js +621 -621
  11. package/lib/webTerminal.js +225 -225
  12. package/lib/winPath.js +1 -1
  13. package/lib/workspace.js +233 -233
  14. package/package.json +57 -57
  15. package/public/css/base.css +99 -99
  16. package/public/css/cards.css +183 -183
  17. package/public/css/feedback.css +504 -504
  18. package/public/css/forms.css +453 -453
  19. package/public/css/layout.css +154 -154
  20. package/public/css/modal.css +190 -190
  21. package/public/css/responsive.css +176 -176
  22. package/public/css/sidebar.css +707 -707
  23. package/public/css/terminals.css +546 -546
  24. package/public/css/tokens.css +81 -81
  25. package/public/css/wco.css +196 -196
  26. package/public/css/widgets.css +2347 -2725
  27. package/public/index.html +152 -152
  28. package/public/js/api.js +349 -371
  29. package/public/js/backend.js +149 -149
  30. package/public/js/components/App.js +73 -73
  31. package/public/js/components/DirectoryPicker.js +203 -203
  32. package/public/js/components/EntityFormModal.js +153 -153
  33. package/public/js/components/Modal.js +57 -57
  34. package/public/js/components/OfflineBanner.js +67 -67
  35. package/public/js/components/PageTitleBar.js +13 -13
  36. package/public/js/components/PendingApprovalOverlay.js +128 -128
  37. package/public/js/components/Picker.js +179 -179
  38. package/public/js/components/Popover.js +55 -55
  39. package/public/js/components/RestartOverlay.js +36 -36
  40. package/public/js/components/Sidebar.js +380 -380
  41. package/public/js/components/TerminalInstance.js +28 -0
  42. package/public/js/components/useDragSort.js +67 -67
  43. package/public/js/dialog.js +67 -67
  44. package/public/js/icons.js +212 -212
  45. package/public/js/main.js +296 -296
  46. package/public/js/pages/AboutPage.js +90 -90
  47. package/public/js/pages/ConfigurePage.js +730 -713
  48. package/public/js/pages/LaunchPage.js +403 -421
  49. package/public/js/pages/RemotePage.js +743 -743
  50. package/public/js/pages/SessionsPage.js +54 -54
  51. package/public/js/state.js +335 -335
  52. package/public/js/util.js +1 -1
  53. package/scripts/dev.js +149 -149
  54. package/scripts/install.js +153 -153
  55. package/scripts/restart-helper.js +96 -96
  56. package/scripts/upgrade-helper.js +687 -687
  57. package/server.js +1748 -1817
  58. package/lib/localCliSessions.js +0 -519
  59. package/public/js/components/AdoptModal.js +0 -261
  60. package/public/manifest.webmanifest +0 -25
  61. package/public/setup/index.html +0 -567
package/README.md CHANGED
@@ -1,189 +1,186 @@
1
- # ccsm — Claude Code Session Manager
2
-
3
- A single pane over every Claude / Codex / Copilot CLI session on your
4
- machine. Each session runs inside the page (xterm.js + a PTY pool in
5
- the local backend), gets recorded, and re-attaches to the exact
6
- upstream conversation when you click it again.
7
-
8
- [![open](https://img.shields.io/badge/open-bakapiano.github.io%2Fccsm-1a1815?style=flat-square)](https://bakapiano.github.io/ccsm/)
9
-
10
- ```
11
- ┌── browser ─────────────────────────┐
12
- │ https://bakapiano.github.io/ccsm/ ← version router
13
- │ ↓
14
- │ /ccsm/X.Y.Z/ ← per-version frontend (pinned to your backend)
15
- └────────────┬───────────────────────┘
16
- │ fetch /api/* (CORS)
17
- │ ws://localhost:7777/ws/*
18
-
19
- ┌── local backend ───────────────────┐
20
- │ ccsm (npm bin) │
21
- │ ├── /api/sessions /api/sessions/new │
22
- │ ├── /api/sessions/:id/resume │
23
- │ ├── /api/sessions/adopt
24
- │ ├── /api/version /api/upgrade
25
- ├── /ws/terminal/:id (PTY)
26
- │ └── /api/health /api/heartbeat │
27
- └────────────────────────────────────┘
28
- ```
29
-
30
- ## What it does
31
-
32
- - **Runs every CLI session in the page.** `claude`, `codex`, `copilot`
33
- or any custom command, in an xterm.js panel. Switch sessions in the
34
- sidebar; the PTY keeps running in the backend.
35
- - **`--resume <uuid>` precision.** ccsm watches the upstream CLI's
36
- transcript dir after spawn and captures its session UUID. Click a
37
- stopped session later → re-spawns with `--resume <uuid>` (or
38
- whatever `resumeIdArgs` template you set per-CLI) so the exact
39
- conversation comes back.
40
- - **Import existing sessions.** Scans `~/.claude` / `~/.codex` /
41
- `~/.copilot` and lets you adopt any session ccsm didn't start.
42
- - **Workspaces + clones.** "New session" picks an unused workspace
43
- under your work-dir, clones selected repos with live `git clone
44
- --progress` streamed to per-repo progress bars, opens a fresh CLI
45
- there. Or pick any existing folder via the file browser.
46
- - **Folders.** Drag sessions into named folders for organisation.
47
- - **In-app upgrade.** About page checks npm for newer versions of
48
- ccsm and offers a one-click upgrade button. Backend self-restarts.
49
-
50
- ## Install
51
-
52
- ```bash
53
- npm i -g @bakapiano/ccsm
54
- ```
55
-
56
- This:
57
- - puts `ccsm` on your PATH
58
- - registers a `ccsm://` URL protocol so the hosted frontend can wake
59
- the backend with one click
60
-
61
- `npx @bakapiano/ccsm` works too for a one-shot trial — the protocol
62
- still gets registered.
63
-
64
- ## Use
65
-
66
- ```bash
67
- ccsm # starts the backend, opens the frontend
68
- ```
69
-
70
- Or just visit **https://bakapiano.github.io/ccsm/** in any browser.
71
- If the backend isn't running, the router shows a "Backend not running"
72
- banner with a **Start ccsm** button click it, Windows asks once
73
- whether to open the `ccsm://` handler (check "Always allow"), and the
74
- backend spawns silently behind the page. The router auto-reconnects in
75
- 1-2s and redirects to the frontend matching your installed backend
76
- version.
77
-
78
- ### Install as PWA
79
-
80
- In Chrome / Edge, click the install icon in the address bar (or use the
81
- "Install ccsm" button on the **About** tab inside the app). The PWA gets
82
- its own window, its own icon, and Window Controls Overlay so the title
83
- bar blends into the page.
84
-
85
- After installing, clicking the PWA icon is the new entry point — no
86
- terminal needed.
87
-
88
- ## Defaults
89
-
90
- | | |
91
- |---|---|
92
- | Port | `7777` (auto-bumps if taken) |
93
- | Work dir | `~/ccsm-workspaces` (each subdirectory holds one or more repo clones) |
94
- | Built-in CLIs | `claude`, `codex`, `copilot` — add your own via the **Configure** tab |
95
- | Data dir | `~/.ccsm/` (override with `CCSM_HOME=<path>`) survives upgrades and npx cache wipes |
96
-
97
- All of the above are editable through the **Configure** tab.
98
-
99
- ## Layout
100
-
101
- ```
102
- ccsm/
103
- ├── server.js # Express + WebSocket; API only in prod
104
- ├── bin/ccsm.js # launcher · detaches server, opens browser
105
- ├── scripts/
106
- ├── install.js # postinstall · registers ccsm:// (Windows)
107
- └── uninstall.js # preuninstall · cleanup
108
- ├── lib/
109
- │ ├── persistedSessions.js # ~/.ccsm/sessions.json the source of truth
110
- │ ├── folders.js # sidebar tree
111
- │ ├── localCliSessions.js # scan ~/.claude · ~/.codex · ~/.copilot
112
- ├── workspace.js # ws-N allocation + repo clones
113
- │ ├── webTerminal.js # node-pty pool · WebSocket bridge
114
- │ ├── jsonStore.js · config.js
115
- ├── pages-root/ # GH Pages / (version router)
116
- └── public/ # → GH Pages /<pkg.version>/ (per-version frontend)
117
-
118
- ~/.ccsm/ # or $CCSM_HOME
119
- ├── config.json
120
- ├── sessions.json # persisted sessions
121
- ├── folders.json
122
- ├── server.log
123
- └── browser-profile/ # Edge/Chrome --user-data-dir
124
- ```
125
-
126
- ## How "wake on click" works
127
-
128
- The hosted frontend lives entirely in the browser sandbox it cannot
129
- spawn processes. So when the backend is down, the OfflineBanner's
130
- **Start ccsm** is a plain `<a href="ccsm://start">`. The OS hands that
131
- off to a per-user URL protocol handler registered at install time:
132
-
133
- ```
134
- HKCU\Software\Classes\ccsm\shell\open\command
135
- wscript.exe "<LOCALAPPDATA>\ccsm\launcher.vbs" "%1"
136
- ```
137
-
138
- The `.vbs` calls `ccsm.cmd "ccsm://start"` with `WindowStyle = 0`. That
139
- gets to `bin/ccsm.js`, which parses the protocol URL, spawns
140
- `server.js` detached, and exits. Zero windows ever flash.
141
-
142
- First click triggers a one-time Windows dialog ("Open ccsm.cmd?"). Tick
143
- **Always allow** and future clicks are silent.
144
-
145
- ## Lifecycle (when does the backend die)
146
-
147
- | trigger | reaction |
148
- |---|---|
149
- | The auto-opened browser window closes | wait 12s · if any other client heartbeats during that window, stay alive; otherwise gracefulShutdown |
150
- | No heartbeat for 90s | gracefulShutdown |
151
- | `POST /api/shutdown` | gracefulShutdown |
152
- | `POST /api/upgrade` after install | self-respawn + gracefulShutdown |
153
- | SIGINT / SIGTERM | gracefulShutdown |
154
-
155
- ## Dev
156
-
157
- ```bash
158
- git clone https://github.com/bakapiano/ccsm
159
- cd ccsm
160
- npm install
161
- CCSM_NO_BROWSER=1 CCSM_KEEP_ALIVE=1 node server.js
162
- # opens http://localhost:7777 with hot-reload (public/ is served locally
163
- # and SSE pushes a reload event on every file save)
164
- ```
165
-
166
- Dev mode is detected via `__dirname.includes('node_modules')` — when
167
- running from a checkout, the backend also serves `public/`. In an
168
- npm-installed copy it's API-only, and you use the hosted frontend.
169
-
170
- ## Versioning (frontend backend)
171
-
172
- The hosted root (`/ccsm/`) is a tiny static **version router**: it
173
- probes `localhost:7777/api/health`, then redirects you to
174
- `/ccsm/<backend.version>/`. Each release publishes a fresh
175
- per-version subdir; old ones stay forever. No semver-compat logic — a
176
- frontend is always 1:1 with the backend it was built against.
177
-
178
- If your backend gets upgraded under a still-loaded page, the
179
- per-version frontend detects the mismatch on its next probe and
180
- bounces you back through the router automatically.
181
-
182
- ## Status
183
-
184
- - Backend: Windows-first. macOS / Linux backend ports planned (URL
185
- protocol registration is the only platform-specific install piece).
186
- - Frontend: cross-platform (pure web).
187
-
188
- See [CLAUDE.md](CLAUDE.md) for design decisions and the non-obvious
189
- gotchas baked into the launcher / session-watcher / lifecycle code.
1
+ # ccsm — Claude Code Session Manager
2
+
3
+ A single pane over every Claude / Codex / Copilot CLI session on your
4
+ machine. Each session runs inside the page (xterm.js + a PTY pool in
5
+ the local backend), gets recorded by filesystem folder, and resumes in
6
+ that folder when you click it again.
7
+
8
+ [![open](https://img.shields.io/badge/open-bakapiano.github.io%2Fccsm-1a1815?style=flat-square)](https://bakapiano.github.io/ccsm/)
9
+
10
+ ```
11
+ ┌── browser ─────────────────────────┐
12
+ │ https://bakapiano.github.io/ccsm/ ← version router
13
+ │ ↓
14
+ │ /ccsm/X.Y.Z/ ← per-version frontend (pinned to your backend)
15
+ └────────────┬───────────────────────┘
16
+ │ fetch /api/* (CORS)
17
+ │ ws://localhost:7777/ws/*
18
+
19
+ ┌── local backend ───────────────────┐
20
+ │ ccsm (npm bin) │
21
+ │ ├── /api/sessions /api/sessions/new │
22
+ │ ├── /api/sessions/:id/resume │
23
+ │ ├── /api/version /api/upgrade
24
+ │ ├── /ws/terminal/:id (PTY)
25
+ └── /api/health /api/heartbeat
26
+ └────────────────────────────────────┘
27
+ ```
28
+
29
+ ## What it does
30
+
31
+ - **Runs every CLI session in the page.** `claude`, `codex`, `copilot`
32
+ or any custom command, in an xterm.js panel. Switch sessions in the
33
+ sidebar; the PTY keeps running in the backend.
34
+ - **Folder-level resume.** ccsm stores the CLI and `cwd` for each
35
+ session. Click a stopped session later and ccsm launches the CLI in
36
+ that folder using either the configured "resume latest" command or
37
+ the CLI's resume picker.
38
+ - **Workspaces + clones.** "New session" picks an unused workspace
39
+ under your work-dir, clones selected repos with live `git clone
40
+ --progress` streamed to per-repo progress bars, and opens a fresh CLI
41
+ in the single selected repo or at the workspace root for zero/multiple
42
+ repos. Or pick any existing folder via the file browser.
43
+ - **Folders.** Drag sessions into named folders for organisation.
44
+ - **In-app upgrade.** About page checks npm for newer versions of
45
+ ccsm and offers a one-click upgrade button. Backend self-restarts.
46
+
47
+ ## Install
48
+
49
+ ```bash
50
+ npm i -g @bakapiano/ccsm
51
+ ```
52
+
53
+ This:
54
+ - puts `ccsm` on your PATH
55
+ - registers a `ccsm://` URL protocol so the hosted frontend can wake
56
+ the backend with one click
57
+
58
+ `npx @bakapiano/ccsm` works too for a one-shot trial the protocol
59
+ still gets registered.
60
+
61
+ ## Use
62
+
63
+ ```bash
64
+ ccsm # starts the backend, opens the frontend
65
+ ```
66
+
67
+ Or just visit **https://bakapiano.github.io/ccsm/** in any browser.
68
+ If the backend isn't running, the router shows a "Backend not running"
69
+ banner with a **Start ccsm** button — click it, Windows asks once
70
+ whether to open the `ccsm://` handler (check "Always allow"), and the
71
+ backend spawns silently behind the page. The router auto-reconnects in
72
+ 1-2s and redirects to the frontend matching your installed backend
73
+ version.
74
+
75
+ ### Install as PWA
76
+
77
+ In Chrome / Edge, click the install icon in the address bar (or use the
78
+ "Install ccsm" button on the **About** tab inside the app). The PWA gets
79
+ its own window, its own icon, and Window Controls Overlay so the title
80
+ bar blends into the page.
81
+
82
+ After installing, clicking the PWA icon is the new entry point no
83
+ terminal needed.
84
+
85
+ ## Defaults
86
+
87
+ | | |
88
+ |---|---|
89
+ | Port | `7777` (auto-bumps if taken) |
90
+ | Work dir | `~/ccsm-workspaces` (each subdirectory holds one or more repo clones) |
91
+ | Built-in CLIs | `claude`, `codex`, `copilot` — add your own via the **Configure** tab |
92
+ | Resume behavior | `latest` by default; switch to `picker` in **Configure** |
93
+ | Data dir | `~/.ccsm/` (override with `CCSM_HOME=<path>`) survives upgrades and npx cache wipes |
94
+
95
+ All of the above are editable through the **Configure** tab.
96
+
97
+ ## Layout
98
+
99
+ ```
100
+ ccsm/
101
+ ├── server.js # Express + WebSocket; API only in prod
102
+ ├── bin/ccsm.js # launcher · detaches server, opens browser
103
+ ├── scripts/
104
+ ├── install.js # postinstall · registers ccsm:// (Windows)
105
+ │ └── uninstall.js # preuninstall · cleanup
106
+ ├── lib/
107
+ ├── persistedSessions.js # ~/.ccsm/sessions.json the source of truth
108
+ ├── folders.js # sidebar tree
109
+ │ ├── workspace.js # ws-N allocation + repo clones
110
+ │ ├── webTerminal.js # node-pty pool · WebSocket bridge
111
+ │ ├── jsonStore.js · config.js
112
+ ├── pages-root/ # GH Pages / (version router)
113
+ └── public/ # GH Pages /<pkg.version>/ (per-version frontend)
114
+
115
+ ~/.ccsm/ # or $CCSM_HOME
116
+ ├── config.json
117
+ ├── sessions.json # persisted sessions
118
+ ├── folders.json
119
+ ├── server.log
120
+ └── browser-profile/ # Edge/Chrome --user-data-dir
121
+ ```
122
+
123
+ ## How "wake on click" works
124
+
125
+ The hosted frontend lives entirely in the browser sandbox — it cannot
126
+ spawn processes. So when the backend is down, the OfflineBanner's
127
+ **Start ccsm** is a plain `<a href="ccsm://start">`. The OS hands that
128
+ off to a per-user URL protocol handler registered at install time:
129
+
130
+ ```
131
+ HKCU\Software\Classes\ccsm\shell\open\command
132
+ → wscript.exe "<LOCALAPPDATA>\ccsm\launcher.vbs" "%1"
133
+ ```
134
+
135
+ The `.vbs` calls `ccsm.cmd "ccsm://start"` with `WindowStyle = 0`. That
136
+ gets to `bin/ccsm.js`, which parses the protocol URL, spawns
137
+ `server.js` detached, and exits. Zero windows ever flash.
138
+
139
+ First click triggers a one-time Windows dialog ("Open ccsm.cmd?"). Tick
140
+ **Always allow** and future clicks are silent.
141
+
142
+ ## Lifecycle (when does the backend die)
143
+
144
+ | trigger | reaction |
145
+ |---|---|
146
+ | The auto-opened browser window closes | wait 12s · if any other client heartbeats during that window, stay alive; otherwise gracefulShutdown |
147
+ | No heartbeat for 90s | gracefulShutdown |
148
+ | `POST /api/shutdown` | gracefulShutdown |
149
+ | `POST /api/upgrade` after install | self-respawn + gracefulShutdown |
150
+ | SIGINT / SIGTERM | gracefulShutdown |
151
+
152
+ ## Dev
153
+
154
+ ```bash
155
+ git clone https://github.com/bakapiano/ccsm
156
+ cd ccsm
157
+ npm install
158
+ CCSM_NO_BROWSER=1 CCSM_KEEP_ALIVE=1 node server.js
159
+ # opens http://localhost:7777 with hot-reload (public/ is served locally
160
+ # and SSE pushes a reload event on every file save)
161
+ ```
162
+
163
+ Dev mode is detected via `__dirname.includes('node_modules')` when
164
+ running from a checkout, the backend also serves `public/`. In an
165
+ npm-installed copy it's API-only, and you use the hosted frontend.
166
+
167
+ ## Versioning (frontend backend)
168
+
169
+ The hosted root (`/ccsm/`) is a tiny static **version router**: it
170
+ probes `localhost:7777/api/health`, then redirects you to
171
+ `/ccsm/<backend.version>/`. Each release publishes a fresh
172
+ per-version subdir; old ones stay forever. No semver-compat logic a
173
+ frontend is always 1:1 with the backend it was built against.
174
+
175
+ If your backend gets upgraded under a still-loaded page, the
176
+ per-version frontend detects the mismatch on its next probe and
177
+ bounces you back through the router automatically.
178
+
179
+ ## Status
180
+
181
+ - Backend: Windows-first. macOS / Linux backend ports planned (URL
182
+ protocol registration is the only platform-specific install piece).
183
+ - Frontend: cross-platform (pure web).
184
+
185
+ See [CLAUDE.md](CLAUDE.md) for design decisions and the non-obvious
186
+ gotchas baked into the launcher, session lifecycle, and workspace code.