mirror of
https://github.com/tiennm99/ccs.git
synced 2026-07-17 00:16:46 +00:00
Add comprehensive UX enhancements for the image analysis CLIProxy hook: - Add `ccs config image-analysis` CLI command for managing settings - Enable/disable toggle - Timeout configuration (10-600s) - Per-provider model configuration - Status display with provider models - Add specialized error handlers with actionable messages - File too large (with compression hints) - CLIProxy unavailable (with start instructions) - Auth failure (with re-auth commands) - Timeout (with increase timeout hint) - Rate limit (with retry guidance) - API error (with response body parsing) - Add comprehensive debug output (CCS_DEBUG=1) - Provider name and model - File size and media type - Timeout and endpoint - Skip reasons with context - Add help text updates - `ccs --help` includes Image Analysis section - `ccs config --help` lists image-analysis subcommand - Add doctor integration - Validates image_analysis config - Checks enabled status, providers, timeout - Warns if CLIProxy not running - Add unit tests for new config command
173 lines
5.4 KiB
TypeScript
173 lines
5.4 KiB
TypeScript
/**
|
|
* Config Command Handler
|
|
*
|
|
* Launches web-based configuration dashboard.
|
|
* Ensures CLIProxy service is running for dashboard features.
|
|
* Usage: ccs config [--port PORT] [--dev]
|
|
*/
|
|
|
|
import getPort from 'get-port';
|
|
import open from 'open';
|
|
import { startServer } from '../web-server';
|
|
import { setupGracefulShutdown } from '../web-server/shutdown';
|
|
import { ensureCliproxyService } from '../cliproxy/service-manager';
|
|
import { CLIPROXY_DEFAULT_PORT } from '../cliproxy/config-generator';
|
|
import { initUI, header, ok, info, warn, fail } from '../utils/ui';
|
|
|
|
interface ConfigOptions {
|
|
port?: number;
|
|
dev?: boolean;
|
|
}
|
|
|
|
/**
|
|
* Parse command line arguments
|
|
*/
|
|
function parseArgs(args: string[]): ConfigOptions {
|
|
const result: ConfigOptions = {};
|
|
|
|
for (let i = 0; i < args.length; i++) {
|
|
const arg = args[i];
|
|
|
|
if ((arg === '--port' || arg === '-p') && args[i + 1]) {
|
|
const port = parseInt(args[++i], 10);
|
|
if (!isNaN(port) && port > 0 && port < 65536) {
|
|
result.port = port;
|
|
} else {
|
|
console.error(fail('Invalid port number'));
|
|
process.exit(1);
|
|
}
|
|
} else if (arg === '--dev') {
|
|
result.dev = true;
|
|
} else if (arg === '--help' || arg === '-h') {
|
|
showHelp();
|
|
process.exit(0);
|
|
}
|
|
}
|
|
|
|
return result;
|
|
}
|
|
|
|
/**
|
|
* Show help message
|
|
*/
|
|
function showHelp(): void {
|
|
console.log('');
|
|
console.log('Usage: ccs config [command] [options]');
|
|
console.log('');
|
|
console.log('Open web-based configuration dashboard');
|
|
console.log('');
|
|
console.log('Commands:');
|
|
console.log(' auth Manage dashboard authentication');
|
|
console.log(' auth setup Configure username and password');
|
|
console.log(' auth show Display current auth status');
|
|
console.log(' auth disable Disable authentication');
|
|
console.log('');
|
|
console.log(' image-analysis Manage image analysis settings');
|
|
console.log(' --enable Enable image analysis via CLIProxy');
|
|
console.log(' --disable Disable image analysis');
|
|
console.log(' --timeout <s> Set analysis timeout (seconds)');
|
|
console.log(' --set-model <p> <m> Set model for provider');
|
|
console.log('');
|
|
console.log('Options:');
|
|
console.log(' --port, -p PORT Specify server port (default: auto-detect)');
|
|
console.log(' --dev Development mode with Vite HMR');
|
|
console.log(' --help, -h Show this help message');
|
|
console.log('');
|
|
console.log('Examples:');
|
|
console.log(' ccs config Auto-detect available port');
|
|
console.log(' ccs config --port 3000 Use specific port');
|
|
console.log(' ccs config --dev Development mode with hot reload');
|
|
console.log(' ccs config auth setup Configure dashboard login');
|
|
console.log(' ccs config image-analysis Show image settings');
|
|
console.log(' ccs config image-analysis --enable Enable feature');
|
|
console.log('');
|
|
}
|
|
|
|
/**
|
|
* Handle config command
|
|
*/
|
|
export async function handleConfigCommand(args: string[]): Promise<void> {
|
|
// Route subcommands before dashboard launch
|
|
if (args[0] === 'auth') {
|
|
const { handleConfigAuthCommand } = await import('./config-auth');
|
|
await handleConfigAuthCommand(args.slice(1));
|
|
return;
|
|
}
|
|
|
|
// Route image-analysis subcommand
|
|
if (args[0] === 'image-analysis') {
|
|
const { handleConfigImageAnalysisCommand } = await import('./config-image-analysis-command');
|
|
await handleConfigImageAnalysisCommand(args.slice(1));
|
|
return;
|
|
}
|
|
|
|
await initUI();
|
|
|
|
const options = parseArgs(args);
|
|
const verbose = options.dev || false;
|
|
|
|
console.log(header('CCS Config Dashboard'));
|
|
console.log('');
|
|
|
|
// Ensure CLIProxy service is running for dashboard features
|
|
console.log(info('Starting CLIProxy service...'));
|
|
const cliproxyResult = await ensureCliproxyService(CLIPROXY_DEFAULT_PORT, verbose);
|
|
|
|
if (cliproxyResult.started) {
|
|
if (cliproxyResult.alreadyRunning) {
|
|
console.log(ok(`CLIProxy already running on port ${cliproxyResult.port}`));
|
|
if (cliproxyResult.configRegenerated) {
|
|
console.log(warn('Config updated - restart CLIProxy to apply changes'));
|
|
}
|
|
} else {
|
|
console.log(ok(`CLIProxy started on port ${cliproxyResult.port}`));
|
|
}
|
|
} else {
|
|
console.log(warn(`CLIProxy not available: ${cliproxyResult.error}`));
|
|
console.log(info('Dashboard will work but Control Panel/Stats may be limited'));
|
|
}
|
|
console.log('');
|
|
|
|
console.log(info('Starting dashboard server...'));
|
|
|
|
// Find available port
|
|
const port =
|
|
options.port ??
|
|
(await getPort({
|
|
port: [3000, 3001, 3002, 8000, 8080],
|
|
}));
|
|
|
|
try {
|
|
// Start server
|
|
const { server, wss } = await startServer({ port, dev: options.dev });
|
|
|
|
// Setup graceful shutdown
|
|
setupGracefulShutdown(server, wss);
|
|
|
|
const url = `http://localhost:${port}`;
|
|
|
|
if (options.dev) {
|
|
console.log(ok(`Dev Server: ${url}`));
|
|
console.log('');
|
|
console.log(info('HMR enabled - UI changes will hot-reload'));
|
|
} else {
|
|
console.log(ok(`Dashboard: ${url}`));
|
|
}
|
|
console.log('');
|
|
|
|
// Open browser
|
|
try {
|
|
await open(url, { wait: false });
|
|
console.log(info('Browser opened automatically'));
|
|
} catch {
|
|
console.log(info(`Open manually: ${url}`));
|
|
}
|
|
|
|
console.log('');
|
|
console.log(info('Press Ctrl+C to stop'));
|
|
} catch (error) {
|
|
console.error(fail(`Failed to start server: ${(error as Error).message}`));
|
|
process.exit(1);
|
|
}
|
|
}
|