@bakapiano/ccsm 0.22.5 → 0.22.7
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.
- package/CLAUDE.md +538 -538
- package/README.md +189 -189
- package/bin/ccsm.js +235 -235
- package/lib/cliActivity.js +139 -139
- package/lib/codexSeed.js +183 -183
- package/lib/config.js +279 -274
- package/lib/devices.js +229 -229
- package/lib/folders.js +124 -124
- package/lib/localCliSessions.js +519 -519
- package/lib/persistedSessions.js +129 -129
- package/lib/tunnel.js +621 -621
- package/lib/webTerminal.js +225 -225
- package/lib/workspace.js +233 -233
- package/package.json +57 -57
- package/public/css/base.css +99 -99
- package/public/css/cards.css +183 -183
- package/public/css/feedback.css +504 -504
- package/public/css/forms.css +453 -453
- package/public/css/layout.css +177 -176
- package/public/css/modal.css +190 -190
- package/public/css/responsive.css +176 -176
- package/public/css/sidebar.css +707 -707
- package/public/css/terminals.css +547 -553
- package/public/css/tokens.css +81 -81
- package/public/css/wco.css +196 -196
- package/public/css/widgets.css +2725 -2725
- package/public/index.html +152 -152
- package/public/js/api.js +371 -371
- package/public/js/backend.js +149 -149
- package/public/js/components/App.js +73 -73
- package/public/js/components/DirectoryPicker.js +203 -203
- package/public/js/components/EntityFormModal.js +153 -153
- package/public/js/components/Modal.js +57 -57
- package/public/js/components/OfflineBanner.js +67 -67
- package/public/js/components/PageTitleBar.js +13 -13
- package/public/js/components/PendingApprovalOverlay.js +128 -128
- package/public/js/components/Picker.js +179 -179
- package/public/js/components/Popover.js +55 -55
- package/public/js/components/RestartOverlay.js +36 -36
- package/public/js/components/Sidebar.js +380 -380
- package/public/js/components/TerminalInstance.js +28 -9
- package/public/js/components/XtermTerminal.js +62 -2
- package/public/js/components/useDragSort.js +67 -67
- package/public/js/dialog.js +67 -67
- package/public/js/icons.js +212 -212
- package/public/js/main.js +296 -296
- package/public/js/pages/AboutPage.js +90 -90
- package/public/js/pages/ConfigurePage.js +728 -713
- package/public/js/pages/LaunchPage.js +421 -421
- package/public/js/pages/RemotePage.js +743 -743
- package/public/js/pages/SessionsPage.js +73 -80
- package/public/js/state.js +335 -335
- package/scripts/dev.js +149 -149
- package/scripts/install.js +153 -153
- package/scripts/restart-helper.js +96 -96
- package/scripts/upgrade-helper.js +687 -687
- package/server.js +1820 -1807
- package/public/manifest.webmanifest +0 -25
- package/public/setup/index.html +0 -567
package/README.md
CHANGED
|
@@ -1,189 +1,189 @@
|
|
|
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
|
-
[](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, and re-attaches to the exact
|
|
6
|
+
upstream conversation when you click it again.
|
|
7
|
+
|
|
8
|
+
[](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.
|