@wangxiaoerqqq/ccs 2.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (64) hide show
  1. package/CHANGELOG.md +52 -0
  2. package/LICENSE +21 -0
  3. package/README.md +287 -0
  4. package/dist/commands/current.d.ts +2 -0
  5. package/dist/commands/current.d.ts.map +1 -0
  6. package/dist/commands/current.js +29 -0
  7. package/dist/commands/current.js.map +1 -0
  8. package/dist/commands/edit.d.ts +2 -0
  9. package/dist/commands/edit.d.ts.map +1 -0
  10. package/dist/commands/edit.js +21 -0
  11. package/dist/commands/edit.js.map +1 -0
  12. package/dist/commands/init.d.ts +2 -0
  13. package/dist/commands/init.d.ts.map +1 -0
  14. package/dist/commands/init.js +47 -0
  15. package/dist/commands/init.js.map +1 -0
  16. package/dist/commands/list.d.ts +2 -0
  17. package/dist/commands/list.d.ts.map +1 -0
  18. package/dist/commands/list.js +31 -0
  19. package/dist/commands/list.js.map +1 -0
  20. package/dist/commands/models.d.ts +2 -0
  21. package/dist/commands/models.d.ts.map +1 -0
  22. package/dist/commands/models.js +44 -0
  23. package/dist/commands/models.js.map +1 -0
  24. package/dist/commands/set-key.d.ts +2 -0
  25. package/dist/commands/set-key.d.ts.map +1 -0
  26. package/dist/commands/set-key.js +51 -0
  27. package/dist/commands/set-key.js.map +1 -0
  28. package/dist/commands/switch.d.ts +3 -0
  29. package/dist/commands/switch.d.ts.map +1 -0
  30. package/dist/commands/switch.js +83 -0
  31. package/dist/commands/switch.js.map +1 -0
  32. package/dist/config/crypto.d.ts +5 -0
  33. package/dist/config/crypto.d.ts.map +1 -0
  34. package/dist/config/crypto.js +89 -0
  35. package/dist/config/crypto.js.map +1 -0
  36. package/dist/config/manager.d.ts +28 -0
  37. package/dist/config/manager.d.ts.map +1 -0
  38. package/dist/config/manager.js +188 -0
  39. package/dist/config/manager.js.map +1 -0
  40. package/dist/index.d.ts +3 -0
  41. package/dist/index.d.ts.map +1 -0
  42. package/dist/index.js +99 -0
  43. package/dist/index.js.map +1 -0
  44. package/dist/providers/defaults.d.ts +22 -0
  45. package/dist/providers/defaults.d.ts.map +1 -0
  46. package/dist/providers/defaults.js +160 -0
  47. package/dist/providers/defaults.js.map +1 -0
  48. package/dist/providers/registry.d.ts +20 -0
  49. package/dist/providers/registry.d.ts.map +1 -0
  50. package/dist/providers/registry.js +81 -0
  51. package/dist/providers/registry.js.map +1 -0
  52. package/dist/utils/logger.d.ts +13 -0
  53. package/dist/utils/logger.d.ts.map +1 -0
  54. package/dist/utils/logger.js +51 -0
  55. package/dist/utils/logger.js.map +1 -0
  56. package/dist/utils/platform.d.ts +11 -0
  57. package/dist/utils/platform.d.ts.map +1 -0
  58. package/dist/utils/platform.js +50 -0
  59. package/dist/utils/platform.js.map +1 -0
  60. package/dist/utils/reload.d.ts +4 -0
  61. package/dist/utils/reload.d.ts.map +1 -0
  62. package/dist/utils/reload.js +51 -0
  63. package/dist/utils/reload.js.map +1 -0
  64. package/package.json +64 -0
