feat(web-dashboard): complete settings, health, shared data and build integration

- Settings editor with API key masking and conflict detection
- Health dashboard with status cards and one-click fixes
- Home dashboard with stats and quick actions
- Shared data viewer for commands/skills/agents
- Build scripts for UI + server bundle
- Bundle size verification (<500KB gzipped)
- Pre-release checklist script
This commit is contained in:
kaitranntt
2025-12-07 14:23:56 -05:00
parent 56502ab6a8
commit 59758024c9
43 changed files with 3557 additions and 138 deletions
+39
View File
@@ -0,0 +1,39 @@
#!/bin/bash
# Pre-Release Checklist for CCS
set -euo pipefail
echo "=== Pre-Release Checklist ==="
echo ""
# 1. Version check
echo "[i] Current version: $(node -p "require('./package.json').version")"
# 2. Clean build
echo "[i] Clean build..."
rm -rf dist
bun run build:all
# 3. Bundle size
echo "[i] Bundle size check..."
node scripts/verify-bundle.js
# 4. Lint & typecheck
echo "[i] Lint & typecheck..."
bun run validate
# 5. Tests
echo "[i] Running tests..."
bun test
# 6. Help consistency check
echo "[i] Checking help text includes config command..."
if ! grep -q "ccs config" src/commands/help-command.ts; then
echo "[!] Missing config in help-command.ts"
fi
# 7. Package contents
echo "[i] Package contents..."
npm pack --dry-run 2>&1 | head -20
echo ""
echo "=== Ready for release ==="
+48
View File
@@ -0,0 +1,48 @@
#!/usr/bin/env node
/**
* Verify UI bundle size is under 500KB gzipped
*/
const fs = require('fs');
const path = require('path');
const zlib = require('zlib');
const UI_DIR = path.join(__dirname, '../dist/ui');
const MAX_SIZE = 500 * 1024; // 500KB
function getGzipSize(filePath) {
const content = fs.readFileSync(filePath);
return zlib.gzipSync(content).length;
}
function walkDir(dir) {
let totalSize = 0;
const files = fs.readdirSync(dir, { withFileTypes: true });
for (const file of files) {
const filePath = path.join(dir, file.name);
if (file.isDirectory()) {
totalSize += walkDir(filePath);
} else {
totalSize += getGzipSize(filePath);
}
}
return totalSize;
}
if (!fs.existsSync(UI_DIR)) {
console.log('[!] dist/ui not found. Run bun run ui:build first.');
process.exit(1);
}
const totalSize = walkDir(UI_DIR);
const sizeKB = (totalSize / 1024).toFixed(1);
if (totalSize > MAX_SIZE) {
console.log(`[X] Bundle too large: ${sizeKB}KB gzipped (max: 500KB)`);
process.exit(1);
} else {
console.log(`[OK] Bundle size: ${sizeKB}KB gzipped`);
}