@kaitranntt/ccs 2.5.1 → 3.0.1
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.ja.md +325 -0
- package/README.md +149 -102
- package/README.vi.md +147 -94
- package/VERSION +1 -1
- package/bin/auth-commands.js +405 -0
- package/bin/ccs.js +113 -35
- package/bin/config-manager.js +36 -7
- package/bin/doctor.js +365 -0
- package/bin/error-manager.js +159 -0
- package/bin/instance-manager.js +218 -0
- package/bin/profile-detector.js +199 -0
- package/bin/profile-registry.js +226 -0
- package/bin/recovery-manager.js +135 -0
- package/lib/ccs +856 -301
- package/lib/ccs.ps1 +792 -122
- package/package.json +1 -1
- package/scripts/postinstall.js +111 -12
|
@@ -0,0 +1,135 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
const fs = require('fs');
|
|
4
|
+
const path = require('path');
|
|
5
|
+
const os = require('os');
|
|
6
|
+
|
|
7
|
+
/**
|
|
8
|
+
* Auto-recovery for missing or corrupted configuration
|
|
9
|
+
*/
|
|
10
|
+
class RecoveryManager {
|
|
11
|
+
constructor() {
|
|
12
|
+
this.homedir = os.homedir();
|
|
13
|
+
this.ccsDir = path.join(this.homedir, '.ccs');
|
|
14
|
+
this.claudeDir = path.join(this.homedir, '.claude');
|
|
15
|
+
this.recovered = [];
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
/**
|
|
19
|
+
* Ensure ~/.ccs/ directory exists
|
|
20
|
+
*/
|
|
21
|
+
ensureCcsDirectory() {
|
|
22
|
+
if (!fs.existsSync(this.ccsDir)) {
|
|
23
|
+
fs.mkdirSync(this.ccsDir, { recursive: true, mode: 0o755 });
|
|
24
|
+
this.recovered.push('Created ~/.ccs/ directory');
|
|
25
|
+
return true;
|
|
26
|
+
}
|
|
27
|
+
return false;
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
/**
|
|
31
|
+
* Ensure ~/.ccs/config.json exists with defaults
|
|
32
|
+
*/
|
|
33
|
+
ensureConfigJson() {
|
|
34
|
+
const configPath = path.join(this.ccsDir, 'config.json');
|
|
35
|
+
|
|
36
|
+
// Check if exists and valid
|
|
37
|
+
if (fs.existsSync(configPath)) {
|
|
38
|
+
try {
|
|
39
|
+
const content = fs.readFileSync(configPath, 'utf8');
|
|
40
|
+
JSON.parse(content); // Validate JSON
|
|
41
|
+
return false; // No recovery needed
|
|
42
|
+
} catch (e) {
|
|
43
|
+
// Corrupted - backup and recreate
|
|
44
|
+
const backupPath = `${configPath}.backup.${Date.now()}`;
|
|
45
|
+
fs.renameSync(configPath, backupPath);
|
|
46
|
+
this.recovered.push(`Backed up corrupted config.json to ${path.basename(backupPath)}`);
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
// Create default config
|
|
51
|
+
const defaultConfig = {
|
|
52
|
+
profiles: {
|
|
53
|
+
glm: '~/.ccs/glm.settings.json',
|
|
54
|
+
kimi: '~/.ccs/kimi.settings.json',
|
|
55
|
+
default: '~/.claude/settings.json'
|
|
56
|
+
}
|
|
57
|
+
};
|
|
58
|
+
|
|
59
|
+
const tmpPath = `${configPath}.tmp`;
|
|
60
|
+
fs.writeFileSync(tmpPath, JSON.stringify(defaultConfig, null, 2) + '\n', 'utf8');
|
|
61
|
+
fs.renameSync(tmpPath, configPath);
|
|
62
|
+
|
|
63
|
+
this.recovered.push('Created ~/.ccs/config.json');
|
|
64
|
+
return true;
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
/**
|
|
68
|
+
* Ensure ~/.claude/settings.json exists
|
|
69
|
+
*/
|
|
70
|
+
ensureClaudeSettings() {
|
|
71
|
+
const claudeSettingsPath = path.join(this.claudeDir, 'settings.json');
|
|
72
|
+
|
|
73
|
+
// Create ~/.claude/ if missing
|
|
74
|
+
if (!fs.existsSync(this.claudeDir)) {
|
|
75
|
+
fs.mkdirSync(this.claudeDir, { recursive: true, mode: 0o755 });
|
|
76
|
+
this.recovered.push('Created ~/.claude/ directory');
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
// Create settings.json if missing
|
|
80
|
+
if (!fs.existsSync(claudeSettingsPath)) {
|
|
81
|
+
const tmpPath = `${claudeSettingsPath}.tmp`;
|
|
82
|
+
fs.writeFileSync(tmpPath, '{}\n', 'utf8');
|
|
83
|
+
fs.renameSync(tmpPath, claudeSettingsPath);
|
|
84
|
+
|
|
85
|
+
this.recovered.push('Created ~/.claude/settings.json');
|
|
86
|
+
return true;
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
return false;
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
/**
|
|
93
|
+
* Run all recovery operations
|
|
94
|
+
* @returns {boolean} True if any recovery performed
|
|
95
|
+
*/
|
|
96
|
+
recoverAll() {
|
|
97
|
+
this.recovered = [];
|
|
98
|
+
|
|
99
|
+
this.ensureCcsDirectory();
|
|
100
|
+
this.ensureConfigJson();
|
|
101
|
+
this.ensureClaudeSettings();
|
|
102
|
+
|
|
103
|
+
return this.recovered.length > 0;
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
/**
|
|
107
|
+
* Get recovery summary
|
|
108
|
+
* @returns {string[]} List of recovery actions performed
|
|
109
|
+
*/
|
|
110
|
+
getRecoverySummary() {
|
|
111
|
+
return this.recovered;
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
/**
|
|
115
|
+
* Show recovery hints
|
|
116
|
+
*/
|
|
117
|
+
showRecoveryHints() {
|
|
118
|
+
if (this.recovered.length === 0) return;
|
|
119
|
+
|
|
120
|
+
console.log('');
|
|
121
|
+
console.log('[i] Auto-recovery completed:');
|
|
122
|
+
this.recovered.forEach(msg => console.log(` - ${msg}`));
|
|
123
|
+
|
|
124
|
+
// Show login hint if created Claude settings
|
|
125
|
+
if (this.recovered.some(msg => msg.includes('settings.json'))) {
|
|
126
|
+
console.log('');
|
|
127
|
+
console.log('[i] Next step: Login to Claude CLI');
|
|
128
|
+
console.log(' Run: claude /login');
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
console.log('');
|
|
132
|
+
}
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
module.exports = RecoveryManager;
|