@tom2012/cc-web 1.5.19 → 1.5.21

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/README.md CHANGED
@@ -1,8 +1,8 @@
1
1
  # CC Web
2
2
 
3
- A self-hosted web application (and macOS Electron desktop app) that provides a browser-based interface for [Claude Code](https://docs.anthropic.com/en/docs/claude-code) CLI sessions. Create projects, each with a persistent terminal running Claude Code, and interact with them through a real-time terminal UI.
3
+ A self-hosted web application (distributed as npm package) that provides a browser-based interface for [Claude Code](https://docs.anthropic.com/en/docs/claude-code) CLI sessions. Create projects, each with a persistent terminal running Claude Code, and interact with them through a real-time terminal UI.
4
4
 
5
- **Current version**: v1.5.19 | [GitHub](https://github.com/zbc0315/cc-web) | MIT License
5
+ **Current version**: v1.5.21 | [GitHub](https://github.com/zbc0315/cc-web) | MIT License
6
6
 
7
7
  ## Features
8
8
 
@@ -16,7 +16,7 @@ A self-hosted web application (and macOS Electron desktop app) that provides a b
16
16
  - **File Browser**: Browse directories and preview/edit files with zoom-level memory per file
17
17
  - **Auto-restart**: Terminals automatically recover from crashes
18
18
  - **Usage Tracking**: Monitor Claude Code plan usage directly from the dashboard
19
- - **In-app Updates**: Check GitHub releases, download, and install without leaving the app
19
+ - **CLI Update**: `ccweb update` stops the server and updates to the latest npm version
20
20
  - **Localhost Auto-auth**: Local access skips login entirely; JWT only required for remote access
21
21
  - **Auto Port Switching**: Backend tries ports 3001–3020 and reports the actual port
22
22
  - **Network Access Modes**: Local only (127.0.0.1), LAN (private IPs), or public — selectable at startup
@@ -57,6 +57,7 @@ ccweb stop # stop background server
57
57
  ccweb status # show PID, port, data location
58
58
  ccweb open # open browser to running server
59
59
  ccweb setup # reconfigure username / password
60
+ ccweb update # stop server & update to latest version
60
61
  ccweb enable-autostart # start automatically on login
61
62
  ccweb disable-autostart # remove auto-start
62
63
  ccweb logs # tail background log file
@@ -116,7 +117,7 @@ Browser (React/Vite :5173 dev | Express :3001 prod)
116
117
  | `usage-terminal.ts` | Claude Code OAuth usage stats |
117
118
  | `routes/auth.ts` | `POST /login`, `GET /local-token` (localhost only) |
118
119
  | `routes/projects.ts` | CRUD + start/stop + `POST /open` (restore from `.ccweb/`) |
119
- | `routes/update.ts` | `GET /check-running`, `POST /prepare` (save memory → wait idle → stop all) |
120
+ | `routes/update.ts` | `GET /check-running`, `POST /prepare` (save memory → wait idle → stop all, used by in-app update flow) |
120
121
  | `routes/filesystem.ts` | Directory browser, file read/write |
121
122
  | `routes/shortcuts.ts` | Global shortcut CRUD with inheritance |
122
123
  | `routes/backup.ts` | Cloud backup API (providers, OAuth, backup trigger, schedule) |
@@ -140,7 +141,7 @@ Browser (React/Vite :5173 dev | Express :3001 prod)
140
141
  | `components/GraphPreview.tsx` | SVG topology graph of `.notebook/graph.yaml` (layered DAG, zoom/pan) |
141
142
  | `components/FileTree.tsx` | Expandable directory tree |
142
143
  | `components/FilePreviewDialog.tsx` | File viewer with plain/rendered/edit modes, zoom memory per file |
143
- | `components/UpdateButton.tsx` | In-app update: check GitHub → save memory → download → install |
144
+ | `components/UpdateButton.tsx` | Version display and update check |
144
145
  | `components/OpenProjectDialog.tsx` | Open existing project from `.ccweb/` folder |
145
146
  | `components/NewProjectDialog.tsx` | 3-step wizard: name → folder → permissions |
146
147
  | `lib/api.ts` | Typed REST client, dynamic base URL (relative in prod, localhost:3001 in dev) |
@@ -149,7 +150,7 @@ Browser (React/Vite :5173 dev | Express :3001 prod)
149
150
 
150
151
  ### Data Storage
151
152
 
152
- **Application data** (`data/` gitignored, or `~/Library/Application Support/cc-web/data/` in Electron):
153
+ **Application data** (`~/.ccweb/` for npm install, `data/` for dev):
153
154
 
154
155
  ```
155
156
  data/
@@ -226,33 +227,7 @@ Localhost WebSocket connections are pre-authenticated — no `auth` message need
226
227
  | `GET/PUT` | `/api/backup/excludes` | Exclude patterns |
227
228
  | `GET` | `/api/backup/history` | Backup history |
228
229
 
229
- ## macOS Desktop App (Electron)
230
-
231
- CC Web can be packaged as a standalone macOS app using Electron.
232
-
233
- ```bash
234
- # Install all dependencies first
235
- npm run install:all
236
- npm install
237
-
238
- # Build DMG (outputs to release/)
239
- npm run dist:dmg
240
- ```
241
-
242
- The DMG will be at `release/CCWeb-{version}-arm64.dmg`. Double-click to install.
243
-
244
- On first launch, the app auto-generates login credentials and displays them in a dialog. Local access (localhost) skips login entirely. You'll need `claude` CLI installed and authenticated on your machine.
245
-
246
- **Update flow**: Download zip from GitHub releases → extract with `ditto` → replace app via detached shell script (no code signing required).
247
-
248
- ### Building for other architectures
249
-
250
- Edit the `arch` field in `package.json` under `build.mac.target`:
251
- - `["arm64"]` — Apple Silicon (default)
252
- - `["x64"]` — Intel Mac
253
- - `["arm64", "x64"]` — Universal
254
-
255
- ## Server Deployment (without Electron)
230
+ ## Server Deployment
256
231
 
257
232
  ```bash
258
233
  # Build everything
@@ -279,37 +254,26 @@ Environment variables:
279
254
  ## Build & Release
280
255
 
281
256
  ```bash
282
- # Full build (frontend + backend + electron)
283
- npm run build:all
284
-
285
- # Build DMG + ZIP for release
286
- npm run dist
257
+ # Full build (frontend + backend)
258
+ npm run build
287
259
 
288
260
  # Release checklist:
289
- # 1. Bump version in package.json
290
- # 2. Update currentVersion in frontend/src/components/UpdateButton.tsx
291
- # 3. npm run dist
261
+ # 1. Bump version in package.json, UpdateButton.tsx, README.md, CLAUDE.md
262
+ # 2. Update docs with new features
263
+ # 3. npm run build
292
264
  # 4. git add -A && git commit && git push
293
- # 5. gh release create vX.Y.Z --title "CCWeb vX.Y.Z" \
294
- # release/CCWeb-X.Y.Z-arm64.dmg \
295
- # release/CCWeb-X.Y.Z-arm64-mac.zip \
296
- # release/CCWeb-X.Y.Z-arm64-mac.zip.blockmap \
297
- # release/latest-mac.yml
265
+ # 5. npm publish --registry https://registry.npmjs.org --access=public
298
266
  ```
299
267
 
300
- > **Note**: `productName` in `package.json` must not contain spaces (currently `CCWeb`), otherwise GitHub mangles the filename and auto-update gets 404.
301
-
302
268
  ## Development Guide
303
269
 
304
270
  ### Project Structure
305
271
 
306
272
  ```
307
273
  cc-web/
308
- ├── package.json ← Root scripts + Electron build config
274
+ ├── package.json ← Root scripts + npm package config
275
+ ├── bin/ccweb.js ← CLI entry point (ccweb command)
309
276
  ├── setup.js ← Interactive credential setup
310
- ├── electron/
311
- │ ├── main.ts ← Electron main process
312
- │ └── tsconfig.json
313
277
  ├── backend/
314
278
  │ ├── package.json
315
279
  │ ├── tsconfig.json
@@ -331,7 +295,7 @@ cc-web/
331
295
  - **Scrollback buffer**: 5 MB per terminal for client reconnect replay.
332
296
  - **Session pruning**: Keeps latest 20 sessions per project, deletes oldest on new session start.
333
297
  - **Zoom memory**: `FilePreviewDialog` persists zoom level per file path in `localStorage`.
334
- - **Auto port switching**: Backend tries ports 3001–3020, reports actual port to Electron via IPC.
298
+ - **Auto port switching**: Backend tries ports 3001–3020, reports actual port via IPC.
335
299
  - **Localhost auto-auth**: Local requests skip JWT verification entirely.
336
300
 
337
301
  ### Adding a New API Endpoint
@@ -351,7 +315,6 @@ cc-web/
351
315
 
352
316
  **Backend**: Node.js, Express, WebSocket (ws), node-pty, TypeScript
353
317
  **Frontend**: React 18, Vite, Tailwind CSS, shadcn/ui, xterm.js, TypeScript
354
- **Desktop**: Electron
355
318
  **Auth**: JWT (bcryptjs for password hashing)
356
319
 
357
320
  ## License
package/bin/ccweb.js CHANGED
@@ -405,6 +405,36 @@ function showStatus() {
405
405
  }
406
406
  }
407
407
 
408
+ function updatePackage() {
409
+ // Stop running server first
410
+ const status = getStatus();
411
+ if (status.running) {
412
+ console.log('Stopping CCWeb...');
413
+ try {
414
+ process.kill(status.pid, 'SIGTERM');
415
+ try { fs.unlinkSync(PID_FILE); } catch {}
416
+ try { fs.unlinkSync(PORT_FILE); } catch {}
417
+ console.log(`Stopped (PID ${status.pid}).`);
418
+ } catch (err) {
419
+ console.error('Failed to stop:', err.message);
420
+ }
421
+ // Brief wait for process to fully exit
422
+ const deadline = Date.now() + 5000;
423
+ while (Date.now() < deadline && isProcessRunning(status.pid)) {
424
+ execSync('sleep 0.2');
425
+ }
426
+ }
427
+
428
+ console.log('\nUpdating @tom2012/cc-web to latest version...\n');
429
+ try {
430
+ execSync('npm install -g @tom2012/cc-web@latest', { stdio: 'inherit' });
431
+ console.log('\nUpdate complete! Run "ccweb" to start the new version.');
432
+ } catch (err) {
433
+ console.error('\nUpdate failed:', err.message);
434
+ process.exit(1);
435
+ }
436
+ }
437
+
408
438
  function showHelp() {
409
439
  console.log(`
410
440
  CCWeb — Self-hosted Claude Code web interface
@@ -421,6 +451,7 @@ Usage:
421
451
  ccweb status Show running status
422
452
  ccweb open Open browser to running server
423
453
  ccweb setup Reconfigure username / password
454
+ ccweb update Update to latest version
424
455
  ccweb enable-autostart Enable auto-start on login
425
456
  ccweb disable-autostart Disable auto-start on login
426
457
  ccweb logs Tail log file (background mode)
@@ -480,6 +511,10 @@ const accessModeFlag = args.includes('--local') ? 'local'
480
511
  await disableAutoStart();
481
512
  break;
482
513
 
514
+ case 'update':
515
+ updatePackage();
516
+ break;
517
+
483
518
  case 'logs': {
484
519
  if (!fs.existsSync(LOG_FILE)) { console.log('No log file found.'); break; }
485
520
  // Tail the log file (cross-platform)