feat(config): add copilot configuration types and loader

- add CopilotConfig interface with account_type, port, model settings

- add DEFAULT_COPILOT_CONFIG with safe opt-in defaults

- bump UNIFIED_CONFIG_VERSION from 3 to 4

- add YAML generation for copilot section

- add 'copilot' to reserved profile names
This commit is contained in:
kaitranntt
2025-12-17 21:36:59 -05:00
parent afe0f66b9f
commit b87aeaeb01
3 changed files with 84 additions and 2 deletions
+2
View File
@@ -9,6 +9,8 @@ export const RESERVED_PROFILE_NAMES = [
'agy',
'qwen',
'iflow',
// Copilot API (GitHub Copilot proxy)
'copilot',
// CLI commands and special names
'default',
'config',
+32
View File
@@ -14,6 +14,7 @@ import {
isUnifiedConfig,
createEmptyUnifiedConfig,
UNIFIED_CONFIG_VERSION,
DEFAULT_COPILOT_CONFIG,
} from './unified-config-types';
import { isUnifiedConfigEnabled } from './feature-flags';
@@ -159,6 +160,16 @@ function mergeWithDefaults(partial: Partial<UnifiedConfig>): UnifiedConfig {
// Legacy fields (keep for backwards compatibility during read)
gemini: partial.websearch?.gemini,
},
// Copilot config - strictly opt-in, merge with defaults
copilot: {
enabled: partial.copilot?.enabled ?? DEFAULT_COPILOT_CONFIG.enabled,
auto_start: partial.copilot?.auto_start ?? DEFAULT_COPILOT_CONFIG.auto_start,
port: partial.copilot?.port ?? DEFAULT_COPILOT_CONFIG.port,
account_type: partial.copilot?.account_type ?? DEFAULT_COPILOT_CONFIG.account_type,
rate_limit: partial.copilot?.rate_limit ?? DEFAULT_COPILOT_CONFIG.rate_limit,
wait_on_limit: partial.copilot?.wait_on_limit ?? DEFAULT_COPILOT_CONFIG.wait_on_limit,
model: partial.copilot?.model ?? DEFAULT_COPILOT_CONFIG.model,
},
};
}
@@ -302,6 +313,27 @@ function generateYamlWithComments(config: UnifiedConfig): string {
lines.push('');
}
// Copilot section (GitHub Copilot proxy)
if (config.copilot) {
lines.push('# ----------------------------------------------------------------------------');
lines.push('# Copilot: GitHub Copilot API proxy (via copilot-api)');
lines.push('# Uses your existing GitHub Copilot subscription with Claude Code.');
lines.push('#');
lines.push('# WARNING: This uses a reverse-engineered API. Use responsibly.');
lines.push('# Excessive automated usage may trigger GitHub abuse detection.');
lines.push('#');
lines.push('# Setup: npx copilot-api auth (authenticate with GitHub)');
lines.push('# Usage: ccs copilot (switch to copilot profile)');
lines.push('#');
lines.push('# Models: claude-opus-4-5-20250514, claude-sonnet-4-20250514, gpt-4.1, o3');
lines.push('# Account types: individual, business, enterprise');
lines.push('# ----------------------------------------------------------------------------');
lines.push(
yaml.dump({ copilot: config.copilot }, { indent: 2, lineWidth: -1, quotingType: '"' }).trim()
);
lines.push('');
}
return lines.join('\n');
}
+50 -2
View File
@@ -13,8 +13,9 @@
* Unified config version.
* Version 2 = YAML unified format
* Version 3 = WebSearch config with model configuration for Gemini/OpenCode
* Version 4 = Copilot API integration (GitHub Copilot proxy)
*/
export const UNIFIED_CONFIG_VERSION = 3;
export const UNIFIED_CONFIG_VERSION = 4;
/**
* Account configuration (formerly in profiles.json).
@@ -148,6 +149,36 @@ export interface WebSearchProvidersConfig {
opencode?: OpenCodeWebSearchConfig;
}
/**
* Copilot API account type.
*/
export type CopilotAccountType = 'individual' | 'business' | 'enterprise';
/**
* Copilot API configuration.
* Enables GitHub Copilot subscription usage via copilot-api proxy.
* Strictly opt-in - disabled by default.
*
* WARNING: This uses a reverse-engineered API. Excessive automated usage
* may trigger GitHub's abuse-detection systems.
*/
export interface CopilotConfig {
/** Enable Copilot integration (default: false) - must be explicitly enabled */
enabled: boolean;
/** Auto-start copilot-api daemon when using profile (default: false) */
auto_start: boolean;
/** Port for copilot-api proxy (default: 4141) */
port: number;
/** GitHub Copilot account type (default: individual) */
account_type: CopilotAccountType;
/** Rate limit in seconds between requests (null = no limit) */
rate_limit: number | null;
/** Wait instead of error when rate limit is hit (default: true) */
wait_on_limit: boolean;
/** Selected model (default: claude-opus-4-5-20250514) */
model: string;
}
/**
* WebSearch configuration.
* Uses CLI tools (Gemini CLI, Grok CLI, OpenCode) for third-party profiles.
@@ -183,7 +214,7 @@ export interface WebSearchConfig {
* Stored in ~/.ccs/config.yaml
*/
export interface UnifiedConfig {
/** Config version (2 for unified format) */
/** Config version (4 for copilot support) */
version: number;
/** Default profile name to use when none specified */
default?: string;
@@ -197,6 +228,8 @@ export interface UnifiedConfig {
preferences: PreferencesConfig;
/** WebSearch configuration */
websearch?: WebSearchConfig;
/** Copilot API configuration (GitHub Copilot proxy) */
copilot?: CopilotConfig;
}
/**
@@ -211,6 +244,20 @@ export interface SecretsConfig {
profiles: Record<string, Record<string, string>>;
}
/**
* Default Copilot configuration.
* Strictly opt-in - disabled by default.
*/
export const DEFAULT_COPILOT_CONFIG: CopilotConfig = {
enabled: false,
auto_start: false,
port: 4141,
account_type: 'individual',
rate_limit: null,
wait_on_limit: true,
model: 'claude-opus-4-5-20250514',
};
/**
* Create an empty unified config with defaults.
*/
@@ -253,6 +300,7 @@ export function createEmptyUnifiedConfig(): UnifiedConfig {
},
},
},
copilot: { ...DEFAULT_COPILOT_CONFIG },
};
}