mirror of
https://github.com/tiennm99/ccs.git
synced 2026-09-04 16:16:46 +00:00
refactor: modularize CCS architecture - Phase 02 complete
Split monolithic ccs.ts (1071 lines) into modular command handlers: Main file reduction: - ccs.ts: 1071 → 593 lines (44.6% reduction) - Maintains routing logic + profile detection + GLMT proxy New utility modules: - src/utils/shell-executor.ts: Cross-platform shell execution - src/utils/package-manager-detector.ts: Package manager detection New command handlers: - src/commands/version-command.ts: Version display - src/commands/help-command.ts: Help text and usage - src/commands/install-command.ts: Install/uninstall stubs - src/commands/doctor-command.ts: Health checks - src/commands/sync-command.ts: CCS synchronization - src/commands/shell-completion-command.ts: Shell completion Validation: - 39/39 tests passing (100% success rate) - TypeScript compilation: ✅ Zero errors - ESLint: ✅ Zero violations - Manual testing: ✅ All commands working Code review: EXCELLENT rating, 0 critical issues, zero regressions Tier1 plan: 2/2 phases complete - both ESLint strictness and modular architecture successfully implemented.
This commit is contained in:
@@ -0,0 +1,59 @@
|
||||
/**
|
||||
* Shell Executor Utilities
|
||||
*
|
||||
* Cross-platform shell execution utilities for CCS.
|
||||
*/
|
||||
|
||||
import { spawn, ChildProcess } from 'child_process';
|
||||
import { ErrorManager } from './error-manager';
|
||||
|
||||
/**
|
||||
* Escape arguments for shell execution (Windows compatibility)
|
||||
*/
|
||||
export function escapeShellArg(arg: string): string {
|
||||
return '"' + String(arg).replace(/"/g, '""') + '"';
|
||||
}
|
||||
|
||||
/**
|
||||
* Execute Claude CLI with unified spawn logic
|
||||
*/
|
||||
export function execClaude(
|
||||
claudeCli: string,
|
||||
args: string[],
|
||||
envVars: NodeJS.ProcessEnv | null = null
|
||||
): void {
|
||||
const isWindows = process.platform === 'win32';
|
||||
const needsShell = isWindows && /\.(cmd|bat|ps1)$/i.test(claudeCli);
|
||||
|
||||
// Prepare environment (merge with process.env if envVars provided)
|
||||
const env = envVars ? { ...process.env, ...envVars } : process.env;
|
||||
|
||||
let child: ChildProcess;
|
||||
if (needsShell) {
|
||||
// When shell needed: concatenate into string to avoid DEP0190 warning
|
||||
const cmdString = [claudeCli, ...args].map(escapeShellArg).join(' ');
|
||||
child = spawn(cmdString, {
|
||||
stdio: 'inherit',
|
||||
windowsHide: true,
|
||||
shell: true,
|
||||
env,
|
||||
});
|
||||
} else {
|
||||
// When no shell needed: use array form (faster, no shell overhead)
|
||||
child = spawn(claudeCli, args, {
|
||||
stdio: 'inherit',
|
||||
windowsHide: true,
|
||||
env,
|
||||
});
|
||||
}
|
||||
|
||||
child.on('exit', (code, signal) => {
|
||||
if (signal) process.kill(process.pid, signal as NodeJS.Signals);
|
||||
else process.exit(code || 0);
|
||||
});
|
||||
|
||||
child.on('error', () => {
|
||||
ErrorManager.showClaudeNotFound();
|
||||
process.exit(1);
|
||||
});
|
||||
}
|
||||
Reference in New Issue
Block a user