@kaitranntt/ccs 4.4.0 → 5.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.
- package/README.md +14 -7
- package/VERSION +1 -1
- package/config/base-agy.settings.json +10 -0
- package/config/base-codex.settings.json +10 -0
- package/config/base-gemini.settings.json +10 -0
- package/dist/auth/auth-commands.d.ts +52 -0
- package/dist/auth/auth-commands.d.ts.map +1 -0
- package/dist/auth/auth-commands.js +479 -0
- package/dist/auth/auth-commands.js.map +1 -0
- package/dist/auth/profile-detector.d.ts +68 -0
- package/dist/auth/profile-detector.d.ts.map +1 -0
- package/dist/auth/profile-detector.js +209 -0
- package/dist/auth/profile-detector.js.map +1 -0
- package/dist/auth/profile-registry.d.ts +60 -0
- package/dist/auth/profile-registry.d.ts.map +1 -0
- package/dist/auth/profile-registry.js +188 -0
- package/dist/auth/profile-registry.js.map +1 -0
- package/dist/ccs.d.ts +10 -0
- package/dist/ccs.d.ts.map +1 -0
- package/dist/ccs.js +320 -0
- package/dist/ccs.js.map +1 -0
- package/dist/cliproxy/auth-handler.d.ts +93 -0
- package/dist/cliproxy/auth-handler.d.ts.map +1 -0
- package/dist/cliproxy/auth-handler.js +402 -0
- package/dist/cliproxy/auth-handler.js.map +1 -0
- package/dist/cliproxy/base-config-loader.d.ts +42 -0
- package/dist/cliproxy/base-config-loader.d.ts.map +1 -0
- package/dist/cliproxy/base-config-loader.js +123 -0
- package/dist/cliproxy/base-config-loader.js.map +1 -0
- package/dist/cliproxy/binary-manager.d.ts +104 -0
- package/dist/cliproxy/binary-manager.d.ts.map +1 -0
- package/dist/cliproxy/binary-manager.js +567 -0
- package/dist/cliproxy/binary-manager.js.map +1 -0
- package/dist/cliproxy/cliproxy-executor.d.ts +33 -0
- package/dist/cliproxy/cliproxy-executor.d.ts.map +1 -0
- package/dist/cliproxy/cliproxy-executor.js +297 -0
- package/dist/cliproxy/cliproxy-executor.js.map +1 -0
- package/dist/cliproxy/config-generator.d.ts +89 -0
- package/dist/cliproxy/config-generator.d.ts.map +1 -0
- package/dist/cliproxy/config-generator.js +263 -0
- package/dist/cliproxy/config-generator.js.map +1 -0
- package/dist/cliproxy/index.d.ts +13 -0
- package/dist/cliproxy/index.d.ts.map +1 -0
- package/dist/cliproxy/index.js +62 -0
- package/dist/cliproxy/index.js.map +1 -0
- package/dist/cliproxy/platform-detector.d.ts +48 -0
- package/dist/cliproxy/platform-detector.d.ts.map +1 -0
- package/dist/cliproxy/platform-detector.js +118 -0
- package/dist/cliproxy/platform-detector.js.map +1 -0
- package/dist/cliproxy/types.d.ts +169 -0
- package/dist/cliproxy/types.d.ts.map +1 -0
- package/dist/cliproxy/types.js +7 -0
- package/dist/cliproxy/types.js.map +1 -0
- package/dist/commands/doctor-command.d.ts +10 -0
- package/dist/commands/doctor-command.d.ts.map +1 -0
- package/dist/commands/doctor-command.js +44 -0
- package/dist/commands/doctor-command.js.map +1 -0
- package/dist/commands/help-command.d.ts +5 -0
- package/dist/commands/help-command.d.ts.map +1 -0
- package/dist/commands/help-command.js +104 -0
- package/dist/commands/help-command.js.map +1 -0
- package/dist/commands/install-command.d.ts +14 -0
- package/dist/commands/install-command.d.ts.map +1 -0
- package/dist/commands/install-command.js +39 -0
- package/dist/commands/install-command.js.map +1 -0
- package/dist/commands/shell-completion-command.d.ts +10 -0
- package/dist/commands/shell-completion-command.d.ts.map +1 -0
- package/dist/commands/shell-completion-command.js +85 -0
- package/dist/commands/shell-completion-command.js.map +1 -0
- package/dist/commands/sync-command.d.ts +10 -0
- package/dist/commands/sync-command.d.ts.map +1 -0
- package/dist/commands/sync-command.js +59 -0
- package/dist/commands/sync-command.js.map +1 -0
- package/dist/commands/update-command.d.ts +12 -0
- package/dist/commands/update-command.d.ts.map +1 -0
- package/dist/commands/update-command.js +295 -0
- package/dist/commands/update-command.js.map +1 -0
- package/dist/commands/version-command.d.ts +10 -0
- package/dist/commands/version-command.d.ts.map +1 -0
- package/dist/commands/version-command.js +100 -0
- package/dist/commands/version-command.js.map +1 -0
- package/dist/delegation/delegation-handler.d.ts +60 -0
- package/dist/delegation/delegation-handler.d.ts.map +1 -0
- package/dist/delegation/delegation-handler.js +174 -0
- package/dist/delegation/delegation-handler.js.map +1 -0
- package/dist/delegation/headless-executor.d.ts +114 -0
- package/dist/delegation/headless-executor.d.ts.map +1 -0
- package/dist/delegation/headless-executor.js +562 -0
- package/dist/delegation/headless-executor.js.map +1 -0
- package/dist/delegation/result-formatter.d.ts +108 -0
- package/dist/delegation/result-formatter.d.ts.map +1 -0
- package/dist/delegation/result-formatter.js +391 -0
- package/dist/delegation/result-formatter.js.map +1 -0
- package/dist/delegation/session-manager.d.ts +58 -0
- package/dist/delegation/session-manager.d.ts.map +1 -0
- package/dist/delegation/session-manager.js +153 -0
- package/dist/delegation/session-manager.js.map +1 -0
- package/dist/delegation/settings-parser.d.ts +31 -0
- package/dist/delegation/settings-parser.d.ts.map +1 -0
- package/dist/delegation/settings-parser.js +107 -0
- package/dist/delegation/settings-parser.js.map +1 -0
- package/dist/glmt/delta-accumulator.d.ts +210 -0
- package/dist/glmt/delta-accumulator.d.ts.map +1 -0
- package/dist/glmt/delta-accumulator.js +351 -0
- package/dist/glmt/delta-accumulator.js.map +1 -0
- package/dist/glmt/glmt-proxy.d.ts +72 -0
- package/dist/glmt/glmt-proxy.d.ts.map +1 -0
- package/dist/glmt/glmt-proxy.js +427 -0
- package/dist/glmt/glmt-proxy.js.map +1 -0
- package/dist/glmt/glmt-transformer.d.ts +265 -0
- package/dist/glmt/glmt-transformer.d.ts.map +1 -0
- package/dist/glmt/glmt-transformer.js +832 -0
- package/dist/glmt/glmt-transformer.js.map +1 -0
- package/dist/glmt/locale-enforcer.d.ts +38 -0
- package/dist/glmt/locale-enforcer.d.ts.map +1 -0
- package/dist/glmt/locale-enforcer.js +69 -0
- package/dist/glmt/locale-enforcer.js.map +1 -0
- package/dist/glmt/reasoning-enforcer.d.ts +52 -0
- package/dist/glmt/reasoning-enforcer.d.ts.map +1 -0
- package/dist/glmt/reasoning-enforcer.js +151 -0
- package/dist/glmt/reasoning-enforcer.js.map +1 -0
- package/dist/glmt/sse-parser.d.ts +47 -0
- package/dist/glmt/sse-parser.d.ts.map +1 -0
- package/dist/glmt/sse-parser.js +93 -0
- package/dist/glmt/sse-parser.js.map +1 -0
- package/dist/management/doctor.d.ts +104 -0
- package/dist/management/doctor.d.ts.map +1 -0
- package/dist/management/doctor.js +673 -0
- package/dist/management/doctor.js.map +1 -0
- package/dist/management/instance-manager.d.ts +57 -0
- package/dist/management/instance-manager.d.ts.map +1 -0
- package/dist/management/instance-manager.js +195 -0
- package/dist/management/instance-manager.js.map +1 -0
- package/dist/management/recovery-manager.d.ts +39 -0
- package/dist/management/recovery-manager.d.ts.map +1 -0
- package/dist/management/recovery-manager.js +141 -0
- package/dist/management/recovery-manager.js.map +1 -0
- package/dist/management/shared-manager.d.ts +47 -0
- package/dist/management/shared-manager.d.ts.map +1 -0
- package/dist/management/shared-manager.js +388 -0
- package/dist/management/shared-manager.js.map +1 -0
- package/dist/types/cli.d.ts +50 -0
- package/dist/types/cli.d.ts.map +1 -0
- package/dist/types/cli.js +16 -0
- package/dist/types/cli.js.map +1 -0
- package/dist/types/config.d.ts +51 -0
- package/dist/types/config.d.ts.map +1 -0
- package/dist/types/config.js +26 -0
- package/dist/types/config.js.map +1 -0
- package/dist/types/delegation.d.ts +61 -0
- package/dist/types/delegation.d.ts.map +1 -0
- package/dist/types/delegation.js +6 -0
- package/dist/types/delegation.js.map +1 -0
- package/dist/types/glmt.d.ts +95 -0
- package/dist/types/glmt.d.ts.map +1 -0
- package/dist/types/glmt.js +7 -0
- package/dist/types/glmt.js.map +1 -0
- package/dist/types/index.d.ts +13 -0
- package/dist/types/index.d.ts.map +1 -0
- package/dist/types/index.js +16 -0
- package/dist/types/index.js.map +1 -0
- package/dist/types/utils.d.ts +36 -0
- package/dist/types/utils.d.ts.map +1 -0
- package/dist/types/utils.js +22 -0
- package/dist/types/utils.js.map +1 -0
- package/dist/utils/claude-detector.d.ts +14 -0
- package/dist/utils/claude-detector.d.ts.map +1 -0
- package/dist/utils/claude-detector.js +112 -0
- package/dist/utils/claude-detector.js.map +1 -0
- package/dist/utils/claude-dir-installer.d.ts +46 -0
- package/dist/utils/claude-dir-installer.d.ts.map +1 -0
- package/dist/utils/claude-dir-installer.js +289 -0
- package/dist/utils/claude-dir-installer.js.map +1 -0
- package/dist/utils/claude-symlink-manager.d.ts +61 -0
- package/dist/utils/claude-symlink-manager.d.ts.map +1 -0
- package/dist/utils/claude-symlink-manager.js +291 -0
- package/dist/utils/claude-symlink-manager.js.map +1 -0
- package/dist/utils/config-manager.d.ts +32 -0
- package/dist/utils/config-manager.d.ts.map +1 -0
- package/dist/utils/config-manager.js +143 -0
- package/dist/utils/config-manager.js.map +1 -0
- package/dist/utils/delegation-validator.d.ts +39 -0
- package/dist/utils/delegation-validator.d.ts.map +1 -0
- package/dist/utils/delegation-validator.js +161 -0
- package/dist/utils/delegation-validator.js.map +1 -0
- package/dist/utils/error-codes.d.ts +36 -0
- package/dist/utils/error-codes.d.ts.map +1 -0
- package/dist/utils/error-codes.js +63 -0
- package/dist/utils/error-codes.js.map +1 -0
- package/dist/utils/error-manager.d.ts +59 -0
- package/dist/utils/error-manager.d.ts.map +1 -0
- package/dist/utils/error-manager.js +228 -0
- package/dist/utils/error-manager.js.map +1 -0
- package/dist/utils/helpers.d.ts +27 -0
- package/dist/utils/helpers.d.ts.map +1 -0
- package/dist/utils/helpers.js +150 -0
- package/dist/utils/helpers.js.map +1 -0
- package/dist/utils/package-manager-detector.d.ts +14 -0
- package/dist/utils/package-manager-detector.d.ts.map +1 -0
- package/dist/utils/package-manager-detector.js +162 -0
- package/dist/utils/package-manager-detector.js.map +1 -0
- package/dist/utils/progress-indicator.d.ts +52 -0
- package/dist/utils/progress-indicator.d.ts.map +1 -0
- package/dist/utils/progress-indicator.js +102 -0
- package/dist/utils/progress-indicator.js.map +1 -0
- package/dist/utils/prompt.d.ts +29 -0
- package/dist/utils/prompt.d.ts.map +1 -0
- package/dist/utils/prompt.js +116 -0
- package/dist/utils/prompt.js.map +1 -0
- package/dist/utils/shell-completion.d.ts +52 -0
- package/dist/utils/shell-completion.d.ts.map +1 -0
- package/dist/utils/shell-completion.js +231 -0
- package/dist/utils/shell-completion.js.map +1 -0
- package/dist/utils/shell-executor.d.ts +15 -0
- package/dist/utils/shell-executor.d.ts.map +1 -0
- package/dist/utils/shell-executor.js +57 -0
- package/dist/utils/shell-executor.js.map +1 -0
- package/dist/utils/update-checker.d.ts +48 -0
- package/dist/utils/update-checker.d.ts.map +1 -0
- package/dist/utils/update-checker.js +241 -0
- package/dist/utils/update-checker.js.map +1 -0
- package/lib/ccs +21 -1907
- package/lib/ccs.ps1 +26 -1800
- package/lib/error-codes.ps1 +2 -1
- package/lib/prompt.ps1 +2 -2
- package/package.json +31 -11
- package/scripts/add-shebang.js +39 -0
- package/scripts/bump-version.sh +25 -37
- package/scripts/dev-install.sh +32 -11
- package/scripts/postinstall.js +29 -29
- package/bin/auth/auth-commands.js +0 -499
- package/bin/auth/profile-detector.js +0 -204
- package/bin/auth/profile-registry.js +0 -225
- package/bin/ccs.js +0 -1034
- package/bin/delegation/README.md +0 -191
- package/bin/delegation/delegation-handler.js +0 -212
- package/bin/delegation/headless-executor.js +0 -618
- package/bin/delegation/result-formatter.js +0 -485
- package/bin/delegation/session-manager.js +0 -157
- package/bin/delegation/settings-parser.js +0 -109
- package/bin/glmt/delta-accumulator.js +0 -276
- package/bin/glmt/glmt-proxy.js +0 -495
- package/bin/glmt/glmt-transformer.js +0 -999
- package/bin/glmt/locale-enforcer.js +0 -72
- package/bin/glmt/reasoning-enforcer.js +0 -173
- package/bin/glmt/sse-parser.js +0 -96
- package/bin/management/doctor.js +0 -721
- package/bin/management/instance-manager.js +0 -202
- package/bin/management/recovery-manager.js +0 -135
- package/bin/management/shared-manager.js +0 -402
- package/bin/utils/claude-detector.js +0 -73
- package/bin/utils/claude-dir-installer.js +0 -283
- package/bin/utils/claude-symlink-manager.js +0 -289
- package/bin/utils/config-manager.js +0 -103
- package/bin/utils/delegation-validator.js +0 -154
- package/bin/utils/error-codes.js +0 -59
- package/bin/utils/error-manager.js +0 -165
- package/bin/utils/helpers.js +0 -136
- package/bin/utils/progress-indicator.js +0 -111
- package/bin/utils/prompt.js +0 -134
- package/bin/utils/shell-completion.js +0 -256
- package/bin/utils/update-checker.js +0 -243
|
@@ -1,154 +0,0 @@
|
|
|
1
|
-
#!/usr/bin/env node
|
|
2
|
-
'use strict';
|
|
3
|
-
|
|
4
|
-
const fs = require('fs');
|
|
5
|
-
const path = require('path');
|
|
6
|
-
const os = require('os');
|
|
7
|
-
|
|
8
|
-
/**
|
|
9
|
-
* Validates delegation profiles for CCS delegation system
|
|
10
|
-
* Ensures profiles exist and have valid API keys configured
|
|
11
|
-
*/
|
|
12
|
-
class DelegationValidator {
|
|
13
|
-
/**
|
|
14
|
-
* Validate a delegation profile
|
|
15
|
-
* @param {string} profileName - Name of profile to validate (e.g., 'glm', 'kimi')
|
|
16
|
-
* @returns {Object} Validation result { valid: boolean, error?: string, settingsPath?: string }
|
|
17
|
-
*/
|
|
18
|
-
static validate(profileName) {
|
|
19
|
-
const homeDir = os.homedir();
|
|
20
|
-
const settingsPath = path.join(homeDir, '.ccs', `${profileName}.settings.json`);
|
|
21
|
-
|
|
22
|
-
// Check if profile directory exists
|
|
23
|
-
if (!fs.existsSync(settingsPath)) {
|
|
24
|
-
return {
|
|
25
|
-
valid: false,
|
|
26
|
-
error: `Profile not found: ${profileName}`,
|
|
27
|
-
suggestion: `Profile settings missing at: ${settingsPath}\n\n` +
|
|
28
|
-
`To set up ${profileName} profile:\n` +
|
|
29
|
-
` 1. Copy base settings: cp config/base-${profileName}.settings.json ~/.ccs/${profileName}.settings.json\n` +
|
|
30
|
-
` 2. Edit settings: Edit ~/.ccs/${profileName}.settings.json\n` +
|
|
31
|
-
` 3. Set your API key in ANTHROPIC_AUTH_TOKEN field`
|
|
32
|
-
};
|
|
33
|
-
}
|
|
34
|
-
|
|
35
|
-
// Read and parse settings.json
|
|
36
|
-
let settings;
|
|
37
|
-
try {
|
|
38
|
-
const settingsContent = fs.readFileSync(settingsPath, 'utf8');
|
|
39
|
-
settings = JSON.parse(settingsContent);
|
|
40
|
-
} catch (error) {
|
|
41
|
-
return {
|
|
42
|
-
valid: false,
|
|
43
|
-
error: `Failed to parse settings.json for ${profileName}`,
|
|
44
|
-
suggestion: `Settings file is corrupted or invalid JSON.\n\n` +
|
|
45
|
-
`Location: ${settingsPath}\n` +
|
|
46
|
-
`Parse error: ${error.message}\n\n` +
|
|
47
|
-
`Fix: Restore from base config:\n` +
|
|
48
|
-
` cp config/base-${profileName}.settings.json ~/.ccs/${profileName}.settings.json`
|
|
49
|
-
};
|
|
50
|
-
}
|
|
51
|
-
|
|
52
|
-
// Validate API key exists and is not default
|
|
53
|
-
const apiKey = settings.env?.ANTHROPIC_AUTH_TOKEN;
|
|
54
|
-
|
|
55
|
-
if (!apiKey) {
|
|
56
|
-
return {
|
|
57
|
-
valid: false,
|
|
58
|
-
error: `API key not configured for ${profileName}`,
|
|
59
|
-
suggestion: `Missing ANTHROPIC_AUTH_TOKEN in settings.\n\n` +
|
|
60
|
-
`Edit: ${settingsPath}\n` +
|
|
61
|
-
`Set: env.ANTHROPIC_AUTH_TOKEN to your API key`
|
|
62
|
-
};
|
|
63
|
-
}
|
|
64
|
-
|
|
65
|
-
// Check for default placeholder values
|
|
66
|
-
const defaultPlaceholders = [
|
|
67
|
-
'YOUR_GLM_API_KEY_HERE',
|
|
68
|
-
'YOUR_KIMI_API_KEY_HERE',
|
|
69
|
-
'YOUR_API_KEY_HERE',
|
|
70
|
-
'your-api-key-here',
|
|
71
|
-
'PLACEHOLDER'
|
|
72
|
-
];
|
|
73
|
-
|
|
74
|
-
if (defaultPlaceholders.some(placeholder => apiKey.includes(placeholder))) {
|
|
75
|
-
return {
|
|
76
|
-
valid: false,
|
|
77
|
-
error: `Default API key placeholder detected for ${profileName}`,
|
|
78
|
-
suggestion: `API key is still set to default placeholder.\n\n` +
|
|
79
|
-
`To configure your profile:\n` +
|
|
80
|
-
` 1. Edit: ${settingsPath}\n` +
|
|
81
|
-
` 2. Replace ANTHROPIC_AUTH_TOKEN with your actual API key\n\n` +
|
|
82
|
-
`Get API key:\n` +
|
|
83
|
-
` GLM: https://z.ai/manage-apikey/apikey-list\n` +
|
|
84
|
-
` Kimi: https://platform.moonshot.cn/console/api-keys`
|
|
85
|
-
};
|
|
86
|
-
}
|
|
87
|
-
|
|
88
|
-
// Validation passed
|
|
89
|
-
return {
|
|
90
|
-
valid: true,
|
|
91
|
-
settingsPath,
|
|
92
|
-
apiKey: apiKey.substring(0, 8) + '...' // Show first 8 chars for verification
|
|
93
|
-
};
|
|
94
|
-
}
|
|
95
|
-
|
|
96
|
-
/**
|
|
97
|
-
* Format validation error for display
|
|
98
|
-
* @param {Object} result - Validation result from validate()
|
|
99
|
-
* @returns {string} Formatted error message
|
|
100
|
-
*/
|
|
101
|
-
static formatError(result) {
|
|
102
|
-
if (result.valid) {
|
|
103
|
-
return '';
|
|
104
|
-
}
|
|
105
|
-
|
|
106
|
-
let message = `\n[X] ${result.error}\n\n`;
|
|
107
|
-
|
|
108
|
-
if (result.suggestion) {
|
|
109
|
-
message += `${result.suggestion}\n`;
|
|
110
|
-
}
|
|
111
|
-
|
|
112
|
-
return message;
|
|
113
|
-
}
|
|
114
|
-
|
|
115
|
-
/**
|
|
116
|
-
* Check if profile is delegation-ready (shorthand)
|
|
117
|
-
* @param {string} profileName - Profile to check
|
|
118
|
-
* @returns {boolean} True if ready for delegation
|
|
119
|
-
*/
|
|
120
|
-
static isReady(profileName) {
|
|
121
|
-
const result = this.validate(profileName);
|
|
122
|
-
return result.valid;
|
|
123
|
-
}
|
|
124
|
-
|
|
125
|
-
/**
|
|
126
|
-
* Get all delegation-ready profiles
|
|
127
|
-
* @returns {Array<string>} List of profile names ready for delegation
|
|
128
|
-
*/
|
|
129
|
-
static getReadyProfiles() {
|
|
130
|
-
const homeDir = os.homedir();
|
|
131
|
-
const ccsDir = path.join(homeDir, '.ccs');
|
|
132
|
-
|
|
133
|
-
if (!fs.existsSync(ccsDir)) {
|
|
134
|
-
return [];
|
|
135
|
-
}
|
|
136
|
-
|
|
137
|
-
const profiles = [];
|
|
138
|
-
const entries = fs.readdirSync(ccsDir, { withFileTypes: true });
|
|
139
|
-
|
|
140
|
-
// Look for *.settings.json files
|
|
141
|
-
for (const entry of entries) {
|
|
142
|
-
if (entry.isFile() && entry.name.endsWith('.settings.json')) {
|
|
143
|
-
const profileName = entry.name.replace('.settings.json', '');
|
|
144
|
-
if (this.isReady(profileName)) {
|
|
145
|
-
profiles.push(profileName);
|
|
146
|
-
}
|
|
147
|
-
}
|
|
148
|
-
}
|
|
149
|
-
|
|
150
|
-
return profiles;
|
|
151
|
-
}
|
|
152
|
-
}
|
|
153
|
-
|
|
154
|
-
module.exports = { DelegationValidator };
|
package/bin/utils/error-codes.js
DELETED
|
@@ -1,59 +0,0 @@
|
|
|
1
|
-
// CCS Error Codes
|
|
2
|
-
// Documentation: ../../docs/errors/README.md
|
|
3
|
-
|
|
4
|
-
const ERROR_CODES = {
|
|
5
|
-
// Configuration Errors (E100-E199)
|
|
6
|
-
CONFIG_MISSING: 'E101',
|
|
7
|
-
CONFIG_INVALID_JSON: 'E102',
|
|
8
|
-
CONFIG_INVALID_PROFILE: 'E103',
|
|
9
|
-
|
|
10
|
-
// Profile Management Errors (E200-E299)
|
|
11
|
-
PROFILE_NOT_FOUND: 'E104',
|
|
12
|
-
PROFILE_ALREADY_EXISTS: 'E105',
|
|
13
|
-
PROFILE_CANNOT_DELETE_DEFAULT: 'E106',
|
|
14
|
-
PROFILE_INVALID_NAME: 'E107',
|
|
15
|
-
|
|
16
|
-
// Claude CLI Detection Errors (E300-E399)
|
|
17
|
-
CLAUDE_NOT_FOUND: 'E301',
|
|
18
|
-
CLAUDE_VERSION_INCOMPATIBLE: 'E302',
|
|
19
|
-
CLAUDE_EXECUTION_FAILED: 'E303',
|
|
20
|
-
|
|
21
|
-
// Network/API Errors (E400-E499)
|
|
22
|
-
GLMT_PROXY_TIMEOUT: 'E401',
|
|
23
|
-
API_KEY_MISSING: 'E402',
|
|
24
|
-
API_AUTH_FAILED: 'E403',
|
|
25
|
-
API_RATE_LIMIT: 'E404',
|
|
26
|
-
|
|
27
|
-
// File System Errors (E500-E599)
|
|
28
|
-
FS_CANNOT_CREATE_DIR: 'E501',
|
|
29
|
-
FS_CANNOT_WRITE_FILE: 'E502',
|
|
30
|
-
FS_CANNOT_READ_FILE: 'E503',
|
|
31
|
-
FS_INSTANCE_NOT_FOUND: 'E504',
|
|
32
|
-
|
|
33
|
-
// Internal Errors (E900-E999)
|
|
34
|
-
INTERNAL_ERROR: 'E900',
|
|
35
|
-
INVALID_STATE: 'E901'
|
|
36
|
-
};
|
|
37
|
-
|
|
38
|
-
// Error code documentation URL generator
|
|
39
|
-
function getErrorDocUrl(errorCode) {
|
|
40
|
-
return `https://github.com/kaitranntt/ccs/blob/main/docs/errors/README.md#${errorCode.toLowerCase()}`;
|
|
41
|
-
}
|
|
42
|
-
|
|
43
|
-
// Get error category from code
|
|
44
|
-
function getErrorCategory(errorCode) {
|
|
45
|
-
const code = parseInt(errorCode.substring(1));
|
|
46
|
-
if (code >= 100 && code < 200) return 'Configuration';
|
|
47
|
-
if (code >= 200 && code < 300) return 'Profile Management';
|
|
48
|
-
if (code >= 300 && code < 400) return 'Claude CLI Detection';
|
|
49
|
-
if (code >= 400 && code < 500) return 'Network/API';
|
|
50
|
-
if (code >= 500 && code < 600) return 'File System';
|
|
51
|
-
if (code >= 900 && code < 1000) return 'Internal';
|
|
52
|
-
return 'Unknown';
|
|
53
|
-
}
|
|
54
|
-
|
|
55
|
-
module.exports = {
|
|
56
|
-
ERROR_CODES,
|
|
57
|
-
getErrorDocUrl,
|
|
58
|
-
getErrorCategory
|
|
59
|
-
};
|
|
@@ -1,165 +0,0 @@
|
|
|
1
|
-
'use strict';
|
|
2
|
-
|
|
3
|
-
const { colored } = require('./helpers');
|
|
4
|
-
const { ERROR_CODES, getErrorDocUrl } = require('./error-codes');
|
|
5
|
-
|
|
6
|
-
/**
|
|
7
|
-
* Error types with structured messages (Legacy - kept for compatibility)
|
|
8
|
-
*/
|
|
9
|
-
const ErrorTypes = {
|
|
10
|
-
NO_CLAUDE_CLI: 'NO_CLAUDE_CLI',
|
|
11
|
-
MISSING_SETTINGS: 'MISSING_SETTINGS',
|
|
12
|
-
INVALID_CONFIG: 'INVALID_CONFIG',
|
|
13
|
-
UNKNOWN_PROFILE: 'UNKNOWN_PROFILE',
|
|
14
|
-
PERMISSION_DENIED: 'PERMISSION_DENIED',
|
|
15
|
-
GENERIC: 'GENERIC'
|
|
16
|
-
};
|
|
17
|
-
|
|
18
|
-
/**
|
|
19
|
-
* Enhanced error manager with context-aware messages
|
|
20
|
-
*/
|
|
21
|
-
class ErrorManager {
|
|
22
|
-
/**
|
|
23
|
-
* Show error code and documentation URL
|
|
24
|
-
* @param {string} errorCode - Error code (e.g., E301)
|
|
25
|
-
*/
|
|
26
|
-
static showErrorCode(errorCode) {
|
|
27
|
-
console.error(colored(`Error: ${errorCode}`, 'yellow'));
|
|
28
|
-
console.error(colored(getErrorDocUrl(errorCode), 'yellow'));
|
|
29
|
-
console.error('');
|
|
30
|
-
}
|
|
31
|
-
|
|
32
|
-
/**
|
|
33
|
-
* Show Claude CLI not found error
|
|
34
|
-
*/
|
|
35
|
-
static showClaudeNotFound() {
|
|
36
|
-
console.error('');
|
|
37
|
-
console.error(colored('[X] Claude CLI not found', 'red'));
|
|
38
|
-
console.error('');
|
|
39
|
-
console.error('CCS requires Claude CLI to be installed and available in PATH.');
|
|
40
|
-
console.error('');
|
|
41
|
-
console.error(colored('Solutions:', 'yellow'));
|
|
42
|
-
console.error(' 1. Install Claude CLI:');
|
|
43
|
-
console.error(' https://docs.claude.com/en/docs/claude-code/installation');
|
|
44
|
-
console.error('');
|
|
45
|
-
console.error(' 2. Verify installation:');
|
|
46
|
-
console.error(' command -v claude (Unix)');
|
|
47
|
-
console.error(' Get-Command claude (Windows)');
|
|
48
|
-
console.error('');
|
|
49
|
-
console.error(' 3. Custom path (if installed elsewhere):');
|
|
50
|
-
console.error(' export CCS_CLAUDE_PATH="/path/to/claude"');
|
|
51
|
-
console.error('');
|
|
52
|
-
this.showErrorCode(ERROR_CODES.CLAUDE_NOT_FOUND);
|
|
53
|
-
}
|
|
54
|
-
|
|
55
|
-
/**
|
|
56
|
-
* Show settings file not found error
|
|
57
|
-
* @param {string} settingsPath - Path to missing settings file
|
|
58
|
-
*/
|
|
59
|
-
static showSettingsNotFound(settingsPath) {
|
|
60
|
-
const isClaudeSettings = settingsPath.includes('.claude') && settingsPath.endsWith('settings.json');
|
|
61
|
-
|
|
62
|
-
console.error('');
|
|
63
|
-
console.error(colored('[X] Settings file not found', 'red'));
|
|
64
|
-
console.error('');
|
|
65
|
-
console.error(`File: ${settingsPath}`);
|
|
66
|
-
console.error('');
|
|
67
|
-
|
|
68
|
-
if (isClaudeSettings) {
|
|
69
|
-
console.error('This file is auto-created when you login to Claude CLI.');
|
|
70
|
-
console.error('');
|
|
71
|
-
console.error(colored('Solutions:', 'yellow'));
|
|
72
|
-
console.error(` echo '{}' > ${settingsPath}`);
|
|
73
|
-
console.error(' claude /login');
|
|
74
|
-
console.error('');
|
|
75
|
-
console.error('Why: Newer Claude CLI versions require explicit login.');
|
|
76
|
-
} else {
|
|
77
|
-
console.error(colored('Solutions:', 'yellow'));
|
|
78
|
-
console.error(' npm install -g @kaitranntt/ccs --force');
|
|
79
|
-
console.error('');
|
|
80
|
-
console.error('This will recreate missing profile settings.');
|
|
81
|
-
}
|
|
82
|
-
|
|
83
|
-
console.error('');
|
|
84
|
-
this.showErrorCode(ERROR_CODES.CONFIG_INVALID_PROFILE);
|
|
85
|
-
}
|
|
86
|
-
|
|
87
|
-
/**
|
|
88
|
-
* Show invalid configuration error
|
|
89
|
-
* @param {string} configPath - Path to invalid config
|
|
90
|
-
* @param {string} errorDetail - JSON parse error detail
|
|
91
|
-
*/
|
|
92
|
-
static showInvalidConfig(configPath, errorDetail) {
|
|
93
|
-
console.error('');
|
|
94
|
-
console.error(colored('[X] Configuration invalid', 'red'));
|
|
95
|
-
console.error('');
|
|
96
|
-
console.error(`File: ${configPath}`);
|
|
97
|
-
console.error(`Issue: ${errorDetail}`);
|
|
98
|
-
console.error('');
|
|
99
|
-
console.error(colored('Solutions:', 'yellow'));
|
|
100
|
-
console.error(' # Backup corrupted file');
|
|
101
|
-
console.error(` mv ${configPath} ${configPath}.backup`);
|
|
102
|
-
console.error('');
|
|
103
|
-
console.error(' # Reinstall CCS');
|
|
104
|
-
console.error(' npm install -g @kaitranntt/ccs --force');
|
|
105
|
-
console.error('');
|
|
106
|
-
console.error('Your profile settings will be preserved.');
|
|
107
|
-
console.error('');
|
|
108
|
-
this.showErrorCode(ERROR_CODES.CONFIG_INVALID_JSON);
|
|
109
|
-
}
|
|
110
|
-
|
|
111
|
-
/**
|
|
112
|
-
* Show profile not found error
|
|
113
|
-
* @param {string} profileName - Requested profile name
|
|
114
|
-
* @param {string[]} availableProfiles - List of available profiles
|
|
115
|
-
* @param {string[]} suggestions - Suggested profile names (fuzzy match)
|
|
116
|
-
*/
|
|
117
|
-
static showProfileNotFound(profileName, availableProfiles, suggestions = []) {
|
|
118
|
-
console.error('');
|
|
119
|
-
console.error(colored(`[X] Profile '${profileName}' not found`, 'red'));
|
|
120
|
-
console.error('');
|
|
121
|
-
|
|
122
|
-
if (suggestions && suggestions.length > 0) {
|
|
123
|
-
console.error(colored('Did you mean:', 'yellow'));
|
|
124
|
-
suggestions.forEach(s => console.error(` ${s}`));
|
|
125
|
-
console.error('');
|
|
126
|
-
}
|
|
127
|
-
|
|
128
|
-
console.error(colored('Available profiles:', 'cyan'));
|
|
129
|
-
availableProfiles.forEach(line => console.error(` ${line}`));
|
|
130
|
-
console.error('');
|
|
131
|
-
console.error(colored('Solutions:', 'yellow'));
|
|
132
|
-
console.error(' # Use existing profile');
|
|
133
|
-
console.error(' ccs <profile> "your prompt"');
|
|
134
|
-
console.error('');
|
|
135
|
-
console.error(' # Create new account profile');
|
|
136
|
-
console.error(' ccs auth create <name>');
|
|
137
|
-
console.error('');
|
|
138
|
-
this.showErrorCode(ERROR_CODES.PROFILE_NOT_FOUND);
|
|
139
|
-
}
|
|
140
|
-
|
|
141
|
-
/**
|
|
142
|
-
* Show permission denied error
|
|
143
|
-
* @param {string} path - Path with permission issue
|
|
144
|
-
*/
|
|
145
|
-
static showPermissionDenied(path) {
|
|
146
|
-
console.error('');
|
|
147
|
-
console.error(colored('[X] Permission denied', 'red'));
|
|
148
|
-
console.error('');
|
|
149
|
-
console.error(`Cannot write to: ${path}`);
|
|
150
|
-
console.error('');
|
|
151
|
-
console.error(colored('Solutions:', 'yellow'));
|
|
152
|
-
console.error(' # Fix ownership');
|
|
153
|
-
console.error(' sudo chown -R $USER ~/.ccs ~/.claude');
|
|
154
|
-
console.error('');
|
|
155
|
-
console.error(' # Fix permissions');
|
|
156
|
-
console.error(' chmod 755 ~/.ccs ~/.claude');
|
|
157
|
-
console.error('');
|
|
158
|
-
console.error(' # Retry installation');
|
|
159
|
-
console.error(' npm install -g @kaitranntt/ccs --force');
|
|
160
|
-
console.error('');
|
|
161
|
-
this.showErrorCode(ERROR_CODES.FS_CANNOT_WRITE_FILE);
|
|
162
|
-
}
|
|
163
|
-
}
|
|
164
|
-
|
|
165
|
-
module.exports = { ErrorManager, ErrorTypes };
|
package/bin/utils/helpers.js
DELETED
|
@@ -1,136 +0,0 @@
|
|
|
1
|
-
'use strict';
|
|
2
|
-
|
|
3
|
-
const fs = require('fs');
|
|
4
|
-
const path = require('path');
|
|
5
|
-
const os = require('os');
|
|
6
|
-
|
|
7
|
-
// TTY-aware color detection (matches lib/ccs bash logic)
|
|
8
|
-
function getColors() {
|
|
9
|
-
const forcedColors = process.env.FORCE_COLOR;
|
|
10
|
-
const noColor = process.env.NO_COLOR;
|
|
11
|
-
const isTTY = process.stdout.isTTY === true; // Must be explicitly true
|
|
12
|
-
|
|
13
|
-
const useColors = forcedColors || (isTTY && !noColor);
|
|
14
|
-
|
|
15
|
-
if (useColors) {
|
|
16
|
-
return {
|
|
17
|
-
red: '\x1b[0;31m',
|
|
18
|
-
yellow: '\x1b[1;33m',
|
|
19
|
-
cyan: '\x1b[0;36m',
|
|
20
|
-
green: '\x1b[0;32m',
|
|
21
|
-
bold: '\x1b[1m',
|
|
22
|
-
reset: '\x1b[0m'
|
|
23
|
-
};
|
|
24
|
-
}
|
|
25
|
-
|
|
26
|
-
return { red: '', yellow: '', cyan: '', green: '', bold: '', reset: '' };
|
|
27
|
-
}
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
// Colors object (dynamic)
|
|
31
|
-
const colors = getColors();
|
|
32
|
-
|
|
33
|
-
// Helper: Apply color to text (returns plain text if colors disabled)
|
|
34
|
-
function colored(text, colorName = 'reset') {
|
|
35
|
-
const currentColors = getColors();
|
|
36
|
-
const color = currentColors[colorName] || '';
|
|
37
|
-
return color ? `${color}${text}${currentColors.reset}` : text;
|
|
38
|
-
}
|
|
39
|
-
|
|
40
|
-
// Simple error formatting
|
|
41
|
-
function error(message) {
|
|
42
|
-
console.error(`ERROR: ${message}`);
|
|
43
|
-
console.error('Try: npm install -g @kaitranntt/ccs --force');
|
|
44
|
-
process.exit(1);
|
|
45
|
-
}
|
|
46
|
-
|
|
47
|
-
// Path expansion (~ and env vars)
|
|
48
|
-
function expandPath(pathStr) {
|
|
49
|
-
// Handle tilde expansion
|
|
50
|
-
if (pathStr.startsWith('~/') || pathStr.startsWith('~\\')) {
|
|
51
|
-
pathStr = path.join(os.homedir(), pathStr.slice(2));
|
|
52
|
-
}
|
|
53
|
-
|
|
54
|
-
// Expand environment variables (Windows and Unix)
|
|
55
|
-
pathStr = pathStr.replace(/\$\{([^}]+)\}/g, (_, name) => process.env[name] || '');
|
|
56
|
-
pathStr = pathStr.replace(/\$([A-Z_][A-Z0-9_]*)/gi, (_, name) => process.env[name] || '');
|
|
57
|
-
|
|
58
|
-
// Windows %VAR% style
|
|
59
|
-
if (process.platform === 'win32') {
|
|
60
|
-
pathStr = pathStr.replace(/%([^%]+)%/g, (_, name) => process.env[name] || '');
|
|
61
|
-
}
|
|
62
|
-
|
|
63
|
-
return path.normalize(pathStr);
|
|
64
|
-
}
|
|
65
|
-
|
|
66
|
-
/**
|
|
67
|
-
* Calculate Levenshtein distance between two strings
|
|
68
|
-
* @param {string} a - First string
|
|
69
|
-
* @param {string} b - Second string
|
|
70
|
-
* @returns {number} Edit distance
|
|
71
|
-
*/
|
|
72
|
-
function levenshteinDistance(a, b) {
|
|
73
|
-
if (a.length === 0) return b.length;
|
|
74
|
-
if (b.length === 0) return a.length;
|
|
75
|
-
|
|
76
|
-
const matrix = [];
|
|
77
|
-
|
|
78
|
-
// Initialize first row and column
|
|
79
|
-
for (let i = 0; i <= b.length; i++) {
|
|
80
|
-
matrix[i] = [i];
|
|
81
|
-
}
|
|
82
|
-
|
|
83
|
-
for (let j = 0; j <= a.length; j++) {
|
|
84
|
-
matrix[0][j] = j;
|
|
85
|
-
}
|
|
86
|
-
|
|
87
|
-
// Fill in the rest of the matrix
|
|
88
|
-
for (let i = 1; i <= b.length; i++) {
|
|
89
|
-
for (let j = 1; j <= a.length; j++) {
|
|
90
|
-
if (b.charAt(i - 1) === a.charAt(j - 1)) {
|
|
91
|
-
matrix[i][j] = matrix[i - 1][j - 1];
|
|
92
|
-
} else {
|
|
93
|
-
matrix[i][j] = Math.min(
|
|
94
|
-
matrix[i - 1][j - 1] + 1, // substitution
|
|
95
|
-
matrix[i][j - 1] + 1, // insertion
|
|
96
|
-
matrix[i - 1][j] + 1 // deletion
|
|
97
|
-
);
|
|
98
|
-
}
|
|
99
|
-
}
|
|
100
|
-
}
|
|
101
|
-
|
|
102
|
-
return matrix[b.length][a.length];
|
|
103
|
-
}
|
|
104
|
-
|
|
105
|
-
/**
|
|
106
|
-
* Find similar strings using fuzzy matching
|
|
107
|
-
* @param {string} target - Target string
|
|
108
|
-
* @param {string[]} candidates - List of candidate strings
|
|
109
|
-
* @param {number} maxDistance - Maximum edit distance (default: 2)
|
|
110
|
-
* @returns {string[]} Similar strings sorted by distance
|
|
111
|
-
*/
|
|
112
|
-
function findSimilarStrings(target, candidates, maxDistance = 2) {
|
|
113
|
-
const targetLower = target.toLowerCase();
|
|
114
|
-
|
|
115
|
-
const matches = candidates
|
|
116
|
-
.map(candidate => ({
|
|
117
|
-
name: candidate,
|
|
118
|
-
distance: levenshteinDistance(targetLower, candidate.toLowerCase())
|
|
119
|
-
}))
|
|
120
|
-
.filter(item => item.distance <= maxDistance && item.distance > 0)
|
|
121
|
-
.sort((a, b) => a.distance - b.distance)
|
|
122
|
-
.slice(0, 3) // Show at most 3 suggestions
|
|
123
|
-
.map(item => item.name);
|
|
124
|
-
|
|
125
|
-
return matches;
|
|
126
|
-
}
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
module.exports = {
|
|
130
|
-
colors,
|
|
131
|
-
colored,
|
|
132
|
-
error,
|
|
133
|
-
expandPath,
|
|
134
|
-
levenshteinDistance,
|
|
135
|
-
findSimilarStrings
|
|
136
|
-
};
|
|
@@ -1,111 +0,0 @@
|
|
|
1
|
-
'use strict';
|
|
2
|
-
|
|
3
|
-
/**
|
|
4
|
-
* Simple Progress Indicator (no external dependencies)
|
|
5
|
-
*
|
|
6
|
-
* Features:
|
|
7
|
-
* - ASCII-only spinner frames (cross-platform compatible)
|
|
8
|
-
* - TTY detection (no spinners in pipes/logs)
|
|
9
|
-
* - Elapsed time display
|
|
10
|
-
* - CI environment detection
|
|
11
|
-
*/
|
|
12
|
-
|
|
13
|
-
class ProgressIndicator {
|
|
14
|
-
/**
|
|
15
|
-
* Create a progress indicator
|
|
16
|
-
* @param {string} message - Message to display
|
|
17
|
-
* @param {Object} options - Options
|
|
18
|
-
* @param {string[]} options.frames - Spinner frames (default: ASCII)
|
|
19
|
-
* @param {number} options.interval - Frame interval in ms (default: 80)
|
|
20
|
-
*/
|
|
21
|
-
constructor(message, options = {}) {
|
|
22
|
-
this.message = message;
|
|
23
|
-
// ASCII-only frames for cross-platform compatibility
|
|
24
|
-
this.frames = options.frames || ['|', '/', '-', '\\'];
|
|
25
|
-
this.frameIndex = 0;
|
|
26
|
-
this.interval = null;
|
|
27
|
-
this.startTime = Date.now();
|
|
28
|
-
|
|
29
|
-
// TTY detection: only animate if stderr is TTY and not in CI
|
|
30
|
-
this.isTTY = process.stderr.isTTY === true && !process.env.CI && !process.env.NO_COLOR;
|
|
31
|
-
}
|
|
32
|
-
|
|
33
|
-
/**
|
|
34
|
-
* Start the spinner
|
|
35
|
-
*/
|
|
36
|
-
start() {
|
|
37
|
-
if (!this.isTTY) {
|
|
38
|
-
// Non-TTY: just print message once
|
|
39
|
-
process.stderr.write(`[i] ${this.message}...\n`);
|
|
40
|
-
return;
|
|
41
|
-
}
|
|
42
|
-
|
|
43
|
-
// TTY: animate spinner
|
|
44
|
-
this.interval = setInterval(() => {
|
|
45
|
-
const frame = this.frames[this.frameIndex];
|
|
46
|
-
const elapsed = ((Date.now() - this.startTime) / 1000).toFixed(1);
|
|
47
|
-
process.stderr.write(`\r[${frame}] ${this.message}... (${elapsed}s)`);
|
|
48
|
-
this.frameIndex = (this.frameIndex + 1) % this.frames.length;
|
|
49
|
-
}, 80); // 12.5fps for smooth animation
|
|
50
|
-
}
|
|
51
|
-
|
|
52
|
-
/**
|
|
53
|
-
* Stop spinner with success message
|
|
54
|
-
* @param {string} message - Optional success message (defaults to original message)
|
|
55
|
-
*/
|
|
56
|
-
succeed(message) {
|
|
57
|
-
this.stop();
|
|
58
|
-
const finalMessage = message || this.message;
|
|
59
|
-
const elapsed = ((Date.now() - this.startTime) / 1000).toFixed(1);
|
|
60
|
-
|
|
61
|
-
if (this.isTTY) {
|
|
62
|
-
// Clear spinner line and show success
|
|
63
|
-
process.stderr.write(`\r[OK] ${finalMessage} (${elapsed}s)\n`);
|
|
64
|
-
} else {
|
|
65
|
-
// Non-TTY: just show completion
|
|
66
|
-
process.stderr.write(`[OK] ${finalMessage}\n`);
|
|
67
|
-
}
|
|
68
|
-
}
|
|
69
|
-
|
|
70
|
-
/**
|
|
71
|
-
* Stop spinner with failure message
|
|
72
|
-
* @param {string} message - Optional failure message (defaults to original message)
|
|
73
|
-
*/
|
|
74
|
-
fail(message) {
|
|
75
|
-
this.stop();
|
|
76
|
-
const finalMessage = message || this.message;
|
|
77
|
-
|
|
78
|
-
if (this.isTTY) {
|
|
79
|
-
// Clear spinner line and show failure
|
|
80
|
-
process.stderr.write(`\r[X] ${finalMessage}\n`);
|
|
81
|
-
} else {
|
|
82
|
-
// Non-TTY: just show failure
|
|
83
|
-
process.stderr.write(`[X] ${finalMessage}\n`);
|
|
84
|
-
}
|
|
85
|
-
}
|
|
86
|
-
|
|
87
|
-
/**
|
|
88
|
-
* Update spinner message (while running)
|
|
89
|
-
* @param {string} newMessage - New message to display
|
|
90
|
-
*/
|
|
91
|
-
update(newMessage) {
|
|
92
|
-
this.message = newMessage;
|
|
93
|
-
}
|
|
94
|
-
|
|
95
|
-
/**
|
|
96
|
-
* Stop the spinner without showing success/failure
|
|
97
|
-
*/
|
|
98
|
-
stop() {
|
|
99
|
-
if (this.interval) {
|
|
100
|
-
clearInterval(this.interval);
|
|
101
|
-
this.interval = null;
|
|
102
|
-
|
|
103
|
-
if (this.isTTY) {
|
|
104
|
-
// Clear the spinner line
|
|
105
|
-
process.stderr.write('\r\x1b[K');
|
|
106
|
-
}
|
|
107
|
-
}
|
|
108
|
-
}
|
|
109
|
-
}
|
|
110
|
-
|
|
111
|
-
module.exports = { ProgressIndicator };
|