mirror of
https://github.com/tiennm99/ccs.git
synced 2026-07-16 20:17:45 +00:00
feat(config): add ccs config auth CLI subcommand
Interactive CLI for managing dashboard authentication: - ccs config auth setup: Interactive wizard with bcrypt password hashing - ccs config auth show: Display current auth status and ENV overrides - ccs config auth disable: Disable auth with confirmation Follows modular facade pattern from auth-commands.ts. Uses InteractivePrompt for masked password input. Includes local documentation at docs/dashboard-auth-cli.md. Related: #319
This commit is contained in:
@@ -0,0 +1,166 @@
|
||||
# Dashboard Authentication CLI
|
||||
|
||||
CLI commands for managing CCS dashboard authentication.
|
||||
|
||||
## Overview
|
||||
|
||||
The CCS dashboard (`ccs config`) can be protected with username/password authentication. This is useful when running the dashboard on a network-accessible machine.
|
||||
|
||||
Authentication is **disabled by default** for backward compatibility. Use the CLI to configure and enable it.
|
||||
|
||||
## Commands
|
||||
|
||||
### `ccs config auth setup`
|
||||
|
||||
Interactive wizard to configure dashboard login.
|
||||
|
||||
```bash
|
||||
$ ccs config auth setup
|
||||
|
||||
╭─────────────────────────────────╮
|
||||
│ Dashboard Auth Setup │
|
||||
╰─────────────────────────────────╯
|
||||
|
||||
[i] Configure username and password for dashboard access.
|
||||
Password will be hashed with bcrypt before storage.
|
||||
|
||||
Username
|
||||
Enter username: admin
|
||||
|
||||
Password
|
||||
Minimum 8 characters
|
||||
Enter password: ********
|
||||
Confirm password: ********
|
||||
|
||||
[i] Hashing password...
|
||||
|
||||
[OK] Dashboard authentication configured
|
||||
|
||||
[i] Settings saved to ~/.ccs/config.yaml
|
||||
[i] Username: admin
|
||||
[i] Session timeout: 24 hours
|
||||
|
||||
Start dashboard: ccs config
|
||||
Show status: ccs config auth show
|
||||
Disable auth: ccs config auth disable
|
||||
```
|
||||
|
||||
### `ccs config auth show`
|
||||
|
||||
Display current authentication status.
|
||||
|
||||
```bash
|
||||
$ ccs config auth show
|
||||
|
||||
╭─────────────────────────────────╮
|
||||
│ Dashboard Auth Status │
|
||||
╰─────────────────────────────────╯
|
||||
|
||||
Configuration
|
||||
[OK] Authentication: Enabled
|
||||
[OK] Username: admin
|
||||
[i] Session timeout: 24 hours
|
||||
|
||||
Commands
|
||||
ccs config auth setup Configure authentication
|
||||
ccs config auth disable Disable authentication
|
||||
ccs config Open dashboard
|
||||
```
|
||||
|
||||
### `ccs config auth disable`
|
||||
|
||||
Disable dashboard authentication with confirmation.
|
||||
|
||||
```bash
|
||||
$ ccs config auth disable
|
||||
|
||||
╭─────────────────────────────────╮
|
||||
│ Disable Dashboard Auth │
|
||||
╰─────────────────────────────────╯
|
||||
|
||||
[!] This will disable login protection for the dashboard.
|
||||
[i] Anyone with network access will be able to view the dashboard.
|
||||
|
||||
Disable authentication? [y/N]: y
|
||||
|
||||
[OK] Dashboard authentication disabled
|
||||
|
||||
[i] Credentials preserved - re-enable with: ccs config auth setup
|
||||
```
|
||||
|
||||
### `ccs config auth --help`
|
||||
|
||||
Display usage information.
|
||||
|
||||
## Environment Variables
|
||||
|
||||
Environment variables override `config.yaml` values:
|
||||
|
||||
| Variable | Description |
|
||||
|----------|-------------|
|
||||
| `CCS_DASHBOARD_AUTH_ENABLED` | Enable/disable auth (`true`/`false`) |
|
||||
| `CCS_DASHBOARD_USERNAME` | Username |
|
||||
| `CCS_DASHBOARD_PASSWORD_HASH` | Bcrypt password hash |
|
||||
|
||||
### Generating a Password Hash
|
||||
|
||||
Use bcrypt to generate a hash:
|
||||
|
||||
```bash
|
||||
# Using Node.js
|
||||
node -e "console.log(require('bcrypt').hashSync('your-password', 10))"
|
||||
|
||||
# Using npx
|
||||
npx bcrypt-cli hash "your-password"
|
||||
```
|
||||
|
||||
## Configuration
|
||||
|
||||
Settings are stored in `~/.ccs/config.yaml`:
|
||||
|
||||
```yaml
|
||||
# Dashboard Auth: Optional login protection for CCS dashboard
|
||||
# Generate password hash: npx bcrypt-cli hash "your-password"
|
||||
# ENV override: CCS_DASHBOARD_AUTH_ENABLED, CCS_DASHBOARD_USERNAME, CCS_DASHBOARD_PASSWORD_HASH
|
||||
dashboard_auth:
|
||||
enabled: true
|
||||
username: "admin"
|
||||
password_hash: "$2b$10$..."
|
||||
session_timeout_hours: 24
|
||||
```
|
||||
|
||||
## Security Notes
|
||||
|
||||
1. **Bcrypt hashing**: Passwords are hashed with bcrypt (10 rounds) before storage
|
||||
2. **Session cookies**: Sessions use HTTP-only cookies (not accessible via JavaScript)
|
||||
3. **Rate limiting**: Login attempts are rate-limited (5 per 15 minutes)
|
||||
4. **File permissions**: Config file is created with 0o600 permissions
|
||||
|
||||
## Troubleshooting
|
||||
|
||||
### "Authentication not configured"
|
||||
|
||||
Run `ccs config auth setup` to configure credentials.
|
||||
|
||||
### Forgot password
|
||||
|
||||
Run `ccs config auth setup` again to set a new password.
|
||||
|
||||
### ENV override not working
|
||||
|
||||
Ensure the variable is exported:
|
||||
|
||||
```bash
|
||||
export CCS_DASHBOARD_AUTH_ENABLED=true
|
||||
export CCS_DASHBOARD_USERNAME=admin
|
||||
export CCS_DASHBOARD_PASSWORD_HASH='$2b$10$...'
|
||||
```
|
||||
|
||||
### Session expired immediately
|
||||
|
||||
Check `session_timeout_hours` in config. Default is 24 hours.
|
||||
|
||||
## See Also
|
||||
|
||||
- [Dashboard Auth Feature](https://ccs.kaitran.ca/features/dashboard-auth) - Full documentation
|
||||
- [Config Schema](https://ccs.kaitran.ca/reference/config-schema) - All config options
|
||||
@@ -0,0 +1,75 @@
|
||||
/**
|
||||
* Config Auth Disable Command
|
||||
*
|
||||
* Disable dashboard authentication with confirmation.
|
||||
*/
|
||||
|
||||
import { InteractivePrompt } from '../../utils/prompt';
|
||||
import {
|
||||
getDashboardAuthConfig,
|
||||
loadOrCreateUnifiedConfig,
|
||||
saveUnifiedConfig,
|
||||
} from '../../config/unified-config-loader';
|
||||
import { initUI, header, ok, info, warn, dim } from '../../utils/ui';
|
||||
|
||||
/**
|
||||
* Handle disable command - disable auth with confirmation
|
||||
*/
|
||||
export async function handleDisable(): Promise<void> {
|
||||
await initUI();
|
||||
|
||||
console.log('');
|
||||
console.log(header('Disable Dashboard Auth'));
|
||||
console.log('');
|
||||
|
||||
const config = getDashboardAuthConfig();
|
||||
|
||||
// Check if already disabled
|
||||
if (!config.enabled) {
|
||||
console.log(info('Dashboard authentication is already disabled.'));
|
||||
console.log('');
|
||||
console.log(dim(' To enable: ccs config auth setup'));
|
||||
console.log('');
|
||||
return;
|
||||
}
|
||||
|
||||
// Check for ENV override
|
||||
if (process.env.CCS_DASHBOARD_AUTH_ENABLED) {
|
||||
console.log(warn('CCS_DASHBOARD_AUTH_ENABLED environment variable is set.'));
|
||||
console.log(info('Disabling in config.yaml, but ENV var will still override.'));
|
||||
console.log('');
|
||||
}
|
||||
|
||||
// Confirm before disabling
|
||||
console.log(warn('This will disable login protection for the dashboard.'));
|
||||
console.log(info('Anyone with network access will be able to view the dashboard.'));
|
||||
console.log('');
|
||||
|
||||
const confirmed = await InteractivePrompt.confirm('Disable authentication?', {
|
||||
default: false, // Safe default
|
||||
});
|
||||
|
||||
if (!confirmed) {
|
||||
console.log('');
|
||||
console.log(info('Cancelled. Authentication remains enabled.'));
|
||||
console.log('');
|
||||
return;
|
||||
}
|
||||
|
||||
// Disable auth
|
||||
const fullConfig = loadOrCreateUnifiedConfig();
|
||||
fullConfig.dashboard_auth = {
|
||||
enabled: false,
|
||||
username: fullConfig.dashboard_auth?.username ?? '',
|
||||
password_hash: fullConfig.dashboard_auth?.password_hash ?? '',
|
||||
session_timeout_hours: fullConfig.dashboard_auth?.session_timeout_hours ?? 24,
|
||||
};
|
||||
|
||||
saveUnifiedConfig(fullConfig);
|
||||
|
||||
console.log('');
|
||||
console.log(ok('Dashboard authentication disabled'));
|
||||
console.log('');
|
||||
console.log(info('Credentials preserved - re-enable with: ccs config auth setup'));
|
||||
console.log('');
|
||||
}
|
||||
@@ -0,0 +1,94 @@
|
||||
/**
|
||||
* Config Auth Commands (Facade)
|
||||
*
|
||||
* CLI interface for managing dashboard authentication.
|
||||
* Commands: setup, show, disable
|
||||
*
|
||||
* Implementation follows auth-commands.ts pattern.
|
||||
*/
|
||||
|
||||
import { initUI, header, subheader, color, dim, fail } from '../../utils/ui';
|
||||
|
||||
// Import command handlers
|
||||
import { handleSetup } from './setup-command';
|
||||
import { handleShow } from './show-command';
|
||||
import { handleDisable } from './disable-command';
|
||||
|
||||
/**
|
||||
* Show help for config auth commands
|
||||
*/
|
||||
async function showHelp(): Promise<void> {
|
||||
await initUI();
|
||||
|
||||
console.log('');
|
||||
console.log(header('Dashboard Auth Management'));
|
||||
console.log('');
|
||||
console.log(subheader('Usage'));
|
||||
console.log(` ${color('ccs config auth', 'command')} <command>`);
|
||||
console.log('');
|
||||
console.log(subheader('Commands'));
|
||||
console.log(` ${color('setup', 'command')} Configure username and password`);
|
||||
console.log(` ${color('show', 'command')} Display current auth status`);
|
||||
console.log(` ${color('disable', 'command')} Disable authentication`);
|
||||
console.log('');
|
||||
console.log(subheader('Examples'));
|
||||
console.log(` ${dim('# Interactive setup wizard')}`);
|
||||
console.log(` ${color('ccs config auth setup', 'command')}`);
|
||||
console.log('');
|
||||
console.log(` ${dim('# Check current status')}`);
|
||||
console.log(` ${color('ccs config auth show', 'command')}`);
|
||||
console.log('');
|
||||
console.log(` ${dim('# Disable authentication')}`);
|
||||
console.log(` ${color('ccs config auth disable', 'command')}`);
|
||||
console.log('');
|
||||
console.log(subheader('Environment Variables'));
|
||||
console.log(' These override config.yaml values:');
|
||||
console.log(
|
||||
` ${color('CCS_DASHBOARD_AUTH_ENABLED', 'command')} Enable/disable (true/false)`
|
||||
);
|
||||
console.log(` ${color('CCS_DASHBOARD_USERNAME', 'command')} Username`);
|
||||
console.log(` ${color('CCS_DASHBOARD_PASSWORD_HASH', 'command')} Bcrypt hash`);
|
||||
console.log('');
|
||||
console.log(subheader('Documentation'));
|
||||
console.log(' https://ccs.kaitran.ca/features/dashboard-auth');
|
||||
console.log('');
|
||||
}
|
||||
|
||||
/**
|
||||
* Route config auth command to appropriate handler
|
||||
*/
|
||||
export async function handleConfigAuthCommand(args: string[]): Promise<void> {
|
||||
// Default to help if no subcommand
|
||||
if (args.length === 0 || args[0] === '--help' || args[0] === '-h' || args[0] === 'help') {
|
||||
await showHelp();
|
||||
return;
|
||||
}
|
||||
|
||||
const command = args[0];
|
||||
|
||||
switch (command) {
|
||||
case 'setup':
|
||||
await handleSetup();
|
||||
break;
|
||||
|
||||
case 'show':
|
||||
case 'status':
|
||||
await handleShow();
|
||||
break;
|
||||
|
||||
case 'disable':
|
||||
await handleDisable();
|
||||
break;
|
||||
|
||||
default:
|
||||
await initUI();
|
||||
console.log(fail(`Unknown command: ${command}`));
|
||||
console.log('');
|
||||
console.log('Run for help:');
|
||||
console.log(` ${color('ccs config auth --help', 'command')}`);
|
||||
process.exit(1);
|
||||
}
|
||||
}
|
||||
|
||||
// Re-export types
|
||||
export type { ConfigAuthContext, AuthSetupResult, AuthStatusInfo } from './types';
|
||||
@@ -0,0 +1,133 @@
|
||||
/**
|
||||
* Config Auth Setup Command
|
||||
*
|
||||
* Interactive wizard for configuring dashboard authentication.
|
||||
* Prompts for username and password, hashes password with bcrypt,
|
||||
* and saves to config.yaml.
|
||||
*/
|
||||
|
||||
import bcrypt from 'bcrypt';
|
||||
import { InteractivePrompt } from '../../utils/prompt';
|
||||
import { loadOrCreateUnifiedConfig, saveUnifiedConfig } from '../../config/unified-config-loader';
|
||||
import { initUI, header, subheader, ok, fail, info, warn, dim } from '../../utils/ui';
|
||||
import type { AuthSetupResult } from './types';
|
||||
|
||||
const BCRYPT_ROUNDS = 10;
|
||||
const MIN_PASSWORD_LENGTH = 8;
|
||||
|
||||
/**
|
||||
* Validate username (non-empty, alphanumeric with underscores)
|
||||
*/
|
||||
function validateUsername(value: string): string | null {
|
||||
if (!value || value.trim().length === 0) {
|
||||
return 'Username cannot be empty';
|
||||
}
|
||||
if (!/^[a-zA-Z][a-zA-Z0-9_-]*$/.test(value)) {
|
||||
return 'Username must start with letter, contain only letters/numbers/underscores/hyphens';
|
||||
}
|
||||
if (value.length < 3) {
|
||||
return 'Username must be at least 3 characters';
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Handle setup command - interactive wizard
|
||||
*/
|
||||
export async function handleSetup(): Promise<AuthSetupResult> {
|
||||
await initUI();
|
||||
|
||||
console.log('');
|
||||
console.log(header('Dashboard Auth Setup'));
|
||||
console.log('');
|
||||
console.log(info('Configure username and password for dashboard access.'));
|
||||
console.log(dim(' Password will be hashed with bcrypt before storage.'));
|
||||
console.log('');
|
||||
|
||||
// Check for ENV overrides
|
||||
if (
|
||||
process.env.CCS_DASHBOARD_AUTH_ENABLED ||
|
||||
process.env.CCS_DASHBOARD_USERNAME ||
|
||||
process.env.CCS_DASHBOARD_PASSWORD_HASH
|
||||
) {
|
||||
console.log(warn('Environment variables detected - they will override config values:'));
|
||||
if (process.env.CCS_DASHBOARD_AUTH_ENABLED) {
|
||||
console.log(` CCS_DASHBOARD_AUTH_ENABLED=${process.env.CCS_DASHBOARD_AUTH_ENABLED}`);
|
||||
}
|
||||
if (process.env.CCS_DASHBOARD_USERNAME) {
|
||||
console.log(` CCS_DASHBOARD_USERNAME=${process.env.CCS_DASHBOARD_USERNAME}`);
|
||||
}
|
||||
if (process.env.CCS_DASHBOARD_PASSWORD_HASH) {
|
||||
console.log(' CCS_DASHBOARD_PASSWORD_HASH=***');
|
||||
}
|
||||
console.log('');
|
||||
}
|
||||
|
||||
try {
|
||||
// Prompt for username
|
||||
console.log(subheader('Username'));
|
||||
const username = await InteractivePrompt.input('Enter username', {
|
||||
validate: validateUsername,
|
||||
});
|
||||
|
||||
console.log('');
|
||||
|
||||
// Prompt for password
|
||||
console.log(subheader('Password'));
|
||||
console.log(dim(` Minimum ${MIN_PASSWORD_LENGTH} characters`));
|
||||
const password = await InteractivePrompt.password('Enter password');
|
||||
|
||||
// Validate password length
|
||||
if (password.length < MIN_PASSWORD_LENGTH) {
|
||||
console.log('');
|
||||
console.log(fail(`Password must be at least ${MIN_PASSWORD_LENGTH} characters`));
|
||||
return { success: false, error: 'Password too short' };
|
||||
}
|
||||
|
||||
// Confirm password
|
||||
const confirmPassword = await InteractivePrompt.password('Confirm password');
|
||||
|
||||
if (password !== confirmPassword) {
|
||||
console.log('');
|
||||
console.log(fail('Passwords do not match'));
|
||||
return { success: false, error: 'Password mismatch' };
|
||||
}
|
||||
|
||||
console.log('');
|
||||
console.log(info('Hashing password...'));
|
||||
|
||||
// Hash password
|
||||
const passwordHash = await bcrypt.hash(password, BCRYPT_ROUNDS);
|
||||
|
||||
// Load existing config and update
|
||||
const config = loadOrCreateUnifiedConfig();
|
||||
config.dashboard_auth = {
|
||||
enabled: true,
|
||||
username,
|
||||
password_hash: passwordHash,
|
||||
session_timeout_hours: config.dashboard_auth?.session_timeout_hours ?? 24,
|
||||
};
|
||||
|
||||
// Save config
|
||||
saveUnifiedConfig(config);
|
||||
|
||||
console.log('');
|
||||
console.log(ok('Dashboard authentication configured'));
|
||||
console.log('');
|
||||
console.log(info('Settings saved to ~/.ccs/config.yaml'));
|
||||
console.log(info(`Username: ${username}`));
|
||||
console.log(info(`Session timeout: ${config.dashboard_auth.session_timeout_hours} hours`));
|
||||
console.log('');
|
||||
console.log(dim(' Start dashboard: ccs config'));
|
||||
console.log(dim(' Show status: ccs config auth show'));
|
||||
console.log(dim(' Disable auth: ccs config auth disable'));
|
||||
console.log('');
|
||||
|
||||
return { success: true, username };
|
||||
} catch (error) {
|
||||
const err = error as Error;
|
||||
console.log('');
|
||||
console.log(fail(`Setup failed: ${err.message}`));
|
||||
return { success: false, error: err.message };
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,89 @@
|
||||
/**
|
||||
* Config Auth Show Command
|
||||
*
|
||||
* Display current dashboard authentication status.
|
||||
*/
|
||||
|
||||
import { getDashboardAuthConfig } from '../../config/unified-config-loader';
|
||||
import { initUI, header, subheader, ok, info, warn, dim, color } from '../../utils/ui';
|
||||
import type { AuthStatusInfo } from './types';
|
||||
|
||||
/**
|
||||
* Get auth status info with ENV override detection
|
||||
*/
|
||||
function getAuthStatus(): AuthStatusInfo {
|
||||
const config = getDashboardAuthConfig();
|
||||
|
||||
return {
|
||||
enabled: config.enabled,
|
||||
configured: !!(config.username && config.password_hash),
|
||||
username: config.username,
|
||||
sessionTimeoutHours: config.session_timeout_hours ?? 24,
|
||||
envOverride: {
|
||||
enabled: process.env.CCS_DASHBOARD_AUTH_ENABLED !== undefined,
|
||||
username: process.env.CCS_DASHBOARD_USERNAME !== undefined,
|
||||
passwordHash: process.env.CCS_DASHBOARD_PASSWORD_HASH !== undefined,
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* Handle show command - display current auth status
|
||||
*/
|
||||
export async function handleShow(): Promise<void> {
|
||||
await initUI();
|
||||
|
||||
console.log('');
|
||||
console.log(header('Dashboard Auth Status'));
|
||||
console.log('');
|
||||
|
||||
const status = getAuthStatus();
|
||||
|
||||
// Status section
|
||||
console.log(subheader('Configuration'));
|
||||
|
||||
if (status.enabled) {
|
||||
console.log(ok('Authentication: Enabled'));
|
||||
} else {
|
||||
console.log(info('Authentication: Disabled'));
|
||||
}
|
||||
|
||||
if (status.configured) {
|
||||
console.log(ok(`Username: ${status.username}`));
|
||||
console.log(info(`Session timeout: ${status.sessionTimeoutHours} hours`));
|
||||
} else {
|
||||
console.log(warn('Not configured - run `ccs config auth setup`'));
|
||||
}
|
||||
|
||||
console.log('');
|
||||
|
||||
// ENV override section
|
||||
const hasEnvOverride =
|
||||
status.envOverride.enabled || status.envOverride.username || status.envOverride.passwordHash;
|
||||
|
||||
if (hasEnvOverride) {
|
||||
console.log(subheader('Environment Overrides'));
|
||||
console.log(warn('The following ENV vars override config.yaml:'));
|
||||
|
||||
if (status.envOverride.enabled) {
|
||||
const value = process.env.CCS_DASHBOARD_AUTH_ENABLED;
|
||||
console.log(` ${color('CCS_DASHBOARD_AUTH_ENABLED', 'command')}=${value}`);
|
||||
}
|
||||
if (status.envOverride.username) {
|
||||
const value = process.env.CCS_DASHBOARD_USERNAME;
|
||||
console.log(` ${color('CCS_DASHBOARD_USERNAME', 'command')}=${value}`);
|
||||
}
|
||||
if (status.envOverride.passwordHash) {
|
||||
console.log(` ${color('CCS_DASHBOARD_PASSWORD_HASH', 'command')}=***`);
|
||||
}
|
||||
|
||||
console.log('');
|
||||
}
|
||||
|
||||
// Help section
|
||||
console.log(subheader('Commands'));
|
||||
console.log(dim(' ccs config auth setup Configure authentication'));
|
||||
console.log(dim(' ccs config auth disable Disable authentication'));
|
||||
console.log(dim(' ccs config Open dashboard'));
|
||||
console.log('');
|
||||
}
|
||||
@@ -0,0 +1,27 @@
|
||||
/**
|
||||
* Config Auth Command Types
|
||||
*
|
||||
* Shared interfaces for dashboard authentication CLI commands.
|
||||
*/
|
||||
|
||||
export interface ConfigAuthContext {
|
||||
verbose?: boolean;
|
||||
}
|
||||
|
||||
export interface AuthSetupResult {
|
||||
success: boolean;
|
||||
username?: string;
|
||||
error?: string;
|
||||
}
|
||||
|
||||
export interface AuthStatusInfo {
|
||||
enabled: boolean;
|
||||
configured: boolean;
|
||||
username: string;
|
||||
sessionTimeoutHours: number;
|
||||
envOverride: {
|
||||
enabled: boolean;
|
||||
username: boolean;
|
||||
passwordHash: boolean;
|
||||
};
|
||||
}
|
||||
@@ -52,10 +52,16 @@ function parseArgs(args: string[]): ConfigOptions {
|
||||
*/
|
||||
function showHelp(): void {
|
||||
console.log('');
|
||||
console.log('Usage: ccs config [options]');
|
||||
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('Options:');
|
||||
console.log(' --port, -p PORT Specify server port (default: auto-detect)');
|
||||
console.log(' --dev Development mode with Vite HMR');
|
||||
@@ -65,6 +71,7 @@ function showHelp(): void {
|
||||
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('');
|
||||
}
|
||||
|
||||
@@ -72,6 +79,13 @@ function showHelp(): void {
|
||||
* 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;
|
||||
}
|
||||
|
||||
await initUI();
|
||||
|
||||
const options = parseArgs(args);
|
||||
|
||||
@@ -230,6 +230,8 @@ Run ${color('ccs config', 'command')} for web dashboard`.trim();
|
||||
['ccs doctor', 'Run health check and diagnostics'],
|
||||
['ccs cleanup', 'Remove old CLIProxy logs'],
|
||||
['ccs config', 'Open web configuration dashboard'],
|
||||
['ccs config auth setup', 'Configure dashboard login'],
|
||||
['ccs config auth show', 'Show dashboard auth status'],
|
||||
['ccs config --port 3000', 'Use specific port'],
|
||||
['ccs sync', 'Sync delegation commands and skills'],
|
||||
['ccs update', 'Update CCS to latest version'],
|
||||
|
||||
Reference in New Issue
Block a user