mirror of
https://github.com/tiennm99/ccs.git
synced 2026-07-16 12:15:57 +00:00
refactor(copilot): use local installation from package manager
- copilot-auth: use getCopilotApiBinPath() instead of npx - copilot-daemon: move PID file to ~/.ccs/copilot/daemon.pid - copilot-executor: auto-install copilot-api on first use - index: export package manager functions
This commit is contained in:
+15
-14
@@ -2,25 +2,22 @@
|
||||
* Copilot Auth Handler
|
||||
*
|
||||
* Handles GitHub OAuth authentication for copilot-api.
|
||||
* Uses local installation from ~/.ccs/copilot/ (managed by copilot-package-manager).
|
||||
*/
|
||||
|
||||
import { spawn, spawnSync } from 'child_process';
|
||||
import { spawn } from 'child_process';
|
||||
import { CopilotAuthStatus, CopilotDebugInfo } from './types';
|
||||
import {
|
||||
isCopilotApiInstalled as checkInstalled,
|
||||
getCopilotApiBinPath,
|
||||
} from './copilot-package-manager';
|
||||
|
||||
/**
|
||||
* Check if copilot-api is installed (available via npx).
|
||||
* Check if copilot-api is installed locally.
|
||||
* Uses copilot-package-manager to check ~/.ccs/copilot/node_modules/.bin/copilot-api
|
||||
*/
|
||||
export function isCopilotApiInstalled(): boolean {
|
||||
try {
|
||||
const result = spawnSync('npx', ['copilot-api', '--version'], {
|
||||
stdio: 'pipe',
|
||||
timeout: 10000,
|
||||
shell: process.platform === 'win32',
|
||||
});
|
||||
return result.status === 0;
|
||||
} catch {
|
||||
return false;
|
||||
}
|
||||
return checkInstalled();
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -28,9 +25,11 @@ export function isCopilotApiInstalled(): boolean {
|
||||
* Returns authentication status and version info.
|
||||
*/
|
||||
export async function getCopilotDebugInfo(): Promise<CopilotDebugInfo | null> {
|
||||
const binPath = getCopilotApiBinPath();
|
||||
|
||||
return new Promise((resolve) => {
|
||||
try {
|
||||
const proc = spawn('npx', ['copilot-api', 'debug', '--json'], {
|
||||
const proc = spawn(binPath, ['debug', '--json'], {
|
||||
stdio: ['ignore', 'pipe', 'pipe'],
|
||||
shell: process.platform === 'win32',
|
||||
timeout: 15000,
|
||||
@@ -100,12 +99,14 @@ export async function checkAuthStatus(): Promise<CopilotAuthStatus> {
|
||||
* @returns Promise that resolves when auth flow completes
|
||||
*/
|
||||
export function startAuthFlow(): Promise<{ success: boolean; error?: string }> {
|
||||
const binPath = getCopilotApiBinPath();
|
||||
|
||||
return new Promise((resolve) => {
|
||||
console.log('[i] Starting GitHub authentication for Copilot...');
|
||||
console.log('[i] A browser window will open for GitHub OAuth.');
|
||||
console.log('');
|
||||
|
||||
const proc = spawn('npx', ['copilot-api', 'auth'], {
|
||||
const proc = spawn(binPath, ['auth'], {
|
||||
stdio: 'inherit',
|
||||
shell: process.platform === 'win32',
|
||||
});
|
||||
|
||||
@@ -2,18 +2,18 @@
|
||||
* Copilot Daemon Manager
|
||||
*
|
||||
* Manages the copilot-api daemon lifecycle (start/stop/status).
|
||||
* Only used when auto_start is enabled in config.
|
||||
* Uses local installation from ~/.ccs/copilot/ (managed by copilot-package-manager).
|
||||
*/
|
||||
|
||||
import { spawn, ChildProcess } from 'child_process';
|
||||
import * as fs from 'fs';
|
||||
import * as path from 'path';
|
||||
import * as os from 'os';
|
||||
import * as http from 'http';
|
||||
import { CopilotDaemonStatus } from './types';
|
||||
import { CopilotConfig } from '../config/unified-config-types';
|
||||
import { getCopilotDir, getCopilotApiBinPath } from './copilot-package-manager';
|
||||
|
||||
const PID_FILE = path.join(os.homedir(), '.ccs', 'copilot.pid');
|
||||
const PID_FILE = path.join(getCopilotDir(), 'daemon.pid');
|
||||
|
||||
/**
|
||||
* Check if copilot-api daemon is running on the specified port.
|
||||
@@ -118,7 +118,8 @@ export async function startDaemon(
|
||||
return { success: true, pid: getPidFromFile() ?? undefined };
|
||||
}
|
||||
|
||||
const args = ['copilot-api', 'start', '--port', config.port.toString()];
|
||||
const binPath = getCopilotApiBinPath();
|
||||
const args = ['start', '--port', config.port.toString()];
|
||||
|
||||
// Add account type
|
||||
if (config.account_type !== 'individual') {
|
||||
@@ -137,7 +138,7 @@ export async function startDaemon(
|
||||
let proc: ChildProcess;
|
||||
|
||||
try {
|
||||
proc = spawn('npx', args, {
|
||||
proc = spawn(binPath, args, {
|
||||
stdio: ['ignore', 'pipe', 'pipe'],
|
||||
detached: true,
|
||||
shell: process.platform === 'win32',
|
||||
|
||||
@@ -2,13 +2,14 @@
|
||||
* Copilot Executor
|
||||
*
|
||||
* Main execution flow for running Claude Code with copilot-api proxy.
|
||||
* Similar to CLIProxy executor but for GitHub Copilot.
|
||||
* Uses local installation from ~/.ccs/copilot/ (managed by copilot-package-manager).
|
||||
*/
|
||||
|
||||
import { spawn } from 'child_process';
|
||||
import { CopilotConfig } from '../config/unified-config-types';
|
||||
import { checkAuthStatus, isCopilotApiInstalled } from './copilot-auth';
|
||||
import { isDaemonRunning, startDaemon } from './copilot-daemon';
|
||||
import { ensureCopilotApi } from './copilot-package-manager';
|
||||
import { CopilotStatus } from './types';
|
||||
|
||||
/**
|
||||
@@ -65,12 +66,24 @@ export async function executeCopilotProfile(
|
||||
config: CopilotConfig,
|
||||
claudeArgs: string[]
|
||||
): Promise<number> {
|
||||
// Check if copilot-api is installed
|
||||
// Ensure copilot-api is installed (auto-install if missing, auto-update if outdated)
|
||||
try {
|
||||
await ensureCopilotApi();
|
||||
} catch (error) {
|
||||
console.error('[X] Failed to install copilot-api.');
|
||||
console.error('');
|
||||
console.error(`Error: ${(error as Error).message}`);
|
||||
console.error('');
|
||||
console.error('Try installing manually:');
|
||||
console.error(' npm install -g copilot-api');
|
||||
return 1;
|
||||
}
|
||||
|
||||
// Check if copilot-api is installed (should be after ensureCopilotApi)
|
||||
if (!isCopilotApiInstalled()) {
|
||||
console.error('[X] copilot-api is not installed.');
|
||||
console.error('');
|
||||
console.error('Install with: npm install -g copilot-api');
|
||||
console.error('Or run via npx: npx copilot-api auth');
|
||||
console.error('Install with: ccs copilot --install');
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
+16
-5
@@ -7,13 +7,24 @@
|
||||
// Types
|
||||
export * from './types';
|
||||
|
||||
// Auth
|
||||
// Package Manager (self-managed installation)
|
||||
export {
|
||||
getCopilotDir,
|
||||
getCopilotApiBinPath,
|
||||
isCopilotApiInstalled,
|
||||
checkAuthStatus,
|
||||
startAuthFlow,
|
||||
getCopilotDebugInfo,
|
||||
} from './copilot-auth';
|
||||
getInstalledVersion,
|
||||
getPinnedVersion,
|
||||
savePinnedVersion,
|
||||
clearPinnedVersion,
|
||||
checkForUpdates,
|
||||
ensureCopilotApi,
|
||||
installCopilotApiVersion,
|
||||
uninstallCopilotApi,
|
||||
getCopilotApiInfo,
|
||||
} from './copilot-package-manager';
|
||||
|
||||
// Auth
|
||||
export { checkAuthStatus, startAuthFlow, getCopilotDebugInfo } from './copilot-auth';
|
||||
|
||||
// Daemon
|
||||
export { isDaemonRunning, getDaemonStatus, startDaemon, stopDaemon } from './copilot-daemon';
|
||||
|
||||
Reference in New Issue
Block a user