@kaitranntt/ccs 3.0.0 → 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 +133 -122
- package/README.vi.md +147 -94
- package/VERSION +1 -1
- package/bin/ccs.js +47 -12
- package/bin/config-manager.js +36 -7
- package/bin/doctor.js +365 -0
- package/bin/error-manager.js +159 -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
package/README.vi.md
CHANGED
|
@@ -4,16 +4,17 @@
|
|
|
4
4
|
|
|
5
5
|

|
|
6
6
|
|
|
7
|
-
**Một lệnh, không downtime,
|
|
7
|
+
**Một lệnh, không downtime, nhiều tài khoản**
|
|
8
8
|
|
|
9
|
-
Chuyển đổi giữa
|
|
9
|
+
Chuyển đổi giữa nhiều tài khoản Claude, GLM, và Kimi ngay lập tức.<br>
|
|
10
|
+
Ngừng hitting rate limits. Làm việc liên tục.
|
|
10
11
|
|
|
11
12
|
|
|
12
13
|
[](LICENSE)
|
|
13
14
|
[]()
|
|
14
15
|
[](https://claudekit.cc?ref=HMNKXOHN)
|
|
15
16
|
|
|
16
|
-
**Ngôn ngữ**: [English](README.md) | [Tiếng Việt](README.vi.md)
|
|
17
|
+
**Ngôn ngữ**: [English](README.md) | [Tiếng Việt](README.vi.md) | [日本語](README.ja.md)
|
|
17
18
|
|
|
18
19
|
</div>
|
|
19
20
|
|
|
@@ -37,7 +38,18 @@ claude /login
|
|
|
37
38
|
npm install -g @kaitranntt/ccs
|
|
38
39
|
```
|
|
39
40
|
|
|
40
|
-
|
|
41
|
+
Tất cả các trình quản lý package chính đều được hỗ trợ:
|
|
42
|
+
|
|
43
|
+
```bash
|
|
44
|
+
# yarn
|
|
45
|
+
yarn global add @kaitranntt/ccs
|
|
46
|
+
|
|
47
|
+
# pnpm (ít hơn 70% dung lượng đĩa)
|
|
48
|
+
pnpm add -g @kaitranntt/ccs
|
|
49
|
+
|
|
50
|
+
# bun (nhanh hơn 30x)
|
|
51
|
+
bun add -g @kaitranntt/ccs
|
|
52
|
+
```
|
|
41
53
|
|
|
42
54
|
#### Option 2: Cài Đặt Trực Tiếp (Truyền thống)
|
|
43
55
|
|
|
@@ -51,38 +63,7 @@ curl -fsSL ccs.kaitran.ca/install | bash
|
|
|
51
63
|
irm ccs.kaitran.ca/install | iex
|
|
52
64
|
```
|
|
53
65
|
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
```bash
|
|
57
|
-
# Dùng Claude subscription (mặc định)
|
|
58
|
-
ccs "Review thiết kế kiến trúc này"
|
|
59
|
-
|
|
60
|
-
# Chuyển sang GLM cho tác vụ tối ưu chi phí
|
|
61
|
-
ccs glm "Tạo REST API đơn giản"
|
|
62
|
-
|
|
63
|
-
# Dùng GLM cho tất cả lệnh tiếp theo cho đến khi chuyển lại
|
|
64
|
-
ccs glm
|
|
65
|
-
ccs "Debug issue này"
|
|
66
|
-
ccs "Viết unit tests"
|
|
67
|
-
```
|
|
68
|
-
|
|
69
|
-
#### Package Manager Options
|
|
70
|
-
|
|
71
|
-
Tất cả các trình quản lý package chính đều được hỗ trợ:
|
|
72
|
-
|
|
73
|
-
```bash
|
|
74
|
-
# npm (mặc định)
|
|
75
|
-
npm install -g @kaitranntt/ccs
|
|
76
|
-
|
|
77
|
-
# yarn
|
|
78
|
-
yarn global add @kaitranntt/ccs
|
|
79
|
-
|
|
80
|
-
# pnpm (ít hơn 70% dung lượng đĩa)
|
|
81
|
-
pnpm add -g @kaitranntt/ccs
|
|
82
|
-
|
|
83
|
-
# bun (nhanh hơn 30x)
|
|
84
|
-
bun add -g @kaitranntt/ccs
|
|
85
|
-
```
|
|
66
|
+
> **💡 Mẹo hiệu năng**: Cài truyền thống bỏ qua Node.js routing để khởi động nhanh hơn, nhưng tôi ưu tiên cập nhật npm do triển khai dễ dàng hơn.
|
|
86
67
|
|
|
87
68
|
### Cấu Hình (Tự Tạo)
|
|
88
69
|
|
|
@@ -111,84 +92,137 @@ $env:CCS_CLAUDE_PATH = "D:\Tools\Claude\claude.exe" # Windows
|
|
|
111
92
|
|
|
112
93
|
---
|
|
113
94
|
|
|
95
|
+
### Lần Chuyển Đổi Đầu Tiên
|
|
96
|
+
|
|
97
|
+
> **⚠️ Quan trọng**: Trước khi dùng profile GLM hay Kimi, bạn cần cập nhật API key trong file settings tương ứng:
|
|
98
|
+
> - **GLM**: Chỉnh sửa `~/.ccs/glm.settings.json` và thêm GLM API key của bạn
|
|
99
|
+
> - **Kimi**: Chỉnh sửa `~/.ccs/kimi.settings.json` và thêm Kimi API key của bạn
|
|
100
|
+
|
|
101
|
+
```bash
|
|
102
|
+
# Dùng Claude subscription (mặc định) cho lập trình cấp cao
|
|
103
|
+
ccs "Lên kế hoạch triển khai kiến trúc microservices"
|
|
104
|
+
|
|
105
|
+
# Chuyển sang GLM cho tác vụ tối ưu chi phí
|
|
106
|
+
ccs glm "Tạo REST API đơn giản"
|
|
107
|
+
|
|
108
|
+
# Chuyển sang Kimi để sử dụng khả năng thinking
|
|
109
|
+
ccs kimi "Viết integration tests với xử lý lỗi phù hợp"
|
|
110
|
+
```
|
|
111
|
+
|
|
112
|
+
---
|
|
113
|
+
|
|
114
114
|
## Điểm Đau Hàng Ngày Của Lập Trình Viên
|
|
115
115
|
|
|
116
|
-
|
|
116
|
+
Lập trình viên đối mặt nhiều kịch bản subscription hàng ngày:
|
|
117
117
|
|
|
118
|
-
1. **
|
|
119
|
-
2. **
|
|
118
|
+
1. **Phân Tách Account**: Tài khoản Claude công ty vs Claude cá nhân → bạn phải tự chuyển context để giữ công việc và cá nhân riêng biệt
|
|
119
|
+
2. **Hết Rate Limit**: Claude dừng giữa chừng project → bạn phải tự tay sửa `~/.claude/settings.json`
|
|
120
|
+
3. **Quản Lý Chi Phí**: 2-3 subscriptions Pro ($20/tháng) vs Claude Max với chi phí 5x ($100/tháng) → Tier Pro là ngưỡng thực tế cho hầu hết lập trình viên
|
|
121
|
+
4. **Lựa Chọn Model**: Tác vụ khác nhau hưởng lợi từ thế mạnh model khác nhau → chuyển đổi thủ công
|
|
120
122
|
|
|
121
|
-
Chuyển đổi thủ công làm gián đoạn workflow
|
|
123
|
+
Chuyển đổi context thủ công làm gián đoạn workflow. **CCS quản lý liền mạch**.
|
|
122
124
|
|
|
123
125
|
## Tại Sao CCS Thay Vì Chuyển Đổi Thủ Công?
|
|
124
126
|
|
|
125
127
|
<div align="center">
|
|
126
128
|
|
|
127
|
-
| Tính năng | Lợi ích |
|
|
128
|
-
|
|
129
|
-
| **
|
|
130
|
-
| **
|
|
131
|
-
| **
|
|
132
|
-
| **
|
|
133
|
-
|
|
|
134
|
-
|
|
|
129
|
+
| Tính năng | Lợi ích |
|
|
130
|
+
|-----------|---------|
|
|
131
|
+
| **Phân Cách Account** | Giữ công việc riêng với cá nhân |
|
|
132
|
+
| **Tối Ưu Chi Phí** | 2-3 account Pro vs Max 5x chi phí |
|
|
133
|
+
| **Chuyển Đổi Tức Thì** | Một lệnh, không sửa file |
|
|
134
|
+
| **Không Downtime** | Không gián đoạn workflow |
|
|
135
|
+
| **Quản Lý Rate Limit** | Chuyển account khi hết limit |
|
|
136
|
+
| **Đa Nền Tảng** | macOS, Linux, Windows |
|
|
135
137
|
|
|
136
138
|
</div>
|
|
137
139
|
|
|
138
140
|
**Giải pháp**:
|
|
139
141
|
```bash
|
|
140
|
-
ccs
|
|
141
|
-
ccs
|
|
142
|
+
ccs cong-ty # Dùng account Claude công ty
|
|
143
|
+
ccs ca-nhan # Chuyển sang account Claude cá nhân
|
|
144
|
+
ccs glm # Chuyển sang GLM cho tác vụ tối ưu chi phí
|
|
145
|
+
ccs kimi # Chuyển sang Kimi cho lựa chọn thay thế
|
|
142
146
|
# Hết rate limit? Chuyển ngay:
|
|
143
|
-
ccs glm
|
|
147
|
+
ccs glm # Tiếp tục làm việc với GLM
|
|
148
|
+
# Cần account công ty khác?
|
|
149
|
+
ccs cong-ty-2 # Chuyển sang account công ty thứ hai
|
|
144
150
|
```
|
|
145
151
|
|
|
146
|
-
Một lệnh. Không downtime. Không phải sửa file. Đúng model, đúng việc.
|
|
147
|
-
|
|
148
152
|
---
|
|
149
153
|
|
|
150
154
|
## 🏗️ Tổng Quan Kiến Trúc
|
|
151
155
|
|
|
156
|
+
**v3.0 Mô hình Login-Per-Profile**: Mỗi profile là một Claude instance riêng biệt nơi người dùng đăng nhập trực tiếp. Không cần sao chép credentials hay vault encryption.
|
|
157
|
+
|
|
152
158
|
```mermaid
|
|
153
|
-
|
|
154
|
-
subgraph "
|
|
155
|
-
|
|
159
|
+
flowchart TD
|
|
160
|
+
subgraph "Người Dùng Input"
|
|
161
|
+
USER["User chạy: ccs <profile> [args...]"]
|
|
156
162
|
end
|
|
157
163
|
|
|
158
|
-
subgraph "
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
164
|
+
subgraph "Engine Phát Hiện Profile"
|
|
165
|
+
DETECT[ProfileDetector]
|
|
166
|
+
PROFILE_CHECK{Profile tồn tại?}
|
|
167
|
+
|
|
168
|
+
subgraph "Loại Profile"
|
|
169
|
+
SETTINGS["Settings-based<br/>glm, kimi, default"]
|
|
170
|
+
ACCOUNT["Account-based<br/>work, personal, team"]
|
|
171
|
+
end
|
|
162
172
|
end
|
|
163
173
|
|
|
164
|
-
subgraph "
|
|
165
|
-
|
|
174
|
+
subgraph "Xử Lý Core CCS"
|
|
175
|
+
CONFIG["Đọc config.json<br/>và profiles.json"]
|
|
176
|
+
|
|
177
|
+
subgraph "Profile Handlers"
|
|
178
|
+
SETTINGS_MGR["SettingsManager<br/>→ --settings flag"]
|
|
179
|
+
INSTANCE_MGR["InstanceManager<br/>→ CLAUDE_CONFIG_DIR"]
|
|
180
|
+
end
|
|
166
181
|
end
|
|
167
182
|
|
|
168
|
-
subgraph "
|
|
169
|
-
|
|
183
|
+
subgraph "Thực Thi Claude CLI"
|
|
184
|
+
CLAUDE_DETECT["Claude CLI Detection<br/>Hỗ trợ CCS_CLAUDE_PATH"]
|
|
185
|
+
|
|
186
|
+
subgraph "Phương Thức Thực Thi"
|
|
187
|
+
SETTINGS_EXEC["claude --settings <path>"]
|
|
188
|
+
INSTANCE_EXEC["CLAUDE_CONFIG_DIR=<instance> claude"]
|
|
189
|
+
end
|
|
170
190
|
end
|
|
171
191
|
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
192
|
+
subgraph "API Layer"
|
|
193
|
+
API["API Response<br/>Claude Sonnet 4.5<br/>GLM 4.6<br/>Kimi K2 Thinking"]
|
|
194
|
+
end
|
|
195
|
+
|
|
196
|
+
%% Flow connections
|
|
197
|
+
USER --> DETECT
|
|
198
|
+
DETECT --> PROFILE_CHECK
|
|
199
|
+
PROFILE_CHECK -->|Có| SETTINGS
|
|
200
|
+
PROFILE_CHECK -->|Có| ACCOUNT
|
|
201
|
+
|
|
202
|
+
SETTINGS --> CONFIG
|
|
203
|
+
ACCOUNT --> CONFIG
|
|
204
|
+
|
|
205
|
+
CONFIG --> SETTINGS_MGR
|
|
206
|
+
CONFIG --> INSTANCE_MGR
|
|
207
|
+
|
|
208
|
+
SETTINGS_MGR --> SETTINGS_EXEC
|
|
209
|
+
INSTANCE_MGR --> INSTANCE_EXEC
|
|
210
|
+
|
|
211
|
+
SETTINGS_EXEC --> CLAUDE_DETECT
|
|
212
|
+
INSTANCE_EXEC --> CLAUDE_DETECT
|
|
213
|
+
|
|
214
|
+
CLAUDE_DETECT --> API
|
|
177
215
|
```
|
|
178
216
|
|
|
179
217
|
---
|
|
180
218
|
|
|
181
219
|
## ⚡ Tính Năng
|
|
182
220
|
|
|
183
|
-
|
|
184
|
-
- **
|
|
185
|
-
- **
|
|
186
|
-
-
|
|
187
|
-
|
|
188
|
-
### Không Gián Đoạn Workflow
|
|
189
|
-
- **Không Downtime**: Chuyển đổi xảy ra ngay lập tức giữa các lệnh
|
|
190
|
-
- **Bảo Toàn Context**: Workflow của bạn không bị gián đoạn
|
|
191
|
-
- **Tích Hợp Liền Mạch**: Hoạt động chính xác như Claude CLI native
|
|
221
|
+
- **Chuyển Đổi Ngay Lập Tức** - `ccs glm` chuyển sang GLM, không cần sửa config
|
|
222
|
+
- **Phiên Đồng Thời** - Chạy nhiều profile cùng lúc ở các terminal khác nhau
|
|
223
|
+
- **Instance Riêng Biệt** - Mỗi profile có config riêng (`~/.ccs/instances/<profile>/`)
|
|
224
|
+
- **Đa Nền Tảng** - macOS, Linux, Windows - hoạt động giống nhau
|
|
225
|
+
- **Không Downtime** - Chuyển đổi ngay lập tức, không gián đoạn workflow
|
|
192
226
|
|
|
193
227
|
|
|
194
228
|
---
|
|
@@ -201,32 +235,51 @@ ccs glm # Dùng GLM fallback
|
|
|
201
235
|
ccs --version # Hiển thị phiên bản CCS và vị trí cài đặt
|
|
202
236
|
```
|
|
203
237
|
|
|
238
|
+
### Phiên Đồng Thời (Multi-Account)
|
|
239
|
+
```bash
|
|
240
|
+
# Tạo nhiều tài khoản Claude
|
|
241
|
+
ccs auth create cong-ty # Tài khoản công ty
|
|
242
|
+
ccs auth create ca-nhan # Tài khoản cá nhân
|
|
243
|
+
ccs auth create team # Tài khoản team
|
|
244
|
+
|
|
245
|
+
# Terminal 1 - Tài khoản công ty
|
|
246
|
+
ccs cong-ty "implement feature"
|
|
247
|
+
|
|
248
|
+
# Terminal 2 - Tài khoản cá nhân (chạy đồng thời)
|
|
249
|
+
ccs ca-nhan "review code"
|
|
250
|
+
```
|
|
251
|
+
|
|
204
252
|
---
|
|
205
253
|
|
|
206
|
-
### 🗑️ Gỡ Cài Đặt
|
|
254
|
+
### 🗑️ Gỡ Cài Đặt
|
|
207
255
|
|
|
208
|
-
**
|
|
256
|
+
**Package Managers**
|
|
257
|
+
```bash
|
|
258
|
+
# npm
|
|
259
|
+
npm uninstall -g @kaitranntt/ccs
|
|
209
260
|
|
|
210
|
-
|
|
261
|
+
# yarn
|
|
262
|
+
yarn global remove @kaitranntt/ccs
|
|
263
|
+
|
|
264
|
+
# pnpm
|
|
265
|
+
pnpm remove -g @kaitranntt/ccs
|
|
266
|
+
|
|
267
|
+
# bun
|
|
268
|
+
bun remove -g @kaitranntt/ccs
|
|
269
|
+
```
|
|
270
|
+
|
|
271
|
+
**Uninstaller Chính Thức**
|
|
272
|
+
|
|
273
|
+
**macOS / Linux**
|
|
211
274
|
```bash
|
|
212
275
|
curl -fsSL ccs.kaitran.ca/uninstall | bash
|
|
213
276
|
```
|
|
214
277
|
|
|
215
|
-
**Windows PowerShell
|
|
278
|
+
**Windows PowerShell**
|
|
216
279
|
```powershell
|
|
217
280
|
irm ccs.kaitran.ca/uninstall | iex
|
|
218
281
|
```
|
|
219
282
|
|
|
220
|
-
> 💡 **Tại sao dùng uninstaller chính thức?**
|
|
221
|
-
> - Gỡ bỏ tất cả file và cấu hình CCS
|
|
222
|
-
> - Dọn dẹp PATH modifications
|
|
223
|
-
> - Gỡ bỏ commands/skills Claude CLI
|
|
224
|
-
> - Xử lý các trường hợp đặc biệt đã test
|
|
225
|
-
|
|
226
|
-
**Phương pháp thay thế** (nếu uninstaller chính thức thất bại):
|
|
227
|
-
- **npm**: `npm uninstall -g @kaitranntt/ccs`
|
|
228
|
-
- **Thủ công**: Xem [hướng dẫn khắc phục](./docs/vi/troubleshooting.vi.md#gỡ-cài-đặt-thủ-công)
|
|
229
|
-
|
|
230
283
|
---
|
|
231
284
|
|
|
232
285
|
## 🎯 Triết Lý
|
|
@@ -244,13 +297,13 @@ irm ccs.kaitran.ca/uninstall | iex
|
|
|
244
297
|
- [Cấu hình](./docs/configuration.md)
|
|
245
298
|
- [Ví dụ Sử dụng](./docs/usage.md)
|
|
246
299
|
- [Khắc phục Sự cố](./docs/troubleshooting.md)
|
|
247
|
-
- [Đóng góp](./
|
|
300
|
+
- [Đóng góp](./CONTRIBUTING.md)
|
|
248
301
|
|
|
249
302
|
---
|
|
250
303
|
|
|
251
304
|
## 🤝 Đóng Góp
|
|
252
305
|
|
|
253
|
-
Chúng tôi chào mừng đóng góp! Vui lòng xem [Hướng dẫn Đóng góp](./
|
|
306
|
+
Chúng tôi chào mừng đóng góp! Vui lòng xem [Hướng dẫn Đóng góp](./CONTRIBUTING.md) để biết chi tiết.
|
|
254
307
|
|
|
255
308
|
---
|
|
256
309
|
|
package/VERSION
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
3.0.
|
|
1
|
+
3.0.1
|
package/bin/ccs.js
CHANGED
|
@@ -8,6 +8,8 @@ const os = require('os');
|
|
|
8
8
|
const { error, colored } = require('./helpers');
|
|
9
9
|
const { detectClaudeCli, showClaudeNotFoundError } = require('./claude-detector');
|
|
10
10
|
const { getSettingsPath, getConfigPath } = require('./config-manager');
|
|
11
|
+
const { ErrorManager } = require('./error-manager');
|
|
12
|
+
const RecoveryManager = require('./recovery-manager');
|
|
11
13
|
|
|
12
14
|
// Version (sync with package.json)
|
|
13
15
|
const CCS_VERSION = require('../package.json').version;
|
|
@@ -97,25 +99,34 @@ function handleHelpCommand() {
|
|
|
97
99
|
|
|
98
100
|
// Description
|
|
99
101
|
console.log(colored('Description:', 'cyan'));
|
|
100
|
-
console.log(' Switch between Claude
|
|
101
|
-
console.log('
|
|
102
|
+
console.log(' Switch between multiple Claude accounts (work, personal, team) and');
|
|
103
|
+
console.log(' alternative models (GLM, Kimi) instantly. Concurrent sessions with');
|
|
104
|
+
console.log(' auto-recovery. Zero downtime.');
|
|
102
105
|
console.log('');
|
|
103
106
|
|
|
104
|
-
//
|
|
105
|
-
console.log(colored('
|
|
106
|
-
console.log(` ${colored('ccs', 'yellow')} Use default
|
|
107
|
-
console.log(` ${colored('ccs glm', 'yellow')} Switch to GLM
|
|
108
|
-
console.log(` ${colored('ccs kimi', 'yellow')} Switch to Kimi
|
|
109
|
-
console.log(` ${colored('ccs
|
|
110
|
-
console.log(` ${colored('ccs glm', 'yellow')} "debug this code" Switch to GLM and run command`);
|
|
111
|
-
console.log(` ${colored('ccs work', 'yellow')} "review code" Use work account and run command`);
|
|
107
|
+
// Model Switching
|
|
108
|
+
console.log(colored('Model Switching:', 'cyan'));
|
|
109
|
+
console.log(` ${colored('ccs', 'yellow')} Use default Claude account`);
|
|
110
|
+
console.log(` ${colored('ccs glm', 'yellow')} Switch to GLM 4.6 model`);
|
|
111
|
+
console.log(` ${colored('ccs kimi', 'yellow')} Switch to Kimi for Coding`);
|
|
112
|
+
console.log(` ${colored('ccs glm', 'yellow')} "debug this code" Use GLM and run command`);
|
|
112
113
|
console.log('');
|
|
113
114
|
|
|
114
115
|
// Account Management
|
|
115
116
|
console.log(colored('Account Management:', 'cyan'));
|
|
116
117
|
console.log(` ${colored('ccs auth create <profile>', 'yellow')} Create new profile and login`);
|
|
117
118
|
console.log(` ${colored('ccs auth list', 'yellow')} List all saved profiles`);
|
|
118
|
-
console.log(` ${colored('ccs auth
|
|
119
|
+
console.log(` ${colored('ccs auth show <profile>', 'yellow')} Show profile details`);
|
|
120
|
+
console.log(` ${colored('ccs auth remove <profile>', 'yellow')} Remove profile (requires --force)`);
|
|
121
|
+
console.log(` ${colored('ccs auth default <profile>', 'yellow')} Set default profile`);
|
|
122
|
+
console.log(` ${colored('ccs work', 'yellow')} Switch to work account`);
|
|
123
|
+
console.log(` ${colored('ccs personal', 'yellow')} Switch to personal account`);
|
|
124
|
+
console.log(` ${colored('ccs work', 'yellow')} "review code" Run command with work account`);
|
|
125
|
+
console.log('');
|
|
126
|
+
|
|
127
|
+
// Diagnostics
|
|
128
|
+
console.log(colored('Diagnostics:', 'cyan'));
|
|
129
|
+
console.log(` ${colored('ccs doctor', 'yellow')} Run health check and diagnostics`);
|
|
119
130
|
console.log('');
|
|
120
131
|
|
|
121
132
|
// Flags
|
|
@@ -195,6 +206,16 @@ function handleUninstallCommand() {
|
|
|
195
206
|
process.exit(0);
|
|
196
207
|
}
|
|
197
208
|
|
|
209
|
+
async function handleDoctorCommand() {
|
|
210
|
+
const Doctor = require('./doctor');
|
|
211
|
+
const doctor = new Doctor();
|
|
212
|
+
|
|
213
|
+
await doctor.runAllChecks();
|
|
214
|
+
|
|
215
|
+
// Exit with error code if unhealthy
|
|
216
|
+
process.exit(doctor.results.isHealthy() ? 0 : 1);
|
|
217
|
+
}
|
|
218
|
+
|
|
198
219
|
// Smart profile detection
|
|
199
220
|
function detectProfile(args) {
|
|
200
221
|
if (args.length === 0 || args[0].startsWith('-')) {
|
|
@@ -234,6 +255,12 @@ async function main() {
|
|
|
234
255
|
return;
|
|
235
256
|
}
|
|
236
257
|
|
|
258
|
+
// Special case: doctor command
|
|
259
|
+
if (firstArg === 'doctor' || firstArg === '--doctor') {
|
|
260
|
+
await handleDoctorCommand();
|
|
261
|
+
return;
|
|
262
|
+
}
|
|
263
|
+
|
|
237
264
|
// Special case: auth command (multi-account management)
|
|
238
265
|
if (firstArg === 'auth') {
|
|
239
266
|
const AuthCommands = require('./auth-commands');
|
|
@@ -242,13 +269,21 @@ async function main() {
|
|
|
242
269
|
return;
|
|
243
270
|
}
|
|
244
271
|
|
|
272
|
+
// Auto-recovery for missing configuration
|
|
273
|
+
const recovery = new RecoveryManager();
|
|
274
|
+
const recovered = recovery.recoverAll();
|
|
275
|
+
|
|
276
|
+
if (recovered) {
|
|
277
|
+
recovery.showRecoveryHints();
|
|
278
|
+
}
|
|
279
|
+
|
|
245
280
|
// Detect profile
|
|
246
281
|
const { profile, remainingArgs } = detectProfile(args);
|
|
247
282
|
|
|
248
283
|
// Detect Claude CLI first (needed for all paths)
|
|
249
284
|
const claudeCli = detectClaudeCli();
|
|
250
285
|
if (!claudeCli) {
|
|
251
|
-
|
|
286
|
+
ErrorManager.showClaudeNotFound();
|
|
252
287
|
process.exit(1);
|
|
253
288
|
}
|
|
254
289
|
|
package/bin/config-manager.js
CHANGED
|
@@ -4,6 +4,7 @@ const fs = require('fs');
|
|
|
4
4
|
const path = require('path');
|
|
5
5
|
const os = require('os');
|
|
6
6
|
const { error, expandPath } = require('./helpers');
|
|
7
|
+
const { ErrorManager } = require('./error-manager');
|
|
7
8
|
|
|
8
9
|
// Get config file path
|
|
9
10
|
function getConfigPath() {
|
|
@@ -16,7 +17,15 @@ function readConfig() {
|
|
|
16
17
|
|
|
17
18
|
// Check config exists
|
|
18
19
|
if (!fs.existsSync(configPath)) {
|
|
19
|
-
|
|
20
|
+
// Attempt recovery
|
|
21
|
+
const RecoveryManager = require('./recovery-manager');
|
|
22
|
+
const recovery = new RecoveryManager();
|
|
23
|
+
recovery.ensureConfigJson();
|
|
24
|
+
|
|
25
|
+
if (!fs.existsSync(configPath)) {
|
|
26
|
+
ErrorManager.showInvalidConfig(configPath, 'File not found');
|
|
27
|
+
process.exit(1);
|
|
28
|
+
}
|
|
20
29
|
}
|
|
21
30
|
|
|
22
31
|
// Read and parse JSON
|
|
@@ -25,12 +34,14 @@ function readConfig() {
|
|
|
25
34
|
const configContent = fs.readFileSync(configPath, 'utf8');
|
|
26
35
|
config = JSON.parse(configContent);
|
|
27
36
|
} catch (e) {
|
|
28
|
-
|
|
37
|
+
ErrorManager.showInvalidConfig(configPath, `Invalid JSON: ${e.message}`);
|
|
38
|
+
process.exit(1);
|
|
29
39
|
}
|
|
30
40
|
|
|
31
41
|
// Validate config has profiles object
|
|
32
42
|
if (!config.profiles || typeof config.profiles !== 'object') {
|
|
33
|
-
|
|
43
|
+
ErrorManager.showInvalidConfig(configPath, "Missing 'profiles' object");
|
|
44
|
+
process.exit(1);
|
|
34
45
|
}
|
|
35
46
|
|
|
36
47
|
return config;
|
|
@@ -44,8 +55,10 @@ function getSettingsPath(profile) {
|
|
|
44
55
|
const settingsPath = config.profiles[profile];
|
|
45
56
|
|
|
46
57
|
if (!settingsPath) {
|
|
47
|
-
const availableProfiles = Object.keys(config.profiles)
|
|
48
|
-
|
|
58
|
+
const availableProfiles = Object.keys(config.profiles);
|
|
59
|
+
const profileList = availableProfiles.map(p => ` - ${p}`);
|
|
60
|
+
ErrorManager.showProfileNotFound(profile, profileList);
|
|
61
|
+
process.exit(1);
|
|
49
62
|
}
|
|
50
63
|
|
|
51
64
|
// Expand path
|
|
@@ -53,7 +66,22 @@ function getSettingsPath(profile) {
|
|
|
53
66
|
|
|
54
67
|
// Validate settings file exists
|
|
55
68
|
if (!fs.existsSync(expandedPath)) {
|
|
56
|
-
|
|
69
|
+
// Auto-create if it's ~/.claude/settings.json
|
|
70
|
+
if (expandedPath.includes('.claude') && expandedPath.endsWith('settings.json')) {
|
|
71
|
+
const RecoveryManager = require('./recovery-manager');
|
|
72
|
+
const recovery = new RecoveryManager();
|
|
73
|
+
recovery.ensureClaudeSettings();
|
|
74
|
+
|
|
75
|
+
if (!fs.existsSync(expandedPath)) {
|
|
76
|
+
ErrorManager.showSettingsNotFound(expandedPath);
|
|
77
|
+
process.exit(1);
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
console.log('[i] Auto-created missing settings file');
|
|
81
|
+
} else {
|
|
82
|
+
ErrorManager.showSettingsNotFound(expandedPath);
|
|
83
|
+
process.exit(1);
|
|
84
|
+
}
|
|
57
85
|
}
|
|
58
86
|
|
|
59
87
|
// Validate settings file is valid JSON
|
|
@@ -61,7 +89,8 @@ function getSettingsPath(profile) {
|
|
|
61
89
|
const settingsContent = fs.readFileSync(expandedPath, 'utf8');
|
|
62
90
|
JSON.parse(settingsContent);
|
|
63
91
|
} catch (e) {
|
|
64
|
-
|
|
92
|
+
ErrorManager.showInvalidConfig(expandedPath, `Invalid JSON: ${e.message}`);
|
|
93
|
+
process.exit(1);
|
|
65
94
|
}
|
|
66
95
|
|
|
67
96
|
return expandedPath;
|