mirror of
https://github.com/catlog22/Claude-Code-Workflow.git
synced 2026-02-10 02:24:35 +08:00
Refactor code structure for improved readability and maintainability
This commit is contained in:
67
ccw/src/commands/serve.js
Normal file
67
ccw/src/commands/serve.js
Normal file
@@ -0,0 +1,67 @@
|
||||
import { startServer } from '../core/server.js';
|
||||
import { launchBrowser } from '../utils/browser-launcher.js';
|
||||
import { resolvePath, validatePath } from '../utils/path-resolver.js';
|
||||
import chalk from 'chalk';
|
||||
|
||||
/**
|
||||
* Serve command handler - starts dashboard server with live path switching
|
||||
* @param {Object} options - Command options
|
||||
*/
|
||||
export async function serveCommand(options) {
|
||||
const port = options.port || 3456;
|
||||
|
||||
// Validate project path
|
||||
let initialPath = process.cwd();
|
||||
if (options.path) {
|
||||
const pathValidation = validatePath(options.path, { mustExist: true });
|
||||
if (!pathValidation.valid) {
|
||||
console.error(chalk.red(`\n Error: ${pathValidation.error}\n`));
|
||||
process.exit(1);
|
||||
}
|
||||
initialPath = pathValidation.path;
|
||||
}
|
||||
|
||||
console.log(chalk.blue.bold('\n CCW Dashboard Server\n'));
|
||||
console.log(chalk.gray(` Initial project: ${initialPath}`));
|
||||
console.log(chalk.gray(` Port: ${port}\n`));
|
||||
|
||||
try {
|
||||
// Start server
|
||||
console.log(chalk.cyan(' Starting server...'));
|
||||
const server = await startServer({ port, initialPath });
|
||||
|
||||
const url = `http://localhost:${port}`;
|
||||
console.log(chalk.green(` Server running at ${url}`));
|
||||
|
||||
// Open browser
|
||||
if (options.browser !== false) {
|
||||
console.log(chalk.cyan(' Opening in browser...'));
|
||||
try {
|
||||
await launchBrowser(url);
|
||||
console.log(chalk.green.bold('\n Dashboard opened in browser!'));
|
||||
} catch (err) {
|
||||
console.log(chalk.yellow(`\n Could not open browser: ${err.message}`));
|
||||
console.log(chalk.gray(` Open manually: ${url}`));
|
||||
}
|
||||
}
|
||||
|
||||
console.log(chalk.gray('\n Press Ctrl+C to stop the server\n'));
|
||||
|
||||
// Handle graceful shutdown
|
||||
process.on('SIGINT', () => {
|
||||
console.log(chalk.yellow('\n Shutting down server...'));
|
||||
server.close(() => {
|
||||
console.log(chalk.green(' Server stopped.\n'));
|
||||
process.exit(0);
|
||||
});
|
||||
});
|
||||
|
||||
} catch (error) {
|
||||
console.error(chalk.red(`\n Error: ${error.message}\n`));
|
||||
if (error.code === 'EADDRINUSE') {
|
||||
console.error(chalk.yellow(` Port ${port} is already in use.`));
|
||||
console.error(chalk.gray(` Try a different port: ccw serve --port ${port + 1}\n`));
|
||||
}
|
||||
process.exit(1);
|
||||
}
|
||||
}
|
||||
@@ -2,7 +2,7 @@ import { scanSessions } from '../core/session-scanner.js';
|
||||
import { aggregateData } from '../core/data-aggregator.js';
|
||||
import { generateDashboard } from '../core/dashboard-generator.js';
|
||||
import { launchBrowser, isHeadlessEnvironment } from '../utils/browser-launcher.js';
|
||||
import { resolvePath, ensureDir, getWorkflowDir, validatePath, validateOutputPath } from '../utils/path-resolver.js';
|
||||
import { resolvePath, ensureDir, getWorkflowDir, validatePath, validateOutputPath, trackRecentPath, getRecentPaths, normalizePathForDisplay } from '../utils/path-resolver.js';
|
||||
import chalk from 'chalk';
|
||||
import { writeFileSync, existsSync } from 'fs';
|
||||
import { join, dirname } from 'path';
|
||||
@@ -22,6 +22,9 @@ export async function viewCommand(options) {
|
||||
const workingDir = pathValidation.path;
|
||||
const workflowDir = join(workingDir, '.workflow');
|
||||
|
||||
// Track this path in recent paths
|
||||
trackRecentPath(workingDir);
|
||||
|
||||
console.log(chalk.blue.bold('\n CCW Dashboard Generator\n'));
|
||||
console.log(chalk.gray(` Project: ${workingDir}`));
|
||||
console.log(chalk.gray(` Workflow: ${workflowDir}\n`));
|
||||
@@ -36,14 +39,19 @@ export async function viewCommand(options) {
|
||||
generatedAt: new Date().toISOString(),
|
||||
activeSessions: [],
|
||||
archivedSessions: [],
|
||||
liteTasks: { litePlan: [], liteFix: [] },
|
||||
reviewData: null,
|
||||
statistics: {
|
||||
totalSessions: 0,
|
||||
activeSessions: 0,
|
||||
totalTasks: 0,
|
||||
completedTasks: 0,
|
||||
reviewFindings: 0
|
||||
}
|
||||
reviewFindings: 0,
|
||||
litePlanCount: 0,
|
||||
liteFixCount: 0
|
||||
},
|
||||
projectPath: normalizePathForDisplay(workingDir),
|
||||
recentPaths: getRecentPaths()
|
||||
};
|
||||
|
||||
await generateAndOpen(emptyData, workflowDir, options);
|
||||
@@ -64,6 +72,10 @@ export async function viewCommand(options) {
|
||||
console.log(chalk.cyan(' Aggregating data...'));
|
||||
const dashboardData = await aggregateData(sessions, workflowDir);
|
||||
|
||||
// Add project path and recent paths
|
||||
dashboardData.projectPath = normalizePathForDisplay(workingDir);
|
||||
dashboardData.recentPaths = getRecentPaths();
|
||||
|
||||
// Log statistics
|
||||
const stats = dashboardData.statistics;
|
||||
console.log(chalk.gray(` Tasks: ${stats.completedTasks}/${stats.totalTasks} completed`));
|
||||
|
||||
Reference in New Issue
Block a user