@@ -0,0 +1 @@
1
+ {"version":3,"file":"set-key.js","sourceRoot":"","sources":["../../src/commands/set-key.ts"],"names":[],"mappings":"AAAA,+CAA+C;AAE/C,OAAO,QAAQ,MAAM,UAAU,CAAC;AAChC,OAAO,EAAE,SAAS,EAAe,UAAU,EAAE,aAAa,EAAE,MAAM,sBAAsB,CAAC;AACzF,OAAO,EAAE,cAAc,EAAE,sBAAsB,EAAE,MAAM,0BAA0B,CAAC;AAClF,OAAO,EAAE,MAAM,EAAE,MAAM,oBAAoB,CAAC;AAE5C,MAAM,CAAC,KAAK,UAAU,aAAa,CAAC,WAAoB,EAAE,SAAkB;IAC1E,UAAU,EAAE,CAAC;IAEb,IAAI,QAAQ,GAAG,WAAW,CAAC;IAE3B,qDAAqD;IACrD,IAAI,CAAC,QAAQ,EAAE,CAAC;QACd,MAAM,SAAS,GAAG,aAAa,EAAE,CAAC;QAClC,MAAM,EAAE,gBAAgB,EAAE,GAAG,MAAM,QAAQ,CAAC,MAAM,CAAC;YACjD;gBACE,IAAI,EAAE,MAAM;gBACZ,IAAI,EAAE,kBAAkB;gBACxB,OAAO,EAAE,iCAAiC;gBAC1C,OAAO,EAAE,MAAM,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC;oBACxC,IAAI,EAAE,GAAG,SAAS,CAAC,CAAC,CAAC,CAAC,IAAI,EAAE;oBAC5B,KAAK,EAAE,CAAC;iBACT,CAAC,CAAC;aACJ;SACF,CAAC,CAAC;QACH,QAAQ,GAAG,gBAAgB,CAAC;IAC9B,CAAC;IAED,oBAAoB;IACpB,IAAI,CAAC,QAAQ,IAAI,CAAC,cAAc,CAAC,QAAQ,CAAC,EAAE,CAAC;QAC3C,MAAM,CAAC,KAAK,CAAC,qBAAqB,QAAQ,IAAI,WAAW,EAAE,CAAC,CAAC;QAC7D,MAAM,CAAC,IAAI,CAAC,2CAA2C,CAAC,CAAC;QACzD,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IAClB,CAAC;IAED,IAAI,MAAM,GAAG,SAAS,CAAC;IAEvB,yCAAyC;IACzC,IAAI,CAAC,MAAM,EAAE,CAAC;QACZ,MAAM,QAAQ,GAAG,MAAM,QAAQ,CAAC,MAAM,CAAqB;YACzD;gBACE,IAAI,EAAE,UAAU;gBAChB,IAAI,EAAE,QAAQ;gBACd,OAAO,EAAE,qBAAqB,sBAAsB,CAAC,QAAQ,CAAC,GAAG;gBACjE,IAAI,EAAE,GAAG;gBACT,QAAQ,EAAE,CAAC,KAAa,EAAE,EAAE,CAAC,KAAK,CAAC,MAAM,GAAG,CAAC,IAAI,yBAAyB;aAC3E;SACF,CAAC,CAAC;QACH,MAAM,GAAG,QAAQ,CAAC,MAAM,CAAC;IAC3B,CAAC;IAED,6DAA6D;IAC7D,IAAI,MAAM,EAAE,CAAC;QACX,SAAS,CAAC,QAAQ,EAAE,MAAM,CAAC,CAAC;QAC5B,MAAM,CAAC,OAAO,CAAC,qBAAqB,sBAAsB,CAAC,QAAQ,CAAC,EAAE,CAAC,CAAC;IAC1E,CAAC;AACH,CAAC"}
@@ -0,0 +1,3 @@
1
+ export declare function switchCommand(provider?: string, model?: string): Promise<void>;
2
+ export declare function switchModelCommand(model: string): Promise<void>;
3
+ //# sourceMappingURL=switch.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"switch.d.ts","sourceRoot":"","sources":["../../src/commands/switch.ts"],"names":[],"mappings":"AAmBA,wBAAsB,aAAa,CAAC,QAAQ,CAAC,EAAE,MAAM,EAAE,KAAK,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAoEpF;AAGD,wBAAsB,kBAAkB,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAarE"}
@@ -0,0 +1,83 @@
1
+ // Switch command - switch provider and/or model
2
+ import { loadCurrent, updateClaudeSettings, initConfig } from '../config/manager.js';
3
+ import { providerExists, modelExists, getProviderDefaultModel, getProviderDisplayName, getModelDisplayName, hasApiKey } from '../providers/registry.js';
4
+ import { logger } from '../utils/logger.js';
5
+ import { sendReloadSignal, findClaudePid } from '../utils/reload.js';
6
+ export async function switchCommand(provider, model) {
7
+ initConfig();
8
+ // If no arguments, show current selection
9
+ if (!provider) {
10
+ const current = loadCurrent();
11
+ logger.info('Current selection:');
12
+ logger.item('Provider', getProviderDisplayName(current.provider));
13
+ logger.item('Model', getModelDisplayName(current.provider, current.model));
14
+ return;
15
+ }
16
+ // Validate provider
17
+ if (!providerExists(provider)) {
18
+ logger.error(`Unknown provider: ${provider}`);
19
+ logger.info('Run "ccs list" to see available providers');
20
+ process.exit(1);
21
+ }
22
+ // Check if API key is set
23
+ if (!hasApiKey(provider)) {
24
+ logger.error(`No API key set for ${getProviderDisplayName(provider)}`);
25
+ logger.info(`Run "ccs set-key ${provider}" to set the API key`);
26
+ process.exit(1);
27
+ }
28
+ // Determine model
29
+ if (!model) {
30
+ const defaultModel = getProviderDefaultModel(provider);
31
+ if (!defaultModel) {
32
+ logger.error(`No models available for provider: ${provider}`);
33
+ process.exit(1);
34
+ }
35
+ model = defaultModel;
36
+ }
37
+ // Validate model
38
+ if (!modelExists(provider, model)) {
39
+ logger.error(`Unknown model "${model}" for provider "${provider}"`);
40
+ logger.info(`Run "ccs models ${provider}" to see available models`);
41
+ process.exit(1);
42
+ }
43
+ // Update settings
44
+ try {
45
+ updateClaudeSettings(provider, model);
46
+ logger.success(`Switched to: ${getProviderDisplayName(provider)} / ${model}`);
47
+ // Try to send reload signal
48
+ const pid = findClaudePid();
49
+ if (pid) {
50
+ const reloaded = sendReloadSignal(pid);
51
+ if (reloaded) {
52
+ logger.success(`Sent reload signal to Claude Code (PID: ${pid})`);
53
+ logger.info('Session will continue with new settings');
54
+ }
55
+ else {
56
+ logger.warning('Could not send reload signal');
57
+ logger.info('Run "/reload" in Claude Code to apply changes');
58
+ }
59
+ }
60
+ else {
61
+ logger.info('Claude Code not running');
62
+ logger.info('Settings will be applied on next startup');
63
+ }
64
+ }
65
+ catch (error) {
66
+ const message = error instanceof Error ? error.message : String(error);
67
+ logger.error(`Failed to switch: ${message}`);
68
+ process.exit(1);
69
+ }
70
+ }
71
+ // Switch only model (keep current provider)
72
+ export async function switchModelCommand(model) {
73
+ initConfig();
74
+ const current = loadCurrent();
75
+ if (!current.provider) {
76
+ logger.error('No provider currently selected');
77
+ logger.info('Run "ccs <provider>" to select a provider first');
78
+ process.exit(1);
79
+ }
80
+ // Use the existing switch logic
81
+ await switchCommand(current.provider, model);
82
+ }
83
+ //# sourceMappingURL=switch.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"switch.js","sourceRoot":"","sources":["../../src/commands/switch.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,5 @@
1
+ export declare function encrypt(plaintext: string): string;
2
+ export declare function decrypt(ciphertext: string): string;
3
+ export declare function encryptObject(obj: Record<string, string>): string;
4
+ export declare function decryptObject(ciphertext: string): Record<string, string>;
5
+ //# sourceMappingURL=crypto.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"crypto.d.ts","sourceRoot":"","sources":["../../src/config/crypto.ts"],"names":[],"mappings":"AA8DA,wBAAgB,OAAO,CAAC,SAAS,EAAE,MAAM,GAAG,MAAM,CAUjD;AAGD,wBAAgB,OAAO,CAAC,UAAU,EAAE,MAAM,GAAG,MAAM,CAiBlD;AAGD,wBAAgB,aAAa,CAAC,GAAG,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,GAAG,MAAM,CAGjE;AAGD,wBAAgB,aAAa,CAAC,UAAU,EAAE,MAAM,GAAG,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAGxE"}
@@ -0,0 +1,89 @@
1
+ // Encryption utilities for storing API keys securely
2
+ import crypto from 'crypto';
3
+ import os from 'os';
4
+ import fs from 'fs';
5
+ import path from 'path';
6
+ import { getConfigDir } from '../utils/platform.js';
7
+ // Algorithm settings
8
+ const ALGORITHM = 'aes-256-cbc';
9
+ const SALT = 'ccs-encryption-salt-v1';
10
+ const ITERATIONS = 100000;
11
+ const KEY_LENGTH = 32;
12
+ // Get or generate machine-specific key
13
+ function getMachineKey() {
14
+ const keyPath = path.join(getConfigDir(), '.key');
15
+ // Try to read existing key
16
+ if (fs.existsSync(keyPath)) {
17
+ try {
18
+ const keyData = fs.readFileSync(keyPath, 'utf8');
19
+ return Buffer.from(keyData, 'hex');
20
+ }
21
+ catch {
22
+ // Fall through to generate new key
23
+ }
24
+ }
25
+ // Generate new key based on machine ID
26
+ const machineId = getMachineId();
27
+ const key = crypto.pbkdf2Sync(machineId, SALT, ITERATIONS, KEY_LENGTH, 'sha512');
28
+ // Save key for future use
29
+ try {
30
+ fs.mkdirSync(getConfigDir(), { recursive: true });
31
+ fs.writeFileSync(keyPath, key.toString('hex'), { mode: 0o600 });
32
+ }
33
+ catch {
34
+ // If we can't save, just use in-memory key
35
+ }
36
+ return key;
37
+ }
38
+ // Generate a machine-specific identifier
39
+ function getMachineId() {
40
+ const parts = [
41
+ os.hostname(),
42
+ os.platform(),
43
+ os.arch(),
44
+ os.cpus()[0]?.model || 'unknown',
45
+ // Use MAC address or other unique identifiers
46
+ Object.values(os.networkInterfaces())
47
+ .flat()
48
+ .filter((iface) => iface !== undefined)
49
+ .map(iface => iface.mac)
50
+ .filter(mac => mac && mac !== '00:00:00:00:00:00')
51
+ .sort()[0] || 'nomac'
52
+ ];
53
+ return parts.join('-');
54
+ }
55
+ // Encrypt a string
56
+ export function encrypt(plaintext) {
57
+ const key = getMachineKey();
58
+ const iv = crypto.randomBytes(16);
59
+ const cipher = crypto.createCipheriv(ALGORITHM, key, iv);
60
+ let encrypted = cipher.update(plaintext, 'utf8', 'hex');
61
+ encrypted += cipher.final('hex');
62
+ // Format: iv:encrypted
63
+ return `${iv.toString('hex')}:${encrypted}`;
64
+ }
65
+ // Decrypt a string
66
+ export function decrypt(ciphertext) {
67
+ const key = getMachineKey();
68
+ const parts = ciphertext.split(':');
69
+ if (parts.length !== 2) {
70
+ throw new Error('Invalid encrypted data format');
71
+ }
72
+ const iv = Buffer.from(parts[0], 'hex');
73
+ const encrypted = parts[1];
74
+ const decipher = crypto.createDecipheriv(ALGORITHM, key, iv);
75
+ let decrypted = decipher.update(encrypted, 'hex', 'utf8');
76
+ decrypted += decipher.final('utf8');
77
+ return decrypted;
78
+ }
79
+ // Encrypt an object (secrets store)
80
+ export function encryptObject(obj) {
81
+ const json = JSON.stringify(obj);
82
+ return encrypt(json);
83
+ }
84
+ // Decrypt an object (secrets store)
85
+ export function decryptObject(ciphertext) {
86
+ const json = decrypt(ciphertext);
87
+ return JSON.parse(json);
88
+ }
89
+ //# sourceMappingURL=crypto.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"crypto.js","sourceRoot":"","sources":["../../src/config/crypto.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,28 @@
1
+ import { type ProviderConfig } from '../providers/defaults.js';
2
+ export interface CurrentSelection {
3
+ provider: string;
4
+ model: string;
5
+ }
6
+ export interface CCSConfig {
7
+ providers: Record<string, ProviderConfig>;
8
+ current: CurrentSelection;
9
+ secrets: Record<string, string>;
10
+ }
11
+ export declare function ensureConfigDir(): void;
12
+ export declare function initConfig(): void;
13
+ export declare function loadProviders(): Record<string, ProviderConfig>;
14
+ export declare function saveProviders(providers: Record<string, ProviderConfig>): void;
15
+ export declare function loadCurrent(): CurrentSelection;
16
+ export declare function saveCurrent(current: CurrentSelection): void;
17
+ export declare function loadSecrets(): Record<string, string>;
18
+ export declare function saveSecrets(secrets: Record<string, string>): void;
19
+ export declare function getApiKey(provider: string): string | null;
20
+ export declare function setApiKey(provider: string, apiKey: string): void;
21
+ export interface ClaudeSettings {
22
+ env?: Record<string, unknown>;
23
+ [key: string]: unknown;
24
+ }
25
+ export declare function loadClaudeSettings(): ClaudeSettings;
26
+ export declare function saveClaudeSettings(settings: ClaudeSettings): void;
27
+ export declare function updateClaudeSettings(provider: string, modelCode: string): void;
28
+ //# sourceMappingURL=manager.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"manager.d.ts","sourceRoot":"","sources":["../../src/config/manager.ts"],"names":[],"mappings":"AAWA,OAAO,EAAoB,KAAK,cAAc,EAAE,MAAM,0BAA0B,CAAC;AAIjF,MAAM,WAAW,gBAAgB;IAC/B,QAAQ,EAAE,MAAM,CAAC;IACjB,KAAK,EAAE,MAAM,CAAC;CACf;AAED,MAAM,WAAW,SAAS;IACxB,SAAS,EAAE,MAAM,CAAC,MAAM,EAAE,cAAc,CAAC,CAAC;IAC1C,OAAO,EAAE,gBAAgB,CAAC;IAC1B,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;CACjC;AAgCD,wBAAgB,eAAe,IAAI,IAAI,CAKtC;AAGD,wBAAgB,UAAU,IAAI,IAAI,CAsBjC;AAGD,wBAAgB,aAAa,IAAI,MAAM,CAAC,MAAM,EAAE,cAAc,CAAC,CA4B9D;AAGD,wBAAgB,aAAa,CAAC,SAAS,EAAE,MAAM,CAAC,MAAM,EAAE,cAAc,CAAC,GAAG,IAAI,CAG7E;AAGD,wBAAgB,WAAW,IAAI,gBAAgB,CAa9C;AAGD,wBAAgB,WAAW,CAAC,OAAO,EAAE,gBAAgB,GAAG,IAAI,CAG3D;AAGD,wBAAgB,WAAW,IAAI,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAapD;AAGD,wBAAgB,WAAW,CAAC,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,GAAG,IAAI,CAIjE;AAGD,wBAAgB,SAAS,CAAC,QAAQ,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAGzD;AAGD,wBAAgB,SAAS,CAAC,QAAQ,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG,IAAI,CAIhE;AAGD,MAAM,WAAW,cAAc;IAC7B,GAAG,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IAC9B,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC;CACxB;AAGD,wBAAgB,kBAAkB,IAAI,cAAc,CAanD;AAGD,wBAAgB,kBAAkB,CAAC,QAAQ,EAAE,cAAc,GAAG,IAAI,CAGjE;AAGD,wBAAgB,oBAAoB,CAAC,QAAQ,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,GAAG,IAAI,CAwC9E"}
@@ -0,0 +1,188 @@
1
+ // Configuration manager for CCS
2
+ import fs from 'fs';
3
+ import { getConfigDir, getProvidersPath, getSecretsPath, getCurrentPath, getClaudeSettingsPath } from '../utils/platform.js';
4
+ import { decryptObject, encryptObject } from './crypto.js';
5
+ import { defaultProviders } from '../providers/defaults.js';
6
+ import { logger } from '../utils/logger.js';
7
+ function isLegacyFormat(provider) {
8
+ return typeof provider === 'object' && provider !== null && typeof provider.base_url === 'string';
9
+ }
10
+ function migrateProvider(legacy) {
11
+ const models = {};
12
+ for (const [key, modelCfg] of Object.entries(legacy.models)) {
13
+ models[key] = {
14
+ name: modelCfg.name,
15
+ model: key,
16
+ ...(modelCfg.default ? { default: true } : {})
17
+ };
18
+ }
19
+ return {
20
+ name: legacy.name,
21
+ env: { ANTHROPIC_BASE_URL: legacy.base_url },
22
+ models,
23
+ ...(legacy.note ? { note: legacy.note } : {})
24
+ };
25
+ }
26
+ // Ensure config directory exists
27
+ export function ensureConfigDir() {
28
+ const dir = getConfigDir();
29
+ if (!fs.existsSync(dir)) {
30
+ fs.mkdirSync(dir, { recursive: true });
31
+ }
32
+ }
33
+ // Initialize configuration
34
+ export function initConfig() {
35
+ ensureConfigDir();
36
+ const providersPath = getProvidersPath();
37
+ if (!fs.existsSync(providersPath)) {
38
+ fs.writeFileSync(providersPath, JSON.stringify(defaultProviders, null, 2));
39
+ }
40
+ const currentPath = getCurrentPath();
41
+ if (!fs.existsSync(currentPath)) {
42
+ const defaultCurrent = {
43
+ provider: 'aliyun',
44
+ model: 'qwen-turbo'
45
+ };
46
+ fs.writeFileSync(currentPath, JSON.stringify(defaultCurrent, null, 2));
47
+ }
48
+ const secretsPath = getSecretsPath();
49
+ if (!fs.existsSync(secretsPath)) {
50
+ const emptySecrets = encryptObject({});
51
+ fs.writeFileSync(secretsPath, emptySecrets, { mode: 0o600 });
52
+ }
53
+ }
54
+ // Load providers configuration (with legacy migration)
55
+ export function loadProviders() {
56
+ const providersPath = getProvidersPath();
57
+ if (fs.existsSync(providersPath)) {
58
+ try {
59
+ const content = fs.readFileSync(providersPath, 'utf8');
60
+ const raw = JSON.parse(content);
61
+ let migrated = false;
62
+ for (const [key, provider] of Object.entries(raw)) {
63
+ if (isLegacyFormat(provider)) {
64
+ raw[key] = migrateProvider(provider);
65
+ migrated = true;
66
+ }
67
+ }
68
+ if (migrated) {
69
+ fs.writeFileSync(providersPath, JSON.stringify(raw, null, 2));
70
+ logger.warning('providers.json 已自动升级为新格式');
71
+ }
72
+ return raw;
73
+ }
74
+ catch {
75
+ return defaultProviders;
76
+ }
77
+ }
78
+ return defaultProviders;
79
+ }
80
+ // Save providers configuration
81
+ export function saveProviders(providers) {
82
+ ensureConfigDir();
83
+ fs.writeFileSync(getProvidersPath(), JSON.stringify(providers, null, 2));
84
+ }
85
+ // Load current selection
86
+ export function loadCurrent() {
87
+ const currentPath = getCurrentPath();
88
+ if (fs.existsSync(currentPath)) {
89
+ try {
90
+ const content = fs.readFileSync(currentPath, 'utf8');
91
+ return JSON.parse(content);
92
+ }
93
+ catch {
94
+ // Return default
95
+ }
96
+ }
97
+ return { provider: 'aliyun', model: 'qwen-turbo' };
98
+ }
99
+ // Save current selection
100
+ export function saveCurrent(current) {
101
+ ensureConfigDir();
102
+ fs.writeFileSync(getCurrentPath(), JSON.stringify(current, null, 2));
103
+ }
104
+ // Load secrets (decrypted)
105
+ export function loadSecrets() {
106
+ const secretsPath = getSecretsPath();
107
+ if (fs.existsSync(secretsPath)) {
108
+ try {
109
+ const content = fs.readFileSync(secretsPath, 'utf8');
110
+ return decryptObject(content);
111
+ }
112
+ catch {
113
+ return {};
114
+ }
115
+ }
116
+ return {};
117
+ }
118
+ // Save secrets (encrypted)
119
+ export function saveSecrets(secrets) {
120
+ ensureConfigDir();
121
+ const encrypted = encryptObject(secrets);
122
+ fs.writeFileSync(getSecretsPath(), encrypted, { mode: 0o600 });
123
+ }
124
+ // Get API key for a provider
125
+ export function getApiKey(provider) {
126
+ const secrets = loadSecrets();
127
+ return secrets[provider] || null;
128
+ }
129
+ // Set API key for a provider
130
+ export function setApiKey(provider, apiKey) {
131
+ const secrets = loadSecrets();
132
+ secrets[provider] = apiKey;
133
+ saveSecrets(secrets);
134
+ }
135
+ // Load Claude Code settings
136
+ export function loadClaudeSettings() {
137
+ const settingsPath = getClaudeSettingsPath();
138
+ if (fs.existsSync(settingsPath)) {
139
+ try {
140
+ const content = fs.readFileSync(settingsPath, 'utf8');
141
+ return JSON.parse(content);
142
+ }
143
+ catch {
144
+ return {};
145
+ }
146
+ }
147
+ return {};
148
+ }
149
+ // Save Claude Code settings
150
+ export function saveClaudeSettings(settings) {
151
+ const settingsPath = getClaudeSettingsPath();
152
+ fs.writeFileSync(settingsPath, JSON.stringify(settings, null, 2));
153
+ }
154
+ // Update Claude Code settings with provider configuration
155
+ export function updateClaudeSettings(provider, modelCode) {
156
+ const providers = loadProviders();
157
+ const providerConfig = providers[provider];
158
+ if (!providerConfig) {
159
+ throw new Error(`Provider not found: ${provider}`);
160
+ }
161
+ const modelConfig = providerConfig.models[modelCode];
162
+ if (!modelConfig) {
163
+ throw new Error(`Model not found: ${modelCode}`);
164
+ }
165
+ const apiKey = getApiKey(provider);
166
+ if (!apiKey) {
167
+ throw new Error(`API key not set for provider: ${provider}`);
168
+ }
169
+ // Build env: provider.env as base, model.env overrides (skip undefined), then force auth token + model.
170
+ // modelConfig.model always wins over model.env.ANTHROPIC_MODEL.
171
+ const env = { ...providerConfig.env };
172
+ if (modelConfig.env) {
173
+ for (const [k, v] of Object.entries(modelConfig.env)) {
174
+ if (v !== undefined) {
175
+ env[k] = v;
176
+ }
177
+ }
178
+ }
179
+ env.ANTHROPIC_AUTH_TOKEN = apiKey;
180
+ env.ANTHROPIC_MODEL = modelConfig.model;
181
+ // Fully replace settings.json env
182
+ const settings = loadClaudeSettings();
183
+ settings.env = env;
184
+ saveClaudeSettings(settings);
185
+ // Record current selection (stores codename, not real model name)
186
+ saveCurrent({ provider, model: modelCode });
187
+ }
188
+ //# sourceMappingURL=manager.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"manager.js","sourceRoot":"","sources":["../../src/config/manager.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,3 @@
1
+ #!/usr/bin/env node
2
+ export {};
3
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":""}
package/dist/index.js ADDED
@@ -0,0 +1,99 @@
1
+ #!/usr/bin/env node
2
+ // CCS - Claude Code Switcher
3
+ // Main CLI entry point
4
+ import { Command } from 'commander';
5
+ import chalk from 'chalk';
6
+ import { initCommand } from './commands/init.js';
7
+ import { setKeyCommand } from './commands/set-key.js';
8
+ import { switchCommand, switchModelCommand } from './commands/switch.js';
9
+ import { listCommand } from './commands/list.js';
10
+ import { currentCommand } from './commands/current.js';
11
+ import { modelsCommand } from './commands/models.js';
12
+ import { editCommand } from './commands/edit.js';
13
+ import { reloadCommand } from './utils/reload.js';
14
+ import { initConfig, loadProviders } from './config/manager.js';
15
+ const program = new Command();
16
+ // Package version
17
+ const VERSION = '2.0.0';
18
+ program
19
+ .name('ccs')
20
+ .description('Claude Code Switcher - Quickly switch AI providers and models')
21
+ .version(VERSION);
22
+ // Init command
23
+ program
24
+ .command('init')
25
+ .description('Initialize CCS configuration')
26
+ .action(async () => {
27
+ await initCommand();
28
+ });
29
+ // Set-key command
30
+ program
31
+ .command('set-key [provider] [apiKey]')
32
+ .description('Set API key for a provider')
33
+ .action(async (provider, apiKey) => {
34
+ await setKeyCommand(provider, apiKey);
35
+ });
36
+ // List command
37
+ program
38
+ .command('list')
39
+ .alias('ls')
40
+ .description('List all available providers and models')
41
+ .action(() => {
42
+ listCommand();
43
+ });
44
+ // Current command
45
+ program
46
+ .command('current')
47
+ .description('Show current provider and model selection')
48
+ .action(() => {
49
+ currentCommand();
50
+ });
51
+ // Models command
52
+ program
53
+ .command('models [provider]')
54
+ .description('List models for a provider')
55
+ .action((provider) => {
56
+ modelsCommand(provider);
57
+ });
58
+ // Edit command
59
+ program
60
+ .command('edit')
61
+ .description('Open providers config file for editing')
62
+ .action(async () => {
63
+ await editCommand();
64
+ });
65
+ // Reload command
66
+ program
67
+ .command('reload')
68
+ .description('Send reload signal to Claude Code')
69
+ .action(() => {
70
+ reloadCommand();
71
+ });
72
+ // Model switch command
73
+ program
74
+ .command('model <model>')
75
+ .description('Switch model (keep current provider)')
76
+ .action(async (model) => {
77
+ await switchModelCommand(model);
78
+ });
79
+ // Provider switch command (dynamic - allows "ccs aliyun", "ccs zhipu", etc.)
80
+ // This handles all provider names as direct commands, including user-customized providers
81
+ initConfig();
82
+ const providers = loadProviders();
83
+ for (const providerId of Object.keys(providers)) {
84
+ program
85
+ .command(`${providerId} [model]`)
86
+ .description(`Switch to ${providerId} provider`)
87
+ .action(async (model) => {
88
+ await switchCommand(providerId, model);
89
+ });
90
+ }
91
+ // Default action - show help if no command provided
92
+ program.on('command:*', () => {
93
+ console.error(chalk.red(`Unknown command: ${program.args.join(' ')}`));
94
+ console.log('Run "ccs help" for available commands');
95
+ process.exit(1);
96
+ });
97
+ // Parse arguments
98
+ program.parse();
99
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,22 @@
1
+ export interface ModelConfig {
2
+ name: string;
3
+ model: string;
4
+ default?: boolean;
5
+ env?: Record<string, unknown>;
6
+ }
7
+ export interface ProviderConfig {
8
+ name: string;
9
+ env: Record<string, unknown>;
10
+ models: Record<string, ModelConfig>;
11
+ note?: string;
12
+ }
13
+ export type ProviderId = 'aliyun' | 'zhipu' | 'volc' | 'deepseek' | 'moonshot' | 'minimax' | 'anthropic' | 'longcat';
14
+ export declare const defaultProviders: Record<ProviderId, ProviderConfig>;
15
+ export declare function getDefaultModel(providerId: ProviderId): string | null;
16
+ export declare function getProviderName(providerId: ProviderId): string;
17
+ export declare function getModelName(providerId: ProviderId, modelId: string): string;
18
+ export declare function isValidProvider(providerId: string): providerId is ProviderId;
19
+ export declare function isValidModel(providerId: ProviderId, modelId: string): boolean;
20
+ export declare function getProviderIds(): ProviderId[];
21
+ export declare function getModels(providerId: ProviderId): string[];
22
+ //# sourceMappingURL=defaults.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"defaults.d.ts","sourceRoot":"","sources":["../../src/providers/defaults.ts"],"names":[],"mappings":"AAGA,MAAM,WAAW,WAAW;IAC1B,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,EAAE,MAAM,CAAC;IACd,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,GAAG,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;CAE/B;AAED,MAAM,WAAW,cAAc;IAC7B,IAAI,EAAE,MAAM,CAAC;IACb,GAAG,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IAC7B,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,WAAW,CAAC,CAAC;IACpC,IAAI,CAAC,EAAE,MAAM,CAAC;CACf;AAED,MAAM,MAAM,UAAU,GAAG,QAAQ,GAAG,OAAO,GAAG,MAAM,GAAG,UAAU,GAAG,UAAU,GAAG,SAAS,GAAG,WAAW,GAAG,SAAS,CAAC;AAErH,eAAO,MAAM,gBAAgB,EAAE,MAAM,CAAC,UAAU,EAAE,cAAc,CAqH/D,CAAC;AAGF,wBAAgB,eAAe,CAAC,UAAU,EAAE,UAAU,GAAG,MAAM,GAAG,IAAI,CAYrE;AAGD,wBAAgB,eAAe,CAAC,UAAU,EAAE,UAAU,GAAG,MAAM,CAE9D;AAGD,wBAAgB,YAAY,CAAC,UAAU,EAAE,UAAU,EAAE,OAAO,EAAE,MAAM,GAAG,MAAM,CAE5E;AAGD,wBAAgB,eAAe,CAAC,UAAU,EAAE,MAAM,GAAG,UAAU,IAAI,UAAU,CAE5E;AAGD,wBAAgB,YAAY,CAAC,UAAU,EAAE,UAAU,EAAE,OAAO,EAAE,MAAM,GAAG,OAAO,CAG7E;AAGD,wBAAgB,cAAc,IAAI,UAAU,EAAE,CAE7C;AAGD,wBAAgB,SAAS,CAAC,UAAU,EAAE,UAAU,GAAG,MAAM,EAAE,CAG1D"}