@kaitranntt/ccs 5.9.0-dev.2 → 5.9.0-dev.4
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 +30 -2
- package/VERSION +1 -1
- package/dist/ccs.js +6 -0
- package/dist/ccs.js.map +1 -1
- package/dist/cliproxy/binary-manager.d.ts +2 -2
- package/dist/cliproxy/binary-manager.js +2 -2
- package/dist/cliproxy/platform-detector.d.ts +2 -2
- package/dist/cliproxy/platform-detector.js +1 -1
- package/dist/commands/cliproxy-command.d.ts.map +1 -1
- package/dist/commands/cliproxy-command.js +37 -28
- package/dist/commands/cliproxy-command.js.map +1 -1
- package/dist/commands/config-command.d.ts +11 -0
- package/dist/commands/config-command.d.ts.map +1 -0
- package/dist/commands/config-command.js +111 -0
- package/dist/commands/config-command.js.map +1 -0
- package/dist/commands/help-command.d.ts.map +1 -1
- package/dist/commands/help-command.js +3 -1
- package/dist/commands/help-command.js.map +1 -1
- package/dist/management/doctor.d.ts.map +1 -1
- package/dist/management/doctor.js +19 -7
- package/dist/management/doctor.js.map +1 -1
- package/dist/utils/port-utils.d.ts +19 -0
- package/dist/utils/port-utils.d.ts.map +1 -0
- package/dist/utils/port-utils.js +113 -0
- package/dist/utils/port-utils.js.map +1 -0
- package/dist/web-server/file-watcher.d.ts +15 -0
- package/dist/web-server/file-watcher.d.ts.map +1 -0
- package/dist/web-server/file-watcher.js +88 -0
- package/dist/web-server/file-watcher.js.map +1 -0
- package/dist/web-server/health-service.d.ts +35 -0
- package/dist/web-server/health-service.d.ts.map +1 -0
- package/dist/web-server/health-service.js +223 -0
- package/dist/web-server/health-service.js.map +1 -0
- package/dist/web-server/index.d.ts +25 -0
- package/dist/web-server/index.d.ts.map +1 -0
- package/dist/web-server/index.js +89 -0
- package/dist/web-server/index.js.map +1 -0
- package/dist/web-server/overview-routes.d.ts +7 -0
- package/dist/web-server/overview-routes.d.ts.map +1 -0
- package/dist/web-server/overview-routes.js +80 -0
- package/dist/web-server/overview-routes.js.map +1 -0
- package/dist/web-server/routes.d.ts +7 -0
- package/dist/web-server/routes.d.ts.map +1 -0
- package/dist/web-server/routes.js +444 -0
- package/dist/web-server/routes.js.map +1 -0
- package/dist/web-server/shared-routes.d.ts +7 -0
- package/dist/web-server/shared-routes.d.ts.map +1 -0
- package/dist/web-server/shared-routes.js +167 -0
- package/dist/web-server/shared-routes.js.map +1 -0
- package/dist/web-server/shutdown.d.ts +14 -0
- package/dist/web-server/shutdown.d.ts.map +1 -0
- package/dist/web-server/shutdown.js +36 -0
- package/dist/web-server/shutdown.js.map +1 -0
- package/dist/web-server/websocket.d.ts +14 -0
- package/dist/web-server/websocket.d.ts.map +1 -0
- package/dist/web-server/websocket.js +82 -0
- package/dist/web-server/websocket.js.map +1 -0
- package/package.json +25 -5
- package/scripts/pre-release.sh +39 -0
- package/scripts/verify-bundle.js +48 -0
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* Graceful Shutdown Handler
|
|
4
|
+
*
|
|
5
|
+
* Handles SIGINT/SIGTERM signals to gracefully close WebSocket connections
|
|
6
|
+
* and HTTP server before process exit.
|
|
7
|
+
*/
|
|
8
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
9
|
+
exports.setupGracefulShutdown = void 0;
|
|
10
|
+
const SHUTDOWN_TIMEOUT = 10000; // 10 seconds
|
|
11
|
+
/**
|
|
12
|
+
* Setup graceful shutdown handlers for SIGINT and SIGTERM
|
|
13
|
+
*/
|
|
14
|
+
function setupGracefulShutdown(server, _wss, cleanup) {
|
|
15
|
+
const shutdown = () => {
|
|
16
|
+
console.log('\n[i] Shutting down gracefully...');
|
|
17
|
+
// Run cleanup first (closes file watchers + WebSocket clients)
|
|
18
|
+
if (cleanup) {
|
|
19
|
+
cleanup();
|
|
20
|
+
}
|
|
21
|
+
// Close HTTP server
|
|
22
|
+
server.close(() => {
|
|
23
|
+
console.log('[OK] Server closed');
|
|
24
|
+
process.exit(0);
|
|
25
|
+
});
|
|
26
|
+
// Force shutdown if graceful shutdown takes too long
|
|
27
|
+
setTimeout(() => {
|
|
28
|
+
console.log('[!] Force shutdown (timeout exceeded)');
|
|
29
|
+
process.exit(1);
|
|
30
|
+
}, SHUTDOWN_TIMEOUT);
|
|
31
|
+
};
|
|
32
|
+
process.on('SIGINT', shutdown);
|
|
33
|
+
process.on('SIGTERM', shutdown);
|
|
34
|
+
}
|
|
35
|
+
exports.setupGracefulShutdown = setupGracefulShutdown;
|
|
36
|
+
//# sourceMappingURL=shutdown.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"shutdown.js","sourceRoot":"","sources":["../../src/web-server/shutdown.ts"],"names":[],"mappings":";AAAA;;;;;GAKG;;;AAKH,MAAM,gBAAgB,GAAG,KAAM,CAAC,CAAC,aAAa;AAE9C;;GAEG;AACH,SAAgB,qBAAqB,CACnC,MAAkB,EAClB,IAAqB,EACrB,OAAoB;IAEpB,MAAM,QAAQ,GAAG,GAAG,EAAE;QACpB,OAAO,CAAC,GAAG,CAAC,mCAAmC,CAAC,CAAC;QAEjD,+DAA+D;QAC/D,IAAI,OAAO,EAAE,CAAC;YACZ,OAAO,EAAE,CAAC;QACZ,CAAC;QAED,oBAAoB;QACpB,MAAM,CAAC,KAAK,CAAC,GAAG,EAAE;YAChB,OAAO,CAAC,GAAG,CAAC,oBAAoB,CAAC,CAAC;YAClC,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;QAClB,CAAC,CAAC,CAAC;QAEH,qDAAqD;QACrD,UAAU,CAAC,GAAG,EAAE;YACd,OAAO,CAAC,GAAG,CAAC,uCAAuC,CAAC,CAAC;YACrD,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;QAClB,CAAC,EAAE,gBAAgB,CAAC,CAAC;IACvB,CAAC,CAAC;IAEF,OAAO,CAAC,EAAE,CAAC,QAAQ,EAAE,QAAQ,CAAC,CAAC;IAC/B,OAAO,CAAC,EAAE,CAAC,SAAS,EAAE,QAAQ,CAAC,CAAC;AAClC,CAAC;AA5BD,sDA4BC"}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* WebSocket Handler (Phase 04)
|
|
3
|
+
*
|
|
4
|
+
* Manages WebSocket connections, broadcasts file changes, and handles client messages.
|
|
5
|
+
*/
|
|
6
|
+
import { WebSocketServer } from 'ws';
|
|
7
|
+
export interface WSMessage {
|
|
8
|
+
type: string;
|
|
9
|
+
[key: string]: unknown;
|
|
10
|
+
}
|
|
11
|
+
export declare function setupWebSocket(wss: WebSocketServer): {
|
|
12
|
+
cleanup: () => void;
|
|
13
|
+
};
|
|
14
|
+
//# sourceMappingURL=websocket.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"websocket.d.ts","sourceRoot":"","sources":["../../src/web-server/websocket.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,EAAE,eAAe,EAAa,MAAM,IAAI,CAAC;AAGhD,MAAM,WAAW,SAAS;IACxB,IAAI,EAAE,MAAM,CAAC;IACb,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC;CACxB;AAED,wBAAgB,cAAc,CAAC,GAAG,EAAE,eAAe,GAAG;IAAE,OAAO,EAAE,MAAM,IAAI,CAAA;CAAE,CA8E5E"}
|
|
@@ -0,0 +1,82 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* WebSocket Handler (Phase 04)
|
|
4
|
+
*
|
|
5
|
+
* Manages WebSocket connections, broadcasts file changes, and handles client messages.
|
|
6
|
+
*/
|
|
7
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
8
|
+
exports.setupWebSocket = void 0;
|
|
9
|
+
const ws_1 = require("ws");
|
|
10
|
+
const file_watcher_1 = require("./file-watcher");
|
|
11
|
+
function setupWebSocket(wss) {
|
|
12
|
+
// Track connected clients
|
|
13
|
+
const clients = new Set();
|
|
14
|
+
// Broadcast message to all clients
|
|
15
|
+
function broadcast(message) {
|
|
16
|
+
const data = JSON.stringify(message);
|
|
17
|
+
clients.forEach((client) => {
|
|
18
|
+
if (client.readyState === ws_1.WebSocket.OPEN) {
|
|
19
|
+
client.send(data);
|
|
20
|
+
}
|
|
21
|
+
});
|
|
22
|
+
}
|
|
23
|
+
// Handle new connections
|
|
24
|
+
wss.on('connection', (ws) => {
|
|
25
|
+
clients.add(ws);
|
|
26
|
+
console.log(`[WS] Client connected (${clients.size} total)`);
|
|
27
|
+
// Send welcome message
|
|
28
|
+
ws.send(JSON.stringify({ type: 'connected', timestamp: Date.now() }));
|
|
29
|
+
// Handle client messages
|
|
30
|
+
ws.on('message', (data) => {
|
|
31
|
+
try {
|
|
32
|
+
const message = JSON.parse(data.toString());
|
|
33
|
+
handleClientMessage(ws, message);
|
|
34
|
+
}
|
|
35
|
+
catch {
|
|
36
|
+
console.log('[WS] Invalid message format');
|
|
37
|
+
}
|
|
38
|
+
});
|
|
39
|
+
// Handle disconnect
|
|
40
|
+
ws.on('close', () => {
|
|
41
|
+
clients.delete(ws);
|
|
42
|
+
console.log(`[WS] Client disconnected (${clients.size} remaining)`);
|
|
43
|
+
});
|
|
44
|
+
ws.on('error', (err) => {
|
|
45
|
+
console.log(`[WS] Error: ${err.message}`);
|
|
46
|
+
clients.delete(ws);
|
|
47
|
+
});
|
|
48
|
+
});
|
|
49
|
+
// Handle incoming client messages
|
|
50
|
+
function handleClientMessage(ws, message) {
|
|
51
|
+
switch (message.type) {
|
|
52
|
+
case 'ping':
|
|
53
|
+
ws.send(JSON.stringify({ type: 'pong', timestamp: Date.now() }));
|
|
54
|
+
break;
|
|
55
|
+
case 'subscribe':
|
|
56
|
+
// Future: selective subscriptions
|
|
57
|
+
break;
|
|
58
|
+
default:
|
|
59
|
+
console.log(`[WS] Unknown message type: ${message.type}`);
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
// Setup file watcher
|
|
63
|
+
const watcher = (0, file_watcher_1.createFileWatcher)((event) => {
|
|
64
|
+
console.log(`[FS] ${event.type}: ${event.path}`);
|
|
65
|
+
broadcast({
|
|
66
|
+
type: event.type,
|
|
67
|
+
path: event.path,
|
|
68
|
+
timestamp: event.timestamp,
|
|
69
|
+
});
|
|
70
|
+
});
|
|
71
|
+
// Cleanup function
|
|
72
|
+
const cleanup = () => {
|
|
73
|
+
watcher.close();
|
|
74
|
+
clients.forEach((client) => {
|
|
75
|
+
client.close(1001, 'Server shutting down');
|
|
76
|
+
});
|
|
77
|
+
clients.clear();
|
|
78
|
+
};
|
|
79
|
+
return { cleanup };
|
|
80
|
+
}
|
|
81
|
+
exports.setupWebSocket = setupWebSocket;
|
|
82
|
+
//# sourceMappingURL=websocket.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"websocket.js","sourceRoot":"","sources":["../../src/web-server/websocket.ts"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@kaitranntt/ccs",
|
|
3
|
-
"version": "5.9.0-dev.
|
|
3
|
+
"version": "5.9.0-dev.4",
|
|
4
4
|
"description": "Claude Code Switch - Instant profile switching between Claude Sonnet 4.5 and GLM 4.6",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"cli",
|
|
@@ -52,45 +52,65 @@
|
|
|
52
52
|
"scripts": {
|
|
53
53
|
"build": "tsc && node scripts/add-shebang.js",
|
|
54
54
|
"build:watch": "tsc --watch",
|
|
55
|
+
"build:server": "tsc && node scripts/add-shebang.js",
|
|
56
|
+
"build:all": "bun run ui:build && bun run build:server",
|
|
55
57
|
"prebuild": "rm -rf dist tsconfig.tsbuildinfo",
|
|
58
|
+
"prebuild:all": "rm -rf dist tsconfig.tsbuildinfo",
|
|
59
|
+
"postbuild:all": "node scripts/verify-bundle.js",
|
|
56
60
|
"typecheck": "tsc --noEmit",
|
|
57
61
|
"lint": "eslint src/",
|
|
58
62
|
"lint:fix": "eslint src/ --fix",
|
|
59
63
|
"format": "prettier --write src/",
|
|
60
64
|
"format:check": "prettier --check src/",
|
|
61
65
|
"validate": "bun run typecheck && bun run lint:fix && bun run format:check && bun run test",
|
|
66
|
+
"verify:bundle": "node scripts/verify-bundle.js",
|
|
62
67
|
"test": "bun run build && bun run test:all",
|
|
63
68
|
"test:all": "bun test",
|
|
64
69
|
"test:unit": "bun test tests/unit/",
|
|
65
70
|
"test:npm": "bun test tests/npm/",
|
|
66
71
|
"test:native": "bash tests/native/unix/edge-cases.sh",
|
|
67
|
-
"
|
|
68
|
-
"
|
|
72
|
+
"dev": "bun run build:server && bun dist/ccs.js config --dev",
|
|
73
|
+
"ui:build": "cd ui && bun run build",
|
|
74
|
+
"ui:preview": "cd ui && bun run preview",
|
|
75
|
+
"ui:validate": "cd ui && bun run validate",
|
|
76
|
+
"prepublishOnly": "bun run validate && node scripts/sync-version.js",
|
|
77
|
+
"prepack": "bun run validate && node scripts/sync-version.js",
|
|
69
78
|
"prepare": "husky",
|
|
70
79
|
"postinstall": "node scripts/postinstall.js"
|
|
71
80
|
},
|
|
72
81
|
"dependencies": {
|
|
73
82
|
"boxen": "^8.0.1",
|
|
74
83
|
"chalk": "^5.6.2",
|
|
84
|
+
"chokidar": "^5.0.0",
|
|
75
85
|
"cli-table3": "^0.6.5",
|
|
86
|
+
"express": "^4.18.2",
|
|
87
|
+
"get-port": "^7.0.0",
|
|
76
88
|
"gradient-string": "^3.0.0",
|
|
77
89
|
"listr2": "^9.0.5",
|
|
78
|
-
"
|
|
90
|
+
"open": "^10.1.0",
|
|
91
|
+
"ora": "^9.0.0",
|
|
92
|
+
"ws": "^8.16.0"
|
|
79
93
|
},
|
|
80
94
|
"devDependencies": {
|
|
81
95
|
"@commitlint/cli": "^20.1.0",
|
|
82
96
|
"@commitlint/config-conventional": "^20.0.0",
|
|
83
97
|
"@semantic-release/changelog": "^6.0.3",
|
|
84
98
|
"@semantic-release/git": "^10.0.1",
|
|
99
|
+
"@tailwindcss/vite": "^4.1.17",
|
|
100
|
+
"@types/chokidar": "^2.1.7",
|
|
101
|
+
"@types/express": "^4.17.21",
|
|
85
102
|
"@types/node": "^20.19.25",
|
|
103
|
+
"@types/ws": "^8.5.10",
|
|
86
104
|
"@typescript-eslint/eslint-plugin": "^8.48.0",
|
|
87
105
|
"@typescript-eslint/parser": "^8.48.0",
|
|
106
|
+
"@vitejs/plugin-react": "^5.1.1",
|
|
88
107
|
"eslint": "^9.39.1",
|
|
89
108
|
"eslint-config-prettier": "^10.1.8",
|
|
90
109
|
"husky": "^9.1.7",
|
|
91
110
|
"mocha": "^11.7.5",
|
|
92
111
|
"prettier": "^3.6.2",
|
|
93
112
|
"semantic-release": "^25.0.2",
|
|
94
|
-
"typescript": "5.3"
|
|
113
|
+
"typescript": "5.3",
|
|
114
|
+
"vite": "^7.2.4"
|
|
95
115
|
}
|
|
96
116
|
}
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
#!/bin/bash
|
|
2
|
+
# Pre-Release Checklist for CCS
|
|
3
|
+
set -euo pipefail
|
|
4
|
+
|
|
5
|
+
echo "=== Pre-Release Checklist ==="
|
|
6
|
+
echo ""
|
|
7
|
+
|
|
8
|
+
# 1. Version check
|
|
9
|
+
echo "[i] Current version: $(node -p "require('./package.json').version")"
|
|
10
|
+
|
|
11
|
+
# 2. Clean build
|
|
12
|
+
echo "[i] Clean build..."
|
|
13
|
+
rm -rf dist
|
|
14
|
+
bun run build:all
|
|
15
|
+
|
|
16
|
+
# 3. Bundle size
|
|
17
|
+
echo "[i] Bundle size check..."
|
|
18
|
+
node scripts/verify-bundle.js
|
|
19
|
+
|
|
20
|
+
# 4. Lint & typecheck
|
|
21
|
+
echo "[i] Lint & typecheck..."
|
|
22
|
+
bun run validate
|
|
23
|
+
|
|
24
|
+
# 5. Tests
|
|
25
|
+
echo "[i] Running tests..."
|
|
26
|
+
bun test
|
|
27
|
+
|
|
28
|
+
# 6. Help consistency check
|
|
29
|
+
echo "[i] Checking help text includes config command..."
|
|
30
|
+
if ! grep -q "ccs config" src/commands/help-command.ts; then
|
|
31
|
+
echo "[!] Missing config in help-command.ts"
|
|
32
|
+
fi
|
|
33
|
+
|
|
34
|
+
# 7. Package contents
|
|
35
|
+
echo "[i] Package contents..."
|
|
36
|
+
npm pack --dry-run 2>&1 | head -20
|
|
37
|
+
|
|
38
|
+
echo ""
|
|
39
|
+
echo "=== Ready for release ==="
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Verify UI bundle size is under 500KB gzipped
|
|
5
|
+
*/
|
|
6
|
+
|
|
7
|
+
const fs = require('fs');
|
|
8
|
+
const path = require('path');
|
|
9
|
+
const zlib = require('zlib');
|
|
10
|
+
|
|
11
|
+
const UI_DIR = path.join(__dirname, '../dist/ui');
|
|
12
|
+
const MAX_SIZE = 500 * 1024; // 500KB
|
|
13
|
+
|
|
14
|
+
function getGzipSize(filePath) {
|
|
15
|
+
const content = fs.readFileSync(filePath);
|
|
16
|
+
return zlib.gzipSync(content).length;
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
function walkDir(dir) {
|
|
20
|
+
let totalSize = 0;
|
|
21
|
+
const files = fs.readdirSync(dir, { withFileTypes: true });
|
|
22
|
+
|
|
23
|
+
for (const file of files) {
|
|
24
|
+
const filePath = path.join(dir, file.name);
|
|
25
|
+
if (file.isDirectory()) {
|
|
26
|
+
totalSize += walkDir(filePath);
|
|
27
|
+
} else {
|
|
28
|
+
totalSize += getGzipSize(filePath);
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
return totalSize;
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
if (!fs.existsSync(UI_DIR)) {
|
|
36
|
+
console.log('[!] dist/ui not found. Run bun run ui:build first.');
|
|
37
|
+
process.exit(1);
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
const totalSize = walkDir(UI_DIR);
|
|
41
|
+
const sizeKB = (totalSize / 1024).toFixed(1);
|
|
42
|
+
|
|
43
|
+
if (totalSize > MAX_SIZE) {
|
|
44
|
+
console.log(`[X] Bundle too large: ${sizeKB}KB gzipped (max: 500KB)`);
|
|
45
|
+
process.exit(1);
|
|
46
|
+
} else {
|
|
47
|
+
console.log(`[OK] Bundle size: ${sizeKB}KB gzipped`);
|
|
48
|
+
}
|