mirror of
https://github.com/tiennm99/ccs.git
synced 2026-10-13 00:14:15 +00:00
feat(cliproxy): add explicit start and restart commands
This commit is contained in:
1 parent
2fe8f2b4ca
commit
8395364970
7 files changed
+118
-4
No files matched your search
@@ -229,6 +229,15 @@ ccs cliproxy doctor # Check quota status for all agy accounts
|
|||||||
|
|
||||||
**Auto-Failover**: When an Antigravity account runs out of quota, CCS automatically switches to another account with remaining capacity. Shared GCP project accounts are excluded (pooled quota).
|
**Auto-Failover**: When an Antigravity account runs out of quota, CCS automatically switches to another account with remaining capacity. Shared GCP project accounts are excluded (pooled quota).
|
||||||
|
|
||||||
|
### CLIProxy Lifecycle
|
||||||
|
|
||||||
|
```bash
|
||||||
|
ccs cliproxy start # Start CLIProxy background service
|
||||||
|
ccs cliproxy status # Check running status
|
||||||
|
ccs cliproxy restart # Restart CLIProxy service
|
||||||
|
ccs cliproxy stop # Stop running CLIProxy service
|
||||||
|
```
|
||||||
|
|
||||||
<br>
|
<br>
|
||||||
|
|
||||||
## Configuration
|
## Configuration
|
||||||
|
|||||||
@@ -22,10 +22,12 @@ export {
|
|||||||
export {
|
export {
|
||||||
getProxyStatus,
|
getProxyStatus,
|
||||||
stopProxy,
|
stopProxy,
|
||||||
|
startProxy,
|
||||||
isProxyRunning,
|
isProxyRunning,
|
||||||
getActiveSessionCount,
|
getActiveSessionCount,
|
||||||
type ProxyStatusResult,
|
type ProxyStatusResult,
|
||||||
type StopProxyResult,
|
type StopProxyResult,
|
||||||
|
type StartProxyResult,
|
||||||
} from './proxy-lifecycle-service';
|
} from './proxy-lifecycle-service';
|
||||||
|
|
||||||
// Binary management
|
// Binary management
|
||||||
|
|||||||
@@ -2,13 +2,15 @@
|
|||||||
* CLIProxy Proxy Lifecycle Service
|
* CLIProxy Proxy Lifecycle Service
|
||||||
*
|
*
|
||||||
* Handles start/stop/status operations for CLIProxy instances.
|
* Handles start/stop/status operations for CLIProxy instances.
|
||||||
* Delegates to session-tracker for actual process management.
|
* Delegates to session-tracker and service-manager for actual process management.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import {
|
import {
|
||||||
stopProxy as stopProxySession,
|
stopProxy as stopProxySession,
|
||||||
getProxyStatus as getProxyStatusSession,
|
getProxyStatus as getProxyStatusSession,
|
||||||
} from '../session-tracker';
|
} from '../session-tracker';
|
||||||
|
import { ensureCliproxyService } from '../service-manager';
|
||||||
|
import { CLIPROXY_DEFAULT_PORT } from '../config-generator';
|
||||||
|
|
||||||
/** Proxy status result */
|
/** Proxy status result */
|
||||||
export interface ProxyStatusResult {
|
export interface ProxyStatusResult {
|
||||||
@@ -27,6 +29,15 @@ export interface StopProxyResult {
|
|||||||
error?: string;
|
error?: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** Start proxy result */
|
||||||
|
export interface StartProxyResult {
|
||||||
|
started: boolean;
|
||||||
|
alreadyRunning: boolean;
|
||||||
|
port: number;
|
||||||
|
configRegenerated?: boolean;
|
||||||
|
error?: string;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get current proxy status
|
* Get current proxy status
|
||||||
*/
|
*/
|
||||||
@@ -41,6 +52,16 @@ export async function stopProxy(): Promise<StopProxyResult> {
|
|||||||
return stopProxySession();
|
return stopProxySession();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Start CLIProxy service (or reuse existing running instance)
|
||||||
|
*/
|
||||||
|
export async function startProxy(
|
||||||
|
port: number = CLIPROXY_DEFAULT_PORT,
|
||||||
|
verbose: boolean = false
|
||||||
|
): Promise<StartProxyResult> {
|
||||||
|
return ensureCliproxyService(port, verbose);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Check if proxy is currently running
|
* Check if proxy is currently running
|
||||||
*/
|
*/
|
||||||
|
|||||||
@@ -61,6 +61,8 @@ export async function showHelp(): Promise<void> {
|
|||||||
[
|
[
|
||||||
'Proxy Lifecycle:',
|
'Proxy Lifecycle:',
|
||||||
[
|
[
|
||||||
|
['start', 'Start CLIProxy instance in background'],
|
||||||
|
['restart', 'Restart CLIProxy instance'],
|
||||||
['status', 'Show running CLIProxy status'],
|
['status', 'Show running CLIProxy status'],
|
||||||
['stop', 'Stop running CLIProxy instance'],
|
['stop', 'Stop running CLIProxy instance'],
|
||||||
['doctor', 'Quota diagnostics and shared project detection'],
|
['doctor', 'Quota diagnostics and shared project detection'],
|
||||||
|
|||||||
@@ -20,7 +20,12 @@ import {
|
|||||||
handleResumeAccount,
|
handleResumeAccount,
|
||||||
} from './quota-subcommand';
|
} from './quota-subcommand';
|
||||||
import { handleCreate, handleRemove, handleEdit } from './variant-subcommand';
|
import { handleCreate, handleRemove, handleEdit } from './variant-subcommand';
|
||||||
import { handleProxyStatus, handleStop } from './proxy-lifecycle-subcommand';
|
import {
|
||||||
|
handleProxyStatus,
|
||||||
|
handleStart,
|
||||||
|
handleStop,
|
||||||
|
handleRestart,
|
||||||
|
} from './proxy-lifecycle-subcommand';
|
||||||
import { showStatus, handleInstallVersion, handleInstallLatest } from './install-subcommand';
|
import { showStatus, handleInstallVersion, handleInstallLatest } from './install-subcommand';
|
||||||
import { showHelp } from './help-subcommand';
|
import { showHelp } from './help-subcommand';
|
||||||
import {
|
import {
|
||||||
@@ -198,11 +203,21 @@ export async function handleCliproxyCommand(args: string[]): Promise<void> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Proxy lifecycle commands
|
// Proxy lifecycle commands
|
||||||
|
if (command === 'start') {
|
||||||
|
await handleStart(verbose);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
if (command === 'stop') {
|
if (command === 'stop') {
|
||||||
await handleStop();
|
await handleStop();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (command === 'restart') {
|
||||||
|
await handleRestart(verbose);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
if (command === 'status') {
|
if (command === 'status') {
|
||||||
await handleProxyStatus();
|
await handleProxyStatus();
|
||||||
return;
|
return;
|
||||||
|
|||||||
@@ -2,15 +2,68 @@
|
|||||||
* CLIProxy Lifecycle Management
|
* CLIProxy Lifecycle Management
|
||||||
*
|
*
|
||||||
* Handles:
|
* Handles:
|
||||||
|
* - ccs cliproxy start
|
||||||
|
* - ccs cliproxy restart
|
||||||
* - ccs cliproxy status
|
* - ccs cliproxy status
|
||||||
* - ccs cliproxy stop
|
* - ccs cliproxy stop
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import { initUI, header, color, dim, ok, warn, info } from '../../utils/ui';
|
import { initUI, header, color, dim, ok, warn, info } from '../../utils/ui';
|
||||||
import { getProxyStatus, stopProxy } from '../../cliproxy/services';
|
import { getProxyStatus, startProxy, stopProxy } from '../../cliproxy/services';
|
||||||
import { detectRunningProxy } from '../../cliproxy/proxy-detector';
|
import { detectRunningProxy } from '../../cliproxy/proxy-detector';
|
||||||
import { CLIPROXY_DEFAULT_PORT } from '../../cliproxy/config-generator';
|
import { CLIPROXY_DEFAULT_PORT } from '../../cliproxy/config-generator';
|
||||||
|
|
||||||
|
export async function handleStart(verbose = false): Promise<void> {
|
||||||
|
await initUI();
|
||||||
|
console.log(header('Start CLIProxy'));
|
||||||
|
console.log('');
|
||||||
|
|
||||||
|
const result = await startProxy(CLIPROXY_DEFAULT_PORT, verbose);
|
||||||
|
if (result.started) {
|
||||||
|
if (result.alreadyRunning) {
|
||||||
|
console.log(info(`CLIProxy already running on port ${result.port}`));
|
||||||
|
if (result.configRegenerated) {
|
||||||
|
console.log(warn('Config updated - restart CLIProxy to apply changes'));
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
console.log(ok(`CLIProxy started on port ${result.port}`));
|
||||||
|
}
|
||||||
|
console.log(dim('To stop: ccs cliproxy stop'));
|
||||||
|
} else {
|
||||||
|
console.log(warn(result.error || 'Failed to start CLIProxy'));
|
||||||
|
}
|
||||||
|
console.log('');
|
||||||
|
}
|
||||||
|
|
||||||
|
export async function handleRestart(verbose = false): Promise<void> {
|
||||||
|
await initUI();
|
||||||
|
console.log(header('Restart CLIProxy'));
|
||||||
|
console.log('');
|
||||||
|
|
||||||
|
const stopResult = await stopProxy();
|
||||||
|
if (stopResult.stopped) {
|
||||||
|
console.log(ok(`CLIProxy stopped (PID ${stopResult.pid})`));
|
||||||
|
} else if (stopResult.error === 'No active CLIProxy session found') {
|
||||||
|
console.log(info('No active CLIProxy session found, starting a new instance'));
|
||||||
|
} else {
|
||||||
|
console.log(warn(stopResult.error || 'Failed to stop existing CLIProxy'));
|
||||||
|
console.log(info('Attempting to start a fresh instance...'));
|
||||||
|
}
|
||||||
|
|
||||||
|
const startResult = await startProxy(CLIPROXY_DEFAULT_PORT, verbose);
|
||||||
|
if (startResult.started) {
|
||||||
|
if (startResult.alreadyRunning) {
|
||||||
|
console.log(info(`CLIProxy already running on port ${startResult.port}`));
|
||||||
|
} else {
|
||||||
|
console.log(ok(`CLIProxy started on port ${startResult.port}`));
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
console.log(warn(startResult.error || 'Failed to restart CLIProxy'));
|
||||||
|
}
|
||||||
|
|
||||||
|
console.log('');
|
||||||
|
}
|
||||||
|
|
||||||
export async function handleProxyStatus(): Promise<void> {
|
export async function handleProxyStatus(): Promise<void> {
|
||||||
await initUI();
|
await initUI();
|
||||||
console.log(header('CLIProxy Status'));
|
console.log(header('CLIProxy Status'));
|
||||||
|
|||||||
@@ -491,6 +491,18 @@ describe('CLIProxy Command - Proxy Lifecycle', () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
describe('Command Routing', () => {
|
describe('Command Routing', () => {
|
||||||
|
it('routes "start" subcommand correctly', () => {
|
||||||
|
const args = ['cliproxy', 'start'];
|
||||||
|
const subcommand = args[1];
|
||||||
|
assert.strictEqual(subcommand, 'start');
|
||||||
|
});
|
||||||
|
|
||||||
|
it('routes "restart" subcommand correctly', () => {
|
||||||
|
const args = ['cliproxy', 'restart'];
|
||||||
|
const subcommand = args[1];
|
||||||
|
assert.strictEqual(subcommand, 'restart');
|
||||||
|
});
|
||||||
|
|
||||||
it('routes "stop" subcommand correctly', () => {
|
it('routes "stop" subcommand correctly', () => {
|
||||||
const args = ['cliproxy', 'stop'];
|
const args = ['cliproxy', 'stop'];
|
||||||
const subcommand = args[1];
|
const subcommand = args[1];
|
||||||
@@ -504,7 +516,7 @@ describe('CLIProxy Command - Proxy Lifecycle', () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
it('handles unknown subcommand', () => {
|
it('handles unknown subcommand', () => {
|
||||||
const validSubcommands = ['stop', 'status', 'create', 'list', 'remove'];
|
const validSubcommands = ['start', 'restart', 'stop', 'status', 'create', 'list', 'remove'];
|
||||||
const unknownCommand = 'invalid';
|
const unknownCommand = 'invalid';
|
||||||
assert.strictEqual(validSubcommands.includes(unknownCommand), false);
|
assert.strictEqual(validSubcommands.includes(unknownCommand), false);
|
||||||
});
|
});
|
||||||
|
|||||||
Reference in new issue
Block a user